ecore_wl2: be compatible with x input
authorMarcel Hollerbach <marcel-hollerbach@t-online.de>
Thu, 21 Jul 2016 18:15:16 +0000 (20:15 +0200)
committerMarcel Hollerbach <marcel-hollerbach@t-online.de>
Thu, 21 Jul 2016 20:10:54 +0000 (22:10 +0200)
This commit introduces a new state per input, this state is just for the
keymap and no modifieres, the state is used to get the keysym from a
keycode. This is done to stay compatible with x since keyname in efl is
the characters which are describing the key which is pressed, without
the transformation of shift etc.

This also escapes keycodes from beeing a utf8 character, and passes out
a keyname instead of the utf8 symbol.

fix T3976
fix T4184

src/lib/ecore_wl2/ecore_wl2_input.c
src/lib/ecore_wl2/ecore_wl2_private.h

index 3bef2f0..baceb92 100644 (file)
@@ -414,33 +414,35 @@ _ecore_wl2_input_key_translate(xkb_keysym_t keysym, unsigned int modifiers, char
 }
 
 static void
-_ecore_wl2_input_key_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, xkb_keysym_t sym, unsigned int code, unsigned int state, unsigned int timestamp)
+_ecore_wl2_input_symbol_rep_find(xkb_keysym_t keysym, char *buffer, int size, unsigned int code)
+{
+    int n = 0;
+
+    n = xkb_keysym_to_utf8(keysym, buffer, size);
+
+    /* check if we are a control code */
+    if (n > 0 && !(buffer[0] > 0x0 && buffer[0] < 0x20))
+      return;
+
+    if (xkb_keysym_get_name(keysym, buffer, size) != 0)
+      return;
+
+    snprintf(buffer, size, "Keycode-%u", code);
+}
+
+static void
+_ecore_wl2_input_key_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, xkb_keysym_t sym, xkb_keysym_t sym_name, unsigned int code, unsigned int state, unsigned int timestamp)
 {
    Ecore_Event_Key *ev;
    char key[256], keyname[256], compose[256];
 
    memset(key, 0, sizeof(key));
    memset(keyname, 0, sizeof(keyname));
+   memset(compose, 0, sizeof(compose));
 
    /*try to get a name or utf char of the given symbol */
-   xkb_keysym_to_utf8(sym, keyname, sizeof(keyname));
-   xkb_keysym_get_name(sym, key, sizeof(key));
-
-   if (keyname[0] == '\0' && key[0] != '\0')
-     {
-        memcpy(keyname, key, sizeof(key));
-     }
-   else if (keyname[0] != '\0' && key[0] == '\0')
-     {
-        memcpy(key, keyname, sizeof(keyname));
-     }
-   else if (keyname[0] == '\0' && key[0] == '\0')
-     {
-        snprintf(keyname, sizeof(keyname), "Keycode-%u", code);
-        memcpy(key, keyname, sizeof(keyname));
-     }
-
-   memset(compose, 0, sizeof(compose));
+   _ecore_wl2_input_symbol_rep_find(sym, key, sizeof(key), code);
+   _ecore_wl2_input_symbol_rep_find(sym_name, keyname, sizeof(keyname), code);
    _ecore_wl2_input_key_translate(sym, input->keyboard.modifiers,
                                   compose, sizeof(compose));
 
@@ -463,6 +465,8 @@ _ecore_wl2_input_key_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, xkb_
    ev->modifiers = input->keyboard.modifiers;
    ev->keycode = code;
 
+   DBG("Emitting Key event (%s,%s,%s,%s)\n", ev->keyname, ev->key, ev->compose, ev->string);
+
    if (state)
      ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, NULL, NULL);
    else
@@ -709,6 +713,7 @@ _keyboard_cb_keymap(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsign
    /* free any existing keymap and state */
    if (input->xkb.keymap) xkb_map_unref(input->xkb.keymap);
    if (input->xkb.state) xkb_state_unref(input->xkb.state);
+   if (input->xkb.maskless_state) xkb_state_unref(input->xkb.maskless_state);
 
    input->xkb.keymap =
      xkb_map_new_from_string(input->display->xkb_context, map,
@@ -724,7 +729,9 @@ _keyboard_cb_keymap(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsign
      }
 
    input->xkb.state = xkb_state_new(input->xkb.keymap);
-   if (!input->xkb.state)
+   input->xkb.maskless_state = xkb_state_new(input->xkb.keymap);
+
+   if (!input->xkb.state || !input->xkb.maskless_state)
      {
         ERR("Failed to create keymap state");
         xkb_map_unref(input->xkb.keymap);
@@ -817,7 +824,7 @@ _keyboard_cb_repeat(void *data)
    window = input->focus.keyboard;
    if (!window) goto out;
 
-   _ecore_wl2_input_key_send(input, input->focus.keyboard, input->repeat.sym, input->repeat.key + 8, WL_KEYBOARD_KEY_STATE_PRESSED,  input->repeat.time);
+   _ecore_wl2_input_key_send(input, input->focus.keyboard, input->repeat.sym, input->repeat.sym_name, input->repeat.key + 8, WL_KEYBOARD_KEY_STATE_PRESSED,  input->repeat.time);
 
    if (!input->repeat.repeating)
      {
@@ -838,9 +845,8 @@ _keyboard_cb_key(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned
 {
    Ecore_Wl2_Input *input;
    Ecore_Wl2_Window *window;
-   unsigned int code, nsyms;
-   const xkb_keysym_t *syms;
-   xkb_keysym_t sym = XKB_KEY_NoSymbol;
+   unsigned int code;
+   xkb_keysym_t sym = XKB_KEY_NoSymbol, sym_name = XKB_KEY_NoSymbol;
 
    input = data;
    if (!input) return;
@@ -854,10 +860,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;
 
-   nsyms = xkb_state_key_get_syms(input->xkb.state, code, &syms);
-   if (nsyms == 1) sym = syms[0];
+   sym = xkb_state_key_get_one_sym(input->xkb.state, code);
+   sym_name = xkb_state_key_get_one_sym(input->xkb.maskless_state, code);
 
-   _ecore_wl2_input_key_send(input, window, sym, code, state, timestamp);
+   _ecore_wl2_input_key_send(input, window, sym, sym_name, code, state, timestamp);
 
    if (!xkb_keymap_key_repeats(input->xkb.keymap, code)) return;
 
@@ -876,6 +882,7 @@ _keyboard_cb_key(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned
         if (!input->repeat.enabled) return;
 
         input->repeat.sym = sym;
+        input->repeat.sym_name = sym;
         input->repeat.key = keycode;
         input->repeat.time = timestamp;
 
@@ -1369,6 +1376,7 @@ _ecore_wl2_input_del(Ecore_Wl2_Input *input)
    if (input->data.device) wl_data_device_destroy(input->data.device);
 
    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->wl.seat) wl_seat_destroy(input->wl.seat);
index 1d27f60..59f63fc 100644 (file)
@@ -388,6 +388,7 @@ struct _Ecore_Wl2_Input
      {
         struct xkb_keymap *keymap;
         struct xkb_state *state;
+        struct xkb_state *maskless_state;
         xkb_mod_mask_t control_mask;
         xkb_mod_mask_t alt_mask;
         xkb_mod_mask_t shift_mask;
@@ -405,7 +406,7 @@ struct _Ecore_Wl2_Input
    struct
      {
         Ecore_Timer *timer;
-        unsigned int sym, key, time;
+        unsigned int sym, sym_name, key, time;
         double rate, delay;
         Eina_Bool enabled : 1;
         Eina_Bool repeating : 1;