From b79d11395c9f8f26287e17e80066fd9034f05266 Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Thu, 17 May 2018 09:59:37 +0200 Subject: [PATCH] Hook up set_cursor in rootston --- include/rootston/seat.h | 1 + include/wlr/types/wlr_tablet_v2.h | 1 + rootston/seat.c | 22 ++++++++++++++++++++++ types/wlr_tablet_v2.c | 27 ++++++++++++++++++++++----- 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/include/rootston/seat.h b/include/rootston/seat.h index 1a0b889a..258c8840 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -118,6 +118,7 @@ struct roots_tablet_tool_tool { struct roots_seat *seat; + struct wl_listener set_cursor; struct wl_listener tool_destroy; struct roots_tablet_tool *current_tablet; diff --git a/include/wlr/types/wlr_tablet_v2.h b/include/wlr/types/wlr_tablet_v2.h index 0be672cb..5de12ec8 100644 --- a/include/wlr/types/wlr_tablet_v2.h +++ b/include/wlr/types/wlr_tablet_v2.h @@ -81,6 +81,7 @@ struct wlr_tablet_v2_event_cursor { uint32_t serial; int32_t hotspot_x; int32_t hotspot_y; + struct wlr_seat_client *seat_client; }; struct wlr_tablet_v2_event_feedback { diff --git a/rootston/seat.c b/rootston/seat.c index 6b12f682..3ca1404e 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -188,6 +188,7 @@ static void handle_tablet_tool_tool_destroy(struct wl_listener *listener, void * wl_list_remove(&tool->tool_link); wl_list_remove(&tool->tool_destroy.link); + wl_list_remove(&tool->set_cursor.link); free(tool); } @@ -203,6 +204,23 @@ static void handle_tool_button(struct wl_listener *listener, void *data) { wlr_send_tablet_v2_tablet_tool_button(roots_tool->tablet_v2_tool, event->button, event->state); } +static void handle_tablet_tool_set_cursor(struct wl_listener *listener, void *data) { + struct roots_tablet_tool_tool *tool = + wl_container_of(listener, tool, set_cursor); + struct wlr_tablet_v2_event_cursor *evt = data; + + + struct wlr_seat_pointer_request_set_cursor_event event = { + .surface = evt->surface, + .hotspot_x = evt->hotspot_x, + .hotspot_y = evt->hotspot_y, + .serial = evt->serial, + .seat_client = evt->seat_client, + }; + + roots_cursor_handle_request_set_cursor(tool->seat->cursor, &event); +} + static void handle_tool_proximity(struct wl_listener *listener, void *data) { struct roots_cursor *cursor = wl_container_of(listener, cursor, tool_proximity); @@ -221,6 +239,10 @@ static void handle_tool_proximity(struct wl_listener *listener, void *data) { cursor->seat->seat, tool); roots_tool->tool_destroy.notify = handle_tablet_tool_tool_destroy; wl_signal_add(&tool->events.destroy, &roots_tool->tool_destroy); + + roots_tool->set_cursor.notify = handle_tablet_tool_set_cursor; + wl_signal_add(&roots_tool->tablet_v2_tool->events.set_cursor, &roots_tool->set_cursor); + wl_list_init(&roots_tool->link); wl_list_init(&roots_tool->tool_link); } diff --git a/types/wlr_tablet_v2.c b/types/wlr_tablet_v2.c index 52089c47..5dec1c5d 100644 --- a/types/wlr_tablet_v2.c +++ b/types/wlr_tablet_v2.c @@ -67,6 +67,7 @@ struct wlr_tablet_tool_client_v2 { struct wl_client *client; struct wl_resource *resource; struct wlr_tablet_v2_tablet_tool *tool; + struct wlr_tablet_seat_client_v2 *seat; uint32_t proximity_serial; @@ -262,24 +263,34 @@ static void handle_wlr_tablet_destroy(struct wl_listener *listener, void *data) free(tablet); } +static const struct wlr_surface_role pointer_cursor_surface_role = { + .name = "wl_pointer-cursor", +}; + static void handle_tablet_tool_v2_set_cursor(struct wl_client *client, - struct wl_resource *resource, - uint32_t serial, + struct wl_resource *resource, uint32_t serial, struct wl_resource *surface_resource, - int32_t hotspot_x, - int32_t hotspot_y) { + 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_surface *surface; + if (surface_resource != NULL) { + surface = wlr_surface_from_resource(surface_resource); + if (!wlr_surface_set_role(surface, &pointer_cursor_surface_role, NULL, + surface_resource, WL_POINTER_ERROR_ROLE)) { + return; + } + } struct wlr_tablet_v2_event_cursor evt = { .surface = surface, .serial = serial, .hotspot_x = hotspot_x, .hotspot_y = hotspot_y, + .seat_client = tool->seat->seat, }; wl_signal_emit(&tool->tool->events.set_cursor, &evt); @@ -324,6 +335,10 @@ static void destroy_tablet_tool(struct wl_resource *resource) { wl_event_source_remove(client->frame_source); } + if (client->tool && client->tool->current_client == client) { + client->tool->current_client = NULL; + } + wl_list_remove(&client->seat_link); wl_list_remove(&client->tool_link); free(client); @@ -337,6 +352,7 @@ static void add_tablet_tool_client(struct wlr_tablet_seat_client_v2 *seat, return; } client->tool = tool; + client->seat = seat; client->resource = wl_resource_create(seat->wl_client, &zwp_tablet_tool_v2_interface, 1, 0); @@ -444,6 +460,7 @@ static void handle_wlr_tablet_tool_destroy(struct wl_listener *listener, void *d wl_list_for_each_safe(pos, tmp, &tool->clients, tool_link) { // XXX: Add a timer/flag to destroy if client is slow? zwp_tablet_tool_v2_send_removed(pos->resource); + pos->tool = NULL; } wl_list_remove(&tool->clients);