InputPlumber is an open source input routing and control daemon for Linux. It can be used to combine any number of input devices (like gamepads, mice, and keyboards) and translate their input to a variety of virtual device formats.
- Combine multiple input devices
- Emulate mouse, keyboard, and gamepad inputs
- Intercept and route input over DBus for overlay interface control
- Input mapping profiles to translate source input into the desired target input
- Route input over the network
InputPlumber requires the following system dependencies:
libevdev
libiio
You can install with:
make build
sudo make install
If you are using ArchLinux, you can install InputPlumber from the AUR:
yay -S inputplumber-bin
Then start the service with:
sudo systemctl enable inputplumber
sudo systemctl start inputplumber
XML specifications for all interfaces can be found in bindings/dbus-xml.
When InputPlumber is running as a service, you can interact with it over DBus. There are various DBus libraries available for popular programming languages like Python, Rust, C++, etc.
You can also interface with DBus using the busctl
command:
busctl tree org.shadowblip.InputPlumber
InputPlumber is capable of loading input device profiles to translate inputs into any other supported input event. Input profiles are defined as YAML configuration files that can be loaded on-demand for any device that InputPlumber manages. The format of an input profile config is defined by the Device Profile Schema to make it easier to create profiles.
Typically input profiles should be generated using an external tool, but you can manually create your own profiles using any text editor. If you use an editor that supports the YAML Language Server you can write profiles with auto-complete and usage information.
Here is a short example:
# yaml-language-server: $schema=https://raw.githubusercontent.com/ShadowBlip/InputPlumber/main/rootfs/usr/share/inputplumber/schema/device_profile_v1.json
version: 1
kind: DeviceProfile
name: Start Button to Escape Key
description: Profile to map a gamepad's start button to the Escape keyboard key
mapping:
- name: Menu
source_event:
gamepad:
button: Start
target_events:
- keyboard: KeyEsc
This example will remap the Start
button from a gamepad to the ESC
key.
To load the input profile, you can use the LoadProfilePath
method on the input
device you want the profile applied to. You can also do this from the command
line using busctl
:
busctl call org.shadowblip.InputPlumber \
/org/shadowblip/InputPlumber/CompositeDevice0 \
org.shadowblip.Input.CompositeDevice \
LoadProfilePath "s" /usr/share/inputplumber/profiles/mouse_keyboard_wasd.yaml
Intercept Mode is a feature of InputPlumber that can allow external applications to intercept input events from an input device and re-route them over DBus instead. The primary use case for this feature is typically to allow overlay applications (like OpenGamepadUI) to stop input from reaching other running applications (like a game), allowing the overlay to process inputs without those inputs leaking into other running apps.
You can set the intercept mode by setting the InterceptMode
property on the
input device you want to intercept input from. The intercept mode can be one
of three values:
0
(NONE) - No inputs are intercepted and re-routed1
(PASS) - No inputs are intercepted and re-routed except for gamepadGuide
events. Upon receiving a gamepadGuide
event, the device is automatically switched to intercept mode2
(ALL).2
(ALL) - All inputs are intercepted and re-routed over DBus
Typically the intercept mode should be handled by an external application, but
you can also set the intercept mode from the command line using busctl
:
busctl set-property org.shadowblip.InputPlumber \
/org/shadowblip/InputPlumber/CompositeDevice0 \
org.shadowblip.Input.CompositeDevice \
InterceptMode u 2
When InputPlumber is running, a virtual keyboard is created that is used for
sending keyboard inputs. You can also use this keyboard to send keyboard events
using the DBus interface with the SendKey
method. You can do this from the
command line using busctl
:
busctl call org.shadowblip.InputPlumber \
/org/shadowblip/InputPlumber/devices/target/keyboard0 \
org.shadowblip.Input.Keyboard \
SendKey sb KEY_ESC 1
One feature of InputPlumber is the ability to combine multiple input devices together into a single logical input device called a "Composite Device". This is often required for many handheld gaming PCs that have built-in gamepads with special non-standard buttons that show up as multiple independent input devices.
Composite devices are defined as YAML configuration files that follow the Composite Device Schema to combine the defined input devices together. When InputPlumber starts up, it looks at all the input devices on the system and checks to see if they match a composite device configuration. If they do, the input devices are combined into a single logical composite device.
A composite device configuration looks like this:
# yaml-language-server: $schema=https://raw.githubusercontent.com/ShadowBlip/InputPlumber/main/rootfs/usr/share/inputplumber/schema/composite_device_v1.json
version: 1
kind: CompositeDevice
name: OneXPlayer Intel
# Only check for source devices if *any* of the given data matches. If this list is
# empty, then the source devices will *always* be checked.
matches:
- dmi_data:
product_name: ONEXPLAYER
sys_vendor: ONE-NETBOOK
cpu_vendor: GenuineIntel
- dmi_data:
product_name: ONE XPLAYER
sys_vendor: ONE-NETBOOK TECHNOLOGY CO., LTD.
cpu_vendor: GenuineIntel
# One or more source devices to combine into a single virtual device. The events
# from these devices will be watched and translated according to the capability map.
source_devices:
- group: gamepad
evdev:
name: OneXPlayer Gamepad
phys_path: usb-0000:00:14.0-9/input0
- group: keyboard
evdev:
name: AT Translated Set 2 keyboard
phys_path: isa0060/serio0/input0
# The target input device(s) that will be created for this composite device
target_devices:
- gamepad
- mouse
- keyboard
# The ID of a device capability mapping in the 'capability_maps' folder
capability_map_id: oxp1
In addition to combining multiple input devices together, composite devices can
also have a "Capability Map" to define the real capabilities of the input
device. This is commonly necessary for handheld gaming PCs where special
non-standard buttons will emit keyboard events (like CTRL
+ALT
+DEL
) instead
of actual gamepad events.
Capability maps are defined in a separate YAML configuration file that follows the Capability Map Schema and are referenced by their unique ID.
A capability map configuration looks like this:
# yaml-language-server: $schema=https://raw.githubusercontent.com/ShadowBlip/InputPlumber/main/rootfs/usr/share/inputplumber/schema/capability_map_v1.json
version: 1
kind: CapabilityMap
name: OneXPlayer Type 1
id: oxp1
# List of mapped events that are activated by a specific set of activation keys.
mapping:
- name: Orange Button
source_events:
- keyboard: KeyLeftMeta
- keyboard: KeyD
target_event:
gamepad:
button: Guide
InputPlumber is licensed under THE GNU GPLv3+. See LICENSE for details.