diff options
-rw-r--r-- | ChangeLog | 47 | ||||
-rw-r--r-- | generic/tkBind.c | 9 | ||||
-rw-r--r-- | generic/tkClipboard.c | 12 | ||||
-rw-r--r-- | generic/tkEvent.c | 6 | ||||
-rw-r--r-- | generic/tkFocus.c | 10 | ||||
-rw-r--r-- | generic/tkOption.c | 4 | ||||
-rw-r--r-- | generic/tkWindow.c | 16 | ||||
-rw-r--r-- | mac/tkMacXStubs.c | 3 | ||||
-rw-r--r-- | unix/tkUnixEvent.c | 19 | ||||
-rw-r--r-- | unix/tkUnixSend.c | 23 | ||||
-rw-r--r-- | win/tkWinX.c | 3 |
11 files changed, 103 insertions, 49 deletions
@@ -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); } /* |