Separate input thread 78/295178/2
authorJihoon Kim <jihoon48.kim@samsung.com>
Fri, 31 Mar 2023 07:40:43 +0000 (16:40 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Tue, 4 Jul 2023 07:31:05 +0000 (07:31 +0000)
Change-Id: I55b0cbcf3b68d97616bdab40dab8bf81b56fb536
Signed-off-by: Jihoon Kim <jihoon48.kim@samsung.com>
22 files changed:
configure.ac
packaging/enlightenment.spec
src/bin/Makefile.mk
src/bin/e_comp.c
src/bin/e_comp_wl.c
src/bin/e_comp_wl.h
src/bin/e_comp_wl_rsm.c
src/bin/e_device.c [new file with mode: 0644]
src/bin/e_device.h [new file with mode: 0644]
src/bin/e_devicemgr_input.c
src/bin/e_devicemgr_inputgen.c
src/bin/e_dnd.c
src/bin/e_input.h
src/bin/e_input_evdev.c
src/bin/e_input_event.c [new file with mode: 0755]
src/bin/e_input_event.h [new file with mode: 0755]
src/bin/e_input_inputs.c
src/bin/e_input_private.h
src/bin/e_keyrouter.c
src/bin/e_keyrouter_events.c
src/bin/e_keyrouter_private.h
src/bin/e_keyrouter_wl.c

index bee742d..ede3828 100755 (executable)
@@ -286,6 +286,8 @@ e_requires="\
   libinput \
   libtbm \
   libtdm >= "1.0.0" \
+  glib-2.0 \
+  gobject-2.0 \
   "
 
 PKG_CHECK_MODULES(E_INFO, [
@@ -590,6 +592,8 @@ eldbus >= ${efl_version} \
 eio >= ${efl_version} \
 eo >= ${efl_version} \
 eeze >= ${efl_version} \
+gobject-2.0 \
+glib-2.0 \
 "
 
 e_libs="$E_LIBS $fnmatch_libs $execinfo_libs $DLOG_LIBS"
index 11fbacd..ea4a875 100644 (file)
@@ -65,6 +65,8 @@ BuildRequires:  pkgconfig(wtz-screen-server)
 BuildRequires:  pkgconfig(wtz-shell-server)
 BuildRequires:  pkgconfig(pointer-constraints-unstable-v1-server)
 BuildRequires:  pkgconfig(relative-pointer-unstable-v1-server)
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(gobject-2.0)
 Requires:       libwayland-extension-server
 
 # for gtest/gmock
index 90b7280..361a796 100644 (file)
@@ -139,7 +139,9 @@ src/bin/e_msg.h     \
 src/bin/e_foreign.h \
 src/bin/e_foreign_private.h \
 src/bin/e_map.h \
-src/bin/e_wtz_shell.h
+src/bin/e_wtz_shell.h \
+src/bin/e_device.h \
+src/bin/e_input_event.h
 
 enlightenment_src = \
 src/bin/e_actions.c \
@@ -268,7 +270,9 @@ src/bin/e_msg.c \
 src/bin/e_foreign.c \
 src/bin/e_foreign_shell.c \
 src/bin/e_map.c \
-src/bin/e_wtz_shell.c
+src/bin/e_wtz_shell.c \
+src/bin/e_device.c \
+src/bin/e_input_event.c
 
 src_bin_enlightenment_CPPFLAGS = $(E_CPPFLAGS) -DEFL_BETA_API_SUPPORT -DEFL_EO_API_SUPPORT -DE_LOGGING=2 @WAYLAND_CFLAGS@ $(TTRACE_CFLAGS) $(DLOG_CFLAGS) $(PIXMAN_CFLAGS) $(POLICY_CFLAGS) $(EGL_CFLAGS)
 if HAVE_LIBGOMP
index 68846c2..54f3c6d 100644 (file)
@@ -1,6 +1,9 @@
 #include "e.h"
 #include <sys/xattr.h>
 #include "services/e_service_quickpanel.h"
+#include "e_input_event.h"
+
+static E_Input_Event_Handler *_key_down_handler = NULL;
 
 #define OVER_FLOW 1
 //////////////////////////////////////////////////////////////////////////
@@ -479,6 +482,7 @@ e_comp_shutdown(void)
 {
    Eina_List *l, *ll;
    E_Client *ec;
+   E_Input_Event_Source *input_event_source = NULL;
 
    E_FREE_FUNC(action_timeout, ecore_timer_del);
    EINA_LIST_FOREACH_SAFE(e_comp->clients, l, ll, ec)
@@ -496,6 +500,15 @@ e_comp_shutdown(void)
    E_FREE_LIST(actions, e_object_del);
    E_FREE_LIST(hooks, e_client_hook_del);
 
+   input_event_source = e_input_event_source_get();
+   if (input_event_source)
+     {
+        if (_key_down_handler)
+          e_input_event_handler_del(input_event_source, _key_down_handler);
+     }
+
+   _key_down_handler = NULL;
+
    gl_avail = EINA_FALSE;
    e_comp_cfdata_config_free(conf);
    E_CONFIG_DD_FREE(conf_match_edd);
index 9e94ef5..01cce49 100644 (file)
@@ -9,6 +9,7 @@
 #include <wayland-tbm-server.h>
 #include <gbm.h>
 #include <Evas_GL.h>
+#include <glib.h>
 
 /* handle include for printing uint64_t */
 #define __STDC_FORMAT_MACROS
@@ -261,6 +262,16 @@ _e_comp_wl_cb_read(void *data EINA_UNUSED, Ecore_Fd_Handler *hdlr EINA_UNUSED)
    return ECORE_CALLBACK_RENEW;
 }
 
+void
+e_comp_wl_display_flush()
+{
+   if (e_comp_wl)
+     {
+        if (e_comp_wl->wl.disp)
+          wl_display_flush_clients(e_comp_wl->wl.disp);
+     }
+}
+
 static void
 _e_comp_wl_cb_prepare(void *data EINA_UNUSED, Ecore_Fd_Handler *hdlr EINA_UNUSED)
 {
@@ -279,7 +290,7 @@ _e_comp_wl_cb_prepare(void *data EINA_UNUSED, Ecore_Fd_Handler *hdlr EINA_UNUSED
    e_comp_wl->idle_exiter_timestamp = 0.0;
 
    /* flush pending client events */
-   wl_display_flush_clients(e_comp_wl->wl.disp);
+   e_comp_wl_display_flush();
 
    TRACE_DS_ASYNC_END((intptr_t)&e_comp_wl->idle_exiter_timestamp,
                       IDLE_EXITER~CB_PREPARE);
@@ -885,9 +896,9 @@ _e_comp_wl_device_send_last_event_device(E_Client *ec, Ecore_Device_Class dev_cl
         if (wl_resource_get_client(dev_res) != wc) continue;
         tizen_input_device_send_event_device(dev_res, serial, last_device->identifier, timestamp);
      }
- }
+}
 
- static void
+static void
 _e_comp_wl_send_event_device(struct wl_client *wc, uint32_t timestamp, Ecore_Device *dev, uint32_t serial)
 {
    E_Devicemgr_Input_Device *input_dev;
@@ -914,6 +925,32 @@ _e_comp_wl_send_event_device(struct wl_client *wc, uint32_t timestamp, Ecore_Dev
 }
 
 static void
+_e_comp_wl_send_event_e_device(struct wl_client *wc, uint32_t timestamp, E_Device *dev, uint32_t serial)
+{
+   E_Devicemgr_Input_Device *input_dev;
+   struct wl_resource *dev_res;
+   const char *dev_name;
+   Eina_List *l, *ll;
+
+   EINA_SAFETY_ON_NULL_RETURN(dev);
+
+   dev_name = e_device_identifier_get(dev);
+
+   EINA_LIST_FOREACH(e_devicemgr->device_list, l, input_dev)
+     {
+        if (!eina_streq(input_dev->identifier, dev_name) ||
+            (input_dev->clas != e_device_class_get(dev))) continue;
+        _e_comp_wl_device_last_device_set(e_device_class_get(dev), input_dev);
+
+        EINA_LIST_FOREACH(input_dev->resources, ll, dev_res)
+          {
+             if (wl_resource_get_client(dev_res) != wc) continue;
+             tizen_input_device_send_event_device(dev_res, serial, input_dev->identifier, timestamp);
+          }
+     }
+}
+
+static void
 _e_comp_wl_cursor_reload(E_Client *ec)
 {
    struct wl_resource *res;
@@ -4517,6 +4554,8 @@ e_comp_wl_init(void)
    if (!e_foreign_global_init(e_comp_wl->wl.disp))
      ELOGF("COMP", "Failed to initialize the e_foreign global", NULL);
 
+   g_mutex_init(&_wl_display_mutex);
+
    /* prepend a mouse move event handler to prevent the mouse move event from being delivered to
       the other mouse move event handlers when a pointer constraint is activated */
    E_LIST_HANDLER_PREPEND(handlers, ECORE_EVENT_MOUSE_MOVE, _e_comp_wl_cb_mouse_move_preventer, NULL);
@@ -5095,7 +5134,7 @@ e_comp_wl_output_remove(const char *id)
 }
 
 static void
-_e_comp_wl_key_send(Ecore_Event_Key *ev, enum wl_keyboard_key_state state, Eina_List *key_list, E_Client *ec)
+_e_comp_wl_key_send(Ecore_Event_Key *ev, E_Device *dev, enum wl_keyboard_key_state state, Eina_List *key_list, E_Client *ec)
 {
    struct wl_resource *res;
    Eina_List *l;
@@ -5117,10 +5156,10 @@ _e_comp_wl_key_send(Ecore_Event_Key *ev, enum wl_keyboard_key_state state, Eina_
         if (wl_resource_get_client(res) != wc) continue;
 
         TRACE_INPUT_BEGIN(_e_comp_wl_key_send);
-        _e_comp_wl_send_event_device(wc, ev->timestamp, ev->dev, serial);
+        _e_comp_wl_send_event_e_device(wc, ev->timestamp, dev, serial);
 
         if (comp_conf && comp_conf->input_log_enable)
-          ELOGF("Key", "Send Key %s (time: %d)", ec, (state ? "Down" : "Up"), ev->timestamp);
+          ELOGF("Key", "Send Key %s (time: %d, device: %s)", ec, (state ? "Down" : "Up"), ev->timestamp, e_device_name_get(dev));
 
         wl_keyboard_send_key(res, serial, ev->timestamp,
                              keycode, state);
@@ -5129,7 +5168,7 @@ _e_comp_wl_key_send(Ecore_Event_Key *ev, enum wl_keyboard_key_state state, Eina_
 }
 
 EINTERN Eina_Bool
-e_comp_wl_key_down(Ecore_Event_Key *ev)
+e_comp_wl_key_down(Ecore_Event_Key *ev, E_Device *dev)
 {
    E_Client *ec = NULL;
    uint32_t keycode;
@@ -5172,7 +5211,7 @@ e_comp_wl_key_down(Ecore_Event_Key *ev)
         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, ec);
+             _e_comp_wl_key_send(ev, dev, WL_KEYBOARD_KEY_STATE_PRESSED, e_comp_wl->kbd.focused, ec);
 
              /* A key only sent to clients is added to the list */
              e_comp_wl->kbd.keys.size = (const char *)end - (const char *)e_comp_wl->kbd.keys.data;
@@ -5193,7 +5232,7 @@ e_comp_wl_key_down(Ecore_Event_Key *ev)
 }
 
 EINTERN Eina_Bool
-e_comp_wl_key_up(Ecore_Event_Key *ev)
+e_comp_wl_key_up(Ecore_Event_Key *ev, E_Device *dev)
 {
    E_Client *ec = NULL;
    uint32_t keycode, delivered_key;
@@ -5232,7 +5271,7 @@ e_comp_wl_key_up(Ecore_Event_Key *ev)
 
         if (e_comp_wl->kbd.focused)
           {
-             _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_RELEASED, e_comp_wl->kbd.focused, ec);
+             _e_comp_wl_key_send(ev, dev, WL_KEYBOARD_KEY_STATE_RELEASED, e_comp_wl->kbd.focused, ec);
           }
      }
 
@@ -5243,17 +5282,17 @@ e_comp_wl_key_up(Ecore_Event_Key *ev)
 }
 
 EINTERN Eina_Bool
-e_comp_wl_key_process(Ecore_Event_Key *ev, int type)
+e_comp_wl_key_process(Ecore_Event_Key *ev, E_Device *dev, int type)
 {
    Eina_Bool res = EINA_FALSE;
 
    if (type == ECORE_EVENT_KEY_DOWN)
      {
-        res = e_comp_wl_key_down(ev);
+        res = e_comp_wl_key_down(ev, dev);
      }
    else if (type == ECORE_EVENT_KEY_UP)
      {
-        res = e_comp_wl_key_up(ev);
+        res = e_comp_wl_key_up(ev, dev);
      }
 
    return res;
@@ -5442,6 +5481,15 @@ e_comp_wl_send_event_device(struct wl_client *wc, uint32_t timestamp, Ecore_Devi
    _e_comp_wl_send_event_device(wc, timestamp, dev, serial);
 }
 
+EINTERN void
+e_comp_wl_send_event_e_device(struct wl_client *wc, uint32_t timestamp, E_Device *dev, uint32_t serial)
+{
+   EINA_SAFETY_ON_NULL_RETURN(wc);
+   EINA_SAFETY_ON_NULL_RETURN(dev);
+
+   _e_comp_wl_send_event_e_device(wc, timestamp, dev, serial);
+}
+
 EINTERN Eina_Bool
 e_comp_wl_key_send(E_Client *ec, int keycode, Eina_Bool pressed, Ecore_Device *dev, uint32_t time)
 {
index 0291d8e..2db9b2d 100644 (file)
@@ -589,8 +589,8 @@ EINTERN E_Comp_Wl_Buffer *e_comp_wl_buffer_get(struct wl_resource *resource, E_C
 EINTERN Eina_Bool e_comp_wl_output_init(const char *id, const char *make, const char *model, int x, int y, int w, int h, int pw, int ph, unsigned int refresh, unsigned int subpixel, unsigned int transform);
 EINTERN 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_down(Ecore_Event_Key *ev, E_Device *dev);
+EINTERN Eina_Bool e_comp_wl_key_up(Ecore_Event_Key *ev, E_Device *dev);
 EINTERN 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);
 
@@ -617,6 +617,7 @@ EINTERN void e_comp_wl_map_inv_coord_get(E_Client *ec, int x, int y, int *mx, in
 
 E_API void e_comp_wl_input_cursor_timer_enable_set(Eina_Bool enabled);
 EINTERN void e_comp_wl_send_event_device(struct wl_client *wc, uint32_t timestamp, Ecore_Device *dev, uint32_t serial);
+EINTERN void e_comp_wl_send_event_e_device(struct wl_client *wc, uint32_t timestamp, E_Device *dev, uint32_t serial);
 
 EINTERN Eina_Bool e_comp_wl_key_send(E_Client *ec, int keycode, Eina_Bool pressed, Ecore_Device *dev, uint32_t time);
 EINTERN Eina_Bool e_comp_wl_key_cancel(E_Client *ec, int keycode, Ecore_Device *dev, uint32_t time);
@@ -631,7 +632,7 @@ EINTERN Eina_Bool e_comp_wl_mouse_out_send(E_Client *ec, Ecore_Device *dev, uint
 EINTERN Eina_Bool e_comp_wl_mouse_relative_motion_send(E_Client *ec, int dx, int dy, int dx_unaccel, int dy_unaccel, uint64_t time);
 EINTERN void e_comp_wl_mouse_in_renew(E_Client *ec, int buttons, int x, int y, void *data, Evas_Modifier *modifiers, Evas_Lock *locks, unsigned int timestamp, Evas_Event_Flags event_flags, Evas_Device *dev, Evas_Object *event_src);
 EINTERN void e_comp_wl_mouse_out_renew(E_Client *ec, int buttons, int x, int y, void *data, Evas_Modifier *modifiers, Evas_Lock *locks, unsigned int timestamp, Evas_Event_Flags event_flags, Evas_Device *dev, Evas_Object *event_src);
-EINTERN Eina_Bool e_comp_wl_key_process(Ecore_Event_Key *ev, int type);
+EINTERN Eina_Bool e_comp_wl_key_process(Ecore_Event_Key *ev, E_Device *dev, int type);
 
 EINTERN Eina_Bool e_comp_wl_cursor_hide(E_Client *ec);
 
@@ -659,5 +660,7 @@ EINTERN Eina_Bool e_comp_wl_surface_viewport_get(E_Client *ec, Eina_Rectangle *b
 
 EINTERN Eina_Bool     e_comp_wl_surface_role_set(E_Client *ec, const char *role_name, struct wl_resource *error_resource, uint32_t error_code);
 EINTERN const char   *e_comp_wl_surface_role_get(E_Client *ec);
+
+EINTERN void    e_comp_wl_display_flush();
 # endif
 #endif
index f417086..d18083b 100644 (file)
@@ -1,5 +1,6 @@
 #include "e.h"
 #include "e_policy_wl.h"
+#include "e_device.h"
 #include <tizen-remote-surface-server-protocol.h>
 #include <tbm_surface.h>
 #include <tbm_surface_internal.h>
diff --git a/src/bin/e_device.c b/src/bin/e_device.c
new file mode 100644 (file)
index 0000000..402cc65
--- /dev/null
@@ -0,0 +1,86 @@
+#include "e_device.h"
+
+typedef struct {
+    gchar *source; // just sample
+} E_DevicePrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE(E_Device, e_device, G_TYPE_OBJECT);
+
+static GList *_dev_list = NULL;
+
+static void
+e_device_class_init(E_DeviceClass *klass)
+{
+
+}
+
+static void
+e_device_init(E_Device *self)
+{
+
+}
+
+E_Device *
+e_device_new(void)
+{
+   E_Device *dev;
+   dev = g_object_new(TYPE_E_DEVICE, NULL);
+
+   _dev_list = g_list_append (_dev_list, dev);
+
+   return dev;
+}
+
+void
+e_device_name_set(E_Device *dev, const char *name)
+{
+   g_object_set_data(G_OBJECT(dev), "name", (gpointer)name);
+}
+
+const gchar *
+e_device_name_get(const E_Device *dev)
+{
+   return g_object_get_data(G_OBJECT(dev), "name");
+}
+
+void
+e_device_class_set(E_Device *dev, Ecore_Device_Class device_class)
+{
+   g_object_set_data(G_OBJECT(dev), "class", GINT_TO_POINTER(device_class));
+}
+
+Ecore_Device_Class
+e_device_class_get(const E_Device *dev)
+{
+   return (Ecore_Device_Class)GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dev), "class"));
+}
+
+void
+e_device_subclass_set(E_Device *dev, Ecore_Device_Subclass subclass)
+{
+   g_object_set_data(G_OBJECT(dev), "subclass", GINT_TO_POINTER(subclass));
+}
+
+Ecore_Device_Subclass
+e_device_subclass_get(const E_Device *dev)
+{
+   return GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dev), "subclass"));
+}
+
+void
+e_device_identifier_set(E_Device *dev, const char *identifier)
+{
+   g_object_set_data(G_OBJECT(dev), "identifier", (gpointer)identifier);
+}
+
+const gchar *
+e_device_identifier_get(const E_Device *dev)
+{
+   return g_object_get_data(G_OBJECT(dev), "identifier");
+}
+
+const GList *
+e_device_list_get(void)
+{
+   return _dev_list;
+}
diff --git a/src/bin/e_device.h b/src/bin/e_device.h
new file mode 100644 (file)
index 0000000..6a9e725
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef E_DEVICE_H
+#define E_DEVICE_H
+
+#include <glib-object.h>
+#include <Ecore.h>
+
+G_BEGIN_DECLS
+
+#define TYPE_E_DEVICE e_device_get_type()
+G_DECLARE_DERIVABLE_TYPE(E_Device, e_device, E, DEVICE, GObject)
+
+struct _E_DeviceClass {
+    GObjectClass parent_class;
+};
+
+E_Device *
+e_device_new(void);
+
+void
+e_device_name_set(E_Device *dev, const char *name);
+
+const gchar *
+e_device_name_get(const E_Device *dev);
+
+void
+e_device_class_set(E_Device *dev, Ecore_Device_Class device_class);
+
+Ecore_Device_Class
+e_device_class_get(const E_Device *dev);
+
+void
+e_device_subclass_set(E_Device *dev, Ecore_Device_Subclass subclass);
+
+Ecore_Device_Subclass
+e_device_subclass_get(const E_Device *dev);
+
+void e_device_identifier_set(E_Device *dev, const char *identifier);
+const gchar *e_device_identifier_get(const E_Device *dev);
+
+const GList *
+e_device_list_get(void);
+
+G_END_DECLS
+
+#endif /* end of include guard: E_DEVICE_H */
index 0f37acf..d036a13 100644 (file)
@@ -1,4 +1,5 @@
 #include "e_devicemgr_private.h"
+#include "e_input_event.h"
 
 Eina_Bool
 e_devicemgr_strcmp(const char *dst, const char *src)
@@ -169,10 +170,8 @@ _e_devicemgr_input_mouse_button_remap(Ecore_Event_Mouse_Button *ev, Eina_Bool pr
    ev_key->keycode = e_devicemgr->dconfig->conf->input.back_keycode;
    ev_key->data = key_data;
 
-   if (pressed)
-     ecore_event_add(ECORE_EVENT_KEY_DOWN, ev_key, _e_devicemgr_input_keyevent_free, NULL);
-   else
-     ecore_event_add(ECORE_EVENT_KEY_UP, ev_key, _e_devicemgr_input_keyevent_free, NULL);
+   E_Input_Event_Source *input_event_source = e_input_event_source_get();
+   e_input_event_add(input_event_source, pressed ? ECORE_EVENT_KEY_DOWN : ECORE_EVENT_KEY_UP, ev_key, _e_devicemgr_input_keyevent_free, NULL);
 
    return ECORE_CALLBACK_DONE;
 
@@ -190,6 +189,7 @@ _e_devicemgr_input_device_add(const char *name, const char *identifier, const ch
 
    EINA_SAFETY_ON_NULL_RETURN(name);
    EINA_SAFETY_ON_NULL_RETURN(identifier);
+   EINA_SAFETY_ON_NULL_RETURN(e_devicemgr);
 
    EINA_LIST_FOREACH(e_devicemgr->device_list, l, dev)
      {
index 1bb4a9c..6640815 100644 (file)
@@ -77,7 +77,6 @@ _e_devicemgr_inputgen_key_event_free(void *data EINA_UNUSED, void *ev)
    eina_stringshare_del(e->key);
    eina_stringshare_del(e->compose);
 
-   if (e->dev) ecore_device_unref(e->dev);
    if (e->data) E_FREE(e->data);
 
    free(e);
@@ -89,6 +88,7 @@ e_devicemgr_inputgen_key_event_add(const char *key, Eina_Bool pressed, char *ide
    Ecore_Event_Key *e;
    unsigned int keycode;
    E_Keyrouter_Event_Data *key_data;
+   E_Device *dev = NULL;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(key, TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER);
 
@@ -114,14 +114,14 @@ e_devicemgr_inputgen_key_event_add(const char *key, Eina_Bool pressed, char *ide
    e->data = key_data;
 
    e->modifiers = 0;
-   e->dev = ecore_device_ref(e_input_evdev_get_ecore_device(identifier, ECORE_DEVICE_CLASS_KEYBOARD));
+
+   dev = e_input_evdev_get_e_device(identifier, ECORE_DEVICE_CLASS_KEYBOARD);
+   e->dev = (Eo *)dev;
 
    DMDBG("Generate key event: key: %s, keycode: %d, iden: %s\n", e->key, e->keycode, identifier);
 
-   if (pressed)
-     ecore_event_add(ECORE_EVENT_KEY_DOWN, e, _e_devicemgr_inputgen_key_event_free, NULL);
-   else
-     ecore_event_add(ECORE_EVENT_KEY_UP, e, _e_devicemgr_inputgen_key_event_free, NULL);
+   E_Input_Event_Source *input_event_source = e_input_event_source_get();
+   e_input_event_add(input_event_source, pressed ? ECORE_EVENT_KEY_DOWN : ECORE_EVENT_KEY_UP, e, _e_devicemgr_inputgen_key_event_free, NULL);
 
    return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
 
@@ -170,6 +170,8 @@ _e_devicemgr_inputgen_mouse_button_event(Eina_Bool state, int x, int y, int butt
    e->multi.y = e->y;
    e->multi.root.x = e->x;
    e->multi.root.y = e->y;
+
+   ecore_thread_main_loop_begin();
    e->dev = ecore_device_ref(e_input_evdev_get_ecore_device(identifier, ECORE_DEVICE_CLASS_MOUSE));
    e->buttons = buttons;
 
@@ -180,6 +182,8 @@ _e_devicemgr_inputgen_mouse_button_event(Eina_Bool state, int x, int y, int butt
    else
      ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, _e_devicemgr_inputgen_mouse_button_event_free, NULL);
 
+   ecore_thread_main_loop_end();
+
    return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
 }
 
@@ -223,11 +227,14 @@ _e_devicemgr_inputgen_mouse_move_event(int x, int y, char *identifier)
    e->multi.y = e->y;
    e->multi.root.x = e->x;
    e->multi.root.y = e->y;
+
+   ecore_thread_main_loop_begin();
    e->dev = ecore_device_ref(e_input_evdev_get_ecore_device(identifier, ECORE_DEVICE_CLASS_MOUSE));
 
    DMDBG("Generate mouse move event: (%d, %d)\n", e->x, e->y);
 
    ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, _e_devicemgr_inputgen_mouse_move_event_free, NULL);
+   ecore_thread_main_loop_end();
 
    return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
 }
@@ -269,6 +276,8 @@ _e_devicemgr_inputgen_mouse_wheel_event(unsigned int type, int value, E_Devicemg
      e->direction = 1;
    e->z = value;
 
+   ecore_thread_main_loop_begin();
+
    if (device)
      {
         if (!e_devicemgr_detent_is_detent(device->name))
@@ -280,6 +289,8 @@ _e_devicemgr_inputgen_mouse_wheel_event(unsigned int type, int value, E_Devicemg
 
    ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, _e_devicemgr_inputgen_mouse_wheel_event_free, NULL);
 
+   ecore_thread_main_loop_end();
+
    return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
 }
 
@@ -402,6 +413,8 @@ _e_devicemgr_inputgen_touch_event(uint32_t type, uint32_t x, uint32_t y, uint32_
    e->multi.y = e->y;
    e->multi.root.x = e->x;
    e->multi.root.y = e->y;
+
+   ecore_thread_main_loop_begin();
    e->dev = ecore_device_ref(e_input_evdev_get_ecore_device(device?device->identifier:NULL, ECORE_DEVICE_CLASS_TOUCH));
    e->buttons = 1;
 
@@ -412,6 +425,8 @@ _e_devicemgr_inputgen_touch_event(uint32_t type, uint32_t x, uint32_t y, uint32_
    else
      ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, _e_devicemgr_inputgen_mouse_button_event_free, NULL);
 
+   ecore_thread_main_loop_end();
+
    return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
 }
 
@@ -459,11 +474,15 @@ _e_devicemgr_inputgen_touch_update_event(uint32_t x, uint32_t y, uint32_t finger
    e->multi.y = e->y;
    e->multi.root.x = e->x;
    e->multi.root.y = e->y;
+
+   ecore_thread_main_loop_begin();
+
    e->dev = ecore_device_ref(e_input_evdev_get_ecore_device(device?device->identifier:NULL, ECORE_DEVICE_CLASS_TOUCH));
 
    DMDBG("Generate touch move event: device: %d (%d, %d)\n", e->multi.device, e->x, e->y);
 
    ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, _e_devicemgr_inputgen_mouse_move_event_free, NULL);
+   ecore_thread_main_loop_end();
 
    return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
 }
index 93b275d..b6edf92 100644 (file)
@@ -1,4 +1,5 @@
 #include "e.h"
+#include "e_input_event.h"
 
 /* local subsystem functions */
 
index f0fc14c..da465bd 100644 (file)
@@ -12,6 +12,8 @@ typedef struct _E_Input E_Input;
 #define E_INPUT_REQUEST_SERVER ((void *)0x1)
 
 #include <xkbcommon/xkbcommon.h>
+#include "e_device.h"
+#include "e_input_event.h"
 
 EINTERN extern int E_INPUT_EVENT_SEAT_ADD;
 EINTERN extern int E_EVENT_INPUT_ENABLED;
@@ -130,6 +132,7 @@ EINTERN const char *e_input_evdev_name_get(E_Input_Evdev *evdev);
 EINTERN Eina_List *e_input_seat_evdev_list_get(E_Input_Seat *seat);
 EINTERN int e_input_evdev_wheel_click_angle_get(E_Input_Evdev *dev);
 EINTERN Ecore_Device *e_input_evdev_get_ecore_device(const char *path, Ecore_Device_Class clas);
+EINTERN E_Device *e_input_evdev_get_e_device(const char *path, Ecore_Device_Class clas);
 
 EINTERN unsigned int e_input_device_touch_pressed_get(E_Input_Device *dev);
 EINTERN Eina_Bool e_input_device_keyboard_remap_set(E_Input_Device *dev, int *from_keys, int *to_keys, int num);
@@ -146,6 +149,7 @@ EINTERN Eina_Bool e_input_device_seat_name_set(E_Input_Device *dev, const char *
 
 E_API E_Input_Hook *e_input_hook_add(E_Input_Hook_Point hookpoint, E_Input_Hook_Cb func, const void *data);
 E_API void e_input_hook_del(E_Input_Hook *ch);
+E_API E_Input_Event_Source *e_input_event_source_get();
 
 EINTERN Eina_Bool e_input_relative_motion_handler_set(e_input_relative_motion_cb handler);
 EINTERN e_input_relative_motion_cb e_input_relative_motion_handler_get(void);
index 69c172a..9c8334f 100644 (file)
@@ -1,5 +1,10 @@
 #include "e.h"
 #include "e_input_private.h"
+#include "e_device.h"
+#include "e_keyrouter_private.h"
+#include "e_input_event.h"
+
+#include <glib.h>
 
 static void  _device_modifiers_update(E_Input_Evdev *edev);
 static void  _device_configured_size_get(E_Input_Evdev *edev, int *x, int *y, int *w, int *h);
@@ -385,6 +390,32 @@ _device_remapped_key_get(E_Input_Evdev *edev, int code)
    return code;
 }
 
+EINTERN E_Device *
+e_input_evdev_get_e_device(const char *path, Ecore_Device_Class clas)
+{
+   const GList *dev_list = NULL;
+   const GList *l;
+   E_Device *dev = NULL;
+   const char *identifier;
+
+   if (!path) return NULL;
+
+   dev_list = e_device_list_get();
+   if (!dev_list) return NULL;
+   for (l = dev_list, dev = dev_list->data;
+        l; \
+        l = g_list_next(l), dev = l->data)
+     {
+        if (!dev) continue;
+        identifier = e_device_identifier_get(dev);
+        if (!identifier) continue;
+        if ((e_device_class_get(dev) == clas) && !(strcmp(identifier, path)))
+          return dev;
+     }
+
+   return NULL;
+}
+
 EINTERN Ecore_Device *
 e_input_evdev_get_ecore_device(const char *path, Ecore_Device_Class clas)
 {
@@ -443,7 +474,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->dev) ecore_device_unref(ev->dev);
    if (ev->data) E_FREE(ev->data);
 
    free(ev);
@@ -465,7 +496,9 @@ _device_handle_key(struct libinput_device *device, struct libinput_event_keyboar
    char *tmp = NULL, *compose = NULL;
    E_Keyrouter_Event_Data *key_data;
    Ecore_Device *ecore_dev = NULL, *data;
-   Eina_List *l, *l_next;
+   E_Device *e_dev = NULL, *e_dev_data;
+   Eina_List *l = NULL, *l_next = NULL;
+   GList *glist = NULL;
    E_Comp_Config *comp_conf = NULL;
    int *pressed_keycode = NULL, *idata = NULL;
    Eina_Bool dup_found = EINA_FALSE;
@@ -504,6 +537,32 @@ _device_handle_key(struct libinput_device *device, struct libinput_event_keyboar
         return;
      }
 
+   if (edev->e_dev) e_dev = edev->e_dev;
+   else if (edev->e_dev_list && g_list_length(edev->e_dev_list) > 0)
+     {
+        for (glist = edev->e_dev_list, e_dev_data = edev->e_dev_list->data;
+             glist; \
+             glist = g_list_next(l), e_dev_data = l->data)
+          {
+             if (e_device_class_get(e_dev_data) == ECORE_DEVICE_CLASS_KEYBOARD)
+               {
+                  e_dev = e_dev_data;
+                  break;
+               }
+          }
+     }
+   else
+     {
+        edev->e_dev = e_input_evdev_get_e_device(edev->path, ECORE_DEVICE_CLASS_KEYBOARD);
+        e_dev = edev->e_dev;
+     }
+
+   if (!e_dev)
+     {
+        ERR("Failed to get source e device from event !\n");
+        return;
+     }
+
    timestamp = libinput_event_keyboard_get_time(event);
    code = libinput_event_keyboard_get_key(event);
    code = _device_remapped_key_get(edev, code + 8);
@@ -653,20 +712,17 @@ _device_handle_key(struct libinput_device *device, struct libinput_event_keyboar
    e->same_screen = 1;
    e->keycode = code;
    e->data = key_data;
+   e->dev = (Eo *)e_dev;
 
    _device_modifiers_update(edev);
 
    e->modifiers = edev->xkb.modifiers;
-   e->dev = ecore_device_ref(ecore_dev);
 
    comp_conf = e_comp_config_get();
    if (comp_conf && comp_conf->input_log_enable)
-     ELOGF("Key", "%s (keyname: %s, keycode: %d, device: %s)", NULL, state?"Press":"Release", e->keyname, e->keycode, ecore_device_name_get(e->dev));
+     ELOGF("Key", "%s (keyname: %s, keycode: %d, device: %s)", NULL, state?"Press":"Release", e->keyname, e->keycode, e_device_name_get(e_dev));
 
-   if (state)
-     ecore_event_add(ECORE_EVENT_KEY_DOWN, e, _e_input_event_key_cb_free, NULL);
-   else
-     ecore_event_add(ECORE_EVENT_KEY_UP, e, _e_input_event_key_cb_free, NULL);
+   e_input_event_add(input->event_source, state ? ECORE_EVENT_KEY_DOWN : ECORE_EVENT_KEY_UP, e, _e_input_event_key_cb_free, NULL);
 
    if (tmp) free(tmp);
 }
@@ -760,9 +816,14 @@ _device_pointer_motion(E_Input_Evdev *edev, struct libinput_event_pointer *event
    ev->multi.y = ev->y;
    ev->multi.root.x = ev->x;
    ev->multi.root.y = ev->y;
+
+   ecore_thread_main_loop_begin();
+
    ev->dev = ecore_device_ref(ecore_dev);
 
    ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, _e_input_event_mouse_move_cb_free, NULL);
+
+   ecore_thread_main_loop_end();
 }
 
 void
@@ -997,6 +1058,9 @@ _device_handle_button(struct libinput_device *device, struct libinput_event_poin
    ev->multi.y = ev->y;
    ev->multi.root.x = ev->x;
    ev->multi.root.y = ev->y;
+
+   ecore_thread_main_loop_begin();
+
    ev->dev = ecore_device_ref(ecore_dev);
 
    if (state)
@@ -1042,6 +1106,8 @@ _device_handle_button(struct libinput_device *device, struct libinput_event_poin
      ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, _e_input_event_mouse_button_cb_free, NULL);
    else
      ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, _e_input_event_mouse_button_cb_free, NULL);
+
+   ecore_thread_main_loop_end();
 }
 
 #if !LIBINPUT_HAVE_SCROLL_VALUE_V120
@@ -1196,8 +1262,6 @@ _device_handle_axis(struct libinput_device *device, struct libinput_event_pointe
    ev->y = edev->seat->ptr.iy;
    ev->root.x = ev->x;
    ev->root.y = ev->y;
-   ev->dev = ecore_device_ref(ecore_dev);
-
    ev->z = z;
    ev->direction = direction;
 
@@ -1209,7 +1273,10 @@ _device_handle_axis(struct libinput_device *device, struct libinput_event_pointe
           ELOGF("Mouse", "Wheel (direction: %d, value: %d)", NULL, ev->direction, ev->z);
      }
 
+   ecore_thread_main_loop_begin();
+   ev->dev = ecore_device_ref(ecore_dev);
    ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, _e_input_event_mouse_wheel_cb_free, NULL);
+   ecore_thread_main_loop_end();
 }
 #endif
 
@@ -1372,8 +1439,6 @@ _device_handle_axis_v120(struct libinput_device *device, struct libinput_event_p
    ev->y = edev->seat->ptr.iy;
    ev->root.x = ev->x;
    ev->root.y = ev->y;
-   ev->dev = ecore_device_ref(ecore_dev);
-
    ev->z = z;
    ev->direction = direction;
 
@@ -1385,7 +1450,10 @@ _device_handle_axis_v120(struct libinput_device *device, struct libinput_event_p
           ELOGF("Mouse", "Wheel (direction: %d, value: %d)", NULL, ev->direction, ev->z);
      }
 
+   ecore_thread_main_loop_begin();
+   ev->dev = ecore_device_ref(ecore_dev);
    ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, _e_input_event_mouse_wheel_cb_free, NULL);
+   ecore_thread_main_loop_end();
 }
 #endif
 
@@ -1467,6 +1535,9 @@ _device_handle_touch_event_send(E_Input_Evdev *edev, struct libinput_event_touch
    ev->multi.y = ev->y;
    ev->multi.root.x = ev->x;
    ev->multi.root.y = ev->y;
+
+   ecore_thread_main_loop_begin();
+
    ev->dev = ecore_device_ref(ecore_dev);
 
    if (state == ECORE_EVENT_MOUSE_BUTTON_DOWN)
@@ -1510,6 +1581,8 @@ _device_handle_touch_event_send(E_Input_Evdev *edev, struct libinput_event_touch
      ev->triple_click = 1;
 
    ecore_event_add(state, ev, _e_input_event_mouse_button_cb_free, NULL);
+
+   ecore_thread_main_loop_end();
 }
 
 static void
@@ -1523,6 +1596,8 @@ _device_handle_touch_motion_send(E_Input_Evdev *edev, struct libinput_event_touc
    if (!edev) return;
    if (!(input = edev->seat->input)) return;
 
+   ecore_thread_main_loop_begin();
+
    if (edev->ecore_dev) ecore_dev = edev->ecore_dev;
    else if (edev->ecore_dev_list && eina_list_count(edev->ecore_dev_list) > 0)
      {
@@ -1586,6 +1661,8 @@ _device_handle_touch_motion_send(E_Input_Evdev *edev, struct libinput_event_touc
    ev->dev = ecore_device_ref(ecore_dev);
 
    ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, _e_input_event_mouse_move_cb_free, NULL);
+
+   ecore_thread_main_loop_end();
 }
 
 static void
@@ -1649,13 +1726,17 @@ _device_handle_touch_cancel_send(E_Input_Evdev *edev, struct libinput_event_touc
    ev->multi.y = ev->y;
    ev->multi.root.x = ev->x;
    ev->multi.root.y = ev->y;
-   ev->dev = ecore_device_ref(ecore_dev);
 
    edev->touch.pressed &= ~(1 << ev->multi.device);
 
    ev->buttons = ((button & 0x00F) + 1);
 
+   ecore_thread_main_loop_begin();
+
+   ev->dev = ecore_device_ref(ecore_dev);
+
    ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_CANCEL, ev, _e_input_event_mouse_button_cb_free, NULL);
+   ecore_thread_main_loop_end();
 }
 
 static void
@@ -1989,13 +2070,17 @@ _device_handle_touch_aux_data(struct libinput_device *device, struct libinput_ev
         ev->naxis = 1;
      }
    ev->axis = axis;
-   ev->dev = ecore_device_ref(ecore_dev);
 
    comp_conf = e_comp_config_get();
    if (comp_conf && comp_conf->input_log_enable)
      ELOGF("Touch", "Axis (label: %d, value: %lf)", NULL, axis?axis->label:-1, axis?axis->value:0.0);
 
+   ecore_thread_main_loop_begin();
+
+   ev->dev = ecore_device_ref(ecore_dev);
+
    ecore_event_add(ECORE_EVENT_AXIS_UPDATE, ev, _e_input_aux_data_event_free, NULL);
+   ecore_thread_main_loop_end();
 
 end:
    ;
@@ -2083,6 +2168,8 @@ _e_input_evdev_device_destroy(E_Input_Evdev *edev)
 
    EINA_SAFETY_ON_NULL_RETURN(edev);
 
+   ecore_thread_main_loop_begin();
+
    if (edev->caps & E_INPUT_SEAT_KEYBOARD)
      {
         if (edev->xkb.state) xkb_state_unref(edev->xkb.state);
@@ -2105,6 +2192,8 @@ _e_input_evdev_device_destroy(E_Input_Evdev *edev)
      }
    eina_stringshare_del(edev->output_name);
 
+   ecore_thread_main_loop_end();
+
    free(edev);
 }
 
diff --git a/src/bin/e_input_event.c b/src/bin/e_input_event.c
new file mode 100755 (executable)
index 0000000..9e071b1
--- /dev/null
@@ -0,0 +1,208 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <stdint.h>
+#include <sys/eventfd.h>
+
+#include <glib.h>
+#include <glib-unix.h>
+#include "e_input_event.h"
+
+#define G_LIST_GET_DATA(list) ((list) ? (((GList *)(list))->data) : NULL)
+
+static gboolean _process_filter_event(E_Input_Event_Source *ev_source, E_Input_Event *ev);
+static gboolean _process_event_handler(E_Input_Event_Source *ev_source, E_Input_Event *ev);
+
+EINTERN void
+e_input_event_process(GSource *source)
+{
+   E_Input_Event_Source *ev_source = (E_Input_Event_Source *)source;
+   E_Input_Event *ev = NULL;
+
+   if (!source) return;
+
+   while ((ev = (E_Input_Event *)g_queue_pop_head(ev_source->ev_queue)))
+     {
+        if (_process_filter_event(ev_source, ev)) {
+             _process_event_handler(ev_source, ev);
+        }
+
+        if (ev->free_func)
+          ev->free_func(ev->free_func_data, ev->ev_data);
+
+        free(ev);
+     }
+}
+
+static GSourceFuncs _event_source_funcs = {
+   .prepare = NULL,
+   .check = NULL,
+   .dispatch = NULL,
+   .finalize = NULL,
+};
+
+EINTERN E_Input_Event_Source *
+e_input_event_source_create(GMainContext *context)
+{
+   E_Input_Event_Source *source = (E_Input_Event_Source *)g_source_new(&_event_source_funcs, sizeof(E_Input_Event_Source));
+
+   source->ev_queue = g_queue_new();
+
+   return source;
+}
+
+EINTERN void
+e_input_event_source_destroy(E_Input_Event_Source *source)
+{
+   if (!source) return;
+
+   E_Input_Event *ev = NULL;
+   while ((ev = g_queue_pop_head(source->ev_queue)) != NULL)
+     {
+        if (ev->free_func)
+          ev->free_func(ev->free_func_data, ev->ev_data);
+        free(ev);
+     }
+
+   g_list_free(source->ev_handler_list);
+
+   /* should be flushed all events in ev_queue before free ev_queue */
+   g_queue_free(source->ev_queue);
+   g_source_destroy(&source->gsource);
+   g_source_unref(&source->gsource);
+}
+
+E_API E_Input_Event_Handler *
+e_input_event_handler_add(E_Input_Event_Source *source, int event, ev_handler_func func, void *user_data)
+{
+   if (!source) return NULL;
+
+   E_Input_Event_Handler *eh = (E_Input_Event_Handler *)calloc(1, sizeof(E_Input_Event_Handler));
+   eh->event = event;
+   eh->func = func;
+   eh->user_data = user_data;
+
+   source->ev_handler_list = g_list_append(source->ev_handler_list, eh);
+
+   return eh;
+}
+
+E_API E_Input_Event_Handler *
+e_input_event_handler_prepend(E_Input_Event_Source *source, int event, ev_handler_func func, void *user_data)
+{
+   if (!source) return NULL;
+
+   E_Input_Event_Handler *eh = (E_Input_Event_Handler *)calloc(1, sizeof(E_Input_Event_Handler));
+   eh->event = event;
+   eh->func = func;
+   eh->user_data = user_data;
+
+   source->ev_handler_list = g_list_prepend(source->ev_handler_list, eh);
+
+   return eh;
+}
+
+E_API void
+e_input_event_handler_del(E_Input_Event_Source *source, E_Input_Event_Handler *event_handler)
+{
+   if (!source) return;
+
+   source->ev_handler_list = g_list_remove(source->ev_handler_list, event_handler);
+   free(event_handler);
+}
+
+E_API E_Input_Event_Filter *
+e_input_event_filter_add(E_Input_Event_Source *source, int event, ev_handler_func func, void *user_data)
+{
+   if (!source) return NULL;
+
+   E_Input_Event_Filter *ef = (E_Input_Event_Filter *)calloc(1, sizeof(E_Input_Event_Filter));
+   ef->event = event;
+   ef->func = func;
+   ef->user_data = user_data;
+
+   source->ev_filter_list = g_list_append(source->ev_filter_list, ef);
+
+   return ef;
+}
+
+E_API void
+e_input_event_filter_del(E_Input_Event_Source *source, E_Input_Event_Filter *event_filter)
+{
+   if (source)
+     source->ev_filter_list = g_list_remove(source->ev_filter_list, event_filter);
+
+   free(event_filter);
+}
+
+static gboolean
+_process_filter_event(E_Input_Event_Source *ev_source, E_Input_Event *ev)
+{
+   GList *l;
+   E_Input_Event_Filter *ef;
+   void *data;
+
+   if (!ev_source || !ev) return TRUE;
+
+   for (l = ev_source->ev_filter_list, data = G_LIST_GET_DATA(l); l; \
+        l = g_list_next(l), data = G_LIST_GET_DATA(l))
+     {
+        ef = (E_Input_Event_Filter *)data;
+        if (ef && ef->event == ev->event_type)
+          {
+             if (ef->func)
+               {
+                  if (ef->func(ef->user_data, ef->event, ev->ev_data) == FALSE)
+                    return FALSE;
+               }
+          }
+     }
+
+   return TRUE;
+}
+
+static gboolean
+_process_event_handler(E_Input_Event_Source *ev_source, E_Input_Event *ev)
+{
+   GList *l;
+   E_Input_Event_Handler *eh = NULL;
+   void *data;
+
+   if (!ev_source || !ev) return TRUE;
+
+   for (l = ev_source->ev_handler_list, data = G_LIST_GET_DATA(l); l; \
+        l = g_list_next(l), data = G_LIST_GET_DATA(l))
+     {
+        eh = (E_Input_Event_Handler *)data;
+        if (eh && eh->event == ev->event_type)
+          {
+             if (eh->func)
+               {
+                  if (eh->func(eh->user_data, eh->event, ev->ev_data) == FALSE)
+                    return FALSE;
+               }
+          }
+     }
+
+   return TRUE;
+}
+
+static void
+_e_input_event_send(E_Input_Event_Source *source, E_Input_Event *ev)
+{
+   if (source)
+     g_queue_push_tail(source->ev_queue, ev);
+}
+
+E_API void
+e_input_event_add(E_Input_Event_Source *source, int event_type, void *ev_data, ev_free_func free_func, void *free_func_data)
+{
+   E_Input_Event *ev = (E_Input_Event *)calloc(1, sizeof(E_Input_Event));
+   ev->ev_data = ev_data;
+   ev->event_type = event_type;
+   ev->free_func = free_func;
+   ev->free_func_data = free_func_data;
+
+   _e_input_event_send(source, ev);
+}
diff --git a/src/bin/e_input_event.h b/src/bin/e_input_event.h
new file mode 100755 (executable)
index 0000000..8b75ec0
--- /dev/null
@@ -0,0 +1,63 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <glib-unix.h>
+#include "e.h"
+
+#ifndef E_INPUT_EVENT_H
+#define E_INPUT_EVENT_H
+
+typedef gboolean (*ev_handler_func)(void *func_data, int type, void *user_data);
+typedef void (*ev_free_func)(void *user_data, void *event_data);
+
+struct _e_input_event_handler {
+    int event;
+    ev_handler_func func;
+    void *func_data;
+    void *user_data;
+};
+
+struct _e_input_event_filter {
+    int event;
+    ev_handler_func func;
+    void *event_data;
+    void *user_data;
+};
+
+struct _e_input_event_source {
+    GSource gsource;
+
+    void *data;
+    GList *ev_handler_list;
+    GList *ev_filter_list;
+    GQueue *ev_queue;
+    GMutex *thread_mutex;
+};
+
+struct _e_input_event {
+    int event_type;
+    void *ev_data;
+    ev_free_func free_func;
+    void *free_func_data;
+};
+
+typedef struct _e_input_event_handler E_Input_Event_Handler;
+typedef struct _e_input_event_filter E_Input_Event_Filter;
+typedef struct _e_input_event_source E_Input_Event_Source;
+typedef struct _e_input_event E_Input_Event;
+
+EINTERN E_Input_Event_Source *e_input_event_source_create(GMainContext *context);
+EINTERN void e_input_event_source_destroy(E_Input_Event_Source *source);
+
+E_API E_Input_Event_Handler *e_input_event_handler_add(E_Input_Event_Source *source, int event, ev_handler_func func, void *user_data);
+E_API E_Input_Event_Handler *e_input_event_handler_prepend(E_Input_Event_Source *source, int event, ev_handler_func func, void *user_data);
+E_API void e_input_event_handler_del(E_Input_Event_Source *source, E_Input_Event_Handler *event_handler);
+
+E_API E_Input_Event_Filter *e_input_event_filter_add(E_Input_Event_Source *source, int event, ev_handler_func func, void *user_data);
+E_API void e_input_event_filter_del(E_Input_Event_Source *source, E_Input_Event_Filter *event_filter);
+
+E_API void e_input_event_add(E_Input_Event_Source *source, int event_type, void *ev_data, ev_free_func free_func, void *free_func_data);
+
+EINTERN void e_input_event_process(GSource *source);
+
+#endif /* E_INPUT_EVENT_H */
index fbbc94f..15a8812 100644 (file)
@@ -1,5 +1,26 @@
 #include "e.h"
 #include "e_input_private.h"
+#include "e_input_event.h"
+
+#include <glib.h>
+
+static gboolean input_dispatch(GSource *source, GSourceFunc callback, gpointer user_data);
+static gboolean input_thread_prepare(GSource *source, gint *time);
+
+static E_Input_Event_Source *g_input_event_source = NULL;
+
+GSourceFuncs input_event_funcs = {
+   .prepare = input_thread_prepare,
+   .check = NULL,
+   .dispatch = input_dispatch,
+   .finalize = NULL
+};
+
+typedef struct
+{
+   GSource gsource;
+   gpointer tag;
+} InputEventSource;
 
 static char *
 _e_input_ecore_device_class_to_string(Ecore_Device_Class clas)
@@ -72,10 +93,12 @@ _e_input_ecore_device_event(Ecore_Device *dev, const char* seat_name, Eina_Bool
    E_Input *e_input;
    const char *name, *identifier;
 
-   if (!(name = ecore_device_name_get(dev))) return;
-   if (!(identifier = ecore_device_identifier_get(dev))) return;
+   ecore_thread_main_loop_begin();
+
+   if (!(name = ecore_device_name_get(dev))) goto end;
+   if (!(identifier = ecore_device_identifier_get(dev))) goto end;
 
-   if (!(e = calloc(1, sizeof(Ecore_Event_Device_Info)))) return;
+   if (!(e = calloc(1, sizeof(Ecore_Event_Device_Info)))) goto end;
 
    e_input = e_input_get();
 
@@ -93,6 +116,9 @@ _e_input_ecore_device_event(Ecore_Device *dev, const char* seat_name, Eina_Bool
      ecore_event_add(ECORE_EVENT_DEVICE_ADD, e, _e_input_ecore_device_info_free, NULL);
    else
      ecore_event_add(ECORE_EVENT_DEVICE_DEL, e, _e_input_ecore_device_info_free, NULL);
+
+end:
+   ecore_thread_main_loop_end();
 }
 
 static E_Input_Seat *
@@ -100,12 +126,16 @@ _seat_create(E_Input_Backend *input, const char *seat)
 {
    E_Input_Seat *s;
    Ecore_Device *ecore_dev = NULL;
+   E_Device *e_dev = NULL;
+
+   ecore_thread_main_loop_begin();
 
    /* create an evas device of a seat */
    ecore_dev = ecore_device_add();
    if (!ecore_dev)
      {
         ERR("Failed to create an ecore device for a seat !\n");
+        ecore_thread_main_loop_end();
                return NULL;
      }
 
@@ -114,22 +144,39 @@ _seat_create(E_Input_Backend *input, const char *seat)
    ecore_device_class_set(ecore_dev, ECORE_DEVICE_CLASS_SEAT);
    ecore_device_subclass_set(ecore_dev, ECORE_DEVICE_SUBCLASS_NONE);
 
+   /* create an e device of a seat */
+   e_dev = e_device_new();
+   if (!e_dev)
+     {
+        ERR("Failed to create an ecore device for a seat !\n");
+        ecore_thread_main_loop_end();
+               return NULL;
+     }
+
+   e_device_name_set(e_dev, seat);
+   e_device_identifier_set(e_dev, "Enlightenment seat");
+   e_device_class_set(e_dev, ECORE_DEVICE_CLASS_SEAT);
+   e_device_subclass_set(e_dev, ECORE_DEVICE_SUBCLASS_NONE);
+
    /* try to allocate space for new seat */
    if (!(s = calloc(1, sizeof(E_Input_Seat))))
      {
         ecore_device_del(ecore_dev);
+        ecore_thread_main_loop_end();
         return NULL;
      }
 
    s->input = input;
    s->name = eina_stringshare_add(seat);
    s->ecore_dev = ecore_dev;
+   s->e_dev = e_dev;
 
    /* add this new seat to list */
    input->dev->seats = eina_list_append(input->dev->seats, s);
    s->dev = input->dev;
 
    ecore_event_add(E_INPUT_EVENT_SEAT_ADD, NULL, NULL, NULL);
+   ecore_thread_main_loop_end();
 
    _e_input_ecore_device_event(ecore_dev, seat, EINA_TRUE);
 
@@ -156,10 +203,13 @@ _e_input_add_ecore_device(E_Input_Evdev *edev, Ecore_Device_Class clas)
    const Eina_List *dev_list = NULL;
    const Eina_List *l;
    Ecore_Device *dev = NULL;
+   E_Device *e_dev = NULL;
    const char *identifier;
 
    if (!edev || !edev->path) return EINA_FALSE;
 
+   ecore_thread_main_loop_begin();
+
    dev_list = ecore_device_list();
    if (dev_list)
      {
@@ -169,14 +219,19 @@ _e_input_add_ecore_device(E_Input_Evdev *edev, Ecore_Device_Class clas)
              identifier = ecore_device_identifier_get(dev);
              if (!identifier) continue;
              if ((ecore_device_class_get(dev) == clas) && (!strcmp(identifier, edev->path)))
-               return EINA_FALSE;
+               {
+                  ecore_thread_main_loop_end();
+                  return EINA_FALSE;
+               }
           }
      }
 
+   // create ecore device info
    dev = ecore_device_add();
    if (!dev)
      {
         edev->ecore_dev = NULL;
+        ecore_thread_main_loop_end();
         return EINA_FALSE;
      }
 
@@ -207,8 +262,45 @@ _e_input_add_ecore_device(E_Input_Evdev *edev, Ecore_Device_Class clas)
         edev->ecore_dev_list = eina_list_append(edev->ecore_dev_list, ecore_device_ref(dev));
      }
 
+   // create E_Device info
+   e_dev = e_device_new();
+   if (!e_dev)
+     {
+        edev->e_dev = NULL;
+        ecore_thread_main_loop_end();
+        return EINA_FALSE;
+     }
+
+   e_device_name_set(e_dev, libinput_device_get_name(edev->device));
+   e_device_identifier_set(e_dev, edev->path);
+   e_device_class_set(e_dev, clas);
+   e_device_subclass_set(e_dev, ECORE_DEVICE_SUBCLASS_NONE);
+
+   if (!edev->e_dev)
+     {
+        if (!edev->e_dev_list || (g_list_length(edev->e_dev_list) == 0))
+          {
+             /* 1st Ecore_Device is added */
+             edev->e_dev = g_object_ref(e_dev);
+          }
+        else
+          {
+             /* 3rd or more Ecore_Device is added */
+             edev->e_dev_list = g_list_append(edev->e_dev_list, g_object_ref(e_dev));
+          }
+     }
+   else
+     {
+        /* 2nd Ecore_Device is added */
+        edev->e_dev_list = g_list_append(edev->e_dev_list, edev->e_dev);
+        edev->e_dev = NULL;
+
+        edev->e_dev_list = g_list_append(edev->e_dev_list, g_object_ref(e_dev));
+     }
+
    _e_input_ecore_device_event(dev, edev->seat ? edev->seat->name : NULL, EINA_TRUE);
 
+   ecore_thread_main_loop_end();
    return EINA_TRUE;
 }
 
@@ -224,6 +316,8 @@ _e_input_remove_ecore_device(E_Input_Evdev *edev, Ecore_Device_Class clas)
 
    dev_list = ecore_device_list();
    if (!dev_list) return EINA_FALSE;
+
+   ecore_thread_main_loop_begin();
    EINA_LIST_FOREACH(dev_list, l, dev)
       {
          if (!dev) continue;
@@ -249,9 +343,11 @@ _e_input_remove_ecore_device(E_Input_Evdev *edev, Ecore_Device_Class clas)
                 }
               _e_input_ecore_device_event(dev, edev->seat ? edev->seat->name : NULL, EINA_FALSE);
               ecore_device_del(dev);
+              ecore_thread_main_loop_end();
               return EINA_TRUE;
            }
       }
+   ecore_thread_main_loop_end();
    return EINA_FALSE;
 }
 
@@ -308,14 +404,19 @@ _e_input_device_remove(E_Input_Evdev *edev)
      {
         if (eina_list_count(edev->ecore_dev_list) > 0)
           {
+             ecore_thread_main_loop_begin();
              EINA_LIST_FREE(edev->ecore_dev_list, data)
                {
+
                   WRN("Invalid device is left. name: %s, identifier: %s, clas: %s\n",
                       ecore_device_name_get(data), ecore_device_identifier_get(data),
                       _e_input_ecore_device_class_to_string(ecore_device_class_get(data)));
+
                   ecore_device_unref(data);
                   ecore_device_del(data);
+
                }
+             ecore_thread_main_loop_end();
           }
         edev->ecore_dev_list = NULL;
      }
@@ -422,12 +523,34 @@ _input_events_process(E_Input_Backend *input)
      }
 }
 
-static Eina_Bool
-_cb_input_dispatch(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
+static gboolean
+input_thread_prepare(GSource *source, gint *time)
 {
-   E_Input_Backend *input;
+   /* flush pending client events */
+   e_comp_wl_display_flush();
+
+   if (time)
+     *time = -1;
 
-   if (!(input = data)) return EINA_TRUE;
+   return FALSE;
+}
+
+static gboolean
+input_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
+{
+   InputEventSource *src = (InputEventSource *)source;
+   E_Input_Backend *input = (E_Input_Backend *)user_data;
+   if (!src) return G_SOURCE_REMOVE;
+   if (!input) return G_SOURCE_REMOVE;
+
+   GIOCondition cond;
+   cond = g_source_query_unix_fd(source, src->tag);
+
+   if (cond & G_IO_ERR || cond & G_IO_HUP || cond & G_IO_NVAL)
+     {
+        INF("error cond(%d)\n", cond);
+        return G_SOURCE_CONTINUE;
+     }
 
    if (libinput_dispatch(input->libinput) != 0)
      ERR("Failed to dispatch libinput events: %m");
@@ -435,7 +558,85 @@ _cb_input_dispatch(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
    /* process pending events */
    _input_events_process(input);
 
-   return EINA_TRUE;
+   e_input_event_process((GSource *)input->event_source);
+
+   return G_SOURCE_CONTINUE;
+}
+
+static void
+input_thread_start(void *data, Ecore_Thread *th)
+{
+   E_Input_Backend *input;
+   GMainContext *context = NULL;
+   InputEventSource *input_event_source = NULL;
+
+   INF("input thread start");
+
+   if (!(input = data)) return;
+
+   eina_thread_name_set(eina_thread_self(), "input-thread");
+
+   //create a context
+   context = g_main_context_new();
+   g_main_context_push_thread_default(context);
+
+   input_event_source = (InputEventSource *)g_source_new(&input_event_funcs, sizeof(InputEventSource));
+   input_event_source->tag = g_source_add_unix_fd(&input_event_source->gsource, input->fd, G_IO_IN);
+
+   input->event_source = e_input_event_source_create(context);
+   //FIXME
+   g_input_event_source = input->event_source;
+
+   //create main loop
+   input->input_thread_loop = g_main_loop_new(context, FALSE);
+
+   //set the callback for this source
+   g_source_set_callback(&input_event_source->gsource, NULL, input, NULL);
+   g_source_attach(&input_event_source->gsource, context);
+
+   g_main_loop_run(input->input_thread_loop);
+}
+
+static void
+input_thread_feedback(void *data, Ecore_Thread *th, void *msgdata)
+{
+   E_Input_Backend *input;
+
+   INF("input thread start");
+
+   if (!(input = data)) return;
+}
+
+static void
+input_thread_end(void *data, Ecore_Thread *th)
+{
+   E_Input_Backend *input;
+
+   if (!(input = data)) return;
+   INF("input thread complete");
+
+   e_input_event_source_destroy(input->event_source);
+   input->event_source = NULL;
+
+   g_main_loop_quit(input->input_thread_loop);
+   g_main_loop_unref(input->input_thread_loop);
+   input->input_thread_loop = NULL;
+
+   if (th == input->input_thread)
+     input->input_thread = NULL;
+}
+
+static void
+input_thread_cancel(void *data, Ecore_Thread *th)
+{
+   E_Input_Backend *input;
+
+   if (!(input = data)) return;
+
+   INF("input thread cancel");
+
+   if (th == input->input_thread)
+     input->input_thread = NULL;
 }
 
 EINTERN Eina_Bool
@@ -446,34 +647,15 @@ e_input_enable_input(E_Input_Backend *input)
 
    input->fd = libinput_get_fd(input->libinput);
 
-   if (!input->hdlr)
-     {
-        input->hdlr =
-          ecore_main_fd_handler_add(input->fd, ECORE_FD_READ,
-                                    _cb_input_dispatch, input, NULL, NULL);
-     }
-
-   if (input->suspended)
-     {
-        if (libinput_resume(input->libinput) != 0)
-          goto err;
-
-        input->suspended = EINA_FALSE;
-
-        /* process pending events */
-        _input_events_process(input);
-     }
-
    input->enabled = EINA_TRUE;
    input->suspended = EINA_FALSE;
 
+   input->input_thread = ecore_thread_feedback_run(input_thread_start, input_thread_feedback, input_thread_end, input_thread_cancel, input, EINA_FALSE);
+
    return EINA_TRUE;
 
 err:
    input->enabled = EINA_FALSE;
-   if (input->hdlr)
-     ecore_main_fd_handler_del(input->hdlr);
-   input->hdlr = NULL;
 
    return EINA_FALSE;
 }
@@ -491,6 +673,9 @@ e_input_disable_input(E_Input_Backend *input)
    _input_events_process(input);
 
    input->suspended = EINA_TRUE;
+
+   if (input->input_thread && !ecore_thread_check(input->input_thread))
+     ecore_thread_cancel(input->input_thread);
 }
 
 EINTERN Eina_List *
@@ -499,3 +684,9 @@ e_input_seat_evdev_list_get(E_Input_Seat *seat)
    EINA_SAFETY_ON_NULL_RETURN_VAL(seat, NULL);
    return seat->devices;
 }
+
+E_API E_Input_Event_Source *
+e_input_event_source_get()
+{
+   return g_input_event_source;
+}
\ No newline at end of file
index e3dbd96..31a5e1c 100644 (file)
@@ -7,8 +7,11 @@
 
 #include "e.h"
 #include "e_input.h"
+#include "e_device.h"
+#include "e_input_event.h"
 #include <libinput.h>
 #include <Eeze.h>
+#include <glib.h>
 
 extern struct xkb_keymap *cached_keymap;
 extern struct xkb_context *cached_context;
@@ -41,6 +44,8 @@ struct _E_Input_Seat
         Eina_Bool invert_x;
         Eina_Bool invert_y;
      } ptr;
+
+   E_Device *e_dev;
 };
 
 struct _E_Input_Backend
@@ -56,12 +61,16 @@ struct _E_Input_Backend
    Eina_Bool left_handed : 1;
 
    Ecore_Thread *thread;
+   Ecore_Thread *input_thread;
    E_Input_Libinput_Backend backend;
 
    Eina_Bool log_disable : 1;
    Eina_Bool log_use_eina : 1;
 
    unsigned int path_ndevices;
