1 #include "e_keyrouter_private.h"
3 static int _e_keyrouter_find_duplicated_client(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode);
4 static Eina_Bool _e_keyrouter_find_key_in_list(struct wl_resource *surface, struct wl_client *wc, int key, int mode);
5 static Eina_List **_e_keyrouter_get_list(int mode, int key);
7 /* add a new key grab info to the list */
9 e_keyrouter_set_keygrab_in_list(struct wl_resource *surface, struct wl_client *client, uint32_t key, uint32_t mode)
11 int res = TIZEN_KEYROUTER_ERROR_NONE;
13 EINA_SAFETY_ON_FALSE_RETURN_VAL
14 (((mode == TIZEN_KEYROUTER_MODE_EXCLUSIVE) ||
15 (mode == TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE) ||
16 (mode == TIZEN_KEYROUTER_MODE_TOPMOST) ||
17 (mode == TIZEN_KEYROUTER_MODE_SHARED)),
18 TIZEN_KEYROUTER_ERROR_INVALID_MODE);
20 if (mode == TIZEN_KEYROUTER_MODE_EXCLUSIVE)
22 EINA_SAFETY_ON_TRUE_RETURN_VAL
23 ((krt->HardKeys[key].excl_ptr != NULL),
24 TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY);
27 if (mode == TIZEN_KEYROUTER_MODE_TOPMOST)
29 EINA_SAFETY_ON_NULL_RETURN_VAL
30 (surface, TIZEN_KEYROUTER_ERROR_INVALID_SURFACE);
33 res = e_keyrouter_prepend_to_keylist(surface,
34 surface ? NULL : client,
39 EINA_SAFETY_ON_FALSE_RETURN_VAL(res == TIZEN_KEYROUTER_ERROR_NONE, res);
44 /* Function for checking whether the key has been grabbed already by the same wl_surface or not */
46 _e_keyrouter_find_duplicated_client(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode)
48 Eina_List *keylist_ptr = NULL, *l = NULL;
49 E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
53 case TIZEN_KEYROUTER_MODE_EXCLUSIVE:
54 return TIZEN_KEYROUTER_ERROR_NONE;
56 case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE:
57 keylist_ptr = krt->HardKeys[key].or_excl_ptr;
60 case TIZEN_KEYROUTER_MODE_TOPMOST:
61 keylist_ptr = krt->HardKeys[key].top_ptr;
64 case TIZEN_KEYROUTER_MODE_SHARED:
65 keylist_ptr = krt->HardKeys[key].shared_ptr;
68 case TIZEN_KEYROUTER_MODE_PRESSED:
69 keylist_ptr = krt->HardKeys[key].press_ptr;
72 case TIZEN_KEYROUTER_MODE_PICTURE_OFF:
73 keylist_ptr = krt->HardKeys[key].pic_off_ptr;
76 KLWRN("Unknown key(%d) and grab mode(%d)", key, mode);
77 return TIZEN_KEYROUTER_ERROR_INVALID_MODE;
80 EINA_LIST_FOREACH(keylist_ptr, l, key_node_data)
82 if (!key_node_data) continue;
86 if (key_node_data->surface == surface)
88 KLDBG("The key(%d) is already grabbed same mode(%s) on the same wl_surface %p",
89 key, e_keyrouter_mode_to_string(mode), surface);
90 return TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY;
95 if (key_node_data->wc == wc)
97 KLDBG("The key(%d) is already grabbed same mode(%s) on the same wl_client %p",
98 key, e_keyrouter_mode_to_string(mode), wc);
99 return TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY;
104 return TIZEN_KEYROUTER_ERROR_NONE;
108 _e_keyrouter_find_key_in_list(struct wl_resource *surface, struct wl_client *wc, int key, int mode)
110 Eina_List **list = NULL;
111 Eina_List *l = NULL, *l_next = NULL;
112 E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
114 EINA_SAFETY_ON_TRUE_RETURN_VAL(((!surface) && (!wc)), EINA_FALSE);
116 list = _e_keyrouter_get_list(mode, key);
117 EINA_SAFETY_ON_NULL_RETURN_VAL(list, EINA_FALSE);
119 EINA_LIST_FOREACH_SAFE(*list, l, l_next, key_node_data)
121 if (!key_node_data) continue;
123 if ((surface) && (surface == key_node_data->surface)) return EINA_TRUE;
124 else if ((wc == key_node_data->wc)) return EINA_TRUE;
131 /* Function for prepending a new key grab information in the keyrouting list */
133 e_keyrouter_prepend_to_keylist(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode, Eina_Bool focused)
135 int res = TIZEN_KEYROUTER_ERROR_NONE;
137 res = _e_keyrouter_find_duplicated_client(surface, wc, key, mode);
140 E_Keyrouter_Key_List_NodePtr new_keyptr = E_NEW(E_Keyrouter_Key_List_Node, 1);
144 KLERR("Failled to allocate memory for new_keyptr");
145 return TIZEN_KEYROUTER_ERROR_NO_SYSTEM_RESOURCES;
148 new_keyptr->surface = surface;
150 new_keyptr->focused = focused;
151 new_keyptr->status = E_KRT_CSTAT_ALIVE;
155 case TIZEN_KEYROUTER_MODE_EXCLUSIVE:
156 krt->HardKeys[key].excl_ptr = eina_list_prepend(krt->HardKeys[key].excl_ptr, new_keyptr);
159 case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE:
160 krt->HardKeys[key].or_excl_ptr= eina_list_prepend(krt->HardKeys[key].or_excl_ptr, new_keyptr);
163 case TIZEN_KEYROUTER_MODE_TOPMOST:
164 krt->HardKeys[key].top_ptr = eina_list_prepend(krt->HardKeys[key].top_ptr, new_keyptr);
167 case TIZEN_KEYROUTER_MODE_SHARED:
168 krt->HardKeys[key].shared_ptr= eina_list_prepend(krt->HardKeys[key].shared_ptr, new_keyptr);
171 case TIZEN_KEYROUTER_MODE_PRESSED:
172 krt->HardKeys[key].press_ptr = eina_list_append(krt->HardKeys[key].press_ptr, new_keyptr);
175 case TIZEN_KEYROUTER_MODE_PICTURE_OFF:
176 krt->HardKeys[key].pic_off_ptr = eina_list_prepend(krt->HardKeys[key].pic_off_ptr, new_keyptr);
180 KLWRN("Unknown key(%d) and grab mode(%d)", key, mode);
182 return TIZEN_KEYROUTER_ERROR_INVALID_MODE;
185 if (TIZEN_KEYROUTER_MODE_PRESSED != mode)
189 e_keyrouter_wl_add_surface_destroy_listener(surface);
190 /* TODO: if failed add surface_destory_listener, remove keygrabs */
194 e_keyrouter_wl_add_client_destroy_listener(wc);
195 /* TODO: if failed add client_destory_listener, remove keygrabs */
199 return TIZEN_KEYROUTER_ERROR_NONE;
202 /* remove key grab info from the list */
204 e_keyrouter_find_and_remove_client_from_list(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode)
206 Eina_List **list = NULL;
207 Eina_List *l = NULL, *l_next = NULL;
208 E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
210 list = _e_keyrouter_get_list(mode, key);
211 EINA_SAFETY_ON_NULL_RETURN(list);
213 EINA_LIST_FOREACH_SAFE(*list, l, l_next, key_node_data)
215 if (!key_node_data) continue;
219 if (surface == key_node_data->surface)
221 if (mode == TIZEN_KEYROUTER_MODE_PRESSED)
223 key_node_data->status = E_KRT_CSTAT_UNGRAB;
227 *list = eina_list_remove_list(*list, l);
228 E_FREE(key_node_data);
230 KLDBG("Remove a %s Mode Grabbed key(%d) by surface(%p)", e_keyrouter_mode_to_string(mode), key, surface);
233 else if ((wc == key_node_data->wc))
235 if (mode == TIZEN_KEYROUTER_MODE_PRESSED)
237 key_node_data->status = E_KRT_CSTAT_UNGRAB;
241 *list = eina_list_remove_list(*list, l);
242 E_FREE(key_node_data);
244 KLDBG("Remove a %s Mode Grabbed key(%d) by wc(%p)", e_keyrouter_mode_to_string(mode), key, wc);
250 e_keyrouter_remove_client_from_list(struct wl_resource *surface, struct wl_client *wc)
253 Eina_List *l = NULL, *l_next = NULL;
254 E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
256 EINA_SAFETY_ON_TRUE_RETURN(((!surface) && (!wc)));
258 for (i = 0; i <= krt->max_tizen_hwkeys; i++)
260 if (0 == krt->HardKeys[i].keycode) continue;
262 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].excl_ptr, l, l_next, key_node_data)
264 if (!key_node_data) continue;
268 if (surface == key_node_data->surface)
270 krt->HardKeys[i].excl_ptr = eina_list_remove_list(krt->HardKeys[i].excl_ptr, l);
271 E_FREE(key_node_data);
272 KLDBG("Remove a Exclusive Mode Grabbed key(%d) by wl_surface(%p)", i, surface);
275 else if ((wc == key_node_data->wc))
277 krt->HardKeys[i].excl_ptr = eina_list_remove_list(krt->HardKeys[i].excl_ptr, l);
278 E_FREE(key_node_data);
279 KLDBG("Remove a Exclusive Mode Grabbed key(%d) by wl_client(%p)", i, wc);
282 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].or_excl_ptr, l, l_next, key_node_data)
284 if (!key_node_data) continue;
288 if (surface == key_node_data->surface)
290 krt->HardKeys[i].or_excl_ptr = eina_list_remove_list(krt->HardKeys[i].or_excl_ptr, l);
291 E_FREE(key_node_data);
292 KLDBG("Remove a Overridable_Exclusive Mode Grabbed key(%d) by wl_surface(%p)", i, surface);
295 else if ((wc == key_node_data->wc))
297 krt->HardKeys[i].or_excl_ptr = eina_list_remove_list(krt->HardKeys[i].or_excl_ptr, l);
298 E_FREE(key_node_data);
299 KLDBG("Remove a Overridable_Exclusive Mode Grabbed key(%d) by wl_client(%p)", i, wc);
302 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].top_ptr, l, l_next, key_node_data)
304 if (!key_node_data) continue;
308 if (surface == key_node_data->surface)
310 krt->HardKeys[i].top_ptr = eina_list_remove_list(krt->HardKeys[i].top_ptr, l);
311 E_FREE(key_node_data);
312 KLDBG("Remove a Topmost Mode Grabbed key(%d) by wl_surface(%p)", i, surface);
315 else if ((wc == key_node_data->wc))
317 krt->HardKeys[i].top_ptr = eina_list_remove_list(krt->HardKeys[i].top_ptr, l);
318 E_FREE(key_node_data);
319 KLDBG("Remove a Topmost Mode Grabbed key(%d) by wl_client(%p)", i, wc);
322 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].shared_ptr, l, l_next, key_node_data)
324 if (!key_node_data) continue;
328 if (surface == key_node_data->surface)
330 krt->HardKeys[i].shared_ptr = eina_list_remove_list(krt->HardKeys[i].shared_ptr, l);
331 E_FREE(key_node_data);
332 KLDBG("Remove a Shared Mode Grabbed key(%d) by wl_surface(%p)", i, surface);
335 else if ((wc == key_node_data->wc))
337 krt->HardKeys[i].shared_ptr = eina_list_remove_list(krt->HardKeys[i].shared_ptr, l);
338 E_FREE(key_node_data);
339 KLDBG("Remove a Shared Mode Grabbed key(%d) by wl_client(%p)", i, wc);
342 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].press_ptr, l, l_next, key_node_data)
344 if (!key_node_data) continue;
348 if (surface == key_node_data->surface)
350 key_node_data->status = E_KRT_CSTAT_DEAD;
351 KLDBG("Remove a Pressed key(%d) by wl_surface(%p)", i, surface);
352 key_node_data->wc = wl_resource_get_client(surface);
355 else if ((wc == key_node_data->wc))
357 key_node_data->status = E_KRT_CSTAT_DEAD;
358 KLDBG("Remove a Pressed key(%d) by wl_client(%p)", i, wc);
361 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].pic_off_ptr, l, l_next, key_node_data)
363 if (!key_node_data) continue;
366 if (surface == key_node_data->surface)
368 krt->HardKeys[i].pic_off_ptr = eina_list_remove_list(krt->HardKeys[i].pic_off_ptr, l);
369 E_FREE(key_node_data);
372 else if ( wc == key_node_data->wc)
374 krt->HardKeys[i].pic_off_ptr = eina_list_remove_list(krt->HardKeys[i].pic_off_ptr, l);
375 E_FREE(key_node_data);
382 e_keyrouter_find_key_in_list(struct wl_resource *surface, struct wl_client *wc, uint32_t key)
384 int mode = TIZEN_KEYROUTER_MODE_NONE;
385 Eina_Bool found = EINA_FALSE;
387 mode = TIZEN_KEYROUTER_MODE_EXCLUSIVE;
388 found = _e_keyrouter_find_key_in_list(surface, wc, key, mode);
389 if (found) goto finish;
391 mode = TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE;
392 found = _e_keyrouter_find_key_in_list(surface, wc, key, mode);
393 if (found) goto finish;
395 mode = TIZEN_KEYROUTER_MODE_TOPMOST;
396 found = _e_keyrouter_find_key_in_list(surface, wc, key, mode);
397 if (found) goto finish;
399 mode = TIZEN_KEYROUTER_MODE_SHARED;
400 found = _e_keyrouter_find_key_in_list(surface, wc, key, mode);
401 if (found) goto finish;
403 KLDBG("%d key is not grabbed by (wl_surface: %p, wl_client: %p)", key, surface, wc);
404 return TIZEN_KEYROUTER_MODE_NONE;
407 KLDBG("Find %d key grabbed by (wl_surface: %p, wl_client: %p) in %s mode",
408 key, surface, wc, e_keyrouter_mode_to_string(mode));
413 e_keyrouter_mode_to_string(uint32_t mode)
415 const char *str = NULL;
419 case TIZEN_KEYROUTER_MODE_EXCLUSIVE: str = "Exclusive"; break;
420 case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE: str = "Overridable_Exclusive"; break;
421 case TIZEN_KEYROUTER_MODE_TOPMOST: str = "Topmost"; break;
422 case TIZEN_KEYROUTER_MODE_SHARED: str = "Shared"; break;
423 case TIZEN_KEYROUTER_MODE_PRESSED: str = "Pressed"; break;
424 default: str = "UnknownMode"; break;
431 _e_keyrouter_get_list(int mode, int key)
433 Eina_List **list = NULL;
437 case TIZEN_KEYROUTER_MODE_EXCLUSIVE: list = &krt->HardKeys[key].excl_ptr; break;
438 case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE: list = &krt->HardKeys[key].or_excl_ptr; break;
439 case TIZEN_KEYROUTER_MODE_TOPMOST: list = &krt->HardKeys[key].top_ptr; break;
440 case TIZEN_KEYROUTER_MODE_SHARED: list = &krt->HardKeys[key].shared_ptr; break;
441 case TIZEN_KEYROUTER_MODE_PRESSED: list = &krt->HardKeys[key].press_ptr; break;
450 e_keyrouter_keygrab_set(struct wl_client *client, struct wl_resource *surface, int key, int mode)
455 if (EINA_FALSE == e_keyrouter_wl_util_do_privilege_check(client, mode, key))
457 KLINF("No permission for %d grab mode ! (key=%d)", mode, key);
458 return TIZEN_KEYROUTER_ERROR_NO_PERMISSION;
464 /* Regarding topmost mode, a client must request to grab a key with a valid surface. */
465 if (mode == TIZEN_KEYROUTER_MODE_TOPMOST)
467 KLWRN("Invalid surface for %d grab mode ! (key=%d)", mode, key);
469 return TIZEN_KEYROUTER_ERROR_INVALID_SURFACE;
473 /* Check the given key range */
474 if (krt->max_tizen_hwkeys < key)
476 KLWRN("Invalid range of key ! (keycode:%d)", key);
477 return TIZEN_KEYROUTER_ERROR_INVALID_KEY;
480 /* Check whether the key can be grabbed or not !
481 * Only key listed in Tizen key layout file can be grabbed. */
482 if (0 == krt->HardKeys[key].keycode)
484 KLWRN("Invalid key ! Disabled to grab ! (keycode:%d)", key);
485 return TIZEN_KEYROUTER_ERROR_INVALID_KEY;
488 /* Check whether the request key can be grabbed or not */
489 res = e_keyrouter_set_keygrab_in_list(surface, client, key, mode);
495 e_keyrouter_keygrab_unset(struct wl_client *client, struct wl_resource *surface, int key)
497 /* Ungrab top position grabs first. This grab mode do not need privilege */
499 e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_TOPMOST);
501 e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_TOPMOST);
504 if (EINA_FALSE == e_keyrouter_wl_util_do_privilege_check(client, TIZEN_KEYROUTER_MODE_NONE, key))
513 e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_EXCLUSIVE);
515 /* OVERRIDABLE_EXCLUSIVE grab */
516 e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
519 e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_SHARED);
522 e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_PRESSED);
527 e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_EXCLUSIVE);
529 /* OVERRIDABLE_EXCLUSIVE grab */
530 e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
533 e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_SHARED);
536 e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_PRESSED);
540 e_keyrouter_keycancel_send(client, surface, key);
542 return TIZEN_KEYROUTER_ERROR_NONE;