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
This commit is contained in:
Mike Blumenkrantz 2015-07-16 16:51:54 -04:00
parent faacad29dc
commit d5e25a8449
8 changed files with 236 additions and 0 deletions

View File

@ -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)

View File

@ -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();
}

View File

@ -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

View File

@ -938,6 +938,7 @@ _e_module_whitelist_check(void)
"wizard",
"wl_desktop_shell",
"wl_x11",
"wl_wl",
"wl_drm",
"wl_screenshot",
"wl_shell",

View File

@ -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

View File

@ -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

View File

@ -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;
}

118
src/modules/wl_wl/wl.c Normal file
View File

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