Skip to content

Commit 9182b8a

Browse files
committed
wayland: Add a fallback for xkb_keymap_key_get_syms_by_level() for old xkbcommon versions
This function is only available since version 1.0.0, but the SDL minimum is 0.5.0, and Steam Runtime 2 'soldier' uses 0.8.2, so add a fallback function with similar functionality for older versions. xkb_keymap_key_get_mods_for_level() is more efficient, so it is still favored when available.
1 parent 8d7cd3c commit 9182b8a

File tree

2 files changed

+66
-13
lines changed

2 files changed

+66
-13
lines changed

src/video/wayland/SDL_waylandevents.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,6 +1414,58 @@ static const struct wl_touch_listener touch_listener = {
14141414
touch_handler_orientation // Version 6
14151415
};
14161416

1417+
// Fallback for xkb_keymap_key_get_mods_for_level(), which is only available from 1.0.0, while the SDL minimum os 0.5.0.
1418+
#if !SDL_XKBCOMMON_CHECK_VERSION(1, 0, 0)
1419+
static size_t xkb_legacy_get_mods_for_level(SDL_WaylandSeat *seat, xkb_keycode_t key, xkb_layout_index_t layout, xkb_level_index_t level, xkb_mod_mask_t *masks_out, size_t masks_size)
1420+
{
1421+
if (!masks_out || !masks_size) {
1422+
return 0;
1423+
}
1424+
1425+
// Level 0 is always unmodified, so early out.
1426+
if (level == 0) {
1427+
*masks_out = 0;
1428+
return 1;
1429+
}
1430+
1431+
struct xkb_state *state = WAYLAND_xkb_state_new(seat->keyboard.xkb.keymap);
1432+
if (state) {
1433+
const xkb_mod_mask_t keymod_masks[] = {
1434+
0,
1435+
seat->keyboard.xkb.shift_mask,
1436+
seat->keyboard.xkb.caps_mask,
1437+
seat->keyboard.xkb.shift_mask | seat->keyboard.xkb.caps_mask,
1438+
seat->keyboard.xkb.level3_mask,
1439+
seat->keyboard.xkb.level3_mask | seat->keyboard.xkb.shift_mask,
1440+
seat->keyboard.xkb.level3_mask | seat->keyboard.xkb.caps_mask,
1441+
seat->keyboard.xkb.level3_mask | seat->keyboard.xkb.shift_mask | seat->keyboard.xkb.caps_mask,
1442+
seat->keyboard.xkb.level5_mask,
1443+
seat->keyboard.xkb.level5_mask | seat->keyboard.xkb.shift_mask,
1444+
seat->keyboard.xkb.level5_mask | seat->keyboard.xkb.caps_mask,
1445+
seat->keyboard.xkb.level5_mask | seat->keyboard.xkb.shift_mask | seat->keyboard.xkb.caps_mask
1446+
};
1447+
const xkb_mod_mask_t pressed_mod_mask = seat->keyboard.xkb.shift_mask | seat->keyboard.xkb.level3_mask | seat->keyboard.xkb.level5_mask;
1448+
const xkb_mod_mask_t locked_mod_mask = seat->keyboard.xkb.caps_mask;
1449+
1450+
size_t mask_idx = 0;
1451+
1452+
for (size_t i = 0; i < SDL_arraysize(keymod_masks); ++i) {
1453+
WAYLAND_xkb_state_update_mask(state, keymod_masks[i] & pressed_mod_mask, 0, keymod_masks[i] & locked_mod_mask, 0, 0, layout);
1454+
if (WAYLAND_xkb_state_key_get_level(state, key, layout) == level) {
1455+
masks_out[mask_idx] = keymod_masks[i];
1456+
1457+
if (++mask_idx == masks_size) {
1458+
break;
1459+
}
1460+
}
1461+
}
1462+
1463+
WAYLAND_xkb_state_unref(state);
1464+
}
1465+
return mask_idx;
1466+
}
1467+
#endif
1468+
14171469
static void Wayland_KeymapIterator(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
14181470
{
14191471
SDL_WaylandSeat *seat = (SDL_WaylandSeat *)data;
@@ -1450,7 +1502,11 @@ static void Wayland_KeymapIterator(struct xkb_keymap *keymap, xkb_keycode_t key,
14501502
}
14511503

14521504
xkb_mod_mask_t xkb_mod_masks[16];
1505+
#if SDL_XKBCOMMON_CHECK_VERSION(1, 0, 0)
14531506
const size_t num_masks = WAYLAND_xkb_keymap_key_get_mods_for_level(seat->keyboard.xkb.keymap, key, layout, level, xkb_mod_masks, SDL_arraysize(xkb_mod_masks));
1507+
#else
1508+
const size_t num_masks = xkb_legacy_get_mods_for_level(seat, key, layout, level, xkb_mod_masks, SDL_arraysize(xkb_mod_masks));
1509+
#endif
14541510
for (size_t mask = 0; mask < num_masks; ++mask) {
14551511
// Ignore this modifier set if it uses unsupported modifier types.
14561512
if ((xkb_mod_masks[mask] | xkb_valid_mod_mask) != xkb_valid_mod_mask) {

src/video/wayland/SDL_waylandsym.h

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -151,22 +151,19 @@ SDL_WAYLAND_SYM(enum xkb_compose_status, xkb_compose_state_get_status, (struct x
151151
SDL_WAYLAND_SYM(xkb_keysym_t, xkb_compose_state_get_one_sym, (struct xkb_compose_state *) )
152152
SDL_WAYLAND_SYM(void, xkb_keymap_key_for_each, (struct xkb_keymap *, xkb_keymap_key_iter_t, void *) )
153153
SDL_WAYLAND_SYM(xkb_layout_index_t, xkb_keymap_num_layouts, (struct xkb_keymap *) )
154-
SDL_WAYLAND_SYM(int, xkb_keymap_key_get_syms_by_level, (struct xkb_keymap *,
155-
xkb_keycode_t,
156-
xkb_layout_index_t,
157-
xkb_level_index_t,
158-
const xkb_keysym_t **) )
154+
SDL_WAYLAND_SYM(int, xkb_keymap_key_get_syms_by_level, (struct xkb_keymap *, xkb_keycode_t, xkb_layout_index_t, xkb_level_index_t, const xkb_keysym_t **) )
159155
SDL_WAYLAND_SYM(xkb_level_index_t, xkb_keymap_num_levels_for_key, (struct xkb_keymap *, xkb_keycode_t, xkb_layout_index_t) )
160-
SDL_WAYLAND_SYM(size_t, xkb_keymap_key_get_mods_for_level, (struct xkb_keymap *,
161-
xkb_keycode_t,
162-
xkb_layout_index_t,
163-
xkb_level_index_t,
164-
xkb_mod_mask_t *,
165-
size_t masks_size) )
166156
SDL_WAYLAND_SYM(uint32_t, xkb_keysym_to_utf32, (xkb_keysym_t) )
167-
SDL_WAYLAND_SYM(uint32_t, xkb_keymap_mod_get_index, (struct xkb_keymap *,
168-
const char *) )
157+
SDL_WAYLAND_SYM(uint32_t, xkb_keymap_mod_get_index, (struct xkb_keymap *, const char *) )
169158
SDL_WAYLAND_SYM(const char *, xkb_keymap_layout_get_name, (struct xkb_keymap *, xkb_layout_index_t))
159+
160+
#if SDL_XKBCOMMON_CHECK_VERSION(1, 0, 0)
161+
SDL_WAYLAND_SYM(size_t, xkb_keymap_key_get_mods_for_level, (struct xkb_keymap *, xkb_keycode_t, xkb_layout_index_t, xkb_level_index_t, xkb_mod_mask_t *, size_t) )
162+
#else
163+
// Only needed in the fallback replacement for xkb_keymap_key_get_mods_for_level().
164+
SDL_WAYLAND_SYM(xkb_level_index_t, xkb_state_key_get_level, (struct xkb_state *, xkb_keycode_t, xkb_layout_index_t) )
165+
#endif
166+
170167
#if SDL_XKBCOMMON_CHECK_VERSION(1, 10, 0)
171168
SDL_WAYLAND_SYM(xkb_mod_mask_t, xkb_keymap_mod_get_mask, (struct xkb_keymap *, const char *))
172169
#endif

0 commit comments

Comments
 (0)