[PATCH weston v3 3/6] Add API to get the list of connected clients

Giulio Camuffo giuliocamuffo at gmail.com
Tue Aug 9 10:46:53 UTC 2016


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 at kdab.com>
Reviewed-by: Jonas Ã…dahl <jadahl at gmail.com>
---

v3: check that the client in the test is the right one

 src/wayland-server-core.h             | 14 +++++++++
 src/wayland-server.c                  | 54 +++++++++++++++++++++++++++++++++++
 tests/compositor-introspection-test.c | 22 ++++++++++++++
 3 files changed, 90 insertions(+)

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);
-- 
2.9.2



More information about the wayland-devel mailing list