mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-20 06:50:05 +01:00
Compare commits
186 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0412fb3d44 | ||
|
|
a376fe366c | ||
|
|
9a07784451 | ||
|
|
3cf723451f | ||
|
|
2d3e47290c | ||
|
|
5bd7f93c16 | ||
|
|
a202ed6115 | ||
|
|
c0c809aaa1 | ||
|
|
e8dfc3bfd6 | ||
|
|
b3f7b4b1ea | ||
|
|
0285001272 | ||
|
|
bde6d07d57 | ||
|
|
1b4dbb9087 | ||
|
|
d5d38b2ed1 | ||
|
|
38b5c2e0cc | ||
|
|
20851b5020 | ||
|
|
2003ab3aef | ||
|
|
4bb6a31894 | ||
|
|
db6a04665c | ||
|
|
7621edab05 | ||
|
|
39aea2a8d6 | ||
|
|
7e8298e9ec | ||
|
|
49d9528bdf | ||
|
|
1e8901d009 | ||
|
|
a6ad084280 | ||
|
|
11b97edcdc | ||
|
|
c2f9ffe17e | ||
|
|
21e3a76bf5 | ||
|
|
9461d1a9a1 | ||
|
|
a595f0bd48 | ||
|
|
32ed3060f9 | ||
|
|
a12dc6eba3 | ||
|
|
f6caae2289 | ||
|
|
20a3131947 | ||
|
|
822e571272 | ||
|
|
9c78f989fb | ||
|
|
9b37ffd340 | ||
|
|
b9a04e4d57 | ||
|
|
4fd5fe9d30 | ||
|
|
941aa9f997 | ||
|
|
b870abd2f3 | ||
|
|
ad6f580b6d | ||
|
|
4ffd8ab544 | ||
|
|
eac44529d8 | ||
|
|
4fe3225050 | ||
|
|
45878c3aac | ||
|
|
f0d8002255 | ||
|
|
037c07d76f | ||
|
|
1dcf630584 | ||
|
|
eb01a4e73f | ||
|
|
f27fbdfa53 | ||
|
|
07659db3d9 | ||
|
|
f18bf988f7 | ||
|
|
6b9dbc2a25 | ||
|
|
2784973b4d | ||
|
|
22dda5b154 | ||
|
|
07a9161ef2 | ||
|
|
141f571aae | ||
|
|
48a3391f33 | ||
|
|
bda0c7478e | ||
|
|
66f2d121ee | ||
|
|
60c5fdbc2f | ||
|
|
cc7dfccd22 | ||
|
|
94b7836456 | ||
|
|
2d4482e03d | ||
|
|
607852e66d | ||
|
|
a60976c1d4 | ||
|
|
aac0d3c2f8 | ||
|
|
327db95a7c | ||
|
|
4a705ba8d7 | ||
|
|
d6e1f93812 | ||
|
|
dd3f931481 | ||
|
|
d1720d351d | ||
|
|
fcb5dfe515 | ||
|
|
43c7644f01 | ||
|
|
3307341ebf | ||
|
|
4b1bae3f8c | ||
|
|
f9977dba9c | ||
|
|
3725bb0b93 | ||
|
|
d19f95ec21 | ||
|
|
533d5f6ee1 | ||
|
|
3250686e70 | ||
|
|
aa7d58005e | ||
|
|
5df3eb8527 | ||
|
|
185e1bd824 | ||
|
|
195c39b21a | ||
|
|
6dcb47185e | ||
|
|
e07e138809 | ||
|
|
a4ea1e2d97 | ||
|
|
772c1f5ebb | ||
|
|
95281de7e4 | ||
|
|
32a9863507 | ||
|
|
a0a6ff2777 | ||
|
|
60bcbb6c88 | ||
|
|
4f6c741570 | ||
|
|
69ed729e80 | ||
|
|
f3f8e8ef6c | ||
|
|
ce1112c263 | ||
|
|
428a3299a8 | ||
|
|
bdb51593fe | ||
|
|
d9c9e0ff25 | ||
|
|
4d317eae17 | ||
|
|
2f2bd357bc | ||
|
|
b2cd9c69a0 | ||
|
|
3ff1a2e24d | ||
|
|
e45cd2bc13 | ||
|
|
537552480d | ||
|
|
5abe051a9c | ||
|
|
9b58177a7e | ||
|
|
cdfe34f62a | ||
|
|
ce87da63ba | ||
|
|
4e002383cf | ||
|
|
17617a75c4 | ||
|
|
48a26f91c3 | ||
|
|
c0519c3b5e | ||
|
|
960df4d8b8 | ||
|
|
347ff90871 | ||
|
|
5b2a723a02 | ||
|
|
afd3be9a99 | ||
|
|
2bb9c66cd7 | ||
|
|
18992b2ec0 | ||
|
|
cf52552eef | ||
|
|
7ac051ab41 | ||
|
|
4f0b82800a | ||
|
|
aa9d5bf630 | ||
|
|
b831068fbb | ||
|
|
a0d286741c | ||
|
|
5495511485 | ||
|
|
4ef50ee946 | ||
|
|
a102269364 | ||
|
|
2562c24f95 | ||
|
|
47d4c563f4 | ||
|
|
931dad76a9 | ||
|
|
7f3aa8058a | ||
|
|
c1d8d92b57 | ||
|
|
2723cadaeb | ||
|
|
9e37bc0cfa | ||
|
|
0c65b1069b | ||
|
|
d557a649fd | ||
|
|
d1dbbb7328 | ||
|
|
3a86b6ea58 | ||
|
|
f04b276ac1 | ||
|
|
d45f4493f1 | ||
|
|
4c4d5f33ee | ||
|
|
8336721dc0 | ||
|
|
6dfd72dc03 | ||
|
|
ce85ee7d35 | ||
|
|
d9a4667a14 | ||
|
|
465fce9128 | ||
|
|
68dbb98f04 | ||
|
|
a22883f7e2 | ||
|
|
7d59252643 | ||
|
|
59f0d8f647 | ||
|
|
936cee2242 | ||
|
|
3ca34aa88a | ||
|
|
96d1954dce | ||
|
|
b8651d798c | ||
|
|
74705ee94c | ||
|
|
e8d24f818b | ||
|
|
4a67ddc111 | ||
|
|
cfec80582e | ||
|
|
36b2afae82 | ||
|
|
6aefc2f166 | ||
|
|
4326413238 | ||
|
|
73103a5c38 | ||
|
|
abd5989ee8 | ||
|
|
7a22eb8d08 | ||
|
|
80b45ff28e | ||
|
|
35838e9b2c | ||
|
|
013ed167a4 | ||
|
|
eed4f84508 | ||
|
|
18b34d0bc0 | ||
|
|
c24ad64d18 | ||
|
|
7140f13d82 | ||
|
|
ccc798808a | ||
|
|
79ea713aa3 | ||
|
|
7e98f2f2d2 | ||
|
|
778caa41af | ||
|
|
f98db521ee | ||
|
|
0b07e77c3e | ||
|
|
c7ec39f51e | ||
|
|
09acce4ce8 | ||
|
|
c75d158bc0 | ||
|
|
8fcacca7da | ||
|
|
1dec6f98b0 | ||
|
|
975ce6dbf5 |
158 changed files with 9864 additions and 1953 deletions
|
|
@ -74,6 +74,7 @@ ForEachMacros:
|
|||
- tp_for_each_touch
|
||||
- range_for_each
|
||||
- litest_log_group
|
||||
- litest_with_logcapture
|
||||
- litest_with_parameters
|
||||
- litest_with_event_frame
|
||||
- udev_list_entry_foreach
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@
|
|||
Checks: >
|
||||
-clang-analyzer-unix.Malloc,
|
||||
-clang-analyzer-optin.core.EnumCastOutOfRange
|
||||
WarningsAsErrors: true
|
||||
WarningsAsErrors: '*'
|
||||
|
|
|
|||
308
.gitlab-ci.yml
308
.gitlab-ci.yml
|
|
@ -98,11 +98,11 @@ variables:
|
|||
# See the documentation here: #
|
||||
# https://wayland.freedesktop.org/libinput/doc/latest/building.html #
|
||||
###############################################################################
|
||||
FEDORA_PACKAGES: 'git-core gcc gcc-c++ pkgconf-pkg-config meson check-devel libudev-devel libevdev-devel doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx_rtd_theme python3-pytest-xdist libwacom-devel cairo-devel gtk4-devel glib2-devel mtdev-devel diffutils wayland-protocols-devel black clang clang-tools-extra jq rpmdevtools valgrind systemd-udev qemu-img qemu-system-x86-core qemu-system-aarch64-core jq python3-click python3-rich virtme-ng'
|
||||
DEBIAN_PACKAGES: 'git gcc g++ pkg-config meson check libudev-dev libevdev-dev doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme python3-pytest-xdist libwacom-dev libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev curl'
|
||||
UBUNTU_PACKAGES: 'git gcc g++ pkg-config meson check libudev-dev libevdev-dev doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme python3-pytest-xdist libwacom-dev libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev'
|
||||
ARCH_PACKAGES: 'git gcc pkgconfig meson check libsystemd libevdev python-pytest-xdist libwacom gtk4 mtdev diffutils'
|
||||
ALPINE_PACKAGES: 'git gcc build-base pkgconfig meson check-dev eudev-dev libevdev-dev libwacom-dev cairo-dev gtk4.0-dev mtdev-dev bash'
|
||||
FEDORA_PACKAGES: 'git-core gcc gcc-c++ pkgconf-pkg-config meson check-devel libudev-devel libevdev-devel doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx_rtd_theme python3-pytest-xdist libwacom-devel cairo-devel gtk4-devel glib2-devel mtdev-devel diffutils wayland-protocols-devel black clang clang-tools-extra jq rpmdevtools valgrind systemd-udev qemu-img qemu-system-x86-core qemu-system-aarch64-core jq python3-click python3-rich virtme-ng lua-devel'
|
||||
DEBIAN_PACKAGES: 'git gcc g++ pkg-config meson check libudev-dev libevdev-dev doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme python3-pytest-xdist libwacom-dev libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev curl lua5.4-dev'
|
||||
UBUNTU_PACKAGES: 'git gcc g++ pkg-config meson check libudev-dev libevdev-dev doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme python3-pytest-xdist libwacom-dev libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev lua5.4-dev'
|
||||
ARCH_PACKAGES: 'git gcc pkgconfig meson check libsystemd libevdev python-pytest-xdist libwacom gtk4 mtdev diffutils lua'
|
||||
ALPINE_PACKAGES: 'git gcc build-base pkgconfig meson check-dev eudev-dev libevdev-dev libwacom-dev cairo-dev gtk4.0-dev mtdev-dev bash lua5.4-dev'
|
||||
FREEBSD_PACKAGES: 'git pkgconf meson libepoll-shim libudev-devd libevdev libwacom gtk3 libmtdev bash wayland'
|
||||
############################ end of package lists #############################
|
||||
|
||||
|
|
@ -110,12 +110,12 @@ variables:
|
|||
# changing these will force rebuilding the associated image
|
||||
# Note: these tags have no meaning and are not tied to a particular
|
||||
# libinput version
|
||||
FEDORA_TAG: '2025-05-19.0'
|
||||
DEBIAN_TAG: '2025-05-19.0'
|
||||
UBUNTU_TAG: '2025-05-19.0'
|
||||
ARCH_TAG: '2025-05-19.0'
|
||||
ALPINE_TAG: '2025-05-19.0'
|
||||
FREEBSD_TAG: '2025-05-19.0'
|
||||
FEDORA_TAG: '2025-11-17.0'
|
||||
DEBIAN_TAG: '2025-11-17.0'
|
||||
UBUNTU_TAG: '2025-11-17.0'
|
||||
ARCH_TAG: '2025-11-17.0'
|
||||
ALPINE_TAG: '2025-11-17.0'
|
||||
FREEBSD_TAG: '2025-11-17.0'
|
||||
|
||||
FDO_UPSTREAM_REPO: libinput/libinput
|
||||
|
||||
|
|
@ -258,7 +258,7 @@ pre-commit-hooks:
|
|||
- python3 -m venv venv
|
||||
- source venv/bin/activate
|
||||
- pip3 install pre-commit
|
||||
- pre-commit run --all-files || true
|
||||
- pre-commit run --all-files
|
||||
- git diff --exit-code || (echo "ERROR - Code style errors found, please fix" && false)
|
||||
|
||||
#################################################################
|
||||
|
|
@ -267,18 +267,6 @@ pre-commit-hooks:
|
|||
# #
|
||||
#################################################################
|
||||
|
||||
fedora:41@container-prep:
|
||||
extends:
|
||||
- .fdo.container-build@fedora
|
||||
- .policy
|
||||
- .fdo-runner-tags
|
||||
stage: prep
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
FDO_DISTRIBUTION_VERSION: '41'
|
||||
FDO_DISTRIBUTION_PACKAGES: $FEDORA_PACKAGES
|
||||
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
||||
|
||||
fedora:42@container-prep:
|
||||
extends:
|
||||
- .fdo.container-build@fedora
|
||||
|
|
@ -291,6 +279,18 @@ fedora:42@container-prep:
|
|||
FDO_DISTRIBUTION_PACKAGES: $FEDORA_PACKAGES
|
||||
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
||||
|
||||
fedora:43@container-prep:
|
||||
extends:
|
||||
- .fdo.container-build@fedora
|
||||
- .policy
|
||||
- .fdo-runner-tags
|
||||
stage: prep
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
FDO_DISTRIBUTION_VERSION: '43'
|
||||
FDO_DISTRIBUTION_PACKAGES: $FEDORA_PACKAGES
|
||||
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
||||
|
||||
debian:stable@container-prep:
|
||||
extends:
|
||||
- .fdo.container-build@debian
|
||||
|
|
@ -303,7 +303,7 @@ debian:stable@container-prep:
|
|||
FDO_DISTRIBUTION_PACKAGES: $DEBIAN_PACKAGES
|
||||
FDO_DISTRIBUTION_TAG: $DEBIAN_TAG
|
||||
|
||||
ubuntu:25.04@container-prep:
|
||||
ubuntu:25.10@container-prep:
|
||||
extends:
|
||||
- .fdo.container-build@ubuntu
|
||||
- .policy
|
||||
|
|
@ -311,7 +311,7 @@ ubuntu:25.04@container-prep:
|
|||
stage: prep
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
FDO_DISTRIBUTION_VERSION: '25.04'
|
||||
FDO_DISTRIBUTION_VERSION: '25.10'
|
||||
FDO_DISTRIBUTION_PACKAGES: $UBUNTU_PACKAGES
|
||||
FDO_DISTRIBUTION_TAG: $UBUNTU_TAG
|
||||
|
||||
|
|
@ -386,16 +386,6 @@ freebsd:14.2@container-prep:
|
|||
only:
|
||||
- schedules
|
||||
|
||||
fedora:41@container-clean:
|
||||
extends:
|
||||
- .policy
|
||||
- .container-clean
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
CURRENT_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/fedora/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG
|
||||
FDO_DISTRIBUTION_VERSION: '41'
|
||||
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
||||
|
||||
fedora:42@container-clean:
|
||||
extends:
|
||||
- .policy
|
||||
|
|
@ -406,6 +396,16 @@ fedora:42@container-clean:
|
|||
FDO_DISTRIBUTION_VERSION: '42'
|
||||
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
||||
|
||||
fedora:43@container-clean:
|
||||
extends:
|
||||
- .policy
|
||||
- .container-clean
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
CURRENT_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/fedora/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG
|
||||
FDO_DISTRIBUTION_VERSION: '43'
|
||||
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
||||
|
||||
debian:stable@container-clean:
|
||||
extends:
|
||||
- .policy
|
||||
|
|
@ -416,14 +416,14 @@ debian:stable@container-clean:
|
|||
FDO_DISTRIBUTION_VERSION: 'stable'
|
||||
FDO_DISTRIBUTION_TAG: $DEBIAN_TAG
|
||||
|
||||
ubuntu:25.04@container-clean:
|
||||
ubuntu:25.10@container-clean:
|
||||
extends:
|
||||
- .policy
|
||||
- .container-clean
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
CURRENT_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/ubuntu/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG
|
||||
FDO_DISTRIBUTION_VERSION: '25.04'
|
||||
FDO_DISTRIBUTION_VERSION: '25.10'
|
||||
FDO_DISTRIBUTION_TAG: $UBUNTU_TAG
|
||||
|
||||
arch:rolling@container-clean:
|
||||
|
|
@ -577,20 +577,20 @@ freebsd:14.2@container-clean:
|
|||
- export MESON_TEST_ARGS="$MESON_TEST_ARGS $SUITES"
|
||||
|
||||
|
||||
.fedora:42@test-suite-vm:
|
||||
.fedora:43@test-suite-vm:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .test-suite-vm
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: 42
|
||||
FDO_DISTRIBUTION_VERSION: 43
|
||||
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
||||
needs:
|
||||
- "fedora:42@container-prep"
|
||||
- "fedora:43@container-prep"
|
||||
|
||||
|
||||
vm-touchpad:
|
||||
extends:
|
||||
- .fedora:42@test-suite-vm
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'touchpad'
|
||||
|
||||
|
|
@ -603,7 +603,7 @@ vm-touchpad-no-libwacom:
|
|||
|
||||
vm-touchpad_palm:
|
||||
extends:
|
||||
- .fedora:42@test-suite-vm
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'touchpad_palm'
|
||||
|
||||
|
|
@ -616,7 +616,7 @@ vm-touchpad_palm-no-libwacom:
|
|||
|
||||
vm-touchpad_dwt:
|
||||
extends:
|
||||
- .fedora:42@test-suite-vm
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'touchpad_dwt'
|
||||
|
||||
|
|
@ -629,7 +629,7 @@ vm-touchpad_dwt-no-libwacom:
|
|||
|
||||
vm-tap:
|
||||
extends:
|
||||
- .fedora:42@test-suite-vm
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'touchpad_tap'
|
||||
|
||||
|
|
@ -642,7 +642,7 @@ vm-tap-no-libwacom:
|
|||
|
||||
vm-tap-drag:
|
||||
extends:
|
||||
- .fedora:42@test-suite-vm
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'touchpad_tap_drag'
|
||||
|
||||
|
|
@ -655,7 +655,7 @@ vm-tap-drag-no-libwacom:
|
|||
|
||||
vm-tap-palm:
|
||||
extends:
|
||||
- .fedora:42@test-suite-vm
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'touchpad_tap_palm'
|
||||
|
||||
|
|
@ -668,7 +668,7 @@ vm-tap-palm-no-libwacom:
|
|||
|
||||
vm-touchpad-buttons:
|
||||
extends:
|
||||
- .fedora:42@test-suite-vm
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'touchpad_buttons'
|
||||
|
||||
|
|
@ -681,7 +681,7 @@ vm-touchpad-buttons-no-libwacom:
|
|||
|
||||
vm-tablet:
|
||||
extends:
|
||||
- .fedora:42@test-suite-vm
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'tablet'
|
||||
|
||||
|
|
@ -694,7 +694,7 @@ vm-tablet-no-libwacom:
|
|||
|
||||
vm-tablet_left_handed:
|
||||
extends:
|
||||
- .fedora:42@test-suite-vm
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'tablet_left_handed'
|
||||
|
||||
|
|
@ -705,9 +705,35 @@ vm-tablet_left_handed-no-libwacom:
|
|||
variables:
|
||||
MESON_ARGS: '-Dlibwacom=false'
|
||||
|
||||
vm-tablet_proximity_tip:
|
||||
extends:
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'tablet_proximity tablet_tip'
|
||||
|
||||
vm-tablet_proximity_tip-no-libwacom:
|
||||
extends:
|
||||
- vm-tablet_proximity_tip
|
||||
stage: test-suite-no-libwacom
|
||||
variables:
|
||||
MESON_ARGS: '-Dlibwacom=false'
|
||||
|
||||
vm-tablet_eraser:
|
||||
extends:
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'tablet_eraser'
|
||||
|
||||
vm-tablet_eraser-no-libwacom:
|
||||
extends:
|
||||
- vm-tablet_eraser
|
||||
stage: test-suite-no-libwacom
|
||||
variables:
|
||||
MESON_ARGS: '-Dlibwacom=false'
|
||||
|
||||
vm-gestures:
|
||||
extends:
|
||||
- .fedora:42@test-suite-vm
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'gestures'
|
||||
|
||||
|
|
@ -720,7 +746,7 @@ vm-gestures-no-libwacom:
|
|||
|
||||
vm-backends:
|
||||
extends:
|
||||
- .fedora:42@test-suite-vm
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'path udev'
|
||||
|
||||
|
|
@ -733,7 +759,7 @@ vm-backends-no-libwacom:
|
|||
|
||||
vm-misc:
|
||||
extends:
|
||||
- .fedora:42@test-suite-vm
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'log misc quirks device'
|
||||
|
||||
|
|
@ -746,7 +772,7 @@ vm-misc-no-libwacom:
|
|||
|
||||
vm-other devices:
|
||||
extends:
|
||||
- .fedora:42@test-suite-vm
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'keyboard pad switch trackball trackpoint totem touch'
|
||||
|
||||
|
|
@ -759,7 +785,7 @@ vm-other devices-no-libwacom:
|
|||
|
||||
vm-pointer:
|
||||
extends:
|
||||
- .fedora:42@test-suite-vm
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'pointer'
|
||||
|
||||
|
|
@ -770,6 +796,19 @@ vm-pointer-no-libwacom:
|
|||
variables:
|
||||
MESON_ARGS: '-Dlibwacom=false'
|
||||
|
||||
vm-lua:
|
||||
extends:
|
||||
- .fedora:43@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: 'lua'
|
||||
|
||||
vm-lua-no-libwacom:
|
||||
extends:
|
||||
- vm-lua
|
||||
stage: test-suite-no-libwacom
|
||||
variables:
|
||||
MESON_ARGS: '-Dlibwacom=false'
|
||||
|
||||
|
||||
vm-valgrind-touchpad:
|
||||
stage: valgrind
|
||||
|
|
@ -888,6 +927,32 @@ vm-valgrind-tablet_left_handed:
|
|||
rules:
|
||||
- if: $GITLAB_USER_LOGIN != "marge-bot"
|
||||
|
||||
vm-valgrind-tablet_proximity_tip:
|
||||
stage: valgrind
|
||||
extends:
|
||||
- vm-tablet_proximity_tip
|
||||
- .policy-retry-on-failure
|
||||
variables:
|
||||
MESON_TEST_ARGS: '--setup=valgrind'
|
||||
LITEST_JOBS: 0
|
||||
retry:
|
||||
max: 2
|
||||
rules:
|
||||
- if: $GITLAB_USER_LOGIN != "marge-bot"
|
||||
|
||||
vm-valgrind-tablet_eraser:
|
||||
stage: valgrind
|
||||
extends:
|
||||
- vm-tablet_eraser
|
||||
- .policy-retry-on-failure
|
||||
variables:
|
||||
MESON_TEST_ARGS: '--setup=valgrind'
|
||||
LITEST_JOBS: 0
|
||||
retry:
|
||||
max: 2
|
||||
rules:
|
||||
- if: $GITLAB_USER_LOGIN != "marge-bot"
|
||||
|
||||
vm-valgrind-gestures:
|
||||
stage: valgrind
|
||||
extends:
|
||||
|
|
@ -953,18 +1018,32 @@ vm-valgrind-pointer:
|
|||
rules:
|
||||
- if: $GITLAB_USER_LOGIN != "marge-bot"
|
||||
|
||||
vm-valgrind-lua:
|
||||
stage: valgrind
|
||||
extends:
|
||||
- vm-lua
|
||||
- .policy-retry-on-failure
|
||||
variables:
|
||||
MESON_TEST_ARGS: '--setup=valgrind'
|
||||
LITEST_JOBS: 0
|
||||
retry:
|
||||
max: 2
|
||||
rules:
|
||||
- if: $GITLAB_USER_LOGIN != "marge-bot"
|
||||
|
||||
|
||||
|
||||
.fedora-build@template:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .build@template
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: '42'
|
||||
FDO_DISTRIBUTION_VERSION: '43'
|
||||
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
||||
needs:
|
||||
- "fedora:42@container-prep"
|
||||
- "fedora:43@container-prep"
|
||||
|
||||
default-build-release@fedora:42:
|
||||
default-build-release@fedora:43:
|
||||
stage: distro
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
|
|
@ -972,7 +1051,7 @@ default-build-release@fedora:42:
|
|||
MESON_ARGS: "-Dbuildtype=release"
|
||||
CFLAGS: "-Werror"
|
||||
|
||||
clang-tidy@fedora:42:
|
||||
clang-tidy@fedora:43:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
variables:
|
||||
|
|
@ -987,13 +1066,13 @@ clang-tidy@fedora:42:
|
|||
# run them on one image, they shouldn't fail on one distro
|
||||
# when they succeed on another.
|
||||
|
||||
build-no-libwacom@fedora:42:
|
||||
build-no-libwacom@fedora:43:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dlibwacom=false"
|
||||
|
||||
build-no-libwacom-nodeps@fedora:42:
|
||||
build-no-libwacom-nodeps@fedora:43:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
variables:
|
||||
|
|
@ -1001,13 +1080,13 @@ build-no-libwacom-nodeps@fedora:42:
|
|||
before_script:
|
||||
- dnf remove -y libwacom libwacom-devel
|
||||
|
||||
build-no-mtdev@fedora:42:
|
||||
build-no-mtdev@fedora:43:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dmtdev=false"
|
||||
|
||||
build-no-mtdev-nodeps@fedora:42:
|
||||
build-no-mtdev-nodeps@fedora:43:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
variables:
|
||||
|
|
@ -1015,13 +1094,27 @@ build-no-mtdev-nodeps@fedora:42:
|
|||
before_script:
|
||||
- dnf remove -y mtdev mtdev-devel
|
||||
|
||||
build-docs@fedora:42:
|
||||
build-no-lua@fedora:43:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dlua-plugins=disabled"
|
||||
|
||||
build-no-lua-nodeps@fedora:43:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dlua-plugins=disabled"
|
||||
before_script:
|
||||
- dnf remove -y lua lua-devel
|
||||
|
||||
build-docs@fedora:43:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Ddocumentation=true"
|
||||
|
||||
build-no-docs-nodeps@fedora:42:
|
||||
build-no-docs-nodeps@fedora:43:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
variables:
|
||||
|
|
@ -1029,13 +1122,13 @@ build-no-docs-nodeps@fedora:42:
|
|||
before_script:
|
||||
- dnf remove -y doxygen graphviz
|
||||
|
||||
build-no-debuggui@fedora:42:
|
||||
build-no-debuggui@fedora:43:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Ddebug-gui=false"
|
||||
|
||||
build-no-debuggui-nodeps@fedora:42:
|
||||
build-no-debuggui-nodeps@fedora:43:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
variables:
|
||||
|
|
@ -1043,13 +1136,13 @@ build-no-debuggui-nodeps@fedora:42:
|
|||
before_script:
|
||||
- dnf remove -y gtk3-devel gtk4-devel
|
||||
|
||||
build-no-tests@fedora:42:
|
||||
build-no-tests@fedora:43:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dtests=false"
|
||||
|
||||
build-no-tests-nodeps@fedora:42:
|
||||
build-no-tests-nodeps@fedora:43:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
variables:
|
||||
|
|
@ -1057,7 +1150,7 @@ build-no-tests-nodeps@fedora:42:
|
|||
before_script:
|
||||
- dnf remove -y check-devel
|
||||
|
||||
valgrind@fedora:42:
|
||||
valgrind@fedora:43:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
variables:
|
||||
|
|
@ -1065,7 +1158,7 @@ valgrind@fedora:42:
|
|||
|
||||
# Python checks, only run on Fedora
|
||||
|
||||
usr-bin-env-python@fedora:42:
|
||||
usr-bin-env-python@fedora:43:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
script:
|
||||
|
|
@ -1093,6 +1186,9 @@ check-test-suites:
|
|||
libinput-test-suite-touchpad_buttons
|
||||
libinput-test-suite-tablet
|
||||
libinput-test-suite-tablet_left_handed
|
||||
libinput-test-suite-tablet_proximity
|
||||
libinput-test-suite-tablet_tip
|
||||
libinput-test-suite-tablet_eraser
|
||||
libinput-test-suite-gestures
|
||||
libinput-test-suite-path
|
||||
libinput-test-suite-udev
|
||||
|
|
@ -1108,6 +1204,7 @@ check-test-suites:
|
|||
libinput-test-suite-totem
|
||||
libinput-test-suite-touch
|
||||
libinput-test-suite-pointer
|
||||
libinput-test-suite-lua
|
||||
EOF
|
||||
- sort -o ci-testsuites ci-testsuites
|
||||
- diff -u8 -w ci-testsuites meson-testsuites || (echo "Some test suites are not run in the CI" && false)
|
||||
|
|
@ -1172,18 +1269,6 @@ coverity:
|
|||
# #
|
||||
#################################################################
|
||||
|
||||
fedora:41@default-build:
|
||||
stage: distro
|
||||
extends:
|
||||
- .build@template
|
||||
- .fdo.distribution-image@fedora
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: '41'
|
||||
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
||||
needs:
|
||||
- "fedora:41@container-prep"
|
||||
|
||||
|
||||
fedora:42@default-build:
|
||||
stage: distro
|
||||
extends:
|
||||
|
|
@ -1196,6 +1281,18 @@ fedora:42@default-build:
|
|||
- "fedora:42@container-prep"
|
||||
|
||||
|
||||
fedora:43@default-build:
|
||||
stage: distro
|
||||
extends:
|
||||
- .build@template
|
||||
- .fdo.distribution-image@fedora
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: '43'
|
||||
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
||||
needs:
|
||||
- "fedora:43@container-prep"
|
||||
|
||||
|
||||
debian:stable@default-build:
|
||||
stage: distro
|
||||
extends:
|
||||
|
|
@ -1208,16 +1305,16 @@ debian:stable@default-build:
|
|||
- "debian:stable@container-prep"
|
||||
|
||||
|
||||
ubuntu:25.04@default-build:
|
||||
ubuntu:25.10@default-build:
|
||||
stage: distro
|
||||
extends:
|
||||
- .build@template
|
||||
- .fdo.distribution-image@ubuntu
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: '25.04'
|
||||
FDO_DISTRIBUTION_VERSION: '25.10'
|
||||
FDO_DISTRIBUTION_TAG: $UBUNTU_TAG
|
||||
needs:
|
||||
- "ubuntu:25.04@container-prep"
|
||||
- "ubuntu:25.10@container-prep"
|
||||
|
||||
|
||||
arch:rolling@default-build:
|
||||
|
|
@ -1267,27 +1364,6 @@ freebsd:14.2@default-build:
|
|||
# #
|
||||
#################################################################
|
||||
|
||||
#
|
||||
# Verify that the merge request has the allow-collaboration checkbox ticked
|
||||
#
|
||||
|
||||
check-merge-request:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
- .policy
|
||||
- .fdo-runner-tags
|
||||
stage: deploy
|
||||
script:
|
||||
- ci-fairy check-merge-request --require-allow-collaboration --junit-xml=results.xml
|
||||
artifacts:
|
||||
when: on_failure
|
||||
reports:
|
||||
junit: results.xml
|
||||
allow_failure: true
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
|
||||
|
||||
|
||||
build rpm:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
|
|
@ -1295,10 +1371,10 @@ build rpm:
|
|||
- .fdo-runner-tags
|
||||
stage: deploy
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: '42'
|
||||
FDO_DISTRIBUTION_VERSION: '43'
|
||||
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
||||
needs:
|
||||
- "fedora:42@container-prep"
|
||||
- "fedora:43@container-prep"
|
||||
script:
|
||||
- meson "$MESON_BUILDDIR"
|
||||
- VERSION=$(meson introspect "$MESON_BUILDDIR" --projectinfo | jq -r .version)
|
||||
|
|
@ -1316,14 +1392,12 @@ build rpm:
|
|||
wayland-web:
|
||||
stage: deploy
|
||||
trigger: wayland/wayland.freedesktop.org
|
||||
except:
|
||||
refs:
|
||||
- schedules
|
||||
variables:
|
||||
MESON_ARGS: '-Ddocumentation=true -Ddebug-gui=false -Dlibwacom=false -Dtests=false'
|
||||
MESON_BUILDDIR: 'builddir'
|
||||
only:
|
||||
refs:
|
||||
- main
|
||||
variables:
|
||||
- $CI_PROJECT_PATH == "libinput/libinput"
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
||||
when: never
|
||||
- if: '$CI_COMMIT_BRANCH == "main" && $GITLAB_USER_LOGIN != "marge-bot" && $CI_PROJECT_PATH == $FDO_UPSTREAM_REPO'
|
||||
when: on_success
|
||||
- when: never
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ pre-commit-hooks:
|
|||
- python3 -m venv venv
|
||||
- source venv/bin/activate
|
||||
- pip3 install pre-commit
|
||||
- pre-commit run --all-files || true
|
||||
- pre-commit run --all-files
|
||||
- git diff --exit-code || (echo "ERROR - Code style errors found, please fix" && false)
|
||||
|
||||
#################################################################
|
||||
|
|
@ -492,6 +492,7 @@ vm-valgrind-{{suite.name}}:
|
|||
- if: $GITLAB_USER_LOGIN != "marge-bot"
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}{# for if distro.use_for_qemu_tests #}
|
||||
|
||||
{% for distro in distributions if distro.use_for_custom_build_tests %}
|
||||
|
|
@ -557,6 +558,20 @@ build-no-mtdev-nodeps@{{distro.name}}:{{version}}:
|
|||
before_script:
|
||||
- dnf remove -y mtdev mtdev-devel
|
||||
|
||||
build-no-lua@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dlua-plugins=disabled"
|
||||
|
||||
build-no-lua-nodeps@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dlua-plugins=disabled"
|
||||
before_script:
|
||||
- dnf remove -y lua lua-devel
|
||||
|
||||
build-docs@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
|
|
@ -746,27 +761,6 @@ coverity:
|
|||
# #
|
||||
#################################################################
|
||||
|
||||
#
|
||||
# Verify that the merge request has the allow-collaboration checkbox ticked
|
||||
#
|
||||
|
||||
check-merge-request:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
- .policy
|
||||
- .fdo-runner-tags
|
||||
stage: deploy
|
||||
script:
|
||||
- ci-fairy check-merge-request --require-allow-collaboration --junit-xml=results.xml
|
||||
artifacts:
|
||||
when: on_failure
|
||||
reports:
|
||||
junit: results.xml
|
||||
allow_failure: true
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
|
||||
|
||||
|
||||
{% for distro in distributions if distro.name == "fedora" %}
|
||||
{% set version = "{}".format(distro.versions|last()) %}
|
||||
build rpm:
|
||||
|
|
@ -798,14 +792,12 @@ build rpm:
|
|||
wayland-web:
|
||||
stage: deploy
|
||||
trigger: wayland/wayland.freedesktop.org
|
||||
except:
|
||||
refs:
|
||||
- schedules
|
||||
variables:
|
||||
MESON_ARGS: '-Ddocumentation=true -Ddebug-gui=false -Dlibwacom=false -Dtests=false'
|
||||
MESON_BUILDDIR: 'builddir'
|
||||
only:
|
||||
refs:
|
||||
- main
|
||||
variables:
|
||||
- $CI_PROJECT_PATH == "libinput/libinput"
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
||||
when: never
|
||||
- if: '$CI_COMMIT_BRANCH == "main" && $GITLAB_USER_LOGIN != "marge-bot" && $CI_PROJECT_PATH == $FDO_UPSTREAM_REPO'
|
||||
when: on_success
|
||||
- when: never
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@
|
|||
#
|
||||
|
||||
# We're happy to rebuild all containers when one changes.
|
||||
.default_tag: &default_tag '2025-05-19.0'
|
||||
.default_tag: &default_tag '2025-11-17.0'
|
||||
|
||||
distributions:
|
||||
- name: fedora
|
||||
tag: *default_tag
|
||||
versions:
|
||||
- '41'
|
||||
- '42'
|
||||
- '43'
|
||||
use_for_custom_build_tests: true
|
||||
use_for_qemu_tests: true
|
||||
packages:
|
||||
|
|
@ -50,6 +50,7 @@ distributions:
|
|||
- python3-click
|
||||
- python3-rich
|
||||
- virtme-ng
|
||||
- lua-devel
|
||||
- name: debian
|
||||
tag: *default_tag
|
||||
versions:
|
||||
|
|
@ -75,10 +76,11 @@ distributions:
|
|||
- libglib2.0-dev
|
||||
- libmtdev-dev
|
||||
- curl # for the coverity job
|
||||
- lua5.4-dev
|
||||
- name: ubuntu
|
||||
tag: *default_tag
|
||||
versions:
|
||||
- '25.04'
|
||||
- '25.10'
|
||||
packages:
|
||||
- git
|
||||
- gcc
|
||||
|
|
@ -99,6 +101,7 @@ distributions:
|
|||
- libgtk-3-dev
|
||||
- libglib2.0-dev
|
||||
- libmtdev-dev
|
||||
- lua5.4-dev
|
||||
- name: arch
|
||||
tag: *default_tag
|
||||
versions:
|
||||
|
|
@ -116,6 +119,7 @@ distributions:
|
|||
- gtk4
|
||||
- mtdev
|
||||
- diffutils
|
||||
- lua
|
||||
build:
|
||||
extra_variables:
|
||||
- "MESON_ARGS: '-Ddocumentation=false'" # python-recommonmark is no longer in the repos
|
||||
|
|
@ -136,6 +140,7 @@ distributions:
|
|||
- gtk4.0-dev
|
||||
- mtdev-dev
|
||||
- bash
|
||||
- lua5.4-dev
|
||||
build:
|
||||
extra_variables:
|
||||
- "MESON_ARGS: '-Ddocumentation=false' # alpine does not have python-recommonmark"
|
||||
|
|
@ -195,6 +200,13 @@ test_suites:
|
|||
- name: tablet_left_handed
|
||||
suites:
|
||||
- tablet_left_handed
|
||||
- name: tablet_proximity_tip
|
||||
suites:
|
||||
- tablet_proximity
|
||||
- tablet_tip
|
||||
- name: tablet_eraser
|
||||
suites:
|
||||
- tablet_eraser
|
||||
- name: gestures
|
||||
suites:
|
||||
- gestures
|
||||
|
|
@ -220,6 +232,9 @@ test_suites:
|
|||
- name: pointer
|
||||
suites:
|
||||
- pointer
|
||||
- name: lua
|
||||
suites:
|
||||
- lua
|
||||
|
||||
vng:
|
||||
kernel: https://gitlab.freedesktop.org/api/v4/projects/libevdev%2Fhid-tools/packages/generic/kernel-x86_64/v6.14/bzImage
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ intended to be run by users.
|
|||
%files utils
|
||||
%{_libexecdir}/libinput/libinput-debug-gui
|
||||
%{_libexecdir}/libinput/libinput-debug-tablet
|
||||
%{_libexecdir}/libinput/libinput-debug-tablet-pad
|
||||
%{_libexecdir}/libinput/libinput-list-kernel-devices
|
||||
%{_libexecdir}/libinput/libinput-measure
|
||||
%{_libexecdir}/libinput/libinput-measure-fuzz
|
||||
|
|
@ -117,6 +118,7 @@ intended to be run by users.
|
|||
%{_libexecdir}/libinput/libinput-analyze-touch-down-state
|
||||
%{_mandir}/man1/libinput-debug-gui.1*
|
||||
%{_mandir}/man1/libinput-debug-tablet.1*
|
||||
%{_mandir}/man1/libinput-debug-tablet-pad.1*
|
||||
%{_mandir}/man1/libinput-list-kernel-devices.1*
|
||||
%{_mandir}/man1/libinput-measure.1*
|
||||
%{_mandir}/man1/libinput-measure-fuzz.1*
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ repos:
|
|||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.12.2
|
||||
hooks:
|
||||
- id: ruff
|
||||
- id: ruff-check
|
||||
args: ['--ignore=E741,E501', '--extend-exclude=subprojects', '.']
|
||||
- id: ruff-format
|
||||
args: ['--check', '--diff']
|
||||
|
|
|
|||
|
|
@ -183,6 +183,16 @@ resource_rules:
|
|||
For a detailed explanation on the how and why of this process please see
|
||||
the [Closed Issues wiki page](https://gitlab.freedesktop.org/libinput/libinput/-/wikis/Closed-Issues).
|
||||
status: "close"
|
||||
- name: "Re-close bug for reopening"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::re-close"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::re-close"
|
||||
comment: |
|
||||
I'm temporarily closing this bug again. This is not a final close, see my comments above for the open/close process.
|
||||
status: "close"
|
||||
- *udev_hid_bpf
|
||||
- *libinput_record
|
||||
- *hid_recorder
|
||||
|
|
|
|||
|
|
@ -93,6 +93,9 @@ __all_seats()
|
|||
+ '(natural-scrolling)' \
|
||||
'--enable-natural-scrolling[Enable natural scrolling]' \
|
||||
'--disable-natural-scrolling[Disable natural scrolling]' \
|
||||
+ '(plugins)' \
|
||||
'--enable-plugins[Enable plugins]' \
|
||||
'--disable-plugins[Disable plugins]' \
|
||||
+ '(tap-to-click)' \
|
||||
'--enable-tap[Enable tap-to-click]' \
|
||||
'--disable-tap[Disable tap-to-click]'
|
||||
|
|
|
|||
|
|
@ -40,11 +40,6 @@ To fix the touchpad you need to:
|
|||
|
||||
Detailed explanations are below.
|
||||
|
||||
.. note:: ``libinput measure touchpad-size`` was introduced in libinput
|
||||
1.16. For earlier versions, use `libevdev <http://freedesktop.org/wiki/Software/libevdev/>`_'s
|
||||
``touchpad-edge-detector`` tool.
|
||||
|
||||
|
||||
The ``libinput measure touchpad-size`` tool is an interactive tool. It must
|
||||
be called with the physical dimensions of the touchpad in mm. In the example
|
||||
below, we use 100mm wide and 55mm high. The tool will find the touchpad device
|
||||
|
|
|
|||
|
|
@ -6,15 +6,21 @@ Configuration options
|
|||
|
||||
Below is a list of configurable options exposed to the users.
|
||||
|
||||
.. contents::
|
||||
:depth: 1
|
||||
:local:
|
||||
|
||||
|
||||
.. hint:: Not all configuration options are available on all devices. Use
|
||||
:ref:`libinput list-devices <libinput-list-devices>` to show the
|
||||
configuration options for local devices.
|
||||
|
||||
libinput's configuration interface is available to the caller only, not
|
||||
directly to the user. Thus is is the responsibility of the caller to expose
|
||||
directly to the user. Thus it is the responsibility of the caller to expose
|
||||
the various options and how these options are exposed. For example, the
|
||||
xf86-input-libinput driver exposes the options through X Input device
|
||||
properties and xorg.conf.d options. See the `libinput(4)
|
||||
`xf86-input-libinput driver <https://gitlab.freedesktop.org/xorg/driver/xf86-input-libinput/>`_
|
||||
exposes the options through X Input device properties and `xorg.conf.d
|
||||
<https://linux.die.net/man/5/xorg.conf.d>`_ options. See the `libinput(4)
|
||||
<https://www.mankier.com/4/libinput>`_ man page for more details.
|
||||
|
||||
|
||||
|
|
@ -205,6 +211,18 @@ before the maximum hardware-supported pressure is reached.
|
|||
|
||||
See :ref:`tablet-pressure-range` for more info.
|
||||
|
||||
.. _config-tablet-eraser-buttons:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Tablet tool eraser buttons
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
On many contemporary :ref:`Tablet tools <tablet-tools>` one button is hardcoded
|
||||
in firmware to emulate an eraser. This button can be remapped to provide
|
||||
a normal stylus button instead.
|
||||
|
||||
See :ref:`tablet-eraser-button` for more info.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Area configuration
|
||||
------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ sufficient to make some of the more confusing steps obvious.
|
|||
with your username). git will call this repository ``gitlab``. ::
|
||||
|
||||
cd /path/to/libinput.git
|
||||
git remote add gitlab git@gitlab.freedesktop.org:USERNAME/libinput.git
|
||||
git remote add gitlab git@ssh.gitlab.freedesktop.org:USERNAME/libinput.git
|
||||
git fetch gitlab
|
||||
|
||||
- Create a new branch and commit your changes to that branch. ::
|
||||
|
|
|
|||
|
|
@ -148,6 +148,9 @@ ModelBouncingKeys
|
|||
ModelSynapticsSerialTouchpad
|
||||
Reserved for touchpads made by Synaptics on the serial bus
|
||||
ModelPressurePad
|
||||
.. warning:: This quirk is no longer in use. Use
|
||||
``AttrInputProp=+INPUT_PROP_PRESSUREPAD`` instead.
|
||||
|
||||
Unlike in traditional touchpads, whose pressure value equals contact size,
|
||||
on pressure pads pressure is a real physical axis.
|
||||
Indicates that the device is a pressure pad.
|
||||
|
|
@ -155,6 +158,10 @@ ModelTouchpadPhantomClicks
|
|||
Some laptops are prone to registering touchpad clicks when the case is
|
||||
bent. Indicates that clicks should be ignored if no fingers are on the
|
||||
touchpad.
|
||||
ModelScrollOnMiddleClick
|
||||
Some mice can generate unwanted high-resolution scroll events when the wheel
|
||||
is pressed. Increases the scroll threshold required to start scrolling to
|
||||
avoid accidentally scrolling when middle clicking.
|
||||
AttrSizeHint=NxM, AttrResolutionHint=N
|
||||
Hints at the width x height of the device in mm, or the resolution
|
||||
of the x/y axis in units/mm. These may only be used where they apply to
|
||||
|
|
@ -195,6 +202,9 @@ AttrInputProp=+INPUT_PROP_BUTTONPAD;-INPUT_PROP_POINTER;
|
|||
Enables or disables the evdev input property on the device. The prefix
|
||||
for each entry is either '+' (enable) or '-' (disable). Entries may be
|
||||
a named input property or the hexadecimal value of that property.
|
||||
|
||||
The most common use of this is ``AttrInputProp=+INPUT_PROP_PRESSUREPAD``
|
||||
which marks a touchpad as a :ref:`forcepad or pressurepad <touchpads_buttons_forcepads>`.
|
||||
AttrPointingStickIntegration=internal|external
|
||||
Indicates the integration of the pointing stick. This is a string enum.
|
||||
Only needed for external pointing sticks. These are rare.
|
||||
|
|
|
|||
36
doc/user/dot/libinput-contexts.gv
Normal file
36
doc/user/dot/libinput-contexts.gv
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
digraph stack
|
||||
{
|
||||
compound=true;
|
||||
splines=line;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
subgraph cluster_2 {
|
||||
label="Kernel";
|
||||
event0 [label="/dev/input/event0"];
|
||||
event1 [label="/dev/input/event1"];
|
||||
}
|
||||
|
||||
subgraph cluster_0 {
|
||||
label="Compositor process";
|
||||
libinput [label="libinput context 1"];
|
||||
}
|
||||
|
||||
subgraph cluster_1 {
|
||||
label="libinput debug-events";
|
||||
libinput2 [label="libinput context 2"];
|
||||
}
|
||||
|
||||
stdout;
|
||||
|
||||
client [label="Wayland client"];
|
||||
|
||||
event0:e -> libinput:w;
|
||||
event1:e -> libinput:w;
|
||||
event0:e -> libinput2:w;
|
||||
event1:e -> libinput2:w;
|
||||
libinput -> client [ltail=cluster_0 label="Wayland protocol"];
|
||||
libinput2 -> stdout [ltail=cluster_1];
|
||||
}
|
||||
31
doc/user/dot/plugin-stack.gv
Normal file
31
doc/user/dot/plugin-stack.gv
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
digraph stack
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
subgraph cluster_2 {
|
||||
label="Kernel";
|
||||
event0 [label="/dev/input/event0"]
|
||||
}
|
||||
|
||||
subgraph cluster_1 {
|
||||
label="libinput";
|
||||
subgraph cluster_0 {
|
||||
label="Plugin pipeline";
|
||||
p1 [label="00-foo.lua"];
|
||||
p2 [label="10-bar.lua"];
|
||||
}
|
||||
libinput [label="libinput core"];
|
||||
}
|
||||
|
||||
|
||||
compositor [label="Compositor"];
|
||||
|
||||
event0 -> p1;
|
||||
p1 -> p2;
|
||||
p2 -> libinput;
|
||||
libinput -> compositor [ltail=cluster_1 label="libinput API"];
|
||||
}
|
||||
|
|
@ -348,10 +348,14 @@ compositor. This indicates a misunderstanding of how libinput works:
|
|||
libinput is a library that converts kernel events into libinput events, much
|
||||
like ``sed`` reads data in, modifies it, and provides it to stdout.
|
||||
|
||||
If ``sed`` is used by a shell-script, that script has full control over how
|
||||
``sed`` processes data. In this analogy, ``sed`` is libinput and the
|
||||
shell script is the compositor. It is not possible to write a program
|
||||
to modify the behavior of the ``sed`` instance used inside that shell script
|
||||
.. graphviz:: libinput-contexts.gv
|
||||
|
||||
A libinput context is private to the process and cannot be modified from the
|
||||
outside. To use the ``sed`` analogy again: if ``sed`` is used by a
|
||||
shell-script, that script has full control over how ``sed`` processes data. In
|
||||
this analogy, ``sed`` is libinput and the shell script is the compositor. It is
|
||||
not possible to write a program to modify the behavior of the ``sed`` instance
|
||||
used inside that shell script.
|
||||
|
||||
Writing a program that uses libinput is akin to writing a new script that
|
||||
invoke ``sed``. It will not have any effect on the original ``sed`` instance.
|
||||
|
|
@ -360,6 +364,14 @@ The only way to modify libinput's behavior is to use the configuration options
|
|||
exposed by the respective compositor. Those affect the libinput context inside
|
||||
the compositor and thus have an effect on the input device behavior.
|
||||
|
||||
.. _faq_debug_events_not_showing_configuration:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Why doesn't libinput debug-events show my configuration
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
See :ref:`faq_separate_contexts`.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Can I configure scroll speed?
|
||||
------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
troubleshooting
|
||||
contributing
|
||||
development
|
||||
lua-plugins
|
||||
API documentation <@HTTP_DOC_LINK@/api/>
|
||||
|
||||
|
||||
|
|
|
|||
661
doc/user/lua-plugins.rst
Normal file
661
doc/user/lua-plugins.rst
Normal file
|
|
@ -0,0 +1,661 @@
|
|||
.. _lua_plugins:
|
||||
|
||||
==============================================================================
|
||||
Lua Plugins
|
||||
==============================================================================
|
||||
|
||||
libinput provides a plugin system that allows users to modify the behavior
|
||||
of devices. For example, a plugin may add or remove axes and/or buttons on a
|
||||
device and/or modify the event stream seen by this device before it is passed
|
||||
to libinput.
|
||||
|
||||
Plugins are implemented in `Lua <https://www.lua.org/>`_ (version 5.4)
|
||||
and are typically loaded from the following paths:
|
||||
|
||||
- ``/etc/libinput/plugins/*.lua``, and
|
||||
- ``/usr/lib{64}/libinput/plugins/*.lua``
|
||||
|
||||
Plugins are loaded in alphabetical order and where
|
||||
multiple plugins share the same file name, the one in the highest precedence
|
||||
directory is used. Plugins in ``/etc`` take precedence over
|
||||
plugins in ``/usr``.
|
||||
|
||||
.. note:: Plugins lookup paths and their order are decided by the compositor.
|
||||
Some compositors may support more/fewer/other lookup paths than the
|
||||
above defaults.
|
||||
|
||||
Plugins are run sequentially in ascending sort-order (i.e. ``00-foo.lua`` runs
|
||||
before ``10-bar.lua``) and each plugin sees the state left by any previous
|
||||
plugins. For example if ``00-foo.lua`` changes all left button events to right
|
||||
button events, ``10-bar.lua`` only ever sees right button events.
|
||||
|
||||
See the `Lua Reference manual <https://www.lua.org/manual/5.4/manual.html>`_ for
|
||||
details on the Lua language.
|
||||
|
||||
.. note:: Plugins are **not** loaded by default, it is up to the compositor
|
||||
whether to allow plugins. An explicit call to
|
||||
``libinput_plugin_system_load_plugins()`` is required.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Limitations
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Each script runs in its own sandbox and cannot communicate or share state with
|
||||
other scripts.
|
||||
|
||||
Tables that hold API methods are not writable, i.e. it is not possible
|
||||
to overwrite the default functionality of those APIs.
|
||||
|
||||
The Lua API available to plugins is limited to the following calls::
|
||||
|
||||
assert error ipairs next pairs tonumber
|
||||
pcall select print tostring type xpcall
|
||||
table string math _VERSION
|
||||
|
||||
It is not possible to e.g. use the ``io`` module from a script.
|
||||
|
||||
To use methods on instantiated objects, the ``object:method`` method call
|
||||
syntax must be used. For example:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
libinput:register()
|
||||
libinput.register() -- this will fail
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
When to use plugins
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
libinput plugins are a relatively niche use-case that typically need to
|
||||
address either once-off issues (e.g. those caused by worn-out hardware) or
|
||||
user preferences that libinput does not and will not cater for.
|
||||
|
||||
Plugins should not be used for issues that can be fixed generically, for
|
||||
example via :ref:`device-quirks`.
|
||||
|
||||
As a rule of thumb: a plugin should be a once-off that only works for one
|
||||
user's hardware. If a plugin can be shared with many users then the plugin
|
||||
implements functionality that should be integrated into libinput proper.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Testing plugins
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Our :ref:`tools` support plugins if passed the ``--enable-plugins`` commandline
|
||||
option. For implementing and testing plugins the easiest commands to test are
|
||||
|
||||
- ``libinput debug-events --enable-plugins`` (see :ref:`libinput-debug-events` docs)
|
||||
- ``libinput debug-gui --enable-plugins`` (see :ref:`libinput-debug-gui` docs)
|
||||
|
||||
Where libinput is built and run from git, the tools will also look for plugins
|
||||
in the meson build directory. See the ``plugins/meson.build`` file for details.
|
||||
|
||||
.. _plugins_api_lua:
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Lua Plugin API
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Lua plugins sit effectively below libinput and the API is not a
|
||||
representation of the libinput API. Plugins modify the evdev event stream
|
||||
received from the kernel.
|
||||
|
||||
.. graphviz:: plugin-stack.gv
|
||||
|
||||
The API revolves around two types: ``libinput`` and ``EvdevDevice``. The
|
||||
``libinput`` type is used to register a plugin from a script, the
|
||||
``EvdevDevice`` represents one device that is present in the system (but may
|
||||
not have yet been added by libinput).
|
||||
|
||||
Typically a script does the following steps:
|
||||
|
||||
- register with libinput via ``libinput:register({versions})``
|
||||
- connect to the ``"new-evdev-device"`` event
|
||||
- receive an ``EvdevDevice`` object in the ``"new-evdev-device"`` callback
|
||||
|
||||
- check and/or modify the evdev event codes on the device
|
||||
- connect to the device's ``"evdev-frame"`` event
|
||||
|
||||
- receive an :ref:`evdev frame <plugins_api_evdev_frame>` in the device's
|
||||
``"evdev-frame"`` callback
|
||||
|
||||
- check and/or modify the events in that frame
|
||||
|
||||
Where multiple plugins are active, the evdev frame passed to the callback is
|
||||
the combined frame as processed by all previous plugins in ascending sort order.
|
||||
For example, if one plugin discards all button events subsequent plugins will
|
||||
never see those button events in the frame.
|
||||
|
||||
.. _plugins_api_version_stability:
|
||||
|
||||
..............................................................................
|
||||
Plugin version stability
|
||||
..............................................................................
|
||||
|
||||
Plugin API version stability is provided on a best effort basis. We aim to provide
|
||||
stable plugin versions for as long as feasible but may need to retire some older
|
||||
versions over time. For this reason a plugin can select multiple versions it
|
||||
implements, libinput will pick one supported version and adjust the plugin
|
||||
behavior to match that version. See the ``libinput:register()`` call for details.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Lua Plugin API Reference
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
libinput provides the following globals and types:
|
||||
|
||||
.. _plugins_api_evdev_usage:
|
||||
|
||||
................................................................................
|
||||
Evdev Usages
|
||||
................................................................................
|
||||
|
||||
Evdev usages are a libinput-specific wrapper around the ``linux/input-event-codes.h``
|
||||
evdev types and codes. They are used by libinput internally and are a 32-bit
|
||||
combination of ``type << 16 | code``. Each usage carries the type and code and
|
||||
is thus simpler to pass around and less prone to type confusion.
|
||||
|
||||
The :ref:`evdev global <plugins_api_evdev_global>` attempts to provide all
|
||||
available usages but for the niche cases where it does not provide a named constant
|
||||
the value can be crafted manually:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
evdev_type = 0x3 -- EV_REL
|
||||
evdev_code = 0x1 -- REL_Y
|
||||
evdev_usage = (evdev_type << 16) | evdev_code
|
||||
|
||||
assert(usage == evdev.REL_Y)
|
||||
|
||||
.. _plugins_api_evdev_global:
|
||||
|
||||
................................................................................
|
||||
The ``evdev`` global
|
||||
................................................................................
|
||||
|
||||
The ``evdev`` global represents all known :ref:`plugins_api_evdev_usage`,
|
||||
effectively in the form:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
evdev = {
|
||||
ABS_X = (3 << 16) | 0,
|
||||
ABS_Y = (3 << 16) | 1,
|
||||
...
|
||||
REL_X = (2 << 16) | 0,
|
||||
REL_Y = (2 << 16) | 1,
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
This global is provided for convenience to improve readability in the code.
|
||||
Note that the name uses the event code name only (e.g. ``evdev.ABS_Y``) but the
|
||||
value is an :ref:`Evdev Usage <plugins_api_evdev_usage>` (type and code).
|
||||
|
||||
See the ``linux/input-event-codes.h`` header file provided by your kernel
|
||||
for a list of all evdev types and codes.
|
||||
|
||||
The evdev global also provides the bus type constants, e.g. ``evdev.BUS_USB``.
|
||||
See the ``linux/input.h`` header file provided by your kernel
|
||||
for a list of bus types.
|
||||
|
||||
|
||||
.. _plugins_api_evdev_frame:
|
||||
|
||||
................................................................................
|
||||
Evdev frames
|
||||
................................................................................
|
||||
|
||||
Evdev frames represent a single frame of evdev events for a device. A frame
|
||||
is a group of events that occurred at the same time. The frame usually only
|
||||
contains state that has changed compared to the previous frame.
|
||||
|
||||
In our API a frame is exposed as a nested table with the following structure:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
frame1 = {
|
||||
{ usage = evdev.ABS_X, value = 123 },
|
||||
{ usage = evdev.ABS_Y, value = 456 },
|
||||
{ usage = evdev.BTN_LEFT, value = 1 },
|
||||
}
|
||||
frame2 = {
|
||||
{ usage = evdev.ABS_Y, value = 457 },
|
||||
}
|
||||
frame3 = {
|
||||
{ usage = evdev.ABS_X, value = 124 },
|
||||
{ usage = evdev.BTN_LEFT, value = 0 },
|
||||
}
|
||||
|
||||
.. note:: This API does not use ``SYN_REPORT`` events, it is implied at the
|
||||
end of the table. Where a plugin writes a ``SYN_REPORT`` into the
|
||||
list of events, that ``SYN_REPORT`` terminates the event frame
|
||||
(similar to writing a ``\0`` into the middle of a C string).
|
||||
A frame containing only a ``SYN_REPORT`` is functionally equivalent
|
||||
to an empty frame.
|
||||
|
||||
Events or frames do not have a timestamp. Where a timestamp is required, that
|
||||
timestamp is passed as additional argument to the function or return value.
|
||||
|
||||
See :ref:`plugins_api_evdev_global` for a list of known usages.
|
||||
|
||||
.. warning:: Evdev frames have an implementation-defined size limit of how many
|
||||
events can be added to a single frame. This limit should never be
|
||||
hit by valid plugins.
|
||||
|
||||
.. _plugins_api_libinputglobal:
|
||||
|
||||
................................................................................
|
||||
The ``libinput`` global object
|
||||
................................................................................
|
||||
|
||||
The core of our plugin API is the ``libinput`` global object. A script must
|
||||
immediately ``register()`` to be active, otherwise it is unloaded immediately.
|
||||
|
||||
All libinput-specific APIs can be accessed through the ``libinput`` object.
|
||||
|
||||
.. function:: libinput:register({1, 2, ...})
|
||||
|
||||
Register this plugin with the given table of supported version numbers and
|
||||
returns the version number selected by libinput for this plugin. See
|
||||
:ref:`plugins_api_version_stability` for details.
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
-- this plugin can support versions 1, 4 and 5
|
||||
version = libinput:register({1, 4, 5})
|
||||
if version == 1 then
|
||||
...
|
||||
|
||||
This function must be the first function called.
|
||||
If the plugin calls any other functions before ``register()``, those functions
|
||||
return the default zero value for the return type (``nil``, ``0``, an empty
|
||||
table, etc.).
|
||||
|
||||
If the plugin does not call ``register()`` it will be removed immediately.
|
||||
Once registered, any connected callbacks will be invoked whenever libinput
|
||||
detects new devices, removes devices, etc.
|
||||
|
||||
This function must only be called once.
|
||||
|
||||
.. function:: libinput:unregister()
|
||||
|
||||
Unregister this plugin. This removes the plugin from libinput and releases
|
||||
any resources associated with this plugin. This call must be the last call
|
||||
in your plugin, it is effectively equivalent to Lua's
|
||||
`os.exit() <https://www.lua.org/manual/5.4/manual.html#pdf-os.exit>`_.
|
||||
|
||||
.. function:: libinput:log_debug(message)
|
||||
|
||||
Log a message at the libinput debug log priority. See
|
||||
``libinput:log_error()`` for details.
|
||||
|
||||
.. function:: libinput:log_info(message)
|
||||
|
||||
Log a message at the libinput info log priority. See
|
||||
``libinput:log_error()`` for details.
|
||||
|
||||
.. function:: libinput:log_error(message)
|
||||
|
||||
Log a message at the libinput error log priority. Whether a message is
|
||||
displayed in the log depends on libinput's log priority, set by the caller.
|
||||
|
||||
A compositor may disable stdout and stderr. Log messages should be preferred
|
||||
over Lua's ``print()`` function to ensure the messages end up in the same
|
||||
location as other libinput log messages and are not discarded.
|
||||
|
||||
.. function:: libinput:now()
|
||||
|
||||
Returns the current time in microseconds in ``CLOCK_MONOTONIC``. This is
|
||||
the timestamp libinput uses internally. This timestamp cannot be mapped
|
||||
to any particular time of day, see the
|
||||
`clock_gettime() man page <https://man7.org/linux/man-pages/man3/clock_gettime.3.html>`_
|
||||
for details.
|
||||
|
||||
.. function:: libinput:version()
|
||||
|
||||
Returns the agreed-on version of the plugin, see ``libinput:register()``.
|
||||
If called before ``libinput:register()`` this function returns ``0``.
|
||||
|
||||
.. function:: libinput:connect(name, function)
|
||||
|
||||
Set the callback to the given event name. Only one callback
|
||||
may be set for an event name at any time, subsequent callbacks
|
||||
will replace any earlier callbacks for the same name.
|
||||
|
||||
Version 1 of the plugin API supports the following events and callback arguments:
|
||||
|
||||
- ``"new-evdev-device"``: A new :ref:`EvdevDevice <plugins_api_evdevdevice>`
|
||||
has been seen by libinput but not yet added.
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
libinput:connect("new-evdev-device", function (device) ... end)
|
||||
|
||||
- ``"timer-expired"``: The timer for this plugin has expired. This event is
|
||||
only sent if the plugin has set a timer with ``timer_set()``.
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
libinput:connect("timer-expired", function (now) ... end)
|
||||
|
||||
The ``now`` argument is the current time in microseconds in
|
||||
``CLOCK_MONOTONIC`` (see ``libinput:now()``).
|
||||
|
||||
.. function:: libinput:timer_cancel()
|
||||
|
||||
Cancel the timer for this plugin. This is a no-op if the timer
|
||||
has not been set or has already expired.
|
||||
|
||||
.. function:: libinput:timer_set_absolute(time)
|
||||
|
||||
Set a timer for this plugin, with the given time in microseconds.
|
||||
The timeout specifies an absolute time in microseconds (see
|
||||
``libinput:now()``) The timer will expire once and then call the
|
||||
``"timer-expired"`` event handler (if any).
|
||||
|
||||
See ``libinput:timer_set_relative()`` for a relative timer.
|
||||
|
||||
The following two lines of code are equivalent:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
libinput:timer_set_relative(1000000) -- 1 second from now
|
||||
libinput:timer_set_absolute(libinput:now() + 1000000) -- 1 second from now
|
||||
|
||||
Calling this function will cancel any existing (relative or absolute) timer.
|
||||
|
||||
.. function:: libinput:timer_set_relative(timeout)
|
||||
|
||||
Set a timer for this plugin, with the given timeout in microseconds from
|
||||
the current time. The timer will expire once and then call the
|
||||
``"timer-expired"`` event handler (if any).
|
||||
|
||||
See ``libinput:timer_set_absolute()`` for an absolute timer.
|
||||
|
||||
The following two lines of code are equivalent:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
libinput:timer_set_relative(1000000) -- 1 second from now
|
||||
libinput:timer_set_absolute(libinput:now() + 1000000) -- 1 second from now
|
||||
|
||||
Calling this function will cancel any existing (relative or absolute) timer.
|
||||
|
||||
.. _plugins_api_evdevdevice:
|
||||
|
||||
................................................................................
|
||||
The ``EvdevDevice`` type
|
||||
................................................................................
|
||||
|
||||
The ``EvdevDevice`` type represents a device available in the system
|
||||
but not (yet) added by libinput. This device may be used to modify
|
||||
a device's capabilities before the device is processed by libinput.
|
||||
|
||||
A plugin should always ``connect()`` to the ``"device-removed"`` callback
|
||||
to be notified when a device is removed. If the plugin keeps a reference
|
||||
to this device but the device is discarded by libinput, the device's query
|
||||
methods will return zero values (e.g. ``nil``, ``0``, an empty table) and
|
||||
methods will be noops.
|
||||
|
||||
.. function:: EvdevDevice:info()
|
||||
|
||||
A table containing static information about the device, e.g.
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
{
|
||||
bustype = evdev.BUS_USB,
|
||||
vid = 0x1234,
|
||||
pid = 0x5678,
|
||||
}
|
||||
|
||||
A plugin must ignore keys it does not know about.
|
||||
|
||||
Version 1 of the plugin API supports the following keys and values:
|
||||
|
||||
- ``bustype``: The numeric bustype of the device. See the
|
||||
``BUS_*`` defines in ``linux/input.h`` for the list of possible values.
|
||||
- ``vid``: The 16-bit vendor ID of the device
|
||||
- ``pid``: The 16-bit product ID of the device
|
||||
|
||||
If the device has since been discarded by libinput, this function returns an
|
||||
empty table.
|
||||
|
||||
.. function:: EvdevDevice:name()
|
||||
|
||||
The device name as set by the kernel
|
||||
|
||||
.. function:: EvdevDevice:usages()
|
||||
|
||||
Returns a table of all usages that are currently enabled for this
|
||||
device. Any type that exists on the device has a table assigned and in this
|
||||
table any code that exists on the device is a boolean true.
|
||||
For example:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
{
|
||||
evdev.REL_X = true,
|
||||
evdev.REL_Y = true,
|
||||
evdev.BTN_LEFT = true,
|
||||
}
|
||||
|
||||
All other usages are ``nil``, so that the following code is possible:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
local usages = device:usages()
|
||||
if usages[evdev.REL_X] then
|
||||
-- do something
|
||||
end
|
||||
|
||||
|
||||
If the device has since been discarded by libinput, this function returns an
|
||||
empty table.
|
||||
|
||||
.. function:: EvdevDevice:absinfos()
|
||||
|
||||
Returns a table of all ``EV_ABS`` codes that are currently enabled for this device.
|
||||
The event code is the key, each value is a table containing the following keys:
|
||||
``minimum``, ``maximum``, ``fuzz``, ``flat``, ``resolution``.
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
{
|
||||
evdev.ABS_X = {
|
||||
minimum = 0,
|
||||
maximum = 1234,
|
||||
fuzz = 0,
|
||||
flat = 0,
|
||||
resolution = 45,
|
||||
},
|
||||
}
|
||||
|
||||
If the device has since been discarded by libinput, this function returns an
|
||||
empty table.
|
||||
|
||||
.. function:: EvdevDevice:udev_properties()
|
||||
|
||||
Returns a table containing a filtered list of udev properties available on this device
|
||||
in the form ``{ property_name = property_value, ... }``.
|
||||
udev properties used as a boolean (e.g. ``ID_INPUT``) are only present if their
|
||||
value is a logical true.
|
||||
|
||||
Version 1 of the plugin API supports the following udev properties:
|
||||
|
||||
- ``ID_INPUT`` and all of ``ID_INPUT_*`` that denote the device type as assigned
|
||||
by udev. This information is usually used by libinput to determine a
|
||||
device type. Note that for historical reasons these properties have
|
||||
varying rules - some properties may be mutually exclusive, others are
|
||||
independent, others may only be set if another property is set. Refer to
|
||||
the udev documentation (if any) for details. ``ID_INPUT_WIDTH_MM`` and
|
||||
``ID_INPUT_HEIGHT_MM`` are excluded from this set.
|
||||
|
||||
If the device has since been discarded by libinput, this function returns an
|
||||
empty table.
|
||||
|
||||
.. function:: EvdevDevice:enable_evdev_usage(usage)
|
||||
|
||||
Enable the given :ref:`evdev usage <plugins_api_evdev_usage>` for this device.
|
||||
Use :ref:`plugins_api_evdev_global` for better readability,
|
||||
e.g. ``device:enable_evdev_usage(evdev.REL_X)``.
|
||||
This function must not be used for ``ABS_*`` events, use ``set_absinfo()``
|
||||
instead.
|
||||
|
||||
Once a usage is enabled, events for that usage may be added to a device's
|
||||
frame.
|
||||
|
||||
If the device has since been discarded by libinput, this function does nothing.
|
||||
|
||||
.. function:: EvdevDevice:disable_evdev_usage(usage)
|
||||
|
||||
Disable the given :ref:`evdev usage <plugins_api_evdev_usage>` for this device.
|
||||
Use :ref:`plugins_api_evdev_global` for better readability,
|
||||
e.g. ``device:disable_evdev_usage(evdev.REL_X)``.
|
||||
|
||||
Once a usage is disabled, events for that usage are discarded from any
|
||||
device frame.
|
||||
|
||||
If the device has since been discarded by libinput, this function does nothing.
|
||||
|
||||
.. function:: EvdevDevice:set_absinfo(usage, absinfo)
|
||||
|
||||
Set the absolute axis information for the given :ref:`evdev usage <plugins_api_evdev_usage>`
|
||||
and enable it if it does not yet exist on the device. The ``absinfo`` argument is a table
|
||||
containing zero or more of the following keys: ``minimum``, ``maximum``, ``fuzz``,
|
||||
``flat``, ``resolution``. Any missing key defaults the corresponding
|
||||
value from the device if the device already has this event usage or zero otherwise.
|
||||
For example, the following code changes the resolution but leaves everything
|
||||
else as-is:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
local absinfo = {
|
||||
resolution = 40,
|
||||
}
|
||||
device:set_absinfo(evdev.ABS_X, absinfo)
|
||||
device:set_absinfo(evdev.ABS_Y, absinfo)
|
||||
|
||||
Use :ref:`plugins_api_evdev_global` for better readability as shown in the
|
||||
example above.
|
||||
|
||||
If the device has since been discarded by libinput, this function does nothing.
|
||||
|
||||
.. note:: Overriding the absinfo values often indicates buggy firmware. This should
|
||||
typically be fixed with an entry in the
|
||||
`60-evdev.hwdb <https://github.com/systemd/systemd/blob/main/hwdb.d/60-evdev.hwdb>`_
|
||||
or :ref:`device-quirks` instead of a plugin so all users of that
|
||||
device can benefit from the fix.
|
||||
|
||||
.. function:: EvdevDevice:connect(name, function)
|
||||
|
||||
Set the callback to the given event name. Only one callback
|
||||
may be set for an event name at any time, subsequent callbacks
|
||||
will overwrite any earlier callbacks for the same name.
|
||||
|
||||
If the device has since been discarded by libinput, this function does nothing.
|
||||
|
||||
Version 1 of the plugin API supports the following events and callback arguments:
|
||||
|
||||
- ``"evdev-frame"``: A new :ref:`evdev frame <plugins_api_evdev_frame>` has
|
||||
started for this device. If the callback returns a value other than
|
||||
``nil``, that value is the frame with any modified events.
|
||||
An empty frame (``{}``) causes libinput to drop the current event frame.
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
device:connect("evdev-frame", function (device, frame, timestamp)
|
||||
-- change any event into a movement left by 1 pixel
|
||||
move_left = {
|
||||
{ usage = evdev.REL_X, value = -1, },
|
||||
}
|
||||
return move_left
|
||||
end
|
||||
|
||||
The timestamp of an event frame is in microseconds in ``CLOCK_MONOTONIC``, see
|
||||
``libinput:now()`` for details.
|
||||
|
||||
For performance reasons plugins that do not modify the event frame should
|
||||
return ``nil`` (or nothing) instead of the event frame that was passed
|
||||
as argument.
|
||||
|
||||
- ``"device-removed"``: This device was removed by libinput. This may happen
|
||||
without the device ever becoming a libinput device as seen by libinput's
|
||||
public API (e.g. if the device does not meet the requirements to be
|
||||
added). Once this callback is invoked, the plugin should remove any
|
||||
references to this device and stop using it.
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
device:connect("device-removed", function (device) ... end)
|
||||
|
||||
Functions to query the device's capabilities (e.g. ``usages()``) will
|
||||
return an empty table.
|
||||
|
||||
.. function:: EvdevDevice:disconnect(name)
|
||||
|
||||
Disconnect the existing callback (if any) for the given event name. See
|
||||
``EvdevDevice:connect()`` for a list of supported names.
|
||||
|
||||
.. function:: EvdevDevice:prepend_frame(frame)
|
||||
|
||||
Prepend an :ref:`evdev frame <plugins_api_evdev_frame>` for this device
|
||||
**before** the current frame (if any). The **next** plugin will see the
|
||||
prepended frame first followed by the current frame.
|
||||
|
||||
This function can only be called from within a device's ``"evdev-frame"``
|
||||
handler or from within the plugin's timer callback function.
|
||||
|
||||
For example, to change a single event into a drag, prepend a button
|
||||
down and append a button up before each event:
|
||||
|
||||
.. code:: lua
|
||||
|
||||
function frame_handler(device, frame, timestamp)
|
||||
device:prepend_frame({
|
||||
{ usage = evdev.BTN_LEFT, value = 1}
|
||||
})
|
||||
device:append_frame({
|
||||
{ usage = evdev.BTN_LEFT, value = 0}
|
||||
})
|
||||
return nil -- return the current frame unmodified
|
||||
|
||||
-- The next plugin sees the event sequence:
|
||||
-- button down, frame, button up
|
||||
end
|
||||
|
||||
If called from within the plugin's timer there is no current frame and this
|
||||
function is identical to ``append_frame()``.
|
||||
|
||||
.. function:: EvdevDevice:append_frame(frame)
|
||||
|
||||
Appends an :ref:`evdev frame <plugins_api_evdev_frame>` for this device
|
||||
**after** the current frame (if any). This function can only be called from
|
||||
within a device's ``"evdev-frame"`` handler or from within the plugin's timer
|
||||
callback function.
|
||||
|
||||
If called from within the plugin's timer there is no current frame and this
|
||||
function is identical to ``prepend_frame()``.
|
||||
|
||||
See ``prepend_frame()`` for more details.
|
||||
|
||||
.. function:: EvdevDevice:disable_feature(feature_name)
|
||||
|
||||
Disable the given libinput-internal feature for this device. This should be used
|
||||
by plugins that replace that feature with a custom implementation for this device.
|
||||
|
||||
libinput may have multiple internal implementations for any given feature, disabling
|
||||
it via this API disables any and all of those implementations, causing the feature to
|
||||
no longer work at all. It is up to the plugin implementation to re-implement that
|
||||
feature to match the user's expectation.
|
||||
|
||||
Version 1 of the plugin API supports the following features:
|
||||
|
||||
- ``"button-debouncing"``: see :ref:`button_debouncing`
|
||||
- ``"touchpad-hysteresis"``: see :ref:`touchpad_jitter`
|
||||
- ``"touchpad-jump-detection"``: see :ref:`touchpad_jumping_cursor`
|
||||
- ``"touchpad-palm-detection"``: see :ref:`palm_detection`
|
||||
- ``"wheel-debouncing"``: some high-resolution mouse wheel movements inside libinput
|
||||
are delayed and/or modified
|
||||
|
|
@ -95,11 +95,13 @@ src_rst = files(
|
|||
# dot drawings
|
||||
'dot/seats-sketch.gv',
|
||||
'dot/seats-sketch-libinput.gv',
|
||||
'dot/libinput-contexts.gv',
|
||||
'dot/libinput-stack-wayland.gv',
|
||||
'dot/libinput-stack-xorg.gv',
|
||||
'dot/libinput-stack-gnome.gv',
|
||||
'dot/evemu.gv',
|
||||
'dot/libinput-record.gv',
|
||||
'dot/plugin-stack.gv',
|
||||
# svgs
|
||||
'svg/button-debouncing-wave-diagram.svg',
|
||||
'svg/button-scrolling.svg',
|
||||
|
|
@ -155,6 +157,7 @@ src_rst = files(
|
|||
'middle-button-emulation.rst',
|
||||
'normalization-of-relative-motion.rst',
|
||||
'palm-detection.rst',
|
||||
'lua-plugins.rst',
|
||||
'pointer-acceleration.rst',
|
||||
'reporting-bugs.rst',
|
||||
'scrolling.rst',
|
||||
|
|
|
|||
|
|
@ -113,8 +113,8 @@ When you file a bug, please attach the following information:
|
|||
- the output from udevadm info, see :ref:`udev_info`.
|
||||
- the vendor model number of your laptop (e.g. "Lenovo Thinkpad T440s")
|
||||
- and the content of ``/sys/class/dmi/id/modalias``.
|
||||
- run the ``touchpad-edge-detector`` tool (provided by libevdev) and verify
|
||||
that the ranges and sizes it prints match the touchpad (up to 5mm
|
||||
- run ``libinput measure touchpad-size`` tool (see :ref:`absolute_coordinate_ranges_fix`)
|
||||
and verify that the ranges and sizes it prints match the touchpad (up to 5mm
|
||||
difference is ok)
|
||||
|
||||
If you are reporting a bug related to button event generation:
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ other properties.
|
|||
Number of buttons
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
.. _touchapds_buttons_phys:
|
||||
.. _touchpads_buttons_phys:
|
||||
|
||||
..............................................................................
|
||||
Physically separate buttons
|
||||
|
|
@ -57,7 +57,7 @@ property.
|
|||
.. _touchpads_buttons_forcepads:
|
||||
|
||||
..............................................................................
|
||||
Forcepads
|
||||
Forcepads/Pressurepads
|
||||
..............................................................................
|
||||
|
||||
Forcepads are Clickpads without a physical button underneath the hardware.
|
||||
|
|
@ -65,6 +65,7 @@ They provide pressure and may have a vibration element that is
|
|||
software-controlled. This element can simulate the feel of a physical
|
||||
click or be co-opted for other tasks.
|
||||
|
||||
Forcepads are also called pressurepads or haptic touchpads.
|
||||
|
||||
.. _touchpads_touch:
|
||||
|
||||
|
|
@ -79,7 +80,7 @@ device can **track**, i.e. provide reliable positional information for.
|
|||
In the kernel each finger is tracked in a so-called "slot", the number of
|
||||
slots thus equals the number of simultaneous touches a device can track.
|
||||
|
||||
.. _touchapds_touch_st:
|
||||
.. _touchpads_touch_st:
|
||||
|
||||
..............................................................................
|
||||
Single-touch touchpads
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
|
||||
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
|
||||
#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
|
||||
#define INPUT_PROP_PRESSUREPAD 0x07 /* pressure triggers clicks */
|
||||
|
||||
#define INPUT_PROP_MAX 0x1f
|
||||
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
|
||||
|
|
@ -278,7 +279,8 @@
|
|||
#define KEY_PAUSECD 201
|
||||
#define KEY_PROG3 202
|
||||
#define KEY_PROG4 203
|
||||
#define KEY_DASHBOARD 204 /* AL Dashboard */
|
||||
#define KEY_ALL_APPLICATIONS 204 /* AC Desktop Show All Applications */
|
||||
#define KEY_DASHBOARD KEY_ALL_APPLICATIONS
|
||||
#define KEY_SUSPEND 205
|
||||
#define KEY_CLOSE 206 /* AC Close */
|
||||
#define KEY_PLAY 207
|
||||
|
|
@ -515,6 +517,10 @@
|
|||
#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
|
||||
#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
|
||||
#define KEY_IMAGES 0x1ba /* AL Image Browser */
|
||||
#define KEY_NOTIFICATION_CENTER 0x1bc /* Show/hide the notification center */
|
||||
#define KEY_PICKUP_PHONE 0x1bd /* Answer incoming call */
|
||||
#define KEY_HANGUP_PHONE 0x1be /* Decline incoming call */
|
||||
#define KEY_LINK_PHONE 0x1bf /* AL Phone Syncing */
|
||||
|
||||
#define KEY_DEL_EOL 0x1c0
|
||||
#define KEY_DEL_EOS 0x1c1
|
||||
|
|
@ -542,6 +548,7 @@
|
|||
#define KEY_FN_F 0x1e2
|
||||
#define KEY_FN_S 0x1e3
|
||||
#define KEY_FN_B 0x1e4
|
||||
#define KEY_FN_RIGHT_SHIFT 0x1e5
|
||||
|
||||
#define KEY_BRL_DOT1 0x1f1
|
||||
#define KEY_BRL_DOT2 0x1f2
|
||||
|
|
@ -595,8 +602,14 @@
|
|||
#define BTN_DPAD_LEFT 0x222
|
||||
#define BTN_DPAD_RIGHT 0x223
|
||||
|
||||
#define BTN_GRIPL 0x224
|
||||
#define BTN_GRIPR 0x225
|
||||
#define BTN_GRIPL2 0x226
|
||||
#define BTN_GRIPR2 0x227
|
||||
|
||||
#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
|
||||
#define KEY_ROTATE_LOCK_TOGGLE 0x231 /* Display rotation lock */
|
||||
#define KEY_REFRESH_RATE_TOGGLE 0x232 /* Display refresh rate toggle */
|
||||
|
||||
#define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */
|
||||
#define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */
|
||||
|
|
@ -607,10 +620,29 @@
|
|||
#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */
|
||||
#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */
|
||||
#define KEY_KBD_LAYOUT_NEXT 0x248 /* AC Next Keyboard Layout Select */
|
||||
#define KEY_EMOJI_PICKER 0x249 /* Show/hide emoji picker (HUTRR101) */
|
||||
#define KEY_DICTATE 0x24a /* Start or Stop Voice Dictation Session (HUTRR99) */
|
||||
#define KEY_CAMERA_ACCESS_ENABLE 0x24b /* Enables programmatic access to camera devices. (HUTRR72) */
|
||||
#define KEY_CAMERA_ACCESS_DISABLE 0x24c /* Disables programmatic access to camera devices. (HUTRR72) */
|
||||
#define KEY_CAMERA_ACCESS_TOGGLE 0x24d /* Toggles the current state of the camera access control. (HUTRR72) */
|
||||
#define KEY_ACCESSIBILITY 0x24e /* Toggles the system bound accessibility UI/command (HUTRR116) */
|
||||
#define KEY_DO_NOT_DISTURB 0x24f /* Toggles the system-wide "Do Not Disturb" control (HUTRR94)*/
|
||||
|
||||
#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
|
||||
#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */
|
||||
|
||||
/*
|
||||
* Keycodes for hotkeys toggling the electronic privacy screen found on some
|
||||
* laptops on/off. Note when the embedded-controller turns on/off the eprivacy
|
||||
* screen itself then the state should be reported through drm connecter props:
|
||||
* https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#standard-connector-properties
|
||||
* Except when implementing the drm connecter properties API is not possible
|
||||
* because e.g. the firmware does not allow querying the presence and/or status
|
||||
* of the eprivacy screen at boot.
|
||||
*/
|
||||
#define KEY_EPRIVACY_SCREEN_ON 0x252
|
||||
#define KEY_EPRIVACY_SCREEN_OFF 0x253
|
||||
|
||||
#define KEY_KBDINPUTASSIST_PREV 0x260
|
||||
#define KEY_KBDINPUTASSIST_NEXT 0x261
|
||||
#define KEY_KBDINPUTASSIST_PREVGROUP 0x262
|
||||
|
|
@ -655,6 +687,27 @@
|
|||
/* Select an area of screen to be copied */
|
||||
#define KEY_SELECTIVE_SCREENSHOT 0x27a
|
||||
|
||||
/* Move the focus to the next or previous user controllable element within a UI container */
|
||||
#define KEY_NEXT_ELEMENT 0x27b
|
||||
#define KEY_PREVIOUS_ELEMENT 0x27c
|
||||
|
||||
/* Toggle Autopilot engagement */
|
||||
#define KEY_AUTOPILOT_ENGAGE_TOGGLE 0x27d
|
||||
|
||||
/* Shortcut Keys */
|
||||
#define KEY_MARK_WAYPOINT 0x27e
|
||||
#define KEY_SOS 0x27f
|
||||
#define KEY_NAV_CHART 0x280
|
||||
#define KEY_FISHING_CHART 0x281
|
||||
#define KEY_SINGLE_RANGE_RADAR 0x282
|
||||
#define KEY_DUAL_RANGE_RADAR 0x283
|
||||
#define KEY_RADAR_OVERLAY 0x284
|
||||
#define KEY_TRADITIONAL_SONAR 0x285
|
||||
#define KEY_CLEARVU_SONAR 0x286
|
||||
#define KEY_SIDEVU_SONAR 0x287
|
||||
#define KEY_NAV_INFO 0x288
|
||||
#define KEY_BRIGHTNESS_MENU 0x289
|
||||
|
||||
/*
|
||||
* Some keyboards have keys which do not have a defined meaning, these keys
|
||||
* are intended to be programmed / bound to macros by the user. For most
|
||||
|
|
@ -730,6 +783,9 @@
|
|||
#define KEY_KBD_LCD_MENU4 0x2bb
|
||||
#define KEY_KBD_LCD_MENU5 0x2bc
|
||||
|
||||
/* Performance Boost key (Alienware)/G-Mode key (Dell) */
|
||||
#define KEY_PERFORMANCE 0x2bd
|
||||
|
||||
#define BTN_TRIGGER_HAPPY 0x2c0
|
||||
#define BTN_TRIGGER_HAPPY1 0x2c0
|
||||
#define BTN_TRIGGER_HAPPY2 0x2c1
|
||||
|
|
@ -834,6 +890,7 @@
|
|||
#define ABS_TOOL_WIDTH 0x1c
|
||||
|
||||
#define ABS_VOLUME 0x20
|
||||
#define ABS_PROFILE 0x21
|
||||
|
||||
#define ABS_MISC 0x28
|
||||
|
||||
|
|
@ -889,7 +946,8 @@
|
|||
#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
|
||||
#define SW_PEN_INSERTED 0x0f /* set = pen inserted */
|
||||
#define SW_MACHINE_COVER 0x10 /* set = cover closed */
|
||||
#define SW_MAX 0x10
|
||||
#define SW_USB_INSERT 0x11 /* set = USB audio device connected */
|
||||
#define SW_MAX 0x11
|
||||
#define SW_CNT (SW_MAX+1)
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
|
||||
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
|
||||
#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
|
||||
#define INPUT_PROP_PRESSUREPAD 0x07 /* pressure triggers clicks */
|
||||
|
||||
#define INPUT_PROP_MAX 0x1f
|
||||
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
|
||||
|
|
@ -278,7 +279,8 @@
|
|||
#define KEY_PAUSECD 201
|
||||
#define KEY_PROG3 202
|
||||
#define KEY_PROG4 203
|
||||
#define KEY_DASHBOARD 204 /* AL Dashboard */
|
||||
#define KEY_ALL_APPLICATIONS 204 /* AC Desktop Show All Applications */
|
||||
#define KEY_DASHBOARD KEY_ALL_APPLICATIONS
|
||||
#define KEY_SUSPEND 205
|
||||
#define KEY_CLOSE 206 /* AC Close */
|
||||
#define KEY_PLAY 207
|
||||
|
|
@ -515,6 +517,10 @@
|
|||
#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
|
||||
#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
|
||||
#define KEY_IMAGES 0x1ba /* AL Image Browser */
|
||||
#define KEY_NOTIFICATION_CENTER 0x1bc /* Show/hide the notification center */
|
||||
#define KEY_PICKUP_PHONE 0x1bd /* Answer incoming call */
|
||||
#define KEY_HANGUP_PHONE 0x1be /* Decline incoming call */
|
||||
#define KEY_LINK_PHONE 0x1bf /* AL Phone Syncing */
|
||||
|
||||
#define KEY_DEL_EOL 0x1c0
|
||||
#define KEY_DEL_EOS 0x1c1
|
||||
|
|
@ -542,6 +548,7 @@
|
|||
#define KEY_FN_F 0x1e2
|
||||
#define KEY_FN_S 0x1e3
|
||||
#define KEY_FN_B 0x1e4
|
||||
#define KEY_FN_RIGHT_SHIFT 0x1e5
|
||||
|
||||
#define KEY_BRL_DOT1 0x1f1
|
||||
#define KEY_BRL_DOT2 0x1f2
|
||||
|
|
@ -595,8 +602,14 @@
|
|||
#define BTN_DPAD_LEFT 0x222
|
||||
#define BTN_DPAD_RIGHT 0x223
|
||||
|
||||
#define BTN_GRIPL 0x224
|
||||
#define BTN_GRIPR 0x225
|
||||
#define BTN_GRIPL2 0x226
|
||||
#define BTN_GRIPR2 0x227
|
||||
|
||||
#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
|
||||
#define KEY_ROTATE_LOCK_TOGGLE 0x231 /* Display rotation lock */
|
||||
#define KEY_REFRESH_RATE_TOGGLE 0x232 /* Display refresh rate toggle */
|
||||
|
||||
#define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */
|
||||
#define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */
|
||||
|
|
@ -607,10 +620,29 @@
|
|||
#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */
|
||||
#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */
|
||||
#define KEY_KBD_LAYOUT_NEXT 0x248 /* AC Next Keyboard Layout Select */
|
||||
#define KEY_EMOJI_PICKER 0x249 /* Show/hide emoji picker (HUTRR101) */
|
||||
#define KEY_DICTATE 0x24a /* Start or Stop Voice Dictation Session (HUTRR99) */
|
||||
#define KEY_CAMERA_ACCESS_ENABLE 0x24b /* Enables programmatic access to camera devices. (HUTRR72) */
|
||||
#define KEY_CAMERA_ACCESS_DISABLE 0x24c /* Disables programmatic access to camera devices. (HUTRR72) */
|
||||
#define KEY_CAMERA_ACCESS_TOGGLE 0x24d /* Toggles the current state of the camera access control. (HUTRR72) */
|
||||
#define KEY_ACCESSIBILITY 0x24e /* Toggles the system bound accessibility UI/command (HUTRR116) */
|
||||
#define KEY_DO_NOT_DISTURB 0x24f /* Toggles the system-wide "Do Not Disturb" control (HUTRR94)*/
|
||||
|
||||
#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
|
||||
#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */
|
||||
|
||||
/*
|
||||
* Keycodes for hotkeys toggling the electronic privacy screen found on some
|
||||
* laptops on/off. Note when the embedded-controller turns on/off the eprivacy
|
||||
* screen itself then the state should be reported through drm connecter props:
|
||||
* https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#standard-connector-properties
|
||||
* Except when implementing the drm connecter properties API is not possible
|
||||
* because e.g. the firmware does not allow querying the presence and/or status
|
||||
* of the eprivacy screen at boot.
|
||||
*/
|
||||
#define KEY_EPRIVACY_SCREEN_ON 0x252
|
||||
#define KEY_EPRIVACY_SCREEN_OFF 0x253
|
||||
|
||||
#define KEY_KBDINPUTASSIST_PREV 0x260
|
||||
#define KEY_KBDINPUTASSIST_NEXT 0x261
|
||||
#define KEY_KBDINPUTASSIST_PREVGROUP 0x262
|
||||
|
|
@ -655,6 +687,27 @@
|
|||
/* Select an area of screen to be copied */
|
||||
#define KEY_SELECTIVE_SCREENSHOT 0x27a
|
||||
|
||||
/* Move the focus to the next or previous user controllable element within a UI container */
|
||||
#define KEY_NEXT_ELEMENT 0x27b
|
||||
#define KEY_PREVIOUS_ELEMENT 0x27c
|
||||
|
||||
/* Toggle Autopilot engagement */
|
||||
#define KEY_AUTOPILOT_ENGAGE_TOGGLE 0x27d
|
||||
|
||||
/* Shortcut Keys */
|
||||
#define KEY_MARK_WAYPOINT 0x27e
|
||||
#define KEY_SOS 0x27f
|
||||
#define KEY_NAV_CHART 0x280
|
||||
#define KEY_FISHING_CHART 0x281
|
||||
#define KEY_SINGLE_RANGE_RADAR 0x282
|
||||
#define KEY_DUAL_RANGE_RADAR 0x283
|
||||
#define KEY_RADAR_OVERLAY 0x284
|
||||
#define KEY_TRADITIONAL_SONAR 0x285
|
||||
#define KEY_CLEARVU_SONAR 0x286
|
||||
#define KEY_SIDEVU_SONAR 0x287
|
||||
#define KEY_NAV_INFO 0x288
|
||||
#define KEY_BRIGHTNESS_MENU 0x289
|
||||
|
||||
/*
|
||||
* Some keyboards have keys which do not have a defined meaning, these keys
|
||||
* are intended to be programmed / bound to macros by the user. For most
|
||||
|
|
@ -730,6 +783,9 @@
|
|||
#define KEY_KBD_LCD_MENU4 0x2bb
|
||||
#define KEY_KBD_LCD_MENU5 0x2bc
|
||||
|
||||
/* Performance Boost key (Alienware)/G-Mode key (Dell) */
|
||||
#define KEY_PERFORMANCE 0x2bd
|
||||
|
||||
#define BTN_TRIGGER_HAPPY 0x2c0
|
||||
#define BTN_TRIGGER_HAPPY1 0x2c0
|
||||
#define BTN_TRIGGER_HAPPY2 0x2c1
|
||||
|
|
@ -834,6 +890,7 @@
|
|||
#define ABS_TOOL_WIDTH 0x1c
|
||||
|
||||
#define ABS_VOLUME 0x20
|
||||
#define ABS_PROFILE 0x21
|
||||
|
||||
#define ABS_MISC 0x28
|
||||
|
||||
|
|
@ -889,7 +946,8 @@
|
|||
#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
|
||||
#define SW_PEN_INSERTED 0x0f /* set = pen inserted */
|
||||
#define SW_MACHINE_COVER 0x10 /* set = cover closed */
|
||||
#define SW_MAX 0x10
|
||||
#define SW_USB_INSERT 0x11 /* set = USB audio device connected */
|
||||
#define SW_MAX 0x11
|
||||
#define SW_CNT (SW_MAX+1)
|
||||
|
||||
/*
|
||||
|
|
|
|||
173
meson.build
173
meson.build
|
|
@ -1,8 +1,8 @@
|
|||
project('libinput', 'c',
|
||||
version : '1.28.901',
|
||||
version : '1.30.0',
|
||||
license : 'MIT/Expat',
|
||||
default_options : [ 'c_std=gnu99', 'warning_level=2' ],
|
||||
meson_version : '>= 0.56.0')
|
||||
meson_version : '>= 0.64.0')
|
||||
|
||||
libinput_version = meson.project_version().split('.')
|
||||
|
||||
|
|
@ -156,8 +156,9 @@ if not cc.has_header_symbol('sys/ptrace.h', 'PTRACE_ATTACH', prefix : prefix)
|
|||
config_h.set('PTRACE_CONT', 'PT_CONTINUE')
|
||||
config_h.set('PTRACE_DETACH', 'PT_DETACH')
|
||||
endif
|
||||
|
||||
config_h.set10('HAVE_INSTALLED_TESTS', get_option('install-tests'))
|
||||
if get_option('install-tests')
|
||||
config_h.set('HAVE_INSTALLED_TESTS', 1)
|
||||
endif
|
||||
|
||||
# Dependencies
|
||||
pkgconfig = import('pkgconfig')
|
||||
|
|
@ -167,6 +168,32 @@ dep_libevdev = dependency('libevdev', version: '>= 1.10.0')
|
|||
dep_lm = cc.find_library('m', required : false)
|
||||
dep_rt = cc.find_library('rt', required : false)
|
||||
|
||||
dep_lua = dependency('lua-5.4', 'lua5.4', 'lua',
|
||||
version : '>= 5.4',
|
||||
required : get_option('lua-plugins'))
|
||||
have_lua = dep_lua.found()
|
||||
if have_lua
|
||||
config_h.set('HAVE_LUA', 1)
|
||||
endif
|
||||
|
||||
have_plugins = dep_lua.found()
|
||||
if have_plugins
|
||||
config_h.set('HAVE_PLUGINS', 1)
|
||||
endif
|
||||
|
||||
autoload_plugins = get_option('autoload-plugins')
|
||||
if autoload_plugins
|
||||
config_h.set('AUTOLOAD_PLUGINS', 1)
|
||||
endif
|
||||
|
||||
summary({
|
||||
'Plugins enabled' : have_plugins,
|
||||
'Autoload plugins' : autoload_plugins,
|
||||
'Lua Plugin support' : have_lua,
|
||||
},
|
||||
section : 'Plugins',
|
||||
bool_yn : true)
|
||||
|
||||
# Include directories
|
||||
includes_include = include_directories('include')
|
||||
includes_src = include_directories('src')
|
||||
|
|
@ -174,8 +201,8 @@ includes_src = include_directories('src')
|
|||
############ mtdev configuration ############
|
||||
|
||||
have_mtdev = get_option('mtdev')
|
||||
config_h.set10('HAVE_MTDEV', have_mtdev)
|
||||
if have_mtdev
|
||||
config_h.set('HAVE_MTDEV', 1)
|
||||
dep_mtdev = dependency('mtdev', version : '>= 1.1.0')
|
||||
else
|
||||
dep_mtdev = declare_dependency()
|
||||
|
|
@ -184,8 +211,8 @@ endif
|
|||
############ libwacom configuration ############
|
||||
|
||||
have_libwacom = get_option('libwacom')
|
||||
config_h.set10('HAVE_LIBWACOM', have_libwacom)
|
||||
if have_libwacom
|
||||
config_h.set('HAVE_LIBWACOM', 1)
|
||||
dep_libwacom = dependency('libwacom', version : '>= 0.27')
|
||||
if cc.has_header_symbol('libwacom/libwacom.h', 'WACOM_BUTTON_DIAL_MODESWITCH',
|
||||
dependencies : dep_libwacom)
|
||||
|
|
@ -206,6 +233,7 @@ executable('libinput-device-group',
|
|||
dependencies : [dep_udev, dep_libwacom],
|
||||
include_directories : [includes_src, includes_include],
|
||||
install : true,
|
||||
install_tag : 'runtime',
|
||||
install_dir : dir_udev_callouts)
|
||||
executable('libinput-fuzz-extract',
|
||||
'udev/libinput-fuzz-extract.c',
|
||||
|
|
@ -214,16 +242,18 @@ executable('libinput-fuzz-extract',
|
|||
dependencies : [dep_udev, dep_libevdev, dep_lm],
|
||||
include_directories : [includes_src, includes_include],
|
||||
install : true,
|
||||
install_tag : 'runtime',
|
||||
install_dir : dir_udev_callouts)
|
||||
executable('libinput-fuzz-to-zero',
|
||||
'udev/libinput-fuzz-to-zero.c',
|
||||
dependencies : [dep_udev, dep_libevdev],
|
||||
include_directories : [includes_src, includes_include],
|
||||
install : true,
|
||||
install_tag : 'runtime',
|
||||
install_dir : dir_udev_callouts)
|
||||
|
||||
udev_rules_config = configuration_data()
|
||||
udev_rules_config.set('UDEV_TEST_PATH', '')
|
||||
udev_rules_config.set('UDEV_TEST_PATH', dir_udev_callouts + '/')
|
||||
configure_file(input : 'udev/80-libinput-device-groups.rules.in',
|
||||
output : '80-libinput-device-groups.rules',
|
||||
install_dir : dir_udev_rules,
|
||||
|
|
@ -369,14 +399,15 @@ libquirks = static_library('quirks', src_libquirks,
|
|||
dep_libquirks = declare_dependency(link_with : libquirks)
|
||||
|
||||
# Create /etc/libinput
|
||||
if meson.version().version_compare('>= 0.60')
|
||||
install_emptydir(dir_etc / 'libinput')
|
||||
else
|
||||
install_subdir('libinput', install_dir : dir_etc)
|
||||
endif
|
||||
install_emptydir(dir_etc / 'libinput')
|
||||
|
||||
############ libinput.so ############
|
||||
config_h.set10('EVENT_DEBUGGING', get_option('internal-event-debugging'))
|
||||
if get_option('internal-event-debugging')
|
||||
config_h.set('EVENT_DEBUGGING', 1)
|
||||
endif
|
||||
|
||||
config_h.set_quoted('LIBINPUT_PLUGIN_LIBDIR', dir_lib / 'libinput' / 'plugins')
|
||||
config_h.set_quoted('LIBINPUT_PLUGIN_ETCDIR', dir_etc / 'libinput' / 'plugins')
|
||||
|
||||
install_headers('src/libinput.h')
|
||||
src_libinput = src_libfilter + [
|
||||
|
|
@ -384,6 +415,7 @@ src_libinput = src_libfilter + [
|
|||
'src/libinput-plugin.c',
|
||||
'src/libinput-plugin-button-debounce.c',
|
||||
'src/libinput-plugin-mouse-wheel.c',
|
||||
'src/libinput-plugin-mouse-wheel-lowres.c',
|
||||
'src/libinput-plugin-tablet-double-tool.c',
|
||||
'src/libinput-plugin-tablet-eraser-button.c',
|
||||
'src/libinput-plugin-tablet-forced-tool.c',
|
||||
|
|
@ -408,10 +440,17 @@ src_libinput = src_libfilter + [
|
|||
'src/timer.c',
|
||||
'src/util-libinput.c',
|
||||
]
|
||||
|
||||
if have_mtdev
|
||||
src_libinput += ['src/libinput-plugin-mtdev.c']
|
||||
endif
|
||||
|
||||
if dep_lua.found()
|
||||
src_libinput += [
|
||||
'src/libinput-plugin-lua.c',
|
||||
]
|
||||
endif
|
||||
|
||||
deps_libinput = [
|
||||
dep_mtdev,
|
||||
dep_udev,
|
||||
|
|
@ -421,7 +460,8 @@ deps_libinput = [
|
|||
dep_rt,
|
||||
dep_libwacom,
|
||||
dep_libinput_util,
|
||||
dep_libquirks
|
||||
dep_libquirks,
|
||||
dep_lua,
|
||||
]
|
||||
|
||||
libinput_version_h_config = configuration_data()
|
||||
|
|
@ -452,9 +492,7 @@ dep_libinput = declare_dependency(
|
|||
link_with : lib_libinput,
|
||||
dependencies : deps_libinput)
|
||||
|
||||
if meson.version().version_compare('>= 0.54.0')
|
||||
meson.override_dependency('libinput', dep_libinput)
|
||||
endif
|
||||
meson.override_dependency('libinput', dep_libinput)
|
||||
|
||||
pkgconfig.generate(
|
||||
filebase : 'libinput',
|
||||
|
|
@ -463,6 +501,9 @@ pkgconfig.generate(
|
|||
version : meson.project_version(),
|
||||
libraries : lib_libinput,
|
||||
requires_private : dep_udev,
|
||||
variables : [
|
||||
'plugindir=${libdir}/libinput/plugins'
|
||||
]
|
||||
)
|
||||
|
||||
git_version_h = vcs_tag(command : ['git', 'describe'],
|
||||
|
|
@ -470,6 +511,8 @@ git_version_h = vcs_tag(command : ['git', 'describe'],
|
|||
input : 'src/libinput-git-version.h.in',
|
||||
output :'libinput-git-version.h')
|
||||
|
||||
subdir('plugins')
|
||||
|
||||
############ documentation ############
|
||||
|
||||
if get_option('documentation')
|
||||
|
|
@ -515,6 +558,7 @@ executable('libinput-debug-events',
|
|||
dependencies : deps_tools,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true
|
||||
)
|
||||
|
||||
|
|
@ -524,8 +568,17 @@ executable('libinput-debug-tablet',
|
|||
dependencies : deps_tools,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true)
|
||||
|
||||
libinput_debug_tablet_pad_sources = [ 'tools/libinput-debug-tablet-pad.c' ]
|
||||
executable('libinput-debug-tablet-pad',
|
||||
libinput_debug_tablet_pad_sources,
|
||||
dependencies : deps_tools,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true)
|
||||
|
||||
libinput_quirks_sources = [ 'tools/libinput-quirks.c' ]
|
||||
libinput_quirks = executable('libinput-quirks',
|
||||
|
|
@ -533,6 +586,7 @@ libinput_quirks = executable('libinput-quirks',
|
|||
dependencies : [dep_libquirks, dep_tools_shared, dep_libinput],
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true
|
||||
)
|
||||
test('validate-quirks',
|
||||
|
|
@ -554,6 +608,7 @@ libinput_list_devices = executable('libinput-list-devices',
|
|||
dependencies : deps_tools,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true,
|
||||
)
|
||||
test('list-devices',
|
||||
|
|
@ -566,6 +621,7 @@ executable('libinput-measure',
|
|||
dependencies : deps_tools,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true,
|
||||
)
|
||||
|
||||
|
|
@ -575,21 +631,22 @@ executable('libinput-analyze',
|
|||
dependencies : deps_tools,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true,
|
||||
)
|
||||
|
||||
src_python_tools = files(
|
||||
'tools/libinput-analyze-buttons.py',
|
||||
'tools/libinput-analyze-per-slot-delta.py',
|
||||
'tools/libinput-analyze-recording.py',
|
||||
'tools/libinput-analyze-touch-down-state.py',
|
||||
'tools/libinput-list-kernel-devices.py',
|
||||
'tools/libinput-measure-fuzz.py',
|
||||
'tools/libinput-measure-touchpad-size.py',
|
||||
'tools/libinput-measure-touchpad-tap.py',
|
||||
'tools/libinput-measure-touchpad-pressure.py',
|
||||
'tools/libinput-measure-touch-size.py',
|
||||
'tools/libinput-replay.py'
|
||||
'tools/libinput-analyze-buttons.py',
|
||||
'tools/libinput-analyze-per-slot-delta.py',
|
||||
'tools/libinput-analyze-recording.py',
|
||||
'tools/libinput-analyze-touch-down-state.py',
|
||||
'tools/libinput-list-kernel-devices.py',
|
||||
'tools/libinput-measure-fuzz.py',
|
||||
'tools/libinput-measure-touchpad-size.py',
|
||||
'tools/libinput-measure-touchpad-tap.py',
|
||||
'tools/libinput-measure-touchpad-pressure.py',
|
||||
'tools/libinput-measure-touch-size.py',
|
||||
'tools/libinput-replay.py'
|
||||
)
|
||||
|
||||
foreach t : src_python_tools
|
||||
|
|
@ -606,23 +663,23 @@ executable('libinput-record',
|
|||
dependencies : deps_tools + [dep_udev],
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true,
|
||||
)
|
||||
|
||||
config_h.set10('HAVE_DEBUG_GUI', get_option('debug-gui'))
|
||||
if get_option('debug-gui')
|
||||
config_h.set('HAVE_DEBUG_GUI', 1)
|
||||
dep_gtk = dependency('gtk4', version : '>= 4.0', required : false)
|
||||
config_h.set10('HAVE_GTK4', dep_gtk.found())
|
||||
if not dep_gtk.found()
|
||||
if dep_gtk.found()
|
||||
config_h.set('HAVE_GTK4', 1)
|
||||
else
|
||||
dep_gtk = dependency('gtk+-3.0', version : '>= 3.20')
|
||||
config_h.set10('HAVE_GTK3', dep_gtk.found())
|
||||
if dep_gtk.found()
|
||||
config_h.set('HAVE_GTK3', 1)
|
||||
endif
|
||||
endif
|
||||
|
||||
if meson.version().version_compare('>= 0.58')
|
||||
gtk_targets = dep_gtk.get_variable('targets')
|
||||
else
|
||||
gtk_targets = dep_gtk.get_pkgconfig_variable('targets')
|
||||
endif
|
||||
gtk_targets = dep_gtk.get_variable('targets')
|
||||
|
||||
have_gtk_wayland = gtk_targets.contains('wayland')
|
||||
have_gtk_x11 = gtk_targets.contains('x11')
|
||||
|
|
@ -633,18 +690,15 @@ if get_option('debug-gui')
|
|||
dep_wayland_client = dependency('wayland-client', required : false)
|
||||
dep_wayland_protocols = dependency('wayland-protocols', required : false)
|
||||
|
||||
config_h.set10('HAVE_GTK_X11', have_gtk_x11 and dep_x11.found())
|
||||
config_h.set10('HAVE_GTK_WAYLAND', false)
|
||||
if have_gtk_x11 and dep_x11.found()
|
||||
config_h.set('HAVE_GTK_X11', 1)
|
||||
endif
|
||||
|
||||
debug_gui_sources = [ 'tools/libinput-debug-gui.c' ]
|
||||
|
||||
if have_gtk_wayland and dep_wayland_client.found() and dep_wayland_protocols.found()
|
||||
wayland_scanner = find_program('wayland-scanner')
|
||||
if meson.version().version_compare('>= 0.58')
|
||||
wlproto_dir = dep_wayland_protocols.get_variable('pkgdatadir')
|
||||
else
|
||||
wlproto_dir = dep_wayland_protocols.get_pkgconfig_variable('pkgdatadir')
|
||||
endif
|
||||
wlproto_dir = dep_wayland_protocols.get_variable('pkgdatadir')
|
||||
|
||||
proto_name = 'pointer-constraints-unstable-v1'
|
||||
input = files(wlproto_dir / 'unstable' / 'pointer-constraints' / '@0@.xml'.format(proto_name))
|
||||
|
|
@ -662,7 +716,7 @@ if get_option('debug-gui')
|
|||
)
|
||||
|
||||
debug_gui_sources += [ wayland_headers, wayland_sources ]
|
||||
config_h.set10('HAVE_GTK_WAYLAND', true)
|
||||
config_h.set('HAVE_GTK_WAYLAND', 1)
|
||||
endif
|
||||
|
||||
deps_debug_gui = [
|
||||
|
|
@ -678,6 +732,7 @@ if get_option('debug-gui')
|
|||
dependencies : deps_debug_gui,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true
|
||||
)
|
||||
src_man += files('tools/libinput-debug-gui.man')
|
||||
|
|
@ -689,6 +744,7 @@ libinput_tool = executable('libinput',
|
|||
libinput_sources,
|
||||
dependencies : deps_tools,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_tag : 'bin',
|
||||
install : true
|
||||
)
|
||||
|
||||
|
|
@ -779,6 +835,7 @@ executable('libinput-test',
|
|||
dependencies : deps_tools,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'tests',
|
||||
install : true,
|
||||
)
|
||||
|
||||
|
|
@ -788,11 +845,15 @@ if get_option('tests')
|
|||
dep_check = dependency('check', version : '>= 0.9.10', required: false)
|
||||
|
||||
gstack = find_program('gstack', required : false)
|
||||
config_h.set10('HAVE_GSTACK', gstack.found())
|
||||
if gstack.found()
|
||||
config_h.set('HAVE_GSTACK', 1)
|
||||
endif
|
||||
|
||||
# for inhibit support during test run
|
||||
dep_libsystemd = dependency('libsystemd', version : '>= 221', required : false)
|
||||
config_h.set10('HAVE_LIBSYSTEMD', dep_libsystemd.found())
|
||||
if dep_libsystemd.found()
|
||||
config_h.set('HAVE_LIBSYSTEMD', 1)
|
||||
endif
|
||||
|
||||
litest_sources = [
|
||||
'src/libinput-private-config.c',
|
||||
|
|
@ -830,6 +891,7 @@ if get_option('tests')
|
|||
'test/litest-device-keyboard-razer-blackwidow.c',
|
||||
'test/litest-device-keyboard-razer-blade-stealth.c',
|
||||
'test/litest-device-keyboard-razer-blade-stealth-videoswitch.c',
|
||||
'test/litest-device-keypad-slide-switch.c',
|
||||
'test/litest-device-lenovo-scrollpoint.c',
|
||||
'test/litest-device-lid-switch.c',
|
||||
'test/litest-device-lid-switch-surface3.c',
|
||||
|
|
@ -839,6 +901,8 @@ if get_option('tests')
|
|||
'test/litest-device-magic-trackpad.c',
|
||||
'test/litest-device-mouse.c',
|
||||
'test/litest-device-mouse-wheel-tilt.c',
|
||||
'test/litest-device-mouse-wheel-hires-disabled.c',
|
||||
'test/litest-device-mouse-ps2.c',
|
||||
'test/litest-device-mouse-roccat.c',
|
||||
'test/litest-device-mouse-low-dpi.c',
|
||||
'test/litest-device-mouse-virtual.c',
|
||||
|
|
@ -998,6 +1062,10 @@ if get_option('tests')
|
|||
'test/test-switch.c',
|
||||
'test/test-quirks.c',
|
||||
]
|
||||
if have_plugins and have_lua
|
||||
tests_sources += ['test/test-plugins-lua.c']
|
||||
endif
|
||||
|
||||
libinput_test_runner_sources = litest_sources + tests_sources
|
||||
libinput_test_runner = executable('libinput-test-suite',
|
||||
libinput_test_runner_sources,
|
||||
|
|
@ -1022,7 +1090,10 @@ if get_option('tests')
|
|||
'quirks',
|
||||
'switch',
|
||||
'tablet',
|
||||
'tablet_eraser',
|
||||
'tablet_left_handed',
|
||||
'tablet_proximity',
|
||||
'tablet_tip',
|
||||
'totem',
|
||||
'touch',
|
||||
'touchpad',
|
||||
|
|
@ -1036,6 +1107,9 @@ if get_option('tests')
|
|||
'trackpoint',
|
||||
'udev',
|
||||
]
|
||||
if have_plugins and have_lua
|
||||
collections += ['lua']
|
||||
endif
|
||||
|
||||
foreach group : collections
|
||||
test('libinput-test-suite-@0@'.format(group),
|
||||
|
|
@ -1043,7 +1117,7 @@ if get_option('tests')
|
|||
suite : ['all', 'valgrind', 'root', 'hardware'],
|
||||
args : ['--filter-group=@0@'.format(group)],
|
||||
is_parallel : false,
|
||||
timeout : 1200)
|
||||
timeout : 1100)
|
||||
endforeach
|
||||
|
||||
test('libinput-test-deviceless',
|
||||
|
|
@ -1063,7 +1137,7 @@ if get_option('tests')
|
|||
'--error-exitcode=3',
|
||||
'--suppressions=' + valgrind_suppressions_file ],
|
||||
env : valgrind_env,
|
||||
timeout_multiplier : 100)
|
||||
timeout_multiplier : 3)
|
||||
else
|
||||
message('valgrind not found, disabling valgrind test suite')
|
||||
endif
|
||||
|
|
@ -1096,6 +1170,7 @@ src_man += files(
|
|||
'tools/libinput-analyze-touch-down-state.man',
|
||||
'tools/libinput-debug-events.man',
|
||||
'tools/libinput-debug-tablet.man',
|
||||
'tools/libinput-debug-tablet-pad.man',
|
||||
'tools/libinput-list-devices.man',
|
||||
'tools/libinput-list-kernel-devices.man',
|
||||
'tools/libinput-measure.man',
|
||||
|
|
|
|||
|
|
@ -42,3 +42,11 @@ option('internal-event-debugging',
|
|||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Enable additional internal event debug tracing. This will print key values to the logs and thus must never be enabled in a release build')
|
||||
option('autoload-plugins',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Always load plugins from default plugin paths (only if the caller does not do so)')
|
||||
option('lua-plugins',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Enable support for Lua plugins')
|
||||
|
|
|
|||
71
plugins/10-copilot-key-override.lua
Normal file
71
plugins/10-copilot-key-override.lua
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- This is an example libinput plugin
|
||||
--
|
||||
-- This plugin detects the Copilot key on the keyboard with
|
||||
-- the given VID/PID and replaces it with a different key (sequence).
|
||||
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
|
||||
-- Replace this with your keyboard's VID/PID
|
||||
KEYBOARD_VID = 0x046d
|
||||
KEYBOARD_PID = 0x4088
|
||||
|
||||
meta_is_down = false
|
||||
shift_is_down = false
|
||||
|
||||
-- shift-A, because you can never have enough screaming
|
||||
replacement_sequence = { evdev.KEY_LEFTSHIFT, evdev.KEY_A }
|
||||
|
||||
function frame(device, frame, _)
|
||||
for _, v in ipairs(frame) do
|
||||
if v.value ~= 2 then -- ignore key repeats
|
||||
if v.usage == evdev.KEY_LEFTMETA then
|
||||
meta_is_down = v.value == 1
|
||||
elseif v.usage == evdev.KEY_LEFTSHIFT then
|
||||
shift_is_down = v.value == 1
|
||||
elseif v.usage == evdev.KEY_F23 and meta_is_down and shift_is_down then
|
||||
-- We know from the MS requirements that F23 for copilot is
|
||||
-- either last key (on press) or the first key (on release)
|
||||
-- of the three-key sequence, and no other keys are
|
||||
-- within this frame.
|
||||
if v.value == 1 then
|
||||
-- Release our modifiers first
|
||||
device:prepend_frame({
|
||||
{ usage = evdev.KEY_LEFTSHIFT, value = 0 },
|
||||
{ usage = evdev.KEY_LEFTMETA, value = 0 },
|
||||
})
|
||||
-- Insert our replacement press sequence
|
||||
local replacement_frame = {}
|
||||
for _, rv in ipairs(replacement_sequence) do
|
||||
table.insert(replacement_frame, { usage = rv, value = 1 })
|
||||
end
|
||||
device:append_frame(replacement_frame)
|
||||
else
|
||||
-- Insert our replacement release sequence
|
||||
local replacement_frame = {}
|
||||
for idx = #replacement_sequence, 1, -1 do
|
||||
table.insert(replacement_frame, { usage = replacement_sequence[idx], value = 0 })
|
||||
end
|
||||
device:append_frame(replacement_frame)
|
||||
|
||||
-- we don't care about re-pressing shift/meta because the
|
||||
-- rest of the stack will filter the release for an
|
||||
-- unpressed key anyway.
|
||||
end
|
||||
|
||||
return {} -- discard this frame
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function device_new(device)
|
||||
local info = device:info()
|
||||
if info.vid == KEYBOARD_VID and info.pid == KEYBOARD_PID then
|
||||
device:connect("evdev-frame", frame)
|
||||
end
|
||||
end
|
||||
|
||||
libinput:connect("new-evdev-device", device_new)
|
||||
64
plugins/10-delay-motion.lua
Normal file
64
plugins/10-delay-motion.lua
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- This is an example libinput plugin
|
||||
--
|
||||
-- This plugin delays any event with relative motion by the given DELAY
|
||||
-- by storing it in a table and replaying it via a timer callback later.
|
||||
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
|
||||
DELAY = 1500 * 1000 -- 1.5s
|
||||
next_timer_expiry = 0
|
||||
devices = {}
|
||||
|
||||
function timer_expired(time_in_microseconds)
|
||||
next_timer_expiry = 0
|
||||
for device, frames in pairs(devices) do
|
||||
while #frames > 0 and frames[1].time <= time_in_microseconds do
|
||||
--- we don't have a current frame so it doesn't matter
|
||||
--- whether we prepend or append
|
||||
device:prepend_frame(frames[1].frame)
|
||||
table.remove(frames, 1)
|
||||
end
|
||||
local next_frame = frames[1]
|
||||
if next_frame and (next_timer_expiry == 0 or next_frame.time < next_timer_expiry) then
|
||||
next_timer_expiry = next_frame.time
|
||||
end
|
||||
end
|
||||
if next_timer_expiry ~= 0 then
|
||||
libinput:timer_set_absolute(next_timer_expiry)
|
||||
end
|
||||
end
|
||||
|
||||
function frame(device, frame, timestamp)
|
||||
for _, v in ipairs(frame) do
|
||||
if v.usage == evdev.REL_X or v.usage == evdev.REL_Y then
|
||||
local next_time = timestamp + DELAY
|
||||
table.insert(devices[device], {
|
||||
time = next_time,
|
||||
frame = frame
|
||||
})
|
||||
if next_timer_expiry == 0 then
|
||||
next_timer_expiry = next_time
|
||||
libinput:timer_set_absolute(next_timer_expiry)
|
||||
end
|
||||
return {} -- discard frame
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function device_new(device)
|
||||
local usages = device:usages()
|
||||
if usages[evdev.REL_X] then
|
||||
devices[device] = {}
|
||||
device:connect("evdev-frame", frame)
|
||||
device:connect("device-removed", function(dev)
|
||||
devices[dev] = nil
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
libinput:connect("new-evdev-device", device_new)
|
||||
libinput:connect("timer-expired", timer_expired)
|
||||
16
plugins/10-disable-feature.lua
Normal file
16
plugins/10-disable-feature.lua
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- An example plugin to show how to disable an internal feature.
|
||||
--
|
||||
-- Typically one would expect the plugin to re-implement the feature
|
||||
-- in a more device-specific manner but that's not done here.
|
||||
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
libinput:connect("new-evdev-device", function(device)
|
||||
local udev_info = device:udev_properties()
|
||||
if udev_info["ID_INPUT_TOUCHPAD"] then
|
||||
libinput:log_info("Disabling palm detection on " .. device:name())
|
||||
device:disable_feature("touchpad-palm-detection")
|
||||
end
|
||||
end)
|
||||
40
plugins/10-dwt.lua
Normal file
40
plugins/10-dwt.lua
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- This plugin implements a very simple version of disable-while-typing.
|
||||
-- It monitors all keyboard devices and if any of them send an event,
|
||||
-- any touchpad device is disabled for 2 seconds.
|
||||
-- And "disabled" means any event from that touchpad is simply
|
||||
-- discarded.
|
||||
--
|
||||
-- Install this file in /etc/libinput/plugins and
|
||||
--
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
|
||||
tp_enabled = true
|
||||
|
||||
libinput:connect("timer-expired", function(now)
|
||||
libinput:log_debug("touchpad enabled")
|
||||
tp_enabled = true
|
||||
end)
|
||||
|
||||
libinput:connect("new-evdev-device", function (device)
|
||||
local props = device:udev_properties()
|
||||
if props.ID_INPUT_KEYBOARD then
|
||||
device:connect("evdev-frame", function (device, frame, timestamp)
|
||||
libinput:timer_set_relative(2000000)
|
||||
if tp_enabled then
|
||||
libinput:log_debug("touchpad disabled")
|
||||
tp_enabled = false
|
||||
end
|
||||
end)
|
||||
elseif props.ID_INPUT_TOUCHPAD then
|
||||
libinput:log_debug("Touchpad detected: " .. device:name())
|
||||
device:connect("evdev-frame", function (device, frame, timestamp)
|
||||
if not tp_enabled then
|
||||
-- Returning an empty table discards the event.
|
||||
return {}
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
87
plugins/10-example.lua
Normal file
87
plugins/10-example.lua
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- This is an example libinput plugin
|
||||
--
|
||||
-- This plugin swaps left and right buttons on any device that has both buttons.
|
||||
|
||||
-- Let's create a plugin. A single Lua script may create more than one
|
||||
-- plugin instance but that's a bit of a nice use-case. Most scripts
|
||||
-- should be a single plugin.
|
||||
|
||||
-- A plugin needs to be registered to activate. If it isn't, it is
|
||||
-- cleaned up immediately. In the register call we supply
|
||||
-- the list of plugin versions we support. Currently we only
|
||||
-- have version 1.
|
||||
--
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
|
||||
-- Note to the reader: it will be easier to understand this example
|
||||
-- if you read it bottom-up from here on.
|
||||
|
||||
-- The callback for our "evdev-frame" signal.
|
||||
-- These frames are sent *before* libinput gets to handle them so
|
||||
-- any modifications will affect libinput.
|
||||
function frame(device, frame, time_in_microseconds)
|
||||
-- Frame is a table in the form
|
||||
-- { { usage: 123, value: 3 }, ... }
|
||||
-- Let's use the evdev module to make it more readable, evdev.KEY_A
|
||||
-- is simply the value (0x1 << 16) | 0x1 (see linux/input-event-codes.h)
|
||||
for _, v in ipairs(frame) do
|
||||
-- If we get a right button event, change it to left, and
|
||||
-- vice versa. Because this happens before libinput (or the next
|
||||
-- plugin in the precedence order) sees the
|
||||
-- frame it doesn't know that the swap happened.
|
||||
if v.usage == evdev.BTN_RIGHT then
|
||||
v.usage = evdev.BTN_LEFT
|
||||
elseif v.usage == evdev.BTN_LEFT then
|
||||
v.usage = evdev.BTN_RIGHT
|
||||
end
|
||||
end
|
||||
-- We changed the frame, let's return it. If we return nil
|
||||
-- the original frame is being used as-is.
|
||||
return frame
|
||||
end
|
||||
|
||||
-- This is a timer callback. It is invoked after one second
|
||||
-- (see below) but only once - re-set the timer so
|
||||
-- it goes off every second.
|
||||
function timer_expired(time_in_microseconds)
|
||||
libinput:timer_set_absolute(time_in_microseconds + 1000000)
|
||||
end
|
||||
|
||||
-- Callback for the "new-evdev-device" signal, see below
|
||||
-- The argument is the EvdevDevice object, see the documentation.
|
||||
function device_new(device)
|
||||
-- A table of evdev usages available on our device.
|
||||
-- Using the evdev module makes it more readable but you can
|
||||
-- use numbers (which is what evdev.EV_KEY and
|
||||
-- friends resolve to anyway).
|
||||
local usages = device:usages()
|
||||
if usages[evdev.BTN_LEFT] and usages[evdev.BTN_RIGHT] then
|
||||
-- The "evdev-frame" callback is invoked whenever the device
|
||||
-- provided us with one evdev frame, i.e. a bunch of events up
|
||||
-- to excluding EV_SYN SYN_REPORT.
|
||||
device:connect("evdev-frame", frame)
|
||||
end
|
||||
|
||||
-- The device has udev information, let's print it out. Right
|
||||
-- now all we get are the ID_INPUT_ bits.
|
||||
-- If this is empty we know libinput will ignore this device anyway
|
||||
local udev_info = device:udev_properties()
|
||||
for k, v in pairs(udev_info) do
|
||||
libinput:log_debug(k .. "=" .. v)
|
||||
end
|
||||
end
|
||||
|
||||
-- Let's connect to the "new-evdev-device" signal. This function
|
||||
-- is invoked when libinput detects a new evdev device (but before
|
||||
-- that device is actually available to libinput as libinput device).
|
||||
-- This allows us to e.g. change properties on the device.
|
||||
libinput:connect("new-evdev-device", device_new)
|
||||
|
||||
-- Set our timer to expire 1s from now (in microseconds).
|
||||
-- Timers are absolute, so they need to be added to the
|
||||
-- current time
|
||||
libinput:connect("timer-expired", timer_expired)
|
||||
libinput:timer_set_relative(1000000)
|
||||
32
plugins/10-logitech-mx-master-horiz-scroll.lua
Normal file
32
plugins/10-logitech-mx-master-horiz-scroll.lua
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- This plugin inverts the horizontal scroll direction of
|
||||
-- the Logitech MX Master mouse. OOTB the mouse scrolls
|
||||
-- in the opposite direction to all other mice out there.
|
||||
--
|
||||
-- This plugin is only needed when the mouse is connected
|
||||
-- to the Logitech Bolt receiver - on that receiver we cannot
|
||||
-- tell which device is connected.
|
||||
--
|
||||
-- For the Logitech Unifying receiver and Bluetooth please
|
||||
-- add the ModelInvertHorizontalScrolling=1 quirk
|
||||
-- in quirks/30-vendor-logitech.quirks.
|
||||
--
|
||||
--
|
||||
-- Install this file in /etc/libinput/plugins and
|
||||
--
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
libinput:connect("new-evdev-device", function (device)
|
||||
local info = device:info()
|
||||
if info.vid == 0x046D and info.pid == 0xC548 then
|
||||
device:connect("evdev-frame", function (device, frame, timestamp)
|
||||
for _, event in ipairs(frame) do
|
||||
if event.usage == evdev.REL_HWHEEL or event.usage == evdev.REL_HWHEEL_HI_RES then
|
||||
event.value = -event.value
|
||||
end
|
||||
end
|
||||
return frame
|
||||
end)
|
||||
end
|
||||
end)
|
||||
22
plugins/10-pointer-go-faster.lua
Normal file
22
plugins/10-pointer-go-faster.lua
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- An example plugin to make the pointer go three times as fast
|
||||
--
|
||||
-- Install this file in /etc/libinput/plugins and
|
||||
--
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
libinput:connect("new-evdev-device", function(device)
|
||||
local usages = device:usages()
|
||||
if usages[evdev.REL_X] then
|
||||
device:connect("evdev-frame", function(device, frame, timestamp)
|
||||
for _, v in ipairs(frame) do
|
||||
if v.usage == evdev.REL_X or v.usage == evdev.REL_Y then
|
||||
-- Multiply the relative motion by 3
|
||||
v.value = v.value * 3
|
||||
end
|
||||
end
|
||||
return frame
|
||||
end)
|
||||
end
|
||||
end)
|
||||
56
plugins/10-pointer-go-slower.lua
Normal file
56
plugins/10-pointer-go-slower.lua
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- An example plugin to make the pointer go three times as slow
|
||||
--
|
||||
-- Install this file in /etc/libinput/plugins and
|
||||
--
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
remainders = {}
|
||||
|
||||
function split(v)
|
||||
if math.abs(v) >= 1.0 then
|
||||
local i = math.floor(math.abs(v))
|
||||
local r = math.abs(v) % 1.0
|
||||
if v < 0.0 then
|
||||
i = -i
|
||||
r = -r
|
||||
end
|
||||
return i, r
|
||||
else
|
||||
return 0, v
|
||||
end
|
||||
end
|
||||
|
||||
function decelerate(device, x, y)
|
||||
local remainder = remainders[device]
|
||||
local rx, ry = 0, 0
|
||||
if x ~= 0.0 then
|
||||
rx, remainder.x = split(remainder.x + x/3.0)
|
||||
end
|
||||
if y ~= 0.0 then
|
||||
ry, remainder.y = split(remainder.y + y/3.0)
|
||||
end
|
||||
|
||||
return rx, ry
|
||||
end
|
||||
|
||||
libinput:connect("new-evdev-device", function(device)
|
||||
local usages = device:usages()
|
||||
if usages[evdev.REL_X] then
|
||||
remainders[device] = { x = 0.0, y = 0.0 }
|
||||
device:connect("evdev-frame", function(device, frame, timestamp)
|
||||
for _, v in ipairs(frame) do
|
||||
if v.usage == evdev.REL_X then
|
||||
v.value, _ = decelerate(device, v.value, 0.0)
|
||||
elseif v.usage == evdev.REL_Y then
|
||||
_, v.value = decelerate(device, 0.0, v.value)
|
||||
end
|
||||
end
|
||||
return frame
|
||||
end)
|
||||
device:connect("device-removed", function(dev)
|
||||
remainders[dev] = nil
|
||||
end)
|
||||
end
|
||||
end)
|
||||
64
plugins/10-wheel-to-button.lua
Normal file
64
plugins/10-wheel-to-button.lua
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- This is an example libinput plugin
|
||||
--
|
||||
-- This plugin maps a downwards mouse wheel to a button down event and
|
||||
-- an upwards wheel movement to a button up event.
|
||||
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
|
||||
-- The button we want to press on wheel events
|
||||
local wheel_button = evdev.BTN_EXTRA
|
||||
local button_states = {}
|
||||
|
||||
local function evdev_frame(device, frame, timestamp)
|
||||
local events = {}
|
||||
local modified = false
|
||||
|
||||
for _, v in ipairs(frame) do
|
||||
if v.usage == evdev.REL_WHEEL then
|
||||
-- REL_WHEEL is inverted, neg value -> down, pos value -> up
|
||||
if v.value < 0 then
|
||||
if not button_states[device] then
|
||||
table.insert(events, { usage = wheel_button, value = 1 })
|
||||
button_states[device] = true
|
||||
end
|
||||
else
|
||||
if button_states[device] then
|
||||
table.insert(events, { usage = wheel_button, value = 0 })
|
||||
button_states[device] = false
|
||||
end
|
||||
end
|
||||
modified = true
|
||||
-- Because REL_WHEEL is no longer a wheel, the high-res
|
||||
-- events are dropped
|
||||
elseif v.usage == evdev.REL_WHEEL_HI_RES then
|
||||
modified = true
|
||||
else
|
||||
table.insert(events, v)
|
||||
end
|
||||
end
|
||||
|
||||
if modified then
|
||||
return events
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local function device_new(device)
|
||||
local usages = device:usages()
|
||||
if usages[evdev.REL_WHEEL] then
|
||||
button_states[device] = false
|
||||
if not usages[wheel_button] then
|
||||
device:enable_evdev_usage(wheel_button)
|
||||
end
|
||||
device:connect("evdev-frame", evdev_frame)
|
||||
device:connect("device-removed", function(dev)
|
||||
button_states[dev] = nil
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
libinput:connect("new-evdev-device", device_new)
|
||||
16
plugins/meson.build
Normal file
16
plugins/meson.build
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
plugins = [
|
||||
'10-example.lua',
|
||||
'10-dwt.lua',
|
||||
'10-logitech-mx-master-horiz-scroll.lua',
|
||||
'10-pointer-go-faster.lua',
|
||||
'10-pointer-go-slower.lua',
|
||||
'10-delay-motion.lua',
|
||||
'10-disable-feature.lua',
|
||||
'10-copilot-key-override.lua',
|
||||
'10-wheel-to-button.lua',
|
||||
]
|
||||
|
||||
fs = import('fs')
|
||||
foreach plugin : plugins
|
||||
fs.copyfile(plugin)
|
||||
endforeach
|
||||
|
|
@ -82,37 +82,45 @@ ModelInvertHorizontalScrolling=1
|
|||
MatchVendor=0x046D
|
||||
MatchProduct=0x4069
|
||||
ModelInvertHorizontalScrolling=1
|
||||
ModelScrollOnMiddleClick=1
|
||||
|
||||
# MX Master 2S has a different PID on bluetooth
|
||||
[Logitech MX Master 2S Bluetooth]
|
||||
MatchVendor=0x046D
|
||||
MatchProduct=0xB019
|
||||
ModelInvertHorizontalScrolling=1
|
||||
ModelScrollOnMiddleClick=1
|
||||
|
||||
[Logitech MX Master 3 USB]
|
||||
MatchVendor=0x046D
|
||||
MatchProduct=0x4082
|
||||
ModelInvertHorizontalScrolling=1
|
||||
ModelLogitechMXMaster3=1
|
||||
ModelScrollOnMiddleClick=1
|
||||
|
||||
# MX Master 3 has a different PID on bluetooth
|
||||
[Logitech MX Master 3 Bluetooth]
|
||||
MatchVendor=0x046D
|
||||
MatchProduct=0xB023
|
||||
ModelInvertHorizontalScrolling=1
|
||||
ModelLogitechMXMaster3=1
|
||||
ModelScrollOnMiddleClick=1
|
||||
|
||||
[Logitech MX Master 3S]
|
||||
MatchVendor=0x046D
|
||||
MatchProduct=0xB034
|
||||
ModelInvertHorizontalScrolling=1
|
||||
ModelLogitechMXMaster3=1
|
||||
ModelScrollOnMiddleClick=1
|
||||
|
||||
[Logitech MX Master 3B]
|
||||
MatchVendor=0x046D
|
||||
MatchProduct=0xB028
|
||||
ModelInvertHorizontalScrolling=1
|
||||
ModelLogitechMXMaster3=1
|
||||
ModelScrollOnMiddleClick=1
|
||||
|
||||
[Logitech MX Master 4]
|
||||
MatchVendor=0x046D
|
||||
MatchProduct=0xB042
|
||||
ModelInvertHorizontalScrolling=1
|
||||
ModelScrollOnMiddleClick=1
|
||||
|
||||
# Don't add quirks for the Logitech Bolt Receiver:
|
||||
# MatchVendor=0x046D
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ AttrKeyboardIntegration=internal
|
|||
MatchName=*Microsoft Surface *Cover*
|
||||
MatchDMIModalias=dmi:*svnMicrosoftCorporation:*
|
||||
AttrKeyboardIntegration=internal
|
||||
AttrEventCode=-BTN_0;
|
||||
|
||||
[Microsoft Surface Laptop Studio Touchpad]
|
||||
MatchVendor=0x045E
|
||||
|
|
|
|||
9
quirks/30-vendor-nulea.quirks
Normal file
9
quirks/30-vendor-nulea.quirks
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Nulea M501 does not name itself as a "Trackball"
|
||||
# In USB mode, it shares a generic dongle and name with other non-trackball
|
||||
# mice. As such, trackball quirks are enabled only for bluetooth modes.
|
||||
|
||||
[Nulea M501 Bluetooth Trackball]
|
||||
MatchBus=bluetooth
|
||||
MatchVendor=0x000E
|
||||
MatchProduct=0x3412
|
||||
ModelTrackball=1
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
[VirtualBox mouse integration]
|
||||
MatchName=*VirtualBox mouse integration*
|
||||
ModelBouncingKeys=1
|
||||
AttrIsVirtual=1
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
[QEMU/KVM mouse integration]
|
||||
MatchName=*spice vdagent tablet*
|
||||
ModelBouncingKeys=1
|
||||
AttrIsVirtual=1
|
||||
|
|
|
|||
|
|
@ -309,3 +309,24 @@ MatchBus=usb
|
|||
MatchVendor=0x1532
|
||||
MatchProduct=0x02B8
|
||||
AttrKeyboardIntegration=internal
|
||||
|
||||
[RazerBlade142025 Keyboard]
|
||||
MatchUdevType=keyboard
|
||||
MatchBus=usb
|
||||
MatchVendor=0x1532
|
||||
MatchProduct=0x02C5
|
||||
AttrKeyboardIntegration=internal
|
||||
|
||||
[RazerBlade162025 Keyboard]
|
||||
MatchUdevType=keyboard
|
||||
MatchBus=usb
|
||||
MatchVendor=0x1532
|
||||
MatchProduct=0x02C6
|
||||
AttrKeyboardIntegration=internal
|
||||
|
||||
[RazerBlade182025 Keyboard]
|
||||
MatchUdevType=keyboard
|
||||
MatchBus=usb
|
||||
MatchVendor=0x1532
|
||||
MatchProduct=0x02C7
|
||||
AttrKeyboardIntegration=internal
|
||||
|
|
|
|||
|
|
@ -7,6 +7,14 @@ MatchVendor=0x0002
|
|||
MatchProduct=0x0007
|
||||
ModelSynapticsSerialTouchpad=1
|
||||
|
||||
# "SYNA3580:00 06CB:CFD2 Touchpad": pressure touchpad mostly used in HP laptops.
|
||||
[Synaptics 06CB:CFD2 Touchpad]
|
||||
MatchBus=i2c
|
||||
MatchVendor=0x06CB
|
||||
MatchProduct=0xCFD2
|
||||
MatchUdevType=touchpad
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
# SYNA3602:00 0911:5288 touchpad, clickpad pretending it has a right button.
|
||||
# Integrated into several systems, including
|
||||
# Purism Librem 14v1
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
[VMWare Virtual PS/2 Mouse]
|
||||
MatchName=*VirtualPS/2 VMware VMMouse*
|
||||
ModelBouncingKeys=1
|
||||
AttrIsVirtual=1
|
||||
|
||||
[VMware VMware Virtual USB Mouse]
|
||||
MatchName=*VMware VMware Virtual USB Mouse*
|
||||
ModelBouncingKeys=1
|
||||
AttrIsVirtual=1
|
||||
|
|
|
|||
|
|
@ -47,3 +47,11 @@ AttrKeyboardIntegration=internal
|
|||
MatchName=AT Translated Set 2 keyboard
|
||||
MatchDMIModalias=dmi:*svnASUSTeKCOMPUTERINC.:pnROGFlowZ13GZ302EA_GZ302EA:*
|
||||
ModelTabletModeNoSuspend=1
|
||||
|
||||
# enable "disable touchpad while typing" to work with z13 keyboard
|
||||
[Asus ROG FLow Z13 2025 keyboard]
|
||||
MatchUdevType=keyboard
|
||||
MatchBus=usb
|
||||
MatchVendor=0x0B05
|
||||
MatchProduct=0x1A30
|
||||
AttrKeyboardIntegration=internal
|
||||
|
|
|
|||
|
|
@ -89,6 +89,16 @@ MatchName=*AT Translated Set 2 keyboard*
|
|||
MatchDMIModalias=dmi:*:svnDellInc.:pnLatitude7275:*
|
||||
ModelTabletModeNoSuspend=1
|
||||
|
||||
[Latitude 7285]
|
||||
MatchName=*AT Translated Set 2 keyboard*
|
||||
MatchDMIModalias=dmi:*:svnDellInc.:pnLatitude7285:*
|
||||
ModelTabletModeNoSuspend=1
|
||||
|
||||
[Dell Pro Rugged Tablet]
|
||||
MatchName=*AT Translated Set 2 keyboard*
|
||||
MatchDMIModalias=dmi:*:svnDellInc.:pnDellProRugged*TabletRA*:*
|
||||
ModelTabletModeNoSuspend=1
|
||||
|
||||
[Latitude 7480 Touchpad]
|
||||
MatchName=DLL07A0*
|
||||
MatchDMIModalias=dmi:**bvnDellInc.:*:pnLatitude7480*
|
||||
|
|
@ -126,13 +136,13 @@ ModelTabletModeNoSuspend=1
|
|||
MatchBus=i2c
|
||||
MatchVendor=0x27C6
|
||||
MatchProduct=0x0F60
|
||||
ModelPressurePad=1
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
[Dell Mayabay Touchpad]
|
||||
MatchBus=i2c
|
||||
MatchVendor=0x06CB
|
||||
MatchProduct=0xCFA0
|
||||
ModelPressurePad=1
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
[Dell Precision 5480]
|
||||
MatchBus=i2c
|
||||
|
|
@ -146,22 +156,58 @@ ModelTouchpadVisibleMarker=0
|
|||
MatchBus=i2c
|
||||
MatchVendor=0x06CB
|
||||
MatchProduct=0xCFF8
|
||||
ModelPressurePad=1
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
[Dell laptop 16 Synaptics touchpad]
|
||||
MatchBus=i2c
|
||||
MatchVendor=0x06CB
|
||||
MatchProduct=0xCFF9
|
||||
ModelPressurePad=1
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
[Dell laptop 14 Goodix touchpad]
|
||||
MatchBus=i2c
|
||||
MatchVendor=0x27C6
|
||||
MatchProduct=0x0F61
|
||||
ModelPressurePad=1
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
[Dell laptop 16 Goodix touchpad]
|
||||
MatchBus=i2c
|
||||
MatchVendor=0x27C6
|
||||
MatchProduct=0x0F62
|
||||
ModelPressurePad=1
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
[Dell 14 Premium DA14250 touchpad]
|
||||
MatchBus=i2c
|
||||
MatchVendor=0x0488
|
||||
MatchProduct=0x108C
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
[Dell 16 Premium DA16250 touchpad]
|
||||
MatchBus=i2c
|
||||
MatchVendor=0x0488
|
||||
MatchProduct=0x108D
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
[Dell laptop 14_1 Synaptics touchpad]
|
||||
MatchBus=i2c
|
||||
MatchVendor=0x06CB
|
||||
MatchProduct=0xD01D
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
[Dell laptop 16_1 Synaptics touchpad]
|
||||
MatchBus=i2c
|
||||
MatchVendor=0x06CB
|
||||
MatchProduct=0xD01A
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
[Dell laptop 14 Sensel touchpad]
|
||||
MatchBus=i2c
|
||||
MatchVendor=0x2C2F
|
||||
MatchProduct=0x0034
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
[Dell laptop 16 Sensel touchpad]
|
||||
MatchBus=i2c
|
||||
MatchVendor=0x2C2F
|
||||
MatchProduct=0x0033
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
|
|
|||
|
|
@ -178,3 +178,17 @@ ModelChromebook=1
|
|||
AttrPressureRange=0:-2
|
||||
AttrThumbPressureThreshold=45
|
||||
AttrPalmPressureThreshold=0
|
||||
|
||||
[Google Chromebook Roric]
|
||||
MatchUdevType=touchpad
|
||||
MatchName=PNP0C50:00 093A:3307 Touchpad
|
||||
MatchDMIModalias=dmi:*svnGoogle:pnRoric*
|
||||
ModelChromebook=1
|
||||
AttrPressureRange=20:10
|
||||
|
||||
[Google Chromebook Rull]
|
||||
MatchUdevType=touchpad
|
||||
MatchName=PNP0C50:00 093A:3307 Touchpad
|
||||
MatchDMIModalias=dmi:*svnGoogle:pnRull*
|
||||
ModelChromebook=1
|
||||
AttrPressureRange=20:10
|
||||
|
|
|
|||
|
|
@ -3,3 +3,9 @@ MatchName=HTIX5288:00 093A:0255 Touchpad
|
|||
MatchUdevType=touchpad
|
||||
MatchDMIModalias=dmi:*svnGPD:*pnG1619-*
|
||||
AttrEventCode=-BTN_RIGHT
|
||||
|
||||
[GPD MicroPC 2 Touchpad]
|
||||
MatchName=ALPS0001:00 36B6:C001 Touchpad
|
||||
MatchUdevType=touchpad
|
||||
MatchDMIModalias=dmi:*svnGPD:pnG1688-08:*
|
||||
AttrInputProp=-INPUT_PROP_BUTTONPAD
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# Clickpad that announces BTN_RIGHT
|
||||
# requires ModelPressurePad=1
|
||||
# requires AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
[HONOR MagicBook Art 14]
|
||||
MatchName=*TOPS0102*
|
||||
MatchDMIModalias=dmi:*svnHONOR:*pnMRA-XXX*
|
||||
MatchUdevType=touchpad
|
||||
AttrEventCode=-BTN_RIGHT
|
||||
ModelPressurePad=1
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
# Do not edit this file, it will be overwritten on update
|
||||
#
|
||||
|
||||
[HP Chromebook 14]
|
||||
MatchName=*Cypress APA Trackpad *cyapa*
|
||||
MatchDMIModalias=dmi:*svnHewlett-Packard*:pnFalco*
|
||||
AttrPressureRange=12:8
|
||||
|
||||
# Claims to have double/tripletap but doesn't actually send it
|
||||
# https://bugs.freedesktop.org/show_bug.cgi?id=98538
|
||||
[HP Compaq 6910p]
|
||||
|
|
@ -14,43 +19,59 @@ MatchName=*SynPS/2 Synaptics TouchPad
|
|||
MatchDMIModalias=dmi:*svnHewlett-Packard:*pnHPCompaq8510w*
|
||||
AttrEventCode=-BTN_TOOL_DOUBLETAP;-BTN_TOOL_TRIPLETAP;
|
||||
|
||||
[HP Elite x2 1013 G3 Keyboard]
|
||||
MatchUdevType=keyboard
|
||||
MatchBus=ps2
|
||||
MatchDMIModalias=dmi:*svnHP:pnHPElitex21013G3:*
|
||||
AttrKeyboardIntegration=external
|
||||
|
||||
[HP Elite x2 1013 G3 Tablet Mode Switch]
|
||||
MatchName=*Intel Virtual Button*
|
||||
MatchDMIModalias=dmi:*svnHP:pnHPElitex21013G3:*
|
||||
ModelTabletModeSwitchUnreliable=1
|
||||
|
||||
[HP Elite x2 1013 G3 Touchpad]
|
||||
MatchUdevType=touchpad
|
||||
MatchBus=usb
|
||||
MatchVendor=0x044E
|
||||
MatchProduct=0x1221
|
||||
AttrTPKComboLayout=below
|
||||
|
||||
# The HP OmniBook Ultra Flip Laptop 14-fh0xxx's custom Intel ISH firmware
|
||||
# filters out events from its builtin keyboard and touchpad when the hinge is
|
||||
# opened little more than 180 degrees but toggles tablet-mode when it's opened
|
||||
# little less than 180 degrees.
|
||||
# Do not suspend the keyboard and touchpad to let use the device in flat
|
||||
# position and also give consistency with some keyboard keys controlled by the
|
||||
# Video Bus device (brightness down/up), the HP WMI hotkeys device (mic mute and
|
||||
# hp hubs launcher key) and the backlight getting on and off by the firmware at
|
||||
# the same time it enables disables the input.
|
||||
# This one is for the keyboard and...
|
||||
[HP OmniBook Ultra Flip Laptop 14-fh0xxx Keyboard]
|
||||
MatchBus=ps2
|
||||
MatchUdevType=keyboard
|
||||
MatchDMIModalias=dmi:*:svnHP:pnHPOmniBookUltraFlipLaptop14-fh0xxx:*
|
||||
ModelTabletModeNoSuspend=1
|
||||
|
||||
# ...this one is for the touchpad.
|
||||
[HP OmniBook Ultra Flip Laptop 14-fh0xxx Touchpad]
|
||||
MatchBus=i2c
|
||||
MatchVendor=0x06CB
|
||||
MatchProduct=0xCFD2
|
||||
MatchUdevType=touchpad
|
||||
MatchDMIModalias=dmi:*:svnHP:pnHPOmniBookUltraFlipLaptop14-fh0xxx:*
|
||||
ModelTabletModeNoSuspend=1
|
||||
|
||||
[HP Pavilion dmi4]
|
||||
MatchName=*SynPS/2 Synaptics TouchPad
|
||||
MatchDMIModalias=dmi:*svnHewlett-Packard:*pnHPPaviliondm4NotebookPC*
|
||||
ModelHPPavilionDM4Touchpad=1
|
||||
|
||||
# Touchpad is a clickpad but INPUT_PROP_BUTTONPAD is not set, see
|
||||
# https://bugs.freedesktop.org/show_bug.cgi?id=97147
|
||||
[HP Stream 11]
|
||||
MatchName=SYN1EDE:00 06CB:7442*
|
||||
MatchDMIModalias=dmi:*svnHewlett-Packard:pnHPStreamNotebookPC11*
|
||||
AttrInputProp=+INPUT_PROP_BUTTONPAD
|
||||
|
||||
# The HP stream x360's embedded-controller filters out events form its builtin
|
||||
# keyboard when in tablet-mode itself; and it has a capacitive home-button
|
||||
# (windows logo) underneath its display which also sends PS/2 key-events.
|
||||
# Do not suspend the keyboard when in tablet-mode so that the home button
|
||||
# keeps working when in tablet-mode.
|
||||
[HP Stream x360 11]
|
||||
MatchName=AT Translated Set 2 keyboard
|
||||
MatchDMIModalias=dmi:*:svnHewlett-Packard:pnHPStreamx360ConvertiblePC11:*
|
||||
ModelTabletModeNoSuspend=1
|
||||
|
||||
[HP Spectre x360 Convertible 15-bl000]
|
||||
MatchName=AT Translated Set 2 keyboard
|
||||
MatchDMIModalias=dmi:*:svnHP:pnHPSpectrex360Convertible15-bl0XX:*
|
||||
ModelTabletModeNoSuspend=1
|
||||
|
||||
[HP ZBook Studio G3]
|
||||
MatchName=AlpsPS/2 ALPS GlidePoint
|
||||
MatchDMIModalias=dmi:*svnHP:pnHPZBookStudioG3:*
|
||||
ModelHPZBookStudioG3=1
|
||||
|
||||
[HP Chromebook 14]
|
||||
MatchName=*Cypress APA Trackpad *cyapa*
|
||||
MatchDMIModalias=dmi:*svnHewlett-Packard*:pnFalco*
|
||||
AttrPressureRange=12:8
|
||||
|
||||
[HP Spectre x360 Convertible 15-bl1xx]
|
||||
MatchUdevType=touchpad
|
||||
MatchName=*SynPS/2 Synaptics TouchPad
|
||||
|
|
@ -75,26 +96,24 @@ MatchName=AT Translated Set 2 keyboard
|
|||
MatchDMIModalias=dmi:*svnHP:pnHPSpectrex360Convertible15-ch0xx:*
|
||||
ModelTabletModeNoSuspend=1
|
||||
|
||||
[HP Elite x2 1013 G3 Tablet Mode Switch]
|
||||
MatchName=*Intel Virtual Button*
|
||||
MatchDMIModalias=dmi:*svnHP:pnHPElitex21013G3:*
|
||||
ModelTabletModeSwitchUnreliable=1
|
||||
# Touchpad is a clickpad but INPUT_PROP_BUTTONPAD is not set, see
|
||||
# https://bugs.freedesktop.org/show_bug.cgi?id=97147
|
||||
[HP Stream 11]
|
||||
MatchName=SYN1EDE:00 06CB:7442*
|
||||
MatchDMIModalias=dmi:*svnHewlett-Packard:pnHPStreamNotebookPC11*
|
||||
AttrInputProp=+INPUT_PROP_BUTTONPAD
|
||||
|
||||
[HP Elite x2 1013 G3 Touchpad]
|
||||
MatchUdevType=touchpad
|
||||
MatchBus=usb
|
||||
MatchVendor=0x044E
|
||||
MatchProduct=0x1221
|
||||
AttrTPKComboLayout=below
|
||||
# The HP stream x360's embedded-controller filters out events form its builtin
|
||||
# keyboard when in tablet-mode itself; and it has a capacitive home-button
|
||||
# (windows logo) underneath its display which also sends PS/2 key-events.
|
||||
# Do not suspend the keyboard when in tablet-mode so that the home button
|
||||
# keeps working when in tablet-mode.
|
||||
[HP Stream x360 11]
|
||||
MatchName=AT Translated Set 2 keyboard
|
||||
MatchDMIModalias=dmi:*:svnHewlett-Packard:pnHPStreamx360ConvertiblePC11:*
|
||||
ModelTabletModeNoSuspend=1
|
||||
|
||||
[HP Elite x2 1013 G3 Keyboard]
|
||||
MatchUdevType=keyboard
|
||||
MatchBus=ps2
|
||||
MatchDMIModalias=dmi:*svnHP:pnHPElitex21013G3:*
|
||||
AttrKeyboardIntegration=external
|
||||
|
||||
[HP Haptics Touchpad CFD2]
|
||||
MatchBus=i2c
|
||||
MatchVendor=0x06CB
|
||||
MatchProduct=0xCFD2
|
||||
ModelPressurePad=1
|
||||
[HP ZBook Studio G3]
|
||||
MatchName=AlpsPS/2 ALPS GlidePoint
|
||||
MatchDMIModalias=dmi:*svnHP:pnHPZBookStudioG3:*
|
||||
ModelHPZBookStudioG3=1
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ MatchUdevType=touchpad
|
|||
MatchDMIModalias=dmi:*svnHUAWEI:*pnMRGF-XX*
|
||||
AttrEventCode=-BTN_RIGHT
|
||||
|
||||
# 2024 model requires ModelPressurePad=1
|
||||
# 2024 model requires AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
[Huawei MateBook X Pro 2024 Touchpad]
|
||||
MatchName=GXTP7863:00 27C6:01E0 Touchpad
|
||||
MatchUdevType=touchpad
|
||||
MatchDMIModalias=dmi:*svnHUAWEI:*pnVGHH-XX*
|
||||
AttrEventCode=-BTN_RIGHT
|
||||
ModelPressurePad=1
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ AttrTrackpointMultiplier=1.25
|
|||
MatchBus=i2c
|
||||
MatchVendor=0x06CB
|
||||
MatchProduct=0xCE37
|
||||
ModelPressurePad=1
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
[Lenovo Yoga C930 Tablet]
|
||||
MatchBus=i2c
|
||||
|
|
@ -317,7 +317,7 @@ AttrKeyboardIntegration=internal
|
|||
MatchBus=i2c
|
||||
MatchVendor=0x27C6
|
||||
MatchProduct=0x01E8
|
||||
ModelPressurePad=1
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
# Duet 7i tablet switch activated by folding keyboard cover, or removing it.
|
||||
# We must not disable volume rocker 'keyboard'.
|
||||
|
|
@ -360,6 +360,12 @@ MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadE14Gen2*
|
|||
AttrPalmPressureThreshold=300
|
||||
AttrPressureRange=10:8
|
||||
|
||||
[Lenovo ThinkPad E16 Gen 3]
|
||||
MatchUdevType=pointingstick
|
||||
MatchName=*TPPS/2 Elan TrackPoint*
|
||||
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadE16Gen3*
|
||||
AttrTrackpointMultiplier=0.5
|
||||
|
||||
# White Backlit Keyboard
|
||||
[Lenovo Ideapad Gaming 3]
|
||||
MatchUdevType=keyboard
|
||||
|
|
@ -388,14 +394,14 @@ AttrKeyboardIntegration=internal
|
|||
MatchName=*GXTP5100*
|
||||
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkBook*G7+ASP*:*
|
||||
MatchUdevType=touchpad
|
||||
ModelPressurePad=1
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
# The ThinkBook 14/16 G6+ IMH also has a similar issue as the G7+ mentioned above.
|
||||
[Lenovo ThinkBook G6+ IMH]
|
||||
MatchName=*GXTP5100*
|
||||
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkBook*G6+IMH*:*
|
||||
MatchUdevType=touchpad
|
||||
ModelPressurePad=1
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
# Lenovo Yoga Slim 7i Carbon sends bogus ABS_MT_TOOL_TYPE MT_TOOL_PALM events
|
||||
[Lenovo Yoga Slim 7i Carbon]
|
||||
|
|
@ -409,11 +415,11 @@ AttrEventCode=-ABS_MT_TOOL_TYPE
|
|||
MatchName=*GXTP5100*
|
||||
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX9-15Gen1*:*
|
||||
MatchUdevType=touchpad
|
||||
ModelPressurePad=1
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
||||
# The ThinkBook 14/16 G7+ IAH also has a similar issue as the ASP mentioned above.
|
||||
[Lenovo ThinkBook G7+ IAH touchpad]
|
||||
MatchName=*GXTP5100*
|
||||
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkBook*G7+IAH*:*
|
||||
MatchUdevType=touchpad
|
||||
ModelPressurePad=1
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
|
|
|||
5
quirks/50-system-tongfang.quirks
Normal file
5
quirks/50-system-tongfang.quirks
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
[TongFang GX4 (X4SP4NAL) Touchpad]
|
||||
MatchName=UNIW0001:00 093A:0255 Touchpad
|
||||
MatchUdevType=touchpad
|
||||
MatchDMIModalias=dmi:*svnAiStone:pnX4SP4NAL:*
|
||||
AttrEventCode=-BTN_RIGHT
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
static void
|
||||
fallback_keyboard_notify_key(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
evdev_usage_t usage,
|
||||
enum libinput_key_state state)
|
||||
{
|
||||
|
|
@ -53,7 +53,7 @@ fallback_keyboard_notify_key(struct fallback_dispatch *dispatch,
|
|||
static void
|
||||
fallback_lid_notify_toggle(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
if (dispatch->lid.is_closed ^ dispatch->lid.is_closed_client_state) {
|
||||
switch_notify_toggle(&device->base,
|
||||
|
|
@ -67,7 +67,7 @@ fallback_lid_notify_toggle(struct fallback_dispatch *dispatch,
|
|||
void
|
||||
fallback_notify_physical_button(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
evdev_usage_t button,
|
||||
enum libinput_button_state state)
|
||||
{
|
||||
|
|
@ -82,20 +82,23 @@ fallback_interface_get_switch_state(struct evdev_dispatch *evdev_dispatch,
|
|||
|
||||
switch (sw) {
|
||||
case LIBINPUT_SWITCH_TABLET_MODE:
|
||||
return dispatch->tablet_mode.sw.state ? LIBINPUT_SWITCH_STATE_ON
|
||||
: LIBINPUT_SWITCH_STATE_OFF;
|
||||
break;
|
||||
case LIBINPUT_SWITCH_KEYPAD_SLIDE:
|
||||
return dispatch->keypad_slide.sw.state ? LIBINPUT_SWITCH_STATE_ON
|
||||
: LIBINPUT_SWITCH_STATE_OFF;
|
||||
break;
|
||||
default:
|
||||
/* Internal function only, so we can abort here */
|
||||
abort();
|
||||
}
|
||||
|
||||
return dispatch->tablet_mode.sw.state ? LIBINPUT_SWITCH_STATE_ON
|
||||
: LIBINPUT_SWITCH_STATE_OFF;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
post_button_scroll(struct evdev_device *device,
|
||||
struct device_float_coords raw,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
if (device->scroll.method != LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN)
|
||||
return false;
|
||||
|
|
@ -117,7 +120,8 @@ post_button_scroll(struct evdev_device *device,
|
|||
filter_dispatch_scroll(device->pointer.filter,
|
||||
&raw,
|
||||
device,
|
||||
time);
|
||||
time,
|
||||
FILTER_SCROLL_TYPE_CONTINUOUS);
|
||||
evdev_post_scroll(device,
|
||||
time,
|
||||
LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
|
||||
|
|
@ -170,7 +174,7 @@ fallback_rotate_relative(struct fallback_dispatch *dispatch,
|
|||
static void
|
||||
fallback_flush_relative_motion(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct normalized_coords accel;
|
||||
|
|
@ -204,12 +208,8 @@ fallback_flush_relative_motion(struct fallback_dispatch *dispatch,
|
|||
static void
|
||||
fallback_flush_wheels(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct normalized_coords wheel_degrees = { 0.0, 0.0 };
|
||||
struct discrete_coords discrete = { 0.0, 0.0 };
|
||||
struct wheel_v120 v120 = { 0.0, 0.0 };
|
||||
|
||||
if (!libinput_device_has_capability(&device->base, LIBINPUT_DEVICE_CAP_POINTER))
|
||||
return;
|
||||
|
||||
|
|
@ -225,7 +225,8 @@ fallback_flush_wheels(struct fallback_dispatch *dispatch,
|
|||
filter_dispatch_scroll(device->pointer.filter,
|
||||
&raw,
|
||||
device,
|
||||
time);
|
||||
time,
|
||||
FILTER_SCROLL_TYPE_WHEEL);
|
||||
evdev_post_scroll(device,
|
||||
time,
|
||||
LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
|
||||
|
|
@ -238,66 +239,93 @@ fallback_flush_wheels(struct fallback_dispatch *dispatch,
|
|||
return;
|
||||
}
|
||||
|
||||
if (dispatch->wheel.hi_res.y != 0) {
|
||||
int value = dispatch->wheel.hi_res.y;
|
||||
|
||||
v120.y = -1 * value;
|
||||
wheel_degrees.y =
|
||||
-1 * value / 120.0 * device->scroll.wheel_click_angle.y;
|
||||
evdev_notify_axis_wheel(device,
|
||||
time,
|
||||
bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
|
||||
&wheel_degrees,
|
||||
&v120);
|
||||
/* High-resolution wheel events */
|
||||
if (dispatch->wheel.hi_res.x != 0 || dispatch->wheel.hi_res.y != 0) {
|
||||
const struct device_float_coords v120_unaccelerated = {
|
||||
.x = dispatch->wheel.hi_res.x,
|
||||
.y = -1 * dispatch->wheel.hi_res.y,
|
||||
};
|
||||
const struct normalized_coords v120_accelerated =
|
||||
device->pointer.filter
|
||||
? filter_dispatch_scroll(device->pointer.filter,
|
||||
&v120_unaccelerated,
|
||||
device,
|
||||
time,
|
||||
FILTER_SCROLL_TYPE_WHEEL)
|
||||
: (const struct normalized_coords){
|
||||
.x = v120_unaccelerated.x,
|
||||
.y = v120_unaccelerated.y
|
||||
};
|
||||
/* Truncate the fractional part when converting floating-point to
|
||||
integer. This is acceptable because the v120 unit maps one logical
|
||||
click to 120 units; values are effectively measured in 1/120 of a
|
||||
click, so truncation does not lose meaningful resolution. */
|
||||
const struct wheel_v120 v120 = {
|
||||
.x = v120_accelerated.x,
|
||||
.y = v120_accelerated.y,
|
||||
};
|
||||
const struct normalized_coords wheel_degrees = {
|
||||
.x = v120.x / 120.0 * device->scroll.wheel_click_angle.x,
|
||||
.y = v120.y / 120.0 * device->scroll.wheel_click_angle.y,
|
||||
};
|
||||
if (v120.x != 0) {
|
||||
evdev_notify_axis_wheel(
|
||||
device,
|
||||
time,
|
||||
bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL),
|
||||
&wheel_degrees,
|
||||
&v120);
|
||||
}
|
||||
if (v120.y != 0) {
|
||||
evdev_notify_axis_wheel(
|
||||
device,
|
||||
time,
|
||||
bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
|
||||
&wheel_degrees,
|
||||
&v120);
|
||||
}
|
||||
dispatch->wheel.hi_res.x = 0;
|
||||
dispatch->wheel.hi_res.y = 0;
|
||||
}
|
||||
|
||||
if (dispatch->wheel.lo_res.y != 0) {
|
||||
int value = dispatch->wheel.lo_res.y;
|
||||
|
||||
wheel_degrees.y = -1 * value * device->scroll.wheel_click_angle.y;
|
||||
discrete.y = -1 * value;
|
||||
evdev_notify_axis_legacy_wheel(
|
||||
device,
|
||||
time,
|
||||
bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
|
||||
&wheel_degrees,
|
||||
&discrete);
|
||||
dispatch->wheel.lo_res.y = 0;
|
||||
}
|
||||
|
||||
if (dispatch->wheel.hi_res.x != 0) {
|
||||
int value = dispatch->wheel.hi_res.x;
|
||||
|
||||
v120.x = value;
|
||||
wheel_degrees.x = value / 120.0 * device->scroll.wheel_click_angle.x;
|
||||
evdev_notify_axis_wheel(device,
|
||||
time,
|
||||
bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL),
|
||||
&wheel_degrees,
|
||||
&v120);
|
||||
dispatch->wheel.hi_res.x = 0;
|
||||
}
|
||||
|
||||
if (dispatch->wheel.lo_res.x != 0) {
|
||||
int value = dispatch->wheel.lo_res.x;
|
||||
|
||||
wheel_degrees.x = value * device->scroll.wheel_click_angle.x;
|
||||
discrete.x = value;
|
||||
evdev_notify_axis_legacy_wheel(
|
||||
device,
|
||||
time,
|
||||
bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL),
|
||||
&wheel_degrees,
|
||||
&discrete);
|
||||
/* Low-resolution wheel events */
|
||||
if (dispatch->wheel.lo_res.x != 0 || dispatch->wheel.lo_res.y != 0) {
|
||||
/* Do not accelerate low-resolution wheel events: they use different
|
||||
units than high-resolution events and should not be accelerated with
|
||||
the same function. */
|
||||
const struct discrete_coords discrete = {
|
||||
.x = dispatch->wheel.lo_res.x,
|
||||
.y = -1 * dispatch->wheel.lo_res.y,
|
||||
};
|
||||
const struct normalized_coords wheel_degrees = {
|
||||
.x = discrete.x * device->scroll.wheel_click_angle.x,
|
||||
.y = discrete.y * device->scroll.wheel_click_angle.y,
|
||||
};
|
||||
if (discrete.x != 0) {
|
||||
evdev_notify_axis_legacy_wheel(
|
||||
device,
|
||||
time,
|
||||
bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL),
|
||||
&wheel_degrees,
|
||||
&discrete);
|
||||
}
|
||||
if (discrete.y != 0) {
|
||||
evdev_notify_axis_legacy_wheel(
|
||||
device,
|
||||
time,
|
||||
bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
|
||||
&wheel_degrees,
|
||||
&discrete);
|
||||
}
|
||||
dispatch->wheel.lo_res.x = 0;
|
||||
dispatch->wheel.lo_res.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fallback_flush_absolute_motion(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct device_coords point;
|
||||
|
|
@ -315,7 +343,7 @@ static bool
|
|||
fallback_flush_mt_down(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
int slot_idx,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct libinput_seat *seat = base->seat;
|
||||
|
|
@ -354,7 +382,7 @@ static bool
|
|||
fallback_flush_mt_motion(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
int slot_idx,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct device_coords point;
|
||||
|
|
@ -384,7 +412,7 @@ static bool
|
|||
fallback_flush_mt_up(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
int slot_idx,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct libinput_seat *seat = base->seat;
|
||||
|
|
@ -412,7 +440,7 @@ static bool
|
|||
fallback_flush_mt_cancel(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
int slot_idx,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct libinput_seat *seat = base->seat;
|
||||
|
|
@ -439,7 +467,7 @@ fallback_flush_mt_cancel(struct fallback_dispatch *dispatch,
|
|||
static bool
|
||||
fallback_flush_st_down(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct libinput_seat *seat = base->seat;
|
||||
|
|
@ -475,7 +503,7 @@ fallback_flush_st_down(struct fallback_dispatch *dispatch,
|
|||
static bool
|
||||
fallback_flush_st_motion(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct device_coords point;
|
||||
|
|
@ -497,7 +525,7 @@ fallback_flush_st_motion(struct fallback_dispatch *dispatch,
|
|||
static bool
|
||||
fallback_flush_st_up(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct libinput_seat *seat = base->seat;
|
||||
|
|
@ -522,7 +550,7 @@ fallback_flush_st_up(struct fallback_dispatch *dispatch,
|
|||
static bool
|
||||
fallback_flush_st_cancel(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct libinput_seat *seat = base->seat;
|
||||
|
|
@ -547,7 +575,7 @@ fallback_flush_st_cancel(struct fallback_dispatch *dispatch,
|
|||
static void
|
||||
fallback_process_touch_button(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
int value)
|
||||
{
|
||||
dispatch->pending_event |=
|
||||
|
|
@ -558,7 +586,7 @@ static inline void
|
|||
fallback_process_key(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
/* ignore kernel key repeat */
|
||||
if (e->value == 2)
|
||||
|
|
@ -600,7 +628,7 @@ static void
|
|||
fallback_process_touch(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct mt_slot *slot = &dispatch->mt.slots[dispatch->mt.slot];
|
||||
|
||||
|
|
@ -701,7 +729,7 @@ fallback_process_absolute_motion(struct fallback_dispatch *dispatch,
|
|||
}
|
||||
|
||||
static void
|
||||
fallback_lid_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
|
||||
fallback_lid_keyboard_event(usec_t time, struct libinput_event *event, void *data)
|
||||
{
|
||||
struct fallback_dispatch *dispatch = fallback_dispatch(data);
|
||||
|
||||
|
|
@ -716,8 +744,8 @@ fallback_lid_keyboard_event(uint64_t time, struct libinput_event *event, void *d
|
|||
int rc;
|
||||
struct input_event ev[2];
|
||||
|
||||
ev[0] = input_event_init(0, EV_SW, SW_LID, 0);
|
||||
ev[1] = input_event_init(0, EV_SYN, SYN_REPORT, 0);
|
||||
ev[0] = input_event_init(usec_from_uint64_t(0), EV_SW, SW_LID, 0);
|
||||
ev[1] = input_event_init(usec_from_uint64_t(0), EV_SYN, SYN_REPORT, 0);
|
||||
|
||||
rc = write(fd, ev, sizeof(ev));
|
||||
|
||||
|
|
@ -775,7 +803,7 @@ static inline void
|
|||
fallback_process_switch(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
enum libinput_switch_state state;
|
||||
bool is_closed;
|
||||
|
|
@ -808,6 +836,20 @@ fallback_process_switch(struct fallback_dispatch *dispatch,
|
|||
LIBINPUT_SWITCH_TABLET_MODE,
|
||||
state);
|
||||
break;
|
||||
case EVDEV_SW_KEYPAD_SLIDE:
|
||||
if (dispatch->keypad_slide.sw.state == e->value)
|
||||
return;
|
||||
|
||||
dispatch->keypad_slide.sw.state = e->value;
|
||||
if (e->value)
|
||||
state = LIBINPUT_SWITCH_STATE_ON;
|
||||
else
|
||||
state = LIBINPUT_SWITCH_STATE_OFF;
|
||||
switch_notify_toggle(&device->base,
|
||||
time,
|
||||
LIBINPUT_SWITCH_KEYPAD_SLIDE,
|
||||
state);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -816,7 +858,7 @@ fallback_process_switch(struct fallback_dispatch *dispatch,
|
|||
static inline bool
|
||||
fallback_reject_relative(struct evdev_device *device,
|
||||
const struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (evdev_usage_enum(e->usage)) {
|
||||
case EVDEV_REL_X:
|
||||
|
|
@ -851,7 +893,7 @@ static inline void
|
|||
fallback_process_relative(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
if (fallback_reject_relative(device, e, time))
|
||||
return;
|
||||
|
|
@ -890,7 +932,7 @@ static inline void
|
|||
fallback_process_absolute(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
if (device->is_mt) {
|
||||
fallback_process_touch(dispatch, device, e, time);
|
||||
|
|
@ -934,7 +976,7 @@ fallback_arbitrate_touch(struct fallback_dispatch *dispatch, struct mt_slot *slo
|
|||
static inline bool
|
||||
fallback_flush_mt_events(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
bool sent = false;
|
||||
|
||||
|
|
@ -1005,7 +1047,7 @@ fallback_flush_mt_events(struct fallback_dispatch *dispatch,
|
|||
static void
|
||||
fallback_handle_state(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
bool need_touch_frame = false;
|
||||
|
||||
|
|
@ -1073,7 +1115,7 @@ static void
|
|||
fallback_interface_process_event(struct evdev_dispatch *evdev_dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct fallback_dispatch *dispatch = fallback_dispatch(evdev_dispatch);
|
||||
static bool warned = false;
|
||||
|
|
@ -1113,7 +1155,7 @@ static void
|
|||
fallback_interface_process(struct evdev_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
size_t nevents;
|
||||
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
|
||||
|
|
@ -1127,7 +1169,7 @@ static void
|
|||
cancel_touches(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
const struct device_coord_rect *rect,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
unsigned int idx;
|
||||
bool need_frame = false;
|
||||
|
|
@ -1158,7 +1200,7 @@ cancel_touches(struct fallback_dispatch *dispatch,
|
|||
static void
|
||||
release_pressed_keys(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
for (evdev_usage_t usage = evdev_usage_from(EVDEV_KEY_RESERVED);
|
||||
evdev_usage_le(usage, EVDEV_KEY_MAX);
|
||||
|
|
@ -1208,9 +1250,9 @@ fallback_return_to_neutral_state(struct fallback_dispatch *dispatch,
|
|||
struct evdev_device *device)
|
||||
{
|
||||
struct libinput *libinput = evdev_libinput_context(device);
|
||||
uint64_t time;
|
||||
usec_t time = libinput_now(libinput);
|
||||
|
||||
if ((time = libinput_now(libinput)) == 0)
|
||||
if (usec_is_zero(time))
|
||||
return;
|
||||
|
||||
cancel_touches(dispatch, device, NULL, time);
|
||||
|
|
@ -1250,7 +1292,7 @@ fallback_interface_sync_initial_state(struct evdev_device *device,
|
|||
struct evdev_dispatch *evdev_dispatch)
|
||||
{
|
||||
struct fallback_dispatch *dispatch = fallback_dispatch(evdev_dispatch);
|
||||
uint64_t time = libinput_now(evdev_libinput_context(device));
|
||||
usec_t time = libinput_now(evdev_libinput_context(device));
|
||||
|
||||
if (device->tags & EVDEV_TAG_LID_SWITCH) {
|
||||
struct libevdev *evdev = device->evdev;
|
||||
|
|
@ -1278,13 +1320,20 @@ fallback_interface_sync_initial_state(struct evdev_device *device,
|
|||
LIBINPUT_SWITCH_TABLET_MODE,
|
||||
LIBINPUT_SWITCH_STATE_ON);
|
||||
}
|
||||
|
||||
if (dispatch->keypad_slide.sw.state) {
|
||||
switch_notify_toggle(&device->base,
|
||||
time,
|
||||
LIBINPUT_SWITCH_KEYPAD_SLIDE,
|
||||
LIBINPUT_SWITCH_STATE_ON);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fallback_interface_update_rect(struct evdev_dispatch *evdev_dispatch,
|
||||
struct evdev_device *device,
|
||||
const struct phys_rect *phys_rect,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct fallback_dispatch *dispatch = fallback_dispatch(evdev_dispatch);
|
||||
struct device_coord_rect rect;
|
||||
|
|
@ -1303,7 +1352,7 @@ fallback_interface_toggle_touch(struct evdev_dispatch *evdev_dispatch,
|
|||
struct evdev_device *device,
|
||||
enum evdev_arbitration_state which,
|
||||
const struct phys_rect *phys_rect,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct fallback_dispatch *dispatch = fallback_dispatch(evdev_dispatch);
|
||||
struct device_coord_rect rect = { 0 };
|
||||
|
|
@ -1322,7 +1371,7 @@ fallback_interface_toggle_touch(struct evdev_dispatch *evdev_dispatch,
|
|||
* arbitration by just a little bit so that any touch in
|
||||
* event is caught as palm touch. */
|
||||
libinput_timer_set(&dispatch->arbitration.arbitration_timer,
|
||||
time + ms2us(90));
|
||||
usec_add_millis(time, 90));
|
||||
state = "not-active";
|
||||
break;
|
||||
case ARBITRATION_IGNORE_RECT:
|
||||
|
|
@ -1416,9 +1465,7 @@ fallback_suspend(struct fallback_dispatch *dispatch, struct evdev_device *device
|
|||
}
|
||||
|
||||
static void
|
||||
fallback_tablet_mode_switch_event(uint64_t time,
|
||||
struct libinput_event *event,
|
||||
void *data)
|
||||
fallback_tablet_mode_switch_event(usec_t time, struct libinput_event *event, void *data)
|
||||
{
|
||||
struct fallback_dispatch *dispatch = data;
|
||||
struct evdev_device *device = dispatch->device;
|
||||
|
|
@ -1708,11 +1755,16 @@ fallback_dispatch_init_switch(struct fallback_dispatch *dispatch,
|
|||
dispatch->tablet_mode.sw.state = val;
|
||||
}
|
||||
|
||||
if (device->tags & EVDEV_TAG_KEYPAD_SLIDE_SWITCH) {
|
||||
val = libevdev_get_event_value(device->evdev, EV_SW, SW_KEYPAD_SLIDE);
|
||||
dispatch->keypad_slide.sw.state = val;
|
||||
}
|
||||
|
||||
libinput_device_init_event_listener(&dispatch->tablet_mode.other.listener);
|
||||
}
|
||||
|
||||
static void
|
||||
fallback_arbitration_timeout(uint64_t now, void *data)
|
||||
fallback_arbitration_timeout(usec_t now, void *data)
|
||||
{
|
||||
struct fallback_dispatch *dispatch = data;
|
||||
|
||||
|
|
|
|||
|
|
@ -116,6 +116,13 @@ struct fallback_dispatch {
|
|||
} other;
|
||||
} tablet_mode;
|
||||
|
||||
struct {
|
||||
/* Switch */
|
||||
struct {
|
||||
int state;
|
||||
} sw;
|
||||
} keypad_slide;
|
||||
|
||||
/* Bitmask of pressed keys used to ignore initial release events from
|
||||
* the kernel. */
|
||||
unsigned long hw_key_mask[NLONGS(KEY_CNT)];
|
||||
|
|
@ -213,11 +220,11 @@ get_key_down_count(struct evdev_device *device, evdev_usage_t usage)
|
|||
}
|
||||
|
||||
void
|
||||
fallback_debounce_handle_state(struct fallback_dispatch *dispatch, uint64_t time);
|
||||
fallback_debounce_handle_state(struct fallback_dispatch *dispatch, usec_t time);
|
||||
void
|
||||
fallback_notify_physical_button(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
evdev_usage_t button,
|
||||
enum libinput_button_state state);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <linux/input.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "util-bits.h"
|
||||
#include "util-input-event.h"
|
||||
#include "util-mem.h"
|
||||
#include "util-newtype.h"
|
||||
|
|
@ -49,6 +50,10 @@ enum evdev_usage {
|
|||
|
||||
EVDEV_KEY_RESERVED = _evbit(EV_KEY, KEY_RESERVED),
|
||||
EVDEV_KEY_ESC = _evbit(EV_KEY, KEY_ESC),
|
||||
EVDEV_KEY_A = _evbit(EV_KEY, KEY_A),
|
||||
EVDEV_KEY_CAPSLOCK = _evbit(EV_KEY, KEY_CAPSLOCK),
|
||||
EVDEV_KEY_KP7 = _evbit(EV_KEY, KEY_KP7),
|
||||
EVDEV_KEY_KPDOT = _evbit(EV_KEY, KEY_KPDOT),
|
||||
EVDEV_KEY_MICMUTE = _evbit(EV_KEY, KEY_MICMUTE),
|
||||
EVDEV_KEY_OK = _evbit(EV_KEY, KEY_OK),
|
||||
EVDEV_KEY_LIGHTS_TOGGLE = _evbit(EV_KEY, KEY_LIGHTS_TOGGLE),
|
||||
|
|
@ -134,6 +139,7 @@ enum evdev_usage {
|
|||
|
||||
EVDEV_SW_LID = _evbit(EV_SW, SW_LID),
|
||||
EVDEV_SW_TABLET_MODE = _evbit(EV_SW, SW_TABLET_MODE),
|
||||
EVDEV_SW_KEYPAD_SLIDE = _evbit(EV_SW, SW_KEYPAD_SLIDE),
|
||||
EVDEV_SW_MAX = _evbit(EV_SW, SW_MAX),
|
||||
|
||||
EVDEV_MSC_SCAN = _evbit(EV_MSC, MSC_SCAN),
|
||||
|
|
@ -150,6 +156,110 @@ enum evdev_usage {
|
|||
*/
|
||||
DECLARE_NEWTYPE(evdev_usage, uint32_t);
|
||||
|
||||
static inline const char *
|
||||
evdev_usage_name(evdev_usage_t usage)
|
||||
{
|
||||
switch (evdev_usage_as_uint32_t(usage)) {
|
||||
CASE_RETURN_STRING(EVDEV_SYN_REPORT);
|
||||
|
||||
CASE_RETURN_STRING(EVDEV_KEY_RESERVED);
|
||||
CASE_RETURN_STRING(EVDEV_KEY_ESC);
|
||||
CASE_RETURN_STRING(EVDEV_KEY_MICMUTE);
|
||||
CASE_RETURN_STRING(EVDEV_KEY_OK);
|
||||
CASE_RETURN_STRING(EVDEV_KEY_LIGHTS_TOGGLE);
|
||||
CASE_RETURN_STRING(EVDEV_KEY_ALS_TOGGLE);
|
||||
CASE_RETURN_STRING(EVDEV_KEY_MAX);
|
||||
|
||||
CASE_RETURN_STRING(EVDEV_BTN_LEFT);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_RIGHT);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_MIDDLE);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_SIDE);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_EXTRA);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_FORWARD);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_BACK);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TASK);
|
||||
|
||||
CASE_RETURN_STRING(EVDEV_BTN_JOYSTICK);
|
||||
|
||||
CASE_RETURN_STRING(EVDEV_BTN_0);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_1);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_2);
|
||||
|
||||
CASE_RETURN_STRING(EVDEV_BTN_STYLUS);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_STYLUS2);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_STYLUS3);
|
||||
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TOUCH);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TOOL_PEN);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TOOL_RUBBER);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TOOL_BRUSH);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TOOL_PENCIL);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TOOL_AIRBRUSH);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TOOL_MOUSE);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TOOL_LENS);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TOOL_QUINTTAP);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TOOL_DOUBLETAP);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TOOL_TRIPLETAP);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TOOL_QUADTAP);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TOOL_FINGER);
|
||||
/* CASE_RETURN_STRING(EVDEV_BTN_MISC); - alias of BTN_0 */
|
||||
/* CASE_RETURN_STRING(EVDEV_BTN_DIGI); - alias of BTN_TOOL_PEN */
|
||||
CASE_RETURN_STRING(EVDEV_BTN_WHEEL);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_GEAR_UP);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_DPAD_UP);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_DPAD_RIGHT);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TRIGGER_HAPPY);
|
||||
CASE_RETURN_STRING(EVDEV_BTN_TRIGGER_HAPPY40);
|
||||
|
||||
CASE_RETURN_STRING(EVDEV_REL_X);
|
||||
CASE_RETURN_STRING(EVDEV_REL_Y);
|
||||
CASE_RETURN_STRING(EVDEV_REL_WHEEL);
|
||||
CASE_RETURN_STRING(EVDEV_REL_WHEEL_HI_RES);
|
||||
CASE_RETURN_STRING(EVDEV_REL_HWHEEL);
|
||||
CASE_RETURN_STRING(EVDEV_REL_HWHEEL_HI_RES);
|
||||
CASE_RETURN_STRING(EVDEV_REL_DIAL);
|
||||
CASE_RETURN_STRING(EVDEV_REL_MAX);
|
||||
|
||||
CASE_RETURN_STRING(EVDEV_ABS_X);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_Y);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_Z);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_RX);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_RY);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_RZ);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_PRESSURE);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_DISTANCE);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_THROTTLE);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_RUDDER);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_WHEEL);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_MISC);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_TILT_X);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_TILT_Y);
|
||||
|
||||
CASE_RETURN_STRING(EVDEV_ABS_MT_SLOT);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_MT_POSITION_X);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_MT_POSITION_Y);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_MT_TOOL_TYPE);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_MT_TRACKING_ID);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_MT_TOUCH_MAJOR);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_MT_TOUCH_MINOR);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_MT_ORIENTATION);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_MT_PRESSURE);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_MT_DISTANCE);
|
||||
CASE_RETURN_STRING(EVDEV_ABS_MAX);
|
||||
|
||||
CASE_RETURN_STRING(EVDEV_SW_LID);
|
||||
CASE_RETURN_STRING(EVDEV_SW_TABLET_MODE);
|
||||
CASE_RETURN_STRING(EVDEV_SW_KEYPAD_SLIDE);
|
||||
CASE_RETURN_STRING(EVDEV_SW_MAX);
|
||||
|
||||
CASE_RETURN_STRING(EVDEV_MSC_SCAN);
|
||||
CASE_RETURN_STRING(EVDEV_MSC_SERIAL);
|
||||
CASE_RETURN_STRING(EVDEV_MSC_TIMESTAMP);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline evdev_usage_t
|
||||
evdev_usage_from(enum evdev_usage usage)
|
||||
{
|
||||
|
|
@ -284,9 +394,9 @@ evdev_event_get_code_name(const struct evdev_event *e)
|
|||
}
|
||||
|
||||
static inline struct input_event
|
||||
evdev_event_to_input_event(const struct evdev_event *e, uint64_t time)
|
||||
evdev_event_to_input_event(const struct evdev_event *e, usec_t time)
|
||||
{
|
||||
struct timeval tv = us2tv(time);
|
||||
struct timeval tv = usec_to_timeval(time);
|
||||
return (struct input_event){
|
||||
.type = evdev_event_type(e),
|
||||
.code = evdev_event_code(e),
|
||||
|
|
@ -297,7 +407,7 @@ evdev_event_to_input_event(const struct evdev_event *e, uint64_t time)
|
|||
}
|
||||
|
||||
static inline struct evdev_event
|
||||
evdev_event_from_input_event(const struct input_event *e, uint64_t *time)
|
||||
evdev_event_from_input_event(const struct input_event *e, usec_t *time)
|
||||
{
|
||||
if (time)
|
||||
*time = input_event_time(e);
|
||||
|
|
@ -324,7 +434,7 @@ struct evdev_frame {
|
|||
int refcount;
|
||||
size_t max_size;
|
||||
size_t count;
|
||||
uint64_t time;
|
||||
usec_t time;
|
||||
struct evdev_event events[];
|
||||
};
|
||||
|
||||
|
|
@ -377,12 +487,12 @@ evdev_frame_get_events(struct evdev_frame *frame, size_t *nevents)
|
|||
* Set the timestamp for all events in this event frame.
|
||||
*/
|
||||
static inline void
|
||||
evdev_frame_set_time(struct evdev_frame *frame, uint64_t time)
|
||||
evdev_frame_set_time(struct evdev_frame *frame, usec_t time)
|
||||
{
|
||||
frame->time = time;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
static inline usec_t
|
||||
evdev_frame_get_time(const struct evdev_frame *frame)
|
||||
{
|
||||
return frame->time;
|
||||
|
|
@ -401,7 +511,7 @@ static inline struct evdev_frame *
|
|||
evdev_frame_new(size_t max_size)
|
||||
{
|
||||
struct evdev_frame *frame =
|
||||
zalloc(max_size * sizeof(sizeof(*frame->events)) + sizeof(*frame));
|
||||
zalloc(max_size * sizeof(*frame->events) + sizeof(*frame));
|
||||
|
||||
frame->refcount = 1;
|
||||
frame->max_size = max_size;
|
||||
|
|
@ -410,21 +520,6 @@ evdev_frame_new(size_t max_size)
|
|||
return frame;
|
||||
}
|
||||
|
||||
static inline struct evdev_frame *
|
||||
evdev_frame_new_on_stack(size_t max_size)
|
||||
{
|
||||
assert(max_size <= 64);
|
||||
struct evdev_frame *frame =
|
||||
alloca(max_size * sizeof(*frame->events) + sizeof(*frame));
|
||||
|
||||
frame->refcount = 1;
|
||||
frame->max_size = max_size;
|
||||
frame->count = 1; /* SYN_REPORT is always there */
|
||||
memset(frame->events, 0, max_size * sizeof(*frame->events));
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append events to the event frame. nevents must be larger than 0
|
||||
* and specifies the number of elements in events. If any events in
|
||||
|
|
@ -497,7 +592,7 @@ evdev_frame_append_input_event(struct evdev_frame *frame,
|
|||
{
|
||||
struct evdev_event e = evdev_event_from_input_event(event, NULL);
|
||||
if (evdev_usage_as_uint32_t(e.usage) == EVDEV_SYN_REPORT) {
|
||||
uint64_t time = input_event_time(event);
|
||||
usec_t time = input_event_time(event);
|
||||
evdev_frame_set_time(frame, time);
|
||||
}
|
||||
return evdev_frame_append(frame, &e, 1);
|
||||
|
|
@ -545,3 +640,121 @@ evdev_frame_clone(struct evdev_frame *frame)
|
|||
|
||||
return clone;
|
||||
}
|
||||
|
||||
struct evdev_mask {
|
||||
bitmask_t ev;
|
||||
bitmask_t rel;
|
||||
bitmask_t sw;
|
||||
infmask_t key; /* < BTN_MISC */
|
||||
infmask_t btn; /* >= BTN_MISC */
|
||||
infmask_t abs;
|
||||
};
|
||||
|
||||
static_assert(sizeof(bitmask_t) * 8 >= EV_MAX, "bitmask size too small");
|
||||
static_assert(sizeof(bitmask_t) * 8 >= EV_REL, "bitmask size too small");
|
||||
static_assert(sizeof(bitmask_t) * 8 >= EV_SW, "bitmask size too small");
|
||||
|
||||
static inline void
|
||||
evdev_mask_reset(struct evdev_mask *mask)
|
||||
{
|
||||
mask->ev = bitmask_new();
|
||||
mask->rel = bitmask_new();
|
||||
mask->sw = bitmask_new();
|
||||
infmask_reset(&mask->key);
|
||||
infmask_reset(&mask->btn);
|
||||
infmask_reset(&mask->abs);
|
||||
}
|
||||
|
||||
static inline struct evdev_mask *
|
||||
evdev_mask_new(void)
|
||||
{
|
||||
struct evdev_mask *mask = zalloc(sizeof(*mask));
|
||||
evdev_mask_reset(mask);
|
||||
return mask;
|
||||
}
|
||||
|
||||
static inline void
|
||||
evdev_mask_destroy(struct evdev_mask *mask)
|
||||
{
|
||||
if (mask) {
|
||||
evdev_mask_reset(mask);
|
||||
free(mask);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_DESTROY_CLEANUP_FUNC(evdev_mask);
|
||||
|
||||
static inline void
|
||||
evdev_mask_set_usage(struct evdev_mask *mask, evdev_usage_t usage)
|
||||
{
|
||||
unsigned int type = evdev_usage_type(usage);
|
||||
unsigned int code = evdev_usage_code(usage);
|
||||
|
||||
if (type >= EV_MAX)
|
||||
return;
|
||||
|
||||
bitmask_set_bit(&mask->ev, type);
|
||||
|
||||
switch (type) {
|
||||
case EV_ABS:
|
||||
if (code <= ABS_MAX)
|
||||
infmask_set_bit(&mask->abs, code);
|
||||
break;
|
||||
case EV_KEY:
|
||||
if (code < BTN_MISC)
|
||||
infmask_set_bit(&mask->key, code);
|
||||
else if (code <= KEY_MAX)
|
||||
infmask_set_bit(&mask->btn, code - BTN_MISC);
|
||||
break;
|
||||
case EV_REL:
|
||||
if (code <= REL_MAX)
|
||||
bitmask_set_bit(&mask->rel, code);
|
||||
break;
|
||||
case EV_SW:
|
||||
if (code <= SW_MAX)
|
||||
bitmask_set_bit(&mask->sw, code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
evdev_mask_set_enum(struct evdev_mask *mask, enum evdev_usage usage)
|
||||
{
|
||||
evdev_mask_set_usage(mask, evdev_usage_from(usage));
|
||||
}
|
||||
|
||||
static inline bool
|
||||
evdev_mask_is_set(const struct evdev_mask *mask, evdev_usage_t usage)
|
||||
{
|
||||
unsigned int type = evdev_usage_type(usage);
|
||||
unsigned int code = evdev_usage_code(usage);
|
||||
|
||||
if (type >= EV_MAX)
|
||||
return false;
|
||||
|
||||
if (!bitmask_bit_is_set(mask->ev, type))
|
||||
return false;
|
||||
|
||||
bool isset = false;
|
||||
switch (type) {
|
||||
case EV_ABS:
|
||||
isset = infmask_bit_is_set(&mask->abs, code);
|
||||
break;
|
||||
case EV_KEY:
|
||||
if (code < BTN_MISC)
|
||||
isset = infmask_bit_is_set(&mask->key, code);
|
||||
else
|
||||
isset = infmask_bit_is_set(&mask->btn, code - BTN_MISC);
|
||||
break;
|
||||
case EV_REL:
|
||||
isset = bitmask_bit_is_set(mask->rel, code);
|
||||
break;
|
||||
case EV_SW:
|
||||
isset = bitmask_bit_is_set(mask->sw, code);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return isset;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "evdev.h"
|
||||
|
||||
#define MIDDLEBUTTON_TIMEOUT ms2us(50)
|
||||
#define MIDDLEBUTTON_TIMEOUT usec_from_millis(50)
|
||||
|
||||
/*****************************************
|
||||
* BEFORE YOU EDIT THIS FILE, look at the state diagram in
|
||||
|
|
@ -88,9 +88,10 @@ middlebutton_state_error(struct evdev_device *device,
|
|||
}
|
||||
|
||||
static void
|
||||
middlebutton_timer_set(struct evdev_device *device, uint64_t now)
|
||||
middlebutton_timer_set(struct evdev_device *device, usec_t now)
|
||||
{
|
||||
libinput_timer_set(&device->middlebutton.timer, now + MIDDLEBUTTON_TIMEOUT);
|
||||
libinput_timer_set(&device->middlebutton.timer,
|
||||
usec_add(now, MIDDLEBUTTON_TIMEOUT));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -102,7 +103,7 @@ middlebutton_timer_cancel(struct evdev_device *device)
|
|||
static inline void
|
||||
middlebutton_set_state(struct evdev_device *device,
|
||||
enum evdev_middlebutton_state state,
|
||||
uint64_t now)
|
||||
usec_t now)
|
||||
{
|
||||
switch (state) {
|
||||
case MIDDLEBUTTON_LEFT_DOWN:
|
||||
|
|
@ -127,7 +128,7 @@ middlebutton_set_state(struct evdev_device *device,
|
|||
|
||||
static void
|
||||
middlebutton_post_event(struct evdev_device *device,
|
||||
uint64_t now,
|
||||
usec_t now,
|
||||
evdev_usage_t button,
|
||||
enum libinput_button_state state)
|
||||
{
|
||||
|
|
@ -136,7 +137,7 @@ middlebutton_post_event(struct evdev_device *device,
|
|||
|
||||
static int
|
||||
evdev_middlebutton_idle_handle_event(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum evdev_middlebutton_event event)
|
||||
{
|
||||
switch (event) {
|
||||
|
|
@ -162,7 +163,7 @@ evdev_middlebutton_idle_handle_event(struct evdev_device *device,
|
|||
|
||||
static int
|
||||
evdev_middlebutton_ldown_handle_event(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum evdev_middlebutton_event event)
|
||||
{
|
||||
switch (event) {
|
||||
|
|
@ -214,7 +215,7 @@ evdev_middlebutton_ldown_handle_event(struct evdev_device *device,
|
|||
|
||||
static int
|
||||
evdev_middlebutton_rdown_handle_event(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum evdev_middlebutton_event event)
|
||||
{
|
||||
switch (event) {
|
||||
|
|
@ -266,7 +267,7 @@ evdev_middlebutton_rdown_handle_event(struct evdev_device *device,
|
|||
|
||||
static int
|
||||
evdev_middlebutton_middle_handle_event(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum evdev_middlebutton_event event)
|
||||
{
|
||||
switch (event) {
|
||||
|
|
@ -308,7 +309,7 @@ evdev_middlebutton_middle_handle_event(struct evdev_device *device,
|
|||
|
||||
static int
|
||||
evdev_middlebutton_lup_pending_handle_event(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum evdev_middlebutton_event event)
|
||||
{
|
||||
switch (event) {
|
||||
|
|
@ -344,7 +345,7 @@ evdev_middlebutton_lup_pending_handle_event(struct evdev_device *device,
|
|||
|
||||
static int
|
||||
evdev_middlebutton_rup_pending_handle_event(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum evdev_middlebutton_event event)
|
||||
{
|
||||
switch (event) {
|
||||
|
|
@ -380,7 +381,7 @@ evdev_middlebutton_rup_pending_handle_event(struct evdev_device *device,
|
|||
|
||||
static int
|
||||
evdev_middlebutton_passthrough_handle_event(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum evdev_middlebutton_event event)
|
||||
{
|
||||
switch (event) {
|
||||
|
|
@ -403,7 +404,7 @@ evdev_middlebutton_passthrough_handle_event(struct evdev_device *device,
|
|||
|
||||
static int
|
||||
evdev_middlebutton_ignore_lr_handle_event(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum evdev_middlebutton_event event)
|
||||
{
|
||||
switch (event) {
|
||||
|
|
@ -432,7 +433,7 @@ evdev_middlebutton_ignore_lr_handle_event(struct evdev_device *device,
|
|||
|
||||
static int
|
||||
evdev_middlebutton_ignore_l_handle_event(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum evdev_middlebutton_event event)
|
||||
{
|
||||
switch (event) {
|
||||
|
|
@ -457,7 +458,7 @@ evdev_middlebutton_ignore_l_handle_event(struct evdev_device *device,
|
|||
}
|
||||
static int
|
||||
evdev_middlebutton_ignore_r_handle_event(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum evdev_middlebutton_event event)
|
||||
{
|
||||
switch (event) {
|
||||
|
|
@ -483,7 +484,7 @@ evdev_middlebutton_ignore_r_handle_event(struct evdev_device *device,
|
|||
|
||||
static int
|
||||
evdev_middlebutton_handle_event(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum evdev_middlebutton_event event)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -553,7 +554,7 @@ evdev_middlebutton_apply_config(struct evdev_device *device)
|
|||
|
||||
bool
|
||||
evdev_middlebutton_filter_button(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
evdev_usage_t button,
|
||||
enum libinput_button_state state)
|
||||
{
|
||||
|
|
@ -616,7 +617,7 @@ evdev_middlebutton_filter_button(struct evdev_device *device,
|
|||
}
|
||||
|
||||
static void
|
||||
evdev_middlebutton_handle_timeout(uint64_t now, void *data)
|
||||
evdev_middlebutton_handle_timeout(usec_t now, void *data)
|
||||
{
|
||||
struct evdev_device *device = evdev_device(data);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@
|
|||
#include "evdev-mt-touchpad.h"
|
||||
#include "linux/input.h"
|
||||
|
||||
#define DEFAULT_BUTTON_ENTER_TIMEOUT ms2us(100)
|
||||
#define DEFAULT_BUTTON_LEAVE_TIMEOUT ms2us(300)
|
||||
#define DEFAULT_BUTTON_ENTER_TIMEOUT usec_from_millis(100)
|
||||
#define DEFAULT_BUTTON_LEAVE_TIMEOUT usec_from_millis(300)
|
||||
|
||||
/*****************************************
|
||||
* BEFORE YOU EDIT THIS FILE, look at the state diagram in
|
||||
|
|
@ -121,15 +121,17 @@ is_inside_top_middle_area(const struct tp_dispatch *tp, const struct tp_touch *t
|
|||
}
|
||||
|
||||
static void
|
||||
tp_button_set_enter_timer(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_button_set_enter_timer(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
libinput_timer_set(&t->button.timer, time + DEFAULT_BUTTON_ENTER_TIMEOUT);
|
||||
libinput_timer_set(&t->button.timer,
|
||||
usec_add(time, DEFAULT_BUTTON_ENTER_TIMEOUT));
|
||||
}
|
||||
|
||||
static void
|
||||
tp_button_set_leave_timer(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_button_set_leave_timer(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
libinput_timer_set(&t->button.timer, time + DEFAULT_BUTTON_LEAVE_TIMEOUT);
|
||||
libinput_timer_set(&t->button.timer,
|
||||
usec_add(time, DEFAULT_BUTTON_LEAVE_TIMEOUT));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -141,7 +143,7 @@ tp_button_set_state(struct tp_dispatch *tp,
|
|||
struct tp_touch *t,
|
||||
enum button_state new_state,
|
||||
enum button_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
libinput_timer_cancel(&t->button.timer);
|
||||
|
||||
|
|
@ -176,7 +178,7 @@ static void
|
|||
tp_button_none_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum button_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case BUTTON_EVENT_IN_BOTTOM_R:
|
||||
|
|
@ -206,7 +208,7 @@ static void
|
|||
tp_button_area_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum button_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case BUTTON_EVENT_IN_BOTTOM_R:
|
||||
|
|
@ -233,23 +235,22 @@ tp_button_area_handle_event(struct tp_dispatch *tp,
|
|||
* that triggered this call).
|
||||
*/
|
||||
static inline void
|
||||
tp_button_release_other_bottom_touches(struct tp_dispatch *tp,
|
||||
uint64_t other_start_time)
|
||||
tp_button_release_other_bottom_touches(struct tp_dispatch *tp, usec_t other_start_time)
|
||||
{
|
||||
struct tp_touch *t;
|
||||
|
||||
tp_for_each_touch(tp, t) {
|
||||
uint64_t tdelta;
|
||||
usec_t tdelta;
|
||||
|
||||
if (t->button.state != BUTTON_STATE_BOTTOM || t->button.has_moved)
|
||||
continue;
|
||||
|
||||
if (other_start_time > t->button.initial_time)
|
||||
tdelta = other_start_time - t->button.initial_time;
|
||||
if (usec_cmp(other_start_time, t->button.initial_time) > 0)
|
||||
tdelta = usec_delta(other_start_time, t->button.initial_time);
|
||||
else
|
||||
tdelta = t->button.initial_time - other_start_time;
|
||||
tdelta = usec_delta(t->button.initial_time, other_start_time);
|
||||
|
||||
if (tdelta > ms2us(80))
|
||||
if (usec_cmp(tdelta, usec_from_millis(80)) > 0)
|
||||
continue;
|
||||
|
||||
t->button.has_moved = true;
|
||||
|
|
@ -260,7 +261,7 @@ static void
|
|||
tp_button_bottom_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum button_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case BUTTON_EVENT_IN_BOTTOM_R:
|
||||
|
|
@ -296,7 +297,7 @@ static void
|
|||
tp_button_top_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum button_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case BUTTON_EVENT_IN_BOTTOM_R:
|
||||
|
|
@ -327,7 +328,7 @@ static void
|
|||
tp_button_top_new_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum button_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case BUTTON_EVENT_IN_BOTTOM_R:
|
||||
|
|
@ -362,7 +363,7 @@ static void
|
|||
tp_button_top_to_ignore_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum button_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case BUTTON_EVENT_IN_TOP_R:
|
||||
|
|
@ -394,7 +395,7 @@ static void
|
|||
tp_button_ignore_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum button_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case BUTTON_EVENT_IN_BOTTOM_R:
|
||||
|
|
@ -422,7 +423,7 @@ static void
|
|||
tp_button_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum button_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
enum button_state current = t->button.state;
|
||||
|
||||
|
|
@ -496,7 +497,7 @@ tp_button_check_for_movement(struct tp_dispatch *tp, struct tp_touch *t)
|
|||
}
|
||||
|
||||
void
|
||||
tp_button_handle_state(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_button_handle_state(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct tp_touch *t;
|
||||
|
||||
|
|
@ -547,7 +548,7 @@ tp_button_handle_state(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_button_handle_timeout(uint64_t now, void *data)
|
||||
tp_button_handle_timeout(usec_t now, void *data)
|
||||
{
|
||||
struct tp_touch *t = data;
|
||||
|
||||
|
|
@ -555,7 +556,7 @@ tp_button_handle_timeout(uint64_t now, void *data)
|
|||
}
|
||||
|
||||
void
|
||||
tp_process_button(struct tp_dispatch *tp, const struct evdev_event *e, uint64_t time)
|
||||
tp_process_button(struct tp_dispatch *tp, const struct evdev_event *e, usec_t time)
|
||||
{
|
||||
uint32_t mask = bit(evdev_usage_enum(e->usage) - EVDEV_BTN_LEFT);
|
||||
|
||||
|
|
@ -577,7 +578,7 @@ tp_process_button(struct tp_dispatch *tp, const struct evdev_event *e, uint64_t
|
|||
}
|
||||
|
||||
void
|
||||
tp_release_all_buttons(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_release_all_buttons(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
if (tp->buttons.state) {
|
||||
tp->buttons.state = 0;
|
||||
|
|
@ -1032,7 +1033,7 @@ tp_remove_buttons(struct tp_dispatch *tp)
|
|||
}
|
||||
|
||||
static int
|
||||
tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_post_physical_buttons(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
uint32_t current, old, button;
|
||||
|
||||
|
|
@ -1180,7 +1181,7 @@ out:
|
|||
|
||||
static int
|
||||
tp_notify_clickpadbutton(struct tp_dispatch *tp,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
evdev_usage_t button,
|
||||
uint32_t is_topbutton,
|
||||
enum libinput_button_state state)
|
||||
|
|
@ -1227,10 +1228,10 @@ tp_notify_clickpadbutton(struct tp_dispatch *tp,
|
|||
}
|
||||
|
||||
static int
|
||||
tp_post_clickpadbutton_buttons(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_post_clickpadbutton_buttons(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
uint32_t current, old, is_top;
|
||||
evdev_usage_t button = evdev_usage_from_uint32_t(0);
|
||||
evdev_usage_t button;
|
||||
enum libinput_button_state state;
|
||||
enum { AREA = 0x01, LEFT = 0x02, MIDDLE = 0x04, RIGHT = 0x08 };
|
||||
bool want_left_handed = true;
|
||||
|
|
@ -1332,7 +1333,7 @@ tp_post_clickpadbutton_buttons(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
int
|
||||
tp_post_button_events(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_post_button_events(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
if (tp->buttons.is_clickpad ||
|
||||
tp->device->model_flags & EVDEV_MODEL_APPLE_TOUCHPAD_ONEBUTTON)
|
||||
|
|
|
|||
|
|
@ -87,9 +87,9 @@ tp_touch_get_edge(const struct tp_dispatch *tp, const struct tp_touch *t)
|
|||
}
|
||||
|
||||
static inline void
|
||||
tp_edge_scroll_set_timer(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_edge_scroll_set_timer(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
const int DEFAULT_SCROLL_LOCK_TIMEOUT = ms2us(300);
|
||||
const usec_t DEFAULT_SCROLL_LOCK_TIMEOUT = usec_from_millis(300);
|
||||
/* if we use software buttons, we disable timeout-based
|
||||
* edge scrolling. A finger resting on the button areas is
|
||||
* likely there to trigger a button event.
|
||||
|
|
@ -97,14 +97,15 @@ tp_edge_scroll_set_timer(struct tp_dispatch *tp, struct tp_touch *t, uint64_t ti
|
|||
if (tp->buttons.click_method == LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS)
|
||||
return;
|
||||
|
||||
libinput_timer_set(&t->scroll.timer, time + DEFAULT_SCROLL_LOCK_TIMEOUT);
|
||||
libinput_timer_set(&t->scroll.timer,
|
||||
usec_add(time, DEFAULT_SCROLL_LOCK_TIMEOUT));
|
||||
}
|
||||
|
||||
static void
|
||||
tp_edge_scroll_set_state(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tp_edge_scroll_touch_state state,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
libinput_timer_cancel(&t->scroll.timer);
|
||||
|
||||
|
|
@ -131,7 +132,7 @@ static void
|
|||
tp_edge_scroll_handle_none(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum scroll_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case SCROLL_EVENT_TOUCH:
|
||||
|
|
@ -164,7 +165,7 @@ static void
|
|||
tp_edge_scroll_handle_edge_new(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum scroll_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case SCROLL_EVENT_TOUCH:
|
||||
|
|
@ -196,7 +197,7 @@ static void
|
|||
tp_edge_scroll_handle_edge(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum scroll_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case SCROLL_EVENT_TOUCH:
|
||||
|
|
@ -230,7 +231,7 @@ static void
|
|||
tp_edge_scroll_handle_area(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum scroll_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case SCROLL_EVENT_TOUCH:
|
||||
|
|
@ -252,7 +253,7 @@ static void
|
|||
tp_edge_scroll_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum scroll_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
enum tp_edge_scroll_touch_state current = t->scroll.edge_state;
|
||||
|
||||
|
|
@ -281,7 +282,7 @@ tp_edge_scroll_handle_event(struct tp_dispatch *tp,
|
|||
}
|
||||
|
||||
static void
|
||||
tp_edge_scroll_handle_timeout(uint64_t now, void *data)
|
||||
tp_edge_scroll_handle_timeout(usec_t now, void *data)
|
||||
{
|
||||
struct tp_touch *t = data;
|
||||
|
||||
|
|
@ -349,7 +350,7 @@ tp_remove_edge_scroll(struct tp_dispatch *tp)
|
|||
}
|
||||
|
||||
void
|
||||
tp_edge_scroll_handle_state(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_edge_scroll_handle_state(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct tp_touch *t;
|
||||
|
||||
|
|
@ -393,7 +394,7 @@ tp_edge_scroll_handle_state(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
int
|
||||
tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_edge_scroll_post_events(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct evdev_device *device = tp->device;
|
||||
struct tp_touch *t;
|
||||
|
|
@ -478,7 +479,7 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
void
|
||||
tp_edge_scroll_stop_events(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_edge_scroll_stop_events(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct evdev_device *device = tp->device;
|
||||
struct tp_touch *t;
|
||||
|
|
|
|||
|
|
@ -33,11 +33,11 @@ enum gesture_cancelled {
|
|||
CANCEL_GESTURE = 1,
|
||||
};
|
||||
|
||||
#define QUICK_GESTURE_HOLD_TIMEOUT ms2us(40)
|
||||
#define DEFAULT_GESTURE_HOLD_TIMEOUT ms2us(180)
|
||||
#define DEFAULT_GESTURE_SWITCH_TIMEOUT ms2us(100)
|
||||
#define DEFAULT_GESTURE_SWIPE_TIMEOUT ms2us(150)
|
||||
#define DEFAULT_GESTURE_PINCH_TIMEOUT ms2us(300)
|
||||
#define QUICK_GESTURE_HOLD_TIMEOUT usec_from_millis(40)
|
||||
#define DEFAULT_GESTURE_HOLD_TIMEOUT usec_from_millis(180)
|
||||
#define DEFAULT_GESTURE_SWITCH_TIMEOUT usec_from_millis(100)
|
||||
#define DEFAULT_GESTURE_SWIPE_TIMEOUT usec_from_millis(150)
|
||||
#define DEFAULT_GESTURE_PINCH_TIMEOUT usec_from_millis(300)
|
||||
|
||||
#define HOLD_AND_MOTION_THRESHOLD 0.5 /* mm */
|
||||
#define PINCH_DISAMBIGUATION_MOVE_THRESHOLD 1.5 /* mm */
|
||||
|
|
@ -152,10 +152,10 @@ tp_gesture_init_scroll(struct tp_dispatch *tp)
|
|||
struct phys_coords zero = { 0.0, 0.0 };
|
||||
tp->scroll.active.h = false;
|
||||
tp->scroll.active.v = false;
|
||||
tp->scroll.duration.h = 0;
|
||||
tp->scroll.duration.v = 0;
|
||||
tp->scroll.duration.h = usec_from_uint64_t(0);
|
||||
tp->scroll.duration.v = usec_from_uint64_t(0);
|
||||
tp->scroll.vector = zero;
|
||||
tp->scroll.time_prev = 0;
|
||||
tp->scroll.time_prev = usec_from_uint64_t(0);
|
||||
}
|
||||
|
||||
static inline struct device_float_coords
|
||||
|
|
@ -185,7 +185,7 @@ tp_get_raw_pointer_motion(struct tp_dispatch *tp)
|
|||
}
|
||||
|
||||
static bool
|
||||
tp_has_pending_pointer_motion(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_has_pending_pointer_motion(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct device_float_coords raw;
|
||||
|
||||
|
|
@ -202,7 +202,7 @@ tp_has_pending_pointer_motion(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_post_pointer_motion(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_post_pointer_motion(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct device_float_coords raw;
|
||||
struct normalized_coords delta;
|
||||
|
|
@ -316,12 +316,12 @@ tp_gesture_init_pinch(struct tp_dispatch *tp)
|
|||
}
|
||||
|
||||
static inline void
|
||||
tp_gesture_init_3fg_drag(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_init_3fg_drag(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_gesture_stop_3fg_drag(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_stop_3fg_drag(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -344,24 +344,27 @@ static void
|
|||
tp_gesture_apply_scroll_constraints(struct tp_dispatch *tp,
|
||||
struct device_float_coords *raw,
|
||||
struct normalized_coords *delta,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
uint64_t tdelta = 0;
|
||||
usec_t tdelta = usec_from_millis(0);
|
||||
struct phys_coords delta_mm, vector;
|
||||
double vector_decay, vector_length, slope;
|
||||
|
||||
const uint64_t ACTIVE_THRESHOLD = ms2us(100), INACTIVE_THRESHOLD = ms2us(50),
|
||||
EVENT_TIMEOUT = ms2us(100);
|
||||
const usec_t ACTIVE_THRESHOLD = usec_from_millis(100),
|
||||
INACTIVE_THRESHOLD = usec_from_millis(50),
|
||||
EVENT_TIMEOUT = usec_from_millis(100);
|
||||
|
||||
/* Both axes active == true means free scrolling is enabled */
|
||||
if (tp->scroll.active.h && tp->scroll.active.v)
|
||||
return;
|
||||
|
||||
/* Determine time delta since last movement event */
|
||||
if (tp->scroll.time_prev != 0)
|
||||
tdelta = time - tp->scroll.time_prev;
|
||||
if (tdelta > EVENT_TIMEOUT)
|
||||
tdelta = 0;
|
||||
if (!usec_is_zero(tp->scroll.time_prev)) {
|
||||
usec_t diff = usec_delta(time, tp->scroll.time_prev);
|
||||
if (usec_cmp(diff, EVENT_TIMEOUT) <= 0)
|
||||
tdelta = diff;
|
||||
}
|
||||
|
||||
tp->scroll.time_prev = time;
|
||||
|
||||
/* Delta since last movement event in mm */
|
||||
|
|
@ -372,11 +375,13 @@ tp_gesture_apply_scroll_constraints(struct tp_dispatch *tp,
|
|||
* EVENT_TIMEOUT of 100, vector_decay = (0.97)^tdelta. This linear
|
||||
* approximation allows easier tweaking of EVENT_TIMEOUT and is faster.
|
||||
*/
|
||||
if (tdelta > 0) {
|
||||
if (usec_gt(tdelta, 0)) {
|
||||
uint64_t delta = usec_as_uint64_t(tdelta);
|
||||
double recent, later;
|
||||
recent = ((EVENT_TIMEOUT / 2.0) - tdelta) / (EVENT_TIMEOUT / 2.0);
|
||||
later = (EVENT_TIMEOUT - tdelta) / (EVENT_TIMEOUT * 2.0);
|
||||
vector_decay = tdelta <= (0.33 * EVENT_TIMEOUT) ? recent : later;
|
||||
uint64_t timeout_us = usec_as_uint64_t(EVENT_TIMEOUT);
|
||||
recent = ((timeout_us / 2.0) - delta) / (timeout_us / 2.0);
|
||||
later = (timeout_us - delta) / (timeout_us * 2.0);
|
||||
vector_decay = delta <= (0.33 * timeout_us) ? recent : later;
|
||||
} else {
|
||||
vector_decay = 0.0;
|
||||
}
|
||||
|
|
@ -407,36 +412,38 @@ tp_gesture_apply_scroll_constraints(struct tp_dispatch *tp,
|
|||
const double MIN_VECTOR = 0.15;
|
||||
|
||||
if (slope >= DEGREE_30 && vector_length > MIN_VECTOR) {
|
||||
tp->scroll.duration.v += tdelta;
|
||||
if (tp->scroll.duration.v > ACTIVE_THRESHOLD)
|
||||
tp->scroll.duration.v = usec_add(tp->scroll.duration.v, tdelta);
|
||||
if (usec_cmp(tp->scroll.duration.v, ACTIVE_THRESHOLD) > 0)
|
||||
tp->scroll.duration.v = ACTIVE_THRESHOLD;
|
||||
if (slope >= DEGREE_75) {
|
||||
if (tp->scroll.duration.h > tdelta)
|
||||
tp->scroll.duration.h -= tdelta;
|
||||
if (usec_cmp(tp->scroll.duration.h, tdelta) > 0)
|
||||
tp->scroll.duration.h =
|
||||
usec_sub(tp->scroll.duration.h, tdelta);
|
||||
else
|
||||
tp->scroll.duration.h = 0;
|
||||
tp->scroll.duration.h = usec_from_uint64_t(0);
|
||||
}
|
||||
}
|
||||
if (slope < DEGREE_60 && vector_length > MIN_VECTOR) {
|
||||
tp->scroll.duration.h += tdelta;
|
||||
if (tp->scroll.duration.h > ACTIVE_THRESHOLD)
|
||||
tp->scroll.duration.h = usec_add(tp->scroll.duration.h, tdelta);
|
||||
if (usec_cmp(tp->scroll.duration.h, ACTIVE_THRESHOLD) > 0)
|
||||
tp->scroll.duration.h = ACTIVE_THRESHOLD;
|
||||
if (slope < DEGREE_15) {
|
||||
if (tp->scroll.duration.v > tdelta)
|
||||
tp->scroll.duration.v -= tdelta;
|
||||
if (usec_cmp(tp->scroll.duration.v, tdelta) > 0)
|
||||
tp->scroll.duration.v =
|
||||
usec_sub(tp->scroll.duration.v, tdelta);
|
||||
else
|
||||
tp->scroll.duration.v = 0;
|
||||
tp->scroll.duration.v = usec_from_uint64_t(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (tp->scroll.duration.h == ACTIVE_THRESHOLD) {
|
||||
if (usec_cmp(tp->scroll.duration.h, ACTIVE_THRESHOLD) == 0) {
|
||||
tp->scroll.active.h = true;
|
||||
if (tp->scroll.duration.v < INACTIVE_THRESHOLD)
|
||||
if (usec_cmp(tp->scroll.duration.v, INACTIVE_THRESHOLD) < 0)
|
||||
tp->scroll.active.v = false;
|
||||
}
|
||||
if (tp->scroll.duration.v == ACTIVE_THRESHOLD) {
|
||||
if (usec_cmp(tp->scroll.duration.v, ACTIVE_THRESHOLD) == 0) {
|
||||
tp->scroll.active.v = true;
|
||||
if (tp->scroll.duration.h < INACTIVE_THRESHOLD)
|
||||
if (usec_cmp(tp->scroll.duration.h, INACTIVE_THRESHOLD) < 0)
|
||||
tp->scroll.active.h = false;
|
||||
}
|
||||
|
||||
|
|
@ -519,9 +526,9 @@ tp_gesture_use_hold_timer(struct tp_dispatch *tp)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_set_hold_timer(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_set_hold_timer(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
uint64_t timeout;
|
||||
usec_t timeout;
|
||||
|
||||
if (!tp->gesture.hold_enabled)
|
||||
return;
|
||||
|
|
@ -530,14 +537,14 @@ tp_gesture_set_hold_timer(struct tp_dispatch *tp, uint64_t time)
|
|||
timeout = tp_gesture_is_quick_hold(tp) ? QUICK_GESTURE_HOLD_TIMEOUT
|
||||
: DEFAULT_GESTURE_HOLD_TIMEOUT;
|
||||
|
||||
libinput_timer_set(&tp->gesture.hold_timer, time + timeout);
|
||||
libinput_timer_set(&tp->gesture.hold_timer, usec_add(time, timeout));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_event_on_state_none(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case GESTURE_EVENT_RESET:
|
||||
|
|
@ -581,7 +588,7 @@ tp_gesture_handle_event_on_state_none(struct tp_dispatch *tp,
|
|||
static void
|
||||
tp_gesture_handle_event_on_state_unknown(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case GESTURE_EVENT_RESET:
|
||||
|
|
@ -634,7 +641,7 @@ tp_gesture_handle_event_on_state_unknown(struct tp_dispatch *tp,
|
|||
static void
|
||||
tp_gesture_handle_event_on_state_hold(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case GESTURE_EVENT_RESET:
|
||||
|
|
@ -692,7 +699,7 @@ tp_gesture_handle_event_on_state_hold(struct tp_dispatch *tp,
|
|||
static void
|
||||
tp_gesture_handle_event_on_state_hold_and_motion(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case GESTURE_EVENT_RESET:
|
||||
|
|
@ -733,7 +740,7 @@ tp_gesture_handle_event_on_state_hold_and_motion(struct tp_dispatch *tp,
|
|||
static void
|
||||
tp_gesture_handle_event_on_state_pointer_motion(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct tp_touch *first;
|
||||
struct phys_coords first_moved;
|
||||
|
|
@ -779,7 +786,7 @@ tp_gesture_handle_event_on_state_pointer_motion(struct tp_dispatch *tp,
|
|||
static void
|
||||
tp_gesture_handle_event_on_state_scroll_start(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case GESTURE_EVENT_RESET:
|
||||
|
|
@ -812,7 +819,7 @@ tp_gesture_handle_event_on_state_scroll_start(struct tp_dispatch *tp,
|
|||
static void
|
||||
tp_gesture_handle_event_on_state_scroll(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case GESTURE_EVENT_RESET:
|
||||
|
|
@ -847,7 +854,7 @@ tp_gesture_handle_event_on_state_scroll(struct tp_dispatch *tp,
|
|||
static void
|
||||
tp_gesture_handle_event_on_state_pinch_start(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case GESTURE_EVENT_RESET:
|
||||
|
|
@ -875,7 +882,7 @@ tp_gesture_handle_event_on_state_pinch_start(struct tp_dispatch *tp,
|
|||
static void
|
||||
tp_gesture_handle_event_on_state_pinch(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case GESTURE_EVENT_RESET:
|
||||
|
|
@ -914,7 +921,7 @@ tp_gesture_handle_event_on_state_pinch(struct tp_dispatch *tp,
|
|||
static void
|
||||
tp_gesture_handle_event_on_state_swipe_start(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case GESTURE_EVENT_RESET:
|
||||
|
|
@ -943,7 +950,7 @@ tp_gesture_handle_event_on_state_swipe_start(struct tp_dispatch *tp,
|
|||
static void
|
||||
tp_gesture_handle_event_on_state_swipe(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case GESTURE_EVENT_RESET:
|
||||
|
|
@ -981,7 +988,7 @@ tp_gesture_handle_event_on_state_swipe(struct tp_dispatch *tp,
|
|||
static void
|
||||
tp_gesture_handle_event_on_state_3fg_drag_start(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case GESTURE_EVENT_RESET:
|
||||
|
|
@ -1008,16 +1015,16 @@ tp_gesture_handle_event_on_state_3fg_drag_start(struct tp_dispatch *tp,
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_set_3fg_drag_timer(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_set_3fg_drag_timer(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
tp->gesture.drag_3fg_release_time = time;
|
||||
libinput_timer_set(&tp->gesture.drag_3fg_timer, time + ms2us(700));
|
||||
libinput_timer_set(&tp->gesture.drag_3fg_timer, usec_add_millis(time, 700));
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_event_on_state_3fg_drag(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case GESTURE_EVENT_RESET:
|
||||
|
|
@ -1065,7 +1072,7 @@ tp_gesture_handle_event_on_state_3fg_drag(struct tp_dispatch *tp,
|
|||
static void
|
||||
tp_gesture_handle_event_on_state_3fg_drag_released(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case GESTURE_EVENT_RESET:
|
||||
|
|
@ -1125,7 +1132,7 @@ tp_gesture_handle_event_on_state_3fg_drag_released(struct tp_dispatch *tp,
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_event(struct tp_dispatch *tp, enum gesture_event event, uint64_t time)
|
||||
tp_gesture_handle_event(struct tp_dispatch *tp, enum gesture_event event, usec_t time)
|
||||
{
|
||||
enum tp_gesture_state oldstate;
|
||||
|
||||
|
|
@ -1187,7 +1194,7 @@ tp_gesture_handle_event(struct tp_dispatch *tp, enum gesture_event event, uint64
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_hold_timeout(uint64_t now, void *data)
|
||||
tp_gesture_hold_timeout(usec_t now, void *data)
|
||||
{
|
||||
struct tp_dispatch *tp = data;
|
||||
|
||||
|
|
@ -1198,7 +1205,7 @@ tp_gesture_hold_timeout(uint64_t now, void *data)
|
|||
}
|
||||
|
||||
void
|
||||
tp_gesture_tap_timeout(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_tap_timeout(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
if (!tp->gesture.hold_enabled)
|
||||
return;
|
||||
|
|
@ -1208,7 +1215,7 @@ tp_gesture_tap_timeout(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_3fg_drag_timeout(uint64_t now, void *data)
|
||||
tp_gesture_3fg_drag_timeout(usec_t now, void *data)
|
||||
{
|
||||
struct tp_dispatch *tp = data;
|
||||
|
||||
|
|
@ -1216,7 +1223,7 @@ tp_gesture_3fg_drag_timeout(uint64_t now, void *data)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_detect_motion_gestures(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_detect_motion_gestures(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct tp_touch *first = tp->gesture.touches[0],
|
||||
*second = tp->gesture.touches[1], *thumb;
|
||||
|
|
@ -1281,7 +1288,9 @@ tp_gesture_detect_motion_gestures(struct tp_dispatch *tp, uint64_t time)
|
|||
/* If both touches are within 7mm vertically and 40mm horizontally
|
||||
* past the timeout, assume scroll/swipe */
|
||||
if ((!tp->gesture.enabled || (distance_mm.x < 40.0 && distance_mm.y < 7.0)) &&
|
||||
time > (tp->gesture.initial_time + DEFAULT_GESTURE_SWIPE_TIMEOUT)) {
|
||||
usec_cmp(time,
|
||||
usec_add(tp->gesture.initial_time,
|
||||
DEFAULT_GESTURE_SWIPE_TIMEOUT)) > 0) {
|
||||
if (tp->gesture.finger_count == 2)
|
||||
tp_gesture_handle_event(tp, GESTURE_EVENT_SCROLL_START, time);
|
||||
else if (tp->drag_3fg.nfingers == tp->gesture.finger_count)
|
||||
|
|
@ -1416,7 +1425,7 @@ tp_gesture_is_pinch(struct tp_dispatch *tp)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state_none(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_handle_state_none(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct tp_touch *first, *second;
|
||||
struct tp_touch *touches[4];
|
||||
|
|
@ -1485,23 +1494,21 @@ tp_gesture_handle_state_none(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state_unknown(struct tp_dispatch *tp,
|
||||
uint64_t time,
|
||||
bool ignore_motion)
|
||||
tp_gesture_handle_state_unknown(struct tp_dispatch *tp, usec_t time, bool ignore_motion)
|
||||
{
|
||||
if (!ignore_motion)
|
||||
tp_gesture_detect_motion_gestures(tp, time);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state_hold(struct tp_dispatch *tp, uint64_t time, bool ignore_motion)
|
||||
tp_gesture_handle_state_hold(struct tp_dispatch *tp, usec_t time, bool ignore_motion)
|
||||
{
|
||||
if (!ignore_motion)
|
||||
tp_gesture_detect_motion_gestures(tp, time);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state_hold_and_pointer_motion(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_handle_state_hold_and_pointer_motion(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
if (tp->queued & TOUCHPAD_EVENT_MOTION)
|
||||
tp_gesture_post_pointer_motion(tp, time);
|
||||
|
|
@ -1510,14 +1517,14 @@ tp_gesture_handle_state_hold_and_pointer_motion(struct tp_dispatch *tp, uint64_t
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state_pointer_motion(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_handle_state_pointer_motion(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
if (tp->queued & TOUCHPAD_EVENT_MOTION)
|
||||
tp_gesture_post_pointer_motion(tp, time);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state_scroll_start(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_handle_state_scroll_start(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct device_float_coords raw;
|
||||
struct normalized_coords delta;
|
||||
|
|
@ -1528,7 +1535,9 @@ tp_gesture_handle_state_scroll_start(struct tp_dispatch *tp, uint64_t time)
|
|||
/* We may confuse a pinch for a scroll initially,
|
||||
* allow ourselves to correct our guess.
|
||||
*/
|
||||
if (time < (tp->gesture.initial_time + DEFAULT_GESTURE_PINCH_TIMEOUT) &&
|
||||
if (usec_cmp(time,
|
||||
usec_add(tp->gesture.initial_time,
|
||||
DEFAULT_GESTURE_PINCH_TIMEOUT)) < 0 &&
|
||||
tp_gesture_is_pinch(tp)) {
|
||||
tp_gesture_handle_event(tp, GESTURE_EVENT_PINCH_START, time);
|
||||
return;
|
||||
|
|
@ -1547,7 +1556,7 @@ tp_gesture_handle_state_scroll_start(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state_scroll(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_handle_state_scroll(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct device_float_coords raw;
|
||||
struct normalized_coords delta;
|
||||
|
|
@ -1558,7 +1567,9 @@ tp_gesture_handle_state_scroll(struct tp_dispatch *tp, uint64_t time)
|
|||
/* We may confuse a pinch for a scroll initially,
|
||||
* allow ourselves to correct our guess.
|
||||
*/
|
||||
if (time < (tp->gesture.initial_time + DEFAULT_GESTURE_PINCH_TIMEOUT) &&
|
||||
if (usec_cmp(time,
|
||||
usec_add(tp->gesture.initial_time,
|
||||
DEFAULT_GESTURE_PINCH_TIMEOUT)) < 0 &&
|
||||
tp_gesture_is_pinch(tp)) {
|
||||
tp_gesture_handle_event(tp, GESTURE_EVENT_PINCH_START, time);
|
||||
return;
|
||||
|
|
@ -1580,7 +1591,7 @@ tp_gesture_handle_state_scroll(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state_swipe_start(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_handle_state_swipe_start(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct device_float_coords raw;
|
||||
struct normalized_coords delta;
|
||||
|
|
@ -1601,7 +1612,7 @@ tp_gesture_handle_state_swipe_start(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state_swipe(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_handle_state_swipe(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct device_float_coords raw;
|
||||
struct normalized_coords delta, unaccel;
|
||||
|
|
@ -1621,7 +1632,7 @@ tp_gesture_handle_state_swipe(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state_pinch_start(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_handle_state_pinch_start(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
const struct normalized_coords zero = { 0.0, 0.0 };
|
||||
double angle, angle_delta, distance, scale;
|
||||
|
|
@ -1662,7 +1673,7 @@ tp_gesture_handle_state_pinch_start(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state_pinch(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_handle_state_pinch(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
double angle, angle_delta, distance, scale;
|
||||
struct device_float_coords center, fdelta;
|
||||
|
|
@ -1702,7 +1713,7 @@ tp_gesture_handle_state_pinch(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state_3fg_drag_start(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_handle_state_3fg_drag_start(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
evdev_pointer_notify_button(tp->device,
|
||||
time,
|
||||
|
|
@ -1713,7 +1724,7 @@ tp_gesture_handle_state_3fg_drag_start(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state_3fg_drag(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_handle_state_3fg_drag(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
if (tp->queued & TOUCHPAD_EVENT_MOTION)
|
||||
tp_gesture_post_pointer_motion(tp, time);
|
||||
|
|
@ -1721,14 +1732,14 @@ tp_gesture_handle_state_3fg_drag(struct tp_dispatch *tp, uint64_t time)
|
|||
|
||||
static void
|
||||
tp_gesture_handle_state_3fg_drag_released(struct tp_dispatch *tp,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
bool ignore_motion)
|
||||
{
|
||||
tp_gesture_detect_motion_gestures(tp, time);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state(struct tp_dispatch *tp, uint64_t time, bool ignore_motion)
|
||||
tp_gesture_handle_state(struct tp_dispatch *tp, usec_t time, bool ignore_motion)
|
||||
{
|
||||
enum tp_gesture_state oldstate = tp->gesture.state;
|
||||
enum tp_gesture_state transitions[16] = { 0 };
|
||||
|
|
@ -1839,7 +1850,7 @@ tp_gesture_thumb_moved(struct tp_dispatch *tp)
|
|||
}
|
||||
|
||||
void
|
||||
tp_gesture_post_events(struct tp_dispatch *tp, uint64_t time, bool ignore_motion)
|
||||
tp_gesture_post_events(struct tp_dispatch *tp, usec_t time, bool ignore_motion)
|
||||
{
|
||||
if (tp->gesture.finger_count == 0)
|
||||
return;
|
||||
|
|
@ -1867,7 +1878,9 @@ tp_gesture_post_events(struct tp_dispatch *tp, uint64_t time, bool ignore_motion
|
|||
/* When pinching, the thumb tends to move slower than the finger,
|
||||
* so we may suppress it too early. Give it some time to move.
|
||||
*/
|
||||
if (time < (tp->gesture.initial_time + DEFAULT_GESTURE_PINCH_TIMEOUT) &&
|
||||
if (usec_cmp(time,
|
||||
usec_add(tp->gesture.initial_time,
|
||||
DEFAULT_GESTURE_PINCH_TIMEOUT)) < 0 &&
|
||||
tp_gesture_thumb_moved(tp))
|
||||
tp_thumb_reset(tp);
|
||||
|
||||
|
|
@ -1876,7 +1889,7 @@ tp_gesture_post_events(struct tp_dispatch *tp, uint64_t time, bool ignore_motion
|
|||
}
|
||||
|
||||
void
|
||||
tp_gesture_stop_twofinger_scroll(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_stop_twofinger_scroll(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_2FG)
|
||||
return;
|
||||
|
|
@ -1885,7 +1898,7 @@ tp_gesture_stop_twofinger_scroll(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_gesture_end(struct tp_dispatch *tp, uint64_t time, enum gesture_cancelled cancelled)
|
||||
tp_gesture_end(struct tp_dispatch *tp, usec_t time, enum gesture_cancelled cancelled)
|
||||
{
|
||||
switch (tp->gesture.state) {
|
||||
case GESTURE_STATE_NONE:
|
||||
|
|
@ -1917,13 +1930,13 @@ tp_gesture_end(struct tp_dispatch *tp, uint64_t time, enum gesture_cancelled can
|
|||
}
|
||||
|
||||
void
|
||||
tp_gesture_cancel(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_cancel(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
tp_gesture_end(tp, time, CANCEL_GESTURE);
|
||||
}
|
||||
|
||||
void
|
||||
tp_gesture_cancel_motion_gestures(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_cancel_motion_gestures(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
|
||||
switch (tp->gesture.state) {
|
||||
|
|
@ -1952,13 +1965,13 @@ tp_gesture_cancel_motion_gestures(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
void
|
||||
tp_gesture_stop(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_stop(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
tp_gesture_end(tp, time, END_GESTURE);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_finger_count_switch_timeout(uint64_t now, void *data)
|
||||
tp_gesture_finger_count_switch_timeout(usec_t now, void *data)
|
||||
{
|
||||
struct tp_dispatch *tp = data;
|
||||
|
||||
|
|
@ -1996,7 +2009,7 @@ tp_gesture_debounce_finger_changes(struct tp_dispatch *tp)
|
|||
}
|
||||
|
||||
void
|
||||
tp_gesture_update_finger_state(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_gesture_update_finger_state(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
unsigned int active_touches = 0;
|
||||
struct tp_touch *t;
|
||||
|
|
@ -2026,8 +2039,9 @@ tp_gesture_update_finger_state(struct tp_dispatch *tp, uint64_t time)
|
|||
/* Else debounce finger changes */
|
||||
} else if (active_touches != tp->gesture.finger_count_pending) {
|
||||
tp->gesture.finger_count_pending = active_touches;
|
||||
libinput_timer_set(&tp->gesture.finger_count_switch_timer,
|
||||
time + DEFAULT_GESTURE_SWITCH_TIMEOUT);
|
||||
libinput_timer_set(
|
||||
&tp->gesture.finger_count_switch_timer,
|
||||
usec_add(time, DEFAULT_GESTURE_SWITCH_TIMEOUT));
|
||||
}
|
||||
} else {
|
||||
tp->gesture.finger_count_pending = 0;
|
||||
|
|
|
|||
|
|
@ -29,10 +29,10 @@
|
|||
|
||||
#include "evdev-mt-touchpad.h"
|
||||
|
||||
#define DEFAULT_TAP_TIMEOUT_PERIOD ms2us(180)
|
||||
#define DEFAULT_DRAG_TIMEOUT_PERIOD_BASE ms2us(160)
|
||||
#define DEFAULT_DRAG_TIMEOUT_PERIOD_PERFINGER ms2us(20)
|
||||
#define DEFAULT_DRAGLOCK_TIMEOUT_PERIOD ms2us(300)
|
||||
#define DEFAULT_TAP_TIMEOUT_PERIOD usec_from_millis(180)
|
||||
#define DEFAULT_DRAG_TIMEOUT_PERIOD_BASE usec_from_millis(160)
|
||||
#define DEFAULT_DRAG_TIMEOUT_PERIOD_PERFINGER usec_from_millis(20)
|
||||
#define DEFAULT_DRAGLOCK_TIMEOUT_PERIOD usec_from_millis(300)
|
||||
#define DEFAULT_TAP_MOVE_THRESHOLD 1.3 /* mm */
|
||||
|
||||
enum tap_event {
|
||||
|
|
@ -120,7 +120,7 @@ log_tap_bug(struct tp_dispatch *tp, struct tp_touch *t, enum tap_event event)
|
|||
|
||||
static void
|
||||
tp_tap_notify(struct tp_dispatch *tp,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
int nfingers,
|
||||
enum libinput_button_state state)
|
||||
{
|
||||
|
|
@ -151,24 +151,25 @@ tp_tap_notify(struct tp_dispatch *tp,
|
|||
}
|
||||
|
||||
static void
|
||||
tp_tap_set_timer(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_tap_set_timer(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
libinput_timer_set(&tp->tap.timer, time + DEFAULT_TAP_TIMEOUT_PERIOD);
|
||||
libinput_timer_set(&tp->tap.timer, usec_add(time, DEFAULT_TAP_TIMEOUT_PERIOD));
|
||||
}
|
||||
|
||||
static void
|
||||
tp_tap_set_drag_timer(struct tp_dispatch *tp, uint64_t time, int nfingers_tapped)
|
||||
tp_tap_set_drag_timer(struct tp_dispatch *tp, usec_t time, int nfingers_tapped)
|
||||
{
|
||||
libinput_timer_set(
|
||||
&tp->tap.timer,
|
||||
time + DEFAULT_DRAG_TIMEOUT_PERIOD_BASE +
|
||||
(nfingers_tapped * DEFAULT_DRAG_TIMEOUT_PERIOD_PERFINGER));
|
||||
usec_t per_finger_timeout =
|
||||
usec_mul(DEFAULT_DRAG_TIMEOUT_PERIOD_PERFINGER, nfingers_tapped);
|
||||
usec_t timeout = usec_add(DEFAULT_DRAG_TIMEOUT_PERIOD_BASE, per_finger_timeout);
|
||||
libinput_timer_set(&tp->tap.timer, usec_add(time, timeout));
|
||||
}
|
||||
|
||||
static void
|
||||
tp_tap_set_draglock_timer(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_tap_set_draglock_timer(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
libinput_timer_set(&tp->tap.timer, time + DEFAULT_DRAGLOCK_TIMEOUT_PERIOD);
|
||||
libinput_timer_set(&tp->tap.timer,
|
||||
usec_add(time, DEFAULT_DRAGLOCK_TIMEOUT_PERIOD));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -189,7 +190,7 @@ static void
|
|||
tp_tap_idle_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case TAP_EVENT_TOUCH:
|
||||
|
|
@ -222,7 +223,7 @@ static void
|
|||
tp_tap_touch_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
|
||||
switch (event) {
|
||||
|
|
@ -276,7 +277,7 @@ static void
|
|||
tp_tap_hold_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
|
||||
switch (event) {
|
||||
|
|
@ -314,7 +315,7 @@ static void
|
|||
tp_tap_tapped_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
int nfingers_tapped)
|
||||
{
|
||||
switch (event) {
|
||||
|
|
@ -363,7 +364,7 @@ static void
|
|||
tp_tap_touch2_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
|
||||
switch (event) {
|
||||
|
|
@ -401,7 +402,7 @@ static void
|
|||
tp_tap_touch2_hold_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
|
||||
switch (event) {
|
||||
|
|
@ -436,7 +437,7 @@ static void
|
|||
tp_tap_touch2_release_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
|
||||
switch (event) {
|
||||
|
|
@ -505,7 +506,7 @@ static void
|
|||
tp_tap_touch3_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
|
||||
switch (event) {
|
||||
|
|
@ -543,7 +544,7 @@ static void
|
|||
tp_tap_touch3_hold_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
|
||||
switch (event) {
|
||||
|
|
@ -576,7 +577,7 @@ static void
|
|||
tp_tap_touch3_release_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
|
||||
switch (event) {
|
||||
|
|
@ -644,7 +645,7 @@ static void
|
|||
tp_tap_touch3_release2_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
|
||||
switch (event) {
|
||||
|
|
@ -742,7 +743,7 @@ static void
|
|||
tp_tap_dragging_or_doubletap_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
int nfingers_tapped)
|
||||
{
|
||||
switch (event) {
|
||||
|
|
@ -808,7 +809,7 @@ static void
|
|||
tp_tap_dragging_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
int nfingers_tapped)
|
||||
{
|
||||
|
||||
|
|
@ -872,7 +873,7 @@ static void
|
|||
tp_tap_dragging_wait_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
int nfingers_tapped)
|
||||
{
|
||||
|
||||
|
|
@ -919,7 +920,7 @@ static void
|
|||
tp_tap_dragging_tap_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
int nfingers_tapped)
|
||||
{
|
||||
|
||||
|
|
@ -979,7 +980,7 @@ static void
|
|||
tp_tap_dragging2_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
int nfingers_tapped)
|
||||
{
|
||||
|
||||
|
|
@ -1033,7 +1034,7 @@ static void
|
|||
tp_tap_dead_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
|
||||
switch (event) {
|
||||
|
|
@ -1060,7 +1061,7 @@ static void
|
|||
tp_tap_handle_event(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
enum tap_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
enum tp_tap_state current;
|
||||
|
||||
|
|
@ -1206,7 +1207,7 @@ tp_tap_enabled(struct tp_dispatch *tp)
|
|||
}
|
||||
|
||||
int
|
||||
tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_tap_handle_state(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct tp_touch *t;
|
||||
int filter_motion = 0;
|
||||
|
|
@ -1341,7 +1342,7 @@ tp_tap_post_process_state(struct tp_dispatch *tp)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_tap_handle_timeout(uint64_t time, void *data)
|
||||
tp_tap_handle_timeout(usec_t time, void *data)
|
||||
{
|
||||
struct tp_dispatch *tp = data;
|
||||
struct tp_touch *t;
|
||||
|
|
@ -1357,10 +1358,7 @@ tp_tap_handle_timeout(uint64_t time, void *data)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_tap_enabled_update(struct tp_dispatch *tp,
|
||||
bool suspended,
|
||||
bool enabled,
|
||||
uint64_t time)
|
||||
tp_tap_enabled_update(struct tp_dispatch *tp, bool suspended, bool enabled, usec_t time)
|
||||
{
|
||||
bool was_enabled = tp_tap_enabled(tp);
|
||||
|
||||
|
|
@ -1599,7 +1597,7 @@ tp_remove_tap(struct tp_dispatch *tp)
|
|||
}
|
||||
|
||||
void
|
||||
tp_release_all_taps(struct tp_dispatch *tp, uint64_t now)
|
||||
tp_release_all_taps(struct tp_dispatch *tp, usec_t now)
|
||||
{
|
||||
struct tp_touch *t;
|
||||
int i;
|
||||
|
|
@ -1626,13 +1624,13 @@ tp_release_all_taps(struct tp_dispatch *tp, uint64_t now)
|
|||
}
|
||||
|
||||
void
|
||||
tp_tap_suspend(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_tap_suspend(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
tp_tap_enabled_update(tp, true, tp->tap.enabled, time);
|
||||
}
|
||||
|
||||
void
|
||||
tp_tap_resume(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_tap_resume(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
tp_tap_enabled_update(tp, false, tp->tap.enabled, time);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
/* distance between fingers to assume it is not a scroll */
|
||||
#define SCROLL_MM_X 35
|
||||
#define SCROLL_MM_Y 25
|
||||
#define THUMB_TIMEOUT ms2us(100)
|
||||
#define THUMB_TIMEOUT usec_from_millis(100)
|
||||
|
||||
static inline const char *
|
||||
thumb_state_to_str(enum tp_thumb_state state)
|
||||
|
|
@ -193,7 +193,7 @@ tp_thumb_revive(struct tp_dispatch *tp, struct tp_touch *t)
|
|||
}
|
||||
|
||||
void
|
||||
tp_thumb_update_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_thumb_update_touch(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
if (!tp->thumb.detect_thumbs)
|
||||
return;
|
||||
|
|
@ -274,7 +274,7 @@ tp_thumb_update_multifinger(struct tp_dispatch *tp)
|
|||
speed_exceeded_count =
|
||||
max(speed_exceeded_count, t->speed.exceeded_count);
|
||||
|
||||
if (!oldest || t->initial_time < oldest->initial_time) {
|
||||
if (!oldest || usec_cmp(t->initial_time, oldest->initial_time) < 0) {
|
||||
oldest = t;
|
||||
}
|
||||
|
||||
|
|
@ -337,10 +337,13 @@ tp_thumb_update_multifinger(struct tp_dispatch *tp)
|
|||
* the behavior of the other touches.)
|
||||
*/
|
||||
|
||||
if (newest && (newest->initial_time - oldest->initial_time) < THUMB_TIMEOUT &&
|
||||
first->point.y < tp->thumb.lower_thumb_line) {
|
||||
tp_thumb_lift(tp);
|
||||
return;
|
||||
if (newest) {
|
||||
usec_t delta = usec_delta(newest->initial_time, oldest->initial_time);
|
||||
if (usec_cmp(delta, THUMB_TIMEOUT) < 0 &&
|
||||
first->point.y < tp->thumb.lower_thumb_line) {
|
||||
tp_thumb_lift(tp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we're past the THUMB_TIMEOUT, and the touches are relatively far
|
||||
|
|
|
|||
|
|
@ -28,19 +28,20 @@
|
|||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
#include <libwacom/libwacom.h>
|
||||
#endif
|
||||
|
||||
#include "util-input-event.h"
|
||||
|
||||
#include "evdev-mt-touchpad.h"
|
||||
#include "libinput-feature.h"
|
||||
#include "quirks.h"
|
||||
|
||||
#define DEFAULT_TRACKPOINT_ACTIVITY_TIMEOUT ms2us(300)
|
||||
#define DEFAULT_TRACKPOINT_EVENT_TIMEOUT ms2us(40)
|
||||
#define DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_1 ms2us(200)
|
||||
#define DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2 ms2us(500)
|
||||
#define DEFAULT_TRACKPOINT_ACTIVITY_TIMEOUT usec_from_millis(300)
|
||||
#define DEFAULT_TRACKPOINT_EVENT_TIMEOUT usec_from_millis(40)
|
||||
#define DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_1 usec_from_millis(200)
|
||||
#define DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2 usec_from_millis(500)
|
||||
#define FAKE_FINGER_OVERFLOW bit(7)
|
||||
#define THUMB_IGNORE_SPEED_THRESHOLD 20 /* mm/s */
|
||||
|
||||
|
|
@ -61,7 +62,7 @@ tp_motion_history_offset(struct tp_touch *t, int offset)
|
|||
struct normalized_coords
|
||||
tp_filter_motion(struct tp_dispatch *tp,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct device_float_coords raw;
|
||||
const struct normalized_coords zero = { 0.0, 0.0 };
|
||||
|
|
@ -78,7 +79,7 @@ tp_filter_motion(struct tp_dispatch *tp,
|
|||
struct normalized_coords
|
||||
tp_filter_motion_unaccelerated(struct tp_dispatch *tp,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct device_float_coords raw;
|
||||
const struct normalized_coords zero = { 0.0, 0.0 };
|
||||
|
|
@ -95,7 +96,7 @@ tp_filter_motion_unaccelerated(struct tp_dispatch *tp,
|
|||
struct normalized_coords
|
||||
tp_filter_scroll(struct tp_dispatch *tp,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct device_float_coords raw;
|
||||
const struct normalized_coords zero = { 0.0, 0.0 };
|
||||
|
|
@ -106,17 +107,19 @@ tp_filter_scroll(struct tp_dispatch *tp,
|
|||
/* Convert to device units with x/y in the same resolution */
|
||||
raw = tp_scale_to_xaxis(tp, *unaccelerated);
|
||||
|
||||
return filter_dispatch_scroll(tp->device->pointer.filter, &raw, tp, time);
|
||||
return filter_dispatch_scroll(tp->device->pointer.filter,
|
||||
&raw,
|
||||
tp,
|
||||
time,
|
||||
FILTER_SCROLL_TYPE_FINGER);
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_calculate_motion_speed(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_calculate_motion_speed(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
const struct tp_history_point *last;
|
||||
struct device_coords delta;
|
||||
struct phys_coords mm;
|
||||
double distance;
|
||||
double speed;
|
||||
|
||||
/* Don't do this on single-touch or semi-mt devices */
|
||||
if (!tp->has_mt || tp->semi_mt)
|
||||
|
|
@ -144,15 +147,16 @@ tp_calculate_motion_speed(struct tp_dispatch *tp, struct tp_touch *t, uint64_t t
|
|||
delta.y = abs(t->point.y - last->point.y);
|
||||
mm = evdev_device_unit_delta_to_mm(tp->device, &delta);
|
||||
|
||||
distance = length_in_mm(mm);
|
||||
speed = distance / (time - last->time); /* mm/us */
|
||||
speed *= 1000000; /* mm/s */
|
||||
usec_t tdelta = usec_delta(time, last->time);
|
||||
double distance = length_in_mm(mm);
|
||||
double speed = distance / usec_as_uint64_t(tdelta); /* mm/us */
|
||||
speed *= 1000000; /* mm/s */
|
||||
|
||||
t->speed.last_speed = speed;
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_motion_history_push(struct tp_touch *t, uint64_t time)
|
||||
tp_motion_history_push(struct tp_touch *t, usec_t time)
|
||||
{
|
||||
int motion_index = (t->history.index + 1) % TOUCHPAD_HISTORY_LENGTH;
|
||||
|
||||
|
|
@ -176,10 +180,9 @@ tp_motion_history_push(struct tp_touch *t, uint64_t time)
|
|||
* This only looks at x changes, y changes are ignored.
|
||||
*/
|
||||
static inline void
|
||||
tp_detect_wobbling(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_detect_wobbling(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
int dx, dy;
|
||||
uint64_t dtime;
|
||||
const struct device_coords *prev_point;
|
||||
|
||||
if (tp->nfingers_down != 1 || tp->nfingers_down != tp->old_nfingers_down)
|
||||
|
|
@ -196,11 +199,11 @@ tp_detect_wobbling(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
prev_point = &tp_motion_history_offset(t, 0)->point;
|
||||
dx = prev_point->x - t->point.x;
|
||||
dy = prev_point->y - t->point.y;
|
||||
dtime = time - tp->hysteresis.last_motion_time;
|
||||
usec_t dtime = usec_delta(time, tp->hysteresis.last_motion_time);
|
||||
|
||||
tp->hysteresis.last_motion_time = time;
|
||||
|
||||
if ((dx == 0 && dy != 0) || dtime > ms2us(40)) {
|
||||
if ((dx == 0 && dy != 0) || usec_cmp(dtime, usec_from_millis(40)) > 0) {
|
||||
t->hysteresis.x_motion_history = 0;
|
||||
return;
|
||||
}
|
||||
|
|
@ -318,7 +321,7 @@ tp_fake_finger_set(struct tp_dispatch *tp, evdev_usage_t usage, bool is_press)
|
|||
}
|
||||
|
||||
static inline void
|
||||
tp_new_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_new_touch(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
if (t->state == TOUCH_BEGIN || t->state == TOUCH_UPDATE ||
|
||||
t->state == TOUCH_HOVERING)
|
||||
|
|
@ -353,7 +356,7 @@ tp_new_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
}
|
||||
|
||||
static inline void
|
||||
tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
t->dirty = true;
|
||||
t->state = TOUCH_BEGIN;
|
||||
|
|
@ -377,7 +380,7 @@ tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
* need.
|
||||
*/
|
||||
static inline void
|
||||
tp_maybe_end_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_maybe_end_touch(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
switch (t->state) {
|
||||
case TOUCH_NONE:
|
||||
|
|
@ -422,7 +425,7 @@ tp_recover_ended_touch(struct tp_dispatch *tp, struct tp_touch *t)
|
|||
* Use tp_maybe_end_touch() instead.
|
||||
*/
|
||||
static inline void
|
||||
tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
if (t->state != TOUCH_MAYBE_END) {
|
||||
evdev_log_bug_libinput(tp->device,
|
||||
|
|
@ -436,7 +439,7 @@ tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
t->palm.state = PALM_NONE;
|
||||
t->state = TOUCH_END;
|
||||
t->pinned.is_pinned = false;
|
||||
t->palm.time = 0;
|
||||
t->palm.time = usec_from_uint64_t(0);
|
||||
t->speed.exceeded_count = 0;
|
||||
tp->queued |= TOUCHPAD_EVENT_MOTION;
|
||||
}
|
||||
|
|
@ -445,14 +448,14 @@ tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
* End the touch sequence on ABS_MT_TRACKING_ID -1 or when the BTN_TOOL_* 0 is received.
|
||||
*/
|
||||
static inline void
|
||||
tp_end_sequence(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_end_sequence(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
t->has_ended = true;
|
||||
tp_maybe_end_touch(tp, t, time);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_stop_actions(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_stop_actions(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
tp_edge_scroll_stop_events(tp, time);
|
||||
tp_gesture_cancel(tp, time);
|
||||
|
|
@ -500,7 +503,7 @@ rotated(struct tp_dispatch *tp, evdev_usage_t usage, int value)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_process_absolute(struct tp_dispatch *tp, const struct evdev_event *e, uint64_t time)
|
||||
tp_process_absolute(struct tp_dispatch *tp, const struct evdev_event *e, usec_t time)
|
||||
{
|
||||
struct tp_touch *t = tp_current_touch(tp);
|
||||
|
||||
|
|
@ -555,9 +558,7 @@ tp_process_absolute(struct tp_dispatch *tp, const struct evdev_event *e, uint64_
|
|||
}
|
||||
|
||||
static void
|
||||
tp_process_absolute_st(struct tp_dispatch *tp,
|
||||
const struct evdev_event *e,
|
||||
uint64_t time)
|
||||
tp_process_absolute_st(struct tp_dispatch *tp, const struct evdev_event *e, usec_t time)
|
||||
{
|
||||
struct tp_touch *t = tp_current_touch(tp);
|
||||
|
||||
|
|
@ -585,7 +586,7 @@ tp_process_absolute_st(struct tp_dispatch *tp,
|
|||
}
|
||||
|
||||
static inline void
|
||||
tp_restore_synaptics_touches(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_restore_synaptics_touches(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int nfake_touches;
|
||||
|
|
@ -619,7 +620,7 @@ tp_restore_synaptics_touches(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_process_fake_touches(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_process_fake_touches(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct tp_touch *t;
|
||||
unsigned int nfake_touches;
|
||||
|
|
@ -672,7 +673,7 @@ tp_process_fake_touches(struct tp_dispatch *tp, uint64_t time)
|
|||
static void
|
||||
tp_process_trackpoint_button(struct tp_dispatch *tp,
|
||||
const struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct evdev_dispatch *dispatch;
|
||||
evdev_usage_t button;
|
||||
|
|
@ -704,7 +705,7 @@ tp_process_trackpoint_button(struct tp_dispatch *tp,
|
|||
}
|
||||
|
||||
static void
|
||||
tp_process_key(struct tp_dispatch *tp, const struct evdev_event *e, uint64_t time)
|
||||
tp_process_key(struct tp_dispatch *tp, const struct evdev_event *e, usec_t time)
|
||||
{
|
||||
/* ignore kernel key repeat */
|
||||
if (e->value == 2)
|
||||
|
|
@ -735,12 +736,12 @@ tp_process_key(struct tp_dispatch *tp, const struct evdev_event *e, uint64_t tim
|
|||
}
|
||||
|
||||
static void
|
||||
tp_process_msc(struct tp_dispatch *tp, const struct evdev_event *e, uint64_t time)
|
||||
tp_process_msc(struct tp_dispatch *tp, const struct evdev_event *e, usec_t time)
|
||||
{
|
||||
if (evdev_usage_eq(e->usage, EVDEV_MSC_TIMESTAMP))
|
||||
return;
|
||||
|
||||
tp->quirks.msc_timestamp.now = e->value;
|
||||
tp->quirks.msc_timestamp.now = usec_from_uint64_t(e->value);
|
||||
tp->queued |= TOUCHPAD_EVENT_TIMESTAMP;
|
||||
}
|
||||
|
||||
|
|
@ -826,7 +827,7 @@ tp_palm_in_edge(const struct tp_dispatch *tp, const struct tp_touch *t)
|
|||
}
|
||||
|
||||
static bool
|
||||
tp_palm_detect_dwt_triggered(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_palm_detect_dwt_triggered(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
if (tp->dwt.dwt_enabled && tp->dwt.keyboard_active && t->state == TOUCH_BEGIN) {
|
||||
t->palm.state = PALM_TYPING;
|
||||
|
|
@ -842,8 +843,8 @@ tp_palm_detect_dwt_triggered(struct tp_dispatch *tp, struct tp_touch *t, uint64_
|
|||
started once we stop typing will be able to control the
|
||||
pointer (alas not tap, etc.).
|
||||
*/
|
||||
if (t->palm.time == 0 ||
|
||||
t->palm.time > tp->dwt.keyboard_last_press_time) {
|
||||
if (usec_is_zero(t->palm.time) ||
|
||||
usec_cmp(t->palm.time, tp->dwt.keyboard_last_press_time) > 0) {
|
||||
t->palm.state = PALM_NONE;
|
||||
evdev_log_debug(
|
||||
tp->device,
|
||||
|
|
@ -858,7 +859,7 @@ tp_palm_detect_dwt_triggered(struct tp_dispatch *tp, struct tp_touch *t, uint64_
|
|||
static bool
|
||||
tp_palm_detect_trackpoint_triggered(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
if (!tp->palm.monitor_trackpoint)
|
||||
return false;
|
||||
|
|
@ -872,8 +873,8 @@ tp_palm_detect_trackpoint_triggered(struct tp_dispatch *tp,
|
|||
if (t->palm.state == PALM_TRACKPOINT && t->state == TOUCH_UPDATE &&
|
||||
!tp->palm.trackpoint_active) {
|
||||
|
||||
if (t->palm.time == 0 ||
|
||||
t->palm.time > tp->palm.trackpoint_last_event_time) {
|
||||
if (usec_is_zero(t->palm.time) ||
|
||||
usec_cmp(t->palm.time, tp->palm.trackpoint_last_event_time) > 0) {
|
||||
t->palm.state = PALM_NONE;
|
||||
evdev_log_debug(
|
||||
tp->device,
|
||||
|
|
@ -886,7 +887,7 @@ tp_palm_detect_trackpoint_triggered(struct tp_dispatch *tp,
|
|||
}
|
||||
|
||||
static bool
|
||||
tp_palm_detect_tool_triggered(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_palm_detect_tool_triggered(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
if (!tp->palm.use_mt_tool)
|
||||
return false;
|
||||
|
|
@ -903,16 +904,15 @@ tp_palm_detect_tool_triggered(struct tp_dispatch *tp, struct tp_touch *t, uint64
|
|||
}
|
||||
|
||||
static inline bool
|
||||
tp_palm_detect_move_out_of_edge(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
uint64_t time)
|
||||
tp_palm_detect_move_out_of_edge(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
const int PALM_TIMEOUT = ms2us(200);
|
||||
const usec_t PALM_TIMEOUT = usec_from_millis(200);
|
||||
int directions = 0;
|
||||
struct device_float_coords delta;
|
||||
int dirs;
|
||||
|
||||
if (time < t->palm.time + PALM_TIMEOUT && !tp_palm_in_edge(tp, t)) {
|
||||
if (usec_cmp(time, usec_add(t->palm.time, PALM_TIMEOUT)) < 0 &&
|
||||
!tp_palm_in_edge(tp, t)) {
|
||||
if (tp_palm_was_in_side_edge(tp, t))
|
||||
directions = NE | E | SE | SW | W | NW;
|
||||
else if (tp_palm_was_in_top_edge(tp, t))
|
||||
|
|
@ -930,7 +930,7 @@ tp_palm_detect_move_out_of_edge(struct tp_dispatch *tp,
|
|||
}
|
||||
|
||||
static inline bool
|
||||
tp_palm_detect_multifinger(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_palm_detect_multifinger(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
struct tp_touch *other;
|
||||
|
||||
|
|
@ -960,7 +960,7 @@ tp_palm_detect_multifinger(struct tp_dispatch *tp, struct tp_touch *t, uint64_t
|
|||
static inline bool
|
||||
tp_palm_detect_touch_size_triggered(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
if (!tp->palm.use_size)
|
||||
return false;
|
||||
|
|
@ -983,7 +983,7 @@ tp_palm_detect_touch_size_triggered(struct tp_dispatch *tp,
|
|||
}
|
||||
|
||||
static inline bool
|
||||
tp_palm_detect_edge(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_palm_detect_edge(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
if (t->palm.state == PALM_EDGE) {
|
||||
if (tp_palm_detect_multifinger(tp, t, time)) {
|
||||
|
|
@ -1030,7 +1030,7 @@ tp_palm_detect_edge(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
static bool
|
||||
tp_palm_detect_pressure_triggered(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
if (!tp->palm.use_pressure)
|
||||
return false;
|
||||
|
|
@ -1047,7 +1047,7 @@ tp_palm_detect_pressure_triggered(struct tp_dispatch *tp,
|
|||
static bool
|
||||
tp_palm_detect_arbitration_triggered(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
if (tp->arbitration.state == ARBITRATION_NOT_ACTIVE)
|
||||
return false;
|
||||
|
|
@ -1058,7 +1058,7 @@ tp_palm_detect_arbitration_triggered(struct tp_dispatch *tp,
|
|||
}
|
||||
|
||||
static void
|
||||
tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
const char *palm_state;
|
||||
enum touch_palm_state oldstate = t->palm.state;
|
||||
|
|
@ -1134,7 +1134,7 @@ out:
|
|||
}
|
||||
|
||||
static void
|
||||
tp_unhover_pressure(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_unhover_pressure(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct tp_touch *t;
|
||||
int i;
|
||||
|
|
@ -1218,7 +1218,7 @@ tp_unhover_pressure(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_unhover_size(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_unhover_size(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct tp_touch *t;
|
||||
int low = tp->touch_size.low, high = tp->touch_size.high;
|
||||
|
|
@ -1258,7 +1258,7 @@ tp_unhover_size(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_unhover_fake_touches(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_unhover_fake_touches(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct tp_touch *t;
|
||||
unsigned int nfake_touches;
|
||||
|
|
@ -1312,7 +1312,7 @@ tp_unhover_fake_touches(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_unhover_touches(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_unhover_touches(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
if (tp->pressure.use_pressure)
|
||||
tp_unhover_pressure(tp, time);
|
||||
|
|
@ -1398,17 +1398,17 @@ tp_need_motion_history_reset(struct tp_dispatch *tp)
|
|||
}
|
||||
|
||||
static bool
|
||||
tp_detect_jumps(const struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
tp_detect_jumps(const struct tp_dispatch *tp, struct tp_touch *t, usec_t time)
|
||||
{
|
||||
struct device_coords delta;
|
||||
struct phys_coords mm;
|
||||
struct tp_history_point *last;
|
||||
double abs_distance, rel_distance;
|
||||
bool is_jump = false;
|
||||
uint64_t tdelta;
|
||||
usec_t tdelta;
|
||||
/* Reference interval from the touchpad the various thresholds
|
||||
* were measured from */
|
||||
unsigned int reference_interval = ms2us(12);
|
||||
usec_t reference_interval = usec_from_millis(12);
|
||||
|
||||
/* On some touchpads the firmware does funky stuff and we cannot
|
||||
* have our own jump detection, e.g. Lenovo Carbon X1 Gen 6 (see
|
||||
|
|
@ -1431,7 +1431,7 @@ tp_detect_jumps(const struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
/* called before tp_motion_history_push, so offset 0 is the most
|
||||
* recent coordinate */
|
||||
last = tp_motion_history_offset(t, 0);
|
||||
tdelta = time - last->time;
|
||||
tdelta = usec_delta(time, last->time);
|
||||
|
||||
/* For test devices we always force the time delta to 12, at least
|
||||
until the test suite actually does proper intervals. */
|
||||
|
|
@ -1441,7 +1441,8 @@ tp_detect_jumps(const struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
/* If the last frame is more than 30ms ago, we have irregular
|
||||
* frames, who knows what's a pointer jump here and what's
|
||||
* legitimate movement.... */
|
||||
if (tdelta > 2.5 * reference_interval || tdelta == 0)
|
||||
if (usec_cmp(tdelta, usec_mul(reference_interval, 2.5)) > 0 ||
|
||||
usec_is_zero(tdelta))
|
||||
return false;
|
||||
|
||||
/* We historically expected ~12ms frame intervals, so the numbers
|
||||
|
|
@ -1450,7 +1451,8 @@ tp_detect_jumps(const struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
delta.x = abs(t->point.x - last->point.x);
|
||||
delta.y = abs(t->point.y - last->point.y);
|
||||
mm = evdev_device_unit_delta_to_mm(tp->device, &delta);
|
||||
abs_distance = hypot(mm.x, mm.y) * reference_interval / tdelta;
|
||||
abs_distance = hypot(mm.x, mm.y) * usec_as_uint64_t(reference_interval) /
|
||||
usec_as_uint64_t(tdelta);
|
||||
rel_distance = abs_distance - t->jumps.last_delta_mm;
|
||||
|
||||
/* Special case for the ALPS devices in the Lenovo ThinkPad E465,
|
||||
|
|
@ -1491,9 +1493,9 @@ tp_detect_jumps(const struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
static inline void
|
||||
tp_motion_history_fix_last(struct tp_dispatch *tp,
|
||||
struct tp_touch *t,
|
||||
unsigned int jumping_interval,
|
||||
unsigned int normal_interval,
|
||||
uint64_t time)
|
||||
usec_t jumping_interval,
|
||||
usec_t normal_interval,
|
||||
usec_t time)
|
||||
{
|
||||
if (t->state != TOUCH_UPDATE)
|
||||
return;
|
||||
|
|
@ -1509,12 +1511,13 @@ tp_motion_history_fix_last(struct tp_dispatch *tp,
|
|||
struct tp_history_point *p;
|
||||
|
||||
p = tp_motion_history_offset(t, i);
|
||||
p->time = time - jumping_interval - normal_interval * i;
|
||||
p->time = usec_sub(usec_sub(time, jumping_interval),
|
||||
usec_mul(normal_interval, i));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tp_process_msc_timestamp(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_process_msc_timestamp(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct msc_timestamp *m = &tp->quirks.msc_timestamp;
|
||||
|
||||
|
|
@ -1548,15 +1551,15 @@ tp_process_msc_timestamp(struct tp_dispatch *tp, uint64_t time)
|
|||
delta is equivalent to 10 events and the movement is x, we
|
||||
instead pretend there was movement of x/10.
|
||||
*/
|
||||
if (m->now == 0) {
|
||||
if (usec_is_zero(m->now)) {
|
||||
m->state = JUMP_STATE_EXPECT_FIRST;
|
||||
m->interval = 0;
|
||||
m->interval = usec_from_uint64_t(0);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (m->state) {
|
||||
case JUMP_STATE_EXPECT_FIRST:
|
||||
if (m->now > ms2us(20)) {
|
||||
if (usec_cmp(m->now, usec_from_millis(20)) > 0) {
|
||||
m->state = JUMP_STATE_IGNORE;
|
||||
} else {
|
||||
m->state = JUMP_STATE_EXPECT_DELAY;
|
||||
|
|
@ -1564,13 +1567,13 @@ tp_process_msc_timestamp(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
break;
|
||||
case JUMP_STATE_EXPECT_DELAY:
|
||||
if (m->now > m->interval * 2) {
|
||||
uint32_t tdelta; /* µs */
|
||||
if (usec_cmp(m->now, usec_mul(m->interval, 2)) > 0) {
|
||||
usec_t tdelta; /* µs */
|
||||
struct tp_touch *t;
|
||||
|
||||
/* The current time is > 2 times the interval so we
|
||||
* have a jump. Fix the motion history */
|
||||
tdelta = m->now - m->interval;
|
||||
tdelta = usec_delta(m->now, m->interval);
|
||||
|
||||
tp_for_each_touch(tp, t) {
|
||||
tp_motion_history_fix_last(tp,
|
||||
|
|
@ -1588,7 +1591,9 @@ tp_process_msc_timestamp(struct tp_dispatch *tp, uint64_t time)
|
|||
* only ever see those jumps over the first three events it
|
||||
* doesn't matter.
|
||||
*/
|
||||
filter_restart(tp->device->pointer.filter, tp, time - tdelta);
|
||||
filter_restart(tp->device->pointer.filter,
|
||||
tp,
|
||||
usec_sub(time, tdelta));
|
||||
}
|
||||
break;
|
||||
case JUMP_STATE_IGNORE:
|
||||
|
|
@ -1597,7 +1602,7 @@ tp_process_msc_timestamp(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_pre_process_state(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_pre_process_state(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct tp_touch *t;
|
||||
|
||||
|
|
@ -1619,7 +1624,7 @@ tp_pre_process_state(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_process_state(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_process_state(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct tp_touch *t;
|
||||
bool restart_filter = false;
|
||||
|
|
@ -1730,7 +1735,7 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_post_process_state(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_post_process_state(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct tp_touch *t;
|
||||
|
||||
|
|
@ -1764,7 +1769,7 @@ tp_post_process_state(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_post_events(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_post_events(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
bool ignore_motion = false;
|
||||
|
||||
|
|
@ -1815,7 +1820,7 @@ tp_apply_rotation(struct evdev_device *device)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_handle_state(struct tp_dispatch *tp, uint64_t time)
|
||||
tp_handle_state(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
tp_pre_process_state(tp, time);
|
||||
tp_process_state(tp, time);
|
||||
|
|
@ -1853,7 +1858,7 @@ static void
|
|||
tp_interface_process_event(struct evdev_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct tp_dispatch *tp = tp_dispatch(dispatch);
|
||||
|
||||
|
|
@ -1884,11 +1889,27 @@ static void
|
|||
tp_interface_process(struct evdev_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
size_t nevents;
|
||||
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
|
||||
|
||||
struct evdev_event *ev_syn = &events[nevents - 1];
|
||||
if (evdev_usage_enum(ev_syn->usage) == EVDEV_SYN_REPORT) {
|
||||
/* A SYN_REPORT 1 event is a kernel-inserted SYN_REPORT.
|
||||
* This happens most commonly on key repeat but in the
|
||||
* touchpad code this causes issues with
|
||||
* timestamp deltas (see e.g. #1145).
|
||||
*
|
||||
* Let's drop this frame, hoping it wasn't important.
|
||||
*/
|
||||
if (ev_syn->value == 1) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
evdev_log_bug_libinput(device, "Terminating event is not a SYN_REPORT");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < nevents; i++) {
|
||||
tp_interface_process_event(dispatch, device, &events[i], time);
|
||||
}
|
||||
|
|
@ -1961,7 +1982,7 @@ tp_release_fake_touches(struct tp_dispatch *tp)
|
|||
static void
|
||||
tp_clear_state(struct tp_dispatch *tp)
|
||||
{
|
||||
uint64_t now = libinput_now(tp_libinput_context(tp));
|
||||
usec_t now = libinput_now(tp_libinput_context(tp));
|
||||
struct tp_touch *t;
|
||||
|
||||
/* Unroll the touchpad state.
|
||||
|
|
@ -2085,7 +2106,7 @@ tp_resume(struct tp_dispatch *tp,
|
|||
}
|
||||
|
||||
static void
|
||||
tp_trackpoint_timeout(uint64_t now, void *data)
|
||||
tp_trackpoint_timeout(usec_t now, void *data)
|
||||
{
|
||||
struct tp_dispatch *tp = data;
|
||||
|
||||
|
|
@ -2097,7 +2118,7 @@ tp_trackpoint_timeout(uint64_t now, void *data)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_trackpoint_event(uint64_t time, struct libinput_event *event, void *data)
|
||||
tp_trackpoint_event(usec_t time, struct libinput_event *event, void *data)
|
||||
{
|
||||
struct tp_dispatch *tp = data;
|
||||
|
||||
|
|
@ -2115,7 +2136,7 @@ tp_trackpoint_event(uint64_t time, struct libinput_event *event, void *data)
|
|||
/* Require at least three events before enabling palm detection */
|
||||
if (tp->palm.trackpoint_event_count < 3) {
|
||||
libinput_timer_set(&tp->palm.trackpoint_timer,
|
||||
time + DEFAULT_TRACKPOINT_EVENT_TIMEOUT);
|
||||
usec_add(time, DEFAULT_TRACKPOINT_EVENT_TIMEOUT));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2125,18 +2146,18 @@ tp_trackpoint_event(uint64_t time, struct libinput_event *event, void *data)
|
|||
}
|
||||
|
||||
libinput_timer_set(&tp->palm.trackpoint_timer,
|
||||
time + DEFAULT_TRACKPOINT_ACTIVITY_TIMEOUT);
|
||||
usec_add(time, tp->palm.timeout));
|
||||
}
|
||||
|
||||
static void
|
||||
tp_keyboard_timeout(uint64_t now, void *data)
|
||||
tp_keyboard_timeout(usec_t now, void *data)
|
||||
{
|
||||
struct tp_dispatch *tp = data;
|
||||
|
||||
if (tp->dwt.dwt_enabled &&
|
||||
long_any_bit_set(tp->dwt.key_mask, ARRAY_LENGTH(tp->dwt.key_mask))) {
|
||||
libinput_timer_set(&tp->dwt.keyboard_timer,
|
||||
now + DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2);
|
||||
usec_add(now, tp->dwt.timeout));
|
||||
tp->dwt.keyboard_last_press_time = now;
|
||||
evdev_log_debug(tp->device, "palm: keyboard timeout refresh\n");
|
||||
return;
|
||||
|
|
@ -2198,11 +2219,11 @@ tp_key_ignore_for_dwt(unsigned int keycode)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
|
||||
tp_keyboard_event(usec_t time, struct libinput_event *event, void *data)
|
||||
{
|
||||
struct tp_dispatch *tp = data;
|
||||
struct libinput_event_keyboard *kbdev;
|
||||
unsigned int timeout;
|
||||
usec_t timeout;
|
||||
unsigned int key;
|
||||
bool is_modifier;
|
||||
|
||||
|
|
@ -2251,12 +2272,12 @@ tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
|
|||
tp->dwt.keyboard_active = true;
|
||||
timeout = DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_1;
|
||||
} else {
|
||||
timeout = DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2;
|
||||
timeout = tp->dwt.timeout;
|
||||
}
|
||||
|
||||
tp->dwt.keyboard_last_press_time = time;
|
||||
long_set_bit(tp->dwt.key_mask, key);
|
||||
libinput_timer_set(&tp->dwt.keyboard_timer, time + timeout);
|
||||
libinput_timer_set(&tp->dwt.keyboard_timer, usec_add(time, timeout));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -2342,7 +2363,7 @@ tp_pair_trackpoint(struct evdev_device *touchpad, struct evdev_device *trackpoin
|
|||
}
|
||||
|
||||
static void
|
||||
tp_lid_switch_event(uint64_t time, struct libinput_event *event, void *data)
|
||||
tp_lid_switch_event(usec_t time, struct libinput_event *event, void *data)
|
||||
{
|
||||
struct tp_dispatch *tp = data;
|
||||
struct libinput_event_switch *swev;
|
||||
|
|
@ -2367,7 +2388,7 @@ tp_lid_switch_event(uint64_t time, struct libinput_event *event, void *data)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_tablet_mode_switch_event(uint64_t time, struct libinput_event *event, void *data)
|
||||
tp_tablet_mode_switch_event(usec_t time, struct libinput_event *event, void *data)
|
||||
{
|
||||
struct tp_dispatch *tp = data;
|
||||
struct libinput_event_switch *swev;
|
||||
|
|
@ -2673,7 +2694,7 @@ evdev_tag_touchpad(struct evdev_device *device, struct udev_device *udev_device)
|
|||
}
|
||||
|
||||
static void
|
||||
tp_arbitration_timeout(uint64_t now, void *data)
|
||||
tp_arbitration_timeout(usec_t now, void *data)
|
||||
{
|
||||
struct tp_dispatch *tp = data;
|
||||
|
||||
|
|
@ -2686,7 +2707,7 @@ tp_interface_toggle_touch(struct evdev_dispatch *dispatch,
|
|||
struct evdev_device *device,
|
||||
enum evdev_arbitration_state which,
|
||||
const struct phys_rect *rect,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct tp_dispatch *tp = tp_dispatch(dispatch);
|
||||
|
||||
|
|
@ -2709,7 +2730,7 @@ tp_interface_toggle_touch(struct evdev_dispatch *dispatch,
|
|||
* arbitration by just a little bit so that any touch in
|
||||
* event is caught as palm touch. */
|
||||
libinput_timer_set(&tp->arbitration.arbitration_timer,
|
||||
time + ms2us(90));
|
||||
usec_add_millis(time, 90));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -2738,6 +2759,32 @@ tp_interface_left_handed_toggled(struct evdev_dispatch *dispatch,
|
|||
tp_change_rotation(device, DONT_NOTIFY);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_interface_disable_feature(struct evdev_dispatch *dispatch,
|
||||
enum libinput_feature feature)
|
||||
{
|
||||
struct tp_dispatch *tp = tp_dispatch(dispatch);
|
||||
|
||||
switch (feature) {
|
||||
case LIBINPUT_FEATURE_TOUCHPAD_JUMP_DETECTION:
|
||||
tp->jump.detection_disabled = true;
|
||||
break;
|
||||
case LIBINPUT_FEATURE_TOUCHPAD_HYSTERESIS:
|
||||
tp->hysteresis.enabled = false;
|
||||
break;
|
||||
case LIBINPUT_FEATURE_TOUCHPAD_PALM_DETECTION:
|
||||
tp->palm.use_mt_tool = false;
|
||||
tp->palm.use_pressure = false;
|
||||
tp->palm.use_size = false;
|
||||
tp->palm.right_edge = INT_MAX;
|
||||
tp->palm.left_edge = INT_MIN;
|
||||
tp->palm.upper_edge = INT_MIN;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static struct evdev_dispatch_interface tp_interface = {
|
||||
.process = tp_interface_process,
|
||||
.suspend = tp_interface_suspend,
|
||||
|
|
@ -2752,6 +2799,7 @@ static struct evdev_dispatch_interface tp_interface = {
|
|||
.touch_arbitration_update_rect = NULL,
|
||||
.get_switch_state = NULL,
|
||||
.left_handed_toggle = tp_interface_left_handed_toggled,
|
||||
.disable_feature = tp_interface_disable_feature,
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
@ -2890,12 +2938,12 @@ tp_init_accel(struct tp_dispatch *tp, enum libinput_config_accel_profile which)
|
|||
tp->device->model_flags & EVDEV_MODEL_LENOVO_X220_TOUCHPAD_FW81) {
|
||||
filter = create_pointer_accelerator_filter_lenovo_x230(dpi, use_v_avg);
|
||||
} else {
|
||||
uint64_t eds_threshold = 0;
|
||||
uint64_t eds_value = 0;
|
||||
usec_t eds_threshold = usec_from_uint64_t(0);
|
||||
usec_t eds_value = usec_from_uint64_t(0);
|
||||
|
||||
if (libevdev_get_id_bustype(device->evdev) == BUS_BLUETOOTH) {
|
||||
eds_threshold = ms2us(50);
|
||||
eds_value = ms2us(10);
|
||||
eds_threshold = usec_from_millis(50);
|
||||
eds_value = usec_from_millis(10);
|
||||
}
|
||||
filter = create_pointer_accelerator_filter_touchpad(dpi,
|
||||
eds_threshold,
|
||||
|
|
@ -2984,7 +3032,7 @@ tp_scroll_config_scroll_method_set_method(struct libinput_device *device,
|
|||
{
|
||||
struct evdev_device *evdev = evdev_device(device);
|
||||
struct tp_dispatch *tp = (struct tp_dispatch *)evdev->dispatch;
|
||||
uint64_t time = libinput_now(tp_libinput_context(tp));
|
||||
usec_t time = libinput_now(tp_libinput_context(tp));
|
||||
|
||||
if (method == tp->scroll.method)
|
||||
return LIBINPUT_CONFIG_STATUS_SUCCESS;
|
||||
|
|
@ -3122,6 +3170,30 @@ tp_dwt_config_get_default(struct libinput_device *device)
|
|||
: LIBINPUT_CONFIG_DWT_DISABLED;
|
||||
}
|
||||
|
||||
static enum libinput_config_status
|
||||
tp_dwt_config_set_timeout(struct libinput_device *device, usec_t timeout)
|
||||
{
|
||||
struct evdev_device *evdev = evdev_device(device);
|
||||
struct tp_dispatch *tp = (struct tp_dispatch *)evdev->dispatch;
|
||||
|
||||
if (usec_cmp(timeout, usec_from_millis(100)) < 0 ||
|
||||
usec_cmp(timeout, usec_from_millis(5000)) > 0)
|
||||
return LIBINPUT_CONFIG_STATUS_INVALID;
|
||||
|
||||
tp->dwt.timeout = timeout;
|
||||
|
||||
return LIBINPUT_CONFIG_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static usec_t
|
||||
tp_dwt_config_get_timeout(struct libinput_device *device)
|
||||
{
|
||||
struct evdev_device *evdev = evdev_device(device);
|
||||
struct tp_dispatch *tp = (struct tp_dispatch *)evdev->dispatch;
|
||||
|
||||
return tp->dwt.timeout;
|
||||
}
|
||||
|
||||
static int
|
||||
tp_dwtp_config_is_available(struct libinput_device *device)
|
||||
{
|
||||
|
|
@ -3174,6 +3246,30 @@ tp_dwtp_config_get_default(struct libinput_device *device)
|
|||
: LIBINPUT_CONFIG_DWTP_DISABLED;
|
||||
}
|
||||
|
||||
static enum libinput_config_status
|
||||
tp_dwtp_config_set_timeout(struct libinput_device *device, usec_t timeout)
|
||||
{
|
||||
struct evdev_device *evdev = evdev_device(device);
|
||||
struct tp_dispatch *tp = (struct tp_dispatch *)evdev->dispatch;
|
||||
|
||||
if (usec_cmp(timeout, usec_from_millis(100)) < 0 ||
|
||||
usec_cmp(timeout, usec_from_millis(5000)) > 0)
|
||||
return LIBINPUT_CONFIG_STATUS_INVALID;
|
||||
|
||||
tp->palm.timeout = timeout;
|
||||
|
||||
return LIBINPUT_CONFIG_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static usec_t
|
||||
tp_dwtp_config_get_timeout(struct libinput_device *device)
|
||||
{
|
||||
struct evdev_device *evdev = evdev_device(device);
|
||||
struct tp_dispatch *tp = (struct tp_dispatch *)evdev->dispatch;
|
||||
|
||||
return tp->palm.timeout;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
tp_is_tpkb_combo_below(struct evdev_device *device)
|
||||
{
|
||||
|
|
@ -3210,7 +3306,10 @@ tp_init_dwt(struct tp_dispatch *tp, struct evdev_device *device)
|
|||
tp->dwt.config.set_enabled = tp_dwt_config_set;
|
||||
tp->dwt.config.get_enabled = tp_dwt_config_get;
|
||||
tp->dwt.config.get_default_enabled = tp_dwt_config_get_default;
|
||||
tp->dwt.config.set_timeout = tp_dwt_config_set_timeout;
|
||||
tp->dwt.config.get_timeout = tp_dwt_config_get_timeout;
|
||||
tp->dwt.dwt_enabled = tp_dwt_default_enabled(tp);
|
||||
tp->dwt.timeout = DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2;
|
||||
device->base.config.dwt = &tp->dwt.config;
|
||||
}
|
||||
|
||||
|
|
@ -3226,6 +3325,9 @@ tp_init_dwtp(struct tp_dispatch *tp, struct evdev_device *device)
|
|||
tp->palm.config.set_enabled = tp_dwtp_config_set;
|
||||
tp->palm.config.get_enabled = tp_dwtp_config_get;
|
||||
tp->palm.config.get_default_enabled = tp_dwtp_config_get_default;
|
||||
tp->palm.config.set_timeout = tp_dwtp_config_set_timeout;
|
||||
tp->palm.config.get_timeout = tp_dwtp_config_get_timeout;
|
||||
tp->palm.timeout = DEFAULT_TRACKPOINT_ACTIVITY_TIMEOUT;
|
||||
device->base.config.dwtp = &tp->palm.config;
|
||||
}
|
||||
|
||||
|
|
@ -3574,8 +3676,8 @@ tp_init_pressurepad(struct tp_dispatch *tp, struct evdev_device *device)
|
|||
*
|
||||
* See also #562
|
||||
*/
|
||||
if (libevdev_get_abs_resolution(device->evdev, ABS_MT_PRESSURE) != 0 ||
|
||||
evdev_device_has_model_quirk(device, QUIRK_MODEL_PRESSURE_PAD)) {
|
||||
if (libevdev_has_property(device->evdev, INPUT_PROP_PRESSUREPAD) ||
|
||||
libevdev_get_abs_resolution(device->evdev, ABS_MT_PRESSURE) != 0) {
|
||||
libevdev_disable_event_code(device->evdev, EV_ABS, ABS_MT_PRESSURE);
|
||||
libevdev_disable_event_code(device->evdev, EV_ABS, ABS_PRESSURE);
|
||||
}
|
||||
|
|
@ -3607,7 +3709,7 @@ tp_init(struct tp_dispatch *tp, struct evdev_device *device)
|
|||
tp_init_pressure(tp, device);
|
||||
|
||||
/* 5 warnings per 24 hours should be enough */
|
||||
ratelimit_init(&tp->jump.warning, h2us(24), 5);
|
||||
ratelimit_init(&tp->jump.warning, usec_from_hours(24), 5);
|
||||
|
||||
/* Set the dpi to that of the x axis, because that's what we normalize
|
||||
to when needed*/
|
||||
|
|
@ -3742,7 +3844,7 @@ static bool
|
|||
tp_requires_rotation(struct tp_dispatch *tp, struct evdev_device *device)
|
||||
{
|
||||
bool rotate = false;
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
struct libinput *li = tp_libinput_context(tp);
|
||||
WacomDeviceDatabase *db = NULL;
|
||||
WacomDevice **devices = NULL, **d;
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ struct tp_touch {
|
|||
bool has_ended; /* TRACKING_ID == -1 */
|
||||
bool dirty;
|
||||
struct device_coords point;
|
||||
uint64_t initial_time;
|
||||
usec_t initial_time;
|
||||
int pressure;
|
||||
bool is_tool_palm; /* MT_TOOL_PALM */
|
||||
int major, minor;
|
||||
|
|
@ -213,7 +213,7 @@ struct tp_touch {
|
|||
|
||||
struct {
|
||||
struct tp_history_point {
|
||||
uint64_t time;
|
||||
usec_t time;
|
||||
struct device_coords point;
|
||||
} samples[TOUCHPAD_HISTORY_LENGTH];
|
||||
unsigned int index;
|
||||
|
|
@ -246,7 +246,7 @@ struct tp_touch {
|
|||
struct libinput_timer timer;
|
||||
struct device_coords initial;
|
||||
bool has_moved; /* has moved more than threshold */
|
||||
uint64_t initial_time;
|
||||
usec_t initial_time;
|
||||
} button;
|
||||
|
||||
struct {
|
||||
|
|
@ -267,7 +267,7 @@ struct tp_touch {
|
|||
struct {
|
||||
enum touch_palm_state state;
|
||||
struct device_coords first; /* first coordinates if is_palm == true */
|
||||
uint64_t time; /* first timestamp if is_palm == true */
|
||||
usec_t time; /* first timestamp if is_palm == true */
|
||||
} palm;
|
||||
|
||||
struct {
|
||||
|
|
@ -344,7 +344,7 @@ struct tp_dispatch {
|
|||
bool enabled;
|
||||
struct device_coords margin;
|
||||
unsigned int other_event_count;
|
||||
uint64_t last_motion_time;
|
||||
usec_t last_motion_time;
|
||||
} hysteresis;
|
||||
|
||||
struct {
|
||||
|
|
@ -361,7 +361,7 @@ struct tp_dispatch {
|
|||
struct libinput_timer finger_count_switch_timer;
|
||||
enum tp_gesture_state state;
|
||||
struct tp_touch *touches[2];
|
||||
uint64_t initial_time;
|
||||
usec_t initial_time;
|
||||
double initial_distance;
|
||||
double prev_scale;
|
||||
double angle;
|
||||
|
|
@ -370,7 +370,7 @@ struct tp_dispatch {
|
|||
bool hold_enabled;
|
||||
|
||||
struct libinput_timer drag_3fg_timer;
|
||||
uint64_t drag_3fg_release_time;
|
||||
usec_t drag_3fg_release_time;
|
||||
} gesture;
|
||||
|
||||
struct {
|
||||
|
|
@ -421,9 +421,9 @@ struct tp_dispatch {
|
|||
bool h, v;
|
||||
} active;
|
||||
struct phys_coords vector;
|
||||
uint64_t time_prev;
|
||||
usec_t time_prev;
|
||||
struct {
|
||||
uint64_t h, v;
|
||||
usec_t h, v;
|
||||
} duration;
|
||||
} scroll;
|
||||
|
||||
|
|
@ -436,7 +436,7 @@ struct tp_dispatch {
|
|||
struct libinput_timer timer;
|
||||
enum tp_tap_state state;
|
||||
uint32_t buttons_pressed;
|
||||
uint64_t saved_press_time, saved_release_time;
|
||||
usec_t saved_press_time, saved_release_time;
|
||||
|
||||
enum libinput_config_tap_button_map map;
|
||||
enum libinput_config_tap_button_map want_map;
|
||||
|
|
@ -457,6 +457,7 @@ struct tp_dispatch {
|
|||
struct {
|
||||
struct libinput_device_config_dwtp config;
|
||||
bool dwtp_enabled;
|
||||
usec_t timeout;
|
||||
|
||||
int32_t right_edge; /* in device coordinates */
|
||||
int32_t left_edge; /* in device coordinates */
|
||||
|
|
@ -465,7 +466,7 @@ struct tp_dispatch {
|
|||
bool trackpoint_active;
|
||||
struct libinput_event_listener trackpoint_listener;
|
||||
struct libinput_timer trackpoint_timer;
|
||||
uint64_t trackpoint_last_event_time;
|
||||
usec_t trackpoint_last_event_time;
|
||||
uint32_t trackpoint_event_count;
|
||||
bool monitor_trackpoint;
|
||||
|
||||
|
|
@ -486,6 +487,7 @@ struct tp_dispatch {
|
|||
struct {
|
||||
struct libinput_device_config_dwt config;
|
||||
bool dwt_enabled;
|
||||
usec_t timeout;
|
||||
|
||||
/* We have to allow for more than one device node to be the
|
||||
* internal dwt keyboard (Razer Blade). But they're the same
|
||||
|
|
@ -498,7 +500,7 @@ struct tp_dispatch {
|
|||
unsigned long mod_mask[NLONGS(KEY_CNT)];
|
||||
bool keyboard_active;
|
||||
struct libinput_timer keyboard_timer;
|
||||
uint64_t keyboard_last_press_time;
|
||||
usec_t keyboard_last_press_time;
|
||||
} dwt;
|
||||
|
||||
struct {
|
||||
|
|
@ -529,8 +531,8 @@ struct tp_dispatch {
|
|||
|
||||
struct msc_timestamp {
|
||||
enum tp_jump_state state;
|
||||
uint32_t interval;
|
||||
uint32_t now;
|
||||
usec_t interval;
|
||||
usec_t now;
|
||||
} msc_timestamp;
|
||||
} quirks;
|
||||
|
||||
|
|
@ -614,17 +616,17 @@ tp_get_delta(struct tp_touch *t);
|
|||
struct normalized_coords
|
||||
tp_filter_motion(struct tp_dispatch *tp,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
|
||||
struct normalized_coords
|
||||
tp_filter_motion_unaccelerated(struct tp_dispatch *tp,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
|
||||
struct normalized_coords
|
||||
tp_filter_scroll(struct tp_dispatch *tp,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
|
||||
bool
|
||||
tp_touch_active(const struct tp_dispatch *tp, const struct tp_touch *t);
|
||||
|
|
@ -633,7 +635,7 @@ bool
|
|||
tp_touch_active_for_gesture(const struct tp_dispatch *tp, const struct tp_touch *t);
|
||||
|
||||
int
|
||||
tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time);
|
||||
tp_tap_handle_state(struct tp_dispatch *tp, usec_t time);
|
||||
|
||||
void
|
||||
tp_tap_post_process_state(struct tp_dispatch *tp);
|
||||
|
|
@ -659,16 +661,16 @@ void
|
|||
tp_remove_buttons(struct tp_dispatch *tp);
|
||||
|
||||
void
|
||||
tp_process_button(struct tp_dispatch *tp, const struct evdev_event *e, uint64_t time);
|
||||
tp_process_button(struct tp_dispatch *tp, const struct evdev_event *e, usec_t time);
|
||||
|
||||
void
|
||||
tp_release_all_buttons(struct tp_dispatch *tp, uint64_t time);
|
||||
tp_release_all_buttons(struct tp_dispatch *tp, usec_t time);
|
||||
|
||||
int
|
||||
tp_post_button_events(struct tp_dispatch *tp, uint64_t time);
|
||||
tp_post_button_events(struct tp_dispatch *tp, usec_t time);
|
||||
|
||||
void
|
||||
tp_button_handle_state(struct tp_dispatch *tp, uint64_t time);
|
||||
tp_button_handle_state(struct tp_dispatch *tp, usec_t time);
|
||||
|
||||
bool
|
||||
tp_button_touch_active(const struct tp_dispatch *tp, const struct tp_touch *t);
|
||||
|
|
@ -678,13 +680,13 @@ tp_button_is_inside_softbutton_area(const struct tp_dispatch *tp,
|
|||
const struct tp_touch *t);
|
||||
|
||||
void
|
||||
tp_release_all_taps(struct tp_dispatch *tp, uint64_t now);
|
||||
tp_release_all_taps(struct tp_dispatch *tp, usec_t now);
|
||||
|
||||
void
|
||||
tp_tap_suspend(struct tp_dispatch *tp, uint64_t time);
|
||||
tp_tap_suspend(struct tp_dispatch *tp, usec_t time);
|
||||
|
||||
void
|
||||
tp_tap_resume(struct tp_dispatch *tp, uint64_t time);
|
||||
tp_tap_resume(struct tp_dispatch *tp, usec_t time);
|
||||
|
||||
bool
|
||||
tp_tap_dragging(const struct tp_dispatch *tp);
|
||||
|
|
@ -699,13 +701,13 @@ void
|
|||
tp_remove_edge_scroll(struct tp_dispatch *tp);
|
||||
|
||||
void
|
||||
tp_edge_scroll_handle_state(struct tp_dispatch *tp, uint64_t time);
|
||||
tp_edge_scroll_handle_state(struct tp_dispatch *tp, usec_t time);
|
||||
|
||||
int
|
||||
tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time);
|
||||
tp_edge_scroll_post_events(struct tp_dispatch *tp, usec_t time);
|
||||
|
||||
void
|
||||
tp_edge_scroll_stop_events(struct tp_dispatch *tp, uint64_t time);
|
||||
tp_edge_scroll_stop_events(struct tp_dispatch *tp, usec_t time);
|
||||
|
||||
int
|
||||
tp_edge_scroll_touch_active(const struct tp_dispatch *tp, const struct tp_touch *t);
|
||||
|
|
@ -720,25 +722,25 @@ void
|
|||
tp_remove_gesture(struct tp_dispatch *tp);
|
||||
|
||||
void
|
||||
tp_gesture_stop(struct tp_dispatch *tp, uint64_t time);
|
||||
tp_gesture_stop(struct tp_dispatch *tp, usec_t time);
|
||||
|
||||
void
|
||||
tp_gesture_cancel(struct tp_dispatch *tp, uint64_t time);
|
||||
tp_gesture_cancel(struct tp_dispatch *tp, usec_t time);
|
||||
|
||||
void
|
||||
tp_gesture_cancel_motion_gestures(struct tp_dispatch *tp, uint64_t time);
|
||||
tp_gesture_cancel_motion_gestures(struct tp_dispatch *tp, usec_t time);
|
||||
|
||||
void
|
||||
tp_gesture_update_finger_state(struct tp_dispatch *tp, uint64_t time);
|
||||
tp_gesture_update_finger_state(struct tp_dispatch *tp, usec_t time);
|
||||
|
||||
void
|
||||
tp_gesture_post_events(struct tp_dispatch *tp, uint64_t time, bool ignore_motion);
|
||||
tp_gesture_post_events(struct tp_dispatch *tp, usec_t time, bool ignore_motion);
|
||||
|
||||
void
|
||||
tp_gesture_stop_twofinger_scroll(struct tp_dispatch *tp, uint64_t time);
|
||||
tp_gesture_stop_twofinger_scroll(struct tp_dispatch *tp, usec_t time);
|
||||
|
||||
void
|
||||
tp_gesture_tap_timeout(struct tp_dispatch *tp, uint64_t time);
|
||||
tp_gesture_tap_timeout(struct tp_dispatch *tp, usec_t time);
|
||||
|
||||
void
|
||||
tp_clickpad_middlebutton_apply_config(struct evdev_device *device);
|
||||
|
|
@ -759,7 +761,7 @@ void
|
|||
tp_thumb_suppress(struct tp_dispatch *tp, struct tp_touch *t);
|
||||
|
||||
void
|
||||
tp_thumb_update_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time);
|
||||
tp_thumb_update_touch(struct tp_dispatch *tp, struct tp_touch *t, usec_t time);
|
||||
|
||||
void
|
||||
tp_detect_thumb_while_moving(struct tp_dispatch *tp);
|
||||
|
|
|
|||
|
|
@ -29,72 +29,11 @@
|
|||
#include "evdev-plugin.h"
|
||||
#include "evdev.h"
|
||||
|
||||
_unused_ static inline void
|
||||
evdev_print_frame(struct evdev_device *device,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time_in_us)
|
||||
{
|
||||
static uint32_t offset = 0;
|
||||
static uint32_t last_time = 0;
|
||||
uint32_t time = us2ms(time_in_us);
|
||||
|
||||
if (offset == 0) {
|
||||
offset = time;
|
||||
last_time = time - offset;
|
||||
}
|
||||
|
||||
time -= offset;
|
||||
|
||||
size_t nevents;
|
||||
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
|
||||
|
||||
for (size_t i = 0; i < nevents; i++) {
|
||||
struct evdev_event *e = &events[i];
|
||||
|
||||
switch (evdev_usage_enum(e->usage)) {
|
||||
case EVDEV_SYN_REPORT:
|
||||
evdev_log_debug(
|
||||
device,
|
||||
"%u.%03u ----------------- EV_SYN ----------------- +%ums\n",
|
||||
time / 1000,
|
||||
time % 1000,
|
||||
time - last_time);
|
||||
|
||||
last_time = time;
|
||||
break;
|
||||
case EVDEV_MSC_SERIAL:
|
||||
evdev_log_debug(device,
|
||||
"%u.%03u %-16s %-16s %#010x\n",
|
||||
time / 1000,
|
||||
time % 1000,
|
||||
evdev_event_get_type_name(e),
|
||||
evdev_event_get_code_name(e),
|
||||
e->value);
|
||||
break;
|
||||
default:
|
||||
evdev_log_debug(device,
|
||||
"%u.%03u %-16s %-20s %4d\n",
|
||||
time / 1000,
|
||||
time % 1000,
|
||||
evdev_event_get_type_name(e),
|
||||
evdev_event_get_code_name(e),
|
||||
e->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
evdev_process_frame(struct evdev_device *device,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
evdev_process_frame(struct evdev_device *device, struct evdev_frame *frame, usec_t time)
|
||||
{
|
||||
struct evdev_dispatch *dispatch = device->dispatch;
|
||||
|
||||
#if EVENT_DEBUGGING
|
||||
evdev_print_frame(device, frame, time);
|
||||
#endif
|
||||
|
||||
libinput_timer_flush(evdev_libinput_context(device), time);
|
||||
|
||||
dispatch->interface->process(dispatch, device, frame, time);
|
||||
|
|
@ -106,7 +45,7 @@ evdev_device_dispatch_frame(struct libinput_plugin *plugin,
|
|||
struct evdev_frame *frame)
|
||||
{
|
||||
struct evdev_device *device = evdev_device(libinput_device);
|
||||
uint64_t time = evdev_frame_get_time(frame);
|
||||
usec_t time = evdev_frame_get_time(frame);
|
||||
evdev_process_frame(device, frame, time);
|
||||
|
||||
/* Discard event to make the plugin system aware we're done */
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "evdev-tablet-pad.h"
|
||||
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
#include <libwacom/libwacom.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -114,7 +114,7 @@ pad_led_destroy(struct libinput *libinput, struct pad_mode_led *led)
|
|||
free(led);
|
||||
}
|
||||
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
static inline struct pad_mode_led *
|
||||
pad_led_new(struct libinput *libinput, const char *prefix, int group, int mode)
|
||||
{
|
||||
|
|
@ -198,7 +198,7 @@ pad_get_mode_group(struct pad_dispatch *pad, unsigned int index)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
static inline bool
|
||||
is_litest_device(struct evdev_device *device)
|
||||
{
|
||||
|
|
@ -618,7 +618,7 @@ pad_init_leds(struct pad_dispatch *pad, struct evdev_device *device, WacomDevice
|
|||
}
|
||||
|
||||
/* If libwacom fails, we init one fallback group anyway */
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
rc = pad_init_leds_from_libwacom(pad, device, wacom);
|
||||
#endif
|
||||
if (rc != 0)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include "evdev-tablet-pad.h"
|
||||
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
#include <libwacom/libwacom.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ static void
|
|||
pad_process_relative(struct pad_dispatch *pad,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (evdev_usage_enum(e->usage)) {
|
||||
case EVDEV_REL_DIAL:
|
||||
|
|
@ -172,7 +172,7 @@ static void
|
|||
pad_process_absolute(struct pad_dispatch *pad,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
enum pad_axes axis = PAD_AXIS_NONE;
|
||||
|
||||
|
|
@ -303,11 +303,15 @@ pad_dial_get_mode_group(struct pad_dispatch *pad, unsigned int dial)
|
|||
struct libinput_tablet_pad_mode_group *group;
|
||||
|
||||
list_for_each(group, &pad->modes.mode_group_list, link) {
|
||||
assert(group != NULL); /* for clang-tidy */
|
||||
if (libinput_tablet_pad_mode_group_has_dial(group, dial))
|
||||
return group;
|
||||
}
|
||||
|
||||
assert(!"Unable to find dial mode group");
|
||||
evdev_log_bug_libinput_ratelimit(pad->device,
|
||||
&pad->modes.group_not_found,
|
||||
"Unable to find mode group for dial %d\n",
|
||||
dial);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -318,11 +322,15 @@ pad_ring_get_mode_group(struct pad_dispatch *pad, unsigned int ring)
|
|||
struct libinput_tablet_pad_mode_group *group;
|
||||
|
||||
list_for_each(group, &pad->modes.mode_group_list, link) {
|
||||
assert(group != NULL); /* for clang-tidy */
|
||||
if (libinput_tablet_pad_mode_group_has_ring(group, ring))
|
||||
return group;
|
||||
}
|
||||
|
||||
assert(!"Unable to find ring mode group");
|
||||
evdev_log_bug_libinput_ratelimit(pad->device,
|
||||
&pad->modes.group_not_found,
|
||||
"Unable to find mode group for ring %d\n",
|
||||
ring);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -333,11 +341,15 @@ pad_strip_get_mode_group(struct pad_dispatch *pad, unsigned int strip)
|
|||
struct libinput_tablet_pad_mode_group *group;
|
||||
|
||||
list_for_each(group, &pad->modes.mode_group_list, link) {
|
||||
assert(group != NULL); /* for clang-tidy */
|
||||
if (libinput_tablet_pad_mode_group_has_strip(group, strip))
|
||||
return group;
|
||||
}
|
||||
|
||||
assert(!"Unable to find strip mode group");
|
||||
evdev_log_bug_libinput_ratelimit(pad->device,
|
||||
&pad->modes.group_not_found,
|
||||
"Unable to find mode group for strip %d\n",
|
||||
strip);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -345,7 +357,7 @@ pad_strip_get_mode_group(struct pad_dispatch *pad, unsigned int strip)
|
|||
static void
|
||||
pad_check_notify_axes(struct pad_dispatch *pad,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct libinput_tablet_pad_mode_group *group;
|
||||
|
|
@ -362,12 +374,14 @@ pad_check_notify_axes(struct pad_dispatch *pad,
|
|||
* so we can't set a source */
|
||||
if (pad->changed_axes & PAD_AXIS_DIAL1) {
|
||||
group = pad_dial_get_mode_group(pad, 0);
|
||||
tablet_pad_notify_dial(base, time, 0, pad->dials.dial1, group);
|
||||
if (group)
|
||||
tablet_pad_notify_dial(base, time, 0, pad->dials.dial1, group);
|
||||
}
|
||||
|
||||
if (pad->changed_axes & PAD_AXIS_DIAL2) {
|
||||
group = pad_dial_get_mode_group(pad, 1);
|
||||
tablet_pad_notify_dial(base, time, 1, pad->dials.dial2, group);
|
||||
if (group)
|
||||
tablet_pad_notify_dial(base, time, 1, pad->dials.dial2, group);
|
||||
}
|
||||
|
||||
if (pad->changed_axes & PAD_AXIS_RING1) {
|
||||
|
|
@ -376,12 +390,13 @@ pad_check_notify_axes(struct pad_dispatch *pad,
|
|||
value = -1.0;
|
||||
|
||||
group = pad_ring_get_mode_group(pad, 0);
|
||||
tablet_pad_notify_ring(base,
|
||||
time,
|
||||
0,
|
||||
value,
|
||||
LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER,
|
||||
group);
|
||||
if (group)
|
||||
tablet_pad_notify_ring(base,
|
||||
time,
|
||||
0,
|
||||
value,
|
||||
LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER,
|
||||
group);
|
||||
}
|
||||
|
||||
if (pad->changed_axes & PAD_AXIS_RING2) {
|
||||
|
|
@ -390,12 +405,13 @@ pad_check_notify_axes(struct pad_dispatch *pad,
|
|||
value = -1.0;
|
||||
|
||||
group = pad_ring_get_mode_group(pad, 1);
|
||||
tablet_pad_notify_ring(base,
|
||||
time,
|
||||
1,
|
||||
value,
|
||||
LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER,
|
||||
group);
|
||||
if (group)
|
||||
tablet_pad_notify_ring(base,
|
||||
time,
|
||||
1,
|
||||
value,
|
||||
LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER,
|
||||
group);
|
||||
}
|
||||
|
||||
if (pad->changed_axes & PAD_AXIS_STRIP1) {
|
||||
|
|
@ -404,12 +420,13 @@ pad_check_notify_axes(struct pad_dispatch *pad,
|
|||
value = -1.0;
|
||||
|
||||
group = pad_strip_get_mode_group(pad, 0);
|
||||
tablet_pad_notify_strip(base,
|
||||
time,
|
||||
0,
|
||||
value,
|
||||
LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER,
|
||||
group);
|
||||
if (group)
|
||||
tablet_pad_notify_strip(base,
|
||||
time,
|
||||
0,
|
||||
value,
|
||||
LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER,
|
||||
group);
|
||||
}
|
||||
|
||||
if (pad->changed_axes & PAD_AXIS_STRIP2) {
|
||||
|
|
@ -418,12 +435,13 @@ pad_check_notify_axes(struct pad_dispatch *pad,
|
|||
value = -1.0;
|
||||
|
||||
group = pad_strip_get_mode_group(pad, 1);
|
||||
tablet_pad_notify_strip(base,
|
||||
time,
|
||||
1,
|
||||
value,
|
||||
LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER,
|
||||
group);
|
||||
if (group)
|
||||
tablet_pad_notify_strip(base,
|
||||
time,
|
||||
1,
|
||||
value,
|
||||
LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER,
|
||||
group);
|
||||
}
|
||||
|
||||
pad->changed_axes = PAD_AXIS_NONE;
|
||||
|
|
@ -434,7 +452,7 @@ static void
|
|||
pad_process_key(struct pad_dispatch *pad,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
uint32_t is_press = e->value != 0;
|
||||
|
||||
|
|
@ -463,7 +481,7 @@ pad_button_get_mode_group(struct pad_dispatch *pad, unsigned int button)
|
|||
static void
|
||||
pad_notify_button_mask(struct pad_dispatch *pad,
|
||||
struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
const struct button_state *buttons,
|
||||
enum libinput_button_state state)
|
||||
{
|
||||
|
|
@ -519,7 +537,7 @@ pad_notify_button_mask(struct pad_dispatch *pad,
|
|||
static void
|
||||
pad_notify_buttons(struct pad_dispatch *pad,
|
||||
struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum libinput_button_state state)
|
||||
{
|
||||
struct button_state buttons;
|
||||
|
|
@ -547,7 +565,7 @@ pad_change_to_left_handed(struct evdev_device *device)
|
|||
}
|
||||
|
||||
static void
|
||||
pad_flush(struct pad_dispatch *pad, struct evdev_device *device, uint64_t time)
|
||||
pad_flush(struct pad_dispatch *pad, struct evdev_device *device, usec_t time)
|
||||
{
|
||||
if (pad_has_status(pad, PAD_AXES_UPDATED)) {
|
||||
pad_check_notify_axes(pad, device, time);
|
||||
|
|
@ -576,7 +594,7 @@ static void
|
|||
pad_process_event(struct evdev_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct pad_dispatch *pad = pad_dispatch(dispatch);
|
||||
|
||||
|
|
@ -611,7 +629,7 @@ static void
|
|||
pad_process(struct evdev_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
size_t nevents;
|
||||
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
|
||||
|
|
@ -667,7 +685,7 @@ pad_init_buttons_from_libwacom(struct pad_dispatch *pad,
|
|||
WacomDevice *tablet)
|
||||
{
|
||||
bool rc = false;
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
|
||||
if (tablet) {
|
||||
int num_buttons = libwacom_get_num_buttons(tablet);
|
||||
|
|
@ -759,7 +777,7 @@ pad_init_left_handed(struct evdev_device *device, WacomDevice *wacom)
|
|||
{
|
||||
bool has_left_handed = true;
|
||||
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
has_left_handed = !wacom || libwacom_is_reversible(wacom);
|
||||
#endif
|
||||
if (has_left_handed)
|
||||
|
|
@ -772,7 +790,7 @@ pad_init(struct pad_dispatch *pad, struct evdev_device *device)
|
|||
int rc = 1;
|
||||
struct libinput *li = evdev_libinput_context(device);
|
||||
WacomDevice *wacom = NULL;
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
WacomDeviceDatabase *db = libinput_libwacom_ref(li);
|
||||
if (db) {
|
||||
char event_path[64];
|
||||
|
|
@ -804,6 +822,7 @@ pad_init(struct pad_dispatch *pad, struct evdev_device *device)
|
|||
pad->device = device;
|
||||
pad->status = PAD_NONE;
|
||||
pad->changed_axes = PAD_AXIS_NONE;
|
||||
ratelimit_init(&pad->modes.group_not_found, usec_from_hours(1), 3);
|
||||
|
||||
/* We expect the kernel to either give us both axes as hires or neither.
|
||||
* Getting one is a kernel bug we don't need to care about */
|
||||
|
|
@ -823,9 +842,9 @@ pad_init(struct pad_dispatch *pad, struct evdev_device *device)
|
|||
rc = pad_init_leds(pad, device, wacom);
|
||||
|
||||
/* at most 5 "Multiple EV_ABS events" log messages per hour */
|
||||
ratelimit_init(&pad->duplicate_abs_limit, s2us(60 * 60), 5);
|
||||
ratelimit_init(&pad->duplicate_abs_limit, usec_from_seconds(60 * 60), 5);
|
||||
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
if (wacom)
|
||||
libwacom_destroy(wacom);
|
||||
if (db)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include "evdev.h"
|
||||
|
||||
#if !HAVE_LIBWACOM
|
||||
#ifndef HAVE_LIBWACOM
|
||||
typedef void *WacomDevice;
|
||||
#endif
|
||||
|
||||
|
|
@ -87,6 +87,7 @@ struct pad_dispatch {
|
|||
|
||||
struct {
|
||||
struct list mode_group_list;
|
||||
struct ratelimit group_not_found;
|
||||
} modes;
|
||||
|
||||
struct ratelimit duplicate_abs_limit;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include "evdev-tablet.h"
|
||||
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
#include <libwacom/libwacom.h>
|
||||
#else
|
||||
typedef void *WacomStylus;
|
||||
|
|
@ -197,7 +197,7 @@ static void
|
|||
tablet_process_absolute(struct tablet_dispatch *tablet,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
enum libinput_tablet_tool_axis axis;
|
||||
|
||||
|
|
@ -557,7 +557,7 @@ tablet_tool_process_delta(struct tablet_dispatch *tablet,
|
|||
struct libinput_tablet_tool *tool,
|
||||
const struct evdev_device *device,
|
||||
struct tablet_axes *axes,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
const struct normalized_coords zero = { 0.0, 0.0 };
|
||||
struct device_coords delta = { 0, 0 };
|
||||
|
|
@ -759,7 +759,7 @@ tablet_check_notify_axes(struct tablet_dispatch *tablet,
|
|||
struct evdev_device *device,
|
||||
struct libinput_tablet_tool *tool,
|
||||
struct tablet_axes *axes_out,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct tablet_axes axes = { 0 };
|
||||
const char tmp[sizeof(tablet->changed_axes)] = { 0 };
|
||||
|
|
@ -884,7 +884,7 @@ static void
|
|||
tablet_process_key(struct tablet_dispatch *tablet,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
enum libinput_tablet_tool_type type;
|
||||
|
||||
|
|
@ -930,7 +930,7 @@ static void
|
|||
tablet_process_relative(struct tablet_dispatch *tablet,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
enum libinput_tablet_tool_axis axis;
|
||||
|
||||
|
|
@ -960,7 +960,7 @@ static void
|
|||
tablet_process_misc(struct tablet_dispatch *tablet,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (evdev_usage_enum(e->usage)) {
|
||||
case EVDEV_MSC_SERIAL:
|
||||
|
|
@ -1004,7 +1004,7 @@ tool_set_bits_from_libwacom(const struct tablet_dispatch *tablet,
|
|||
const WacomStylus *s)
|
||||
{
|
||||
bool rc = false;
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
int code;
|
||||
WacomStylusType type;
|
||||
WacomAxisTypeFlags axes;
|
||||
|
|
@ -1221,7 +1221,7 @@ pressure_range_set(struct libinput_tablet_tool *tool, double min, double max)
|
|||
|
||||
tool->pressure.wanted_range.min = min;
|
||||
tool->pressure.wanted_range.max = max;
|
||||
tool->pressure.has_configured_range = true;
|
||||
tool->pressure.has_configured_range = min != 0.0 || max != 1.0;
|
||||
|
||||
return LIBINPUT_CONFIG_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -1272,10 +1272,13 @@ static void
|
|||
eraser_button_toggle(struct libinput_tablet_tool *tool)
|
||||
{
|
||||
struct libinput_device *libinput_device = tool->last_device;
|
||||
struct evdev_device *device = evdev_device(libinput_device);
|
||||
struct tablet_dispatch *tablet = tablet_dispatch(device->dispatch);
|
||||
|
||||
tablet_tool_apply_eraser_button(tablet, tool);
|
||||
if (libinput_device) {
|
||||
struct evdev_device *device = evdev_device(libinput_device);
|
||||
struct tablet_dispatch *tablet = tablet_dispatch(device->dispatch);
|
||||
|
||||
tablet_tool_apply_eraser_button(tablet, tool);
|
||||
}
|
||||
}
|
||||
|
||||
static enum libinput_config_status
|
||||
|
|
@ -1296,7 +1299,7 @@ eraser_button_set_mode(struct libinput_tablet_tool *tool,
|
|||
static enum libinput_config_eraser_button_mode
|
||||
eraser_button_get_mode(struct libinput_tablet_tool *tool)
|
||||
{
|
||||
return tool->eraser_button.mode;
|
||||
return tool->eraser_button.want_mode;
|
||||
}
|
||||
|
||||
static enum libinput_config_eraser_button_mode
|
||||
|
|
@ -1330,7 +1333,7 @@ eraser_button_set_button(struct libinput_tablet_tool *tool, uint32_t button)
|
|||
static unsigned int
|
||||
eraser_button_get_button(struct libinput_tablet_tool *tool)
|
||||
{
|
||||
return tool->eraser_button.button;
|
||||
return tool->eraser_button.want_button;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
|
|
@ -1369,7 +1372,7 @@ tool_init_eraser_button(struct tablet_dispatch *tablet,
|
|||
if (libinput_tablet_tool_get_type(tool) != LIBINPUT_TABLET_TOOL_TYPE_PEN)
|
||||
return;
|
||||
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
/* libwacom's API is a bit terrible here:
|
||||
* - has_eraser is true on styli that have a separate eraser, all
|
||||
* those are INVERT so we can exclude them
|
||||
|
|
@ -1400,7 +1403,7 @@ tablet_new_tool(struct tablet_dispatch *tablet,
|
|||
{
|
||||
struct libinput_tablet_tool *tool = zalloc(sizeof *tool);
|
||||
const WacomStylus *s = NULL;
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
WacomDeviceDatabase *db;
|
||||
|
||||
db = tablet_libinput_context(tablet)->libwacom.db;
|
||||
|
|
@ -1519,7 +1522,7 @@ tablet_get_tool(struct tablet_dispatch *tablet,
|
|||
static void
|
||||
tablet_notify_button_mask(struct tablet_dispatch *tablet,
|
||||
struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
struct libinput_tablet_tool *tool,
|
||||
const struct button_state *buttons,
|
||||
enum libinput_button_state state)
|
||||
|
|
@ -1553,7 +1556,7 @@ tablet_notify_button_mask(struct tablet_dispatch *tablet,
|
|||
static void
|
||||
tablet_notify_buttons(struct tablet_dispatch *tablet,
|
||||
struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
struct libinput_tablet_tool *tool,
|
||||
enum libinput_button_state state)
|
||||
{
|
||||
|
|
@ -1762,8 +1765,9 @@ detect_pressure_offset(struct tablet_dispatch *tablet,
|
|||
}
|
||||
|
||||
evdev_log_info(device,
|
||||
"Pressure offset detected on tool %s (serial %#x). "
|
||||
"Pressure offset of %d%% detected on tool %s (serial %#x). "
|
||||
"See %s/tablet-support.html\n",
|
||||
(int)(pressure_offset_as_double(offset) * 100),
|
||||
tablet_tool_type_to_string(tool->type),
|
||||
tool->serial,
|
||||
HTTP_DOC_LINK);
|
||||
|
|
@ -1913,7 +1917,7 @@ tablet_calculate_arbitration_rect(struct tablet_dispatch *tablet)
|
|||
static inline void
|
||||
tablet_update_touch_device_rect(struct tablet_dispatch *tablet,
|
||||
const struct tablet_axes *axes,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct evdev_dispatch *dispatch;
|
||||
struct phys_rect rect = { 0 };
|
||||
|
|
@ -1937,7 +1941,7 @@ tablet_send_proximity_in(struct tablet_dispatch *tablet,
|
|||
struct libinput_tablet_tool *tool,
|
||||
struct evdev_device *device,
|
||||
struct tablet_axes *axes,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
if (!tablet_has_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY))
|
||||
return false;
|
||||
|
|
@ -1965,7 +1969,7 @@ tablet_send_proximity_out(struct tablet_dispatch *tablet,
|
|||
struct libinput_tablet_tool *tool,
|
||||
struct evdev_device *device,
|
||||
struct tablet_axes *axes,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY) &&
|
||||
!tablet_has_status(tablet, TABLET_TOOL_OUTSIDE_AREA)) {
|
||||
|
|
@ -1985,7 +1989,7 @@ tablet_send_tip(struct tablet_dispatch *tablet,
|
|||
struct libinput_tablet_tool *tool,
|
||||
struct evdev_device *device,
|
||||
struct tablet_axes *axes,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
if (tablet_has_status(tablet, TABLET_TOOL_ENTERING_CONTACT)) {
|
||||
tablet_notify_tip(&device->base,
|
||||
|
|
@ -2035,7 +2039,7 @@ tablet_send_axes(struct tablet_dispatch *tablet,
|
|||
struct libinput_tablet_tool *tool,
|
||||
struct evdev_device *device,
|
||||
struct tablet_axes *axes,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
enum libinput_tablet_tool_tip_state tip_state;
|
||||
|
||||
|
|
@ -2065,7 +2069,7 @@ static inline void
|
|||
tablet_send_buttons(struct tablet_dispatch *tablet,
|
||||
struct libinput_tablet_tool *tool,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
if (tablet_has_status(tablet, TABLET_BUTTONS_RELEASED)) {
|
||||
tablet_notify_buttons(tablet,
|
||||
|
|
@ -2090,7 +2094,7 @@ static void
|
|||
tablet_send_events(struct tablet_dispatch *tablet,
|
||||
struct libinput_tablet_tool *tool,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct tablet_axes axes = { 0 };
|
||||
|
||||
|
|
@ -2127,7 +2131,7 @@ tablet_send_events(struct tablet_dispatch *tablet,
|
|||
static void
|
||||
tablet_update_tool_state(struct tablet_dispatch *tablet,
|
||||
struct evdev_device *device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
enum libinput_tablet_tool_type type;
|
||||
uint32_t changed;
|
||||
|
|
@ -2191,18 +2195,18 @@ update_pressure_range(struct tablet_dispatch *tablet,
|
|||
threshold->threshold.upper = hi;
|
||||
threshold->threshold.lower = lo;
|
||||
|
||||
if (threshold->has_offset)
|
||||
set_pressure_offset(threshold, threshold->offset);
|
||||
|
||||
/* Disable any heuristics */
|
||||
if (tool->pressure.has_configured_range) {
|
||||
threshold->has_offset = true;
|
||||
threshold->heuristic_state = PRESSURE_HEURISTIC_STATE_DONE;
|
||||
threshold->offset = pressure_offset_from_double(0.0);
|
||||
} else if (threshold->has_offset) {
|
||||
set_pressure_offset(threshold, threshold->offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_flush(struct tablet_dispatch *tablet, struct evdev_device *device, uint64_t time)
|
||||
tablet_flush(struct tablet_dispatch *tablet, struct evdev_device *device, usec_t time)
|
||||
{
|
||||
struct libinput_tablet_tool *tool;
|
||||
|
||||
|
|
@ -2286,7 +2290,7 @@ static inline void
|
|||
tablet_set_touch_device_enabled(struct tablet_dispatch *tablet,
|
||||
enum evdev_arbitration_state which,
|
||||
const struct phys_rect *rect,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct evdev_device *touch_device = tablet->touch_device;
|
||||
struct evdev_dispatch *dispatch;
|
||||
|
|
@ -2308,7 +2312,7 @@ tablet_set_touch_device_enabled(struct tablet_dispatch *tablet,
|
|||
static inline void
|
||||
tablet_toggle_touch_device(struct tablet_dispatch *tablet,
|
||||
struct evdev_device *tablet_device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
enum evdev_arbitration_state which;
|
||||
struct phys_rect r = { 0 };
|
||||
|
|
@ -2355,7 +2359,7 @@ static void
|
|||
tablet_process_event(struct evdev_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct tablet_dispatch *tablet = tablet_dispatch(dispatch);
|
||||
|
||||
|
|
@ -2391,7 +2395,7 @@ static void
|
|||
tablet_process(struct evdev_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
size_t nevents;
|
||||
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
|
||||
|
|
@ -2406,7 +2410,7 @@ tablet_suspend(struct evdev_dispatch *dispatch, struct evdev_device *device)
|
|||
{
|
||||
struct tablet_dispatch *tablet = tablet_dispatch(dispatch);
|
||||
struct libinput *li = tablet_libinput_context(tablet);
|
||||
uint64_t now = libinput_now(li);
|
||||
usec_t now = libinput_now(li);
|
||||
|
||||
tablet_set_touch_device_enabled(tablet, ARBITRATION_NOT_ACTIVE, NULL, now);
|
||||
|
||||
|
|
@ -2447,6 +2451,8 @@ tablet_destroy(struct evdev_dispatch *dispatch)
|
|||
struct libinput *li = tablet_libinput_context(tablet);
|
||||
|
||||
list_for_each_safe(tool, &tablet->tool_list, link) {
|
||||
list_remove(&tool->link);
|
||||
list_init(&tool->link); /* unref may list_remove() too */
|
||||
libinput_tablet_tool_unref(tool);
|
||||
}
|
||||
|
||||
|
|
@ -2788,7 +2794,7 @@ tablet_init_left_handed(struct evdev_device *device, WacomDevice *wacom)
|
|||
{
|
||||
bool has_left_handed = true;
|
||||
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
has_left_handed = !wacom || libwacom_is_reversible(wacom);
|
||||
#endif
|
||||
if (has_left_handed)
|
||||
|
|
@ -2798,7 +2804,7 @@ tablet_init_left_handed(struct evdev_device *device, WacomDevice *wacom)
|
|||
static inline bool
|
||||
tablet_is_display_tablet(WacomDevice *wacom)
|
||||
{
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
return !wacom ||
|
||||
(libwacom_get_integration_flags(wacom) &
|
||||
(WACOM_DEVICE_INTEGRATED_SYSTEM | WACOM_DEVICE_INTEGRATED_DISPLAY));
|
||||
|
|
@ -2810,7 +2816,7 @@ tablet_is_display_tablet(WacomDevice *wacom)
|
|||
static inline bool
|
||||
tablet_is_aes(struct evdev_device *device, WacomDevice *wacom)
|
||||
{
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
int vid = evdev_device_get_id_vendor(device);
|
||||
/* Wacom-specific check for whether smoothing is required:
|
||||
* libwacom keeps all the AES pens in a single group, so any device
|
||||
|
|
@ -2943,7 +2949,7 @@ tablet_init(struct tablet_dispatch *tablet, struct evdev_device *device)
|
|||
enum libinput_tablet_tool_axis axis;
|
||||
int rc = -1;
|
||||
WacomDevice *wacom = NULL;
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
WacomDeviceDatabase *db = libinput_libwacom_ref(li);
|
||||
if (db) {
|
||||
char event_path[64];
|
||||
|
|
@ -3018,7 +3024,7 @@ tablet_init(struct tablet_dispatch *tablet, struct evdev_device *device)
|
|||
|
||||
rc = 0;
|
||||
out:
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
if (wacom)
|
||||
libwacom_destroy(wacom);
|
||||
if (db)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "evdev.h"
|
||||
|
||||
#if !HAVE_LIBWACOM
|
||||
#ifndef HAVE_LIBWACOM
|
||||
typedef void *WacomDevice;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ totem_new_tool(struct totem_dispatch *totem)
|
|||
static inline void
|
||||
totem_set_touch_device_enabled(struct totem_dispatch *totem,
|
||||
bool enable_touch_device,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct evdev_device *touch_device = totem->touch_device;
|
||||
struct evdev_dispatch *dispatch;
|
||||
|
|
@ -183,7 +183,7 @@ static void
|
|||
totem_process_key(struct totem_dispatch *totem,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
/* ignore kernel key repeat */
|
||||
if (e->value == 2)
|
||||
|
|
@ -205,7 +205,7 @@ static void
|
|||
totem_process_abs(struct totem_dispatch *totem,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct totem_slot *slot = &totem->slots[totem->slot];
|
||||
|
||||
|
|
@ -263,7 +263,7 @@ totem_slot_fetch_axes(struct totem_dispatch *totem,
|
|||
struct totem_slot *slot,
|
||||
struct libinput_tablet_tool *tool,
|
||||
struct tablet_axes *axes_out,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct evdev_device *device = totem->device;
|
||||
const char tmp[sizeof(slot->changed_axes)] = { 0 };
|
||||
|
|
@ -358,7 +358,7 @@ slot_axes_initialize(struct totem_dispatch *totem, struct totem_slot *slot)
|
|||
static enum totem_slot_state
|
||||
totem_handle_slot_state(struct totem_dispatch *totem,
|
||||
struct totem_slot *slot,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct evdev_device *device = totem->device;
|
||||
struct tablet_axes axes;
|
||||
|
|
@ -493,7 +493,7 @@ totem_handle_slot_state(struct totem_dispatch *totem,
|
|||
}
|
||||
|
||||
static enum totem_slot_state
|
||||
totem_handle_state(struct totem_dispatch *totem, uint64_t time)
|
||||
totem_handle_state(struct totem_dispatch *totem, usec_t time)
|
||||
{
|
||||
enum totem_slot_state global_state = SLOT_STATE_NONE;
|
||||
|
||||
|
|
@ -514,7 +514,7 @@ static void
|
|||
totem_process_event(struct evdev_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct totem_dispatch *totem = totem_dispatch(dispatch);
|
||||
enum totem_slot_state global_state;
|
||||
|
|
@ -549,7 +549,7 @@ static void
|
|||
totem_interface_process(struct evdev_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
size_t nevents;
|
||||
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
|
||||
|
|
@ -563,7 +563,7 @@ static void
|
|||
totem_interface_suspend(struct evdev_dispatch *dispatch, struct evdev_device *device)
|
||||
{
|
||||
struct totem_dispatch *totem = totem_dispatch(dispatch);
|
||||
uint64_t now = libinput_now(evdev_libinput_context(device));
|
||||
usec_t now = libinput_now(evdev_libinput_context(device));
|
||||
|
||||
for (size_t i = 0; i < totem->nslots; i++) {
|
||||
struct totem_slot *slot = &totem->slots[i];
|
||||
|
|
@ -682,7 +682,7 @@ totem_interface_initial_proximity(struct evdev_device *device,
|
|||
struct evdev_dispatch *dispatch)
|
||||
{
|
||||
struct totem_dispatch *totem = totem_dispatch(dispatch);
|
||||
uint64_t now = libinput_now(evdev_libinput_context(device));
|
||||
usec_t now = libinput_now(evdev_libinput_context(device));
|
||||
bool enable_touch = true;
|
||||
|
||||
for (size_t i = 0; i < totem->nslots; i++) {
|
||||
|
|
|
|||
64
src/evdev.c
64
src/evdev.c
|
|
@ -48,12 +48,12 @@
|
|||
#include "linux/input.h"
|
||||
#include "quirks.h"
|
||||
|
||||
#if HAVE_LIBWACOM
|
||||
#ifdef HAVE_LIBWACOM
|
||||
#include <libwacom/libwacom.h>
|
||||
#endif
|
||||
|
||||
#define DEFAULT_WHEEL_CLICK_ANGLE 15
|
||||
#define DEFAULT_BUTTON_SCROLL_TIMEOUT ms2us(200)
|
||||
#define DEFAULT_BUTTON_SCROLL_TIMEOUT usec_from_millis(200)
|
||||
|
||||
enum evdev_device_udev_tags {
|
||||
EVDEV_UDEV_TAG_NONE = 0,
|
||||
|
|
@ -167,7 +167,7 @@ evdev_device_switch_get_state(struct evdev_device *device, enum libinput_switch
|
|||
|
||||
void
|
||||
evdev_pointer_notify_physical_button(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
evdev_usage_t button,
|
||||
enum libinput_button_state state)
|
||||
{
|
||||
|
|
@ -179,7 +179,7 @@ evdev_pointer_notify_physical_button(struct evdev_device *device,
|
|||
|
||||
static void
|
||||
evdev_pointer_post_button(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
evdev_usage_t button,
|
||||
enum libinput_button_state state)
|
||||
{
|
||||
|
|
@ -205,7 +205,7 @@ evdev_pointer_post_button(struct evdev_device *device,
|
|||
}
|
||||
|
||||
static void
|
||||
evdev_button_scroll_timeout(uint64_t time, void *data)
|
||||
evdev_button_scroll_timeout(usec_t time, void *data)
|
||||
{
|
||||
struct evdev_device *device = data;
|
||||
|
||||
|
|
@ -213,7 +213,7 @@ evdev_button_scroll_timeout(uint64_t time, void *data)
|
|||
}
|
||||
|
||||
static void
|
||||
evdev_button_scroll_button(struct evdev_device *device, uint64_t time, int is_press)
|
||||
evdev_button_scroll_button(struct evdev_device *device, usec_t time, int is_press)
|
||||
{
|
||||
/* Where the button lock is enabled, we wrap the buttons into
|
||||
their own little state machine and filter out the events.
|
||||
|
|
@ -265,9 +265,10 @@ evdev_button_scroll_button(struct evdev_device *device, uint64_t time, int is_pr
|
|||
flags = TIMER_FLAG_ALLOW_NEGATIVE;
|
||||
}
|
||||
|
||||
libinput_timer_set_flags(&device->scroll.timer,
|
||||
time + DEFAULT_BUTTON_SCROLL_TIMEOUT,
|
||||
flags);
|
||||
libinput_timer_set_flags(
|
||||
&device->scroll.timer,
|
||||
usec_add(time, DEFAULT_BUTTON_SCROLL_TIMEOUT),
|
||||
flags);
|
||||
} else {
|
||||
/* For extra mouse buttons numbered 6 or more (0x115+) we assume
|
||||
* it is dedicated exclusively to scrolling, so we don't apply
|
||||
|
|
@ -314,7 +315,7 @@ evdev_button_scroll_button(struct evdev_device *device, uint64_t time, int is_pr
|
|||
|
||||
void
|
||||
evdev_pointer_notify_button(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
evdev_usage_t button,
|
||||
enum libinput_button_state state)
|
||||
{
|
||||
|
|
@ -394,7 +395,7 @@ evdev_device_transform_y(struct evdev_device *device, double y, uint32_t height)
|
|||
|
||||
void
|
||||
evdev_notify_axis_legacy_wheel(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
uint32_t axes,
|
||||
const struct normalized_coords *delta_in,
|
||||
const struct discrete_coords *discrete_in)
|
||||
|
|
@ -419,7 +420,7 @@ evdev_notify_axis_legacy_wheel(struct evdev_device *device,
|
|||
|
||||
void
|
||||
evdev_notify_axis_wheel(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
uint32_t axes,
|
||||
const struct normalized_coords *delta_in,
|
||||
const struct wheel_v120 *v120_in)
|
||||
|
|
@ -444,7 +445,7 @@ evdev_notify_axis_wheel(struct evdev_device *device,
|
|||
|
||||
void
|
||||
evdev_notify_axis_finger(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
uint32_t axes,
|
||||
const struct normalized_coords *delta_in)
|
||||
{
|
||||
|
|
@ -460,7 +461,7 @@ evdev_notify_axis_finger(struct evdev_device *device,
|
|||
|
||||
void
|
||||
evdev_notify_axis_continous(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
uint32_t axes,
|
||||
const struct normalized_coords *delta_in)
|
||||
{
|
||||
|
|
@ -1014,7 +1015,7 @@ evdev_note_time_delay(struct evdev_device *device, const struct input_event *ev)
|
|||
{
|
||||
struct libinput *libinput = evdev_libinput_context(device);
|
||||
uint32_t tdelta;
|
||||
uint64_t eventtime = input_event_time(ev);
|
||||
usec_t eventtime = input_event_time(ev);
|
||||
|
||||
/* if we have a current libinput_dispatch() snapshot, compare our
|
||||
* event time with the one from the snapshot. If we have more than
|
||||
|
|
@ -1022,10 +1023,11 @@ evdev_note_time_delay(struct evdev_device *device, const struct input_event *ev)
|
|||
* where there is no steady event flow and thus SYN_DROPPED may not
|
||||
* get hit by the kernel despite us being too slow.
|
||||
*/
|
||||
if (libinput->dispatch_time == 0 || eventtime > libinput->dispatch_time)
|
||||
if (usec_is_zero(libinput->dispatch_time) ||
|
||||
usec_cmp(eventtime, libinput->dispatch_time) > 0)
|
||||
return;
|
||||
|
||||
tdelta = us2ms(libinput->dispatch_time - eventtime);
|
||||
tdelta = usec_to_millis(usec_delta(libinput->dispatch_time, eventtime));
|
||||
if (tdelta > 20) {
|
||||
evdev_log_bug_client_ratelimit(
|
||||
device,
|
||||
|
|
@ -1084,15 +1086,7 @@ evdev_device_dispatch(void *data)
|
|||
"event frame overflow, discarding events.\n");
|
||||
}
|
||||
if (ev.type == EV_SYN && ev.code == SYN_REPORT) {
|
||||
/* A SYN_REPORT 1 event is a kernel-inserted
|
||||
* auto-repeat. Nothing in libinput cares about kernel
|
||||
* repeats and the inserted frame causes issues with
|
||||
* timestamp deltas (see e.g. #1145)
|
||||
*/
|
||||
if (ev.value != 1)
|
||||
evdev_device_dispatch_frame(libinput,
|
||||
device,
|
||||
frame);
|
||||
evdev_device_dispatch_frame(libinput, device, frame);
|
||||
evdev_frame_reset(frame);
|
||||
}
|
||||
} else if (rc == -ENODEV) {
|
||||
|
|
@ -2007,6 +2001,11 @@ evdev_configure_device(struct evdev_device *device,
|
|||
}
|
||||
}
|
||||
|
||||
if (libevdev_has_event_code(evdev, EV_SW, SW_KEYPAD_SLIDE)) {
|
||||
device->seat_caps |= EVDEV_DEVICE_SWITCH;
|
||||
device->tags |= EVDEV_TAG_KEYPAD_SLIDE_SWITCH;
|
||||
}
|
||||
|
||||
if (device->seat_caps & EVDEV_DEVICE_SWITCH)
|
||||
evdev_log_info(device, "device is a switch device\n");
|
||||
}
|
||||
|
|
@ -2316,11 +2315,11 @@ evdev_device_create(struct libinput_seat *seat, struct udev_device *udev_device)
|
|||
device->dpi = DEFAULT_MOUSE_DPI;
|
||||
|
||||
/* at most 5 SYN_DROPPED log-messages per 30s */
|
||||
ratelimit_init(&device->syn_drop_limit, s2us(30), 5);
|
||||
ratelimit_init(&device->syn_drop_limit, usec_from_seconds(30), 5);
|
||||
/* at most 5 "delayed processing" log messages per hour */
|
||||
ratelimit_init(&device->delay_warning_limit, s2us(60 * 60), 5);
|
||||
ratelimit_init(&device->delay_warning_limit, usec_from_hours(1), 5);
|
||||
/* at most 5 log-messages per 5s */
|
||||
ratelimit_init(&device->nonpointer_rel_limit, s2us(5), 5);
|
||||
ratelimit_init(&device->nonpointer_rel_limit, usec_from_seconds(5), 5);
|
||||
|
||||
matrix_init_identity(&device->abs.calibration);
|
||||
matrix_init_identity(&device->abs.usermatrix);
|
||||
|
|
@ -2678,6 +2677,9 @@ evdev_device_has_switch(struct evdev_device *device, enum libinput_switch sw)
|
|||
case LIBINPUT_SWITCH_TABLET_MODE:
|
||||
code = SW_TABLET_MODE;
|
||||
break;
|
||||
case LIBINPUT_SWITCH_KEYPAD_SLIDE:
|
||||
code = SW_KEYPAD_SLIDE;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -2705,7 +2707,7 @@ evdev_start_scrolling(struct evdev_device *device, enum libinput_pointer_axis ax
|
|||
|
||||
void
|
||||
evdev_post_scroll(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum libinput_pointer_axis_source source,
|
||||
const struct normalized_coords *delta)
|
||||
{
|
||||
|
|
@ -2779,7 +2781,7 @@ evdev_post_scroll(struct evdev_device *device,
|
|||
|
||||
void
|
||||
evdev_stop_scroll(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum libinput_pointer_axis_source source)
|
||||
{
|
||||
const struct normalized_coords zero = { 0.0, 0.0 };
|
||||
|
|
|
|||
45
src/evdev.h
45
src/evdev.h
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include "evdev-frame.h"
|
||||
#include "filter.h"
|
||||
#include "libinput-feature.h"
|
||||
#include "libinput-private.h"
|
||||
#include "linux/input.h"
|
||||
#include "quirks.h"
|
||||
|
|
@ -79,6 +80,7 @@ enum evdev_device_tags {
|
|||
EVDEV_TAG_TABLET_MODE_SWITCH = bit(8),
|
||||
EVDEV_TAG_TABLET_TOUCHPAD = bit(9),
|
||||
EVDEV_TAG_VIRTUAL = bit(10),
|
||||
EVDEV_TAG_KEYPAD_SLIDE_SWITCH = bit(11),
|
||||
};
|
||||
|
||||
enum evdev_middlebutton_state {
|
||||
|
|
@ -217,7 +219,7 @@ struct evdev_device {
|
|||
/* Currently enabled method, button */
|
||||
enum libinput_config_scroll_method method;
|
||||
evdev_usage_t button;
|
||||
uint64_t button_down_time;
|
||||
usec_t button_down_time;
|
||||
|
||||
/* set during device init, used at runtime to delay changes
|
||||
* until all buttons are up */
|
||||
|
|
@ -277,7 +279,7 @@ struct evdev_device {
|
|||
enum evdev_middlebutton_state state;
|
||||
struct libinput_timer timer;
|
||||
uint32_t button_mask;
|
||||
uint64_t first_event_time;
|
||||
usec_t first_event_time;
|
||||
} middlebutton;
|
||||
};
|
||||
|
||||
|
|
@ -296,7 +298,7 @@ struct evdev_dispatch_interface {
|
|||
void (*process)(struct evdev_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
|
||||
/* Device is being suspended */
|
||||
void (*suspend)(struct evdev_dispatch *dispatch, struct evdev_device *device);
|
||||
|
|
@ -335,7 +337,7 @@ struct evdev_dispatch_interface {
|
|||
struct evdev_device *device,
|
||||
enum evdev_arbitration_state which,
|
||||
const struct phys_rect *rect, /* may be NULL */
|
||||
uint64_t now);
|
||||
usec_t now);
|
||||
|
||||
/* Called when touch arbitration is on, updates the area where touch
|
||||
* arbitration should apply.
|
||||
|
|
@ -343,7 +345,7 @@ struct evdev_dispatch_interface {
|
|||
void (*touch_arbitration_update_rect)(struct evdev_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
const struct phys_rect *rect,
|
||||
uint64_t now);
|
||||
usec_t now);
|
||||
|
||||
/* Return the state of the given switch */
|
||||
enum libinput_switch_state (*get_switch_state)(struct evdev_dispatch *dispatch,
|
||||
|
|
@ -352,6 +354,9 @@ struct evdev_dispatch_interface {
|
|||
void (*left_handed_toggle)(struct evdev_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
bool left_handed_enabled);
|
||||
|
||||
void (*disable_feature)(struct evdev_dispatch *dispatch,
|
||||
enum libinput_feature feature);
|
||||
};
|
||||
|
||||
enum evdev_dispatch_type {
|
||||
|
|
@ -389,6 +394,14 @@ evdev_libinput_context(const struct evdev_device *device)
|
|||
return device->base.seat->libinput;
|
||||
}
|
||||
|
||||
static inline void
|
||||
evdev_device_disable_feature(struct evdev_device *device, enum libinput_feature feature)
|
||||
{
|
||||
if (device->dispatch && device->dispatch->interface &&
|
||||
device->dispatch->interface->disable_feature)
|
||||
device->dispatch->interface->disable_feature(device->dispatch, feature);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
evdev_device_has_model_quirk(struct evdev_device *device, enum quirk model_quirk)
|
||||
{
|
||||
|
|
@ -540,12 +553,12 @@ evdev_notify_resumed_device(struct evdev_device *device);
|
|||
|
||||
void
|
||||
evdev_pointer_notify_button(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
evdev_usage_t button,
|
||||
enum libinput_button_state state);
|
||||
void
|
||||
evdev_pointer_notify_physical_button(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
evdev_usage_t button,
|
||||
enum libinput_button_state state);
|
||||
|
||||
|
|
@ -566,36 +579,36 @@ evdev_update_key_down_count(struct evdev_device *device,
|
|||
|
||||
void
|
||||
evdev_notify_axis_legacy_wheel(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
uint32_t axes,
|
||||
const struct normalized_coords *delta_in,
|
||||
const struct discrete_coords *discrete_in);
|
||||
void
|
||||
evdev_notify_axis_wheel(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
uint32_t axes,
|
||||
const struct normalized_coords *delta_in,
|
||||
const struct wheel_v120 *v120_in);
|
||||
void
|
||||
evdev_notify_axis_finger(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
uint32_t axes,
|
||||
const struct normalized_coords *delta_in);
|
||||
void
|
||||
evdev_notify_axis_continous(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
uint32_t axes,
|
||||
const struct normalized_coords *delta_in);
|
||||
|
||||
void
|
||||
evdev_post_scroll(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum libinput_pointer_axis_source source,
|
||||
const struct normalized_coords *delta);
|
||||
|
||||
void
|
||||
evdev_stop_scroll(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
enum libinput_pointer_axis_source source);
|
||||
|
||||
void
|
||||
|
|
@ -606,7 +619,7 @@ evdev_device_destroy(struct evdev_device *device);
|
|||
|
||||
bool
|
||||
evdev_middlebutton_filter_button(struct evdev_device *device,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
evdev_usage_t button,
|
||||
enum libinput_button_state state);
|
||||
|
||||
|
|
@ -957,7 +970,9 @@ evdev_device_init_abs_range_warnings(struct evdev_device *device)
|
|||
device->abs.warning_range.max.y = y->maximum + 0.05 * height;
|
||||
|
||||
/* One warning every 5 min is enough */
|
||||
ratelimit_init(&device->abs.warning_range.range_warn_limit, s2us(3000), 1);
|
||||
ratelimit_init(&device->abs.warning_range.range_warn_limit,
|
||||
usec_from_seconds(3000),
|
||||
1);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
|
|||
|
|
@ -29,11 +29,12 @@
|
|||
#include "filter-private.h"
|
||||
#include "filter.h"
|
||||
|
||||
#define MOTION_TIMEOUT ms2us(1000)
|
||||
#define FIRST_MOTION_TIME_INTERVAL ms2us(7) /* random but good enough interval for very first event */
|
||||
#define MOTION_TIMEOUT usec_from_millis(1000)
|
||||
#define FIRST_MOTION_TIME_INTERVAL usec_from_millis(7) /* random but good enough interval for very first event */
|
||||
|
||||
struct custom_accel_function {
|
||||
uint64_t last_time;
|
||||
usec_t last_time;
|
||||
usec_t last_delta_time;
|
||||
double step;
|
||||
size_t npoints;
|
||||
double points[];
|
||||
|
|
@ -57,7 +58,8 @@ create_custom_accel_function(double step, const double *points, size_t npoints)
|
|||
|
||||
struct custom_accel_function *cf =
|
||||
zalloc(sizeof(*cf) + npoints * sizeof(*points));
|
||||
cf->last_time = 0;
|
||||
cf->last_time = usec_from_uint64_t(0);
|
||||
cf->last_delta_time = FIRST_MOTION_TIME_INTERVAL;
|
||||
cf->step = step;
|
||||
cf->npoints = npoints;
|
||||
memcpy(cf->points, points, sizeof(*points) * npoints);
|
||||
|
|
@ -77,7 +79,7 @@ custom_accel_function_destroy(struct custom_accel_function *cf)
|
|||
static double
|
||||
custom_accel_function_calculate_speed(struct custom_accel_function *cf,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
/* Although most devices have a constant polling rate, and for fast
|
||||
* movements these distances do represent the actual speed,
|
||||
|
|
@ -110,13 +112,26 @@ custom_accel_function_calculate_speed(struct custom_accel_function *cf,
|
|||
|
||||
/* calculate speed based on time passed since last event */
|
||||
double distance = hypot(unaccelerated->x, unaccelerated->y);
|
||||
/* delta_time can be zero when:
|
||||
* - the fallback acceleration function is used for multiple movement types
|
||||
* (for example, pointer motion and wheel scrolling simultaneously)
|
||||
* - two different methods produce the same movement at the same time
|
||||
* (for example, button-scrolling and wheel-scrolling)
|
||||
*
|
||||
* Reusing the last delta_time is a graceful fallback even if there are
|
||||
* duplicate events or event-ordering bugs.
|
||||
*/
|
||||
usec_t delta_time = usec_cmp(time, cf->last_time) > 0
|
||||
? usec_delta(time, cf->last_time)
|
||||
: cf->last_delta_time;
|
||||
/* handle first event in a motion */
|
||||
if (time - cf->last_time > MOTION_TIMEOUT)
|
||||
cf->last_time = time - FIRST_MOTION_TIME_INTERVAL;
|
||||
if (usec_cmp(delta_time, MOTION_TIMEOUT) > 0)
|
||||
delta_time = FIRST_MOTION_TIME_INTERVAL;
|
||||
|
||||
double dt = us2ms_f(time - cf->last_time);
|
||||
double speed = distance / dt; /* speed is in device-units per ms */
|
||||
/* speed is in device-units per ms */
|
||||
double speed = distance / us2ms_f(delta_time);
|
||||
cf->last_time = time;
|
||||
cf->last_delta_time = delta_time;
|
||||
|
||||
return speed;
|
||||
}
|
||||
|
|
@ -182,7 +197,7 @@ custom_accel_function_profile(struct custom_accel_function *cf, double speed_in)
|
|||
static struct normalized_coords
|
||||
custom_accel_function_filter(struct custom_accel_function *cf,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
double speed = custom_accel_function_calculate_speed(cf, unaccelerated, time);
|
||||
|
||||
|
|
@ -238,7 +253,7 @@ static struct normalized_coords
|
|||
custom_accelerator_filter(enum libinput_config_accel_type accel_type,
|
||||
struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct custom_accelerator *f = (struct custom_accelerator *)filter;
|
||||
struct custom_accel_function *cf;
|
||||
|
|
@ -249,7 +264,7 @@ custom_accelerator_filter(enum libinput_config_accel_type accel_type,
|
|||
}
|
||||
|
||||
static void
|
||||
custom_accelerator_restart(struct motion_filter *filter, void *data, uint64_t time)
|
||||
custom_accelerator_restart(struct motion_filter *filter, void *data, usec_t time)
|
||||
{
|
||||
/* noop, this function has no effect in the custom interface */
|
||||
}
|
||||
|
|
@ -333,7 +348,7 @@ double
|
|||
custom_accel_profile_fallback(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
return custom_accelerator_profile(LIBINPUT_ACCEL_TYPE_FALLBACK,
|
||||
filter,
|
||||
|
|
@ -344,7 +359,7 @@ static struct normalized_coords
|
|||
custom_accelerator_filter_fallback(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
return custom_accelerator_filter(LIBINPUT_ACCEL_TYPE_FALLBACK,
|
||||
filter,
|
||||
|
|
@ -356,7 +371,7 @@ double
|
|||
custom_accel_profile_motion(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
return custom_accelerator_profile(LIBINPUT_ACCEL_TYPE_MOTION, filter, speed_in);
|
||||
}
|
||||
|
|
@ -365,7 +380,7 @@ static struct normalized_coords
|
|||
custom_accelerator_filter_motion(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
return custom_accelerator_filter(LIBINPUT_ACCEL_TYPE_MOTION,
|
||||
filter,
|
||||
|
|
@ -377,7 +392,7 @@ double
|
|||
custom_accel_profile_scroll(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
return custom_accelerator_profile(LIBINPUT_ACCEL_TYPE_SCROLL, filter, speed_in);
|
||||
}
|
||||
|
|
@ -386,7 +401,8 @@ static struct normalized_coords
|
|||
custom_accelerator_filter_scroll(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time,
|
||||
enum filter_scroll_type type)
|
||||
{
|
||||
return custom_accelerator_filter(LIBINPUT_ACCEL_TYPE_SCROLL,
|
||||
filter,
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ static struct normalized_coords
|
|||
accelerator_filter_flat(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct pointer_accelerator_flat *accel_filter =
|
||||
(struct pointer_accelerator_flat *)filter;
|
||||
|
|
@ -62,10 +62,10 @@ accelerator_filter_flat(struct motion_filter *filter,
|
|||
}
|
||||
|
||||
static struct normalized_coords
|
||||
accelerator_filter_noop_flat(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
accelerator_filter_constant_flat(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
usec_t time)
|
||||
{
|
||||
/* We map the unaccelerated flat filter to have the same behavior as
|
||||
* the "accelerated" flat filter.
|
||||
|
|
@ -81,6 +81,27 @@ accelerator_filter_noop_flat(struct motion_filter *filter,
|
|||
return accelerator_filter_flat(filter, unaccelerated, data, time);
|
||||
}
|
||||
|
||||
static struct normalized_coords
|
||||
accelerator_filter_scroll_flat(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
usec_t time,
|
||||
enum filter_scroll_type type)
|
||||
{
|
||||
/* Scroll wheels were not historically accelerated and have different
|
||||
* units than button scrolling. Maintain the status quo and do not
|
||||
* accelerate wheel events.
|
||||
*/
|
||||
if (type == FILTER_SCROLL_TYPE_WHEEL) {
|
||||
return (struct normalized_coords){
|
||||
.x = unaccelerated->x,
|
||||
.y = unaccelerated->y,
|
||||
};
|
||||
}
|
||||
|
||||
return accelerator_filter_constant_flat(filter, unaccelerated, data, time);
|
||||
}
|
||||
|
||||
static bool
|
||||
accelerator_set_speed_flat(struct motion_filter *filter, double speed_adjustment)
|
||||
{
|
||||
|
|
@ -112,8 +133,8 @@ accelerator_destroy_flat(struct motion_filter *filter)
|
|||
static const struct motion_filter_interface accelerator_interface_flat = {
|
||||
.type = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
|
||||
.filter = accelerator_filter_flat,
|
||||
.filter_constant = accelerator_filter_noop_flat,
|
||||
.filter_scroll = accelerator_filter_noop_flat,
|
||||
.filter_constant = accelerator_filter_constant_flat,
|
||||
.filter_scroll = accelerator_filter_scroll_flat,
|
||||
.restart = NULL,
|
||||
.destroy = accelerator_destroy_flat,
|
||||
.set_speed = accelerator_set_speed_flat,
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@
|
|||
* Default parameters for pointer acceleration profiles.
|
||||
*/
|
||||
|
||||
#define DEFAULT_THRESHOLD v_ms2us(0.4) /* in units/us */
|
||||
#define MINIMUM_THRESHOLD v_ms2us(0.2) /* in units/us */
|
||||
#define DEFAULT_THRESHOLD v_usec_from_millis(0.4) /* in units/us */
|
||||
#define MINIMUM_THRESHOLD v_usec_from_millis(0.2) /* in units/us */
|
||||
#define DEFAULT_ACCELERATION 2.0 /* unitless factor */
|
||||
#define DEFAULT_INCLINE 1.1 /* unitless factor */
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ double
|
|||
pointer_accel_profile_linear_low_dpi(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in, /* in device units (units/us) */
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct pointer_accelerator_low_dpi *accel_filter =
|
||||
(struct pointer_accelerator_low_dpi *)filter;
|
||||
|
|
@ -107,7 +107,7 @@ static inline double
|
|||
calculate_acceleration_factor(struct pointer_accelerator_low_dpi *accel,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
double velocity; /* units/us in device-native dpi*/
|
||||
double accel_factor;
|
||||
|
|
@ -129,7 +129,7 @@ static struct normalized_coords
|
|||
accelerator_filter_low_dpi(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct pointer_accelerator_low_dpi *accel =
|
||||
(struct pointer_accelerator_low_dpi *)filter;
|
||||
|
|
@ -145,10 +145,10 @@ accelerator_filter_low_dpi(struct motion_filter *filter,
|
|||
}
|
||||
|
||||
static struct normalized_coords
|
||||
accelerator_filter_noop(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
accelerator_filter_constant(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
usec_t time)
|
||||
{
|
||||
const struct normalized_coords normalized = {
|
||||
.x = unaccelerated->x,
|
||||
|
|
@ -157,8 +157,18 @@ accelerator_filter_noop(struct motion_filter *filter,
|
|||
return normalized;
|
||||
}
|
||||
|
||||
static struct normalized_coords
|
||||
accelerator_filter_scroll(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
usec_t time,
|
||||
enum filter_scroll_type type)
|
||||
{
|
||||
return accelerator_filter_constant(filter, unaccelerated, data, time);
|
||||
}
|
||||
|
||||
static void
|
||||
accelerator_restart(struct motion_filter *filter, void *data, uint64_t time)
|
||||
accelerator_restart(struct motion_filter *filter, void *data, usec_t time)
|
||||
{
|
||||
struct pointer_accelerator_low_dpi *accel =
|
||||
(struct pointer_accelerator_low_dpi *)filter;
|
||||
|
|
@ -188,7 +198,8 @@ accelerator_set_speed(struct motion_filter *filter, double speed_adjustment)
|
|||
don't read more into them other than "they mostly worked ok" */
|
||||
|
||||
/* delay when accel kicks in */
|
||||
accel_filter->threshold = DEFAULT_THRESHOLD - v_ms2us(0.25) * speed_adjustment;
|
||||
accel_filter->threshold =
|
||||
DEFAULT_THRESHOLD - v_usec_from_millis(0.25) * speed_adjustment;
|
||||
if (accel_filter->threshold < MINIMUM_THRESHOLD)
|
||||
accel_filter->threshold = MINIMUM_THRESHOLD;
|
||||
|
||||
|
|
@ -205,8 +216,8 @@ accelerator_set_speed(struct motion_filter *filter, double speed_adjustment)
|
|||
static const struct motion_filter_interface accelerator_interface_low_dpi = {
|
||||
.type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
|
||||
.filter = accelerator_filter_low_dpi,
|
||||
.filter_constant = accelerator_filter_noop,
|
||||
.filter_scroll = accelerator_filter_noop,
|
||||
.filter_constant = accelerator_filter_constant,
|
||||
.filter_scroll = accelerator_filter_scroll,
|
||||
.restart = accelerator_restart,
|
||||
.destroy = accelerator_destroy,
|
||||
.set_speed = accelerator_set_speed,
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@
|
|||
* Default parameters for pointer acceleration profiles.
|
||||
*/
|
||||
|
||||
#define DEFAULT_THRESHOLD v_ms2us(0.4) /* in 1000dpi units/us */
|
||||
#define MINIMUM_THRESHOLD v_ms2us(0.2) /* in 1000dpi units/us */
|
||||
#define DEFAULT_THRESHOLD v_usec_from_millis(0.4) /* in 1000dpi units/us */
|
||||
#define MINIMUM_THRESHOLD v_usec_from_millis(0.2) /* in 1000dpi units/us */
|
||||
#define DEFAULT_ACCELERATION 2.0 /* unitless factor */
|
||||
#define DEFAULT_INCLINE 1.1 /* unitless factor */
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ static inline double
|
|||
calculate_acceleration_factor(struct pointer_accelerator *accel,
|
||||
const struct normalized_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
double velocity; /* units/us in normalized 1000dpi units*/
|
||||
double accel_factor;
|
||||
|
|
@ -104,7 +104,7 @@ static struct normalized_coords
|
|||
accelerator_filter_linear(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct pointer_accelerator *accel = (struct pointer_accelerator *)filter;
|
||||
|
||||
|
|
@ -133,18 +133,39 @@ accelerator_filter_linear(struct motion_filter *filter,
|
|||
* motion
|
||||
*/
|
||||
static struct normalized_coords
|
||||
accelerator_filter_noop(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
accelerator_filter_constant(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
usec_t time)
|
||||
{
|
||||
struct pointer_accelerator *accel = (struct pointer_accelerator *)filter;
|
||||
|
||||
return normalize_for_dpi(unaccelerated, accel->dpi);
|
||||
}
|
||||
|
||||
static struct normalized_coords
|
||||
accelerator_filter_scroll(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
usec_t time,
|
||||
enum filter_scroll_type type)
|
||||
{
|
||||
/* Scroll wheels were not historically accelerated and have different
|
||||
* units than button scrolling. Maintain the status quo and do not
|
||||
* accelerate wheel events.
|
||||
*/
|
||||
if (type == FILTER_SCROLL_TYPE_WHEEL) {
|
||||
return (struct normalized_coords){
|
||||
.x = unaccelerated->x,
|
||||
.y = unaccelerated->y,
|
||||
};
|
||||
}
|
||||
|
||||
return accelerator_filter_constant(filter, unaccelerated, data, time);
|
||||
}
|
||||
|
||||
static void
|
||||
accelerator_restart(struct motion_filter *filter, void *data, uint64_t time)
|
||||
accelerator_restart(struct motion_filter *filter, void *data, usec_t time)
|
||||
{
|
||||
struct pointer_accelerator *accel = (struct pointer_accelerator *)filter;
|
||||
|
||||
|
|
@ -171,7 +192,8 @@ accelerator_set_speed(struct motion_filter *filter, double speed_adjustment)
|
|||
don't read more into them other than "they mostly worked ok" */
|
||||
|
||||
/* delay when accel kicks in */
|
||||
accel_filter->threshold = DEFAULT_THRESHOLD - v_ms2us(0.25) * speed_adjustment;
|
||||
accel_filter->threshold =
|
||||
DEFAULT_THRESHOLD - v_usec_from_millis(0.25) * speed_adjustment;
|
||||
if (accel_filter->threshold < MINIMUM_THRESHOLD)
|
||||
accel_filter->threshold = MINIMUM_THRESHOLD;
|
||||
|
||||
|
|
@ -189,7 +211,7 @@ double
|
|||
pointer_accel_profile_linear(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in, /* in normalized units */
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct pointer_accelerator *accel_filter = (struct pointer_accelerator *)filter;
|
||||
const double max_accel = accel_filter->accel; /* unitless factor */
|
||||
|
|
@ -260,8 +282,8 @@ pointer_accel_profile_linear(struct motion_filter *filter,
|
|||
static const struct motion_filter_interface accelerator_interface = {
|
||||
.type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
|
||||
.filter = accelerator_filter_linear,
|
||||
.filter_constant = accelerator_filter_noop,
|
||||
.filter_scroll = accelerator_filter_noop,
|
||||
.filter_constant = accelerator_filter_constant,
|
||||
.filter_scroll = accelerator_filter_scroll,
|
||||
.restart = accelerator_restart,
|
||||
.destroy = accelerator_destroy,
|
||||
.set_speed = accelerator_set_speed,
|
||||
|
|
|
|||
|
|
@ -34,18 +34,19 @@ struct motion_filter_interface {
|
|||
struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
struct normalized_coords (*filter_constant)(
|
||||
struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
struct normalized_coords (*filter_scroll)(
|
||||
struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time);
|
||||
void (*restart)(struct motion_filter *filter, void *data, uint64_t time);
|
||||
usec_t time,
|
||||
enum filter_scroll_type type);
|
||||
void (*restart)(struct motion_filter *filter, void *data, usec_t time);
|
||||
void (*destroy)(struct motion_filter *filter);
|
||||
bool (*set_speed)(struct motion_filter *filter, double speed_adjustment);
|
||||
bool (*set_accel_config)(struct motion_filter *filter,
|
||||
|
|
@ -59,19 +60,19 @@ struct motion_filter {
|
|||
|
||||
struct pointer_tracker {
|
||||
struct device_float_coords delta; /* delta to most recent event */
|
||||
uint64_t time; /* us */
|
||||
usec_t time; /* us */
|
||||
uint32_t dir;
|
||||
};
|
||||
|
||||
/* For smoothing timestamps from devices with unreliable timing */
|
||||
struct pointer_delta_smoothener {
|
||||
uint64_t threshold;
|
||||
uint64_t value;
|
||||
usec_t threshold;
|
||||
usec_t value;
|
||||
};
|
||||
|
||||
static inline struct pointer_delta_smoothener *
|
||||
pointer_delta_smoothener_create(uint64_t event_delta_smooth_threshold,
|
||||
uint64_t event_delta_smooth_value)
|
||||
pointer_delta_smoothener_create(usec_t event_delta_smooth_threshold,
|
||||
usec_t event_delta_smooth_value)
|
||||
{
|
||||
struct pointer_delta_smoothener *s = zalloc(sizeof(*s));
|
||||
s->threshold = event_delta_smooth_threshold;
|
||||
|
|
@ -99,17 +100,17 @@ void
|
|||
trackers_free(struct pointer_trackers *trackers);
|
||||
|
||||
void
|
||||
trackers_reset(struct pointer_trackers *trackers, uint64_t time);
|
||||
trackers_reset(struct pointer_trackers *trackers, usec_t time);
|
||||
void
|
||||
trackers_feed(struct pointer_trackers *trackers,
|
||||
const struct device_float_coords *delta,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
|
||||
struct pointer_tracker *
|
||||
trackers_by_offset(struct pointer_trackers *trackers, unsigned int offset);
|
||||
|
||||
double
|
||||
trackers_velocity(struct pointer_trackers *trackers, uint64_t time);
|
||||
trackers_velocity(struct pointer_trackers *trackers, usec_t time);
|
||||
|
||||
double
|
||||
calculate_acceleration_simpsons(struct motion_filter *filter,
|
||||
|
|
@ -117,7 +118,7 @@ calculate_acceleration_simpsons(struct motion_filter *filter,
|
|||
void *data,
|
||||
double velocity,
|
||||
double last_velocity,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
|
||||
/* Convert speed/velocity from units/us to units/ms */
|
||||
static inline double
|
||||
|
|
@ -134,7 +135,7 @@ v_us2s(double units_per_us)
|
|||
|
||||
/* Convert speed/velocity from units/ms to units/us */
|
||||
static inline double
|
||||
v_ms2us(double units_per_ms)
|
||||
v_usec_from_millis(double units_per_ms)
|
||||
{
|
||||
return units_per_ms / 1000.0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ static struct normalized_coords
|
|||
tablet_accelerator_filter_flat(struct motion_filter *filter,
|
||||
const struct device_float_coords *units,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct tablet_accelerator_flat *accel_filter =
|
||||
(struct tablet_accelerator_flat *)filter;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ static struct normalized_coords
|
|||
accelerator_filter_touchpad_flat(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct touchpad_accelerator_flat *accel =
|
||||
(struct touchpad_accelerator_flat *)filter;
|
||||
|
|
@ -65,10 +65,11 @@ accelerator_filter_touchpad_flat(struct motion_filter *filter,
|
|||
}
|
||||
|
||||
static struct normalized_coords
|
||||
accelerator_filter_noop_touchpad_flat(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
accelerator_filter_constant_touchpad_flat(
|
||||
struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
usec_t time)
|
||||
{
|
||||
/* We map the unaccelerated flat filter to have the same behavior as
|
||||
* the "accelerated" flat filter.
|
||||
|
|
@ -84,6 +85,30 @@ accelerator_filter_noop_touchpad_flat(struct motion_filter *filter,
|
|||
return accelerator_filter_touchpad_flat(filter, unaccelerated, data, time);
|
||||
}
|
||||
|
||||
static struct normalized_coords
|
||||
accelerator_filter_scroll_touchpad_flat(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
usec_t time,
|
||||
enum filter_scroll_type type)
|
||||
{
|
||||
/* Scroll wheels were not historically accelerated and have different
|
||||
* units than button scrolling. Maintain the status quo and do not
|
||||
* accelerate wheel events.
|
||||
*/
|
||||
if (type == FILTER_SCROLL_TYPE_WHEEL) {
|
||||
return (struct normalized_coords){
|
||||
.x = unaccelerated->x,
|
||||
.y = unaccelerated->y,
|
||||
};
|
||||
}
|
||||
|
||||
return accelerator_filter_constant_touchpad_flat(filter,
|
||||
unaccelerated,
|
||||
data,
|
||||
time);
|
||||
}
|
||||
|
||||
static bool
|
||||
accelerator_set_speed_touchpad_flat(struct motion_filter *filter,
|
||||
double speed_adjustment)
|
||||
|
|
@ -111,8 +136,8 @@ accelerator_destroy_touchpad_flat(struct motion_filter *filter)
|
|||
static const struct motion_filter_interface accelerator_interface_touchpad_flat = {
|
||||
.type = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
|
||||
.filter = accelerator_filter_touchpad_flat,
|
||||
.filter_constant = accelerator_filter_noop_touchpad_flat,
|
||||
.filter_scroll = accelerator_filter_noop_touchpad_flat,
|
||||
.filter_constant = accelerator_filter_constant_touchpad_flat,
|
||||
.filter_scroll = accelerator_filter_scroll_touchpad_flat,
|
||||
.restart = NULL,
|
||||
.destroy = accelerator_destroy_touchpad_flat,
|
||||
.set_speed = accelerator_set_speed_touchpad_flat,
|
||||
|
|
|
|||
|
|
@ -45,13 +45,13 @@
|
|||
* Default parameters for pointer acceleration profiles.
|
||||
*/
|
||||
|
||||
#define DEFAULT_THRESHOLD v_ms2us(0.4) /* in units/us */
|
||||
#define MINIMUM_THRESHOLD v_ms2us(0.2) /* in units/us */
|
||||
#define DEFAULT_THRESHOLD v_usec_from_millis(0.4) /* in units/us */
|
||||
#define MINIMUM_THRESHOLD v_usec_from_millis(0.2) /* in units/us */
|
||||
#define DEFAULT_ACCELERATION 2.0 /* unitless factor */
|
||||
#define DEFAULT_INCLINE 1.1 /* unitless factor */
|
||||
|
||||
/* for the Lenovo x230 custom accel. do not touch */
|
||||
#define X230_THRESHOLD v_ms2us(0.4) /* in units/us */
|
||||
#define X230_THRESHOLD v_usec_from_millis(0.4) /* in units/us */
|
||||
#define X230_ACCELERATION 2.0 /* unitless factor */
|
||||
#define X230_INCLINE 1.1 /* unitless factor */
|
||||
#define X230_MAGIC_SLOWDOWN 0.4 /* unitless */
|
||||
|
|
@ -88,7 +88,7 @@ static double
|
|||
acceleration_profile(struct pointer_accelerator_x230 *accel,
|
||||
void *data,
|
||||
double velocity,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
return accel->profile(&accel->base, data, velocity, time);
|
||||
}
|
||||
|
|
@ -110,7 +110,7 @@ calculate_acceleration(struct pointer_accelerator_x230 *accel,
|
|||
void *data,
|
||||
double velocity,
|
||||
double last_velocity,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
double factor;
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ static struct normalized_coords
|
|||
accelerator_filter_x230(struct motion_filter *filter,
|
||||
const struct device_float_coords *raw,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct pointer_accelerator_x230 *accel =
|
||||
(struct pointer_accelerator_x230 *)filter;
|
||||
|
|
@ -171,7 +171,7 @@ static struct normalized_coords
|
|||
accelerator_filter_constant_x230(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct pointer_accelerator_x230 *accel =
|
||||
(struct pointer_accelerator_x230 *)filter;
|
||||
|
|
@ -185,8 +185,29 @@ accelerator_filter_constant_x230(struct motion_filter *filter,
|
|||
return normalized;
|
||||
}
|
||||
|
||||
static struct normalized_coords
|
||||
accelerator_filter_scroll_x230(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
usec_t time,
|
||||
enum filter_scroll_type type)
|
||||
{
|
||||
/* Scroll wheels were not historically accelerated and have different
|
||||
* units than button scrolling. Maintain the status quo and do not
|
||||
* accelerate wheel events.
|
||||
*/
|
||||
if (type == FILTER_SCROLL_TYPE_WHEEL) {
|
||||
return (struct normalized_coords){
|
||||
.x = unaccelerated->x,
|
||||
.y = unaccelerated->y,
|
||||
};
|
||||
}
|
||||
|
||||
return accelerator_filter_constant_x230(filter, unaccelerated, data, time);
|
||||
}
|
||||
|
||||
static void
|
||||
accelerator_restart_x230(struct motion_filter *filter, void *data, uint64_t time)
|
||||
accelerator_restart_x230(struct motion_filter *filter, void *data, usec_t time)
|
||||
{
|
||||
struct pointer_accelerator_x230 *accel =
|
||||
(struct pointer_accelerator_x230 *)filter;
|
||||
|
|
@ -195,7 +216,7 @@ accelerator_restart_x230(struct motion_filter *filter, void *data, uint64_t time
|
|||
|
||||
for (offset = 1; offset < accel->trackers.ntrackers; offset++) {
|
||||
tracker = trackers_by_offset(&accel->trackers, offset);
|
||||
tracker->time = 0;
|
||||
tracker->time = usec_from_uint64_t(0);
|
||||
tracker->dir = 0;
|
||||
tracker->delta.x = 0;
|
||||
tracker->delta.y = 0;
|
||||
|
|
@ -228,7 +249,8 @@ accelerator_set_speed_x230(struct motion_filter *filter, double speed_adjustment
|
|||
don't read more into them other than "they mostly worked ok" */
|
||||
|
||||
/* delay when accel kicks in */
|
||||
accel_filter->threshold = DEFAULT_THRESHOLD - v_ms2us(0.25) * speed_adjustment;
|
||||
accel_filter->threshold =
|
||||
DEFAULT_THRESHOLD - v_usec_from_millis(0.25) * speed_adjustment;
|
||||
if (accel_filter->threshold < MINIMUM_THRESHOLD)
|
||||
accel_filter->threshold = MINIMUM_THRESHOLD;
|
||||
|
||||
|
|
@ -246,7 +268,7 @@ double
|
|||
touchpad_lenovo_x230_accel_profile(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in, /* 1000dpi-units/µs */
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
/* Those touchpads presents an actual lower resolution that what is
|
||||
* advertised. We see some jumps from the cursor due to the big steps
|
||||
|
|
@ -285,7 +307,7 @@ static const struct motion_filter_interface accelerator_interface_x230 = {
|
|||
.type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
|
||||
.filter = accelerator_filter_x230,
|
||||
.filter_constant = accelerator_filter_constant_x230,
|
||||
.filter_scroll = accelerator_filter_constant_x230,
|
||||
.filter_scroll = accelerator_filter_scroll_x230,
|
||||
.restart = accelerator_restart_x230,
|
||||
.destroy = accelerator_destroy_x230,
|
||||
.set_speed = accelerator_set_speed_x230,
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ static inline double
|
|||
calculate_acceleration_factor(struct touchpad_accelerator *accel,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
double velocity; /* units/us in device-native dpi*/
|
||||
double accel_factor;
|
||||
|
|
@ -94,7 +94,7 @@ static struct normalized_coords
|
|||
accelerator_filter_touchpad(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct touchpad_accelerator *accel = (struct touchpad_accelerator *)filter;
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ static struct normalized_coords
|
|||
touchpad_constant_filter(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct touchpad_accelerator *accel = (struct touchpad_accelerator *)filter;
|
||||
struct normalized_coords normalized;
|
||||
|
|
@ -162,8 +162,29 @@ touchpad_constant_filter(struct motion_filter *filter,
|
|||
return normalized;
|
||||
}
|
||||
|
||||
static struct normalized_coords
|
||||
touchpad_scroll_filter(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
usec_t time,
|
||||
enum filter_scroll_type type)
|
||||
{
|
||||
/* Scroll wheels were not historically accelerated and have different
|
||||
* units than button scrolling. Maintain the status quo and do not
|
||||
* accelerate wheel events.
|
||||
*/
|
||||
if (type == FILTER_SCROLL_TYPE_WHEEL) {
|
||||
return (struct normalized_coords){
|
||||
.x = unaccelerated->x,
|
||||
.y = unaccelerated->y,
|
||||
};
|
||||
}
|
||||
|
||||
return touchpad_constant_filter(filter, unaccelerated, data, time);
|
||||
}
|
||||
|
||||
static void
|
||||
touchpad_accelerator_restart(struct motion_filter *filter, void *data, uint64_t time)
|
||||
touchpad_accelerator_restart(struct motion_filter *filter, void *data, usec_t time)
|
||||
{
|
||||
struct touchpad_accelerator *accel = (struct touchpad_accelerator *)filter;
|
||||
|
||||
|
|
@ -183,7 +204,7 @@ double
|
|||
touchpad_accel_profile_linear(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in, /* in device units/µs */
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct touchpad_accelerator *accel_filter =
|
||||
(struct touchpad_accelerator *)filter;
|
||||
|
|
@ -272,7 +293,7 @@ static const struct motion_filter_interface accelerator_interface_touchpad = {
|
|||
.type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
|
||||
.filter = accelerator_filter_touchpad,
|
||||
.filter_constant = touchpad_constant_filter,
|
||||
.filter_scroll = touchpad_constant_filter,
|
||||
.filter_scroll = touchpad_scroll_filter,
|
||||
.restart = touchpad_accelerator_restart,
|
||||
.destroy = touchpad_accelerator_destroy,
|
||||
.set_speed = touchpad_accelerator_set_speed,
|
||||
|
|
@ -280,8 +301,8 @@ static const struct motion_filter_interface accelerator_interface_touchpad = {
|
|||
|
||||
struct motion_filter *
|
||||
create_pointer_accelerator_filter_touchpad(int dpi,
|
||||
uint64_t event_delta_smooth_threshold,
|
||||
uint64_t event_delta_smooth_value,
|
||||
usec_t event_delta_smooth_threshold,
|
||||
usec_t event_delta_smooth_value,
|
||||
bool use_velocity_averaging)
|
||||
{
|
||||
struct touchpad_accelerator *filter;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ static struct normalized_coords
|
|||
trackpoint_flat_filter(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct trackpoint_flat_accelerator *accel_filter =
|
||||
(struct trackpoint_flat_accelerator *)filter;
|
||||
|
|
@ -60,10 +60,10 @@ trackpoint_flat_filter(struct motion_filter *filter,
|
|||
}
|
||||
|
||||
static struct normalized_coords
|
||||
trackpoint_flat_filter_noop(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
trackpoint_flat_filter_constant(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
usec_t time)
|
||||
{
|
||||
/* We map the unaccelerated flat filter to have the same behavior as
|
||||
* the "accelerated" flat filter.
|
||||
|
|
@ -79,6 +79,27 @@ trackpoint_flat_filter_noop(struct motion_filter *filter,
|
|||
return trackpoint_flat_filter(filter, unaccelerated, data, time);
|
||||
}
|
||||
|
||||
static struct normalized_coords
|
||||
trackpoint_flat_filter_scroll(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
usec_t time,
|
||||
enum filter_scroll_type type)
|
||||
{
|
||||
/* Scroll wheels were not historically accelerated and have different
|
||||
* units than button scrolling. Maintain the status quo and do not
|
||||
* accelerate wheel events.
|
||||
*/
|
||||
if (type == FILTER_SCROLL_TYPE_WHEEL) {
|
||||
return (struct normalized_coords){
|
||||
.x = unaccelerated->x,
|
||||
.y = unaccelerated->y,
|
||||
};
|
||||
}
|
||||
|
||||
return trackpoint_flat_filter_constant(filter, unaccelerated, data, time);
|
||||
}
|
||||
|
||||
/* Maps the [-1, 1] speed setting into a constant acceleration
|
||||
* range. This isn't a linear scale, we keep 0 as the 'optimized'
|
||||
* mid-point and scale down to 0 for setting -1 and up to 5 for
|
||||
|
|
@ -128,8 +149,8 @@ trackpoint_flat_destroy(struct motion_filter *filter)
|
|||
static struct motion_filter_interface accelerator_interface_flat = {
|
||||
.type = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
|
||||
.filter = trackpoint_flat_filter,
|
||||
.filter_constant = trackpoint_flat_filter_noop,
|
||||
.filter_scroll = trackpoint_flat_filter_noop,
|
||||
.filter_constant = trackpoint_flat_filter_constant,
|
||||
.filter_scroll = trackpoint_flat_filter_scroll,
|
||||
.restart = NULL,
|
||||
.destroy = trackpoint_flat_destroy,
|
||||
.set_speed = trackpoint_flat_set_speed,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ double
|
|||
trackpoint_accel_profile(struct motion_filter *filter,
|
||||
void *data,
|
||||
double velocity,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct trackpoint_accelerator *accel_filter =
|
||||
(struct trackpoint_accelerator *)filter;
|
||||
|
|
@ -74,7 +74,7 @@ static struct normalized_coords
|
|||
trackpoint_accelerator_filter(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
struct trackpoint_accelerator *accel_filter =
|
||||
(struct trackpoint_accelerator *)filter;
|
||||
|
|
@ -97,10 +97,10 @@ trackpoint_accelerator_filter(struct motion_filter *filter,
|
|||
}
|
||||
|
||||
static struct normalized_coords
|
||||
trackpoint_accelerator_filter_noop(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
trackpoint_accelerator_filter_constant(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
usec_t time)
|
||||
{
|
||||
struct trackpoint_accelerator *accel_filter =
|
||||
(struct trackpoint_accelerator *)filter;
|
||||
|
|
@ -112,6 +112,30 @@ trackpoint_accelerator_filter_noop(struct motion_filter *filter,
|
|||
return coords;
|
||||
}
|
||||
|
||||
static struct normalized_coords
|
||||
trackpoint_accelerator_filter_scroll(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
usec_t time,
|
||||
enum filter_scroll_type type)
|
||||
{
|
||||
/* Scroll wheels were not historically accelerated and have different
|
||||
* units than button scrolling. Maintain the status quo and do not
|
||||
* accelerate wheel events.
|
||||
*/
|
||||
if (type == FILTER_SCROLL_TYPE_WHEEL) {
|
||||
return (struct normalized_coords){
|
||||
.x = unaccelerated->x,
|
||||
.y = unaccelerated->y,
|
||||
};
|
||||
}
|
||||
|
||||
return trackpoint_accelerator_filter_constant(filter,
|
||||
unaccelerated,
|
||||
data,
|
||||
time);
|
||||
}
|
||||
|
||||
/* Maps the [-1, 1] speed setting into a constant acceleration
|
||||
* range. This isn't a linear scale, we keep 0 as the 'optimized'
|
||||
* mid-point and scale down to 0 for setting -1 and up to 5 for
|
||||
|
|
@ -150,7 +174,7 @@ trackpoint_accelerator_set_speed(struct motion_filter *filter, double speed_adju
|
|||
}
|
||||
|
||||
static void
|
||||
trackpoint_accelerator_restart(struct motion_filter *filter, void *data, uint64_t time)
|
||||
trackpoint_accelerator_restart(struct motion_filter *filter, void *data, usec_t time)
|
||||
{
|
||||
struct trackpoint_accelerator *accel = (struct trackpoint_accelerator *)filter;
|
||||
|
||||
|
|
@ -170,8 +194,8 @@ trackpoint_accelerator_destroy(struct motion_filter *filter)
|
|||
static const struct motion_filter_interface accelerator_interface_trackpoint = {
|
||||
.type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
|
||||
.filter = trackpoint_accelerator_filter,
|
||||
.filter_constant = trackpoint_accelerator_filter_noop,
|
||||
.filter_scroll = trackpoint_accelerator_filter_noop,
|
||||
.filter_constant = trackpoint_accelerator_filter_constant,
|
||||
.filter_scroll = trackpoint_accelerator_filter_scroll,
|
||||
.restart = trackpoint_accelerator_restart,
|
||||
.destroy = trackpoint_accelerator_destroy,
|
||||
.set_speed = trackpoint_accelerator_set_speed,
|
||||
|
|
@ -207,7 +231,8 @@ create_pointer_accelerator_filter_trackpoint(double multiplier,
|
|||
|
||||
filter->base.interface = &accelerator_interface_trackpoint;
|
||||
filter->trackers.smoothener =
|
||||
pointer_delta_smoothener_create(ms2us(10), ms2us(10));
|
||||
pointer_delta_smoothener_create(usec_from_millis(10),
|
||||
usec_from_millis(10));
|
||||
|
||||
return &filter->base;
|
||||
}
|
||||
|
|
|
|||
45
src/filter.c
45
src/filter.c
|
|
@ -35,13 +35,13 @@
|
|||
#include "filter.h"
|
||||
#include "libinput-util.h"
|
||||
|
||||
#define MOTION_TIMEOUT ms2us(1000)
|
||||
#define MOTION_TIMEOUT usec_from_millis(1000)
|
||||
|
||||
struct normalized_coords
|
||||
filter_dispatch(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
return filter->interface->filter(filter, unaccelerated, data, time);
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ struct normalized_coords
|
|||
filter_dispatch_constant(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
return filter->interface->filter_constant(filter, unaccelerated, data, time);
|
||||
}
|
||||
|
|
@ -59,13 +59,18 @@ struct normalized_coords
|
|||
filter_dispatch_scroll(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time)
|
||||
usec_t time,
|
||||
enum filter_scroll_type type)
|
||||
{
|
||||
return filter->interface->filter_scroll(filter, unaccelerated, data, time);
|
||||
return filter->interface->filter_scroll(filter,
|
||||
unaccelerated,
|
||||
data,
|
||||
time,
|
||||
type);
|
||||
}
|
||||
|
||||
void
|
||||
filter_restart(struct motion_filter *filter, void *data, uint64_t time)
|
||||
filter_restart(struct motion_filter *filter, void *data, usec_t time)
|
||||
{
|
||||
if (filter->interface->restart)
|
||||
filter->interface->restart(filter, data, time);
|
||||
|
|
@ -127,14 +132,14 @@ trackers_free(struct pointer_trackers *trackers)
|
|||
}
|
||||
|
||||
void
|
||||
trackers_reset(struct pointer_trackers *trackers, uint64_t time)
|
||||
trackers_reset(struct pointer_trackers *trackers, usec_t time)
|
||||
{
|
||||
unsigned int offset;
|
||||
struct pointer_tracker *tracker;
|
||||
|
||||
for (offset = 1; offset < trackers->ntrackers; offset++) {
|
||||
tracker = trackers_by_offset(trackers, offset);
|
||||
tracker->time = 0;
|
||||
tracker->time = usec_from_uint64_t(0);
|
||||
tracker->dir = 0;
|
||||
tracker->delta.x = 0;
|
||||
tracker->delta.y = 0;
|
||||
|
|
@ -148,7 +153,7 @@ trackers_reset(struct pointer_trackers *trackers, uint64_t time)
|
|||
void
|
||||
trackers_feed(struct pointer_trackers *trackers,
|
||||
const struct device_float_coords *delta,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
unsigned int i, current;
|
||||
struct pointer_tracker *ts = trackers->trackers;
|
||||
|
|
@ -179,16 +184,17 @@ trackers_by_offset(struct pointer_trackers *trackers, unsigned int offset)
|
|||
|
||||
static double
|
||||
calculate_trackers_velocity(const struct pointer_tracker *tracker,
|
||||
uint64_t time,
|
||||
usec_t time,
|
||||
struct pointer_delta_smoothener *smoothener)
|
||||
{
|
||||
uint64_t tdelta = time - tracker->time + 1;
|
||||
usec_t tdelta = usec_delta(time, tracker->time);
|
||||
tdelta = usec_add(tdelta, usec_from_uint64_t(1));
|
||||
|
||||
if (smoothener && tdelta < smoothener->threshold)
|
||||
if (smoothener && usec_cmp(tdelta, smoothener->threshold) < 0)
|
||||
tdelta = smoothener->value;
|
||||
|
||||
return hypot(tracker->delta.x, tracker->delta.y) /
|
||||
(double)tdelta; /* units/us */
|
||||
(double)usec_as_uint64_t(tdelta); /* units/us */
|
||||
}
|
||||
|
||||
static double
|
||||
|
|
@ -207,7 +213,7 @@ trackers_velocity_after_timeout(const struct pointer_tracker *tracker,
|
|||
* movement in normal use-cases (pause, move, pause, move)
|
||||
*/
|
||||
return calculate_trackers_velocity(tracker,
|
||||
tracker->time + MOTION_TIMEOUT,
|
||||
usec_add(tracker->time, MOTION_TIMEOUT),
|
||||
smoothener);
|
||||
}
|
||||
|
||||
|
|
@ -219,9 +225,9 @@ trackers_velocity_after_timeout(const struct pointer_tracker *tracker,
|
|||
* change between events.
|
||||
*/
|
||||
double
|
||||
trackers_velocity(struct pointer_trackers *trackers, uint64_t time)
|
||||
trackers_velocity(struct pointer_trackers *trackers, usec_t time)
|
||||
{
|
||||
const double MAX_VELOCITY_DIFF = v_ms2us(1); /* units/us */
|
||||
const double MAX_VELOCITY_DIFF = v_usec_from_millis(1); /* units/us */
|
||||
double result = 0.0;
|
||||
double initial_velocity = 0.0;
|
||||
|
||||
|
|
@ -234,11 +240,12 @@ trackers_velocity(struct pointer_trackers *trackers, uint64_t time)
|
|||
trackers_by_offset(trackers, offset);
|
||||
|
||||
/* Bug: time running backwards */
|
||||
if (tracker->time > time)
|
||||
if (usec_cmp(tracker->time, time) > 0)
|
||||
break;
|
||||
|
||||
/* Stop if too far away in time */
|
||||
if (time - tracker->time > MOTION_TIMEOUT) {
|
||||
usec_t tdelta = usec_delta(time, tracker->time);
|
||||
if (usec_cmp(tdelta, MOTION_TIMEOUT) > 0) {
|
||||
if (offset == 1)
|
||||
result = trackers_velocity_after_timeout(
|
||||
tracker,
|
||||
|
|
@ -297,7 +304,7 @@ calculate_acceleration_simpsons(struct motion_filter *filter,
|
|||
void *data,
|
||||
double velocity,
|
||||
double last_velocity,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
double factor;
|
||||
|
||||
|
|
|
|||
38
src/filter.h
38
src/filter.h
|
|
@ -34,6 +34,12 @@
|
|||
|
||||
struct motion_filter;
|
||||
|
||||
enum filter_scroll_type {
|
||||
FILTER_SCROLL_TYPE_CONTINUOUS,
|
||||
FILTER_SCROLL_TYPE_WHEEL,
|
||||
FILTER_SCROLL_TYPE_FINGER,
|
||||
};
|
||||
|
||||
/**
|
||||
* Accelerate the given coordinates.
|
||||
* Takes a set of unaccelerated deltas and accelerates them based on the
|
||||
|
|
@ -60,7 +66,7 @@ struct normalized_coords
|
|||
filter_dispatch(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
|
||||
/**
|
||||
* Apply constant motion filters, but no acceleration.
|
||||
|
|
@ -82,7 +88,7 @@ struct normalized_coords
|
|||
filter_dispatch_constant(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
|
||||
/**
|
||||
* Apply a scroll filter.
|
||||
|
|
@ -98,6 +104,7 @@ filter_dispatch_constant(struct motion_filter *filter,
|
|||
* originally provided resolution.
|
||||
* @param data Custom data
|
||||
* @param time The time of the delta
|
||||
* @param type The type of scroll event
|
||||
*
|
||||
* @see filter_dispatch
|
||||
*/
|
||||
|
|
@ -105,10 +112,11 @@ struct normalized_coords
|
|||
filter_dispatch_scroll(struct motion_filter *filter,
|
||||
const struct device_float_coords *unaccelerated,
|
||||
void *data,
|
||||
uint64_t time);
|
||||
usec_t time,
|
||||
enum filter_scroll_type type);
|
||||
|
||||
void
|
||||
filter_restart(struct motion_filter *filter, void *data, uint64_t time);
|
||||
filter_restart(struct motion_filter *filter, void *data, usec_t time);
|
||||
|
||||
void
|
||||
filter_destroy(struct motion_filter *filter);
|
||||
|
|
@ -124,7 +132,7 @@ filter_get_type(struct motion_filter *filter);
|
|||
typedef double (*accel_profile_func_t)(struct motion_filter *filter,
|
||||
void *data,
|
||||
double velocity,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
|
||||
bool
|
||||
filter_set_accel_config(struct motion_filter *filter,
|
||||
|
|
@ -142,8 +150,8 @@ create_pointer_accelerator_filter_linear_low_dpi(int dpi, bool use_velocity_aver
|
|||
|
||||
struct motion_filter *
|
||||
create_pointer_accelerator_filter_touchpad(int dpi,
|
||||
uint64_t event_delta_smooth_threshold,
|
||||
uint64_t event_delta_smooth_value,
|
||||
usec_t event_delta_smooth_threshold,
|
||||
usec_t event_delta_smooth_value,
|
||||
bool use_velocity_averaging);
|
||||
|
||||
struct motion_filter *
|
||||
|
|
@ -173,40 +181,40 @@ double
|
|||
pointer_accel_profile_linear_low_dpi(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
double
|
||||
pointer_accel_profile_linear(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
double
|
||||
touchpad_accel_profile_linear(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
double
|
||||
touchpad_lenovo_x230_accel_profile(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
double
|
||||
trackpoint_accel_profile(struct motion_filter *filter,
|
||||
void *data,
|
||||
double velocity,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
double
|
||||
custom_accel_profile_fallback(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
double
|
||||
custom_accel_profile_motion(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
double
|
||||
custom_accel_profile_scroll(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in,
|
||||
uint64_t time);
|
||||
usec_t time);
|
||||
#endif /* FILTER_H */
|
||||
|
|
|
|||
34
src/libinput-feature.h
Normal file
34
src/libinput-feature.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright © 2025 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
|
||||
|
||||
enum libinput_feature {
|
||||
LIBINPUT_FEATURE_BUTTON_DEBOUNCING = 1,
|
||||
LIBINPUT_FEATURE_WHEEL_DEBOUNCING,
|
||||
LIBINPUT_FEATURE_TOUCHPAD_JUMP_DETECTION,
|
||||
LIBINPUT_FEATURE_TOUCHPAD_HYSTERESIS,
|
||||
LIBINPUT_FEATURE_TOUCHPAD_PALM_DETECTION,
|
||||
|
||||
_LIBINPUT_N_FEATURES
|
||||
};
|
||||
|
|
@ -30,9 +30,11 @@
|
|||
#include "util-strings.h"
|
||||
|
||||
#include "evdev-frame.h"
|
||||
#include "libinput-feature.h"
|
||||
#include "libinput-log.h"
|
||||
#include "libinput-plugin-button-debounce.h"
|
||||
#include "libinput-plugin.h"
|
||||
#include "libinput-private.h"
|
||||
#include "libinput-util.h"
|
||||
#include "quirks.h"
|
||||
#include "timer.h"
|
||||
|
|
@ -134,10 +136,12 @@ struct plugin_device {
|
|||
struct plugin_data *parent;
|
||||
|
||||
evdev_usage_t button_usage;
|
||||
uint64_t button_time;
|
||||
usec_t button_time;
|
||||
enum debounce_state state;
|
||||
bool spurious_enabled;
|
||||
|
||||
bool want_feature_disabled;
|
||||
|
||||
struct libinput_plugin_timer *timer;
|
||||
struct libinput_plugin_timer *timer_short;
|
||||
};
|
||||
|
|
@ -175,7 +179,6 @@ plugin_data_destroy(void *d)
|
|||
free(data);
|
||||
}
|
||||
|
||||
DEFINE_DESTROY_CLEANUP_FUNC(plugin_data);
|
||||
static void
|
||||
plugin_destroy(struct libinput_plugin *libinput_plugin)
|
||||
{
|
||||
|
|
@ -192,6 +195,23 @@ log_debounce_bug(struct plugin_device *device, enum debounce_event event)
|
|||
debounce_state_to_str(device->state));
|
||||
}
|
||||
|
||||
static inline void
|
||||
debounce_maybe_disable(struct plugin_device *device)
|
||||
{
|
||||
if (device->state != DEBOUNCE_STATE_IS_UP)
|
||||
return;
|
||||
|
||||
if (device->want_feature_disabled) {
|
||||
plugin_log_debug(device->parent->plugin,
|
||||
"%s: disabled button debouncing on request\n",
|
||||
libinput_device_get_name(device->device));
|
||||
device->state = DEBOUNCE_STATE_DISABLED;
|
||||
libinput_plugin_enable_device_event_frame(device->parent->plugin,
|
||||
device->device,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
debounce_set_state(struct plugin_device *device, enum debounce_state new_state)
|
||||
{
|
||||
|
|
@ -202,20 +222,21 @@ debounce_set_state(struct plugin_device *device, enum debounce_state new_state)
|
|||
}
|
||||
|
||||
static inline void
|
||||
debounce_set_timer(struct plugin_device *device, uint64_t time)
|
||||
debounce_set_timer(struct plugin_device *device, usec_t time)
|
||||
{
|
||||
const int DEBOUNCE_TIMEOUT_BOUNCE = ms2us(25);
|
||||
const usec_t DEBOUNCE_TIMEOUT_BOUNCE = usec_from_millis(25);
|
||||
|
||||
libinput_plugin_timer_set(device->timer, time + DEBOUNCE_TIMEOUT_BOUNCE);
|
||||
libinput_plugin_timer_set(device->timer,
|
||||
usec_add(time, DEBOUNCE_TIMEOUT_BOUNCE));
|
||||
}
|
||||
|
||||
static inline void
|
||||
debounce_set_timer_short(struct plugin_device *device, uint64_t time)
|
||||
debounce_set_timer_short(struct plugin_device *device, usec_t time)
|
||||
{
|
||||
const int DEBOUNCE_TIMEOUT_SPURIOUS = ms2us(12);
|
||||
const usec_t DEBOUNCE_TIMEOUT_SPURIOUS = usec_from_millis(12);
|
||||
|
||||
libinput_plugin_timer_set(device->timer_short,
|
||||
time + DEBOUNCE_TIMEOUT_SPURIOUS);
|
||||
usec_add(time, DEBOUNCE_TIMEOUT_SPURIOUS));
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
@ -264,13 +285,18 @@ debounce_notify_button(struct plugin_device *device,
|
|||
libinput_plugin_prepend_evdev_frame(device->parent->plugin,
|
||||
device->device,
|
||||
frame);
|
||||
|
||||
/* If we used the original frame, reset it to avoid re-sending any
|
||||
* non-button events that may be present in this frame */
|
||||
if (button_frame == NULL)
|
||||
evdev_frame_reset(frame);
|
||||
}
|
||||
|
||||
static void
|
||||
debounce_is_up_handle_event(struct plugin_device *device,
|
||||
enum debounce_event event,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case DEBOUNCE_EVENT_PRESS:
|
||||
|
|
@ -293,7 +319,7 @@ static void
|
|||
debounce_is_down_handle_event(struct plugin_device *device,
|
||||
enum debounce_event event,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case DEBOUNCE_EVENT_PRESS:
|
||||
|
|
@ -329,7 +355,7 @@ static void
|
|||
debounce_is_down_waiting_handle_event(struct plugin_device *device,
|
||||
enum debounce_event event,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case DEBOUNCE_EVENT_PRESS:
|
||||
|
|
@ -358,7 +384,7 @@ static void
|
|||
debounce_is_up_delaying_handle_event(struct plugin_device *device,
|
||||
enum debounce_event event,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case DEBOUNCE_EVENT_PRESS:
|
||||
|
|
@ -372,6 +398,7 @@ debounce_is_up_delaying_handle_event(struct plugin_device *device,
|
|||
case DEBOUNCE_EVENT_TIMEOUT:
|
||||
case DEBOUNCE_EVENT_OTHERBUTTON:
|
||||
debounce_set_state(device, DEBOUNCE_STATE_IS_UP);
|
||||
debounce_maybe_disable(device);
|
||||
debounce_notify_button(device, frame, LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
break;
|
||||
}
|
||||
|
|
@ -381,7 +408,7 @@ static void
|
|||
debounce_is_up_delaying_spurious_handle_event(struct plugin_device *device,
|
||||
enum debounce_event event,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case DEBOUNCE_EVENT_PRESS:
|
||||
|
|
@ -399,6 +426,7 @@ debounce_is_up_delaying_spurious_handle_event(struct plugin_device *device,
|
|||
break;
|
||||
case DEBOUNCE_EVENT_OTHERBUTTON:
|
||||
debounce_set_state(device, DEBOUNCE_STATE_IS_UP);
|
||||
debounce_maybe_disable(device);
|
||||
debounce_notify_button(device, frame, LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
break;
|
||||
}
|
||||
|
|
@ -408,7 +436,7 @@ static void
|
|||
debounce_is_up_detecting_spurious_handle_event(struct plugin_device *device,
|
||||
enum debounce_event event,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case DEBOUNCE_EVENT_PRESS:
|
||||
|
|
@ -424,12 +452,14 @@ debounce_is_up_detecting_spurious_handle_event(struct plugin_device *device,
|
|||
break;
|
||||
case DEBOUNCE_EVENT_TIMEOUT:
|
||||
debounce_set_state(device, DEBOUNCE_STATE_IS_UP);
|
||||
debounce_maybe_disable(device);
|
||||
break;
|
||||
case DEBOUNCE_EVENT_TIMEOUT_SHORT:
|
||||
debounce_set_state(device, DEBOUNCE_STATE_IS_UP_WAITING);
|
||||
break;
|
||||
case DEBOUNCE_EVENT_OTHERBUTTON:
|
||||
debounce_set_state(device, DEBOUNCE_STATE_IS_UP);
|
||||
debounce_maybe_disable(device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -438,7 +468,7 @@ static void
|
|||
debounce_is_down_detecting_spurious_handle_event(struct plugin_device *device,
|
||||
enum debounce_event event,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case DEBOUNCE_EVENT_PRESS:
|
||||
|
|
@ -467,7 +497,7 @@ static void
|
|||
debounce_is_up_waiting_handle_event(struct plugin_device *device,
|
||||
enum debounce_event event,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case DEBOUNCE_EVENT_PRESS:
|
||||
|
|
@ -484,6 +514,7 @@ debounce_is_up_waiting_handle_event(struct plugin_device *device,
|
|||
case DEBOUNCE_EVENT_TIMEOUT:
|
||||
case DEBOUNCE_EVENT_OTHERBUTTON:
|
||||
debounce_set_state(device, DEBOUNCE_STATE_IS_UP);
|
||||
debounce_maybe_disable(device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -492,7 +523,7 @@ static void
|
|||
debounce_is_down_delaying_handle_event(struct plugin_device *device,
|
||||
enum debounce_event event,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case DEBOUNCE_EVENT_PRESS:
|
||||
|
|
@ -517,7 +548,7 @@ static void
|
|||
debounce_disabled_handle_event(struct plugin_device *device,
|
||||
enum debounce_event event,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case DEBOUNCE_EVENT_PRESS:
|
||||
|
|
@ -541,7 +572,7 @@ static void
|
|||
debounce_handle_event(struct plugin_device *device,
|
||||
enum debounce_event event,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
enum debounce_state current = device->state;
|
||||
|
||||
|
|
@ -602,7 +633,7 @@ debounce_handle_event(struct plugin_device *device,
|
|||
static void
|
||||
debounce_plugin_handle_frame(struct plugin_device *device,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
size_t nchanged = 0;
|
||||
bool flushed = false;
|
||||
|
|
@ -661,6 +692,7 @@ debounce_plugin_handle_frame(struct plugin_device *device,
|
|||
!is_down ? DEBOUNCE_STATE_IS_DOWN
|
||||
: DEBOUNCE_STATE_IS_UP);
|
||||
flushed = false;
|
||||
debounce_maybe_disable(device);
|
||||
}
|
||||
|
||||
device->button_usage = e->usage;
|
||||
|
|
@ -703,7 +735,7 @@ debounce_plugin_evdev_frame(struct libinput_plugin *libinput_plugin,
|
|||
}
|
||||
|
||||
static void
|
||||
debounce_timeout(struct libinput_plugin *plugin, uint64_t now, void *data)
|
||||
debounce_timeout(struct libinput_plugin *plugin, usec_t now, void *data)
|
||||
{
|
||||
struct plugin_device *device = data;
|
||||
|
||||
|
|
@ -711,7 +743,7 @@ debounce_timeout(struct libinput_plugin *plugin, uint64_t now, void *data)
|
|||
}
|
||||
|
||||
static void
|
||||
debounce_timeout_short(struct libinput_plugin *plugin, uint64_t now, void *data)
|
||||
debounce_timeout_short(struct libinput_plugin *plugin, usec_t now, void *data)
|
||||
{
|
||||
struct plugin_device *device = data;
|
||||
|
||||
|
|
@ -725,6 +757,9 @@ debounce_plugin_device_added(struct libinput_plugin *libinput_plugin,
|
|||
if (!libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER))
|
||||
return;
|
||||
|
||||
if (libinput_device_is_virtual(device))
|
||||
return;
|
||||
|
||||
_unref_(udev_device) *udev_device = libinput_device_get_udev_device(device);
|
||||
if (udev_device) {
|
||||
const char *prop = udev_device_get_property_value(udev_device,
|
||||
|
|
@ -743,6 +778,15 @@ debounce_plugin_device_added(struct libinput_plugin *libinput_plugin,
|
|||
|
||||
libinput_plugin_enable_device_event_frame(libinput_plugin, device, true);
|
||||
|
||||
/* We don't care about BTN_TRIGGER_HAPPY_* */
|
||||
for (unsigned int code = BTN_0; code <= KEY_OK; code++) {
|
||||
evdev_usage_t usage = evdev_usage_from_code(EV_KEY, code);
|
||||
if (evdev_usage_is_button(usage)) {
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin,
|
||||
evdev_usage_enum(usage));
|
||||
}
|
||||
}
|
||||
|
||||
struct plugin_data *plugin = libinput_plugin_get_user_data(libinput_plugin);
|
||||
struct plugin_device *pd = zalloc(sizeof(*pd));
|
||||
pd->device = libinput_device_ref(device);
|
||||
|
|
@ -779,6 +823,24 @@ debounce_plugin_device_removed(struct libinput_plugin *libinput_plugin,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
debounce_plugin_feature_disabled(struct libinput_plugin *libinput_plugin,
|
||||
struct libinput_device *device,
|
||||
enum libinput_feature feature)
|
||||
{
|
||||
if (feature != LIBINPUT_FEATURE_BUTTON_DEBOUNCING)
|
||||
return;
|
||||
|
||||
struct plugin_data *plugin = libinput_plugin_get_user_data(libinput_plugin);
|
||||
struct plugin_device *pd;
|
||||
list_for_each(pd, &plugin->devices, link) {
|
||||
if (pd->device == device) {
|
||||
pd->want_feature_disabled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct libinput_plugin_interface interface = {
|
||||
.run = NULL,
|
||||
.destroy = plugin_destroy,
|
||||
|
|
@ -787,6 +849,7 @@ static const struct libinput_plugin_interface interface = {
|
|||
.device_added = debounce_plugin_device_added,
|
||||
.device_removed = debounce_plugin_device_removed,
|
||||
.evdev_frame = debounce_plugin_evdev_frame,
|
||||
.feature_disabled = debounce_plugin_feature_disabled,
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
|||
1360
src/libinput-plugin-lua.c
Normal file
1360
src/libinput-plugin-lua.c
Normal file
File diff suppressed because it is too large
Load diff
32
src/libinput-plugin-lua.h
Normal file
32
src/libinput-plugin-lua.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright © 2025 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"
|
||||
|
||||
#include "libinput-plugin.h"
|
||||
#include "libinput.h"
|
||||
|
||||
struct libinput_plugin *
|
||||
libinput_lua_plugin_new_from_path(struct libinput *libinput, const char *path);
|
||||
123
src/libinput-plugin-mouse-wheel-lowres.c
Normal file
123
src/libinput-plugin-mouse-wheel-lowres.c
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright © 2025 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 <libevdev/libevdev.h>
|
||||
|
||||
#include "evdev.h"
|
||||
#include "libinput-plugin-mouse-wheel-lowres.h"
|
||||
#include "libinput-plugin.h"
|
||||
#include "src/evdev-frame.h"
|
||||
|
||||
static void
|
||||
wheel_plugin_device_new(struct libinput_plugin *libinput_plugin,
|
||||
struct libinput_device *device,
|
||||
struct libevdev *libevdev,
|
||||
struct udev_device *udev_device)
|
||||
{
|
||||
struct evdev_device *evdev = evdev_device(device);
|
||||
|
||||
if (libevdev_has_event_code(libevdev, EV_REL, REL_WHEEL_HI_RES) ||
|
||||
libevdev_has_event_code(libevdev, EV_REL, REL_HWHEEL_HI_RES))
|
||||
return;
|
||||
|
||||
if (libevdev_has_event_code(libevdev, EV_REL, REL_WHEEL) ||
|
||||
libevdev_has_event_code(libevdev, EV_REL, REL_HWHEEL))
|
||||
evdev_log_info(evdev,
|
||||
"emulating high-resolution scroll wheel events.\n");
|
||||
|
||||
if (libevdev_has_event_code(libevdev, EV_REL, REL_WHEEL))
|
||||
libevdev_enable_event_code(libevdev, EV_REL, REL_WHEEL_HI_RES, NULL);
|
||||
|
||||
if (libevdev_has_event_code(libevdev, EV_REL, REL_HWHEEL))
|
||||
libevdev_enable_event_code(libevdev, EV_REL, REL_HWHEEL_HI_RES, NULL);
|
||||
|
||||
libinput_plugin_enable_device_event_frame(libinput_plugin, device, true);
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_REL_WHEEL);
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_REL_HWHEEL);
|
||||
|
||||
/* A device may have those disabled via a quirk but we just re-enabled it
|
||||
* above. Make sure we get those events too to filter them out */
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_REL_WHEEL_HI_RES);
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_REL_HWHEEL_HI_RES);
|
||||
}
|
||||
|
||||
static void
|
||||
wheel_plugin_evdev_frame(struct libinput_plugin *libinput_plugin,
|
||||
struct libinput_device *device,
|
||||
struct evdev_frame *frame)
|
||||
{
|
||||
size_t nevents;
|
||||
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
|
||||
|
||||
_unref_(evdev_frame) *filtered_frame = evdev_frame_new(nevents + 2);
|
||||
for (size_t i = 0; i < nevents; i++) {
|
||||
struct evdev_event *e = &events[i];
|
||||
|
||||
switch (evdev_usage_enum(e->usage)) {
|
||||
case EVDEV_REL_WHEEL_HI_RES:
|
||||
case EVDEV_REL_HWHEEL_HI_RES:
|
||||
/* In the uncommon case that our device sends high-res events
|
||||
* filter those out. This can happen on devices that have the
|
||||
* highres scroll axes disabled via quirks. The device still
|
||||
* sends events so when we re-enable the axis in
|
||||
* wheel_plugin_device_new we get the device events again,
|
||||
* effectively duplicating the high resolution scroll events.
|
||||
*/
|
||||
break;
|
||||
case EVDEV_REL_WHEEL:
|
||||
evdev_frame_append(filtered_frame, e, 1);
|
||||
evdev_frame_append_one(filtered_frame,
|
||||
evdev_usage_from(EVDEV_REL_WHEEL_HI_RES),
|
||||
e->value * 120);
|
||||
break;
|
||||
case EVDEV_REL_HWHEEL:
|
||||
evdev_frame_append(filtered_frame, e, 1);
|
||||
evdev_frame_append_one(
|
||||
filtered_frame,
|
||||
evdev_usage_from(EVDEV_REL_HWHEEL_HI_RES),
|
||||
e->value * 120);
|
||||
break;
|
||||
default:
|
||||
evdev_frame_append(filtered_frame, e, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
evdev_frame_set(frame,
|
||||
evdev_frame_get_events(filtered_frame, NULL),
|
||||
evdev_frame_get_count(filtered_frame));
|
||||
}
|
||||
|
||||
static const struct libinput_plugin_interface interface = {
|
||||
.device_new = wheel_plugin_device_new,
|
||||
.evdev_frame = wheel_plugin_evdev_frame,
|
||||
};
|
||||
|
||||
void
|
||||
libinput_mouse_plugin_wheel_lowres(struct libinput *libinput)
|
||||
{
|
||||
_unref_(libinput_plugin) *p =
|
||||
libinput_plugin_new(libinput, "mouse-wheel-lowres", &interface, NULL);
|
||||
}
|
||||
30
src/libinput-plugin-mouse-wheel-lowres.h
Normal file
30
src/libinput-plugin-mouse-wheel-lowres.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright © 2025 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 "libinput-plugin.h"
|
||||
#include "libinput.h"
|
||||
|
||||
void
|
||||
libinput_mouse_plugin_wheel_lowres(struct libinput *libinput);
|
||||
|
|
@ -31,14 +31,16 @@
|
|||
|
||||
#include "evdev-fallback.h"
|
||||
#include "evdev.h"
|
||||
#include "libinput-feature.h"
|
||||
#include "libinput-log.h"
|
||||
#include "libinput-plugin-mouse-wheel.h"
|
||||
#include "libinput-plugin.h"
|
||||
#include "libinput-private.h"
|
||||
#include "libinput-util.h"
|
||||
|
||||
#define ACC_V120_TRIGGER_THRESHOLD 30 /* 1/4 of a wheel detent */
|
||||
#define ACC_V120_THRESHOLD 59
|
||||
#define WHEEL_SCROLL_TIMEOUT ms2us(500)
|
||||
#define ACC_V120_THRESHOLD 47 /* Good for both high-ish multipliers (8/120) and the rest of the mice (30/120, 40/120, etc) */
|
||||
const usec_t WHEEL_SCROLL_TIMEOUT = { 500 * 1000 };
|
||||
|
||||
enum wheel_state {
|
||||
WHEEL_STATE_NONE,
|
||||
|
|
@ -62,8 +64,7 @@ enum wheel_event {
|
|||
};
|
||||
|
||||
enum ignore_strategy {
|
||||
MAYBE, /* use heuristics but don't yet accumulate */
|
||||
PASSTHROUGH, /* do not accumulate, pass through */
|
||||
MAYBE = 1, /* use heuristics but don't yet accumulate */
|
||||
ACCUMULATE, /* accumulate scroll wheel events */
|
||||
ALWAYS_ACCUMULATE, /* always accumulate wheel events */
|
||||
};
|
||||
|
|
@ -83,6 +84,8 @@ struct plugin_device {
|
|||
int min_movement;
|
||||
|
||||
struct ratelimit hires_warning_limit;
|
||||
|
||||
bool want_feature_disabled;
|
||||
};
|
||||
|
||||
struct plugin_data {
|
||||
|
|
@ -123,12 +126,13 @@ log_wheel_bug(struct plugin_device *pd, enum wheel_event event)
|
|||
}
|
||||
|
||||
static inline void
|
||||
wheel_set_scroll_timer(struct plugin_device *pd, uint64_t time)
|
||||
wheel_set_scroll_timer(struct plugin_device *pd, usec_t time)
|
||||
{
|
||||
if (!pd->scroll_timer)
|
||||
return;
|
||||
|
||||
libinput_plugin_timer_set(pd->scroll_timer, time + WHEEL_SCROLL_TIMEOUT);
|
||||
libinput_plugin_timer_set(pd->scroll_timer,
|
||||
usec_add(time, WHEEL_SCROLL_TIMEOUT));
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
@ -140,10 +144,29 @@ wheel_cancel_scroll_timer(struct plugin_device *pd)
|
|||
libinput_plugin_timer_cancel(pd->scroll_timer);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wheel_maybe_disable(struct plugin_device *device)
|
||||
{
|
||||
if (device->state != WHEEL_STATE_NONE)
|
||||
return;
|
||||
|
||||
if (device->want_feature_disabled) {
|
||||
plugin_log_debug(device->parent->plugin,
|
||||
"%s: disabled wheel debouncing on request\n",
|
||||
libinput_device_get_name(device->device));
|
||||
libinput_plugin_enable_device_event_frame(device->parent->plugin,
|
||||
device->device,
|
||||
false);
|
||||
libinput_plugin_timer_cancel(device->scroll_timer);
|
||||
device->scroll_timer =
|
||||
libinput_plugin_timer_unref(device->scroll_timer);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wheel_handle_event_on_state_none(struct plugin_device *pd,
|
||||
enum wheel_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case WHEEL_EVENT_SCROLL:
|
||||
|
|
@ -152,7 +175,6 @@ wheel_handle_event_on_state_none(struct plugin_device *pd,
|
|||
case ALWAYS_ACCUMULATE:
|
||||
pd->state = WHEEL_STATE_ACCUMULATING_SCROLL;
|
||||
break;
|
||||
case PASSTHROUGH:
|
||||
case MAYBE:
|
||||
pd->state = WHEEL_STATE_SCROLLING;
|
||||
break;
|
||||
|
|
@ -170,7 +192,7 @@ wheel_handle_event_on_state_none(struct plugin_device *pd,
|
|||
static void
|
||||
wheel_handle_event_on_state_accumulating_scroll(struct plugin_device *pd,
|
||||
enum wheel_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case WHEEL_EVENT_SCROLL_ACCUMULATED:
|
||||
|
|
@ -192,7 +214,7 @@ wheel_handle_event_on_state_accumulating_scroll(struct plugin_device *pd,
|
|||
static void
|
||||
wheel_handle_event_on_state_scrolling(struct plugin_device *pd,
|
||||
enum wheel_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case WHEEL_EVENT_SCROLL:
|
||||
|
|
@ -212,7 +234,7 @@ wheel_handle_event_on_state_scrolling(struct plugin_device *pd,
|
|||
}
|
||||
|
||||
static void
|
||||
wheel_handle_event(struct plugin_device *pd, enum wheel_event event, uint64_t time)
|
||||
wheel_handle_event(struct plugin_device *pd, enum wheel_event event, usec_t time)
|
||||
{
|
||||
enum wheel_state oldstate = pd->state;
|
||||
|
||||
|
|
@ -298,14 +320,14 @@ wheel_queue_scroll_events(struct plugin_device *pd, struct evdev_frame *frame)
|
|||
static void
|
||||
wheel_handle_state_none(struct plugin_device *pd,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
wheel_handle_state_accumulating_scroll(struct plugin_device *pd,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
wheel_remove_scroll_events(frame);
|
||||
|
||||
|
|
@ -319,7 +341,7 @@ wheel_handle_state_accumulating_scroll(struct plugin_device *pd,
|
|||
static void
|
||||
wheel_handle_state_scrolling(struct plugin_device *pd,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
wheel_remove_scroll_events(frame);
|
||||
wheel_queue_scroll_events(pd, frame);
|
||||
|
|
@ -328,7 +350,7 @@ wheel_handle_state_scrolling(struct plugin_device *pd,
|
|||
static void
|
||||
wheel_handle_direction_change(struct plugin_device *pd,
|
||||
struct evdev_event *e,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
enum wheel_direction new_dir = WHEEL_DIR_UNKNOW;
|
||||
|
||||
|
|
@ -365,7 +387,7 @@ wheel_update_strategy(struct plugin_device *pd, int32_t value)
|
|||
}
|
||||
|
||||
static void
|
||||
wheel_process_relative(struct plugin_device *pd, struct evdev_event *e, uint64_t time)
|
||||
wheel_process_relative(struct plugin_device *pd, struct evdev_event *e, usec_t time)
|
||||
{
|
||||
switch (evdev_usage_enum(e->usage)) {
|
||||
case EVDEV_REL_WHEEL:
|
||||
|
|
@ -396,7 +418,7 @@ wheel_process_relative(struct plugin_device *pd, struct evdev_event *e, uint64_t
|
|||
}
|
||||
|
||||
static void
|
||||
wheel_handle_state(struct plugin_device *pd, struct evdev_frame *frame, uint64_t time)
|
||||
wheel_handle_state(struct plugin_device *pd, struct evdev_frame *frame, usec_t time)
|
||||
{
|
||||
struct evdev_device *evdev = evdev_device(pd->device);
|
||||
|
||||
|
|
@ -422,10 +444,12 @@ wheel_handle_state(struct plugin_device *pd, struct evdev_frame *frame, uint64_t
|
|||
wheel_handle_state_scrolling(pd, frame, time);
|
||||
break;
|
||||
}
|
||||
|
||||
wheel_maybe_disable(pd);
|
||||
}
|
||||
|
||||
static void
|
||||
wheel_on_scroll_timer_timeout(struct libinput_plugin *plugin, uint64_t now, void *data)
|
||||
wheel_on_scroll_timer_timeout(struct libinput_plugin *plugin, usec_t now, void *data)
|
||||
{
|
||||
struct plugin_device *pd = data;
|
||||
|
||||
|
|
@ -437,32 +461,27 @@ wheel_plugin_device_create(struct libinput_plugin *libinput_plugin,
|
|||
struct plugin_data *plugin,
|
||||
struct libinput_device *device)
|
||||
{
|
||||
struct evdev_device *evdev = evdev_device(device);
|
||||
struct plugin_device *pd = zalloc(sizeof(*pd));
|
||||
if (libinput_device_is_virtual(device))
|
||||
return NULL;
|
||||
|
||||
struct plugin_device *pd = zalloc(sizeof(*pd));
|
||||
pd->parent = plugin;
|
||||
pd->device = libinput_device_ref(device);
|
||||
pd->state = WHEEL_STATE_NONE;
|
||||
pd->dir = WHEEL_DIR_UNKNOW;
|
||||
pd->min_movement = ACC_V120_THRESHOLD;
|
||||
ratelimit_init(&pd->hires_warning_limit, s2us(24 * 60 * 60), 1);
|
||||
ratelimit_init(&pd->hires_warning_limit, usec_from_hours(24), 1);
|
||||
|
||||
if (evdev_device_is_virtual(evdev))
|
||||
pd->ignore_small_hi_res_movements = PASSTHROUGH;
|
||||
else if (libinput_device_has_model_quirk(device,
|
||||
QUIRK_MODEL_LOGITECH_MX_MASTER_3))
|
||||
if (libinput_device_has_model_quirk(device, QUIRK_MODEL_SCROLL_ON_MIDDLE_CLICK))
|
||||
pd->ignore_small_hi_res_movements = ALWAYS_ACCUMULATE;
|
||||
else
|
||||
pd->ignore_small_hi_res_movements = MAYBE;
|
||||
|
||||
if (pd->ignore_small_hi_res_movements != PASSTHROUGH) {
|
||||
pd->scroll_timer =
|
||||
libinput_plugin_timer_new(libinput_plugin,
|
||||
libinput_device_get_sysname(device),
|
||||
wheel_on_scroll_timer_timeout,
|
||||
pd);
|
||||
}
|
||||
|
||||
pd->scroll_timer =
|
||||
libinput_plugin_timer_new(libinput_plugin,
|
||||
libinput_device_get_sysname(device),
|
||||
wheel_on_scroll_timer_timeout,
|
||||
pd);
|
||||
return pd;
|
||||
}
|
||||
|
||||
|
|
@ -504,12 +523,20 @@ wheel_plugin_device_new(struct libinput_plugin *libinput_plugin,
|
|||
!libevdev_has_event_code(libevdev, EV_REL, REL_HWHEEL_HI_RES))
|
||||
return;
|
||||
|
||||
libinput_plugin_enable_device_event_frame(libinput_plugin, device, true);
|
||||
|
||||
struct plugin_data *plugin = libinput_plugin_get_user_data(libinput_plugin);
|
||||
struct plugin_device *pd =
|
||||
wheel_plugin_device_create(libinput_plugin, plugin, device);
|
||||
if (!pd)
|
||||
return;
|
||||
|
||||
list_take_append(&plugin->devices, pd, link);
|
||||
|
||||
libinput_plugin_enable_device_event_frame(libinput_plugin, device, true);
|
||||
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_REL_WHEEL);
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_REL_WHEEL_HI_RES);
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_REL_HWHEEL);
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_REL_HWHEEL_HI_RES);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -549,7 +576,7 @@ wheel_plugin_device_removed(struct libinput_plugin *libinput_plugin,
|
|||
}
|
||||
|
||||
static void
|
||||
wheel_handle_frame(struct plugin_device *pd, struct evdev_frame *frame, uint64_t time)
|
||||
wheel_handle_frame(struct plugin_device *pd, struct evdev_frame *frame, usec_t time)
|
||||
{
|
||||
size_t nevents;
|
||||
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
|
||||
|
|
@ -576,7 +603,7 @@ wheel_plugin_evdev_frame(struct libinput_plugin *libinput_plugin,
|
|||
{
|
||||
struct plugin_data *plugin = libinput_plugin_get_user_data(libinput_plugin);
|
||||
struct plugin_device *pd;
|
||||
uint64_t time = evdev_frame_get_time(frame);
|
||||
usec_t time = evdev_frame_get_time(frame);
|
||||
|
||||
list_for_each(pd, &plugin->devices, link) {
|
||||
if (pd->device == device) {
|
||||
|
|
@ -586,6 +613,24 @@ wheel_plugin_evdev_frame(struct libinput_plugin *libinput_plugin,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wheel_plugin_feature_disabled(struct libinput_plugin *libinput_plugin,
|
||||
struct libinput_device *device,
|
||||
enum libinput_feature feature)
|
||||
{
|
||||
if (feature != LIBINPUT_FEATURE_WHEEL_DEBOUNCING)
|
||||
return;
|
||||
|
||||
struct plugin_data *plugin = libinput_plugin_get_user_data(libinput_plugin);
|
||||
struct plugin_device *pd;
|
||||
list_for_each(pd, &plugin->devices, link) {
|
||||
if (pd->device == device) {
|
||||
pd->want_feature_disabled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct libinput_plugin_interface interface = {
|
||||
.run = NULL,
|
||||
.destroy = wheel_plugin_destroy,
|
||||
|
|
@ -594,6 +639,7 @@ static const struct libinput_plugin_interface interface = {
|
|||
.device_added = wheel_plugin_device_added,
|
||||
.device_removed = wheel_plugin_device_removed,
|
||||
.evdev_frame = wheel_plugin_evdev_frame,
|
||||
.feature_disabled = wheel_plugin_feature_disabled,
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ mtdev_plugin_device_handle_frame(struct libinput_plugin *libinput_plugin,
|
|||
struct plugin_device *device,
|
||||
struct evdev_frame *frame)
|
||||
{
|
||||
uint64_t time = evdev_frame_get_time(frame);
|
||||
usec_t time = evdev_frame_get_time(frame);
|
||||
size_t nevents;
|
||||
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
|
||||
for (size_t i = 0; i < nevents; i++) {
|
||||
|
|
|
|||
|
|
@ -47,8 +47,3 @@ libinput_plugin_notify_device_ignored(struct libinput_plugin *plugin,
|
|||
void
|
||||
libinput_plugin_notify_device_removed(struct libinput_plugin *plugin,
|
||||
struct libinput_device *device);
|
||||
|
||||
void
|
||||
libinput_plugin_notify_evdev_frame(struct libinput_plugin *plugin,
|
||||
struct libinput_device *device,
|
||||
struct evdev_frame *frame);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "evdev-frame.h"
|
||||
#include "libinput.h"
|
||||
|
||||
enum libinput_feature;
|
||||
struct libinput;
|
||||
struct libinput_plugin;
|
||||
|
||||
|
|
@ -41,6 +42,7 @@ struct libinput_plugin_system {
|
|||
char **directories; /* NULL once loaded == true */
|
||||
|
||||
bool loaded;
|
||||
bool autoload;
|
||||
|
||||
struct list plugins;
|
||||
struct list removed_plugins;
|
||||
|
|
@ -52,8 +54,7 @@ void
|
|||
libinput_plugin_system_init(struct libinput_plugin_system *system);
|
||||
|
||||
void
|
||||
libinput_plugin_system_load_internal_plugins(struct libinput *libinput,
|
||||
struct libinput_plugin_system *system);
|
||||
libinput_plugin_system_autoload(struct libinput *libinput);
|
||||
|
||||
void
|
||||
libinput_plugin_system_destroy(struct libinput_plugin_system *system);
|
||||
|
|
@ -95,3 +96,9 @@ void
|
|||
libinput_plugin_system_notify_evdev_frame(struct libinput_plugin_system *system,
|
||||
struct libinput_device *device,
|
||||
struct evdev_frame *frame);
|
||||
|
||||
void
|
||||
libinput_plugin_system_notify_device_feature_disabled(
|
||||
struct libinput_plugin_system *system,
|
||||
struct libinput_device *device,
|
||||
enum libinput_feature feature);
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ double_tool_plugin_device_handle_frame(struct libinput_plugin *libinput_plugin,
|
|||
bool eraser_toggled = eraser_toggle != NULL;
|
||||
bool pen_toggled = pen_toggle != NULL;
|
||||
|
||||
#if EVENT_DEBUGGING
|
||||
#ifdef EVENT_DEBUGGING
|
||||
plugin_log_debug(libinput_plugin,
|
||||
"device %s: tool state: pen:%s eraser:%s\n",
|
||||
libinput_device_get_name(device->device),
|
||||
|
|
@ -217,6 +217,9 @@ double_tool_plugin_device_handle_frame(struct libinput_plugin *libinput_plugin,
|
|||
libinput_plugin,
|
||||
"device %s: device is fine, unregistering device\n",
|
||||
libinput_device_get_name(device->device));
|
||||
libinput_plugin_enable_device_event_frame(libinput_plugin,
|
||||
device->device,
|
||||
false);
|
||||
plugin_device_destroy(device);
|
||||
return;
|
||||
}
|
||||
|
|
@ -339,6 +342,8 @@ double_tool_plugin_device_added(struct libinput_plugin *libinput_plugin,
|
|||
return;
|
||||
|
||||
libinput_plugin_enable_device_event_frame(libinput_plugin, device, true);
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_BTN_TOOL_PEN);
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_BTN_TOOL_RUBBER);
|
||||
|
||||
struct plugin_data *plugin = libinput_plugin_get_user_data(libinput_plugin);
|
||||
struct plugin_device *pd = zalloc(sizeof(*pd));
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
#include "libinput-plugin.h"
|
||||
#include "libinput-util.h"
|
||||
|
||||
static int ERASER_BUTTON_DELAY = 30 * 1000; /* µs */
|
||||
static usec_t ERASER_BUTTON_DELAY = { 30 * 1000 }; /* µs */
|
||||
|
||||
enum frame_filter_state {
|
||||
DISCARD,
|
||||
|
|
@ -146,9 +146,9 @@ eraser_button_set_state(struct plugin_device *device, enum eraser_button_state t
|
|||
}
|
||||
|
||||
static void
|
||||
eraser_button_set_timer(struct plugin_device *device, uint64_t time)
|
||||
eraser_button_set_timer(struct plugin_device *device, usec_t time)
|
||||
{
|
||||
libinput_plugin_timer_set(device->timer, time + ERASER_BUTTON_DELAY);
|
||||
libinput_plugin_timer_set(device->timer, usec_add(time, ERASER_BUTTON_DELAY));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -235,7 +235,7 @@ static enum frame_filter_state
|
|||
eraser_button_neutral_handle_event(struct plugin_device *device,
|
||||
struct evdev_frame *frame,
|
||||
enum eraser_button_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case ERASER_EVENT_PEN_ENTERING_PROX:
|
||||
|
|
@ -266,7 +266,7 @@ static enum frame_filter_state
|
|||
eraser_button_pending_eraser_handle_event(struct plugin_device *device,
|
||||
struct evdev_frame *frame,
|
||||
enum eraser_button_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case ERASER_EVENT_PEN_ENTERING_PROX:
|
||||
|
|
@ -306,7 +306,7 @@ static enum frame_filter_state
|
|||
eraser_button_button_held_handle_event(struct plugin_device *device,
|
||||
struct evdev_frame *frame,
|
||||
enum eraser_button_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case ERASER_EVENT_PEN_ENTERING_PROX:
|
||||
|
|
@ -339,7 +339,7 @@ static enum frame_filter_state
|
|||
eraser_button_button_released_handle_event(struct plugin_device *device,
|
||||
struct evdev_frame *frame,
|
||||
enum eraser_button_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case ERASER_EVENT_PEN_ENTERING_PROX:
|
||||
|
|
@ -379,7 +379,7 @@ static enum frame_filter_state
|
|||
eraser_button_handle_state(struct plugin_device *device,
|
||||
struct evdev_frame *frame,
|
||||
enum eraser_button_event event,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
enum eraser_button_state state = device->state;
|
||||
enum frame_filter_state ret = PROCESS;
|
||||
|
|
@ -426,7 +426,7 @@ eraser_button_handle_state(struct plugin_device *device,
|
|||
static void
|
||||
eraser_button_handle_frame(struct plugin_device *device,
|
||||
struct evdev_frame *frame,
|
||||
uint64_t time)
|
||||
usec_t time)
|
||||
{
|
||||
if (device->mode == LIBINPUT_CONFIG_ERASER_BUTTON_DEFAULT)
|
||||
return;
|
||||
|
|
@ -505,7 +505,7 @@ eraser_button_plugin_evdev_frame(struct libinput_plugin *libinput_plugin,
|
|||
{
|
||||
struct plugin_data *plugin = libinput_plugin_get_user_data(libinput_plugin);
|
||||
struct plugin_device *pd;
|
||||
uint64_t time = evdev_frame_get_time(frame);
|
||||
usec_t time = evdev_frame_get_time(frame);
|
||||
|
||||
list_for_each(pd, &plugin->devices, link) {
|
||||
if (pd->device == device) {
|
||||
|
|
@ -516,7 +516,7 @@ eraser_button_plugin_evdev_frame(struct libinput_plugin *libinput_plugin,
|
|||
}
|
||||
|
||||
static void
|
||||
eraser_button_timer_func(struct libinput_plugin *plugin, uint64_t now, void *d)
|
||||
eraser_button_timer_func(struct libinput_plugin *plugin, usec_t now, void *d)
|
||||
{
|
||||
struct plugin_device *device = d;
|
||||
|
||||
|
|
@ -541,6 +541,13 @@ eraser_button_plugin_device_added(struct libinput_plugin *libinput_plugin,
|
|||
return;
|
||||
|
||||
libinput_plugin_enable_device_event_frame(libinput_plugin, device, true);
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_BTN_TOOL_PEN);
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_BTN_TOOL_RUBBER);
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_BTN_TOUCH);
|
||||
/* These are the only ones we allow setting the eraser button to */
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_BTN_STYLUS);
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_BTN_STYLUS2);
|
||||
libinput_plugin_enable_evdev_usage(libinput_plugin, EVDEV_BTN_STYLUS3);
|
||||
|
||||
struct plugin_data *plugin = libinput_plugin_get_user_data(libinput_plugin);
|
||||
struct plugin_device *pd = zalloc(sizeof(*pd));
|
||||
|
|
@ -600,7 +607,7 @@ void
|
|||
libinput_tablet_plugin_eraser_button(struct libinput *libinput)
|
||||
{
|
||||
if (getenv("LIBINPUT_RUNNING_TEST_SUITE"))
|
||||
ERASER_BUTTON_DELAY = ms2us(150);
|
||||
ERASER_BUTTON_DELAY = usec_from_millis(150);
|
||||
|
||||
_destroy_(plugin_data) *plugin = zalloc(sizeof(*plugin));
|
||||
list_init(&plugin->devices);
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ struct plugin_device {
|
|||
struct list link;
|
||||
struct libinput_device *device;
|
||||
bitmask_t tool_state;
|
||||
bool pen_forced_into_proximity;
|
||||
size_t pen_prox_out_events;
|
||||
};
|
||||
|
||||
struct plugin_data {
|
||||
|
|
@ -89,6 +91,18 @@ plugin_destroy(struct libinput_plugin *libinput_plugin)
|
|||
plugin_data_destroy(plugin);
|
||||
}
|
||||
|
||||
static void
|
||||
forced_tool_plugin_force_pen_out(struct libinput_plugin *libinput_plugin,
|
||||
struct libinput_device *device,
|
||||
struct evdev_frame *frame)
|
||||
{
|
||||
_unref_(evdev_frame) *prox_out_frame = evdev_frame_new(2);
|
||||
evdev_frame_append_one(prox_out_frame, evdev_usage_from(EVDEV_BTN_TOOL_PEN), 0);
|
||||
evdev_frame_set_time(prox_out_frame, evdev_frame_get_time(frame));
|
||||
|
||||
libinput_plugin_prepend_evdev_frame(libinput_plugin, device, prox_out_frame);
|
||||
}
|
||||
|
||||
static void
|
||||
forced_tool_plugin_device_handle_frame(struct libinput_plugin *libinput_plugin,
|
||||
struct plugin_device *device,
|
||||
|
|
@ -103,21 +117,51 @@ forced_tool_plugin_device_handle_frame(struct libinput_plugin *libinput_plugin,
|
|||
struct evdev_event *event = &events[i];
|
||||
switch (evdev_usage_enum(event->usage)) {
|
||||
case EVDEV_BTN_TOOL_PEN:
|
||||
if (event->value == 1) {
|
||||
bitmask_set_bit(&device->tool_state, BTN_TOOL_PEN);
|
||||
} else {
|
||||
bitmask_clear_bit(&device->tool_state, BTN_TOOL_PEN);
|
||||
device->pen_forced_into_proximity = false;
|
||||
|
||||
/* If we get three valid pen proximity out events, let's
|
||||
* assume this device works fine and disable our plugin
|
||||
*/
|
||||
if (++device->pen_prox_out_events > 2) {
|
||||
plugin_log_debug(
|
||||
libinput_plugin,
|
||||
"%s: forced tool handling unloaded\n",
|
||||
libinput_device_get_name(
|
||||
device->device));
|
||||
libinput_plugin_enable_device_event_frame(
|
||||
libinput_plugin,
|
||||
device->device,
|
||||
false);
|
||||
plugin_device_destroy(device);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return; /* Nothing to do */
|
||||
case EVDEV_BTN_TOOL_RUBBER:
|
||||
case EVDEV_BTN_TOOL_BRUSH:
|
||||
case EVDEV_BTN_TOOL_PENCIL:
|
||||
case EVDEV_BTN_TOOL_AIRBRUSH:
|
||||
case EVDEV_BTN_TOOL_MOUSE:
|
||||
case EVDEV_BTN_TOOL_LENS:
|
||||
case EVDEV_BTN_TOOL_LENS: {
|
||||
int code = evdev_event_code(event) - BTN_TOOL_PEN;
|
||||
if (event->value == 1) {
|
||||
bitmask_set_bit(&device->tool_state,
|
||||
evdev_event_code(event) - BTN_TOOL_PEN);
|
||||
bitmask_set_bit(&device->tool_state, code);
|
||||
if (device->pen_forced_into_proximity) {
|
||||
forced_tool_plugin_force_pen_out(
|
||||
libinput_plugin,
|
||||
device->device,
|
||||
frame);
|
||||
device->pen_forced_into_proximity = false;
|
||||
}
|
||||
} else {
|
||||
bitmask_clear_bit(&device->tool_state,
|
||||
evdev_event_code(event) -
|
||||
BTN_TOOL_PEN);
|
||||
bitmask_clear_bit(&device->tool_state, code);
|
||||
}
|
||||
return; /* Nothing to do */
|
||||
return; /* Keep the frame as-is */
|
||||
}
|
||||
case EVDEV_ABS_X:
|
||||
case EVDEV_ABS_Y:
|
||||
case EVDEV_ABS_Z: /* rotation */
|
||||
|
|
@ -155,6 +199,7 @@ forced_tool_plugin_device_handle_frame(struct libinput_plugin *libinput_plugin,
|
|||
evdev_frame_append_one(frame,
|
||||
evdev_usage_from(EVDEV_BTN_TOOL_PEN),
|
||||
1); /* libinput's event frame will have space */
|
||||
device->pen_forced_into_proximity = true;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -39,14 +39,14 @@
|
|||
/* The tablet sends events every ~2ms , 50ms should be plenty enough to
|
||||
detect out-of-range.
|
||||
This value is higher during test suite runs */
|
||||
static int FORCED_PROXOUT_TIMEOUT = 50 * 1000; /* µs */
|
||||
static usec_t FORCED_PROXOUT_TIMEOUT = { 50 * 1000 };
|
||||
|
||||
struct plugin_device {
|
||||
struct list link;
|
||||
|
||||
struct libinput_plugin_timer *prox_out_timer;
|
||||
bool proximity_out_forced;
|
||||
uint64_t last_event_time;
|
||||
usec_t last_event_time;
|
||||
|
||||
bool pen_state;
|
||||
bitmask_t button_state;
|
||||
|
|
@ -86,18 +86,16 @@ plugin_data_destroy(void *d)
|
|||
free(data);
|
||||
}
|
||||
|
||||
DEFINE_DESTROY_CLEANUP_FUNC(plugin_data);
|
||||
|
||||
static inline void
|
||||
proximity_timer_plugin_set_timer(struct plugin_device *device, uint64_t time)
|
||||
proximity_timer_plugin_set_timer(struct plugin_device *device, usec_t time)
|
||||
{
|
||||
libinput_plugin_timer_set(device->prox_out_timer,
|
||||
time + FORCED_PROXOUT_TIMEOUT);
|
||||
usec_add(time, FORCED_PROXOUT_TIMEOUT));
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_proximity_out_quirk_timer_func(struct libinput_plugin *plugin,
|
||||
uint64_t now,
|
||||
usec_t now,
|
||||
void *data)
|
||||
{
|
||||
struct plugin_device *device = data;
|
||||
|
|
@ -107,7 +105,8 @@ tablet_proximity_out_quirk_timer_func(struct libinput_plugin *plugin,
|
|||
return;
|
||||
}
|
||||
|
||||
if (device->last_event_time > now - FORCED_PROXOUT_TIMEOUT) {
|
||||
usec_t proxout_time = usec_sub(now, FORCED_PROXOUT_TIMEOUT);
|
||||
if (usec_cmp(device->last_event_time, proxout_time) > 0) {
|
||||
proximity_timer_plugin_set_timer(device, device->last_event_time);
|
||||
return;
|
||||
}
|
||||
|
|
@ -146,11 +145,10 @@ proximity_timer_plugin_device_handle_frame(struct libinput_plugin *libinput_plug
|
|||
struct plugin_device *device,
|
||||
struct evdev_frame *frame)
|
||||
{
|
||||
uint64_t time = evdev_frame_get_time(frame);
|
||||
usec_t time = evdev_frame_get_time(frame);
|
||||
/* First event after adding a device - by definition the pen
|
||||
*
|
||||
* is in proximity if we get this one */
|
||||
if (device->last_event_time == 0)
|
||||
if (usec_is_zero(device->last_event_time))
|
||||
proximity_timer_plugin_set_timer(device, time);
|
||||
|
||||
device->last_event_time = time;
|
||||
|
|
@ -188,6 +186,9 @@ proximity_timer_plugin_device_handle_frame(struct libinput_plugin *libinput_plug
|
|||
case EVDEV_BTN_TOOL_FINGER:
|
||||
case EVDEV_BTN_TOOL_MOUSE:
|
||||
case EVDEV_BTN_TOOL_LENS:
|
||||
libinput_plugin_enable_device_event_frame(libinput_plugin,
|
||||
device->device,
|
||||
false);
|
||||
plugin_device_destroy(device);
|
||||
return;
|
||||
default:
|
||||
|
|
@ -207,6 +208,9 @@ proximity_timer_plugin_device_handle_frame(struct libinput_plugin *libinput_plug
|
|||
plugin_log_debug(libinput_plugin,
|
||||
"%s: proximity out timer unloaded\n",
|
||||
libinput_device_get_name(device->device));
|
||||
libinput_plugin_enable_device_event_frame(libinput_plugin,
|
||||
device->device,
|
||||
false);
|
||||
plugin_device_destroy(device);
|
||||
return;
|
||||
}
|
||||
|
|
@ -299,7 +303,7 @@ libinput_tablet_plugin_proximity_timer(struct libinput *libinput)
|
|||
|
||||
/* Stop false positives caused by the forced proximity code */
|
||||
if (getenv("LIBINPUT_RUNNING_TEST_SUITE"))
|
||||
FORCED_PROXOUT_TIMEOUT = 150 * 1000; /* µs */
|
||||
FORCED_PROXOUT_TIMEOUT = usec_from_millis(150);
|
||||
|
||||
_unref_(libinput_plugin) *p = libinput_plugin_new(libinput,
|
||||
"tablet-proximity-timer",
|
||||
|
|
|
|||
|
|
@ -28,11 +28,16 @@
|
|||
#include "util-files.h"
|
||||
#include "util-list.h"
|
||||
|
||||
#include "evdev-frame.h"
|
||||
#include "evdev-plugin.h"
|
||||
#include "libinput-feature.h"
|
||||
#include "libinput-plugin-button-debounce.h"
|
||||
#include "libinput-plugin-lua.h"
|
||||
#include "libinput-plugin-mouse-wheel-lowres.h"
|
||||
#include "libinput-plugin-mouse-wheel.h"
|
||||
#include "libinput-plugin-mtdev.h"
|
||||
#include "libinput-plugin-private.h"
|
||||
#include "libinput-plugin-system.h"
|
||||
#include "libinput-plugin-tablet-double-tool.h"
|
||||
#include "libinput-plugin-tablet-eraser-button.h"
|
||||
#include "libinput-plugin-tablet-forced-tool.h"
|
||||
|
|
@ -60,6 +65,8 @@ struct libinput_plugin {
|
|||
struct list *after;
|
||||
struct list *before;
|
||||
} event_queue;
|
||||
|
||||
struct evdev_mask *mask;
|
||||
};
|
||||
|
||||
struct libinput_plugin_timer {
|
||||
|
|
@ -67,7 +74,7 @@ struct libinput_plugin_timer {
|
|||
struct list link;
|
||||
struct libinput_plugin *plugin;
|
||||
struct libinput_timer timer;
|
||||
void (*func)(struct libinput_plugin *plugin, uint64_t now, void *user_data);
|
||||
void (*func)(struct libinput_plugin *plugin, usec_t now, void *user_data);
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
|
|
@ -91,6 +98,10 @@ plugin_log_msg(struct libinput_plugin *plugin,
|
|||
log_msg(plugin->libinput, priority, "%s%s", prefix, message);
|
||||
}
|
||||
|
||||
static void
|
||||
libinput_plugin_system_load_internal_plugins(struct libinput *libinput,
|
||||
struct libinput_plugin_system *system);
|
||||
|
||||
struct libinput_plugin *
|
||||
libinput_plugin_new(struct libinput *libinput,
|
||||
const char *name,
|
||||
|
|
@ -151,6 +162,7 @@ libinput_plugin_unref(struct libinput_plugin *plugin)
|
|||
if (plugin->interface->destroy)
|
||||
plugin->interface->destroy(plugin);
|
||||
free(plugin->name);
|
||||
evdev_mask_destroy(plugin->mask);
|
||||
free(plugin);
|
||||
}
|
||||
return NULL;
|
||||
|
|
@ -192,6 +204,32 @@ libinput_plugin_enable_device_event_frame(struct libinput_plugin *plugin,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
libinput_plugin_enable_evdev_usage(struct libinput_plugin *plugin,
|
||||
enum evdev_usage usage)
|
||||
{
|
||||
if (!plugin->mask)
|
||||
plugin->mask = evdev_mask_new();
|
||||
|
||||
evdev_mask_set_usage(plugin->mask, evdev_usage_from(usage));
|
||||
}
|
||||
|
||||
void
|
||||
libinput_plugin_disable_device_feature(struct libinput_plugin *plugin,
|
||||
struct libinput_device *device,
|
||||
enum libinput_feature feature)
|
||||
{
|
||||
struct libinput *libinput = plugin->libinput;
|
||||
|
||||
/* During device-added, only some plugins are loaded so this notifies
|
||||
* some of the plugins. All plugins are notified once device-added is
|
||||
* complete. */
|
||||
libinput_plugin_system_notify_device_feature_disabled(&libinput->plugin_system,
|
||||
device,
|
||||
feature);
|
||||
bitmask_set_bit(&device->disabled_features, feature);
|
||||
}
|
||||
|
||||
struct plugin_queued_event {
|
||||
struct list link;
|
||||
struct evdev_frame *frame; /* owns a ref */
|
||||
|
|
@ -312,13 +350,92 @@ libinput_plugin_notify_device_removed(struct libinput_plugin *plugin,
|
|||
plugin->interface->device_removed(plugin, device);
|
||||
}
|
||||
|
||||
void
|
||||
libinput_plugin_notify_evdev_frame(struct libinput_plugin *plugin,
|
||||
struct libinput_device *device,
|
||||
struct evdev_frame *frame)
|
||||
static void
|
||||
plugin_system_append_path(struct libinput_plugin_system *plugin_system,
|
||||
const char *path)
|
||||
{
|
||||
if (plugin->interface->evdev_frame)
|
||||
plugin->interface->evdev_frame(plugin, device, frame);
|
||||
if (strv_find(plugin_system->directories, path, NULL))
|
||||
return;
|
||||
|
||||
plugin_system->directories =
|
||||
strv_append_strdup(plugin_system->directories, path);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT void
|
||||
libinput_plugin_system_append_path(struct libinput *libinput, const char *path)
|
||||
{
|
||||
if (libinput->plugin_system.loaded) {
|
||||
log_bug_client(libinput, "plugin system already initialized\n");
|
||||
return;
|
||||
}
|
||||
|
||||
libinput->plugin_system.autoload = false;
|
||||
|
||||
plugin_system_append_path(&libinput->plugin_system, path);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT void
|
||||
libinput_plugin_system_append_default_paths(struct libinput *libinput)
|
||||
{
|
||||
if (libinput->plugin_system.loaded) {
|
||||
log_bug_client(libinput, "plugin system already initialized\n");
|
||||
return;
|
||||
}
|
||||
|
||||
libinput->plugin_system.autoload = false;
|
||||
|
||||
plugin_system_append_path(&libinput->plugin_system, LIBINPUT_PLUGIN_ETCDIR);
|
||||
plugin_system_append_path(&libinput->plugin_system, LIBINPUT_PLUGIN_LIBDIR);
|
||||
}
|
||||
|
||||
void
|
||||
libinput_plugin_system_autoload(struct libinput *libinput)
|
||||
{
|
||||
if (libinput->plugin_system.loaded)
|
||||
return;
|
||||
|
||||
if (libinput->plugin_system.autoload) {
|
||||
libinput_plugin_system_append_default_paths(libinput);
|
||||
libinput_plugin_system_load_plugins(libinput,
|
||||
LIBINPUT_PLUGIN_SYSTEM_FLAG_NONE);
|
||||
} else {
|
||||
libinput_plugin_system_load_internal_plugins(libinput,
|
||||
&libinput->plugin_system);
|
||||
}
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT int
|
||||
libinput_plugin_system_load_plugins(struct libinput *libinput,
|
||||
enum libinput_plugin_system_flags flags)
|
||||
{
|
||||
if (libinput->plugin_system.loaded) {
|
||||
log_bug_client(libinput, "%s() called twice\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LUA
|
||||
_autostrvfree_ char **directories = steal(&libinput->plugin_system.directories);
|
||||
size_t nfiles = 0;
|
||||
_autostrvfree_ char **plugin_files =
|
||||
list_files((const char **)directories, ".lua", &nfiles);
|
||||
for (size_t i = 0; i < nfiles; i++) {
|
||||
char *path = plugin_files[i];
|
||||
log_debug(libinput, "Loading plugin from %s\n", path);
|
||||
libinput_lua_plugin_new_from_path(libinput, path);
|
||||
}
|
||||
#endif
|
||||
|
||||
libinput_plugin_system_load_internal_plugins(libinput,
|
||||
&libinput->plugin_system);
|
||||
libinput->plugin_system.loaded = true;
|
||||
|
||||
libinput_plugin_system_run(&libinput->plugin_system);
|
||||
|
||||
#ifdef HAVE_PLUGINS
|
||||
return 0;
|
||||
#else
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -367,11 +484,16 @@ void
|
|||
libinput_plugin_system_init(struct libinput_plugin_system *system)
|
||||
{
|
||||
system->loaded = false;
|
||||
#ifdef AUTOLOAD_PLUGINS
|
||||
system->autoload = true;
|
||||
#else
|
||||
system->autoload = false;
|
||||
#endif
|
||||
list_init(&system->plugins);
|
||||
list_init(&system->removed_plugins);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
libinput_plugin_system_load_internal_plugins(struct libinput *libinput,
|
||||
struct libinput_plugin_system *system)
|
||||
{
|
||||
|
|
@ -380,9 +502,7 @@ libinput_plugin_system_load_internal_plugins(struct libinput *libinput,
|
|||
|
||||
system->loaded = true;
|
||||
|
||||
/* FIXME: this should really be one of the first in the sequence
|
||||
* so plugins don't have to take care of this? */
|
||||
#if HAVE_MTDEV
|
||||
#ifdef HAVE_MTDEV
|
||||
libinput_mtdev_plugin(libinput);
|
||||
#endif
|
||||
libinput_tablet_plugin_forced_tool(libinput);
|
||||
|
|
@ -390,6 +510,7 @@ libinput_plugin_system_load_internal_plugins(struct libinput *libinput,
|
|||
libinput_tablet_plugin_proximity_timer(libinput);
|
||||
libinput_tablet_plugin_eraser_button(libinput);
|
||||
libinput_debounce_plugin(libinput);
|
||||
libinput_mouse_plugin_wheel_lowres(libinput);
|
||||
libinput_mouse_plugin_wheel(libinput);
|
||||
|
||||
/* Our own event dispatch is implemented as mini-plugin,
|
||||
|
|
@ -398,6 +519,7 @@ libinput_plugin_system_load_internal_plugins(struct libinput *libinput,
|
|||
* actually connected to anything yet */
|
||||
libinput_evdev_dispatch_plugin(libinput);
|
||||
}
|
||||
|
||||
void
|
||||
libinput_plugin_system_destroy(struct libinput_plugin_system *system)
|
||||
{
|
||||
|
|
@ -433,6 +555,21 @@ libinput_plugin_system_notify_device_added(struct libinput_plugin_system *system
|
|||
libinput_plugin_notify_device_added(plugin, device);
|
||||
}
|
||||
libinput_plugin_system_drop_unregistered_plugins(system);
|
||||
|
||||
/* Now that we added all our devices in all our plugins, notify
|
||||
* all plugins about disabled features. Some plugins may get
|
||||
* this notification twice but they should be able to handle that
|
||||
* case.
|
||||
*/
|
||||
enum libinput_feature feature = _LIBINPUT_N_FEATURES;
|
||||
|
||||
while (--feature > 0) {
|
||||
if (bitmask_bit_is_set(device->disabled_features, feature)) {
|
||||
libinput_plugin_system_notify_device_feature_disabled(system,
|
||||
device,
|
||||
feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -470,6 +607,22 @@ libinput_plugin_system_notify_tablet_tool_configured(
|
|||
libinput_plugin_system_drop_unregistered_plugins(system);
|
||||
}
|
||||
|
||||
void
|
||||
libinput_plugin_system_notify_device_feature_disabled(
|
||||
struct libinput_plugin_system *system,
|
||||
struct libinput_device *device,
|
||||
enum libinput_feature feature)
|
||||
{
|
||||
libinput_device_disable_feature(device, feature);
|
||||
|
||||
struct libinput_plugin *plugin;
|
||||
list_for_each_safe(plugin, &system->plugins, link) {
|
||||
if (plugin->interface->feature_disabled)
|
||||
plugin->interface->feature_disabled(plugin, device, feature);
|
||||
}
|
||||
libinput_plugin_system_drop_unregistered_plugins(system);
|
||||
}
|
||||
|
||||
static void
|
||||
libinput_plugin_process_frame(struct libinput_plugin *plugin,
|
||||
struct libinput_device *device,
|
||||
|
|
@ -504,7 +657,7 @@ print_frame(struct libinput *libinput, struct evdev_frame *frame, const char *pr
|
|||
{
|
||||
static uint32_t offset = 0;
|
||||
static uint32_t last_time = 0;
|
||||
uint32_t time = evdev_frame_get_time(frame) / 1000;
|
||||
uint32_t time = usec_to_millis(evdev_frame_get_time(frame));
|
||||
|
||||
if (offset == 0) {
|
||||
offset = time;
|
||||
|
|
@ -517,9 +670,17 @@ print_frame(struct libinput *libinput, struct evdev_frame *frame, const char *pr
|
|||
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
|
||||
|
||||
for (size_t i = 0; i < nevents; i++) {
|
||||
struct evdev_event *e = &events[i];
|
||||
struct evdev_event e = events[i];
|
||||
enum evdev_usage usage = evdev_usage_enum(e.usage);
|
||||
|
||||
switch (evdev_usage_enum(e->usage)) {
|
||||
if ((usage > EVDEV_KEY_ESC && usage < EVDEV_KEY_CAPSLOCK) ||
|
||||
(usage >= EVDEV_KEY_KP7 && usage <= EVDEV_KEY_KPDOT)) {
|
||||
e.usage = evdev_usage_from(EVDEV_KEY_A);
|
||||
} else if (usage == EVDEV_MSC_SCAN) {
|
||||
e.value = 30; /* KEY_A scancode */
|
||||
}
|
||||
|
||||
switch (evdev_usage_enum(e.usage)) {
|
||||
case EVDEV_SYN_REPORT:
|
||||
log_debug(
|
||||
libinput,
|
||||
|
|
@ -537,9 +698,9 @@ print_frame(struct libinput *libinput, struct evdev_frame *frame, const char *pr
|
|||
prefix,
|
||||
time / 1000,
|
||||
time % 1000,
|
||||
evdev_event_get_type_name(e),
|
||||
evdev_event_get_code_name(e),
|
||||
e->value);
|
||||
evdev_event_get_type_name(&e),
|
||||
evdev_event_get_code_name(&e),
|
||||
e.value);
|
||||
break;
|
||||
default:
|
||||
log_debug(libinput,
|
||||
|
|
@ -547,14 +708,35 @@ print_frame(struct libinput *libinput, struct evdev_frame *frame, const char *pr
|
|||
prefix,
|
||||
time / 1000,
|
||||
time % 1000,
|
||||
evdev_event_get_type_name(e),
|
||||
evdev_event_get_code_name(e),
|
||||
e->value);
|
||||
evdev_event_get_type_name(&e),
|
||||
evdev_event_get_code_name(&e),
|
||||
e.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
plugin_has_mask(struct libinput_plugin *plugin, struct evdev_frame *frame)
|
||||
{
|
||||
/* A plugin without a mask wants all events */
|
||||
if (plugin->mask == NULL)
|
||||
return true;
|
||||
|
||||
size_t nevents;
|
||||
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
|
||||
|
||||
/* nevents - 1 because we don't check the SYN_REPORT */
|
||||
for (size_t i = 0; i < nevents - 1; i++) {
|
||||
struct evdev_event *e = &events[i];
|
||||
|
||||
if (evdev_mask_is_set(plugin->mask, e->usage))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
plugin_system_notify_evdev_frame(struct libinput_plugin_system *system,
|
||||
struct libinput_device *device,
|
||||
|
|
@ -574,7 +756,7 @@ plugin_system_notify_evdev_frame(struct libinput_plugin_system *system,
|
|||
struct list queued_events = LIST_INIT(queued_events);
|
||||
list_take_insert(&queued_events, our_event, link);
|
||||
|
||||
uint64_t frame_time = evdev_frame_get_time(frame);
|
||||
usec_t frame_time = evdev_frame_get_time(frame);
|
||||
|
||||
bool delay = !!sender_plugin;
|
||||
|
||||
|
|
@ -602,20 +784,22 @@ plugin_system_notify_evdev_frame(struct libinput_plugin_system *system,
|
|||
list_for_each_safe(event, &queued_events, link) {
|
||||
struct list next = LIST_INIT(next);
|
||||
|
||||
if (evdev_frame_get_time(event->frame) == 0)
|
||||
if (usec_is_zero(evdev_frame_get_time(event->frame)))
|
||||
evdev_frame_set_time(event->frame, frame_time);
|
||||
|
||||
if (!bitmask_bit_is_set(device->plugin_frame_callbacks,
|
||||
plugin->index)) {
|
||||
plugin->index) ||
|
||||
!plugin_has_mask(plugin, event->frame)) {
|
||||
list_remove(&event->link);
|
||||
list_append(&next_events, &event->link);
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef EVENT_DEBUGGING
|
||||
_autofree_ char *prefix =
|
||||
strdup_printf("plugin %-25s - %s:",
|
||||
plugin->name,
|
||||
libinput_device_get_name(event->device));
|
||||
_autofree_ char *prefix = strdup_printf(
|
||||
"%7s: plugin %-22s - ",
|
||||
libinput_device_get_sysname(event->device),
|
||||
plugin->name);
|
||||
print_frame(libinput_device_get_context(device),
|
||||
event->frame,
|
||||
prefix);
|
||||
|
|
@ -664,7 +848,7 @@ libinput_plugin_system_notify_evdev_frame(struct libinput_plugin_system *system,
|
|||
}
|
||||
|
||||
static void
|
||||
plugin_timer_func(uint64_t now, void *data)
|
||||
plugin_timer_func(usec_t now, void *data)
|
||||
{
|
||||
struct libinput_plugin_timer *timer = data;
|
||||
struct libinput_plugin *plugin = timer->plugin;
|
||||
|
|
@ -698,7 +882,7 @@ struct libinput_plugin_timer *
|
|||
libinput_plugin_timer_new(struct libinput_plugin *plugin,
|
||||
const char *name,
|
||||
void (*func)(struct libinput_plugin *plugin,
|
||||
uint64_t now,
|
||||
usec_t now,
|
||||
void *data),
|
||||
void *data)
|
||||
{
|
||||
|
|
@ -758,7 +942,7 @@ libinput_plugin_timer_unref(struct libinput_plugin_timer *timer)
|
|||
|
||||
/* Set timer expire time, in absolute us CLOCK_MONOTONIC */
|
||||
void
|
||||
libinput_plugin_timer_set(struct libinput_plugin_timer *timer, uint64_t expire)
|
||||
libinput_plugin_timer_set(struct libinput_plugin_timer *timer, usec_t expire)
|
||||
{
|
||||
libinput_timer_set(&timer->timer, expire);
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue