3 #endif /* ifdef HAVE_CONFIG_H */
10 #endif /* ifdef LOGRT */
12 #include "ecore_x_private.h"
14 #include "Ecore_X_Atoms.h"
17 //////////////////////////////////////////////////////////////////////////////
18 // This api and structure only for the key router and window client side
19 // Application do not use this
21 //this mask is defined by key router.
22 //after discussing with keyrouter module, this mask can be changed
23 #define GRAB_MASK 0xffff00
24 #define OVERRIDE_EXCLUSIVE_GRAB 0xf00000
25 #define EXCLUSIVE_GRAB 0x0f0000
26 #define TOPMOST_GRAB 0x00f000
27 #define SHARED_GRAB 0x000f00
29 //if _ecore_keyrouter = 0, not yet check keyrouter
30 //if _ecore_keyrouter = -1, keyrouter not exist
31 //if _ecore_keyrouter = 1, keyrouter exist
32 int _ecore_keyrouter = 0;
34 struct _Ecore_X_Window_Key_Table
36 Ecore_X_Window win; //windo ID
37 int *key_list; //list of key
38 unsigned long key_cnt; // the number of key
41 typedef struct _Ecore_X_Window_Key_Table Ecore_X_Window_Key_Table;
43 static int _ecore_x_window_keytable_key_search(Ecore_X_Window_Key_Table *keytable, int key);
44 static Eina_Bool _ecore_x_window_keytable_key_del(Ecore_X_Window_Key_Table *key_table, int key, Ecore_X_Atom keytable_atom);
46 static Eina_Bool _ecore_x_window_keytable_key_add(Ecore_X_Window_Key_Table *keytable,
48 Ecore_X_Win_Keygrab_Mode grab_mode);
50 static Eina_Bool _ecore_x_window_keygrab_set_internal(Ecore_X_Window win, const char *key, Ecore_X_Win_Keygrab_Mode grab_mode);
51 static Eina_Bool _ecore_x_window_keygrab_unset_internal(Ecore_X_Window win, const char *key);
52 static Eina_Bool _ecore_x_window_keytable_get(Ecore_X_Window win, Ecore_X_Window_Key_Table *keytable);
55 //(Below Atom and exclusiveness_get/set functions) should be changed after keyrouter finds the solution to avoid race condition
56 //solution 1. window manages two key table. keytable and keytable result
57 //solution 2. using client messabe between the window client and the key router.
59 static Atom _atom_grab_excl_win = None;
60 #define STR_ATOM_GRAB_EXCL_WIN "_GRAB_EXCL_WIN_KEYCODE"
63 _keytable_free(Ecore_X_Window_Key_Table *keytable)
65 if (keytable->key_list)
66 free(keytable->key_list);
67 keytable->key_list = NULL;
69 keytable->key_cnt = 0;
73 _keytable_property_list_get(Ecore_X_Window win,
77 unsigned char *prop_ret;
79 unsigned long bytes_after, num_ret;
86 if (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
87 XA_CARDINAL, &type_ret, &format_ret, &num_ret,
88 &bytes_after, &prop_ret) != Success)
90 WRN("XGetWindowProperty failed");
93 else if ((num_ret == 0) || (!prop_ret))
97 val = malloc(num_ret * sizeof(unsigned int));
100 if (prop_ret) XFree(prop_ret);
101 WRN("Memory alloc failed");
104 for (i = 0; i < num_ret; i++)
105 val[i] = ((unsigned long *)prop_ret)[i];
110 if (_ecore_xlib_sync) ecore_x_sync();
117 _ecore_x_window_keytable_possible_global_exclusiveness_get(int keycode)
121 Ecore_X_Window_Key_Table keytable;
123 keytable.win = ecore_x_window_root_first_get();
124 keytable.key_list = NULL;
125 keytable.key_cnt = 0;
127 if(_atom_grab_excl_win == None )
128 _atom_grab_excl_win = XInternAtom(_ecore_x_disp, STR_ATOM_GRAB_EXCL_WIN, False);
130 ret = _keytable_property_list_get(keytable.win, _atom_grab_excl_win,
131 (unsigned int **)&(keytable.key_list));
138 keytable.key_cnt = ret;
140 if (keytable.key_cnt == 0)
142 WRN("There is no keygrab entry in the table");
146 //check keycode exists in the global exclusiveness keytable
148 ret = _ecore_x_window_keytable_key_search(&keytable, keycode);
151 WRN("Can't search keygrab entry in the table");
152 _keytable_free(&keytable);
155 _keytable_free(&keytable);
160 _ecore_x_window_keytable_possible_global_exclusiveness_set(int keycode)
164 Ecore_X_Window_Key_Table keytable;
166 keytable.win = ecore_x_window_root_first_get();
167 keytable.key_list = NULL;
168 keytable.key_cnt = 0;
170 if(_atom_grab_excl_win == None )
171 _atom_grab_excl_win = XInternAtom(_ecore_x_disp, STR_ATOM_GRAB_EXCL_WIN, False);
173 ret = _keytable_property_list_get(keytable.win, _atom_grab_excl_win,
174 (unsigned int **)&(keytable.key_list));
175 if (ret < 0) return EINA_FALSE;
177 keytable.key_cnt = ret;
179 if (keytable.key_cnt == 0)
181 XChangeProperty(_ecore_x_disp, keytable.win, _atom_grab_excl_win, XA_CARDINAL, 32,
182 PropModeReplace, (unsigned char *)&keycode, 1);
183 XSync(_ecore_x_disp, False);
184 _keytable_free(&keytable);
188 //check keycode exists in the global exclusiveness keytable
189 ret = _ecore_x_window_keytable_key_search(&keytable, keycode);
192 XChangeProperty(_ecore_x_disp, keytable.win, _atom_grab_excl_win, XA_CARDINAL, 32,
193 PropModeAppend, (unsigned char *)&keycode, 1);
194 XSync(_ecore_x_disp, False);
195 _keytable_free(&keytable);
198 WRN("Already key is grabbed");
199 _keytable_free(&keytable);
204 _ecore_x_window_keytable_possible_global_exclusiveness_unset(int keycode)
208 Ecore_X_Window_Key_Table keytable;
210 keytable.win = ecore_x_window_root_first_get();
211 keytable.key_list = NULL;
212 keytable.key_cnt = 0;
214 if(_atom_grab_excl_win == None )
215 _atom_grab_excl_win = XInternAtom(_ecore_x_disp, STR_ATOM_GRAB_EXCL_WIN, False);
217 ret = _keytable_property_list_get(keytable.win, _atom_grab_excl_win,
218 (unsigned int **)&(keytable.key_list));
219 if (ret <= 0) return EINA_FALSE;
221 keytable.key_cnt = ret;
223 //check keycode exists in the global exclusiveness keytable
224 ret = _ecore_x_window_keytable_key_search(&keytable, keycode);
227 WRN("Already key exists");
228 _keytable_free(&keytable);
232 ret = _ecore_x_window_keytable_key_del(&keytable, keycode, _atom_grab_excl_win);
234 _keytable_free(&keytable);
239 _ecore_x_window_keytable_keycode_decode(int keycode_encoded,
241 Ecore_X_Win_Keygrab_Mode *grab_mode)
245 *keycode = keycode_encoded & (~GRAB_MASK);
246 key_mask = keycode_encoded & GRAB_MASK;
248 if (key_mask == SHARED_GRAB)
250 *grab_mode = ECORE_X_WIN_KEYGRAB_SHARED;
253 else if (key_mask == TOPMOST_GRAB)
255 *grab_mode = ECORE_X_WIN_KEYGRAB_TOPMOST;
258 else if (key_mask == EXCLUSIVE_GRAB)
260 *grab_mode = ECORE_X_WIN_KEYGRAB_EXCLUSIVE;
263 else if (key_mask == OVERRIDE_EXCLUSIVE_GRAB)
265 *grab_mode = ECORE_X_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE;
270 *grab_mode = ECORE_X_WIN_KEYGRAB_UNKNOWN;
271 WRN("Keycode decoding failed. Unknown Keygrab mode");
277 _ecore_x_window_keytable_keycode_encode(int keycode,
278 Ecore_X_Win_Keygrab_Mode grab_mode,
279 int *keycode_encoded)
281 if ((grab_mode <= ECORE_X_WIN_KEYGRAB_UNKNOWN) || (grab_mode > ECORE_X_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE))
283 *keycode_encoded = 0;
284 WRN("Keycode encoding failed. Unknown Keygrab mode");
287 if (grab_mode == ECORE_X_WIN_KEYGRAB_SHARED)
288 *keycode_encoded = keycode | SHARED_GRAB;
289 else if (grab_mode == ECORE_X_WIN_KEYGRAB_TOPMOST)
290 *keycode_encoded = keycode | TOPMOST_GRAB;
291 else if (grab_mode == ECORE_X_WIN_KEYGRAB_EXCLUSIVE)
292 *keycode_encoded = keycode | EXCLUSIVE_GRAB;
293 else if (grab_mode == ECORE_X_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE)
294 *keycode_encoded = keycode | OVERRIDE_EXCLUSIVE_GRAB;
299 _ecore_x_window_keytable_get(Ecore_X_Window win,
300 Ecore_X_Window_Key_Table *keytable)
304 ret = _keytable_property_list_get(win, ECORE_X_ATOM_E_KEYROUTER_WINDOW_KEYTABLE,
305 (unsigned int **)&(keytable->key_list));
306 if (ret < 0) return EINA_FALSE;
308 keytable->key_cnt = ret;
314 _ecore_x_window_keytable_key_search(Ecore_X_Window_Key_Table *keytable,
319 unsigned long key_cnt;
320 int *key_list = NULL;
322 keycode = key & (~GRAB_MASK);
323 key_cnt = keytable->key_cnt;
324 key_list = keytable->key_list;
326 for (i = key_cnt - 1; i >= 0; i--)
328 if ((key_list[i] & (~GRAB_MASK)) == keycode) break;
335 _ecore_x_window_keytable_key_add(Ecore_X_Window_Key_Table *keytable,
337 Ecore_X_Win_Keygrab_Mode grab_mode)
340 int keycode_masked = 0;
343 unsigned long key_cnt;
346 key_cnt = keytable->key_cnt;
348 if (!_ecore_x_window_keytable_keycode_encode(keycode, grab_mode, &keycode_masked))
353 XChangeProperty(_ecore_x_disp, win, ECORE_X_ATOM_E_KEYROUTER_WINDOW_KEYTABLE, XA_CARDINAL, 32,
354 PropModeReplace, (unsigned char *)&keycode_masked, 1);
355 XSync(_ecore_x_disp, False);
360 i = _ecore_x_window_keytable_key_search(keytable, keycode_masked);
363 //already exist key in key table
364 WRN("Already key exists");
367 XChangeProperty(_ecore_x_disp, win, ECORE_X_ATOM_E_KEYROUTER_WINDOW_KEYTABLE, XA_CARDINAL, 32,
368 PropModeAppend, (unsigned char *)&keycode_masked, 1);
369 XSync(_ecore_x_disp, False);
375 _ecore_x_window_keytable_key_del(Ecore_X_Window_Key_Table *key_table,
377 Ecore_X_Atom keytable_atom)
380 int *new_key_list = NULL;
381 unsigned long key_cnt = 0;
383 // Only one element is exists in the list of grabbed key
384 i = _ecore_x_window_keytable_key_search(key_table, key);
388 WRN("Key doesn't exist in the key table.");
392 (key_table->key_cnt)--;
393 key_cnt = key_table->key_cnt;
397 XDeleteProperty(_ecore_x_disp, key_table->win, keytable_atom);
398 XSync(_ecore_x_disp, False);
403 new_key_list = malloc((key_cnt) * sizeof(int));
405 if (new_key_list == NULL)
410 memcpy(new_key_list, key_table->key_list, sizeof(int) * i);
413 if ((key_cnt) - i > 0)
415 memcpy(new_key_list + i,
416 key_table->key_list + i + 1,
417 sizeof(int) * (key_cnt - i));
420 XChangeProperty(_ecore_x_disp, key_table->win, keytable_atom, XA_CARDINAL, 32,
421 PropModeReplace, (unsigned char *)new_key_list, key_cnt);
422 XSync(_ecore_x_disp, False);
429 _ecore_x_window_keygrab_set_internal(Ecore_X_Window win,
431 Ecore_X_Win_Keygrab_Mode grab_mode)
436 Eina_Bool ret = EINA_FALSE;
437 Ecore_X_Window_Key_Table keytable;
440 keytable.key_list = NULL;
441 keytable.key_cnt = 0;
444 //check the key string
445 if (!strncmp(key, "Keycode-", 8))
446 keycode = atoi(key + 8);
449 keysym = XStringToKeysym(key);
450 if (keysym == NoSymbol)
452 WRN("Keysym of key(\"%s\") doesn't exist", key);
455 keycode = XKeysymToKeycode(_ecore_x_disp, keysym);
460 WRN("Keycode of key(\"%s\") doesn't exist", key);
464 if(grab_mode == ECORE_X_WIN_KEYGRAB_EXCLUSIVE)
466 //Only one window can grab this key;
467 //keyrouter should avoid race condition
468 if (!_ecore_x_window_keytable_possible_global_exclusiveness_get(keycode))
472 if (!_ecore_x_window_keytable_get(win, &keytable))
475 ret = _ecore_x_window_keytable_key_add(&keytable, keycode, grab_mode);
480 WRN("Key(\"%s\") add failed", key);
484 if(grab_mode == ECORE_X_WIN_KEYGRAB_EXCLUSIVE)
486 //Only one window can grab this key;
487 if(!_ecore_x_window_keytable_possible_global_exclusiveness_set(keycode))
489 _ecore_x_window_keytable_key_del(&keytable, keycode, ECORE_X_ATOM_E_KEYROUTER_WINDOW_KEYTABLE);
490 WRN("Key(\"%s\") already is grabbed", key);
495 _keytable_free(&keytable);
498 _keytable_free(&keytable);
503 _ecore_x_window_keygrab_unset_internal(Ecore_X_Window win,
513 Eina_Bool ret = EINA_FALSE;
515 Ecore_X_Window_Key_Table keytable;
516 Ecore_X_Win_Keygrab_Mode grab_mode = ECORE_X_WIN_KEYGRAB_UNKNOWN;
519 keytable.key_list = NULL;
520 keytable.key_cnt = 0;
522 if (!strncmp(key, "Keycode-", 8))
523 keycode = atoi(key + 8);
526 keysym = XStringToKeysym(key);
527 if (keysym == NoSymbol)
529 WRN("Keysym of key(\"%s\") doesn't exist", key);
532 keycode = XKeysymToKeycode(_ecore_x_disp, keysym);
537 WRN("Keycode of key(\"%s\") doesn't exist", key);
541 //construct the keytable structure using Xproperty
542 if (!_ecore_x_window_keytable_get(win, &keytable))
545 if (keytable.key_cnt <= 0)
548 i = _ecore_x_window_keytable_key_search(&keytable, keycode);
550 if (i == -1) //cannot find key in keytable
552 WRN("Key(\"%s\") doesn't exist", key);
556 //find key in keytable
557 key_masked = keytable.key_list[i];
559 ret = _ecore_x_window_keytable_keycode_decode(key_masked, &key_decoded, &grab_mode);
564 ret = _ecore_x_window_keytable_key_del(&keytable, key_masked, ECORE_X_ATOM_E_KEYROUTER_WINDOW_KEYTABLE);
568 if (grab_mode == ECORE_X_WIN_KEYGRAB_EXCLUSIVE)
570 ret = _ecore_x_window_keytable_possible_global_exclusiveness_unset(keycode);
573 _keytable_free(&keytable);
576 _keytable_free(&keytable);
581 ecore_x_window_keygrab_set(Ecore_X_Window win,
584 int not_mod EINA_UNUSED,
585 int priority EINA_UNUSED,
586 Ecore_X_Win_Keygrab_Mode grab_mode)
588 if (_ecore_keyrouter == 0)
590 if(ecore_x_e_keyrouter_get(win))
591 _ecore_keyrouter = 1;
594 WRN("Keyrouter is not supported");
595 _ecore_keyrouter = -1;
598 if (_ecore_keyrouter < 0)
601 return _ecore_x_window_keygrab_set_internal(win, key, grab_mode);
605 ecore_x_window_keygrab_unset(Ecore_X_Window win,
608 int any_mod EINA_UNUSED)
610 if (_ecore_keyrouter != 1)
612 WRN("Keyrouter is not supported");
616 return _ecore_x_window_keygrab_unset_internal(win, key);