From dfcd5fbcade077df038269123d9f3e57880aec4b Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Thu, 8 Apr 2021 21:57:58 -0400 Subject: [PATCH] wayland: Set the keymap in keyboard_handle_modifiers --- src/video/wayland/SDL_waylandevents.c | 57 +++++++++++++++++++++++++++ src/video/wayland/SDL_waylandsym.h | 7 ++++ 2 files changed, 64 insertions(+) diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index ef4f2ccca..73b81c1e0 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -767,6 +767,54 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard, } } +typedef struct Wayland_Keymap +{ + xkb_layout_index_t layout; + SDL_Keycode keymap[SDL_NUM_SCANCODES]; +} Wayland_Keymap; + +static void +Wayland_keymap_iter(struct xkb_keymap *keymap, xkb_keycode_t key, void *data) +{ + const xkb_keysym_t *syms; + Wayland_Keymap *sdlKeymap = (Wayland_Keymap *)data; + + if ((key - 8) < SDL_arraysize(xfree86_scancode_table2)) { + SDL_Scancode scancode = xfree86_scancode_table2[key - 8]; + if (scancode == SDL_SCANCODE_UNKNOWN) { + return; + } + + if (WAYLAND_xkb_keymap_key_get_syms_by_level(keymap, key, sdlKeymap->layout, 0, &syms) > 0) { + uint32_t keycode = WAYLAND_xkb_keysym_to_utf32(syms[0]); + if (keycode) { + sdlKeymap->keymap[scancode] = keycode; + } else { + switch (scancode) { + case SDL_SCANCODE_RETURN: + sdlKeymap->keymap[scancode] = SDLK_RETURN; + break; + case SDL_SCANCODE_ESCAPE: + sdlKeymap->keymap[scancode] = SDLK_ESCAPE; + break; + case SDL_SCANCODE_BACKSPACE: + sdlKeymap->keymap[scancode] = SDLK_BACKSPACE; + break; + case SDL_SCANCODE_TAB: + sdlKeymap->keymap[scancode] = SDLK_TAB; + break; + case SDL_SCANCODE_DELETE: + sdlKeymap->keymap[scancode] = SDLK_DELETE; + break; + default: + sdlKeymap->keymap[scancode] = SDL_SCANCODE_TO_KEYCODE(scancode); + break; + } + } + } + } +} + static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, @@ -774,9 +822,18 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t group) { struct SDL_WaylandInput *input = data; + Wayland_Keymap keymap; WAYLAND_xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched, mods_locked, 0, 0, group); + + keymap.layout = group; + SDL_GetDefaultKeymap(keymap.keymap); + WAYLAND_xkb_keymap_key_for_each(input->xkb.keymap, + Wayland_keymap_iter, + &keymap); + SDL_SetKeymap(0, keymap.keymap, SDL_NUM_SCANCODES); + SDL_SendKeymapChangedEvent(); } static void diff --git a/src/video/wayland/SDL_waylandsym.h b/src/video/wayland/SDL_waylandsym.h index 5962ff68a..5e9bafefa 100644 --- a/src/video/wayland/SDL_waylandsym.h +++ b/src/video/wayland/SDL_waylandsym.h @@ -118,6 +118,13 @@ SDL_WAYLAND_SYM(enum xkb_state_component, xkb_state_update_mask, (struct xkb_sta xkb_layout_index_t depressed_layout,\ xkb_layout_index_t latched_layout,\ xkb_layout_index_t locked_layout) ) +SDL_WAYLAND_SYM(void, xkb_keymap_key_for_each, (struct xkb_keymap *, xkb_keymap_key_iter_t, void*) ) +SDL_WAYLAND_SYM(int, xkb_keymap_key_get_syms_by_level, (struct xkb_keymap *, + xkb_keycode_t, + xkb_layout_index_t, + xkb_layout_index_t, + const xkb_keysym_t **) ) +SDL_WAYLAND_SYM(uint32_t, xkb_keysym_to_utf32, (xkb_keysym_t) ) #undef SDL_WAYLAND_MODULE #undef SDL_WAYLAND_SYM