These are all data structs that are used in libinput and the tests,
let's declare them in a shared header so we can use them everywhere.
For udev and libevdev let's use an ifdef check for a known #define
so we don't have to add those deps everywhere.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1184>
Taken from libei, with slight modifications. The general approach is:
basic data types use _autofoo_ to call the maching foo function on
cleanup. Struct types use _unref_, _destory_, _free_, whichever applies
to that struct.
Notably: attribute syntax depends on where it's declared [1] so in the
following examles only a, b, and d have the autofree attribute:
_autofree_ char *a, *b;
char *c, _autofree *d;
Simplest way to ensure it's all correct to keep the declarations one per
line.
[1] https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html#Attribute-Syntax
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1184>
C23 auto is basically __auto_type so let's wrap it if our compiler
doesn't provide it (yet).
This lets us use `auto` as type specifier, e.g. compare
enum libinput_config_status status = libinput_device_config_set(...)
auto status = libinput_device_config_set(...)
Note that as of now meson will never detect this as it requires -std=c23
to be passed to the compiler. This flag is only supported by Clang 18
(released 2024) and we don't want to break things for older compilers
for what is a bit of a niche feature right now.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1181>
Before this patch, tp_filter_motion() was called twice in pointer motion
handler during 3fg drag, causing the pointer speed to be much faster
than during 1fg motion when the acceleration profile is adaptive.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1180>
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>
These are all internal API so having a NONE value means we can shut up
warnings about 0 not being an enum value without having those exposed in
our public API.
And they slightly improve readability in the callers anyway.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1175>
In a valiant approach to introduce some type-safety (after spending time
debugging a int vs double confusion) this adds a DECLARE_NEWTYPE()
macro that declares a named struct with a single typed value field.
This is basically the C version of Rusts "struct Foo(u32)" with
a few accessors auto-generated by the macro.
C is happy to silently convert between base types but it doesn't do
so for structs so this allows us to have some type safety
when we accidentally assign two incompatible fields to each other (e.g.
an axis value in device units vs a percentage value).
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1171>
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>
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>
A tablet with multiple mode toggle buttons had each mode toggle button
merely cycle to the next mode in the sequence, removing the whole point
of having multiple toggle buttons.
Fix this by defaulting each mode toggle button to "next". Once we
have initialized all buttons we can check if we have multiple buttons -
if so we number them sequentially so that the first button maps to mode
0, the second maps to mode 1, etc.
Closes#1082
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1132>
These have been behind #if 0 for ages but there are more to come, let's
make it possible to toggle those on/off with a meson option.
This is an option that must not be used in a release build, it will leak
key codes to the logs.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1156>
Two advantages here: fewer actual printf() calls making the output
slightly more coherent if there are other things writing to stdout but
also better re-usability since we can now move the print functions to
shared code.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1156>
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>
Similar to the condition just north of here, if we have 3 fingers in a
roughly linear line and 3fg dragging is enabled, assume we're actually
trying to drag. This reduces the minimum movement otherwise required
to detect the type of gesture.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1042>
Exposed via new configuration option this enables 3 and 4 finger
dragging on touchpads. When enabled a 3/4 finger swipe
gesture is actually a button down + motion + button up sequence.
If tapping is disabled the drag starts immediately, if tapping is
enabled the drag starts after the tap timeout/motion so we can distinguish
between a tap and a drag.
When fingers are released:
- if two fingers remain -> keep dragging
- if one finger remains -> release drag, switch to pointer motion
When 3/4 fingers are set down immediately after releasing all fingers
the drag continues, similar to the tap drag lock feature. This drag lock
is not currently configurable.
This matches the macos behavior for the same feature.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1042>
Where the tapping code calls into the timeout function make sure we have
a separate event for this. This way we know whether the current gesture
event is caused by the hold timeout or something else.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1042>
This shouldn't have any effect in the current setup as there is
"coincidentally" no overlap between the two state machines so this is
effectively a noop.
Nonetheless, if we're about to send a tap button event we cannot be in
any other gesture than tapping so all swipe/pinch/holds need to be
cancelled.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1042>
This is a workaround for a kernel bug with the Wacom Mobile Studio Pro
13: this device sends erroneous ABS_WHEEL events when pressing
buttons:
- evdev:
- [ 0, 0, 1, 256, 1] # EV_KEY / BTN_0 1
- [ 0, 0, 3, 8, 17] # EV_ABS / ABS_WHEEL 17 (+17)
- [ 0, 0, 3, 8, 0] # EV_ABS / ABS_WHEEL 0 (-17)
- [ 0, 0, 3, 40, 15] # EV_ABS / ABS_MISC 15 (+15)
- [ 0, 0, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +0ms
ABS_WHEEL to 17 then to 0 in the same frame. We should (and do) treat this
as a zero event and drop the 17 to the floor. Alas, we then generate a
ring event for the zero value despite our current value being zero
anyway. This again causes confusing behavior.
This is simple enough to work around, at least until the kernel is fixed
but also to prevent this happening in the future: warn if we get
multiple events and if so and the later event is zero, undo the axis
change state.
Closes: #1081
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1136>
Slightly less efficient but easier to read and it's not possible to
accidentally provide the wrong length. Plus it handles null pointers
correctly so get to skip the checks (which weren't needed for strneq()
either, but still).
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1121>
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>
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>