When I connect a gamepad on my Linux kernel v5.14 there are two new devices that show up:
/dev/input/event23
/dev/input/js1
If I cat <file> | xxd
both device files provide gamepad event information. But event23
is much more verbose than js1
.
Also, evtest
gives error Invalid Argument
on js1
but works fine on event23
. The same happens when I use libevdev both device files.
It looks like with every event, js1
dumps the contents of an input_event
struct (defined in linux/input.h
)
What is the difference between the device files? Why do they have different information and what more information does event23
provide over js1
?
/dev/input/js*
devices are created by the joydev
legacy joystick driver. It only supports joysticks and joystick-like devices.
https://www.kernel.org/doc/html/latest/input/joydev/joystick.html
/dev/input/event*
devices are created by the evdev
input event interface. It supports all types of input devices, not just joysticks.
https://linux.die.net/man/4/evdev
The joydev
interface exposes a subset of the information exposed through evdev
, specifically it will only expose an input if it looks like a joystick button or axis. New applications should prefer to use evdev
, but joydev
is usually still available.
The "looks like a joystick button or axis" heuristic can sometimes be a problem for joydev
. When a HID gamepad is connected, evdev
and joydev
use information in the device's HID report descriptor to detect the number of button and axis inputs. joydev
only considers buttons from the HID Button usage page, but newer gamepads sometimes define special buttons with different usages. This is especially common for Android gamepads, which have non-Button usages for the Home and Back buttons. These buttons don't get picked up by joydev
.
Another big difference: joydev
is purely for input. evdev
supports gamepad rumble and force feedback effects.