1 #include "e_keyrouter_private.h"
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);
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);
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);
14 _e_keyrouter_is_key_grabbed(int key)
16 if (!krt->HardKeys[key].keycode)
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)
32 _e_keyrouter_event_routed_key_check(Ecore_Event_Key *ev, int type)
34 Eina_List *l, *l_next;
37 if ((ev->modifiers != 0) && (type == ECORE_EVENT_KEY_DOWN))
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);
43 *keycode_data = ev->keycode;
44 krt->ignore_list = eina_list_append(krt->ignore_list, keycode_data);
49 EINA_LIST_FOREACH_SAFE(krt->ignore_list, l, l_next, keycode_data)
51 if (*keycode_data == ev->keycode)
53 KLDBG("Find ignore key, propagate event (%d)\n", ev->keycode);
55 krt->ignore_list = eina_list_remove_list(krt->ignore_list, l);
61 if (krt->max_tizen_hwkeys < ev->keycode)
63 KLWRN("The key(%d) is too larger to process keyrouting: Invalid keycode", ev->keycode);
67 if (!krt->HardKeys[ev->keycode].keycode) return EINA_FALSE;
72 /* Function for checking the existing grab for a key and sending key event(s) */
74 e_keyrouter_event_process(void *event, int type)
76 Eina_Bool res = EINA_FALSE;
77 Ecore_Event_Key *ev = event;
78 E_Keyrouter_Event_Data *key_data;
80 KLDBG("[%s] keyname: %s, key: %s, keycode: %d", (type == ECORE_EVENT_KEY_DOWN) ? "KEY_PRESS" : "KEY_RELEASE", ev->keyname, ev->key, ev->keycode);
82 e_screensaver_notidle();
86 KLWRN("%s key (%d) %s is not handled by keyrouter\n", ev->keyname, ev->keycode, (type == ECORE_EVENT_KEY_DOWN) ? "press" : "release");
90 key_data = (E_Keyrouter_Event_Data *)ev->data;
92 if (key_data->client || key_data->surface)
94 e_keyrouter_wl_key_send(ev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_FALSE);
98 if (!_e_keyrouter_event_routed_key_check(event, type))
103 res = e_keyrouter_intercept_hook_call(E_KEYROUTER_INTERCEPT_HOOK_BEFORE_KEYROUTING, type, ev);
106 if (key_data->ignored) goto finish;
107 if (key_data->client || key_data->surface)
109 e_keyrouter_wl_key_send(ev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_FALSE);
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);
124 res = e_comp_wl_key_process(event, type);
129 /* Function for sending key events to wl_client(s) */
131 _e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev)
133 if (ECORE_EVENT_KEY_DOWN == type)
135 _e_keyrouter_send_key_events_press(type, ev);
139 _e_keyrouter_send_key_events_release(type, ev);
144 _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev)
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;
152 /* Deliver release clean up pressed key list */
153 EINA_LIST_FREE(krt->HardKeys[ev->keycode].press_ptr, key_node_data)
155 if (key_node_data->focused == EINA_TRUE)
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;
162 if (key_data->ignored)
164 E_FREE(key_node_data);
167 if (key_data->surface || key_data->client)
169 _e_keyrouter_send_key_event(type, key_data->surface, key_data->client, ev,
170 key_node_data->focused, TIZEN_KEYROUTER_MODE_PRESSED);
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);
181 E_FREE(key_node_data);
189 E_FREE(key_node_data);
193 if (key_node_data->status == E_KRT_CSTAT_ALIVE)
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);
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);
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);
214 E_FREE(key_node_data);
216 krt->HardKeys[ev->keycode].press_ptr = NULL;
220 _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev)
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;
229 char *pname = NULL, *cmd = NULL;
231 E_Keyrouter_Key_List_NodePtr key_node_data;
234 ec_focus = e_client_focused_get();
235 surface_focus = e_keyrouter_util_get_surface_from_eclient(ec_focus);
237 if (krt->isPictureOffEnabled == 1)
239 EINA_LIST_FOREACH(krt->HardKeys[keycode].pic_off_ptr, l, key_node_data)
243 _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, key_node_data->focused, TIZEN_KEYROUTER_MODE_SHARED);
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);
256 if (!_e_keyrouter_is_key_grabbed(ev->keycode))
258 _e_keyrouter_send_key_events_focus(type, surface_focus, ev, &delivered_surface);
262 EINA_LIST_FOREACH(krt->HardKeys[keycode].excl_ptr, l, key_node_data)
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);
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);
281 EINA_LIST_FOREACH(krt->HardKeys[keycode].or_excl_ptr, l, key_node_data)
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);
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);
301 // Top position grab must need a focus surface.
304 EINA_LIST_FOREACH(krt->HardKeys[keycode].top_ptr, l, key_node_data)
308 if ((EINA_FALSE == krt->isWindowStackChanged) && (surface_focus == key_node_data->surface))
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);
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");
320 if(pname) E_FREE(pname);
324 krt->isWindowStackChanged = EINA_FALSE;
326 if (_e_keyrouter_check_top_visible_window(ec_focus, keycode))
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);
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");
339 if(pname) E_FREE(pname);
349 if (krt->HardKeys[keycode].shared_ptr)
352 res = _e_keyrouter_send_key_events_focus(type, surface_focus, ev, &delivered_surface);
353 if (delivered_surface)
355 ret = e_keyrouter_wl_add_surface_destroy_listener(delivered_surface);
356 if (ret != TIZEN_KEYROUTER_ERROR_NONE)
358 KLWRN("Failed to add wl_surface to destroy listener (res: %d)", res);
363 EINA_LIST_FOREACH(krt->HardKeys[keycode].shared_ptr, l, key_node_data)
367 if (delivered_surface && key_node_data->surface == delivered_surface)
369 // Check for already delivered surface
370 // do not deliver double events in this case.
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);
391 _e_keyrouter_send_key_events_focus(int type, struct wl_resource *surface_focus, Ecore_Event_Key *ev, struct wl_resource **delivered_surface)
393 Eina_Bool res = EINA_TRUE;
395 char *pname = NULL, *cmd = NULL;
396 E_Keyrouter_Event_Data *key_data;
398 res = e_keyrouter_intercept_hook_call(E_KEYROUTER_INTERCEPT_HOOK_DELIVER_FOCUS, type, ev);
399 key_data = (E_Keyrouter_Event_Data *)ev->data;
402 if (key_data->ignored)
404 e_keyrouter_prepend_to_keylist(NULL, NULL, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, EINA_TRUE);
407 else if (key_data->surface)
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);
416 e_keyrouter_prepend_to_keylist(NULL, NULL, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, EINA_TRUE);
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);
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);
434 _e_keyrouter_check_top_visible_window(E_Client *ec_focus, int arr_idx)
436 E_Client *ec_top = NULL;
437 Eina_List *l = NULL, *l_next = NULL;
438 E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
440 ec_top = e_client_top_get();
444 if (!ec_top->visible && ec_top == ec_focus)
446 KLDBG("Top e_client (%p) is invisible(%d) but focus client", ec_top, ec_top->visible);
449 if (!ec_top->visible)
451 ec_top = e_client_below_get(ec_top);
455 /* TODO: Check this client is located inside a display boundary */
457 EINA_LIST_FOREACH_SAFE(krt->HardKeys[arr_idx].top_ptr, l, l_next, key_node_data)
461 if (ec_top == wl_resource_get_user_data(key_node_data->surface))
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);
471 if (ec_top == ec_focus)
473 KLDBG("The e_client(%p) is a focus client", ec_top);
477 ec_top = e_client_below_get(ec_top);
482 /* Function for sending key event to wl_client(s) */
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)
486 struct wl_client *wc_send;
487 Eina_Bool pressed = EINA_FALSE;
489 if (surface == NULL) wc_send = wc;
490 else wc_send = wl_resource_get_client(surface);
494 KLWRN("wl_surface: %p or wl_client: %p returns null wayland client", surface, wc);
498 if (ECORE_EVENT_KEY_DOWN == type)
501 e_keyrouter_prepend_to_keylist(surface, wc, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, focused);
504 e_keyrouter_wl_key_send(ev, pressed, wc_send, surface, focused);
510 e_keyrouter_util_get_surface_from_eclient(E_Client *client)
512 if (!client || !client->comp_data) return NULL;
514 return client->comp_data->wl_surface;
518 e_keyrouter_util_get_pid(struct wl_client *client, struct wl_resource *surface)
523 struct wl_client *cur_client = NULL;
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);
529 wl_client_get_credentials(cur_client, &pid, &uid, &gid);
535 e_keyrouter_util_cmd_get_from_pid(int pid)
538 E_Comp_Connected_Client_Info *cdata;
540 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, NULL);
542 EINA_LIST_FOREACH(e_comp->connected_clients, l, cdata)
544 if (cdata->pid == pid) return strdup(cdata->name);
550 typedef struct _keycode_map{
552 xkb_keycode_t keycode;
556 find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
558 keycode_map *found_keycodes = (keycode_map *)data;
559 xkb_keysym_t keysym = found_keycodes->keysym;
561 const xkb_keysym_t *syms_out = NULL;
563 nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
564 if (nsyms && syms_out)
566 if (*syms_out == keysym)
568 found_keycodes->keycode = key;
574 _e_keyrouter_keycode_get_from_keysym(struct xkb_keymap *keymap, xkb_keysym_t keysym)
576 keycode_map found_keycodes = {0,};
577 found_keycodes.keysym = keysym;
578 xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes);
580 return found_keycodes.keycode;
584 e_keyrouter_util_keycode_get_from_string(char * name)
586 struct xkb_keymap *keymap = NULL;
587 xkb_keysym_t keysym = 0x0;
590 keymap = e_comp_wl->xkb.keymap;
591 EINA_SAFETY_ON_NULL_GOTO(keymap, finish);
593 keysym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
594 EINA_SAFETY_ON_FALSE_GOTO(keysym != XKB_KEY_NoSymbol, finish);
596 keycode = _e_keyrouter_keycode_get_from_keysym(keymap, keysym);
598 KLDBG("request name: %s, return value: %d", name, keycode);
607 e_keyrouter_util_keyname_get_from_keycode(int keycode)
609 struct xkb_state *state;
610 xkb_keysym_t sym = XKB_KEY_NoSymbol;
611 char name[256] = {0, };
613 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, NULL);
614 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl->xkb.state, NULL);
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));
624 e_keyrouter_util_process_name_get_from_cmd(char *cmd)
632 for (i = 0; i < len; i++)
634 pbuf = cmd[len - i - 1];
637 pname = &cmd[len - i];
638 return strdup(pname);