diff options
Diffstat (limited to 'generic/tkFrame.c')
-rw-r--r-- | generic/tkFrame.c | 365 |
1 files changed, 232 insertions, 133 deletions
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; i<argc; i++) { Tcl_DecrRefCount(objv[i]); } @@ -272,21 +308,20 @@ TkCreateFrame(clientData, interp, argc, argv, toplevel, appName) } static int -CreateFrame(clientData, interp, objc, objv, 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. */ +CreateFrame(clientData, interp, objc, objv, type, appName) + 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. */ - 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 + enum FrameType type; /* What widget type to create. */ + char *appName; /* Should only be non-NULL if there are no + * Main window associated with the interpreter. + * Gives the base name to use for the * new application. */ { - Tk_Window tkwin = (Tk_Window) clientData; + Tk_Window tkwin; Frame *framePtr; + Tk_OptionTable optionTable; Tk_Window new; char *className, *screenName, *visualName, *colormapName, *arg, *useOption; int i, c, depth; @@ -295,6 +330,25 @@ CreateFrame(clientData, interp, objc, objv, toplevel, appName) Colormap colormap; Visual *visual; + optionTable = (Tk_OptionTable) clientData; + if (optionTable == NULL) { + Tcl_CmdInfo info; + char *name; + + /* + * We haven't created the option table for this widget class + * yet. Do it now and save the table as the clientData for + * the command, so we'll have access to it in future + * invocations of the command. + */ + + optionTable = Tk_CreateOptionTable(interp, optionSpecs[type]); + name = Tcl_GetString(objv[0]); + Tcl_GetCommandInfo(interp, name, &info); + info.objClientData = (ClientData) optionTable; + Tcl_SetCommandInfo(interp, name, &info); + } + if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); return TCL_ERROR; @@ -321,10 +375,10 @@ CreateFrame(clientData, interp, objc, objv, toplevel, appName) } else if ((c == 'c') && (strncmp(arg, "-colormap", length) == 0)) { colormapName = Tcl_GetString(objv[i+1]); - } else if ((c == 's') && toplevel + } else if ((c == 's') && (type == TYPE_TOPLEVEL) && (strncmp(arg, "-screen", length) == 0)) { screenName = Tcl_GetString(objv[i+1]); - } else if ((c == 'u') && toplevel + } else if ((c == 'u') && (type == TYPE_TOPLEVEL) && (strncmp(arg, "-use", length) == 0)) { useOption = Tcl_GetString(objv[i+1]); } else if ((c == 'v') @@ -349,8 +403,16 @@ CreateFrame(clientData, interp, objc, objv, toplevel, appName) */ if (screenName == NULL) { - screenName = (toplevel) ? "" : NULL; + screenName = (type == TYPE_TOPLEVEL) ? "" : NULL; } + + /* + * Main window associated with interpreter. + * If we're called by Tk_Init to create a + * new application, then this is NULL. + */ + + tkwin = Tk_MainWindow(interp); if (tkwin != NULL) { new = Tk_CreateWindowFromPath(interp, tkwin, Tcl_GetString(objv[1]), screenName); @@ -370,7 +432,7 @@ CreateFrame(clientData, interp, objc, objv, toplevel, appName) if (className == NULL) { className = Tk_GetOption(new, "class", "Class"); if (className == NULL) { - className = (toplevel) ? "Toplevel" : "Frame"; + className = classNames[type]; } } Tk_SetClass(new, className); @@ -410,7 +472,7 @@ CreateFrame(clientData, interp, objc, objv, toplevel, appName) * doesn't request a size for itself. */ - if (toplevel) { + if (type == TYPE_TOPLEVEL) { Tk_GeometryRequest(new, 200, 200); } @@ -427,11 +489,13 @@ CreateFrame(clientData, interp, objc, objv, toplevel, appName) framePtr->widgetCmd = 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); } |