diff --git a/backend/libinput/tablet_pad.c b/backend/libinput/tablet_pad.c index f1fb6d7a..579a11cf 100644 --- a/backend/libinput/tablet_pad.c +++ b/backend/libinput/tablet_pad.c @@ -12,23 +12,6 @@ #include "backend/libinput.h" #include "util/signal.h" -//TODO: Move out -static void add_tablet_path(struct wl_list *list, const char *path) { - struct wlr_tablet_path *tablet_path = calloc(1, sizeof(struct wlr_tablet_path)); - - if (!tablet_path) { - return; - } - - tablet_path->path = strdup(path); - if (!tablet_path->path) { - free(tablet_path); - return; - } - - wl_list_insert(list, &tablet_path->link); -} - // FIXME: Decide on how to alloc/count here static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad, struct libinput_device *device, unsigned int index) { @@ -99,9 +82,9 @@ struct wlr_tablet_pad *create_libinput_tablet_pad( wlr_tablet_pad->strip_count = libinput_device_tablet_pad_get_num_strips(libinput_dev); - wl_list_init(&wlr_tablet_pad->paths); + wlr_list_init(&wlr_tablet_pad->paths); struct udev_device *udev = libinput_device_get_udev_device(libinput_dev); - add_tablet_path(&wlr_tablet_pad->paths, udev_device_get_syspath(udev)); + wlr_list_push(&wlr_tablet_pad->paths, strdup(udev_device_get_syspath(udev))); wl_list_init(&wlr_tablet_pad->groups); int groups = libinput_device_tablet_pad_get_num_mode_groups(libinput_dev); diff --git a/backend/libinput/tablet_tool.c b/backend/libinput/tablet_tool.c index 7cecb091..5dc0584c 100644 --- a/backend/libinput/tablet_tool.c +++ b/backend/libinput/tablet_tool.c @@ -13,18 +13,6 @@ #include "backend/libinput.h" #include "util/signal.h" -//TODO: Move out -static void add_tablet_path(struct wl_list *list, const char *path) { - struct wlr_tablet_path *tablet_path = calloc(1, sizeof(struct wlr_tablet_path)); - - if (!tablet_path) { - return; - } - - tablet_path->path = strdup(path); - wl_list_insert(list, &tablet_path->link); -} - struct wlr_libinput_tablet_tool { struct wlr_tablet_tool_tool wlr_tool; @@ -91,9 +79,9 @@ struct wlr_tablet_tool *create_libinput_tablet_tool( } struct wlr_tablet_tool *wlr_tablet_tool = &libinput_tablet_tool->wlr_tool; - wl_list_init(&wlr_tablet_tool->paths); + wlr_list_init(&wlr_tablet_tool->paths); struct udev_device *udev = libinput_device_get_udev_device(libinput_dev); - add_tablet_path(&wlr_tablet_tool->paths, udev_device_get_syspath(udev)); + wlr_list_push(&wlr_tablet_tool->paths, strdup(udev_device_get_syspath(udev))); wlr_tablet_tool->name = strdup(libinput_device_get_name(libinput_dev)); wl_list_init(&libinput_tablet_tool->tools); diff --git a/include/wlr/types/wlr_tablet_pad.h b/include/wlr/types/wlr_tablet_pad.h index ec291c75..23ac464d 100644 --- a/include/wlr/types/wlr_tablet_pad.h +++ b/include/wlr/types/wlr_tablet_pad.h @@ -4,6 +4,7 @@ #include #include #include +#include /* * NOTE: the wlr tablet pad implementation does not currently support tablets @@ -28,7 +29,7 @@ struct wlr_tablet_pad { size_t strip_count; struct wl_list groups; // wlr_tablet_pad_group::link - struct wl_list paths; // wlr_tablet_path::link + struct wlr_list paths; // char * void *data; }; diff --git a/include/wlr/types/wlr_tablet_tool.h b/include/wlr/types/wlr_tablet_tool.h index 114ce98a..71fa0f82 100644 --- a/include/wlr/types/wlr_tablet_tool.h +++ b/include/wlr/types/wlr_tablet_tool.h @@ -4,6 +4,7 @@ #include #include #include +#include /* * Copy+Paste from libinput, but this should neither use libinput, nor @@ -42,11 +43,6 @@ struct wlr_tablet_tool_tool { struct wlr_tablet_tool_impl; -struct wlr_tablet_path { - struct wl_list link; - char *path; -}; - struct wlr_tablet_tool { struct wlr_tablet_tool_impl *impl; @@ -58,7 +54,7 @@ struct wlr_tablet_tool { } events; const char *name; - struct wl_list paths; // wlr_table_path::link + struct wlr_list paths; // char * void *data; }; diff --git a/types/wlr_tablet_pad.c b/types/wlr_tablet_pad.c index f7d6c436..804d6910 100644 --- a/types/wlr_tablet_pad.c +++ b/types/wlr_tablet_pad.c @@ -14,7 +14,14 @@ void wlr_tablet_pad_init(struct wlr_tablet_pad *pad, } void wlr_tablet_pad_destroy(struct wlr_tablet_pad *pad) { - if (pad && pad->impl && pad->impl->destroy) { + if (!pad) { + return; + } + + wlr_list_for_each(&pad->paths, free); + wlr_list_finish(&pad->paths); + + if (pad->impl && pad->impl->destroy) { pad->impl->destroy(pad); } else { free(pad); diff --git a/types/wlr_tablet_tool.c b/types/wlr_tablet_tool.c index f46a5434..85a13832 100644 --- a/types/wlr_tablet_tool.c +++ b/types/wlr_tablet_tool.c @@ -17,6 +17,10 @@ void wlr_tablet_tool_destroy(struct wlr_tablet_tool *tool) { if (!tool) { return; } + + wlr_list_for_each(&tool->paths, free); + wlr_list_finish(&tool->paths); + if (tool->impl && tool->impl->destroy) { tool->impl->destroy(tool); } else { diff --git a/types/wlr_tablet_v2.c b/types/wlr_tablet_v2.c index e05e85f3..52089c47 100644 --- a/types/wlr_tablet_v2.c +++ b/types/wlr_tablet_v2.c @@ -234,9 +234,9 @@ static void add_tablet_client(struct wlr_tablet_seat_client_v2 *seat, } zwp_tablet_v2_send_id(client->resource, tablet->wlr_device->vendor, tablet->wlr_device->product); - struct wlr_tablet_path *path; - wl_list_for_each(path, &tablet->wlr_tool->paths, link) { - zwp_tablet_v2_send_path(client->resource, path->path); + for (size_t i = 0; i < tablet->wlr_tool->paths.length; ++i) { + zwp_tablet_v2_send_path(client->resource, + tablet->wlr_tool->paths.items[i]); } zwp_tablet_v2_send_done(client->resource); @@ -546,6 +546,7 @@ static void destroy_tablet_pad_ring_v2(struct wl_resource *resource) { aux->pad->rings[aux->index] = NULL; free(aux); + wl_resource_set_user_data(resource, NULL); } static void handle_tablet_pad_ring_v2_set_feedback(struct wl_client *client, struct wl_resource *resource, const char *description, @@ -582,6 +583,7 @@ static void destroy_tablet_pad_strip_v2(struct wl_resource *resource) { aux->pad->strips[aux->index] = NULL; free(aux); + wl_resource_set_user_data(resource, NULL); } static void handle_tablet_pad_strip_v2_set_feedback(struct wl_client *client, @@ -631,14 +633,15 @@ static struct zwp_tablet_pad_v2_interface tablet_pad_impl = { }; static void destroy_tablet_pad_group_v2(struct wl_resource *resource) { - struct wlr_tablet_pad_client_v2 *client = wl_resource_get_user_data(resource); + struct tablet_pad_auxiliary_user_data *aux = wl_resource_get_user_data(resource); - for (size_t i = 0; i < client->group_count; ++i) { - if (client->groups[i] == resource) { - client->groups[i] = NULL; - return; - } + if (!aux) { + return; } + + aux->pad->groups[aux->index] = NULL; + free(aux); + wl_resource_set_user_data(resource, NULL); } static void handle_tablet_pad_group_v2_destroy(struct wl_client *client, @@ -659,8 +662,15 @@ static void add_tablet_pad_group(struct wlr_tablet_v2_tablet_pad *pad, wl_client_post_no_memory(client->client); return; } + struct tablet_pad_auxiliary_user_data *user_data = + calloc(1, sizeof(struct tablet_pad_auxiliary_user_data)); + if (!user_data) { + return; + } + user_data->pad = client; + user_data->index = index; wl_resource_set_implementation(client->groups[index], &tablet_pad_group_impl, - client, destroy_tablet_pad_group_v2); + user_data, destroy_tablet_pad_group_v2); zwp_tablet_pad_v2_send_group(client->resource, client->groups[index]); zwp_tablet_pad_group_v2_send_modes(client->groups[index], group->mode_count); @@ -762,9 +772,9 @@ static void add_tablet_pad_client(struct wlr_tablet_seat_client_v2 *seat, if (pad->wlr_pad->button_count) { zwp_tablet_pad_v2_send_buttons(client->resource, pad->wlr_pad->button_count); } - struct wlr_tablet_path *path; - wl_list_for_each(path, &pad->wlr_pad->paths, link) { - zwp_tablet_pad_v2_send_path(client->resource, path->path); + for (size_t i = 0; i < pad->wlr_pad->paths.length; ++i) { + zwp_tablet_pad_v2_send_path(client->resource, + pad->wlr_pad->paths.items[i]); } size_t i = 0; struct wlr_tablet_pad_group *group; @@ -786,6 +796,18 @@ static void handle_wlr_tablet_pad_destroy(struct wl_listener *listener, void *da wl_list_for_each_safe(pos, tmp, &pad->clients, pad_link) { // XXX: Add a timer/flag to destroy if client is slow? zwp_tablet_pad_v2_send_removed(pos->resource); + + for (size_t i = 0; i < pos->group_count; ++i) { + destroy_tablet_pad_group_v2(pos->groups[i]); + } + + for (size_t i = 0; i < pos->strip_count; ++i) { + destroy_tablet_pad_strip_v2(pos->strips[i]); + } + + for (size_t i = 0; i < pos->ring_count; ++i) { + destroy_tablet_pad_ring_v2(pos->rings[i]); + } } wl_list_remove(&pad->clients);