enlightenment/src/bin/e_comp_wl.c

249 lines
6.1 KiB
C
Raw Normal View History

#define E_COMP_WL
#include "e.h"
#define COMPOSITOR_VERSION 3
#define E_COMP_WL_PIXMAP_CHECK \
if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return
/* local functions */
static void
_e_comp_wl_log_cb_print(const char *format, va_list args)
{
INF("WL: ", format, args);
}
static Eina_Bool
_e_comp_wl_cb_read(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
{
E_Comp_Data *cdata;
if (!(cdata = data)) return ECORE_CALLBACK_RENEW;
/* dispatch pending wayland events */
wl_event_loop_dispatch(cdata->wl.loop, 0);
return ECORE_CALLBACK_RENEW;
}
static void
_e_comp_wl_cb_prepare(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
{
E_Comp_Data *cdata;
if (!(cdata = data)) return;
/* flush pending client events */
wl_display_flush_clients(cdata->wl.disp);
}
static Eina_Bool
_e_comp_wl_cb_module_idle(void *data)
{
E_Comp_Data *cdata;
E_Module *mod = NULL;
if (!(cdata = data)) return ECORE_CALLBACK_RENEW;
/* check if we are still loading modules */
if (e_module_loading_get()) return ECORE_CALLBACK_RENEW;
if (!(mod = e_module_find("wl_desktop_shell")))
mod = e_module_new("wl_desktop_shell");
if (mod)
{
e_module_enable(mod);
/* FIXME: NB:
* Do we need to dispatch pending wl events here ?? */
return ECORE_CALLBACK_CANCEL;
}
return ECORE_CALLBACK_RENEW;
}
static void
_e_comp_wl_compositor_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
{
E_Comp *comp;
struct wl_resource *res;
if (!(comp = data)) return;
if (!(res =
wl_resource_create(client, &wl_compositor_interface,
MIN(version, COMPOSITOR_VERSION), id)))
{
ERR("Could not create compositor resource: %m");
wl_client_post_no_memory(client);
return;
}
}
static void
_e_comp_wl_compositor_cb_del(E_Comp *comp)
{
E_Comp_Data *cdata;
/* get existing compositor data */
if (!(cdata = comp->wl_comp_data)) return;
/* free allocated data structure */
free(cdata);
}
static Eina_Bool
_e_comp_wl_compositor_create(void)
{
E_Comp *comp;
const char *name;
int fd = 0;
/* check for existing compositor. create if needed */
if (!(comp = e_comp_get(NULL)))
{
comp = e_comp_new();
comp->comp_type = E_PIXMAP_TYPE_WL;
E_OBJECT_DEL_SET(comp, _e_comp_wl_compositor_cb_del);
}
/* create new compositor data */
cdata = E_NEW(E_Comp_Data, 1);
/* set wayland log handler */
wl_log_set_handler_server(_e_comp_wl_log_cb_print);
/* try to create a wayland display */
if (!(cdata->wl.disp = wl_display_create()))
{
ERR("Could not create a Wayland display: %m");
goto disp_err;
}
/* try to setup wayland socket */
if (!(name = wl_display_add_socket_auto(cdata->wl.disp)))
{
ERR("Could not create Wayland display socket: %m");
goto sock_err;
}
/* set wayland display environment variable */
e_env_set("WAYLAND_DISPLAY", name);
/* initialize compositor signals */
wl_signal_init(&cdata->signals.surface.create);
wl_signal_init(&cdata->signals.surface.activate);
wl_signal_init(&cdata->signals.surface.kill);
/* try to add compositor to wayland globals */
if (!wl_global_create(cdata->wl.disp, &wl_compositor_interface,
COMPOSITOR_VERSION, comp,
_e_comp_wl_compositor_cb_bind))
{
ERR("Could not add compositor to wayland globals: %m");
goto comp_global_err;
}
/* try to init data manager */
if (!e_comp_wl_data_manager_init(cdata))
{
ERR("Could not initialize data manager");
goto data_err;
}
/* try to init input */
if (!e_comp_wl_input_init(cdata))
{
ERR("Could not initialize input");
goto input_err;
}
/* initialize shm mechanism */
wl_display_init_shm(cdata->wl.disp);
/* get the wayland display loop */
cdata->wl.loop = wl_display_get_event_loop(cdata->wl.disp);
/* get the file descriptor of the wayland event loop */
fd = wl_event_loop_get_fd(cdata->wl.loop);
/* create a listener for wayland main loop events */
cdata->fd_hdlr =
ecore_main_fd_handler_add(fd, (ECORE_FD_READ | ECORE_FD_ERROR),
_e_comp_wl_cb_read, cdata, NULL, NULL);
ecore_main_fd_handler_prepare_callback_set(cdata->fd_hdlr,
_e_comp_wl_cb_prepare, cdata);
/* setup module idler to load shell mmodule */
ecore_idler_add(_e_comp_wl_cb_module_idle, cdata);
if (comp->comp_type == E_PIXMAP_TYPE_X)
{
e_comp_wl_input_pointer_enabled_set(cdata, EINA_TRUE);
e_comp_wl_input_keyboard_enabled_set(cdata, EINA_TRUE);
}
/* set compositor wayland data */
comp->wl_comp_data = cdata;
return EINA_TRUE;
input_err:
e_comp_wl_data_manager_shutdown(cdata);
data_err:
comp_global_err:
e_env_unset("WAYLAND_DISPLAY");
sock_err:
wl_display_destroy(cdata->wl.disp);
disp_err:
free(cdata);
return EINA_FALSE;
}
/* public functions */
EAPI Eina_Bool
e_comp_wl_init(void)
{
/* set gl available if we have ecore_evas support */
if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_WAYLAND_EGL) ||
ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_OPENGL_DRM))
e_comp_gl_set(EINA_TRUE);
/* try to create a wayland compositor */
if (!_e_comp_wl_compositor_create())
{
e_error_message_show(_("Enlightenment cannot create a Wayland Compositor!\n"));
return EINA_FALSE;
}
/* try to init ecore_wayland */
if (!ecore_wl_init(NULL))
{
e_error_message_show(_("Enlightenment cannot initialize Ecore_Wayland!\n"));
return EINA_FALSE;
}
return EINA_TRUE;
}
EAPI struct wl_signal
e_comp_wl_surface_create_signal_get(E_Comp *comp)
{
return comp->wl_comp_data->signals.surface.create;
}
/* internal functions */
EINTERN void
e_comp_wl_shutdown(void)
{
}
EINTERN struct wl_resource *
e_comp_wl_surface_create(struct wl_client *client, int version, uint32_t id)
{
return NULL;
}