devilhorns pushed a commit to branch master.
commit 1fac56a7e4490a99c007b46a98c5d5fbde3b5104
Author: Chris Michael <[email protected]>
Date: Wed Apr 10 10:59:14 2013 +0100
Add code to load/unload the desktop shell module.
Add code to handle surface attach requests.
Add code to handle surface commit requests:
- Use the surface smart object to handle input and image updates.
Signed-off-by: Chris Michael <[email protected]>
---
src/bin/e_comp_wl.c | 224 ++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 207 insertions(+), 17 deletions(-)
diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index ef13c44..d524540 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -1,5 +1,6 @@
#include "e.h"
#include "e_comp_wl.h"
+#include "e_surface.h"
#include <sys/mman.h>
/* compositor function prototypes */
@@ -241,6 +242,8 @@ err:
void
e_comp_wl_shutdown(void)
{
+ E_Module *mod = NULL;
+
/* remove the idler */
if (_e_wl_comp->idler) ecore_idler_del(_e_wl_comp->idler);
@@ -264,7 +267,20 @@ e_comp_wl_shutdown(void)
/* free the compositor */
E_FREE(_e_wl_comp);
- /* TODO: unload shell module */
+ /* disable the loaded shell module */
+ /* TODO: we should have a config variable somewhere to store which
+ * shell we want to unload (tablet, mobile, etc) */
+ if ((mod = e_module_find("wl_desktop_shell")))
+ e_module_disable(mod);
+}
+
+unsigned int
+e_comp_wl_time_get(void)
+{
+ struct timeval tm;
+
+ gettimeofday(&tm, NULL);
+ return (tm.tv_sec * 1000 + tm.tv_usec / 1000);
}
/* local functions */
@@ -351,6 +367,8 @@ _e_comp_wl_cb_surface_create(struct wl_client *client,
struct wl_resource *resou
wl_list_init(&ews->wl.frames);
wl_list_init(&ews->pending.frames);
+ ews->wl.surface.resource.client = NULL;
+
/* set destroy function for pending buffers */
ews->pending.buffer_destroy.notify =
_e_comp_wl_surface_cb_pending_buffer_destroy;
@@ -846,7 +864,7 @@ _e_comp_wl_input_cb_pointer_get(struct wl_client *client,
struct wl_resource *re
if ((input->wl.seat.pointer->focus) &&
(input->wl.seat.pointer->focus->resource.client == client))
{
- /* FIXME: what to pass to wl_pointer_set_focus (x/y) */
+ /* tell pointer which surface is focused */
wl_pointer_set_focus(input->wl.seat.pointer,
input->wl.seat.pointer->focus,
input->wl.seat.pointer->x,
@@ -960,31 +978,32 @@ _e_comp_wl_pointer_configure(E_Wayland_Surface *ews,
Evas_Coord x, Evas_Coord y,
* using the pixels from their cursor surface */
/* is it mapped ? */
- if ((focus->mapped) && (focus->ee))
- {
- Ecore_Window win;
+ /* FIXME !!! Use Smart Object */
+ /* if ((focus->mapped) && (focus->ee)) */
+ /* { */
+ /* Ecore_Window win; */
/* try to get the ecore_window */
- if ((win = ecore_evas_window_get(focus->ee)))
- {
- void *pixels;
- Ecore_X_Cursor cur;
+ /* if ((win = ecore_evas_window_get(focus->ee))) */
+ /* { */
+ /* void *pixels; */
+ /* Ecore_X_Cursor cur; */
/* grab the pixels from the cursor surface */
- pixels = wl_shm_buffer_get_data(ews->reference.buffer);
+ /* pixels = wl_shm_buffer_get_data(ews->reference.buffer); */
/* create the new X cursor with this image */
- cur = ecore_x_cursor_new(win, pixels, w, h,
- input->pointer.hot.x,
- input->pointer.hot.y);
+ /* cur = ecore_x_cursor_new(win, pixels, w, h, */
+ /* input->pointer.hot.x, */
+ /* input->pointer.hot.y); */
/* set the cursor on this window */
- ecore_x_window_cursor_set(win, cur);
+ /* ecore_x_window_cursor_set(win, cur); */
/* free the cursor */
- ecore_x_cursor_free(cur);
- }
- }
+ /* ecore_x_cursor_free(cur); */
+ /* } */
+ /* } */
}
}
@@ -1019,6 +1038,9 @@ _e_comp_wl_pointer_cb_cursor_set(struct wl_client
*client, struct wl_resource *r
/* if we were passed in a surface, try to cast it to our structure */
if (surface_resource) ews = (E_Wayland_Surface *)surface_resource->data;
+ /* if this input has no pointer, get out */
+ if (!input->has_pointer) return;
+
/* if the input has no current focus, get out */
if (!input->wl.seat.pointer->focus) return;
@@ -1210,7 +1232,40 @@ _e_comp_wl_surface_cb_destroy(struct wl_client *client
EINA_UNUSED, struct wl_re
static void
_e_comp_wl_surface_cb_attach(struct wl_client *client EINA_UNUSED, struct
wl_resource *resource, struct wl_resource *buffer_resource, int x, int y)
{
+ E_Wayland_Surface *ews = NULL;
+ struct wl_buffer *buffer = NULL;
+
+ /* try to cast the resource data to our surface structure */
+ if (!(ews = resource->data)) return;
+
+ if (buffer_resource) buffer = buffer_resource->data;
+
+ /* reference any existing buffers */
+ _e_comp_wl_surface_buffer_reference(ews, buffer);
+
+ /* if we are setting a null buffer, then unmap the surface */
+ if (!buffer)
+ {
+ if (ews->mapped)
+ {
+ if (ews->unmap) ews->unmap(ews);
+ }
+ }
+
+ /* if we already have a pending buffer, remove the listener */
+ if (ews->pending.buffer)
+ wl_list_remove(&ews->pending.buffer_destroy.link);
+
+ /* set some pending values */
+ ews->pending.x = x;
+ ews->pending.y = y;
+ ews->pending.buffer = buffer;
+ ews->pending.new_buffer = EINA_TRUE;
+ /* if we were given a buffer, initialize the destroy signal */
+ if (buffer)
+ wl_signal_add(&buffer->resource.destroy_signal,
+ &ews->pending.buffer_destroy);
}
static void
@@ -1312,5 +1367,140 @@ _e_comp_wl_surface_cb_input_region_set(struct wl_client
*client EINA_UNUSED, str
static void
_e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct
wl_resource *resource)
{
+ E_Wayland_Surface *ews = NULL;
+ Evas_Coord bw = 0, bh = 0;
+ pixman_region32_t opaque;
+ pixman_box32_t *rects;
+ int n = 0;
+
+ /* FIXME */
+
+ /* try to cast the resource data to our surface structure */
+ if (!(ews = resource->data)) return;
+
+ /* if we have a pending buffer or a new pending buffer, attach it */
+ if ((ews->pending.buffer) || (ews->pending.new_buffer))
+ {
+ /* reference the pending buffer */
+ _e_comp_wl_surface_buffer_reference(ews, ews->pending.buffer);
+
+ /* if the pending buffer is NULL, unmap the surface */
+ if (!ews->pending.buffer)
+ {
+ if (ews->mapped)
+ {
+ if (ews->unmap) ews->unmap(ews);
+ }
+ }
+ else
+ {
+ if (ews->obj)
+ {
+ void *data;
+
+ bw = ews->pending.buffer->width;
+ bh = ews->pending.buffer->height;
+
+ /* grab the pixel data from the buffer */
+ data = wl_shm_buffer_get_data(ews->pending.buffer);
+
+ /* send the pixel data to the smart object */
+ e_surface_image_set(ews->obj, bw, bh, data);
+ }
+ }
+ }
+
+ /* if we have a reference to a buffer, get it's size */
+ if (ews->reference.buffer)
+ {
+ bw = ews->reference.buffer->width;
+ bh = ews->reference.buffer->height;
+ }
+
+ /* if we have a new pending buffer, call configure */
+ if ((ews->configure) && (ews->pending.new_buffer))
+ ews->configure(ews, ews->geometry.x, ews->geometry.y, bw, bh);
+
+ if (ews->pending.buffer)
+ wl_list_remove(&ews->pending.buffer_destroy.link);
+
+ /* set some pending values */
+ ews->pending.buffer = NULL;
+ ews->pending.x = 0;
+ ews->pending.y = 0;
+ ews->pending.new_buffer = EINA_FALSE;
+
+ /* set surface damage */
+ pixman_region32_union(&ews->region.damage, &ews->region.damage,
+ &ews->pending.damage);
+ pixman_region32_intersect_rect(&ews->region.damage, &ews->region.damage,
+ 0, 0, ews->geometry.w, ews->geometry.h);
+
+ /* empty any pending damage */
+ pixman_region32_fini(&ews->pending.damage);
+ pixman_region32_init(&ews->pending.damage);
+
+ /* get the extent of the damage region */
+ rects = pixman_region32_rectangles(&ews->region.damage, &n);
+ while (n--)
+ {
+ pixman_box32_t *r;
+
+ r = &rects[n];
+
+ /* send damages to the image */
+ e_surface_damage_add(ews->obj, r->x1, r->y1, r->x2, r->y2);
+ }
+
+ /* tell pixman we are finished with this region */
+ /* pixman_region32_fini(&ews->region.damage); */
+
+ /* reinitalize the damage region */
+ /* pixman_region32_init(&ews->region.damage); */
+
+ /* calculate new opaque region */
+ pixman_region32_init_rect(&opaque, 0, 0, ews->geometry.w, ews->geometry.h);
+ pixman_region32_intersect(&opaque, &opaque, &ews->pending.opaque);
+
+ /* if new opaque region is not equal to the current one, then update */
+ if (!pixman_region32_equal(&opaque, &ews->region.opaque))
+ {
+ pixman_region32_copy(&ews->region.opaque, &opaque);
+ ews->geometry.changed = EINA_TRUE;
+ }
+
+ /* tell pixman we are done with this temporary region */
+ pixman_region32_fini(&opaque);
+
+ /* clear any existing input region */
+ pixman_region32_fini(&ews->region.input);
+
+ /* initialize a new input region */
+ pixman_region32_init_rect(&ews->region.input, 0, 0,
+ ews->geometry.w, ews->geometry.h);
+
+ /* put pending input region into new input region */
+ pixman_region32_intersect(&ews->region.input, &ews->region.input,
+ &ews->pending.input);
+
+ /* check for valid input region */
+ if (pixman_region32_not_empty(&ews->region.input))
+ {
+ /* get the extent of the input region */
+ rects = pixman_region32_extents(&ews->region.input);
+
+ /* update the smart object's input region */
+ if (ews->obj)
+ e_surface_input_set(ews->obj, rects->x1, rects->y1,
+ (rects->x2 - rects->x1),
+ (rects->y2 - rects->y1));
+ }
+
+ /* put any pending frame callbacks into active list */
+ wl_list_insert_list(&ews->wl.frames, &ews->pending.frames);
+
+ /* clear list of pending frame callbacks */
+ wl_list_init(&ews->pending.frames);
+ /* TODO: schedule repaint ?? */
}
--
------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter