From 4050a42cea3699874f7265ba07a11c36bad0f66c Mon Sep 17 00:00:00 2001 From: Duna Oh Date: Mon, 16 Nov 2015 21:09:33 +0900 Subject: [PATCH] Ecore_Input: for multi-touch event, store the name of source device and send a valid Evas_Device Change-Id: Ie94ceb187ad72a7bde57fb0d0e60fd353ac027f5 Signed-off-by: Duna Oh --- src/lib/ecore_drm/ecore_drm_device.c | 10 ++ src/lib/ecore_drm/ecore_drm_evdev.c | 8 ++ src/lib/ecore_drm/ecore_drm_inputs.c | 40 +++++- src/lib/ecore_drm/ecore_drm_private.h | 1 + src/lib/ecore_input/Ecore_Input.h | 24 ++++ src/lib/ecore_input/ecore_input.c | 6 + src/lib/ecore_input_evas/Ecore_Input_Evas.h | 2 + src/lib/ecore_input_evas/ecore_input_evas.c | 196 +++++++++++++++++++++++++++- src/lib/evas/canvas/evas_device.c | 7 + 9 files changed, 292 insertions(+), 2 deletions(-) diff --git a/src/lib/ecore_drm/ecore_drm_device.c b/src/lib/ecore_drm/ecore_drm_device.c index 4d07a9a..347906a 100644 --- a/src/lib/ecore_drm/ecore_drm_device.c +++ b/src/lib/ecore_drm/ecore_drm_device.c @@ -494,10 +494,20 @@ ecore_drm_device_fd_get(Ecore_Drm_Device *dev) EAPI void ecore_drm_device_window_set(Ecore_Drm_Device *dev, unsigned int window) { + Eina_List *l, *ll; + Ecore_Drm_Seat *seat = NULL; + Ecore_Drm_Evdev *edev = NULL; + /* check for valid device */ EINA_SAFETY_ON_TRUE_RETURN((!dev) || (dev->drm.fd < 0)); dev->window = window; + + EINA_LIST_FOREACH(dev->seats, l , seat) + { + EINA_LIST_FOREACH(seat->devices, ll, edev) + _ecore_drm_device_info_send(window, edev, EINA_TRUE); + } } EAPI const char * diff --git a/src/lib/ecore_drm/ecore_drm_evdev.c b/src/lib/ecore_drm/ecore_drm_evdev.c index 3d424f7..28efc77 100644 --- a/src/lib/ecore_drm/ecore_drm_evdev.c +++ b/src/lib/ecore_drm/ecore_drm_evdev.c @@ -114,6 +114,7 @@ _device_output_set(Ecore_Drm_Evdev *edev) ev->multi.y = ev->y; ev->multi.root.x = ev->x; ev->multi.root.y = ev->y; + ev->dev_name = eina_stringshare_add(edev->path); ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL); } @@ -375,6 +376,7 @@ _device_handle_key(struct libinput_device *device, struct libinput_event_keyboar _device_modifiers_update(edev); e->modifiers = edev->xkb.modifiers; + e->dev_name = eina_stringshare_add(edev->path); if (state) ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL); @@ -431,6 +433,7 @@ _device_pointer_motion(Ecore_Drm_Evdev *edev, struct libinput_event_pointer *eve ev->multi.y = ev->y; ev->multi.root.x = ev->x; ev->multi.root.y = ev->y; + ev->dev_name = eina_stringshare_add(edev->path); ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL); } @@ -524,6 +527,7 @@ _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; + ev->dev_name = eina_stringshare_add(edev->path); if (state) { @@ -595,6 +599,7 @@ _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_name = eina_stringshare_add(edev->path); #if LIBINPUT_HIGHER_08 axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL; @@ -630,6 +635,7 @@ _ecore_drm_evdev_device_create(Ecore_Drm_Seat *seat, struct libinput_device *dev edev->seat = seat; edev->device = device; edev->path = eina_stringshare_add(libinput_device_get_sysname(device)); + edev->fd = -1; devices = eeze_udev_find_by_filter("input", NULL, edev->path); if (eina_list_count(devices) >= 1) @@ -717,6 +723,7 @@ _device_handle_touch_event_send(Ecore_Drm_Evdev *edev, struct libinput_event_tou ev->multi.y = ev->y; ev->multi.root.x = ev->x; ev->multi.root.y = ev->y; + ev->dev_name = eina_stringshare_add(edev->path); if (state == ECORE_EVENT_MOUSE_BUTTON_DOWN) { @@ -792,6 +799,7 @@ _device_handle_touch_motion_send(Ecore_Drm_Evdev *edev, struct libinput_event_to ev->multi.y = ev->y; ev->multi.root.x = ev->x; ev->multi.root.y = ev->y; + ev->dev_name = eina_stringshare_add(edev->path); ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL); } diff --git a/src/lib/ecore_drm/ecore_drm_inputs.c b/src/lib/ecore_drm/ecore_drm_inputs.c index 78683eb..f9fd424 100644 --- a/src/lib/ecore_drm/ecore_drm_inputs.c +++ b/src/lib/ecore_drm/ecore_drm_inputs.c @@ -119,6 +119,38 @@ _seat_get(Ecore_Drm_Input *input, const char *seat) return _seat_create(input, seat); } +static void +_ecore_event_device_info_free(void *data EINA_UNUSED, void *ev) +{ + Ecore_Event_Device_Info *e; + + e = ev; + eina_stringshare_del(e->name); + eina_stringshare_del(e->identifier); + eina_stringshare_del(e->seatname); + + free(e); +} + +void +_ecore_drm_device_info_send(unsigned int window, Ecore_Drm_Evdev *edev, Eina_Bool flag) +{ + Ecore_Event_Device_Info *e; + + if (!(e = calloc(1, sizeof(Ecore_Event_Device_Info)))) return; + + e->name = eina_stringshare_add(libinput_device_get_name(edev->device)); + e->identifier = eina_stringshare_add(edev->path); + e->seatname = eina_stringshare_add(edev->seat->name); + e->caps = edev->seat_caps; + e->window = window; + + if (flag) + ecore_event_add(ECORE_EVENT_DEVICE_ADD, e, _ecore_event_device_info_free, NULL); + else + ecore_event_add(ECORE_EVENT_DEVICE_DEL, e, _ecore_event_device_info_free, NULL); +} + static void _device_added(Ecore_Drm_Input *input, struct libinput_device *device) { @@ -160,10 +192,13 @@ _device_added(Ecore_Drm_Input *input, struct libinput_device *device) ev, _ecore_drm_event_input_device_add_free, NULL); + + if (input->dev->window != 0) + _ecore_drm_device_info_send(input->dev->window, edev, EINA_TRUE); } static void -_device_removed(Ecore_Drm_Input *input EINA_UNUSED, struct libinput_device *device) +_device_removed(Ecore_Drm_Input *input, struct libinput_device *device) { Ecore_Drm_Evdev *edev; Ecore_Drm_Event_Input_Device_Del *ev; @@ -185,6 +220,9 @@ _device_removed(Ecore_Drm_Input *input EINA_UNUSED, struct libinput_device *devi _ecore_drm_event_input_device_del_free, NULL); + if (input->dev->window != 0) + _ecore_drm_device_info_send(input->dev->window, edev, EINA_FALSE); + /* remove this evdev from the seat's list of devices */ edev->seat->devices = eina_list_remove(edev->seat->devices, edev); diff --git a/src/lib/ecore_drm/ecore_drm_private.h b/src/lib/ecore_drm/ecore_drm_private.h index 33fc969..69111ed 100644 --- a/src/lib/ecore_drm/ecore_drm_private.h +++ b/src/lib/ecore_drm/ecore_drm_private.h @@ -301,4 +301,5 @@ void _ecore_drm_dbus_device_release(uint32_t major, uint32_t minor); Eina_Bool _ecore_drm_dbus_session_take(void); Eina_Bool _ecore_drm_dbus_session_release(void); +void _ecore_drm_device_info_send(unsigned int window, Ecore_Drm_Evdev *edev, Eina_Bool flag); #endif diff --git a/src/lib/ecore_input/Ecore_Input.h b/src/lib/ecore_input/Ecore_Input.h index 1e7e836..6175827 100644 --- a/src/lib/ecore_input/Ecore_Input.h +++ b/src/lib/ecore_input/Ecore_Input.h @@ -55,6 +55,8 @@ extern "C" { EAPI extern int ECORE_EVENT_MOUSE_OUT; EAPI extern int ECORE_EVENT_AXIS_UPDATE; /**< @since 1.13 */ EAPI extern int ECORE_EVENT_MOUSE_BUTTON_CANCEL; /**< @since 1.15 */ + EAPI extern int ECORE_EVENT_DEVICE_ADD; + EAPI extern int ECORE_EVENT_DEVICE_DEL; #define ECORE_EVENT_MODIFIER_SHIFT 0x0001 #define ECORE_EVENT_MODIFIER_CTRL 0x0002 @@ -82,6 +84,7 @@ extern "C" { typedef struct _Ecore_Event_Modifiers Ecore_Event_Modifiers; typedef struct _Ecore_Event_Axis_Update Ecore_Event_Axis_Update; /**< @since 1.13 */ typedef struct _Ecore_Axis Ecore_Axis; /**< @since 1.13 */ + typedef struct _Ecore_Event_Device_Info Ecore_Event_Device_Info; /** * @typedef Ecore_Event_Modifier @@ -145,6 +148,7 @@ extern "C" { Ecore_Window window; /**< The main window where event happened */ Ecore_Window root_window; /**< The root window where event happened */ Ecore_Window event_window; /**< The child window where event happened */ + const char *dev_name; /**event_window); if (!lookup) return ECORE_CALLBACK_PASS_ON; + Evas_Device *dev = _ecore_event_get_evas_device(lookup->evas, e->dev_name); + if (dev) + evas_device_push(lookup->evas, dev); ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers); if (press == ECORE_DOWN) evas_event_feed_key_down_with_keycode(lookup->evas, @@ -416,6 +445,7 @@ _ecore_event_evas_key(Ecore_Event_Key *e, Ecore_Event_Press press) e->timestamp, e->data, e->keycode); + evas_device_pop(lookup->evas); return ECORE_CALLBACK_PASS_ON; } @@ -490,6 +520,9 @@ _ecore_event_evas_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Press pr } } + Evas_Device *dev = _ecore_event_get_evas_device(lookup->evas, e->dev_name); + if (dev) + evas_device_push(lookup->evas, dev); if (e->multi.device == 0) { ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers); @@ -537,6 +570,7 @@ _ecore_event_evas_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Press pr e->timestamp, NULL); } } + evas_device_pop(lookup->evas); return ECORE_CALLBACK_PASS_ON; } @@ -549,6 +583,10 @@ ecore_event_evas_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void * e = event; lookup = _ecore_event_window_match(e->event_window); if (!lookup) return ECORE_CALLBACK_PASS_ON; + + Evas_Device *dev = _ecore_event_get_evas_device(lookup->evas, e->dev_name); + if (dev) + evas_device_push(lookup->evas, dev); if (e->multi.device == 0) { _ecore_event_evas_push_mouse_move(e); @@ -575,6 +613,7 @@ ecore_event_evas_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void * e->multi.x, e->multi.y, e->timestamp, NULL); } + evas_device_pop(lookup->evas); return ECORE_CALLBACK_PASS_ON; } @@ -605,6 +644,9 @@ _ecore_event_evas_mouse_io(Ecore_Event_Mouse_IO *e, Ecore_Event_IO io) lookup = _ecore_event_window_match(e->event_window); if (!lookup) return ECORE_CALLBACK_PASS_ON; + Evas_Device *dev = _ecore_event_get_evas_device(lookup->evas, e->dev_name); + if (dev) + evas_device_push(lookup->evas, dev); ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers); switch (io) { @@ -619,6 +661,7 @@ _ecore_event_evas_mouse_io(Ecore_Event_Mouse_IO *e, Ecore_Event_IO io) } lookup->move_mouse(lookup->window, e->x, e->y, e->timestamp); + evas_device_pop(lookup->evas); return ECORE_CALLBACK_PASS_ON; } @@ -643,8 +686,12 @@ ecore_event_evas_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void e = event; lookup = _ecore_event_window_match(e->event_window); if (!lookup) return ECORE_CALLBACK_PASS_ON; + Evas_Device *dev = _ecore_event_get_evas_device(lookup->evas, e->dev_name); + if (dev) + evas_device_push(lookup->evas, dev); ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers); evas_event_feed_mouse_wheel(lookup->evas, e->direction, e->z, e->timestamp, NULL); + evas_device_pop(lookup->evas); return ECORE_CALLBACK_PASS_ON; } @@ -675,6 +722,147 @@ ecore_event_evas_axis_update(void *data EINA_UNUSED, int type EINA_UNUSED, void return ECORE_CALLBACK_PASS_ON; } +static short +_ecore_event_device_cap_to_class(int cap) +{ + switch(cap) + { + case ECORE_DEVICE_POINTER: + return EVAS_DEVICE_CLASS_MOUSE; + case ECORE_DEVICE_KEYBOARD: + return EVAS_DEVICE_CLASS_KEYBOARD; + case ECORE_DEVICE_TOUCH: + return EVAS_DEVICE_CLASS_TOUCH; + default: + return EVAS_DEVICE_CLASS_NONE; + } + return EVAS_DEVICE_CLASS_NONE; +} + +static void +_ecore_event_evas_add_evas_device(Evas *e, const char *name, const char *identifier, Evas_Device_Class clas) +{ + const Eina_List *dev_list = NULL; + const Eina_List *l; + Evas_Device *edev = NULL; + + dev_list = evas_device_list(e, NULL); + if (dev_list) + { + EINA_LIST_FOREACH(dev_list, l, edev) + { + if (!edev) continue; + if ((evas_device_class_get(edev) == clas) && + !(strcmp(evas_device_name_get(edev), identifier))) + return; + else if ((evas_device_class_get(edev) == clas) && + !(strcmp(evas_device_description_get(edev), name))) + { + evas_device_del(edev); + break; + } + } + } + + edev = evas_device_add(e); + if (!edev) + { + ERR("_ecore_event_add_evas_device: failed to add evas device"); + return; + } + evas_device_name_set(edev, identifier); + evas_device_description_set(edev, name); + evas_device_class_set(edev, clas); +} + +static void +_ecore_event_evas_del_evas_device(Evas *e, const char *name, const char *identifier, Evas_Device_Class clas) +{ + const Eina_List *dev_list = NULL; + const Eina_List *l; + Evas_Device *edev = NULL; + + dev_list = evas_device_list(e, NULL); + if (!dev_list) + { + ERR("_ecore_event_evas_del_evas_device: failed to get the list of evas device"); + return; + } + EINA_LIST_FOREACH(dev_list, l, edev) + { + if (!edev) continue; + if ((evas_device_class_get(edev) == clas) && + !(strcmp(evas_device_name_get(edev), identifier)) && + !(strcmp(evas_device_description_get(edev), name))) + { + evas_device_del(edev); + return; + } + } +} + +static void +_ecore_event_add_del_evas_devices(Evas *e, const char *name, const char *identifier, int caps, Eina_Bool flag) +{ + Evas_Device_Class clas = EVAS_DEVICE_CLASS_NONE; + if (caps & ECORE_DEVICE_POINTER) + { + clas = _ecore_event_device_cap_to_class(ECORE_DEVICE_POINTER); + if (flag) + _ecore_event_evas_add_evas_device(e, name, identifier, clas); + else + _ecore_event_evas_del_evas_device(e, name, identifier, clas); + } + if (caps & ECORE_DEVICE_KEYBOARD) + { + clas = _ecore_event_device_cap_to_class(ECORE_DEVICE_KEYBOARD); + if (flag) + _ecore_event_evas_add_evas_device(e, name, identifier, clas); + else + _ecore_event_evas_del_evas_device(e, name, identifier, clas); + } + if (caps & ECORE_DEVICE_TOUCH) + { + clas = _ecore_event_device_cap_to_class(ECORE_DEVICE_TOUCH); + if (flag) + _ecore_event_evas_add_evas_device(e, name, identifier, clas); + else + _ecore_event_evas_del_evas_device(e, name, identifier, clas); + } +} + +EAPI Eina_Bool +ecore_event_evas_device_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Event_Device_Info *e; + Ecore_Input_Window *lookup; + + if(!(e = event)) return ECORE_CALLBACK_PASS_ON; + + lookup = _ecore_event_window_match(e->window); + if (!lookup) return ECORE_CALLBACK_PASS_ON; + + _ecore_event_add_del_evas_devices(lookup->evas, e->name, e->identifier, e->caps, EINA_TRUE); + + return ECORE_CALLBACK_PASS_ON; +} + +EAPI Eina_Bool +ecore_event_evas_device_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Event_Device_Info *e; + Ecore_Input_Window *lookup; + + if(!(e = event)) return ECORE_CALLBACK_PASS_ON; + + lookup = _ecore_event_window_match(e->window); + if (!lookup) return ECORE_CALLBACK_PASS_ON; + + _ecore_event_add_del_evas_devices(lookup->evas, e->name, e->identifier, e->caps, EINA_FALSE); + + return ECORE_CALLBACK_PASS_ON; +} + EAPI int ecore_event_evas_init(void) { @@ -729,6 +917,12 @@ ecore_event_evas_init(void) ecore_event_evas_handlers[9] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_CANCEL, ecore_event_evas_mouse_button_cancel, NULL); + ecore_event_evas_handlers[10] = ecore_event_handler_add(ECORE_EVENT_DEVICE_ADD, + ecore_event_evas_device_add, + NULL); + ecore_event_evas_handlers[11] = ecore_event_handler_add(ECORE_EVENT_DEVICE_DEL, + ecore_event_evas_device_del, + NULL); _window_hash = eina_hash_pointer_new(free); diff --git a/src/lib/evas/canvas/evas_device.c b/src/lib/evas/canvas/evas_device.c index b57a587..effed55 100644 --- a/src/lib/evas/canvas/evas_device.c +++ b/src/lib/evas/canvas/evas_device.c @@ -73,6 +73,10 @@ evas_device_pop(Evas *eo_e) return; MAGIC_CHECK_END(); Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CANVAS_CLASS); + + // resolving crash issue + if (!e->cur_device) return; + dev = eina_array_pop(e->cur_device); if (dev) _evas_device_unref(dev); } @@ -276,6 +280,9 @@ _evas_device_unref(Evas_Device *dev) { dev->ref--; if (dev->ref > 0) return; + Evas_Public_Data *e = eo_data_scope_get(dev->evas, EVAS_CANVAS_CLASS); + e->devices = eina_list_remove(e->devices, dev); + evas_event_callback_call(dev->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev); if (dev->name) eina_stringshare_del(dev->name); if (dev->desc) eina_stringshare_del(dev->desc); dev->magic = 0; -- 2.7.4