Ecore_Input: for multi-touch event, store the name of source device and send a valid... 40/52540/12
authorDuna Oh <duna.oh@samsung.com>
Mon, 16 Nov 2015 12:09:33 +0000 (21:09 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Wed, 9 Dec 2015 05:20:09 +0000 (21:20 -0800)
Change-Id: Ie94ceb187ad72a7bde57fb0d0e60fd353ac027f5
Signed-off-by: Duna Oh <duna.oh@samsung.com>
src/lib/ecore_drm/ecore_drm_device.c
src/lib/ecore_drm/ecore_drm_evdev.c
src/lib/ecore_drm/ecore_drm_inputs.c
src/lib/ecore_drm/ecore_drm_private.h
src/lib/ecore_input/Ecore_Input.h
src/lib/ecore_input/ecore_input.c
src/lib/ecore_input_evas/Ecore_Input_Evas.h
src/lib/ecore_input_evas/ecore_input_evas.c
src/lib/evas/canvas/evas_device.c

index 4d07a9a..347906a 100644 (file)
@@ -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 *
index 3d424f7..28efc77 100644 (file)
@@ -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);
 }
index 78683eb..f9fd424 100644 (file)
@@ -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);
 
index 33fc969..69111ed 100644 (file)
@@ -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
index 1e7e836..6175827 100644 (file)
@@ -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; /**<The sysname of source device where event came from*/
         
         unsigned int     timestamp; /**< Time when the event occurred */
         unsigned int     modifiers; /**< The combination of modifiers key (SHIT,CTRL,ALT,..)*/
@@ -165,6 +169,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; /**<The sysname of source device where event came from*/
 
         unsigned int     timestamp; /**< Time when the event occurred */
         unsigned int     modifiers; /**< The combination of modifiers key (SHIT,CTRL,ALT,..)*/
@@ -201,6 +206,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; /**<The sysname of source device where event came from*/
         
         unsigned int     timestamp; /**< Time when the event occurred */
         unsigned int     modifiers; /**< The combination of modifiers key (SHIT,CTRL,ALT,..)*/
@@ -226,6 +232,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; /**<The sysname of source device where event came from*/
         
         unsigned int     timestamp; /**< Time when the event occurred */
         unsigned int     modifiers; /**< The combination of modifiers key (SHIT,CTRL,ALT,..)*/
@@ -287,6 +294,22 @@ extern "C" {
         Ecore_Axis *axis;
      };
 
+   typedef enum _Ecore_Device_Type
+     {
+        ECORE_DEVICE_POINTER = (1 << 0),
+        ECORE_DEVICE_KEYBOARD = (1 << 1),
+        ECORE_DEVICE_TOUCH = (1 << 2),
+     } Ecore_Device_Type;
+
+   struct _Ecore_Event_Device_Info
+     {
+        Ecore_Window window;
+        const char *name;
+        const char *identifier;
+        const char *seatname;
+        unsigned int caps;
+     };
+
    /**
     * @struct _Ecore_Event_Mouse_IO
     * Contains information about an Ecore mouse input/output event.
@@ -295,6 +318,7 @@ extern "C" {
      {
         Ecore_Window     window; /**< The main window where event happened */
         Ecore_Window     event_window; /**< The child window where event happened */
+        const char       *dev_name; /**<The sysname of source device where event came from*/
         
         unsigned int     timestamp; /**< Time when the event occurred */
         unsigned int     modifiers; /**< The combination of modifiers key (SHIT,CTRL,ALT,..)*/
index 6b52eff..4a16611 100644 (file)
@@ -24,6 +24,8 @@ EAPI int ECORE_EVENT_MOUSE_IN = 0;
 EAPI int ECORE_EVENT_MOUSE_OUT = 0;
 EAPI int ECORE_EVENT_AXIS_UPDATE = 0;
 EAPI int ECORE_EVENT_MOUSE_BUTTON_CANCEL = 0;
