From ecb04afcadc96cc8d39749311e4c1c412bebf4a9 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 19 Jun 2017 14:49:07 -0400 Subject: Implement tablet pads --- backend/libinput/events.c | 14 ++++++- backend/libinput/tablet_pad.c | 95 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 backend/libinput/tablet_pad.c (limited to 'backend/libinput') diff --git a/backend/libinput/events.c b/backend/libinput/events.c index 8ebec63b..2e7cc541 100644 --- a/backend/libinput/events.c +++ b/backend/libinput/events.c @@ -91,7 +91,10 @@ static void handle_device_added(struct wlr_backend_state *state, wl_signal_emit(&state->backend->events.input_add, wlr_device); } if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TABLET_PAD)) { - // TODO + struct wlr_input_device *wlr_device = allocate_device(state, + device, devices, WLR_INPUT_DEVICE_TABLET_PAD); + wlr_device->tablet_pad = wlr_libinput_tablet_pad_create(device); + wl_signal_emit(&state->backend->events.input_add, wlr_device); } if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_GESTURE)) { // TODO @@ -169,6 +172,15 @@ void wlr_libinput_event(struct wlr_backend_state *state, case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: handle_tablet_tool_button(event, device); break; + case LIBINPUT_EVENT_TABLET_PAD_BUTTON: + handle_tablet_pad_button(event, device); + break; + case LIBINPUT_EVENT_TABLET_PAD_RING: + handle_tablet_pad_ring(event, device); + break; + case LIBINPUT_EVENT_TABLET_PAD_STRIP: + handle_tablet_pad_strip(event, device); + break; default: wlr_log(L_DEBUG, "Unknown libinput event %d", event_type); break; diff --git a/backend/libinput/tablet_pad.c b/backend/libinput/tablet_pad.c new file mode 100644 index 00000000..ee7c82f8 --- /dev/null +++ b/backend/libinput/tablet_pad.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include +#include "backend/libinput.h" +#include "common/log.h" +#include "types.h" + +struct wlr_tablet_pad *wlr_libinput_tablet_pad_create( + struct libinput_device *device) { + assert(device); + return wlr_tablet_pad_create(NULL, NULL); +} + +void handle_tablet_pad_button(struct libinput_event *event, + struct libinput_device *device) { + struct wlr_input_device *dev = + get_appropriate_device(WLR_INPUT_DEVICE_TABLET_PAD, device); + if (!dev) { + wlr_log(L_DEBUG, "Got a tablet pad event for a device with no tablet pad?"); + return; + } + struct libinput_event_tablet_pad *pevent = + libinput_event_get_tablet_pad_event(event); + struct wlr_tablet_pad_button *wlr_event = + calloc(1, sizeof(struct wlr_tablet_pad_button)); + wlr_event->time_sec = libinput_event_tablet_pad_get_time(pevent); + wlr_event->time_usec = libinput_event_tablet_pad_get_time_usec(pevent); + wlr_event->button = libinput_event_tablet_pad_get_button_number(pevent); + switch (libinput_event_tablet_pad_get_button_state(pevent)) { + case LIBINPUT_BUTTON_STATE_PRESSED: + wlr_event->state = WLR_BUTTON_PRESSED; + break; + case LIBINPUT_BUTTON_STATE_RELEASED: + wlr_event->state = WLR_BUTTON_RELEASED; + break; + } + wl_signal_emit(&dev->tablet_pad->events.button, wlr_event); +} + +void handle_tablet_pad_ring(struct libinput_event *event, + struct libinput_device *device) { + struct wlr_input_device *dev = + get_appropriate_device(WLR_INPUT_DEVICE_TABLET_PAD, device); + if (!dev) { + wlr_log(L_DEBUG, "Got a tablet pad event for a device with no tablet pad?"); + return; + } + struct libinput_event_tablet_pad *pevent = + libinput_event_get_tablet_pad_event(event); + struct wlr_tablet_pad_ring *wlr_event = + calloc(1, sizeof(struct wlr_tablet_pad_ring)); + wlr_event->time_sec = libinput_event_tablet_pad_get_time(pevent); + wlr_event->time_usec = libinput_event_tablet_pad_get_time_usec(pevent); + wlr_event->ring = libinput_event_tablet_pad_get_ring_number(pevent); + wlr_event->position = libinput_event_tablet_pad_get_ring_position(pevent); + switch (libinput_event_tablet_pad_get_ring_source(pevent)) { + case LIBINPUT_TABLET_PAD_RING_SOURCE_UNKNOWN: + wlr_event->source = WLR_TABLET_PAD_RING_SOURCE_UNKNOWN; + break; + case LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER: + wlr_event->source = WLR_TABLET_PAD_RING_SOURCE_FINGER; + break; + } + wl_signal_emit(&dev->tablet_pad->events.ring, wlr_event); +} + +void handle_tablet_pad_strip(struct libinput_event *event, + struct libinput_device *device) { + struct wlr_input_device *dev = + get_appropriate_device(WLR_INPUT_DEVICE_TABLET_PAD, device); + if (!dev) { + wlr_log(L_DEBUG, "Got a tablet pad event for a device with no tablet pad?"); + return; + } + struct libinput_event_tablet_pad *pevent = + libinput_event_get_tablet_pad_event(event); + struct wlr_tablet_pad_strip *wlr_event = + calloc(1, sizeof(struct wlr_tablet_pad_strip)); + wlr_event->time_sec = libinput_event_tablet_pad_get_time(pevent); + wlr_event->time_usec = libinput_event_tablet_pad_get_time_usec(pevent); + wlr_event->strip = libinput_event_tablet_pad_get_strip_number(pevent); + wlr_event->position = libinput_event_tablet_pad_get_strip_position(pevent); + switch (libinput_event_tablet_pad_get_strip_source(pevent)) { + case LIBINPUT_TABLET_PAD_STRIP_SOURCE_UNKNOWN: + wlr_event->source = WLR_TABLET_PAD_STRIP_SOURCE_UNKNOWN; + break; + case LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER: + wlr_event->source = WLR_TABLET_PAD_STRIP_SOURCE_FINGER; + break; + } + wl_signal_emit(&dev->tablet_pad->events.strip, wlr_event); +} -- cgit v1.2.3 From 632a04f1b7dea35f46a2fa478bf53869854a1b5e Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 19 Jun 2017 15:15:37 -0400 Subject: Implement keyboard LEDs --- backend/libinput/keyboard.c | 23 ++++++++++++++++++++++- example/shared.c | 19 +++++++++++++++++++ example/shared.h | 1 + include/types.h | 1 + include/wlr/types.h | 10 ++++++++++ types/wlr_keyboard.c | 6 ++++++ 6 files changed, 59 insertions(+), 1 deletion(-) (limited to 'backend/libinput') diff --git a/backend/libinput/keyboard.c b/backend/libinput/keyboard.c index 9ad41a78..f94f0103 100644 --- a/backend/libinput/keyboard.c +++ b/backend/libinput/keyboard.c @@ -8,11 +8,32 @@ #include "common/log.h" #include "types.h" +struct wlr_keyboard_state { + struct libinput_device *device; +}; + +static void wlr_libinput_keyboard_set_leds(struct wlr_keyboard_state *kbstate, uint32_t leds) { + libinput_device_led_update(kbstate->device, leds); +} + +static void wlr_libinput_keyboard_destroy(struct wlr_keyboard_state *kbstate) { + libinput_device_unref(kbstate->device); + free(kbstate); +} + +struct wlr_keyboard_impl impl = { + .destroy = wlr_libinput_keyboard_destroy, + .led_update = wlr_libinput_keyboard_set_leds +}; + struct wlr_keyboard *wlr_libinput_keyboard_create( struct libinput_device *device) { assert(device); + struct wlr_keyboard_state *kbstate = calloc(1, sizeof(struct wlr_keyboard_state)); + kbstate->device = device; + libinput_device_ref(device); libinput_device_led_update(device, 0); - return wlr_keyboard_create(NULL, NULL); + return wlr_keyboard_create(&impl, kbstate); } void handle_keyboard_key(struct libinput_event *event, diff --git a/example/shared.c b/example/shared.c index 56cb89af..be1bdee7 100644 --- a/example/shared.c +++ b/example/shared.c @@ -12,6 +12,16 @@ #include #include "shared.h" +static void keyboard_led_update(struct keyboard_state *kbstate) { + uint32_t leds = 0; + for (uint32_t i = 0; i < WLR_LED_LAST; ++i) { + if (xkb_state_led_index_is_active(kbstate->xkb_state, kbstate->leds[i])) { + leds |= (1 << i); + } + } + wlr_keyboard_led_update(kbstate->device->keyboard, leds); +} + static void keyboard_key_notify(struct wl_listener *listener, void *data) { struct wlr_keyboard_key *event = data; struct keyboard_state *kbstate = wl_container_of(listener, kbstate, key); @@ -33,6 +43,7 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { } xkb_state_update_key(kbstate->xkb_state, keycode, event->state == WLR_KEY_PRESSED ? XKB_KEY_DOWN : XKB_KEY_UP); + keyboard_led_update(kbstate); } static void keyboard_add(struct wlr_input_device *device, struct compositor_state *state) { @@ -68,6 +79,14 @@ static void keyboard_add(struct wlr_input_device *device, struct compositor_stat fprintf(stderr, "Failed to create XKB state\n"); exit(1); } + const char *led_names[3] = { + XKB_LED_NAME_NUM, + XKB_LED_NAME_CAPS, + XKB_LED_NAME_SCROLL + }; + for (uint32_t i = 0; i < 3; ++i) { + kbstate->leds[i] = xkb_map_led_get_index(kbstate->keymap, led_names[i]); + } } static void pointer_motion_notify(struct wl_listener *listener, void *data) { diff --git a/example/shared.h b/example/shared.h index 173a5719..6d533443 100644 --- a/example/shared.h +++ b/example/shared.h @@ -25,6 +25,7 @@ struct keyboard_state { struct wl_list link; struct xkb_keymap *keymap; struct xkb_state *xkb_state; + xkb_led_index_t leds[WLR_LED_LAST]; void *data; }; diff --git a/include/types.h b/include/types.h index 2063c3f5..54aa5606 100644 --- a/include/types.h +++ b/include/types.h @@ -23,6 +23,7 @@ void wlr_output_free(struct wlr_output *output); struct wlr_keyboard_impl { void (*destroy)(struct wlr_keyboard_state *state); + void (*led_update)(struct wlr_keyboard_state *state, uint32_t leds); }; struct wlr_keyboard *wlr_keyboard_create(struct wlr_keyboard_impl *impl, diff --git a/include/wlr/types.h b/include/wlr/types.h index 2ca73cc2..1d2abab5 100644 --- a/include/wlr/types.h +++ b/include/wlr/types.h @@ -53,18 +53,28 @@ void wlr_output_destroy(struct wlr_output *output); void wlr_output_effective_resolution(struct wlr_output *output, int *width, int *height); +enum WLR_KEYBOARD_LED { + WLR_LED_NUM_LOCK = 1, + WLR_LED_CAPS_LOCK = 2, + WLR_LED_SCROLL_LOCK = 4, + WLR_LED_LAST +}; + struct wlr_keyboard_state; struct wlr_keyboard_impl; struct wlr_keyboard { struct wlr_keyboard_state *state; struct wlr_keyboard_impl *impl; + uint32_t leds; struct { struct wl_signal key; } events; }; +void wlr_keyboard_led_update(struct wlr_keyboard *keyboard, uint32_t leds); + enum wlr_key_state { WLR_KEY_RELEASED, WLR_KEY_PRESSED, diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index 32728c78..c2ad5c49 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -21,3 +21,9 @@ void wlr_keyboard_destroy(struct wlr_keyboard *kb) { } free(kb); } + +void wlr_keyboard_led_update(struct wlr_keyboard *kb, uint32_t leds) { + if (kb->impl) { + kb->impl->led_update(kb->state, leds); + } +} -- cgit v1.2.3