Commit e2c0d47b authored by Jasper St. Pierre's avatar Jasper St. Pierre
Browse files

server: Add a simple API to find a good default display

This allows compositors to easily select a good display to listen on.
parent f0401059
......@@ -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;
}
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment