From: JengHyun Kang Date: Mon, 5 Mar 2018 12:27:33 +0000 (+0900) Subject: e_keyrouter: send keys to specific surface X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Fsandbox%2Fjeon%2Fdevel;p=platform%2Fupstream%2Fenlightenment.git e_keyrouter: send keys to specific surface Change-Id: Ib36b4763a7a854dd7f55dd48f832f7133b22225d --- diff --git a/src/bin/e_input_evdev.c b/src/bin/e_input_evdev.c index 3b1f752fad..485d94fda6 100644 --- a/src/bin/e_input_evdev.c +++ b/src/bin/e_input_evdev.c @@ -349,6 +349,7 @@ _e_input_event_key_cb_free(void *data EINA_UNUSED, void *event) Ecore_Event_Key *ev = event; if (ev->dev) ecore_device_unref(ev->dev); + if (ev->data) E_FREE(ev->data); free(ev); } @@ -367,6 +368,7 @@ _device_handle_key(struct libinput_device *device, struct libinput_event_keyboar char key[256], keyname[256], compose_buffer[256]; Ecore_Event_Key *e; char *tmp = NULL, *compose = NULL; + E_Keyrouter_Event_Data *key_data; if (!(edev = libinput_device_get_user_data(device))) { @@ -450,6 +452,13 @@ _device_handle_key(struct libinput_device *device, struct libinput_event_keyboar E_FREE(tmp); return; } + key_data = E_NEW(E_Keyrouter_Event_Data, 1); + if (!key_data) + { + E_FREE(tmp); + E_FREE(e); + return; + } e->keyname = (char *)(e + 1); e->key = e->keyname + strlen(keyname) + 1; @@ -466,7 +475,7 @@ _device_handle_key(struct libinput_device *device, struct libinput_event_keyboar e->timestamp = timestamp; e->same_screen = 1; e->keycode = code; - e->data = NULL; + e->data = key_data; _device_modifiers_update(edev); diff --git a/src/bin/e_keyrouter.h b/src/bin/e_keyrouter.h index fe54f88199..8c70428cff 100644 --- a/src/bin/e_keyrouter.h +++ b/src/bin/e_keyrouter.h @@ -7,6 +7,7 @@ typedef struct _E_Keyrouter_Key_List_Node* E_Keyrouter_Key_List_NodePtr; typedef struct _E_Keyrouter_Tizen_HWKey E_Keyrouter_Tizen_HWKey; typedef struct _E_Keyrouter_Grabbed_Key E_Keyrouter_Grabbed_Key; typedef struct _E_Keyrouter_Registered_Window_Info E_Keyrouter_Registered_Window_Info; +typedef struct _E_Keyrouter_Event_Data E_Keyrouter_Event_Data; typedef enum _E_Keyrouter_Intercept_Hook_Point { @@ -82,6 +83,12 @@ struct _E_Keyrouter_Grabbed_Key Eina_List *pic_off_ptr; }; +struct _E_Keyrouter_Event_Data +{ + struct wl_client *client; + struct wl_resource *surface; +}; + E_API E_Keyrouter_Intercept_Hook *e_keyrouter_intercept_hook_add(E_Keyrouter_Intercept_Hook_Point hookpoint, E_Keyrouter_Intercept_Hook_Cb func, const void *data); E_API void e_keyrouter_intercept_hook_del(E_Keyrouter_Intercept_Hook *ch); E_API Eina_Bool e_keyrouter_intercept_hook_call(E_Keyrouter_Intercept_Hook_Point hookpoint, int type, Ecore_Event_Key *event); diff --git a/src/bin/e_keyrouter_events.c b/src/bin/e_keyrouter_events.c index 208c59cdc2..bd3af020d8 100644 --- a/src/bin/e_keyrouter_events.c +++ b/src/bin/e_keyrouter_events.c @@ -31,12 +31,6 @@ _e_keyrouter_is_key_grabbed(int key) static Eina_Bool _e_keyrouter_event_routed_key_check(Ecore_Event_Key *ev, int type) { - if (ev->data) - { - KLDBG("data is exist send to compositor: %p", ev->data); - return EINA_FALSE; - } - if (ev->modifiers != 0) { KLDBG("Modifier key delivered to Focus window : Key %s(%d)", ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode); @@ -60,17 +54,35 @@ e_keyrouter_event_process(void *event, int type) { Eina_Bool res = EINA_FALSE; Ecore_Event_Key *ev = event; + E_Keyrouter_Event_Data *key_data; KLDBG("[%s] keyname: %s, key: %s, keycode: %d", (type == ECORE_EVENT_KEY_DOWN) ? "KEY_PRESS" : "KEY_RELEASE", ev->keyname, ev->key, ev->keycode); e_screensaver_notidle(); + key_data = (E_Keyrouter_Event_Data *)ev->data; + + if (key_data->client || key_data->surface) + { + e_keyrouter_wl_key_send(ev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_FALSE); + return EINA_TRUE; + } + if (!_e_keyrouter_event_routed_key_check(event, type)) { - goto finish; + goto focus_deliver; } - if (!e_keyrouter_intercept_hook_call(E_KEYROUTER_INTERCEPT_HOOK_BEFORE_KEYROUTING, type, ev)) + res = e_keyrouter_intercept_hook_call(E_KEYROUTER_INTERCEPT_HOOK_BEFORE_KEYROUTING, type, ev); + if (res) + { + if (key_data->client || key_data->surface) + { + e_keyrouter_wl_key_send(ev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_FALSE); + goto finish; + } + } + else { goto finish; } @@ -78,7 +90,7 @@ e_keyrouter_event_process(void *event, int type) if ((ECORE_EVENT_KEY_UP == type) && (!krt->HardKeys[ev->keycode].press_ptr)) { KLDBG("The release key(%d) isn't a processed by keyrouter!", ev->keycode); - goto finish; + goto focus_deliver; } //KLDBG("The key(%d) is going to be sent to the proper wl client(s) !", ev->keycode); @@ -86,8 +98,9 @@ e_keyrouter_event_process(void *event, int type) res = _e_keyrouter_send_key_events(type, ev); if (res) return EINA_FALSE; -finish: +focus_deliver: res = e_comp_wl_key_process(event, type); +finish: return res; } @@ -134,18 +147,7 @@ _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev) } else { - if (key_node_data->focused == EINA_TRUE) - { - res = EINA_FALSE; - if (key_node_data->status == E_KRT_CSTAT_DEAD) - { - ev->data = key_node_data->wc; - } - else - { - ev->data = (void *)0x1; - } - } + if (key_node_data->focused == EINA_TRUE) res = EINA_FALSE; KLINF("Release Pair : %s(%s:%d)(Focus: %d)(Status: %d) => wl_surface (%p) wl_client (%p) process is ungrabbed / dead", ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode, key_node_data->focused, key_node_data->status, key_node_data->surface, key_node_data->wc); @@ -167,6 +169,7 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev) E_Client *ec_focus = NULL; struct wl_resource *delivered_surface = NULL; Eina_Bool res = EINA_TRUE; + int ret = 0; int pid = 0; char *pname = NULL, *cmd = NULL; @@ -293,32 +296,35 @@ need_shared: res = _e_keyrouter_send_key_events_focus(type, surface_focus, ev, &delivered_surface); if (delivered_surface) { - res = e_keyrouter_wl_add_surface_destroy_listener(delivered_surface); - if (res != TIZEN_KEYROUTER_ERROR_NONE) + ret = e_keyrouter_wl_add_surface_destroy_listener(delivered_surface); + if (ret != TIZEN_KEYROUTER_ERROR_NONE) { KLWRN("Failed to add wl_surface to destroy listener (res: %d)", res); } } - EINA_LIST_FOREACH(krt->HardKeys[keycode].shared_ptr, l, key_node_data) + if (res) { - if (key_node_data) + EINA_LIST_FOREACH(krt->HardKeys[keycode].shared_ptr, l, key_node_data) { - if (delivered_surface && key_node_data->surface == delivered_surface) - { - // Check for already delivered surface - // do not deliver double events in this case. - continue; - } - else + if (key_node_data) { - _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, key_node_data->focused, TIZEN_KEYROUTER_MODE_SHARED); - pid = e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface); - cmd = e_keyrouter_util_cmd_get_from_pid(pid); - pname = e_keyrouter_util_process_name_get_from_cmd(cmd); - KLINF("SHARED : %s(%s:%d) => wl_surface (%p) wl_client (%p) (pid: %d) (pname: %s)", - ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode, key_node_data->surface, key_node_data->wc, pid, pname ?: "Unknown"); - if(pname) E_FREE(pname); - if(cmd) E_FREE(cmd); + if (delivered_surface && key_node_data->surface == delivered_surface) + { + // Check for already delivered surface + // do not deliver double events in this case. + continue; + } + else + { + _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, key_node_data->focused, TIZEN_KEYROUTER_MODE_SHARED); + pid = e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface); + cmd = e_keyrouter_util_cmd_get_from_pid(pid); + pname = e_keyrouter_util_process_name_get_from_cmd(cmd); + KLINF("SHARED : %s(%s:%d) => wl_surface (%p) wl_client (%p) (pid: %d) (pname: %s)", + ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode, key_node_data->surface, key_node_data->wc, pid, pname ?: "Unknown"); + if(pname) E_FREE(pname); + if(cmd) E_FREE(cmd); + } } } } @@ -334,15 +340,22 @@ _e_keyrouter_send_key_events_focus(int type, struct wl_resource *surface_focus, Eina_Bool res = EINA_TRUE; int pid = 0; char *pname = NULL, *cmd = NULL; + E_Keyrouter_Event_Data *key_data; - if (!e_keyrouter_intercept_hook_call(E_KEYROUTER_INTERCEPT_HOOK_DELIVER_FOCUS, type, ev)) + res = e_keyrouter_intercept_hook_call(E_KEYROUTER_INTERCEPT_HOOK_DELIVER_FOCUS, type, ev); + key_data = (E_Keyrouter_Event_Data *)ev->data; + if (res) { - if (ev->data) + if (key_data->surface) { - *delivered_surface = ev->data; - ev->data = wl_resource_get_client(ev->data); + *delivered_surface = key_data->surface; + res = e_keyrouter_wl_key_send(ev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_TRUE); + return res; } - return res; + } + else + { + return EINA_FALSE; } pid = e_keyrouter_util_get_pid(NULL, surface_focus); diff --git a/src/bin/e_keyrouter_wl.c b/src/bin/e_keyrouter_wl.c index 40cb6d0b6e..945cce05b6 100644 --- a/src/bin/e_keyrouter_wl.c +++ b/src/bin/e_keyrouter_wl.c @@ -1,5 +1,26 @@ #include "e_keyrouter_private.h" +static void +_e_keyrouter_event_surface_send(struct wl_resource *surface, int key, int mode) +{ + Eina_List *l; + struct wl_resource *res_data; + struct wl_client *wc; + + EINA_SAFETY_ON_NULL_RETURN(krt); + EINA_SAFETY_ON_NULL_RETURN(surface); + + wc = wl_resource_get_client(surface); + EINA_SAFETY_ON_NULL_RETURN(wc); + + EINA_LIST_FOREACH(krt->resources, l, res_data) + { + if (wl_resource_get_client(res_data) != wc) continue; + + tizen_keyrouter_send_event_surface(res_data, surface, key, mode); + } +} + static void _e_keyrouter_wl_key_send(Ecore_Event_Key *ev, enum wl_keyboard_key_state state, Eina_List *key_list, Eina_Bool focused, struct wl_client *client, struct wl_resource *surface) { @@ -15,6 +36,8 @@ _e_keyrouter_wl_key_send(Ecore_Event_Key *ev, enum wl_keyboard_key_state state, comp_conf = e_comp_config_get(); + if (surface) _e_keyrouter_event_surface_send(surface, ev->keycode, TIZEN_KEYROUTER_MODE_NONE); + EINA_LIST_FOREACH(key_list, l, res) { wc = wl_resource_get_client(res); @@ -568,7 +591,7 @@ e_keyrouter_wl_init(void) EINA_SAFETY_ON_NULL_RETURN_VAL(krt, EINA_FALSE); - krt->global = wl_global_create(e_comp_wl->wl.disp, &tizen_keyrouter_interface, 1, krt, _e_keyrouter_cb_bind); + krt->global = wl_global_create(e_comp_wl->wl.disp, &tizen_keyrouter_interface, 2, krt, _e_keyrouter_cb_bind); EINA_SAFETY_ON_NULL_RETURN_VAL(krt->global, EINA_FALSE); #ifdef HAVE_CYNARA