1 /*
2 * Copyright © 2008 Kristian Høgsberg
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26 #define _GNU_SOURCE
27
28 #include <stdlib.h>
29 #include <stdint.h>
30 #include <stddef.h>
31 #include <stdio.h>
32 #include <stdarg.h>
33 #include <stdbool.h>
34 #include <errno.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <sys/socket.h>
38 #include <sys/un.h>
39 #include <dlfcn.h>
40 #include <assert.h>
41 #include <sys/time.h>
42 #include <fcntl.h>
43 #include <sys/file.h>
44 #include <sys/stat.h>
45
46 #include "wayland-util.h"
47 #include "wayland-private.h"
48 #include "wayland-server.h"
49 #include "wayland-os.h"
50
51 /* This is the size of the char array in struct sock_addr_un.
52 * No Wayland socket can be created with a path longer than this,
53 * including the null terminator.
54 */
55 #ifndef UNIX_PATH_MAX
56 #define UNIX_PATH_MAX 108
57 #endif
58
59 #define LOCK_SUFFIX ".lock"
60 #define LOCK_SUFFIXLEN 5
61
62 struct wl_socket {
63 int fd;
64 int fd_lock;
65 struct sockaddr_un addr;
66 char lock_addr[UNIX_PATH_MAX + LOCK_SUFFIXLEN];
67 struct wl_list link;
68 struct wl_event_source *source;
69 char *display_name;
70 };
71
72 struct wl_client {
73 struct wl_connection *connection;
74 struct wl_event_source *source;
75 struct wl_display *display;
76 struct wl_resource *display_resource;
77 uint32_t id_count;
78 uint32_t mask;
79 struct wl_list link;
80 struct wl_map objects;
81 struct wl_signal destroy_signal;
82 struct ucred ucred;
83 int error;
84 struct wl_signal resource_created_signal;
85 };
86
87 struct wl_display {
88 struct wl_event_loop *loop;
89 int run;
90
91 uint32_t id;
92 uint32_t serial;
93
94 struct wl_list registry_resource_list;
95 struct wl_list global_list;
96 struct wl_list socket_list;
97 struct wl_list client_list;
98 struct wl_list protocol_loggers;
99
100 struct wl_signal destroy_signal;
101 struct wl_signal create_client_signal;
102
103 struct wl_array additional_shm_formats;
104 };
105
106 struct wl_global {
107 struct wl_display *display;
108 const struct wl_interface *interface;
109 uint32_t name;
110 uint32_t version;
111 void *data;
112 wl_global_bind_func_t bind;
113 struct wl_list link;
114 };
115
116 struct wl_resource {
117 struct wl_object object;
118 wl_resource_destroy_func_t destroy;
119 struct wl_list link;
120 struct wl_signal destroy_signal;
121 struct wl_client *client;
122 void *data;
123 int version;
124 wl_dispatcher_func_t dispatcher;
125 };
126
127 struct wl_protocol_logger {
128 struct wl_list link;
129 wl_protocol_logger_func_t func;
130 void *user_data;
131 };
132
133 static int debug_server = 0;
134
135 static void
log_closure(struct wl_resource * resource,struct wl_closure * closure,int send)136 log_closure(struct wl_resource *resource,
137 struct wl_closure *closure, int send)
138 {
139 struct wl_object *object = &resource->object;
140 struct wl_display *display = resource->client->display;
141 struct wl_protocol_logger *protocol_logger;
142 struct wl_protocol_logger_message message;
143
144 if (debug_server)
145 wl_closure_print(closure, object, send);
146
147 if (!wl_list_empty(&display->protocol_loggers)) {
148 message.resource = resource;
149 message.message_opcode = closure->opcode;
150 message.message = closure->message;
151 message.arguments_count = closure->count;
152 message.arguments = closure->args;
153 wl_list_for_each(protocol_logger,
154 &display->protocol_loggers, link) {
155 protocol_logger->func(protocol_logger->user_data,
156 send ? WL_PROTOCOL_LOGGER_EVENT :
157 WL_PROTOCOL_LOGGER_REQUEST,
158 &message);
159 }
160 }
161 }
162
163 WL_EXPORT void
wl_resource_post_event_array(struct wl_resource * resource,uint32_t opcode,union wl_argument * args)164 wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode,
165 union wl_argument *args)
166 {
167 struct wl_closure *closure;
168 struct wl_object *object = &resource->object;
169
170 closure = wl_closure_marshal(object, opcode, args,
171 &object->interface->events[opcode]);
172
173 if (closure == NULL) {
174 resource->client->error = 1;
175 return;
176 }
177
178 if (wl_closure_send(closure, resource->client->connection))
179 resource->client->error = 1;
180
181 log_closure(resource, closure, true);
182
183 wl_closure_destroy(closure);
184 }
185
186 WL_EXPORT void
wl_resource_post_event(struct wl_resource * resource,uint32_t opcode,...)187 wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...)
188 {
189 union wl_argument args[WL_CLOSURE_MAX_ARGS];
190 struct wl_object *object = &resource->object;
191 va_list ap;
192
193 va_start(ap, opcode);
194 wl_argument_from_va_list(object->interface->events[opcode].signature,
195 args, WL_CLOSURE_MAX_ARGS, ap);
196 va_end(ap);
197
198 wl_resource_post_event_array(resource, opcode, args);
199 }
200
201
202 WL_EXPORT void
wl_resource_queue_event_array(struct wl_resource * resource,uint32_t opcode,union wl_argument * args)203 wl_resource_queue_event_array(struct wl_resource *resource, uint32_t opcode,
204 union wl_argument *args)
205 {
206 struct wl_closure *closure;
207 struct wl_object *object = &resource->object;
208
209 closure = wl_closure_marshal(object, opcode, args,
210 &object->interface->events[opcode]);
211
212 if (closure == NULL) {
213 resource->client->error = 1;
214 return;
215 }
216
217 if (wl_closure_queue(closure, resource->client->connection))
218 resource->client->error = 1;
219
220 log_closure(resource, closure, true);
221
222 wl_closure_destroy(closure);
223 }
224
225 WL_EXPORT void
wl_resource_queue_event(struct wl_resource * resource,uint32_t opcode,...)226 wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
227 {
228 union wl_argument args[WL_CLOSURE_MAX_ARGS];
229 struct wl_object *object = &resource->object;
230 va_list ap;
231
232 va_start(ap, opcode);
233 wl_argument_from_va_list(object->interface->events[opcode].signature,
234 args, WL_CLOSURE_MAX_ARGS, ap);
235 va_end(ap);
236
237 wl_resource_queue_event_array(resource, opcode, args);
238 }
239
240 WL_EXPORT void
wl_resource_post_error(struct wl_resource * resource,uint32_t code,const char * msg,...)241 wl_resource_post_error(struct wl_resource *resource,
242 uint32_t code, const char *msg, ...)
243 {
244 struct wl_client *client = resource->client;
245 char buffer[128];
246 va_list ap;
247
248 va_start(ap, msg);
249 vsnprintf(buffer, sizeof buffer, msg, ap);
250 va_end(ap);
251
252 client->error = 1;
253
254 /*
255 * When a client aborts, its resources are destroyed in id order,
256 * which means the display resource is destroyed first. If destruction
257 * of any later resources results in a protocol error, we end up here
258 * with a NULL display_resource. Do not try to send errors to an
259 * already dead client.
260 */
261 if (!client->display_resource)
262 return;
263
264 wl_resource_post_event(client->display_resource,
265 WL_DISPLAY_ERROR, resource, code, buffer);
266 }
267
268 static int
wl_client_connection_data(int fd,uint32_t mask,void * data)269 wl_client_connection_data(int fd, uint32_t mask, void *data)
270 {
271 struct wl_client *client = data;
272 struct wl_connection *connection = client->connection;
273 struct wl_resource *resource;
274 struct wl_object *object;
275 struct wl_closure *closure;
276 const struct wl_message *message;
277 uint32_t p[2];
278 uint32_t resource_flags;
279 int opcode, size, since;
280 int len;
281
282 if (mask & (WL_EVENT_ERROR | WL_EVENT_HANGUP)) {
283 wl_client_destroy(client);
284 return 1;
285 }
286
287 if (mask & WL_EVENT_WRITABLE) {
288 len = wl_connection_flush(connection);
289 if (len < 0 && errno != EAGAIN) {
290 wl_client_destroy(client);
291 return 1;
292 } else if (len >= 0) {
293 wl_event_source_fd_update(client->source,
294 WL_EVENT_READABLE);
295 }
296 }
297
298 len = 0;
299 if (mask & WL_EVENT_READABLE) {
300 len = wl_connection_read(connection);
301 if (len == 0 || (len < 0 && errno != EAGAIN)) {
302 wl_client_destroy(client);
303 return 1;
304 }
305 }
306
307 while ((size_t) len >= sizeof p) {
308 wl_connection_copy(connection, p, sizeof p);
309 opcode = p[1] & 0xffff;
310 size = p[1] >> 16;
311 if (len < size)
312 break;
313
314 resource = wl_map_lookup(&client->objects, p[0]);
315 resource_flags = wl_map_lookup_flags(&client->objects, p[0]);
316 if (resource == NULL) {
317 wl_resource_post_error(client->display_resource,
318 WL_DISPLAY_ERROR_INVALID_OBJECT,
319 "invalid object %u", p[0]);
320 break;
321 }
322
323 object = &resource->object;
324 if (opcode >= object->interface->method_count) {
325 wl_resource_post_error(client->display_resource,
326 WL_DISPLAY_ERROR_INVALID_METHOD,
327 "invalid method %d, object %s@%u",
328 opcode,
329 object->interface->name,
330 object->id);
331 break;
332 }
333
334 message = &object->interface->methods[opcode];
335 since = wl_message_get_since(message);
336 if (!(resource_flags & WL_MAP_ENTRY_LEGACY) &&
337 resource->version > 0 && resource->version < since) {
338 wl_resource_post_error(client->display_resource,
339 WL_DISPLAY_ERROR_INVALID_METHOD,
340 "invalid method %d (since %d < %d)"
341 ", object %s@%u",
342 opcode, resource->version, since,
343 object->interface->name,
344 object->id);
345 break;
346 }
347
348
349 closure = wl_connection_demarshal(client->connection, size,
350 &client->objects, message);
351
352 if (closure == NULL && errno == ENOMEM) {
353 wl_resource_post_no_memory(resource);
354 break;
355 } else if (closure == NULL ||
356 wl_closure_lookup_objects(closure, &client->objects) < 0) {
357 wl_resource_post_error(client->display_resource,
358 WL_DISPLAY_ERROR_INVALID_METHOD,
359 "invalid arguments for %s@%u.%s",
360 object->interface->name,
361 object->id,
362 message->name);
363 wl_closure_destroy(closure);
364 break;
365 }
366
367 log_closure(resource, closure, false);
368
369 if ((resource_flags & WL_MAP_ENTRY_LEGACY) ||
370 resource->dispatcher == NULL) {
371 wl_closure_invoke(closure, WL_CLOSURE_INVOKE_SERVER,
372 object, opcode, client);
373 } else {
374 wl_closure_dispatch(closure, resource->dispatcher,
375 object, opcode);
376 }
377
378 wl_closure_destroy(closure);
379
380 if (client->error)
381 break;
382
383 len = wl_connection_pending_input(connection);
384 }
385
386 if (client->error)
387 wl_client_destroy(client);
388
389 return 1;
390 }
391
392 /** Flush pending events to the client
393 *
394 * \param client The client object
395 *
396 * Events sent to clients are queued in a buffer and written to the
397 * socket later - typically when the compositor has handled all
398 * requests and goes back to block in the event loop. This function
399 * flushes all queued up events for a client immediately.
400 *
401 * \memberof wl_client
402 */
403 WL_EXPORT void
wl_client_flush(struct wl_client * client)404 wl_client_flush(struct wl_client *client)
405 {
406 wl_connection_flush(client->connection);
407 }
408
409 /** Get the display object for the given client
410 *
411 * \param client The client object
412 * \return The display object the client is associated with.
413 *
414 * \memberof wl_client
415 */
416 WL_EXPORT struct wl_display *
wl_client_get_display(struct wl_client * client)417 wl_client_get_display(struct wl_client *client)
418 {
419 return client->display;
420 }
421
422 static int
423 bind_display(struct wl_client *client, struct wl_display *display);
424
425 /** Create a client for the given file descriptor
426 *
427 * \param display The display object
428 * \param fd The file descriptor for the socket to the client
429 * \return The new client object or NULL on failure.
430 *
431 * Given a file descriptor corresponding to one end of a socket, this
432 * function will create a wl_client struct and add the new client to
433 * the compositors client list. At that point, the client is
434 * initialized and ready to run, as if the client had connected to the
435 * servers listening socket. When the client eventually sends
436 * requests to the compositor, the wl_client argument to the request
437 * handler will be the wl_client returned from this function.
438 *
439 * The other end of the socket can be passed to
440 * wl_display_connect_to_fd() on the client side or used with the
441 * WAYLAND_SOCKET environment variable on the client side.
442 *
443 * Listeners added with wl_display_add_client_created_listener() will
444 * be notified by this function after the client is fully constructed.
445 *
446 * On failure this function sets errno accordingly and returns NULL.
447 *
448 * \memberof wl_display
449 */
450 WL_EXPORT struct wl_client *
wl_client_create(struct wl_display * display,int fd)451 wl_client_create(struct wl_display *display, int fd)
452 {
453 struct wl_client *client;
454 socklen_t len;
455
456 client = zalloc(sizeof *client);
457 if (client == NULL)
458 return NULL;
459
460 wl_signal_init(&client->resource_created_signal);
461 client->display = display;
462 client->source = wl_event_loop_add_fd(display->loop, fd,
463 WL_EVENT_READABLE,
464 wl_client_connection_data, client);
465
466 if (!client->source)
467 goto err_client;
468
469 len = sizeof client->ucred;
470 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED,
471 &client->ucred, &len) < 0)
472 goto err_source;
473
474 client->connection = wl_connection_create(fd);
475 if (client->connection == NULL)
476 goto err_source;
477
478 wl_map_init(&client->objects, WL_MAP_SERVER_SIDE);
479
480 if (wl_map_insert_at(&client->objects, 0, 0, NULL) < 0)
481 goto err_map;
482
483 wl_signal_init(&client->destroy_signal);
484 if (bind_display(client, display) < 0)
485 goto err_map;
486
487 wl_list_insert(display->client_list.prev, &client->link);
488
489 wl_signal_emit(&display->create_client_signal, client);
490
491 return client;
492
493 err_map:
494 wl_map_release(&client->objects);
495 wl_connection_destroy(client->connection);
496 err_source:
497 wl_event_source_remove(client->source);
498 err_client:
499 free(client);
500 return NULL;
501 }
502
503 /** Return Unix credentials for the client
504 *
505 * \param client The display object
506 * \param pid Returns the process ID
507 * \param uid Returns the user ID
508 * \param gid Returns the group ID
509 *
510 * This function returns the process ID, the user ID and the group ID
511 * for the given client. The credentials come from getsockopt() with
512 * SO_PEERCRED, on the client socket fd. All the pointers can be
513 * NULL, if the caller is not interested in a particular ID.
514 *
515 * Be aware that for clients that a compositor forks and execs and
516 * then connects using socketpair(), this function will return the
517 * credentials for the compositor. The credentials for the socketpair
518 * are set at creation time in the compositor.
519 *
520 * \memberof wl_client
521 */
522 WL_EXPORT void
wl_client_get_credentials(struct wl_client * client,pid_t * pid,uid_t * uid,gid_t * gid)523 wl_client_get_credentials(struct wl_client *client,
524 pid_t *pid, uid_t *uid, gid_t *gid)
525 {
526 if (pid)
527 *pid = client->ucred.pid;
528 if (uid)
529 *uid = client->ucred.uid;
530 if (gid)
531 *gid = client->ucred.gid;
532 }
533
534 /** Get the file descriptor for the client
535 *
536 * \param client The display object
537 * \return The file descriptor to use for the connection
538 *
539 * This function returns the file descriptor for the given client.
540 *
541 * Be sure to use the file descriptor from the client for inspection only.
542 * If the caller does anything to the file descriptor that changes its state,
543 * it will likely cause problems.
544 *
545 * See also wl_client_get_credentials().
546 * It is recommended that you evaluate whether wl_client_get_credentials()
547 * can be applied to your use case instead of this function.
548 *
549 * If you would like to distinguish just between the client and the compositor
550 * itself from the client's request, it can be done by getting the client
551 * credentials and by checking the PID of the client and the compositor's PID.
552 * Regarding the case in which the socketpair() is being used, you need to be
553 * careful. Please note the documentation for wl_client_get_credentials().
554 *
555 * This function can be used for a compositor to validate a request from
556 * a client if there are additional information provided from the client's
557 * file descriptor. For instance, suppose you can get the security contexts
558 * from the client's file descriptor. The compositor can validate the client's
559 * request with the contexts and make a decision whether it permits or deny it.
560 *
561 * \memberof wl_client
562 */
563 WL_EXPORT int
wl_client_get_fd(struct wl_client * client)564 wl_client_get_fd(struct wl_client *client)
565 {
566 return wl_connection_get_fd(client->connection);
567 }
568
569 /** Look up an object in the client name space
570 *
571 * \param client The client object
572 * \param id The object id
573 * \return The object or NULL if there is not object for the given ID
574 *
575 * This looks up an object in the client object name space by its
576 * object ID.
577 *
578 * \memberof wl_client
579 */
580 WL_EXPORT struct wl_resource *
wl_client_get_object(struct wl_client * client,uint32_t id)581 wl_client_get_object(struct wl_client *client, uint32_t id)
582 {
583 return wl_map_lookup(&client->objects, id);
584 }
585
586 WL_EXPORT void
wl_client_post_no_memory(struct wl_client * client)587 wl_client_post_no_memory(struct wl_client *client)
588 {
589 wl_resource_post_error(client->display_resource,
590 WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
591 }
592
593 WL_EXPORT void
wl_resource_post_no_memory(struct wl_resource * resource)594 wl_resource_post_no_memory(struct wl_resource *resource)
595 {
596 wl_resource_post_error(resource->client->display_resource,
597 WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
598 }
599
600 static enum wl_iterator_result
destroy_resource(void * element,void * data)601 destroy_resource(void *element, void *data)
602 {
603 struct wl_resource *resource = element;
604 struct wl_client *client = resource->client;
605 uint32_t flags;
606
607 wl_signal_emit(&resource->destroy_signal, resource);
608
609 flags = wl_map_lookup_flags(&client->objects, resource->object.id);
610 if (resource->destroy)
611 resource->destroy(resource);
612
613 if (!(flags & WL_MAP_ENTRY_LEGACY))
614 free(resource);
615
616 return WL_ITERATOR_CONTINUE;
617 }
618
619 WL_EXPORT void
wl_resource_destroy(struct wl_resource * resource)620 wl_resource_destroy(struct wl_resource *resource)
621 {
622 struct wl_client *client = resource->client;
623 uint32_t id;
624
625 id = resource->object.id;
626 destroy_resource(resource, NULL);
627
628 if (id < WL_SERVER_ID_START) {
629 if (client->display_resource) {
630 wl_resource_queue_event(client->display_resource,
631 WL_DISPLAY_DELETE_ID, id);
632 }
633 wl_map_insert_at(&client->objects, 0, id, NULL);
634 } else {
635 wl_map_remove(&client->objects, id);
636 }
637 }
638
639 WL_EXPORT uint32_t
wl_resource_get_id(struct wl_resource * resource)640 wl_resource_get_id(struct wl_resource *resource)
641 {
642 return resource->object.id;
643 }
644
645 WL_EXPORT struct wl_list *
wl_resource_get_link(struct wl_resource * resource)646 wl_resource_get_link(struct wl_resource *resource)
647 {
648 return &resource->link;
649 }
650
651 WL_EXPORT struct wl_resource *
wl_resource_from_link(struct wl_list * link)652 wl_resource_from_link(struct wl_list *link)
653 {
654 struct wl_resource *resource;
655
656 return wl_container_of(link, resource, link);
657 }
658
659 WL_EXPORT struct wl_resource *
wl_resource_find_for_client(struct wl_list * list,struct wl_client * client)660 wl_resource_find_for_client(struct wl_list *list, struct wl_client *client)
661 {
662 struct wl_resource *resource;
663
664 if (client == NULL)
665 return NULL;
666
667 wl_list_for_each(resource, list, link) {
668 if (resource->client == client)
669 return resource;
670 }
671
672 return NULL;
673 }
674
675 WL_EXPORT struct wl_client *
wl_resource_get_client(struct wl_resource * resource)676 wl_resource_get_client(struct wl_resource *resource)
677 {
678 return resource->client;
679 }
680
681 WL_EXPORT void
wl_resource_set_user_data(struct wl_resource * resource,void * data)682 wl_resource_set_user_data(struct wl_resource *resource, void *data)
683 {
684 resource->data = data;
685 }
686
687 WL_EXPORT void *
wl_resource_get_user_data(struct wl_resource * resource)688 wl_resource_get_user_data(struct wl_resource *resource)
689 {
690 return resource->data;
691 }
692
693 WL_EXPORT int
wl_resource_get_version(struct wl_resource * resource)694 wl_resource_get_version(struct wl_resource *resource)
695 {
696 return resource->version;
697 }
698
699 WL_EXPORT void
wl_resource_set_destructor(struct wl_resource * resource,wl_resource_destroy_func_t destroy)700 wl_resource_set_destructor(struct wl_resource *resource,
701 wl_resource_destroy_func_t destroy)
702 {
703 resource->destroy = destroy;
704 }
705
706 WL_EXPORT int
wl_resource_instance_of(struct wl_resource * resource,const struct wl_interface * interface,const void * implementation)707 wl_resource_instance_of(struct wl_resource *resource,
708 const struct wl_interface *interface,
709 const void *implementation)
710 {
711 return wl_interface_equal(resource->object.interface, interface) &&
712 resource->object.implementation == implementation;
713 }
714
715 WL_EXPORT void
wl_resource_add_destroy_listener(struct wl_resource * resource,struct wl_listener * listener)716 wl_resource_add_destroy_listener(struct wl_resource *resource,
717 struct wl_listener * listener)
718 {
719 wl_signal_add(&resource->destroy_signal, listener);
720 }
721
722 WL_EXPORT struct wl_listener *
wl_resource_get_destroy_listener(struct wl_resource * resource,wl_notify_func_t notify)723 wl_resource_get_destroy_listener(struct wl_resource *resource,
724 wl_notify_func_t notify)
725 {
726 return wl_signal_get(&resource->destroy_signal, notify);
727 }
728
729 /** Retrieve the interface name (class) of a resource object.
730 *
731 * \param resource The resource object
732 *
733 * \memberof wl_resource
734 */
735 WL_EXPORT const char *
wl_resource_get_class(struct wl_resource * resource)736 wl_resource_get_class(struct wl_resource *resource)
737 {
738 return resource->object.interface->name;
739 }
740
741 WL_EXPORT void
wl_client_add_destroy_listener(struct wl_client * client,struct wl_listener * listener)742 wl_client_add_destroy_listener(struct wl_client *client,
743 struct wl_listener *listener)
744 {
745 wl_signal_add(&client->destroy_signal, listener);
746 }
747
748 WL_EXPORT struct wl_listener *
wl_client_get_destroy_listener(struct wl_client * client,wl_notify_func_t notify)749 wl_client_get_destroy_listener(struct wl_client *client,
750 wl_notify_func_t notify)
751 {
752 return wl_signal_get(&client->destroy_signal, notify);
753 }
754
755 WL_EXPORT void
wl_client_destroy(struct wl_client * client)756 wl_client_destroy(struct wl_client *client)
757 {
758 uint32_t serial = 0;
759
760 wl_signal_emit(&client->destroy_signal, client);
761
762 wl_client_flush(client);
763 wl_map_for_each(&client->objects, destroy_resource, &serial);
764 wl_map_release(&client->objects);
765 wl_event_source_remove(client->source);
766 close(wl_connection_destroy(client->connection));
767 wl_list_remove(&client->link);
768 wl_list_remove(&client->resource_created_signal.listener_list);
769 free(client);
770 }
771
772 static void
registry_bind(struct wl_client * client,struct wl_resource * resource,uint32_t name,const char * interface,uint32_t version,uint32_t id)773 registry_bind(struct wl_client *client,
774 struct wl_resource *resource, uint32_t name,
775 const char *interface, uint32_t version, uint32_t id)
776 {
777 struct wl_global *global;
778 struct wl_display *display = resource->data;
779
780 wl_list_for_each(global, &display->global_list, link)
781 if (global->name == name)
782 break;
783
784 if (&global->link == &display->global_list)
785 wl_resource_post_error(resource,
786 WL_DISPLAY_ERROR_INVALID_OBJECT,
787 "invalid global %s (%d)", interface, name);
788 else if (version == 0)
789 wl_resource_post_error(resource,
790 WL_DISPLAY_ERROR_INVALID_OBJECT,
791 "invalid version for global %s (%d): 0 is not a valid version",
792 interface, name);
793 else if (global->version < version)
794 wl_resource_post_error(resource,
795 WL_DISPLAY_ERROR_INVALID_OBJECT,
796 "invalid version for global %s (%d): have %d, wanted %d",
797 interface, name, global->version, version);
798 else
799 global->bind(client, global->data, version, id);
800 }
801
802 static const struct wl_registry_interface registry_interface = {
803 registry_bind
804 };
805
806 static void
display_sync(struct wl_client * client,struct wl_resource * resource,uint32_t id)807 display_sync(struct wl_client *client,
808 struct wl_resource *resource, uint32_t id)
809 {
810 struct wl_resource *callback;
811 uint32_t serial;
812
813 callback = wl_resource_create(client, &wl_callback_interface, 1, id);
814 if (callback == NULL) {
815 wl_client_post_no_memory(client);
816 return;
817 }
818
819 serial = wl_display_get_serial(client->display);
820 wl_callback_send_done(callback, serial);
821 wl_resource_destroy(callback);
822 }
823
824 static void
unbind_resource(struct wl_resource * resource)825 unbind_resource(struct wl_resource *resource)
826 {
827 wl_list_remove(&resource->link);
828 }
829
830 static void
display_get_registry(struct wl_client * client,struct wl_resource * resource,uint32_t id)831 display_get_registry(struct wl_client *client,
832 struct wl_resource *resource, uint32_t id)
833 {
834 struct wl_display *display = resource->data;
835 struct wl_resource *registry_resource;
836 struct wl_global *global;
837
838 registry_resource =
839 wl_resource_create(client, &wl_registry_interface, 1, id);
840 if (registry_resource == NULL) {
841 wl_client_post_no_memory(client);
842 return;
843 }
844
845 wl_resource_set_implementation(registry_resource,
846 ®istry_interface,
847 display, unbind_resource);
848
849 wl_list_insert(&display->registry_resource_list,
850 ®istry_resource->link);
851
852 wl_list_for_each(global, &display->global_list, link)
853 wl_resource_post_event(registry_resource,
854 WL_REGISTRY_GLOBAL,
855 global->name,
856 global->interface->name,
857 global->version);
858 }
859
860 static const struct wl_display_interface display_interface = {
861 display_sync,
862 display_get_registry
863 };
864
865 static void
destroy_client_display_resource(struct wl_resource * resource)866 destroy_client_display_resource(struct wl_resource *resource)
867 {
868 resource->client->display_resource = NULL;
869 }
870
871 static int
bind_display(struct wl_client * client,struct wl_display * display)872 bind_display(struct wl_client *client, struct wl_display *display)
873 {
874 client->display_resource =
875 wl_resource_create(client, &wl_display_interface, 1, 1);
876 if (client->display_resource == NULL) {
877 /* DON'T send no-memory error to client - it has no
878 * resource to which it could post the event */
879 return -1;
880 }
881
882 wl_resource_set_implementation(client->display_resource,
883 &display_interface, display,
884 destroy_client_display_resource);
885 return 0;
886 }
887
888 /** Create Wayland display object.
889 *
890 * \return The Wayland display object. Null if failed to create
891 *
892 * This creates the wl_display object.
893 *
894 * \memberof wl_display
895 */
896 WL_EXPORT struct wl_display *
wl_display_create(void)897 wl_display_create(void)
898 {
899 struct wl_display *display;
900 const char *debug;
901
902 debug = getenv("WAYLAND_DEBUG");
903 if (debug && (strstr(debug, "server") || strstr(debug, "1")))
904 debug_server = 1;
905
906 display = malloc(sizeof *display);
907 if (display == NULL)
908 return NULL;
909
910 display->loop = wl_event_loop_create();
911 if (display->loop == NULL) {
912 free(display);
913 return NULL;
914 }
915
916 wl_list_init(&display->global_list);
917 wl_list_init(&display->socket_list);
918 wl_list_init(&display->client_list);
919 wl_list_init(&display->registry_resource_list);
920 wl_list_init(&display->protocol_loggers);
921
922 wl_signal_init(&display->destroy_signal);
923 wl_signal_init(&display->create_client_signal);
924
925 display->id = 1;
926 display->serial = 0;
927
928 wl_array_init(&display->additional_shm_formats);
929
930 return display;
931 }
932
933 static void
wl_socket_destroy(struct wl_socket * s)934 wl_socket_destroy(struct wl_socket *s)
935 {
936 if (s->source)
937 wl_event_source_remove(s->source);
938 if (s->addr.sun_path[0])
939 unlink(s->addr.sun_path);
940 if (s->fd >= 0)
941 close(s->fd);
942 if (s->lock_addr[0])
943 unlink(s->lock_addr);
944 if (s->fd_lock >= 0)
945 close(s->fd_lock);
946
947 free(s);
948 }
949
950 static struct wl_socket *
wl_socket_alloc(void)951 wl_socket_alloc(void)
952 {
953 struct wl_socket *s;
954
955 s = zalloc(sizeof *s);
956 if (!s)
957 return NULL;
958
959 s->fd = -1;
960 s->fd_lock = -1;
961
962 return s;
963 }
964
965 /** Destroy Wayland display object.
966 *
967 * \param display The Wayland display object which should be destroyed.
968 * \return None.
969 *
970 * This function emits the wl_display destroy signal, releases
971 * all the sockets added to this display, free's all the globals associated
972 * with this display, free's memory of additional shared memory formats and
973 * destroy the display object.
974 *
975 * \sa wl_display_add_destroy_listener
976 *
977 * \memberof wl_display
978 */
979 WL_EXPORT void
wl_display_destroy(struct wl_display * display)980 wl_display_destroy(struct wl_display *display)
981 {
982 struct wl_socket *s, *next;
983 struct wl_global *global, *gnext;
984
985 wl_signal_emit(&display->destroy_signal, display);
986
987 wl_list_for_each_safe(s, next, &display->socket_list, link) {
988 wl_socket_destroy(s);
989 }
990 wl_event_loop_destroy(display->loop);
991
992 wl_list_for_each_safe(global, gnext, &display->global_list, link)
993 free(global);
994
995 wl_array_release(&display->additional_shm_formats);
996
997 wl_list_remove(&display->protocol_loggers);
998
999 free(display);
1000 }
1001
1002 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)1003 wl_global_create(struct wl_display *display,
1004 const struct wl_interface *interface, int version,
1005 void *data, wl_global_bind_func_t bind)
1006 {
1007 struct wl_global *global;
1008 struct wl_resource *resource;
1009
1010 if (version < 1) {
1011 wl_log("wl_global_create: failing to create interface "
1012 "'%s' with version %d because it is less than 1\n",
1013 interface->name, version);
1014 return NULL;
1015 }
1016
1017 if (version > interface->version) {
1018 wl_log("wl_global_create: implemented version for '%s' "
1019 "higher than interface version (%d > %d)\n",
1020 interface->name, version, interface->version);
1021 return NULL;
1022 }
1023
1024 global = malloc(sizeof *global);
1025 if (global == NULL)
1026 return NULL;
1027
1028 global->display = display;
1029 global->name = display->id++;
1030 global->interface = interface;
1031 global->version = version;
1032 global->data = data;
1033 global->bind = bind;
1034 wl_list_insert(display->global_list.prev, &global->link);
1035
1036 wl_list_for_each(resource, &display->registry_resource_list, link)
1037 wl_resource_post_event(resource,
1038 WL_REGISTRY_GLOBAL,
1039 global->name,
1040 global->interface->name,
1041 global->version);
1042
1043 return global;
1044 }
1045
1046 WL_EXPORT void
wl_global_destroy(struct wl_global * global)1047 wl_global_destroy(struct wl_global *global)
1048 {
1049 struct wl_display *display = global->display;
1050 struct wl_resource *resource;
1051
1052 wl_list_for_each(resource, &display->registry_resource_list, link)
1053 wl_resource_post_event(resource, WL_REGISTRY_GLOBAL_REMOVE,
1054 global->name);
1055 wl_list_remove(&global->link);
1056 free(global);
1057 }
1058
1059 /** Get the current serial number
1060 *
1061 * \param display The display object
1062 *
1063 * This function returns the most recent serial number, but does not
1064 * increment it.
1065 *
1066 * \memberof wl_display
1067 */
1068 WL_EXPORT uint32_t
wl_display_get_serial(struct wl_display * display)1069 wl_display_get_serial(struct wl_display *display)
1070 {
1071 return display->serial;
1072 }
1073
1074 /** Get the next serial number
1075 *
1076 * \param display The display object
1077 *
1078 * This function increments the display serial number and returns the
1079 * new value.
1080 *
1081 * \memberof wl_display
1082 */
1083 WL_EXPORT uint32_t
wl_display_next_serial(struct wl_display * display)1084 wl_display_next_serial(struct wl_display *display)
1085 {
1086 display->serial++;
1087
1088 return display->serial;
1089 }
1090
1091 WL_EXPORT struct wl_event_loop *
wl_display_get_event_loop(struct wl_display * display)1092 wl_display_get_event_loop(struct wl_display *display)
1093 {
1094 return display->loop;
1095 }
1096
1097 WL_EXPORT void
wl_display_terminate(struct wl_display * display)1098 wl_display_terminate(struct wl_display *display)
1099 {
1100 display->run = 0;
1101 }
1102
1103 WL_EXPORT void
wl_display_run(struct wl_display * display)1104 wl_display_run(struct wl_display *display)
1105 {
1106 display->run = 1;
1107
1108 while (display->run) {
1109 wl_display_flush_clients(display);
1110 wl_event_loop_dispatch(display->loop, -1);
1111 }
1112 }
1113
1114 WL_EXPORT void
wl_display_flush_clients(struct wl_display * display)1115 wl_display_flush_clients(struct wl_display *display)
1116 {
1117 struct wl_client *client, *next;
1118 int ret;
1119
1120 wl_list_for_each_safe(client, next, &display->client_list, link) {
1121 ret = wl_connection_flush(client->connection);
1122 if (ret < 0 && errno == EAGAIN) {
1123 wl_event_source_fd_update(client->source,
1124 WL_EVENT_WRITABLE |
1125 WL_EVENT_READABLE);
1126 } else if (ret < 0) {
1127 wl_client_destroy(client);
1128 }
1129 }
1130 }
1131
1132 static int
socket_data(int fd,uint32_t mask,void * data)1133 socket_data(int fd, uint32_t mask, void *data)
1134 {
1135 struct wl_display *display = data;
1136 struct sockaddr_un name;
1137 socklen_t length;
1138 int client_fd;
1139
1140 length = sizeof name;
1141 client_fd = wl_os_accept_cloexec(fd, (struct sockaddr *) &name,
1142 &length);
1143 if (client_fd < 0)
1144 wl_log("failed to accept: %m\n");
1145 else
1146 if (!wl_client_create(display, client_fd))
1147 close(client_fd);
1148
1149 return 1;
1150 }
1151
1152 static int
wl_socket_lock(struct wl_socket * socket)1153 wl_socket_lock(struct wl_socket *socket)
1154 {
1155 struct stat socket_stat;
1156
1157 snprintf(socket->lock_addr, sizeof socket->lock_addr,
1158 "%s%s", socket->addr.sun_path, LOCK_SUFFIX);
1159
1160 socket->fd_lock = open(socket->lock_addr, O_CREAT | O_CLOEXEC,
1161 (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
1162
1163 if (socket->fd_lock < 0) {
1164 wl_log("unable to open lockfile %s check permissions\n",
1165 socket->lock_addr);
1166 goto err;
1167 }
1168
1169 if (flock(socket->fd_lock, LOCK_EX | LOCK_NB) < 0) {
1170 wl_log("unable to lock lockfile %s, maybe another compositor is running\n",
1171 socket->lock_addr);
1172 goto err_fd;
1173 }
1174
1175 if (stat(socket->addr.sun_path, &socket_stat) < 0 ) {
1176 if (errno != ENOENT) {
1177 wl_log("did not manage to stat file %s\n",
1178 socket->addr.sun_path);
1179 goto err_fd;
1180 }
1181 } else if (socket_stat.st_mode & S_IWUSR ||
1182 socket_stat.st_mode & S_IWGRP) {
1183 unlink(socket->addr.sun_path);
1184 }
1185
1186 return 0;
1187 err_fd:
1188 close(socket->fd_lock);
1189 socket->fd_lock = -1;
1190 err:
1191 *socket->lock_addr = 0;
1192 /* we did not set this value here, but without lock the
1193 * socket won't be created anyway. This prevents the
1194 * wl_socket_destroy from unlinking already existing socket
1195 * created by other compositor */
1196 *socket->addr.sun_path = 0;
1197
1198 return -1;
1199 }
1200
1201 static int
wl_socket_init_for_display_name(struct wl_socket * s,const char * name)1202 wl_socket_init_for_display_name(struct wl_socket *s, const char *name)
1203 {
1204 int name_size;
1205 const char *runtime_dir;
1206
1207 runtime_dir = getenv("XDG_RUNTIME_DIR");
1208 if (!runtime_dir) {
1209 wl_log("error: XDG_RUNTIME_DIR not set in the environment\n");
1210
1211 /* to prevent programs reporting
1212 * "failed to add socket: Success" */
1213 errno = ENOENT;
1214 return -1;
1215 }
1216
1217 s->addr.sun_family = AF_LOCAL;
1218 name_size = snprintf(s->addr.sun_path, sizeof s->addr.sun_path,
1219 "%s/%s", runtime_dir, name) + 1;
1220
1221 s->display_name = (s->addr.sun_path + name_size - 1) - strlen(name);
1222
1223 assert(name_size > 0);
1224 if (name_size > (int)sizeof s->addr.sun_path) {
1225 wl_log("error: socket path \"%s/%s\" plus null terminator"
1226 " exceeds 108 bytes\n", runtime_dir, name);
1227 *s->addr.sun_path = 0;
1228 /* to prevent programs reporting
1229 * "failed to add socket: Success" */
1230 errno = ENAMETOOLONG;
1231 return -1;
1232 }
1233
1234 return 0;
1235 }
1236
1237 static int
_wl_display_add_socket(struct wl_display * display,struct wl_socket * s)1238 _wl_display_add_socket(struct wl_display *display, struct wl_socket *s)
1239 {
1240 socklen_t size;
1241
1242 s->fd = wl_os_socket_cloexec(PF_LOCAL, SOCK_STREAM, 0);
1243 if (s->fd < 0) {
1244 return -1;
1245 }
1246
1247 size = offsetof (struct sockaddr_un, sun_path) + strlen(s->addr.sun_path);
1248 if (bind(s->fd, (struct sockaddr *) &s->addr, size) < 0) {
1249 wl_log("bind() failed with error: %m\n");
1250 return -1;
1251 }
1252
1253 if (listen(s->fd, 128) < 0) {
1254 wl_log("listen() failed with error: %m\n");
1255 return -1;
1256 }
1257
1258 s->source = wl_event_loop_add_fd(display->loop, s->fd,
1259 WL_EVENT_READABLE,
1260 socket_data, display);
1261 if (s->source == NULL) {
1262 return -1;
1263 }
1264
1265 wl_list_insert(display->socket_list.prev, &s->link);
1266 return 0;
1267 }
1268
1269 WL_EXPORT const char *
wl_display_add_socket_auto(struct wl_display * display)1270 wl_display_add_socket_auto(struct wl_display *display)
1271 {
1272 struct wl_socket *s;
1273 int displayno = 0;
1274 char display_name[16] = "";
1275
1276 /* A reasonable number of maximum default sockets. If
1277 * you need more than this, use the explicit add_socket API. */
1278 const int MAX_DISPLAYNO = 32;
1279
1280 s = wl_socket_alloc();
1281 if (s == NULL)
1282 return NULL;
1283
1284 do {
1285 snprintf(display_name, sizeof display_name, "wayland-%d", displayno);
1286 if (wl_socket_init_for_display_name(s, display_name) < 0) {
1287 wl_socket_destroy(s);
1288 return NULL;
1289 }
1290
1291 if (wl_socket_lock(s) < 0)
1292 continue;
1293
1294 if (_wl_display_add_socket(display, s) < 0) {
1295 wl_socket_destroy(s);
1296 return NULL;
1297 }
1298
1299 return s->display_name;
1300 } while (displayno++ < MAX_DISPLAYNO);
1301
1302 /* Ran out of display names. */
1303 wl_socket_destroy(s);
1304 errno = EINVAL;
1305 return NULL;
1306 }
1307
1308 /** Add a socket with an existing fd to Wayland display for the clients to connect.
1309 *
1310 * \param display Wayland display to which the socket should be added.
1311 * \param sock_fd The existing socket file descriptor to be used
1312 * \return 0 if success. -1 if failed.
1313 *
1314 * The existing socket fd must already be created, opened, and locked.
1315 * The fd must be properly set to CLOEXEC and bound to a socket file
1316 * with both bind() and listen() already called.
1317 *
1318 * \memberof wl_display
1319 */
1320 WL_EXPORT int
wl_display_add_socket_fd(struct wl_display * display,int sock_fd)1321 wl_display_add_socket_fd(struct wl_display *display, int sock_fd)
1322 {
1323 struct wl_socket *s;
1324 struct stat buf;
1325
1326 /* Require a valid fd or fail */
1327 if (sock_fd < 0 || fstat(sock_fd, &buf) < 0 || !S_ISSOCK(buf.st_mode)) {
1328 return -1;
1329 }
1330
1331 s = wl_socket_alloc();
1332 if (s == NULL)
1333 return -1;
1334
1335 s->source = wl_event_loop_add_fd(display->loop, sock_fd,
1336 WL_EVENT_READABLE,
1337 socket_data, display);
1338 if (s->source == NULL) {
1339 wl_log("failed to establish event source\n");
1340 wl_socket_destroy(s);
1341 return -1;
1342 }
1343
1344 /* Reuse the existing fd */
1345 s->fd = sock_fd;
1346
1347 wl_list_insert(display->socket_list.prev, &s->link);
1348
1349 return 0;
1350 }
1351
1352 /** Add a socket to Wayland display for the clients to connect.
1353 *
1354 * \param display Wayland display to which the socket should be added.
1355 * \param name Name of the Unix socket.
1356 * \return 0 if success. -1 if failed.
1357 *
1358 * This adds a Unix socket to Wayland display which can be used by clients to
1359 * connect to Wayland display.
1360 *
1361 * If NULL is passed as name, then it would look for WAYLAND_DISPLAY env
1362 * variable for the socket name. If WAYLAND_DISPLAY is not set, then default
1363 * wayland-0 is used.
1364 *
1365 * The Unix socket will be created in the directory pointed to by environment
1366 * variable XDG_RUNTIME_DIR. If XDG_RUNTIME_DIR is not set, then this function
1367 * fails and returns -1.
1368 *
1369 * The length of socket path, i.e., the path set in XDG_RUNTIME_DIR and the
1370 * socket name, must not exceed the maximum length of a Unix socket path.
1371 * The function also fails if the user do not have write permission in the
1372 * XDG_RUNTIME_DIR path or if the socket name is already in use.
1373 *
1374 * \memberof wl_display
1375 */
1376 WL_EXPORT int
wl_display_add_socket(struct wl_display * display,const char * name)1377 wl_display_add_socket(struct wl_display *display, const char *name)
1378 {
1379 struct wl_socket *s;
1380
1381 s = wl_socket_alloc();
1382 if (s == NULL)
1383 return -1;
1384
1385 if (name == NULL)
1386 name = getenv("WAYLAND_DISPLAY");
1387 if (name == NULL)
1388 name = "wayland-0";
1389
1390 if (wl_socket_init_for_display_name(s, name) < 0) {
1391 wl_socket_destroy(s);
1392 return -1;
1393 }
1394
1395 if (wl_socket_lock(s) < 0) {
1396 wl_socket_destroy(s);
1397 return -1;
1398 }
1399
1400 if (_wl_display_add_socket(display, s) < 0) {
1401 wl_socket_destroy(s);
1402 return -1;
1403 }
1404
1405 return 0;
1406 }
1407
1408 WL_EXPORT void
wl_display_add_destroy_listener(struct wl_display * display,struct wl_listener * listener)1409 wl_display_add_destroy_listener(struct wl_display *display,
1410 struct wl_listener *listener)
1411 {
1412 wl_signal_add(&display->destroy_signal, listener);
1413 }
1414
1415 /** Registers a listener for the client connection signal.
1416 * When a new client object is created, \a listener will be notified, carrying
1417 * a pointer to the new wl_client object.
1418 *
1419 * \ref wl_client_create
1420 * \ref wl_display
1421 * \ref wl_listener
1422 *
1423 * \param display The display object
1424 * \param listener Signal handler object
1425 */
1426 WL_EXPORT void
wl_display_add_client_created_listener(struct wl_display * display,struct wl_listener * listener)1427 wl_display_add_client_created_listener(struct wl_display *display,
1428 struct wl_listener *listener)
1429 {
1430 wl_signal_add(&display->create_client_signal, listener);
1431 }
1432
1433 WL_EXPORT struct wl_listener *
wl_display_get_destroy_listener(struct wl_display * display,wl_notify_func_t notify)1434 wl_display_get_destroy_listener(struct wl_display *display,
1435 wl_notify_func_t notify)
1436 {
1437 return wl_signal_get(&display->destroy_signal, notify);
1438 }
1439
1440 WL_EXPORT void
wl_resource_set_implementation(struct wl_resource * resource,const void * implementation,void * data,wl_resource_destroy_func_t destroy)1441 wl_resource_set_implementation(struct wl_resource *resource,
1442 const void *implementation,
1443 void *data, wl_resource_destroy_func_t destroy)
1444 {
1445 resource->object.implementation = implementation;
1446 resource->data = data;
1447 resource->destroy = destroy;
1448 resource->dispatcher = NULL;
1449 }
1450
1451 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)1452 wl_resource_set_dispatcher(struct wl_resource *resource,
1453 wl_dispatcher_func_t dispatcher,
1454 const void *implementation,
1455 void *data, wl_resource_destroy_func_t destroy)
1456 {
1457 resource->dispatcher = dispatcher;
1458 resource->object.implementation = implementation;
1459 resource->data = data;
1460 resource->destroy = destroy;
1461 }
1462
1463 /** Create a new resource object
1464 *
1465 * \param client The client owner of the new resource.
1466 * \param interface The interface of the new resource.
1467 * \param version The version of the new resource.
1468 * \param id The id of the new resource. If 0, an available id will be used.
1469 *
1470 * Listeners added with \a wl_client_add_resource_created_listener will be
1471 * notified at the end of this function.
1472 *
1473 * \memberof wl_resource
1474 */
1475 WL_EXPORT struct wl_resource *
wl_resource_create(struct wl_client * client,const struct wl_interface * interface,int version,uint32_t id)1476 wl_resource_create(struct wl_client *client,
1477 const struct wl_interface *interface,
1478 int version, uint32_t id)
1479 {
1480 struct wl_resource *resource;
1481
1482 resource = malloc(sizeof *resource);
1483 if (resource == NULL)
1484 return NULL;
1485
1486 if (id == 0)
1487 id = wl_map_insert_new(&client->objects, 0, NULL);
1488
1489 resource->object.id = id;
1490 resource->object.interface = interface;
1491 resource->object.implementation = NULL;
1492
1493 wl_signal_init(&resource->destroy_signal);
1494
1495 resource->destroy = NULL;
1496 resource->client = client;
1497 resource->data = NULL;
1498 resource->version = version;
1499 resource->dispatcher = NULL;
1500
1501 if (wl_map_insert_at(&client->objects, 0, id, resource) < 0) {
1502 wl_resource_post_error(client->display_resource,
1503 WL_DISPLAY_ERROR_INVALID_OBJECT,
1504 "invalid new id %d", id);
1505 free(resource);
1506 return NULL;
1507 }
1508
1509 wl_signal_emit(&client->resource_created_signal, resource);
1510 return resource;
1511 }
1512
1513 WL_EXPORT void
wl_log_set_handler_server(wl_log_func_t handler)1514 wl_log_set_handler_server(wl_log_func_t handler)
1515 {
1516 wl_log_handler = handler;
1517 }
1518
1519 /** Adds a new protocol logger.
1520 *
1521 * When a new protocol message arrives or is sent from the server
1522 * all the protocol logger functions will be called, carrying the
1523 * \a user_data pointer, the type of the message (request or
1524 * event) and the actual message.
1525 * The lifetime of the messages passed to the logger function ends
1526 * when they return so the messages cannot be stored and accessed
1527 * later.
1528 *
1529 * \a errno is set on error.
1530 *
1531 * \param display The display object
1532 * \param func The function to call to log a new protocol message
1533 * \param user_data The user data pointer to pass to \a func
1534 *
1535 * \return The protol logger object on success, NULL on failure.
1536 *
1537 * \sa wl_protocol_logger_destroy
1538 *
1539 * \memberof wl_display
1540 */
1541 WL_EXPORT struct wl_protocol_logger *
wl_display_add_protocol_logger(struct wl_display * display,wl_protocol_logger_func_t func,void * user_data)1542 wl_display_add_protocol_logger(struct wl_display *display,
1543 wl_protocol_logger_func_t func, void *user_data)
1544 {
1545 struct wl_protocol_logger *logger;
1546
1547 logger = malloc(sizeof *logger);
1548 if (!logger)
1549 return NULL;
1550
1551 logger->func = func;
1552 logger->user_data = user_data;
1553 wl_list_insert(&display->protocol_loggers, &logger->link);
1554
1555 return logger;
1556 }
1557
1558 /** Destroys a protocol logger.
1559 *
1560 * This function destroys a protocol logger and removes it from the display
1561 * it was added to with \a wl_display_add_protocol_logger.
1562 * The \a logger object becomes invalid after calling this function.
1563 *
1564 * \sa wl_display_add_protocol_logger
1565 *
1566 * \memberof wl_protocol_logger
1567 */
1568 WL_EXPORT void
wl_protocol_logger_destroy(struct wl_protocol_logger * logger)1569 wl_protocol_logger_destroy(struct wl_protocol_logger *logger)
1570 {
1571 wl_list_remove(&logger->link);
1572 free(logger);
1573 }
1574
1575 /** Add support for a wl_shm pixel format
1576 *
1577 * \param display The display object
1578 * \param format The wl_shm pixel format to advertise
1579 * \return A pointer to the wl_shm format that was added to the list
1580 * or NULL if adding it to the list failed.
1581 *
1582 * Add the specified wl_shm format to the list of formats the wl_shm
1583 * object advertises when a client binds to it. Adding a format to
1584 * the list means that clients will know that the compositor supports
1585 * this format and may use it for creating wl_shm buffers. The
1586 * compositor must be able to handle the pixel format when a client
1587 * requests it.
1588 *
1589 * The compositor by default supports WL_SHM_FORMAT_ARGB8888 and
1590 * WL_SHM_FORMAT_XRGB8888.
1591 *
1592 * \memberof wl_display
1593 */
1594 WL_EXPORT uint32_t *
wl_display_add_shm_format(struct wl_display * display,uint32_t format)1595 wl_display_add_shm_format(struct wl_display *display, uint32_t format)
1596 {
1597 uint32_t *p = NULL;
1598
1599 p = wl_array_add(&display->additional_shm_formats, sizeof *p);
1600
1601 if (p != NULL)
1602 *p = format;
1603 return p;
1604 }
1605
1606 /**
1607 * Get list of additional wl_shm pixel formats
1608 *
1609 * \param display The display object
1610 *
1611 * This function returns the list of addition wl_shm pixel formats
1612 * that the compositor supports. WL_SHM_FORMAT_ARGB8888 and
1613 * WL_SHM_FORMAT_XRGB8888 are always supported and not included in the
1614 * array, but all formats added through wl_display_add_shm_format()
1615 * will be in the array.
1616 *
1617 * \sa wl_display_add_shm_format()
1618 *
1619 * \private
1620 *
1621 * \memberof wl_display
1622 */
1623 struct wl_array *
wl_display_get_additional_shm_formats(struct wl_display * display)1624 wl_display_get_additional_shm_formats(struct wl_display *display)
1625 {
1626 return &display->additional_shm_formats;
1627 }
1628
1629 /** Get the list of currently connected clients
1630 *
1631 * \param display The display object
1632 *
1633 * This function returns a pointer to the list of clients currently
1634 * connected to the display. You can iterate on the list by using
1635 * the \a wl_client_for_each macro.
1636 * The returned value is valid for the lifetime of the \a display.
1637 * You must not modify the returned list, but only access it.
1638 *
1639 * \sa wl_client_for_each()
1640 * \sa wl_client_get_link()
1641 * \sa wl_client_from_link()
1642 *
1643 * \memberof wl_display
1644 */
1645 WL_EXPORT struct wl_list *
wl_display_get_client_list(struct wl_display * display)1646 wl_display_get_client_list(struct wl_display *display)
1647 {
1648 return &display->client_list;
1649 }
1650
1651 /** Get the link by which a client is inserted in the client list
1652 *
1653 * \param client The client object
1654 *
1655 * \sa wl_client_for_each()
1656 * \sa wl_display_get_client_list()
1657 * \sa wl_client_from_link()
1658 *
1659 * \memberof wl_client
1660 */
1661 WL_EXPORT struct wl_list *
wl_client_get_link(struct wl_client * client)1662 wl_client_get_link(struct wl_client *client)
1663 {
1664 return &client->link;
1665 }
1666
1667 /** Get a wl_client by its link
1668 *
1669 * \param link The link of a wl_client
1670 *
1671 * \sa wl_client_for_each()
1672 * \sa wl_display_get_client_list()
1673 * \sa wl_client_get_link()
1674 *
1675 * \memberof wl_client
1676 */
1677 WL_EXPORT struct wl_client *
wl_client_from_link(struct wl_list * link)1678 wl_client_from_link(struct wl_list *link)
1679 {
1680 return container_of(link, struct wl_client, link);
1681 }
1682
1683 /** Add a listener for the client's resource creation signal
1684 *
1685 * \param client The client object
1686 * \param listener The listener to be added
1687 *
1688 * When a new resource is created for this client the listener
1689 * will be notified, carrying the new resource as the data argument.
1690 *
1691 * \memberof wl_client
1692 */
1693 WL_EXPORT void
wl_client_add_resource_created_listener(struct wl_client * client,struct wl_listener * listener)1694 wl_client_add_resource_created_listener(struct wl_client *client,
1695 struct wl_listener *listener)
1696 {
1697 wl_signal_add(&client->resource_created_signal, listener);
1698 }
1699
1700 struct wl_resource_iterator_context {
1701 void *user_data;
1702 wl_client_for_each_resource_iterator_func_t it;
1703 };
1704
1705 static enum wl_iterator_result
resource_iterator_helper(void * res,void * user_data)1706 resource_iterator_helper(void *res, void *user_data)
1707 {
1708 struct wl_resource_iterator_context *context = user_data;
1709 struct wl_resource *resource = res;
1710
1711 return context->it(resource, context->user_data);
1712 }
1713
1714 /** Iterate over all the resources of a client
1715 *
1716 * \param client The client object
1717 * \param iterator The iterator function
1718 * \param user_data The user data pointer
1719 *
1720 * The function pointed by \a iterator will be called for each
1721 * resource owned by the client. The \a user_data will be passed
1722 * as the second argument of the iterator function.
1723 * If the \a iterator function returns \a WL_ITERATOR_CONTINUE the iteration
1724 * will continue, if it returns \a WL_ITERATOR_STOP it will stop.
1725 *
1726 * Creating and destroying resources while iterating is safe, but new
1727 * resources may or may not be picked up by the iterator.
1728 *
1729 * \sa wl_iterator_result
1730 *
1731 * \memberof wl_client
1732 */
1733 WL_EXPORT void
wl_client_for_each_resource(struct wl_client * client,wl_client_for_each_resource_iterator_func_t iterator,void * user_data)1734 wl_client_for_each_resource(struct wl_client *client,
1735 wl_client_for_each_resource_iterator_func_t iterator,
1736 void *user_data)
1737 {
1738 struct wl_resource_iterator_context context = {
1739 .user_data = user_data,
1740 .it = iterator,
1741 };
1742
1743 wl_map_for_each(&client->objects, resource_iterator_helper, &context);
1744 }
1745
1746 /** \cond */ /* Deprecated functions below. */
1747
1748 uint32_t
1749 wl_client_add_resource(struct wl_client *client,
1750 struct wl_resource *resource) WL_DEPRECATED;
1751
1752 WL_EXPORT uint32_t
wl_client_add_resource(struct wl_client * client,struct wl_resource * resource)1753 wl_client_add_resource(struct wl_client *client,
1754 struct wl_resource *resource)
1755 {
1756 if (resource->object.id == 0) {
1757 resource->object.id =
1758 wl_map_insert_new(&client->objects,
1759 WL_MAP_ENTRY_LEGACY, resource);
1760 } else if (wl_map_insert_at(&client->objects, WL_MAP_ENTRY_LEGACY,
1761 resource->object.id, resource) < 0) {
1762 wl_resource_post_error(client->display_resource,
1763 WL_DISPLAY_ERROR_INVALID_OBJECT,
1764 "invalid new id %d",
1765 resource->object.id);
1766 return 0;
1767 }
1768
1769 resource->client = client;
1770 wl_signal_init(&resource->destroy_signal);
1771
1772 return resource->object.id;
1773 }
1774
1775 struct wl_resource *
1776 wl_client_add_object(struct wl_client *client,
1777 const struct wl_interface *interface,
1778 const void *implementation,
1779 uint32_t id, void *data) WL_DEPRECATED;
1780
1781 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)1782 wl_client_add_object(struct wl_client *client,
1783 const struct wl_interface *interface,
1784 const void *implementation, uint32_t id, void *data)
1785 {
1786 struct wl_resource *resource;
1787
1788 resource = wl_resource_create(client, interface, -1, id);
1789 if (resource == NULL)
1790 wl_client_post_no_memory(client);
1791 else
1792 wl_resource_set_implementation(resource,
1793 implementation, data, NULL);
1794
1795 return resource;
1796 }
1797
1798 struct wl_resource *
1799 wl_client_new_object(struct wl_client *client,
1800 const struct wl_interface *interface,
1801 const void *implementation, void *data) WL_DEPRECATED;
1802
1803 WL_EXPORT struct wl_resource *
wl_client_new_object(struct wl_client * client,const struct wl_interface * interface,const void * implementation,void * data)1804 wl_client_new_object(struct wl_client *client,
1805 const struct wl_interface *interface,
1806 const void *implementation, void *data)
1807 {
1808 struct wl_resource *resource;
1809
1810 resource = wl_resource_create(client, interface, -1, 0);
1811 if (resource == NULL)
1812 wl_client_post_no_memory(client);
1813 else
1814 wl_resource_set_implementation(resource,
1815 implementation, data, NULL);
1816
1817 return resource;
1818 }
1819
1820 struct wl_global *
1821 wl_display_add_global(struct wl_display *display,
1822 const struct wl_interface *interface,
1823 void *data, wl_global_bind_func_t bind) WL_DEPRECATED;
1824
1825 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)1826 wl_display_add_global(struct wl_display *display,
1827 const struct wl_interface *interface,
1828 void *data, wl_global_bind_func_t bind)
1829 {
1830 return wl_global_create(display, interface, interface->version, data, bind);
1831 }
1832
1833 void
1834 wl_display_remove_global(struct wl_display *display,
1835 struct wl_global *global) WL_DEPRECATED;
1836
1837 WL_EXPORT void
wl_display_remove_global(struct wl_display * display,struct wl_global * global)1838 wl_display_remove_global(struct wl_display *display, struct wl_global *global)
1839 {
1840 wl_global_destroy(global);
1841 }
1842
1843 /** \endcond */
1844
1845 /* Functions at the end of this file are deprecated. Instead of adding new
1846 * code here, add it before the comment above that states:
1847 * Deprecated functions below.
1848 */
1849