6a8cbcb4487311b514331b6525df9703f70ae9ae
[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
48 struct wl_socket {
49         int fd;
50         int fd_lock;
51         struct sockaddr_un addr;
52         char lock_addr[113];
53         struct wl_list link;
54         struct wl_event_source *source;
55 };
56
57 struct wl_client {
58         struct wl_connection *connection;
59         struct wl_event_source *source;
60         struct wl_display *display;
61         struct wl_resource *display_resource;
62         uint32_t id_count;
63         uint32_t mask;
64         struct wl_list link;
65         struct wl_map objects;
66         struct ucred ucred;
67         int error;
68 };
69
70 struct wl_display {
71         struct wl_event_loop *loop;
72         int run;
73
74         uint32_t id;
75
76         struct wl_list global_list;
77         struct wl_list socket_list;
78         struct wl_list client_list;
79 };
80
81 struct wl_global {
82         const struct wl_interface *interface;
83         uint32_t name;
84         void *data;
85         wl_global_bind_func_t bind;
86         struct wl_list link;
87 };
88
89 static int wl_debug = 0;
90
91 static void
92 destroy_client(void *data)
93 {
94         struct wl_client *client = data;
95
96         wl_client_destroy(client);
97 }
98
99 WL_EXPORT void
100 wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...)
101 {
102         struct wl_closure *closure;
103         struct wl_object *object = &resource->object;
104         va_list ap;
105
106         va_start(ap, opcode);
107         closure = wl_connection_vmarshal(resource->client->connection,
108                                          object, opcode, ap,
109                                          &object->interface->events[opcode]);
110         va_end(ap);
111
112         if (closure == NULL)
113                 return;
114
115         if (wl_closure_send(closure, resource->client->connection))
116                 wl_event_loop_add_idle(resource->client->display->loop,
117                                        destroy_client, resource->client);
118
119         if (wl_debug)
120                 wl_closure_print(closure, object, true);
121
122         wl_closure_destroy(closure);
123 }
124
125
126 WL_EXPORT void
127 wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
128 {
129         struct wl_closure *closure;
130         struct wl_object *object = &resource->object;
131         va_list ap;
132
133         va_start(ap, opcode);
134         closure = wl_connection_vmarshal(resource->client->connection,
135                                          object, opcode, ap,
136                                          &object->interface->events[opcode]);
137         va_end(ap);
138
139         if (closure == NULL)
140                 return;
141
142         if (wl_closure_queue(closure, resource->client->connection))
143                 wl_event_loop_add_idle(resource->client->display->loop,
144                                        destroy_client, resource->client);
145
146         if (wl_debug)
147                 wl_closure_print(closure, object, true);
148
149         wl_closure_destroy(closure);
150 }
151
152 WL_EXPORT void
153 wl_resource_post_error(struct wl_resource *resource,
154                        uint32_t code, const char *msg, ...)
155 {
156         struct wl_client *client = resource->client;
157         char buffer[128];
158         va_list ap;
159
160         va_start(ap, msg);
161         vsnprintf(buffer, sizeof buffer, msg, ap);
162         va_end(ap);
163
164         client->error = 1;
165
166         /*
167          * When a client aborts, its resources are destroyed in id order,
168          * which means the display resource is destroyed first. If destruction
169          * of any later resources results in a protocol error, we end up here
170          * with a NULL display_resource. Do not try to send errors to an
171          * already dead client.
172          */
173         if (!client->display_resource)
174                 return;
175
176         wl_resource_post_event(client->display_resource,
177                                WL_DISPLAY_ERROR, resource, code, buffer);
178 }
179
180 static int
181 wl_client_connection_data(int fd, uint32_t mask, void *data)
182 {
183         struct wl_client *client = data;
184         struct wl_connection *connection = client->connection;
185         struct wl_resource *resource;
186         struct wl_object *object;
187         struct wl_closure *closure;
188         const struct wl_message *message;
189         uint32_t p[2], opcode, size;
190         uint32_t cmask = 0;
191         int len;
192
193         if (mask & WL_EVENT_READABLE)
194                 cmask |= WL_CONNECTION_READABLE;
195         if (mask & WL_EVENT_WRITABLE)
196                 cmask |= WL_CONNECTION_WRITABLE;
197
198         len = wl_connection_data(connection, cmask);
199         if (len < 0) {
200                 wl_client_destroy(client);
201                 return 1;
202         }
203
204         while (len >= sizeof p) {
205                 wl_connection_copy(connection, p, sizeof p);
206                 opcode = p[1] & 0xffff;
207                 size = p[1] >> 16;
208                 if (len < size)
209                         break;
210
211                 resource = wl_map_lookup(&client->objects, p[0]);
212                 if (resource == NULL) {
213                         wl_resource_post_error(client->display_resource,
214                                                WL_DISPLAY_ERROR_INVALID_OBJECT,
215                                                "invalid object %d", p[0]);
216                         break;
217                 }
218
219                 object = &resource->object;
220                 if (opcode >= object->interface->method_count) {
221                         wl_resource_post_error(client->display_resource,
222                                                WL_DISPLAY_ERROR_INVALID_METHOD,
223                                                "invalid method %d, object %s@%d",
224                                                object->interface->name,
225                                                object->id, opcode);
226                         break;
227                 }
228
229                 message = &object->interface->methods[opcode];
230                 closure = wl_connection_demarshal(client->connection, size,
231                                                   &client->objects, message);
232                 len -= size;
233
234                 if (closure == NULL && errno == EINVAL) {
235                         wl_resource_post_error(client->display_resource,
236                                                WL_DISPLAY_ERROR_INVALID_METHOD,
237                                                "invalid arguments for %s@%d.%s",
238                                                object->interface->name,
239                                                object->id,
240                                                message->name);
241                         break;
242                 } else if (closure == NULL && errno == ENOMEM) {
243                         wl_resource_post_no_memory(resource);
244                         break;
245                 }
246
247                 if (wl_debug)
248                         wl_closure_print(closure, object, false); 
249
250                 wl_closure_invoke(closure, object,
251                                   object->implementation[opcode], client);
252
253                 wl_closure_destroy(closure);
254
255                 if (client->error)
256                         break;
257         }
258
259         if (client->error)
260                 wl_client_destroy(client);
261
262         return 1;
263 }
264
265 static int
266 wl_client_connection_update(struct wl_connection *connection,
267                             uint32_t mask, void *data)
268 {
269         struct wl_client *client = data;
270         uint32_t emask = 0;
271
272         client->mask = mask;
273         if (mask & WL_CONNECTION_READABLE)
274                 emask |= WL_EVENT_READABLE;
275         if (mask & WL_CONNECTION_WRITABLE)
276                 emask |= WL_EVENT_WRITABLE;
277
278         return wl_event_source_fd_update(client->source, emask);
279 }
280
281 WL_EXPORT void
282 wl_client_flush(struct wl_client *client)
283 {
284         if (client->mask & WL_CONNECTION_WRITABLE)
285                 wl_connection_data(client->connection, WL_CONNECTION_WRITABLE);
286 }
287
288 WL_EXPORT struct wl_display *
289 wl_client_get_display(struct wl_client *client)
290 {
291         return client->display;
292 }
293
294 static void
295 bind_display(struct wl_client *client,
296              void *data, uint32_t version, uint32_t id);
297
298 WL_EXPORT struct wl_client *
299 wl_client_create(struct wl_display *display, int fd)
300 {
301         struct wl_client *client;
302         socklen_t len;
303
304         client = malloc(sizeof *client);
305         if (client == NULL)
306                 return NULL;
307
308         memset(client, 0, sizeof *client);
309         client->display = display;
310         client->source = wl_event_loop_add_fd(display->loop, fd,
311                                               WL_EVENT_READABLE,
312                                               wl_client_connection_data, client);
313
314         len = sizeof client->ucred;
315         if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED,
316                        &client->ucred, &len) < 0) {
317                 free(client);
318                 return NULL;
319         }
320
321         client->connection =
322                 wl_connection_create(fd, wl_client_connection_update, client);
323         if (client->connection == NULL) {
324                 free(client);
325                 return NULL;
326         }
327
328         wl_map_init(&client->objects);
329
330         if (wl_map_insert_at(&client->objects, 0, NULL) < 0) {
331                 wl_map_release(&client->objects);
332                 free(client);
333                 return NULL;
334         }
335
336         bind_display(client, display, 1, 1);
337
338         wl_list_insert(display->client_list.prev, &client->link);
339
340         return client;
341 }
342
343 WL_EXPORT void
344 wl_client_get_credentials(struct wl_client *client,
345                           pid_t *pid, uid_t *uid, gid_t *gid)
346 {
347         if (pid)
348                 *pid = client->ucred.pid;
349         if (uid)
350                 *uid = client->ucred.uid;
351         if (gid)
352                 *gid = client->ucred.gid;
353 }
354
355 WL_EXPORT void
356 wl_client_add_resource(struct wl_client *client,
357                        struct wl_resource *resource)
358 {
359         if (resource->object.id == 0)
360                 resource->object.id =
361                         wl_map_insert_new(&client->objects,
362                                           WL_MAP_SERVER_SIDE, resource);
363         else
364                 wl_map_insert_at(&client->objects,
365                                  resource->object.id, resource);
366
367         resource->client = client;
368         wl_list_init(&resource->destroy_listener_list);
369 }
370
371 WL_EXPORT void
372 wl_resource_post_no_memory(struct wl_resource *resource)
373 {
374         wl_resource_post_error(resource->client->display_resource,
375                                WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
376 }
377
378 static void
379 destroy_resource(void *element, void *data)
380 {
381         struct wl_resource *resource = element;
382         struct wl_listener *l, *next;
383         uint32_t *time = data;
384
385         wl_list_for_each_safe(l, next, &resource->destroy_listener_list, link)
386                 l->func(l, resource, *time);
387
388         if (resource->destroy)
389                 resource->destroy(resource);
390 }
391
392 WL_EXPORT void
393 wl_resource_destroy(struct wl_resource *resource, uint32_t time)
394 {
395         struct wl_client *client = resource->client;
396         uint32_t id;
397
398         id = resource->object.id;
399         destroy_resource(resource, &time);
400
401         if (id < WL_SERVER_ID_START) {
402                 if (client->display_resource) {
403                         wl_resource_queue_event(client->display_resource,
404                                                 WL_DISPLAY_DELETE_ID, id);
405                 }
406                 wl_map_insert_at(&client->objects, id, NULL);
407         } else {
408                 wl_map_remove(&client->objects, id);
409         }
410 }
411
412 WL_EXPORT void
413 wl_client_destroy(struct wl_client *client)
414 {
415         uint32_t time = 0;
416         
417         printf("disconnect from client %p\n", client);
418
419         wl_client_flush(client);
420         wl_map_for_each(&client->objects, destroy_resource, &time);
421         wl_map_release(&client->objects);
422         wl_event_source_remove(client->source);
423         wl_connection_destroy(client->connection);
424         wl_list_remove(&client->link);
425         free(client);
426 }
427
428 static void
429 lose_pointer_focus(struct wl_listener *listener,
430                    struct wl_resource *resource, uint32_t time)
431 {
432         struct wl_input_device *device =
433                 container_of(listener, struct wl_input_device,
434                              pointer_focus_listener);
435
436         device->pointer_focus_resource = NULL;
437 }
438
439 static void
440 lose_keyboard_focus(struct wl_listener *listener,
441                     struct wl_resource *resource, uint32_t time)
442 {
443         struct wl_input_device *device =
444                 container_of(listener, struct wl_input_device,
445                              keyboard_focus_listener);
446
447         device->keyboard_focus_resource = NULL;
448 }
449
450 static void
451 default_grab_focus(struct wl_pointer_grab *grab, uint32_t time,
452                    struct wl_surface *surface, int32_t x, int32_t y)
453 {
454         struct wl_input_device *device = grab->input_device;
455
456         if (device->button_count > 0)
457                 return;
458
459         wl_input_device_set_pointer_focus(device, surface, time, x, y);
460 }
461
462 static void
463 default_grab_motion(struct wl_pointer_grab *grab,
464                     uint32_t time, int32_t x, int32_t y)
465 {
466         struct wl_resource *resource;
467
468         resource = grab->input_device->pointer_focus_resource;
469         if (resource)
470                 wl_resource_post_event(resource, WL_INPUT_DEVICE_MOTION,
471                                        time, x, y);
472 }
473
474 static void
475 default_grab_button(struct wl_pointer_grab *grab,
476                     uint32_t time, int32_t button, int32_t state)
477 {
478         struct wl_input_device *device = grab->input_device;
479         struct wl_resource *resource;
480
481         resource = device->pointer_focus_resource;
482         if (resource)
483                 wl_resource_post_event(resource, WL_INPUT_DEVICE_BUTTON,
484                                        time, button, state);
485
486         if (device->button_count == 0 && state == 0)
487                 wl_input_device_set_pointer_focus(device,
488                                                   device->current, time,
489                                                   device->current_x,
490                                                   device->current_y);
491 }
492
493 static const struct wl_pointer_grab_interface
494                                 default_pointer_grab_interface = {
495         default_grab_focus,
496         default_grab_motion,
497         default_grab_button
498 };
499
500 static void
501 default_grab_key(struct wl_keyboard_grab *grab,
502                     uint32_t time, uint32_t key, int32_t state)
503 {
504         struct wl_input_device *device = grab->input_device;
505         struct wl_resource *resource;
506
507         resource = device->keyboard_focus_resource;
508         if (resource)
509                 wl_resource_post_event(resource, WL_INPUT_DEVICE_KEY,
510                                        time, key, state);
511 }
512
513 static const struct wl_keyboard_grab_interface
514                                 default_keyboard_grab_interface = {
515         default_grab_key
516 };
517
518 WL_EXPORT void
519 wl_input_device_init(struct wl_input_device *device)
520 {
521         memset(device, 0, sizeof *device);
522         wl_list_init(&device->resource_list);
523         wl_array_init(&device->keys);
524         device->pointer_focus_listener.func = lose_pointer_focus;
525         device->keyboard_focus_listener.func = lose_keyboard_focus;
526
527         device->default_pointer_grab.interface = &default_pointer_grab_interface;
528         device->default_pointer_grab.input_device = device;
529         device->pointer_grab = &device->default_pointer_grab;
530
531         device->default_keyboard_grab.interface = &default_keyboard_grab_interface;
532         device->default_keyboard_grab.input_device = device;
533         device->keyboard_grab = &device->default_keyboard_grab;
534
535         wl_list_init(&device->drag_resource_list);
536         device->selection_data_source = NULL;
537         wl_list_init(&device->selection_listener_list);
538
539         device->x = 100;
540         device->y = 100;
541 }
542
543 WL_EXPORT void
544 wl_input_device_release(struct wl_input_device *device)
545 {
546         if (device->keyboard_focus_resource)
547                 wl_list_remove(&device->keyboard_focus_listener.link);
548
549         if (device->pointer_focus_resource)
550                 wl_list_remove(&device->pointer_focus_listener.link);
551
552         /* XXX: What about device->resource_list? */
553
554         wl_array_release(&device->keys);
555 }
556
557 static struct wl_resource *
558 find_resource_for_surface(struct wl_list *list, struct wl_surface *surface)
559 {
560         struct wl_resource *r;
561
562         if (!surface)
563                 return NULL;
564
565         wl_list_for_each(r, list, link) {
566                 if (r->client == surface->resource.client)
567                         return r;
568         }
569
570         return NULL;
571 }
572
573 WL_EXPORT void
574 wl_input_device_set_pointer_focus(struct wl_input_device *device,
575                                   struct wl_surface *surface,
576                                   uint32_t time,
577                                   int32_t sx, int32_t sy)
578 {
579         struct wl_resource *resource;
580
581         if (device->pointer_focus == surface)
582                 return;
583
584         if (device->pointer_focus_resource) {
585                 wl_resource_post_event(device->pointer_focus_resource,
586                                        WL_INPUT_DEVICE_POINTER_LEAVE,
587                                        time, device->pointer_focus);
588                 wl_list_remove(&device->pointer_focus_listener.link);
589         }
590
591         resource = find_resource_for_surface(&device->resource_list, surface);
592         if (resource) {
593                 wl_resource_post_event(resource,
594                                        WL_INPUT_DEVICE_POINTER_ENTER,
595                                        time, surface, sx, sy);
596                 wl_list_insert(resource->destroy_listener_list.prev,
597                                &device->pointer_focus_listener.link);
598         }
599
600         device->pointer_focus_resource = resource;
601         device->pointer_focus = surface;
602         device->pointer_focus_time = time;
603         device->default_pointer_grab.focus = surface;
604 }
605
606 WL_EXPORT void
607 wl_input_device_set_keyboard_focus(struct wl_input_device *device,
608                                    struct wl_surface *surface,
609                                    uint32_t time)
610 {
611         struct wl_resource *resource;
612
613         if (device->keyboard_focus == surface)
614                 return;
615
616         if (device->keyboard_focus_resource) {
617                 wl_resource_post_event(device->keyboard_focus_resource,
618                                        WL_INPUT_DEVICE_KEYBOARD_LEAVE,
619                                        time, device->keyboard_focus);
620                 wl_list_remove(&device->keyboard_focus_listener.link);
621         }
622
623         resource = find_resource_for_surface(&device->resource_list, surface);
624         if (resource) {
625                 wl_resource_post_event(resource,
626                                        WL_INPUT_DEVICE_KEYBOARD_ENTER,
627                                        time, surface, &device->keys);
628                 wl_list_insert(resource->destroy_listener_list.prev,
629                                &device->keyboard_focus_listener.link);
630         }
631
632         device->keyboard_focus_resource = resource;
633         device->keyboard_focus = surface;
634         device->keyboard_focus_time = time;
635 }
636
637 WL_EXPORT void
638 wl_input_device_start_keyboard_grab(struct wl_input_device *device,
639                            struct wl_keyboard_grab *grab, uint32_t time)
640 {
641         device->keyboard_grab = grab;
642         grab->input_device = device;
643
644 }
645
646 WL_EXPORT void
647 wl_input_device_end_keyboard_grab(struct wl_input_device *device, uint32_t time)
648 {
649         device->keyboard_grab = &device->default_keyboard_grab;
650 }
651
652 WL_EXPORT void
653 wl_input_device_start_pointer_grab(struct wl_input_device *device,
654                            struct wl_pointer_grab *grab, uint32_t time)
655 {
656         const struct wl_pointer_grab_interface *interface;
657
658         device->pointer_grab = grab;
659         interface = device->pointer_grab->interface;
660         grab->input_device = device;
661
662         if (device->current)
663                 interface->focus(device->pointer_grab, time, device->current,
664                                  device->current_x, device->current_y);
665 }
666
667 WL_EXPORT void
668 wl_input_device_end_pointer_grab(struct wl_input_device *device, uint32_t time)
669 {
670         const struct wl_pointer_grab_interface *interface;
671
672         device->pointer_grab = &device->default_pointer_grab;
673         interface = device->pointer_grab->interface;
674         interface->focus(device->pointer_grab, time, device->current,
675                          device->current_x, device->current_y);
676 }
677
678 static void
679 display_bind(struct wl_client *client,
680              struct wl_resource *resource, uint32_t name,
681              const char *interface, uint32_t version, uint32_t id)
682 {
683         struct wl_global *global;
684         struct wl_display *display = resource->data;
685
686         wl_list_for_each(global, &display->global_list, link)
687                 if (global->name == name)
688                         break;
689
690         if (&global->link == &display->global_list)
691                 wl_resource_post_error(resource,
692                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
693                                        "invalid global %d", name);
694         else
695                 global->bind(client, global->data, version, id);
696 }
697
698 static void
699 display_sync(struct wl_client *client,
700              struct wl_resource *resource, uint32_t id)
701 {
702         struct wl_resource *callback;
703
704         callback = wl_client_add_object(client,
705                                         &wl_callback_interface, NULL, id, NULL);
706         wl_resource_post_event(callback, WL_CALLBACK_DONE, 0);
707         wl_resource_destroy(callback, 0);
708 }
709
710 struct wl_display_interface display_interface = {
711         display_bind,
712         display_sync,
713 };
714
715 static void
716 destroy_client_display_resource(struct wl_resource *resource)
717 {
718         resource->client->display_resource = NULL;
719         free(resource);
720 }
721
722 static void
723 bind_display(struct wl_client *client,
724              void *data, uint32_t version, uint32_t id)
725 {
726         struct wl_display *display = data;
727         struct wl_global *global;
728
729         client->display_resource =
730                 wl_client_add_object(client, &wl_display_interface,
731                                      &display_interface, id, display);
732         client->display_resource->destroy = destroy_client_display_resource;
733
734         wl_list_for_each(global, &display->global_list, link)
735                 wl_resource_post_event(client->display_resource,
736                                        WL_DISPLAY_GLOBAL,
737                                        global->name,
738                                        global->interface->name,
739                                        global->interface->version);
740 }
741
742 WL_EXPORT struct wl_display *
743 wl_display_create(void)
744 {
745         struct wl_display *display;
746         const char *debug;
747
748         debug = getenv("WAYLAND_DEBUG");
749         if (debug)
750                 wl_debug = 1;
751
752         display = malloc(sizeof *display);
753         if (display == NULL)
754                 return NULL;
755
756         display->loop = wl_event_loop_create();
757         if (display->loop == NULL) {
758                 free(display);
759                 return NULL;
760         }
761
762         wl_list_init(&display->global_list);
763         wl_list_init(&display->socket_list);
764         wl_list_init(&display->client_list);
765
766         display->id = 1;
767
768         if (!wl_display_add_global(display, &wl_display_interface, 
769                                    display, bind_display)) {
770                 wl_event_loop_destroy(display->loop);
771                 free(display);
772                 return NULL;
773         }
774
775         return display;
776 }
777
778 WL_EXPORT void
779 wl_display_destroy(struct wl_display *display)
780 {
781         struct wl_socket *s, *next;
782         struct wl_global *global, *gnext;
783
784         wl_list_for_each_safe(s, next, &display->socket_list, link) {
785                 wl_event_source_remove(s->source);
786                 close(s->fd);
787                 unlink(s->addr.sun_path);
788                 close(s->fd_lock);
789                 unlink(s->lock_addr);
790                 free(s);
791         }
792         wl_event_loop_destroy(display->loop);
793
794         wl_list_for_each_safe(global, gnext, &display->global_list, link)
795                 free(global);
796
797         free(display);
798 }
799
800 WL_EXPORT struct wl_global *
801 wl_display_add_global(struct wl_display *display,
802                       const struct wl_interface *interface,
803                       void *data, wl_global_bind_func_t bind)
804 {
805         struct wl_global *global;
806
807         global = malloc(sizeof *global);
808         if (global == NULL)
809                 return NULL;
810
811         global->name = display->id++;
812         global->interface = interface;
813         global->data = data;
814         global->bind = bind;
815         wl_list_insert(display->global_list.prev, &global->link);
816
817         return global;
818 }
819
820 WL_EXPORT void
821 wl_display_remove_global(struct wl_display *display, struct wl_global *global)
822 {
823         struct wl_client *client;
824
825         wl_list_for_each(client, &display->client_list, link)
826                 wl_resource_post_event(client->display_resource,
827                                        WL_DISPLAY_GLOBAL_REMOVE, global->name);
828         wl_list_remove(&global->link);
829         free(global);
830 }
831
832 WL_EXPORT struct wl_event_loop *
833 wl_display_get_event_loop(struct wl_display *display)
834 {
835         return display->loop;
836 }
837
838 WL_EXPORT void
839 wl_display_terminate(struct wl_display *display)
840 {
841         display->run = 0;
842 }
843
844 WL_EXPORT void
845 wl_display_run(struct wl_display *display)
846 {
847         display->run = 1;
848
849         while (display->run)
850                 wl_event_loop_dispatch(display->loop, -1);
851 }
852
853 static int
854 socket_data(int fd, uint32_t mask, void *data)
855 {
856         struct wl_display *display = data;
857         struct sockaddr_un name;
858         socklen_t length;
859         int client_fd;
860
861         length = sizeof name;
862         client_fd =
863                 accept4(fd, (struct sockaddr *) &name, &length, SOCK_CLOEXEC);
864         if (client_fd < 0 && errno == ENOSYS) {
865                 client_fd = accept(fd, (struct sockaddr *) &name, &length);
866                 if (client_fd >= 0 && fcntl(client_fd, F_SETFD, FD_CLOEXEC) == -1)
867                         fprintf(stderr, "failed to set FD_CLOEXEC flag on client fd, errno: %d\n", errno);
868         }
869
870         if (client_fd < 0)
871                 fprintf(stderr, "failed to accept, errno: %d\n", errno);
872
873         wl_client_create(display, client_fd);
874
875         return 1;
876 }
877
878 static int
879 get_socket_lock(struct wl_socket *socket, socklen_t name_size)
880 {
881         struct stat socket_stat;
882         int lock_size = name_size + 5;
883
884         snprintf(socket->lock_addr, lock_size,
885                  "%s.lock", socket->addr.sun_path);
886
887         socket->fd_lock = open(socket->lock_addr, O_CREAT | O_CLOEXEC,
888                                (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
889
890         if (socket->fd_lock < 0) {
891                 fprintf(stderr,
892                         "unable to open lockfile %s check permissions\n",
893                         socket->lock_addr);
894                 return -1;
895         }
896
897         if (flock(socket->fd_lock, LOCK_EX | LOCK_NB) < 0) {
898                 fprintf(stderr,
899                         "unable to lock lockfile %s, maybe another compositor is running\n",
900                         socket->lock_addr);
901                 close(socket->fd_lock);
902                 return -1;
903         }
904
905         if (stat(socket->addr.sun_path, &socket_stat) < 0 ) {
906                 if (errno != ENOENT) {
907                         fprintf(stderr, "did not manage to stat file %s\n",
908                                 socket->addr.sun_path);
909                         close(socket->fd_lock);
910                         return -1;
911                 }
912         } else if (socket_stat.st_mode & S_IWUSR ||
913                    socket_stat.st_mode & S_IWGRP) {
914                 unlink(socket->addr.sun_path);
915         }
916
917         return 0;
918 }
919
920 WL_EXPORT int
921 wl_display_add_socket(struct wl_display *display, const char *name)
922 {
923         struct wl_socket *s;
924         socklen_t size, name_size;
925         const char *runtime_dir;
926
927         s = malloc(sizeof *s);
928         if (s == NULL)
929                 return -1;
930
931         s->fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
932         if (s->fd < 0) {
933                 free(s);
934                 return -1;
935         }
936
937         runtime_dir = getenv("XDG_RUNTIME_DIR");
938         if (runtime_dir == NULL) {
939                 runtime_dir = ".";
940                 fprintf(stderr,
941                         "XDG_RUNTIME_DIR not set, falling back to %s\n",
942                         runtime_dir);
943         }
944
945         if (name == NULL)
946                 name = getenv("WAYLAND_DISPLAY");
947         if (name == NULL)
948                 name = "wayland-0";
949
950         memset(&s->addr, 0, sizeof s->addr);
951         s->addr.sun_family = AF_LOCAL;
952         name_size = snprintf(s->addr.sun_path, sizeof s->addr.sun_path,
953                              "%s/%s", runtime_dir, name) + 1;
954         fprintf(stderr, "using socket %s\n", s->addr.sun_path);
955
956         if (get_socket_lock(s,name_size) < 0) {
957                 close(s->fd);
958                 free(s);
959                 return -1;
960         }
961
962         size = offsetof (struct sockaddr_un, sun_path) + name_size;
963         if (bind(s->fd, (struct sockaddr *) &s->addr, size) < 0) {
964                 close(s->fd);
965                 free(s);
966                 return -1;
967         }
968
969         if (listen(s->fd, 1) < 0) {
970                 close(s->fd);
971                 unlink(s->addr.sun_path);
972                 free(s);
973                 return -1;
974         }
975
976         s->source = wl_event_loop_add_fd(display->loop, s->fd,
977                                          WL_EVENT_READABLE,
978                                          socket_data, display);
979         if (s->source == NULL) {
980                 close(s->fd);
981                 unlink(s->addr.sun_path);
982                 free(s);
983                 return -1;
984         }
985         wl_list_insert(display->socket_list.prev, &s->link);
986
987         return 0;
988 }
989
990 WL_EXPORT struct wl_resource *
991 wl_client_add_object(struct wl_client *client,
992                      const struct wl_interface *interface,
993                      const void *implementation,
994                      uint32_t id, void *data)
995 {
996         struct wl_resource *resource;
997
998         resource = malloc(sizeof *resource);
999         if (resource == NULL) {
1000                 wl_resource_post_no_memory(client->display_resource);
1001                 return NULL;
1002         }
1003
1004         resource->object.interface = interface;
1005         resource->object.implementation = implementation;
1006         resource->object.id = id;
1007         resource->client = client;
1008         resource->data = data;
1009         resource->destroy = (void *) free;
1010         wl_list_init(&resource->destroy_listener_list);
1011
1012         if (wl_map_insert_at(&client->objects, resource->object.id, resource) < 0) {
1013                 wl_resource_post_no_memory(client->display_resource);
1014                 free(resource);
1015                 return NULL;
1016         }
1017
1018         return resource;
1019 }
1020
1021 WL_EXPORT struct wl_resource *
1022 wl_client_new_object(struct wl_client *client,
1023                      const struct wl_interface *interface,
1024                      const void *implementation, void *data)
1025 {
1026         uint32_t id;
1027
1028         id = wl_map_insert_new(&client->objects, WL_MAP_SERVER_SIDE, NULL);
1029         return wl_client_add_object(client,
1030                                     interface, implementation, id, data);
1031
1032 }