<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>