tests: Handle removal of seat global in test clients

The current test client code completely ignores removal of globals.
This commit updates the code to properly handle removal of globals in
general, and of seat globals in particular. This ensures that the test
client objects are in sync with the server and any relevant resources
are released accordingly.

This update will be used by upcoming tests to check that seat removal
and re-addition is working properly.

Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
This commit is contained in:
Alexandros Frantzis 2018-02-08 15:37:55 +02:00 committed by Pekka Paalanen
parent 8480d13f6d
commit c1937971fb
2 changed files with 75 additions and 9 deletions

View File

@ -538,6 +538,27 @@ static const struct weston_test_listener test_listener = {
test_handle_capture_screenshot_done,
};
static void
input_destroy(struct input *inp)
{
if (inp->pointer) {
wl_pointer_release(inp->pointer->wl_pointer);
free(inp->pointer);
}
if (inp->keyboard) {
wl_keyboard_release(inp->keyboard->wl_keyboard);
free(inp->keyboard);
}
if (inp->touch) {
wl_touch_release(inp->touch->wl_touch);
free(inp->touch);
}
wl_list_remove(&inp->link);
wl_seat_release(inp->wl_seat);
free(inp->seat_name);
free(inp);
}
static void
input_update_devices(struct input *input)
{
@ -705,6 +726,7 @@ handle_global(void *data, struct wl_registry *registry,
&wl_compositor_interface, version);
} else if (strcmp(interface, "wl_seat") == 0) {
input = xzalloc(sizeof *input);
input->global_name = global->name;
input->wl_seat =
wl_registry_bind(registry, id,
&wl_seat_interface, version);
@ -735,8 +757,59 @@ handle_global(void *data, struct wl_registry *registry,
}
}
static struct global *
client_find_global_with_name(struct client *client, uint32_t name)
{
struct global *global;
wl_list_for_each(global, &client->global_list, link) {
if (global->name == name)
return global;
}
return NULL;
}
static struct input *
client_find_input_with_name(struct client *client, uint32_t name)
{
struct input *input;
wl_list_for_each(input, &client->inputs, link) {
if (input->global_name == name)
return input;
}
return NULL;
}
static void
handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
{
struct client *client = data;
struct global *global;
struct input *input;
global = client_find_global_with_name(client, name);
assert(global && "Request to remove unknown global");
if (strcmp(global->interface, "wl_seat") == 0) {
input = client_find_input_with_name(client, name);
if (input) {
if (client->input == input)
client->input = NULL;
input_destroy(input);
}
}
wl_list_remove(&global->link);
free(global->interface);
free(global);
}
static const struct wl_registry_listener registry_listener = {
handle_global
handle_global,
handle_global_remove,
};
void
@ -809,14 +882,6 @@ 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

View File

@ -74,6 +74,7 @@ struct test {
};
struct input {
uint32_t global_name;
struct wl_seat *wl_seat;
struct pointer *pointer;
struct keyboard *keyboard;