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;
12 Eina_List *keylist_ptr = NULL, *l = NULL;
13 E_Keyrouter_Key_List_NodePtr kdata = NULL;
16 EINA_SAFETY_ON_FALSE_RETURN_VAL
17 (((mode == TIZEN_KEYROUTER_MODE_EXCLUSIVE) ||
18 (mode == TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE) ||
19 (mode == TIZEN_KEYROUTER_MODE_TOPMOST) ||
20 (mode == TIZEN_KEYROUTER_MODE_SHARED)),
21 TIZEN_KEYROUTER_ERROR_INVALID_MODE);
23 if ((mode == TIZEN_KEYROUTER_MODE_EXCLUSIVE) && (krt->HardKeys[key].excl_ptr != NULL))
25 keylist_ptr = krt->HardKeys[key].excl_ptr;
27 EINA_LIST_FOREACH(keylist_ptr, l, kdata)
29 pid = e_keyrouter_util_get_pid(kdata->wc, kdata->surface);
30 KLINF("The key(%d) is already grabbed exclusively by other [surface: %p, client: %p, pid:%d(%s)]",
31 key, kdata->surface, kdata->wc, pid, e_keyrouter_util_cmd_get_from_pid(pid));
33 return TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY;
36 if (mode == TIZEN_KEYROUTER_MODE_TOPMOST)
38 EINA_SAFETY_ON_NULL_RETURN_VAL
39 (surface, TIZEN_KEYROUTER_ERROR_INVALID_SURFACE);
42 res = e_keyrouter_prepend_to_keylist(surface,
43 surface ? NULL : client,
48 EINA_SAFETY_ON_FALSE_RETURN_VAL(res == TIZEN_KEYROUTER_ERROR_NONE, res);
53 /* Function for checking whether the key has been grabbed already by the same wl_surface or not */
55 _e_keyrouter_find_duplicated_client(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode)
57 Eina_List *keylist_ptr = NULL, *l = NULL;
58 E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
62 case TIZEN_KEYROUTER_MODE_EXCLUSIVE:
63 return TIZEN_KEYROUTER_ERROR_NONE;
65 case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE:
66 keylist_ptr = krt->HardKeys[key].or_excl_ptr;
69 case TIZEN_KEYROUTER_MODE_TOPMOST:
70 keylist_ptr = krt->HardKeys[key].top_ptr;
73 case TIZEN_KEYROUTER_MODE_SHARED:
74 keylist_ptr = krt->HardKeys[key].shared_ptr;
77 case TIZEN_KEYROUTER_MODE_PRESSED:
78 keylist_ptr = krt->HardKeys[key].press_ptr;
81 case TIZEN_KEYROUTER_MODE_PICTURE_OFF:
82 keylist_ptr = krt->HardKeys[key].pic_off_ptr;
85 KLWRN("Unknown key(%d) and grab mode(%d)", key, mode);
86 return TIZEN_KEYROUTER_ERROR_INVALID_MODE;
89 EINA_LIST_FOREACH(keylist_ptr, l, key_node_data)
91 if (!key_node_data) continue;
95 if (key_node_data->surface == surface)
97 KLDBG("The key(%d) is already grabbed same mode(%s) on the same wl_surface %p",
98 key, e_keyrouter_mode_to_string(mode), surface);
99 return TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY;
104 if (key_node_data->wc == wc)
106 KLDBG("The key(%d) is already grabbed same mode(%s) on the same wl_client %p",
107 key, e_keyrouter_mode_to_string(mode), wc);
108 return TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY;
113 return TIZEN_KEYROUTER_ERROR_NONE;
117 _e_keyrouter_find_key_in_list(struct wl_resource *surface, struct wl_client *wc, int key, int mode)
119 Eina_List **list = NULL;
120 Eina_List *l = NULL, *l_next = NULL;
121 E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
123 EINA_SAFETY_ON_TRUE_RETURN_VAL(((!surface) && (!wc)), EINA_FALSE);
125 list = _e_keyrouter_get_list(mode, key);
126 EINA_SAFETY_ON_NULL_RETURN_VAL(list, EINA_FALSE);
128 EINA_LIST_FOREACH_SAFE(*list, l, l_next, key_node_data)
130 if (!key_node_data) continue;
132 if ((surface) && (surface == key_node_data->surface)) return EINA_TRUE;
133 else if ((wc == key_node_data->wc)) return EINA_TRUE;
140 /* Function for prepending a new key grab information in the keyrouting list */
142 e_keyrouter_prepend_to_keylist(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode, Eina_Bool focused)
144 int res = TIZEN_KEYROUTER_ERROR_NONE;
146 res = _e_keyrouter_find_duplicated_client(surface, wc, key, mode);
149 E_Keyrouter_Key_List_NodePtr new_keyptr = E_NEW(E_Keyrouter_Key_List_Node, 1);
153 KLERR("Failled to allocate memory for new_keyptr");
154 return TIZEN_KEYROUTER_ERROR_NO_SYSTEM_RESOURCES;
157 new_keyptr->surface = surface;
159 new_keyptr->focused = focused;
160 new_keyptr->status = E_KRT_CSTAT_ALIVE;
164 case TIZEN_KEYROUTER_MODE_EXCLUSIVE:
165 krt->HardKeys[key].excl_ptr = eina_list_prepend(krt->HardKeys[key].excl_ptr, new_keyptr);
168 case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE:
169 krt->HardKeys[key].or_excl_ptr= eina_list_prepend(krt->HardKeys[key].or_excl_ptr, new_keyptr);
172 case TIZEN_KEYROUTER_MODE_TOPMOST:
173 krt->HardKeys[key].top_ptr = eina_list_prepend(krt->HardKeys[key].top_ptr, new_keyptr);
176 case TIZEN_KEYROUTER_MODE_SHARED:
177 krt->HardKeys[key].shared_ptr= eina_list_prepend(krt->HardKeys[key].shared_ptr, new_keyptr);
180 case TIZEN_KEYROUTER_MODE_PRESSED:
181 krt->HardKeys[key].press_ptr = eina_list_append(krt->HardKeys[key].press_ptr, new_keyptr);
184 case TIZEN_KEYROUTER_MODE_PICTURE_OFF:
185 krt->HardKeys[key].pic_off_ptr = eina_list_prepend(krt->HardKeys[key].pic_off_ptr, new_keyptr);
189 KLWRN("Unknown key(%d) and grab mode(%d)", key, mode);
191 return TIZEN_KEYROUTER_ERROR_INVALID_MODE;
194 if (TIZEN_KEYROUTER_MODE_PRESSED != mode)
198 e_keyrouter_wl_add_surface_destroy_listener(surface);
199 /* TODO: if failed add surface_destory_listener, remove keygrabs */
203 e_keyrouter_wl_add_client_destroy_listener(wc);
204 /* TODO: if failed add client_destory_listener, remove keygrabs */
208 return TIZEN_KEYROUTER_ERROR_NONE;
211 /* remove key grab info from the list */
213 e_keyrouter_find_and_remove_client_from_list(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode)
215 Eina_List **list = NULL;
216 Eina_List *l = NULL, *l_next = NULL;
217 E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
219 list = _e_keyrouter_get_list(mode, key);
220 EINA_SAFETY_ON_NULL_RETURN(list);
222 EINA_LIST_FOREACH_SAFE(*list, l, l_next, key_node_data)
224 if (!key_node_data) continue;
228 if (surface == key_node_data->surface)
230 if (mode == TIZEN_KEYROUTER_MODE_PRESSED)
232 key_node_data->status = E_KRT_CSTAT_UNGRAB;
236 *list = eina_list_remove_list(*list, l);
237 E_FREE(key_node_data);
239 KLDBG("Remove a %s Mode Grabbed key(%d) by surface(%p)", e_keyrouter_mode_to_string(mode), key, surface);
242 else if ((wc == key_node_data->wc))
244 if (mode == TIZEN_KEYROUTER_MODE_PRESSED)
246 key_node_data->status = E_KRT_CSTAT_UNGRAB;
250 *list = eina_list_remove_list(*list, l);
251 E_FREE(key_node_data);
253 KLDBG("Remove a %s Mode Grabbed key(%d) by wc(%p)", e_keyrouter_mode_to_string(mode), key, wc);
259 e_keyrouter_remove_client_from_list(struct wl_resource *surface, struct wl_client *wc)
262 Eina_List *l = NULL, *l_next = NULL;
263 E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
265 EINA_SAFETY_ON_TRUE_RETURN(((!surface) && (!wc)));
267 for (i = 0; i <= krt->max_tizen_hwkeys; i++)
269 if (0 == krt->HardKeys[i].keycode) continue;
271 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].excl_ptr, l, l_next, key_node_data)
273 if (!key_node_data) continue;
277 if (surface == key_node_data->surface)
279 krt->HardKeys[i].excl_ptr = eina_list_remove_list(krt->HardKeys[i].excl_ptr, l);
280 E_FREE(key_node_data);
281 KLDBG("Remove a Exclusive Mode Grabbed key(%d) by wl_surface(%p)", i, surface);
284 else if ((wc == key_node_data->wc))
286 krt->HardKeys[i].excl_ptr = eina_list_remove_list(krt->HardKeys[i].excl_ptr, l);
287 E_FREE(key_node_data);
288 KLDBG("Remove a Exclusive Mode Grabbed key(%d) by wl_client(%p)", i, wc);
291 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].or_excl_ptr, l, l_next, key_node_data)
293 if (!key_node_data) continue;
297 if (surface == key_node_data->surface)
299 krt->HardKeys[i].or_excl_ptr = eina_list_remove_list(krt->HardKeys[i].or_excl_ptr, l);
300 E_FREE(key_node_data);
301 KLDBG("Remove a Overridable_Exclusive Mode Grabbed key(%d) by wl_surface(%p)", i, surface);
304 else if ((wc == key_node_data->wc))
306 krt->HardKeys[i].or_excl_ptr = eina_list_remove_list(krt->HardKeys[i].or_excl_ptr, l);
307 E_FREE(key_node_data);
308 KLDBG("Remove a Overridable_Exclusive Mode Grabbed key(%d) by wl_client(%p)", i, wc);
311 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].top_ptr, l, l_next, key_node_data)
313 if (!key_node_data) continue;
317 if (surface == key_node_data->surface)
319 krt->HardKeys[i].top_ptr = eina_list_remove_list(krt->HardKeys[i].top_ptr, l);
320 E_FREE(key_node_data);
321 KLDBG("Remove a Topmost Mode Grabbed key(%d) by wl_surface(%p)", i, surface);
324 else if ((wc == key_node_data->wc))
326 krt->HardKeys[i].top_ptr = eina_list_remove_list(krt->HardKeys[i].top_ptr, l);
327 E_FREE(key_node_data);
328 KLDBG("Remove a Topmost Mode Grabbed key(%d) by wl_client(%p)", i, wc);
331 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].shared_ptr, l, l_next, key_node_data)
333 if (!key_node_data) continue;
337 if (surface == key_node_data->surface)
339 krt->HardKeys[i].shared_ptr = eina_list_remove_list(krt->HardKeys[i].shared_ptr, l);
340 E_FREE(key_node_data);
341 KLDBG("Remove a Shared Mode Grabbed key(%d) by wl_surface(%p)", i, surface);
344 else if ((wc == key_node_data->wc))
346 krt->HardKeys[i].shared_ptr = eina_list_remove_list(krt->HardKeys[i].shared_ptr, l);
347 E_FREE(key_node_data);
348 KLDBG("Remove a Shared Mode Grabbed key(%d) by wl_client(%p)", i, wc);
351 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].press_ptr, l, l_next, key_node_data)
353 if (!key_node_data) continue;
357 if (surface == key_node_data->surface)
359 key_node_data->status = E_KRT_CSTAT_DEAD;
360 KLDBG("Remove a Pressed key(%d) by wl_surface(%p)", i, surface);
361 key_node_data->wc = wl_resource_get_client(surface);
364 else if ((wc == key_node_data->wc))
366 key_node_data->status = E_KRT_CSTAT_DEAD;
367 KLDBG("Remove a Pressed key(%d) by wl_client(%p)", i, wc);
370 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].pic_off_ptr, l, l_next, key_node_data)
372 if (!key_node_data) continue;
375 if (surface == key_node_data->surface)
377 krt->HardKeys[i].pic_off_ptr = eina_list_remove_list(krt->HardKeys[i].pic_off_ptr, l);
378 E_FREE(key_node_data);
381 else if ( wc == key_node_data->wc)
383 krt->HardKeys[i].pic_off_ptr = eina_list_remove_list(krt->HardKeys[i].pic_off_ptr, l);
384 E_FREE(key_node_data);
391 e_keyrouter_find_key_in_list(struct wl_resource *surface, struct wl_client *wc, uint32_t key)
393 int mode = TIZEN_KEYROUTER_MODE_NONE;
394 Eina_Bool found = EINA_FALSE;
396 mode = TIZEN_KEYROUTER_MODE_EXCLUSIVE;
397 found = _e_keyrouter_find_key_in_list(surface, wc, key, mode);
398 if (found) goto finish;
400 mode = TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE;
401 found = _e_keyrouter_find_key_in_list(surface, wc, key, mode);
402 if (found) goto finish;
404 mode = TIZEN_KEYROUTER_MODE_TOPMOST;
405 found = _e_keyrouter_find_key_in_list(surface, wc, key, mode);
406 if (found) goto finish;
408 mode = TIZEN_KEYROUTER_MODE_SHARED;
409 found = _e_keyrouter_find_key_in_list(surface, wc, key, mode);
410 if (found) goto finish;
412 KLDBG("%d key is not grabbed by (wl_surface: %p, wl_client: %p)", key, surface, wc);
413 return TIZEN_KEYROUTER_MODE_NONE;
416 KLDBG("Find %d key grabbed by (wl_surface: %p, wl_client: %p) in %s mode",
417 key, surface, wc, e_keyrouter_mode_to_string(mode));
422 e_keyrouter_mode_to_string(uint32_t mode)
424 const char *str = NULL;
428 case TIZEN_KEYROUTER_MODE_EXCLUSIVE: str = "Exclusive"; break;
429 case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE: str = "Overridable_Exclusive"; break;
430 case TIZEN_KEYROUTER_MODE_TOPMOST: str = "Topmost"; break;
431 case TIZEN_KEYROUTER_MODE_SHARED: str = "Shared"; break;
432 case TIZEN_KEYROUTER_MODE_PRESSED: str = "Pressed"; break;
433 default: str = "UnknownMode"; break;
440 _e_keyrouter_get_list(int mode, int key)
442 Eina_List **list = NULL;
446 case TIZEN_KEYROUTER_MODE_EXCLUSIVE: list = &krt->HardKeys[key].excl_ptr; break;
447 case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE: list = &krt->HardKeys[key].or_excl_ptr; break;
448 case TIZEN_KEYROUTER_MODE_TOPMOST: list = &krt->HardKeys[key].top_ptr; break;
449 case TIZEN_KEYROUTER_MODE_SHARED: list = &krt->HardKeys[key].shared_ptr; break;
450 case TIZEN_KEYROUTER_MODE_PRESSED: list = &krt->HardKeys[key].press_ptr; break;
459 e_keyrouter_keygrab_set(struct wl_client *client, struct wl_resource *surface, int key, int mode)
464 if (EINA_FALSE == e_keyrouter_wl_util_do_privilege_check(client, mode, key))
466 KLINF("No permission for %d grab mode ! (key=%d)", mode, key);
467 return TIZEN_KEYROUTER_ERROR_NO_PERMISSION;
473 /* Regarding topmost mode, a client must request to grab a key with a valid surface. */
474 if (mode == TIZEN_KEYROUTER_MODE_TOPMOST)
476 KLWRN("Invalid surface for %d grab mode ! (key=%d)", mode, key);
478 return TIZEN_KEYROUTER_ERROR_INVALID_SURFACE;
482 /* Check the given key range */
483 if (krt->max_tizen_hwkeys < key)
485 KLWRN("Invalid range of key ! (keycode:%d)", key);
486 return TIZEN_KEYROUTER_ERROR_INVALID_KEY;
489 /* Check whether the key can be grabbed or not !
490 * Only key listed in Tizen key layout file can be grabbed. */
491 if (0 == krt->HardKeys[key].keycode)
493 KLWRN("Invalid key ! Disabled to grab ! (keycode:%d)", key);
494 return TIZEN_KEYROUTER_ERROR_INVALID_KEY;
497 /* Check whether the request key can be grabbed or not */
498 res = e_keyrouter_set_keygrab_in_list(surface, client, key, mode);
504 e_keyrouter_keygrab_unset(struct wl_client *client, struct wl_resource *surface, int key)
506 /* Ungrab top position grabs first. This grab mode do not need privilege */
508 e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_TOPMOST);
510 e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_TOPMOST);
513 if (EINA_FALSE == e_keyrouter_wl_util_do_privilege_check(client, TIZEN_KEYROUTER_MODE_NONE, key))
522 e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_EXCLUSIVE);
524 /* OVERRIDABLE_EXCLUSIVE grab */
525 e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
528 e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_SHARED);
531 e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_PRESSED);
536 e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_EXCLUSIVE);
538 /* OVERRIDABLE_EXCLUSIVE grab */
539 e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
542 e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_SHARED);
545 e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_PRESSED);
549 e_keyrouter_keycancel_send(client, surface, key);
551 return TIZEN_KEYROUTER_ERROR_NONE;