Creates virtual input devices from real ones, SteamController support included.
This program lets you create a virtual input device, by using the Linux uinput
module, and map to it
any number of buttons or axes from real devices. Currently, it is able to use raw input devices and SteamControllers.
The main motivation for this program is to be able to use the SteamController as a normal gamepad, but you can find many other uses for it.
If you are looking for information about the SteamController protocol, then read the STEAM.md file.
This program is licensed under the GPLv3 or later, except:
- Directory
steam
, the implementation of the SteamController decoder, that is under the LGPLv3 or later. - Directory
lemon
, the Lemon parser generator, by D. Richard Hipp, that is Public Domain.
This program uses the meson/ninja build system. To build, install meson and ninja from your Linux distribution, and run:
$ meson --buildtype release build
$ ninja -C build install
To create a virtual device you must write a file describing the real input devices and how they map to the virtual device you want to create. This file uses the INI file syntax. Then you just run:
$ inputmap configuration.ini
And you are ready to go. You may need to run the program as root, depending on your system configuration.
The INI configuration file is quite simple. You can only have two types of sections:
[input]
: defines a standard input physical device.[steam]
: defines a SteamController input physical device.[output]
: defines an output virtual device.
You can write as many sections of any of these as you want.
There are several ways to describe the device referred to by this section:
dev
: The full name of the input device, such as/dev/input/event1
. Since the device name is not stable across reboots, you should try other approach first.by-id
: A shortcut to refer to a device from/dev/input/by-id
. This one should be stable across reboots.by-path
: A shortcut to refer to a device from/dev/input/by-path
. This identifies the port where the device is connected plut the device itself.by-name
: Identifies the device by its name.by-uniq
: Identifies the device by its unique name, that is, its serial number, if available.usb
: A tuple of two hexadecimal values, separated by:
that identifies the USB device, such as1234:5678
.pci
,i8042
,bluetooth
, ...: Just likeusb
, but for this other bus. Only one bus can be specified.
You can see the available devices and its properties by using the -v
option.
These values are mandatory:
name
: the name to refer to this device from the rest of the file. A single unique word, made of letters numbers and underscore.
These values are optional:
grab
: a boolean value (Y
/N
), defaults toN
. IfY
then the device is grabbed, that is it is prevented from sending input events to the rest of the system.
This section describes a SteamController device. The name
value is mandatory, just like in [input]
. Additionally, there are these possible values:
serial
: Only a SteamController with this serial number will be used for this input device. Useful if you have several of them.mouse
: a boolean value (Y
/N
), defaults toN
. IfN
then the builtin mouse emulation of the controller will be disabled.auto_haptic
: a character stringL
,R
orLR
, defaults to empty. If it has aL
then it will enable automatic haptic feedback on the left pad. If it has aR
then it will do the same on the right pad.
In this section you will define the virtual device. First you have a few optional values to describe the device:
name
: The name of the virtual device, defaults toInputMap
.phys
: The name of the phys parameter of the virtual device, defaults to empty.bus
: The bus that the virtual device reports as using, it can beVIRTUAL
,USB
,BLUETOOTH
orPCI
, defaults toVIRTUAL
.vendor
: An hexadecimal number to be reported as VendorId, defaults to 0. Useful to emulate well known devices.product
: An hexadecimal number to be reported as ProductId, defaults to 0.version
: The version of the device, mostly useless. Defaults to 1.
Additionally, you map all the buttons and axes of the virtual device and how the physical devices map to them.
To create a virtual button, you just define a value in the [output]
section with the name of that button.
You can see the available button names in `/usr/include/linux/input-event-codes.h.
The value itself describes how the value of that button is obtained. The easiest way is to write the name of an input device, a period, and the name of the physical button.
For example, to map the keys 1 and 2 to the left and right mouse buttons:
[input]
by-id=usb-USB_Keyboard-event-kbd
name=keyb
[output]
BTN_LEFT=keyb.KEY_1
BTN_RIGHT=keyb.KEY_2
To create a virtual axis, either relative or absolute, you do the same as with the buttons:
[input]
by-id=usb-USB_Joystick-event-joystick
name=joy
[output]
ABS_X=joy.ABS_Z
ABS_Y=joy.ABS_RZ
You can also build a virtual input from physical inputs of a different kind. For example, to create a virtual absolute axis from two buttons (useful for the hat axis) you write the two buttons within parentheses separated by comma:
[output]
ABS_HAT0X=(keyb.KEY_A,keyb.KEY_D)
ABS_HAT0Y=(keyb.KEY_S,keyb.KEY_W)
You can start inputmap from udev when the device is connected.
[steam]
name=Steam
mouse=N
serial={SERIAL}
# /etc/udev/rules.d/90-inputmap.rules
SUBSYSTEM=="input", ATTRS{name}=="*Steam Controller", TAG+="systemd", ENV{SYSTEMD_WANTS}="inputmap@%s{uniq}.service"
# /etc/systemd/system/inputmap@.service
[Unit]
Description=%i service for inputmap
[Service]
ExecStart=/usr/bin/inputmap -m SERIAL=%i /etc/inputmap/xbox.ini