[PATCH weston v2] tests: use special seat

Marek Chalupa mchqwerty at gmail.com
Mon Mar 30 06:17:40 PDT 2015


When running on different backends, we don't know what devices
the backend provides. Create new seat for tests that contains
everything what we need. This is also first step in adding
touch support for tests.

v2: do not add devices in wl_seat.name event. Collect first
    all wl_seats and then pick the one that we need and
    destroy the rest. The effect is the same, but this code
    is better understandable.

Signed-off-by: Marek Chalupa <mchqwerty at gmail.com>
---
 tests/weston-test-client-helper.c | 77 +++++++++++++++++++++++++++++++++------
 tests/weston-test-client-helper.h |  9 +++++
 tests/weston-test.c               | 18 +++++----
 3 files changed, 85 insertions(+), 19 deletions(-)

diff --git a/tests/weston-test-client-helper.c b/tests/weston-test-client-helper.c
index 67a1ad9..2e424dc 100644
--- a/tests/weston-test-client-helper.c
+++ b/tests/weston-test-client-helper.c
@@ -372,13 +372,14 @@ static const struct weston_test_listener test_listener = {
 };
 
 static void
-seat_handle_capabilities(void *data, struct wl_seat *seat,
-			 enum wl_seat_capability caps)
+input_update_devices(struct input *input)
 {
-	struct input *input = data;
 	struct pointer *pointer;
 	struct keyboard *keyboard;
 
+	struct wl_seat *seat = input->wl_seat;
+	enum wl_seat_capability caps = input->caps;
+
 	if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
 		pointer = xzalloc(sizeof *pointer);
 		pointer->wl_pointer = wl_seat_get_pointer(seat);
@@ -407,6 +408,24 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
 }
 
 static void
