From 5c7a37f30922d973e176b0eec29bb5fddf241eee Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Fri, 4 May 2018 11:46:32 +0200 Subject: [PATCH] Add tool buttons --- backend/libinput/tablet_tool.c | 5 ++- include/rootston/cursor.h | 1 + include/wlr/types/wlr_tablet_v2.h | 11 ++++++ rootston/seat.c | 19 ++++++++-- types/wlr_tablet_v2.c | 63 +++++++++++++++++++++++++++++-- 5 files changed, 91 insertions(+), 8 deletions(-) diff --git a/backend/libinput/tablet_tool.c b/backend/libinput/tablet_tool.c index 36b64836..3a39f5dc 100644 --- a/backend/libinput/tablet_tool.c +++ b/backend/libinput/tablet_tool.c @@ -263,11 +263,14 @@ void handle_tablet_tool_proximity(struct libinput_event *event, break; case LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN: wlr_event.state = WLR_TABLET_TOOL_PROXIMITY_IN; - handle_tablet_tool_axis(event, libinput_dev); break; } wlr_signal_emit_safe(&wlr_dev->tablet_tool->events.proximity, &wlr_event); + if (libinput_event_tablet_tool_get_proximity_state(tevent) == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN) { + handle_tablet_tool_axis(event, libinput_dev); + } + // If the tool is not unique, libinput will not find it again after the // proximity out, so we should destroy it if (!tool->unique && diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index 0478c3ca..f7410dec 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -41,6 +41,7 @@ struct roots_cursor { struct wl_listener tool_axis; struct wl_listener tool_tip; struct wl_listener tool_proximity; + struct wl_listener tool_button; struct wl_listener request_set_cursor; }; diff --git a/include/wlr/types/wlr_tablet_v2.h b/include/wlr/types/wlr_tablet_v2.h index a07a0177..12995308 100644 --- a/include/wlr/types/wlr_tablet_v2.h +++ b/include/wlr/types/wlr_tablet_v2.h @@ -7,6 +7,9 @@ #include "tablet-unstable-v2-protocol.h" +/* This can probably be even lower,the tools don't have a lot of buttons */ +#define WLR_TABLEt_V2_TOOL_BUTTONS_CAP 16 + struct wlr_tablet_client_v2; struct wlr_tablet_tool_client_v2; struct wlr_tablet_pad_client_v2; @@ -43,6 +46,10 @@ struct wlr_tablet_v2_tablet_tool { struct wlr_surface *focused_surface; struct wl_listener surface_destroy; struct wl_listener client_destroy; + + uint32_t button_serial; + size_t num_buttons; + uint32_t pressed_buttons[WLR_TABLEt_V2_TOOL_BUTTONS_CAP]; }; struct wlr_tablet_v2_tablet_pad { @@ -94,6 +101,10 @@ void wlr_send_tablet_v2_tablet_tool_wheel( void wlr_send_tablet_v2_tablet_tool_proximity_out( struct wlr_tablet_v2_tablet_tool *tool); +uint32_t wlr_send_tablet_v2_tablet_tool_button( + struct wlr_tablet_v2_tablet_tool *tool, uint32_t button, + enum zwp_tablet_pad_v2_button_state state); + uint32_t wlr_send_tablet_v2_tablet_pad_enter( struct wlr_tablet_v2_tablet_pad *pad, struct wlr_tablet_v2_tablet *tablet, diff --git a/rootston/seat.c b/rootston/seat.c index eb909e78..eb1e7e0b 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -140,7 +140,6 @@ static void handle_tablet_tool_position(struct roots_cursor *cursor, } static void handle_tool_axis(struct wl_listener *listener, void *data) { - wlr_log(L_DEBUG, "Tool Axis"); struct roots_cursor *cursor = wl_container_of(listener, cursor, tool_axis); struct roots_desktop *desktop = cursor->seat->input->server->desktop; @@ -148,7 +147,7 @@ static void handle_tool_axis(struct wl_listener *listener, void *data) { struct wlr_event_tablet_tool_axis *event = data; struct roots_tablet_tool_tool *roots_tool = event->tool->data; - if (!roots_tool) { + if (!roots_tool) { // Should this be an assert? wlr_log(L_DEBUG, "Tool Axis, before proximity"); return; } @@ -182,7 +181,6 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) { } static void handle_tablet_tool_tool_destroy(struct wl_listener *listener, void *data) { - wlr_log(L_DEBUG, "Tool destroy"); struct roots_tablet_tool_tool *tool = wl_container_of(listener, tool, tool_destroy); @@ -195,8 +193,18 @@ static void handle_tablet_tool_tool_destroy(struct wl_listener *listener, void * free(tool); } +static void handle_tool_button(struct wl_listener *listener, void *data) { + struct roots_cursor *cursor = + wl_container_of(listener, cursor, tool_button); + struct roots_desktop *desktop = cursor->seat->input->server->desktop; + wlr_idle_notify_activity(desktop->idle, cursor->seat->seat); + struct wlr_event_tablet_tool_button *event = data; + struct roots_tablet_tool_tool *roots_tool = event->tool->data; + + wlr_send_tablet_v2_tablet_tool_button(roots_tool->tablet_v2_tool, event->button, event->state); +} + static void handle_tool_proximity(struct wl_listener *listener, void *data) { - wlr_log(L_DEBUG, "Tool Proximity"); struct roots_cursor *cursor = wl_container_of(listener, cursor, tool_proximity); struct roots_desktop *desktop = cursor->seat->input->server->desktop; @@ -358,6 +366,9 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { wl_signal_add(&wlr_cursor->events.tablet_tool_proximity, &seat->cursor->tool_proximity); seat->cursor->tool_proximity.notify = handle_tool_proximity; + wl_signal_add(&wlr_cursor->events.tablet_tool_button, &seat->cursor->tool_button); + seat->cursor->tool_button.notify = handle_tool_button; + wl_signal_add(&seat->seat->events.request_set_cursor, &seat->cursor->request_set_cursor); seat->cursor->request_set_cursor.notify = handle_request_set_cursor; diff --git a/types/wlr_tablet_v2.c b/types/wlr_tablet_v2.c index 042713b7..104de65f 100644 --- a/types/wlr_tablet_v2.c +++ b/types/wlr_tablet_v2.c @@ -941,6 +941,47 @@ struct wlr_tablet_manager_v2 *wlr_tablet_v2_create(struct wl_display *display) { } /* Actual protocol foo */ +// https://www.geeksforgeeks.org/move-zeroes-end-array/ +static size_t push_zeroes_to_end(uint32_t arr[], size_t n) { + size_t count = 0; + + for (size_t i = 0; i < n; i++) { + if (arr[i] != 0) { + arr[count++] = arr[i]; + } + } + + size_t ret = count; + + while (count < n) { + arr[count++] = 0; + } + + return ret; +} + +static void tablet_tool_button_update(struct wlr_tablet_v2_tablet_tool *tool, + uint32_t button, enum zwp_tablet_pad_v2_button_state state) { + bool found = false; + size_t i = 0; + for (; i < tool->num_buttons; ++i) { + if (tool->pressed_buttons[i] == button) { + found = true; + break; + } + } + + if (button == ZWP_TABLET_PAD_V2_BUTTON_STATE_PRESSED && !found && + tool->num_buttons < WLR_TABLEt_V2_TOOL_BUTTONS_CAP) { + tool->pressed_buttons[tool->num_buttons++] = button; + } + if (button == ZWP_TABLET_PAD_V2_BUTTON_STATE_RELEASED && found) { + tool->pressed_buttons[i] = 0; + tool->num_buttons = push_zeroes_to_end(tool->pressed_buttons, WLR_TABLEt_V2_TOOL_BUTTONS_CAP); + } + + assert(tool->num_buttons <= WLR_TABLEt_V2_TOOL_BUTTONS_CAP); +} static void send_tool_frame(void *data) { struct wlr_tablet_tool_client_v2 *tool = data; @@ -1041,7 +1082,7 @@ void wlr_send_tablet_v2_tablet_tool_proximity_out( } void wlr_send_tablet_v2_tablet_tool_distance( - struct wlr_tablet_v2_tablet_tool *tool, uint32_t distance) { + struct wlr_tablet_v2_tablet_tool *tool, uint32_t distance) { if (tool->current_client) { zwp_tablet_tool_v2_send_distance(tool->current_client->resource, distance); @@ -1050,6 +1091,24 @@ void wlr_send_tablet_v2_tablet_tool_distance( } } +uint32_t wlr_send_tablet_v2_tablet_tool_button( + struct wlr_tablet_v2_tablet_tool *tool, uint32_t button, + enum zwp_tablet_pad_v2_button_state state) { + tablet_tool_button_update(tool, button, state); + + if (tool->current_client) { + uint32_t serial = ++tool->button_serial; + + zwp_tablet_tool_v2_send_button(tool->current_client->resource, + serial, button, state); + queue_tool_frame(tool->current_client); + + return serial; + } + + return 0; +} + void wlr_send_tablet_v2_tablet_tool_wheel( struct wlr_tablet_v2_tablet_tool *tool, double delta, int32_t clicks) { if (tool->current_client) { @@ -1058,10 +1117,8 @@ void wlr_send_tablet_v2_tablet_tool_wheel( queue_tool_frame(tool->current_client); } - } - uint32_t wlr_send_tablet_v2_tablet_pad_enter( struct wlr_tablet_v2_tablet_pad *pad, struct wlr_tablet_v2_tablet *tablet,