commit 441ff74005162daf10f717d41848a4952fdb2cdd
parent f60ae1114f2a48d64aafa0aef5722ff4514734d7
Author: Michael Forney <mforney@mforney.org>
Date: Fri, 14 Jun 2013 04:05:39 -0700
Pass stuff from evdev up through events
Diffstat:
M | evdev_device.c | | | 74 | +++++++++++++++++++++++++++++++++++++++++++++++++++----------------------- |
M | evdev_device.h | | | 58 | ++++++++++++++++++++++++++++++++++++++++++++++------------ |
M | seat.c | | | 272 | ++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------- |
M | seat.h | | | 6 | ------ |
4 files changed, 270 insertions(+), 140 deletions(-)
diff --git a/evdev_device.c b/evdev_device.c
@@ -1,6 +1,7 @@
#include "evdev_device.h"
#include "seat.h"
+#include "event.h"
#include <stdlib.h>
#include <stdio.h>
@@ -18,49 +19,57 @@ static inline uint32_t timeval_to_msec(struct timeval * time)
}
static void handle_key_event(struct swc_evdev_device * device,
- struct input_event * event)
+ struct input_event * input_event)
{
- uint32_t time = timeval_to_msec(&event->time);
+ struct swc_event event;
+ struct swc_evdev_device_event_data data;
- if ((event->code >= BTN_MISC && event->code <= BTN_GEAR_UP)
- || event->code >= BTN_TRIGGER_HAPPY)
+ event.data = &data;
+ data.time = timeval_to_msec(&input_event->time);
+
+ if ((input_event->code >= BTN_MISC && input_event->code <= BTN_GEAR_UP)
+ || input_event->code >= BTN_TRIGGER_HAPPY)
{
- swc_seat_handle_button(device->seat, time, event->value,
- event->value ? WL_POINTER_BUTTON_STATE_PRESSED
- : WL_POINTER_BUTTON_STATE_RELEASED);
+ event.type = SWC_EVDEV_DEVICE_EVENT_BUTTON;
+ data.button.button = input_event->code;
+ data.button.state = input_event->value ? WL_POINTER_BUTTON_STATE_PRESSED
+ : WL_POINTER_BUTTON_STATE_RELEASED;
}
else
{
- swc_seat_handle_key(device->seat, time, event->code,
- event->value ? WL_KEYBOARD_KEY_STATE_PRESSED
- : WL_KEYBOARD_KEY_STATE_RELEASED);
+ event.type = SWC_EVDEV_DEVICE_EVENT_KEY;
+ data.key.key = input_event->code;
+ data.key.state = input_event->value ? WL_KEYBOARD_KEY_STATE_PRESSED
+ : WL_KEYBOARD_KEY_STATE_RELEASED;
}
+
+ wl_signal_emit(&device->event_signal, &event);
}
static void handle_rel_event(struct swc_evdev_device * device,
- struct input_event * event)
+ struct input_event * input_event)
{
- //printf("rel event\n");
-
- switch (event->code)
+ switch (input_event->code)
{
case REL_X:
- //printf("rel_x: %d\n", event->value);
+ device->motion.rel.dx += input_event->value;
+ device->motion.rel.pending = true;
break;
case REL_Y:
- //printf("rel_y: %d\n", event->value);
+ device->motion.rel.dy += input_event->value;
+ device->motion.rel.pending = true;
break;
}
}
static void handle_abs_event(struct swc_evdev_device * device,
- struct input_event * event)
+ struct input_event * input_event)
{
printf("abs event\n");
}
static void (* event_handlers[])(struct swc_evdev_device * device,
- struct input_event * event) = {
+ struct input_event * input_event) = {
[EV_KEY] = &handle_key_event,
[EV_REL] = &handle_rel_event,
[EV_ABS] = &handle_abs_event
@@ -75,6 +84,24 @@ static bool is_motion_event(struct input_event * event)
static void handle_motion_events(struct swc_evdev_device * device,
uint32_t time)
{
+ struct swc_event event;
+ struct swc_evdev_device_event_data data;
+
+ event.data = &data;
+ data.time = time;
+
+ if (device->motion.rel.pending)
+ {
+ event.type = SWC_EVDEV_DEVICE_EVENT_RELATIVE_MOTION;
+ data.relative_motion.dx = wl_fixed_from_int(device->motion.rel.dx);
+ data.relative_motion.dy = wl_fixed_from_int(device->motion.rel.dy);
+
+ wl_signal_emit(&device->event_signal, &event);
+
+ device->motion.rel.pending = false;
+ device->motion.rel.dx = 0;
+ device->motion.rel.dy = 0;
+ }
}
static void process_events(struct swc_evdev_device * device,
@@ -121,7 +148,6 @@ static int handle_data(int fd, uint32_t mask, void * data)
}
bool swc_evdev_device_initialize(struct swc_evdev_device * device,
- struct swc_seat * seat,
struct udev_device * udev_device)
{
const char * path, * model, * vendor;
@@ -134,10 +160,12 @@ bool swc_evdev_device_initialize(struct swc_evdev_device * device,
vendor = udev_device_get_property_value(udev_device, "ID_VENDOR")
?: "unknown";
- device->seat = seat;
device->model = strdup(model);
device->vendor = strdup(vendor);
device->fd = open(path, O_RDWR | O_NONBLOCK | O_CLOEXEC);
+ memset(&device->motion, 0, sizeof device->motion);
+
+ wl_signal_init(&device->event_signal);
if (device->fd == -1)
{
@@ -150,7 +178,7 @@ bool swc_evdev_device_initialize(struct swc_evdev_device * device,
ioctl(device->fd, EVIOCGBIT(0, sizeof ev_bits), &ev_bits);
device->capabilities = 0;
- /* Currently, I don't care about touch devices. */
+ /* XXX: touch devices */
if (udev_device_get_property_value(udev_device, "ID_INPUT_KEYBOARD"))
{
@@ -187,9 +215,9 @@ bool swc_evdev_device_initialize(struct swc_evdev_device * device,
ioctl(device->fd, EVIOCGBIT(EV_ABS, sizeof abs_bits), &abs_bits);
if (TEST_BIT(abs_bits, ABS_X))
- ioctl(device->fd, EVIOCGABS(ABS_X), &device->abs.info.x);
+ ioctl(device->fd, EVIOCGABS(ABS_X), &device->motion.abs.info.x);
if (TEST_BIT(abs_bits, ABS_Y))
- ioctl(device->fd, EVIOCGABS(ABS_X), &device->abs.info.y);
+ ioctl(device->fd, EVIOCGABS(ABS_X), &device->motion.abs.info.y);
}
}
diff --git a/evdev_device.h b/evdev_device.h
@@ -6,10 +6,40 @@
#include <linux/input.h>
#include <wayland-server.h>
-struct swc_evdev_device
+enum swc_evdev_device_event_type
{
- struct swc_seat * seat;
+ SWC_EVDEV_DEVICE_EVENT_KEY,
+ SWC_EVDEV_DEVICE_EVENT_BUTTON,
+ SWC_EVDEV_DEVICE_EVENT_RELATIVE_MOTION,
+ SWC_EVDEV_DEVICE_EVENT_ABSOLUTE_MOTION
+};
+
+struct swc_evdev_device_event_data
+{
+ uint32_t time;
+ union
+ {
+ struct
+ {
+ wl_fixed_t dx, dy;
+ } relative_motion;
+
+ struct
+ {
+ uint32_t key;
+ enum wl_keyboard_key_state state;
+ } key;
+ struct
+ {
+ uint32_t button;
+ enum wl_pointer_button_state state;
+ } button;
+ };
+};
+
+struct swc_evdev_device
+{
int fd;
char * model, * vendor;
@@ -17,26 +47,30 @@ struct swc_evdev_device
{
struct
{
- struct input_absinfo x, y;
- } info;
+ struct
+ {
+ struct input_absinfo x, y;
+ } info;
- int32_t x, y;
- bool pending;
- } abs;
+ int32_t x, y;
+ bool pending;
+ } abs;
- struct
- {
- bool pending;
- } rel;
+ struct
+ {
+ int32_t dx, dy;
+ bool pending;
+ } rel;
+ } motion;
uint32_t capabilities;
struct wl_event_source * source;
+ struct wl_signal event_signal;
struct wl_list link;
};
bool swc_evdev_device_initialize(struct swc_evdev_device * device,
- struct swc_seat * seat,
struct udev_device * udev_device);
void swc_evdev_device_finish(struct swc_evdev_device * device);
diff --git a/seat.c b/seat.c
@@ -3,17 +3,164 @@
#include "evdev_device.h"
#include "util.h"
#include "binding.h"
+#include "event.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+struct evdev_device_entry
+{
+ struct swc_evdev_device device;
+ struct wl_listener event_listener;
+ struct swc_seat * seat;
+ struct wl_list link;
+};
+
struct wl_seat_interface swc_seat_interface = {
.get_pointer = &swc_seat_get_pointer,
.get_keyboard = &swc_seat_get_keyboard,
.get_touch = &swc_seat_get_touch
};
+static void handle_key(struct swc_seat * seat, uint32_t time, uint32_t key,
+ uint32_t state)
+{
+ uint32_t * pressed_key;
+ struct swc_keyboard * keyboard = &seat->keyboard;
+ struct swc_xkb * xkb = &seat->xkb;
+ struct wl_display * display;
+ uint32_t serial;
+ enum xkb_key_direction direction;
+
+ if (keyboard->focus.resource)
+ {
+ struct wl_client * focus_client
+ = wl_resource_get_client(keyboard->focus.resource);
+ display = wl_client_get_display(focus_client);
+ }
+
+ /* Update keyboard state state */
+ wl_array_for_each(pressed_key, &keyboard->keys)
+ {
+ if (*pressed_key == key)
+ {
+ /* Ignore repeat evdev events. */
+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
+ return;
+ else
+ {
+ /* Remove the key from the array */
+ uint32_t bytes_to_copy = keyboard->keys.size + 1
+ - (((void *) pressed_key) - keyboard->keys.data);
+
+ if (bytes_to_copy > 0)
+ memmove(pressed_key, pressed_key + 1, bytes_to_copy);
+
+ keyboard->keys.size -= sizeof key;
+
+ break;
+ }
+ }
+ }
+
+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
+ {
+ //keyboard->grab_key = key;
+ //keyboard->grab_time = time;
+ pressed_key = wl_array_add(&keyboard->keys, sizeof key);
+ *pressed_key = key;
+ }
+
+ /* See if the key press is not handled by the compositor */
+ if (!(keyboard->handler && keyboard->handler->key)
+ || !keyboard->handler->key(keyboard, time, key, state))
+ {
+ if (keyboard->focus.resource)
+ {
+ serial = wl_display_next_serial(display);
+ wl_keyboard_send_key(keyboard->focus.resource, serial, time, key, state);
+
+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
+ printf("\t-> sent to client\n");
+ }
+ }
+
+ /* Update XKB state. Apparently the keycodes are offset by 8 in XKB. */
+ direction = state == WL_KEYBOARD_KEY_STATE_PRESSED ? XKB_KEY_DOWN
+ : XKB_KEY_UP;
+ xkb_state_update_key(xkb->state, key + 8, direction);
+
+ {
+ uint32_t mods_depressed, mods_latched, mods_locked, mods_active;
+ uint32_t group;
+
+ mods_depressed = xkb_state_serialize_mods(xkb->state, XKB_STATE_DEPRESSED);
+ mods_latched = xkb_state_serialize_mods(xkb->state, XKB_STATE_LATCHED);
+ mods_locked = xkb_state_serialize_mods(xkb->state, XKB_STATE_LOCKED);
+ mods_active = mods_depressed | mods_latched;
+
+ group = xkb_state_serialize_layout(xkb->state, XKB_STATE_LAYOUT_EFFECTIVE);
+
+ if (mods_depressed != keyboard->modifiers.mods_depressed
+ || mods_latched != keyboard->modifiers.mods_latched
+ || mods_locked != keyboard->modifiers.mods_locked
+ || group != keyboard->modifiers.group)
+ {
+ if (keyboard->focus.resource)
+ {
+ serial = wl_display_next_serial(display);
+ wl_keyboard_send_modifiers(keyboard->focus.resource, serial,
+ mods_depressed, mods_latched,
+ mods_locked, group);
+ }
+ }
+
+ keyboard->modifiers.mods_depressed = mods_depressed;
+ keyboard->modifiers.mods_latched = mods_latched;
+ keyboard->modifiers.mods_locked = mods_locked;
+ keyboard->modifiers.group = group;
+ }
+}
+
+static void handle_button(struct swc_seat * seat, uint32_t time,
+ uint32_t button, uint32_t state)
+{
+}
+
+static void handle_relative_motion(struct swc_seat * seat, uint32_t time,
+ wl_fixed_t dx, wl_fixed_t dy)
+{
+}
+
+static void handle_evdev_event(struct wl_listener * listener, void * data)
+{
+ struct evdev_device_entry * entry;
+ struct swc_event * event = data;
+ struct swc_evdev_device_event_data * evdev_data = event->data;
+
+ entry = wl_container_of(listener, entry, event_listener);
+
+ switch (event->type)
+ {
+ case SWC_EVDEV_DEVICE_EVENT_KEY:
+ handle_key(entry->seat, evdev_data->time, evdev_data->key.key,
+ evdev_data->key.state);
+ break;
+ case SWC_EVDEV_DEVICE_EVENT_BUTTON:
+ handle_button(entry->seat, evdev_data->time,
+ evdev_data->button.button, evdev_data->button.state);
+ break;
+ case SWC_EVDEV_DEVICE_EVENT_RELATIVE_MOTION:
+ handle_relative_motion(entry->seat, evdev_data->time,
+ evdev_data->relative_motion.dx,
+ evdev_data->relative_motion.dy);
+ break;
+ case SWC_EVDEV_DEVICE_EVENT_ABSOLUTE_MOTION:
+ break;
+ }
+}
+
static void bind_seat(struct wl_client * client, void * data, uint32_t version,
uint32_t id)
{
@@ -40,7 +187,7 @@ static void add_device(struct swc_seat * seat, struct udev_device * udev_device)
{
const char * device_seat;
const char * device_path;
- struct swc_evdev_device * evdev_device;
+ struct evdev_device_entry * entry;
device_seat = udev_device_get_property_value(udev_device, "ID_SEAT");
@@ -51,16 +198,27 @@ static void add_device(struct swc_seat * seat, struct udev_device * udev_device)
if (strcmp(device_seat, seat->name) != 0)
return;
- evdev_device = malloc(sizeof *evdev_device);
+ entry = malloc(sizeof *entry);
- if (!swc_evdev_device_initialize(evdev_device, seat, udev_device))
+ if (!entry)
{
- free(evdev_device);
+ printf("could not allocate evdev device\n");
return;
}
+ entry->seat = seat;
+ entry->event_listener.notify = &handle_evdev_event;
+
+ if (!swc_evdev_device_initialize(&entry->device, udev_device))
+ {
+ free(entry);
+ return;
+ }
+
+ wl_signal_add(&entry->device.event_signal, &entry->event_listener);
+
if (!(seat->capabilities & WL_SEAT_CAPABILITY_POINTER)
- && evdev_device->capabilities & WL_SEAT_CAPABILITY_POINTER)
+ && entry->device.capabilities & WL_SEAT_CAPABILITY_POINTER)
{
printf("initializing pointer\n");
swc_pointer_initialize(&seat->pointer);
@@ -69,7 +227,7 @@ static void add_device(struct swc_seat * seat, struct udev_device * udev_device)
}
if (!(seat->capabilities & WL_SEAT_CAPABILITY_KEYBOARD)
- && evdev_device->capabilities & WL_SEAT_CAPABILITY_KEYBOARD)
+ && entry->device.capabilities & WL_SEAT_CAPABILITY_KEYBOARD)
{
printf("initializing keyboard\n");
swc_keyboard_initialize(&seat->keyboard);
@@ -77,9 +235,9 @@ static void add_device(struct swc_seat * seat, struct udev_device * udev_device)
update_capabilities(seat);
}
- seat->capabilities |= evdev_device->capabilities;
+ seat->capabilities |= entry->device.capabilities;
- wl_list_insert(&seat->devices, &evdev_device->link);
+ wl_list_insert(&seat->devices, &entry->link);
}
bool swc_seat_initialize(struct swc_seat * seat, struct udev * udev,
@@ -109,7 +267,7 @@ bool swc_seat_initialize(struct swc_seat * seat, struct udev * udev,
void swc_seat_finish(struct swc_seat * seat)
{
- struct swc_evdev_device * device, * tmp;
+ struct evdev_device_entry * entry, * tmp;
wl_signal_emit(&seat->destroy_signal, seat);
@@ -122,10 +280,10 @@ void swc_seat_finish(struct swc_seat * seat)
free(seat->name);
swc_xkb_finish(&seat->xkb);
- wl_list_for_each_safe(device, tmp, &seat->devices, link)
+ wl_list_for_each_safe(entry, tmp, &seat->devices, link)
{
- swc_evdev_device_finish(device);
- free(device);
+ swc_evdev_device_finish(&entry->device);
+ free(entry);
}
}
@@ -137,11 +295,11 @@ void swc_seat_add_globals(struct swc_seat * seat, struct wl_display * display)
void swc_seat_add_event_sources(struct swc_seat * seat,
struct wl_event_loop * event_loop)
{
- struct swc_evdev_device * device;
+ struct evdev_device_entry * entry;
- wl_list_for_each(device, &seat->devices, link)
+ wl_list_for_each(entry, &seat->devices, link)
{
- swc_evdev_device_add_event_sources(device, event_loop);
+ swc_evdev_device_add_event_sources(&entry->device, event_loop);
}
}
@@ -169,90 +327,6 @@ void swc_seat_add_devices(struct swc_seat * seat, struct udev * udev)
udev_enumerate_unref(enumerate);
}
-void swc_seat_handle_key(struct swc_seat * seat, uint32_t time, uint32_t key,
- uint32_t state)
-{
- uint32_t * pressed_key;
- struct swc_keyboard * keyboard = &seat->keyboard;
- struct swc_xkb * xkb = &seat->xkb;
- struct wl_display * display;
- uint32_t serial;
- enum xkb_key_direction direction;
-
- /* Update XKB state */
- direction = state == WL_KEYBOARD_KEY_STATE_PRESSED ? XKB_KEY_DOWN
- : XKB_KEY_UP;
-
- /* Apparently these are offset by 8 in X. */
- xkb_state_update_key(xkb->state, key + 8, direction);
-
- if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
- {
- //keyboard->grab_key = key;
- //keyboard->grab_time = time;
- pressed_key = wl_array_add(&keyboard->keys, sizeof key);
- *pressed_key = key;
- }
- else
- {
- wl_array_for_each(pressed_key, &keyboard->keys)
- {
- if (*pressed_key == key)
- {
- /* Remove the key from the array */
- uint32_t bytes_to_copy = keyboard->keys.size + 1
- - (((void *) pressed_key) - keyboard->keys.data);
- memmove(pressed_key, pressed_key + 1, bytes_to_copy);
- --keyboard->keys.size;
- break;
- }
- }
- }
-
- /* See if the key press is not handled by the compositor */
- if (!(keyboard->handler && keyboard->handler->key)
- || !keyboard->handler->key(keyboard, time, key, state))
- {
- if (keyboard->focus.resource)
- {
- serial = wl_display_next_serial(display);
- wl_keyboard_send_key(keyboard->focus.resource, serial, time, key, state);
-
- if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
- printf("\t-> sent to client\n");
- }
- }
-
- {
- uint32_t mods_depressed, mods_latched, mods_locked, mods_active;
- uint32_t layout;
-
- mods_depressed = xkb_state_serialize_mods(xkb->state, XKB_STATE_DEPRESSED);
- mods_latched = xkb_state_serialize_mods(xkb->state, XKB_STATE_LATCHED);
- mods_locked = xkb_state_serialize_mods(xkb->state, XKB_STATE_LOCKED);
- mods_active = mods_depressed | mods_latched;
-
- layout = xkb_state_serialize_layout(xkb->state, XKB_STATE_LAYOUT_EFFECTIVE);
-
- if (mods_depressed != keyboard->modifiers.mods_depressed
- || mods_latched != keyboard->modifiers.mods_latched
- || mods_locked != keyboard->modifiers.mods_locked
- || layout != keyboard->modifiers.group)
- {
- }
-
- keyboard->modifiers.mods_depressed = mods_depressed;
- keyboard->modifiers.mods_latched = mods_latched;
- keyboard->modifiers.mods_locked = mods_locked;
- keyboard->modifiers.group = layout;
- }
-}
-
-void swc_seat_handle_button(struct swc_seat * seat, uint32_t time,
- uint32_t button, uint32_t state)
-{
-}
-
/* Wayland Seat Interface */
void swc_seat_get_pointer(struct wl_client * client,
struct wl_resource * resource, uint32_t id)
diff --git a/seat.h b/seat.h
@@ -38,12 +38,6 @@ void swc_seat_add_event_sources(struct swc_seat * seat,
void swc_seat_add_devices(struct swc_seat * seat, struct udev * udev);
-void swc_seat_handle_key(struct swc_seat * seat, uint32_t time, uint32_t key,
- uint32_t state);
-
-void swc_seat_handle_button(struct swc_seat * seat, uint32_t time,
- uint32_t button, uint32_t state);
-
/* Wayland Seat Interface */
extern struct wl_seat_interface swc_seat_interface;