From 59ceaf507e9a7c80e04460d1ae4946ce7b6f56ac Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 9 Jun 2017 17:52:11 -0400 Subject: [PATCH] Handle key presses --- backend/libinput/backend.c | 14 ++++++++-- backend/libinput/events.c | 56 +++++++++++++++++++++++++++++++++++--- example/simple.c | 9 ++++++ include/wlr/types.h | 26 ++++++++++++++++-- 4 files changed, 95 insertions(+), 10 deletions(-) diff --git a/backend/libinput/backend.c b/backend/libinput/backend.c index 3af088754..dc018b105 100644 --- a/backend/libinput/backend.c +++ b/backend/libinput/backend.c @@ -99,7 +99,12 @@ struct wlr_backend *wlr_libinput_backend_create(struct wl_display *display, struct wlr_backend *backend = wlr_backend_create(&backend_impl, state); if (!backend) { wlr_log(L_ERROR, "Allocation failed: %s", strerror(errno)); - return NULL; + goto error_state; + } + + if (!(state->keyboards = list_create())) { + wlr_log(L_ERROR, "Allocation failed: %s", strerror(errno)); + goto error_backend; } state->backend = backend; @@ -107,7 +112,10 @@ struct wlr_backend *wlr_libinput_backend_create(struct wl_display *display, state->udev = udev; state->display = display; - state->keyboards = list_create(); - return backend; +error_state: + free(state); +error_backend: + wlr_backend_destroy(backend); + return NULL; } diff --git a/backend/libinput/events.c b/backend/libinput/events.c index b4816928f..c31632b50 100644 --- a/backend/libinput/events.c +++ b/backend/libinput/events.c @@ -8,6 +8,22 @@ #include "common/log.h" #include "types.h" +static struct wlr_input_device *get_appropriate_device( + enum wlr_input_device_type desired_type, + struct libinput_device *device) { + list_t *devices = libinput_device_get_user_data(device); + if (!devices) { + return NULL; + } + for (size_t i = 0; i < devices->length; ++i) { + struct wlr_input_device *dev = devices->items[i]; + if (dev->type == desired_type) { + return dev; + } + } + return NULL; +} + static void wlr_libinput_keyboard_destroy(struct wlr_keyboard_state *state) { free(state); } @@ -22,10 +38,39 @@ static struct wlr_keyboard *wlr_libinput_keyboard_create( struct wlr_keyboard_state *kbstate = calloc(1, sizeof(struct wlr_keyboard_state)); kbstate->handle = device; + libinput_device_ref(device); return wlr_keyboard_create(&keyboard_impl, kbstate); } -static void device_added(struct wlr_backend_state *state, +static void handle_keyboard_key(struct libinput_event *event, + struct libinput_device *device) { + struct wlr_input_device *dev = + get_appropriate_device(WLR_INPUT_DEVICE_KEYBOARD, device); + if (!dev) { + wlr_log(L_DEBUG, "Got a keyboard event for a device with no keyboards?"); + return; + } + struct libinput_event_keyboard *kbevent = + libinput_event_get_keyboard_event(event); + struct wlr_keyboard_key *wlr_event = + calloc(1, sizeof(struct wlr_keyboard_key)); + wlr_event->time_sec = libinput_event_keyboard_get_time(kbevent); + wlr_event->time_usec = libinput_event_keyboard_get_time_usec(kbevent); + wlr_event->keycode = libinput_event_keyboard_get_key(kbevent); + enum libinput_key_state state = + libinput_event_keyboard_get_key_state(kbevent); + switch (state) { + case LIBINPUT_KEY_STATE_RELEASED: + wlr_event->state = WLR_KEY_RELEASED; + break; + case LIBINPUT_KEY_STATE_PRESSED: + wlr_event->state = WLR_KEY_PRESSED; + break; + } + wl_signal_emit(&dev->keyboard->events.key, wlr_event); +} + +static void handle_device_added(struct wlr_backend_state *state, struct libinput_device *device) { assert(state && device); /* @@ -73,7 +118,7 @@ static void device_added(struct wlr_backend_state *state, } } -static void device_removed(struct wlr_backend_state *state, +static void handle_device_removed(struct wlr_backend_state *state, struct libinput_device *device) { wlr_log(L_DEBUG, "libinput device removed"); // TODO @@ -88,10 +133,13 @@ void wlr_libinput_event(struct wlr_backend_state *state, (void)context; switch (event_type) { case LIBINPUT_EVENT_DEVICE_ADDED: - device_added(state, device); + handle_device_added(state, device); break; case LIBINPUT_EVENT_DEVICE_REMOVED: - device_removed(state, device); + handle_device_removed(state, device); + break; + case LIBINPUT_EVENT_KEYBOARD_KEY: + handle_keyboard_key(event, device); break; default: wlr_log(L_DEBUG, "Unknown libinput event %d", event_type); diff --git a/example/simple.c b/example/simple.c index 3206b3fa6..660c56a64 100644 --- a/example/simple.c +++ b/example/simple.c @@ -97,6 +97,13 @@ void output_remove(struct wl_listener *listener, void *data) { wl_list_remove(&ostate->frame.link); } +static void keyboard_key(struct wl_listener *listener, void *data) { + struct wlr_keyboard_key *event = data; + struct keyboard_state *kbstate = wl_container_of(listener, kbstate, key); + fprintf(stderr, "Key event: %u %s\n", event->keycode, + event->state == WLR_KEY_PRESSED ? "pressed" : "released"); +} + void input_add(struct wl_listener *listener, void *data) { struct wlr_input_device *device = data; struct state *state = wl_container_of(listener, state, input_add); @@ -109,6 +116,8 @@ void input_add(struct wl_listener *listener, void *data) { kbstate->device = device; wl_list_init(&kbstate->key.link); wl_list_init(&kbstate->mods.link); + kbstate->key.notify = keyboard_key; + wl_signal_add(&device->keyboard->events.key, &kbstate->key); wl_list_insert(&state->keyboards, &kbstate->link); } diff --git a/include/wlr/types.h b/include/wlr/types.h index a65b5d9cd..e2f3075f2 100644 --- a/include/wlr/types.h +++ b/include/wlr/types.h @@ -65,6 +65,18 @@ struct wlr_keyboard { } events; }; +enum wlr_key_state { + WLR_KEY_RELEASED, + WLR_KEY_PRESSED, +}; + +struct wlr_keyboard_key { + uint32_t time_sec; + uint64_t time_usec; + uint32_t keycode; + enum wlr_key_state state; +}; + struct wlr_pointer_state; struct wlr_pointer_impl; @@ -81,20 +93,26 @@ struct wlr_pointer { }; struct wlr_pointer_motion { + uint32_t time_sec; + uint64_t time_usec; double delta_x, delta_y; }; struct wlr_pointer_motion_absolute { + uint32_t time_sec; + uint64_t time_usec; double x_mm, y_mm; double width_mm, height_mm; }; enum wlr_button_state { - WLR_BUTTON_DEPRESSED, - WLR_BUTTON_RELEASED + WLR_BUTTON_RELEASED, + WLR_BUTTON_PRESSED, }; struct wlr_pointer_button { + uint32_t time_sec; + uint64_t time_usec; uint32_t button; enum wlr_button_state state; }; @@ -108,10 +126,12 @@ enum wlr_axis_source { enum wlr_axis_orientation { WLR_AXIS_ORIENTATION_VERTICAL, - WLR_AXIS_ORIENTATION_HORIZONTAL + WLR_AXIS_ORIENTATION_HORIZONTAL, }; struct wlr_pointer_axis { + uint32_t time_sec; + uint64_t time_usec; enum wlr_axis_source source; enum wlr_axis_orientation orientation; double delta;