jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=9ba11c5cd020b6ec5cb78dfaeda2d4c0472659ab

commit 9ba11c5cd020b6ec5cb78dfaeda2d4c0472659ab
Author: Guilherme Iscaro <isc...@profusion.mobi>
Date:   Mon Nov 14 11:03:56 2016 +0900

    Ecore Evas Wayland: Create the devices during Ecore_Evas setup.
    
    Summary:
    When launching an Elementary App using Wayland the elm_config will
    automatically connect to the Wayland's display server and all events
    regarding seats are lost, since by the time that Ecore_Evas is created
    the global events were already dispatched. To fix this problem,
    everytime an Ecore_Evas is created, the code must check if there
    are any seat capabilities available, if so, the devices will be created.
    
    Reviewers: bdilly, barbieri, cedric, jpeg
    
    Subscribers: devilhorns, cedric, jpeg
    
    Differential Revision: https://phab.enlightenment.org/D4390
---
 src/lib/ecore_wl2/Ecore_Wl2.h                      |  33 +++++
 src/lib/ecore_wl2/ecore_wl2_input.c                |  26 ++++
 src/lib/ecore_wl2/ecore_wl2_window.c               |   7 +
 .../engines/wayland/ecore_evas_wayland_common.c    | 143 +++++++++++++++++----
 4 files changed, 186 insertions(+), 23 deletions(-)

diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h
index 402206c..2d3cc16 100644
--- a/src/lib/ecore_wl2/Ecore_Wl2.h
+++ b/src/lib/ecore_wl2/Ecore_Wl2.h
@@ -54,6 +54,15 @@ typedef enum
    ECORE_WL2_DRAG_ACTION_LAST = 5,
 } Ecore_Wl2_Drag_Action;
 
