diff options
Diffstat (limited to 'generic/tkBind.c')
-rw-r--r-- | generic/tkBind.c | 112 |
1 files changed, 87 insertions, 25 deletions
diff --git a/generic/tkBind.c b/generic/tkBind.c index 192ea69..031ded7 100644 --- a/generic/tkBind.c +++ b/generic/tkBind.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkBind.c,v 1.8 1999/04/21 21:53:23 rjohnson Exp $ + * RCS: @(#) $Id: tkBind.c,v 1.9 1999/12/14 06:52:25 hobbs Exp $ */ #include "tkPort.h" @@ -403,10 +403,15 @@ typedef struct { * e.g. for double-clicks. * TRIPLE - Non-zero means triplicate this event, * e.g. for triple-clicks. + * QUADRUPLE - Non-zero means quadruple this event, + * e.g. for 4-fold-clicks. + * MULT_CLICKS - Combination of all of above. */ #define DOUBLE 1 #define TRIPLE 2 +#define QUADRUPLE 4 +#define MULT_CLICKS 7 /* * The following special modifier mask bits are defined, to indicate @@ -448,6 +453,7 @@ static ModInfo modArray[] = { {"M5", Mod5Mask, 0}, {"Double", 0, DOUBLE}, {"Triple", 0, TRIPLE}, + {"Quadruple", 0, QUADRUPLE}, {"Any", 0, 0}, /* Ignored: historical relic. */ {NULL, 0, 0} }; @@ -685,6 +691,7 @@ static int ParseEventDescription _ANSI_ARGS_((Tcl_Interp *interp, unsigned long *eventMaskPtr)); static void SetKeycodeAndState _ANSI_ARGS_((Tk_Window tkwin, KeySym keySym, XEvent *eventPtr)); +static void DoWarp _ANSI_ARGS_((ClientData clientData)); /* * The following define is used as a short circuit for the callback @@ -3170,8 +3177,8 @@ HandleEventGenerate(interp, mainWin, objc, objv) Tcl_Obj *CONST objv[]; /* Argument objects. */ { XEvent event; - char *name, *p; - int count, flags, synch, i, number; + char *name, *p, *windowName; + int count, flags, synch, i, number, warp; Tcl_QueuePosition pos; Pattern pat; Tk_Window tkwin, tkwin2; @@ -3184,8 +3191,8 @@ HandleEventGenerate(interp, mainWin, objc, objv) "-keycode", "-keysym", "-mode", "-override", "-place", "-root", "-rootx", "-rooty", "-sendevent", "-serial", "-state", "-subwindow", - "-time", "-width", "-window", "-x", - "-y", NULL + "-time", "-warp", "-width", "-window", + "-x", "-y", NULL }; enum field { EVENT_WHEN, EVENT_ABOVE, EVENT_BORDER, EVENT_BUTTON, @@ -3194,11 +3201,14 @@ HandleEventGenerate(interp, mainWin, objc, objv) EVENT_KEYCODE, EVENT_KEYSYM, EVENT_MODE, EVENT_OVERRIDE, EVENT_PLACE, EVENT_ROOT, EVENT_ROOTX, EVENT_ROOTY, EVENT_SEND, EVENT_SERIAL, EVENT_STATE, EVENT_SUBWINDOW, - EVENT_TIME, EVENT_WIDTH, EVENT_WINDOW, EVENT_X, - EVENT_Y + EVENT_TIME, EVENT_WARP, EVENT_WIDTH, EVENT_WINDOW, + EVENT_X, EVENT_Y }; - if (NameToWindow(interp, mainWin, objv[0], &tkwin) != TCL_OK) { + windowName = Tcl_GetStringFromObj(objv[0], NULL); + if (!windowName[0]) { + tkwin = mainWin; + } else if (NameToWindow(interp, mainWin, objv[0], &tkwin) != TCL_OK) { return TCL_ERROR; } @@ -3236,7 +3246,11 @@ HandleEventGenerate(interp, mainWin, objc, objv) event.xany.type = pat.eventType; event.xany.serial = NextRequest(Tk_Display(tkwin)); event.xany.send_event = False; - event.xany.window = Tk_WindowId(tkwin); + if (windowName[0]) { + event.xany.window = Tk_WindowId(tkwin); + } else { + event.xany.window = RootWindow(Tk_Display(tkwin), Tk_ScreenNumber(tkwin)); + } event.xany.display = Tk_Display(tkwin); flags = flagArray[event.xany.type]; @@ -3260,6 +3274,7 @@ HandleEventGenerate(interp, mainWin, objc, objv) */ synch = 1; + warp = 0; pos = TCL_QUEUE_TAIL; for (i = 2; i < objc; i += 2) { Tcl_Obj *optionPtr, *valuePtr; @@ -3287,6 +3302,15 @@ HandleEventGenerate(interp, mainWin, objc, objv) } switch ((enum field) index) { + case EVENT_WARP: { + if (Tcl_GetBooleanFromObj(interp, valuePtr, &warp) != TCL_OK) { + return TCL_ERROR; + } + if (!(flags & (KEY_BUTTON_MOTION_VIRTUAL))) { + goto badopt; + } + break; + } case EVENT_WHEN: { pos = (Tcl_QueuePosition) TkFindStateNumObj(interp, optionPtr, queuePosition, valuePtr); @@ -3667,6 +3691,17 @@ HandleEventGenerate(interp, mainWin, objc, objv) } else { Tk_QueueWindowEvent(&event, pos); } + if (warp != 0) { + TkDisplay *dispPtr; + dispPtr = TkGetDisplay(event.xmotion.display); + if (!dispPtr->warpInProgress) { + Tcl_DoWhenIdle(DoWarp, (ClientData) dispPtr); + dispPtr->warpInProgress = 1; + } + dispPtr->warpWindow = event.xany.window; + dispPtr->warpX = event.xkey.x; + dispPtr->warpY = event.xkey.y; + } Tcl_ResetResult(interp); return TCL_OK; @@ -3747,6 +3782,33 @@ SetKeycodeAndState(tkwin, keySym, eventPtr) /* *------------------------------------------------------------------------- * + * DoWarp -- + * + * Perform Warping of X pointer. Executed as an idle handler only. + * + * Results: + * None + * + * Side effects: + * X Pointer will move to a new location. + * + *------------------------------------------------------------------------- + */ +static void +DoWarp(clientData) + ClientData clientData; +{ + TkDisplay *dispPtr = (TkDisplay *) clientData; + + XWarpPointer(dispPtr->display, (Window) None, (Window) dispPtr->warpWindow, + 0, 0, 0, 0, (int) dispPtr->warpX, (int) dispPtr->warpY); + XForceScreenSaver(dispPtr->display, ScreenSaverReset); + dispPtr->warpInProgress = 0; +} + +/* + *------------------------------------------------------------------------- + * * GetVirtualEventUid -- * * Determine if the given string is in the proper format for a @@ -3886,19 +3948,14 @@ FindSequence(interp, patternTablePtr, object, eventString, create, } /* - * Replicate events for DOUBLE and TRIPLE. + * Replicate events for DOUBLE, TRIPLE, QUADRUPLE. */ - if ((count > 1) && (numPats < EVENT_BUFFER_SIZE-1)) { + while ((count-- > 1) && (numPats < EVENT_BUFFER_SIZE-1)) { flags |= PAT_NEARBY; patPtr[-1] = patPtr[0]; patPtr--; numPats++; - if ((count == 3) && (numPats < EVENT_BUFFER_SIZE-1)) { - patPtr[-1] = patPtr[0]; - patPtr--; - numPats++; - } } } @@ -4117,12 +4174,10 @@ ParseEventDescription(interp, eventStringPtr, patPtr, } modPtr = (ModInfo *) Tcl_GetHashValue(hPtr); patPtr->needMods |= modPtr->mask; - if (modPtr->flags & (DOUBLE|TRIPLE)) { - if (modPtr->flags & DOUBLE) { - count = 2; - } else { - count = 3; - } + if (modPtr->flags & (MULT_CLICKS)) { + int i = modPtr->flags & MULT_CLICKS; + count = 2; + while (i >>= 1) count++; } while ((*p == '-') || isspace(UCHAR(*p))) { p++; @@ -4310,8 +4365,8 @@ GetPatternString(psPtr, dsPtr) /* * It's a more general event specification. First check - * for "Double" or "Triple", then modifiers, then event type, - * then keysym or button detail. + * for "Double", "Triple", "Quadruple", then modifiers, + * then event type, then keysym or button detail. */ Tcl_DStringAppend(dsPtr, "<", 1); @@ -4324,7 +4379,14 @@ GetPatternString(psPtr, dsPtr) (char *) (patPtr-1), sizeof(Pattern)) == 0)) { patsLeft--; patPtr--; - Tcl_DStringAppend(dsPtr, "Triple-", 7); + if ((patsLeft > 1) && (memcmp((char *) patPtr, + (char *) (patPtr-1), sizeof(Pattern)) == 0)) { + patsLeft--; + patPtr--; + Tcl_DStringAppend(dsPtr, "Quadruple-", 10); + } else { + Tcl_DStringAppend(dsPtr, "Triple-", 7); + } } else { Tcl_DStringAppend(dsPtr, "Double-", 7); } |