diff options
author | lfb <lfb> | 1999-03-09 01:47:27 (GMT) |
---|---|---|
committer | lfb <lfb> | 1999-03-09 01:47:27 (GMT) |
commit | fc7fc30bb7804077e6320e54b74913e759361a8b (patch) | |
tree | 746a5fe161656bced64b5a78e01a783ed598a518 | |
parent | 40344330fa300c3b58eedfea7c705b14029be3ca (diff) | |
download | tk-fc7fc30bb7804077e6320e54b74913e759361a8b.zip tk-fc7fc30bb7804077e6320e54b74913e759361a8b.tar.gz tk-fc7fc30bb7804077e6320e54b74913e759361a8b.tar.bz2 |
Window class should not use the CS_CLASSDC flag, as this causes
Tk to get confused during thread context switches and to draw to
the wrong windows.
This change should be revisited later, and a subsystem added to
manage device contexts on a thread-specific basis.
-rw-r--r-- | win/tkWinWm.c | 76 | ||||
-rw-r--r-- | win/tkWinX.c | 5 |
2 files changed, 56 insertions, 25 deletions
diff --git a/win/tkWinWm.c b/win/tkWinWm.c index 69b9aec..51dd28d 100644 --- a/win/tkWinWm.c +++ b/win/tkWinWm.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinWm.c,v 1.1.4.9 1999/03/01 19:35:28 redman Exp $ + * RCS: @(#) $Id: tkWinWm.c,v 1.1.4.10 1999/03/09 01:47:27 lfb Exp $ */ #include "tkWinInt.h" @@ -251,15 +251,26 @@ typedef struct ThreadSpecificData { * damage where it sends the * WM_GETMINMAXINFO message before the * WM_CREATE window. */ - WNDCLASS toplevelClass; /* Class for toplevel windows. */ - int initialized; /* Flag indicating whether module has - * been initialized yet. */ + int initialized; /* Flag indicating whether thread- + * specific elements of module have + * been initialized. */ int firstWindow; /* Flag, cleared when the first window * is mapped in a non-iconic state. */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; /* + * The following variables cannot be placed in thread local storage + * because they must be shared across threads. + */ + +static WNDCLASS toplevelClass; /* Class for toplevel windows. */ +static int initialized; /* Flag indicating whether module has + * been initialized. */ +TCL_DECLARE_MUTEX(winWmMutex) + + +/* * Forward declarations for procedures defined in this file: */ @@ -320,26 +331,45 @@ InitWm(void) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); WNDCLASS * classPtr; - if (tsdPtr->initialized) { - return; + if (! tsdPtr->initialized) { + tsdPtr->initialized = 1; + tsdPtr->firstWindow = 1; } - tsdPtr->initialized = 1; - tsdPtr->firstWindow = 1; - classPtr = &tsdPtr->toplevelClass; - - classPtr->style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC; - classPtr->cbClsExtra = 0; - classPtr->cbWndExtra = 0; - classPtr->hInstance = Tk_GetHINSTANCE(); - classPtr->hbrBackground = NULL; - classPtr->lpszMenuName = NULL; - classPtr->lpszClassName = TK_WIN_TOPLEVEL_CLASS_NAME; - classPtr->lpfnWndProc = WmProc; - classPtr->hIcon = LoadIcon(Tk_GetHINSTANCE(), "tk"); - classPtr->hCursor = LoadCursor(NULL, IDC_ARROW); - - if (!RegisterClass(classPtr)) { - panic("Unable to register TkTopLevel class"); + if (! initialized) { + Tcl_MutexLock(&winWmMutex); + if (! initialized) { + initialized = 1; + classPtr = &toplevelClass; + + /* + * When threads are enabled, we cannot use CLASSDC because + * threads will then write into the same device context. + * + * This is a hack; we should add a subsystem that manages + * device context on a per-thread basis. See also tkWinX.c, + * which also initializes a WNDCLASS structure. + */ + +#ifdef TCL_THREADS + childClass.style = CS_HREDRAW | CS_VREDRAW; +#else + childClass.style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC; +#endif + classPtr->cbClsExtra = 0; + classPtr->cbWndExtra = 0; + classPtr->hInstance = Tk_GetHINSTANCE(); + classPtr->hbrBackground = NULL; + classPtr->lpszMenuName = NULL; + classPtr->lpszClassName = TK_WIN_TOPLEVEL_CLASS_NAME; + classPtr->lpfnWndProc = WmProc; + classPtr->hIcon = LoadIcon(Tk_GetHINSTANCE(), "tk"); + classPtr->hCursor = LoadCursor(NULL, IDC_ARROW); + + if (!RegisterClass(classPtr)) { + panic("Unable to register TkTopLevel class"); + } + } + Tcl_MutexUnlock(&winWmMutex); } } diff --git a/win/tkWinX.c b/win/tkWinX.c index 290656b..4d5fbb6 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinX.c,v 1.1.4.8 1999/03/09 01:40:46 lfb Exp $ + * RCS: @(#) $Id: tkWinX.c,v 1.1.4.9 1999/03/09 01:47:28 lfb Exp $ */ #include "tkWinInt.h" @@ -156,7 +156,8 @@ TkWinXInit(hInstance) * threads will then write into the same device context. * * This is a hack; we should add a subsystem that manages - * device context on a per-thread basis. + * device context on a per-thread basis. See also tkWinWm.c, + * which also initializes a WNDCLASS structure. */ #ifdef TCL_THREADS |