[RFC weston 04/12] data-device: Change resources in wl_data_offer and wl_data_source to pointers.

Jason Ekstrand jason at jlekstrand.net
Fri Jun 14 08:07:55 PDT 2013


Because of its links to selection.c and xwayland, a destroy_signal field
was also added to wl_data_source.  Before selection.c and xwayland were
manually initializing the resource.destroy_signal field so that it could be
used without a valid resource.

Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
---

Here I replaced the previous resource list mechanism with one that is built
into wayland as of my wayland patch.  I figured that since putting
resources in lists was so common (especially for globals) it made sense to
add that to libwayland instead of repeating it all over weston.  Also,
because the structure is now opaque you cannot simply iterate over a list
of them using wl_list_for_each so making the search function part of
libwayland made it simpler and faster.  I am open to moving this back to
weston, but I don't see putting it in libwayland as a problem.

 src/clipboard.c          |   8 ++--
 src/compositor.h         |   5 ++-
 src/data-device.c        | 100 +++++++++++++++++++++--------------------------
 src/xwayland/selection.c |   3 +-
 4 files changed, 53 insertions(+), 63 deletions(-)

diff --git a/src/clipboard.c b/src/clipboard.c
index eb0b230..21a7e69 100644
--- a/src/clipboard.c
+++ b/src/clipboard.c
@@ -60,8 +60,8 @@ clipboard_source_unref(struct clipboard_source *source)
 
 	if (source->event_source)
 		wl_event_source_remove(source->event_source);
-	wl_signal_emit(&source->base.resource.destroy_signal,
-		       &source->base.resource);
+	wl_signal_emit(&source->base.destroy_signal,
+		       &source->base);
 	s = source->base.mime_types.data;
 	free(*s);
 	wl_array_release(&source->base.mime_types);
