xref: /aosp_15_r20/external/wayland/src/wayland-server.c (revision 84e872a0dc482bffdb63672969dd03a827d67c73)
1*84e872a0SLloyd Pique /*
2*84e872a0SLloyd Pique  * Copyright © 2008 Kristian Høgsberg
3*84e872a0SLloyd Pique  *
4*84e872a0SLloyd Pique  * Permission is hereby granted, free of charge, to any person obtaining
5*84e872a0SLloyd Pique  * a copy of this software and associated documentation files (the
6*84e872a0SLloyd Pique  * "Software"), to deal in the Software without restriction, including
7*84e872a0SLloyd Pique  * without limitation the rights to use, copy, modify, merge, publish,
8*84e872a0SLloyd Pique  * distribute, sublicense, and/or sell copies of the Software, and to
9*84e872a0SLloyd Pique  * permit persons to whom the Software is furnished to do so, subject to
10*84e872a0SLloyd Pique  * the following conditions:
11*84e872a0SLloyd Pique  *
12*84e872a0SLloyd Pique  * The above copyright notice and this permission notice (including the
13*84e872a0SLloyd Pique  * next paragraph) shall be included in all copies or substantial
14*84e872a0SLloyd Pique  * portions of the Software.
15*84e872a0SLloyd Pique  *
16*84e872a0SLloyd Pique  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17*84e872a0SLloyd Pique  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18*84e872a0SLloyd Pique  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19*84e872a0SLloyd Pique  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20*84e872a0SLloyd Pique  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21*84e872a0SLloyd Pique  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22*84e872a0SLloyd Pique  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23*84e872a0SLloyd Pique  * SOFTWARE.
24*84e872a0SLloyd Pique  */
25*84e872a0SLloyd Pique 
26*84e872a0SLloyd Pique #define _GNU_SOURCE
27*84e872a0SLloyd Pique 
28*84e872a0SLloyd Pique #include <stdbool.h>
29*84e872a0SLloyd Pique #include <stdlib.h>
30*84e872a0SLloyd Pique #include <stdint.h>
31*84e872a0SLloyd Pique #include <stddef.h>
32*84e872a0SLloyd Pique #include <stdio.h>
33*84e872a0SLloyd Pique #include <stdarg.h>
34*84e872a0SLloyd Pique #include <errno.h>
35*84e872a0SLloyd Pique #include <string.h>
36*84e872a0SLloyd Pique #include <unistd.h>
37*84e872a0SLloyd Pique #include <sys/socket.h>
38*84e872a0SLloyd Pique #include <sys/un.h>
39*84e872a0SLloyd Pique #include <dlfcn.h>
40*84e872a0SLloyd Pique #include <assert.h>
41*84e872a0SLloyd Pique #include <sys/time.h>
42*84e872a0SLloyd Pique #include <fcntl.h>
43*84e872a0SLloyd Pique #include <sys/eventfd.h>
44*84e872a0SLloyd Pique #include <sys/file.h>
45*84e872a0SLloyd Pique #include <sys/stat.h>
46*84e872a0SLloyd Pique 
47*84e872a0SLloyd Pique #include "wayland-util.h"
48*84e872a0SLloyd Pique #include "wayland-private.h"
49*84e872a0SLloyd Pique #include "wayland-server-private.h"
50*84e872a0SLloyd Pique #include "wayland-server.h"
51*84e872a0SLloyd Pique #include "wayland-os.h"
52*84e872a0SLloyd Pique 
53*84e872a0SLloyd Pique /* This is the size of the char array in struct sock_addr_un.
54*84e872a0SLloyd Pique  * No Wayland socket can be created with a path longer than this,
55*84e872a0SLloyd Pique  * including the null terminator.
56*84e872a0SLloyd Pique  */
57*84e872a0SLloyd Pique #ifndef UNIX_PATH_MAX
58*84e872a0SLloyd Pique #define UNIX_PATH_MAX	108
59*84e872a0SLloyd Pique #endif
60*84e872a0SLloyd Pique 
61*84e872a0SLloyd Pique #define LOCK_SUFFIX	".lock"
62*84e872a0SLloyd Pique #define LOCK_SUFFIXLEN	5
63*84e872a0SLloyd Pique 
64*84e872a0SLloyd Pique struct wl_socket {
65*84e872a0SLloyd Pique 	int fd;
66*84e872a0SLloyd Pique 	int fd_lock;
67*84e872a0SLloyd Pique 	struct sockaddr_un addr;
68*84e872a0SLloyd Pique 	char lock_addr[UNIX_PATH_MAX + LOCK_SUFFIXLEN];
69*84e872a0SLloyd Pique 	struct wl_list link;
70*84e872a0SLloyd Pique 	struct wl_event_source *source;
71*84e872a0SLloyd Pique 	char *display_name;
72*84e872a0SLloyd Pique };
73*84e872a0SLloyd Pique 
74*84e872a0SLloyd Pique struct wl_client {
75*84e872a0SLloyd Pique 	struct wl_connection *connection;
76*84e872a0SLloyd Pique 	struct wl_event_source *source;
77*84e872a0SLloyd Pique 	struct wl_display *display;
78*84e872a0SLloyd Pique 	struct wl_resource *display_resource;
79*84e872a0SLloyd Pique 	struct wl_list link;
80*84e872a0SLloyd Pique 	struct wl_map objects;
81*84e872a0SLloyd Pique 	struct wl_priv_signal destroy_signal;
82*84e872a0SLloyd Pique 	struct wl_priv_signal destroy_late_signal;
83*84e872a0SLloyd Pique 	pid_t pid;
84*84e872a0SLloyd Pique 	uid_t uid;
85*84e872a0SLloyd Pique 	gid_t gid;
86*84e872a0SLloyd Pique 	int error;
87*84e872a0SLloyd Pique 	struct wl_priv_signal resource_created_signal;
88*84e872a0SLloyd Pique };
89*84e872a0SLloyd Pique 
90*84e872a0SLloyd Pique struct wl_display {
91*84e872a0SLloyd Pique 	struct wl_event_loop *loop;
92*84e872a0SLloyd Pique 	int run;
93*84e872a0SLloyd Pique 
94*84e872a0SLloyd Pique 	uint32_t next_global_name;
95*84e872a0SLloyd Pique 	uint32_t serial;
96*84e872a0SLloyd Pique 
97*84e872a0SLloyd Pique 	struct wl_list registry_resource_list;
98*84e872a0SLloyd Pique 	struct wl_list global_list;
99*84e872a0SLloyd Pique 	struct wl_list socket_list;
100*84e872a0SLloyd Pique 	struct wl_list client_list;
101*84e872a0SLloyd Pique 	struct wl_list protocol_loggers;
102*84e872a0SLloyd Pique 
103*84e872a0SLloyd Pique 	struct wl_priv_signal destroy_signal;
104*84e872a0SLloyd Pique 	struct wl_priv_signal create_client_signal;
105*84e872a0SLloyd Pique 
106*84e872a0SLloyd Pique 	struct wl_array additional_shm_formats;
107*84e872a0SLloyd Pique 
108*84e872a0SLloyd Pique 	wl_display_global_filter_func_t global_filter;
109*84e872a0SLloyd Pique 	void *global_filter_data;
110*84e872a0SLloyd Pique 
111*84e872a0SLloyd Pique 	int terminate_efd;
112*84e872a0SLloyd Pique 	struct wl_event_source *term_source;
113*84e872a0SLloyd Pique };
114*84e872a0SLloyd Pique 
115*84e872a0SLloyd Pique struct wl_global {
116*84e872a0SLloyd Pique 	struct wl_display *display;
117*84e872a0SLloyd Pique 	const struct wl_interface *interface;
118*84e872a0SLloyd Pique 	uint32_t name;
119*84e872a0SLloyd Pique 	uint32_t version;
120*84e872a0SLloyd Pique 	void *data;
121*84e872a0SLloyd Pique 	wl_global_bind_func_t bind;
122*84e872a0SLloyd Pique 	struct wl_list link;
123*84e872a0SLloyd Pique 	bool removed;
124*84e872a0SLloyd Pique };
125*84e872a0SLloyd Pique 
126*84e872a0SLloyd Pique struct wl_resource {
127*84e872a0SLloyd Pique 	struct wl_object object;
128*84e872a0SLloyd Pique 	wl_resource_destroy_func_t destroy;
129*84e872a0SLloyd Pique 	struct wl_list link;
130*84e872a0SLloyd Pique 	/* Unfortunately some users of libwayland (e.g. mesa) still use the
131*84e872a0SLloyd Pique 	 * deprecated wl_resource struct, even if creating it with the new
132*84e872a0SLloyd Pique 	 * wl_resource_create(). So we cannot change the layout of the struct
133*84e872a0SLloyd Pique 	 * unless after the data field. */
134*84e872a0SLloyd Pique 	struct wl_signal deprecated_destroy_signal;
135*84e872a0SLloyd Pique 	struct wl_client *client;
136*84e872a0SLloyd Pique 	void *data;
137*84e872a0SLloyd Pique 	int version;
138*84e872a0SLloyd Pique 	wl_dispatcher_func_t dispatcher;
139*84e872a0SLloyd Pique 	struct wl_priv_signal destroy_signal;
140*84e872a0SLloyd Pique };
141*84e872a0SLloyd Pique 
142*84e872a0SLloyd Pique struct wl_protocol_logger {
143*84e872a0SLloyd Pique 	struct wl_list link;
144*84e872a0SLloyd Pique 	wl_protocol_logger_func_t func;
145*84e872a0SLloyd Pique 	void *user_data;
146*84e872a0SLloyd Pique };
147*84e872a0SLloyd Pique 
148*84e872a0SLloyd Pique static int debug_server = 0;
149*84e872a0SLloyd Pique 
150*84e872a0SLloyd Pique static void
log_closure(struct wl_resource * resource,struct wl_closure * closure,int send)151*84e872a0SLloyd Pique log_closure(struct wl_resource *resource,
152*84e872a0SLloyd Pique 	    struct wl_closure *closure, int send)
153*84e872a0SLloyd Pique {
154*84e872a0SLloyd Pique 	struct wl_object *object = &resource->object;
155*84e872a0SLloyd Pique 	struct wl_display *display = resource->client->display;
156*84e872a0SLloyd Pique 	struct wl_protocol_logger *protocol_logger;
157*84e872a0SLloyd Pique 	struct wl_protocol_logger_message message;
158*84e872a0SLloyd Pique 
159*84e872a0SLloyd Pique 	if (debug_server)
160*84e872a0SLloyd Pique 		wl_closure_print(closure, object, send, NULL);
161*84e872a0SLloyd Pique 
162*84e872a0SLloyd Pique 	if (!wl_list_empty(&display->protocol_loggers)) {
163*84e872a0SLloyd Pique 		message.resource = resource;
164*84e872a0SLloyd Pique 		message.message_opcode = closure->opcode;
165*84e872a0SLloyd Pique 		message.message = closure->message;
166*84e872a0SLloyd Pique 		message.arguments_count = closure->count;
167*84e872a0SLloyd Pique 		message.arguments = closure->args;
168*84e872a0SLloyd Pique 		wl_list_for_each(protocol_logger,
169*84e872a0SLloyd Pique 				 &display->protocol_loggers, link) {
170*84e872a0SLloyd Pique 			protocol_logger->func(protocol_logger->user_data,
171*84e872a0SLloyd Pique 					      send ? WL_PROTOCOL_LOGGER_EVENT :
172*84e872a0SLloyd Pique 						     WL_PROTOCOL_LOGGER_REQUEST,
173*84e872a0SLloyd Pique 					      &message);
174*84e872a0SLloyd Pique 		}
175*84e872a0SLloyd Pique 	}
176*84e872a0SLloyd Pique }
177*84e872a0SLloyd Pique 
178*84e872a0SLloyd Pique static bool
verify_objects(struct wl_resource * resource,uint32_t opcode,union wl_argument * args)179*84e872a0SLloyd Pique verify_objects(struct wl_resource *resource, uint32_t opcode,
180*84e872a0SLloyd Pique 	       union wl_argument *args)
181*84e872a0SLloyd Pique {
182*84e872a0SLloyd Pique 	struct wl_object *object = &resource->object;
183*84e872a0SLloyd Pique 	const char *signature = object->interface->events[opcode].signature;
184*84e872a0SLloyd Pique 	struct argument_details arg;
185*84e872a0SLloyd Pique 	struct wl_resource *res;
186*84e872a0SLloyd Pique 	int count, i;
187*84e872a0SLloyd Pique 
188*84e872a0SLloyd Pique 	count = arg_count_for_signature(signature);
189*84e872a0SLloyd Pique 	for (i = 0; i < count; i++) {
190*84e872a0SLloyd Pique 		signature = get_next_argument(signature, &arg);
191*84e872a0SLloyd Pique 		switch (arg.type) {
192*84e872a0SLloyd Pique 		case 'n':
193*84e872a0SLloyd Pique 		case 'o':
194*84e872a0SLloyd Pique 			res = (struct wl_resource *) (args[i].o);
195*84e872a0SLloyd Pique 			if (res && res->client != resource->client) {
196*84e872a0SLloyd Pique 				wl_log("compositor bug: The compositor "
197*84e872a0SLloyd Pique 				       "tried to use an object from one "
198*84e872a0SLloyd Pique 				       "client in a '%s.%s' for a different "
199*84e872a0SLloyd Pique 				       "client.\n", object->interface->name,
200*84e872a0SLloyd Pique 				       object->interface->events[opcode].name);
201*84e872a0SLloyd Pique 				return false;
202*84e872a0SLloyd Pique 			}
203*84e872a0SLloyd Pique 		}
204*84e872a0SLloyd Pique 	}
205*84e872a0SLloyd Pique 	return true;
206*84e872a0SLloyd Pique }
207*84e872a0SLloyd Pique 
208*84e872a0SLloyd Pique static void
handle_array(struct wl_resource * resource,uint32_t opcode,union wl_argument * args,int (* send_func)(struct wl_closure *,struct wl_connection *))209*84e872a0SLloyd Pique handle_array(struct wl_resource *resource, uint32_t opcode,
210*84e872a0SLloyd Pique 	     union wl_argument *args,
211*84e872a0SLloyd Pique 	     int (*send_func)(struct wl_closure *, struct wl_connection *))
212*84e872a0SLloyd Pique {
213*84e872a0SLloyd Pique 	struct wl_closure *closure;
214*84e872a0SLloyd Pique 	struct wl_object *object = &resource->object;
215*84e872a0SLloyd Pique 
216*84e872a0SLloyd Pique 	if (resource->client->error)
217*84e872a0SLloyd Pique 		return;
218*84e872a0SLloyd Pique 
219*84e872a0SLloyd Pique 	if (!verify_objects(resource, opcode, args)) {
220*84e872a0SLloyd Pique 		resource->client->error = 1;
221*84e872a0SLloyd Pique 		return;
222*84e872a0SLloyd Pique 	}
223*84e872a0SLloyd Pique 
224*84e872a0SLloyd Pique 	closure = wl_closure_marshal(object, opcode, args,
225*84e872a0SLloyd Pique 				     &object->interface->events[opcode]);
226*84e872a0SLloyd Pique 
227*84e872a0SLloyd Pique 	if (closure == NULL) {
228*84e872a0SLloyd Pique 		resource->client->error = 1;
229*84e872a0SLloyd Pique 		return;
230*84e872a0SLloyd Pique 	}
231*84e872a0SLloyd Pique 
232*84e872a0SLloyd Pique 	log_closure(resource, closure, true);
233*84e872a0SLloyd Pique 
234*84e872a0SLloyd Pique 	if (send_func(closure, resource->client->connection))
235*84e872a0SLloyd Pique 		resource->client->error = 1;
236*84e872a0SLloyd Pique 
237*84e872a0SLloyd Pique 	wl_closure_destroy(closure);
238*84e872a0SLloyd Pique }
239*84e872a0SLloyd Pique 
240*84e872a0SLloyd Pique WL_EXPORT void
wl_resource_post_event_array(struct wl_resource * resource,uint32_t opcode,union wl_argument * args)241*84e872a0SLloyd Pique wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode,
242*84e872a0SLloyd Pique 			     union wl_argument *args)
243*84e872a0SLloyd Pique {
244*84e872a0SLloyd Pique 	handle_array(resource, opcode, args, wl_closure_send);
245*84e872a0SLloyd Pique }
246*84e872a0SLloyd Pique 
247*84e872a0SLloyd Pique WL_EXPORT void
wl_resource_post_event(struct wl_resource * resource,uint32_t opcode,...)248*84e872a0SLloyd Pique wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...)
249*84e872a0SLloyd Pique {
250*84e872a0SLloyd Pique 	union wl_argument args[WL_CLOSURE_MAX_ARGS];
251*84e872a0SLloyd Pique 	struct wl_object *object = &resource->object;
252*84e872a0SLloyd Pique 	va_list ap;
253*84e872a0SLloyd Pique 
254*84e872a0SLloyd Pique 	va_start(ap, opcode);
255*84e872a0SLloyd Pique 	wl_argument_from_va_list(object->interface->events[opcode].signature,
256*84e872a0SLloyd Pique 				 args, WL_CLOSURE_MAX_ARGS, ap);
257*84e872a0SLloyd Pique 	va_end(ap);
258*84e872a0SLloyd Pique 
259*84e872a0SLloyd Pique 	wl_resource_post_event_array(resource, opcode, args);
260*84e872a0SLloyd Pique }
261*84e872a0SLloyd Pique 
262*84e872a0SLloyd Pique 
263*84e872a0SLloyd Pique WL_EXPORT void
wl_resource_queue_event_array(struct wl_resource * resource,uint32_t opcode,union wl_argument * args)264*84e872a0SLloyd Pique wl_resource_queue_event_array(struct wl_resource *resource, uint32_t opcode,
265*84e872a0SLloyd Pique 			      union wl_argument *args)
266*84e872a0SLloyd Pique {
267*84e872a0SLloyd Pique 	handle_array(resource, opcode, args, wl_closure_queue);
268*84e872a0SLloyd Pique }
269*84e872a0SLloyd Pique 
270*84e872a0SLloyd Pique WL_EXPORT void
wl_resource_queue_event(struct wl_resource * resource,uint32_t opcode,...)271*84e872a0SLloyd Pique wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
272*84e872a0SLloyd Pique {
273*84e872a0SLloyd Pique 	union wl_argument args[WL_CLOSURE_MAX_ARGS];
274*84e872a0SLloyd Pique 	struct wl_object *object = &resource->object;
275*84e872a0SLloyd Pique 	va_list ap;
276*84e872a0SLloyd Pique 
277*84e872a0SLloyd Pique 	va_start(ap, opcode);
278*84e872a0SLloyd Pique 	wl_argument_from_va_list(object->interface->events[opcode].signature,
279*84e872a0SLloyd Pique 				 args, WL_CLOSURE_MAX_ARGS, ap);
280*84e872a0SLloyd Pique 	va_end(ap);
281*84e872a0SLloyd Pique 
282*84e872a0SLloyd Pique 	wl_resource_queue_event_array(resource, opcode, args);
283*84e872a0SLloyd Pique }
284*84e872a0SLloyd Pique 
285*84e872a0SLloyd Pique static void
wl_resource_post_error_vargs(struct wl_resource * resource,uint32_t code,const char * msg,va_list argp)286*84e872a0SLloyd Pique wl_resource_post_error_vargs(struct wl_resource *resource,
287*84e872a0SLloyd Pique 			     uint32_t code, const char *msg, va_list argp)
288*84e872a0SLloyd Pique {
289*84e872a0SLloyd Pique 	struct wl_client *client = resource->client;
290*84e872a0SLloyd Pique 	char buffer[128];
291*84e872a0SLloyd Pique 
292*84e872a0SLloyd Pique 	vsnprintf(buffer, sizeof buffer, msg, argp);
293*84e872a0SLloyd Pique 
294*84e872a0SLloyd Pique 	/*
295*84e872a0SLloyd Pique 	 * When a client aborts, its resources are destroyed in id order,
296*84e872a0SLloyd Pique 	 * which means the display resource is destroyed first. If destruction
297*84e872a0SLloyd Pique 	 * of any later resources results in a protocol error, we end up here
298*84e872a0SLloyd Pique 	 * with a NULL display_resource. Do not try to send errors to an
299*84e872a0SLloyd Pique 	 * already dead client.
300*84e872a0SLloyd Pique 	 */
301*84e872a0SLloyd Pique 	if (client->error || !client->display_resource)
302*84e872a0SLloyd Pique 		return;
303*84e872a0SLloyd Pique 
304*84e872a0SLloyd Pique 	wl_resource_post_event(client->display_resource,
305*84e872a0SLloyd Pique 			       WL_DISPLAY_ERROR, resource, code, buffer);
306*84e872a0SLloyd Pique 	client->error = 1;
307*84e872a0SLloyd Pique 
308*84e872a0SLloyd Pique }
309*84e872a0SLloyd Pique 
310*84e872a0SLloyd Pique WL_EXPORT void
wl_resource_post_error(struct wl_resource * resource,uint32_t code,const char * msg,...)311*84e872a0SLloyd Pique wl_resource_post_error(struct wl_resource *resource,
312*84e872a0SLloyd Pique 		       uint32_t code, const char *msg, ...)
313*84e872a0SLloyd Pique {
314*84e872a0SLloyd Pique 	va_list ap;
315*84e872a0SLloyd Pique 
316*84e872a0SLloyd Pique 	va_start(ap, msg);
317*84e872a0SLloyd Pique 	wl_resource_post_error_vargs(resource, code, msg, ap);
318*84e872a0SLloyd Pique 	va_end(ap);
319*84e872a0SLloyd Pique }
320*84e872a0SLloyd Pique 
321*84e872a0SLloyd Pique static void
destroy_client_with_error(struct wl_client * client,const char * reason)322*84e872a0SLloyd Pique destroy_client_with_error(struct wl_client *client, const char *reason)
323*84e872a0SLloyd Pique {
324*84e872a0SLloyd Pique 	wl_log("%s (pid %u)\n", reason, client->pid);
325*84e872a0SLloyd Pique 	wl_client_destroy(client);
326*84e872a0SLloyd Pique }
327*84e872a0SLloyd Pique 
328*84e872a0SLloyd Pique static int
wl_client_connection_data(int fd,uint32_t mask,void * data)329*84e872a0SLloyd Pique wl_client_connection_data(int fd, uint32_t mask, void *data)
330*84e872a0SLloyd Pique {
331*84e872a0SLloyd Pique 	struct wl_client *client = data;
332*84e872a0SLloyd Pique 	struct wl_connection *connection = client->connection;
333*84e872a0SLloyd Pique 	struct wl_resource *resource;
334*84e872a0SLloyd Pique 	struct wl_object *object;
335*84e872a0SLloyd Pique 	struct wl_closure *closure;
336*84e872a0SLloyd Pique 	const struct wl_message *message;
337*84e872a0SLloyd Pique 	uint32_t p[2];
338*84e872a0SLloyd Pique 	uint32_t resource_flags;
339*84e872a0SLloyd Pique 	int opcode, size, since;
340*84e872a0SLloyd Pique 	int len;
341*84e872a0SLloyd Pique 
342*84e872a0SLloyd Pique 	if (mask & WL_EVENT_HANGUP) {
343*84e872a0SLloyd Pique 		wl_client_destroy(client);
344*84e872a0SLloyd Pique 		return 1;
345*84e872a0SLloyd Pique 	}
346*84e872a0SLloyd Pique 
347*84e872a0SLloyd Pique 	if (mask & WL_EVENT_ERROR) {
348*84e872a0SLloyd Pique 		destroy_client_with_error(client, "socket error");
349*84e872a0SLloyd Pique 		return 1;
350*84e872a0SLloyd Pique 	}
351*84e872a0SLloyd Pique 
352*84e872a0SLloyd Pique 	if (mask & WL_EVENT_WRITABLE) {
353*84e872a0SLloyd Pique 		len = wl_connection_flush(connection);
354*84e872a0SLloyd Pique 		if (len < 0 && errno != EAGAIN) {
355*84e872a0SLloyd Pique 			destroy_client_with_error(
356*84e872a0SLloyd Pique 			    client, "failed to flush client connection");
357*84e872a0SLloyd Pique 			return 1;
358*84e872a0SLloyd Pique 		} else if (len >= 0) {
359*84e872a0SLloyd Pique 			wl_event_source_fd_update(client->source,
360*84e872a0SLloyd Pique 						  WL_EVENT_READABLE);
361*84e872a0SLloyd Pique 		}
362*84e872a0SLloyd Pique 	}
363*84e872a0SLloyd Pique 
364*84e872a0SLloyd Pique 	len = 0;
365*84e872a0SLloyd Pique 	if (mask & WL_EVENT_READABLE) {
366*84e872a0SLloyd Pique 		len = wl_connection_read(connection);
367*84e872a0SLloyd Pique 		if (len == 0 || (len < 0 && errno != EAGAIN)) {
368*84e872a0SLloyd Pique 			destroy_client_with_error(
369*84e872a0SLloyd Pique 			    client, "failed to read client connection");
370*84e872a0SLloyd Pique 			return 1;
371*84e872a0SLloyd Pique 		}
372*84e872a0SLloyd Pique 	}
373*84e872a0SLloyd Pique 
374*84e872a0SLloyd Pique 	while (len >= 0 && (size_t) len >= sizeof p) {
375*84e872a0SLloyd Pique 		wl_connection_copy(connection, p, sizeof p);
376*84e872a0SLloyd Pique 		opcode = p[1] & 0xffff;
377*84e872a0SLloyd Pique 		size = p[1] >> 16;
378*84e872a0SLloyd Pique 		if (len < size)
379*84e872a0SLloyd Pique 			break;
380*84e872a0SLloyd Pique 
381*84e872a0SLloyd Pique 		resource = wl_map_lookup(&client->objects, p[0]);
382*84e872a0SLloyd Pique 		resource_flags = wl_map_lookup_flags(&client->objects, p[0]);
383*84e872a0SLloyd Pique 		if (resource == NULL) {
384*84e872a0SLloyd Pique 			wl_resource_post_error(client->display_resource,
385*84e872a0SLloyd Pique 					       WL_DISPLAY_ERROR_INVALID_OBJECT,
386*84e872a0SLloyd Pique 					       "invalid object %u", p[0]);
387*84e872a0SLloyd Pique 			break;
388*84e872a0SLloyd Pique 		}
389*84e872a0SLloyd Pique 
390*84e872a0SLloyd Pique 		object = &resource->object;
391*84e872a0SLloyd Pique 		if (opcode >= object->interface->method_count) {
392*84e872a0SLloyd Pique 			wl_resource_post_error(client->display_resource,
393*84e872a0SLloyd Pique 					       WL_DISPLAY_ERROR_INVALID_METHOD,
394*84e872a0SLloyd Pique 					       "invalid method %d, object %s@%u",
395*84e872a0SLloyd Pique 					       opcode,
396*84e872a0SLloyd Pique 					       object->interface->name,
397*84e872a0SLloyd Pique 					       object->id);
398*84e872a0SLloyd Pique 			break;
399*84e872a0SLloyd Pique 		}
400*84e872a0SLloyd Pique 
401*84e872a0SLloyd Pique 		message = &object->interface->methods[opcode];
402*84e872a0SLloyd Pique 		since = wl_message_get_since(message);
403*84e872a0SLloyd Pique 		if (!(resource_flags & WL_MAP_ENTRY_LEGACY) &&
404*84e872a0SLloyd Pique 		    resource->version > 0 && resource->version < since) {
405*84e872a0SLloyd Pique 			wl_resource_post_error(client->display_resource,
406*84e872a0SLloyd Pique 					       WL_DISPLAY_ERROR_INVALID_METHOD,
407*84e872a0SLloyd Pique 					       "invalid method %d (since %d < %d)"
408*84e872a0SLloyd Pique 					       ", object %s@%u",
409*84e872a0SLloyd Pique 					       opcode, resource->version, since,
410*84e872a0SLloyd Pique 					       object->interface->name,
411*84e872a0SLloyd Pique 					       object->id);
412*84e872a0SLloyd Pique 			break;
413*84e872a0SLloyd Pique 		}
414*84e872a0SLloyd Pique 
415*84e872a0SLloyd Pique 
416*84e872a0SLloyd Pique 		closure = wl_connection_demarshal(client->connection, size,
417*84e872a0SLloyd Pique 						  &client->objects, message);
418*84e872a0SLloyd Pique 
419*84e872a0SLloyd Pique 		if (closure == NULL && errno == ENOMEM) {
420*84e872a0SLloyd Pique 			wl_resource_post_no_memory(resource);
421*84e872a0SLloyd Pique 			break;
422*84e872a0SLloyd Pique 		} else if (closure == NULL ||
423*84e872a0SLloyd Pique 			   wl_closure_lookup_objects(closure, &client->objects) < 0) {
424*84e872a0SLloyd Pique 			wl_resource_post_error(client->display_resource,
425*84e872a0SLloyd Pique 					       WL_DISPLAY_ERROR_INVALID_METHOD,
426*84e872a0SLloyd Pique 					       "invalid arguments for %s@%u.%s",
427*84e872a0SLloyd Pique 					       object->interface->name,
428*84e872a0SLloyd Pique 					       object->id,
429*84e872a0SLloyd Pique 					       message->name);
430*84e872a0SLloyd Pique 			wl_closure_destroy(closure);
431*84e872a0SLloyd Pique 			break;
432*84e872a0SLloyd Pique 		}
433*84e872a0SLloyd Pique 
434*84e872a0SLloyd Pique 		log_closure(resource, closure, false);
435*84e872a0SLloyd Pique 
436*84e872a0SLloyd Pique 		if ((resource_flags & WL_MAP_ENTRY_LEGACY) ||
437*84e872a0SLloyd Pique 		    resource->dispatcher == NULL) {
438*84e872a0SLloyd Pique 			wl_closure_invoke(closure, WL_CLOSURE_INVOKE_SERVER,
439*84e872a0SLloyd Pique 					  object, opcode, client);
440*84e872a0SLloyd Pique 		} else {
441*84e872a0SLloyd Pique 			wl_closure_dispatch(closure, resource->dispatcher,
442*84e872a0SLloyd Pique 					    object, opcode);
443*84e872a0SLloyd Pique 		}
444*84e872a0SLloyd Pique 
445*84e872a0SLloyd Pique 		wl_closure_destroy(closure);
446*84e872a0SLloyd Pique 
447*84e872a0SLloyd Pique 		if (client->error)
448*84e872a0SLloyd Pique 			break;
449*84e872a0SLloyd Pique 
450*84e872a0SLloyd Pique 		len = wl_connection_pending_input(connection);
451*84e872a0SLloyd Pique 	}
452*84e872a0SLloyd Pique 
453*84e872a0SLloyd Pique 	if (client->error) {
454*84e872a0SLloyd Pique 		destroy_client_with_error(client,
455*84e872a0SLloyd Pique 					  "error in client communication");
456*84e872a0SLloyd Pique 	}
457*84e872a0SLloyd Pique 
458*84e872a0SLloyd Pique 	return 1;
459*84e872a0SLloyd Pique }
460*84e872a0SLloyd Pique 
461*84e872a0SLloyd Pique /** Flush pending events to the client
462*84e872a0SLloyd Pique  *
463*84e872a0SLloyd Pique  * \param client The client object
464*84e872a0SLloyd Pique  *
465*84e872a0SLloyd Pique  * Events sent to clients are queued in a buffer and written to the
466*84e872a0SLloyd Pique  * socket later - typically when the compositor has handled all
467*84e872a0SLloyd Pique  * requests and goes back to block in the event loop.  This function
468*84e872a0SLloyd Pique  * flushes all queued up events for a client immediately.
469*84e872a0SLloyd Pique  *
470*84e872a0SLloyd Pique  * \memberof wl_client
471*84e872a0SLloyd Pique  */
472*84e872a0SLloyd Pique WL_EXPORT void
wl_client_flush(struct wl_client * client)473*84e872a0SLloyd Pique wl_client_flush(struct wl_client *client)
474*84e872a0SLloyd Pique {
475*84e872a0SLloyd Pique 	wl_connection_flush(client->connection);
476*84e872a0SLloyd Pique }
477*84e872a0SLloyd Pique 
478*84e872a0SLloyd Pique /** Get the display object for the given client
479*84e872a0SLloyd Pique  *
480*84e872a0SLloyd Pique  * \param client The client object
481*84e872a0SLloyd Pique  * \return The display object the client is associated with.
482*84e872a0SLloyd Pique  *
483*84e872a0SLloyd Pique  * \memberof wl_client
484*84e872a0SLloyd Pique  */
485*84e872a0SLloyd Pique WL_EXPORT struct wl_display *
wl_client_get_display(struct wl_client * client)486*84e872a0SLloyd Pique wl_client_get_display(struct wl_client *client)
487*84e872a0SLloyd Pique {
488*84e872a0SLloyd Pique 	return client->display;
489*84e872a0SLloyd Pique }
490*84e872a0SLloyd Pique 
491*84e872a0SLloyd Pique static int
492*84e872a0SLloyd Pique bind_display(struct wl_client *client, struct wl_display *display);
493*84e872a0SLloyd Pique 
494*84e872a0SLloyd Pique /** Create a client for the given file descriptor
495*84e872a0SLloyd Pique  *
496*84e872a0SLloyd Pique  * \param display The display object
497*84e872a0SLloyd Pique  * \param fd The file descriptor for the socket to the client
498*84e872a0SLloyd Pique  * \return The new client object or NULL on failure.
499*84e872a0SLloyd Pique  *
500*84e872a0SLloyd Pique  * Given a file descriptor corresponding to one end of a socket, this
501*84e872a0SLloyd Pique  * function will create a wl_client struct and add the new client to
502*84e872a0SLloyd Pique  * the compositors client list.  At that point, the client is
503*84e872a0SLloyd Pique  * initialized and ready to run, as if the client had connected to the
504*84e872a0SLloyd Pique  * servers listening socket.  When the client eventually sends
505*84e872a0SLloyd Pique  * requests to the compositor, the wl_client argument to the request
506*84e872a0SLloyd Pique  * handler will be the wl_client returned from this function.
507*84e872a0SLloyd Pique  *
508*84e872a0SLloyd Pique  * The other end of the socket can be passed to
509*84e872a0SLloyd Pique  * wl_display_connect_to_fd() on the client side or used with the
510*84e872a0SLloyd Pique  * WAYLAND_SOCKET environment variable on the client side.
511*84e872a0SLloyd Pique  *
512*84e872a0SLloyd Pique  * Listeners added with wl_display_add_client_created_listener() will
513*84e872a0SLloyd Pique  * be notified by this function after the client is fully constructed.
514*84e872a0SLloyd Pique  *
515*84e872a0SLloyd Pique  * On failure this function sets errno accordingly and returns NULL.
516*84e872a0SLloyd Pique  *
517*84e872a0SLloyd Pique  * \memberof wl_display
518*84e872a0SLloyd Pique  */
519*84e872a0SLloyd Pique WL_EXPORT struct wl_client *
wl_client_create(struct wl_display * display,int fd)520*84e872a0SLloyd Pique wl_client_create(struct wl_display *display, int fd)
521*84e872a0SLloyd Pique {
522*84e872a0SLloyd Pique 	struct wl_client *client;
523*84e872a0SLloyd Pique 
524*84e872a0SLloyd Pique 	client = zalloc(sizeof *client);
525*84e872a0SLloyd Pique 	if (client == NULL)
526*84e872a0SLloyd Pique 		return NULL;
527*84e872a0SLloyd Pique 
528*84e872a0SLloyd Pique 	wl_priv_signal_init(&client->resource_created_signal);
529*84e872a0SLloyd Pique 	client->display = display;
530*84e872a0SLloyd Pique 	client->source = wl_event_loop_add_fd(display->loop, fd,
531*84e872a0SLloyd Pique 					      WL_EVENT_READABLE,
532*84e872a0SLloyd Pique 					      wl_client_connection_data, client);
533*84e872a0SLloyd Pique 
534*84e872a0SLloyd Pique 	if (!client->source)
535*84e872a0SLloyd Pique 		goto err_client;
536*84e872a0SLloyd Pique 
537*84e872a0SLloyd Pique 	if (wl_os_socket_peercred(fd, &client->uid, &client->gid,
538*84e872a0SLloyd Pique 				  &client->pid) != 0)
539*84e872a0SLloyd Pique 		goto err_source;
540*84e872a0SLloyd Pique 
541*84e872a0SLloyd Pique 	client->connection = wl_connection_create(fd);
542*84e872a0SLloyd Pique 	if (client->connection == NULL)
543*84e872a0SLloyd Pique 		goto err_source;
544*84e872a0SLloyd Pique 
545*84e872a0SLloyd Pique 	wl_map_init(&client->objects, WL_MAP_SERVER_SIDE);
546*84e872a0SLloyd Pique 
547*84e872a0SLloyd Pique 	if (wl_map_insert_at(&client->objects, 0, 0, NULL) < 0)
548*84e872a0SLloyd Pique 		goto err_map;
549*84e872a0SLloyd Pique 
550*84e872a0SLloyd Pique 	wl_priv_signal_init(&client->destroy_signal);
551*84e872a0SLloyd Pique 	wl_priv_signal_init(&client->destroy_late_signal);
552*84e872a0SLloyd Pique 	if (bind_display(client, display) < 0)
553*84e872a0SLloyd Pique 		goto err_map;
554*84e872a0SLloyd Pique 
555*84e872a0SLloyd Pique 	wl_list_insert(display->client_list.prev, &client->link);
556*84e872a0SLloyd Pique 
557*84e872a0SLloyd Pique 	wl_priv_signal_emit(&display->create_client_signal, client);
558*84e872a0SLloyd Pique 
559*84e872a0SLloyd Pique 	return client;
560*84e872a0SLloyd Pique 
561*84e872a0SLloyd Pique err_map:
562*84e872a0SLloyd Pique 	wl_map_release(&client->objects);
563*84e872a0SLloyd Pique 	wl_connection_destroy(client->connection);
564*84e872a0SLloyd Pique err_source:
565*84e872a0SLloyd Pique 	wl_event_source_remove(client->source);
566*84e872a0SLloyd Pique err_client:
567*84e872a0SLloyd Pique 	free(client);
568*84e872a0SLloyd Pique 	return NULL;
569*84e872a0SLloyd Pique }
570*84e872a0SLloyd Pique 
571*84e872a0SLloyd Pique /** Return Unix credentials for the client
572*84e872a0SLloyd Pique  *
573*84e872a0SLloyd Pique  * \param client The display object
574*84e872a0SLloyd Pique  * \param pid Returns the process ID
575*84e872a0SLloyd Pique  * \param uid Returns the user ID
576*84e872a0SLloyd Pique  * \param gid Returns the group ID
577*84e872a0SLloyd Pique  *
578*84e872a0SLloyd Pique  * This function returns the process ID, the user ID and the group ID
579*84e872a0SLloyd Pique  * for the given client.  The credentials come from getsockopt() with
580*84e872a0SLloyd Pique  * SO_PEERCRED, on the client socket fd.  All the pointers can be
581*84e872a0SLloyd Pique  * NULL, if the caller is not interested in a particular ID.
582*84e872a0SLloyd Pique  *
583*84e872a0SLloyd Pique  * Note, process IDs are subject to race conditions and are not a reliable way
584*84e872a0SLloyd Pique  * to identify a client.
585*84e872a0SLloyd Pique  *
586*84e872a0SLloyd Pique  * Be aware that for clients that a compositor forks and execs and
587*84e872a0SLloyd Pique  * then connects using socketpair(), this function will return the
588*84e872a0SLloyd Pique  * credentials for the compositor.  The credentials for the socketpair
589*84e872a0SLloyd Pique  * are set at creation time in the compositor.
590*84e872a0SLloyd Pique  *
591*84e872a0SLloyd Pique  * \memberof wl_client
592*84e872a0SLloyd Pique  */
593*84e872a0SLloyd Pique WL_EXPORT void
wl_client_get_credentials(struct wl_client * client,pid_t * pid,uid_t * uid,gid_t * gid)594*84e872a0SLloyd Pique wl_client_get_credentials(struct wl_client *client,
595*84e872a0SLloyd Pique 			  pid_t *pid, uid_t *uid, gid_t *gid)
596*84e872a0SLloyd Pique {
597*84e872a0SLloyd Pique 	if (pid)
598*84e872a0SLloyd Pique 		*pid = client->pid;
599*84e872a0SLloyd Pique 	if (uid)
600*84e872a0SLloyd Pique 		*uid = client->uid;
601*84e872a0SLloyd Pique 	if (gid)
602*84e872a0SLloyd Pique 		*gid = client->gid;
603*84e872a0SLloyd Pique }
604*84e872a0SLloyd Pique 
605*84e872a0SLloyd Pique /** Get the file descriptor for the client
606*84e872a0SLloyd Pique  *
607*84e872a0SLloyd Pique  * \param client The display object
608*84e872a0SLloyd Pique  * \return The file descriptor to use for the connection
609*84e872a0SLloyd Pique  *
610*84e872a0SLloyd Pique  * This function returns the file descriptor for the given client.
611*84e872a0SLloyd Pique  *
612*84e872a0SLloyd Pique  * Be sure to use the file descriptor from the client for inspection only.
613*84e872a0SLloyd Pique  * If the caller does anything to the file descriptor that changes its state,
614*84e872a0SLloyd Pique  * it will likely cause problems.
615*84e872a0SLloyd Pique  *
616*84e872a0SLloyd Pique  * See also wl_client_get_credentials().
617*84e872a0SLloyd Pique  * It is recommended that you evaluate whether wl_client_get_credentials()
618*84e872a0SLloyd Pique  * can be applied to your use case instead of this function.
619*84e872a0SLloyd Pique  *
620*84e872a0SLloyd Pique  * If you would like to distinguish just between the client and the compositor
621*84e872a0SLloyd Pique  * itself from the client's request, it can be done by getting the client
622*84e872a0SLloyd Pique  * credentials and by checking the PID of the client and the compositor's PID.
623*84e872a0SLloyd Pique  * Regarding the case in which the socketpair() is being used, you need to be
624*84e872a0SLloyd Pique  * careful. Please note the documentation for wl_client_get_credentials().
625*84e872a0SLloyd Pique  *
626*84e872a0SLloyd Pique  * This function can be used for a compositor to validate a request from
627*84e872a0SLloyd Pique  * a client if there are additional information provided from the client's
628*84e872a0SLloyd Pique  * file descriptor. For instance, suppose you can get the security contexts
629*84e872a0SLloyd Pique  * from the client's file descriptor. The compositor can validate the client's
630*84e872a0SLloyd Pique  * request with the contexts and make a decision whether it permits or deny it.
631*84e872a0SLloyd Pique  *
632*84e872a0SLloyd Pique  * \memberof wl_client
633*84e872a0SLloyd Pique  */
634*84e872a0SLloyd Pique WL_EXPORT int
wl_client_get_fd(struct wl_client * client)635*84e872a0SLloyd Pique wl_client_get_fd(struct wl_client *client)
636*84e872a0SLloyd Pique {
637*84e872a0SLloyd Pique 	return wl_connection_get_fd(client->connection);
638*84e872a0SLloyd Pique }
639*84e872a0SLloyd Pique 
640*84e872a0SLloyd Pique /** Look up an object in the client name space
641*84e872a0SLloyd Pique  *
642*84e872a0SLloyd Pique  * \param client The client object
643*84e872a0SLloyd Pique  * \param id The object id
644*84e872a0SLloyd Pique  * \return The object or NULL if there is not object for the given ID
645*84e872a0SLloyd Pique  *
646*84e872a0SLloyd Pique  * This looks up an object in the client object name space by its
647*84e872a0SLloyd Pique  * object ID.
648*84e872a0SLloyd Pique  *
649*84e872a0SLloyd Pique  * \memberof wl_client
650*84e872a0SLloyd Pique  */
651*84e872a0SLloyd Pique WL_EXPORT struct wl_resource *
wl_client_get_object(struct wl_client * client,uint32_t id)652*84e872a0SLloyd Pique wl_client_get_object(struct wl_client *client, uint32_t id)
653*84e872a0SLloyd Pique {
654*84e872a0SLloyd Pique 	return wl_map_lookup(&client->objects, id);
655*84e872a0SLloyd Pique }
656*84e872a0SLloyd Pique 
657*84e872a0SLloyd Pique WL_EXPORT void
wl_client_post_no_memory(struct wl_client * client)658*84e872a0SLloyd Pique wl_client_post_no_memory(struct wl_client *client)
659*84e872a0SLloyd Pique {
660*84e872a0SLloyd Pique 	wl_resource_post_error(client->display_resource,
661*84e872a0SLloyd Pique 			       WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
662*84e872a0SLloyd Pique }
663*84e872a0SLloyd Pique 
664*84e872a0SLloyd Pique /** Report an internal server error
665*84e872a0SLloyd Pique  *
666*84e872a0SLloyd Pique  * \param client The client object
667*84e872a0SLloyd Pique  * \param msg A printf-style format string
668*84e872a0SLloyd Pique  * \param ... Format string arguments
669*84e872a0SLloyd Pique  *
670*84e872a0SLloyd Pique  * Report an unspecified internal implementation error and disconnect
671*84e872a0SLloyd Pique  * the client.
672*84e872a0SLloyd Pique  *
673*84e872a0SLloyd Pique  * \memberof wl_client
674*84e872a0SLloyd Pique  */
675*84e872a0SLloyd Pique WL_EXPORT void
wl_client_post_implementation_error(struct wl_client * client,char const * msg,...)676*84e872a0SLloyd Pique wl_client_post_implementation_error(struct wl_client *client,
677*84e872a0SLloyd Pique 				    char const *msg, ...)
678*84e872a0SLloyd Pique {
679*84e872a0SLloyd Pique 	va_list ap;
680*84e872a0SLloyd Pique 
681*84e872a0SLloyd Pique 	va_start(ap, msg);
682*84e872a0SLloyd Pique 	wl_resource_post_error_vargs(client->display_resource,
683*84e872a0SLloyd Pique 				     WL_DISPLAY_ERROR_IMPLEMENTATION,
684*84e872a0SLloyd Pique 				     msg, ap);
685*84e872a0SLloyd Pique 	va_end(ap);
686*84e872a0SLloyd Pique }
687*84e872a0SLloyd Pique 
688*84e872a0SLloyd Pique WL_EXPORT void
wl_resource_post_no_memory(struct wl_resource * resource)689*84e872a0SLloyd Pique wl_resource_post_no_memory(struct wl_resource *resource)
690*84e872a0SLloyd Pique {
691*84e872a0SLloyd Pique 	wl_resource_post_error(resource->client->display_resource,
692*84e872a0SLloyd Pique 			       WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
693*84e872a0SLloyd Pique }
694*84e872a0SLloyd Pique 
695*84e872a0SLloyd Pique /** Detect if a wl_resource uses the deprecated public definition.
696*84e872a0SLloyd Pique  *
697*84e872a0SLloyd Pique  * Before Wayland 1.2.0, the definition of struct wl_resource was public.
698*84e872a0SLloyd Pique  * It was made opaque just before 1.2.0, and later new fields were added.
699*84e872a0SLloyd Pique  * The new fields cannot be accessed if a program is using the deprecated
700*84e872a0SLloyd Pique  * definition, as there would not be memory allocated for them.
701*84e872a0SLloyd Pique  *
702*84e872a0SLloyd Pique  * The creation pattern for the deprecated definition was wl_resource_init()
703*84e872a0SLloyd Pique  * followed by wl_client_add_resource(). wl_resource_init() was an inline
704*84e872a0SLloyd Pique  * function and no longer exists, but binaries might still carry it.
705*84e872a0SLloyd Pique  * wl_client_add_resource() still exists for ABI compatibility.
706*84e872a0SLloyd Pique  */
707*84e872a0SLloyd Pique static bool
resource_is_deprecated(struct wl_resource * resource)708*84e872a0SLloyd Pique resource_is_deprecated(struct wl_resource *resource)
709*84e872a0SLloyd Pique {
710*84e872a0SLloyd Pique 	struct wl_map *map = &resource->client->objects;
711*84e872a0SLloyd Pique 	int id = resource->object.id;
712*84e872a0SLloyd Pique 
713*84e872a0SLloyd Pique 	/* wl_client_add_resource() marks deprecated resources with the flag. */
714*84e872a0SLloyd Pique 	if (wl_map_lookup_flags(map, id) & WL_MAP_ENTRY_LEGACY)
715*84e872a0SLloyd Pique 		return true;
716*84e872a0SLloyd Pique 
717*84e872a0SLloyd Pique 	return false;
718*84e872a0SLloyd Pique }
719*84e872a0SLloyd Pique 
720*84e872a0SLloyd Pique static enum wl_iterator_result
destroy_resource(void * element,void * data,uint32_t flags)721*84e872a0SLloyd Pique destroy_resource(void *element, void *data, uint32_t flags)
722*84e872a0SLloyd Pique {
723*84e872a0SLloyd Pique 	struct wl_resource *resource = element;
724*84e872a0SLloyd Pique 
725*84e872a0SLloyd Pique 	wl_signal_emit(&resource->deprecated_destroy_signal, resource);
726*84e872a0SLloyd Pique 	/* Don't emit the new signal for deprecated resources, as that would
727*84e872a0SLloyd Pique 	 * access memory outside the bounds of the deprecated struct */
728*84e872a0SLloyd Pique 	if (!resource_is_deprecated(resource))
729*84e872a0SLloyd Pique 		wl_priv_signal_final_emit(&resource->destroy_signal, resource);
730*84e872a0SLloyd Pique 
731*84e872a0SLloyd Pique 	if (resource->destroy)
732*84e872a0SLloyd Pique 		resource->destroy(resource);
733*84e872a0SLloyd Pique 
734*84e872a0SLloyd Pique 	if (!(flags & WL_MAP_ENTRY_LEGACY))
735*84e872a0SLloyd Pique 		free(resource);
736*84e872a0SLloyd Pique 
737*84e872a0SLloyd Pique 	return WL_ITERATOR_CONTINUE;
738*84e872a0SLloyd Pique }
739*84e872a0SLloyd Pique 
740*84e872a0SLloyd Pique WL_EXPORT void
wl_resource_destroy(struct wl_resource * resource)741*84e872a0SLloyd Pique wl_resource_destroy(struct wl_resource *resource)
742*84e872a0SLloyd Pique {
743*84e872a0SLloyd Pique 	struct wl_client *client = resource->client;
744*84e872a0SLloyd Pique 	uint32_t id;
745*84e872a0SLloyd Pique 	uint32_t flags;
746*84e872a0SLloyd Pique 
747*84e872a0SLloyd Pique 	id = resource->object.id;
748*84e872a0SLloyd Pique 	flags = wl_map_lookup_flags(&client->objects, id);
749*84e872a0SLloyd Pique 	destroy_resource(resource, NULL, flags);
750*84e872a0SLloyd Pique 
751*84e872a0SLloyd Pique 	if (id < WL_SERVER_ID_START) {
752*84e872a0SLloyd Pique 		if (client->display_resource) {
753*84e872a0SLloyd Pique 			wl_resource_queue_event(client->display_resource,
754*84e872a0SLloyd Pique 						WL_DISPLAY_DELETE_ID, id);
755*84e872a0SLloyd Pique 		}
756*84e872a0SLloyd Pique 		wl_map_insert_at(&client->objects, 0, id, NULL);
757*84e872a0SLloyd Pique 	} else {
758*84e872a0SLloyd Pique 		wl_map_remove(&client->objects, id);
759*84e872a0SLloyd Pique 	}
760*84e872a0SLloyd Pique }
761*84e872a0SLloyd Pique 
762*84e872a0SLloyd Pique WL_EXPORT uint32_t
wl_resource_get_id(struct wl_resource * resource)763*84e872a0SLloyd Pique wl_resource_get_id(struct wl_resource *resource)
764*84e872a0SLloyd Pique {
765*84e872a0SLloyd Pique 	return resource->object.id;
766*84e872a0SLloyd Pique }
767*84e872a0SLloyd Pique 
768*84e872a0SLloyd Pique WL_EXPORT struct wl_list *
wl_resource_get_link(struct wl_resource * resource)769*84e872a0SLloyd Pique wl_resource_get_link(struct wl_resource *resource)
770*84e872a0SLloyd Pique {
771*84e872a0SLloyd Pique 	return &resource->link;
772*84e872a0SLloyd Pique }
773*84e872a0SLloyd Pique 
774*84e872a0SLloyd Pique WL_EXPORT struct wl_resource *
wl_resource_from_link(struct wl_list * link)775*84e872a0SLloyd Pique wl_resource_from_link(struct wl_list *link)
776*84e872a0SLloyd Pique {
777*84e872a0SLloyd Pique 	struct wl_resource *resource;
778*84e872a0SLloyd Pique 
779*84e872a0SLloyd Pique 	return wl_container_of(link, resource, link);
780*84e872a0SLloyd Pique }
781*84e872a0SLloyd Pique 
782*84e872a0SLloyd Pique WL_EXPORT struct wl_resource *
wl_resource_find_for_client(struct wl_list * list,struct wl_client * client)783*84e872a0SLloyd Pique wl_resource_find_for_client(struct wl_list *list, struct wl_client *client)
784*84e872a0SLloyd Pique {
785*84e872a0SLloyd Pique 	struct wl_resource *resource;
786*84e872a0SLloyd Pique 
787*84e872a0SLloyd Pique 	if (client == NULL)
788*84e872a0SLloyd Pique 		return NULL;
789*84e872a0SLloyd Pique 
790*84e872a0SLloyd Pique 	wl_list_for_each(resource, list, link) {
791*84e872a0SLloyd Pique 		if (resource->client == client)
792*84e872a0SLloyd Pique 			return resource;
793*84e872a0SLloyd Pique 	}
794*84e872a0SLloyd Pique 
795*84e872a0SLloyd Pique 	return NULL;
796*84e872a0SLloyd Pique }
797*84e872a0SLloyd Pique 
798*84e872a0SLloyd Pique WL_EXPORT struct wl_client *
wl_resource_get_client(struct wl_resource * resource)799*84e872a0SLloyd Pique wl_resource_get_client(struct wl_resource *resource)
800*84e872a0SLloyd Pique {
801*84e872a0SLloyd Pique 	return resource->client;
802*84e872a0SLloyd Pique }
803*84e872a0SLloyd Pique 
804*84e872a0SLloyd Pique WL_EXPORT void
wl_resource_set_user_data(struct wl_resource * resource,void * data)805*84e872a0SLloyd Pique wl_resource_set_user_data(struct wl_resource *resource, void *data)
806*84e872a0SLloyd Pique {
807*84e872a0SLloyd Pique 	resource->data = data;
808*84e872a0SLloyd Pique }
809*84e872a0SLloyd Pique 
810*84e872a0SLloyd Pique WL_EXPORT void *
wl_resource_get_user_data(struct wl_resource * resource)811*84e872a0SLloyd Pique wl_resource_get_user_data(struct wl_resource *resource)
812*84e872a0SLloyd Pique {
813*84e872a0SLloyd Pique 	return resource->data;
814*84e872a0SLloyd Pique }
815*84e872a0SLloyd Pique 
816*84e872a0SLloyd Pique WL_EXPORT int
wl_resource_get_version(struct wl_resource * resource)817*84e872a0SLloyd Pique wl_resource_get_version(struct wl_resource *resource)
818*84e872a0SLloyd Pique {
819*84e872a0SLloyd Pique 	return resource->version;
820*84e872a0SLloyd Pique }
821*84e872a0SLloyd Pique 
822*84e872a0SLloyd Pique WL_EXPORT void
wl_resource_set_destructor(struct wl_resource * resource,wl_resource_destroy_func_t destroy)823*84e872a0SLloyd Pique wl_resource_set_destructor(struct wl_resource *resource,
824*84e872a0SLloyd Pique 			   wl_resource_destroy_func_t destroy)
825*84e872a0SLloyd Pique {
826*84e872a0SLloyd Pique 	resource->destroy = destroy;
827*84e872a0SLloyd Pique }
828*84e872a0SLloyd Pique 
829*84e872a0SLloyd Pique WL_EXPORT int
wl_resource_instance_of(struct wl_resource * resource,const struct wl_interface * interface,const void * implementation)830*84e872a0SLloyd Pique wl_resource_instance_of(struct wl_resource *resource,
831*84e872a0SLloyd Pique 			const struct wl_interface *interface,
832*84e872a0SLloyd Pique 			const void *implementation)
833*84e872a0SLloyd Pique {
834*84e872a0SLloyd Pique 	return wl_interface_equal(resource->object.interface, interface) &&
835*84e872a0SLloyd Pique 		resource->object.implementation == implementation;
836*84e872a0SLloyd Pique }
837*84e872a0SLloyd Pique 
838*84e872a0SLloyd Pique WL_EXPORT void
wl_resource_add_destroy_listener(struct wl_resource * resource,struct wl_listener * listener)839*84e872a0SLloyd Pique wl_resource_add_destroy_listener(struct wl_resource *resource,
840*84e872a0SLloyd Pique 				 struct wl_listener * listener)
841*84e872a0SLloyd Pique {
842*84e872a0SLloyd Pique 	if (resource_is_deprecated(resource))
843*84e872a0SLloyd Pique 		wl_signal_add(&resource->deprecated_destroy_signal, listener);
844*84e872a0SLloyd Pique 	else
845*84e872a0SLloyd Pique 		wl_priv_signal_add(&resource->destroy_signal, listener);
846*84e872a0SLloyd Pique }
847*84e872a0SLloyd Pique 
848*84e872a0SLloyd Pique WL_EXPORT struct wl_listener *
wl_resource_get_destroy_listener(struct wl_resource * resource,wl_notify_func_t notify)849*84e872a0SLloyd Pique wl_resource_get_destroy_listener(struct wl_resource *resource,
850*84e872a0SLloyd Pique 				 wl_notify_func_t notify)
851*84e872a0SLloyd Pique {
852*84e872a0SLloyd Pique 	if (resource_is_deprecated(resource))
853*84e872a0SLloyd Pique 		return wl_signal_get(&resource->deprecated_destroy_signal, notify);
854*84e872a0SLloyd Pique 	return wl_priv_signal_get(&resource->destroy_signal, notify);
855*84e872a0SLloyd Pique }
856*84e872a0SLloyd Pique 
857*84e872a0SLloyd Pique /** Retrieve the interface name (class) of a resource object.
858*84e872a0SLloyd Pique  *
859*84e872a0SLloyd Pique  * \param resource The resource object
860*84e872a0SLloyd Pique  *
861*84e872a0SLloyd Pique  * \memberof wl_resource
862*84e872a0SLloyd Pique  */
863*84e872a0SLloyd Pique WL_EXPORT const char *
wl_resource_get_class(struct wl_resource * resource)864*84e872a0SLloyd Pique wl_resource_get_class(struct wl_resource *resource)
865*84e872a0SLloyd Pique {
866*84e872a0SLloyd Pique 	return resource->object.interface->name;
867*84e872a0SLloyd Pique }
868*84e872a0SLloyd Pique 
869*84e872a0SLloyd Pique /** Safely converts an object into its corresponding resource
870*84e872a0SLloyd Pique  *
871*84e872a0SLloyd Pique  * \param object object to get the resource for
872*84e872a0SLloyd Pique  * \return A corresponding resource, or NULL on failure
873*84e872a0SLloyd Pique  *
874*84e872a0SLloyd Pique  * Safely converts an object into its corresponding resource.
875*84e872a0SLloyd Pique  *
876*84e872a0SLloyd Pique  * This is useful for implementing functions that are given a \c wl_argument
877*84e872a0SLloyd Pique  * array, and that need to do further introspection on the ".o" field, as it
878*84e872a0SLloyd Pique  * is otherwise an opaque type.
879*84e872a0SLloyd Pique  *
880*84e872a0SLloyd Pique  * \memberof wl_resource
881*84e872a0SLloyd Pique  */
882*84e872a0SLloyd Pique WL_EXPORT struct wl_resource *
wl_resource_from_object(struct wl_object * object)883*84e872a0SLloyd Pique wl_resource_from_object(struct wl_object *object)
884*84e872a0SLloyd Pique {
885*84e872a0SLloyd Pique 	struct wl_resource *resource;
886*84e872a0SLloyd Pique 	if (object == NULL)
887*84e872a0SLloyd Pique 		return NULL;
888*84e872a0SLloyd Pique 	return wl_container_of(object, resource, object);
889*84e872a0SLloyd Pique }
890*84e872a0SLloyd Pique 
891*84e872a0SLloyd Pique /**
892*84e872a0SLloyd Pique  * Add a listener to be called at the beginning of wl_client destruction
893*84e872a0SLloyd Pique  *
894*84e872a0SLloyd Pique  * The listener provided will be called when wl_client destroy has begun,
895*84e872a0SLloyd Pique  * before any of that client's resources have been destroyed.
896*84e872a0SLloyd Pique  *
897*84e872a0SLloyd Pique  * There is no requirement to remove the link of the wl_listener when the
898*84e872a0SLloyd Pique  * signal is emitted.
899*84e872a0SLloyd Pique  *
900*84e872a0SLloyd Pique  * \memberof wl_client
901*84e872a0SLloyd Pique  */
902*84e872a0SLloyd Pique WL_EXPORT void
wl_client_add_destroy_listener(struct wl_client * client,struct wl_listener * listener)903*84e872a0SLloyd Pique wl_client_add_destroy_listener(struct wl_client *client,
904*84e872a0SLloyd Pique 			       struct wl_listener *listener)
905*84e872a0SLloyd Pique {
906*84e872a0SLloyd Pique 	wl_priv_signal_add(&client->destroy_signal, listener);
907*84e872a0SLloyd Pique }
908*84e872a0SLloyd Pique 
909*84e872a0SLloyd Pique WL_EXPORT struct wl_listener *
wl_client_get_destroy_listener(struct wl_client * client,wl_notify_func_t notify)910*84e872a0SLloyd Pique wl_client_get_destroy_listener(struct wl_client *client,
911*84e872a0SLloyd Pique 			       wl_notify_func_t notify)
912*84e872a0SLloyd Pique {
913*84e872a0SLloyd Pique 	return wl_priv_signal_get(&client->destroy_signal, notify);
914*84e872a0SLloyd Pique }
915*84e872a0SLloyd Pique 
916*84e872a0SLloyd Pique /**
917*84e872a0SLloyd Pique  * Add a listener to be called at the end of wl_client destruction
918*84e872a0SLloyd Pique  *
919*84e872a0SLloyd Pique  * The listener provided will be called when wl_client destroy is nearly
920*84e872a0SLloyd Pique  * complete, after all of that client's resources have been destroyed.
921*84e872a0SLloyd Pique  *
922*84e872a0SLloyd Pique  * There is no requirement to remove the link of the wl_listener when the
923*84e872a0SLloyd Pique  * signal is emitted.
924*84e872a0SLloyd Pique  *
925*84e872a0SLloyd Pique  * \memberof wl_client
926*84e872a0SLloyd Pique  * \since 1.22.0
927*84e872a0SLloyd Pique  */
928*84e872a0SLloyd Pique WL_EXPORT void
wl_client_add_destroy_late_listener(struct wl_client * client,struct wl_listener * listener)929*84e872a0SLloyd Pique wl_client_add_destroy_late_listener(struct wl_client *client,
930*84e872a0SLloyd Pique 				    struct wl_listener *listener)
931*84e872a0SLloyd Pique {
932*84e872a0SLloyd Pique 	wl_priv_signal_add(&client->destroy_late_signal, listener);
933*84e872a0SLloyd Pique }
934*84e872a0SLloyd Pique 
935*84e872a0SLloyd Pique WL_EXPORT struct wl_listener *
wl_client_get_destroy_late_listener(struct wl_client * client,wl_notify_func_t notify)936*84e872a0SLloyd Pique wl_client_get_destroy_late_listener(struct wl_client *client,
937*84e872a0SLloyd Pique 				    wl_notify_func_t notify)
938*84e872a0SLloyd Pique {
939*84e872a0SLloyd Pique 	return wl_priv_signal_get(&client->destroy_late_signal, notify);
940*84e872a0SLloyd Pique }
941*84e872a0SLloyd Pique 
942*84e872a0SLloyd Pique WL_EXPORT void
wl_client_destroy(struct wl_client * client)943*84e872a0SLloyd Pique wl_client_destroy(struct wl_client *client)
944*84e872a0SLloyd Pique {
945*84e872a0SLloyd Pique 	uint32_t serial = 0;
946*84e872a0SLloyd Pique 
947*84e872a0SLloyd Pique 	wl_priv_signal_final_emit(&client->destroy_signal, client);
948*84e872a0SLloyd Pique 
949*84e872a0SLloyd Pique 	wl_client_flush(client);
950*84e872a0SLloyd Pique 	wl_map_for_each(&client->objects, destroy_resource, &serial);
951*84e872a0SLloyd Pique 	wl_map_release(&client->objects);
952*84e872a0SLloyd Pique 	wl_event_source_remove(client->source);
953*84e872a0SLloyd Pique 	close(wl_connection_destroy(client->connection));
954*84e872a0SLloyd Pique 
955*84e872a0SLloyd Pique 	wl_priv_signal_final_emit(&client->destroy_late_signal, client);
956*84e872a0SLloyd Pique 
957*84e872a0SLloyd Pique 	wl_list_remove(&client->link);
958*84e872a0SLloyd Pique 	wl_list_remove(&client->resource_created_signal.listener_list);
959*84e872a0SLloyd Pique 	free(client);
960*84e872a0SLloyd Pique }
961*84e872a0SLloyd Pique 
962*84e872a0SLloyd Pique /* Check if a global filter is registered and use it if any.
963*84e872a0SLloyd Pique  *
964*84e872a0SLloyd Pique  * If no wl_global filter has been registered, this function will
965*84e872a0SLloyd Pique  * return true, allowing the wl_global to be visible to the wl_client
966*84e872a0SLloyd Pique  */
967*84e872a0SLloyd Pique static bool
wl_global_is_visible(const struct wl_client * client,const struct wl_global * global)968*84e872a0SLloyd Pique wl_global_is_visible(const struct wl_client *client,
969*84e872a0SLloyd Pique 	      const struct wl_global *global)
970*84e872a0SLloyd Pique {
971*84e872a0SLloyd Pique 	struct wl_display *display = client->display;
972*84e872a0SLloyd Pique 
973*84e872a0SLloyd Pique 	return (display->global_filter == NULL ||
974*84e872a0SLloyd Pique 		display->global_filter(client, global, display->global_filter_data));
975*84e872a0SLloyd Pique }
976*84e872a0SLloyd Pique 
977*84e872a0SLloyd Pique static void
registry_bind(struct wl_client * client,struct wl_resource * resource,uint32_t name,const char * interface,uint32_t version,uint32_t id)978*84e872a0SLloyd Pique registry_bind(struct wl_client *client,
979*84e872a0SLloyd Pique 	      struct wl_resource *resource, uint32_t name,
980*84e872a0SLloyd Pique 	      const char *interface, uint32_t version, uint32_t id)
981*84e872a0SLloyd Pique {
982*84e872a0SLloyd Pique 	struct wl_global *global;
983*84e872a0SLloyd Pique 	struct wl_display *display = resource->data;
984*84e872a0SLloyd Pique 
985*84e872a0SLloyd Pique 	wl_list_for_each(global, &display->global_list, link)
986*84e872a0SLloyd Pique 		if (global->name == name)
987*84e872a0SLloyd Pique 			break;
988*84e872a0SLloyd Pique 
989*84e872a0SLloyd Pique 	if (&global->link == &display->global_list)
990*84e872a0SLloyd Pique 		wl_resource_post_error(resource,
991*84e872a0SLloyd Pique 				       WL_DISPLAY_ERROR_INVALID_OBJECT,
992*84e872a0SLloyd Pique 				       "invalid global %s (%d)", interface, name);
993*84e872a0SLloyd Pique 	else if (strcmp(global->interface->name, interface) != 0)
994*84e872a0SLloyd Pique 		wl_resource_post_error(resource,
995*84e872a0SLloyd Pique 				       WL_DISPLAY_ERROR_INVALID_OBJECT,
996*84e872a0SLloyd Pique 				       "invalid interface for global %u: "
997*84e872a0SLloyd Pique 				       "have %s, wanted %s",
998*84e872a0SLloyd Pique 				       name, interface, global->interface->name);
999*84e872a0SLloyd Pique 	else if (version == 0)
1000*84e872a0SLloyd Pique 		wl_resource_post_error(resource,
1001*84e872a0SLloyd Pique 				       WL_DISPLAY_ERROR_INVALID_OBJECT,
1002*84e872a0SLloyd Pique 				       "invalid version for global %s (%d): 0 is not a valid version",
1003*84e872a0SLloyd Pique 				       interface, name);
1004*84e872a0SLloyd Pique 	else if (global->version < version)
1005*84e872a0SLloyd Pique 		wl_resource_post_error(resource,
1006*84e872a0SLloyd Pique 				       WL_DISPLAY_ERROR_INVALID_OBJECT,
1007*84e872a0SLloyd Pique 				       "invalid version for global %s (%d): have %d, wanted %d",
1008*84e872a0SLloyd Pique 				       interface, name, global->version, version);
1009*84e872a0SLloyd Pique 	else if (!wl_global_is_visible(client, global))
1010*84e872a0SLloyd Pique 		wl_resource_post_error(resource,
1011*84e872a0SLloyd Pique 				       WL_DISPLAY_ERROR_INVALID_OBJECT,
1012*84e872a0SLloyd Pique 				       "invalid global %s (%d)", interface, name);
1013*84e872a0SLloyd Pique 	else
1014*84e872a0SLloyd Pique 		global->bind(client, global->data, version, id);
1015*84e872a0SLloyd Pique }
1016*84e872a0SLloyd Pique 
1017*84e872a0SLloyd Pique static const struct wl_registry_interface registry_interface = {
1018*84e872a0SLloyd Pique 	registry_bind
1019*84e872a0SLloyd Pique };
1020*84e872a0SLloyd Pique 
1021*84e872a0SLloyd Pique static void
display_sync(struct wl_client * client,struct wl_resource * resource,uint32_t id)1022*84e872a0SLloyd Pique display_sync(struct wl_client *client,
1023*84e872a0SLloyd Pique 	     struct wl_resource *resource, uint32_t id)
1024*84e872a0SLloyd Pique {
1025*84e872a0SLloyd Pique 	struct wl_resource *callback;
1026*84e872a0SLloyd Pique 	uint32_t serial;
1027*84e872a0SLloyd Pique 
1028*84e872a0SLloyd Pique 	callback = wl_resource_create(client, &wl_callback_interface, 1, id);
1029*84e872a0SLloyd Pique 	if (callback == NULL) {
1030*84e872a0SLloyd Pique 		wl_client_post_no_memory(client);
1031*84e872a0SLloyd Pique 		return;
1032*84e872a0SLloyd Pique 	}
1033*84e872a0SLloyd Pique 
1034*84e872a0SLloyd Pique 	serial = wl_display_get_serial(client->display);
1035*84e872a0SLloyd Pique 	wl_callback_send_done(callback, serial);
1036*84e872a0SLloyd Pique 	wl_resource_destroy(callback);
1037*84e872a0SLloyd Pique }
1038*84e872a0SLloyd Pique 
1039*84e872a0SLloyd Pique static void
unbind_resource(struct wl_resource * resource)1040*84e872a0SLloyd Pique unbind_resource(struct wl_resource *resource)
1041*84e872a0SLloyd Pique {
1042*84e872a0SLloyd Pique 	wl_list_remove(&resource->link);
1043*84e872a0SLloyd Pique }
1044*84e872a0SLloyd Pique 
1045*84e872a0SLloyd Pique static void
display_get_registry(struct wl_client * client,struct wl_resource * resource,uint32_t id)1046*84e872a0SLloyd Pique display_get_registry(struct wl_client *client,
1047*84e872a0SLloyd Pique 		     struct wl_resource *resource, uint32_t id)
1048*84e872a0SLloyd Pique {
1049*84e872a0SLloyd Pique 	struct wl_display *display = resource->data;
1050*84e872a0SLloyd Pique 	struct wl_resource *registry_resource;
1051*84e872a0SLloyd Pique 	struct wl_global *global;
1052*84e872a0SLloyd Pique 
1053*84e872a0SLloyd Pique 	registry_resource =
1054*84e872a0SLloyd Pique 		wl_resource_create(client, &wl_registry_interface, 1, id);
1055*84e872a0SLloyd Pique 	if (registry_resource == NULL) {
1056*84e872a0SLloyd Pique 		wl_client_post_no_memory(client);
1057*84e872a0SLloyd Pique 		return;
1058*84e872a0SLloyd Pique 	}
1059*84e872a0SLloyd Pique 
1060*84e872a0SLloyd Pique 	wl_resource_set_implementation(registry_resource,
1061*84e872a0SLloyd Pique 				       &registry_interface,
1062*84e872a0SLloyd Pique 				       display, unbind_resource);
1063*84e872a0SLloyd Pique 
1064*84e872a0SLloyd Pique 	wl_list_insert(&display->registry_resource_list,
1065*84e872a0SLloyd Pique 		       &registry_resource->link);
1066*84e872a0SLloyd Pique 
1067*84e872a0SLloyd Pique 	wl_list_for_each(global, &display->global_list, link)
1068*84e872a0SLloyd Pique 		if (wl_global_is_visible(client, global) && !global->removed)
1069*84e872a0SLloyd Pique 			wl_resource_post_event(registry_resource,
1070*84e872a0SLloyd Pique 					       WL_REGISTRY_GLOBAL,
1071*84e872a0SLloyd Pique 					       global->name,
1072*84e872a0SLloyd Pique 					       global->interface->name,
1073*84e872a0SLloyd Pique 					       global->version);
1074*84e872a0SLloyd Pique }
1075*84e872a0SLloyd Pique 
1076*84e872a0SLloyd Pique static const struct wl_display_interface display_interface = {
1077*84e872a0SLloyd Pique 	display_sync,
1078*84e872a0SLloyd Pique 	display_get_registry
1079*84e872a0SLloyd Pique };
1080*84e872a0SLloyd Pique 
1081*84e872a0SLloyd Pique static void
destroy_client_display_resource(struct wl_resource * resource)1082*84e872a0SLloyd Pique destroy_client_display_resource(struct wl_resource *resource)
1083*84e872a0SLloyd Pique {
1084*84e872a0SLloyd Pique 	resource->client->display_resource = NULL;
1085*84e872a0SLloyd Pique }
1086*84e872a0SLloyd Pique 
1087*84e872a0SLloyd Pique static int
bind_display(struct wl_client * client,struct wl_display * display)1088*84e872a0SLloyd Pique bind_display(struct wl_client *client, struct wl_display *display)
1089*84e872a0SLloyd Pique {
1090*84e872a0SLloyd Pique 	client->display_resource =
1091*84e872a0SLloyd Pique 		wl_resource_create(client, &wl_display_interface, 1, 1);
1092*84e872a0SLloyd Pique 	if (client->display_resource == NULL) {
1093*84e872a0SLloyd Pique 		/* DON'T send no-memory error to client - it has no
1094*84e872a0SLloyd Pique 		 * resource to which it could post the event */
1095*84e872a0SLloyd Pique 		return -1;
1096*84e872a0SLloyd Pique 	}
1097*84e872a0SLloyd Pique 
1098*84e872a0SLloyd Pique 	wl_resource_set_implementation(client->display_resource,
1099*84e872a0SLloyd Pique 				       &display_interface, display,
1100*84e872a0SLloyd Pique 				       destroy_client_display_resource);
1101*84e872a0SLloyd Pique 	return 0;
1102*84e872a0SLloyd Pique }
1103*84e872a0SLloyd Pique 
1104*84e872a0SLloyd Pique static int
handle_display_terminate(int fd,uint32_t mask,void * data)1105*84e872a0SLloyd Pique handle_display_terminate(int fd, uint32_t mask, void *data) {
1106*84e872a0SLloyd Pique 	uint64_t term_event;
1107*84e872a0SLloyd Pique 
1108*84e872a0SLloyd Pique 	if (read(fd, &term_event, sizeof(term_event)) < 0 && errno != EAGAIN)
1109*84e872a0SLloyd Pique 		return -1;
1110*84e872a0SLloyd Pique 
1111*84e872a0SLloyd Pique 	return 0;
1112*84e872a0SLloyd Pique }
1113*84e872a0SLloyd Pique 
1114*84e872a0SLloyd Pique /** Create Wayland display object.
1115*84e872a0SLloyd Pique  *
1116*84e872a0SLloyd Pique  * \return The Wayland display object. Null if failed to create
1117*84e872a0SLloyd Pique  *
1118*84e872a0SLloyd Pique  * This creates the wl_display object.
1119*84e872a0SLloyd Pique  *
1120*84e872a0SLloyd Pique  * \memberof wl_display
1121*84e872a0SLloyd Pique  */
1122*84e872a0SLloyd Pique WL_EXPORT struct wl_display *
wl_display_create(void)1123*84e872a0SLloyd Pique wl_display_create(void)
1124*84e872a0SLloyd Pique {
1125*84e872a0SLloyd Pique 	struct wl_display *display;
1126*84e872a0SLloyd Pique 	const char *debug;
1127*84e872a0SLloyd Pique 
1128*84e872a0SLloyd Pique 	debug = getenv("WAYLAND_DEBUG");
1129*84e872a0SLloyd Pique 	if (debug && (strstr(debug, "server") || strstr(debug, "1")))
1130*84e872a0SLloyd Pique 		debug_server = 1;
1131*84e872a0SLloyd Pique 
1132*84e872a0SLloyd Pique 	display = zalloc(sizeof *display);
1133*84e872a0SLloyd Pique 	if (display == NULL)
1134*84e872a0SLloyd Pique 		return NULL;
1135*84e872a0SLloyd Pique 
1136*84e872a0SLloyd Pique 	display->loop = wl_event_loop_create();
1137*84e872a0SLloyd Pique 	if (display->loop == NULL) {
1138*84e872a0SLloyd Pique 		free(display);
1139*84e872a0SLloyd Pique 		return NULL;
1140*84e872a0SLloyd Pique 	}
1141*84e872a0SLloyd Pique 
1142*84e872a0SLloyd Pique 	display->terminate_efd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
1143*84e872a0SLloyd Pique 	if (display->terminate_efd < 0)
1144*84e872a0SLloyd Pique 		goto err_eventfd;
1145*84e872a0SLloyd Pique 
1146*84e872a0SLloyd Pique 	display->term_source = wl_event_loop_add_fd(display->loop,
1147*84e872a0SLloyd Pique 						    display->terminate_efd,
1148*84e872a0SLloyd Pique 						    WL_EVENT_READABLE,
1149*84e872a0SLloyd Pique 						    handle_display_terminate,
1150*84e872a0SLloyd Pique 						    NULL);
1151*84e872a0SLloyd Pique 
1152*84e872a0SLloyd Pique 	if (display->term_source == NULL)
1153*84e872a0SLloyd Pique 		goto err_term_source;
1154*84e872a0SLloyd Pique 
1155*84e872a0SLloyd Pique 	wl_list_init(&display->global_list);
1156*84e872a0SLloyd Pique 	wl_list_init(&display->socket_list);
1157*84e872a0SLloyd Pique 	wl_list_init(&display->client_list);
1158*84e872a0SLloyd Pique 	wl_list_init(&display->registry_resource_list);
1159*84e872a0SLloyd Pique 	wl_list_init(&display->protocol_loggers);
1160*84e872a0SLloyd Pique 
1161*84e872a0SLloyd Pique 	wl_priv_signal_init(&display->destroy_signal);
1162*84e872a0SLloyd Pique 	wl_priv_signal_init(&display->create_client_signal);
1163*84e872a0SLloyd Pique 
1164*84e872a0SLloyd Pique 	display->next_global_name = 1;
1165*84e872a0SLloyd Pique 	display->serial = 0;
1166*84e872a0SLloyd Pique 
1167*84e872a0SLloyd Pique 	display->global_filter = NULL;
1168*84e872a0SLloyd Pique 	display->global_filter_data = NULL;
1169*84e872a0SLloyd Pique 
1170*84e872a0SLloyd Pique 	wl_array_init(&display->additional_shm_formats);
1171*84e872a0SLloyd Pique 
1172*84e872a0SLloyd Pique 	return display;
1173*84e872a0SLloyd Pique 
1174*84e872a0SLloyd Pique err_term_source:
1175*84e872a0SLloyd Pique 	close(display->terminate_efd);
1176*84e872a0SLloyd Pique err_eventfd:
1177*84e872a0SLloyd Pique 	wl_event_loop_destroy(display->loop);
1178*84e872a0SLloyd Pique 	free(display);
1179*84e872a0SLloyd Pique 	return NULL;
1180*84e872a0SLloyd Pique }
1181*84e872a0SLloyd Pique 
1182*84e872a0SLloyd Pique static void
wl_socket_destroy(struct wl_socket * s)1183*84e872a0SLloyd Pique wl_socket_destroy(struct wl_socket *s)
1184*84e872a0SLloyd Pique {
1185*84e872a0SLloyd Pique 	if (s->source)
1186*84e872a0SLloyd Pique 		wl_event_source_remove(s->source);
1187*84e872a0SLloyd Pique 	if (s->addr.sun_path[0])
1188*84e872a0SLloyd Pique 		unlink(s->addr.sun_path);
1189*84e872a0SLloyd Pique 	if (s->fd >= 0)
1190*84e872a0SLloyd Pique 		close(s->fd);
1191*84e872a0SLloyd Pique 	if (s->lock_addr[0])
1192*84e872a0SLloyd Pique 		unlink(s->lock_addr);
1193*84e872a0SLloyd Pique 	if (s->fd_lock >= 0)
1194*84e872a0SLloyd Pique 		close(s->fd_lock);
1195*84e872a0SLloyd Pique 
1196*84e872a0SLloyd Pique 	free(s);
1197*84e872a0SLloyd Pique }
1198*84e872a0SLloyd Pique 
1199*84e872a0SLloyd Pique static struct wl_socket *
wl_socket_alloc(void)1200*84e872a0SLloyd Pique wl_socket_alloc(void)
1201*84e872a0SLloyd Pique {
1202*84e872a0SLloyd Pique 	struct wl_socket *s;
1203*84e872a0SLloyd Pique 
1204*84e872a0SLloyd Pique 	s = zalloc(sizeof *s);
1205*84e872a0SLloyd Pique 	if (!s)
1206*84e872a0SLloyd Pique 		return NULL;
1207*84e872a0SLloyd Pique 
1208*84e872a0SLloyd Pique 	s->fd = -1;
1209*84e872a0SLloyd Pique 	s->fd_lock = -1;
1210*84e872a0SLloyd Pique 
1211*84e872a0SLloyd Pique 	return s;
1212*84e872a0SLloyd Pique }
1213*84e872a0SLloyd Pique 
1214*84e872a0SLloyd Pique /** Destroy Wayland display object.
1215*84e872a0SLloyd Pique  *
1216*84e872a0SLloyd Pique  * \param display The Wayland display object which should be destroyed.
1217*84e872a0SLloyd Pique  *
1218*84e872a0SLloyd Pique  * This function emits the wl_display destroy signal, releases
1219*84e872a0SLloyd Pique  * all the sockets added to this display, free's all the globals associated
1220*84e872a0SLloyd Pique  * with this display, free's memory of additional shared memory formats and
1221*84e872a0SLloyd Pique  * destroy the display object.
1222*84e872a0SLloyd Pique  *
1223*84e872a0SLloyd Pique  * \sa wl_display_add_destroy_listener
1224*84e872a0SLloyd Pique  *
1225*84e872a0SLloyd Pique  * \memberof wl_display
1226*84e872a0SLloyd Pique  */
1227*84e872a0SLloyd Pique WL_EXPORT void
wl_display_destroy(struct wl_display * display)1228*84e872a0SLloyd Pique wl_display_destroy(struct wl_display *display)
1229*84e872a0SLloyd Pique {
1230*84e872a0SLloyd Pique 	struct wl_socket *s, *next;
1231*84e872a0SLloyd Pique 	struct wl_global *global, *gnext;
1232*84e872a0SLloyd Pique 
1233*84e872a0SLloyd Pique 	wl_priv_signal_final_emit(&display->destroy_signal, display);
1234*84e872a0SLloyd Pique 
1235*84e872a0SLloyd Pique 	wl_list_for_each_safe(s, next, &display->socket_list, link) {
1236*84e872a0SLloyd Pique 		wl_socket_destroy(s);
1237*84e872a0SLloyd Pique 	}
1238*84e872a0SLloyd Pique 
1239*84e872a0SLloyd Pique 	close(display->terminate_efd);
1240*84e872a0SLloyd Pique 	wl_event_source_remove(display->term_source);
1241*84e872a0SLloyd Pique 
1242*84e872a0SLloyd Pique 	wl_event_loop_destroy(display->loop);
1243*84e872a0SLloyd Pique 
1244*84e872a0SLloyd Pique 	wl_list_for_each_safe(global, gnext, &display->global_list, link)
1245*84e872a0SLloyd Pique 		free(global);
1246*84e872a0SLloyd Pique 
1247*84e872a0SLloyd Pique 	wl_array_release(&display->additional_shm_formats);
1248*84e872a0SLloyd Pique 
1249*84e872a0SLloyd Pique 	wl_list_remove(&display->protocol_loggers);
1250*84e872a0SLloyd Pique 
1251*84e872a0SLloyd Pique 	free(display);
1252*84e872a0SLloyd Pique }
1253*84e872a0SLloyd Pique 
1254*84e872a0SLloyd Pique /** Set a filter function for global objects
1255*84e872a0SLloyd Pique  *
1256*84e872a0SLloyd Pique  * \param display The Wayland display object.
1257*84e872a0SLloyd Pique  * \param filter  The global filter function.
1258*84e872a0SLloyd Pique  * \param data User data to be associated with the global filter.
1259*84e872a0SLloyd Pique  *
1260*84e872a0SLloyd Pique  * Set a filter for the wl_display to advertise or hide global objects
1261*84e872a0SLloyd Pique  * to clients.
1262*84e872a0SLloyd Pique  * The set filter will be used during wl_global advertisement to
1263*84e872a0SLloyd Pique  * determine whether a global object should be advertised to a
1264*84e872a0SLloyd Pique  * given client, and during wl_global binding to determine whether
1265*84e872a0SLloyd Pique  * a given client should be allowed to bind to a global.
1266*84e872a0SLloyd Pique  *
1267*84e872a0SLloyd Pique  * Clients that try to bind to a global that was filtered out will
1268*84e872a0SLloyd Pique  * have an error raised.
1269*84e872a0SLloyd Pique  *
1270*84e872a0SLloyd Pique  * Setting the filter NULL will result in all globals being
1271*84e872a0SLloyd Pique  * advertised to all clients. The default is no filter.
1272*84e872a0SLloyd Pique  *
1273*84e872a0SLloyd Pique  * The filter should be installed before any client connects and should always
1274*84e872a0SLloyd Pique  * take the same decision given a client and a global. Not doing so will result
1275*84e872a0SLloyd Pique  * in inconsistent filtering and broken wl_registry event sequences.
1276*84e872a0SLloyd Pique  *
1277*84e872a0SLloyd Pique  * \memberof wl_display
1278*84e872a0SLloyd Pique  */
1279*84e872a0SLloyd Pique WL_EXPORT void
wl_display_set_global_filter(struct wl_display * display,wl_display_global_filter_func_t filter,void * data)1280*84e872a0SLloyd Pique wl_display_set_global_filter(struct wl_display *display,
1281*84e872a0SLloyd Pique 			     wl_display_global_filter_func_t filter,
1282*84e872a0SLloyd Pique 			     void *data)
1283*84e872a0SLloyd Pique {
1284*84e872a0SLloyd Pique 	display->global_filter = filter;
1285*84e872a0SLloyd Pique 	display->global_filter_data = data;
1286*84e872a0SLloyd Pique }
1287*84e872a0SLloyd Pique 
1288*84e872a0SLloyd Pique 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)1289*84e872a0SLloyd Pique wl_global_create(struct wl_display *display,
1290*84e872a0SLloyd Pique 		 const struct wl_interface *interface, int version,
1291*84e872a0SLloyd Pique 		 void *data, wl_global_bind_func_t bind)
1292*84e872a0SLloyd Pique {
1293*84e872a0SLloyd Pique 	struct wl_global *global;
1294*84e872a0SLloyd Pique 	struct wl_resource *resource;
1295*84e872a0SLloyd Pique 
1296*84e872a0SLloyd Pique 	if (version < 1) {
1297*84e872a0SLloyd Pique 		wl_log("wl_global_create: failing to create interface "
1298*84e872a0SLloyd Pique 		       "'%s' with version %d because it is less than 1\n",
1299*84e872a0SLloyd Pique 			interface->name, version);
1300*84e872a0SLloyd Pique 		return NULL;
1301*84e872a0SLloyd Pique 	}
1302*84e872a0SLloyd Pique 
1303*84e872a0SLloyd Pique 	if (version > interface->version) {
1304*84e872a0SLloyd Pique 		wl_log("wl_global_create: implemented version for '%s' "
1305*84e872a0SLloyd Pique 		       "higher than interface version (%d > %d)\n",
1306*84e872a0SLloyd Pique 		       interface->name, version, interface->version);
1307*84e872a0SLloyd Pique 		return NULL;
1308*84e872a0SLloyd Pique 	}
1309*84e872a0SLloyd Pique 
1310*84e872a0SLloyd Pique 	if (display->next_global_name >= UINT32_MAX) {
1311*84e872a0SLloyd Pique 		wl_log("wl_global_create: ran out of global names\n");
1312*84e872a0SLloyd Pique 		return NULL;
1313*84e872a0SLloyd Pique 	}
1314*84e872a0SLloyd Pique 
1315*84e872a0SLloyd Pique 	global = zalloc(sizeof *global);
1316*84e872a0SLloyd Pique 	if (global == NULL)
1317*84e872a0SLloyd Pique 		return NULL;
1318*84e872a0SLloyd Pique 
1319*84e872a0SLloyd Pique 	global->display = display;
1320*84e872a0SLloyd Pique 	global->name = display->next_global_name++;
1321*84e872a0SLloyd Pique 	global->interface = interface;
1322*84e872a0SLloyd Pique 	global->version = version;
1323*84e872a0SLloyd Pique 	global->data = data;
1324*84e872a0SLloyd Pique 	global->bind = bind;
1325*84e872a0SLloyd Pique 	global->removed = false;
1326*84e872a0SLloyd Pique 	wl_list_insert(display->global_list.prev, &global->link);
1327*84e872a0SLloyd Pique 
1328*84e872a0SLloyd Pique 	wl_list_for_each(resource, &display->registry_resource_list, link)
1329*84e872a0SLloyd Pique 		if (wl_global_is_visible(resource->client, global))
1330*84e872a0SLloyd Pique 			wl_resource_post_event(resource,
1331*84e872a0SLloyd Pique 					       WL_REGISTRY_GLOBAL,
1332*84e872a0SLloyd Pique 					       global->name,
1333*84e872a0SLloyd Pique 					       global->interface->name,
1334*84e872a0SLloyd Pique 					       global->version);
1335*84e872a0SLloyd Pique 
1336*84e872a0SLloyd Pique 	return global;
1337*84e872a0SLloyd Pique }
1338*84e872a0SLloyd Pique 
1339*84e872a0SLloyd Pique /** Remove the global
1340*84e872a0SLloyd Pique  *
1341*84e872a0SLloyd Pique  * \param global The Wayland global.
1342*84e872a0SLloyd Pique  *
1343*84e872a0SLloyd Pique  * Broadcast a global remove event to all clients without destroying the
1344*84e872a0SLloyd Pique  * global. This function can only be called once per global.
1345*84e872a0SLloyd Pique  *
1346*84e872a0SLloyd Pique  * wl_global_destroy() removes the global and immediately destroys it. On
1347*84e872a0SLloyd Pique  * the other end, this function only removes the global, allowing clients
1348*84e872a0SLloyd Pique  * that have not yet received the global remove event to continue to bind to
1349*84e872a0SLloyd Pique  * it.
1350*84e872a0SLloyd Pique  *
1351*84e872a0SLloyd Pique  * This can be used by compositors to mitigate clients being disconnected
1352*84e872a0SLloyd Pique  * because a global has been added and removed too quickly. Compositors can call
1353*84e872a0SLloyd Pique  * wl_global_remove(), then wait an implementation-defined amount of time, then
1354*84e872a0SLloyd Pique  * call wl_global_destroy(). Note that the destruction of a global is still
1355*84e872a0SLloyd Pique  * racy, since clients have no way to acknowledge that they received the remove
1356*84e872a0SLloyd Pique  * event.
1357*84e872a0SLloyd Pique  *
1358*84e872a0SLloyd Pique  * \since 1.17.90
1359*84e872a0SLloyd Pique  */
1360*84e872a0SLloyd Pique WL_EXPORT void
wl_global_remove(struct wl_global * global)1361*84e872a0SLloyd Pique wl_global_remove(struct wl_global *global)
1362*84e872a0SLloyd Pique {
1363*84e872a0SLloyd Pique 	struct wl_display *display = global->display;
1364*84e872a0SLloyd Pique 	struct wl_resource *resource;
1365*84e872a0SLloyd Pique 
1366*84e872a0SLloyd Pique 	if (global->removed)
1367*84e872a0SLloyd Pique 		wl_abort("wl_global_remove: called twice on the same "
1368*84e872a0SLloyd Pique 			 "global '%s@%"PRIu32"'", global->interface->name,
1369*84e872a0SLloyd Pique 			 global->name);
1370*84e872a0SLloyd Pique 
1371*84e872a0SLloyd Pique 	wl_list_for_each(resource, &display->registry_resource_list, link)
1372*84e872a0SLloyd Pique 		if (wl_global_is_visible(resource->client, global))
1373*84e872a0SLloyd Pique 			wl_resource_post_event(resource, WL_REGISTRY_GLOBAL_REMOVE,
1374*84e872a0SLloyd Pique 					       global->name);
1375*84e872a0SLloyd Pique 
1376*84e872a0SLloyd Pique 	global->removed = true;
1377*84e872a0SLloyd Pique }
1378*84e872a0SLloyd Pique 
1379*84e872a0SLloyd Pique WL_EXPORT void
wl_global_destroy(struct wl_global * global)1380*84e872a0SLloyd Pique wl_global_destroy(struct wl_global *global)
1381*84e872a0SLloyd Pique {
1382*84e872a0SLloyd Pique 	if (!global->removed)
1383*84e872a0SLloyd Pique 		wl_global_remove(global);
1384*84e872a0SLloyd Pique 	wl_list_remove(&global->link);
1385*84e872a0SLloyd Pique 	free(global);
1386*84e872a0SLloyd Pique }
1387*84e872a0SLloyd Pique 
1388*84e872a0SLloyd Pique WL_EXPORT const struct wl_interface *
wl_global_get_interface(const struct wl_global * global)1389*84e872a0SLloyd Pique wl_global_get_interface(const struct wl_global *global)
1390*84e872a0SLloyd Pique {
1391*84e872a0SLloyd Pique 	return global->interface;
1392*84e872a0SLloyd Pique }
1393*84e872a0SLloyd Pique 
1394*84e872a0SLloyd Pique /** Get the name of the global.
1395*84e872a0SLloyd Pique  *
1396*84e872a0SLloyd Pique  * \param global The global object.
1397*84e872a0SLloyd Pique  * \param client Client for which to look up the global.
1398*84e872a0SLloyd Pique  * \return The name of the global, or 0 if the global is not visible to the
1399*84e872a0SLloyd Pique  *         client.
1400*84e872a0SLloyd Pique  *
1401*84e872a0SLloyd Pique  * \memberof wl_global
1402*84e872a0SLloyd Pique  * \since 1.22
1403*84e872a0SLloyd Pique  */
1404*84e872a0SLloyd Pique WL_EXPORT uint32_t
wl_global_get_name(const struct wl_global * global,const struct wl_client * client)1405*84e872a0SLloyd Pique wl_global_get_name(const struct wl_global *global,
1406*84e872a0SLloyd Pique 		   const struct wl_client *client)
1407*84e872a0SLloyd Pique {
1408*84e872a0SLloyd Pique 	return wl_global_is_visible(client, global) ? global->name : 0;
1409*84e872a0SLloyd Pique }
1410*84e872a0SLloyd Pique 
1411*84e872a0SLloyd Pique /** Get the version of the given global.
1412*84e872a0SLloyd Pique  *
1413*84e872a0SLloyd Pique  * \param global The global object.
1414*84e872a0SLloyd Pique  * \return The version advertised by the global.
1415*84e872a0SLloyd Pique  *
1416*84e872a0SLloyd Pique  * \memberof wl_global
1417*84e872a0SLloyd Pique  * \since 1.21
1418*84e872a0SLloyd Pique  */
1419*84e872a0SLloyd Pique WL_EXPORT uint32_t
wl_global_get_version(const struct wl_global * global)1420*84e872a0SLloyd Pique wl_global_get_version(const struct wl_global *global)
1421*84e872a0SLloyd Pique {
1422*84e872a0SLloyd Pique 	return global->version;
1423*84e872a0SLloyd Pique }
1424*84e872a0SLloyd Pique 
1425*84e872a0SLloyd Pique /** Get the display object for the given global
1426*84e872a0SLloyd Pique  *
1427*84e872a0SLloyd Pique  * \param global The global object
1428*84e872a0SLloyd Pique  * \return The display object the global is associated with.
1429*84e872a0SLloyd Pique  *
1430*84e872a0SLloyd Pique  * \memberof wl_global
1431*84e872a0SLloyd Pique  * \since 1.20
1432*84e872a0SLloyd Pique  */
1433*84e872a0SLloyd Pique WL_EXPORT struct wl_display *
wl_global_get_display(const struct wl_global * global)1434*84e872a0SLloyd Pique wl_global_get_display(const struct wl_global *global)
1435*84e872a0SLloyd Pique {
1436*84e872a0SLloyd Pique 	return global->display;
1437*84e872a0SLloyd Pique }
1438*84e872a0SLloyd Pique 
1439*84e872a0SLloyd Pique WL_EXPORT void *
wl_global_get_user_data(const struct wl_global * global)1440*84e872a0SLloyd Pique wl_global_get_user_data(const struct wl_global *global)
1441*84e872a0SLloyd Pique {
1442*84e872a0SLloyd Pique 	return global->data;
1443*84e872a0SLloyd Pique }
1444*84e872a0SLloyd Pique 
1445*84e872a0SLloyd Pique /** Set the global's user data
1446*84e872a0SLloyd Pique  *
1447*84e872a0SLloyd Pique  * \param global The global object
1448*84e872a0SLloyd Pique  * \param data The user data pointer
1449*84e872a0SLloyd Pique  *
1450*84e872a0SLloyd Pique  * \since 1.17.90
1451*84e872a0SLloyd Pique  */
1452*84e872a0SLloyd Pique WL_EXPORT void
wl_global_set_user_data(struct wl_global * global,void * data)1453*84e872a0SLloyd Pique wl_global_set_user_data(struct wl_global *global, void *data)
1454*84e872a0SLloyd Pique {
1455*84e872a0SLloyd Pique 	global->data = data;
1456*84e872a0SLloyd Pique }
1457*84e872a0SLloyd Pique 
1458*84e872a0SLloyd Pique /** Get the current serial number
1459*84e872a0SLloyd Pique  *
1460*84e872a0SLloyd Pique  * \param display The display object
1461*84e872a0SLloyd Pique  *
1462*84e872a0SLloyd Pique  * This function returns the most recent serial number, but does not
1463*84e872a0SLloyd Pique  * increment it.
1464*84e872a0SLloyd Pique  *
1465*84e872a0SLloyd Pique  * \memberof wl_display
1466*84e872a0SLloyd Pique  */
1467*84e872a0SLloyd Pique WL_EXPORT uint32_t
wl_display_get_serial(struct wl_display * display)1468*84e872a0SLloyd Pique wl_display_get_serial(struct wl_display *display)
1469*84e872a0SLloyd Pique {
1470*84e872a0SLloyd Pique 	return display->serial;
1471*84e872a0SLloyd Pique }
1472*84e872a0SLloyd Pique 
1473*84e872a0SLloyd Pique /** Get the next serial number
1474*84e872a0SLloyd Pique  *
1475*84e872a0SLloyd Pique  * \param display The display object
1476*84e872a0SLloyd Pique  *
1477*84e872a0SLloyd Pique  * This function increments the display serial number and returns the
1478*84e872a0SLloyd Pique  * new value.
1479*84e872a0SLloyd Pique  *
1480*84e872a0SLloyd Pique  * \memberof wl_display
1481*84e872a0SLloyd Pique  */
1482*84e872a0SLloyd Pique WL_EXPORT uint32_t
wl_display_next_serial(struct wl_display * display)1483*84e872a0SLloyd Pique wl_display_next_serial(struct wl_display *display)
1484*84e872a0SLloyd Pique {
1485*84e872a0SLloyd Pique 	display->serial++;
1486*84e872a0SLloyd Pique 
1487*84e872a0SLloyd Pique 	return display->serial;
1488*84e872a0SLloyd Pique }
1489*84e872a0SLloyd Pique 
1490*84e872a0SLloyd Pique WL_EXPORT struct wl_event_loop *
wl_display_get_event_loop(struct wl_display * display)1491*84e872a0SLloyd Pique wl_display_get_event_loop(struct wl_display *display)
1492*84e872a0SLloyd Pique {
1493*84e872a0SLloyd Pique 	return display->loop;
1494*84e872a0SLloyd Pique }
1495*84e872a0SLloyd Pique 
1496*84e872a0SLloyd Pique WL_EXPORT void
wl_display_terminate(struct wl_display * display)1497*84e872a0SLloyd Pique wl_display_terminate(struct wl_display *display)
1498*84e872a0SLloyd Pique {
1499*84e872a0SLloyd Pique 	int ret;
1500*84e872a0SLloyd Pique 	uint64_t terminate = 1;
1501*84e872a0SLloyd Pique 
1502*84e872a0SLloyd Pique 	display->run = 0;
1503*84e872a0SLloyd Pique 
1504*84e872a0SLloyd Pique 	ret = write(display->terminate_efd, &terminate, sizeof(terminate));
1505*84e872a0SLloyd Pique 	assert (ret >= 0 || errno == EAGAIN);
1506*84e872a0SLloyd Pique }
1507*84e872a0SLloyd Pique 
1508*84e872a0SLloyd Pique WL_EXPORT void
wl_display_run(struct wl_display * display)1509*84e872a0SLloyd Pique wl_display_run(struct wl_display *display)
1510*84e872a0SLloyd Pique {
1511*84e872a0SLloyd Pique 	display->run = 1;
1512*84e872a0SLloyd Pique 
1513*84e872a0SLloyd Pique 	while (display->run) {
1514*84e872a0SLloyd Pique 		wl_display_flush_clients(display);
1515*84e872a0SLloyd Pique 		wl_event_loop_dispatch(display->loop, -1);
1516*84e872a0SLloyd Pique 	}
1517*84e872a0SLloyd Pique }
1518*84e872a0SLloyd Pique 
1519*84e872a0SLloyd Pique WL_EXPORT void
wl_display_flush_clients(struct wl_display * display)1520*84e872a0SLloyd Pique wl_display_flush_clients(struct wl_display *display)
1521*84e872a0SLloyd Pique {
1522*84e872a0SLloyd Pique 	struct wl_client *client, *next;
1523*84e872a0SLloyd Pique 	int ret;
1524*84e872a0SLloyd Pique 
1525*84e872a0SLloyd Pique 	wl_list_for_each_safe(client, next, &display->client_list, link) {
1526*84e872a0SLloyd Pique 		ret = wl_connection_flush(client->connection);
1527*84e872a0SLloyd Pique 		if (ret < 0 && errno == EAGAIN) {
1528*84e872a0SLloyd Pique 			wl_event_source_fd_update(client->source,
1529*84e872a0SLloyd Pique 						  WL_EVENT_WRITABLE |
1530*84e872a0SLloyd Pique 						  WL_EVENT_READABLE);
1531*84e872a0SLloyd Pique 		} else if (ret < 0) {
1532*84e872a0SLloyd Pique 			wl_client_destroy(client);
1533*84e872a0SLloyd Pique 		}
1534*84e872a0SLloyd Pique 	}
1535*84e872a0SLloyd Pique }
1536*84e872a0SLloyd Pique 
1537*84e872a0SLloyd Pique /** Destroy all clients connected to the display
1538*84e872a0SLloyd Pique  *
1539*84e872a0SLloyd Pique  * \param display The display object
1540*84e872a0SLloyd Pique  *
1541*84e872a0SLloyd Pique  * This function should be called right before wl_display_destroy() to ensure
1542*84e872a0SLloyd Pique  * all client resources are closed properly. Destroying a client from within
1543*84e872a0SLloyd Pique  * wl_display_destroy_clients() is safe, but creating one will leak resources
1544*84e872a0SLloyd Pique  * and raise a warning.
1545*84e872a0SLloyd Pique  *
1546*84e872a0SLloyd Pique  * \memberof wl_display
1547*84e872a0SLloyd Pique  */
1548*84e872a0SLloyd Pique WL_EXPORT void
wl_display_destroy_clients(struct wl_display * display)1549*84e872a0SLloyd Pique wl_display_destroy_clients(struct wl_display *display)
1550*84e872a0SLloyd Pique {
1551*84e872a0SLloyd Pique 	struct wl_list tmp_client_list, *pos;
1552*84e872a0SLloyd Pique 	struct wl_client *client;
1553*84e872a0SLloyd Pique 
1554*84e872a0SLloyd Pique 	/* Move the whole client list to a temporary head because some new clients
1555*84e872a0SLloyd Pique 	 * might be added to the original head. */
1556*84e872a0SLloyd Pique 	wl_list_init(&tmp_client_list);
1557*84e872a0SLloyd Pique 	wl_list_insert_list(&tmp_client_list, &display->client_list);
1558*84e872a0SLloyd Pique 	wl_list_init(&display->client_list);
1559*84e872a0SLloyd Pique 
1560*84e872a0SLloyd Pique 	/* wl_list_for_each_safe isn't enough here: it fails if the next client is
1561*84e872a0SLloyd Pique 	 * destroyed by the destroy handler of the current one. */
1562*84e872a0SLloyd Pique 	while (!wl_list_empty(&tmp_client_list)) {
1563*84e872a0SLloyd Pique 		pos = tmp_client_list.next;
1564*84e872a0SLloyd Pique 		client = wl_container_of(pos, client, link);
1565*84e872a0SLloyd Pique 
1566*84e872a0SLloyd Pique 		wl_client_destroy(client);
1567*84e872a0SLloyd Pique 	}
1568*84e872a0SLloyd Pique 
1569*84e872a0SLloyd Pique 	if (!wl_list_empty(&display->client_list)) {
1570*84e872a0SLloyd Pique 		wl_log("wl_display_destroy_clients: cannot destroy all clients because "
1571*84e872a0SLloyd Pique 			   "new ones were created by destroy callbacks\n");
1572*84e872a0SLloyd Pique 	}
1573*84e872a0SLloyd Pique }
1574*84e872a0SLloyd Pique 
1575*84e872a0SLloyd Pique static int
socket_data(int fd,uint32_t mask,void * data)1576*84e872a0SLloyd Pique socket_data(int fd, uint32_t mask, void *data)
1577*84e872a0SLloyd Pique {
1578*84e872a0SLloyd Pique 	struct wl_display *display = data;
1579*84e872a0SLloyd Pique 	struct sockaddr_un name;
1580*84e872a0SLloyd Pique 	socklen_t length;
1581*84e872a0SLloyd Pique 	int client_fd;
1582*84e872a0SLloyd Pique 
1583*84e872a0SLloyd Pique 	length = sizeof name;
1584*84e872a0SLloyd Pique 	client_fd = wl_os_accept_cloexec(fd, (struct sockaddr *) &name,
1585*84e872a0SLloyd Pique 					 &length);
1586*84e872a0SLloyd Pique 	if (client_fd < 0)
1587*84e872a0SLloyd Pique 		wl_log("failed to accept: %s\n", strerror(errno));
1588*84e872a0SLloyd Pique 	else
1589*84e872a0SLloyd Pique 		if (!wl_client_create(display, client_fd))
1590*84e872a0SLloyd Pique 			close(client_fd);
1591*84e872a0SLloyd Pique 
1592*84e872a0SLloyd Pique 	return 1;
1593*84e872a0SLloyd Pique }
1594*84e872a0SLloyd Pique 
1595*84e872a0SLloyd Pique static int
wl_socket_lock(struct wl_socket * socket)1596*84e872a0SLloyd Pique wl_socket_lock(struct wl_socket *socket)
1597*84e872a0SLloyd Pique {
1598*84e872a0SLloyd Pique 	struct stat socket_stat;
1599*84e872a0SLloyd Pique 
1600*84e872a0SLloyd Pique 	snprintf(socket->lock_addr, sizeof socket->lock_addr,
1601*84e872a0SLloyd Pique 		 "%s%s", socket->addr.sun_path, LOCK_SUFFIX);
1602*84e872a0SLloyd Pique 
1603*84e872a0SLloyd Pique 	socket->fd_lock = open(socket->lock_addr, O_CREAT | O_CLOEXEC | O_RDWR,
1604*84e872a0SLloyd Pique 			       (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
1605*84e872a0SLloyd Pique 
1606*84e872a0SLloyd Pique 	if (socket->fd_lock < 0) {
1607*84e872a0SLloyd Pique 		wl_log("unable to open lockfile %s check permissions\n",
1608*84e872a0SLloyd Pique 			socket->lock_addr);
1609*84e872a0SLloyd Pique 		goto err;
1610*84e872a0SLloyd Pique 	}
1611*84e872a0SLloyd Pique 
1612*84e872a0SLloyd Pique 	if (flock(socket->fd_lock, LOCK_EX | LOCK_NB) < 0) {
1613*84e872a0SLloyd Pique 		wl_log("unable to lock lockfile %s, maybe another compositor is running\n",
1614*84e872a0SLloyd Pique 			socket->lock_addr);
1615*84e872a0SLloyd Pique 		goto err_fd;
1616*84e872a0SLloyd Pique 	}
1617*84e872a0SLloyd Pique 
1618*84e872a0SLloyd Pique 	if (lstat(socket->addr.sun_path, &socket_stat) < 0 ) {
1619*84e872a0SLloyd Pique 		if (errno != ENOENT) {
1620*84e872a0SLloyd Pique 			wl_log("did not manage to stat file %s\n",
1621*84e872a0SLloyd Pique 				socket->addr.sun_path);
1622*84e872a0SLloyd Pique 			goto err_fd;
1623*84e872a0SLloyd Pique 		}
1624*84e872a0SLloyd Pique 	} else if (socket_stat.st_mode & S_IWUSR ||
1625*84e872a0SLloyd Pique 		   socket_stat.st_mode & S_IWGRP) {
1626*84e872a0SLloyd Pique 		unlink(socket->addr.sun_path);
1627*84e872a0SLloyd Pique 	}
1628*84e872a0SLloyd Pique 
1629*84e872a0SLloyd Pique 	return 0;
1630*84e872a0SLloyd Pique err_fd:
1631*84e872a0SLloyd Pique 	close(socket->fd_lock);
1632*84e872a0SLloyd Pique 	socket->fd_lock = -1;
1633*84e872a0SLloyd Pique err:
1634*84e872a0SLloyd Pique 	*socket->lock_addr = 0;
1635*84e872a0SLloyd Pique 	/* we did not set this value here, but without lock the
1636*84e872a0SLloyd Pique 	 * socket won't be created anyway. This prevents the
1637*84e872a0SLloyd Pique 	 * wl_socket_destroy from unlinking already existing socket
1638*84e872a0SLloyd Pique 	 * created by other compositor */
1639*84e872a0SLloyd Pique 	*socket->addr.sun_path = 0;
1640*84e872a0SLloyd Pique 
1641*84e872a0SLloyd Pique 	return -1;
1642*84e872a0SLloyd Pique }
1643*84e872a0SLloyd Pique 
1644*84e872a0SLloyd Pique static int
wl_socket_init_for_display_name(struct wl_socket * s,const char * name)1645*84e872a0SLloyd Pique wl_socket_init_for_display_name(struct wl_socket *s, const char *name)
1646*84e872a0SLloyd Pique {
1647*84e872a0SLloyd Pique 	int name_size;
1648*84e872a0SLloyd Pique 	const char *runtime_dir = "";
1649*84e872a0SLloyd Pique 	const char *separator = "";
1650*84e872a0SLloyd Pique 
1651*84e872a0SLloyd Pique 	if (name[0] != '/') {
1652*84e872a0SLloyd Pique 		runtime_dir = getenv("XDG_RUNTIME_DIR");
1653*84e872a0SLloyd Pique 		if (!runtime_dir || runtime_dir[0] != '/') {
1654*84e872a0SLloyd Pique 			wl_log("error: XDG_RUNTIME_DIR is invalid or not set in"
1655*84e872a0SLloyd Pique 			       " the environment\n");
1656*84e872a0SLloyd Pique 
1657*84e872a0SLloyd Pique 			/* to prevent programs reporting
1658*84e872a0SLloyd Pique 			 * "failed to add socket: Success" */
1659*84e872a0SLloyd Pique 			errno = ENOENT;
1660*84e872a0SLloyd Pique 			return -1;
1661*84e872a0SLloyd Pique 		}
1662*84e872a0SLloyd Pique 		separator = "/";
1663*84e872a0SLloyd Pique 	}
1664*84e872a0SLloyd Pique 
1665*84e872a0SLloyd Pique 	s->addr.sun_family = AF_LOCAL;
1666*84e872a0SLloyd Pique 	name_size = snprintf(s->addr.sun_path, sizeof s->addr.sun_path,
1667*84e872a0SLloyd Pique 			     "%s%s%s", runtime_dir, separator, name) + 1;
1668*84e872a0SLloyd Pique 
1669*84e872a0SLloyd Pique 	assert(name_size > 0);
1670*84e872a0SLloyd Pique 	if (name_size > (int)sizeof s->addr.sun_path) {
1671*84e872a0SLloyd Pique 		wl_log("error: socket path \"%s%s%s\" plus null terminator"
1672*84e872a0SLloyd Pique 		       " exceeds 108 bytes\n", runtime_dir, separator, name);
1673*84e872a0SLloyd Pique 		*s->addr.sun_path = 0;
1674*84e872a0SLloyd Pique 		/* to prevent programs reporting
1675*84e872a0SLloyd Pique 		 * "failed to add socket: Success" */
1676*84e872a0SLloyd Pique 		errno = ENAMETOOLONG;
1677*84e872a0SLloyd Pique 		return -1;
1678*84e872a0SLloyd Pique 	}
1679*84e872a0SLloyd Pique 
1680*84e872a0SLloyd Pique 	s->display_name = (s->addr.sun_path + name_size - 1) - strlen(name);
1681*84e872a0SLloyd Pique 
1682*84e872a0SLloyd Pique 	return 0;
1683*84e872a0SLloyd Pique }
1684*84e872a0SLloyd Pique 
1685*84e872a0SLloyd Pique static int
_wl_display_add_socket(struct wl_display * display,struct wl_socket * s)1686*84e872a0SLloyd Pique _wl_display_add_socket(struct wl_display *display, struct wl_socket *s)
1687*84e872a0SLloyd Pique {
1688*84e872a0SLloyd Pique 	socklen_t size;
1689*84e872a0SLloyd Pique 
1690*84e872a0SLloyd Pique 	s->fd = wl_os_socket_cloexec(PF_LOCAL, SOCK_STREAM, 0);
1691*84e872a0SLloyd Pique 	if (s->fd < 0) {
1692*84e872a0SLloyd Pique 		return -1;
1693*84e872a0SLloyd Pique 	}
1694*84e872a0SLloyd Pique 
1695*84e872a0SLloyd Pique 	size = offsetof (struct sockaddr_un, sun_path) + strlen(s->addr.sun_path);
1696*84e872a0SLloyd Pique 	if (bind(s->fd, (struct sockaddr *) &s->addr, size) < 0) {
1697*84e872a0SLloyd Pique 		wl_log("bind() failed with error: %s\n", strerror(errno));
1698*84e872a0SLloyd Pique 		return -1;
1699*84e872a0SLloyd Pique 	}
1700*84e872a0SLloyd Pique 
1701*84e872a0SLloyd Pique 	if (listen(s->fd, 128) < 0) {
1702*84e872a0SLloyd Pique 		wl_log("listen() failed with error: %s\n", strerror(errno));
1703*84e872a0SLloyd Pique 		return -1;
1704*84e872a0SLloyd Pique 	}
1705*84e872a0SLloyd Pique 
1706*84e872a0SLloyd Pique 	s->source = wl_event_loop_add_fd(display->loop, s->fd,
1707*84e872a0SLloyd Pique 					 WL_EVENT_READABLE,
1708*84e872a0SLloyd Pique 					 socket_data, display);
1709*84e872a0SLloyd Pique 	if (s->source == NULL) {
1710*84e872a0SLloyd Pique 		return -1;
1711*84e872a0SLloyd Pique 	}
1712*84e872a0SLloyd Pique 
1713*84e872a0SLloyd Pique 	wl_list_insert(display->socket_list.prev, &s->link);
1714*84e872a0SLloyd Pique 	return 0;
1715*84e872a0SLloyd Pique }
1716*84e872a0SLloyd Pique 
1717*84e872a0SLloyd Pique WL_EXPORT const char *
wl_display_add_socket_auto(struct wl_display * display)1718*84e872a0SLloyd Pique wl_display_add_socket_auto(struct wl_display *display)
1719*84e872a0SLloyd Pique {
1720*84e872a0SLloyd Pique 	struct wl_socket *s;
1721*84e872a0SLloyd Pique 	int displayno = 0;
1722*84e872a0SLloyd Pique 	char display_name[20] = "";
1723*84e872a0SLloyd Pique 
1724*84e872a0SLloyd Pique 	/* A reasonable number of maximum default sockets. If
1725*84e872a0SLloyd Pique 	 * you need more than this, use the explicit add_socket API. */
1726*84e872a0SLloyd Pique 	const int MAX_DISPLAYNO = 32;
1727*84e872a0SLloyd Pique 
1728*84e872a0SLloyd Pique 	s = wl_socket_alloc();
1729*84e872a0SLloyd Pique 	if (s == NULL)
1730*84e872a0SLloyd Pique 		return NULL;
1731*84e872a0SLloyd Pique 
1732*84e872a0SLloyd Pique 	do {
1733*84e872a0SLloyd Pique 		snprintf(display_name, sizeof display_name, "wayland-%d", displayno);
1734*84e872a0SLloyd Pique 		if (wl_socket_init_for_display_name(s, display_name) < 0) {
1735*84e872a0SLloyd Pique 			wl_socket_destroy(s);
1736*84e872a0SLloyd Pique 			return NULL;
1737*84e872a0SLloyd Pique 		}
1738*84e872a0SLloyd Pique 
1739*84e872a0SLloyd Pique 		if (wl_socket_lock(s) < 0)
1740*84e872a0SLloyd Pique 			continue;
1741*84e872a0SLloyd Pique 
1742*84e872a0SLloyd Pique 		if (_wl_display_add_socket(display, s) < 0) {
1743*84e872a0SLloyd Pique 			wl_socket_destroy(s);
1744*84e872a0SLloyd Pique 			return NULL;
1745*84e872a0SLloyd Pique 		}
1746*84e872a0SLloyd Pique 
1747*84e872a0SLloyd Pique 		return s->display_name;
1748*84e872a0SLloyd Pique 	} while (displayno++ < MAX_DISPLAYNO);
1749*84e872a0SLloyd Pique 
1750*84e872a0SLloyd Pique 	/* Ran out of display names. */
1751*84e872a0SLloyd Pique 	wl_socket_destroy(s);
1752*84e872a0SLloyd Pique 	errno = EINVAL;
1753*84e872a0SLloyd Pique 	return NULL;
1754*84e872a0SLloyd Pique }
1755*84e872a0SLloyd Pique 
1756*84e872a0SLloyd Pique /**  Add a socket with an existing fd to Wayland display for the clients to connect.
1757*84e872a0SLloyd Pique  *
1758*84e872a0SLloyd Pique  * \param display Wayland display to which the socket should be added.
1759*84e872a0SLloyd Pique  * \param sock_fd The existing socket file descriptor to be used
1760*84e872a0SLloyd Pique  * \return 0 if success. -1 if failed.
1761*84e872a0SLloyd Pique  *
1762*84e872a0SLloyd Pique  * The existing socket fd must already be created, opened, and locked.
1763*84e872a0SLloyd Pique  * The fd must be properly set to CLOEXEC and bound to a socket file
1764*84e872a0SLloyd Pique  * with both bind() and listen() already called.
1765*84e872a0SLloyd Pique  *
1766*84e872a0SLloyd Pique  * \memberof wl_display
1767*84e872a0SLloyd Pique  */
1768*84e872a0SLloyd Pique WL_EXPORT int
wl_display_add_socket_fd(struct wl_display * display,int sock_fd)1769*84e872a0SLloyd Pique wl_display_add_socket_fd(struct wl_display *display, int sock_fd)
1770*84e872a0SLloyd Pique {
1771*84e872a0SLloyd Pique 	struct wl_socket *s;
1772*84e872a0SLloyd Pique 	struct stat buf;
1773*84e872a0SLloyd Pique 
1774*84e872a0SLloyd Pique 	/* Require a valid fd or fail */
1775*84e872a0SLloyd Pique 	if (sock_fd < 0 || fstat(sock_fd, &buf) < 0 || !S_ISSOCK(buf.st_mode)) {
1776*84e872a0SLloyd Pique 		return -1;
1777*84e872a0SLloyd Pique 	}
1778*84e872a0SLloyd Pique 
1779*84e872a0SLloyd Pique 	s = wl_socket_alloc();
1780*84e872a0SLloyd Pique 	if (s == NULL)
1781*84e872a0SLloyd Pique 		return -1;
1782*84e872a0SLloyd Pique 
1783*84e872a0SLloyd Pique 	s->source = wl_event_loop_add_fd(display->loop, sock_fd,
1784*84e872a0SLloyd Pique 					 WL_EVENT_READABLE,
1785*84e872a0SLloyd Pique 					 socket_data, display);
1786*84e872a0SLloyd Pique 	if (s->source == NULL) {
1787*84e872a0SLloyd Pique 		wl_log("failed to establish event source\n");
1788*84e872a0SLloyd Pique 		wl_socket_destroy(s);
1789*84e872a0SLloyd Pique 		return -1;
1790*84e872a0SLloyd Pique 	}
1791*84e872a0SLloyd Pique 
1792*84e872a0SLloyd Pique 	/* Reuse the existing fd */
1793*84e872a0SLloyd Pique 	s->fd = sock_fd;
1794*84e872a0SLloyd Pique 
1795*84e872a0SLloyd Pique 	wl_list_insert(display->socket_list.prev, &s->link);
1796*84e872a0SLloyd Pique 
1797*84e872a0SLloyd Pique 	return 0;
1798*84e872a0SLloyd Pique }
1799*84e872a0SLloyd Pique 
1800*84e872a0SLloyd Pique /** Add a socket to Wayland display for the clients to connect.
1801*84e872a0SLloyd Pique  *
1802*84e872a0SLloyd Pique  * \param display Wayland display to which the socket should be added.
1803*84e872a0SLloyd Pique  * \param name Name of the Unix socket.
1804*84e872a0SLloyd Pique  * \return 0 if success. -1 if failed.
1805*84e872a0SLloyd Pique  *
1806*84e872a0SLloyd Pique  * This adds a Unix socket to Wayland display which can be used by clients to
1807*84e872a0SLloyd Pique  * connect to Wayland display.
1808*84e872a0SLloyd Pique  *
1809*84e872a0SLloyd Pique  * If NULL is passed as name, then it would look for WAYLAND_DISPLAY env
1810*84e872a0SLloyd Pique  * variable for the socket name. If WAYLAND_DISPLAY is not set, then default
1811*84e872a0SLloyd Pique  * wayland-0 is used.
1812*84e872a0SLloyd Pique  *
1813*84e872a0SLloyd Pique  * If the socket name is a relative path, the Unix socket will be created in
1814*84e872a0SLloyd Pique  * the directory pointed to by environment variable XDG_RUNTIME_DIR. If
1815*84e872a0SLloyd Pique  * XDG_RUNTIME_DIR is invalid or not set, then this function fails and returns -1.
1816*84e872a0SLloyd Pique  *
1817*84e872a0SLloyd Pique  * If the socket name is an absolute path, then it is used as-is for the
1818*84e872a0SLloyd Pique  * the Unix socket.
1819*84e872a0SLloyd Pique  *
1820*84e872a0SLloyd Pique  * The length of the computed socket path must not exceed the maximum length
1821*84e872a0SLloyd Pique  * of a Unix socket path.
1822*84e872a0SLloyd Pique  * The function also fails if the user does not have write permission in the
1823*84e872a0SLloyd Pique  * directory or if the path is already in use.
1824*84e872a0SLloyd Pique  *
1825*84e872a0SLloyd Pique  * \memberof wl_display
1826*84e872a0SLloyd Pique  */
1827*84e872a0SLloyd Pique WL_EXPORT int
wl_display_add_socket(struct wl_display * display,const char * name)1828*84e872a0SLloyd Pique wl_display_add_socket(struct wl_display *display, const char *name)
1829*84e872a0SLloyd Pique {
1830*84e872a0SLloyd Pique 	struct wl_socket *s;
1831*84e872a0SLloyd Pique 
1832*84e872a0SLloyd Pique 	s = wl_socket_alloc();
1833*84e872a0SLloyd Pique 	if (s == NULL)
1834*84e872a0SLloyd Pique 		return -1;
1835*84e872a0SLloyd Pique 
1836*84e872a0SLloyd Pique 	if (name == NULL)
1837*84e872a0SLloyd Pique 		name = getenv("WAYLAND_DISPLAY");
1838*84e872a0SLloyd Pique 	if (name == NULL)
1839*84e872a0SLloyd Pique 		name = "wayland-0";
1840*84e872a0SLloyd Pique 
1841*84e872a0SLloyd Pique 	if (wl_socket_init_for_display_name(s, name) < 0) {
1842*84e872a0SLloyd Pique 		wl_socket_destroy(s);
1843*84e872a0SLloyd Pique 		return -1;
1844*84e872a0SLloyd Pique 	}
1845*84e872a0SLloyd Pique 
1846*84e872a0SLloyd Pique 	if (wl_socket_lock(s) < 0) {
1847*84e872a0SLloyd Pique 		wl_socket_destroy(s);
1848*84e872a0SLloyd Pique 		return -1;
1849*84e872a0SLloyd Pique 	}
1850*84e872a0SLloyd Pique 
1851*84e872a0SLloyd Pique 	if (_wl_display_add_socket(display, s) < 0) {
1852*84e872a0SLloyd Pique 		wl_socket_destroy(s);
1853*84e872a0SLloyd Pique 		return -1;
1854*84e872a0SLloyd Pique 	}
1855*84e872a0SLloyd Pique 
1856*84e872a0SLloyd Pique 	return 0;
1857*84e872a0SLloyd Pique }
1858*84e872a0SLloyd Pique 
1859*84e872a0SLloyd Pique WL_EXPORT void
wl_display_add_destroy_listener(struct wl_display * display,struct wl_listener * listener)1860*84e872a0SLloyd Pique wl_display_add_destroy_listener(struct wl_display *display,
1861*84e872a0SLloyd Pique 				struct wl_listener *listener)
1862*84e872a0SLloyd Pique {
1863*84e872a0SLloyd Pique 	wl_priv_signal_add(&display->destroy_signal, listener);
1864*84e872a0SLloyd Pique }
1865*84e872a0SLloyd Pique 
1866*84e872a0SLloyd Pique /** Registers a listener for the client connection signal.
1867*84e872a0SLloyd Pique  *  When a new client object is created, \a listener will be notified, carrying
1868*84e872a0SLloyd Pique  *  a pointer to the new wl_client object.
1869*84e872a0SLloyd Pique  *
1870*84e872a0SLloyd Pique  *  \ref wl_client_create
1871*84e872a0SLloyd Pique  *  \ref wl_display
1872*84e872a0SLloyd Pique  *  \ref wl_listener
1873*84e872a0SLloyd Pique  *
1874*84e872a0SLloyd Pique  * \param display The display object
1875*84e872a0SLloyd Pique  * \param listener Signal handler object
1876*84e872a0SLloyd Pique  */
1877*84e872a0SLloyd Pique WL_EXPORT void
wl_display_add_client_created_listener(struct wl_display * display,struct wl_listener * listener)1878*84e872a0SLloyd Pique wl_display_add_client_created_listener(struct wl_display *display,
1879*84e872a0SLloyd Pique 					struct wl_listener *listener)
1880*84e872a0SLloyd Pique {
1881*84e872a0SLloyd Pique 	wl_priv_signal_add(&display->create_client_signal, listener);
1882*84e872a0SLloyd Pique }
1883*84e872a0SLloyd Pique 
1884*84e872a0SLloyd Pique WL_EXPORT struct wl_listener *
wl_display_get_destroy_listener(struct wl_display * display,wl_notify_func_t notify)1885*84e872a0SLloyd Pique wl_display_get_destroy_listener(struct wl_display *display,
1886*84e872a0SLloyd Pique 				wl_notify_func_t notify)
1887*84e872a0SLloyd Pique {
1888*84e872a0SLloyd Pique 	return wl_priv_signal_get(&display->destroy_signal, notify);
1889*84e872a0SLloyd Pique }
1890*84e872a0SLloyd Pique 
1891*84e872a0SLloyd Pique WL_EXPORT void
wl_resource_set_implementation(struct wl_resource * resource,const void * implementation,void * data,wl_resource_destroy_func_t destroy)1892*84e872a0SLloyd Pique wl_resource_set_implementation(struct wl_resource *resource,
1893*84e872a0SLloyd Pique 			       const void *implementation,
1894*84e872a0SLloyd Pique 			       void *data, wl_resource_destroy_func_t destroy)
1895*84e872a0SLloyd Pique {
1896*84e872a0SLloyd Pique 	resource->object.implementation = implementation;
1897*84e872a0SLloyd Pique 	resource->data = data;
1898*84e872a0SLloyd Pique 	resource->destroy = destroy;
1899*84e872a0SLloyd Pique 	resource->dispatcher = NULL;
1900*84e872a0SLloyd Pique }
1901*84e872a0SLloyd Pique 
1902*84e872a0SLloyd Pique 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)1903*84e872a0SLloyd Pique wl_resource_set_dispatcher(struct wl_resource *resource,
1904*84e872a0SLloyd Pique 			   wl_dispatcher_func_t dispatcher,
1905*84e872a0SLloyd Pique 			   const void *implementation,
1906*84e872a0SLloyd Pique 			   void *data, wl_resource_destroy_func_t destroy)
1907*84e872a0SLloyd Pique {
1908*84e872a0SLloyd Pique 	resource->dispatcher = dispatcher;
1909*84e872a0SLloyd Pique 	resource->object.implementation = implementation;
1910*84e872a0SLloyd Pique 	resource->data = data;
1911*84e872a0SLloyd Pique 	resource->destroy = destroy;
1912*84e872a0SLloyd Pique }
1913*84e872a0SLloyd Pique 
1914*84e872a0SLloyd Pique /** Create a new resource object
1915*84e872a0SLloyd Pique  *
1916*84e872a0SLloyd Pique  * \param client The client owner of the new resource.
1917*84e872a0SLloyd Pique  * \param interface The interface of the new resource.
1918*84e872a0SLloyd Pique  * \param version The version of the new resource.
1919*84e872a0SLloyd Pique  * \param id The id of the new resource. If 0, an available id will be used.
1920*84e872a0SLloyd Pique  *
1921*84e872a0SLloyd Pique  * Listeners added with \a wl_client_add_resource_created_listener will be
1922*84e872a0SLloyd Pique  * notified at the end of this function.
1923*84e872a0SLloyd Pique  *
1924*84e872a0SLloyd Pique  * \memberof wl_resource
1925*84e872a0SLloyd Pique  */
1926*84e872a0SLloyd Pique WL_EXPORT struct wl_resource *
wl_resource_create(struct wl_client * client,const struct wl_interface * interface,int version,uint32_t id)1927*84e872a0SLloyd Pique wl_resource_create(struct wl_client *client,
1928*84e872a0SLloyd Pique 		   const struct wl_interface *interface,
1929*84e872a0SLloyd Pique 		   int version, uint32_t id)
1930*84e872a0SLloyd Pique {
1931*84e872a0SLloyd Pique 	struct wl_resource *resource;
1932*84e872a0SLloyd Pique 
1933*84e872a0SLloyd Pique 	resource = zalloc(sizeof *resource);
1934*84e872a0SLloyd Pique 	if (resource == NULL)
1935*84e872a0SLloyd Pique 		return NULL;
1936*84e872a0SLloyd Pique 
1937*84e872a0SLloyd Pique 	if (id == 0) {
1938*84e872a0SLloyd Pique 		id = wl_map_insert_new(&client->objects, 0, NULL);
1939*84e872a0SLloyd Pique 		if (id == 0) {
1940*84e872a0SLloyd Pique 			free(resource);
1941*84e872a0SLloyd Pique 			return NULL;
1942*84e872a0SLloyd Pique 		}
1943*84e872a0SLloyd Pique 	}
1944*84e872a0SLloyd Pique 
1945*84e872a0SLloyd Pique 	resource->object.id = id;
1946*84e872a0SLloyd Pique 	resource->object.interface = interface;
1947*84e872a0SLloyd Pique 	resource->object.implementation = NULL;
1948*84e872a0SLloyd Pique 
1949*84e872a0SLloyd Pique 	wl_signal_init(&resource->deprecated_destroy_signal);
1950*84e872a0SLloyd Pique 	wl_priv_signal_init(&resource->destroy_signal);
1951*84e872a0SLloyd Pique 
1952*84e872a0SLloyd Pique 	resource->destroy = NULL;
1953*84e872a0SLloyd Pique 	resource->client = client;
1954*84e872a0SLloyd Pique 	resource->data = NULL;
1955*84e872a0SLloyd Pique 	resource->version = version;
1956*84e872a0SLloyd Pique 	resource->dispatcher = NULL;
1957*84e872a0SLloyd Pique 
1958*84e872a0SLloyd Pique 	if (wl_map_insert_at(&client->objects, 0, id, resource) < 0) {
1959*84e872a0SLloyd Pique 		if (errno == EINVAL) {
1960*84e872a0SLloyd Pique 			wl_resource_post_error(client->display_resource,
1961*84e872a0SLloyd Pique 					       WL_DISPLAY_ERROR_INVALID_OBJECT,
1962*84e872a0SLloyd Pique 					       "invalid new id %d", id);
1963*84e872a0SLloyd Pique 		}
1964*84e872a0SLloyd Pique 		free(resource);
1965*84e872a0SLloyd Pique 		return NULL;
1966*84e872a0SLloyd Pique 	}
1967*84e872a0SLloyd Pique 
1968*84e872a0SLloyd Pique 	wl_priv_signal_emit(&client->resource_created_signal, resource);
1969*84e872a0SLloyd Pique 	return resource;
1970*84e872a0SLloyd Pique }
1971*84e872a0SLloyd Pique 
1972*84e872a0SLloyd Pique WL_EXPORT void
wl_log_set_handler_server(wl_log_func_t handler)1973*84e872a0SLloyd Pique wl_log_set_handler_server(wl_log_func_t handler)
1974*84e872a0SLloyd Pique {
1975*84e872a0SLloyd Pique 	wl_log_handler = handler;
1976*84e872a0SLloyd Pique }
1977*84e872a0SLloyd Pique 
1978*84e872a0SLloyd Pique /** Adds a new protocol logger.
1979*84e872a0SLloyd Pique  *
1980*84e872a0SLloyd Pique  * When a new protocol message arrives or is sent from the server
1981*84e872a0SLloyd Pique  * all the protocol logger functions will be called, carrying the
1982*84e872a0SLloyd Pique  * \a user_data pointer, the type of the message (request or
1983*84e872a0SLloyd Pique  * event) and the actual message.
1984*84e872a0SLloyd Pique  * The lifetime of the messages passed to the logger function ends
1985*84e872a0SLloyd Pique  * when they return so the messages cannot be stored and accessed
1986*84e872a0SLloyd Pique  * later.
1987*84e872a0SLloyd Pique  *
1988*84e872a0SLloyd Pique  * \a errno is set on error.
1989*84e872a0SLloyd Pique  *
1990*84e872a0SLloyd Pique  * \param display The display object
1991*84e872a0SLloyd Pique  * \param func The function to call to log a new protocol message
1992*84e872a0SLloyd Pique  * \param user_data The user data pointer to pass to \a func
1993*84e872a0SLloyd Pique  *
1994*84e872a0SLloyd Pique  * \return The protol logger object on success, NULL on failure.
1995*84e872a0SLloyd Pique  *
1996*84e872a0SLloyd Pique  * \sa wl_protocol_logger_destroy
1997*84e872a0SLloyd Pique  *
1998*84e872a0SLloyd Pique  * \memberof wl_display
1999*84e872a0SLloyd Pique  */
2000*84e872a0SLloyd Pique WL_EXPORT struct wl_protocol_logger *
wl_display_add_protocol_logger(struct wl_display * display,wl_protocol_logger_func_t func,void * user_data)2001*84e872a0SLloyd Pique wl_display_add_protocol_logger(struct wl_display *display,
2002*84e872a0SLloyd Pique 			       wl_protocol_logger_func_t func, void *user_data)
2003*84e872a0SLloyd Pique {
2004*84e872a0SLloyd Pique 	struct wl_protocol_logger *logger;
2005*84e872a0SLloyd Pique 
2006*84e872a0SLloyd Pique 	logger = zalloc(sizeof *logger);
2007*84e872a0SLloyd Pique 	if (!logger)
2008*84e872a0SLloyd Pique 		return NULL;
2009*84e872a0SLloyd Pique 
2010*84e872a0SLloyd Pique 	logger->func = func;
2011*84e872a0SLloyd Pique 	logger->user_data = user_data;
2012*84e872a0SLloyd Pique 	wl_list_insert(&display->protocol_loggers, &logger->link);
2013*84e872a0SLloyd Pique 
2014*84e872a0SLloyd Pique 	return logger;
2015*84e872a0SLloyd Pique }
2016*84e872a0SLloyd Pique 
2017*84e872a0SLloyd Pique /** Destroys a protocol logger.
2018*84e872a0SLloyd Pique  *
2019*84e872a0SLloyd Pique  * This function destroys a protocol logger and removes it from the display
2020*84e872a0SLloyd Pique  * it was added to with \a wl_display_add_protocol_logger.
2021*84e872a0SLloyd Pique  * The \a logger object becomes invalid after calling this function.
2022*84e872a0SLloyd Pique  *
2023*84e872a0SLloyd Pique  * \sa wl_display_add_protocol_logger
2024*84e872a0SLloyd Pique  *
2025*84e872a0SLloyd Pique  * \memberof wl_protocol_logger
2026*84e872a0SLloyd Pique  */
2027*84e872a0SLloyd Pique WL_EXPORT void
wl_protocol_logger_destroy(struct wl_protocol_logger * logger)2028*84e872a0SLloyd Pique wl_protocol_logger_destroy(struct wl_protocol_logger *logger)
2029*84e872a0SLloyd Pique {
2030*84e872a0SLloyd Pique 	wl_list_remove(&logger->link);
2031*84e872a0SLloyd Pique 	free(logger);
2032*84e872a0SLloyd Pique }
2033*84e872a0SLloyd Pique 
2034*84e872a0SLloyd Pique /** Add support for a wl_shm pixel format
2035*84e872a0SLloyd Pique  *
2036*84e872a0SLloyd Pique  * \param display The display object
2037*84e872a0SLloyd Pique  * \param format The wl_shm pixel format to advertise
2038*84e872a0SLloyd Pique  * \return A pointer to the wl_shm format that was added to the list
2039*84e872a0SLloyd Pique  * or NULL if adding it to the list failed.
2040*84e872a0SLloyd Pique  *
2041*84e872a0SLloyd Pique  * Add the specified wl_shm format to the list of formats the wl_shm
2042*84e872a0SLloyd Pique  * object advertises when a client binds to it.  Adding a format to
2043*84e872a0SLloyd Pique  * the list means that clients will know that the compositor supports
2044*84e872a0SLloyd Pique  * this format and may use it for creating wl_shm buffers.  The
2045*84e872a0SLloyd Pique  * compositor must be able to handle the pixel format when a client
2046*84e872a0SLloyd Pique  * requests it.
2047*84e872a0SLloyd Pique  *
2048*84e872a0SLloyd Pique  * The compositor by default supports WL_SHM_FORMAT_ARGB8888 and
2049*84e872a0SLloyd Pique  * WL_SHM_FORMAT_XRGB8888.
2050*84e872a0SLloyd Pique  *
2051*84e872a0SLloyd Pique  * \memberof wl_display
2052*84e872a0SLloyd Pique  */
2053*84e872a0SLloyd Pique WL_EXPORT uint32_t *
wl_display_add_shm_format(struct wl_display * display,uint32_t format)2054*84e872a0SLloyd Pique wl_display_add_shm_format(struct wl_display *display, uint32_t format)
2055*84e872a0SLloyd Pique {
2056*84e872a0SLloyd Pique 	uint32_t *p = NULL;
2057*84e872a0SLloyd Pique 
2058*84e872a0SLloyd Pique 	p = wl_array_add(&display->additional_shm_formats, sizeof *p);
2059*84e872a0SLloyd Pique 
2060*84e872a0SLloyd Pique 	if (p != NULL)
2061*84e872a0SLloyd Pique 		*p = format;
2062*84e872a0SLloyd Pique 	return p;
2063*84e872a0SLloyd Pique }
2064*84e872a0SLloyd Pique 
2065*84e872a0SLloyd Pique /**
2066*84e872a0SLloyd Pique  * Get list of additional wl_shm pixel formats
2067*84e872a0SLloyd Pique  *
2068*84e872a0SLloyd Pique  * \param display The display object
2069*84e872a0SLloyd Pique  *
2070*84e872a0SLloyd Pique  * This function returns the list of addition wl_shm pixel formats
2071*84e872a0SLloyd Pique  * that the compositor supports.  WL_SHM_FORMAT_ARGB8888 and
2072*84e872a0SLloyd Pique  * WL_SHM_FORMAT_XRGB8888 are always supported and not included in the
2073*84e872a0SLloyd Pique  * array, but all formats added through wl_display_add_shm_format()
2074*84e872a0SLloyd Pique  * will be in the array.
2075*84e872a0SLloyd Pique  *
2076*84e872a0SLloyd Pique  * \sa wl_display_add_shm_format()
2077*84e872a0SLloyd Pique  *
2078*84e872a0SLloyd Pique  * \private
2079*84e872a0SLloyd Pique  *
2080*84e872a0SLloyd Pique  * \memberof wl_display
2081*84e872a0SLloyd Pique  */
2082*84e872a0SLloyd Pique struct wl_array *
wl_display_get_additional_shm_formats(struct wl_display * display)2083*84e872a0SLloyd Pique wl_display_get_additional_shm_formats(struct wl_display *display)
2084*84e872a0SLloyd Pique {
2085*84e872a0SLloyd Pique 	return &display->additional_shm_formats;
2086*84e872a0SLloyd Pique }
2087*84e872a0SLloyd Pique 
2088*84e872a0SLloyd Pique /** Get the list of currently connected clients
2089*84e872a0SLloyd Pique  *
2090*84e872a0SLloyd Pique  * \param display The display object
2091*84e872a0SLloyd Pique  *
2092*84e872a0SLloyd Pique  * This function returns a pointer to the list of clients currently
2093*84e872a0SLloyd Pique  * connected to the display. You can iterate on the list by using
2094*84e872a0SLloyd Pique  * the \a wl_client_for_each macro.
2095*84e872a0SLloyd Pique  * The returned value is valid for the lifetime of the \a display.
2096*84e872a0SLloyd Pique  * You must not modify the returned list, but only access it.
2097*84e872a0SLloyd Pique  *
2098*84e872a0SLloyd Pique  * \sa wl_client_for_each()
2099*84e872a0SLloyd Pique  * \sa wl_client_get_link()
2100*84e872a0SLloyd Pique  * \sa wl_client_from_link()
2101*84e872a0SLloyd Pique  *
2102*84e872a0SLloyd Pique  * \memberof wl_display
2103*84e872a0SLloyd Pique  */
2104*84e872a0SLloyd Pique WL_EXPORT struct wl_list *
wl_display_get_client_list(struct wl_display * display)2105*84e872a0SLloyd Pique wl_display_get_client_list(struct wl_display *display)
2106*84e872a0SLloyd Pique {
2107*84e872a0SLloyd Pique 	return &display->client_list;
2108*84e872a0SLloyd Pique }
2109*84e872a0SLloyd Pique 
2110*84e872a0SLloyd Pique /** Get the link by which a client is inserted in the client list
2111*84e872a0SLloyd Pique  *
2112*84e872a0SLloyd Pique  * \param client The client object
2113*84e872a0SLloyd Pique  *
2114*84e872a0SLloyd Pique  * \sa wl_client_for_each()
2115*84e872a0SLloyd Pique  * \sa wl_display_get_client_list()
2116*84e872a0SLloyd Pique  * \sa wl_client_from_link()
2117*84e872a0SLloyd Pique  *
2118*84e872a0SLloyd Pique  * \memberof wl_client
2119*84e872a0SLloyd Pique  */
2120*84e872a0SLloyd Pique WL_EXPORT struct wl_list *
wl_client_get_link(struct wl_client * client)2121*84e872a0SLloyd Pique wl_client_get_link(struct wl_client *client)
2122*84e872a0SLloyd Pique {
2123*84e872a0SLloyd Pique 	return &client->link;
2124*84e872a0SLloyd Pique }
2125*84e872a0SLloyd Pique 
2126*84e872a0SLloyd Pique /** Get a wl_client by its link
2127*84e872a0SLloyd Pique  *
2128*84e872a0SLloyd Pique  * \param link The link of a wl_client
2129*84e872a0SLloyd Pique  *
2130*84e872a0SLloyd Pique  * \sa wl_client_for_each()
2131*84e872a0SLloyd Pique  * \sa wl_display_get_client_list()
2132*84e872a0SLloyd Pique  * \sa wl_client_get_link()
2133*84e872a0SLloyd Pique  *
2134*84e872a0SLloyd Pique  * \memberof wl_client
2135*84e872a0SLloyd Pique  */
2136*84e872a0SLloyd Pique WL_EXPORT struct wl_client *
wl_client_from_link(struct wl_list * link)2137*84e872a0SLloyd Pique wl_client_from_link(struct wl_list *link)
2138*84e872a0SLloyd Pique {
2139*84e872a0SLloyd Pique 	struct wl_client *client;
2140*84e872a0SLloyd Pique 
2141*84e872a0SLloyd Pique 	return wl_container_of(link, client, link);
2142*84e872a0SLloyd Pique }
2143*84e872a0SLloyd Pique 
2144*84e872a0SLloyd Pique /** Add a listener for the client's resource creation signal
2145*84e872a0SLloyd Pique  *
2146*84e872a0SLloyd Pique  * \param client The client object
2147*84e872a0SLloyd Pique  * \param listener The listener to be added
2148*84e872a0SLloyd Pique  *
2149*84e872a0SLloyd Pique  * When a new resource is created for this client the listener
2150*84e872a0SLloyd Pique  * will be notified, carrying the new resource as the data argument.
2151*84e872a0SLloyd Pique  *
2152*84e872a0SLloyd Pique  * \memberof wl_client
2153*84e872a0SLloyd Pique  */
2154*84e872a0SLloyd Pique WL_EXPORT void
wl_client_add_resource_created_listener(struct wl_client * client,struct wl_listener * listener)2155*84e872a0SLloyd Pique wl_client_add_resource_created_listener(struct wl_client *client,
2156*84e872a0SLloyd Pique 					struct wl_listener *listener)
2157*84e872a0SLloyd Pique {
2158*84e872a0SLloyd Pique 	wl_priv_signal_add(&client->resource_created_signal, listener);
2159*84e872a0SLloyd Pique }
2160*84e872a0SLloyd Pique 
2161*84e872a0SLloyd Pique struct wl_resource_iterator_context {
2162*84e872a0SLloyd Pique 	void *user_data;
2163*84e872a0SLloyd Pique 	wl_client_for_each_resource_iterator_func_t it;
2164*84e872a0SLloyd Pique };
2165*84e872a0SLloyd Pique 
2166*84e872a0SLloyd Pique static enum wl_iterator_result
resource_iterator_helper(void * res,void * user_data,uint32_t flags)2167*84e872a0SLloyd Pique resource_iterator_helper(void *res, void *user_data, uint32_t flags)
2168*84e872a0SLloyd Pique {
2169*84e872a0SLloyd Pique 	struct wl_resource_iterator_context *context = user_data;
2170*84e872a0SLloyd Pique 	struct wl_resource *resource = res;
2171*84e872a0SLloyd Pique 
2172*84e872a0SLloyd Pique 	return context->it(resource, context->user_data);
2173*84e872a0SLloyd Pique }
2174*84e872a0SLloyd Pique 
2175*84e872a0SLloyd Pique /** Iterate over all the resources of a client
2176*84e872a0SLloyd Pique  *
2177*84e872a0SLloyd Pique  * \param client The client object
2178*84e872a0SLloyd Pique  * \param iterator The iterator function
2179*84e872a0SLloyd Pique  * \param user_data The user data pointer
2180*84e872a0SLloyd Pique  *
2181*84e872a0SLloyd Pique  * The function pointed by \a iterator will be called for each
2182*84e872a0SLloyd Pique  * resource owned by the client. The \a user_data will be passed
2183*84e872a0SLloyd Pique  * as the second argument of the iterator function.
2184*84e872a0SLloyd Pique  * If the \a iterator function returns \a WL_ITERATOR_CONTINUE the iteration
2185*84e872a0SLloyd Pique  * will continue, if it returns \a WL_ITERATOR_STOP it will stop.
2186*84e872a0SLloyd Pique  *
2187*84e872a0SLloyd Pique  * Creating and destroying resources while iterating is safe, but new
2188*84e872a0SLloyd Pique  * resources may or may not be picked up by the iterator.
2189*84e872a0SLloyd Pique  *
2190*84e872a0SLloyd Pique  * \sa wl_iterator_result
2191*84e872a0SLloyd Pique  *
2192*84e872a0SLloyd Pique  * \memberof wl_client
2193*84e872a0SLloyd Pique  */
2194*84e872a0SLloyd Pique WL_EXPORT void
wl_client_for_each_resource(struct wl_client * client,wl_client_for_each_resource_iterator_func_t iterator,void * user_data)2195*84e872a0SLloyd Pique wl_client_for_each_resource(struct wl_client *client,
2196*84e872a0SLloyd Pique 			    wl_client_for_each_resource_iterator_func_t iterator,
2197*84e872a0SLloyd Pique 			    void *user_data)
2198*84e872a0SLloyd Pique {
2199*84e872a0SLloyd Pique 	struct wl_resource_iterator_context context = {
2200*84e872a0SLloyd Pique 		.user_data = user_data,
2201*84e872a0SLloyd Pique 		.it = iterator,
2202*84e872a0SLloyd Pique 	};
2203*84e872a0SLloyd Pique 
2204*84e872a0SLloyd Pique 	wl_map_for_each(&client->objects, resource_iterator_helper, &context);
2205*84e872a0SLloyd Pique }
2206*84e872a0SLloyd Pique 
2207*84e872a0SLloyd Pique static void
handle_noop(struct wl_listener * listener,void * data)2208*84e872a0SLloyd Pique handle_noop(struct wl_listener *listener, void *data)
2209*84e872a0SLloyd Pique {
2210*84e872a0SLloyd Pique 	/* Do nothing */
2211*84e872a0SLloyd Pique }
2212*84e872a0SLloyd Pique 
2213*84e872a0SLloyd Pique /** Emits this signal, notifying all registered listeners.
2214*84e872a0SLloyd Pique  *
2215*84e872a0SLloyd Pique  * A safer version of wl_signal_emit() which can gracefully handle additions
2216*84e872a0SLloyd Pique  * and deletions of any signal listener from within listener notification
2217*84e872a0SLloyd Pique  * callbacks.
2218*84e872a0SLloyd Pique  *
2219*84e872a0SLloyd Pique  * Listeners deleted during a signal emission and which have not already been
2220*84e872a0SLloyd Pique  * notified at the time of deletion are not notified by that emission.
2221*84e872a0SLloyd Pique  *
2222*84e872a0SLloyd Pique  * Listeners added (or readded) during signal emission are ignored by that
2223*84e872a0SLloyd Pique  * emission.
2224*84e872a0SLloyd Pique  *
2225*84e872a0SLloyd Pique  * Note that repurposing a listener without explicitly removing it and readding
2226*84e872a0SLloyd Pique  * it is not supported and can lead to unexpected behavior.
2227*84e872a0SLloyd Pique  *
2228*84e872a0SLloyd Pique  * \param signal The signal object that will emit the signal
2229*84e872a0SLloyd Pique  * \param data The data that will be emitted with the signal
2230*84e872a0SLloyd Pique  *
2231*84e872a0SLloyd Pique  * \memberof wl_signal
2232*84e872a0SLloyd Pique  * \since 1.20.90
2233*84e872a0SLloyd Pique  */
2234*84e872a0SLloyd Pique WL_EXPORT void
wl_signal_emit_mutable(struct wl_signal * signal,void * data)2235*84e872a0SLloyd Pique wl_signal_emit_mutable(struct wl_signal *signal, void *data)
2236*84e872a0SLloyd Pique {
2237*84e872a0SLloyd Pique 	struct wl_listener cursor;
2238*84e872a0SLloyd Pique 	struct wl_listener end;
2239*84e872a0SLloyd Pique 
2240*84e872a0SLloyd Pique 	/* Add two special markers: one cursor and one end marker. This way, we
2241*84e872a0SLloyd Pique 	 * know that we've already called listeners on the left of the cursor
2242*84e872a0SLloyd Pique 	 * and that we don't want to call listeners on the right of the end
2243*84e872a0SLloyd Pique 	 * marker. The 'it' function can remove any element it wants from the
2244*84e872a0SLloyd Pique 	 * list without troubles.
2245*84e872a0SLloyd Pique 	 *
2246*84e872a0SLloyd Pique 	 * There was a previous attempt that used to steal the whole list of
2247*84e872a0SLloyd Pique 	 * listeners but then that broke wl_signal_get().
2248*84e872a0SLloyd Pique 	 *
2249*84e872a0SLloyd Pique 	 * wl_list_for_each_safe tries to be safe but it fails: it works fine
2250*84e872a0SLloyd Pique 	 * if the current item is removed, but not if the next one is. */
2251*84e872a0SLloyd Pique 	wl_list_insert(&signal->listener_list, &cursor.link);
2252*84e872a0SLloyd Pique 	cursor.notify = handle_noop;
2253*84e872a0SLloyd Pique 	wl_list_insert(signal->listener_list.prev, &end.link);
2254*84e872a0SLloyd Pique 	end.notify = handle_noop;
2255*84e872a0SLloyd Pique 
2256*84e872a0SLloyd Pique 	while (cursor.link.next != &end.link) {
2257*84e872a0SLloyd Pique 		struct wl_list *pos = cursor.link.next;
2258*84e872a0SLloyd Pique 		struct wl_listener *l = wl_container_of(pos, l, link);
2259*84e872a0SLloyd Pique 
2260*84e872a0SLloyd Pique 		wl_list_remove(&cursor.link);
2261*84e872a0SLloyd Pique 		wl_list_insert(pos, &cursor.link);
2262*84e872a0SLloyd Pique 
2263*84e872a0SLloyd Pique 		l->notify(l, data);
2264*84e872a0SLloyd Pique 	}
2265*84e872a0SLloyd Pique 
2266*84e872a0SLloyd Pique 	wl_list_remove(&cursor.link);
2267*84e872a0SLloyd Pique 	wl_list_remove(&end.link);
2268*84e872a0SLloyd Pique }
2269*84e872a0SLloyd Pique 
2270*84e872a0SLloyd Pique /** \cond INTERNAL */
2271*84e872a0SLloyd Pique 
2272*84e872a0SLloyd Pique /** Initialize a wl_priv_signal object
2273*84e872a0SLloyd Pique  *
2274*84e872a0SLloyd Pique  * wl_priv_signal is a safer implementation of a signal type, with the same API
2275*84e872a0SLloyd Pique  * as wl_signal, but kept as a private utility of libwayland-server.
2276*84e872a0SLloyd Pique  * It is safer because listeners can be removed from within wl_priv_signal_emit()
2277*84e872a0SLloyd Pique  * without corrupting the signal's list.
2278*84e872a0SLloyd Pique  *
2279*84e872a0SLloyd Pique  * Before passing a wl_priv_signal object to any other function it must be
2280*84e872a0SLloyd Pique  * initialized by using wl_priv_signal_init().
2281*84e872a0SLloyd Pique  *
2282*84e872a0SLloyd Pique  * \memberof wl_priv_signal
2283*84e872a0SLloyd Pique  */
2284*84e872a0SLloyd Pique void
wl_priv_signal_init(struct wl_priv_signal * signal)2285*84e872a0SLloyd Pique wl_priv_signal_init(struct wl_priv_signal *signal)
2286*84e872a0SLloyd Pique {
2287*84e872a0SLloyd Pique 	wl_list_init(&signal->listener_list);
2288*84e872a0SLloyd Pique 	wl_list_init(&signal->emit_list);
2289*84e872a0SLloyd Pique }
2290*84e872a0SLloyd Pique 
2291*84e872a0SLloyd Pique /** Add a listener to a signal
2292*84e872a0SLloyd Pique  *
2293*84e872a0SLloyd Pique  * The new listener will be called when calling wl_signal_emit(). If a listener is
2294*84e872a0SLloyd Pique  * added to the signal while wl_signal_emit() is running it will be called from
2295*84e872a0SLloyd Pique  * the next time wl_priv_signal_emit() is called.
2296*84e872a0SLloyd Pique  * To remove a listener call wl_list_remove() on its link member.
2297*84e872a0SLloyd Pique  *
2298*84e872a0SLloyd Pique  * \memberof wl_priv_signal
2299*84e872a0SLloyd Pique  */
2300*84e872a0SLloyd Pique void
wl_priv_signal_add(struct wl_priv_signal * signal,struct wl_listener * listener)2301*84e872a0SLloyd Pique wl_priv_signal_add(struct wl_priv_signal *signal, struct wl_listener *listener)
2302*84e872a0SLloyd Pique {
2303*84e872a0SLloyd Pique 	wl_list_insert(signal->listener_list.prev, &listener->link);
2304*84e872a0SLloyd Pique }
2305*84e872a0SLloyd Pique 
2306*84e872a0SLloyd Pique /** Get a listener added to a signal
2307*84e872a0SLloyd Pique  *
2308*84e872a0SLloyd Pique  * Returns the listener added to the given \a signal and with the given
2309*84e872a0SLloyd Pique  * \a notify function, or NULL if there isn't any.
2310*84e872a0SLloyd Pique  * Calling this function from within wl_priv_signal_emit() is safe and will
2311*84e872a0SLloyd Pique  * return the correct value.
2312*84e872a0SLloyd Pique  *
2313*84e872a0SLloyd Pique  * \memberof wl_priv_signal
2314*84e872a0SLloyd Pique  */
2315*84e872a0SLloyd Pique struct wl_listener *
wl_priv_signal_get(struct wl_priv_signal * signal,wl_notify_func_t notify)2316*84e872a0SLloyd Pique wl_priv_signal_get(struct wl_priv_signal *signal, wl_notify_func_t notify)
2317*84e872a0SLloyd Pique {
2318*84e872a0SLloyd Pique 	struct wl_listener *l;
2319*84e872a0SLloyd Pique 
2320*84e872a0SLloyd Pique 	wl_list_for_each(l, &signal->listener_list, link)
2321*84e872a0SLloyd Pique 		if (l->notify == notify)
2322*84e872a0SLloyd Pique 			return l;
2323*84e872a0SLloyd Pique 	wl_list_for_each(l, &signal->emit_list, link)
2324*84e872a0SLloyd Pique 		if (l->notify == notify)
2325*84e872a0SLloyd Pique 			return l;
2326*84e872a0SLloyd Pique 
2327*84e872a0SLloyd Pique 	return NULL;
2328*84e872a0SLloyd Pique }
2329*84e872a0SLloyd Pique 
2330*84e872a0SLloyd Pique /** Emit the signal, calling all the installed listeners
2331*84e872a0SLloyd Pique  *
2332*84e872a0SLloyd Pique  * Iterate over all the listeners added to this \a signal and call
2333*84e872a0SLloyd Pique  * their \a notify function pointer, passing on the given \a data.
2334*84e872a0SLloyd Pique  * Removing or adding a listener from within wl_priv_signal_emit()
2335*84e872a0SLloyd Pique  * is safe.
2336*84e872a0SLloyd Pique  */
2337*84e872a0SLloyd Pique void
wl_priv_signal_emit(struct wl_priv_signal * signal,void * data)2338*84e872a0SLloyd Pique wl_priv_signal_emit(struct wl_priv_signal *signal, void *data)
2339*84e872a0SLloyd Pique {
2340*84e872a0SLloyd Pique 	struct wl_listener *l;
2341*84e872a0SLloyd Pique 	struct wl_list *pos;
2342*84e872a0SLloyd Pique 
2343*84e872a0SLloyd Pique 	wl_list_insert_list(&signal->emit_list, &signal->listener_list);
2344*84e872a0SLloyd Pique 	wl_list_init(&signal->listener_list);
2345*84e872a0SLloyd Pique 
2346*84e872a0SLloyd Pique 	/* Take every element out of the list and put them in a temporary list.
2347*84e872a0SLloyd Pique 	 * This way, the 'it' func can remove any element it wants from the list
2348*84e872a0SLloyd Pique 	 * without troubles, because we always get the first element, not the
2349*84e872a0SLloyd Pique 	 * one after the current, which may be invalid.
2350*84e872a0SLloyd Pique 	 * wl_list_for_each_safe tries to be safe but it fails: it works fine
2351*84e872a0SLloyd Pique 	 * if the current item is removed, but not if the next one is. */
2352*84e872a0SLloyd Pique 	while (!wl_list_empty(&signal->emit_list)) {
2353*84e872a0SLloyd Pique 		pos = signal->emit_list.next;
2354*84e872a0SLloyd Pique 		l = wl_container_of(pos, l, link);
2355*84e872a0SLloyd Pique 
2356*84e872a0SLloyd Pique 		wl_list_remove(pos);
2357*84e872a0SLloyd Pique 		wl_list_insert(&signal->listener_list, pos);
2358*84e872a0SLloyd Pique 
2359*84e872a0SLloyd Pique 		l->notify(l, data);
2360*84e872a0SLloyd Pique 	}
2361*84e872a0SLloyd Pique }
2362*84e872a0SLloyd Pique 
2363*84e872a0SLloyd Pique /** Emit the signal for the last time, calling all the installed listeners
2364*84e872a0SLloyd Pique  *
2365*84e872a0SLloyd Pique  * Iterate over all the listeners added to this \a signal and call
2366*84e872a0SLloyd Pique  * their \a notify function pointer, passing on the given \a data.
2367*84e872a0SLloyd Pique  * Removing or adding a listener from within wl_priv_signal_emit()
2368*84e872a0SLloyd Pique  * is safe, as is freeing the structure containing the listener.
2369*84e872a0SLloyd Pique  *
2370*84e872a0SLloyd Pique  * A large body of external code assumes it's ok to free a destruction
2371*84e872a0SLloyd Pique  * listener without removing that listener from the list.  Mixing code
2372*84e872a0SLloyd Pique  * that acts like this and code that doesn't will result in list
2373*84e872a0SLloyd Pique  * corruption.
2374*84e872a0SLloyd Pique  *
2375*84e872a0SLloyd Pique  * We resolve this by removing each item from the list and isolating it
2376*84e872a0SLloyd Pique  * in another list.  We discard it completely after firing the notifier.
2377*84e872a0SLloyd Pique  * This should allow interoperability between code that unlinks its
2378*84e872a0SLloyd Pique  * destruction listeners and code that just frees structures they're in.
2379*84e872a0SLloyd Pique  *
2380*84e872a0SLloyd Pique  */
2381*84e872a0SLloyd Pique void
wl_priv_signal_final_emit(struct wl_priv_signal * signal,void * data)2382*84e872a0SLloyd Pique wl_priv_signal_final_emit(struct wl_priv_signal *signal, void *data)
2383*84e872a0SLloyd Pique {
2384*84e872a0SLloyd Pique 	struct wl_listener *l;
2385*84e872a0SLloyd Pique 	struct wl_list *pos;
2386*84e872a0SLloyd Pique 
2387*84e872a0SLloyd Pique 	/* During a destructor notifier isolate every list item before
2388*84e872a0SLloyd Pique 	 * notifying.  This renders harmless the long standing misuse
2389*84e872a0SLloyd Pique 	 * of freeing listeners without removing them, but allows
2390*84e872a0SLloyd Pique 	 * callers that do choose to remove them to interoperate with
2391*84e872a0SLloyd Pique 	 * ones that don't. */
2392*84e872a0SLloyd Pique 	while (!wl_list_empty(&signal->listener_list)) {
2393*84e872a0SLloyd Pique 		pos = signal->listener_list.next;
2394*84e872a0SLloyd Pique 		l = wl_container_of(pos, l, link);
2395*84e872a0SLloyd Pique 
2396*84e872a0SLloyd Pique 		wl_list_remove(pos);
2397*84e872a0SLloyd Pique 		wl_list_init(pos);
2398*84e872a0SLloyd Pique 
2399*84e872a0SLloyd Pique 		l->notify(l, data);
2400*84e872a0SLloyd Pique 	}
2401*84e872a0SLloyd Pique }
2402*84e872a0SLloyd Pique 
2403*84e872a0SLloyd Pique /** \endcond INTERNAL */
2404*84e872a0SLloyd Pique 
2405*84e872a0SLloyd Pique /** \cond */ /* Deprecated functions below. */
2406*84e872a0SLloyd Pique 
2407*84e872a0SLloyd Pique uint32_t
2408*84e872a0SLloyd Pique wl_client_add_resource(struct wl_client *client,
2409*84e872a0SLloyd Pique 		       struct wl_resource *resource) WL_DEPRECATED;
2410*84e872a0SLloyd Pique 
2411*84e872a0SLloyd Pique WL_EXPORT uint32_t
wl_client_add_resource(struct wl_client * client,struct wl_resource * resource)2412*84e872a0SLloyd Pique wl_client_add_resource(struct wl_client *client,
2413*84e872a0SLloyd Pique 		       struct wl_resource *resource)
2414*84e872a0SLloyd Pique {
2415*84e872a0SLloyd Pique 	if (resource->object.id == 0) {
2416*84e872a0SLloyd Pique 		resource->object.id =
2417*84e872a0SLloyd Pique 			wl_map_insert_new(&client->objects,
2418*84e872a0SLloyd Pique 					  WL_MAP_ENTRY_LEGACY, resource);
2419*84e872a0SLloyd Pique 		if (resource->object.id == 0)
2420*84e872a0SLloyd Pique 			return 0;
2421*84e872a0SLloyd Pique 	} else if (wl_map_insert_at(&client->objects, WL_MAP_ENTRY_LEGACY,
2422*84e872a0SLloyd Pique 				  resource->object.id, resource) < 0) {
2423*84e872a0SLloyd Pique 		if (errno == EINVAL) {
2424*84e872a0SLloyd Pique 			wl_resource_post_error(client->display_resource,
2425*84e872a0SLloyd Pique 					       WL_DISPLAY_ERROR_INVALID_OBJECT,
2426*84e872a0SLloyd Pique 					       "invalid new id %d",
2427*84e872a0SLloyd Pique 					       resource->object.id);
2428*84e872a0SLloyd Pique 		}
2429*84e872a0SLloyd Pique 		return 0;
2430*84e872a0SLloyd Pique 	}
2431*84e872a0SLloyd Pique 
2432*84e872a0SLloyd Pique 	resource->client = client;
2433*84e872a0SLloyd Pique 	wl_signal_init(&resource->deprecated_destroy_signal);
2434*84e872a0SLloyd Pique 
2435*84e872a0SLloyd Pique 	return resource->object.id;
2436*84e872a0SLloyd Pique }
2437*84e872a0SLloyd Pique 
2438*84e872a0SLloyd Pique struct wl_resource *
2439*84e872a0SLloyd Pique wl_client_add_object(struct wl_client *client,
2440*84e872a0SLloyd Pique 		     const struct wl_interface *interface,
2441*84e872a0SLloyd Pique 		     const void *implementation,
2442*84e872a0SLloyd Pique 		     uint32_t id, void *data) WL_DEPRECATED;
2443*84e872a0SLloyd Pique 
2444*84e872a0SLloyd Pique 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)2445*84e872a0SLloyd Pique wl_client_add_object(struct wl_client *client,
2446*84e872a0SLloyd Pique 		     const struct wl_interface *interface,
2447*84e872a0SLloyd Pique 		     const void *implementation, uint32_t id, void *data)
2448*84e872a0SLloyd Pique {
2449*84e872a0SLloyd Pique 	struct wl_resource *resource;
2450*84e872a0SLloyd Pique 
2451*84e872a0SLloyd Pique 	resource = wl_resource_create(client, interface, -1, id);
2452*84e872a0SLloyd Pique 	if (resource == NULL)
2453*84e872a0SLloyd Pique 		wl_client_post_no_memory(client);
2454*84e872a0SLloyd Pique 	else
2455*84e872a0SLloyd Pique 		wl_resource_set_implementation(resource,
2456*84e872a0SLloyd Pique 					       implementation, data, NULL);
2457*84e872a0SLloyd Pique 
2458*84e872a0SLloyd Pique 	return resource;
2459*84e872a0SLloyd Pique }
2460*84e872a0SLloyd Pique 
2461*84e872a0SLloyd Pique struct wl_resource *
2462*84e872a0SLloyd Pique wl_client_new_object(struct wl_client *client,
2463*84e872a0SLloyd Pique 		     const struct wl_interface *interface,
2464*84e872a0SLloyd Pique 		     const void *implementation, void *data) WL_DEPRECATED;
2465*84e872a0SLloyd Pique 
2466*84e872a0SLloyd Pique WL_EXPORT struct wl_resource *
wl_client_new_object(struct wl_client * client,const struct wl_interface * interface,const void * implementation,void * data)2467*84e872a0SLloyd Pique wl_client_new_object(struct wl_client *client,
2468*84e872a0SLloyd Pique 		     const struct wl_interface *interface,
2469*84e872a0SLloyd Pique 		     const void *implementation, void *data)
2470*84e872a0SLloyd Pique {
2471*84e872a0SLloyd Pique 	struct wl_resource *resource;
2472*84e872a0SLloyd Pique 
2473*84e872a0SLloyd Pique 	resource = wl_resource_create(client, interface, -1, 0);
2474*84e872a0SLloyd Pique 	if (resource == NULL)
2475*84e872a0SLloyd Pique 		wl_client_post_no_memory(client);
2476*84e872a0SLloyd Pique 	else
2477*84e872a0SLloyd Pique 		wl_resource_set_implementation(resource,
2478*84e872a0SLloyd Pique 					       implementation, data, NULL);
2479*84e872a0SLloyd Pique 
2480*84e872a0SLloyd Pique 	return resource;
2481*84e872a0SLloyd Pique }
2482*84e872a0SLloyd Pique 
2483*84e872a0SLloyd Pique struct wl_global *
2484*84e872a0SLloyd Pique wl_display_add_global(struct wl_display *display,
2485*84e872a0SLloyd Pique 		      const struct wl_interface *interface,
2486*84e872a0SLloyd Pique 		      void *data, wl_global_bind_func_t bind) WL_DEPRECATED;
2487*84e872a0SLloyd Pique 
2488*84e872a0SLloyd Pique 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)2489*84e872a0SLloyd Pique wl_display_add_global(struct wl_display *display,
2490*84e872a0SLloyd Pique 		      const struct wl_interface *interface,
2491*84e872a0SLloyd Pique 		      void *data, wl_global_bind_func_t bind)
2492*84e872a0SLloyd Pique {
2493*84e872a0SLloyd Pique 	return wl_global_create(display, interface, interface->version, data, bind);
2494*84e872a0SLloyd Pique }
2495*84e872a0SLloyd Pique 
2496*84e872a0SLloyd Pique void
2497*84e872a0SLloyd Pique wl_display_remove_global(struct wl_display *display,
2498*84e872a0SLloyd Pique 			 struct wl_global *global) WL_DEPRECATED;
2499*84e872a0SLloyd Pique 
2500*84e872a0SLloyd Pique WL_EXPORT void
wl_display_remove_global(struct wl_display * display,struct wl_global * global)2501*84e872a0SLloyd Pique wl_display_remove_global(struct wl_display *display, struct wl_global *global)
2502*84e872a0SLloyd Pique {
2503*84e872a0SLloyd Pique 	wl_global_destroy(global);
2504*84e872a0SLloyd Pique }
2505*84e872a0SLloyd Pique 
2506*84e872a0SLloyd Pique /** \endcond */
2507*84e872a0SLloyd Pique 
2508*84e872a0SLloyd Pique /* Functions at the end of this file are deprecated.  Instead of adding new
2509*84e872a0SLloyd Pique  * code here, add it before the comment above that states:
2510*84e872a0SLloyd Pique  * Deprecated functions below.
2511*84e872a0SLloyd Pique  */
2512