The SpaceBall Controller

==============================================================================

Useful information about the SpaceBall and driving software.
 
						Mark Harris Mar 2001

==============================================================================
The Logitec SpaceBalls are the big brothers of the SpaceOrb, and we are considering them now despite their price because the SpaceOrb has been discontinued.

They are sold by LabTec, whose homepage is impossible to access if your machine doesn't support Flash. You can get to some of their old pages though, and I have some manuals on my local disk.

If you want to know how to run the Spaceball and Spacemouse under GLut on SGI, skip the junk and go here.

17-May-2001
Bought a Spaceball 4000FLX from Adapco (+46(16)51 12 20) for around 4000SEK. Installed on Windows machine and under UNIX on Narva with the following commands :

% rm /mnt
% mkdir /mnt
% mount -rt cdfs -o noversion /dev/rz8c /mnt
% cd /mnt
% ./install.csh
% cd /
% umount /mnt
At first it complained about their being no Spaceball on the serial port. This seemed to be due to X taking over those ports, so I pulled out the old devices plugged in there and restarted the X server (by killing the process "/usr/bin/X11/X"). Worked. Plugged into the lower of the sockets (/dev/tty0 - port1).

Need to start the demon with :
% /usr/SpaceWare/spaceball

Got the SDK from :
http://www.conversations.com/Partners/Labtec/product/3d_motion_control/support/developers/developers.htm

This packaged in the following rather remarkable way :
You download spwsdk_unix_v0706001.tar, and untar to get some files including sdk.tar. When you untar that, you get a file called sdk.tar.Z. You then uncompress this, which overwrites the old sdk.tar, which you then untar to get the sdk out.

Putting the spaceball into O

One day all platforms will use GLut for windowing, openGL for graphics, but at the moment Alphas, Sgi and Sun don't use Glut.

Alpha UNIX

OpenGl-X. Maybe modify the spaceorb demon to pick up X-events from the spaceball demon and hand them on. Maybe use spaceball sdk to write a demon to talk directly to device.

Made spaceball.c that picks up ClientMessages from Labtec demon, and passes them on. But at the moment I need a special window to get focus for input, and then the O-emulator window doesn't have focus. Hmmm.
Needed to be incorporated directly into O. Code is of the following form (demo prog jol.c).
(Note that only button state-changes generate events, and the sensitivity of the ball can be adjusted at the driver level. The user also needs to reset the button functions to AP1, AP2 etc. We can ship this config file to do that when placed in a .spcware directory)

I hoped to be able to port this to Linux, but it seems the SpaceWare library doesn't support it.


// ==================================================================

#include "labtec/spwinput.h";

XEvent event;

SPW_InputEvent          sbEvent;     /* Spaceball event              */
SPW_InputDispatchStruct sbDispatch;  /* Spaceball dispatch structure */

int buttons[15];
int tx,ty,tz,rx,ry,rz;

// ==================================================================

// Setup callback routines
void SbMotionEvent(Display *display, float *data, void *appdata) {
  fprintf(stderr, "Move %f %f \n",data[0],data[1]); // tx,ty,tz,rx,ry,rz
  tx = (int)(data[0]*32.0);
  ty = (int)(data[1]*32.0);
  tz = (int)(data[2]*32.0);
  rx = (int)(data[3]*256.0);
  ry = (int)(data[4]*256.0);
  rz = (int)(data[5]*256.0);
}
void SbButtonPressEvent(Display *display, int button, void *appdata)
{  buttons[button] = 1;
   fprintf(stderr, "Press\n");}

void SbButtonReleaseEvent(Display *display, int button, void *appdata)
{  buttons[button] = 0;
   fprintf(stderr, "Release\n");}

// ==================================================================

main {
...

  XMapWindow(display, SPW_MainWindow);

   if (SPW_InputCheckForSpaceball(display, SPW_MainWindow, "spaceball") == SPW_FALSE) {
      fprintf(stderr, "Sorry - No Spaceball found.\n");
      exit(1);
   }

// Set up callbacks
   SPW_InputInitDispatchStruct(&sbDispatch);

   sbDispatch.display         = display;
   sbDispatch.xevent          = &event;
   sbDispatch.spwevent        = &sbEvent;
   sbDispatch.handle_motion   = SbMotionEvent;
   sbDispatch.handle_bpress   = SbButtonPressEvent;
   sbDispatch.handle_brelease = SbButtonReleaseEvent;

   while(1) { // Check for events, and check it is really a SpaceBall event
      XNextEvent(display, &event);
      if(SPW_InputIsSpaceballEvent(display, &event, &sbEvent) == SPW_TRUE)
         { SPW_InputDispatchEx(&sbDispatch);}
      }

}

// ==================================================================


SGI UNIX

You can read the development history below, or just read the user summary.

OpenGl-X.
This should be an easy one, using X-input-extensions. The simplest test would be to replace the string "dial+buttons" with "spaceball". Nice, but the code doesn't help with the other platforms.

Installed Glut v3.7 on O2 from http://reality.sgi.com/mjk/glut3/glut3.html
Installed SpaceWare driver from CD.
Downloaded red-book example OpenGL/GLut programs from ftp://ftp.sgi.com/sgi/opengl/ to ~markh/glut/openglbk/
Tried to build, Glut library is O32, not N32, so had to add -O32 to compiler options. Then demos run.

Copied movelight.c to ball.c and added callback to glutSpaceBallRotateFunc(). Build fails due to lack of a lot of X routines. Needed -lXi to be added. But then glutDeviceGet() fails to acknowledge the presence of a spaceball even with daemon running.
Or it acknowledged it was there, but then made a terrible beeping noise.

Incidentally, I can't get the SGI confidence test to acknowledge the old SG Spaceball either.

