<div dir="ltr"><div>Alex,<br></div>Really, this looks like a pretty clean solution.  I've spent a fair amount of time banging around trying to extend wl_resource and this is better than anything I ever came up with.  I only have the one comment (already mentioned on IRC but repeated here for the sake of the list).<br>
<div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 23, 2013 at 1:28 PM,  <span dir="ltr"><<a href="mailto:alexl@redhat.com" target="_blank">alexl@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
From: Alexander Larsson <<a href="mailto:alexl@redhat.com">alexl@redhat.com</a>><br>
<br>
We create a private structure for extra data and store it in<br>
a destroy notifier. In this way we can store the version<br>
in a backwards compatible way.<br>
<div class="im"><br>
This lets us track the actual version of a resource which<br>
is generally the min of what the client requested and what<br>
the server supports. This will let us avoid sending messages<br>
the client doesn't support and to not handle requests the<br>
server doesn't support.<br>
---<br>
</div> src/wayland-server.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++-<br>
<div class="im"> src/wayland-server.h |  6 ++++++<br>
 2 files changed, 63 insertions(+), 1 deletion(-)<br>
<br>
</div>diff --git a/src/wayland-server.c b/src/wayland-server.c<br>
index a3d3887..c808f6a 100644<br>
--- a/src/wayland-server.c<br>
+++ b/src/wayland-server.c<br>
@@ -102,6 +102,11 @@ struct wl_global {<br>
        struct wl_list link;<br>
 };<br>
<br>
+struct wl_resource_private {<br>
+       struct wl_listener listener;<br>
+       uint32_t version;<br>
+};<br>
+<br>
 static int wl_debug = 0;<br>
<br>
 static void<br>
@@ -377,6 +382,14 @@ WL_EXPORT uint32_t<br>
 wl_client_add_resource(struct wl_client *client,<br>
                       struct wl_resource *resource)<br>
 {<br>
+       struct wl_resource_private *priv;<br>
+<br>
+       priv = calloc(1, sizeof(struct wl_resource_private));<br>
+       if (!priv) {<br>
+               wl_resource_post_no_memory(resource);<br>
+               return 0;<br>
+       }<br>
+<br>
        if (resource-><a href="http://object.id" target="_blank">object.id</a> == 0) {<br>
                resource-><a href="http://object.id" target="_blank">object.id</a> =<br>
                        wl_map_insert_new(&client->objects,<br>
@@ -387,12 +400,18 @@ wl_client_add_resource(struct wl_client *client,<br>
                                       WL_DISPLAY_ERROR_INVALID_OBJECT,<br>
                                       "invalid new id %d",<br>
                                       resource-><a href="http://object.id" target="_blank">object.id</a>);<br>
+               free(priv);<br>
                return 0;<br>
        }<br>
<br>
        resource->client = client;<br>
        wl_signal_init(&resource->destroy_signal);<br>
<br>
+       priv->listener.notify = (wl_notify_func_t)free;<br>
+       wl_signal_add(&resource->destroy_signal, &priv->listener);<br>
+<br>
+       priv->version = 1;<br>
+<br>
        return resource-><a href="http://object.id" target="_blank">object.id</a>;<br>
 }<br>
<br>
@@ -895,6 +914,35 @@ wl_display_get_destroy_listener(struct wl_display *display,<br>
        return wl_signal_get(&display->destroy_signal, notify);<br>
 }<br>
<br>
+static struct wl_resource_private *<br>
+wl_resource_get_priv (struct wl_resource *resource)<br>
+{<br>
+       /* The priv pointer is always the notify handler */<br>
+       return (struct wl_resource_private *)resource->destroy_signal.listener_list.next;<br>
+}<br></blockquote><div><br></div><div>wl_signal_get might be better here.  It's more robust in (somewhat odd) case the user code decides to manually put a listener at the beginning.  It's also more readable and almost just as fast (different by an if).<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">+<br>
+WL_EXPORT void<br>
+wl_resource_set_version(struct wl_resource *resource,<br>
+                       uint32_t version)<br>
+{<br>
</div>+       struct wl_resource_private *priv = wl_resource_get_priv (resource);<br>
+<br>
+       priv->version = version;<br>
<div class="im">+}<br>
+<br>
+WL_EXPORT uint32_t<br>
+wl_resource_get_version(struct wl_resource *resource)<br>
+{<br>
</div>+       struct wl_resource_private *priv = wl_resource_get_priv (resource);<br>
+<br>
+       return priv->version;<br>
+}<br>
+<br>
+static void<br>
+dummy_notify(struct wl_listener *listener, void *data)<br>
<div class="im">+{<br>
+}<br>
+<br>
 WL_EXPORT struct wl_resource *<br>
 wl_client_add_object(struct wl_client *client,<br>
                     const struct wl_interface *interface,<br>
</div>@@ -902,8 +950,9 @@ wl_client_add_object(struct wl_client *client,<br>
                     uint32_t id, void *data)<br>
 {<br>
        struct wl_resource *resource;<br>
+       struct wl_resource_private *priv;<br>
<br>
-       resource = malloc(sizeof *resource);<br>
+       resource = malloc(sizeof *resource + sizeof (struct wl_resource_private));<br>
        if (resource == NULL) {<br>
                wl_resource_post_no_memory(client->display_resource);<br>
                return NULL;<br>
@@ -913,6 +962,13 @@ wl_client_add_object(struct wl_client *client,<br>
<div class="im">        resource->client = client;<br>
        resource->destroy = (void *) free;<br>
<br>
</div>+       priv = (struct wl_resource_private *)(resource + 1);<br>
+<br>
+       priv->listener.notify = dummy_notify;<br>
+       wl_signal_add(&resource->destroy_signal, &priv->listener);<br>
+<br>
+       priv->version = 1;<br>
<div class="im">+<br>
        if (wl_map_insert_at(&client->objects, resource-><a href="http://object.id" target="_blank">object.id</a>, resource) < 0) {<br>
                wl_resource_post_error(client->display_resource,<br>
</div>                                       WL_DISPLAY_ERROR_INVALID_OBJECT,<br>
diff --git a/src/wayland-server.h b/src/wayland-server.h<br>
index a9cf544..6beb0dd 100644<br>
<div class="HOEnZb"><div class="h5">--- a/src/wayland-server.h<br>
+++ b/src/wayland-server.h<br>
@@ -135,6 +135,12 @@ wl_client_new_object(struct wl_client *client,<br>
 struct wl_resource *<br>
 wl_client_get_object(struct wl_client *client, uint32_t id);<br>
<br>
+void<br>
+wl_resource_set_version(struct wl_resource *resource,<br>
+                       uint32_t version);<br>
+uint32_t<br>
+wl_resource_get_version(struct wl_resource *resource);<br>
+<br>
 struct wl_listener {<br>
        struct wl_list link;<br>
        wl_notify_func_t notify;<br>
--<br>
1.8.1.4<br>
<br>
_______________________________________________<br>
wayland-devel mailing list<br>
<a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/wayland-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br>
</div></div></blockquote></div><br></div><div class="gmail_extra">Thanks,<br></div><div class="gmail_extra">--Jason Ekstrand<br></div></div>