Section "InputDevice" Identifier "idevname" Driver "spaceball" Option "Device" "devpath" ... EndSection
It is possible to send command strings that will be sent directly to
the spaceball. These are sent via an XChangeDeviceControl hack.
It is a hack because the only currently defined control type is DEVICE_RESOLUTION
(see BUGS). The example code below shows how to send a string
to the Spaceball. The most useful string is a bell command. You can
send a single beep with "\rS\r" or a custom multi-beep with "\rBbeep-commands\r",
where beep-commands are lowercase letters for a beep from short (a) to
long (z), and uppercase for a pause. You must end in a pause, or the bell
will stay on. Example: "\rBcCcA\r" will send a double beep.
/* Subroutine to send a char string to the spaceball */
#include <X11/extensions/XInput.h>
#define DATA_LENGTH 6
int
SpaceballDeviceControl (Display * display, XDevice * xdevice, char
*string)
{
int i;
int slen = strlen (string);
int data[DATA_LENGTH];
int err = 0;
XDeviceResolutionControl ctrl;
ctrl.control = DEVICE_RESOLUTION;
ctrl.length = sizeof (ctrl);
ctrl.first_valuator = 0;
ctrl.num_valuators = 0;
ctrl.resolutions = (int *) data;
for (i = 0; i < slen; i++)
{
data[ctrl.num_valuators] = (int)
string[i];
if (++ctrl.num_valuators == DATA_LENGTH)
{
if ((err
= XChangeDeviceControl(display,
xdevice, DEVICE_RESOLUTION,
(XDeviceControl *) (&ctrl))) )
return (err);
ctrl.num_valuators
= 0;
}
}
if (ctrl.num_valuators != 0)
err =
XChangeDeviceControl (display, xdevice,
DEVICE_RESOLUTION,
(XDeviceControl *) (&ctrl));
return (err);
}
This driver works with the glut spaceball callbacks, and with a patched
version of the Spaceware SDK. The only significant patch to the SDK was
adding the DeviceControl hack to send stings to the spaceball. Contact
the author if you would like a copy of this patch.
The driver can supply a period pseudo-valuator, which represents the time since the last internal motion event in 1/16 milliseconds. Scaling the valuators by this number will give an integration effect in case events are delayed. Events normally occur at a constant rate, so this value can typically be ignored. The period is supplied as the 7th valuator, and is sent in a seperate motion event preceding the actual valuator data. This is the format expected by the Spaceware SDK. Default: on.
Option "Device" "devpath"
This defines the name of the serial port device that the Spaceball is connected to. Default: /dev/spaceball
Please refer to XF86Config(5x)
for general configuration details and for options that can be used with
all input drivers. This section only covers configuration details specific
to this driver.
Driver initialization will take up to 10 seconds trying access the device on the serial port, with the Xserver paused during the process. This is bad, but consistent with at least the SpaceORB driver. Ideally, we should only try to access the device at the time of an XOpenDevice call, and return a failure if it isn't found right away.
Currently, I send device-control strings to the spcaeball as they arrive. I should probably accumulate characters until a zero is received, then send the whole packet.
The device controls are implemented via a hack. To do it right, the device control copmmands need a new control type. I propose a DEVICE_PRIVATE type for device control commands, to send for device-specific character string commands. Char data is the easiest to implement for general-purpose data, because there is no byte-swapping to worry about.
typedef struct {
XID
control; /* DEVICE_PRIVATE */
int
length;
int
private_type; /* device-specific command type */
int
data_length; /* Number of chars to send */
char
*data; /* device
char command data*/
} XDevicePrivateCharControl;