The libjoyevent library transparently intercepts joystick events, simultaneously modifying/masking/logging/generating fake X11 keyboard events as a response to each joystick event based on dynamically selectable configuration profile.
The libjoyevent library supports both 32bit and 64bit Linux binaries as well both 32bit and 64bit Windows application running under wine.
The libjoyevent library was initially designed to help me use the different knobs and buttons on my Saitek X52 joystick / throttle under Linux, but never the less, the code itself is general, and should work just as well under other Joysticks.
Please contact me if you joystick is not supported.
The latest version of libjoyevent can be downloaded from: https://sourceforge.net/projects/libjoyevent/.
The current release is 0.2.0.
3.1. Pre-requisites.
The following packages are required by libjoyevent:gcc. GNU make. GNU file. X11. X11-devel. XTest. ( Optional ). XTest-Devel. ( Optional ).
3.2. Building.
I. In-order to build a 32bit library on a 32bit host and/or build a 64bit library on a 64bit host:
$ make
II. In-order to build a i386 library on a x86_64 host:
$ make ARCH=i386
III. In-order to enable debug symbols:
$ make DEBUG=yes
3.3. Installation.
I. In-order to install the libraries in the default locations (/usr/lib, /usr/lib64):
$ make install
II. In-order to install the libraries in non-default locations:
$ make LIB_PREFIX=/usr/games/lib BIN_PREFIX=/usr/games/bin install (Optional: ARCH=i386)
In-order to get a complete listing of all the make options:
$ make help
In-order to support multi-lib installations, the joyevent_exec script will only be configured and install, when the native ARCH is built.
As such, in-order to create multi-lib capable libjoyevent setup, it is advised to build the 32bit version first, install it, and then build the 64bit version (Which will configure and install joyevent_exec script).
The supplied build_32_64.sh script can be used as reference.
4.1. Configuration file.
profiles <num_profiles>
Number of profiles. Default is 0. ( Limited to 10. )
Must precede other configuration variables in-order to enable profile support in subsequent commands.
General comment: If the number of values in each axis/button command is lower than the number of profiles, the last value will be copied to the remaining profiles.
device /dev/jsX
Joystick device.
alias /dev/jsX
Device alias.
Trying to open alias device will open the primary device instead ( Useful when running legacy games with single joystick support on a machine with more than one joystick ).
debug <0,1,2>
Debug level.
profilecycle <btnX>
Switch to the next profile ( cyclic ).
profileselect <btnX>=<profZ>
Switch profile to profile Z.
# Comment
Comment ( Ignored ).
buttonreplace <btnX> <btnY [prof0]> <btnY [prof1]> ...
Replace joystick button X with a per-profile button Y.
buttontokey <btnX> <keyY [prof0]> <keyY [prof1]> ...
Convert the joystick button X an per-profile X11 keyboard event Y.
buttonmask <btnX> 0 1 0 ...
Mask out joystick button X. Per-profile, 1 enables the mask and 0 disables the mask.
If a single event is being read, an empty event will be returned to the application.
buttonlog <btnX> <log-level-X>
Generate a log event level X each time button X is pressed / released.
axistokey <axisX> <divider> <decY [prof0]> <incY prof0]> <decY[prof1]> <incY[prof1]> ...
Convert a joystick axis X event to per-profile either "decY" X11 keyboard event (Axis going down, or either a per-profile "incY.Z" X11 keyboard event (Axis going up).
The divider value is used to counter the joydev's forced -15bit - +15bit range manipulation.
(No matter what value range is being used by the joystick, the kernel will always report values between -32767 and 32768 by using a conversion function).
Set this parameter to 1, if the joystick has no problems centering to 0.
The actual -hardware- value range can yanked from jscal and friends.
axisreplace <axisX> <axisY [prof0]> <axisY [prof1]> ...
Replace joystick axis X with axis Y.Z, where Z is the currently selected profile.
axismask <axisX> 0 1 0 ...
Mask out joystick axis X. Per-profile, 1 enables the mask and 0 disables the mask.
If a single event is being read, an empty event will be returned to the application.
axislog <btnX> <log-level-X>
Generate a log event level X each time axis X moves.
4.2. Environment variables used.
The libjoyevent environment variables are used to configure the libjoyevent runtime as well as override
values inside the configuration file.
JOYEV_CONFIG=~/.XXX.conf
Configuration file.Generated automatically in joyevent_exec mode. Required in manual mode.
JOYEV_DEVICE=/dev/jsX
Joystick device ( Default: /dev/js0 ).
Overrides the device configuration file variable.
JOYEV_ALIAS=/dev/jsX
Joystick alias.
Overrides the alias configuration file variable.
JOYEV_DEBUG=<0,1,2>
Dump debug/error information to the console.
0: None. 1: Errors only ( Default ). 2: Full.
Overrides the debug configuration file variable.
DISPLAY=xx:xx.x
Display to use.
4.3. Keyboard key names.
There are two methods to locate the key names (required by axistokey and buttontokey):
I. xev:
The xev application (most likely part of the Xorg-utils package) lets the user capture X11 events as they happen.
When xev starts, a new window will appear. Move the focus (using the mouse) to the new window, and click on the requested key.
Once the key is pressed/release, two events will appear - KeyPress and KeyRelease events.
The key name will appear right after the keycode and the keysym.
E.g.
$ xev
...
KeyPress event, serial 31, synthetic NO, window 0x1800001,
root 0x13b, subw 0x1800002, time 558985120, (52,38), root:(1561,63),
state 0x0, keycode 103 (keysym 0xff57, End), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: FalseKeyRelease event, serial 31, synthetic NO, window 0x1800001,
root 0x13b, subw 0x1800002, time 558985164, (52,38), root:(1561,63),
state 0x0, keycode 103 (keysym 0xff57, End), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
II. keysymdef.h:
If your distribution doesn't ship the xev utility, a list of all possible key names can be found in keysymdef.h (usually resides in /usr/include/X11).
Please note that when copying a key name from keysymdef.h, the XK prefix should not be copied.
The joyevent_exec script is the preferred method to automatically start an application with libjoyevent support.
The joyevent_exec was designed automates the following tasks:Detecting the application ARCH ( 32bit, 64bit ). Locating and pre-loading the correct libjoyevent.so. Passing the correct configuration to libjoyevent.so. 5.1. Examples:
Start js_demo ( joystick test application ) with full logging. $ joyevent_exec --config=~/.joyevent_jsdemo.conf js_demoStart LGP's X3:R ( Space simulation, 32bit Linux version ). $ joyevent_exec --config=~/.joyevent_x3.conf /usr/games/x3/x3_sse2Start Egosoft's X3:TC under Steam ( Space simulation, 32bit Windows binary running under 64bit Wine ). $ joyevent_exec --config=~/.joyevent_x3tc.conf /usr/bin/wine "C:\\Program Files\\Steam\\Steam.exe" -applaunch 28205.2. ARCH configuration override.
By default, the joyevent_exec attempts to auto-detect the binary ARCH. In certain configurations, this auto-detection can either fail ( E.g. when the game is being started by script ), or simply irrelevant ( when the same wine session is being used to execute both 32bit and 64bit applications ). In order to manually force the libjoyevent ARCH, one of the following options can be used:
-a/--auto: Auto-detect mode ( default ). -3/--32: 32bit version of libjoyevent will be pre-loaded. -6/--64: 64bit version of libjoyevent will be pre-loaded. -b/--both: Both 32bit and 64bit versions of libjoyevent will be pre-loaded. 5.3. Getting help.
In-order to get a complete listing of all the joyevent_exec options:
$ joyevent_exec --help
6. Starting applications manually.
In-order to start an application with libjoyevent support without using the joyevent_exec script, the correct libjoyevent version must be manually pre-loaded and configured before the application's binary is being loaded.6.1. Examples:
Start js_demo ( joystick test application ) with full logging. $ JOYEV_DEBUG=2 JOYEV_CONFIG=~/.joyevent_jsdemo.conf LD_PRELOAD=/usr/lib64/libjoyevent.so.x86_64 js_demoStart LGP's X3:R ( Space simulation, 32bit Linux version ). $ JOYEV_CONFIG=~/.joyevent_x3.conf LD_PRELOAD=/usr/games/lib/libjoyevent.so.i386 /usr/games/x3/x3_sse2Start Egosoft's X3:TC ( Space simulation, 32bit Windows binary running under 64bit Wine ). $ JOYEV_CONFIG=~/.joyevent_x3tc.conf LD_PRELOAD=/usr/games/lib/libjoyevent.so.i386 /usr/bin/wine "C:\\Program Files\\Steam\\Steam.exe" -applaunch 2820
GUI wrapper for joyevent_exec script ( using zenity? ). Normal man page. Real GUI for configuration generation and runtime. X52 LCD support. Additional joystick support?
Initial idea: http://hans.fugal.net/blog/2007/06/02/joystick-hat-in-x-plane-in-linux.XTest solution: Xautomation: http://hoopajoo.net.
For additional information / support / bug requests, please visit: https://sourceforge.net/projects/libjoyevent.
Gilboa Davara
Linkedin page