diff --git a/backend/libinput/tablet_pad.c b/backend/libinput/tablet_pad.c index bb65adf6..f1fb6d7a 100644 --- a/backend/libinput/tablet_pad.c +++ b/backend/libinput/tablet_pad.c @@ -21,7 +21,11 @@ static void add_tablet_path(struct wl_list *list, const char *path) { } tablet_path->path = strdup(path); - assert(tablet_path->path); + if (!tablet_path->path) { + free(tablet_path); + return; + } + wl_list_insert(list, &tablet_path->link); } diff --git a/backend/libinput/tablet_tool.c b/backend/libinput/tablet_tool.c index a20637c1..f02e045a 100644 --- a/backend/libinput/tablet_tool.c +++ b/backend/libinput/tablet_tool.c @@ -79,11 +79,11 @@ struct wlr_tablet_tool *create_libinput_tablet_tool( assert(libinput_dev); struct wlr_libinput_tablet *libinput_tablet_tool = calloc(1, sizeof(struct wlr_libinput_tablet)); - struct wlr_tablet_tool *wlr_tablet_tool = &libinput_tablet_tool->wlr_tool; - if (!wlr_tablet_tool) { + if (!libinput_tablet_tool) { wlr_log(WLR_ERROR, "Unable to allocate wlr_tablet_tool"); return NULL; } + struct wlr_tablet_tool *wlr_tablet_tool = &libinput_tablet_tool->wlr_tool; wl_list_init(&wlr_tablet_tool->paths); struct udev_device *udev = libinput_device_get_udev_device(libinput_dev); diff --git a/include/wlr/types/wlr_tablet_v2.h b/include/wlr/types/wlr_tablet_v2.h index 12995308..0be672cb 100644 --- a/include/wlr/types/wlr_tablet_v2.h +++ b/include/wlr/types/wlr_tablet_v2.h @@ -50,6 +50,10 @@ struct wlr_tablet_v2_tablet_tool { uint32_t button_serial; size_t num_buttons; uint32_t pressed_buttons[WLR_TABLEt_V2_TOOL_BUTTONS_CAP]; + + struct { + struct wl_signal set_cursor; // struct wlr_tablet_v2_event_cursor + } events; }; struct wlr_tablet_v2_tablet_pad { @@ -64,19 +68,38 @@ struct wlr_tablet_v2_tablet_pad { struct wl_listener pad_destroy; struct wlr_tablet_pad_client_v2 *current_client; + + struct { + struct wl_signal button_feedback; // struct wlr_tablet_v2_event_feedback + struct wl_signal strip_feedback; // struct wlr_tablet_v2_event_feedback + struct wl_signal ring_feedback; // struct wlr_tablet_v2_event_feedback + } events; }; -struct wlr_tablet_v2_tablet *wlr_make_tablet( +struct wlr_tablet_v2_event_cursor { + struct wlr_surface *surface; + uint32_t serial; + int32_t hotspot_x; + int32_t hotspot_y; +}; + +struct wlr_tablet_v2_event_feedback { + const char *description; + size_t index; + uint32_t serial; +}; + +struct wlr_tablet_v2_tablet *wlr_tablet_create( struct wlr_tablet_manager_v2 *manager, struct wlr_seat *wlr_seat, struct wlr_input_device *wlr_device); -struct wlr_tablet_v2_tablet_pad *wlr_make_tablet_pad( +struct wlr_tablet_v2_tablet_pad *wlr_tablet_pad_create( struct wlr_tablet_manager_v2 *manager, struct wlr_seat *wlr_seat, struct wlr_input_device *wlr_device); -struct wlr_tablet_v2_tablet_tool *wlr_make_tablet_tool( +struct wlr_tablet_v2_tablet_tool *wlr_tablet_tool_create( struct wlr_tablet_manager_v2 *manager, struct wlr_seat *wlr_seat, struct wlr_tablet_tool_tool *wlr_tool); diff --git a/rootston/seat.c b/rootston/seat.c index b7bf28fc..6b12f682 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -148,7 +148,7 @@ static void handle_tool_axis(struct wl_listener *listener, void *data) { struct roots_tablet_tool_tool *roots_tool = event->tool->data; if (!roots_tool) { // Should this be an assert? - wlr_log(L_DEBUG, "Tool Axis, before proximity"); + wlr_log(WLR_DEBUG, "Tool Axis, before proximity"); return; } @@ -217,7 +217,8 @@ static void handle_tool_proximity(struct wl_listener *listener, void *data) { roots_tool->seat = cursor->seat; tool->data = roots_tool; roots_tool->tablet_v2_tool = - wlr_make_tablet_tool(desktop->tablet_v2, cursor->seat->seat, tool); + wlr_tablet_tool_create(desktop->tablet_v2, + cursor->seat->seat, tool); roots_tool->tool_destroy.notify = handle_tablet_tool_tool_destroy; wl_signal_add(&tool->events.destroy, &roots_tool->tool_destroy); wl_list_init(&roots_tool->link); @@ -683,7 +684,7 @@ static void handle_pad_tool_destroy(struct wl_listener *listener, void *data) { static void attach_tablet_pad(struct roots_tablet_pad *pad, struct roots_tablet_tool *tool) { - wlr_log(L_DEBUG, "Attaching tablet pad \"%s\" to tablet tool \"%s\"", + wlr_log(WLR_DEBUG, "Attaching tablet pad \"%s\" to tablet tool \"%s\"", pad->device->name, tool->device->name); pad->tablet = tool; @@ -742,7 +743,7 @@ static void seat_add_tablet_pad(struct roots_seat *seat, struct roots_tablet_pad *tablet_pad = calloc(sizeof(struct roots_tablet_pad), 1); if (!tablet_pad) { - wlr_log(L_ERROR, "could not allocate tablet_pad for seat"); + wlr_log(WLR_ERROR, "could not allocate tablet_pad for seat"); return; } @@ -772,7 +773,7 @@ static void seat_add_tablet_pad(struct roots_seat *seat, struct roots_desktop *desktop = seat->input->server->desktop; tablet_pad->tablet_v2_pad = - wlr_make_tablet_pad(desktop->tablet_v2, seat->seat, device); + wlr_tablet_pad_create(desktop->tablet_v2, seat->seat, device); /* Search for a sibling tablet */ if (!wlr_input_device_is_libinput(device)) { @@ -837,7 +838,7 @@ static void seat_add_tablet_tool(struct roots_seat *seat, struct roots_desktop *desktop = seat->input->server->desktop; tablet_tool->tablet_v2 = - wlr_make_tablet(desktop->tablet_v2, seat->seat, device); + wlr_tablet_create(desktop->tablet_v2, seat->seat, device); struct libinput_device_group *group = libinput_device_get_device_group(wlr_libinput_get_device_handle(device)); diff --git a/types/wlr_tablet_v2.c b/types/wlr_tablet_v2.c index 104de65f..e05e85f3 100644 --- a/types/wlr_tablet_v2.c +++ b/types/wlr_tablet_v2.c @@ -2,18 +2,16 @@ #define _POSIX_C_SOURCE 200809L #endif -#include - -#include #include #include -#include #include +#include #include #include #include #include - +#include +#include #include "tablet-unstable-v2-protocol.h" struct wlr_tablet_seat_v2 { @@ -68,6 +66,7 @@ struct wlr_tablet_tool_client_v2 { struct wl_list tool_link; struct wl_client *client; struct wl_resource *resource; + struct wlr_tablet_v2_tablet_tool *tool; uint32_t proximity_serial; @@ -79,6 +78,7 @@ struct wlr_tablet_pad_client_v2 { struct wl_list pad_link; struct wl_client *client; struct wl_resource *resource; + struct wlr_tablet_v2_tablet_pad *pad; uint32_t enter_serial; uint32_t mode_serial; @@ -96,6 +96,11 @@ struct wlr_tablet_pad_client_v2 { struct wl_resource **strips; }; +struct tablet_pad_auxiliary_user_data { + struct wlr_tablet_pad_client_v2 *pad; + size_t index; +}; + static struct zwp_tablet_v2_interface tablet_impl; static struct wlr_tablet_client_v2 *tablet_client_from_resource(struct wl_resource *resource) { @@ -257,12 +262,35 @@ static void handle_wlr_tablet_destroy(struct wl_listener *listener, void *data) free(tablet); } +static void handle_tablet_tool_v2_set_cursor(struct wl_client *client, + struct wl_resource *resource, + uint32_t serial, + struct wl_resource *surface_resource, + int32_t hotspot_x, + int32_t hotspot_y) { + struct wlr_tablet_tool_client_v2 *tool = wl_resource_get_user_data(resource); + if (!tool) { + return; + } + + struct wlr_surface *surface = wlr_surface_from_resource(surface_resource); + + struct wlr_tablet_v2_event_cursor evt = { + .surface = surface, + .serial = serial, + .hotspot_x = hotspot_x, + .hotspot_y = hotspot_y, + }; + + wl_signal_emit(&tool->tool->events.set_cursor, &evt); +} + static void handle_tablet_tool_v2_destroy(struct wl_client *client, struct wl_resource *resource) { wl_resource_destroy(resource); } static struct zwp_tablet_tool_v2_interface tablet_tool_impl = { - .set_cursor = NULL, + .set_cursor = handle_tablet_tool_v2_set_cursor, .destroy = handle_tablet_tool_v2_destroy, }; @@ -308,6 +336,7 @@ static void add_tablet_tool_client(struct wlr_tablet_seat_client_v2 *seat, if (!client) { return; } + client->tool = tool; client->resource = wl_resource_create(seat->wl_client, &zwp_tablet_tool_v2_interface, 1, 0); @@ -372,7 +401,7 @@ static void add_tablet_tool_client(struct wlr_tablet_seat_client_v2 *seat, wl_list_insert(&tool->clients, &client->tool_link); } -struct wlr_tablet_v2_tablet *wlr_make_tablet( +struct wlr_tablet_v2_tablet *wlr_tablet_create( struct wlr_tablet_manager_v2 *manager, struct wlr_seat *wlr_seat, struct wlr_input_device *wlr_device) { @@ -420,10 +449,11 @@ static void handle_wlr_tablet_tool_destroy(struct wl_listener *listener, void *d wl_list_remove(&tool->clients); wl_list_remove(&tool->link); wl_list_remove(&tool->tool_destroy.link); + wl_list_remove(&tool->events.set_cursor.listener_list); free(tool); } -struct wlr_tablet_v2_tablet_tool *wlr_make_tablet_tool( +struct wlr_tablet_v2_tablet_tool *wlr_tablet_tool_create( struct wlr_tablet_manager_v2 *manager, struct wlr_seat *wlr_seat, struct wlr_tablet_tool_tool *wlr_tool) { @@ -452,6 +482,8 @@ struct wlr_tablet_v2_tablet_tool *wlr_make_tablet_tool( add_tablet_tool_client(pos, tool); } + wl_signal_init(&tool->events.set_cursor); + return tool; } @@ -506,14 +538,30 @@ static void handle_tablet_pad_v2_destroy(struct wl_client *client, } static void destroy_tablet_pad_ring_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->ring_count; ++i) { - if (client->rings[i] == resource) { - client->rings[i] = NULL; - return; - } + if (!aux) { + return; } + + aux->pad->rings[aux->index] = NULL; + free(aux); +} +static void handle_tablet_pad_ring_v2_set_feedback(struct wl_client *client, + struct wl_resource *resource, const char *description, + uint32_t serial) { + struct tablet_pad_auxiliary_user_data *aux = wl_resource_get_user_data(resource); + if (!aux) { + return; + } + + struct wlr_tablet_v2_event_feedback evt = { + .serial = serial, + .description = description, + .index = aux->index + }; + + wl_signal_emit(&aux->pad->pad->events.ring_feedback, &evt); } static void handle_tablet_pad_ring_v2_destroy(struct wl_client *client, @@ -522,19 +570,35 @@ static void handle_tablet_pad_ring_v2_destroy(struct wl_client *client, } static struct zwp_tablet_pad_ring_v2_interface tablet_pad_ring_impl = { - .set_feedback = NULL, + .set_feedback = handle_tablet_pad_ring_v2_set_feedback, .destroy = handle_tablet_pad_ring_v2_destroy, }; static void destroy_tablet_pad_strip_v2(struct wl_resource *resource) { - struct wlr_tablet_pad_client_v2 *client = wl_resource_get_user_data(resource); - - for (size_t i = 0; i < client->strip_count; ++i) { - if (client->strips[i] == resource) { - client->strips[i] = NULL; - return; - } + struct tablet_pad_auxiliary_user_data *aux = wl_resource_get_user_data(resource); + if (!aux) { + return; } + + aux->pad->strips[aux->index] = NULL; + free(aux); +} + +static void handle_tablet_pad_strip_v2_set_feedback(struct wl_client *client, + struct wl_resource *resource, const char *description, + uint32_t serial) { + struct tablet_pad_auxiliary_user_data *aux = wl_resource_get_user_data(resource); + if (!aux) { + return; + } + + struct wlr_tablet_v2_event_feedback evt = { + .serial = serial, + .description = description, + .index = aux->index + }; + + wl_signal_emit(&aux->pad->pad->events.strip_feedback, &evt); } static void handle_tablet_pad_strip_v2_destroy(struct wl_client *client, @@ -543,12 +607,26 @@ static void handle_tablet_pad_strip_v2_destroy(struct wl_client *client, } static struct zwp_tablet_pad_strip_v2_interface tablet_pad_strip_impl = { - .set_feedback = NULL, + .set_feedback = handle_tablet_pad_strip_v2_set_feedback, .destroy = handle_tablet_pad_strip_v2_destroy, }; +static void handle_tablet_pad_v2_set_feedback( struct wl_client *client, + struct wl_resource *resource, uint32_t button, + const char *description, uint32_t serial) { + struct wlr_tablet_v2_tablet_pad *pad = wl_resource_get_user_data(resource); + + struct wlr_tablet_v2_event_feedback evt = { + .serial = serial, + .index = button, + .description = description, + }; + + wl_signal_emit(&pad->events.button_feedback, &evt); +} + static struct zwp_tablet_pad_v2_interface tablet_pad_impl = { - .set_feedback = NULL, + .set_feedback = handle_tablet_pad_v2_set_feedback, .destroy = handle_tablet_pad_v2_destroy, }; @@ -597,22 +675,34 @@ static void add_tablet_pad_group(struct wlr_tablet_v2_tablet_pad *pad, client->strip_count = group->strip_count; for (size_t i = 0; i < group->strip_count; ++i) { size_t strip = group->strips[i]; + struct tablet_pad_auxiliary_user_data *user_data = + calloc(1, sizeof(struct tablet_pad_auxiliary_user_data)); + if (!user_data) { + continue; + } + user_data->pad = client; + user_data->index = strip; client->strips[strip] = wl_resource_create(client->client, &zwp_tablet_pad_strip_v2_interface, 1, 0); wl_resource_set_implementation(client->strips[strip], - &tablet_pad_strip_impl, - client, destroy_tablet_pad_strip_v2); + &tablet_pad_strip_impl, user_data, destroy_tablet_pad_strip_v2); zwp_tablet_pad_group_v2_send_strip(client->groups[index], client->strips[strip]); } client->ring_count = group->ring_count; for (size_t i = 0; i < group->ring_count; ++i) { size_t ring = group->rings[i]; + struct tablet_pad_auxiliary_user_data *user_data = + calloc(1, sizeof(struct tablet_pad_auxiliary_user_data)); + if (!user_data) { + continue; + } + user_data->pad = client; + user_data->index = ring; client->rings[ring] = wl_resource_create(client->client, &zwp_tablet_pad_ring_v2_interface, 1, 0); wl_resource_set_implementation(client->rings[ring], - &tablet_pad_ring_impl, - client, destroy_tablet_pad_ring_v2); + &tablet_pad_ring_impl, user_data, destroy_tablet_pad_ring_v2); zwp_tablet_pad_group_v2_send_ring(client->groups[index], client->rings[ring]); } @@ -627,6 +717,7 @@ static void add_tablet_pad_client(struct wlr_tablet_seat_client_v2 *seat, wl_client_post_no_memory(seat->wl_client); return; } + client->pad = pad; client->groups = calloc(sizeof(int), wl_list_length(&pad->wlr_pad->groups)); if (!client->groups) { @@ -700,10 +791,13 @@ static void handle_wlr_tablet_pad_destroy(struct wl_listener *listener, void *da wl_list_remove(&pad->clients); wl_list_remove(&pad->link); wl_list_remove(&pad->pad_destroy.link); + wl_list_remove(&pad->events.button_feedback.listener_list); + wl_list_remove(&pad->events.strip_feedback.listener_list); + wl_list_remove(&pad->events.ring_feedback.listener_list); free(pad); } -struct wlr_tablet_v2_tablet_pad *wlr_make_tablet_pad( +struct wlr_tablet_v2_tablet_pad *wlr_tablet_pad_create( struct wlr_tablet_manager_v2 *manager, struct wlr_seat *wlr_seat, struct wlr_input_device *wlr_device) { @@ -739,6 +833,10 @@ struct wlr_tablet_v2_tablet_pad *wlr_make_tablet_pad( add_tablet_pad_client(pos, pad); } + wl_signal_init(&pad->events.button_feedback); + wl_signal_init(&pad->events.strip_feedback); + wl_signal_init(&pad->events.ring_feedback); + return pad; }