1 #include "ecore_xcb_private.h"
3 //////////////////////////////////////////////////////////////////////////////
4 // This api and structure only for the key router and window client side
5 // Application do not use this
7 //this mask is defined by key router.
8 //after discussing with keyrouter module, this mask can be changed
9 #define GRAB_MASK 0xffff00
10 #define OVERRIDE_EXCLUSIVE_GRAB 0xf00000
11 #define EXCLUSIVE_GRAB 0x0f0000
12 #define TOPMOST_GRAB 0x00f000
13 #define SHARED_GRAB 0x000f00
15 //if _ecore_keyrouter = 0, not yet check keyrouter
16 //if _ecore_keyrouter = -1, keyrouter not exist
17 //if _ecore_keyrouter = 1, keyrouter exist
18 int _ecore_keyrouter = 0;
20 typedef struct _Ecore_X_Window_Key_Table
22 Ecore_X_Window win; //windo ID
23 int *key_list; //list of key
24 unsigned long key_cnt; // the number of key
25 } Ecore_X_Window_Key_Table;
27 static Ecore_X_Atom _atom_grab_excl_win = XCB_NONE;
28 #define STR_ATOM_GRAB_EXCL_WIN "_GRAB_EXCL_WIN_KEYCODE"
31 _keytable_free(Ecore_X_Window_Key_Table *keytable)
33 if (keytable->key_list) free(keytable->key_list);
34 keytable->key_list = NULL;
36 keytable->key_cnt = 0;
40 _keytable_property_list_get(Ecore_X_Window win, Ecore_X_Atom atom, unsigned int **plst)
42 return ecore_x_window_prop_card32_list_get(win, atom, plst);
46 _keytable_get(Ecore_X_Window win, Ecore_X_Window_Key_Table *keytable)
50 ret = _keytable_property_list_get(win, ECORE_X_ATOM_E_KEYROUTER_WINDOW_KEYTABLE,
51 (unsigned int **)&(keytable->key_list));
52 if (ret < 0) return EINA_FALSE;
54 keytable->key_cnt = ret;
59 _keytable_keycode_decode(int encoded, int *keycode, Ecore_X_Win_Keygrab_Mode *grab_mode)
63 *keycode = encoded & (~GRAB_MASK);
64 mask = encoded & GRAB_MASK;
66 if (mask == SHARED_GRAB)
67 *grab_mode = ECORE_X_WIN_KEYGRAB_SHARED;
68 else if (mask == TOPMOST_GRAB)
69 *grab_mode = ECORE_X_WIN_KEYGRAB_TOPMOST;
70 else if (mask == EXCLUSIVE_GRAB)
71 *grab_mode = ECORE_X_WIN_KEYGRAB_EXCLUSIVE;
72 else if (mask == OVERRIDE_EXCLUSIVE_GRAB)
73 *grab_mode = ECORE_X_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE;
76 *grab_mode = ECORE_X_WIN_KEYGRAB_UNKNOWN;
77 WRN("Keycode decoding failed. Unknown Keygrab mode");
85 _keytable_keycode_encode(int keycode, Ecore_X_Win_Keygrab_Mode grab_mode, int *encoded)
87 if ((grab_mode <= ECORE_X_WIN_KEYGRAB_UNKNOWN) ||
88 (grab_mode > ECORE_X_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE))
91 WRN("Keycode encoding failed. Unknown Keygrab mode");
95 if (grab_mode == ECORE_X_WIN_KEYGRAB_SHARED)
96 *encoded = keycode | SHARED_GRAB;
97 else if (grab_mode == ECORE_X_WIN_KEYGRAB_TOPMOST)
98 *encoded = keycode | TOPMOST_GRAB;
99 else if (grab_mode == ECORE_X_WIN_KEYGRAB_EXCLUSIVE)
100 *encoded = keycode | EXCLUSIVE_GRAB;
101 else if (grab_mode == ECORE_X_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE)
102 *encoded = keycode | OVERRIDE_EXCLUSIVE_GRAB;
108 _keytable_key_search(Ecore_X_Window_Key_Table *keytable, int key)
110 int i, code = 0, *list = NULL;
113 code = key & (~GRAB_MASK);
114 count = keytable->key_cnt;
115 list = keytable->key_list;
117 for (i = count - 1; i >= 0; i--)
118 if ((list[i] & (~GRAB_MASK)) == code) break;
124 _keytable_key_add(Ecore_X_Window_Key_Table *keytable, int keycode, Ecore_X_Win_Keygrab_Mode grab_mode)
128 int i = 0, masked = 0;
131 count = keytable->key_cnt;
133 if (!_keytable_keycode_encode(keycode, grab_mode, &masked))
138 xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
139 ECORE_X_ATOM_E_KEYROUTER_WINDOW_KEYTABLE,
140 ECORE_X_ATOM_CARDINAL, 32, 1,
141 (unsigned char *)&masked);
146 i = _keytable_key_search(keytable, masked);
149 WRN("Key already exists");
152 xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_APPEND, win,
153 ECORE_X_ATOM_E_KEYROUTER_WINDOW_KEYTABLE,
154 ECORE_X_ATOM_CARDINAL, 32, 1,
155 (unsigned char *)&masked);
161 _keytable_key_del(Ecore_X_Window_Key_Table *keytable, int key, Ecore_X_Atom atom)
163 int i, *new_key_list = NULL;
164 unsigned long count = 0;
166 i = _keytable_key_search(keytable, key);
169 WRN("Key does not exist in the key table");
174 count = keytable->key_cnt;
177 ecore_x_window_prop_property_del(keytable->win, atom);
181 new_key_list = malloc(count * sizeof(int));
182 if (!new_key_list) return EINA_FALSE;
185 memcpy(new_key_list, keytable->key_list, sizeof(int) * i);
188 memcpy(new_key_list + i, keytable->key_list + i + 1,
189 sizeof(int) * (count - i));
191 xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, keytable->win,
192 atom, ECORE_X_ATOM_CARDINAL, 32, count,
193 (unsigned char *)new_key_list);
200 _keytable_possible_global_exclusiveness_get(int keycode)
202 Ecore_X_Window_Key_Table keytable;
205 keytable.win = ecore_x_window_root_first_get();
206 keytable.key_list = NULL;
207 keytable.key_cnt = 0;
209 if (_atom_grab_excl_win == XCB_NONE)
210 _atom_grab_excl_win = ecore_x_atom_get(STR_ATOM_GRAB_EXCL_WIN);
212 ret = _keytable_property_list_get(keytable.win, _atom_grab_excl_win,
213 (unsigned int **)&(keytable.key_list));
214 if (ret < 0) return EINA_FALSE;
216 keytable.key_cnt = ret;
217 if (keytable.key_cnt == 0)
219 WRN("There is no keygrab entry in the table");
223 ret = _keytable_key_search(&keytable, keycode);
226 WRN("Can't search keygrab entry in the table");
227 _keytable_free(&keytable);
231 _keytable_free(&keytable);
236 _keytable_possible_global_exclusiveness_set(int keycode)
238 Ecore_X_Window_Key_Table keytable;
241 keytable.win = ecore_x_window_root_first_get();
242 keytable.key_list = NULL;
243 keytable.key_cnt = 0;
245 if (_atom_grab_excl_win == XCB_NONE)
246 _atom_grab_excl_win = ecore_x_atom_get(STR_ATOM_GRAB_EXCL_WIN);
248 ret = _keytable_property_list_get(keytable.win, _atom_grab_excl_win,
249 (unsigned int **)&(keytable.key_list));
250 if (ret < 0) return EINA_FALSE;
252 keytable.key_cnt = ret;
253 if (keytable.key_cnt == 0)
255 xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE,
256 keytable.win, _atom_grab_excl_win,
257 ECORE_X_ATOM_CARDINAL, 32, 1,
258 (unsigned char *)&keycode);
259 _keytable_free(&keytable);
263 ret = _keytable_key_search(&keytable, keycode);
266 xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_APPEND,
267 keytable.win, _atom_grab_excl_win,
268 ECORE_X_ATOM_CARDINAL, 32, 1,
269 (unsigned char *)&keycode);
270 _keytable_free(&keytable);
274 WRN("Key is already grabbed");
275 _keytable_free(&keytable);
280 _keytable_possible_global_exclusiveness_unset(int keycode)
282 Ecore_X_Window_Key_Table keytable;
285 keytable.win = ecore_x_window_root_first_get();
286 keytable.key_list = NULL;
287 keytable.key_cnt = 0;
289 if (_atom_grab_excl_win == XCB_NONE)
290 _atom_grab_excl_win = ecore_x_atom_get(STR_ATOM_GRAB_EXCL_WIN);
292 ret = _keytable_property_list_get(keytable.win, _atom_grab_excl_win,
293 (unsigned int **)&(keytable.key_list));
294 if (ret < 0) return EINA_FALSE;
296 keytable.key_cnt = ret;
298 ret = _keytable_key_search(&keytable, keycode);
301 WRN("Keygrab already exists");
302 _keytable_free(&keytable);
306 ret = _keytable_key_del(&keytable, keycode, _atom_grab_excl_win);
308 _keytable_free(&keytable);
313 _ecore_xcb_window_keygrab_set_internal(Ecore_X_Window win, const char *key, Ecore_X_Win_Keygrab_Mode grab_mode)
315 Ecore_X_Window_Key_Table keytable;
316 xcb_keycode_t keycode = 0;
317 Eina_Bool ret = EINA_FALSE;
320 keytable.key_list = NULL;
321 keytable.key_cnt = 0;
323 keycode = _ecore_xcb_keymap_string_to_keycode(key);
324 if (keycode == XCB_NO_SYMBOL)
326 WRN("Keycode of key(\"%s\") does not exist", key);
330 if (grab_mode == ECORE_X_WIN_KEYGRAB_EXCLUSIVE)
332 if (!_keytable_possible_global_exclusiveness_get(keycode))
336 if (!_keytable_get(win, &keytable)) return EINA_FALSE;
338 ret = _keytable_key_add(&keytable, keycode, grab_mode);
341 WRN("Key(\"%s\") add failed", key);
345 if (grab_mode == ECORE_X_WIN_KEYGRAB_EXCLUSIVE)
347 if (!_keytable_possible_global_exclusiveness_set(keycode))
349 _keytable_key_del(&keytable, keycode, ECORE_X_ATOM_E_KEYROUTER_WINDOW_KEYTABLE);
350 WRN("Key(\"%s\") already is grabbed", key);
355 _keytable_free(&keytable);
359 _keytable_free(&keytable);
364 _ecore_xcb_window_keygrab_unset_internal(Ecore_X_Window win, const char *key)
366 Ecore_X_Window_Key_Table keytable;
367 Ecore_X_Win_Keygrab_Mode grab_mode = ECORE_X_WIN_KEYGRAB_UNKNOWN;
368 xcb_keycode_t keycode = 0;
369 int i, masked = 0, decoded = 0;
370 Eina_Bool ret = EINA_FALSE;
373 keytable.key_list = NULL;
374 keytable.key_cnt = 0;
376 keycode = _ecore_xcb_keymap_string_to_keycode(key);
377 if (keycode == XCB_NO_SYMBOL)
379 WRN("Keycode of key(\"%s\") does not exist", key);
383 if (!_keytable_get(win, &keytable)) return EINA_FALSE;
385 if (keytable.key_cnt <= 0) return EINA_FALSE;
387 i = _keytable_key_search(&keytable, keycode);
390 WRN("Key(\"%s\") does not exist", key);
394 masked = keytable.key_list[i];
396 ret = _keytable_keycode_decode(masked, &decoded, &grab_mode);
399 ret = _keytable_key_del(&keytable, masked, ECORE_X_ATOM_E_KEYROUTER_WINDOW_KEYTABLE);
402 if (grab_mode == ECORE_X_WIN_KEYGRAB_EXCLUSIVE)
403 ret = _keytable_possible_global_exclusiveness_unset(keycode);
405 _keytable_free(&keytable);
409 _keytable_free(&keytable);
414 ecore_x_window_keygrab_set(Ecore_X_Window win, const char *key, int mod EINA_UNUSED, int not_mod EINA_UNUSED, int priority EINA_UNUSED, Ecore_X_Win_Keygrab_Mode grab_mode)
416 if (_ecore_keyrouter == 0)
418 if (ecore_x_e_keyrouter_get(win))
419 _ecore_keyrouter = 1;
422 WRN("Keyrouter is not supported");
423 _ecore_keyrouter = -1;
427 if (_ecore_keyrouter < 0) return EINA_FALSE;
429 return _ecore_xcb_window_keygrab_set_internal(win, key, grab_mode);
433 ecore_x_window_keygrab_unset(Ecore_X_Window win, const char *key, int mod EINA_UNUSED, int any_mod EINA_UNUSED)
435 if (_ecore_keyrouter != 1)
437 WRN("Keyrouter is not supported");
441 return _ecore_xcb_window_keygrab_unset_internal(win, key);