From 632a04f1b7dea35f46a2fa478bf53869854a1b5e Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 19 Jun 2017 15:15:37 -0400 Subject: [PATCH] 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(-) 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); + } +}