Skip to content

Instantly share code, notes, and snippets.

@gatopeich
Created February 5, 2023 10:26
Show Gist options
  • Save gatopeich/21863b353b505ee3b116a2135a3a4315 to your computer and use it in GitHub Desktop.
Save gatopeich/21863b353b505ee3b116a2135a3a4315 to your computer and use it in GitHub Desktop.
Mapping keys and mouse to gamepad with Linux UDEV system
This is something I never had the time to put together.
Today I asked openai.org and it provided a nice walk-through...
QUESTION> How can I map gamepad buttons to keys and mouse with UDEV?
To map gamepad buttons to keyboard and mouse inputs with UDEV, you will need to create a udev rule file to specify the mapping. Here are the steps:
Identify the gamepad device name: Run ls /dev/input/by-id to see a list of all input devices connected to your system. Look for the one that corresponds to your gamepad and note its name, e.g. /dev/input/by-id/usb-<VENDOR_ID>-<PRODUCT_ID>.
Create a udev rule file: Create a new file in /etc/udev/rules.d/ with a descriptive name, e.g. 99-gamepad-mapping.rules.
Add the mapping rules: In the rule file, add a line for each button you want to map. The format of each line is as follows:
makefile
SUBSYSTEM=="input", ATTRS{idVendor}=="<VENDOR_ID>", ATTRS{idProduct}=="<PRODUCT_ID>", ENV{ID_INPUT_KEY}=="<KEY_NAME>", RUN+="<COMMAND>"
Replace <VENDOR_ID> and <PRODUCT_ID> with the values you noted in step 1.
Replace <KEY_NAME> with the name of the button you want to map. The names of buttons can be found by running evtest on the device and pressing buttons to see the corresponding output.
Replace <COMMAND> with a shell command that simulates the desired keyboard or mouse input. For example, to map a button to the "A" key, you would use /bin/sh -c 'echo a > /dev/input/uinput'.
Reload udev rules: Run sudo udevadm control --reload-rules to reload the udev rules and apply the changes.
Test the mapping: Test the mapping by pressing the buttons on your gamepad and checking if the corresponding keys or mouse inputs are triggered.
Note: The exact steps may vary depending on the Linux distribution you are using.
QUESTION #2: Thanks that is helpful. Only missing how to mapping axis to mouse a... (accidentally hit enter)
To map a gamepad axis to mouse movement, you can use the jstest utility to identify the axis number, and then use that in the udev rule to control the mouse. Here are the steps:
Identify the gamepad axis number: Run jstest /dev/input/js0 (replace js0 with the appropriate joystick device for your system) to see the state of all axes and buttons on the gamepad. Move the joystick or trigger you want to map and note the number of the corresponding axis.
Create a udev rule file: Create a new file in /etc/udev/rules.d/ with a descriptive name, e.g. 99-gamepad-mapping.rules.
Add the mapping rule: In the rule file, add the following line to map the axis to mouse movement:
makefile
SUBSYSTEM=="input", ATTRS{idVendor}=="<VENDOR_ID>", ATTRS{idProduct}=="<PRODUCT_ID>", ENV{ID_INPUT_JOYSTICK}=="1", ATTRS{[axis_number]}=="+*", RUN+="/usr/bin/xdotool mousemove_relative -- [axis_number]"
Replace <VENDOR_ID> and <PRODUCT_ID> with the values you noted in step 1.
Replace [axis_number] with the number of the axis you want to map, as identified in step 1.
Reload udev rules: Run sudo udevadm control --reload-rules to reload the udev rules and apply the changes.
Test the mapping: Test the mapping by moving the joystick or trigger and checking if the mouse pointer moves accordingly.
Note: The exact steps may vary depending on the Linux distribution you are using, and you may need to adjust the xdotool command to fit your specific needs.
QUESTION #2 (edited): Thanks that is helpful. Only missing how to map axis to mouse movement and wheels
To map gamepad axes to mouse movement and wheel inputs with UDEV, you can use the evtest tool to monitor the events generated by the axes and then write a udev rule to map them to desired mouse inputs. Here's an example of how to do this:
Install evtest: Run sudo apt-get install evtest or equivalent to install the evtest tool.
Identify the gamepad device name: Run ls /dev/input/by-id to see a list of all input devices connected to your system. Look for the one that corresponds to your gamepad and note its name, e.g. /dev/input/by-id/usb-<VENDOR_ID>-<PRODUCT_ID>.
Test the axes with evtest: Run sudo evtest /dev/input/by-id/<DEVICE_NAME> to start the evtest tool and monitor the events generated by the gamepad. Move the axes you want to map to mouse movement and note the event codes generated.
Create a udev rule file: Create a new file in /etc/udev/rules.d/ with a descriptive name, e.g. 99-gamepad-mapping.rules.
Add the mapping rules: In the rule file, add a line for each axis you want to map. The format of each line is as follows:
makefile
SUBSYSTEM=="input", ATTRS{idVendor}=="<VENDOR_ID>", ATTRS{idProduct}=="<PRODUCT_ID>", ENV{ID_INPUT_ABS}=="<EVENT_CODE>", RUN+="/bin/sh -c 'echo <MOUSE_INPUT> > /dev/input/mice'"
Replace <VENDOR_ID> and <PRODUCT_ID> with the values you noted in step 2.
Replace <EVENT_CODE> with the event code for the axis you want to map, which you noted in step 3.
Replace <MOUSE_INPUT> with the desired mouse input. To map an axis to mouse movement, you would use $((<EVENT_VALUE> * <SCALING_FACTOR>)). To map an axis to mouse wheel, you would use $((<EVENT_VALUE> * <SCALING_FACTOR> / WHEEL_DELTA)). Replace <EVENT_VALUE> with the value of the axis event, <SCALING_FACTOR> with the desired scaling factor for mouse movement, and WHEEL_DELTA with the standard mouse wheel delta (usually 120).
Reload udev rules: Run sudo udevadm control --reload-rules to reload the udev rules and apply the changes.
Test the mapping: Test the mapping by moving the axes on your gamepad and checking if the corresponding mouse movement or wheel inputs are triggered.
Note: The exact steps may vary depending on the Linux distribution you are using.
@gatopeich
Copy link
Author

To be honest the instructions provided by OpenAI have glitches but saved me a lot of time gathering information about obscure topics

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment