[PATCH weston 4/5] compositor: Track pointer image protocol change

Ander Conselvan de Oliveira ander.conselvan.de.oliveira at intel.com
Fri Jun 15 07:27:35 PDT 2012


The request pointer.attach was replaced with pointer.set_cursor that
lets a client set the cursor surface for a given pointer.
---
 clients/simple-egl.c     |    2 +-
 clients/window.c         |   13 +++++-
 src/compositor-wayland.c |    2 +-
 src/compositor.c         |  112 +++++++++++++++++++++++++++++++++++-----------
 src/compositor.h         |    1 +
 5 files changed, 99 insertions(+), 31 deletions(-)

diff --git a/clients/simple-egl.c b/clients/simple-egl.c
index 4cb5bc7..f7a9f74 100644
--- a/clients/simple-egl.c
+++ b/clients/simple-egl.c
@@ -362,7 +362,7 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
 	struct display *display = data;
 
 	if (display->window->fullscreen)
-		wl_pointer_attach(pointer, serial, NULL, 0, 0);
+		wl_pointer_set_cursor(pointer, serial, NULL, 0, 0);
 }
 
 static void
diff --git a/clients/window.c b/clients/window.c
index 53022aa..57443d9 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -189,6 +189,7 @@ struct input {
 	struct window *pointer_focus;
 	struct window *keyboard_focus;
 	int current_cursor;
+	struct wl_surface *pointer_surface;
 	uint32_t modifiers;
 	uint32_t pointer_enter_serial;
 	float sx, sy;
@@ -2295,8 +2296,12 @@ input_set_pointer_image_index(struct input *input, int pointer, int index)
 		return;
 
 	input->current_cursor = pointer;
-	wl_pointer_attach(input->pointer, input->pointer_enter_serial,
-			  buffer, image->hotspot_x, image->hotspot_y);
+	wl_pointer_set_cursor(input->pointer, input->display->serial,
+			      input->pointer_surface,
+			      image->hotspot_x, image->hotspot_y);
+	wl_surface_attach(input->pointer_surface, buffer, 0, 0);
+	wl_surface_damage(input->pointer_surface, 0, 0,
+			  image->width, image->height);
 }
 
 void
@@ -3168,6 +3173,8 @@ display_add_input(struct display *d, uint32_t id)
 						       input->seat);
 	wl_data_device_add_listener(input->data_device, &data_device_listener,
 				    input);
+
+	input->pointer_surface = wl_compositor_create_surface(d->compositor);
 }
 
 static void
@@ -3190,6 +3197,8 @@ input_destroy(struct input *input)
 	wl_data_device_destroy(input->data_device);
 	fini_xkb(input);
 
+	wl_surface_destroy(input->pointer_surface);
+
 	wl_list_remove(&input->link);
 	wl_seat_destroy(input->seat);
 	free(input);
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index f09463e..d498e84 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -505,7 +505,7 @@ input_handle_pointer_enter(void *data, struct wl_pointer *pointer,
 
 	output = wl_surface_get_user_data(surface);
 	notify_pointer_focus(&c->base.seat->seat, &output->base, x, y);
-	wl_pointer_attach(input->pointer, serial, NULL, 0, 0);
+	wl_pointer_set_cursor(input->pointer, serial, NULL, 0, 0);
 }
 
 static void
diff --git a/src/compositor.c b/src/compositor.c
index 726e15f..44f5b11 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -2064,13 +2064,59 @@ notify_touch(struct wl_seat *seat, uint32_t time, int touch_id,
 }
 
 static void
