From 2fccff16eb48fbf57f9ad237e3dc748676d9fb03 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 2 Oct 2017 19:23:30 +0200 Subject: Begin modifiers support --- include/wlr/types/wlr_keyboard.h | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'include/wlr') diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index af205c63..97517cbe 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -6,13 +6,25 @@ #include #include -enum WLR_KEYBOARD_LED { +enum wlr_keyboard_led { WLR_LED_NUM_LOCK = 1, WLR_LED_CAPS_LOCK = 2, WLR_LED_SCROLL_LOCK = 4, WLR_LED_LAST }; +enum wlr_keyboard_modifier { + WLR_MODIFIER_SHIFT = 1, + WLR_MODIFIER_CAPS = 2, + WLR_MODIFIER_CTRL = 4, + WLR_MODIFIER_ALT = 8, + WLR_MODIFIER_MOD2 = 16, + WLR_MODIFIER_MOD3 = 32, + WLR_MODIFIER_LOGO = 64, + WLR_MODIFIER_MOD5 = 128, + WLR_MODIFIER_LAST +}; + struct wlr_keyboard_impl; struct wlr_keyboard { @@ -23,7 +35,15 @@ struct wlr_keyboard { size_t keymap_size; struct xkb_keymap *keymap; struct xkb_state *xkb_state; - xkb_led_index_t leds[WLR_LED_LAST]; + xkb_led_index_t led_indexes[WLR_LED_LAST]; + xkb_mod_index_t mod_indexes[WLR_MODIFIER_LAST]; + + struct { + xkb_mod_mask_t depressed; + xkb_mod_mask_t latched; + xkb_mod_mask_t locked; + xkb_mod_mask_t group; + } modifiers; struct { struct wl_signal key; @@ -48,6 +68,6 @@ struct wlr_event_keyboard_key { }; void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, - struct xkb_keymap *keymap); + struct xkb_keymap *keymap); #endif -- cgit v1.2.3 From 3a8fdebaaa819f7b27b51e507cccff638b4939ae Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 2 Oct 2017 20:21:47 +0200 Subject: Fix modifiers handling, add wlr_keyboard_get_modifiers --- include/wlr/types/wlr_keyboard.h | 14 +++++++----- types/wlr_keyboard.c | 49 +++++++++++++++------------------------- types/wlr_seat.c | 32 +++++++++++++++++--------- 3 files changed, 47 insertions(+), 48 deletions(-) (limited to 'include/wlr') 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) { -- cgit v1.2.3 From d3d9aca40cfccf7f3d03a3111f732c884aab8766 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 3 Oct 2017 08:40:10 +0200 Subject: Add modifiers support in wayland backend, parse modifiers in rootston config --- backend/wayland/wl_seat.c | 4 +++ include/rootston/config.h | 1 + include/wlr/interfaces/wlr_keyboard.h | 3 +++ rootston/config.c | 48 +++++++++++++++++++++++++---------- rootston/keyboard.c | 5 ++++ types/wlr_keyboard.c | 9 +++++++ 6 files changed, 57 insertions(+), 13 deletions(-) (limited to 'include/wlr') diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index ba3feb8d..44ce6028 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -155,7 +155,11 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { + struct wlr_input_device *dev = data; + assert(dev && dev->keyboard); + wlr_keyboard_update_modifiers(dev->keyboard, mods_depressed, mods_latched, + mods_locked, group); } static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, diff --git a/include/rootston/config.h b/include/rootston/config.h index ef101f2d..ece11829 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -19,6 +19,7 @@ struct device_config { }; struct binding_config { + uint32_t modifiers; xkb_keysym_t *keysyms; size_t keysyms_len; char *command; diff --git a/include/wlr/interfaces/wlr_keyboard.h b/include/wlr/interfaces/wlr_keyboard.h index 78c1f753..9755267a 100644 --- a/include/wlr/interfaces/wlr_keyboard.h +++ b/include/wlr/interfaces/wlr_keyboard.h @@ -13,5 +13,8 @@ void wlr_keyboard_init(struct wlr_keyboard *keyboard, struct wlr_keyboard_impl * void wlr_keyboard_destroy(struct wlr_keyboard *keyboard); void wlr_keyboard_update_state(struct wlr_keyboard *keyboard, struct wlr_event_keyboard_key *event); +void wlr_keyboard_update_modifiers(struct wlr_keyboard *keyboard, + uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, + uint32_t group); #endif diff --git a/rootston/config.c b/rootston/config.c index a80a8304..3a21aff3 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -177,28 +177,49 @@ static int config_ini_handler(void *user, const char *section, const char *name, bc->command = strdup(value); - bc->keysyms_len = 1; + size_t keysyms_len = 1; char *symnames = strdup(name); for (char *c = symnames; *c != '\0'; c++) { if (*c == '+') { *c = '\0'; - bc->keysyms_len++; + keysyms_len++; } } - bc->keysyms = calloc(1, bc->keysyms_len * sizeof(xkb_keysym_t)); + // TODO: bc->keysyms is larger than needed + bc->keysyms = calloc(1, keysyms_len * sizeof(xkb_keysym_t)); char *symname = symnames; - for (size_t i = 0; i < bc->keysyms_len; i++) { - xkb_keysym_t sym = xkb_keysym_from_name(symname, - XKB_KEYSYM_NO_FLAGS); - if (sym == XKB_KEY_NoSymbol) { - wlr_log(L_ERROR, "got unknown key binding symbol: %s", symname); - wl_list_remove(&bc->link); - free(bc->keysyms); - free(bc); - break; + for (size_t i = 0; i < keysyms_len; i++) { + if (strcmp(symname, "Shift") == 0) { + bc->modifiers |= WLR_MODIFIER_SHIFT; + } else if (strcmp(symname, "Caps") == 0) { + bc->modifiers |= WLR_MODIFIER_CAPS; + } else if (strcmp(symname, "Ctrl") == 0) { + bc->modifiers |= WLR_MODIFIER_CTRL; + } else if (strcmp(symname, "Alt") == 0) { + bc->modifiers |= WLR_MODIFIER_ALT; + } else if (strcmp(symname, "Mod2") == 0) { + bc->modifiers |= WLR_MODIFIER_MOD2; + } else if (strcmp(symname, "Mod3") == 0) { + bc->modifiers |= WLR_MODIFIER_MOD3; + } else if (strcmp(symname, "Logo") == 0) { + bc->modifiers |= WLR_MODIFIER_LOGO; + } else if (strcmp(symname, "Mod5") == 0) { + bc->modifiers |= WLR_MODIFIER_MOD5; + } else { + xkb_keysym_t sym = xkb_keysym_from_name(symname, + XKB_KEYSYM_NO_FLAGS); + if (sym == XKB_KEY_NoSymbol) { + wlr_log(L_ERROR, "got unknown key binding symbol: %s", + symname); + wl_list_remove(&bc->link); + free(bc->keysyms); + free(bc); + break; + } + bc->keysyms[bc->keysyms_len] = sym; + bc->keysyms_len++; } - bc->keysyms[i] = sym; symname += strlen(symname) + 1; } @@ -249,6 +270,7 @@ struct roots_config *parse_args(int argc, char *argv[]) { struct binding_config *bc = calloc(1, sizeof(struct binding_config)); wl_list_insert(&config->bindings, &bc->link); bc->command = strdup("exit"); + bc->modifiers = WLR_MODIFIER_LOGO; bc->keysyms_len = 2; bc->keysyms = calloc(1, bc->keysyms_len * sizeof(xkb_keysym_t)); bc->keysyms[0] = XKB_KEY_Meta_L; diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 5ac6e59b..6f6fa0e8 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -61,9 +61,14 @@ static void keyboard_keysym_press(struct roots_keyboard *keyboard, return; } + uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); struct wl_list *bindings = &keyboard->input->server->config->bindings; struct binding_config *bc; wl_list_for_each(bc, bindings, link) { + if (modifiers ^ bc->modifiers) { + continue; + } + bool ok = true; for (size_t i = 0; i < bc->keysyms_len; i++) { ssize_t j = keyboard_pressed_keysym_index(keyboard, bc->keysyms[i]); diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index 4d7f215c..9c111af4 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -30,6 +30,15 @@ void wlr_keyboard_update_state(struct wlr_keyboard *keyboard, wl_signal_emit(&keyboard->events.key, event); } +void wlr_keyboard_update_modifiers(struct wlr_keyboard *keyboard, + uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, + uint32_t group) { + keyboard->modifiers.depressed = mods_depressed; + keyboard->modifiers.latched = mods_latched; + keyboard->modifiers.locked = mods_locked; + keyboard->modifiers.group = group; +} + void wlr_keyboard_init(struct wlr_keyboard *kb, struct wlr_keyboard_impl *impl) { kb->impl = impl; -- cgit v1.2.3 From 521e893528eb68691fad4944257fd073619d6338 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 3 Oct 2017 14:03:26 +0200 Subject: Add modifiers signal, remove wlr_keyboard_update_modifiers --- backend/wayland/wl_seat.c | 4 --- include/wlr/interfaces/wlr_keyboard.h | 3 -- include/wlr/types/wlr_keyboard.h | 1 + include/wlr/types/wlr_seat.h | 1 + types/wlr_keyboard.c | 40 +++++++++++----------- types/wlr_seat.c | 64 ++++++++++++++++++++++++----------- 6 files changed, 67 insertions(+), 46 deletions(-) (limited to 'include/wlr') diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 44ce6028..ba3feb8d 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -155,11 +155,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { - struct wlr_input_device *dev = data; - assert(dev && dev->keyboard); - wlr_keyboard_update_modifiers(dev->keyboard, mods_depressed, mods_latched, - mods_locked, group); } static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, diff --git a/include/wlr/interfaces/wlr_keyboard.h b/include/wlr/interfaces/wlr_keyboard.h index 9755267a..78c1f753 100644 --- a/include/wlr/interfaces/wlr_keyboard.h +++ b/include/wlr/interfaces/wlr_keyboard.h @@ -13,8 +13,5 @@ void wlr_keyboard_init(struct wlr_keyboard *keyboard, struct wlr_keyboard_impl * void wlr_keyboard_destroy(struct wlr_keyboard *keyboard); void wlr_keyboard_update_state(struct wlr_keyboard *keyboard, struct wlr_event_keyboard_key *event); -void wlr_keyboard_update_modifiers(struct wlr_keyboard *keyboard, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group); #endif diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index 2d9f1490..9ec8ddd4 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -49,6 +49,7 @@ struct wlr_keyboard { struct { struct wl_signal key; + struct wl_signal modifiers; struct wl_signal keymap; } events; diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index 6927cd16..489bd529 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -37,6 +37,7 @@ struct wlr_seat_keyboard { struct wlr_seat *seat; struct wlr_keyboard *keyboard; struct wl_listener key; + struct wl_listener modifiers; struct wl_listener keymap; struct wl_listener destroy; struct wl_list link; diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index 168475bd..f51ea8c4 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -21,19 +21,28 @@ static void keyboard_led_update(struct wlr_keyboard *keyboard) { wlr_keyboard_led_update(keyboard, leds); } -void wlr_keyboard_update_modifiers(struct wlr_keyboard *keyboard, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group) { - if (mods_depressed == keyboard->modifiers.depressed && - mods_latched == keyboard->modifiers.latched && - mods_locked == keyboard->modifiers.locked && +static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { + xkb_mod_mask_t depressed = xkb_state_serialize_mods(keyboard->xkb_state, + XKB_STATE_MODS_DEPRESSED); + xkb_mod_mask_t latched = xkb_state_serialize_mods(keyboard->xkb_state, + XKB_STATE_MODS_LATCHED); + xkb_mod_mask_t locked = xkb_state_serialize_mods(keyboard->xkb_state, + XKB_STATE_MODS_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 = mods_depressed; - keyboard->modifiers.latched = mods_latched; - keyboard->modifiers.locked = mods_locked; + + keyboard->modifiers.depressed = depressed; + keyboard->modifiers.latched = latched; + keyboard->modifiers.locked = locked; keyboard->modifiers.group = group; + + wl_signal_emit(&keyboard->events.modifiers, keyboard); } void wlr_keyboard_update_state(struct wlr_keyboard *keyboard, @@ -42,17 +51,7 @@ void wlr_keyboard_update_state(struct wlr_keyboard *keyboard, xkb_state_update_key(keyboard->xkb_state, keycode, event->state == WLR_KEY_PRESSED ? XKB_KEY_DOWN : XKB_KEY_UP); keyboard_led_update(keyboard); - - xkb_mod_mask_t depressed = xkb_state_serialize_mods(keyboard->xkb_state, - XKB_STATE_MODS_DEPRESSED); - xkb_mod_mask_t latched = xkb_state_serialize_mods(keyboard->xkb_state, - XKB_STATE_MODS_LATCHED); - xkb_mod_mask_t locked = xkb_state_serialize_mods(keyboard->xkb_state, - XKB_STATE_MODS_LOCKED); - xkb_mod_mask_t group = xkb_state_serialize_layout(keyboard->xkb_state, - XKB_STATE_LAYOUT_EFFECTIVE); - wlr_keyboard_update_modifiers(keyboard, depressed, latched, locked, group); - + keyboard_modifier_update(keyboard); wl_signal_emit(&keyboard->events.key, event); } @@ -60,6 +59,7 @@ void wlr_keyboard_init(struct wlr_keyboard *kb, struct wlr_keyboard_impl *impl) { kb->impl = impl; wl_signal_init(&kb->events.key); + wl_signal_init(&kb->events.modifiers); wl_signal_init(&kb->events.keymap); } diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 66b2f18e..2702f1b5 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -376,39 +376,61 @@ void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time, wl_pointer_send_frame(pointer); } +static void keyboard_switch_seat_keyboard(struct wlr_seat_handle *handle, + struct wlr_seat_keyboard *seat_kb) { + if (handle->seat_keyboard == seat_kb) { + return; + } + + // 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); + + if (wl_resource_get_version(handle->keyboard) >= 2) { + // TODO: Make this better + wl_keyboard_send_repeat_info(handle->keyboard, 25, 600); + } + handle->seat_keyboard = seat_kb; +} + static void keyboard_key_notify(struct wl_listener *listener, void *data) { - struct wlr_seat_keyboard *seat_kb = wl_container_of( - listener, seat_kb, key); + struct wlr_seat_keyboard *seat_kb = wl_container_of(listener, seat_kb, key); struct wlr_seat *seat = seat_kb->seat; struct wlr_seat_handle *handle = seat->keyboard_state.focused_handle; if (!handle || !handle->keyboard) { return; } - struct wlr_keyboard *keyboard = seat_kb->keyboard; + + keyboard_switch_seat_keyboard(handle, seat_kb); + struct wlr_event_keyboard_key *event = data; enum wlr_key_state key_state = event->state; - if (handle->seat_keyboard != seat_kb) { - // 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); - - if (wl_resource_get_version(handle->keyboard) >= 2) { - // TODO: Make this better - wl_keyboard_send_repeat_info(handle->keyboard, 25, 600); - } - handle->seat_keyboard = seat_kb; + + uint32_t key_serial = wl_display_next_serial(seat->display); + wl_keyboard_send_key(handle->keyboard, key_serial, + (uint32_t)event->time_usec, event->keycode, key_state); +} + +static void keyboard_modifiers_notify(struct wl_listener *listener, + void *data) { + struct wlr_seat_keyboard *seat_kb = wl_container_of(listener, seat_kb, + modifiers); + struct wlr_seat *seat = seat_kb->seat; + struct wlr_seat_handle *handle = seat->keyboard_state.focused_handle; + if (!handle || !handle->keyboard) { + return; } + keyboard_switch_seat_keyboard(handle, seat_kb); + + struct wlr_keyboard *keyboard = seat_kb->keyboard; + uint32_t modifiers_serial = wl_display_next_serial(seat->display); wl_keyboard_send_modifiers(handle->keyboard, modifiers_serial, keyboard->modifiers.depressed, keyboard->modifiers.latched, keyboard->modifiers.locked, keyboard->modifiers.group); - uint32_t key_serial = wl_display_next_serial(seat->display); - wl_keyboard_send_key(handle->keyboard, key_serial, - (uint32_t)event->time_usec, event->keycode, key_state); } static void keyboard_keymap_notify(struct wl_listener *listener, void *data) { @@ -434,6 +456,9 @@ void wlr_seat_attach_keyboard(struct wlr_seat *seat, wl_list_init(&seat_kb->key.link); seat_kb->key.notify = keyboard_key_notify; wl_signal_add(&kb->events.key, &seat_kb->key); + wl_list_init(&seat_kb->modifiers.link); + seat_kb->modifiers.notify = keyboard_modifiers_notify; + wl_signal_add(&kb->events.modifiers, &seat_kb->modifiers); wl_list_init(&seat_kb->keymap.link); seat_kb->keymap.notify = keyboard_keymap_notify; wl_signal_add(&kb->events.keymap, &seat_kb->keymap); @@ -450,6 +475,7 @@ void wlr_seat_detach_keyboard(struct wlr_seat *seat, struct wlr_keyboard *kb) { if (seat_kb->keyboard == kb) { wl_list_remove(&seat_kb->link); wl_list_remove(&seat_kb->key.link); + wl_list_remove(&seat_kb->modifiers.link); wl_list_remove(&seat_kb->keymap.link); wl_list_remove(&seat_kb->destroy.link); free(seat_kb); -- cgit v1.2.3 From 606311c755066db94042a41fb1a3f027f67cacf8 Mon Sep 17 00:00:00 2001 From: Versus Void Date: Tue, 3 Oct 2017 18:57:23 +0000 Subject: Reset buffer resource pointer on destroy signal --- include/wlr/types/wlr_surface.h | 1 + types/wlr_surface.c | 49 +++++++++++++++++++++++++++++++++-------- 2 files changed, 41 insertions(+), 9 deletions(-) (limited to 'include/wlr') diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index ae278815..23e53811 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -24,6 +24,7 @@ struct wlr_frame_callback { struct wlr_surface_state { uint32_t invalid; struct wl_resource *buffer; + struct wl_listener buffer_destroy_listener; int32_t sx, sy; pixman_region32_t surface_damage, buffer_damage; pixman_region32_t opaque, input; diff --git a/types/wlr_surface.c b/types/wlr_surface.c index e44ea9fc..45b51363 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -7,6 +7,39 @@ #include #include +static void wlr_surface_state_reset_buffer(struct wlr_surface_state *state) { + if (state->buffer) { + wl_list_remove(&state->buffer_destroy_listener.link); + state->buffer = NULL; + } +} + +static void buffer_destroy(struct wl_listener *listener, void *data) { + struct wlr_surface_state *state = + wl_container_of(listener, state, buffer_destroy_listener); + + wl_list_remove(&state->buffer_destroy_listener.link); + state->buffer = NULL; +} + +static void wlr_surface_state_release_buffer(struct wlr_surface_state *state) { + if (state->buffer) { + wl_resource_post_event(state->buffer, WL_BUFFER_RELEASE); + wl_list_remove(&state->buffer_destroy_listener.link); + state->buffer = NULL; + } +} + +static void wlr_surface_state_set_buffer(struct wlr_surface_state *state, + struct wl_resource *buffer) { + state->buffer = buffer; + if (buffer) { + wl_resource_add_destroy_listener(buffer, + &state->buffer_destroy_listener); + state->buffer_destroy_listener.notify = buffer_destroy; + } +} + static void surface_destroy(struct wl_client *client, struct wl_resource *resource) { wl_resource_destroy(resource); @@ -18,7 +51,8 @@ static void surface_attach(struct wl_client *client, struct wlr_surface *surface = wl_resource_get_user_data(resource); surface->pending->invalid |= WLR_SURFACE_INVALID_BUFFER; - surface->pending->buffer = buffer; + wlr_surface_state_reset_buffer(surface->pending); + wlr_surface_state_set_buffer(surface->pending, buffer); } static void surface_damage(struct wl_client *client, @@ -223,12 +257,9 @@ static void wlr_surface_move_state(struct wlr_surface *surface, struct wlr_surfa update_size = true; } if ((next->invalid & WLR_SURFACE_INVALID_BUFFER)) { - if (state->buffer) { - wl_resource_post_event(state->buffer, WL_BUFFER_RELEASE); - } - - state->buffer = next->buffer; - next->buffer = NULL; + wlr_surface_state_release_buffer(state); + wlr_surface_state_set_buffer(state, next->buffer); + wlr_surface_state_reset_buffer(next); update_size = true; } if (update_size) { @@ -460,8 +491,7 @@ release: pixman_region32_clear(&surface->current->surface_damage); pixman_region32_clear(&surface->current->buffer_damage); - wl_resource_post_event(surface->current->buffer, WL_BUFFER_RELEASE); - surface->current->buffer = NULL; + wlr_surface_state_release_buffer(surface->current); } static void surface_set_buffer_transform(struct wl_client *client, @@ -522,6 +552,7 @@ static struct wlr_surface_state *wlr_surface_state_create() { } static void wlr_surface_state_destroy(struct wlr_surface_state *state) { + wlr_surface_state_reset_buffer(state); struct wlr_frame_callback *cb, *tmp; wl_list_for_each_safe(cb, tmp, &state->frame_callback_list, link) { wl_resource_destroy(cb->resource); -- cgit v1.2.3