discomfitor pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=fbe5ff0104a171840d32e21aa49650ae4c546182
commit fbe5ff0104a171840d32e21aa49650ae4c546182 Author: Mike Blumenkrantz <[email protected]> Date: Fri May 26 16:34:10 2017 -0400 ecore-wl2: implement compose keys @feature ref T5006 --- src/lib/ecore_wl2/ecore_wl2_input.c | 46 ++++++++++++++++++++++++++++++++++- src/lib/ecore_wl2/ecore_wl2_private.h | 3 +++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/lib/ecore_wl2/ecore_wl2_input.c b/src/lib/ecore_wl2/ecore_wl2_input.c index 6ad915212f..510139006b 100644 --- a/src/lib/ecore_wl2/ecore_wl2_input.c +++ b/src/lib/ecore_wl2/ecore_wl2_input.c @@ -832,6 +832,7 @@ _keyboard_cb_keymap(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsign { Ecore_Wl2_Input *input; char *map = NULL; + const char *locale; input = data; if (!input) @@ -881,6 +882,17 @@ _keyboard_cb_keymap(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsign input->xkb.keymap = NULL; return; } + + if (!(locale = getenv("LC_ALL"))) + if (!(locale = getenv("LC_CTYPE"))) + if (!(locale = getenv("LANG"))) + locale = "C"; + if (input->xkb.compose_table) xkb_compose_table_unref(input->xkb.compose_table); + input->xkb.compose_table = xkb_compose_table_new_from_locale(input->display->xkb_context, + locale, XKB_COMPOSE_COMPILE_NO_FLAGS); + if (input->xkb.compose_state) xkb_compose_state_unref(input->xkb.compose_state); + input->xkb.compose_state = xkb_compose_state_new(input->xkb.compose_table, XKB_COMPOSE_STATE_NO_FLAGS); + { Ecore_Wl2_Event_Seat_Keymap_Changed *ev = malloc(sizeof(Ecore_Wl2_Event_Seat_Keymap_Changed)); if (ev) @@ -992,6 +1004,32 @@ out: return ECORE_CALLBACK_CANCEL; } +/* from weston/clients/window.c */ +/* Translate symbols appropriately if a compose sequence is being entered */ +static xkb_keysym_t +process_key_press(xkb_keysym_t sym, Ecore_Wl2_Input *input) +{ + if (!input->xkb.compose_state) + return sym; + if (sym == XKB_KEY_NoSymbol) + return sym; + if (xkb_compose_state_feed(input->xkb.compose_state, sym) != XKB_COMPOSE_FEED_ACCEPTED) + return sym; + + switch (xkb_compose_state_get_status(input->xkb.compose_state)) + { + case XKB_COMPOSE_COMPOSING: + return XKB_KEY_NoSymbol; + case XKB_COMPOSE_COMPOSED: + return xkb_compose_state_get_one_sym(input->xkb.compose_state); + case XKB_COMPOSE_CANCELLED: + return XKB_KEY_NoSymbol; + case XKB_COMPOSE_NOTHING: + default: break; + } + return sym; +} + static void _keyboard_cb_key(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int keycode, unsigned int state) { @@ -999,6 +1037,7 @@ _keyboard_cb_key(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned Ecore_Wl2_Window *window; unsigned int code; xkb_keysym_t sym = XKB_KEY_NoSymbol, sym_name = XKB_KEY_NoSymbol; + const xkb_keysym_t *syms; input = data; if (!input) return; @@ -1012,7 +1051,10 @@ _keyboard_cb_key(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned /* xkb rules reflect X broken keycodes, so offset by 8 */ code = keycode + 8; - sym = xkb_state_key_get_one_sym(input->xkb.state, code); + if (xkb_state_key_get_syms(input->xkb.state, code, &syms) == 1) + sym = syms[0]; + if (state == WL_KEYBOARD_KEY_STATE_PRESSED) + sym = process_key_press(sym, input); sym_name = xkb_state_key_get_one_sym(input->xkb.maskless_state, code); _ecore_wl2_input_key_send(input, window, sym, sym_name, code, state, timestamp); @@ -1620,6 +1662,8 @@ _ecore_wl2_input_del(Ecore_Wl2_Input *input) if (input->xkb.state) xkb_state_unref(input->xkb.state); if (input->xkb.maskless_state) xkb_state_unref(input->xkb.maskless_state); if (input->xkb.keymap) xkb_map_unref(input->xkb.keymap); + if (input->xkb.compose_table) xkb_compose_table_unref(input->xkb.compose_table); + if (input->xkb.compose_state) xkb_compose_state_unref(input->xkb.compose_state); if (input->wl.seat) wl_seat_destroy(input->wl.seat); diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h index f9aedf1823..c150a4b6ce 100644 --- a/src/lib/ecore_wl2/ecore_wl2_private.h +++ b/src/lib/ecore_wl2/ecore_wl2_private.h @@ -4,6 +4,7 @@ # include <unistd.h> # include "Ecore_Wl2.h" # include "Ecore_Input.h" +#include <xkbcommon/xkbcommon-compose.h> # include "www-client-protocol.h" #define EFL_TEAMWORK_VERSION 2 @@ -402,6 +403,8 @@ struct _Ecore_Wl2_Input struct xkb_keymap *keymap; struct xkb_state *state; struct xkb_state *maskless_state; + struct xkb_compose_table *compose_table; + struct xkb_compose_state *compose_state; xkb_mod_mask_t control_mask; xkb_mod_mask_t alt_mask; xkb_mod_mask_t shift_mask; --
