mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-10-29 05:40:16 -04:00
server: Add a simple API to find a good default display
This allows compositors to easily select a good display to listen on.
This commit is contained in:
parent
f0401059b9
commit
e2c0d47b0c
2 changed files with 74 additions and 25 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue