2 * Copyright © 2008 Kristian Høgsberg
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.
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
34 #include <sys/socket.h>
44 #include "wayland-private.h"
45 #include "wayland-server.h"
46 #include "wayland-server-protocol.h"
47 #include "wayland-os.h"
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. */
53 #define UNIX_PATH_MAX 108
56 #define LOCK_SUFFIX ".lock"
57 #define LOCK_SUFFIXLEN 5
62 struct sockaddr_un addr;
63 char lock_addr[UNIX_PATH_MAX + LOCK_SUFFIXLEN];
65 struct wl_event_source *source;
69 struct wl_connection *connection;
70 struct wl_event_source *source;
71 struct wl_display *display;
72 struct wl_resource *display_resource;
76 struct wl_map objects;
77 struct wl_signal destroy_signal;
83 struct wl_event_loop *loop;
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;
94 struct wl_signal destroy_signal;
98 const struct wl_interface *interface;
101 wl_global_bind_func_t bind;
105 static int wl_debug = 0;
108 destroy_client(void *data)
110 struct wl_client *client = data;
112 wl_client_destroy(client);
116 wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...)
118 struct wl_closure *closure;
119 struct wl_object *object = &resource->object;
122 va_start(ap, opcode);
123 closure = wl_closure_vmarshal(object, opcode, ap,
124 &object->interface->events[opcode]);
130 if (wl_closure_send(closure, resource->client->connection))
131 wl_event_loop_add_idle(resource->client->display->loop,
132 destroy_client, resource->client);
135 wl_closure_print(closure, object, true);
137 wl_closure_destroy(closure);
142 wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
144 struct wl_closure *closure;
145 struct wl_object *object = &resource->object;
148 va_start(ap, opcode);
149 closure = wl_closure_vmarshal(object, opcode, ap,
150 &object->interface->events[opcode]);
156 if (wl_closure_queue(closure, resource->client->connection))
157 wl_event_loop_add_idle(resource->client->display->loop,
158 destroy_client, resource->client);
161 wl_closure_print(closure, object, true);
163 wl_closure_destroy(closure);
167 wl_resource_post_error(struct wl_resource *resource,
168 uint32_t code, const char *msg, ...)
170 struct wl_client *client = resource->client;
175 vsnprintf(buffer, sizeof buffer, msg, ap);
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.
187 if (!client->display_resource)
190 wl_resource_post_event(client->display_resource,
191 WL_DISPLAY_ERROR, resource, code, buffer);
195 wl_client_connection_data(int fd, uint32_t mask, void *data)
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;
207 if (mask & (WL_EVENT_ERROR | WL_EVENT_HANGUP)) {
208 wl_client_destroy(client);
212 if (mask & WL_EVENT_WRITABLE) {
213 len = wl_connection_flush(connection);
214 if (len < 0 && errno != EAGAIN) {
215 wl_client_destroy(client);
217 } else if (len >= 0) {
218 wl_event_source_fd_update(client->source,
224 if (mask & WL_EVENT_READABLE) {
225 len = wl_connection_read(connection);
226 if (len < 0 && errno != EAGAIN) {
227 wl_client_destroy(client);
232 while ((size_t) len >= sizeof p) {
233 wl_connection_copy(connection, p, sizeof p);
234 opcode = p[1] & 0xffff;
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]);
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",
253 object->interface->name,
258 message = &object->interface->methods[opcode];
259 closure = wl_connection_demarshal(client->connection, size,
260 &client->objects, message);
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,
272 } else if (closure == NULL && errno == ENOMEM) {
273 wl_resource_post_no_memory(resource);
278 wl_closure_print(closure, object, false);
280 wl_closure_invoke(closure, object,
281 object->implementation[opcode], client);
283 wl_closure_destroy(closure);
290 wl_client_destroy(client);
296 wl_client_flush(struct wl_client *client)
298 wl_connection_flush(client->connection);
301 WL_EXPORT struct wl_display *
302 wl_client_get_display(struct wl_client *client)
304 return client->display;
308 bind_display(struct wl_client *client,
309 void *data, uint32_t version, uint32_t id);
311 WL_EXPORT struct wl_client *
312 wl_client_create(struct wl_display *display, int fd)
314 struct wl_client *client;
317 client = malloc(sizeof *client);
321 memset(client, 0, sizeof *client);
322 client->display = display;
323 client->source = wl_event_loop_add_fd(display->loop, fd,
325 wl_client_connection_data, client);
330 len = sizeof client->ucred;
331 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED,
332 &client->ucred, &len) < 0)
335 client->connection = wl_connection_create(fd);
336 if (client->connection == NULL)
339 wl_map_init(&client->objects);
341 if (wl_map_insert_at(&client->objects, 0, NULL) < 0)
344 wl_signal_init(&client->destroy_signal);
345 bind_display(client, display, 1, 1);
347 if (!client->display_resource)
350 wl_list_insert(display->client_list.prev, &client->link);
355 wl_map_release(&client->objects);
356 wl_connection_destroy(client->connection);
358 wl_event_source_remove(client->source);
365 wl_client_get_credentials(struct wl_client *client,
366 pid_t *pid, uid_t *uid, gid_t *gid)
369 *pid = client->ucred.pid;
371 *uid = client->ucred.uid;
373 *gid = client->ucred.gid;
377 wl_client_add_resource(struct wl_client *client,
378 struct wl_resource *resource)
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,
389 resource->object.id);
393 resource->client = client;
394 wl_signal_init(&resource->destroy_signal);
396 return resource->object.id;
399 WL_EXPORT struct wl_resource *
400 wl_client_get_object(struct wl_client *client, uint32_t id)
402 return wl_map_lookup(&client->objects, id);
406 wl_resource_post_no_memory(struct wl_resource *resource)
408 wl_resource_post_error(resource->client->display_resource,
409 WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
413 destroy_resource(void *element, void *data)
415 struct wl_resource *resource = element;
417 wl_signal_emit(&resource->destroy_signal, resource);
419 if (resource->destroy)
420 resource->destroy(resource);
424 wl_resource_destroy(struct wl_resource *resource)
426 struct wl_client *client = resource->client;
429 id = resource->object.id;
430 destroy_resource(resource, NULL);
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);
437 wl_map_insert_at(&client->objects, id, NULL);
439 wl_map_remove(&client->objects, id);
444 wl_client_add_destroy_listener(struct wl_client *client,
445 struct wl_listener *listener)
447 wl_signal_add(&client->destroy_signal, listener);
450 WL_EXPORT struct wl_listener *
451 wl_client_get_destroy_listener(struct wl_client *client,
452 wl_notify_func_t notify)
454 return wl_signal_get(&client->destroy_signal, notify);
458 wl_client_destroy(struct wl_client *client)
462 wl_log("disconnect from client %p\n", client);
464 wl_signal_emit(&client->destroy_signal, client);
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);
476 lose_pointer_focus(struct wl_listener *listener, void *data)
478 struct wl_pointer *pointer =
479 container_of(listener, struct wl_pointer, focus_listener);
481 pointer->focus_resource = NULL;
485 lose_keyboard_focus(struct wl_listener *listener, void *data)
487 struct wl_keyboard *keyboard =
488 container_of(listener, struct wl_keyboard, focus_listener);
490 keyboard->focus_resource = NULL;
494 lose_touch_focus(struct wl_listener *listener, void *data)
496 struct wl_touch *touch =
497 container_of(listener, struct wl_touch, focus_listener);
499 touch->focus_resource = NULL;
503 default_grab_focus(struct wl_pointer_grab *grab,
504 struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y)
506 struct wl_pointer *pointer = grab->pointer;
508 if (pointer->button_count > 0)
511 wl_pointer_set_focus(pointer, surface, x, y);
515 default_grab_motion(struct wl_pointer_grab *grab,
516 uint32_t time, wl_fixed_t x, wl_fixed_t y)
518 struct wl_resource *resource;
520 resource = grab->pointer->focus_resource;
522 wl_pointer_send_motion(resource, time, x, y);
526 default_grab_button(struct wl_pointer_grab *grab,
527 uint32_t time, uint32_t button, uint32_t state_w)
529 struct wl_pointer *pointer = grab->pointer;
530 struct wl_resource *resource;
532 enum wl_pointer_button_state state = state_w;
534 resource = pointer->focus_resource;
536 serial = wl_display_next_serial(resource->client->display);
537 wl_pointer_send_button(resource, serial, time, button, state_w);
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);
546 static const struct wl_pointer_grab_interface
547 default_pointer_grab_interface = {
553 static void default_grab_touch_down(struct wl_touch_grab *grab,
559 struct wl_touch *touch = grab->touch;
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);
569 static void default_grab_touch_up(struct wl_touch_grab *grab,
573 struct wl_touch *touch = grab->touch;
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);
582 static void default_grab_touch_motion(struct wl_touch_grab *grab,
588 struct wl_touch *touch = grab->touch;
590 if (touch->focus_resource) {
591 wl_touch_send_motion(touch->focus_resource, time,
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
603 default_grab_key(struct wl_keyboard_grab *grab,
604 uint32_t time, uint32_t key, uint32_t state)
606 struct wl_keyboard *keyboard = grab->keyboard;
607 struct wl_resource *resource;
610 resource = keyboard->focus_resource;
612 serial = wl_display_next_serial(resource->client->display);
613 wl_keyboard_send_key(resource, serial, time, key, state);
617 static struct wl_resource *
618 find_resource_for_surface(struct wl_list *list, struct wl_surface *surface)
620 struct wl_resource *r;
625 wl_list_for_each(r, list, link) {
626 if (r->client == surface->resource.client)
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)
638 struct wl_keyboard *keyboard = grab->keyboard;
639 struct wl_pointer *pointer = keyboard->seat->pointer;
640 struct wl_resource *resource, *pr;
642 resource = keyboard->focus_resource;
646 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
647 mods_latched, mods_locked, group);
649 if (pointer && pointer->focus && pointer->focus != keyboard->focus) {
650 pr = find_resource_for_surface(&keyboard->resource_list,
653 wl_keyboard_send_modifiers(pr,
655 keyboard->modifiers.mods_depressed,
656 keyboard->modifiers.mods_latched,
657 keyboard->modifiers.mods_locked,
658 keyboard->modifiers.group);
663 static const struct wl_keyboard_grab_interface
664 default_keyboard_grab_interface = {
666 default_grab_modifiers,
670 wl_pointer_init(struct wl_pointer *pointer)
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);
680 /* FIXME: Pick better co-ords. */
681 pointer->x = wl_fixed_from_int(100);
682 pointer->y = wl_fixed_from_int(100);
686 wl_pointer_release(struct wl_pointer *pointer)
688 /* XXX: What about pointer->resource_list? */
689 if (pointer->focus_resource)
690 wl_list_remove(&pointer->focus_listener.link);
694 wl_keyboard_init(struct wl_keyboard *keyboard)
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);
707 wl_keyboard_release(struct wl_keyboard *keyboard)
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);
716 wl_touch_init(struct wl_touch *touch)
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);
728 wl_touch_release(struct wl_touch *touch)
730 /* XXX: What about touch->resource_list? */
731 if (touch->focus_resource)
732 wl_list_remove(&touch->focus_listener.link);
736 wl_seat_init(struct wl_seat *seat)
738 memset(seat, 0, sizeof *seat);
740 wl_signal_init(&seat->destroy_signal);
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);
750 wl_seat_release(struct wl_seat *seat)
752 wl_signal_emit(&seat->destroy_signal, seat);
755 wl_pointer_release(seat->pointer);
757 wl_keyboard_release(seat->keyboard);
759 wl_touch_release(seat->touch);
763 seat_send_updated_caps(struct wl_seat *seat)
765 struct wl_resource *r;
766 enum wl_seat_capability caps = 0;
769 caps |= WL_SEAT_CAPABILITY_POINTER;
771 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
773 caps |= WL_SEAT_CAPABILITY_TOUCH;
775 wl_list_for_each(r, &seat->base_resource_list, link)
776 wl_seat_send_capabilities(r, caps);
780 wl_seat_set_pointer(struct wl_seat *seat, struct wl_pointer *pointer)
782 if (pointer && (seat->pointer || pointer->seat))
783 return; /* XXX: error? */
784 if (!pointer && !seat->pointer)
787 seat->pointer = pointer;
789 pointer->seat = seat;
791 seat_send_updated_caps(seat);
795 wl_seat_set_keyboard(struct wl_seat *seat, struct wl_keyboard *keyboard)
797 if (keyboard && (seat->keyboard || keyboard->seat))
798 return; /* XXX: error? */
799 if (!keyboard && !seat->keyboard)
802 seat->keyboard = keyboard;
804 keyboard->seat = seat;
806 seat_send_updated_caps(seat);
810 wl_seat_set_touch(struct wl_seat *seat, struct wl_touch *touch)
812 if (touch && (seat->touch || touch->seat))
813 return; /* XXX: error? */
814 if (!touch && !seat->touch)
821 seat_send_updated_caps(seat);
825 wl_pointer_set_focus(struct wl_pointer *pointer, struct wl_surface *surface,
826 wl_fixed_t sx, wl_fixed_t sy)
828 struct wl_keyboard *kbd = pointer->seat->keyboard;
829 struct wl_resource *resource, *kr;
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);
840 resource = find_resource_for_surface(&pointer->resource_list,
843 (pointer->focus != surface ||
844 pointer->focus_resource != resource)) {
845 serial = wl_display_next_serial(resource->client->display);
847 kr = find_resource_for_surface(&kbd->resource_list,
850 wl_keyboard_send_modifiers(kr,
852 kbd->modifiers.mods_depressed,
853 kbd->modifiers.mods_latched,
854 kbd->modifiers.mods_locked,
855 kbd->modifiers.group);
858 wl_pointer_send_enter(resource, serial, &surface->resource,
860 wl_signal_add(&resource->destroy_signal,
861 &pointer->focus_listener);
862 pointer->focus_serial = serial;
865 pointer->focus_resource = resource;
866 pointer->focus = surface;
867 pointer->default_grab.focus = surface;
868 wl_signal_emit(&pointer->focus_signal, pointer);
872 wl_keyboard_set_focus(struct wl_keyboard *keyboard, struct wl_surface *surface)
874 struct wl_resource *resource;
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);
885 resource = find_resource_for_surface(&keyboard->resource_list,
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,
898 wl_signal_add(&resource->destroy_signal,
899 &keyboard->focus_listener);
900 keyboard->focus_serial = serial;
903 keyboard->focus_resource = resource;
904 keyboard->focus = surface;
905 wl_signal_emit(&keyboard->focus_signal, keyboard);
909 wl_keyboard_start_grab(struct wl_keyboard *keyboard,
910 struct wl_keyboard_grab *grab)
912 keyboard->grab = grab;
913 grab->keyboard = keyboard;
919 wl_keyboard_end_grab(struct wl_keyboard *keyboard)
921 keyboard->grab = &keyboard->default_grab;
925 wl_pointer_start_grab(struct wl_pointer *pointer, struct wl_pointer_grab *grab)
927 const struct wl_pointer_grab_interface *interface;
929 pointer->grab = grab;
930 interface = pointer->grab->interface;
931 grab->pointer = pointer;
933 if (pointer->current)
934 interface->focus(pointer->grab, pointer->current,
935 pointer->current_x, pointer->current_y);
939 wl_pointer_end_grab(struct wl_pointer *pointer)
941 const struct wl_pointer_grab_interface *interface;
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);
950 wl_touch_start_grab(struct wl_touch *touch, struct wl_touch_grab *grab)
957 wl_touch_end_grab(struct wl_touch *touch)
959 touch->grab = &touch->default_grab;
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)
967 struct wl_global *global;
968 struct wl_display *display = resource->data;
970 wl_list_for_each(global, &display->global_list, link)
971 if (global->name == name)
974 if (&global->link == &display->global_list)
975 wl_resource_post_error(resource,
976 WL_DISPLAY_ERROR_INVALID_OBJECT,
977 "invalid global %d", name);
979 global->bind(client, global->data, version, id);
982 static const struct wl_registry_interface registry_interface = {
987 display_sync(struct wl_client *client,
988 struct wl_resource *resource, uint32_t id)
990 struct wl_resource *callback;
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);
1001 unbind_resource(struct wl_resource *resource)
1003 wl_list_remove(&resource->link);
1008 display_get_registry(struct wl_client *client,
1009 struct wl_resource *resource, uint32_t id)
1011 struct wl_display *display = resource->data;
1012 struct wl_resource *registry_resource;
1013 struct wl_global *global;
1016 wl_client_add_object(client, &wl_registry_interface,
1017 ®istry_interface, id, display);
1018 registry_resource->destroy = unbind_resource;
1020 wl_list_insert(&display->registry_resource_list,
1021 ®istry_resource->link);
1023 wl_list_for_each(global, &display->global_list, link)
1024 wl_resource_post_event(registry_resource,
1027 global->interface->name,
1028 global->interface->version);
1031 static const struct wl_display_interface display_interface = {
1033 display_get_registry
1037 destroy_client_display_resource(struct wl_resource *resource)
1039 resource->client->display_resource = NULL;
1044 bind_display(struct wl_client *client,
1045 void *data, uint32_t version, uint32_t id)
1047 struct wl_display *display = data;
1049 client->display_resource =
1050 wl_client_add_object(client, &wl_display_interface,
1051 &display_interface, id, display);
1053 if(client->display_resource)
1054 client->display_resource->destroy = destroy_client_display_resource;
1057 WL_EXPORT struct wl_display *
1058 wl_display_create(void)
1060 struct wl_display *display;
1063 debug = getenv("WAYLAND_DEBUG");
1064 if (debug && (strstr(debug, "server") || strstr(debug, "1")))
1067 display = malloc(sizeof *display);
1068 if (display == NULL)
1071 display->loop = wl_event_loop_create();
1072 if (display->loop == NULL) {
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);
1082 wl_signal_init(&display->destroy_signal);
1085 display->serial = 0;
1087 if (!wl_display_add_global(display, &wl_display_interface,
1088 display, bind_display)) {
1089 wl_event_loop_destroy(display->loop);
1098 wl_display_destroy(struct wl_display *display)
1100 struct wl_socket *s, *next;
1101 struct wl_global *global, *gnext;
1103 wl_signal_emit(&display->destroy_signal, display);
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);
1109 unlink(s->lock_addr);
1113 wl_event_loop_destroy(display->loop);
1115 wl_list_for_each_safe(global, gnext, &display->global_list, link)
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)
1126 struct wl_global *global;
1127 struct wl_resource *resource;
1129 global = malloc(sizeof *global);
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);
1139 wl_list_for_each(resource, &display->registry_resource_list, link)
1140 wl_resource_post_event(resource,
1143 global->interface->name,
1144 global->interface->version);
1150 wl_display_remove_global(struct wl_display *display, struct wl_global *global)
1152 struct wl_resource *resource;
1154 wl_list_for_each(resource, &display->registry_resource_list, link)
1155 wl_resource_post_event(resource, WL_REGISTRY_GLOBAL_REMOVE,
1157 wl_list_remove(&global->link);
1162 wl_display_get_serial(struct wl_display *display)
1164 return display->serial;
1168 wl_display_next_serial(struct wl_display *display)
1172 return display->serial;
1175 WL_EXPORT struct wl_event_loop *
1176 wl_display_get_event_loop(struct wl_display *display)
1178 return display->loop;
1182 wl_display_terminate(struct wl_display *display)
1188 wl_display_run(struct wl_display *display)
1192 while (display->run) {
1193 wl_display_flush_clients(display);
1194 wl_event_loop_dispatch(display->loop, -1);
1199 wl_display_flush_clients(struct wl_display *display)
1201 struct wl_client *client, *next;
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,
1210 } else if (ret < 0) {
1211 wl_client_destroy(client);
1217 socket_data(int fd, uint32_t mask, void *data)
1219 struct wl_display *display = data;
1220 struct sockaddr_un name;
1224 length = sizeof name;
1225 client_fd = wl_os_accept_cloexec(fd, (struct sockaddr *) &name,
1228 wl_log("failed to accept: %m\n");
1230 if (!wl_client_create(display, client_fd))
1237 get_socket_lock(struct wl_socket *socket)
1239 struct stat socket_stat;
1242 snprintf(socket->lock_addr, sizeof socket->lock_addr,
1243 "%s%s", socket->addr.sun_path, LOCK_SUFFIX);
1245 fd_lock = open(socket->lock_addr, O_CREAT | O_CLOEXEC,
1246 (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
1249 wl_log("unable to open lockfile %s check permissions\n",
1254 if (flock(fd_lock, LOCK_EX | LOCK_NB) < 0) {
1255 wl_log("unable to lock lockfile %s, maybe another compositor is running\n",
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);
1268 } else if (socket_stat.st_mode & S_IWUSR ||
1269 socket_stat.st_mode & S_IWGRP) {
1270 unlink(socket->addr.sun_path);
1277 wl_display_add_socket(struct wl_display *display, const char *name)
1279 struct wl_socket *s;
1282 const char *runtime_dir;
1284 runtime_dir = getenv("XDG_RUNTIME_DIR");
1286 wl_log("error: XDG_RUNTIME_DIR not set in the environment\n");
1288 /* to prevent programs reporting
1289 * "failed to add socket: Success" */
1294 s = malloc(sizeof *s);
1298 s->fd = wl_os_socket_cloexec(PF_LOCAL, SOCK_STREAM, 0);
1305 name = getenv("WAYLAND_DISPLAY");
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;
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);
1320 /* to prevent programs reporting
1321 * "failed to add socket: Success" */
1322 errno = ENAMETOOLONG;
1326 wl_log("using socket %s\n", s->addr.sun_path);
1328 s->fd_lock = get_socket_lock(s);
1329 if (s->fd_lock < 0) {
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");
1339 unlink(s->lock_addr);
1345 if (listen(s->fd, 1) < 0) {
1346 wl_log("listen() failed with error: %m\n");
1347 unlink(s->addr.sun_path);
1349 unlink(s->lock_addr);
1355 s->source = wl_event_loop_add_fd(display->loop, s->fd,
1357 socket_data, display);
1358 if (s->source == NULL) {
1359 unlink(s->addr.sun_path);
1361 unlink(s->lock_addr);
1366 wl_list_insert(display->socket_list.prev, &s->link);
1372 wl_display_add_destroy_listener(struct wl_display *display,
1373 struct wl_listener *listener)
1375 wl_signal_add(&display->destroy_signal, listener);
1378 WL_EXPORT struct wl_listener *
1379 wl_display_get_destroy_listener(struct wl_display *display,
1380 wl_notify_func_t notify)
1382 return wl_signal_get(&display->destroy_signal, notify);
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)
1391 struct wl_resource *resource;
1393 resource = malloc(sizeof *resource);
1394 if (resource == NULL) {
1395 wl_resource_post_no_memory(client->display_resource);
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);
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);
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)
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);
1433 wl_log_set_handler_server(wl_log_func_t handler)
1435 wl_log_handler = handler;