From 94bc1474a0cff0e2e9b84c7c5dbc74fe304c40c8 Mon Sep 17 00:00:00 2001 From: "peter.spjuth@gmail.com" Date: Mon, 28 May 2001 16:56:02 +0000 Subject: Upgraded frame to use the newer TK_OPTION style when processing configuration options. Some cleanup of bad comments and bad code. [part of patch #420861] --- ChangeLog | 8 ++ generic/tkFrame.c | 365 ++++++++++++++++++++++++++++++++++------------------- generic/tkWindow.c | 6 +- tests/frame.test | 23 +++- 4 files changed, 260 insertions(+), 142 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1a0535b..10ec883 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2001-05-28 Peter Spjuth + + * generic/tkFrame.c: + * generic/tkWindow.c: + * tests/frame.test: Upgraded frame to use the newer TK_OPTION + style when processing configuration options. Some cleanup of + bad comments and bad code. [part of patch #420861] + 2001-05-23 Mo DeJong * unix/configure: diff --git a/generic/tkFrame.c b/generic/tkFrame.c index cf356ce..6b70e62 100644 --- a/generic/tkFrame.c +++ b/generic/tkFrame.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: tkFrame.c,v 1.7 2000/11/22 01:49:38 ericm Exp $ + * RCS: @(#) $Id: tkFrame.c,v 1.8 2001/05/28 16:56:02 pspjuth Exp $ */ #include "default.h" @@ -20,6 +20,14 @@ #include "tkInt.h" /* + * The following enum is used to define the type of the frame. + */ + +enum FrameType { + TYPE_FRAME, TYPE_TOPLEVEL +}; + +/* * A data structure of the following type is kept for each * frame that currently exists for this process: */ @@ -35,11 +43,11 @@ typedef struct { Tcl_Interp *interp; /* Interpreter associated with widget. Used * to delete widget command. */ Tcl_Command widgetCmd; /* Token for frame's widget command. */ + Tk_OptionTable optionTable; /* Table that defines configuration options + * available for this widget. */ char *className; /* Class name for widget (from configuration * option). Malloc-ed. */ - int mask; /* Either FRAME or TOPLEVEL; used to select - * which configuration options are valid for - * widget. */ + enum FrameType type; /* Type of widget, such as TYPE_FRAME. */ char *screenName; /* Screen on which widget is created. Non-null * only for top-levels. Malloc-ed, may be * NULL. */ @@ -98,68 +106,97 @@ typedef struct { #define GOT_FOCUS 4 /* - * The following flag bits are used so that there can be separate - * defaults for some configuration options for frames and toplevels. + * Information used for parsing configuration options. There are + * one common table used by both, one frame table and one toplevel table. + */ + +static Tk_OptionSpec commonOptSpec[] = { + {TK_OPTION_BORDER, "-background", "background", "Background", + DEF_FRAME_BG_COLOR, -1, Tk_Offset(Frame, border), + TK_OPTION_NULL_OK, (ClientData) DEF_FRAME_BG_MONO, 0}, + {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-background", 0}, + {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", + DEF_FRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), + 0, 0, 0}, + {TK_OPTION_STRING, "-colormap", "colormap", "Colormap", + DEF_FRAME_COLORMAP, -1, Tk_Offset(Frame, colormapName), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_BOOLEAN, "-container", "container", "Container", + DEF_FRAME_CONTAINER, -1, Tk_Offset(Frame, isContainer), + 0, 0, 0}, + {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", + DEF_FRAME_CURSOR, -1, Tk_Offset(Frame, cursor), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_PIXELS, "-height", "height", "Height", + DEF_FRAME_HEIGHT, -1, Tk_Offset(Frame, height), + 0, 0, 0}, + {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground", + "HighlightBackground", DEF_FRAME_HIGHLIGHT_BG, -1, + Tk_Offset(Frame, highlightBgColorPtr), 0, 0, 0}, + {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", + DEF_FRAME_HIGHLIGHT, -1, Tk_Offset(Frame, highlightColorPtr), + 0, 0, 0}, + {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", + "HighlightThickness", DEF_FRAME_HIGHLIGHT_WIDTH, -1, + Tk_Offset(Frame, highlightWidth), 0, 0, 0}, + {TK_OPTION_RELIEF, "-relief", "relief", "Relief", + DEF_FRAME_RELIEF, -1, Tk_Offset(Frame, relief), + 0, 0, 0}, + {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", + DEF_FRAME_TAKE_FOCUS, -1, Tk_Offset(Frame, takeFocus), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING, "-visual", "visual", "Visual", + DEF_FRAME_VISUAL, -1, Tk_Offset(Frame, visualName), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_PIXELS, "-width", "width", "Width", + DEF_FRAME_WIDTH, -1, Tk_Offset(Frame, width), + 0, 0, 0}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, 0, 0, 0, 0} +}; + +static Tk_OptionSpec frameOptSpec[] = { + {TK_OPTION_STRING, "-class", "class", "Class", + DEF_FRAME_CLASS, -1, Tk_Offset(Frame, className), + 0, 0, 0}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, 0, 0, (ClientData) commonOptSpec, 0} +}; + +static Tk_OptionSpec toplevelOptSpec[] = { + {TK_OPTION_STRING, "-class", "class", "Class", + DEF_TOPLEVEL_CLASS, -1, Tk_Offset(Frame, className), + 0, 0, 0}, + {TK_OPTION_STRING, "-menu", "menu", "Menu", + DEF_TOPLEVEL_MENU, -1, Tk_Offset(Frame, menuName), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING, "-screen", "screen", "Screen", + DEF_TOPLEVEL_SCREEN, -1, Tk_Offset(Frame, screenName), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING, "-use", "use", "Use", + DEF_FRAME_USE, -1, Tk_Offset(Frame, useThis), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, 0, 0, (ClientData) commonOptSpec, 0} +}; + +/* + * Class names for widgets, indexed by FrameType. + */ + +static char *classNames[] = {"Frame", "Toplevel"}; + +/* + * The following table maps from FrameType to the option template for + * that class of widgets. */ -#define FRAME TK_CONFIG_USER_BIT -#define TOPLEVEL (TK_CONFIG_USER_BIT << 1) -#define BOTH (FRAME | TOPLEVEL) - -static Tk_ConfigSpec configSpecs[] = { - {TK_CONFIG_BORDER, "-background", "background", "Background", - DEF_FRAME_BG_COLOR, Tk_Offset(Frame, border), - BOTH|TK_CONFIG_COLOR_ONLY|TK_CONFIG_NULL_OK}, - {TK_CONFIG_BORDER, "-background", "background", "Background", - DEF_FRAME_BG_MONO, Tk_Offset(Frame, border), - BOTH|TK_CONFIG_MONO_ONLY|TK_CONFIG_NULL_OK}, - {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL, - (char *) NULL, 0, BOTH}, - {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL, - (char *) NULL, 0, BOTH}, - {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_FRAME_BORDER_WIDTH, Tk_Offset(Frame, borderWidth), BOTH}, - {TK_CONFIG_STRING, "-class", "class", "Class", - DEF_FRAME_CLASS, Tk_Offset(Frame, className), FRAME}, - {TK_CONFIG_STRING, "-class", "class", "Class", - DEF_TOPLEVEL_CLASS, Tk_Offset(Frame, className), TOPLEVEL}, - {TK_CONFIG_STRING, "-colormap", "colormap", "Colormap", - DEF_FRAME_COLORMAP, Tk_Offset(Frame, colormapName), - BOTH|TK_CONFIG_NULL_OK}, - {TK_CONFIG_BOOLEAN, "-container", "container", "Container", - DEF_FRAME_CONTAINER, Tk_Offset(Frame, isContainer), BOTH}, - {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", - DEF_FRAME_CURSOR, Tk_Offset(Frame, cursor), BOTH|TK_CONFIG_NULL_OK}, - {TK_CONFIG_PIXELS, "-height", "height", "Height", - DEF_FRAME_HEIGHT, Tk_Offset(Frame, height), BOTH}, - {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground", - "HighlightBackground", DEF_FRAME_HIGHLIGHT_BG, - Tk_Offset(Frame, highlightBgColorPtr), BOTH}, - {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", - DEF_FRAME_HIGHLIGHT, Tk_Offset(Frame, highlightColorPtr), BOTH}, - {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", - "HighlightThickness", - DEF_FRAME_HIGHLIGHT_WIDTH, Tk_Offset(Frame, highlightWidth), BOTH}, - {TK_CONFIG_STRING, "-menu", "menu", "Menu", - DEF_TOPLEVEL_MENU, Tk_Offset(Frame, menuName), - TOPLEVEL|TK_CONFIG_NULL_OK}, - {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", - DEF_FRAME_RELIEF, Tk_Offset(Frame, relief), BOTH}, - {TK_CONFIG_STRING, "-screen", "screen", "Screen", - DEF_TOPLEVEL_SCREEN, Tk_Offset(Frame, screenName), - TOPLEVEL|TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", - DEF_FRAME_TAKE_FOCUS, Tk_Offset(Frame, takeFocus), - BOTH|TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-use", "use", "Use", - DEF_FRAME_USE, Tk_Offset(Frame, useThis), TOPLEVEL|TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-visual", "visual", "Visual", - DEF_FRAME_VISUAL, Tk_Offset(Frame, visualName), - BOTH|TK_CONFIG_NULL_OK}, - {TK_CONFIG_PIXELS, "-width", "width", "Width", - DEF_FRAME_WIDTH, Tk_Offset(Frame, width), BOTH}, - {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, - (char *) NULL, 0, 0} +static Tk_OptionSpec *optionSpecs[] = { + frameOptSpec, + toplevelOptSpec }; /* @@ -167,11 +204,10 @@ static Tk_ConfigSpec configSpecs[] = { */ static int ConfigureFrame _ANSI_ARGS_((Tcl_Interp *interp, - Frame *framePtr, int objc, Tcl_Obj *CONST objv[], - int flags)); + Frame *framePtr, int objc, Tcl_Obj *CONST objv[])); static int CreateFrame _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST argv[], - int toplevel, char *appName)); + enum FrameType type, char *appName)); static void DestroyFrame _ANSI_ARGS_((char *memPtr)); static void DisplayFrame _ANSI_ARGS_((ClientData clientData)); static void FrameCmdDeletedProc _ANSI_ARGS_(( @@ -196,31 +232,31 @@ static void MapFrame _ANSI_ARGS_((ClientData clientData)); * * Side effects: * See the user documentation. These procedures are just wrappers; - * they call ButtonCreate to do all of the real work. + * they call CreateFrame to do all of the real work. * *-------------------------------------------------------------- */ int Tk_FrameObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Main window associated with - * interpreter. */ + ClientData clientData; /* Either NULL or pointer to option table. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ { - return CreateFrame(clientData, interp, objc, objv, 0, (char *) NULL); + return CreateFrame(clientData, interp, objc, objv, TYPE_FRAME, + (char *) NULL); } int Tk_ToplevelObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Main window associated with - * interpreter. */ + ClientData clientData; /* Either NULL or pointer to option table. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ { - return CreateFrame(clientData, interp, objc, objv, 1, (char *) NULL); + return CreateFrame(clientData, interp, objc, objv, TYPE_TOPLEVEL, + (char *) NULL); } /* @@ -228,10 +264,10 @@ Tk_ToplevelObjCmd(clientData, interp, objc, objv) * * TkCreateFrame -- * - * This procedure is invoked to process the "frame" and "toplevel" - * Tcl commands; it is also invoked directly by Tk_Init to create - * a new main window. See the user documentation for the "frame" - * and "toplevel" commands for details on what it does. + * This procedure is the old command procedure for the "frame" + * and "toplevel" commands. Now it is used directly by Tk_Init to + * create a new main window. See the user documentation for the + * "frame" and "toplevel" commands for details on what it does. * * Results: * A standard Tcl result. @@ -244,16 +280,15 @@ Tk_ToplevelObjCmd(clientData, interp, objc, objv) int TkCreateFrame(clientData, interp, argc, argv, toplevel, appName) - ClientData clientData; /* Main window associated with interpreter. - * If we're called by Tk_Init to create a - * new application, then this is NULL. */ + ClientData clientData; /* Either NULL or pointer to option table. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ int toplevel; /* Non-zero means create a toplevel window, * zero means create a frame. */ - char *appName; /* Should only be non-NULL if clientData is - * NULL: gives the base name to use for the + char *appName; /* Should only be non-NULL if there is no main + * window associated with the interpreter. + * Gives the base name to use for the * new application. */ { int result, i; @@ -263,7 +298,8 @@ TkCreateFrame(clientData, interp, argc, argv, toplevel, appName) Tcl_IncrRefCount(objv[i]); } objv[argc] = NULL; - result = CreateFrame(clientData, interp, argc, objv, toplevel, appName); + result = CreateFrame(clientData, interp, argc, objv, + toplevel ? TYPE_TOPLEVEL : TYPE_FRAME, appName); for (i=0; iwidgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(new), FrameWidgetObjCmd, (ClientData) framePtr, FrameCmdDeletedProc); + framePtr->optionTable = optionTable; framePtr->className = NULL; - framePtr->mask = (toplevel) ? TOPLEVEL : FRAME; + framePtr->type = type; framePtr->screenName = NULL; framePtr->visualName = NULL; framePtr->colormapName = NULL; + framePtr->menuName = NULL; framePtr->colormap = colormap; framePtr->border = NULL; framePtr->borderWidth = 0; @@ -446,7 +510,6 @@ CreateFrame(clientData, interp, objc, objv, toplevel, appName) framePtr->isContainer = 0; framePtr->useThis = NULL; framePtr->flags = 0; - framePtr->menuName = NULL; /* * Store backreference to frame widget in window structure. @@ -454,23 +517,25 @@ CreateFrame(clientData, interp, objc, objv, toplevel, appName) Tk_SetClassProcs(new, NULL, (ClientData) framePtr); mask = ExposureMask | StructureNotifyMask | FocusChangeMask; - if (toplevel) { + if (type == TYPE_TOPLEVEL) { mask |= ActivateMask; } Tk_CreateEventHandler(new, mask, FrameEventProc, (ClientData) framePtr); - if (ConfigureFrame(interp, framePtr, objc-2, objv+2, 0) != TCL_OK) { + if ((Tk_InitOptions(interp, (char *) framePtr, optionTable, new) + != TCL_OK) || + (ConfigureFrame(interp, framePtr, objc-2, objv+2) != TCL_OK)) { goto error; } if ((framePtr->isContainer)) { if (framePtr->useThis == NULL) { TkpMakeContainer(framePtr->tkwin); } else { - Tcl_AppendResult(interp,"A window cannot have both the -use ", - "and the -container option set."); + Tcl_AppendResult(interp, "A window cannot have both the -use ", + "and the -container option set.", (char *) NULL); return TCL_ERROR; } } - if (toplevel) { + if (type == TYPE_TOPLEVEL) { Tcl_DoWhenIdle(MapFrame, (ClientData) framePtr); } Tcl_SetResult(interp, Tk_PathName(new), TCL_STATIC); @@ -518,6 +583,7 @@ FrameWidgetObjCmd(clientData, interp, objc, objv) int result = TCL_OK, index; size_t length; int c, i; + Tcl_Obj *objPtr; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); @@ -535,17 +601,28 @@ FrameWidgetObjCmd(clientData, interp, objc, objv) result = TCL_ERROR; goto done; } - result = Tk_ConfigureValue(interp, framePtr->tkwin, configSpecs, - (char *) framePtr, Tcl_GetString(objv[2]), framePtr->mask); + objPtr = Tk_GetOptionValue(interp, (char *) framePtr, + framePtr->optionTable, objv[2], framePtr->tkwin); + if (objPtr == NULL) { + result = TCL_ERROR; + goto done; + } else { + Tcl_SetObjResult(interp, objPtr); + } break; } case FRAME_CONFIGURE: { - if (objc == 2) { - result = Tk_ConfigureInfo(interp, framePtr->tkwin, configSpecs, - (char *) framePtr, (char *) NULL, framePtr->mask); - } else if (objc == 3) { - result = Tk_ConfigureInfo(interp, framePtr->tkwin, configSpecs, - (char *) framePtr, Tcl_GetString(objv[2]), framePtr->mask); + if (objc <= 3) { + objPtr = Tk_GetOptionInfo(interp, (char *) framePtr, + framePtr->optionTable, + (objc == 3) ? objv[2] : (Tcl_Obj *) NULL, + framePtr->tkwin); + if (objPtr == NULL) { + result = TCL_ERROR; + goto done; + } else { + Tcl_SetObjResult(interp, objPtr); + } } else { /* * Don't allow the options -class, -colormap, -container, @@ -560,17 +637,17 @@ FrameWidgetObjCmd(clientData, interp, objc, objv) c = arg[1]; if (((c == 'c') && (strncmp(arg, "-class", length) == 0) && (length >= 2)) - || ((c == 'c') && (framePtr->mask == TOPLEVEL) + || ((c == 'c') && (framePtr->type == TYPE_TOPLEVEL) && (strncmp(arg, "-colormap", length) == 0) && (length >= 3)) || ((c == 'c') && (strncmp(arg, "-container", length) == 0) && (length >= 3)) - || ((c == 's') && (framePtr->mask == TOPLEVEL) + || ((c == 's') && (framePtr->type == TYPE_TOPLEVEL) && (strncmp(arg, "-screen", length) == 0)) - || ((c == 'u') && (framePtr->mask == TOPLEVEL) + || ((c == 'u') && (framePtr->type == TYPE_TOPLEVEL) && (strncmp(arg, "-use", length) == 0)) - || ((c == 'v') && (framePtr->mask == TOPLEVEL) + || ((c == 'v') && (framePtr->type == TYPE_TOPLEVEL) && (strncmp(arg, "-visual", length) == 0))) { Tcl_AppendResult(interp, "can't modify ", arg, " option after widget is created", (char *) NULL); @@ -578,8 +655,7 @@ FrameWidgetObjCmd(clientData, interp, objc, objv) goto done; } } - result = ConfigureFrame(interp, framePtr, objc-2, objv+2, - TK_CONFIG_ARGV_ONLY); + result = ConfigureFrame(interp, framePtr, objc-2, objv+2); } break; } @@ -614,8 +690,6 @@ DestroyFrame(memPtr) { register Frame *framePtr = (Frame *) memPtr; - Tk_FreeOptions(configSpecs, (char *) framePtr, framePtr->display, - framePtr->mask); if (framePtr->colormap != None) { Tk_FreeColormap(framePtr->display, framePtr->colormap); } @@ -644,16 +718,16 @@ DestroyFrame(memPtr) */ static int -ConfigureFrame(interp, framePtr, objc, objv, flags) +ConfigureFrame(interp, framePtr, objc, objv) Tcl_Interp *interp; /* Used for error reporting. */ register Frame *framePtr; /* Information about widget; may or may * not already have values for some fields. */ int objc; /* Number of valid entries in objv. */ Tcl_Obj *CONST objv[]; /* Arguments. */ - int flags; /* Flags to pass to Tk_ConfigureWidget. */ { + Tk_SavedOptions savedOptions; char *oldMenuName; - + /* * Need the old menubar name for the menu code to delete it. */ @@ -665,12 +739,21 @@ ConfigureFrame(interp, framePtr, objc, objv, flags) strcpy(oldMenuName, framePtr->menuName); } - if (Tk_ConfigureWidget(interp, framePtr->tkwin, configSpecs, - objc, (char **) objv, (char *) framePtr, - flags | framePtr->mask | TK_CONFIG_OBJS) != TCL_OK) { + if (Tk_SetOptions(interp, (char *) framePtr, + framePtr->optionTable, objc, objv, + framePtr->tkwin, &savedOptions, (int *) NULL) != TCL_OK) { + if (oldMenuName != NULL) { + ckfree(oldMenuName); + } return TCL_ERROR; + } else { + Tk_FreeSavedOptions(&savedOptions); } + /* + * A few of the options require additional processing. + */ + if (((oldMenuName == NULL) && (framePtr->menuName != NULL)) || ((oldMenuName != NULL) && (framePtr->menuName == NULL)) || ((oldMenuName != NULL) && (framePtr->menuName != NULL) @@ -678,7 +761,11 @@ ConfigureFrame(interp, framePtr, objc, objv, flags) TkSetWindowMenuBar(interp, framePtr->tkwin, oldMenuName, framePtr->menuName); } - + + if (oldMenuName != NULL) { + ckfree(oldMenuName); + } + if (framePtr->border != NULL) { Tk_SetBackgroundFromBorder(framePtr->tkwin, framePtr->border); } else { @@ -695,10 +782,6 @@ ConfigureFrame(interp, framePtr, objc, objv, flags) framePtr->height); } - if (oldMenuName != NULL) { - ckfree(oldMenuName); - } - if (Tk_IsMapped(framePtr->tkwin)) { if (!(framePtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayFrame, (ClientData) framePtr); @@ -812,7 +895,15 @@ FrameEventProc(clientData, eventPtr) * could be gone by then. To do so, delete the event handler * explicitly (normally it's done implicitly by Tk_DestroyWindow). */ - + + /* + * Since the tkwin pointer will be gone when we reach + * DestroyFrame, we must free all options now. + */ + + Tk_FreeConfigOptions((char *) framePtr, framePtr->optionTable, + framePtr->tkwin); + Tk_DeleteEventHandler(framePtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, FrameEventProc, (ClientData) framePtr); @@ -891,6 +982,14 @@ FrameCmdDeletedProc(clientData) */ if (tkwin != NULL) { + /* + * Some options need tkwin to be freed, so we free them here, + * before setting tkwin to NULL. + */ + + Tk_FreeConfigOptions((char *) framePtr, framePtr->optionTable, + framePtr->tkwin); + framePtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } diff --git a/generic/tkWindow.c b/generic/tkWindow.c index e6fccf9..6a33f44 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.29 2000/11/22 01:49:38 ericm Exp $ + * RCS: @(#) $Id: tkWindow.c,v 1.30 2001/05/28 16:56:02 pspjuth Exp $ */ #include "tkPort.h" @@ -137,7 +137,7 @@ static TkCmd commands[] = { {"canvas", NULL, Tk_CanvasObjCmd, 1, 1}, {"checkbutton", NULL, Tk_CheckbuttonObjCmd, 1, 0}, {"entry", NULL, Tk_EntryObjCmd, 1, 0}, - {"frame", NULL, Tk_FrameObjCmd, 1, 1}, + {"frame", NULL, Tk_FrameObjCmd, 1, 0}, {"label", NULL, Tk_LabelObjCmd, 1, 0}, {"listbox", NULL, Tk_ListboxObjCmd, 1, 0}, {"menubutton", NULL, Tk_MenubuttonObjCmd, 1, 0}, @@ -147,7 +147,7 @@ static TkCmd commands[] = { {"scrollbar", Tk_ScrollbarCmd, NULL, 1, 1}, {"spinbox", NULL, Tk_SpinboxObjCmd, 1, 0}, {"text", Tk_TextCmd, NULL, 1, 1}, - {"toplevel", NULL, Tk_ToplevelObjCmd, 0, 1}, + {"toplevel", NULL, Tk_ToplevelObjCmd, 0, 0}, /* * Misc. diff --git a/tests/frame.test b/tests/frame.test index 1b28954..8f5644b 100644 --- a/tests/frame.test +++ b/tests/frame.test @@ -7,7 +7,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: frame.test,v 1.4 1999/12/14 06:53:13 hobbs Exp $ +# RCS: @(#) $Id: frame.test,v 1.5 2001/05/28 16:56:02 pspjuth Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { source [file join [pwd] [file dirname [info script]] defs.tcl] @@ -105,7 +105,7 @@ foreach test { {-highlightcolor #123456 #123456 non-existent {unknown color name "non-existent"}} {-highlightthickness 6 6 badValue {bad screen distance "badValue"}} - {-relief ridge ridge badValue {bad relief type "badValue": must be flat, groove, raised, ridge, solid, or sunken}} + {-relief ridge ridge badValue {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}} {-takefocus "any string" "any string" {} {}} {-width 32 32 badValue {bad screen distance "badValue"}} } { @@ -178,11 +178,22 @@ test frame-2.9 {toplevel configuration options} { catch {destroy .t} list [catch {toplevel .t -width 200 -height 100 -screen bogus} msg] $msg } {1 {couldn't connect to display "bogus"}} +test frame-2.10 {toplevel configuration options} { + catch {destroy .t} + catch {destroy .x} + toplevel .t -container 1 -width 300 -height 120 + wm geometry .t +0+0 + set result [list \ + [catch {toplevel .x -container 1 -use [winfo id .t]} msg] $msg] + destroy .t .x + set result +} {1 {A window cannot have both the -use and the -container option set.}} + catch {destroy .t} toplevel .t -width 300 -height 150 wm geometry .t +0+0 update -set i 8 +set i 11 foreach test { {-background #ff0000 #ff0000 non-existent {unknown color name "non-existent"}} @@ -195,17 +206,17 @@ foreach test { {-highlightcolor #123456 #123456 non-existent {unknown color name "non-existent"}} {-highlightthickness 3 3 badValue {bad screen distance "badValue"}} - {-relief ridge ridge badValue {bad relief type "badValue": must be flat, groove, raised, ridge, solid, or sunken}} + {-relief ridge ridge badValue {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}} {-width 32 32 badValue {bad screen distance "badValue"}} } { set name [lindex $test 0] - test frame-2.$i {frame configuration options} { + test frame-2.$i {toplevel configuration options} { .t configure $name [lindex $test 1] lindex [.t configure $name] 4 } [lindex $test 2] incr i if {[lindex $test 3] != ""} { - test frame-2.$i {frame configuration options} { + test frame-2.$i {toplevel configuration options} { list [catch {.t configure $name [lindex $test 3]} msg] $msg } [list 1 [lindex $test 4]] } -- cgit v0.12