diff options
author | lfb <lfb> | 1998-12-13 09:54:43 (GMT) |
---|---|---|
committer | lfb <lfb> | 1998-12-13 09:54:43 (GMT) |
commit | 1b6aa4a2fd7521a6e0249fcab56940aeee597c14 (patch) | |
tree | b513ba2a8adf5b45c4a93c2dad501e1799731d27 /win | |
parent | 6a11e0ffdf0b7a302f94f3b38b1f9e751dc8ab8b (diff) | |
download | tk-1b6aa4a2fd7521a6e0249fcab56940aeee597c14.zip tk-1b6aa4a2fd7521a6e0249fcab56940aeee597c14.tar.gz tk-1b6aa4a2fd7521a6e0249fcab56940aeee597c14.tar.bz2 |
Fixed Windows bugs encountered while building w/ threads enabled.
Diffstat (limited to 'win')
-rw-r--r-- | win/tkWinDialog.c | 3 | ||||
-rw-r--r-- | win/tkWinMenu.c | 120 |
2 files changed, 72 insertions, 51 deletions
diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c index ce79a5f..c4f85f7 100644 --- a/win/tkWinDialog.c +++ b/win/tkWinDialog.c @@ -1,3 +1,4 @@ + /* * tkWinDialog.c -- * @@ -8,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinDialog.c,v 1.1.4.3 1998/12/13 08:16:17 lfb Exp $ + * RCS: @(#) $Id: tkWinDialog.c,v 1.1.4.4 1998/12/13 09:54:45 lfb Exp $ * */ diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c index 4dc2c0e..52845d7 100644 --- a/win/tkWinMenu.c +++ b/win/tkWinMenu.c @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinMenu.c,v 1.1.4.7 1998/12/13 08:16:18 lfb Exp $ + * RCS: @(#) $Id: tkWinMenu.c,v 1.1.4.8 1998/12/13 09:54:45 lfb Exp $ */ #define OEMRESOURCE @@ -52,30 +52,30 @@ static int indicatorDimensions[2]; * in a menu entry. Calculated at init * time to save time. */ -static Tcl_HashTable commandTable; +typedef struct ThreadSpecificData { + Tcl_HashTable commandTable; /* A map of command ids to menu entries */ -static int inPostMenu; /* We cannot be re-entrant like X Windows. */ -static WORD lastCommandID; /* The last command ID we allocated. */ -static HWND menuHWND; /* A window to service popup-menu messages + int inPostMenu; /* We cannot be re-entrant like X Windows. */ + WORD lastCommandID; /* The last command ID we allocated. */ + HWND menuHWND; /* A window to service popup-menu messages * in. */ - -static int oldServiceMode; /* Used while processing a menu; we need + int oldServiceMode; /* Used while processing a menu; we need * to set the event mode specially when we * enter the menu processing modal loop * and reset it when menus go away. */ -static TkMenu *modalMenuPtr; /* The menu we are processing inside the modal + TkMenu *modalMenuPtr; /* The menu we are processing inside the modal * loop. We need this to reset all of the * active items when menus go away since * Windows does not see fit to give this * to us when it sends its WM_MENUSELECT. */ -static Tcl_HashTable winMenuTable; + Tcl_HashTable winMenuTable; /* Need this to map HMENUs back to menuPtrs */ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; static OSVERSIONINFO versionInfo; /* So we don't have to keep doing this */ -TCL_DECLARE_MUTEX(winmenuMutex) - /* * The following are default menu value strings. */ @@ -84,6 +84,7 @@ static int defaultBorderWidth; /* The windows default border width. */ static Tcl_DString menuFontDString; /* A buffer to store the default menu font * string. */ +TCL_DECLARE_MUTEX(winMenuMutex) /* * Forward declarations for procedures defined later in this file: @@ -196,16 +197,18 @@ GetNewID(mePtr, menuIDPtr) int newEntry; Tcl_HashEntry *commandEntryPtr; WORD returnID; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - WORD curID = lastCommandID + 1; + WORD curID = tsdPtr->lastCommandID + 1; /* * The following code relies on WORD wrapping when the highest value is * incremented. */ - while (curID != lastCommandID) { - commandEntryPtr = Tcl_CreateHashEntry(&commandTable, + while (curID != tsdPtr->lastCommandID) { + commandEntryPtr = Tcl_CreateHashEntry(&tsdPtr->commandTable, (char *) curID, &newEntry); if (newEntry == 1) { found = 1; @@ -218,7 +221,7 @@ GetNewID(mePtr, menuIDPtr) if (found) { Tcl_SetHashValue(commandEntryPtr, (char *) mePtr); *menuIDPtr = (int) returnID; - lastCommandID = returnID; + tsdPtr->lastCommandID = returnID; return TCL_OK; } else { return TCL_ERROR; @@ -245,7 +248,10 @@ static void FreeID(commandID) int commandID; { - Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&commandTable, + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable, (char *) commandID); if (entryPtr != NULL) { @@ -279,6 +285,8 @@ TkpNewMenu(menuPtr) HMENU winMenuHdl; Tcl_HashEntry *hashEntryPtr; int newEntry; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); winMenuHdl = CreatePopupMenu(); @@ -293,7 +301,7 @@ TkpNewMenu(menuPtr) * back when dispatch messages. */ - hashEntryPtr = Tcl_CreateHashEntry(&winMenuTable, (char *) winMenuHdl, + hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable, (char *) winMenuHdl, &newEntry); Tcl_SetHashValue(hashEntryPtr, (char *) menuPtr); @@ -323,6 +331,8 @@ TkpDestroyMenu(menuPtr) { HMENU winMenuHdl = (HMENU) menuPtr->platformData; char *searchName; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) { Tcl_CancelIdleCall(ReconfigureWindowsMenu, (ClientData) menuPtr); @@ -366,7 +376,8 @@ TkpDestroyMenu(menuPtr) * Remove the menu from the menu hash table, then destroy the handle. */ - hashEntryPtr = Tcl_FindHashEntry(&winMenuTable, (char *) winMenuHdl); + hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, + (char *) winMenuHdl); if (hashEntryPtr != NULL) { Tcl_DeleteHashEntry(hashEntryPtr); } @@ -700,8 +711,10 @@ TkpPostMenu(interp, menuPtr, x, y) POINT point; Tk_Window parentWindow = Tk_Parent(menuPtr->tkwin); int oldServiceMode = Tcl_GetServiceMode(); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - inPostMenu++; + tsdPtr->inPostMenu++; if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) { Tcl_CancelIdleCall(ReconfigureWindowsMenu, (ClientData) menuPtr); @@ -710,7 +723,7 @@ TkpPostMenu(interp, menuPtr, x, y) result = TkPreprocessMenu(menuPtr); if (result != TCL_OK) { - inPostMenu--; + tsdPtr->inPostMenu--; return result; } @@ -720,7 +733,7 @@ TkpPostMenu(interp, menuPtr, x, y) */ if (menuPtr->tkwin == NULL) { - inPostMenu--; + tsdPtr->inPostMenu--; return TCL_OK; } @@ -761,14 +774,14 @@ TkpPostMenu(interp, menuPtr, x, y) } TrackPopupMenu(winMenuHdl, flags, x, y, 0, - menuHWND, &noGoawayRect); + tsdPtr->menuHWND, &noGoawayRect); Tcl_SetServiceMode(oldServiceMode); GetCursorPos(&point); Tk_PointerEvent(NULL, point.x, point.y); - if (inPostMenu) { - inPostMenu = 0; + if (tsdPtr->inPostMenu) { + tsdPtr->inPostMenu = 0; } return TCL_OK; } @@ -877,21 +890,24 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult) int returnResult = 0; TkMenu *menuPtr; TkMenuEntry *mePtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); switch (*pMessage) { case WM_INITMENU: TkMenuInit(); - hashEntryPtr = Tcl_FindHashEntry(&winMenuTable, (char *) *pwParam); + hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, + (char *) *pwParam); if (hashEntryPtr != NULL) { - oldServiceMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); + tsdPtr->oldServiceMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); - modalMenuPtr = menuPtr; + tsdPtr->modalMenuPtr = menuPtr; if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) { Tcl_CancelIdleCall(ReconfigureWindowsMenu, (ClientData) menuPtr); ReconfigureWindowsMenu((ClientData) menuPtr); } - if (!inPostMenu) { + if (!tsdPtr->inPostMenu) { Tcl_Interp *interp; int code; @@ -909,7 +925,7 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult) *plResult = 0; returnResult = 1; } else { - modalMenuPtr = NULL; + tsdPtr->modalMenuPtr = NULL; } break; @@ -919,7 +935,7 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult) if (HIWORD(*pwParam) != 0) { break; } - hashEntryPtr = Tcl_FindHashEntry(&commandTable, + hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable, (char *)LOWORD(*pwParam)); if (hashEntryPtr == NULL) { break; @@ -980,7 +996,8 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult) case WM_MENUCHAR: { unsigned char menuChar = (unsigned char) LOWORD(*pwParam); - hashEntryPtr = Tcl_FindHashEntry(&winMenuTable, (char *) *plParam); + hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, + (char *) *plParam); if (hashEntryPtr != NULL) { int i; @@ -1078,14 +1095,14 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult) TkMenuInit(); if ((flags == 0xFFFF) && (*plParam == 0)) { - Tcl_SetServiceMode(oldServiceMode); - if (modalMenuPtr != NULL) { - RecursivelyClearActiveMenu(modalMenuPtr); + Tcl_SetServiceMode(tsdPtr->oldServiceMode); + if (tsdPtr->modalMenuPtr != NULL) { + RecursivelyClearActiveMenu(tsdPtr->modalMenuPtr); } } else { menuPtr = NULL; - if (*plParam != 0) { - hashEntryPtr = Tcl_FindHashEntry(&winMenuTable, + if (*plParam != 0) { + hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, (char *) *plParam); if (hashEntryPtr != NULL) { menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); @@ -1098,7 +1115,8 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult) if (flags & MF_POPUP) { mePtr = menuPtr->entries[LOWORD(*pwParam)]; } else { - hashEntryPtr = Tcl_FindHashEntry(&commandTable, + hashEntryPtr = Tcl_FindHashEntry( + &tsdPtr->commandTable, (char *) LOWORD(*pwParam)); if (hashEntryPtr != NULL) { mePtr = (TkMenuEntry *) @@ -1180,18 +1198,21 @@ TkpSetWindowMenuBar(tkwin, menuPtr) TkMenu *menuPtr; /* The menu we are inserting */ { HMENU winMenuHdl; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (menuPtr != NULL) { Tcl_HashEntry *hashEntryPtr; int newEntry; winMenuHdl = (HMENU) menuPtr->platformData; - hashEntryPtr = Tcl_FindHashEntry(&winMenuTable, (char *) winMenuHdl); + hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, + (char *) winMenuHdl); Tcl_DeleteHashEntry(hashEntryPtr); DestroyMenu(winMenuHdl); winMenuHdl = CreateMenu(); - hashEntryPtr = Tcl_CreateHashEntry(&winMenuTable, (char *) winMenuHdl, - &newEntry); + hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable, + (char *) winMenuHdl, &newEntry); Tcl_SetHashValue(hashEntryPtr, (char *) menuPtr); menuPtr->platformData = (TkMenuPlatformData) winMenuHdl; TkWinSetMenu(tkwin, winMenuHdl); @@ -2569,7 +2590,10 @@ static void MenuExitHandler( ClientData clientData) /* Not used */ { - DestroyWindow(menuHWND); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + DestroyWindow(tsdPtr->menuHWND); UnregisterClass(MENU_CLASS_NAME, Tk_GetHINSTANCE()); } @@ -2760,15 +2784,11 @@ void TkpMenuInit() { WNDCLASS wndClass; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - Tcl_MutexLock(&winMenuMutex); - - - Tcl_MutexUnlock(&winMenuMutex); - - - Tcl_InitHashTable(&winMenuTable, TCL_ONE_WORD_KEYS); - Tcl_InitHashTable(&commandTable, TCL_ONE_WORD_KEYS); + Tcl_InitHashTable(&tsdPtr->winMenuTable, TCL_ONE_WORD_KEYS); + Tcl_InitHashTable(&tsdPtr->commandTable, TCL_ONE_WORD_KEYS); wndClass.style = CS_OWNDC; wndClass.lpfnWndProc = TkWinMenuProc; wndClass.cbClsExtra = 0; @@ -2781,7 +2801,7 @@ TkpMenuInit() wndClass.lpszClassName = MENU_CLASS_NAME; RegisterClass(&wndClass); - menuHWND = CreateWindow(MENU_CLASS_NAME, "MenuWindow", WS_POPUP, + tsdPtr->menuHWND = CreateWindow(MENU_CLASS_NAME, "MenuWindow", WS_POPUP, 0, 0, 10, 10, NULL, NULL, Tk_GetHINSTANCE(), NULL); Tcl_CreateExitHandler(MenuExitHandler, (ClientData) NULL); |