diff --git a/pointer-gestures-unstable-v1.xml b/pointer-gestures-unstable-v1.xml new file mode 100644 index 0000000..f92a116 --- /dev/null +++ b/pointer-gestures-unstable-v1.xml @@ -0,0 +1,253 @@ + + + + + + A global interface to provide semantic touchpad gestures for a given + pointer. + + Three gestures are currently supported: swipe, pinch, and hold. + Pinch and swipe gestures follow a three-stage cycle: begin, update, + end, hold gestures follow a two-stage cycle: begin and end. All + gestures are identified by a unique id. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible changes + may be added together with the corresponding interface version bump. + Backward incompatible changes are done by bumping the version number in + the protocol and interface names and resetting the interface version. + Once the protocol is to be declared stable, the 'z' prefix and the + version number in the protocol and interface names are removed and the + interface version number is reset. + + + + + Create a swipe gesture object. See the + wl_pointer_gesture_swipe interface for details. + + + + + + + + Create a pinch gesture object. See the + wl_pointer_gesture_pinch interface for details. + + + + + + + + + + Destroy the pointer gesture object. Swipe, pinch and hold objects + created via this gesture object remain valid. + + + + + + + + Create a hold gesture object. See the + wl_pointer_gesture_hold interface for details. + + + + + + + + + + A swipe gesture object notifies a client about a multi-finger swipe + gesture detected on an indirect input device such as a touchpad. + The gesture is usually initiated by multiple fingers moving in the + same direction but once initiated the direction may change. + The precise conditions of when such a gesture is detected are + implementation-dependent. + + A gesture consists of three stages: begin, update (optional) and end. + There cannot be multiple simultaneous hold, pinch or swipe gestures on a + same pointer/seat, how compositors prevent these situations is + implementation-dependent. + + A gesture may be cancelled by the compositor or the hardware. + Clients should not consider performing permanent or irreversible + actions until the end of a gesture has been received. + + + + + + + + + This event is sent when a multi-finger swipe gesture is detected + on the device. + + + + + + + + + + This event is sent when a multi-finger swipe gesture changes the + position of the logical center. + + The dx and dy coordinates are relative coordinates of the logical + center of the gesture compared to the previous event. + + + + + + + + + This event is sent when a multi-finger swipe gesture ceases to + be valid. This may happen when one or more fingers are lifted or + the gesture is cancelled. + + When a gesture is cancelled, the client should undo state changes + caused by this gesture. What causes a gesture to be cancelled is + implementation-dependent. + + + + + + + + + + A pinch gesture object notifies a client about a multi-finger pinch + gesture detected on an indirect input device such as a touchpad. + The gesture is usually initiated by multiple fingers moving towards + each other or away from each other, or by two or more fingers rotating + around a logical center of gravity. The precise conditions of when + such a gesture is detected are implementation-dependent. + + A gesture consists of three stages: begin, update (optional) and end. + There cannot be multiple simultaneous hold, pinch or swipe gestures on a + same pointer/seat, how compositors prevent these situations is + implementation-dependent. + + A gesture may be cancelled by the compositor or the hardware. + Clients should not consider performing permanent or irreversible + actions until the end of a gesture has been received. + + + + + + + + + This event is sent when a multi-finger pinch gesture is detected + on the device. + + + + + + + + + + This event is sent when a multi-finger pinch gesture changes the + position of the logical center, the rotation or the relative scale. + + The dx and dy coordinates are relative coordinates in the + surface coordinate space of the logical center of the gesture. + + The scale factor is an absolute scale compared to the + pointer_gesture_pinch.begin event, e.g. a scale of 2 means the fingers + are now twice as far apart as on pointer_gesture_pinch.begin. + + The rotation is the relative angle in degrees clockwise compared to the previous + pointer_gesture_pinch.begin or pointer_gesture_pinch.update event. + + + + + + + + + + + This event is sent when a multi-finger pinch gesture ceases to + be valid. This may happen when one or more fingers are lifted or + the gesture is cancelled. + + When a gesture is cancelled, the client should undo state changes + caused by this gesture. What causes a gesture to be cancelled is + implementation-dependent. + + + + + + + + + + + A hold gesture object notifies a client about a single- or + multi-finger hold gesture detected on an indirect input device such as + a touchpad. The gesture is usually initiated by one or more fingers + being held down without significant movement. The precise conditions + of when such a gesture is detected are implementation-dependent. + + In particular, this gesture may be used to cancel kinetic scrolling. + + A hold gesture consists of two stages: begin and end. Unlike pinch and + swipe there is no update stage. + There cannot be multiple simultaneous hold, pinch or swipe gestures on a + same pointer/seat, how compositors prevent these situations is + implementation-dependent. + + A gesture may be cancelled by the compositor or the hardware. + Clients should not consider performing permanent or irreversible + actions until the end of a gesture has been received. + + + + + + + + + This event is sent when a hold gesture is detected on the device. + + + + + + + + + + This event is sent when a hold gesture ceases to + be valid. This may happen when the holding fingers are lifted or + the gesture is cancelled, for example if the fingers move past an + implementation-defined threshold, the finger count changes or the hold + gesture changes into a different type of gesture. + + When a gesture is cancelled, the client may need to undo state changes + caused by this gesture. What causes a gesture to be cancelled is + implementation-dependent. + + + + + + + + diff --git a/pointer_gestures.c b/pointer_gestures.c new file mode 100644 index 0000000..cf49559 --- /dev/null +++ b/pointer_gestures.c @@ -0,0 +1,205 @@ +/* Wayland compositor running on top of an X server. + +Copyright (C) 2022 to various contributors. + +This file is part of 12to11. + +12to11 is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + +12to11 is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with 12to11. If not, see . */ + +#include "compositor.h" +#include "pointer-gestures-unstable-v1.h" + +/* The struct zwp_pointer_gestures_v1 global. */ +static struct wl_global *pointer_gestures_global; + +static void +DestroySwipeGesture (struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static struct zwp_pointer_gesture_swipe_v1_interface gesture_swipe_impl = + { + .destroy = DestroySwipeGesture, + }; + +static void +HandleSwipeGestureResourceDestroy (struct wl_resource *resource) +{ + SwipeGesture *gesture; + + gesture = wl_resource_get_user_data (resource); + XLSeatDestroySwipeGesture (gesture); +} + + + +static void +DestroyPinchGesture (struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static struct zwp_pointer_gesture_pinch_v1_interface gesture_pinch_impl = + { + .destroy = DestroyPinchGesture, + }; + +static void +HandlePinchGestureResourceDestroy (struct wl_resource *resource) +{ + PinchGesture *gesture; + + gesture = wl_resource_get_user_data (resource); + XLSeatDestroyPinchGesture (gesture); +} + + + +static void +DestroyHoldGesture (struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static struct zwp_pointer_gesture_hold_v1_interface gesture_hold_impl = + { + .destroy = DestroyHoldGesture, + }; + + + +static void +GetSwipeGesture (struct wl_client *client, struct wl_resource *resource, + uint32_t id, struct wl_resource *pointer_resource) +{ + struct wl_resource *gesture_resource; + Pointer *pointer; + Seat *seat; + SwipeGesture *gesture_swipe; + + pointer = wl_resource_get_user_data (pointer_resource); + seat = XLPointerGetSeat (pointer); + gesture_resource + = wl_resource_create (client, + &zwp_pointer_gesture_swipe_v1_interface, + wl_resource_get_version (resource), id); + + if (!gesture_resource) + { + wl_resource_post_no_memory (resource); + return; + } + + gesture_swipe = XLSeatGetSwipeGesture (seat, gesture_resource); + wl_resource_set_implementation (gesture_resource, &gesture_swipe_impl, + gesture_swipe, + HandleSwipeGestureResourceDestroy); +} + +static void +GetPinchGesture (struct wl_client *client, struct wl_resource *resource, + uint32_t id, struct wl_resource *pointer_resource) +{ + struct wl_resource *gesture_resource; + Pointer *pointer; + Seat *seat; + PinchGesture *gesture_pinch; + + pointer = wl_resource_get_user_data (pointer_resource); + seat = XLPointerGetSeat (pointer); + gesture_resource + = wl_resource_create (client, + &zwp_pointer_gesture_pinch_v1_interface, + wl_resource_get_version (resource), id); + + if (!gesture_resource) + { + wl_resource_post_no_memory (resource); + return; + } + + gesture_pinch = XLSeatGetPinchGesture (seat, gesture_resource); + wl_resource_set_implementation (gesture_resource, &gesture_pinch_impl, + gesture_pinch, + HandlePinchGestureResourceDestroy); +} + +static void +Release (struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +GetHoldGesture (struct wl_client *client, struct wl_resource *resource, + uint32_t id, struct wl_resource *pointer_resource) +{ + struct wl_resource *gesture_resource; + + /* Hold gestures are not supported by the X Input extension, so a + dummy resource is created that just does nothing. */ + gesture_resource + = wl_resource_create (client, &zwp_pointer_gesture_hold_v1_interface, + wl_resource_get_version (resource), id); + + if (!gesture_resource) + { + wl_resource_post_no_memory (resource); + return; + } + + wl_resource_set_implementation (gesture_resource, &gesture_hold_impl, + NULL, NULL); +} + +static struct zwp_pointer_gestures_v1_interface pointer_gestures_impl = + { + .get_swipe_gesture = GetSwipeGesture, + .get_pinch_gesture = GetPinchGesture, + .release = Release, + .get_hold_gesture = GetHoldGesture, + }; + +static void +HandleBind (struct wl_client *client, void *data, uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &zwp_pointer_gestures_v1_interface, + version, id); + + if (!resource) + { + wl_client_post_no_memory (client); + return; + } + + wl_resource_set_implementation (resource, &pointer_gestures_impl, + NULL, NULL); +} + +void +XLInitPointerGestures (void) +{ + if (xi2_major > 2 || xi2_minor >= 4) + /* Create the pointer gestures global. */ + pointer_gestures_global + = wl_global_create (compositor.wl_display, + &zwp_pointer_gestures_v1_interface, + 3, NULL, HandleBind); + + /* Pointer gestures are not supported without XI 2.4 or later. */ +}