+
+   GMainLoop *input_thread_loop;
+   E_Input_Event_Source *event_source;
 };
 
 struct _E_Input_Evdev
@@ -72,6 +81,8 @@ struct _E_Input_Evdev
    const char *path;
    Ecore_Device *ecore_dev;
    Eina_List *ecore_dev_list;
+   E_Device *e_dev;
+   GList *e_dev_list;
 
    int mt_slot;
 
index 658d8e0..4560d99 100644 (file)
@@ -1,6 +1,9 @@
 #include "e.h"
 #include "e_keyrouter.h"
 #include "e_keyrouter_private.h"
+#include "e_input_event.h"
+
+#include <glib.h>
 
 static int _e_keyrouter_intercept_hooks_delete = 0;
 static int _e_keyrouter_intercept_hooks_walking = 0;
@@ -269,40 +272,34 @@ _e_keyrouter_keygrab_print(void *data, const char *log_path)
    log_fl = NULL;
 }
 
-static Eina_Bool
+static gboolean
 _e_keyrouter_cb_key_down(void *data, int type, void *event)
 {
    Ecore_Event_Key *ev;
-   Eina_Bool res = ECORE_CALLBACK_PASS_ON;
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(event, ECORE_CALLBACK_PASS_ON);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(event, FALSE);
 
    ev = (Ecore_Event_Key *)event;
 
    TRACE_INPUT_BEGIN(_e_keyrouter_cb_key_down:KEY_PRESS(%d), ev->keycode);
    TRACE_INPUT_END();
 
-   res = e_keyrouter_event_process(event, type);
-   
-   return res;
+   return e_keyrouter_event_process(event, (E_Device *)ev->dev, type);
 }
 
