From ac7d8acb9d7b2d18335e5482304f837b1c499360 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 23 Jul 2019 15:24:05 +0000 Subject: Fix [38dc27bd1d]: Tk does not support nor events. Now handle all events up to Button 9. On Windows and Mac, Buttons 8 and 9 are used for the mouse side buttons (as X11 already does). TIP needed for this. --- generic/tkBind.c | 8 ++++++++ generic/tkCanvas.c | 26 +++----------------------- generic/tkEvent.c | 35 ++++++++++++----------------------- generic/tkGrab.c | 13 +------------ generic/tkInt.h | 37 +++++++++++++++++++++++++++++++++++++ generic/tkPointer.c | 14 +------------- generic/tkTextTag.c | 35 ++++++----------------------------- macosx/tkMacOSXMouseEvent.c | 17 +++++++++++------ win/tkWinPointer.c | 6 ++++++ win/tkWinTest.c | 10 ++++++++++ win/tkWinX.c | 17 +++++++++++++++++ 11 files changed, 112 insertions(+), 106 deletions(-) diff --git a/generic/tkBind.c b/generic/tkBind.c index 953d936..15a66f1 100644 --- a/generic/tkBind.c +++ b/generic/tkBind.c @@ -388,6 +388,14 @@ static const ModInfo modArray[] = { {"Button4", Button4Mask, 0}, {"B5", Button5Mask, 0}, {"Button5", Button5Mask, 0}, + {"B6", Button6Mask, 0}, + {"Button6", Button6Mask, 0}, + {"B7", Button7Mask, 0}, + {"Button7", Button7Mask, 0}, + {"B8", Button8Mask, 0}, + {"Button8", Button8Mask, 0}, + {"B9", Button9Mask, 0}, + {"Button9", Button9Mask, 0}, {"Mod1", Mod1Mask, 0}, {"M1", Mod1Mask, 0}, {"Command", Mod1Mask, 0}, diff --git a/generic/tkCanvas.c b/generic/tkCanvas.c index 10e2ce2..7124d51 100644 --- a/generic/tkCanvas.c +++ b/generic/tkCanvas.c @@ -5092,26 +5092,7 @@ CanvasBindProc( switch (eventPtr->type) { case ButtonPress: case ButtonRelease: - switch (eventPtr->xbutton.button) { - case Button1: - mask = Button1Mask; - break; - case Button2: - mask = Button2Mask; - break; - case Button3: - mask = Button3Mask; - break; - case Button4: - mask = Button4Mask; - break; - case Button5: - mask = Button5Mask; - break; - default: - mask = 0; - break; - } + mask = TkGetButtonMask(eventPtr->xbutton.button); /* * For button press events, repick the current item using the button @@ -5194,7 +5175,7 @@ PickCurrentItem( * ButtonRelease, or MotionNotify. */ { double coords[2]; - int buttonDown; + unsigned int buttonDown; Tk_Item *prevItemPtr; SearchUids *searchUids = GetStaticUids(); @@ -5205,8 +5186,7 @@ PickCurrentItem( * for windows. */ - buttonDown = canvasPtr->state - & (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask); + buttonDown = canvasPtr->state & ALL_BUTTONS; /* * Save information about this event in the canvas. The event in the diff --git a/generic/tkEvent.c b/generic/tkEvent.c index b36d5de..d8501c3 100644 --- a/generic/tkEvent.c +++ b/generic/tkEvent.c @@ -193,7 +193,6 @@ TCL_DECLARE_MUTEX(exitMutex) static void CleanUpTkEvent(XEvent *eventPtr); static void DelayedMotionProc(ClientData clientData); -static int GetButtonMask(unsigned int Button); static unsigned long GetEventMaskFromXEvent(XEvent *eventPtr); static TkWindow * GetTkWindowFromXEvent(XEvent *eventPtr); static void InvokeClientMessageHandlers(ThreadSpecificData *tsdPtr, @@ -524,7 +523,7 @@ RefreshKeyboardMappingIfNeeded( /* *---------------------------------------------------------------------- * - * GetButtonMask -- + * TkGetButtonMask -- * * Return the proper Button${n}Mask for the button. * @@ -537,23 +536,15 @@ RefreshKeyboardMappingIfNeeded( *---------------------------------------------------------------------- */ -static int -GetButtonMask( +static const int buttonMasks[] = { + 0, Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask, Button6Mask, Button7Mask, Button8Mask, Button9Mask +}; + +int +TkGetButtonMask( unsigned int button) { - switch (button) { - case 1: - return Button1Mask; - case 2: - return Button2Mask; - case 3: - return Button3Mask; - case 4: - return Button4Mask; - case 5: - return Button5Mask; - } - return 0; + return (button > Button9) ? 0 : buttonMasks[button]; } /* @@ -582,8 +573,6 @@ UpdateButtonEventState( XEvent *eventPtr) { TkDisplay *dispPtr; - int allButtonsMask = Button1Mask | Button2Mask | Button3Mask - | Button4Mask | Button5Mask; switch (eventPtr->type) { case ButtonPress: @@ -591,19 +580,19 @@ UpdateButtonEventState( dispPtr->mouseButtonWindow = eventPtr->xbutton.window; eventPtr->xbutton.state |= dispPtr->mouseButtonState; - dispPtr->mouseButtonState |= GetButtonMask(eventPtr->xbutton.button); + dispPtr->mouseButtonState |= TkGetButtonMask(eventPtr->xbutton.button); break; case ButtonRelease: dispPtr = TkGetDisplay(eventPtr->xbutton.display); dispPtr->mouseButtonWindow = None; - dispPtr->mouseButtonState &= ~GetButtonMask(eventPtr->xbutton.button); + dispPtr->mouseButtonState &= ~TkGetButtonMask(eventPtr->xbutton.button); eventPtr->xbutton.state |= dispPtr->mouseButtonState; break; case MotionNotify: dispPtr = TkGetDisplay(eventPtr->xmotion.display); - if (dispPtr->mouseButtonState & allButtonsMask) { + if (dispPtr->mouseButtonState & ALL_BUTTONS) { if (eventPtr->xbutton.window != dispPtr->mouseButtonWindow) { /* * This motion event should not be interpreted as a button @@ -611,7 +600,7 @@ UpdateButtonEventState( * button was pressed down in. */ - dispPtr->mouseButtonState &= ~allButtonsMask; + dispPtr->mouseButtonState &= ~ALL_BUTTONS; dispPtr->mouseButtonWindow = None; } else { eventPtr->xmotion.state |= dispPtr->mouseButtonState; diff --git a/generic/tkGrab.c b/generic/tkGrab.c index 917ec69..50d2517 100644 --- a/generic/tkGrab.c +++ b/generic/tkGrab.c @@ -135,17 +135,6 @@ typedef struct NewGrabWinEvent { #define GENERATED_GRAB_EVENT_MAGIC ((Bool) 0x147321ac) /* - * Mask that selects any of the state bits corresponding to buttons, plus - * masks that select individual buttons' bits: - */ - -#define ALL_BUTTONS \ - (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask) -static const unsigned int buttonStates[] = { - Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask -}; - -/* * Forward declarations for functions declared later in this file: */ @@ -883,7 +872,7 @@ TkPointerEvent( } else { if (eventPtr->xbutton.button != AnyButton && ((eventPtr->xbutton.state & ALL_BUTTONS) - == buttonStates[eventPtr->xbutton.button - Button1])) { + == (unsigned int)TkGetButtonMask(eventPtr->xbutton.button))) { ReleaseButtonGrab(dispPtr); /* Note 4. */ } } diff --git a/generic/tkInt.h b/generic/tkInt.h index 77b7725..10888f7 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -965,6 +965,43 @@ typedef struct TkpClipMask { #define ALT_MASK (AnyModifier<<2) #define EXTENDED_MASK (AnyModifier<<3) +#ifndef Button6 +# define Button6 6 +#endif +#ifndef Button7 +# define Button7 7 +#endif +#ifndef Button8 +# define Button8 8 +#endif +#ifndef Button9 +# define Button9 9 +#endif + +#ifndef Button6Mask +# define Button6Mask (AnyModifier<<4) +#endif +#ifndef Button7Mask +# define Button7Mask (AnyModifier<<5) +#endif +#ifndef Button8Mask +# define Button8Mask (AnyModifier<<6) +#endif +#ifndef Button9Mask +# define Button9Mask (AnyModifier<<7) +#endif + +/* + * Mask that selects any of the state bits corresponding to buttons, plus + * masks that select individual buttons' bits: + */ + +#define ALL_BUTTONS \ + (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask|Button6Mask|Button7Mask|Button8Mask|Button9Mask) + + +MODULE_SCOPE int TkGetButtonMask(unsigned int); + /* * Object types not declared in tkObj.c need to be mentioned here so they can * be properly registered with Tcl: diff --git a/generic/tkPointer.c b/generic/tkPointer.c index 6e87638..de9d49d 100644 --- a/generic/tkPointer.c +++ b/generic/tkPointer.c @@ -23,18 +23,6 @@ #define Cursor XCursor #endif -/* - * Mask that selects any of the state bits corresponding to buttons, plus - * masks that select individual buttons' bits: - */ - -#define ALL_BUTTONS \ - (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask) -static const unsigned int buttonMasks[] = { - Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask -}; -#define ButtonMask(b) (buttonMasks[(b)-Button1]) - typedef struct { TkWindow *grabWinPtr; /* Window that defines the top of the grab * tree in a global grab. */ @@ -267,7 +255,7 @@ Tk_UpdatePointer( */ for (b = Button1; b <= Button5; b++) { - mask = ButtonMask(b); + mask = TkGetButtonMask(b); if (changes & mask) { if (state & mask) { type = ButtonPress; diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c index cb0993b..bda315e 100644 --- a/generic/tkTextTag.c +++ b/generic/tkTextTag.c @@ -1446,9 +1446,6 @@ TkTextBindProc( TkText *textPtr = clientData; int repick = 0; -# define AnyButtonMask \ - (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask) - textPtr->refCount++; /* @@ -1460,35 +1457,16 @@ TkTextBindProc( if (eventPtr->type == ButtonPress) { textPtr->flags |= BUTTON_DOWN; } else if (eventPtr->type == ButtonRelease) { - int mask; + unsigned int mask; - switch (eventPtr->xbutton.button) { - case Button1: - mask = Button1Mask; - break; - case Button2: - mask = Button2Mask; - break; - case Button3: - mask = Button3Mask; - break; - case Button4: - mask = Button4Mask; - break; - case Button5: - mask = Button5Mask; - break; - default: - mask = 0; - break; - } - if ((eventPtr->xbutton.state & AnyButtonMask) == (unsigned) mask) { + mask = TkGetButtonMask(eventPtr->xbutton.button); + if ((eventPtr->xbutton.state & ALL_BUTTONS) == mask) { textPtr->flags &= ~BUTTON_DOWN; repick = 1; } } else if ((eventPtr->type == EnterNotify) || (eventPtr->type == LeaveNotify)) { - if (eventPtr->xcrossing.state & AnyButtonMask) { + if (eventPtr->xcrossing.state & ALL_BUTTONS) { textPtr->flags |= BUTTON_DOWN; } else { textPtr->flags &= ~BUTTON_DOWN; @@ -1496,7 +1474,7 @@ TkTextBindProc( TkTextPickCurrent(textPtr, eventPtr); goto done; } else if (eventPtr->type == MotionNotify) { - if (eventPtr->xmotion.state & AnyButtonMask) { + if (eventPtr->xmotion.state & ALL_BUTTONS) { textPtr->flags |= BUTTON_DOWN; } else { textPtr->flags &= ~BUTTON_DOWN; @@ -1513,8 +1491,7 @@ TkTextBindProc( unsigned int oldState; oldState = eventPtr->xbutton.state; - eventPtr->xbutton.state &= ~(Button1Mask|Button2Mask - |Button3Mask|Button4Mask|Button5Mask); + eventPtr->xbutton.state &= ~ALL_BUTTONS; if (!(textPtr->flags & DESTROYED)) { TkTextPickCurrent(textPtr, eventPtr); } diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c index 2517769..42fae98 100644 --- a/macosx/tkMacOSXMouseEvent.c +++ b/macosx/tkMacOSXMouseEvent.c @@ -178,22 +178,26 @@ enum { */ unsigned int state = 0; - NSInteger button = [theEvent buttonNumber]; + int button = [theEvent buttonNumber]; + if (++button > 3) { + button += 4; /* Map buttons 4/5 to 8/9 */ + } EventRef eventRef = (EventRef)[theEvent eventRef]; UInt32 buttons; OSStatus err = GetEventParameter(eventRef, kEventParamMouseChord, typeUInt32, NULL, sizeof(UInt32), NULL, &buttons); if (err == noErr) { - state |= (buttons & ((1<<5) - 1)) << 8; - } else if (button < 5) { + state |= (buttons & 0x07) << 8; + state |= (buttons & 0x18) << 12; + } else if (button <= 9) { switch (eventType) { case NSLeftMouseDown: case NSRightMouseDown: case NSLeftMouseDragged: case NSRightMouseDragged: case NSOtherMouseDown: - state |= 1 << (button + 8); + state |= TkGetButtonMask(button); break; default: break; @@ -361,10 +365,11 @@ ButtonModifiers2State( unsigned int state; /* - * Tk supports at most 5 buttons. + * Tk on OSX supports at most 5 buttons. */ - state = (buttonState & ((1<<5) - 1)) << 8; + state = (buttonState & 0x07) * Button1Mask; + state |= (buttonState & 0x18) * (Button8Mask >> 3); if (keyModifiers & alphaLock) { state |= LockMask; diff --git a/win/tkWinPointer.c b/win/tkWinPointer.c index 6f1f840..e3445c7 100644 --- a/win/tkWinPointer.c +++ b/win/tkWinPointer.c @@ -81,6 +81,12 @@ TkWinGetModifierState(void) if (GetKeyState(VK_RBUTTON) & 0x8000) { state |= Button3Mask; } + if (GetKeyState(VK_XBUTTON1) & 0x8000) { + state |= Button8Mask; + } + if (GetKeyState(VK_XBUTTON2) & 0x8000) { + state |= Button9Mask; + } return state; } diff --git a/win/tkWinTest.c b/win/tkWinTest.c index e58ee7c..e386605 100644 --- a/win/tkWinTest.c +++ b/win/tkWinTest.c @@ -287,6 +287,16 @@ TestwineventObjCmd( static const TkStateMap messageMap[] = { {WM_LBUTTONDOWN, "WM_LBUTTONDOWN"}, {WM_LBUTTONUP, "WM_LBUTTONUP"}, + {WM_LBUTTONDBLCLK, "WM_LBUTTONDBLCLK"}, + {WM_MBUTTONDOWN, "WM_MBUTTONDOWN"}, + {WM_MBUTTONUP, "WM_MBUTTONUP"}, + {WM_MBUTTONDBLCLK, "WM_MBUTTONDBLCLK"}, + {WM_RBUTTONDOWN, "WM_RBUTTONDOWN"}, + {WM_RBUTTONUP, "WM_RBUTTONUP"}, + {WM_RBUTTONDBLCLK, "WM_RBUTTONDBLCLK"}, + {WM_XBUTTONDOWN, "WM_XBUTTONDOWN"}, + {WM_XBUTTONUP, "WM_XBUTTONUP"}, + {WM_XBUTTONDBLCLK, "WM_XBUTTONDBLCLK"}, {WM_CHAR, "WM_CHAR"}, {WM_GETTEXT, "WM_GETTEXT"}, {WM_SETTEXT, "WM_SETTEXT"}, diff --git a/win/tkWinX.c b/win/tkWinX.c index db8bc4f..d724282 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -884,9 +884,12 @@ Tk_TranslateWinEvent( case WM_MBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: + case WM_XBUTTONDOWN: + case WM_XBUTTONDBLCLK: case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: + case WM_XBUTTONUP: case WM_MOUSEMOVE: Tk_PointerEvent(hwnd, (short) LOWORD(lParam), (short) HIWORD(lParam)); return 1; @@ -1713,6 +1716,14 @@ TkWinResendEvent( msg = WM_RBUTTONDOWN; wparam = MK_RBUTTON; break; + case Button8: + msg = WM_XBUTTONDOWN; + wparam = MAKEWPARAM(MK_XBUTTON1, XBUTTON1); + break; + case Button9: + msg = WM_XBUTTONDOWN; + wparam = MAKEWPARAM(MK_XBUTTON2, XBUTTON2); + break; default: return 0; } @@ -1726,6 +1737,12 @@ TkWinResendEvent( if (eventPtr->xbutton.state & Button3Mask) { wparam |= MK_RBUTTON; } + if (eventPtr->xbutton.state & Button8Mask) { + wparam |= MK_XBUTTON1; + } + if (eventPtr->xbutton.state & Button9Mask) { + wparam |= MK_XBUTTON2; + } if (eventPtr->xbutton.state & ShiftMask) { wparam |= MK_SHIFT; } -- cgit v0.12