@@ -136,11 +136,11 @@ clipboard_source_create(struct clipboard *clipboard,
 	source = malloc(sizeof *source);
 	wl_array_init(&source->contents);
 	wl_array_init(&source->base.mime_types);
+	source->base.resource = NULL;
 	source->base.accept = clipboard_source_accept;
 	source->base.send = clipboard_source_send;
 	source->base.cancel = clipboard_source_cancel;
-	source->base.resource.data = &source->base;
-	wl_signal_init(&source->base.resource.destroy_signal);
+	wl_signal_init(&source->base.destroy_signal);
 	source->refcount = 1;
 	source->clipboard = clipboard;
 	source->serial = serial;
diff --git a/src/compositor.h b/src/compositor.h
index c87d9f1..36875a6 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -261,13 +261,14 @@ struct weston_touch_grab {
 };
 
 struct wl_data_offer {
-	struct wl_resource resource;
+	struct wl_resource *resource;
 	struct wl_data_source *source;
 	struct wl_listener source_destroy_listener;
 };
 
 struct wl_data_source {
-	struct wl_resource resource;
+	struct wl_resource *resource;
+	struct wl_signal destroy_signal;
 	struct wl_array mime_types;
 
 	void (*accept)(struct wl_data_source *source,
diff --git a/src/data-device.c b/src/data-device.c
index 1735620..91c18df 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -51,7 +51,7 @@ static void
 data_offer_accept(struct wl_client *client, struct wl_resource *resource,
 		  uint32_t serial, const char *mime_type)
 {
-	struct wl_data_offer *offer = resource->data;
+	struct wl_data_offer *offer = wl_resource_get_user_data(resource);
 
 	/* FIXME: Check that client is currently focused by the input
 	 * device that is currently dragging this data source.  Should
@@ -65,7 +65,7 @@ static void
 data_offer_receive(struct wl_client *client, struct wl_resource *resource,
 		   const char *mime_type, int32_t fd)
 {
-	struct wl_data_offer *offer = resource->data;
+	struct wl_data_offer *offer = wl_resource_get_user_data(resource);
 
 	if (offer->source)
 		offer->source->send(offer->source, mime_type, fd);
@@ -88,7 +88,7 @@ static const struct wl_data_offer_interface data_offer_interface = {
 static void
 destroy_data_offer(struct wl_resource *resource)
 {
-	struct wl_data_offer *offer = resource->data;
+	struct wl_data_offer *offer = wl_resource_get_user_data(resource);
 
 	if (offer->source)
 		wl_list_remove(&offer->source_destroy_listener.link);
@@ -117,23 +117,22 @@ wl_data_source_send_offer(struct wl_data_source *source,
 	if (offer == NULL)
 		return NULL;
 
-	wl_resource_init(&offer->resource, &wl_data_offer_interface,
-			 &data_offer_interface, 0, offer);
-	offer->resource.destroy = destroy_data_offer;
+	offer->resource = wl_client_new_object(wl_resource_get_client(target),
+					       &wl_data_offer_interface,
+					       &data_offer_interface, offer);
+	wl_resource_set_destructor(offer->resource, destroy_data_offer);
 
 	offer->source = source;
 	offer->source_destroy_listener.notify = destroy_offer_data_source;
-	wl_signal_add(&source->resource.destroy_signal,
+	wl_signal_add(&source->destroy_signal,
 		      &offer->source_destroy_listener);
 
-	wl_client_add_resource(target->client, &offer->resource);
-
-	wl_data_device_send_data_offer(target, &offer->resource);
+	wl_data_device_send_data_offer(target, offer->resource);
 
 	wl_array_for_each(p, &source->mime_types)
-		wl_data_offer_send_offer(&offer->resource, *p);
+		wl_data_offer_send_offer(offer->resource, *p);
 
-	return &offer->resource;
+	return offer->resource;
 }
 
 static void
@@ -141,7 +140,7 @@ data_source_offer(struct wl_client *client,
 		  struct wl_resource *resource,
 		  const char *type)
 {
-	struct wl_data_source *source = resource->data;
+	struct wl_data_source *source = wl_resource_get_user_data(resource);
 	char **p;
 
 	p = wl_array_add(&source->mime_types, sizeof *p);
@@ -162,19 +161,6 @@ static struct wl_data_source_interface data_source_interface = {
 	data_source_destroy
 };
 
-static struct wl_resource *
-find_resource(struct wl_list *list, struct wl_client *client)
-{
-	struct wl_resource *r;
-
-	wl_list_for_each(r, list, link) {
-		if (r->client == client)
-			return r;
-	}
-
-	return NULL;
-}
-
 static void
 drag_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
 {
@@ -234,12 +220,12 @@ weston_drag_set_focus(struct weston_drag *drag, struct weston_surface *surface,
 	    wl_resource_get_client(surface->resource) != drag->client)
 		return;
 
-	resource = find_resource(&pointer->seat->drag_resource_list,
-				 wl_resource_get_client(surface->resource));
+	resource = wl_resource_find_for_client(&pointer->seat->drag_resource_list,
+					       wl_resource_get_client(surface->resource));
 	if (!resource)
 		return;
 
-	display = wl_client_get_display(resource->client);
+	display = wl_client_get_display(wl_resource_get_client(resource));
 	serial = wl_display_next_serial(display);
 
 	if (drag->data_source)
@@ -250,7 +236,7 @@ weston_drag_set_focus(struct weston_drag *drag, struct weston_surface *surface,
 
 	drag->focus = surface;
 	drag->focus_listener.notify = destroy_drag_focus;
-	wl_signal_add(&resource->destroy_signal, &drag->focus_listener);
+	wl_resource_add_destroy_listener(resource, &drag->focus_listener);
 	drag->focus_resource = resource;
 }
 
@@ -397,10 +383,10 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
 	drag->client = client;
 
 	if (source_resource) {
-		drag->data_source = source_resource->data;
+		drag->data_source = wl_resource_get_user_data(source_resource);
 		drag->data_source_listener.notify = destroy_data_device_source;
-		wl_signal_add(&source_resource->destroy_signal,
-			      &drag->data_source_listener);
+		wl_resource_add_destroy_listener(source_resource,
+						 &drag->data_source_listener);
 	}
 
 	if (icon) {
@@ -431,8 +417,8 @@ destroy_selection_data_source(struct wl_listener *listener, void *data)
 	if (seat->keyboard)
 		focus = seat->keyboard->focus_resource;
 	if (focus) {
-		data_device = find_resource(&seat->drag_resource_list,
-					    focus->client);
+		data_device = wl_resource_find_for_client(&seat->drag_resource_list,
+							  wl_resource_get_client(focus));
 		if (data_device)
 			wl_data_device_send_selection(data_device, NULL);
 	}
@@ -463,8 +449,8 @@ weston_seat_set_selection(struct weston_seat *seat,
 	if (seat->keyboard)
 		focus = seat->keyboard->focus_resource;
 	if (focus) {
-		data_device = find_resource(&seat->drag_resource_list,
-					    focus->client);
+		data_device = wl_resource_find_for_client(&seat->drag_resource_list,
+							  wl_resource_get_client(focus));
 		if (data_device && source) {
 			offer = wl_data_source_send_offer(seat->selection_data_source,
 							  data_device);
@@ -479,7 +465,7 @@ weston_seat_set_selection(struct weston_seat *seat,
 	if (source) {
 		seat->selection_data_source_listener.notify =
 			destroy_selection_data_source;
-		wl_signal_add(&source->resource.destroy_signal,
+		wl_signal_add(&source->destroy_signal,
 			      &seat->selection_data_source_listener);
 	}
 }
@@ -493,7 +479,8 @@ data_device_set_selection(struct wl_client *client,
 		return;
 
 	/* FIXME: Store serial and check against incoming serial here. */
-	weston_seat_set_selection(resource->data, wl_resource_get_user_data(source_resource),
+	weston_seat_set_selection(wl_resource_get_user_data(resource),
+				  wl_resource_get_user_data(source_resource),
 				  serial);
 }
 
@@ -505,37 +492,38 @@ static const struct wl_data_device_interface data_device_interface = {
 static void
 destroy_data_source(struct wl_resource *resource)
 {
-	struct wl_data_source *source =
-		container_of(resource, struct wl_data_source, resource);
+	struct wl_data_source *source = wl_resource_get_user_data(resource);
 	char **p;
 
+	wl_signal_emit(&source->destroy_signal, source);
+
 	wl_array_for_each(p, &source->mime_types)
 		free(*p);
 
 	wl_array_release(&source->mime_types);
 
-	source->resource.object.id = 0;
+	source->resource = NULL;
 }
 
 static void
 client_source_accept(struct wl_data_source *source,
 		     uint32_t time, const char *mime_type)
 {
-	wl_data_source_send_target(&source->resource, mime_type);
+	wl_data_source_send_target(source->resource, mime_type);
 }
 
 static void
 client_source_send(struct wl_data_source *source,
 		   const char *mime_type, int32_t fd)
 {
-	wl_data_source_send_send(&source->resource, mime_type, fd);
+	wl_data_source_send_send(source->resource, mime_type, fd);
 	close(fd);
 }
 
 static void
 client_source_cancel(struct wl_data_source *source)
 {
-	wl_data_source_send_cancelled(&source->resource);
+	wl_data_source_send_cancelled(source->resource);
 }
 
 static void
@@ -550,21 +538,23 @@ create_data_source(struct wl_client *client,
 		return;
 	}
 
-	wl_resource_init(&source->resource, &wl_data_source_interface,
-			 &data_source_interface, id, source);
-	source->resource.destroy = destroy_data_source;
-
+	wl_signal_init(&source->destroy_signal);
 	source->accept = client_source_accept;
 	source->send = client_source_send;
 	source->cancel = client_source_cancel;
 
 	wl_array_init(&source->mime_types);
-	wl_client_add_resource(client, &source->resource);
+
+	source->resource = wl_client_add_object(client,
+						&wl_data_source_interface,
+						&data_source_interface,
+						id, source);
+	wl_resource_set_destructor(source->resource, destroy_data_source);
 }
 
 static void unbind_data_device(struct wl_resource *resource)
 {
-	wl_list_remove(&resource->link);
+	wl_list_remove(wl_resource_get_link(resource));
 	free(resource);
 }
 
@@ -580,8 +570,8 @@ get_data_device(struct wl_client *client,
 					&data_device_interface, id,
 					seat);
 
-	wl_list_insert(&seat->drag_resource_list, &resource->link);
-	resource->destroy = unbind_data_device;
+	wl_list_insert(&seat->drag_resource_list, wl_resource_get_link(resource));
+	wl_resource_set_destructor(resource, unbind_data_device);
 }
 
 static const struct wl_data_device_manager_interface manager_interface = {
@@ -610,8 +600,8 @@ wl_data_device_set_keyboard_focus(struct weston_seat *seat)
 	if (!focus)
 		return;
 
-	data_device = find_resource(&seat->drag_resource_list,
-				    focus->client);
+	data_device = wl_resource_find_for_client(&seat->drag_resource_list,
+						  wl_resource_get_client(focus));
 	if (!data_device)
 		return;
 
diff --git a/src/xwayland/selection.c b/src/xwayland/selection.c
index 66cb5fe..6c7cfc0 100644
--- a/src/xwayland/selection.c
+++ b/src/xwayland/selection.c
@@ -177,11 +177,10 @@ weston_wm_get_selection_targets(struct weston_wm *wm)
 	if (source == NULL)
 		return;
 
-	wl_signal_init(&source->base.resource.destroy_signal);
+	wl_signal_init(&source->base.destroy_signal);
 	source->base.accept = data_source_accept;
 	source->base.send = data_source_send;
 	source->base.cancel = data_source_cancel;
-	source->base.resource.data = source;
 	source->wm = wm;
 
 	wl_array_init(&source->base.mime_types);
-- 
1.8.1.4



More information about the wayland-devel mailing list