Wayland: Implement key name support
(cherry picked from commit 17a9e34fbc
)
This commit is contained in:
parent
0eaf9d557f
commit
1f7ce12cbc
@ -124,6 +124,7 @@ information on what to include when reporting a bug.
|
||||
## Changelog
|
||||
|
||||
- [X11] Bugfix: Dynamic loading on OpenBSD failed due to soname differences
|
||||
- [Wayland] Added support for key names via xkbcommon
|
||||
- [Wayland] Bugfix: Key repeat could lead to a race condition (#1710)
|
||||
- [Wayland] Bugfix: Activating a window would emit two input focus events
|
||||
- [Wayland] Bugfix: Disable key repeat mechanism when window loses input focus
|
||||
|
@ -1110,6 +1110,8 @@ int _glfwPlatformInit(void)
|
||||
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_mod_get_index");
|
||||
_glfw.wl.xkb.keymap_key_repeats = (PFN_xkb_keymap_key_repeats)
|
||||
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_key_repeats");
|
||||
_glfw.wl.xkb.keymap_key_get_syms_by_level = (PFN_xkb_keymap_key_get_syms_by_level)
|
||||
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_key_get_syms_by_level");
|
||||
_glfw.wl.xkb.state_new = (PFN_xkb_state_new)
|
||||
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_new");
|
||||
_glfw.wl.xkb.state_unref = (PFN_xkb_state_unref)
|
||||
@ -1120,6 +1122,8 @@ int _glfwPlatformInit(void)
|
||||
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_update_mask");
|
||||
_glfw.wl.xkb.state_serialize_mods = (PFN_xkb_state_serialize_mods)
|
||||
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_serialize_mods");
|
||||
_glfw.wl.xkb.state_key_get_layout = (PFN_xkb_state_key_get_layout)
|
||||
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_key_get_layout");
|
||||
|
||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
||||
_glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale)
|
||||
|
@ -112,22 +112,26 @@ typedef struct xkb_keymap* (* PFN_xkb_keymap_new_from_string)(struct xkb_context
|
||||
typedef void (* PFN_xkb_keymap_unref)(struct xkb_keymap*);
|
||||
typedef xkb_mod_index_t (* PFN_xkb_keymap_mod_get_index)(struct xkb_keymap*, const char*);
|
||||
typedef int (* PFN_xkb_keymap_key_repeats)(struct xkb_keymap*, xkb_keycode_t);
|
||||
typedef int (* PFN_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**);
|
||||
typedef struct xkb_state* (* PFN_xkb_state_new)(struct xkb_keymap*);
|
||||
typedef void (* PFN_xkb_state_unref)(struct xkb_state*);
|
||||
typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, const xkb_keysym_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_mod_mask_t (* PFN_xkb_state_serialize_mods)(struct xkb_state*, enum xkb_state_component);
|
||||
typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xkb_keycode_t);
|
||||
#define xkb_context_new _glfw.wl.xkb.context_new
|
||||
#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_unref _glfw.wl.xkb.keymap_unref
|
||||
#define xkb_keymap_mod_get_index _glfw.wl.xkb.keymap_mod_get_index
|
||||
#define xkb_keymap_key_repeats _glfw.wl.xkb.keymap_key_repeats
|
||||
#define xkb_keymap_key_get_syms_by_level _glfw.wl.xkb.keymap_key_get_syms_by_level
|
||||
#define xkb_state_new _glfw.wl.xkb.state_new
|
||||
#define xkb_state_unref _glfw.wl.xkb.state_unref
|
||||
#define xkb_state_key_get_syms _glfw.wl.xkb.state_key_get_syms
|
||||
#define xkb_state_update_mask _glfw.wl.xkb.state_update_mask
|
||||
#define xkb_state_serialize_mods _glfw.wl.xkb.state_serialize_mods
|
||||
#define xkb_state_key_get_layout _glfw.wl.xkb.state_key_get_layout
|
||||
|
||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
||||
typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags);
|
||||
@ -262,6 +266,7 @@ typedef struct _GLFWlibraryWayland
|
||||
int timerfd;
|
||||
short int keycodes[256];
|
||||
short int scancodes[GLFW_KEY_LAST + 1];
|
||||
char keynames[GLFW_KEY_LAST + 1][5];
|
||||
|
||||
struct {
|
||||
void* handle;
|
||||
@ -287,11 +292,13 @@ typedef struct _GLFWlibraryWayland
|
||||
PFN_xkb_keymap_unref keymap_unref;
|
||||
PFN_xkb_keymap_mod_get_index keymap_mod_get_index;
|
||||
PFN_xkb_keymap_key_repeats keymap_key_repeats;
|
||||
PFN_xkb_keymap_key_get_syms_by_level keymap_key_get_syms_by_level;
|
||||
PFN_xkb_state_new state_new;
|
||||
PFN_xkb_state_unref state_unref;
|
||||
PFN_xkb_state_key_get_syms state_key_get_syms;
|
||||
PFN_xkb_state_update_mask state_update_mask;
|
||||
PFN_xkb_state_serialize_mods state_serialize_mods;
|
||||
PFN_xkb_state_key_get_layout state_key_get_layout;
|
||||
|
||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
||||
PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale;
|
||||
|
@ -1354,8 +1354,57 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
||||
|
||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
||||
{
|
||||
// TODO
|
||||
return NULL;
|
||||
if (scancode < 0 || scancode > 255 ||
|
||||
_glfw.wl.keycodes[scancode] == GLFW_KEY_UNKNOWN)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"Wayland: Invalid scancode %i",
|
||||
scancode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const int key = _glfw.wl.keycodes[scancode];
|
||||
const xkb_keycode_t keycode = scancode + 8;
|
||||
const xkb_layout_index_t layout =
|
||||
xkb_state_key_get_layout(_glfw.wl.xkb.state, keycode);
|
||||
if (layout == XKB_LAYOUT_INVALID)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to retrieve layout for key name");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const xkb_keysym_t* keysyms = NULL;
|
||||
xkb_keymap_key_get_syms_by_level(_glfw.wl.xkb.keymap,
|
||||
keycode,
|
||||
layout,
|
||||
0,
|
||||
&keysyms);
|
||||
if (keysyms == NULL)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to retrieve keysym for key name");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const long codepoint = _glfwKeySym2Unicode(keysyms[0]);
|
||||
if (codepoint == -1)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to retrieve codepoint for key name");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const size_t count = _glfwEncodeUTF8(_glfw.wl.keynames[key], (unsigned int) 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];
|
||||
}
|
||||
|
||||
int _glfwPlatformGetKeyScancode(int key)
|
||||
|
Loading…
Reference in New Issue
Block a user