mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Add tool buttons
This commit is contained in:
		
							parent
							
								
									391eef6ea9
								
							
						
					
					
						commit
						5c7a37f309
					
				
					 5 changed files with 91 additions and 8 deletions
				
			
		| 
						 | 
					@ -263,11 +263,14 @@ void handle_tablet_tool_proximity(struct libinput_event *event,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN:
 | 
						case LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN:
 | 
				
			||||||
		wlr_event.state = WLR_TABLET_TOOL_PROXIMITY_IN;
 | 
							wlr_event.state = WLR_TABLET_TOOL_PROXIMITY_IN;
 | 
				
			||||||
		handle_tablet_tool_axis(event, libinput_dev);
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	wlr_signal_emit_safe(&wlr_dev->tablet_tool->events.proximity, &wlr_event);
 | 
						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
 | 
						// If the tool is not unique, libinput will not find it again after the
 | 
				
			||||||
	// proximity out, so we should destroy it
 | 
						// proximity out, so we should destroy it
 | 
				
			||||||
	if (!tool->unique &&
 | 
						if (!tool->unique &&
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,6 +41,7 @@ struct roots_cursor {
 | 
				
			||||||
	struct wl_listener tool_axis;
 | 
						struct wl_listener tool_axis;
 | 
				
			||||||
	struct wl_listener tool_tip;
 | 
						struct wl_listener tool_tip;
 | 
				
			||||||
	struct wl_listener tool_proximity;
 | 
						struct wl_listener tool_proximity;
 | 
				
			||||||
 | 
						struct wl_listener tool_button;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_listener request_set_cursor;
 | 
						struct wl_listener request_set_cursor;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,9 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "tablet-unstable-v2-protocol.h"
 | 
					#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_client_v2;
 | 
				
			||||||
struct wlr_tablet_tool_client_v2;
 | 
					struct wlr_tablet_tool_client_v2;
 | 
				
			||||||
struct wlr_tablet_pad_client_v2;
 | 
					struct wlr_tablet_pad_client_v2;
 | 
				
			||||||
| 
						 | 
					@ -43,6 +46,10 @@ struct wlr_tablet_v2_tablet_tool {
 | 
				
			||||||
	struct wlr_surface *focused_surface;
 | 
						struct wlr_surface *focused_surface;
 | 
				
			||||||
	struct wl_listener surface_destroy;
 | 
						struct wl_listener surface_destroy;
 | 
				
			||||||
	struct wl_listener client_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 {
 | 
					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(
 | 
					void wlr_send_tablet_v2_tablet_tool_proximity_out(
 | 
				
			||||||
	struct wlr_tablet_v2_tablet_tool *tool);
 | 
						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(
 | 
					uint32_t wlr_send_tablet_v2_tablet_pad_enter(
 | 
				
			||||||
		struct wlr_tablet_v2_tablet_pad *pad,
 | 
							struct wlr_tablet_v2_tablet_pad *pad,
 | 
				
			||||||
		struct wlr_tablet_v2_tablet *tablet,
 | 
							struct wlr_tablet_v2_tablet *tablet,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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) {
 | 
					static void handle_tool_axis(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	wlr_log(L_DEBUG, "Tool Axis");
 | 
					 | 
				
			||||||
	struct roots_cursor *cursor =
 | 
						struct roots_cursor *cursor =
 | 
				
			||||||
		wl_container_of(listener, cursor, tool_axis);
 | 
							wl_container_of(listener, cursor, tool_axis);
 | 
				
			||||||
	struct roots_desktop *desktop = cursor->seat->input->server->desktop;
 | 
						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 wlr_event_tablet_tool_axis *event = data;
 | 
				
			||||||
	struct roots_tablet_tool_tool *roots_tool = event->tool->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");
 | 
							wlr_log(L_DEBUG, "Tool Axis, before proximity");
 | 
				
			||||||
		return;
 | 
							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) {
 | 
					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 =
 | 
						struct roots_tablet_tool_tool *tool =
 | 
				
			||||||
		wl_container_of(listener, tool, tool_destroy);
 | 
							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);
 | 
						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) {
 | 
					static void handle_tool_proximity(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	wlr_log(L_DEBUG, "Tool Proximity");
 | 
					 | 
				
			||||||
	struct roots_cursor *cursor =
 | 
						struct roots_cursor *cursor =
 | 
				
			||||||
		wl_container_of(listener, cursor, tool_proximity);
 | 
							wl_container_of(listener, cursor, tool_proximity);
 | 
				
			||||||
	struct roots_desktop *desktop = cursor->seat->input->server->desktop;
 | 
						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);
 | 
						wl_signal_add(&wlr_cursor->events.tablet_tool_proximity, &seat->cursor->tool_proximity);
 | 
				
			||||||
	seat->cursor->tool_proximity.notify = handle_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,
 | 
						wl_signal_add(&seat->seat->events.request_set_cursor,
 | 
				
			||||||
		&seat->cursor->request_set_cursor);
 | 
							&seat->cursor->request_set_cursor);
 | 
				
			||||||
	seat->cursor->request_set_cursor.notify = handle_request_set_cursor;
 | 
						seat->cursor->request_set_cursor.notify = handle_request_set_cursor;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -941,6 +941,47 @@ struct wlr_tablet_manager_v2 *wlr_tablet_v2_create(struct wl_display *display) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Actual protocol foo */
 | 
					/* 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) {
 | 
					static void send_tool_frame(void *data) {
 | 
				
			||||||
	struct wlr_tablet_tool_client_v2 *tool = 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(
 | 
					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) {
 | 
						if (tool->current_client) {
 | 
				
			||||||
		zwp_tablet_tool_v2_send_distance(tool->current_client->resource,
 | 
							zwp_tablet_tool_v2_send_distance(tool->current_client->resource,
 | 
				
			||||||
			distance);
 | 
								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(
 | 
					void wlr_send_tablet_v2_tablet_tool_wheel(
 | 
				
			||||||
	struct wlr_tablet_v2_tablet_tool *tool, double delta, int32_t clicks) {
 | 
						struct wlr_tablet_v2_tablet_tool *tool, double delta, int32_t clicks) {
 | 
				
			||||||
	if (tool->current_client) {
 | 
						if (tool->current_client) {
 | 
				
			||||||
| 
						 | 
					@ -1058,10 +1117,8 @@ void wlr_send_tablet_v2_tablet_tool_wheel(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		queue_tool_frame(tool->current_client);
 | 
							queue_tool_frame(tool->current_client);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
uint32_t wlr_send_tablet_v2_tablet_pad_enter(
 | 
					uint32_t wlr_send_tablet_v2_tablet_pad_enter(
 | 
				
			||||||
		struct wlr_tablet_v2_tablet_pad *pad,
 | 
							struct wlr_tablet_v2_tablet_pad *pad,
 | 
				
			||||||
		struct wlr_tablet_v2_tablet *tablet,
 | 
							struct wlr_tablet_v2_tablet *tablet,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue