e_input_evdev: generate touch ecore event asynchronously 25/318925/2
authorJihoon Kim <jihoon48.kim@samsung.com>
Thu, 26 Sep 2024 02:43:44 +0000 (11:43 +0900)
committerJihoon Kim <jihoon48.kim@samsung.com>
Mon, 28 Oct 2024 03:06:08 +0000 (12:06 +0900)
Change-Id: Ib9203fb7cba2947dca2c67472549bee2162cf12f
Signed-off-by: Jihoon Kim <jihoon48.kim@samsung.com>
src/bin/e_input_evdev.c

index 722d55f89a88b9299ede5462ed28f0552e856882..aa7d12b7efd7a7570772006a560f2896e596d73f 100644 (file)
@@ -16,6 +16,15 @@ struct _E_Input_Pending_Event {
    void *event;
 };
 
+typedef struct _E_Input_Event
+{
+   E_Input_Evdev *evdev;
+   int event_type;
+   void *ev;
+   ev_free_func free_func;
+   void *free_func_data;
+} E_Input_Event_Info;
+
 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);
 static void  _device_output_assign(E_Input_Evdev *edev, E_Input_Seat_Capabilities cap);
@@ -1682,6 +1691,39 @@ end:
 }
 #endif
 
+static Ecore_Device *
+_touch_device_get(E_Input_Evdev *evdev)
+{
+   Ecore_Device *ecore_dev = NULL, *data;
+   Eina_List *l;
+
+   if (evdev->ecore_dev) ecore_dev = evdev->ecore_dev;
+   else if (evdev->ecore_dev_list && eina_list_count(evdev->ecore_dev_list) > 0)
+     {
+        EINA_LIST_FOREACH(evdev->ecore_dev_list, l, data)
+          {
+             if (ecore_device_class_get(data) == ECORE_DEVICE_CLASS_TOUCH)
+               {
+                  ecore_dev = data;
+                  break;
+               }
+          }
+     }
+   else
+     {
+        evdev->ecore_dev = e_input_evdev_get_ecore_device(evdev->path, ECORE_DEVICE_CLASS_TOUCH);
+        ecore_dev = evdev->ecore_dev;
+     }
+
+   if (!ecore_dev)
+     {
+        ERR("Failed to get source ecore device from event !\n");
+        return NULL;
+     }
+
+   return ecore_dev;
+}
+
 static Eina_Bool
 _touch_event_pending_add(E_Input_Evdev *edev, int type, void *event)
 {
@@ -1698,6 +1740,51 @@ _touch_event_pending_add(E_Input_Evdev *edev, int type, void *event)
    return EINA_TRUE;
 }
 
