1 #include "ecore_xcb_private.h"
2 #define NEED_KEYSYM_TABLE
4 #include "ecore_xcb_keysym_table.h"
5 #include <xcb/xcb_keysyms.h>
6 #include <X11/keysym.h>
8 /* local function prototypes */
9 static int _ecore_xcb_keymap_mask_get(void *reply,
11 static xcb_keysym_t _ecore_xcb_keymap_string_to_keysym(const char *str);
12 static int _ecore_xcb_keymap_translate_key(xcb_keycode_t keycode,
13 unsigned int modifiers,
14 unsigned int *modifiers_return,
15 xcb_keysym_t *keysym_return);
16 static int _ecore_xcb_keymap_translate_keysym(xcb_keysym_t keysym,
17 unsigned int modifiers,
22 static xcb_key_symbols_t *_ecore_xcb_keysyms;
23 static int _ecore_xcb_mode_switch = 0;
25 /* public variables */
26 EAPI int ECORE_X_MODIFIER_SHIFT = 0;
27 EAPI int ECORE_X_MODIFIER_CTRL = 0;
28 EAPI int ECORE_X_MODIFIER_ALT = 0;
29 EAPI int ECORE_X_MODIFIER_WIN = 0;
30 EAPI int ECORE_X_MODIFIER_ALTGR = 0;
31 EAPI int ECORE_X_LOCK_SCROLL = 0;
32 EAPI int ECORE_X_LOCK_NUM = 0;
33 EAPI int ECORE_X_LOCK_CAPS = 0;
34 EAPI int ECORE_X_LOCK_SHIFT = 0;
37 _ecore_xcb_keymap_init(void)
39 LOGFN(__FILE__, __LINE__, __FUNCTION__);
41 _ecore_xcb_keysyms = xcb_key_symbols_alloc(_ecore_xcb_conn);
45 _ecore_xcb_keymap_finalize(void)
47 xcb_get_modifier_mapping_cookie_t cookie;
48 xcb_get_modifier_mapping_reply_t *reply;
50 LOGFN(__FILE__, __LINE__, __FUNCTION__);
53 cookie = xcb_get_modifier_mapping_unchecked(_ecore_xcb_conn);
54 reply = xcb_get_modifier_mapping_reply(_ecore_xcb_conn, cookie, NULL);
57 xcb_key_symbols_free(_ecore_xcb_keysyms);
61 _ecore_xcb_mode_switch = _ecore_xcb_keymap_mask_get(reply, XK_Mode_switch);
63 ECORE_X_MODIFIER_SHIFT = _ecore_xcb_keymap_mask_get(reply, XK_Shift_L);
64 ECORE_X_MODIFIER_CTRL = _ecore_xcb_keymap_mask_get(reply, XK_Control_L);
66 ECORE_X_MODIFIER_ALT = _ecore_xcb_keymap_mask_get(reply, XK_Alt_L);
67 if (!ECORE_X_MODIFIER_ALT)
68 ECORE_X_MODIFIER_ALT = _ecore_xcb_keymap_mask_get(reply, XK_Meta_L);
69 if (!ECORE_X_MODIFIER_ALT)
70 ECORE_X_MODIFIER_ALT = _ecore_xcb_keymap_mask_get(reply, XK_Super_L);
72 ECORE_X_MODIFIER_WIN = _ecore_xcb_keymap_mask_get(reply, XK_Super_L);
73 if (!ECORE_X_MODIFIER_WIN)
74 ECORE_X_MODIFIER_WIN = _ecore_xcb_keymap_mask_get(reply, XK_Meta_L);
76 ECORE_X_MODIFIER_ALTGR = _ecore_xcb_keymap_mask_get(reply, XK_Mode_switch);
78 if (ECORE_X_MODIFIER_WIN == ECORE_X_MODIFIER_ALT)
79 ECORE_X_MODIFIER_WIN = 0;
80 if (ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_CTRL)
81 ECORE_X_MODIFIER_ALT = 0;
83 if (ECORE_X_MODIFIER_ALTGR)
85 if ((ECORE_X_MODIFIER_ALTGR == ECORE_X_MODIFIER_SHIFT) ||
86 (ECORE_X_MODIFIER_ALTGR == ECORE_X_MODIFIER_CTRL) ||
87 (ECORE_X_MODIFIER_ALTGR == ECORE_X_MODIFIER_ALT) ||
88 (ECORE_X_MODIFIER_ALTGR == ECORE_X_MODIFIER_WIN))
90 ERR("ALTGR conflicts with other modifiers. IGNORE ALTGR");
91 ECORE_X_MODIFIER_ALTGR = 0;
95 if (ECORE_X_MODIFIER_ALT)
97 if ((ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_SHIFT) ||
98 (ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_CTRL) ||
99 (ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_WIN))
101 ERR("ALT conflicts with other modifiers. IGNORE ALT");
102 ECORE_X_MODIFIER_ALT = 0;
106 if (ECORE_X_MODIFIER_WIN)
108 if ((ECORE_X_MODIFIER_WIN == ECORE_X_MODIFIER_SHIFT) ||
109 (ECORE_X_MODIFIER_WIN == ECORE_X_MODIFIER_CTRL))
111 ERR("WIN conflicts with other modifiers. IGNORE WIN");
112 ECORE_X_MODIFIER_WIN = 0;
116 if (ECORE_X_MODIFIER_SHIFT)
118 if ((ECORE_X_MODIFIER_SHIFT == ECORE_X_MODIFIER_CTRL))
120 ERR("CTRL conflicts with other modifiers. IGNORE CTRL");
121 ECORE_X_MODIFIER_CTRL = 0;
125 ECORE_X_LOCK_SCROLL = _ecore_xcb_keymap_mask_get(reply, XK_Scroll_Lock);
126 ECORE_X_LOCK_NUM = _ecore_xcb_keymap_mask_get(reply, XK_Num_Lock);
127 ECORE_X_LOCK_CAPS = _ecore_xcb_keymap_mask_get(reply, XK_Caps_Lock);
128 ECORE_X_LOCK_SHIFT = _ecore_xcb_keymap_mask_get(reply, XK_Shift_Lock);
133 _ecore_xcb_modifiers_get(void)
135 _ecore_xcb_keymap_finalize();
139 _ecore_xcb_keymap_shutdown(void)
141 LOGFN(__FILE__, __LINE__, __FUNCTION__);
143 if (_ecore_xcb_keysyms) xcb_key_symbols_free(_ecore_xcb_keysyms);
147 _ecore_xcb_keymap_refresh(xcb_mapping_notify_event_t *event)
150 xcb_refresh_keyboard_mapping(_ecore_xcb_keysyms, event);
154 _ecore_xcb_keymap_keycode_to_keysym(xcb_keycode_t keycode,
157 xcb_keysym_t key0, key1;
160 if (col & _ecore_xcb_mode_switch)
162 key0 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 4);
163 key1 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 5);
167 key0 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 0);
168 key1 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 1);
171 if (key1 == XCB_NO_SYMBOL)
174 if ((col & ECORE_X_LOCK_NUM) &&
175 ((xcb_is_keypad_key(key1)) || (xcb_is_private_keypad_key(key1))))
177 if ((col & XCB_MOD_MASK_SHIFT) ||
178 ((col & XCB_MOD_MASK_LOCK) && (col & ECORE_X_LOCK_SHIFT)))
183 else if (!(col & XCB_MOD_MASK_SHIFT) && !(col & XCB_MOD_MASK_LOCK))
185 else if (!(col & XCB_MOD_MASK_SHIFT) &&
186 (col & XCB_MOD_MASK_LOCK && (col & ECORE_X_LOCK_CAPS)))
188 else if ((col & XCB_MOD_MASK_SHIFT) &&
189 (col & XCB_MOD_MASK_LOCK) && (col & ECORE_X_LOCK_CAPS))
191 else if ((col & XCB_MOD_MASK_SHIFT) ||
192 (col & XCB_MOD_MASK_LOCK && (col & ECORE_X_LOCK_SHIFT)))
195 return XCB_NO_SYMBOL;
199 _ecore_xcb_keymap_keysym_to_keycode(xcb_keysym_t keysym)
202 return xcb_key_symbols_get_keycode(_ecore_xcb_keysyms, keysym);
206 _ecore_xcb_keymap_keysym_to_string(xcb_keysym_t keysym)
208 int i = 0, n = 0, h = 0, idx = 0;
209 const unsigned char *entry;
210 unsigned char val1, val2, val3, val4;
213 if (!keysym) return NULL;
214 if (keysym == XK_VoidSymbol) keysym = 0;
215 if (keysym <= 0x1fffffff)
217 val1 = (keysym >> 24);
218 val2 = ((keysym >> 16) & 0xff);
219 val3 = ((keysym >> 8) & 0xff);
220 val4 = (keysym & 0xff);
221 i = keysym % VTABLESIZE;
224 while ((idx = hashKeysym[i]))
226 entry = &_ecore_xcb_keytable[idx];
227 if ((entry[0] == val1) && (entry[1] == val2) &&
228 (entry[2] == val3) && (entry[3] == val4))
229 return (char *)entry + 4;
232 if (i >= VTABLESIZE) i -= VTABLESIZE;
236 if ((keysym >= 0x01000100) && (keysym <= 0x0110ffff))
242 val = (keysym & 0xffffff);
248 if (!(s = malloc(i))) return NULL;
258 s[i] = 'A' + val1 - 10;
268 _ecore_xcb_keymap_string_to_keycode(const char *key)
270 if (!strncmp(key, "Keycode-", 8))
271 return atoi(key + 8);
274 xcb_keysym_t keysym = XCB_NO_SYMBOL;
275 xcb_keycode_t *keycodes, keycode = 0;
280 keysym = _ecore_xcb_keymap_string_to_keysym(key);
281 if (keysym == XCB_NO_SYMBOL) return XCB_NO_SYMBOL;
283 keycodes = _ecore_xcb_keymap_keysym_to_keycode(keysym);
284 if (!keycodes) return XCB_NO_SYMBOL;
286 while (keycodes[i] != XCB_NO_SYMBOL)
288 if (keycodes[i] != 0)
290 keycode = keycodes[i];
300 _ecore_xcb_keymap_lookup_string(xcb_keycode_t keycode,
306 unsigned int modifiers = 0;
310 if (!_ecore_xcb_keymap_translate_key(keycode, state, &modifiers, &keysym))
313 if (sym) *sym = keysym;
315 return _ecore_xcb_keymap_translate_keysym(keysym, state, buffer, bytes);
319 ecore_x_keysym_string_get(int keysym)
321 LOGFN(__FILE__, __LINE__, __FUNCTION__);
323 return _ecore_xcb_keymap_keysym_to_string(keysym);
327 ecore_x_keysym_keycode_get(const char *keyname)
329 LOGFN(__FILE__, __LINE__, __FUNCTION__);
331 return _ecore_xcb_keymap_string_to_keycode(keyname);
335 ecore_x_keysym_get(const char *string)
337 return _ecore_xcb_keymap_string_to_keysym(string);
340 /* local functions */
342 _ecore_xcb_keymap_mask_get(void *reply,
345 xcb_get_modifier_mapping_reply_t *rep;
350 XCB_MOD_MASK_SHIFT, XCB_MOD_MASK_LOCK, XCB_MOD_MASK_CONTROL,
351 XCB_MOD_MASK_1, XCB_MOD_MASK_2, XCB_MOD_MASK_3, XCB_MOD_MASK_4,
355 LOGFN(__FILE__, __LINE__, __FUNCTION__);
358 rep = (xcb_get_modifier_mapping_reply_t *)reply;
359 if ((rep) && (rep->keycodes_per_modifier > 0))
362 xcb_keycode_t *modmap;
364 modmap = xcb_get_modifier_mapping_keycodes(rep);
365 for (i = 0; i < (8 * rep->keycodes_per_modifier); i++)
369 for (j = 0; j < 8; j++)
371 sym2 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms,
373 if (sym2 != 0) break;
375 if (sym2 == sym) mask = masks[i / rep->keycodes_per_modifier];
382 _ecore_xcb_keymap_string_to_keysym(const char *str)
384 int i = 0, n = 0, h = 0;
385 unsigned long sig = 0;
386 const char *p = NULL;
388 const unsigned char *entry;
389 unsigned char sig1, sig2;
390 long unsigned int val;
394 sig = (sig << 1) + c;
396 i = (sig % KTABLESIZE);
398 sig1 = (sig >> 8) & 0xff;
402 while ((idx = hashString[i]))
404 entry = &_ecore_xcb_keytable[idx];
405 if ((entry[0] == sig1) && (entry[1] == sig2) &&
406 !strcmp(str, (char *)entry + 6))
408 val = ((entry[2] << 24) | (entry[3] << 16) |
409 (entry[4] << 8) | (entry[5]));
410 if (!val) val = 0xffffff;
415 if (i >= KTABLESIZE) i -= KTABLESIZE;
421 for (p = &str[1]; *p; p++)
424 if (('0' <= c) && (c <= '9'))
425 val = (val << 4) + c - '0';
426 else if (('a' <= c) && (c <= 'f'))
427 val = (val << 4) + c - 'a' + 10;
428 else if (('A' <= c) && (c <= 'F'))
429 val = (val << 4) + c - 'A' + 10;
431 return XCB_NO_SYMBOL;
432 if (val > 0x10ffff) return XCB_NO_SYMBOL;
434 if ((val < 0x20) || ((val > 0x7e) && (val < 0xa0)))
435 return XCB_NO_SYMBOL;
436 if (val < 0x100) return val;
437 return val | 0x01000000;
440 if ((strlen(str) > 2) && (str[0] == '0') && (str[1] == 'x'))
444 val = strtoul(str, &tmp, 16);
445 if ((val == ULONG_MAX) || ((tmp) && (*tmp != '\0')))
446 return XCB_NO_SYMBOL;
451 if (!strncmp(str, "XF86_", 5))
453 long unsigned int ret;
457 if (!tmp) return XCB_NO_SYMBOL;
458 memmove(&tmp[4], &tmp[5], strlen(str) - 5 + 1);
459 ret = _ecore_xcb_keymap_string_to_keysym(tmp);
464 return XCB_NO_SYMBOL;
468 _ecore_xcb_keymap_translate_key(xcb_keycode_t keycode,
469 unsigned int modifiers,
470 unsigned int *modifiers_return,
471 xcb_keysym_t *keysym_return)
475 if (!_ecore_xcb_keysyms) return 0;
477 sym = _ecore_xcb_keymap_keycode_to_keysym(keycode, modifiers);
479 if (modifiers_return)
480 *modifiers_return = ((XCB_MOD_MASK_SHIFT | XCB_MOD_MASK_LOCK) |
481 _ecore_xcb_mode_switch | ECORE_X_LOCK_NUM);
483 *keysym_return = sym;
489 _ecore_xcb_keymap_translate_keysym(xcb_keysym_t keysym,
490 unsigned int modifiers,
494 unsigned long hbytes = 0;
497 if (!keysym) return 0;
498 hbytes = (keysym >> 8);
503 (((keysym >= XK_BackSpace) && (keysym <= XK_Clear)) ||
504 (keysym == XK_Return) || (keysym == XK_Escape) ||
505 (keysym == XK_KP_Space) || (keysym == XK_KP_Tab) ||
506 (keysym == XK_KP_Enter) ||
507 ((keysym >= XK_KP_Multiply) && (keysym <= XK_KP_9)) ||
508 (keysym == XK_KP_Equal) || (keysym == XK_Delete))))))
511 if (keysym == XK_KP_Space)
512 c = (XK_space & 0x7F);
513 else if (hbytes == 0xFF)
518 if (modifiers & ECORE_X_MODIFIER_CTRL)
520 if (((c >= '@') && (c < '\177')) || c == ' ')
524 else if ((c >= '3') && (c <= '7'))