Manage keygrab list by wl_surface from E_Client 07/47907/3
authorJengHyun Kang <jhyuni.kang@samsung.com>
Thu, 10 Sep 2015 01:59:45 +0000 (10:59 +0900)
committerJengHyun Kang <jhyuni.kang@samsung.com>
Tue, 15 Sep 2015 11:00:16 +0000 (20:00 +0900)
  - Allow keygrab requests with no E_Client
  - If a client request keygrab before mapped, there is no E_Client.

Change-Id: I0727a9c5d620d7f6e7fa463fba773fdf40b9175f

src/e_mod_keyrouter_list.c
src/e_mod_main_wl.c
src/e_mod_main_wl.h

index 7fca604..38fc29c 100644 (file)
@@ -3,15 +3,13 @@
 #include "e_mod_main_wl.h"
 #include <string.h>
 
-static int _e_keyrouter_find_duplicated_client(E_Client *ec, struct wl_client *wc, uint32_t key, uint32_t mode);
+static int _e_keyrouter_find_duplicated_client(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode);
 static const char *_mode_str_get(uint32_t mode);
 
 /* add a new key grab info to the list */
 int
 e_keyrouter_set_keygrab_in_list(struct wl_resource *surface, struct wl_client *client, uint32_t key, uint32_t mode)
 {
-   E_Pixmap *cp = NULL;
-   E_Client *ec = NULL;
    int res = TIZEN_KEYROUTER_ERROR_NONE;
 
    EINA_SAFETY_ON_FALSE_RETURN_VAL
@@ -28,38 +26,27 @@ e_keyrouter_set_keygrab_in_list(struct wl_resource *surface, struct wl_client *c
            TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY);
      }
 
-   if (surface)
-     {
-        cp = wl_resource_get_user_data(surface);
-        EINA_SAFETY_ON_NULL_RETURN_VAL
-          (cp, TIZEN_KEYROUTER_ERROR_INVALID_SURFACE);
-
-        ec = e_pixmap_client_get(cp);
-        EINA_SAFETY_ON_NULL_RETURN_VAL
-          (cp, TIZEN_KEYROUTER_ERROR_INVALID_SURFACE);
-     }
-
    if (mode == TIZEN_KEYROUTER_MODE_TOPMOST)
      {
         EINA_SAFETY_ON_NULL_RETURN_VAL
-          (ec, TIZEN_KEYROUTER_ERROR_INVALID_SURFACE);
+          (surface, TIZEN_KEYROUTER_ERROR_INVALID_SURFACE);
      }
 
-   res = e_keyrouter_prepend_to_keylist(ec,
-                                        ec ? NULL : client,
+   res = e_keyrouter_prepend_to_keylist(surface,
+                                        surface ? NULL : client,
                                         key,
                                         mode);
    EINA_SAFETY_ON_FALSE_RETURN_VAL(res == TIZEN_KEYROUTER_ERROR_NONE, res);
 
-   KLDBG("Succeed to set keygrab info ec:%p key:%d mode:%s\n",
-         ec, key, _mode_str_get(mode));
+   KLDBG("Succeed to set keygrab info surface: %p, client: %p key: %d mode: %s\n",
+         surface, client, key, _mode_str_get(mode));
 
    return res;
 }
 
 /* Function for checking whether the key has been grabbed already by the same wl_surface or not */
 static int
