summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2013-11-20 09:11:56 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2013-11-20 09:11:56 (GMT)
commit4197b73f60e37fcdbbc3dc13b73b44572d540935 (patch)
tree9f1ea6f37bf9b83b56ab922c8f7ddf7932c5180d
parent2e969c1eebe657e1b57a2e5ee2aa11f300e9fd5f (diff)
parent96e81b3476d38bee2a514d39e6a3914206a6353d (diff)
downloadtk-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.h4
-rw-r--r--generic/tkMenu.c110
-rw-r--r--generic/tkMenu.h16
-rw-r--r--generic/tkWindow.c3
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.
*/