diff options
author | Jasper St. Pierre <jstpierre@mecheye.net> | 2014-05-08 11:01:24 -0400 |
---|---|---|
committer | Jasper St. Pierre <jstpierre@mecheye.net> | 2014-08-05 15:43:00 -0400 |
commit | e2c0d47b0c77f18cd90e9c6eabb358c4d89681c8 (patch) | |
tree | 6fbf4a69ae25cdd04679bac66ae77d13fe40de0b | |
parent | f0401059b9927b0f4c9ac765ec00814ea19c1ee9 (diff) |
server: Add a simple API to find a good default display
This allows compositors to easily select a good display to listen on.
-rw-r--r-- | src/wayland-server.c | 98 | ||||
-rw-r--r-- | src/wayland-server.h | 1 |
2 files changed, 74 insertions, 25 deletions
diff --git a/src/wayland-server.c b/src/wayland-server.c index b3929ed..39d29ec 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -1097,11 +1097,82 @@ wl_socket_init_for_display_name(struct wl_socket *s, const char *name) return 0; } +static int +_wl_display_add_socket(struct wl_display *display, struct wl_socket *s) +{ + socklen_t size; + + s->fd = wl_os_socket_cloexec(PF_LOCAL, SOCK_STREAM, 0); + if (s->fd < 0) { + return -1; + } + + size = offsetof (struct sockaddr_un, sun_path) + strlen(s->addr.sun_path); + if (bind(s->fd, (struct sockaddr *) &s->addr, size) < 0) { + wl_log("bind() failed with error: %m\n"); + return -1; + } + + if (listen(s->fd, 1) < 0) { + wl_log("listen() failed with error: %m\n"); + return -1; + } + + s->source = wl_event_loop_add_fd(display->loop, s->fd, + WL_EVENT_READABLE, + socket_data, display); + if (s->source == NULL) { + return -1; + } + + wl_list_insert(display->socket_list.prev, &s->link); + return 0; +} + +WL_EXPORT const char * +wl_display_add_socket_auto(struct wl_display *display) +{ + struct wl_socket *s; + int displayno = 0; + char display_name[16] = ""; + + /* A reasonable number of maximum default sockets. If + * you need more than this, use the explicit add_socket API. */ + const int MAX_DISPLAYNO = 32; + + s = malloc(sizeof *s); + memset(s, 0, sizeof *s); + if (s == NULL) + return NULL; + + do { + snprintf(display_name, sizeof display_name, "wayland-%d", displayno); + if (wl_socket_init_for_display_name(s, display_name) < 0) { + wl_socket_destroy(s); + return NULL; + } + + if (wl_socket_lock(s) < 0) + continue; + + if (_wl_display_add_socket(display, s) < 0) { + wl_socket_destroy(s); + return NULL; + } + + return s->display_name; + } while (displayno++ < MAX_DISPLAYNO); + + /* Ran out of display names. */ + wl_socket_destroy(s); + errno = EINVAL; + return NULL; +} + WL_EXPORT int wl_display_add_socket(struct wl_display *display, const char *name) { struct wl_socket *s; - socklen_t size; s = malloc(sizeof *s); memset(s, 0, sizeof *s); @@ -1123,34 +1194,11 @@ wl_display_add_socket(struct wl_display *display, const char *name) return -1; } - s->fd = wl_os_socket_cloexec(PF_LOCAL, SOCK_STREAM, 0); - if (s->fd < 0) { + if (_wl_display_add_socket(display, s) < 0) { wl_socket_destroy(s); return -1; } - size = offsetof (struct sockaddr_un, sun_path) + strlen(s->addr.sun_path); - if (bind(s->fd, (struct sockaddr *) &s->addr, size) < 0) { - wl_log("bind() failed with error: %m\n"); - wl_socket_destroy(s); - return -1; - } - - if (listen(s->fd, 1) < 0) { - wl_log("listen() failed with error: %m\n"); - wl_socket_destroy(s); - return -1; - } - - s->source = wl_event_loop_add_fd(display->loop, s->fd, - WL_EVENT_READABLE, - socket_data, display); - if (s->source == NULL) { - wl_socket_destroy(s); - return -1; - } - wl_list_insert(display->socket_list.prev, &s->link); - return 0; } diff --git a/src/wayland-server.h b/src/wayland-server.h index 0a3f2f6..38855c9 100644 --- a/src/wayland-server.h +++ b/src/wayland-server.h @@ -92,6 +92,7 @@ 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); +const char *wl_display_add_socket_auto(struct wl_display *display); void wl_display_terminate(struct wl_display *display); void wl_display_run(struct wl_display *display); void wl_display_flush_clients(struct wl_display *display); |