$Id$ This patch by Bartosz Zapalowski. Already submitted upstream; see . diff -ruN xc-old/programs/Xserver/hw/xfree86/input/mouse/mouse.c xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c --- xc-old/programs/Xserver/hw/xfree86/input/mouse/mouse.c 2004-10-21 06:27:45.939356000 +0000 +++ xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c 2004-10-21 06:57:22.764238432 +0000 @@ -368,6 +368,45 @@ } #endif +static void +MousePrepareShiftData(MouseDevPtr pMse) +{ + int wheels = 0; + int c, cs = 1, shifted = 0, s, ss, seen, mayshift = 0; + + if (!pMse->buttonsShiftData) + return; + + wheels |= pMse->negativeZ | pMse->positiveZ + | pMse->negativeW | pMse->positiveW; + + for (c = 0; c < pMse->buttons; c++, cs = cs << 1) + { + if ((wheels & cs) == cs) + shifted++; + else if (shifted > 0) + mayshift++; + + if (shifted == 0) + pMse->buttonsShiftData[c] = cs; + else { + ss = cs; + seen = 1; + for (s = c; s < pMse->buttons; s++, ss = ss << 1) + { + if ((wheels & ss) == ss) + continue; + if (seen < (shifted + mayshift)) { + seen++; + continue; + } + pMse->buttonsShiftData[c] = ss; + break; + } + } + } +} + /* Process options common to all mouse types. */ static void MouseCommonOptions(InputInfoPtr pInfo) @@ -664,7 +703,11 @@ if (origButtons != pMse->buttons) buttons_from = X_CONFIG; xf86Msg(buttons_from, "%s: Buttons: %d\n", pInfo->name, pMse->buttons); - + + pMse->buttonsShiftData = xcalloc(sizeof(int), pMse->buttons); + + MousePrepareShiftData(pMse); + } /* * map bits corresponding to lock buttons. @@ -2185,6 +2228,23 @@ } } +static int +MouseShiftButtons (MouseDevPtr pMse, int buttons) +{ + int i, s = 1; + int newbuttons = 0; + + if (!pMse->buttonsShiftData) + return buttons; + + for (i = 0; i < pMse->buttons; i++, s = s << 1) { + if (buttons & s) + newbuttons |= pMse->buttonsShiftData[i]; + } + + return newbuttons; +} + static void MousePostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy, int dz, int dw) { @@ -2211,6 +2271,7 @@ } break; default: /* buttons */ + buttons = MouseShiftButtons (pMse, buttons); buttons &= ~(pMse->negativeZ | pMse->positiveZ | pMse->negativeW | pMse->positiveW); if (dw < 0 || dz < -1) diff -ruN xc-old/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h --- xc-old/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h 2004-07-24 17:35:39.000000000 +0000 +++ xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h 2004-10-21 06:58:47.382374520 +0000 @@ -269,6 +269,7 @@ int angleOffset; pointer pDragLock; /* drag lock area */ int xisbscale; /* buffer size for 1 event */ + int * buttonsShiftData; } MouseDevRec, *MouseDevPtr; /* Z axis mapping */