ml32/Linux-Virtual-Joystick — comment on commit cb59dd979b8438f4436fe1c8eb22552ebbdda408
File:  line 0
By ml32:

Hey,
I actually wrote this a few years ago and haven't touched it since, so I might have forgotten a few of the details.
First, make sure that /dev/uinput exists (it might also be /dev/misc/uinput or /dev/input/uinput) and that you have the necessary permissions to read/write from it. The uinput system is used to create the virtual device and send input events. It should exist on most distros, but if it doesn't you might have to install the module yourself.
What the main program does is load a Python module from ~/.config/vjoy/modules/ and create the device from information obtained through the getVJoyInfo() callback within the module. The bulk of the work is done within the doVJoyThink() callback, which is called periodically (60Hz, as defined in the vjoy.h header). This function is expected to return a tuple of input events in the form (type, code, value). The 'type' and 'code' constants can be imported from the python module provided by vjoy (you can get a list by calling dir(vjoy) from the interpreter or by reading vjoy_python.c). For a simple absolute X-axis input event, you would return [(vjoy.EV_ABS, vjoy.ABS_X, x_value)].
Some other callbacks are provided, including doVJoyUploadFeedback(effect) and doVJoyEraseFeedback(effectid), which are only relevant for virtual devices supporting force-feedback/rumble and doVJoyEvent(evtype, evcode, evvalue), which allows you to handle miscellaneous events from uinput. You don't need to really support any of these three methods for a very basic input device, it is sufficient to do something like:
def doVJoyUploadFeedback(effect):
pass
def doVJoyEraseFeedback(effectid):
pass
doVJoyEvent(evtype, evcode, evvalue):
pass

So it really all boils down to the dictionary returned from getVJoyInfo() and doVJoyThink(). You would run the program with the module you wish to load as the argument (i.e. if you want to load ~/.config/vjoy/modules/example.py, invoke it as "vjoy example").
example.py is code for a complete device with x- and y- axises which move in a circle and prints force-feedback information. I would ignore testjoy.py, as it appears to be outdated. As for the remote interface, you should be able to import and use any Python module to actually obtain input, including pySerial or any networking libraries you may use.

I wouldn't consider any of this code 'complete', but I think it's a decent starting point. Hope this helps.