tizen 2.4 release accepted/tizen/2.4/mobile/20151029.031319 submit/tizen_2.4/20151028.064840 tizen_2.4_mobile_release
authorjk7744.park <jk7744.park@samsung.com>
Mon, 26 Oct 2015 06:49:13 +0000 (15:49 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Mon, 26 Oct 2015 06:49:13 +0000 (15:49 +0900)
14 files changed:
.gitignore [new file with mode: 0644]
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
configure.ac [new file with mode: 0644]
e17-mod-tizen-bufferqueue.manifest [new file with mode: 0644]
packaging/e17-mod-tizen-bufferqueue.spec [new file with mode: 0644]
protocol/bq_mgr.xml [new file with mode: 0644]
src/Makefile.am [new file with mode: 0644]
src/e_mod_main.c [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..e596b11
--- /dev/null
@@ -0,0 +1,44 @@
+*~
+*swp
+*swo
+*.gmo
+Makefile
+Makefile.in
+tags
+.DS_Store
+.deps
+.libs
+*.trs
+*.log
+*.o
+*.lo
+*.a
+*.la
+*.gcno
+*.gcda
+*.dirstamp
+.dir-locals.el
+/ar-lib
+/stamp-h1
+/aclocal.m4
+/autom4te.cache/
+/config.cache
+/config.cache-env
+/config.guess
+/config.h
+/config.h.in
+/config.log
+/config.status
+/config.sub
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/compile
+/test-driver
+/missing
+/INSTALL
+/ABOUT-NLS
+/config.rpath
+Session.vim
diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..67aade9
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Seunghun Lee <shiin.lee@samsung.com>
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..8a6d098
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,48 @@
+Copyright notice for Enlightenment:
+
+Copyright (C) 2000-2015 Carsten Haitzler and various contributors (see AUTHORS)
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Copyright © 2008-2012 Kristian Høgsberg
+Copyright © 2010-2012 Intel Corporation
+Copyright © 2010-2011 Benjamin Franzke
+Copyright © 2011-2012 Collabora, Ltd.
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting documentation, and
+that the name of the copyright holders not be used in advertising or
+publicity pertaining to distribution of the software without specific,
+written prior permission.  The copyright holders make no representations
+about the suitability of this software for any purpose.  It is provided "as
+is" without express or implied warranty.
+
+THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+OF THIS SOFTWARE.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..a88e6f3
--- /dev/null
@@ -0,0 +1,6 @@
+ACLOCAL_AMFLAGS =
+MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess config.h.in \
+                      config.sub configure depcomp install-sh ltmain.sh \
+                      missing config.rpath mkinstalldirs
+
+SUBDIRS = src
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..df6110d
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+rm -rf autom4te.cache
+rm -f aclocal.m4 ltmain.sh
+
+#echo "Running autopoint..." ; autopoint -f || :
+echo "Running aclocal..." ; aclocal || exit 1
+echo "Running autoconf..." ; autoconf || exit 1
+echo "Running autoheader..." ; autoheader || exit 1
+echo "Running libtoolize..." ; (libtoolize --copy --automake || glibtoolize --automake) || exit 1
+echo "Running automake..." ; automake --add-missing --copy --gnu || exit 1
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..6d1b9f7
--- /dev/null
@@ -0,0 +1,53 @@
+dnl Process this file with autoconf to produce a configure script.
+
+# get rid of that stupid cache mechanism
+rm -f config.cache
+
+AC_INIT(e17-mod-tizen-bufferqueue, 0.1, shiin.lee@samsung.com)
+AC_PREREQ(2.52)
+AC_CONFIG_SRCDIR(configure.ac)
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+AC_ISC_POSIX
+
+AM_INIT_AUTOMAKE(1.8)
+AM_CONFIG_HEADER(config.h)
+
+AC_PROG_CC
+AM_PROG_CC_STDC
+AM_PROG_CC_C_O
+AC_HEADER_STDC
+AC_C_CONST
+
+define([AC_LIBTOOL_LANG_CXX_CONFIG], [:])dnl
+define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl
+AC_PROG_LIBTOOL
+
+#AM_GNU_GETTEXT([external])
+#AM_GNU_GETTEXT_VERSION(0.14)
+
+AC_PATH_PROG([wayland_scanner], [wayland-scanner])
+if test x$wayland_scanner = x; then
+   AC_MSG_ERROR([wayland-scanner is needed to compile])
+fi
+
+PKG_CHECK_MODULES(WAYLAND_SCANNER, wayland-scanner)
+PKG_CHECK_MODULES(WAYLAND, [wayland-server])
+PKG_CHECK_MODULES(ENLIGHTENMENT, [enlightenment])
+
+AC_SUBST(ENLIGHTENMENT_CFLAGS)
+AC_SUBST(ENLIGHTENMENT_LIBS)
+
+AC_CHECK_LIB(dl, dlopen, dlopen_libs=-ldl)
+AC_SUBST(dlopen_libs)
+
+release=$(pkg-config --variable=release enlightenment)
+MODULE_ARCH="$host_os-$host_cpu-$release"
+AC_SUBST(MODULE_ARCH)
+AC_DEFINE_UNQUOTED(MODULE_ARCH, "$MODULE_ARCH", "Module architecture")
+
+datadir=$(pkg-config --variable=modules enlightenment)/${PACKAGE}
+
+AC_CONFIG_FILES([Makefile
+                src/Makefile])
+AC_OUTPUT
diff --git a/e17-mod-tizen-bufferqueue.manifest b/e17-mod-tizen-bufferqueue.manifest
new file mode 100644 (file)
index 0000000..2a0cec5
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+  <request>
+    <domain name="_"/>
+  </request>
+</manifest>
diff --git a/packaging/e17-mod-tizen-bufferqueue.spec b/packaging/e17-mod-tizen-bufferqueue.spec
new file mode 100644 (file)
index 0000000..729be26
--- /dev/null
@@ -0,0 +1,39 @@
+Name:       e17-mod-tizen-bufferqueue
+Summary:    The Enlightenment WM Module for Buffer Queue Protocol
+Version:    0.1.2
+Release:    1
+Group:      Graphics & UI Framework/Other
+License:    BSD 2-Clause and MIT
+Source0:    %{name}-%{version}.tar.bz2
+BuildRequires: pkgconfig(wayland-server)
+BuildRequires: pkgconfig(enlightenment)
+
+%description
+The Enlightenment WM Module for Buffer Queue Protocol
+
+%prep
+%setup -q -n %{name}-%{version}
+
+%build
+export GC_SECTIONS_FLAGS="-fdata-sections -ffunction-sections -Wl,--gc-sections"
+export CFLAGS+=" -Wall -g -fPIC -rdynamic -Werror-implicit-function-declaration ${GC_SECTIONS_FLAGS}"
+
+%autogen
+%configure
+make %{?_smp_mflags}
+
+%install
+# for license notification
+mkdir -p %{buildroot}/usr/share/license
+cp -a %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/usr/share/license/%{name}
+
+# install
+%make_install
+
+%files
+%manifest e17-mod-tizen-bufferqueue.manifest
+%defattr(-,root,root,-)
+%{_libdir}/enlightenment/modules/e17-mod-tizen-bufferqueue
+/usr/share/license/%{name}
+
+%define _unpackaged_files_terminate_build 0
diff --git a/protocol/bq_mgr.xml b/protocol/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/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..e1e28cc
--- /dev/null
@@ -0,0 +1,25 @@
+MAINTAINERCLEANFILES = Makefile.in
+MODULE = e17-mod-tizen-bufferqueue
+
+# data files for the module
+filesdir = $(libdir)/enlightenment/modules/$(MODULE)
+
+pkgdir                 = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH)
+pkg_LTLIBRARIES        = module.la
+module_la_SOURCES      = e_mod_main.c \
+                         bq_mgr_protocol.c
+module_la_LIBADD       =
+module_la_CFLAGS       = @WAYLAND_CFLAGS@ @ENLIGHTENMENT_CFLAGS@
+module_la_LDFLAGS      = -module -avoid-version @WAYLAND_LIBS@ @ENLIGHTENMENT_LIBS@
+module_la_DEPENDENCIES = $(top_builddir)/config.h
+
+BUILT_SOURCES = bq_mgr_protocol.c \
+                bq_mgr_protocol.h
+
+CLEANFILES = $(BUILT_SOURCES)
+
+%_protocol.c : $(top_srcdir)/protocol/%.xml
+       $(AM_V_GEN)$(MKDIR_P) $(dir $@) && $(wayland_scanner) code < $< > $@
+
+%_protocol.h : $(top_srcdir)/protocol/%.xml
+       $(AM_V_GEN)$(MKDIR_P) $(dir $@) && $(wayland_scanner) server-header < $< > $@
diff --git a/src/e_mod_main.c b/src/e_mod_main.c
new file mode 100644 (file)
index 0000000..df76c1d
--- /dev/null
@@ -0,0 +1,924 @@
+#define E_COMP_WL
+#include "e.h"
+#include <wayland-server.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_Bq_Mgr *bq_mgr;
+   int fd;
+   static char *default_sock_name = "bq_mgr_daemon";
+
+   bq_mgr = E_OBJECT_ALLOC(E_Bq_Mgr, E_BQ_MGR_TYPE, _e_bq_mgr_free);
+   if (!bq_mgr)
+     return NULL;
+
+   bq_mgr->wdpy = wl_display_create();
+   if (!bq_mgr->wdpy)
+     {
+        free(bq_mgr);
+        return NULL;
+     }
+
+   bq_mgr->loop = wl_display_get_event_loop(bq_mgr->wdpy);
+   if (!bq_mgr->loop)
+     {
+        wl_display_destroy(bq_mgr->wdpy);
+        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;
+
+   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);
+
+   if(!buffer->consumer)
+     return;
+
+   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);
+
+   if(!bq_buf)
+     return;
+
+   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;
+}
+