debug: Allow WAYLAND_DEBUG=server/client for server/client side only debug
[profile/ivi/wayland.git] / src / wayland-server.c
1 /*
2  * Copyright © 2008 Kristian Høgsberg
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  The copyright holders make no representations
11  * about the suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22
23 #define _GNU_SOURCE
24
25 #include <stdlib.h>
26 #include <stdint.h>
27 #include <stddef.h>
28 #include <stdio.h>
29 #include <stdarg.h>
30 #include <stdbool.h>
31 #include <errno.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <sys/socket.h>
35 #include <sys/un.h>
36 #include <dlfcn.h>
37 #include <assert.h>
38 #include <sys/time.h>
39 #include <fcntl.h>
40 #include <sys/file.h>
41 #include <sys/stat.h>
42 #include <ffi.h>
43
44 #include "wayland-private.h"
45 #include "wayland-server.h"
46 #include "wayland-server-protocol.h"
47 #include "wayland-os.h"
48
49 /* This is the size of the char array in struct sock_addr_un.
50    No Wayland socket can be created with a path longer than this,
51    including the null terminator. */
52 #ifndef UNIX_PATH_MAX
53 #define UNIX_PATH_MAX   108
54 #endif
55
56 #define LOCK_SUFFIX     ".lock"
57 #define LOCK_SUFFIXLEN  5
58
59 struct wl_socket {
60         int fd;
61         int fd_lock;
62         struct sockaddr_un addr;
63         char lock_addr[UNIX_PATH_MAX + LOCK_SUFFIXLEN];
64         struct wl_list link;
65         struct wl_event_source *source;
66 };
67
68 struct wl_client {
69         struct wl_connection *connection;
70         struct wl_event_source *source;
71         struct wl_display *display;
72         struct wl_resource *display_resource;
73         uint32_t id_count;
74         uint32_t mask;
75         struct wl_list link;
76         struct wl_map objects;
77         struct wl_signal destroy_signal;
78         struct ucred ucred;
79         int error;
80 };
81
82 struct wl_display {
83         struct wl_event_loop *loop;
84         int run;
85
86         uint32_t id;
87         uint32_t serial;
88
89         struct wl_list registry_resource_list;
90         struct wl_list global_list;
91         struct wl_list socket_list;
92         struct wl_list client_list;
93 };
94
95 struct wl_global {
96         const struct wl_interface *interface;
97         uint32_t name;
98         void *data;
99         wl_global_bind_func_t bind;
100         struct wl_list link;
101 };
102
103 static int wl_debug = 0;
104
105 static void
106 destroy_client(void *data)
107 {
108         struct wl_client *client = data;
109
110         wl_client_destroy(client);
111 }
112
113 WL_EXPORT void
114 wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...)
115 {
116         struct wl_closure *closure;
117         struct wl_object *object = &resource->object;
118         va_list ap;
119
120         va_start(ap, opcode);
121         closure = wl_closure_vmarshal(object, opcode, ap,
122                                       &object->interface->events[opcode]);
123         va_end(ap);
124
125         if (closure == NULL)
126                 return;
127
128         if (wl_closure_send(closure, resource->client->connection))
129                 wl_event_loop_add_idle(resource->client->display->loop,
130                                        destroy_client, resource->client);
131
132         if (wl_debug)
133                 wl_closure_print(closure, object, true);
134
135         wl_closure_destroy(closure);
136 }
137
138
139 WL_EXPORT void
140 wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
141 {
142         struct wl_closure *closure;
143         struct wl_object *object = &resource->object;
144         va_list ap;
145
146         va_start(ap, opcode);
147         closure = wl_closure_vmarshal(object, opcode, ap,
148                                       &object->interface->events[opcode]);
149         va_end(ap);
150
151         if (closure == NULL)
152                 return;
153
154         if (wl_closure_queue(closure, resource->client->connection))
155                 wl_event_loop_add_idle(resource->client->display->loop,
156                                        destroy_client, resource->client);
157
158         if (wl_debug)
159                 wl_closure_print(closure, object, true);
160
161         wl_closure_destroy(closure);
162 }
163
164 WL_EXPORT void
165 wl_resource_post_error(struct wl_resource *resource,
166                        uint32_t code, const char *msg, ...)
167 {
168         struct wl_client *client = resource->client;
169         char buffer[128];
170         va_list ap;
171
172         va_start(ap, msg);
173         vsnprintf(buffer, sizeof buffer, msg, ap);
174         va_end(ap);
175
176         client->error = 1;
177
178         /*
179          * When a client aborts, its resources are destroyed in id order,
180          * which means the display resource is destroyed first. If destruction
181          * of any later resources results in a protocol error, we end up here
182          * with a NULL display_resource. Do not try to send errors to an
183          * already dead client.
184          */
185         if (!client->display_resource)
186                 return;
187
188         wl_resource_post_event(client->display_resource,
189                                WL_DISPLAY_ERROR, resource, code, buffer);
190 }
191
192 static void
193 deref_new_objects(struct wl_closure *closure)
194 {
195         const char *signature;
196         int i;
197
198         signature = closure->message->signature;
199         for (i = 0; signature[i]; i++) {
200                 switch (signature[i]) {
201                 case 'n':
202                         closure->args[i + 2] = *(uint32_t **) closure->args[i + 2];
203                         closure->types[i] = &ffi_type_uint32;
204                         break;
205                 }
206         }
207 }
208
209 static int
210 wl_client_connection_data(int fd, uint32_t mask, void *data)
211 {
212         struct wl_client *client = data;
213         struct wl_connection *connection = client->connection;
214         struct wl_resource *resource;
215         struct wl_object *object;
216         struct wl_closure *closure;
217         const struct wl_message *message;
218         uint32_t p[2];
219         int opcode, size;
220         int len;
221
222         if (mask & (WL_EVENT_ERROR | WL_EVENT_HANGUP)) {
223                 wl_client_destroy(client);
224                 return 1;
225         }
226
227         if (mask & WL_EVENT_WRITABLE) {
228                 len = wl_connection_flush(connection);
229                 if (len < 0 && errno != EAGAIN) {
230                         wl_client_destroy(client);
231                         return 1;
232                 } else if (len >= 0) {
233                         wl_event_source_fd_update(client->source,
234                                                   WL_EVENT_READABLE);
235                 }
236         }
237
238         len = 0;
239         if (mask & WL_EVENT_READABLE) {
240                 len = wl_connection_read(connection);
241                 if (len < 0 && errno != EAGAIN) {
242                         wl_client_destroy(client);
243                         return 1;
244                 }
245         }
246
247         while ((size_t) len >= sizeof p) {
248                 wl_connection_copy(connection, p, sizeof p);
249                 opcode = p[1] & 0xffff;
250                 size = p[1] >> 16;
251                 if (len < size)
252                         break;
253
254                 resource = wl_map_lookup(&client->objects, p[0]);
255                 if (resource == NULL) {
256                         wl_resource_post_error(client->display_resource,
257                                                WL_DISPLAY_ERROR_INVALID_OBJECT,
258                                                "invalid object %u", p[0]);
259                         break;
260                 }
261
262                 object = &resource->object;
263                 if (opcode >= object->interface->method_count) {
264                         wl_resource_post_error(client->display_resource,
265                                                WL_DISPLAY_ERROR_INVALID_METHOD,
266                                                "invalid method %d, object %s@%u",
267                                                opcode,
268                                                object->interface->name,
269                                                object->id);
270                         break;
271                 }
272
273                 message = &object->interface->methods[opcode];
274                 closure = wl_connection_demarshal(client->connection, size,
275                                                   &client->objects, message);
276                 len -= size;
277
278                 if ((closure == NULL && errno == EINVAL) ||
279                     wl_closure_lookup_objects(closure, &client->objects) < 0) {
280                         wl_resource_post_error(client->display_resource,
281                                                WL_DISPLAY_ERROR_INVALID_METHOD,
282                                                "invalid arguments for %s@%u.%s",
283                                                object->interface->name,
284                                                object->id,
285                                                message->name);
286                         break;
287                 } else if (closure == NULL && errno == ENOMEM) {
288                         wl_resource_post_no_memory(resource);
289                         break;
290                 }
291
292                 if (wl_debug)
293                         wl_closure_print(closure, object, false);
294
295                 deref_new_objects(closure);
296
297                 wl_closure_invoke(closure, object,
298                                   object->implementation[opcode], client);
299
300                 wl_closure_destroy(closure);
301
302                 if (client->error)
303                         break;
304         }
305
306         if (client->error)
307                 wl_client_destroy(client);
308
309         return 1;
310 }
311
312 WL_EXPORT void
313 wl_client_flush(struct wl_client *client)
314 {
315         wl_connection_flush(client->connection);
316 }
317
318 WL_EXPORT struct wl_display *
319 wl_client_get_display(struct wl_client *client)
320 {
321         return client->display;
322 }
323
324 static void
325 bind_display(struct wl_client *client,
326              void *data, uint32_t version, uint32_t id);
327
328 WL_EXPORT struct wl_client *
329 wl_client_create(struct wl_display *display, int fd)
330 {
331         struct wl_client *client;
332         socklen_t len;
333
334         client = malloc(sizeof *client);
335         if (client == NULL)
336                 return NULL;
337
338         memset(client, 0, sizeof *client);
339         client->display = display;
340         client->source = wl_event_loop_add_fd(display->loop, fd,
341                                               WL_EVENT_READABLE,
342                                               wl_client_connection_data, client);
343
344         if (!client->source)
345                 goto err_client;
346
347         len = sizeof client->ucred;
348         if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED,
349                        &client->ucred, &len) < 0)
350                 goto err_source;
351
352         client->connection = wl_connection_create(fd);
353         if (client->connection == NULL)
354                 goto err_source;
355
356         wl_map_init(&client->objects);
357
358         if (wl_map_insert_at(&client->objects, 0, NULL) < 0)
359                 goto err_map;
360
361         wl_signal_init(&client->destroy_signal);
362         bind_display(client, display, 1, 1);
363
364         if (!client->display_resource)
365                 goto err_map;
366
367         wl_list_insert(display->client_list.prev, &client->link);
368
369         return client;
370
371 err_map:
372         wl_map_release(&client->objects);
373         wl_connection_destroy(client->connection);
374 err_source:
375         wl_event_source_remove(client->source);
376 err_client:
377         free(client);
378         return NULL;
379 }
380
381 WL_EXPORT void
382 wl_client_get_credentials(struct wl_client *client,
383                           pid_t *pid, uid_t *uid, gid_t *gid)
384 {
385         if (pid)
386                 *pid = client->ucred.pid;
387         if (uid)
388                 *uid = client->ucred.uid;
389         if (gid)
390                 *gid = client->ucred.gid;
391 }
392
393 WL_EXPORT uint32_t
394 wl_client_add_resource(struct wl_client *client,
395                        struct wl_resource *resource)
396 {
397         if (resource->object.id == 0) {
398                 resource->object.id =
399                         wl_map_insert_new(&client->objects,
400                                           WL_MAP_SERVER_SIDE, resource);
401         } else if (wl_map_insert_at(&client->objects,
402                                   resource->object.id, resource) < 0) {
403                 wl_resource_post_error(client->display_resource,
404                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
405                                        "invalid new id %d",
406                                        resource->object.id);
407                 return 0;
408         }
409
410         resource->client = client;
411         wl_signal_init(&resource->destroy_signal);
412
413         return resource->object.id;
414 }
415
416 WL_EXPORT struct wl_resource *
417 wl_client_get_object(struct wl_client *client, uint32_t id)
418 {
419         return wl_map_lookup(&client->objects, id);
420 }
421
422 WL_EXPORT void
423 wl_resource_post_no_memory(struct wl_resource *resource)
424 {
425         wl_resource_post_error(resource->client->display_resource,
426                                WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
427 }
428
429 static void
430 destroy_resource(void *element, void *data)
431 {
432         struct wl_resource *resource = element;
433
434         wl_signal_emit(&resource->destroy_signal, resource);
435
436         if (resource->destroy)
437                 resource->destroy(resource);
438 }
439
440 WL_EXPORT void
441 wl_resource_destroy(struct wl_resource *resource)
442 {
443         struct wl_client *client = resource->client;
444         uint32_t id;
445
446         id = resource->object.id;
447         destroy_resource(resource, NULL);
448
449         if (id < WL_SERVER_ID_START) {
450                 if (client->display_resource) {
451                         wl_resource_queue_event(client->display_resource,
452                                                 WL_DISPLAY_DELETE_ID, id);
453                 }
454                 wl_map_insert_at(&client->objects, id, NULL);
455         } else {
456                 wl_map_remove(&client->objects, id);
457         }
458 }
459
460 WL_EXPORT void
461 wl_client_add_destroy_listener(struct wl_client *client,
462                                struct wl_listener *listener)
463 {
464         wl_signal_add(&client->destroy_signal, listener);
465 }
466
467 WL_EXPORT struct wl_listener *
468 wl_client_get_destroy_listener(struct wl_client *client,
469                                wl_notify_func_t notify)
470 {
471         return wl_signal_get(&client->destroy_signal, notify);
472 }
473
474 WL_EXPORT void
475 wl_client_destroy(struct wl_client *client)
476 {
477         uint32_t serial = 0;
478         
479         wl_log("disconnect from client %p\n", client);
480
481         wl_signal_emit(&client->destroy_signal, client);
482
483         wl_client_flush(client);
484         wl_map_for_each(&client->objects, destroy_resource, &serial);
485         wl_map_release(&client->objects);
486         wl_event_source_remove(client->source);
487         wl_connection_destroy(client->connection);
488         wl_list_remove(&client->link);
489         free(client);
490 }
491
492 static void
493 lose_pointer_focus(struct wl_listener *listener, void *data)
494 {
495         struct wl_pointer *pointer =
496                 container_of(listener, struct wl_pointer, focus_listener);
497
498         pointer->focus_resource = NULL;
499 }
500
501 static void
502 lose_keyboard_focus(struct wl_listener *listener, void *data)
503 {
504         struct wl_keyboard *keyboard =
505                 container_of(listener, struct wl_keyboard, focus_listener);
506
507         keyboard->focus_resource = NULL;
508 }
509
510 static void
511 lose_touch_focus(struct wl_listener *listener, void *data)
512 {
513         struct wl_touch *touch =
514                 container_of(listener, struct wl_touch, focus_listener);
515
516         touch->focus_resource = NULL;
517 }
518
519 static void
520 default_grab_focus(struct wl_pointer_grab *grab,
521                    struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y)
522 {
523         struct wl_pointer *pointer = grab->pointer;
524
525         if (pointer->button_count > 0)
526                 return;
527
528         wl_pointer_set_focus(pointer, surface, x, y);
529 }
530
531 static void
532 default_grab_motion(struct wl_pointer_grab *grab,
533                     uint32_t time, wl_fixed_t x, wl_fixed_t y)
534 {
535         struct wl_resource *resource;
536
537         resource = grab->pointer->focus_resource;
538         if (resource)
539                 wl_pointer_send_motion(resource, time, x, y);
540 }
541
542 static void
543 default_grab_button(struct wl_pointer_grab *grab,
544                     uint32_t time, uint32_t button, uint32_t state_w)
545 {
546         struct wl_pointer *pointer = grab->pointer;
547         struct wl_resource *resource;
548         uint32_t serial;
549         enum wl_pointer_button_state state = state_w;
550
551         resource = pointer->focus_resource;
552         if (resource) {
553                 serial = wl_display_next_serial(resource->client->display);
554                 wl_pointer_send_button(resource, serial, time, button, state_w);
555         }
556
557         if (pointer->button_count == 0 &&
558             state == WL_POINTER_BUTTON_STATE_RELEASED)
559                 wl_pointer_set_focus(pointer, pointer->current,
560                                      pointer->current_x, pointer->current_y);
561 }
562
563 static const struct wl_pointer_grab_interface
564                                 default_pointer_grab_interface = {
565         default_grab_focus,
566         default_grab_motion,
567         default_grab_button
568 };
569
570 static void default_grab_touch_down(struct wl_touch_grab *grab,
571                 uint32_t time,
572                 int touch_id,
573                 wl_fixed_t sx,
574                 wl_fixed_t sy)
575 {
576         struct wl_touch *touch = grab->touch;
577         uint32_t serial;
578
579         if (touch->focus_resource && touch->focus) {
580                 serial = wl_display_next_serial(touch->focus_resource->client->display);
581                 wl_touch_send_down(touch->focus_resource, serial, time,
582                                 &touch->focus->resource, touch_id, sx, sy);
583         }
584 }
585
586 static void default_grab_touch_up(struct wl_touch_grab *grab,
587                 uint32_t time,
588                 int touch_id)
589 {
590         struct wl_touch *touch = grab->touch;
591         uint32_t serial;
592
593         if (touch->focus_resource) {
594                 serial = wl_display_next_serial(touch->focus_resource->client->display);
595                 wl_touch_send_up(touch->focus_resource, serial, time, touch_id);
596         }
597 }
598
599 static void default_grab_touch_motion(struct wl_touch_grab *grab,
600                 uint32_t time,
601                 int touch_id,
602                 wl_fixed_t sx,
603                 wl_fixed_t sy)
604 {
605         struct wl_touch *touch = grab->touch;
606
607         if (touch->focus_resource) {
608                 wl_touch_send_motion(touch->focus_resource, time,
609                                 touch_id, sx, sy);
610         }
611 }
612
613 static const struct wl_touch_grab_interface default_touch_grab_interface = {
614         default_grab_touch_down,
615         default_grab_touch_up,
616         default_grab_touch_motion
617 };
618
619 static void
620 default_grab_key(struct wl_keyboard_grab *grab,
621                  uint32_t time, uint32_t key, uint32_t state)
622 {
623         struct wl_keyboard *keyboard = grab->keyboard;
624         struct wl_resource *resource;
625         uint32_t serial;
626
627         resource = keyboard->focus_resource;
628         if (resource) {
629                 serial = wl_display_next_serial(resource->client->display);
630                 wl_keyboard_send_key(resource, serial, time, key, state);
631         }
632 }
633
634 static struct wl_resource *
635 find_resource_for_surface(struct wl_list *list, struct wl_surface *surface)
636 {
637         struct wl_resource *r;
638
639         if (!surface)
640                 return NULL;
641
642         wl_list_for_each(r, list, link) {
643                 if (r->client == surface->resource.client)
644                         return r;
645         }
646
647         return NULL;
648 }
649
650 static void
651 default_grab_modifiers(struct wl_keyboard_grab *grab, uint32_t serial,
652                        uint32_t mods_depressed, uint32_t mods_latched,
653                        uint32_t mods_locked, uint32_t group)
654 {
655         struct wl_keyboard *keyboard = grab->keyboard;
656         struct wl_pointer *pointer = keyboard->seat->pointer;
657         struct wl_resource *resource, *pr;
658
659         resource = keyboard->focus_resource;
660         if (!resource)
661                 return;
662
663         wl_keyboard_send_modifiers(resource, serial, mods_depressed,
664                                    mods_latched, mods_locked, group);
665
666         if (pointer && pointer->focus && pointer->focus != keyboard->focus) {
667                 pr = find_resource_for_surface(&keyboard->resource_list,
668                                                pointer->focus);
669                 if (pr) {
670                         wl_keyboard_send_modifiers(pr,
671                                                    serial,
672                                                    keyboard->modifiers.mods_depressed,
673                                                    keyboard->modifiers.mods_latched,
674                                                    keyboard->modifiers.mods_locked,
675                                                    keyboard->modifiers.group);
676                 }
677         }
678 }
679
680 static const struct wl_keyboard_grab_interface
681                                 default_keyboard_grab_interface = {
682         default_grab_key,
683         default_grab_modifiers,
684 };
685
686 WL_EXPORT void
687 wl_pointer_init(struct wl_pointer *pointer)
688 {
689         memset(pointer, 0, sizeof *pointer);
690         wl_list_init(&pointer->resource_list);
691         pointer->focus_listener.notify = lose_pointer_focus;
692         pointer->default_grab.interface = &default_pointer_grab_interface;
693         pointer->default_grab.pointer = pointer;
694         pointer->grab = &pointer->default_grab;
695         wl_signal_init(&pointer->focus_signal);
696
697         /* FIXME: Pick better co-ords. */
698         pointer->x = wl_fixed_from_int(100);
699         pointer->y = wl_fixed_from_int(100);
700 }
701
702 WL_EXPORT void
703 wl_pointer_release(struct wl_pointer *pointer)
704 {
705         /* XXX: What about pointer->resource_list? */
706         if (pointer->focus_resource)
707                 wl_list_remove(&pointer->focus_listener.link);
708 }
709
710 WL_EXPORT void
711 wl_keyboard_init(struct wl_keyboard *keyboard)
712 {
713         memset(keyboard, 0, sizeof *keyboard);
714         wl_list_init(&keyboard->resource_list);
715         wl_array_init(&keyboard->keys);
716         keyboard->focus_listener.notify = lose_keyboard_focus;
717         keyboard->default_grab.interface = &default_keyboard_grab_interface;
718         keyboard->default_grab.keyboard = keyboard;
719         keyboard->grab = &keyboard->default_grab;
720         wl_signal_init(&keyboard->focus_signal);
721 }
722
723 WL_EXPORT void
724 wl_keyboard_release(struct wl_keyboard *keyboard)
725 {
726         /* XXX: What about keyboard->resource_list? */
727         if (keyboard->focus_resource)
728                 wl_list_remove(&keyboard->focus_listener.link);
729         wl_array_release(&keyboard->keys);
730 }
731
732 WL_EXPORT void
733 wl_touch_init(struct wl_touch *touch)
734 {
735         memset(touch, 0, sizeof *touch);
736         wl_list_init(&touch->resource_list);
737         touch->focus_listener.notify = lose_touch_focus;
738         touch->default_grab.interface = &default_touch_grab_interface;
739         touch->default_grab.touch = touch;
740         touch->grab = &touch->default_grab;
741         wl_signal_init(&touch->focus_signal);
742 }
743
744 WL_EXPORT void
745 wl_touch_release(struct wl_touch *touch)
746 {
747         /* XXX: What about touch->resource_list? */
748         if (touch->focus_resource)
749                 wl_list_remove(&touch->focus_listener.link);
750 }
751
752 WL_EXPORT void
753 wl_seat_init(struct wl_seat *seat)
754 {
755         memset(seat, 0, sizeof *seat);
756
757         wl_signal_init(&seat->destroy_signal);
758
759         seat->selection_data_source = NULL;
760         wl_list_init(&seat->base_resource_list);
761         wl_signal_init(&seat->selection_signal);
762         wl_list_init(&seat->drag_resource_list);
763         wl_signal_init(&seat->drag_icon_signal);
764 }
765
766 WL_EXPORT void
767 wl_seat_release(struct wl_seat *seat)
768 {
769         wl_signal_emit(&seat->destroy_signal, seat);
770
771         if (seat->pointer)
772                 wl_pointer_release(seat->pointer);
773         if (seat->keyboard)
774                 wl_keyboard_release(seat->keyboard);
775         if (seat->touch)
776                 wl_touch_release(seat->touch);
777 }
778
779 static void
780 seat_send_updated_caps(struct wl_seat *seat)
781 {
782         struct wl_resource *r;
783         enum wl_seat_capability caps = 0;
784
785         if (seat->pointer)
786                 caps |= WL_SEAT_CAPABILITY_POINTER;
787         if (seat->keyboard)
788                 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
789         if (seat->touch)
790                 caps |= WL_SEAT_CAPABILITY_TOUCH;
791
792         wl_list_for_each(r, &seat->base_resource_list, link)
793                 wl_seat_send_capabilities(r, caps);
794 }
795
796 WL_EXPORT void
797 wl_seat_set_pointer(struct wl_seat *seat, struct wl_pointer *pointer)
798 {
799         if (pointer && (seat->pointer || pointer->seat))
800                 return; /* XXX: error? */
801         if (!pointer && !seat->pointer)
802                 return;
803
804         seat->pointer = pointer;
805         if (pointer)
806                 pointer->seat = seat;
807
808         seat_send_updated_caps(seat);
809 }
810
811 WL_EXPORT void
812 wl_seat_set_keyboard(struct wl_seat *seat, struct wl_keyboard *keyboard)
813 {
814         if (keyboard && (seat->keyboard || keyboard->seat))
815                 return; /* XXX: error? */
816         if (!keyboard && !seat->keyboard)
817                 return;
818
819         seat->keyboard = keyboard;
820         if (keyboard)
821                 keyboard->seat = seat;
822
823         seat_send_updated_caps(seat);
824 }
825
826 WL_EXPORT void
827 wl_seat_set_touch(struct wl_seat *seat, struct wl_touch *touch)
828 {
829         if (touch && (seat->touch || touch->seat))
830                 return; /* XXX: error? */
831         if (!touch && !seat->touch)
832                 return;
833
834         seat->touch = touch;
835         if (touch)
836                 touch->seat = seat;
837
838         seat_send_updated_caps(seat);
839 }
840
841 WL_EXPORT void
842 wl_pointer_set_focus(struct wl_pointer *pointer, struct wl_surface *surface,
843                      wl_fixed_t sx, wl_fixed_t sy)
844 {
845         struct wl_keyboard *kbd = pointer->seat->keyboard;
846         struct wl_resource *resource, *kr;
847         uint32_t serial;
848
849         resource = pointer->focus_resource;
850         if (resource && pointer->focus != surface) {
851                 serial = wl_display_next_serial(resource->client->display);
852                 wl_pointer_send_leave(resource, serial,
853                                       &pointer->focus->resource);
854                 wl_list_remove(&pointer->focus_listener.link);
855         }
856
857         resource = find_resource_for_surface(&pointer->resource_list,
858                                              surface);
859         if (resource &&
860             (pointer->focus != surface ||
861              pointer->focus_resource != resource)) {
862                 serial = wl_display_next_serial(resource->client->display);
863                 if (kbd) {
864                         kr = find_resource_for_surface(&kbd->resource_list,
865                                                        surface);
866                         if (kr) {
867                                 wl_keyboard_send_modifiers(kr,
868                                                            serial,
869                                                            kbd->modifiers.mods_depressed,
870                                                            kbd->modifiers.mods_latched,
871                                                            kbd->modifiers.mods_locked,
872                                                            kbd->modifiers.group);
873                         }
874                 }
875                 wl_pointer_send_enter(resource, serial, &surface->resource,
876                                       sx, sy);
877                 wl_signal_add(&resource->destroy_signal,
878                               &pointer->focus_listener);
879                 pointer->focus_serial = serial;
880         }
881
882         pointer->focus_resource = resource;
883         pointer->focus = surface;
884         pointer->default_grab.focus = surface;
885         wl_signal_emit(&pointer->focus_signal, pointer);
886 }
887
888 WL_EXPORT void
889 wl_keyboard_set_focus(struct wl_keyboard *keyboard, struct wl_surface *surface)
890 {
891         struct wl_resource *resource;
892         uint32_t serial;
893
894         if (keyboard->focus_resource && keyboard->focus != surface) {
895                 resource = keyboard->focus_resource;
896                 serial = wl_display_next_serial(resource->client->display);
897                 wl_keyboard_send_leave(resource, serial,
898                                        &keyboard->focus->resource);
899                 wl_list_remove(&keyboard->focus_listener.link);
900         }
901
902         resource = find_resource_for_surface(&keyboard->resource_list,
903                                              surface);
904         if (resource &&
905             (keyboard->focus != surface ||
906              keyboard->focus_resource != resource)) {
907                 serial = wl_display_next_serial(resource->client->display);
908                 wl_keyboard_send_modifiers(resource, serial,
909                                            keyboard->modifiers.mods_depressed,
910                                            keyboard->modifiers.mods_latched,
911                                            keyboard->modifiers.mods_locked,
912                                            keyboard->modifiers.group);
913                 wl_keyboard_send_enter(resource, serial, &surface->resource,
914                                        &keyboard->keys);
915                 wl_signal_add(&resource->destroy_signal,
916                               &keyboard->focus_listener);
917                 keyboard->focus_serial = serial;
918         }
919
920         keyboard->focus_resource = resource;
921         keyboard->focus = surface;
922         wl_signal_emit(&keyboard->focus_signal, keyboard);
923 }
924
925 WL_EXPORT void
926 wl_keyboard_start_grab(struct wl_keyboard *keyboard,
927                        struct wl_keyboard_grab *grab)
928 {
929         keyboard->grab = grab;
930         grab->keyboard = keyboard;
931
932         /* XXX focus? */
933 }
934
935 WL_EXPORT void
936 wl_keyboard_end_grab(struct wl_keyboard *keyboard)
937 {
938         keyboard->grab = &keyboard->default_grab;
939 }
940
941 WL_EXPORT void
942 wl_pointer_start_grab(struct wl_pointer *pointer, struct wl_pointer_grab *grab)
943 {
944         const struct wl_pointer_grab_interface *interface;
945
946         pointer->grab = grab;
947         interface = pointer->grab->interface;
948         grab->pointer = pointer;
949
950         if (pointer->current)
951                 interface->focus(pointer->grab, pointer->current,
952                                  pointer->current_x, pointer->current_y);
953 }
954
955 WL_EXPORT void
956 wl_pointer_end_grab(struct wl_pointer *pointer)
957 {
958         const struct wl_pointer_grab_interface *interface;
959
960         pointer->grab = &pointer->default_grab;
961         interface = pointer->grab->interface;
962         interface->focus(pointer->grab, pointer->current,
963                          pointer->current_x, pointer->current_y);
964 }
965
966 WL_EXPORT void
967 wl_touch_start_grab(struct wl_touch *touch, struct wl_touch_grab *grab)
968 {
969         touch->grab = grab;
970         grab->touch = touch;
971 }
972
973 WL_EXPORT void
974 wl_touch_end_grab(struct wl_touch *touch)
975 {
976         touch->grab = &touch->default_grab;
977 }
978
979 static void
980 registry_bind(struct wl_client *client,
981               struct wl_resource *resource, uint32_t name,
982               const char *interface, uint32_t version, uint32_t id)
983 {
984         struct wl_global *global;
985         struct wl_display *display = resource->data;
986
987         wl_list_for_each(global, &display->global_list, link)
988                 if (global->name == name)
989                         break;
990
991         if (&global->link == &display->global_list)
992                 wl_resource_post_error(resource,
993                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
994                                        "invalid global %d", name);
995         else
996                 global->bind(client, global->data, version, id);
997 }
998
999 static const struct wl_registry_interface registry_interface = {
1000         registry_bind
1001 };
1002
1003 static void
1004 display_sync(struct wl_client *client,
1005              struct wl_resource *resource, uint32_t id)
1006 {
1007         struct wl_resource *callback;
1008         uint32_t serial;
1009
1010         callback = wl_client_add_object(client,
1011                                         &wl_callback_interface, NULL, id, NULL);
1012         serial = wl_display_get_serial(client->display);
1013         wl_callback_send_done(callback, serial);
1014         wl_resource_destroy(callback);
1015 }
1016
1017 static void
1018 unbind_resource(struct wl_resource *resource)
1019 {
1020         wl_list_remove(&resource->link);
1021         free(resource);
1022 }
1023
1024 static void
1025 display_get_registry(struct wl_client *client,
1026                      struct wl_resource *resource, uint32_t id)
1027 {
1028         struct wl_display *display = resource->data;
1029         struct wl_resource *registry_resource;
1030         struct wl_global *global;
1031
1032         registry_resource =
1033                 wl_client_add_object(client, &wl_registry_interface,
1034                                      &registry_interface, id, display);
1035         registry_resource->destroy = unbind_resource;
1036
1037         wl_list_insert(&display->registry_resource_list,
1038                        &registry_resource->link);
1039
1040         wl_list_for_each(global, &display->global_list, link)
1041                 wl_resource_post_event(registry_resource,
1042                                        WL_REGISTRY_GLOBAL,
1043                                        global->name,
1044                                        global->interface->name,
1045                                        global->interface->version);
1046 }
1047
1048 static const struct wl_display_interface display_interface = {
1049         display_sync,
1050         display_get_registry
1051 };
1052
1053 static void
1054 destroy_client_display_resource(struct wl_resource *resource)
1055 {
1056         resource->client->display_resource = NULL;
1057         free(resource);
1058 }
1059
1060 static void
1061 bind_display(struct wl_client *client,
1062              void *data, uint32_t version, uint32_t id)
1063 {
1064         struct wl_display *display = data;
1065
1066         client->display_resource =
1067                 wl_client_add_object(client, &wl_display_interface,
1068                                      &display_interface, id, display);
1069
1070         if(client->display_resource)
1071                 client->display_resource->destroy = destroy_client_display_resource;
1072 }
1073
1074 WL_EXPORT struct wl_display *
1075 wl_display_create(void)
1076 {
1077         struct wl_display *display;
1078         const char *debug;
1079
1080         debug = getenv("WAYLAND_DEBUG");
1081         if (debug && (strstr(debug, "server") || strstr(debug, "1")))
1082                 wl_debug = 1;
1083
1084         display = malloc(sizeof *display);
1085         if (display == NULL)
1086                 return NULL;
1087
1088         display->loop = wl_event_loop_create();
1089         if (display->loop == NULL) {
1090                 free(display);
1091                 return NULL;
1092         }
1093
1094         wl_list_init(&display->global_list);
1095         wl_list_init(&display->socket_list);
1096         wl_list_init(&display->client_list);
1097         wl_list_init(&display->registry_resource_list);
1098
1099         display->id = 1;
1100         display->serial = 0;
1101
1102         if (!wl_display_add_global(display, &wl_display_interface, 
1103                                    display, bind_display)) {
1104                 wl_event_loop_destroy(display->loop);
1105                 free(display);
1106                 return NULL;
1107         }
1108
1109         return display;
1110 }
1111
1112 WL_EXPORT void
1113 wl_display_destroy(struct wl_display *display)
1114 {
1115         struct wl_socket *s, *next;
1116         struct wl_global *global, *gnext;
1117
1118         wl_list_for_each_safe(s, next, &display->socket_list, link) {
1119                 wl_event_source_remove(s->source);
1120                 unlink(s->addr.sun_path);
1121                 close(s->fd);
1122                 unlink(s->lock_addr);
1123                 close(s->fd_lock);
1124                 free(s);
1125         }
1126         wl_event_loop_destroy(display->loop);
1127
1128         wl_list_for_each_safe(global, gnext, &display->global_list, link)
1129                 free(global);
1130
1131         free(display);
1132 }
1133
1134 WL_EXPORT struct wl_global *
1135 wl_display_add_global(struct wl_display *display,
1136                       const struct wl_interface *interface,
1137                       void *data, wl_global_bind_func_t bind)
1138 {
1139         struct wl_global *global;
1140         struct wl_resource *resource;
1141
1142         global = malloc(sizeof *global);
1143         if (global == NULL)
1144                 return NULL;
1145
1146         global->name = display->id++;
1147         global->interface = interface;
1148         global->data = data;
1149         global->bind = bind;
1150         wl_list_insert(display->global_list.prev, &global->link);
1151
1152         wl_list_for_each(resource, &display->registry_resource_list, link)
1153                 wl_resource_post_event(resource,
1154                                        WL_REGISTRY_GLOBAL,
1155                                        global->name,
1156                                        global->interface->name,
1157                                        global->interface->version);
1158
1159         return global;
1160 }
1161
1162 WL_EXPORT void
1163 wl_display_remove_global(struct wl_display *display, struct wl_global *global)
1164 {
1165         struct wl_resource *resource;
1166
1167         wl_list_for_each(resource, &display->registry_resource_list, link)
1168                 wl_resource_post_event(resource, WL_REGISTRY_GLOBAL_REMOVE,
1169                                        global->name);
1170         wl_list_remove(&global->link);
1171         free(global);
1172 }
1173
1174 WL_EXPORT uint32_t
1175 wl_display_get_serial(struct wl_display *display)
1176 {
1177         return display->serial;
1178 }
1179
1180 WL_EXPORT uint32_t
1181 wl_display_next_serial(struct wl_display *display)
1182 {
1183         display->serial++;
1184
1185         return display->serial;
1186 }
1187
1188 WL_EXPORT struct wl_event_loop *
1189 wl_display_get_event_loop(struct wl_display *display)
1190 {
1191         return display->loop;
1192 }
1193
1194 WL_EXPORT void
1195 wl_display_terminate(struct wl_display *display)
1196 {
1197         display->run = 0;
1198 }
1199
1200 WL_EXPORT void
1201 wl_display_run(struct wl_display *display)
1202 {
1203         display->run = 1;
1204
1205         while (display->run) {
1206                 wl_display_flush_clients(display);
1207                 wl_event_loop_dispatch(display->loop, -1);
1208         }
1209 }
1210
1211 WL_EXPORT void
1212 wl_display_flush_clients(struct wl_display *display)
1213 {
1214         struct wl_client *client, *next;
1215         int ret;
1216
1217         wl_list_for_each_safe(client, next, &display->client_list, link) {
1218                 ret = wl_connection_flush(client->connection);
1219                 if (ret < 0 && errno == EAGAIN) {
1220                         wl_event_source_fd_update(client->source,
1221                                                   WL_EVENT_WRITABLE |
1222                                                   WL_EVENT_READABLE);
1223                 } else if (ret < 0) {
1224                         wl_client_destroy(client);
1225                 }
1226         }
1227 }
1228
1229 static int
1230 socket_data(int fd, uint32_t mask, void *data)
1231 {
1232         struct wl_display *display = data;
1233         struct sockaddr_un name;
1234         socklen_t length;
1235         int client_fd;
1236
1237         length = sizeof name;
1238         client_fd = wl_os_accept_cloexec(fd, (struct sockaddr *) &name,
1239                                          &length);
1240         if (client_fd < 0)
1241                 wl_log("failed to accept: %m\n");
1242         else
1243                 if (!wl_client_create(display, client_fd))
1244                         close(client_fd);
1245
1246         return 1;
1247 }
1248
1249 static int
1250 get_socket_lock(struct wl_socket *socket)
1251 {
1252         struct stat socket_stat;
1253         int fd_lock;
1254
1255         snprintf(socket->lock_addr, sizeof socket->lock_addr,
1256                  "%s%s", socket->addr.sun_path, LOCK_SUFFIX);
1257
1258         fd_lock = open(socket->lock_addr, O_CREAT | O_CLOEXEC,
1259                        (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
1260
1261         if (fd_lock < 0) {
1262                 wl_log("unable to open lockfile %s check permissions\n",
1263                         socket->lock_addr);
1264                 return -1;
1265         }
1266
1267         if (flock(fd_lock, LOCK_EX | LOCK_NB) < 0) {
1268                 wl_log("unable to lock lockfile %s, maybe another compositor is running\n",
1269                         socket->lock_addr);
1270                 close(fd_lock);
1271                 return -1;
1272         }
1273
1274         if (stat(socket->addr.sun_path, &socket_stat) < 0 ) {
1275                 if (errno != ENOENT) {
1276                         wl_log("did not manage to stat file %s\n",
1277                                 socket->addr.sun_path);
1278                         close(fd_lock);
1279                         return -1;
1280                 }
1281         } else if (socket_stat.st_mode & S_IWUSR ||
1282                    socket_stat.st_mode & S_IWGRP) {
1283                 unlink(socket->addr.sun_path);
1284         }
1285
1286         return fd_lock;
1287 }
1288
1289 WL_EXPORT int
1290 wl_display_add_socket(struct wl_display *display, const char *name)
1291 {
1292         struct wl_socket *s;
1293         socklen_t size;
1294         int name_size;
1295         const char *runtime_dir;
1296
1297         runtime_dir = getenv("XDG_RUNTIME_DIR");
1298         if (!runtime_dir) {
1299                 wl_log("error: XDG_RUNTIME_DIR not set in the environment\n");
1300
1301                 /* to prevent programs reporting
1302                  * "failed to add socket: Success" */
1303                 errno = ENOENT;
1304                 return -1;
1305         }
1306
1307         s = malloc(sizeof *s);
1308         if (s == NULL)
1309                 return -1;
1310
1311         s->fd = wl_os_socket_cloexec(PF_LOCAL, SOCK_STREAM, 0);
1312         if (s->fd < 0) {
1313                 free(s);
1314                 return -1;
1315         }
1316
1317         if (name == NULL)
1318                 name = getenv("WAYLAND_DISPLAY");
1319         if (name == NULL)
1320                 name = "wayland-0";
1321
1322         memset(&s->addr, 0, sizeof s->addr);
1323         s->addr.sun_family = AF_LOCAL;
1324         name_size = snprintf(s->addr.sun_path, sizeof s->addr.sun_path,
1325                              "%s/%s", runtime_dir, name) + 1;
1326
1327         assert(name_size > 0);
1328         if (name_size > (int)sizeof s->addr.sun_path) {
1329                 wl_log("error: socket path \"%s/%s\" plus null terminator"
1330                        " exceeds 108 bytes\n", runtime_dir, name);
1331                 close(s->fd);
1332                 free(s);
1333                 /* to prevent programs reporting
1334                  * "failed to add socket: Success" */
1335                 errno = ENAMETOOLONG;
1336                 return -1;
1337         };
1338
1339         wl_log("using socket %s\n", s->addr.sun_path);
1340
1341         s->fd_lock = get_socket_lock(s);
1342         if (s->fd_lock < 0) {
1343                 close(s->fd);
1344                 free(s);
1345                 return -1;
1346         }
1347
1348         size = offsetof (struct sockaddr_un, sun_path) + name_size;
1349         if (bind(s->fd, (struct sockaddr *) &s->addr, size) < 0) {
1350                 wl_log("bind() failed with error: %m\n");
1351                 close(s->fd);
1352                 unlink(s->lock_addr);
1353                 close(s->fd_lock);
1354                 free(s);
1355                 return -1;
1356         }
1357
1358         if (listen(s->fd, 1) < 0) {
1359                 wl_log("listen() failed with error: %m\n");
1360                 unlink(s->addr.sun_path);
1361                 close(s->fd);
1362                 unlink(s->lock_addr);
1363                 close(s->fd_lock);
1364                 free(s);
1365                 return -1;
1366         }
1367
1368         s->source = wl_event_loop_add_fd(display->loop, s->fd,
1369                                          WL_EVENT_READABLE,
1370                                          socket_data, display);
1371         if (s->source == NULL) {
1372                 unlink(s->addr.sun_path);
1373                 close(s->fd);
1374                 unlink(s->lock_addr);
1375                 close(s->fd_lock);
1376                 free(s);
1377                 return -1;
1378         }
1379         wl_list_insert(display->socket_list.prev, &s->link);
1380
1381         return 0;
1382 }
1383
1384 WL_EXPORT struct wl_resource *
1385 wl_client_add_object(struct wl_client *client,
1386                      const struct wl_interface *interface,
1387                      const void *implementation,
1388                      uint32_t id, void *data)
1389 {
1390         struct wl_resource *resource;
1391
1392         resource = malloc(sizeof *resource);
1393         if (resource == NULL) {
1394                 wl_resource_post_no_memory(client->display_resource);
1395                 return NULL;
1396         }
1397
1398         resource->object.interface = interface;
1399         resource->object.implementation = implementation;
1400         resource->object.id = id;
1401         resource->client = client;
1402         resource->data = data;
1403         resource->destroy = (void *) free;
1404         wl_signal_init(&resource->destroy_signal);
1405
1406         if (wl_map_insert_at(&client->objects, resource->object.id, resource) < 0) {
1407                 wl_resource_post_error(client->display_resource,
1408                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
1409                                        "invalid new id %d",
1410                                        resource->object.id);
1411                 free(resource);
1412                 return NULL;
1413         }
1414
1415         return resource;
1416 }
1417
1418 WL_EXPORT struct wl_resource *
1419 wl_client_new_object(struct wl_client *client,
1420                      const struct wl_interface *interface,
1421                      const void *implementation, void *data)
1422 {
1423         uint32_t id;
1424
1425         id = wl_map_insert_new(&client->objects, WL_MAP_SERVER_SIDE, NULL);
1426         return wl_client_add_object(client,
1427                                     interface, implementation, id, data);
1428
1429 }
1430
1431 WL_EXPORT void
1432 wl_log_set_handler_server(wl_log_func_t handler)
1433 {
1434         wl_log_handler = handler;
1435 }