-static Eina_Bool
+static gboolean
 _e_keyrouter_cb_key_up(void *data, int type, void *event)
 {
    Ecore_Event_Key *ev;
-   Eina_Bool res = ECORE_CALLBACK_PASS_ON;
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(event, ECORE_CALLBACK_PASS_ON);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(event, FALSE);
 
    ev = (Ecore_Event_Key *)event;
 
    TRACE_INPUT_BEGIN(_e_keyrouter_cb_key_down:KEY_RELEASE(%d), ev->keycode);
    TRACE_INPUT_END();
 
-   res = e_keyrouter_event_process(event, type);
-   
-   return res;
+   return e_keyrouter_event_process(event, (E_Device *)ev->dev, type);
 }
 
 static Eina_Bool
@@ -317,7 +314,7 @@ _e_keyrouter_client_cb_stack(void *data, int type, void *event)
    (void) ev;
    (void) ec;
 
-   //KLDBG("ec: %p, visibile: %d, focused: %d, take_focus: %d, want_focus: %d, bordername: %s, input_only: %d",
+   //KLDBG("ec: %p, visible: %d, focused: %d, take_focus: %d, want_focus: %d, bordername: %s, input_only: %d",
    //        ec, ec->visible, ec->focused, ec->take_focus, ec->want_focus, ec->bordername, ec->input_only);
 
    krt->isWindowStackChanged = EINA_TRUE;
