input: send mouse move to focused_ec thru input thread 12/317412/1
authorJihoon Kim <jihoon48.kim@samsung.com>
Wed, 14 Aug 2024 06:40:43 +0000 (15:40 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Tue, 10 Sep 2024 04:21:17 +0000 (13:21 +0900)
Change-Id: If0df018aec957ef635b205fa3f22fe62cf8b9ea4
Signed-off-by: Duna Oh <duna.oh@samsung.com>
14 files changed:
src/bin/Makefile.mk
src/bin/core/e_client.c
src/bin/debug/e_info_client.c
src/bin/debug/e_info_server.c
src/bin/inputmgr/e_input_backend.c
src/bin/inputmgr/e_input_evdev.c
src/bin/inputmgr/e_input_intern.h
src/bin/inputmgr/e_input_thread_client.c
src/bin/server/e_comp_wl.c
src/bin/server/e_comp_wl_input_thread.c [new file with mode: 0644]
src/bin/server/e_comp_wl_input_thread_intern.h [new file with mode: 0644]
src/bin/server/e_comp_wl_intern.h
src/bin/windowmgr/e_pointer.c
src/include/e_client.h

index 7f1c843..4c6085a 100644 (file)
@@ -156,6 +156,7 @@ src/bin/server/e_compositor.c \
 src/bin/server/e_comp_wl.c \
 src/bin/server/e_comp_wl_data.c \
 src/bin/server/e_comp_wl_input.c \
+src/bin/server/e_comp_wl_input_thread.c \
 src/bin/server/e_comp_wl_subsurface.c \
 src/bin/server/e_comp_wl_tbm.c \
 src/bin/server/e_comp_wl_renderer.c \
index 3335dc8..c82c8d4 100644 (file)
@@ -1881,7 +1881,8 @@ _e_client_under_pointer_input_helper(E_Desk *desk, int x, int y)
 
    E_CLIENT_REVERSE_FOREACH(cec)
      {
-        if (_e_client_under_pointer_helper_ignore_client(desk, cec)) continue;
+        Eina_Bool ignore_client = _e_client_under_pointer_helper_ignore_client(desk, cec);
+        if (ignore_client) continue;
 
         Eina_List *list = NULL;
         Eina_Rectangle *rect;
@@ -8647,6 +8648,7 @@ e_client_vkbd_vkbd_get(E_Client *ec)
    if (!ec) return EINA_FALSE;
    return ec->vkbd.vkbd;
 }
+
 /////////////////////////////////////////////////////////
 EINTERN E_Comp_Wl_Subsurf_Data *
 e_client_subsurface_data_try_get(E_Client *ec)
index a5cf34c..dada26b 100644 (file)
@@ -6752,6 +6752,30 @@ err:
    printf("%s", USAGE_VIDEO_SHELL);
 }
 
+static void
+_e_info_client_proc_pointer_thread_mode(int argc, char **argv)
+{
+   int set = 0;
+   Eina_Bool res;
+
+   EINA_SAFETY_ON_FALSE_GOTO(argc == 3, usage);
+
+   set = atoi(argv[2]);
+   if ((set != 0) && (set != 1))
+     goto usage;
+
+   res = _e_info_client_eldbus_message_with_args("pointer_thread_mode", NULL, "i", set);
+   EINA_SAFETY_ON_FALSE_RETURN(res);
+
+   goto finish;
+
+usage :
+   printf("Usage: %s -pointer_thread_mode [0:unset(default), 1:set(input thread)]\n", argv[0]);
+
+finish:
+   return;
+}
+
 typedef struct _ProcInfo
 {
    const char *option;
@@ -7225,6 +7249,12 @@ ProcInfo procs_to_input[] =
       "Print key events elapsed time (default path:/tmp/elapsed_time.txt)", /* Description */
       _e_info_client_proc_key_elapsed_time /* func */
    },
+   {
+      "pointer_thread_mode",
+      "[0:unset(default), 1:set(input thread)]",
+      "Set/Unset pointer_thread_mode",
+      _e_info_client_proc_pointer_thread_mode
+   },
 };
 
 static Eina_List *list_tracelogs = NULL;
index e266c6d..92357f7 100644 (file)
@@ -7386,6 +7386,30 @@ _e_info_server_cb_key_elapsed_time(const Eldbus_Service_Interface *iface EINA_UN
    return reply;
 }
 
+static Eldbus_Message *
+_e_info_server_cb_pointer_thread_mode(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
+{
+   Eldbus_Message *reply = eldbus_message_method_return_new(msg);
+   int set = 0;
+
+   if (!eldbus_message_arguments_get(msg, "i", &set))
+     {
+        ERR("Failed to get argument");
+        return reply;
+     }
+
+   if (set)
+     {
+        e_input_pointer_thread_mode_set(EINA_TRUE);
+     }
+   else
+     {
+        e_input_pointer_thread_mode_set(EINA_FALSE);
+     }
+
+   return reply;
+}
+
 //{ "method_name", arguments_from_client, return_values_to_client, _method_cb, ELDBUS_METHOD_FLAG },
 static const Eldbus_Method methods[] = {
    { "get_window_info", NULL, ELDBUS_ARGS({"iiisiiia("VALUE_TYPE_FOR_TOPVWINS")", "array of ec"}), _e_info_server_cb_window_info_get, 0 },
@@ -7488,6 +7512,7 @@ static const Eldbus_Method methods[] = {
    { VIDEO_SHELL_BORDER_METHOD_NAME, ELDBUS_ARGS({"b", "The command for border of video viewport"}), NULL, _e_info_server_cb_video_shell_border, 0},
    { VIDEO_SHELL_INFO_METHOD_NAME, ELDBUS_ARGS({"s", "Print video shell information"}), NULL, _e_info_server_cb_video_shell_info, 0},
    { "key_elapsed_time", ELDBUS_ARGS({"i", "key elapsed time"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_key_elapsed_time, 0},
+   { "pointer_thread_mode", ELDBUS_ARGS({"i", "set pointer_thread_mode"}), NULL, _e_info_server_cb_pointer_thread_mode, 0 },
    { NULL, NULL, NULL, NULL, 0 }
 };
 
index b6c026b..30599e3 100644 (file)
@@ -44,6 +44,7 @@ static E_Input_Event_Source *g_input_event_source = NULL;
 static GList *_key_event_list = NULL;
 static GList *_elapsed_time_list = NULL;
 static int _print_count = 0;
+static Eina_Bool g_pointer_thread_mode = EINA_FALSE;
 
 GSourceFuncs input_event_funcs = {
    .prepare = input_thread_prepare,
@@ -1983,3 +1984,16 @@ e_input_backend_key_elapsed_time_print(int count)
 {
    e_input_backend_thread_safe_call(_e_input_thread_cb_print_count_set, &count, sizeof(int));
 }
+
+EINTERN Eina_Bool
+e_input_pointer_thread_mode_get()
+{
+   return g_pointer_thread_mode;
+}
+
+EINTERN void
+e_input_pointer_thread_mode_set(Eina_Bool set)
+{
+   g_pointer_thread_mode = set;
+}
+
index 55b79eb..46aaad6 100644 (file)
@@ -465,7 +465,13 @@ _e_input_event_mouse_move_cb_free(void *data EINA_UNUSED, void *event)
 {
    Ecore_Event_Mouse_Move *ev = event;
 
-   if (ev->dev) ecore_device_unref(ev->dev);
+   if (ev->dev)
+     {
+        if (e_input_thread_mode_get() && e_input_pointer_thread_mode_get())
+          g_object_unref(ev->dev);
+        else
+          ecore_device_unref(ev->dev);
+     }
 
    free(ev);
 }
@@ -816,23 +822,16 @@ e_input_evdev_handle_key(E_Input_Evdev *evdev, struct libinput_event_keyboard *e
    if (tmp) free(tmp);
 }
 
-static void
-_device_pointer_motion(E_Input_Evdev *evdev, struct libinput_event_pointer *event)
+static Ecore_Device *
+_device_pointer_send_motion(E_Input_Evdev *evdev)
 {
    E_Input_Backend *input;
-   Ecore_Event_Mouse_Move *ev;
    Ecore_Device *ecore_dev = NULL, *data, *detent_data = NULL;
    Eina_List *l;
    const char *device_name = NULL;
-   uint32_t timestamp = 0;
-
-   if (!(input = evdev->seat->input)) return;
-
-   ecore_thread_main_loop_begin();
 
+   if (!(input = evdev->seat->input)) return NULL;
    device_name = evdev->name;
-   if (event)
-     timestamp = libinput_event_pointer_get_time(event);
 
    if (evdev->ecore_dev) ecore_dev = evdev->ecore_dev;
    else if (evdev->ecore_dev_list && eina_list_count(evdev->ecore_dev_list) > 0)
@@ -863,14 +862,85 @@ _device_pointer_motion(E_Input_Evdev *evdev, struct libinput_event_pointer *even
    if (!ecore_dev)
      {
         ERR("Failed to get source ecore device from event !\n");
-        goto end;
+        return NULL;
      }
    else if ((detent_data == ecore_dev) || e_devicemgr_detent_is_detent(ecore_device_name_get(ecore_dev)))
      {
         /* Do not process detent device's move events. */
-        goto end;
+        return NULL;
      }
 
+   return ecore_dev;
+}
+
+static E_Device *
+_device_pointer_send_motion_thread_mode(E_Input_Evdev *evdev)
+{
+   E_Input_Backend *input;
+   E_Device *e_dev = NULL, *e_dev_data, *detent_data = NULL;
+   GList *glist = NULL;
+   const char *device_name = NULL;
+
+   if (!(input = evdev->seat->input)) return NULL;
+   device_name = evdev->name;
+
+   if (evdev->e_dev) e_dev = evdev->e_dev;
+   else if (evdev->e_dev_list && g_list_length(evdev->e_dev_list) > 0)
+     {
+        glist = evdev->e_dev_list;
+        while (glist)
+          {
+             e_dev_data = glist->data;
+             if (e_device_class_get(e_dev_data) == ECORE_DEVICE_CLASS_MOUSE)
+               {
+                  e_dev = e_dev_data;
+                  break;
+               }
+             else if (e_device_class_get(e_dev_data) == ECORE_DEVICE_CLASS_NONE)
+               {
+                  detent_data = e_dev_data;
+                  break;
+               }
+          }
+        if (!e_dev && e_devicemgr_detent_is_detent(device_name))
+          {
+             e_dev = detent_data;
+          }
+     }
+   else
+     {
+        evdev->e_dev = e_input_evdev_e_device_get(evdev->path, ECORE_DEVICE_CLASS_MOUSE);
+        e_dev = evdev->e_dev;
+     }
+
+   if (!e_dev)
+     {
+        ERR("Failed to get source ecore device from event !\n");
+        return NULL;
+     }
+   else if ((detent_data == e_dev) || e_devicemgr_detent_is_detent(e_device_name_get(e_dev)))
+     {
+        /* Do not process detent device's move events. */
+        return NULL;
+     }
+
+   return e_dev;
+}
+
+static void
+_device_pointer_motion(E_Input_Evdev *evdev, struct libinput_event_pointer *event)
+{
+   Ecore_Device *ecore_dev = NULL;
+   E_Device *e_dev = NULL;
+   Ecore_Event_Mouse_Move *ev;
+   E_Input_Backend *input;
+   uint32_t timestamp = 0;
+   const char *device_name = evdev->name;
+
+   if (!(input = evdev->seat->input)) return;
+   if (event)
+     timestamp = libinput_event_pointer_get_time(event);
+
    if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Move)))) return;
 
    evdev->mouse.dx = evdev->seat->ptr.dx;
@@ -897,7 +967,7 @@ _device_pointer_motion(E_Input_Evdev *evdev, struct libinput_event_pointer *even
      {
         ev->timestamp = e_util_timestamp_get();
         ELOGF("Mouse", "Move (x: %d, y: %d, timestamp: %u (current time), device: %s)", NULL,
-              ev->x, ev->y, ev->timestamp, ecore_device_name_get(ecore_dev));
+              ev->x, ev->y, ev->timestamp, device_name);
      }
 
    ev->multi.device = evdev->mt_slot;
@@ -911,12 +981,22 @@ _device_pointer_motion(E_Input_Evdev *evdev, struct libinput_event_pointer *even
    ev->multi.root.x = ev->x;
    ev->multi.root.y = ev->y;
 
-   ev->dev = ecore_device_ref(ecore_dev);
+   if (e_input_thread_mode_get() && e_input_pointer_thread_mode_get())
+     {
+        e_dev = _device_pointer_send_motion_thread_mode(evdev);
+        ev->dev = (Eo *)g_object_ref(e_dev);
+        e_input_event_add(input->event_source, ECORE_EVENT_MOUSE_MOVE, ev, _e_input_event_mouse_move_cb_free, NULL);
+     }
+   else
+     {
+        ecore_thread_main_loop_begin();
 
-   ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, _e_input_event_mouse_move_cb_free, NULL);
+        ecore_dev = _device_pointer_send_motion(evdev);
+        ev->dev = ecore_device_ref(ecore_dev);
+        ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, _e_input_event_mouse_move_cb_free, NULL);
 
-end:
-   ecore_thread_main_loop_end();
+        ecore_thread_main_loop_end();
+     }
 }
 
 void
index 7b8616d..e0764e3 100644 (file)
@@ -69,4 +69,7 @@ EINTERN void      e_input_main_thread_connection_unlock(GMutex *mutex);
 
 EINTERN void e_input_hook_call(E_Input_Hook_Point hookpoint, const char *device_name);
 
+EINTERN Eina_Bool e_input_pointer_thread_mode_get();
+EINTERN void e_input_pointer_thread_mode_set(Eina_Bool set);
+
 #endif
index e528266..3d7c4da 100644 (file)
@@ -375,8 +375,7 @@ EINTERN Eina_Inlist * e_input_thread_client_Inlist_get(E_Client *ec)
 
 EINTERN Eina_Bool e_input_thread_check_client_cloning_needed()
 {
-   // Disable cloning of e_client data temporarily.
-   return EINA_FALSE;
+   return EINA_TRUE;
 }
 
 E_API E_Input_Thread_Client *e_input_thread_client_above_get(E_Input_Thread_Client *iec)
index f11dd25..5da962e 100644 (file)
@@ -22,6 +22,7 @@
 #include "e_comp_wl_viewport_intern.h"
 #include "e_comp_intern.h"
 #include "e_input_backend_intern.h"
+#include "e_input_event_intern.h"
 #include "e_keyrouter_wl_intern.h"
 #include "e_error_intern.h"
 #include "e_pointer_intern.h"
 #include "e_comp_input_intern.h"
 #include "e_blur_intern.h"
 #include "e_input_thread_client_intern.h"
+#include "e_input_thread_client.h"
 #include "e_display_intern.h"
 #include "e_devicemgr_wl_intern.h"
 #include "e_view_client_intern.h"
+#include "e_comp_wl_input_thread_intern.h"
 
 #include <tizen-extension-server-protocol.h>
 #include <relative-pointer-unstable-v1-server-protocol.h>
@@ -150,6 +153,8 @@ static Eina_Inlist *_e_comp_wl_intercept_hooks[] =
 static Eina_List *hooks = NULL;
 static Eina_Bool serial_trace_debug = 0;
 
+static E_Input_Hook *input_hook = NULL;
+
 /* local functions */
 static void
 _e_comp_wl_hooks_clean(void)
@@ -1511,17 +1516,13 @@ _e_comp_wl_send_touch_frame(E_Client *ec)
    e_comp_wl_touch_frame_send_ec_set(NULL);
 }
 
