Compare commits

...

119 commits
1.30.2 ... main

Author SHA1 Message Date
Marcin Jahn
bb7aa004f8 quirks: add clevetura clvx s touchpad quirk
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1454>
2026-03-22 20:59:13 +01:00
Freeman Zhang
a1c5f35a69 Add Goodix haptic touchpad 27C6:0F90 support
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1451>
2026-03-22 10:53:44 +00:00
Freeman Zhang
57c71c567f Add Elan haptic touchpad 04F3:3355 support
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1450>
2026-03-22 12:37:19 +08:00
Peter Hutterer
ef9624a16b evdev: store the SYN_REPORT value in the frame
If the SYN_REPORT has a value of nonzero we need to keep that value in
the frame - our upper layers rely on this to detect repeat frames.

Closes #1261

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1449>
2026-03-19 00:09:30 +00:00
GKraats
dcbfbc4cf1 util: fix usec computation on 32 bits
Enforce the needed 64-bit computing on 32 bits.

Signed-off-by: GKraats <vd.kraats@hccnet.nl>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1446>
2026-03-18 00:25:48 +00:00
Peter Hutterer
ad857a51a4 tools/record: fix delta times not being relative
Missing last_time assignment caused the delta time between events to be
the total time.

Fixes: a202ed6115 ("Use a newtype usec_t for timestamps for better type-safety")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1448>
2026-03-17 05:05:14 +00:00
Peter Hutterer
a521d054d4 tools: fix leak of evdev_prev in libinput-record
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
2026-03-17 00:46:46 +00:00
Peter Hutterer
f86d5ab2ab test: add missing button state assertion for eraser button release
The second 'Expect button event' block in
tablet_eraser_button_different_buttons is missing the button state
assertion that the first block has. This event should be a
BUTTON_STATE_RELEASED (the eraser left proximity), but without the
check the test passes even if the state is wrong.

Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
2026-03-17 00:46:46 +00:00
Peter Hutterer
32fd9ec95f tools: Remove dead eraser_button_button initialization to BTN_STYLUS
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
2026-03-17 00:46:46 +00:00
Peter Hutterer
45150cc6ec tools: fix missing fd assignment in libinput-debug-tablet
The fd opened for the evdev device is never stored in ctx->fds[1].fd
so we never poll for it. Real impact was limited since we do poll for
the libinput fd and we process libevdev events whenever any of the fds
triggers.

Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
2026-03-17 00:46:46 +00:00
Peter Hutterer
c8c1c07a2a tools: fix swapped fread arguments causing DMI modalias to always be "unknown"
fread(buf, sizeof(buf), 1, dmi) reads one block of 2048 bytes,
returning the number of complete blocks (0 or 1). Since DMI modalias
files are always shorter than 2048 bytes, fread returns 0 even when
data was successfully read into buf. The 'if (n > 0)' check then
always fails and the DMI string stays as "unknown".

Swap the size and nmemb arguments so fread returns the number of
bytes read instead.

Fixes: 0ecd08c134 ("tools: use __attribute__(cleanup)")

Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
2026-03-17 00:46:46 +00:00
Peter Hutterer
b1f478b897 tools: fix pencil tablet tool type in libinput-record
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
2026-03-17 00:46:45 +00:00
Peter Hutterer
333d7131ab tools: fix swapped strstartswith arguments in find_device()
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
2026-03-17 00:46:45 +00:00
Peter Hutterer
cd9d6c66fd tablet: fix eraser button get_default_mode/get_default_button return values
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
2026-03-17 00:46:45 +00:00
Peter Hutterer
a0dc0997f5 meson.build: explicitly convert a boolean to string
Fixes:
  DEPRECATION: Variable substitution with boolean value 'MESON_ENABLED_DEBUG_GUI' is deprecated.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1445>
2026-03-13 12:15:21 +10:00
Peter Hutterer
c6813dc7d8 tools: add --compress-motion-events to the man page and zsh completion
Fixes: dc249b0ffe ("tools/debug-events: add ability to compress motion events")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1443>
2026-03-11 14:22:40 +10:00
Ilya Kamenko
8dd25ece10 Fold hold-to-scroll into existing scroll button lock mode
Instead of adding a new ENABLED_HOLD enum value, modify the existing
ENABLED lock mode so that hold+scroll+release doesn't engage the lock.

Add a 500ms grace period: if the button was held and used to scroll for
longer than 500ms, releasing the button does not engage the lock
(temporary scroll). If released within 500ms (e.g. shaky hands
triggering accidental motion), the lock still engages as before.

This fixes the unintuitive behavior where the lock engages even after
actively scrolling, without requiring new API surface.

Closes: https://gitlab.freedesktop.org/libinput/libinput/-/issues/1259

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1435>
2026-03-10 23:12:25 +00:00
Mingcong Bai
43547b461b quirks: add Goodix pressure pad quirk for 27C6:01E7
This touchpad is found on the newly released Lenovo ThinkBook G8+ IPH.

Signed-off-by: Mingcong Bai <jeffbai@aosc.io>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1442>
2026-03-10 11:37:34 +08:00
David Santamaría Rogado
2ddc734114 test: set ID_INTEGRATION into test devices
Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1429>
2026-03-10 02:27:36 +00:00
David Santamaría Rogado
819e943ab0 evdev: use udev's ID_INTEGRATION
Now we have in udev the ID_INTEGRATION propery that tells us if a device
is internal or external, use it while still allow hwdb and quirks to
override it.

In the future is possible that we could remove quirks for keyboards
integration and hwdb for touchpads and joysticks integration.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1429>
2026-03-10 02:27:36 +00:00
David Santamaría Rogado
1c82aa1659 quirks: add some more goodix haptic touchpads
Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1440>
2026-03-09 09:48:05 +01:00
David Santamaría Rogado
526130fe8d quirks: hp omnibook ultra flip 14 touch pressure
Add pressure attributes to make libinput measure touchpad-pressure
behave right.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1430>
2026-03-09 01:34:07 +00:00
David Santamaría Rogado
b95840d36e quirks: hp omnibook ultra flip 14 improve rule set
Some initial units had 14t-fh000 instead 14-fh0xxx in their product name
but they are exactly the same model.

We could match both in product version SBKPF or in board product name
8CDE. Match board as seems the way hp-wmi kernel module uses to match.

While at it rewrite the entire huge comment to a little less huge
comment but with more really interesting info.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1430>
2026-03-09 01:34:07 +00:00
Peter Hutterer
7726350420 tablet: allow for the eraser button to be any button
The previous restriction was BTN_STYLUS* or any button the pen
advertises. This is too restrictive - it works well enough for any pen
with less than 3 buttons (BTN_STYLUS3 is always available on those) but
otherwise it cannot work. A 3-button pen may not advertise any other
buttons, leaving us with the eraser button being a duplicate button. And
events cannot be distinquished between eraser button or real button.

Open up the configuration to effectively any BTN_ event code.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1436>
2026-03-09 01:14:21 +00:00
Peter Hutterer
cdcb827365 Fix the evdev_usage_is_button check for the BTN_STYLUS group
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1436>
2026-03-09 01:14:21 +00:00
Peter Hutterer
0a3ecbea24 tablet: fix missing linebreak after an error message
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1436>
2026-03-09 01:14:21 +00:00
BBaoVanC
db62bf7ab1 quirks/apple: Add AttrSizeHint to Magic Trackpad USB-C
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1437>
2026-03-04 04:53:28 +00:00
David Santamaría Rogado
9eae99d4fe quirks: microsoft surface keyboard event BTN_0
Apply AttrEventCode=-BTN_0 to all surface keyboards.

Fixes: #1251.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1431>
2026-02-22 08:40:11 +00:00
David Santamaría Rogado
a86b8a0008 doc: list-quirks should be quirks list
while at it replace also a code comment in the same line.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1432>
2026-02-20 19:56:46 +01:00
Sicelo A. Mhlongo
3428edf1ea doc/user: document keypad slide switch support
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1428>
2026-02-17 12:03:56 +02:00
Peter Hutterer
659967488e libinput 1.31.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2026-02-13 09:25:46 +10:00
Lorenzo Ianotto
b9fc550f28 Set ModelTabletModeNoSuspend only for Thinkpad S1 Yoga and X1 Yoga 1st gen
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1425>
2026-02-09 02:42:33 +00:00
Richie Roy Jayme
df8f5a3627 quirks: add quirk support for Goodix touchpad
This commit adds a specific vendor HWID for Goodix Haptic Touchpad to
improve detection and handling.

Signed-off-by: Richie Roy Jayme <rjayme.jp@gmail.com>
Signed-off-by: Richie Roy Jayme <rjayme2@lenovo.com>
Reviewed-by: Vishnu Sankar <vishnuocv@gmail.com>
Reviewed-by: Vishnu Sankar <vsankar@lenovo.com>
Reported-by: Ameer Ivan Julkarnain <ajulkarnain1@lenovo.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1426>
2026-02-07 08:27:58 +00:00
Peter Hutterer
e0ba559117 libinput 1.30.901
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1424>
2026-02-04 12:41:58 +10:00
Peter Hutterer
e78f4f689d util: add guards for the etrace/trace defines
This file is really useful on its own for other projects if
auto-included via export CFLAGS="$CFLAGS -include /path/to/file.h"
However, that causes compiler warnings, let's add indef checks for this
as a quick workaround.

Since these three come as a set and are only used for debugging, we can
ifndef them all in one go rather than individually.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1423>
2026-02-04 11:18:54 +10:00
Peter Hutterer
ad89a83ae6 tablet: ignore the tablet tool name if it's a generic tool
libwacom has generic pens that are used for devices that don't have tool
ids. Let's ignore the names for those pens since they're just made up
names anyway.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1422>
2026-02-03 23:27:14 +00:00
Peter Hutterer
6d514ee6fa touchpad: add get_default_timeout for dwt and dwtp
I doubt this is really needed but our convention for all config options
is set/get/get_default so let's stick with that.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1421>
2026-02-03 13:01:59 +10:00
David Santamaría Rogado
6f79797308 test: recover external usb keyboard touchpad combo
This recovers the testing that a USB keyboard plus touchpad combo both
set as external, only its own keyboard should affect to DWT that was
removed when Acer Hawaii combo was set as internal.

This is uncommon as usb touchpads nowadays are set as internal, but,
perhaps someone that adds a quirk for a really external combo also adds
in udev's hwdb the external integration for the touchpad, or perhaps we
should set the integration to external when AttrTPKComboLayout=below is
used for the touchpad.

The issue is if the touchpad is leave as internal every keyboard affect
DWT, not only the one that belongs to its combo.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1415>
2026-02-02 09:52:08 +00:00
Michał Chojnowski
b58d5a165b tablet: fix handling of AttrPressureRange quirk
tablet_get_quirked_pressure_thresholds() is wrong:
the pressure thresholds for tip press and tip release are swapped around.
This seems to be a regression introduced in commit 4bc27543e9.

This prevents AttrPressureRange from working as intended for tablets,
and causes weird things to happen if it's set.
(For example, when pressure is in the range between
the intended release threshold and the intended press threshold,
the "pressed" status flip-flops between 0 and 1 every frame).

Fix that.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1420>
2026-02-02 08:41:24 +01:00
Peter Hutterer
fe1d44637f touchpad: add support for fast swipe when 3fg drag is enabled
This adds a movement threshold (5mm) and a timeout (80ms) to the 3fg
drag gesture. On 3fg down with 3fg drag enabled we immediately send a
GESTURE_SWIPE event. After the timeout expires we check the movement of
the fingers - if it is below the threshold cancel the swipe and hold a
button down (i.e. a 3fg drag). Otherwise, continue with this being a
swipe.

This allows for swipe gestures to be used while 3fg drag is enabled.

Above applies the same way for 4fg with 4fg drag enabled.
Thresholds selected using the "yeah, that seems about alright" method,
intentionally quite low because we assume that users that enable 3fg
drag prefer 3fg dragging over swipe.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1410>
2026-02-02 06:44:48 +00:00
Peter Hutterer
5b7b8f1bb2 gestures: remove two empty helper functions
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1410>
2026-02-02 06:44:48 +00:00
Peter Hutterer
33b1d87c08 touchpad: don't disable on external mice until we see an event
Instead of disabling the touchpad as soon as a mouse is seen by
libinput, disable it as soon as a mouse sends an actual event. This
works around the current issues with many devices (touchpads and
keyboards alike) announcing a HID Mouse Application Collection which
gets its own event node in the kernel. That event node usually just sits
there and does nothing but its mere presence disabled the touchpad.

Let's change this and instead only disable once we see an event.

Closes: #1104
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1414>
2026-01-28 00:43:37 +00:00
Peter Hutterer
89351c715a test: parametrize the external mouse test
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1414>
2026-01-28 00:43:37 +00:00
Peter Hutterer
e161abdc19 evdev: rename evdev_paired_keyboard to evdev_paired_device
We'll be using this struct for other devices than keyboards.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1414>
2026-01-28 00:43:36 +00:00
David Santamaría Rogado
47482bcd8b quirks: add more specific matches to actual quirks
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1418>
2026-01-27 00:43:51 +00:00
David Santamaría Rogado
307d2509a9 quirks: merge ibm with lenovo
ScrollPoint mouses as well IBM USB Travel Keyboard with Ultra Nav Mouse
are owned by Lenovo.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1419>
2026-01-27 00:19:16 +00:00
Peter Hutterer
86f19a0978 lua: install a timeout hook before any pcalls to prevent infinite loops
If a lua pcall takes longer than one second, kill the plugin.

How often to call the timeout handler is a trade-off but we err on the
side of "possibly too high" since the overwhelmingly vast majority of
plugins will never trigger it anyway.

Gemini suggests that Lua 5.4 can do ~500k ops per second for string
concat (the slowest listed), Claude suggests 1 to 10 million ops per
second. The test in this patch on my 4y old cheap desktop runs the
timeout hook roughly every 37ms. Any normal plugin will be well and
truly done with its work by then.

Closes: #1245
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1416>
2026-01-27 00:02:15 +00:00
Helga K
cc1499fbb3 quirks: Add quirk for Gigabyte Aorus 15BKF keyboard
This keyboard sits on the USB bus, so it's considered an external
keyboard by default. This commit changes that to internal
so that DWT detection on the laptop touchpad works.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1411>
2026-01-22 15:59:42 +04:00
Jens Peters
8854066e93 plugin: add an example for controlling a mouse with a tablet
This plugin controls a mouse/pointer from a tablet device. This
effectively hides stylus interactions and sends pointer events
instead. In other words: mouse emulation for tablets, implemented
by (remote) controlling a mouse device. This allows using a
tablet stylus as a mouse replacement without tablet limitations
from compositors or clients. Note that axis usually needed for
drawing (like pressure, tilt or distance) are no longer emitted
when this plugin is active and a mouse is connected. When no
mouse is connected, this plugin doesn't change tablet events,
thus the stylus works like a normal stylus.

Follow up from https://gitlab.freedesktop.org/libinput/libinput/-/issues/1195

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1412>
2026-01-21 08:44:13 +00:00
Peter Hutterer
074a6f57b8 test: fix some comments for accuracy
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 14:59:02 +10:00
Peter Hutterer
9f096b0403 test: move two helper functions into the only caller
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 14:59:02 +10:00
Peter Hutterer
328b9a8a32 test: fix the gesture hold cancel test
This didn't actually check for the cancellation of the gesture, so let's
add that.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 14:59:02 +10:00
Peter Hutterer
7ff2326efb test: change the gesture state color to normal yellow
The current color is unreadable on my screens and since no-one else
really looks at this much, let's change it for my benefit.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 14:59:02 +10:00
Peter Hutterer
6bca272629 test: parametrize a gesture test
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 14:59:02 +10:00
Peter Hutterer
00e568f43a test: correct a copy/pasted comment
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 13:14:24 +10:00
Peter Hutterer
13405e4b8c test: add missing BTN_TOOL_QUINTTAP to the acer hawaii test device
This recording comes from
https://bugs.freedesktop.org/show_bug.cgi?id=99140 and it's set there so
this si presumably a copy/paste issue.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 11:49:58 +10:00
Peter Hutterer
bee28a7e53 test: remove a leftover etrace()
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 11:49:58 +10:00
Peter Hutterer
dee2d38476 Add libinput_tablet_tool_get_name() for the tool's specific name
If the tool has a name let's provide that to the caller. We have it
easily accessible so let's export it to make everyone's life easier. The
name is provided by libwacom, there is no need for us
to even copy that value since we don't need it ourselves.

Note that at this point effectively only (some) Wacom devices have
meaningful names. Virtually all non-wacom devices will use a generic
tool and even the built-in Wacoms will largely just say "AES Pen".

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1399>
2026-01-14 16:44:01 +10:00
Peter Hutterer
7d19cb5f40 CI: rebuild to pick up newer libwacom on Fedora 43
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1399>
2026-01-14 09:27:28 +10:00
Peter Hutterer
21ac8568d5 CI: temporarily drop FreeBSD
14.2 is 404 so we cannot rebuild any images and,
14.3 has a bug that blocks it from building images:
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=292375

So let's disable BSD until the bug is fixed.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1409>
2026-01-13 22:42:07 +00:00
Peter Hutterer
6b4d1905b6 plugin: always disable wheel debouncing on request
The WHEEL_STATE_NONE check was effectively always false:
- if we didn't receive any event yet, wheel_maybe_disable() wasn't
  called in any code path
- if we did receive a scroll event, the wheel state was either
  WHEEL_STATE_SCROLLING or WHEEL_STATE_ACCUMULATING_SCROLL

Fix this two-pronged: remove the check for WHEEL_STATE_NONE but also
immediately call disable when we disable the feature. We don't carry
enough state in this plugin to really worry about the device being in
a fully neutral state (and realistically the vast majority of use-cases
will likely disable wheel debouncing on new device anyway).

Closes #1241

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1408>
2026-01-13 21:52:52 +00:00
Peter Hutterer
005a3e5622 test: remove a leftover etrace()
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1408>
2026-01-13 21:52:52 +00:00
David Santamaría Rogado
2772863af0 quirks: separate logitech quirks
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1407>
2026-01-13 01:50:51 +00:00
David Santamaría Rogado
47312e99d8 quirks: wipe HP Elite x2 G3 keyboard and touchpad
Actually not needed using internal approach.

Keyboard is ps2 wired in pogo pins and touchpad is usb, both internal by
default so dwt is in effect.

If tablet side buttons are also within ps2, they are not going to be
disabled as chassis is detachable.

Tablet mode switch untouched as is unclear if actual kernels play nice
with it.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1406>
2026-01-13 01:53:28 +01:00
David Santamaría Rogado
24ac440ecc quirks: add edit warning where missing
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1405>
2026-01-13 01:00:19 +01:00
David Santamaría Rogado
0110512b3e quirks: huawei better use pn instead pvr
Huawei MateBook X 2020 used M1010 product version but is used within
different Matebook X over the years.

Use EUL-WX9 product name instead.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1403>
2026-01-12 03:49:00 +01:00
David Santamaría Rogado
605abf2f37 quirks: normalize dmi matches
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1403>
2026-01-12 03:49:00 +01:00
David Santamaría Rogado
9a036bec30 test: set usb touchpad as internal
Actually all usb touchpads are internal by default, reflect this in the
acer touchpad definition.

This causes that not only the acer keyboard in its group activates DWT
but all the intenal keyboards.

Remove asserting that other keyboards doesn't affect DWT as that is the
intended behaviour.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1400>
2026-01-10 23:33:41 +01:00
Peter Hutterer
731d4452c3 meson: revamp the debug build detection for the builddir lookup
Ifdef out any special behavior we want so we no longer leak this via
strings in the resulting binary. Ideally we want the compile to fail for
anything missed rather than surprising behavior when we try to access
files in the build directory.

Closes: #1230
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1396>
2026-01-10 10:39:21 +00:00
David Santamaría Rogado
48e367e841 quirks: missing matches
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1402>
2026-01-10 10:23:19 +00:00
David Santamaría Rogado
1e9b81f75d quirks: refactor pixart touchpads
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1401>
2026-01-09 18:46:40 +01:00
David Santamaría Rogado
02b495e790 quirks: internal integration for lenovo detachable
These are quirks needed for Lenovo detachable devices by setting the
keyboard as internal to enable DWT and act as if it's a laptop.

Here we try to cover all the ideapad ones.

Also remove a quirk in Chicony that sets the touchpad below to enable
DWT, prefer to set the keyboard as internal as touchpad position is
intended for external ones like the input device we also move to the
bottom in Lenovo to have all pure input device quirks in one place.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1389>
2026-01-09 02:44:11 +00:00
Peter Hutterer
822a6d9365 tools: make the touchpad-pressure thresholds interactive
Easier to play around with than having to re-start with different
commandline arguments all the time.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1394>
2026-01-09 02:21:13 +00:00
Peter Hutterer
49624ace16 tools: use box-drawing characters for the table in touchpad-pressure
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1394>
2026-01-09 02:21:13 +00:00
Peter Hutterer
82cbbdab78 test: add (a broken) test for a second range config
This tests for a known bug in the implementation rather than the ideal case
how it should work.

The config is applied to the tool and on prox out to the current tablet
but then the tool goes in prox on a new tablet and the configuration
doesn't get applied there. In the test we work around this by injecting
an extra proximity event to get the range applied.

This needs some rework in the evdev-tablet code but it's questionable
whether it makes a difference given the small number of users with
multiple tablets and pressure ranges set.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1397>
2026-01-09 02:01:14 +00:00
Peter Hutterer
47c7bd934a test: fix the multiple-tablet-pressure-range test
The previous test was incomplete, add support for setting pressure
ranges and generally expand and tighten up the test case so it tests
more specficially for the expected events.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1397>
2026-01-09 02:01:14 +00:00
Peter Hutterer
ef1ee837e4 test: allow overriding any axis value
Previously test devices had to set LITEST_AUTO_ASSIGN to be able
to override an axis-specific value. But this prevented us from
easily overriding other axis values (e.g. tablet tool ids) that usually
have the same value.

LITEST_AUTO_ASSIGN should indicate a value that must always be
auto-assigned, that makes a lot more sense.

This does mean we need to handle ABS_MT_TRACKING_ID -1 to avoid that
getting overwritten by auto_assign_tablet_value() but oh well.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1398>
2026-01-09 01:47:13 +00:00
Peter Hutterer
c8e0312195 test: don't assign -1/-1 to x/y on proximity out
This only worked because any all our test devices declare a fixed 0
value for x/y in the proximity out event frame. Since 0 !=
LITEST_AUTO_ASSIGN we never got to the litest_scale() for x/y which
would abort because of the -1 value.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1398>
2026-01-09 01:47:13 +00:00
Peter Hutterer
c9e175a507 test: correct overriding ABS_MISC in litest event frames
This still requires LITEST_AUTO_ASSIGN for that value in the test
devices (which no device currently sets) but meanwhile: not scaling
ABS_MISC into a magic range is the correct thing to do.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1398>
2026-01-09 01:47:12 +00:00
David Santamaría Rogado
d5110e1e68 quirks: acer add detachable keyboards
Cover Acer detachable keyboards used in Switch tablet devices to set
them internal and allow DWT.

Move one of them from chicony using the below method.

While at it change the match for internal keyboard in Acer Spin 5 to
rely of bus and type and add ':' before svn dmi match.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1392>
2026-01-06 22:41:37 +00:00
David Santamaría Rogado
130f95fd43 quirks: rework minisforum keyboard and add one
Use ids for Minisforum V3 and remove dmi match.

Also add Minisforum V3 SE one.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1395>
2026-01-06 13:58:57 +01:00
David Santamaría Rogado
b60416083e quirks: rework tablet mode using chassis type
Don't disable inputs for detachable and tablet devices, they are
physically unplugged from their input devices but tend to have buttons
as internal keyboard in the tablet part that must work always. We know
what kind of device is using the Chassis Type DMI value.

Also remove specific device quirks now covered by the chassis type.

Finally refactor some Lenovo devices using this quirk and redefine Dell
2-in-1 with this quirk using chassis type.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1390>
2026-01-05 04:44:41 +00:00
Peter Hutterer
58228f12f0 tools: fix the man page for the libinput-test command
The way we run this, the feature is appended to the libinput-test
command so this resulted in trying to execute libinput
libinput-test-libinput-test-suite.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1384>
2026-01-05 01:53:41 +00:00
Peter Hutterer
b48ce4c5be test: fix --help output for --filter-deviceless
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1384>
2026-01-05 01:53:41 +00:00
Peter Hutterer
6c2b9dcbde meson.build: add a summary for the test options
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1384>
2026-01-05 01:53:41 +00:00
Peter Hutterer
1d4ce84746 test: only use the quirks srcdir if we have a builddir
Same approach as we already do for other constants though note the
builddir_lookup() hack only works for release builds.

Closes #1230

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1384>
2026-01-05 01:53:41 +00:00
David Santamaría Rogado
08a8e0cc38 quirks: add missing match in synaptic touchpad
Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1391>
2026-01-02 06:07:28 +01:00
David Santamaría Rogado
83966ee306 quirks: remove now not needed entries
The recently added ITE usb keyboard and pressure touchpad entries makes
them unnecessary.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1383>
2025-12-23 21:06:27 +01:00
David Santamaría Rogado
56eec4afca quirks: add another lenovo haptic touchpad quirk
Used at least in another more Lenovo model that the one in the comment
where is actually.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1383>
2025-12-23 20:03:05 +01:00
David Santamaría Rogado
a525b30326 quirks: add Lenovo touchpad quirk in a generic way
Matching in vendor and product covers many models as possible.

01E8 product is always haptic.

01E0 can be or not haptic, leave it outside this and mantain it per
system model. When the kernel detects haptic touchpads the ones that
cannot be differenciated won't need to have quirk neither.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1383>
2025-12-23 18:27:53 +01:00
David Santamaría Rogado
8901ddf354 quirks: define generic quirks for ITE
Actual quirk in ITE vendor changed for a more generic one.
This is a step prior to cleanup other quirks.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1383>
2025-12-23 15:22:30 +01:00
David Santamaría Rogado
3cac03c8b2 quirks: Remove Vaio quirks file
The only rule is already defined for the touchpad in it's vendor file.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1386>
2025-12-22 23:35:05 +00:00
David Santamaría Rogado
3a54526d03 quirks: Move Synaptics touchpad to Hanticks
Synaptics 0911:5288 Touchpad really is a Hantick one, move it.

Also change it to rely on bus and ids because name can vary.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1381>
2025-12-22 22:20:18 +00:00
David Santamaría Rogado
23cd0408cc quirks: HP 14-fh0xxx just match internal touchpad
Apply ModelTabletModeNoSuspend just for internal touchpad no matter what
model is.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1388>
2025-12-22 00:01:34 +01:00
Peter Hutterer
0412fb3d44 pad: fix missing newline for mode group error messages
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1380>
2025-12-17 14:37:59 +10:00
David Santamaría Rogado
a376fe366c quirks: HP 14-fh0xxx rely on bus, ids and type
Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1378>
2025-12-16 21:52:31 +01:00
David Santamaría Rogado
9a07784451 quirks: Sort HP entries alphabetically
Also remove generic HP Haptics Touchpad CFD2 moved to Synaptics.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1378>
2025-12-16 21:51:53 +01:00
David Santamaría Rogado
3cf723451f quirks: Add generic Synaptics quirk found in HP ones
This quirk is a generic one for all the HP laptops with haptic touchpad
so makes more sense here because we are applying it dmi independent
being more difficult to track this change if the touchpad became used in
other vendors.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1378>
2025-12-16 16:35:22 +01:00
Peter Hutterer
2d3e47290c quirks: add a quirk for the RazerBlade182025 keyboard
Generated by tools/razer-quirks-lister.py

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1379>
2025-12-16 16:54:18 +10:00
Peter Hutterer
5bd7f93c16 doc/user: add a graph of how different contexts work
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1376>
2025-12-12 04:29:13 +00:00
Peter Hutterer
a202ed6115 Use a newtype usec_t for timestamps for better type-safety
This avoids mixing up milliseconds and usec, both by failing if
we're providing just a number somewhere we expect usecs and also
by making the API blindingly obvious that we're in usecs now.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1373>
2025-12-12 04:15:15 +00:00
Peter Hutterer
c0c809aaa1 util: fix documentation issues for newtypes
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1373>
2025-12-12 04:15:15 +00:00
Peter Hutterer
e8dfc3bfd6 util: make the newtype comparision functions return bool
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1373>
2025-12-12 04:15:15 +00:00
Sicelo A. Mhlongo
b3f7b4b1ea evdev: add support for SW_KEYPAD_SLIDE
A few devices have a keyboard/keypad which can be slid under the device,
leaving the device with only touch-based interaction. The corresponding kernel
event is reported as SW_KEYPAD_SLIDE [0]. Implement support in libinput.

Since the position of the switch varies across devices, it cannot always be
certain whether the keypad is usable when the switch is in the set position.
Therefore, do not automatically disable the keyboard.

[0] e68d80b13b/include/linux/linux/input-event-codes.h (L885)

Closes: #1069
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1242>
2025-12-11 13:28:41 +02:00
Peter Hutterer
0285001272 touchpad: make the dwt/dwtp timeout inclusive min/max
This makes it easier in callers that don't really differ between
inclusive and exclusive and makes the visualization in UIs a bit
nicer to look at too.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1377>
2025-12-10 03:07:36 +00:00
Peter Hutterer
bde6d07d57 quirks: replace ModelPressurepad with setting INPUT_PROP_PRESSUREPAD
This is the more generic approach and doesn't require us to have any
specific implementation in libinput itself.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1374>
2025-12-09 06:07:01 +00:00
Peter Hutterer
1b4dbb9087 doc/user: minor update to the forcepad/pressurepad documentation
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1374>
2025-12-09 06:07:01 +00:00
Peter Hutterer
d5d38b2ed1 doc/user: fix two typos in ref anchors
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1374>
2025-12-09 06:07:01 +00:00
Peter Hutterer
38b5c2e0cc touchpad: add configurable timeouts to disable-while-trackpointing
Same motivation as in commit
"touchpad: add configurable timeouts to disable-while-typing"

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1372>
2025-12-02 09:24:15 +10:00
Peter Hutterer
20851b5020 touchpad: add configurable timeouts to disable-while-typing
Touchpads that don't give us useful palm detection data are getting more
common (see e.g. our ABS_MT_TOOL_TYPE quirks). On those touchpads we can
only rely on dwt and palm edge detection which means those two must be
more spot on than ever before.

DWT in particular is more prone to user-specific requirements, the
current timeouts have been insufficient for a number of users. So let's
make them more configurable.

Currently limited to >100ms and <5 seconds to avoid DWT being used in
the xkcd workflow style.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1372>
2025-12-02 09:24:15 +10:00
Peter Hutterer
2003ab3aef test: rename a dwt test for better clarity
This is the "short-timeout after a single key press" dwt test so let's
rename it that way

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1372>
2025-12-02 09:20:08 +10:00
Peter Hutterer
4bb6a31894 doc: fix a few miss-hyphenated disable-while-typing comments
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1372>
2025-12-02 09:20:08 +10:00
Peter Hutterer
db6a04665c touchpad: use INPUT_PROP_PRESSUREPAD as signal it's a pressurepad
Because, well, it says so on the box now. No more quirks, hopefully!

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1359>
2025-12-01 21:39:11 +00:00
Peter Hutterer
7621edab05 include: sync headers with kernel 6.18
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1359>
2025-12-01 21:39:11 +00:00
Peter Hutterer
39aea2a8d6 test: silence a valgrind warning
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1370>
2025-11-27 09:32:13 +10:00
Peter Hutterer
7e8298e9ec tablet: when destroying a tablet, unlink the tablet tools
If a caller holds a ref to a tablet tool when the device is
destroyed, the tool didn't get removed from the tablet->tool_list.

Later on tool unref the list_remove() would try to reset the pointers
but the list head was long since freed, causing an invalid write.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1370>
2025-11-27 09:26:54 +10:00
Peter Hutterer
49d9528bdf tablet: after three valid prox out events, unload the forced prox plugin
Once we receive three valid proximity out events for the pen, unload the
plugin that generates forced proximity in events for tablets that
don't send BTN_TOOL_PEN.

Closes #1222

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1370>
2025-11-26 10:55:03 +10:00
Peter Hutterer
1e8901d009 tablet: only apply eraser button settings if we have a device
If the device is unplugged, our tool's last_device is NULL. If a caller
then tries to the toggle the eraser button setting libinput would crash.
Fix this by simply skipping the configuration until the tool goes back
into proximity over some other device (if any).

Closes #1223

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1370>
2025-11-26 10:54:47 +10:00
Peter Hutterer
a6ad084280 tablet: return the wanted eraser button mode/button from the config
This matches our behavior for other settings - always return the
user-configured setting from the configuration API, not the current
setting (which may be delayed until the device is in a netural state).

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1370>
2025-11-26 10:32:18 +10:00
254 changed files with 5561 additions and 2365 deletions

View file

@ -49,8 +49,6 @@ include:
- '/templates/debian.yml'
# Fedora container builder template
- '/templates/fedora.yml'
# Freebsd container builder template
- '/templates/freebsd.yml'
# Ubuntu container builder template
- '/templates/ubuntu.yml'
@ -103,19 +101,17 @@ variables:
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 #############################
# these tags should be updated each time the list of packages is updated
# 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-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'
FEDORA_TAG: '2026-01-09.0'
DEBIAN_TAG: '2026-01-09.0'
UBUNTU_TAG: '2026-01-09.0'
ARCH_TAG: '2026-01-09.0'
ALPINE_TAG: '2026-01-09.0'
FDO_UPSTREAM_REPO: libinput/libinput
@ -339,20 +335,6 @@ alpine:latest@container-prep:
FDO_DISTRIBUTION_PACKAGES: $ALPINE_PACKAGES
FDO_DISTRIBUTION_TAG: $ALPINE_TAG
freebsd:14.2@container-prep:
extends:
- .fdo.qemu-build@freebsd
- .policy
- .fdo-runner-tags
tags:
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM
stage: prep
variables:
GIT_STRATEGY: none
FDO_DISTRIBUTION_VERSION: '14.2'
FDO_DISTRIBUTION_PACKAGES: $FREEBSD_PACKAGES
FDO_DISTRIBUTION_TAG: $FREEBSD_TAG
#################################################################
@ -446,16 +428,6 @@ alpine:latest@container-clean:
FDO_DISTRIBUTION_VERSION: 'latest'
FDO_DISTRIBUTION_TAG: $ALPINE_TAG
freebsd:14.2@container-clean:
extends:
- .policy
- .container-clean
variables:
GIT_STRATEGY: none
CURRENT_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/freebsd/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG
FDO_DISTRIBUTION_VERSION: '14.2'
FDO_DISTRIBUTION_TAG: $FREEBSD_TAG
#################################################################
# #
@ -1344,19 +1316,6 @@ alpine:latest@default-build:
- "alpine:latest@container-prep"
freebsd:14.2@default-build:
stage: distro
extends:
- .build-in-qemu@template
- .fdo.distribution-image@freebsd
variables:
FDO_DISTRIBUTION_VERSION: '14.2'
FDO_DISTRIBUTION_TAG: $FREEBSD_TAG
MESON_ARGS: '-Dtests=false -Ddocumentation=false' # doxygen drags down too many deps
MESON_TEST_ARGS: '' # test suite doesn't work on BSD yet
needs:
- "freebsd:14.2@container-prep"
#################################################################
# #

View file

@ -3,7 +3,7 @@
#
# We're happy to rebuild all containers when one changes.
.default_tag: &default_tag '2025-11-17.0'
.default_tag: &default_tag '2026-01-09.0'
distributions:
- name: fedora
@ -148,29 +148,6 @@ distributions:
# for any tcase_add_exit_test/tcase_add_test_raise_signal
# but someone more invested in musl will have to figure that out.
- "MESON_TEST_ARGS: '' # litest-selftest fails on musl"
- name: freebsd
tag: *default_tag
qemu_based: true
versions:
- '14.2'
packages:
- git
- pkgconf
- meson
- libepoll-shim
- libudev-devd
- libevdev
- libwacom
- gtk3
- libmtdev
- bash
- wayland
build:
extra_variables:
- "MESON_ARGS: '-Dtests=false -Ddocumentation=false' # doxygen drags down too many deps"
# We don't run the tests on FreeBSD, someone would have to fix the
# test suite to work on BSD first.
- "MESON_TEST_ARGS: '' # test suite doesn't work on BSD yet"
test_suites:
- name: touchpad

View file

@ -45,6 +45,7 @@ __all_seats()
'--verbose[Use verbose output]' \
'--show-keycodes[Make all keycodes visible]' \
'--grab[Exclusively grab all opened devices]' \
'--compress-motion-events[Compress repeated motion events on a TTY]' \
'--device=[Use the given device with the path backend]:device:_files -W /dev/input/ -P /dev/input/' \
'--udev=[Listen for notifications on the given seat]:seat:__all_seats' \
'--apply-to=[Apply configuration options where the device name matches the pattern]:pattern' \

View file

@ -29,7 +29,7 @@ MyVendor OEM::
[MyVendor MyModel Touchpad]
MatchName=Foo Bar Touchpad
MatchUdevtype=touchpad
MatchDMIModAlias=dmi:*svnMyVendor:pnMyModel:*
MatchDMIModAlias=dmi:*:svnMyVendor:pnMyModel:*
AttrEventCode=-BTN_RIGHT
The name of the device can be obtained using :ref:`libinput record <libinput-record>`,

View file

@ -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.
@ -199,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.

View 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];
}

View file

@ -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?
------------------------------------------------------------------------------

View file

@ -95,6 +95,7 @@ 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',

View file

@ -124,6 +124,12 @@ button lock, the button is now considered logically held down. Pressing and
releasing the button a second time logically releases the button. While the
button is logically held down, motion events are converted to scroll events.
If the button is held and used to scroll for longer than a short grace
period, releasing the button does not engage the lock. This allows
hold-to-scroll for short, precise adjustments without accidentally toggling
the lock. A quick click or a brief scroll within the grace period still
engages the lock as normal.
.. _scroll_sources:
------------------------------------------------------------------------------

View file

@ -4,9 +4,9 @@
Switches
==============================================================================
libinput supports the lid and tablet-mode switches. Unlike button events
that come in press and release pairs, switches are usually toggled once and
left at the setting for an extended period of time.
libinput supports the lid, tablet-mode, and keypad slide switches. Unlike
button events that come in press and release pairs, switches are usually
toggled once and left at the setting for an extended period of time.
Only some switches are handled by libinput, see **libinput_switch** for a
list of supported switches. Switch events are exposed to the caller, but
@ -59,3 +59,20 @@ tablet mode is disengaged.
This handling of tablet mode switches is transparent to the user, no
notifications are sent and the device appears as enabled at all times.
.. _switches_keypad_slide:
------------------------------------------------------------------------------
Keypad slide switch handling
------------------------------------------------------------------------------
Where available, libinput listens to devices providing a keypad slide switch.
This is usually available on devices that have an always-attached physical
keyboard which can slide under the screen. An example of such a device is the
Nokia N900.
The event sent by the kernel is ``EV_SW`` ``SW_KEYPAD_SLIDE`` and is provided
as **LIBINPUT_SWITCH_KEYPAD_SLIDE**. The keypad slide switch does not cause any
other input devices to be enabled nor disabled in response, since on some
devices the kernel event is sent while the keyboard is partially visible and
thus usable.

