From a0dd8501aacc56e95636ca9139f6b029d127a837 Mon Sep 17 00:00:00 2001 From: Jihoon Kim Date: Wed, 21 Aug 2024 10:49:24 +0900 Subject: [PATCH] input: send mouse down and up event in input thread Change-Id: I04759e3a2423658049929d852568b8c79247fd5c Signed-off-by: Jihoon Kim --- src/bin/inputmgr/e_input_evdev.c | 76 +++++++----------- src/bin/server/e_comp_wl.c | 64 +++++++++------ src/bin/server/e_comp_wl_input_thread.c | 133 ++++++++++++++++++++++++++++++++ src/bin/server/e_comp_wl_intern.h | 1 + 4 files changed, 201 insertions(+), 73 deletions(-) diff --git a/src/bin/inputmgr/e_input_evdev.c b/src/bin/inputmgr/e_input_evdev.c index 46aaad6..6abf033 100644 --- a/src/bin/inputmgr/e_input_evdev.c +++ b/src/bin/inputmgr/e_input_evdev.c @@ -501,7 +501,13 @@ _e_input_event_mouse_button_cb_free(void *data EINA_UNUSED, void *event) { Ecore_Event_Mouse_Button *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); } @@ -1261,8 +1267,8 @@ e_input_evdev_handle_button(E_Input_Evdev *evdev, struct libinput_event_pointer Ecore_Event_Mouse_Button *ev; enum libinput_button_state state; uint32_t button, timestamp; - Ecore_Device *ecore_dev = NULL, *detent_data = NULL, *data; - Eina_List *l; + Ecore_Device *ecore_dev = NULL; + E_Device *e_dev = NULL; E_Comp_Config *comp_conf = NULL; const char *device_name = NULL; @@ -1278,40 +1284,6 @@ e_input_evdev_handle_button(E_Input_Evdev *evdev, struct libinput_event_pointer timestamp = libinput_event_pointer_get_time(event); device_name = evdev->name; - ecore_thread_main_loop_begin(); - - 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_MOUSE) - { - ecore_dev = data; - break; - } - else if (ecore_device_class_get(data) == ECORE_DEVICE_CLASS_NONE) - { - detent_data = data; - } - } - if (!ecore_dev && e_devicemgr_detent_is_detent(device_name)) - { - ecore_dev = detent_data; - } - } - else - { - evdev->ecore_dev = e_input_evdev_ecore_device_get(evdev->path, ECORE_DEVICE_CLASS_MOUSE); - ecore_dev = evdev->ecore_dev; - } - - if (!ecore_dev) - { - ERR("Failed to get source ecore device from event !\n"); - goto end; - } - button = ((button & 0x00F) + 1); if (button == 3) button = 2; else if (button == 2) button = 3; @@ -1324,9 +1296,9 @@ e_input_evdev_handle_button(E_Input_Evdev *evdev, struct libinput_event_pointer (evdev->seat->dev->server_blocked & E_INPUT_SEAT_POINTER)) { ELOGF("Mouse", "Button Press (btn: %d, device: %s) is blocked by %p, server: 0x%x", NULL, - button, ecore_device_name_get(ecore_dev), blocked_client, + button, device_name, blocked_client, evdev->seat->dev->server_blocked); - goto end; + return; } else { @@ -1338,16 +1310,16 @@ e_input_evdev_handle_button(E_Input_Evdev *evdev, struct libinput_event_pointer if (!(evdev->mouse.pressed_button & (1 << button))) { ELOGF("Mouse", "Button Release (btn: %d, device: %s) is blocked by %p, server: 0x%x", NULL, - button, ecore_device_name_get(ecore_dev), blocked_client, + button, device_name, blocked_client, evdev->seat->dev->server_blocked); - goto end; + return; } evdev->mouse.pressed_button &= ~(1 << button); } if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)))) { - goto end; + return; } ev->window = (Ecore_Window)input->dev->window; @@ -1374,7 +1346,6 @@ e_input_evdev_handle_button(E_Input_Evdev *evdev, struct libinput_event_pointer 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) { @@ -1415,13 +1386,22 @@ e_input_evdev_handle_button(E_Input_Evdev *evdev, struct libinput_event_pointer if (comp_conf && comp_conf->input_log_enable) ELOGF("Mouse", "Button %s (btn: %d, device: %s)", NULL, state?"Press":"Release", button, ecore_device_name_get(ev->dev)); - if (state) - ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, _e_input_event_mouse_button_cb_free, NULL); + 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, state ? ECORE_EVENT_MOUSE_BUTTON_DOWN : ECORE_EVENT_MOUSE_BUTTON_UP, 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_begin(); -end: - ecore_thread_main_loop_end(); + ecore_dev = _device_pointer_send_motion(evdev); + ev->dev = ecore_device_ref(ecore_dev); + ecore_event_add(state ? ECORE_EVENT_MOUSE_BUTTON_DOWN : 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 diff --git a/src/bin/server/e_comp_wl.c b/src/bin/server/e_comp_wl.c index 5da962e..d910609 100644 --- a/src/bin/server/e_comp_wl.c +++ b/src/bin/server/e_comp_wl.c @@ -1666,6 +1666,7 @@ _e_comp_wl_evas_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *o Evas_Device *dev = NULL; const Evas_Device *seat_dev; const char *dev_name, *seat_name; + Evas_Device_Class dev_class; if (!ec) return; if (e_object_is_del(E_OBJECT(ec))) return; @@ -1676,6 +1677,7 @@ _e_comp_wl_evas_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *o seat_dev = evas_device_parent_get(dev); seat_name = evas_device_name_get(seat_dev); + dev_class = evas_device_class_get(dev); ELOGF("Mouse", "Down (obj: %p, button: %d, time: %d, x:%d, y:%d, name:%20s) (dev:%s, seat:%s)", ec, obj, ev->button, ev->timestamp, ev->output.x, ev->output.y, e_client_util_name_get(ec), @@ -1683,12 +1685,12 @@ _e_comp_wl_evas_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *o _e_comp_wl_device_send_event_device(ec, dev, ev->timestamp); - if (dev && (evas_device_class_get(dev) == EVAS_DEVICE_CLASS_TOUCH)) + if (dev && (dev_class == EVAS_DEVICE_CLASS_TOUCH)) { e_comp_wl->touch.faked_ec = ec; if (dev_name) - _e_comp_wl_device_renew_axis(dev_name, evas_device_class_get(dev), + _e_comp_wl_device_renew_axis(dev_name, dev_class, ec, 0, ev->radius_x, ev->radius_y, ev->pressure, ev->angle); _e_comp_wl_evas_handle_mouse_button_to_touch(ec, ev->timestamp, ev->canvas.x, ev->canvas.y, EINA_TRUE); @@ -1719,7 +1721,8 @@ _e_comp_wl_evas_cb_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *even Evas_Event_Mouse_Up *ev = event; Evas_Device *dev = NULL; const Evas_Device *seat_dev; - const char *dev_name, *seat_name;; + const char *dev_name, *seat_name; + Evas_Device_Class dev_class; Evas_Event_Flags flags; if (!ec) return; @@ -1738,12 +1741,13 @@ _e_comp_wl_evas_cb_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *even seat_dev = evas_device_parent_get(dev); seat_name = evas_device_name_get(seat_dev); flags = evas_event_default_flags_get(evas); + dev_class = evas_device_class_get(dev); ELOGF("Mouse", "Up (obj: %p, button: %d, flag: 0x%x, time: %d, x:%d, y:%d, name:%20s) (dev:%s, seat:%s)", ec, obj, ev->button, flags, ev->timestamp, ev->output.x, ev->output.y, e_client_util_name_get(ec), dev_name, seat_name); - if (dev && (evas_device_class_get(dev) == EVAS_DEVICE_CLASS_TOUCH)) + if (dev && (dev_class == EVAS_DEVICE_CLASS_TOUCH)) { e_comp_wl->touch.pressed &= ~(1 << 0); @@ -1755,10 +1759,10 @@ _e_comp_wl_evas_cb_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *even _e_comp_wl_device_send_event_device(ec, dev, ev->timestamp); - if (dev && (evas_device_class_get(dev) == EVAS_DEVICE_CLASS_TOUCH)) + if (dev && (dev_class == EVAS_DEVICE_CLASS_TOUCH)) { 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_evas_handle_mouse_button_to_touch(ec, ev->timestamp, ev->canvas.x, ev->canvas.y, EINA_FALSE); } @@ -4216,22 +4220,13 @@ e_comp_wl_key_process(Ecore_Event_Key *ev, E_Device *dev, int type) return res; } -EINTERN Eina_Bool -e_comp_wl_evas_handle_mouse_button(E_Client *ec, uint32_t timestamp, uint32_t button_id, uint32_t state) +EINTERN void +e_comp_wl_surface_mouse_button_send(struct wl_resource *surface, uint32_t timestamp, uint32_t button_id, uint32_t state) { Eina_List *l; struct wl_client *wc; - uint32_t serial, btn; struct wl_resource *res; - - if (ec->cur_mouse_action) return EINA_FALSE; - if (e_comp_wl->drag) - { - ELOGF("Mouse", "Button %s ignored. dragging. (btn: %d, time: %d)", ec, (state ? "Down" : "Up"), button_id, timestamp); - return EINA_FALSE; - } - if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE; - if ((ec->ignored) && (!ec->remote_surface.provider)) return EINA_FALSE; + uint32_t serial, btn; switch (button_id) { @@ -4242,11 +4237,6 @@ e_comp_wl_evas_handle_mouse_button(E_Client *ec, uint32_t timestamp, uint32_t bu } e_comp_wl->ptr.button = btn; - struct wl_resource *surface = e_comp_wl_client_surface_get(ec); - if (!surface) return EINA_FALSE; - - if (!eina_list_count(e_comp_wl->ptr.resources)) - return EINA_TRUE; wc = wl_resource_get_client(surface); serial = wl_display_next_serial(e_comp_wl->wl.disp); @@ -4255,13 +4245,37 @@ e_comp_wl_evas_handle_mouse_button(E_Client *ec, uint32_t timestamp, uint32_t bu { if (wl_resource_get_client(res) != wc) continue; if (!e_comp_wl_input_pointer_check(res)) continue; - TRACE_INPUT_BEGIN(e_comp_wl_evas_handle_mouse_button); + TRACE_INPUT_BEGIN(e_comp_wl_surface_mouse_button); - ELOGF("Mouse", "Button %s (btn: %d, time: %d)", ec, (state ? "Down" : "Up"), btn, timestamp); + ELOGF("Mouse", "Button %s (btn: %d, time: %d)", NULL, (state ? "Down" : "Up"), btn, timestamp); wl_pointer_send_button(res, serial, timestamp, btn, state); TRACE_INPUT_END(); } +} + +EINTERN Eina_Bool +e_comp_wl_evas_handle_mouse_button(E_Client *ec, uint32_t timestamp, uint32_t button_id, uint32_t state) +{ + if (ec->cur_mouse_action) return EINA_FALSE; + if (e_comp_wl->drag) + { + ELOGF("Mouse", "Button %s ignored. dragging. (btn: %d, time: %d)", ec, (state ? "Down" : "Up"), button_id, timestamp); + return EINA_FALSE; + } + if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE; + if ((ec->ignored) && (!ec->remote_surface.provider)) return EINA_FALSE; + + struct wl_resource *surface = e_comp_wl_client_surface_get(ec); + if (!surface) return EINA_FALSE; + + if (!eina_list_count(e_comp_wl->ptr.resources)) + return EINA_TRUE; + + ELOGF("Mouse", "Button %s (btn: %d, time: %d)", ec, (state ? "Down" : "Up"), button_id, timestamp); + + e_comp_wl_surface_mouse_button_send(surface, timestamp, button_id, state); + return EINA_TRUE; } diff --git a/src/bin/server/e_comp_wl_input_thread.c b/src/bin/server/e_comp_wl_input_thread.c index 56d7fe6..84eabb4 100644 --- a/src/bin/server/e_comp_wl_input_thread.c +++ b/src/bin/server/e_comp_wl_input_thread.c @@ -7,8 +7,14 @@ #include "e_input_thread_client.h" static E_Input_Event_Handler *_mouse_move_handler = NULL; +static E_Input_Event_Handler *_mouse_down_handler = NULL; +static E_Input_Event_Handler *_mouse_up_handler = NULL; + static Eina_Bool e_input_handlers_added = EINA_FALSE; +static Eina_Bool need_send_released = EINA_FALSE; +static Eina_Bool need_send_motion = EINA_TRUE; + static Eina_Bool _e_input_thread_client_under_pointer_helper_ignore_client(E_Input_Thread_Client *iec) { @@ -125,6 +131,117 @@ err: return ECORE_CALLBACK_RENEW; } +static Eina_Bool +_e_comp_wl_cb_mouse_button_down_thread_mode(void *d EINA_UNUSED, int t EINA_UNUSED, void *event) +{ + Ecore_Event_Mouse_Button *ev = event; + E_Device *dev = NULL; + const char *dev_name = NULL;; + Ecore_Device_Class device_class; + + ELOGF("Mouse", "E Event Mouse Down (time: %d, x:%d y:%d), fixed(%d, %d)", NULL, ev->timestamp, ev->x, ev->y, wl_fixed_from_int(ev->x), wl_fixed_from_int(ev->y)); + + if (!e_input_pointer_thread_mode_get()) return ECORE_CALLBACK_RENEW; + + E_Input_Thread_Client *iec; + iec = _e_comp_wl_input_thread_client_under_pointer(ev->x, ev->y); + if (!iec) + return ECORE_CALLBACK_RENEW; + + ELOGF("Mouse", "Down. iec: %p name:%s", NULL, iec, e_input_thread_client_util_name_get(iec)); + struct wl_resource *surface = e_input_thread_client_wl_resource_get(iec); + if (!surface) + { + ELOGF("Mouse", "Down. surface NULL", NULL); + goto err; + } + + // send device data + dev = (E_Device *)ev->dev; + dev_name = e_device_name_get(dev); + + device_class = e_device_class_get(dev); + + ELOGF("Mouse", "Down (button: %d, time: %d, x:%d, y:%d, fixed_x: %d, fixed_y: %d) (dev:%s)", + NULL, ev->buttons, ev->timestamp, ev->x, ev->y, wl_fixed_from_int(ev->x), wl_fixed_from_int(ev->y), + dev_name); + + if (dev && device_class == ECORE_DEVICE_CLASS_TOUCH) + { + e_comp_wl->touch.pressed |= (1 << 0); + } + else + { + ELOGF("Mouse", "button(%d)", NULL, ev->buttons); + e_comp_wl_surface_mouse_button_send(surface, ev->timestamp, ev->buttons, WL_POINTER_BUTTON_STATE_PRESSED); + + e_pointer_mouse_move(e_comp->pointer, ev->x, ev->y); + } + + need_send_released = EINA_TRUE; + +err: + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_e_comp_wl_cb_mouse_button_up_thread_mode(void *d EINA_UNUSED, int t EINA_UNUSED, void *event) +{ + Ecore_Event_Mouse_Button *ev = event; + E_Device *dev = NULL; + const char *dev_name = NULL; + Ecore_Device_Class device_class; + E_Input_Thread_Client *iec = NULL; + struct wl_resource *surface; + + if (!need_send_released) + { + need_send_motion = EINA_TRUE; + } + + dev = (E_Device *)ev->dev; + dev_name = e_device_name_get(dev); + device_class = e_device_class_get(dev); + + ELOGF("Mouse", "Up (button: %d, time: %d, x:%d, y:%d) (dev:%s)", + NULL, ev->buttons, ev->timestamp, ev->x, ev->y, dev_name); + + if (dev && (device_class == EVAS_DEVICE_CLASS_TOUCH)) + { + e_comp_wl->touch.pressed &= ~(1 << 0); + + if (!e_comp_wl->touch.pressed && e_comp_wl->touch.faked_ec) + e_comp_wl->touch.faked_ec = NULL; + } + + iec = _e_comp_wl_input_thread_client_under_pointer(ev->x, ev->y); + ELOGF("Mouse", "Up. cursor under pointer iec: %p", NULL, iec); + if (!iec) + return ECORE_CALLBACK_RENEW; + + surface = e_input_thread_client_wl_resource_get(iec); + if (!surface) + { + ELOGF("Mouse", "Up. surface NULL", NULL); + goto err; + } + + if (dev && (device_class == ECORE_DEVICE_CLASS_TOUCH)) + { + + } + else + { + e_comp_wl_surface_mouse_button_send(surface, ev->timestamp, ev->buttons, + WL_POINTER_BUTTON_STATE_RELEASED); + } + + need_send_released = EINA_FALSE; + +err: + return ECORE_CALLBACK_RENEW; +} + EINTERN void e_comp_wl_input_thread_add_e_input_handlers() { @@ -142,6 +259,12 @@ e_comp_wl_input_thread_add_e_input_handlers() 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); + if (!_mouse_down_handler) + _mouse_down_handler = e_input_event_handler_add(input_event_source, ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_comp_wl_cb_mouse_button_down_thread_mode, NULL); + + if (!_mouse_up_handler) + _mouse_up_handler = e_input_event_handler_add(input_event_source, ECORE_EVENT_MOUSE_BUTTON_UP, _e_comp_wl_cb_mouse_button_up_thread_mode, NULL); + e_input_handlers_added = EINA_TRUE; } } @@ -166,6 +289,16 @@ e_comp_wl_input_thread_remove_e_input_handlers() e_input_event_handler_del(input_event_source, _mouse_move_handler); _mouse_move_handler = NULL; + + if (_mouse_down_handler) + e_input_event_handler_del(input_event_source, _mouse_down_handler); + + _mouse_down_handler = NULL; + + if (_mouse_up_handler) + e_input_event_handler_del(input_event_source, _mouse_up_handler); + + _mouse_up_handler = NULL; } } else diff --git a/src/bin/server/e_comp_wl_intern.h b/src/bin/server/e_comp_wl_intern.h index 2cce630..65ea0c3 100644 --- a/src/bin/server/e_comp_wl_intern.h +++ b/src/bin/server/e_comp_wl_intern.h @@ -106,5 +106,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); +EINTERN void e_comp_wl_surface_mouse_button_send(struct wl_resource *surface, uint32_t timestamp, uint32_t button_id, uint32_t state); #endif -- 2.7.4