2 * Copyright © 2008-2012 Kristian Høgsberg
3 * Copyright © 2010-2012 Intel Corporation
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that copyright
8 * notice and this permission notice appear in supporting documentation, and
9 * that the name of the copyright holders not be used in advertising or
10 * publicity pertaining to distribution of the software without specific,
11 * written prior permission. The copyright holders make no representations
12 * about the suitability of this software for any purpose. It is provided "as
13 * is" without express or implied warranty.
15 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
32 #include <sys/socket.h>
40 #include "wayland-util.h"
41 #include "wayland-os.h"
42 #include "wayland-client.h"
43 #include "wayland-private.h"
49 WL_PROXY_FLAG_ID_DELETED = (1 << 0),
50 WL_PROXY_FLAG_DESTROYED = (1 << 1)
54 struct wl_object object;
55 struct wl_display *display;
56 struct wl_event_queue *queue;
69 struct wl_event_queue {
71 struct wl_list event_list;
72 struct wl_display *display;
77 struct wl_proxy proxy;
78 struct wl_connection *connection;
81 pthread_t display_thread;
82 struct wl_map objects;
83 struct wl_event_queue queue;
84 struct wl_list event_queue_list;
85 pthread_mutex_t mutex;
90 static int wl_debug = 0;
93 display_fatal_error(struct wl_display *display, int error)
95 struct wl_event_queue *iter;
97 if (display->last_error)
103 display->last_error = error;
107 wl_list_for_each(iter, &display->event_queue_list, link)
108 pthread_cond_broadcast(&iter->cond);
112 wl_display_fatal_error(struct wl_display *display, int error)
114 pthread_mutex_lock(&display->mutex);
115 display_fatal_error(display, error);
116 pthread_mutex_unlock(&display->mutex);
120 wl_event_queue_init(struct wl_event_queue *queue, struct wl_display *display)
122 wl_list_init(&queue->event_list);
123 pthread_cond_init(&queue->cond, NULL);
124 queue->display = display;
128 wl_event_queue_release(struct wl_event_queue *queue)
130 struct wl_closure *closure;
132 while (!wl_list_empty(&queue->event_list)) {
133 closure = container_of(queue->event_list.next,
134 struct wl_closure, link);
135 wl_list_remove(&closure->link);
136 wl_closure_destroy(closure);
138 pthread_cond_destroy(&queue->cond);
141 /** Destroy an event queue
143 * \param queue The event queue to be destroyed
145 * Destroy the given event queue. Any pending event on that queue is
148 * The \ref wl_display object used to create the queue should not be
149 * destroyed until all event queues created with it are destroyed with
152 * \memberof wl_event_queue
155 wl_event_queue_destroy(struct wl_event_queue *queue)
157 struct wl_display *display = queue->display;
159 pthread_mutex_lock(&display->mutex);
160 wl_list_remove(&queue->link);
161 wl_event_queue_release(queue);
163 pthread_mutex_unlock(&display->mutex);
166 /** Create a new event queue for this display
168 * \param display The display context object
169 * \return A new event queue associated with this display or NULL on
172 * \memberof wl_display
174 WL_EXPORT struct wl_event_queue *
175 wl_display_create_queue(struct wl_display *display)
177 struct wl_event_queue *queue;
179 queue = malloc(sizeof *queue);
183 wl_event_queue_init(queue, display);
185 pthread_mutex_lock(&display->mutex);
186 wl_list_insert(&display->event_queue_list, &queue->link);
187 pthread_mutex_unlock(&display->mutex);
192 /** Create a proxy object with a given interface
194 * \param factory Factory proxy object
195 * \param interface Interface the proxy object should use
196 * \return A newly allocated proxy object or NULL on failure
198 * This function creates a new proxy object with the supplied interface. The
199 * proxy object will have an id assigned from the client id space. The id
200 * should be created on the compositor side by sending an appropriate request
201 * with \ref wl_proxy_marshal().
203 * The proxy will inherit the display and event queue of the factory object.
205 * \note This should not normally be used by non-generated code.
207 * \sa wl_display, wl_event_queue, wl_proxy_marshal()
211 WL_EXPORT struct wl_proxy *
212 wl_proxy_create(struct wl_proxy *factory, const struct wl_interface *interface)
214 struct wl_proxy *proxy;
215 struct wl_display *display = factory->display;
217 proxy = malloc(sizeof *proxy);
221 proxy->object.interface = interface;
222 proxy->object.implementation = NULL;
223 proxy->display = display;
224 proxy->queue = factory->queue;
228 pthread_mutex_lock(&display->mutex);
229 proxy->object.id = wl_map_insert_new(&display->objects,
230 WL_MAP_CLIENT_SIDE, proxy);
231 pthread_mutex_unlock(&display->mutex);
236 /* The caller should hold the display lock */
237 static struct wl_proxy *
238 wl_proxy_create_for_id(struct wl_proxy *factory,
239 uint32_t id, const struct wl_interface *interface)
241 struct wl_proxy *proxy;
242 struct wl_display *display = factory->display;
244 proxy = malloc(sizeof *proxy);
248 proxy->object.interface = interface;
249 proxy->object.implementation = NULL;
250 proxy->object.id = id;
251 proxy->display = display;
252 proxy->queue = factory->queue;
256 wl_map_insert_at(&display->objects, id, proxy);
261 /** Destroy a proxy object
263 * \param proxy The proxy to be destroyed
268 wl_proxy_destroy(struct wl_proxy *proxy)
270 struct wl_display *display = proxy->display;
272 pthread_mutex_lock(&display->mutex);
274 if (proxy->flags & WL_PROXY_FLAG_ID_DELETED)
275 wl_map_remove(&proxy->display->objects, proxy->object.id);
276 else if (proxy->object.id < WL_SERVER_ID_START)
277 wl_map_insert_at(&proxy->display->objects,
278 proxy->object.id, WL_ZOMBIE_OBJECT);
280 wl_map_insert_at(&proxy->display->objects,
281 proxy->object.id, NULL);
284 proxy->flags |= WL_PROXY_FLAG_DESTROYED;
287 if (!proxy->refcount)
290 pthread_mutex_unlock(&display->mutex);
293 /** Set a proxy's listener
295 * \param proxy The proxy object
296 * \param implementation The listener to be added to proxy
297 * \param data User data to be associated with the proxy
298 * \return 0 on success or -1 on failure
300 * Set proxy's listener to \c implementation and its user data to
301 * \c data. Ifa listener has already been set, this functions
302 * fails and nothing is changed.
304 * \c implementation is a vector of function pointers. For an opcode
305 * \c n, \c implemention[n] should point to the handler of \c n for
311 wl_proxy_add_listener(struct wl_proxy *proxy,
312 void (**implementation)(void), void *data)
314 if (proxy->object.implementation) {
315 fprintf(stderr, "proxy already has listener\n");
319 proxy->object.implementation = implementation;
320 proxy->user_data = data;
325 /** Prepare a request to be sent to the compositor
327 * \param proxy The proxy object
328 * \param opcode Opcode of the request to be sent
329 * \param ... Extra arguments for the given request
331 * Translates the request given by opcode and the extra arguments into the
332 * wire format and write it to the connection buffer.
334 * The example below creates a proxy object with the wl_surface_interface
335 * using a wl_compositor factory interface and sends the
336 * \c compositor.create_surface request using \ref wl_proxy_marshal(). Note
337 * the \c id is the extra argument to the request as specified by the
341 * id = wl_proxy_create((struct wl_proxy *) wl_compositor,
342 * &wl_surface_interface);
343 * wl_proxy_marshal((struct wl_proxy *) wl_compositor,
344 * WL_COMPOSITOR_CREATE_SURFACE, id);
347 * \note This should not normally be used by non-generated code.
349 * \sa wl_proxy_create()
354 wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
356 struct wl_closure *closure;
359 pthread_mutex_lock(&proxy->display->mutex);
361 va_start(ap, opcode);
362 closure = wl_closure_vmarshal(&proxy->object, opcode, ap,
363 &proxy->object.interface->methods[opcode]);
366 if (closure == NULL) {
367 fprintf(stderr, "Error marshalling request\n");
372 wl_closure_print(closure, &proxy->object, true);
374 if (wl_closure_send(closure, proxy->display->connection)) {
375 fprintf(stderr, "Error sending request: %m\n");
379 wl_closure_destroy(closure);
381 pthread_mutex_unlock(&proxy->display->mutex);
385 display_handle_error(void *data,
386 struct wl_display *display, struct wl_object *object,
387 uint32_t code, const char *message)
391 wl_log("%s@%u: error %d: %s\n",
392 object->interface->name, object->id, code, message);
395 case WL_DISPLAY_ERROR_INVALID_OBJECT:
396 case WL_DISPLAY_ERROR_INVALID_METHOD:
399 case WL_DISPLAY_ERROR_NO_MEMORY:
407 wl_display_fatal_error(display, err);
411 display_handle_delete_id(void *data, struct wl_display *display, uint32_t id)
413 struct wl_proxy *proxy;
415 pthread_mutex_lock(&display->mutex);
417 proxy = wl_map_lookup(&display->objects, id);
418 if (proxy != WL_ZOMBIE_OBJECT)
419 proxy->flags |= WL_PROXY_FLAG_ID_DELETED;
421 wl_map_remove(&display->objects, id);
423 pthread_mutex_unlock(&display->mutex);
426 static const struct wl_display_listener display_listener = {
427 display_handle_error,
428 display_handle_delete_id
432 connect_to_socket(const char *name)
434 struct sockaddr_un addr;
436 const char *runtime_dir;
439 runtime_dir = getenv("XDG_RUNTIME_DIR");
442 "error: XDG_RUNTIME_DIR not set in the environment.\n");
444 /* to prevent programs reporting
445 * "failed to create display: Success" */
451 name = getenv("WAYLAND_DISPLAY");
455 fd = wl_os_socket_cloexec(PF_LOCAL, SOCK_STREAM, 0);
459 memset(&addr, 0, sizeof addr);
460 addr.sun_family = AF_LOCAL;
462 snprintf(addr.sun_path, sizeof addr.sun_path,
463 "%s/%s", runtime_dir, name) + 1;
465 assert(name_size > 0);
466 if (name_size > (int)sizeof addr.sun_path) {
468 "error: socket path \"%s/%s\" plus null terminator"
469 " exceeds 108 bytes\n", runtime_dir, name);
471 /* to prevent programs reporting
472 * "failed to add socket: Success" */
473 errno = ENAMETOOLONG;
477 size = offsetof (struct sockaddr_un, sun_path) + name_size;
479 if (connect(fd, (struct sockaddr *) &addr, size) < 0) {
487 /** Connect to Wayland display on an already open fd
489 * \param fd The fd to use for the connection
490 * \return A \ref wl_display object or \c NULL on failure
492 * The wl_display takes ownership of the fd and will close it when the
493 * display is destroyed. The fd will also be closed in case of
496 * \memberof wl_display
498 WL_EXPORT struct wl_display *
499 wl_display_connect_to_fd(int fd)
501 struct wl_display *display;
504 debug = getenv("WAYLAND_DEBUG");
508 display = malloc(sizeof *display);
509 if (display == NULL) {
514 memset(display, 0, sizeof *display);
517 wl_map_init(&display->objects);
518 wl_event_queue_init(&display->queue, display);
519 wl_list_init(&display->event_queue_list);
520 pthread_mutex_init(&display->mutex, NULL);
522 wl_map_insert_new(&display->objects, WL_MAP_CLIENT_SIDE, NULL);
524 display->proxy.object.interface = &wl_display_interface;
525 display->proxy.object.id =
526 wl_map_insert_new(&display->objects,
527 WL_MAP_CLIENT_SIDE, display);
528 display->proxy.display = display;
529 display->proxy.object.implementation = (void(**)(void)) &display_listener;
530 display->proxy.user_data = display;
531 display->proxy.queue = &display->queue;
532 display->proxy.flags = 0;
533 display->proxy.refcount = 1;
535 display->connection = wl_connection_create(display->fd);
536 if (display->connection == NULL) {
537 wl_map_release(&display->objects);
546 /** Connect to a Wayland display
548 * \param name Name of the Wayland display to connect to
549 * \return A \ref wl_display object or \c NULL on failure
551 * Connect to the Wayland display named \c name. If \c name is \c NULL,
552 * its value will bee replaced with the WAYLAND_DISPLAY environment
553 * variable if it is set, otherwise display "wayland-0" will be used.
555 * \memberof wl_display
557 WL_EXPORT struct wl_display *
558 wl_display_connect(const char *name)
560 char *connection, *end;
563 connection = getenv("WAYLAND_SOCKET");
565 fd = strtol(connection, &end, 0);
569 flags = fcntl(fd, F_GETFD);
571 fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
572 unsetenv("WAYLAND_SOCKET");
574 fd = connect_to_socket(name);
579 return wl_display_connect_to_fd(fd);
582 /** Close a connection to a Wayland display
584 * \param display The display context object
586 * Close the connection to \c display and free all resources associated
589 * \memberof wl_display
592 wl_display_disconnect(struct wl_display *display)
594 wl_connection_destroy(display->connection);
595 wl_map_release(&display->objects);
596 wl_event_queue_release(&display->queue);
597 pthread_mutex_destroy(&display->mutex);
604 /** Get a display context's file descriptor
606 * \param display The display context object
607 * \return Display object file descriptor
609 * Return the file descriptor associated with a display so it can be
610 * integrated into the client's main loop.
612 * \memberof wl_display
615 wl_display_get_fd(struct wl_display *display)
621 sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
626 wl_callback_destroy(callback);
629 static const struct wl_callback_listener sync_listener = {
633 /** Block until all pending request are processed by the server
635 * \param display The display context object
636 * \return The number of dispatched events on success or -1 on failure
638 * Blocks until the server process all currently issued requests and
639 * sends out pending events on all event queues.
641 * \memberof wl_display
644 wl_display_roundtrip(struct wl_display *display)
646 struct wl_callback *callback;
650 callback = wl_display_sync(display);
651 wl_callback_add_listener(callback, &sync_listener, &done);
652 while (!done && !ret)
653 ret = wl_display_dispatch(display);
659 create_proxies(struct wl_proxy *sender, struct wl_closure *closure)
661 struct wl_proxy *proxy;
662 const char *signature;
663 struct argument_details arg;
668 signature = closure->message->signature;
669 count = arg_count_for_signature(signature) + 2;
670 for (i = 2; i < count; i++) {
671 signature = get_next_argument(signature, &arg);
674 id = **(uint32_t **) closure->args[i];
676 *(void **) closure->args[i] = NULL;
679 proxy = wl_proxy_create_for_id(sender, id,
680 closure->message->types[i - 2]);
683 *(void **) closure->args[i] = proxy;
694 increase_closure_args_refcount(struct wl_closure *closure)
696 const char *signature;
697 struct argument_details arg;
699 struct wl_proxy *proxy;
701 signature = closure->message->signature;
702 count = arg_count_for_signature(signature) + 2;
703 for (i = 2; i < count; i++) {
704 signature = get_next_argument(signature, &arg);
708 proxy = *(struct wl_proxy **) closure->args[i];
719 queue_event(struct wl_display *display, int len)
723 struct wl_proxy *proxy;
724 struct wl_closure *closure;
725 const struct wl_message *message;
727 wl_connection_copy(display->connection, p, sizeof p);
729 opcode = p[1] & 0xffff;
734 proxy = wl_map_lookup(&display->objects, id);
735 if (proxy == WL_ZOMBIE_OBJECT) {
736 wl_connection_consume(display->connection, size);
738 } else if (proxy == NULL) {
739 wl_connection_consume(display->connection, size);
743 message = &proxy->object.interface->events[opcode];
744 closure = wl_connection_demarshal(display->connection, size,
745 &display->objects, message);
749 if (create_proxies(proxy, closure) < 0) {
750 wl_closure_destroy(closure);
754 if (wl_closure_lookup_objects(closure, &display->objects) != 0) {
755 wl_closure_destroy(closure);
759 increase_closure_args_refcount(closure);
761 closure->proxy = proxy;
763 if (wl_list_empty(&proxy->queue->event_list))
764 pthread_cond_signal(&proxy->queue->cond);
765 wl_list_insert(proxy->queue->event_list.prev, &closure->link);
771 decrease_closure_args_refcount(struct wl_closure *closure)
773 const char *signature;
774 struct argument_details arg;
776 struct wl_proxy *proxy;
778 signature = closure->message->signature;
779 count = arg_count_for_signature(signature) + 2;
780 for (i = 2; i < count; i++) {
781 signature = get_next_argument(signature, &arg);
785 proxy = *(struct wl_proxy **) closure->args[i];
787 if (proxy->flags & WL_PROXY_FLAG_DESTROYED)
788 *(void **) closure->args[i] = NULL;
791 if (!proxy->refcount)
802 dispatch_event(struct wl_display *display, struct wl_event_queue *queue)
804 struct wl_closure *closure;
805 struct wl_proxy *proxy;
807 bool proxy_destroyed;
809 closure = container_of(queue->event_list.next,
810 struct wl_closure, link);
811 wl_list_remove(&closure->link);
812 opcode = closure->buffer[1] & 0xffff;
814 /* Verify that the receiving object is still valid by checking if has
815 * been destroyed by the application. */
817 decrease_closure_args_refcount(closure);
818 proxy = closure->proxy;
819 proxy_destroyed = !!(proxy->flags & WL_PROXY_FLAG_DESTROYED);
822 if (!proxy->refcount)
825 if (proxy_destroyed) {
826 wl_closure_destroy(closure);
830 pthread_mutex_unlock(&display->mutex);
832 if (proxy->object.implementation) {
834 wl_closure_print(closure, &proxy->object, false);
836 wl_closure_invoke(closure, &proxy->object,
837 proxy->object.implementation[opcode],
841 wl_closure_destroy(closure);
843 pthread_mutex_lock(&display->mutex);
847 dispatch_queue(struct wl_display *display,
848 struct wl_event_queue *queue, int block)
850 int len, size, count, ret;
852 pthread_mutex_lock(&display->mutex);
854 if (display->last_error)
857 ret = wl_connection_flush(display->connection);
858 if (ret < 0 && errno != EAGAIN) {
859 display_fatal_error(display, errno);
863 if (block && wl_list_empty(&queue->event_list) &&
864 pthread_equal(display->display_thread, pthread_self())) {
865 len = wl_connection_read(display->connection);
867 display_fatal_error(display, errno);
869 } else if (len == 0) {
870 display_fatal_error(display, EPIPE);
874 size = queue_event(display, len);
876 display_fatal_error(display, errno);
878 } else if (size == 0) {
883 } else if (block && wl_list_empty(&queue->event_list)) {
884 pthread_cond_wait(&queue->cond, &display->mutex);
885 if (display->last_error)
889 for (count = 0; !wl_list_empty(&queue->event_list); count++) {
890 dispatch_event(display, queue);
891 if (display->last_error)
895 pthread_mutex_unlock(&display->mutex);
900 errno = display->last_error;
901 pthread_mutex_unlock(&display->mutex);
906 /** Dispatch events in an event queue
908 * \param display The display context object
909 * \param queue The event queue to dispatch
910 * \return The number of dispatched events on success or -1 on failure
912 * Dispatch all incoming events for objects assigned to the given
913 * event queue. On failure -1 is returned and errno set appropriately.
915 * This function blocks if there are no events to dispatch. If calling from
916 * the main thread, it will block reading data from the display fd. For other
917 * threads this will block until the main thread queues events on the queue
918 * passed as argument.
920 * \memberof wl_display
923 wl_display_dispatch_queue(struct wl_display *display,
924 struct wl_event_queue *queue)
926 return dispatch_queue(display, queue, 1);
929 /** Process incoming events
931 * \param display The display context object
932 * \return The number of dispatched events on success or -1 on failure
934 * Dispatch the display's main event queue.
936 * If the main event queue is empty, this function blocks until there are
937 * events to be read from the display fd. Events are read and queued on
938 * the appropriate event queues. Finally, events on the main event queue
941 * \note It is not possible to check if there are events on the main queue
942 * or not. For dispatching main queue events without blocking, see \ref
943 * wl_display_dispatch_pending().
945 * \note Calling this makes the current thread the main one.
947 * \sa wl_display_dispatch_pending(), wl_display_dispatch_queue()
949 * \memberof wl_display
952 wl_display_dispatch(struct wl_display *display)
954 display->display_thread = pthread_self();
956 return dispatch_queue(display, &display->queue, 1);
959 /** Dispatch main queue events without reading from the display fd
961 * \param display The display context object
962 * \return The number of dispatched events or -1 on failure
964 * This function dispatches events on the main event queue. It does not
965 * attempt to read the display fd and simply returns zero if the main
966 * queue is empty, i.e., it doesn't block.
968 * This is necessary when a client's main loop wakes up on some fd other
969 * than the display fd (network socket, timer fd, etc) and calls \ref
970 * wl_display_dispatch_queue() from that callback. This may queue up
971 * events in the main queue while reading all data from the display fd.
972 * When the main thread returns to the main loop to block, the display fd
973 * no longer has data, causing a call to \em poll(2) (or similar
974 * functions) to block indefinitely, even though there are events ready
977 * To proper integrate the wayland display fd into a main loop, the
978 * client should always call \ref wl_display_dispatch_pending() and then
979 * \ref wl_display_flush() prior to going back to sleep. At that point,
980 * the fd typically doesn't have data so attempting I/O could block, but
981 * events queued up on the main queue should be dispatched.
983 * A real-world example is a main loop that wakes up on a timerfd (or a
984 * sound card fd becoming writable, for example in a video player), which
985 * then triggers GL rendering and eventually eglSwapBuffers().
986 * eglSwapBuffers() may call wl_display_dispatch_queue() if it didn't
987 * receive the frame event for the previous frame, and as such queue
988 * events in the main queue.
990 * \note Calling this makes the current thread the main one.
992 * \sa wl_display_dispatch(), wl_display_dispatch_queue(),
995 * \memberof wl_display
998 wl_display_dispatch_pending(struct wl_display *display)
1000 display->display_thread = pthread_self();
1002 return dispatch_queue(display, &display->queue, 0);
1005 /** Retrieve the last error occured on a display
1007 * \param display The display context object
1008 * \return The last error occured on \c display or 0 if no error occured
1010 * Return the last error occured on the display. This may be an error sent
1011 * by the server or caused by the local client.
1013 * \note Errors are \b fatal. If this function returns non-zero the display
1014 * can no longer be used.
1016 * \memberof wl_display
1019 wl_display_get_error(struct wl_display *display)
1023 pthread_mutex_lock(&display->mutex);
1025 ret = display->last_error;
1027 pthread_mutex_unlock(&display->mutex);
1032 /** Send all buffered request on the display to the server
1034 * \param display The display context object
1035 * \return The number of bytes send on success or -1 on failure
1037 * Send all buffered data on the client side to the server. Clients
1038 * should call this function before blocking. On success, the number
1039 * of bytes sent to the server is returned. On failure, this
1040 * function returns -1 and errno is set appropriately.
1042 * \memberof wl_display
1045 wl_display_flush(struct wl_display *display)
1049 pthread_mutex_lock(&display->mutex);
1051 if (display->last_error) {
1052 errno = display->last_error;
1055 ret = wl_connection_flush(display->connection);
1056 if (ret < 0 && errno != EAGAIN)
1057 display_fatal_error(display, errno);
1060 pthread_mutex_unlock(&display->mutex);
1065 /** Set the user data associated with a proxy
1067 * \param proxy The proxy object
1068 * \param user_data The data to be associated with proxy
1070 * Set the user data associated with \c proxy. When events for this
1071 * proxy are received, \c user_data will be supplied to its listener.
1073 * \memberof wl_proxy
1076 wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data)
1078 proxy->user_data = user_data;
1081 /** Get the user data associated with a proxy
1083 * \param proxy The proxy object
1084 * \return The user data associated with proxy
1086 * \memberof wl_proxy
1089 wl_proxy_get_user_data(struct wl_proxy *proxy)
1091 return proxy->user_data;
1094 /** Get the id of a proxy object
1096 * \param proxy The proxy object
1097 * \return The id the object associated with the proxy
1099 * \memberof wl_proxy
1102 wl_proxy_get_id(struct wl_proxy *proxy)
1104 return proxy->object.id;
1108 /** Assign a proxy to an event queue
1110 * \param proxy The proxy object
1111 * \param queue The event queue that will handle this proxy
1113 * Assign proxy to event queue. Events coming from \c proxy will be
1114 * queued in \c queue instead of the display's main queue.
1116 * \sa wl_display_dispatch_queue()
1118 * \memberof wl_proxy
1121 wl_proxy_set_queue(struct wl_proxy *proxy, struct wl_event_queue *queue)
1123 proxy->queue = queue;
1127 wl_log_set_handler_client(wl_log_func_t handler)
1129 wl_log_handler = handler;