4 * This module implements the common elements of the Mac and Windows
5 * specific features of menus. This file is not used for UNIX.
7 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
9 * See the file "license.terms" for information on usage and redistribution of
10 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
17 int postCommandGeneration;
19 static Tcl_ThreadDataKey dataKey;
21 static int PreprocessMenu(TkMenu *menuPtr);
24 *----------------------------------------------------------------------
28 * The guts of the preprocessing. Recursive.
31 * The return value is a standard Tcl result (errors can occur while the
32 * postcommands are being processed).
35 * Since commands can get executed while this routine is being executed,
36 * the entire world can change.
38 *----------------------------------------------------------------------
45 int index, result, finished;
46 ThreadSpecificData *tsdPtr =
47 Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
49 Tcl_Preserve(menuPtr);
52 * First, let's process the post command on ourselves. If this command
53 * destroys this menu, or if there was an error, we are done.
56 result = TkPostCommand(menuPtr);
57 if ((result != TCL_OK) || (menuPtr->tkwin == NULL)) {
62 * Now, we go through structure and process all of the commands. Since the
63 * structure is changing, we stop after we do one command, and start over.
64 * When we get through without doing any, we are done.
69 for (index = 0; index < menuPtr->numEntries; index++) {
70 TkMenuEntry *entryPtr = menuPtr->entries[index];
72 if ((entryPtr->type == CASCADE_ENTRY)
73 && (entryPtr->namePtr != NULL)
74 && (entryPtr->childMenuRefPtr != NULL)
75 && (entryPtr->childMenuRefPtr->menuPtr != NULL)) {
76 TkMenu *cascadeMenuPtr = entryPtr->childMenuRefPtr->menuPtr;
78 if (cascadeMenuPtr->postCommandGeneration !=
79 tsdPtr->postCommandGeneration) {
80 cascadeMenuPtr->postCommandGeneration =
81 tsdPtr->postCommandGeneration;
82 result = PreprocessMenu(cascadeMenuPtr);
83 if (result != TCL_OK) {
99 *----------------------------------------------------------------------
101 * TkPreprocessMenu --
103 * On the Mac and on Windows, all of the postcommand processing has to be
104 * done on the entire tree underneath the main window to be posted. This
105 * means that we have to traverse the menu tree and issue the
106 * postcommands for all of the menus that have cascades attached. Since
107 * the postcommands can change the menu structure while we are
108 * traversing, we have to be extremely careful. Basically, the idea is to
109 * traverse the structure until we succesfully process one postcommand.
110 * Then we start over, and do it again until we traverse the whole
111 * structure without processing any postcommands.
113 * We are also going to set up the cascade back pointers in here since we
114 * have to traverse the entire structure underneath the menu anyway. We
115 * can clear the postcommand marks while we do that.
118 * The return value is a standard Tcl result (errors can occur while the
119 * postcommands are being processed).
122 * Since commands can get executed while this routine is being executed,
123 * the entire world can change.
125 *----------------------------------------------------------------------
132 ThreadSpecificData *tsdPtr =
133 Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
135 tsdPtr->postCommandGeneration++;
136 menuPtr->postCommandGeneration = tsdPtr->postCommandGeneration;
137 return PreprocessMenu(menuPtr);