@@ -346,10 +343,17 @@ _e_keyrouter_client_cb_remove(void *data, int type, void *event)
 static void
 _e_keyrouter_init_handlers(void)
 {
+   E_Input_Event_Source *input_event_source = NULL;
+
    E_LIST_HANDLER_APPEND(krt->handlers, E_EVENT_CLIENT_STACK, _e_keyrouter_client_cb_stack, NULL);
    E_LIST_HANDLER_APPEND(krt->handlers, E_EVENT_CLIENT_REMOVE, _e_keyrouter_client_cb_remove, NULL);
-   E_LIST_HANDLER_APPEND(krt->handlers, ECORE_EVENT_KEY_DOWN, _e_keyrouter_cb_key_down, NULL);
-   E_LIST_HANDLER_APPEND(krt->handlers, ECORE_EVENT_KEY_UP, _e_keyrouter_cb_key_up, NULL);
+
+   input_event_source = e_input_event_source_get();
+   if (input_event_source)
+     {
+        krt->_key_down_handler = e_input_event_handler_add(input_event_source, ECORE_EVENT_KEY_DOWN, _e_keyrouter_cb_key_down, NULL);
+        krt->_key_up_handler = e_input_event_handler_add(input_event_source, ECORE_EVENT_KEY_UP, _e_keyrouter_cb_key_up, NULL);
+     }
 
    e_info_server_hook_set("keyrouter", _e_keyrouter_info_print, NULL);
    e_info_server_hook_set("keygrab", _e_keyrouter_keygrab_print, NULL);
@@ -359,12 +363,26 @@ static void
 _e_keyrouter_deinit_handlers(void)
 {
    Ecore_Event_Handler *h = NULL;
+   E_Input_Event_Source *input_event_source = NULL;
 
    if (!krt ||  !krt->handlers) return;
 
    EINA_LIST_FREE(krt->handlers, h)
      ecore_event_handler_del(h);
 
+   input_event_source = e_input_event_source_get();
+   if (input_event_source)
+     {
+        if (krt->_key_down_handler)
+          e_input_event_handler_del(input_event_source, krt->_key_down_handler);
+
+        if (krt->_key_up_handler)
+          e_input_event_handler_del(input_event_source, krt->_key_up_handler);
+     }
+
+   krt->_key_down_handler = NULL;
+   krt->_key_up_handler = NULL;
+
    e_info_server_hook_set("keyrouter", NULL, NULL);
    e_info_server_hook_set("keygrab", NULL, NULL);
 }
@@ -684,15 +702,15 @@ e_keyrouter_shutdown(void)
    E_KEYROUTER_EVENT_KEY_COMPOSITION_PRESS = 0;
    E_KEYROUTER_EVENT_KEY_COMPOSITION_RELEASE = 0;
 
-   if (krt->composition_key.waiting_timer)
+   if (krt->composition_key.waiting_timer > 0)
      {
-        ecore_timer_del(krt->composition_key.waiting_timer);
-        krt->composition_key.waiting_timer = NULL;
+        g_source_remove(krt->composition_key.waiting_timer);
+        krt->composition_key.waiting_timer = 0;
      }
-   if (krt->longkey.timer)
+   if (krt->longkey.timer > 0)
      {
-        ecore_timer_del(krt->longkey.timer);
-        krt->longkey.timer = NULL;
+        g_source_remove(krt->longkey.timer);
+        krt->longkey.timer = 0;
      }
 
    e_keyrouter_wl_shutdown();
index 7544ea3..49232c4 100644 (file)
@@ -1,11 +1,11 @@
 #include "e_keyrouter_private.h"
 
-static void _e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev);
-static void _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev);
-static void _e_keyrouter_send_key_events_release(int type, 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, Eina_Bool focused, unsigned int mode);
+static void _e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev, E_Device *dev);
+static void _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev);
+static void _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev, E_Device *dev);
+static void _e_keyrouter_send_key_event(int type, struct wl_resource *surface, struct wl_client *wc, Ecore_Event_Key *ev, E_Device *dev, Eina_Bool focused, unsigned int mode);
 
