2013-04-25 00:34:56 -07:00
|
|
|
#include "e.h"
|
|
|
|
#include "e_mod_main.h"
|
|
|
|
|
|
|
|
/* local function prototypes */
|
2013-05-02 01:10:56 -07:00
|
|
|
static Eina_Bool _output_init(void);
|
|
|
|
static void _output_shutdown(E_Output_X11 *output);
|
|
|
|
static int _output_cb_frame(void *data);
|
2013-05-06 05:28:30 -07:00
|
|
|
static void _output_cb_repaint_start(E_Output *output);
|
|
|
|
static void _output_cb_repaint(E_Output *output, E_Region *damages);
|
2013-05-02 01:10:56 -07:00
|
|
|
static void _output_cb_destroy(E_Output *output);
|
2013-05-02 04:22:53 -07:00
|
|
|
static Eina_Bool _output_cb_window_destroy(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
|
2013-05-06 05:28:30 -07:00
|
|
|
static void _comp_cb_attach(E_Surface *es, struct wl_buffer *buffer);
|
2013-04-25 00:34:56 -07:00
|
|
|
|
|
|
|
/* local variables */
|
2013-05-03 02:31:26 -07:00
|
|
|
static E_Compositor_X11 *_e_x11_comp;
|
2013-05-02 04:22:53 -07:00
|
|
|
static Eina_List *_hdlrs = NULL;
|
2013-04-25 00:34:56 -07:00
|
|
|
|
|
|
|
EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_X11" };
|
|
|
|
|
|
|
|
EAPI void *
|
|
|
|
e_modapi_init(E_Module *m)
|
|
|
|
{
|
|
|
|
/* try to allocate space for comp structure */
|
2013-05-03 02:31:26 -07:00
|
|
|
if (!(_e_x11_comp = E_NEW(E_Compositor_X11, 1)))
|
2013-04-25 00:34:56 -07:00
|
|
|
{
|
|
|
|
ERR("Could not allocate space for compositor: %m");
|
2013-05-02 01:10:56 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* try to init ecore_x */
|
|
|
|
if (!ecore_x_init(NULL))
|
|
|
|
{
|
|
|
|
ERR("Could not initialize ecore_x: %m");
|
|
|
|
goto x_err;
|
2013-04-25 00:34:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* get the X display */
|
2013-05-03 02:31:26 -07:00
|
|
|
_e_x11_comp->display = ecore_x_display_get();
|
2013-04-25 00:34:56 -07:00
|
|
|
|
|
|
|
/* try to initialize generic compositor */
|
2013-05-03 02:31:26 -07:00
|
|
|
if (!e_compositor_init(&_e_x11_comp->base, _e_x11_comp->display))
|
2013-04-25 00:34:56 -07:00
|
|
|
{
|
|
|
|
ERR("Could not initialize compositor: %m");
|
2013-05-02 01:10:56 -07:00
|
|
|
goto comp_err;
|
2013-04-25 00:34:56 -07:00
|
|
|
}
|
|
|
|
|
2013-05-06 05:28:30 -07:00
|
|
|
/* set the compositor attach function */
|
|
|
|
_e_x11_comp->base.attach = _comp_cb_attach;
|
|
|
|
|
2013-05-02 01:10:56 -07:00
|
|
|
/* try to initialize output */
|
|
|
|
if (!_output_init())
|
|
|
|
{
|
|
|
|
ERR("Could not initialize output: %m");
|
|
|
|
goto output_err;
|
|
|
|
}
|
2013-04-25 00:34:56 -07:00
|
|
|
|
2013-05-02 04:22:53 -07:00
|
|
|
E_LIST_HANDLER_APPEND(_hdlrs, ECORE_X_EVENT_WINDOW_DELETE_REQUEST,
|
|
|
|
_output_cb_window_destroy, NULL);
|
|
|
|
|
2013-04-25 05:59:13 -07:00
|
|
|
/* flush any pending events
|
|
|
|
*
|
|
|
|
* NB: This advertises out any globals so it needs to be deferred
|
|
|
|
* until after the module has finished initialize */
|
2013-05-03 02:31:26 -07:00
|
|
|
/* wl_event_loop_dispatch(_e_x11_comp->base.wl.loop, 0); */
|
2013-04-25 05:59:13 -07:00
|
|
|
|
2013-04-25 00:34:56 -07:00
|
|
|
return m;
|
|
|
|
|
2013-05-02 01:10:56 -07:00
|
|
|
output_err:
|
|
|
|
/* shutdown the e_compositor */
|
2013-05-03 02:31:26 -07:00
|
|
|
e_compositor_shutdown(&_e_x11_comp->base);
|
2013-05-02 01:10:56 -07:00
|
|
|
|
|
|
|
comp_err:
|
2013-04-25 00:34:56 -07:00
|
|
|
/* shutdown ecore_x */
|
|
|
|
ecore_x_shutdown();
|
|
|
|
|
2013-05-02 01:10:56 -07:00
|
|
|
x_err:
|
2013-04-25 00:34:56 -07:00
|
|
|
/* free the structure */
|
2013-05-03 02:31:26 -07:00
|
|
|
E_FREE(_e_x11_comp);
|
2013-04-25 00:34:56 -07:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
|
|
|
e_modapi_shutdown(E_Module *m)
|
|
|
|
{
|
2013-05-02 01:10:56 -07:00
|
|
|
E_Output_X11 *output;
|
|
|
|
|
2013-05-02 04:22:53 -07:00
|
|
|
/* destroy the list of handlers */
|
|
|
|
E_FREE_LIST(_hdlrs, ecore_event_handler_del);
|
|
|
|
|
2013-05-02 01:10:56 -07:00
|
|
|
/* destroy the outputs */
|
2013-05-03 02:31:26 -07:00
|
|
|
EINA_LIST_FREE(_e_x11_comp->base.outputs, output)
|
2013-05-02 01:10:56 -07:00
|
|
|
_output_shutdown(output);
|
2013-04-25 00:34:56 -07:00
|
|
|
|
|
|
|
/* shutdown generic compositor */
|
2013-05-03 02:31:26 -07:00
|
|
|
if (&_e_x11_comp->base) e_compositor_shutdown(&_e_x11_comp->base);
|
2013-04-25 00:34:56 -07:00
|
|
|
|
|
|
|
/* shutdown ecore_x */
|
|
|
|
ecore_x_shutdown();
|
|
|
|
|
|
|
|
/* free the structure */
|
2013-05-03 02:31:26 -07:00
|
|
|
E_FREE(_e_x11_comp);
|
2013-04-25 00:34:56 -07:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2013-05-02 01:10:56 -07:00
|
|
|
|
|
|
|
/* local functions */
|
|
|
|
static Eina_Bool
|
|
|
|
_output_init(void)
|
|
|
|
{
|
|
|
|
E_Output_X11 *output;
|
|
|
|
struct wl_event_loop *loop;
|
2013-05-06 05:28:30 -07:00
|
|
|
unsigned int mask;
|
2013-05-02 01:10:56 -07:00
|
|
|
|
|
|
|
/* try to allocate space for our output structure */
|
|
|
|
if (!(output = E_NEW(E_Output_X11, 1)))
|
|
|
|
{
|
|
|
|
ERR("Could not allocate space for output structure");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
output->mode.flags = (WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED);
|
|
|
|
output->mode.w = 1024;
|
|
|
|
output->mode.h = 768;
|
|
|
|
output->mode.refresh = 60;
|
|
|
|
|
|
|
|
/* add this mode to the base outputs list of modes */
|
|
|
|
output->base.modes = eina_list_append(output->base.modes, &output->mode);
|
|
|
|
|
|
|
|
/* try to create the output window */
|
|
|
|
if (!(output->win =
|
|
|
|
ecore_x_window_new(0, 0, 0, output->mode.w, output->mode.h)))
|
|
|
|
{
|
|
|
|
ERR("Failed to create ecore_x_window");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set window background color */
|
|
|
|
ecore_x_window_background_color_set(output->win, 0, 0, 0);
|
|
|
|
|
2013-05-02 04:22:53 -07:00
|
|
|
ecore_x_icccm_protocol_set(output->win,
|
|
|
|
ECORE_X_WM_PROTOCOL_DELETE_REQUEST, EINA_TRUE);
|
|
|
|
|
2013-05-02 01:10:56 -07:00
|
|
|
/* set window to not maximize */
|
|
|
|
ecore_x_icccm_size_pos_hints_set(output->win, EINA_FALSE,
|
|
|
|
ECORE_X_GRAVITY_NW,
|
|
|
|
output->mode.w, output->mode.h,
|
|
|
|
output->mode.w, output->mode.h,
|
|
|
|
0, 0, 1, 1, 0.0, 0.0);
|
|
|
|
|
|
|
|
/* set window title */
|
|
|
|
ecore_x_icccm_title_set(output->win, "E_Wayland X11 Compositor");
|
|
|
|
ecore_x_icccm_name_class_set(output->win, "E_Wayland X11 Compositor",
|
|
|
|
"e_wayland/X11 Compositor");
|
|
|
|
|
|
|
|
/* show the window */
|
|
|
|
ecore_x_window_show(output->win);
|
|
|
|
|
2013-05-06 05:28:30 -07:00
|
|
|
/* output->pmap = */
|
|
|
|
/* ecore_x_pixmap_new(output->win, output->mode.w, output->mode.h, */
|
|
|
|
/* ecore_x_window_depth_get(output->win)); */
|
|
|
|
|
|
|
|
/* output->gc = */
|
|
|
|
/* ecore_x_gc_new(output->pmap, (ECORE_X_GC_VALUE_MASK_PLANE_MASK | */
|
|
|
|
/* ECORE_X_GC_VALUE_MASK_FOREGROUND), &mask); */
|
|
|
|
|
|
|
|
/* ecore_x_window_pixmap_set(output->win, output->pmap); */
|
|
|
|
|
2013-05-02 01:10:56 -07:00
|
|
|
output->base.current = &output->mode;
|
|
|
|
output->base.original = output->base.current;
|
|
|
|
output->base.make = "e_wayland";
|
|
|
|
output->base.model = "none";
|
|
|
|
output->base.cb_destroy = _output_cb_destroy;
|
2013-05-06 05:28:30 -07:00
|
|
|
output->base.cb_repaint_start = _output_cb_repaint_start;
|
|
|
|
|
|
|
|
/* FIXME: Change this based on software/gl */
|
|
|
|
output->base.cb_repaint = _output_cb_repaint;
|
2013-05-02 01:10:56 -07:00
|
|
|
|
|
|
|
/* initialize base output */
|
2013-05-03 02:31:26 -07:00
|
|
|
e_output_init(&output->base, &_e_x11_comp->base, 0, 0,
|
2013-05-02 01:10:56 -07:00
|
|
|
output->mode.w, output->mode.h, output->mode.flags);
|
|
|
|
|
|
|
|
/* TODO: deal with render */
|
|
|
|
|
|
|
|
/* get the wl event loop */
|
2013-05-03 02:31:26 -07:00
|
|
|
loop = wl_display_get_event_loop(_e_x11_comp->base.wl.display);
|
2013-05-02 01:10:56 -07:00
|
|
|
|
|
|
|
/* add a timer to the event loop */
|
|
|
|
output->frame_timer =
|
|
|
|
wl_event_loop_add_timer(loop, _output_cb_frame, output);
|
|
|
|
|
|
|
|
/* add this output to the base compositors output list */
|
2013-05-03 02:31:26 -07:00
|
|
|
_e_x11_comp->base.outputs = eina_list_append(_e_x11_comp->base.outputs, output);
|
2013-05-02 01:10:56 -07:00
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_output_shutdown(E_Output_X11 *output)
|
|
|
|
{
|
|
|
|
E_FREE(output);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_output_cb_frame(void *data)
|
|
|
|
{
|
|
|
|
E_Output_X11 *output;
|
|
|
|
|
|
|
|
if (!(output = data)) return 1;
|
2013-05-06 05:28:30 -07:00
|
|
|
|
|
|
|
/* start the repaint loop */
|
2013-05-07 02:42:36 -07:00
|
|
|
_output_cb_repaint_start(&output->base);
|
2013-05-06 05:28:30 -07:00
|
|
|
|
2013-05-02 01:10:56 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-05-06 05:28:30 -07:00
|
|
|
static void
|
|
|
|
_output_cb_repaint_start(E_Output *output)
|
|
|
|
{
|
|
|
|
/* TODO */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_output_cb_repaint(E_Output *output, E_Region *damages)
|
|
|
|
{
|
|
|
|
/* TODO */
|
|
|
|
}
|
|
|
|
|
2013-05-02 01:10:56 -07:00
|
|
|
static void
|
|
|
|
_output_cb_destroy(E_Output *output)
|
|
|
|
{
|
|
|
|
E_Output_X11 *xout;
|
|
|
|
|
|
|
|
xout = (E_Output_X11 *)output;
|
|
|
|
|
|
|
|
/* remove the frame timer */
|
|
|
|
wl_event_source_remove(xout->frame_timer);
|
|
|
|
|
2013-05-06 05:28:30 -07:00
|
|
|
/* destroy the pixmap */
|
|
|
|
if (xout->pmap) ecore_x_pixmap_free(xout->pmap);
|
|
|
|
|
|
|
|
/* destroy the gc */
|
|
|
|
if (xout->gc) ecore_x_gc_free(xout->gc);
|
|
|
|
|
2013-05-02 01:10:56 -07:00
|
|
|
/* destroy the window */
|
|
|
|
if (xout->win) ecore_x_window_free(xout->win);
|
|
|
|
|
|
|
|
/* destroy the base output */
|
|
|
|
e_output_shutdown(&xout->base);
|
|
|
|
|
|
|
|
/* free the structure */
|
|
|
|
E_FREE(xout);
|
|
|
|
}
|
2013-05-02 04:22:53 -07:00
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_output_cb_window_destroy(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Ecore_X_Event_Window_Delete_Request *ev;
|
|
|
|
E_Output_X11 *output;
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
ev = event;
|
|
|
|
|
|
|
|
/* loop the existing outputs */
|
2013-05-03 02:31:26 -07:00
|
|
|
EINA_LIST_FOREACH(_e_x11_comp->base.outputs, l, output)
|
2013-05-02 04:22:53 -07:00
|
|
|
{
|
|
|
|
/* try to match the output window */
|
|
|
|
if (ev->win == output->win)
|
|
|
|
{
|
|
|
|
/* output window being closed, quit */
|
|
|
|
/* NB: FIXME: This assumes we have only one output window */
|
|
|
|
ecore_main_loop_quit();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
}
|
2013-05-06 05:28:30 -07:00
|
|
|
|
|
|
|
static void
|
|
|
|
_comp_cb_attach(E_Surface *es, struct wl_buffer *buffer)
|
|
|
|
{
|
|
|
|
printf("Wl_X11 Attach: %p\n", es);
|
|
|
|
}
|