discomfitor pushed a commit to branch master.

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

commit d5e25a84499418a95eeaf8e4d79d69c1dc105782
Author: Mike Blumenkrantz <zm...@osg.samsung.com>
Date:   Thu Jul 16 16:51:54 2015 -0400

    add wl_wl wl output module
    
    it is now possible to create a xephyr window in a drm-enlightenment session,
    launch wl-x11 enlightenment in xephyr, and then launch wl-wl enlightenment
    inside that enlightenment
    
    the primary limitation on this output module is that all internal windows 
will
    appear in the outer compositor due to the current restriction of 
ecore-wayland
    with regard to only having a single global display server connection
    
     #Inception
---
 configure.ac                   |  12 +++++
 src/bin/e_comp_wl.c            |  11 ++++
 src/bin/e_comp_wl.h            |   3 ++
 src/bin/e_module.c             |   1 +
 src/modules/Makefile.mk        |   2 +
 src/modules/Makefile_wl_wl.mk  |  18 +++++++
 src/modules/wl_wl/e_mod_main.c |  71 +++++++++++++++++++++++++
 src/modules/wl_wl/wl.c         | 118 +++++++++++++++++++++++++++++++++++++++++
 8 files changed, 236 insertions(+)

diff --git a/configure.ac b/configure.ac
index 3cabc22..ff04d9c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -789,6 +789,17 @@ define([CHECK_MODULE_WL_X11],
 ])
 AM_CONDITIONAL([HAVE_WL_X11], [test "x${WL_X11}" = "xtrue"])
 
+WL_WL=false
+define([CHECK_MODULE_WL_WL],
+[
+  if test "x${have_wayland}" = "xyes"; then
+    WL_WL=true
+  else
+    WL_WL=false
+  fi
+])
+AM_CONDITIONAL([HAVE_WL_WL], [test "x${WL_WL}" = "xtrue"])
+
 WL_DESKTOP_SHELL=false
 define([CHECK_MODULE_WL_DESKTOP_SHELL],
 [
@@ -885,6 +896,7 @@ AC_E_OPTIONAL_MODULE([music_control], true, 
[CHECK_MODULE_MUSIC_CONTROL])
 AC_E_OPTIONAL_MODULE([packagekit], true)
 AC_E_OPTIONAL_MODULE([wl_desktop_shell], $have_wayland, 
[CHECK_MODULE_WL_DESKTOP_SHELL])
 AC_E_OPTIONAL_MODULE([wl_x11], $have_wayland, [CHECK_MODULE_WL_X11])
+AC_E_OPTIONAL_MODULE([wl_wl], $have_wayland, [CHECK_MODULE_WL_WL])
 #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([policy_mobile], true)
diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index 36f4896..353a030 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -2790,6 +2790,17 @@ e_comp_wl_shutdown(void)
    /* free handlers */
    E_FREE_LIST(handlers, ecore_event_handler_del);
 
+   while (e_comp->wl_comp_data->wl.globals)
+     {
+        Ecore_Wl_Global *global = 
EINA_INLIST_CONTAINER_GET(e_comp->wl_comp_data->wl.globals, Ecore_Wl_Global);
+        e_comp->wl_comp_data->wl.globals =
+          eina_inlist_remove(e_comp->wl_comp_data->wl.globals,
+                             e_comp->wl_comp_data->wl.globals);
+        free(global->interface);
+        free(global);
+     }
+   if (e_comp->wl_comp_data->wl.shm) 
wl_shm_destroy(e_comp->wl_comp_data->wl.shm);
+
    /* shutdown ecore_wayland */
    ecore_wl_shutdown();
 }
diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h
index ce0b8f7..736cc90 100644
--- a/src/bin/e_comp_wl.h
+++ b/src/bin/e_comp_wl.h
@@ -105,7 +105,10 @@ struct _E_Comp_Wl_Data
    struct
      {
         struct wl_display *disp;
+        struct wl_registry *registry; // only used for nested wl compositors
         struct wl_event_loop *loop;
+        Eina_Inlist *globals;  // only used for nested wl compositors
+        struct wl_shm *shm;  // only used for nested wl compositors
      } wl;
 
    struct
diff --git a/src/bin/e_module.c b/src/bin/e_module.c
index 0fe391a..d12d817 100644
--- a/src/bin/e_module.c
+++ b/src/bin/e_module.c
@@ -938,6 +938,7 @@ _e_module_whitelist_check(void)
       "wizard",
       "wl_desktop_shell",
       "wl_x11",
+      "wl_wl",
       "wl_drm",
       "wl_screenshot",
       "wl_shell",
diff --git a/src/modules/Makefile.mk b/src/modules/Makefile.mk
index 7548c50..8993191 100644
--- a/src/modules/Makefile.mk
+++ b/src/modules/Makefile.mk
@@ -111,6 +111,8 @@ include src/modules/Makefile_packagekit.mk
 
 include src/modules/Makefile_wl_drm.mk
 
+include src/modules/Makefile_wl_wl.mk
+
 include src/modules/Makefile_wl_desktop_shell.mk
 
 include src/modules/Makefile_wl_x11.mk
diff --git a/src/modules/Makefile_wl_wl.mk b/src/modules/Makefile_wl_wl.mk
new file mode 100644
index 0000000..1721a3f
--- /dev/null
+++ b/src/modules/Makefile_wl_wl.mk
@@ -0,0 +1,18 @@
+if USE_MODULE_WL_WL
+wl_wldir = $(MDIR)/wl_wl
+
+wl_wlpkgdir = $(MDIR)/wl_wl/$(MODULE_ARCH)
+wl_wlpkg_LTLIBRARIES = src/modules/wl_wl/module.la
+
+src_modules_wl_wl_module_la_DEPENDENCIES = $(MDEPENDENCIES)
+src_modules_wl_wl_module_la_CPPFLAGS  = $(MOD_CPPFLAGS) @WAYLAND_CFLAGS@
+src_modules_wl_wl_module_la_LIBADD   = $(LIBS) @WAYLAND_LIBS@
+src_modules_wl_wl_module_la_LDFLAGS = $(MOD_LDFLAGS)
+src_modules_wl_wl_module_la_SOURCES = \
+src/modules/wl_wl/e_mod_main.c \
+src/modules/wl_wl/wl.c
+
+PHONIES += wl_wl install-wl_wl
+wl_wl: $(wl_wlpkg_LTLIBRARIES) $(wl_wl_DATA)
+install-wl_wl: install-wl_wlpkgLTLIBRARIES
+endif
diff --git a/src/modules/wl_wl/e_mod_main.c b/src/modules/wl_wl/e_mod_main.c
new file mode 100644
index 0000000..4a3fb69
--- /dev/null
+++ b/src/modules/wl_wl/e_mod_main.c
@@ -0,0 +1,71 @@
+#include "e.h"
+
+EINTERN void wl_wl_init(void);
+
+E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_Wl" };
+
+static void
+_cb_delete_request(Ecore_Evas *ee EINA_UNUSED)
+{
+   ecore_main_loop_quit();
+}
+
+E_API void *
+e_modapi_init(E_Module *m)
+{
+   int w = 0, h = 0;
+
+   printf("LOAD WL_WL MODULE\n");
+
+   if (e_comp_config_get()->engine == E_COMP_ENGINE_GL)
+     {
+        e_comp->ee = ecore_evas_new("wayland_egl", 0, 0, 1, 1, NULL);
+        e_comp_gl_set(!!e_comp->ee);
+     }
+   if (!e_comp->ee)
+     {
+        if ((e_comp->ee = ecore_evas_new("wayland_shm", 0, 0, 1, 1, NULL)))
+          {
+             e_comp_gl_set(EINA_FALSE);
+             elm_config_accel_preference_set("none");
+             elm_config_accel_preference_override_set(EINA_TRUE);
+             elm_config_all_flush();
+             elm_config_save();
+          }
+        else
+          {
+             fprintf(stderr, "Could not create ecore_evas_drm canvas");
+             return NULL;
+          }
+     }
+   ecore_evas_callback_delete_request_set(e_comp->ee, _cb_delete_request);
+   ecore_evas_title_set(e_comp->ee, "Enlightenment: WL-WL");
+   ecore_evas_name_class_set(e_comp->ee, "E", "compositor");
+
+   ecore_evas_screen_geometry_get(e_comp->ee, NULL, NULL, &w, &h);
+
+   if (!e_comp_wl_init()) return NULL;
+   if (!e_comp_canvas_init(w * 3 / 4, h * 3 / 4)) return NULL;
+
+   ecore_evas_pointer_xy_get(e_comp->ee, &e_comp->wl_comp_data->ptr.x,
+                             &e_comp->wl_comp_data->ptr.y);
+   e_comp_wl_input_pointer_enabled_set(EINA_TRUE);
+   e_comp_wl_input_keyboard_enabled_set(EINA_TRUE);
+   e_comp_wl_input_touch_enabled_set(EINA_TRUE);
+
+   /* e_comp->pointer =  */
+   /*   e_pointer_window_new(ecore_evas_window_get(e_comp->ee), EINA_TRUE); */
+   e_comp->pointer = e_pointer_canvas_new(e_comp->ee, EINA_TRUE);
+   e_comp->pointer->color = EINA_TRUE;
+
+   e_comp_wl_input_keymap_set(NULL, NULL, NULL);
+   wl_wl_init();
+
+   return m;
+}
+
+E_API int
+e_modapi_shutdown(E_Module *m EINA_UNUSED)
+{
+   return 1;
+}
diff --git a/src/modules/wl_wl/wl.c b/src/modules/wl_wl/wl.c
new file mode 100644
index 0000000..36f88ce
--- /dev/null
+++ b/src/modules/wl_wl/wl.c
@@ -0,0 +1,118 @@
+#include "e.h"
+
+static struct wl_display *disp;
+static Ecore_Fd_Handler *wl_fdh;
+
+static void
+_wl_handle_global(void *data EINA_UNUSED, struct wl_registry *registry 
EINA_UNUSED, unsigned int id, const char *interface, unsigned int version)
+{
+   Ecore_Wl_Global *global;
+
+   if (!(global = calloc(1, sizeof(Ecore_Wl_Global)))) return;
+
+   global->id = id;
+   global->interface = strdup(interface);
+   global->version = version;
+   e_comp->wl_comp_data->wl.globals = 
eina_inlist_append(e_comp->wl_comp_data->wl.globals, EINA_INLIST_GET(global));
+
+   if (!strcmp(interface, "wl_shm"))
+     e_comp->wl_comp_data->wl.shm = wl_registry_bind(registry, id, 
&wl_shm_interface, 1);
+}
+
+static void
+_wl_handle_global_remove(void *data EINA_UNUSED, struct wl_registry *registry 
EINA_UNUSED, unsigned int id)
+{
+   Ecore_Wl_Global *global;
+   Eina_Inlist *tmp;
+
+   EINA_INLIST_FOREACH_SAFE(e_comp->wl_comp_data->wl.globals, tmp, global)
+     {
+        if (global->id != id) continue;
+        e_comp->wl_comp_data->wl.globals =
+          eina_inlist_remove(e_comp->wl_comp_data->wl.globals, 
EINA_INLIST_GET(global));
+        free(global->interface);
+        free(global);
+     }
+}
+
+static const struct wl_registry_listener _global_registry_listener =
+{
+   _wl_handle_global,
+   _wl_handle_global_remove
+};
+
+
+static Eina_Bool
+_ecore_wl_cb_idle_enterer(void *data EINA_UNUSED)
+{
+   int ret = 0;
+
+   ret = wl_display_get_error(disp);
+   if (ret < 0) goto err;
+
+   ret = wl_display_dispatch_pending(disp);
+   if (ret < 0) goto err;
+
+   ret = wl_display_flush(disp);
+   if ((ret < 0) && (errno == EAGAIN))
+     ecore_main_fd_handler_active_set(wl_fdh, ECORE_FD_READ | ECORE_FD_WRITE);
+
+   return ECORE_CALLBACK_RENEW;
+
+err:
+   if ((ret < 0) && ((errno != EAGAIN) && (errno != EINVAL)))
+     {
+        /* raise exit signal */
+        fprintf(stderr, "Wayland socket error: %s\n", strerror(errno));
+        abort();
+
+        return ECORE_CALLBACK_CANCEL;
+     }
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+
+static Eina_Bool
+_ecore_wl_cb_handle_data(void *data EINA_UNUSED, Ecore_Fd_Handler *hdl)
+{
+   int ret = 0;
+
+   if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_ERROR))
+     {
+        fprintf(stderr, "Received error on wayland display fd\n");
+        abort();
+
+        return ECORE_CALLBACK_CANCEL;
+     }
+
+   if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ))
+     ret = wl_display_dispatch(disp);
+   else if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE))
+     {
+        ret = wl_display_flush(disp);
+        if (ret == 0)
+          ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ);
+     }
+
+   if ((ret < 0) && ((errno != EAGAIN) && (errno != EINVAL)))
+     {
+        /* raise exit signal */
+        abort();
+
+        return ECORE_CALLBACK_CANCEL;
+     }
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+EINTERN void
+wl_wl_init(void)
+{
+   disp = wl_display_connect(getenv("WAYLAND_DISPLAY"));
+   ecore_main_fd_handler_add(wl_display_get_fd(disp), ECORE_FD_READ | 
ECORE_FD_WRITE | ECORE_FD_ERROR,
+                               _ecore_wl_cb_handle_data, NULL, NULL, NULL);
+   e_comp->wl_comp_data->wl.registry = wl_display_get_registry(disp);
+   wl_registry_add_listener(e_comp->wl_comp_data->wl.registry, 
&_global_registry_listener, NULL);
+   ecore_idle_enterer_add(_ecore_wl_cb_idle_enterer, NULL);
+}

-- 


Reply via email to