summaryrefslogtreecommitdiffstats
path: root/generic/tkBind.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkBind.c')
-rw-r--r--generic/tkBind.c290
1 files changed, 160 insertions, 130 deletions
diff --git a/generic/tkBind.c b/generic/tkBind.c
index e8827b3..3416f52 100644
--- a/generic/tkBind.c
+++ b/generic/tkBind.c
@@ -59,7 +59,9 @@
/*
* In old implementation (the one that used an event ring), <Double-1> and <1><1> were
- * equivalent sequences. However it is logical to give <Double-1> higher precedence.
+ * 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 is achieved by setting PREFER_MOST_SPECIALIZED_EVENT to 1.
*/
@@ -135,17 +137,10 @@ typedef struct {
* this count considers the detail (keySym or button). */
} Event;
-/*
- * We need a structure providing a list of pattern sequences.
- */
-
-typedef unsigned EventMask;
-typedef unsigned long ModMask;
-
struct PatSeq; /* forward declaration */
/* We need this array for bookkeeping the last matching modifier mask per pattern. */
-TK_ARRAY_DEFINE(PSModMaskArr, ModMask);
+TK_ARRAY_DEFINE(PSModMaskArr, unsigned);
typedef struct PSEntry {
TK_DLIST_LINKS(PSEntry); /* Makes this struct a double linked list; must be first entry. */
@@ -201,7 +196,7 @@ typedef struct Tk_BindingTable_ {
/* Containing the most recent event for every event type. */
PromArr *promArr; /* Contains the promoted pattern sequences. */
Event *curEvent; /* Pointing to most recent event. */
- ModMask curModMask; /* Containing the current modifier mask. */
+ unsigned curModMask; /* Containing the current modifier mask. */
LookupTables lookupTables; /* Containing hash tables for fast lookup. */
Tcl_HashTable objectTable; /* Used to map from an object to a list of patterns associated with
* that object. Keys are ClientData, values are (PatSeq *). */
@@ -263,7 +258,7 @@ typedef struct {
typedef struct {
unsigned eventType; /* Type of X event, e.g. ButtonPress. */
unsigned count; /* Multi-event count, e.g. double-clicks, triple-clicks, etc. */
- ModMask modMask; /* Mask of modifiers that must be present (zero means no modifiers
+ unsigned modMask; /* Mask of modifiers that must be present (zero means no modifiers
* are required). */
Info info; /* Additional information that must match event. Normally this is zero,
* meaning no additional information must match. For KeyPress and
@@ -414,7 +409,7 @@ static Tcl_HashTable nameTable; /* keyArray hashed by keysym name. */
typedef struct {
const char *name; /* Name of modifier. */
- ModMask mask; /* Button/modifier mask value, such as Button1Mask. */
+ unsigned mask; /* Button/modifier mask value, such as Button1Mask. */
unsigned flags; /* Various flags; see below for definitions. */
} ModInfo;
@@ -460,10 +455,20 @@ static const ModInfo modArray[] = {
{"Button9", Button9Mask, 0},
{"Mod1", Mod1Mask, 0},
{"M1", Mod1Mask, 0},
+#ifdef MAC_OSX_TK
{"Command", Mod1Mask, 0},
+#elif defined (_WIN32)
+ {"Command", ControlMask, 0},
+#else
+ {"Command", META_MASK, 0},
+#endif
{"Mod2", Mod2Mask, 0},
{"M2", Mod2Mask, 0},
+#ifdef MAC_OSX_TK
{"Option", Mod2Mask, 0},
+#else
+ {"Option", ALT_MASK, 0},
+#endif
{"Mod3", Mod3Mask, 0},
{"M3", Mod3Mask, 0},
{"Mod4", Mod4Mask, 0},
@@ -719,7 +724,7 @@ static void ExpandPercents(TkWindow *winPtr, const char *before, Event *eventPt
unsigned scriptCount, Tcl_DString *dsPtr);
static PatSeq * FindSequence(Tcl_Interp *interp, LookupTables *lookupTables,
ClientData object, const char *eventString, int create,
- int allowVirtual, EventMask *maskPtr);
+ int allowVirtual, unsigned *maskPtr);
static void GetAllVirtualEvents(Tcl_Interp *interp, VirtualEventTable *vetPtr);
static const char * GetField(const char *p, char *copy, unsigned size);
static Tcl_Obj * GetPatternObj(const PatSeq *psPtr);
@@ -735,8 +740,7 @@ static PatSeq * MatchPatterns(TkDisplay *dispPtr, Tk_BindingTable bindPtr, PSLi
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, EventMask *eventMaskPtr);
-static void DoWarp(ClientData clientData);
+ TkPattern *patPtr, unsigned *eventMaskPtr);
static PSList * GetLookupForEvent(LookupTables* lookupPtr, const Event *eventPtr,
Tcl_Obj *object, int onlyConsiderDetailedEvents);
static void ClearLookupTable(LookupTables *lookupTables, ClientData object);
@@ -767,8 +771,8 @@ static int TestNearbyCoords(int lhs, int rhs) { return Abs(lhs - rhs) <= NEARBY_
static int
IsSubsetOf(
- ModMask lhsMask, /* this is a subset */
- ModMask rhsMask) /* of this bit field? */
+ unsigned lhsMask, /* this is a subset */
+ unsigned rhsMask) /* of this bit field? */
{
return (lhsMask & rhsMask) == lhsMask;
}
@@ -798,8 +802,10 @@ static unsigned
GetButtonNumber(
const char *field)
{
+ unsigned button;
assert(field);
- return (field[0] >= '1' && field[0] <= '9' && 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
@@ -854,6 +860,20 @@ CountSpecialized(
return sndCount - fstCount;
}
+int
+IsKeyEventType(
+ unsigned eventType)
+{
+ return eventType == KeyPress || eventType == KeyRelease;
+}
+
+int
+IsButtonEventType(
+ unsigned eventType)
+{
+ return eventType == ButtonPress || eventType == ButtonRelease;
+}
+
static int
MatchEventNearby(
const XEvent *lhs, /* previous button event */
@@ -861,7 +881,7 @@ MatchEventNearby(
{
assert(lhs);
assert(rhs);
- assert(lhs->type == ButtonPress || lhs->type == ButtonRelease);
+ assert(IsButtonEventType(lhs->type));
assert(lhs->type == rhs->type);
/* assert: lhs->xbutton.time <= rhs->xbutton.time */
@@ -873,16 +893,16 @@ MatchEventNearby(
static int
MatchEventRepeat(
- const XEvent *lhs, /* previous key event */
- const XEvent *rhs) /* current key event */
+ const XKeyEvent *lhs, /* previous key event */
+ const XKeyEvent *rhs) /* current key event */
{
assert(lhs);
assert(rhs);
- assert(lhs->type == KeyPress || lhs->type == KeyRelease);
+ assert(IsKeyEventType(lhs->type));
assert(lhs->type == rhs->type);
- /* assert: lhs->xkey.time <= rhs->xkey.time */
- return TestNearbyTime(rhs->xkey.time, lhs->xkey.time);
+ /* assert: lhs->time <= rhs->time */
+ return lhs->keycode == rhs->keycode && TestNearbyTime(lhs->time, rhs->time);
}
static void
@@ -941,11 +961,10 @@ ClearList(
static PSEntry *
FreePatSeqEntry(
- PSList *pool,
+ TCL_UNUSED(PSList *),
PSEntry *entry)
{
PSEntry *next = PSList_Next(entry);
- (void)pool;
PSModMaskArr_Free(&entry->lastModMaskArr);
ckfree(entry);
@@ -961,13 +980,13 @@ ResolveModifiers(
if (dispPtr->metaModMask) {
if (modMask & META_MASK) {
- modMask &= ~(ModMask)META_MASK;
+ modMask &= ~META_MASK;
modMask |= dispPtr->metaModMask;
}
}
if (dispPtr->altModMask) {
if (modMask & ALT_MASK) {
- modMask &= ~(ModMask)ALT_MASK;
+ modMask &= ~ALT_MASK;
modMask |= dispPtr->altModMask;
}
}
@@ -977,7 +996,7 @@ ResolveModifiers(
static int
ButtonNumberFromState(
- ModMask state)
+ unsigned state)
{
if (!(state & ALL_BUTTONS)) { return 0; }
if (state & Button1Mask) { return 1; }
@@ -1632,7 +1651,7 @@ Tk_CreateBinding(
* existing binding will always be replaced. */
{
PatSeq *psPtr;
- EventMask eventMask;
+ unsigned eventMask;
char *oldStr;
char *newStr;
@@ -2157,7 +2176,7 @@ Tk_BindEvent(
TkDisplay *dispPtr;
TkDisplay *oldDispPtr;
Event *curEvent;
- TkWindow *winPtr = (TkWindow *) tkwin;
+ TkWindow *winPtr = (TkWindow *)tkwin;
BindInfo *bindInfoPtr;
Tcl_InterpState interpState;
LookupTables *physTables;
@@ -2213,7 +2232,7 @@ Tk_BindEvent(
* Ignore the event completely if it is an Enter, Leave, FocusIn, or
* FocusOut event with detail NotifyInferior. The reason for ignoring
* these events is that we don't want transitions between a window and its
- * children to visible to bindings on the parent: this would cause
+ * children to be visible to bindings on the parent: this would cause
* problems for mega-widgets, since the internal structure of a
* mega-widget isn't supposed to be visible to people watching the parent.
*
@@ -2297,7 +2316,7 @@ Tk_BindEvent(
switch (eventPtr->type) {
case KeyPress:
case KeyRelease:
- if (MatchEventRepeat(&curEvent->xev, eventPtr)) {
+ if (MatchEventRepeat(&curEvent->xev.xkey, &eventPtr->xkey)) {
if (curEvent->xev.xkey.keycode == eventPtr->xkey.keycode) {
++curEvent->countDetailed;
} else {
@@ -2447,7 +2466,6 @@ Tk_BindEvent(
LookupTables *virtTables = &bindInfoPtr->virtualEventTable.lookupTables;
PatSeq *matchPtr = matchPtrArr[k];
PatSeq *mPtr;
- PSList *psl[2];
/*
* Note that virtual events cannot promote.
@@ -2521,13 +2539,13 @@ Tk_BindEvent(
switch (patPtr->eventType) {
case ButtonPress:
case ButtonRelease:
- if (curEvent->xev.type == KeyPress || curEvent->xev.type == KeyRelease) {
+ if (IsKeyEventType(curEvent->xev.type)) {
RemoveListEntry(&bindPtr->lookupTables.entryPool, psEntry);
}
break;
case KeyPress:
case KeyRelease:
- if (curEvent->xev.type == ButtonPress || curEvent->xev.type == ButtonRelease) {
+ if (IsButtonEventType(curEvent->xev.type)) {
RemoveListEntry(&bindPtr->lookupTables.entryPool, psEntry);
}
break;
@@ -2725,8 +2743,8 @@ static int
CompareModMasks(
const PSModMaskArr *fstModMaskArr,
const PSModMaskArr *sndModMaskArr,
- ModMask fstModMask,
- ModMask sndModMask)
+ unsigned fstModMask,
+ unsigned sndModMask)
{
int fstCount = 0;
int sndCount = 0;
@@ -2750,11 +2768,11 @@ CompareModMasks(
assert(PSModMaskArr_Size(fstModMaskArr) == PSModMaskArr_Size(sndModMaskArr));
for (i = PSModMaskArr_Size(fstModMaskArr) - 1; i >= 0; --i) {
- ModMask fstModMask = *PSModMaskArr_Get(fstModMaskArr, i);
- ModMask sndModMask = *PSModMaskArr_Get(sndModMaskArr, i);
+ unsigned fstiModMask = *PSModMaskArr_Get(fstModMaskArr, i);
+ unsigned sndiModMask = *PSModMaskArr_Get(sndModMaskArr, i);
- if (IsSubsetOf(fstModMask, sndModMask)) { ++sndCount; }
- if (IsSubsetOf(sndModMask, fstModMask)) { ++fstCount; }
+ if (IsSubsetOf(fstiModMask, sndiModMask)) { ++sndCount; }
+ if (IsSubsetOf(sndiModMask, fstiModMask)) { ++fstCount; }
}
}
@@ -2784,8 +2802,9 @@ MatchPatterns(
PSEntry *psEntry;
PatSeq *bestPtr;
PatSeq *bestPhysPtr;
- ModMask bestModMask;
+ unsigned bestModMask;
const PSModMaskArr *bestModMaskArr = NULL;
+ int i, isModKeyOnly = 0;
assert(dispPtr);
assert(bindPtr);
@@ -2800,6 +2819,26 @@ MatchPatterns(
bestPhysPtr = NULL;
window = curEvent->xev.xany.window;
+ /*
+ * Modifier key events interlaced between patterns parts of a
+ * sequence shall not prevent a sequence from ultimately
+ * matching. Example: when trying to trigger <a><Control-c>
+ * from the keyboard, the sequence of events actually seen is
+ * <a> then <Control_L> (possibly repeating if the key is hold
+ * down), and finally <Control-c>. At the time <Control_L> is
+ * seen, we shall keep the <a><Control-c> pattern sequence in
+ * the promotion list, otherwise it is impossible to trigger
+ * it from the keyboard. See bug [16ef161925].
+ */
+ if (IsKeyEventType(curEvent->xev.type)) {
+ for (i = 0; i < dispPtr->numModKeyCodes; ++i) {
+ if (dispPtr->modKeyCodes[i] == curEvent->xev.xkey.keycode) {
+ isModKeyOnly = 1;
+ break;
+ }
+ }
+ }
+
for (psEntry = PSList_First(psList); psEntry; psEntry = PSList_Next(psEntry)) {
if (patIndex == 0 || psEntry->window == window) {
PatSeq* psPtr = psEntry->psPtr;
@@ -2814,6 +2853,12 @@ MatchPatterns(
: VirtPatIsBound(bindPtr, psPtr, object, physPtrPtr)) {
TkPattern *patPtr = psPtr->pats + patIndex;
+ /* ignore modifier key events, and KeyRelease events if the current event
+ * is of a different type (e.g. a Button event)
+ */
+ psEntry->keepIt = isModKeyOnly || \
+ ((patPtr->eventType != (unsigned) curEvent->xev.type) && curEvent->xev.type == KeyRelease);
+
if (patPtr->eventType == (unsigned) curEvent->xev.type
&& (curEvent->xev.type != CreateNotify
|| curEvent->xev.xcreatewindow.parent == window)
@@ -2824,12 +2869,13 @@ MatchPatterns(
* cannot be done in ParseEventDescription, otherwise this function would
* be the better place.
*/
- ModMask modMask = ResolveModifiers(dispPtr, patPtr->modMask);
- ModMask curModMask = ResolveModifiers(dispPtr, bindPtr->curModMask);
+ unsigned modMask = ResolveModifiers(dispPtr, patPtr->modMask);
+ unsigned curModMask = ResolveModifiers(dispPtr, bindPtr->curModMask);
psEntry->expired = 1; /* remove it from promotion list */
+ psEntry->keepIt = 0; /* don't keep matching patterns */
- if ((modMask & ~curModMask) == 0) {
+ if (IsSubsetOf(modMask, curModMask)) {
unsigned count = patPtr->info ? curEvent->countDetailed : curEvent->countAny;
if (patIndex < PSModMaskArr_Size(psEntry->lastModMaskArr)) {
@@ -3476,7 +3522,7 @@ DeleteVirtualEventTable(
* already defined, the new definition augments those that already exist.
*
* Results:
- * The return value is TCL_ERROR if an error occured while creating the
+ * The return value is TCL_ERROR if an error occurred while creating the
* virtual binding. In this case, an error message will be left in the
* interp's result. If all went well then the return value is TCL_OK.
*
@@ -3820,7 +3866,7 @@ HandleEventGenerate(
Tk_Window tkwin;
Tk_Window tkwin2;
TkWindow *mainPtr;
- EventMask eventMask;
+ unsigned eventMask;
Tcl_Obj *userDataObj;
int synch;
int warp;
@@ -4004,6 +4050,9 @@ HandleEventGenerate(
return TCL_ERROR;
}
if (flags & BUTTON) {
+ if (number >= Button4) {
+ number += (Button8 - Button4);
+ }
event.general.xbutton.button = number;
} else {
badOpt = 1;
@@ -4358,17 +4407,6 @@ HandleEventGenerate(
}
/*
- * Now we have constructed the event, inject it into the event handling
- * code.
- */
-
- if (synch) {
- Tk_HandleEvent(&event.general);
- } else {
- Tk_QueueWindowEvent(&event.general, pos);
- }
-
- /*
* We only allow warping if the window is mapped.
*/
@@ -4377,11 +4415,6 @@ HandleEventGenerate(
Tk_Window warpWindow = Tk_IdToWindow(dispPtr->display, event.general.xmotion.window);
- if (!(dispPtr->flags & TK_DISPLAY_IN_WARP)) {
- Tcl_DoWhenIdle(DoWarp, dispPtr);
- dispPtr->flags |= TK_DISPLAY_IN_WARP;
- }
-
if (warpWindow != dispPtr->warpWindow) {
if (warpWindow) {
Tcl_Preserve(warpWindow);
@@ -4394,6 +4427,31 @@ HandleEventGenerate(
dispPtr->warpMainwin = mainWin;
dispPtr->warpX = event.general.xmotion.x;
dispPtr->warpY = event.general.xmotion.y;
+
+ /*
+ * 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);
+ }
+ }
+
+ /*
+ * Now we have constructed the event, inject it into the event handling
+ * code.
+ */
+
+ if (synch) {
+ Tk_HandleEvent(&event.general);
+ } else {
+ Tk_QueueWindowEvent(&event.general, pos);
}
}
@@ -4466,46 +4524,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 = (TkDisplay *)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;
}
/*
@@ -4592,7 +4651,7 @@ FindSequence(
* 1 means create. */
int allowVirtual, /* 0 means that virtual events are not allowed in the sequence.
* 1 otherwise. */
- EventMask *maskPtr) /* *maskPtr is filled in with the event types on which this
+ unsigned *maskPtr) /* *maskPtr is filled in with the event types on which this
* pattern sequence depends. */
{
unsigned patsBufSize = 1;
@@ -4606,8 +4665,8 @@ FindSequence(
int isNew;
unsigned count;
unsigned maxCount = 0;
- EventMask eventMask = 0;
- ModMask modMask = 0;
+ unsigned eventMask = 0;
+ unsigned modMask = 0;
PatternTableKey key;
assert(lookupTables);
@@ -4781,10 +4840,10 @@ ParseEventDescription(
const char **eventStringPtr,/* On input, holds a pointer to start of event string. On exit,
* gets pointer to rest of string after parsed event. */
TkPattern *patPtr, /* Filled with the pattern parsed from the event string. */
- EventMask *eventMaskPtr) /* Filled with event mask of matched event. */
+ unsigned *eventMaskPtr) /* Filled with event mask of matched event. */
{
const char *p;
- EventMask eventMask = 0;
+ unsigned eventMask = 0;
unsigned count = 1;
assert(eventStringPtr);
@@ -4957,7 +5016,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)));
@@ -4967,7 +5026,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
@@ -5097,7 +5156,7 @@ GetPatternObj(
assert(patPtr->name);
Tcl_AppendPrintfToObj(patternObj, "<<%s>>", patPtr->name);
} else {
- ModMask modMask;
+ unsigned modMask;
const ModInfo *modPtr;
/*
@@ -5145,16 +5204,16 @@ GetPatternObj(
}
case ButtonPress:
case ButtonRelease:
- assert(patPtr->info <= Button9);
- Tcl_AppendPrintfToObj(patternObj, "-%d", (int) 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: {
- ModMask mask = patPtr->modMask;
+ unsigned mask = patPtr->modMask;
while (mask & ALL_BUTTONS) {
- int button = ButtonNumberFromState(mask);
- Tcl_AppendPrintfToObj(patternObj, "-%d", button);
- mask &= ~TkGetButtonMask(button);
+ unsigned button = ButtonNumberFromState(mask);
+ Tcl_AppendPrintfToObj(patternObj, "-%u", (button > 7) ? (button - 4) : button);
+ mask &= ~Tk_GetButtonMask(button);
}
break;
}
@@ -5276,35 +5335,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.