Compare commits

...

11 Commits

Author SHA1 Message Date
Povilas Kanapickas
cbdd9efaab xf86-input-libinput 1.2.0
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-09-19 19:55:46 +03:00
Peter Hutterer
4c54f4d0d2 Rename HAS_GESTURES to HAVE_GESTURES
HAVE_FOO is generally used everywhere (see HAVE_CONFIG_H) so let's keep
this consistent.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-09-16 11:23:53 +10:00
Povilas Kanapickas
8331214771 gitlab-ci: Configure xorgproto build from source
We need newer xorgproto than what's in fedora as we depend on inputproto
2.3.99.1 or newer.
2021-09-16 11:23:53 +10:00
Povilas Kanapickas
8588a19f63 Require inputproto 2.4 to build the gesture support
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-09-16 11:23:33 +10:00
Peter Hutterer
beb94333e1 Use the new v120 API from libinput if available
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-08-06 08:45:01 +02:00
José Expósito
ca9042c7f0 Get scroll source in the event handler
Where libinput supports high-resolution scroll events, the scroll source
is encoded in the event type.

Get the scroll source in xf86libinput_handle_event to facilitate the
migration.

Refactor, no functional changes.

Signed-off-by: José Expósito <jose.exposito89@gmail.com>
2021-08-04 17:51:26 +02:00
Peter Hutterer
bf8dc2e2ed Upgrade the default scroll distance to 120
This is just a number, to be used as divider and shouldn't have any effect in
correctly written clients. With the high-res scrolling coming up however, we
have a few devices where the dist cannot be expressed as an integer fraction
of 15, so let's up it to 120 because we know all hardware wheels have to be an
integer fraction of that that, thanks to Microsoft's API requirements.

For non-wheel scrolls we need to now map into the new range. Previously we
just passed the scroll events on from the touchpad/button scrolling, meaning a
vdist of 15 meant 15 "libinput pixels" of scrolling resulted in a logical
wheel click. Now that we have 120 as vdist, we need to times the input data by
8 to keep the same proportions.

See 39b0bb4585 for the previous revert.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-08-04 12:09:54 +02:00
Povilas Kanapickas
ecd845c307 Implement support for touchpad gestures 2021-07-05 13:35:02 +00:00
Peter Hutterer
0d9184cb76 xf86-input-libinput 1.1.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-06-24 08:26:19 +10:00
Peter Hutterer
9bb9e635df Implement a touchpad scroll distance property
To be used for touchpads and continuous (i.e. button-based scrolling).

libinput provides us with pixel data for finger-based and button-based
scrolling but the X server does support this - XI2.1 smooth scrolling is
merely centered around a logical scroll click (defined as "increment"), with
smooth scrolling being a fraction of that increment. For example, in the old
synaptics driver that value was in device-specific units and thus different
for every device.

The increment is a constant value set in the ScrollClass and cannot be changed
at device runtime. So we simply initialize with a random default (15, because
that works well for wheels) and then scale our pixel delta in to that range.

With the default value, a 15 pixel movement would result in a logical scroll
click, if the distance is set to 30 the users has to move 30 pixels to trigger
that scroll click. Pixel here being defined as the deltas that libinput
provides to us.

From the client's perspective nothing changes, the increment is still the
same.

Range checks are quite restrictive, this option is supposed to improve
usability, not as a workaround around other bugs.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-05-05 13:34:36 +10:00
Peter Hutterer
cc10918bdc Fix a spacing issue
yay for copy/paste proliferation

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-05-05 13:18:19 +10:00
6 changed files with 407 additions and 41 deletions

View File

@@ -19,7 +19,8 @@ stages:
variables:
FDO_DISTRIBUTION_VERSION: 33
FDO_DISTRIBUTION_PACKAGES: 'git autoconf automake libtool make xorg-x11-server-devel libudev-devel libevdev-devel libinput-devel xorg-x11-util-macros'
FDO_DISTRIBUTION_TAG: '2021-04-06.0'
FDO_DISTRIBUTION_EXEC: 'env FDO_CI_CONCURRENT=${FDO_CI_CONCURRENT} bash .gitlab-ci/fedora-install.sh'
FDO_DISTRIBUTION_TAG: '2021-09-15.0'
fedora@container_build:

9
.gitlab-ci/fedora-install.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/bash
# we require at least inputproto >= 2.3.99.1 which has been released in xorgproto 2021.5
git clone https://gitlab.freedesktop.org/xorg/proto/xorgproto.git --depth 1 --branch=xorgproto-2021.5
pushd xorgproto
./autogen.sh
make -j${FDO_CI_CONCURRENT:-4} install
popd
rm -rf xorgproto

View File

@@ -23,7 +23,7 @@
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([xf86-input-libinput],
[1.0.1],
[1.2.0],
[https://gitlab.freedesktop.org/xorg/driver/xf86-input-libinput/issues],
[xf86-input-libinput])
AC_CONFIG_SRCDIR([Makefile.am])
@@ -47,6 +47,9 @@ XORG_DEFAULT_OPTIONS
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.19] xproto [inputproto >= 2.2])
PKG_CHECK_MODULES(LIBINPUT, [libinput >= 1.11.0])
PKG_CHECK_MODULES(INPUTPROTO24, [inputproto >= 2.3.99.1],
[AC_DEFINE(HAVE_INPUTPROTO24, [1], [inputproto 2.4 is available])])
OLD_LIBS=$LIBS
OLD_CFLAGS=$CFLAGS
LIBS="$LIBS $LIBINPUT_LIBS"
@@ -62,6 +65,18 @@ AC_LINK_IFELSE(
[libinput_have_scroll_button_lock=yes]],
[AC_MSG_RESULT([no])
[libinput_have_scroll_button_lock=no]])
AC_MSG_CHECKING([if libinput_event_pointer_get_scroll_value_v120 is available])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[#include <libinput.h>]],
[[libinput_event_pointer_get_scroll_value_v120(NULL, 0)]])],
[AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_LIBINPUT_AXIS_VALUE_V120, [1],
[libinput_event_pointer_get_scroll_value_v120() is available])
[libinput_have_axis_value_v120=yes]],
[AC_MSG_RESULT([no])
[libinput_have_axis_value_v120=no]])
LIBS=$OLD_LIBS
CFLAGS=$OLD_CFLAGS

View File

@@ -123,6 +123,12 @@
/* Scroll button lock: BOOL, 1 value, TRUE for enabled, FALSE otherwise, read-only*/
#define LIBINPUT_PROP_SCROLL_BUTTON_LOCK_DEFAULT "libinput Button Scrolling Button Lock Enabled Default"
/* Scroll pixel distance: CARD32, 1 value (with implementation-defined limits) */
#define LIBINPUT_PROP_SCROLL_PIXEL_DISTANCE "libinput Scrolling Pixel Distance"
/* Scroll pixel distance: CARD32, 1 value, read-only */
#define LIBINPUT_PROP_SCROLL_PIXEL_DISTANCE_DEFAULT "libinput Scrolling Pixel Distance Default"
/* Click method: BOOL read-only, 2 values in order buttonareas, clickfinger
shows available click methods */
#define LIBINPUT_PROP_CLICK_METHODS_AVAILABLE "libinput Click Methods Available"

View File

