/* * Copyright © 2008 Kristian Høgsberg * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial * portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #define _GNU_SOURCE #include <stdbool.h> #include <stdlib.h> #include <stdint.h> #include <stddef.h> #include <stdio.h> #include <stdarg.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/un.h> #include <dlfcn.h> #include <assert.h> #include <sys/time.h> #include <fcntl.h> #include <sys/eventfd.h> #include <sys/file.h> #include <sys/stat.h> #include "wayland-util.h" #include "wayland-private.h" #include "wayland-server-private.h" #include "wayland-server.h" #include "wayland-os.h" /* This is the size of the char array in struct sock_addr_un. * No Wayland socket can be created with a path longer than this, * including the null terminator. */ #ifndef UNIX_PATH_MAX #define UNIX_PATH_MAX … #endif #define LOCK_SUFFIX … #define LOCK_SUFFIXLEN … struct wl_socket { … }; struct wl_client { … }; struct wl_display { … }; struct wl_global { … }; struct wl_resource { … }; struct wl_protocol_logger { … }; static int debug_server = …; static void log_closure(struct wl_resource *resource, struct wl_closure *closure, int send) { … } static bool verify_objects(struct wl_resource *resource, uint32_t opcode, union wl_argument *args) { … } static void handle_array(struct wl_resource *resource, uint32_t opcode, union wl_argument *args, int (*send_func)(struct wl_closure *, struct wl_connection *)) { … } WL_EXPORT void wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode, union wl_argument *args) { … } WL_EXPORT void wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...) { … } WL_EXPORT void wl_resource_queue_event_array(struct wl_resource *resource, uint32_t opcode, union wl_argument *args) { … } WL_EXPORT void wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...) { … } static void wl_resource_post_error_vargs(struct wl_resource *resource, uint32_t code, const char *msg, va_list argp) { … } WL_EXPORT void wl_resource_post_error(struct wl_resource *resource, uint32_t code, const char *msg, ...) { … } static void destroy_client_with_error(struct wl_client *client, const char *reason) { … } static int wl_client_connection_data(int fd, uint32_t mask, void *data) { … } /** Flush pending events to the client * * \param client The client object * * Events sent to clients are queued in a buffer and written to the * socket later - typically when the compositor has handled all * requests and goes back to block in the event loop. This function * flushes all queued up events for a client immediately. * * \memberof wl_client */ WL_EXPORT void wl_client_flush(struct wl_client *client) { … } /** Get the display object for the given client * * \param client The client object * \return The display object the client is associated with. * * \memberof wl_client */ WL_EXPORT struct wl_display * wl_client_get_display(struct wl_client *client) { … } static int bind_display(struct wl_client *client, struct wl_display *display); /** Create a client for the given file descriptor * * \param display The display object * \param fd The file descriptor for the socket to the client * \return The new client object or NULL on failure. * * Given a file descriptor corresponding to one end of a socket, this * function will create a wl_client struct and add the new client to * the compositors client list. At that point, the client is * initialized and ready to run, as if the client had connected to the * servers listening socket. When the client eventually sends * requests to the compositor, the wl_client argument to the request * handler will be the wl_client returned from this function. * * The other end of the socket can be passed to * wl_display_connect_to_fd() on the client side or used with the * WAYLAND_SOCKET environment variable on the client side. * * Listeners added with wl_display_add_client_created_listener() will * be notified by this function after the client is fully constructed. * * On failure this function sets errno accordingly and returns NULL. * * On success, the new client object takes the ownership of the file * descriptor. On failure, the ownership of the socket endpoint file * descriptor is unchanged, it is the responsibility of the caller to * perform cleanup, e.g. call close(). * * \memberof wl_display */ WL_EXPORT struct wl_client * wl_client_create(struct wl_display *display, int fd) { … } /** Return Unix credentials for the client * * \param client The display object * \param pid Returns the process ID * \param uid Returns the user ID * \param gid Returns the group ID * * This function returns the process ID, the user ID and the group ID * for the given client. The credentials come from getsockopt() with * SO_PEERCRED, on the client socket fd. All the pointers can be * NULL, if the caller is not interested in a particular ID. * * Note, process IDs are subject to race conditions and are not a reliable way * to identify a client. * * Be aware that for clients that a compositor forks and execs and * then connects using socketpair(), this function will return the * credentials for the compositor. The credentials for the socketpair * are set at creation time in the compositor. * * \memberof wl_client */ WL_EXPORT void wl_client_get_credentials(struct wl_client *client, pid_t *pid, uid_t *uid, gid_t *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) { … } /** Look up an object in the client name space * * \param client The client object * \param id The object id * \return The object or NULL if there is not object for the given ID * * This looks up an object in the client object name space by its * object ID. * * \memberof wl_client */ WL_EXPORT struct wl_resource * wl_client_get_object(struct wl_client *client, uint32_t id) { … } WL_EXPORT void wl_client_post_no_memory(struct wl_client *client) { … } /** Report an internal server error * * \param client The client object * \param msg A printf-style format string * \param ... Format string arguments * * Report an unspecified internal implementation error and disconnect * the client. * * \memberof wl_client */ WL_EXPORT void wl_client_post_implementation_error(struct wl_client *client, char const *msg, ...) { … } WL_EXPORT void wl_resource_post_no_memory(struct wl_resource *resource) { … } /** Detect if a wl_resource uses the deprecated public definition. * * Before Wayland 1.2.0, the definition of struct wl_resource was public. * It was made opaque just before 1.2.0, and later new fields were added. * The new fields cannot be accessed if a program is using the deprecated * definition, as there would not be memory allocated for them. * * The creation pattern for the deprecated definition was wl_resource_init() * followed by wl_client_add_resource(). wl_resource_init() was an inline * function and no longer exists, but binaries might still carry it. * wl_client_add_resource() still exists for ABI compatibility. */ static bool resource_is_deprecated(struct wl_resource *resource) { … } /** Removes the wl_resource from the client's object map and deletes it. * * Triggers the destroy signal and destructor for the resource before * removing it from the client's object map and releasing the resource's * memory. * * This order is important to ensure listeners and destruction code can * find the resource before it has been destroyed whilst ensuring the * resource is not accessible via the object map after memory has been * freed. */ static enum wl_iterator_result remove_and_destroy_resource(void *element, void *data, uint32_t flags) { … } WL_EXPORT void wl_resource_destroy(struct wl_resource *resource) { … } WL_EXPORT uint32_t wl_resource_get_id(struct wl_resource *resource) { … } WL_EXPORT struct wl_list * wl_resource_get_link(struct wl_resource *resource) { … } WL_EXPORT struct wl_resource * wl_resource_from_link(struct wl_list *link) { … } WL_EXPORT struct wl_resource * wl_resource_find_for_client(struct wl_list *list, struct wl_client *client) { … } WL_EXPORT struct wl_client * wl_resource_get_client(struct wl_resource *resource) { … } WL_EXPORT void wl_resource_set_user_data(struct wl_resource *resource, void *data) { … } WL_EXPORT void * wl_resource_get_user_data(struct wl_resource *resource) { … } WL_EXPORT int wl_resource_get_version(struct wl_resource *resource) { … } WL_EXPORT void wl_resource_set_destructor(struct wl_resource *resource, wl_resource_destroy_func_t destroy) { … } WL_EXPORT int wl_resource_instance_of(struct wl_resource *resource, const struct wl_interface *interface, const void *implementation) { … } WL_EXPORT void wl_resource_add_destroy_listener(struct wl_resource *resource, struct wl_listener * listener) { … } WL_EXPORT struct wl_listener * wl_resource_get_destroy_listener(struct wl_resource *resource, wl_notify_func_t notify) { … } /** Retrieve the interface name (class) of a resource object. * * \param resource The resource object * * \memberof wl_resource */ WL_EXPORT const char * wl_resource_get_class(struct wl_resource *resource) { … } /** * Add a listener to be called at the beginning of wl_client destruction * * The listener provided will be called when wl_client destroy has begun, * before any of that client's resources have been destroyed. * * There is no requirement to remove the link of the wl_listener when the * signal is emitted. * * \memberof wl_client */ WL_EXPORT void wl_client_add_destroy_listener(struct wl_client *client, struct wl_listener *listener) { … } WL_EXPORT struct wl_listener * wl_client_get_destroy_listener(struct wl_client *client, wl_notify_func_t notify) { … } /** * Add a listener to be called at the end of wl_client destruction * * The listener provided will be called when wl_client destroy is nearly * complete, after all of that client's resources have been destroyed. * * There is no requirement to remove the link of the wl_listener when the * signal is emitted. * * \memberof wl_client * \since 1.22.0 */ WL_EXPORT void wl_client_add_destroy_late_listener(struct wl_client *client, struct wl_listener *listener) { … } WL_EXPORT struct wl_listener * wl_client_get_destroy_late_listener(struct wl_client *client, wl_notify_func_t notify) { … } WL_EXPORT void wl_client_destroy(struct wl_client *client) { … } /* Check if a global filter is registered and use it if any. * * If no wl_global filter has been registered, this function will * return true, allowing the wl_global to be visible to the wl_client */ static bool wl_global_is_visible(const struct wl_client *client, const struct wl_global *global) { … } static void registry_bind(struct wl_client *client, struct wl_resource *resource, uint32_t name, const char *interface, uint32_t version, uint32_t id) { … } static const struct wl_registry_interface registry_interface = …; static void display_sync(struct wl_client *client, struct wl_resource *resource, uint32_t id) { … } static void unbind_resource(struct wl_resource *resource) { … } static void display_get_registry(struct wl_client *client, struct wl_resource *resource, uint32_t id) { … } static const struct wl_display_interface display_interface = …; static void destroy_client_display_resource(struct wl_resource *resource) { … } static int bind_display(struct wl_client *client, struct wl_display *display) { … } static int handle_display_terminate(int fd, uint32_t mask, void *data) { … } /** Create Wayland display object. * * \return The Wayland display object. Null if failed to create * * This creates the wl_display object. * * \memberof wl_display */ WL_EXPORT struct wl_display * wl_display_create(void) { … } static void wl_socket_destroy(struct wl_socket *s) { … } static struct wl_socket * wl_socket_alloc(void) { … } /** Destroy Wayland display object. * * \param display The Wayland display object which should be destroyed. * * This function emits the wl_display destroy signal, releases * all the sockets added to this display, free's all the globals associated * with this display, free's memory of additional shared memory formats and * destroy the display object. * * \sa wl_display_add_destroy_listener * * \memberof wl_display */ WL_EXPORT void wl_display_destroy(struct wl_display *display) { … } /** Set a filter function for global objects * * \param display The Wayland display object. * \param filter The global filter function. * \param data User data to be associated with the global filter. * * Set a filter for the wl_display to advertise or hide global objects * to clients. * The set filter will be used during wl_global advertisement to * determine whether a global object should be advertised to a * given client, and during wl_global binding to determine whether * a given client should be allowed to bind to a global. * * Clients that try to bind to a global that was filtered out will * have an error raised. * * Setting the filter NULL will result in all globals being * advertised to all clients. The default is no filter. * * The filter should be installed before any client connects and should always * take the same decision given a client and a global. Not doing so will result * in inconsistent filtering and broken wl_registry event sequences. * * \memberof wl_display */ WL_EXPORT void wl_display_set_global_filter(struct wl_display *display, wl_display_global_filter_func_t filter, void *data) { … } WL_EXPORT struct wl_global * wl_global_create(struct wl_display *display, const struct wl_interface *interface, int version, void *data, wl_global_bind_func_t bind) { … } /** Remove the global * * \param global The Wayland global. * * Broadcast a global remove event to all clients without destroying the * global. This function can only be called once per global. * * wl_global_destroy() removes the global and immediately destroys it. On * the other end, this function only removes the global, allowing clients * that have not yet received the global remove event to continue to bind to * it. * * This can be used by compositors to mitigate clients being disconnected * because a global has been added and removed too quickly. Compositors can call * wl_global_remove(), then wait an implementation-defined amount of time, then * call wl_global_destroy(). Note that the destruction of a global is still * racy, since clients have no way to acknowledge that they received the remove * event. * * \since 1.17.90 */ WL_EXPORT void wl_global_remove(struct wl_global *global) { … } WL_EXPORT void wl_global_destroy(struct wl_global *global) { … } WL_EXPORT const struct wl_interface * wl_global_get_interface(const struct wl_global *global) { … } /** Get the name of the global. * * \param global The global object. * \param client Client for which to look up the global. * \return The name of the global, or 0 if the global is not visible to the * client. * * \memberof wl_global * \since 1.22 */ WL_EXPORT uint32_t wl_global_get_name(const struct wl_global *global, const struct wl_client *client) { … } /** Get the version of the given global. * * \param global The global object. * \return The version advertised by the global. * * \memberof wl_global * \since 1.21 */ WL_EXPORT uint32_t wl_global_get_version(const struct wl_global *global) { … } /** Get the display object for the given global * * \param global The global object * \return The display object the global is associated with. * * \memberof wl_global * \since 1.20 */ WL_EXPORT struct wl_display * wl_global_get_display(const struct wl_global *global) { … } WL_EXPORT void * wl_global_get_user_data(const struct wl_global *global) { … } /** Set the global's user data * * \param global The global object * \param data The user data pointer * * \since 1.17.90 */ WL_EXPORT void wl_global_set_user_data(struct wl_global *global, void *data) { … } /** Get the current serial number * * \param display The display object * * This function returns the most recent serial number, but does not * increment it. * * \memberof wl_display */ WL_EXPORT uint32_t wl_display_get_serial(struct wl_display *display) { … } /** Get the next serial number * * \param display The display object * * This function increments the display serial number and returns the * new value. * * \memberof wl_display */ WL_EXPORT uint32_t wl_display_next_serial(struct wl_display *display) { … } WL_EXPORT struct wl_event_loop * wl_display_get_event_loop(struct wl_display *display) { … } WL_EXPORT void wl_display_terminate(struct wl_display *display) { … } WL_EXPORT void wl_display_run(struct wl_display *display) { … } WL_EXPORT void wl_display_flush_clients(struct wl_display *display) { … } /** Destroy all clients connected to the display * * \param display The display object * * This function should be called right before wl_display_destroy() to ensure * all client resources are closed properly. Destroying a client from within * wl_display_destroy_clients() is safe, but creating one will leak resources * and raise a warning. * * \memberof wl_display */ WL_EXPORT void wl_display_destroy_clients(struct wl_display *display) { … } /** Sets the default maximum size for connection buffers of new clients * * \param display The display object * \param max_buffer_size The default maximum size of the connection buffers * * This function sets the default size of the internal connection buffers for * new clients. It doesn't change the buffer size for existing wl_client. * * The connection buffer size of an existing wl_client can be adjusted using * wl_client_set_max_buffer_size(). * * The actual size of the connection buffers is a power of two, the requested * \a max_buffer_size is therefore rounded up to the nearest power of two value. * * The minimum buffer size is 4096. * * \sa wl_client_set_max_buffer_size * * \memberof wl_display * \since 1.22.90 */ WL_EXPORT void wl_display_set_default_max_buffer_size(struct wl_display *display, size_t max_buffer_size) { … } static int socket_data(int fd, uint32_t mask, void *data) { … } static int wl_socket_lock(struct wl_socket *socket) { … } static int wl_socket_init_for_display_name(struct wl_socket *s, const char *name) { … } static int _wl_display_add_socket(struct wl_display *display, struct wl_socket *s) { … } WL_EXPORT const char * wl_display_add_socket_auto(struct wl_display *display) { … } /** Add a socket with an existing fd to Wayland display for the clients to connect. * * \param display Wayland display to which the socket should be added. * \param sock_fd The existing socket file descriptor to be used * \return 0 if success. -1 if failed. * * The existing socket fd must already be created, opened, and locked. * The fd must be properly set to CLOEXEC and bound to a socket file * with both bind() and listen() already called. * * On success, the socket fd ownership is transferred to libwayland: * libwayland will close the socket when the display is destroyed. * * \memberof wl_display */ WL_EXPORT int wl_display_add_socket_fd(struct wl_display *display, int sock_fd) { … } /** Add a socket to Wayland display for the clients to connect. * * \param display Wayland display to which the socket should be added. * \param name Name of the Unix socket. * \return 0 if success. -1 if failed. * * This adds a Unix socket to Wayland display which can be used by clients to * connect to Wayland display. * * If NULL is passed as name, then it would look for WAYLAND_DISPLAY env * variable for the socket name. If WAYLAND_DISPLAY is not set, then default * wayland-0 is used. * * If the socket name is a relative path, the Unix socket will be created in * the directory pointed to by environment variable XDG_RUNTIME_DIR. If * XDG_RUNTIME_DIR is invalid or not set, then this function fails and returns -1. * * If the socket name is an absolute path, then it is used as-is for the * the Unix socket. * * The length of the computed socket path must not exceed the maximum length * of a Unix socket path. * The function also fails if the user does not have write permission in the * directory or if the path is already in use. * * \memberof wl_display */ WL_EXPORT int wl_display_add_socket(struct wl_display *display, const char *name) { … } WL_EXPORT void wl_display_add_destroy_listener(struct wl_display *display, struct wl_listener *listener) { … } /** Registers a listener for the client connection signal. * When a new client object is created, \a listener will be notified, carrying * a pointer to the new wl_client object. * * \ref wl_client_create * \ref wl_display * \ref wl_listener * * \param display The display object * \param listener Signal handler object */ WL_EXPORT void wl_display_add_client_created_listener(struct wl_display *display, struct wl_listener *listener) { … } WL_EXPORT struct wl_listener * wl_display_get_destroy_listener(struct wl_display *display, wl_notify_func_t notify) { … } WL_EXPORT void wl_resource_set_implementation(struct wl_resource *resource, const void *implementation, void *data, wl_resource_destroy_func_t destroy) { … } WL_EXPORT void wl_resource_set_dispatcher(struct wl_resource *resource, wl_dispatcher_func_t dispatcher, const void *implementation, void *data, wl_resource_destroy_func_t destroy) { … } /** Create a new resource object * * \param client The client owner of the new resource. * \param interface The interface of the new resource. * \param version The version of the new resource. * \param id The id of the new resource. If 0, an available id will be used. * * Listeners added with \a wl_client_add_resource_created_listener will be * notified at the end of this function. * * \memberof wl_resource */ WL_EXPORT struct wl_resource * wl_resource_create(struct wl_client *client, const struct wl_interface *interface, int version, uint32_t id) { … } WL_EXPORT void wl_log_set_handler_server(wl_log_func_t handler) { … } /** Adds a new protocol logger. * * When a new protocol message arrives or is sent from the server * all the protocol logger functions will be called, carrying the * \a user_data pointer, the type of the message (request or * event) and the actual message. * The lifetime of the messages passed to the logger function ends * when they return so the messages cannot be stored and accessed * later. * * \a errno is set on error. * * \param display The display object * \param func The function to call to log a new protocol message * \param user_data The user data pointer to pass to \a func * * \return The protol logger object on success, NULL on failure. * * \sa wl_protocol_logger_destroy * * \memberof wl_display */ WL_EXPORT struct wl_protocol_logger * wl_display_add_protocol_logger(struct wl_display *display, wl_protocol_logger_func_t func, void *user_data) { … } /** Destroys a protocol logger. * * This function destroys a protocol logger and removes it from the display * it was added to with \a wl_display_add_protocol_logger. * The \a logger object becomes invalid after calling this function. * * \sa wl_display_add_protocol_logger * * \memberof wl_protocol_logger */ WL_EXPORT void wl_protocol_logger_destroy(struct wl_protocol_logger *logger) { … } /** Add support for a wl_shm pixel format * * \param display The display object * \param format The wl_shm pixel format to advertise * \return A pointer to the wl_shm format that was added to the list * or NULL if adding it to the list failed. * * Add the specified wl_shm format to the list of formats the wl_shm * object advertises when a client binds to it. Adding a format to * the list means that clients will know that the compositor supports * this format and may use it for creating wl_shm buffers. The * compositor must be able to handle the pixel format when a client * requests it. * * The compositor by default supports WL_SHM_FORMAT_ARGB8888 and * WL_SHM_FORMAT_XRGB8888. * * \memberof wl_display */ WL_EXPORT uint32_t * wl_display_add_shm_format(struct wl_display *display, uint32_t format) { … } /** * Get list of additional wl_shm pixel formats * * \param display The display object * * This function returns the list of addition wl_shm pixel formats * that the compositor supports. WL_SHM_FORMAT_ARGB8888 and * WL_SHM_FORMAT_XRGB8888 are always supported and not included in the * array, but all formats added through wl_display_add_shm_format() * will be in the array. * * \sa wl_display_add_shm_format() * * \private * * \memberof wl_display */ struct wl_array * wl_display_get_additional_shm_formats(struct wl_display *display) { … } /** Get the list of currently connected clients * * \param display The display object * * This function returns a pointer to the list of clients currently * connected to the display. You can iterate on the list by using * the \a wl_client_for_each macro. * The returned value is valid for the lifetime of the \a display. * You must not modify the returned list, but only access it. * * \sa wl_client_for_each() * \sa wl_client_get_link() * \sa wl_client_from_link() * * \memberof wl_display */ WL_EXPORT struct wl_list * wl_display_get_client_list(struct wl_display *display) { … } /** Get the link by which a client is inserted in the client list * * \param client The client object * * \sa wl_client_for_each() * \sa wl_display_get_client_list() * \sa wl_client_from_link() * * \memberof wl_client */ WL_EXPORT struct wl_list * wl_client_get_link(struct wl_client *client) { … } /** Get a wl_client by its link * * \param link The link of a wl_client * * \sa wl_client_for_each() * \sa wl_display_get_client_list() * \sa wl_client_get_link() * * \memberof wl_client */ WL_EXPORT struct wl_client * wl_client_from_link(struct wl_list *link) { … } /** Add a listener for the client's resource creation signal * * \param client The client object * \param listener The listener to be added * * When a new resource is created for this client the listener * will be notified, carrying the new resource as the data argument. * * \memberof wl_client */ WL_EXPORT void wl_client_add_resource_created_listener(struct wl_client *client, struct wl_listener *listener) { … } struct wl_resource_iterator_context { … }; static enum wl_iterator_result resource_iterator_helper(void *res, void *user_data, uint32_t flags) { … } /** Iterate over all the resources of a client * * \param client The client object * \param iterator The iterator function * \param user_data The user data pointer * * The function pointed by \a iterator will be called for each * resource owned by the client. The \a user_data will be passed * as the second argument of the iterator function. * If the \a iterator function returns \a WL_ITERATOR_CONTINUE the iteration * will continue, if it returns \a WL_ITERATOR_STOP it will stop. * * Creating and destroying resources while iterating is safe, but new * resources may or may not be picked up by the iterator. * * \sa wl_iterator_result * * \memberof wl_client */ WL_EXPORT void wl_client_for_each_resource(struct wl_client *client, wl_client_for_each_resource_iterator_func_t iterator, void *user_data) { … } static void handle_noop(struct wl_listener *listener, void *data) { … } /** Emits this signal, notifying all registered listeners. * * A safer version of wl_signal_emit() which can gracefully handle additions * and deletions of any signal listener from within listener notification * callbacks. * * Listeners deleted during a signal emission and which have not already been * notified at the time of deletion are not notified by that emission. * * Listeners added (or readded) during signal emission are ignored by that * emission. * * Note that repurposing a listener without explicitly removing it and readding * it is not supported and can lead to unexpected behavior. * * \param signal The signal object that will emit the signal * \param data The data that will be emitted with the signal * * \memberof wl_signal * \since 1.20.90 */ WL_EXPORT void wl_signal_emit_mutable(struct wl_signal *signal, void *data) { … } /** Adjust the maximum size of the client connection buffers * * \param client The client object * \param max_buffer_size The maximum size of the connection buffers * * The actual size of the connection buffers is a power of two, the requested * \a max_buffer_size is therefore rounded up to the nearest power of two value. * * Lowering the maximum size may not take effect immediately if the current content * of the buffer does not fit within the new size limit. * * The minimum buffer size is 4096. The default buffers size can be set using * wl_display_set_default_max_buffer_size(). * * \sa wl_display_set_default_max_buffer_size() * * \memberof wl_client * \since 1.22.90 */ WL_EXPORT void wl_client_set_max_buffer_size(struct wl_client *client, size_t max_buffer_size) { … } /** \cond INTERNAL */ /** Initialize a wl_priv_signal object * * wl_priv_signal is a safer implementation of a signal type, with the same API * as wl_signal, but kept as a private utility of libwayland-server. * It is safer because listeners can be removed from within wl_priv_signal_emit() * without corrupting the signal's list. * * Before passing a wl_priv_signal object to any other function it must be * initialized by using wl_priv_signal_init(). * * \memberof wl_priv_signal */ void wl_priv_signal_init(struct wl_priv_signal *signal) { … } /** Add a listener to a signal * * The new listener will be called when calling wl_signal_emit(). If a listener is * added to the signal while wl_signal_emit() is running it will be called from * the next time wl_priv_signal_emit() is called. * To remove a listener call wl_list_remove() on its link member. * * \memberof wl_priv_signal */ void wl_priv_signal_add(struct wl_priv_signal *signal, struct wl_listener *listener) { … } /** Get a listener added to a signal * * Returns the listener added to the given \a signal and with the given * \a notify function, or NULL if there isn't any. * Calling this function from within wl_priv_signal_emit() is safe and will * return the correct value. * * \memberof wl_priv_signal */ struct wl_listener * wl_priv_signal_get(struct wl_priv_signal *signal, wl_notify_func_t notify) { … } /** Emit the signal, calling all the installed listeners * * Iterate over all the listeners added to this \a signal and call * their \a notify function pointer, passing on the given \a data. * Removing or adding a listener from within wl_priv_signal_emit() * is safe. */ void wl_priv_signal_emit(struct wl_priv_signal *signal, void *data) { … } /** Emit the signal for the last time, calling all the installed listeners * * Iterate over all the listeners added to this \a signal and call * their \a notify function pointer, passing on the given \a data. * Removing or adding a listener from within wl_priv_signal_emit() * is safe, as is freeing the structure containing the listener. * * A large body of external code assumes it's ok to free a destruction * listener without removing that listener from the list. Mixing code * that acts like this and code that doesn't will result in list * corruption. * * We resolve this by removing each item from the list and isolating it * in another list. We discard it completely after firing the notifier. * This should allow interoperability between code that unlinks its * destruction listeners and code that just frees structures they're in. * */ void wl_priv_signal_final_emit(struct wl_priv_signal *signal, void *data) { … } /** \endcond INTERNAL */ /** \cond */ /* Deprecated functions below. */ uint32_t wl_client_add_resource(struct wl_client *client, struct wl_resource *resource) WL_DEPRECATED; WL_EXPORT uint32_t wl_client_add_resource(struct wl_client *client, struct wl_resource *resource) { … } struct wl_resource * wl_client_add_object(struct wl_client *client, const struct wl_interface *interface, const void *implementation, uint32_t id, void *data) WL_DEPRECATED; WL_EXPORT struct wl_resource * wl_client_add_object(struct wl_client *client, const struct wl_interface *interface, const void *implementation, uint32_t id, void *data) { … } struct wl_resource * wl_client_new_object(struct wl_client *client, const struct wl_interface *interface, const void *implementation, void *data) WL_DEPRECATED; WL_EXPORT struct wl_resource * wl_client_new_object(struct wl_client *client, const struct wl_interface *interface, const void *implementation, void *data) { … } /** Set the client's user data * * User data is whatever the caller wants to store. Use dtor if * the user data needs freeing as the very last step of destroying * the client. * * \param client The client object * \param data The user data pointer * \param dtor Destroy function to be called after all resources have been * destroyed and all destroy listeners have been called. Can be NULL. * * The argument to the destroy function is the user data pointer. If the * destroy function is not NULL, it will be called even if user data is NULL. * * \since 1.22.90 * \sa wl_client_get_user_data */ WL_EXPORT void wl_client_set_user_data(struct wl_client *client, void *data, wl_user_data_destroy_func_t dtor) { … } /** Get the client's user data * * \param client The client object * \return The user data pointer * * \since 1.22.90 * \sa wl_client_set_user_data */ WL_EXPORT void * wl_client_get_user_data(struct wl_client *client) { … } struct wl_global * wl_display_add_global(struct wl_display *display, const struct wl_interface *interface, void *data, wl_global_bind_func_t bind) WL_DEPRECATED; WL_EXPORT struct wl_global * wl_display_add_global(struct wl_display *display, const struct wl_interface *interface, void *data, wl_global_bind_func_t bind) { … } void wl_display_remove_global(struct wl_display *display, struct wl_global *global) WL_DEPRECATED; WL_EXPORT void wl_display_remove_global(struct wl_display *display, struct wl_global *global) { … } /** \endcond */ /* Functions at the end of this file are deprecated. Instead of adding new * code here, add it before the comment above that states: * Deprecated functions below. */