swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

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:
Mevdev_device.c | 74+++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Mevdev_device.h | 58++++++++++++++++++++++++++++++++++++++++++++++------------
Mseat.c | 272++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Mseat.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;