summaryrefslogtreecommitdiffstats
path: root/generic/tkMacWinMenu.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkMacWinMenu.c')
-rw-r--r--generic/tkMacWinMenu.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/generic/tkMacWinMenu.c b/generic/tkMacWinMenu.c
new file mode 100644
index 0000000..8ae403b
--- /dev/null
+++ b/generic/tkMacWinMenu.c
@@ -0,0 +1,134 @@
+/*
+ * tkMacWinMenu.c --
+ *
+ * This module implements the common elements of the Mac and Windows
+ * specific features of menus. This file is not used for UNIX.
+ *
+ * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * SCCS: @(#) tkMacWinMenu.c 1.39 97/04/09 14:56:59
+ */
+
+#include "tkMenu.h"
+
+static int postCommandGeneration;
+
+static int PreprocessMenu _ANSI_ARGS_((TkMenu *menuPtr));
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PreprocessMenu --
+ *
+ * The guts of the preprocessing. Recursive.
+ *
+ * Results:
+ * The return value is a standard Tcl result (errors can occur
+ * while the postcommands are being processed).
+ *
+ * Side effects:
+ * Since commands can get executed while this routine is being executed,
+ * the entire world can change.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+PreprocessMenu(menuPtr)
+ TkMenu *menuPtr;
+{
+ int index, result, finished;
+ TkMenu *cascadeMenuPtr;
+
+ Tcl_Preserve((ClientData) menuPtr);
+
+ /*
+ * First, let's process the post command on ourselves. If this command
+ * destroys this menu, or if there was an error, we are done.
+ */
+
+ result = TkPostCommand(menuPtr);
+ if ((result != TCL_OK) || (menuPtr->tkwin == NULL)) {
+ goto done;
+ }
+
+ /*
+ * Now, we go through structure and process all of the commands.
+ * Since the structure is changing, we stop after we do one command,
+ * and start over. When we get through without doing any, we are done.
+ */
+
+
+ do {
+ finished = 1;
+ for (index = 0; index < menuPtr->numEntries; index++) {
+ if ((menuPtr->entries[index]->type == CASCADE_ENTRY)
+ && (menuPtr->entries[index]->name != NULL)) {
+ if ((menuPtr->entries[index]->childMenuRefPtr != NULL)
+ && (menuPtr->entries[index]->childMenuRefPtr->menuPtr
+ != NULL)) {
+ cascadeMenuPtr =
+ menuPtr->entries[index]->childMenuRefPtr->menuPtr;
+ if (cascadeMenuPtr->postCommandGeneration !=
+ postCommandGeneration) {
+ cascadeMenuPtr->postCommandGeneration =
+ postCommandGeneration;
+ result = PreprocessMenu(cascadeMenuPtr);
+ if (result != TCL_OK) {
+ goto done;
+ }
+ finished = 0;
+ break;
+ }
+ }
+ }
+ }
+ } while (!finished);
+
+ done:
+ Tcl_Release((ClientData)menuPtr);
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkPreprocessMenu --
+ *
+ * On the Mac and on Windows, all of the postcommand processing has
+ * to be done on the entire tree underneath the main window to be
+ * posted. This means that we have to traverse the menu tree and
+ * issue the postcommands for all of the menus that have cascades
+ * attached. Since the postcommands can change the menu structure while
+ * we are traversing, we have to be extremely careful. Basically, the
+ * idea is to traverse the structure until we succesfully process
+ * one postcommand. Then we start over, and do it again until
+ * we traverse the whole structure without processing any postcommands.
+ *
+ * We are also going to set up the cascade back pointers in here
+ * since we have to traverse the entire structure underneath the menu
+ * anyway, We can clear the postcommand marks while we do that.
+ *
+ * Results:
+ * The return value is a standard Tcl result (errors can occur
+ * while the postcommands are being processed).
+ *
+ * Side effects:
+ * Since commands can get executed while this routine is being executed,
+ * the entire world can change.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkPreprocessMenu(menuPtr)
+ TkMenu *menuPtr;
+{
+ postCommandGeneration++;
+ menuPtr->postCommandGeneration = postCommandGeneration;
+ return PreprocessMenu(menuPtr);
+}