View file

@ -53,31 +53,38 @@ Example output of the tool is below: ::
with --touch-thresholds=down:up using observed pressure values.
See --help for more options.
Interactive keys:
q/a - decrease/increase down threshold
w/s - decrease/increase up threshold
e/d - decrease/increase palm threshold
r/f - decrease/increase thumb threshold
Press Ctrl+C to exit
+-------------------------------------------------------------------------------+
| Thresh | 70 | 60 | 130 | 100 | |
+-------------------------------------------------------------------------------+
| Touch | down | up | palm | thumb | min | max | p | avg | median |
+-------------------------------------------------------------------------------+
| 178 | x | x | | | 75 | 75 | 0 | 75 | 75 |
| 179 | x | x | | | 35 | 88 | 0 | 77 | 81 |
| 180 | x | x | | x | 65 | 113 | 0 | 98 | 98 |
| 181 | x | x | | x | 50 | 101 | 0 | 86 | 90 |
| 182 | x | x | | | 40 | 80 | 0 | 66 | 70 |
| 183 | x | | | | 43 | 78 | 78 | |
┌───────────────────────────────────────────────────────────────────────────────┐
│ Touch │ down │ up │ palm │ thumb │ min │ max │ p │ avg │ median │
├───────────────────────────────────────────────────────────────────────────────┤
│ 178 │ x │ x │ │ │ 75 │ 75 │ 0 │ 75 │ 75 │
│ 179 │ x │ x │ │ │ 35 │ 88 │ 0 │ 77 │ 81 │
│ 180 │ x │ x │ │ x │ 65 │ 113 │ 0 │ 98 │ 98 │
│ 181 │ x │ x │ │ x │ 50 │ 101 │ 0 │ 86 │ 90 │
│ 182 │ x │ x │ │ │ 40 │ 80 │ 0 │ 66 │ 70 │
│ 183 │ x │ │ │ │ 43 │ 78 │ 78 │ │
│ Thresh │ 70 │ 60 │ 130 │ 100 │
...
The example output shows five completed touch sequences and one ongoing one.
For each, the respective minimum and maximum pressure values are printed as
well as some statistics. The ``down`` column show that each sequence was
considered logically down at some point, two of the sequences were considered
thumbs. This is an interactive tool and its output may change frequently. Refer
to the **libinput-measure-touchpad-pressure(1)** man page for more details.
considered logically down at some point (see the threholds in the last line),
two of the sequences were considered thumbs. This is an interactive tool and
its output may change frequently. Refer to the
**libinput-measure-touchpad-pressure(1)** man page for more details.
By default, this tool uses the :ref:`device-quirks` for the pressure range. To
narrow down on the best values for your device, specify the 'logically down'
narrow down on the best values for your device, adjust the thresholds using
the keys q/a, w/s, e/d and r/f or specify the 'logically down'
and 'logically up' pressure thresholds with the ``--touch-thresholds``
argument: ::
@ -100,7 +107,7 @@ Once the thresholds are decided on (e.g. 10 and 8), they can be enabled with
[Touchpad pressure override]
MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX230*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX230:*
AttrPressureRange=10:8
AttrPalmPressureThreshold=150
AttrThumbPressureThreshold=100
@ -117,7 +124,7 @@ and product name (pn).
Once in place, run the following command to verify the quirk is valid and
works for your device: ::
$ sudo libinput list-quirks /dev/input/event10
$ sudo libinput quirks list /dev/input/event10
AttrPressureRange=10:8
Replace the event node with the one from your device. If the
@ -199,7 +206,7 @@ Once the thresholds are decided on (e.g. 10 and 8), they can be enabled with
[Touchpad touch size override]
MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX230*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX230:*
AttrTouchSizeRange=10:8
The first line is the match line and should be adjusted for the device name
@ -211,7 +218,7 @@ and product name (pn).
Once in place, run the following command to verify the quirk is valid and
works for your device: ::
$ sudo libinput list-quirks /dev/input/event10
$ sudo libinput quirks list /dev/input/event10
AttrTouchSizeRange=10:8
Replace the event node with the one from your device. If the

View file

@ -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

View file

@ -131,7 +131,7 @@ variation of the following is sufficient:
[Trackpoint Override]
MatchUdevType=pointingstick
MatchName=*TPPS/2 IBM TrackPoint*
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT440p*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadT440p:*
AttrTrackpointMultiplier=1.0

View file

@ -131,7 +131,7 @@ Handled device types
- Mice
- Keyboards
- Virtual absolute pointing devices such as those used by QEMU or VirtualBox
- Switches (Lid Switch and Tablet Mode switch)
- Switches (Lid Switch, Tablet Mode switch, and Keypad Slide switch)
- Graphics tablets
- :ref:`Trackpoints`

View file

@ -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)
/*

View file

@ -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)
/*

View file

@ -1,5 +1,5 @@
project('libinput', 'c',
version : '1.30.0',
version : '1.31.0',
license : 'MIT/Expat',
default_options : [ 'c_std=gnu99', 'warning_level=2' ],
meson_version : '>= 0.64.0')
@ -80,10 +80,11 @@ endif
config_h.set_quoted('HTTP_DOC_LINK', doc_url)
config_h.set('_GNU_SOURCE', '1')
if get_option('buildtype') == 'debug' or get_option('buildtype') == 'debugoptimized'
is_debug_build = get_option('buildtype') == 'debug' or get_option('buildtype') == 'debugoptimized'
if is_debug_build
config_h.set('IS_DEBUG_BUILD', '1')
config_h.set_quoted('MESON_BUILD_ROOT', meson.current_build_dir())
else
config_h.set_quoted('MESON_BUILD_ROOT', '')
endif
prefix = '''#define _GNU_SOURCE 1
@ -222,6 +223,10 @@ if have_libwacom
dependencies: dep_libwacom)
config_h.set('HAVE_LIBWACOM_BUTTON_MODESWITCH_MODE', '1')
endif
if cc.has_function('libwacom_stylus_is_generic',
dependencies: dep_libwacom)
config_h.set('HAVE_LIBWACOM_STYLUS_IS_GENERIC', '1')
endif
else
dep_libwacom = declare_dependency()
endif
@ -758,10 +763,10 @@ executable('ptraccel-debug',
# Don't run the test during a release build because we rely on the magic
# subtool lookup
if get_option('buildtype') == 'debug' or get_option('buildtype') == 'debugoptimized'
if is_debug_build
config_tool_option_test = configuration_data()
config_tool_option_test.set('DISABLE_WARNING', 'yes')
config_tool_option_test.set('MESON_ENABLED_DEBUG_GUI', get_option('debug-gui'))
config_tool_option_test.set('MESON_ENABLED_DEBUG_GUI', get_option('debug-gui').to_string())
config_tool_option_test.set('MESON_BUILD_ROOT', meson.current_build_dir())
config_tool_option_test.set('TOOL_PATH', libinput_tool.full_path())
tool_option_test = configure_file(input: 'tools/test_tool_option_parsing.py',
@ -795,6 +800,13 @@ test('tools-builddir-lookup-installed',
############ tests ############
summary({
'Tests enabled' : get_option('tests'),
'Install tests' : get_option('install-tests'),
},
section : 'Tests',
bool_yn : true)
test('symbols-leak-test',
find_program('test/symbols-leak-test'),
args : [ dir_src / 'libinput.sym', dir_src],
@ -880,6 +892,8 @@ if get_option('tests')
'test/litest-device-format-string.c',
'test/litest-device-generic-pressurepad.c',
'test/litest-device-generic-singletouch.c',
'test/litest-device-generic-usb-keyboard.c',
'test/litest-device-generic-usb-touchpad.c',
'test/litest-device-gpio-keys.c',
'test/litest-device-huion-pentablet.c',
'test/litest-device-huion-q620m-dial.c',
@ -891,6 +905,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',

View file

@ -0,0 +1,121 @@
-- SPDX-License-Identifier: MIT
--
-- This is an example libinput plugin
--
-- This plugin controls a mouse/pointer from a tablet device. This
-- effectively hides stylus interactions and sends pointer events
-- instead. In other words: mouse emulation for tablets, implemented
-- by (remote) controlling a mouse device. This allows using a
-- tablet stylus as a mouse replacement without tablet limitations
-- from compositors or clients. Note that axis usually needed for
-- drawing (like pressure, tilt or distance) are no longer emitted
-- when this plugin is active and a mouse is connected. When no
-- mouse is connected, this plugin doesn't change tablet events,
-- thus the stylus works like a normal stylus.
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
-- libinput:register({1})
-- globals
pointer_device = nil
tablet_device = nil
maximum_x = nil
maximum_y = nil
function adjust_for_aspect_ratio(y)
-- adjust y to match monitor 21:9 aspect ratio
local adj_maximum_y = maximum_x * 1440 / 3440
return math.floor(math.min(y * maximum_y / adj_maximum_y, maximum_y + 1))
end
function on_tablet_frame(device, frame, time_in_microseconds)
-- emit tablet frame when there is no pointer device
if not pointer_device then return nil end
-- map tablet frame to pointer frame
local events = {}
for _, v in ipairs(frame) do
if v.usage == evdev.ABS_MISC then
-- save a few cycles on Wacom tablets by discarding a
-- proximity in / out frame early, non-Wacom tablets should
-- use BTN_TOOL_PEN/RUBBER/... instead
return {}
elseif v.usage == evdev.ABS_X then
table.insert(events, { usage = evdev.ABS_X, value = v.value })
elseif v.usage == evdev.ABS_Y then
-- uncomment the next two lines and comment the original line
-- for configuring aspect correction, see
-- adjust_for_aspect_ratio() for details and configuration
-- local adj_value = adjust_for_aspect_ratio(v.value)
-- table.insert(events, { usage = evdev.ABS_Y, value = adj_value })
table.insert(events, { usage = evdev.ABS_Y, value = v.value })
elseif v.usage == evdev.BTN_TOUCH then
table.insert(events, { usage = evdev.BTN_LEFT, value = v.value })
elseif v.usage == evdev.BTN_STYLUS then
table.insert(events, { usage = evdev.BTN_RIGHT, value = v.value })
elseif v.usage == evdev.BTN_STYLUS2 then
table.insert(events, { usage = evdev.BTN_MIDDLE, value = v.value })
end
end
-- emit pointer frame, if any
if #events > 0 then pointer_device:append_frame(events) end
-- discard tablet frame
return {}
end
function on_tablet_removed(device)
libinput:log_info("Remove tablet device")
tablet_device = nil
end
function on_pointer_removed(device)
libinput:log_info("Remove pointer device")
pointer_device = nil
end
function setup()
if not pointer_device or not tablet_device then return end
libinput:log_info("Controlling '" .. pointer_device:name() .. "' with '" .. tablet_device:name() .. "'")
-- fetch absinfos from tablet
local absinfo_x = {}
local absinfo_y = {}
for a, b in pairs(tablet_device:absinfos()) do
if a == evdev.ABS_X then absinfo_x = b end
if a == evdev.ABS_Y then absinfo_y = b end
end
-- copy max values for aspect ratio correction later on
maximum_x = absinfo_x.maximum
maximum_y = absinfo_y.maximum
-- copy absinfos to pointer device
pointer_device:set_absinfo(evdev.ABS_X, absinfo_x)
pointer_device:set_absinfo(evdev.ABS_Y, absinfo_y)
-- setup listeners
pointer_device:connect("device-removed", on_pointer_removed)
tablet_device:connect("device-removed", on_tablet_removed)
tablet_device:connect("evdev-frame", on_tablet_frame)
end
function on_new_device(device)
local udev = device:udev_properties()
if udev["ID_INPUT_TABLET"] and not udev["ID_INPUT_TABLET_PAD"] then
libinput:log_info("Found tablet device")
tablet_device = device
setup()
end
if udev["ID_INPUT_MOUSE"] then
libinput:log_info("Found pointer device")
pointer_device = device
setup()
end
end
-- setup listener
libinput:connect("new-evdev-device", on_new_device)

View file

@ -8,6 +8,7 @@ plugins = [
'10-disable-feature.lua',
'10-copilot-key-override.lua',
'10-wheel-to-button.lua',
'10-tablet-mouse-control.lua',
]
fs = import('fs')

View file

@ -9,3 +9,23 @@ AttrKeyboardIntegration=internal
MatchUdevType=keyboard
MatchBus=bluetooth
AttrKeyboardIntegration=external
# Detachable devices usually have the tablet part buttons wired as ps2 keyboard,
# don't disable them when tablet-mode switch is in effect.
# DMI Chassis Type 20h (32 decimal) is Detachable as per SMBIOS specification.
[Detachable Device Buttons]
MatchBus=ps2
MatchUdevType=keyboard
MatchDMIModalias=dmi:*:ct32:*
ModelTabletModeNoSuspend=1
# Tablet devices usually have the tablet part buttons wired as ps2 keyboard,
# despite being tablets some of them, e.g. Microsoft Surface Laptop Studio,
# expose tablet-mode switch, so don't disable the ps2 keyboard.
# Tablets that don't expose tablet-mode switch won't have any diference.
# DMI Chassis Type 1Eh (30 decimal) is Tablet as per SMBIOS specification.
[Tablet Device Buttons]
MatchBus=ps2
MatchUdevType=keyboard
MatchDMIModalias=dmi:*:ct30:*
ModelTabletModeNoSuspend=1

View file

@ -1,5 +1,8 @@
# Do not edit this file, it will be overwritten on update
[A4TECH USB X-710BK]
MatchUdevType=mouse
MatchBus=usb
MatchVendor=0x09DA
MatchProduct=0x9090
MatchUdevType=mouse
ModelBouncingKeys=1

View file

@ -0,0 +1,11 @@
# Do not edit this file, it will be overwritten on update
# Touchpad is not a clickpad but INPUT_PROP_BUTTONPAD is set,
# causing libinput to drop physical button events.
[Clevetura CLVX S Touchpad]
MatchUdevType=touchpad
MatchBus=bluetooth
MatchVendor=0x36F7
MatchProduct=0x5755
AttrInputProp=-INPUT_PROP_BUTTONPAD
AttrEventCode=+BTN_RIGHT

View file

@ -1,35 +1,43 @@
# Do not edit this file, it will be overwritten on update
[Contour Design RollerMouse Free 2]
MatchUdevType=mouse
MatchBus=usb
MatchVendor=0x0B33
MatchProduct=0x0401
MatchUdevType=mouse
ModelBouncingKeys=1
[Contour Design RollerMouse Free 3]
MatchUdevType=mouse
MatchBus=usb
MatchVendor=0x0B33
MatchProduct=0x0404
MatchUdevType=mouse
ModelBouncingKeys=1
[Contour Design RollerMouse Re:d]
MatchUdevType=mouse
MatchBus=usb
MatchVendor=0x0B33
MatchProduct=0x1000
MatchUdevType=mouse
ModelBouncingKeys=1
[Contour Design RollerMouse Red v3]
MatchUdevType=mouse
MatchBus=usb
MatchVendor=0x0B33
MatchProduct=0x1004
MatchUdevType=mouse
ModelBouncingKeys=1
[Contour Design RollerMouse Pro3]
MatchUdevType=mouse
MatchBus=usb
MatchVendor=0x0B33
MatchProduct=0x0703
MatchUdevType=mouse
ModelBouncingKeys=1
[Contour Design RollerMouse USB Receiver]
MatchUdevType=mouse
MatchBus=usb
MatchVendor=0x0B33
MatchProduct=0x2000
MatchUdevType=mouse
ModelBouncingKeys=1

View file

@ -1,10 +1,13 @@
# Do not edit this file, it will be overwritten on update
[Cyapa Touchpads]
MatchBus=i2c
MatchUdevType=touchpad
MatchName=*Cypress APA Trackpad ?cyapa?
AttrPressureRange=10:8
[Cypress Touchpads]
MatchBus=ps2
MatchUdevType=touchpad
MatchName=*CyPS/2 Cypress Trackpad
AttrPressureRange=10:8

View file

@ -9,3 +9,11 @@ AttrPressureRange=10:8
MatchName=*Elan Touchpad*
AttrResolutionHint=31x31
AttrPressureRange=10:8
# Elan Hapticpad mostly used in Lenovo laptops.
[Elan Haptic Touchpad (04F3:3355)]
MatchBus=i2c
MatchVendor=0x04F3
MatchProduct=0x3355
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD

View file

@ -1,3 +1,5 @@
# Do not edit this file, it will be overwritten on update
[Glorious Model O]
MatchUdevType=mouse
MatchBus=usb

View file

@ -0,0 +1,63 @@
# Do not edit this file, it will be overwritten on update
# "GXTP5100 Touchpad": pressure touchpad mostly used in Lenovo laptops.
# Match vid and pid as it can have other names.
[Goodix Haptic Touchpad (27C6:01E7)]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x01E7
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD
# "GXTP5100 Touchpad": pressure touchpad mostly used in Lenovo laptops.
# GXTP5100:00 27C6:01E8 Touchpad
[Goodix Haptic Touchpad (27C6:01E8)]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x01E8
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD
# "GXTP5100 Touchpad": pressure touchpad mostly used in Lenovo laptops.
# GXTP5100:00 27C6:01E9 Touchpad
[Goodix Haptic Touchpad (27C6:01E9)]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x01E9
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD
# "GXTP5100 Touchpad": pressure touchpad mostly used in Lenovo laptops.
# GXTP5100:00 27C6:01EA Touchpad
[Goodix Haptic Touchpad (27C6:01EA)]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x01EA
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD
# "GXTP5100 Touchpad": pressure touchpad mostly used in Lenovo laptops.
# GXTP5100:00 27C6:01EB Touchpad
[Goodix Haptic Touchpad (27C6:01EB)]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x01EB
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD
# "GXTP5420 Touchpad": pressure touchpad mostly used in Lenovo laptops.
# GXTP5420:00 27C6:0F95 Touchpad
[Goodix Haptic Touchpad (27C6:0F95)]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x0F95
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD
# "GXTP5420 Touchpad": pressure touchpad mostly used in Lenovo laptops.
[Goodix Haptic Touchpad (27C6:0F90)]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x0F90
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD

View file

@ -0,0 +1,22 @@
# Do not edit this file, it will be overwritten on update
# HTIX3602:00 0911:5288 touchpad, clickpad pretending it has a right button.
# Integrated into several systems, including
# Purism Librem 14v1
# Prestigio Smartbook 141 C2
# StarLite Mk II
# Iota IOTA2320
# with different names
# ALPS0001:00 0911:5288
# HTIX3602:00 0911:5288
# PCT2342:00 0911:5288
# SP3105FT:00 0911:5288
# SYNA3602:00 0911:5288
# Also exist FTSC1000:00 0911:5288 Mouse, so match in type
# is needed to leave mouse button untouched.
[Hantick 0911:5288 Touchpad]
MatchBus=i2c
MatchVendor=0x0911
MatchProduct=0x5288
MatchUdevType=touchpad
AttrEventCode=-BTN_RIGHT

View file

@ -3,5 +3,7 @@
# This will match several vendors that all
# re-use the same vendor ID 256C.
[Huion/Gaomon Tablets]
MatchUdevType=tablet
MatchBus=usb
MatchVendor=0x256C
AttrResolutionHint=205x328

View file

@ -1,47 +0,0 @@
# Do not edit this file, it will be overwritten on update
# IBM/Lenovo Scrollpoint mouse. Instead of a scroll wheel these mice
# feature trackpoint-like sticks which generate a huge amount of scroll
# events that need to be handled differently than scroll wheel events
[IBM ScrollPoint Mouse 3100]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3100
ModelLenovoScrollPoint=1
[IBM ScrollPoint Mouse 3103]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3103
ModelLenovoScrollPoint=1
[IBM ScrollPoint Mouse 3105]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3105
ModelLenovoScrollPoint=1
[IBM ScrollPoint Mouse 3108]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3108
ModelLenovoScrollPoint=1
[IBM ScrollPoint Mouse 3109]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3109
ModelLenovoScrollPoint=1
[IBM ScrollPoint Mouse 6049]
MatchUdevType=mouse
MatchVendor=0x17EF
MatchProduct=0x6049
ModelLenovoScrollPoint=1
[IBM USB Travel Keyboard with Ultra Nav Mouse]
MatchUdevType=pointingstick
MatchVendor=0x04B3
MatchProduct=0x301E
AttrTrackpointMultiplier=1.50

View file

@ -1,9 +1,41 @@
# Do not edit this file, it will be overwritten on update
# Tested on PCSpecialist Recoil 17
[ITE Device(8176) Keyboard]
# ITE keyboards are usb keyboards mostly used in notebook and laptops,
# set as internal.
[ITE Device(8???) Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0x5000
AttrKeyboardIntegration=internal
# Exception used in desktops (external)
[ITE Device(8595) Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0x8295
AttrKeyboardIntegration=external
# Exception used in some desktops and few laptops (external)
[ITE Device(8911) Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0x8911
AttrKeyboardIntegration=external
# Exception used in desktops (external)
[IT8297 RGB LED Controller Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0x8297
AttrKeyboardIntegration=external
# Exception used in desktops (external)
[Corsair Gaming K95 RGB PLATINUM Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0xC935
AttrKeyboardIntegration=external

View file

@ -1,3 +1,5 @@
# Do not edit this file, it will be overwritten on update
# Kensington Orbit claims to have a middle button, same for
[Kensington Orbit Scroll Wheel]
MatchBus=usb

View file

@ -55,10 +55,12 @@ AttrPalmPressureThreshold=400
MatchVendor=0x046D
MatchProduct=0x4041
ModelInvertHorizontalScrolling=1
[Logitech MX Master (4060)]
MatchVendor=0x046D
MatchProduct=0x4060
ModelInvertHorizontalScrolling=1
[Logitech MX Master (4071)]
MatchVendor=0x046D
MatchProduct=0x4071
@ -69,10 +71,12 @@ ModelInvertHorizontalScrolling=1
MatchVendor=0x046D
MatchProduct=0xB012
ModelInvertHorizontalScrolling=1
[Logitech MX Master (Bluetooth B017)]
MatchVendor=0x046D
MatchProduct=0xB017
ModelInvertHorizontalScrolling=1
[Logitech MX Master (Bluetooth B01E)]
MatchVendor=0x046D
MatchProduct=0xB01E

View file

@ -2,7 +2,7 @@
[Microsoft Surface 3 Lid Switch]
MatchName=*Lid Switch*
MatchDMIModalias=dmi:*svnMicrosoftCorporation:pnSurface3:*
MatchDMIModalias=dmi:*:svnMicrosoftCorporation:pnSurface3:*
AttrLidSwitchReliability=write_open
# Matches both Surface Laptop keyboards as well as type covers.
@ -11,15 +11,10 @@ AttrLidSwitchReliability=write_open
# - Surface Laptop 3: Microsoft Surface 045E:09AE Keyboard
# - Surface Book 2: Microsoft Surface Keyboard
[Microsoft Surface Keyboard]
MatchName=*Microsoft Surface *Keyboard*
MatchDMIModalias=dmi:*svnMicrosoftCorporation:*
AttrKeyboardIntegration=internal
[Microsoft Surface Cover]
MatchName=*Microsoft Surface *Cover*
MatchDMIModalias=dmi:*svnMicrosoftCorporation:*
AttrKeyboardIntegration=internal
MatchName=Microsoft Surface *Keyboard
MatchDMIModalias=dmi:*:svnMicrosoftCorporation:*
AttrEventCode=-BTN_0;
AttrKeyboardIntegration=internal
[Microsoft Surface Laptop Studio Touchpad]
MatchVendor=0x045E
@ -28,11 +23,6 @@ MatchUdevType=touchpad
AttrPressureRange=25:10
AttrPalmPressureThreshold=500
[Microsoft Surface Laptop Studio Built-In Peripherals]
MatchName=*Microsoft Surface*
MatchDMIModalias=dmi:*svnMicrosoftCorporation:*pnSurfaceLaptopStudio
ModelTabletModeNoSuspend=1
[Microsoft Nano Transceiver v2.0]
MatchUdevType=mouse
MatchBus=usb

View file

@ -1,7 +1,8 @@
# Do not edit this file, it will be overwritten on update
# 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

View file

@ -1,3 +1,5 @@
# Do not edit this file, it will be overwritten on update
[VirtualBox mouse integration]
MatchName=*VirtualBox mouse integration*
AttrIsVirtual=1

View file

@ -0,0 +1,28 @@
# Do not edit this file, it will be overwritten on update
# GPD Win Max - All versions
# TongFang GX4 (X4SP4NAL)
[Pixart Touchpad (093A:0255)]
MatchBus=i2c
MatchUdevType=touchpad
MatchVendor=0x093A
MatchProduct=0x0255
AttrEventCode=-BTN_RIGHT
# Framework Laptop
# PCSpecialist Recoil 17
[Pixart Touchpad (093A:0274)]
MatchBus=i2c
MatchUdevType=touchpad
MatchVendor=0x093A
MatchProduct=0x0274
AttrEventCode=-BTN_RIGHT
# Chuwi AeroBook Plus
# Chuwi Gemibook
[Pixart Touchpad (093A:1336)]
MatchBus=i2c
MatchUdevType=touchpad
MatchVendor=0x093A
MatchProduct=0x1336
AttrEventCode=-BTN_RIGHT

View file

@ -1,3 +1,5 @@
# Do not edit this file, it will be overwritten on update
[QEMU/KVM mouse integration]
MatchName=*spice vdagent tablet*
AttrIsVirtual=1

View file

@ -2,7 +2,7 @@
[Razer Blade Lid Switch]
MatchName=*Lid Switch*
MatchDMIModalias=dmi:*svnRazer:pnBlade*
MatchDMIModalias=dmi:*:svnRazer:pnBlade*:*
AttrLidSwitchReliability=write_open
# Manually added entries must go above this line.
@ -323,3 +323,10 @@ MatchBus=usb
MatchVendor=0x1532
MatchProduct=0x02C6
AttrKeyboardIntegration=internal
[RazerBlade182025 Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x1532
MatchProduct=0x02C7
AttrKeyboardIntegration=internal

View file

@ -7,13 +7,22 @@ MatchVendor=0x0002
MatchProduct=0x0007
ModelSynapticsSerialTouchpad=1
# SYNA3602:00 0911:5288 touchpad, clickpad pretending it has a right button.
# Integrated into several systems, including
# Purism Librem 14v1
# Prestigio Smartbook 141 C2
# StarLite Mk II
# Iota IOTA2320
[Synaptics 0911:5288 Touchpad]
# "SYNA2B31:00 06CB:CE37 Touchpad": pressure touchpad used in Lenovo laptops.
# also known as
# MSFT0001:00 06CB:CE37
# MSFT0001:01 06CB:CE37
# PNP0C50:01 06CB:CE37
[Synaptics 06CB:CE37 Touchpad]
MatchBus=i2c
MatchVendor=0x06CB
MatchProduct=0xCE37
MatchUdevType=touchpad
MatchName=* 0911:5288 Touchpad
AttrEventCode=-BTN_RIGHT
AttrInputProp=+INPUT_PROP_PRESSUREPAD
# "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

View file

@ -1,3 +1,5 @@
# Do not edit this file, it will be overwritten on update
[Trust GXT 25 Gaming Mouse]
MatchUdevType=mouse
MatchBus=usb

View file

@ -1,9 +0,0 @@
# Do not edit this file, it will be overwritten on update
# Tested on PCSpecialist Recoil 17
[Uniwill Touchpad]
MatchUdevType=touchpad
MatchBus=i2c
MatchVendor=0x093A
MatchProduct=0x0274
AttrEventCode=-BTN_RIGHT

View file

@ -1,9 +1,38 @@
[Acer Switch Alpha 12]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnAcer:pnSwitchSA5-271:*
# Do not edit this file, it will be overwritten on update
[Acer Spin 5 (SP513-52N)]
MatchBus=ps2
MatchUdevType=keyboard
MatchDMIModalias=dmi:*:svnAcer:pnSpinSP513-52N:*
ModelTabletModeNoSuspend=1
[Acer Spin 5]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnAcer:pnSpinSP513-52N:*
ModelTabletModeNoSuspend=1
# Input devices
# These ones are detachable keyboard+touchpad combos, set internal to allow DWT
# Acer Switch Alpha 12 (SA5-271) and (SA5-271P)
# Acer Switch 3 (SW312-31)
[Acer Detachable Keyboard (04F2:1558)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x04F2
MatchProduct=0x1558
AttrKeyboardIntegration=internal
# Acer Switch 7 (SW713-51GNP)
[Acer Detachable Keyboard (06CB:819E)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x06CB
MatchProduct=0x819E
AttrKeyboardIntegration=internal
# Acer Switch Alpha 12 (SA5-271P)
# Acer Switch 3 (SW312-31)
# Acer Switch 5 (SW512-52) and (SW512-52P)
[Acer Detachable Keyboard (06CB:81A7)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x06CB
MatchProduct=0x81A7
AttrKeyboardIntegration=internal

View file

@ -88,6 +88,7 @@ AttrThumbSizeThreshold=700
MatchBus=usb
MatchVendor=0x05AC
MatchProduct=0x0324
AttrSizeHint=162x115
AttrTouchSizeRange=20:10
AttrPressureRange=3:0
AttrPalmSizeThreshold=900

View file

@ -2,12 +2,12 @@
[Asus X555LAB]
MatchName=*ETPS/2 Elantech Touchpad*
MatchDMIModalias=dmi:*svnASUSTeKCOMPUTERINC.:pnX555LAB:*
MatchDMIModalias=dmi:*:svnASUSTeKCOMPUTERINC.:pnX555LAB:*
ModelTouchpadVisibleMarker=1
[Asus UX21E]
MatchName=*ETPS/2 Elantech Touchpad*
MatchDMIModalias=dmi:*svnASUSTeKComputerInc.:pnUX21E:*
MatchDMIModalias=dmi:*:svnASUSTeKComputerInc.:pnUX21E:*
AttrPressureRange=24:10
# Asus UX302LA touchpad doesn't update the pressure values once two
@ -15,39 +15,35 @@ AttrPressureRange=24:10
# at all. https://gitlab.freedesktop.org/libinput/libinput/issues/145
[Asus UX302LA]
MatchName=*ETPS/2 Elantech Touchpad*
MatchDMIModalias=dmi:*svnASUSTeKCOMPUTERINC.:pnUX302LA:*
MatchDMIModalias=dmi:*:svnASUSTeKCOMPUTERINC.:pnUX302LA:*
AttrEventCode=-ABS_MT_PRESSURE;-ABS_PRESSURE;
# Asus VivoBook Flip 14 TP412UA tablet switch seems misbehaving, always
# indicating tablet position
[Asus TP412UA Tablet Mode Switch]
MatchName=*Intel Virtual Button*
MatchDMIModalias=dmi:*svnASUSTeKCOMPUTERINC.:pnVivoBookFlip14_ASUSFlipTP412UA:*
MatchDMIModalias=dmi:*:svnASUSTeKCOMPUTERINC.:pnVivoBookFlip14_ASUSFlipTP412UA:*
ModelTabletModeSwitchUnreliable=1
# keyboard has a different vid/pid to the touchpad
# so libinput won't pair the two together and dwt isn't active.
# see: https://gitlab.freedesktop.org/libinput/libinput/-/issues/615
[Asus ROG Zephyrus G15 2021 keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x0B05
MatchProduct=0x19B6
MatchUdevType=keyboard
AttrKeyboardIntegration=internal
# keyboard has a different vid/pid to the touchpad
# so libinput won't pair the two together and dwt isn't active.
[Asus ROG Strix G15 2021 keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x0B05
MatchProduct=0x1866
MatchUdevType=keyboard
AttrKeyboardIntegration=internal
# don't disable volume buttons in tablet mode
[Asus ROG Flow Z13 2025 volume buttons]
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

View file

@ -1,17 +0,0 @@
# Do not edit this file, it will be overwritten on update
# Acer Hawaii Keyboard, uses Chicony VID
[Acer Hawaii Keyboard]
MatchUdevType=touchpad
MatchBus=usb
MatchVendor=0x04F2
MatchProduct=0x1558
AttrTPKComboLayout=below
# Lenovo MIIX 720 comes with a detachable touchpad-keyboard combo
[Chicony Lenovo MIIX 720 Touchpad]
MatchUdevType=touchpad
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x60A6
AttrTPKComboLayout=below

View file

@ -1,9 +0,0 @@
[Chuwi Gemibook]
MatchName=HTIX5288:00 093A:1336 Touchpad
MatchUdevType=touchpad
AttrEventCode=-BTN_RIGHT
[Chuwi AeroBook Plus]
MatchName=SYNA3602:01 093A:1336 Touchpad
MatchUdevType=touchpad
AttrEventCode=-BTN_RIGHT

View file

@ -2,118 +2,104 @@
[Dell Touchpads]
MatchName=* Touchpad
MatchDMIModalias=dmi:*svnDellInc.:*
MatchDMIModalias=dmi:*:svnDellInc.:*
ModelTouchpadVisibleMarker=1
[Dell i2c Touchpads]
MatchBus=i2c
MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnDellInc.:*
MatchDMIModalias=dmi:*:svnDellInc.:*
AttrMscTimestamp=watch
[Dell Inspiron 15R N5110 Touchpad]
MatchUdevType=touchpad
MatchName=*AlpsPS/2 ALPS GlidePoint
MatchVersion=0x0300
MatchDMIModalias=dmi:*svnDellInc.:*pnInspironN5110*
MatchDMIModalias=dmi:*:svnDellInc.:pnInspironN5110:*
AttrPressureRange=100:95
[Dell Latitude E5510 Touchpad]
MatchUdevType=touchpad
MatchName=*AlpsPS/2 ALPS GlidePoint
MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE5510:*
MatchDMIModalias=dmi:*:svnDellInc.:pnLatitudeE5510:*
AttrPressureRange=100:90
[Dell Latitude E6220 Touchpad]
MatchName=*AlpsPS/2 ALPS GlidePoint
MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE6220:*
MatchDMIModalias=dmi:*:svnDellInc.:pnLatitudeE6220:*
AttrPressureRange=100:90
[Dell XPS L322X Touchpad]
MatchName=*CyPS/2 Cypress Trackpad
MatchDMIModalias=dmi:*svnDell*:*XPSL322X*
# pn can be "XPS L322X" and "Dell System XPS L322X", match both :pn*XPSL322X:.
MatchDMIModalias=dmi:*:svnDellInc.:pn*XPSL322X:*
AttrPressureRange=30:20
AttrPalmPressureThreshold=254
[Dell XPS13 9333 Touchpad]
MatchName=*Synaptics s3203
MatchDMIModalias=dmi:*svnDellInc.:*pnXPS139333*
MatchDMIModalias=dmi:*:svnDellInc.:pnXPS139333:*
AttrPressureRange=15:10
AttrPalmPressureThreshold=150
[Dell XPS 15 9500 Touchpad]
MatchName=* Touchpad
MatchDMIModalias=dmi:*svnDellInc.:pnXPS159500:*
MatchDMIModalias=dmi:*:svnDellInc.:pnXPS159500:*
ModelTouchpadVisibleMarker=0
ModelTouchpadPhantomClicks=1
[Dell Latitude D620 Trackpoint]
MatchName=*DualPoint Stick
MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeD620*
MatchDMIModalias=dmi:*:svnDellInc.:pnLatitudeD620:*
AttrTrackpointMultiplier=0.5
[Latitude E5480 Trackpoint]
MatchName=*DualPoint Stick
MatchUdevType=pointingstick
MatchDMIModalias=dmi:**bvnDellInc.:*:pnLatitude5480*
MatchDMIModalias=dmi:*:svnDellInc.:pnLatitude5480:*
AttrTrackpointMultiplier=0.5
[Latitude 5580 Trackpoint]
MatchName=*DualPoint Stick
MatchUdevType=pointingstick
MatchDMIModalias=dmi:**bvnDellInc.:*:pnLatitude5580*
MatchDMIModalias=dmi:*:svnDellInc.:pnLatitude5580:*
AttrTrackpointMultiplier=0.5
[Latitude E5570 Trackpoint]
MatchName=*DualPoint Stick
MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE5570*
MatchDMIModalias=dmi:*:svnDellInc.:pnLatitudeE5570:*
AttrTrackpointMultiplier=0.1
[Latitude E6320 Trackpoint]
MatchName=*DualPoint Stick
MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE6320*
MatchDMIModalias=dmi:*:svnDellInc.:pnLatitudeE6320:*
AttrTrackpointMultiplier=2.0
[Latitude E6400 Trackpoint]
MatchName=*DualPoint Stick
MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE6400*
MatchDMIModalias=dmi:*:svnDellInc.:pnLatitudeE6400:*
AttrTrackpointMultiplier=1.5
[Latitude E7470 Trackpoint]
MatchName=*DualPoint Stick
MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE7470*
MatchDMIModalias=dmi:*:svnDellInc.:pnLatitudeE7470:*
AttrTrackpointMultiplier=0.125
[Latitude 7275]
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*
MatchDMIModalias=dmi:*:svnDellInc.:pnLatitude7480:*
AttrPressureRange=35:34
[Latitude 7490 Trackpoint]
MatchName=*Mouse
MatchUdevType=pointingstick
MatchDMIModalias=dmi:**bvnDellInc.:*:pnLatitude7490*
MatchDMIModalias=dmi:*:svnDellInc.:pnLatitude7490:*
AttrTrackpointMultiplier=0.3
[Precision 7x50 Touchpad]
MatchBus=i2c
MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnDellInc.:pnPrecision7?50*
MatchDMIModalias=dmi:*:svnDellInc.:pnPrecision7?50:*
AttrInputProp=-INPUT_PROP_BUTTONPAD
# The touch device has the same vid/pid as the totem, the MatchName
@ -125,9 +111,14 @@ MatchVendor=0x2575
MatchProduct=0x0204
ModelDellCanvasTotem=1
[Dell 2-in-1 Models]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*:svnDellInc.:pn*2-in-1:*
# Dell 2-in-1s have DMI Chassis Type Convertible, match it as by name can be
# 2-in-1, 2n1 or even some models miss it in name. Also Dell respect this, even
# if they made a mistake they tend to fix it in firmware updates.
# DMI Chassis Type 1Fh (31 decimal) is Convertible as per SMBIOS specification.
[Dell 2-in-1 Model Buttons]
MatchBus=ps2
MatchUdevType=keyboard
MatchDMIModalias=dmi:*:svnDellInc.:*:ct31:*
ModelTabletModeNoSuspend=1
# This is a true pressurepad so disable pressure for contact size
@ -136,78 +127,78 @@ 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
MatchVendor=0x0488
MatchProduct=0x1063
MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnDellInc.:pnPrecision5480*
MatchDMIModalias=dmi:*:svnDellInc.:pnPrecision5480:*
ModelTouchpadVisibleMarker=0
[Dell laptop 14 Synaptics touchpad]
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
ModelPressurePad=1
AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell 16 Premium DA16250 touchpad]
MatchBus=i2c
MatchVendor=0x0488
MatchProduct=0x108D
ModelPressurePad=1
AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell laptop 14_1 Synaptics touchpad]
MatchBus=i2c
MatchVendor=0x06CB
MatchProduct=0xD01D
ModelPressurePad=1
AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell laptop 16_1 Synaptics touchpad]
MatchBus=i2c
MatchVendor=0x06CB
MatchProduct=0xD01A
ModelPressurePad=1
AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell laptop 14 Sensel touchpad]
MatchBus=i2c
MatchVendor=0x2C2F
MatchProduct=0x0034
ModelPressurePad=1
AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell laptop 16 Sensel touchpad]
MatchBus=i2c
MatchVendor=0x2C2F
MatchProduct=0x0033
ModelPressurePad=1
AttrInputProp=+INPUT_PROP_PRESSUREPAD

View file

@ -1,11 +1,7 @@
[Framework Laptop Touchpad]
MatchName=PIXA3854:00 093A:0274 Touchpad
MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnFramework:pnLaptop*
AttrEventCode=-BTN_RIGHT
# Do not edit this file, it will be overwritten on update
[Framework Laptop 16 Keyboard Module]
MatchName=Framework Laptop 16 Keyboard Module*
MatchUdevType=keyboard
MatchDMIModalias=dmi:*svnFramework:pnLaptop16*
MatchDMIModalias=dmi:*:svnFramework:pnLaptop16*:*
AttrKeyboardIntegration=internal

View file

@ -1,5 +1,15 @@
# Do not edit this file, it will be overwritten on update
[Gigabyte Aero 15 touchpad]
MatchUdevType=touchpad
MatchName=ETPS/2 Elantech Touchpad
MatchDMIModalias=dmi:*svnGIGABYTE:pnAERO15-XA*
MatchDMIModalias=dmi:*:svnGIGABYTE:pnAERO15-XA:*
AttrPalmSizeThreshold=800
[Gigabyte Aorus15BKF keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x0414
MatchProduct=0x7A44
MatchDMIModalias=dmi:*:svnGIGABYTE:pnAORUS15BKF:*
AttrKeyboardIntegration=internal

View file

@ -1,11 +1,7 @@
[GPD Win Max - All versions]
MatchName=HTIX5288:00 093A:0255 Touchpad
MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnGPD:*pnG1619-*
AttrEventCode=-BTN_RIGHT
# Do not edit this file, it will be overwritten on update
[GPD MicroPC 2 Touchpad]
MatchName=ALPS0001:00 36B6:C001 Touchpad
MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnGPD:pnG1688-08:*
MatchDMIModalias=dmi:*:svnGPD:pnG1688-08:*
AttrInputProp=-INPUT_PROP_BUTTONPAD

View file

@ -1,14 +1,16 @@
# Do not edit this file, it will be overwritten on update
# Touchpad is not a clickpad but INPUT_PROP_BUTTONPAD is set
[Synaptics ALPS0001:00 0911:5288 Touchpad]
MatchUdevType=touchpad
MatchName=ALPS0001:00 0911:5288 Touchpad
MatchDMIModalias=dmi:*svn3LogicGroup:*:pnGravitonN15i-K2*:*
MatchDMIModalias=dmi:*:svn3LogicGroup:pnGravitonN15i-K2:*
AttrInputProp=-INPUT_PROP_BUTTONPAD
AttrEventCode=+BTN_RIGHT
[PCTel PCT2342:00 0911:5288 Touchpad]
MatchUdevType=touchpad
MatchName=PCT2342:00 0911:5288 Touchpad
MatchDMIModalias=dmi:*svn3LogicGroup:pnGravitonN15i:*
MatchDMIModalias=dmi:*:svn3LogicGroup:pnGravitonN15i:*
AttrInputProp=-INPUT_PROP_BUTTONPAD
AttrEventCode=+BTN_RIGHT

View file

@ -1,8 +1,10 @@
# Do not edit this file, it will be overwritten on update
# Clickpad that announces BTN_RIGHT
# requires ModelPressurePad=1
# requires AttrInputProp=+INPUT_PROP_PRESSUREPAD
[HONOR MagicBook Art 14]
MatchName=*TOPS0102*
MatchDMIModalias=dmi:*svnHONOR:*pnMRA-XXX*
MatchDMIModalias=dmi:*:svnHONOR:pnMRA-XXX:*
MatchUdevType=touchpad
AttrEventCode=-BTN_RIGHT
ModelPressurePad=1
AttrInputProp=+INPUT_PROP_PRESSUREPAD

View file

@ -1,29 +1,90 @@
# 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]
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnHewlett-Packard:*pnHPCompaq6910p*
MatchDMIModalias=dmi:*:svnHewlett-Packard:pnHPCompaq6910p*:*
AttrEventCode=-BTN_TOOL_DOUBLETAP;-BTN_TOOL_TRIPLETAP;
# Claims to have double/tripletap but doesn't actually send it
# https://bugzilla.redhat.com/show_bug.cgi?id=1351285 and
[HP Compaq 8510w]
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnHewlett-Packard:*pnHPCompaq8510w*
MatchDMIModalias=dmi:*:svnHewlett-Packard:pnHPCompaq8510w*:*
AttrEventCode=-BTN_TOOL_DOUBLETAP;-BTN_TOOL_TRIPLETAP;
[HP Pavilion dmi4]
[HP Elite x2 1013 G3 Tablet Mode Switch]
MatchName=*Intel Virtual Button*
MatchDMIModalias=dmi:*:svnHP:pnHPElitex21013G3:*
ModelTabletModeSwitchUnreliable=1
# The HP OmniBook Ultra Flip 14 toggles tablet mode at a little less than 180
# degrees and hardware switches off inputs at a little more than 180 degrees.
# We don't suspend ourselves to allow using them in flat position. It is
# possible that HP fixes this in the future (i.e. so tablet mode toggles
# after 180 degrees) so check before removing these rules.
# This rule is for the keyboard and...
[HP OmniBook Ultra Flip Laptop 14-fh0xxx and 14t-fh000 Keyboard]
MatchBus=ps2
MatchUdevType=keyboard
MatchDMIModalias=dmi:*:svnHP:*:rn8CDE:*
ModelTabletModeNoSuspend=1
# ...this rule is for the touchpad.
[HP OmniBook Ultra Flip Laptop 14-fh0xxx and 14t-fh000 Touchpad]
MatchBus=i2c
MatchUdevType=touchpad
MatchDMIModalias=dmi:*:svnHP:*:rn8CDE:*
ModelTabletModeNoSuspend=1
AttrPressureRange=15:5
AttrThumbPressureThreshold=80
AttrPalmPressureThreshold=125
[HP Pavilion dm4]
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnHewlett-Packard:*pnHPPaviliondm4NotebookPC*
MatchDMIModalias=dmi:*:svnHewlett-Packard:pnHPPaviliondm4NotebookPC:*
ModelHPPavilionDM4Touchpad=1
[HP Spectre x360 Convertible 15-bl000]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*:svnHP:pnHPSpectrex360Convertible15-bl0XX:*
ModelTabletModeNoSuspend=1
[HP Spectre x360 Convertible 15-bl1xx]
MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*:svnHP:pnHPSpectrex360Convertible15-bl1XX:*
AttrPressureRange=55:40
AttrThumbPressureThreshold=90
AttrPalmPressureThreshold=100
[HP Spectre x360 Convertible 15-ch0xx]
MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*:svnHP:pnHPSpectrex360Convertible15-ch0xx:*
AttrThumbPressureThreshold=90
AttrPalmPressureThreshold=100
# The HP stream x360's embedded-controller filters out events form its builtin
# keyboard when in tablet-mode itself; and it has a volume up/down on the side.
# Do not suspend the keyboard when in tablet-mode so that the volume up/down
# button keeps working when in tablet-mode.
[HP Spectre x360 Convertible 15-ch0xx Tablet Mode Switch]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*:svnHP:pnHPSpectrex360Convertible15-ch0xx:*
ModelTabletModeNoSuspend=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*
MatchDMIModalias=dmi:*:svnHewlett-Packard:pnHPStreamNotebookPC11:*
AttrInputProp=+INPUT_PROP_BUTTONPAD
# The HP stream x360's embedded-controller filters out events form its builtin
@ -36,86 +97,7 @@ 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:*
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
MatchDMIModalias=dmi:*svnHP:pnHPSpectrex360Convertible15-bl1XX:*
AttrPressureRange=55:40
AttrThumbPressureThreshold=90
AttrPalmPressureThreshold=100
[HP Spectre x360 Convertible 15-ch0xx]
MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnHP:pnHPSpectrex360Convertible15-ch0xx:*
AttrThumbPressureThreshold=90
AttrPalmPressureThreshold=100
# The HP stream x360's embedded-controller filters out events form its builtin
# keyboard when in tablet-mode itself; and it has a volume up/down on the side.
# Do not suspend the keyboard when in tablet-mode so that the volume up/down
# button keeps working when in tablet-mode.
[HP Spectre x360 Convertible 15-ch0xx Tablet Mode Switch]
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
[HP Elite x2 1013 G3 Touchpad]
MatchUdevType=touchpad
MatchBus=usb
MatchVendor=0x044E
MatchProduct=0x1221
AttrTPKComboLayout=below
[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
# 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]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnHP:pnHPOmniBookUltraFlipLaptop14-fh0xxx:*
ModelTabletModeNoSuspend=1
# ...this one is for the touchpad.
[HP OmniBook Ultra Flip Laptop 14-fh0xxx Touchpad]
MatchName=SYNA3580:00 06CB:CFD2 Touchpad
MatchDMIModalias=dmi:*svnHP:pnHPOmniBookUltraFlipLaptop14-fh0xxx:*
ModelTabletModeNoSuspend=1

View file

@ -1,21 +1,23 @@
# Do not edit this file, it will be overwritten on update
# Clickpad that announces BTN_RIGHT
# https://bugzilla.redhat.com/show_bug.cgi?id=1972370
[Huawei MateBook 2020 Touchpad]
[Huawei MateBook X 2020 Touchpad]
MatchName=ELAN2604:00 04F3:3114 Touchpad
MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnHUAWEI:*pvrM1010*
MatchDMIModalias=dmi:*:svnHUAWEI:pnEUL-WX9:*
AttrEventCode=-BTN_RIGHT
[Huawei MateBook X Pro 2022 Touchpad]
MatchName=GXTP7863:00 27C6:01E0 Touchpad
MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnHUAWEI:*pnMRGF-XX*
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*
MatchDMIModalias=dmi:*:svnHUAWEI:pnVGHH-XX:*
AttrEventCode=-BTN_RIGHT
ModelPressurePad=1
AttrInputProp=+INPUT_PROP_PRESSUREPAD

View file

@ -1,7 +1,9 @@
# Do not edit this file, it will be overwritten on update
# Touchpad is not a clickpad but INPUT_PROP_BUTTONPAD is set
[Synaptics ALPS0001:00 0911:5288 Touchpad]
MatchUdevType=touchpad
MatchName=ALPS0001:00 0911:5288 Touchpad
MatchDMIModalias=dmi:*svnICL:*:rvnICL:rnSi16:*
MatchDMIModalias=dmi:*:svnICL:*:rnSi16:*
AttrInputProp=-INPUT_PROP_BUTTONPAD
AttrEventCode=+BTN_RIGHT

View file

@ -2,132 +2,240 @@
[Lenovo Thinkpad Touchpad]
MatchName=*Synaptics*
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPad*:*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPad*:*
AttrThumbPressureThreshold=100
[Lenovo x230 Touchpad]
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX230*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX230*:*
ModelLenovoX230=1
[Lenovo T440p Touchpad PS/2]
MatchName=SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT440p*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadT440p:*
ModelLenovoT450Touchpad=1
[Lenovo T440p Touchpad RMI4]
MatchName=Synaptics tm2964-001
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT440p*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadT440p:*
ModelLenovoT450Touchpad=1
[Lenovo T470 Trackpoint]
MatchName=*TPPS/2 IBM TrackPoint
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT470:*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadT470:*
AttrTrackpointMultiplier=0.75
[Lenovo T480 Trackpoint]
MatchName=*TPPS/2 IBM TrackPoint
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT480:*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadT480:*
AttrTrackpointMultiplier=0.75
[Lenovo A485 Trackpoint]
MatchName=*TPPS/2 IBM TrackPoint
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadA485:*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadA485:*
AttrTrackpointMultiplier=0.75
# Touchpad is a clickpad but INPUT_PROP_BUTTONPAD is not set, see
# https://gitlab.freedesktop.org/libinput/libinput/issues/177
[Lenovo T480s Touchpad]
MatchName=Elan Touchpad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT480s*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadT480s:*
AttrInputProp=+INPUT_PROP_BUTTONPAD
# Touchpad is a clickpad but INPUT_PROP_BUTTONPAD is not set, see
# https://gitlab.freedesktop.org/libinput/libinput/issues/177
[Lenovo T490s Touchpad]
MatchName=Elan Touchpad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT490s*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadT490s:*
AttrInputProp=+INPUT_PROP_BUTTONPAD
[Lenovo T490s Trackpoint]
MatchName=*TPPS/2 IBM TrackPoint
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT490s:*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadT490s:*
AttrTrackpointMultiplier=0.4
[Lenovo P14s Gen 1 AMD Trackpoint]
MatchUdevType=pointingstick
MatchName=*TPPS/2 Elan TrackPoint*
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadP14sGen1*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadP14sGen1:*
AttrTrackpointMultiplier=0.4
# Touchpad is a clickpad but INPUT_PROP_BUTTONPAD is not set, see
# https://gitlab.freedesktop.org/libinput/libinput/issues/234
[Lenovo L380 Touchpad]
# NOTE: This was intended for L380 Yoga but was applied before also for normal
# L380. Is needed also for non covertible model?
[Lenovo L380 Yoga Touchpad]
MatchName=Elan Touchpad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadL380*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadL380Yoga:*
AttrInputProp=+INPUT_PROP_BUTTONPAD
[Lenovo X200/201 Trackpoint]
MatchName=*TPPS/2 IBM TrackPoint
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX20?:*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX20?:*
AttrTrackpointMultiplier=0.25
[Lenovo X200s/201s Trackpoint]
MatchName=*TPPS/2 IBM TrackPoint
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX20??:*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX20??:*
AttrTrackpointMultiplier=0.25
[Lenovo X230 Trackpoint]
MatchName=*TPPS/2 IBM TrackPoint
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX230:*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX230:*
AttrTrackpointMultiplier=0.25
[Lenovo X280 Trackpoint]
MatchName=*TPPS/2 Elan TrackPoint
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX280:*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX280:*
AttrTrackpointMultiplier=0.5
[Lenovo X280 Touchpad]
MatchName=Synaptics TM3381-002
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX280*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX280:*
AttrPalmSizeThreshold=6
[Lenovo P50 Touchpad]
MatchName=SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadP50*:
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadP50*:*
ModelLenovoT450Touchpad=1
AttrPalmPressureThreshold=150
[Lenovo *50 Touchpad]
MatchName=SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPad??50*:
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPad??50*:*
ModelLenovoT450Touchpad=1
AttrPalmPressureThreshold=150
[Lenovo *60 Touchpad]
MatchName=SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPad??60*:
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPad??60*:*
ModelLenovoT450Touchpad=1
AttrPalmPressureThreshold=150
[Lenovo X1 Carbon 3rd Touchpad]
MatchName=SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX1Carbon3rd:*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX1Carbon3rd:*
ModelLenovoT450Touchpad=1
AttrPalmPressureThreshold=150
[Lenovo X1 Carbon 4th Trackpoint]
MatchUdevType=pointingstick
MatchName=*TPPS/2 IBM TrackPoint*
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX1Carbon4th*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX1Carbon4th:*
AttrTrackpointMultiplier=0.5
[Lenovo X1 Carbon 6th Trackpoint]
MatchUdevType=pointingstick
MatchName=*TPPS/2 Elan TrackPoint*
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX1Carbon6th*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX1Carbon6th:*
AttrTrackpointMultiplier=0.4
# Don't disable keys accessible in tablet mode, #106799 comment 7
[Lenovo Thinkpad S1 Yoga and S1 Yoga 12]
MatchBus=ps2
MatchUdevType=keyboard
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadS1Yoga*:*
ModelTabletModeNoSuspend=1
# Don't disable keys accessible in tablet mode, #103749
[Lenovo Thinkpad X1 Yoga 1st]
MatchBus=ps2
MatchUdevType=keyboard
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX1Yoga1st:*
ModelTabletModeNoSuspend=1
[Lenovo X1 Yoga Trackpoint 1st gen]
MatchName=*TPPS/2 IBM TrackPoint
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX1Yoga1st:*
AttrTrackpointMultiplier=1.25
[Lenovo Yoga C930 Tablet]
MatchBus=i2c
MatchVendor=0x056A
MatchProduct=0x5196
AttrTabletSmoothing=1
# Lenovo Carbon X1 6th gen (RMI4 only, PS/2 is broken on this device,
# sends bogus ABS_MT_TOOL_TYPE events for MT_TOOL_PALM
[Lenovo Carbon X1 6th gen]
MatchName=Synaptics TM3288-011
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX1Carbon6th:*
AttrEventCode=-ABS_MT_TOOL_TYPE
ModelLenovoX1Gen6Touchpad=1
# IBM ThinkPad X41 Tablet identify itself as DMI Chassis Type: 0Ah 10 Notebook
# but it's really a convertible one and have buttons wired as ps2 keyboard,
# don't disable them when tablet-mode switch is in effect.
[IBM ThinkPad X41 Tablet Buttons]
MatchUdevType=keyboard
MatchBus=ps2
MatchDMIModalias=dmi:*:svnIBM:*:pvrThinkPadX41Tablet:*
ModelTabletModeNoSuspend=1
# Lenovo ThinkPad X60 X61 X200 X201 X220 X230 Tablets identify themselves as
# DMI Chassis Type: 0Ah 10 Notebook but they are really convertibles ones and
# have buttons wired as ps2 keyboard, don't disable them when tablet-mode switch
# is in effect.
[Lenovo ThinkPad X Tablet Series Buttons]
MatchUdevType=keyboard
MatchBus=ps2
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX*Tablet:*
ModelTabletModeNoSuspend=1
# Modifies pressure range to avoid random jumps.
# https://gitlab.freedesktop.org/libinput/libinput/-/issues/407
[Lenovo Yoga 2 Pro touchpad]
MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrLenovoYoga2Pro:*
AttrPressureRange=50:45
[Lenovo ThinkPad E14 Gen 2]
MatchUdevType=touchpad
MatchName=*Elan Touchpad
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
[Lenovo Thinkpad Yoga X390]
MatchUdevType=pointingstick
MatchName=*TPPS/2 Elan TrackPoint*
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX390Yoga*:*
AttrTrackpointMultiplier=0.4
# Lenovo Yoga Slim 7i Carbon sends bogus ABS_MT_TOOL_TYPE MT_TOOL_PALM events
[Lenovo Yoga Slim 7i Carbon]
MatchName=* Touchpad
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrYogaSlim7Carbon13IAP7:*
AttrEventCode=-ABS_MT_TOOL_TYPE
# Lenovo detachable devices prior to SMBIOS 3.0.0 specficiation (2015-02-12)
# when Tablet, Convertible and Detachable Chassis Types didn't exist use Hand
# Held. e.g. First Miix devices till Lenovo MIIX 300-10IBY (80NR) and initial
# firmware versions of Lenovo MIIX 310-10ICR (80SG).
# Match chassis and *MIIX* Product Version.
# DMI Chassis Type 0Bh (11 decimal) is Hand Held as per SMBIOS specification.
[Lenovo 1st Convertible Device Buttons]
MatchBus=ps2
MatchUdevType=keyboard
MatchDMIModalias=dmi:*:svnLENOVO:*:pvr*MIIX*:*:ct11:*
ModelTabletModeNoSuspend=1
# Match also *Miix* Product Version.
[Lenovo 1st Convertible Device Buttons 2]
MatchBus=ps2
MatchUdevType=keyboard
MatchDMIModalias=dmi:*:svnLENOVO:*:pvr*Miix*:*:ct11:*
ModelTabletModeNoSuspend=1
# Input devices
[Lenovo ThinkPad Compact USB Keyboard with TrackPoint (keyboard)]
MatchUdevType=keyboard
MatchBus=usb
@ -142,284 +250,259 @@ MatchVendor=0x17EF
MatchProduct=0x6047
AttrPointingStickIntegration=external
# Lenovo Thinkpad Yoga (not the consumer versions) disables the keyboard
# mechanically. We must not disable the keyboard because some keys are
# still accessible on the screen and volume rocker.
# Initially #103749 and extended by #106799 comment 7
[Lenovo Thinkpad Yoga]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPad*Yoga*:*
ModelTabletModeNoSuspend=1
# IBM/Lenovo Scrollpoint mouse. Instead of a scroll wheel these mice
# feature trackpoint-like sticks which generate a huge amount of scroll
# events that need to be handled differently than scroll wheel events
[Lenovo X1 Yoga Trackpoint 1st gen]
MatchName=*TPPS/2 IBM TrackPoint
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX1Yoga1st:*
AttrTrackpointMultiplier=1.25
[IBM ScrollPoint Mouse 3100]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3100
ModelLenovoScrollPoint=1
# A true pressurepad so let's not use pressure for contact size
# https://gitlab.freedesktop.org/libinput/libinput/-/issues/562
[Lenovo Yoga 9i Pressurepad]
MatchBus=i2c
MatchVendor=0x06CB
MatchProduct=0xCE37
ModelPressurePad=1
[IBM ScrollPoint Mouse 3103]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3103
ModelLenovoScrollPoint=1
[Lenovo Yoga C930 Tablet]
MatchBus=i2c
MatchVendor=0x056A
MatchProduct=0x5196
AttrTabletSmoothing=1
[IBM ScrollPoint Mouse 3105]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3105
ModelLenovoScrollPoint=1
# Lenovo Carbon X1 6th gen (RMI4 only, PS/2 is broken on this device,
# sends bogus ABS_MT_TOOL_TYPE events for MT_TOOL_PALM
[Lenovo Carbon X1 6th gen]
MatchName=Synaptics TM3288-011
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX1Carbon6th:*
AttrEventCode=-ABS_MT_TOOL_TYPE
ModelLenovoX1Gen6Touchpad=1
[IBM ScrollPoint Mouse 3108]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3108
ModelLenovoScrollPoint=1
[Lenovo X41 Tablet]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnIBM:*pvrThinkPadX41Tablet:*
ModelTabletModeNoSuspend=1
[IBM ScrollPoint Mouse 3109]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3109
ModelLenovoScrollPoint=1
[Lenovo X60 Tablet]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX60Tablet:*
ModelTabletModeNoSuspend=1
[Lenovo ScrollPoint Mouse 6049]
MatchUdevType=mouse
MatchVendor=0x17EF
MatchProduct=0x6049
ModelLenovoScrollPoint=1
[Lenovo X61 Tablet]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX61Tablet:*
ModelTabletModeNoSuspend=1
# Lenovo X220 Tablet special bezel buttons are associated to the
# keyboard and would therefore mistakenly be deactivated as well.
# See https://gitlab.freedesktop.org/libinput/libinput/issues/154
[Lenovo X220 Tablet]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX220Tablet:*
ModelTabletModeNoSuspend=1
# Special bezel button deactivation with
# keyboard also applies to X230 Tablet
[Lenovo X230 Tablet]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX230Tablet:*
ModelTabletModeNoSuspend=1
# Special bezel button deactivation with
# keyboard also applies to X200 Tablet
[Lenovo X200 Tablet]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX200Tablet:*
ModelTabletModeNoSuspend=1
[Lenovo X201 Tablet]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX201Tablet:*
ModelTabletModeNoSuspend=1
# Lenovo MIIX 720 comes with a detachable keyboard. We must not disable
# the keyboard because some keys are still accessible on the screen and
# volume rocker. See
# https://gitlab.freedesktop.org/libinput/libinput/issues/115
[Lenovo MIIX 720]
MatchName=AT Raw Set 2 keyboard
MatchDMIModalias=dmi:*svnLENOVO:*pvrLenovoMIIX720-12IKB:*
ModelTabletModeNoSuspend=1
# Lenovo ThinkPad X1 Tablet (1st Gen) also comes with a detachable keyboard.
# We must not disable the keyboard because some keys are still accessible on
# volume rocker.
[Lenovo ThinkPad X1 Tablet (1st Gen)]
MatchName=AT Raw Set 2 keyboard
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX1Tablet:*
ModelTabletModeNoSuspend=1
# Misidentified as an external keyboard by libinput
# Tested on Legion 5 15AR05H
[Lenovo Legion 5 Keyboard (C100)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0xC100
AttrKeyboardIntegration=internal
# Tested on Legion 5 15ARH7H, should also work for Legion 5 Pro 16ARH7H
# 048d:c102 Integrated Technology Express, Inc. ITE Device(8910)
[Lenovo Legion 5 Keyboard (C102)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0xC102
AttrKeyboardIntegration=internal
# Tested on Legion Pro 5 16IRX8
# 048d:c103 Integrated Technology Express, Inc. ITE Device(8910)
[Lenovo Legion 5 Keyboard (C103)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0xC103
AttrKeyboardIntegration=internal
[Lenovo Legion 5 Keyboard (C955)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0xC955
AttrKeyboardIntegration=internal
# Tested on Lenovo Legion 5 Pro 16ACH6H
[Lenovo Legion 5 Pro Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0xC101
AttrKeyboardIntegration=internal
[Lenovo Legion 5i Keyboard]
MatchName=ITE Tech. Inc. ITE Device(8910) Keyboard
MatchDMIModalias=dmi:*svnLENOVO:*pvrLegion515IAH7H:*
AttrKeyboardIntegration=internal
[Lenovo Legion 7 Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0xC968
AttrKeyboardIntegration=internal
[Lenovo Legion Y740 Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0xC936
AttrKeyboardIntegration=internal
[Lenovo Legion Slim 7]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0xC967
AttrKeyboardIntegration=internal
[Lenovo Legion Slim 7 Gen 8]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0xC987
AttrKeyboardIntegration=internal
# https://gitlab.freedesktop.org/libinput/libinput/-/issues/604
[Lenovo Yoga Slim 9 14ITL5 Pressurepad]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x01E8
ModelPressurePad=1
# Duet 7i tablet switch activated by folding keyboard cover, or removing it.
# We must not disable volume rocker 'keyboard'.
[Lenovo Duet 7i]
MatchName=AT Raw Set 2 keyboard
MatchDMIModalias=dmi:*svnLENOVO:*pvrYogaDuet713IML05:*
ModelTabletModeNoSuspend=1
# Lenovo IdeaPad Duet 3 also comes with a detachable keyboard.
[Lenovo IdeaPad Duet 3]
MatchName=AT Raw Set 2 keyboard
MatchDMIModalias=dmi:*svnLENOVO:*pvrIdeaPadDuet3*:*
ModelTabletModeNoSuspend=1
# Modifies pressure range to avoid random jumps.
# https://gitlab.freedesktop.org/libinput/libinput/-/issues/407
[Lenovo Yoga 2 Pro touchpad]
MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrLenovoYoga2Pro*
AttrPressureRange=50:45
[Lenovo Legion 7i 4090 Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchDMIModalias=dmi:*svnLENOVO:*:pvrLegionY9000PIRX8H*
AttrKeyboardIntegration=internal
[Lenovo LOQ 15IRH8 Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0xC986
AttrKeyboardIntegration=internal
[Lenovo ThinkPad E14 v2]
MatchUdevType=touchpad
MatchName=*Elan Touchpad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadE14Gen2*
AttrPalmPressureThreshold=300
AttrPressureRange=10:8
[Lenovo ThinkPad E16 Gen 3]
[IBM USB Travel Keyboard with Ultra Nav Mouse]
MatchUdevType=pointingstick
MatchName=*TPPS/2 Elan TrackPoint*
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadE16Gen3*
AttrTrackpointMultiplier=0.5
MatchVendor=0x04B3
MatchProduct=0x301E
AttrTrackpointMultiplier=1.50
# White Backlit Keyboard
[Lenovo Ideapad Gaming 3]
# The following ones correspond to detachable keyboard+touchpad combos used in
# Lenovo detachable devices. Names can vary within the same ids and some are
# repeated over different devices. They're mostly connected over USB bus through
# pogo pins and we need to set the keyboard as internal to achieve DWT.
# We could also do it matching the touchpad and setting AttrTPKComboLayout=below
# but this combos are tied to the structure of the device they are designed for.
# At least some of them affect lid switch state when closed while attached.
# Found in:
# Lenovo MIIX 320-10ICR (80XF)
# Known names:
# "HAILUCK CO.,LTD Lenovo HID Device" in 80XF
# "HTX USB HID Device HTX HID Device Keyboard" in 80XF
# "SIPODEV Lenovo HID Device" in 80XF
[Lenovo Detachable Keyboard (048D:8911)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0xC966
MatchProduct=0x8911
AttrKeyboardIntegration=internal
[Lenovo Thinkpad Yoga X390]
MatchUdevType=pointingstick
MatchName=*TPPS/2 Elan TrackPoint*
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX390Yoga*:*
AttrTrackpointMultiplier=0.4
# This should cover all keyboards that are misidentified as external.
# Tested on Lenovo Legion 5 Pro (2023)
[Lenovo 16ARX8 keyboard]
MatchName=ITE Tech. Inc. ITE Device(8910) Keyboard
# Found in:
# Lenovo MIIX 510-12ISK (80U1)
# Lenovo MIIX 510-12IKB (80XE)
# Known names:
# "SIPODEV Lenovo HID Device" in 80U1 and 80XE
[Lenovo Detachable Keyboard (04F2:1622)]
MatchUdevType=keyboard
MatchDMIModalias=dmi:*svnLENOVO:*
MatchBus=usb
MatchVendor=0x04F2
MatchProduct=0x1622
AttrKeyboardIntegration=internal
# Some ThinkBook 14/16 G7+ ASP models come with pressure pads that were not
# correctly declared as such.
[Lenovo ThinkBook G7+ ASP touchpad]
MatchName=*GXTP5100*
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkBook*G7+ASP*:*
MatchUdevType=touchpad
ModelPressurePad=1
# Found in:
# Lenovo MIIX 3-1030 (80HV)
# Known names:
# "Lenovo Lenovo Miix 3 1030 USB Keyboard" in 80HV
[Lenovo Detachable Keyboard (17EF:606E)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x606E
AttrKeyboardIntegration=internal
# 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
# Found in:
# Lenovo MIIX 700-121SK (80QL)
# Known names:
# "Lenovo ideapad MIIX 700 USB keyboard" in 80QL
[Lenovo Detachable Keyboard (17EF:60A2)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x60A2
AttrKeyboardIntegration=internal
# Lenovo Yoga Slim 7i Carbon sends bogus ABS_MT_TOOL_TYPE MT_TOOL_PALM events
[Lenovo Yoga Slim 7i Carbon]
MatchName=* Touchpad
MatchDMIModalias=dmi:*:svnLENOVO:*pvrYogaSlim7Carbon13IAP7:*
AttrEventCode=-ABS_MT_TOOL_TYPE
# Found in:
# Lenovo MIIX 720-12IKB (80VV)
# Known names:
# "Chicony Lenovo MIIX 720" in 80VV
[Lenovo Detachable Keyboard (17EF:60A6)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x60A6
AttrKeyboardIntegration=internal
# The ThinkPad X9 15 Gen 1 Forcepad touchpad is not
# detected as a pressure pad
[Lenovo ThinkPad X9 15 Gen 1]
MatchName=*GXTP5100*
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX9-15Gen1*:*
MatchUdevType=touchpad
ModelPressurePad=1
# Found in:
# Lenovo MIIX 720-12IKB (80VV)
# Known names:
# "Chicony Lenovo MIIX 720" in 80VV
[Lenovo Detachable Keyboard (17EF:60A7)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x60A7
AttrKeyboardIntegration=internal
# 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
# Found in:
# Lenovo MIIX 510-12IKB (80XE)
# Lenovo MIIX 520-12IKB (20M3), (20M4) and (81CG)
# Known names:
# "SIPODEV Lenovo HID Device" in 80XE, 20M3, 20M4 and 81CG
[Lenovo Detachable Keyboard (17EF:60BB)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x60BB
AttrKeyboardIntegration=internal
# Found in:
# Lenovo IdeaPad D330-10IGM (81H3) and (81MD)
# Lenovo IdeaPad D330-10IGL (82H0)
# Known names:
# "SIPODEV Lenovo HID Device" in 81H3, 81MD and 82H0
[Lenovo Detachable Keyboard (17EF:60C3)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x60C3
AttrKeyboardIntegration=internal
# Found in:
# Lenovo IdeaPad D330-10IGM (81H3) and (81MD)
# Known names:
# "HAILUCK CO.,LTD Lenovo HID Device" in 81H3 and 81MD
[Lenovo Detachable Keyboard (17EF:60C6)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x60C6
AttrKeyboardIntegration=internal
# Found in:
# Lenovo IdeaPad D330-10IGL (82H0)
# Known names:
# "HAILUCK CO.,LTD Lenovo HID Device" in 82H0
[Lenovo Detachable Keyboard (17EF:60C8)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x60C8
AttrKeyboardIntegration=internal
# Found in:
# Lenovo IdeaPad Duet3 10IGL5 (82AT)
# Lenovo IdeaPad Duet3 10IGL5-LTE (82HK)
# Known names:
# "HAILUCK CO.,LTD Duet 3 USB Composite Device" in 82AT and 82HK
[Lenovo Detachable Keyboard (17EF:60FA) USB]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x60FA
AttrKeyboardIntegration=internal
# Found in:
# Lenovo IdeaPad Duet3 10IGL5 (82AT)
# Known names:
# "Duet 3 BT Keyboard" in 82AT
# "Lenovo Duet 3 BT Folio Keyboard" in 82AT
[Lenovo Detachable Keyboard (17EF:60FA) BT]
MatchUdevType=keyboard
MatchBus=bluetooth
MatchVendor=0x17EF
MatchProduct=0x60FA
AttrKeyboardIntegration=internal
# Found in:
# Lenovo IdeaPad Duet3 10IGL5 (82AT)
# Known names:
# "SIPODEV Duet 3 USB Composite Device" in 82AT
[Lenovo Detachable Keyboard (17EF:60FB)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x60FB
AttrKeyboardIntegration=internal
# Found in:
# Lenovo IdeaPad Duet 5 12IAU7 (82TQ)
# Known names:
# "DOKING Duet 5 USB Composite Device" in 82TQ
[Lenovo Detachable Keyboard (17EF:6139)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x6139
AttrKeyboardIntegration=internal
# Found in:
# Lenovo IdeaPad Duet 5 12IAU7 (82TQ)
# Lenovo XiaoXinDuet IAU7 (82TQ)
# Known names:
# "DOKING Duet 5 USB Composite Device" in 82TQ
[Lenovo Detachable Keyboard (17EF:613A)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x613A
AttrKeyboardIntegration=internal
# Found in:
# Lenovo IdeaPad Duet3 11IAN8 (82XK)
# Known names:
# "SINO WEALTH USB Composite Device Keyboard" in 82XK
[Lenovo Detachable Keyboard (17EF:6169)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x6169
AttrKeyboardIntegration=internal
# Found in:
# Lenovo MIIX 300-10IBY (80NR)
# Lenovo MIIX 310-10ICR (80SG)
# Lenovo MIIX 510-12ISK (80U1)
# Lenovo MIIX 510-12IKB (80XE)
# As non detachable in:
# DEXP NAVIS M100
# Insyde B14
# Known names:
# "SINO WEALTH USB Composite Device" in 80NR
# "SIPODEV USB Composite Device" in 80SG
# "SIPODEV Lenovo HID Device" in 80U1, 80XE, NAVIS M100 and B14
[Lenovo Detachable Keyboard (258A:1015)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x258A
MatchProduct=0x1015
AttrKeyboardIntegration=internal

View file

@ -2,5 +2,5 @@
[LG gram 14 2023 Touchpad]
MatchName=* Touchpad
MatchDMIModalias=dmi:*svnLGElectronics:pn14Z90R-G.AA79G:*
MatchDMIModalias=dmi:*:svnLGElectronics:pn14Z90R-G.AA79G:*
ModelTouchpadPhantomClicks=1

View file

@ -1,11 +1,15 @@
# Do not edit this file, it will be overwritten on update
[Minisforum V3 volume keys]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnMicroComputer(HK)TechLimited:pnV3:*
ModelTabletModeNoSuspend=1
[Minisforum V3 touchpad dwt]
MatchName=USB Keyboard
MatchDMIModalias=dmi:*svnMicroComputer(HK)TechLimited:pnV3:*
[Minisforum V3 Detachable Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x05AF
MatchProduct=0x326A
AttrKeyboardIntegration=internal
[Minisforum V3 SE Detachable Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x1C4F
MatchProduct=0x00B8
AttrKeyboardIntegration=internal

View file

@ -1,3 +1,5 @@
# Do not edit this file, it will be overwritten on update
[PineBook Pro Keyboard]
MatchVendor=0x258A
MatchProduct=0x001E

View file

@ -3,5 +3,5 @@
[Sony Vaio VPCEG Series Touchpad Pressure Override]
MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnSonyCorporation:pnVPCEG*
MatchDMIModalias=dmi:*:svnSonyCorporation:pnVPCEG*:*
AttrPressureRange=45:40

View file

@ -1,6 +1,8 @@
# Do not edit this file, it will be overwritten on update
[Star Labs Touchpad]
MatchName=*Touchpad
MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnStarLabs:*
MatchDMIModalias=dmi:*:svnStarLabs:*
AttrEventCode=-BTN_RIGHT
AttrInputProp=+INPUT_PROP_BUTTONPAD

View file

@ -1,21 +1,21 @@
# Do not edit this file, it will be overwritten on update
[System76 Bonobo Professional]
[System76 Bonobo Professional]
MatchName=SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnSystem76*pvrbonp5*
MatchDMIModalias=dmi:*:svnSystem76:*:pvrbonp5:*
ModelSystem76Bonobo=1
[System76 Clevo]
[System76 Clevo]
MatchName=SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*pnW740SU*rnW740SU*
MatchDMIModalias=dmi:*:pnW740SU:*:rnW740SU:*
ModelClevoW740SU=1
[System76 Galago Ultra Pro]
[System76 Galago Ultra Pro]
MatchName=SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnSystem76*pvrgalu1*
MatchDMIModalias=dmi:*:svnSystem76:*:pvrgalu1:*
ModelSystem76Galago=1
[System76 Kudu Professional]
[System76 Kudu Professional]
MatchName=SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnSystem76*pvrkudp1*
MatchDMIModalias=dmi:*:svnSystem76:*:pvrkudp1:*
ModelSystem76Kudu=1

View file

@ -1,5 +0,0 @@
[TongFang GX4 (X4SP4NAL) Touchpad]
MatchName=UNIW0001:00 093A:0255 Touchpad
MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnAiStone:pnX4SP4NAL:*
AttrEventCode=-BTN_RIGHT

View file

@ -1,4 +1,7 @@
# Do not edit this file, it will be overwritten on update
# Can't find no Satellite with all uppercase in DMI.
[Toshiba Satellite L855-14E Touchpad]
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnTOSHIBA:pnSATELLITEL855*
MatchDMIModalias=dmi:*:svnTOSHIBA:pnSATELLITEL855:*
AttrPressureRange=45:44

View file

@ -1,5 +0,0 @@
[Positivo-Vaio Touchpad]
MatchName=SYNA3602:00 0911:5288 Touchpad
MatchDMIModalias=dmi:*svnPositivoBahia-VAIO:pnVJ[FP][EWX]*
MatchUdevType=touchpad
AttrEventCode=+BTN_RIGHT

View file

@ -82,10 +82,10 @@ files will not be used.
Debugging
---------
When modifying a data file, use the `libinput list-quirks` tool to
When modifying a data file, use the `libinput quirks list` tool to
verify the changes. The tool can be pointed at the data directory to
analyse, use `--verbose` to get more info. For example:
```
libinput list-quirks --data-dir /path/to/git/repo/quirks/ --verbose /dev/input/event0
libinput quirks list --data-dir /path/to/git/repo/quirks/ --verbose /dev/input/event0
```

View file

@ -36,6 +36,7 @@
static inline bool
builddir_lookup(char **builddir)
{
#ifdef IS_DEBUG_BUILD
char execdir[PATH_MAX];
char *pathsep;
ssize_t nread;
@ -65,4 +66,7 @@ builddir_lookup(char **builddir)
*builddir = safe_strdup(execdir);
return true;
#else
return false;
#endif
}

View file

@ -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;
@ -171,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;
@ -205,7 +208,7 @@ 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)
{
if (!libinput_device_has_capability(&device->base, LIBINPUT_DEVICE_CAP_POINTER))
return;
@ -322,7 +325,7 @@ fallback_flush_wheels(struct fallback_dispatch *dispatch,
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;
@ -340,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;
@ -379,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;
@ -409,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;
@ -437,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;
@ -464,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;
@ -500,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;
@ -522,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;
@ -547,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;
@ -572,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 |=
@ -583,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)
@ -625,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];
@ -726,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);
@ -741,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));
@ -765,7 +768,7 @@ fallback_lid_keyboard_event(uint64_t time, struct libinput_event *event, void *d
static void
fallback_lid_toggle_keyboard_listener(struct fallback_dispatch *dispatch,
struct evdev_paired_keyboard *kbd,
struct evdev_paired_device *kbd,
bool is_closed)
{
assert(kbd->device);
@ -786,7 +789,7 @@ static void
fallback_lid_toggle_keyboard_listeners(struct fallback_dispatch *dispatch,
bool is_closed)
{
struct evdev_paired_keyboard *kbd;
struct evdev_paired_device *kbd;
list_for_each(kbd, &dispatch->lid.paired_keyboard_list, link) {
if (!kbd->device)
@ -800,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;
@ -833,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;
}
@ -841,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:
@ -876,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;
@ -915,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);
@ -959,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;
@ -1030,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;
@ -1098,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;
@ -1138,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);
@ -1152,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;
@ -1183,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);
@ -1233,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);
@ -1257,7 +1274,7 @@ static void
fallback_interface_remove(struct evdev_dispatch *evdev_dispatch)
{
struct fallback_dispatch *dispatch = fallback_dispatch(evdev_dispatch);
struct evdev_paired_keyboard *kbd;
struct evdev_paired_device *kbd;
libinput_timer_cancel(&dispatch->debounce.timer);
libinput_timer_cancel(&dispatch->debounce.timer_short);
@ -1266,7 +1283,7 @@ fallback_interface_remove(struct evdev_dispatch *evdev_dispatch)
libinput_device_remove_event_listener(&dispatch->tablet_mode.other.listener);
list_for_each_safe(kbd, &dispatch->lid.paired_keyboard_list, link) {
evdev_paired_keyboard_destroy(kbd);
evdev_paired_device_destroy(kbd);
}
}
@ -1275,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;
@ -1303,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;
@ -1328,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 };
@ -1347,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:
@ -1388,7 +1412,7 @@ fallback_lid_pair_keyboard(struct evdev_device *lid_switch,
struct evdev_device *keyboard)
{
struct fallback_dispatch *dispatch = fallback_dispatch(lid_switch->dispatch);
struct evdev_paired_keyboard *kbd;
struct evdev_paired_device *kbd;
size_t count = 0;
if ((keyboard->tags & EVDEV_TAG_KEYBOARD) == 0 ||
@ -1441,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;
@ -1527,7 +1549,7 @@ fallback_interface_device_removed(struct evdev_device *device,
struct evdev_device *removed_device)
{
struct fallback_dispatch *dispatch = fallback_dispatch(device->dispatch);
struct evdev_paired_keyboard *kbd;
struct evdev_paired_device *kbd;
list_for_each_safe(kbd, &dispatch->lid.paired_keyboard_list, link) {
if (!kbd->device)
@ -1536,7 +1558,7 @@ fallback_interface_device_removed(struct evdev_device *device,
if (kbd->device != removed_device)
continue;
evdev_paired_keyboard_destroy(kbd);
evdev_paired_device_destroy(kbd);
}
if (removed_device == dispatch->tablet_mode.other.sw_device) {
@ -1733,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;

View file

@ -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);

View file

@ -139,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),
@ -248,6 +249,7 @@ evdev_usage_name(evdev_usage_t usage)
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);
@ -330,9 +332,9 @@ evdev_usage_is_button(evdev_usage_t usage)
case EVDEV_BTN_TOOL_FINGER:
case EVDEV_BTN_TOUCH:
return false;
case BTN_STYLUS:
case BTN_STYLUS2:
case BTN_STYLUS3:
case EVDEV_BTN_STYLUS:
case EVDEV_BTN_STYLUS2:
case EVDEV_BTN_STYLUS3:
return true;
case EVDEV_BTN_MISC ... EVDEV_BTN_DIGI - 1:
case EVDEV_BTN_WHEEL ... EVDEV_BTN_GEAR_UP:
@ -392,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),
@ -405,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);
@ -432,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[];
};
@ -485,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;
@ -548,10 +550,12 @@ evdev_frame_append(struct evdev_frame *frame,
size_t nevents)
{
assert(nevents > 0);
int syn_report_value = 0;
for (size_t i = 0; i < nevents; i++) {
if (evdev_usage_eq(events[i].usage, EVDEV_SYN_REPORT)) {
nevents = i;
syn_report_value = events[i].value;
break;
}
}
@ -566,14 +570,24 @@ evdev_frame_append(struct evdev_frame *frame,
frame->count += nevents;
}
frame->events[frame->count - 1] = (struct evdev_event){
.usage = evdev_usage_from_uint32_t(EVDEV_SYN_REPORT),
.value = syn_report_value,
};
return 0;
}
static inline int
evdev_frame_append_one(struct evdev_frame *frame, evdev_usage_t usage, int32_t value)
{
if (evdev_usage_eq(usage, EVDEV_SYN_REPORT))
if (evdev_usage_eq(usage, EVDEV_SYN_REPORT)) {
frame->events[frame->count - 1] = (struct evdev_event){
.usage = evdev_usage_from_uint32_t(EVDEV_SYN_REPORT),
.value = value,
};
return 0;
}
if (frame->count >= frame->max_size)
return -ENOMEM;
@ -590,7 +604,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);

View file

@ -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);

View file

@ -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,7 +1228,7 @@ 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;
@ -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)

View file

@ -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;

File diff suppressed because it is too large Load diff

View file

@ -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);
}

View file

@ -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

View file

@ -38,13 +38,15 @@
#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 */
#define MOUSE_HAS_SENT_EVENTS bit(1)
enum notify {
DONT_NOTIFY,
DO_NOTIFY,
@ -62,7 +64,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 };
@ -79,7 +81,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 };
@ -96,7 +98,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 };
@ -115,13 +117,11 @@ tp_filter_scroll(struct tp_dispatch *tp,
}
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)
@ -149,15 +149,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;
@ -181,10 +182,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)
@ -201,11 +201,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;
}
@ -323,7 +323,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)
@ -358,7 +358,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;
@ -382,7 +382,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:
@ -427,7 +427,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,
@ -441,7 +441,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;
}
@ -450,14 +450,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);
@ -505,7 +505,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);
@ -560,9 +560,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);
@ -590,7 +588,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;
@ -624,7 +622,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;
@ -677,7 +675,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;
@ -709,7 +707,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)
@ -740,12 +738,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;
}
@ -831,7 +829,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;
@ -847,8 +845,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,
@ -863,7 +861,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;
@ -877,8 +875,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,
@ -891,7 +889,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;
@ -908,16 +906,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))
@ -935,7 +932,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;
@ -965,7 +962,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;
@ -988,7 +985,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)) {
@ -1035,7 +1032,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;
@ -1052,7 +1049,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;
@ -1063,7 +1060,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;
@ -1139,7 +1136,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;
@ -1223,7 +1220,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;
@ -1263,7 +1260,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;
@ -1317,7 +1314,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);
@ -1403,17 +1400,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
@ -1436,7 +1433,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. */
@ -1446,7 +1443,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
@ -1455,7 +1453,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,
@ -1496,9 +1495,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;
@ -1514,12 +1513,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;
@ -1553,15 +1553,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;
@ -1569,13 +1569,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,
@ -1593,7 +1593,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:
@ -1602,7 +1604,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;
@ -1624,7 +1626,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;
@ -1735,7 +1737,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;
@ -1769,7 +1771,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;
@ -1820,7 +1822,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);
@ -1858,7 +1860,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);
@ -1889,7 +1891,7 @@ 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);
@ -1918,7 +1920,7 @@ tp_interface_process(struct evdev_dispatch *dispatch,
static void
tp_remove_sendevents(struct tp_dispatch *tp)
{
struct evdev_paired_keyboard *kbd;
struct evdev_paired_device *kbd, *mouse;
libinput_timer_cancel(&tp->palm.trackpoint_timer);
libinput_timer_cancel(&tp->dwt.keyboard_timer);
@ -1930,6 +1932,10 @@ tp_remove_sendevents(struct tp_dispatch *tp)
libinput_device_remove_event_listener(&kbd->listener);
}
list_for_each_safe(mouse, &tp->sendevents.external_mice_list, link) {
evdev_paired_device_destroy(mouse);
}
if (tp->lid_switch.lid_switch)
libinput_device_remove_event_listener(&tp->lid_switch.listener);
@ -1941,12 +1947,12 @@ static void
tp_interface_remove(struct evdev_dispatch *dispatch)
{
struct tp_dispatch *tp = tp_dispatch(dispatch);
struct evdev_paired_keyboard *kbd;
struct evdev_paired_device *kbd;
libinput_timer_cancel(&tp->arbitration.arbitration_timer);
list_for_each_safe(kbd, &tp->dwt.paired_keyboard_list, link) {
evdev_paired_keyboard_destroy(kbd);
evdev_paired_device_destroy(kbd);
}
tp->dwt.keyboard_active = false;
@ -1969,6 +1975,7 @@ tp_interface_destroy(struct evdev_dispatch *dispatch)
libinput_timer_destroy(&tp->gesture.finger_count_switch_timer);
libinput_timer_destroy(&tp->gesture.hold_timer);
libinput_timer_destroy(&tp->gesture.drag_3fg_timer);
libinput_timer_destroy(&tp->gesture.drag_3fg_or_swipe_timer);
free(tp->touches);
free(tp);
}
@ -1982,7 +1989,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.
@ -2106,7 +2113,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;
@ -2118,7 +2125,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;
@ -2136,7 +2143,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;
}
@ -2146,18 +2153,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;
@ -2219,11 +2226,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;
@ -2272,12 +2279,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
@ -2305,7 +2312,7 @@ static void
tp_dwt_pair_keyboard(struct evdev_device *touchpad, struct evdev_device *keyboard)
{
struct tp_dispatch *tp = (struct tp_dispatch *)touchpad->dispatch;
struct evdev_paired_keyboard *kbd;
struct evdev_paired_device *kbd;
size_t count = 0;
if ((keyboard->tags & EVDEV_TAG_KEYBOARD) == 0)
@ -2363,7 +2370,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;
@ -2388,7 +2395,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;
@ -2530,24 +2537,60 @@ tp_pair_tablet(struct evdev_device *touchpad, struct evdev_device *tablet)
}
}
static void
tp_external_mouse_event(usec_t time, struct libinput_event *event, void *data)
{
struct tp_dispatch *tp = data;
if (event->type < LIBINPUT_EVENT_POINTER_MOTION ||
event->type >= LIBINPUT_EVENT_TOUCH_DOWN)
return;
struct libinput_device *libinput_device = libinput_event_get_device(event);
struct evdev_device *device = (struct evdev_device *)libinput_device;
struct evdev_paired_device *paired;
list_for_each(paired, &tp->sendevents.external_mice_list, link) {
if (paired->device == device) {
paired->flags |= MOUSE_HAS_SENT_EVENTS;
/* In theory we should be waiting for a neutral state here but
* that's hopefully niche enough. tp_suspend() clears our state
* anyway.
*/
if (tp->sendevents.current_mode ==
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
tp_suspend(tp, tp->device, SUSPEND_EXTERNAL_MOUSE);
break;
}
}
}
static void
tp_pair_external_mouse(struct evdev_device *touchpad, struct evdev_device *mouse)
{
struct tp_dispatch *tp = (struct tp_dispatch *)touchpad->dispatch;
if (!(mouse->tags & EVDEV_TAG_EXTERNAL_MOUSE))
return;
struct evdev_paired_device *paired = zalloc(sizeof(*paired));
paired->device = mouse;
libinput_device_add_event_listener(&mouse->base,
&paired->listener,
tp_external_mouse_event,
tp);
list_insert(&tp->sendevents.external_mice_list, &paired->link);
}
static void
tp_interface_device_added(struct evdev_device *device,
struct evdev_device *added_device)
{
struct tp_dispatch *tp = (struct tp_dispatch *)device->dispatch;
tp_pair_trackpoint(device, added_device);
tp_dwt_pair_keyboard(device, added_device);
tp_pair_lid_switch(device, added_device);
tp_pair_tablet_mode_switch(device, added_device);
tp_pair_tablet(device, added_device);
if (tp->sendevents.current_mode !=
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
return;
if (added_device->tags & EVDEV_TAG_EXTERNAL_MOUSE)
tp_suspend(tp, device, SUSPEND_EXTERNAL_MOUSE);
tp_pair_external_mouse(device, added_device);
}
static void
@ -2555,7 +2598,7 @@ tp_interface_device_removed(struct evdev_device *device,
struct evdev_device *removed_device)
{
struct tp_dispatch *tp = (struct tp_dispatch *)device->dispatch;
struct evdev_paired_keyboard *kbd;
struct evdev_paired_device *kbd, *mouse;
if (removed_device == tp->buttons.trackpoint) {
/* Clear any pending releases for the trackpoint */
@ -2572,7 +2615,7 @@ tp_interface_device_removed(struct evdev_device *device,
list_for_each_safe(kbd, &tp->dwt.paired_keyboard_list, link) {
if (kbd->device == removed_device) {
evdev_paired_keyboard_destroy(kbd);
evdev_paired_device_destroy(kbd);
tp->dwt.keyboard_active = false;
}
}
@ -2589,21 +2632,18 @@ tp_interface_device_removed(struct evdev_device *device,
tp_resume(tp, device, SUSPEND_TABLET_MODE);
}
if (tp->sendevents.current_mode ==
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE) {
struct libinput_device *dev;
bool found = false;
list_for_each(dev, &device->base.seat->devices_list, link) {
struct evdev_device *d = evdev_device(dev);
if (d != removed_device &&
(d->tags & EVDEV_TAG_EXTERNAL_MOUSE)) {
found = true;
break;
}
bool have_external_mouse_sending_events = false;
list_for_each_safe(mouse, &tp->sendevents.external_mice_list, link) {
if (mouse->device == removed_device) {
evdev_paired_device_destroy(mouse);
} else if (mouse->flags & MOUSE_HAS_SENT_EVENTS) {
have_external_mouse_sending_events = true;
}
if (!found)
tp_resume(tp, device, SUSPEND_EXTERNAL_MOUSE);
}
if (tp->sendevents.current_mode ==
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE &&
!have_external_mouse_sending_events) {
tp_resume(tp, device, SUSPEND_EXTERNAL_MOUSE);
}
if (removed_device == tp->left_handed.tablet_device) {
@ -2638,6 +2678,22 @@ evdev_tag_touchpad(struct evdev_device *device, struct udev_device *udev_device)
int bustype, vendor;
const char *prop;
prop = udev_device_get_property_value(udev_device, "ID_INTEGRATION");
if (prop) {
if (streq(prop, "internal")) {
evdev_tag_touchpad_internal(device);
return;
}
if (streq(prop, "external")) {
evdev_tag_touchpad_external(device);
return;
}
evdev_log_info(device, "tagged with unknown value %s\n", prop);
}
/* Fall back to ID_TOUCHPAD_INTEGRATION if ID_INTEGRATION is missing */
prop = udev_device_get_property_value(udev_device,
"ID_INPUT_TOUCHPAD_INTEGRATION");
if (prop) {
@ -2694,7 +2750,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;
@ -2707,7 +2763,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);
@ -2730,7 +2786,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;
}
}
@ -2938,12 +2994,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,
@ -3032,7 +3088,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;
@ -3170,6 +3226,36 @@ 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 usec_t
tp_dwt_config_get_default_timeout(struct libinput_device *device)
{
return DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2;
}
static int
tp_dwtp_config_is_available(struct libinput_device *device)
{
@ -3222,6 +3308,36 @@ 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 usec_t
tp_dwtp_config_get_default_timeout(struct libinput_device *device)
{
return DEFAULT_TRACKPOINT_ACTIVITY_TIMEOUT;
}
static inline bool
tp_is_tpkb_combo_below(struct evdev_device *device)
{
@ -3258,7 +3374,11 @@ 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.config.get_default_timeout = tp_dwt_config_get_default_timeout;
tp->dwt.dwt_enabled = tp_dwt_default_enabled(tp);
tp->dwt.timeout = tp_dwt_config_get_default_timeout(&device->base);
device->base.config.dwt = &tp->dwt.config;
}
@ -3274,6 +3394,10 @@ 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.config.get_default_timeout = tp_dwtp_config_get_default_timeout;
tp->palm.timeout = tp_dwtp_config_get_default_timeout(&device->base);
device->base.config.dwtp = &tp->palm.config;
}
@ -3414,6 +3538,8 @@ tp_init_sendevents(struct tp_dispatch *tp, struct evdev_device *device)
{
char timer_name[64];
list_init(&tp->sendevents.external_mice_list);
snprintf(timer_name,
sizeof(timer_name),
"%s trackpoint",
@ -3622,8 +3748,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);
}
@ -3655,7 +3781,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*/

View file

@ -166,6 +166,8 @@ enum tp_gesture_state {
GESTURE_STATE_PINCH,
GESTURE_STATE_SWIPE_START,
GESTURE_STATE_SWIPE,
GESTURE_STATE_3FG_DRAG_OR_SWIPE_START,
GESTURE_STATE_3FG_DRAG_OR_SWIPE,
GESTURE_STATE_3FG_DRAG_START,
GESTURE_STATE_3FG_DRAG,
GESTURE_STATE_3FG_DRAG_RELEASED,
@ -194,7 +196,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 +215,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 +248,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 +269,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 +346,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 +363,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 +372,9 @@ struct tp_dispatch {
bool hold_enabled;
struct libinput_timer drag_3fg_timer;
uint64_t drag_3fg_release_time;
usec_t drag_3fg_release_time;
struct libinput_timer drag_3fg_or_swipe_timer;
} gesture;
struct {
@ -421,9 +425,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 +440,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 +461,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 +470,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;
@ -481,11 +486,14 @@ struct tp_dispatch {
struct {
struct libinput_device_config_send_events config;
enum libinput_config_send_events_mode current_mode;
struct list external_mice_list;
} sendevents;
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 +506,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 +537,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 +622,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 +641,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 +667,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 +686,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 +707,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 +728,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 +767,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);

View file

@ -30,9 +30,7 @@
#include "evdev.h"
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;
@ -47,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 */

View file

@ -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;
@ -310,7 +310,7 @@ pad_dial_get_mode_group(struct pad_dispatch *pad, unsigned int dial)
evdev_log_bug_libinput_ratelimit(pad->device,
&pad->modes.group_not_found,
"Unable to find mode group for dial %d",
"Unable to find mode group for dial %d\n",
dial);
return NULL;
@ -329,7 +329,7 @@ pad_ring_get_mode_group(struct pad_dispatch *pad, unsigned int ring)
evdev_log_bug_libinput_ratelimit(pad->device,
&pad->modes.group_not_found,
"Unable to find mode group for ring %d",
"Unable to find mode group for ring %d\n",
ring);
return NULL;
@ -348,7 +348,7 @@ pad_strip_get_mode_group(struct pad_dispatch *pad, unsigned int strip)
evdev_log_bug_libinput_ratelimit(pad->device,
&pad->modes.group_not_found,
"Unable to find mode group for strip %d",
"Unable to find mode group for strip %d\n",
strip);
return NULL;
@ -357,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;
@ -452,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;
@ -481,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)
{
@ -537,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;
@ -565,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);
@ -594,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);
@ -629,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);
@ -822,7 +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, h2us(1), 3);
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 */
@ -842,7 +842,7 @@ 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);
#ifdef HAVE_LIBWACOM
if (wacom)

View file

@ -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:
@ -1142,8 +1142,8 @@ tablet_get_quirked_pressure_thresholds(struct tablet_dispatch *tablet, int *hi,
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (q && quirks_get_range(q, QUIRK_ATTR_PRESSURE_RANGE, &r)) {
if (r.lower < r.upper) {
*hi = r.lower;
*lo = r.upper;
*lo = r.lower;
*hi = r.upper;
status = true;
} else {
evdev_log_info(device,
@ -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
@ -1308,18 +1311,6 @@ eraser_button_get_default_mode(struct libinput_tablet_tool *tool)
static enum libinput_config_status
eraser_button_set_button(struct libinput_tablet_tool *tool, uint32_t button)
{
switch (button) {
case BTN_STYLUS:
case BTN_STYLUS2:
case BTN_STYLUS3:
break;
default:
log_bug_libinput(libinput_device_get_context(tool->last_device),
"Unsupported eraser button 0x%x",
button);
return LIBINPUT_CONFIG_STATUS_INVALID;
}
tool->eraser_button.want_button = button;
eraser_button_toggle(tool);
@ -1330,7 +1321,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
@ -1519,7 +1510,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 +1544,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)
{
@ -1914,7 +1905,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 };
@ -1938,7 +1929,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;
@ -1966,7 +1957,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)) {
@ -1986,7 +1977,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,
@ -2036,7 +2027,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;
@ -2066,7 +2057,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,
@ -2091,7 +2082,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 };
@ -2128,7 +2119,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;
@ -2203,7 +2194,7 @@ update_pressure_range(struct tablet_dispatch *tablet,
}
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;
@ -2287,7 +2278,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;
@ -2309,7 +2300,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 };
@ -2356,7 +2347,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);
@ -2392,7 +2383,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);
@ -2407,7 +2398,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);
@ -2448,6 +2439,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);
}

View file

@ -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++) {

View file

@ -53,7 +53,8 @@
#endif
#define DEFAULT_WHEEL_CLICK_ANGLE 15
#define DEFAULT_BUTTON_SCROLL_TIMEOUT ms2us(200)
#define DEFAULT_BUTTON_SCROLL_TIMEOUT usec_from_millis(200)
#define SCROLL_BUTTON_LOCK_GRACE_TIMEOUT usec_from_millis(500)
enum evdev_device_udev_tags {
EVDEV_UDEV_TAG_NONE = 0,
@ -167,7 +168,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 +180,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 +206,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 +214,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.
@ -228,6 +229,15 @@ evdev_button_scroll_button(struct evdev_device *device, uint64_t time, int is_pr
break; /* handle event */
case BUTTONSCROLL_LOCK_FIRSTDOWN:
assert(!is_press);
if (device->scroll.button_scroll_state == BUTTONSCROLL_SCROLLING &&
usec_cmp(usec_delta(time, device->scroll.button_down_time),
SCROLL_BUTTON_LOCK_GRACE_TIMEOUT) >= 0) {
/* held + scrolled past grace period: temporary scroll,
* no lock engaged */
device->scroll.lock_state = BUTTONSCROLL_LOCK_IDLE;
evdev_log_debug(device, "scroll lock: temp scroll done\n");
break; /* pass release through */
}
device->scroll.lock_state = BUTTONSCROLL_LOCK_FIRSTUP;
evdev_log_debug(device, "scroll lock: first up\n");
return; /* filter release event */
@ -265,9 +275,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 +325,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 +405,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 +430,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 +455,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 +471,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)
{
@ -488,6 +499,7 @@ static void
evdev_tag_trackpoint(struct evdev_device *device, struct udev_device *udev_device)
{
char *prop;
const char *udev_prop;
if (!libevdev_has_property(device->evdev, INPUT_PROP_POINTING_STICK) &&
!parse_udev_flag(device, udev_device, "ID_INPUT_POINTINGSTICK"))
@ -495,10 +507,22 @@ evdev_tag_trackpoint(struct evdev_device *device, struct udev_device *udev_devic
device->tags |= EVDEV_TAG_TRACKPOINT;
udev_prop = udev_device_get_property_value(udev_device, "ID_INTEGRATION");
if (udev_prop) {
if (streq(udev_prop, "internal")) {
/* noop, this is the default anyway */
} else if (streq(udev_prop, "external"))
device->tags |= EVDEV_TAG_EXTERNAL_MOUSE;
else
evdev_log_info(device,
"tagged with unknown value %s\n",
udev_prop);
}
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (q && quirks_get_string(q, QUIRK_ATTR_TRACKPOINT_INTEGRATION, &prop)) {
if (streq(prop, "internal")) {
/* noop, this is the default anyway */
device->tags &= ~EVDEV_TAG_EXTERNAL_MOUSE;
} else if (streq(prop, "external")) {
device->tags |= EVDEV_TAG_EXTERNAL_MOUSE;
evdev_log_info(device, "is an external pointing stick\n");
@ -526,6 +550,7 @@ static void
evdev_tag_keyboard(struct evdev_device *device, struct udev_device *udev_device)
{
char *prop;
const char *udev_prop;
int code;
if (!libevdev_has_event_type(device->evdev, EV_KEY))
@ -536,6 +561,18 @@ evdev_tag_keyboard(struct evdev_device *device, struct udev_device *udev_device)
return;
}
udev_prop = udev_device_get_property_value(udev_device, "ID_INTEGRATION");
if (udev_prop) {
if (streq(udev_prop, "internal"))
evdev_tag_keyboard_internal(device);
else if (streq(udev_prop, "external"))
evdev_tag_keyboard_external(device);
else
evdev_log_info(device,
"tagged with unknown value %s\n",
udev_prop);
}
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (q && quirks_get_string(q, QUIRK_ATTR_KEYBOARD_INTEGRATION, &prop)) {
if (streq(prop, "internal")) {
@ -1014,7 +1051,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 +1059,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,
@ -1999,6 +2037,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");
}
@ -2308,11 +2351,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);
@ -2670,6 +2713,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;
}
@ -2697,7 +2743,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)
{
@ -2771,7 +2817,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 };

View file

@ -80,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 {
@ -218,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 */
@ -278,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;
};
@ -297,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);
@ -336,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.
@ -344,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,
@ -552,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);
@ -578,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
@ -618,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);
@ -969,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
@ -1008,19 +1011,20 @@ evdev_device_check_abs_axis_range(struct evdev_device *device,
}
}
struct evdev_paired_keyboard {
struct evdev_paired_device {
struct list link;
struct evdev_device *device;
struct libinput_event_listener listener;
uint32_t flags; /* generic flags used by the caller */
};
static inline void
evdev_paired_keyboard_destroy(struct evdev_paired_keyboard *kbd)
evdev_paired_device_destroy(struct evdev_paired_device *device)
{
kbd->device = NULL;
libinput_device_remove_event_listener(&kbd->listener);
list_remove(&kbd->link);
free(kbd);
device->device = NULL;
libinput_device_remove_event_listener(&device->listener);
list_remove(&device->link);
free(device);
}
static inline bool

View file

@ -29,12 +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;
uint64_t last_delta_time;
usec_t last_time;
usec_t last_delta_time;
double step;
size_t npoints;
double points[];
@ -58,7 +58,7 @@ 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;
@ -79,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,
@ -121,10 +121,11 @@ custom_accel_function_calculate_speed(struct custom_accel_function *cf,
* Reusing the last delta_time is a graceful fallback even if there are
* duplicate events or event-ordering bugs.
*/
uint64_t delta_time =
(time > cf->last_time) ? time - cf->last_time : cf->last_delta_time;
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 (delta_time > MOTION_TIMEOUT)
if (usec_cmp(delta_time, MOTION_TIMEOUT) > 0)
delta_time = FIRST_MOTION_TIME_INTERVAL;
/* speed is in device-units per ms */
@ -196,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);
@ -252,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;
@ -263,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 */
}
@ -347,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,
@ -358,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,
@ -370,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);
}
@ -379,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,
@ -391,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);
}
@ -400,7 +401,7 @@ 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,

View file

@ -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;
@ -65,7 +65,7 @@ static struct normalized_coords
accelerator_filter_constant_flat(struct motion_filter *filter,
const struct device_float_coords *unaccelerated,
void *data,
uint64_t time)
usec_t time)
{
/* We map the unaccelerated flat filter to have the same behavior as
* the "accelerated" flat filter.
@ -85,7 +85,7 @@ static struct normalized_coords
accelerator_filter_scroll_flat(struct motion_filter *filter,
const struct device_float_coords *unaccelerated,
void *data,
uint64_t time,
usec_t time,
enum filter_scroll_type type)
{
/* Scroll wheels were not historically accelerated and have different

View file

@ -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;
@ -148,7 +148,7 @@ static struct normalized_coords
accelerator_filter_constant(struct motion_filter *filter,
const struct device_float_coords *unaccelerated,
void *data,
uint64_t time)
usec_t time)
{
const struct normalized_coords normalized = {
.x = unaccelerated->x,
@ -161,14 +161,14 @@ static struct normalized_coords
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 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;
@ -198,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;

View file

@ -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;
@ -136,7 +136,7 @@ static struct normalized_coords
accelerator_filter_constant(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;
@ -147,7 +147,7 @@ static struct normalized_coords
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)
{
/* Scroll wheels were not historically accelerated and have different
@ -165,7 +165,7 @@ accelerator_filter_scroll(struct motion_filter *filter,
}
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;
@ -192,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;
@ -210,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 */

View file

@ -34,19 +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,
usec_t time,
enum filter_scroll_type type);
void (*restart)(struct motion_filter *filter, void *data, uint64_t time);
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,
@ -60,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;
@ -100,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,
@ -118,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
@ -135,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;
}

View file

@ -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;

View file

@ -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;
@ -69,7 +69,7 @@ accelerator_filter_constant_touchpad_flat(
struct motion_filter *filter,
const struct device_float_coords *unaccelerated,
void *data,
uint64_t time)
usec_t time)
{
/* We map the unaccelerated flat filter to have the same behavior as
* the "accelerated" flat filter.
@ -89,7 +89,7 @@ static struct normalized_coords
accelerator_filter_scroll_touchpad_flat(struct motion_filter *filter,
const struct device_float_coords *unaccelerated,
void *data,
uint64_t time,
usec_t time,
enum filter_scroll_type type)
{
/* Scroll wheels were not historically accelerated and have different

View file

@ -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;
@ -189,7 +189,7 @@ static struct normalized_coords
accelerator_filter_scroll_x230(struct motion_filter *filter,
const struct device_float_coords *unaccelerated,
void *data,
uint64_t time,
usec_t time,
enum filter_scroll_type type)
{
/* Scroll wheels were not historically accelerated and have different
@ -207,7 +207,7 @@ accelerator_filter_scroll_x230(struct motion_filter *filter,
}
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;
@ -216,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;
@ -249,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;
@ -267,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

View file

@ -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;
@ -166,7 +166,7 @@ static struct normalized_coords
touchpad_scroll_filter(struct motion_filter *filter,
const struct device_float_coords *unaccelerated,
void *data,
uint64_t time,
usec_t time,
enum filter_scroll_type type)
{
/* Scroll wheels were not historically accelerated and have different
@ -184,7 +184,7 @@ touchpad_scroll_filter(struct motion_filter *filter,
}
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;
@ -204,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;
@ -301,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;

View file

@ -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;
@ -63,7 +63,7 @@ static struct normalized_coords
trackpoint_flat_filter_constant(struct motion_filter *filter,
const struct device_float_coords *unaccelerated,
void *data,
uint64_t time)
usec_t time)
{
/* We map the unaccelerated flat filter to have the same behavior as
* the "accelerated" flat filter.
@ -83,7 +83,7 @@ static struct normalized_coords
trackpoint_flat_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)
{
/* Scroll wheels were not historically accelerated and have different

View file

@ -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;
@ -100,7 +100,7 @@ static struct normalized_coords
trackpoint_accelerator_filter_constant(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;
@ -116,7 +116,7 @@ static struct normalized_coords
trackpoint_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)
{
/* Scroll wheels were not historically accelerated and have different
@ -174,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;
@ -231,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;
}

View file

@ -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,7 +59,7 @@ 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,
@ -70,7 +70,7 @@ filter_dispatch_scroll(struct motion_filter *filter,
}
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);
@ -132,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;
@ -153,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;
@ -184,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
@ -212,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);
}
@ -224,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;
@ -239,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,
@ -302,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;

View file

@ -66,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.
@ -88,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.
@ -112,11 +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);
@ -132,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,
@ -150,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 *
@ -181,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 */

View file

@ -136,7 +136,7 @@ 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;
@ -222,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
@ -295,7 +296,7 @@ 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:
@ -318,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:
@ -354,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:
@ -383,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:
@ -407,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:
@ -435,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:
@ -467,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:
@ -496,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:
@ -522,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:
@ -547,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:
@ -571,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;
@ -632,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;
@ -734,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;
@ -742,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;

View file

@ -116,6 +116,8 @@ struct libinput_lua_plugin {
struct libinput_plugin_timer *timer;
bool in_timer_func;
usec_t lua_pcall_timeout_end;
};
static struct libinput_lua_plugin *
@ -291,12 +293,34 @@ out:
lua_pop(L, 1);
}
static void
lua_timeout_hook(lua_State *L, lua_Debug *debug)
{
struct libinput_lua_plugin *plugin = lua_get_libinput_lua_plugin(L);
struct libinput *libinput = lua_get_libinput(L);
usec_t now = libinput_now(libinput);
if (usec_cmp(now, plugin->lua_pcall_timeout_end) > 0) {
luaL_error(L, "Plugin execution timeout (exceeded 1 second)");
}
}
static bool
libinput_lua_pcall(struct libinput_lua_plugin *plugin, int narg, int nres)
{
lua_State *L = plugin->L;
struct libinput *libinput = lua_get_libinput(L);
plugin->lua_pcall_timeout_end = usec_add_millis(libinput_now(libinput), 1000);
/* Hook is called every 10M instructions (10-1000ms, depending operations) */
lua_sethook(L, lua_timeout_hook, LUA_MASKCOUNT, 10000000);
int rc = lua_pcall(L, narg, nres, 0);
/* Clear the hook */
lua_sethook(L, NULL, 0, 0);
plugin->lua_pcall_timeout_end = usec_from_millis(0);
if (rc != LUA_OK) {
auto libinput_plugin = plugin->parent;
const char *errormsg = lua_tostring(L, -1);
@ -408,7 +432,8 @@ libinput_lua_plugin_evdev_frame(struct libinput_plugin *libinput_plugin,
lua_rawgeti(plugin->L, LUA_REGISTRYINDEX, evdev->frame_refid);
lua_rawgeti(plugin->L, LUA_REGISTRYINDEX, evdev->refid);
lua_push_evdev_frame(plugin->L, frame);
lua_pushinteger(plugin->L, evdev_frame_get_time(frame));
lua_pushinteger(plugin->L,
usec_as_uint64_t(evdev_frame_get_time(frame)));
if (!libinput_lua_pcall(plugin, 3, 1))
return;
@ -464,9 +489,9 @@ libinputplugin_now(lua_State *L)
luaL_argcheck(L, p != NULL, 1, PLUGIN_METATABLE " expected");
struct libinput *libinput = lua_get_libinput(L);
uint64_t now = libinput_now(libinput);
usec_t now = libinput_now(libinput);
lua_pushinteger(L, now);
lua_pushinteger(L, usec_as_uint64_t(now));
return 1;
}
@ -555,19 +580,19 @@ libinputplugin_gc(lua_State *L)
}
static void
plugin_timer_func(struct libinput_plugin *libinput_plugin, uint64_t now, void *data)
plugin_timer_func(struct libinput_plugin *libinput_plugin, usec_t now, void *data)
{
struct libinput_lua_plugin *plugin = data;
struct lua_State *L = plugin->L;
lua_rawgeti(L, LUA_REGISTRYINDEX, plugin->timer_expired_refid);
lua_pushinteger(L, now);
lua_pushinteger(L, usec_as_uint64_t(now));
libinput_lua_pcall(plugin, 1, 0);
}
static int
libinputplugin_timer_set(lua_State *L, uint64_t offset)
libinputplugin_timer_set(lua_State *L, usec_t offset)
{
LibinputPlugin *p = luaL_checkudata(L, 1, PLUGIN_METATABLE);
luaL_argcheck(L, p != NULL, 1, PLUGIN_METATABLE " expected");
@ -583,7 +608,8 @@ libinputplugin_timer_set(lua_State *L, uint64_t offset)
plugin);
}
libinput_plugin_timer_set(plugin->timer, offset + timeout);
libinput_plugin_timer_set(plugin->timer,
usec_add(offset, usec_from_uint64_t(timeout)));
return 0;
}
@ -591,7 +617,7 @@ libinputplugin_timer_set(lua_State *L, uint64_t offset)
static int
libinputplugin_timer_set_absolute(lua_State *L)
{
return libinputplugin_timer_set(L, 0);
return libinputplugin_timer_set(L, usec_from_uint64_t(0));
}
static int
@ -944,7 +970,7 @@ evdevdevice_frame(lua_State *L, struct libinput_lua_plugin *plugin, EvdevDevice
lua_pop_evdev_frame(plugin, device->evdev, frame);
struct libinput *libinput = lua_get_libinput(L);
uint64_t now = libinput_now(libinput);
usec_t now = libinput_now(libinput);
evdev_frame_set_time(frame, now);
return frame;

Some files were not shown because too many files have changed in this diff Show more