[PATCH wayland 4/4] Add support for proper global versioning.

Jason Ekstrand jason at jlekstrand.net
Thu Jun 27 18:09:21 PDT 2013


In previous versions of libwayland the version of the global that was
advertised to the client was taken from the wl_interface object.  This has
two problems.  First it makes it impossible for a compositor to only
support a lower version than the version against which it was built.
Second, since the wl_interface objects are linked directly into the
library, the compositor will advertise the global version based on the
version of the library not the compositor.  This commit fixes both of these
problems.

Because existing EGL implementations advertise globals, a new
wl_display_add_versioned_global function was added instead of simply adding
an argument to wl_display_add_global.

Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
---
 src/wayland-server.c | 24 ++++++++++++++++++++++--
 src/wayland-server.h |  4 ++++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/wayland-server.c b/src/wayland-server.c
index 67d52bd..bd323e4 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -100,6 +100,7 @@ struct wl_global {
 	void *data;
 	wl_global_bind_func_t bind;
 	struct wl_list link;
+	int version;
 };
 
 struct wl_resource {
@@ -662,7 +663,7 @@ display_get_registry(struct wl_client *client,
 				       WL_REGISTRY_GLOBAL,
 				       global->name,
 				       global->interface->name,
-				       global->interface->version);
+				       global->version);
 }
 
 static const struct wl_display_interface display_interface = {
@@ -760,9 +761,27 @@ wl_display_add_global(struct wl_display *display,
 		      const struct wl_interface *interface,
 		      void *data, wl_global_bind_func_t bind)
 {
+	return wl_display_add_versioned_global(display, interface,
+					       interface->version,
+					       data, bind);
+}
+
+WL_EXPORT struct wl_global *
+wl_display_add_versioned_global(struct wl_display *display,
+				const struct wl_interface *interface,
+				int version, void *data,
+				wl_global_bind_func_t bind)
+{
 	struct wl_global *global;
 	struct wl_resource *resource;
 
+	if (version > interface->version) {
+		wl_log("warning: version %d of %s not supported by this "
+		       "libwayland version; using version %d.",
+		       version, interface->name, interface->version);
+		version = interface->version;
+	}
+
 	global = malloc(sizeof *global);
 	if (global == NULL)
 		return NULL;
@@ -771,6 +790,7 @@ wl_display_add_global(struct wl_display *display,
 	global->interface = interface;
 	global->data = data;
 	global->bind = bind;
+	global->version = version;
 	wl_list_insert(display->global_list.prev, &global->link);
 
 	wl_list_for_each(resource, &display->registry_resource_list, link)
@@ -778,7 +798,7 @@ wl_display_add_global(struct wl_display *display,
 				       WL_REGISTRY_GLOBAL,
 				       global->name,
 				       global->interface->name,
-				       global->interface->version);
+				       global->version);
 
 	return global;
 }
diff --git a/src/wayland-server.h b/src/wayland-server.h
index 8924128..4c8381a 100644
--- a/src/wayland-server.h
+++ b/src/wayland-server.h
@@ -103,6 +103,10 @@ struct wl_global *wl_display_add_global(struct wl_display *display,
 					const struct wl_interface *interface,
 					void *data,
 					wl_global_bind_func_t bind);
+struct wl_global *wl_display_add_versioned_global(struct wl_display *display,
+						  const struct wl_interface *interface,
+						  int version, void *data,
+						  wl_global_bind_func_t bind);
 
 void wl_display_remove_global(struct wl_display *display,
 			      struct wl_global *global);
-- 
1.8.2.1



More information about the wayland-devel mailing list