@@ -160,6 +160,16 @@ Enables a scroll method. Permitted values are
Not all devices support all options, if an option is unsupported, the
default scroll option for this device is used.
.TP 7
.BI "Option \*qScrollPixelDistance\*q \*q" int \*q
Sets the movement distance, in "pixels", required to trigger one logical
wheel click. This option only applies to the scroll methods
.BI twofinger,
.BI edge,
.BI button.
See section
.B SCROLL PIXEL DISTANCE
for more details.
.TP 7
.BI "Option \*qSendEventsMode\*q \*q" (disabled|enabled|disabled-on-external-mouse) \*q
Sets the send events mode to disabled, enabled, or "disable when an external
mouse is connected".
@@ -279,6 +289,10 @@ Indicates which scroll methods are available on this device.
3 boolean values (8 bit, 0 or 1), in order "two-finger", "edge", "button".
Indicates which scroll method is currently enabled on this device.
.TP 7
.BI "libinput Scroll Pixel Distance"
1 32-bit value (nonzero, with additional implementation-defined range checks).
Changes the movement distance required to trigger one logical wheel click.
.TP 7
.BI "libinput Send Events Modes Available"
2 boolean values (8 bit, 0 or 1), in order "disabled" and
"disabled-on-external-mouse". Indicates which send-event modes are available
@@ -396,6 +410,17 @@ it takes left-handed-ness into account.
.TP
This feature is provided by this driver, not by libinput.
.SH SCROLL PIXEL DISTANCE
The X server does not support per-pixel scrolling but it does support
smooth scrolling. All scroll events however are based around a logical
unit of scrolling (traditionally corresponding to a wheel click).
It is thus not possible to scroll by 10 pixels, but it is possible for a
driver to scroll by 1/10th of a logical wheel click.
.PP
libinput provides scroll data in pixels. The \fBScrollPixelDistance\fR
option defines the amount of movement equivalent to one wheel click. For
example, a value of 50 means the user has to move a finger by 50 pixels to
generate one logical click event and each pixel is 1/50th of a wheel click.
.SH BUGS
This driver does not work with \fBOption \*qDevice\*q\fR set to an event
node in \fI/dev/input/by-id\fR and \fI/dev/input/by-path\fR. This can be

View File

@@ -52,6 +52,9 @@
#define TABLET_NUM_BUTTONS 7 /* we need scroll buttons */
#define TOUCH_MAX_SLOTS 15
#define XORG_KEYCODE_OFFSET 8
#define SCROLL_INCREMENT 15
#define TOUCHPAD_SCROLL_DIST_MIN 10 /* in libinput pixels */
#define TOUCHPAD_SCROLL_DIST_MAX 50 /* in libinput pixels */
#define streq(a, b) (strcmp(a, b) == 0)
#define strneq(a, b, n) (strncmp(a, b, n) == 0)
@@ -75,6 +78,13 @@
#define CAP_TABLET 0x8
#define CAP_TABLET_TOOL 0x10
#define CAP_TABLET_PAD 0x20
#define CAP_GESTURE 0x40
#if HAVE_INPUTPROTO24
#if ABI_XINPUT_VERSION >= SET_ABI_VERSION(24, 4)
#define HAVE_GESTURES
#endif
#endif
struct xf86libinput_driver {
struct libinput *libinput;
@@ -146,6 +156,7 @@ struct xf86libinput {
CARD32 sendevents;
CARD32 scroll_button; /* xorg button number */
BOOL scroll_buttonlock;
uint32_t scroll_pixel_distance;
float speed;
float matrix[9];
enum libinput_config_scroll_method scroll_method;
@@ -1085,9 +1096,18 @@ xf86libinput_init_touch(InputInfoPtr pInfo)
if (ntouches == 0) /* unknown - mtdev */
ntouches = TOUCH_MAX_SLOTS;
InitTouchClassDeviceStruct(dev, ntouches, XIDirectTouch, 2);
}
#ifdef HAVE_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,
struct libinput_tablet_tool *tool)
@@ -1331,6 +1351,10 @@ xf86libinput_init(DeviceIntPtr dev)
}
if (driver_data->capabilities & CAP_TOUCH)
xf86libinput_init_touch(pInfo);
#ifdef HAVE_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)
@@ -1543,9 +1567,9 @@ xf86libinput_handle_key(InputInfoPtr pInfo, struct libinput_event_keyboard *even
* so the use-case above shouldn't matter anymore.
*/
static inline double
get_wheel_scroll_value(struct xf86libinput *driver_data,
struct libinput_event_pointer *event,
enum libinput_pointer_axis axis)
guess_wheel_scroll_value(struct xf86libinput *driver_data,
struct libinput_event_pointer *event,
enum libinput_pointer_axis axis)
{
struct scroll_axis *s;
double f;
@@ -1605,23 +1629,91 @@ out:
return s->dist/s->fraction * discrete;
}
#if HAVE_LIBINPUT_AXIS_VALUE_V120
static inline double
get_wheel_120_value(struct xf86libinput *driver_data,
struct libinput_event_pointer *event,
enum libinput_pointer_axis axis)
{
struct scroll_axis *s;
double angle;
switch (axis) {
case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
s = &driver_data->scroll.h;
break;
case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
s = &driver_data->scroll.v;
break;
default:
return 0.0;
}
angle = libinput_event_pointer_get_scroll_value_v120(event, axis);
return s->dist * angle/120;
}
#endif
static inline double
get_wheel_scroll_value(struct xf86libinput *driver_data,
struct libinput_event_pointer *event,
enum libinput_pointer_axis axis)
{
#if HAVE_LIBINPUT_AXIS_VALUE_V120
return get_wheel_120_value(driver_data, event, axis);
#else
return guess_wheel_scroll_value(driver_data, event, axis);
#endif
}
static inline double
get_finger_or_continuous_scroll_value(struct libinput_event_pointer *event,
enum libinput_pointer_axis axis)
{
#if HAVE_LIBINPUT_AXIS_VALUE_V120
return libinput_event_pointer_get_scroll_value(event, axis);
#else
return libinput_event_pointer_get_axis_value(event, axis);
#endif
}
static inline bool
calculate_axis_value(struct xf86libinput *driver_data,
enum libinput_pointer_axis axis,
struct libinput_event_pointer *event,
enum libinput_pointer_axis_source source,
double *value_out)
{
enum libinput_pointer_axis_source source;
double value;
if (!libinput_event_pointer_has_axis(event, axis))
return false;
source = libinput_event_pointer_get_axis_source(event);
/* Event may be LIBINPUT_POINTER_AXIS or
* LIBINPUT_EVENT_POINTER_SCROLL_{WHEEL|FINGER|CONTINUOUS}, depending
* on the libinput version.
*
* libinput guarantees the axis source is set for the second set of
* events too but we can switch to the event type once we ditch
* libinput < 1.19 support.
*/
if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL) {
value = get_wheel_scroll_value(driver_data, event, axis);
} else {
value = libinput_event_pointer_get_axis_value(event, axis);
double dist = driver_data->options.scroll_pixel_distance;
assert(dist != 0.0);
value = get_finger_or_continuous_scroll_value(event, axis);
/* We need to scale this value into our scroll increment range
* because that one is constant for the lifetime of the
* device. The user may change the ScrollPixelDistance
* though, so where we have a dist of 10 but an increment of
* 15, we need to scale from 0..10 into 0..15.
*
* We now switched to vdist of 120, so make this
* proportionate - 120/15 is 8.
*/
value = value/dist * SCROLL_INCREMENT * 8;
}
*value_out = value;
@@ -1630,32 +1722,26 @@ calculate_axis_value(struct xf86libinput *driver_data,
}
static void
xf86libinput_handle_axis(InputInfoPtr pInfo, struct libinput_event_pointer *event)
xf86libinput_handle_axis(InputInfoPtr pInfo,
struct libinput_event *e,
enum libinput_pointer_axis_source source)
{
struct libinput_event_pointer *event;
DeviceIntPtr dev = pInfo->dev;
struct xf86libinput *driver_data = pInfo->private;
ValuatorMask *mask = driver_data->valuators;
double value;
enum libinput_pointer_axis_source source;
if ((driver_data->capabilities & CAP_POINTER) == 0)
return;
valuator_mask_zero(mask);
source = libinput_event_pointer_get_axis_source(event);
switch(source) {
case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
break;
default:
return;
}
event = libinput_event_get_pointer_event(e);
if (calculate_axis_value(driver_data,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
event,
source,
&value))
valuator_mask_set_double(mask, 3, value);
@@ -1665,9 +1751,15 @@ xf86libinput_handle_axis(InputInfoPtr pInfo, struct libinput_event_pointer *even
if (calculate_axis_value(driver_data,
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
event,
source,
&value))
valuator_mask_set_double(mask, 2, value);
if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL &&
!valuator_mask_isset(mask, 2) &&
!valuator_mask_isset(mask, 3))
return;
out:
xf86PostMotionEventM(dev, Relative, mask);
}
@@ -1723,6 +1815,86 @@ xf86libinput_handle_touch(InputInfoPtr pInfo,
xf86PostTouchEvent(dev, touchids[slot], type, 0, m);
}
#ifdef HAVE_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)
@@ -2265,9 +2437,30 @@ xf86libinput_handle_event(struct libinput_event *event)
libinput_event_get_keyboard_event(event));
break;
case LIBINPUT_EVENT_POINTER_AXIS:
#if !HAVE_LIBINPUT_AXIS_VALUE_V120
/* ignore POINTER_AXIS where we have libinput 1.19 and higher */
xf86libinput_handle_axis(pInfo,
libinput_event_get_pointer_event(event));
event,
libinput_event_pointer_get_axis_source(event));
#endif
break;
#if HAVE_LIBINPUT_AXIS_VALUE_V120
case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
xf86libinput_handle_axis(pInfo,
event,
LIBINPUT_POINTER_AXIS_SOURCE_WHEEL);
break;
case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
xf86libinput_handle_axis(pInfo,
event,
LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
break;
case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
xf86libinput_handle_axis(pInfo,
event,
LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
break;
#endif
case LIBINPUT_EVENT_TOUCH_FRAME:
break;
case LIBINPUT_EVENT_TOUCH_UP:
@@ -2281,9 +2474,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 HAVE_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 HAVE_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,
@@ -2826,6 +3030,39 @@ xf86libinput_parse_scrollbuttonlock_option(InputInfoPtr pInfo,
return buttonlock;
}
static inline bool
xf86libinput_want_scroll_distance_option(struct libinput_device *device)
{
uint32_t methods =
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN |
LIBINPUT_CONFIG_SCROLL_2FG |
LIBINPUT_CONFIG_SCROLL_EDGE;
if ((libinput_device_config_scroll_get_methods(device) & methods) == 0)
return false;
return true;
}
static inline uint32_t
xf86libinput_parse_scroll_pixel_distance_option(InputInfoPtr pInfo,
struct libinput_device *device)
{
uint32_t dflt = SCROLL_INCREMENT;
uint32_t dist;
if (!xf86libinput_want_scroll_distance_option(device))
return dflt;
dist = xf86SetIntOption(pInfo->options, "ScrollPixelDistance", dflt);
if (dist < TOUCHPAD_SCROLL_DIST_MIN || dist > TOUCHPAD_SCROLL_DIST_MAX) {
xf86IDrvMsg(pInfo, X_ERROR,
"Invalid ScrollPixelDistance %d\n", dist);
dist = dflt;
}
return dist;
}
static inline unsigned int
xf86libinput_parse_clickmethod_option(InputInfoPtr pInfo,
struct libinput_device *device)
@@ -3107,6 +3344,7 @@ xf86libinput_parse_options(InputInfoPtr pInfo,
options->scroll_method = xf86libinput_parse_scroll_option(pInfo, device);
options->scroll_button = xf86libinput_parse_scrollbutton_option(pInfo, device);
options->scroll_buttonlock = xf86libinput_parse_scrollbuttonlock_option(pInfo, device);
options->scroll_pixel_distance = xf86libinput_parse_scroll_pixel_distance_option(pInfo, device);
options->click_method = xf86libinput_parse_clickmethod_option(pInfo, device);
options->middle_emulation = xf86libinput_parse_middleemulation_option(pInfo, device);
options->disable_while_typing = xf86libinput_parse_disablewhiletyping_option(pInfo, device);
@@ -3247,6 +3485,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 HAVE_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)
@@ -3285,6 +3527,10 @@ caps_from_options(InputInfoPtr pInfo)
capabilities |= CAP_POINTER;
if (xf86CheckBoolOption(pInfo->options, "_libinput/cap-touch", 0))
capabilities |= CAP_TOUCH;
#ifdef HAVE_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;
@@ -3420,8 +3666,8 @@ xf86libinput_pre_init(InputDriverPtr drv,
* affect touchpad scroll speed. For wheels it doesn't matter as
* we're using the discrete value only.
*/
driver_data->scroll.v.dist = 15;
driver_data->scroll.h.dist = 15;
driver_data->scroll.v.dist = 120;
driver_data->scroll.h.dist = 120;
if (!is_subdevice) {
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER))
@@ -3430,6 +3676,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 HAVE_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))
@@ -3452,7 +3702,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,
@@ -3563,6 +3813,8 @@ static Atom prop_scroll_button;
static Atom prop_scroll_button_default;
static Atom prop_scroll_buttonlock;
static Atom prop_scroll_buttonlock_default;
static Atom prop_scroll_pixel_distance;
static Atom prop_scroll_pixel_distance_default;
static Atom prop_click_methods_available;
static Atom prop_click_method_enabled;
static Atom prop_click_method_default;
@@ -3684,7 +3936,7 @@ update_mode_prop(InputInfoPtr pInfo,
}
static inline BOOL
xf86libinput_check_device (DeviceIntPtr dev,
xf86libinput_check_device(DeviceIntPtr dev,
Atom atom)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
@@ -3722,7 +3974,7 @@ LibinputSetPropertyTap(DeviceIntPtr dev,
if (*data != 0 && *data != 1)
return BadValue;
if (!xf86libinput_check_device (dev, atom))
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
if (libinput_device_config_tap_get_finger_count(device) == 0)
@@ -3816,7 +4068,7 @@ LibinputSetPropertyTapButtonmap(DeviceIntPtr dev,
if ((data[0] && data[1]) || (!data[0] && !data[1]))
return BadValue;
if (!xf86libinput_check_device (dev, atom))
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
}
@@ -3855,7 +4107,7 @@ LibinputSetPropertyCalibration(DeviceIntPtr dev,
data[8] != 1.0)
return BadValue;
if (!xf86libinput_check_device (dev, atom))
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
if (!libinput_device_config_calibration_has_matrix(device))
@@ -3889,7 +4141,7 @@ LibinputSetPropertyAccel(DeviceIntPtr dev,
if (*data < -1.0 || *data > 1.0)
return BadValue;
if (!xf86libinput_check_device (dev, atom))
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
if (libinput_device_config_accel_is_available(device) == 0)
@@ -3929,7 +4181,7 @@ LibinputSetPropertyAccelProfile(DeviceIntPtr dev,
if (__builtin_popcount(profiles) > 1)
return BadValue;
if (!xf86libinput_check_device (dev, atom))
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
supported = libinput_device_config_accel_get_profiles(device);
@@ -3962,7 +4214,7 @@ LibinputSetPropertyNaturalScroll(DeviceIntPtr dev,
if (*data != 0 && *data != 1)
return BadValue;
if (!xf86libinput_check_device (dev, atom))
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
if (libinput_device_config_scroll_has_natural_scroll(device) == 0)
@@ -3999,7 +4251,7 @@ LibinputSetPropertySendEvents(DeviceIntPtr dev,
if (checkonly) {
uint32_t supported;
if (!xf86libinput_check_device (dev, atom))
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
supported = libinput_device_config_send_events_get_modes(device);
@@ -4033,7 +4285,7 @@ LibinputSetPropertyLeftHanded(DeviceIntPtr dev,
int supported;
int left_handed = *data;
if (!xf86libinput_check_device (dev, atom))
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
supported = libinput_device_config_left_handed_is_available(device);
@@ -4097,7 +4349,7 @@ LibinputSetPropertyScrollMethods(DeviceIntPtr dev,
if (__builtin_popcount(modes) > 1)
return BadValue;
if (!xf86libinput_check_device (dev, atom))
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
supported = libinput_device_config_scroll_get_methods(device);
@@ -4130,7 +4382,7 @@ LibinputSetPropertyScrollButton(DeviceIntPtr dev,
uint32_t button = *data;
uint32_t supported;
if (!xf86libinput_check_device (dev, atom))
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
supported = libinput_device_pointer_has_button(device,
@@ -4162,7 +4414,7 @@ LibinputSetPropertyScrollButtonLock(DeviceIntPtr dev,
if (enabled != 0 && enabled != 1)
return BadValue;
if (!xf86libinput_check_device (dev, atom))
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
} else {
driver_data->options.scroll_buttonlock = enabled;
@@ -4371,7 +4623,7 @@ LibinputSetPropertyHorizScroll(DeviceIntPtr dev,
if (enabled != 0 && enabled != 1)
return BadValue;
if (!xf86libinput_check_device (dev, atom))
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
} else {
driver_data->options.horiz_scrolling_enabled = enabled;
@@ -4380,6 +4632,34 @@ LibinputSetPropertyHorizScroll(DeviceIntPtr dev,
return Success;
}
static inline int
LibinputSetPropertyScrollPixelDistance(DeviceIntPtr dev,
Atom atom,
XIPropertyValuePtr val,
BOOL checkonly)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
uint32_t dist;
if (val->format != 32 || val->type != XA_CARDINAL || val->size != 1)
return BadMatch;
dist = *(BOOL*)val->data;
if (checkonly) {
if (dist < TOUCHPAD_SCROLL_DIST_MIN ||
dist > TOUCHPAD_SCROLL_DIST_MAX)
return BadValue;
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
} else {
driver_data->options.scroll_pixel_distance = dist;
}
return Success;
}
static inline int
LibinputSetPropertyRotationAngle(DeviceIntPtr dev,
Atom atom,
@@ -4400,7 +4680,7 @@ LibinputSetPropertyRotationAngle(DeviceIntPtr dev,
if (*angle < 0.0 || *angle >= 360.0)
return BadValue;
if (!xf86libinput_check_device (dev, atom))
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
if (libinput_device_config_rotation_is_available(device) == 0)
@@ -4444,7 +4724,7 @@ LibinputSetPropertyPressureCurve(DeviceIntPtr dev,
return BadValue;
}
if (!xf86libinput_check_device (dev, atom))
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
if (!cubic_bezier(controls, test_bezier, ARRAY_SIZE(test_bezier)))
@@ -4484,7 +4764,7 @@ LibinputSetPropertyAreaRatio(DeviceIntPtr dev,
(area.x == 0 && area.y != 0))
return BadValue;
if (!xf86libinput_check_device (dev, atom))
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
} else {
struct xf86libinput *other;
@@ -4557,6 +4837,8 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
rc = LibinputSetPropertyDragLockButtons(dev, atom, val, checkonly);
else if (atom == prop_horiz_scroll)
rc = LibinputSetPropertyHorizScroll(dev, atom, val, checkonly);
else if (atom == prop_scroll_pixel_distance)
rc = LibinputSetPropertyScrollPixelDistance(dev, atom, val, checkonly);
else if (atom == prop_mode_groups) {
InputInfoPtr pInfo = dev->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
@@ -4588,6 +4870,7 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
atom == prop_scroll_methods_available ||
atom == prop_scroll_button_default ||
atom == prop_scroll_buttonlock_default ||
atom == prop_scroll_pixel_distance_default ||
atom == prop_click_method_default ||
atom == prop_click_methods_available ||
atom == prop_middle_emulation_default ||
@@ -5114,6 +5397,32 @@ LibinputInitScrollMethodsProperty(DeviceIntPtr dev,
}
}
static void
LibinputInitScrollPixelDistanceProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
CARD32 dist = driver_data->options.scroll_pixel_distance;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (!xf86libinput_want_scroll_distance_option(device))
return;
prop_scroll_pixel_distance = LibinputMakeProperty(dev,
LIBINPUT_PROP_SCROLL_PIXEL_DISTANCE,
XA_CARDINAL, 32,
1, &dist);
if (!prop_scroll_pixel_distance)
return;
prop_scroll_pixel_distance_default = LibinputMakeProperty(dev,
LIBINPUT_PROP_SCROLL_PIXEL_DISTANCE_DEFAULT,
XA_CARDINAL, 32,
1, &dist);
}
static void
LibinputInitClickMethodsProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data,
@@ -5555,6 +5864,7 @@ LibinputInitProperty(DeviceIntPtr dev)
LibinputInitDragLockProperty(dev, driver_data);
LibinputInitHorizScrollProperty(dev, driver_data);
LibinputInitScrollPixelDistanceProperty(dev, driver_data, device);
LibinputInitPressureCurveProperty(dev, driver_data);
LibinputInitTabletAreaRatioProperty(dev, driver_data);
}