summaryrefslogtreecommitdiffstats
path: root/generic/tkPointer.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkPointer.c')
-rw-r--r--generic/tkPointer.c168
1 files changed, 94 insertions, 74 deletions
diff --git a/generic/tkPointer.c b/generic/tkPointer.c
index 4b18d0b..d14074d 100644
--- a/generic/tkPointer.c
+++ b/generic/tkPointer.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: tkPointer.c,v 1.3 1999/03/10 07:04:43 stanton Exp $
+ * RCS: @(#) $Id: tkPointer.c,v 1.4 1999/04/16 01:51:21 stanton Exp $
*/
#include "tkInt.h"
@@ -36,19 +36,18 @@ static unsigned int buttonMasks[] = {
};
#define ButtonMask(b) (buttonMasks[(b)-Button1])
-/*
- * Declarations of static variables used in the pointer module.
- */
-
-static TkWindow *cursorWinPtr = NULL; /* Window that is currently
- * controlling the global cursor. */
-static TkWindow *grabWinPtr = NULL; /* Window that defines the top of the
+typedef struct ThreadSpecificData {
+ TkWindow *grabWinPtr; /* Window that defines the top of the
* grab tree in a global grab. */
-static XPoint lastPos = { 0, 0}; /* Last reported mouse position. */
-static int lastState = 0; /* Last known state flags. */
-static TkWindow *lastWinPtr = NULL; /* Last reported mouse window. */
-static TkWindow *restrictWinPtr = NULL; /* Window to which all mouse events
+ int lastState; /* Last known state flags. */
+ XPoint lastPos; /* Last reported mouse position. */
+ TkWindow *lastWinPtr; /* Last reported mouse window. */
+ TkWindow *restrictWinPtr; /* Window to which all mouse events
* will be reported. */
+ TkWindow *cursorWinPtr; /* Window that is currently
+ * controlling the global cursor. */
+} ThreadSpecificData;
+static Tcl_ThreadDataKey dataKey;
/*
* Forward declarations of procedures used in this file.
@@ -141,8 +140,12 @@ GenerateEnterLeave(winPtr, x, y, state)
int state; /* State flags. */
{
int crossed = 0; /* 1 if mouse crossed a window boundary */
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ TkWindow *restrictWinPtr = tsdPtr->restrictWinPtr;
+ TkWindow *lastWinPtr = tsdPtr->lastWinPtr;
- if (winPtr != lastWinPtr) {
+ if (winPtr != tsdPtr->lastWinPtr) {
if (restrictWinPtr) {
int newPos, oldPos;
@@ -200,7 +203,7 @@ GenerateEnterLeave(winPtr, x, y, state)
crossed = 1;
}
}
- lastWinPtr = winPtr;
+ tsdPtr->lastWinPtr = winPtr;
}
return crossed;
@@ -230,11 +233,13 @@ Tk_UpdatePointer(tkwin, x, y, state)
int x, y; /* Pointer location in root coords. */
int state; /* Modifier state mask. */
{
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
TkWindow *winPtr = (TkWindow *)tkwin;
TkWindow *targetWinPtr;
XPoint pos;
XEvent event;
- int changes = (state ^ lastState) & ALL_BUTTONS;
+ int changes = (state ^ tsdPtr->lastState) & ALL_BUTTONS;
int type, b, mask;
pos.x = x;
@@ -245,7 +250,8 @@ Tk_UpdatePointer(tkwin, x, y, state)
* state since we haven't generated the button events yet.
*/
- lastState = (state & ~ALL_BUTTONS) | (lastState & ALL_BUTTONS);
+ tsdPtr->lastState = (state & ~ALL_BUTTONS) | (tsdPtr->lastState
+ & ALL_BUTTONS);
/*
* Generate Enter/Leave events. If the pointer has crossed window
@@ -253,8 +259,8 @@ Tk_UpdatePointer(tkwin, x, y, state)
* redundant motion events.
*/
- if (GenerateEnterLeave(winPtr, x, y, lastState)) {
- lastPos = pos;
+ if (GenerateEnterLeave(winPtr, x, y, tsdPtr->lastState)) {
+ tsdPtr->lastPos = pos;
}
/*
@@ -273,30 +279,30 @@ Tk_UpdatePointer(tkwin, x, y, state)
* if this is the first button down.
*/
- if (!restrictWinPtr) {
- if (!grabWinPtr) {
+ if (!tsdPtr->restrictWinPtr) {
+ if (!tsdPtr->grabWinPtr) {
/*
* Mouse is not grabbed, so set a button grab.
*/
- restrictWinPtr = winPtr;
- TkpSetCapture(restrictWinPtr);
+ tsdPtr->restrictWinPtr = winPtr;
+ TkpSetCapture(tsdPtr->restrictWinPtr);
- } else if ((lastState & ALL_BUTTONS) == 0) {
+ } else if ((tsdPtr->lastState & ALL_BUTTONS) == 0) {
/*
* Mouse is in a non-button grab, so ensure
* the button grab is inside the grab tree.
*/
- if (TkPositionInTree(winPtr, grabWinPtr)
+ if (TkPositionInTree(winPtr, tsdPtr->grabWinPtr)
== TK_GRAB_IN_TREE) {
- restrictWinPtr = winPtr;
+ tsdPtr->restrictWinPtr = winPtr;
} else {
- restrictWinPtr = grabWinPtr;
+ tsdPtr->restrictWinPtr = tsdPtr->grabWinPtr;
}
- TkpSetCapture(restrictWinPtr);
+ TkpSetCapture(tsdPtr->restrictWinPtr);
}
}
@@ -309,8 +315,8 @@ Tk_UpdatePointer(tkwin, x, y, state)
* aren't in a global grab.
*/
- if ((lastState & ALL_BUTTONS) == mask) {
- if (!grabWinPtr) {
+ if ((tsdPtr->lastState & ALL_BUTTONS) == mask) {
+ if (!tsdPtr->grabWinPtr) {
TkpSetCapture(NULL);
}
}
@@ -321,16 +327,16 @@ Tk_UpdatePointer(tkwin, x, y, state)
* the restrict window to the current mouse position.
*/
- if (restrictWinPtr) {
- InitializeEvent(&event, restrictWinPtr, type, x, y,
- lastState, b);
+ if (tsdPtr->restrictWinPtr) {
+ InitializeEvent(&event, tsdPtr->restrictWinPtr, type, x, y,
+ tsdPtr->lastState, b);
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
- lastState &= ~mask;
- lastWinPtr = restrictWinPtr;
- restrictWinPtr = NULL;
+ tsdPtr->lastState &= ~mask;
+ tsdPtr->lastWinPtr = tsdPtr->restrictWinPtr;
+ tsdPtr->restrictWinPtr = NULL;
- GenerateEnterLeave(winPtr, x, y, lastState);
- lastPos = pos;
+ GenerateEnterLeave(winPtr, x, y, tsdPtr->lastState);
+ tsdPtr->lastPos = pos;
continue;
}
}
@@ -342,10 +348,10 @@ Tk_UpdatePointer(tkwin, x, y, state)
* managed by Tk should be reported to the grab window.
*/
- if (restrictWinPtr) {
- targetWinPtr = restrictWinPtr;
- } else if (grabWinPtr && !winPtr) {
- targetWinPtr = grabWinPtr;
+ if (tsdPtr->restrictWinPtr) {
+ targetWinPtr = tsdPtr->restrictWinPtr;
+ } else if (tsdPtr->grabWinPtr && !winPtr) {
+ targetWinPtr = tsdPtr->grabWinPtr;
} else {
targetWinPtr = winPtr;
}
@@ -356,7 +362,7 @@ Tk_UpdatePointer(tkwin, x, y, state)
if (winPtr != NULL) {
InitializeEvent(&event, targetWinPtr, type, x, y,
- lastState, b);
+ tsdPtr->lastState, b);
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
}
@@ -364,9 +370,9 @@ Tk_UpdatePointer(tkwin, x, y, state)
* Update the state for the next iteration.
*/
- lastState = (type == ButtonPress)
- ? (lastState | mask) : (lastState & ~mask);
- lastPos = pos;
+ tsdPtr->lastState = (type == ButtonPress)
+ ? (tsdPtr->lastState | mask) : (tsdPtr->lastState & ~mask);
+ tsdPtr->lastPos = pos;
}
}
@@ -374,11 +380,11 @@ Tk_UpdatePointer(tkwin, x, y, state)
* Make sure the cursor window is up to date.
*/
- if (restrictWinPtr) {
- targetWinPtr = restrictWinPtr;
- } else if (grabWinPtr) {
- targetWinPtr = (TkPositionInTree(winPtr, grabWinPtr)
- == TK_GRAB_IN_TREE) ? winPtr : grabWinPtr;
+ if (tsdPtr->restrictWinPtr) {
+ targetWinPtr = tsdPtr->restrictWinPtr;
+ } else if (tsdPtr->grabWinPtr) {
+ targetWinPtr = (TkPositionInTree(winPtr, tsdPtr->grabWinPtr)
+ == TK_GRAB_IN_TREE) ? winPtr : tsdPtr->grabWinPtr;
} else {
targetWinPtr = winPtr;
}
@@ -389,19 +395,19 @@ Tk_UpdatePointer(tkwin, x, y, state)
* generate a motion event.
*/
- if (lastPos.x != pos.x || lastPos.y != pos.y) {
- if (restrictWinPtr) {
- targetWinPtr = restrictWinPtr;
- } else if (grabWinPtr && !winPtr) {
- targetWinPtr = grabWinPtr;
+ if (tsdPtr->lastPos.x != pos.x || tsdPtr->lastPos.y != pos.y) {
+ if (tsdPtr->restrictWinPtr) {
+ targetWinPtr = tsdPtr->restrictWinPtr;
+ } else if (tsdPtr->grabWinPtr && !winPtr) {
+ targetWinPtr = tsdPtr->grabWinPtr;
}
if (targetWinPtr != NULL) {
InitializeEvent(&event, targetWinPtr, MotionNotify, x, y,
- lastState, NotifyNormal);
+ tsdPtr->lastState, NotifyNormal);
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
}
- lastPos = pos;
+ tsdPtr->lastPos = pos;
}
}
@@ -437,12 +443,16 @@ XGrabPointer(display, grab_window, owner_events, event_mask, pointer_mode,
Cursor cursor;
Time time;
{
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
display->request++;
- grabWinPtr = (TkWindow *) Tk_IdToWindow(display, grab_window);
- restrictWinPtr = NULL;
- TkpSetCapture(grabWinPtr);
- if (TkPositionInTree(lastWinPtr, grabWinPtr) != TK_GRAB_IN_TREE) {
- UpdateCursor(grabWinPtr);
+ tsdPtr->grabWinPtr = (TkWindow *) Tk_IdToWindow(display, grab_window);
+ tsdPtr->restrictWinPtr = NULL;
+ TkpSetCapture(tsdPtr->grabWinPtr);
+ if (TkPositionInTree(tsdPtr->lastWinPtr, tsdPtr->grabWinPtr)
+ != TK_GRAB_IN_TREE) {
+ UpdateCursor(tsdPtr->grabWinPtr);
}
return GrabSuccess;
}
@@ -468,11 +478,14 @@ XUngrabPointer(display, time)
Display* display;
Time time;
{
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
display->request++;
- grabWinPtr = NULL;
- restrictWinPtr = NULL;
+ tsdPtr->grabWinPtr = NULL;
+ tsdPtr->restrictWinPtr = NULL;
TkpSetCapture(NULL);
- UpdateCursor(lastWinPtr);
+ UpdateCursor(tsdPtr->lastWinPtr);
}
/*
@@ -495,16 +508,19 @@ void
TkPointerDeadWindow(winPtr)
TkWindow *winPtr;
{
- if (winPtr == lastWinPtr) {
- lastWinPtr = NULL;
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+ if (winPtr == tsdPtr->lastWinPtr) {
+ tsdPtr->lastWinPtr = NULL;
}
- if (winPtr == grabWinPtr) {
- grabWinPtr = NULL;
+ if (winPtr == tsdPtr->grabWinPtr) {
+ tsdPtr->grabWinPtr = NULL;
}
- if (winPtr == restrictWinPtr) {
- restrictWinPtr = NULL;
+ if (winPtr == tsdPtr->restrictWinPtr) {
+ tsdPtr->restrictWinPtr = NULL;
}
- if (!(restrictWinPtr || grabWinPtr)) {
+ if (!(tsdPtr->restrictWinPtr || tsdPtr->grabWinPtr)) {
TkpSetCapture(NULL);
}
}
@@ -531,6 +547,8 @@ UpdateCursor(winPtr)
TkWindow *winPtr;
{
Cursor cursor = None;
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
* A window inherits its cursor from its parent if it doesn't
@@ -538,7 +556,7 @@ UpdateCursor(winPtr)
* cursor.
*/
- cursorWinPtr = winPtr;
+ tsdPtr->cursorWinPtr = winPtr;
while (winPtr != NULL) {
if (winPtr->atts.cursor != None) {
cursor = winPtr->atts.cursor;
@@ -577,8 +595,10 @@ XDefineCursor(display, w, cursor)
Cursor cursor;
{
TkWindow *winPtr = (TkWindow *)Tk_IdToWindow(display, w);
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- if (cursorWinPtr == winPtr) {
+ if (tsdPtr->cursorWinPtr == winPtr) {
UpdateCursor(winPtr);
}
display->request++;