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; | ||||
| 	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 && | ||||
|  |  | |||
|  | @ -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; | ||||
| }; | ||||
|  |  | |||
|  | @ -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, | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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, | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue