keyrouter: support a event_surface event 14/152914/6
authorJengHyun Kang <jhyuni.kang@samsung.com>
Wed, 4 Apr 2018 07:51:41 +0000 (16:51 +0900)
committerJengHyun Kang <jhyuni.kang@samsung.com>
Thu, 12 Apr 2018 08:43:03 +0000 (17:43 +0900)
Change-Id: Iacf9f8090ae3d0e11744fa9cb87fc67b3a8559b9

src/bin/e_input_evdev.c
src/bin/e_keyrouter.h
src/bin/e_keyrouter_events.c
src/bin/e_keyrouter_wl.c

index 3b1f752..485d94f 100644 (file)
@@ -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);
 
index fe54f88..8c70428 100644 (file)
@@ -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);
index 208c59c..bd3af02 100644 (file)
@@ -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);
index 40cb6d0..0338081 100644 (file)
@@ -1,6 +1,28 @@
 #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;
+        if (wl_resource_get_version(res_data) < 2) 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)
 {
    struct wl_resource *res;
@@ -15,6 +37,11 @@ _e_keyrouter_wl_key_send(Ecore_Event_Key *ev, enum wl_keyboard_key_state state,
 
    comp_conf = e_comp_config_get();
 
+   if (surface && !focused)
+     {
+        _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 +595,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