-_e_keyrouter_find_duplicated_client(E_Client *ec, struct wl_client *wc, uint32_t key, uint32_t mode)
+_e_keyrouter_find_duplicated_client(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode)
 {
    Eina_List *keylist_ptr = NULL, *l = NULL;
    E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
@@ -94,12 +81,12 @@ _e_keyrouter_find_duplicated_client(E_Client *ec, struct wl_client *wc, uint32_t
      {
         if (!key_node_data) continue;
 
-        if (ec)
+        if (surface)
           {
-             if (key_node_data->ec == ec)
+             if (key_node_data->surface == surface)
                {
-                  KLDBG("The key(%d) is already grabbed same mode(%d) on the same ec %p\n",
-                        key, mode, ec);
+                  KLDBG("The key(%d) is already grabbed same mode(%d) on the same surface %p\n",
+                        key, mode, surface);
                   return TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY;
                }
           }
@@ -119,11 +106,11 @@ _e_keyrouter_find_duplicated_client(E_Client *ec, struct wl_client *wc, uint32_t
 
 /* Function for prepending a new key grab information in the keyrouting list */
 int
-e_keyrouter_prepend_to_keylist(E_Client *ec, struct wl_client *wc, uint32_t key, uint32_t mode)
+e_keyrouter_prepend_to_keylist(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode)
 {
    int res = TIZEN_KEYROUTER_ERROR_NONE;
 
-   res = _e_keyrouter_find_duplicated_client(ec, wc, key, mode);
+   res = _e_keyrouter_find_duplicated_client(surface, wc, key, mode);
    CHECK_ERR_VAL(res);
 
    E_Keyrouter_Key_List_NodePtr new_keyptr = E_NEW(E_Keyrouter_Key_List_Node, 1);
@@ -134,16 +121,16 @@ e_keyrouter_prepend_to_keylist(E_Client *ec, struct wl_client *wc, uint32_t key,
         return TIZEN_KEYROUTER_ERROR_NO_SYSTEM_RESOURCES;
      }
 
-   new_keyptr->ec = ec;
+   new_keyptr->surface = surface;
    new_keyptr->wc = wc;
 
-   if (ec)
+   if (surface)
      {
-        KLDBG("Now it's going to add a key(%d) mode(%d) for ec(%p), wc(NULL)\n", key, mode, ec);
+        KLDBG("Now it's going to add a key(%d) mode(%d) for surface(%p), wc(NULL)\n", key, mode, surface);
      }
    else
      {
-        KLDBG("Now it's going to add a key(%d) mode(%d) for ec(NULL), wc(%p)\n", key, mode, wc);
+        KLDBG("Now it's going to add a key(%d) mode(%d) for surface(NULL), wc(%p)\n", key, mode, wc);
      }
 
    switch(mode)
@@ -151,65 +138,65 @@ e_keyrouter_prepend_to_keylist(E_Client *ec, struct wl_client *wc, uint32_t key,
       case TIZEN_KEYROUTER_MODE_EXCLUSIVE:
          krt->HardKeys[key].excl_ptr = eina_list_prepend(krt->HardKeys[key].excl_ptr, new_keyptr);
 
-         if (ec)
+         if (surface)
            {
-              KLDBG("Succeed to set keygrab information (e_client:%p, wl_client:NULL, key:%d, mode:EXCLUSIVE)\n", ec, key);
+              KLDBG("Succeed to set keygrab information (surface:%p, wl_client:NULL, key:%d, mode:EXCLUSIVE)\n", surface, key);
            }
          else
            {
-              KLDBG("Succeed to set keygrab information (e_client:NULL, wl_client:%p, key:%d, mode:EXCLUSIVE)\n", wc, key);
+              KLDBG("Succeed to set keygrab information (surface:NULL, wl_client:%p, key:%d, mode:EXCLUSIVE)\n", wc, key);
            }
          break;
 
       case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE:
          krt->HardKeys[key].or_excl_ptr= eina_list_prepend(krt->HardKeys[key].or_excl_ptr, new_keyptr);
 
-         if (ec)
+         if (surface)
            {
-              KLDBG("TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE, key=%d, e_client(%p), wl_client(NULL) has been set !\n", key, ec);
+              KLDBG("TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE, key=%d, surface(%p), wl_client(NULL) has been set !\n", key, surface);
            }
          else
            {
-              KLDBG("TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE, key=%d, e_client(NULL), wl_client(%p) has been set !\n", key, wc);
+              KLDBG("TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE, key=%d, surface(NULL), wl_client(%p) has been set !\n", key, wc);
            }
          break;
 
       case TIZEN_KEYROUTER_MODE_TOPMOST:
          krt->HardKeys[key].top_ptr = eina_list_prepend(krt->HardKeys[key].top_ptr, new_keyptr);
 
-         if (ec)
+         if (surface)
            {
-              KLDBG("TIZEN_KEYROUTER_MODE_TOPMOST, key=%d, e_client(%p), wl_client(NULL) has been set !\n", key, ec);
+              KLDBG("TIZEN_KEYROUTER_MODE_TOPMOST, key=%d, surface(%p), wl_client(NULL) has been set !\n", key, surface);
            }
          else
            {
-              KLDBG("TIZEN_KEYROUTER_MODE_TOPMOST, key=%d, e_client(NULL), wl_client(%p) has been set !\n", key, wc);
+              KLDBG("TIZEN_KEYROUTER_MODE_TOPMOST, key=%d, surface(NULL), wl_client(%p) has been set !\n", key, wc);
            }
          break;
 
       case TIZEN_KEYROUTER_MODE_SHARED:
          krt->HardKeys[key].shared_ptr= eina_list_prepend(krt->HardKeys[key].shared_ptr, new_keyptr);
 
-         if (ec)
+         if (surface)
            {
-              KLDBG("TIZEN_KEYROUTER_MODE_SHARED, key=%d, e_client(%p), wl_client(NULL) has been set !\n", key, ec);
+              KLDBG("TIZEN_KEYROUTER_MODE_SHARED, key=%d, surface(%p), wl_client(NULL) has been set !\n", key, surface);
            }
          else
            {
-              KLDBG("TIZEN_KEYROUTER_MODE_SHARED, key=%d, e_client(NULL), wl_client(%p) has been set !\n", key, wc);
+              KLDBG("TIZEN_KEYROUTER_MODE_SHARED, key=%d, surface(NULL), wl_client(%p) has been set !\n", key, wc);
            }
          break;
 
       case TIZEN_KEYROUTER_MODE_PRESSED:
          krt->HardKeys[key].press_ptr = eina_list_prepend(krt->HardKeys[key].press_ptr, new_keyptr);
 
-         if (ec)
+         if (surface)
            {
-              KLDBG("TIZEN_KEYROUTER_MODE_PRESSED, key=%d, e_client(%p), wl_client(NULL) has been set !\n", key, ec);
+              KLDBG("TIZEN_KEYROUTER_MODE_PRESSED, key=%d, surface(%p), wl_client(NULL) has been set !\n", key, surface);
            }
          else
            {
-              KLDBG("TIZEN_KEYROUTER_MODE_PRESSED, key=%d, e_client(NULL), wl_client(%p) has been set !\n", key, wc);
+              KLDBG("TIZEN_KEYROUTER_MODE_PRESSED, key=%d, surface(NULL), wl_client(%p) has been set !\n", key, wc);
            }
          break;
 
@@ -219,11 +206,20 @@ e_keyrouter_prepend_to_keylist(E_Client *ec, struct wl_client *wc, uint32_t key,
          return TIZEN_KEYROUTER_ERROR_INVALID_MODE;
      }
 
-   if (wc)
+   if (TIZEN_KEYROUTER_MODE_PRESSED != mode)
      {
-        KLDBG("Add a client(%p) destory listener\n", wc);
-        e_keyrouter_add_client_destroy_listener(wc);
-        /* TODO: if failed add client_destory_listener, remove keygrabs */
+        if (surface)
+          {
+             KLDBG("Add a surface(%p) destory listener\n", surface);
+             e_keyrouter_add_surface_destroy_listener(surface);
+             /* TODO: if failed add surface_destory_listener, remove keygrabs */
+          }
+        else if (wc)
+          {
+             KLDBG("Add a client(%p) destory listener\n", wc);
+             e_keyrouter_add_client_destroy_listener(wc);
+             /* TODO: if failed add client_destory_listener, remove keygrabs */
+          }
      }
 
    return TIZEN_KEYROUTER_ERROR_NONE;
@@ -231,12 +227,11 @@ e_keyrouter_prepend_to_keylist(E_Client *ec, struct wl_client *wc, uint32_t key,
 
 /* remove key grab info from the list */
 void
-e_keyrouter_find_and_remove_client_from_list(E_Client *ec, struct wl_client *wc, uint32_t key, uint32_t mode)
+e_keyrouter_find_and_remove_client_from_list(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode)
 {
    Eina_List **list = NULL;
    Eina_List *l = NULL, *l_next = NULL;
    E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
-   Eina_Bool removed;
 
    switch (mode)
      {
@@ -253,50 +248,36 @@ e_keyrouter_find_and_remove_client_from_list(E_Client *ec, struct wl_client *wc,
      {
         if (!key_node_data) continue;
 
-        removed = EINA_FALSE;
-
-        if (ec)
-          {
-             if (ec == key_node_data->ec)
-               {
-                  *list = eina_list_remove_list(*list, l);
-                  E_FREE(key_node_data);
-                  removed = EINA_TRUE;
-               }
-          }
-        else
+        if ((surface) && (surface == key_node_data->surface))
           {
-             if (wc == key_node_data->wc)
-               {
-                  *list = eina_list_remove_list(*list, l);
-                  E_FREE(key_node_data);
-                  removed = EINA_TRUE;
-               }
+             *list = eina_list_remove_list(*list, l);
+             E_FREE(key_node_data);
+             KLDBG("Remove a %s Mode Grabbed key(%d) by surface(%p)\n", _mode_str_get(mode), key, surface);
           }
-
-        if (removed)
+        else if ((wc) && (wc == key_node_data->wc))
           {
-             KLDBG("Remove a %s Mode Grabbed key(%d) by ec(%p) wc(NULL)\n",
-                   _mode_str_get(mode), key, ec);
+             *list = eina_list_remove_list(*list, l);
+             E_FREE(key_node_data);
+             KLDBG("Remove a %s Mode Grabbed key(%d) by wc(%p)\n", _mode_str_get(mode), key, wc);
           }
      }
 }
 
 void
-e_keyrouter_remove_client_from_list(E_Client *ec, struct wl_client *wc)
+e_keyrouter_remove_client_from_list(struct wl_resource *surface, struct wl_client *wc)
 {
    int i = 0;
 
-   EINA_SAFETY_ON_TRUE_RETURN(((!ec) && (!wc)));
+   EINA_SAFETY_ON_TRUE_RETURN(((!surface) && (!wc)));
 
    for (i = 0; i < MAX_HWKEYS; i++)
      {
         if (0 == krt->HardKeys[i].keycode) continue;
 
-        e_keyrouter_find_and_remove_client_from_list(ec, wc, i, TIZEN_KEYROUTER_MODE_EXCLUSIVE);
-        e_keyrouter_find_and_remove_client_from_list(ec, wc, i, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
-        e_keyrouter_find_and_remove_client_from_list(ec, wc, i, TIZEN_KEYROUTER_MODE_TOPMOST);
-        e_keyrouter_find_and_remove_client_from_list(ec, wc, i, TIZEN_KEYROUTER_MODE_SHARED);
+        e_keyrouter_find_and_remove_client_from_list(surface, wc, i, TIZEN_KEYROUTER_MODE_EXCLUSIVE);
+        e_keyrouter_find_and_remove_client_from_list(surface, wc, i, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
+        e_keyrouter_find_and_remove_client_from_list(surface, wc, i, TIZEN_KEYROUTER_MODE_TOPMOST);
+        e_keyrouter_find_and_remove_client_from_list(surface, wc, i, TIZEN_KEYROUTER_MODE_SHARED);
      }
 }
 
index 67b414e..03967fb 100644 (file)
@@ -13,16 +13,17 @@ static Eina_Bool _e_keyrouter_process_key_event(void *event, int type);
 static Eina_Bool _e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev);
 static Eina_Bool _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev);
 static Eina_Bool _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev);
-static void _e_keyrouter_send_key_event(int type, E_Client *ec, struct wl_client *wc, Ecore_Event_Key *ev);
+static void _e_keyrouter_send_key_event(int type, struct wl_resource *surface, struct wl_client *wc, Ecore_Event_Key *ev);
 static Eina_Bool _e_keyrouter_is_key_grabbed(int key);
 static Eina_Bool _e_keyrouter_check_top_visible_window(E_Comp *c, E_Client *ec_focus, int arr_idx);
 static void _e_keyrouter_query_tizen_key_table(void);
 static int _e_keyrouter_wl_array_length(const struct wl_array *array);
-
+static struct wl_resource *_e_keyrouter_util_get_surface_from_eclient(E_Client *client);
 
 static Eina_Bool _e_keyrouter_client_cb_stack(void *data, int type, void *event);
 static Eina_Bool _e_keyrouter_client_cb_remove(void *data, int type, void *event);
 static void _e_keyrouter_wl_client_cb_destroy(struct wl_listener *l, void *data);
+static void _e_keyrouter_wl_surface_cb_destroy(struct wl_listener *l, void *data);
 
 static int _e_keyrouter_keygrab_set(struct wl_client *client, struct wl_resource *surface, uint32_t key, uint32_t mode);
 static int _e_keyrouter_keygrab_unset(struct wl_client *client, struct wl_resource *surface, uint32_t key);
@@ -81,9 +82,6 @@ _e_keyrouter_keygrab_set(struct wl_client *client, struct wl_resource *surface,
 static int
 _e_keyrouter_keygrab_unset(struct wl_client *client, struct wl_resource *surface, uint32_t key)
 {
-   E_Pixmap *ep = NULL;
-   E_Client *ec = NULL;
-
    if (!surface)
      {
         /* EXCLUSIVE grab */
@@ -101,29 +99,17 @@ _e_keyrouter_keygrab_unset(struct wl_client *client, struct wl_resource *surface
         return TIZEN_KEYROUTER_ERROR_NONE;
      }
 
-    if (!surface || !(ep = wl_resource_get_user_data(surface)))
-     {
-        KLDBG("Surface or E_Pixman from the surface is invalid ! Return error !\n");
-        return TIZEN_KEYROUTER_ERROR_INVALID_SURFACE;
-     }
-
-   if (!(ec = e_pixmap_client_get(ep)))
-     {
-        KLDBG("E_Client pointer from E_Pixman from surface is invalid ! Return error !\n");
-        return TIZEN_KEYROUTER_ERROR_INVALID_SURFACE;
-     }
-
    /* EXCLUSIVE grab */
-   e_keyrouter_find_and_remove_client_from_list(ec, NULL, key, TIZEN_KEYROUTER_MODE_EXCLUSIVE);
+   e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_EXCLUSIVE);
 
    /* OVERRIDABLE_EXCLUSIVE grab */
-   e_keyrouter_find_and_remove_client_from_list(ec, NULL, key, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
+   e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
 
    /* TOPMOST(TOP_POSITION) grab */
-   e_keyrouter_find_and_remove_client_from_list(ec, NULL, key, TIZEN_KEYROUTER_MODE_TOPMOST);
+   e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_TOPMOST);
 
    /* SHARED grab */
-   e_keyrouter_find_and_remove_client_from_list(ec, NULL, key, TIZEN_KEYROUTER_MODE_SHARED);
+   e_keyrouter_find_and_remove_client_from_list(surface, client, key, TIZEN_KEYROUTER_MODE_SHARED);
 
    return TIZEN_KEYROUTER_ERROR_NONE;
 }
@@ -292,6 +278,44 @@ e_keyrouter_add_client_destroy_listener(struct wl_client *client)
    return TIZEN_KEYROUTER_ERROR_NONE;
 }
 
+/* Function for registering wl_surface destroy listener */
+int
+e_keyrouter_add_surface_destroy_listener(struct wl_resource *surface)
+{
+   struct wl_listener *destroy_listener = NULL;
+   Eina_List *l;
+   struct wl_resource *surface_data;
+
+   EINA_LIST_FOREACH(krt->surface_grab_client, l, surface_data)
+     {
+        if (surface_data)
+          {
+             if (surface_data == surface)
+               {
+                  KLDBG("surface(%p)'s destroy listener is already added, wc_data(%p)\n", surface, surface_data);
+                  return TIZEN_KEYROUTER_ERROR_NONE;
+               }
+          }
+     }
+
+   destroy_listener = E_NEW(struct wl_listener, 1);
+
+   if (!destroy_listener)
+     {
+        KLDBG("Failed to allocate memory for wl_surface destroy listener !\n");
+        return TIZEN_KEYROUTER_ERROR_NO_SYSTEM_RESOURCES;
+     }
+
+   destroy_listener->notify = _e_keyrouter_wl_surface_cb_destroy;
+   wl_resource_add_destroy_listener(surface, destroy_listener);
+   krt->surface_grab_client = eina_list_append(krt->surface_grab_client, surface);
+
+   KLDBG("Add a surface(%p) destroy listener(%p)\n", surface, destroy_listener);
+
+   return TIZEN_KEYROUTER_ERROR_NONE;
+}
+
+
 static const struct tizen_keyrouter_interface _e_keyrouter_implementation = {
    _e_keyrouter_cb_keygrab_set,
    _e_keyrouter_cb_keygrab_unset,
@@ -414,9 +438,9 @@ _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev)
      {
         if (key_node_data)
           {
-             _e_keyrouter_send_key_event(type, key_node_data->ec, key_node_data->wc, ev);
+             _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev);
              KLDBG("Release Pair : Key %s(%d) ===> E_Client (%p) WL_Client (%p)\n",
-                      ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode, key_node_data->ec, key_node_data->wc);
+                      ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode, key_node_data->surface, key_node_data->wc);
              E_FREE(key_node_data);
           }
      }
@@ -429,6 +453,7 @@ static Eina_Bool
 _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev)
 {
    unsigned int keycode = ev->keycode;
+   struct wl_resource *surface_focus = NULL;
    E_Client *ec_focus = NULL;
    E_Comp *c = NULL;
 
@@ -439,9 +464,9 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev)
      {
         if (key_node_data)
           {
-             _e_keyrouter_send_key_event(type, key_node_data->ec, key_node_data->wc, ev);
-             KLDBG("EXCLUSIVE Mode : Key %s(%d) ===> E_Client (%p) WL_Client (%p)\n",
-                      ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode, key_node_data->ec, key_node_data->wc);
+             _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev);
+             KLDBG("EXCLUSIVE Mode : Key %s(%d) ===> Surface (%p) WL_Client (%p)\n",
+                      ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode, key_node_data->surface, key_node_data->wc);
 
              return EINA_TRUE;
           }
@@ -451,25 +476,26 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev)
      {
         if (key_node_data)
           {
-             _e_keyrouter_send_key_event(type, key_node_data->ec, key_node_data->wc, ev);
-             KLDBG("OVERRIDABLE_EXCLUSIVE Mode : Key %s(%d) ===> E_Client (%p) WL_Client (%p)\n",
-                     ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode, key_node_data->ec, key_node_data->wc);
+             _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev);
+             KLDBG("OVERRIDABLE_EXCLUSIVE Mode : Key %s(%d) ===> Surface (%p) WL_Client (%p)\n",
+                     ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode, key_node_data->surface, key_node_data->wc);
 
              return EINA_TRUE;
           }
      }
 
    ec_focus = e_client_focused_get();
+   surface_focus = _e_keyrouter_util_get_surface_from_eclient(ec_focus);
 
    EINA_LIST_FOREACH(krt->HardKeys[keycode].top_ptr, l, key_node_data)
      {
         if (key_node_data)
           {
-             if ((EINA_FALSE == krt->isWindowStackChanged) && (ec_focus == key_node_data->ec))
+             if ((EINA_FALSE == krt->isWindowStackChanged) && (surface_focus == key_node_data->surface))
                {
-                  _e_keyrouter_send_key_event(type, key_node_data->ec, NULL, ev);
-                  KLDBG("TOPMOST (TOP_POSITION) Mode : Key %s (%d) ===> Client (%p)\n",
-                           ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode, key_node_data->ec);
+                  _e_keyrouter_send_key_event(type, key_node_data->surface, NULL, ev);
+                  KLDBG("TOPMOST (TOP_POSITION) Mode : Key %s (%d) ===> Surface (%p)\n",
+                           ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode, key_node_data->surface);
 
                   return EINA_TRUE;
                }
@@ -478,9 +504,9 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev)
              c = e_comp_find_by_window(ev->window);
              if (_e_keyrouter_check_top_visible_window(c, ec_focus, keycode))
                {
-                  _e_keyrouter_send_key_event(type, key_node_data->ec, NULL, ev);
-                  KLDBG("TOPMOST (TOP_POSITION) Mode : Key %s (%d) ===> Client (%p)\n",
-                        ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode,key_node_data->ec);
+                  _e_keyrouter_send_key_event(type, key_node_data->surface, NULL, ev);
+                  KLDBG("TOPMOST (TOP_POSITION) Mode : Key %s (%d) ===> Surface (%p)\n",
+                        ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode,key_node_data->surface);
 
                   return EINA_TRUE;
                }
@@ -490,30 +516,30 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev)
 
    if (krt->HardKeys[keycode].shared_ptr)
      {
-        _e_keyrouter_send_key_event(type, ec_focus, NULL, ev);
-        KLDBG("SHARED [Focus client] : Key %s (%d) ===> Client (%p)\n",
-                 ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up "), ev->keycode, ec_focus);
+        _e_keyrouter_send_key_event(type, surface_focus, NULL, ev);
+        KLDBG("SHARED [Focus client] : Key %s (%d) ===> Surface (%p)\n",
+                 ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up "), ev->keycode, surface_focus);
 
         EINA_LIST_FOREACH(krt->HardKeys[keycode].shared_ptr, l, key_node_data)
           {
              if (key_node_data)
                {
-                  if (key_node_data->ec)
+                  if (key_node_data->surface)
                     {
-                       if (key_node_data->ec != ec_focus)
+                       if (key_node_data->surface != surface_focus)
                          {
-                            _e_keyrouter_send_key_event(type, key_node_data->ec, key_node_data->wc, ev);
-                            KLDBG("SHARED Mode : Key %s(%d) ===> E_Client (%p) WL_Client (%p)\n",
-                                     ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode, key_node_data->ec, key_node_data->wc);
+                            _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev);
+                            KLDBG("SHARED Mode : Key %s(%d) ===> Surface (%p) WL_Client (%p)\n",
+                                     ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode, key_node_data->surface, key_node_data->wc);
                          }
                     }
                   else
                     {
-                       if (key_node_data->wc != wl_resource_get_client(ec_focus->comp_data->wl_surface))
+                       if (key_node_data->wc != wl_resource_get_client(surface_focus))
                          {
-                            _e_keyrouter_send_key_event(type, key_node_data->ec, key_node_data->wc, ev);
-                            KLDBG("SHARED Mode : Key %s(%d) ===> E_Client (%p) WL_Client (%p)\n",
-                                     ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode, key_node_data->ec, key_node_data->wc);
+                            _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev);
+                            KLDBG("SHARED Mode : Key %s(%d) ===> Surface (%p) WL_Client (%p)\n",
+                                     ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode, key_node_data->surface, key_node_data->wc);
                          }
                     }
                }
@@ -549,7 +575,7 @@ _e_keyrouter_check_top_visible_window(E_Comp *c, E_Client *ec_focus, int arr_idx
           {
              if (key_node_data)
                {
-                  if (ec_top == key_node_data->ec)
+                  if (ec_top == e_pixmap_client_get(wl_resource_get_user_data(key_node_data->surface)))
                     {
                        krt->HardKeys[arr_idx].top_ptr = eina_list_promote_list(krt->HardKeys[arr_idx].top_ptr, l);
                        KLDBG("Move a client(%p) to first index of list(key: %d)\n",
@@ -573,7 +599,7 @@ _e_keyrouter_check_top_visible_window(E_Comp *c, E_Client *ec_focus, int arr_idx
 
 /* Function for sending key event to wl_client(s) */
 static void
-_e_keyrouter_send_key_event(int type, E_Client *ec, struct wl_client *wc, Ecore_Event_Key *ev)
+_e_keyrouter_send_key_event(int type, struct wl_resource *surface, struct wl_client *wc, Ecore_Event_Key *ev)
 {
    struct wl_client *wc_send;
    struct wl_resource *res;
@@ -582,18 +608,18 @@ _e_keyrouter_send_key_event(int type, E_Client *ec, struct wl_client *wc, Ecore_
    uint serial;
    Eina_List *l;
 
-   if (ec == NULL)
+   if (surface == NULL)
      {
         wc_send = wc;
      }
    else
      {
-        wc_send = wl_resource_get_client(ec->comp_data->wl_surface);
+        wc_send = wl_resource_get_client(surface);
      }
 
    if (ECORE_EVENT_KEY_DOWN == type)
      {
-        e_keyrouter_prepend_to_keylist(ec, wc, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED);
+        e_keyrouter_prepend_to_keylist(surface, wc, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED);
         evtype = WL_KEYBOARD_KEY_STATE_PRESSED;
      }
    else
@@ -779,6 +805,17 @@ _e_keyrouter_wl_array_length(const struct wl_array *array)
    return count;
 }
 
+static struct wl_resource *
+_e_keyrouter_util_get_surface_from_eclient(E_Client *client)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL
+     (client, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL
+     (client->comp_data, NULL);
+
+   return client->comp_data->wl_surface;
+}
+
 static void
 _e_keyrouter_deinit_handlers(void)
 {
@@ -825,11 +862,12 @@ _e_keyrouter_client_cb_remove(void *data, int type, void *event)
 
    (void) data;
    (void) type;
-   (void) event;
-
-   KLDBG("e_client: %p is died\n", ec);
+   (void) ev;
+   (void) ec;
 
-   e_keyrouter_remove_client_from_list(ec, NULL);
+   /* FIXME: Remove this callback or do something others.
+    *             It was moved to _e_keyrouter_wl_surface_cb_destroy() where it had here.
+    */
 
    return ECORE_CALLBACK_PASS_ON;
 }
@@ -847,3 +885,17 @@ _e_keyrouter_wl_client_cb_destroy(struct wl_listener *l, void *data)
 
    krt->none_surface_grab_client = eina_list_remove(krt->none_surface_grab_client, client);
 }
+
+static void
+_e_keyrouter_wl_surface_cb_destroy(struct wl_listener *l, void *data)
+{
+   struct wl_resource *surface = data;
+
+   KLDBG("Listener(%p) called: surface: %p is died\n", l, surface);
+   e_keyrouter_remove_client_from_list(surface, NULL);
+
+   E_FREE(l);
+   l = NULL;
+
+   krt->surface_grab_client = eina_list_remove(krt->surface_grab_client, surface);
+}
index 4eb0863..4930738 100644 (file)
@@ -28,7 +28,7 @@ extern E_KeyrouterPtr krt;
 
 struct _E_Keyrouter_Key_List_Node
 {
-   E_Client *ec;
+   struct wl_resource *surface;
    struct wl_client *wc;
 };
 
@@ -59,6 +59,7 @@ struct _E_Keyrouter
 
    E_Keyrouter_Grabbed_Key HardKeys[MAX_HWKEYS];
    E_Keyrouter_Tizen_HWKey *TizenHWKeys;
+   Eina_List *surface_grab_client;
    Eina_List *none_surface_grab_client;
 
    Eina_Bool isWindowStackChanged;
@@ -83,10 +84,11 @@ EAPI int   e_modapi_shutdown(E_Module *m);
 EAPI int   e_modapi_save(E_Module *m);
 
 int e_keyrouter_set_keygrab_in_list(struct wl_resource *surface, struct wl_client *client, uint32_t key, uint32_t mode);
-int e_keyrouter_prepend_to_keylist(E_Client *ec, struct wl_client *wc, uint32_t key, uint32_t mode);
-void e_keyrouter_find_and_remove_client_from_list(E_Client *ec, struct wl_client *wc, uint32_t key, uint32_t mode);
-void e_keyrouter_remove_client_from_list(E_Client *ec, struct wl_client *wc);
+int e_keyrouter_prepend_to_keylist(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode);
+void e_keyrouter_find_and_remove_client_from_list(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode);
+void e_keyrouter_remove_client_from_list(struct wl_resource *surface, struct wl_client *wc);
 
 int e_keyrouter_add_client_destroy_listener(struct wl_client *client);
+int e_keyrouter_add_surface_destroy_listener(struct wl_resource *surface);
 
 #endif