+static void
+_touch_ecore_event_add(void *data)
+{
+   E_Input_Event_Info *input_info = data;
+   Ecore_Device *ecore_dev = NULL;
+
+   ecore_dev = _touch_device_get(input_info->evdev);
+
+   if (input_info->event_type == ECORE_EVENT_MOUSE_MOVE)
+     {
+        Ecore_Event_Mouse_Move *ev = input_info->ev;
+        ev->dev = ecore_device_ref(ecore_dev);
+     }
+   else if (input_info->event_type == ECORE_EVENT_MOUSE_BUTTON_DOWN ||
+            input_info->event_type == ECORE_EVENT_MOUSE_BUTTON_UP ||
+            input_info->event_type == ECORE_EVENT_MOUSE_BUTTON_CANCEL)
+     {
+        Ecore_Event_Mouse_Button *ev = input_info->ev;
+        ev->dev = ecore_device_ref(ecore_dev);
+     }
+
+   ecore_event_add(input_info->event_type, input_info->ev, input_info->free_func, input_info->free_func_data);
+
+   free(input_info);
+}
+
+static void
+_input_thread_ecore_event_add(E_Input_Evdev *evdev, int event_type, void *ev, ev_free_func free_func, void *free_func_data)
+{
+   E_Input_Backend *input;
+   E_Input_Event_Info *input_event = NULL;
+
+   if (!(input = evdev->seat->input))
+     return;
+
+   input_event = E_NEW(E_Input_Event_Info, 1);
+   input_event->evdev = evdev;
+   input_event->event_type = event_type;
+   input_event->ev = ev;
+   input_event->free_func = free_func;
+   input_event->free_func_data = free_func_data;
+
+   ecore_main_loop_thread_safe_call_async(_touch_ecore_event_add, input_event);
+}
+
 static void
 _touch_event_pending_flush(E_Input_Evdev *edev)
 {
@@ -1727,39 +1814,11 @@ _device_handle_touch_event_send(E_Input_Evdev *edev, struct libinput_event_touch
    E_Input_Backend *input;
    Ecore_Event_Mouse_Button *ev;
    uint32_t timestamp, button = 0;
-   Ecore_Device *ecore_dev = NULL, *data;
-   Eina_List *l;
 
    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)
-     {
-        EINA_LIST_FOREACH(edev->ecore_dev_list, l, data)
-          {
-             if (ecore_device_class_get(data) == ECORE_DEVICE_CLASS_TOUCH)
-               {
-                  ecore_dev = data;
-                  break;
-               }
-          }
-     }
-   else
-     {
-        edev->ecore_dev = e_input_evdev_get_ecore_device(edev->path, ECORE_DEVICE_CLASS_TOUCH);
-        ecore_dev = edev->ecore_dev;
-     }
-
-   if (!ecore_dev)
-     {
-        ERR("Failed to get source ecore device from event !\n");
-        goto end;
-     }
-
-   if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)))) goto end;
+   if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)))) return;
 
    timestamp = libinput_event_touch_get_time(event);
 
@@ -1801,7 +1860,6 @@ _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;
-   ev->dev = ecore_device_ref(ecore_dev);
 
    if (state == ECORE_EVENT_MOUSE_BUTTON_DOWN)
      {
@@ -1847,11 +1905,9 @@ _device_handle_touch_event_send(E_Input_Evdev *edev, struct libinput_event_touch
      {
         ELOGF("Touch", "Failed to pend event (%s). Call ecore_event_add imediately.", NULL,
               state == ECORE_EVENT_MOUSE_BUTTON_DOWN ? "DOWN" : "UP");
-        ecore_event_add(state, ev, _e_input_event_mouse_button_cb_free, NULL);
-     }
 
-end:
-   ecore_thread_main_loop_end();
+        _input_thread_ecore_event_add(edev, state, ev, _e_input_event_mouse_button_cb_free, NULL);
+     }
 }
 
 static void
@@ -1859,39 +1915,11 @@ _device_handle_touch_motion_send(E_Input_Evdev *edev, struct libinput_event_touc
 {
    E_Input_Backend *input;
    Ecore_Event_Mouse_Move *ev;
-   Ecore_Device *ecore_dev = NULL, *data;
-   Eina_List *l;
 
    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)
-     {
-        EINA_LIST_FOREACH(edev->ecore_dev_list, l, data)
-          {
-             if (ecore_device_class_get(data) == ECORE_DEVICE_CLASS_TOUCH)
-               {
-                  ecore_dev = data;
-                  break;
-               }
-          }
-     }
-   else
-     {
-        edev->ecore_dev = e_input_evdev_get_ecore_device(edev->path, ECORE_DEVICE_CLASS_TOUCH);
-        ecore_dev = edev->ecore_dev;
-     }
-
-   if (!ecore_dev)
-     {
-        ERR("Failed to get source ecore device from event !\n");
-        goto end;
-     }
-
-   if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Move)))) goto end;
+   if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Move)))) return;
 
    ev->window = (Ecore_Window)input->dev->window;
    ev->event_window = (Ecore_Window)input->dev->window;
@@ -1927,16 +1955,12 @@ _device_handle_touch_motion_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);
 
    if (!_touch_event_pending_add(edev, ECORE_EVENT_MOUSE_MOVE, ev))
      {
-        ELOGF("Touch", "Failed to pend event (MOVE). Call ecore_event_add imediately.", NULL);
-        ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, _e_input_event_mouse_move_cb_free, NULL);
+        ELOGF("Touch", "Failed to pend event (MOVE). Call ecore_event_add immediately.", NULL);
+        _input_thread_ecore_event_add(edev, ECORE_EVENT_MOUSE_MOVE, ev, _e_input_event_mouse_move_cb_free, NULL);
      }
-
-end:
-   ecore_thread_main_loop_end();
 }
 
 static void
@@ -1945,39 +1969,11 @@ _device_handle_touch_cancel_send(E_Input_Evdev *edev, struct libinput_event_touc
    E_Input_Backend *input;
    Ecore_Event_Mouse_Button *ev;
    uint32_t timestamp, button = 0;
-   Ecore_Device *ecore_dev = NULL, *data;
-   Eina_List *l;
 
    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)
-     {
-        EINA_LIST_FOREACH(edev->ecore_dev_list, l, data)
-          {
-             if (ecore_device_class_get(data) == ECORE_DEVICE_CLASS_TOUCH)
-               {
-                  ecore_dev = data;
-                  break;
-               }
-          }
-     }
-   else
-     {
-        edev->ecore_dev = e_input_evdev_get_ecore_device(edev->path, ECORE_DEVICE_CLASS_TOUCH);
-        ecore_dev = edev->ecore_dev;
-     }
-
-   if (!ecore_dev)
-     {
-        ERR("Failed to get source ecore device from event !\n");
-        goto end;
-     }
-
-   if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)))) goto end;
+   if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)))) return;
 
    timestamp = libinput_event_touch_get_time(event);
 
@@ -2006,16 +2002,12 @@ _device_handle_touch_cancel_send(E_Input_Evdev *edev, struct libinput_event_touc
    edev->touch.pressed &= ~(1 << ev->multi.device);
 
    ev->buttons = ((button & 0x00F) + 1);
-   ev->dev = ecore_device_ref(ecore_dev);
 
    if (!_touch_event_pending_add(edev, ECORE_EVENT_MOUSE_BUTTON_CANCEL, ev))
      {
         ELOGF("Touch", "Failed to pend event (CANCEL). Call ecore_event_add imediately.", NULL);
-        ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_CANCEL, ev, _e_input_event_mouse_button_cb_free, NULL);
+        _input_thread_ecore_event_add(edev, ECORE_EVENT_MOUSE_BUTTON_CANCEL, ev, _e_input_event_mouse_button_cb_free, NULL);
      }
-
-end:
-   ecore_thread_main_loop_end();
 }
 
 static void
@@ -2308,6 +2300,14 @@ _device_handle_touch_cancel(struct libinput_device *device, struct libinput_even
    _device_handle_touch_cancel_send(edev, event);
 }
 
+static void
+_touch_frame_event_add(void *data)
+{
+   E_Input_Evdev *evdev = data;
+
+   _touch_event_pending_flush(evdev);
+   ecore_event_add(E_EVENT_INPUT_TOUCH_FRAME, NULL, NULL, NULL);
+}
 
 static void
 _device_handle_touch_frame(struct libinput_device *device, struct libinput_event_touch *event)
@@ -2317,11 +2317,7 @@ _device_handle_touch_frame(struct libinput_device *device, struct libinput_event
    if (!(edev = libinput_device_get_user_data(device)))
      return;
 
-   ecore_thread_main_loop_begin();
-   _touch_event_pending_flush(edev);
-   ecore_event_add(E_EVENT_INPUT_TOUCH_FRAME, NULL, NULL, NULL);
-
-   ecore_thread_main_loop_end();
+   ecore_main_loop_thread_safe_call_async(_touch_frame_event_add, edev);
 }
 
 static void