This patch series adds EV_BTN and it's handling to the input system. It's main
focus is to add a simple event for generic buttons, not relying on defined
usages and meanings.
Joysticks unlike keyboards, mice and even gamepads (though that's debatable)
define arbitrary number of buttons that don't mean anything. They can be used
in any kind of software, but mainly games, by assigning them manually to
functions. Some games even carry default presets for devices based on their USB
VID:PID pairs.
The more important issue that this is trying to solve is the longstanding
problem of limited button support in Linux. The use for arbitrary number of
buttons wasn't considered some 20 years ago because Linux wasn't a good platform
for gaming. First, Joystick and Gamepad ranges were limited to 16 buttons, later
extended by 40 additional usages in the TRIGGER_HAPPY range. By allowing the
usages to be incremented up to KEY_MAX, Joysticks were able to expose up to 80
buttons for the past 15 years or so.
Many simracing, simflight etc. devices actually expose way more then that. 128
is a pretty common number with even more in the wild. Usually the numbers get so
big to support things like positional rotary switches as one such rotary can
have 12+ positions. My Moza GS V2P wheel has 5 such rotaries and that's not
counting other buttons.
Doing something about this limit was brought up maaany times in the past:
https://forums.x-plane.org/forums/topic/299033-xp12-linux-winwing-orion-2-throttle-has-too-many-buttons/?page=1
https://forum.falcon-bms.com/topic/26403/solved-winwing-orion-2-on-linux-only-80-buttons-detected
https://lore.kernel.org/linux-input/CACa7zynMpa3BOJUW=s_Tj1TwH5txDQOuta5Fph45PYhDOtQQ3g@mail.gmail.com/
https://lore.kernel.org/linux-input/20200710065112.18286-1-cpuwolf@gmail.com/#r
https://lore.kernel.org/linux-input/20240802201001.406898-1-tomasz.pakula.oficjalny@gmail.com/
https://lore.kernel.org/linux-input/20250201113906.769162-11-tomasz.pakula.oficjalny@gmail.com/
https://lore.kernel.org/linux-input/20251119163844.1343-1-Hunter.Moore@garmin.com/
https://lore.kernel.org/linux-input/20251220194100.GA12646@altimeter-info/
https://lore.kernel.org/linux-input/665df7c9-0d32-4ecd-9f4d-fff67deb5878@endrift.com/
But some considerations:
1. Usages have their actual meanings and we shouldn't use them willy-nilly to add
more buttons, even if that approach works with naive approaches use by SDL and
Wine alike.
2. Extending the KEY_MAX will cause additional issues when it comes to bitmask
sizes, mapping usages and reading them afterward. Basically, we're moving the
goalpost somewhere, but a device that would define 1024 buttons would break
things again.
I must give HUGE thanks to Dmitry for forcing this into my head to a point where
I actually understood the whole issue.
Thus, I thought up of a best, long-term solution to this problem. I do think
EV_BTN should be a first-class event so it can be as easy to handle as possible.
If there's a need, it could be hooked up for Gamepads as well as HID gamepads do
the same thing and only expose raw buttons without specific usages. The usages
are a best guess when handling generic ones and only custom drivers can actually
assign proper buttons like BTN_A, THUMBL etc.
In the future, the Joystick usages could be completely removed and joysticks
could rely ONLY on the new event. For now, the old way is kept to not break
compatibility.
I'm eagerly waiting for comments, recommendations and critique. Currently, there
isn't a way to poll states of all buttons like with EVIOCGKEY but I'm not sure
if it's needed? I added INPUT_MAX_KEYS just for some sane limits BUT I don't see
a real use for it. Instead of this define, we could just use U16_MAX. 65k of
buttons ought to be enough for ANYBODY :D
Companion changes to consumers that already show the working state of this patch series:
Wine: https://gitlab.winehq.org/wine/wine/-/merge_requests/9853
SDL: https://github.com/libsdl-org/SDL/pull/14758
evtest: https://gitlab.freedesktop.org/libevdev/evtest/-/merge_requests/25
Tested with my Moza Racing R9 and Moza Universal Hub (both expose 128 usable
buttons). hid-universal-pidff driver was disabled for testing as it contains
usage range hack.
Sneak peek from updated evtest:
Event: time 1767559522.509446, type 6 (EV_BTN), button 12, value 1
Event: time 1767559522.509446, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9000c
Event: time 1767559522.509446, type 1 (EV_KEY), code 299 (BTN_BASE6), value 1
Event: time 1767559522.509446, -------------- SYN_REPORT ------------
Event: time 1767559522.656447, type 6 (EV_BTN), button 12, value 0
Event: time 1767559522.656447, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9000c
Event: time 1767559522.656447, type 1 (EV_KEY), code 299 (BTN_BASE6), value 0
Event: time 1767559522.656447, -------------- SYN_REPORT ------------
Event: time 1767559523.737498, type 6 (EV_BTN), button 112, value 1
Event: time 1767559523.737498, -------------- SYN_REPORT ------------
Event: time 1767559523.807477, type 6 (EV_BTN), button 112, value 0
Event: time 1767559523.807477, -------------- SYN_REPORT ------------
Tomasz Pakuła (6):
Input: Introduce EV_BTN event for generic buttons
Input: Add info about EV_BTN
Input: Fire EV_BTN if found in ev_bit
Input: Assign EV_BTN event to HID Joysticks
Input: Realign rest of the HID_UP_BUTTON cases
Input: Add EVIOCGBTNCNT
Documentation/input/event-codes.rst | 5 ++
drivers/hid/hid-input.c | 77 +++++++++++++++++---------
drivers/input/evdev.c | 5 ++
drivers/input/input.c | 10 ++++
include/linux/input.h | 4 ++
include/uapi/linux/input-event-codes.h | 1 +
include/uapi/linux/input.h | 1 +
7 files changed, 77 insertions(+), 26 deletions(-)
--
2.52.0