+seat_handle_capabilities(void *data, struct wl_seat *seat,
+			 enum wl_seat_capability caps)
+{
+	struct input *input = data;
+
+	input->caps = caps;
+
+	/* we will create/update the devices only with the right (test) seat.
+	 * If we haven't discovered which seat is the test seat, just
+	 * store capabilities and bail out */
+	if(input->seat_name && strcmp(input->seat_name, "test-seat") == 0)
+		input_update_devices(input);
+
+	fprintf(stderr, "test-client: got seat %p capabilities: %x\n",
+		input, caps);
+}
+
+static void
 seat_handle_name(void *data, struct wl_seat *seat, const char *name)
 {
 	struct input *input = data;
@@ -414,7 +433,8 @@ seat_handle_name(void *data, struct wl_seat *seat, const char *name)
 	input->seat_name = strdup(name);
 	assert(input->seat_name && "No memory");
 
-	fprintf(stderr, "test-client: got seat name: %s\n", name);
+	fprintf(stderr, "test-client: got seat %p name: \'%s\'\n",
+		input, name);
 }
 
 static const struct wl_seat_listener seat_listener = {
@@ -486,10 +506,10 @@ handle_global(void *data, struct wl_registry *registry,
 	      uint32_t id, const char *interface, uint32_t version)
 {
 	struct client *client = data;
-	struct input *input;
 	struct output *output;
 	struct test *test;
 	struct global *global;
+	struct input *input;
 
 	global = xzalloc(sizeof *global);
 	global->name = id;
@@ -508,7 +528,7 @@ handle_global(void *data, struct wl_registry *registry,
 			wl_registry_bind(registry, id,
 					 &wl_seat_interface, version);
 		wl_seat_add_listener(input->wl_seat, &seat_listener, input);
-		client->input = input;
+		wl_list_insert(&client->inputs, &input->link);
 	} else if (strcmp(interface, "wl_shm") == 0) {
 		client->wl_shm =
 			wl_registry_bind(registry, id,
@@ -608,6 +628,34 @@ log_handler(const char *fmt, va_list args)
 	vfprintf(stderr, fmt, args);
 }
 
+static void
+input_destroy(struct input *inp)
+{
+	wl_list_remove(&inp->link);
+	wl_seat_destroy(inp->wl_seat);
+	free(inp);
+}
+
+/* find the test-seat and set it in client.
+ * Destroy other inputs */
+static void
+client_set_input(struct client *cl)
+{
+	struct input *inp, *inptmp;
+	wl_list_for_each_safe(inp, inptmp, &cl->inputs, link) {
+		assert(inp->seat_name && "BUG: input with no name");
+		if (strcmp(inp->seat_name, "test-seat") == 0) {
+			cl->input = inp;
+			input_update_devices(inp);
+		} else {
+			input_destroy(inp);
+		}
+	}
+
+	/* we keep only one input */
+	assert(wl_list_length(&cl->inputs) == 1);
+}
+
 struct client *
 client_create(int x, int y, int width, int height)
 {
@@ -621,16 +669,20 @@ client_create(int x, int y, int width, int height)
 	client->wl_display = wl_display_connect(NULL);
 	assert(client->wl_display);
 	wl_list_init(&client->global_list);
+	wl_list_init(&client->inputs);
 
 	/* setup registry so we can bind to interfaces */
 	client->wl_registry = wl_display_get_registry(client->wl_display);
 	wl_registry_add_listener(client->wl_registry, &registry_listener, client);
 
-	/* trigger global listener. Need to dispatch two times, because wl_shm
-	 * will emit new events after binding and we need them to arrive
-	 * before continuing */
-	wl_display_roundtrip(client->wl_display);
-	wl_display_roundtrip(client->wl_display);
+	/* this roundtrip makes sure we have all globals and we bound to them */
+	client_roundtrip(client);
+	/* this roundtrip makes sure we got all wl_shm.format and wl_seat.*
+	 * events */
+	client_roundtrip(client);
+
+	/* find the right input for us */
+	client_set_input(client);
 
 	/* must have WL_SHM_FORMAT_ARGB32 */
 	assert(client->has_argb);
@@ -644,6 +696,9 @@ client_create(int x, int y, int width, int height)
 	/* the output must be initialized */
 	assert(client->output->initialized == 1);
 
+	/* must have seat set */
+	assert(client->input);
+
 	/* initialize the client surface */
 	surface = xzalloc(sizeof *surface);
 	surface->wl_surface =
diff --git a/tests/weston-test-client-helper.h b/tests/weston-test-client-helper.h
index 9be39d9..bd60f28 100644
--- a/tests/weston-test-client-helper.h
+++ b/tests/weston-test-client-helper.h
@@ -36,7 +36,14 @@ struct client {
 	struct wl_compositor *wl_compositor;
 	struct wl_shm *wl_shm;
 	struct test *test;
+	/* the seat that is actually used for input events */
 	struct input *input;
+	/* server can have more wl_seats. We need keep them all until we
+	 * find the one that we need. After that, the others
+	 * will be destroyed, so this list will have the length of 1.
+	 * If some day in the future we will need the other seats,
+	 * we can just keep them here. */
+	struct wl_list inputs;
 	struct output *output;
 	struct surface *surface;
 	int has_argb;
@@ -63,6 +70,8 @@ struct input {
 	struct pointer *pointer;
 	struct keyboard *keyboard;
 	char *seat_name;
+	enum wl_seat_capability caps;
+	struct wl_list link;
 };
 
 struct pointer {
diff --git a/tests/weston-test.c b/tests/weston-test.c
index eb431f3..9f1f49b 100644
--- a/tests/weston-test.c
+++ b/tests/weston-test.c
@@ -41,6 +41,7 @@ struct weston_test {
 	struct weston_compositor *compositor;
 	struct weston_layer layer;
 	struct weston_process process;
+	struct weston_seat seat;
 };
 
 struct weston_test_surface {
@@ -70,14 +71,7 @@ test_client_sigchld(struct weston_process *process, int status)
 static struct weston_seat *
 get_seat(struct weston_test *test)
 {
-	struct wl_list *seat_list;
-	struct weston_seat *seat;
-
-	seat_list = &test->compositor->seat_list;
-	assert(wl_list_length(seat_list) == 1);
-	seat = container_of(seat_list->next, struct weston_seat, link);
-
-	return seat;
+	return &test->seat;
 }
 
 static void
@@ -349,6 +343,14 @@ module_init(struct weston_compositor *ec,
 			     test, bind_test) == NULL)
 		return -1;
 
+	/* create our own seat */
+	weston_seat_init(&test->seat, ec, "test-seat");
+
+	/* add devices */
+	weston_seat_init_pointer(&test->seat);
+	weston_seat_init_keyboard(&test->seat, NULL);
+	weston_seat_init_touch(&test->seat);
+
 	loop = wl_display_get_event_loop(ec->wl_display);
 	wl_event_loop_add_idle(loop, idle_launch_client, test);
 
-- 
2.1.0



More information about the wayland-devel mailing list