Index: programs/Xserver/hw/xfree86/input/mouse/mouse.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c,v retrieving revision 1.14 diff -u -p -r1.14 mouse.c --- programs/Xserver/hw/xfree86/input/mouse/mouse.c 8 Nov 2005 06:33:28 -0000 1.14 +++ programs/Xserver/hw/xfree86/input/mouse/mouse.c 9 Nov 2005 16:49:02 -0000 @@ -205,7 +205,8 @@ typedef enum { OPTION_VTIME, OPTION_VMIN, OPTION_DRAGLOCKBUTTONS, - OPTION_DOUBLECLICK_BUTTONS + OPTION_DOUBLECLICK_BUTTONS, + OPTION_BUTTON_MAPPING } MouseOpts; #ifdef XFree86LOADER @@ -245,9 +246,10 @@ static const OptionInfoRec mouseOptions[ { OPTION_FLOW_CONTROL, "FlowControl", OPTV_STRING, {0}, FALSE }, { OPTION_VTIME, "VTime", OPTV_INTEGER, {0}, FALSE }, { OPTION_VMIN, "VMin", OPTV_INTEGER, {0}, FALSE }, + /* end serial options */ { OPTION_DRAGLOCKBUTTONS, "DragLockButtons",OPTV_STRING, {0}, FALSE }, { OPTION_DOUBLECLICK_BUTTONS,"DoubleClickButtons", OPTV_STRING, {0}, FALSE }, - /* end serial options */ + { OPTION_BUTTON_MAPPING, "ButtonMapping", OPTV_STRING, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; #endif @@ -384,6 +386,7 @@ MouseCommonOptions(InputInfoPtr pInfo) MessageType buttons_from = X_CONFIG; char *s; int origButtons; + int i; pMse = pInfo->private; @@ -678,6 +681,27 @@ MouseCommonOptions(InputInfoPtr pInfo) pInfo->name, wheelButton, pMse->wheelInertia, pMse->wheelButtonTimeout); } + s = xf86SetStrOption(pInfo->options, "ButtonMapping", NULL); + if (s) { + int b, n = 0; + /* keep getting numbers which are buttons */ + while (s && n < MSE_MAXBUTTONS && (b = strtol(s, &s, 10)) != 0) { + /* check sanity for a button */ + if (b < 0 || b > MSE_MAXBUTTONS) { + xf86Msg(X_WARNING, + "ButtonMapping: Invalid button number = %d\n", b); + break; + }; + pMse->buttonMap[n++] = 1 << (b-1); + if (b > pMse->buttons) pMse->buttons = b; + } + } + /* get maximum of mapped buttons */ + for (i = pMse->buttons-1; i >= 0; i--) { + int f = ffs (pMse->buttonMap[i]); + if (f > pMse->buttons) + pMse->buttons = f; + } if (origButtons != pMse->buttons) buttons_from = X_CONFIG; xf86Msg(buttons_from, "%s: Buttons: %d\n", pInfo->name, pMse->buttons); @@ -932,6 +956,7 @@ MousePreInit(InputDriverPtr drv, IDevPtr MouseProtocolID protocolID; MouseProtocolPtr pProto; Bool detected; + int i; if (!InitProtocols()) return NULL; @@ -1065,6 +1090,13 @@ MousePreInit(InputDriverPtr drv, IDevPtr pMse->oldProtocolID = protocolID; /* hack */ pMse->autoProbe = FALSE; + /* XXX If the default for ZAxisMapping is decided to be "4 5 6 7" again, + * ButtonMapping should by default remap all button >= 4 to button+4 : + * for (i = 0; i < MSE_MAXBUTTONS; i++) + * pMse->buttonMap[i] = 1 << (i > 2 && i < MSE_MAXBUTTONS-4 ? i+4 : i); + */ + for (i = 0; i < MSE_MAXBUTTONS; i++) + pMse->buttonMap[i] = 1 << i; /* Collect the options, and process the common options. */ xf86CollectInputOptions(pInfo, pProto->defaults, NULL); @@ -1715,6 +1747,7 @@ MouseProc(DeviceIntPtr device, int what) } } pMse->lastButtons = 0; + pMse->lastMappedButtons = 0; pMse->emulateState = 0; pMse->emulate3Pending = FALSE; pMse->wheelButtonExpires = GetTimeInMillis (); @@ -1787,6 +1820,7 @@ FlushButtons(MouseDevPtr pMse) int i, blocked; pMse->lastButtons = 0; + pMse->lastMappedButtons = 0; blocked = xf86BlockSIGIO (); for (i = 1; i <= 5; i++) @@ -1948,11 +1982,10 @@ static signed char stateTab[11][5][3] = * And we remap them (MSBit described first) : * 0 | 4th | 3rd | 2nd | 1st */ -static char reverseMap[32] = { 0, 4, 2, 6, 1, 5, 3, 7, - 8, 12, 10, 14, 9, 13, 11, 15, - 16, 20, 18, 22, 17, 21, 19, 23, - 24, 28, 26, 30, 25, 29, 27, 31}; - +static char reverseMap[16] = { 0, 4, 2, 6, + 1, 5, 3, 7, + 8, 12, 10, 14, + 9, 13, 11, 15 }; static char hitachMap[16] = { 0, 2, 1, 3, 8, 10, 9, 11, @@ -2045,7 +2078,7 @@ static void MouseDoPostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy) { MouseDevPtr pMse; - int truebuttons, emulateButtons; + int emulateButtons; int id, change; int emuWheelDelta, emuWheelButton, emuWheelButtonMask; int wheelButtonMask; @@ -2053,12 +2086,6 @@ MouseDoPostEvent(InputInfoPtr pInfo, int pMse = pInfo->private; - truebuttons = buttons; - if (pMse->protocolID == PROT_MMHIT) - buttons = reverseBits(hitachMap, buttons); - else - buttons = reverseBits(reverseMap, buttons); - /* Do single button double click */ if (pMse->doubleClickSourceButtonMask) { if (buttons & pMse->doubleClickSourceButtonMask) { @@ -2089,10 +2116,7 @@ MouseDoPostEvent(InputInfoPtr pInfo, int /* Emulate wheel button handling */ wheelButtonMask = 1 << (pMse->wheelButton - 1); - if (pMse->protocolID == PROT_MMHIT) - change = buttons ^ reverseBits(hitachMap, pMse->lastButtons); - else - change = buttons ^ reverseBits(reverseMap, pMse->lastButtons); + change = buttons ^ pMse->lastMappedButtons; if (change & wheelButtonMask) { if (buttons & wheelButtonMask) { @@ -2186,12 +2210,9 @@ MouseDoPostEvent(InputInfoPtr pInfo, int if (dx || dy) xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy); - if (truebuttons != pMse->lastButtons) { + if (buttons != pMse->lastMappedButtons) { - if (pMse->protocolID == PROT_MMHIT) - change = buttons ^ reverseBits(hitachMap, pMse->lastButtons); - else - change = buttons ^ reverseBits(reverseMap, pMse->lastButtons); + change = buttons ^ pMse->lastMappedButtons; /* * adjust buttons state for drag locks! @@ -2292,17 +2313,31 @@ MouseDoPostEvent(InputInfoPtr pInfo, int (buttons & (1 << (id - 1))), 0, 0); } - pMse->lastButtons = truebuttons; + pMse->lastMappedButtons = buttons; } } static void -MousePostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy, int dz, int dw) +MousePostEvent(InputInfoPtr pInfo, int truebuttons, + int dx, int dy, int dz, int dw) { MouseDevPtr pMse; int zbutton = 0; + int i, b, buttons = 0; pMse = pInfo->private; + if (pMse->protocolID == PROT_MMHIT) + b = reverseBits(hitachMap, truebuttons); + else + b = reverseBits(reverseMap, truebuttons); + + /* Remap mouse buttons */ + b &= (1<buttonMap[i]; + b >>= 1; + } /* Map the Z axis movement. */ /* XXX Could this go in the conversion_proc? */ @@ -2362,6 +2397,8 @@ MousePostEvent(InputInfoPtr pInfo, int b buttons &= ~zbutton; MouseDoPostEvent(pInfo, buttons, 0, 0); } + + pMse->lastButtons = truebuttons; } /****************************************************************** * Index: programs/Xserver/hw/xfree86/input/mouse/mouse.man =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/input/mouse/mouse.man,v retrieving revision 1.7 diff -u -p -r1.7 mouse.man --- programs/Xserver/hw/xfree86/input/mouse/mouse.man 9 Nov 2005 16:32:51 -0000 1.7 +++ programs/Xserver/hw/xfree86/input/mouse/mouse.man 9 Nov 2005 16:49:02 -0000 @@ -163,6 +163,16 @@ and .IR N4 . Default: no mapping. .TP 7 +.BI "Option \*qButtonMapping\*q \*q" "N1 N2 [...]" \*q +Specifies how physical mouse buttons are mapped to logical buttons. +Physcial button 1 is mapped to logical button +.IR N1 , +physical button 2 to +.IR N2 , +and so forth. This enables the use of physical buttons that are obscured by +.IR ZAxisMapping . +Default: 1-to-1 mapping. +.TP 7 .BI "Option \*qFlipXY\*q \*q" boolean \*q Enable/disable swapping the X and Y axes. This transformation is applied after the Index: programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h,v retrieving revision 1.6 diff -u -p -r1.6 xf86OSmouse.h --- programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h 24 Aug 2005 11:18:31 -0000 1.6 +++ programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h 9 Nov 2005 16:49:04 -0000 @@ -190,6 +190,19 @@ extern OSMouseInfoPtr xf86OSMouseInit(in (xf86GetBuiltinInterfaceVersion(BUILTIN_IF_OSMOUSE, 0) >= \ BUILTIN_INTERFACE_VERSION_NUMERIC(1, 1, 0)) +/* Z axis mapping */ +#define MSE_NOZMAP 0 +#define MSE_MAPTOX -1 +#define MSE_MAPTOY -2 +#define MSE_MAPTOZ -3 +#define MSE_MAPTOW -4 + +/* Generalize for other axes. */ +#define MSE_NOAXISMAP MSE_NOZMAP + +#define MSE_MAXBUTTONS 24 +#define MSE_DFLTBUTTONS 3 + /* * Mouse device record. This is shared by the mouse driver and the OSMouse * layer. @@ -275,19 +288,8 @@ typedef struct _MouseDevRec { int doubleClickTargetButton; int doubleClickTargetButtonMask; int doubleClickOldSourceState; + int lastMappedButtons; + int buttonMap[MSE_MAXBUTTONS]; } MouseDevRec, *MouseDevPtr; -/* Z axis mapping */ -#define MSE_NOZMAP 0 -#define MSE_MAPTOX -1 -#define MSE_MAPTOY -2 -#define MSE_MAPTOZ -3 -#define MSE_MAPTOW -4 - -/* Generalize for other axes. */ -#define MSE_NOAXISMAP MSE_NOZMAP - -#define MSE_MAXBUTTONS 24 -#define MSE_DFLTBUTTONS 3 - #endif /* _XF86OSMOUSE_H_ */ Index: programs/Xserver/hw/xfree86/os-support/bsd/bsd_mouse.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_mouse.c,v retrieving revision 1.6 diff -u -p -r1.6 bsd_mouse.c --- programs/Xserver/hw/xfree86/os-support/bsd/bsd_mouse.c 3 Oct 2005 16:46:14 -0000 1.6 +++ programs/Xserver/hw/xfree86/os-support/bsd/bsd_mouse.c 9 Nov 2005 16:49:04 -0000 @@ -551,6 +551,7 @@ usbMouseProc(DeviceIntPtr pPointer, int } } pMse->lastButtons = 0; + pMse->lastMappedButtons = 0; pMse->emulateState = 0; pPointer->public.on = TRUE; break; Index: programs/Xserver/hw/xfree86/os-support/hurd/hurd_mouse.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_mouse.c,v retrieving revision 1.4 diff -u -p -r1.4 hurd_mouse.c --- programs/Xserver/hw/xfree86/os-support/hurd/hurd_mouse.c 3 Jul 2005 07:01:31 -0000 1.4 +++ programs/Xserver/hw/xfree86/os-support/hurd/hurd_mouse.c 9 Nov 2005 16:49:04 -0000 @@ -131,6 +131,7 @@ OsMouseProc(DeviceIntPtr pPointer, int w } } pMse->lastButtons = 0; + pMse->lastMappedButtons = 0; pMse->emulateState = 0; pPointer->public.on = TRUE; break; Index: programs/Xserver/hw/xfree86/os-support/nto/nto_mouse.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/os-support/nto/nto_mouse.c,v retrieving revision 1.4 diff -u -p -r1.4 nto_mouse.c --- programs/Xserver/hw/xfree86/os-support/nto/nto_mouse.c 3 Jul 2005 07:01:34 -0000 1.4 +++ programs/Xserver/hw/xfree86/os-support/nto/nto_mouse.c 9 Nov 2005 16:49:04 -0000 @@ -99,6 +99,7 @@ int what; AddEnabledDevice(pInfo->fd); } pMse->lastButtons = 0; + pMse->lastMappedButtons = 0; pMse->emulateState = 0; pPointer->public.on = TRUE; break; Index: programs/Xserver/hw/xfree86/os-support/os2/os2_mouse.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_mouse.c,v retrieving revision 1.6 diff -u -p -r1.6 os2_mouse.c --- programs/Xserver/hw/xfree86/os-support/os2/os2_mouse.c 3 Jul 2005 08:53:47 -0000 1.6 +++ programs/Xserver/hw/xfree86/os-support/os2/os2_mouse.c 9 Nov 2005 16:49:04 -0000 @@ -462,6 +462,7 @@ int os2MouseProc(DeviceIntPtr pPointer, case DEVICE_ON: if (!HandleValid) return -1; pMse->lastButtons = 0; + pMse->lastMappedButtons = 0; pMse->emulateState = 0; pPointer->public.on = TRUE; state = 0x300; Index: programs/Xserver/hw/xfree86/os-support/qnx4/qnx_mouse.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/os-support/qnx4/qnx_mouse.c,v retrieving revision 1.4 diff -u -p -r1.4 qnx_mouse.c --- programs/Xserver/hw/xfree86/os-support/qnx4/qnx_mouse.c 3 Jul 2005 07:01:35 -0000 1.4 +++ programs/Xserver/hw/xfree86/os-support/qnx4/qnx_mouse.c 9 Nov 2005 16:49:04 -0000 @@ -159,6 +159,7 @@ int what; case DEVICE_ON: if(QNX_mouse == NULL) return(-1); pMse->lastButtons = 0; + pMse->lastMappedButtons = 0; pMse->emulateState = 0; pPointer->public.on = TRUE; mouse_flush(QNX_mouse); Index: programs/Xserver/hw/xfree86/os-support/sco/sco_mouse.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/os-support/sco/sco_mouse.c,v retrieving revision 1.5 diff -u -p -r1.5 sco_mouse.c --- programs/Xserver/hw/xfree86/os-support/sco/sco_mouse.c 8 Nov 2005 06:33:29 -0000 1.5 +++ programs/Xserver/hw/xfree86/os-support/sco/sco_mouse.c 9 Nov 2005 16:49:04 -0000 @@ -152,6 +152,7 @@ OsMouseProc (DeviceIntPtr pPointer, int case DEVICE_ON: pMse->lastButtons = 0; + pMse->lastMappedButtons = 0; pMse->emulateState = 0; pPointer->public.on = TRUE; ev_resume(); Index: programs/Xserver/hw/xfree86/os-support/sysv/xqueue.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/os-support/sysv/xqueue.c,v retrieving revision 1.4 diff -u -p -r1.4 xqueue.c --- programs/Xserver/hw/xfree86/os-support/sysv/xqueue.c 3 Jul 2005 07:01:37 -0000 1.4 +++ programs/Xserver/hw/xfree86/os-support/sysv/xqueue.c 9 Nov 2005 16:49:04 -0000 @@ -480,6 +480,7 @@ XqMouseProc(DeviceIntPtr pPointer, int w case DEVICE_ON: pMse->lastButtons = 0; + pMse->lastMappedButtons = 0; pMse->emulateState = 0; pPointer->public.on = TRUE; ret = XqEnable(pInfo);