.gitignore | 19 COPYING | 39 Makefile.am | 102 +- configure.ac | 85 + cursor/cursor-data.h | 1038 ++++++++++----------- cursor/os-compatibility.c | 35 cursor/os-compatibility.h | 35 cursor/wayland-cursor.c | 81 + cursor/wayland-cursor.h | 39 cursor/xcursor.c | 35 cursor/xcursor.h | 35 debian/changelog | 31 debian/control | 4 debian/libwayland-client0.symbols | 3 debian/libwayland-cursor0.symbols | 1 debian/libwayland-server0.symbols | 4 debian/watch | 2 doc/Contributing | 88 + doc/doxygen/.gitignore | 1 doc/doxygen/Makefile.am | 11 doc/doxygen/wayland.doxygen.in | 1728 ----------------------------------- doc/publican/protocol-to-docbook.xsl | 9 doc/publican/sources/Book_Info.xml | 46 doc/publican/sources/Client.xml | 2 doc/publican/sources/Protocol.xml | 41 protocol/wayland.dtd | 4 protocol/wayland.xml | 663 +++++++++++-- publish-doc | 15 src/connection.c | 75 - src/dtddata.S | 39 src/event-loop.c | 38 src/scanner.c | 802 ++++++++++++---- src/wayland-client-core.h | 258 +++++ src/wayland-client.c | 633 ++++++------ src/wayland-client.h | 197 --- src/wayland-egl-core.h | 59 + src/wayland-egl.h | 64 - src/wayland-os.c | 35 src/wayland-os.h | 35 src/wayland-private.h | 130 +- src/wayland-server-core.h | 489 +++++++++ src/wayland-server.c | 162 ++- src/wayland-server.h | 421 -------- src/wayland-shm.c | 143 +- src/wayland-util.c | 49 src/wayland-util.h | 82 + src/wayland-version.h.in | 35 tests/array-test.c | 44 tests/client-test.c | 35 tests/connection-test.c | 47 tests/display-test.c | 362 ++++++- tests/event-loop-test.c | 35 tests/exec-fd-leak-checker.c | 35 tests/fixed-benchmark.c | 37 tests/fixed-test.c | 35 tests/headers-protocol-core-test.c | 34 tests/headers-protocol-test.c | 34 tests/headers-test.c | 53 + tests/list-test.c | 37 tests/map-test.c | 35 tests/message-test.c | 35 tests/os-wrappers-test.c | 37 tests/queue-test.c | 41 tests/resources-test.c | 35 tests/sanity-test.c | 62 - tests/signal-test.c | 35 tests/socket-test.c | 55 - tests/test-compositor.c | 83 + tests/test-compositor.h | 46 tests/test-helpers.c | 35 tests/test-runner.c | 35 tests/test-runner.h | 24 72 files changed, 4972 insertions(+), 4316 deletions(-)
New commits: commit 7f86f329de597ac562b08d7572e48bcf72492ee2 Author: Héctor Orón Martínez <zu...@debian.org> Date: Thu Feb 4 23:45:27 2016 +0100 Release Debian version 1.9.92-1 Signed-off-by: Héctor Orón Martínez <zu...@debian.org> diff --git a/debian/changelog b/debian/changelog index 4c080dd..6adbc9a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,15 @@ +wayland (1.9.92-1) experimental; urgency=medium + + * New upstream release, experimental upload. + + [ Hideki Yamane ] + * debian/control + - add Build-Depends: libxml2-dev + * update debian/libwayland-{client,server}0.symbols + * update debian/watch (Closes: #813484) + + -- Héctor Orón Martínez <zu...@debian.org> Thu, 04 Feb 2016 23:22:27 +0100 + wayland (1.9.0-1) unstable; urgency=medium * New upstream release commit e6fbf4f564a089c48c76aea2b027e187a017c086 Author: Héctor Orón Martínez <zu...@debian.org> Date: Thu Feb 4 23:31:54 2016 +0100 d/control: build depend on libxml2-dev Signed-off-by: Héctor Orón Martínez <zu...@debian.org> diff --git a/debian/control b/debian/control index 508eb67..75a51bb 100644 --- a/debian/control +++ b/debian/control @@ -16,6 +16,7 @@ Build-Depends: docbook-xsl, libexpat1-dev, libffi-dev, + libxml2-dev, Standards-Version: 3.9.6 Vcs-Git: git://anonscm.debian.org/pkg-xorg/wayland/wayland Vcs-Browser: http://anonscm.debian.org/cgit/pkg-xorg/wayland/wayland.git commit bece5a9fc4c865b1edf1ad0858963502cae6e633 Author: Héctor Orón Martínez <zu...@debian.org> Date: Thu Feb 4 23:30:21 2016 +0100 update debian/libwayland-{client,server}0.symbols Signed-off-by: Héctor Orón Martínez <zu...@debian.org> diff --git a/debian/libwayland-client0.symbols b/debian/libwayland-client0.symbols index 15b4f8d..b73f51d 100644 --- a/debian/libwayland-client0.symbols +++ b/debian/libwayland-client0.symbols @@ -58,10 +58,13 @@ libwayland-client.so.0 libwayland-client0 #MINVER# wl_proxy_get_id@Base 1.0.2 wl_proxy_get_listener@Base 1.3.0 wl_proxy_get_user_data@Base 1.0.2 + wl_proxy_get_version@Base 1.9.91 wl_proxy_marshal@Base 1.0.2 wl_proxy_marshal_array@Base 1.3.0 wl_proxy_marshal_array_constructor@Base 1.3.92 + wl_proxy_marshal_array_constructor_versioned@Base 1.9.91 wl_proxy_marshal_constructor@Base 1.3.92 + wl_proxy_marshal_constructor_versioned@Base 1.9.91 wl_proxy_set_queue@Base 1.0.2 wl_proxy_set_user_data@Base 1.0.2 wl_region_interface@Base 1.0.2 diff --git a/debian/libwayland-server0.symbols b/debian/libwayland-server0.symbols index 8a2f372..6c1a71e 100644 --- a/debian/libwayland-server0.symbols +++ b/debian/libwayland-server0.symbols @@ -15,6 +15,7 @@ libwayland-server.so.0 libwayland-server0 #MINVER# wl_client_get_credentials@Base 1.0.2 wl_client_get_destroy_listener@Base 1.0.2 wl_client_get_display@Base 1.0.2 + wl_client_get_fd@Base 1.9.91 wl_client_get_object@Base 1.0.2 wl_client_new_object@Base 1.0.2 wl_client_post_no_memory@Base 1.2.0 @@ -28,6 +29,7 @@ libwayland-server.so.0 libwayland-server0 #MINVER# wl_display_add_shm_format@Base 1.3.0 wl_display_add_socket@Base 1.0.2 wl_display_add_socket_auto@Base 1.5.91 + wl_display_add_socket_fd@Base 1.9.91 wl_display_create@Base 1.0.2 wl_display_destroy@Base 1.0.2 wl_display_flush_clients@Base 1.0.2 @@ -112,8 +114,10 @@ libwayland-server.so.0 libwayland-server0 #MINVER# wl_shm_buffer_get_height@Base 1.0.2 wl_shm_buffer_get_stride@Base 1.0.2 wl_shm_buffer_get_width@Base 1.0.2 + wl_shm_buffer_ref_pool@Base 1.9.91 wl_shm_interface@Base 1.0.2 wl_shm_pool_interface@Base 1.0.2 + wl_shm_pool_unref@Base 1.9.91 wl_subcompositor_interface@Base 1.3.92 wl_subsurface_interface@Base 1.3.92 wl_surface_interface@Base 1.0.2 commit 55d2b4a8811713ca5ae9091ccf8a380bd060aba2 Author: Héctor Orón Martínez <zu...@debian.org> Date: Thu Feb 4 23:28:58 2016 +0100 update debian/watch (Closes: #813484) Signed-off-by: Héctor Orón Martínez <zu...@debian.org> diff --git a/debian/watch b/debian/watch index bcc66e6..c8aafea 100644 --- a/debian/watch +++ b/debian/watch @@ -1,3 +1,3 @@ #git=git://anongit.freedesktop.org/wayland/wayland version=3 -http://wayland.freedesktop.org/releases/wayland-(.*)\.tar\.xz +http://wayland.freedesktop.org/releases/wayland-([\d].*)\.tar\.xz commit 816a0ae09bd5c370b95cee459905976dc14cfac0 Author: Bryce Harrington <br...@bryceharrington.org> Date: Tue Feb 2 15:30:36 2016 -0800 configure.ac: bump to version 1.9.92 for the beta release diff --git a/configure.ac b/configure.ac index 2469cdb..63dd2cf 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ([2.64]) m4_define([wayland_major_version], [1]) m4_define([wayland_minor_version], [9]) -m4_define([wayland_micro_version], [91]) +m4_define([wayland_micro_version], [92]) m4_define([wayland_version], [wayland_major_version.wayland_minor_version.wayland_micro_version]) commit 7b42788f212079c2ef4c69c095efa50e90ca1301 Author: Jonas Ådahl <jad...@gmail.com> Date: Mon Jan 25 17:28:06 2016 +0800 scanner: Print filename on DTD validation error Don't just print prefix the errors with "protocol", but the actual file name, if wayland-scanner was passed with the filename of the protocol file. If wayland-scanner is reading from stdin, errors will be prefixed with "<stdin>" instead of "protocol". Signed-off-by: Jonas Ådahl <jad...@gmail.com> Reviewed-by: David Fort <cont...@hardening-consulting.com> Reviewed-by: Derek Foreman <der...@osg.samsung.com> Reviewed-by: Bryce Harrington <br...@osg.samsung.com> diff --git a/src/scanner.c b/src/scanner.c index 1d626f4..dda5473 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -71,7 +71,7 @@ usage(int ret) } static bool -is_dtd_valid(FILE *input) +is_dtd_valid(FILE *input, const char *filename) { bool rc = true; #if HAVE_LIBXML @@ -101,7 +101,7 @@ is_dtd_valid(FILE *input) abort(); } - doc = xmlCtxtReadFd(ctx, fd, "protocol", NULL, 0); + doc = xmlCtxtReadFd(ctx, fd, filename, NULL, 0); if (!doc) { fprintf(stderr, "Failed to read XML\n"); abort(); @@ -1623,6 +1623,7 @@ int main(int argc, char *argv[]) struct parse_context ctx; struct protocol protocol; FILE *input = stdin; + char *input_filename = NULL; int len; void *buf; bool help = false, core_headers = false; @@ -1678,7 +1679,8 @@ int main(int argc, char *argv[]) usage(EXIT_FAILURE); if (argc == 3) { - input = fopen(argv[1], "r"); + input_filename = argv[1]; + input = fopen(input_filename, "r"); if (input == NULL) { fprintf(stderr, "Could not open input file: %s\n", strerror(errno)); @@ -1700,9 +1702,12 @@ int main(int argc, char *argv[]) /* initialize context */ memset(&ctx, 0, sizeof ctx); ctx.protocol = &protocol; - ctx.loc.filename = "<stdin>"; + if (input == stdin) + ctx.loc.filename = "<stdin>"; + else + ctx.loc.filename = input_filename; - if (!is_dtd_valid(input)) { + if (!is_dtd_valid(input, ctx.loc.filename)) { fprintf(stderr, "*******************************************************\n" "* *\n" commit 0d56e380f676e6fe475ffba71f11b480adf4e0a5 Author: Derek Foreman <der...@osg.samsung.com> Date: Thu Jan 14 13:33:52 2016 -0600 server: Fail to bind object when requested version is 0 0 is not a valid version number for registry bind requests, so let's check for it in registry_bind. Signed-off-by: Derek Foreman <der...@osg.samsung.com> Reviewed-by: Daniel Stone <dani...@collabora.com> Reviewed-by: Bryce Harrington <br...@osg.samsung.com> diff --git a/src/wayland-server.c b/src/wayland-server.c index 3ba8a5d..ae9365f 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -730,6 +730,11 @@ registry_bind(struct wl_client *client, wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, "invalid global %s (%d)", interface, name); + else if (version == 0) + wl_resource_post_error(resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "invalid version for global %s (%d): 0 is not a valid version", + interface, name); else if (global->version < version) wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, commit 5ac34a101237a1534dcd7c14952f7c20ac2d9235 Author: Marek Chalupa <mchqwe...@gmail.com> Date: Wed Jan 27 10:06:28 2016 +0100 cosmetic: return NULL instead of 0 we're returning a pointer Signed-off-by: Marek Chalupa <mchqwe...@gmail.com> Reviewed-by: Bryce Harrington <br...@osg.samsung.com> diff --git a/src/wayland-util.c b/src/wayland-util.c index e782309..3f95877 100644 --- a/src/wayland-util.c +++ b/src/wayland-util.c @@ -127,7 +127,7 @@ wl_array_add(struct wl_array *array, size_t size) data = malloc(alloc); if (data == NULL) - return 0; + return NULL; array->data = data; array->alloc = alloc; } commit ed680954c87a726a7e98c098b8c35604b1633295 Author: Jonas Ådahl <jad...@gmail.com> Date: Mon Jan 18 18:18:16 2016 +0800 protocol: Add note about per version requirements to wl_data_device_manager Add a note to the wl_data_device_manager global interface about the different requirements for operating the objects created from the bound global. Signed-off-by: Jonas Ådahl <jad...@gmail.com> Reviewed-by: Carlos Garnacho <carl...@gnome.org> diff --git a/protocol/wayland.xml b/protocol/wayland.xml index b223bb4..8739cd3 100644 --- a/protocol/wayland.xml +++ b/protocol/wayland.xml @@ -910,6 +910,11 @@ copy-and-paste and drag-and-drop. These mechanisms are tied to a wl_seat and this interface lets a client get a wl_data_device corresponding to a wl_seat. + + Depending on the version bound, the objects created from the bound + wl_data_device_manager object will have different requirements for + functioning properly. See wl_data_source.set_actions, + wl_data_offer.accept and wl_data_offer.finish for details. </description> <request name="create_data_source"> commit ac36082813c459e64ae1f564002a7cadfa0a7637 Author: Sergi Granell <xerpi.g...@gmail.com> Date: Mon Feb 1 19:35:51 2016 +0100 server: Fix possible wl_display_add_socket_fd memleak If wl_event_loop_add_fd failed, the fail path didn't free the newly allocated struct wl_socket. Reviewed-by: Derek Foreman <der...@osg.samsung.com> diff --git a/src/wayland-server.c b/src/wayland-server.c index 6654cd7..3ba8a5d 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -1268,17 +1268,18 @@ wl_display_add_socket_fd(struct wl_display *display, int sock_fd) if (s == NULL) return -1; - /* Reuse the existing fd */ - s->fd = sock_fd; - - s->source = wl_event_loop_add_fd(display->loop, s->fd, + s->source = wl_event_loop_add_fd(display->loop, sock_fd, WL_EVENT_READABLE, socket_data, display); if (s->source == NULL) { wl_log("failed to establish event source\n"); + wl_socket_destroy(s); return -1; } + /* Reuse the existing fd */ + s->fd = sock_fd; + wl_list_insert(display->socket_list.prev, &s->link); return 0; commit 14b76a0e24c988334c18f477572a556ba005b182 Author: Bryce Harrington <br...@osg.samsung.com> Date: Tue Jan 19 14:54:32 2016 -0800 configure.ac: re-bump to version 1.9.91 for the alpha release diff --git a/configure.ac b/configure.ac index 16735fb..2469cdb 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ AC_PREREQ([2.64]) -m4_define([wayland_major_version], [1]) -m4_define([wayland_minor_version], [9]) +m4_define([wayland_major_version], [1]) +m4_define([wayland_minor_version], [9]) m4_define([wayland_micro_version], [91]) m4_define([wayland_version], [wayland_major_version.wayland_minor_version.wayland_micro_version]) commit eb52bb8e14f4d1ed3564abbb48ef3ddd28b115c0 Author: Sung-Jin Park <input.hac...@gmail.com> Date: Thu Jan 14 16:03:43 2016 +0900 server: Add an API to get the file descriptor for a client This adds an API to get the file descriptor for a client. The client file descriptor can be used for a wayland compositor to validate a request from a client if there are any additional information provided from the client's file descriptor. For instance, this will be helpful in some linux distributions, in which SELinux or SMACK is enabled. In those environments, each file (including socket) will have each security contexts in its inode as xattr member variable. A wayland compositor can validate a client request by getting the file descriptor of the client and by checking the security contexts associated with the file descriptor. Signed-off-by: Sung-Jin Park <input.hac...@gmail.com> diff --git a/src/connection.c b/src/connection.c index bc373f6..65b64e9 100644 --- a/src/connection.c +++ b/src/connection.c @@ -405,6 +405,12 @@ wl_message_count_arrays(const struct wl_message *message) return arrays; } +int +wl_connection_get_fd(struct wl_connection *connection) +{ + return connection->fd; +} + static int wl_connection_put_fd(struct wl_connection *connection, int32_t fd) { diff --git a/src/wayland-private.h b/src/wayland-private.h index da578d1..994bc45 100644 --- a/src/wayland-private.h +++ b/src/wayland-private.h @@ -136,6 +136,9 @@ int wl_connection_queue(struct wl_connection *connection, const void *data, size_t count); +int +wl_connection_get_fd(struct wl_connection *connection); + struct wl_closure { int count; const struct wl_message *message; diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h index 1700cd3..e8e1e9c 100644 --- a/src/wayland-server-core.h +++ b/src/wayland-server-core.h @@ -182,6 +182,9 @@ void wl_client_get_credentials(struct wl_client *client, pid_t *pid, uid_t *uid, gid_t *gid); +int +wl_client_get_fd(struct wl_client *client); + void wl_client_add_destroy_listener(struct wl_client *client, struct wl_listener *listener); diff --git a/src/wayland-server.c b/src/wayland-server.c index 3a7d79d..6654cd7 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -491,6 +491,41 @@ wl_client_get_credentials(struct wl_client *client, *gid = client->ucred.gid; } +/** Get the file descriptor for the client + * + * \param client The display object + * \return The file descriptor to use for the connection + * + * This function returns the file descriptor for the given client. + * + * Be sure to use the file descriptor from the client for inspection only. + * If the caller does anything to the file descriptor that changes its state, + * it will likely cause problems. + * + * See also wl_client_get_credentials(). + * It is recommended that you evaluate whether wl_client_get_credentials() + * can be applied to your use case instead of this function. + * + * If you would like to distinguish just between the client and the compositor + * itself from the client's request, it can be done by getting the client + * credentials and by checking the PID of the client and the compositor's PID. + * Regarding the case in which the socketpair() is being used, you need to be + * careful. Please note the documentation for wl_client_get_credentials(). + * + * This function can be used for a compositor to validate a request from + * a client if there are additional information provided from the client's + * file descriptor. For instance, suppose you can get the security contexts + * from the client's file descriptor. The compositor can validate the client's + * request with the contexts and make a decision whether it permits or deny it. + * + * \memberof wl_client + */ +WL_EXPORT int +wl_client_get_fd(struct wl_client *client) +{ + return wl_connection_get_fd(client->connection); +} + /** Look up an object in the client name space * * \param client The client object commit 7ed00c1de77afbab23f4908fbd9d60ec070c209b Author: Bryce Harrington <br...@osg.samsung.com> Date: Tue Jan 19 14:30:33 2016 -0800 configure.ac: bump to version 1.9.91 for the alpha release diff --git a/configure.ac b/configure.ac index 48658cf..16735fb 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ([2.64]) m4_define([wayland_major_version], [1]) m4_define([wayland_minor_version], [9]) -m4_define([wayland_micro_version], [90]) +m4_define([wayland_micro_version], [91]) m4_define([wayland_version], [wayland_major_version.wayland_minor_version.wayland_micro_version]) commit e9d894204b1a424ff999acbfd28a933478bd6531 Author: Derek Foreman <der...@osg.samsung.com> Date: Tue Jan 12 16:15:04 2016 -0600 tests: Test proxy versions Add a test that confirms that proxy versions are always 0 for display and correct otherwise. Signed-off-by: Derek Foreman <der...@osg.samsung.com> Reviewed-by: Daniel Stone <dani...@collabora.com> diff --git a/tests/display-test.c b/tests/display-test.c index 0d25ca3..1a6c345 100644 --- a/tests/display-test.c +++ b/tests/display-test.c @@ -37,6 +37,7 @@ #include <sys/stat.h> #include <pthread.h> #include <poll.h> +#include <stdbool.h> #include "wayland-private.h" #include "wayland-server.h" @@ -102,16 +103,48 @@ TEST(tc_leaks_tests) display_destroy(d); } +/* This is how pre proxy-version registry binds worked, + * this should create a proxy that shares the display's + * version number: 0 */ +static void * +old_registry_bind(struct wl_registry *wl_registry, + uint32_t name, + const struct wl_interface *interface, + uint32_t version) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_constructor( + (struct wl_proxy *) wl_registry, WL_REGISTRY_BIND, + interface, name, interface->name, version, NULL); + + return (void *) id; +} + +struct handler_info { + struct wl_seat *seat; + uint32_t bind_version; + bool use_unversioned; +}; + static void registry_handle_globals(void *data, struct wl_registry *registry, uint32_t id, const char *intf, uint32_t ver) { - struct wl_seat **seat = data; + struct handler_info *hi = data; + + /* This is only for the proxy version test */ + if (hi->bind_version) + ver = hi->bind_version; if (strcmp(intf, "wl_seat") == 0) { - *seat = wl_registry_bind(registry, id, - &wl_seat_interface, ver); - assert(*seat); + if (hi->use_unversioned) + hi->seat = old_registry_bind(registry, id, + &wl_seat_interface, ver); + else + hi->seat = wl_registry_bind(registry, id, + &wl_seat_interface, ver); + assert(hi->seat); } } @@ -121,19 +154,31 @@ static const struct wl_registry_listener registry_listener = { }; static struct wl_seat * -client_get_seat(struct client *c) +client_get_seat_with_info(struct client *c, struct handler_info *hi) { - struct wl_seat *seat; struct wl_registry *reg = wl_display_get_registry(c->wl_display); assert(reg); - wl_registry_add_listener(reg, ®istry_listener, &seat); + assert(hi); + hi->seat = NULL; + wl_registry_add_listener(reg, ®istry_listener, hi); wl_display_roundtrip(c->wl_display); - assert(seat); + assert(hi->seat); wl_registry_destroy(reg); - return seat; + return hi->seat; +} + +static struct wl_seat * +client_get_seat(struct client *c) +{ + struct handler_info hi; + + hi.use_unversioned = false; + hi.bind_version = 0; + + return client_get_seat_with_info(c, &hi); } static void @@ -769,3 +814,65 @@ TEST(error_code_after_epipe) display_destroy(d); } + +static void +check_seat_versions(struct wl_seat *seat, uint32_t ev) +{ + struct wl_pointer *pointer; + + assert(wl_proxy_get_version((struct wl_proxy *) seat) == ev); + assert(wl_seat_get_version(seat) == ev); + + pointer = wl_seat_get_pointer(seat); + assert(wl_pointer_get_version(pointer) == ev); + assert(wl_proxy_get_version((struct wl_proxy *) pointer) == ev); + wl_proxy_destroy((struct wl_proxy *) pointer); +} + +/* Normal client with proxy versions available. */ +static void +seat_version(void *data) +{ + struct handler_info *hi = data; + struct client *c = client_connect(); + struct wl_seat *seat; + + /* display proxy should always be version 0 */ + assert(wl_proxy_get_version((struct wl_proxy *) c->wl_display) == 0); + + seat = client_get_seat_with_info(c, hi); + if (hi->use_unversioned) + check_seat_versions(seat, 0); + else + check_seat_versions(seat, hi->bind_version); + + wl_proxy_destroy((struct wl_proxy *) seat); + + client_disconnect_nocheck(c); +} + +TEST(versions) +{ + struct display *d = display_create(); + struct wl_global *global; + int i; + + global = wl_global_create(d->wl_display, &wl_seat_interface, + 5, d, bind_seat); + + for (i = 1; i <= 5; i++) { + struct handler_info hi; + + hi.bind_version = i; + hi.use_unversioned = false; + client_create(d, seat_version, &hi); + hi.use_unversioned = true; + client_create(d, seat_version, &hi); + } + + display_run(d); + + wl_global_destroy(global); + + display_destroy(d); +} commit 557032e36cf5c45ec1a827f2ec49bdcce3833e80 Author: Jason Ekstrand <ja...@jlekstrand.net> Date: Thu Nov 12 13:53:15 2015 -0600 Track protocol object versions inside wl_proxy. This provides a standardized mechanism for tracking protocol object versions in client code. The wl_display object is created with version 1. Every time an object is created from within wl_registry_bind, it gets the bound version. Every other time an object is created, it simply inherits it's version from the parent object that created it. (comments and minor reformatting added by Derek Foreman <der...@osg.samsung.com>) Reviewed-by: Pekka Paalanen <pekka.paala...@collabora.co.uk> Second trivial commit squashed into this one: Authored by Derek Foreman <der...@osg.samsung.com> Signed-off-by: Derek Foreman <der...@osg.samsung.com> (it's literally one of code and a lot of comments) This sets wl_display's version (for proxy version query purposes) to 0. Any proxy created with unversioned API (this happens when a client compiled with old headers links against new wayland) will inherit this 0. This gives us a way for new libraries linked by old clients to realize they can't know a proxy's version. wl_display's version being unqueryable (always returning 0) is an acceptable side effect, since it's a special object you can't bind specific versions of anyway. Second half: Reviewed-by: Pekka Paalanen <pekka.paala...@collabora.co.uk> Reviewed-by: Jason Ekstrand <ja...@jlekstrand.net> diff --git a/src/scanner.c b/src/scanner.c index b00f036..1d626f4 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -956,6 +956,14 @@ emit_stubs(struct wl_list *message_list, struct interface *interface) interface->name, interface->name, interface->name, interface->name); + printf("static inline uint32_t\n" + "%s_get_version(struct %s *%s)\n" + "{\n" + "\treturn wl_proxy_get_version((struct wl_proxy *) %s);\n" + "}\n\n", + interface->name, interface->name, interface->name, + interface->name); + has_destructor = 0; has_destroy = 0; wl_list_for_each(m, message_list, link) { @@ -1027,21 +1035,31 @@ emit_stubs(struct wl_list *message_list, struct interface *interface) printf(")\n" "{\n"); - if (ret) { + if (ret && ret->interface_name == NULL) { + /* an arg has type ="new_id" but interface is not + * provided, such as in wl_registry.bind */ printf("\tstruct wl_proxy *%s;\n\n" - "\t%s = wl_proxy_marshal_constructor(" + "\t%s = wl_proxy_marshal_constructor_versioned(" "(struct wl_proxy *) %s,\n" - "\t\t\t %s_%s, ", + "\t\t\t %s_%s, interface, version", ret->name, ret->name, interface->name, interface->uppercase_name, m->uppercase_name); - - if (ret->interface_name == NULL) - printf("interface"); - else - printf("&%s_interface", ret->interface_name); + } else if (ret) { + /* Normal factory case, an arg has type="new_id" and + * an interface is provided */ + printf("\tstruct wl_proxy *%s;\n\n" + "\t%s = wl_proxy_marshal_constructor(" + "(struct wl_proxy *) %s,\n" + "\t\t\t %s_%s, &%s_interface", + ret->name, ret->name, + interface->name, + interface->uppercase_name, + m->uppercase_name, + ret->interface_name); } else { + /* No args have type="new_id" */ printf("\twl_proxy_marshal((struct wl_proxy *) %s,\n" "\t\t\t %s_%s", interface->name, diff --git a/src/wayland-client-core.h b/src/wayland-client-core.h index a729395..91f7e7b 100644 --- a/src/wayland-client-core.h +++ b/src/wayland-client-core.h @@ -139,9 +139,21 @@ wl_proxy_marshal_constructor(struct wl_proxy *proxy, ...); struct wl_proxy * +wl_proxy_marshal_constructor_versioned(struct wl_proxy *proxy, + uint32_t opcode, + const struct wl_interface *interface, + uint32_t version, + ...); +struct wl_proxy * wl_proxy_marshal_array_constructor(struct wl_proxy *proxy, uint32_t opcode, union wl_argument *args, const struct wl_interface *interface); +struct wl_proxy * +wl_proxy_marshal_array_constructor_versioned(struct wl_proxy *proxy, + uint32_t opcode, + union wl_argument *args, + const struct wl_interface *interface, + uint32_t version); void wl_proxy_destroy(struct wl_proxy *proxy); @@ -165,6 +177,9 @@ void * wl_proxy_get_user_data(struct wl_proxy *proxy); uint32_t +wl_proxy_get_version(struct wl_proxy *proxy); + +uint32_t wl_proxy_get_id(struct wl_proxy *proxy); const char * diff --git a/src/wayland-client.c b/src/wayland-client.c index 55483c6..ef12bfc 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -62,6 +62,7 @@ struct wl_proxy { int refcount; void *user_data; wl_dispatcher_func_t dispatcher; + uint32_t version; }; struct wl_global { @@ -326,7 +327,8 @@ wl_display_create_queue(struct wl_display *display) } static struct wl_proxy * -proxy_create(struct wl_proxy *factory, const struct wl_interface *interface) +proxy_create(struct wl_proxy *factory, const struct wl_interface *interface, + uint32_t version) { struct wl_proxy *proxy; struct wl_display *display = factory->display; @@ -339,6 +341,7 @@ proxy_create(struct wl_proxy *factory, const struct wl_interface *interface) proxy->display = display; proxy->queue = factory->queue; proxy->refcount = 1; + proxy->version = version; proxy->object.id = wl_map_insert_new(&display->objects, 0, proxy); @@ -371,7 +374,7 @@ wl_proxy_create(struct wl_proxy *factory, const struct wl_interface *interface) struct wl_proxy *proxy; pthread_mutex_lock(&display->mutex); - proxy = proxy_create(factory, interface); + proxy = proxy_create(factory, interface, factory->version); pthread_mutex_unlock(&display->mutex); return proxy; @@ -394,6 +397,7 @@ wl_proxy_create_for_id(struct wl_proxy *factory, proxy->display = display; proxy->queue = factory->queue; proxy->refcount = 1; + proxy->version = factory->version; wl_map_insert_at(&display->objects, 0, id, proxy); @@ -525,7 +529,7 @@ wl_proxy_add_dispatcher(struct wl_proxy *proxy, static struct wl_proxy * create_outgoing_proxy(struct wl_proxy *proxy, const struct wl_message *message, union wl_argument *args, - const struct wl_interface *interface) + const struct wl_interface *interface, uint32_t version) { int i, count; const char *signature; @@ -539,7 +543,7 @@ create_outgoing_proxy(struct wl_proxy *proxy, const struct wl_message *message, switch (arg.type) { case 'n': - new_proxy = proxy_create(proxy, interface); + new_proxy = proxy_create(proxy, interface, version); if (new_proxy == NULL) return NULL; @@ -564,7 +568,8 @@ create_outgoing_proxy(struct wl_proxy *proxy, const struct wl_message *message, * * For new-id arguments, this function will allocate a new wl_proxy * and send the ID to the server. The new wl_proxy will be returned - * on success or NULL on errror with errno set accordingly. + * on success or NULL on errror with errno set accordingly. The newly + * created proxy will inherit their version from their parent. * * \note This is intended to be used by language bindings and not in * non-generated code. @@ -578,6 +583,43 @@ wl_proxy_marshal_array_constructor(struct wl_proxy *proxy, uint32_t opcode, union wl_argument *args, const struct wl_interface *interface) { + return wl_proxy_marshal_array_constructor_versioned(proxy, opcode, + args, interface, + proxy->version); +} + + +/** Prepare a request to be sent to the compositor + * + * \param proxy The proxy object + * \param opcode Opcode of the request to be sent + * \param args Extra arguments for the given request + * \param interface The interface to use for the new proxy + * \param version The protocol object version for the new proxy + * + * Translates the request given by opcode and the extra arguments into the + * wire format and write it to the connection buffer. This version takes an + * array of the union type wl_argument. + * + * For new-id arguments, this function will allocate a new wl_proxy + * and send the ID to the server. The new wl_proxy will be returned + * on success or NULL on errror with errno set accordingly. The newly + * created proxy will have the version specified. + * + * \note This is intended to be used by language bindings and not in + * non-generated code. + * + * \sa wl_proxy_marshal() + * + * \memberof wl_proxy + */ +WL_EXPORT struct wl_proxy * +wl_proxy_marshal_array_constructor_versioned(struct wl_proxy *proxy, + uint32_t opcode, + union wl_argument *args, + const struct wl_interface *interface, + uint32_t version) +{ struct wl_closure *closure; struct wl_proxy *new_proxy = NULL;