[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <aV8eksQWbJcCehdy@quokka>
Date: Thu, 8 Jan 2026 13:24:22 +1000
From: Peter Hutterer <peter.hutterer@...-t.net>
To: Tomasz Pakuła <tomasz.pakula.oficjalny@...il.com>
Cc: dmitry.torokhov@...il.com, corbet@....net, jikos@...nel.org,
bentiss@...nel.org, linux-input@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-doc@...r.kernel.org, vi@...rift.com, linux-kernel@...imeter.info
Subject: Re: [RFC PATCH 0/6] Input: New EV_BTN event for generic buttons
On Sun, Jan 04, 2026 at 10:31:26PM +0100, Tomasz Pakuła wrote:
> 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.
fwiw, we *already* add those usages willy-nilly for a rather large
proportion of devices. any HID device with the Button usage page will
convert from HID button 4 to BTN_SIDE and then the rest of the stack
pretends this was a conscious choice. Which leads to hilarities that
BTN_SIDE is actually the back button and BTN_BACK is just... button 7
(or button 11 thanks to X11 history). Which then again leads to
hilarities that sending BTN_BACK to indicate a back action may or may
not have an effect, I recently had a bug like this in mutter/gtk's tablet
handling. IOW, it's quite messy anyway.
So what I (think I) would like is to use EV_BTN in addition with EV_KEY
to signal purely numbered buttons but *also* which buttons have the
exact semantic meaning. The logic becomes:
If an EV_KEY $code is just a numbered button it *also* sends EV_BTN
$number.
If an EV_KEY $code is a fixed semantic meaning (e.g. BTN_BACK) it does
*not* send an EV_BTN $number.
Then we can have a mapping in the device that maps from EV_BTN to EV_KEY
code, obtained via some EVIOCBTNKEYCODE() ioctl. The hypothetical
example of a device with 3 numbered buttons and a fixed BTN_BACK would
be: EV_BTN count of 3, EV_KEY bits for left/middle/right and back.
nbuttons = EVIOCBTNCNT()
EVIOCBTNKEYCODE(0, nbuttons) returns [BTN_LEFT, BTN_RIGHT, BTN_MIDDLE]
A sequence with right and back down would look like this:
Event: time 1767559522.509446, type 6 (EV_BTN), button 2, value 1
Event: time 1767559522.509446, type 6 (EV_KEY), code 0x110 (BTN_RIGHT), value 1
Event: time 1767559522.509446, type 6 (EV_KEY), code 0x110 (BTN_BACK), value 1
Event: time 1767559522.509446, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9000c
Event: time 1767559522.509446, -------------- SYN_REPORT ------------
And userspace can ignore BTN_RIGHT thanks to that mapping but BTN_BACK
retains its semantic meaning. This is flexible enough even though I'm
not sure how many devices will mix the two.
Does that make sense?
Cheers,
Peter
> 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
>
Powered by blists - more mailing lists