summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlfb <lfb>1999-03-09 01:47:27 (GMT)
committerlfb <lfb>1999-03-09 01:47:27 (GMT)
commitfc7fc30bb7804077e6320e54b74913e759361a8b (patch)
tree746a5fe161656bced64b5a78e01a783ed598a518
parent40344330fa300c3b58eedfea7c705b14029be3ca (diff)
downloadtk-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.c76
-rw-r--r--win/tkWinX.c5
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