wayland: Set the keymap in keyboard_handle_modifiers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index ef4f2cc..73b81c1 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 5962ff6..5e9bafe 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