mirror of
https://github.com/glfw/glfw.git
synced 2024-11-22 10:05:10 +00:00
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.
This commit is contained in:
parent
46cebb5081
commit
3a12edd988
@ -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)
|
||||||
|
@ -682,6 +682,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.hints.init.wl.libdecorMode == GLFW_WAYLAND_PREFER_LIBDECOR)
|
if (_glfw.hints.init.wl.libdecorMode == GLFW_WAYLAND_PREFER_LIBDECOR)
|
||||||
_glfw.wl.libdecor.handle = _glfwPlatformLoadModule("libdecor-0.so.0");
|
_glfw.wl.libdecor.handle = _glfwPlatformLoadModule("libdecor-0.so.0");
|
||||||
|
@ -44,7 +44,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);
|
||||||
@ -176,6 +175,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
|
||||||
@ -189,6 +190,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*);
|
||||||
@ -494,6 +497,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;
|
||||||
|
@ -1086,8 +1086,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));
|
||||||
@ -2584,23 +2584,23 @@ const char* _glfwGetScancodeNameWayland(int scancode)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t codepoint = _glfwKeySym2Unicode(keysyms[0]);
|
// WORKAROUND: 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 first copy to a temporary buffer.
|
||||||
|
//
|
||||||
|
// See: https://github.com/xkbcommon/libxkbcommon/issues/418
|
||||||
|
char temp_buffer[7];
|
||||||
|
const int bytes_written = xkb_keysym_to_utf8(keysyms[0], temp_buffer, sizeof(temp_buffer));
|
||||||
|
if (bytes_written <= 0 || bytes_written > 5)
|
||||||
{
|
{
|
||||||
_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;
|
||||||
}
|
}
|
||||||
|
memcpy(_glfw.wl.keynames[key], temp_buffer, bytes_written);
|
||||||
|
|
||||||
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];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user