diff options
Diffstat (limited to 'mac/tkMacMenu.c')
-rw-r--r-- | mac/tkMacMenu.c | 4605 |
1 files changed, 0 insertions, 4605 deletions
diff --git a/mac/tkMacMenu.c b/mac/tkMacMenu.c deleted file mode 100644 index d9ec4fd..0000000 --- a/mac/tkMacMenu.c +++ /dev/null @@ -1,4605 +0,0 @@ -/* - * tkMacMenu.c -- - * - * This module implements the Mac-platform specific features of menus. - * - * 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 "tkMacInt.h" -#include "tkMenu.h" -#include "tkMenuButton.h" -#include "tkColor.h" -#include "tkMacInt.h" -#undef Status -#include <Menus.h> -#include <OSUtils.h> -#include <Palettes.h> -#include <Resources.h> -#include <string.h> -#include <ToolUtils.h> -#include <Balloons.h> -#include <Appearance.h> -#include <Devices.h> - -typedef struct MacMenu { - MenuHandle menuHdl; /* The Menu Manager data structure. */ - Rect menuRect; /* The rectangle as calculated in the - * MDEF. This is used to figure ou the - * clipping rgn before we push - * the <<MenuSelect>> virtual binding - * through. */ -} MacMenu; - -typedef struct MenuEntryUserData { - Drawable mdefDrawable; - TkMenuEntry *mePtr; - Tk_Font tkfont; - Tk_FontMetrics *fmPtr; -} MenuEntryUserData; -/* - * Various geometry definitions: - */ - -#define CASCADE_ARROW_HEIGHT 10 -#define CASCADE_ARROW_WIDTH 8 -#define DECORATION_BORDER_WIDTH 2 -#define MAC_MARGIN_WIDTH 8 - -/* - * The following are constants relating to the SICNs used for drawing the MDEF. - */ - -#define SICN_RESOURCE_NUMBER 128 - -#define SICN_HEIGHT 16 -#define SICN_ROWS 2 -#define CASCADE_ICON_WIDTH 7 -#define SHIFT_ICON_WIDTH 10 -#define OPTION_ICON_WIDTH 16 -#define CONTROL_ICON_WIDTH 12 -#define COMMAND_ICON_WIDTH 10 - -#define CASCADE_ARROW 0 -#define SHIFT_ICON 1 -#define OPTION_ICON 2 -#define CONTROL_ICON 3 -#define COMMAND_ICON 4 -#define DOWN_ARROW 5 -#define UP_ARROW 6 - -/* - * Platform specific flags for menu entries - * - * ENTRY_COMMAND_ACCEL Indicates the entry has the command key - * in its accelerator string. - * ENTRY_OPTION_ACCEL Indicates the entry has the option key - * in its accelerator string. - * ENTRY_SHIFT_ACCEL Indicates the entry has the shift key - * in its accelerator string. - * ENTRY_CONTROL_ACCEL Indicates the entry has the control key - * in its accelerator string. - */ - -#define ENTRY_COMMAND_ACCEL ENTRY_PLATFORM_FLAG1 -#define ENTRY_OPTION_ACCEL ENTRY_PLATFORM_FLAG2 -#define ENTRY_SHIFT_ACCEL ENTRY_PLATFORM_FLAG3 -#define ENTRY_CONTROL_ACCEL ENTRY_PLATFORM_FLAG4 -#define ENTRY_ACCEL_MASK (ENTRY_COMMAND_ACCEL | ENTRY_OPTION_ACCEL \ - | ENTRY_SHIFT_ACCEL | ENTRY_CONTROL_ACCEL) - -/* - * This structure is used to keep track of subfields within Macintosh menu - * items. - */ - -typedef struct EntryGeometry { - int accelTextStart; /* Offset into the accel string where - * the text starts. Everything before - * this is modifier key descriptions. - */ - int modifierWidth; /* Width of modifier symbols. */ - int accelTextWidth; /* Width of the text after the modifier - * keys. */ - int nonAccelMargin; /* The width of the margin for entries - * without accelerators. */ -} EntryGeometry; - -/* - * Structure to keep track of toplevel windows and their menubars. - */ - -typedef struct TopLevelMenubarList { - struct TopLevelMenubarList *nextPtr; - /* The next window in the list. */ - Tk_Window tkwin; /* The toplevel window. */ - TkMenu *menuPtr; /* The menu associated with this - * toplevel. */ -} TopLevelMenubarList; - -/* - * Platform-specific flags for menus. - * - * MENU_APPLE_MENU 0 indicates a custom Apple menu has - * not been installed; 1 a custom Apple - * menu has been installed. - * MENU_HELP_MENU 0 indicates a custom Help menu has - * not been installed; 1 a custom Help - * menu has been installed. - * MENU_RECONFIGURE_PENDING 1 indicates that an idle handler has - * been scheduled to reconfigure the - * Macintosh MenuHandle. - */ - -#define MENU_APPLE_MENU MENU_PLATFORM_FLAG1 -#define MENU_HELP_MENU MENU_PLATFORM_FLAG2 -#define MENU_RECONFIGURE_PENDING MENU_PLATFORM_FLAG3 - -#define CASCADE_CMD (0x1b) - /* The special command char for cascade - * menus. */ -#define SEPARATOR_TEXT "\p(-" - /* The text for a menu separator. */ - -#define MENUBAR_REDRAW_PENDING 1 - -static int gNoTkMenus = 0; /* This is used by Tk_MacTurnOffMenus as the - * flag that Tk is not to draw any menus. */ -RgnHandle tkMenuCascadeRgn = NULL; - /* The region to clip drawing to when the - * MDEF is up. */ -int tkUseMenuCascadeRgn = 0; /* If this is 1, clipping code - * should intersect tkMenuCascadeRgn - * before drawing occurs. - * tkMenuCascadeRgn will only - * be valid when the value of this - * variable is 1. */ - -static Tcl_HashTable commandTable; - /* The list of menuInstancePtrs associated with - * menu ids */ -static short currentAppleMenuID; - /* The id of the current Apple menu. 0 for - * none. */ -static short currentHelpMenuID; /* The id of the current Help menu. 0 for - * none. */ -static Tcl_Interp *currentMenuBarInterp; - /* The interpreter of the window that owns - * the current menubar. */ -static char *currentMenuBarName; - /* Malloced. Name of current menu in menu bar. - * NULL if no menu set. TO DO: make this a - * DString. */ -static Tk_Window currentMenuBarOwner; - /* Which window owns the current menu bar. */ -static char elipsisString[TCL_UTF_MAX + 1]; - /* The UTF representation of the elipsis (Š) - * character. */ -static int helpItemCount; /* The number of items in the help menu. - * -1 means that the help menu is - * unavailable. This does not include - * the automatically generated separator. */ -static int inPostMenu; /* We cannot be re-entrant like X - * windows. */ -static short lastMenuID; /* To pass to NewMenu; need to figure out - * a good way to do this. */ -static unsigned char lastCascadeID; - /* Cascades have to have ids that are - * less than 256. */ -static MacDrawable macMDEFDrawable; - /* Drawable for use by MDEF code */ -static MDEFScrollFlag = 0; /* Used so that popups don't scroll too soon. */ -static int menuBarFlags; /* Used for whether the menu bar needs - * redrawing or not. */ -static TkMenuDefUPP menuDefProc = NULL ; - /* The routine descriptor to the MDEF proc. - * The MDEF is needed to draw menus with - * non-standard attributes and to support - * tearoff menus. */ -static struct TearoffSelect { - TkMenu *menuPtr; /* The menu that is torn off */ - Point point; /* The point to place the new menu */ - Rect excludeRect; /* We don't want to drag tearoff highlights - * when we are in this menu */ -} tearoffStruct; - -static RgnHandle totalMenuRgn = NULL; - /* Used to update windows which have been - * obscured by menus. */ -static RgnHandle utilRgn = NULL;/* Used when creating the region that is to - * be clipped out while the MDEF is active. */ - -static TopLevelMenubarList *windowListPtr; - /* A list of windows that have menubars set. */ -static MenuItemDrawingUPP tkThemeMenuItemDrawingUPP; - /* Points to the UPP for theme Item drawing. */ - - -/* - * Forward declarations for procedures defined later in this file: - */ - -static void CompleteIdlers _ANSI_ARGS_((TkMenu *menuPtr)); -static void DrawMenuBarWhenIdle _ANSI_ARGS_(( - ClientData clientData)); -static void DrawMenuBackground _ANSI_ARGS_(( - Rect *menuRectPtr, Drawable d, ThemeMenuType type)); -static void DrawMenuEntryAccelerator _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Drawable d, GC gc, Tk_Font tkfont, - CONST Tk_FontMetrics *fmPtr, - Tk_3DBorder activeBorder, int x, int y, - int width, int height, int drawArrow)); -static void DrawMenuEntryBackground _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Drawable d, Tk_3DBorder activeBorder, - Tk_3DBorder bgBorder, int x, int y, - int width, int heigth)); -static void DrawMenuEntryIndicator _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Drawable d, GC gc, GC indicatorGC, - Tk_Font tkfont, - CONST Tk_FontMetrics *fmPtr, int x, int y, - int width, int height)); -static void DrawMenuEntryLabel _ANSI_ARGS_(( - TkMenu * menuPtr, TkMenuEntry *mePtr, Drawable d, - GC gc, Tk_Font tkfont, - CONST Tk_FontMetrics *fmPtr, int x, int y, - int width, int height)); -static void DrawMenuSeparator _ANSI_ARGS_((TkMenu *menuPtr, - TkMenuEntry *mePtr, Drawable d, GC gc, - Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, - int x, int y, int width, int height)); -static void DrawTearoffEntry _ANSI_ARGS_((TkMenu *menuPtr, - TkMenuEntry *mePtr, Drawable d, GC gc, - Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, - int x, int y, int width, int height)); -static Handle FixMDEF _ANSI_ARGS_((void)); -static void GetEntryText _ANSI_ARGS_((TkMenuEntry *mePtr, - Tcl_DString *dStringPtr)); -static void GetMenuAccelGeometry _ANSI_ARGS_((TkMenu *menuPtr, - TkMenuEntry *mePtr, Tk_Font tkfont, - CONST Tk_FontMetrics *fmPtr, int *modWidthPtr, - int *textWidthPtr, int *heightPtr)); -static void GetMenuLabelGeometry _ANSI_ARGS_((TkMenuEntry *mePtr, - Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, - int *widthPtr, int *heightPtr)); -static void GetMenuIndicatorGeometry _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, - int *widthPtr, int *heightPtr)); -static void GetMenuSeparatorGeometry _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, - int *widthPtr, int *heightPtr)); -static void GetTearoffEntryGeometry _ANSI_ARGS_((TkMenu *menuPtr, - TkMenuEntry *mePtr, Tk_Font tkfont, - CONST Tk_FontMetrics *fmPtr, int *widthPtr, - int *heightPtr)); -static int GetNewID _ANSI_ARGS_((Tcl_Interp *interp, - TkMenu *menuInstPtr, int cascade, - short *menuIDPtr)); -static char FindMarkCharacter _ANSI_ARGS_((TkMenuEntry *mePtr)); -static void FreeID _ANSI_ARGS_((short menuID)); -static void InvalidateMDEFRgns _ANSI_ARGS_((void)); -static void MenuDefProc _ANSI_ARGS_((short message, - MenuHandle menu, Rect *menuRectPtr, - Point hitPt, short *whichItem, - TkMenuLowMemGlobals *globalsPtr)); -static void MenuSelectEvent _ANSI_ARGS_((TkMenu *menuPtr)); -static void ReconfigureIndividualMenu _ANSI_ARGS_(( - TkMenu *menuPtr, MenuHandle macMenuHdl, - int base)); -static void ReconfigureMacintoshMenu _ANSI_ARGS_ (( - ClientData clientData)); -static void RecursivelyClearActiveMenu _ANSI_ARGS_(( - TkMenu *menuPtr)); -static void RecursivelyDeleteMenu _ANSI_ARGS_(( - TkMenu *menuPtr)); -static void RecursivelyInsertMenu _ANSI_ARGS_(( - TkMenu *menuPtr)); -static void SetDefaultMenubar _ANSI_ARGS_((void)); -static int SetMenuCascade _ANSI_ARGS_((TkMenu *menuPtr)); -static void SetMenuIndicator _ANSI_ARGS_((TkMenuEntry *mePtr)); -static void SetMenuTitle _ANSI_ARGS_((MenuHandle menuHdl, - Tcl_Obj *titlePtr)); -static void AppearanceEntryDrawWrapper _ANSI_ARGS_((TkMenuEntry *mePtr, - Rect * menuRectPtr, TkMenuLowMemGlobals *globalsPtr, - Drawable d, Tk_FontMetrics *fmPtr, Tk_Font tkfont, - int x, int y, int width, int height)); -pascal void tkThemeMenuItemDrawingProc _ANSI_ARGS_ ((const Rect *inBounds, - SInt16 inDepth, Boolean inIsColorDevice, - SInt32 inUserData)); - - -/* - *---------------------------------------------------------------------- - * - * TkMacUseID -- - * - * Take the ID out of the available list for new menus. Used by the - * default menu bar's menus so that they do not get created at the tk - * level. See GetNewID for more information. - * - * Results: - * Returns TCL_OK if the id was not in use. Returns TCL_ERROR if the - * id was in use. - * - * Side effects: - * A hash table entry in the command table is created with a NULL - * value. - * - *---------------------------------------------------------------------- - */ - -int -TkMacUseMenuID( - short macID) /* The id to take out of the table */ -{ - Tcl_HashEntry *commandEntryPtr; - int newEntry; - - TkMenuInit(); - commandEntryPtr = Tcl_CreateHashEntry(&commandTable, (char *) macID, - &newEntry); - if (newEntry == 1) { - Tcl_SetHashValue(commandEntryPtr, NULL); - return TCL_OK; - } else { - return TCL_ERROR; - } -} - -/* - *---------------------------------------------------------------------- - * - * GetNewID -- - * - * Allocates a new menu id and marks it in use. Each menu on the - * mac must be designated by a unique id, which is a short. In - * addition, some ids are reserved by the system. Since Tk uses - * mostly dynamic menus, we must allocate and free these ids on - * the fly. We use the id as a key into a hash table; if there - * is no hash entry, we know that we can use the id. - * - * Results: - * Returns TCL_OK if succesful; TCL_ERROR if there are no more - * ids of the appropriate type to allocate. menuIDPtr contains - * the new id if succesful. - * - * Side effects: - * An entry is created for the menu in the command hash table, - * and the hash entry is stored in the appropriate field in the - * menu data structure. - * - *---------------------------------------------------------------------- - */ - -static int -GetNewID( - Tcl_Interp *interp, /* Used for error reporting */ - TkMenu *menuPtr, /* The menu we are working with */ - int cascade, /* 0 if we are working with a normal menu; - 1 if we are working with a cascade */ - short *menuIDPtr) /* The resulting id */ -{ - int found = 0; - int newEntry; - Tcl_HashEntry *commandEntryPtr; - short returnID = *menuIDPtr; - - /* - * The following code relies on shorts and unsigned chars wrapping - * when the highest value is incremented. Also, the values between - * 236 and 255 inclusive are reserved for DA's by the Mac OS. - */ - - if (!cascade) { - short curID = lastMenuID + 1; - if (curID == 236) { - curID = 256; - } - - while (curID != lastMenuID) { - commandEntryPtr = Tcl_CreateHashEntry(&commandTable, - (char *) curID, &newEntry); - if (newEntry == 1) { - found = 1; - lastMenuID = returnID = curID; - break; - } - curID++; - if (curID == 236) { - curID = 256; - } - } - } else { - - /* - * Cascade ids must be between 0 and 235 only, so they must be - * dealt with separately. - */ - - unsigned char curID = lastCascadeID + 1; - if (curID == 236) { - curID = 0; - } - - while (curID != lastCascadeID) { - commandEntryPtr = Tcl_CreateHashEntry(&commandTable, - (char *) curID, &newEntry); - if (newEntry == 1) { - found = 1; - lastCascadeID = returnID = curID; - break; - } - curID++; - if (curID == 236) { - curID = 0; - } - } - } - - if (found) { - Tcl_SetHashValue(commandEntryPtr, (char *) menuPtr); - *menuIDPtr = returnID; - return TCL_OK; - } else { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "No more menus can be allocated.", - (char *) NULL); - return TCL_ERROR; - } -} - -/* - *---------------------------------------------------------------------- - * - * FreeID -- - * - * Marks the id as free. - * - * Results: - * None. - * - * Side effects: - * The hash table entry for the ID is cleared. - * - *---------------------------------------------------------------------- - */ - -static void -FreeID( - short menuID) /* The id to free */ -{ - Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&commandTable, - (char *) menuID); - - if (entryPtr != NULL) { - Tcl_DeleteHashEntry(entryPtr); - } - if (menuID == currentAppleMenuID) { - currentAppleMenuID = 0; - } - if (menuID == currentHelpMenuID) { - currentHelpMenuID = 0; - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpNewMenu -- - * - * Gets a new blank menu. Only the platform specific options are filled - * in. - * - * Results: - * Returns a standard TCL error. - * - * Side effects: - * Allocates a Macintosh menu handle and puts in the platformData - * field of the menuPtr. - * - *---------------------------------------------------------------------- - */ - -int -TkpNewMenu( - TkMenu *menuPtr) /* The common structure we are making the - * platform structure for. */ -{ - short menuID; - Str255 itemText; - int length; - MenuHandle macMenuHdl; - int error = TCL_OK; - - error = GetNewID(menuPtr->interp, menuPtr, 0, &menuID); - if (error != TCL_OK) { - return error; - } - length = strlen(Tk_PathName(menuPtr->tkwin)); - memmove(&itemText[1], Tk_PathName(menuPtr->tkwin), - (length > 230) ? 230 : length); - itemText[0] = (length > 230) ? 230 : length; - macMenuHdl = NewMenu(menuID, itemText); -#if GENERATINGCFM - { - Handle mdefProc = FixMDEF(); - if ((mdefProc != NULL)) { - (*macMenuHdl)->menuProc = mdefProc; - } - } -#endif - menuPtr->platformData = (TkMenuPlatformData) ckalloc(sizeof(MacMenu)); - ((MacMenu *) menuPtr->platformData)->menuHdl = macMenuHdl; - SetRect(&((MacMenu *) menuPtr->platformData)->menuRect, 0, 0, 0, 0); - - if ((currentMenuBarInterp == menuPtr->interp) - && (currentMenuBarName != NULL)) { - Tk_Window parentWin = Tk_Parent(menuPtr->tkwin); - - if (strcmp(currentMenuBarName, Tk_PathName(parentWin)) == 0) { - if ((strcmp(Tk_PathName(menuPtr->tkwin) - + strlen(Tk_PathName(parentWin)), ".apple") == 0) - || (strcmp(Tk_PathName(menuPtr->tkwin) - + strlen(Tk_PathName(parentWin)), ".help") == 0)) { - if (!(menuBarFlags & MENUBAR_REDRAW_PENDING)) { - Tcl_DoWhenIdle(DrawMenuBarWhenIdle, (ClientData *) NULL); - menuBarFlags |= MENUBAR_REDRAW_PENDING; - } - } - } - } - - menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) menuPtr); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TkpDestroyMenu -- - * - * Destroys platform-specific menu structures. - * - * Results: - * None. - * - * Side effects: - * All platform-specific allocations are freed up. - * - *---------------------------------------------------------------------- - */ - -void -TkpDestroyMenu( - TkMenu *menuPtr) /* The common menu structure */ -{ - MenuHandle macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl; - - if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) { - Tcl_CancelIdleCall(ReconfigureMacintoshMenu, (ClientData) menuPtr); - menuPtr->menuFlags &= ~MENU_RECONFIGURE_PENDING; - } - - if ((*macMenuHdl)->menuID == currentHelpMenuID) { - MenuHandle helpMenuHdl; - - if ((HMGetHelpMenuHandle(&helpMenuHdl) == noErr) - && (helpMenuHdl != NULL)) { - int i, count = CountMItems(helpMenuHdl); - - for (i = helpItemCount; i <= count; i++) { - DeleteMenuItem(helpMenuHdl, helpItemCount); - } - } - currentHelpMenuID = 0; - } - - if (menuPtr->platformData != NULL) { - DeleteMenu((*macMenuHdl)->menuID); - FreeID((*macMenuHdl)->menuID); - DisposeMenu(macMenuHdl); - ckfree((char *) menuPtr->platformData); - menuPtr->platformData = NULL; - } -} - -/* - *---------------------------------------------------------------------- - * - * SetMenuCascade -- - * - * Does any cleanup to change a menu from a normal to a cascade. - * - * Results: - * Standard Tcl error. - * - * Side effects: - * The mac menu id is reset. - * - *---------------------------------------------------------------------- - */ - -static int -SetMenuCascade( - TkMenu* menuPtr) /* The menu we are setting up to be a - * cascade. */ -{ - MenuHandle macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl; - short newMenuID, menuID = (*macMenuHdl)->menuID; - int error = TCL_OK; - - if (menuID >= 256) { - error = GetNewID(menuPtr->interp, menuPtr, 1, &newMenuID); - if (error == TCL_OK) { - FreeID(menuID); - (*macMenuHdl)->menuID = newMenuID; - } - } - return error; -} - -/* - *---------------------------------------------------------------------- - * - * TkpDestroyMenuEntry -- - * - * Cleans up platform-specific menu entry items. - * - * Results: - * None - * - * Side effects: - * All platform-specific allocations are freed up. - * - *---------------------------------------------------------------------- - */ - -void -TkpDestroyMenuEntry( - TkMenuEntry *mePtr) /* The common structure for the menu - * entry. */ -{ - TkMenu *menuPtr = mePtr->menuPtr; - - ckfree((char *) mePtr->platformEntryData); - if ((menuPtr->platformData != NULL) - && !(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) { - menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) menuPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * GetEntryText -- - * - * Given a menu entry, gives back the text that should go in it. - * Separators should be done by the caller, as they have to be - * handled specially. This is primarily used to do a substitution - * between "..." and "Š". - * - * Results: - * itemText points to the new text for the item. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -GetEntryText( - TkMenuEntry *mePtr, /* A pointer to the menu entry. */ - Tcl_DString *dStringPtr) /* The DString to put the text into. This - * will be initialized by this routine. */ -{ - Tcl_DStringInit(dStringPtr); - if (mePtr->type == TEAROFF_ENTRY) { - Tcl_DStringAppend(dStringPtr, "(Tear-off)", -1); - } else if ((mePtr->imagePtr != NULL) && (mePtr->compound == COMPOUND_NONE)) { - Tcl_DStringAppend(dStringPtr, "(Image)", -1); - } else if ((mePtr->bitmapPtr != NULL) && (mePtr->compound == COMPOUND_NONE)) { - Tcl_DStringAppend(dStringPtr, "(Pixmap)", -1); - } else if (mePtr->labelPtr == NULL || mePtr->labelLength == 0) { - /* - * The Mac menu manager does not like null strings. - */ - - Tcl_DStringAppend(dStringPtr, " ", -1); - } else { - int length; - char *text = Tcl_GetStringFromObj(mePtr->labelPtr, &length); - char *dStringText; - int i; - - for (i = 0; *text; text++, i++) { - if ((*text == '.') - && (*(text + 1) != '\0') && (*(text + 1) == '.') - && (*(text + 2) != '\0') && (*(text + 2) == '.')) { - Tcl_DStringAppend(dStringPtr, elipsisString, -1); - i += strlen(elipsisString) - 1; - text += 2; - } else { - Tcl_DStringSetLength(dStringPtr, - Tcl_DStringLength(dStringPtr) + 1); - dStringText = Tcl_DStringValue(dStringPtr); - dStringText[i] = *text; - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * FindMarkCharacter -- - * - * Finds the Macintosh mark character based on the font of the - * item. We calculate a good mark character based on the font - * that this item is rendered in. - * - * We try the following special mac characters. If none of them - * are present, just use the check mark. - * '' - Check mark character (\022) - * '€' - Mac Bullet character (\245) - * '' - Filled diamond (\023) - * '×' - Hollow diamond (\327) - * '‹' = Mac Long dash ("em dash") (\321) - * '-' = short dash (minus, "en dash"); - * - * Results: - * None. - * - * Side effects: - * New item is added to platform menu - * - *---------------------------------------------------------------------- - */ - -static char -FindMarkCharacter( - TkMenuEntry *mePtr) /* The entry we are finding the character - * for. */ -{ - char markChar; - Tk_Font tkfont; - - tkfont = Tk_GetFontFromObj(mePtr->menuPtr->tkwin, - (mePtr->fontPtr == NULL) ? mePtr->menuPtr->fontPtr - : mePtr->fontPtr); - - if (!TkMacIsCharacterMissing(tkfont, '\022')) { - markChar = '\022'; /* Check mark */ - } else if (!TkMacIsCharacterMissing(tkfont, '\245')) { - markChar = '\245'; /* Bullet */ - } else if (!TkMacIsCharacterMissing(tkfont, '\023')) { - markChar = '\023'; /* Filled Diamond */ - } else if (!TkMacIsCharacterMissing(tkfont, '\327')) { - markChar = '\327'; /* Hollow Diamond */ - } else if (!TkMacIsCharacterMissing(tkfont, '\321')) { - markChar = '\321'; /* Long Dash */ - } else if (!TkMacIsCharacterMissing(tkfont, '-')) { - markChar = '-'; /* Short Dash */ - } else { - markChar = '\022'; /* Check mark */ - } - return markChar; -} - -/* - *---------------------------------------------------------------------- - * - * SetMenuIndicator -- - * - * Sets the Macintosh mark character based on the font of the - * item. - * - * Results: - * None. - * - * Side effects: - * New item is added to platform menu - * - *---------------------------------------------------------------------- - */ - -static void -SetMenuIndicator( - TkMenuEntry *mePtr) /* The entry we are setting */ -{ - TkMenu *menuPtr = mePtr->menuPtr; - MenuHandle macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl; - char markChar; - - /* - * There can be no indicators on menus that are not checkbuttons - * or radiobuttons. However, we should go ahead and set them - * so that menus look right when they are displayed. We should - * not set cascade entries, however, as the mark character - * means something different for cascade items on the Mac. - * Also, we do reflect the tearOff menu items in the Mac menu - * handle, so we ignore them. - */ - - if (mePtr->type == CASCADE_ENTRY) { - return; - } - - markChar = 0; - if ((mePtr->type == RADIO_BUTTON_ENTRY) - || (mePtr->type == CHECK_BUTTON_ENTRY)) { - if (mePtr->indicatorOn && (mePtr->entryFlags & ENTRY_SELECTED)) { - markChar = FindMarkCharacter(mePtr); - } - } - SetItemMark(macMenuHdl, mePtr->index + 1, markChar); -} - -/* - *---------------------------------------------------------------------- - * - * SetMenuTitle -- - * - * Sets title of menu so that the text displays correctly in menubar. - * This code directly manipulates menu handle data. This code - * was originally part of an ancient Apple Developer Response mail. - * - * Results: - * None. - * - * Side effects: - * The menu handle will change size depending on the length of the - * title - * - *---------------------------------------------------------------------- - */ - -static void -SetMenuTitle( - MenuHandle menuHdl, /* The menu we are setting the title of. */ - Tcl_Obj *titlePtr) /* The C string to set the title to. */ -{ - int oldLength, newLength, oldHandleSize, dataLength; - Ptr menuDataPtr; - char *title = (titlePtr == NULL) ? "" - : Tcl_GetStringFromObj(titlePtr, NULL); - - menuDataPtr = (Ptr) (*menuHdl)->menuData; - - if (strncmp(title, menuDataPtr + 1, menuDataPtr[0]) != 0) { - newLength = strlen(title) + 1; - oldLength = menuDataPtr[0] + 1; - oldHandleSize = GetHandleSize((Handle) menuHdl); - dataLength = oldHandleSize - (sizeof(MenuInfo) - sizeof(Str255)) - - oldLength; - if (newLength > oldLength) { - SetHandleSize((Handle) menuHdl, oldHandleSize + (newLength - - oldLength)); - menuDataPtr = (Ptr) (*menuHdl)->menuData; - } - - BlockMove(menuDataPtr + oldLength, menuDataPtr + newLength, - dataLength); - BlockMove(title, menuDataPtr + 1, newLength - 1); - menuDataPtr[0] = newLength - 1; - - if (newLength < oldLength) { - SetHandleSize((Handle) menuHdl, oldHandleSize + (newLength - - oldLength)); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpConfigureMenuEntry -- - * - * Processes configurations for menu entries. - * - * Results: - * Returns standard TCL result. If TCL_ERROR is returned, then - * the interp's result contains an error message. - * - * Side effects: - * Configuration information get set for mePtr; old resources - * get freed, if any need it. - * - *---------------------------------------------------------------------- - */ - -int -TkpConfigureMenuEntry( - register TkMenuEntry *mePtr) /* Information about menu entry; may - * or may not already have values for - * some fields. */ -{ - TkMenu *menuPtr = mePtr->menuPtr; - int index = mePtr->index; - MenuHandle macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl; - MenuHandle helpMenuHdl = NULL; - - /* - * Cascade menus have to have menu IDs of less than 256. So - * we need to change the child menu if this has been configured - * for a cascade item. - */ - - if (mePtr->type == CASCADE_ENTRY) { - if ((mePtr->childMenuRefPtr != NULL) - && (mePtr->childMenuRefPtr->menuPtr != NULL)) { - MenuHandle childMenuHdl = ((MacMenu *) mePtr - ->childMenuRefPtr->menuPtr->platformData)->menuHdl; - - if (childMenuHdl != NULL) { - int error = SetMenuCascade(mePtr->childMenuRefPtr->menuPtr); - - if (error != TCL_OK) { - return error; - } - - if (menuPtr->menuType == MENUBAR) { - SetMenuTitle(childMenuHdl, mePtr->labelPtr); - } - } - } - } - - /* - * We need to parse the accelerator string. If it has the strings - * for Command, Control, Shift or Option, we need to flag it - * so we can draw the symbols for it. We also need to precalcuate - * the position of the first real character we are drawing. - */ - - if (0 == mePtr->accelLength) { - ((EntryGeometry *)mePtr->platformEntryData)->accelTextStart = -1; - } else { - char *accelString = (mePtr->accelPtr == NULL) ? "" - : Tcl_GetStringFromObj(mePtr->accelPtr, NULL); - char *accel = accelString; - mePtr->entryFlags |= ~ENTRY_ACCEL_MASK; - - while (1) { - if ((0 == strncasecmp("Control", accelString, 6)) - && (('-' == accelString[6]) || ('+' == accelString[6]))) { - mePtr->entryFlags |= ENTRY_CONTROL_ACCEL; - accelString += 7; - } else if ((0 == strncasecmp("Ctrl", accelString, 4)) - && (('-' == accelString[4]) || ('+' == accelString[4]))) { - mePtr->entryFlags |= ENTRY_CONTROL_ACCEL; - accelString += 5; - } else if ((0 == strncasecmp("Shift", accelString, 5)) - && (('-' == accelString[5]) || ('+' == accelString[5]))) { - mePtr->entryFlags |= ENTRY_SHIFT_ACCEL; - accelString += 6; - } else if ((0 == strncasecmp("Option", accelString, 6)) - && (('-' == accelString[6]) || ('+' == accelString[6]))) { - mePtr->entryFlags |= ENTRY_OPTION_ACCEL; - accelString += 7; - } else if ((0 == strncasecmp("Opt", accelString, 3)) - && (('-' == accelString[3]) || ('+' == accelString[3]))) { - mePtr->entryFlags |= ENTRY_OPTION_ACCEL; - accelString += 4; - } else if ((0 == strncasecmp("Command", accelString, 7)) - && (('-' == accelString[7]) || ('+' == accelString[7]))) { - mePtr->entryFlags |= ENTRY_COMMAND_ACCEL; - accelString += 8; - } else if ((0 == strncasecmp("Cmd", accelString, 3)) - && (('-' == accelString[3]) || ('+' == accelString[3]))) { - mePtr->entryFlags |= ENTRY_COMMAND_ACCEL; - accelString += 4; - } else if ((0 == strncasecmp("Alt", accelString, 3)) - && (('-' == accelString[3]) || ('+' == accelString[3]))) { - mePtr->entryFlags |= ENTRY_OPTION_ACCEL; - accelString += 4; - } else if ((0 == strncasecmp("Meta", accelString, 4)) - && (('-' == accelString[4]) || ('+' == accelString[4]))) { - mePtr->entryFlags |= ENTRY_COMMAND_ACCEL; - accelString += 5; - } else { - break; - } - } - - ((EntryGeometry *)mePtr->platformEntryData)->accelTextStart - = ((long) accelString - (long) accel); - } - - if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) { - menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) menuPtr); - } - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * ReconfigureIndividualMenu -- - * - * This routine redoes the guts of the menu. It works from - * a base item and offset, so that a regular menu will - * just have all of its items added, but the help menu will - * have all of its items appended after the apple-defined - * items. - * - * Results: - * None. - * - * Side effects: - * The Macintosh menu handle is updated - * - *---------------------------------------------------------------------- - */ - -static void -ReconfigureIndividualMenu( - TkMenu *menuPtr, /* The menu we are affecting. */ - MenuHandle macMenuHdl, /* The macintosh menu we are affecting. - * Will not necessarily be - * menuPtr->platformData because this could - * be the help menu. */ - int base) /* The last index that we do not want - * touched. 0 for normal menus; - * helpMenuItemCount for help menus. */ -{ - int count; - int index; - TkMenuEntry *mePtr; - Str255 itemText; - int parentDisabled = 0; - - for (mePtr = menuPtr->menuRefPtr->parentEntryPtr; mePtr != NULL; - mePtr = mePtr->nextCascadePtr) { - char *name = (mePtr->namePtr == NULL) ? "" - : Tcl_GetStringFromObj(mePtr->namePtr, NULL); - - if (strcmp(Tk_PathName(menuPtr->tkwin), name) == 0) { - if (mePtr->state == ENTRY_DISABLED) { - parentDisabled = 1; - } - break; - } - } - - /* - * First, we get rid of all of the old items. - */ - - count = CountMItems(macMenuHdl); - for (index = base; index < count; index++) { - DeleteMenuItem(macMenuHdl, base + 1); - } - - count = menuPtr->numEntries; - - for (index = 1; index <= count; index++) { - mePtr = menuPtr->entries[index - 1]; - - /* - * We have to do separators separately because SetMenuItemText - * does not parse meta-characters. - */ - - if (mePtr->type == SEPARATOR_ENTRY) { - AppendMenu(macMenuHdl, SEPARATOR_TEXT); - } else { - Tcl_DString itemTextDString; - int destWrote; - - GetEntryText(mePtr, &itemTextDString); - Tcl_UtfToExternal(NULL, NULL, Tcl_DStringValue(&itemTextDString), - Tcl_DStringLength(&itemTextDString), 0, NULL, - (char *) &itemText[1], - 231, NULL, &destWrote, NULL); - itemText[0] = destWrote; - - AppendMenu(macMenuHdl, "\px"); - SetMenuItemText(macMenuHdl, base + index, itemText); - Tcl_DStringFree(&itemTextDString); - - /* - * Set enabling and disabling correctly. - */ - - if (parentDisabled || (mePtr->state == ENTRY_DISABLED)) { - DisableItem(macMenuHdl, base + index); - } else { - EnableItem(macMenuHdl, base + index); - } - - /* - * Set the check mark for check entries and radio entries. - */ - - SetItemMark(macMenuHdl, base + index, 0); - if ((mePtr->type == CHECK_BUTTON_ENTRY) - || (mePtr->type == RADIO_BUTTON_ENTRY)) { - CheckItem(macMenuHdl, base + index, (mePtr->entryFlags - & ENTRY_SELECTED) && mePtr->indicatorOn); - if (mePtr->indicatorOn - && (mePtr->entryFlags & ENTRY_SELECTED)) { - SetItemMark(macMenuHdl, base + index, - FindMarkCharacter(mePtr)); - } - } - - if (mePtr->type == CASCADE_ENTRY) { - if ((mePtr->childMenuRefPtr != NULL) - && (mePtr->childMenuRefPtr->menuPtr != NULL)) { - MenuHandle childMenuHdl = - ((MacMenu *) mePtr->childMenuRefPtr - ->menuPtr->platformData)->menuHdl; - - if (childMenuHdl == NULL) { - childMenuHdl = ((MacMenu *) mePtr->childMenuRefPtr - ->menuPtr->platformData)->menuHdl; - } - if (childMenuHdl != NULL) { - if (TkMacHaveAppearance() > 1) { - SetMenuItemHierarchicalID(macMenuHdl, base + index, - (*childMenuHdl)->menuID); - } else { - SetItemMark(macMenuHdl, base + index, - (*childMenuHdl)->menuID); - SetItemCmd(macMenuHdl, base + index, CASCADE_CMD); - } - } - /* - * If we changed the highligthing of this menu, its - * children all have to be reconfigured so that - * their state will be reflected in the menubar. - */ - - if (!(mePtr->childMenuRefPtr->menuPtr->menuFlags - & MENU_RECONFIGURE_PENDING)) { - mePtr->childMenuRefPtr->menuPtr->menuFlags - |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, - (ClientData) mePtr->childMenuRefPtr->menuPtr); - } - } - } - - if ((mePtr->type != CASCADE_ENTRY) - && (ENTRY_COMMAND_ACCEL - == (mePtr->entryFlags & ENTRY_ACCEL_MASK))) { - char *accel = Tcl_GetStringFromObj(mePtr->accelPtr, NULL); - SetItemCmd(macMenuHdl, base + index, accel[((EntryGeometry *) - mePtr->platformEntryData)->accelTextStart]); - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * ReconfigureMacintoshMenu -- - * - * Rebuilds the Macintosh MenuHandle items from the menu. Called - * usually as an idle handler, but can be called synchronously - * if the menu is about to be posted. - * - * Results: - * None. - * - * Side effects: - * Configuration information get set for mePtr; old resources - * get freed, if any need it. - * - *---------------------------------------------------------------------- - */ - -static void -ReconfigureMacintoshMenu( - ClientData clientData) /* Information about menu entry; may - * or may not already have values for - * some fields. */ -{ - TkMenu *menuPtr = (TkMenu *) clientData; - MenuHandle macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl; - MenuHandle helpMenuHdl = NULL; - - menuPtr->menuFlags &= ~MENU_RECONFIGURE_PENDING; - - if (NULL == macMenuHdl) { - return; - } - - ReconfigureIndividualMenu(menuPtr, macMenuHdl, 0); - - if (menuPtr->menuFlags & MENU_APPLE_MENU) { - AppendResMenu(macMenuHdl, 'DRVR'); - } - - if ((*macMenuHdl)->menuID == currentHelpMenuID) { - HMGetHelpMenuHandle(&helpMenuHdl); - if (helpMenuHdl != NULL) { - ReconfigureIndividualMenu(menuPtr, helpMenuHdl, helpItemCount); - } - } - - if (menuPtr->menuType == MENUBAR) { - if (!(menuBarFlags & MENUBAR_REDRAW_PENDING)) { - Tcl_DoWhenIdle(DrawMenuBarWhenIdle, (ClientData *) NULL); - menuBarFlags |= MENUBAR_REDRAW_PENDING; - } - } -} - -/* - *---------------------------------------------------------------------- - * - * CompleteIdlers -- - * - * Completes all idle handling so that the menus are in sync when - * the user invokes them with the mouse. - * - * Results: - * None. - * - * Side effects: - * The Macintosh menu handles are flushed out. - * - *---------------------------------------------------------------------- - */ - -static void -CompleteIdlers( - TkMenu *menuPtr) /* The menu we are completing. */ -{ - int i; - - if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) { - Tcl_CancelIdleCall(ReconfigureMacintoshMenu, (ClientData) menuPtr); - ReconfigureMacintoshMenu((ClientData) menuPtr); - } - - for (i = 0; i < menuPtr->numEntries; i++) { - if (menuPtr->entries[i]->type == CASCADE_ENTRY) { - if ((menuPtr->entries[i]->childMenuRefPtr != NULL) - && (menuPtr->entries[i]->childMenuRefPtr->menuPtr - != NULL)) { - CompleteIdlers(menuPtr->entries[i]->childMenuRefPtr - ->menuPtr); - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpPostMenu -- - * - * Posts a menu on the screen - * - * Results: - * None. - * - * Side effects: - * The menu is posted and handled. - * - *---------------------------------------------------------------------- - */ - -int -TkpPostMenu( - Tcl_Interp *interp, /* The interpreter this menu lives in */ - TkMenu *menuPtr, /* The menu we are posting */ - int x, /* The global x-coordinate of the top, left- - * hand corner of where the menu is supposed - * to be posted. */ - int y) /* The global y-coordinate */ -{ - MenuHandle macMenuHdl = ((MacMenu *) menuPtr->platformData)->menuHdl; - long popUpResult; - int result; - int oldMode; - - if (inPostMenu) { - Tcl_AppendResult(interp, - "Cannot call post menu while already posting menu", - (char *) NULL); - result = TCL_ERROR; - } else { - Window dummyWin; - unsigned int state; - int dummy, mouseX, mouseY; - short menuID; - Window window; - int oldWidth = menuPtr->totalWidth; - Tk_Window parentWindow = Tk_Parent(menuPtr->tkwin); - - inPostMenu++; - - result = TkPreprocessMenu(menuPtr); - if (result != TCL_OK) { - inPostMenu--; - return result; - } - - /* - * The post commands could have deleted the menu, which means - * we are dead and should go away. - */ - - if (menuPtr->tkwin == NULL) { - inPostMenu--; - return TCL_OK; - } - - CompleteIdlers(menuPtr); - if (menuBarFlags & MENUBAR_REDRAW_PENDING) { - Tcl_CancelIdleCall(DrawMenuBarWhenIdle, (ClientData *) NULL); - DrawMenuBarWhenIdle((ClientData *) NULL); - } - - if (NULL == parentWindow) { - tearoffStruct.excludeRect.top = tearoffStruct.excludeRect.left - = tearoffStruct.excludeRect.bottom - = tearoffStruct.excludeRect.right = SHRT_MAX; - } else { - int left, top; - - Tk_GetRootCoords(parentWindow, &left, &top); - tearoffStruct.excludeRect.left = left; - tearoffStruct.excludeRect.top = top; - tearoffStruct.excludeRect.right = left + Tk_Width(parentWindow); - tearoffStruct.excludeRect.bottom = top + Tk_Height(parentWindow); - if (Tk_Class(parentWindow) == Tk_GetUid("Menubutton")) { - TkWindow *parentWinPtr = (TkWindow *) parentWindow; - TkMenuButton *mbPtr = - (TkMenuButton *) parentWinPtr->instanceData; - int menuButtonWidth = Tk_Width(parentWindow) - - 2 * (mbPtr->highlightWidth + mbPtr->borderWidth + 1); - menuPtr->totalWidth = menuButtonWidth > menuPtr->totalWidth - ? menuButtonWidth : menuPtr->totalWidth; - } - } - - InsertMenu(macMenuHdl, -1); - RecursivelyInsertMenu(menuPtr); - CountMItems(macMenuHdl); - - FixMDEF(); - oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); - popUpResult = PopUpMenuSelect(macMenuHdl, y, x, menuPtr->active); - Tcl_SetServiceMode(oldMode); - - menuPtr->totalWidth = oldWidth; - RecursivelyDeleteMenu(menuPtr); - DeleteMenu((*macMenuHdl)->menuID); - - /* - * Simulate the mouse up. - */ - - XQueryPointer(NULL, None, &dummyWin, &dummyWin, &mouseX, - &mouseY, &dummy, &dummy, &state); - window = Tk_WindowId(menuPtr->tkwin); - TkGenerateButtonEvent(mouseX, mouseY, window, state); - - /* - * Dispatch the command. - */ - - menuID = HiWord(popUpResult); - if (menuID != 0) { - result = TkMacDispatchMenuEvent(menuID, LoWord(popUpResult)); - } else { - TkMacHandleTearoffMenu(); - result = TCL_OK; - } - InvalidateMDEFRgns(); - RecursivelyClearActiveMenu(menuPtr); - - inPostMenu--; - } - return result; -} - -/* - *---------------------------------------------------------------------- - * - * TkpMenuNewEntry -- - * - * Adds a pointer to a new menu entry structure with the platform- - * specific fields filled in. The Macintosh uses the - * platformEntryData field of the TkMenuEntry record to store - * geometry information. - * - * Results: - * Standard TCL error. - * - * Side effects: - * Storage gets allocated. New menu entry data is put into the - * platformEntryData field of the mePtr. - * - *---------------------------------------------------------------------- - */ - -int -TkpMenuNewEntry( - TkMenuEntry *mePtr) /* The menu we are adding an entry to */ -{ - EntryGeometry *geometryPtr = - (EntryGeometry *) ckalloc(sizeof(EntryGeometry)); - TkMenu *menuPtr = mePtr->menuPtr; - - geometryPtr->accelTextStart = 0; - geometryPtr->accelTextWidth = 0; - geometryPtr->nonAccelMargin = 0; - geometryPtr->modifierWidth = 0; - mePtr->platformEntryData = (TkMenuPlatformEntryData) geometryPtr; - if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) { - menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, (ClientData) menuPtr); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * - * Tk_MacTurnOffMenus -- - * - * Turns off all the menu drawing code. This is more than just disabling - * the "menu" command, this means that Tk will NEVER touch the menubar. - * It is needed in the Plugin, where Tk does not own the menubar. - * - * Results: - * None. - * - * Side effects: - * A flag is set which will disable all menu drawing. - * - *---------------------------------------------------------------------- - */ - -void -Tk_MacTurnOffMenus() -{ - gNoTkMenus = 1; -} - -/* - *---------------------------------------------------------------------- - * - * - * DrawMenuBarWhenIdle -- - * - * Update the menu bar next time there is an idle event. - * - * Results: - * None. - * - * Side effects: - * Menu bar is redrawn. - * - *---------------------------------------------------------------------- - */ - -static void -DrawMenuBarWhenIdle( - ClientData clientData) /* ignored here */ -{ - TkMenuReferences *menuRefPtr; - TkMenu *appleMenuPtr, *helpMenuPtr; - MenuHandle macMenuHdl; - Tcl_HashEntry *hashEntryPtr; - - /* - * If we have been turned off, exit. - */ - - if (gNoTkMenus) { - return; - } - - /* - * We need to clear the apple and help menus of any extra items. - */ - - if (currentAppleMenuID != 0) { - hashEntryPtr = Tcl_FindHashEntry(&commandTable, - (char *) currentAppleMenuID); - appleMenuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); - TkpDestroyMenu(appleMenuPtr); - TkpNewMenu(appleMenuPtr); - appleMenuPtr->menuFlags &= ~MENU_APPLE_MENU; - appleMenuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, - (ClientData) appleMenuPtr); - } - - if (currentHelpMenuID != 0) { - hashEntryPtr = Tcl_FindHashEntry(&commandTable, - (char *) currentHelpMenuID); - helpMenuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); - TkpDestroyMenu(helpMenuPtr); - TkpNewMenu(helpMenuPtr); - helpMenuPtr->menuFlags &= ~MENU_HELP_MENU; - helpMenuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, - (ClientData) helpMenuPtr); - } - - /* - * We need to find the clone of this menu that is the menubar. - * Once we do that, for every cascade in the menu, we need to - * insert the Mac menu in the Mac menubar. Finally, we need - * to redraw the menubar. - */ - - menuRefPtr = NULL; - if (currentMenuBarName != NULL) { - menuRefPtr = TkFindMenuReferences(currentMenuBarInterp, - currentMenuBarName); - } - if (menuRefPtr != NULL) { - TkMenu *menuPtr, *menuBarPtr; - TkMenu *cascadeMenuPtr; - char *appleMenuName, *helpMenuName; - int appleIndex = -1, helpIndex = -1; - int i; - - menuPtr = menuRefPtr->menuPtr; - if (menuPtr != NULL) { - TkMenuReferences *specialMenuRefPtr; - TkMenuEntry *specialEntryPtr; - - appleMenuName = ckalloc(strlen(currentMenuBarName) - + 1 + strlen(".apple") + 1); - sprintf(appleMenuName, "%s.apple", - Tk_PathName(menuPtr->tkwin)); - specialMenuRefPtr = TkFindMenuReferences(currentMenuBarInterp, - appleMenuName); - if ((specialMenuRefPtr != NULL) - && (specialMenuRefPtr->menuPtr != NULL)) { - for (specialEntryPtr - = specialMenuRefPtr->parentEntryPtr; - specialEntryPtr != NULL; - specialEntryPtr - = specialEntryPtr->nextCascadePtr) { - if (specialEntryPtr->menuPtr == menuPtr) { - appleIndex = specialEntryPtr->index; - break; - } - } - } - ckfree(appleMenuName); - - helpMenuName = ckalloc(strlen(currentMenuBarName) - + 1 + strlen(".help") + 1); - sprintf(helpMenuName, "%s.help", - Tk_PathName(menuPtr->tkwin)); - specialMenuRefPtr = TkFindMenuReferences(currentMenuBarInterp, - helpMenuName); - if ((specialMenuRefPtr != NULL) - && (specialMenuRefPtr->menuPtr != NULL)) { - for (specialEntryPtr - = specialMenuRefPtr->parentEntryPtr; - specialEntryPtr != NULL; - specialEntryPtr - = specialEntryPtr->nextCascadePtr) { - if (specialEntryPtr->menuPtr == menuPtr) { - helpIndex = specialEntryPtr->index; - break; - } - } - } - ckfree(helpMenuName); - - } - - for (menuBarPtr = menuPtr; - (menuBarPtr != NULL) - && (menuBarPtr->menuType != MENUBAR); - menuBarPtr = menuBarPtr->nextInstancePtr) { - - /* - * Null loop body. - */ - - } - - if (menuBarPtr == NULL) { - SetDefaultMenubar(); - } else { - if (menuBarPtr->tearoff != menuPtr->tearoff) { - if (menuBarPtr->tearoff) { - appleIndex = (-1 == appleIndex) ? appleIndex - : appleIndex + 1; - helpIndex = (-1 == helpIndex) ? helpIndex - : helpIndex + 1; - } else { - appleIndex = (-1 == appleIndex) ? appleIndex - : appleIndex - 1; - helpIndex = (-1 == helpIndex) ? helpIndex - : helpIndex - 1; - } - } - ClearMenuBar(); - - if (appleIndex == -1) { - InsertMenu(tkAppleMenu, 0); - currentAppleMenuID = 0; - } else { - short appleID; - appleMenuPtr = menuBarPtr->entries[appleIndex] - ->childMenuRefPtr->menuPtr; - TkpDestroyMenu(appleMenuPtr); - GetNewID(appleMenuPtr->interp, appleMenuPtr, 0, - &appleID); - macMenuHdl = NewMenu(appleID, "\p\024"); - appleMenuPtr->platformData = - (TkMenuPlatformData) ckalloc(sizeof(MacMenu)); - ((MacMenu *)appleMenuPtr->platformData)->menuHdl - = macMenuHdl; - SetRect(&((MacMenu *) appleMenuPtr->platformData)->menuRect, - 0, 0, 0, 0); - appleMenuPtr->menuFlags |= MENU_APPLE_MENU; - if (!(appleMenuPtr->menuFlags - & MENU_RECONFIGURE_PENDING)) { - appleMenuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, - (ClientData) appleMenuPtr); - } - InsertMenu(macMenuHdl, 0); - RecursivelyInsertMenu(appleMenuPtr); - currentAppleMenuID = appleID; - } - if (helpIndex == -1) { - currentHelpMenuID = 0; - } - - for (i = 0; i < menuBarPtr->numEntries; i++) { - if (i == appleIndex) { - if (menuBarPtr->entries[i]->state == ENTRY_DISABLED) { - DisableItem(((MacMenu *) menuBarPtr->entries[i] - ->childMenuRefPtr->menuPtr - ->platformData)->menuHdl, - 0); - } else { - EnableItem(((MacMenu *) menuBarPtr->entries[i] - ->childMenuRefPtr->menuPtr - ->platformData)->menuHdl, - 0); - } - continue; - } else if (i == helpIndex) { - TkMenu *helpMenuPtr = menuBarPtr->entries[i] - ->childMenuRefPtr->menuPtr; - MenuHandle helpMenuHdl = NULL; - - if (helpMenuPtr == NULL) { - continue; - } - helpMenuPtr->menuFlags |= MENU_HELP_MENU; - if (!(helpMenuPtr->menuFlags - & MENU_RECONFIGURE_PENDING)) { - helpMenuPtr->menuFlags - |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureMacintoshMenu, - (ClientData) helpMenuPtr); - } - macMenuHdl = - ((MacMenu *) helpMenuPtr->platformData)->menuHdl; - currentHelpMenuID = (*macMenuHdl)->menuID; - } else if (menuBarPtr->entries[i]->type - == CASCADE_ENTRY) { - if ((menuBarPtr->entries[i]->childMenuRefPtr != NULL) - && menuBarPtr->entries[i]->childMenuRefPtr - ->menuPtr != NULL) { - cascadeMenuPtr = menuBarPtr->entries[i] - ->childMenuRefPtr->menuPtr; - macMenuHdl = ((MacMenu *) cascadeMenuPtr - ->platformData)->menuHdl; - DeleteMenu((*macMenuHdl)->menuID); - InsertMenu(macMenuHdl, 0); - RecursivelyInsertMenu(cascadeMenuPtr); - if (menuBarPtr->entries[i]->state == ENTRY_DISABLED) { - DisableItem(((MacMenu *) menuBarPtr->entries[i] - ->childMenuRefPtr->menuPtr - ->platformData)->menuHdl, - 0); - } else { - EnableItem(((MacMenu *) menuBarPtr->entries[i] - ->childMenuRefPtr->menuPtr - ->platformData)->menuHdl, - 0); - } - } - } - } - } - } else { - SetDefaultMenubar(); - } - DrawMenuBar(); - menuBarFlags &= ~MENUBAR_REDRAW_PENDING; -} - - -/* - *---------------------------------------------------------------------- - * - * RecursivelyInsertMenu -- - * - * Puts all of the cascades of this menu in the Mac hierarchical list. - * - * - * Results: - * None. - * - * Side effects: - * The menubar is changed. - * - *---------------------------------------------------------------------- - */ - -static void -RecursivelyInsertMenu( - TkMenu *menuPtr) /* All of the cascade items in this menu - * will be inserted into the mac menubar. */ -{ - int i; - TkMenu *cascadeMenuPtr; - MenuHandle macMenuHdl; - - for (i = 0; i < menuPtr->numEntries; i++) { - if (menuPtr->entries[i]->type == CASCADE_ENTRY) { - if ((menuPtr->entries[i]->childMenuRefPtr != NULL) - && (menuPtr->entries[i]->childMenuRefPtr->menuPtr - != NULL)) { - cascadeMenuPtr = menuPtr->entries[i]->childMenuRefPtr->menuPtr; - macMenuHdl = - ((MacMenu *) cascadeMenuPtr->platformData)->menuHdl; - InsertMenu(macMenuHdl, -1); - RecursivelyInsertMenu(cascadeMenuPtr); - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * RecursivelyDeleteMenu -- - * - * Takes all of the cascades of this menu out of the Mac hierarchical - * list. - * - * - * Results: - * None. - * - * Side effects: - * The menubar is changed. - * - *---------------------------------------------------------------------- - */ - -static void -RecursivelyDeleteMenu( - TkMenu *menuPtr) /* All of the cascade items in this menu - * will be inserted into the mac menubar. */ -{ - int i; - TkMenu *cascadeMenuPtr; - MenuHandle macMenuHdl; - - for (i = 0; i < menuPtr->numEntries; i++) { - if (menuPtr->entries[i]->type == CASCADE_ENTRY) { - if ((menuPtr->entries[i]->childMenuRefPtr != NULL) - && (menuPtr->entries[i]->childMenuRefPtr->menuPtr - != NULL)) { - cascadeMenuPtr = menuPtr->entries[i]->childMenuRefPtr->menuPtr; - macMenuHdl = - ((MacMenu *) cascadeMenuPtr->platformData)->menuHdl; - DeleteMenu((*macMenuHdl)->menuID); - RecursivelyInsertMenu(cascadeMenuPtr); - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * SetDefaultMenubar -- - * - * Puts the Apple, File and Edit menus into the Macintosh menubar. - * - * Results: - * None. - * - * Side effects: - * The menubar is changed. - * - *---------------------------------------------------------------------- - */ - -static void -SetDefaultMenubar() -{ - if (currentMenuBarName != NULL) { - ckfree(currentMenuBarName); - currentMenuBarName = NULL; - } - currentMenuBarOwner = NULL; - ClearMenuBar(); - InsertMenu(tkAppleMenu, 0); - InsertMenu(tkFileMenu, 0); - InsertMenu(tkEditMenu, 0); - if (!(menuBarFlags & MENUBAR_REDRAW_PENDING)) { - Tcl_DoWhenIdle(DrawMenuBarWhenIdle, (ClientData *) NULL); - menuBarFlags |= MENUBAR_REDRAW_PENDING; - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpSetMainMenubar -- - * - * Puts the menu associated with a window into the menubar. Should - * only be called when the window is in front. - * - * Results: - * None. - * - * Side effects: - * The menubar is changed. - * - *---------------------------------------------------------------------- - */ - -void -TkpSetMainMenubar( - Tcl_Interp *interp, /* The interpreter of the application */ - Tk_Window tkwin, /* The frame we are setting up */ - char *menuName) /* The name of the menu to put in front. - * If NULL, use the default menu bar. - */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - WindowRef macWindowPtr = (WindowRef) TkMacGetDrawablePort(winPtr->window); - WindowRef frontNonFloating; - - if (TkMacHaveAppearance() >= 0x110) { - frontNonFloating = FrontNonFloatingWindow(); - } else { - frontNonFloating = FrontWindow(); - } - - if ((macWindowPtr == NULL) || (macWindowPtr != frontNonFloating)) { - return; - } - - if ((currentMenuBarInterp != interp) - || (currentMenuBarOwner != tkwin) - || (currentMenuBarName == NULL) - || (menuName == NULL) - || (strcmp(menuName, currentMenuBarName) != 0)) { - Tk_Window searchWindow; - TopLevelMenubarList *listPtr; - - if (currentMenuBarName != NULL) { - ckfree(currentMenuBarName); - } - - if (menuName == NULL) { - searchWindow = tkwin; - if (strcmp(Tk_Class(searchWindow), "Menu") == 0) { - TkMenuReferences *menuRefPtr; - - menuRefPtr = TkFindMenuReferences(interp, Tk_PathName(tkwin)); - if (menuRefPtr != NULL) { - TkMenu *menuPtr = menuRefPtr->menuPtr; - if (menuPtr != NULL) { - menuPtr = menuPtr->masterMenuPtr; - searchWindow = menuPtr->tkwin; - } - } - } - for (; searchWindow != NULL; - searchWindow = Tk_Parent(searchWindow)) { - - for (listPtr = windowListPtr; listPtr != NULL; - listPtr = listPtr->nextPtr) { - if (listPtr->tkwin == searchWindow) { - break; - } - } - if (listPtr != NULL) { - menuName = Tk_PathName(listPtr->menuPtr->masterMenuPtr - ->tkwin); - break; - } - } - } - - if (menuName == NULL) { - currentMenuBarName = NULL; - } else { - currentMenuBarName = ckalloc(strlen(menuName) + 1); - strcpy(currentMenuBarName, menuName); - } - currentMenuBarOwner = tkwin; - currentMenuBarInterp = interp; - } - if (!(menuBarFlags & MENUBAR_REDRAW_PENDING)) { - Tcl_DoWhenIdle(DrawMenuBarWhenIdle, (ClientData *) NULL); - menuBarFlags |= MENUBAR_REDRAW_PENDING; - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpSetWindowMenuBar -- - * - * Associates a given menu with a window. - * - * Results: - * None. - * - * Side effects: - * On Windows and UNIX, associates the platform menu with the - * platform window. - * - *---------------------------------------------------------------------- - */ - -void -TkpSetWindowMenuBar( - Tk_Window tkwin, /* The window we are setting the menu in */ - TkMenu *menuPtr) /* The menu we are setting */ -{ - TopLevelMenubarList *listPtr, *prevPtr; - - /* - * Remove any existing reference to this window. - */ - - for (prevPtr = NULL, listPtr = windowListPtr; - listPtr != NULL; - prevPtr = listPtr, listPtr = listPtr->nextPtr) { - if (listPtr->tkwin == tkwin) { - break; - } - } - - if (listPtr != NULL) { - if (prevPtr != NULL) { - prevPtr->nextPtr = listPtr->nextPtr; - } else { - windowListPtr = listPtr->nextPtr; - } - ckfree((char *) listPtr); - } - - if (menuPtr != NULL) { - listPtr = (TopLevelMenubarList *) ckalloc(sizeof(TopLevelMenubarList)); - listPtr->nextPtr = windowListPtr; - windowListPtr = listPtr; - listPtr->tkwin = tkwin; - listPtr->menuPtr = menuPtr; - } -} - -/* - *---------------------------------------------------------------------- - * - * TkMacDispatchMenuEvent -- - * - * Given a menu id and an item, dispatches the command associated - * with it. - * - * Results: - * None. - * - * Side effects: - * Commands get executed. - * - *---------------------------------------------------------------------- - */ - -int -TkMacDispatchMenuEvent( - int menuID, /* The menu id of the menu we are invoking */ - int index) /* The one-based index of the item that was - * selected. */ -{ - int result = TCL_OK; - if (menuID != 0) { - if (menuID == kHMHelpMenuID) { - if (currentMenuBarOwner != NULL) { - TkMenuReferences *helpMenuRef; - char *helpMenuName = ckalloc(strlen(currentMenuBarName) - + strlen(".help") + 1); - sprintf(helpMenuName, "%s.help", currentMenuBarName); - helpMenuRef = TkFindMenuReferences(currentMenuBarInterp, - helpMenuName); - ckfree(helpMenuName); - if ((helpMenuRef != NULL) && (helpMenuRef->menuPtr != NULL)) { - int newIndex = index - helpItemCount - 1; - result = TkInvokeMenu(currentMenuBarInterp, - helpMenuRef->menuPtr, newIndex); - } - } - } else { - Tcl_HashEntry *commandEntryPtr = - Tcl_FindHashEntry(&commandTable, (char *) menuID); - TkMenu *menuPtr = (TkMenu *) Tcl_GetHashValue(commandEntryPtr); - if ((currentAppleMenuID == menuID) - && (index > menuPtr->numEntries + 1)) { - Str255 itemText; - - GetMenuItemText(GetMenuHandle(menuID), index, itemText); - OpenDeskAcc(itemText); - result = TCL_OK; - } else { - result = TkInvokeMenu(menuPtr->interp, menuPtr, index - 1); - } - } - } - return result; -} - -/* - *---------------------------------------------------------------------- - * - * GetMenuIndicatorGeometry -- - * - * Gets the width and height of the indicator area of a menu. - * - * Results: - * widthPtr and heightPtr are set. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -GetMenuIndicatorGeometry ( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* Precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* Precalculated font metrics */ - int *widthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ -{ - char markChar; - - *heightPtr = fmPtr->linespace; - - markChar = (char) FindMarkCharacter(mePtr); - *widthPtr = Tk_TextWidth(tkfont, &markChar, 1) + 4; -} - -/* - *---------------------------------------------------------------------- - * - * GetMenuAccelGeometry -- - * - * Gets the width and height of the accelerator area of a menu. - * - * Results: - * widthPtr and heightPtr are set. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -GetMenuAccelGeometry ( - TkMenu *menuPtr, /* The menu we are measuring */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - int *modWidthPtr, /* The width of all of the key - * modifier symbols. */ - int *textWidthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ -{ - *heightPtr = fmPtr->linespace; - *modWidthPtr = 0; - if (mePtr->type == CASCADE_ENTRY) { - *textWidthPtr = SICN_HEIGHT; - *modWidthPtr = Tk_TextWidth(tkfont, "W", 1); - } else if (0 == mePtr->accelLength) { - *textWidthPtr = 0; - } else { - char *accel = (mePtr->accelPtr == NULL) ? "" - : Tcl_GetStringFromObj(mePtr->accelPtr, NULL); - - if (NULL == GetResource('SICN', SICN_RESOURCE_NUMBER)) { - *textWidthPtr = Tk_TextWidth(tkfont, accel, mePtr->accelLength); - } else { - int emWidth = Tk_TextWidth(tkfont, "W", 1) + 1; - if ((mePtr->entryFlags & ENTRY_ACCEL_MASK) == 0) { - int width = Tk_TextWidth(tkfont, accel, mePtr->accelLength); - *textWidthPtr = emWidth; - if (width < emWidth) { - *modWidthPtr = 0; - } else { - *modWidthPtr = width - emWidth; - } - } else { - int length = ((EntryGeometry *)mePtr->platformEntryData) - ->accelTextStart; - if (mePtr->entryFlags & ENTRY_CONTROL_ACCEL) { - *modWidthPtr += CONTROL_ICON_WIDTH; - } - if (mePtr->entryFlags & ENTRY_SHIFT_ACCEL) { - *modWidthPtr += SHIFT_ICON_WIDTH; - } - if (mePtr->entryFlags & ENTRY_OPTION_ACCEL) { - *modWidthPtr += OPTION_ICON_WIDTH; - } - if (mePtr->entryFlags & ENTRY_COMMAND_ACCEL) { - *modWidthPtr += COMMAND_ICON_WIDTH; - } - if (1 == (mePtr->accelLength - length)) { - *textWidthPtr = emWidth; - } else { - *textWidthPtr += Tk_TextWidth(tkfont, accel - + length, mePtr->accelLength - length); - } - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * GetTearoffEntryGeometry -- - * - * Gets the width and height of of a tearoff entry. - * - * Results: - * widthPtr and heightPtr are set. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -GetTearoffEntryGeometry ( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - int *widthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ -{ - if ((GetResource('MDEF', 591) == NULL) && - (menuPtr->menuType == MASTER_MENU)) { - *heightPtr = fmPtr->linespace; - *widthPtr = 0; - } else { - *widthPtr = *heightPtr = 0; - } -} - -/* - *---------------------------------------------------------------------- - * - * GetMenuSeparatorGeometry -- - * - * Gets the width and height of menu separator. - * - * Results: - * widthPtr and heightPtr are set. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -GetMenuSeparatorGeometry( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalcualted font metrics */ - int *widthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ -{ - if (TkMacHaveAppearance() > 1) { - SInt16 outHeight; - - GetThemeMenuSeparatorHeight(&outHeight); - *widthPtr = 0; - *heightPtr = outHeight; - } else { - *widthPtr = 0; - *heightPtr = fmPtr->linespace; - } -} - -/* - *---------------------------------------------------------------------- - * - * DrawMenuEntryIndicator -- - * - * This procedure draws the indicator part of a menu. - * - * Results: - * None. - * - * Side effects: - * Commands are output to X to display the menu in its - * current mode. - * - *---------------------------------------------------------------------- - */ - -static void -DrawMenuEntryIndicator( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* The drawable we are drawing */ - GC gc, /* The GC we are drawing with */ - GC indicatorGC, /* The GC to use for the indicator */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - int x, /* topleft hand corner of entry */ - int y, /* topleft hand corner of entry */ - int width, /* width of entry */ - int height) /* height of entry */ -{ - if ((mePtr->type == CHECK_BUTTON_ENTRY) || - (mePtr->type == RADIO_BUTTON_ENTRY)) { - if (mePtr->indicatorOn - && (mePtr->entryFlags & ENTRY_SELECTED)) { - int baseline; - short markShort; - - baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; - GetItemMark(((MacMenu *) menuPtr->platformData)->menuHdl, - mePtr->index + 1, &markShort); - if (markShort != 0) { - char markChar; - char markCharUTF[TCL_UTF_MAX + 1]; - int dstWrote; - - markChar = (char) markShort; - Tcl_ExternalToUtf(NULL, NULL, &markChar, 1, 0, NULL, - markCharUTF, TCL_UTF_MAX + 1, NULL, &dstWrote, NULL); - Tk_DrawChars(menuPtr->display, d, gc, tkfont, markCharUTF, - dstWrote, x + 2, baseline); - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * DrawMenuBackground -- - * - * If Appearance is present, draws the Appearance background - * - * Results: - * Nothing - * - * Side effects: - * Commands are output to X to display the menu in its - * current mode. - * - *---------------------------------------------------------------------- - */ -static void -DrawMenuBackground( - Rect *menuRectPtr, /* The menu rect */ - Drawable d, /* What we are drawing into */ - ThemeMenuType type /* Type of menu */ - ) -{ - if (!TkMacHaveAppearance()) { - return; - } else { - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; - - destPort = TkMacGetDrawablePort(d); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacSetUpClippingRgn(d); - DrawThemeMenuBackground (menuRectPtr, type); - SetGWorld(saveWorld, saveDevice); - return; - } -} - -/* - *---------------------------------------------------------------------- - * - * DrawSICN -- - * - * Given a resource id and an index, loads the appropriate SICN - * and draws it into a given drawable using the given gc. - * - * Results: - * Returns 1 if the SICN was found, 0 if not found. - * - * Side effects: - * Commands are output to X to display the menu in its - * current mode. - * - *---------------------------------------------------------------------- - */ -static int -DrawSICN( - int resourceID, /* The resource # of the SICN table */ - int index, /* The index into the SICN table of the - * icon we want. */ - Drawable d, /* What we are drawing into */ - GC gc, /* The GC to draw with */ - int x, /* The left hand coord of the SICN */ - int y) /* The top coord of the SICN */ -{ - Handle sicnHandle = (Handle) GetResource('SICN', SICN_RESOURCE_NUMBER); - - if (NULL == sicnHandle) { - return 0; - } else { - BitMap sicnBitmap; - Rect destRect; - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; - BitMapPtr destBitMap; - RGBColor origForeColor, origBackColor, foreColor, backColor; - - HLock(sicnHandle); - destPort = TkMacGetDrawablePort(d); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacSetUpClippingRgn(d); - TkMacSetUpGraphicsPort(gc); - GetForeColor(&origForeColor); - GetBackColor(&origBackColor); - - if (TkSetMacColor(gc->foreground, &foreColor)) { - RGBForeColor(&foreColor); - } - - if (TkSetMacColor(gc->background, &backColor)) { - RGBBackColor(&backColor); - } - - SetRect(&destRect, x, y, x + SICN_HEIGHT, y + SICN_HEIGHT); - sicnBitmap.baseAddr = (Ptr) (*sicnHandle) + index * SICN_HEIGHT - * SICN_ROWS; - sicnBitmap.rowBytes = SICN_ROWS; - SetRect(&sicnBitmap.bounds, 0, 0, 16, 16); - destBitMap = &((GrafPtr) destPort)->portBits; - CopyBits(&sicnBitmap, destBitMap, &sicnBitmap.bounds, &destRect, - destPort->txMode, NULL); - HUnlock(sicnHandle); - RGBForeColor(&origForeColor); - RGBBackColor(&origBackColor); - SetGWorld(saveWorld, saveDevice); - return 1; - } -} - -/* - *---------------------------------------------------------------------- - * - * DrawMenuEntryAccelerator -- - * - * This procedure draws the accelerator part of a menu. We - * need to decide what to draw here. Should we replace strings - * like "Control", "Command", etc? - * - * Results: - * None. - * - * Side effects: - * Commands are output to X to display the menu in its - * current mode. - * - *---------------------------------------------------------------------- - */ - -static void -DrawMenuEntryAccelerator( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* The drawable we are drawing in */ - GC gc, /* The gc to draw into */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - Tk_3DBorder activeBorder, /* border for menu background */ - int x, /* The left side of the entry */ - int y, /* The top of the entry */ - int width, /* The width of the entry */ - int height, /* The height of the entry */ - int drawArrow) /* Whether or not to draw cascade arrow */ -{ - int activeBorderWidth; - - Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr, - &activeBorderWidth); - if (mePtr->type == CASCADE_ENTRY) { - /* - * Under Appearance, we let the Appearance Manager draw the icon - */ - - if (!TkMacHaveAppearance()) { - if (0 == DrawSICN(SICN_RESOURCE_NUMBER, CASCADE_ARROW, d, gc, - x + width - SICN_HEIGHT, (y + (height / 2)) - - (SICN_HEIGHT / 2))) { - XPoint points[3]; - Tk_Window tkwin = menuPtr->tkwin; - - if (mePtr->type == CASCADE_ENTRY) { - points[0].x = width - activeBorderWidth - - MAC_MARGIN_WIDTH - CASCADE_ARROW_WIDTH; - points[0].y = y + (height - CASCADE_ARROW_HEIGHT)/2; - points[1].x = points[0].x; - points[1].y = points[0].y + CASCADE_ARROW_HEIGHT; - points[2].x = points[0].x + CASCADE_ARROW_WIDTH; - points[2].y = points[0].y + CASCADE_ARROW_HEIGHT/2; - Tk_Fill3DPolygon(menuPtr->tkwin, d, activeBorder, points, - 3, DECORATION_BORDER_WIDTH, TK_RELIEF_FLAT); - } - } - } - } else if (mePtr->accelLength != 0) { - int leftEdge = x + width; - int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; - char *accel; - - accel = Tcl_GetStringFromObj(mePtr->accelPtr, NULL); - - if (NULL == GetResource('SICN', SICN_RESOURCE_NUMBER)) { - leftEdge -= ((EntryGeometry *) mePtr->platformEntryData) - ->accelTextWidth; - Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel, - mePtr->accelLength, leftEdge, baseline); - } else { - EntryGeometry *geometryPtr = - (EntryGeometry *) mePtr->platformEntryData; - int length = mePtr->accelLength - geometryPtr->accelTextStart; - - leftEdge -= geometryPtr->accelTextWidth; - if ((mePtr->entryFlags & ENTRY_ACCEL_MASK) == 0) { - leftEdge -= geometryPtr->modifierWidth; - } - - Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel - + geometryPtr->accelTextStart, length, leftEdge, baseline); - - if (mePtr->entryFlags & ENTRY_COMMAND_ACCEL) { - leftEdge -= COMMAND_ICON_WIDTH; - DrawSICN(SICN_RESOURCE_NUMBER, COMMAND_ICON, d, gc, - leftEdge, (y + (height / 2)) - (SICN_HEIGHT / 2) - 1); - } - - if (mePtr->entryFlags & ENTRY_OPTION_ACCEL) { - leftEdge -= OPTION_ICON_WIDTH; - DrawSICN(SICN_RESOURCE_NUMBER, OPTION_ICON, d, gc, - leftEdge, (y + (height / 2)) - (SICN_HEIGHT / 2) - 1); - } - - if (mePtr->entryFlags & ENTRY_SHIFT_ACCEL) { - leftEdge -= SHIFT_ICON_WIDTH; - DrawSICN(SICN_RESOURCE_NUMBER, SHIFT_ICON, d, gc, - leftEdge, (y + (height / 2)) - (SICN_HEIGHT / 2) - 1); - } - - if (mePtr->entryFlags & ENTRY_CONTROL_ACCEL) { - leftEdge -= CONTROL_ICON_WIDTH; - DrawSICN(SICN_RESOURCE_NUMBER, CONTROL_ICON, d, gc, - leftEdge, (y + (height / 2)) - (SICN_HEIGHT / 2) - 1); - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * DrawMenuSeparator -- - * - * The menu separator is drawn. - * - * Results: - * None. - * - * Side effects: - * Commands are output to X to display the menu in its - * current mode. - * - *---------------------------------------------------------------------- - */ - -static void -DrawMenuSeparator( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* The drawable we are drawing into */ - GC gc, /* The gc we are drawing with */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - int x, /* left coordinate of entry */ - int y, /* top coordinate of entry */ - int width, /* width of entry */ - int height) /* height of entry */ -{ - CGrafPtr saveWorld; - GDHandle saveDevice; - GWorldPtr destPort; - - destPort = TkMacGetDrawablePort(d); - GetGWorld(&saveWorld, &saveDevice); - SetGWorld(destPort, NULL); - TkMacSetUpClippingRgn(d); - if (TkMacHaveAppearance() > 1) { - Rect r; - r.top = y; - r.left = x; - r.bottom = y + height; - r.right = x + width; - - DrawThemeMenuSeparator(&r); - } else { - /* - * We don't want to use the text GC for drawing the separator. It - * needs to be the same color as disabled items. - */ - - TkMacSetUpGraphicsPort(mePtr->disabledGC != None ? mePtr->disabledGC - : menuPtr->disabledGC); - - MoveTo(x, y + (height / 2)); - Line(width, 0); - - SetGWorld(saveWorld, saveDevice); -} -} - -/* - *---------------------------------------------------------------------- - * - * MenuDefProc -- - * - * This routine is the MDEF handler for Tk. It receives all messages - * for the menu and dispatches them. - * - * Results: - * None. - * - * Side effects: - * This routine causes menus to be drawn and will certainly allocate - * memory as a result. Also, the menu can scroll up and down, and - * various other interface actions can take place. - * - *---------------------------------------------------------------------- - */ - -static void -MenuDefProc( - short message, /* What action are we taking? */ - MenuHandle menu, /* The menu we are working with */ - Rect *menuRectPtr, /* A pointer to the rect for the - * whole menu. */ - Point hitPt, /* Where the mouse was clicked for - * the appropriate messages. */ - short *whichItem, /* Output result. Which item was - * hit by the user? */ - TkMenuLowMemGlobals *globalsPtr) /* The low mem globals we have - * to change */ -{ -#define SCREEN_MARGIN 5 - TkMenu *menuPtr; - TkMenuEntry *parentEntryPtr; - Tcl_HashEntry *commandEntryPtr; - GrafPtr windowMgrPort; - Tk_Font tkfont, menuFont; - Tk_FontMetrics fontMetrics, entryMetrics; - Tk_FontMetrics *fmPtr; - TkMenuEntry *mePtr; - int i; - int maxMenuHeight; - int oldItem; - int newItem = -1; - GDHandle device; - Rect itemRect; - short windowPart; - WindowRef whichWindow; - RGBColor bgColor; - RGBColor fgColor; - RGBColor origFgColor; - PenState origPenState; - Rect dragRect; - Rect scratchRect = {-32768, -32768, 32767, 32767}; - RgnHandle oldClipRgn; - TkMenuReferences *menuRefPtr; - TkMenu *searchMenuPtr; - Rect menuClipRect; - - HLock((Handle) menu); - commandEntryPtr = Tcl_FindHashEntry(&commandTable, - (char *) (*menu)->menuID); - HUnlock((Handle) menu); - menuPtr = (TkMenu *) Tcl_GetHashValue(commandEntryPtr); - - switch (message) { - case mSizeMsg: - GetWMgrPort(&windowMgrPort); - maxMenuHeight = windowMgrPort->portRect.bottom - - windowMgrPort->portRect.top - - GetMBarHeight() - SCREEN_MARGIN; - (*menu)->menuWidth = menuPtr->totalWidth; - (*menu)->menuHeight = maxMenuHeight < menuPtr->totalHeight ? - maxMenuHeight : menuPtr->totalHeight; - break; - - case mDrawMsg: - - /* - * Store away the menu rectangle so we can keep track of the - * different regions that the menu obscures. - */ - - ((MacMenu *) menuPtr->platformData)->menuRect = *menuRectPtr; - if (tkMenuCascadeRgn == NULL) { - tkMenuCascadeRgn = NewRgn(); - } - if (utilRgn == NULL) { - utilRgn = NewRgn(); - } - if (totalMenuRgn == NULL) { - totalMenuRgn = NewRgn(); - } - SetEmptyRgn(tkMenuCascadeRgn); - for (searchMenuPtr = menuPtr; searchMenuPtr != NULL; ) { - RectRgn(utilRgn, - &((MacMenu *) searchMenuPtr->platformData)->menuRect); - InsetRgn(utilRgn, -1, -1); - UnionRgn(tkMenuCascadeRgn, utilRgn, tkMenuCascadeRgn); - OffsetRgn(utilRgn, 1, 1); - UnionRgn(tkMenuCascadeRgn, utilRgn, tkMenuCascadeRgn); - - if (searchMenuPtr->menuRefPtr->parentEntryPtr != NULL) { - searchMenuPtr = searchMenuPtr->menuRefPtr - ->parentEntryPtr->menuPtr; - } else { - break; - } - if (searchMenuPtr->menuType == MENUBAR) { - break; - } - } - UnionRgn(totalMenuRgn, tkMenuCascadeRgn, totalMenuRgn); - SetEmptyRgn(utilRgn); - - /* - * Now draw the background if Appearance is present... - */ - - GetGWorld(&macMDEFDrawable.portPtr, &device); - if (TkMacHaveAppearance() > 1) { - ThemeMenuType menuType; - - if (menuPtr->menuRefPtr->topLevelListPtr != NULL) { - menuType = kThemeMenuTypePullDown; - } else if (menuPtr->menuRefPtr->parentEntryPtr != NULL) { - menuType = kThemeMenuTypeHierarchical; - } else { - menuType = kThemeMenuTypePopUp; - } - - DrawMenuBackground(menuRectPtr, (Drawable) &macMDEFDrawable, - menuType); - } - - /* - * Next, figure out scrolling information. - */ - - menuClipRect = *menuRectPtr; - if ((menuClipRect.bottom - menuClipRect.top) - < menuPtr->totalHeight) { - if (globalsPtr->menuTop < menuRectPtr->top) { - DrawSICN(SICN_RESOURCE_NUMBER, UP_ARROW, - (Drawable) &macMDEFDrawable, - menuPtr->textGC, - menuRectPtr->left - + menuPtr->entries[1]->indicatorSpace, - menuRectPtr->top); - menuClipRect.top += SICN_HEIGHT; - } - if ((globalsPtr->menuTop + menuPtr->totalHeight) - > menuRectPtr->bottom) { - DrawSICN(SICN_RESOURCE_NUMBER, DOWN_ARROW, - (Drawable) &macMDEFDrawable, - menuPtr->textGC, - menuRectPtr->left - + menuPtr->entries[1]->indicatorSpace, - menuRectPtr->bottom - SICN_HEIGHT); - menuClipRect.bottom -= SICN_HEIGHT; - } - GetClip(utilRgn); - } - - /* - * Now, actually draw the menu. Don't draw entries that - * are higher than the top arrow, and don't draw entries - * that are lower than the bottom. - */ - - menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); - Tk_GetFontMetrics(menuFont, &fontMetrics); - for (i = 0; i < menuPtr->numEntries; i++) { - mePtr = menuPtr->entries[i]; - if (globalsPtr->menuTop + mePtr->y + mePtr->height - < menuClipRect.top) { - continue; - } else if (globalsPtr->menuTop + mePtr->y - > menuClipRect.bottom) { - continue; - } - /* ClipRect(&menuClipRect); */ - if (mePtr->fontPtr == NULL) { - fmPtr = &fontMetrics; - tkfont = menuFont; - } else { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr); - Tk_GetFontMetrics(tkfont, &entryMetrics); - fmPtr = &entryMetrics; - } - AppearanceEntryDrawWrapper(mePtr, menuRectPtr, globalsPtr, - (Drawable) &macMDEFDrawable, fmPtr, tkfont, - menuRectPtr->left + mePtr->x, - globalsPtr->menuTop + mePtr->y, - (mePtr->entryFlags & ENTRY_LAST_COLUMN) ? - menuPtr->totalWidth - mePtr->x : mePtr->width, - menuPtr->entries[i]->height); - } - globalsPtr->menuBottom = globalsPtr->menuTop - + menuPtr->totalHeight; - if (!EmptyRgn(utilRgn)) { - SetClip(utilRgn); - SetEmptyRgn(utilRgn); - } - MDEFScrollFlag = 1; - break; - - case mChooseMsg: { - int hasTopScroll, hasBottomScroll; - enum { - DONT_SCROLL, DOWN_SCROLL, UP_SCROLL - } scrollDirection; - Rect updateRect; - short scrollAmt; - RGBColor origForeColor, origBackColor, foreColor, backColor; - - GetGWorld(&macMDEFDrawable.portPtr, &device); - GetForeColor(&origForeColor); - GetBackColor(&origBackColor); - - if (TkSetMacColor(menuPtr->textGC->foreground, - &foreColor)) { - /* if (!TkMacHaveAppearance()) { */ - RGBForeColor(&foreColor); - /* } */ - } - if (TkSetMacColor(menuPtr->textGC->background, - &backColor)) { - /* if (!TkMacHaveAppearance()) { */ - RGBBackColor(&backColor); - /* } */ - } - - /* - * Find out which item was hit. If it is the same as the old item, - * we don't need to do anything. - */ - - oldItem = *whichItem - 1; - - if (PtInRect(hitPt, menuRectPtr)) { - for (i = 0; i < menuPtr->numEntries; i++) { - mePtr = menuPtr->entries[i]; - itemRect.left = menuRectPtr->left + mePtr->x; - itemRect.top = globalsPtr->menuTop + mePtr->y; - if (mePtr->entryFlags & ENTRY_LAST_COLUMN) { - itemRect.right = itemRect.left + menuPtr->totalWidth - - mePtr->x; - } else { - itemRect.right = itemRect.left + mePtr->width; - } - itemRect.bottom = itemRect.top - + menuPtr->entries[i]->height; - if (PtInRect(hitPt, &itemRect)) { - if ((mePtr->type == SEPARATOR_ENTRY) - || (mePtr->state == ENTRY_DISABLED)) { - newItem = -1; - } else { - TkMenuEntry *cascadeEntryPtr; - int parentDisabled = 0; - - for (cascadeEntryPtr - = menuPtr->menuRefPtr->parentEntryPtr; - cascadeEntryPtr != NULL; - cascadeEntryPtr - = cascadeEntryPtr->nextCascadePtr) { - char *name; - - name = Tcl_GetStringFromObj( - cascadeEntryPtr->namePtr, NULL); - if (strcmp(name, Tk_PathName(menuPtr->tkwin)) - == 0) { - if (cascadeEntryPtr->state == ENTRY_DISABLED) { - parentDisabled = 1; - } - break; - } - } - if (parentDisabled) { - newItem = -1; - } else { - newItem = i; - if ((mePtr->type == CASCADE_ENTRY) - && (oldItem != newItem)) { - globalsPtr->itemRect = itemRect; - } - } - } - break; - } - } - } - - /* - * Now we need to take care of scrolling the menu. - */ - - hasTopScroll = globalsPtr->menuTop < menuRectPtr->top; - hasBottomScroll = globalsPtr->menuBottom > menuRectPtr->bottom; - scrollDirection = DONT_SCROLL; - if (hasTopScroll - && (hitPt.v < menuRectPtr->top + SICN_HEIGHT)) { - newItem = -1; - scrollDirection = DOWN_SCROLL; - } else if (hasBottomScroll - && (hitPt.v > menuRectPtr->bottom - SICN_HEIGHT)) { - newItem = -1; - scrollDirection = UP_SCROLL; - } - menuClipRect = *menuRectPtr; - if (hasTopScroll) { - menuClipRect.top += SICN_HEIGHT; - } - if (hasBottomScroll) { - menuClipRect.bottom -= SICN_HEIGHT; - } - if (MDEFScrollFlag) { - scrollDirection = DONT_SCROLL; - MDEFScrollFlag = 0; - } - GetClip(utilRgn); - ClipRect(&menuClipRect); - - if (oldItem != newItem) { - if (oldItem >= 0) { - mePtr = menuPtr->entries[oldItem]; - if (mePtr->fontPtr == NULL) { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, - menuPtr->fontPtr); - } else { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, - mePtr->fontPtr); - } - Tk_GetFontMetrics(tkfont, &fontMetrics); - AppearanceEntryDrawWrapper(mePtr, menuRectPtr, globalsPtr, - (Drawable) &macMDEFDrawable, &fontMetrics, tkfont, - menuRectPtr->left + mePtr->x, - globalsPtr->menuTop + mePtr->y, - (mePtr->entryFlags & ENTRY_LAST_COLUMN) ? - menuPtr->totalWidth - mePtr->x : mePtr->width, - mePtr->height); - } - if (newItem != -1) { - int oldActiveItem = menuPtr->active; - - mePtr = menuPtr->entries[newItem]; - if (mePtr->state != ENTRY_DISABLED) { - TkActivateMenuEntry(menuPtr, newItem); - } - if (mePtr->fontPtr == NULL) { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, - menuPtr->fontPtr); - } else { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, - mePtr->fontPtr); - } - Tk_GetFontMetrics(tkfont, &fontMetrics); - AppearanceEntryDrawWrapper(mePtr, menuRectPtr, globalsPtr, - (Drawable) &macMDEFDrawable, &fontMetrics, tkfont, - menuRectPtr->left + mePtr->x, - globalsPtr->menuTop + mePtr->y, - (mePtr->entryFlags & ENTRY_LAST_COLUMN) ? - menuPtr->totalWidth - mePtr->x : mePtr->width, - mePtr->height); - } - - tkUseMenuCascadeRgn = 1; - MenuSelectEvent(menuPtr); - Tcl_ServiceAll(); - tkUseMenuCascadeRgn = 0; - if (mePtr->state != ENTRY_DISABLED) { - TkActivateMenuEntry(menuPtr, -1); - } - *whichItem = newItem + 1; - } - globalsPtr->menuDisable = ((*menu)->menuID << 16) | (newItem + 1); - - if (scrollDirection == UP_SCROLL) { - scrollAmt = menuClipRect.bottom - hitPt.v; - if (scrollAmt < menuRectPtr->bottom - - globalsPtr->menuBottom) { - scrollAmt = menuRectPtr->bottom - globalsPtr->menuBottom; - } - if (!hasTopScroll && ((globalsPtr->menuTop + scrollAmt) - < menuRectPtr->top)) { - SetRect(&updateRect, menuRectPtr->left, - globalsPtr->menuTop, menuRectPtr->right, - globalsPtr->menuTop + SICN_HEIGHT); - EraseRect(&updateRect); - DrawSICN(SICN_RESOURCE_NUMBER, UP_ARROW, - (Drawable) &macMDEFDrawable, - menuPtr->textGC, menuRectPtr->left - + menuPtr->entries[1]->indicatorSpace, - menuRectPtr->top); - menuClipRect.top += SICN_HEIGHT; - } - } else if (scrollDirection == DOWN_SCROLL) { - scrollAmt = menuClipRect.top - hitPt.v; - if (scrollAmt > menuRectPtr->top - globalsPtr->menuTop) { - scrollAmt = menuRectPtr->top - globalsPtr->menuTop; - } - if (!hasBottomScroll && ((globalsPtr->menuBottom + scrollAmt) - > menuRectPtr->bottom)) { - SetRect(&updateRect, menuRectPtr->left, - globalsPtr->menuBottom - SICN_HEIGHT, - menuRectPtr->right, globalsPtr->menuBottom); - EraseRect(&updateRect); - DrawSICN(SICN_RESOURCE_NUMBER, DOWN_ARROW, - (Drawable) &macMDEFDrawable, - menuPtr->textGC, menuRectPtr->left - + menuPtr->entries[1]->indicatorSpace, - menuRectPtr->bottom - SICN_HEIGHT); - menuClipRect.bottom -= SICN_HEIGHT; - } - } - if (scrollDirection != DONT_SCROLL) { - Tk_Font menuFont; - RgnHandle updateRgn = NewRgn(); - ScrollRect(&menuClipRect, 0, scrollAmt, updateRgn); - updateRect = (*updateRgn)->rgnBBox; - DisposeRgn(updateRgn); - globalsPtr->menuTop += scrollAmt; - globalsPtr->menuBottom += scrollAmt; - if (globalsPtr->menuTop == menuRectPtr->top) { - updateRect.top -= SICN_HEIGHT; - } - if (globalsPtr->menuBottom == menuRectPtr->bottom) { - updateRect.bottom += SICN_HEIGHT; - } - ClipRect(&updateRect); - EraseRect(&updateRect); - menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); - Tk_GetFontMetrics(menuFont, &fontMetrics); - for (i = 0; i < menuPtr->numEntries; i++) { - mePtr = menuPtr->entries[i]; - if (globalsPtr->menuTop + mePtr->y + mePtr->height - < updateRect.top) { - continue; - } else if (globalsPtr->menuTop + mePtr->y - > updateRect.bottom) { - continue; - } - if (mePtr->fontPtr == NULL) { - fmPtr = &fontMetrics; - tkfont = menuFont; - } else { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, - mePtr->fontPtr); - Tk_GetFontMetrics(tkfont, &entryMetrics); - fmPtr = &entryMetrics; - } - AppearanceEntryDrawWrapper(mePtr, menuRectPtr, globalsPtr, - (Drawable) &macMDEFDrawable, fmPtr, tkfont, - menuRectPtr->left + mePtr->x, - globalsPtr->menuTop + mePtr->y, - (mePtr->entryFlags & ENTRY_LAST_COLUMN) ? - menuPtr->totalWidth - mePtr->x : mePtr->width, - menuPtr->entries[i]->height); - } - } - - SetClip(utilRgn); - SetEmptyRgn(utilRgn); - RGBForeColor(&origForeColor); - RGBBackColor(&origBackColor); - - /* - * If the menu is a tearoff, and the mouse is outside the menu, - * we need to draw the drag rectangle. - * - * In order for tearoffs to work properly, we need to set - * the active member of the containing menubar. - */ - - menuRefPtr = TkFindMenuReferences(menuPtr->interp, - Tk_PathName(menuPtr->tkwin)); - if ((menuRefPtr != NULL) && (menuRefPtr->parentEntryPtr != NULL)) { - char *name; - for (parentEntryPtr = menuRefPtr->parentEntryPtr; - parentEntryPtr != NULL - ; parentEntryPtr = parentEntryPtr->nextCascadePtr) { - name = Tcl_GetStringFromObj(parentEntryPtr->namePtr, - NULL); - if (strcmp(name, Tk_PathName(menuPtr->tkwin)) != 0) { - break; - } - } - if (parentEntryPtr != NULL) { - TkActivateMenuEntry(parentEntryPtr->menuPtr, - parentEntryPtr->index); - } - } - - if (menuPtr->tearoff) { - scratchRect = *menuRectPtr; - if (tearoffStruct.menuPtr == NULL) { - scratchRect.top -= 10; - scratchRect.bottom += 10; - scratchRect.left -= 10; - scratchRect.right += 10; - } - - windowPart = FindWindow(hitPt, &whichWindow); - if ((windowPart != inMenuBar) && (newItem == -1) - && (hitPt.v != 0) && (hitPt.h != 0) - && (!PtInRect(hitPt, &scratchRect)) - && (!PtInRect(hitPt, &tearoffStruct.excludeRect))) { -/* - * This is the second argument to the Toolbox Delay function. It changed - * from long to unsigned long between Universal Headers 2.0 & 3.0 - */ -#if !defined(UNIVERSAL_INTERFACES_VERSION) || (UNIVERSAL_INTERFACES_VERSION < 0x0300) - long dummy; -#else - unsigned long dummy; -#endif - oldClipRgn = NewRgn(); - GetClip(oldClipRgn); - GetForeColor(&origFgColor); - GetPenState(&origPenState); - GetForeColor(&fgColor); - GetBackColor(&bgColor); - GetGray(device, &bgColor, &fgColor); - RGBForeColor(&fgColor); - SetRect(&scratchRect, -32768, -32768, 32767, 32767); - ClipRect(&scratchRect); - - dragRect = *menuRectPtr; - tearoffStruct.menuPtr = menuPtr; - - PenMode(srcXor); - dragRect = *menuRectPtr; - OffsetRect(&dragRect, -dragRect.left, -dragRect.top); - OffsetRect(&dragRect, tearoffStruct.point.h, - tearoffStruct.point.v); - if ((dragRect.top != 0) && (dragRect.left != 0)) { - FrameRect(&dragRect); - Delay(1, &dummy); - FrameRect(&dragRect); - } - tearoffStruct.point = hitPt; - - SetClip(oldClipRgn); - DisposeRgn(oldClipRgn); - RGBForeColor(&origFgColor); - SetPenState(&origPenState); - } else { - tearoffStruct.menuPtr = NULL; - tearoffStruct.point.h = tearoffStruct.point.v = 0; - } - } else { - tearoffStruct.menuPtr = NULL; - tearoffStruct.point.h = tearoffStruct.point.v = 0; - } - - break; - } - - case mPopUpMsg: - - /* - * Note that for some oddball reason, h and v are reversed in the - * point given to us by the MDEF. - */ - - oldItem = *whichItem; - if (oldItem >= menuPtr->numEntries) { - oldItem = -1; - } - GetWMgrPort(&windowMgrPort); - maxMenuHeight = windowMgrPort->portRect.bottom - - windowMgrPort->portRect.top - - GetMBarHeight() - SCREEN_MARGIN; - if (menuPtr->totalHeight > maxMenuHeight) { - menuRectPtr->top = GetMBarHeight(); - } else { - int delta; - menuRectPtr->top = hitPt.h; - if (oldItem >= 0) { - menuRectPtr->top -= menuPtr->entries[oldItem]->y; - } - - if (menuRectPtr->top < GetMBarHeight()) { - /* Displace downward if the menu would stick off the - * top of the screen. - */ - - menuRectPtr->top = GetMBarHeight() + SCREEN_MARGIN; - } else { - /* - * Or upward if the menu sticks off the - * bottom end... - */ - - delta = menuRectPtr->top + menuPtr->totalHeight - - maxMenuHeight; - if (delta > 0) { - menuRectPtr->top -= delta; - } - } - } - menuRectPtr->left = hitPt.v; - menuRectPtr->right = menuRectPtr->left + menuPtr->totalWidth; - menuRectPtr->bottom = menuRectPtr->top + - ((maxMenuHeight < menuPtr->totalHeight) - ? maxMenuHeight : menuPtr->totalHeight); - if (menuRectPtr->top == GetMBarHeight()) { - *whichItem = hitPt.h; - } else { - *whichItem = menuRectPtr->top; - } - globalsPtr->menuTop = *whichItem; - globalsPtr->menuBottom = menuRectPtr->bottom; - break; - } -} - -/* - *---------------------------------------------------------------------- - * - * AppearanceEntryDrawWrapper -- - * - * This routine wraps the TkpDrawMenuEntry function. Under Appearance, - * it routes to the Appearance Managers DrawThemeEntry, otherwise it - * just goes straight to TkpDrawMenuEntry. - * - * Results: - * A menu entry is drawn - * - * Side effects: - * None - * - *---------------------------------------------------------------------- - */ -static void -AppearanceEntryDrawWrapper( - TkMenuEntry *mePtr, - Rect *menuRectPtr, - TkMenuLowMemGlobals *globalsPtr, - Drawable d, - Tk_FontMetrics *fmPtr, - Tk_Font tkfont, - int x, - int y, - int width, - int height) -{ - if (TkMacHaveAppearance() > 1) { - MenuEntryUserData meData; - Rect itemRect; - ThemeMenuState theState; - ThemeMenuItemType theType; - - meData.mePtr = mePtr; - meData.mdefDrawable = d; - meData.fmPtr = fmPtr; - meData.tkfont = tkfont; - - itemRect.top = y; - itemRect.left = x; - itemRect.bottom = itemRect.top + height; - itemRect.right = itemRect.left + width; - - if (mePtr->state == ENTRY_ACTIVE) { - theState = kThemeMenuSelected; - } else if (mePtr->state == ENTRY_DISABLED) { - theState = kThemeMenuDisabled; - } else { - theState = kThemeMenuActive; - } - - if (mePtr->type == CASCADE_ENTRY) { - theType = kThemeMenuItemHierarchical; - } else { - theType = kThemeMenuItemPlain; - } - - DrawThemeMenuItem (menuRectPtr, &itemRect, - globalsPtr->menuTop, globalsPtr->menuBottom, theState, - theType, tkThemeMenuItemDrawingUPP, - (unsigned long) &meData); - - } else { - TkpDrawMenuEntry(mePtr, d, tkfont, fmPtr, - x, y, width, height, 0, 1); - } -} - -/* - *---------------------------------------------------------------------- - * - * tkThemeMenuItemDrawingProc -- - * - * This routine is called from the Appearance DrawThemeMenuEntry - * - * Results: - * A menu entry is drawn - * - * Side effects: - * None - * - *---------------------------------------------------------------------- - */ -pascal void -tkThemeMenuItemDrawingProc ( - const Rect *inBounds, - SInt16 inDepth, - Boolean inIsColorDevice, - SInt32 inUserData) -{ - MenuEntryUserData *meData = (MenuEntryUserData *) inUserData; - - TkpDrawMenuEntry(meData->mePtr, meData->mdefDrawable, - meData->tkfont, meData->fmPtr, inBounds->left, - inBounds->top, inBounds->right - inBounds->left, - inBounds->bottom - inBounds->top, 0, 1); - -} - -/* - *---------------------------------------------------------------------- - * - * TkMacHandleTearoffMenu() -- - * - * This routine sees if the MDEF has set a menu and a mouse position - * for tearing off and makes a tearoff menu if it has. - * - * Results: - * menuPtr->interp will have the result of the tearoff command. - * - * Side effects: - * A new tearoff menu is created if it is supposed to be. - * - *---------------------------------------------------------------------- - */ - -void -TkMacHandleTearoffMenu(void) -{ - if (tearoffStruct.menuPtr != NULL) { - Tcl_DString tearoffCmdStr; - char intString[TCL_INTEGER_SPACE]; - short windowPart; - WindowRef whichWindow; - - windowPart = FindWindow(tearoffStruct.point, &whichWindow); - - if (windowPart != inMenuBar) { - Tcl_DStringInit(&tearoffCmdStr); - Tcl_DStringAppendElement(&tearoffCmdStr, "tk::TearOffMenu"); - Tcl_DStringAppendElement(&tearoffCmdStr, - Tk_PathName(tearoffStruct.menuPtr->tkwin)); - sprintf(intString, "%d", tearoffStruct.point.h); - Tcl_DStringAppendElement(&tearoffCmdStr, intString); - sprintf(intString, "%d", tearoffStruct.point.v); - Tcl_DStringAppendElement(&tearoffCmdStr, intString); - Tcl_Eval(tearoffStruct.menuPtr->interp, - Tcl_DStringValue(&tearoffCmdStr)); - Tcl_DStringFree(&tearoffCmdStr); - tearoffStruct.menuPtr = NULL; - } - } -} - -/* - *-------------------------------------------------------------- - * - * TkpInitializeMenuBindings -- - * - * For every interp, initializes the bindings for Windows - * menus. Does nothing on Mac or XWindows. - * - * Results: - * None. - * - * Side effects: - * C-level bindings are setup for the interp which will - * handle Alt-key sequences for menus without beeping - * or interfering with user-defined Alt-key bindings. - * - *-------------------------------------------------------------- - */ - -void -TkpInitializeMenuBindings(interp, bindingTable) - Tcl_Interp *interp; /* The interpreter to set. */ - Tk_BindingTable bindingTable; /* The table to add to. */ -{ - /* - * Nothing to do. - */ -} - -/* - *-------------------------------------------------------------- - * - * TkpComputeMenubarGeometry -- - * - * This procedure is invoked to recompute the size and - * layout of a menu that is a menubar clone. - * - * Results: - * None. - * - * Side effects: - * Fields of menu entries are changed to reflect their - * current positions, and the size of the menu window - * itself may be changed. - * - *-------------------------------------------------------------- - */ - -void -TkpComputeMenubarGeometry(menuPtr) - TkMenu *menuPtr; /* Structure describing menu. */ -{ - TkpComputeStandardMenuGeometry(menuPtr); -} - -/* - *---------------------------------------------------------------------- - * - * DrawTearoffEntry -- - * - * This procedure draws the background part of a menu. - * - * Results: - * None. - * - * Side effects: - * Commands are output to X to display the menu in its - * current mode. - * - *---------------------------------------------------------------------- - */ - -void -DrawTearoffEntry( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* The drawable we are drawing into */ - GC gc, /* The gc we are drawing with */ - Tk_Font tkfont, /* The font we are drawing with */ - CONST Tk_FontMetrics *fmPtr, /* The metrics we are drawing with */ - int x, /* Left edge of entry. */ - int y, /* Top edge of entry. */ - int width, /* Width of entry. */ - int height) /* Height of entry. */ -{ - XPoint points[2]; - int margin, segmentWidth, maxX; - Tk_3DBorder border; - - if ((menuPtr->menuType != MASTER_MENU) || (FixMDEF() != NULL)) { - return; - } - - margin = (fmPtr->ascent + fmPtr->descent)/2; - points[0].x = x; - points[0].y = y + height/2; - points[1].y = points[0].y; - segmentWidth = 6; - maxX = width - 1; - border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); - - while (points[0].x < maxX) { - points[1].x = points[0].x + segmentWidth; - if (points[1].x > maxX) { - points[1].x = maxX; - } - Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1, - TK_RELIEF_RAISED); - points[0].x += 2*segmentWidth; - } -} - -/* - *---------------------------------------------------------------------- - * - * TkMacSetHelpMenuItemCount -- - * - * Has to be called after the first call to InsertMenu. Sets - * up the global variable for the number of items in the - * unmodified help menu. - * - * Results: - * None. - * - * Side effects: - * Sets the global helpItemCount. - * - *---------------------------------------------------------------------- - */ - -void -TkMacSetHelpMenuItemCount() -{ - MenuHandle helpMenuHandle; - - if ((HMGetHelpMenuHandle(&helpMenuHandle) != noErr) - || (helpMenuHandle == NULL)) { - helpItemCount = -1; - } else { - helpItemCount = CountMItems(helpMenuHandle); - DeleteMenuItem(helpMenuHandle, helpItemCount); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkMacMenuClick -- - * - * Prepares a menubar for MenuSelect or MenuKey. - * - * Results: - * None. - * - * Side effects: - * Any pending configurations of the menubar are completed. - * - *---------------------------------------------------------------------- - */ - -void -TkMacMenuClick() -{ - TkMenu *menuPtr; - TkMenuReferences *menuRefPtr; - - if ((currentMenuBarInterp != NULL) && (currentMenuBarName != NULL)) { - menuRefPtr = TkFindMenuReferences(currentMenuBarInterp, - currentMenuBarName); - for (menuPtr = menuRefPtr->menuPtr->masterMenuPtr; - menuPtr != NULL; menuPtr = menuPtr->nextInstancePtr) { - if (menuPtr->menuType == MENUBAR) { - CompleteIdlers(menuPtr); - break; - } - } - } - - if (menuBarFlags & MENUBAR_REDRAW_PENDING) { - Tcl_CancelIdleCall(DrawMenuBarWhenIdle, (ClientData *) NULL); - DrawMenuBarWhenIdle((ClientData *) NULL); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpDrawMenuEntry -- - * - * Draws the given menu entry at the given coordinates with the - * given attributes. - * - * Results: - * None. - * - * Side effects: - * X Server commands are executed to display the menu entry. - * - *---------------------------------------------------------------------- - */ - -void -TkpDrawMenuEntry( - TkMenuEntry *mePtr, /* The entry to draw */ - Drawable d, /* What to draw into */ - Tk_Font tkfont, /* Precalculated font for menu */ - CONST Tk_FontMetrics *menuMetricsPtr, - /* Precalculated metrics for menu */ - int x, /* X-coordinate of topleft of entry */ - int y, /* Y-coordinate of topleft of entry */ - int width, /* Width of the entry rectangle */ - int height, /* Height of the current rectangle */ - int strictMotif, /* Boolean flag */ - int drawArrow) /* Whether or not to draw the cascade - * arrow for cascade items. Only applies - * to Windows. */ -{ - GC gc; - TkMenu *menuPtr = mePtr->menuPtr; - int padY = (menuPtr->menuType == MENUBAR) ? 3 : 0; - GC indicatorGC; - Tk_3DBorder bgBorder, activeBorder; - const Tk_FontMetrics *fmPtr; - Tk_FontMetrics entryMetrics; - int adjustedY = y + padY; - int adjustedHeight = height - 2 * padY; - - /* - * Choose the gc for drawing the foreground part of the entry. - * Under Appearance, we pass a null (appearanceGC) to tell - * ourselves not to change whatever color the appearance manager has set. - */ - - if ((mePtr->state == ENTRY_ACTIVE) && !strictMotif) { - gc = mePtr->activeGC; - if (gc == NULL) { - gc = menuPtr->activeGC; - } - } else { - TkMenuEntry *cascadeEntryPtr; - int parentDisabled = 0; - - for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr; - cascadeEntryPtr != NULL; - cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) { - char *name = (cascadeEntryPtr->namePtr == NULL) ? "" - : Tcl_GetStringFromObj(cascadeEntryPtr->namePtr, NULL); - - if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) { - if (cascadeEntryPtr->state == ENTRY_DISABLED) { - parentDisabled = 1; - } - break; - } - } - - if (((parentDisabled || (mePtr->state == ENTRY_DISABLED))) - && (menuPtr->disabledFgPtr != NULL)) { - gc = mePtr->disabledGC; - if (gc == NULL) { - gc = menuPtr->disabledGC; - } - } else { - gc = mePtr->textGC; - if (gc == NULL) { - gc = menuPtr->textGC; - } - } - } - - indicatorGC = mePtr->indicatorGC; - if (indicatorGC == NULL) { - indicatorGC = menuPtr->indicatorGC; - } - - bgBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin, - (mePtr->borderPtr == NULL) - ? menuPtr->borderPtr : mePtr->borderPtr); - if (strictMotif) { - activeBorder = bgBorder; - } else { - activeBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin, - (mePtr->activeBorderPtr == NULL) - ? menuPtr->activeBorderPtr : mePtr->activeBorderPtr); - } - - if (mePtr->fontPtr == NULL) { - fmPtr = menuMetricsPtr; - } else { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr); - Tk_GetFontMetrics(tkfont, &entryMetrics); - fmPtr = &entryMetrics; - } - - /* - * Need to draw the entire background, including padding. On Unix, - * for menubars, we have to draw the rest of the entry taking - * into account the padding. - */ - - DrawMenuEntryBackground(menuPtr, mePtr, d, activeBorder, - bgBorder, x, y, width, height); - - if (mePtr->type == SEPARATOR_ENTRY) { - DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont, - fmPtr, x, adjustedY, width, adjustedHeight); - } else if (mePtr->type == TEAROFF_ENTRY) { - DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY, - width, adjustedHeight); - } else { - DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, - adjustedY, width, adjustedHeight); - DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr, - activeBorder, x, adjustedY, width, adjustedHeight, drawArrow); - if (!mePtr->hideMargin) { - DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont, - fmPtr, x, adjustedY, width, adjustedHeight); - } - - } -} - -/* - *-------------------------------------------------------------- - * - * TkpComputeStandardMenuGeometry -- - * - * This procedure is invoked to recompute the size and - * layout of a menu that is not a menubar clone. - * - * Results: - * None. - * - * Side effects: - * Fields of menu entries are changed to reflect their - * current positions, and the size of the menu window - * itself may be changed. - * - *-------------------------------------------------------------- - */ - -void -TkpComputeStandardMenuGeometry( - TkMenu *menuPtr) /* Structure describing menu. */ -{ - Tk_Font tkfont, menuFont; - Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr; - int x, y, height, modifierWidth, labelWidth, indicatorSpace; - int windowWidth, windowHeight, accelWidth, maxAccelTextWidth; - int i, j, lastColumnBreak, maxModifierWidth, maxWidth, nonAccelMargin; - int maxNonAccelMargin, maxEntryWithAccelWidth, maxEntryWithoutAccelWidth; - int entryWidth, maxIndicatorSpace, borderWidth, activeBorderWidth; - TkMenuEntry *mePtr, *columnEntryPtr; - EntryGeometry *geometryPtr; - - if (menuPtr->tkwin == NULL) { - return; - } - - Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr, - &borderWidth); - Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr, - &activeBorderWidth); - x = y = borderWidth; - indicatorSpace = labelWidth = accelWidth = maxAccelTextWidth = 0; - windowHeight = windowWidth = maxWidth = lastColumnBreak = 0; - maxModifierWidth = nonAccelMargin = maxNonAccelMargin = 0; - maxEntryWithAccelWidth = maxEntryWithoutAccelWidth = 0; - maxIndicatorSpace = 0; - - /* - * On the Mac especially, getting font metrics can be quite slow, - * so we want to do it intelligently. We are going to precalculate - * them and pass them down to all of the measuring and drawing - * routines. We will measure the font metrics of the menu once. - * If an entry does not have its own font set, then we give - * the geometry/drawing routines the menu's font and metrics. - * If an entry has its own font, we will measure that font and - * give all of the geometry/drawing the entry's font and metrics. - */ - - menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); - Tk_GetFontMetrics(menuFont, &menuMetrics); - - for (i = 0; i < menuPtr->numEntries; i++) { - mePtr = menuPtr->entries[i]; - if (mePtr->fontPtr == NULL) { - tkfont = menuFont; - fmPtr = &menuMetrics; - } else { - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr); - Tk_GetFontMetrics(tkfont, &entryMetrics); - fmPtr = &entryMetrics; - } - - if ((i > 0) && mePtr->columnBreak) { - if (maxIndicatorSpace != 0) { - maxIndicatorSpace += 2; - } - for (j = lastColumnBreak; j < i; j++) { - columnEntryPtr = menuPtr->entries[j]; - geometryPtr = - (EntryGeometry *) columnEntryPtr->platformEntryData; - - columnEntryPtr->indicatorSpace = maxIndicatorSpace; - columnEntryPtr->width = maxIndicatorSpace + maxWidth - + 2 * activeBorderWidth; - geometryPtr->accelTextWidth = maxAccelTextWidth; - geometryPtr->modifierWidth = maxModifierWidth; - columnEntryPtr->x = x; - columnEntryPtr->entryFlags &= ~ENTRY_LAST_COLUMN; - if (maxEntryWithoutAccelWidth > maxEntryWithAccelWidth) { - geometryPtr->nonAccelMargin = maxEntryWithoutAccelWidth - - maxEntryWithAccelWidth; - if (geometryPtr->nonAccelMargin > maxNonAccelMargin) { - geometryPtr->nonAccelMargin = maxNonAccelMargin; - } - } else { - geometryPtr->nonAccelMargin = 0; - } - } - x += maxIndicatorSpace + maxWidth + 2 * borderWidth; - windowWidth = x; - maxWidth = maxIndicatorSpace = maxAccelTextWidth = 0; - maxModifierWidth = maxNonAccelMargin = maxEntryWithAccelWidth = 0; - maxEntryWithoutAccelWidth = 0; - lastColumnBreak = i; - y = borderWidth; - } - - if (mePtr->type == SEPARATOR_ENTRY) { - GetMenuSeparatorGeometry(menuPtr, mePtr, tkfont, - fmPtr, &entryWidth, &height); - mePtr->height = height; - } else if (mePtr->type == TEAROFF_ENTRY) { - GetTearoffEntryGeometry(menuPtr, mePtr, tkfont, - fmPtr, &entryWidth, &height); - mePtr->height = height; - } else { - /* - * For each entry, compute the height required by that - * particular entry, plus three widths: the width of the - * label, the width to allow for an indicator to be displayed - * to the left of the label (if any), and the width of the - * accelerator to be displayed to the right of the label - * (if any). These sizes depend, of course, on the type - * of the entry. - */ - - GetMenuLabelGeometry(mePtr, tkfont, fmPtr, &labelWidth, - &height); - mePtr->height = height; - - if (mePtr->type == CASCADE_ENTRY) { - GetMenuAccelGeometry(menuPtr, mePtr, tkfont, fmPtr, - &modifierWidth, &accelWidth, &height); - nonAccelMargin = 0; - } else if (mePtr->accelLength == 0) { - nonAccelMargin = mePtr->hideMargin ? 0 - : Tk_TextWidth(tkfont, "m", 1); - accelWidth = modifierWidth = 0; - } else { - labelWidth += Tk_TextWidth(tkfont, "m", 1); - GetMenuAccelGeometry(menuPtr, mePtr, tkfont, - fmPtr, &modifierWidth, &accelWidth, &height); - if (height > mePtr->height) { - mePtr->height = height; - } - nonAccelMargin = 0; - } - - if (!(mePtr->hideMargin)) { - GetMenuIndicatorGeometry(menuPtr, mePtr, tkfont, - fmPtr, &indicatorSpace, &height); - if (height > mePtr->height) { - mePtr->height = height; - } - } else { - indicatorSpace = 0; - } - - if (nonAccelMargin > maxNonAccelMargin) { - maxNonAccelMargin = nonAccelMargin; - } - if (accelWidth > maxAccelTextWidth) { - maxAccelTextWidth = accelWidth; - } - if (modifierWidth > maxModifierWidth) { - maxModifierWidth = modifierWidth; - } - if (indicatorSpace > maxIndicatorSpace) { - maxIndicatorSpace = indicatorSpace; - } - - entryWidth = labelWidth + modifierWidth + accelWidth - + nonAccelMargin; - - if (entryWidth > maxWidth) { - maxWidth = entryWidth; - } - - if (mePtr->accelLength > 0) { - if (entryWidth > maxEntryWithAccelWidth) { - maxEntryWithAccelWidth = entryWidth; - } - } else { - if (entryWidth > maxEntryWithoutAccelWidth) { - maxEntryWithoutAccelWidth = entryWidth; - } - } - - mePtr->height += 2 * activeBorderWidth; - } - mePtr->y = y; - y += menuPtr->entries[i]->height + borderWidth; - if (y > windowHeight) { - windowHeight = y; - } - } - - for (j = lastColumnBreak; j < menuPtr->numEntries; j++) { - columnEntryPtr = menuPtr->entries[j]; - geometryPtr = (EntryGeometry *) columnEntryPtr->platformEntryData; - - columnEntryPtr->indicatorSpace = maxIndicatorSpace; - columnEntryPtr->width = maxIndicatorSpace + maxWidth - + 2 * activeBorderWidth; - geometryPtr->accelTextWidth = maxAccelTextWidth; - geometryPtr->modifierWidth = maxModifierWidth; - columnEntryPtr->x = x; - columnEntryPtr->entryFlags |= ENTRY_LAST_COLUMN; - if (maxEntryWithoutAccelWidth > maxEntryWithAccelWidth) { - geometryPtr->nonAccelMargin = maxEntryWithoutAccelWidth - - maxEntryWithAccelWidth; - if (geometryPtr->nonAccelMargin > maxNonAccelMargin) { - geometryPtr->nonAccelMargin = maxNonAccelMargin; - } - } else { - geometryPtr->nonAccelMargin = 0; - } - } - windowWidth = x + maxIndicatorSpace + maxWidth - + 2 * activeBorderWidth + borderWidth; - windowHeight += borderWidth; - - /* - * The X server doesn't like zero dimensions, so round up to at least - * 1 (a zero-sized menu should never really occur, anyway). - */ - - if (windowWidth <= 0) { - windowWidth = 1; - } - if (windowHeight <= 0) { - windowHeight = 1; - } - menuPtr->totalWidth = windowWidth; - menuPtr->totalHeight = windowHeight; -} - -/* - *---------------------------------------------------------------------- - * - * DrawMenuEntryLabel -- - * - * This procedure draws the label part of a menu. - * - * Results: - * None. - * - * Side effects: - * Commands are output to X to display the menu in its - * current mode. - * - *---------------------------------------------------------------------- - */ - -static void -DrawMenuEntryLabel( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* What we are drawing into */ - GC gc, /* The gc we are drawing into */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - int x, /* left edge */ - int y, /* right edge */ - int width, /* width of entry */ - int height) /* height of entry */ -{ - int indicatorSpace = mePtr->indicatorSpace; - int leftEdge = x + indicatorSpace; - int imageHeight, imageWidth; - int textHeight, textWidth; - int haveImage = 0, haveText = 0; - int imageXOffset = 0, imageYOffset = 0; - int textXOffset = 0, textYOffset = 0; - - /* - * Work out what we will need to draw first. - */ - - if (mePtr->image != NULL) { - Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight); - haveImage = 1; - } else if (mePtr->bitmapPtr != NULL) { - Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); - Tk_SizeOfBitmap(menuPtr->display, bitmap, &imageWidth, &imageHeight); - haveImage = 1; - } - if (!haveImage || (mePtr->compound != COMPOUND_NONE)) { - if (mePtr->labelLength > 0) { - Tcl_DString itemTextDString; - textHeight = fmPtr->linespace; - GetEntryText(mePtr, &itemTextDString); - textWidth = Tk_TextWidth(tkfont, - Tcl_DStringValue(&itemTextDString), - Tcl_DStringLength(&itemTextDString)); - Tcl_DStringFree(&itemTextDString); - haveText = 1; - } - } - - /* - * Now work out what the relative positions are. - */ - - if (haveImage && haveText) { - int fullWidth = (imageWidth > textWidth ? imageWidth : textWidth); - switch ((enum compound) mePtr->compound) { - case COMPOUND_TOP: { - textXOffset = (fullWidth - textWidth)/2; - textYOffset = imageHeight/2 + 2; - imageXOffset = (fullWidth - imageWidth)/2; - imageYOffset = -textHeight/2; - break; - } - case COMPOUND_BOTTOM: { - textXOffset = (fullWidth - textWidth)/2; - textYOffset = -imageHeight/2; - imageXOffset = (fullWidth - imageWidth)/2; - imageYOffset = textHeight/2 + 2; - break; - } - case COMPOUND_LEFT: { - textXOffset = imageWidth + 2; - textYOffset = 0; - imageXOffset = 0; - imageYOffset = 0; - break; - } - case COMPOUND_RIGHT: { - textXOffset = 0; - textYOffset = 0; - imageXOffset = textWidth + 2; - imageYOffset = 0; - break; - } - case COMPOUND_CENTER: { - textXOffset = (fullWidth - textWidth)/2; - textYOffset = 0; - imageXOffset = (fullWidth - imageWidth)/2; - imageYOffset = 0; - break; - } - case COMPOUND_NONE: {break;} - } - } else { - textXOffset = 0; - textYOffset = 0; - imageXOffset = 0; - imageYOffset = 0; - } - - /* - * Draw label and/or bitmap or image for entry. - */ - - if (mePtr->image != NULL) { - Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight); - if ((mePtr->selectImage != NULL) - && (mePtr->entryFlags & ENTRY_SELECTED)) { - Tk_RedrawImage(mePtr->selectImage, 0, 0, - imageWidth, imageHeight, d, leftEdge + imageXOffset, - (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset)); - } else { - Tk_RedrawImage(mePtr->image, 0, 0, imageWidth, - imageHeight, d, leftEdge + imageXOffset, - (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset)); - } - } else if (mePtr->bitmapPtr != NULL) { - Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); - XCopyPlane(menuPtr->display, bitmap, d, gc, 0, 0, - (unsigned) imageWidth, (unsigned) imageHeight, - leftEdge + imageXOffset, - (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), 1); - } - if ((mePtr->compound != COMPOUND_NONE) || !haveImage) { - if (mePtr->labelLength > 0) { - Tcl_DString itemTextDString, convertedTextDString; - int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; - - GetEntryText(mePtr, &itemTextDString); - - /* Somehow DrawChars is changing the colors, it is odd, since - it works for the Apple Platinum Appearance, but not for - some Kaleidoscope Themes... Untill I can figure out what - exactly is going on, this will have to do: */ - - TkMacSetUpGraphicsPort(gc); - MoveTo((short) leftEdge + textXOffset, - (short) baseline + textYOffset); - Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&itemTextDString), - Tcl_DStringLength(&itemTextDString), &convertedTextDString); - DrawText(Tcl_DStringValue(&convertedTextDString), 0, - Tcl_DStringLength(&convertedTextDString)); - - /* Tk_DrawChars(menuPtr->display, d, gc, - tkfont, Tcl_DStringValue(&itemTextDString), - Tcl_DStringLength(&itemTextDString), - leftEdge, baseline); */ - - Tcl_DStringFree(&itemTextDString); - } - } - - if (mePtr->state == ENTRY_DISABLED) { - if (menuPtr->disabledFgPtr == NULL) { - if (!TkMacHaveAppearance()) { - XFillRectangle(menuPtr->display, d, menuPtr->disabledGC, x, y, - (unsigned) width, (unsigned) height); - } - } else if ((mePtr->image != NULL) - && (menuPtr->disabledImageGC != None)) { - XFillRectangle(menuPtr->display, d, menuPtr->disabledImageGC, - leftEdge + imageXOffset, - (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), - (unsigned) imageWidth, (unsigned) imageHeight); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * DrawMenuEntryBackground -- - * - * This procedure draws the background part of a menu entry. - * Under Appearance, we only draw the background if the entry's - * border is set, we DO NOT inherit it from the menu... - * - * Results: - * None. - * - * Side effects: - * Commands are output to X to display the menu in its - * current mode. - * - *---------------------------------------------------------------------- - */ - -static void -DrawMenuEntryBackground( - TkMenu *menuPtr, /* The menu we are drawing. */ - TkMenuEntry *mePtr, /* The entry we are drawing. */ - Drawable d, /* What we are drawing into */ - Tk_3DBorder activeBorder, /* Border for active items */ - Tk_3DBorder bgBorder, /* Border for the background */ - int x, /* left edge */ - int y, /* top edge */ - int width, /* width of rectangle to draw */ - int height) /* height of rectangle to draw */ -{ - if (!TkMacHaveAppearance() - || (menuPtr->menuType == TEAROFF_MENU) - || ((mePtr->state == ENTRY_ACTIVE) - && (mePtr->activeBorderPtr != None)) - || ((mePtr->state != ENTRY_ACTIVE) && (mePtr->borderPtr != None))) { - if (mePtr->state == ENTRY_ACTIVE) { - bgBorder = activeBorder; - } - Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, - x, y, width, height, 0, TK_RELIEF_FLAT); - } -} - -/* - *---------------------------------------------------------------------- - * - * GetMenuLabelGeometry -- - * - * Figures out the size of the label portion of a menu item. - * - * Results: - * widthPtr and heightPtr are filled in with the correct geometry - * information. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -GetMenuLabelGeometry( - TkMenuEntry *mePtr, /* The entry we are computing */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated metrics */ - int *widthPtr, /* The resulting width of the label - * portion */ - int *heightPtr) /* The resulting height of the label - * portion */ -{ - TkMenu *menuPtr = mePtr->menuPtr; - int haveImage = 0, haveText = 0; - - if (mePtr->image != NULL) { - Tk_SizeOfImage(mePtr->image, widthPtr, heightPtr); - haveImage = 1; - } else if (mePtr->bitmapPtr != NULL) { - Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); - Tk_SizeOfBitmap(menuPtr->display, bitmap, widthPtr, heightPtr); - haveImage = 1; - } else { - *heightPtr = 0; - *widthPtr = 0; - } - - if (haveImage && (mePtr->compound == COMPOUND_NONE)) { - /* We don't care about the text in this case */ - } else { - /* Either it is compound or we don't have an image */ - if (mePtr->labelPtr != NULL) { - Tcl_DString itemTextDString; - int textWidth; - GetEntryText(mePtr, &itemTextDString); - textWidth = Tk_TextWidth(tkfont, - Tcl_DStringValue(&itemTextDString), - Tcl_DStringLength(&itemTextDString)); - Tcl_DStringFree(&itemTextDString); - - if ((mePtr->compound != COMPOUND_NONE) && haveImage) { - switch ((enum compound) mePtr->compound) { - case COMPOUND_TOP: - case COMPOUND_BOTTOM: { - if (textWidth > *widthPtr) { - *widthPtr = textWidth; - } - /* Add text and padding */ - *heightPtr += fmPtr->linespace + 2; - break; - } - case COMPOUND_LEFT: - case COMPOUND_RIGHT: { - if (fmPtr->linespace > *heightPtr) { - *heightPtr = fmPtr->linespace; - } - /* Add text and padding */ - *widthPtr += textWidth + 2; - break; - } - case COMPOUND_CENTER: { - if (fmPtr->linespace > *heightPtr) { - *heightPtr = fmPtr->linespace; - } - if (textWidth > *widthPtr) { - *widthPtr = textWidth; - } - break; - } - case COMPOUND_NONE: {break;} - } - } else { - /* We don't have an image or we're not compound */ - *heightPtr = fmPtr->linespace; - *widthPtr = textWidth; - } - } else { - /* An empty entry still has this height */ - *heightPtr = fmPtr->linespace; - } - } - *heightPtr += 1; -} - -/* - *---------------------------------------------------------------------- - * - * MenuSelectEvent -- - * - * Generates a "MenuSelect" virtual event. This can be used to - * do context-sensitive menu help. - * - * Results: - * None. - * - * Side effects: - * Places a virtual event on the event queue. - * - *---------------------------------------------------------------------- - */ - -static void -MenuSelectEvent( - TkMenu *menuPtr) /* the menu we have selected. */ -{ - XVirtualEvent event; - Point where; - - event.type = VirtualEvent; - event.serial = menuPtr->display->request; - event.send_event = false; - event.display = menuPtr->display; - Tk_MakeWindowExist(menuPtr->tkwin); - event.event = Tk_WindowId(menuPtr->tkwin); - event.root = XRootWindow(menuPtr->display, 0); - event.subwindow = None; - event.time = TkpGetMS(); - - GetMouse(&where); - event.x_root = where.h; - event.y_root = where.v; - event.state = TkMacButtonKeyState(); - event.same_screen = true; - event.name = Tk_GetUid("MenuSelect"); - Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); -} - -/* - *---------------------------------------------------------------------- - * - * RecursivelyClearActiveMenu -- - * - * Recursively clears the active entry in the menu's cascade hierarchy. - * - * Results: - * None. - * - * Side effects: - * Generates <<MenuSelect>> virtual events. - * - *---------------------------------------------------------------------- - */ - -void -RecursivelyClearActiveMenu( - TkMenu *menuPtr) /* The menu to reset. */ -{ - int i; - TkMenuEntry *mePtr; - - TkActivateMenuEntry(menuPtr, -1); - MenuSelectEvent(menuPtr); - for (i = 0; i < menuPtr->numEntries; i++) { - mePtr = menuPtr->entries[i]; - if (mePtr->type == CASCADE_ENTRY) { - if ((mePtr->childMenuRefPtr != NULL) - && (mePtr->childMenuRefPtr->menuPtr != NULL)) { - RecursivelyClearActiveMenu(mePtr->childMenuRefPtr->menuPtr); - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * InvalidateMDEFRgns -- - * - * Invalidates the regions covered by menus that did redrawing and - * might be damaged. - * - * Results: - * None. - * - * Side effects: - * Generates Mac update events for affected windows. - * - *---------------------------------------------------------------------- - */ - -void -InvalidateMDEFRgns(void) -{ - GDHandle saveDevice; - GWorldPtr saveWorld, destPort; - Point scratch; - MacDrawable *macDraw; - TkMacWindowList *listPtr; - - if (totalMenuRgn == NULL) { - return; - } - - GetGWorld(&saveWorld, &saveDevice); - for (listPtr = tkMacWindowListPtr ; listPtr != NULL; - listPtr = listPtr->nextPtr) { - macDraw = (MacDrawable *) Tk_WindowId(listPtr->winPtr); - if (macDraw->flags & TK_DRAWN_UNDER_MENU) { - destPort = TkMacGetDrawablePort(Tk_WindowId(listPtr->winPtr)); - SetGWorld(destPort, NULL); - scratch.h = scratch.v = 0; - GlobalToLocal(&scratch); - OffsetRgn(totalMenuRgn, scratch.v, scratch.h); - InvalRgn(totalMenuRgn); - OffsetRgn(totalMenuRgn, -scratch.v, -scratch.h); - macDraw->flags &= ~TK_DRAWN_UNDER_MENU; - } - } - - SetGWorld(saveWorld, saveDevice); - SetEmptyRgn(totalMenuRgn); -} - -/* - *---------------------------------------------------------------------- - * - * TkMacClearMenubarActive -- - * - * Recursively clears the active entry in the current menubar hierarchy. - * - * Results: - * None. - * - * Side effects: - * Generates <<MenuSelect>> virtual events. - * - *---------------------------------------------------------------------- - */ - -void -TkMacClearMenubarActive(void) -{ - TkMenuReferences *menuBarRefPtr; - - if (currentMenuBarName != NULL) { - menuBarRefPtr = TkFindMenuReferences(currentMenuBarInterp, - currentMenuBarName); - if ((menuBarRefPtr != NULL) && (menuBarRefPtr->menuPtr != NULL)) { - TkMenu *menuPtr; - - for (menuPtr = menuBarRefPtr->menuPtr->masterMenuPtr; menuPtr != NULL; - menuPtr = menuPtr->nextInstancePtr) { - if (menuPtr->menuType == MENUBAR) { - RecursivelyClearActiveMenu(menuPtr); - } - } - } - } - InvalidateMDEFRgns(); - FixMDEF(); -} - -/* - *---------------------------------------------------------------------- - * - * TkpMenuNotifyToplevelCreate -- - * - * This routine reconfigures the menu and the clones indicated by - * menuName becuase a toplevel has been created and any system - * menus need to be created. Only applicable to Windows. - * - * Results: - * None. - * - * Side effects: - * An idle handler is set up to do the reconfiguration. - * - *---------------------------------------------------------------------- - */ - -void -TkpMenuNotifyToplevelCreate( - Tcl_Interp *interp, /* The interp the menu lives in. */ - char *menuName) /* The name of the menu to - * reconfigure. */ -{ - /* - * Nothing to do. - */ -} - -/* - *---------------------------------------------------------------------- - * - * FixMDEF -- - * - * Loads the MDEF and blasts our routine descriptor into it. - * We have to set up the MDEF. This is pretty slimy. The real MDEF - * resource is 68K code. All this code does is call another procedure. - * When the application in launched, a dummy value for the procedure - * is compiled into the MDEF. We are going to replace that dummy - * value with a routine descriptor. When the routine descriptor - * is invoked, the globals and everything will be setup, and we - * can do what we need. This will not work from 68K or CFM 68k - * currently, so we will conditional compile this until we - * figure it out. - * - * Results: - * Returns the MDEF handle. - * - * Side effects: - * The MDEF is read in and massaged. - * - *---------------------------------------------------------------------- - */ - -#if __MWERKS__ != 0x2400 -#define MDEF_PROC_OFFSET 0x24 -#else -#define MDEF_PROC_OFFSET 0x20 -#endif - -static Handle -FixMDEF(void) -{ -#if GENERATINGCFM - Handle MDEFHandle = GetResource('MDEF', 591); - Handle SICNHandle = GetResource('SICN', SICN_RESOURCE_NUMBER); - if ((MDEFHandle != NULL) && (SICNHandle != NULL)) { - HLock(MDEFHandle); - HLock(SICNHandle); - if (menuDefProc == NULL) { - menuDefProc = TkNewMenuDefProc(MenuDefProc); - } - memmove((void *) (((long) (*MDEFHandle)) + MDEF_PROC_OFFSET), &menuDefProc, 4); - return MDEFHandle; - } else { - return NULL; - } -#else - return NULL; -#endif -} - -/* - *---------------------------------------------------------------------- - * - * TkpMenuInit -- - * - * Initializes Mac-specific menu data. - * - * Results: - * None. - * - * Side effects: - * Allocates a hash table. - * - *---------------------------------------------------------------------- - */ - -void -TkpMenuInit(void) -{ - lastMenuID = 256; - Tcl_InitHashTable(&commandTable, TCL_ONE_WORD_KEYS); - currentMenuBarOwner = NULL; - tearoffStruct.menuPtr = NULL; - currentAppleMenuID = 0; - currentHelpMenuID = 0; - currentMenuBarInterp = NULL; - currentMenuBarName = NULL; - windowListPtr = NULL; - - /* - * Get the GC that we will use as the sign to the font - * routines that they should not muck with the foreground color... - */ - - if (TkMacHaveAppearance() > 1) { - XGCValues tmpValues; - TkColor *tmpColorPtr; - - tmpColorPtr = TkpGetColor(NULL, "systemAppearanceColor"); - tmpValues.foreground = tmpColorPtr->color.pixel; - tmpValues.background = tmpColorPtr->color.pixel; - ckfree((char *) tmpColorPtr); - - tkThemeMenuItemDrawingUPP = NewMenuItemDrawingProc(tkThemeMenuItemDrawingProc); - } - FixMDEF(); - - Tcl_ExternalToUtf(NULL, NULL, "\311", /* Š */ - -1, 0, NULL, elipsisString, - TCL_UTF_MAX + 1, NULL, NULL, NULL); -} - -/* - *---------------------------------------------------------------------- - * - * TkpMenuThreadInit -- - * - * Does platform-specific initialization of thread-specific - * menu state. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkpMenuThreadInit() -{ - /* - * Nothing to do. - */ -} - -/* - *---------------------------------------------------------------------- - * - * TkpPreprocessMacMenu -- - * - * Handle preprocessing of menubar if it exists. - * - * Results: - * None. - * - * Side effects: - * All post commands for the current menubar get executed. - * - *---------------------------------------------------------------------- - */ - -void -TkMacPreprocessMenu() -{ - TkMenuReferences *mbRefPtr; - int code; - - if ((currentMenuBarName != NULL) && (currentMenuBarInterp != NULL)) { - mbRefPtr = TkFindMenuReferences(currentMenuBarInterp, - currentMenuBarName); - if ((mbRefPtr != NULL) && (mbRefPtr->menuPtr != NULL)) { - Tcl_Preserve((ClientData)currentMenuBarInterp); - code = TkPreprocessMenu(mbRefPtr->menuPtr->masterMenuPtr); - if ((code != TCL_OK) && (code != TCL_CONTINUE) - && (code != TCL_BREAK)) { - Tcl_AddErrorInfo(currentMenuBarInterp, - "\n (menu preprocess)"); - Tcl_BackgroundError(currentMenuBarInterp); - } - Tcl_Release((ClientData)currentMenuBarInterp); - } - } -} |