-static void
-_e_comp_wl_send_mouse_move(E_Client *ec, int x, int y, unsigned int timestamp)
+EINTERN void
+e_comp_wl_surface_send_mouse_move(struct wl_resource *surface, int x, int y, int client_x, int client_y, unsigned int timestamp)
 {
    struct wl_resource *res;
    struct wl_client *wc;
    Eina_List *l;
 
-   if (!ec) return;
-   if (ec->cur_mouse_action) return;
-   if (e_object_is_del(E_OBJECT(ec))) return;
-   struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
    if (!surface) return;
 
    wc = wl_resource_get_client(surface);
@@ -1530,12 +1531,22 @@ _e_comp_wl_send_mouse_move(E_Client *ec, int x, int y, unsigned int timestamp)
         if (!e_comp_wl_input_pointer_check(res)) continue;
         if (wl_resource_get_client(res) != wc) continue;
         wl_pointer_send_motion(res, timestamp,
-                               wl_fixed_from_int(x - ec->client.x),
-                               wl_fixed_from_int(y - ec->client.y));
+                               wl_fixed_from_int(x - client_x),
+                               wl_fixed_from_int(y - client_y));
      }
 }
 
 static void
+_e_comp_wl_send_mouse_move(E_Client *ec, int x, int y, unsigned int timestamp)
+{
+   if (!ec) return;
+   if (ec->cur_mouse_action) return;
+   if (e_object_is_del(E_OBJECT(ec))) return;
+   struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
+   e_comp_wl_surface_send_mouse_move(surface, x, y, ec->client.x, ec->client.y, timestamp);
+}
+
+static void
 _e_comp_wl_cursor_move_timer_control(E_Client *ec)
 {
    if (e_comp_wl->ptr.hide_tmr)
@@ -1567,6 +1578,7 @@ _e_comp_wl_evas_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
    Evas_Device *dev = NULL;
    const char *dev_name;
    E_Comp_Config *comp_conf;
+   Evas_Device_Class dev_class;
 
    ev = event;
 
@@ -1583,6 +1595,7 @@ _e_comp_wl_evas_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
 
    dev = ev->dev;
    dev_name = evas_device_description_get(dev);
+   dev_class = evas_device_class_get(dev);
 
    comp_conf = e_comp_config_get();
    if (comp_conf && comp_conf->input_log_enable)
@@ -1590,7 +1603,7 @@ _e_comp_wl_evas_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
            ec, obj, ev->timestamp, ev->cur.canvas.x, ev->cur.canvas.y, ev->cur.output.x, ev->cur.output.y,
            e_client_util_name_get(ec), dev_name);
 
