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