devilhorns pushed a commit to branch master.

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

commit ba10e3547cffacaee92d10779703824dd2fc1460
Author: Chris Michael <cp.mich...@samsung.com>
Date:   Sun Nov 22 16:13:36 2015 -0500

    ecore-wl2: Start on implementing support for multi-seat
    
    Signed-off-by: Chris Michael <cp.mich...@samsung.com>
---
 src/Makefile_Ecore_Wl2.am             |   1 +
 src/lib/ecore_wl2/Ecore_Wl2.h         |  15 +++
 src/lib/ecore_wl2/ecore_wl2_display.c |   2 +-
 src/lib/ecore_wl2/ecore_wl2_input.c   |  29 +++--
 src/lib/ecore_wl2/ecore_wl2_private.h | 100 ++++++++++++++-
 src/lib/ecore_wl2/ecore_wl2_seat.c    | 233 ++++++++++++++++++++++++++++++++++
 6 files changed, 368 insertions(+), 12 deletions(-)

diff --git a/src/Makefile_Ecore_Wl2.am b/src/Makefile_Ecore_Wl2.am
index 0dc3dec..d08414b 100644
--- a/src/Makefile_Ecore_Wl2.am
+++ b/src/Makefile_Ecore_Wl2.am
@@ -12,6 +12,7 @@ lib/ecore_wl2/subsurface-client-protocol.h \
 lib/ecore_wl2/subsurface-protocol.c \
 lib/ecore_wl2/xdg-shell-client-protocol.h \
 lib/ecore_wl2/xdg-shell-protocol.c \
+lib/ecore_wl2/ecore_wl2_seat.c \
 lib/ecore_wl2/ecore_wl2_subsurf.c \
 lib/ecore_wl2/ecore_wl2_dnd.c \
 lib/ecore_wl2/ecore_wl2_window.c \
diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h
index 018365c..42875a6 100644
--- a/src/lib/ecore_wl2/Ecore_Wl2.h
+++ b/src/lib/ecore_wl2/Ecore_Wl2.h
@@ -37,6 +37,10 @@ typedef struct _Ecore_Wl2_Window Ecore_Wl2_Window;
 typedef struct _Ecore_Wl2_Display Ecore_Wl2_Display;
 typedef struct _Ecore_Wl2_Output Ecore_Wl2_Output;
 typedef struct _Ecore_Wl2_Input Ecore_Wl2_Input;
+typedef struct _Ecore_Wl2_Seat Ecore_Wl2_Seat;
+typedef struct _Ecore_Wl2_Pointer Ecore_Wl2_Pointer;
+typedef struct _Ecore_Wl2_Keyboard Ecore_Wl2_Keyboard;
+typedef struct _Ecore_Wl2_Touch Ecore_Wl2_Touch;
 
 typedef struct _Ecore_Wl2_Global
 {
@@ -135,6 +139,9 @@ typedef enum _Ecore_Wl2_Window_Type
    ECORE_WL2_WINDOW_TYPE_LAST
 } Ecore_Wl2_Window_Type;
 
+typedef void (*Ecore_Wl2_Bind_Cb)(struct wl_client *client, void *data, 
uint32_t version, uint32_t id);
+typedef void (*Ecore_Wl2_Unbind_Cb)(struct wl_resource *resource);
+
 EAPI extern int ECORE_WL2_EVENT_GLOBAL_ADDED;
 EAPI extern int ECORE_WL2_EVENT_GLOBAL_REMOVED;
 EAPI extern int ECORE_WL2_EVENT_FOCUS_IN;
