From c3c3fc411eec1233f68098c630dd7892fc762308 Mon Sep 17 00:00:00 2001 From: Marek Chalupa Date: Mon, 30 Mar 2015 09:17:40 -0400 Subject: [PATCH] tests: use special seat 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 Reviewed-by: Pekka Paalanen --- 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 67a1ad98..2e424dce 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); @@ -406,6 +407,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) { @@ -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, ®istry_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 9be39d9e..bd60f281 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 eb431f3a..9f1f49b3 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);