Skip to content

Commit

Permalink
chore(docs): update README and dbus XML
Browse files Browse the repository at this point in the history
  • Loading branch information
ShadowApex committed Mar 31, 2024
1 parent 3fad3b2 commit 06e5e98
Show file tree
Hide file tree
Showing 19 changed files with 970 additions and 252 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 27 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,25 @@ dist/$(NAME).raw: dist/$(NAME).tar.gz
mv $(CACHE_DIR)/$(NAME).raw $@
cd dist && sha256sum $(NAME).raw > $(NAME).raw.sha256.txt

.PHONY: dbus-xml
dbus-xml: ## Generate DBus XML spec from running InputPlumber
busctl introspect org.shadowblip.InputPlumber \
--xml-interface /org/shadowblip/InputPlumber/Manager > ./bindings/dbus-xml/org.shadowblip.Input.Manager.xml
busctl introspect org.shadowblip.InputPlumber \
--xml-interface /org/shadowblip/InputPlumber/CompositeDevice0 > ./bindings/dbus-xml/org.shadowblip.Input.CompositeDevice.xml
busctl introspect org.shadowblip.InputPlumber \
--xml-interface /org/shadowblip/InputPlumber/devices/target/dbus0 > ./bindings/dbus-xml/org.shadowblip.Input.DBusDevice.xml
busctl introspect org.shadowblip.InputPlumber \
--xml-interface /org/shadowblip/InputPlumber/devices/target/keyboard0 > ./bindings/dbus-xml/org.shadowblip.Input.Keyboard.xml
busctl introspect org.shadowblip.InputPlumber \
--xml-interface /org/shadowblip/InputPlumber/devices/target/mouse0 > ./bindings/dbus-xml/org.shadowblip.Input.Mouse.xml
busctl introspect org.shadowblip.InputPlumber \
--xml-interface /org/shadowblip/InputPlumber/devices/target/gamepad0 > ./bindings/dbus-xml/org.shadowblip.Input.Gamepad.xml
busctl introspect org.shadowblip.InputPlumber \
--xml-interface /org/shadowblip/InputPlumber/devices/source/event0 > ./bindings/dbus-xml/org.shadowblip.Input.Source.EventDevice.xml
busctl introspect org.shadowblip.InputPlumber \
--xml-interface /org/shadowblip/InputPlumber/devices/source/hidraw0 > ./bindings/dbus-xml/org.shadowblip.Input.Source.HIDRawDevice.xml

XSL_TEMPLATE := ./docs/dbus2markdown.xsl
.PHONY: docs
docs: ## Generate markdown docs for DBus interfaces
Expand All @@ -157,14 +176,18 @@ docs: ## Generate markdown docs for DBus interfaces
sed -i 's/DBus Interface API/Manager DBus Interface API/g' ./docs/manager.md
xsltproc --novalid -o docs/composite_device.md $(XSL_TEMPLATE) ./bindings/dbus-xml/org.shadowblip.Input.CompositeDevice.xml
sed -i 's/DBus Interface API/CompositeDevice DBus Interface API/g' ./docs/composite_device.md
xsltproc --novalid -o docs/target_dbus.md $(XSL_TEMPLATE) ./bindings/dbus-xml/org.shadowblip.Input.DBusDevice.xml
sed -i 's/DBus Interface API/DBusDevice DBus Interface API/g' ./docs/target_dbus.md
xsltproc --novalid -o docs/target_keyboard.md $(XSL_TEMPLATE) ./bindings/dbus-xml/org.shadowblip.Input.Keyboard.xml
sed -i 's/DBus Interface API/Keyboard DBus Interface API/g' ./docs/target_keyboard.md
xsltproc --novalid -o docs/target_mouse.md $(XSL_TEMPLATE) ./bindings/dbus-xml/org.shadowblip.Input.Mouse.xml
sed -i 's/DBus Interface API/Mouse DBus Interface API/g' ./docs/target_mouse.md
xsltproc --novalid -o docs/target_gamepad.md $(XSL_TEMPLATE) ./bindings/dbus-xml/org.shadowblip.Input.Gamepad.xml
sed -i 's/DBus Interface API/Gamepad DBus Interface API/g' ./docs/target_gamepad.md
xsltproc --novalid -o docs/source_event_device.md $(XSL_TEMPLATE) ./bindings/dbus-xml/org.shadowblip.Input.Source.EventDevice.xml
sed -i 's/DBus Interface API/Source EventDevice DBus Interface API/g' ./docs/source_event_device.md
xsltproc --novalid -o docs/source_hidraw_device.md $(XSL_TEMPLATE) ./bindings/dbus-xml/org.shadowblip.Input.Source.HIDRawDevice.xml
sed -i 's/DBus Interface API/Source HIDRaw DBus Interface API/g' ./docs/source_hidraw_device.md
xsltproc --novalid -o docs/keyboard.md $(XSL_TEMPLATE) ./bindings/dbus-xml/org.shadowblip.Input.Keyboard
sed -i 's/DBus Interface API/Keyboard DBus Interface API/g' ./docs/keyboard.md
xsltproc --novalid -o docs/target_dbus_device.md $(XSL_TEMPLATE) ./bindings/dbus-xml/org.shadowblip.Input.DBusDevice.xml
sed -i 's/DBus Interface API/Target DBus Device Interface API/g' ./docs/target_dbus_device.md

