devilhorns pushed a commit to branch devs/devilhorns/wayland.
commit de204e130194f06206ef7b34d6130b4cb343c2c2
Author: Chris Michael <[email protected]>
Date: Wed Mar 6 13:10:04 2013 +0000
Add start of new Wayland Client compositor code (for wayland clients
in E17).
Signed-off-by: Chris Michael <[email protected]>
---
src/bin/e_comp_wl.c | 544 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 544 insertions(+)
diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index 3e3363f..8c6e525 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -3,14 +3,558 @@
# include "e_comp_wl.h"
#endif
+/* local function prototypes */
+static void _e_comp_wl_cb_bind(struct wl_client *client, void *data
EINA_UNUSED, unsigned int version EINA_UNUSED, unsigned int id);
+static Eina_Bool _e_comp_wl_cb_fd_handle(void *data EINA_UNUSED,
Ecore_Fd_Handler *hdl EINA_UNUSED);
+
+static void _e_comp_wl_cb_surface_create(struct wl_client *client, struct
wl_resource *resource, unsigned int id);
+static void _e_comp_wl_cb_surface_destroy(struct wl_resource *resource);
+static void _e_comp_wl_cb_region_create(struct wl_client *client, struct
wl_resource *resource, unsigned int id);
+static void _e_comp_wl_cb_region_destroy(struct wl_resource *resource);
+
+static void _e_comp_wl_surface_cb_destroy(struct wl_client *client
EINA_UNUSED, struct wl_resource *resource);
+static void _e_comp_wl_surface_cb_attach(struct wl_client *client EINA_UNUSED,
struct wl_resource *resource, struct wl_resource *buffer, int x EINA_UNUSED,
int y EINA_UNUSED);
+static void _e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED,
struct wl_resource *resource, int x, int y, int w, int h);
+static void _e_comp_wl_surface_cb_frame(struct wl_client *client, struct
wl_resource *resource, unsigned int callback);
+static void _e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client
EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region);
+static void _e_comp_wl_surface_cb_input_region_set(struct wl_client *client
EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region);
+static void _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED,
struct wl_resource *resource);
+static void _e_comp_wl_surface_cb_buffer_transform_set(struct wl_client
*client, struct wl_resource *resource, int transform);
+static void _e_comp_wl_surface_cb_pending_buffer_destroy(struct wl_listener
*listener, void *data EINA_UNUSED);
+
+static void _e_comp_wl_region_cb_destroy(struct wl_client *client EINA_UNUSED,
struct wl_resource *resource);
+static void _e_comp_wl_region_cb_add(struct wl_client *client EINA_UNUSED,
struct wl_resource *resource, int x, int y, int w, int h);
+static void _e_comp_wl_region_cb_subtract(struct wl_client *client
EINA_UNUSED, struct wl_resource *resource, int x, int y, int w, int h);
+
+static void _e_comp_wl_frame_cb_destroy(struct wl_resource *resource);
+
+/* local wayland interfaces */
+static const struct wl_compositor_interface _e_wl_comp_interface =
+{
+ _e_comp_wl_cb_surface_create,
+ _e_comp_wl_cb_region_create
+};
+
+static const struct wl_surface_interface _e_wl_surface_interface =
+{
+ _e_comp_wl_surface_cb_destroy,
+ _e_comp_wl_surface_cb_attach,
+ _e_comp_wl_surface_cb_damage,
+ _e_comp_wl_surface_cb_frame,
+ _e_comp_wl_surface_cb_opaque_region_set,
+ _e_comp_wl_surface_cb_input_region_set,
+ _e_comp_wl_surface_cb_commit,
+ _e_comp_wl_surface_cb_buffer_transform_set
+};
+
+static const struct wl_region_interface _e_wl_region_interface =
+{
+ _e_comp_wl_region_cb_destroy,
+ _e_comp_wl_region_cb_add,
+ _e_comp_wl_region_cb_subtract
+};
+
+/* local variables */
+static E_Wayland_Compositor *_e_wl_comp = NULL;
+
Eina_Bool
e_comp_wl_init(void)
{
+ struct wl_event_loop *loop;
+ int fd = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ /* FIXME: This should get the DISPLAY variable and set -0 accordingly */
+ /* setenv("WAYLAND_DISPLAY", "wayland-0", 1); */
+
+ /* try to allocate space for the compositor structure */
+ if (!(_e_wl_comp = E_NEW(E_Wayland_Compositor, 1)))
+ return EINA_FALSE;
+
+ /* try to create the wayland display */
+ if (!(_e_wl_comp->wl.display = wl_display_create()))
+ {
+ ERR("Could not Create a Wayland Display: %m");
+ goto err;
+ }
+
+ /* NB: wl_display_add_socket last */
+ if (wl_display_add_socket(_e_wl_comp->wl.display, NULL) < 0)
+ {
+ ERR("Could not Add Socket to Wayland Display: %m");
+ goto err;
+ }
+
+ /* try to add this wl_display to the globals */
+ if (!wl_display_add_global(_e_wl_comp->wl.display,
+ &wl_compositor_interface, _e_wl_comp,
+ _e_comp_wl_cb_bind))
+ {
+ ERR("Could not Add Wayland Display to Globals: %m");
+ goto err;
+ }
+
+ /* initialize compositor signals */
+ wl_signal_init(&_e_wl_comp->wl.signals.destroy);
+ wl_signal_init(&_e_wl_comp->wl.signals.activate);
+ wl_signal_init(&_e_wl_comp->wl.signals.kill);
+ wl_signal_init(&_e_wl_comp->wl.signals.idle);
+ wl_signal_init(&_e_wl_comp->wl.signals.wake);
+ wl_signal_init(&_e_wl_comp->wl.signals.seat);
+
+ /* initialize compositor lists */
+ wl_list_init(&_e_wl_comp->wl.lists.surface);
+
+ /* TODO: ping_handler = NULL */
+
+ /* initalize the wayland data device manager */
+ wl_data_device_manager_init(_e_wl_comp->wl.display);
+
+ /* initialize the wayland shm mechanism */
+ if (wl_display_init_shm(_e_wl_comp->wl.display) < 0)
+ ERR("Could not intiialize SHM !!!");
+
+ /* get the display's event loop */
+ loop = wl_display_get_event_loop(_e_wl_comp->wl.display);
+
+ /* get the wayland fd */
+ fd = wl_event_loop_get_fd(loop);
+
+ /* add a handler for wayland display events */
+ _e_wl_comp->fd_handler =
+ ecore_main_fd_handler_add(fd, ECORE_FD_READ,
+ _e_comp_wl_cb_fd_handle, NULL, NULL, NULL);
+
return EINA_TRUE;
+
+err:
+ if (_e_wl_comp->fd_handler)
+ ecore_main_fd_handler_del(_e_wl_comp->fd_handler);
+
+ /* destroy the display */
+ if (_e_wl_comp->wl.display) wl_display_destroy(_e_wl_comp->wl.display);
+
+ /* free the allocated structure */
+ free(_e_wl_comp);
+
+ return EINA_FALSE;
}
void
e_comp_wl_shutdown(void)
{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (_e_wl_comp->fd_handler)
+ ecore_main_fd_handler_del(_e_wl_comp->fd_handler);
+
+ /* destroy the display */
+ if (_e_wl_comp->wl.display) wl_display_destroy(_e_wl_comp->wl.display);
+
+ /* free the allocated structure */
+ free(_e_wl_comp);
+}
+
+/* local functions */
+static void
+_e_comp_wl_cb_bind(struct wl_client *client, void *data EINA_UNUSED, unsigned
int version EINA_UNUSED, unsigned int id)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ wl_client_add_object(client, &wl_compositor_interface,
+ &_e_wl_comp_interface, id, _e_wl_comp);
+}
+
+static Eina_Bool
+_e_comp_wl_cb_fd_handle(void *data EINA_UNUSED, Ecore_Fd_Handler *hdl
EINA_UNUSED)
+{
+ struct wl_event_loop *loop;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ /* flush out any events before we sleep */
+ loop = wl_display_get_event_loop(_e_wl_comp->wl.display);
+ wl_event_loop_dispatch(loop, 0);
+
+ wl_display_flush_clients(_e_wl_comp->wl.display);
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_e_comp_wl_cb_surface_create(struct wl_client *client, struct wl_resource
*resource, unsigned int id)
+{
+ E_Wayland_Surface *ews = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ /* try to allocate space for the new surface */
+ if (!(ews = E_NEW(E_Wayland_Surface, 1)))
+ {
+ wl_resource_post_no_memory(resource);
+ return;
+ }
+
+ wl_signal_init(&ews->wl.surface.resource.destroy_signal);
+
+ wl_list_init(&ews->wl.link);
+ wl_list_init(&ews->wl.frames);
+ wl_list_init(&ews->pending.frames);
+ ews->wl.surface.resource.client = NULL;
+
+ ews->pending.buffer_destroy.notify =
+ _e_comp_wl_surface_cb_pending_buffer_destroy;
+
+ ews->width = 700;
+ ews->height = 400;
+
+ ews->win = e_win_new(e_container_current_get(e_manager_current_get()));
+ e_win_borderless_set(ews->win, EINA_TRUE);
+ e_win_shaped_set(ews->win, EINA_TRUE);
+ e_win_move_resize(ews->win, 0, 0, ews->width, ews->height);
+ e_win_show(ews->win);
+
+ ews->img = evas_object_image_filled_add(e_win_evas_get(ews->win));
+ evas_object_move(ews->img, 0, 0);
+ evas_object_resize(ews->img, ews->width, ews->height);
+ evas_object_show(ews->img);
+
+ ews->wl.surface.resource.destroy = _e_comp_wl_cb_surface_destroy;
+ ews->wl.surface.resource.object.id = id;
+ ews->wl.surface.resource.object.interface = &wl_surface_interface;
+ ews->wl.surface.resource.object.implementation =
+ (void (**)(void)) &_e_wl_surface_interface;
+ ews->wl.surface.resource.data = ews;
+
+ wl_client_add_resource(client, &ews->wl.surface.resource);
+}
+
+static void
+_e_comp_wl_cb_surface_destroy(struct wl_resource *resource)
+{
+ E_Wayland_Surface *ews = NULL;
+ E_Wayland_Frame_Cb *cb, *next;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ews = container_of(resource, E_Wayland_Surface, wl.surface.resource);
+
+ /* loop surface pending frame callbacks and destroy them */
+ wl_list_for_each_safe(cb, next, &ews->pending.frames, wl.link)
+ wl_resource_destroy(&cb->wl.resource);
+
+ /* remove pending buffer from list */
+ if (ews->pending.buffer) wl_list_remove(&ews->pending.buffer_destroy.link);
+
+ /* actually destroy the surface */
+ if (ews->img) evas_object_del(ews->img);
+ if (ews->win) e_object_del(E_OBJECT(ews->win));
+
+ /* free any input region */
+// if (ews->input) wl_resource_destroy(&ews->input->wl.resource);
+
+ /* free any opaque region */
+// if (ews->opaque) wl_resource_destroy(&ews->opaque->wl.resource);
+
+ /* loop surface frame callbacks and destroy them */
+ wl_list_for_each_safe(cb, next, &ews->wl.frames, wl.link)
+ wl_resource_destroy(&cb->wl.resource);
+
+ free(ews);
+}
+
+static void
+_e_comp_wl_cb_region_create(struct wl_client *client, struct wl_resource
*resource, unsigned int id)
+{
+ E_Wayland_Region *ewr = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(ewr = E_NEW(E_Wayland_Region, 1)))
+ {
+ wl_resource_post_no_memory(resource);
+ return;
+ }
+
+ ewr->wl.resource.destroy = _e_comp_wl_cb_region_destroy;
+ ewr->wl.resource.object.id = id;
+ ewr->wl.resource.object.interface = &wl_region_interface;
+ ewr->wl.resource.object.implementation =
+ (void (**)(void)) &_e_wl_region_interface;
+ ewr->wl.resource.data = ewr;
+
+ wl_client_add_resource(client, &ewr->wl.resource);
+}
+
+static void
+_e_comp_wl_cb_region_destroy(struct wl_resource *resource)
+{
+ E_Wayland_Region *ewr = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ewr = container_of(resource, E_Wayland_Region, wl.resource);
+ if (!ewr) return;
+
+ eina_tiler_clear(ewr->tiler);
+ eina_tiler_free(ewr->tiler);
+ free(ewr);
+}
+
+static void
+_e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct
wl_resource *resource)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ wl_resource_destroy(resource);
+}
+
+static void
+_e_comp_wl_surface_cb_attach(struct wl_client *client EINA_UNUSED, struct
wl_resource *resource, struct wl_resource *buffer, int x EINA_UNUSED, int y
EINA_UNUSED)
+{
+ E_Wayland_Surface *ews = NULL;
+ struct wl_buffer *buff = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(ews = resource->data)) return;
+ if (buffer) buff = buffer->data;
+
+ /* remove pending buffer */
+ if (ews->pending.buffer)
+ wl_list_remove(&ews->pending.buffer_destroy.link);
+
+ ews->pending.buffer = buff;
+
+ if (buff)
+ {
+ wl_signal_add(&buff->resource.destroy_signal,
+ &ews->pending.buffer_destroy);
+
+ ews->pending.remove_buffer = EINA_FALSE;
+ }
+ else
+ ews->pending.remove_buffer = EINA_TRUE;
+}
+
+static void
+_e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct
wl_resource *resource, int x, int y, int w, int h)
+{
+ E_Wayland_Surface *ews = NULL;
+ Eina_Rectangle *r = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(ews = resource->data)) return;
+
+ if (!ews->damages) ews->damages = eina_tiler_new(ews->width, ews->height);
+
+ if (!(r = eina_rectangle_new(x, y, w, h))) return;
+
+ /* add this rectangle to surface->damage */
+ eina_tiler_rect_add(ews->damages, r);
+}
+
+static void
+_e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource
*resource, unsigned int callback)
+{
+ E_Wayland_Surface *ews = NULL;
+ E_Wayland_Frame_Cb *cb = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(ews = resource->data)) return;
+
+ if (!(cb = E_NEW(E_Wayland_Frame_Cb, 1)))
+ {
+ wl_resource_post_no_memory(resource);
+ return;
+ }
+
+ cb->wl.resource.object.interface = &wl_callback_interface;
+ cb->wl.resource.object.id = callback;
+ cb->wl.resource.destroy = _e_comp_wl_frame_cb_destroy;
+ cb->wl.resource.client = client;
+ cb->wl.resource.data = cb;
+
+ wl_client_add_resource(client, &cb->wl.resource);
+ wl_list_insert(ews->pending.frames.prev, &cb->wl.link);
+}
+
+static void
+_e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED,
struct wl_resource *resource, struct wl_resource *region)
+{
+ E_Wayland_Surface *ews = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(ews = resource->data)) return;
+
+ if (region)
+ {
+ E_Wayland_Region *ewr = NULL;
+
+ if (!(ewr = region->data)) return;
+ ews->opaque = ewr;
+ }
+ else
+ {
+ if (ews->opaque)
+ wl_resource_destroy(&ews->opaque->wl.resource);
+ ews->opaque = NULL;
+ }
+}
+
+static void
+_e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED,
struct wl_resource *resource, struct wl_resource *region)
+{
+ E_Wayland_Surface *ews = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(ews = resource->data)) return;
+
+ if (region)
+ {
+ E_Wayland_Region *ewr = NULL;
+
+ if (!(ewr = region->data)) return;
+ ews->input = ewr;
+ }
+ else
+ {
+ if (ews->input)
+ wl_resource_destroy(&ews->input->wl.resource);
+ ews->input = NULL;
+ }
+}
+
+static void
+_e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct
wl_resource *resource)
+{
+ E_Wayland_Surface *ews = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(ews = resource->data)) return;
+
+ if ((!ews->pending.buffer) || (ews->pending.remove_buffer))
+ {
+ evas_object_image_data_set(ews->img, NULL);
+ ews->pending.buffer = NULL;
+ return;
+ }
+
+ if (ews->damages)
+ {
+ Eina_Iterator *itr;
+ Eina_Rectangle *r;
+
+ itr = eina_tiler_iterator_new(ews->damages);
+ EINA_ITERATOR_FOREACH(itr, r)
+ evas_object_image_data_update_add(ews->img, r->x, r->y,
+ r->w, r->h);
+ /* _e_comp_win_damage(ews->win->border->cw, */
+ /* r->x, r->y, r->w, r->h, EINA_FALSE); */
+ eina_iterator_free(itr);
+
+ eina_tiler_clear(ews->damages);
+ }
+
+ if (ews->pending.buffer)
+ {
+ int bw = 0, bh = 0;
+ void *data;
+
+ bw = ews->pending.buffer->width;
+ bh = ews->pending.buffer->height;
+
+ if ((ews->width != bw) || (ews->height != bh))
+ {
+ ews->width = bw;
+ ews->height = bh;
+ e_win_resize(ews->win, bw, bh);
+
+ evas_object_resize(ews->img, bw, bh);
+ }
+
+ evas_object_image_load_size_set(ews->img, bw, bh);
+ evas_object_image_size_set(ews->img, bw, bh);
+
+ /* grab the pixel data from the buffer */
+ data = wl_shm_buffer_get_data(ews->pending.buffer);
+
+ /* set the image data */
+ evas_object_image_data_set(ews->img, data);
+ }
+
+ wl_list_insert_list(&ews->wl.frames, &ews->pending.frames);
+ wl_list_init(&ews->pending.frames);
+}
+
+static void
+_e_comp_wl_surface_cb_buffer_transform_set(struct wl_client *client, struct
wl_resource *resource, int transform)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+}
+
+static void
+_e_comp_wl_surface_cb_pending_buffer_destroy(struct wl_listener *listener,
void *data EINA_UNUSED)
+{
+ E_Wayland_Surface *ews = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ ews = container_of(listener, E_Wayland_Surface, pending.buffer_destroy);
+ if (!ews) return;
+ ews->pending.buffer = NULL;
+}
+
+static void
+_e_comp_wl_region_cb_destroy(struct wl_client *client EINA_UNUSED, struct
wl_resource *resource)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ wl_resource_destroy(resource);
+}
+
+static void
+_e_comp_wl_region_cb_add(struct wl_client *client EINA_UNUSED, struct
wl_resource *resource, int x, int y, int w, int h)
+{
+ E_Wayland_Region *ewr = NULL;
+ Eina_Rectangle *r;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(ewr = resource->data)) return;
+ if (!ewr->tiler) ewr->tiler = eina_tiler_new(w, h);
+ if (!(r = eina_rectangle_new(x, y, w, h))) return;
+ eina_tiler_rect_add(ewr->tiler, r);
+}
+
+static void
+_e_comp_wl_region_cb_subtract(struct wl_client *client EINA_UNUSED, struct
wl_resource *resource, int x, int y, int w, int h)
+{
+ E_Wayland_Region *ewr = NULL;
+ Eina_Rectangle *r;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(ewr = resource->data)) return;
+ if (!(r = eina_rectangle_new(x, y, w, h))) return;
+ eina_tiler_rect_del(ewr->tiler, r);
+}
+
+static void
+_e_comp_wl_frame_cb_destroy(struct wl_resource *resource)
+{
+ E_Wayland_Frame_Cb *cb = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!(cb = resource->data)) return;
+ wl_list_remove(&cb->wl.link);
+ free(cb);
}
--
------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev