summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog47
-rw-r--r--generic/tkBind.c9
-rw-r--r--generic/tkClipboard.c12
-rw-r--r--generic/tkEvent.c6
-rw-r--r--generic/tkFocus.c10
-rw-r--r--generic/tkOption.c4
-rw-r--r--generic/tkWindow.c16
-rw-r--r--mac/tkMacXStubs.c3
-rw-r--r--unix/tkUnixEvent.c19
-rw-r--r--unix/tkUnixSend.c23
-rw-r--r--win/tkWinX.c3
11 files changed, 103 insertions, 49 deletions
diff --git a/ChangeLog b/ChangeLog
index b134225..d2ce879 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,50 @@
+2002-06-19 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tkBind.c (TkBindDeadWindow):
+ Handle case where Tk_DestroyWindow is invoked
+ on clipboard and send windows.
+ * generic/tkClipboard.c (TkClipCleanup):
+ Invoke Tk_DestroyWindow to cleanup the
+ dispPtr->clipWindow. Call Tcl_Preserve
+ and Tcl_Release on the window to avoid an
+ invalid memory ref on shutdown.
+ * generic/tkEvent.c (Tk_HandleEvent):
+ Panic if XCreateIC is invoked twice for
+ the same window. This should never happen,
+ the check were just added to make sure it
+ does not since this could lead to crashes
+ in XCloseIM.
+ * generic/tkFocus.c (TkFocusDeadWindow):
+ Handle case where Tk_DestroyWindow is invoked
+ on clipboard and send windows.
+ * generic/tkOption.c (TkOptionDeadWindow): Ditto.
+ * generic/tkWindow.c (TkCloseDisplay): Move
+ deletion of dispPtr->winTable after TkpCloseDisplay
+ call since Tk_DestroyWindow uses it and could
+ be called by TkpCloseDisplay for clipboard/send windows.
+ Also invoke ckfree for the dispPtr instead of
+ doing it in TkpCloseDisplay.
+ (Tk_DestroyWindow): Check for a null winPtr->mainPtr
+ before doing certain cleanup tasks so the we can
+ invoke Tk_DestroyWindow on clipboard and send windows.
+ We need to do this so that XDestroyIC will get invoked
+ for the input contexts of each window.
+ * mac/tkMacXStubs.c (TkpCloseDisplay): Don't free
+ the displayPtr since this is now done in TkCloseDisplay.
+ * unix/tkUnixEvent.c (TkpCloseDisplay, OpenIM): Remove
+ conditional compilation around calls to XCloseIM
+ since I am confident that the crashes related to
+ input contexts has been fixed. Don't free
+ the displayPtr since this is now done in TkCloseDisplay.
+ * unix/tkUnixSend.c (TkSendCleanup): Invoke the
+ Tk_DestroyWindow method to cleanup the special
+ send window. This will call XDestroyIC and thereby
+ avoid a crash in XCloseIM. The send window needs
+ to be Tcl_Preserve and Tcl_Release to avoid an
+ invalid memory ref on shutdown.
+ * win/tkWinX.c (TkpCloseDisplay): Don't free
+ the displayPtr since this is now done in TkCloseDisplay.
+
2002-06-19 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* generic/tkStyle.c: TIP#48 style engine.
diff --git a/generic/tkBind.c b/generic/tkBind.c
index e472d8e..c70a1a5 100644
--- a/generic/tkBind.c
+++ b/generic/tkBind.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: tkBind.c,v 1.24 2002/06/15 02:15:51 hobbs Exp $
+ * RCS: @(#) $Id: tkBind.c,v 1.25 2002/06/19 19:37:53 mdejong Exp $
*/
#include "tkPort.h"
@@ -1907,6 +1907,13 @@ TkBindDeadWindow(winPtr)
BindInfo *bindInfoPtr;
PendingBinding *curPtr;
+ /*
+ * Certain special windows like those used for send and clipboard
+ * have no mainPtr.
+ */
+ if (winPtr->mainPtr == NULL)
+ return;
+
bindInfoPtr = (BindInfo *) winPtr->mainPtr->bindInfo;
curPtr = bindInfoPtr->pendingList;
while (curPtr != NULL) {
diff --git a/generic/tkClipboard.c b/generic/tkClipboard.c
index 149f65d..c43d621 100644
--- a/generic/tkClipboard.c
+++ b/generic/tkClipboard.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: tkClipboard.c,v 1.9 2002/04/12 10:03:02 hobbs Exp $
+ * RCS: @(#) $Id: tkClipboard.c,v 1.10 2002/06/19 19:37:54 mdejong Exp $
*/
#include "tkInt.h"
@@ -649,12 +649,9 @@ TkClipCleanup(dispPtr)
dispPtr->applicationAtom);
Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
dispPtr->windowAtom);
- /*
- * It may be too late to call Tk_DestroyWindow, so just free the
- * memory created directly.
- */
- ckfree((char *) dispPtr->clipWindow);
- dispPtr->clipWindow = NULL;
+
+ Tk_DestroyWindow(dispPtr->clipWindow);
+ Tcl_Release((ClientData) dispPtr->clipWindow);
}
}
@@ -700,6 +697,7 @@ TkClipInit(interp, dispPtr)
if (dispPtr->clipWindow == NULL) {
return TCL_ERROR;
}
+ Tcl_Preserve((ClientData) dispPtr->clipWindow);
atts.override_redirect = True;
Tk_ChangeWindowAttributes(dispPtr->clipWindow, CWOverrideRedirect, &atts);
Tk_MakeWindowExist(dispPtr->clipWindow);
diff --git a/generic/tkEvent.c b/generic/tkEvent.c
index 754b451..009e2f5 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.15 2002/06/15 02:08:12 hobbs Exp $
+ * RCS: @(#) $Id: tkEvent.c,v 1.16 2002/06/19 19:37:54 mdejong Exp $
*/
#include "tkPort.h"
@@ -888,6 +888,8 @@ Tk_HandleEvent(eventPtr)
preedit_attr = XVaCreateNestedList(0, XNSpotLocation,
&spot, XNFontSet, dispPtr->inputXfs, NULL);
+ if (winPtr->inputContext != NULL)
+ panic("inputContext not NULL");
winPtr->inputContext = XCreateIC(dispPtr->inputMethod,
XNInputStyle, XIMPreeditPosition|XIMStatusNothing,
XNClientWindow, winPtr->window,
@@ -897,6 +899,8 @@ Tk_HandleEvent(eventPtr)
XFree(preedit_attr);
} else
#endif
+ if (winPtr->inputContext != NULL)
+ panic("inputContext not NULL");
winPtr->inputContext = XCreateIC(dispPtr->inputMethod,
XNInputStyle, XIMPreeditNothing|XIMStatusNothing,
XNClientWindow, winPtr->window,
diff --git a/generic/tkFocus.c b/generic/tkFocus.c
index b1ba279..f31d2a3 100644
--- a/generic/tkFocus.c
+++ b/generic/tkFocus.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: tkFocus.c,v 1.8 2002/06/14 22:25:12 jenglish Exp $
+ * RCS: @(#) $Id: tkFocus.c,v 1.9 2002/06/19 19:37:54 mdejong Exp $
*/
#include "tkInt.h"
@@ -813,6 +813,14 @@ TkFocusDeadWindow(winPtr)
TkDisplay *dispPtr = winPtr->dispPtr;
/*
+ * Certain special windows like those used for send and clipboard
+ * have no mainPtr.
+ */
+
+ if (winPtr->mainPtr == NULL)
+ return;
+
+ /*
* Search for focus records that refer to this window either as
* the top-level window or the current focus window.
*/
diff --git a/generic/tkOption.c b/generic/tkOption.c
index d562e6c..227ae40 100644
--- a/generic/tkOption.c
+++ b/generic/tkOption.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: tkOption.c,v 1.13 2002/06/15 21:02:20 mdejong Exp $
+ * RCS: @(#) $Id: tkOption.c,v 1.14 2002/06/19 19:37:54 mdejong Exp $
*/
#include "tkPort.h"
@@ -787,7 +787,7 @@ TkOptionDeadWindow(winPtr)
* database.
*/
- if ((winPtr->mainPtr->winPtr == winPtr)
+ if ((winPtr->mainPtr != NULL) && (winPtr->mainPtr->winPtr == winPtr)
&& (winPtr->mainPtr->optionRootPtr != NULL)) {
ClearOptionTree(winPtr->mainPtr->optionRootPtr);
winPtr->mainPtr->optionRootPtr = NULL;
diff --git a/generic/tkWindow.c b/generic/tkWindow.c
index e778e40..187dce4 100644
--- a/generic/tkWindow.c
+++ b/generic/tkWindow.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: tkWindow.c,v 1.49 2002/06/18 23:51:46 dkf Exp $
+ * RCS: @(#) $Id: tkWindow.c,v 1.50 2002/06/19 19:37:54 mdejong Exp $
*/
#include "tkPort.h"
@@ -240,8 +240,6 @@ TkCloseDisplay(TkDisplay *dispPtr)
ckfree(dispPtr->name);
}
- Tcl_DeleteHashTable(&dispPtr->winTable);
-
if (dispPtr->atomInit) {
Tcl_DeleteHashTable(&dispPtr->nameTable);
Tcl_DeleteHashTable(&dispPtr->atomTable);
@@ -263,6 +261,15 @@ TkCloseDisplay(TkDisplay *dispPtr)
TkpCloseDisplay(dispPtr);
/*
+ * Delete winTable after TkpCloseDisplay since special windows
+ * may need call Tk_DestroyWindow and it checks the winTable.
+ */
+
+ Tcl_DeleteHashTable(&dispPtr->winTable);
+
+ ckfree((char *) dispPtr);
+
+ /*
* There is more to clean up, we leave it at this for the time being.
*/
}
@@ -1262,7 +1269,7 @@ Tk_DestroyWindow(tkwin)
* can be closed and its data structures deleted.
*/
- if (winPtr->mainPtr->winPtr == winPtr) {
+ if (winPtr->mainPtr != NULL && winPtr->mainPtr->winPtr == winPtr) {
dispPtr->refCount--;
if (tsdPtr->mainWindowList == winPtr->mainPtr) {
tsdPtr->mainWindowList = winPtr->mainPtr->nextPtr;
@@ -1388,6 +1395,7 @@ Tk_DestroyWindow(tkwin)
#ifdef TK_USE_INPUT_METHODS
if (winPtr->inputContext != NULL) {
XDestroyIC(winPtr->inputContext);
+ winPtr->inputContext = NULL;
}
#endif /* TK_USE_INPUT_METHODS */
if (winPtr->tagPtr != NULL) {
diff --git a/mac/tkMacXStubs.c b/mac/tkMacXStubs.c
index 6525c1f..82078b9 100644
--- a/mac/tkMacXStubs.c
+++ b/mac/tkMacXStubs.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: tkMacXStubs.c,v 1.14 2002/06/17 20:09:01 hobbs Exp $
+ * RCS: @(#) $Id: tkMacXStubs.c,v 1.15 2002/06/19 19:37:55 mdejong Exp $
*/
#include "tkInt.h"
@@ -184,7 +184,6 @@ TkpCloseDisplay(
ckfree((char *) display->screens);
}
ckfree((char *) display);
- ckfree((char *) displayPtr);
}
/*
diff --git a/unix/tkUnixEvent.c b/unix/tkUnixEvent.c
index 98132a1..918d66a 100644
--- a/unix/tkUnixEvent.c
+++ b/unix/tkUnixEvent.c
@@ -9,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: tkUnixEvent.c,v 1.8 2002/06/15 01:54:09 hobbs Exp $
+ * RCS: @(#) $Id: tkUnixEvent.c,v 1.9 2002/06/19 19:37:55 mdejong Exp $
*/
#include "tkInt.h"
@@ -172,24 +172,23 @@ TkpCloseDisplay(dispPtr)
XFreeFontSet(dispPtr->display, dispPtr->inputXfs);
}
#endif
-#if ! defined(SOLARIS2) || defined(HAVE_X11R6)
if (dispPtr->inputMethod) {
/*
- * This causes core dumps on some systems (e.g. Solaris 2.3 as of
- * 1/6/95), but is OK with X11R6
+ * This caused core dumps on some systems (Solaris 2.3 1/6/95).
+ * The most likely cause of this is a bug in X that accesses
+ * memory that was already deallocated inside XCloseIM().
+ * One can work around this issue by making sure a XDestroyIC()
+ * gets invoked for each XCreateIC().
*/
XCloseIM(dispPtr->inputMethod);
}
#endif
-#endif
if (dispPtr->display != 0) {
Tcl_DeleteFileHandler(ConnectionNumber(dispPtr->display));
(void) XSync(dispPtr->display, False);
(void) XCloseDisplay(dispPtr->display);
}
-
- ckfree((char *) dispPtr);
}
/*
@@ -610,12 +609,10 @@ OpenIM(dispPtr)
if (dispPtr->inputMethod) {
/*
- * This causes core dumps on some systems (e.g. Solaris 2.3 as of
- * 1/6/95), but is OK with X11R6
+ * This call should not suffer from any core dumping problems
+ * since we have not allocated any input contexts.
*/
-#if ! defined (SOLARIS2) || defined (HAVE_X11R6)
XCloseIM(dispPtr->inputMethod);
-#endif
dispPtr->inputMethod = NULL;
}
}
diff --git a/unix/tkUnixSend.c b/unix/tkUnixSend.c
index 843360a..ea0d393 100644
--- a/unix/tkUnixSend.c
+++ b/unix/tkUnixSend.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: tkUnixSend.c,v 1.7 2002/06/17 19:42:11 hobbs Exp $
+ * RCS: @(#) $Id: tkUnixSend.c,v 1.8 2002/06/19 19:37:55 mdejong Exp $
*/
#include "tkPort.h"
@@ -1275,25 +1275,11 @@ void
TkSendCleanup(dispPtr)
TkDisplay *dispPtr;
{
- TkWindow *winPtr = (TkWindow *) dispPtr->commTkwin;
-
if (dispPtr->commTkwin != NULL) {
- Tk_DeleteEventHandler((Tk_Window) winPtr, PropertyChangeMask,
+ Tk_DeleteEventHandler(dispPtr->commTkwin, PropertyChangeMask,
SendEventProc, (ClientData) dispPtr);
-
- /*
- * We need to manually free all the XIC structures that
- * have been allocated in order to avoid a nasty bug in XCloseIM().
- */
- if (winPtr->inputContext != NULL) {
- XDestroyIC(winPtr->inputContext);
- winPtr->inputContext = NULL;
- }
-
-#ifdef PURIFY
- /* Tk_DestroyWindow(dispPtr->commTkwin); */
- ckfree((char *) dispPtr->commTkwin);
-#endif
+ Tk_DestroyWindow(dispPtr->commTkwin);
+ Tcl_Release((ClientData) dispPtr->commTkwin);
dispPtr->commTkwin = NULL;
}
}
@@ -1335,6 +1321,7 @@ SendInit(interp, dispPtr)
if (dispPtr->commTkwin == NULL) {
panic("Tk_CreateWindow failed in SendInit!");
}
+ Tcl_Preserve((ClientData) dispPtr->commTkwin);
atts.override_redirect = True;
Tk_ChangeWindowAttributes(dispPtr->commTkwin,
CWOverrideRedirect, &atts);
diff --git a/win/tkWinX.c b/win/tkWinX.c
index 85e9464..9de5da3 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.22 2002/06/17 20:09:01 hobbs Exp $
+ * RCS: @(#) $Id: tkWinX.c,v 1.23 2002/06/19 19:37:55 mdejong Exp $
*/
#include "tkWinInt.h"
@@ -558,7 +558,6 @@ TkpCloseDisplay(dispPtr)
ckfree((char *) display->screens);
}
ckfree((char *) display);
- ckfree((char *) dispPtr);
}
/*