diff --git a/clients/dnd.c b/clients/dnd.c index abddd1bb..e6dd0910 100644 --- a/clients/dnd.c +++ b/clients/dnd.c @@ -37,8 +37,6 @@ #include "window.h" -static const char socket_name[] = "\0wayland"; - struct dnd { struct window *window; struct display *display; diff --git a/clients/image.c b/clients/image.c index 8f30c4a4..bb563ede 100644 --- a/clients/image.c +++ b/clients/image.c @@ -38,9 +38,6 @@ #include "window.h" -static const char gem_device[] = "/dev/dri/card0"; -static const char socket_name[] = "\0wayland"; - struct image { struct window *window; struct display *display; diff --git a/clients/screenshot.c b/clients/screenshot.c index 8b7dd8b1..8f444609 100644 --- a/clients/screenshot.c +++ b/clients/screenshot.c @@ -35,8 +35,6 @@ * the compositor and serves as a test bed for implementing client * side marshalling outside libwayland.so */ -static const char socket_name[] = "\0wayland"; - static void handle_global(struct wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data) @@ -54,7 +52,7 @@ int main(int argc, char *argv[]) GSource *source; struct wl_screenshooter *screenshooter; - display = wl_display_connect(socket_name, sizeof socket_name); + display = wl_display_connect(NULL); if (display == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; diff --git a/clients/view.c b/clients/view.c index e6f18573..67149fb7 100644 --- a/clients/view.c +++ b/clients/view.c @@ -42,9 +42,6 @@ #include "window.h" -static const char gem_device[] = "/dev/dri/card0"; -static const char socket_name[] = "\0wayland"; - struct view { struct window *window; struct display *display; diff --git a/clients/window.c b/clients/window.c index c77a8ce0..d03ef4b0 100644 --- a/clients/window.c +++ b/clients/window.c @@ -1337,8 +1337,6 @@ display_handle_global(struct wl_display *display, uint32_t id, } } -static const char socket_name[] = "\0wayland"; - static void display_render_frame(struct display *d) { @@ -1425,7 +1423,7 @@ display_create(int *argc, char **argv[], const GOptionEntry *option_entries) if (d == NULL) return NULL; - d->display = wl_display_connect(socket_name, sizeof socket_name); + d->display = wl_display_connect(NULL); if (d->display == NULL) { fprintf(stderr, "failed to create display: %m\n"); return NULL; diff --git a/compositor/compositor-wayland.c b/compositor/compositor-wayland.c index 98c675bd..e289a292 100644 --- a/compositor/compositor-wayland.c +++ b/compositor/compositor-wayland.c @@ -513,8 +513,6 @@ wayland_compositor_create(struct wl_display *display, int width, int height) struct wayland_compositor *c; struct wl_event_loop *loop; int fd; - char *socket_name, *env; - int socket_name_size; c = malloc(sizeof *c); if (c == NULL) @@ -522,11 +520,7 @@ wayland_compositor_create(struct wl_display *display, int width, int height) memset(c, 0, sizeof *c); - env = getenv("WAYLAND_DISPLAY"); - socket_name_size = asprintf(&socket_name, "%c%s", '\0', env) + 1; - - c->parent.display = wl_display_connect(socket_name, socket_name_size); - free(socket_name); + c->parent.display = wl_display_connect(NULL); if (c->parent.display == NULL) { fprintf(stderr, "failed to create display: %m\n"); diff --git a/compositor/compositor.c b/compositor/compositor.c index ad5b8a77..bca2095a 100644 --- a/compositor/compositor.c +++ b/compositor/compositor.c @@ -37,8 +37,7 @@ /* The plan here is to generate a random anonymous socket name and * advertise that through a service on the session dbus. */ -static const char *option_socket_name = "wayland"; - +static const char *option_socket_name = NULL; static const char *option_background = "background.jpg"; static const char *option_geometry = "1024x640"; static int option_connector = 0; @@ -901,7 +900,7 @@ notify_key(struct wlsc_input_device *device, switch (key | device->modifier_state) { case KEY_BACKSPACE | MODIFIER_CTRL | MODIFIER_ALT: - kill(0, SIGTERM); + wl_display_terminate(device->ec->wl_display); return; } @@ -1396,7 +1395,6 @@ wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display) return 0; } - int main(int argc, char *argv[]) { struct wl_display *display; @@ -1404,8 +1402,6 @@ int main(int argc, char *argv[]) GError *error = NULL; GOptionContext *context; int width, height; - char *socket_name; - int socket_name_size; g_type_init(); /* GdkPixbuf needs this, it seems. */ @@ -1435,16 +1431,14 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - socket_name_size = - asprintf(&socket_name, "%c%s", '\0', option_socket_name) + 1; - - if (wl_display_add_socket(display, socket_name, socket_name_size)) { + if (wl_display_add_socket(display, option_socket_name)) { fprintf(stderr, "failed to add socket: %m\n"); exit(EXIT_FAILURE); } - free(socket_name); wl_display_run(display); + wl_display_destroy(display); + return 0; } diff --git a/wayland/wayland-client.c b/wayland/wayland-client.c index aaf20662..0b0e52ba 100644 --- a/wayland/wayland-client.c +++ b/wayland/wayland-client.c @@ -38,8 +38,6 @@ #include "wayland-util.h" #include "wayland-client.h" -static const char socket_name[] = "\0wayland"; - struct wl_global_listener { wl_display_global_func_t handler; void *data; @@ -330,11 +328,13 @@ static const struct wl_display_listener display_listener = { }; WL_EXPORT struct wl_display * -wl_display_connect(const char *name, size_t name_size) +wl_display_connect(const char *name) { struct wl_display *display; struct sockaddr_un addr; socklen_t size; + const char *runtime_dir; + size_t name_size; display = malloc(sizeof *display); if (display == NULL) @@ -347,8 +347,24 @@ wl_display_connect(const char *name, size_t name_size) return NULL; } + runtime_dir = getenv("XDG_RUNTIME_DIR"); + if (runtime_dir == NULL) { + runtime_dir = "."; + fprintf(stderr, + "XDG_RUNTIME_DIR not set, falling back to %s\n", + runtime_dir); + } + + if (name == NULL) + name = getenv("WAYLAND_DISPLAY"); + if (name == NULL) + name = "wayland-0"; + + memset(&addr, 0, sizeof addr); addr.sun_family = AF_LOCAL; - memcpy(addr.sun_path, name, name_size); + name_size = + snprintf(addr.sun_path, sizeof addr.sun_path, + "%s/%s", runtime_dir, name) + 1; size = offsetof (struct sockaddr_un, sun_path) + name_size; diff --git a/wayland/wayland-client.h b/wayland/wayland-client.h index 6ebf9acd..d207b076 100644 --- a/wayland/wayland-client.h +++ b/wayland/wayland-client.h @@ -37,7 +37,7 @@ typedef int (*wl_display_update_func_t)(uint32_t mask, void *data); typedef void (*wl_display_sync_func_t)(void *data); typedef void (*wl_display_frame_func_t)(void *data, uint32_t time); -struct wl_display *wl_display_connect(const char *name, size_t name_size); +struct wl_display *wl_display_connect(const char *name); void wl_display_destroy(struct wl_display *display); int wl_display_get_fd(struct wl_display *display, wl_display_update_func_t update, void *data); diff --git a/wayland/wayland-server.c b/wayland/wayland-server.c index ad1637d5..41cd0ab0 100644 --- a/wayland/wayland-server.c +++ b/wayland/wayland-server.c @@ -38,6 +38,12 @@ #include "wayland-server-protocol.h" #include "connection.h" +struct wl_socket { + int fd; + struct sockaddr_un addr; + struct wl_list link; +}; + struct wl_client { struct wl_connection *connection; struct wl_event_source *source; @@ -50,12 +56,14 @@ struct wl_display { struct wl_object base; struct wl_event_loop *loop; struct wl_hash_table *objects; + int run; struct wl_list frame_list; uint32_t client_id_range; uint32_t id; struct wl_list global_list; + struct wl_list socket_list; }; struct wl_frame_listener { @@ -425,6 +433,7 @@ wl_display_create(void) wl_list_init(&display->frame_list); wl_list_init(&display->global_list); + wl_list_init(&display->socket_list); display->client_id_range = 256; /* Gah, arbitrary... */ @@ -441,6 +450,23 @@ wl_display_create(void) return display; } +WL_EXPORT void +wl_display_destroy(struct wl_display *display) +{ + struct wl_socket *s, *next; + + wl_event_loop_destroy(display->loop); + wl_hash_table_destroy(display->objects); + + wl_list_for_each_safe(s, next, &display->socket_list, link) { + close(s->fd); + unlink(s->addr.sun_path); + free(s); + } + + free(display); +} + WL_EXPORT void wl_display_add_object(struct wl_display *display, struct wl_object *object) { @@ -483,10 +509,18 @@ wl_display_get_event_loop(struct wl_display *display) return display->loop; } +WL_EXPORT void +wl_display_terminate(struct wl_display *display) +{ + display->run = 0; +} + WL_EXPORT void wl_display_run(struct wl_display *display) { - while (1) + display->run = 1; + + while (display->run) wl_event_loop_dispatch(display->loop, -1); } @@ -507,30 +541,50 @@ socket_data(int fd, uint32_t mask, void *data) } WL_EXPORT int -wl_display_add_socket(struct wl_display *display, - const char *name, size_t name_size) +wl_display_add_socket(struct wl_display *display, const char *name) { - struct sockaddr_un addr; - int sock; - socklen_t size; + struct wl_socket *s; + socklen_t size, name_size; + const char *runtime_dir; - sock = socket(PF_LOCAL, SOCK_STREAM, 0); - if (sock < 0) + s = malloc(sizeof *s); + if (socket == NULL) return -1; - addr.sun_family = AF_LOCAL; - memcpy(addr.sun_path, name, name_size); + s->fd = socket(PF_LOCAL, SOCK_STREAM, 0); + if (s->fd < 0) + return -1; + + runtime_dir = getenv("XDG_RUNTIME_DIR"); + if (runtime_dir == NULL) { + runtime_dir = "."; + fprintf(stderr, + "XDG_RUNTIME_DIR not set, falling back to %s\n", + runtime_dir); + } + + if (name == NULL) + name = getenv("WAYLAND_DISPLAY"); + if (name == NULL) + name = "wayland-0"; + + memset(&s->addr, 0, sizeof s->addr); + s->addr.sun_family = AF_LOCAL; + name_size = snprintf(s->addr.sun_path, sizeof s->addr.sun_path, + "%s/%s", runtime_dir, name) + 1; + fprintf(stderr, "using socket %s\n", s->addr.sun_path); size = offsetof (struct sockaddr_un, sun_path) + name_size; - if (bind(sock, (struct sockaddr *) &addr, size) < 0) + if (bind(s->fd, (struct sockaddr *) &s->addr, size) < 0) return -1; - if (listen(sock, 1) < 0) + if (listen(s->fd, 1) < 0) return -1; - wl_event_loop_add_fd(display->loop, sock, + wl_event_loop_add_fd(display->loop, s->fd, WL_EVENT_READABLE, socket_data, display); + wl_list_insert(display->socket_list.prev, &s->link); return 0; } diff --git a/wayland/wayland-server.h b/wayland/wayland-server.h index 34fea860..c4daa219 100644 --- a/wayland/wayland-server.h +++ b/wayland/wayland-server.h @@ -81,8 +81,10 @@ struct wl_display; struct wl_input_device; struct wl_display *wl_display_create(void); +void wl_display_destroy(struct wl_display *display); struct wl_event_loop *wl_display_get_event_loop(struct wl_display *display); -int wl_display_add_socket(struct wl_display *display, const char *name, size_t name_size); +int wl_display_add_socket(struct wl_display *display, const char *name); +void wl_display_terminate(struct wl_display *display); void wl_display_run(struct wl_display *display); void wl_display_add_object(struct wl_display *display, struct wl_object *object);