Import Tk 8.6.6 (as of svn r86089)
This commit is contained in:
146
generic/tkMacWinMenu.c
Normal file
146
generic/tkMacWinMenu.c
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "tkInt.h"
|
||||
#include "tkMenu.h"
|
||||
|
||||
typedef struct ThreadSpecificData {
|
||||
int postCommandGeneration;
|
||||
} ThreadSpecificData;
|
||||
static Tcl_ThreadDataKey dataKey;
|
||||
|
||||
static int PreprocessMenu(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(
|
||||
TkMenu *menuPtr)
|
||||
{
|
||||
int index, result, finished;
|
||||
ThreadSpecificData *tsdPtr =
|
||||
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
|
||||
|
||||
Tcl_Preserve(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++) {
|
||||
register TkMenuEntry *entryPtr = menuPtr->entries[index];
|
||||
|
||||
if ((entryPtr->type == CASCADE_ENTRY)
|
||||
&& (entryPtr->namePtr != NULL)
|
||||
&& (entryPtr->childMenuRefPtr != NULL)
|
||||
&& (entryPtr->childMenuRefPtr->menuPtr != NULL)) {
|
||||
TkMenu *cascadeMenuPtr = entryPtr->childMenuRefPtr->menuPtr;
|
||||
|
||||
if (cascadeMenuPtr->postCommandGeneration !=
|
||||
tsdPtr->postCommandGeneration) {
|
||||
cascadeMenuPtr->postCommandGeneration =
|
||||
tsdPtr->postCommandGeneration;
|
||||
result = PreprocessMenu(cascadeMenuPtr);
|
||||
if (result != TCL_OK) {
|
||||
goto done;
|
||||
}
|
||||
finished = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!finished);
|
||||
|
||||
done:
|
||||
Tcl_Release(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(
|
||||
TkMenu *menuPtr)
|
||||
{
|
||||
ThreadSpecificData *tsdPtr =
|
||||
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
|
||||
|
||||
tsdPtr->postCommandGeneration++;
|
||||
menuPtr->postCommandGeneration = tsdPtr->postCommandGeneration;
|
||||
return PreprocessMenu(menuPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 4
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
||||
Reference in New Issue
Block a user