diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index 42e87036f9..cbebf9ede2 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -594,6 +594,18 @@ macro(CheckWayland) sdl_link_dependency(wayland LIBS PkgConfig::PC_WAYLAND PKG_CONFIG_PREFIX PC_WAYLAND PKG_CONFIG_SPECS ${WAYLAND_PKG_CONFIG_SPEC}) endif() + # xkbcommon doesn't provide internal version defines, so generate them here. + if (PC_WAYLAND_xkbcommon_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)") + set(SDL_XKBCOMMON_VERSION_MAJOR ${CMAKE_MATCH_1}) + set(SDL_XKBCOMMON_VERSION_MINOR ${CMAKE_MATCH_2}) + set(SDL_XKBCOMMON_VERSION_PATCH ${CMAKE_MATCH_3}) + else() + message(WARNING "Failed to parse xkbcommon version; defaulting to lowest supported (0.5.0)") + set(SDL_XKBCOMMON_VERSION_MAJOR 0) + set(SDL_XKBCOMMON_VERSION_MINOR 5) + set(SDL_XKBCOMMON_VERSION_PATCH 0) + endif() + if(SDL_WAYLAND_LIBDECOR) set(LibDecor_PKG_CONFIG_SPEC libdecor-0) pkg_check_modules(PC_LIBDECOR IMPORTED_TARGET ${LibDecor_PKG_CONFIG_SPEC}) diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake index 4d013c108c..3cd00ed956 100644 --- a/include/build_config/SDL_build_config.h.cmake +++ b/include/build_config/SDL_build_config.h.cmake @@ -548,6 +548,11 @@ #cmakedefine SDL_VIDEO_VITA_PVR 1 #cmakedefine SDL_VIDEO_VITA_PVR_OGL 1 +/* xkbcommon version info */ +#define SDL_XKBCOMMON_VERSION_MAJOR @SDL_XKBCOMMON_VERSION_MAJOR@ +#define SDL_XKBCOMMON_VERSION_MINOR @SDL_XKBCOMMON_VERSION_MINOR@ +#define SDL_XKBCOMMON_VERSION_PATCH @SDL_XKBCOMMON_VERSION_PATCH@ + /* Libdecor version info */ #define SDL_LIBDECOR_VERSION_MAJOR @SDL_LIBDECOR_VERSION_MAJOR@ #define SDL_LIBDECOR_VERSION_MINOR @SDL_LIBDECOR_VERSION_MINOR@ diff --git a/src/video/wayland/SDL_waylanddyn.h b/src/video/wayland/SDL_waylanddyn.h index fd85a7c2d9..8a2c8aba38 100644 --- a/src/video/wayland/SDL_waylanddyn.h +++ b/src/video/wayland/SDL_waylanddyn.h @@ -59,6 +59,11 @@ enum libdecor_window_state; (WAYLAND_VERSION_MAJOR == x && WAYLAND_VERSION_MINOR > y) || \ (WAYLAND_VERSION_MAJOR == x && WAYLAND_VERSION_MINOR == y && WAYLAND_VERSION_MICRO >= z)) +#define SDL_XKBCOMMON_CHECK_VERSION(x, y, z) \ + (SDL_XKBCOMMON_VERSION_MAJOR > x || \ + (SDL_XKBCOMMON_VERSION_MAJOR == x && SDL_XKBCOMMON_VERSION_MINOR > y) || \ + (SDL_XKBCOMMON_VERSION_MAJOR == x && SDL_XKBCOMMON_VERSION_MINOR == y && SDL_XKBCOMMON_VERSION_PATCH >= z)) + #ifdef HAVE_LIBDECOR_H #define SDL_LIBDECOR_CHECK_VERSION(x, y, z) \ (SDL_LIBDECOR_VERSION_MAJOR > x || \ diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index e9325ac51d..bfbc775c30 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -1489,6 +1489,16 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, return; } +#if SDL_XKBCOMMON_CHECK_VERSION(1, 10, 0) + seat->keyboard.xkb.idx_shift = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_MOD_NAME_SHIFT); + seat->keyboard.xkb.idx_ctrl = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_MOD_NAME_CTRL); + seat->keyboard.xkb.idx_alt = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_VMOD_NAME_ALT); + seat->keyboard.xkb.idx_gui = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_VMOD_NAME_SUPER); + seat->keyboard.xkb.idx_mod5 = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_VMOD_NAME_LEVEL3); + seat->keyboard.xkb.idx_mod3 = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_VMOD_NAME_LEVEL5); + seat->keyboard.xkb.idx_num = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_VMOD_NAME_NUM); + seat->keyboard.xkb.idx_caps = WAYLAND_xkb_keymap_mod_get_mask(seat->keyboard.xkb.keymap, XKB_MOD_NAME_CAPS); +#else #define GET_MOD_INDEX(mod) \ WAYLAND_xkb_keymap_mod_get_index(seat->keyboard.xkb.keymap, XKB_MOD_NAME_##mod) seat->keyboard.xkb.idx_shift = 1 << GET_MOD_INDEX(SHIFT); @@ -1500,6 +1510,7 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, seat->keyboard.xkb.idx_num = 1 << GET_MOD_INDEX(NUM); seat->keyboard.xkb.idx_caps = 1 << GET_MOD_INDEX(CAPS); #undef GET_MOD_INDEX +#endif if (seat->keyboard.xkb.state != NULL) { /* if there's already a state, throw it away rather than leaking it before diff --git a/src/video/wayland/SDL_waylandsym.h b/src/video/wayland/SDL_waylandsym.h index 846c876a87..64e6e44dad 100644 --- a/src/video/wayland/SDL_waylandsym.h +++ b/src/video/wayland/SDL_waylandsym.h @@ -159,6 +159,9 @@ SDL_WAYLAND_SYM(uint32_t, xkb_keysym_to_utf32, (xkb_keysym_t) ) SDL_WAYLAND_SYM(uint32_t, xkb_keymap_mod_get_index, (struct xkb_keymap *, const char *) ) SDL_WAYLAND_SYM(const char *, xkb_keymap_layout_get_name, (struct xkb_keymap*, xkb_layout_index_t)) +#if SDL_XKBCOMMON_CHECK_VERSION(1, 10, 0) +SDL_WAYLAND_SYM(xkb_mod_mask_t, xkb_keymap_mod_get_mask, (struct xkb_keymap*, const char*)) +#endif #ifdef HAVE_LIBDECOR_H SDL_WAYLAND_MODULE(WAYLAND_LIBDECOR)