diff options
Diffstat (limited to 'generic/tkEvent.c')
-rw-r--r-- | generic/tkEvent.c | 145 |
1 files changed, 103 insertions, 42 deletions
diff --git a/generic/tkEvent.c b/generic/tkEvent.c index 6403001..a72be72 100644 --- a/generic/tkEvent.c +++ b/generic/tkEvent.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: tkEvent.c,v 1.3 1998/10/10 00:30:36 rjohnson Exp $ + * RCS: @(#) $Id: tkEvent.c,v 1.4 1999/04/16 01:51:13 stanton Exp $ */ #include "tkPort.h" @@ -39,10 +39,6 @@ typedef struct InProgress { struct InProgress *nextPtr; /* Next higher nested search. */ } InProgress; -static InProgress *pendingPtr = NULL; - /* Topmost search in progress, or - * NULL if none. */ - /* * For each call to Tk_CreateGenericHandler, an instance of the following * structure will be created. All of the active handlers are linked into a @@ -58,11 +54,6 @@ typedef struct GenericHandler { * handlers, or NULL for end of list. */ } GenericHandler; -static GenericHandler *genericList = NULL; - /* First handler in the list, or NULL. */ -static GenericHandler *lastGenericPtr = NULL; - /* Last handler in list. */ - /* * There's a potential problem if Tk_HandleEvent is entered recursively. * A handler cannot be deleted physically until we have returned from @@ -70,11 +61,8 @@ static GenericHandler *lastGenericPtr = NULL; * its `next' entry. We deal with the problem by using the `delete flag' and * deleting handlers only when it's known that there's no handler active. * - * The following variable has a non-zero value when a handler is active. */ -static int genericHandlersActive = 0; - /* * The following structure is used for queueing X-style events on the * Tcl event queue. @@ -134,15 +122,37 @@ static unsigned long eventMasks[TK_LASTEVENT] = { MouseWheelMask /* MouseWheelEvent */ }; + /* - * If someone has called Tk_RestrictEvents, the information below - * keeps track of it. + * The structure below is used to store Data for the Event module that + * must be kept thread-local. The "dataKey" is used to fetch the + * thread-specific storage for the current thread. */ -static Tk_RestrictProc *restrictProc; +typedef struct ThreadSpecificData { + + int genericHandlersActive; + /* The following variable has a non-zero + * value when a handler is active. */ + InProgress *pendingPtr; + /* Topmost search in progress, or + * NULL if none. */ + GenericHandler *genericList; + /* First handler in the list, or NULL. */ + GenericHandler *lastGenericPtr; + /* Last handler in list. */ + + /* + * If someone has called Tk_RestrictEvents, the information below + * keeps track of it. + */ + + Tk_RestrictProc *restrictProc; /* Procedure to call. NULL means no * restrictProc is currently in effect. */ -static ClientData restrictArg; /* Argument to pass to restrictProc. */ + ClientData restrictArg; /* Argument to pass to restrictProc. */ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; /* * Prototypes for procedures that are only referenced locally within @@ -266,6 +276,8 @@ Tk_DeleteEventHandler(token, mask, proc, clientData) register InProgress *ipPtr; TkEventHandler *prevPtr; register TkWindow *winPtr = (TkWindow *) token; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * Find the event handler to be deleted, or return @@ -288,7 +300,7 @@ Tk_DeleteEventHandler(token, mask, proc, clientData) * process the next one instead. */ - for (ipPtr = pendingPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { + for (ipPtr = tsdPtr->pendingPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { if (ipPtr->nextHandler == handlerPtr) { ipPtr->nextHandler = handlerPtr->nextPtr; } @@ -337,6 +349,8 @@ Tk_CreateGenericHandler(proc, clientData) ClientData clientData; /* One-word value to pass to proc. */ { GenericHandler *handlerPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); handlerPtr = (GenericHandler *) ckalloc (sizeof (GenericHandler)); @@ -344,12 +358,12 @@ Tk_CreateGenericHandler(proc, clientData) handlerPtr->clientData = clientData; handlerPtr->deleteFlag = 0; handlerPtr->nextPtr = NULL; - if (genericList == NULL) { - genericList = handlerPtr; + if (tsdPtr->genericList == NULL) { + tsdPtr->genericList = handlerPtr; } else { - lastGenericPtr->nextPtr = handlerPtr; + tsdPtr->lastGenericPtr->nextPtr = handlerPtr; } - lastGenericPtr = handlerPtr; + tsdPtr->lastGenericPtr = handlerPtr; } /* @@ -377,8 +391,10 @@ Tk_DeleteGenericHandler(proc, clientData) ClientData clientData; { GenericHandler * handler; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - for (handler = genericList; handler; handler = handler->nextPtr) { + for (handler = tsdPtr->genericList; handler; handler = handler->nextPtr) { if ((handler->proc == proc) && (handler->clientData == clientData)) { handler->deleteFlag = 1; } @@ -388,6 +404,39 @@ Tk_DeleteGenericHandler(proc, clientData) /* *-------------------------------------------------------------- * + * TkEventInit -- + * + * This procedures initializes all the event module + * structures used by the current thread. It must be + * called before any other procedure in this file is + * called. + * + * Results: + * None. + * + * Side Effects: + * None. + * + *-------------------------------------------------------------- + */ + +void +TkEventInit(void) +{ + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + tsdPtr->genericHandlersActive = 0; + tsdPtr->pendingPtr = NULL; + tsdPtr->genericList = NULL; + tsdPtr->lastGenericPtr = NULL; + tsdPtr->restrictProc = NULL; + tsdPtr->restrictArg = NULL; +} + +/* + *-------------------------------------------------------------- + * * Tk_HandleEvent -- * * Given an event, invoke all the handlers that have @@ -415,6 +464,8 @@ Tk_HandleEvent(eventPtr) Window handlerWindow; TkDisplay *dispPtr; Tcl_Interp *interp = (Tcl_Interp *) NULL; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * Next, invoke all the generic event handlers (those that are @@ -422,9 +473,10 @@ Tk_HandleEvent(eventPtr) * an event is fully processed, go no further. */ - for (genPrevPtr = NULL, genericPtr = genericList; genericPtr != NULL; ) { + for (genPrevPtr = NULL, genericPtr = tsdPtr->genericList; + genericPtr != NULL; ) { if (genericPtr->deleteFlag) { - if (!genericHandlersActive) { + if (!tsdPtr->genericHandlersActive) { GenericHandler *tmpPtr; /* @@ -435,12 +487,12 @@ Tk_HandleEvent(eventPtr) tmpPtr = genericPtr->nextPtr; if (genPrevPtr == NULL) { - genericList = tmpPtr; + tsdPtr->genericList = tmpPtr; } else { genPrevPtr->nextPtr = tmpPtr; } if (tmpPtr == NULL) { - lastGenericPtr = genPrevPtr; + tsdPtr->lastGenericPtr = genPrevPtr; } (void) ckfree((char *) genericPtr); genericPtr = tmpPtr; @@ -449,9 +501,9 @@ Tk_HandleEvent(eventPtr) } else { int done; - genericHandlersActive++; + tsdPtr->genericHandlersActive++; done = (*genericPtr->proc)(genericPtr->clientData, eventPtr); - genericHandlersActive--; + tsdPtr->genericHandlersActive--; if (done) { return; } @@ -623,8 +675,8 @@ Tk_HandleEvent(eventPtr) ip.eventPtr = eventPtr; ip.winPtr = winPtr; ip.nextHandler = NULL; - ip.nextPtr = pendingPtr; - pendingPtr = &ip; + ip.nextPtr = tsdPtr->pendingPtr; + tsdPtr->pendingPtr = &ip; if (mask == 0) { if ((eventPtr->type == SelectionClear) || (eventPtr->type == SelectionRequest) @@ -657,7 +709,7 @@ Tk_HandleEvent(eventPtr) TkBindEventProc(winPtr, eventPtr); } } - pendingPtr = ip.nextPtr; + tsdPtr->pendingPtr = ip.nextPtr; done: /* @@ -695,6 +747,8 @@ TkEventDeadWindow(winPtr) { register TkEventHandler *handlerPtr; register InProgress *ipPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * While deleting all the handlers, be careful to check for @@ -706,7 +760,8 @@ TkEventDeadWindow(winPtr) while (winPtr->handlerList != NULL) { handlerPtr = winPtr->handlerList; winPtr->handlerList = handlerPtr->nextPtr; - for (ipPtr = pendingPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { + for (ipPtr = tsdPtr->pendingPtr; ipPtr != NULL; + ipPtr = ipPtr->nextPtr) { if (ipPtr->nextHandler == handlerPtr) { ipPtr->nextHandler = NULL; } @@ -744,11 +799,13 @@ TkCurrentTime(dispPtr) TkDisplay *dispPtr; /* Display for which the time is desired. */ { register XEvent *eventPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - if (pendingPtr == NULL) { + if (tsdPtr->pendingPtr == NULL) { return dispPtr->lastEventTime; } - eventPtr = pendingPtr->eventPtr; + eventPtr = tsdPtr->pendingPtr->eventPtr; switch (eventPtr->type) { case ButtonPress: case ButtonRelease: @@ -798,11 +855,13 @@ Tk_RestrictEvents(proc, arg, prevArgPtr) * argument. */ { Tk_RestrictProc *prev; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - prev = restrictProc; - *prevArgPtr = restrictArg; - restrictProc = proc; - restrictArg = arg; + prev = tsdPtr->restrictProc; + *prevArgPtr = tsdPtr->restrictArg; + tsdPtr->restrictProc = proc; + tsdPtr->restrictArg = arg; return prev; } @@ -841,7 +900,7 @@ Tk_QueueWindowEvent(eventPtr, position) * Find our display structure for the event's display. */ - for (dispPtr = tkDisplayList; ; dispPtr = dispPtr->nextPtr) { + for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) { if (dispPtr == NULL) { return; } @@ -962,12 +1021,14 @@ WindowEventProc(evPtr, flags) { TkWindowEvent *wevPtr = (TkWindowEvent *) evPtr; Tk_RestrictAction result; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!(flags & TCL_WINDOW_EVENTS)) { return 0; } - if (restrictProc != NULL) { - result = (*restrictProc)(restrictArg, &wevPtr->event); + if (tsdPtr->restrictProc != NULL) { + result = (*tsdPtr->restrictProc)(tsdPtr->restrictArg, &wevPtr->event); if (result != TK_PROCESS_EVENT) { if (result == TK_DEFER_EVENT) { return 0; |