mirror of
https://github.com/glfw/glfw.git
synced 2024-11-26 03:52:01 +00:00
Wayland: Implement compose key for character input
This commit has been copied almost verbatim from Bryce Harrington’s patch against Weston’s toytoolkit[1]. He gave his agreement to relicense it under zlib[2]. [1] https://patchwork.freedesktop.org/patch/114661/ [2] https://github.com/glfw/glfw/pull/879#issuecomment-252988257
This commit is contained in:
parent
efc6b35615
commit
046d281abc
@ -172,7 +172,10 @@ static void keyboardHandleKeymap(void* data,
|
|||||||
{
|
{
|
||||||
struct xkb_keymap* keymap;
|
struct xkb_keymap* keymap;
|
||||||
struct xkb_state* state;
|
struct xkb_state* state;
|
||||||
|
struct xkb_compose_table* composeTable;
|
||||||
|
struct xkb_compose_state* composeState;
|
||||||
char* mapStr;
|
char* mapStr;
|
||||||
|
const char* locale;
|
||||||
|
|
||||||
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
|
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
|
||||||
{
|
{
|
||||||
@ -209,6 +212,35 @@ static void keyboardHandleKeymap(void* data,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Look up the preferred locale, falling back to "C" as default.
|
||||||
|
locale = getenv("LC_ALL");
|
||||||
|
if (!locale)
|
||||||
|
locale = getenv("LC_CTYPE");
|
||||||
|
if (!locale)
|
||||||
|
locale = getenv("LANG");
|
||||||
|
if (!locale)
|
||||||
|
locale = "C";
|
||||||
|
|
||||||
|
composeTable =
|
||||||
|
xkb_compose_table_new_from_locale(_glfw.wl.xkb.context, locale,
|
||||||
|
XKB_COMPOSE_COMPILE_NO_FLAGS);
|
||||||
|
if (composeTable)
|
||||||
|
{
|
||||||
|
composeState =
|
||||||
|
xkb_compose_state_new(composeTable, XKB_COMPOSE_STATE_NO_FLAGS);
|
||||||
|
xkb_compose_table_unref(composeTable);
|
||||||
|
if (composeState)
|
||||||
|
_glfw.wl.xkb.composeState = composeState;
|
||||||
|
else
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to create XKB compose state");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to create XKB compose table");
|
||||||
|
}
|
||||||
|
|
||||||
xkb_keymap_unref(_glfw.wl.xkb.keymap);
|
xkb_keymap_unref(_glfw.wl.xkb.keymap);
|
||||||
xkb_state_unref(_glfw.wl.xkb.state);
|
xkb_state_unref(_glfw.wl.xkb.state);
|
||||||
_glfw.wl.xkb.keymap = keymap;
|
_glfw.wl.xkb.keymap = keymap;
|
||||||
@ -258,18 +290,40 @@ static int toGLFWKeyCode(uint32_t key)
|
|||||||
return GLFW_KEY_UNKNOWN;
|
return GLFW_KEY_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static xkb_keysym_t composeSymbol(xkb_keysym_t sym)
|
||||||
|
{
|
||||||
|
if (sym == XKB_KEY_NoSymbol)
|
||||||
|
return sym;
|
||||||
|
if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym)
|
||||||
|
!= XKB_COMPOSE_FEED_ACCEPTED)
|
||||||
|
return sym;
|
||||||
|
switch (xkb_compose_state_get_status(_glfw.wl.xkb.composeState))
|
||||||
|
{
|
||||||
|
case XKB_COMPOSE_COMPOSED:
|
||||||
|
return xkb_compose_state_get_one_sym(_glfw.wl.xkb.composeState);
|
||||||
|
case XKB_COMPOSE_COMPOSING:
|
||||||
|
case XKB_COMPOSE_CANCELLED:
|
||||||
|
return XKB_KEY_NoSymbol;
|
||||||
|
case XKB_COMPOSE_NOTHING:
|
||||||
|
default:
|
||||||
|
return sym;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void inputChar(_GLFWwindow* window, uint32_t key)
|
static void inputChar(_GLFWwindow* window, uint32_t key)
|
||||||
{
|
{
|
||||||
uint32_t code, numSyms;
|
uint32_t code, numSyms;
|
||||||
long cp;
|
long cp;
|
||||||
const xkb_keysym_t *syms;
|
const xkb_keysym_t *syms;
|
||||||
|
xkb_keysym_t sym;
|
||||||
|
|
||||||
code = key + 8;
|
code = key + 8;
|
||||||
numSyms = xkb_state_key_get_syms(_glfw.wl.xkb.state, code, &syms);
|
numSyms = xkb_state_key_get_syms(_glfw.wl.xkb.state, code, &syms);
|
||||||
|
|
||||||
if (numSyms == 1)
|
if (numSyms == 1)
|
||||||
{
|
{
|
||||||
cp = _glfwKeySym2Unicode(syms[0]);
|
sym = composeSymbol(syms[0]);
|
||||||
|
cp = _glfwKeySym2Unicode(sym);
|
||||||
if (cp != -1)
|
if (cp != -1)
|
||||||
{
|
{
|
||||||
const int mods = _glfw.wl.xkb.modifiers;
|
const int mods = _glfw.wl.xkb.modifiers;
|
||||||
@ -645,6 +699,7 @@ void _glfwPlatformTerminate(void)
|
|||||||
_glfwTerminateJoysticksLinux();
|
_glfwTerminateJoysticksLinux();
|
||||||
_glfwTerminateThreadLocalStoragePOSIX();
|
_glfwTerminateThreadLocalStoragePOSIX();
|
||||||
|
|
||||||
|
xkb_compose_state_unref(_glfw.wl.xkb.composeState);
|
||||||
xkb_keymap_unref(_glfw.wl.xkb.keymap);
|
xkb_keymap_unref(_glfw.wl.xkb.keymap);
|
||||||
xkb_state_unref(_glfw.wl.xkb.state);
|
xkb_state_unref(_glfw.wl.xkb.state);
|
||||||
xkb_context_unref(_glfw.wl.xkb.context);
|
xkb_context_unref(_glfw.wl.xkb.context);
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
#include <xkbcommon/xkbcommon-compose.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
|
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
|
||||||
@ -136,6 +137,7 @@ typedef struct _GLFWlibraryWayland
|
|||||||
struct xkb_context* context;
|
struct xkb_context* context;
|
||||||
struct xkb_keymap* keymap;
|
struct xkb_keymap* keymap;
|
||||||
struct xkb_state* state;
|
struct xkb_state* state;
|
||||||
|
struct xkb_compose_state* composeState;
|
||||||
xkb_mod_mask_t controlMask;
|
xkb_mod_mask_t controlMask;
|
||||||
xkb_mod_mask_t altMask;
|
xkb_mod_mask_t altMask;
|
||||||
xkb_mod_mask_t shiftMask;
|
xkb_mod_mask_t shiftMask;
|
||||||
|
Loading…
Reference in New Issue
Block a user