-   if (dev && (evas_device_class_get(dev) == EVAS_DEVICE_CLASS_TOUCH))
+   if (dev && (dev_class == EVAS_DEVICE_CLASS_TOUCH))
      {
         if (!e_comp_wl->drag_client)
           {
@@ -1599,7 +1612,7 @@ _e_comp_wl_evas_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
                {
                   _e_comp_wl_device_send_event_device(ec, dev, ev->timestamp);
                   if (dev_name)
-                    _e_comp_wl_device_handle_axes(dev_name, evas_device_class_get(dev),
+                    _e_comp_wl_device_handle_axes(dev_name, dev_class,
                                                   ec, 0, ev->radius_x, ev->radius_y, ev->pressure, ev->angle);
                   _e_comp_wl_send_touch_move(ec, 0, ev->cur.canvas.x, ev->cur.canvas.y, ev->timestamp);
                }
@@ -3668,6 +3681,13 @@ _e_comp_wl_gl_shutdown(void)
    E_FREE(e_comp_wl->evas_gl);
 }
 
+static void
+_e_comp_wl_cb_input_thread_start(void *data, const char *device_name)
+{
+    INF("Input thread hook cb ");
+    e_comp_wl_input_thread_add_e_input_handlers();
+}
+
 /* public functions */
 
 /**
@@ -3712,6 +3732,20 @@ e_comp_wl_init(void)
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_SCREEN_CHANGE,            _e_comp_wl_cb_randr_change,        NULL);
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_COMP_OBJECT_ADD,         _e_comp_wl_cb_comp_object_add,     NULL);
    E_LIST_HANDLER_PREPEND(handlers, ECORE_EVENT_MOUSE_MOVE,          _e_comp_wl_cb_mouse_move,          NULL);
+   if (e_input_thread_mode_get())
+     {
+        if (e_input_thread_id_get())
+          {
+             ERR("Input thread is ready. add handlers");
+             e_comp_wl_input_thread_add_e_input_handlers();
+          }
+        else
+          {
+             ERR("Input thread is not ready YET. add hook");
+             input_hook = e_input_hook_add(E_INPUT_HOOK_INPUT_THREAD_START,
+                                 (E_Input_Hook_Cb)_e_comp_wl_cb_input_thread_start, NULL);
+          }
+     }
    E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_RELATIVE_MOVE,  _e_comp_wl_cb_mouse_relative_move, NULL);
    E_LIST_HANDLER_PREPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_CANCEL, _e_comp_wl_cb_mouse_button_cancel, NULL);
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DISPLAY_STATE_CHANGE, _e_comp_wl_cb_zone_display_state_change, NULL);
@@ -3748,6 +3782,11 @@ e_comp_wl_shutdown(void)
    /* free handlers */
    E_FREE_LIST(handlers, ecore_event_handler_del);
    E_FREE_LIST(hooks, e_client_hook_del);
+
+   if (e_input_thread_mode_get())
+     e_input_hook_del(input_hook);
+
+   e_comp_wl_input_thread_remove_e_input_handlers();
    _e_comp_wl_gl_shutdown();
 
    e_comp_wl_capture_shutdown();
diff --git a/src/bin/server/e_comp_wl_input_thread.c b/src/bin/server/e_comp_wl_input_thread.c
new file mode 100644 (file)
index 0000000..56d7fe6
--- /dev/null
@@ -0,0 +1,173 @@
+#include "e_comp_wl_intern.h"
+#include "e_input.h"
+#include "e_input_intern.h"
+#include "e_comp_wl_input_intern.h"
+#include "e_input_event_intern.h"
+#include "e_input_thread_client_intern.h"
+#include "e_input_thread_client.h"
+
+static E_Input_Event_Handler *_mouse_move_handler = NULL;
+static Eina_Bool e_input_handlers_added = EINA_FALSE;
+
+static Eina_Bool
+_e_input_thread_client_under_pointer_helper_ignore_client(E_Input_Thread_Client *iec)
+{
+   /* If a border was specified which should be excluded from the list
+    * (because it will be closed shortly for example), skip */
+   E_Visibility vis = e_input_thread_client_visibility_get(iec);
+   if (vis != E_VISIBILITY_UNOBSCURED &&
+       vis != E_VISIBILITY_PARTIALLY_OBSCURED)
+      return EINA_TRUE;
+
+   if (e_input_thread_client_cursor_mode_get(iec)) return EINA_TRUE;
+
+   return EINA_FALSE;
+}
+
+static E_Input_Thread_Client *
+_e_comp_wl_input_thread_client_under_pointer(int x, int y)
+{
+   E_Input_Thread_Client *iec, *target_iec = NULL;
+   Eina_Bool inside = EINA_FALSE;
+   int cx, cy, cw, ch;
+   Eina_Bool ignore_client = EINA_FALSE;
+   GList *input_region_list = NULL;
+   Eina_Rectangle *rect;
+   int ir_x, ir_y, ir_w, ir_h;
+
+   for (iec = e_input_thread_client_top_get(); iec; iec = e_input_thread_client_below_get(iec))
+     {
+        ignore_client = _e_input_thread_client_under_pointer_helper_ignore_client(iec);
+
+        if (ignore_client) continue;
+
+        e_input_thread_client_geometry_get(iec, &cx, &cy, &cw, &ch);
+        e_input_thread_client_input_region_get(iec, &input_region_list);
+        if (input_region_list)
+          {
+            for (GList *list = g_list_first(input_region_list); list; list = list->next)
+               {
+                  rect = (Eina_Rectangle *)list->data;
+
+                  ir_x = rect->x;
+                  ir_y = rect->y;
+                  ir_w = rect->w;
+                  ir_h = rect->h;
+
+                  if (E_INSIDE(x, y, ir_x, ir_y, ir_w, ir_h))
+                    {
+                       inside = EINA_TRUE;
+                    }
+               }
+          }
+        else if (E_INSIDE(x, y, cx, cy, cw, ch))
+          {
+             inside = EINA_TRUE;
+          }
+
+        if (!inside) continue;
+        else
+          {
+             target_iec = iec;
+             break;
+          }
+     }
+
+   return target_iec;
+}
+
+static Eina_Bool
+_e_comp_wl_cb_mouse_move_thread_mode(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
+{
+   Ecore_Event_Mouse_Move *ev = event;
+   E_Input_Thread_Client *iec;
+   E_Comp_Config *comp_conf;
+   E_Device *dev = NULL;
+   const char *dev_name;
+   Ecore_Device_Class dev_class;
+   int client_x = 0, client_y = 0;
+
+   e_comp_wl->ptr.x = wl_fixed_from_int(ev->x);
+   e_comp_wl->ptr.y = wl_fixed_from_int(ev->y);
+
+   ELOGF("Mouse", "E Event Mouse Move (time: %d, x:%d y:%d)", NULL, ev->timestamp, ev->x, ev->y);
+
+   if (!e_input_pointer_thread_mode_get()) return ECORE_CALLBACK_RENEW;
+
+   iec = _e_comp_wl_input_thread_client_under_pointer(ev->x, ev->y);
+   if (!iec)
+     return ECORE_CALLBACK_RENEW;
+
+   struct wl_resource *surface = e_input_thread_client_wl_resource_get(iec);
+   if (!surface)
+     {
+        ELOGF("Mouse", "Move. surface NULL", NULL);
+        goto err;
+     }
+
+   dev = (E_Device *)ev->dev;
+   dev_name = e_device_name_get(dev);
+   dev_class = e_device_class_get(dev);
+
+   comp_conf = e_comp_config_get();
+   if (comp_conf && comp_conf->input_log_enable)
+     ELOGF("Mouse", "Move (time: %d, output(%d, %d), name:%20s) (dev:%s, device class:%d)",
+           NULL, ev->timestamp, ev->x, ev->y,
+           e_input_thread_client_util_name_get(iec), dev_name, dev_class);
+
+   e_input_thread_client_geometry_get(iec, &client_x, &client_y, NULL, NULL);
+
+   e_comp_wl_surface_send_mouse_move(surface, ev->x, ev->y, client_x, client_y, ev->timestamp);
+
+   e_pointer_mouse_move(e_comp->pointer, ev->x, ev->y);
+
+err:
+   return ECORE_CALLBACK_RENEW;
+}
+
+EINTERN void
+e_comp_wl_input_thread_add_e_input_handlers()
+{
+   E_Input_Event_Source *input_event_source = NULL;
+
+   if (e_input_handlers_added == EINA_TRUE)
+     return;
+
+   if (e_input_thread_mode_get())
+     {
+        input_event_source = e_input_event_source_get();
+        if (input_event_source)
+          {
+             INF("Succeeded to get input_event_source");
+             if (!_mouse_move_handler)
+               _mouse_move_handler = e_input_event_handler_add(input_event_source, ECORE_EVENT_MOUSE_MOVE, _e_comp_wl_cb_mouse_move_thread_mode, NULL);
+
+             e_input_handlers_added = EINA_TRUE;
+          }
+     }
+   else
+     ERR("Input source is NULL. handlers not added yet");
+}
+
+EINTERN void
+e_comp_wl_input_thread_remove_e_input_handlers()
+{
+   E_Input_Event_Source *input_event_source = NULL;
+
+   if (e_input_handlers_added == EINA_TRUE)
+     return;
+
+   if (e_input_thread_mode_get())
+     {
+        input_event_source = e_input_event_source_get();
+        if (input_event_source)
+          {
+             INF("Succeeded to get input_event_source");
+             e_input_event_handler_del(input_event_source, _mouse_move_handler);
+
+             _mouse_move_handler = NULL;
+          }
+     }
+   else
+     ERR("Input source is NULL. handlers not added yet");
+}
diff --git a/src/bin/server/e_comp_wl_input_thread_intern.h b/src/bin/server/e_comp_wl_input_thread_intern.h
new file mode 100644 (file)
index 0000000..ceed3a6
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef E_COMP_WL_INPUT_THREAD_INTERN_H
+#define E_COMP_WL_INPUT_THREAD_INTERN_H
+
+#include "e_intern.h"
+
+EINTERN void e_comp_wl_input_thread_add_e_input_handlers();
+EINTERN void e_comp_wl_input_thread_remove_e_input_handlers();
+
+#endif
index 737bb6c..2cce630 100644 (file)
@@ -105,4 +105,6 @@ EINTERN void      e_comp_wl_move_resize_shutdown(void);
 
 EINTERN void      e_comp_wl_trace_serial_debug(Eina_Bool on);
 
+EINTERN void      e_comp_wl_surface_send_mouse_move(struct wl_resource *surface, int x, int y, int client_x, int client_y, unsigned int timestamp);
+
 #endif
index 0492460..6571f18 100644 (file)
@@ -525,6 +525,13 @@ e_pointer_touch_move(E_Pointer *ptr, int x, int y)
    _e_pointer_hook_call(E_POINTER_HOOK_TOUCH_MOVE, ptr);
 }
 
+static void
+_pointer_position_update(void *data)
+{
+   E_Pointer *ptr = data;
+   _e_pointer_position_update(ptr);
+}
+
 E_API void
 e_pointer_mouse_move(E_Pointer *ptr, int x, int y)
 {
@@ -538,7 +545,7 @@ e_pointer_mouse_move(E_Pointer *ptr, int x, int y)
 
    if (ptr->device != E_POINTER_MOUSE) ptr->device = E_POINTER_MOUSE;
 
-   _e_pointer_position_update(ptr);
+   ecore_main_loop_thread_safe_call_async(_pointer_position_update, ptr);
 
    _e_pointer_hook_call(E_POINTER_HOOK_MOUSE_MOVE, ptr);
 }
index 773b19f..5a2c338 100644 (file)
@@ -1412,6 +1412,7 @@ E_API void      e_client_vkbd_floating_state_set(E_Client *ec, Eina_Bool set);
 E_API Eina_Bool e_client_vkbd_floating_state_get(E_Client *ec);
 E_API void      e_client_vkbd_vkbd_set(E_Client *ec, Eina_Bool set);
 E_API Eina_Bool e_client_vkbd_vkbd_get(E_Client *ec);
+
 /////////////////////////////////////////////////////////
 
 #endif