From c0bb952520e32d12b6acd32d4d15b42dc32c5460 Mon Sep 17 00:00:00 2001 From: hobbs Date: Wed, 29 Aug 2001 23:22:24 +0000 Subject: * tests/config.test: added config-14.1 to test namespace import evaluation of widgets. * generic/tkButton.c (ButtonCreate): * generic/tkFrame.c (CreateFrame): * generic/tkMenubutton.c (Tk_MenubuttonObjCmd): * generic/tkPlace.c (Tk_PlaceObjCmd): * generic/tkScale.c (Tk_ScaleObjCmd): * generic/tkMessage.c (Tk_MessageObjCmd): * generic/tkEntry.c (Tk_EntryObjCmd, Tk_SpinboxObjCmd): * generic/tkSquare.c (SquareObjCmd): redid the handling of optionTables in widgets to allow them to be imported into other namespaces. [Bug #456632] --- ChangeLog | 15 ++++++++++ generic/tkButton.c | 38 ++++++++++++------------ generic/tkEntry.c | 58 +++++++++++------------------------- generic/tkFrame.c | 67 +++++++++++++----------------------------- generic/tkListbox.c | 79 +++++++++++++------------------------------------- generic/tkMenubutton.c | 41 +++++++++----------------- generic/tkMessage.c | 30 ++++++------------- generic/tkPlace.c | 29 ++++++------------ generic/tkScale.c | 30 ++++++------------- generic/tkSquare.c | 70 +++++++++++++++++--------------------------- tests/config.test | 22 ++++++++++++-- 11 files changed, 177 insertions(+), 302 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc6c899..b5b7daa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2001-08-29 Jeff Hobbs + + * tests/config.test: added config-14.1 to test namespace import + evaluation of widgets. + * generic/tkButton.c (ButtonCreate): + * generic/tkFrame.c (CreateFrame): + * generic/tkMenubutton.c (Tk_MenubuttonObjCmd): + * generic/tkPlace.c (Tk_PlaceObjCmd): + * generic/tkScale.c (Tk_ScaleObjCmd): + * generic/tkMessage.c (Tk_MessageObjCmd): + * generic/tkEntry.c (Tk_EntryObjCmd, Tk_SpinboxObjCmd): + * generic/tkSquare.c (SquareObjCmd): redid the handling of + optionTables in widgets to allow them to be imported into other + namespaces. [Bug #456632] + 2001-08-28 Jeff Hobbs * win/tkWinDialog.c (ChooseDirectoryHookProc): work-around for MS diff --git a/generic/tkButton.c b/generic/tkButton.c index 23bc057..3e835fb 100644 --- a/generic/tkButton.c +++ b/generic/tkButton.c @@ -11,12 +11,17 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkButton.c,v 1.12 2000/11/22 01:49:37 ericm Exp $ + * RCS: @(#) $Id: tkButton.c,v 1.13 2001/08/29 23:22:24 hobbs Exp $ */ #include "tkButton.h" #include "default.h" +typedef struct ThreadSpecificData { + int defaultsInitialized; +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; + /* * Class names for buttons, indexed by one of the type values defined * in tkButton.h. @@ -607,8 +612,7 @@ Tk_RadiobuttonObjCmd(clientData, interp, objc, objv) static int ButtonCreate(clientData, interp, objc, objv, type) - ClientData clientData; /* Option table for this widget class, or - * NULL if not created yet. */ + ClientData clientData; /* NULL. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument values. */ @@ -619,25 +623,12 @@ ButtonCreate(clientData, interp, objc, objv, type) TkButton *butPtr; Tk_OptionTable optionTable; Tk_Window tkwin; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - 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. - */ - + if (!tsdPtr->defaultsInitialized) { TkpButtonSetDefaults(optionSpecs[type]); - 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); + tsdPtr->defaultsInitialized = 1; } if (objc < 2) { @@ -655,6 +646,13 @@ ButtonCreate(clientData, interp, objc, objv, type) return TCL_ERROR; } + /* + * Create the option table for this widget class. If it has already + * been created, the cached pointer will be returned. + */ + + optionTable = Tk_CreateOptionTable(interp, optionSpecs[type]); + Tk_SetClass(tkwin, classNames[type]); butPtr = TkpCreateButton(tkwin); diff --git a/generic/tkEntry.c b/generic/tkEntry.c index 35464da..233fd90 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.21 2001/07/03 06:16:19 hobbs Exp $ + * RCS: @(#) $Id: tkEntry.c,v 1.22 2001/08/29 23:22:24 hobbs Exp $ */ #include "tkInt.h" @@ -762,7 +762,7 @@ static Tk_ClassProcs entryClass = { int Tk_EntryObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Either NULL or pointer to option table. */ + ClientData clientData; /* NULL. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ @@ -771,25 +771,6 @@ Tk_EntryObjCmd(clientData, interp, objc, objv) Tk_OptionTable optionTable; Tk_Window tkwin; - 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, entryOptSpec); - 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; @@ -802,6 +783,13 @@ Tk_EntryObjCmd(clientData, interp, objc, objv) } /* + * Create the option table for this widget class. If it has already + * been created, Tk will return the cached value. + */ + + optionTable = Tk_CreateOptionTable(interp, entryOptSpec); + + /* * Initialize the fields of the structure that won't be initialized * by ConfigureEntry, or that ConfigureEntry requires to be * initialized already (e.g. resource pointers). Only the non-NULL/0 @@ -3696,7 +3684,7 @@ ExpandPercents(entryPtr, before, change, new, index, type, dsPtr) int Tk_SpinboxObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Either NULL or pointer to option table. */ + ClientData clientData; /* NULL. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ @@ -3706,25 +3694,6 @@ Tk_SpinboxObjCmd(clientData, interp, objc, objv) Tk_OptionTable optionTable; Tk_Window tkwin; - 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, sbOptSpec); - 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; @@ -3737,6 +3706,13 @@ Tk_SpinboxObjCmd(clientData, interp, objc, objv) } /* + * Create the option table for this widget class. If it has already + * been created, Tk will return the cached value. + */ + + optionTable = Tk_CreateOptionTable(interp, sbOptSpec); + + /* * Initialize the fields of the structure that won't be initialized * by ConfigureEntry, or that ConfigureEntry requires to be * initialized already (e.g. resource pointers). Only the non-NULL/0 diff --git a/generic/tkFrame.c b/generic/tkFrame.c index 6b70e62..9c6f84b 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.8 2001/05/28 16:56:02 pspjuth Exp $ + * RCS: @(#) $Id: tkFrame.c,v 1.9 2001/08/29 23:22:24 hobbs Exp $ */ #include "default.h" @@ -309,7 +309,7 @@ TkCreateFrame(clientData, interp, argc, argv, toplevel, appName) static int CreateFrame(clientData, interp, objc, objv, type, appName) - ClientData clientData; /* Either NULL or pointer to option table. */ + ClientData clientData; /* NULL. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ @@ -330,31 +330,19 @@ CreateFrame(clientData, interp, objc, objv, type, 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; } /* + * Create the option table for this widget class. If it has already + * been created, the cached pointer will be returned. + */ + + optionTable = Tk_CreateOptionTable(interp, optionSpecs[type]); + + /* * Pre-process the argument list. Scan through it to find any * "-class", "-screen", "-visual", and "-colormap" options. These * arguments need to be processed specially, before the window @@ -482,34 +470,19 @@ CreateFrame(clientData, interp, objc, objv, type, appName) * in the widget record from the special options. */ - framePtr = (Frame *) ckalloc(sizeof(Frame)); - framePtr->tkwin = new; - framePtr->display = Tk_Display(new); - framePtr->interp = interp; - framePtr->widgetCmd = Tcl_CreateObjCommand(interp, + framePtr = (Frame *) ckalloc(sizeof(Frame)); + memset((void *) framePtr, 0, (sizeof(Frame))); + framePtr->tkwin = new; + framePtr->display = Tk_Display(new); + framePtr->interp = interp; + framePtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(new), FrameWidgetObjCmd, (ClientData) framePtr, FrameCmdDeletedProc); - framePtr->optionTable = optionTable; - framePtr->className = NULL; - framePtr->type = type; - framePtr->screenName = NULL; - framePtr->visualName = NULL; - framePtr->colormapName = NULL; - framePtr->menuName = NULL; - framePtr->colormap = colormap; - framePtr->border = NULL; - framePtr->borderWidth = 0; - framePtr->relief = TK_RELIEF_FLAT; - framePtr->highlightWidth = 0; - framePtr->highlightBgColorPtr = NULL; - framePtr->highlightColorPtr = NULL; - framePtr->width = 0; - framePtr->height = 0; - framePtr->cursor = None; - framePtr->takeFocus = NULL; - framePtr->isContainer = 0; - framePtr->useThis = NULL; - framePtr->flags = 0; + framePtr->optionTable = optionTable; + framePtr->type = type; + framePtr->colormap = colormap; + framePtr->relief = TK_RELIEF_FLAT; + framePtr->cursor = None; /* * Store backreference to frame widget in window structure. diff --git a/generic/tkListbox.c b/generic/tkListbox.c index 356f3af..a939479 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.21 2001/07/03 06:16:19 hobbs Exp $ + * RCS: @(#) $Id: tkListbox.c,v 1.22 2001/08/29 23:22:24 hobbs Exp $ */ #include "tkPort.h" @@ -460,7 +460,7 @@ static Tk_ClassProcs listboxClass = { int Tk_ListboxObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Either NULL or pointer to option table */ + ClientData clientData; /* NULL. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ @@ -469,18 +469,28 @@ Tk_ListboxObjCmd(clientData, interp, objc, objv) Tk_Window tkwin; ListboxOptionTables *optionTables; - optionTables = (ListboxOptionTables *)clientData; - if (optionTables == NULL) { - Tcl_CmdInfo info; - char *name; + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); + return TCL_ERROR; + } + + tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), + Tcl_GetString(objv[1]), (char *) NULL); + if (tkwin == NULL) { + return TCL_ERROR; + } + optionTables = (ListboxOptionTables *) + Tcl_GetAssocData(interp, "ListboxOptionTables", NULL); + if (optionTables == NULL) { /* * We haven't created the option tables for this widget class yet. * Do it now and save the a pointer to them as the ClientData for * the command, so future invocations will have access to it. */ - optionTables = - (ListboxOptionTables *) ckalloc(sizeof(ListboxOptionTables)); + + optionTables = (ListboxOptionTables *) + ckalloc(sizeof(ListboxOptionTables)); /* Set up an exit handler to free the optionTables struct */ Tcl_SetAssocData(interp, "ListboxOptionTables", DestroyListboxOptionTables, (ClientData) optionTables); @@ -490,23 +500,6 @@ Tk_ListboxObjCmd(clientData, interp, objc, objv) Tk_CreateOptionTable(interp, optionSpecs); optionTables->itemAttrOptionTable = Tk_CreateOptionTable(interp, itemAttrOptionSpecs); - - /* Store a pointer to the tables as the ClientData for the command */ - name = Tcl_GetString(objv[0]); - Tcl_GetCommandInfo(interp, name, &info); - info.objClientData = (ClientData) optionTables; - Tcl_SetCommandInfo(interp, name, &info); - } - - if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); - return TCL_ERROR; - } - - tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), - Tcl_GetString(objv[1]), (char *) NULL); - if (tkwin == NULL) { - return TCL_ERROR; } /* @@ -515,6 +508,8 @@ Tk_ListboxObjCmd(clientData, interp, objc, objv) * initialized already (e.g. resource pointers). */ listPtr = (Listbox *) ckalloc(sizeof(Listbox)); + memset((void *) listPtr, 0, (sizeof(Listbox))); + listPtr->tkwin = tkwin; listPtr->display = Tk_Display(tkwin); listPtr->interp = interp; @@ -523,56 +518,22 @@ Tk_ListboxObjCmd(clientData, interp, objc, objv) (ClientData) listPtr, ListboxCmdDeletedProc); listPtr->optionTable = optionTables->listboxOptionTable; listPtr->itemAttrOptionTable = optionTables->itemAttrOptionTable; - listPtr->listVarName = NULL; - listPtr->listObj = NULL; listPtr->selection = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(listPtr->selection, TCL_ONE_WORD_KEYS); listPtr->itemAttrTable = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(listPtr->itemAttrTable, TCL_ONE_WORD_KEYS); - listPtr->nElements = 0; - listPtr->normalBorder = NULL; - listPtr->borderWidth = 0; listPtr->relief = TK_RELIEF_RAISED; - listPtr->highlightWidth = 0; - listPtr->highlightBgColorPtr = NULL; - listPtr->highlightColorPtr = NULL; - listPtr->inset = 0; - listPtr->tkfont = NULL; - listPtr->fgColorPtr = NULL; - listPtr->dfgColorPtr = NULL; listPtr->textGC = None; - listPtr->selBorder = NULL; - listPtr->selBorderWidth = 0; listPtr->selFgColorPtr = None; listPtr->selTextGC = None; - listPtr->width = 0; - listPtr->height = 0; - listPtr->lineHeight = 0; - listPtr->topIndex = 0; listPtr->fullLines = 1; - listPtr->partialLine = 0; - listPtr->setGrid = 0; - listPtr->maxWidth = 0; listPtr->xScrollUnit = 1; - listPtr->xOffset = 0; - listPtr->selectMode = NULL; - listPtr->numSelected = 0; - listPtr->selectAnchor = 0; listPtr->exportSelection = 1; - listPtr->active = 0; - listPtr->scanMarkX = 0; - listPtr->scanMarkY = 0; - listPtr->scanMarkXOffset = 0; - listPtr->scanMarkYIndex = 0; listPtr->cursor = None; - listPtr->takeFocus = NULL; - listPtr->xScrollCmd = NULL; - listPtr->yScrollCmd = NULL; listPtr->state = STATE_NORMAL; listPtr->gray = None; - listPtr->flags = 0; /* * Keep a hold of the associated tkwin until we destroy the listbox, diff --git a/generic/tkMenubutton.c b/generic/tkMenubutton.c index a685f9d..815837f 100644 --- a/generic/tkMenubutton.c +++ b/generic/tkMenubutton.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: tkMenubutton.c,v 1.6 2001/05/21 14:07:33 tmh Exp $ + * RCS: @(#) $Id: tkMenubutton.c,v 1.7 2001/08/29 23:22:24 hobbs Exp $ */ #include "tkMenubutton.h" @@ -205,8 +205,7 @@ static void DestroyMenuButton _ANSI_ARGS_((char *memPtr)); int Tk_MenubuttonObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Either NULL or pointer to - * option table. */ + ClientData clientData; /* NULL. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ @@ -215,25 +214,6 @@ Tk_MenubuttonObjCmd(clientData, interp, objc, objv) Tk_OptionTable optionTable; Tk_Window tkwin; - 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); - 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; @@ -243,12 +223,19 @@ Tk_MenubuttonObjCmd(clientData, interp, objc, objv) * Create the new window. */ - tkwin = Tk_CreateWindowFromPath(interp, - Tk_MainWindow(interp), Tcl_GetString(objv[1]), (char *) NULL); + tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), + Tcl_GetString(objv[1]), (char *) NULL); if (tkwin == NULL) { return TCL_ERROR; } + /* + * Create the option table for this widget class. If it has already + * been created, the cached pointer will be returned. + */ + + optionTable = Tk_CreateOptionTable(interp, optionSpecs); + Tk_SetClass(tkwin, "Menubutton"); mbPtr = TkpCreateMenuButton(tkwin); @@ -313,8 +300,7 @@ Tk_MenubuttonObjCmd(clientData, interp, objc, objv) ExposureMask|StructureNotifyMask|FocusChangeMask, MenuButtonEventProc, (ClientData) mbPtr); - if (Tk_InitOptions(interp, (char *) mbPtr, optionTable, tkwin) - != TCL_OK) { + if (Tk_InitOptions(interp, (char *) mbPtr, optionTable, tkwin) != TCL_OK) { Tk_DestroyWindow(mbPtr->tkwin); return TCL_ERROR; } @@ -324,8 +310,7 @@ Tk_MenubuttonObjCmd(clientData, interp, objc, objv) return TCL_ERROR; } - Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(mbPtr->tkwin), - -1); + Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(mbPtr->tkwin), -1); return TCL_OK; } diff --git a/generic/tkMessage.c b/generic/tkMessage.c index 5a3b3e1..1e82ba5 100644 --- a/generic/tkMessage.c +++ b/generic/tkMessage.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: tkMessage.c,v 1.9 2000/11/22 01:49:38 ericm Exp $ + * RCS: @(#) $Id: tkMessage.c,v 1.10 2001/08/29 23:22:24 hobbs Exp $ */ #include "tkPort.h" @@ -221,8 +221,7 @@ static Tk_ClassProcs messageClass = { int Tk_MessageObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Main window associated with - * interpreter. */ + ClientData clientData; /* NULL. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument strings. */ @@ -231,24 +230,6 @@ Tk_MessageObjCmd(clientData, interp, objc, objv) Tk_OptionTable optionTable; Tk_Window tkwin; - 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); - 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; @@ -260,6 +241,13 @@ Tk_MessageObjCmd(clientData, interp, objc, objv) return TCL_ERROR; } + /* + * Create the option table for this widget class. If it has already + * been created, the cached pointer will be returned. + */ + + optionTable = Tk_CreateOptionTable(interp, optionSpecs); + msgPtr = (Message *) ckalloc(sizeof(Message)); memset(msgPtr, 0, (size_t) sizeof(Message)); diff --git a/generic/tkPlace.c b/generic/tkPlace.c index 2214926..23cd783 100644 --- a/generic/tkPlace.c +++ b/generic/tkPlace.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: tkPlace.c,v 1.8 2000/08/10 00:21:07 ericm Exp $ + * RCS: @(#) $Id: tkPlace.c,v 1.9 2001/08/29 23:22:24 hobbs Exp $ */ #include "tkPort.h" @@ -199,7 +199,7 @@ static void UnlinkSlave _ANSI_ARGS_((Slave *slavePtr)); int Tk_PlaceObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Main window associated with interpreter. */ + ClientData clientData; /* NULL. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ @@ -208,7 +208,7 @@ Tk_PlaceObjCmd(clientData, interp, objc, objv) Slave *slavePtr; char *string; TkDisplay *dispPtr; - Tk_OptionTable optionTable = (Tk_OptionTable)clientData; + Tk_OptionTable optionTable; static char *optionStrings[] = { "configure", "forget", "info", "slaves", (char *) NULL }; enum options { PLACE_CONFIGURE, PLACE_FORGET, PLACE_INFO, PLACE_SLAVES }; @@ -220,23 +220,12 @@ Tk_PlaceObjCmd(clientData, interp, objc, objv) return TCL_ERROR; } - 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); - name = Tcl_GetString(objv[0]); - Tcl_GetCommandInfo(interp, name, &info); - info.objClientData = (ClientData) optionTable; - Tcl_SetCommandInfo(interp, name, &info); - } + /* + * Create the option table for this widget class. If it has already + * been created, the cached pointer will be returned. + */ + + optionTable = Tk_CreateOptionTable(interp, optionSpecs); /* * Handle special shortcut where window name is first argument. diff --git a/generic/tkScale.c b/generic/tkScale.c index 8327ab7..1be68ec 100644 --- a/generic/tkScale.c +++ b/generic/tkScale.c @@ -18,7 +18,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkScale.c,v 1.13 2000/11/22 01:49:38 ericm Exp $ + * RCS: @(#) $Id: tkScale.c,v 1.14 2001/08/29 23:22:24 hobbs Exp $ */ #include "tkPort.h" @@ -211,7 +211,7 @@ static Tk_ClassProcs scaleClass = { int Tk_ScaleObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Either NULL or pointer to option table. */ + ClientData clientData; /* NULL. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument values. */ @@ -220,25 +220,6 @@ Tk_ScaleObjCmd(clientData, interp, objc, objv) Tk_OptionTable optionTable; Tk_Window tkwin; - 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); - 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; @@ -250,6 +231,13 @@ Tk_ScaleObjCmd(clientData, interp, objc, objv) return TCL_ERROR; } + /* + * Create the option table for this widget class. If it has already + * been created, the cached pointer will be returned. + */ + + optionTable = Tk_CreateOptionTable(interp, optionSpecs); + Tk_SetClass(tkwin, "Scale"); scalePtr = TkpCreateScale(tkwin); diff --git a/generic/tkSquare.c b/generic/tkSquare.c index a835e31..1a2704d 100644 --- a/generic/tkSquare.c +++ b/generic/tkSquare.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: tkSquare.c,v 1.3 1999/04/16 01:51:22 stanton Exp $ + * RCS: @(#) $Id: tkSquare.c,v 1.4 2001/08/29 23:22:24 hobbs Exp $ */ #include "tkPort.h" @@ -60,7 +60,7 @@ typedef struct { * Information used for argv parsing. */ -static Tk_OptionSpec configSpecs[] = { +static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_BORDER, "-background", "background", "Background", "#d9d9d9", Tk_Offset(Square, bgBorderPtr), -1, 0, (ClientData) "white"}, @@ -126,32 +126,14 @@ static int SquareWidgetCmd _ANSI_ARGS_((ClientData clientData, int SquareObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Main window associated with - * interpreter. */ + ClientData clientData; /* NULL. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj * CONST objv[]; /* Argument objects. */ { Square *squarePtr; Tk_Window tkwin; - Tk_OptionTable optionTable = (Tk_OptionTable) clientData; - Tcl_CmdInfo info; - char *commandName; - - if (optionTable == NULL) { - /* - * The first time this procedure is invoked, optionTable will - * be NULL. We then create the option table from the template - * and store the table pointer as the command's clinical so - * we'll have easy access to it in the future. - */ - - optionTable = Tk_CreateOptionTable(interp, configSpecs); - commandName = Tcl_GetStringFromObj(objv[0], (int *) NULL); - Tcl_GetCommandInfo(interp, commandName, &info); - info.clientData = (ClientData) optionTable; - Tcl_SetCommandInfo(interp, commandName, &info); - } + Tk_OptionTable optionTable; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); @@ -166,29 +148,31 @@ SquareObjCmd(clientData, interp, objc, objv) Tk_SetClass(tkwin, "Square"); /* - * Allocate and initialize the widget record. + * Create the option table for this widget class. If it has + * already been created, the refcount will get bumped and just + * the pointer will be returned. The refcount getting bumped + * does not concern us, because Tk will ensure the table is + * deleted when the interpreter is destroyed. */ - squarePtr = (Square *) ckalloc(sizeof(Square)); - squarePtr->tkwin = tkwin; - squarePtr->display = Tk_Display(tkwin); - squarePtr->interp = interp; - squarePtr->widgetCmd = Tcl_CreateObjCommand(interp, + optionTable = Tk_CreateOptionTable(interp, optionSpecs); + + /* + * Allocate and initialize the widget record. The memset allows + * us to set just the non-NULL/0 items. + */ + + squarePtr = (Square *) ckalloc(sizeof(Square)); + memset((void *) squarePtr, 0, (sizeof(Square))); + + squarePtr->tkwin = tkwin; + squarePtr->display = Tk_Display(tkwin); + squarePtr->interp = interp; + squarePtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(squarePtr->tkwin), SquareWidgetCmd, (ClientData) squarePtr, SquareDeletedProc); - squarePtr->xPtr = NULL; - squarePtr->yPtr = NULL; - squarePtr->x = 0; - squarePtr->y = 0; - squarePtr->sizeObjPtr = NULL; - squarePtr->borderWidthPtr = NULL; - squarePtr->bgBorderPtr = NULL; - squarePtr->fgBorderPtr = NULL; - squarePtr->reliefPtr = NULL; - squarePtr->gc = None; - squarePtr->doubleBufferPtr = NULL; - squarePtr->updatePending = 0; - squarePtr->optionTable = optionTable; + squarePtr->gc = None; + squarePtr->optionTable = optionTable; if (Tk_InitOptions(interp, (char *) squarePtr, optionTable, tkwin) != TCL_OK) { @@ -207,8 +191,8 @@ SquareObjCmd(clientData, interp, objc, objv) goto error; } - Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(squarePtr->tkwin), - -1)); + Tcl_SetObjResult(interp, + Tcl_NewStringObj(Tk_PathName(squarePtr->tkwin), -1)); return TCL_OK; error: diff --git a/tests/config.test b/tests/config.test index 078c3f5..34c81fd 100644 --- a/tests/config.test +++ b/tests/config.test @@ -6,7 +6,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: config.test,v 1.4 2000/09/17 21:02:40 ericm Exp $ +# RCS: @(#) $Id: config.test,v 1.5 2001/08/29 23:22:24 hobbs Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { source [file join [pwd] [file dirname [info script]] defs.tcl] @@ -864,7 +864,25 @@ test config-13.1 {proper cleanup of options with widget destroy} { } { destroy .w $type .w -cursor crosshair - destroy .w + destroy .w + } +} {} + +eval destroy [winfo children .] + +test config-14.1 {Tk_CreateOptionTable - use with namespace import} { + namespace export -clear * + foreach type { + button canvas entry frame listbox menu menubutton message + scale scrollbar spinbox text radiobutton checkbutton + } { + namespace eval ::foo [subst { + namespace import -force ::$type + ::foo::$type .a + ::foo::$type .b + } + ] + destroy .a .b } } {} -- cgit v0.12