diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index 97517cbe..2d9f1490 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -6,13 +6,16 @@ #include #include +#define WLR_LED_COUNT 3 + enum wlr_keyboard_led { WLR_LED_NUM_LOCK = 1, WLR_LED_CAPS_LOCK = 2, WLR_LED_SCROLL_LOCK = 4, - WLR_LED_LAST }; +#define WLR_MODIFIER_COUNT 8 + enum wlr_keyboard_modifier { WLR_MODIFIER_SHIFT = 1, WLR_MODIFIER_CAPS = 2, @@ -22,7 +25,6 @@ enum wlr_keyboard_modifier { WLR_MODIFIER_MOD3 = 32, WLR_MODIFIER_LOGO = 64, WLR_MODIFIER_MOD5 = 128, - WLR_MODIFIER_LAST }; struct wlr_keyboard_impl; @@ -35,8 +37,8 @@ struct wlr_keyboard { size_t keymap_size; struct xkb_keymap *keymap; struct xkb_state *xkb_state; - xkb_led_index_t led_indexes[WLR_LED_LAST]; - xkb_mod_index_t mod_indexes[WLR_MODIFIER_LAST]; + xkb_led_index_t led_indexes[WLR_LED_COUNT]; + xkb_mod_index_t mod_indexes[WLR_MODIFIER_COUNT]; struct { xkb_mod_mask_t depressed; @@ -53,8 +55,6 @@ struct wlr_keyboard { void *data; }; -void wlr_keyboard_led_update(struct wlr_keyboard *keyboard, uint32_t leds); - enum wlr_key_state { WLR_KEY_RELEASED, WLR_KEY_PRESSED, @@ -69,5 +69,7 @@ struct wlr_event_keyboard_key { void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, struct xkb_keymap *keymap); +void wlr_keyboard_led_update(struct wlr_keyboard *keyboard, uint32_t leds); +uint32_t wlr_keyboard_get_modifiers(struct wlr_keyboard *keyboard); #endif diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index dc3b8f8e..4d7f215c 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -12,7 +12,7 @@ int os_create_anonymous_file(off_t size); static void keyboard_led_update(struct wlr_keyboard *keyboard) { uint32_t leds = 0; - for (uint32_t i = 0; i < WLR_LED_LAST; ++i) { + for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) { if (xkb_state_led_index_is_active(keyboard->xkb_state, keyboard->led_indexes[i])) { leds |= (1 << i); @@ -21,37 +21,12 @@ static void keyboard_led_update(struct wlr_keyboard *keyboard) { wlr_keyboard_led_update(keyboard, leds); } -static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { - xkb_mod_mask_t depressed = xkb_state_serialize_mods(keyboard->xkb_state, - XKB_STATE_DEPRESSED); - xkb_mod_mask_t latched = xkb_state_serialize_mods(keyboard->xkb_state, - XKB_STATE_LATCHED); - xkb_mod_mask_t locked = xkb_state_serialize_mods(keyboard->xkb_state, - XKB_STATE_LOCKED); - xkb_mod_mask_t group = xkb_state_serialize_layout(keyboard->xkb_state, - XKB_STATE_LAYOUT_EFFECTIVE); - if (depressed == keyboard->modifiers.depressed && - latched == keyboard->modifiers.latched && - locked == keyboard->modifiers.locked && - group == keyboard->modifiers.group) { - return; - } - - keyboard->modifiers.depressed = depressed; - keyboard->modifiers.latched = latched; - keyboard->modifiers.locked = locked; - keyboard->modifiers.group = group; - - // TODO: wl_keyboard_send_modifiers -} - void wlr_keyboard_update_state(struct wlr_keyboard *keyboard, struct wlr_event_keyboard_key *event) { uint32_t keycode = event->keycode + 8; xkb_state_update_key(keyboard->xkb_state, keycode, event->state == WLR_KEY_PRESSED ? XKB_KEY_DOWN : XKB_KEY_UP); keyboard_led_update(keyboard); - keyboard_modifier_update(keyboard); wl_signal_emit(&keyboard->events.key, event); } @@ -84,16 +59,16 @@ void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, kb->keymap = keymap; assert(kb->xkb_state = xkb_state_new(kb->keymap)); - const char *led_names[WLR_LED_LAST] = { + const char *led_names[WLR_LED_COUNT] = { XKB_LED_NAME_NUM, XKB_LED_NAME_CAPS, - XKB_LED_NAME_SCROLL + XKB_LED_NAME_SCROLL, }; - for (size_t i = 0; i < WLR_LED_LAST; ++i) { + for (size_t i = 0; i < WLR_LED_COUNT; ++i) { kb->led_indexes[i] = xkb_map_led_get_index(kb->keymap, led_names[i]); } - const char *mod_names[WLR_MODIFIER_LAST] = { + const char *mod_names[WLR_MODIFIER_COUNT] = { XKB_MOD_NAME_SHIFT, XKB_MOD_NAME_CAPS, XKB_MOD_NAME_CTRL, // "Control" @@ -104,7 +79,7 @@ void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, "Mod5", }; // TODO: there's also "Ctrl", "Alt"? - for (size_t i = 0; i < WLR_LED_LAST; ++i) { + for (size_t i = 0; i < WLR_MODIFIER_COUNT; ++i) { kb->mod_indexes[i] = xkb_map_mod_get_index(kb->keymap, mod_names[i]); } @@ -119,3 +94,15 @@ void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, wl_signal_emit(&kb->events.keymap, kb); } + +uint32_t wlr_keyboard_get_modifiers(struct wlr_keyboard *kb) { + xkb_mod_mask_t mask = kb->modifiers.depressed | kb->modifiers.latched; + uint32_t modifiers = 0; + for (size_t i = 0; i < WLR_MODIFIER_COUNT; ++i) { + if (kb->mod_indexes[i] != XKB_MOD_INVALID && + (mask & (1 << kb->mod_indexes[i]))) { + modifiers |= (1 << i); + } + } + return modifiers; +} diff --git a/types/wlr_seat.c b/types/wlr_seat.c index aaff6005..ff050223 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -391,9 +391,9 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { // TODO: We should probably lift all of the keys set by the other // keyboard wl_keyboard_send_keymap(handle->keyboard, - WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, - seat_kb->keyboard->keymap_fd, - seat_kb->keyboard->keymap_size); + WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, + seat_kb->keyboard->keymap_fd, + seat_kb->keyboard->keymap_size); if (wl_resource_get_version(handle->keyboard) >= 2) { // TODO: Make this better @@ -402,21 +402,31 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { handle->seat_keyboard = seat_kb; } - uint32_t depressed = xkb_state_serialize_mods(keyboard->xkb_state, + xkb_mod_mask_t depressed = xkb_state_serialize_mods(keyboard->xkb_state, XKB_STATE_MODS_DEPRESSED); - uint32_t latched = xkb_state_serialize_mods(keyboard->xkb_state, + xkb_mod_mask_t latched = xkb_state_serialize_mods(keyboard->xkb_state, XKB_STATE_MODS_LATCHED); - uint32_t locked = xkb_state_serialize_mods(keyboard->xkb_state, + xkb_mod_mask_t locked = xkb_state_serialize_mods(keyboard->xkb_state, XKB_STATE_MODS_LOCKED); - uint32_t group = xkb_state_serialize_layout(keyboard->xkb_state, + xkb_mod_mask_t group = xkb_state_serialize_layout(keyboard->xkb_state, XKB_STATE_LAYOUT_EFFECTIVE); + if (depressed != keyboard->modifiers.depressed || + latched != keyboard->modifiers.latched || + locked != keyboard->modifiers.locked || + group != keyboard->modifiers.group) { + keyboard->modifiers.depressed = depressed; + keyboard->modifiers.latched = latched; + keyboard->modifiers.locked = locked; + keyboard->modifiers.group = group; + + uint32_t modifiers_serial = wl_display_next_serial(seat->display); + wl_keyboard_send_modifiers(handle->keyboard, modifiers_serial, depressed, + latched, locked, group); + } - uint32_t modifiers_serial = wl_display_next_serial(seat->display); uint32_t key_serial = wl_display_next_serial(seat->display); - wl_keyboard_send_modifiers(handle->keyboard, modifiers_serial, - depressed, latched, locked, group); wl_keyboard_send_key(handle->keyboard, key_serial, - (uint32_t)event->time_usec, event->keycode, key_state); + (uint32_t)event->time_usec, event->keycode, key_state); } static void keyboard_keymap_notify(struct wl_listener *listener, void *data) {