-pointer_attach(struct wl_client *client, struct wl_resource *resource,
-	       uint32_t serial, struct wl_resource *buffer_resource,
-	       int32_t x, int32_t y)
+pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
+{
+	struct weston_seat *seat = container_of(listener, struct weston_seat,
+						sprite_destroy_listener);
+
+	seat->sprite = NULL;
+}
+
+static void
+pointer_cursor_surface_configure(struct weston_surface *es,
+				 int32_t dx, int32_t dy)
+{
+	struct weston_seat *seat = es->private;
+	int x, y;
+
+	assert(es == seat->sprite);
+
+	seat->hotspot_x -= dx;
+	seat->hotspot_y -= dy;
+
+	x = wl_fixed_to_int(seat->seat.pointer->x) - seat->hotspot_x;
+	y = wl_fixed_to_int(seat->seat.pointer->y) - seat->hotspot_y;
+
+	weston_surface_configure(seat->sprite, x, y,
+				 es->buffer->width, es->buffer->height);
+
+	if (!weston_surface_is_mapped(es)) {
+		wl_list_insert(&es->compositor->cursor_layer.surface_list,
+			       &es->layer_link);
+		weston_surface_assign_output(es);
+		empty_region(&es->input);
+	}
+}
+
+static void
+pointer_unmap_sprite(struct weston_seat *seat)
+{
+	if (weston_surface_is_mapped(seat->sprite))
+		weston_surface_unmap(seat->sprite);
+
+	wl_list_remove(&seat->sprite_destroy_listener.link);
+	seat->sprite->configure = NULL;
+	seat->sprite->private = NULL;
+	seat->sprite = NULL;
+}
+
+static void
+pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
+		   uint32_t serial, struct wl_resource *surface_resource,
+		   int32_t x, int32_t y)
 {
 	struct weston_seat *seat = resource->data;
-	struct weston_compositor *compositor = seat->compositor;
-	struct wl_buffer *buffer = NULL;
+	struct weston_surface *surface = NULL;
 
 	if (serial < seat->seat.pointer->focus_serial)
 		return;
@@ -2079,35 +2125,41 @@ pointer_attach(struct wl_client *client, struct wl_resource *resource,
 	if (seat->seat.pointer->focus->resource.client != client)
 		return;
 
-	if (buffer_resource)
-		buffer = buffer_resource->data;
+	if (surface_resource)
+		surface = container_of(surface_resource->data,
+				       struct weston_surface, surface);
 
-	weston_surface_attach(&seat->sprite->surface, buffer);
-	empty_region(&seat->sprite->input);
+	if (surface && surface != seat->sprite && surface->configure) {
+		wl_resource_post_error(&surface->surface.resource,
+				       WL_DISPLAY_ERROR_INVALID_OBJECT,
+				       "surface->configure already set");
+		return;
+	}
 
-	if (!buffer)
+	if (seat->sprite)
+		pointer_unmap_sprite(seat);
+
+	if (!surface)
 		return;
 
-	if (!weston_surface_is_mapped(seat->sprite)) {
-		wl_list_insert(&compositor->cursor_layer.surface_list,
-			       &seat->sprite->layer_link);
-		weston_surface_assign_output(seat->sprite);
-	}
+	wl_signal_add(&surface->surface.resource.destroy_signal,
+		      &seat->sprite_destroy_listener);
 
+	surface->configure = pointer_cursor_surface_configure;
+	surface->private = seat;
+	empty_region(&surface->input);
 
+	seat->sprite = surface;
 	seat->hotspot_x = x;
 	seat->hotspot_y = y;
-	weston_surface_configure(seat->sprite,
-				 wl_fixed_to_int(seat->seat.pointer->x) - x,
-				 wl_fixed_to_int(seat->seat.pointer->y) - y,
-				 buffer->width, buffer->height);
 
-	surface_damage(NULL, &seat->sprite->surface.resource,
-		       0, 0, buffer->width, buffer->height);
+	weston_surface_set_position(surface,
+				    wl_fixed_to_int(seat->seat.pointer->x) - x,
+				    wl_fixed_to_int(seat->seat.pointer->y) - y);
 }
 
 static const struct wl_pointer_interface pointer_interface = {
-	pointer_attach,
+	pointer_set_cursor
 };
 
 static void
@@ -2428,8 +2480,8 @@ weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec)
 	wl_display_add_global(ec->wl_display, &wl_seat_interface, seat,
 			      bind_seat);
 
-	seat->sprite = weston_surface_create(ec);
-	seat->sprite->surface.resource.data = seat->sprite;
+	seat->sprite = NULL;
+	seat->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
 
 	seat->compositor = ec;
 	seat->hotspot_x = 16;
@@ -2456,7 +2508,7 @@ weston_seat_release(struct weston_seat *seat)
 	/* The global object is destroyed at wl_display_destroy() time. */
 
 	if (seat->sprite)
-		destroy_surface(&seat->sprite->surface.resource);
+		pointer_unmap_sprite(seat);
 
 	if (seat->xkb_state.state != NULL)
 		xkb_state_unref(seat->xkb_state.state);
@@ -2512,12 +2564,18 @@ device_release_drag_surface(struct weston_seat *seat)
 static void
 device_map_drag_surface(struct weston_seat *seat)
 {
+	struct wl_list *list;
+
 	if (weston_surface_is_mapped(seat->drag_surface) ||
 	    !seat->drag_surface->buffer)
 		return;
 
-	wl_list_insert(&seat->sprite->layer_link,
-		       &seat->drag_surface->layer_link);
+	if (seat->sprite && weston_surface_is_mapped(seat->sprite))
+		list = &seat->sprite->layer_link;
+	else
+		list = &seat->compositor->cursor_layer.surface_list;
+
+	wl_list_insert(list, &seat->drag_surface->layer_link);
 	weston_surface_assign_output(seat->drag_surface);
 	empty_region(&seat->drag_surface->input);
 }
diff --git a/src/compositor.h b/src/compositor.h
index b5136fc..4147811 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -207,6 +207,7 @@ struct weston_seat {
 
 	struct weston_compositor *compositor;
 	struct weston_surface *sprite;
+	struct wl_listener sprite_destroy_listener;
 	struct weston_surface *drag_surface;
 	struct wl_listener drag_surface_destroy_listener;
 	int32_t hotspot_x, hotspot_y;
-- 
1.7.4.1



More information about the wayland-devel mailing list