bufferqueue: implementation bufferqueue module 05/39505/5
authorSeunghun Lee <shiin.lee@samsung.com>
Sun, 17 May 2015 09:23:01 +0000 (18:23 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Mon, 18 May 2015 11:21:41 +0000 (04:21 -0700)
Change-Id: I4e6e8243ed29b242bfaa5823ecf5982fa3d277d7

configure.ac
src/modules/Makefile.mk
src/modules/Makefile_bufferqueue.mk [new file with mode: 0644]
src/modules/bufferqueue/bq_mgr.xml [new file with mode: 0644]
src/modules/bufferqueue/bq_mgr_protocol.c [new file with mode: 0644]
src/modules/bufferqueue/bq_mgr_protocol.h [new file with mode: 0644]
src/modules/bufferqueue/e_mod_main.c [new file with mode: 0644]

index 55ba0bfc0a30a971520767ee077ad0125e8d0d27..c1d3a097623706f0ea963b01a0c3e4642c46053c 100644 (file)
@@ -929,6 +929,16 @@ define([CHECK_MODULE_WL_DRM],
 ])
 AM_CONDITIONAL([HAVE_WL_DRM], [test "x${WL_DRM}" = "xtrue"])
 
+define([CHECK_MODULE_BUFFERQUEUE],
+[
+  if test "x${have_wayland_clients}" = "xyes" || test "x${e_cv_want_wayland_only}" = "xyes"; then
+    AC_E_CHECK_PKG(BUFFERQUEUE, [ ecore >= $efl_version eina >= $efl_version ], [BUFFERQUEUE=true], [BUFFERQUEUE=false])
+  else
+    BUFFERQUEUE=false
+  fi
+])
+AM_CONDITIONAL([HAVE_BUFFERQUEUE], [test "x${BUFFERQUEUE}" = "xtrue"])
+
 AC_E_OPTIONAL_MODULE([ibar], true)
 AC_E_OPTIONAL_MODULE([clock], true)
 AC_E_OPTIONAL_MODULE([pager], true)
@@ -986,6 +996,7 @@ AC_E_OPTIONAL_MODULE([wl_fb], $have_wayland, [CHECK_MODULE_WL_FB])
 AC_E_OPTIONAL_MODULE([wl_drm], $have_wayland, [CHECK_MODULE_WL_DRM])
 AC_E_OPTIONAL_MODULE([wl_screenshot], $have_wayland, [CHECK_MODULE_WL_SCREENSHOT])
 AC_E_OPTIONAL_MODULE([policy_mobile], true)
+AC_E_OPTIONAL_MODULE([bufferqueue], $have_wayland, [CHECK_MODULE_BUFFERQUEUE])
 
 HALT="/sbin/shutdown -h now"
 REBOOT="/sbin/shutdown -r now"
index 27184a9c77fa4b04ffd2ee6e5dcbf12221dd99f9..ee0f57fa46348d5729fd6ecd5edf9ad2b2c4d6c8 100644 (file)
@@ -132,3 +132,5 @@ include src/modules/Makefile_wl_fb.mk
 include src/modules/Makefile_wl_screenshot.mk
 
 include src/modules/Makefile_policy_mobile.mk
