e_input: move kbd structure to e_comp_input_intern.h
[platform/upstream/enlightenment.git] / src / bin / e_keyrouter_wl.c
1 #include "e_keyrouter_intern.h"
2 #include "e_input_intern.h"
3 #include "e_comp_wl_input_intern.h"
4 #include "e_comp_wl_intern.h"
5 #include "e_client_intern.h"
6 #include "e_config_intern.h"
7 #include "e_comp_input_intern.h"
8
9 #include <tizen-extension-server-protocol.h>
10
11 void
12 e_keyrouter_wl_event_surface_send(struct wl_resource *surface, int key, int mode)
13 {
14    Eina_List *l;
15    struct wl_resource *res_data;
16    struct wl_client *wc;
17
18    EINA_SAFETY_ON_NULL_RETURN(krt);
19    EINA_SAFETY_ON_NULL_RETURN(surface);
20
21    wc = wl_resource_get_client(surface);
22    EINA_SAFETY_ON_NULL_RETURN(wc);
23
24    EINA_LIST_FOREACH(krt->resources, l, res_data)
25      {
26         if (wl_resource_get_client(res_data) != wc) continue;
27         if (wl_resource_get_version(res_data) < 2) continue;
28
29         if (e_config->key_input_ttrace_enable)
30           {
31              TRACE_INPUT_BEGIN(tizen_keyrouter_send_event_surface);
32              ELOGF("INPUT", "tizen_keyrouter_send_event_surface|B|", NULL);
33           }
34
35         tizen_keyrouter_send_event_surface(res_data, surface, key, mode);
36
37         if (e_config->key_input_ttrace_enable)
38           {
39              TRACE_INPUT_END();
40              ELOGF("INPUT", "tizen_keyrouter_send_event_surface|E|", NULL);
41           }
42      }
43 }
44
45 static void
46 _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)
47 {
48    struct wl_resource *res;
49    Eina_List *l;
50    uint32_t serial, keycode;
51    struct wl_client *wc;
52    E_Comp_Config *comp_conf = NULL;
53
54    keycode = (ev->keycode - 8);
55
56    serial = wl_display_next_serial(e_comp_wl->wl.disp);
57
58    comp_conf = e_comp_config_get();
59
60    if (surface && !focused)
61      {
62         e_comp_wl_connection_lock();
63         e_keyrouter_wl_event_surface_send(surface, ev->keycode, TIZEN_KEYROUTER_MODE_NONE);
64         e_comp_wl_connection_unlock();
65      }
66
67    if (e_config->key_input_ttrace_enable)
68      {
69         TRACE_INPUT_BEGIN(wl_keyboard_send_key:%s:%s, (state ? "PRESS" : "RELEASE"), ev->keyname);
70         ELOGF("INPUT", "wl_keyboard_send_key:%s:%s|B|", NULL, (state ? "PRESS" : "RELEASE"), ev->keyname);
71      }
72
73    EINA_LIST_FOREACH(key_list, l, res)
74      {
75         wc = wl_resource_get_client(res);
76         if (!focused && wc != client) continue;
77         TRACE_INPUT_BEGIN(_e_comp_wl_key_send);
78         if (!e_input_thread_mode_get())
79           {
80              e_comp_wl_send_event_device(client, ev->timestamp, ev->dev, serial);
81           }
82         else
83           {
84              if (dev)
85                e_comp_wl_send_event_e_device(client, ev->timestamp, dev, serial);
86           }
87
88         if (comp_conf && comp_conf->input_log_enable)
89           INF("[Server] Routed Key %s (time: %d)\n", (state ? "Down" : "Up"), ev->timestamp);
90
91         wl_keyboard_send_key(res, serial, ev->timestamp,
92                              keycode, state);
93         TRACE_INPUT_END();
94      }
95
96    if (e_config->key_input_ttrace_enable)
97      {
98         TRACE_INPUT_END();
99         ELOGF("INPUT", "wl_keyboard_send_key|E|", NULL);
100      }
101 }
102
103 Eina_Bool
104 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)
105 {
106    E_Client *ec = NULL;
107    struct wl_client *wc = NULL;
108    uint32_t keycode;
109    enum wl_keyboard_key_state state;
110
111    if (ev->window != e_comp->ee_win)
112      {
113         return EINA_FALSE;
114      }
115
116    keycode = (ev->keycode - 8);
117    if (!(e_comp_wl = e_comp->wl_comp_data))
118      {
119         return EINA_FALSE;
120      }
121
122 #ifndef E_RELEASE_BUILD
123    if ((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
124        ((ev->modifiers & ECORE_EVENT_MODIFIER_ALT) ||
125        (ev->modifiers & ECORE_EVENT_MODIFIER_ALTGR)) &&
126        eina_streq(ev->key, "BackSpace"))
127      {
128         exit(0);
129      }
130 #endif
131
132    if (pressed) state = WL_KEYBOARD_KEY_STATE_PRESSED;
133    else state = WL_KEYBOARD_KEY_STATE_RELEASED;
134
135    if (!focused)
136      {
137         _e_keyrouter_wl_key_send(ev, dev, state, e_comp_input_key->kbd.resources, EINA_FALSE, client, surface);
138         return EINA_FALSE;
139      }
140
141    if ((!e_client_action_get()) && (!e_comp->input_key_grabs))
142      {
143         ec = e_client_focused_get();
144
145         if (ec && ec->comp_data)
146           {
147              struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
148              if (surface)
149                {
150                   if (e_comp_input_key->kbd.focused)
151                     {
152                        wc = wl_resource_get_client(surface);
153                        _e_keyrouter_wl_key_send(ev, dev, state, e_comp_input_key->kbd.focused, EINA_TRUE, wc, surface);
154                     }
155                }
156
157              /* update modifier state */
158              e_comp_wl_input_keyboard_state_update(keycode, pressed);
159           }
160      }
161    return !!ec;
162 }
163
164 void
165 e_keyrouter_keycancel_send(struct wl_client *client, struct wl_resource *surface, unsigned int key)
166 {
167    Eina_List *l;
168    struct wl_resource *resource = NULL;
169    struct wl_client *wc = NULL;
170    E_Keyrouter_Key_List_NodePtr data;
171    Eina_List *press_ptr_list = NULL;
172
173    if (surface) wc = wl_resource_get_client(surface);
174    else wc = client;
175
176    EINA_SAFETY_ON_NULL_RETURN(wc);
177
178    press_ptr_list = krt->HardKeys[key].press_ptr;
179    EINA_LIST_FOREACH(press_ptr_list, l, data)
180      {
181         if (surface)
182           {
183              if (surface == data->surface)
184                {
185                   EINA_LIST_FOREACH(krt->resources, l, resource)
186                     {
187                        if (wl_resource_get_client(resource) != wc) continue;
188
189                        tizen_keyrouter_send_key_cancel(resource, key-8);
190                     }
191                }
192           }
193         else if (client == data->wc)
194           {
195              EINA_LIST_FOREACH(krt->resources, l, resource)
196                {
197                   if (wl_resource_get_client(resource) != wc) continue;
198
199                   tizen_keyrouter_send_key_cancel(resource, key-8);
200                }
201           }
202      }
203 }
204
205 static int
206 _e_keyrouter_wl_array_length(const struct wl_array *array)
207 {
208    int *data = NULL;
209    int count = 0;
210
211    wl_array_for_each(data, array)
212      {
213         count++;
214      }
215
216    return count;
217 }
218
219 static void
220 _e_keyrouter_input_thread_keygrab_set(void *data)
221 {
222    int res = 0;
223
224    E_Input_Thread_Request_Keygrab_Data keygrab_data;
225    memcpy(&keygrab_data, data, sizeof(E_Input_Thread_Request_Keygrab_Data));
226
227    TRACE_INPUT_BEGIN(_e_keyrouter_cb_keygrab_set);
228
229    res = e_keyrouter_keygrab_set(keygrab_data.client, keygrab_data.surface, keygrab_data.key, keygrab_data.mode);
230
231    TRACE_INPUT_END();
232
233    if (res == TIZEN_KEYROUTER_ERROR_NONE)
234      {
235         if (keygrab_data.mode == TIZEN_KEYROUTER_MODE_EXCLUSIVE)
236           {
237              KLINF("Success to %d key %s grab request (wl_client: %p, wl_surface: %p, pid: %d)", keygrab_data.key, e_keyrouter_mode_to_string(keygrab_data.mode),
238                 keygrab_data.client, keygrab_data.surface, e_keyrouter_util_get_pid(keygrab_data.client, keygrab_data.surface));
239           }
240         else
241           {
242              KLDBG("Success to %d key %s grab request (wl_client: %p, wl_surface: %p, pid: %d)", keygrab_data.key, e_keyrouter_mode_to_string(keygrab_data.mode),
243                 keygrab_data.client, keygrab_data.surface, e_keyrouter_util_get_pid(keygrab_data.client, keygrab_data.surface));
244           }
245      }
246    else
247      KLINF("Failed to %d key %s grab request (wl_client: %p, wl_surface: %p, pid: %d): res: %d", keygrab_data.key, e_keyrouter_mode_to_string(keygrab_data.mode),
248         keygrab_data.client, keygrab_data.surface, e_keyrouter_util_get_pid(keygrab_data.client, keygrab_data.surface), res);
249
250    tizen_keyrouter_send_keygrab_notify(keygrab_data.resource, keygrab_data.surface, keygrab_data.key, keygrab_data.mode, res);
251 }
252
253 /* tizen_keyrouter_set_keygrab request handler */
254 static void
255 _e_keyrouter_cb_keygrab_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, uint32_t key, uint32_t mode)
256 {
257    TRACE_INPUT_BEGIN(_e_keyrouter_cb_keygrab_set);
258
259    E_Input_Thread_Request_Keygrab_Data keygrab_data;
260
261    keygrab_data.resource = resource;
262    keygrab_data.surface = surface;
263    keygrab_data.client = client;
264    keygrab_data.key = key;
265    keygrab_data.mode = mode;
266
267    INF("client: %p, surface: %p, key: %d, mode: %d\n", keygrab_data.client, keygrab_data.surface, keygrab_data.key, keygrab_data.mode);
268    e_input_thread_safe_call(_e_keyrouter_input_thread_keygrab_set, &keygrab_data, sizeof(E_Input_Thread_Request_Keygrab_Data));
269 }
270
271 static void
272 _e_keyrouter_input_thread_keygrab_unset(void *data)
273 {
274    int res = 0;
275    E_Input_Thread_Request_Keygrab_Data keygrab_data;
276    memcpy(&keygrab_data, data, sizeof(E_Input_Thread_Request_Keygrab_Data));
277
278    res = e_keyrouter_keygrab_unset(keygrab_data.client, keygrab_data.surface, keygrab_data.key);
279
280    TRACE_INPUT_END();
281
282    if (res == TIZEN_KEYROUTER_ERROR_NONE)
283      KLDBG("Success to %d key ungrab request (wl_client: %p, wl_surface: %p, pid: %d)", keygrab_data.key, keygrab_data.client, keygrab_data.surface,
284            e_keyrouter_util_get_pid(keygrab_data.client, keygrab_data.surface));
285    else
286      KLINF("Failed to %d key ungrab request (wl_client: %p, wl_surface: %p, pid: %d): res: %d", keygrab_data.key, keygrab_data.client, keygrab_data.surface,
287            e_keyrouter_util_get_pid(keygrab_data.client, keygrab_data.surface), res);
288
289    tizen_keyrouter_send_keygrab_notify(keygrab_data.resource, keygrab_data.surface, keygrab_data.key, TIZEN_KEYROUTER_MODE_NONE, res);
290 }
291
292 /* tizen_keyrouter unset_keygrab request handler */
293 static void
294 _e_keyrouter_cb_keygrab_unset(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, uint32_t key)
295 {
296    TRACE_INPUT_BEGIN(_e_keyrouter_cb_keygrab_unset);
297
298    E_Input_Thread_Request_Keygrab_Data keygrab_data;
299
300    keygrab_data.resource = resource;
301    keygrab_data.surface = surface;
302    keygrab_data.client = client;
303    keygrab_data.key = key;
304
305    INF("client: %p, surface: %p, key: %d, mode: %d\n", keygrab_data.client, keygrab_data.surface, keygrab_data.key, keygrab_data.mode);
306    e_input_thread_safe_call(_e_keyrouter_input_thread_keygrab_unset, &keygrab_data, sizeof(E_Input_Thread_Request_Keygrab_Data));
307 }
308
309 /* tizen_keyrouter get_keygrab_status request handler */
310 static void
311 _e_keyrouter_cb_get_keygrab_status(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, uint32_t key)
312 {
313    (void) client;
314    (void) resource;
315    (void) surface;
316    (void) key;
317    int mode = TIZEN_KEYROUTER_MODE_NONE;
318
319    TRACE_INPUT_BEGIN(_e_keyrouter_cb_get_keygrab_status);
320    mode = e_keyrouter_find_key_in_list(surface, client, key);
321
322    TRACE_INPUT_END();
323    tizen_keyrouter_send_keygrab_notify(resource, surface, key, mode, TIZEN_KEYROUTER_ERROR_NONE);
324 }
325
326 static void
327 _e_keyrouter_cb_keygrab_set_list(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, struct wl_array *grab_list)
328 {
329    E_Keyrouter_Grab_Request *grab_request = NULL;
330    int res = TIZEN_KEYROUTER_ERROR_NONE;
331    int array_len = 0;
332
333    TRACE_INPUT_BEGIN(_e_keyrouter_cb_keygrab_set_list);
334
335    array_len = _e_keyrouter_wl_array_length(grab_list);
336
337    if (0 != (array_len % 3))
338      {
339         /* FIX ME: Which way is effectively to notify invalid pair to client */
340         KLWRN("Invalid keycode and grab mode pair. Check arguments in a list");
341         TRACE_INPUT_END();
342         tizen_keyrouter_send_keygrab_notify_list(resource, surface, NULL);
343         return;
344      }
345
346    wl_array_for_each(grab_request, grab_list)
347      {
348         res = e_keyrouter_keygrab_set(client, surface, grab_request->key, grab_request->mode);
349         grab_request->err = res;
350         if (res == TIZEN_KEYROUTER_ERROR_NONE)
351           KLDBG("Success to %d key %s grab using list(wl_client: %p, wl_surface: %p, pid: %d)",
352                 grab_request->key, e_keyrouter_mode_to_string(grab_request->mode),
353                 client, surface, e_keyrouter_util_get_pid(client, surface));
354         else
355           KLINF("Failed to %d key %s grab using list(wl_client: %p, wl_surface: %p, pid: %d): res: %d",
356                 grab_request->key, e_keyrouter_mode_to_string(grab_request->mode),
357                 client, surface, e_keyrouter_util_get_pid(client, surface), grab_request->err);
358      }
359
360    TRACE_INPUT_END();
361    tizen_keyrouter_send_keygrab_notify_list(resource, surface, grab_list);
362 }
363
364 static void
365 _e_keyrouter_cb_keygrab_unset_list(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, struct wl_array *ungrab_list)
366 {
367    E_Keyrouter_Ungrab_Request *ungrab_request = NULL;
368    int res = TIZEN_KEYROUTER_ERROR_NONE;
369    int array_len = 0;
370
371    TRACE_INPUT_BEGIN(_e_keyrouter_cb_keygrab_unset_list);
372
373    array_len = _e_keyrouter_wl_array_length(ungrab_list);
374
375    if (0 != (array_len % 2))
376      {
377         /* FIX ME: Which way is effectively to notify invalid pair to client */
378         KLWRN("Invalid keycode and error pair. Check arguments in a list");
379         TRACE_INPUT_END();
380         tizen_keyrouter_send_keygrab_notify_list(resource, surface, ungrab_list);
381         return;
382      }
383
384    wl_array_for_each(ungrab_request, ungrab_list)
385      {
386         res = e_keyrouter_keygrab_unset(client, surface, ungrab_request->key);
387         ungrab_request->err = res;
388         if (res == TIZEN_KEYROUTER_ERROR_NONE)
389           KLDBG("Success to ungrab using list: %d key (wl_client: %p, wl_surface: %p, pid: %d)",
390                 ungrab_request->key, client, surface, e_keyrouter_util_get_pid(client, surface));
391         else
392           KLINF("Failed to ungrab using list: %d key (wl_client: %p, wl_surface: %p, pid: %d): res: %d",
393                 ungrab_request->key, client, surface, e_keyrouter_util_get_pid(client, surface), ungrab_request->err);
394      }
395
396    TRACE_INPUT_END();
397    tizen_keyrouter_send_keygrab_notify_list(resource, surface, ungrab_list);
398 }
399
400 static void
401 _e_keyrouter_cb_keygrab_get_list(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface)
402 {
403    (void) client;
404
405    tizen_keyrouter_send_getgrab_notify_list(resource, surface, NULL);
406 }
407
408 static void
409 _e_keyrouter_cb_set_register_none_key(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, uint32_t data)
410 {
411    (void) client;
412    (void) data;
413
414    tizen_keyrouter_send_set_register_none_key_notify(resource, NULL, 0);
415 }
416
417 static void
418 _e_keyrouter_cb_get_keyregister_status(struct wl_client *client, struct wl_resource *resource, uint32_t key)
419 {
420    (void) client;
421    (void) key;
422
423    tizen_keyrouter_send_keyregister_notify(resource, (int)EINA_FALSE);
424 }
425
426 static void
427 _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)
428 {
429    tizen_keyrouter_send_set_input_config_notify(resource, 0);
430 }
431
432 static void
433 _e_keyrouter_cb_destroy(struct wl_client *client, struct wl_resource *resource)
434 {
435    wl_resource_destroy(resource);
436 }
437
438 static const struct tizen_keyrouter_interface _e_keyrouter_implementation = {
439    _e_keyrouter_cb_keygrab_set,
440    _e_keyrouter_cb_keygrab_unset,
441    _e_keyrouter_cb_get_keygrab_status,
442    _e_keyrouter_cb_keygrab_set_list,
443    _e_keyrouter_cb_keygrab_unset_list,
444    _e_keyrouter_cb_keygrab_get_list,
445    _e_keyrouter_cb_set_register_none_key,
446    _e_keyrouter_cb_get_keyregister_status,
447    _e_keyrouter_cb_set_input_config,
448    _e_keyrouter_cb_destroy,
449 };
450
451 static void
452 _e_keyrouter_cb_unbind(struct wl_resource *resource)
453 {
454    krt->resources = eina_list_remove(krt->resources, resource);
455 }
456
457 /* tizen_keyrouter global object bind function */
458 static void
459 _e_keyrouter_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
460 {
461    E_KeyrouterPtr krt_instance = data;
462    struct wl_resource *resource;
463
464    resource = wl_resource_create(client, &tizen_keyrouter_interface, version, id);
465
466    KLDBG("wl_resource_create(...,&tizen_keyrouter_interface,...)");
467
468    if (!resource)
469      {
470         KLERR("Failed to create resource ! (version :%d, id:%d)", version, id);
471         wl_client_post_no_memory(client);
472          return;
473      }
474
475    krt->resources = eina_list_append(krt->resources, resource);
476
477    wl_resource_set_implementation(resource, &_e_keyrouter_implementation, krt_instance, _e_keyrouter_cb_unbind);
478 }
479
480 static void
481 _e_keyrouter_wl_client_cb_destroy(struct wl_listener *l, void *data)
482 {
483    struct wl_client *client = data;
484
485    KLDBG("Listener(%p) called: wl_client: %p is died", l, client);
486    e_keyrouter_remove_client_from_list(NULL, client);
487
488    wl_list_remove(&l->link);
489    E_FREE(l);
490
491    krt->grab_client_list = eina_list_remove(krt->grab_client_list, client);
492 }
493
494 static void
495 _e_keyrouter_wl_surface_cb_destroy(struct wl_listener *l, void *data)
496 {
497    struct wl_resource *surface = (struct wl_resource *)data;
498
499    KLDBG("Listener(%p) called: surface: %p is died", l, surface);
500    e_keyrouter_remove_client_from_list(surface, NULL);
501
502    wl_list_remove(&l->link);
503    E_FREE(l);
504
505    krt->grab_surface_list = eina_list_remove(krt->grab_surface_list, surface);
506 }
507
508 int
509 e_keyrouter_wl_add_client_destroy_listener(struct wl_client *client)
510 {
511    struct wl_listener *destroy_listener = NULL;
512    Eina_List *l;
513    struct wl_client *wc_data;
514
515    if (!client) return TIZEN_KEYROUTER_ERROR_NONE;
516
517    EINA_LIST_FOREACH(krt->grab_client_list, l, wc_data)
518      {
519         if (wc_data)
520           {
521              if (wc_data == client)
522                {
523                   return TIZEN_KEYROUTER_ERROR_NONE;
524                }
525           }
526      }
527
528    destroy_listener = E_NEW(struct wl_listener, 1);
529
530    if (!destroy_listener)
531      {
532         KLERR("Failed to allocate memory for wl_client destroy listener !");
533         return TIZEN_KEYROUTER_ERROR_NO_SYSTEM_RESOURCES;
534      }
535
536    destroy_listener->notify = _e_keyrouter_wl_client_cb_destroy;
537    wl_client_add_destroy_listener(client, destroy_listener);
538    krt->grab_client_list = eina_list_append(krt->grab_client_list, client);
539
540    return TIZEN_KEYROUTER_ERROR_NONE;
541 }
542
543 /* Function for registering wl_surface destroy listener */
544 int
545 e_keyrouter_wl_add_surface_destroy_listener(struct wl_resource *surface)
546 {
547    struct wl_listener *destroy_listener = NULL;
548    Eina_List *l;
549    struct wl_resource *surface_data;
550
551    if (!surface) return TIZEN_KEYROUTER_ERROR_NONE;
552
553    EINA_LIST_FOREACH(krt->grab_surface_list, l, surface_data)
554      {
555         if (surface_data)
556           {
557              if (surface_data == surface)
558                {
559                   return TIZEN_KEYROUTER_ERROR_NONE;
560                }
561           }
562      }
563
564    destroy_listener = E_NEW(struct wl_listener, 1);
565
566    if (!destroy_listener)
567      {
568         KLERR("Failed to allocate memory for wl_surface destroy listener !");
569         return TIZEN_KEYROUTER_ERROR_NO_SYSTEM_RESOURCES;
570      }
571
572    destroy_listener->notify = _e_keyrouter_wl_surface_cb_destroy;
573    wl_resource_add_destroy_listener(surface, destroy_listener);
574    krt->grab_surface_list = eina_list_append(krt->grab_surface_list, surface);
575
576    return TIZEN_KEYROUTER_ERROR_NONE;
577 }
578
579 #ifdef HAVE_CYNARA
580 static void
581 _e_keyrouter_wl_util_cynara_log(const char *func_name, int err)
582 {
583 #define CYNARA_BUFSIZE 128
584    char buf[CYNARA_BUFSIZE] = "\0";
585    int ret;
586
587    ret = cynara_strerror(err, buf, CYNARA_BUFSIZE);
588    if (ret != CYNARA_API_SUCCESS)
589      {
590         KLWRN("Failed to cynara_strerror: %d (error log about %s: %d)", ret, func_name, err);
591         return;
592      }
593    KLWRN("%s is failed: %s", func_name, buf);
594 }
595
596 Eina_Bool
597 e_keyrouter_wl_util_do_privilege_check(struct wl_client *client, uint32_t mode, uint32_t keycode)
598 {
599    int ret, retry_cnt=0, len=0;
600    char *clientSmack=NULL, *client_session=NULL, uid2[16]={0, };
601    Eina_Bool res = EINA_FALSE;
602    Eina_List *l;
603    struct wl_client *wc_data;
604    static Eina_Bool retried = EINA_FALSE;
605    pid_t pid = 0;
606    uid_t uid = 0;
607    gid_t gid = 0;
608
609    /* Top position grab is always allowed. This mode do not need privilege.*/
610    if (mode == TIZEN_KEYROUTER_MODE_TOPMOST)
611      return EINA_TRUE;
612
613    if (krt->HardKeys[keycode].no_privcheck == EINA_TRUE &&
614        mode == TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE)
615      return EINA_TRUE;
616
617    if (!client) return EINA_FALSE;
618
619    /* If initialize cynara is failed, allow keygrabs regardless of the previlege permition. */
620    if (krt->p_cynara == NULL)
621      {
622         if (retried == EINA_FALSE)
623           {
624              retried = EINA_TRUE;
625              for(retry_cnt = 0; retry_cnt < 5; retry_cnt++)
626                {
627                   KLDBG("Retry cynara initialize: %d", retry_cnt+1);
628                   ret = cynara_initialize(&krt->p_cynara, NULL);
629                   if (EINA_UNLIKELY(CYNARA_API_SUCCESS != ret))
630                     {
631                       _e_keyrouter_wl_util_cynara_log("cynara_initialize", ret);
632                        krt->p_cynara = NULL;
633                     }
634                   else
635                     {
636                        KLDBG("Success cynara initialize to try %d times", retry_cnt+1);
637                        break;
638                     }
639                }
640           }
641         return EINA_TRUE;
642      }
643
644    EINA_LIST_FOREACH(krt->grab_client_list, l, wc_data)
645      {
646         if (wc_data == client)
647           {
648              res = EINA_TRUE;
649              goto finish;
650           }
651      }
652
653    wl_client_get_credentials(client, &pid, &uid, &gid);
654
655    len = smack_new_label_from_process((int)pid, &clientSmack);
656    if (len <= 0) goto finish;
657
658    snprintf(uid2, 15, "%d", (int)uid);
659    client_session = cynara_session_from_pid(pid);
660
661    ret = cynara_check(krt->p_cynara, clientSmack, client_session, uid2, "http://tizen.org/privilege/keygrab");
662    if (CYNARA_API_ACCESS_ALLOWED == ret)
663      {
664         res = EINA_TRUE;
665      }
666    else
667      {
668         KLINF("Fail to check cynara,  error : %d (pid : %d)", ret, pid);
669      }
670 finish:
671    if (client_session) E_FREE(client_session);
672    if (clientSmack) E_FREE(clientSmack);
673
674    return res;
675 }
676 #endif
677
678 Eina_Bool
679 e_keyrouter_wl_init(void)
680 {
681    int ret;
682
683    EINA_SAFETY_ON_NULL_RETURN_VAL(krt, EINA_FALSE);
684    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, EINA_FALSE);
685
686    krt->global = wl_global_create(e_comp_wl->wl.disp, &tizen_keyrouter_interface, 2, krt, _e_keyrouter_cb_bind);
687    EINA_SAFETY_ON_NULL_RETURN_VAL(krt->global, EINA_FALSE);
688
689 #ifdef HAVE_CYNARA
690    ret = cynara_initialize(&krt->p_cynara, NULL);
691    if (EINA_UNLIKELY(CYNARA_API_SUCCESS != ret))
692      {
693         _e_keyrouter_wl_util_cynara_log("cynara_initialize", ret);
694         krt->p_cynara = NULL;
695      }
696 #endif
697
698    return EINA_TRUE;
699 }
700
701 void
702 e_keyrouter_wl_shutdown(void)
703 {
704    Eina_List *l, *l_next;
705    struct wl_resource *resource;
706    struct wl_client *client;
707    struct wl_listener *destroy_listener;
708
709    EINA_SAFETY_ON_NULL_RETURN(krt);
710
711    EINA_LIST_FOREACH_SAFE(krt->grab_client_list, l, l_next, client)
712      {
713         destroy_listener = wl_client_get_destroy_listener(client, _e_keyrouter_wl_client_cb_destroy);
714         if (destroy_listener)
715           {
716              wl_list_remove(&destroy_listener->link);
717              E_FREE(destroy_listener);
718           }
719         krt->grab_client_list = eina_list_remove(krt->grab_client_list, client);
720      }
721    EINA_LIST_FOREACH_SAFE(krt->grab_surface_list, l, l_next, resource)
722      {
723         destroy_listener = wl_resource_get_destroy_listener(resource, _e_keyrouter_wl_surface_cb_destroy);
724         if (destroy_listener)
725           {
726              wl_list_remove(&destroy_listener->link);
727              E_FREE(destroy_listener);
728           }
729         krt->grab_surface_list = eina_list_remove(krt->grab_surface_list, client);
730      }
731
732    EINA_LIST_FREE(krt->resources, resource)
733      wl_resource_destroy(resource);
734
735    if (krt->global) wl_global_destroy(krt->global);
736
737 #ifdef HAVE_CYNARA
738    if (krt->p_cynara) cynara_finish(krt->p_cynara);
739 #endif
740 }