Compare commits

...

2 Commits

Author SHA1 Message Date
Victor Chernyakin
00669be34f
Merge af9bfbff74 into 228e58262e 2024-03-29 16:14:08 +01:00
LocalSpook
af9bfbff74 Replace _glfwKeySym2Unicode with xkb_keysym_to_utf{8,32} on Wayland
libxkbcommon already provides functions to convert keysyms
to codepoints and UTF-8. The library has offered these
functions since 0.5.0 (https://xkbcommon.org/doc/0.5.0/group__keysyms.html),
so using them won't cause any compatibility problems.
2023-12-10 08:20:38 -07:00
5 changed files with 25 additions and 17 deletions

View File

@ -37,6 +37,7 @@ video tutorials.
- Chi-kwan Chan - Chi-kwan Chan
- Victor Chernyakin - Victor Chernyakin
- TheChocolateOre - TheChocolateOre
- Виктор Чернякин
- Ali Chraghi - Ali Chraghi
- Joseph Chua - Joseph Chua
- Ian Clarkson - Ian Clarkson

View File

@ -52,8 +52,8 @@ endif()
if (GLFW_BUILD_WAYLAND) if (GLFW_BUILD_WAYLAND)
target_compile_definitions(glfw PRIVATE _GLFW_WAYLAND) target_compile_definitions(glfw PRIVATE _GLFW_WAYLAND)
target_sources(glfw PRIVATE wl_platform.h xkb_unicode.h wl_init.c target_sources(glfw PRIVATE wl_platform.h wl_init.c
wl_monitor.c wl_window.c xkb_unicode.c) wl_monitor.c wl_window.c)
endif() endif()
if (GLFW_BUILD_X11 OR GLFW_BUILD_WAYLAND) if (GLFW_BUILD_X11 OR GLFW_BUILD_WAYLAND)

View File

@ -711,6 +711,10 @@ int _glfwInitWayland(void)
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_status"); _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_status");
_glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym) _glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym)
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym"); _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym");
_glfw.wl.xkb.keysym_to_utf32 = (PFN_xkb_keysym_to_utf32)
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keysym_to_utf32");
_glfw.wl.xkb.keysym_to_utf8 = (PFN_xkb_keysym_to_utf8)
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keysym_to_utf8");
if (!_glfw.wl.xkb.context_new || if (!_glfw.wl.xkb.context_new ||
!_glfw.wl.xkb.context_unref || !_glfw.wl.xkb.context_unref ||

View File

@ -42,7 +42,6 @@ typedef struct VkWaylandSurfaceCreateInfoKHR
typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*); typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
#include "xkb_unicode.h"
#include "posix_poll.h" #include "posix_poll.h"
typedef int (* PFN_wl_display_flush)(struct wl_display* display); typedef int (* PFN_wl_display_flush)(struct wl_display* display);
@ -178,6 +177,8 @@ typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, con
typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t); typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t);
typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xkb_keycode_t); typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xkb_keycode_t);
typedef int (* PFN_xkb_state_mod_index_is_active)(struct xkb_state*,xkb_mod_index_t,enum xkb_state_component); typedef int (* PFN_xkb_state_mod_index_is_active)(struct xkb_state*,xkb_mod_index_t,enum xkb_state_component);
typedef uint32_t (* PFN_xkb_keysym_to_utf32)(xkb_keysym_t);
typedef int (* PFN_xkb_keysym_to_utf8)(xkb_keysym_t, char*, size_t);
#define xkb_context_new _glfw.wl.xkb.context_new #define xkb_context_new _glfw.wl.xkb.context_new
#define xkb_context_unref _glfw.wl.xkb.context_unref #define xkb_context_unref _glfw.wl.xkb.context_unref
#define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string #define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string
@ -191,6 +192,8 @@ typedef int (* PFN_xkb_state_mod_index_is_active)(struct xkb_state*,xkb_mod_inde
#define xkb_state_update_mask _glfw.wl.xkb.state_update_mask #define xkb_state_update_mask _glfw.wl.xkb.state_update_mask
#define xkb_state_key_get_layout _glfw.wl.xkb.state_key_get_layout #define xkb_state_key_get_layout _glfw.wl.xkb.state_key_get_layout
#define xkb_state_mod_index_is_active _glfw.wl.xkb.state_mod_index_is_active #define xkb_state_mod_index_is_active _glfw.wl.xkb.state_mod_index_is_active
#define xkb_keysym_to_utf32 _glfw.wl.xkb.keysym_to_utf32
#define xkb_keysym_to_utf8 _glfw.wl.xkb.keysym_to_utf8
typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags); typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags);
typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*); typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*);
@ -495,6 +498,8 @@ typedef struct _GLFWlibraryWayland
PFN_xkb_state_update_mask state_update_mask; PFN_xkb_state_update_mask state_update_mask;
PFN_xkb_state_key_get_layout state_key_get_layout; PFN_xkb_state_key_get_layout state_key_get_layout;
PFN_xkb_state_mod_index_is_active state_mod_index_is_active; PFN_xkb_state_mod_index_is_active state_mod_index_is_active;
PFN_xkb_keysym_to_utf32 keysym_to_utf32;
PFN_xkb_keysym_to_utf8 keysym_to_utf8;
PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale; PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale;
PFN_xkb_compose_table_unref compose_table_unref; PFN_xkb_compose_table_unref compose_table_unref;

View File

@ -1192,8 +1192,8 @@ static void inputText(_GLFWwindow* window, uint32_t scancode)
if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1) if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1)
{ {
const xkb_keysym_t keysym = composeSymbol(keysyms[0]); const xkb_keysym_t keysym = composeSymbol(keysyms[0]);
const uint32_t codepoint = _glfwKeySym2Unicode(keysym); const uint32_t codepoint = xkb_keysym_to_utf32(keysym);
if (codepoint != GLFW_INVALID_CODEPOINT) if (codepoint != 0)
{ {
const int mods = _glfw.wl.xkb.modifiers; const int mods = _glfw.wl.xkb.modifiers;
const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
@ -2719,23 +2719,21 @@ const char* _glfwGetScancodeNameWayland(int scancode)
return NULL; return NULL;
} }
const uint32_t codepoint = _glfwKeySym2Unicode(keysyms[0]); // HACK: xkb_keysym_to_utf8() requires the third parameter (size of the output buffer)
if (codepoint == GLFW_INVALID_CODEPOINT) // to be at least 7 (6 bytes + a null terminator), because it was written when UTF-8
// sequences could be up to 6 bytes long. The _glfw.wl.keynames buffers are only 5 bytes
// long, because UTF-8 sequences are now limited to 4 bytes and no codepoints were ever assigned
// that needed more than that. To work around this, we lie to the function about the buffer
// size, because we know it won't use more than 5 bytes.
//
// See: https://github.com/xkbcommon/libxkbcommon/issues/418
if (xkb_keysym_to_utf8(keysyms[0], _glfw.wl.keynames[key], 7) <= 0)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to retrieve codepoint for key name"); "Wayland: Failed to encode keysym as UTF-8");
return NULL; return NULL;
} }
const size_t count = _glfwEncodeUTF8(_glfw.wl.keynames[key], codepoint);
if (count == 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to encode codepoint for key name");
return NULL;
}
_glfw.wl.keynames[key][count] = '\0';
return _glfw.wl.keynames[key]; return _glfw.wl.keynames[key];
} }