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

Reply via email to