1 #include "e_keyrouter_wl_intern.h"
2 #include "e_input_intern.h"
3 #include "e_input_backend_intern.h"
4 #include "e_comp_wl_input_intern.h"
5 #include "e_comp_wl_intern.h"
6 #include "e_client_intern.h"
7 #include "e_config_intern.h"
8 #include "e_comp_input_intern.h"
9 #include "e_input_thread_client_intern.h"
10 #include "e_security.h"
11 #include "e_keyrouter_intern.h"
13 #include <tizen-extension-server-protocol.h>
15 static E_Tizen_Keyrouter *g_tizen_keyrouter = NULL;
17 struct _E_Tizen_Keyrouter
19 struct wl_global *global;
23 Eina_List *grab_surface_list;
24 Eina_List *grab_client_list;
28 e_keyrouter_wl_event_surface_send(struct wl_resource *surface, int key, int mode)
31 struct wl_resource *res_data;
34 EINA_SAFETY_ON_NULL_RETURN(surface);
36 wc = wl_resource_get_client(surface);
37 EINA_SAFETY_ON_NULL_RETURN(wc);
39 EINA_LIST_FOREACH(g_tizen_keyrouter->resources, l, res_data)
41 if (wl_resource_get_client(res_data) != wc) continue;
42 if (wl_resource_get_version(res_data) < 2) continue;
44 if (e_config->key_input_ttrace_enable)
46 TRACE_INPUT_BEGIN(tizen_keyrouter_send_event_surface);
47 ELOGF("INPUT", "tizen_keyrouter_send_event_surface|B|", NULL);
50 tizen_keyrouter_send_event_surface(res_data, surface, key, mode);
52 if (e_config->key_input_ttrace_enable)
55 ELOGF("INPUT", "tizen_keyrouter_send_event_surface|E|", NULL);
61 _e_keyrouter_wl_key_send(Ecore_Event_Key *ev, E_Device *dev, enum wl_keyboard_key_state state, Eina_List *key_list, Eina_Bool focused, struct wl_client *client, struct wl_resource *surface)
63 struct wl_resource *res;
65 uint32_t serial, keycode;
67 E_Comp_Config *comp_conf = NULL;
69 keycode = (ev->keycode - 8);
71 serial = wl_display_next_serial(e_comp_wl->wl.disp);
73 comp_conf = e_comp_config_get();
75 if (surface && !focused)
77 e_comp_wl_connection_lock();
78 e_keyrouter_wl_event_surface_send(surface, ev->keycode, TIZEN_KEYROUTER_MODE_NONE);
79 e_comp_wl_connection_unlock();
82 if (e_config->key_input_ttrace_enable)
84 TRACE_INPUT_BEGIN(wl_keyboard_send_key:%s:%s, (state ? "PRESS" : "RELEASE"), ev->keyname);
85 ELOGF("INPUT", "wl_keyboard_send_key:%s:%s|B|", NULL, (state ? "PRESS" : "RELEASE"), ev->keyname);
88 EINA_LIST_FOREACH(key_list, l, res)
90 wc = wl_resource_get_client(res);
91 if (!focused && wc != client) continue;
92 TRACE_INPUT_BEGIN(_e_comp_wl_key_send);
93 if (!e_input_thread_mode_get())
95 e_comp_wl_send_event_device(client, ev->timestamp, ev->dev, serial);
100 e_comp_wl_send_event_e_device(client, ev->timestamp, dev, serial);
103 if (comp_conf && comp_conf->input_log_enable)
104 INF("[Server] Routed Key %s (time: %d)\n", (state ? "Down" : "Up"), ev->timestamp);
106 wl_keyboard_send_key(res, serial, ev->timestamp,
111 if (e_config->key_input_ttrace_enable)
114 ELOGF("INPUT", "wl_keyboard_send_key|E|", NULL);
119 e_keyrouter_wl_key_send(Ecore_Event_Key *ev, E_Device *dev, Eina_Bool pressed, struct wl_client *client, struct wl_resource *surface, Eina_Bool focused)
122 struct wl_client *wc = NULL;
124 enum wl_keyboard_key_state state;
126 if (ev->window != e_comp->ee_win)
131 keycode = (ev->keycode - 8);
132 if (!(e_comp_wl = e_comp->wl_comp_data))
137 #ifndef E_RELEASE_BUILD
138 if ((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
139 ((ev->modifiers & ECORE_EVENT_MODIFIER_ALT) ||
140 (ev->modifiers & ECORE_EVENT_MODIFIER_ALTGR)) &&
141 eina_streq(ev->key, "BackSpace"))
147 if (pressed) state = WL_KEYBOARD_KEY_STATE_PRESSED;
148 else state = WL_KEYBOARD_KEY_STATE_RELEASED;
152 _e_keyrouter_wl_key_send(ev, dev, state, e_comp_input_key->kbd.resources, EINA_FALSE, client, surface);
156 if ((!e_client_action_get()) && (!e_comp->input_key_grabs))
158 ec = e_client_focused_get();
160 if (ec && ec->comp_data)
162 struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
165 if (e_comp_input_key->kbd.focused)
167 wc = wl_resource_get_client(surface);
168 _e_keyrouter_wl_key_send(ev, dev, state, e_comp_input_key->kbd.focused, EINA_TRUE, wc, surface);
172 /* update modifier state */
173 e_comp_wl_input_keyboard_state_update(keycode, pressed);
180 e_keyrouter_surface_keycancel_send(struct wl_resource *surface, unsigned int key)
183 Eina_List *press_ptr_list;
184 E_Keyrouter_Key_List_NodePtr data;
185 struct wl_resource *resource;
186 struct wl_client *client;
188 EINA_SAFETY_ON_NULL_RETURN(surface);
190 client = wl_resource_get_client(surface);
192 g_rec_mutex_lock(&krt->grab_key_mutex);
194 press_ptr_list = krt->HardKeys[key].press_ptr;
195 EINA_LIST_FOREACH(press_ptr_list, l, data)
197 if (surface != data->surface) continue;
199 EINA_LIST_FOREACH(g_tizen_keyrouter->resources, l, resource)
201 if (wl_resource_get_client(resource) != client) continue;
203 tizen_keyrouter_send_key_cancel(resource, key-8);
207 g_rec_mutex_unlock(&krt->grab_key_mutex);
211 e_keyrouter_client_keycancel_send(struct wl_client *client, unsigned int key)
214 E_Keyrouter_Key_List_NodePtr data;
215 Eina_List *press_ptr_list;
216 struct wl_resource *resource;
218 EINA_SAFETY_ON_NULL_RETURN(client);
220 g_rec_mutex_lock(&krt->grab_key_mutex);
222 press_ptr_list = krt->HardKeys[key].press_ptr;
223 EINA_LIST_FOREACH(press_ptr_list, l, data)
225 if (client != data->wc) continue;
227 EINA_LIST_FOREACH(g_tizen_keyrouter->resources, l, resource)
229 if (wl_resource_get_client(resource) != client) continue;
231 tizen_keyrouter_send_key_cancel(resource, key-8);
235 g_rec_mutex_unlock(&krt->grab_key_mutex);
239 _e_keyrouter_wl_array_length(const struct wl_array *array)
244 wl_array_for_each(data, array)
253 _e_keyrouter_keygrab_set_available_check(struct wl_client *client, struct wl_resource *surface, int key, int mode)
255 if (!((mode == TIZEN_KEYROUTER_MODE_EXCLUSIVE) ||
256 (mode == TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE) ||
257 (mode == TIZEN_KEYROUTER_MODE_TOPMOST) ||
258 (mode == TIZEN_KEYROUTER_MODE_SHARED)))
259 return TIZEN_KEYROUTER_ERROR_INVALID_MODE;
261 /* Regarding topmost mode, a client must request to grab a key with a valid surface. */
262 if (!surface && mode == TIZEN_KEYROUTER_MODE_TOPMOST)
264 KLWRN("Invalid surface for %d grab mode ! (key=%d)", mode, key);
265 return TIZEN_KEYROUTER_ERROR_INVALID_SURFACE;
268 return TIZEN_KEYROUTER_ERROR_NONE;
272 _e_keyrouter_keygrab_privilege_available_check(struct wl_client *client, int key, int mode)
275 if (!e_keyrouter_wl_util_do_privilege_check(client, mode, key))
277 KLINF("No permission for %d grab mode ! (key=%d)", mode, key);
278 return TIZEN_KEYROUTER_ERROR_NO_PERMISSION;
282 return TIZEN_KEYROUTER_ERROR_NONE;
286 _e_keyrouter_keygrab_key_available_check(int key)
288 /* Check the given key range */
289 if (krt->max_tizen_hwkeys < key)
291 KLWRN("Invalid range of key ! (keycode:%d) maximum value(%d)", key, krt->max_tizen_hwkeys);
292 return TIZEN_KEYROUTER_ERROR_INVALID_KEY;
295 /* Check whether the key can be grabbed or not !
296 * Only key listed in Tizen key layout file can be grabbed. */
297 if (0 == krt->HardKeys[key].keycode)
299 KLWRN("Invalid key ! Disabled to set keygrab ! (keycode:%d)", key);
300 return TIZEN_KEYROUTER_ERROR_INVALID_KEY;
303 return TIZEN_KEYROUTER_ERROR_NONE;
307 _e_keyrouter_input_thread_keygrab_set(void *data)
309 E_Input_Thread_Request_Keygrab_Data *keygrab_data = data;
310 int res = TIZEN_KEYROUTER_ERROR_NONE;
312 res = _e_keyrouter_keygrab_set_available_check(keygrab_data->client,
313 keygrab_data->surface, keygrab_data->key, keygrab_data->mode);
314 if (res != TIZEN_KEYROUTER_ERROR_NONE)
317 res = _e_keyrouter_keygrab_privilege_available_check(keygrab_data->client,
318 keygrab_data->key, keygrab_data->mode);
319 if (res != TIZEN_KEYROUTER_ERROR_NONE)
322 res = _e_keyrouter_keygrab_key_available_check(keygrab_data->key);
323 if (res != TIZEN_KEYROUTER_ERROR_NONE)
326 res = e_keyrouter_keygrab_set(keygrab_data->client, keygrab_data->surface,
327 keygrab_data->key, keygrab_data->mode);
328 if (res != TIZEN_KEYROUTER_ERROR_NONE)
331 KLINF("Success to %d key %s grab request (wl_client: %p, wl_surface: %p, pid: %d)",
332 keygrab_data->key, e_keyrouter_mode_to_string(keygrab_data->mode),
333 keygrab_data->client, keygrab_data->surface,
334 e_keyrouter_util_get_pid(keygrab_data->client, keygrab_data->surface));
336 tizen_keyrouter_send_keygrab_notify(keygrab_data->resource,
337 keygrab_data->surface, keygrab_data->key, keygrab_data->mode, res);
342 KLINF("Failed to %d key %s grab request (wl_client: %p, wl_surface: %p, pid: %d): res: %d",
343 keygrab_data->key, e_keyrouter_mode_to_string(keygrab_data->mode),
344 keygrab_data->client, keygrab_data->surface,
345 e_keyrouter_util_get_pid(keygrab_data->client, keygrab_data->surface),
348 tizen_keyrouter_send_keygrab_notify(keygrab_data->resource,
349 keygrab_data->surface, keygrab_data->key, keygrab_data->mode, res);
352 /* tizen_keyrouter_set_keygrab request handler */
354 _e_keyrouter_cb_keygrab_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, uint32_t key, uint32_t mode)
356 TRACE_INPUT_BEGIN(_e_keyrouter_cb_keygrab_set);
358 E_Input_Thread_Request_Keygrab_Data keygrab_data;
360 keygrab_data.resource = resource;
361 keygrab_data.surface = surface;
362 keygrab_data.client = client;
363 keygrab_data.key = key;
364 keygrab_data.mode = mode;
366 INF("client: %p, surface: %p, key: %d, mode: %d\n", keygrab_data.client, keygrab_data.surface, keygrab_data.key, keygrab_data.mode);
367 _e_keyrouter_input_thread_keygrab_set(&keygrab_data);
373 _e_keyrouter_input_thread_keygrab_unset(void *data)
375 E_Input_Thread_Request_Keygrab_Data *keygrab_data = data;
376 int res = TIZEN_KEYROUTER_ERROR_NONE;
378 res = _e_keyrouter_keygrab_key_available_check(keygrab_data->key);
379 if (res != TIZEN_KEYROUTER_ERROR_NONE)
382 res = _e_keyrouter_keygrab_privilege_available_check(keygrab_data->client,
383 keygrab_data->key, TIZEN_KEYROUTER_MODE_NONE);
384 if (res != TIZEN_KEYROUTER_ERROR_NONE)
387 if (keygrab_data->surface)
388 e_keyrouter_surface_keygrab_unset(keygrab_data->surface, keygrab_data->key);
390 e_keyrouter_client_keygrab_unset(keygrab_data->client, keygrab_data->key);
392 KLDBG("Success to %d key ungrab request (wl_client: %p, wl_surface: %p, pid: %d)",
393 keygrab_data->key, keygrab_data->client, keygrab_data->surface,
394 e_keyrouter_util_get_pid(keygrab_data->client, keygrab_data->surface));
396 tizen_keyrouter_send_keygrab_notify(keygrab_data->resource,
397 keygrab_data->surface, keygrab_data->key, TIZEN_KEYROUTER_MODE_NONE, res);
402 if (keygrab_data->surface)
403 e_keyrouter_surface_keycancel_send(keygrab_data->surface, keygrab_data->key);
405 e_keyrouter_client_keycancel_send(keygrab_data->client, keygrab_data->key);
408 KLINF("Failed to %d key ungrab request (wl_client: %p, wl_surface: %p, pid: %d): res: %d",
409 keygrab_data->key, keygrab_data->client, keygrab_data->surface,
410 e_keyrouter_util_get_pid(keygrab_data->client, keygrab_data->surface),
413 tizen_keyrouter_send_keygrab_notify(keygrab_data->resource,
414 keygrab_data->surface, keygrab_data->key, TIZEN_KEYROUTER_MODE_NONE, res);
417 /* tizen_keyrouter unset_keygrab request handler */
419 _e_keyrouter_cb_keygrab_unset(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, uint32_t key)
421 TRACE_INPUT_BEGIN(_e_keyrouter_cb_keygrab_unset);
423 E_Input_Thread_Request_Keygrab_Data keygrab_data;
425 keygrab_data.resource = resource;
426 keygrab_data.surface = surface;
427 keygrab_data.client = client;
428 keygrab_data.key = key;
429 keygrab_data.mode = TIZEN_KEYROUTER_MODE_NONE; /* UNUSED */
431 INF("client: %p, surface: %p, key: %d\n", keygrab_data.client,
432 keygrab_data.surface, keygrab_data.key);
434 _e_keyrouter_input_thread_keygrab_unset(&keygrab_data);
439 /* tizen_keyrouter get_keygrab_status request handler */
441 _e_keyrouter_cb_get_keygrab_status(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, uint32_t key)
447 int mode = TIZEN_KEYROUTER_MODE_NONE;
449 TRACE_INPUT_BEGIN(_e_keyrouter_cb_get_keygrab_status);
450 mode = e_keyrouter_find_key_in_list(surface, client, key);
453 tizen_keyrouter_send_keygrab_notify(resource, surface, key, mode, TIZEN_KEYROUTER_ERROR_NONE);
457 _e_keyrouter_cb_keygrab_set_list(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, struct wl_array *grab_list)
459 E_Keyrouter_Grab_Request *grab_request = NULL;
460 int res = TIZEN_KEYROUTER_ERROR_NONE;
463 TRACE_INPUT_BEGIN(_e_keyrouter_cb_keygrab_set_list);
465 array_len = _e_keyrouter_wl_array_length(grab_list);
467 if (0 != (array_len % 3))
469 /* FIX ME: Which way is effectively to notify invalid pair to client */
470 KLWRN("Invalid keycode and grab mode pair. Check arguments in a list");
472 tizen_keyrouter_send_keygrab_notify_list(resource, surface, NULL);
476 wl_array_for_each(grab_request, grab_list)
478 res = _e_keyrouter_keygrab_set_available_check(client, surface,
479 grab_request->key, grab_request->mode);
480 if (res != TIZEN_KEYROUTER_ERROR_NONE)
483 res = _e_keyrouter_keygrab_privilege_available_check(client,
484 grab_request->key, grab_request->mode);
485 if (res != TIZEN_KEYROUTER_ERROR_NONE)
488 res = _e_keyrouter_keygrab_key_available_check(grab_request->key);
489 if (res != TIZEN_KEYROUTER_ERROR_NONE)
492 res = e_keyrouter_keygrab_set(client, surface,
493 grab_request->key, grab_request->mode);
496 grab_request->err = res;
498 if (res == TIZEN_KEYROUTER_ERROR_NONE)
499 KLDBG("Success to %d key %s grab using list(wl_client: %p, wl_surface: %p, pid: %d)",
500 grab_request->key, e_keyrouter_mode_to_string(grab_request->mode),
501 client, surface, e_keyrouter_util_get_pid(client, surface));
503 KLINF("Failed to %d key %s grab using list(wl_client: %p, wl_surface: %p, pid: %d): res: %d",
504 grab_request->key, e_keyrouter_mode_to_string(grab_request->mode),
505 client, surface, e_keyrouter_util_get_pid(client, surface),
511 tizen_keyrouter_send_keygrab_notify_list(resource, surface, grab_list);
515 _e_keyrouter_cb_keygrab_unset_list(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, struct wl_array *ungrab_list)
517 E_Keyrouter_Ungrab_Request *ungrab_request = NULL;
518 int res = TIZEN_KEYROUTER_ERROR_NONE;
521 TRACE_INPUT_BEGIN(_e_keyrouter_cb_keygrab_unset_list);
523 array_len = _e_keyrouter_wl_array_length(ungrab_list);
525 if (0 != (array_len % 2))
527 /* FIX ME: Which way is effectively to notify invalid pair to client */
528 KLWRN("Invalid keycode and error pair. Check arguments in a list");
530 tizen_keyrouter_send_keygrab_notify_list(resource, surface, ungrab_list);
534 wl_array_for_each(ungrab_request, ungrab_list)
536 res = _e_keyrouter_keygrab_key_available_check(ungrab_request->key);
537 if (res != TIZEN_KEYROUTER_ERROR_NONE)
540 res = _e_keyrouter_keygrab_privilege_available_check(client,
541 ungrab_request->key, TIZEN_KEYROUTER_MODE_NONE);
542 if (res != TIZEN_KEYROUTER_ERROR_NONE)
546 e_keyrouter_client_keygrab_unset(client, ungrab_request->key);
548 e_keyrouter_surface_keygrab_unset(surface, ungrab_request->key);
552 e_keyrouter_surface_keycancel_send(surface, ungrab_request->key);
554 e_keyrouter_client_keycancel_send(client, ungrab_request->key);
557 ungrab_request->err = res;
559 if (res == TIZEN_KEYROUTER_ERROR_NONE)
560 KLDBG("Success to ungrab using list: %d key (wl_client: %p, wl_surface: %p, pid: %d)",
561 ungrab_request->key, client, surface,
562 e_keyrouter_util_get_pid(client, surface));
564 KLINF("Failed to ungrab using list: %d key (wl_client: %p, wl_surface: %p, pid: %d): res: %d",
565 ungrab_request->key, client, surface,
566 e_keyrouter_util_get_pid(client, surface), ungrab_request->err);
571 tizen_keyrouter_send_keygrab_notify_list(resource, surface, ungrab_list);
575 _e_keyrouter_cb_keygrab_get_list(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface)
579 tizen_keyrouter_send_getgrab_notify_list(resource, surface, NULL);
583 _e_keyrouter_cb_set_register_none_key(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, uint32_t data)
588 tizen_keyrouter_send_set_register_none_key_notify(resource, NULL, 0);
592 _e_keyrouter_cb_get_keyregister_status(struct wl_client *client, struct wl_resource *resource, uint32_t key)
597 tizen_keyrouter_send_keyregister_notify(resource, (int)EINA_FALSE);
601 _e_keyrouter_cb_set_input_config(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *surface EINA_UNUSED, uint32_t config_mode EINA_UNUSED, uint32_t value EINA_UNUSED)
603 tizen_keyrouter_send_set_input_config_notify(resource, 0);
607 _e_keyrouter_cb_destroy(struct wl_client *client, struct wl_resource *resource)
609 wl_resource_destroy(resource);
612 static const struct tizen_keyrouter_interface _e_keyrouter_implementation = {
613 _e_keyrouter_cb_keygrab_set,
614 _e_keyrouter_cb_keygrab_unset,
615 _e_keyrouter_cb_get_keygrab_status,
616 _e_keyrouter_cb_keygrab_set_list,
617 _e_keyrouter_cb_keygrab_unset_list,
618 _e_keyrouter_cb_keygrab_get_list,
619 _e_keyrouter_cb_set_register_none_key,
620 _e_keyrouter_cb_get_keyregister_status,
621 _e_keyrouter_cb_set_input_config,
622 _e_keyrouter_cb_destroy,
626 _e_keyrouter_cb_unbind(struct wl_resource *resource)
628 g_tizen_keyrouter->resources = eina_list_remove(g_tizen_keyrouter->resources, resource);
631 /* tizen_keyrouter global object bind function */
633 _e_keyrouter_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
635 struct wl_resource *resource;
637 resource = wl_resource_create(client, &tizen_keyrouter_interface, version, id);
639 KLDBG("wl_resource_create(...,&tizen_keyrouter_interface,...)");
643 KLERR("Failed to create resource ! (version :%d, id:%d)", version, id);
644 wl_client_post_no_memory(client);
648 g_tizen_keyrouter->resources = eina_list_append(g_tizen_keyrouter->resources, resource);
650 wl_resource_set_implementation(resource, &_e_keyrouter_implementation, NULL, _e_keyrouter_cb_unbind);
654 _e_keyrouter_wl_client_cb_destroy(struct wl_listener *l, void *data)
656 struct wl_client *client = data;
658 KLDBG("Listener(%p) called: wl_client: %p is died", l, client);
659 e_keyrouter_remove_client_from_list(NULL, client);
661 wl_list_remove(&l->link);
664 g_tizen_keyrouter->grab_client_list = eina_list_remove(g_tizen_keyrouter->grab_client_list, client);
668 _e_keyrouter_wl_surface_cb_destroy(struct wl_listener *l, void *data)
670 struct wl_resource *surface = (struct wl_resource *)data;
672 KLDBG("Listener(%p) called: surface: %p is died", l, surface);
673 e_keyrouter_remove_client_from_list(surface, NULL);
675 wl_list_remove(&l->link);
678 g_tizen_keyrouter->grab_surface_list = eina_list_remove(g_tizen_keyrouter->grab_surface_list, surface);
682 e_keyrouter_wl_add_client_destroy_listener(struct wl_client *client)
684 struct wl_listener *destroy_listener = NULL;
686 struct wl_client *wc_data;
688 if (!client) return TIZEN_KEYROUTER_ERROR_NONE;
690 EINA_LIST_FOREACH(g_tizen_keyrouter->grab_client_list, l, wc_data)
694 if (wc_data == client)
696 return TIZEN_KEYROUTER_ERROR_NONE;
701 destroy_listener = E_NEW(struct wl_listener, 1);
703 if (!destroy_listener)
705 KLERR("Failed to allocate memory for wl_client destroy listener !");
706 return TIZEN_KEYROUTER_ERROR_NO_SYSTEM_RESOURCES;
709 destroy_listener->notify = _e_keyrouter_wl_client_cb_destroy;
710 wl_client_add_destroy_listener(client, destroy_listener);
711 g_tizen_keyrouter->grab_client_list = eina_list_append(g_tizen_keyrouter->grab_client_list, client);
713 return TIZEN_KEYROUTER_ERROR_NONE;
716 /* Function for registering wl_surface destroy listener */
718 e_keyrouter_wl_add_surface_destroy_listener(struct wl_resource *surface)
720 struct wl_listener *destroy_listener = NULL;
722 struct wl_resource *surface_data;
724 if (!surface) return TIZEN_KEYROUTER_ERROR_NONE;
726 EINA_LIST_FOREACH(g_tizen_keyrouter->grab_surface_list, l, surface_data)
730 if (surface_data == surface)
732 return TIZEN_KEYROUTER_ERROR_NONE;
737 destroy_listener = E_NEW(struct wl_listener, 1);
739 if (!destroy_listener)
741 KLERR("Failed to allocate memory for wl_surface destroy listener !");
742 return TIZEN_KEYROUTER_ERROR_NO_SYSTEM_RESOURCES;
745 destroy_listener->notify = _e_keyrouter_wl_surface_cb_destroy;
746 wl_resource_add_destroy_listener(surface, destroy_listener);
747 g_tizen_keyrouter->grab_surface_list = eina_list_append(g_tizen_keyrouter->grab_surface_list, surface);
749 return TIZEN_KEYROUTER_ERROR_NONE;
754 e_keyrouter_wl_util_do_privilege_check(struct wl_client *client, uint32_t mode, uint32_t keycode)
756 Eina_Bool res = EINA_FALSE;
758 struct wl_client *wc_data;
763 /* Top position grab is always allowed. This mode do not need privilege.*/
764 if (mode == TIZEN_KEYROUTER_MODE_TOPMOST)
767 if (krt->HardKeys[keycode].no_privcheck == EINA_TRUE &&
768 mode == TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE)
771 if (!client) return EINA_FALSE;
773 EINA_LIST_FOREACH(g_tizen_keyrouter->grab_client_list, l, wc_data)
775 if (wc_data == client)
782 wl_client_get_credentials(client, &pid, &uid, &gid);
783 res = e_security_privilege_check(pid, uid, "http://tizen.org/privilege/keygrab");
786 KLINF("Fail to check privilege, (pid : %d)", pid);
794 EINTERN E_Tizen_Keyrouter *
795 e_keyrouter_wl_init(struct wl_display *display)
797 EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
799 if (g_tizen_keyrouter) return g_tizen_keyrouter;
801 g_tizen_keyrouter = E_NEW(E_Tizen_Keyrouter, 1);
802 EINA_SAFETY_ON_NULL_RETURN_VAL(g_tizen_keyrouter, NULL);
805 g_tizen_keyrouter->global = wl_global_create(display,
806 &tizen_keyrouter_interface, 2, NULL, _e_keyrouter_cb_bind);
807 EINA_SAFETY_ON_NULL_RETURN_VAL(g_tizen_keyrouter->global, NULL);
809 return g_tizen_keyrouter;
813 e_keyrouter_wl_shutdown(void)
815 Eina_List *l, *l_next;
816 struct wl_resource *resource;
817 struct wl_client *client;
818 struct wl_listener *destroy_listener;
820 if (!g_tizen_keyrouter) return;
822 EINA_LIST_FOREACH_SAFE(g_tizen_keyrouter->grab_client_list, l, l_next, client)
824 destroy_listener = wl_client_get_destroy_listener(client, _e_keyrouter_wl_client_cb_destroy);
825 if (destroy_listener)
827 wl_list_remove(&destroy_listener->link);
828 E_FREE(destroy_listener);
830 g_tizen_keyrouter->grab_client_list = eina_list_remove(g_tizen_keyrouter->grab_client_list, client);
832 EINA_LIST_FOREACH_SAFE(g_tizen_keyrouter->grab_surface_list, l, l_next, resource)
834 destroy_listener = wl_resource_get_destroy_listener(resource, _e_keyrouter_wl_surface_cb_destroy);
835 if (destroy_listener)
837 wl_list_remove(&destroy_listener->link);
838 E_FREE(destroy_listener);
840 g_tizen_keyrouter->grab_surface_list = eina_list_remove(g_tizen_keyrouter->grab_surface_list, client);
843 EINA_LIST_FREE(g_tizen_keyrouter->resources, resource)
844 wl_resource_destroy(resource);
846 if (g_tizen_keyrouter->global)
848 wl_global_destroy(g_tizen_keyrouter->global);
850 E_FREE(g_tizen_keyrouter);