+EAPI int ECORE_EVENT_DEVICE_ADD = 0;
+EAPI int ECORE_EVENT_DEVICE_DEL = 0;
 
 static int _ecore_event_init_count = 0;
 
@@ -56,6 +58,8 @@ ecore_event_init(void)
    ECORE_EVENT_MOUSE_OUT = ecore_event_type_new();
    ECORE_EVENT_AXIS_UPDATE = ecore_event_type_new();
    ECORE_EVENT_MOUSE_BUTTON_CANCEL = ecore_event_type_new();
+   ECORE_EVENT_DEVICE_ADD = ecore_event_type_new();
+   ECORE_EVENT_DEVICE_DEL = ecore_event_type_new();
 
    return _ecore_event_init_count;
 }
@@ -76,6 +80,8 @@ ecore_event_shutdown(void)
    ECORE_EVENT_MOUSE_OUT = 0;
    ECORE_EVENT_AXIS_UPDATE = 0;
    ECORE_EVENT_MOUSE_BUTTON_CANCEL = 0;
+   ECORE_EVENT_DEVICE_ADD = 0;
+   ECORE_EVENT_DEVICE_DEL = 0;
    eina_log_domain_unregister(_ecore_input_log_dom);
    _ecore_input_log_dom = -1;
    ecore_shutdown();
index db4029f..184d0c8 100644 (file)
@@ -51,6 +51,8 @@ EAPI Eina_Bool ecore_event_evas_mouse_in(void *data, int type, void *event);
 EAPI Eina_Bool ecore_event_evas_mouse_out(void *data, int type, void *event);
 EAPI Eina_Bool ecore_event_evas_axis_update(void *data, int type, void *event); /**< @since 1.13 */
 EAPI Eina_Bool ecore_event_evas_mouse_button_cancel(void *data, int type, void *event); /**< @since 1.15 */
+EAPI Eina_Bool ecore_event_evas_device_add(void *data, int type, void *event);
+EAPI Eina_Bool ecore_event_evas_device_del(void *data, int type, void *event);
 
 EAPI void      ecore_event_window_register(Ecore_Window id, void *window, Evas *evas, Ecore_Event_Mouse_Move_Cb move_mouse, Ecore_Event_Multi_Move_Cb move_multi, Ecore_Event_Multi_Down_Cb down_multi, Ecore_Event_Multi_Up_Cb up_multi);
 EAPI void      ecore_event_window_unregister(Ecore_Window id);
index bea13cb..36cbe11 100644 (file)
@@ -54,7 +54,7 @@ struct _Ecore_Input_Last
 };
 
 static int _ecore_event_evas_init_count = 0;
-static Ecore_Event_Handler *ecore_event_evas_handlers[10];
+static Ecore_Event_Handler *ecore_event_evas_handlers[12];
 static Eina_Hash *_window_hash = NULL;
 
 static Eina_List *_last_events = NULL;
@@ -390,6 +390,32 @@ _ecore_event_window_match(Ecore_Window id)
    return lookup;
 }
 
+static Evas_Device *
+_ecore_event_get_evas_device(Evas *e, const char *dev_name)
+{
+   const Eina_List *dev_list = NULL;
+   const Eina_List *l;
+   Evas_Device *edev = NULL;
+   const char *name = NULL;
+
+   if (!dev_name) return NULL;
+
+   dev_list = evas_device_list(e, NULL);
+   if (!dev_list)
+     return NULL;
+   EINA_LIST_FOREACH(dev_list, l, edev)
+     {
+        if (!edev) continue;
+        name = evas_device_name_get(edev);
+        if (!name) continue;
+        if (!(strcmp(name, dev_name)))
+          {
+             break;
+          }
+     }
+   return edev;
+}
+
 static Eina_Bool
 _ecore_event_evas_key(Ecore_Event_Key *e, Ecore_Event_Press press)
 {
@@ -397,6 +423,9 @@ _ecore_event_evas_key(Ecore_Event_Key *e, Ecore_Event_Press press)
 
    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);
    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);
 
index b57a587..effed55 100644 (file)
@@ -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;