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