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