e_keyrouter: call hook functions about release events, if press events call hook...
[platform/upstream/enlightenment.git] / src / bin / e_keyrouter_events.c
1 #include "e_keyrouter_private.h"
2
3 static void _e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev);
4 static void _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev);
5 static void _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev);
6 static void _e_keyrouter_send_key_event(int type, struct wl_resource *surface, struct wl_client *wc, Ecore_Event_Key *ev, Eina_Bool focused, unsigned int mode);
7
8 static Eina_Bool _e_keyrouter_send_key_events_focus(int type, struct wl_resource *surface, Ecore_Event_Key *ev, struct wl_resource **delivered_surface);
9
10 static Eina_Bool _e_keyrouter_is_key_grabbed(int key);
11 static Eina_Bool _e_keyrouter_check_top_visible_window(E_Client *ec_focus, int arr_idx);
12
13 static Eina_Bool
14 _e_keyrouter_is_key_grabbed(int key)
15 {
16    if (!krt->HardKeys[key].keycode)
17      {
18         return EINA_FALSE;
19      }
20    if (krt->HardKeys[key].excl_ptr ||
21         krt->HardKeys[key].or_excl_ptr ||
22         krt->HardKeys[key].top_ptr ||
23         krt->HardKeys[key].shared_ptr)
24      {
25         return EINA_TRUE;
26      }
27
28    return EINA_FALSE;
29 }
30
31 static Eina_Bool
32 _e_keyrouter_event_routed_key_check(Ecore_Event_Key *ev, int type)
33 {
34    Eina_List *l, *l_next;
35    int *keycode_data;
36
37    if ((ev->modifiers != 0) && (type == ECORE_EVENT_KEY_DOWN))
38      {
39         KLDBG("Modifier key delivered to Focus window : Key %s(%d)", ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode);
40         keycode_data = E_NEW(int, 1);
41         if (keycode_data)
42           {
43              *keycode_data = ev->keycode;
44              krt->ignore_list = eina_list_append(krt->ignore_list, keycode_data);
45           }
46         return EINA_FALSE;
47      }
48
49    EINA_LIST_FOREACH_SAFE(krt->ignore_list, l, l_next, keycode_data)
50      {
51         if (*keycode_data == ev->keycode)
52           {
53              KLDBG("Find ignore key, propagate event (%d)\n", ev->keycode);
54              E_FREE(keycode_data);
55              krt->ignore_list = eina_list_remove_list(krt->ignore_list, l);
56
57              return EINA_FALSE;
58           }
59      }
60
61    if (krt->max_tizen_hwkeys < ev->keycode)
62      {
63         KLWRN("The key(%d) is too larger to process keyrouting: Invalid keycode", ev->keycode);
64         return EINA_FALSE;
65      }
66
67    if (!krt->HardKeys[ev->keycode].keycode) return EINA_FALSE;
68
69    return EINA_TRUE;
70 }
71
72 /* Function for checking the existing grab for a key and sending key event(s) */
73 Eina_Bool
74 e_keyrouter_event_process(void *event, int type)
75 {
76    Eina_Bool res = EINA_FALSE;
77    Ecore_Event_Key *ev = event;
78    E_Keyrouter_Event_Data *key_data;
79
80    KLDBG("[%s] keyname: %s, key: %s, keycode: %d", (type == ECORE_EVENT_KEY_DOWN) ? "KEY_PRESS" : "KEY_RELEASE", ev->keyname, ev->key, ev->keycode);
81
82    e_screensaver_notidle();
83
84    if (!ev->data)
85      {
86         KLWRN("%s key (%d) %s is not handled by keyrouter\n", ev->keyname, ev->keycode, (type == ECORE_EVENT_KEY_DOWN) ? "press" : "release");
87         goto focus_deliver;
88      }
89
90    key_data = (E_Keyrouter_Event_Data *)ev->data;
91
92    if (key_data->client || key_data->surface)
93      {
94         e_keyrouter_wl_key_send(ev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_FALSE);
95         return EINA_TRUE;
96      }
97
98    if (!_e_keyrouter_event_routed_key_check(event, type))
99      {
100         goto focus_deliver;
101      }
102
103    res = e_keyrouter_intercept_hook_call(E_KEYROUTER_INTERCEPT_HOOK_BEFORE_KEYROUTING, type, ev);
104    if (res)
105      {
106         if (key_data->ignored) goto finish;
107         if (key_data->client || key_data->surface)
108           {
109              e_keyrouter_wl_key_send(ev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_FALSE);
110              goto finish;
111           }
112      }
113    else
114      {
115         goto finish;
116      }
117
118    //KLDBG("The key(%d) is going to be sent to the proper wl client(s) !", ev->keycode);
119    KLDBG("[%s] keyname: %s, key: %s, keycode: %d", (type == ECORE_EVENT_KEY_DOWN) ? "KEY_PRESS" : "KEY_RELEASE", ev->keyname, ev->key, ev->keycode);
120    _e_keyrouter_send_key_events(type, ev);
121    return EINA_FALSE;
122
123 focus_deliver:
124    res = e_comp_wl_key_process(event, type);
125 finish:
126    return res;
127 }
128
129 /* Function for sending key events to wl_client(s) */
130 static void
131 _e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev)
132 {
133    if (ECORE_EVENT_KEY_DOWN == type)
134      {
135         _e_keyrouter_send_key_events_press(type, ev);
136      }
137   else
138      {
139         _e_keyrouter_send_key_events_release(type, ev);
140      }
141 }
142
143 static void
144 _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev)
145 {
146    int pid = 0;
147    char *pname = NULL, *cmd = NULL;
148    E_Keyrouter_Key_List_NodePtr key_node_data;
149    Eina_Bool res_hook = EINA_TRUE;
150    E_Keyrouter_Event_Data *key_data = NULL;
151
152    /* Deliver release  clean up pressed key list */
153    EINA_LIST_FREE(krt->HardKeys[ev->keycode].press_ptr, key_node_data)
154      {
155         if (key_node_data->focused == EINA_TRUE)
156           {
157              res_hook = e_keyrouter_intercept_hook_call(E_KEYROUTER_INTERCEPT_HOOK_DELIVER_FOCUS, type, ev);
158              key_data = (E_Keyrouter_Event_Data *)ev->data;
159
160              if (res_hook)
161                {
162                   if (key_data->ignored)
163                     {
164                        E_FREE(key_node_data);
165                        continue;
166                     }
167                   if (key_data->surface || key_data->client)
168                     {
169                        _e_keyrouter_send_key_event(type, key_data->surface, key_data->client, ev,
170                                                    key_node_data->focused, TIZEN_KEYROUTER_MODE_PRESSED);
171
172                        pid = e_keyrouter_util_get_pid(key_data->client, key_data->surface);
173                        cmd = e_keyrouter_util_cmd_get_from_pid(pid);
174                        pname = e_keyrouter_util_process_name_get_from_cmd(cmd);
175                        KLINF("Release Direct : %s(%s:%d)(Focus: %d)(Status: %d) => wl_surface (%p) wl_client (%p) (pid: %d) (pname: %s)",
176                              ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode, key_node_data->focused,
177                              key_node_data->status, key_data->surface, key_data->client, pid, pname ?: "Unknown");
178                        if(pname) E_FREE(pname);
179                        if(cmd) E_FREE(cmd);
180
181                        E_FREE(key_node_data);
182                        continue;
183                     }
184                }
185           }
186
187         if (!res_hook)
188           {
189              E_FREE(key_node_data);
190              continue;
191           }
192
193         if (key_node_data->status == E_KRT_CSTAT_ALIVE)
194           {
195              _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev,
196                                          key_node_data->focused, TIZEN_KEYROUTER_MODE_PRESSED);
197
198              pid = e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface);
199              cmd = e_keyrouter_util_cmd_get_from_pid(pid);
200              pname = e_keyrouter_util_process_name_get_from_cmd(cmd);
201              KLINF("Release Pair : %s(%s:%d)(Focus: %d)(Status: %d) => wl_surface (%p) wl_client (%p) (pid: %d) (pname: %s)",
202                       ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode, key_node_data->focused,
203                       key_node_data->status, key_node_data->surface, key_node_data->wc, pid, pname ?: "Unknown");
204              if(pname) E_FREE(pname);
205              if(cmd) E_FREE(cmd);
206           }
207         else
208           {
209              KLINF("Release Skip : %s(%s:%d)(Focus: %d)(Status: %d) => wl_surface (%p) wl_client (%p) process is ungrabbed / dead",
210                       ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode, key_node_data->focused,
211                       key_node_data->status, key_node_data->surface, key_node_data->wc);
212           }
213
214         E_FREE(key_node_data);
215      }
216    krt->HardKeys[ev->keycode].press_ptr = NULL;
217 }
218
219 static void
220 _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev)
221 {
222    unsigned int keycode = ev->keycode;
223    struct wl_resource *surface_focus = NULL;
224    E_Client *ec_focus = NULL;
225    struct wl_resource *delivered_surface = NULL;
226    Eina_Bool res;
227    int ret = 0;
228    int pid = 0;
229    char *pname = NULL, *cmd = NULL;
230
231    E_Keyrouter_Key_List_NodePtr key_node_data;
232    Eina_List *l = NULL;
233
234    ec_focus = e_client_focused_get();
235    surface_focus = e_keyrouter_util_get_surface_from_eclient(ec_focus);
236
237    if (krt->isPictureOffEnabled == 1)
238      {
239        EINA_LIST_FOREACH(krt->HardKeys[keycode].pic_off_ptr, l, key_node_data)
240           {
241             if (key_node_data)
242                 {
243                  _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, key_node_data->focused, TIZEN_KEYROUTER_MODE_SHARED);
244
245                  pid = e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface);
246                  cmd = e_keyrouter_util_cmd_get_from_pid(pid);
247                  pname = e_keyrouter_util_process_name_get_from_cmd(cmd);
248                  KLINF("PICTURE OFF : %s(%d) => wl_surface (%p) wl_client (%p) (pid: %d) (pname: %s)",
249                        ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode, key_node_data->surface, key_node_data->wc, pid, pname ?: "Unknown");
250                  if(pname) E_FREE(pname);
251                  if(cmd) E_FREE(cmd);
252                 }
253           }
254        return;
255      }
256    if (!_e_keyrouter_is_key_grabbed(ev->keycode))
257      {
258         _e_keyrouter_send_key_events_focus(type, surface_focus, ev, &delivered_surface);
259         return;
260      }
261
262    EINA_LIST_FOREACH(krt->HardKeys[keycode].excl_ptr, l, key_node_data)
263      {
264         if (key_node_data)
265           {
266              _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev,
267                                         key_node_data->focused, TIZEN_KEYROUTER_MODE_EXCLUSIVE);
268
269              pid = e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface);
270              cmd = e_keyrouter_util_cmd_get_from_pid(pid);
271              pname = e_keyrouter_util_process_name_get_from_cmd(cmd);
272              KLINF("EXCLUSIVE : %s(%s:%d) => wl_surface (%p) wl_client (%p) (pid: %d) (pname: %s)",
273                       ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode,
274                       key_node_data->surface, key_node_data->wc, pid, pname ?: "Unknown");
275              if(pname) E_FREE(pname);
276              if(cmd) E_FREE(cmd);
277              return;
278           }
279      }
280
281    EINA_LIST_FOREACH(krt->HardKeys[keycode].or_excl_ptr, l, key_node_data)
282      {
283         if (key_node_data)
284           {
285              _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev,
286                                          key_node_data->focused, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
287
288              pid = e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface);
289              cmd = e_keyrouter_util_cmd_get_from_pid(pid);
290              pname = e_keyrouter_util_process_name_get_from_cmd(cmd);
291              KLINF("OVERRIDABLE_EXCLUSIVE : %s(%s:%d) => wl_surface (%p) wl_client (%p) (pid: %d) (pname: %s)",
292                      ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode,
293                      key_node_data->surface, key_node_data->wc, pid, pname ?: "Unknown");
294              if(pname) E_FREE(pname);
295              if(cmd) E_FREE(cmd);
296
297              return;
298           }
299      }
300
301    // Top position grab must need a focus surface.
302    if (surface_focus)
303      {
304         EINA_LIST_FOREACH(krt->HardKeys[keycode].top_ptr, l, key_node_data)
305           {
306              if (key_node_data)
307                {
308                   if ((EINA_FALSE == krt->isWindowStackChanged) && (surface_focus == key_node_data->surface))
309                     {
310                        pid = e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface);
311                        cmd = e_keyrouter_util_cmd_get_from_pid(pid);
312                        pname = e_keyrouter_util_process_name_get_from_cmd(cmd);
313
314                        _e_keyrouter_send_key_event(type, key_node_data->surface, NULL, ev, key_node_data->focused,
315                                                    TIZEN_KEYROUTER_MODE_TOPMOST);
316                        KLINF("TOPMOST (TOP_POSITION) : %s (%s:%d) => wl_surface (%p) (pid: %d) (pname: %s)",
317                                 ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode,
318                                 key_node_data->surface, pid, pname ?: "Unknown");
319
320                        if(pname) E_FREE(pname);
321                        if(cmd) E_FREE(cmd);
322                        return;
323                     }
324                   krt->isWindowStackChanged = EINA_FALSE;
325
326                   if (_e_keyrouter_check_top_visible_window(ec_focus, keycode))
327                     {
328                        E_Keyrouter_Key_List_NodePtr top_key_node_data = eina_list_data_get(krt->HardKeys[keycode].top_ptr);
329                        pid = e_keyrouter_util_get_pid(top_key_node_data->wc, top_key_node_data->surface);
330                        cmd = e_keyrouter_util_cmd_get_from_pid(pid);
331                        pname = e_keyrouter_util_process_name_get_from_cmd(cmd);
332
333                        _e_keyrouter_send_key_event(type, top_key_node_data->surface, NULL, ev, top_key_node_data->focused,
334                                                    TIZEN_KEYROUTER_MODE_TOPMOST);
335                        KLINF("TOPMOST (TOP_POSITION) : %s (%s:%d) => wl_surface (%p) (pid: %d) (pname: %s)",
336                              ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode,
337                              top_key_node_data->surface, pid, pname ?: "Unknown");
338
339                        if(pname) E_FREE(pname);
340                        if(cmd) E_FREE(cmd);
341                        return;
342                     }
343                   break;
344                }
345           }
346        goto need_shared;
347      }
348
349    if (krt->HardKeys[keycode].shared_ptr)
350      {
351 need_shared:
352         res = _e_keyrouter_send_key_events_focus(type, surface_focus, ev, &delivered_surface);
353         if (delivered_surface)
354           {
355              ret = e_keyrouter_wl_add_surface_destroy_listener(delivered_surface);
356              if (ret != TIZEN_KEYROUTER_ERROR_NONE)
357                {
358                   KLWRN("Failed to add wl_surface to destroy listener (res: %d)", res);
359                }
360           }
361         if (res)
362           {
363              EINA_LIST_FOREACH(krt->HardKeys[keycode].shared_ptr, l, key_node_data)
364                {
365                   if (key_node_data)
366                     {
367                        if (delivered_surface && key_node_data->surface == delivered_surface)
368                          {
369                             // Check for already delivered surface
370                             // do not deliver double events in this case.
371                             continue;
372                          }
373                        else
374                          {
375                             _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, key_node_data->focused, TIZEN_KEYROUTER_MODE_SHARED);
376                             pid = e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface);
377                             cmd = e_keyrouter_util_cmd_get_from_pid(pid);
378                             pname = e_keyrouter_util_process_name_get_from_cmd(cmd);
379                             KLINF("SHARED : %s(%s:%d) => wl_surface (%p) wl_client (%p) (pid: %d) (pname: %s)",
380                                   ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode, key_node_data->surface, key_node_data->wc, pid, pname ?: "Unknown");
381                             if(pname) E_FREE(pname);
382                             if(cmd) E_FREE(cmd);
383                          }
384                     }
385                }
386           }
387      }
388 }
389
390 static Eina_Bool
391 _e_keyrouter_send_key_events_focus(int type, struct wl_resource *surface_focus,  Ecore_Event_Key *ev, struct wl_resource **delivered_surface)
392 {
393    Eina_Bool res = EINA_TRUE;
394    int pid = 0;
395    char *pname = NULL, *cmd = NULL;
396    E_Keyrouter_Event_Data *key_data;
397
398    res = e_keyrouter_intercept_hook_call(E_KEYROUTER_INTERCEPT_HOOK_DELIVER_FOCUS, type, ev);
399    key_data = (E_Keyrouter_Event_Data *)ev->data;
400    if (res)
401      {
402         if (key_data->ignored)
403           {
404              e_keyrouter_prepend_to_keylist(NULL, NULL, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, EINA_TRUE);
405              return EINA_TRUE;
406           }
407         else if (key_data->surface)
408           {
409              *delivered_surface = key_data->surface;
410              res = e_keyrouter_wl_key_send(ev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_FALSE);
411              return EINA_TRUE;
412           }
413      }
414    else
415      {
416         e_keyrouter_prepend_to_keylist(NULL, NULL, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, EINA_TRUE);
417         return EINA_FALSE;
418      }
419
420    pid = e_keyrouter_util_get_pid(NULL, surface_focus);
421    cmd = e_keyrouter_util_cmd_get_from_pid(pid);
422    pname = e_keyrouter_util_process_name_get_from_cmd(cmd);
423
424    _e_keyrouter_send_key_event(type, surface_focus, NULL,ev, EINA_TRUE, TIZEN_KEYROUTER_MODE_SHARED);
425    KLINF("FOCUS DIRECT : %s(%s:%d) => wl_surface (%p) (pid: %d) (pname: %s)",
426          ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode, surface_focus, pid, pname ?: "Unknown");
427    *delivered_surface = surface_focus;
428    if(pname) E_FREE(pname);
429    if(cmd) E_FREE(cmd);
430    return res;
431 }
432
433 static Eina_Bool
434 _e_keyrouter_check_top_visible_window(E_Client *ec_focus, int arr_idx)
435 {
436    E_Client *ec_top = NULL;
437    Eina_List *l = NULL, *l_next = NULL;
438    E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
439
440    ec_top = e_client_top_get();
441
442    while (ec_top)
443      {
444         if (!ec_top->visible && ec_top == ec_focus)
445           {
446              KLDBG("Top e_client (%p) is invisible(%d) but focus client", ec_top, ec_top->visible);
447              return EINA_FALSE;
448           }
449         if (!ec_top->visible)
450           {
451              ec_top = e_client_below_get(ec_top);
452              continue;
453           }
454
455         /* TODO: Check this client is located inside a display boundary */
456
457         EINA_LIST_FOREACH_SAFE(krt->HardKeys[arr_idx].top_ptr, l, l_next, key_node_data)
458           {
459              if (key_node_data)
460                {
461                   if (ec_top == wl_resource_get_user_data(key_node_data->surface))
462                     {
463                        krt->HardKeys[arr_idx].top_ptr = eina_list_promote_list(krt->HardKeys[arr_idx].top_ptr, l);
464                        KLDBG("Move a client(e_client: %p, wl_surface: %p) to first index of list(key: %d)",
465                                 ec_top, key_node_data->surface, arr_idx);
466                        return EINA_TRUE;
467                     }
468                }
469           }
470
471         if (ec_top == ec_focus)
472           {
473              KLDBG("The e_client(%p) is a focus client", ec_top);
474              return EINA_FALSE;
475           }
476
477         ec_top = e_client_below_get(ec_top);
478      }
479    return EINA_FALSE;
480 }
481
482 /* Function for sending key event to wl_client(s) */
483 static void
484 _e_keyrouter_send_key_event(int type, struct wl_resource *surface, struct wl_client *wc, Ecore_Event_Key *ev, Eina_Bool focused, unsigned int mode)
485 {
486    struct wl_client *wc_send;
487    Eina_Bool pressed = EINA_FALSE;
488
489    if (surface == NULL) wc_send = wc;
490    else wc_send = wl_resource_get_client(surface);
491
492    if (!wc_send)
493      {
494         KLWRN("wl_surface: %p or wl_client: %p returns null wayland client", surface, wc);
495         return;
496      }
497
498    if (ECORE_EVENT_KEY_DOWN == type)
499      {
500         pressed = EINA_TRUE;
501         e_keyrouter_prepend_to_keylist(surface, wc, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, focused);
502      }
503
504    e_keyrouter_wl_key_send(ev, pressed, wc_send, surface, focused);
505
506    return;
507 }
508
509 struct wl_resource *
510 e_keyrouter_util_get_surface_from_eclient(E_Client *client)
511 {
512    if (!client || !client->comp_data) return NULL;
513
514    return client->comp_data->wl_surface;
515 }
516
517 int
518 e_keyrouter_util_get_pid(struct wl_client *client, struct wl_resource *surface)
519 {
520    pid_t pid = 0;
521    uid_t uid = 0;
522    gid_t gid = 0;
523    struct wl_client *cur_client = NULL;
524
525    if (client) cur_client = client;
526    else if (surface) cur_client = wl_resource_get_client(surface);
527    EINA_SAFETY_ON_NULL_RETURN_VAL(cur_client, 0);
528
529    wl_client_get_credentials(cur_client, &pid, &uid, &gid);
530
531    return pid;
532 }
533
534 char *
535 e_keyrouter_util_cmd_get_from_pid(int pid)
536 {
537    Eina_List *l;
538    E_Comp_Connected_Client_Info *cdata;
539
540    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, NULL);
541
542    EINA_LIST_FOREACH(e_comp->connected_clients, l, cdata)
543      {
544         if (cdata->pid == pid) return strdup(cdata->name);
545      }
546
547    return NULL;
548 }
549
550 typedef struct _keycode_map{
551     xkb_keysym_t keysym;
552     xkb_keycode_t keycode;
553 }keycode_map;
554
555 static void
556 find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
557 {
558    keycode_map *found_keycodes = (keycode_map *)data;
559    xkb_keysym_t keysym = found_keycodes->keysym;
560    int nsyms = 0;
561    const xkb_keysym_t *syms_out = NULL;
562
563    nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
564    if (nsyms && syms_out)
565      {
566         if (*syms_out == keysym)
567           {
568              found_keycodes->keycode = key;
569           }
570      }
571 }
572
573 int
574 _e_keyrouter_keycode_get_from_keysym(struct xkb_keymap *keymap, xkb_keysym_t keysym)
575 {
576    keycode_map found_keycodes = {0,};
577    found_keycodes.keysym = keysym;
578    xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes);
579
580    return found_keycodes.keycode;
581 }
582
583 int
584 e_keyrouter_util_keycode_get_from_string(char * name)
585 {
586    struct xkb_keymap *keymap = NULL;
587    xkb_keysym_t keysym = 0x0;
588    int keycode = 0;
589
590    keymap = e_comp_wl->xkb.keymap;
591    EINA_SAFETY_ON_NULL_GOTO(keymap, finish);
592
593    keysym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
594    EINA_SAFETY_ON_FALSE_GOTO(keysym != XKB_KEY_NoSymbol, finish);
595
596    keycode = _e_keyrouter_keycode_get_from_keysym(keymap, keysym);
597
598    KLDBG("request name: %s, return value: %d", name, keycode);
599
600    return keycode;
601
602 finish:
603    return 0;
604 }
605
606 char *
607 e_keyrouter_util_keyname_get_from_keycode(int keycode)
608 {
609    struct xkb_state *state;
610    xkb_keysym_t sym = XKB_KEY_NoSymbol;
611    char name[256] = {0, };
612
613    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, NULL);
614    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl->xkb.state, NULL);
615
616    state = e_comp_wl->xkb.state;
617    sym = xkb_state_key_get_one_sym(state, keycode);
618    xkb_keysym_get_name(sym, name, sizeof(name));
619
620    return strdup(name);
621 }
622
623 char *
624 e_keyrouter_util_process_name_get_from_cmd(char *cmd)
625 {
626    int len, i;
627    char pbuf = '\0';
628    char *pname = NULL;
629    if (cmd)
630      {
631         len = strlen(cmd);
632         for (i = 0; i < len; i++)
633           {
634              pbuf = cmd[len - i - 1];
635              if (pbuf == '/')
636                {
637                   pname = &cmd[len - i];
638                   return strdup(pname);
639                }
640           }
641      }
642    return NULL;
643 }
644