From ff4708d4068b220f55f6bb5c3f8afeedcb5f2c3c Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 30 Apr 2018 22:20:39 +0100 Subject: linux-dmabuf: correctly destroy resources --- include/wlr/types/wlr_linux_dmabuf.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/wlr/types/wlr_linux_dmabuf.h b/include/wlr/types/wlr_linux_dmabuf.h index 3fe8e1fc..531e68ab 100644 --- a/include/wlr/types/wlr_linux_dmabuf.h +++ b/include/wlr/types/wlr_linux_dmabuf.h @@ -25,8 +25,7 @@ struct wlr_dmabuf_buffer_attribs { uint64_t modifier[WLR_LINUX_DMABUF_MAX_PLANES]; int fd[WLR_LINUX_DMABUF_MAX_PLANES]; /* set via params_create */ - int32_t width; - int32_t height; + int32_t width, height; uint32_t format; uint32_t flags; }; @@ -61,8 +60,15 @@ struct wlr_dmabuf_buffer *wlr_dmabuf_buffer_from_params_resource( /* the protocol interface */ struct wlr_linux_dmabuf { struct wl_global *wl_global; - struct wl_listener display_destroy; struct wlr_renderer *renderer; + struct wl_list wl_resources; + + struct { + struct wl_signal destroy; + } events; + + struct wl_listener display_destroy; + struct wl_listener renderer_destroy; }; /** -- cgit v1.2.3 From 5d37b14116e61d5f21f72cdfbd979fe92e17e295 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 3 May 2018 20:22:51 +0100 Subject: data-device: make sure resources are correctly destroyed --- include/types/wlr_data_device.h | 3 ++- include/wlr/types/wlr_data_device.h | 8 ++++++ types/data_device/wlr_data_device.c | 52 ++++++++++++++++++++++++++++++------- types/data_device/wlr_data_offer.c | 4 +-- types/data_device/wlr_data_source.c | 5 +++- 5 files changed, 59 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/types/wlr_data_device.h b/include/types/wlr_data_device.h index 4aa53dc0..ee423f80 100644 --- a/include/types/wlr_data_device.h +++ b/include/types/wlr_data_device.h @@ -18,7 +18,8 @@ struct wlr_data_offer *data_offer_create(struct wl_client *client, void data_offer_update_action(struct wlr_data_offer *offer); struct wlr_client_data_source *client_data_source_create( - struct wl_client *client, uint32_t version, uint32_t id); + struct wl_client *client, uint32_t version, uint32_t id, + struct wl_list *resource_list); struct wlr_client_data_source *client_data_source_from_resource( struct wl_resource *resource); struct wlr_data_offer *data_source_send_offer(struct wlr_data_source *source, diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h index 6fb41c29..80d4bc8b 100644 --- a/include/wlr/types/wlr_data_device.h +++ b/include/wlr/types/wlr_data_device.h @@ -15,8 +15,16 @@ wlr_touch_grab_interface wlr_data_device_touch_drag_interface; struct wlr_data_device_manager { struct wl_global *global; + struct wl_list wl_resources; + struct wl_list data_sources; struct wl_listener display_destroy; + + struct { + struct wl_signal destroy; + } events; + + void *data; }; struct wlr_data_offer { diff --git a/types/data_device/wlr_data_device.c b/types/data_device/wlr_data_device.c index fffb2f1b..70ba3bfa 100644 --- a/types/data_device/wlr_data_device.c +++ b/types/data_device/wlr_data_device.c @@ -11,6 +11,8 @@ #include "types/wlr_data_device.h" #include "util/signal.h" +#define DATA_DEVICE_MANAGER_VERSION 3 + static const struct wl_data_device_interface data_device_impl; static struct wlr_seat_client *seat_client_from_data_device_resource( @@ -83,7 +85,7 @@ static const struct wl_data_device_interface data_device_impl = { .release = data_device_release, }; -static void data_device_destroy(struct wl_resource *resource) { +static void data_device_handle_resource_destroy(struct wl_resource *resource) { wl_list_remove(wl_resource_get_link(resource)); } @@ -164,6 +166,15 @@ void wlr_seat_set_selection(struct wlr_seat *seat, } +static const struct wl_data_device_manager_interface data_device_manager_impl; + +static struct wlr_data_device_manager *data_device_manager_from_resource( + struct wl_resource *resource) { + assert(wl_resource_instance_of(resource, &wl_data_device_manager_interface, + &data_device_manager_impl)); + return wl_resource_get_user_data(resource); +} + static void data_device_manager_get_data_device(struct wl_client *client, struct wl_resource *manager_resource, uint32_t id, struct wl_resource *seat_resource) { @@ -178,13 +189,17 @@ static void data_device_manager_get_data_device(struct wl_client *client, return; } wl_resource_set_implementation(resource, &data_device_impl, seat_client, - &data_device_destroy); + &data_device_handle_resource_destroy); wl_list_insert(&seat_client->data_devices, wl_resource_get_link(resource)); } static void data_device_manager_create_data_source(struct wl_client *client, - struct wl_resource *resource, uint32_t id) { - client_data_source_create(client, wl_resource_get_version(resource), id); + struct wl_resource *manager_resource, uint32_t id) { + struct wlr_data_device_manager *manager = + data_device_manager_from_resource(manager_resource); + + client_data_source_create(client, wl_resource_get_version(manager_resource), + id, &manager->data_sources); } static const struct wl_data_device_manager_interface @@ -193,8 +208,15 @@ static const struct wl_data_device_manager_interface .get_data_device = data_device_manager_get_data_device, }; +static void data_device_manager_handle_resource_destroy( + struct wl_resource *resource) { + wl_list_remove(wl_resource_get_link(resource)); +} + static void data_device_manager_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) { + struct wlr_data_device_manager *manager = data; + struct wl_resource *resource = wl_resource_create(client, &wl_data_device_manager_interface, version, id); @@ -202,18 +224,26 @@ static void data_device_manager_bind(struct wl_client *client, wl_client_post_no_memory(client); return; } - wl_resource_set_implementation(resource, &data_device_manager_impl, - NULL, NULL); + manager, data_device_manager_handle_resource_destroy); + + wl_list_insert(&manager->wl_resources, wl_resource_get_link(resource)); } void wlr_data_device_manager_destroy(struct wlr_data_device_manager *manager) { if (!manager) { return; } + wlr_signal_emit_safe(&manager->events.destroy, manager); wl_list_remove(&manager->display_destroy.link); - // TODO: free wl_resources wl_global_destroy(manager->global); + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe(resource, tmp, &manager->wl_resources) { + wl_resource_destroy(resource); + } + wl_resource_for_each_safe(resource, tmp, &manager->data_sources) { + wl_resource_destroy(resource); + } free(manager); } @@ -232,11 +262,15 @@ struct wlr_data_device_manager *wlr_data_device_manager_create( return NULL; } + wl_list_init(&manager->wl_resources); + wl_list_init(&manager->data_sources); + wl_signal_init(&manager->events.destroy); + manager->global = wl_global_create(display, &wl_data_device_manager_interface, - 3, NULL, data_device_manager_bind); + DATA_DEVICE_MANAGER_VERSION, manager, data_device_manager_bind); if (!manager->global) { - wlr_log(L_ERROR, "could not create data device manager wl global"); + wlr_log(L_ERROR, "could not create data device manager wl_global"); free(manager); return NULL; } diff --git a/types/data_device/wlr_data_offer.c b/types/data_device/wlr_data_offer.c index dfaf054c..a5ea9183 100644 --- a/types/data_device/wlr_data_offer.c +++ b/types/data_device/wlr_data_offer.c @@ -145,7 +145,7 @@ static void data_offer_set_actions(struct wl_client *client, data_offer_update_action(offer); } -static void data_offer_resource_destroy(struct wl_resource *resource) { +static void data_offer_handle_resource_destroy(struct wl_resource *resource) { struct wlr_data_offer *offer = data_offer_from_resource(resource); if (!offer->source) { @@ -208,7 +208,7 @@ struct wlr_data_offer *data_offer_create(struct wl_client *client, return NULL; } wl_resource_set_implementation(offer->resource, &data_offer_impl, offer, - data_offer_resource_destroy); + data_offer_handle_resource_destroy); offer->source_destroy.notify = handle_offer_source_destroyed; wl_signal_add(&source->events.destroy, &offer->source_destroy); diff --git a/types/data_device/wlr_data_source.c b/types/data_device/wlr_data_source.c index 7c554d35..bf638f5a 100644 --- a/types/data_device/wlr_data_source.c +++ b/types/data_device/wlr_data_source.c @@ -245,11 +245,13 @@ static void data_source_handle_resource_destroy(struct wl_resource *resource) { struct wlr_client_data_source *source = client_data_source_from_resource(resource); wlr_data_source_finish(&source->source); + wl_list_remove(wl_resource_get_link(source->resource)); free(source); } struct wlr_client_data_source *client_data_source_create( - struct wl_client *client, uint32_t version, uint32_t id) { + struct wl_client *client, uint32_t version, uint32_t id, + struct wl_list *resource_list) { struct wlr_client_data_source *source = calloc(1, sizeof(struct wlr_client_data_source)); if (source == NULL) { @@ -265,6 +267,7 @@ struct wlr_client_data_source *client_data_source_create( } wl_resource_set_implementation(source->resource, &data_source_impl, source, data_source_handle_resource_destroy); + wl_list_insert(resource_list, wl_resource_get_link(source->resource)); source->impl.accept = client_data_source_accept; source->impl.send = client_data_source_send; -- cgit v1.2.3 From d136026a2cf04294368ffc6e69f4bc5c734bd6e9 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 3 May 2018 22:03:44 +0100 Subject: seat: implement inert seat resources --- include/types/wlr_seat.h | 3 + types/seat/wlr_seat.c | 125 +++++++++++++++++++++++++---------------- types/seat/wlr_seat_keyboard.c | 41 +++++++++++++- types/seat/wlr_seat_pointer.c | 64 ++++++++++++++------- types/seat/wlr_seat_touch.c | 30 +++++++++- 5 files changed, 193 insertions(+), 70 deletions(-) (limited to 'include') diff --git a/include/types/wlr_seat.h b/include/types/wlr_seat.h index b76525ec..15f1dc38 100644 --- a/include/types/wlr_seat.h +++ b/include/types/wlr_seat.h @@ -10,11 +10,14 @@ const struct wlr_touch_grab_interface default_touch_grab_impl; void seat_client_create_pointer(struct wlr_seat_client *seat_client, uint32_t version, uint32_t id); +void seat_client_destroy_pointer(struct wl_resource *resource); void seat_client_create_keyboard(struct wlr_seat_client *seat_client, uint32_t version, uint32_t id); +void seat_client_destroy_keyboard(struct wl_resource *resource); void seat_client_create_touch(struct wlr_seat_client *seat_client, uint32_t version, uint32_t id); +void seat_client_destroy_touch(struct wl_resource *resource); #endif diff --git a/types/seat/wlr_seat.c b/types/seat/wlr_seat.c index dc876f04..4a680157 100644 --- a/types/seat/wlr_seat.c +++ b/types/seat/wlr_seat.c @@ -12,11 +12,15 @@ #include "types/wlr_seat.h" #include "util/signal.h" +#define SEAT_VERSION 6 + static void seat_handle_get_pointer(struct wl_client *client, struct wl_resource *seat_resource, uint32_t id) { struct wlr_seat_client *seat_client = wlr_seat_client_from_resource(seat_resource); if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_POINTER)) { + wlr_log(L_ERROR, "Client sent get_pointer on seat without the " + "pointer capability"); return; } @@ -29,6 +33,8 @@ static void seat_handle_get_keyboard(struct wl_client *client, struct wlr_seat_client *seat_client = wlr_seat_client_from_resource(seat_resource); if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_KEYBOARD)) { + wlr_log(L_ERROR, "Client sent get_keyboard on seat without the " + "keyboard capability"); return; } @@ -41,6 +47,8 @@ static void seat_handle_get_touch(struct wl_client *client, struct wlr_seat_client *seat_client = wlr_seat_client_from_resource(seat_resource); if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_TOUCH)) { + wlr_log(L_ERROR, "Client sent get_touch on seat without the " + "touch capability"); return; } @@ -48,7 +56,8 @@ static void seat_handle_get_touch(struct wl_client *client, seat_client_create_touch(seat_client, version, id); } -static void seat_client_resource_destroy(struct wl_resource *seat_resource) { +static void seat_client_handle_resource_destroy( + struct wl_resource *seat_resource) { struct wlr_seat_client *client = wlr_seat_client_from_resource(seat_resource); wlr_signal_emit_safe(&client->events.destroy, client); @@ -120,7 +129,7 @@ static void seat_handle_bind(struct wl_client *client, void *_wlr_seat, wl_list_init(&seat_client->data_devices); wl_list_init(&seat_client->primary_selection_devices); wl_resource_set_implementation(seat_client->wl_resource, &seat_impl, - seat_client, seat_client_resource_destroy); + seat_client, seat_client_handle_resource_destroy); wl_list_insert(&wlr_seat->clients, &seat_client->link); if (version >= WL_SEAT_NAME_SINCE_VERSION) { wl_seat_send_name(seat_client->wl_resource, wlr_seat->name); @@ -170,41 +179,41 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) { } struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) { - struct wlr_seat *wlr_seat = calloc(1, sizeof(struct wlr_seat)); - if (!wlr_seat) { + struct wlr_seat *seat = calloc(1, sizeof(struct wlr_seat)); + if (!seat) { return NULL; } // pointer state - wlr_seat->pointer_state.seat = wlr_seat; - wl_list_init(&wlr_seat->pointer_state.surface_destroy.link); + seat->pointer_state.seat = seat; + wl_list_init(&seat->pointer_state.surface_destroy.link); struct wlr_seat_pointer_grab *pointer_grab = calloc(1, sizeof(struct wlr_seat_pointer_grab)); if (!pointer_grab) { - free(wlr_seat); + free(seat); return NULL; } pointer_grab->interface = &default_pointer_grab_impl; - pointer_grab->seat = wlr_seat; - wlr_seat->pointer_state.default_grab = pointer_grab; - wlr_seat->pointer_state.grab = pointer_grab; + pointer_grab->seat = seat; + seat->pointer_state.default_grab = pointer_grab; + seat->pointer_state.grab = pointer_grab; // keyboard state struct wlr_seat_keyboard_grab *keyboard_grab = calloc(1, sizeof(struct wlr_seat_keyboard_grab)); if (!keyboard_grab) { free(pointer_grab); - free(wlr_seat); + free(seat); return NULL; } keyboard_grab->interface = &default_keyboard_grab_impl; - keyboard_grab->seat = wlr_seat; - wlr_seat->keyboard_state.default_grab = keyboard_grab; - wlr_seat->keyboard_state.grab = keyboard_grab; + keyboard_grab->seat = seat; + seat->keyboard_state.default_grab = keyboard_grab; + seat->keyboard_state.grab = keyboard_grab; - wlr_seat->keyboard_state.seat = wlr_seat; - wl_list_init(&wlr_seat->keyboard_state.surface_destroy.link); + seat->keyboard_state.seat = seat; + wl_list_init(&seat->keyboard_state.surface_destroy.link); // touch state struct wlr_seat_touch_grab *touch_grab = @@ -212,57 +221,58 @@ struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) { if (!touch_grab) { free(pointer_grab); free(keyboard_grab); - free(wlr_seat); + free(seat); return NULL; } touch_grab->interface = &default_touch_grab_impl; - touch_grab->seat = wlr_seat; - wlr_seat->touch_state.default_grab = touch_grab; - wlr_seat->touch_state.grab = touch_grab; + touch_grab->seat = seat; + seat->touch_state.default_grab = touch_grab; + seat->touch_state.grab = touch_grab; - wlr_seat->touch_state.seat = wlr_seat; - wl_list_init(&wlr_seat->touch_state.touch_points); + seat->touch_state.seat = seat; + wl_list_init(&seat->touch_state.touch_points); - struct wl_global *wl_global = wl_global_create(display, - &wl_seat_interface, 6, wlr_seat, seat_handle_bind); - if (!wl_global) { - free(wlr_seat); + seat->wl_global = wl_global_create(display, &wl_seat_interface, + SEAT_VERSION, seat, seat_handle_bind); + if (seat->wl_global == NULL) { + free(touch_grab); + free(pointer_grab); + free(keyboard_grab); + free(seat); return NULL; } - wlr_seat->wl_global = wl_global; - wlr_seat->display = display; - wlr_seat->name = strdup(name); - wl_list_init(&wlr_seat->clients); - wl_list_init(&wlr_seat->drag_icons); + seat->display = display; + seat->name = strdup(name); + wl_list_init(&seat->clients); + wl_list_init(&seat->drag_icons); - wl_signal_init(&wlr_seat->events.start_drag); - wl_signal_init(&wlr_seat->events.new_drag_icon); + wl_signal_init(&seat->events.start_drag); + wl_signal_init(&seat->events.new_drag_icon); - wl_signal_init(&wlr_seat->events.request_set_cursor); + wl_signal_init(&seat->events.request_set_cursor); - wl_signal_init(&wlr_seat->events.selection); - wl_signal_init(&wlr_seat->events.primary_selection); + wl_signal_init(&seat->events.selection); + wl_signal_init(&seat->events.primary_selection); - wl_signal_init(&wlr_seat->events.pointer_grab_begin); - wl_signal_init(&wlr_seat->events.pointer_grab_end); + wl_signal_init(&seat->events.pointer_grab_begin); + wl_signal_init(&seat->events.pointer_grab_end); - wl_signal_init(&wlr_seat->events.keyboard_grab_begin); - wl_signal_init(&wlr_seat->events.keyboard_grab_end); + wl_signal_init(&seat->events.keyboard_grab_begin); + wl_signal_init(&seat->events.keyboard_grab_end); - wl_signal_init(&wlr_seat->events.touch_grab_begin); - wl_signal_init(&wlr_seat->events.touch_grab_end); + wl_signal_init(&seat->events.touch_grab_begin); + wl_signal_init(&seat->events.touch_grab_end); - wl_signal_init(&wlr_seat->events.destroy); + wl_signal_init(&seat->events.destroy); - wlr_seat->display_destroy.notify = handle_display_destroy; - wl_display_add_destroy_listener(display, &wlr_seat->display_destroy); + seat->display_destroy.notify = handle_display_destroy; + wl_display_add_destroy_listener(display, &seat->display_destroy); - return wlr_seat; + return seat; } struct wlr_seat_client *wlr_seat_client_for_wl_client(struct wlr_seat *wlr_seat, struct wl_client *wl_client) { - assert(wlr_seat); struct wlr_seat_client *seat_client; wl_list_for_each(seat_client, &wlr_seat->clients, link) { if (seat_client->client == wl_client) { @@ -275,8 +285,29 @@ struct wlr_seat_client *wlr_seat_client_for_wl_client(struct wlr_seat *wlr_seat, void wlr_seat_set_capabilities(struct wlr_seat *wlr_seat, uint32_t capabilities) { wlr_seat->capabilities = capabilities; + struct wlr_seat_client *client; wl_list_for_each(client, &wlr_seat->clients, link) { + // Make resources inert if necessary + if ((capabilities & WL_SEAT_CAPABILITY_POINTER) == 0) { + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe(resource, tmp, &client->pointers) { + seat_client_destroy_pointer(resource); + } + } + if ((capabilities & WL_SEAT_CAPABILITY_KEYBOARD) == 0) { + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe(resource, tmp, &client->keyboards) { + seat_client_destroy_keyboard(resource); + } + } + if ((capabilities & WL_SEAT_CAPABILITY_TOUCH) == 0) { + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe(resource, tmp, &client->touches) { + seat_client_destroy_touch(resource); + } + } + wl_seat_send_capabilities(client->wl_resource, capabilities); } } diff --git a/types/seat/wlr_seat_keyboard.c b/types/seat/wlr_seat_keyboard.c index 975b195c..77fda68f 100644 --- a/types/seat/wlr_seat_keyboard.c +++ b/types/seat/wlr_seat_keyboard.c @@ -48,8 +48,16 @@ static const struct wl_keyboard_interface keyboard_impl = { .release = keyboard_release, }; +static struct wlr_seat_client *seat_client_from_keyboard_resource( + struct wl_resource *resource) { + assert(wl_resource_instance_of(resource, &wl_keyboard_interface, + &keyboard_impl)); + return wl_resource_get_user_data(resource); +} + static void keyboard_handle_resource_destroy(struct wl_resource *resource) { wl_list_remove(wl_resource_get_link(resource)); + seat_client_destroy_keyboard(resource); } @@ -63,6 +71,10 @@ void wlr_seat_keyboard_send_key(struct wlr_seat *wlr_seat, uint32_t time, uint32_t serial = wl_display_next_serial(wlr_seat->display); struct wl_resource *resource; wl_resource_for_each(resource, &client->keyboards) { + if (seat_client_from_keyboard_resource(resource) == NULL) { + continue; + } + wl_keyboard_send_key(resource, serial, time, key, state); } } @@ -188,6 +200,10 @@ void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat, uint32_t serial = wl_display_next_serial(seat->display); struct wl_resource *resource; wl_resource_for_each(resource, &client->keyboards) { + if (seat_client_from_keyboard_resource(resource) == NULL) { + continue; + } + if (modifiers == NULL) { wl_keyboard_send_modifiers(resource, serial, 0, 0, 0, 0); } else { @@ -223,6 +239,9 @@ void wlr_seat_keyboard_enter(struct wlr_seat *seat, uint32_t serial = wl_display_next_serial(seat->display); struct wl_resource *resource; wl_resource_for_each(resource, &focused_client->keyboards) { + if (seat_client_from_keyboard_resource(resource) == NULL) { + continue; + } wl_keyboard_send_leave(resource, serial, focused_surface->resource); } } @@ -243,6 +262,9 @@ void wlr_seat_keyboard_enter(struct wlr_seat *seat, uint32_t serial = wl_display_next_serial(seat->display); struct wl_resource *resource; wl_resource_for_each(resource, &client->keyboards) { + if (seat_client_from_keyboard_resource(resource) == NULL) { + continue; + } wl_keyboard_send_enter(resource, serial, surface->resource, &keys); } wl_array_release(&keys); @@ -312,6 +334,10 @@ static void seat_client_send_keymap(struct wlr_seat_client *client, // keyboard struct wl_resource *resource; wl_resource_for_each(resource, &client->keyboards) { + if (seat_client_from_keyboard_resource(resource) == NULL) { + continue; + } + wl_keyboard_send_keymap(resource, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keyboard->keymap_fd, keyboard->keymap_size); @@ -326,6 +352,10 @@ static void seat_client_send_repeat_info(struct wlr_seat_client *client, struct wl_resource *resource; wl_resource_for_each(resource, &client->keyboards) { + if (seat_client_from_keyboard_resource(resource) == NULL) { + continue; + } + if (wl_resource_get_version(resource) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) { wl_keyboard_send_repeat_info(resource, @@ -343,7 +373,7 @@ void seat_client_create_keyboard(struct wlr_seat_client *seat_client, return; } wl_resource_set_implementation(resource, &keyboard_impl, seat_client, - &keyboard_handle_resource_destroy); + keyboard_handle_resource_destroy); wl_list_insert(&seat_client->keyboards, wl_resource_get_link(resource)); struct wlr_keyboard *keyboard = seat_client->seat->keyboard_state.keyboard; @@ -353,3 +383,12 @@ void seat_client_create_keyboard(struct wlr_seat_client *seat_client, // TODO possibly handle the case where this keyboard needs an enter // right away } + +void seat_client_destroy_keyboard(struct wl_resource *resource) { + struct wlr_seat_client *seat_client = + seat_client_from_keyboard_resource(resource); + if (seat_client == NULL) { + return; + } + wl_resource_set_user_data(resource, NULL); +} diff --git a/types/seat/wlr_seat_pointer.c b/types/seat/wlr_seat_pointer.c index 344597b5..4a0bcef1 100644 --- a/types/seat/wlr_seat_pointer.c +++ b/types/seat/wlr_seat_pointer.c @@ -64,30 +64,27 @@ static void pointer_set_cursor(struct wl_client *client, int32_t hotspot_x, int32_t hotspot_y) { struct wlr_seat_client *seat_client = seat_client_from_pointer_resource(pointer_resource); + if (seat_client == NULL) { + return; + } + struct wlr_surface *surface = NULL; if (surface_resource != NULL) { surface = wlr_surface_from_resource(surface_resource); - if (wlr_surface_set_role(surface, "wl_pointer-cursor", surface_resource, WL_POINTER_ERROR_ROLE) < 0) { return; } } - struct wlr_seat_pointer_request_set_cursor_event *event = - calloc(1, sizeof(struct wlr_seat_pointer_request_set_cursor_event)); - if (event == NULL) { - return; - } - event->seat_client = seat_client; - event->surface = surface; - event->serial = serial; - event->hotspot_x = hotspot_x; - event->hotspot_y = hotspot_y; - - wlr_signal_emit_safe(&seat_client->seat->events.request_set_cursor, event); - - free(event); + struct wlr_seat_pointer_request_set_cursor_event event = { + .seat_client = seat_client, + .surface = surface, + .serial = serial, + .hotspot_x = hotspot_x, + .hotspot_y = hotspot_y, + }; + wlr_signal_emit_safe(&seat_client->seat->events.request_set_cursor, &event); } static void pointer_release(struct wl_client *client, @@ -102,6 +99,7 @@ static const struct wl_pointer_interface pointer_impl = { static void pointer_handle_resource_destroy(struct wl_resource *resource) { wl_list_remove(wl_resource_get_link(resource)); + seat_client_destroy_pointer(resource); } @@ -112,8 +110,8 @@ bool wlr_seat_pointer_surface_has_focus(struct wlr_seat *wlr_seat, static void seat_pointer_handle_surface_destroy(struct wl_listener *listener, void *data) { - struct wlr_seat_pointer_state *state = wl_container_of( - listener, state, surface_destroy); + struct wlr_seat_pointer_state *state = + wl_container_of(listener, state, surface_destroy); wl_list_remove(&state->surface_destroy.link); wl_list_init(&state->surface_destroy.link); wlr_seat_pointer_clear_focus(state->seat); @@ -121,8 +119,6 @@ static void seat_pointer_handle_surface_destroy(struct wl_listener *listener, void wlr_seat_pointer_enter(struct wlr_seat *wlr_seat, struct wlr_surface *surface, double sx, double sy) { - assert(wlr_seat); - if (wlr_seat->pointer_state.focused_surface == surface) { // this surface already got an enter notify return; @@ -144,6 +140,10 @@ void wlr_seat_pointer_enter(struct wlr_seat *wlr_seat, uint32_t serial = wl_display_next_serial(wlr_seat->display); struct wl_resource *resource; wl_resource_for_each(resource, &focused_client->pointers) { + if (seat_client_from_pointer_resource(resource) == NULL) { + continue; + } + wl_pointer_send_leave(resource, serial, focused_surface->resource); pointer_send_frame(resource); } @@ -154,6 +154,10 @@ void wlr_seat_pointer_enter(struct wlr_seat *wlr_seat, uint32_t serial = wl_display_next_serial(wlr_seat->display); struct wl_resource *resource; wl_resource_for_each(resource, &client->pointers) { + if (seat_client_from_pointer_resource(resource) == NULL) { + continue; + } + wl_pointer_send_enter(resource, serial, surface->resource, wl_fixed_from_double(sx), wl_fixed_from_double(sy)); pointer_send_frame(resource); @@ -189,6 +193,10 @@ void wlr_seat_pointer_send_motion(struct wlr_seat *wlr_seat, uint32_t time, struct wl_resource *resource; wl_resource_for_each(resource, &client->pointers) { + if (seat_client_from_pointer_resource(resource) == NULL) { + continue; + } + wl_pointer_send_motion(resource, time, wl_fixed_from_double(sx), wl_fixed_from_double(sy)); pointer_send_frame(resource); @@ -205,6 +213,10 @@ uint32_t wlr_seat_pointer_send_button(struct wlr_seat *wlr_seat, uint32_t time, uint32_t serial = wl_display_next_serial(wlr_seat->display); struct wl_resource *resource; wl_resource_for_each(resource, &client->pointers) { + if (seat_client_from_pointer_resource(resource) == NULL) { + continue; + } + wl_pointer_send_button(resource, serial, time, button, state); pointer_send_frame(resource); } @@ -220,6 +232,10 @@ void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time, struct wl_resource *resource; wl_resource_for_each(resource, &client->pointers) { + if (seat_client_from_pointer_resource(resource) == NULL) { + continue; + } + if (value) { wl_pointer_send_axis(resource, time, orientation, wl_fixed_from_double(value)); @@ -235,7 +251,6 @@ void wlr_seat_pointer_start_grab(struct wlr_seat *wlr_seat, struct wlr_seat_pointer_grab *grab) { assert(wlr_seat); grab->seat = wlr_seat; - assert(grab->seat); wlr_seat->pointer_state.grab = grab; wlr_signal_emit_safe(&wlr_seat->events.pointer_grab_begin, grab); @@ -312,3 +327,12 @@ void seat_client_create_pointer(struct wlr_seat_client *seat_client, &pointer_handle_resource_destroy); wl_list_insert(&seat_client->pointers, wl_resource_get_link(resource)); } + +void seat_client_destroy_pointer(struct wl_resource *resource) { + struct wlr_seat_client *seat_client = + seat_client_from_pointer_resource(resource); + if (seat_client == NULL) { + return; + } + wl_resource_set_user_data(resource, NULL); +} diff --git a/types/seat/wlr_seat_touch.c b/types/seat/wlr_seat_touch.c index a81369df..489882ba 100644 --- a/types/seat/wlr_seat_touch.c +++ b/types/seat/wlr_seat_touch.c @@ -9,8 +9,8 @@ #include "types/wlr_seat.h" #include "util/signal.h" -static uint32_t default_touch_down(struct wlr_seat_touch_grab *grab, uint32_t time, - struct wlr_touch_point *point) { +static uint32_t default_touch_down(struct wlr_seat_touch_grab *grab, + uint32_t time, struct wlr_touch_point *point) { return wlr_seat_touch_send_down(grab->seat, point->surface, time, point->touch_id, point->sx, point->sy); } @@ -57,6 +57,14 @@ static const struct wl_touch_interface touch_impl = { static void touch_handle_resource_destroy(struct wl_resource *resource) { wl_list_remove(wl_resource_get_link(resource)); + seat_client_destroy_touch(resource); +} + +static struct wlr_seat_client *seat_client_from_touch_resource( + struct wl_resource *resource) { + assert(wl_resource_instance_of(resource, &wl_touch_interface, + &touch_impl)); + return wl_resource_get_user_data(resource); } @@ -273,6 +281,9 @@ uint32_t wlr_seat_touch_send_down(struct wlr_seat *seat, uint32_t serial = wl_display_next_serial(seat->display); struct wl_resource *resource; wl_resource_for_each(resource, &point->client->touches) { + if (seat_client_from_touch_resource(resource) == NULL) { + continue; + } wl_touch_send_down(resource, serial, time, surface->resource, touch_id, wl_fixed_from_double(sx), wl_fixed_from_double(sy)); wl_touch_send_frame(resource); @@ -291,6 +302,9 @@ void wlr_seat_touch_send_up(struct wlr_seat *seat, uint32_t time, int32_t touch_ uint32_t serial = wl_display_next_serial(seat->display); struct wl_resource *resource; wl_resource_for_each(resource, &point->client->touches) { + if (seat_client_from_touch_resource(resource) == NULL) { + continue; + } wl_touch_send_up(resource, serial, time, touch_id); wl_touch_send_frame(resource); } @@ -306,6 +320,9 @@ void wlr_seat_touch_send_motion(struct wlr_seat *seat, uint32_t time, int32_t to struct wl_resource *resource; wl_resource_for_each(resource, &point->client->touches) { + if (seat_client_from_touch_resource(resource) == NULL) { + continue; + } wl_touch_send_motion(resource, time, touch_id, wl_fixed_from_double(sx), wl_fixed_from_double(sy)); wl_touch_send_frame(resource); @@ -333,3 +350,12 @@ void seat_client_create_touch(struct wlr_seat_client *seat_client, &touch_handle_resource_destroy); wl_list_insert(&seat_client->touches, wl_resource_get_link(resource)); } + +void seat_client_destroy_touch(struct wl_resource *resource) { + struct wlr_seat_client *seat_client = + seat_client_from_touch_resource(resource); + if (seat_client == NULL) { + return; + } + wl_resource_set_user_data(resource, NULL); +} -- cgit v1.2.3