+
+include src/modules/Makefile_bufferqueue.mk
diff --git a/src/modules/Makefile_bufferqueue.mk b/src/modules/Makefile_bufferqueue.mk
new file mode 100644 (file)
index 0000000..de924df
--- /dev/null
@@ -0,0 +1,24 @@
+EXTRA_DIST += \
+src/modules/bufferqueue/bq_mgr_protocol.h \
+src/modules/bufferqueue/bq_mgr_protocol.c
+
+if USE_MODULE_BUFFERQUEUE
+bufferqueuedir = $(MDIR)/bufferqueue
+
+bufferqueuepkgdir = $(MDIR)/bufferqueue/$(MODULE_ARCH)
+bufferqueuepkg_LTLIBRARIES = src/modules/bufferqueue/module.la
+
+src_modules_bufferqueue_module_la_DEPENDENCIES = $(MDEPENDENCIES)
+src_modules_bufferqueue_module_la_CPPFLAGS  = $(MOD_CPPFLAGS) @BUFFERQUEUE_CFLAGS@ @WAYLAND_CFLAGS@ -DNEED_WL
+src_modules_bufferqueue_module_la_LIBADD   = $(LIBS) @BUFFERQUEUE_LIBS@ @WAYLAND_LIBS@
+src_modules_bufferqueue_module_la_LDFLAGS = $(MOD_LDFLAGS)
+
+src_modules_bufferqueue_module_la_SOURCES = src/modules/bufferqueue/e_mod_main.c \
+                                            src/modules/bufferqueue/e_mod_main.h \
+                                            src/modules/bufferqueue/bq_mgr_protocol.h \
+                                            src/modules/bufferqueue/bq_mgr_protocol.c
+
+PHONIES += bufferqueue install-bufferqueue
+bufferqueue: $(bufferqueuepkg_LTLIBRARIES) $(bufferqueue_DATA)
+install-bufferqueue: install-bufferqueuepkgLTLIBRARIES
+endif
diff --git a/src/modules/bufferqueue/bq_mgr.xml b/src/modules/bufferqueue/bq_mgr.xml
new file mode 100644 (file)
index 0000000..d86df2c
--- /dev/null
@@ -0,0 +1,123 @@
+<protocol name="bq_mgr">
+
+  <interface name="bq_mgr" version="1">
+    <enum name="error">
+      <entry name="invalid_permission" value="0"/>
+      <entry name="invalid_name" value="1"/>
+      <entry name="already_used" value="2"/>
+    </enum>
+    <request name="create_consumer">
+      <arg name="id" type="new_id" interface="bq_consumer"/>
+      <arg name="name" type="string"/>
+      <arg name="queue_size" type="int"/>
+      <arg name="width" type="int"/>
+      <arg name="height" type="int"/>
+    </request>
+    <request name="create_provider">
+      <arg name="id" type="new_id" interface="bq_provider"/>
+      <arg name="name" type="string"/>
+    </request>
+  </interface>
+
+  <interface name="bq_consumer" version="1">
+    <request name="release_buffer">
+      <arg name="buffer" type="object" interface="bq_buffer"/>
+    </request>
+
+    <event name="connected"/>
+    <event name="disconnected"/>
+    <event name="buffer_attached">
+      <arg name="buffer" type="new_id" interface="bq_buffer"/>
+      <arg name="engine" type="string"/>
+      <arg name="width" type="int"/>
+      <arg name="height" type="int"/>
+      <arg name="format" type="int"/>
+      <arg name="flags" type="uint"/>
+    </event>
+    <event name="set_buffer_id">
+      <arg name="buffer" type="object" interface="bq_buffer"/>
+      <arg name="id" type="int"/>
+      <arg name="offset0" type="int"/>
+      <arg name="stride0" type="int"/>
+      <arg name="offset1" type="int"/>
+      <arg name="stride1" type="int"/>
+      <arg name="offset2" type="int"/>
+      <arg name="stride2" type="int"/>
+    </event>
+    <event name="set_buffer_fd">
+      <arg name="buffer" type="object" interface="bq_buffer"/>
+      <arg name="fd" type="fd"/>
+      <arg name="offset0" type="int"/>
+      <arg name="stride0" type="int"/>
+      <arg name="offset1" type="int"/>
+      <arg name="stride1" type="int"/>
+      <arg name="offset2" type="int"/>
+      <arg name="stride2" type="int"/>
+    </event>
+    <event name="buffer_detached">
+      <arg name="buffer" type="object" interface="bq_buffer"/>
+    </event>
+    <event name="add_buffer">
+      <arg name="buffer" type="object" interface="bq_buffer"/>
+      <arg name="serial" type="uint"/>
+    </event>
+  </interface>
+
+  <interface name="bq_provider" version="1">
+    <enum name="error">
+      <entry name="overflow_queue_size" value="0"/>
+      <entry name="connection" value="1"/>
+    </enum>
+
+    <request name="attach_buffer">
+      <arg name="buffer" type="new_id" interface="bq_buffer"/>
+      <arg name="engine" type="string"/>
+      <arg name="width" type="int"/>
+      <arg name="height" type="int"/>
+      <arg name="format" type="int"/>
+      <arg name="flags" type="uint"/>
+    </request>
+    <request name="set_buffer_id">
+      <arg name="buffer" type="object" interface="bq_buffer"/>
+      <arg name="id" type="int"/>
+      <arg name="offset0" type="int"/>
+      <arg name="stride0" type="int"/>
+      <arg name="offset1" type="int"/>
+      <arg name="stride1" type="int"/>
+      <arg name="offset2" type="int"/>
+      <arg name="stride2" type="int"/>
+    </request>
+    <request name="set_buffer_fd">
+      <arg name="buffer" type="object" interface="bq_buffer"/>
+      <arg name="fd" type="fd"/>
+      <arg name="offset0" type="int"/>
+      <arg name="stride0" type="int"/>
+      <arg name="offset1" type="int"/>
+      <arg name="stride1" type="int"/>
+      <arg name="offset2" type="int"/>
+      <arg name="stride2" type="int"/>
+    </request>
+    <request name="detach_buffer">
+      <arg name="buffer" type="object" interface="bq_buffer"/>
+    </request>
+    <request name="enqueue_buffer">
+      <arg name="buffer" type="object" interface="bq_buffer"/>
+      <arg name="serial" type="uint"/>
+    </request>
+
+    <event name="connected">
+      <arg name="queue_size" type="int"/>
+      <arg name="width" type="int"/>
+      <arg name="height" type="int"/>
+    </event>
+    <event name="disconnected"/>
+    <event name="add_buffer">
+      <arg name="buffer" type="object" interface="bq_buffer"/>
+      <arg name="serial" type="uint"/>
+    </event>
+  </interface>
+
+  <interface name="bq_buffer" version="1">
+  </interface>
+</protocol>
+
diff --git a/src/modules/bufferqueue/bq_mgr_protocol.c b/src/modules/bufferqueue/bq_mgr_protocol.c
new file mode 100644 (file)
index 0000000..fe8b98c
--- /dev/null
@@ -0,0 +1,131 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include "wayland-util.h"
+
+extern const struct wl_interface bq_buffer_interface;
+extern const struct wl_interface bq_consumer_interface;
+extern const struct wl_interface bq_provider_interface;
+
+static const struct wl_interface *types[] = {
+       NULL,
+       NULL,
+       NULL,
+       &bq_consumer_interface,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       &bq_provider_interface,
+       NULL,
+       &bq_buffer_interface,
+       &bq_buffer_interface,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       &bq_buffer_interface,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       &bq_buffer_interface,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       &bq_buffer_interface,
+       &bq_buffer_interface,
+       NULL,
+       &bq_buffer_interface,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       &bq_buffer_interface,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       &bq_buffer_interface,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       &bq_buffer_interface,
+       &bq_buffer_interface,
+       NULL,
+       &bq_buffer_interface,
+       NULL,
+};
+
+static const struct wl_message bq_mgr_requests[] = {
+       { "create_consumer", "nsiii", types + 3 },
+       { "create_provider", "ns", types + 8 },
+};
+
+WL_EXPORT const struct wl_interface bq_mgr_interface = {
+       "bq_mgr", 1,
+       2, bq_mgr_requests,
+       0, NULL,
+};
+
+static const struct wl_message bq_consumer_requests[] = {
+       { "release_buffer", "o", types + 10 },
+};
+
+static const struct wl_message bq_consumer_events[] = {
+       { "connected", "", types + 0 },
+       { "disconnected", "", types + 0 },
+       { "buffer_attached", "nsiiiu", types + 11 },
+       { "set_buffer_id", "oiiiiiii", types + 17 },
+       { "set_buffer_fd", "ohiiiiii", types + 25 },
+       { "buffer_detached", "o", types + 33 },
+       { "add_buffer", "ou", types + 34 },
+};
+
+WL_EXPORT const struct wl_interface bq_consumer_interface = {
+       "bq_consumer", 1,
+       1, bq_consumer_requests,
+       7, bq_consumer_events,
+};
+
+static const struct wl_message bq_provider_requests[] = {
+       { "attach_buffer", "nsiiiu", types + 36 },
+       { "set_buffer_id", "oiiiiiii", types + 42 },
+       { "set_buffer_fd", "ohiiiiii", types + 50 },
+       { "detach_buffer", "o", types + 58 },
+       { "enqueue_buffer", "ou", types + 59 },
+};
+
+static const struct wl_message bq_provider_events[] = {
+       { "connected", "iii", types + 0 },
+       { "disconnected", "", types + 0 },
+       { "add_buffer", "ou", types + 61 },
+};
+
+WL_EXPORT const struct wl_interface bq_provider_interface = {
+       "bq_provider", 1,
+       5, bq_provider_requests,
+       3, bq_provider_events,
+};
+
+WL_EXPORT const struct wl_interface bq_buffer_interface = {
+       "bq_buffer", 1,
+       0, NULL,
+       0, NULL,
+};
+
diff --git a/src/modules/bufferqueue/bq_mgr_protocol.h b/src/modules/bufferqueue/bq_mgr_protocol.h
new file mode 100644 (file)
index 0000000..b2d7bcc
--- /dev/null
@@ -0,0 +1,247 @@
+#ifndef BQ_MGR_SERVER_PROTOCOL_H
+#define BQ_MGR_SERVER_PROTOCOL_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-server.h"
+
+struct wl_client;
+struct wl_resource;
+
+struct bq_mgr;
+struct bq_consumer;
+struct bq_provider;
+struct bq_buffer;
+
+extern const struct wl_interface bq_mgr_interface;
+extern const struct wl_interface bq_consumer_interface;
+extern const struct wl_interface bq_provider_interface;
+extern const struct wl_interface bq_buffer_interface;
+
+#ifndef BQ_MGR_ERROR_ENUM
+#define BQ_MGR_ERROR_ENUM
+enum bq_mgr_error {
+       BQ_MGR_ERROR_INVALID_PERMISSION = 0,
+       BQ_MGR_ERROR_INVALID_NAME = 1,
+       BQ_MGR_ERROR_ALREADY_USED = 2,
+};
+#endif /* BQ_MGR_ERROR_ENUM */
+
+struct bq_mgr_interface {
+       /**
+        * create_consumer - (none)
+        * @id: (none)
+        * @name: (none)
+        * @queue_size: (none)
+        * @width: (none)
+        * @height: (none)
+        */
+       void (*create_consumer)(struct wl_client *client,
+                               struct wl_resource *resource,
+                               uint32_t id,
+                               const char *name,
+                               int32_t queue_size,
+                               int32_t width,
+                               int32_t height);
+       /**
+        * create_provider - (none)
+        * @id: (none)
+        * @name: (none)
+        */
+       void (*create_provider)(struct wl_client *client,
+                               struct wl_resource *resource,
+                               uint32_t id,
+                               const char *name);
+};
+
+
+struct bq_consumer_interface {
+       /**
+        * release_buffer - (none)
+        * @buffer: (none)
+        */
+       void (*release_buffer)(struct wl_client *client,
+                              struct wl_resource *resource,
+                              struct wl_resource *buffer);
+};
+
+#define BQ_CONSUMER_CONNECTED  0
+#define BQ_CONSUMER_DISCONNECTED       1
+#define BQ_CONSUMER_BUFFER_ATTACHED    2
+#define BQ_CONSUMER_SET_BUFFER_ID      3
+#define BQ_CONSUMER_SET_BUFFER_FD      4
+#define BQ_CONSUMER_BUFFER_DETACHED    5
+#define BQ_CONSUMER_ADD_BUFFER 6
+
+#define BQ_CONSUMER_CONNECTED_SINCE_VERSION    1
+#define BQ_CONSUMER_DISCONNECTED_SINCE_VERSION 1
+#define BQ_CONSUMER_BUFFER_ATTACHED_SINCE_VERSION      1
+#define BQ_CONSUMER_SET_BUFFER_ID_SINCE_VERSION        1
+#define BQ_CONSUMER_SET_BUFFER_FD_SINCE_VERSION        1
+#define BQ_CONSUMER_BUFFER_DETACHED_SINCE_VERSION      1
+#define BQ_CONSUMER_ADD_BUFFER_SINCE_VERSION   1
+
+static inline void
+bq_consumer_send_connected(struct wl_resource *resource_)
+{
+       wl_resource_post_event(resource_, BQ_CONSUMER_CONNECTED);
+}
+
+static inline void
+bq_consumer_send_disconnected(struct wl_resource *resource_)
+{
+       wl_resource_post_event(resource_, BQ_CONSUMER_DISCONNECTED);
+}
+
+static inline void
+bq_consumer_send_buffer_attached(struct wl_resource *resource_, struct wl_resource *buffer, const char *engine, int32_t width, int32_t height, int32_t format, uint32_t flags)
+{
+       wl_resource_post_event(resource_, BQ_CONSUMER_BUFFER_ATTACHED, buffer, engine, width, height, format, flags);
+}
+
+static inline void
+bq_consumer_send_set_buffer_id(struct wl_resource *resource_, struct wl_resource *buffer, int32_t id, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
+{
+       wl_resource_post_event(resource_, BQ_CONSUMER_SET_BUFFER_ID, buffer, id, offset0, stride0, offset1, stride1, offset2, stride2);
+}
+
+static inline void
+bq_consumer_send_set_buffer_fd(struct wl_resource *resource_, struct wl_resource *buffer, int32_t fd, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
+{
+       wl_resource_post_event(resource_, BQ_CONSUMER_SET_BUFFER_FD, buffer, fd, offset0, stride0, offset1, stride1, offset2, stride2);
+}
+
+static inline void
+bq_consumer_send_buffer_detached(struct wl_resource *resource_, struct wl_resource *buffer)
+{
+       wl_resource_post_event(resource_, BQ_CONSUMER_BUFFER_DETACHED, buffer);
+}
+
+static inline void
+bq_consumer_send_add_buffer(struct wl_resource *resource_, struct wl_resource *buffer, uint32_t serial)
+{
+       wl_resource_post_event(resource_, BQ_CONSUMER_ADD_BUFFER, buffer, serial);
+}
+
+#ifndef BQ_PROVIDER_ERROR_ENUM
+#define BQ_PROVIDER_ERROR_ENUM
+enum bq_provider_error {
+       BQ_PROVIDER_ERROR_OVERFLOW_QUEUE_SIZE = 0,
+       BQ_PROVIDER_ERROR_CONNECTION = 1,
+};
+#endif /* BQ_PROVIDER_ERROR_ENUM */
+
+struct bq_provider_interface {
+       /**
+        * attach_buffer - (none)
+        * @buffer: (none)
+        * @engine: (none)
+        * @width: (none)
+        * @height: (none)
+        * @format: (none)
+        * @flags: (none)
+        */
+       void (*attach_buffer)(struct wl_client *client,
+                             struct wl_resource *resource,
+                             uint32_t buffer,
+                             const char *engine,
+                             int32_t width,
+                             int32_t height,
+                             int32_t format,
+                             uint32_t flags);
+       /**
+        * set_buffer_id - (none)
+        * @buffer: (none)
+        * @id: (none)
+        * @offset0: (none)
+        * @stride0: (none)
+        * @offset1: (none)
+        * @stride1: (none)
+        * @offset2: (none)
+        * @stride2: (none)
+        */
+       void (*set_buffer_id)(struct wl_client *client,
+                             struct wl_resource *resource,
+                             struct wl_resource *buffer,
+                             int32_t id,
+                             int32_t offset0,
+                             int32_t stride0,
+                             int32_t offset1,
+                             int32_t stride1,
+                             int32_t offset2,
+                             int32_t stride2);
+       /**
+        * set_buffer_fd - (none)
+        * @buffer: (none)
+        * @fd: (none)
+        * @offset0: (none)
+        * @stride0: (none)
+        * @offset1: (none)
+        * @stride1: (none)
+        * @offset2: (none)
+        * @stride2: (none)
+        */
+       void (*set_buffer_fd)(struct wl_client *client,
+                             struct wl_resource *resource,
+                             struct wl_resource *buffer,
+                             int32_t fd,
+                             int32_t offset0,
+                             int32_t stride0,
+                             int32_t offset1,
+                             int32_t stride1,
+                             int32_t offset2,
+                             int32_t stride2);
+       /**
+        * detach_buffer - (none)
+        * @buffer: (none)
+        */
+       void (*detach_buffer)(struct wl_client *client,
+                             struct wl_resource *resource,
+                             struct wl_resource *buffer);
+       /**
+        * enqueue_buffer - (none)
+        * @buffer: (none)
+        * @serial: (none)
+        */
+       void (*enqueue_buffer)(struct wl_client *client,
+                              struct wl_resource *resource,
+                              struct wl_resource *buffer,
+                              uint32_t serial);
+};
+
+#define BQ_PROVIDER_CONNECTED  0
+#define BQ_PROVIDER_DISCONNECTED       1
+#define BQ_PROVIDER_ADD_BUFFER 2
+
+#define BQ_PROVIDER_CONNECTED_SINCE_VERSION    1
+#define BQ_PROVIDER_DISCONNECTED_SINCE_VERSION 1
+#define BQ_PROVIDER_ADD_BUFFER_SINCE_VERSION   1
+
+static inline void
+bq_provider_send_connected(struct wl_resource *resource_, int32_t queue_size, int32_t width, int32_t height)
+{
+       wl_resource_post_event(resource_, BQ_PROVIDER_CONNECTED, queue_size, width, height);
+}
+
+static inline void
+bq_provider_send_disconnected(struct wl_resource *resource_)
+{
+       wl_resource_post_event(resource_, BQ_PROVIDER_DISCONNECTED);
+}
+
+static inline void
+bq_provider_send_add_buffer(struct wl_resource *resource_, struct wl_resource *buffer, uint32_t serial)
+{
+       wl_resource_post_event(resource_, BQ_PROVIDER_ADD_BUFFER, buffer, serial);
+}
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/modules/bufferqueue/e_mod_main.c b/src/modules/bufferqueue/e_mod_main.c
new file mode 100644 (file)
index 0000000..304d165
--- /dev/null
@@ -0,0 +1,933 @@
+#define E_COMP_WL
+#include "e.h"
+#include "bq_mgr_protocol.h"
+
+#define E_BQ_MGR_TYPE         (int)0xE0b91001
+#define E_BQ_QUEUE_TYPE       (int)0xE0b91002
+#define E_BQ_CONSUMER_TYPE    (int)0xE0b91003
+#define E_BQ_PROVIDER         (int)0xE0b91004
+#define E_BQ_BUFFER_TYPE      (int)0xE0b91005
+
+#define ARRAY_LENGTH(a)       (sizeof (a) / sizeof (a)[0])
+
+typedef struct _E_Bq_Mgr E_Bq_Mgr;
+typedef struct _E_Bq_Queue E_Bq_Queue;
+typedef struct _E_Bq_Consumer E_Bq_Consumer;
+typedef struct _E_Bq_Provider E_Bq_Provider;
+typedef struct _E_Bq_Buffer E_Bq_Buffer;
+
+typedef enum _E_Bq_Buffer_Type E_Bq_Buffer_Type;
+
+enum _E_Bq_Buffer_Type
+{
+   E_BQ_BUFFER_TYPE_ID,
+   E_BQ_BUFFER_TYPE_FD,
+};
+
+struct _E_Bq_Mgr
+{
+   E_Object e_obj_inherit;
+
+   int self_dpy;
+   struct wl_display *wdpy;
+   struct wl_event_source *signals[3];
+   struct wl_event_loop *loop;
+
+   /* BufferQueue manager */
+   struct wl_global *global;
+   Eina_Hash *bqs;
+
+   Ecore_Fd_Handler *fd_hdlr;
+   Ecore_Idle_Enterer *idler;
+};
+
+struct _E_Bq_Queue
+{
+   E_Object e_obj_inherit;
+   Eina_Hash *link;
+
+   char *name;
+   struct wl_signal connect;
+
+   E_Bq_Consumer *consumer;
+   E_Bq_Provider *provider;
+   Eina_Inlist *buffers;
+};
+
+struct _E_Bq_Consumer
+{
+   E_Object e_obj_inherit;
+   E_Bq_Queue *bq;
+
+   int32_t queue_size;
+   int32_t width;
+   int32_t height;
+};
+
+struct _E_Bq_Provider
+{
+   E_Object e_obj_inherit;
+   E_Bq_Queue *bq;
+};
+
+struct _E_Bq_Buffer
+{
+   E_Object e_obj_inherit; /*Don't use wl_resource in e_obj*/
+   EINA_INLIST;
+
+   struct wl_resource *consumer;
+   struct wl_resource *provider;
+   uint32_t serial;
+
+   char *engine;
+   E_Bq_Buffer_Type type;
+   int32_t width;
+   int32_t height;
+   int32_t format;
+   uint32_t flags;
+
+   int32_t id;
+   int32_t offset0;
+   int32_t stride0;
+   int32_t offset1;
+   int32_t stride1;
+   int32_t offset2;
+   int32_t stride2;
+};
+
+static void _e_bq_mgr_consumer_side_buffer_set(E_Bq_Consumer *consumer, E_Bq_Buffer *buffer);
+
+static Eina_Bool
+_e_bq_mgr_wl_cb_read(void *data, Ecore_Fd_Handler *hdl EINA_UNUSED)
+{
+   E_Bq_Mgr *bq_mgr = data;
+
+   if (!bq_mgr)
+     return ECORE_CALLBACK_RENEW;
+
+   if (!bq_mgr->wdpy)
+     return ECORE_CALLBACK_RENEW;
+
+   /* flush any pending client events */
+   wl_display_flush_clients(bq_mgr->wdpy);
+
+   /* dispatch any pending main loop events */
+   wl_event_loop_dispatch(bq_mgr->loop, 0);
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+_e_bq_mgr_wl_cb_idle(void *data)
+{
+   E_Bq_Mgr *bq_mgr = data;
+
+   if (!bq_mgr)
+     return ECORE_CALLBACK_RENEW;
+
+   if (!bq_mgr->wdpy)
+     return ECORE_CALLBACK_RENEW;
+
+   /* flush any pending client events */
+   wl_display_flush_clients(bq_mgr->wdpy);
+
+   /* dispatch any pending main loop events */
+   wl_event_loop_dispatch(bq_mgr->loop, 0);
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+static int
+_e_bq_mgr_on_term_signal(int signal_number, void *data)
+{
+   E_Bq_Mgr *bq_mgr = data;
+
+   ERR("caught signal %d\n", signal_number);
+
+   wl_display_terminate(bq_mgr->wdpy);
+
+   return 1;
+}
+
+static void
+_e_bq_mgr_free(E_Bq_Mgr *bq_mgr)
+{
+   int i;
+
+   if (!bq_mgr->self_dpy)
+     return;
+
+   for (i = (ARRAY_LENGTH(bq_mgr->signals) - 1); i >= 0; i--)
+     {
+        if (bq_mgr->signals[i])
+          wl_event_source_remove(bq_mgr->signals[i]);
+     }
+
+   if (bq_mgr->wdpy)
+     wl_display_destroy(bq_mgr->wdpy);
+}
+
+static E_Bq_Mgr *
+_e_bq_mgr_new(char *sock_name)
+{
+   E_Comp *comp;
+   E_Bq_Mgr *bq_mgr;
+   E_Comp_Data *cdata;
+   int fd;
+   static char *default_sock_name = "e_bq_mgr_daemon";
+
+   bq_mgr = E_OBJECT_ALLOC(E_Bq_Mgr, E_BQ_MGR_TYPE, _e_bq_mgr_free);
+   if (!bq_mgr)
+     return NULL;
+
+   /* try to get the current compositor */
+   if (!(comp = e_comp))
+     return NULL;
+
+   if ((comp->comp_type == E_PIXMAP_TYPE_X) ||
+       (sock_name != NULL))
+     {
+        bq_mgr->wdpy = wl_display_create();
+        bq_mgr->loop = wl_display_get_event_loop(bq_mgr->wdpy);
+        if (bq_mgr->loop)
+          {
+             free(bq_mgr);
+             return NULL;
+          }
+
+        bq_mgr->signals[0] =
+           wl_event_loop_add_signal(bq_mgr->loop, SIGTERM,
+                                    _e_bq_mgr_on_term_signal, bq_mgr);
+        bq_mgr->signals[1] =
+           wl_event_loop_add_signal(bq_mgr->loop, SIGINT,
+                                    _e_bq_mgr_on_term_signal, bq_mgr);
+        bq_mgr->signals[2] =
+           wl_event_loop_add_signal(bq_mgr->loop, SIGQUIT,
+                                    _e_bq_mgr_on_term_signal, bq_mgr);
+
+        if (!sock_name)
+          sock_name = default_sock_name;
+
+        wl_display_add_socket(bq_mgr->wdpy, sock_name);
+
+        fd = wl_event_loop_get_fd(bq_mgr->loop);
+
+        bq_mgr->fd_hdlr =
+           ecore_main_fd_handler_add(fd, ECORE_FD_READ | ECORE_FD_WRITE,
+                                     _e_bq_mgr_wl_cb_read, bq_mgr, NULL, NULL);
+
+        bq_mgr->idler = ecore_idle_enterer_add(_e_bq_mgr_wl_cb_idle, bq_mgr);
+
+        bq_mgr->self_dpy = 1;
+     }
+   else
+     {
+        /* try to get the compositor data */
+        cdata = comp->wl_comp_data;
+        if (!cdata)
+          {
+             free(bq_mgr);
+             return NULL;
+          }
+
+        bq_mgr->wdpy = cdata->wl.disp;
+        bq_mgr->loop = wl_display_get_event_loop(bq_mgr->wdpy);
+        bq_mgr->self_dpy = 0;
+     }
+
+   return bq_mgr;
+}
+
+static void
+_e_bq_mgr_bq_free(E_Bq_Queue *bq)
+{
+   E_Bq_Buffer *bq_buf;
+
+   if (!bq)
+     return;
+
+   DBG("destroy buffer queue : %s\n", bq->name);
+
+   if (bq->consumer)
+     {
+        wl_resource_destroy(e_object_data_get(E_OBJECT(bq->consumer)));
+        bq->consumer = NULL;
+     }
+
+   if (bq->provider)
+     {
+        wl_resource_destroy(e_object_data_get(E_OBJECT(bq->provider)));
+        bq->provider = NULL;
+     }
+
+   while (bq->buffers)
+     {
+        bq_buf = EINA_INLIST_CONTAINER_GET(bq->buffers, E_Bq_Buffer);
+        bq->buffers = eina_inlist_remove(bq->buffers, bq->buffers);
+
+        if (bq_buf->consumer)
+          {
+             wl_resource_destroy(bq_buf->consumer);
+             bq_buf->consumer = NULL;
+          }
+
+        if (bq_buf->provider)
+          {
+             wl_resource_destroy(bq_buf->provider);
+             bq_buf->provider = NULL;
+          }
+     }
+
+   if (bq->link)
+     {
+        eina_hash_del(bq->link, bq->name, bq);
+        bq->link = NULL;
+     }
+
+   if (bq->name)
+     {
+        free(bq->name);
+        bq->name = NULL;
+     }
+}
+
+static E_Bq_Queue *
+_e_bq_mgr_bq_new(E_Bq_Mgr *bq_mgr, const char *name)
+{
+   E_Bq_Queue *bq;
+
+   bq = eina_hash_find(bq_mgr->bqs, name);
+   if (bq)
+     {
+        e_object_ref(E_OBJECT(bq));
+        return bq;
+     }
+
+   bq = E_OBJECT_ALLOC(E_Bq_Queue, E_BQ_QUEUE_TYPE, _e_bq_mgr_bq_free);
+   if (!bq)
+     return NULL;
+
+   bq->link = bq_mgr->bqs;
+   bq->name = strdup(name);
+
+   if (!eina_hash_add(bq->link, bq->name, bq))
+     {
+        free(bq->name);
+        free(bq);
+        return NULL;
+     }
+
+   wl_signal_init(&bq->connect);
+   bq->buffers = NULL;
+
+   return bq;
+}
+
+static void
+_e_bq_mgr_buffer_consumer_release_buffer(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer)
+{
+   E_Bq_Queue *bq;
+   E_Bq_Provider *provider;
+   E_Bq_Consumer *consumer = wl_resource_get_user_data(resource);
+   E_Bq_Buffer *bq_buf = wl_resource_get_user_data(buffer);
+
+   if ((!consumer) || (!bq_buf))
+     return;
+
+   bq = consumer->bq;
+   provider = bq->provider;
+
+   if (provider && bq_buf->provider)
+     {
+        bq_provider_send_add_buffer(e_object_data_get(E_OBJECT(provider)),
+                                    bq_buf->provider, bq_buf->serial);
+     }
+}
+
+static const struct bq_consumer_interface _bq_consumer_interface = {
+     _e_bq_mgr_buffer_consumer_release_buffer
+};
+
+static void
+_e_bq_mgr_buffer_consumer_destroy(struct wl_resource *resource)
+{
+   E_Bq_Consumer *consumer = wl_resource_get_user_data(resource);
+   E_Bq_Provider *provider;
+   E_Bq_Queue *bq;
+   E_Bq_Buffer *bq_buf;
+
+   if (!consumer)
+     return;
+
+   DBG("destroy buffer consumer : %s\n", consumer->bq->name);
+
+   bq = consumer->bq;
+   provider = bq->provider;
+
+   bq->consumer = NULL;
+   e_object_data_set(E_OBJECT(consumer), NULL);
+
+   if (provider)
+     bq_provider_send_disconnected(e_object_data_get(E_OBJECT(provider)));
+
+   while (bq->buffers)
+     {
+        bq_buf = EINA_INLIST_CONTAINER_GET(bq->buffers, E_Bq_Buffer);
+        bq->buffers = eina_inlist_remove(bq->buffers, bq->buffers);
+
+        DBG("destroy BUFFER : %d\n", bq_buf->type);
+
+        if (bq_buf->consumer)
+          {
+             wl_resource_destroy(bq_buf->consumer);
+             bq_buf->consumer = NULL;
+             e_object_unref(E_OBJECT(bq_buf));
+          }
+
+        if (bq_buf->provider)
+          {
+             wl_resource_destroy(bq_buf->provider);
+             bq_buf->provider = NULL;
+             e_object_del(E_OBJECT(bq_buf));
+          }
+     }
+
+   e_object_unref(E_OBJECT(bq));
+   e_object_del(E_OBJECT(consumer));
+}
+
+static void
+_e_bq_mgr_buffer_consumer_free(E_Bq_Consumer *consumer)
+{
+   free(consumer);
+}
+
+static void
+_e_bq_mgr_buffer_destroy(struct wl_resource *resource)
+{
+   E_Bq_Buffer *bq_buf = wl_resource_get_user_data(resource);
+
+   if (!bq_buf)
+     return;
+
+   if (bq_buf->consumer == resource)
+     {
+        DBG("destroy buffer : consumer");
+     }
+   else if (bq_buf->provider == resource)
+     {
+        DBG("destroy buffer : provider");
+     }
+}
+
+static void
+_e_bq_mgr_consumer_side_buffer_create(E_Bq_Consumer *consumer, E_Bq_Buffer *buffer)
+{
+   struct wl_resource *resource;
+
+   if (!consumer)
+     return;
+
+   resource = e_object_data_get(E_OBJECT(consumer));
+   buffer->consumer = wl_resource_create(wl_resource_get_client(resource),
+                                        &bq_buffer_interface, 1, 0);
+
+   wl_resource_set_implementation(buffer->consumer, NULL, buffer, _e_bq_mgr_buffer_destroy);
+   e_object_ref(E_OBJECT(buffer));
+
+   bq_consumer_send_buffer_attached(resource,
+                                    buffer->consumer,
+                                    buffer->engine,
+                                    buffer->width,
+                                    buffer->height,
+                                    buffer->format,
+                                    buffer->flags);
+}
+
+static void
+_e_bq_mgr_consumer_side_buffer_set(E_Bq_Consumer *consumer, E_Bq_Buffer *buffer)
+{
+   struct wl_resource *resource;
+
+   if (!consumer)
+     return;
+
+   if (!buffer)
+     return;
+
+   if (!buffer->consumer)
+     return;
+
+   resource = e_object_data_get(E_OBJECT(consumer));
+
+   if (buffer->type == E_BQ_BUFFER_TYPE_ID)
+     {
+        bq_consumer_send_set_buffer_id(resource,
+                                       buffer->consumer,
+                                       buffer->id,
+                                       buffer->offset0,
+                                       buffer->stride0,
+                                       buffer->offset1,
+                                       buffer->stride1,
+                                       buffer->offset2,
+                                       buffer->stride2);
+     }
+   else
+     {
+        bq_consumer_send_set_buffer_fd(resource,
+                                       buffer->consumer,
+                                       buffer->id,
+                                       buffer->offset0,
+                                       buffer->stride0,
+                                       buffer->offset1,
+                                       buffer->stride1,
+                                       buffer->offset2,
+                                       buffer->stride2);
+        close(buffer->id);
+     }
+}
+
+static void
+_e_bq_mgr_bq_create_consumer(struct wl_client *client, struct wl_resource *resource, uint32_t id, const char *name, int32_t queue_size, int32_t width, int32_t height)
+{
+   E_Bq_Mgr *bq_mgr = wl_resource_get_user_data(resource);
+   E_Bq_Queue *bq;
+   E_Bq_Consumer *consumer;
+   E_Bq_Provider *provider;
+   E_Bq_Buffer *bq_buf;
+   struct wl_resource *new_resource;
+
+   if (!bq_mgr)
+     return;
+
+   bq = _e_bq_mgr_bq_new(bq_mgr, name);
+   if (!bq)
+     return;
+
+   if (bq->consumer)
+     {
+        e_object_unref(E_OBJECT(bq));
+        wl_resource_post_error(resource,
+                               BQ_MGR_ERROR_ALREADY_USED,
+                               "%s consumer already used", name);
+        return;
+     }
+
+   consumer = E_OBJECT_ALLOC(E_Bq_Consumer, E_BQ_CONSUMER_TYPE, _e_bq_mgr_buffer_consumer_free);
+   if (!consumer)
+     return;
+
+   new_resource = wl_resource_create(client,
+                                     &bq_consumer_interface,
+                                     1, id);
+   if (!new_resource)
+     {
+        free(consumer);
+        wl_client_post_no_memory(client);
+        return;
+     }
+
+   e_object_data_set(E_OBJECT(consumer), new_resource);
+   wl_resource_set_implementation(new_resource,
+                                  &_bq_consumer_interface,
+                                  consumer,
+                                  _e_bq_mgr_buffer_consumer_destroy);
+
+   consumer->bq = bq;
+   consumer->queue_size = queue_size;
+   consumer->width = width;
+   consumer->height = height;
+
+   provider = bq->provider;
+   bq->consumer = consumer;
+   if (provider)
+     {
+        bq_provider_send_connected(e_object_data_get(E_OBJECT(provider)),
+                                   queue_size, width, height);
+        bq_consumer_send_connected(new_resource);
+     }
+
+   EINA_INLIST_FOREACH(bq->buffers, bq_buf)
+     {
+        _e_bq_mgr_consumer_side_buffer_create(consumer, bq_buf);
+        _e_bq_mgr_consumer_side_buffer_set(consumer, bq_buf);
+     }
+}
+
+static void
+_e_bq_mgr_buffer_free(E_Bq_Buffer *bq_buf)
+{
+   if (bq_buf->engine)
+     free(bq_buf->engine);
+}
+
+static void
+_e_bq_mgr_provider_buffer_attach(struct wl_client *client, struct wl_resource *resource, uint32_t buffer, const char *engine, int32_t width, int32_t height, int32_t format, uint32_t flags)
+{
+   E_Bq_Provider *provider = wl_resource_get_user_data(resource);
+   E_Bq_Consumer *consumer;
+   E_Bq_Queue *bq;
+   E_Bq_Buffer *bq_buf;
+
+   if (!provider)
+     return;
+
+   bq = provider->bq;
+   consumer = bq->consumer;
+
+   bq_buf = E_OBJECT_ALLOC(E_Bq_Buffer, E_BQ_BUFFER_TYPE, _e_bq_mgr_buffer_free);
+   bq_buf->provider = wl_resource_create(client, &bq_buffer_interface, 1, buffer);
+   if (!bq_buf->provider)
+     {
+        free(bq_buf);
+        wl_client_post_no_memory(client);
+        return;
+     }
+
+   wl_resource_set_implementation(bq_buf->provider, NULL, bq_buf, _e_bq_mgr_buffer_destroy);
+
+   bq_buf->engine = strdup(engine);
+   bq_buf->width = width;
+   bq_buf->height = height;
+   bq_buf->format = format;
+   bq_buf->flags = flags;
+
+   bq->buffers = eina_inlist_append(bq->buffers, EINA_INLIST_GET(bq_buf));
+
+   _e_bq_mgr_consumer_side_buffer_create(consumer, bq_buf);
+}
+
+static void
+_e_bq_mgr_provider_buffer_id_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer, int32_t id, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
+{
+   E_Bq_Provider *provider = wl_resource_get_user_data(resource);
+   E_Bq_Consumer *consumer;
+   E_Bq_Queue *bq;
+   E_Bq_Buffer *bq_buf;
+
+   if (!provider)
+     return;
+
+   bq = provider->bq;
+   consumer = bq->consumer;
+
+   bq_buf = wl_resource_get_user_data(buffer);
+   if (!bq_buf)
+     return;
+
+   bq_buf->type = E_BQ_BUFFER_TYPE_ID;
+   bq_buf->id = id;
+   bq_buf->offset0 = offset0;
+   bq_buf->stride0 = stride0;
+   bq_buf->offset1 = offset1;
+   bq_buf->stride1 = stride1;
+   bq_buf->offset2 = offset2;
+   bq_buf->stride2 = stride2;
+
+   _e_bq_mgr_consumer_side_buffer_set(consumer, bq_buf);
+}
+
+static void
+_e_bq_mgr_provider_buffer_fd_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer, int32_t fd, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
+{
+   E_Bq_Provider *provider = wl_resource_get_user_data(resource);
+   E_Bq_Consumer *consumer;
+   E_Bq_Queue *bq;
+   E_Bq_Buffer *bq_buf;
+
+   if (!provider)
+     return;
+
+   bq = provider->bq;
+   consumer = bq->consumer;
+
+   bq_buf= wl_resource_get_user_data(buffer);
+   if (!bq_buf)
+     return;
+
+   bq_buf->type = E_BQ_BUFFER_TYPE_FD;
+   bq_buf->id = fd;
+   bq_buf->offset0 = offset0;
+   bq_buf->stride0 = stride0;
+   bq_buf->offset1 = offset1;
+   bq_buf->stride1 = stride1;
+   bq_buf->offset2 = offset2;
+   bq_buf->stride2 = stride2;
+
+   _e_bq_mgr_consumer_side_buffer_set(consumer, bq_buf);
+}
+
+static void
+_e_bq_mgr_provider_buffer_detach(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer)
+{
+   E_Bq_Provider *provider = wl_resource_get_user_data(resource);
+   E_Bq_Consumer *consumer;
+   E_Bq_Queue *bq;
+   E_Bq_Buffer *bq_buf;
+
+   EINA_SAFETY_ON_NULL_RETURN(provider);
+   bq = provider->bq;
+   consumer = bq->consumer;
+   bq_buf= wl_resource_get_user_data(buffer);
+
+   if (consumer)
+     {
+        bq_consumer_send_buffer_detached(e_object_data_get(E_OBJECT(consumer)),
+                                         bq_buf->consumer);
+        wl_resource_destroy(bq_buf->consumer);
+        e_object_unref(E_OBJECT(bq_buf));
+     }
+
+   wl_resource_destroy(bq_buf->provider);
+   bq->buffers = eina_inlist_remove(bq->buffers, EINA_INLIST_GET(bq_buf));
+   e_object_del(E_OBJECT(bq_buf));
+}
+
+static void
+_e_bq_mgr_provider_buffer_enqueue(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer, uint32_t serial)
+{
+   E_Bq_Provider *provider = wl_resource_get_user_data(resource);
+   E_Bq_Consumer *consumer;
+   E_Bq_Queue *bq;
+   E_Bq_Buffer *bq_buf;
+
+   if (!provider)
+     return;
+
+   bq = provider->bq;
+
+   consumer = bq->consumer;
+   if (!consumer)
+     return;
+
+   bq_buf= wl_resource_get_user_data(buffer);
+   if (!bq_buf)
+     return;
+
+   bq_buf->serial = serial;
+
+   bq_consumer_send_add_buffer(e_object_data_get(E_OBJECT(consumer)),
+                               bq_buf->consumer,
+                               bq_buf->serial);
+}
+
+static const struct bq_provider_interface _bq_provider_interface = {
+   _e_bq_mgr_provider_buffer_attach,
+   _e_bq_mgr_provider_buffer_id_set,
+   _e_bq_mgr_provider_buffer_fd_set,
+   _e_bq_mgr_provider_buffer_detach,
+   _e_bq_mgr_provider_buffer_enqueue
+};
+
+static void
+_e_bq_mgr_provider_destroy(struct wl_resource *resource)
+{
+   E_Bq_Queue *bq;
+   E_Bq_Provider *provider = wl_resource_get_user_data(resource);
+   E_Bq_Consumer *consumer;
+   E_Bq_Buffer *bq_buf;
+   struct wl_resource *consumer_res;
+
+   if (!provider)
+     return;
+
+   DBG("destroy buffer provider : %s\n", provider->bq->name);
+
+   bq = provider->bq;
+   consumer = bq->consumer;
+
+   e_object_data_set(E_OBJECT(provider), NULL);
+   bq->provider = NULL;
+
+   while (bq->buffers)
+     {
+        bq_buf = EINA_INLIST_CONTAINER_GET(bq->buffers, E_Bq_Buffer);
+        bq->buffers = eina_inlist_remove(bq->buffers, bq->buffers);
+
+        if (bq_buf->consumer)
+          {
+             bq_consumer_send_buffer_detached(e_object_data_get(E_OBJECT(consumer)),
+                                              bq_buf->consumer);
+             wl_resource_destroy(bq_buf->consumer);
+             bq_buf->consumer = NULL;
+             e_object_unref(E_OBJECT(bq_buf));
+          }
+
+        if (bq_buf->provider)
+          {
+             wl_resource_destroy(bq_buf->provider);
+             bq_buf->provider = NULL;
+             e_object_del(E_OBJECT(bq_buf));
+          }
+     }
+
+   if (consumer)
+     {
+        consumer_res = e_object_data_get(E_OBJECT(consumer));
+        if (consumer_res)
+          bq_consumer_send_disconnected(consumer_res);
+     }
+
+   e_object_del(E_OBJECT(provider));
+   e_object_unref(E_OBJECT(bq));
+}
+
+static void
+_e_bq_mgr_provider_free(E_Bq_Provider *provider)
+{
+   free(provider);
+}
+
+static void
+_e_bq_mgr_provider_create(struct wl_client *client, struct wl_resource *resource, uint32_t id, const char *name)
+{
+   E_Bq_Mgr *bq_mgr = wl_resource_get_user_data(resource);
+   E_Bq_Queue *bq;
+   E_Bq_Provider *provider;
+   E_Bq_Consumer *consumer;
+   struct wl_resource *new_resource;
+
+   if (!bq_mgr)
+     return;
+
+   bq = _e_bq_mgr_bq_new(bq_mgr, name);
+   if (!bq)
+     return;
+
+   if (bq->provider)
+     {
+        e_object_unref(E_OBJECT(bq));
+        wl_resource_post_error(resource,
+                               BQ_MGR_ERROR_ALREADY_USED,
+                               "%s provider already used", name);
+        return;
+     }
+
+   provider = E_OBJECT_ALLOC(E_Bq_Provider, E_BQ_PROVIDER, _e_bq_mgr_provider_free);
+   if (!provider)
+     goto on_error;
+
+   new_resource = wl_resource_create(client,
+                                     &bq_provider_interface,
+                                     1, id);
+   if (!new_resource)
+     goto on_error;
+
+   e_object_data_set(E_OBJECT(provider), new_resource);
+
+   wl_resource_set_implementation(new_resource,
+                                  &_bq_provider_interface,
+                                  provider,
+                                  _e_bq_mgr_provider_destroy);
+
+   provider->bq = bq;
+   bq->provider = provider;
+   consumer = bq->consumer;
+   if (consumer)
+     {
+        /*Send connect*/
+        bq_consumer_send_connected(e_object_data_get(E_OBJECT(consumer)));
+        bq_provider_send_connected(new_resource,
+                                   consumer->queue_size,
+                                   consumer->width, consumer->height);
+     }
+
+   return;
+
+on_error:
+   if (bq) e_object_unref(E_OBJECT(bq));
+   if (provider) free(provider);
+   wl_client_post_no_memory(client);
+}
+
+static const struct bq_mgr_interface _bq_mgr_interface =
+{
+   _e_bq_mgr_bq_create_consumer,
+   _e_bq_mgr_provider_create
+};
+
+static void
+_e_bq_mgr_bind(struct wl_client *client, void *data,
+                          uint32_t version, uint32_t id)
+{
+   E_Bq_Mgr *bq_mgr = (E_Bq_Mgr *)data;
+   struct wl_resource *resource;
+
+   resource = wl_resource_create(client, &bq_mgr_interface, 1, id);
+   if (resource == NULL)
+     {
+        wl_client_post_no_memory(client);
+        return;
+     }
+
+   wl_resource_set_implementation(resource,
+                                  &_bq_mgr_interface,
+                                  bq_mgr, NULL);
+}
+
+Eina_Bool
+_e_bq_mgr_init(E_Bq_Mgr *bq_mgr)
+{
+   if (!bq_mgr)
+     return EINA_FALSE;
+
+   bq_mgr->global =
+      wl_global_create(bq_mgr->wdpy, &bq_mgr_interface,
+                       1, bq_mgr, _e_bq_mgr_bind);
+
+   if (!bq_mgr->global)
+     return EINA_FALSE;
+
+   bq_mgr->bqs = eina_hash_string_superfast_new(NULL);
+   if (!bq_mgr->bqs)
+     return EINA_FALSE;
+
+   return EINA_TRUE;
+}
+
+/* this is needed to advertise a label for the module IN the code (not just
+ * the .desktop file) but more specifically the api version it was compiled
+ * for so E can skip modules that are compiled for an incorrect API version
+ * safely) */
+EAPI E_Module_Api e_modapi =
+{
+   E_MODULE_API_VERSION, "Buffer queue manager"
+};
+
+EAPI void *
+e_modapi_init(E_Module *m)
+{
+   E_Bq_Mgr *bq_mgr = NULL;
+
+   bq_mgr = _e_bq_mgr_new(NULL);
+   if (!bq_mgr)
+     return NULL;
+
+   if (!_e_bq_mgr_init(bq_mgr))
+     {
+        e_object_del(E_OBJECT(bq_mgr));
+        return NULL;
+     }
+
+   m->data = bq_mgr;
+
+   return m;
+}
+
+EAPI int
+e_modapi_shutdown(E_Module *m)
+{
+   E_Bq_Mgr *bq_mgr = m->data;
+
+   e_object_del(E_OBJECT(bq_mgr));
+
+   return 1;
+}
+
+EAPI int
+e_modapi_save(E_Module *m)
+{
+   /* Do Something */
+   return 1;
+}
+