diff options
Diffstat (limited to 'generic/tkBind.c')
-rw-r--r-- | generic/tkBind.c | 224 |
1 files changed, 111 insertions, 113 deletions
diff --git a/generic/tkBind.c b/generic/tkBind.c index ad59299..3776c95 100644 --- a/generic/tkBind.c +++ b/generic/tkBind.c @@ -62,21 +62,21 @@ * equivalent sequences. However it is logical to give <Double-1> higher precedence * since it is more specific. Indeed <Double-1> includes time and space requirements, * which is not the case for <1><1>. - * This can be achieved by setting PREFER_MOST_SPECIALIZED_EVENT to 1. + * This is achieved by setting PREFER_MOST_SPECIALIZED_EVENT to 1. */ #ifndef PREFER_MOST_SPECIALIZED_EVENT -# define PREFER_MOST_SPECIALIZED_EVENT 0 +# define PREFER_MOST_SPECIALIZED_EVENT 1 #endif /* * Traditionally motion events can be combined with buttons in this way: <B1-B2-Motion>. - * However it should be allowed to express this as <Motion-1-2> in addition. This can be - * achieved by setting SUPPORT_ADDITIONAL_MOTION_SYNTAX to 1. + * However it should be allowed to express this as <Motion-1-2> in addition. This is achieved + * by setting SUPPORT_ADDITIONAL_MOTION_SYNTAX to 1. */ #ifndef SUPPORT_ADDITIONAL_MOTION_SYNTAX -# define SUPPORT_ADDITIONAL_MOTION_SYNTAX 0 /* set to 1 if wanted */ +# define SUPPORT_ADDITIONAL_MOTION_SYNTAX 1 #endif /* @@ -445,6 +445,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}, @@ -723,7 +731,6 @@ static int NameToWindow(Tcl_Interp *interp, Tk_Window main, Tcl_Obj *objPtr, Tk_Window *tkwinPtr); static unsigned ParseEventDescription(Tcl_Interp *interp, const char **eventStringPtr, TkPattern *patPtr, unsigned *eventMaskPtr); -static void DoWarp(ClientData clientData); static PSList * GetLookupForEvent(LookupTables* lookupPtr, const Event *eventPtr, Tcl_Obj *object, int onlyConsiderDetailedEvents); static void ClearLookupTable(LookupTables *lookupTables, ClientData object); @@ -785,8 +792,10 @@ static unsigned GetButtonNumber( const char *field) { + unsigned button; assert(field); - return (field[0] >= '1' && field[0] <= '5' && field[1] == '\0') ? field[0] - '0' : 0; + button = (field[0] >= '1' && field[0] <= '9' && field[1] == '\0') ? field[0] - '0' : 0; + return (button > 3) ? (button + 4) : button; } static Time @@ -946,6 +955,7 @@ FreePatSeqEntry( PSEntry *entry) { PSEntry *next = PSList_Next(entry); + PSModMaskArr_Free(&entry->lastModMaskArr); ckfree(entry); return next; @@ -983,7 +993,11 @@ ButtonNumberFromState( if (state & Button2Mask) { return 2; } if (state & Button3Mask) { return 3; } if (state & Button4Mask) { return 4; } - return 5; + if (state & Button5Mask) { return 5; } + if (state & Button6Mask) { return 6; } + if (state & Button7Mask) { return 7; } + if (state & Button8Mask) { return 8; } + return 9; } static void @@ -1272,49 +1286,49 @@ TkBindInit( assert(NoSymbol == 0L); /* this must be a union, not a struct, otherwise comparison with NULL will not work */ - assert(Tk_Offset(Detail, name) == Tk_Offset(Detail, info)); + assert(offsetof(Detail, name) == offsetof(Detail, info)); /* we use some constraints about X*Event */ - assert(Tk_Offset(XButtonEvent, time) == Tk_Offset(XMotionEvent, time)); - assert(Tk_Offset(XButtonEvent, x_root) == Tk_Offset(XMotionEvent, x_root)); - assert(Tk_Offset(XButtonEvent, y_root) == Tk_Offset(XMotionEvent, y_root)); - assert(Tk_Offset(XCreateWindowEvent, border_width) == Tk_Offset(XConfigureEvent, border_width)); - assert(Tk_Offset(XCreateWindowEvent, width) == Tk_Offset(XConfigureEvent, width)); - assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XCirculateRequestEvent, window)); - assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XConfigureEvent, window)); - assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XGravityEvent, window)); - assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XMapEvent, window)); - assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XReparentEvent, window)); - assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XUnmapEvent, window)); - assert(Tk_Offset(XCreateWindowEvent, x) == Tk_Offset(XConfigureEvent, x)); - assert(Tk_Offset(XCreateWindowEvent, x) == Tk_Offset(XGravityEvent, x)); - assert(Tk_Offset(XCreateWindowEvent, y) == Tk_Offset(XConfigureEvent, y)); - assert(Tk_Offset(XCreateWindowEvent, y) == Tk_Offset(XGravityEvent, y)); - assert(Tk_Offset(XCrossingEvent, time) == Tk_Offset(XEnterWindowEvent, time)); - assert(Tk_Offset(XCrossingEvent, time) == Tk_Offset(XLeaveWindowEvent, time)); - assert(Tk_Offset(XCrossingEvent, time) == Tk_Offset(XKeyEvent, time)); - assert(Tk_Offset(XKeyEvent, root) == Tk_Offset(XButtonEvent, root)); - assert(Tk_Offset(XKeyEvent, root) == Tk_Offset(XCrossingEvent, root)); - assert(Tk_Offset(XKeyEvent, root) == Tk_Offset(XMotionEvent, root)); - assert(Tk_Offset(XKeyEvent, state) == Tk_Offset(XButtonEvent, state)); - assert(Tk_Offset(XKeyEvent, state) == Tk_Offset(XMotionEvent, state)); - assert(Tk_Offset(XKeyEvent, subwindow) == Tk_Offset(XButtonEvent, subwindow)); - assert(Tk_Offset(XKeyEvent, subwindow) == Tk_Offset(XCrossingEvent, subwindow)); - assert(Tk_Offset(XKeyEvent, subwindow) == Tk_Offset(XMotionEvent, subwindow)); - assert(Tk_Offset(XKeyEvent, time) == Tk_Offset(XButtonEvent, time)); - assert(Tk_Offset(XKeyEvent, time) == Tk_Offset(XMotionEvent, time)); - assert(Tk_Offset(XKeyEvent, x) == Tk_Offset(XButtonEvent, x)); - assert(Tk_Offset(XKeyEvent, x) == Tk_Offset(XCrossingEvent, x)); - assert(Tk_Offset(XKeyEvent, x) == Tk_Offset(XMotionEvent, x)); - assert(Tk_Offset(XKeyEvent, x_root) == Tk_Offset(XButtonEvent, x_root)); - assert(Tk_Offset(XKeyEvent, x_root) == Tk_Offset(XCrossingEvent, x_root)); - assert(Tk_Offset(XKeyEvent, x_root) == Tk_Offset(XMotionEvent, x_root)); - assert(Tk_Offset(XKeyEvent, y) == Tk_Offset(XButtonEvent, y)); - assert(Tk_Offset(XKeyEvent, y) == Tk_Offset(XCrossingEvent, y)); - assert(Tk_Offset(XKeyEvent, y) == Tk_Offset(XMotionEvent, y)); - assert(Tk_Offset(XKeyEvent, y_root) == Tk_Offset(XButtonEvent, y_root)); - assert(Tk_Offset(XKeyEvent, y_root) == Tk_Offset(XCrossingEvent, y_root)); - assert(Tk_Offset(XKeyEvent, y_root) == Tk_Offset(XMotionEvent, y_root)); + assert(offsetof(XButtonEvent, time) == offsetof(XMotionEvent, time)); + assert(offsetof(XButtonEvent, x_root) == offsetof(XMotionEvent, x_root)); + assert(offsetof(XButtonEvent, y_root) == offsetof(XMotionEvent, y_root)); + assert(offsetof(XCreateWindowEvent, border_width) == offsetof(XConfigureEvent, border_width)); + assert(offsetof(XCreateWindowEvent, width) == offsetof(XConfigureEvent, width)); + assert(offsetof(XCreateWindowEvent, window) == offsetof(XCirculateRequestEvent, window)); + assert(offsetof(XCreateWindowEvent, window) == offsetof(XConfigureEvent, window)); + assert(offsetof(XCreateWindowEvent, window) == offsetof(XGravityEvent, window)); + assert(offsetof(XCreateWindowEvent, window) == offsetof(XMapEvent, window)); + assert(offsetof(XCreateWindowEvent, window) == offsetof(XReparentEvent, window)); + assert(offsetof(XCreateWindowEvent, window) == offsetof(XUnmapEvent, window)); + assert(offsetof(XCreateWindowEvent, x) == offsetof(XConfigureEvent, x)); + assert(offsetof(XCreateWindowEvent, x) == offsetof(XGravityEvent, x)); + assert(offsetof(XCreateWindowEvent, y) == offsetof(XConfigureEvent, y)); + assert(offsetof(XCreateWindowEvent, y) == offsetof(XGravityEvent, y)); + assert(offsetof(XCrossingEvent, time) == offsetof(XEnterWindowEvent, time)); + assert(offsetof(XCrossingEvent, time) == offsetof(XLeaveWindowEvent, time)); + assert(offsetof(XCrossingEvent, time) == offsetof(XKeyEvent, time)); + assert(offsetof(XKeyEvent, root) == offsetof(XButtonEvent, root)); + assert(offsetof(XKeyEvent, root) == offsetof(XCrossingEvent, root)); + assert(offsetof(XKeyEvent, root) == offsetof(XMotionEvent, root)); + assert(offsetof(XKeyEvent, state) == offsetof(XButtonEvent, state)); + assert(offsetof(XKeyEvent, state) == offsetof(XMotionEvent, state)); + assert(offsetof(XKeyEvent, subwindow) == offsetof(XButtonEvent, subwindow)); + assert(offsetof(XKeyEvent, subwindow) == offsetof(XCrossingEvent, subwindow)); + assert(offsetof(XKeyEvent, subwindow) == offsetof(XMotionEvent, subwindow)); + assert(offsetof(XKeyEvent, time) == offsetof(XButtonEvent, time)); + assert(offsetof(XKeyEvent, time) == offsetof(XMotionEvent, time)); + assert(offsetof(XKeyEvent, x) == offsetof(XButtonEvent, x)); + assert(offsetof(XKeyEvent, x) == offsetof(XCrossingEvent, x)); + assert(offsetof(XKeyEvent, x) == offsetof(XMotionEvent, x)); + assert(offsetof(XKeyEvent, x_root) == offsetof(XButtonEvent, x_root)); + assert(offsetof(XKeyEvent, x_root) == offsetof(XCrossingEvent, x_root)); + assert(offsetof(XKeyEvent, x_root) == offsetof(XMotionEvent, x_root)); + assert(offsetof(XKeyEvent, y) == offsetof(XButtonEvent, y)); + assert(offsetof(XKeyEvent, y) == offsetof(XCrossingEvent, y)); + assert(offsetof(XKeyEvent, y) == offsetof(XMotionEvent, y)); + assert(offsetof(XKeyEvent, y_root) == offsetof(XButtonEvent, y_root)); + assert(offsetof(XKeyEvent, y_root) == offsetof(XCrossingEvent, y_root)); + assert(offsetof(XKeyEvent, y_root) == offsetof(XMotionEvent, y_root)); /* * Initialize the static data structures used by the binding package. They @@ -1621,7 +1635,7 @@ Tk_CreateBinding( ClientData object, /* Token for object with which binding is associated. */ const char *eventString, /* String describing event sequence that triggers binding. */ const char *script, /* Contains Tcl script to execute when binding triggers. */ - int append) /* 0 means replace any existing binding for eventString; + int append) /* 0 means replace any existing binding for eventString; * 1 means append to that binding. If the existing binding is * for a callback function and not a Tcl command string, the * existing binding will always be replaced. */ @@ -4026,6 +4040,9 @@ HandleEventGenerate( return TCL_ERROR; } if (flags & BUTTON) { + if (number >= Button4) { + number += (Button8 - Button4); + } event.general.xbutton.button = number; } else { badOpt = 1; @@ -4401,10 +4418,19 @@ HandleEventGenerate( dispPtr->warpX = event.general.xmotion.x; dispPtr->warpY = event.general.xmotion.y; - if (!(dispPtr->flags & TK_DISPLAY_IN_WARP)) { - Tcl_DoWhenIdle(DoWarp, dispPtr); - dispPtr->flags |= TK_DISPLAY_IN_WARP; - } + /* + * Warping with respect to a window will be done when Tk_handleEvent + * below will run the event handlers and in particular TkPointerEvent. + * This allows to make grabs and warping work together robustly, that + * is without depending on a precise sequence of events. + * Warping with respect to the whole screen (i.e. dispPtr->warpWindow + * is NULL) is run directly here. + */ + + if (!dispPtr->warpWindow) { + TkpWarpPointer(dispPtr); + XForceScreenSaver(dispPtr->display, ScreenSaverReset); + } } /* @@ -4488,46 +4514,47 @@ NameToWindow( /* *------------------------------------------------------------------------- * - * DoWarp -- + * TkDoWarpWrtWin -- * - * Perform Warping of X pointer. Executed as an idle handler only. + * Perform warping of mouse pointer with respect to a window. * * Results: * None * * Side effects: - * X Pointer will move to a new location. + * Mouse pointer moves to a new location. * *------------------------------------------------------------------------- */ -static void -DoWarp( - ClientData clientData) +void +TkDoWarpWrtWin( + TkDisplay *dispPtr) { - TkDisplay *dispPtr = clientData; - - assert(clientData); + assert(dispPtr); /* - * DoWarp was scheduled only if the window was mapped. It needs to be - * still mapped at the time the present idle callback is executed. Also - * one needs to guard against window destruction in the meantime. - * Finally, the case warpWindow == NULL is special in that it means - * the whole screen. + * A NULL warpWindow means warping with respect to the whole screen. + * We want to warp here only if we're warping with respect to a window. */ - if (!dispPtr->warpWindow || - (Tk_IsMapped(dispPtr->warpWindow) && Tk_WindowId(dispPtr->warpWindow) != None)) { - TkpWarpPointer(dispPtr); - XForceScreenSaver(dispPtr->display, ScreenSaverReset); - } - if (dispPtr->warpWindow) { - Tcl_Release(dispPtr->warpWindow); - dispPtr->warpWindow = NULL; + + /* + * Warping with respect to a window can only be done if the window is + * mapped. This was checked in HandleEvent. The window needs to be + * still mapped at the time the present code is executed. Also + * one needs to guard against window destruction in the meantime, + * which could have happened as a side effect of an event handler. + */ + + if (Tk_IsMapped(dispPtr->warpWindow) && Tk_WindowId(dispPtr->warpWindow) != None) { + TkpWarpPointer(dispPtr); + XForceScreenSaver(dispPtr->display, ScreenSaverReset); + } + Tcl_Release(dispPtr->warpWindow); + dispPtr->warpWindow = NULL; } - dispPtr->flags &= ~TK_DISPLAY_IN_WARP; } /* @@ -4610,7 +4637,7 @@ FindSequence( * associated. For virtual event table, NULL. */ const char *eventString, /* String description of pattern to match on. See user * documentation for details. */ - int create, /* 0 means don't create the entry if it doesn't already exist. + int create, /* 0 means don't create the entry if it doesn't already exist. * 1 means create. */ int allowVirtual, /* 0 means that virtual events are not allowed in the sequence. * 1 otherwise. */ @@ -4979,7 +5006,7 @@ ParseEventDescription( "NON_BUTTON"); } #if SUPPORT_ADDITIONAL_MOTION_SYNTAX - patPtr->modMask |= TkGetButtonMask(button); + patPtr->modMask |= Tk_GetButtonMask(button); p = SkipFieldDelims(p); while (*p && *p != '>') { p = SkipFieldDelims(GetField(p, field, sizeof(field))); @@ -4989,7 +5016,7 @@ ParseEventDescription( patPtr, 0, Tcl_ObjPrintf("bad button number \"%s\"", field), "BUTTON"); } - patPtr->modMask |= TkGetButtonMask(button); + patPtr->modMask |= Tk_GetButtonMask(button); } patPtr->info = ButtonNumberFromState(patPtr->modMask); #endif @@ -5167,16 +5194,16 @@ GetPatternObj( } case ButtonPress: case ButtonRelease: - assert(patPtr->info <= Button5); - Tcl_AppendPrintfToObj(patternObj, "-%u", (unsigned) patPtr->info); + assert(patPtr->info <= 13); + Tcl_AppendPrintfToObj(patternObj, "-%u", (unsigned) ((patPtr->info > 7) ? (patPtr->info - 4) : patPtr->info)); break; #if PRINT_SHORT_MOTION_SYNTAX case MotionNotify: { unsigned mask = patPtr->modMask; while (mask & ALL_BUTTONS) { unsigned button = ButtonNumberFromState(mask); - Tcl_AppendPrintfToObj(patternObj, "-%u", button); - mask &= ~TkGetButtonMask(button); + Tcl_AppendPrintfToObj(patternObj, "-%u", (button > 7) ? (button - 4) : button); + mask &= ~Tk_GetButtonMask(button); } break; } @@ -5298,35 +5325,6 @@ TkpGetBindingXEvent( /* *---------------------------------------------------------------------- * - * TkpCancelWarp -- - * - * This function cancels an outstanding pointer warp and - * is called during tear down of the display. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkpCancelWarp( - TkDisplay *dispPtr) -{ - assert(dispPtr); - - if (dispPtr->flags & TK_DISPLAY_IN_WARP) { - Tcl_CancelIdleCall(DoWarp, dispPtr); - dispPtr->flags &= ~TK_DISPLAY_IN_WARP; - } -} - -/* - *---------------------------------------------------------------------- - * * TkpDumpPS -- * * Dump given pattern sequence to stdout. |