e_keyrouter: support a event_surface event 06/163406/1
authorJengHyun Kang <jhyuni.kang@samsung.com>
Fri, 13 Oct 2017 10:13:07 +0000 (19:13 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Mon, 11 Dec 2017 05:13:30 +0000 (05:13 +0000)
Change-Id: Ib14f91db1311bb7f96957431328ff26f188ef42a
(cherry picked from commit 6af552cf362869198c2664b6c42fffb2deb87f00)

src/bin/e_comp_canvas.c
src/bin/e_comp_wl.c
src/bin/e_comp_wl.h
src/bin/e_keyrouter.c
src/bin/e_keyrouter.h
src/bin/e_main.c

index 0a8dd6f404b6050d04557354ebe281f964a0e294..4f9113a6dcc361ce788391c02505dc5c9d7deaeb 100644 (file)
@@ -94,6 +94,16 @@ _e_comp_cb_key_up(void *data EINA_UNUSED, int ev_type EINA_UNUSED, Ecore_Event_K
    return !e_comp_wl_key_up(ev);
 }
 
+static Eina_Bool
+_e_comp_cb_keyrouter_key(void *data EINA_UNUSED, int ev_type EINA_UNUSED, E_Keyrouter_Event_Key *ev)
+{
+   Eina_Bool res;
+
+   res = e_comp_wl_key_process(ev);
+
+   return res;
+}
+
 ////////////////////////////////////
 
 static Eina_Bool
@@ -220,6 +230,7 @@ e_comp_canvas_init(int w, int h)
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_COMPOSITOR_ENABLE,    _e_comp_cb_compositor_enabled, NULL);
    E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_KEY_DOWN, _e_comp_cb_key_down, NULL);
    E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_KEY_UP, _e_comp_cb_key_up, NULL);
+   E_LIST_HANDLER_APPEND(handlers, E_KEYROUTER_EVENT_KEY, _e_comp_cb_keyrouter_key, NULL);
 
    ecore_evas_callback_pre_render_set(e_comp->ee, _e_comp_canvas_prerender);
    ecore_evas_callback_resize_set(e_comp->ee, _e_comp_canvas_resize);
index 798f61563207e2a33e7e3ffbccab7e3ed9ebd7a5..4012185664b30be08fead58966c38a0fea688b5f 100644 (file)
@@ -49,6 +49,12 @@ typedef struct _E_Comp_Wl_Key_Data
    Evas_Device *dev;
 } E_Comp_Wl_Key_Data;
 
+typedef struct _E_Comp_Wl_Routed_Key_Data
+{
+   uint32_t key;
+   Eina_Bool pressed;
+} E_Comp_Wl_Routed_Key_Data;
+
 static Eina_List *handlers = NULL;
 static E_Client *cursor_timer_ec = NULL;
 static Eina_Bool need_send_leave = EINA_TRUE;
@@ -5376,6 +5382,51 @@ _e_comp_wl_key_send(Ecore_Event_Key *ev, enum wl_keyboard_key_state state, Eina_
      }
 }
 
