Compare commits

...

21 Commits

Author SHA1 Message Date
Peter Hutterer
8cf533df3a xf86-input-libinput 1.3.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-04-04 14:56:40 +10:00
Yinon Burgansky
484b6a7f3f Add support for the scroll movement type of the custom acceleration profile
Adds new properties and xorg.conf entries for setting the scroll acceleration
function's points and step.
The new xorg.conf entries are AccelPointsScroll, AccelStepScroll.
2023-02-18 21:22:15 +02:00
Shin-myoung-serp
e87c7bfcc2 Correct the coordinate transform parameters for an absolute pointer
Fixes #53
2023-02-01 18:33:31 +09:00
Peter Hutterer
f94a8edb0e Add support for custom pointer acceleration
Adds new properties and xorg.conf entries for setting the acceleration
function's points and step.

`AccelProfile` option can now accept `custom` value.

Add 4 new options which only apply when `AccelProfile` is `custom`:

- Add `AccelPointsFallback` option for setting the points of the
  Fallback acceleration function. Points values are represented by a
  space-separated list, e.g. "0.0 1.0 2.4 2.5".

- Add `AccelStepFallback` option for setting the step of the Fallback
  acceleration function. When a step of 0.0 is provided,
  libinput default Fallback acceleration function is used.

- Add `AccelPointsMotion` and `AccelStepMotion` options, which are
  equivalent to `AccelPointsFallback` and `AccelStepFallback` options,
  but apply to the Motion acceleration function.

See libinput documentation for a detailed explanation of custom
pointer acceleration.
2023-01-09 15:53:38 +02:00
Peter Hutterer
ca02afd8d2 configure.ac: inputproto 2.4 is optional
Missing else condition in PKG_CHECK_MODULES caused configure to bail out
where 2.4 wasn't available.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-12-09 09:15:09 +10:00
Alan Coopersmith
252bc4ba0d gitlab CI: enable gitlab's builtin static analysis
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2022-07-23 16:58:19 -07:00
Alan Coopersmith
925903018f gitlab CI: enable commit & merge request checks
Uses ci-fairy from freedesktop/ci-templates

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2022-07-23 16:58:19 -07:00
Hong Xu
dfc5e20426 Better explain HorizontalScrolling. 2022-04-27 11:33:46 +00:00
Peter Hutterer
2ee183a6cd Add meson build system
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-01-25 12:21:09 +10:00
Peter Hutterer
efa999e377 man: use @VERSION@ for the driver version
Makes use of meson easier which requires @ as pre/suffix for variables.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-01-25 12:16:04 +10:00
Peter Hutterer
7b4a870b23 man: replace the various suffixes with their actual numbers
These don't change, iirc they exist because of some unixes having
different man pages but at this point really on Solaris is left and that
uses the same suffixes as everyone else.

And the __xservername__ is a leftover from the Xfree86 vs Xorg days - if
you're still running Xfree86, you're not using this driver.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-01-25 12:16:04 +10:00
Peter Hutterer
30500626fe Drop HAVE_CONFIG_H, we always have it defined
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-01-25 09:56:13 +10:00
Peter Hutterer
62f267a952 xf86-input-libinput 1.2.1
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-01-24 15:00:09 +10:00
Peter Hutterer
c1f07edafa Fix a compiler warning
xf86libinput.c:2457:89: warning: passing argument 1 of
‘libinput_event_pointer_get_axis_source’ from incompatible
pointer type [-Wincompatible-pointer-types]

No function changes due to the binary layout of libinput events but
let's not rely on that.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-01-24 11:38:53 +10:00
Alan Coopersmith
a3d38b0f40 Build xz tarballs instead of bzip2
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2022-01-16 21:32:35 +00:00
Alan Coopersmith
e3a75f34f8 Fix spelling/wording issues
Found by using:
    codespell --builtin clear,rare,usage,informal,code,names

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2022-01-16 11:50:26 -08:00
Luna Nova
830f7c3b1b Fix copy-paste error in LibinputInitAccelProperty checking available profiles against adaptive/flat 2021-12-18 04:55:14 +00:00
Peter Hutterer
4ab7873366 Quietly check for the _source option
xf86CheckStrOption returns the same value but doesn't mark it as used in
the server and, more importantly, doesn't spam the log with
  (**) Option "_source" "server/udev"
messages.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-11-24 01:14:05 +00:00
José Expósito
b3e65904db Make XIPropertyValuePtr verification consistent
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
2021-11-17 07:57:28 +01:00
José Expósito
75cc87518b Add an option to disable high-resolution wheel scroll
Starting on libinput 1.19 pointer axis events have been deprecated in
favor of their scroll equivalents, including support for high-resolution
wheel scroll.

While it is recommended to handle the new events, some applications
and/or frameworks might not be ready at the moment.

Provide an option to discard high-resolution wheel scroll events.

Fix #41

Signed-off-by: José Expósito <jose.exposito89@gmail.com>
2021-11-14 22:52:47 +00:00
José Expósito
3951ce739d man: fix horizontal scroll property name
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
2021-11-10 18:12:46 +01:00
13 changed files with 1587 additions and 75 deletions

View File

@@ -1,19 +1,28 @@
# vim: set expandtab shiftwidth=2 tabstop=8 textwidth=0:
# vim: set expandtab shiftwidth=2 tabstop=8 textwidth=0 filetype=yaml:
#
# This CI uses the freedesktop.org ci-templates.
# Please see the ci-templates documentation for details:
# https://freedesktop.pages.freedesktop.org/ci-templates/
.templates_sha: &template_sha c5626190ec14b475271288dda7a7dae8dbe0cd76 # see https://docs.gitlab.com/ee/ci/yaml/#includefile
include:
- project: 'freedesktop/ci-templates'
ref: 59de540b620c45739871d1a073d76d5521989d11 # see https://docs.gitlab.com/ee/ci/yaml/#includefile
ref: *template_sha
file: '/templates/fedora.yml'
- project: 'freedesktop/ci-templates'
ref: *template_sha
file: '/templates/ci-fairy.yml'
- template: Security/SAST.gitlab-ci.yml
variables:
FDO_UPSTREAM_REPO: xorg/drivers/xf86-input-libinput
FDO_UPSTREAM_REPO: xorg/driver/xf86-input-libinput
stages:
- containers
- build
- test
.fedora:
variables:
@@ -54,3 +63,36 @@ fedora:33@default-build:
- .fedora
- .fdo.distribution-image@fedora
- .default_build
#
# Verify that commit messages are as expected
#
check-commits:
extends:
- .fdo.ci-fairy
stage: test
script:
- ci-fairy check-commits --junit-xml=results.xml
except:
- master@xorg/driver/xf86-input-libinput
variables:
GIT_DEPTH: 100
artifacts:
reports:
junit: results.xml
allow_failure: true
#
# Verify that the merge request has the allow-collaboration checkbox ticked
#
check-merge-request:
extends:
- .fdo.ci-fairy
stage: test
script:
- ci-fairy check-merge-request --require-allow-collaboration --junit-xml=results.xml
artifacts:
when: on_failure
reports:
junit: results.xml
allow_failure: true

View File

@@ -23,7 +23,7 @@
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([xf86-input-libinput],
[1.2.0],
[1.3.0],
[https://gitlab.freedesktop.org/xorg/driver/xf86-input-libinput/issues],
[xf86-input-libinput])
AC_CONFIG_SRCDIR([Makefile.am])
@@ -31,7 +31,7 @@ AC_CONFIG_HEADERS([config.h])
AC_CONFIG_AUX_DIR(.)
# Initialize Automake
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_INIT_AUTOMAKE([foreign dist-xz])
# Initialize libtool
AC_DISABLE_STATIC
@@ -48,7 +48,8 @@ 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])])
[AC_DEFINE(HAVE_INPUTPROTO24, [1], [inputproto 2.4 is available])],
[:])
OLD_LIBS=$LIBS
OLD_CFLAGS=$CFLAGS
@@ -77,6 +78,17 @@ AC_LINK_IFELSE(
[AC_MSG_RESULT([no])
[libinput_have_axis_value_v120=no]])
AC_MSG_CHECKING([if libinput_config_accel_create is available])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[#include <libinput.h>]],
[[libinput_config_accel_create(0)]])],
[AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_LIBINPUT_CUSTOM_ACCEL, [1],
[libinput_config_accel_create() is available])
[libinput_have_custom_accel=yes]],
[AC_MSG_RESULT([no])
[libinput_have_custom_accel=no]])
LIBS=$OLD_LIBS
CFLAGS=$OLD_CFLAGS

View File

@@ -63,18 +63,36 @@
/* Pointer accel speed: FLOAT, 1 value, 32 bit, read-only*/
#define LIBINPUT_PROP_ACCEL_DEFAULT "libinput Accel Speed Default"
/* Pointer accel profile: BOOL, 2 values in oder adaptive, flat,
/* Pointer accel profile: BOOL, 3 values in order adaptive, flat, custom
* only one is enabled at a time at max, read-only */
#define LIBINPUT_PROP_ACCEL_PROFILES_AVAILABLE "libinput Accel Profiles Available"
/* Pointer accel profile: BOOL, 2 values in order adaptive, flat,
/* Pointer accel profile: BOOL, 3 values in order adaptive, flat, custom
only one is enabled at a time at max, read-only */
#define LIBINPUT_PROP_ACCEL_PROFILE_ENABLED_DEFAULT "libinput Accel Profile Enabled Default"
/* Pointer accel profile: BOOL, 2 values in order adaptive, flat,
/* Pointer accel profile: BOOL, 3 values in order adaptive, flat, custom
only one is enabled at a time at max */
#define LIBINPUT_PROP_ACCEL_PROFILE_ENABLED "libinput Accel Profile Enabled"
/* Points for the custom accel profile: FLOAT, N values */
#define LIBINPUT_PROP_ACCEL_CUSTOM_POINTS_FALLBACK "libinput Accel Custom Fallback Points"
/* Steps for the custom accel profile: FLOAT, 1 value */
#define LIBINPUT_PROP_ACCEL_CUSTOM_STEP_FALLBACK "libinput Accel Custom Fallback Step"
/* Points for the custom accel profile: FLOAT, N values */
#define LIBINPUT_PROP_ACCEL_CUSTOM_POINTS_MOTION "libinput Accel Custom Motion Points"
/* Steps for the custom accel profile: FLOAT, 1 value */
#define LIBINPUT_PROP_ACCEL_CUSTOM_STEP_MOTION "libinput Accel Custom Motion Step"
/* Points for the custom accel profile: FLOAT, N values */
#define LIBINPUT_PROP_ACCEL_CUSTOM_POINTS_SCROLL "libinput Accel Custom Scroll Points"
/* Steps for the custom accel profile: FLOAT, 1 value */
#define LIBINPUT_PROP_ACCEL_CUSTOM_STEP_SCROLL "libinput Accel Custom Scroll Step"
/* Natural scrolling: BOOL, 1 value */
#define LIBINPUT_PROP_NATURAL_SCROLL "libinput Natural Scrolling Enabled"
@@ -207,4 +225,8 @@
/* Tablet tool area ratio: CARD32, 2 values, w and h */
#define LIBINPUT_PROP_TABLET_TOOL_AREA_RATIO "libinput Tablet Tool Area Ratio"
/* High-resolution wheel scroll events enabled: BOOL, 1 value (0 or 1).
* If disabled, high-resolution wheel scroll events are discarded */
#define LIBINPUT_PROP_HIRES_WHEEL_SCROLL_ENABLED "libinput High Resolution Wheel Scroll Enabled"
#endif /* _LIBINPUT_PROPERTIES_H_ */

View File

@@ -32,6 +32,9 @@ CLEANFILES = $(driverman_DATA)
SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man
MAN_SUBSTS += \
-e 's|\@VERSION\@|$(PACKAGE_NAME) $(PACKAGE_VERSION)|g'
# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure
.man.$(DRIVER_MAN_SUFFIX):
$(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@

View File

@@ -1,6 +1,6 @@
.\" shorthand for double quote that works everywhere.
.ds q \N'34'
.TH LIBINPUT __drivermansuffix__ __vendorversion__
.TH LIBINPUT 4 @VERSION@
.SH NAME
libinput \- libinput-based X.Org input driver
.SH SYNOPSIS
@@ -20,7 +20,7 @@ library documentation, go to
.SH DESCRIPTION
.B libinput
is an __xservername__ input driver based on libinput. It
is an Xorg input driver based on libinput. It
therefore supports all input devices that libinput can handle, including
most mice, keyboards, tablets and touchscreens.
.PP
@@ -28,12 +28,12 @@ It is recommended that
.B libinput
devices are configured through the
.B InputClass
directive (refer to __xconfigfile__(__filemansuffix__)) instead of manual
directive (refer to xorg.conf(5)) instead of manual
per-device configuration. Devices configured in the
__xconfigfile__(__filemansuffix__) are not hot-plug capable.
xorg.conf(5) are not hot-plug capable.
.SH CONFIGURATION DETAILS
Please refer to __xconfigfile__(__filemansuffix__) for general configuration
Please refer to xorg.conf(5) for general configuration
details and for options that can be used with all input drivers. This
section only covers configuration details specific to this driver.
.PP
@@ -45,17 +45,36 @@ are supported:
Sets the pointer acceleration profile to the given profile. Permitted values
are
.BI adaptive,
.BI flat.
.BI flat,
.BI custom.
Not all devices support this option or all profiles. If a profile is
unsupported, the default profile for this device is used. For a description
on the profiles and their behavior, see the libinput documentation.
.TP 7
.BI "Option \*qAccelSpeed\*q \*q" float \*q
Sets the pointer acceleration speed within the range [-1, 1]
Sets the pointer acceleration speed within the range [-1, 1].
This only applies to the flat or adaptive profile.
.BI "Option \*AccelPointsFallback\*q \*q" string \*q
Sets the points of the Fallback acceleration function, (see the libinput documentation).
The string must be a space-separated list of floating point non-negative numbers, e.g.
"0.0 1.0 2.4 2.5".
This only applies to the custom profile.
.BI "Option \*AccelStepFallback\*q \*q" float \*q
Sets the step between the points of the Fallback acceleration function, (see the libinput documentation).
When a step of 0.0 is provided, libinput's default Fallback acceleration function is used.
This only applies to the custom profile.
.BI "Option \*AccelPointsMotion\*q \*q" string \*q
Equivalent to AccelPointsFallback but applies to the Motion acceleration function.
.BI "Option \*AccelStepMotion\*q \*q" float \*q
Equivalent to AccelStepFallback but applies to the Motion acceleration function.
.BI "Option \*AccelPointsScroll\*q \*q" string \*q
Equivalent to AccelPointsFallback but applies to the Scroll acceleration function.
.BI "Option \*AccelStepScroll\*q \*q" float \*q
Equivalent to AccelStepFallback but applies to the Scroll acceleration function.
.TP 7
.BI "Option \*qButtonMapping\*q \*q" string \*q
Sets the logical button mapping for this device, see
XSetPointerMapping(__libmansuffix__). The string must be a
XSetPointerMapping(3). The string must be a
space-separated list of button mappings in the order of the
logical buttons on the device, starting with button 1.
The default mapping is "1 2 3 ... 32". A mapping of 0
@@ -114,11 +133,16 @@ device button numbers, i.e. the
.B ButtonMapping
applies after drag lock.
.TP 7
.BI "Option \*qHighResolutionWheelScrolling\*q \*q" bool \*q
Disables high-resolution wheel scroll events, enabled by default. When enabled,
the driver forwards only high-resolution wheel scroll events from libinput.
When disabled, the driver forwards legacy wheel scroll events instead.
.TP 7
.BI "Option \*qHorizontalScrolling\*q \*q" bool \*q
Disables horizontal scrolling. When disabled, this driver will discard any
horizontal scroll events from libinput. Note that this does not disable
horizontal scrolling, it merely discards the horizontal axis from any scroll
events.
Enables or disables horizontal scrolling. When disabled, this driver will
discard any horizontal scroll events from libinput. This does not disable
horizontal scroll events from libinput; it merely discards the horizontal axis
from any scroll events. Default is enabled.
.TP 7
.BI "Option \*qLeftHanded\*q \*q" bool \*q
Enables left-handed button orientation, i.e. swapping left and right buttons.
@@ -262,7 +286,11 @@ button pairs. See section
.B BUTTON DRAG LOCK
for details.
.TP 7
.BI "libinput Horizontal Scrolling Enabled"
.BI "libinput High Resolution Wheel Scroll Enabled"
1 boolean value (8 bit, 0 or 1). Indicates whether high-resolution
wheel scroll events are enabled or not.
.TP 7
.BI "libinput Horizontal Scroll Enabled"
1 boolean value (8 bit, 0 or 1). Indicates whether horizontal scrolling
events are enabled or not.
.TP 7
@@ -346,14 +374,14 @@ button mapping of
.B "\*q3 2 1 ...\*q"
On systems using the
.B libinput
__xservername__ input driver it is recommended to use the
Xorg input driver it is recommended to use the
.B LeftHanded
option instead.
.PP
The
.B libinput
__xservername__ input driver does not use the button mapping after setup.
Use XSetPointerMapping(__libmansuffix__) to modify the button mapping at
Xorg input driver does not use the button mapping after setup.
Use XSetPointerMapping(3) to modify the button mapping at
runtime.
.SH BUTTON DRAG LOCK
@@ -425,9 +453,9 @@ generate one logical click event and each pixel is 1/50th of a wheel click.
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
usually be worked by using \fBSection \*qInputClass\*q\fR with an
appropriate \fBMatch*\fR statement in the __xconfigfile__(__filemansuffix__).
appropriate \fBMatch*\fR statement in the xorg.conf(5).
.SH AUTHORS
Peter Hutterer
.SH "SEE ALSO"
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
Xorg(1), xorg.conf(5), Xserver(1), X(7)

141
meson.build Normal file
View File

@@ -0,0 +1,141 @@
project('xf86-input-libinput', 'c',
version: '1.3.0', # bump version in configure.ac
default_options: ['warning_level=2'],
meson_version: '>= 0.50.0')
driver_version = meson.project_version().split('.')
dir_pkgconf = get_option('prefix') / get_option('libdir') / 'pkgconfig'
dir_man4 = get_option('prefix') / get_option('mandir') / 'man4'
cc = meson.get_compiler('c')
cflags = [
'-Wno-unused-parameter',
'-Wno-sign-compare', # lots of work to get rid of this
'-Wmissing-prototypes',
'-Wstrict-prototypes',
'-Wlogical-op',
'-Wpointer-arith',
'-Wuninitialized',
'-Winit-self',
'-Wstrict-prototypes',
'-Wimplicit-fallthrough',
'-Wredundant-decls',
'-Wincompatible-pointer-types',
'-Wformat=2',
'-Wno-missing-field-initializers',
'-Wmissing-declarations',
'-fvisibility=hidden',
]
add_project_arguments(cc.get_supported_arguments(cflags), language: 'c')
pkgconfig = import('pkgconfig')
dep_xserver = dependency('xorg-server', version: '>= 1.19')
dep_xproto = dependency('xproto')
dep_inputproto = dependency('inputproto', version: '>= 2.2')
dep_libinput = dependency('libinput', version: '>= 1.11.0')
config_h = configuration_data()
config_h.set('PACKAGE_VERSION_MAJOR', driver_version[0])
config_h.set('PACKAGE_VERSION_MINOR', driver_version[1])
config_h.set('PACKAGE_VERSION_PATCHLEVEL', driver_version[2])
if dep_inputproto.version().version_compare('>= 2.3.99.1')
config_h.set('HAVE_INPUTPROTO24', 1)
endif
if cc.has_function('libinput_device_config_scroll_get_button_lock',
dependencies: dep_libinput)
config_h.set('HAVE_LIBINPUT_SCROLL_BUTTON_LOCK', 1)
endif
if cc.has_function('libinput_event_pointer_get_scroll_value_v120',
dependencies: dep_libinput)
config_h.set('HAVE_LIBINPUT_AXIS_VALUE_V120', 1)
endif
if cc.has_function('libinput_config_accel_create',
dependencies: dep_libinput)
config_h.set('HAVE_LIBINPUT_CUSTOM_ACCEL', 1)
endif
dir_headers = get_option('sdkdir')
if dir_headers == ''
dir_headers = dep_xserver.get_pkgconfig_variable('sdkdir')
endif
dir_xorg_module = get_option('xorg-module-dir')
if dir_xorg_module == ''
dir_xorg_module = dep_xserver.get_pkgconfig_variable('moduledir') / 'input'
endif
dir_xorg_conf = get_option('xorg-conf-dir')
if dir_xorg_conf == ''
dir_xorg_conf = dep_xserver.get_pkgconfig_variable('sysconfigdir')
endif
libbezier = static_library('bezier', ['src/bezier.c', 'src/bezier.h'])
dep_libbezier = declare_dependency(link_with: libbezier)
libdraglock = static_library('draglock', ['src/draglock.c', 'src/draglock.h'])
dep_libdraglock = declare_dependency(link_with: libdraglock)
dep_drivers = [
dep_xserver,
dep_xproto,
dep_inputproto,
dep_libinput,
dep_libbezier,
dep_libdraglock,
]
driver_src = ['src/xf86libinput.c', 'src/util-strings.c']
driver_lib = shared_module(
'libinput_drv',
driver_src,
name_prefix: '', # we want libinput_drv.so, not liblibinput_drv.so
include_directories: include_directories('include'),
dependencies: dep_drivers,
install: true,
install_dir: dir_xorg_module,
)
test_bezier = executable('test-bezier',
['test/test-bezier.c'],
dependencies: dep_libbezier,
include_directories: include_directories('src'),
install: false)
test('test-bezier', test_bezier)
test_draglock = executable('test-draglock',
['test/test-draglock.c'],
dependencies: dep_libdraglock,
include_directories: include_directories('src'),
install: false)
test('test-draglock', test_draglock)
conf_pkgconf = configuration_data()
conf_pkgconf.set('PACKAGE_VERSION', meson.project_version())
conf_pkgconf.set('sdkdir', dir_headers)
configure_file(
input: 'xorg-libinput.pc.in',
output: 'xorg-libinput.pc',
configuration: conf_pkgconf,
install_dir: dir_pkgconf,
)
config_man = configuration_data()
config_man.set('VERSION', '@0@ @1@'.format(meson.project_name(), meson.project_version()))
configure_file(
input: 'man/libinput.man',
output: 'libinput.4',
configuration: config_man,
install_dir: dir_man4
)
install_data('conf/40-libinput.conf', install_dir: dir_xorg_conf)
# Now generate config.h
configure_file(output: 'config.h', configuration: config_h)

15
meson_options.txt Normal file
View File

@@ -0,0 +1,15 @@
option('sdkdir',
type: 'string',
value: '',
description: 'Directory to install header files in [default=from xorg-server pkgconf]',
)
option('xorg-module-dir',
type : 'string',
value : '',
description : 'Default xorg module directory [default=from xorg-server pkgconf]',
)
option('xorg-conf-dir',
type : 'string',
value : '',
description : 'Default xorg.conf.d directory [default=from xorg-server pkgconfig]'
)

View File

@@ -33,7 +33,12 @@ AM_CPPFLAGS =-I$(top_srcdir)/include $(LIBINPUT_CFLAGS)
@DRIVER_NAME@_drv_la_LIBADD = $(LIBINPUT_LIBS) libdraglock.la libbezier.la -lm
@DRIVER_NAME@_drv_ladir = @inputdir@
@DRIVER_NAME@_drv_la_SOURCES = xf86libinput.c
@DRIVER_NAME@_drv_la_SOURCES = \
xf86libinput.c \
util-macros.h \
util-strings.h \
util-strings.c \
$(NULL)
noinst_LTLIBRARIES = libdraglock.la libbezier.la
libdraglock_la_SOURCES = draglock.c draglock.h

View File

@@ -56,7 +56,7 @@ extern const struct bezier_control_point bezier_defaults[4];
* This function requires that c[i].x <= c[i+1].x
*
* The curve is mapped into a canvas size [0, bezier_sz)². For each x
* coordiante in [0, bezier_sz), the matching y coordinate is thus
* coordinate in [0, bezier_sz), the matching y coordinate is thus
* bezier[x].
*
* In other words, if you have a range [0,2048) input possible values,

65
src/util-macros.h Normal file
View File

@@ -0,0 +1,65 @@
/*
* Copyright © 2008-2011 Kristian Høgsberg
* Copyright © 2011 Intel Corporation
* Copyright © 2013-2015 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include "config.h"
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
/**
* Iterate through the array _arr, assigning the variable elem to each
* element. elem only exists within the loop.
*/
#define ARRAY_FOR_EACH(_arr, _elem) \
for (__typeof__((_arr)[0]) *_elem = _arr; \
_elem < (_arr) + ARRAY_LENGTH(_arr); \
_elem++)
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define ANSI_HIGHLIGHT "\x1B[0;1;39m"
#define ANSI_RED "\x1B[0;31m"
#define ANSI_GREEN "\x1B[0;32m"
#define ANSI_YELLOW "\x1B[0;33m"
#define ANSI_BLUE "\x1B[0;34m"
#define ANSI_MAGENTA "\x1B[0;35m"
#define ANSI_CYAN "\x1B[0;36m"
#define ANSI_BRIGHT_RED "\x1B[0;31;1m"
#define ANSI_BRIGHT_GREEN "\x1B[0;32;1m"
#define ANSI_BRIGHT_YELLOW "\x1B[0;33;1m"
#define ANSI_BRIGHT_BLUE "\x1B[0;34;1m"
#define ANSI_BRIGHT_MAGENTA "\x1B[0;35;1m"
#define ANSI_BRIGHT_CYAN "\x1B[0;36;1m"
#define ANSI_NORMAL "\x1B[0m"
#define ANSI_UP "\x1B[%dA"
#define ANSI_DOWN "\x1B[%dB"
#define ANSI_RIGHT "\x1B[%dC"
#define ANSI_LEFT "\x1B[%dD"
#define CASE_RETURN_STRING(a) case a: return #a
#define _fallthrough_ __attribute__((fallthrough))

243
src/util-strings.c Normal file
View File

@@ -0,0 +1,243 @@
/*
* Copyright © 2008 Kristian Høgsberg
* Copyright © 2013-2015 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "config.h"
#include "util-strings.h"
/**
* Return the next word in a string pointed to by state before the first
* separator character. Call repeatedly to tokenize a whole string.
*
* @param state Current state
* @param len String length of the word returned
* @param separators List of separator characters
*
* @return The first word in *state, NOT null-terminated
*/
static const char *
next_word(const char **state, size_t *len, const char *separators)
{
const char *next = *state;
size_t l;
if (!*next)
return NULL;
next += strspn(next, separators);
if (!*next) {
*state = next;
return NULL;
}
l = strcspn(next, separators);
*state = next + l;
*len = l;
return next;
}
/**
* Return a null-terminated string array with the contents of argv
* duplicated.
*
* Use strv_free() to free the array.
*
* @return A null-terminated string array or NULL on errors
*/
char**
strv_from_argv(int argc, char **argv)
{
char **strv = NULL;
assert(argc >= 0);
if (argc == 0)
return NULL;
strv = zalloc((argc + 1) * sizeof *strv);
for (int i = 0; i < argc; i++) {
char *copy = safe_strdup(argv[i]);
if (!copy) {
strv_free(strv);
return NULL;
}
strv[i] = copy;
}
return strv;
}
/**
* Return a null-terminated string array with the tokens in the input
* string, e.g. "one two\tthree" with a separator list of " \t" will return
* an array [ "one", "two", "three", NULL ] and num elements 3.
*
* Use strv_free() to free the array.
*
* Another example:
* result = strv_from_string("+1-2++3--4++-+5-+-", "+-", &nelem)
* result == [ "1", "2", "3", "4", "5", NULL ] and nelem == 5
*
* @param in Input string
* @param separators List of separator characters
* @param num_elements Number of elements found in the input string
*
* @return A null-terminated string array or NULL on errors
*/
char **
strv_from_string(const char *in, const char *separators, size_t *num_elements)
{
assert(in != NULL);
const char *s = in;
size_t l, nelems = 0;
while (next_word(&s, &l, separators) != NULL)
nelems++;
if (nelems == 0) {
*num_elements = 0;
return NULL;
}
size_t strv_len = nelems + 1; /* NULL-terminated */
char **strv = zalloc(strv_len * sizeof *strv);
size_t idx = 0;
const char *word;
s = in;
while ((word = next_word(&s, &l, separators)) != NULL) {
char *copy = strndup(word, l);
if (!copy) {
strv_free(strv);
*num_elements = 0;
return NULL;
}
strv[idx++] = copy;
}
*num_elements = nelems;
return strv;
}
/**
* Return a newly allocated string with all elements joined by the
* joiner, same as Python's string.join() basically.
* A strv of ["one", "two", "three", NULL] with a joiner of ", " results
* in "one, two, three".
*
* An empty strv ([NULL]) returns NULL, same for passing NULL as either
* argument.
*
* @param strv Input string array
* @param joiner Joiner between the elements in the final string
*
* @return A null-terminated string joining all elements
*/
char *
strv_join(char **strv, const char *joiner)
{
char **s;
char *str;
size_t slen = 0;
size_t count = 0;
if (!strv || !joiner)
return NULL;
if (strv[0] == NULL)
return NULL;
for (s = strv, count = 0; *s; s++, count++) {
slen += strlen(*s);
}
assert(slen < 1000);
assert(strlen(joiner) < 1000);
assert(count > 0);
assert(count < 100);
slen += (count - 1) * strlen(joiner);
str = zalloc(slen + 1); /* trailing \0 */
for (s = strv; *s; s++) {
strcat(str, *s);
--count;
if (count > 0)
strcat(str, joiner);
}
return str;
}
/**
* Return a pointer to the basename within filename.
* If the filename the empty string or a directory (i.e. the last char of
* filename is '/') NULL is returned.
*/
const char *
safe_basename(const char *filename)
{
const char *basename;
if (*filename == '\0')
return NULL;
basename = strrchr(filename, '/');
if (basename == NULL)
return filename;
if (*(basename + 1) == '\0')
return NULL;
return basename + 1;
}
/**
* Similar to basename() but returns the trunk only without the (last)
* trailing suffix, so that:
*
* - foo.c returns foo
* - foo.a.b returns foo.a
* - foo returns foo
* - foo/ returns ""
*
* @return an allocated string representing the trunk name of the file
*/
char *
trunkname(const char *filename)
{
const char *base = safe_basename(filename);
char *suffix;
if (base == NULL)
return safe_strdup("");
suffix = rindex(base, '.');
if (suffix == NULL)
return safe_strdup(base);
else
return strndup(base, suffix-base);
}

464
src/util-strings.h Normal file
View File

@@ -0,0 +1,464 @@
/*
* Copyright © 2008 Kristian Høgsberg
* Copyright © 2013-2015 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include "config.h"
#define _GNU_SOURCE
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdarg.h>
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#ifdef HAVE_XLOCALE_H
#include <xlocale.h>
#endif
#include "util-macros.h"
static inline bool
streq(const char *str1, const char *str2)
{
/* one NULL, one not NULL is always false */
if (str1 && str2)
return strcmp(str1, str2) == 0;
return str1 == str2;
}
static inline bool
strneq(const char *str1, const char *str2, int n)
{
/* one NULL, one not NULL is always false */
if (str1 && str2)
return strncmp(str1, str2, n) == 0;
return str1 == str2;
}
static inline void *
zalloc(size_t size)
{
void *p;
/* We never need to alloc anything more than 1,5 MB so we can assume
* if we ever get above that something's going wrong */
if (size > 1536 * 1024)
assert(!"bug: internal malloc size limit exceeded");
p = calloc(1, size);
if (!p)
abort();
return p;
}
/**
* strdup guaranteed to succeed. If the input string is NULL, the output
* string is NULL. If the input string is a string pointer, we strdup or
* abort on failure.
*/
static inline char*
safe_strdup(const char *str)
{
char *s;
if (!str)
return NULL;
s = strdup(str);
if (!s)
abort();
return s;
}
/**
* Simple wrapper for asprintf that ensures the passed in-pointer is set
* to NULL upon error.
* The standard asprintf() call does not guarantee the passed in pointer
* will be NULL'ed upon failure, whereas this wrapper does.
*
* @param strp pointer to set to newly allocated string.
* This pointer should be passed to free() to release when done.
* @param fmt the format string to use for printing.
* @return The number of bytes printed (excluding the null byte terminator)
* upon success or -1 upon failure. In the case of failure the pointer is set
* to NULL.
*/
__attribute__ ((format (printf, 2, 3)))
static inline int
xasprintf(char **strp, const char *fmt, ...)
{
int rc = 0;
va_list args;
va_start(args, fmt);
rc = vasprintf(strp, fmt, args);
va_end(args);
if ((rc == -1) && strp)
*strp = NULL;
return rc;
}
__attribute__ ((format (printf, 2, 0)))
static inline int
xvasprintf(char **strp, const char *fmt, va_list args)
{
int rc = 0;
rc = vasprintf(strp, fmt, args);
if ((rc == -1) && strp)
*strp = NULL;
return rc;
}
static inline bool
safe_atoi_base(const char *str, int *val, int base)
{
char *endptr;
long v;
assert(base == 10 || base == 16 || base == 8);
errno = 0;
v = strtol(str, &endptr, base);
if (errno > 0)
return false;
if (str == endptr)
return false;
if (*str != '\0' && *endptr != '\0')
return false;
if (v > INT_MAX || v < INT_MIN)
return false;
*val = v;
return true;
}
static inline bool
safe_atoi(const char *str, int *val)
{
return safe_atoi_base(str, val, 10);
}
static inline bool
safe_atou_base(const char *str, unsigned int *val, int base)
{
char *endptr;
unsigned long v;
assert(base == 10 || base == 16 || base == 8);
errno = 0;
v = strtoul(str, &endptr, base);
if (errno > 0)
return false;
if (str == endptr)
return false;
if (*str != '\0' && *endptr != '\0')
return false;
if ((long)v < 0)
return false;
*val = v;
return true;
}
static inline bool
safe_atou(const char *str, unsigned int *val)
{
return safe_atou_base(str, val, 10);
}
static inline bool
safe_atod(const char *str, double *val)
{
char *endptr;
double v;
#ifdef HAVE_LOCALE_H
locale_t c_locale;
#endif
size_t slen = strlen(str);
/* We don't have a use-case where we want to accept hex for a double
* or any of the other values strtod can parse */
for (size_t i = 0; i < slen; i++) {
char c = str[i];
if (isdigit(c))
continue;
switch(c) {
case '+':
case '-':
case '.':
break;
default:
return false;
}
}
#ifdef HAVE_LOCALE_H
/* Create a "C" locale to force strtod to use '.' as separator */
c_locale = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0);
if (c_locale == (locale_t)0)
return false;
errno = 0;
v = strtod_l(str, &endptr, c_locale);
freelocale(c_locale);
#else
/* No locale support in provided libc, assume it already uses '.' */
errno = 0;
v = strtod(str, &endptr);
#endif
if (errno > 0)
return false;
if (str == endptr)
return false;
if (*str != '\0' && *endptr != '\0')
return false;
if (v != 0.0 && !isnormal(v))
return false;
*val = v;
return true;
}
char **strv_from_argv(int argc, char **argv);
char **strv_from_string(const char *in, const char *separator, size_t *num_elements);
char *strv_join(char **strv, const char *joiner);
static inline void
strv_free(char **strv) {
char **s = strv;
if (!strv)
return;
while (*s != NULL) {
free(*s);
*s = (char*)0x1; /* detect use-after-free */
s++;
}
free (strv);
}
/**
* parse a string containing a list of doubles into a double array.
*
* @param in string to parse
* @param separator string used to separate double in list e.g. ","
* @param result double array
* @param length length of double array
* @return true when parsed successfully otherwise false
*/
static inline double *
double_array_from_string(const char *in,
const char *separator,
size_t *length)
{
double *result = NULL;
*length = 0;
size_t nelem;
char **strv = strv_from_string(in, separator, &nelem);
if(!strv)
return result;
double *numv = zalloc(sizeof(double) * nelem);
for (size_t idx = 0; idx < nelem; idx++) {
double val;
if (!safe_atod(strv[idx], &val))
goto out;
numv[idx] = val;
}
result = numv;
numv = NULL;
*length = nelem;
out:
strv_free(strv);
free(numv);
return result;
}
struct key_value_str{
char *key;
char *value;
};
struct key_value_double {
double key;
double value;
};
static inline ssize_t
kv_double_from_string(const char *string,
const char *pair_separator,
const char *kv_separator,
struct key_value_double **result_out)
{
struct key_value_double *result = NULL;
if (!pair_separator || pair_separator[0] == '\0' ||
!kv_separator || kv_separator[0] == '\0')
return -1;
size_t npairs;
char **pairs = strv_from_string(string, pair_separator, &npairs);
if (!pairs || npairs == 0)
goto error;
result = zalloc(npairs * sizeof *result);
for (size_t idx = 0; idx < npairs; idx++) {
char *pair = pairs[idx];
size_t nelem;
char **kv = strv_from_string(pair, kv_separator, &nelem);
double k, v;
if (!kv || nelem != 2 ||
!safe_atod(kv[0], &k) ||
!safe_atod(kv[1], &v)) {
strv_free(kv);
goto error;
}
result[idx].key = k;
result[idx].value = v;
strv_free(kv);
}
strv_free(pairs);
*result_out = result;
return npairs;
error:
strv_free(pairs);
free(result);
return -1;
}
/**
* Strip any of the characters in what from the beginning and end of the
* input string.
*
* @return a newly allocated string with none of "what" at the beginning or
* end of string
*/
static inline char *
strstrip(const char *input, const char *what)
{
char *str, *last;
str = safe_strdup(&input[strspn(input, what)]);
last = str;
for (char *c = str; *c != '\0'; c++) {
if (!strchr(what, *c))
last = c + 1;
}
*last = '\0';
return str;
}
/**
* Return true if str ends in suffix, false otherwise. If the suffix is the
* empty string, strendswith() always returns false.
*/
static inline bool
strendswith(const char *str, const char *suffix)
{
size_t slen = strlen(str);
size_t suffixlen = strlen(suffix);
size_t offset;
if (slen == 0 || suffixlen == 0 || suffixlen > slen)
return false;
offset = slen - suffixlen;
return strneq(&str[offset], suffix, suffixlen);
}
static inline bool
strstartswith(const char *str, const char *prefix)
{
size_t prefixlen = strlen(prefix);
return prefixlen > 0 ? strneq(str, prefix, strlen(prefix)) : false;
}
const char *
safe_basename(const char *filename);
char *
trunkname(const char *filename);
/**
* Return a copy of str with all % converted to %% to make the string
* acceptable as printf format.
*/
static inline char *
str_sanitize(const char *str)
{
if (!str)
return NULL;
if (!strchr(str, '%'))
return strdup(str);
size_t slen = min(strlen(str), 512);
char *sanitized = zalloc(2 * slen + 1);
const char *src = str;
char *dst = sanitized;
for (size_t i = 0; i < slen; i++) {
if (*src == '%')
*dst++ = '%';
*dst++ = *src++;
}
*dst = '\0';
return sanitized;
}

View File

@@ -23,9 +23,7 @@
* IN THE SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <errno.h>
#include <fcntl.h>
@@ -47,6 +45,7 @@
#include "bezier.h"
#include "draglock.h"
#include "libinput-properties.h"
#include "util-strings.h"
#define TOUCHPAD_NUM_AXES 4 /* x, y, hscroll, vscroll */
#define TABLET_NUM_BUTTONS 7 /* we need scroll buttons */
@@ -56,6 +55,15 @@
#define TOUCHPAD_SCROLL_DIST_MIN 10 /* in libinput pixels */
#define TOUCHPAD_SCROLL_DIST_MAX 50 /* in libinput pixels */
#if HAVE_LIBINPUT_CUSTOM_ACCEL
#define CUSTOM_ACCEL_NPOINTS_MIN 2
#define CUSTOM_ACCEL_NPOINTS_MAX 64
#define CUSTOM_ACCEL_POINT_MIN 0
#define CUSTOM_ACCEL_POINT_MAX 10000
#define CUSTOM_ACCEL_STEP_MIN 0
#define CUSTOM_ACCEL_STEP_MAX 10000
#endif
#define streq(a, b) (strcmp(a, b) == 0)
#define strneq(a, b, n) (strncmp(a, b, n) == 0)
@@ -120,6 +128,14 @@ struct xf86libinput_tablet_tool {
struct libinput_tablet_tool *tool;
};
#if HAVE_LIBINPUT_CUSTOM_ACCEL
struct accel_points {
double step;
double points[CUSTOM_ACCEL_NPOINTS_MAX];
size_t npoints;
};
#endif
struct xf86libinput {
InputInfoPtr pInfo;
char *path;
@@ -162,10 +178,15 @@ struct xf86libinput {
enum libinput_config_scroll_method scroll_method;
enum libinput_config_click_method click_method;
enum libinput_config_accel_profile accel_profile;
#if HAVE_LIBINPUT_CUSTOM_ACCEL
struct accel_points accel_points_fallback;
struct accel_points accel_points_motion;
struct accel_points accel_points_scroll;
#endif
unsigned char btnmap[MAX_BUTTONS + 1];
BOOL horiz_scrolling_enabled;
BOOL hires_scrolling_enabled;
float rotation_angle;
struct bezier_control_point pressurecurve[4];
@@ -264,7 +285,7 @@ xf86libinput_is_subdevice(InputInfoPtr pInfo)
char *source;
BOOL is_subdevice;
source = xf86SetStrOption(pInfo->options, "_source", "");
source = xf86CheckStrOption(pInfo->options, "_source", "");
is_subdevice = streq(source, "_driver/libinput");
free(source);
@@ -515,11 +536,68 @@ LibinputApplyConfigNaturalScroll(DeviceIntPtr dev,
driver_data->options.natural_scrolling);
}
#if HAVE_LIBINPUT_CUSTOM_ACCEL
static bool
LibinputApplyConfigAccelCustom(struct xf86libinput *driver_data,
struct libinput_device *device)
{
bool success = false;
struct libinput_config_accel *accel;
enum libinput_config_status status;
accel = libinput_config_accel_create(LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
if (!accel)
goto out;
/* If the step is 0, the user has not set a custom function,
thus we don't set the points */
if (driver_data->options.accel_points_fallback.step > 0 &&
driver_data->options.accel_points_fallback.npoints >= 2) {
status = libinput_config_accel_set_points(accel,
LIBINPUT_ACCEL_TYPE_FALLBACK,
driver_data->options.accel_points_fallback.step,
driver_data->options.accel_points_fallback.npoints,
driver_data->options.accel_points_fallback.points);
if (status != LIBINPUT_CONFIG_STATUS_SUCCESS)
goto out;
}
if (driver_data->options.accel_points_motion.step > 0 &&
driver_data->options.accel_points_motion.npoints >= 2) {
status = libinput_config_accel_set_points(accel,
LIBINPUT_ACCEL_TYPE_MOTION,
driver_data->options.accel_points_motion.step,
driver_data->options.accel_points_motion.npoints,
driver_data->options.accel_points_motion.points);
if (status != LIBINPUT_CONFIG_STATUS_SUCCESS)
goto out;
}
if (driver_data->options.accel_points_scroll.step > 0 &&
driver_data->options.accel_points_scroll.npoints >= 2) {
status = libinput_config_accel_set_points(accel,
LIBINPUT_ACCEL_TYPE_SCROLL,
driver_data->options.accel_points_scroll.step,
driver_data->options.accel_points_scroll.npoints,
driver_data->options.accel_points_scroll.points);
if (status != LIBINPUT_CONFIG_STATUS_SUCCESS)
goto out;
}
status = libinput_device_config_accel_apply(device, accel);
success = status == LIBINPUT_CONFIG_STATUS_SUCCESS;
out:
libinput_config_accel_destroy(accel);
return success;
}
#endif
static void
LibinputApplyConfigAccel(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
bool success = false;
InputInfoPtr pInfo = dev->public.devicePrivate;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
@@ -528,15 +606,31 @@ LibinputApplyConfigAccel(DeviceIntPtr dev,
if (libinput_device_config_accel_is_available(device) &&
libinput_device_config_accel_set_speed(device,
driver_data->options.speed) != LIBINPUT_CONFIG_STATUS_SUCCESS)
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set speed %.2f\n",
driver_data->options.speed);
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set speed %.2f\n",
driver_data->options.speed);
if (libinput_device_config_accel_get_profiles(device) &&
driver_data->options.accel_profile != LIBINPUT_CONFIG_ACCEL_PROFILE_NONE &&
libinput_device_config_accel_set_profile(device,
driver_data->options.accel_profile) !=
LIBINPUT_CONFIG_STATUS_SUCCESS) {
if (!libinput_device_config_accel_get_profiles(device) ||
driver_data->options.accel_profile == LIBINPUT_CONFIG_ACCEL_PROFILE_NONE)
return;
switch (driver_data->options.accel_profile) {
case LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT:
case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE:
success = libinput_device_config_accel_set_profile(device, driver_data->options.accel_profile) ==
LIBINPUT_CONFIG_STATUS_SUCCESS;
break;
#if HAVE_LIBINPUT_CUSTOM_ACCEL
case LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM:
success = LibinputApplyConfigAccelCustom(driver_data, device);
break;
#endif
default:
success = false;
break;
}
if (!success) {
const char *profile;
switch (driver_data->options.accel_profile) {
@@ -546,6 +640,11 @@ LibinputApplyConfigAccel(DeviceIntPtr dev,
case LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT:
profile = "flat";
break;
#if HAVE_LIBINPUT_CUSTOM_ACCEL
case LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM:
profile = "custom";
break;
#endif
default:
profile = "unknown";
break;
@@ -1504,8 +1603,8 @@ xf86libinput_handle_absmotion(InputInfoPtr pInfo, struct libinput_event_pointer
if ((driver_data->capabilities & CAP_POINTER) == 0)
return;
x = libinput_event_pointer_get_absolute_x_transformed(event, TOUCH_AXIS_MAX);
y = libinput_event_pointer_get_absolute_y_transformed(event, TOUCH_AXIS_MAX);
x = libinput_event_pointer_get_absolute_x_transformed(event, TOUCH_AXIS_MAX + 1);
y = libinput_event_pointer_get_absolute_y_transformed(event, TOUCH_AXIS_MAX + 1);
valuator_mask_zero(mask);
valuator_mask_set_double(mask, 0, x);
@@ -1660,21 +1759,22 @@ get_wheel_scroll_value(struct xf86libinput *driver_data,
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);
if (driver_data->options.hires_scrolling_enabled)
return get_wheel_120_value(driver_data, event, axis);
#endif
return guess_wheel_scroll_value(driver_data, event, axis);
}
static inline double
get_finger_or_continuous_scroll_value(struct libinput_event_pointer *event,
get_finger_or_continuous_scroll_value(struct xf86libinput *driver_data,
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);
if (driver_data->options.hires_scrolling_enabled)
return libinput_event_pointer_get_scroll_value(event, axis);
#endif
return libinput_event_pointer_get_axis_value(event, axis);
}
static inline bool
@@ -1703,7 +1803,10 @@ calculate_axis_value(struct xf86libinput *driver_data,
double dist = driver_data->options.scroll_pixel_distance;
assert(dist != 0.0);
value = get_finger_or_continuous_scroll_value(event, axis);
value = get_finger_or_continuous_scroll_value(driver_data,
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
@@ -2404,6 +2507,7 @@ xf86libinput_handle_event(struct libinput_event *event)
struct libinput_device *device;
enum libinput_event_type type;
InputInfoPtr pInfo;
struct xf86libinput *driver_data;
enum event_handling event_handling = EVENT_HANDLED;
type = libinput_event_get_type(event);
@@ -2414,6 +2518,8 @@ xf86libinput_handle_event(struct libinput_event *event)
if (!pInfo || !pInfo->dev->public.on)
goto out;
driver_data = pInfo->private;
switch (type) {
case LIBINPUT_EVENT_NONE:
case LIBINPUT_EVENT_DEVICE_ADDED:
@@ -2437,28 +2543,40 @@ 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 */
#if HAVE_LIBINPUT_AXIS_VALUE_V120
/* ignore POINTER_AXIS where we have libinput 1.19 and
higher and high-resolution scroll is enabled */
if (driver_data->options.hires_scrolling_enabled)
break;
#endif
xf86libinput_handle_axis(pInfo,
event,
libinput_event_pointer_get_axis_source(event));
#endif
libinput_event_pointer_get_axis_source(
libinput_event_get_pointer_event(event)
));
break;
#if HAVE_LIBINPUT_AXIS_VALUE_V120
case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
xf86libinput_handle_axis(pInfo,
event,
LIBINPUT_POINTER_AXIS_SOURCE_WHEEL);
if (driver_data->options.hires_scrolling_enabled) {
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);
if (driver_data->options.hires_scrolling_enabled) {
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);
if (driver_data->options.hires_scrolling_enabled) {
xf86libinput_handle_axis(pInfo,
event,
LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
}
break;
#endif
case LIBINPUT_EVENT_TOUCH_FRAME:
@@ -2797,10 +2915,14 @@ xf86libinput_parse_accel_profile_option(InputInfoPtr pInfo,
str = xf86SetStrOption(pInfo->options, "AccelProfile", NULL);
if (!str)
profile = libinput_device_config_accel_get_profile(device);
else if (strncasecmp(str, "adaptive", 9) == 0)
else if (strcasecmp(str, "adaptive") == 0)
profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
else if (strncasecmp(str, "flat", 4) == 0)
else if (strcasecmp(str, "flat") == 0)
profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT;
#if HAVE_LIBINPUT_CUSTOM_ACCEL
else if (strcasecmp(str, "custom") == 0)
profile = LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM;
#endif
else {
xf86IDrvMsg(pInfo, X_ERROR,
"Unknown accel profile '%s'. Using default.\n",
@@ -2813,6 +2935,119 @@ xf86libinput_parse_accel_profile_option(InputInfoPtr pInfo,
return profile;
}
#if HAVE_LIBINPUT_CUSTOM_ACCEL
static inline struct accel_points
xf86libinput_parse_accel_points_option(InputInfoPtr pInfo, struct libinput_device *device, const char *name)
{
struct accel_points accel_points = {0};
char *str = NULL;
double *points = NULL;
size_t npoints = 0;
if ((libinput_device_config_accel_get_profiles(device) & LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM) == 0)
goto out;
str = xf86SetStrOption(pInfo->options, name, NULL);
if (!str)
goto out;
points = double_array_from_string(str, " ", &npoints);
if (!points) {
xf86IDrvMsg(pInfo, X_ERROR, "Failed to parse AccelPoints, ignoring points.\n");
goto out;
}
if (npoints < CUSTOM_ACCEL_NPOINTS_MIN) {
xf86IDrvMsg(pInfo, X_ERROR, "At least %d AccelPoints are required, ignoring points.\n",
CUSTOM_ACCEL_NPOINTS_MIN);
goto out;
}
if (npoints > CUSTOM_ACCEL_NPOINTS_MAX) {
xf86IDrvMsg(pInfo, X_WARNING, "Excessive number of AccelPoints, clipping to first %d points.\n",
CUSTOM_ACCEL_NPOINTS_MAX);
npoints = CUSTOM_ACCEL_NPOINTS_MAX;
}
for (size_t idx = 0; idx < npoints; idx++) {
if (points[idx] < CUSTOM_ACCEL_POINT_MIN || points[idx] > CUSTOM_ACCEL_POINT_MAX) {
xf86IDrvMsg(pInfo, X_ERROR, "AccelPoints are not in the allowed range between %d and %d, ignoring points.\n",
CUSTOM_ACCEL_POINT_MIN,
CUSTOM_ACCEL_POINT_MAX);
goto out;
}
}
memcpy(accel_points.points, points, npoints * sizeof(*points));
accel_points.npoints = npoints;
out:
free(str);
free(points);
return accel_points;
}
static inline struct accel_points
xf86libinput_parse_accel_points_fallback_option(InputInfoPtr pInfo, struct libinput_device *device)
{
return xf86libinput_parse_accel_points_option(pInfo, device, "AccelPointsFallback");
}
static inline struct accel_points
xf86libinput_parse_accel_points_motion_option(InputInfoPtr pInfo, struct libinput_device *device)
{
return xf86libinput_parse_accel_points_option(pInfo, device, "AccelPointsMotion");
}
static inline struct accel_points
xf86libinput_parse_accel_points_scroll_option(InputInfoPtr pInfo, struct libinput_device *device)
{
return xf86libinput_parse_accel_points_option(pInfo, device, "AccelPointsScroll");
}
static inline double
xf86libinput_parse_accel_step_option(InputInfoPtr pInfo, struct libinput_device *device, const char *name)
{
double step = 0.0;
double parsed_step;
if ((libinput_device_config_accel_get_profiles(device) & LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM) == 0)
return step;
parsed_step = xf86SetRealOption(pInfo->options, name, 0.0);
if (parsed_step < CUSTOM_ACCEL_STEP_MIN || parsed_step > CUSTOM_ACCEL_STEP_MAX) {
xf86IDrvMsg(pInfo, X_ERROR, "Invalid step value, ignoring step.\n");
return step;
}
if (parsed_step == 0)
xf86IDrvMsg(pInfo, X_INFO, "Step value 0 was provided, libinput Fallback acceleration function is used.\n");
step = parsed_step;
return step;
}
static inline double
xf86libinput_parse_accel_step_fallback_option(InputInfoPtr pInfo, struct libinput_device *device)
{
return xf86libinput_parse_accel_step_option(pInfo, device, "AccelStepFallback");
}
static inline double
xf86libinput_parse_accel_step_motion_option(InputInfoPtr pInfo, struct libinput_device *device)
{
return xf86libinput_parse_accel_step_option(pInfo, device, "AccelStepMotion");
}
static inline double
xf86libinput_parse_accel_step_scroll_option(InputInfoPtr pInfo, struct libinput_device *device)
{
return xf86libinput_parse_accel_step_option(pInfo, device, "AccelStepScroll");
}
#endif
static inline BOOL
xf86libinput_parse_natscroll_option(InputInfoPtr pInfo,
struct libinput_device *device)
@@ -3196,6 +3431,15 @@ xf86libinput_parse_horiz_scroll_option(InputInfoPtr pInfo)
return xf86SetBoolOption(pInfo->options, "HorizontalScrolling", TRUE);
}
static inline BOOL
xf86libinput_parse_hirescroll_option(InputInfoPtr pInfo,
struct libinput_device *device)
{
return xf86SetBoolOption(pInfo->options,
"HighResolutionWheelScrolling",
TRUE);
}
static inline double
xf86libinput_parse_rotation_angle_option(InputInfoPtr pInfo,
struct libinput_device *device)
@@ -3338,6 +3582,14 @@ xf86libinput_parse_options(InputInfoPtr pInfo,
options->tap_button_map = xf86libinput_parse_tap_buttonmap_option(pInfo, device);
options->speed = xf86libinput_parse_accel_option(pInfo, device);
options->accel_profile = xf86libinput_parse_accel_profile_option(pInfo, device);
#if HAVE_LIBINPUT_CUSTOM_ACCEL
options->accel_points_fallback = xf86libinput_parse_accel_points_fallback_option(pInfo, device);
options->accel_points_fallback.step = xf86libinput_parse_accel_step_fallback_option(pInfo, device);
options->accel_points_motion = xf86libinput_parse_accel_points_motion_option(pInfo, device);
options->accel_points_motion.step = xf86libinput_parse_accel_step_motion_option(pInfo, device);
options->accel_points_scroll = xf86libinput_parse_accel_points_scroll_option(pInfo, device);
options->accel_points_scroll.step = xf86libinput_parse_accel_step_scroll_option(pInfo, device);
#endif
options->natural_scrolling = xf86libinput_parse_natscroll_option(pInfo, device);
options->sendevents = xf86libinput_parse_sendevents_option(pInfo, device);
options->left_handed = xf86libinput_parse_lefthanded_option(pInfo, device);
@@ -3358,6 +3610,7 @@ xf86libinput_parse_options(InputInfoPtr pInfo,
if (driver_data->capabilities & CAP_POINTER) {
xf86libinput_parse_draglock_option(pInfo, driver_data);
options->horiz_scrolling_enabled = xf86libinput_parse_horiz_scroll_option(pInfo);
options->hires_scrolling_enabled = xf86libinput_parse_hirescroll_option(pInfo, device);
}
xf86libinput_parse_pressurecurve_option(pInfo,
@@ -3641,7 +3894,7 @@ xf86libinput_pre_init(InputDriverPtr drv,
goto fail;
}
/* We ref the device above, then remove it. It get's
/* We ref the device above, then remove it. It gets
re-added with the same path in DEVICE_ON, we hope
it doesn't change until then */
libinput_device_ref(device);
@@ -3797,6 +4050,14 @@ static Atom prop_calibration_default;
static Atom prop_accel;
static Atom prop_accel_default;
static Atom prop_accel_profile_enabled;
#if HAVE_LIBINPUT_CUSTOM_ACCEL
static Atom prop_accel_points_fallback;
static Atom prop_accel_step_fallback;
static Atom prop_accel_points_motion;
static Atom prop_accel_step_motion;
static Atom prop_accel_points_scroll;
static Atom prop_accel_step_scroll;
#endif
static Atom prop_accel_profile_default;
static Atom prop_accel_profiles_available;
static Atom prop_natural_scroll;
@@ -3835,6 +4096,7 @@ static Atom prop_draglock;
static Atom prop_horiz_scroll;
static Atom prop_pressurecurve;
static Atom prop_area_ratio;
static Atom prop_hires_scroll;
/* general properties */
static Atom prop_float;
@@ -4165,7 +4427,7 @@ LibinputSetPropertyAccelProfile(DeviceIntPtr dev,
BOOL* data;
uint32_t profiles = 0;
if (val->format != 8 || val->size != 2 || val->type != XA_INTEGER)
if (val->format != 8 || val->size < 2 || val->size > 3 || val->type != XA_INTEGER)
return BadMatch;
data = (BOOL*)val->data;
@@ -4174,6 +4436,10 @@ LibinputSetPropertyAccelProfile(DeviceIntPtr dev,
profiles |= LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
if (data[1])
profiles |= LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT;
#if HAVE_LIBINPUT_CUSTOM_ACCEL
if (val->size > 2 && data[2])
profiles |= LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM;
#endif
if (checkonly) {
uint32_t supported;
@@ -4194,6 +4460,96 @@ LibinputSetPropertyAccelProfile(DeviceIntPtr dev,
return Success;
}
#if HAVE_LIBINPUT_CUSTOM_ACCEL
static inline int
LibinputSetPropertyAccelPoints(DeviceIntPtr dev,
Atom atom,
XIPropertyValuePtr val,
BOOL checkonly)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
struct libinput_device *device = driver_data->shared_device->device;
float* data;
struct accel_points *accel_points = NULL;
if (val->format != 32 || val->type != prop_float ||
val->size < CUSTOM_ACCEL_NPOINTS_MIN || val->size > CUSTOM_ACCEL_NPOINTS_MAX)
return BadMatch;
data = (float*)val->data;
if (checkonly) {
uint32_t profiles;
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
profiles = libinput_device_config_accel_get_profiles(device);
if ((profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM) == 0)
return BadValue;
for (size_t idx = 0; idx < val->size; idx++) {
if (data[idx] < CUSTOM_ACCEL_POINT_MIN || data[idx] > CUSTOM_ACCEL_POINT_MAX)
return BadValue;
}
} else {
if (atom == prop_accel_points_fallback)
accel_points = &driver_data->options.accel_points_fallback;
else if (atom == prop_accel_points_motion)
accel_points = &driver_data->options.accel_points_motion;
else if (atom == prop_accel_points_scroll)
accel_points = &driver_data->options.accel_points_scroll;
for (size_t idx = 0; idx < val->size; idx++)
accel_points->points[idx] = data[idx];
accel_points->npoints = val->size;
}
return Success;
}
static inline int
LibinputSetPropertyAccelStep(DeviceIntPtr dev,
Atom atom,
XIPropertyValuePtr val,
BOOL checkonly)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
struct libinput_device *device = driver_data->shared_device->device;
float* data;
if (val->format != 32 || val->type != prop_float || val->size != 1)
return BadMatch;
data = (float*)val->data;
if (checkonly) {
uint32_t profiles;
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
profiles = libinput_device_config_accel_get_profiles(device);
if ((profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM) == 0)
return BadValue;
if (*data < CUSTOM_ACCEL_STEP_MIN || *data > CUSTOM_ACCEL_STEP_MAX)
return BadValue;
} else {
if (atom == prop_accel_step_fallback)
driver_data->options.accel_points_fallback.step = *data;
else if (atom == prop_accel_step_motion)
driver_data->options.accel_points_motion.step = *data;
else if (atom == prop_accel_step_scroll)
driver_data->options.accel_points_scroll.step = *data;
}
return Success;
}
#endif
static inline int
LibinputSetPropertyNaturalScroll(DeviceIntPtr dev,
Atom atom,
@@ -4406,7 +4762,7 @@ LibinputSetPropertyScrollButtonLock(DeviceIntPtr dev,
struct xf86libinput *driver_data = pInfo->private;
BOOL enabled;
if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
enabled = *(BOOL*)val->data;
@@ -4615,7 +4971,7 @@ LibinputSetPropertyHorizScroll(DeviceIntPtr dev,
struct xf86libinput *driver_data = pInfo->private;
BOOL enabled;
if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
enabled = *(BOOL*)val->data;
@@ -4642,7 +4998,7 @@ LibinputSetPropertyScrollPixelDistance(DeviceIntPtr dev,
struct xf86libinput *driver_data = pInfo->private;
uint32_t dist;
if (val->format != 32 || val->type != XA_CARDINAL || val->size != 1)
if (val->format != 32 || val->size != 1 || val->type != XA_CARDINAL)
return BadMatch;
dist = *(BOOL*)val->data;
@@ -4794,6 +5150,33 @@ LibinputSetPropertyAreaRatio(DeviceIntPtr dev,
return Success;
}
static inline int
LibinputSetPropertyHighResolutionScroll(DeviceIntPtr dev,
Atom atom,
XIPropertyValuePtr val,
BOOL checkonly)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
BOOL enabled;
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
enabled = *(BOOL*)val->data;
if (checkonly) {
if (enabled != 0 && enabled != 1)
return BadValue;
if (!xf86libinput_check_device(dev, atom))
return BadMatch;
} else {
driver_data->options.hires_scrolling_enabled = enabled;
}
return Success;
}
static int
LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
BOOL checkonly)
@@ -4815,6 +5198,16 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
rc = LibinputSetPropertyAccel(dev, atom, val, checkonly);
else if (atom == prop_accel_profile_enabled)
rc = LibinputSetPropertyAccelProfile(dev, atom, val, checkonly);
#if HAVE_LIBINPUT_CUSTOM_ACCEL
else if (atom == prop_accel_points_fallback ||
atom == prop_accel_points_motion ||
atom == prop_accel_points_scroll)
rc = LibinputSetPropertyAccelPoints(dev, atom, val, checkonly);
else if (atom == prop_accel_step_fallback ||
atom == prop_accel_step_motion ||
atom == prop_accel_step_scroll)
rc = LibinputSetPropertyAccelStep(dev, atom, val, checkonly);
#endif
else if (atom == prop_natural_scroll)
rc = LibinputSetPropertyNaturalScroll(dev, atom, val, checkonly);
else if (atom == prop_sendevents_enabled)
@@ -4854,6 +5247,8 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
rc = LibinputSetPropertyPressureCurve(dev, atom, val, checkonly);
else if (atom == prop_area_ratio)
rc = LibinputSetPropertyAreaRatio(dev, atom, val, checkonly);
else if (atom == prop_hires_scroll)
rc = LibinputSetPropertyHighResolutionScroll(dev, atom, val, checkonly);
else if (atom == prop_device || atom == prop_product_id ||
atom == prop_tap_default ||
atom == prop_tap_drag_default ||
@@ -5094,7 +5489,24 @@ LibinputInitAccelProperty(DeviceIntPtr dev,
float speed = driver_data->options.speed;
uint32_t profile_mask;
enum libinput_config_accel_profile profile;
BOOL profiles[2] = {FALSE};
BOOL profiles[3] = {FALSE};
#if HAVE_LIBINPUT_CUSTOM_ACCEL
float custom_points_fallback[CUSTOM_ACCEL_NPOINTS_MAX] = {0};
float custom_points_motion[CUSTOM_ACCEL_NPOINTS_MAX] = {0};
float custom_points_scroll[CUSTOM_ACCEL_NPOINTS_MAX] = {0};
size_t custom_npoints_fallback = driver_data->options.accel_points_fallback.npoints;
size_t custom_npoints_motion = driver_data->options.accel_points_motion.npoints;
size_t custom_npoints_scroll = driver_data->options.accel_points_scroll.npoints;
float custom_step_fallback = driver_data->options.accel_points_fallback.step;
float custom_step_motion = driver_data->options.accel_points_motion.step;
float custom_step_scroll = driver_data->options.accel_points_scroll.step;
for (size_t idx = 0; idx < CUSTOM_ACCEL_NPOINTS_MAX; idx++) {
custom_points_fallback[idx] = driver_data->options.accel_points_fallback.points[idx];
custom_points_motion[idx] = driver_data->options.accel_points_motion.points[idx];
custom_points_scroll[idx] = driver_data->options.accel_points_scroll.points[idx];
}
#endif
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
@@ -5122,8 +5534,12 @@ LibinputInitAccelProperty(DeviceIntPtr dev,
if (profile_mask & LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE)
profiles[0] = TRUE;
if (profile_mask & LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE)
if (profile_mask & LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT)
profiles[1] = TRUE;
#if HAVE_LIBINPUT_CUSTOM_ACCEL
if (profile_mask & LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM)
profiles[2] = TRUE;
#endif
prop_accel_profiles_available = LibinputMakeProperty(dev,
LIBINPUT_PROP_ACCEL_PROFILES_AVAILABLE,
@@ -5143,6 +5559,11 @@ LibinputInitAccelProperty(DeviceIntPtr dev,
case LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT:
profiles[1] = TRUE;
break;
#if HAVE_LIBINPUT_CUSTOM_ACCEL
case LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM:
profiles[2] = TRUE;
break;
#endif
default:
break;
}
@@ -5165,6 +5586,11 @@ LibinputInitAccelProperty(DeviceIntPtr dev,
case LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT:
profiles[1] = TRUE;
break;
#if HAVE_LIBINPUT_CUSTOM_ACCEL
case LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM:
profiles[2] = TRUE;
break;
#endif
default:
break;
}
@@ -5177,6 +5603,35 @@ LibinputInitAccelProperty(DeviceIntPtr dev,
if (!prop_accel_profile_default)
return;
#if HAVE_LIBINPUT_CUSTOM_ACCEL
prop_accel_points_fallback = LibinputMakeProperty(dev,
LIBINPUT_PROP_ACCEL_CUSTOM_POINTS_FALLBACK,
prop_float, 32,
custom_npoints_fallback,
custom_points_fallback);
prop_accel_step_fallback = LibinputMakeProperty(dev,
LIBINPUT_PROP_ACCEL_CUSTOM_STEP_FALLBACK,
prop_float, 32, 1,
&custom_step_fallback);
prop_accel_points_motion = LibinputMakeProperty(dev,
LIBINPUT_PROP_ACCEL_CUSTOM_POINTS_MOTION,
prop_float, 32,
custom_npoints_motion,
custom_points_motion);
prop_accel_step_motion = LibinputMakeProperty(dev,
LIBINPUT_PROP_ACCEL_CUSTOM_STEP_MOTION,
prop_float, 32, 1,
&custom_step_motion);
prop_accel_points_scroll = LibinputMakeProperty(dev,
LIBINPUT_PROP_ACCEL_CUSTOM_POINTS_SCROLL,
prop_float, 32,
custom_npoints_scroll,
custom_points_scroll);
prop_accel_step_scroll = LibinputMakeProperty(dev,
LIBINPUT_PROP_ACCEL_CUSTOM_STEP_SCROLL,
prop_float, 32, 1,
&custom_step_scroll);
#endif
}
static void
@@ -5808,6 +6263,22 @@ LibinputInitTabletAreaRatioProperty(DeviceIntPtr dev,
2, data);
}
static void
LibinputInitHighResolutionScrollProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
BOOL enabled = driver_data->options.hires_scrolling_enabled;
if ((driver_data->capabilities & CAP_POINTER) == 0)
return;
prop_hires_scroll = LibinputMakeProperty(dev,
LIBINPUT_PROP_HIRES_WHEEL_SCROLL_ENABLED,
XA_INTEGER, 8,
1, &enabled);
}
static void
LibinputInitProperty(DeviceIntPtr dev)
{
@@ -5867,4 +6338,5 @@ LibinputInitProperty(DeviceIntPtr dev)
LibinputInitScrollPixelDistanceProperty(dev, driver_data, device);
LibinputInitPressureCurveProperty(dev, driver_data);
LibinputInitTabletAreaRatioProperty(dev, driver_data);
LibinputInitHighResolutionScrollProperty(dev, driver_data, device);
}