mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-10-29 05:40:12 -04:00 
			
		
		
		
	Implement the pointer-gestures-unstable-v1 protocol
This protocol relays touchpad gesture events produced by libinput to supporting clients (e.g. Evince, Eye of GNOME).
This commit is contained in:
		
							parent
							
								
									018727b1fc
								
							
						
					
					
						commit
						9fe8e37961
					
				
					 16 changed files with 790 additions and 0 deletions
				
			
		|  | @ -287,6 +287,24 @@ void handle_libinput_event(struct wlr_libinput_backend *backend, | |||
| 	case LIBINPUT_EVENT_SWITCH_TOGGLE: | ||||
| 		handle_switch_toggle(event, libinput_dev); | ||||
| 		break; | ||||
| 	case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN: | ||||
| 		handle_pointer_swipe_begin(event, libinput_dev); | ||||
| 		break; | ||||
| 	case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE: | ||||
| 		handle_pointer_swipe_update(event, libinput_dev); | ||||
| 		break; | ||||
| 	case LIBINPUT_EVENT_GESTURE_SWIPE_END: | ||||
| 		handle_pointer_swipe_end(event, libinput_dev); | ||||
| 		break; | ||||
| 	case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN: | ||||
| 		handle_pointer_pinch_begin(event, libinput_dev); | ||||
| 		break; | ||||
| 	case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE: | ||||
| 		handle_pointer_pinch_update(event, libinput_dev); | ||||
| 		break; | ||||
| 	case LIBINPUT_EVENT_GESTURE_PINCH_END: | ||||
| 		handle_pointer_pinch_end(event, libinput_dev); | ||||
| 		break; | ||||
| 	default: | ||||
| 		wlr_log(WLR_DEBUG, "Unknown libinput event %d", event_type); | ||||
| 		break; | ||||
|  |  | |||
|  | @ -140,3 +140,123 @@ void handle_pointer_axis(struct libinput_event *event, | |||
| 	} | ||||
| 	wlr_signal_emit_safe(&wlr_dev->pointer->events.frame, wlr_dev->pointer); | ||||
| } | ||||
| 
 | ||||
| void handle_pointer_swipe_begin(struct libinput_event *event, | ||||
| 		struct libinput_device *libinput_dev) { | ||||
| 	struct wlr_input_device *wlr_dev = | ||||
| 		get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev); | ||||
| 	if (!wlr_dev) { | ||||
| 		wlr_log(WLR_DEBUG, "Got a pointer gesture event for a device with no pointers?"); | ||||
| 		return; | ||||
| 	} | ||||
| 	struct libinput_event_gesture *gevent = | ||||
| 		libinput_event_get_gesture_event(event); | ||||
| 	struct wlr_event_pointer_swipe_begin wlr_event = { | ||||
| 		.device = wlr_dev, | ||||
| 		.time_msec = | ||||
| 			usec_to_msec(libinput_event_gesture_get_time_usec(gevent)), | ||||
| 		.fingers = libinput_event_gesture_get_finger_count(gevent), | ||||
| 	}; | ||||
| 	wlr_signal_emit_safe(&wlr_dev->pointer->events.swipe_begin, &wlr_event); | ||||
| } | ||||
| 
 | ||||
| void handle_pointer_swipe_update(struct libinput_event *event, | ||||
| 		struct libinput_device *libinput_dev) { | ||||
| 	struct wlr_input_device *wlr_dev = | ||||
| 		get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev); | ||||
| 	if (!wlr_dev) { | ||||
| 		wlr_log(WLR_DEBUG, "Got a pointer gesture event for a device with no pointers?"); | ||||
| 		return; | ||||
| 	} | ||||
| 	struct libinput_event_gesture *gevent = | ||||
| 		libinput_event_get_gesture_event(event); | ||||
| 	struct wlr_event_pointer_swipe_update wlr_event = { | ||||
| 		.device = wlr_dev, | ||||
| 		.time_msec = | ||||
| 			usec_to_msec(libinput_event_gesture_get_time_usec(gevent)), | ||||
| 		.fingers = libinput_event_gesture_get_finger_count(gevent), | ||||
| 		.dx = libinput_event_gesture_get_dx(gevent), | ||||
| 		.dy = libinput_event_gesture_get_dy(gevent), | ||||
| 	}; | ||||
| 	wlr_signal_emit_safe(&wlr_dev->pointer->events.swipe_update, &wlr_event); | ||||
| } | ||||
| 
 | ||||
| void handle_pointer_swipe_end(struct libinput_event *event, | ||||
| 		struct libinput_device *libinput_dev) { | ||||
| 	struct wlr_input_device *wlr_dev = | ||||
| 		get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev); | ||||
| 	if (!wlr_dev) { | ||||
| 		wlr_log(WLR_DEBUG, "Got a pointer gesture event for a device with no pointers?"); | ||||
| 		return; | ||||
| 	} | ||||
| 	struct libinput_event_gesture *gevent = | ||||
| 		libinput_event_get_gesture_event(event); | ||||
| 	struct wlr_event_pointer_swipe_end wlr_event = { | ||||
| 		.device = wlr_dev, | ||||
| 		.time_msec = | ||||
| 			usec_to_msec(libinput_event_gesture_get_time_usec(gevent)), | ||||
| 		.cancelled = libinput_event_gesture_get_cancelled(gevent), | ||||
| 	}; | ||||
| 	wlr_signal_emit_safe(&wlr_dev->pointer->events.swipe_end, &wlr_event); | ||||
| } | ||||
| 
 | ||||
| void handle_pointer_pinch_begin(struct libinput_event *event, | ||||
| 		struct libinput_device *libinput_dev) { | ||||
| 	struct wlr_input_device *wlr_dev = | ||||
| 		get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev); | ||||
| 	if (!wlr_dev) { | ||||
| 		wlr_log(WLR_DEBUG, "Got a pointer gesture event for a device with no pointers?"); | ||||
| 		return; | ||||
| 	} | ||||
| 	struct libinput_event_gesture *gevent = | ||||
| 		libinput_event_get_gesture_event(event); | ||||
| 	struct wlr_event_pointer_pinch_begin wlr_event = { | ||||
| 		.device = wlr_dev, | ||||
| 		.time_msec = | ||||
| 			usec_to_msec(libinput_event_gesture_get_time_usec(gevent)), | ||||
| 		.fingers = libinput_event_gesture_get_finger_count(gevent), | ||||
| 	}; | ||||
| 	wlr_signal_emit_safe(&wlr_dev->pointer->events.pinch_begin, &wlr_event); | ||||
| } | ||||
| 
 | ||||
| void handle_pointer_pinch_update(struct libinput_event *event, | ||||
| 		struct libinput_device *libinput_dev) { | ||||
| 	struct wlr_input_device *wlr_dev = | ||||
| 		get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev); | ||||
| 	if (!wlr_dev) { | ||||
| 		wlr_log(WLR_DEBUG, "Got a pointer gesture event for a device with no pointers?"); | ||||
| 		return; | ||||
| 	} | ||||
| 	struct libinput_event_gesture *gevent = | ||||
| 		libinput_event_get_gesture_event(event); | ||||
| 	struct wlr_event_pointer_pinch_update wlr_event = { | ||||
| 		.device = wlr_dev, | ||||
| 		.time_msec = | ||||
| 			usec_to_msec(libinput_event_gesture_get_time_usec(gevent)), | ||||
| 		.fingers = libinput_event_gesture_get_finger_count(gevent), | ||||
| 		.dx = libinput_event_gesture_get_dx(gevent), | ||||
| 		.dy = libinput_event_gesture_get_dy(gevent), | ||||
| 		.scale = libinput_event_gesture_get_scale(gevent), | ||||
| 		.rotation = libinput_event_gesture_get_angle_delta(gevent), | ||||
| 	}; | ||||
| 	wlr_signal_emit_safe(&wlr_dev->pointer->events.pinch_update, &wlr_event); | ||||
| } | ||||
| 
 | ||||
| void handle_pointer_pinch_end(struct libinput_event *event, | ||||
| 		struct libinput_device *libinput_dev) { | ||||
| 	struct wlr_input_device *wlr_dev = | ||||
| 		get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev); | ||||
| 	if (!wlr_dev) { | ||||
| 		wlr_log(WLR_DEBUG, "Got a pointer gesture event for a device with no pointers?"); | ||||
| 		return; | ||||
| 	} | ||||
| 	struct libinput_event_gesture *gevent = | ||||
| 		libinput_event_get_gesture_event(event); | ||||
| 	struct wlr_event_pointer_pinch_end wlr_event = { | ||||
| 		.device = wlr_dev, | ||||
| 		.time_msec = | ||||
| 			usec_to_msec(libinput_event_gesture_get_time_usec(gevent)), | ||||
| 		.cancelled = libinput_event_gesture_get_cancelled(gevent), | ||||
| 	}; | ||||
| 	wlr_signal_emit_safe(&wlr_dev->pointer->events.pinch_end, &wlr_event); | ||||
| } | ||||
|  |  | |||
|  | @ -54,6 +54,18 @@ void handle_pointer_button(struct libinput_event *event, | |||
| 		struct libinput_device *device); | ||||
| void handle_pointer_axis(struct libinput_event *event, | ||||
| 		struct libinput_device *device); | ||||
| void handle_pointer_swipe_begin(struct libinput_event *event, | ||||
| 		struct libinput_device *device); | ||||
| void handle_pointer_swipe_update(struct libinput_event *event, | ||||
| 		struct libinput_device *device); | ||||
| void handle_pointer_swipe_end(struct libinput_event *event, | ||||
| 		struct libinput_device *device); | ||||
| void handle_pointer_pinch_begin(struct libinput_event *event, | ||||
| 		struct libinput_device *device); | ||||
| void handle_pointer_pinch_update(struct libinput_event *event, | ||||
| 		struct libinput_device *device); | ||||
| void handle_pointer_pinch_end(struct libinput_event *event, | ||||
| 		struct libinput_device *device); | ||||
| 
 | ||||
