[PATCH] wl_resource: Add version field and getter/setter

alexl at redhat.com alexl at redhat.com
Thu May 23 11:28:29 PDT 2013


From: Alexander Larsson <alexl at redhat.com>

We create a private structure for extra data and store it in
a destroy notifier. In this way we can store the version
in a backwards compatible way.

This lets us track the actual version of a resource which
is generally the min of what the client requested and what
the server supports. This will let us avoid sending messages
the client doesn't support and to not handle requests the
server doesn't support.
---
 src/wayland-server.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/wayland-server.h |  6 ++++++
 2 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/src/wayland-server.c b/src/wayland-server.c
index a3d3887..c808f6a 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -102,6 +102,11 @@ struct wl_global {
 	struct wl_list link;
 };
 
+struct wl_resource_private {
+	struct wl_listener listener;
+	uint32_t version;
+};
+
 static int wl_debug = 0;
 
 static void
@@ -377,6 +382,14 @@ WL_EXPORT uint32_t
 wl_client_add_resource(struct wl_client *client,
 		       struct wl_resource *resource)
 {
+	struct wl_resource_private *priv;
+
+	priv = calloc(1, sizeof(struct wl_resource_private));
+	if (!priv) {
+		wl_resource_post_no_memory(resource);
+		return 0;
+	}
+
 	if (resource->object.id == 0) {
 		resource->object.id =
 			wl_map_insert_new(&client->objects,
@@ -387,12 +400,18 @@ wl_client_add_resource(struct wl_client *client,
 				       WL_DISPLAY_ERROR_INVALID_OBJECT,
 				       "invalid new id %d",
 				       resource->object.id);
+		free(priv);
 		return 0;
 	}
 
 	resource->client = client;
 	wl_signal_init(&resource->destroy_signal);
 
+	priv->listener.notify = (wl_notify_func_t)free;
+	wl_signal_add(&resource->destroy_signal, &priv->listener);
+
+	priv->version = 1;
+
 	return resource->object.id;
 }
 
@@ -895,6 +914,35 @@ wl_display_get_destroy_listener(struct wl_display *display,
 	return wl_signal_get(&display->destroy_signal, notify);
 }
 
+static struct wl_resource_private *
+wl_resource_get_priv (struct wl_resource *resource)
+{
+	/* The priv pointer is always the notify handler */
+	return (struct wl_resource_private *)resource->destroy_signal.listener_list.next;
+}
+
+WL_EXPORT void
+wl_resource_set_version(struct wl_resource *resource,
+			uint32_t version)
+{
+	struct wl_resource_private *priv = wl_resource_get_priv (resource);
+
+	priv->version = version;
+}
+
+WL_EXPORT uint32_t
+wl_resource_get_version(struct wl_resource *resource)
+{
+	struct wl_resource_private *priv = wl_resource_get_priv (resource);
+
+	return priv->version;
+}
+
+static void
+dummy_notify(struct wl_listener *listener, void *data)
+{
+}
+
 WL_EXPORT struct wl_resource *
 wl_client_add_object(struct wl_client *client,
 		     const struct wl_interface *interface,
@@ -902,8 +950,9 @@ wl_client_add_object(struct wl_client *client,
 		     uint32_t id, void *data)
 {
 	struct wl_resource *resource;
+	struct wl_resource_private *priv;
 
-	resource = malloc(sizeof *resource);
+	resource = malloc(sizeof *resource + sizeof (struct wl_resource_private));
 	if (resource == NULL) {
 		wl_resource_post_no_memory(client->display_resource);
 		return NULL;
@@ -913,6 +962,13 @@ wl_client_add_object(struct wl_client *client,
 	resource->client = client;
 	resource->destroy = (void *) free;
 
+	priv = (struct wl_resource_private *)(resource + 1);
+
+	priv->listener.notify = dummy_notify;
+	wl_signal_add(&resource->destroy_signal, &priv->listener);
+
+	priv->version = 1;
+
 	if (wl_map_insert_at(&client->objects, resource->object.id, resource) < 0) {
 		wl_resource_post_error(client->display_resource,
 				       WL_DISPLAY_ERROR_INVALID_OBJECT,
diff --git a/src/wayland-server.h b/src/wayland-server.h
index a9cf544..6beb0dd 100644
--- a/src/wayland-server.h
+++ b/src/wayland-server.h
@@ -135,6 +135,12 @@ wl_client_new_object(struct wl_client *client,
 struct wl_resource *
 wl_client_get_object(struct wl_client *client, uint32_t id);
 
+void
+wl_resource_set_version(struct wl_resource *resource,
+			uint32_t version);
+uint32_t
+wl_resource_get_version(struct wl_resource *resource);
+
 struct wl_listener {
 	struct wl_list link;
 	wl_notify_func_t notify;
-- 
1.8.1.4



More information about the wayland-devel mailing list