2013-04-24 07:16:19 -07:00
|
|
|
#include "e.h"
|
|
|
|
|
|
|
|
/* local function prototypes */
|
|
|
|
static void _e_comp_cb_bind(struct wl_client *client, void *data EINA_UNUSED, unsigned int version EINA_UNUSED, unsigned int id);
|
2013-04-24 23:43:39 -07:00
|
|
|
static void _e_comp_cb_surface_create(struct wl_client *client, struct wl_resource *resource, unsigned int id);
|
|
|
|
static void _e_comp_cb_region_create(struct wl_client *client, struct wl_resource *resource, unsigned int id);
|
2013-04-24 07:16:19 -07:00
|
|
|
|
|
|
|
/* local interfaces */
|
|
|
|
static const struct wl_compositor_interface _e_compositor_interface =
|
|
|
|
{
|
2013-04-24 23:43:39 -07:00
|
|
|
_e_comp_cb_surface_create,
|
|
|
|
_e_comp_cb_region_create
|
2013-04-24 07:16:19 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
/* local variables */
|
|
|
|
|
|
|
|
EINTERN int
|
|
|
|
e_comp_init(void)
|
|
|
|
{
|
2013-04-24 23:43:39 -07:00
|
|
|
E_Module *mod = NULL;
|
|
|
|
const char *modname;
|
2013-04-24 07:16:19 -07:00
|
|
|
|
2013-04-24 23:43:39 -07:00
|
|
|
/* NB: Basically, this function needs to load the appropriate
|
|
|
|
* compositor module (drm, fb, x11, etc) */
|
|
|
|
|
|
|
|
if (getenv("DISPLAY"))
|
|
|
|
modname = "wl_x11";
|
|
|
|
else
|
|
|
|
modname = "wl_drm";
|
|
|
|
|
|
|
|
if (!(mod = e_module_find(modname)))
|
|
|
|
mod = e_module_new(modname);
|
|
|
|
|
|
|
|
if (mod)
|
2013-04-24 07:16:19 -07:00
|
|
|
{
|
2013-04-24 23:43:39 -07:00
|
|
|
e_module_enable(mod);
|
|
|
|
return 1;
|
2013-04-24 07:16:19 -07:00
|
|
|
}
|
|
|
|
|
2013-04-24 23:43:39 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
EINTERN int
|
|
|
|
e_comp_shutdown(void)
|
|
|
|
{
|
|
|
|
E_Module *mod = NULL;
|
|
|
|
const char *modname;
|
|
|
|
|
|
|
|
/* NB: This function needs to unload the compositor module */
|
|
|
|
|
|
|
|
if (getenv("DISPLAY"))
|
|
|
|
modname = "wl_x11";
|
|
|
|
else
|
|
|
|
modname = "wl_drm";
|
|
|
|
|
|
|
|
if ((mod = e_module_find(modname)))
|
|
|
|
e_module_disable(mod);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Bool
|
|
|
|
e_compositor_init(E_Compositor *comp)
|
|
|
|
{
|
2013-04-24 07:16:19 -07:00
|
|
|
/* try to create a wayland display */
|
2013-04-24 23:43:39 -07:00
|
|
|
if (!(comp->wl.display = wl_display_create()))
|
2013-04-24 07:16:19 -07:00
|
|
|
{
|
|
|
|
ERR("Could not create a wayland display: %m");
|
2013-04-24 23:43:39 -07:00
|
|
|
return EINA_FALSE;
|
2013-04-24 07:16:19 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* initialize signals */
|
2013-04-24 23:43:39 -07:00
|
|
|
wl_signal_init(&comp->signals.destroy);
|
|
|
|
wl_signal_init(&comp->signals.activate);
|
|
|
|
wl_signal_init(&comp->signals.kill);
|
|
|
|
wl_signal_init(&comp->signals.seat);
|
2013-04-24 07:16:19 -07:00
|
|
|
|
|
|
|
/* try to add the compositor to the displays global list */
|
2013-04-24 23:43:39 -07:00
|
|
|
if (!wl_display_add_global(comp->wl.display, &wl_compositor_interface,
|
|
|
|
comp, _e_comp_cb_bind))
|
2013-04-24 07:16:19 -07:00
|
|
|
{
|
|
|
|
ERR("Could not add compositor to globals: %m");
|
|
|
|
goto global_err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* initialize the data device manager */
|
2013-04-24 23:43:39 -07:00
|
|
|
wl_data_device_manager_init(comp->wl.display);
|
2013-04-24 07:16:19 -07:00
|
|
|
|
|
|
|
/* try to initialize the shm mechanism */
|
2013-04-24 23:43:39 -07:00
|
|
|
if (wl_display_init_shm(comp->wl.display) < 0)
|
2013-04-24 07:16:19 -07:00
|
|
|
ERR("Could not initialize SHM mechanism: %m");
|
|
|
|
|
|
|
|
#ifdef HAVE_WAYLAND_EGL
|
2013-04-24 22:58:46 -07:00
|
|
|
/* 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 */
|
2013-04-24 23:43:39 -07:00
|
|
|
comp->egl.display = eglGetDisplay(NULL);
|
|
|
|
if (comp->egl.display == EGL_NO_DISPLAY)
|
2013-04-24 22:58:46 -07:00
|
|
|
ERR("Could not get EGL display: %m");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
EGLint major, minor;
|
|
|
|
|
|
|
|
/* try to initialize EGL */
|
2013-04-24 23:43:39 -07:00
|
|
|
if (!eglInitialize(comp->egl.display, &major, &minor))
|
2013-04-24 22:58:46 -07:00
|
|
|
{
|
|
|
|
ERR("Could not initialize EGL: %m");
|
2013-04-24 23:43:39 -07:00
|
|
|
eglTerminate(comp->egl.display);
|
|
|
|
eglReleaseThread();
|
2013-04-24 22:58:46 -07:00
|
|
|
}
|
|
|
|
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
|
|
|
|
};
|
|
|
|
|
|
|
|
/* try to find a matching egl config */
|
2013-04-24 23:43:39 -07:00
|
|
|
if ((!eglChooseConfig(comp->egl.display, attribs,
|
|
|
|
&comp->egl.config, 1, &n) || (n == 0)))
|
2013-04-24 22:58:46 -07:00
|
|
|
{
|
|
|
|
ERR("Could not choose EGL config: %m");
|
2013-04-24 23:43:39 -07:00
|
|
|
eglTerminate(comp->egl.display);
|
|
|
|
eglReleaseThread();
|
2013-04-24 22:58:46 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-04-24 07:16:19 -07:00
|
|
|
#endif
|
|
|
|
|
2013-04-24 23:43:39 -07:00
|
|
|
return EINA_TRUE;
|
2013-04-24 07:16:19 -07:00
|
|
|
|
|
|
|
global_err:
|
|
|
|
/* destroy the previously created display */
|
2013-04-24 23:43:39 -07:00
|
|
|
if (comp->wl.display) wl_display_destroy(comp->wl.display);
|
2013-04-24 07:16:19 -07:00
|
|
|
|
2013-04-24 23:43:39 -07:00
|
|
|
return EINA_FALSE;
|
2013-04-24 07:16:19 -07:00
|
|
|
}
|
|
|
|
|
2013-04-24 23:43:39 -07:00
|
|
|
EAPI Eina_Bool
|
|
|
|
e_compositor_shutdown(E_Compositor *comp)
|
2013-04-24 07:16:19 -07:00
|
|
|
{
|
2013-04-24 22:58:46 -07:00
|
|
|
#ifdef HAVE_WAYLAND_EGL
|
|
|
|
/* destroy the egl display */
|
2013-04-24 23:43:39 -07:00
|
|
|
if (comp->egl.display) eglTerminate(comp->egl.display);
|
|
|
|
eglReleaseThread();
|
2013-04-24 22:58:46 -07:00
|
|
|
#endif
|
|
|
|
|
2013-04-24 07:16:19 -07:00
|
|
|
/* destroy the previously created display */
|
2013-04-24 23:43:39 -07:00
|
|
|
if (comp->wl.display) wl_display_destroy(comp->wl.display);
|
2013-04-24 07:16:19 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* local functions */
|
|
|
|
static void
|
|
|
|
_e_comp_cb_bind(struct wl_client *client, void *data EINA_UNUSED, unsigned int version EINA_UNUSED, unsigned int id)
|
|
|
|
{
|
|
|
|
/* add the compositor to the client */
|
|
|
|
wl_client_add_object(client, &wl_compositor_interface,
|
|
|
|
&_e_compositor_interface, id, _e_comp);
|
|
|
|
}
|
2013-04-24 23:43:39 -07:00
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_cb_surface_create(struct wl_client *client, struct wl_resource *resource, unsigned int id)
|
|
|
|
{
|
|
|
|
E_Compositor *comp;
|
|
|
|
|
|
|
|
if (!(comp = resource->data)) return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_cb_region_create(struct wl_client *client, struct wl_resource *resource, unsigned int id)
|
|
|
|
{
|
|
|
|
E_Compositor *comp;
|
|
|
|
|
|
|
|
if (!(comp = resource->data)) return;
|
|
|
|
}
|