devilhorns pushed a commit to branch master.
commit a1447c102eb4f9c8cf0358e69fe777cee3fa9f41
Author: Chris Michael <[email protected]>
Date: Tue Apr 9 10:19:00 2013 +0100
Add start of a wayland compositor.
Signed-off-by: Chris Michael <[email protected]>
---
src/bin/e_comp_wl.c | 246 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 246 insertions(+)
diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
new file mode 100644
index 0000000..c2430d9
--- /dev/null
+++ b/src/bin/e_comp_wl.c
@@ -0,0 +1,246 @@
+#include "e.h"
+#include "e_comp_wl.h"
+#include <sys/mman.h>
+
+/* local function prototypes */
+static void _e_comp_wl_cb_bind(struct wl_client *client, void *data
EINA_UNUSED, unsigned int version EINA_UNUSED, unsigned int id);
+static Eina_Bool _e_comp_wl_cb_read(void *data EINA_UNUSED, Ecore_Fd_Handler
*hdl EINA_UNUSED);
+static Eina_Bool _e_comp_wl_cb_idle(void *data EINA_UNUSED);
+
+/* input function prototypes */
+static Eina_Bool _e_comp_wl_input_init(void);
+static void _e_comp_wl_input_shutdown(void);
+
+/* compositor interface prototypes */
+static void _e_comp_wl_cb_surface_create(struct wl_client *client, struct
wl_resource *resource, unsigned int id);
+static void _e_comp_wl_cb_region_create(struct wl_client *client, struct
wl_resource *resource, unsigned int id);
+
+/* local wayland interfaces */
+static const struct wl_compositor_interface _e_compositor_interface =
+{
+ _e_comp_wl_cb_surface_create,
+ _e_comp_wl_cb_region_create
+};
+
+/* local variables */
+
+/* external variables */
+E_Wayland_Compositor *_e_wl_comp;
+
+/* external functions */
+Eina_Bool
+e_comp_wl_init(void)
+{
+ int fd = 0;
+
+ /* try to allocate space for a new compositor */
+ if (!(_e_wl_comp = E_NEW(E_Wayland_Compositor, 1)))
+ return EINA_FALSE;
+
+ /* try to create a wayland display */
+ if (!(_e_wl_comp->wl.display = wl_display_create()))
+ {
+ ERR("Could not create a Wayland Display: %m");
+ goto err;
+ }
+
+ /* try to add a display socket */
+ if (wl_display_add_socket(_e_wl_comp->wl.display, NULL) < 0)
+ {
+ ERR("Could not add a Wayland Display socket: %m");
+ goto err;
+ }
+
+ /* init compositor signals */
+ wl_signal_init(&_e_wl_comp->signals.destroy);
+ wl_signal_init(&_e_wl_comp->signals.activate);
+ wl_signal_init(&_e_wl_comp->signals.kill);
+ wl_signal_init(&_e_wl_comp->signals.seat);
+
+ /* try to add compositor to the displays globals */
+ if (!wl_display_add_global(_e_wl_comp->wl.display, &wl_compositor_interface,
+ _e_wl_comp, _e_comp_wl_cb_bind))
+ {
+ ERR("Could not add compositor to globals: %m");
+ goto err;
+ }
+
+ /* init data device manager */
+ wl_data_device_manager_init(_e_wl_comp->wl.display);
+
+ /* try to init shm mechanism */
+ if (wl_display_init_shm(_e_wl_comp->wl.display) < 0)
+ ERR("Could not initialize SHM: %m");
+
+#ifdef HAVE_WAYLAND_EGL
+ /* try to get the egl display
+ *
+ * NB: This is interesting....if we try to eglGetDisplay and pass in the
+ * wayland display, then EGL fails due to XCB not owning the event queue.
+ * If we pass it a NULL, it inits just fine */
+ _e_wl_comp->egl.display = eglGetDisplay(NULL);
+ if (_e_wl_comp->egl.display == EGL_NO_DISPLAY)
+ ERR("Could not get EGL display: %m");
+ else
+ {
+ EGLint major, minor;
+
+ /* try to initialize egl */
+ if (!eglInitialize(_e_wl_comp->egl.display, &major, &minor))
+ {
+ ERR("Could not initialize EGL: %m");
+ eglTerminate(_e_wl_comp->egl.display);
+ }
+ else
+ {
+ EGLint n;
+ EGLint attribs[] =
+ {
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1,
+ EGL_ALPHA_SIZE, 1, EGL_RENDERABLE_TYPE,
+ EGL_OPENGL_ES2_BIT, EGL_NONE
+ };
+
+ if ((!eglChooseConfig(_e_wl_comp->egl.display, attribs,
+ &_e_wl_comp->egl.config, 1, &n) || (n ==
0)))
+ {
+ ERR("Could not choose EGL config: %m");
+ eglTerminate(_e_wl_comp->egl.display);
+ }
+ }
+ }
+#endif
+
+ /* try to initialize input */
+ if (!_e_comp_wl_input_init())
+ {
+ ERR("Could not initialize input: %m");
+ goto err;
+ }
+
+ /* TODO: module idler */
+
+ /* get the displays event loop */
+ _e_wl_comp->wl.loop = wl_display_get_event_loop(_e_wl_comp->wl.display);
+
+ /* get the event loop's file descriptor so we can listen on it */
+ fd = wl_event_loop_get_fd(_e_wl_comp->wl.loop);
+
+ /* add the fd to E's main loop */
+ _e_wl_comp->fd_handler =
+ ecore_main_fd_handler_add(fd, ECORE_FD_READ,
+ _e_comp_wl_cb_read, NULL, NULL, NULL);
+
+ /* add an idler for flushing clients */
+ _e_wl_comp->idler = ecore_idle_enterer_add(_e_comp_wl_cb_idle, NULL);
+
+ /* TODO: event handlers ?? */
+
+ /* flush any pending events */
+ wl_event_loop_dispatch(_e_wl_comp->wl.loop, 0);
+
+ /* return success */
+ return EINA_TRUE;
+
+err:
+#ifdef HAVE_WAYLAND_EGL
+ /* terminate the egl display */
+ if (_e_wl_comp->egl.display)
+ eglTerminate(_e_wl_comp->egl.display);
+ eglReleaseThread();
+#endif
+
+ /* if we have a display, destroy it */
+ if (_e_wl_comp->wl.display) wl_display_destroy(_e_wl_comp->wl.display);
+
+ /* free the compositor */
+ E_FREE(_e_wl_comp);
+
+ /* return failure */
+ return EINA_FALSE;
+}
+
+void
+e_comp_wl_shutdown(void)
+{
+ /* remove the idler */
+ if (_e_wl_comp->idler) ecore_idler_del(_e_wl_comp->idler);
+
+ /* remove the fd handler */
+ if (_e_wl_comp->fd_handler)
+ ecore_main_fd_handler_del(_e_wl_comp->fd_handler);
+
+ /* shutdown input */
+ _e_comp_wl_input_shutdown();
+
+#ifdef HAVE_WAYLAND_EGL
+ /* terminate the egl display */
+ if (_e_wl_comp->egl.display)
+ eglTerminate(_e_wl_comp->egl.display);
+ eglReleaseThread();
+#endif
+
+ /* if we have a display, destroy it */
+ if (_e_wl_comp->wl.display) wl_display_destroy(_e_wl_comp->wl.display);
+
+ /* free the compositor */
+ E_FREE(_e_wl_comp);
+
+ /* TODO: unload shell module */
+}
+
+/* local functions */
+static void
+_e_comp_wl_cb_bind(struct wl_client *client, void *data EINA_UNUSED, unsigned
int version EINA_UNUSED, unsigned int id)
+{
+ /* add the compositor object to the client */
+ wl_client_add_object(client, &wl_compositor_interface,
+ &_e_compositor_interface, id, _e_wl_comp);
+}
+
+static Eina_Bool
+_e_comp_wl_cb_read(void *data EINA_UNUSED, Ecore_Fd_Handler *hdl EINA_UNUSED)
+{
+ /* flush any events before we sleep */
+ wl_event_loop_dispatch(_e_wl_comp->wl.loop, 0);
+ wl_display_flush_clients(_e_wl_comp->wl.display);
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+_e_comp_wl_cb_idle(void *data EINA_UNUSED)
+{
+ /* flush any clients before we idle */
+ wl_display_flush_clients(_e_wl_comp->wl.display);
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+/* input functions */
+static Eina_Bool
+_e_comp_wl_input_init(void)
+{
+ return EINA_TRUE;
+}
+
+static void
+_e_comp_wl_input_shutdown(void)
+{
+
+}
+
+/* compositor interface functions */
+static void
+_e_comp_wl_cb_surface_create(struct wl_client *client, struct wl_resource
*resource, unsigned int id)
+{
+
+}
+
+static void
+_e_comp_wl_cb_region_create(struct wl_client *client, struct wl_resource
*resource, unsigned int id)
+{
+
+}
+
--
------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter