[PATCH 3/3 v2] Send surface enter/leave events

cdahlin at redhat.com cdahlin at redhat.com
Thu Apr 19 19:50:09 PDT 2012


From: Casey Dahlin <cdahlin at redhat.com>

These new protocol events allow us to tell which outputs a surface is on, and
potentially update where we allocate our buffers from.

Signed-off-by: Casey Dahlin <cdahlin at redhat.com>
---
 src/compositor.c |   69 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/compositor.h |    7 +++++
 2 files changed, 75 insertions(+), 1 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 798b1e1..5d09042 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1126,13 +1126,70 @@ find_resource_for_client(struct wl_list *list, struct wl_client *client)
         return NULL;
 }
 
+static struct weston_output *
+get_output_by_id(struct weston_compositor *compositor, uint32_t id)
+{
+	struct weston_output *ret;
+
+        wl_list_for_each(ret, &compositor->output_list, link) {
+		if (ret->id == id)
+			return ret;
+	}
+
+	return NULL;
+}
+
+static inline void
+weston_surface_send_leave(struct weston_surface *es, uint32_t output_id)
+{
+	struct wl_resource *output_resource;
+	struct weston_output *output = get_output_by_id(es->compositor, output_id);
+
+	output_resource =
+		find_resource_for_client(&output->resource_list,
+					 es->surface.resource.client);
+
+	wl_surface_send_leave(&es->surface.resource, output_resource);
+}
+
+static inline void
+weston_surface_send_enter(struct weston_surface *es, uint32_t output_id)
+{
+	struct wl_resource *output_resource;
+	struct weston_output *output = get_output_by_id(es->compositor, output_id);
+
+	output_resource =
+		find_resource_for_client(&output->resource_list,
+					 es->surface.resource.client);
+
+	wl_surface_send_enter(&es->surface.resource, output_resource);
+}
+
+static void
+weston_surface_update_output_mask(struct weston_surface *es, uint32_t mask)
+{
+	uint32_t different = es->output_mask ^ mask;
+	uint32_t entered = mask & different;
+	uint32_t left = es->output_mask & different;
+	uint32_t i;
+
+	es->output_mask = mask;
+
+	for (i = 0; (1 << i) <= different; i++) {
+		if (entered & i)
+			weston_surface_send_enter(es, i);
+		if (left & i)
+			weston_surface_send_leave(es, i);
+	}
+}
+
 WL_EXPORT void
 weston_surface_assign_output(struct weston_surface *es)
 {
 	struct weston_compositor *ec = es->compositor;
 	struct weston_output *output, *new_output;
 	pixman_region32_t region;
-	uint32_t max, area;
+	uint32_t max, area, mask;
 	pixman_box32_t *e;
 
 	weston_surface_update_transform(es);
@@ -1147,6 +1204,11 @@ weston_surface_assign_output(struct weston_surface *es)
 		e = pixman_region32_extents(&region);
 		area = (e->x2 - e->x1) * (e->y2 - e->y1);
 
+		if (! area)
+			continue;
+
+		mask |= 1 << output->id;
+
 		if (area >= max) {
 			new_output = output;
 			max = area;
@@ -1155,6 +1217,8 @@ weston_surface_assign_output(struct weston_surface *es)
 	pixman_region32_fini(&region);
 
 	es->output = new_output;
+	weston_surface_update_output_mask(es, mask);
+
 	if (!wl_list_empty(&es->frame_callback_list)) {
 		wl_list_insert_list(new_output->frame_callback_list.prev,
 				    &es->frame_callback_list);
@@ -2126,6 +2190,8 @@ bind_output(struct wl_client *client,
 	resource = wl_client_add_object(client,
 					&wl_output_interface, NULL, id, data);
 
+	wl_list_insert(&output->resource_list, &resource->link);
+
 	wl_output_send_geometry(resource,
 				output->x,
 				output->y,
@@ -2341,6 +2407,7 @@ weston_output_init(struct weston_output *output, struct weston_compositor *c,
 	weston_output_damage(output);
 
 	wl_list_init(&output->frame_callback_list);
+	wl_list_init(&output->resource_list);
 
 	output_allocate_id(output);
 
diff --git a/src/compositor.h b/src/compositor.h
index 183c4e7..ec581d8 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -76,6 +76,7 @@ struct weston_output {
 	uint32_t id;
 
 	struct wl_list link;
+	struct wl_list resource_list;
 	struct wl_global *global;
 	struct weston_compositor *compositor;
 	struct weston_matrix matrix;
@@ -331,6 +332,12 @@ struct weston_surface {
 	 */
 	struct weston_output *output;
 
+	/*
+	 * A more complete representation of all outputs this surface is
+	 * displayed on.
+	 */
+	uint32_t output_mask;
+
 	struct wl_list frame_callback_list;
 
 	EGLImageKHR image;
-- 
1.7.7.6



More information about the wayland-devel mailing list