A caller is likely to unconditionally call
libinput_tablet_tool_config_pressure_range_set() with whatever
values it has in its config storage. Those values will be 0 and 1 by
default, we should not take this as a sign that the tool has a pressure
range.
Setting a pressure range resets the automatic offset handling which we
definitely don't want to do for the default range.
Fixes: #1177
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1340>
When a user configures a pressure range, the tool would get locked into
the current offset even if that offset was still pending. For example, a
sequence of
- tool in-prox with pressure 50%
- libinput_tablet_tool_config_pressure_range_set(tool, 0.0, 0.9)
- tool out-of-prox, tool-in-prox
- libinput applies the tool config, tool now has a configured range,
has_offset = true
- tool out-of-prox, tool-in-prox
- update_pressure_range() sees has_offset = true, scales the last offset
(50%) to the actual offset.
Fix this by resetting the detected offset to zero when we shortcut the
heuristics. A user-defined pressure range should include the tool's
pressure offset anyway, the user knows this much better than our
heuristics.
Closes: 1177
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1340>
delta_time can be zero when:
- the fallback acceleration function is used for multiple movement types
(for example, pointer motion and wheel scrolling simultaneously)
- two different methods produce the same movement at the same time
(for example, button-scrolling and wheel-scrolling)
Reusing the last delta_time is a graceful fallback even if there are
duplicate events or event-ordering bugs.
Signed-off-by: Yinon Burgansky <yinonburgansky@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1336>
Dispatch high-resolution scroll wheel events through filter_dispatch_scroll
so they can be accelerated using the custom acceleration profile.
Low-resolution scroll wheel events are not accelerated to avoid zero
delta-time in the filter.
Signed-off-by: Yinon Burgansky <yinonburgansky@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1316>
"libinput_plugins_flags" is bound to be annoying to approximately
everyone who'll ever have to use them so let's rename this while we
still can. Renamed to libinput_plugin_system_flags to leave the
namespace open for a possible future libinput_plugin_flags that works
on individual plugins.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1337>
If a plugin adds events to an event frame that are not supported by the
target device we may eventually dereference a null pointer (for ABS_*
events) or, possibly, use an OOB index access (for buttons or keys).
Let's filter out any events that the device doesn't support immediately.
Fixes#1202
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1324>
A device may send axis events while the tool is out of proximity,
causing our plugin to force a proximity in for the pen. If the tool then
sends a proximity event for a different tool we ended up with two tools
in proximity.
The sequence in #1171 shows this:
- evdev:
- [ 1, 499608, 3, 27, 0] # EV_ABS / ABS_TILT_Y 0 (+30)
- [ 1, 499608, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +0ms
- evdev:
- [ 2, 199637, 1, 321, 1] # EV_KEY / BTN_TOOL_RUBBER 1
- [ 2, 199637, 4, 4, 30] # EV_MSC / MSC_SCAN 30 (obfuscated)
- [ 2, 199637, 1, 330, 1] # EV_KEY / BTN_TOUCH 1
- [ 2, 199637, 3, 0, 910] # EV_ABS / ABS_X 910 (+246)
- [ 2, 199637, 3, 1, 8736] # EV_ABS / ABS_Y 8736 (-105)
- [ 2, 199637, 3, 27, -25] # EV_ABS / ABS_TILT_Y -25 (-25)
- [ 2, 199637, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +700ms
Fix this by remembering that we forced the tool out of proximity so if
we see tool events for another tool we force the pen out of proximity
again.
This will have some interplay with the other tablet plugins but
hopefully none that affect real-world devices, e.g. forcing a proximity
out means the proximity out timer plugin gets disabled. Since devices
behave in unexpected manners anyway let's see if it affects a real-world
device.
Closes#1171
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1306>
When printing tablet events always print a '*' or ' ' suffix to ensure
the alignment of the next field matches. We're using a tab to align
after each field so if the string length doesn't match, our events may
print at different tab stops.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1299>
For some reason clang-tidy believes that in the second iteration group
is set to NULL and causes a NULL-pointer dereference.
../src/evdev-tablet-pad.c:305:2: error: Access to field 'next' results in a dereference of a null pointer [clang-analyzer-core.NullDereference,-warnings-as-errors]
305 | list_for_each(group, &pad->modes.mode_group_list, link) {
| ^
../src/util-list.h:265:13: note: expanded from macro 'list_for_each'
265 | pos = list_first_entry_by_type(&pos->member, __typeof__(*pos), member))
| ^
../src/util-list.h:202:2: note: expanded from macro 'list_first_entry_by_type'
202 | container_of((head)->next, container_type, member)
| ^
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1298>
Because our lua hooks don't expose the device-added callback we need to
cache any calls to disable a feature and then apply it quietly when the
device is actually added. Any other call can go straight through.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1249>
Also a long-requested configuration option but it's difficult to expose
- depending on the touchpad we utilize different palm detection methods
and in theory may add to those at any time as we see fit.
Disabling it completely via a configuration option is only going to get
us more bug reports because *some* palm detection is likely desired on
most setups. So let's allow disabling it in a plugin and thus leave any
further palm detection code up to the plugin.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1249>
Over the years we had a few devices that required some special
hysteresis handling - all of it very customized to the device and not
upstreamable (or even implementable by upstream without the device).
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1249>
Both about the same complaint, somehow it is of the impression that
masks->mask can be an uninitialized value. The only place where we
allocate those is in _infmask_ensure_size() and they're set to zero
there.
libinput/src/util-bits.h:166:22: warning: The left operand of '&' is a garbage value [clang-analyzer-core.UndefinedBinaryOperatorResult]
166 | return !!(mask.mask & bit(bit));
| ^
libinput/src/util-bits.h:444:2: note: Calling 'infmask_set_bit'
444 | infmask_set_bit(&m, mask);
| ^~~~~~~~~~~~~~~~~~~~~~~~~
libinput/src/util-bits.h:394:15: note: Calling 'infmask_bit_is_set'
394 | bool isset = infmask_bit_is_set(mask, bit);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
libinput/src/util-bits.h:382:13: note: Field 'mask' is non-null
382 | if (!mask->mask || bit / bitmask_size() >= mask->nmasks)
| ^
libinput/src/util-bits.h:382:6: note: Left side of '||' is false
382 | if (!mask->mask || bit / bitmask_size() >= mask->nmasks)
| ^
libinput/src/util-bits.h:382:2: note: Taking false branch
382 | if (!mask->mask || bit / bitmask_size() >= mask->nmasks)
| ^
libinput/src/util-bits.h:385:9: note: Uninitialized value stored to 'mask.mask'
385 | return bitmask_bit_is_set(mask->mask[bit / bitmask_size()], // NOLINT(core.UndefinedBinaryOperatorResult)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
386 | bit % bitmask_size());
| ~~~~~~~~~~~~~~~~~~~~~
libinput/src/util-bits.h:385:9: note: Calling 'bitmask_bit_is_set'
385 | return bitmask_bit_is_set(mask->mask[bit / bitmask_size()], // NOLINT(core.UndefinedBinaryOperatorResult)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
386 | bit % bitmask_size());
| ~~~~~~~~~~~~~~~~~~~~~
libinput/src/util-bits.h:166:22: note: The left operand of '&' is a garbage value
166 | return !!(mask.mask & bit(bit));
| ~~~~~~~~~ ^
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1292>
../src/evdev-mt-touchpad-buttons.c:1233:16: warning: Value stored to 'button' during its initialization is never read [clang-analyzer-deadcode.DeadStores]
1233 | evdev_usage_t button = evdev_usage_from_uint32_t(0);
| ^~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1292>
Instead of a hard assert if we fail to find the mode group for the given
ring/dial/strip let's just log an error and discard the event.
I'm not sure this assert can be triggered in the current code base but
if it can an error message is going to be more useful to the user than
an assert.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1291>
This looks like a copy-and-paste error. In practice it was harmless on
64-bit systems because evdev_event happens to be 64 bits long, but on
32-bit systems it would allocate too little memory.
Found by GCC 15 with _FORTIFY_SOURCE=3 on ia32.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1288>
This patch adds support for Lua scripts to modify evdev devices and
event frames before libinput sees those events.
Plugins in Lua are sandboxed and restricted in what they can do: no IO,
no network, not much of anything else.
A plugin is notified about a new device before libinput handles it and
it can thus modify that device (changes are passed through to our libevdev
context). A plugin can then also connect an evdev frame handler which
gives it access to the evdev frames before libinput processes them. The
example plugin included shows how to swap left/right mouse buttons:
libinput:register({1})
function frame(device, frame)
for _, v in ipairs(frame.events) do
if v.usage == evdev.BTN_RIGHT then
v.usage = evdev.BTN_LEFT
elseif v.usage == evdev.BTN_LEFT then
v.usage = evdev.BTN_RIGHT
end
end
return frame
end
function device_new(plugin, device)
local usages = device:usages()
if usages[evdev.BTN_LEFT] and usages[evdev.BTN_RIGHT] then
device:connect("evdev-frame", frame)
end
end
libinput:connect("new-evdev-device", device_new)
A few other example plugins are included in this patch
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1192>
This patch adds a new API for enabling public "plugins" in libinput, in
addition to the exisitng internal ones. The API is currently limited to
specifying which paths should be loaded and whether to load them.
Public plugins are static, they are loaded before the context is initialized
and do not update after that.
If plugins are to be loaded, libinput will then run through those paths,
look up files and pass them to (future) plugins to load the actual
files.
Our debugging tools have an --enable-plugins and
--disable-plugins option that load from the default data paths
(/etc/libinput/plugins and /usr/lib{64}/libinput/plugins) and from
the $builddir/plugins directory.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1192>
The debounce, wheel/wheel-low-res, double-tool and eraser-button plugins can limit
themselves to a specific usage.
The mtdev plugin needs to pass each each event to mtdev and the proximity
timer plugin needs to get each event's timestamp so they cannot be
restricted.
The forced-tool could be restricted but effectively any event on the
devices it works on will have one of those usages set so there's no
point.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1271>
This adds the ability for a plugin to announce the evdev usages it may
possibly care about. Only event frames that contain one or more of those
usages will be passed to the plugin. Ideally this is an optimization
over calling every plugin for every frame but that largely also depends
on what exactly the plugin does with each frame.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1271>
Allows to keep track of a set of evdev masks, or at least the subset we
care about.
The EV_KEY range is split into two masks to save some memory. The future
use of this is for the plugins to use those masks and some of those will
set BTN_TOOL_PEN and friends. This would immediately create an 81 byte
mask of zeroes just to keep that one bit.
Splitting it into a key/btn mask with the latter starting at BTN_MISC
means we duplicate the infmask struct (2x16 bytes) but instead only use
8 bytes for the mask itself to keep the BTN_TOOL_PEN bits.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1271>
In commit 9a9466b6a9 ("evdev: discard any frame with EV_SYN SYN_REPORT 1")
all frames with a SYN_REPORT 1 were discarded on the assumption of those
being key repeat frames. Unfortunately the kernel uses the same sequence
to simply mark *any* injected/emulated event, regardless of the cause. Key repeat
events are merely the most numerous ones but as shown in commit
7140f13d82 ("evdev: track KEY_SYSRQ frames and pass them even as repeat frames")
Alt+PrintScreen is also an emulated event.
Issue #1165 details another case: keyboards with n-key rollover can
exceed the kernel-internal event buffer, typically 8 events for devices
without EV_REL/EV_ABS. Those events will be broken up by the kernel into
multiple frames - once nevents == buffer_size the current state is
flushed as SYN_REPORT 1 frame. Then, if any more events are pending
those are flushed as SYN_REPORT 0 frame. In the case of exactly 8
events, the second frame is never present, so we cannot easily detect if
another one is coming.
Issue #1145 only affects us in the touchpad code, the rest of the
backends seem to (so far) be fine. So let's move the discarding of
SYN_REPORT 1 to the touchpad backend and leave the rest of the code
as-is.
This effectively
Reverts: 7140f13d82 ("evdev: track KEY_SYSRQ frames and pass them even as repeat frames")
Reverts: 9a9466b6a9 ("evdev: discard any frame with EV_SYN SYN_REPORT 1")
Closes#1165
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1282>