** Svgalib mouse wheel support: the Readme ** by Brion Vibber 5 July 1998 / svgalib 1.3.0 (development version) ** Introduction In 1997 Microsoft shocked the world by releasing a pretty nifty product - the IntelliMouse. This radical new mouse design included a wheel between its two buttons, which could be clicked like a middle button or turned to provide an application-specific function, normally scrolling but sometimes zooming or something else. A number of similar designs now exist, some with simple wheels, some with clickable up and down buttons, even some with two wheels, mini-joysticks, and all manner of odd enhancements. Currently only the single wheel mice compatible with the original IntelliMouse are supported by svgalib. However mouse wheel support for svgalib is still in its infancy... as such things are in a state of flux and could be changed dramatically in the near future. Suggestions and comments on the wheel interface are welcome! Future updates will be available at http://pobox.com/~brion/linux/svgalib.html ** The Mice The wheel mice known to work are: Microsoft IntelliMouse version 1.1A PS/2 Logitech FirstMouse+ PS/2 Logitech Pilot+ Serial Logitech MouseMan+ Serial ** For the User If you're upgrading from a previous version of svgalib, take a look at the sample libvga.config file in the source distribution; there are many new features and they are described here. Or you can look at the man page for libvga.config which contains the same information. You will need to set the appropriate mouse type - `IntelliMouse' for serial mice or `IMPS2' for PS/2 mice - in order for the mouse to work properly. Note that at least with PS/2 IntelliMice, once it is initialized into wheel mode it stays that way, so gpm and X if you use them should be properly configured as well - see http://www.inria.fr/koala/colas/mouse-wheel-scroll/ for such information. The wheel uses the RX axis (rotation around the X axis), which is not used by most existing programs, so as a bridge there is a feature called fake keyboard events - this simulates a keypress when the wheel is turned. It is only useful for some programs that use raw keyboard support, and only for some functions within them. If in doubt, try it out. Quake and Quake II are known to work, although it's not very useful in classic Quake. ** For the Developer So you want to support the wheel in your programs? Excellent, because now you finally can! Turning the wheel rotates the mouse around the RX axis - you can use the mouse_getposition_6d function to return a 3d position; if you don't care about the others (not used on anything but the Spaceball) you can just give NULL pointers for z, ry, and rz. You can set the range along the RX axis that the mouse can move with mouse_setrange_6d(); it is recommended that you allow negative positions, or else set the initial position to something in the middle of the range instead of zero. Note that the user can set the amount that the RX axis is changed for each turn in the configuration file, and mouse acceleration may also affect the rate, so you might experiment a bit with how distance along the axis translates into program action; the user should be able to increase the speed or amount of your program's action by increasing the delta but things should remain reasonable. You may wish to zero out the RX axis position with mouse_setposition_6d after each turn is handled, but this depends on how you are using it. Remember that while regular mice have no RX axis and thus always show 0 on it, the Spaceball does have a real RX axis. You should either do something that will make since on the spaceball as well as wheel mice or you should detect the mouse type to determine whether you've got a wheel or not. To make this forwards-compatible to future mouse types I've added a way to ask svgalib for the mouse's capabilities. But, tn order to try to keep it somewhat backwards compatible, I'm setting this up as a funny sequence of existing funtion calls and an inline function to simplify calling them. Call mouse_setposition_6d() with the X axis set to MOUSE_WANTCAPS and a mask of MOUSE_CAPS, then immediately call mouse_getposition_6d() and store the results (currently only X, Y, Z, and RX are used). The X axis should be set to MOUSE_GOTCAPS; if it is not then you are linked with an old version of svgalib and you should base your info on the mouse type - this can be determined from (vga_getmousetype() & MOUSE_TYPE_MASK) and compared against the type constants determined in vgamouse.h. If it is then you can parse the various `axes' for the information they contain - Y is the available buttons (a combination of the MOUSE_*BUTTON constants), Z is the axes (MOUSE_*DIM), and RX is other info (MOUSE_INFO_*). Just a note - we can't tell for sure if a middle button is available on many mouse types so it'll probably be set regardless. If this seems a bit complicated, don't worry. An inline function is provided to hide this complexity called mouse_getcaps (which will probably become a real function in a future version of svgalib) and a structure type called MouseCaps. Here's an example of how a program might go about this: struct MouseCaps caps; if(mouse_getcaps(&caps)) { /* Failed! Old version... Check the mouse type. */ switch(vga_getmousetype() & MOUSE_TYPE_MASK) { case MOUSE_SPACEBALL: /* This is a 6D mouse but there may be other types added later that we won't know about! */ break; case MOUSE_INTELLIMOUSE: case MOUSE_IMPS2: /* This is a wheel mouse but there may be new and incompatible types added later... */ break; default: /* Probably a regular mouse... */ } } else { if((caps.axes & MOUSE_6DIM) == MOUSE_6DIM) { /* We have any 6D mouse, interpret axes appropriately */ } if(caps.info & MOUSE_INFO_WHEEL) { /* This is any wheel mouse, interpret rx as for a wheel */ } /* ... */ } For a vague example of all this look at the updated mousetest.c in the demos subdirectory of the svgalib distribution. It's not perfect but you might get some ideas. ** Notes 'n' stuff ** END