@@ -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+
14171469static 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 ) {
0 commit comments