summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPovilas Kanapickas <povilas@radix.lt>2020-10-10 02:57:40 +0300
committerPovilas Kanapickas <povilas@radix.lt>2021-07-05 13:35:02 +0000
commitecd845c30752a328acfeccb7750dc70350beab0d (patch)
tree9a7e6e633f3e7419d41e77b2995a28399c2e938e
parent0d9184cb769d38f3cf5a92004211315e5407183d (diff)
downloadxorg-driver-xf86-input-libinput-ecd845c30752a328acfeccb7750dc70350beab0d.tar.gz
Implement support for touchpad gestures
-rw-r--r--src/xf86libinput.c123
1 files changed, 122 insertions, 1 deletions
diff --git a/src/xf86libinput.c b/src/xf86libinput.c
index 9c9bc88..33b02da 100644
--- a/src/xf86libinput.c
+++ b/src/xf86libinput.c
@@ -78,6 +78,11 @@
#define CAP_TABLET 0x8
#define CAP_TABLET_TOOL 0x10
#define CAP_TABLET_PAD 0x20
+#define CAP_GESTURE 0x40
+
+#if ABI_XINPUT_VERSION >= SET_ABI_VERSION(24, 4)
+#define HAS_GESTURES
+#endif
struct xf86libinput_driver {
struct libinput *libinput;
@@ -1089,8 +1094,17 @@ xf86libinput_init_touch(InputInfoPtr pInfo)
if (ntouches == 0) /* unknown - mtdev */
ntouches = TOUCH_MAX_SLOTS;
InitTouchClassDeviceStruct(dev, ntouches, XIDirectTouch, 2);
+}
+#ifdef HAS_GESTURES
+static void
+xf86libinput_init_gesture(InputInfoPtr pInfo)
+{
+ DeviceIntPtr dev = pInfo->dev;
+ int ntouches = TOUCH_MAX_SLOTS;
+ InitGestureClassDeviceStruct(dev, ntouches);
}
+#endif
static int
xf86libinput_init_tablet_pen_or_eraser(InputInfoPtr pInfo,
@@ -1335,6 +1349,10 @@ xf86libinput_init(DeviceIntPtr dev)
}
if (driver_data->capabilities & CAP_TOUCH)
xf86libinput_init_touch(pInfo);
+#ifdef HAS_GESTURES
+ if (driver_data->capabilities & CAP_GESTURE)
+ xf86libinput_init_gesture(pInfo);
+#endif
if (driver_data->capabilities & CAP_TABLET_TOOL)
xf86libinput_init_tablet(pInfo);
if (driver_data->capabilities & CAP_TABLET_PAD)
@@ -1737,6 +1755,86 @@ xf86libinput_handle_touch(InputInfoPtr pInfo,
xf86PostTouchEvent(dev, touchids[slot], type, 0, m);
}
+#ifdef HAS_GESTURES
+static void
+xf86libinput_handle_gesture_swipe(InputInfoPtr pInfo,
+ struct libinput_event_gesture *event,
+ enum libinput_event_type event_type)
+{
+ DeviceIntPtr dev = pInfo->dev;
+ struct xf86libinput *driver_data = pInfo->private;
+ int type;
+ uint32_t flags = 0;
+
+ if ((driver_data->capabilities & CAP_GESTURE) == 0)
+ return;
+
+ switch (event_type) {
+ case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
+ type = XI_GestureSwipeBegin;
+ break;
+ case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
+ type = XI_GestureSwipeUpdate;
+ break;
+ case LIBINPUT_EVENT_GESTURE_SWIPE_END:
+ type = XI_GestureSwipeEnd;
+ if (libinput_event_gesture_get_cancelled(event))
+ flags |= XIGestureSwipeEventCancelled;
+ break;
+ default:
+ return;
+ }
+
+ xf86PostGestureSwipeEvent(dev, type,
+ libinput_event_gesture_get_finger_count(event),
+ flags,
+ libinput_event_gesture_get_dx(event),
+ libinput_event_gesture_get_dy(event),
+ libinput_event_gesture_get_dx_unaccelerated(event),
+ libinput_event_gesture_get_dy_unaccelerated(event));
+}
+
+static void
+xf86libinput_handle_gesture_pinch(InputInfoPtr pInfo,
+ struct libinput_event_gesture *event,
+ enum libinput_event_type event_type)
+{
+ DeviceIntPtr dev = pInfo->dev;
+ struct xf86libinput *driver_data = pInfo->private;
+ int type;
+ uint32_t flags = 0;
+
+ if ((driver_data->capabilities & CAP_GESTURE) == 0)
+ return;
+
+ switch (event_type) {
+ case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN:
+ type = XI_GesturePinchBegin;
+ break;
+ case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
+ type = XI_GesturePinchUpdate;
+ break;
+ case LIBINPUT_EVENT_GESTURE_PINCH_END:
+ type = XI_GesturePinchEnd;
+ if (libinput_event_gesture_get_cancelled(event))
+ flags |= XIGesturePinchEventCancelled;
+ break;
+ default:
+ return;
+ }
+
+ xf86PostGesturePinchEvent(dev, type,
+ libinput_event_gesture_get_finger_count(event),
+ flags,
+ libinput_event_gesture_get_dx(event),
+ libinput_event_gesture_get_dy(event),
+ libinput_event_gesture_get_dx_unaccelerated(event),
+ libinput_event_gesture_get_dy_unaccelerated(event),
+ libinput_event_gesture_get_scale(event),
+ libinput_event_gesture_get_angle_delta(event));
+}
+#endif
+
static InputInfoPtr
xf86libinput_pick_device(struct xf86libinput_device *shared_device,
struct libinput_event *event)
@@ -2295,9 +2393,20 @@ xf86libinput_handle_event(struct libinput_event *event)
case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
case LIBINPUT_EVENT_GESTURE_SWIPE_END:
+#ifdef HAS_GESTURES
+ xf86libinput_handle_gesture_swipe(pInfo,
+ libinput_event_get_gesture_event(event),
+ type);
+#endif
+ break;
case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN:
case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
case LIBINPUT_EVENT_GESTURE_PINCH_END:
+#ifdef HAS_GESTURES
+ xf86libinput_handle_gesture_pinch(pInfo,
+ libinput_event_get_gesture_event(event),
+ type);
+#endif
break;
case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
event_handling = xf86libinput_handle_tablet_axis(pInfo,
@@ -3295,6 +3404,10 @@ xf86libinput_create_subdevice(InputInfoPtr pInfo,
options = xf86ReplaceBoolOption(options, "_libinput/cap-pointer", 1);
if (capabilities & CAP_TOUCH)
options = xf86ReplaceBoolOption(options, "_libinput/cap-touch", 1);
+#ifdef HAS_GESTURES
+ if (capabilities & CAP_GESTURE)
+ options = xf86ReplaceBoolOption(options, "_libinput/cap-gesture", 1);
+#endif
if (capabilities & CAP_TABLET_TOOL)
options = xf86ReplaceBoolOption(options, "_libinput/cap-tablet-tool", 1);
if (capabilities & CAP_TABLET_PAD)
@@ -3333,6 +3446,10 @@ caps_from_options(InputInfoPtr pInfo)
capabilities |= CAP_POINTER;
if (xf86CheckBoolOption(pInfo->options, "_libinput/cap-touch", 0))
capabilities |= CAP_TOUCH;
+#ifdef HAS_GESTURES
+ if (xf86CheckBoolOption(pInfo->options, "_libinput/cap-gesture", 0))
+ capabilities |= CAP_GESTURE;
+#endif
if (xf86CheckBoolOption(pInfo->options, "_libinput/cap-tablet-tool", 0))
capabilities |= CAP_TABLET_TOOL;
@@ -3478,6 +3595,10 @@ xf86libinput_pre_init(InputDriverPtr drv,
driver_data->capabilities |= CAP_KEYBOARD;
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH))
driver_data->capabilities |= CAP_TOUCH;
+#ifdef HAS_GESTURES
+ if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_GESTURE))
+ driver_data->capabilities |= CAP_GESTURE;
+#endif
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TABLET_TOOL))
driver_data->capabilities |= CAP_TABLET;
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TABLET_PAD))
@@ -3500,7 +3621,7 @@ xf86libinput_pre_init(InputDriverPtr drv,
* this device, create a separate device instead */
if (!is_subdevice &&
driver_data->capabilities & CAP_KEYBOARD &&
- driver_data->capabilities & (CAP_POINTER|CAP_TOUCH)) {
+ driver_data->capabilities & (CAP_POINTER|CAP_TOUCH|CAP_GESTURE)) {
driver_data->capabilities &= ~CAP_KEYBOARD;
xf86libinput_create_subdevice(pInfo,
CAP_KEYBOARD,