summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tkEntry.c54
-rw-r--r--generic/tkListbox.c26
2 files changed, 52 insertions, 28 deletions
diff --git a/generic/tkEntry.c b/generic/tkEntry.c
index 805b208..35464da 100644
--- a/generic/tkEntry.c
+++ b/generic/tkEntry.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: tkEntry.c,v 1.20 2001/07/02 23:52:36 hobbs Exp $
+ * RCS: @(#) $Id: tkEntry.c,v 1.21 2001/07/03 06:16:19 hobbs Exp $
*/
#include "tkInt.h"
@@ -837,6 +837,13 @@ Tk_EntryObjCmd(clientData, interp, objc, objv)
entryPtr->avgWidth = 1;
entryPtr->validate = VALIDATE_NONE;
+ /*
+ * Keep a hold of the associated tkwin until we destroy the listbox,
+ * otherwise Tk might free it while we still need it.
+ */
+
+ Tcl_Preserve((ClientData) entryPtr->tkwin);
+
Tk_SetClass(entryPtr->tkwin, "Entry");
Tk_SetClassProcs(entryPtr->tkwin, &entryClass, (ClientData) entryPtr);
Tk_CreateEventHandler(entryPtr->tkwin,
@@ -889,7 +896,6 @@ EntryWidgetObjCmd(clientData, interp, objc, objv)
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
return TCL_ERROR;
}
- Tcl_Preserve((ClientData) entryPtr);
/*
* Parse the widget command by looking up the second token in
@@ -902,6 +908,7 @@ EntryWidgetObjCmd(clientData, interp, objc, objv)
return result;
}
+ Tcl_Preserve((ClientData) entryPtr);
switch ((enum entryCmd) cmdIndex) {
case COMMAND_BBOX: {
int index, x, y, width, height;
@@ -1360,18 +1367,10 @@ DestroyEntry(memPtr)
Tk_FreeTextLayout(entryPtr->textLayout);
Tk_FreeConfigOptions((char *) entryPtr, entryPtr->optionTable,
entryPtr->tkwin);
+ Tcl_Release((ClientData) entryPtr->tkwin);
entryPtr->tkwin = NULL;
- /*
- * Tcl_EventuallyFree should be used in
- * DestroyNotify branch of EntryEventProc. However, that can lead
- * complications in Tk_FreeConfigOptions where the display for the
- * entry has been deleted by Tk_DestroyWindow, which is needed
- * when freeing the cursor option. Also, there can be a timing
- * issue were we wouldn't get called until too late in Tk clean-up,
- * and it complains that we haven't freed our fonts yet.
- */
- Tcl_EventuallyFree((ClientData) entryPtr, TCL_DYNAMIC);
+ ckfree((char *) entryPtr);
}
/*
@@ -1810,16 +1809,20 @@ DisplayEntry(clientData)
if (entryPtr->flags & UPDATE_SCROLLBAR) {
entryPtr->flags &= ~UPDATE_SCROLLBAR;
- EntryUpdateScrollbar(entryPtr);
- }
- /*
- * We do this check twice because updating the scrollbar can have
- * the side-effect of destroying or unmapping the entry widget.
- */
+ /*
+ * Preserve/Release because updating the scrollbar can have
+ * the side-effect of destroying or unmapping the entry widget.
+ */
- if ((entryPtr->flags & ENTRY_DELETED) || !Tk_IsMapped(tkwin)) {
- return;
+ Tcl_Preserve((ClientData) entryPtr);
+ EntryUpdateScrollbar(entryPtr);
+
+ if ((entryPtr->flags & ENTRY_DELETED) || !Tk_IsMapped(tkwin)) {
+ Tcl_Release((ClientData) entryPtr);
+ return;
+ }
+ Tcl_Release((ClientData) entryPtr);
}
/*
@@ -2635,7 +2638,7 @@ EntryEventProc(clientData, eventPtr)
if (entryPtr->flags & REDRAW_PENDING) {
Tcl_CancelIdleCall(DisplayEntry, clientData);
}
- DestroyEntry((char *) entryPtr);
+ Tcl_EventuallyFree(clientData, DestroyEntry);
}
break;
case ConfigureNotify:
@@ -3782,6 +3785,13 @@ Tk_SpinboxObjCmd(clientData, interp, objc, objv)
sbPtr->bdRelief = TK_RELIEF_FLAT;
sbPtr->buRelief = TK_RELIEF_FLAT;
+ /*
+ * Keep a hold of the associated tkwin until we destroy the listbox,
+ * otherwise Tk might free it while we still need it.
+ */
+
+ Tcl_Preserve((ClientData) entryPtr->tkwin);
+
Tk_SetClass(entryPtr->tkwin, "Spinbox");
Tk_SetClassProcs(entryPtr->tkwin, &entryClass, (ClientData) entryPtr);
Tk_CreateEventHandler(entryPtr->tkwin,
@@ -3841,7 +3851,6 @@ SpinboxWidgetObjCmd(clientData, interp, objc, objv)
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
return TCL_ERROR;
}
- Tcl_Preserve((ClientData) entryPtr);
/*
* Parse the widget command by looking up the second token in
@@ -3854,6 +3863,7 @@ SpinboxWidgetObjCmd(clientData, interp, objc, objv)
return result;
}
+ Tcl_Preserve((ClientData) entryPtr);
switch ((enum sbCmd) cmdIndex) {
case SB_CMD_BBOX: {
int index, x, y, width, height;
diff --git a/generic/tkListbox.c b/generic/tkListbox.c
index 6c45dfd..356f3af 100644
--- a/generic/tkListbox.c
+++ b/generic/tkListbox.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: tkListbox.c,v 1.20 2001/04/03 04:41:08 hobbs Exp $
+ * RCS: @(#) $Id: tkListbox.c,v 1.21 2001/07/03 06:16:19 hobbs Exp $
*/
#include "tkPort.h"
@@ -574,6 +574,13 @@ Tk_ListboxObjCmd(clientData, interp, objc, objv)
listPtr->gray = None;
listPtr->flags = 0;
+ /*
+ * Keep a hold of the associated tkwin until we destroy the listbox,
+ * otherwise Tk might free it while we still need it.
+ */
+
+ Tcl_Preserve((ClientData) listPtr->tkwin);
+
Tk_SetClass(listPtr->tkwin, "Listbox");
Tk_SetClassProcs(listPtr->tkwin, &listboxClass, (ClientData) listPtr);
Tk_CreateEventHandler(listPtr->tkwin,
@@ -629,7 +636,6 @@ ListboxWidgetObjCmd(clientData, interp, objc, objv)
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
return TCL_ERROR;
}
- Tcl_Preserve((ClientData)listPtr);
/*
* Parse the command by looking up the second argument in the list
@@ -638,10 +644,10 @@ ListboxWidgetObjCmd(clientData, interp, objc, objv)
result = Tcl_GetIndexFromObj(interp, objv[1], commandNames,
"option", 0, &cmdIndex);
if (result != TCL_OK) {
- Tcl_Release((ClientData)listPtr);
return result;
}
+ Tcl_Preserve((ClientData)listPtr);
/* The subcommand was valid, so continue processing */
switch (cmdIndex) {
case COMMAND_ACTIVATE: {
@@ -1498,6 +1504,7 @@ DestroyListbox(memPtr)
Tk_FreeConfigOptions((char *)listPtr, listPtr->optionTable,
listPtr->tkwin);
+ Tcl_Release((ClientData) listPtr->tkwin);
listPtr->tkwin = NULL;
ckfree((char *) listPtr);
}
@@ -1834,16 +1841,23 @@ DisplayListbox(clientData)
listPtr->flags |= UPDATE_H_SCROLLBAR;
}
+ Tcl_Preserve((ClientData) listPtr);
if (listPtr->flags & UPDATE_V_SCROLLBAR) {
ListboxUpdateVScrollbar(listPtr);
+ if ((listPtr->flags & LISTBOX_DELETED) || !Tk_IsMapped(tkwin)) {
+ Tcl_Release((ClientData) listPtr);
+ return;
+ }
}
if (listPtr->flags & UPDATE_H_SCROLLBAR) {
ListboxUpdateHScrollbar(listPtr);
+ if ((listPtr->flags & LISTBOX_DELETED) || !Tk_IsMapped(tkwin)) {
+ Tcl_Release((ClientData) listPtr);
+ return;
+ }
}
listPtr->flags &= ~(REDRAW_PENDING|UPDATE_V_SCROLLBAR|UPDATE_H_SCROLLBAR);
- if ((listPtr->flags & LISTBOX_DELETED) || (!Tk_IsMapped(tkwin))) {
- return;
- }
+ Tcl_Release((ClientData) listPtr);
/*
* Redrawing is done in a temporary pixmap that is allocated