XBOXDRV(1)
๐ฎ xboxdrv โ the user-space Xbox/Xbox360 gamepad driver (from the xboxdrv (1) manual, User Commands) ๐
โจ NAME โจ
xboxdrv โ a driver for Xbox/Xbox360 gamepads that works entirely in userspace ๐ฆ
โจ SYNOPSIS โจ
xboxdrv [OPTION]... [--] [COMMAND] [ARGUMENTS]
โจ DESCRIPTION โจ
okay so bestie, listen. xboxdrv is a driver for Xbox and Xbox360 gamepads. How does it do it? It reads the raw data straight off your controller using the userspace library libusb, then hands that interpreted data over to the kernel through uinput. And that is the whole trick โ because of it, xboxdrv can hand you regular joystick and event devices, which means it plays nice with literally all Linux software. no cap. ๐
But wait, it's not just a driver. xboxdrv also ships with a whole rich set of configuration options that let you tweak the abilities of the virtual input devices it's gonna create. We're talking basic button and axis remapping, sure โ but also the fancy stuff: mouse and keyboard emulation, auto-fire, throttle control emulation. it's giving power user. ๐
And plot twist: xboxdrv can also read input data directly from an event device. That means you get all of xboxdrv's configurability on regular PC joysticks, keyboards and mice, which makes xboxdrv serve a similar purpose as joy2key. See the --evdev option below for the deets. ๐ง
Also, when you provide a COMMAND, xboxdrv will launch that application and keep running till that application exits. It's a convenience thing, so that using xboxdrv in wrapper scripts is easier. Peep the section [Writing Start-Up Scripts for Games] for more. ๐ธ
โจ OPTIONS โจ
๐ GENERAL OPTIONS ๐
-h,--helpโ shows you the help text and dips. ๐ซถ-V,--versionโ prints the version number and exits. โญ-v,--verboseโ prints verbose messages.--debugโ prints even more verbose messages than--verbose. like, maximum yapping. ๐-s,--silentโ stops displaying controller events on the terminal. For regular use you should always use this one, because dumping output to the terminal can eat up quite a bit of CPU.--quietโ doesn't display the startup text and suppresses most other output.--priority PRIORITYโ possible values for PRIORITY are"normal"and"realtime". Realtime scheduling gives thexboxdrvprocess higher priority, which lets it function properly even when the machine is under load.
Note that realtime priority requires running xboxdrv as root โ when running xboxdrv as a user, there's no way to increase the priority.
โ ๏ธ This option is deprecated โ use chrt(1) instead to get the same effect.
๐ LIST OPTIONS ๐
--help-ledโ lists the possible values for the led.--help-devicesโ lists supported devices.--list-supported-devicesโ lists supported devices (used byxboxdrv-daemon.py).--list-supported-devices-xpadโ lists supported devices inxpad.cstyle.--help-absโ lists all allowedEV_ABSsymbols.--help-relโ lists all allowedEV_RELsymbols.--help-keyโ lists all allowedEV_KEYsymbols.--help-x11keysymโ lists all allowed X11 Keysym symbols.--help-axisโ lists all allowedXboxAxissymbols.--help-buttonโ lists all allowedXboxButtonsymbols.--help-allโ lists all symbols that can be used in--ui-buttonmap,--ui-axismap,--buttonmapand--axismap. This option is the same as--help-abs,--help-rel,--help-key,--help-x11keysym,--help-axisand--help-buttoncombined. โจ
๐ CONFIG FILE OPTIONS ๐
-c,--config FILEโ reads configuration information from FILE. Configurations from the file are handled as if they were command line options at the position of--config FILE.
The syntax of FILE is the familiar INI syntax used for many configuration files. Regular key/value pairs must go into the [xboxdrv] section. '#' and ';' can be used for comments. Key names mostly have the same name as command line options. Command line options that take a list of input mappings (--ui-buttonmap, --ui-axismap, --evdev-absmap, ...) can be split off into their own section for better readability.
The examples/ directory contains some example configuration files. ๐
[xboxdrv]
silent=true
deadzone=6000
dpad-as-button=true
trigger-as-button=true
[ui-axismap]
x2=REL_X:10
y2=REL_Y:-10
x1=KEY_A:KEY_D
y1=KEY_W:KEY_S
[ui-buttonmap]
a=KEY_LEFTSHIFT
b=BTN_C
x=BTN_EXTRA
y=KEY_C
[ui-buttonmap]
lb=BTN_RIGHT
rb=KEY_SPACE
[ui-buttonmap]
lt=KEY_Z
rt=BTN_LEFT
[ui-buttonmap]
dl=KEY_4
dr=KEY_2
du=REL_WHEEL:-1:150
dd=REL_WHEEL:1:150
[ui-buttonmap]
back=KEY_TAB
start=KEY_ESC
# EOF #
--alt-config FILEโ a shortcut for writing--next-config --config FILE.
To load multiple configuration options use:
xboxdrv --config first.ini --alt-config second.ini --alt-config third.ini
-o,--option NAME=VALUEโ sets an option as if it came from a config file, but from the command line.--write-config FILEโ writes an example configuration file to FILE.
๐ DAEMON OPTIONS ๐
-D,--daemonโ runsxboxdrvas a daemon. If this option is given,xboxdrvwill listen to udev for USB connection events and launch driver threads for newly connected controllers.
Configuration options can still be supplied as usual. Note however that when run as daemon, xboxdrv will not create new uinput devices on demand โ instead it will only create devices once at startup for the given configurations, and then assign new controllers to these configurations. While this means xboxdrv can't support an unlimited number of controllers, it also means xboxdrv can allow hot plugging even for applications that don't support it themselves, since applications will only see the permanent device files, not the controller that xboxdrv will change around under the hood. sneaky. ๐
An example configuration that supports three controllers would look like this:
xboxdrv --daemon \
# config options for the first controller
--next-controller \
# config options for the second controller
--next-controller
# config options for the third controller
The --match option can be used to limit the controller slots to only those controllers that match the given RULE, and thus be used to assign configurations only to specific controllers.
--detachโ detachesxboxdrvfrom the current shell. Only valid if--daemonis given.--pid-file FILEโ writes thexboxdrvdaemon process id to FILE.--dbus BUSโ sets which bus typexboxdrvshould connect to. Allowed values for BUS aresession,system,disabledandauto. The default isauto, which will detect the appropriate bus type depending on ifxboxdrvis run as root (system) or as user (session). Running withdisabledwill disable D-Bus support completely.--on-connect EXEโ launches EXE when a controller gets connected. As arguments"BUSDEV:DEVNUM","idVendor:idProduct","NAMEare provided.--on-disconnect EXEโ launches EXE when a controller gets disconnected. As arguments"BUSDEV:DEVNUM","idVendor:idProduct","NAMEare provided.
๐ฆ DEVICE OPTIONS ๐ฆ
-L,--list-controllerโ lists the available controllers on the system.-i,--id Nโ uses the controller with id N (default:0). Use--list-controllerto obtain a list of available controllers.-w,--wid Nโ uses the wireless controller with wid N (default:0).--device-by-path BUS:DEVโ uses the controller atBUS:DEV, and does no automatic scanning whatsoever. Useful for cases when a controller isn't known byxboxdrv, but supports one of the given protocols.--device-by-id VENDOR:PRODUCTโ uses the device that matchesVENDOR:PRODUCT(as returned bylsusb). Useful for cases when a controller isn't known byxboxdrv, but supports one of the given protocols.--type TYPEโ ignores autodetection and enforces the controller type. Possible values for TYPE:xboxxbox-matxbox360xbox360-wirelessxbox360-guitarfirestormfirestorm-vsbsaitek-p2500generic-usb
The generic-usb type is a special type that will work with any USB controller โ it will however not interpret the input it gets, it'll just dump it to the console for development purposes. See --generic-usb-spec for further information.
-d,--detach-kernel-driverโ detaches the kernel driver that's currently associated with the given device. Super useful when you have thexpadmodule loaded and want to usexboxdrvwithout unloading it. ๐ฅ--generic-usb-spec NAME=VALUE,...โ lets you specify from which endpointgeneric-usbwill read. The spec has the formNAME=VALUE,.... Allowed values are:vid=HEXโ the vendor id of the controller to which this spec applies.pid=HEXโ the product id of the controller to which this spec applies.if=NUMโ the interface from whichGenericUSBControllershould be read.ep=NUMโ the endpoint from whichGenericUSBControllershould be read.
๐ EVDEV OPTION ๐
--evdev DEVICEโ lets you read input data from a regular event device. This lets you usexboxdrvon regular PC joysticks. The data that's read from the event device is converted internally into aXboxMsgobject and then passed through the same configuration pipeline as it would be for a regular Xbox360 controller. That means you get to use all the regular configurability โ but it also limits you to the number of axes and buttons that an Xbox360 controller provides. ๐
okay so real talk bestie ๐
โ your average regular PC joystick is gonna create its own /dev/input/jsX device all by itself, and that's lowkey a problem, because then a game might not properly detect the joystick device that xboxdrv made. The easiest fix? Just delete the old joystick and rename the device xboxdrv created to /dev/input/js0. And if you're running udev, this whole operation is harmless โ it automatically reverses itself when you unplug the controller and plug it back in, or when you reboot your computer. ๐ซถ no cap.
--evdev-debugโ the evdev event handler will print every single event it receives straight to stdout, which makes it super easy to see which events a given controller is sending. โจ--evdev-no-grabโ by default the evdev driver grabs the device, which means no other application can receive events from it. Why? Because otherwise an app would get every event twice โ once from the original device and once from the virtual xboxdrv one, and that's confusing af. But sometimes you don't want the grab, like when you're only mapping an otherwise unhandled subset of keys on a device (say, the multimedia keys on a keyboard). This option turns the grab off. ๐--evdev-absmapABSMAP,... โ sets how evdev events get mapped to Xbox axis events. Here's the signature:
ABSMAP = EVDEV_ABS [ "+", "-" ] "=" XBOXAXIS ;
An example configuration would look like this:
--evdev-absmap ABS_X=x1,ABS_Y=y1,ABS_RZ=x2,ABS_THROTTLE=y2,ABS_HAT0X=dpad_x,ABS_HAT0Y=dpad_y
xboxdrv will output on startup a full list of event names that the given event device supports, and those are the names you can use in place of EVDEV_ABS. ๐
It's also possible to map a half-axis with a command like:
--evdev-absmap ABS_Y+=LT,ABS_Y-=RT
That maps the upward movement of the Y axis to the left trigger, and the downward movement to the right trigger. iconic.
--evdev-keymapKEYMAP โ sets how evdev events get mapped to Xbox controller events. Example configuration:
--evdev-keymap BTN_TRIGGER=a,BTN_THUMB=b,BTN_THUMB2=x
xboxdrv will output on start a full list of event names that the given event device supports. ๐ฆ
โจ STATUS OPTIONS โจ
-l,--ledNUM โ sets the LED status. Possible values for NUM are:
LED Status Codes
0โ off1โ all blinking2โ 1/top-left blink, then on3โ 2/top-right blink, then on4โ 3/bottom-left blink, then on5โ 4/bottom-right blink, then on6โ 1/top-left on7โ 2/top-right on8โ 3/bottom-left on9โ 4/bottom-right on10โ rotate11โ blink12โ blink slower13โ rotate with two lights14โ blink15โ blink once--rumble-gainAMOUNT โ you can change the rumble strength like this:
$ xboxdrv --rumble-gain 50%
Values larger than 100% are possible too, and they'll amplify small rumble commands. Rumble commands that are already at the max stay unchanged. ๐ฅ
-q,--quitโ exits xboxdrv after setting LED or rumble values. bye bestie ๐
๐ CHATPAD OPTIONS (EXPERIMENTAL) ๐
Chatpad support is still experimental. Basic keyboard usage will work, but there's currently no support for customization or for the green and orange key modifiers. ๐
Starting xboxdrv multiple times in a row with the --chatpad option can crash the controller. Unplugging it and plugging it back in should reset it.
--chatpadโ enables support for the Xbox360 Chatpad. WARNING: this is preliminary code, it will crash your gamepad when xboxdrv is started multiple times, and it won't provide proper keymapping for any of the umlauts and special characters. ๐--chatpad-no-initโ this starts chatpad support without sending the init sequence, which potentially avoids crashing the controller if xboxdrv is started multiple times.--chatpad-debugโ outputs raw chatpad data to stdout for debugging purposes.
๐ธ HEADSET OPTIONS (EXPERIMENTAL, XBOX360 USB ONLY) ๐ธ
Xboxdrv does not support the headset, so heads up: the options below are for developers only and will dump raw headset data, not .wav files.
--headsetโ enables headset support and dumps incoming data to stdout.--headset-dumpFILE โ enables headset support and dumps incoming data to FILE.--headset-playFILE โ enables headset support and sends FILE to the headset for playback.
๐ FORCE FEEDBACK ๐
--force-feedbackโ enables the standard kernel force feedback interface. It's disabled by default because it causes trouble with some applications running in Wine. ๐ญ
Since the Xbox360 controller supports just rumble and not full force feedback, xboxdrv tries to emulate the other effects. This emulation hasn't been tested much and might not always work as expected โ bug reports and test cases are welcome, fr fr.
Note that you must always close the application that's using force feedback before you close the xboxdrv driver. Otherwise you might end up with a hanging, non-interruptable xboxdrv process that requires a reboot to get rid of. ๐
When using xboxdrv in daemon mode with multiple controller slots, you have to enable force feedback for each slot separately.
--ff-deviceDEVICEID โ selects which virtual device the force-feedback callbacks get connected to. It defaults tojoystick. Other allowed values aremouse,keyboard, and any integer number. See--ui-buttonmapfor more info on how device-ids work.-R,--test-rumbleโ pressingLTmoves the left rumble motor, and pressingRTmoves the right one. The rumble motor strength depends on how hard you press. Super useful for testing the rumble motors. โจ-r,--rumbleL,R โ sets the speed for both rumble motors. Values from0to255are accepted, the default is0,0.
๐ CONTROLLER SLOT OPTIONS ๐
Controller slots are used when you're running xboxdrv in daemon mode. Each slot represents a complete controller configuration. So if you want multiple controllers in daemon mode, you have to supply multiple controller slots. periodt.
--controller-slotN โ switches to the controller slot with the number N. Numbering starts at zero.--next-controllerโ switches to the next controller slot.--matchRULE,... โ limits a controller slot to devices that match any one of the given rules. Possible match rules are:usbid=VENDOR:PRODUCTโ match controllers that have the given USB vendor and product ids.vendor=VENDORโ match controllers that have the given USBidVendor.product=PRODUCTโ match controllers that have the given USBidProduct.property=PROPERTY:VALUEโ match against an arbitrary udev property, with name PROPERTY and value VALUE.usbpath=BUS:DEVโ match against the USB path given by BUS and DEV.usbserial=SERIALโ match against the USBiSerialnumber.
--match-groupRULE,... โ limits a controller slot to devices that match all of the given rules. Possible match rules are the same as for--match.
๐ฆ CONFIG SLOT OPTIONS ๐ฆ
You can use multiple configurations โ called config slots โ with your controller. By default you switch between them by pressing the Guide button, but you can also set another button via the --toggle option. ๐
--config-slotNUM โ selects the config slot NUM.--next-configโ allows the creation of an alternative uinput configuration, which you can toggle to at runtime by pressing the ui-toggle button (defaults to guide).
$ xboxdrv \
--mouse \
--next-config
--ui-axismap X1=ABS_X,Y1=ABS_Y \
--ui-buttonmap A=JS_0,B=JS_1
The above configuration would install mouse emulation as the first configuration and a simple joystick emulation as the second configuration โ letting you toggle between mouse emulation and joystick handling by pressing the guide button. ๐
Note that--next-configis currently limited to only configurations done with--ui-buttonmapand--ui-axismap. Autofire, throttle emulation, deadzones and all other things can currently not be switched at runtime. ๐
--toggleXBOXBTN โ sets the button that will be used to toggle between different configurations. A value of'void'will disable the toggle button. If no toggle button is specified, the guide button will be used to toggle between configurations.
โญ CONFIGURATION OPTIONS โญ
--modifierMOD โ adds a modifier to the modifier stack. See[Modifier]for a full list of possible modifiers.--timeoutMSEC โ specifies the number of milliseconds that xboxdrv will wait for events from the controller before moving on and processing things like auto-fire or relative-axis. The default value is10. Smaller values give you a higher resolution auto fire and relative event movement, but will waste a little more CPU. ๐ง-b,--buttonmapBUTTON=BUTTON,... โ button remapping is available via the--buttonmapoption. If you want to swap buttonAandB, start with:
$ xboxdrv --buttonmap A=B,B=A
If you want all face buttons to send out A button events:
$ xboxdrv --buttonmap B=A,X=A,Y=A
Possible button names are (aliases are in parenthesis):
okay so first up, the button names you can use in your mappings: ๐
start,backโ start, back buttonsguideโ big X-button in the middle (Xbox360 only)a(1),b(2),x(3),y(4)โ face buttonsblack,whiteโ black, white buttons (Xbox1 only, mapped tolb,rbon Xbox360)lb(5),rb(6)โ shoulder buttons (Xbox360 only, mapped toblack,whiteon Xbox1)lt(7),rt(8)โ analog trigger (needs--trigger-as-buttonoption)tl,trโ pressing the left or right analog stickdu(up),dd(down),dl(left),dr(right)โ dpad directions (needs--dpad-as-buttonoption)green,red,yellow,blue,orangeโ guitar buttons
Just like with --ui-buttonmap you can add button filter to each button. โจ
--axismap AXIS=MAPPING,...โ Axis remapping is available via--axismapand works the same as button mapping. In addition you can supply a sign to indicate that an axis should be inverted. So if you want to invert they1axis start with:
$ xboxdrv --axismap -Y1=Y1
If you want to swap the left and right stick start with:
$ xboxdrv --axismap X2=X1,Y2=Y1,X1=X2,Y1=Y2
Possible axis names are: x1, y1, x2, y2, lt, rt
Swapping lt or rt with x1, y1, x2, y2 will not work properly, since their range is different. ๐ญ
Just like with --ui-axismap you can add axis filter to each axis. ๐ธ
โจ MODIFIER PRESET CONFIGURATION OPTIONS โจ
The options in this section are shortcuts for --modifier options. Unlike --modifier they are not order dependent, but have a predefined order that is used no matter the order in which the options are given. ๐
--autofire BUTTON=FREQUENCY,...โ Autofire mapping allows you to let a button automatically fire with a given frequency in milliseconds:
$ xboxdrv --autofire A=250
Combining --autofire with button map allows you to have one button act as autofire while another one, emitting the same signal, acts normally.
$ xboxdrv --autofire B=250 --buttonmap B=A
--axis-sensitivty AXIS=SENSITIVITY,...โ The sensitive of an axis can be adjusted via--axis-sensitivty:
$ xboxdrv --axis-sensitivty X1=-1.0,Y1=-1.0
A value of 0 gives you the default linear sensitivity, values larger then 0 will give you higher sensitivity, while values smaller then 0 will give you lower sensitivity. Sensitivity values in the range of [-1, 1] will generally give good results, everything beyond that won't be of much practical use.
Sensitivity works by applying:
t = 2 ** sensitivity;
pos = (1.0f - (1.0f - pos) ** t) ** (1 / t);
To the value of the axis, this means that both the minimum value and the maximum value of the axis will always stay the same, just the response inbetween changes.
For a complete freeform way to change the axis response see the Response Curve Filter.
--calibration CALIBRATIONSPECโ If your gamepad for some reason can't reach the maximum value or isn't centered properly you can fix that via the calibration options:
$ xboxdrv --calibration X2=-32768:0:32767
X2 is the axis name and the three values that follow are min, center and max. Simply insert the values that jstest reports when your axis is in the respective positions.
You can also use the calibration option if you want to make your joystick more sensitive. A setting of:
xboxdrv --calibration AXIS=MIN:CENTER:MAX,...
Will cause the joystick device report maximum position when your stick is only moved half the way.
--deadzone NUMโ The deadzone is the area at which the sticks do not report any events. The default is zero, which gives the best sensitivity but might also cause trouble in some games in that the character or camera might move without moving the stick. To fix this one has to set the value to something higher:
$ xboxdrv --deadzone 4000
A value of 4000 works quite well for most games.
You can also give the deadzone in percentage:
$ xboxdrv --deadzone 15%
--deadzone-trigger NUMโ The left and right trigger have a separate deadzone value which can be specified with:
$ xboxdrv --deadzone-trigger 15%
--dpad-rotation DEGREEโ Allows you to rotate the dpad.DEGREEmust be a multiple of 45. This can be useful in isometric games where the playfield itself is rotated, thus a:
xboxdrv --dpad-rotation 45
Will give you controls that are relative to your character instead of your viewpoint.
--four-way-restrictorโ The--four-way-restrictoroption allows one to limit the movement on both analogsticks to only four directions (up, down, left, right), the diagonals (up/left, up/right, down/left, down/right) are filtered out from the output. This option is useful for games such as Tetris, that don't need diagonals and where you don't want to accidentally trigger the down-move while trying to do a left/right move.--relative-axis AXIS=NUM,...โ The function--relative-axisallows you to change the behaviour of an axis so that your movement of it moves its value up or down instead of applying it directly. This allows you to simulate throttle control for flightsim games.
Since the axis might be upside down, you might want to use the --axismap function to reverse it.
$ xboxdrv --relative-axis y2=64000 --axismap -y2=y2
--square-axisโ The Xbox360 gamepad, as most other current day gamepads, features a circular movement range, which restricts the movement so that the distance to the center never gets beyond 1. This means that when you have the controller at the top/left the value reported is(0.7, 0.7)(i.e. length 1, angle 45) instead of(1,1). This behaviour is different then most classic PC joysticks, which had a square range and would report(1,1)when hold in the top/left corner.
Some old games (i.e. mostly DOS stuff) require a square movement range and will not function properly with the Xbox360 gamepad. Via the --square-axis option you can work around this issue and diagonals will be reported as (1,1).
๐ UINPUT PRESET CONFIGURATION OPTIONS ๐
The following options are simple shortcuts for common configurations that can be accomplished manually by using --ui-buttonmap and --ui-axismap. ๐
--trigger-as-buttonโ LT and RT send button instead of axis events--trigger-as-zaxisโ Combine LT and RT to form a zaxis instead--dpad-as-buttonโ The DPad sends button instead of axis events.--dpad-onlyโ Both sticks are ignored, only the DPad sends out axis events. Useful for games that might get confused by additional analog axis. Combining this option with--trigger-as-buttonis recommend in most situations.--guitarโ Sets a predefined button and axis mapping for use with guitar controllers. This mainly gets rid of a few unnecessary buttons and axis not used by a guitar controller.-m,--mouseโ Lets the controller act as a mouse. It is identical to:
$ xboxdrv \
--dpad-as-button
--deadzone 4000
--trigger-as-zaxis
--axismap "-y2=y2,-trigger=trigger"
--ui-axismap "x1=REL_X:15:20,y1=REL_Y:15:20,y2=REL_WHEEL:5:100,x2=REL_HWHEEL:5:100,trigger=REL_WHEEL:5:100"
--ui-buttonmap "a=BTN_LEFT,b=BTN_RIGHT,x=BTN_MIDDLE,y=KEY_ENTER,rb=KEY_PAGEDOWN,lb=KEY_PAGEUP,"
--ui-buttonmap "dl=KEY_LEFT,dr=KEY_RIGHT,du=KEY_UP,dd=KEY_DOWN,"
--ui-buttonmap "start=KEY_FORWARD,back=KEY_BACK,guide=KEY_ESC,tl=void,tr=void"
You can customize it however you want bestie, just make sure --mouse comes before your customization options on the command line. Order matters, she's picky ๐
Heads up: if you've got your mouse buttons switched, you gotta adjust all of the above to match your mouse config, or the button events will come out wrong. No cap. ๐
--mimic-xpadโ makes xboxdrv use the exact same axis and button names as thexpadkernel driver for wired Xbox360 controller ๐ฎ--mimic-xpad-wirelessโ makes xboxdrv use the exact same axis and button names as thexpadkernel driver for wired Xbox360 controller ๐ฎ
๐ฆ UINPUT CONFIGURATION OPTIONS ๐ฆ
--no-uinputโ literally just don't start UInput at all. Instead you simply read events from the controller, which is lowkey perfect for debugging ๐โจ--no-extra-devicesโ okay so by default xboxdrv allocates multiple uinput devices and sorts events to each one of them. So mouse-ish events likeBTN_LEFTorREL_Xgo to a virtual mouse device, whileABS_Xevents go to a virtual joystick device, andKEY_ESCgoes to a virtual keyboard device. Very organized, very demure. ๐
This option disables that automatism and sends all events to the same virtual device. One device, one vibe. ๐
Manual assignment to a specific device (i.e. KEY_ESC@keyboard, BTN_A@joystick, ...) is still possible though, so you're not trapped.
--no-extra-eventsโ again, by default xboxdrv allocates multiple uinput devices and sorts events to each of them. Mouse-related events likeBTN_LEFTorREL_Xgo to a virtual mouse device,ABS_Xevents go to a virtual joystick device,KEY_ESCgoes to a virtual keyboard device. You know the drill. ๐ฑ๏ธโจ๏ธ๐น๏ธ
Now, to make sure a mouse, keyboard or joystick device is properly detected by Xorg, the kernel or libraries such as SDL, xboxdrv will insert extra dummy events. For example a mouse device needs REL_X and REL_Y events to be detected as such, but a configuration that only wants to emulate the mouse buttons won't provide those, so xboxdrv will add them automatically. The --no-extra-events option switches this behaviour off. โ
--device-nameNAME โ changes the descriptive name the device will have. This option acts the same as--device-names CURRENTSLOT.auto=NAME๐ท๏ธ--device-namesTYPE.SLOT=NAME,... โ changes the descriptive name the device will have. TYPE is one ofmouse,keyboard,joystick,autoor a number. SLOT is a slot number orauto. Theautoname acts as a wildcard and matches everything. โจ--device-usbidVENDOR:PRODUCT:VERSION:BUS โ changes the vendor, product, version and bus id that the device will have. The last two arguments are optional. This option acts the same as--device-usbids CURRENTSLOT.auto=VENDOR:PRODUCT:VERSION:BUS๐--device-usbidsTYPE.SLOT=VENDOR:PRODUCT:VERSION:BUS,... โ changes the vendor, product, version and bus id the device will have. TYPE is one ofmouse,keyboard,joystick,autoor a number. SLOT is a slot number orauto. Theautoname acts as a wildcard and matches everything. ๐ช--ui-clearโ removes all uinput mappings and leaves the driver in a blank state, only mapping the things you added yourself. If you just want to get rid of individual buttons, use thevoidevent instead. Clean slate energy ๐งผ๐--ui-buttonmapUIBUTTONSPEC,... โ bestie this one is a whole meal, let me lay it out:
UIBUTTONSPEC = XBOXBUTTON [ "+" XBOXBUTTON ] [ "^" FILTER ] ... "=" ( RELSPEC | BTNSPEC | EXECSPEC ) ;
RELSPEC = [ DEVICEID "-" ] "REL_" [ ":" [ VALUE ] [ ":" REPEAT ] ] ;
BTNSPEC = [ DEVICEID "-" ] ( ( "BTN_" NAME ) | ( "KEY_" NAME ) ) { "+" BTNSPEC } ;
EXECSPEC = PROGRAM { ":" ARGUMENT } ;
XBOXBUTTON = "a" | "b" | "x" | "y" | "lb" | "rb" | "lt" | "rt" |
"tl" | "tr" | "start" | "select" | "back" | "guide" | "black" | "white" ;
FILTER = "toggle" | "invert" | "autofire" [ ":" RATE ] [ ":" DELAY ] | log [ ":" STRING ] ;
NAME = STRING ;
VALUE = NUMBER ;
REPEAT = NUMBER ;
DEVICEID = NUMBER ;
This lets you change the event code that gets sent to the kernel for buttons. The usage is similar to the normal button mapping, except the right hand side is an event name from /usr/include/linux/input.h. You can use all KEY_ or BTN_ codes for --ui-buttonmap. ๐ธ
If the right hand side is left empty, all the supplied filters will be added to the already existing button binding instead of making a new one. Sneaky but useful. ๐
Aside from the named keys, you can also give the input code directly as a number via the syntax KEY_#NUM. ๐ข
Instead of the low level KEY_ names (which represent keycodes), you can also use the higher level X11 keysyms XK_. The keysyms have the advantage that they map directly to the key you expect, while a KEY_ name gets mangled by the X11 keymap and will often not report what you expect if you use a keymap that's different than your keyboard (i.e. dvorak on a qwerty keyboard). It's giving chaos otherwise ๐ญ
A full list of valid X11 keysyms can be obtained with --help-x11keysym. ๐
For joystick buttons there is, in addition to the BTN_JOYSTICK, BTN_X, etc. macros, the special name JS_$NUM, which sets the given button to the $NUMs joystick button, i.e.:
$ xboxdrv --ui-clear --ui-buttonmap A=JS_0,B=JS_1
Note that this will only work if no other joystick button ids are in the way. ๐ง
You can also map a button to a REL_ event. In that case you can supply additional parameters in the form of:
$ xboxdrv --ui-buttonmap X=REL_???:VALUE:REPEAT
VALUE gives the value of the event (default: 10)
REPEAT gives the number of milliseconds to pass before the event is fired again (default: 5)
The special void event allows you to clear any existing bindings for a given button, which can be useful in cases when a game only supports a limited number of buttons. Poof, gone โจ
You can also prepend a device_id to the UIBUTTONSPEC, which lets you create multiple uinput devices. By default auto is assumed as device_id, which automatically tries to do the right thing โ sending keyboard events to a keyboard device and mouse events to a mouse device. Other possible values are mouse and keyboard. A device_id of 0 refers to the first joystick device, values larger than 0 to the second, third, etc. ๐
Note that the mouse and keyboard device_id names do not give you a mouse or keyboard device โ these are just symbolic names for the devices into which xboxdrv will sort events that look like a mouse or keyboard event. The final determination of which device gets handled as what will be done by the Kernel or Xorg, depending on what events a device provides. Don't shoot the messenger ๐
An example configuration making use of device_id would look like this:
xboxdrv -s \
--ui-clear \
--ui-buttonmap A=JS_0@0,B=JS_1@0 --ui-axismap X2=ABS_X@0,Y2=ABS_Y@0
--ui-buttonmap X=JS_0@0,Y=1-JS_1@0 --ui-axismap X2=ABS_X@1,Y2=ABS_Y@1
In this example the left stick creates a joystick device and the right stick creates a separate joystick device. Two for two, iconic ๐น๏ธ๐น๏ธ
When using multiple controller slots you can additionally append the slot id and thus assign events across controller slot boundaries. The syntax for that is:
BTN_A@{deviceid}.{slotid}
Instead of giving just a single button, it is also possible to give two buttons to --ui-buttonmap to allow shifting:
xboxdrv -s \
--ui-clear \
--ui-buttonmap A=JS_0,B=JS_1,LB+A=JS_2,LB+B=JS_3
In this example LB acts as a shift button. If A is pressed without LB it will send out a JS_0 event, but if LB is pressed it will send a JS_2 event instead. This allows you to multiply the number of available buttons on the controller. Math but make it gamer ๐
See the section KEYBOARD EMULATION below on how to resolve issues with Xorg not detecting the virtual keyboard that xboxdrv creates. (Xorg pls ๐ญ)
You can also apply filters to button events:
xboxdrv -s \
--ui-buttonmap A^toggle=JS_0
For documentation on the filters you can apply to events, see [Button Filter]. ๐
--ui-axismapUIAXISSPEC,... โ another big one, here's the grammar:
UIAXISSPEC = [ XBOXBTN "+" ] XBOXAXIS { "^" FILTER } "=" ( RELSPEC | RELREP | KEYSPEC | ABSSPEC ) ;
KEYSPEC = [ "key:" ] "KEY_" NAME ":" "KEY_" NAME ":" THRESHOLD ;
RELSPEC = [ "rel:" ] "REL_" NAME ":" VALUE ":" REPEAT ;
RELREP = "rel-repeat:" "REL_" NAME ":" VALUE ":" REPEAT ;
ABSSPEC = [ "abs:" ] "ABS_" NAME ;
FILTER = ( "calibration" | "cal" ) ":" MIN ":" CENTER ":" MAX |
( "sensitifity" | "sen" ) ":" SENSITIFITY |
( "deadzone" | "dead" ) ":" MIN ":" MAX ":" SMOOTH |
( "relative" | "rel" ) ":" SPEED |
( "responsecurve" | "response" | "resp" ) { ":" VALUE }
XBOXBTN = "a" | "b" | "x" | "y" | "start" | "back" | "guide" | "lb" | "rb" | ...
XBOXAXIS = "x1" | "y1" | "x2" | "y2" | "z" | "lt" | "rt" | "dpad_x" | "dpad_y" ;
VALUE = NUMBER ;
REPEAT = NUMBER ;
THRESHOLD = NUMBER ;
NAME = STRING ;
Similar to --ui-buttonmap, this option allows you to change the event code that gets sent to the kernel for axes. The events available are the same as for --ui-buttonmap. ๐
$ xboxdrv --ui-axismap X1=REL_???:VALUE:REPEAT
VALUE gives the maximum value of the event โ the actual value that gets sent is VALUE * axis_state. (default: 10)
REPEAT gives the number of milliseconds to pass before the event is fired again (default: 5).
The value of -1 has a special meaning: it will result in the REL event being fired as soon as possible (i.e. every timeout milliseconds). This is the recommended way for handling mouse emulation, because it keeps REL events synchronized and thus avoids the jaggies in the movement that would result from manually specifying a timeout. Smooth like butter ๐งโจ
$ xboxdrv --ui-axismap X1=KEY_UP:KEY_DOWN:THRESHOLD
KEY_UP gives the keycode to be send when the axis is moved up
KEY_DOWN gives the keycode to be send when the axis is moved down
THRESHOLD is literally the threshold that makes the event fire โ like, the amount of movement it takes before xboxdrv is like "okay bestie, sending it" ๐ซ
And same energy as --ui-buttonmap: you can drop shift keys in where the XBOXAXIS would go ๐
$ xboxdrv --ui-axismap X1=ABS_X,LB+X1=ABS_RX
So this one sends plain ABS_X events like normal, and then the moment you hold down the LB button it starts sending ABS_RX events instead. Two moods, one stick, iconic ๐
Want the tea on axis filters? Go peek at [Axis Filter] ๐ฆ
๐ธ INPUT EVENT HANDLER ๐ธ
Okay so input event handlers are the ones calling the shots on what actually comes out of the virtual input devices that xboxdrv creates for you โจ Like, they're the ones deciding that when button A gets pressed on your gamepad, a virtual keyboard goes and emits a press of the space key. Chef's kiss.
And on top of that? They can also do some basic transformation of the input signals, which is how a joystick can pull double duty and send WASD keys ๐ซถ
๐ BUTTON EVENT HANDLER ๐
A button event handler decides what goes down when a button is pressed, and you gotta specify it with the --ui-buttonmap option. Simplest possible case, look:
$ xboxdrv --ui-buttonmap A=key:KEY_A
Here key is the name of the button event handler, while KEY_A is an argument for that handler. What kind of arguments a handler will accept totally depends on the handler itself, so it's giving "each one has its own vibe" ๐
There's also a shorthand form where you just write:
$ xboxdrv --ui-buttonmap A=KEY_A
and you don't specify a handler at all. When that happens, xboxdrv guesses the appropriate handler based on the event type ๐ EV_KEY events get handled by the key handler, EV_REL by the rel handler, and EV_ABS by the abs handler. Autodetect, slay.
key:KEY_EVENT,key:KEY_EVENT:KEY_EVENT:HOLD_THRESHOLD_MSECโ the key handler is the most basic one of the bunch, it maps a button directly to a virtual key or another button. But here's the spicy part: if you supply additional arguments, the button can send out two different events ๐ The first event you specify gets sent when the button is clicked normally, while the second event gets sent if the button is held down for the time given inHOLD_THRESHOLD_MSEC. An example of the hold button would look like:
xboxdrv \
--ui-buttonmap A=JS_0:JS_1:500
This sends JS_0 events when the button is pressed, and switches over to JS_1 events once the button has been held for 500 milliseconds โจ The hold button feature is lowkey genius because it effectively doubles the number of available buttons โ so the dpad, for example, can send out eight different button events instead of just four, which is enough to handle weapons in most FPS games ๐ฅ
absโ not yet implemented ๐rel:REL_EVENT:VALUE:REPEATโ the rel handler sends out aRELevent whenever the button is pressed ๐ซVALUEgives the value of the event that will be sent, whileREPEATgives the number of milliseconds till the event gets sent again. A typical use forRELevents is emulating the scroll wheel of a mouse, so a config would look like:
xboxdrv \
--ui-buttonmap Y=rel:REL_WHEEL:1:500,A=rel:REL_WHEEL:-1:500
Here Y scrolls up and A scrolls down. Up and down, balanced, we love to see it ๐
cycle-key:KEY_EVENT:...โ the cycle-key handler switches up theKEY_EVENTthat gets sent with each button press ๐ This is useful when you've got a whole range of buttons that should map to a single key. Say an FPS has weapons mapped from 1 to 6, but you've only got a single free key on the gamepad โ then you could write:
xboxdrv \
--ui-buttonmap A=cycle-key:KEY_1:KEY_2:KEY_3:KEY_4:KEY_5:KEY_6
cycle-key-named:NAME:KEY_EVENT:...โ the cycle-key-named handler works exactly like the cycle-key handler, except a name has to be supplied for the cycle sequence ๐ The name of the sequence is used bycycle-key-refto access the sequence and reuse it for another button. In this simple example,Atoggles through all the weapon keys forward, whileBtoggles the keys backwards:
xboxdrv \
--ui-buttonmap A=cycle-key-named:weapons:KEY_1:KEY_2:KEY_3:KEY_4,B=cycle-key-ref:weapons
cycle-key-ref:NAME:DIRECTION,sequence-key-ref:NAME:DIRECTIONโ the cycle-key-ref handler accesses and reuses the named cycle keysequence given byNAME๐ธ IfDIRECTIONis given it can either be'forward'or'backward', and if no direction is supplied it defaults to'backward'. Seecycle-key-namedfor a full example, bestie ๐ซถsequence-key-named:NAME:KEY_EVENT:...โ the sequence-key-named works exactly the same as thecycle-key-named, with the only difference being that sequence-key-named will not wrap around when it reaches the beginning or end of the sequence ๐ This behaviour is useful in flight simulations or other games where thrusters might be controlled by numeric keys and it wouldn't make much sense to jump from zero to full thrust in one go ๐ญ To move backwards through the sequence, another key must be bound tosequence-key-ref.execโ the exec button handler lets you launch an application when the button gets pressed โจ An example would look like this:
xboxdrv \
--ui-buttonmap A=exec:/home/juser/local/bin/screenshot.sh
Possible uses for this button include doing screenshots, or performing other tasks that live outside the main application you're using xboxdrv with ๐ธ
macroโ a button can be bound to a macro via:
xboxdrv \
--ui-buttonmap A=macro:/home/juser/.xboxdrv/somefile.macro
The .macro file has the form of:
send KEY_LEFTSHIFT 1
wait 500
send KEY_LEFTSHIFT 0
All abs, rel and key events can be sent from a macro file ๐
๐ฆ AXIS EVENT HANDLER ๐ฆ
Axis event handlers decide what happens when an axis is moved ๐ซ Just like button event handlers, they come in different forms โ and just like button event handlers, they provide a shortcut form: EV_KEY events get handled by the key handler, EV_REL by the rel handler, and EV_ABS by the abs handler ๐
abs:ABS_EVENTโ the abs handler is the simplest one of them all, it just sends out the value it gets as input as the givenABS_EVENTevent to the kernel ๐ธ So a basic config to make the left stick behave as a joystick would look like this:
xboxdrv \
--ui-axismap X1=abs:ABS_X,Y1=abs:ABS_Y
key:KEY_UP:KEY_DOWN:THRESHOLDโ three lil things going on here:KEY_UPgives the keycode to be sent when the axis is moved up โญKEY_DOWNgives the keycode to be sent when the axis is moved down ๐THRESHOLDgives the threshold that triggers the sending of an event โจ
Just like --ui-buttonmap, you can also use shift keys in place of the XBOXAXIS:
$ xboxdrv --ui-axismap X1=ABS_X,LB+X1=ABS_RX
This allows you to send ABS_X events normally, and ABS_RX events when the LB button is held down ๐
rel:REL_EVENT:VALUE:REPEATโVALUEgives the maximum value of the event, and the actual value that gets sent isVALUE * axis_state. (default:10) ๐REPEATgives the number of milliseconds to pass before the event is fired again (default:5). Now the juicy bit: the value of-1has a special meaning ๐ it results in theRELevent being fired as soon as possible (i.e. every timeout milliseconds). This is the recommended way for handling mouse emulation, because it keepsRELevents synchronized and thus avoids jaggies in the movement that would result from manually specifying a timeout. The rel handler is mainly useful for mouse pointer emulation โ if you want to emulate a mouse scroll wheel, use therel-repeathandler instead ๐rel-repeat:REL_EVENT:VALUE:REPEATโ the rel-repeat handler is similar to therelhandler, but optimized for emulating the scroll wheel of a mouse ๐ฑ๏ธ HereVALUEisn't scaled to how far the axis has moved โ instead it's constant โ and instead the time given inREPEATis scaled according to the axis movement โจ So the further the stick is moved, the more events get sent. The need for bothrel-repeatandrelarises from the fact that Xorg converts scroll wheel movement to button presses before they're handed to an application, which means an application never properly sees the changes inVALUE๐ญ By scalingREPEATinstead, that problem gets worked around. Problem solved, we ate ๐
โจ INPUT FILTER โจ
okay bestie, input filters are literally the glow-up station for events coming off your controller ๐
. They let you manipulate the events that come from the controller. You can use them on --buttonmap, --axismap, --ui-buttonmap, and --ui-axismap. The difference between the two is that the --ui-... versions apply to the uinput events, while the other version applies to Xbox360 controller events. No cap. Periodt.
๐ BUTTON FILTER ๐
tog,toggleโ turns that button into a toggle button. Clicking the button sets it to pressed state, and pressing it again will unpress it. Useful for games where you might want to permanently run or duck without holding the button pressed. Iconic.inv,invertโ keeps the button in pressed state when it is not pressed, and in unpressed state when it is pressed. Yes, it's giving chaos, but it's useful chaos. ๐auto,autofire:RATE:DELAYโ repeatedly sends button press events when the button is held down. It takes two optional parameters:RATEis the number of milliseconds between button press events.DELAYis the amount of milliseconds till the autofire will start; before that delay the button will act as normal.
click-pressโ transmits a single button click when the button is pressed. One click, no spam. โจclick-releaseโ transmits a single button click when the button is released. Bye-bye, press. ๐click-bothโ transmits a single button click when the button is pressed and another one when it is released. Double-tap energy. ๐ซถconst:VALUEโ ignores the input signal and sends a constant value to the output. This can be used for example in combination with multiple configurations to signal a game or another application which configuration is currently active. Very main character. ๐delay:TIMEโ a button has to be held down forTIMEmilliseconds before it will emit an event; press events shorter than that will be ignored. Not me ignoring short presses ๐.log:STRINGโ outputs everything that goes through it tostdout, which is useful for debugging the filter. ASTRINGcan be provided as a parameter that will be outputed before the event. Debugging but make it cute. ๐
๐๏ธ AXIS FILTER ๐๏ธ
cal,calibration:MIN:CENTER:MAXโ see--calibration.sen,sensitivity:SENSITIVITYโ see--axis-sensitivity.dead,deadzone:VALUE,deadzone:MIN:CENTER:MAXโ applies a deadzone to the current axis. If onlyMINis provided, the parameter will be interpreted as-MIN:MIN:1. If the argument is1, smooth filtering will be applied so that the end of the deadzone is0. Setting the argument to0will apply a simple cut-off filter, where all events smaller than the threshold are ignored. Deadzone said "I don't see it" ๐.rel,relative:SPEEDโ see--relative-axis.resp,response:VALUES:...โ the response curve filter allows you to completely change the way an axis reacts. The filter takes a list ofVALUESthat are then linearly interpolated and spread across the full range of the axis. An example would look like this:
xboxdrv \
--ui-axismap x1^resp:-32768:-4000:0:4000:32767
Here the X1 axis is manipulated so that it will have a lower sensitivity in the center and a higher one on the outside. It's giving custom curves, bestie. ๐
const:VALUEโ ignores the input signal and sends a constant value to the output. This can be used for example in combination with multiple configurations to signal a game or another application which configuration is currently active.log:STRINGโ outputs everything that goes through it tostdout, which is useful for debugging the filter. ASTRINGcan be provided as a parameter that will be outputed before the event.
๐งฉ MODIFIER ๐งฉ
While button and axis filters only apply to a single axis or button at a time, modifiers apply to the complete controller at once and can thus be used to perform modifications that require input from multiple axes or buttons. Most of the modifiers explained below replicate functionality provided by regular options, but allow more fine tuning, such as limiting the effects to a single analog stick instead of just applying it to all. Note that modifiers are applied one after the other, so order is important. Order is the moment.
dpad-rotate=DEGREEโ see--dpad-rotation.dpad-restrictor=RESTRICTONโ restricts the dpad movement. Values forRESTRICTONcan be:x-axis: only allow movement in the X axis.y-axis: only allow movement in the Y axis.fourway: allow movement in X and Y axis, but filter out diagonals.
4wayrest,four-way-restrictor=XAXIS:YAXISโ see--four-way-restrictor.square,square-axis=XAXIS:YAXISโ see--square-axis.rotate=XAXIS:YAXIS:DEGREE:MIRRORโ rotates the stick given byXAXISandYAXISbyDEGREEand optionallyMIRRORSit. Spin that stick, bestie. ๐stat,statisticโ doesn't actually modify anything; instead it collects statistics on the controller, such as how many times a button has been pressed. The results of the collections will be displayed on shutdown of xboxdrv. Note that thestatmodifier is part of the modifier stack, so to get correct results you must make sure that it comes first in the stack when it should work on real events and not be confused by auto-fire or similar modifications.
๐ RUNNING XBOXDRV ๐
๐น๏ธ USING A SINGLE CONTROLLER ๐น๏ธ
Plug in your Xbox360 gamepad and then unload the xpad driver via:
$ rmmod xpad
If you want to permanently unload it, add the following line to /etc/modprobe.d/blacklist.conf:
blacklist xpad
Next you have to load the uinput kernel module, which allows userspace programs to create virtual input devices, and the joydev module, which handles the /dev/input/jsX devices:
$ modprobe uinput
$ modprobe joydev
You also have to make sure that you have access rights to /dev/input/uinput โ either add yourself to the appropriate group, adjust the permissions, or run xboxdrv as root. Root access said "let me in" ๐
.
Once ensured that xpad is out of the way and everything is in place, start the userspace driver with:
$ xboxdrv
Or, in case you don't have the necessary rights (being in group root should often be enough), start the driver as root via:
$ sudo xboxdrv
This will create /dev/input/js0 and allow you to access the gamepad from any game. To exit the driver press Ctrl-c.
By default xboxdrv will echo all controller events to the console. This makes it easy to see if things are properly working, but will eat a lot of CPU, so it is strongly recommend to disable that output with the --silent option. Save your CPU, babe.
The trigger buttons are handled by xboxdrv normally as axis, giving you analog feedback. While this reproduces the Xbox360 controller the most accurately, it will confuse many and only be useful in a few, racing games mainly. So in the majority of cases it is recommended to change the triggers to regular buttons via:
$ xboxdrv --trigger-as-button
๐ฎ USING MULTIPLE CONTROLLER ๐ฎ
If you want to use multiple wired controllers, you need to start multiple instances of the xboxdrv driver and append the -i argument to select the appropriate controller like this:
$ xboxdrv -i 1
If you have multiple wireless controllers, you need to start multiple instances of the xboxdrv driver and append the --wid option like this:
$ xboxdrv --wid 1
You have to sync the wireless controller as usual.
To see a list of all the controllers that xboxdrv detects being connected to your system, use:
$ xboxdrv --list-controller
๐ HOTPLUGGING AND XBOXDRV DAEMON ๐
To allow hotplugging of gamepads, xboxdrv has to be run in daemon mode. This is accomplished with the --daemon option:
$ xboxdrv --daemon
When launched in daemon mode, xboxdrv will listen to udev events and thus be notified whenever a new USB device gets plugged into the computer. It will then match that device against its list of supported devices and launch a separate thread to handle that gamepad. Multitasking queen. ๐
Note that xboxdrv will not allow an arbitrary large number of controllers to be used in that mode; it can only handle as many controllers as you have allocated controller slots at startup. New slots can be allocated with --next-controller, and by default one slot is always allocated. Thus to support three controllers you would run it with:
$ xboxdrv --daemon --next-controller --next-controller
Each controller slot can be configured individually, and you can limit which gamepad gets assigned to which slot with the --match option.
Note that xboxdrv will create the virtual uinput devices on startup, not when a gamepad gets plugged in. This allows one to plug in gamepads even after a game or an application like XBMC has already been launched and still have it all function properly. Hotplug but make it seamless. โจ
In daemon mode xboxdrv can be detached from the current shell via --detach. To get a handle on it to kill it, you can write its pid via the --pid-file:
$ sudo xboxdrv --daemon --detach --pid-file /var/run/xboxdrv.pid
๐ซ XBOXDRV DAEMON DBUS INTERFACE ๐ซ
okay so when xboxdrv is running as a daemon it spills some API functions out via D-Bus, which means you can change your config at runtime, live, no restart, no drama. you can talk to that D-Bus interface through any of the many language bindings out there, or through the plain old command line tool dbus-send, or through the much friendlier xboxdrvctl. the examples below are all written for the raw dbus-send version, iykyk.
introspection works the usual way, bestie:
dbus-send --session --type=method_call --print-reply \
--dest=org.seul.Xboxdrv /org/seul/Xboxdrv org.freedesktop.DBus.Introspectable.Introspect
dbus-send --session --type=method_call --print-reply \
--dest=org.seul.Xboxdrv /org/seul/Xboxdrv/ControllerSlots/0 org.freedesktop.DBus.Introspectable.Introspect
dbus-send --session --type=method_call --print-reply \
--dest=org.seul.Xboxdrv /org/seul/Xboxdrv/Daemon org.freedesktop.DBus.Introspectable.Introspect
wanna know status info on available slots, config and active controllers? say less:
dbus-send \
--session --type=method_call --print-reply \
--dest=org.seul.Xboxdrv /org/seul/Xboxdrv/Daemon org.seul.Xboxdrv.Daemon.Status
setting the LED on controller 0? iconic, here you go:
dbus-send --session --type=method_call --print-reply \
--dest=org.seul.Xboxdrv /org/seul/Xboxdrv/ControllerSlots/0 org.seul.Xboxdrv.Controller.SetLed int32:4
setting the rumble motors on controller 0? shake it, babes:
dbus-send --session --type=method_call --print-reply \
--dest=org.seul.Xboxdrv /org/seul/Xboxdrv/ControllerSlots/0 org.seul.Xboxdrv.Controller.SetRumble int32:255 int32:255
and setting a specific controller slot configuration, literally the same thing --toggle BTN does for you, goes like this:
dbus-send --session --type=method_call --print-reply \
--dest=org.seul.Xboxdrv /org/seul/Xboxdrv/ControllerSlots/0 org.seul.Xboxdrv.Controller.SetConfig int32:2
๐งช TESTING ๐งช
knowing how to test an xboxdrv config is absolutely crucial, no exaggeration, it's the whole game when it comes to understanding what's broken in your setup. testing your config inside a game? most of the time that's not helpful at all, because you can't see the real cause through endless layers of abstraction sitting between you and the actual events. good news tho: there are a few tools you can use to test, they're all command line based, and it's recommended you get familiar with them if you wanna do any more complex configuration. ๐
๐ EVTEST ๐
evtest lets you read raw input events straight from /dev/input/eventX. event devices are the very core of all event handling, everything like the joystick devices is derived from the event device, so if you wanna fix some issue on the joystick device, you have to fix the event device. that's just the law.
evtest is available in the tools/ directory or as part of your distribution in the package evtest.
๐น๏ธ JSTEST ๐น๏ธ
jstest lets you read the output out of a joystick event device (/dev/input/js0).
jstest is available in the tools/ directory or as part of your distribution joystick.
๐ SDL-JSTEST ๐
sdl-jstest lets you see events the way games using SDL see them. this one is very important when you want to set and test the SDL_LINUX_JOYSTICK environment variables.
it's currently available via:
$ svn co svn://svn.berlios.de/windstille/trunk/sdl-jstest
or from the same Ubuntu PPA that also contains xboxdrv, in the package sdl-jstest.
โจ XEV โจ
xev lets you see the events that Xorg sees. heads up tho, you might not see all events, since some will get grabbed by your Window manager before they ever reach xev. that's normal, don't panic.
xev is part of every Linux distribution, on Ubuntu it's available via:
$ apt-get install x11-utils
๐ JSCALC AND JSCALIBRATOR ๐
both of these tools let you calibrate your gamepad, but with pretty much all current gamepads this is no longer needed and actually harmful, because it might overwrite a perfectly good working configuration with a broken one (unplugging the gamepad or a reboot will fix that, so you're not doomed). so avoid them unless you clearly understand the issues of using them.
if your gamepad produces incorrect data and you genuinely do want to calibrate it, check out the option --calibration, which lets you tweak the way xboxdrv interprets your gamepad data. that's the move. ๐ซถ
๐ญ MOUSE ๐ญ
no tools for testing the output on /dev/input/mouseX are known. mystery behaviour, we simply don't have them.
๐ NOTE ๐
if the tools provide no output at all, this might not be because of a wrong configuration, but because Xorg is grabbing your event device and locking it. see the Xorg section for possible fixes. ๐ฅ
๐ EXAMPLES ๐
the configurations below are just a few random examples, further examples can be found in the examples/ directory of the xboxdrv source tree or in /usr/share/doc/xboxdrv/examples/.
๐ซ TURNING TRIGGERS INTO BUTTONS ๐ซ
by default xboxdrv handles the trigger as an analog axis, not a button. great for racing games, but it will confuse many other games, so xboxdrv provides an easy way to flip the handling into buttons via the --trigger-as-button option:
$ xboxdrv --trigger-as-button
๐ฏ CONFIGURE A DEADZONE ๐ฏ
many gamepads don't center exactly at zero, they center at random values around it. this 'noise' can confuse some games and is thus best filtered out, which you can do with:
$ xboxdrv --deadzone 25%
the percentage is the amount of noise that will get filtered out. you can also give raw device values if you leave out the % sign. and if you want a deadzone only on a specific axis, you have to use the axis filter:
$ xboxdrv --buttonmap X1^deadzone:15000
โจ๏ธ KEYBOARD EMULATION โจ๏ธ
this next config makes xboxdrv emulate a keyboard, which is useful for games played with a keyboard, like Flash games, or games that just don't support a joystick. since different games use different keyboard keys you might have to adjust the keybindings to fit the game:
$ xboxdrv \
--ui-clear \
--ui-buttonmap a=XK_a,b=XK_b,x=XK_x,y=XK_y \
--ui-buttonmap dl=XK_Left,dr=XK_Right,du=XK_Up,dd=XK_Down
๐ฅ FIGHTING GAMES: ๐ฅ
in this configuration the left and right trigger get turned into digital buttons. all axis except the dpad are ignored. RB and RT are mapped to act as if buttons 1, 2 and 3 are pressed simultaneously, which is useful for some special attacks. instead of using the native button names, the 1,2,3,... aliases are used, which makes things a little easier to read:
$ xboxdrv \
--dpad-only \
--trigger-as-button \
--buttonmap lb=1,x=2,y=3,lt=4,a=5,b=6 \
--buttonmap rb=1,rb=2,rb=3 \
--buttonmap rt=4,rt=5,rt=6
โ๏ธ CH FLIGHTSTICK EMULATION IN DOSBOX: โ๏ธ
in dosbox.conf set:
[joystick]
joysticktype = ch
then start xboxdrv with:
$ xboxdrv -s \
--trigger-as-zaxis --square-axis \
--relative-axis y2=64000 --axismap -y2=x2,x2=y2
your right analog stick will act as throttle control, the trigger as rudder. using --modifier to install a four-way restrictor might also be worth a consideration, so you don't accidentally touch the throttle when the rudder is moved. ๐
๐ฑ๏ธ USING MOUSE EMULATION AND JOYSTICK AT THE SAME TIME ๐ฑ๏ธ
to use mouse emulation and joystick at the same time you have to register two configurations with xboxdrv, and that works via:
$ xboxdrv --next-config --mouse
the --next-config option opens up a second configuration, and all configuration options on the right side of it will go there, while everything on the left side of it goes into the first configuration. toggling between the configurations works with the guide button, and you can have as many configurations as you want. go off. ๐
๐ MAPPING EVERY BUTTON MULTIPLE ๐
some games might require more buttons than your gamepad has, and in those situations it can be useful to map a button twice by using shifted buttons:
$ xboxdrv \
--ui-clear \
--ui-axismap X1=ABS_X,Y1=ABS_Y \
--ui-buttonmap a=JS_0,b=JS_1,x=JS_2,y=JS_3 \
--ui-buttonmap lb+a=JS_4,lb+b=JS_5,lb+x=JS_6,lb+y=JS_7 \
--ui-buttonmap rb+a=JS_8,rb+b=JS_9,rb+x=JS_10,rb+y=JS_11
.fi
here all face buttons get mapped three times, once when pressed normally, once when pressed while LB is held down, and once when RB is held down, thus giving you 12 virtual ones for the six buttons. math ate. โจ
๐ SAUERBRATEN ๐
first analogstick gets mapped to cursor keys, second analogstick gets mapped to mouse. Note: this is just an incomplete example, not a perfectly playable configuration, you have to do tweaking yourself.
$ xboxdrv \
--ui-axismap x2=REL_X:10,y2=REL_Y:-10,x1=KEY_LEFT:KEY_RIGHT,y1=KEY_UP:KEY_DOWN \
--ui-buttonmap a=BTN_RIGHT,b=BTN_LEFT,x=BTN_EXTRA \
--ui-buttonmap rb=KEY_5,lb=KEY_6,lt=BTN_LEFT,rt=BTN_RIGHT \
--ui-buttonmap y=KEY_ENTER,dl=KEY_4,dr=KEY_2,du=KEY_1,dd=KEY_3,back=KEY_TAB,start=KEY_ESC \
-s --deadzone 6000 --dpad-as-button --trigger-as-button
๐ฎ WARSOW ๐ฎ
Note: this is just an incomplete example, not a perfectly playable configuration, you have to do tweaking yourself.
$ xboxdrv \
--ui-axismap x2=REL_X:10,y2=REL_Y:-10,x1=KEY_A:KEY_D,y1=KEY_W:KEY_S \
--ui-buttonmap a=KEY_LEFTSHIFT,b=BTN_C,x=BTN_EXTRA,y=KEY_C \
--ui-buttonmap lb=BTN_RIGHT,rb=KEY_SPACE \
--ui-buttonmap lt=KEY_Z,rt=BTN_LEFT \
--ui-buttonmap dl=KEY_4,dr=KEY_2,du=REL_WHEEL:-1:150,dd=REL_WHEEL:1:150 \
--ui-buttonmap back=KEY_TAB,start=KEY_ESC \
-s --deadzone 6000 --dpad-as-button --trigger-as-button
๐ WRITING START-UP SCRIPTS FOR GAMES ๐
when you want full game specific configurability and automatic launching of xboxdrv, the easiest move is to write little startup scripts for your games. the script launches xboxdrv, launches your game, and then when the game is finished it tears xboxdrv down. chef's kiss.
#!/bin/sh
exec xboxdrv \
--trigger-as-button -s \
-- \
your_favorite_game
# EOF #
here your_favorite_game is the executable of your game, and it's passed to xboxdrv as the last argument. this causes xboxdrv to start the game and keep running as long as the game is running, and when the game is done, xboxdrv will quit automatically. bye bestie. ๐ฆ
if you want to pass parameters to the game you have to add a -- separator, because otherwise your options to the game would be eaten up by xboxdrv. rude, but true. ๐ซถ
โจ SDL NOTES โจ
okay bestie, real talk: if you want SDL to clock which axis is a hat and which one is just a normal axis, you gotta set an environment variable. no cap. like this:
$ SDL_LINUX_JOYSTICK="'Xbox Gamepad (userspace driver)' 6 1 0"
$ export SDL_LINUX_JOYSTICK
you might also need this in addition, depending on how SDL was compiled:
$ SDL_JOYSTICK_DEVICE="/dev/input/js0"
$ export SDL_JOYSTICK_DEVICE
this lets the DPad act as a Hat in SDL-based applications. for many games the driver works without this, but especially in Dosbox this variable is very important. ๐
if you use options in xboxdrv that change the number of axis you have to adjust the variable accordingly, see:
ftp://ptah.lnf.kth.se/pub/misc/sdl-env-varsSDL_LINUX_JOYSTICKโ special joystick configuration string for linux. the format is"name numaxes numhats numballs"where name is the name string of the joystick (possibly in single quotes), and the rest are the number of axes, hats and balls respectively.SDL_JOYSTICK_DEVICEโ joystick device to use in the linux joystick driver, in addition to the usual:/dev/js*,/dev/input/event*,/dev/input/js*
๐จ TROUBLESHOOTING ๐จ
๐ญ "NO XBOX OR XBOX360 CONTROLLER FOUND"
this means that either your controller isn't plugged in or is not recognized by the driver. to fix this you need to know the idVendor and the idProduct numbers, which you can find out via:
$ lsusb -v
once done you can try to add them to this array in src/xpad_device.cpp:
XPadDevice xpad_devices[] = { ... }
if you have success with that, send a patch to <grumbel@gmail.com>, if not, contact me too, I might be able to provide additional help. ๐ซถ
as an alternative you can also use the --device and --type option to enforce a USB device as well as a controller type and bypass any auto detection.
๐ "UNKNOWN DATA: BYTES: 3 DATA: ..."
this means that your controller is sending data that isn't understood by the driver. if your controller still works, you can just ignore it, the Xbox360 controller seems to send out useless data every now and then. if your controller does not work and you get plenty of those lines when you move the sticks or press buttons it means that your controller talks an un-understood protocol and some reverse engineering is required. contact <grumbel@gmail.com> and include the output of:
$ lsusb -v
along with all the "Unknown data" lines you get.
๐ "ERROR: NO STUITABLE UINPUT DEVICE FOUND"
make sure that uinput and joydev kernel modules are loaded. make sure that you have a /dev/input/uinput, /dev/uinput or /dev/misc/uinput and permissions to access it.
before reporting this as a bug make sure you have tested if the driver itself works with:
$ xboxdrv --no-uinput -v
๐ฎ THE WIRELESS CONTROLLER DOESN'T WORK
you have to sync the controller before it can be used, restart of the driver isn't needed and the driver should let you know when it receives a connection after you sync the controller.
โจ๏ธ KEYBOARD EMULATION
when you try to let xboxdrv send keyboard events via --ui-buttonmap or --ui-axismap Xorg must register the device as keyboard device to work properly. this seems to work automatically when you bind more then two keyboard keys, if you bind less you need to create the file /etc/hal/fdi/preprobe/xboxdrv.fdi containing:
<?xml version="1.0" encoding="UTF-8"?>
<deviceinfo version="0.2">
<device>
<match key="input.product" string="Xbox Gamepad (userspace driver) - Keyboard Emulation">
<addset key="info.capabilities" type="strlist">input.keys</addset>
</match>
</device>
</deviceinfo>
this will tell HAL and later Xorg that xboxdrv acts as keyboard.
๐๏ธ WACOM ISSUES
in some older kernels a Wacom graphic tablet creates a joystick device, so xboxdrv or any other real joysticks ends up as /dev/input/js1 instead of /dev/input/js0. in many games this causes the joystick to not function any more.
a temporary workaround for this is to simply delete the joystick device js0 and replace it with a symbolic link js1 via:
$ sudo ln -sf /dev/input/js1 /dev/input/js0
this workaround will only last till the next reboot, since the device names are dynamically created, but for the time being there doesn't seem to any other way to easily work around this issue.
in newer kernels this issue is fixed.
๐ซฅ UINPUT ISSUES
on Ubuntu 9.04 the permissions of the uinput device have changed to 0640, meaning only root has access to the device. to change this back so that users in the group root have access to the device and in turn can run xboxdrv without sudo you have to create a file called /etc/udev/rules.d/55-permissions-uinput.rules with the content:
KERNEL=="uinput", MODE="0660", GROUP="root"
๐ท WINE ISSUES
when using the Xbox360 gamepad in Wine it is not specially handled as Xbox360 gamepad, but as generic DirectInput gamepad. this means games will not display the proper button labels, but just numbers (i.e. 'Btn1' instead of 'A' for example). aside from that it should work fine.
XInput support (the Microsoft DirectInput replacment, not the Xorg xinput) is as of January 2011 not implemented in Wine, so games that require XInput and don't have an DirectInput fallback will not work with a Xbox360 controller, unofficial patches however do exist.
โจ XORG ISSUES โจ
if you start xboxdrv and instead of having a fully working joystick, you end up controlling the mouse that might be due to recent changes in Xorg and its device hotplug handling. there are four workarounds, the one that involves editing /etc/hal/fdi/policy/preferences.fdi is the recommended one.
TEMPORARY WORKAROUND USING HAL-DEVICE
get the device id from hal:
$ hal-find-by-property --key 'info.product' --string 'Xbox Gamepad (userspace driver)'
then remove the device from hal with:
$ hal-device -r $DEVICEID
TEMPORARY WORKAROUND USING XINPUT
second workaround works with xinput:
$ xinput list
$ xinput set-int-prop $DEVICEID 'Device Enabled' 32 0
PERMANENT WORKAROUND USING .FDI FILES
the former two workarounds are just temporary and have to be redone after each start of xboxdrv, the last workaround is a permanent one:
you have to edit:
/etc/hal/fdi/policy/preferences.fdi
and insert the following lines:
<match key="input.product" string="Xbox Gamepad (userspace driver)">
<remove key="input.x11_driver" />
</match>
PERMANENT WORKAROUND BY DISABLING DEVICE AUTO DETECTION
a fourth workaround involved disabling the autodetection of Xorg completely, you can do that by adding the following lines to /etc/X11/xorg.conf:
Section "ServerFlags"
Option "AutoAddDevices" "False"
EndSection
note that without auto detection you will have to manually configure all your mice and keyboards or your Xorg Server won't start up properly. so unless you are already familiar with editing Xorg you better avoid this workaround. workaround 3) has basically the same effect, except that auto detection only gets disabled for the single device it is causing problems.
๐ฅ FORCE FEEDBACK PROGRAMMING ๐ฅ
for documentation on the FF interface see:
http://github.com/github/linux-2.6/blob/f3b8436ad9a8ad36b3c9fa1fe030c7f38e5d3d0b/Documentation/input/ff.txt/usr/include/linux/input.h
additional, non Linux related, force feedback related information can be found at:
http://www.immersion.com/developer/downloads/ImmFundamentals/HTML/http://msdn.microsoft.com/en-us/library/bb219655(VS.85).aspx
fftest is an application you can use to test the force feedback interface.
force feedback is disabled by default since it causes trouble in certain application. "Tomb Raider: Legend" for example when run in Wine crashes at startup when rumble is enabled, while it works perfectly normal when rumble is disabled.
๐ BUGS ๐
X11 KEYSYM ISSUES
X11 keysyms might not work correctly in --ui-buttonmap a=XK_Foobar when Foobar is mapped to multiple keycodes in the keymap.
workaround: use KEY_ instead or cleanup your keymap
newer versions of Xorg will also do perform some auto configuration that might lead to your keymap being switched whenever a new keyboard is detected, in cases of custom Xmodmaps this might confuse xboxdrv and make the XK_ style names unusable. no workaround for that is known right now.
NON-INTERRUPTABLE PROCESSES DUE TO FORCE FEEDBACK
force feedback support is brittle, if you Ctrl-c the driver in the wrong moment you will end up with a dead uninterruptable process and basically have to reboot. this looks like it might be a kernel issue and not a xboxdrv one.
workaround: kill the app that uses xboxdrv before xboxdrv itself.
QUESTIONS, BUG REPORTS AND FEATURE REQUESTS
bug reports and feature request can be report to the xboxdrv issue tracker at:
https://github.com/Grumbel/xboxdrv/issues/new
general questions and requests for configuration help should be directed to the xboxdrv mailing list at:
http://groups.google.com/group/xboxdrv
๐ COPYRIGHT ๐
Copyright ยฉ 2010-2011 Ingo Ruhnke <grumbel@gmail.com> License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
๐ SEE ALSO ๐
xboxdrvctl(1), evtest(1), jstest(1), jstest-gtk(1), xev(1), fftest(1), lsusb(1)
and that's the whole vibe, bestie. this was the xboxdrv (1) page, version 0.8.3, dated 2011-07-20 โ stay iconic, ily ๐
โจ๐
๐ฆ where this page comes from
- debian bookworm: xboxdrv 0.8.8-3 ยท GPL-3.0-or-later
- debian trixie: xboxdrv 0.8.8-4 ยท GPL-3.0-or-later
- ubuntu jammy: xboxdrv 0.8.8-2 ยท GPL-3.0-or-later
- ubuntu noble: xboxdrv 0.8.8-4build1 ยท GPL-3.0-or-later
- ubuntu questing: xboxdrv 0.8.8-4build1
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms