Add tool buttons
This commit is contained in:
		
							parent
							
								
									391eef6ea9
								
							
						
					
					
						commit
						5c7a37f309
					
				|  | @ -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; | ||||||
|  | @ -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…
	
		Reference in New Issue