|
|
|
@ -172,7 +172,10 @@ static void keyboardHandleKeymap(void* data, |
|
|
|
|
{ |
|
|
|
|
struct xkb_keymap* keymap; |
|
|
|
|
struct xkb_state* state; |
|
|
|
|
struct xkb_compose_table* composeTable; |
|
|
|
|
struct xkb_compose_state* composeState; |
|
|
|
|
char* mapStr; |
|
|
|
|
const char* locale; |
|
|
|
|
|
|
|
|
|
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) |
|
|
|
|
{ |
|
|
|
@ -209,6 +212,35 @@ static void keyboardHandleKeymap(void* data, |
|
|
|
|
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_state_unref(_glfw.wl.xkb.state); |
|
|
|
|
_glfw.wl.xkb.keymap = keymap; |
|
|
|
@ -258,18 +290,40 @@ static int toGLFWKeyCode(uint32_t key) |
|
|
|
|
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) |
|
|
|
|
{ |
|
|
|
|
uint32_t code, numSyms; |
|
|
|
|
long cp; |
|
|
|
|
const xkb_keysym_t *syms; |
|
|
|
|
xkb_keysym_t sym; |
|
|
|
|
|
|
|
|
|
code = key + 8; |
|
|
|
|
numSyms = xkb_state_key_get_syms(_glfw.wl.xkb.state, code, &syms); |
|
|
|
|
|
|
|
|
|
if (numSyms == 1) |
|
|
|
|
{ |
|
|
|
|
cp = _glfwKeySym2Unicode(syms[0]); |
|
|
|
|
sym = composeSymbol(syms[0]); |
|
|
|
|
cp = _glfwKeySym2Unicode(sym); |
|
|
|
|
if (cp != -1) |
|
|
|
|
{ |
|
|
|
|
const int mods = _glfw.wl.xkb.modifiers; |
|
|
|
@ -645,6 +699,7 @@ void _glfwPlatformTerminate(void) |
|
|
|
|
_glfwTerminateJoysticksLinux(); |
|
|
|
|
_glfwTerminateThreadLocalStoragePOSIX(); |
|
|
|
|
|
|
|
|
|
xkb_compose_state_unref(_glfw.wl.xkb.composeState); |
|
|
|
|
xkb_keymap_unref(_glfw.wl.xkb.keymap); |
|
|
|
|
xkb_state_unref(_glfw.wl.xkb.state); |
|
|
|
|
xkb_context_unref(_glfw.wl.xkb.context); |
|
|
|
|