-static Eina_Bool _e_keyrouter_send_key_events_focus(int type, struct wl_resource *surface, Ecore_Event_Key *ev, struct wl_resource **delivered_surface);
+static Eina_Bool _e_keyrouter_send_key_events_focus(int type, struct wl_resource *surface, Ecore_Event_Key *ev, E_Device *dev, struct wl_resource **delivered_surface);
 
 static Eina_Bool _e_keyrouter_is_key_grabbed(int key);
 static Eina_Bool _e_keyrouter_check_top_visible_window(E_Client *ec_focus, int arr_idx);
@@ -124,7 +124,7 @@ failed:
 }
 
 static void
-_e_keyrouter_key_send(int type, Ecore_Event_Key *ev, E_Keyrouter_Key_List_NodePtr key_node)
+_e_keyrouter_key_send(int type, Ecore_Event_Key *ev, E_Device *dev, E_Keyrouter_Key_List_NodePtr key_node)
 {
    Eina_Bool res_hook = EINA_TRUE;
    E_Keyrouter_Event_Data *key_data = NULL;
@@ -139,7 +139,7 @@ _e_keyrouter_key_send(int type, Ecore_Event_Key *ev, E_Keyrouter_Key_List_NodePt
              KLINF("This hook is called to notify a current key is cancel. Please check why hook returns FALSE or ignored.\n");
           }
      }
-   e_keyrouter_wl_key_send(ev, (type == ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE,
+   e_keyrouter_wl_key_send(ev, dev, (type == ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE,
                            key_node->wc, key_node->surface, key_node->focused);
 }
 
@@ -163,9 +163,9 @@ _e_keyrouter_key_cancel(int keycode)
 
    EINA_LIST_FREE(krt->HardKeys[keycode].press_ptr, key_node_data)
      {
-        _e_keyrouter_key_send(ECORE_EVENT_KEY_DOWN, key_cancel, key_node_data);
-        _e_keyrouter_key_send(ECORE_EVENT_KEY_UP, key_release, key_node_data);
-        _e_keyrouter_key_send(ECORE_EVENT_KEY_UP, key_cancel, key_node_data);
+        _e_keyrouter_key_send(ECORE_EVENT_KEY_DOWN, key_cancel, NULL, key_node_data);
+        _e_keyrouter_key_send(ECORE_EVENT_KEY_UP, key_release, NULL, key_node_data);
+        _e_keyrouter_key_send(ECORE_EVENT_KEY_UP, key_cancel, NULL, key_node_data);
 
         pid = e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface);
         cmd = e_keyrouter_util_cmd_get_from_pid(pid);
@@ -189,7 +189,7 @@ failed:
 }
 
 
-static Eina_Bool
+static gboolean
 _e_keyrouter_long_timer(void *data)
 {
    E_Keyrouter_Event_Key_Long *ev;
@@ -197,10 +197,10 @@ _e_keyrouter_long_timer(void *data)
    ev = E_NEW(E_Keyrouter_Event_Key_Long, 1);
    if (!ev)
      {
-        krt->longkey.timer = NULL;
+        krt->longkey.timer = 0;
         krt->longkey.key = 0;
 
-        return ECORE_CALLBACK_CANCEL;
+        return G_SOURCE_REMOVE;
      }
 
    ev->keycode = krt->longkey.key;
@@ -211,18 +211,18 @@ _e_keyrouter_long_timer(void *data)
    KLINF("LONGKEY : %s(%d) long press event is generated.\n",
          krt->HardKeys[krt->longkey.key].keyname, krt->longkey.key);
 
-   krt->longkey.timer = NULL;
+   krt->longkey.timer = 0;
 
    /* Cancel a longkey to prevent irregal operation */
-   if (krt->composition_key.waiting_timer)
+   if (krt->composition_key.waiting_timer > 0)
      {
-        ecore_timer_del(krt->composition_key.waiting_timer);
-        krt->composition_key.waiting_timer = NULL;
+        g_source_remove(krt->composition_key.waiting_timer);
+        krt->composition_key.waiting_timer = 0;
         krt->composition_key.key[0] = 0;
         krt->composition_key.key[1] = 0;
      }
 
-   return ECORE_CALLBACK_CANCEL;
+   return G_SOURCE_REMOVE;
 }
 
 static Eina_Bool
@@ -236,13 +236,14 @@ _e_keyrouter_long_check(int type, Ecore_Event_Key *ev)
           }
         else if (krt->HardKeys[ev->keycode].longkey.enabled)
           {
-             krt->longkey.timer = ecore_timer_add(krt->HardKeys[ev->keycode].longkey.time, _e_keyrouter_long_timer, NULL);
+             krt->longkey.timer = g_timeout_add(krt->HardKeys[ev->keycode].longkey.time*1000, _e_keyrouter_long_timer, NULL);
+
              krt->longkey.key = ev->keycode;
           }
      }
    else
      {
-        if (!krt->longkey.timer)
+        if (krt->longkey.timer == 0)
           {
              /* Already process a long press key. So ignore a long pressed key's release event */
              if (krt->longkey.key && krt->longkey.key == ev->keycode)
@@ -257,8 +258,8 @@ _e_keyrouter_long_check(int type, Ecore_Event_Key *ev)
         /* Current key event is a short press, so cancel a long press timer. */
         if (krt->longkey.key == ev->keycode)
           {
-             ecore_timer_del(krt->longkey.timer);
-             krt->longkey.timer = NULL;
+             g_source_remove(krt->longkey.timer);
+             krt->longkey.timer = 0;
              krt->longkey.key = 0;
           }
      }
@@ -290,15 +291,15 @@ _e_keyrouter_composition_key_event(Eina_Bool pressed)
      ecore_event_add(E_KEYROUTER_EVENT_KEY_COMPOSITION_RELEASE, ev, NULL, NULL);
 }
 
-static Eina_Bool
+static gboolean
 _e_keyrouter_composition_key_timer(void *data)
 {
    krt->composition_key.key[0] = 0;
    krt->composition_key.key[1] = 0;
 
-   krt->composition_key.waiting_timer = NULL;
+   krt->composition_key.waiting_timer = 0;
 
-   return ECORE_CALLBACK_CANCEL;
+   return G_SOURCE_REMOVE;
 }
 
 static Eina_Bool
@@ -318,14 +319,15 @@ _e_keyrouter_composition_key_check(int type, Ecore_Event_Key *ev)
                     {
                        krt->composition_key.key[1] = ev->keycode;
 
-                       ecore_timer_del(krt->composition_key.waiting_timer);
-                       krt->composition_key.waiting_timer = NULL;
+                       g_source_remove(krt->composition_key.waiting_timer);
+                       krt->composition_key.waiting_timer = 0;
 
                        /* Cancel a longkey to prevent irregal operation */
                        if (krt->longkey.timer)
                          {
-                            ecore_timer_del(krt->longkey.timer);
-                            krt->longkey.timer = NULL;
+                            //ecore_timer_del(krt->longkey.timer);
+                            g_source_remove(krt->longkey.timer);
+                            krt->longkey.timer = 0;
                             krt->longkey.key = 0;
                          }
 
@@ -337,10 +339,10 @@ _e_keyrouter_composition_key_check(int type, Ecore_Event_Key *ev)
                }
 
              /* Not modkey is pressed, cancel current modkey process */
-             if (krt->composition_key.waiting_timer)
+             if (krt->composition_key.waiting_timer > 0)
                {
-                  ecore_timer_del(krt->composition_key.waiting_timer);
-                  krt->composition_key.waiting_timer = NULL;
+                  g_source_remove(krt->composition_key.waiting_timer);
+                  krt->composition_key.waiting_timer = 0;
                   krt->composition_key.key[0] = 0;
                   krt->composition_key.key[1] = 0;
                }
@@ -350,7 +352,7 @@ _e_keyrouter_composition_key_check(int type, Ecore_Event_Key *ev)
              if (eina_list_count(krt->HardKeys[ev->keycode].composition_key_list) > 0)
                {
                   krt->composition_key.key[0] = ev->keycode;
-                  krt->composition_key.waiting_timer = ecore_timer_add(krt->composition_key.waiting_time, _e_keyrouter_composition_key_timer, NULL);
+                  krt->composition_key.waiting_timer = g_timeout_add(krt->composition_key.waiting_time*1000, _e_keyrouter_composition_key_timer, NULL);
                }
           }
      }
@@ -385,8 +387,8 @@ _e_keyrouter_composition_key_check(int type, Ecore_Event_Key *ev)
         /* Not modkey, just key short press */
         if (krt->composition_key.key[0] == ev->keycode)
           {
-             ecore_timer_del(krt->composition_key.waiting_timer);
-             krt->composition_key.waiting_timer = NULL;
+             g_source_remove(krt->composition_key.waiting_timer);
+             krt->composition_key.waiting_timer = 0;
              krt->composition_key.key[0] = 0;
 
              return ECORE_CALLBACK_PASS_ON;
@@ -399,7 +401,7 @@ _e_keyrouter_composition_key_check(int type, Ecore_Event_Key *ev)
 
 /* Function for checking the existing grab for a key and sending key event(s) */
 Eina_Bool
-e_keyrouter_event_process(void *event, int type)
+e_keyrouter_event_process(void *event, E_Device *dev, int type)
 {
    Eina_Bool res = EINA_FALSE;
    Ecore_Event_Key *ev = event;
@@ -419,7 +421,7 @@ e_keyrouter_event_process(void *event, int type)
 
    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);
+        e_keyrouter_wl_key_send(ev, dev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_FALSE);
         return EINA_TRUE;
      }
 
@@ -434,7 +436,7 @@ e_keyrouter_event_process(void *event, int type)
         if (key_data->ignored) goto finish;
         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);
+             e_keyrouter_wl_key_send(ev, dev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_FALSE);
              goto finish;
           }
      }
@@ -445,18 +447,18 @@ e_keyrouter_event_process(void *event, int type)
 
    //KLDBG("The key(%d) is going to be sent to the proper wl client(s) !", ev->keycode);
    KLDBG("[%s] keyname: %s, key: %s, keycode: %d", (type == ECORE_EVENT_KEY_DOWN) ? "KEY_PRESS" : "KEY_RELEASE", ev->keyname, ev->key, ev->keycode);
-   _e_keyrouter_send_key_events(type, ev);
+   _e_keyrouter_send_key_events(type, ev, dev);
    return EINA_FALSE;
 
 focus_deliver:
-   res = e_comp_wl_key_process(event, type);
+   res = e_comp_wl_key_process(event, dev, type);
 finish:
    return res;
 }
 
 /* Function for sending key events to wl_client(s) */
 static void
-_e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev)
+_e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev, E_Device *dev)
 {
    int pid = 0, keycode = 0;
    char *pname = NULL, *cmd = NULL;
@@ -471,7 +473,7 @@ _e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev)
           {
              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);
+                  _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, dev, 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);
@@ -502,16 +504,16 @@ _e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev)
 
    if (ECORE_EVENT_KEY_DOWN == type)
      {
-        _e_keyrouter_send_key_events_press(type, ev);
+        _e_keyrouter_send_key_events_press(type, ev, dev);
      }
    else
      {
-        _e_keyrouter_send_key_events_release(type, ev);
+        _e_keyrouter_send_key_events_release(type, ev, dev);
      }
 }
 
 static void