| struct wlr_switch *create_libinput_switch( | ||||
| 		struct libinput_device *device); | ||||
|  |  | |||
|  | @ -39,6 +39,12 @@ struct roots_cursor { | |||
| 	struct wl_listener button; | ||||
| 	struct wl_listener axis; | ||||
| 	struct wl_listener frame; | ||||
| 	struct wl_listener swipe_begin; | ||||
| 	struct wl_listener swipe_update; | ||||
| 	struct wl_listener swipe_end; | ||||
| 	struct wl_listener pinch_begin; | ||||
| 	struct wl_listener pinch_update; | ||||
| 	struct wl_listener pinch_end; | ||||
| 
 | ||||
| 	struct wl_listener touch_down; | ||||
| 	struct wl_listener touch_up; | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ | |||
| #include <wlr/types/wlr_list.h> | ||||
| #include <wlr/types/wlr_output_layout.h> | ||||
| #include <wlr/types/wlr_output.h> | ||||
| #include <wlr/types/wlr_pointer_gestures_v1.h> | ||||
| #include <wlr/types/wlr_presentation_time.h> | ||||
| #include <wlr/types/wlr_gtk_primary_selection.h> | ||||
| #include <wlr/types/wlr_relative_pointer_v1.h> | ||||
|  | @ -67,6 +68,7 @@ struct roots_desktop { | |||
| 	struct wlr_presentation *presentation; | ||||
| 	struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager_v1; | ||||
| 	struct wlr_relative_pointer_manager_v1 *relative_pointer_manager; | ||||
| 	struct wlr_pointer_gestures_v1 *pointer_gestures; | ||||
| 
 | ||||
| 	struct wl_listener new_output; | ||||
| 	struct wl_listener layout_change; | ||||
|  |  | |||
|  | @ -25,6 +25,7 @@ install_headers( | |||
| 	'wlr_output_layout.h', | ||||
| 	'wlr_output.h', | ||||
| 	'wlr_pointer_constraints_v1.h', | ||||
| 	'wlr_pointer_gestures_v1.h', | ||||
| 	'wlr_pointer.h', | ||||
| 	'wlr_presentation_time.h', | ||||
| 	'wlr_primary_selection.h', | ||||
|  |  | |||
|  | @ -52,6 +52,12 @@ struct wlr_cursor { | |||
| 		struct wl_signal button; | ||||
| 		struct wl_signal axis; | ||||
| 		struct wl_signal frame; | ||||
| 		struct wl_signal swipe_begin; | ||||
| 		struct wl_signal swipe_update; | ||||
| 		struct wl_signal swipe_end; | ||||
| 		struct wl_signal pinch_begin; | ||||
| 		struct wl_signal pinch_update; | ||||
| 		struct wl_signal pinch_end; | ||||
| 
 | ||||
| 		struct wl_signal touch_up; | ||||
| 		struct wl_signal touch_down; | ||||
|  |  | |||
|  | @ -24,6 +24,12 @@ struct wlr_pointer { | |||
| 		struct wl_signal button; | ||||
| 		struct wl_signal axis; | ||||
| 		struct wl_signal frame; | ||||
| 		struct wl_signal swipe_begin; | ||||
| 		struct wl_signal swipe_update; | ||||
| 		struct wl_signal swipe_end; | ||||
| 		struct wl_signal pinch_begin; | ||||
| 		struct wl_signal pinch_update; | ||||
| 		struct wl_signal pinch_end; | ||||
| 	} events; | ||||
| 
 | ||||
| 	void *data; | ||||
|  | @ -71,4 +77,50 @@ struct wlr_event_pointer_axis { | |||
| 	int32_t delta_discrete; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_event_pointer_swipe_begin { | ||||
| 	struct wlr_input_device *device; | ||||
| 	uint32_t time_msec; | ||||
| 	uint32_t fingers; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_event_pointer_swipe_update { | ||||
| 	struct wlr_input_device *device; | ||||
| 	uint32_t time_msec; | ||||
| 	uint32_t fingers; | ||||
| 	// Relative coordinates of the logical center of the gesture
 | ||||
| 	// compared to the previous event.
 | ||||
| 	double dx, dy; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_event_pointer_swipe_end { | ||||
| 	struct wlr_input_device *device; | ||||
| 	uint32_t time_msec; | ||||
| 	bool cancelled; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_event_pointer_pinch_begin { | ||||
| 	struct wlr_input_device *device; | ||||
| 	uint32_t time_msec; | ||||
| 	uint32_t fingers; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_event_pointer_pinch_update { | ||||
| 	struct wlr_input_device *device; | ||||
| 	uint32_t time_msec; | ||||
| 	uint32_t fingers; | ||||
| 	// Relative coordinates of the logical center of the gesture
 | ||||
| 	// compared to the previous event.
 | ||||
| 	double dx, dy; | ||||
| 	// Absolute scale compared to the begin event
 | ||||
| 	double scale; | ||||
| 	// Relative angle in degrees clockwise compared to the previous event.
 | ||||
| 	double rotation; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_event_pointer_pinch_end { | ||||
| 	struct wlr_input_device *device; | ||||
| 	uint32_t time_msec; | ||||
| 	bool cancelled; | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										73
									
								
								include/wlr/types/wlr_pointer_gestures_v1.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								include/wlr/types/wlr_pointer_gestures_v1.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,73 @@ | |||
| /*
 | ||||
|  * This an unstable interface of wlroots. No guarantees are made regarding the | ||||
|  * future consistency of this API. | ||||
|  */ | ||||
| #ifndef WLR_USE_UNSTABLE | ||||
| #error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features" | ||||
| #endif | ||||
| 
 | ||||
| #ifndef WLR_TYPES_WLR_POINTER_GESTURES_V1_H | ||||
| #define WLR_TYPES_WLR_POINTER_GESTURES_V1_H | ||||
| 
 | ||||
| #include <wayland-server.h> | ||||
| #include <wlr/types/wlr_seat.h> | ||||
| #include <wlr/types/wlr_surface.h> | ||||
| 
 | ||||
| struct wlr_pointer_gestures_v1 { | ||||
| 	struct wl_global *global; | ||||
| 	struct wl_list resources; // wl_resource_get_link
 | ||||
| 	struct wl_list swipes;    // wl_resource_get_link
 | ||||
| 	struct wl_list pinches;   // wl_resource_get_link
 | ||||
| 
 | ||||
| 	struct wl_listener display_destroy; | ||||
| 
 | ||||
| 	struct { | ||||
| 		struct wl_signal destroy; | ||||
| 	} events; | ||||
| 
 | ||||
| 	void *data; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_pointer_gestures_v1 *wlr_pointer_gestures_v1_create( | ||||
| 	struct wl_display *display); | ||||
| 
 | ||||
| void wlr_pointer_gestures_v1_send_swipe_begin( | ||||
| 	struct wlr_pointer_gestures_v1 *gestures, | ||||
| 	struct wlr_seat *seat, | ||||
| 	uint32_t time_msec, | ||||
| 	uint32_t fingers); | ||||
| void wlr_pointer_gestures_v1_send_swipe_update( | ||||
| 	struct wlr_pointer_gestures_v1 *gestures, | ||||
| 	struct wlr_seat *seat, | ||||
| 	uint32_t time_msec, | ||||
| 	double dx, | ||||
| 	double dy); | ||||
| void wlr_pointer_gestures_v1_send_swipe_end( | ||||
| 	struct wlr_pointer_gestures_v1 *gestures, | ||||
| 	struct wlr_seat *seat, | ||||
| 	uint32_t time_msec, | ||||
| 	bool cancelled); | ||||
| 
 | ||||
| void wlr_pointer_gestures_v1_send_pinch_begin( | ||||
| 	struct wlr_pointer_gestures_v1 *gestures, | ||||
| 	struct wlr_seat *seat, | ||||
| 	uint32_t time_msec, | ||||
| 	uint32_t fingers); | ||||
| void wlr_pointer_gestures_v1_send_pinch_update( | ||||
| 	struct wlr_pointer_gestures_v1 *gestures, | ||||
| 	struct wlr_seat *seat, | ||||
| 	uint32_t time_msec, | ||||
| 	double dx, | ||||
| 	double dy, | ||||
| 	double scale, | ||||
| 	double rotation); | ||||
| void wlr_pointer_gestures_v1_send_pinch_end( | ||||
| 	struct wlr_pointer_gestures_v1 *gestures, | ||||
| 	struct wlr_seat *seat, | ||||
| 	uint32_t time_msec, | ||||
| 	bool cancelled); | ||||
| 
 | ||||
| void wlr_pointer_gestures_v1_destroy( | ||||
| 	struct wlr_pointer_gestures_v1 *pointer_gestures_v1); | ||||
| 
 | ||||
| #endif | ||||
|  | @ -17,6 +17,7 @@ protocols = [ | |||
| 	[wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml'], | ||||
| 	[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'], | ||||
| 	[wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'], | ||||
| 	[wl_protocol_dir, 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml'], | ||||
| 	[wl_protocol_dir, 'unstable/relative-pointer/relative-pointer-unstable-v1.xml'], | ||||
| 	[wl_protocol_dir, 'unstable/tablet/tablet-unstable-v2.xml'], | ||||
| 	[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v3.xml'], | ||||
|  |  | |||
|  | @ -1084,6 +1084,8 @@ struct roots_desktop *desktop_create(struct roots_server *server, | |||
| 		wlr_foreign_toplevel_manager_v1_create(server->wl_display); | ||||
| 	desktop->relative_pointer_manager = | ||||
| 		wlr_relative_pointer_manager_v1_create(server->wl_display); | ||||
| 	desktop->pointer_gestures = | ||||
| 		wlr_pointer_gestures_v1_create(server->wl_display); | ||||
| 
 | ||||
| 	wlr_data_control_manager_v1_create(server->wl_display); | ||||
| 
 | ||||
|  |  | |||
|  | @ -85,6 +85,67 @@ static void handle_cursor_frame(struct wl_listener *listener, void *data) { | |||
| 	roots_cursor_handle_frame(cursor); | ||||
| } | ||||
| 
 | ||||
| static void handle_swipe_begin(struct wl_listener *listener, void *data) { | ||||
| 	struct roots_cursor *cursor = | ||||
| 		wl_container_of(listener, cursor, swipe_begin); | ||||
| 	struct wlr_pointer_gestures_v1 *gestures = | ||||
| 		cursor->seat->input->server->desktop->pointer_gestures; | ||||
| 	struct wlr_event_pointer_swipe_begin *event = data; | ||||
| 	wlr_pointer_gestures_v1_send_swipe_begin(gestures, cursor->seat->seat, | ||||
| 			event->time_msec, event->fingers); | ||||
| } | ||||
| 
 | ||||
| static void handle_swipe_update(struct wl_listener *listener, void *data) { | ||||
| 	struct roots_cursor *cursor = | ||||
| 		wl_container_of(listener, cursor, swipe_update); | ||||
| 	struct wlr_pointer_gestures_v1 *gestures = | ||||
| 		cursor->seat->input->server->desktop->pointer_gestures; | ||||
| 	struct wlr_event_pointer_swipe_update *event = data; | ||||
| 	wlr_pointer_gestures_v1_send_swipe_update(gestures, cursor->seat->seat, | ||||
| 			event->time_msec, event->dx, event->dy); | ||||
| } | ||||
| 
 | ||||
| static void handle_swipe_end(struct wl_listener *listener, void *data) { | ||||
| 	struct roots_cursor *cursor = | ||||
| 		wl_container_of(listener, cursor, swipe_end); | ||||
| 	struct wlr_pointer_gestures_v1 *gestures = | ||||
| 		cursor->seat->input->server->desktop->pointer_gestures; | ||||
| 	struct wlr_event_pointer_swipe_end *event = data; | ||||
| 	wlr_pointer_gestures_v1_send_swipe_end(gestures, cursor->seat->seat, | ||||
| 			event->time_msec, event->cancelled); | ||||
| } | ||||
| 
 | ||||
| static void handle_pinch_begin(struct wl_listener *listener, void *data) { | ||||
| 	struct roots_cursor *cursor = | ||||
| 		wl_container_of(listener, cursor, pinch_begin); | ||||
| 	struct wlr_pointer_gestures_v1 *gestures = | ||||
| 		cursor->seat->input->server->desktop->pointer_gestures; | ||||
| 	struct wlr_event_pointer_pinch_begin *event = data; | ||||
| 	wlr_pointer_gestures_v1_send_pinch_begin(gestures, cursor->seat->seat, | ||||
| 			event->time_msec, event->fingers); | ||||
| } | ||||
| 
 | ||||
| static void handle_pinch_update(struct wl_listener *listener, void *data) { | ||||
| 	struct roots_cursor *cursor = | ||||
| 		wl_container_of(listener, cursor, pinch_update); | ||||
| 	struct wlr_pointer_gestures_v1 *gestures = | ||||
| 		cursor->seat->input->server->desktop->pointer_gestures; | ||||
| 	struct wlr_event_pointer_pinch_update *event = data; | ||||
| 	wlr_pointer_gestures_v1_send_pinch_update(gestures, cursor->seat->seat, | ||||
| 			event->time_msec, event->dx, event->dy, | ||||
| 			event->scale, event->rotation); | ||||
| } | ||||
| 
 | ||||
| static void handle_pinch_end(struct wl_listener *listener, void *data) { | ||||
| 	struct roots_cursor *cursor = | ||||
| 		wl_container_of(listener, cursor, pinch_end); | ||||
| 	struct wlr_pointer_gestures_v1 *gestures = | ||||
| 		cursor->seat->input->server->desktop->pointer_gestures; | ||||
| 	struct wlr_event_pointer_pinch_end *event = data; | ||||
| 	wlr_pointer_gestures_v1_send_pinch_end(gestures, cursor->seat->seat, | ||||
| 			event->time_msec, event->cancelled); | ||||
| } | ||||
| 
 | ||||
| static void handle_switch_toggle(struct wl_listener *listener, void *data) { | ||||
| 	struct roots_switch *lid_switch = | ||||
| 		wl_container_of(listener, lid_switch, toggle); | ||||
|  | @ -454,6 +515,24 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { | |||
| 	wl_signal_add(&wlr_cursor->events.frame, &seat->cursor->frame); | ||||
| 	seat->cursor->frame.notify = handle_cursor_frame; | ||||
| 
 | ||||
| 	wl_signal_add(&wlr_cursor->events.swipe_begin, &seat->cursor->swipe_begin); | ||||
| 	seat->cursor->swipe_begin.notify = handle_swipe_begin; | ||||
| 
 | ||||
| 	wl_signal_add(&wlr_cursor->events.swipe_update, &seat->cursor->swipe_update); | ||||
| 	seat->cursor->swipe_update.notify = handle_swipe_update; | ||||
| 
 | ||||
| 	wl_signal_add(&wlr_cursor->events.swipe_end, &seat->cursor->swipe_end); | ||||
| 	seat->cursor->swipe_end.notify = handle_swipe_end; | ||||
| 
 | ||||
| 	wl_signal_add(&wlr_cursor->events.pinch_begin, &seat->cursor->pinch_begin); | ||||
| 	seat->cursor->pinch_begin.notify = handle_pinch_begin; | ||||
| 
 | ||||
| 	wl_signal_add(&wlr_cursor->events.pinch_update, &seat->cursor->pinch_update); | ||||
| 	seat->cursor->pinch_update.notify = handle_pinch_update; | ||||
| 
 | ||||
| 	wl_signal_add(&wlr_cursor->events.pinch_end, &seat->cursor->pinch_end); | ||||
| 	seat->cursor->pinch_end.notify = handle_pinch_end; | ||||
| 
 | ||||
| 	wl_signal_add(&wlr_cursor->events.touch_down, &seat->cursor->touch_down); | ||||
| 	seat->cursor->touch_down.notify = handle_touch_down; | ||||
| 
 | ||||
|  |  | |||
|  | @ -48,6 +48,7 @@ lib_wlr_types = static_library( | |||
| 		'wlr_output_layout.c', | ||||
| 		'wlr_output.c', | ||||
| 		'wlr_pointer_constraints_v1.c', | ||||
| 		'wlr_pointer_gestures_v1.c', | ||||
| 		'wlr_pointer.c', | ||||
| 		'wlr_presentation_time.c', | ||||
| 		'wlr_primary_selection.c', | ||||
|  |  | |||
|  | @ -22,6 +22,12 @@ struct wlr_cursor_device { | |||
| 	struct wl_listener button; | ||||
| 	struct wl_listener axis; | ||||
| 	struct wl_listener frame; | ||||
| 	struct wl_listener swipe_begin; | ||||
| 	struct wl_listener swipe_update; | ||||
| 	struct wl_listener swipe_end; | ||||
| 	struct wl_listener pinch_begin; | ||||
| 	struct wl_listener pinch_update; | ||||
| 	struct wl_listener pinch_end; | ||||
| 
 | ||||
| 	struct wl_listener touch_down; | ||||
| 	struct wl_listener touch_up; | ||||
|  | @ -83,6 +89,12 @@ struct wlr_cursor *wlr_cursor_create(void) { | |||
| 	wl_signal_init(&cur->events.button); | ||||
| 	wl_signal_init(&cur->events.axis); | ||||
| 	wl_signal_init(&cur->events.frame); | ||||
| 	wl_signal_init(&cur->events.swipe_begin); | ||||
| 	wl_signal_init(&cur->events.swipe_update); | ||||
| 	wl_signal_init(&cur->events.swipe_end); | ||||
| 	wl_signal_init(&cur->events.pinch_begin); | ||||
| 	wl_signal_init(&cur->events.pinch_update); | ||||
| 	wl_signal_init(&cur->events.pinch_end); | ||||
| 
 | ||||
| 	// touch signals
 | ||||
| 	wl_signal_init(&cur->events.touch_up); | ||||
|  | @ -136,6 +148,12 @@ static void cursor_device_destroy(struct wlr_cursor_device *c_device) { | |||
| 		wl_list_remove(&c_device->button.link); | ||||
| 		wl_list_remove(&c_device->axis.link); | ||||
| 		wl_list_remove(&c_device->frame.link); | ||||
| 		wl_list_remove(&c_device->swipe_begin.link); | ||||
| 		wl_list_remove(&c_device->swipe_update.link); | ||||
| 		wl_list_remove(&c_device->swipe_end.link); | ||||
| 		wl_list_remove(&c_device->pinch_begin.link); | ||||
| 		wl_list_remove(&c_device->pinch_update.link); | ||||
| 		wl_list_remove(&c_device->pinch_end.link); | ||||
| 	} else if (dev->type == WLR_INPUT_DEVICE_TOUCH) { | ||||
| 		wl_list_remove(&c_device->touch_down.link); | ||||
| 		wl_list_remove(&c_device->touch_up.link); | ||||
|  | @ -423,6 +441,42 @@ static void handle_pointer_frame(struct wl_listener *listener, void *data) { | |||
| 	wlr_signal_emit_safe(&device->cursor->events.frame, device->cursor); | ||||
| } | ||||
| 
 | ||||
| static void handle_pointer_swipe_begin(struct wl_listener *listener, void *data) { | ||||
| 	struct wlr_event_pointer_swipe_begin *event = data; | ||||
| 	struct wlr_cursor_device *device = wl_container_of(listener, device, swipe_begin); | ||||
| 	wlr_signal_emit_safe(&device->cursor->events.swipe_begin, event); | ||||
| } | ||||
| 
 | ||||
| static void handle_pointer_swipe_update(struct wl_listener *listener, void *data) { | ||||
| 	struct wlr_event_pointer_swipe_update *event = data; | ||||
| 	struct wlr_cursor_device *device = wl_container_of(listener, device, swipe_update); | ||||
| 	wlr_signal_emit_safe(&device->cursor->events.swipe_update, event); | ||||
| } | ||||
| 
 | ||||
| static void handle_pointer_swipe_end(struct wl_listener *listener, void *data) { | ||||
| 	struct wlr_event_pointer_swipe_end *event = data; | ||||
| 	struct wlr_cursor_device *device = wl_container_of(listener, device, swipe_end); | ||||
| 	wlr_signal_emit_safe(&device->cursor->events.swipe_end, event); | ||||
| } | ||||
| 
 | ||||
| static void handle_pointer_pinch_begin(struct wl_listener *listener, void *data) { | ||||
| 	struct wlr_event_pointer_pinch_begin *event = data; | ||||
| 	struct wlr_cursor_device *device = wl_container_of(listener, device, pinch_begin); | ||||
| 	wlr_signal_emit_safe(&device->cursor->events.pinch_begin, event); | ||||
| } | ||||
| 
 | ||||
| static void handle_pointer_pinch_update(struct wl_listener *listener, void *data) { | ||||
| 	struct wlr_event_pointer_pinch_update *event = data; | ||||
| 	struct wlr_cursor_device *device = wl_container_of(listener, device, pinch_update); | ||||
| 	wlr_signal_emit_safe(&device->cursor->events.pinch_update, event); | ||||
| } | ||||
| 
 | ||||
| static void handle_pointer_pinch_end(struct wl_listener *listener, void *data) { | ||||
| 	struct wlr_event_pointer_pinch_end *event = data; | ||||
| 	struct wlr_cursor_device *device = wl_container_of(listener, device, pinch_end); | ||||
| 	wlr_signal_emit_safe(&device->cursor->events.pinch_end, event); | ||||
| } | ||||
| 
 | ||||
| static void handle_touch_up(struct wl_listener *listener, void *data) { | ||||
| 	struct wlr_event_touch_up *event = data; | ||||
| 	struct wlr_cursor_device *device; | ||||
|  | @ -549,6 +603,24 @@ static struct wlr_cursor_device *cursor_device_create( | |||
| 
 | ||||
| 		wl_signal_add(&device->pointer->events.frame, &c_device->frame); | ||||
| 		c_device->frame.notify = handle_pointer_frame; | ||||
| 
 | ||||
| 		wl_signal_add(&device->pointer->events.swipe_begin, &c_device->swipe_begin); | ||||
| 		c_device->swipe_begin.notify = handle_pointer_swipe_begin; | ||||
| 
 | ||||
| 		wl_signal_add(&device->pointer->events.swipe_update, &c_device->swipe_update); | ||||
| 		c_device->swipe_update.notify = handle_pointer_swipe_update; | ||||
| 
 | ||||
| 		wl_signal_add(&device->pointer->events.swipe_end, &c_device->swipe_end); | ||||
| 		c_device->swipe_end.notify = handle_pointer_swipe_end; | ||||
| 
 | ||||
| 		wl_signal_add(&device->pointer->events.pinch_begin, &c_device->pinch_begin); | ||||
| 		c_device->pinch_begin.notify = handle_pointer_pinch_begin; | ||||
| 
 | ||||
| 		wl_signal_add(&device->pointer->events.pinch_update, &c_device->pinch_update); | ||||
| 		c_device->pinch_update.notify = handle_pointer_pinch_update; | ||||
| 
 | ||||
| 		wl_signal_add(&device->pointer->events.pinch_end, &c_device->pinch_end); | ||||
| 		c_device->pinch_end.notify = handle_pointer_pinch_end; | ||||
| 	} else if (device->type == WLR_INPUT_DEVICE_TOUCH) { | ||||
| 		wl_signal_add(&device->touch->events.motion, &c_device->touch_motion); | ||||
| 		c_device->touch_motion.notify = handle_touch_motion; | ||||
|  |  | |||
|  | @ -12,6 +12,12 @@ void wlr_pointer_init(struct wlr_pointer *pointer, | |||
| 	wl_signal_init(&pointer->events.button); | ||||
| 	wl_signal_init(&pointer->events.axis); | ||||
| 	wl_signal_init(&pointer->events.frame); | ||||
| 	wl_signal_init(&pointer->events.swipe_begin); | ||||
| 	wl_signal_init(&pointer->events.swipe_update); | ||||
| 	wl_signal_init(&pointer->events.swipe_end); | ||||
| 	wl_signal_init(&pointer->events.pinch_begin); | ||||
| 	wl_signal_init(&pointer->events.pinch_update); | ||||
| 	wl_signal_init(&pointer->events.pinch_end); | ||||
| } | ||||
| 
 | ||||
| void wlr_pointer_destroy(struct wlr_pointer *pointer) { | ||||
|  |  | |||
							
								
								
									
										339
									
								
								types/wlr_pointer_gestures_v1.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										339
									
								
								types/wlr_pointer_gestures_v1.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,339 @@ | |||
| #ifndef _POSIX_C_SOURCE | ||||
| #define _POSIX_C_SOURCE 200809L | ||||
| #endif | ||||
| 
 | ||||
| #include <assert.h> | ||||
| #include <stdlib.h> | ||||
| #include <wayland-server.h> | ||||
| #include <wlr/types/wlr_pointer.h> | ||||
| #include <wlr/types/wlr_pointer_gestures_v1.h> | ||||
| #include <wlr/util/log.h> | ||||
| #include "util/signal.h" | ||||
| #include "pointer-gestures-unstable-v1-protocol.h" | ||||
| 
 | ||||
| #define POINTER_GESTURES_VERSION 1 | ||||
| 
 | ||||
| static void resource_handle_destroy(struct wl_client *client, | ||||
| 		struct wl_resource *resource) { | ||||
| 	wl_resource_destroy(resource); | ||||
| } | ||||
| 
 | ||||
| static void resource_remove_from_list(struct wl_resource *resource) { | ||||
| 	wl_list_remove(wl_resource_get_link(resource)); | ||||
| } | ||||
| 
 | ||||
| static const struct zwp_pointer_gestures_v1_interface gestures_impl; | ||||
| static const struct zwp_pointer_gesture_swipe_v1_interface swipe_impl; | ||||
| static const struct zwp_pointer_gesture_pinch_v1_interface pinch_impl; | ||||
| 
 | ||||
| static struct wlr_pointer_gestures_v1 *pointer_gestures_from_resource( | ||||
| 		struct wl_resource *resource) { | ||||
| 	assert(wl_resource_instance_of(resource, | ||||
| 				&zwp_pointer_gestures_v1_interface, &gestures_impl)); | ||||
| 	return wl_resource_get_user_data(resource); | ||||
| } | ||||
| 
 | ||||
| static struct wlr_seat *seat_from_pointer_resource( | ||||
| 		struct wl_resource *resource) { | ||||
| 	assert(wl_resource_instance_of(resource, | ||||
| 				&zwp_pointer_gesture_swipe_v1_interface, &swipe_impl) || | ||||
| 			wl_resource_instance_of(resource, | ||||
| 				&zwp_pointer_gesture_pinch_v1_interface, &pinch_impl)); | ||||
| 	return wl_resource_get_user_data(resource); | ||||
| } | ||||
| 
 | ||||
| void wlr_pointer_gestures_v1_send_swipe_begin( | ||||
| 		struct wlr_pointer_gestures_v1 *gestures, | ||||
| 		struct wlr_seat *seat, | ||||
| 		uint32_t time_msec, | ||||
| 		uint32_t fingers) { | ||||
| 	struct wlr_surface *focus = seat->pointer_state.focused_surface; | ||||
| 	if (focus == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wl_client *focus_client = wl_resource_get_client(focus->resource); | ||||
| 	uint32_t serial = wl_display_next_serial( | ||||
| 			wl_client_get_display(focus_client)); | ||||
| 
 | ||||
| 	struct wl_resource *gesture; | ||||
| 	wl_resource_for_each(gesture, &gestures->swipes) { | ||||
| 		struct wlr_seat *gesture_seat = seat_from_pointer_resource(gesture); | ||||
| 		struct wl_client *gesture_client = wl_resource_get_client(gesture); | ||||
| 		if (gesture_seat != seat || gesture_client != focus_client) { | ||||
| 			continue; | ||||
| 		} | ||||
| 		zwp_pointer_gesture_swipe_v1_send_begin(gesture, serial, | ||||
| 				time_msec, focus->resource, fingers); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void wlr_pointer_gestures_v1_send_swipe_update( | ||||
| 		struct wlr_pointer_gestures_v1 *gestures, | ||||
| 		struct wlr_seat *seat, | ||||
| 		uint32_t time_msec, | ||||
| 		double dx, | ||||
| 		double dy) { | ||||
| 	struct wlr_surface *focus = seat->pointer_state.focused_surface; | ||||
| 	if (focus == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wl_client *focus_client = wl_resource_get_client(focus->resource); | ||||
| 
 | ||||
| 	struct wl_resource *gesture; | ||||
| 	wl_resource_for_each(gesture, &gestures->swipes) { | ||||
| 		struct wlr_seat *gesture_seat = seat_from_pointer_resource(gesture); | ||||
| 		struct wl_client *gesture_client = wl_resource_get_client(gesture); | ||||
| 		if (gesture_seat != seat || gesture_client != focus_client) { | ||||
| 			continue; | ||||
| 		} | ||||
| 		zwp_pointer_gesture_swipe_v1_send_update(gesture, time_msec, | ||||
| 				wl_fixed_from_double(dx), wl_fixed_from_double(dy)); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void wlr_pointer_gestures_v1_send_swipe_end( | ||||
| 		struct wlr_pointer_gestures_v1 *gestures, | ||||
| 		struct wlr_seat *seat, | ||||
| 		uint32_t time_msec, | ||||
| 		bool cancelled) { | ||||
| 	struct wlr_surface *focus = seat->pointer_state.focused_surface; | ||||
| 	if (focus == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wl_client *focus_client = wl_resource_get_client(focus->resource); | ||||
| 	uint32_t serial = wl_display_next_serial( | ||||
| 			wl_client_get_display(focus_client)); | ||||
| 
 | ||||
| 	struct wl_resource *gesture; | ||||
| 	wl_resource_for_each(gesture, &gestures->swipes) { | ||||
| 		struct wlr_seat *gesture_seat = seat_from_pointer_resource(gesture); | ||||
| 		struct wl_client *gesture_client = wl_resource_get_client(gesture); | ||||
| 		if (gesture_seat != seat || gesture_client != focus_client) { | ||||
| 			continue; | ||||
| 		} | ||||
| 		zwp_pointer_gesture_swipe_v1_send_end(gesture, serial, | ||||
| 				time_msec, cancelled); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static const struct zwp_pointer_gesture_swipe_v1_interface swipe_impl = { | ||||
| 	.destroy = resource_handle_destroy, | ||||
| }; | ||||
| 
 | ||||
| static void get_swipe_gesture(struct wl_client *client, | ||||
| 		struct wl_resource *gestures_resource, | ||||
| 		uint32_t id, | ||||
| 		struct wl_resource *pointer_resource) { | ||||
| 	struct wlr_seat_client *seat_client = | ||||
| 		wlr_seat_client_from_pointer_resource(pointer_resource); | ||||
| 	struct wlr_seat *seat = NULL; | ||||
| 
 | ||||
| 	if (seat_client != NULL) { | ||||
| 		seat = seat_client->seat; | ||||
| 	} | ||||
| 	// Otherwise, the resource will be inert
 | ||||
| 	// (NULL seat, so all seat comparisons will fail)
 | ||||
| 
 | ||||
| 	struct wlr_pointer_gestures_v1 *gestures = | ||||
| 		pointer_gestures_from_resource(gestures_resource); | ||||
| 
 | ||||
| 	struct wl_resource *gesture = wl_resource_create(client, | ||||
| 		&zwp_pointer_gesture_swipe_v1_interface, | ||||
| 		wl_resource_get_version(gestures_resource), | ||||
| 		id); | ||||
| 	if (gesture == NULL) { | ||||
| 		wl_client_post_no_memory(client); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	wl_resource_set_implementation(gesture, &swipe_impl, seat, | ||||
| 			resource_remove_from_list); | ||||
| 	wl_list_insert(&gestures->swipes, wl_resource_get_link(gesture)); | ||||
| } | ||||
| 
 | ||||
| void wlr_pointer_gestures_v1_send_pinch_begin( | ||||
| 		struct wlr_pointer_gestures_v1 *gestures, | ||||
| 		struct wlr_seat *seat, | ||||
| 		uint32_t time_msec, | ||||
| 		uint32_t fingers) { | ||||
| 	struct wlr_surface *focus = seat->pointer_state.focused_surface; | ||||
| 	if (focus == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wl_client *focus_client = wl_resource_get_client(focus->resource); | ||||
| 	uint32_t serial = wl_display_next_serial( | ||||
| 			wl_client_get_display(focus_client)); | ||||
| 
 | ||||
| 	struct wl_resource *gesture; | ||||
| 	wl_resource_for_each(gesture, &gestures->pinches) { | ||||
| 		struct wlr_seat *gesture_seat = seat_from_pointer_resource(gesture); | ||||
| 		struct wl_client *gesture_client = wl_resource_get_client(gesture); | ||||
| 		if (gesture_seat != seat || gesture_client != focus_client) { | ||||
| 			continue; | ||||
| 		} | ||||
| 		zwp_pointer_gesture_pinch_v1_send_begin(gesture, serial, | ||||
| 				time_msec, focus->resource, fingers); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void wlr_pointer_gestures_v1_send_pinch_update( | ||||
| 		struct wlr_pointer_gestures_v1 *gestures, | ||||
| 		struct wlr_seat *seat, | ||||
| 		uint32_t time_msec, | ||||
| 		double dx, | ||||
| 		double dy, | ||||
| 		double scale, | ||||
| 		double rotation) { | ||||
| 	struct wlr_surface *focus = seat->pointer_state.focused_surface; | ||||
| 	if (focus == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wl_client *focus_client = wl_resource_get_client(focus->resource); | ||||
| 
 | ||||
| 	struct wl_resource *gesture; | ||||
| 	wl_resource_for_each(gesture, &gestures->pinches) { | ||||
| 		struct wlr_seat *gesture_seat = seat_from_pointer_resource(gesture); | ||||
| 		struct wl_client *gesture_client = wl_resource_get_client(gesture); | ||||
| 		if (gesture_seat != seat || gesture_client != focus_client) { | ||||
| 			continue; | ||||
| 		} | ||||
| 		zwp_pointer_gesture_pinch_v1_send_update(gesture, time_msec, | ||||
| 				wl_fixed_from_double(dx), wl_fixed_from_double(dy), | ||||
| 				wl_fixed_from_double(scale), | ||||
| 				wl_fixed_from_double(rotation)); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void wlr_pointer_gestures_v1_send_pinch_end( | ||||
| 		struct wlr_pointer_gestures_v1 *gestures, | ||||
| 		struct wlr_seat *seat, | ||||
| 		uint32_t time_msec, | ||||
| 		bool cancelled) { | ||||
| 	struct wlr_surface *focus = seat->pointer_state.focused_surface; | ||||
| 	if (focus == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wl_client *focus_client = wl_resource_get_client(focus->resource); | ||||
| 	uint32_t serial = wl_display_next_serial( | ||||
| 			wl_client_get_display(focus_client)); | ||||
| 
 | ||||
| 	struct wl_resource *gesture; | ||||
| 	wl_resource_for_each(gesture, &gestures->pinches) { | ||||
| 		struct wlr_seat *gesture_seat = seat_from_pointer_resource(gesture); | ||||
| 		struct wl_client *gesture_client = wl_resource_get_client(gesture); | ||||
| 		if (gesture_seat != seat || gesture_client != focus_client) { | ||||
| 			continue; | ||||
| 		} | ||||
| 		zwp_pointer_gesture_pinch_v1_send_end(gesture, serial, | ||||
| 				time_msec, cancelled); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static const struct zwp_pointer_gesture_pinch_v1_interface pinch_impl = { | ||||
| 	.destroy = resource_handle_destroy, | ||||
| }; | ||||
| 
 | ||||
| static void get_pinch_gesture(struct wl_client *client, | ||||
| 		struct wl_resource *gestures_resource, | ||||
| 		uint32_t id, | ||||
| 		struct wl_resource *pointer_resource) { | ||||
| 	struct wlr_seat_client *seat_client = | ||||
| 		wlr_seat_client_from_pointer_resource(pointer_resource); | ||||
| 	struct wlr_seat *seat = NULL; | ||||
| 
 | ||||
| 	if (seat_client != NULL) { | ||||
| 		seat = seat_client->seat; | ||||
| 	} | ||||
| 	// Otherwise, the resource will be inert
 | ||||
| 	// (NULL seat, so all seat comparisons will fail)
 | ||||
| 
 | ||||
| 	struct wlr_pointer_gestures_v1 *gestures = | ||||
| 		pointer_gestures_from_resource(gestures_resource); | ||||
| 
 | ||||
| 	struct wl_resource *gesture = wl_resource_create(client, | ||||
| 		&zwp_pointer_gesture_pinch_v1_interface, | ||||
| 		wl_resource_get_version(gestures_resource), | ||||
| 		id); | ||||
| 	if (gesture == NULL) { | ||||
| 		wl_client_post_no_memory(client); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	wl_resource_set_implementation(gesture, &pinch_impl, seat, | ||||
| 			resource_remove_from_list); | ||||
| 	wl_list_insert(&gestures->pinches, wl_resource_get_link(gesture)); | ||||
| } | ||||
| 
 | ||||
| static const struct zwp_pointer_gestures_v1_interface gestures_impl = { | ||||
| 	.get_swipe_gesture = get_swipe_gesture, | ||||
| 	.get_pinch_gesture = get_pinch_gesture, | ||||
| }; | ||||
| 
 | ||||
| static void pointer_gestures_v1_bind(struct wl_client *wl_client, void *data, | ||||
| 		uint32_t version, uint32_t id) { | ||||
| 	struct wlr_pointer_gestures_v1 *gestures = data; | ||||
| 
 | ||||
| 	struct wl_resource *resource = wl_resource_create(wl_client, | ||||
| 			&zwp_pointer_gestures_v1_interface, version, id); | ||||
| 	if (resource == NULL) { | ||||
| 		wl_client_post_no_memory(wl_client); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	wl_resource_set_implementation(resource, | ||||
| 			&gestures_impl, gestures, resource_remove_from_list); | ||||
| 	wl_list_insert(&gestures->resources, wl_resource_get_link(resource)); | ||||
| } | ||||
| 
 | ||||
| static void handle_display_destroy(struct wl_listener *listener, void *data) { | ||||
| 	struct wlr_pointer_gestures_v1 *tablet = | ||||
| 		wl_container_of(listener, tablet, display_destroy); | ||||
| 	wlr_pointer_gestures_v1_destroy(tablet); | ||||
| } | ||||
| 
 | ||||
| void wlr_pointer_gestures_v1_destroy(struct wlr_pointer_gestures_v1 *gestures) { | ||||
| 	struct wl_resource *resource, *tmp; | ||||
| 	wl_resource_for_each_safe(resource, tmp, &gestures->resources) { | ||||
| 		wl_resource_destroy(resource); | ||||
| 	} | ||||
| 	wl_resource_for_each_safe(resource, tmp, &gestures->swipes) { | ||||
| 		wl_resource_destroy(resource); | ||||
| 	} | ||||
| 	wl_resource_for_each_safe(resource, tmp, &gestures->pinches) { | ||||
| 		wl_resource_destroy(resource); | ||||
| 	} | ||||
| 	wl_global_destroy(gestures->global); | ||||
| 	free(gestures); | ||||
| } | ||||
| 
 | ||||
| struct wlr_pointer_gestures_v1 *wlr_pointer_gestures_v1_create( | ||||
| 		struct wl_display *display) { | ||||
| 	struct wlr_pointer_gestures_v1 *gestures = | ||||
| 		calloc(1, sizeof(struct wlr_pointer_gestures_v1)); | ||||
| 	if (!gestures) { | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	wl_list_init(&gestures->resources); | ||||
| 	wl_list_init(&gestures->swipes); | ||||
| 	wl_list_init(&gestures->pinches); | ||||
| 
 | ||||
| 	gestures->global = wl_global_create(display, | ||||
| 			&zwp_pointer_gestures_v1_interface, POINTER_GESTURES_VERSION, | ||||
| 			gestures, pointer_gestures_v1_bind); | ||||
| 	if (gestures->global == NULL) { | ||||
| 		free(gestures); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	gestures->display_destroy.notify = handle_display_destroy; | ||||
| 	wl_display_add_destroy_listener(display, &gestures->display_destroy); | ||||
| 
 | ||||
| 	return gestures; | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Greg V
						Greg V