diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2013-11-20 09:11:56 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2013-11-20 09:11:56 (GMT) |
commit | 4197b73f60e37fcdbbc3dc13b73b44572d540935 (patch) | |
tree | 9f1ea6f37bf9b83b56ab922c8f7ddf7932c5180d | |
parent | 2e969c1eebe657e1b57a2e5ee2aa11f300e9fd5f (diff) | |
parent | 96e81b3476d38bee2a514d39e6a3914206a6353d (diff) | |
download | tk-4197b73f60e37fcdbbc3dc13b73b44572d540935.zip tk-4197b73f60e37fcdbbc3dc13b73b44572d540935.tar.gz tk-4197b73f60e37fcdbbc3dc13b73b44572d540935.tar.bz2 |
Store menu option tables in Thread storage in stead of allocated storage. This makes "menu" a normal command without needing special initialization tricks.
-rw-r--r-- | generic/tkInt.h | 4 | ||||
-rw-r--r-- | generic/tkMenu.c | 110 | ||||
-rw-r--r-- | generic/tkMenu.h | 16 | ||||
-rw-r--r-- | generic/tkWindow.c | 3 |
4 files changed, 44 insertions, 89 deletions
diff --git a/generic/tkInt.h b/generic/tkInt.h index 933fa5e..b48647d 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -1077,6 +1077,9 @@ MODULE_SCOPE int Tk_ListboxObjCmd(ClientData clientData, MODULE_SCOPE int Tk_LowerObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_MenuObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); MODULE_SCOPE int Tk_MenubuttonObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -1148,7 +1151,6 @@ MODULE_SCOPE void TkFreeGeometryMaster(Tk_Window tkwin, MODULE_SCOPE void TkEventInit(void); MODULE_SCOPE void TkRegisterObjTypes(void); -MODULE_SCOPE int TkCreateMenuCmd(Tcl_Interp *interp); MODULE_SCOPE int TkDeadAppCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv); MODULE_SCOPE int TkCanvasGetCoordObj(Tcl_Interp *interp, diff --git a/generic/tkMenu.c b/generic/tkMenu.c index 8f8a176..cd9ff08 100644 --- a/generic/tkMenu.c +++ b/generic/tkMenu.c @@ -81,6 +81,10 @@ typedef struct ThreadSpecificData { int menusInitialized; /* Flag indicates whether thread-specific * elements of the Windows Menu module have * been initialized. */ + Tk_OptionTable menuOptionTable; + /* The option table for menus. */ + Tk_OptionTable entryOptionTables[6]; + /* The tables for menu entries. */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; @@ -349,8 +353,6 @@ static int MenuDoXPosition(Tcl_Interp *interp, static int MenuAddOrInsert(Tcl_Interp *interp, TkMenu *menuPtr, Tcl_Obj *indexPtr, int objc, Tcl_Obj *const objv[]); -static int MenuCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); static void MenuCmdDeletedProc(ClientData clientData); static TkMenuEntry * MenuNewEntry(TkMenu *menuPtr, int index, int type); static char * MenuVarProc(ClientData clientData, @@ -381,63 +383,7 @@ static const Tk_ClassProcs menuClass = { /* *-------------------------------------------------------------- * - * TkCreateMenuCmd -- - * - * Called by Tk at initialization time to create the menu command. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *-------------------------------------------------------------- - */ - -static void -FreeOptionTables( - ClientData clientData, - Tcl_Interp *interp) -{ - ckfree(clientData); -} - -int -TkCreateMenuCmd( - Tcl_Interp *interp) /* Interpreter we are creating the command - * in. */ -{ - TkMenuOptionTables *optionTablesPtr = ckalloc(sizeof(TkMenuOptionTables)); - - optionTablesPtr->menuOptionTable = - Tk_CreateOptionTable(interp, tkMenuConfigSpecs); - optionTablesPtr->entryOptionTables[TEAROFF_ENTRY] = - Tk_CreateOptionTable(interp, specsArray[TEAROFF_ENTRY]); - optionTablesPtr->entryOptionTables[COMMAND_ENTRY] = - Tk_CreateOptionTable(interp, specsArray[COMMAND_ENTRY]); - optionTablesPtr->entryOptionTables[CASCADE_ENTRY] = - Tk_CreateOptionTable(interp, specsArray[CASCADE_ENTRY]); - optionTablesPtr->entryOptionTables[SEPARATOR_ENTRY] = - Tk_CreateOptionTable(interp, specsArray[SEPARATOR_ENTRY]); - optionTablesPtr->entryOptionTables[RADIO_BUTTON_ENTRY] = - Tk_CreateOptionTable(interp, specsArray[RADIO_BUTTON_ENTRY]); - optionTablesPtr->entryOptionTables[CHECK_BUTTON_ENTRY] = - Tk_CreateOptionTable(interp, specsArray[CHECK_BUTTON_ENTRY]); - - Tcl_CreateObjCommand(interp, "menu", MenuCmd, optionTablesPtr, 0); - Tcl_CallWhenDeleted(interp, FreeOptionTables, optionTablesPtr); - - if (Tcl_IsSafe(interp)) { - Tcl_HideCommand(interp, "menu", "menu"); - } - - return TCL_OK; -} - -/* - *-------------------------------------------------------------- - * - * MenuCmd -- + * Tk_MenuObjCmd -- * * This function is invoked to process the "menu" Tcl command. See the * user documentation for details on what it does. @@ -451,21 +397,22 @@ TkCreateMenuCmd( *-------------------------------------------------------------- */ -static int -MenuCmd( +int +Tk_MenuObjCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument strings. */ { - Tk_Window tkwin = Tk_MainWindow(interp); + Tk_Window tkwin = clientData; Tk_Window newWin; register TkMenu *menuPtr; TkMenuReferences *menuRefPtr; int i, index, toplevel; const char *windowName; static const char *const typeStringList[] = {"-type", NULL}; - TkMenuOptionTables *optionTablesPtr = clientData; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); @@ -511,7 +458,6 @@ MenuCmd( menuPtr->cursorPtr = None; menuPtr->masterMenuPtr = menuPtr; menuPtr->menuType = UNKNOWN_TYPE; - menuPtr->optionTablesPtr = optionTablesPtr; TkMenuInitializeDrawingFields(menuPtr); Tk_SetClass(menuPtr->tkwin, "Menu"); @@ -520,7 +466,7 @@ MenuCmd( ExposureMask|StructureNotifyMask|ActivateMask, TkMenuEventProc, menuPtr); if (Tk_InitOptions(interp, (char *) menuPtr, - menuPtr->optionTablesPtr->menuOptionTable, menuPtr->tkwin) + tsdPtr->menuOptionTable, menuPtr->tkwin) != TCL_OK) { Tk_DestroyWindow(menuPtr->tkwin); return TCL_ERROR; @@ -675,6 +621,8 @@ MenuWidgetObjCmd( register TkMenuEntry *mePtr; int result = TCL_OK; int option; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); @@ -725,7 +673,7 @@ MenuWidgetObjCmd( goto error; } resultPtr = Tk_GetOptionValue(interp, (char *) menuPtr, - menuPtr->optionTablesPtr->menuOptionTable, objv[2], + tsdPtr->menuOptionTable, objv[2], menuPtr->tkwin); if (resultPtr == NULL) { goto error; @@ -745,7 +693,7 @@ MenuWidgetObjCmd( if (objc == 2) { resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr, - menuPtr->optionTablesPtr->menuOptionTable, NULL, + tsdPtr->menuOptionTable, NULL, menuPtr->tkwin); if (resultPtr == NULL) { result = TCL_ERROR; @@ -755,7 +703,7 @@ MenuWidgetObjCmd( } } else if (objc == 3) { resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr, - menuPtr->optionTablesPtr->menuOptionTable, objv[2], + tsdPtr->menuOptionTable, objv[2], menuPtr->tkwin); if (resultPtr == NULL) { result = TCL_ERROR; @@ -1144,6 +1092,8 @@ DestroyMenuInstance( Tcl_Obj *newObjv[2]; TkMenu *parentMasterMenuPtr; TkMenuEntry *parentMasterEntryPtr; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * If the menu has any cascade menu entries pointing to it, the cascade @@ -1233,7 +1183,7 @@ DestroyMenuInstance( } TkMenuFreeDrawOptions(menuPtr); Tk_FreeConfigOptions((char *) menuPtr, - menuPtr->optionTablesPtr->menuOptionTable, menuPtr->tkwin); + tsdPtr->menuOptionTable, menuPtr->tkwin); if (menuPtr->tkwin != NULL) { Tk_Window tkwin = menuPtr->tkwin; @@ -1566,12 +1516,14 @@ ConfigureMenu( int i; TkMenu *menuListPtr, *cleanupPtr; int result; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL; menuListPtr = menuListPtr->nextInstancePtr) { menuListPtr->errorStructPtr = ckalloc(sizeof(Tk_SavedOptions)); result = Tk_SetOptions(interp, (char *) menuListPtr, - menuListPtr->optionTablesPtr->menuOptionTable, objc, objv, + tsdPtr->menuOptionTable, objc, objv, menuListPtr->tkwin, menuListPtr->errorStructPtr, NULL); if (result != TCL_OK) { for (cleanupPtr = menuPtr->masterMenuPtr; @@ -2287,6 +2239,8 @@ MenuNewEntry( TkMenuEntry *mePtr; TkMenuEntry **newEntries; int i; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * Create a new array of entries with an empty slot for the new entry. @@ -2308,7 +2262,7 @@ MenuNewEntry( mePtr = ckalloc(sizeof(TkMenuEntry)); menuPtr->entries[index] = mePtr; mePtr->type = type; - mePtr->optionTable = menuPtr->optionTablesPtr->entryOptionTables[type]; + mePtr->optionTable = tsdPtr->entryOptionTables[type]; mePtr->menuPtr = menuPtr; mePtr->labelPtr = NULL; mePtr->labelLength = 0; @@ -3625,6 +3579,20 @@ TkMenuInit(void) } if (!tsdPtr->menusInitialized) { TkpMenuThreadInit(); + tsdPtr->menuOptionTable = + Tk_CreateOptionTable(NULL, tkMenuConfigSpecs); + tsdPtr->entryOptionTables[TEAROFF_ENTRY] = + Tk_CreateOptionTable(NULL, specsArray[TEAROFF_ENTRY]); + tsdPtr->entryOptionTables[COMMAND_ENTRY] = + Tk_CreateOptionTable(NULL, specsArray[COMMAND_ENTRY]); + tsdPtr->entryOptionTables[CASCADE_ENTRY] = + Tk_CreateOptionTable(NULL, specsArray[CASCADE_ENTRY]); + tsdPtr->entryOptionTables[SEPARATOR_ENTRY] = + Tk_CreateOptionTable(NULL, specsArray[SEPARATOR_ENTRY]); + tsdPtr->entryOptionTables[RADIO_BUTTON_ENTRY] = + Tk_CreateOptionTable(NULL, specsArray[RADIO_BUTTON_ENTRY]); + tsdPtr->entryOptionTables[CHECK_BUTTON_ENTRY] = + Tk_CreateOptionTable(NULL, specsArray[CHECK_BUTTON_ENTRY]); tsdPtr->menusInitialized = 1; } } diff --git a/generic/tkMenu.h b/generic/tkMenu.h index def7d19..bac51aa 100644 --- a/generic/tkMenu.h +++ b/generic/tkMenu.h @@ -359,10 +359,7 @@ typedef struct TkMenu { /* A pointer to the original menu for this * clone chain. Points back to this structure * if this menu is a master menu. */ - struct TkMenuOptionTables *optionTablesPtr; - /* A pointer to the collection of option - * tables that work with menus and menu - * entries. */ + void *reserved1; /* not used any more. */ Tk_Window parentTopLevelPtr;/* If this menu is a menubar, this is the * toplevel that owns the menu. Only * applicable for menubar clones. */ @@ -431,17 +428,6 @@ typedef struct TkMenuReferences { } TkMenuReferences; /* - * This structure contains all of the option tables that are needed by menus. - */ - -typedef struct TkMenuOptionTables { - Tk_OptionTable menuOptionTable; - /* The option table for menus. */ - Tk_OptionTable entryOptionTables[6]; - /* The tables for menu entries. */ -} TkMenuOptionTables; - -/* * Flag bits for menus: * * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has diff --git a/generic/tkWindow.c b/generic/tkWindow.c index 91806cf..6f5ee95 100644 --- a/generic/tkWindow.c +++ b/generic/tkWindow.c @@ -149,6 +149,7 @@ static const TkCmd commands[] = { {"label", Tk_LabelObjCmd, ISSAFE}, {"labelframe", Tk_LabelframeObjCmd, ISSAFE}, {"listbox", Tk_ListboxObjCmd, ISSAFE}, + {"menu", Tk_MenuObjCmd, PASSMAINWINDOW}, {"menubutton", Tk_MenubuttonObjCmd, ISSAFE}, {"message", Tk_MessageObjCmd, ISSAFE}, {"panedwindow", Tk_PanedWindowObjCmd, ISSAFE}, @@ -987,8 +988,6 @@ TkCreateMainWindow( } } - TkCreateMenuCmd(interp); - /* * Set variables for the intepreter. */ |