From 9f2055de34737189c62135fac5a186ca8fcd6b54 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Fri, 24 Jun 2016 12:38:05 +0200 Subject: [PATCH] ecore_wl2_input: Fix key keyname pairs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit before key and keyname could have been filled invalid, for example the character "ö" from the german layout produced "Odiaeresis" instead of ö. This commit also documents and refactors _ecore_wl2_input_key_translate. I added the documentation for later use, it was hard to find out why this was done. The function also drops the input now if invalid control codes would have been generated, this is equivalent to the behaviour in x. So applications cannot get confused by codes which dont exist. It also doesnt check if there is actual output by checking the highest bytes anymore, it just tries to create a utf8 character. This fixes arabic greek and korean keyboard input on wl. If this breaks the input for some user, feel free to contact me. This fixes T3073. --- src/lib/ecore_wl2/ecore_wl2_input.c | 97 ++++++++++++++++++----------- 1 file changed, 62 insertions(+), 35 deletions(-) diff --git a/src/lib/ecore_wl2/ecore_wl2_input.c b/src/lib/ecore_wl2/ecore_wl2_input.c index 4761672222..e86936c636 100644 --- a/src/lib/ecore_wl2/ecore_wl2_input.c +++ b/src/lib/ecore_wl2/ecore_wl2_input.c @@ -354,44 +354,59 @@ _ecore_wl2_input_focus_out_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window static int _ecore_wl2_input_key_translate(xkb_keysym_t keysym, unsigned int modifiers, char *buffer, int bytes) { - unsigned long hbytes = 0; - unsigned char c; - if (!keysym) return 0; - hbytes = (keysym >> 8); - - if (!(bytes && - ((hbytes == 0) || - ((hbytes == 0xFF) && - (((keysym >= XKB_KEY_BackSpace) && (keysym <= XKB_KEY_Clear)) || - (keysym == XKB_KEY_Return) || (keysym == XKB_KEY_Escape) || - (keysym == XKB_KEY_KP_Space) || (keysym == XKB_KEY_KP_Tab) || - (keysym == XKB_KEY_KP_Enter) || - ((keysym >= XKB_KEY_KP_Multiply) && (keysym <= XKB_KEY_KP_9)) || - (keysym == XKB_KEY_KP_Equal) || (keysym == XKB_KEY_Delete)))))) - return 0; - - if (keysym == XKB_KEY_KP_Space) - c = (XKB_KEY_space & 0x7F); - else if (hbytes == 0xFF) - c = (keysym & 0x7F); - else - c = (keysym & 0xFF); + /* check for possible control codes */ if (modifiers & ECORE_EVENT_MODIFIER_CTRL) { - if (((c >= '@') && (c < '\177')) || c == ' ') + Eina_Bool valid_control_code = EINA_TRUE; + unsigned long hbytes = 0; + unsigned char c; + + hbytes = (keysym >> 8); + + if (keysym == XKB_KEY_KP_Space) + c = (XKB_KEY_space & 0x7F); + else if (hbytes == 0xFF) + c = (keysym & 0x7F); + else + c = (keysym & 0xFF); + + /* We are building here a control code + for more details, read: + https://en.wikipedia.org/wiki/C0_and_C1_control_codes#C0_.28ASCII_and_derivatives.29 + */ + + if (((c >= '@') && (c <= '_')) || /* those are the one defined in C0 with capital letters */ + ((c >= 'a') && (c <= 'z')) || /* the lowercase symbols (not part of the standard, but usefull */ + c == ' ') c &= 0x1F; - else if (c == '2') - c = '\000'; - else if ((c >= '3') && (c <= '7')) - c -= ('3' - '\033'); - else if (c == '8') + else if (c == '\x7f') c = '\177'; + /* following codes are alternatives, they are longer here, i dont want to change them */ + else if (c == '2') + c = '\000'; /* 0 code */ + else if ((c >= '3') && (c <= '7')) + c -= ('3' - '\033'); /* from escape to unitseperator code*/ + else if (c == '8') + c = '\177'; /* delete code */ else if (c == '/') - c = '_' & 0x1F; + c = '_' & 0x1F; /* unit seperator code */ + else + valid_control_code = EINA_FALSE; + + if (valid_control_code) + buffer[0] = c; + else + return 0; } - buffer[0] = c; + else + { + /* if its not a control code, try to produce a usefull output */ + if (!xkb_keysym_to_utf8(keysym, buffer, bytes)) + return 0; + } + return 1; } @@ -402,13 +417,25 @@ _ecore_wl2_input_key_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, xkb_ char key[256], keyname[256], compose[256]; memset(key, 0, sizeof(key)); + memset(keyname, 0, sizeof(keyname)); + + /*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)); - memset(keyname, 0, sizeof(keyname)); - memcpy(keyname, key, sizeof(keyname)); - - if (keyname[0] == '\0') - snprintf(keyname, sizeof(keyname), "Keycode-%u", code); + 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_key_translate(sym, input->keyboard.modifiers,