client: Add wl_display_dispatch_pending() for dispatching without reading
[profile/ivi/wayland.git] / src / wayland-client.c
1 /*
2  * Copyright © 2008-2012 Kristian Høgsberg
3  * Copyright © 2010-2012 Intel Corporation
4  *
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.
14  *
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
21  * OF THIS SOFTWARE.
22  */
23
24 #include <stdlib.h>
25 #include <stdint.h>
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <stdbool.h>
29 #include <errno.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <sys/socket.h>
33 #include <sys/un.h>
34 #include <ctype.h>
35 #include <assert.h>
36 #include <fcntl.h>
37 #include <sys/poll.h>
38 #include <pthread.h>
39
40 #include "wayland-util.h"
41 #include "wayland-os.h"
42 #include "wayland-client.h"
43 #include "wayland-private.h"
44
45 struct wl_proxy {
46         struct wl_object object;
47         struct wl_display *display;
48         struct wl_event_queue *queue;
49         int id_deleted;
50         void *user_data;
51 };
52
53 struct wl_global {
54         uint32_t id;
55         char *interface;
56         uint32_t version;
57         struct wl_list link;
58 };
59
60 struct wl_event_queue {
61         struct wl_list event_list;
62         pthread_cond_t cond;
63 };
64
65 struct wl_display {
66         struct wl_proxy proxy;
67         struct wl_connection *connection;
68         int fd;
69         int close_fd;
70         pthread_t display_thread;
71         struct wl_map objects;
72         struct wl_event_queue queue;
73         pthread_mutex_t mutex;
74 };
75
76 static int wl_debug = 0;
77
78 static void
79 wl_event_queue_init(struct wl_event_queue *queue)
80 {
81         wl_list_init(&queue->event_list);
82         pthread_cond_init(&queue->cond, NULL);
83 }
84
85 static void
86 wl_event_queue_release(struct wl_event_queue *queue)
87 {
88         struct wl_closure *closure;
89
90         while (!wl_list_empty(&queue->event_list)) {
91                 closure = container_of(queue->event_list.next,
92                                        struct wl_closure, link);
93                 wl_list_remove(&closure->link);
94                 wl_closure_destroy(closure);
95         }
96         pthread_cond_destroy(&queue->cond);
97 }
98
99 WL_EXPORT void
100 wl_event_queue_destroy(struct wl_event_queue *queue)
101 {
102         wl_event_queue_release(queue);
103         free(queue);
104 }
105
106 WL_EXPORT struct wl_event_queue *
107 wl_display_create_queue(struct wl_display *display)
108 {
109         struct wl_event_queue *queue;
110
111         queue = malloc(sizeof *queue);
112         if (queue == NULL)
113                 return NULL;
114
115         wl_event_queue_init(queue);
116
117         return queue;
118 }
119
120 WL_EXPORT struct wl_proxy *
121 wl_proxy_create(struct wl_proxy *factory, const struct wl_interface *interface)
122 {
123         struct wl_proxy *proxy;
124         struct wl_display *display = factory->display;
125
126         proxy = malloc(sizeof *proxy);
127         if (proxy == NULL)
128                 return NULL;
129
130         proxy->object.interface = interface;
131         proxy->object.implementation = NULL;
132         proxy->display = display;
133         proxy->queue = factory->queue;
134         proxy->id_deleted = 0;
135
136         pthread_mutex_lock(&display->mutex);
137         proxy->object.id = wl_map_insert_new(&display->objects,
138                                              WL_MAP_CLIENT_SIDE, proxy);
139         pthread_mutex_unlock(&display->mutex);
140
141         return proxy;
142 }
143
144 /* The caller should hold the display lock */
145 static struct wl_proxy *
146 wl_proxy_create_for_id(struct wl_proxy *factory,
147                        uint32_t id, const struct wl_interface *interface)
148 {
149         struct wl_proxy *proxy;
150         struct wl_display *display = factory->display;
151
152         proxy = malloc(sizeof *proxy);
153         if (proxy == NULL)
154                 return NULL;
155
156         proxy->object.interface = interface;
157         proxy->object.implementation = NULL;
158         proxy->object.id = id;
159         proxy->display = display;
160         proxy->queue = factory->queue;
161         proxy->id_deleted = 0;
162
163         wl_map_insert_at(&display->objects, id, proxy);
164
165         return proxy;
166 }
167
168 WL_EXPORT void
169 wl_proxy_destroy(struct wl_proxy *proxy)
170 {
171         pthread_mutex_lock(&proxy->display->mutex);
172
173         if (proxy->id_deleted)
174                 wl_map_remove(&proxy->display->objects, proxy->object.id);
175         else if (proxy->object.id < WL_SERVER_ID_START)
176                 wl_map_insert_at(&proxy->display->objects,
177                                  proxy->object.id, WL_ZOMBIE_OBJECT);
178         else
179                 wl_map_insert_at(&proxy->display->objects,
180                                  proxy->object.id, NULL);
181
182         pthread_mutex_unlock(&proxy->display->mutex);
183
184         free(proxy);
185 }
186
187 WL_EXPORT int
188 wl_proxy_add_listener(struct wl_proxy *proxy,
189                       void (**implementation)(void), void *data)
190 {
191         if (proxy->object.implementation) {
192                 fprintf(stderr, "proxy already has listener\n");
193                 return -1;
194         }
195
196         proxy->object.implementation = implementation;
197         proxy->user_data = data;
198
199         return 0;
200 }
201
202 WL_EXPORT void
203 wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
204 {
205         struct wl_closure *closure;
206         va_list ap;
207
208         pthread_mutex_lock(&proxy->display->mutex);
209
210         va_start(ap, opcode);
211         closure = wl_closure_vmarshal(&proxy->object, opcode, ap,
212                                       &proxy->object.interface->methods[opcode]);
213         va_end(ap);
214
215         if (closure == NULL) {
216                 fprintf(stderr, "Error marshalling request\n");
217                 abort();
218         }
219
220         if (wl_debug)
221                 wl_closure_print(closure, &proxy->object, true);
222
223         if (wl_closure_send(closure, proxy->display->connection)) {
224                 fprintf(stderr, "Error sending request: %m\n");
225                 abort();
226         }
227
228         wl_closure_destroy(closure);
229
230         pthread_mutex_unlock(&proxy->display->mutex);
231 }
232
233 static void
234 display_handle_error(void *data,
235                      struct wl_display *display, struct wl_object *object,
236                      uint32_t code, const char *message)
237 {
238         fprintf(stderr, "%s@%u: error %d: %s\n",
239                 object->interface->name, object->id, code, message);
240         abort();
241 }
242
243 static void
244 display_handle_delete_id(void *data, struct wl_display *display, uint32_t id)
245 {
246         struct wl_proxy *proxy;
247
248         pthread_mutex_lock(&display->mutex);
249
250         proxy = wl_map_lookup(&display->objects, id);
251         if (proxy != WL_ZOMBIE_OBJECT)
252                 proxy->id_deleted = 1;
253         else
254                 wl_map_remove(&display->objects, id);
255
256         pthread_mutex_unlock(&display->mutex);
257 }
258
259 static const struct wl_display_listener display_listener = {
260         display_handle_error,
261         display_handle_delete_id
262 };
263
264 static int
265 connect_to_socket(const char *name)
266 {
267         struct sockaddr_un addr;
268         socklen_t size;
269         const char *runtime_dir;
270         int name_size, fd;
271
272         runtime_dir = getenv("XDG_RUNTIME_DIR");
273         if (!runtime_dir) {
274                 fprintf(stderr,
275                         "error: XDG_RUNTIME_DIR not set in the environment.\n");
276
277                 /* to prevent programs reporting
278                  * "failed to create display: Success" */
279                 errno = ENOENT;
280                 return -1;
281         }
282
283         if (name == NULL)
284                 name = getenv("WAYLAND_DISPLAY");
285         if (name == NULL)
286                 name = "wayland-0";
287
288         fd = wl_os_socket_cloexec(PF_LOCAL, SOCK_STREAM, 0);
289         if (fd < 0)
290                 return -1;
291
292         memset(&addr, 0, sizeof addr);
293         addr.sun_family = AF_LOCAL;
294         name_size =
295                 snprintf(addr.sun_path, sizeof addr.sun_path,
296                          "%s/%s", runtime_dir, name) + 1;
297
298         assert(name_size > 0);
299         if (name_size > (int)sizeof addr.sun_path) {
300                 fprintf(stderr,
301                        "error: socket path \"%s/%s\" plus null terminator"
302                        " exceeds 108 bytes\n", runtime_dir, name);
303                 close(fd);
304                 /* to prevent programs reporting
305                  * "failed to add socket: Success" */
306                 errno = ENAMETOOLONG;
307                 return -1;
308         };
309
310         size = offsetof (struct sockaddr_un, sun_path) + name_size;
311
312         if (connect(fd, (struct sockaddr *) &addr, size) < 0) {
313                 close(fd);
314                 return -1;
315         }
316
317         return fd;
318 }
319
320 WL_EXPORT struct wl_display *
321 wl_display_connect_to_fd(int fd)
322 {
323         struct wl_display *display;
324         const char *debug;
325
326         debug = getenv("WAYLAND_DEBUG");
327         if (debug)
328                 wl_debug = 1;
329
330         display = malloc(sizeof *display);
331         if (display == NULL)
332                 return NULL;
333
334         memset(display, 0, sizeof *display);
335
336         display->fd = fd;
337         wl_map_init(&display->objects);
338         wl_event_queue_init(&display->queue);
339         pthread_mutex_init(&display->mutex, NULL);
340
341         wl_map_insert_new(&display->objects, WL_MAP_CLIENT_SIDE, NULL);
342
343         display->proxy.object.interface = &wl_display_interface;
344         display->proxy.object.id =
345                 wl_map_insert_new(&display->objects,
346                                   WL_MAP_CLIENT_SIDE, display);
347         display->proxy.display = display;
348         display->proxy.object.implementation = (void(**)(void)) &display_listener;
349         display->proxy.user_data = display;
350         display->proxy.queue = &display->queue;
351
352         display->connection = wl_connection_create(display->fd);
353         if (display->connection == NULL) {
354                 wl_map_release(&display->objects);
355                 close(display->fd);
356                 free(display);
357                 return NULL;
358         }
359
360         return display;
361 }
362
363 WL_EXPORT struct wl_display *
364 wl_display_connect(const char *name)
365 {
366         struct wl_display *display;
367         char *connection, *end;
368         int flags, fd;
369
370         connection = getenv("WAYLAND_SOCKET");
371         if (connection) {
372                 fd = strtol(connection, &end, 0);
373                 if (*end != '\0')
374                         return NULL;
375
376                 flags = fcntl(fd, F_GETFD);
377                 if (flags != -1)
378                         fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
379                 unsetenv("WAYLAND_SOCKET");
380         } else {
381                 fd = connect_to_socket(name);
382                 if (fd < 0)
383                         return NULL;
384         }
385
386         display = wl_display_connect_to_fd(fd);
387         if (display)
388                 display->close_fd = 1;
389
390         return display;
391 }
392
393 WL_EXPORT void
394 wl_display_disconnect(struct wl_display *display)
395 {
396         wl_connection_destroy(display->connection);
397         wl_map_release(&display->objects);
398         wl_event_queue_release(&display->queue);
399         pthread_mutex_destroy(&display->mutex);
400
401         if (display->close_fd)
402                 close(display->fd);
403
404         free(display);
405 }
406
407 WL_EXPORT int
408 wl_display_get_fd(struct wl_display *display)
409 {
410         return display->fd;
411 }
412
413 static void
414 sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
415 {
416    int *done = data;
417
418    *done = 1;
419    wl_callback_destroy(callback);
420 }
421
422 static const struct wl_callback_listener sync_listener = {
423         sync_callback
424 };
425
426 WL_EXPORT void
427 wl_display_roundtrip(struct wl_display *display)
428 {
429         struct wl_callback *callback;
430         int done;
431
432         done = 0;
433         callback = wl_display_sync(display);
434         wl_callback_add_listener(callback, &sync_listener, &done);
435         while (!done)
436                 wl_display_dispatch(display);
437 }
438
439 static int
440 create_proxies(struct wl_proxy *sender, struct wl_closure *closure)
441 {
442         struct wl_proxy *proxy;
443         const char *signature;
444         struct argument_details arg;
445         uint32_t id;
446         int i;
447         int count;
448
449         signature = closure->message->signature;
450         count = arg_count_for_signature(signature) + 2;
451         for (i = 2; i < count; i++) {
452                 signature = get_next_argument(signature, &arg);
453                 switch (arg.type) {
454                 case 'n':
455                         id = **(uint32_t **) closure->args[i];
456                         if (id == 0) {
457                                 *(void **) closure->args[i] = NULL;
458                                 break;
459                         }
460                         proxy = wl_proxy_create_for_id(sender, id,
461                                                        closure->message->types[i - 2]);
462                         if (proxy == NULL)
463                                 return -1;
464                         *(void **) closure->args[i] = proxy;
465                         break;
466                 default:
467                         break;
468                 }
469         }
470
471         return 0;
472 }
473
474 static int
475 queue_event(struct wl_display *display, int len)
476 {
477         uint32_t p[2], id;
478         int opcode, size;
479         struct wl_proxy *proxy;
480         struct wl_closure *closure;
481         const struct wl_message *message;
482
483         wl_connection_copy(display->connection, p, sizeof p);
484         id = p[0];
485         opcode = p[1] & 0xffff;
486         size = p[1] >> 16;
487         if (len < size)
488                 return 0;
489
490         proxy = wl_map_lookup(&display->objects, id);
491         if (proxy == WL_ZOMBIE_OBJECT) {
492                 wl_connection_consume(display->connection, size);
493                 return size;
494         } else if (proxy == NULL) {
495                 wl_connection_consume(display->connection, size);
496                 return size;
497         }
498
499         message = &proxy->object.interface->events[opcode];
500         closure = wl_connection_demarshal(display->connection, size,
501                                           &display->objects, message);
502
503         if (closure == NULL || create_proxies(proxy, closure) < 0) {
504                 fprintf(stderr, "Error demarshalling event\n");
505                 abort();
506         }
507
508         if (wl_list_empty(&proxy->queue->event_list))
509                 pthread_cond_signal(&proxy->queue->cond);
510         wl_list_insert(proxy->queue->event_list.prev, &closure->link);
511
512         return size;
513 }
514
515 static void
516 dispatch_event(struct wl_display *display, struct wl_event_queue *queue)
517 {
518         struct wl_closure *closure;
519         struct wl_proxy *proxy;
520         uint32_t id;
521         int opcode, ret;
522
523         closure = container_of(queue->event_list.next,
524                                struct wl_closure, link);
525         wl_list_remove(&closure->link);
526         id = closure->buffer[0];
527         opcode = closure->buffer[1] & 0xffff;
528
529         /* Verify that the receiving object is still valid and look up
530          * proxies for any arguments.  We have to do this just before
531          * calling the handler, since preceeding events may have
532          * destroyed either the proxy or the proxy args since the
533          * event was queued. */
534         proxy = wl_map_lookup(&display->objects, id);
535         ret = wl_closure_lookup_objects(closure, &display->objects);
536
537         pthread_mutex_unlock(&display->mutex);
538
539         if (proxy != WL_ZOMBIE_OBJECT &&
540             proxy->object.implementation && ret == 0) {
541                 if (wl_debug)
542                         wl_closure_print(closure, &proxy->object, false);
543
544                 wl_closure_invoke(closure, &proxy->object,
545                                   proxy->object.implementation[opcode],
546                                   proxy->user_data);
547         }
548
549         wl_closure_destroy(closure);
550
551         pthread_mutex_lock(&display->mutex);
552 }
553
554
555 static int
556 dispatch_queue(struct wl_display *display,
557                struct wl_event_queue *queue, int block)
558 {
559         int len, size;
560
561         pthread_mutex_lock(&display->mutex);
562
563         /* FIXME: Handle flush errors, EAGAIN... */
564         wl_connection_flush(display->connection);
565
566         if (block && wl_list_empty(&queue->event_list) &&
567             pthread_equal(display->display_thread, pthread_self())) {
568                 len = wl_connection_read(display->connection);
569                 if (len == -1) {
570                         pthread_mutex_unlock(&display->mutex);
571                         return -1;
572                 }
573                 while (len >= 8) {
574                         size = queue_event(display, len);
575                         if (size == 0)
576                                 break;
577                         len -= size;
578                 }
579         } else if (block && wl_list_empty(&queue->event_list)) {
580                 pthread_cond_wait(&queue->cond, &display->mutex);
581         }
582
583         while (!wl_list_empty(&queue->event_list))
584                 dispatch_event(display, queue);
585
586         pthread_mutex_unlock(&display->mutex);
587
588         return 0;
589 }
590
591 WL_EXPORT int
592 wl_display_dispatch_queue(struct wl_display *display,
593                           struct wl_event_queue *queue)
594 {
595         return dispatch_queue(display, queue, 1);
596 }
597
598 WL_EXPORT int
599 wl_display_dispatch(struct wl_display *display)
600 {
601         display->display_thread = pthread_self();
602
603         return dispatch_queue(display, &display->queue, 1);
604 }
605
606 WL_EXPORT int
607 wl_display_dispatch_pending(struct wl_display *display)
608 {
609         display->display_thread = pthread_self();
610
611         return dispatch_queue(display, &display->queue, 0);
612 }
613
614 WL_EXPORT int
615 wl_display_flush(struct wl_display *display)
616 {
617         int ret;
618
619         pthread_mutex_lock(&display->mutex);
620
621         ret = wl_connection_flush(display->connection);
622
623         pthread_mutex_unlock(&display->mutex);
624
625         return ret;
626 }
627
628 WL_EXPORT void
629 wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data)
630 {
631         proxy->user_data = user_data;
632 }
633
634 WL_EXPORT void *
635 wl_proxy_get_user_data(struct wl_proxy *proxy)
636 {
637         return proxy->user_data;
638 }
639
640 WL_EXPORT uint32_t
641 wl_proxy_get_id(struct wl_proxy *proxy)
642 {
643         return proxy->object.id;
644 }
645
646
647 WL_EXPORT void
648 wl_proxy_set_queue(struct wl_proxy *proxy, struct wl_event_queue *queue)
649 {
650         proxy->queue = queue;
651 }
652
653 WL_EXPORT void
654 wl_log_set_handler_client(wl_log_func_t handler)
655 {
656         wl_log_handler = handler;
657 }