+typedef enum
+{
+  ECORE_WL2_SEAT_CAPABILITIES_NO_SEAT = 0,
+  ECORE_WL2_SEAT_CAPABILITIES_NONE = 1,
+  ECORE_WL2_SEAT_CAPABILITIES_POINTER = 2,
+  ECORE_WL2_SEAT_CAPABILITIES_KEYBOARD = 4,
+  ECORE_WL2_SEAT_CAPABILITIES_TOUCH = 8
+} Ecore_Wl2_Seat_Capabilities;
+
 struct _Ecore_Wl2_Event_Connection
 {
    Ecore_Wl2_Display *display;
@@ -440,6 +449,14 @@ EAPI Eina_Iterator 
*ecore_wl2_display_globals_get(Ecore_Wl2_Display *display);
 EAPI void ecore_wl2_display_screen_size_get(Ecore_Wl2_Display *display, int 
*w, int *h);
 
 /**
+ * Get all the Ecore_Wl2_Input from the display.
+ * @param display The display
+ * @return A Eina_Iterator of Ecore_Wl2_Input or @c NULL on error
+ * @since 1.19
+ */
+EAPI Eina_Iterator *ecore_wl2_display_inputs_get(Ecore_Wl2_Display *display);
+
+/**
  * Find an Ecore_Wl2_Window based on id
  *
  * @param display The display to search for the window
@@ -887,6 +904,22 @@ EAPI void ecore_wl2_input_ungrab(Ecore_Wl2_Input *input);
 EAPI struct wl_seat *ecore_wl2_input_seat_get(Ecore_Wl2_Input *input);
 
 /**
+ * Get the seat capabilities for a given input.
+ *
+ * @param input The input
+ * @since 1.19
+ */
+EAPI Ecore_Wl2_Seat_Capabilities 
ecore_wl2_input_seat_capabilities_get(Ecore_Wl2_Input *input);
+
+/**
+ * Get the wayland's seat id from an input.
+ * @param input The input
+ * @return The seat id
+ * @since 1.19
+ */
+EAPI unsigned int ecore_wl2_input_seat_id_get(Ecore_Wl2_Input *input);
+
+/**
  * @defgroup Ecore_Wl2_Dnd_Group Wayland Library Drag-n-Drop Functions
  * @ingroup Ecore_Wl2_Group
  *
diff --git a/src/lib/ecore_wl2/ecore_wl2_input.c 
b/src/lib/ecore_wl2/ecore_wl2_input.c
index 830c6ad..a17c665 100644
--- a/src/lib/ecore_wl2/ecore_wl2_input.c
+++ b/src/lib/ecore_wl2/ecore_wl2_input.c
@@ -1572,3 +1572,29 @@ ecore_wl2_input_seat_get(Ecore_Wl2_Input *input)
 
    return input->wl.seat;
 }
+
+EAPI Ecore_Wl2_Seat_Capabilities
+ecore_wl2_input_seat_capabilities_get(Ecore_Wl2_Input *input)
+{
+
+   Ecore_Wl2_Seat_Capabilities cap = ECORE_WL2_SEAT_CAPABILITIES_NONE;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(input, ECORE_WL2_SEAT_CAPABILITIES_NO_SEAT);
+
+   if (!input->wl.seat)
+     return ECORE_WL2_SEAT_CAPABILITIES_NO_SEAT;
+   if (input->wl.keyboard)
+     cap |= ECORE_WL2_SEAT_CAPABILITIES_KEYBOARD;
+   if (input->wl.pointer)
+     cap |= ECORE_WL2_SEAT_CAPABILITIES_POINTER;
+   if (input->wl.touch)
+     cap |= ECORE_WL2_SEAT_CAPABILITIES_TOUCH;
+   return cap;
+}
+
+EAPI unsigned int
+ecore_wl2_input_seat_id_get(Ecore_Wl2_Input *input)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(input, 0);
+   return input->id;
+}
diff --git a/src/lib/ecore_wl2/ecore_wl2_window.c 
b/src/lib/ecore_wl2/ecore_wl2_window.c
index b2aa63f..2c19f05 100644
--- a/src/lib/ecore_wl2/ecore_wl2_window.c
+++ b/src/lib/ecore_wl2/ecore_wl2_window.c
@@ -993,6 +993,13 @@ ecore_wl2_window_input_get(Ecore_Wl2_Window *window)
    return NULL;
 }
 
+EAPI Eina_Iterator *
+ecore_wl2_display_inputs_get(Ecore_Wl2_Display *display)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
+   return eina_inlist_iterator_new(display->inputs);
+}
+
 EAPI Eina_Bool
 ecore_wl2_window_has_shell_surface(Ecore_Wl2_Window *window)
 {
diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c 
b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
index db60d98..9184c6c 100644
--- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
+++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
@@ -516,11 +516,43 @@ _ecore_evas_wl_common_device_event_add(int event_type, 
Ecore_Wl2_Device_Type dev
                    dev);
 }
 
+static EE_Wl_Device *
+_ecore_evas_wl_common_seat_add(Ecore_Evas *ee,
+                               const char *seat_name,
+                               unsigned int id)
+{
+   Ecore_Evas_Engine_Wl_Data *wdata;
+   EE_Wl_Device *device;
+   Evas_Device *dev;
+
+   device = calloc(1, sizeof(EE_Wl_Device));
+   EINA_SAFETY_ON_NULL_RETURN_VAL(device, NULL);
+
+   dev = evas_device_add_full(ee->evas, seat_name, "Wayland seat",
+                              NULL, NULL,
+                              EVAS_DEVICE_CLASS_SEAT,
+                              EVAS_DEVICE_SUBCLASS_NONE);
+   EINA_SAFETY_ON_NULL_GOTO(dev, err_dev);
+
+   device->seat = dev;
+   device->id = id;
+
+   wdata = ee->engine.data;
+   wdata->devices_list = eina_list_append(wdata->devices_list, device);
+
+   _ecore_evas_wl_common_device_event_add(ECORE_WL2_EVENT_DEVICE_ADDED,
+                                          ECORE_WL2_DEVICE_TYPE_SEAT,
+                                          id, dev, ee);
+   return device;
+ err_dev:
+   free(device);
+   return NULL;
+}
+
 static Eina_Bool
 _ecore_evas_wl_common_cb_global_added(void *d EINA_UNUSED, int t EINA_UNUSED, 
void *event)
 {
    Ecore_Wl2_Event_Global *ev = event;
-   EE_Wl_Device *device;
    Ecore_Evas *ee;
    Eina_List *l;
    char buf[32];
@@ -532,34 +564,27 @@ _ecore_evas_wl_common_cb_global_added(void *d 
EINA_UNUSED, int t EINA_UNUSED, vo
 
    EINA_LIST_FOREACH(ee_list, l, ee)
      {
-        Ecore_Evas_Engine_Wl_Data *wdata;
-        Evas_Device *dev;
-
-        device = calloc(1, sizeof(EE_Wl_Device));
-        EINA_SAFETY_ON_NULL_GOTO(device, err_device);
-
-        dev = evas_device_add_full(ee->evas, buf, "Wayland seat",
-                                   NULL, NULL,
-                                   EVAS_DEVICE_CLASS_SEAT,
-                                   EVAS_DEVICE_SUBCLASS_NONE);
-        EINA_SAFETY_ON_NULL_GOTO(dev, err_dev);
-
-        device->seat = dev;
-        device->id = ev->id;
+        Eina_List *ll;
+        EE_Wl_Device *device;
+        Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+        Eina_Bool already_present = EINA_FALSE;
 
-        wdata = ee->engine.data;
-        wdata->devices_list = eina_list_append(wdata->devices_list, device);
+        EINA_LIST_FOREACH(wdata->devices_list, ll, device)
+          {
+             if (device->id == ev->id)
+               {
+                  already_present = EINA_TRUE;
+                  break;
+               }
+          }
 
-        _ecore_evas_wl_common_device_event_add(ECORE_WL2_EVENT_DEVICE_ADDED,
-                                               ECORE_WL2_DEVICE_TYPE_SEAT,
-                                               ev->id, dev, ee);
+        if (!already_present && !_ecore_evas_wl_common_seat_add(ee, buf, 
ev->id))
+          goto err_add;
      }
 
    return ECORE_CALLBACK_PASS_ON;
 
-err_dev:
-   free(device);
-err_device:
+err_add:
    return ECORE_CALLBACK_PASS_ON;
 }
 
@@ -2006,6 +2031,72 @@ _ee_cb_sync_done(void *data, int type EINA_UNUSED, void 
*event EINA_UNUSED)
    return ECORE_CALLBACK_PASS_ON;
 }
 
+static Eina_Bool
+_ecore_wl2_devices_setup(Ecore_Evas *ee, Ecore_Wl2_Display *display)
+{
+   Eina_Bool r = EINA_TRUE;
+   Ecore_Wl2_Input *input;
+   Eina_Iterator *itr = ecore_wl2_display_inputs_get(display);
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(itr, EINA_FALSE);
+   EINA_ITERATOR_FOREACH(itr, input)
+     {
+        EE_Wl_Device *device;
+        Ecore_Wl2_Seat_Capabilities cap;
+        char buf[32];
+        unsigned int id;
+
+        id = ecore_wl2_input_seat_id_get(input);
+        cap = ecore_wl2_input_seat_capabilities_get(input);
+        //No seat, ignore...
+        if (cap == ECORE_WL2_SEAT_CAPABILITIES_NO_SEAT)
+          continue;
+
+        snprintf(buf, sizeof(buf), "seat-%u", id);
+        device = _ecore_evas_wl_common_seat_add(ee, buf, id);
+        if (!device)
+          {
+             r = EINA_FALSE;
+             break;
+          }
+        if (cap & ECORE_WL2_SEAT_CAPABILITIES_KEYBOARD)
+          {
+             device->keyboard = evas_device_add_full(ee->evas, "Keyboard",
+                                                     "A wayland keyboard 
device",
+                                                     device->seat, NULL,
+                                                     
EVAS_DEVICE_CLASS_KEYBOARD,
+                                                     
EVAS_DEVICE_SUBCLASS_NONE);
+             
_ecore_evas_wl_common_device_event_add(ECORE_WL2_EVENT_DEVICE_ADDED,
+                                                    
ECORE_WL2_DEVICE_TYPE_KEYBOARD,
+                                                    id, device->keyboard, ee);
+          }
+        if (cap & ECORE_WL2_SEAT_CAPABILITIES_POINTER)
+          {
+             device->pointer = evas_device_add_full(ee->evas, "Mouse",
+                                                    "A wayland pointer device",
+                                                    device->seat, NULL,
+                                                    EVAS_DEVICE_CLASS_MOUSE,
+                                                    EVAS_DEVICE_SUBCLASS_NONE);
+             
_ecore_evas_wl_common_device_event_add(ECORE_WL2_EVENT_DEVICE_ADDED,
+                                                    
ECORE_WL2_DEVICE_TYPE_POINTER,
+                                                    id, device->pointer, ee);
+          }
+        if (cap & ECORE_WL2_SEAT_CAPABILITIES_TOUCH)
+          {
+             device->touch = evas_device_add_full(ee->evas, "Touch",
+                                                  "A wayland touch device",
+                                                  device->seat, NULL,
+                                                  EVAS_DEVICE_CLASS_TOUCH,
+                                                  EVAS_DEVICE_SUBCLASS_NONE);
+             
_ecore_evas_wl_common_device_event_add(ECORE_WL2_EVENT_DEVICE_ADDED,
+                                                    
ECORE_WL2_DEVICE_TYPE_TOUCH,
+                                                    id, device->touch, ee);
+          }
+     }
+   eina_iterator_free(itr);
+   return r;
+}
+
 Ecore_Evas *
 _ecore_evas_wl_common_new_internal(const char *disp_name, unsigned int parent, 
int x, int y, int w, int h, Eina_Bool frame, const char *engine_name)
 {
@@ -2146,6 +2237,12 @@ _ecore_evas_wl_common_new_internal(const char 
*disp_name, unsigned int parent, i
           }
      }
 
+   if (!_ecore_wl2_devices_setup(ee, ewd))
+     {
+        ERR("Failed to create the devices");
+        goto eng_err;
+     }
+
    ee->engine.func->fn_render = _ecore_evas_wl_common_render;
 
    _ecore_evas_register(ee);

-- 


Reply via email to