@@ -983,6 +990,14 @@ EAPI void 
ecore_wl2_subsurface_opaque_region_set(Ecore_Wl2_Subsurface *subsurfac
  */
 EAPI int ecore_wl2_output_dpi_get(Ecore_Wl2_Output *output);
 
+EAPI Ecore_Wl2_Seat *ecore_wl2_seat_create(Ecore_Wl2_Display *display, const 
char *name, const struct wl_seat_interface *implementation, int version, 
Ecore_Wl2_Bind_Cb bind_cb, Ecore_Wl2_Unbind_Cb unbind_cb);
+EAPI void ecore_wl2_seat_destroy(Ecore_Wl2_Seat *seat);
+EAPI void ecore_wl2_seat_capabilities_send(Ecore_Wl2_Seat *seat, enum 
wl_seat_capability caps);
+EAPI void ecore_wl2_seat_pointer_release(Ecore_Wl2_Seat *seat);
+
+EAPI Ecore_Wl2_Pointer *ecore_wl2_pointer_get(Ecore_Wl2_Seat *seat);
+EAPI Eina_Bool ecore_wl2_pointer_resource_create(Ecore_Wl2_Pointer *ptr, 
struct wl_client *client, const struct wl_pointer_interface *implementation, 
int version, uint32_t id);
+
 /* # ifdef __cplusplus */
 /* } */
 /* # endif */
diff --git a/src/lib/ecore_wl2/ecore_wl2_display.c 
b/src/lib/ecore_wl2/ecore_wl2_display.c
index 22b76b7..b0c387f 100644
--- a/src/lib/ecore_wl2/ecore_wl2_display.c
+++ b/src/lib/ecore_wl2/ecore_wl2_display.c
@@ -108,7 +108,7 @@ _cb_global_add(void *data, struct wl_registry *registry, 
unsigned int id, const
    else if (!strcmp(interface, "wl_output"))
      _ecore_wl2_output_add(ewd, id);
    else if (!strcmp(interface, "wl_seat"))
-     _ecore_wl2_input_add(ewd, id);
+     _ecore_wl2_input_add(ewd, id, version);
 
 event:
    /* allocate space for event structure */
diff --git a/src/lib/ecore_wl2/ecore_wl2_input.c 
b/src/lib/ecore_wl2/ecore_wl2_input.c
index dccb184..7ccf1d1 100644
--- a/src/lib/ecore_wl2/ecore_wl2_input.c
+++ b/src/lib/ecore_wl2/ecore_wl2_input.c
@@ -1087,18 +1087,21 @@ _seat_cb_capabilities(void *data, struct wl_seat *seat, 
enum wl_seat_capability
         wl_pointer_set_user_data(input->wl.pointer, input);
         wl_pointer_add_listener(input->wl.pointer, &_pointer_listener, input);
 
-        if (!input->cursor.surface)
-          {
-             input->cursor.surface =
-               wl_compositor_create_surface(input->display->wl.compositor);
-          }
+        /* if (!input->cursor.surface) */
+        /*   { */
+        /*      input->cursor.surface = */
+        /*        wl_compositor_create_surface(input->display->wl.compositor); 
*/
+        /*   } */
      }
    else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && (input->wl.pointer))
      {
         if (input->cursor.surface) wl_surface_destroy(input->cursor.surface);
         input->cursor.surface = NULL;
 
-        wl_pointer_destroy(input->wl.pointer);
+        if (input->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
+          wl_pointer_release(input->wl.pointer);
+        else
+          wl_pointer_destroy(input->wl.pointer);
         input->wl.pointer = NULL;
      }
 
@@ -1110,7 +1113,10 @@ _seat_cb_capabilities(void *data, struct wl_seat *seat, 
enum wl_seat_capability
      }
    else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && (input->wl.keyboard))
      {
-        wl_keyboard_destroy(input->wl.keyboard);
+        if (input->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
+          wl_keyboard_release(input->wl.keyboard);
+        else
+          wl_keyboard_destroy(input->wl.keyboard);
         input->wl.keyboard = NULL;
      }
 
@@ -1122,7 +1128,10 @@ _seat_cb_capabilities(void *data, struct wl_seat *seat, 
enum wl_seat_capability
      }
    else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && (input->wl.touch))
      {
-        wl_touch_destroy(input->wl.touch);
+        if (input->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
+          wl_touch_release(input->wl.touch);
+        else
+          wl_touch_destroy(input->wl.touch);
         input->wl.touch = NULL;
      }
 }
@@ -1208,7 +1217,7 @@ _ecore_wl2_input_cursor_update(void *data)
 }
 
 void
-_ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned int id)
+_ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned int id, unsigned int 
version)
 {
    Ecore_Wl2_Input *input;
 
@@ -1216,7 +1225,7 @@ _ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned 
int id)
    if (!input) return;
 
    input->display = display;
-
+   input->seat_version = MIN(version, 4);
    input->repeat.rate = 0.025;
    input->repeat.delay = 0.4;
    input->repeat.enabled = EINA_TRUE;
diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h 
b/src/lib/ecore_wl2/ecore_wl2_private.h
index 26a15ca..c428993 100644
--- a/src/lib/ecore_wl2/ecore_wl2_private.h
+++ b/src/lib/ecore_wl2/ecore_wl2_private.h
@@ -5,6 +5,10 @@
 # include "Ecore_Wl2.h"
 # include "Ecore_Input.h"
 
+# ifndef MIN
+#  define MIN(x, y) (((x) < (y)) ? (x) : (y))
+# endif
+
 /* NB: Test if subsurface protocol is part of wayland code, if not then
  * include our own copy */
 # ifndef WL_SUBSURFACE_ERROR_ENUM
@@ -76,6 +80,7 @@ struct _Ecore_Wl2_Display
    Eina_Inlist *windows;
    Eina_Inlist *outputs;
    Eina_Inlist *inputs;
+   Eina_Inlist *seats;
 
    Eina_Bool sync_done : 1;
 };
@@ -157,6 +162,97 @@ typedef struct _Ecore_Wl2_Dnd_Source
    struct wl_array types;
 } Ecore_Wl2_Dnd_Source;
 
+
+/** TODO: Refactor ALL Input code :(
+ *
+ * wl_seat is a GROUP of Input Devices (such as):
+ *      keyboards, pointers, touch devices
+ */
+struct _Ecore_Wl2_Pointer
+{
+   EINA_INLIST;
+
+   Ecore_Wl2_Seat *seat;
+
+   double sx, sy;
+   unsigned int button;
+   unsigned int enter_serial;
+
+   struct
+     {
+        const char *name, *theme_name;
+        unsigned int index, size;
+        struct wl_cursor *wl_cursor;
+        struct wl_cursor_theme *theme;
+        struct wl_surface *surface;
+        struct wl_callback *frame_cb;
+        Ecore_Timer *timer;
+     } cursor;
+
+   struct
+     {
+        unsigned int button, count, timestamp;
+        Ecore_Wl2_Window *window;
+     } grab;
+
+   Ecore_Wl2_Window *focus;
+
+   Eina_List *resources;
+};
+
+struct _Ecore_Wl2_Keyboard
+{
+   EINA_INLIST;
+
+   struct
+     {
+        unsigned int button, count, timestamp;
+        Ecore_Wl2_Window *window;
+     } grab;
+};
+
+struct _Ecore_Wl2_Touch
+{
+   EINA_INLIST;
+
+   struct
+     {
+        unsigned int button, count, timestamp;
+        Ecore_Wl2_Window *window;
+     } grab;
+};
+
+struct _Ecore_Wl2_Seat
+{
+   EINA_INLIST;
+
+   uint32_t id;
+   uint32_t version;
+   const char *name;
+   struct wl_global *global;
+   const struct wl_seat_interface *implementation;
+
+   struct
+     {
+        struct wl_global *global;
+        struct wl_resource *resource;
+     } im;
+
+   Ecore_Wl2_Bind_Cb bind_cb;
+   Ecore_Wl2_Unbind_Cb unbind_cb;
+
+   Ecore_Wl2_Pointer *pointer;
+   int pointer_count;
+
+   Ecore_Wl2_Keyboard *keyboard;
+   int keyboard_count;
+
+   Ecore_Wl2_Touch *touch;
+   int touch_count;
+
+   Eina_List *resources;
+};
+
 struct _Ecore_Wl2_Input
 {
    EINA_INLIST;
@@ -246,6 +342,8 @@ struct _Ecore_Wl2_Input
      {
         Ecore_Wl2_Dnd_Source *source;
      } drag, selection;
+
+   unsigned int seat_version;
 };
 
 Ecore_Wl2_Window *_ecore_wl2_display_window_surface_find(Ecore_Wl2_Display 
*display, struct wl_surface *wl_surface);
@@ -253,7 +351,7 @@ Ecore_Wl2_Window 
*_ecore_wl2_display_window_surface_find(Ecore_Wl2_Display *disp
 void _ecore_wl2_output_add(Ecore_Wl2_Display *display, unsigned int id);
 void _ecore_wl2_output_del(Ecore_Wl2_Output *output);
 
-void _ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned int id);
+void _ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned int id, 
unsigned int version);
 void _ecore_wl2_input_del(Ecore_Wl2_Input *input);
 
 void _ecore_wl2_input_ungrab(Ecore_Wl2_Input *input);
diff --git a/src/lib/ecore_wl2/ecore_wl2_seat.c 
b/src/lib/ecore_wl2/ecore_wl2_seat.c
new file mode 100644
index 0000000..5d7dcdf
--- /dev/null
+++ b/src/lib/ecore_wl2/ecore_wl2_seat.c
@@ -0,0 +1,233 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ecore_wl2_private.h"
+
+static void
+_seat_cb_unbind(struct wl_resource *resource)
+{
+   Ecore_Wl2_Seat *seat;
+
+   DBG("Seat Unbind");
+
+   seat = wl_resource_get_user_data(resource);
+   if (!seat) return;
+
+   seat->resources = eina_list_remove(seat->resources, resource);
+
+   if (seat->unbind_cb) seat->unbind_cb(resource);
+}
+
+static void
+_seat_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t 
id)
+{
+   Ecore_Wl2_Seat *seat;
+   struct wl_resource *res;
+
+   seat = data;
+   seat->id = id;
+
+   DBG("Seat Bind");
+
+   res = wl_resource_create(client, &wl_seat_interface, MIN(version, 4), id);
+   if (!res)
+     {
+        ERR("Failed to create seat resource: %m");
+        return;
+     }
+
+   seat->resources = eina_list_append(seat->resources, res);
+
+   wl_resource_set_implementation(res, seat->implementation, seat,
+                                  _seat_cb_unbind);
+
+   if (version >= WL_SEAT_NAME_SINCE_VERSION)
+     wl_seat_send_name(res, seat->name);
+
+   if (seat->bind_cb) seat->bind_cb(client, seat, version, id);
+}
+
+static void
+_pointer_cb_unbind(struct wl_resource *resource)
+{
+   Ecore_Wl2_Pointer *ptr;
+
+   DBG("Pointer Unbind");
+
+   ptr = wl_resource_get_user_data(resource);
+   if (!ptr) return;
+
+   ptr->resources = eina_list_remove(ptr->resources, resource);
+
+   /* wl_pointer_release(); */
+}
+
+static Ecore_Wl2_Pointer *
+_ecore_wl2_seat_pointer_create(Ecore_Wl2_Seat *seat)
+{
+   Ecore_Wl2_Pointer *ptr;
+
+   ptr = calloc(1, sizeof(Ecore_Wl2_Pointer));
+   if (!ptr) return NULL;
+
+   /* FIXME: Init pointer fields */
+
+   ptr->seat = seat;
+
+   return ptr;
+}
+
+static void
+_ecore_wl2_seat_pointer_destroy(Ecore_Wl2_Pointer *ptr)
+{
+   /* FIXME: Free pointer fields */
+   free(ptr);
+}
+
+EAPI Ecore_Wl2_Seat *
+ecore_wl2_seat_create(Ecore_Wl2_Display *display, const char *name, const 
struct wl_seat_interface *implementation, int version, Ecore_Wl2_Bind_Cb 
bind_cb, Ecore_Wl2_Unbind_Cb unbind_cb)
+{
+   Ecore_Wl2_Seat *seat;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
+
+   if (!name) name = "default";
+
+   EINA_INLIST_FOREACH(display->seats, seat)
+     {
+        if (!strcmp(seat->name, name))
+          return seat;
+     }
+
+   seat = calloc(1, sizeof(Ecore_Wl2_Seat));
+   if (!seat) return NULL;
+
+   seat->version = version;
+   seat->implementation = implementation;
+   seat->bind_cb = bind_cb;
+   seat->unbind_cb = unbind_cb;
+
+   eina_stringshare_replace(&seat->name, name);
+
+   seat->global =
+     wl_global_create(display->wl.display, &wl_seat_interface, seat->version,
+                      seat, _seat_cb_bind);
+   if (!seat->global)
+     {
+        ERR("Could not create seat global: %m");
+        free(seat);
+        return NULL;
+     }
+
+   return seat;
+}
+
+EAPI void
+ecore_wl2_seat_destroy(Ecore_Wl2_Seat *seat)
+{
+   EINA_SAFETY_ON_NULL_RETURN(seat);
+
+   eina_stringshare_del(seat->name);
+
+   if (seat->pointer) _ecore_wl2_seat_pointer_destroy(seat->pointer);
+
+   /* NB: Hmmm, should we iterate and free resources here ?? */
+
+   wl_global_destroy(seat->global);
+
+   free(seat);
+}
+
+EAPI void
+ecore_wl2_seat_capabilities_send(Ecore_Wl2_Seat *seat, enum wl_seat_capability 
caps)
+{
+   Eina_List *l;
+   struct wl_resource *res;
+
+   EINA_SAFETY_ON_NULL_RETURN(seat);
+
+   EINA_LIST_FOREACH(seat->resources, l, res)
+     wl_seat_send_capabilities(res, caps);
+}
+
+EAPI void
+ecore_wl2_seat_pointer_release(Ecore_Wl2_Seat *seat)
+{
+   enum wl_seat_capability caps = 0;
+
+   EINA_SAFETY_ON_NULL_RETURN(seat);
+
+   seat->pointer_count--;
+   if (seat->pointer_count == 0)
+     {
+        if (seat->pointer_count > 0)
+          caps |= WL_SEAT_CAPABILITY_POINTER;
+        if (seat->keyboard_count > 0)
+          caps |= WL_SEAT_CAPABILITY_KEYBOARD;
+        if (seat->touch_count > 0)
+          caps |= WL_SEAT_CAPABILITY_TOUCH;
+
+        ecore_wl2_seat_capabilities_send(seat, 0);
+     }
+}
+
+EAPI Ecore_Wl2_Pointer *
+ecore_wl2_pointer_get(Ecore_Wl2_Seat *seat)
+{
+   enum wl_seat_capability caps = 0;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(seat, NULL);
+
+   if (seat->pointer_count > 0)
+     caps |= WL_SEAT_CAPABILITY_POINTER;
+   if (seat->keyboard_count > 0)
+     caps |= WL_SEAT_CAPABILITY_KEYBOARD;
+   if (seat->touch_count > 0)
+     caps |= WL_SEAT_CAPABILITY_TOUCH;
+
+   if (seat->pointer)
+     {
+        seat->pointer_count += 1;
+        if (seat->pointer_count == 1)
+          {
+             caps |= WL_SEAT_CAPABILITY_POINTER;
+             ecore_wl2_seat_capabilities_send(seat, caps);
+          }
+
+        return seat->pointer;
+     }
+
+   seat->pointer = _ecore_wl2_seat_pointer_create(seat);
+   seat->pointer_count = 1;
+
+   caps |= WL_SEAT_CAPABILITY_POINTER;
+   ecore_wl2_seat_capabilities_send(seat, caps);
+
+   return seat->pointer;
+}
+
+EAPI Eina_Bool
+ecore_wl2_pointer_resource_create(Ecore_Wl2_Pointer *ptr, struct wl_client 
*client, const struct wl_pointer_interface *implementation, int version, 
uint32_t id)
+{
+   struct wl_resource *res;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
+
+   res = wl_resource_create(client, &wl_pointer_interface, version, id);
+   if (!res)
+     {
+        ERR("Could not create pointer resource: %m");
+        wl_client_post_no_memory(client);
+        return EINA_FALSE;
+     }
+
+   wl_resource_set_implementation(res, implementation, ptr, 
_pointer_cb_unbind);
+
+   ptr->resources = eina_list_append(ptr->resources, res);
+
+   /* FIXME: Hmmm, should we sent a pointer_enter to ptr->focus'd surface
+    * here like weston does ? */
+
+   return EINA_TRUE;
+}

-- 


Reply via email to