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); +} --