+static void
+_e_comp_wl_routed_key_send(E_Keyrouter_Event_Key *ev, enum wl_keyboard_key_state state, Eina_List *key_list, Eina_Bool focused)
+{
+   struct wl_resource *res;
+   Eina_List *l;
+   uint32_t serial, keycode;
+   struct wl_client *wc;
+   Ecore_Device *last_dev;
+   E_Comp_Config *comp_conf = NULL;
+
+   keycode = (ev->keycode - 8);
+
+   serial = wl_display_next_serial(e_comp_wl->wl.disp);
+
+   comp_conf = e_comp_config_get();
+
+   EINA_LIST_FOREACH(key_list, l, res)
+     {
+        wc = wl_resource_get_client(res);
+        if (!focused && wc != ev->routed.client) continue;
+        TRACE_INPUT_BEGIN(_e_comp_wl_routed_key_send);
+        last_dev = eina_hash_find(_last_keydev_hash, wc);
+        if (!last_dev)
+          {
+             _e_comp_wl_client_destroy_listener_add(wc);
+             eina_hash_direct_add(_last_keydev_hash, wc, ev->dev);
+             _e_comp_wl_send_event_device(ev->routed.client, ev->timestamp, ev->dev, serial);
+          }
+        else if (last_dev != ev->dev)
+          {
+             eina_hash_modify(_last_keydev_hash, wc, ev->dev);
+             _e_comp_wl_send_event_device(ev->routed.client, ev->timestamp, ev->dev, serial);
+          }
+
+        if (comp_conf && comp_conf->input_log_enable)
+          INF("[Server] Key %s (time: %d)\n", (state ? "Down" : "Up"), ev->timestamp);
+
+        if (ev->routed.surface) e_keyrouter_send_event_surface(ev->routed.surface, ev->keycode, ev->routed.mode);
+
+        wl_keyboard_send_key(res, serial, ev->timestamp,
+                             keycode, state);
+        TRACE_INPUT_END();
+     }
+}
+
 EINTERN Eina_Bool
 e_comp_wl_key_down(Ecore_Event_Key *ev)
 {
@@ -5383,6 +5434,7 @@ e_comp_wl_key_down(Ecore_Event_Key *ev)
    struct wl_client *wc = NULL;
    uint32_t keycode;
    E_Comp_Wl_Key_Data *end, *k;
+   E_Comp_Wl_Routed_Key_Data *r_end, *r_k;
 
    if ((e_comp->comp_type != E_PIXMAP_TYPE_WL) || (ev->window != e_comp->ee_win))
      {
@@ -5409,50 +5461,18 @@ e_comp_wl_key_down(Ecore_Event_Key *ev)
    if (ec && ec->comp_data && ec->comp_data->surface)
      wc = wl_resource_get_client(ec->comp_data->surface);
 
-   if (ev->data)
+   if (ev->data && ev->data != (void *)0x1)
      {
-        if ((wc != ev->data) && (ev->data != (void *)0x1))
-          {
-             _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_PRESSED, e_comp_wl->kbd.resources, EINA_FALSE);
-          }
-        else
-          {
-             ec = NULL;
-             end = (E_Comp_Wl_Key_Data *)e_comp_wl->kbd.routed_keys.data + (e_comp_wl->kbd.routed_keys.size / sizeof(*k));
+        r_end = (E_Comp_Wl_Routed_Key_Data *)e_comp_wl->kbd.routed_keys.data + (e_comp_wl->kbd.routed_keys.size / sizeof(*r_k));
 
-             for (k = e_comp_wl->kbd.routed_keys.data; k < end; k++)
-               {
-                  /* ignore server-generated key repeats */
-                  if (k->key == keycode)
-                    {
-                       return EINA_FALSE;
-                    }
-               }
-
-             if (ev->data == (void *)0x1) return EINA_FALSE;
-
-             if ((!e_client_action_get()) && (!e_comp->input_key_grabs))
-               {
-                  ec = e_client_focused_get();
-                  if (ec && ec->comp_data && ec->comp_data->surface && e_comp_wl->kbd.focused)
-                    {
-                       _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_PRESSED, e_comp_wl->kbd.focused, EINA_TRUE);
-
-                       /* A key only sent to clients is added to the list */
-                       e_comp_wl->kbd.routed_keys.size = (const char *)end - (const char *)e_comp_wl->kbd.routed_keys.data;
-                       if (!(k = wl_array_add(&e_comp_wl->kbd.routed_keys, sizeof(*k))))
-                         {
-                            DBG("wl_array_add: Out of memory\n");
-                            return EINA_FALSE;
-                         }
-                       k->key = keycode;
-                       k->dev = ev->dev;
-                    }
-               }
-
-             /* update modifier state */
-             e_comp_wl_input_keyboard_state_update(keycode, EINA_TRUE);
+        e_comp_wl->kbd.routed_keys.size = (const char *)r_end - (const char *)e_comp_wl->kbd.routed_keys.data;
+        if (!(r_k = wl_array_add(&e_comp_wl->kbd.routed_keys, sizeof(*r_k))))
+          {
+             DBG("wl_array_add: Out of memory\n");
+             return EINA_FALSE;
           }
+        r_k->key = keycode;
+        r_k->pressed = EINA_TRUE;
 
         return !!ec;
      }
@@ -5503,6 +5523,7 @@ e_comp_wl_key_up(Ecore_Event_Key *ev)
    struct wl_client *wc = NULL;
    uint32_t keycode, delivered_key;
    E_Comp_Wl_Key_Data *end, *k;
+   E_Comp_Wl_Routed_Key_Data *r_end, *r_k;
 
    if ((e_comp->comp_type != E_PIXMAP_TYPE_WL) ||
        (ev->window != e_comp->ee_win))
@@ -5522,42 +5543,19 @@ e_comp_wl_key_up(Ecore_Event_Key *ev)
    if (ec && ec->comp_data && ec->comp_data->surface)
      wc = wl_resource_get_client(ec->comp_data->surface);
 
-   if (ev->data)
+   if (ev->data && ev->data != (void *)0x1)
      {
-        end = (E_Comp_Wl_Key_Data *)e_comp_wl->kbd.routed_keys.data + (e_comp_wl->kbd.routed_keys.size / sizeof(*k));
-        for (k = e_comp_wl->kbd.routed_keys.data; k < end; k++)
-          {
-             if (k->key == keycode)
-               {
-                  *k = *--end;
-                  delivered_key = 1;
-               }
-          }
-        e_comp_wl->kbd.routed_keys.size =
-          (const char *)end - (const char *)e_comp_wl->kbd.routed_keys.data;
+        r_end = (E_Comp_Wl_Routed_Key_Data *)e_comp_wl->kbd.routed_keys.data + (e_comp_wl->kbd.routed_keys.size / sizeof(*r_k));
 
-        if (wc != ev->data)
+        e_comp_wl->kbd.routed_keys.size = (const char *)r_end - (const char *)e_comp_wl->kbd.routed_keys.data;
+        if (!(r_k = wl_array_add(&e_comp_wl->kbd.routed_keys, sizeof(*r_k))))
           {
-             _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_RELEASED, e_comp_wl->kbd.resources, EINA_FALSE);
+             DBG("wl_array_add: Out of memory\n");
+             return EINA_FALSE;
           }
-        else
-          {
-             ec = NULL;
+        r_k->key = keycode;
+        r_k->pressed = EINA_FALSE;
 
-             if ((delivered_key) ||
-                 ((!e_client_action_get()) && (!e_comp->input_key_grabs)))
-               {
-                  ec = e_client_focused_get();
-
-                  if (e_comp_wl->kbd.focused)
-                    {
-                       _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_RELEASED, e_comp_wl->kbd.focused, EINA_FALSE);
-                    }
-               }
-
-             /* update modifier state */
-             e_comp_wl_input_keyboard_state_update(keycode, EINA_FALSE);
-          }
         return !!ec;
      }
 
@@ -5595,6 +5593,65 @@ e_comp_wl_key_up(Ecore_Event_Key *ev)
    return !!ec;
 }
 
+EINTERN Eina_Bool
+e_comp_wl_key_process(E_Keyrouter_Event_Key *ev)
+{
+   int keycode;
+   Eina_Bool process_flag = EINA_FALSE;
+   E_Comp_Wl_Routed_Key_Data *r_end, *r_k;
+   E_Client *ec;
+   struct wl_client *wc = NULL;
+
+   keycode = ev->keycode - 8;
+
+   r_end = (E_Comp_Wl_Routed_Key_Data *)e_comp_wl->kbd.routed_keys.data + (e_comp_wl->kbd.routed_keys.size / sizeof(*r_k));
+   for (r_k = e_comp_wl->kbd.routed_keys.data; r_k < r_end; r_k++)
+     {
+        if ((r_k->key == keycode) &&
+            (r_k->pressed == ev->pressed))
+          {
+             *r_k = *--r_end;
+             process_flag = EINA_TRUE;
+             break;
+          }
+     }
+
+   e_comp_wl->kbd.routed_keys.size =
+     (const char *)r_end - (const char *)e_comp_wl->kbd.routed_keys.data;
+
+   ec = e_client_focused_get();
+
+   if (ec && ec->comp_data && ec->comp_data->surface)
+     wc = wl_resource_get_client(ec->comp_data->surface);
+
+   if (!process_flag) return EINA_FALSE;
+   if ((wc !=ev->routed.client) && (ev->routed.client != (void *)0x1))
+     {
+        if (ev->pressed)
+          _e_comp_wl_routed_key_send(ev, WL_KEYBOARD_KEY_STATE_PRESSED, e_comp_wl->kbd.resources, EINA_FALSE);
+        else
+          _e_comp_wl_routed_key_send(ev, WL_KEYBOARD_KEY_STATE_RELEASED, e_comp_wl->kbd.resources, EINA_FALSE);
+     }
+   else
+     {
+        if ((!e_client_action_get()) && (!e_comp->input_key_grabs))
+          {
+             if (ec && ec->comp_data && ec->comp_data->surface && e_comp_wl->kbd.focused)
+               {
+                  if (ev->pressed)
+                    _e_comp_wl_routed_key_send(ev, WL_KEYBOARD_KEY_STATE_PRESSED, e_comp_wl->kbd.focused, EINA_TRUE);
+                  else
+                    _e_comp_wl_routed_key_send(ev, WL_KEYBOARD_KEY_STATE_RELEASED, e_comp_wl->kbd.focused, EINA_TRUE);
+               }
+          }
+     }
+
+   /* update modifier state */
+   e_comp_wl_input_keyboard_state_update(keycode, EINA_TRUE);
+
+   return EINA_TRUE;
+}
+
 E_API Eina_Bool
 e_comp_wl_evas_handle_mouse_button(E_Client *ec, uint32_t timestamp, uint32_t button_id, uint32_t state)
 {
index 1341056c13f0b64bce40905e1dad5a2fee6737c0..2642bee8c9ba9dcd4abbf116472a67a67976de68 100644 (file)
@@ -557,6 +557,7 @@ E_API void e_comp_wl_output_remove(const char *id);
 
 EINTERN Eina_Bool e_comp_wl_key_down(Ecore_Event_Key *ev);
 EINTERN Eina_Bool e_comp_wl_key_up(Ecore_Event_Key *ev);
+EINTERN Eina_Bool e_comp_wl_key_process(E_Keyrouter_Event_Key *ev);
 E_API Eina_Bool e_comp_wl_evas_handle_mouse_button(E_Client *ec, uint32_t timestamp, uint32_t button_id, uint32_t state);
 E_API void        e_comp_wl_touch_cancel(void);
 
index 9deb5bfdc87ab4a41a512f32b828ac2c984fa165..476d607fb15d27823417ae4f4c0e379caea9afed 100644 (file)
@@ -1,6 +1,8 @@
 #include "e.h"
 #include "e_keyrouter.h"
 
+E_API int E_KEYROUTER_EVENT_KEY;
+
 static int _e_keyrouter_intercept_hooks_delete = 0;
 static int _e_keyrouter_intercept_hooks_walking = 0;
 
@@ -75,3 +77,26 @@ e_keyrouter_intercept_hook_call(E_Keyrouter_Intercept_Hook_Point hookpoint, int
 
    return res;
 }
+
+E_API void
+e_keyrouter_send_event_surface(struct wl_resource *surface, int key, int mode)
+{
+   EINA_SAFETY_ON_NULL_RETURN(e_keyrouter.event_surface_send);
+   EINA_SAFETY_ON_NULL_RETURN(surface);
+
+   e_keyrouter.event_surface_send(surface, key, mode);
+}
+
+EINTERN void
+e_keyrouter_init(void)
+{
+   E_KEYROUTER_EVENT_KEY = ecore_event_type_new();
+}
+
+EINTERN int
+e_keyrouter_shutdown(void)
+{
+   E_KEYROUTER_EVENT_KEY = 0;
+
+   return 1;
+}
index 66cecb3d4ea9f6a426e986893a9b8ddbb3efb2da..747e47e8dd3041ac3b670bb1817157a029f85a9b 100644 (file)
@@ -8,6 +8,8 @@ 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_Key E_Keyrouter_Event_Key;
+
 typedef enum _E_Keyrouter_Intercept_Hook_Point
 {
    E_KEYROUTER_INTERCEPT_HOOK_BEFORE_KEYROUTING,
@@ -30,6 +32,8 @@ typedef Eina_Bool (*E_Keyrouter_Intercept_Hook_Cb) (void *data, int type, Ecore_
 
 extern E_API E_Keyrouter_Info e_keyrouter;
 
+extern E_API int E_KEYROUTER_EVENT_KEY;
+
 struct _E_Keyrouter_Intercept_Hook
 {
    EINA_INLIST;
@@ -43,6 +47,7 @@ struct _E_Keyrouter_Info
 {
    void *(*keygrab_list_get)(void);
    int (*max_keycode_get)(void);
+   void (*event_surface_send)(struct wl_resource *surface, int key, int mode);
 };
 
 struct _E_Keyrouter_Registered_Window_Info
@@ -83,10 +88,34 @@ struct _E_Keyrouter_Grabbed_Key
    Eina_List *pic_off_ptr;
 };
 
+struct _E_Keyrouter_Event_Key
+{
+   Eina_Bool pressed;
+   int keycode;
+
+   Ecore_Window window;
+   unsigned int timestamp;
+   unsigned int modifiers;
+
+   Ecore_Device *dev;
+
+   struct
+   {
+      struct wl_client *client;
+      struct wl_resource *surface;
+      int mode;
+   } routed;
+};
+
 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);
 
+E_API void e_keyrouter_send_event_surface(struct wl_resource *surface, int key, int mode);
+
+EINTERN void e_keyrouter_init(void);
+EINTERN int e_keyrouter_shutdown(void);
+
 #endif
 #endif
 
index d005fd362c2e6789e0a6f3900edbd6191dc5c411..b696ca2540d93bd16122efc2d914febc630d53fb 100644 (file)
@@ -636,6 +636,11 @@ main(int argc, char **argv)
    TSE("E_Pointer Init Done");
    _e_main_shutdown_push(e_pointer_shutdown);
 
+   TSB("E_Keyrouter Init");
+   e_keyrouter_init();
+   TSE("E_Keyrouter Init Done");
+   _e_main_shutdown_push(e_keyrouter_shutdown);
+
    TRACE_DS_BEGIN(MAIN:SCREEN INIT);
    TSB("Screens Init");
    if (!_e_main_screens_init())