mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-10-29 05:40:12 -04:00 
			
		
		
		
	backend/wayland/tablet_v2: give wlr_tablet_* ownership to wlr_wl_seat
This commit is contained in:
		
							parent
							
								
									d3fb44314c
								
							
						
					
					
						commit
						56f7c000b5
					
				
					 4 changed files with 262 additions and 255 deletions
				
			
		|  | @ -418,7 +418,7 @@ static bool backend_start(struct wlr_backend *backend) { | |||
| 		} | ||||
| 
 | ||||
| 		if (wl->tablet_manager) { | ||||
| 			wl_add_tablet_seat(wl->tablet_manager, seat); | ||||
| 			init_seat_tablet(seat); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -255,6 +255,9 @@ void destroy_wl_seats(struct wlr_wl_backend *wl) { | |||
| 			wl_keyboard_release(seat->wl_keyboard); | ||||
| 			wlr_keyboard_finish(&seat->wlr_keyboard); | ||||
| 		} | ||||
| 		if (seat->zwp_tablet_seat_v2) { | ||||
| 			finish_seat_tablet(seat); | ||||
| 		} | ||||
| 
 | ||||
| 		free(seat->name); | ||||
| 		assert(seat->wl_seat); | ||||
|  | @ -281,9 +284,9 @@ bool wlr_input_device_is_wl(struct wlr_input_device *dev) { | |||
| 	case WLR_INPUT_DEVICE_TOUCH: | ||||
| 		return dev->touch->impl == &touch_impl; | ||||
| 	case WLR_INPUT_DEVICE_TABLET_TOOL: | ||||
| 		return dev->tablet->impl == &tablet_impl; | ||||
| 		return dev->tablet->impl == &wl_tablet_impl; | ||||
| 	case WLR_INPUT_DEVICE_TABLET_PAD: | ||||
| 		return dev->tablet_pad->impl == &tablet_pad_impl; | ||||
| 		return dev->tablet_pad->impl == &wl_tablet_pad_impl; | ||||
| 	default: | ||||
| 		return false; | ||||
| 	} | ||||
|  | @ -318,11 +321,13 @@ struct wlr_wl_input_device *create_wl_input_device( | |||
| 		free(dev); | ||||
| 		return NULL; | ||||
| 	case WLR_INPUT_DEVICE_TABLET_TOOL: | ||||
| 		type_name = "tablet-tool"; | ||||
| 		break; | ||||
| 		wlr_log(WLR_ERROR, "can't create tablet tool wlr_wl_input_device"); | ||||
| 		free(dev); | ||||
| 		return NULL; | ||||
| 	case WLR_INPUT_DEVICE_TABLET_PAD: | ||||
| 		type_name = "tablet-pad"; | ||||
| 		break; | ||||
| 		wlr_log(WLR_ERROR, "can't create tablet pad wlr_wl_input_device"); | ||||
| 		free(dev); | ||||
| 		return NULL; | ||||
| 	default: | ||||
| 		wlr_log(WLR_ERROR, "device not handled"); | ||||
| 		free(dev); | ||||
|  | @ -355,12 +360,10 @@ void destroy_wl_input_device(struct wlr_wl_input_device *dev) { | |||
| 			wlr_log(WLR_ERROR, "wlr_wl_input_device has no pointer"); | ||||
| 			break; | ||||
| 		case WLR_INPUT_DEVICE_TABLET_PAD: | ||||
| 			wlr_tablet_pad_finish(wlr_dev->tablet_pad); | ||||
| 			free(wlr_dev->tablet_pad); | ||||
| 			wlr_log(WLR_ERROR, "wlr_wl_input_device has no tablet pad"); | ||||
| 			break; | ||||
| 		case WLR_INPUT_DEVICE_TABLET_TOOL: | ||||
| 			wlr_tablet_finish(wlr_dev->tablet); | ||||
| 			free(wlr_dev->tablet); | ||||
| 			wlr_log(WLR_ERROR, "wlr_wl_input_device has no tablet_tool"); | ||||
| 			break; | ||||
| 		case WLR_INPUT_DEVICE_TOUCH: | ||||
| 			wlr_log(WLR_ERROR, "wlr_wl_input_device has no touch"); | ||||
|  |  | |||
|  | @ -1,35 +1,25 @@ | |||
| #ifndef _POSIX_C_SOURCE | ||||
| #define _POSIX_C_SOURCE 200809L | ||||
| #endif | ||||
| 
 | ||||
| #include <wayland-util.h> | ||||
| #include <assert.h> | ||||
| #include <math.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <wlr/interfaces/wlr_tablet_pad.h> | ||||
| #include <wlr/interfaces/wlr_tablet_tool.h> | ||||
| #include <wlr/types/wlr_input_device.h> | ||||
| 
 | ||||
| #include "util/signal.h" | ||||
| #include "util/time.h" | ||||
| #include "wlr/util/log.h" | ||||
| #include "tablet-unstable-v2-client-protocol.h" | ||||
| #include <wlr/util/log.h> | ||||
| 
 | ||||
| #include "backend/wayland.h" | ||||
| #include "util/signal.h" | ||||
| #include "util/time.h" | ||||
| 
 | ||||
| struct wlr_wl_tablet_seat { | ||||
| 	struct zwp_tablet_seat_v2 *tablet_seat; | ||||
| }; | ||||
| #include "tablet-unstable-v2-client-protocol.h" | ||||
| 
 | ||||
| struct wlr_wl_tablet_tool { | ||||
| struct tablet_tool { | ||||
| 	/* static */ | ||||
| 	struct zwp_tablet_tool_v2 *tool; | ||||
| 	struct wlr_tablet_tool wlr_tool; | ||||
| 	struct wlr_wl_seat *seat; | ||||
| 
 | ||||
| 	/* semi-static */ | ||||
| 	struct wlr_wl_output *output; | ||||
| 	struct wlr_wl_input_device *tablet; | ||||
| 	double pre_x, pre_y; | ||||
| 
 | ||||
| 	/* per frame */ | ||||
|  | @ -49,11 +39,11 @@ struct wlr_wl_tablet_tool { | |||
| 	bool is_down; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_wl_tablet_pad_ring { | ||||
| 	struct wl_list link; // wlr_wl_tablet_pad_group::rings
 | ||||
| struct tablet_pad_ring { | ||||
| 	struct wl_list link; // tablet_pad_group::rings
 | ||||
| 	/* static */ | ||||
| 	struct zwp_tablet_pad_ring_v2 *ring; | ||||
| 	struct wlr_wl_tablet_pad_group *group; | ||||
| 	struct tablet_pad_group *group; | ||||
| 	size_t index; | ||||
| 
 | ||||
| 	/* per frame */ | ||||
|  | @ -62,10 +52,10 @@ struct wlr_wl_tablet_pad_ring { | |||
| 	bool stopped; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_wl_tablet_pad_strip { | ||||
| 	struct wl_list link; // wlr_wl_tablet_pad_group::strips
 | ||||
| struct tablet_pad_strip { | ||||
| 	struct wl_list link; // tablet_pad_group::strips
 | ||||
| 	struct zwp_tablet_pad_strip_v2 *strip; | ||||
| 	struct wlr_wl_tablet_pad_group *group; | ||||
| 	struct tablet_pad_group *group; | ||||
| 	size_t index; | ||||
| 
 | ||||
| 	enum wlr_tablet_pad_strip_source source; | ||||
|  | @ -73,41 +63,41 @@ struct wlr_wl_tablet_pad_strip { | |||
| 	bool stopped; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_wl_tablet_pad_group { | ||||
| struct tablet_pad_group { | ||||
| 	struct zwp_tablet_pad_group_v2 *pad_group; | ||||
| 	struct wlr_tablet_pad *pad; | ||||
| 	unsigned int mode; | ||||
| 
 | ||||
| 	struct wlr_tablet_pad_group group; | ||||
| 
 | ||||
| 	struct wl_list rings; // wlr_wl_tablet_pad_ring::link
 | ||||
| 	struct wl_list strips; // wlr_wl_tablet_pad_strips::link
 | ||||
| 	struct wl_list rings; // tablet_pad_ring::link
 | ||||
| 	struct wl_list strips; // tablet_pad_strips::link
 | ||||
| }; | ||||
| 
 | ||||
| static void handle_tablet_pad_ring_source(void *data, | ||||
| 		struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2, | ||||
| 		uint32_t source) { | ||||
| 	struct wlr_wl_tablet_pad_ring *ring = data; | ||||
| 	struct tablet_pad_ring *ring = data; | ||||
| 	ring->source = source; | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_pad_ring_angle(void *data, | ||||
| 		struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2, | ||||
| 		wl_fixed_t degrees) { | ||||
| 	struct wlr_wl_tablet_pad_ring *ring = data; | ||||
| 	struct tablet_pad_ring *ring = data; | ||||
| 	ring->angle = wl_fixed_to_double(degrees); | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_pad_ring_stop(void *data, | ||||
| 		struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2) { | ||||
| 	struct wlr_wl_tablet_pad_ring *ring = data; | ||||
| 	struct tablet_pad_ring *ring = data; | ||||
| 	ring->stopped = true; | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_pad_ring_frame(void *data, | ||||
| 		struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2, | ||||
| 		uint32_t time) { | ||||
| 	struct wlr_wl_tablet_pad_ring *ring = data; | ||||
| 	struct tablet_pad_ring *ring = data; | ||||
| 
 | ||||
| 	struct wlr_event_tablet_pad_ring evt = { | ||||
| 		.time_msec = time, | ||||
|  | @ -140,27 +130,27 @@ static const struct zwp_tablet_pad_ring_v2_listener tablet_pad_ring_listener = { | |||
| static void handle_tablet_pad_strip_source(void *data, | ||||
| 		struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2, | ||||
| 		uint32_t source) { | ||||
| 	struct wlr_wl_tablet_pad_strip *strip = data; | ||||
| 	struct tablet_pad_strip *strip = data; | ||||
| 	strip->source = source; | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_pad_strip_position(void *data, | ||||
| 		struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2, | ||||
| 		uint32_t position) { | ||||
| 	struct wlr_wl_tablet_pad_strip *strip = data; | ||||
| 	struct tablet_pad_strip *strip = data; | ||||
| 	strip->position = (double) position / 65536.0; | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_pad_strip_stop(void *data, | ||||
| 		struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2) { | ||||
| 	struct wlr_wl_tablet_pad_strip *strip = data; | ||||
| 	struct tablet_pad_strip *strip = data; | ||||
| 	strip->stopped = true; | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_pad_strip_frame(void *data, | ||||
| 		struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2, | ||||
| 		uint32_t time) { | ||||
| 	struct wlr_wl_tablet_pad_strip *strip = data; | ||||
| 	struct tablet_pad_strip *strip = data; | ||||
| 
 | ||||
| 	struct wlr_event_tablet_pad_strip evt = { | ||||
| 		.time_msec = time, | ||||
|  | @ -193,7 +183,7 @@ static const struct zwp_tablet_pad_strip_v2_listener tablet_pad_strip_listener = | |||
| static void handle_tablet_pad_group_buttons(void *data, | ||||
| 		struct zwp_tablet_pad_group_v2 *pad_group, | ||||
| 		struct wl_array *buttons) { | ||||
| 	struct wlr_wl_tablet_pad_group *group = data; | ||||
| 	struct tablet_pad_group *group = data; | ||||
| 
 | ||||
| 	free(group->group.buttons); | ||||
| 	group->group.buttons = calloc(1, buttons->size); | ||||
|  | @ -208,7 +198,7 @@ static void handle_tablet_pad_group_buttons(void *data, | |||
| 
 | ||||
| static void handle_tablet_pad_group_modes(void *data, | ||||
| 		struct zwp_tablet_pad_group_v2 *pad_group, uint32_t modes) { | ||||
| 	struct wlr_wl_tablet_pad_group *group = data; | ||||
| 	struct tablet_pad_group *group = data; | ||||
| 
 | ||||
| 	group->group.mode_count = modes; | ||||
| } | ||||
|  | @ -216,9 +206,9 @@ static void handle_tablet_pad_group_modes(void *data, | |||
| static void handle_tablet_pad_group_ring(void *data, | ||||
| 		struct zwp_tablet_pad_group_v2 *pad_group, | ||||
| 		struct zwp_tablet_pad_ring_v2 *ring) { | ||||
| 	struct wlr_wl_tablet_pad_group *group = data; | ||||
| 	struct wlr_wl_tablet_pad_ring *tablet_ring = | ||||
| 		calloc(1, sizeof(struct wlr_wl_tablet_pad_ring)); | ||||
| 	struct tablet_pad_group *group = data; | ||||
| 	struct tablet_pad_ring *tablet_ring = | ||||
| 		calloc(1, sizeof(struct tablet_pad_ring)); | ||||
| 	if (!tablet_ring) { | ||||
| 		zwp_tablet_pad_ring_v2_destroy(ring); | ||||
| 		return; | ||||
|  | @ -237,9 +227,9 @@ static void handle_tablet_pad_group_ring(void *data, | |||
| static void handle_tablet_pad_group_strip(void *data, | ||||
| 		struct zwp_tablet_pad_group_v2 *pad_group, | ||||
| 		struct zwp_tablet_pad_strip_v2 *strip) { | ||||
| 	struct wlr_wl_tablet_pad_group *group = data; | ||||
| 	struct wlr_wl_tablet_pad_strip *tablet_strip = | ||||
| 		calloc(1, sizeof(struct wlr_wl_tablet_pad_strip)); | ||||
| 	struct tablet_pad_group *group = data; | ||||
| 	struct tablet_pad_strip *tablet_strip = | ||||
| 		calloc(1, sizeof(struct tablet_pad_strip)); | ||||
| 	if (!tablet_strip) { | ||||
| 		zwp_tablet_pad_strip_v2_destroy(strip); | ||||
| 		return; | ||||
|  | @ -263,25 +253,20 @@ static void handle_tablet_pad_group_done(void *data, | |||
| static void handle_tablet_pad_group_mode_switch(void *data, | ||||
| 		struct zwp_tablet_pad_group_v2 *pad_group, | ||||
| 		uint32_t time, uint32_t serial, uint32_t mode) { | ||||
| 	struct wlr_wl_tablet_pad_group *group = data; | ||||
| 	struct tablet_pad_group *group = data; | ||||
| 	group->mode = mode; | ||||
| } | ||||
| 
 | ||||
| /* This isn't in the listener, but keep the naming scheme around since the
 | ||||
|  * other removed functions work like this, and pad sub-resources are just a bit | ||||
|  * special */ | ||||
| static void handle_tablet_pad_group_removed( | ||||
| 		struct wlr_wl_tablet_pad_group *group) { | ||||
| 
 | ||||
| static void destroy_tablet_pad_group(struct tablet_pad_group *group) { | ||||
| 	/* No need to remove the ::link on strips rings as long as we do *not*
 | ||||
| 	 * wl_list_remove on the wl_groups ring/strip attributes here */ | ||||
| 	struct wlr_wl_tablet_pad_ring *ring, *tmp_ring; | ||||
| 	struct tablet_pad_ring *ring, *tmp_ring; | ||||
| 	wl_list_for_each_safe(ring, tmp_ring, &group->rings, link) { | ||||
| 		zwp_tablet_pad_ring_v2_destroy(ring->ring); | ||||
| 		free(ring); | ||||
| 	} | ||||
| 
 | ||||
| 	struct wlr_wl_tablet_pad_strip *strip, *tmp_strip; | ||||
| 	struct tablet_pad_strip *strip, *tmp_strip; | ||||
| 	wl_list_for_each_safe(strip, tmp_strip, &group->strips, link) { | ||||
| 		zwp_tablet_pad_strip_v2_destroy(strip->strip); | ||||
| 		free(strip); | ||||
|  | @ -309,12 +294,13 @@ static const struct zwp_tablet_pad_group_v2_listener tablet_pad_group_listener = | |||
| static void handle_tablet_pad_group(void *data, | ||||
| 		struct zwp_tablet_pad_v2 *zwp_tablet_pad, | ||||
| 		struct zwp_tablet_pad_group_v2 *pad_group) { | ||||
| 	struct wlr_wl_input_device *dev = data; | ||||
| 	struct wlr_tablet_pad *pad = dev->wlr_input_device.tablet_pad; | ||||
| 	struct wlr_wl_seat *seat = data; | ||||
| 	struct wlr_tablet_pad *pad = &seat->wlr_tablet_pad; | ||||
| 
 | ||||
| 	struct wlr_wl_tablet_pad_group *group = | ||||
| 		calloc(1, sizeof(struct wlr_wl_tablet_pad_group)); | ||||
| 	struct tablet_pad_group *group = | ||||
| 		calloc(1, sizeof(struct tablet_pad_group)); | ||||
| 	if (!group) { | ||||
| 		wlr_log_errno(WLR_ERROR, "failed to allocate tablet_pad_group"); | ||||
| 		zwp_tablet_pad_group_v2_destroy(pad_group); | ||||
| 		return; | ||||
| 	} | ||||
|  | @ -331,20 +317,18 @@ static void handle_tablet_pad_group(void *data, | |||
| } | ||||
| 
 | ||||
| static void handle_tablet_pad_path(void *data, | ||||
| 		struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2, | ||||
| 		const char *path) { | ||||
| 	struct wlr_wl_input_device *dev = data; | ||||
| 	struct wlr_tablet_pad *tablet_pad = dev->wlr_input_device.tablet_pad; | ||||
| 		struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2, const char *path) { | ||||
| 	struct wlr_wl_seat *seat = data; | ||||
| 	struct wlr_tablet_pad *tablet_pad = &seat->wlr_tablet_pad; | ||||
| 
 | ||||
| 	char **dst = wl_array_add(&tablet_pad->paths, sizeof(char *)); | ||||
| 	*dst = strdup(path); | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_pad_buttons(void *data, | ||||
| 		struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2, | ||||
| 		uint32_t buttons) { | ||||
| 	struct wlr_wl_input_device *dev = data; | ||||
| 	struct wlr_tablet_pad *tablet_pad = dev->wlr_input_device.tablet_pad; | ||||
| 		struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2, uint32_t buttons) { | ||||
| 	struct wlr_wl_seat *seat = data; | ||||
| 	struct wlr_tablet_pad *tablet_pad = &seat->wlr_tablet_pad; | ||||
| 
 | ||||
| 	tablet_pad->button_count = buttons; | ||||
| } | ||||
|  | @ -352,9 +336,7 @@ static void handle_tablet_pad_buttons(void *data, | |||
| static void handle_tablet_pad_button(void *data, | ||||
| 		struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2, | ||||
| 		uint32_t time, uint32_t button, uint32_t state) { | ||||
| 	struct wlr_wl_input_device *dev = data; | ||||
| 	struct wlr_tablet_pad *tablet_pad = dev->wlr_input_device.tablet_pad; | ||||
| 
 | ||||
| 	struct wlr_wl_seat *seat = data; | ||||
| 	struct wlr_event_tablet_pad_button evt = { | ||||
| 		.time_msec = time, | ||||
| 		.button = button, | ||||
|  | @ -363,28 +345,25 @@ static void handle_tablet_pad_button(void *data, | |||
| 		.group = 0, | ||||
| 	}; | ||||
| 
 | ||||
| 	wlr_signal_emit_safe(&tablet_pad->events.button, &evt); | ||||
| 	wlr_signal_emit_safe(&seat->wlr_tablet_pad.events.button, &evt); | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_pad_done(void *data, | ||||
| 		struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2) { | ||||
| 	struct wlr_wl_input_device *dev = data; | ||||
| 
 | ||||
| 	wlr_signal_emit_safe(&dev->backend->backend.events.new_input, | ||||
| 		&dev->wlr_input_device); | ||||
| 	struct wlr_wl_seat *seat = data; | ||||
| 	wlr_signal_emit_safe(&seat->backend->backend.events.new_input, | ||||
| 		&seat->wlr_tablet_pad.base); | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_pad_enter(void *data, | ||||
| 		struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2, | ||||
| 		uint32_t serial, struct zwp_tablet_v2 *tablet_p, | ||||
| 		struct wl_surface *surface) { | ||||
| 	struct wlr_wl_input_device *dev = data; | ||||
| 	struct wlr_tablet_pad *tablet_pad = dev->wlr_input_device.tablet_pad; | ||||
| 	struct wlr_wl_input_device *tab_dev = zwp_tablet_v2_get_user_data(tablet_p); | ||||
| 	struct wlr_input_device *tablet = &tab_dev->wlr_input_device; | ||||
| 	wlr_log(WLR_DEBUG, "Tablet: %p\n", tablet); | ||||
| 	struct wlr_wl_seat *seat = data; | ||||
| 	assert(seat->zwp_tablet_v2 == tablet_p); | ||||
| 
 | ||||
| 	wlr_signal_emit_safe(&tablet_pad->events.attach_tablet, tablet); | ||||
| 	wlr_signal_emit_safe(&seat->wlr_tablet_pad.events.attach_tablet, | ||||
| 		&seat->wlr_tablet_tool); | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_pad_leave(void *data, | ||||
|  | @ -396,16 +375,17 @@ static void handle_tablet_pad_leave(void *data, | |||
| 
 | ||||
| static void handle_tablet_pad_removed(void *data, | ||||
| 		struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2) { | ||||
| 	struct wlr_wl_input_device *dev = data; | ||||
| 	struct wlr_wl_seat *seat = data; | ||||
| 
 | ||||
| 	struct wlr_tablet_pad *tablet_pad = dev->wlr_input_device.tablet_pad; | ||||
| 	struct wlr_wl_tablet_pad_group *group, *it; | ||||
| 	struct wlr_tablet_pad *tablet_pad = &seat->wlr_tablet_pad; | ||||
| 	struct tablet_pad_group *group, *it; | ||||
| 	wl_list_for_each_safe(group, it, &tablet_pad->groups, group.link) { | ||||
| 		handle_tablet_pad_group_removed(group); | ||||
| 		destroy_tablet_pad_group(group); | ||||
| 	} | ||||
| 
 | ||||
| 	zwp_tablet_pad_v2_destroy(dev->resource); | ||||
| 	destroy_wl_input_device(dev); | ||||
| 	wlr_tablet_pad_finish(tablet_pad); | ||||
| 	zwp_tablet_pad_v2_destroy(seat->zwp_tablet_pad_v2); | ||||
| 	seat->zwp_tablet_pad_v2 = NULL; | ||||
| } | ||||
| 
 | ||||
| static const struct zwp_tablet_pad_v2_listener tablet_pad_listener = { | ||||
|  | @ -419,39 +399,25 @@ static const struct zwp_tablet_pad_v2_listener tablet_pad_listener = { | |||
| 	.removed = handle_tablet_pad_removed, | ||||
| }; | ||||
| 
 | ||||
| const struct wlr_tablet_pad_impl tablet_pad_impl = { | ||||
| const struct wlr_tablet_pad_impl wl_tablet_pad_impl = { | ||||
| 	.name = "wl-tablet-pad", | ||||
| }; | ||||
| 
 | ||||
| static void handle_pad_added(void *data, | ||||
| 		struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2, | ||||
| 		struct zwp_tablet_pad_v2 *id) { | ||||
| 	wlr_log(WLR_DEBUG, "New tablet pad"); | ||||
| 		struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2) { | ||||
| 	struct wlr_wl_seat *seat = data; | ||||
| 	struct wlr_wl_input_device *dev = create_wl_input_device( | ||||
| 		seat, WLR_INPUT_DEVICE_TABLET_PAD); | ||||
| 	if (!dev) { | ||||
| 		/* This leaks a couple of server-sent resource ids. iirc this
 | ||||
| 		 * shouldn't ever be a problem, but it isn't exactly nice | ||||
| 		 * either. */ | ||||
| 		zwp_tablet_pad_v2_destroy(id); | ||||
| 	if (seat->zwp_tablet_pad_v2 != NULL) { | ||||
| 		wlr_log(WLR_ERROR, "zwp_tablet_pad_v2 is already present"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	dev->resource = id; | ||||
| 	struct wlr_input_device *wlr_dev = &dev->wlr_input_device; | ||||
| 	wlr_dev->tablet_pad = calloc(1, sizeof(*wlr_dev->tablet_pad)); | ||||
| 	seat->zwp_tablet_pad_v2 = zwp_tablet_pad_v2; | ||||
| 	zwp_tablet_pad_v2_add_listener(zwp_tablet_pad_v2, &tablet_pad_listener, | ||||
| 		seat); | ||||
| 
 | ||||
| 	if (!wlr_dev->tablet_pad) { | ||||
| 		/* This leaks a couple of server-sent resource ids. iirc this
 | ||||
| 		 * shouldn't ever be a problem, but it isn't exactly nice | ||||
| 		 * either. */ | ||||
| 		free(dev); | ||||
| 		zwp_tablet_pad_v2_destroy(id); | ||||
| 		return; | ||||
| 	} | ||||
| 	wlr_tablet_pad_init(wlr_dev->tablet_pad, &tablet_pad_impl, "wlr_tablet_v2"); | ||||
| 	zwp_tablet_pad_v2_add_listener(id, &tablet_pad_listener, dev); | ||||
| 	wlr_tablet_pad_init(&seat->wlr_tablet_pad, &wl_tablet_pad_impl, | ||||
| 		"wlr_tablet_v2"); | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_done(void *data, | ||||
|  | @ -459,7 +425,8 @@ static void handle_tablet_tool_done(void *data, | |||
| 	/* empty */ | ||||
| } | ||||
| 
 | ||||
| static enum wlr_tablet_tool_type tablet_type_to_wlr_type(enum zwp_tablet_tool_v2_type type) { | ||||
| static enum wlr_tablet_tool_type tablet_type_to_wlr_type( | ||||
| 		enum zwp_tablet_tool_v2_type type) { | ||||
| 	switch (type) { | ||||
| 	case ZWP_TABLET_TOOL_V2_TYPE_PEN: | ||||
| 		return WLR_TABLET_TOOL_TYPE_PEN; | ||||
|  | @ -484,94 +451,85 @@ static enum wlr_tablet_tool_type tablet_type_to_wlr_type(enum zwp_tablet_tool_v2 | |||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_type(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id, | ||||
| 		uint32_t tool_type) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 
 | ||||
| 	tool->wlr_tool.type = tablet_type_to_wlr_type(tool_type); | ||||
| 		struct zwp_tablet_tool_v2 *id, uint32_t tool_type) { | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	struct wlr_tablet_tool *wlr_tool = &tool->seat->wlr_tablet_tool; | ||||
| 	wlr_tool->type = tablet_type_to_wlr_type(tool_type); | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_serial(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id, | ||||
| 		uint32_t high, uint32_t low) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 
 | ||||
| 	tool->wlr_tool.hardware_serial = | ||||
| 		((uint64_t) high) << 32 | (uint64_t) low; | ||||
| 		struct zwp_tablet_tool_v2 *id, uint32_t high, uint32_t low) { | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	struct wlr_tablet_tool *wlr_tool = &tool->seat->wlr_tablet_tool; | ||||
| 	wlr_tool->hardware_serial = ((uint64_t) high) << 32 | (uint64_t) low; | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_id_wacom(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id, | ||||
| 		uint32_t high, uint32_t low) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 
 | ||||
| 	tool->wlr_tool.hardware_wacom = | ||||
| 		((uint64_t) high) << 32 | (uint64_t) low; | ||||
| 		struct zwp_tablet_tool_v2 *id, uint32_t high, uint32_t low) { | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	struct wlr_tablet_tool *wlr_tool = &tool->seat->wlr_tablet_tool; | ||||
| 	wlr_tool->hardware_wacom = ((uint64_t) high) << 32 | (uint64_t) low; | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_capability(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id, | ||||
| 		uint32_t capability) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 		struct zwp_tablet_tool_v2 *id, uint32_t capability) { | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	struct wlr_tablet_tool *wlr_tool = &tool->seat->wlr_tablet_tool; | ||||
| 
 | ||||
| 	enum zwp_tablet_tool_v2_capability cap = capability; | ||||
| 
 | ||||
| 	switch (cap) { | ||||
| 	/* One event is sent for each capability */ | ||||
| 	switch (capability) { | ||||
| 	case ZWP_TABLET_TOOL_V2_CAPABILITY_TILT: | ||||
| 		tool->wlr_tool.tilt = true; | ||||
| 		wlr_tool->tilt = true; | ||||
| 		break; | ||||
| 	case ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE: | ||||
| 		tool->wlr_tool.pressure = true; | ||||
| 		wlr_tool->pressure = true; | ||||
| 		break; | ||||
| 	case ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE: | ||||
| 		tool->wlr_tool.distance = true; | ||||
| 		wlr_tool->distance = true; | ||||
| 		break; | ||||
| 	case ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION: | ||||
| 		tool->wlr_tool.rotation = true; | ||||
| 		wlr_tool->rotation = true; | ||||
| 		break; | ||||
| 	case ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER: | ||||
| 		tool->wlr_tool.slider = true; | ||||
| 		wlr_tool->slider = true; | ||||
| 		break; | ||||
| 	case ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL: | ||||
| 		tool->wlr_tool.wheel = true; | ||||
| 		wlr_tool->wheel = true; | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_proximity_in(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id, uint32_t serial, | ||||
| 		struct zwp_tablet_v2 *tablet_id, | ||||
| 		struct wl_surface *surface) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 		struct zwp_tablet_v2 *tablet_id, struct wl_surface *surface) { | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	assert(tablet_id == tool->seat->zwp_tablet_v2); | ||||
| 
 | ||||
| 	tool->is_in = true; | ||||
| 	tool->tablet = zwp_tablet_v2_get_user_data(tablet_id); | ||||
| 	tool->output = wl_surface_get_user_data(surface); | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_proximity_out(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	tool->is_out = true; | ||||
| 	tool->output = NULL; | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_down(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id, | ||||
| static void handle_tablet_tool_down(void *data, struct zwp_tablet_tool_v2 *id, | ||||
| 		unsigned int serial) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	tool->is_down = true; | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_up(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| static void handle_tablet_tool_up(void *data, struct zwp_tablet_tool_v2 *id) { | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	tool->is_up = true; | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_motion(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id, | ||||
| static void handle_tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *id, | ||||
| 		wl_fixed_t x, wl_fixed_t y) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	struct wlr_wl_output *output = tool->output; | ||||
| 	assert(output); | ||||
| 
 | ||||
|  | @ -580,58 +538,53 @@ static void handle_tablet_tool_motion(void *data, | |||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_pressure(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id, | ||||
| 		uint32_t pressure) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 		struct zwp_tablet_tool_v2 *id, uint32_t pressure) { | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	tool->pressure = (double) pressure / 65535.0; | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_distance(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id, | ||||
| 		uint32_t distance) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 		struct zwp_tablet_tool_v2 *id, uint32_t distance) { | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	tool->distance = (double) distance / 65535.0; | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_tilt(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id, | ||||
| static void handle_tablet_tool_tilt(void *data, struct zwp_tablet_tool_v2 *id, | ||||
| 		wl_fixed_t x, wl_fixed_t y) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	tool->tilt_x = wl_fixed_to_double(x); | ||||
| 	tool->tilt_y = wl_fixed_to_double(y); | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_rotation(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id, | ||||
| 		wl_fixed_t rotation) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 		struct zwp_tablet_tool_v2 *id, wl_fixed_t rotation) { | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	tool->rotation = wl_fixed_to_double(rotation); | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_slider(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id, | ||||
| static void handle_tablet_tool_slider(void *data, struct zwp_tablet_tool_v2 *id, | ||||
| 		int slider) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	tool->slider = (double) slider / 65535.0;; | ||||
| } | ||||
| 
 | ||||
| // TODO: This looks wrong :/
 | ||||
| static void handle_tablet_tool_wheel(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id, | ||||
| static void handle_tablet_tool_wheel(void *data, struct zwp_tablet_tool_v2 *id, | ||||
| 		wl_fixed_t degree, int clicks) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	tool->wheel_delta = wl_fixed_to_double(degree); | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_tool_button(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id, | ||||
| 		uint32_t serial, uint32_t button, uint32_t state) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 	struct wlr_tablet *tablet = tool->tablet->wlr_input_device.tablet; | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	struct wlr_wl_seat *seat = tool->seat; | ||||
| 	struct wlr_tablet *tablet = &seat->wlr_tablet; | ||||
| 
 | ||||
| 	struct wlr_event_tablet_tool_button evt = { | ||||
| 		.device = &tool->tablet->wlr_input_device, | ||||
| 		.tool = &tool->wlr_tool, | ||||
| 		.device = &tablet->base, | ||||
| 		.tool = &seat->wlr_tablet_tool, | ||||
| 		.time_msec = get_current_time_msec(), | ||||
| 		.button = button, | ||||
| 		.state = state == ZWP_TABLET_TOOL_V2_BUTTON_STATE_RELEASED ? | ||||
|  | @ -641,7 +594,7 @@ static void handle_tablet_tool_button(void *data, | |||
| 	wlr_signal_emit_safe(&tablet->events.button, &evt); | ||||
| } | ||||
| 
 | ||||
| static void clear_tablet_tool_values(struct wlr_wl_tablet_tool *tool) { | ||||
| static void clear_tablet_tool_values(struct tablet_tool *tool) { | ||||
| 	tool->is_out = tool->is_in = false; | ||||
| 	tool->is_up = tool->is_down = false; | ||||
| 	tool->x = tool->y = NAN; | ||||
|  | @ -656,18 +609,20 @@ static void clear_tablet_tool_values(struct wlr_wl_tablet_tool *tool) { | |||
| static void handle_tablet_tool_frame(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id, | ||||
| 		uint32_t time) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	struct wlr_wl_seat *seat = tool->seat; | ||||
| 
 | ||||
| 	if (tool->is_out && tool->is_in) { | ||||
| 		/* we got a tablet tool coming in and out of proximity before
 | ||||
| 		 * we could process it. Just ignore anything it did */ | ||||
| 		goto clear_values; | ||||
| 	} | ||||
| 	struct wlr_tablet *tablet = tool->tablet->wlr_input_device.tablet; | ||||
| 	struct wlr_tablet *tablet = &seat->wlr_tablet; | ||||
| 
 | ||||
| 	if (tool->is_in) { | ||||
| 		struct wlr_event_tablet_tool_proximity evt = { | ||||
| 			.device = &tool->tablet->wlr_input_device, | ||||
| 			.tool = &tool->wlr_tool, | ||||
| 			.device = &tablet->base, | ||||
| 			.tool = &seat->wlr_tablet_tool, | ||||
| 			.time_msec = time, | ||||
| 			.x = tool->x, | ||||
| 			.y = tool->y, | ||||
|  | @ -679,8 +634,8 @@ static void handle_tablet_tool_frame(void *data, | |||
| 
 | ||||
| 	{ | ||||
| 		struct wlr_event_tablet_tool_axis evt = { | ||||
| 			.device = &tool->tablet->wlr_input_device, | ||||
| 			.tool = &tool->wlr_tool, | ||||
| 			.device = &tablet->base, | ||||
| 			.tool = &seat->wlr_tablet_tool, | ||||
| 			.time_msec = time, | ||||
| 			.updated_axes = 0, | ||||
| 		}; | ||||
|  | @ -742,8 +697,8 @@ static void handle_tablet_tool_frame(void *data, | |||
| 	 * need to generate the time */ | ||||
| 	if (tool->is_down) { | ||||
| 		struct wlr_event_tablet_tool_tip evt = { | ||||
| 			.device = &tool->tablet->wlr_input_device, | ||||
| 			.tool = &tool->wlr_tool, | ||||
| 			.device = &tablet->base, | ||||
| 			.tool = &seat->wlr_tablet_tool, | ||||
| 			.time_msec = time, | ||||
| 			.x = tool->x, | ||||
| 			.y = tool->y, | ||||
|  | @ -755,8 +710,8 @@ static void handle_tablet_tool_frame(void *data, | |||
| 
 | ||||
| 	if (tool->is_up) { | ||||
| 		struct wlr_event_tablet_tool_tip evt = { | ||||
| 			.device = &tool->tablet->wlr_input_device, | ||||
| 			.tool = &tool->wlr_tool, | ||||
| 			.device = &tablet->base, | ||||
| 			.tool = &seat->wlr_tablet_tool, | ||||
| 			.time_msec = time, | ||||
| 			.x = tool->x, | ||||
| 			.y = tool->y, | ||||
|  | @ -768,8 +723,8 @@ static void handle_tablet_tool_frame(void *data, | |||
| 
 | ||||
| 	if (tool->is_out) { | ||||
| 		struct wlr_event_tablet_tool_proximity evt = { | ||||
| 			.device = &tool->tablet->wlr_input_device, | ||||
| 			.tool = &tool->wlr_tool, | ||||
| 			.device = &tablet->base, | ||||
| 			.tool = &seat->wlr_tablet_tool, | ||||
| 			.time_msec = time, | ||||
| 			.x = tool->x, | ||||
| 			.y = tool->y, | ||||
|  | @ -785,10 +740,12 @@ clear_values: | |||
| 
 | ||||
| static void handle_tablet_tool_removed(void *data, | ||||
| 		struct zwp_tablet_tool_v2 *id) { | ||||
| 	struct wlr_wl_tablet_tool *tool = data; | ||||
| 	struct tablet_tool *tool = data; | ||||
| 	struct wlr_wl_seat *seat = tool->seat; | ||||
| 
 | ||||
| 	zwp_tablet_tool_v2_destroy(seat->zwp_tablet_tool_v2); | ||||
| 	seat->zwp_tablet_tool_v2 = NULL; | ||||
| 
 | ||||
| 	zwp_tablet_tool_v2_destroy(tool->tool); | ||||
| 	wlr_signal_emit_safe(&tool->wlr_tool.events.destroy, &tool->wlr_tool); | ||||
| 	free(tool); | ||||
| } | ||||
| 
 | ||||
|  | @ -818,23 +775,34 @@ static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = { | |||
| 
 | ||||
| static void handle_tool_added(void *data, | ||||
| 		struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2, | ||||
| 		struct zwp_tablet_tool_v2 *id) { | ||||
| 	wlr_log(WLR_DEBUG, "New tablet tool"); | ||||
| 	struct wlr_wl_tablet_tool *tool = calloc(1, sizeof(*tool)); | ||||
| 	if (!tool) { | ||||
| 		zwp_tablet_tool_v2_destroy(id); | ||||
| 		struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2) { | ||||
| 	struct wlr_wl_seat *seat = data; | ||||
| 	if (seat->zwp_tablet_tool_v2 != NULL) { | ||||
| 		wlr_log(WLR_ERROR, "zwp_tablet_tool_v2 already present"); | ||||
| 		return; | ||||
| 	} | ||||
| 	tool->tool = id; | ||||
| 
 | ||||
| 	wl_signal_init(&seat->wlr_tablet_tool.events.destroy); | ||||
| 
 | ||||
| 	struct tablet_tool *tool = calloc(1, sizeof(struct tablet_tool)); | ||||
| 	if (tool == NULL) { | ||||
| 		wlr_log_errno(WLR_ERROR, "failed to allocate tablet_tool"); | ||||
| 		zwp_tablet_tool_v2_destroy(zwp_tablet_tool_v2); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	tool->seat = seat; | ||||
| 	clear_tablet_tool_values(tool); | ||||
| 	wl_signal_init(&tool->wlr_tool.events.destroy); | ||||
| 	zwp_tablet_tool_v2_add_listener(id, &tablet_tool_listener, tool); | ||||
| 
 | ||||
| 	seat->zwp_tablet_tool_v2 = zwp_tablet_tool_v2; | ||||
| 	zwp_tablet_tool_v2_add_listener(seat->zwp_tablet_tool_v2, &tablet_tool_listener, | ||||
| 		tool); | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_name(void *data, struct zwp_tablet_v2 *zwp_tablet_v2, | ||||
| 		const char *name) { | ||||
| 	struct wlr_wl_input_device *dev = data; | ||||
| 	struct wlr_tablet *tablet = dev->wlr_input_device.tablet; | ||||
| 	struct wlr_wl_seat *seat = data; | ||||
| 	struct wlr_tablet *tablet = &seat->wlr_tablet; | ||||
| 
 | ||||
| 	free(tablet->base.name); | ||||
| 	tablet->base.name = strdup(name); | ||||
|  | @ -842,33 +810,36 @@ static void handle_tablet_name(void *data, struct zwp_tablet_v2 *zwp_tablet_v2, | |||
| 
 | ||||
| static void handle_tablet_id(void *data, struct zwp_tablet_v2 *zwp_tablet_v2, | ||||
| 		uint32_t vid, uint32_t pid) { | ||||
| 	struct wlr_wl_input_device *dev = data; | ||||
| 	dev->wlr_input_device.vendor = vid; | ||||
| 	dev->wlr_input_device.product = pid; | ||||
| 	struct wlr_wl_seat *seat = data; | ||||
| 	struct wlr_tablet *tablet = &seat->wlr_tablet; | ||||
| 
 | ||||
| 	tablet->base.vendor = vid; | ||||
| 	tablet->base.product = pid; | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_path(void *data, struct zwp_tablet_v2 *zwp_tablet_v2, | ||||
| 		const char *path) { | ||||
| 	struct wlr_wl_input_device *dev = data; | ||||
| 	struct wlr_tablet *tablet = dev->wlr_input_device.tablet; | ||||
| 	struct wlr_wl_seat *seat = data; | ||||
| 	struct wlr_tablet *tablet = &seat->wlr_tablet; | ||||
| 
 | ||||
| 	char **dst = wl_array_add(&tablet->paths, sizeof(char *)); | ||||
| 	*dst = strdup(path); | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_done(void *data, struct zwp_tablet_v2 *zwp_tablet_v2) { | ||||
| 	struct wlr_wl_input_device *dev = data; | ||||
| 	struct wlr_wl_seat *seat = data; | ||||
| 
 | ||||
| 	wlr_signal_emit_safe(&dev->backend->backend.events.new_input, | ||||
| 		&dev->wlr_input_device); | ||||
| 	wlr_signal_emit_safe(&seat->backend->backend.events.new_input, | ||||
| 		&seat->wlr_tablet.base); | ||||
| } | ||||
| 
 | ||||
| static void handle_tablet_removed(void *data, | ||||
| 		struct zwp_tablet_v2 *zwp_tablet_v2) { | ||||
| 	struct wlr_wl_input_device *dev = data; | ||||
| 	struct wlr_wl_seat *seat = data; | ||||
| 
 | ||||
| 	zwp_tablet_v2_destroy(dev->resource); | ||||
| 	destroy_wl_input_device(dev); | ||||
| 	wlr_tablet_finish(&seat->wlr_tablet); | ||||
| 	zwp_tablet_v2_destroy(seat->zwp_tablet_v2); | ||||
| 	seat->zwp_tablet_v2 = NULL; | ||||
| } | ||||
| 
 | ||||
| static const struct zwp_tablet_v2_listener tablet_listener = { | ||||
|  | @ -879,34 +850,23 @@ static const struct zwp_tablet_v2_listener tablet_listener = { | |||
| 	.removed = handle_tablet_removed, | ||||
| }; | ||||
| 
 | ||||
| const struct wlr_tablet_impl tablet_impl = { | ||||
| const struct wlr_tablet_impl wl_tablet_impl = { | ||||
| 	.name = "wl-tablet-tool", | ||||
| }; | ||||
| 
 | ||||
| static void handle_tab_added(void *data, | ||||
| 		struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2, | ||||
| 		struct zwp_tablet_v2 *id) { | ||||
| 	wlr_log(WLR_DEBUG, "New tablet"); | ||||
| 		struct zwp_tablet_v2 *zwp_tablet_v2) { | ||||
| 	struct wlr_wl_seat *seat = data; | ||||
| 	struct wlr_wl_input_device *dev = create_wl_input_device( | ||||
| 		seat, WLR_INPUT_DEVICE_TABLET_TOOL); | ||||
| 
 | ||||
| 	if (!dev) { | ||||
| 		zwp_tablet_v2_destroy(id); | ||||
| 	if (seat->zwp_tablet_v2 != NULL) { | ||||
| 		wlr_log(WLR_ERROR, "zwp_tablet_v2 already present"); | ||||
| 		return; | ||||
| 	} | ||||
| 	dev->resource = id; | ||||
| 
 | ||||
| 	struct wlr_input_device *wlr_dev = &dev->wlr_input_device; | ||||
| 	wlr_dev->tablet = calloc(1, sizeof(*wlr_dev->tablet)); | ||||
| 	seat->zwp_tablet_v2 = zwp_tablet_v2; | ||||
| 	zwp_tablet_v2_add_listener(zwp_tablet_v2, &tablet_listener, seat); | ||||
| 
 | ||||
| 	if (!wlr_dev->tablet) { | ||||
| 		zwp_tablet_v2_destroy(id); | ||||
| 		return; | ||||
| 	} | ||||
| 	zwp_tablet_v2_set_user_data(id, wlr_dev->tablet); | ||||
| 	wlr_tablet_init(wlr_dev->tablet, &tablet_impl, "wlr_tablet_v2"); | ||||
| 	zwp_tablet_v2_add_listener(id, &tablet_listener, dev); | ||||
| 	wlr_tablet_init(&seat->wlr_tablet, &wl_tablet_impl, "wlr_tablet_v2"); | ||||
| } | ||||
| 
 | ||||
| static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = { | ||||
|  | @ -915,20 +875,55 @@ static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = { | |||
| 	.pad_added = handle_pad_added, | ||||
| }; | ||||
| 
 | ||||
| struct wlr_wl_tablet_seat *wl_add_tablet_seat( | ||||
| 		struct zwp_tablet_manager_v2 *manager, | ||||
| 		struct wlr_wl_seat *seat) { | ||||
| 	struct wlr_wl_tablet_seat *ret = | ||||
| 		calloc(1, sizeof(struct wlr_wl_tablet_seat)); | ||||
| void init_seat_tablet(struct wlr_wl_seat *seat) { | ||||
| 	struct zwp_tablet_manager_v2 *manager = seat->backend->tablet_manager; | ||||
| 	assert(manager); | ||||
| 
 | ||||
| 	if (!(ret->tablet_seat = | ||||
| 			zwp_tablet_manager_v2_get_tablet_seat(manager, seat->wl_seat))) { | ||||
| 		free(ret); | ||||
| 		return NULL; | ||||
| 	/**
 | ||||
| 	 * TODO: multi tablet support | ||||
| 	 * The wlr_wl_seat should support multiple tablet_v2 devices, but for | ||||
| 	 * the sake of simplicity, it supports only one device of each. | ||||
| 	 * If this is a feature you want/need, please open an issue on the wlroots | ||||
| 	 * tracker here https://gitlab.freedesktop.org/wlroots/wlroots/-/issues
 | ||||
| 	 */ | ||||
| 
 | ||||
| 	seat->zwp_tablet_seat_v2 = | ||||
| 		zwp_tablet_manager_v2_get_tablet_seat(manager, seat->wl_seat); | ||||
| 	if (seat->zwp_tablet_seat_v2 == NULL) { | ||||
| 		wlr_log(WLR_ERROR, "failed to get zwp_tablet_manager_v2 from seat '%s'", | ||||
| 			seat->name); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	zwp_tablet_seat_v2_add_listener(ret->tablet_seat, | ||||
| 	zwp_tablet_seat_v2_add_listener(seat->zwp_tablet_seat_v2, | ||||
| 		&tablet_seat_listener, seat); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| void finish_seat_tablet(struct wlr_wl_seat *seat) { | ||||
| 	if (seat->zwp_tablet_v2 != NULL) { | ||||
| 		wlr_tablet_finish(&seat->wlr_tablet); | ||||
| 		zwp_tablet_v2_destroy(seat->zwp_tablet_v2); | ||||
| 	} | ||||
| 
 | ||||
| 	if (seat->zwp_tablet_tool_v2 != NULL) { | ||||
| 		struct tablet_tool *tool = | ||||
| 			zwp_tablet_tool_v2_get_user_data(seat->zwp_tablet_tool_v2); | ||||
| 		free(tool); | ||||
| 
 | ||||
| 		zwp_tablet_tool_v2_destroy(seat->zwp_tablet_tool_v2); | ||||
| 	} | ||||
| 
 | ||||
| 	if (seat->zwp_tablet_pad_v2 != NULL) { | ||||
| 		struct wlr_tablet_pad *tablet_pad = &seat->wlr_tablet_pad; | ||||
| 		struct tablet_pad_group *group, *it; | ||||
| 		wl_list_for_each_safe(group, it, &tablet_pad->groups, group.link) { | ||||
| 			destroy_tablet_pad_group(group); | ||||
| 		} | ||||
| 
 | ||||
| 		wlr_tablet_pad_finish(tablet_pad); | ||||
| 		zwp_tablet_pad_v2_destroy(seat->zwp_tablet_pad_v2); | ||||
| 	} | ||||
| 
 | ||||
| 	zwp_tablet_seat_v2_destroy(seat->zwp_tablet_seat_v2); | ||||
| 	seat->zwp_tablet_seat_v2 = NULL; | ||||
| } | ||||
|  |  | |||
|  | @ -10,6 +10,8 @@ | |||
| #include <wlr/render/wlr_renderer.h> | ||||
| #include <wlr/types/wlr_keyboard.h> | ||||
| #include <wlr/types/wlr_pointer.h> | ||||
| #include <wlr/types/wlr_tablet_pad.h> | ||||
| #include <wlr/types/wlr_tablet_tool.h> | ||||
| #include <wlr/types/wlr_touch.h> | ||||
| #include <wlr/render/drm_format_set.h> | ||||
| 
 | ||||
|  | @ -132,6 +134,14 @@ struct wlr_wl_seat { | |||
| 	struct wl_touch *wl_touch; | ||||
| 	struct wlr_touch wlr_touch; | ||||
| 
 | ||||
| 	struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2; | ||||
| 	struct zwp_tablet_v2 *zwp_tablet_v2; | ||||
| 	struct wlr_tablet wlr_tablet; | ||||
| 	struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2; | ||||
| 	struct wlr_tablet_tool wlr_tablet_tool; | ||||
| 	struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2; | ||||
| 	struct wlr_tablet_pad wlr_tablet_pad; | ||||
| 
 | ||||
| 	struct wl_list link; // wlr_wl_backend.seats
 | ||||
| }; | ||||
| 
 | ||||
|  | @ -144,6 +154,9 @@ void init_seat_pointer(struct wlr_wl_seat *seat); | |||
| void finish_seat_pointer(struct wlr_wl_seat *seat); | ||||
| void create_pointer(struct wlr_wl_seat *seat, struct wlr_wl_output *output); | ||||
| 
 | ||||
| void init_seat_tablet(struct wlr_wl_seat *seat); | ||||
| void finish_seat_tablet(struct wlr_wl_seat *seat); | ||||
| 
 | ||||
| struct wlr_wl_input_device *create_wl_input_device( | ||||
| 	struct wlr_wl_seat *seat, enum wlr_input_device_type type); | ||||
| bool create_wl_seat(struct wl_seat *wl_seat, struct wlr_wl_backend *wl); | ||||
|  | @ -154,11 +167,7 @@ void destroy_wl_buffer(struct wlr_wl_buffer *buffer); | |||
| extern const struct wl_seat_listener seat_listener; | ||||
| 
 | ||||
| extern const struct wlr_pointer_impl wl_pointer_impl; | ||||
| extern const struct wlr_tablet_pad_impl tablet_pad_impl; | ||||
| extern const struct wlr_tablet_impl tablet_impl; | ||||
| 
 | ||||
| struct wlr_wl_tablet_seat *wl_add_tablet_seat( | ||||
| 		struct zwp_tablet_manager_v2 *manager, | ||||
| 		struct wlr_wl_seat *seat); | ||||
| extern const struct wlr_tablet_pad_impl wl_tablet_pad_impl; | ||||
| extern const struct wlr_tablet_impl wl_tablet_impl; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Simon Zeni
						Simon Zeni