mirror of
https://github.com/X11Libre/xf86-input-libinput.git
synced 2026-03-24 17:44:05 +00:00
Compare commits
21 Commits
xf86-input
...
xf86-input
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8cf533df3a | ||
|
|
484b6a7f3f | ||
|
|
e87c7bfcc2 | ||
|
|
f94a8edb0e | ||
|
|
ca02afd8d2 | ||
|
|
252bc4ba0d | ||
|
|
925903018f | ||
|
|
dfc5e20426 | ||
|
|
2ee183a6cd | ||
|
|
efa999e377 | ||
|
|
7b4a870b23 | ||
|
|
30500626fe | ||
|
|
62f267a952 | ||
|
|
c1f07edafa | ||
|
|
a3d38b0f40 | ||
|
|
e3a75f34f8 | ||
|
|
830f7c3b1b | ||
|
|
4ab7873366 | ||
|
|
b3e65904db | ||
|
|
75cc87518b | ||
|
|
3951ce739d |
@@ -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
|
||||
|
||||
18
configure.ac
18
configure.ac
@@ -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
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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) < $< > $@
|
||||
|
||||
@@ -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
141
meson.build
Normal 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
15
meson_options.txt
Normal 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]'
|
||||
)
|
||||
@@ -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
|
||||
|
||||
@@ -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
65
src/util-macros.h
Normal 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
243
src/util-strings.c
Normal 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
464
src/util-strings.h
Normal 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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user