commit 5f2cbc2f0549aa2bc3d98d0d9e2297c92d1ffbef
parent 33c78468eca63558148b64b86e2008caaefd9884
Author: Michael Forney <mforney@mforney.org>
Date: Fri, 13 Sep 2013 01:42:03 -0700
Finish implementing pointer events
Diffstat:
4 files changed, 97 insertions(+), 2 deletions(-)
diff --git a/libswc/evdev_device.c b/libswc/evdev_device.c
@@ -13,6 +13,8 @@
#define TEST_BIT(var, n) \
(((var)[(n)/((sizeof (var)[0])*8)] >> ((n)%((sizeof (var)[0])*8))) & 1)
+#define AXIS_STEP_DISTANCE 10
+
static inline uint32_t timeval_to_msec(struct timeval * time)
{
return time->tv_sec * 1000 + time->tv_usec / 1000;
@@ -49,6 +51,12 @@ static void handle_key_event(struct swc_evdev_device * device,
static void handle_rel_event(struct swc_evdev_device * device,
struct input_event * input_event)
{
+ struct swc_event event;
+ struct swc_evdev_device_event_data data;
+
+ event.data = &data;
+ data.time = timeval_to_msec(&input_event->time);
+
switch (input_event->code)
{
case REL_X:
@@ -59,6 +67,20 @@ static void handle_rel_event(struct swc_evdev_device * device,
device->motion.rel.dy += input_event->value;
device->motion.rel.pending = true;
break;
+ case REL_WHEEL:
+ event.type = SWC_EVDEV_DEVICE_EVENT_AXIS_MOTION;
+ data.axis_motion.axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
+ data.axis_motion.amount
+ = -AXIS_STEP_DISTANCE * wl_fixed_from_int(input_event->value);
+ wl_signal_emit(&device->event_signal, &event);
+ break;
+ case REL_HWHEEL:
+ event.type = SWC_EVDEV_DEVICE_EVENT_AXIS_MOTION;
+ data.axis_motion.axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
+ data.axis_motion.amount
+ = AXIS_STEP_DISTANCE * wl_fixed_from_int(input_event->value);
+ wl_signal_emit(&device->event_signal, &event);
+ break;
}
}
diff --git a/libswc/evdev_device.h b/libswc/evdev_device.h
@@ -11,7 +11,8 @@ enum swc_evdev_device_event_type
SWC_EVDEV_DEVICE_EVENT_KEY,
SWC_EVDEV_DEVICE_EVENT_BUTTON,
SWC_EVDEV_DEVICE_EVENT_RELATIVE_MOTION,
- SWC_EVDEV_DEVICE_EVENT_ABSOLUTE_MOTION
+ SWC_EVDEV_DEVICE_EVENT_ABSOLUTE_MOTION,
+ SWC_EVDEV_DEVICE_EVENT_AXIS_MOTION
};
struct swc_evdev_device_event_data
@@ -26,6 +27,12 @@ struct swc_evdev_device_event_data
struct
{
+ wl_fixed_t amount;
+ enum wl_pointer_axis axis;
+ } axis_motion;
+
+ struct
+ {
uint32_t key;
enum wl_keyboard_key_state state;
} key;
diff --git a/libswc/pointer.h b/libswc/pointer.h
@@ -12,8 +12,10 @@ struct swc_pointer_handler
{
void (* focus)(struct swc_pointer * pointer);
bool (* motion)(struct swc_pointer * pointer, uint32_t time);
- void (* button)(struct swc_pointer * pointer, uint32_t time,
+ bool (* button)(struct swc_pointer * pointer, uint32_t time,
uint32_t button, uint32_t state);
+ bool (* axis)(struct swc_pointer * pointer, uint32_t time,
+ enum wl_pointer_axis axis, wl_fixed_t amount);
};
enum swc_pointer_event_type
diff --git a/libswc/seat.c b/libswc/seat.c
@@ -141,11 +141,70 @@ static void handle_key(struct swc_seat * seat, uint32_t time, uint32_t key,
static void handle_button(struct swc_seat * seat, uint32_t time,
uint32_t button, uint32_t state)
{
+ struct swc_pointer * pointer = &seat->pointer;
+
+ if ((!pointer->handler || !pointer->handler->button
+ || !pointer->handler->button(pointer, time, button, state))
+ && pointer->focus.resource)
+ {
+ struct wl_client * client
+ = wl_resource_get_client(pointer->focus.resource);
+ struct wl_display * display = wl_client_get_display(client);
+ uint32_t serial = wl_display_next_serial(display);
+
+ wl_pointer_send_button(pointer->focus.resource, serial, time,
+ button, state);
+ }
}
static void handle_relative_motion(struct swc_seat * seat, uint32_t time,
wl_fixed_t dx, wl_fixed_t dy)
{
+ struct swc_pointer * pointer = &seat->pointer;
+
+ clip_position(seat, pointer->x + dx, pointer->y + dy);
+
+ if (pointer->handler && pointer->handler->focus)
+ pointer->handler->focus(pointer);
+
+ if ((!pointer->handler || !pointer->handler->motion
+ || !pointer->handler->motion(pointer, time))
+ && pointer->focus.resource)
+ {
+ wl_fixed_t surface_x, surface_y;
+ surface_x = pointer->x
+ - wl_fixed_from_int(pointer->focus.surface->geometry.x);
+ surface_y = pointer->y
+ - wl_fixed_from_int(pointer->focus.surface->geometry.y);
+
+ wl_pointer_send_motion(pointer->focus.resource, time,
+ surface_x, surface_y);
+
+ if (pointer->cursor.surface)
+ {
+ swc_surface_move
+ (pointer->cursor.surface,
+ wl_fixed_to_int(pointer->x) - pointer->cursor.hotspot_x,
+ wl_fixed_to_int(pointer->y) - pointer->cursor.hotspot_y);
+ }
+ }
+}
+
+static void handle_axis_motion(struct swc_seat * seat, uint32_t time,
+ enum wl_pointer_axis axis, wl_fixed_t amount)
+{
+ struct swc_pointer * pointer = &seat->pointer;
+
+ if ((!pointer->handler || !pointer->handler->axis
+ || !pointer->handler->axis(pointer, time, axis, amount))
+ && pointer->focus.resource)
+ {
+ struct wl_client * client
+ = wl_resource_get_client(pointer->focus.resource);
+ struct wl_display * display = wl_client_get_display(client);
+
+ wl_pointer_send_axis(pointer->focus.resource, time, axis, amount);
+ }
}
static void handle_evdev_event(struct wl_listener * listener, void * data)
@@ -173,6 +232,11 @@ static void handle_evdev_event(struct wl_listener * listener, void * data)
break;
case SWC_EVDEV_DEVICE_EVENT_ABSOLUTE_MOTION:
break;
+ case SWC_EVDEV_DEVICE_EVENT_AXIS_MOTION:
+ handle_axis_motion(entry->seat, evdev_data->time,
+ evdev_data->axis_motion.axis,
+ evdev_data->axis_motion.amount);
+ break;
}
}