-_e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev)
+_e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev, E_Device *dev)
 {
    int pid = 0;
    char *pname = NULL, *cmd = NULL;
@@ -536,7 +538,7 @@ _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev)
                     }
                   if (key_data->surface || key_data->client)
                     {
-                       _e_keyrouter_send_key_event(type, key_data->surface, key_data->client, ev,
+                       _e_keyrouter_send_key_event(type, key_data->surface, key_data->client, ev, dev,
                                                    EINA_FALSE, TIZEN_KEYROUTER_MODE_PRESSED);
 
                        pid = e_keyrouter_util_get_pid(key_data->client, key_data->surface);
@@ -562,7 +564,7 @@ _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev)
 
         if (key_node_data->status == E_KRT_CSTAT_ALIVE)
           {
-             _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev,
+             _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, dev,
                                          key_node_data->focused, TIZEN_KEYROUTER_MODE_PRESSED);
 
              pid = e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface);
@@ -587,7 +589,7 @@ _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev)
 }
 
 static void
-_e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev)
+_e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev)
 {
    unsigned int keycode = ev->keycode;
    struct wl_resource *surface_focus = NULL;
@@ -606,7 +608,7 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev)
 
    if (!_e_keyrouter_is_key_grabbed(ev->keycode))
      {
-        _e_keyrouter_send_key_events_focus(type, surface_focus, ev, &delivered_surface);
+        _e_keyrouter_send_key_events_focus(type, surface_focus, ev, dev, &delivered_surface);
         return;
      }
 
@@ -614,7 +616,7 @@ _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->surface, key_node_data->wc, ev,
+             _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, dev,
                                         key_node_data->focused, TIZEN_KEYROUTER_MODE_EXCLUSIVE);
 
              pid = e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface);
@@ -633,7 +635,7 @@ _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->surface, key_node_data->wc, ev,
+             _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, dev,
                                          key_node_data->focused, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE);
 
              pid = e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface);
@@ -662,7 +664,7 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev)
                        cmd = e_keyrouter_util_cmd_get_from_pid(pid);
                        pname = e_keyrouter_util_process_name_get_from_cmd(cmd);
 
-                       _e_keyrouter_send_key_event(type, key_node_data->surface, NULL, ev, key_node_data->focused,
+                       _e_keyrouter_send_key_event(type, key_node_data->surface, NULL, ev, dev, key_node_data->focused,
                                                    TIZEN_KEYROUTER_MODE_TOPMOST);
                        KLINF("TOPMOST (TOP_POSITION) : %s (%s:%d) => wl_surface (%p) (pid: %d) (pname: %s)",
                                 ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode,
@@ -681,7 +683,7 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev)
                        cmd = e_keyrouter_util_cmd_get_from_pid(pid);
                        pname = e_keyrouter_util_process_name_get_from_cmd(cmd);
 
-                       _e_keyrouter_send_key_event(type, top_key_node_data->surface, NULL, ev, top_key_node_data->focused,
+                       _e_keyrouter_send_key_event(type, top_key_node_data->surface, NULL, ev, dev, top_key_node_data->focused,
                                                    TIZEN_KEYROUTER_MODE_TOPMOST);
                        KLINF("TOPMOST (TOP_POSITION) : %s (%s:%d) => wl_surface (%p) (pid: %d) (pname: %s)",
                              ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode,
@@ -700,7 +702,7 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev)
    if (krt->HardKeys[keycode].shared_ptr)
      {
 need_shared:
-        res = _e_keyrouter_send_key_events_focus(type, surface_focus, ev, &delivered_surface);
+        res = _e_keyrouter_send_key_events_focus(type, surface_focus, ev, dev, &delivered_surface);
         if (delivered_surface)
           {
              ret = e_keyrouter_wl_add_surface_destroy_listener(delivered_surface);
@@ -723,7 +725,7 @@ need_shared:
                          }
                        else
                          {
-                            _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, key_node_data->focused, TIZEN_KEYROUTER_MODE_SHARED);
+                            _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, dev, 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);
@@ -739,7 +741,7 @@ need_shared:
 }
 
 static Eina_Bool
-_e_keyrouter_send_key_events_focus(int type, struct wl_resource *surface_focus,  Ecore_Event_Key *ev, struct wl_resource **delivered_surface)
+_e_keyrouter_send_key_events_focus(int type, struct wl_resource *surface_focus,  Ecore_Event_Key *ev, E_Device *dev, struct wl_resource **delivered_surface)
 {
    Eina_Bool res = EINA_TRUE;
    int pid = 0;
@@ -759,7 +761,7 @@ _e_keyrouter_send_key_events_focus(int type, struct wl_resource *surface_focus,
           {
              *delivered_surface = key_data->surface;
              e_keyrouter_prepend_to_keylist(key_data->surface, key_data->client, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, EINA_TRUE);
-             res = e_keyrouter_wl_key_send(ev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_FALSE);
+             res = e_keyrouter_wl_key_send(ev, dev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_FALSE);
 
              pid = e_keyrouter_util_get_pid(NULL, key_data->surface);
              cmd = e_keyrouter_util_cmd_get_from_pid(pid);
@@ -784,7 +786,7 @@ _e_keyrouter_send_key_events_focus(int type, struct wl_resource *surface_focus,
    cmd = e_keyrouter_util_cmd_get_from_pid(pid);
    pname = e_keyrouter_util_process_name_get_from_cmd(cmd);
 
-   _e_keyrouter_send_key_event(type, surface_focus, NULL,ev, EINA_TRUE, TIZEN_KEYROUTER_MODE_SHARED);
+   _e_keyrouter_send_key_event(type, surface_focus, NULL,ev, dev, EINA_TRUE, TIZEN_KEYROUTER_MODE_SHARED);
    KLINF("FOCUS DIRECT : %s(%s:%d) => wl_surface (%p) (pid: %d) (pname: %s)",
          ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode, surface_focus, pid, pname ?: "Unknown");
    *delivered_surface = surface_focus;
@@ -844,7 +846,7 @@ _e_keyrouter_check_top_visible_window(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, struct wl_resource *surface, struct wl_client *wc, Ecore_Event_Key *ev, Eina_Bool focused, unsigned int mode)
+_e_keyrouter_send_key_event(int type, struct wl_resource *surface, struct wl_client *wc, Ecore_Event_Key *ev, E_Device *dev, Eina_Bool focused, unsigned int mode)
 {
    struct wl_client *wc_send;
    Eina_Bool pressed = EINA_FALSE;
@@ -864,7 +866,7 @@ _e_keyrouter_send_key_event(int type, struct wl_resource *surface, struct wl_cli
         e_keyrouter_prepend_to_keylist(surface, wc, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, focused);
      }
 
-   e_keyrouter_wl_key_send(ev, pressed, wc_send, surface, focused);
+   e_keyrouter_wl_key_send(ev, dev, pressed, wc_send, surface, focused);
 
    return;
 }
index c775f3f..46010f1 100644 (file)
@@ -1,5 +1,6 @@
 #include "e.h"
 #include "e_keyrouter.h"
+#include "e_input_event.h"
 #ifdef HAVE_CYNARA
 #include <cynara-session.h>
 #include <cynara-client.h>
@@ -74,16 +75,19 @@ struct _E_Keyrouter
 
    struct
      {
-        Ecore_Timer *waiting_timer;
+        gint waiting_timer;
         double waiting_time;
 
         int key[2];
      } composition_key;
    struct
      {
-        Ecore_Timer *timer;
+        gint timer;
         int key;
      } longkey;
+
+   E_Input_Event_Handler *_key_down_handler;
+   E_Input_Event_Handler *_key_up_handler;
 };
 
 struct _E_Keyrouter_Grab_Request {
@@ -126,9 +130,9 @@ Eina_Bool e_keyrouter_wl_util_do_privilege_check(struct wl_client *client, uint3
 int e_keyrouter_keygrab_set(struct wl_client *client, struct wl_resource *surface, int key, int mode);
 int e_keyrouter_keygrab_unset(struct wl_client *client, struct wl_resource *surface, int key);
 
-Eina_Bool e_keyrouter_event_process(void *event, int type);
+Eina_Bool e_keyrouter_event_process(void *event, E_Device *dev, int type);
 
-Eina_Bool e_keyrouter_wl_key_send(Ecore_Event_Key *ev, Eina_Bool pressed, struct wl_client *client, struct wl_resource *surface, Eina_Bool focused);
+Eina_Bool e_keyrouter_wl_key_send(Ecore_Event_Key *ev, E_Device *dev, Eina_Bool pressed, struct wl_client *client, struct wl_resource *surface, Eina_Bool focused);
 void e_keyrouter_keycancel_send(struct wl_client *client, struct wl_resource *surface, unsigned int key);
 void e_keyrouter_wl_event_surface_send(struct wl_resource *surface, int key, int mode);
 
index 57cf32a..6d89682 100644 (file)
@@ -23,7 +23,7 @@ e_keyrouter_wl_event_surface_send(struct wl_resource *surface, int key, int 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)
+_e_keyrouter_wl_key_send(Ecore_Event_Key *ev, E_Device *dev, 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;
    Eina_List *l;
@@ -47,7 +47,8 @@ _e_keyrouter_wl_key_send(Ecore_Event_Key *ev, enum wl_keyboard_key_state state,
         wc = wl_resource_get_client(res);
         if (!focused && wc != client) continue;
         TRACE_INPUT_BEGIN(_e_comp_wl_key_send);
-        e_comp_wl_send_event_device(client, ev->timestamp, ev->dev, serial);
+        if (dev)
+          e_comp_wl_send_event_e_device(client, ev->timestamp, dev, serial);
 
         if (comp_conf && comp_conf->input_log_enable)
           INF("[Server] Routed Key %s (time: %d)\n", (state ? "Down" : "Up"), ev->timestamp);
@@ -59,7 +60,7 @@ _e_keyrouter_wl_key_send(Ecore_Event_Key *ev, enum wl_keyboard_key_state state,
 }
 
 Eina_Bool
-e_keyrouter_wl_key_send(Ecore_Event_Key *ev, Eina_Bool pressed, struct wl_client *client, struct wl_resource *surface, Eina_Bool focused)
+e_keyrouter_wl_key_send(Ecore_Event_Key *ev, E_Device *dev, Eina_Bool pressed, struct wl_client *client, struct wl_resource *surface, Eina_Bool focused)
 {
    E_Client *ec = NULL;
    struct wl_client *wc = NULL;
@@ -92,7 +93,7 @@ e_keyrouter_wl_key_send(Ecore_Event_Key *ev, Eina_Bool pressed, struct wl_client
 
    if (!focused)
      {
-        _e_keyrouter_wl_key_send(ev, state, e_comp_wl->kbd.resources, EINA_FALSE, client, surface);
+        _e_keyrouter_wl_key_send(ev, dev, state, e_comp_wl->kbd.resources, EINA_FALSE, client, surface);
         return EINA_FALSE;
      }
 
@@ -104,7 +105,7 @@ e_keyrouter_wl_key_send(Ecore_Event_Key *ev, Eina_Bool pressed, struct wl_client
              if (e_comp_wl->kbd.focused)
                {
                   wc = wl_resource_get_client(ec->comp_data->surface);
-                  _e_keyrouter_wl_key_send(ev, state, e_comp_wl->kbd.focused, EINA_TRUE, wc, surface);
+                  _e_keyrouter_wl_key_send(ev, dev, state, e_comp_wl->kbd.focused, EINA_TRUE, wc, surface);
                }
 
              /* update modifier state */
@@ -644,9 +645,9 @@ e_keyrouter_wl_shutdown(void)
 
    EINA_LIST_FREE(krt->resources, resource)
      wl_resource_destroy(resource);
+
    if (krt->global) wl_global_destroy(krt->global);
-   
+
 #ifdef HAVE_CYNARA
    if (krt->p_cynara) cynara_finish(krt->p_cynara);
 #endif