Suppose you were to read from /dev/psaux with a mouse attached. What would you see? Every time these was mouse action, you'd see three bytes. The first one of these indicates the state of the first three mouse buttons, using bit 1 (0x01) for button 1, bit 2 (0x02) for button 2, and so forth. The bits are set when the buttons are down. Bit 4 (0x08) is always set (but I'm told Microsoft mice violate the spec by not setting it). The next two bytes contain movement information, first for X and then for Y.
So where does the scroll-wheel information come from? The scroll-wheel mice extended the protocol by adding a fourth byte, for the "z axis." By default, this byte is not sent; the mice are in "backward-compatible" mode where they send three bytes only. When the computer can deal with the fourth byte, it tells the mouse this (the exact initialization string sent differs by brand; look in mice.c in GPM or xf86_Mouse.c in XFree86 for details, or see the datasheets for the mouse controller chips, some of which describe the protocol very nicely). After the mouse gets this initialization, it starts sending the fourth byte with Z information.
What's in this fourth byte? My Logitech scroll mouse sends -1 when the wheel is scrolled up, and 1 when it is scrolled down. My recently acquired "A4 Tech WinBest 4D+ Mouse", which has two scroll wheels, sends -1 and 1 for the left one, and -2 and 2 for the right one.
default: /* buttons */ buttons &= ~(mouse->negativeZ | mouse->positiveZ); if (dz < 0) buttons |= mouse->negativeZ; else if (dz > 0) buttons |= mouse->positiveZ; dz = 0; break;In this code snippet, mouse->negativeZ and mouse->positiveZ are the two buttons you specified on the ZAxisMapping line of your XF86Config file; dz is the value of the fourth byte received from the mouse. As can be easily seen, XFree86 look only at whether this value is less than or greater than zero, so a mouse which sends -1 and -2 to mean different things isn't going to accomplish very much.
Note that this may or may not apply to XFree86 4, about which I know absolutely nothing.
Section "Pointer" Protocol "IMPS/2" Device "/dev/psaux" Buttons 7 ZAxisMapping 4 5 6 7 EndSectionThe second set of buttons are used when the mouse returns -2 or 2; the third set when it returns -3 and 3, and so forth. The first set is used for -1 and 1, and also for any other values that don't match.
The modifications above weren't enough to get it working. XFree86 purports to support up to 12 buttons, but it doesn't, really. XFree86 stores buttons as ORed bits; the first button is 1, the second is 2, the third is 4, and so forth. It turns out that the order of the first three buttons is the opposite of what most people actually want, going from 3 to 1 instead of the other way around. XFree86 reverses them for your convenience. Because they're stored as ORed bits, XFree86 uses a lookup table to do the reversal, for efficiency. However, the lookup table has only 32 entries - which means it doesn't cover anything with button 6 or higher set. This seems to be completely arbitrary, and introduces an artificial limitation that needn't be there.
Thus, I apply the lookup table only to the low three bits of the button value. This allows buttons 6 and 7, and in fact all the buttons up to 12, to pass through unscathed.
#define MAX_BUTTONS 5in twm.h is changed to a higher number, ctwm is perfectly able to use the higher buttons. You're unlikely to be able to get support from closed-source programs, however; forget about using the second scroll wheel in Netscape, at least directly as buttons 6 and 7.