diff options
author | Giulio Camuffo <giuliocamuffo@gmail.com> | 2016-08-09 12:46:53 +0200 |
---|---|---|
committer | Pekka Paalanen <pekka.paalanen@collabora.co.uk> | 2016-08-11 15:52:15 +0300 |
commit | 596024f728b0a1292ee69a80dd72a85167870936 (patch) | |
tree | 4f2ea7daf3a7b3b6353f62158c2022e90b9de957 | |
parent | 68abfa6732672ab3534102de55edaa10343f4d1b (diff) |
Add API to get the list of connected clients
This patch chooses the wl_list_for_each-style of iterating over
the clients, instead of using an iterator function, because i think
it is easier to use.
Signed-off-by: Giulio Camuffo <giulio.camuffo@kdab.com>
Reviewed-by: Jonas Ã…dahl <jadahl@gmail.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
-rw-r--r-- | src/wayland-server-core.h | 14 | ||||
-rw-r--r-- | src/wayland-server.c | 54 | ||||
-rw-r--r-- | tests/compositor-introspection-test.c | 22 |
3 files changed, 90 insertions, 0 deletions
diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h index c0d25e9..69c09dc 100644 --- a/src/wayland-server-core.h +++ b/src/wayland-server-core.h @@ -171,6 +171,20 @@ wl_global_destroy(struct wl_global *global); struct wl_client * wl_client_create(struct wl_display *display, int fd); +struct wl_list * +wl_display_get_client_list(struct wl_display *display); + +struct wl_list * +wl_client_get_link(struct wl_client *client); + +struct wl_client * +wl_client_from_link(struct wl_list *link); + +#define wl_client_for_each(client, list) \ + for (client = wl_client_from_link((list)->next); \ + wl_client_get_link(client) != (list); \ + client = wl_client_from_link(wl_client_get_link(client)->next)) + void wl_client_destroy(struct wl_client *client); diff --git a/src/wayland-server.c b/src/wayland-server.c index e2212e2..2dd9a4a 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -1517,6 +1517,60 @@ wl_display_get_additional_shm_formats(struct wl_display *display) return &display->additional_shm_formats; } +/** Get the list of currently connected clients + * + * \param display The display object + * + * This function returns a pointer to the list of clients currently + * connected to the display. You can iterate on the list by using + * the \a wl_client_for_each macro. + * The returned value is valid for the lifetime of the \a display. + * You must not modify the returned list, but only access it. + * + * \sa wl_client_for_each() + * \sa wl_client_get_link() + * \sa wl_client_from_link() + * + * \memberof wl_display + */ +WL_EXPORT struct wl_list * +wl_display_get_client_list(struct wl_display *display) +{ + return &display->client_list; +} + +/** Get the link by which a client is inserted in the client list + * + * \param client The client object + * + * \sa wl_client_for_each() + * \sa wl_display_get_client_list() + * \sa wl_client_from_link() + * + * \memberof wl_client + */ +WL_EXPORT struct wl_list * +wl_client_get_link(struct wl_client *client) +{ + return &client->link; +} + +/** Get a wl_client by its link + * + * \param link The link of a wl_client + * + * \sa wl_client_for_each() + * \sa wl_display_get_client_list() + * \sa wl_client_get_link() + * + * \memberof wl_client + */ +WL_EXPORT struct wl_client * +wl_client_from_link(struct wl_list *link) +{ + return container_of(link, struct wl_client, link); +} + /** \cond */ /* Deprecated functions below. */ uint32_t diff --git a/tests/compositor-introspection-test.c b/tests/compositor-introspection-test.c index 5d2085d..50ff1dd 100644 --- a/tests/compositor-introspection-test.c +++ b/tests/compositor-introspection-test.c @@ -58,6 +58,26 @@ client_created(struct wl_listener *listener, void *data) c->client = data; } +static void +check_client_list(struct compositor *compositor) +{ + struct wl_list *client_list; + struct wl_client *client, *client_it; + int num_clients = 0; + + client_list = wl_display_get_client_list(compositor->display); + wl_client_for_each(client_it, client_list) { + num_clients++; + client = client_it; + } + assert(num_clients == 1); + /* 'client_it' is not valid here, so we took a copy of the client in the loop. + * We could also do this assert in the loop directly, but in case it fails it is + * easier to understand the problem when we know that the previous assert passed, + * so that there is only one client but the wrong one. */ + assert(compositor->client == client); +} + TEST(new_client_connect) { const char *socket; @@ -80,6 +100,8 @@ TEST(new_client_connect) assert(compositor.client != NULL); + check_client_list(&compositor); + wl_display_disconnect(client.display); wl_client_destroy(compositor.client); |