# Refer to .releaserc.yaml for release configuration
.PHONY: sem-release
Expand Down
173 changes: 172 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ and translate their input to a variety of virtual device formats.
- [x] Combine multiple input devices
- [x] Emulate mouse, keyboard, and gamepad inputs
- [x] Intercept and route input over DBus for overlay interface control
- [ ] Input mapping profiles to translate source input into the desired target input
- [x] Input mapping profiles to translate source input into the desired target input
- [ ] Route input over the network

## Install
Expand Down Expand Up @@ -63,6 +63,177 @@ You can also interface with DBus using the `busctl` command:
busctl tree org.shadowblip.InputPlumber
```

### Input Profiles

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](rootfs/usr/share/inputplumber/schema/device_profile_v1.json) 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](https://github.com/redhat-developer/yaml-language-server)
you can write profiles with auto-complete and usage information.

Here is a short example:

```yaml
# 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`:

```bash
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

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](https://github.com/ShadowBlip/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-routed
- `1` (PASS) - No inputs are intercepted and re-routed *except* for gamepad `Guide` events. Upon receiving a gamepad `Guide` event, the device is automatically switched to intercept mode `2` (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`:

```bash
busctl set-property org.shadowblip.InputPlumber \
/org/shadowblip/InputPlumber/CompositeDevice0 \
org.shadowblip.Input.CompositeDevice \
InterceptMode u 2
```

### Virtual Keyboard

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`:

```bash
busctl call org.shadowblip.InputPlumber \
/org/shadowblip/InputPlumber/devices/target/keyboard0 \
org.shadowblip.Input.Keyboard \
SendKey sb KEY_ESC 1
```

### Device Compositing & Capability Maps

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](./rootfs/usr/share/inputplumber/schema/composite_device_v1.json)
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
# 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](./rootfs/usr/share/inputplumber/schema/capability_map_v1.json)
and are referenced by their unique ID.

A capability map configuration looks like this:

```yaml
# 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
```

## License

InputPlumber is licensed under THE GNU GPLv3+. See LICENSE for details.
28 changes: 21 additions & 7 deletions bindings/dbus-xml/org.shadowblip.Input.CompositeDevice.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.shadowblip.Input.CompositeDevice">
<!--
Load the device profile from the given path
-->
<method name="LoadProfilePath">
<arg name="path" type="s" direction="in"/>
</method>
<!--
List of capabilities that all source devices implement
-->
<property name="Capabilities" type="as" access="read"/>
<!--
Target dbus devices that this [CompositeDevice] is managing
-->
Expand All @@ -15,6 +25,10 @@
Name of the composite device
-->
<property name="Name" type="s" access="read"/>
<!--
Name of the currently loaded profile
-->
<property name="ProfileName" type="s" access="read"/>
<!--
List of source devices that this composite device is processing inputs for
-->
Expand All @@ -29,13 +43,6 @@
<arg type="s" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping">
</method>
<method name="GetMachineId">
<arg type="s" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg name="interface_name" type="s" direction="in"/>
Expand All @@ -60,5 +67,12 @@
<arg name="invalidated_properties" type="as"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping">
</method>
<method name="GetMachineId">
<arg type="s" direction="out"/>
</method>
</interface>
</node>

14 changes: 7 additions & 7 deletions bindings/dbus-xml/org.shadowblip.Input.DBusDevice.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping">
</method>
<method name="GetMachineId">
<arg type="s" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" direction="out"/>
Expand All @@ -27,6 +20,13 @@
-->
<property name="Name" type="s" access="read"/>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping">
</method>
<method name="GetMachineId">
<arg type="s" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg name="interface_name" type="s" direction="in"/>
Expand Down
48 changes: 48 additions & 0 deletions bindings/dbus-xml/org.shadowblip.Input.Gamepad.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping">
</method>
<method name="GetMachineId">
<arg type="s" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg name="interface_name" type="s" direction="in"/>
<arg name="property_name" type="s" direction="in"/>
<arg type="v" direction="out"/>
</method>
<method name="Set">
<arg name="interface_name" type="s" direction="in"/>
<arg name="property_name" type="s" direction="in"/>
<arg name="value" type="v" direction="in"/>
</method>
<method name="GetAll">
<arg name="interface_name" type="s" direction="in"/>
<arg type="a{sv}" direction="out"/>
</method>
<!--
Emits the `org.freedesktop.DBus.Properties.PropertiesChanged` signal.
-->
<signal name="PropertiesChanged">
<arg name="interface_name" type="s"/>
<arg name="changed_properties" type="a{sv}"/>
<arg name="invalidated_properties" type="as"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" direction="out"/>
</method>
</interface>
<interface name="org.shadowblip.Input.Gamepad">
<!--
Name of the DBus device
-->
<property name="Name" type="s" access="read"/>
</interface>
</node>

Loading

0 comments on commit 06e5e98

Please sign in to comment.