16-Apr-2002 Made a library called mrh_spaceball_lib.c that contains mrh_init_spaceball() and mrh_read_spaceball(), which listens to the Xevents coming from the SpaceWare demon if that is running. A demo program called jolly.c works on Alphas and SGI. glutton.c is the demo Glut program, and alwyn.c is a more advanced demo. Glutton.c waits for events, so I need to have a daughter process doing that. The first attempt is to fork the entire process, which works on the Alpha, but crashes the SGI. It seems that X doesn't really like threads, and/or both X and Glut are looping and waiting for events. Now looking into doing all this through eoe.sw.optinput. Went to SGI "System" "Add input device" "Magellan", and now the confidence test shows the spacemouse to be there (as 'spaceball'). This was a red herring, as we are no longer going the SGI kernal route.

Combined SpaceBall/SpaceMouse driver is /usr/bin/xdriver

Modifying GLut to run the Spaceball or Spacemouse on SGI

Using Adrian Bowyer's modifications to GLut, which include a new callback : glutUserEventFunc(handler);
Downloaded GLut source from http://www.opengl.org/developers/documentation/glut to /home/markh/glut/glut-3.7/ and built it normally.
Demo program ball.c builds and runs fine (but doesn't yet see spacemouse).
Copied the files glut.h and glut_event.c from http://www.bath.ac.uk/~ensab/G_mod/Svlis/spacemouse.html, but then the build failed with Display and window undefined, so had to add "#include " to the new glut.h. Odd that he hadn't done that. Then copied libglut.a to /usr/lib32/
Then downloaded xdrvlib.h (from labtec at http://www.logicad3d.com/software/newsoft-archive.html) into local directory and compiled.
Wrote some interrogation routines in mrh_spaceware_lib.c Need to run SpaceWare demon with application set to "Xlib v2/3" in control panel, and the demon will detect whether you are running a spacemouse or spaceball.

The GLut code looks like this :

...
#include "xdrvlib.h"
extern int mrh_space_event_handler(Display* display, Window window, XEvent*);
...
int mrh_handler(Display* display, Window window, XEvent* event) {
  int ret, data[6],buttons[15];
  ret=mrh_space_event_handler(display, window, event);
  if (ret) { 
    mrh_get_space_motion(rotrans);
    mrh_get_space_buttons(buttons);
    ...
  }
...
  glutInit (&argc, argv);
...
  glutUserEventFunc(mrh_handler);
...
  glutMainLoop ();

Build with :

cc myprog.c -n32 -o myprog  mrh_spaceware_lib.o xdrvlib.o -lglut -lGLU -lGL -lXmu -lX11 -lm

Test program is called alwyn.c

Rotations and translations are returned in a 6-dim int array (rx,ry,rz,tx,ty,tz) and the buttons are returned in a 12-dim int array, with the current state of each button in a corresponding element. Note that the buttons array is bigger than needed for these devices, and that element [0] is never used, as I thought it was better that the state of the button labelled "1" on the device was stored in element [1]. The values of the rotations and translations range from around -3000 to +3000 (except for Y rots which go -6000 to +6000. Maybe I'll change that).
alwyn.c now works. But not if I copy executable over to sarek. Then I get :
11074:./alwyn: rld: Fatal Error: attempted access to unresolvable symbol in ./alwyn: _XSGIFastInternAtom
This is probably because X is being linked dynamically, so should try to link static versions of libXmu and libX11. The first exists in /usr/lib32, the second doesn't.
This worked, and Alwyn built an O with a static library for SGIs that could be exported.

19 June 2002
Alwyn reckons we can link to the new GLut routines without using a modified library, so trying the following :
Put old GLut library back, and tried to build glut_event.c by itself, complained about glutint.h missing, so copied over that. Now alwynl builds but crashes with seg viol. Crash seems to be in glut_event.c. Ugh.

I thought that xdrvlib.c would contain a call for determining which type of joystick has been found (spacemouse or spaceball, but apparently not).

Linux

GLut-OpenGl-X. Glut v3 seems to support the Spaceball directly. Should try aeroplane demo.

Jan 2005

Installed the linux xdriver from 3dconnexion, and got the driver interface to work. Then tried to build a GLut with Bowyer's glutUserEventFunc() included, but the build is going badly.
And even if we succeed, it doesn't help us with O, as we can't distribute a static executable for Linux because there are so many flavours. Even if SpaceMouse users are willing to rebuild their GLut, others won't be, and they will be stuck with undefined symbols.

So now wondering about calling glutSpaceBallRotateFunc() instead. It would be nice to use this as intended, but I suspect that it is just a dummy entry point, in which case we can rewrite it using the code in glutUserEventFunc(). This way we have the same functionality for those willing to rebuild GLut, but there is still an existing entrying point in the default library. This idea started off well, but the rebuild failed.

Windows

GLut-OpenGl-"Windows". Glut v3 seems to support the Spaceball directly. Build ball.c OK, but just like on the SGI, glutDeviceGet() fails to acknowledge the presence of a spaceball with or without the daemon running


Feb 2002

It seems like things are happening at : http://www.3dconnexion.com

Created directory ~markh/spaceball/
Downloaded alpha/NT SDK and Linux Xdriver + xapp. In /home/markh/spaceball/linux/, xapp refuses to run until I load the driver. How do I do that ?

Found more Linux stuff at : http://atrey.karlin.mff.cuni.cz/~vojtech/joystick/ and downloaded the driver to /home/markh/spaceball/linjoy/. Tried to build on jokkmokk but missing pci_ids.h (bug ?). Seem not to have serial port on jokkmokk anyway.

Thinking about SDL too. Licence seems to be OK.

Mark Harris June 2001/Feb202