ecore_wl2_input: Fix key keyname pairs

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.
This commit is contained in:
Marcel Hollerbach 2016-06-24 12:38:05 +02:00
parent 56074fd579
commit 9f2055de34
1 changed files with 62 additions and 35 deletions

View File

@ -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,