Properly clean up all sub-objects (e.g., weston_pointer_client objects) when a weston_pointer object is destroyed. The clean-up ensures that the server is able to safely handle client requests to any associated pointer resources, which, as a consenquence of a weston_pointer destruction, have now become inert.
The clean-up involves, among other things, unsetting the destroyed weston_pointer object from the user data of pointer resources, and handling this NULL user data case where required. Signed-off-by: Alexandros Frantzis <alexandros.frant...@collabora.com> --- libweston/input.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/libweston/input.c b/libweston/input.c index 94a3423a..01f0d568 100644 --- a/libweston/input.c +++ b/libweston/input.c @@ -105,6 +105,19 @@ weston_pointer_client_create(struct wl_client *client) static void weston_pointer_client_destroy(struct weston_pointer_client *pointer_client) { + struct wl_resource *resource; + + wl_resource_for_each(resource, &pointer_client->pointer_resources) { + wl_resource_set_user_data(resource, NULL); + } + + wl_resource_for_each(resource, + &pointer_client->relative_pointer_resources) { + wl_resource_set_user_data(resource, NULL); + } + + wl_list_remove(&pointer_client->pointer_resources); + wl_list_remove(&pointer_client->relative_pointer_resources); free(pointer_client); } @@ -170,11 +183,14 @@ unbind_pointer_client_resource(struct wl_resource *resource) struct wl_client *client = wl_resource_get_client(resource); struct weston_pointer_client *pointer_client; - pointer_client = weston_pointer_get_pointer_client(pointer, client); - assert(pointer_client); - wl_list_remove(wl_resource_get_link(resource)); - weston_pointer_cleanup_pointer_client(pointer, pointer_client); + + if (pointer) { + pointer_client = weston_pointer_get_pointer_client(pointer, + client); + assert(pointer_client); + weston_pointer_cleanup_pointer_client(pointer, pointer_client); + } } static void unbind_resource(struct wl_resource *resource) @@ -1092,12 +1108,18 @@ weston_pointer_create(struct weston_seat *seat) WL_EXPORT void weston_pointer_destroy(struct weston_pointer *pointer) { + struct weston_pointer_client *pointer_client, *tmp; + wl_signal_emit(&pointer->destroy_signal, pointer); if (pointer->sprite) pointer_unmap_sprite(pointer); - /* XXX: What about pointer->resource_list? */ + wl_list_for_each_safe(pointer_client, tmp, &pointer->pointer_clients, + link) { + wl_list_remove(&pointer_client->link); + weston_pointer_client_destroy(pointer_client); + } wl_list_remove(&pointer->focus_resource_listener.link); wl_list_remove(&pointer->focus_view_listener.link); @@ -2297,6 +2319,9 @@ pointer_set_cursor(struct wl_client *client, struct wl_resource *resource, struct weston_pointer *pointer = wl_resource_get_user_data(resource); struct weston_surface *surface = NULL; + if (!pointer) + return; + if (surface_resource) surface = wl_resource_get_user_data(surface_resource); @@ -3674,6 +3699,9 @@ pointer_constraints_lock_pointer(struct wl_client *client, struct weston_region *region = region_resource ? wl_resource_get_user_data(region_resource) : NULL; + if (!pointer) + return; + init_pointer_constraint(resource, id, surface, pointer, region, lifetime, &zwp_locked_pointer_v1_interface, &locked_pointer_interface, @@ -4467,6 +4495,9 @@ pointer_constraints_confine_pointer(struct wl_client *client, struct weston_region *region = region_resource ? wl_resource_get_user_data(region_resource) : NULL; + if (!pointer) + return; + init_pointer_constraint(resource, id, surface, pointer, region, lifetime, &zwp_confined_pointer_v1_interface, &confined_pointer_interface, -- 2.14.1 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel