Commit graph

283 commits

Author SHA1 Message Date
Peter Hutterer
7d8fac2868 quirks: add a helper function for returning quirks for a device
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1230>
2025-06-24 12:01:51 +10:00
Peter Hutterer
56f0524115 tablet: always allow BTN_STYLUS* for eraser button configuration
If the button we want to map to isn't enabled by the kernel allow
setting the button nonetheless. On some tablets we only get the
actual number of button codes (e.g. BTN_STYLUS only on an Inspiroy 2S)
so not being able to map the eraser button to some other button makes
this whole feature a bit pointless.

Special-case BTN_STYLUS* because these are the ones we'll always allow.

This fixes an issue with the eraser button defaulting to BTN_STYLUS2
on some devices but it couldn't actually be set to that value by the
caller.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1231>
2025-06-19 01:51:52 +00:00
Peter Hutterer
34da27650d tablet: take an uint32_t for the eraser button
For consistency with other set_button configuration options.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1231>
2025-06-19 01:51:52 +00:00
Peter Hutterer
c48aff86d7 tablet: implement eraser button disabling
This adds a new (internal) plugin that is responsible for eraser button
disabling.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1218>
2025-06-18 19:38:14 +10:00
Peter Hutterer
42c0bff29b plugin: add internal api to notify plugins of tool configuration
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1218>
2025-06-18 19:38:14 +10:00
Peter Hutterer
2d23d7f4aa tablet: implement the tablet proximity timer as plugin
Together with the "forced-tool" quirk (that enforces BTN_TOOL_PEN to be
set even if the tablet doesn't) since those two go hand-in-hand.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1218>
2025-06-18 19:38:14 +10:00
Peter Hutterer
e5e28ea7e6 tablet: implement the tablet double tool quirk as plugin
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1218>
2025-06-18 19:38:14 +10:00
Peter Hutterer
e7ebb1bca6 tablet: keep a ref to the last tablet in proximity for each tool
99.9% of the time the next tablet will be the same tablet it was used on
last. Having a ref means we can modify tablet settings while the tool is
out of proximity.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1218>
2025-06-18 19:38:14 +10:00
Peter Hutterer
28e50024ab tablet: move the libwacom stylus query out into the caller
Better re-usability of the WacomStylus struct in subsequent patches.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1218>
2025-06-18 19:38:14 +10:00
Peter Hutterer
5d23794d53 tablet: disable smoothing for uinput devices
When a tablet was created via uinput we trust that the
tablet's events are preprocessed to the point where we
no longer need to apply smoothing to the axes.

Closes #1120

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1219>
2025-06-12 09:49:15 +00:00
Peter Hutterer
1c5715fedf Use a newtype for the keycode, button code and pad button
This provides both some type-safety but also better readability of what
the integer we're passing around is supposed to be. In particular the
pad buttons are numeric buttons while the normal buttons are evdev
codes.

Future extension of this could be to also check for (or against) the
valid BTN_* ranges for a button code or keycode.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1215>
2025-06-12 18:20:40 +10:00
Peter Hutterer
c821bbd8e4 Drop struct input-event from dispatch->interface->process
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1215>
2025-06-12 18:20:40 +10:00
Peter Hutterer
56bad53f29 Switch the tablet backend to use struct evdev_event
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1215>
2025-06-12 18:20:40 +10:00
Peter Hutterer
5774463dde tablet: shut up deprecated declarations warnings
No need to see those every time, #1137 now tracks this

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1214>
2025-06-06 11:00:04 +10:00
Peter Hutterer
546debe926 Remove empty lines between closing braces
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1190>
2025-04-16 11:44:09 +10:00
Peter Hutterer
e9f3fc080c tablet: revamp the tablet pressure range handling
Commit 48cd4c7287 ("tablet: track pressure ranges per tablet") added
tracking of pressure ranges per tablet by storing ranges for multiple
(up to 4) tablets in the tool. This doesn't scale well, had the
disadvantage of the range only being updated on out-of-proximity, and is
the wrong approach anyway.

Turns out we can update the pressure range on proximity in since we
haven't processed the pressure values yet at that stage. This gives us
better behavior when switching between tablet devices (including unplug)
as the pen will only lag behind once (when setting the range) instead
of once per new tablet.

However, since the offset (which is a tool issue) applies on top of the
pressure range (which is a tablet property) this requires that we now
track the offset as percent of the range.

So on proximity in we apply the new tablet range, then apply the e.g. 5%
pressure offset within this range.

This means we no longer have to track multiple tablets since it'll just
apply on the current tablet when in proximity.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1172>
2025-04-04 22:44:29 +00:00
Peter Hutterer
7d4e152aea tablet: delete the tablet's pressure range from the tool pressure ranges
Commit 48cd4c7287 ("tablet: track pressure ranges per tablet") added
up to 4 per-tablet pressure ranges that are stored in the tool on the
assumption that tools are never used across more than 4 tools.

However, if the tablet gets unplugged it will show up as new devices.
Fix this by removing the tool's reference to the previous tablet after
device removal.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1165>
2025-03-31 19:41:00 +10:00
Peter Hutterer
fc4e806e0b tablet: always initialize the pressure thresholds
When the tool is moved in proximity of a new tablet but the pressure
range hasn't changed since the last proximity, the new tablet was left
with a threshold range of 0:0.

For some reason this requires tightening up the check for the test too,
with our default episolon 0.091 fails the test of being > 0.9

Closes #1109

Fixes: 48cd4c7287 ("tablet: track pressure ranges per tablet")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1165>
2025-03-31 18:09:19 +10:00
Peter Hutterer
79dc0261e2 tablet: fix an indentation issue
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1161>
2025-03-25 15:05:45 +10:00
Peter Hutterer
48cd4c7287 tablet: track pressure ranges per tablet
Tablets may have different ABS_PRESSURE ranges with the oldest tablets
having 1k pressure range, then 2k, and the newer ones 8k.

If the same tool is used across two tablets with different ABS_PRESSURE
ranges, the first tablet in proximity calculated the range on where to
normalize to. As a result the other tablet either couldn't reach the
full pressure (2k pressure first, then 8k) or the full pressure range
was reached at a fraction of the full range (8k pressure first, then
2k).

Fix this by moving the threshold handling into a separate struct and
hardcoding up to 4 of those per tool. That is 2 more than the more
complicated setups I've heard of (and this only applies to tracking the
same stylus across those tablets anyway).

This duplicates the pressure offset heuristics but that's easier than
figuring out how to handle heuristics across potentially two tablets.

The range configuration is left as-is on the assumption that this one is
per tool, not per tablet.

Closes #1089

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1143>
2025-02-25 05:18:58 +00:00
Peter Hutterer
1d8f2903ed tablet: always unset the various statuses if we're leaving proximity
The previous invocation was gated behind a TABLET_OUT_OF_AREA check
resulting in a nonresponsive tool when the tablet was moved out of
proximity outside the tablet area and the area was changed.

Move the actual status bit changes up into tablet_flush()
so we unconditionally set those.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1118>
2025-01-20 09:54:32 +00:00
Peter Hutterer
865b2e748f tablet: ignore movements started outside the configured area
If a tablet has an area configured and the pen goes into proximity
outside this area, ignore all events from this sequence. This truly
deactivates that area so it can even be used for e.g. placing a pen
there.

For simplicity, a sequence that starts outside the configured area will
be completely ignored, i.e. moving into the tablet area will not trigger
any fake proximity events as we cross into the allowed area. This
requires quite a bit of effort and it's unclear if it's really needed by
users - we can reconsider when we get complaints.

We do however accept a proximity event within within 3% of the
configured area.  This gives us 6mm on a 200mm tablet where we can move
in from the area and still have events work, i.e. some error margin for
where a user needs both an area and work closes to the edge of that
area.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1013>
2024-11-05 12:10:48 +10:00
Peter Hutterer
0b28eeea5a tablet: implement support for area configuration for external tablets
For external tablets like the Intuos series we now expose the area
rectangle configuration and the (minimum) implementation required to
make this work.

Because an area configuration may apply late and tablet events usually
get scaled by the compositor we need to store the current axis extents
in each event. This is to behave correctly in this events sequence:

1. tool proximity in
2. caller changes config, config is pending
3. tool moves, generates events
4. tool goes out of prox, new config applies
5. caller processes motion events from step 3

If the caller in step five uses any of the get_x_transformed calls these
need to be scaled relative to the original area, not the one set in
step 2.

The current implementation merely clips into the area so moving a stylus
outside the area will be equivalent to moving it along the respective
edge of the area. It's not a true dead zone yet.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1013>
2024-11-05 12:10:48 +10:00
Peter Hutterer
9735229dee tablet: use our absinfo_x/y struct instead of the libevdev one
device->abs.absinfo_x/y points to the x/y axis we want to use and
that axis is used in all the evdev helper function. For consistency
use that one here too.

This is for consistency only and has no effect on tablet devices, the
only time this isn't ABS_X/Y is on multitouch devices where that points to
ABS_MT_POSITION_X/Y.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1013>
2024-11-05 12:05:05 +10:00
Peter Hutterer
d1e49c7b3d tablet: default to a built-in tablet
The vast majority of devices that libwacom doesn't know about are the
various built-in ones. Since the only effect in our code here is that we
enable the calibration matrix, let's default to built-in if we don't
know any better - better to have the matrix and not use it than to not
be able to calibrate a tablet.

Note that libwacom 2.11 and later also now default to a built-in tablet.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1074>
2024-10-31 15:58:31 +10:00
Peter Hutterer
2b2959fc8b tablet: centralize the libwacom handling
Instead of re-creating the the libwacom device from the database every
time we need it let's create it once during tablet|pad_init and pass it
down to the functions.

This allows us to have one point per tablet/pad where we can log an
error if the device is not supported by libwacom - previously this was
printed during the left-handed setup.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1073>
2024-10-31 13:38:28 +10:00
Peter Hutterer
d3bc0c79ff tablet: minor rework to remove one ifdef HAVE_LIBWACOM
Change to a boolean for more obvious return values and move the ifdef
into the function so we can skip the ifdef in the caller.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1073>
2024-10-31 13:38:28 +10:00
Peter Hutterer
5f744c8928 tablet: fix a memory leak caused by an early return
Previously we'd return early, failing to libwacom_destroy() the device.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1064>
2024-10-18 09:48:05 +10:00
Peter Hutterer
978676be1e tablet: allow calibration if libwacom says our tablet is a display tablet
Not all display tablets have INPUT_PROP_DIRECT SET (looking at you,
Huion Kamvas 12) so our calibration went nowhere. Let libwacom override
whatever the kernel says.

This also makes testing without matching hardware a bit easier now since
we only need to override the libwacom file, not the whole device.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1019>
2024-06-19 12:37:44 +10:00
Peter Hutterer
41a4b128e9 tablet: rework a helper function to be more reusable
This allows us to look more things up from libwacom in one go.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1019>
2024-06-19 12:37:44 +10:00
Peter Hutterer
4bc27543e9 tablet: add tablet tool pressure range configuration
Add a configuration option to reduce the available hardware range to a
fraction thereof. This is done by copying the absinfo struct for the
pressure value and adjusting that copy's minimum/maximum value for
scaling into the target normalized range.

The 1%/5% tip thresholds are kept but pressure offset detection is
disabled if there is a custom pressure range.

Unlike the pressure curve which is implemented in the compositor, the
pressure min/max range needs to be in libinput, primarily because the
tip threshold needs to adjust to any new minimum, allowing for
light touches with a pen without triggering tip down even at a higher
hardware pressure.
2024-01-30 14:29:25 +10:00
Peter Hutterer
47f0bce7ec tablet: document a known bug about pressure thresholds across tablets 2024-01-30 14:29:25 +10:00
Peter Hutterer
54aa01a267 tablet: move tool creation into a helper function 2024-01-30 14:29:25 +10:00
Peter Hutterer
7cffd28e8f tablet: don't use absinfo_range for the percentage calculation
Our percents are inclusive 0% and 100%.
2024-01-30 14:29:25 +10:00
Peter Hutterer
0322403ea4 tablet: fix tilt handling for even-ranged tablets
The tablet tilt range may be set as [-N, M] in which case we assume that
a value of zero is vertical (and thus should result in a libinput tilt
value of zero). Unfortunately some tablets report an even total value
range, e.g. [-64, 63] so zero is not actually the mathematical center of
the axis.

Fix this by bumping the axis maximum so zero becomes the logical center.
All devices we've seen so far have [-A, (A-1)] as range so bumping it by
one makes it symmetric.
2024-01-30 14:29:25 +10:00
Peter Hutterer
72eca2db56 util: add a helper to normalize an axis to [0.0, 1.0]
Like the input axis, a normalized range has min/max inclusive so we
cannot use the absinfo_range() helper which assumes the max is exclusive.

Reverts parts of 4effe6b1b9
2024-01-30 14:29:25 +10:00
Peter Hutterer
f20eefbc59 Revert "tablet: fix the pressure offset range being off by one"
Fixing the range is only required when the output range is not inclusive
of the min/max (such as when mapping an abs axis to a screen width).

Our pressure range is inclusive 0.0 and 1.0, so we want absinfo->maximum
to map to exactly 1.0

This reverts commit a5b6f4009b.
2024-01-30 14:29:25 +10:00
Peter Hutterer
8bb53150a9 tablet: handle BTN_STYLUS3
And add a test to make sure the tool we know that has three buttons (Pro
Pen 3) can send all those. Enough to run that test one one compatible
device, no real benefit of running it on all tablet devices.
2024-01-24 12:34:25 +10:00
Peter Hutterer
cf1c07e066 Add a helper for radians to degrees 2024-01-16 19:49:02 +10:00
Peter Hutterer
4effe6b1b9 evdev: add a helper macro for the absinfo range
The range is (max - min + 1) because the kernel range is inclusive min
and max. Let's fix that once and for all with a helper function.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-08-29 17:07:38 +00:00
Peter Hutterer
a5b6f4009b tablet: fix the pressure offset range being off by one
Kernel ranges are inclusiv min/max, so let's make sure we calculate that
correctly.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-08-29 17:07:38 +00:00
Peter Hutterer
d75a0fa42d tablet: fix the tilt range being off by one
Kernel ranges are inclusiv min/max, so let's make sure we calculate that
correctly.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-08-29 17:07:38 +00:00
Bjørn Forsman
3dba00845c tablet: increase pressure offset limit from 20% to 50%
detect_pressure_offset() currently rejects offsets that are greater than
20%. My graphics tablet (Wacom Bamboo Fun) is about 30%. The pen tip is
2 mm. Wacom recommends replacing at 1 mm, which means this isn't worn
out yet and we should instead increase the limit to make these devices
usable.

Without this change a "pen down" event happens simultaneously with the
pen being detected -- about 1 cm above the surface -- and producing
libinput pressure of about 0.30. This means you start drawing "in the
air", without knowing up front where the cursor is going to be.

Signed-off-by: Bjørn Forsman <bjorn.forsman@gmail.com>
2023-08-24 08:04:03 +02:00
Peter Hutterer
a244b9e32b tablet: apply pressure offset handling for non-distance tablets
Previously we only applied pressure offset handling for tablets that
supported ABS_DISTANCE. Detecting a pressure offset when the tool
doesn't actually touch the surface is easy after all.

But tablets without distance handling may also have a pressure offset,
so let's try to detect this. This is obviously harder since the pen will
always touch the tablet's surface whenever it is in proximity and thus
will always have *some* pressure applied to it.

The process here is to merely observe the minimum pressure value during
the first two strokes of the pen. On the third prox in, that minimum
pressure value is taken as the offset. If the pressure drops below the
offset, the offset is adjusted downwards [1] so over time we'll
get closer to the pen's real offset.

[1] this is already done for distance tablets too

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-06-23 05:21:51 +00:00
Peter Hutterer
ecf02deb17 tablet: split proximity and axis update handling
Let's make this two conditions, this is too confusing to read otherwise.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-06-23 05:21:51 +00:00
Peter Hutterer
eea10aef47 tablet: split detecting and updating the pressure offset
detect_pressure_offset() would previously update an existing offset but
otherwise skip most of the work for any event other than proximity-in
events. This was too hidden, let's split this into two functions - one
to update an existing offset and another one to detect a new offset.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-06-23 05:21:51 +00:00
Peter Hutterer
71f5dc6e23 tablet: move setting the pressure offset into a helper function
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-06-23 05:21:51 +00:00
Peter Hutterer
898f80fa37 tablet: always enable touch arbitration with touchscreens/ext. touchpads
Right now for touch arbitration to work, we require the device group to
be the same (i.e. they're hanging off the same physical bus). That's not
always the case and statistically we have a lot more devices that have
a built-in tablet + touchscreen than we have Intuos-like external
tablets.

So let's default to the more common case - enabling arbitration with the
first touchscreen/external touchpad we find. If a subsequent device is
"better", swap it out. Right now, the only heuristic we have here is the
device group check but in the future we could get more precise.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-03-30 05:53:23 +00:00
Peter Hutterer
c26c05b255 tablet: split out arbitration/rotation handling assignment
No functional changes

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-03-30 05:53:23 +00:00
hrdl
1e64d52fe9 evdev-tablet: clip touch arbitration rectangle
Previously the arbitration rectangle would be moved to lie completely in
the first quadrant of the coordinate system.

Signed-off-by: hrdl <51402-hrdl@users.noreply.gitlab.freedesktop.org>
2023-02-07 11:26:27 +01:00