1 #include "e_keyrouter_intern.h"
2 #include "e_input_thread_client_intern.h"
3 #include "e_input_backend_intern.h"
4 #include "e_keyrouter_wl_intern.h"
6 #include <tizen-extension-server-protocol.h>
8 static int _e_keyrouter_find_duplicated_client(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode);
9 static Eina_Bool _e_keyrouter_find_key_in_list(struct wl_resource *surface, struct wl_client *wc, int key, int mode);
10 static Eina_List **_e_keyrouter_get_list(int mode, int key);
12 /* add a new key grab info to the list */
14 e_keyrouter_set_keygrab_in_list(struct wl_resource *surface, struct wl_client *client, uint32_t key, uint32_t mode)
16 int res = TIZEN_KEYROUTER_ERROR_NONE;
18 if (mode == TIZEN_KEYROUTER_MODE_EXCLUSIVE)
20 g_rec_mutex_lock(&krt->grab_key_mutex);
21 if (krt->HardKeys[key].excl_ptr != NULL)
23 g_rec_mutex_unlock(&krt->grab_key_mutex);
24 return TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY;
26 g_rec_mutex_unlock(&krt->grab_key_mutex);
29 res = e_keyrouter_prepend_to_keylist(surface,
30 surface ? NULL : client,
35 EINA_SAFETY_ON_FALSE_RETURN_VAL(res == TIZEN_KEYROUTER_ERROR_NONE, res);
40 /* Function for checking whether the key has been grabbed already by the same wl_surface or not */
42 _e_keyrouter_find_duplicated_client(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode)
44 Eina_List *keylist_ptr = NULL, *l = NULL;
45 E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
47 g_rec_mutex_lock(&krt->grab_key_mutex);
50 case TIZEN_KEYROUTER_MODE_EXCLUSIVE:
51 g_rec_mutex_unlock(&krt->grab_key_mutex);
52 return TIZEN_KEYROUTER_ERROR_NONE;
54 case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE:
55 keylist_ptr = krt->HardKeys[key].or_excl_ptr;
58 case TIZEN_KEYROUTER_MODE_TOPMOST:
59 keylist_ptr = krt->HardKeys[key].top_ptr;
62 case TIZEN_KEYROUTER_MODE_SHARED:
63 keylist_ptr = krt->HardKeys[key].shared_ptr;
66 case TIZEN_KEYROUTER_MODE_PRESSED:
67 keylist_ptr = krt->HardKeys[key].press_ptr;
70 case TIZEN_KEYROUTER_MODE_PICTURE_OFF:
71 keylist_ptr = krt->HardKeys[key].pic_off_ptr;
74 KLWRN("Unknown key(%d) and grab mode(%d)", key, mode);
75 g_rec_mutex_unlock(&krt->grab_key_mutex);
76 return TIZEN_KEYROUTER_ERROR_INVALID_MODE;
79 EINA_LIST_FOREACH(keylist_ptr, l, key_node_data)
81 if (!key_node_data) continue;
85 if (key_node_data->surface == surface)
87 KLDBG("The key(%d) is already grabbed same mode(%s) on the same wl_surface %p",
88 key, e_keyrouter_mode_to_string(mode), surface);
89 g_rec_mutex_unlock(&krt->grab_key_mutex);
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 g_rec_mutex_unlock(&krt->grab_key_mutex);
100 return TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY;
104 g_rec_mutex_unlock(&krt->grab_key_mutex);
106 return TIZEN_KEYROUTER_ERROR_NONE;
110 _e_keyrouter_find_key_in_list(struct wl_resource *surface, struct wl_client *wc, int key, int mode)
112 Eina_List **list = NULL;
113 Eina_List *l = NULL, *l_next = NULL;
114 E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
115 Eina_Bool ret = EINA_FALSE;
117 EINA_SAFETY_ON_TRUE_RETURN_VAL(((!surface) && (!wc)), EINA_FALSE);
119 g_rec_mutex_lock(&krt->grab_key_mutex);
120 list = _e_keyrouter_get_list(mode, key);
127 EINA_LIST_FOREACH_SAFE(*list, l, l_next, key_node_data)
129 if (!key_node_data) continue;
131 if ((surface) && (surface == key_node_data->surface))
136 else if ((wc == key_node_data->wc))
144 g_rec_mutex_unlock(&krt->grab_key_mutex);
150 /* Function for prepending a new key grab information in the keyrouting list */
152 e_keyrouter_prepend_to_keylist(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode, Eina_Bool focused)
154 int res = TIZEN_KEYROUTER_ERROR_NONE;
156 res = _e_keyrouter_find_duplicated_client(surface, wc, key, mode);
159 E_Keyrouter_Key_List_NodePtr new_keyptr = E_NEW(E_Keyrouter_Key_List_Node, 1);
163 KLERR("Failled to allocate memory for new_keyptr");
164 return TIZEN_KEYROUTER_ERROR_NO_SYSTEM_RESOURCES;
167 new_keyptr->surface = surface;
169 new_keyptr->focused = focused;
170 new_keyptr->status = E_KRT_CSTAT_ALIVE;
172 g_rec_mutex_lock(&krt->grab_key_mutex);
176 case TIZEN_KEYROUTER_MODE_EXCLUSIVE:
177 krt->HardKeys[key].excl_ptr = eina_list_prepend(krt->HardKeys[key].excl_ptr, new_keyptr);
180 case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE:
181 krt->HardKeys[key].or_excl_ptr= eina_list_prepend(krt->HardKeys[key].or_excl_ptr, new_keyptr);
184 case TIZEN_KEYROUTER_MODE_TOPMOST:
185 krt->HardKeys[key].top_ptr = eina_list_prepend(krt->HardKeys[key].top_ptr, new_keyptr);
188 case TIZEN_KEYROUTER_MODE_SHARED:
189 krt->HardKeys[key].shared_ptr= eina_list_prepend(krt->HardKeys[key].shared_ptr, new_keyptr);
192 case TIZEN_KEYROUTER_MODE_PRESSED:
193 krt->HardKeys[key].press_ptr = eina_list_append(krt->HardKeys[key].press_ptr, new_keyptr);
196 case TIZEN_KEYROUTER_MODE_PICTURE_OFF:
197 krt->HardKeys[key].pic_off_ptr = eina_list_prepend(krt->HardKeys[key].pic_off_ptr, new_keyptr);
201 KLWRN("Unknown key(%d) and grab mode(%d)", key, mode);
203 g_rec_mutex_unlock(&krt->grab_key_mutex);
204 return TIZEN_KEYROUTER_ERROR_INVALID_MODE;
206 g_rec_mutex_unlock(&krt->grab_key_mutex);
208 if (TIZEN_KEYROUTER_MODE_PRESSED != mode)
212 e_keyrouter_wl_add_surface_destroy_listener(surface);
213 /* TODO: if failed add surface_destroy_listener, remove keygrabs */
217 e_keyrouter_wl_add_client_destroy_listener(wc);
218 /* TODO: if failed add client_destroy_listener, remove keygrabs */
222 return TIZEN_KEYROUTER_ERROR_NONE;
225 /* remove key grab info from the list */
227 e_keyrouter_find_and_remove_client_from_list(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode)
229 Eina_List **list = NULL;
230 Eina_List *l = NULL, *l_next = NULL;
231 E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
233 g_rec_mutex_lock(&krt->grab_key_mutex);
234 list = _e_keyrouter_get_list(mode, key);
237 g_rec_mutex_unlock(&krt->grab_key_mutex);
241 EINA_LIST_FOREACH_SAFE(*list, l, l_next, key_node_data)
243 if (!key_node_data) continue;
247 if (surface == key_node_data->surface)
249 if (mode == TIZEN_KEYROUTER_MODE_PRESSED)
251 key_node_data->status = E_KRT_CSTAT_UNGRAB;
255 *list = eina_list_remove_list(*list, l);
256 E_FREE(key_node_data);
258 KLDBG("Remove a %s Mode Grabbed key(%d) by surface(%p)", e_keyrouter_mode_to_string(mode), key, surface);
261 else if ((wc == key_node_data->wc))
263 if (mode == TIZEN_KEYROUTER_MODE_PRESSED)
265 key_node_data->status = E_KRT_CSTAT_UNGRAB;
269 *list = eina_list_remove_list(*list, l);
270 E_FREE(key_node_data);
272 KLDBG("Remove a %s Mode Grabbed key(%d) by wc(%p)", e_keyrouter_mode_to_string(mode), key, wc);
276 g_rec_mutex_unlock(&krt->grab_key_mutex);
280 _e_keyrouter_remove_client_from_list(void *data)
283 Eina_List *l = NULL, *l_next = NULL;
284 E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
285 struct wl_resource *surface;
286 struct wl_client *wc;
287 E_Input_Thread_Request_Keygrab_Data *keygrab_data = data;
288 EINA_SAFETY_ON_NULL_RETURN(keygrab_data);
290 surface = keygrab_data->surface;
291 wc = keygrab_data->client;
293 INF("[%s] surface(%p), client(%p)\n", __func__, surface, wc);
295 EINA_SAFETY_ON_TRUE_RETURN(((!surface) && (!wc)));
297 g_rec_mutex_lock(&krt->grab_key_mutex);
299 for (i = 0; i <= krt->max_tizen_hwkeys; i++)
301 if (0 == krt->HardKeys[i].keycode) continue;
303 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].excl_ptr, l, l_next, key_node_data)
305 if (!key_node_data) continue;
309 if (surface == key_node_data->surface)
311 krt->HardKeys[i].excl_ptr = eina_list_remove_list(krt->HardKeys[i].excl_ptr, l);
312 E_FREE(key_node_data);
313 KLDBG("Remove a Exclusive Mode Grabbed key(%d) by wl_surface(%p)", i, surface);
316 else if ((wc == key_node_data->wc))
318 krt->HardKeys[i].excl_ptr = eina_list_remove_list(krt->HardKeys[i].excl_ptr, l);
319 E_FREE(key_node_data);
320 KLDBG("Remove a Exclusive Mode Grabbed key(%d) by wl_client(%p)", i, wc);
323 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].or_excl_ptr, l, l_next, key_node_data)
325 if (!key_node_data) continue;
329 if (surface == key_node_data->surface)
331 krt->HardKeys[i].or_excl_ptr = eina_list_remove_list(krt->HardKeys[i].or_excl_ptr, l);
332 E_FREE(key_node_data);
333 KLDBG("Remove a Overridable_Exclusive Mode Grabbed key(%d) by wl_surface(%p)", i, surface);
336 else if ((wc == key_node_data->wc))
338 krt->HardKeys[i].or_excl_ptr = eina_list_remove_list(krt->HardKeys[i].or_excl_ptr, l);
339 E_FREE(key_node_data);
340 KLDBG("Remove a Overridable_Exclusive Mode Grabbed key(%d) by wl_client(%p)", i, wc);
343 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].top_ptr, l, l_next, key_node_data)
345 if (!key_node_data) continue;
349 if (surface == key_node_data->surface)
351 krt->HardKeys[i].top_ptr = eina_list_remove_list(krt->HardKeys[i].top_ptr, l);
352 E_FREE(key_node_data);
353 KLDBG("Remove a Topmost Mode Grabbed key(%d) by wl_surface(%p)", i, surface);
356 else if ((wc == key_node_data->wc))
358 krt->HardKeys[i].top_ptr = eina_list_remove_list(krt->HardKeys[i].top_ptr, l);
359 E_FREE(key_node_data);
360 KLDBG("Remove a Topmost Mode Grabbed key(%d) by wl_client(%p)", i, wc);
363 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].shared_ptr, l, l_next, key_node_data)
365 if (!key_node_data) continue;
369 if (surface == key_node_data->surface)
371 krt->HardKeys[i].shared_ptr = eina_list_remove_list(krt->HardKeys[i].shared_ptr, l);
372 E_FREE(key_node_data);
373 KLDBG("Remove a Shared Mode Grabbed key(%d) by wl_surface(%p)", i, surface);
376 else if ((wc == key_node_data->wc))
378 krt->HardKeys[i].shared_ptr = eina_list_remove_list(krt->HardKeys[i].shared_ptr, l);
379 E_FREE(key_node_data);
380 KLDBG("Remove a Shared Mode Grabbed key(%d) by wl_client(%p)", i, wc);
383 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].press_ptr, l, l_next, key_node_data)
385 if (!key_node_data) continue;
389 if (surface == key_node_data->surface)
391 key_node_data->status = E_KRT_CSTAT_DEAD;
392 KLDBG("Remove a Pressed key(%d) by wl_surface(%p)", i, surface);
393 key_node_data->wc = wl_resource_get_client(surface);
396 else if ((wc == key_node_data->wc))
398 key_node_data->status = E_KRT_CSTAT_DEAD;
399 KLDBG("Remove a Pressed key(%d) by wl_client(%p)", i, wc);
402 EINA_LIST_FOREACH_SAFE(krt->HardKeys[i].pic_off_ptr, l, l_next, key_node_data)
404 if (!key_node_data) continue;
407 if (surface == key_node_data->surface)
409 krt->HardKeys[i].pic_off_ptr = eina_list_remove_list(krt->HardKeys[i].pic_off_ptr, l);
410 E_FREE(key_node_data);
413 else if ( wc == key_node_data->wc)
415 krt->HardKeys[i].pic_off_ptr = eina_list_remove_list(krt->HardKeys[i].pic_off_ptr, l);
416 E_FREE(key_node_data);
420 g_rec_mutex_unlock(&krt->grab_key_mutex);
424 e_keyrouter_remove_client_from_list(struct wl_resource *surface, struct wl_client *wc)
426 E_Input_Thread_Request_Keygrab_Data keygrab_data;
427 memset(&keygrab_data, 0, sizeof(E_Input_Thread_Request_Keygrab_Data));
429 keygrab_data.surface = surface;
430 keygrab_data.client = wc;
432 INF("[%s] surface(%p), client(%p)\n", __func__, surface, wc);
433 _e_keyrouter_remove_client_from_list(&keygrab_data);
437 e_keyrouter_find_key_in_list(struct wl_resource *surface, struct wl_client *wc, uint32_t key)
439 int mode = TIZEN_KEYROUTER_MODE_NONE;
440 Eina_Bool found = EINA_FALSE;
442 mode = TIZEN_KEYROUTER_MODE_EXCLUSIVE;
443 found = _e_keyrouter_find_key_in_list(surface, wc, key, mode);
444 if (found) goto finish;
446 mode = TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE;
447 found = _e_keyrouter_find_key_in_list(surface, wc, key, mode);
448 if (found) goto finish;
450 mode = TIZEN_KEYROUTER_MODE_TOPMOST;
451 found = _e_keyrouter_find_key_in_list(surface, wc, key, mode);
452 if (found) goto finish;
454 mode = TIZEN_KEYROUTER_MODE_SHARED;
455 found = _e_keyrouter_find_key_in_list(surface, wc, key, mode);
456 if (found) goto finish;
458 KLDBG("%d key is not grabbed by (wl_surface: %p, wl_client: %p)", key, surface, wc);
459 return TIZEN_KEYROUTER_MODE_NONE;
462 KLDBG("Find %d key grabbed by (wl_surface: %p, wl_client: %p) in %s mode",
463 key, surface, wc, e_keyrouter_mode_to_string(mode));
468 e_keyrouter_mode_to_string(uint32_t mode)
470 const char *str = NULL;
474 case TIZEN_KEYROUTER_MODE_EXCLUSIVE: str = "Exclusive"; break;
475 case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE: str = "Overridable_Exclusive"; break;
476 case TIZEN_KEYROUTER_MODE_TOPMOST: str = "Topmost"; break;
477 case TIZEN_KEYROUTER_MODE_SHARED: str = "Shared"; break;
478 case TIZEN_KEYROUTER_MODE_PRESSED: str = "Pressed"; break;
479 default: str = "UnknownMode"; break;
486 _e_keyrouter_get_list(int mode, int key)
488 Eina_List **list = NULL;
492 case TIZEN_KEYROUTER_MODE_EXCLUSIVE: list = &krt->HardKeys[key].excl_ptr; break;
493 case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE: list = &krt->HardKeys[key].or_excl_ptr; break;
494 case TIZEN_KEYROUTER_MODE_TOPMOST: list = &krt->HardKeys[key].top_ptr; break;
495 case TIZEN_KEYROUTER_MODE_SHARED: list = &krt->HardKeys[key].shared_ptr; break;
496 case TIZEN_KEYROUTER_MODE_PRESSED: list = &krt->HardKeys[key].press_ptr; break;
505 e_keyrouter_keygrab_set(struct wl_client *client, struct wl_resource *surface, int key, int mode)
509 /* Check whether the request key can be grabbed or not */
510 res = e_keyrouter_set_keygrab_in_list(surface, client, key, mode);
516 e_keyrouter_keygrab_unset(struct wl_client *client, struct wl_resource *surface, int key)
518 /* Ungrab top position grabs first. This grab mode do not need privilege */
520 e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_TOPMOST);
522 e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_TOPMOST);
525 if (EINA_FALSE == e_keyrouter_wl_util_do_privilege_check(client, TIZEN_KEYROUTER_MODE_NONE, key))
534 e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_EXCLUSIVE);
536 /* OVERRIDABLE_EXCLUSIVE grab */
537 e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
540 e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_SHARED);
543 e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_PRESSED);
548 e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_EXCLUSIVE);
550 /* OVERRIDABLE_EXCLUSIVE grab */
551 e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
554 e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_SHARED);
557 e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_PRESSED);
561 e_keyrouter_keycancel_send(client, surface, key);