/* Copyright 1986-2000 by Abacus Research and * Development, Inc. All rights reserved. */ /* Forward declarations in MenuMgr.h (DO NOT DELETE THIS LINE) */ /* * TODO: use update regions if we don't have room to save and restore bitmaps */ #if !defined (OMIT_RCSID_STRINGS) char ROMlib_rcsid_menu[] = "$Id: menu.c 87 2005-05-25 01:57:33Z ctm $"; #endif #include "rsys/common.h" #include "QuickDraw.h" #include "MenuMgr.h" #include "WindowMgr.h" #include "ResourceMgr.h" #include "MemoryMgr.h" #include "EventMgr.h" #include "FontMgr.h" #include "OSUtil.h" #include "ToolboxUtil.h" #include "ToolboxEvent.h" #include "OSEvent.h" #include "DeskMgr.h" #include "SysErr.h" #include "rsys/menu.h" #include "rsys/cquick.h" #include "rsys/quick.h" #include "rsys/screen.h" #include "rsys/glue.h" #include "rsys/mman.h" #include "rsys/smash.h" #include "rsys/wind.h" #include "rsys/hook.h" #include "rsys/resource.h" #include "rsys/aboutbox.h" #include "rsys/system_error.h" #include "rsys/vdriver.h" #include "rsys/custom.h" #include "rsys/notmac.h" #include "rsys/version.h" #include "rsys/custom.h" PUBLIC int ROMlib_sticky_menus_p = 0; A1(PRIVATE, void, dirtymenusize, MenuHandle, mh) { if (mh) { HxX(mh, menuWidth) = -1; HxX(mh, menuHeight) = -1; } } P0 (PUBLIC pascal trap, void, InvalMenuBar) { DrawMenuBar (); } #if defined (DISPLAY_DEMO_ON_MENU_BAR) /* Bounding box for "DEMO" text on menu bar. */ static Rect menu_demo_text_rect; #endif P0(PUBLIC pascal trap, void, DrawMenuBar) { if (MBDFHndl) { TheMenu = 0; MBDFCALL(mbDraw, 0, 0L); #if defined (DISPLAY_DEMO_ON_MENU_BAR) if (WWExist == EXIST_YES) { THEPORT_SAVE_EXCURSION (MR (wmgr_port), { static char demo_string[] = DEMO_PREFIX "DEMO"; FontInfo font_info; int text_width; int text_height; int left; int top; RGBColor save_fg; RGBColor save_bk; save_fg = CPORT_RGB_FG_COLOR (MR (wmgr_port)); save_bk = CPORT_RGB_BK_COLOR (MR (wmgr_port)); /* Set up the pen and colors. */ PenNormal (); if (vdriver_bpp > 2) ForeColor (redColor); else ForeColor (blackColor); BackColor (whiteColor); /* Set up the font. */ TextFont (0); TextSize (0); GetFontInfo (&font_info); text_width = TextWidth ((Ptr) demo_string, 0, strlen (demo_string)); text_height = (CW (font_info.ascent)); left = vdriver_width - 16 - text_width; top = (CW (MBarHeight) - text_height) / 2 - 2; /* Record the bounding rect. */ SetRect (&menu_demo_text_rect, left, top, left + text_width, top + text_height); /* Draw the demo text. */ MoveTo (left, top + text_height); DrawText_c_string (demo_string); /* Restore the foreground and background colors. */ RGBForeColor (&save_fg); RGBBackColor (&save_bk); }); } #endif /* DISPLAY_DEMO_ON_MENU_BAR */ } } #define HIEROFFX \ (*(INTEGER *) ((char *) STARH(MENULIST) + \ Hx(MENULIST, muoff) + sizeof(muelem) + 4)) #define HIEROFF \ CW(HIEROFFX) #define MINMENULISTSIZE ((Size) sizeof(INTEGER) * 4 + sizeof(HIDDEN_Handle)) P0(PUBLIC pascal trap, void, ClearMenuBar) { if (MenuList) SetHandleSize(MR(MenuList), MINMENULISTSIZE); else MenuList = RM(NewHandle(MINMENULISTSIZE)); HxX(MENULIST, muoff) = 0; /* int 1 */ HxX(MENULIST, muright) = CWC(MENULEFT); /* int 2 */ (&STARH(MENULIST)->mufu)[3] = CWC(sizeof(muelem)); /* lastHMenu: int 6 */ (*(HIDDEN_Handle *)&(&STARH(MENULIST)->mufu)[1]).p = CLC(0);/* menuTitleSave: int 4,5 */ } #define BLACK_RGB { CWC (0), CWC (0), CWC (0) } #define WHITE_RGB { CWC (0xFFFF), CWC (0xFFFF), CWC (0xFFFF) } #define RESERVED_RGB /* arbitrary */ WHITE_RGB PRIVATE MCEntry default_menu_ctab[] = { { CWC (0), CWC (0), BLACK_RGB, WHITE_RGB, BLACK_RGB, WHITE_RGB, /* reserved */ CWC (0), }, /* end marker */ { CWC (-99), /* reserved */ CWC (0), RESERVED_RGB, RESERVED_RGB, RESERVED_RGB, RESERVED_RGB, /* reserved */ CWC (0), }, }; #undef BLACK_RGB #undef WHITE_RGB #undef RESERVED_RGB PRIVATE void append_end_marker_if_necessary (MCTableHandle h) { Size size; MCEntryPtr entries; int i, nelem; size = GetHandleSize ((Handle) h); entries = STARH (h); nelem = size / sizeof *entries; for (i = 0; i < nelem && MCENTRY_ID_X (&entries[i]) != CWC (-99);) ++i; if (i == nelem) { size += sizeof *entries; SetHandleSize ((Handle) h, size); if (MemError() == noErr) { entries = STARH (h); entries[nelem] = default_menu_ctab[NELEM (default_menu_ctab) - 1]; } } } P0(PUBLIC pascal trap, void, InitMenus) { Handle default_mcinfo; MenuHook = MBarHook = 0; ClearMenuBar (); default_mcinfo = ROMlib_getrestid (TICK ("mctb"), 0); if (!default_mcinfo) { /* try to load 'mctb' resource 0; otherwise use default built into `ROM' */ MenuCInfo = (MCTableHandle) RM (NewHandle (sizeof default_menu_ctab)); BlockMove ((Ptr) default_menu_ctab, (Ptr) STARH (MR (MenuCInfo)), sizeof default_menu_ctab); } else { int n_entries; n_entries = CW (*(uint16 *) STARH (default_mcinfo)); MenuCInfo = (MCTableHandle) RM (NewHandle (n_entries * sizeof (MCEntry))); BlockMove ((Ptr) (&((uint16 *) STARH (default_mcinfo))[1]), (Ptr) STARH (MR (MenuCInfo)), n_entries * sizeof (MCEntry)); append_end_marker_if_necessary (MR (MenuCInfo)); } InitProcMenu (0); /* sets mbResID */ /* int 3 */ MBDFCALL(mbHeight, 0, 0L); DrawMenuBar (); } P2(PUBLIC pascal trap, MenuHandle, NewMenu, INTEGER, mid, StringPtr, str) { MenuHandle retval; Handle temph; if (!str) str = (StringPtr) ""; retval = (MenuHandle) NewHandle((Size) SIZEOFMINFO + U(str[0]) + 1); HxX(retval, menuID) = CW(mid); HxX(retval, menuWidth) = HxX(retval, menuHeight) = 0; /* menuHeight calculated elsewhere */ SetResLoad(TRUE); temph = RM(GetResource(TICK("MDEF"), textMenuProc)); HxX(retval, menuProc) = temph; HxX(retval, enableFlags) = -1; str255assign(HxX(retval, menuData), str); *((char *) STARH(retval) + SIZEOFMINFO + U(str[0])) = 0; return(retval); } P1(PUBLIC pascal trap, void, CalcMenuSize, MenuHandle, mh) { Point dummy_pt; Rect rect; int16 i; if (mh) { i = -1; THEPORT_SAVE_EXCURSION (MR (wmgr_port), { PORT_TX_FACE_X (MR (wmgr_port)) = (Style) CB (0); PORT_TX_FONT_X (MR (wmgr_port)) = CWC (0); /* initialize the unused point to a known value */ memset (&dummy_pt, 0xFF, sizeof dummy_pt); memset (&rect, 0, sizeof rect); MENUCALL (mSizeMsg, mh, &rect, dummy_pt, &i); }); } } /* * NOTE: the nastiness below is because it is very hard to tell * whether or not someone has already converted a menuProc * from a resource id to a handle. */ typedef struct mct_res { int16 n_entries; MCEntry entries[1]; } mct_res_t; P1 (PUBLIC pascal trap, MenuHandle, GetMenu, int16, rid) { MenuHandle retval; Handle mct_res_h; SetResLoad (TRUE); retval = (MenuHandle) GetResource (TICK ("MENU"), rid); mct_res_h = ROMlib_getrestid (TICK ("mctb"), rid); if (mct_res_h) LOCK_HANDLE_EXCURSION_1 (mct_res_h, { mct_res_t *mct_res; /* MCEntry entry; int i; entry.mctReserved = 0; mct_res = (mct_res_t *) STARH (mct_res_h); for (i = 0; i < CW (mct_res->n_entries); i ++) { memcpy (&entry, &mct_res->entries[i], sizeof mct_res->entries[i]); SetMCEntries (1, &entry); } */ mct_res = (mct_res_t *) STARH (mct_res_h); SetMCEntries (CW (mct_res->n_entries), &mct_res->entries[0]); }); if (retval) { Handle current_proc; current_proc = HxP (retval, menuProc); if (!HandleZone (current_proc) || !GetHandleSize (current_proc)) { Handle temph; MemErr = CWC (noErr); temph = GetResource (TICK("MDEF"), CW (*(int16 *)&HxX(retval, menuProc))); if (SIZEOFMINFO != 15) Munger ((Handle) retval, (int32) 6, (Ptr) 0, (int32) 0, (Ptr) "x", (int32) 2); MI_PROC_X (retval) = RM (temph); CalcMenuSize(retval); } } return retval; } P1(PUBLIC pascal trap, void, DisposeMenu, MenuHandle, mh) { if (mh) { ReleaseResource((Handle) mh); if (Cx(ResErr) == resNotFound) DisposHandle((Handle) mh); } } typedef struct { /* NOTE: These structures are strictly local */ MenuHandle menh; /* There's no reason to swap the bytes */ INTEGER menitem; /* in these fields */ INTEGER menoff; /* although *menh will still need to be swapped */ } endinfo; A2(PRIVATE, void, toend, MenuHandle, mh, endinfo *, eip) { char *menuop; eip->menh = mh; eip->menitem = 0; menuop = (char *) STARH(mh) + SIZEOFMINFO + Hx(mh, menuData[0]); while (*menuop != 0) { ++eip->menitem; menuop += (*menuop) + SIZEOFMEXT; } eip->menoff = menuop - (char *) STARH(mh); } A7(PRIVATE, void, app, StringPtr, str, char, icon, char, marker, char, style, char, keyequiv, char, disflag, endinfo *, eip) { char *ip, *ep, *menuop; Size newsize; SignedByte state; eip->menitem++; if (disflag) STARH(eip->menh)->enableFlags &= CL(~((LONGINT)1 << eip->menitem)); else STARH(eip->menh)->enableFlags |= CL((LONGINT)1 << eip->menitem); newsize = eip->menoff + SIZEOFMEXT + 1 + U(str[0]); SetHandleSize((Handle) eip->menh, newsize); /* * The following lines were put in because Virex 4.0 calls AddResMenu with * a locked handle that happens to have a locked block past it, hence it * can't grow. It's unclear what we should do about this sort of thing * in general, but this hack will suffice for now. */ if (MemError() != noErr) { state = HGetState((Handle) eip->menh); HUnlock((Handle) eip->menh); SetHandleSize((Handle) eip->menh, newsize); HSetState((Handle) eip->menh, state); } menuop = (char *)STARH(eip->menh) + eip->menoff; ip = (char *) str; ep = ip + U(str[0]) + 1; while (ip != ep) *menuop++ = *ip++; *menuop++ = icon; *menuop++ = keyequiv; *menuop++ = marker; *menuop++ = style; *menuop = 0; eip->menoff = menuop - (char *)STARH(eip->menh); } P2(PUBLIC pascal trap, void, AppendMenu, MenuHandle, mh, StringPtr, str) { Str255 tempstr; char *ip, *op; char c, icon = 0, marker = 0, keyequiv = 0, disflag = 0; int style = 0; int i; endinfo endinf; if (mh) { toend(mh, &endinf); ip = (char *) str+1; op = (char *) tempstr+1; tempstr[0] = 0; i = U(str[0]); while (i > 0) { switch (i--, c = *ip++) { case '^': icon = *ip++ - '0'; i--; break; case '!': marker = *ip++; i--; break; case '<': switch (i--, c = *ip++) { case 'B': style |= (int) bold; break; case 'I': style |= (int) italic; break; case 'U': style |= (int) underline; break; case 'O': style |= (int) outline; break; case 'S': style |= (int) shadow; break; default: *op++ = '<'; *op++ = c; tempstr[0] += 2; } break; case '/': keyequiv = *ip++; i--; break; case '(': disflag = TRUE; break; case ';': case '\n': case '\r': if (tempstr[0]) app(tempstr, icon, marker, style, keyequiv, disflag, &endinf); op = (char *) tempstr+1; tempstr[0] = icon = marker = style = keyequiv = disflag = 0; break; default: *op++ = c; tempstr[0]++; } } if (tempstr[0]) app(tempstr, icon, marker, style, keyequiv, disflag, &endinf); dirtymenusize(mh); } } A2(PRIVATE, void, handleinsert, Handle, h, StringPtr, strp) { LONGINT n; StringPtr sp; BOOLEAN done; n = GetHandleSize(h); sp = (StringPtr) STARH(h); done = FALSE; while (n > 0 && !done) { switch (RelString(sp, strp, TRUE, TRUE)) { case 1: done = TRUE; break; case 0: return; break; default: n -= sp[0] + 1; sp += sp[0] + 1; break; } } Munger(h, sp - (StringPtr) STARH(h), (Ptr) 0, 0, (Ptr) strp, strp[0]+1); } P2(PUBLIC pascal trap, void, AddResMenu, MenuHandle, mh, ResType, restype) { if (mh) { int nres, n; Handle h; INTEGER i; ResType t; Str255 str; endinfo endinf; Handle temph; StringPtr sp; SetResLoad(FALSE); toend(mh, &endinf); temph = NewHandle((Size) 0); do { nres = CountResources(restype); for (n = 1; n <= nres; n++) { h = GetIndResource(restype, n); GetResInfo(h, &i, &t, str); if (str[0] && str[1] != '.' && str[1] != '%') handleinsert(temph, str); } } while (restype == TICK("FONT") && (restype = TICK("FOND"))); #if defined (SUPPORT_ABOUT_EXECUTOR_BOX) /* Add an "About Executor..." menu to the Apple menu when they * ask for desk accessories. */ if (!ROMlib_menu_about_stringp && (strncasecmp (ROMlib_appname,EXECUTOR_NAME, sizeof EXECUTOR_NAME - 1) != 0)) about_box_menu_name_pstr = (StringPtr) "\016\000About CCRS..."; if (restype == TICK ("DRVR") && about_box_menu_name_pstr[0]) app (about_box_menu_name_pstr, 0, 0, 0, 0, FALSE, &endinf); #endif /* defined (SUPPORT_ABOUT_EXECUTOR_BOX) */ n = GetHandleSize(temph); sp = (StringPtr) STARH(temph); HLock(temph); while (n > 0) { app(sp, 0, 0, 0, 0, FALSE, &endinf); n -= sp[0] + 1; sp += sp[0] + 1; } HUnlock(temph); DisposHandle(temph); SetResLoad(TRUE); /* IMI-353 says to do this. */ dirtymenusize(mh); } /* FIXME - IMI-353 says to call SetResLoad(TRUE), but we only do * this "if (mh)". */ } A3(PUBLIC, mextp, ROMlib_mitemtop, MenuHandle, mh, /* INTERNAL */ INTEGER, item, StringPtr *, stashstringp) { mextp retval; StringPtr stashstring; if (!mh) /*-->*/ return 0; retval = (mextp) ( (char *)STARH(mh) + SIZEOFMINFO + U(Hx(mh, menuData[0]))); if (*(char *)retval != 0) { stashstring = (StringPtr) retval; retval = (mextp) ((char *) retval + *(char *) retval + 1); while (retval->mnextlen && item > 1) { stashstring = (StringPtr) &(retval->mnextlen); retval = (mextp) ((char *) retval + SIZEOFMEXT + U(retval->mnextlen)); item--; } if (stashstringp) *stashstringp = stashstring; if (item != 1) retval = 0; } else retval = 0; return retval; } P2(PUBLIC pascal trap, void, DelMenuItem, MenuHandle, mh, /* IMIV-56 */ INTEGER, item) { if (mh) { ULONGINT unchangedmask; StringPtr stashstring; if (ROMlib_mitemtop(mh, item, &stashstring)) { Munger((Handle) mh, (char *) stashstring - (char *) STARH(mh), (Ptr) 0, SIZEOFMEXT + stashstring[0], (Ptr) "", 0); if (item < 32) { unchangedmask = (1L << item) - 1; /* 2s complement dependent */ HxX(mh, enableFlags) = CL(((Hx(mh, enableFlags) >> 1) & ~unchangedmask) | (Hx(mh, enableFlags) & unchangedmask) | 0x80000000); } } dirtymenusize(mh); } } A4(PRIVATE, void, xInsertResMenu, MenuHandle, mh, StringPtr, str, ResType, restype, INTEGER, after) { LONGINT oldeflags; Size hsize; Handle h; int soff; char *sp, *dp, *ep; int omen; mextp mmm; endinfo endinf; if (mh) { toend(mh, &endinf); omen = endinf.menitem; mmm = 0; if (after > 0 && !(mmm = ROMlib_mitemtop(mh, after, (StringPtr *) 0))) if (str) AppendMenu(mh, str); else AddResMenu(mh, restype); else { oldeflags = Hx(mh, enableFlags) & ~(((LONGINT)1<<(after+1))-1); if (mmm) soff = (char *)&(mmm->mnextlen) - (char *) STARH(mh); else soff = SIZEOFMINFO + U(Hx(mh, menuData[0])); hsize = GetHandleSize((Handle) mh) - soff; gui_assert (hsize >= 0); h = NewHandle(hsize); sp = (char *) STARH(mh) + soff; dp = (char *) STARH(h); ep = sp + hsize; while (sp != ep) *dp++ = *sp++; *((char *)STARH(mh) + soff) = 0; SetHandleSize((Handle) mh, (Size)soff + 1); if (str) AppendMenu(mh, str); else AddResMenu(mh, restype); SetHandleSize((Handle) mh, GetHandleSize((Handle) mh) + hsize - 1); sp = (char *) STARH(h); toend(mh, &endinf); dp = (char *) STARH(mh) + endinf.menoff; ep = sp + hsize; while (sp != ep) *dp++ = *sp++; HxX(mh, enableFlags) = CL(Hx(mh, enableFlags) | oldeflags << (endinf.menitem - after)); #if 0 /* RagTime suggests that at least for InsMenuItem */ /* CalcMenuSize shouldn't be called */ CalcMenuSize(mh); #else dirtymenusize(mh); #endif DisposHandle(h); } } } P3(PUBLIC pascal trap, void, InsertResMenu, MenuHandle, mh, ResType, restype, INTEGER, after) { if (mh) xInsertResMenu(mh, (StringPtr) 0, restype, after); } P3(PUBLIC pascal trap, void, InsMenuItem, MenuHandle, mh, StringPtr, str, INTEGER, after) /* IMIV-55 */ { if (mh) xInsertResMenu(mh, str, (ResType) 0, after); } #define FIRSTHIER \ ((muelem *) ((char *) STARH(MENULIST) + Hx(MENULIST, muoff)) + 2) P2(PUBLIC pascal trap, void, InsertMenu, MenuHandle, mh, INTEGER, before) { muelem *mp, *mpend, *bindex, newmuelem; INTEGER mid1, mid2; LONGINT binoff; if (mh) { mid1 = Hx(mh, menuID); if (before == -1) { mpend = HxX(MENULIST, mulist) + HIEROFF / sizeof(muelem); for (mp = FIRSTHIER; mp != mpend && (CW(STARH(MR(mp->muhandle))->menuID) != mid1); mp++) ; if (mp != mpend) /* already there */ /*-->*/ return; SetHandleSize(MR(MenuList), (Size) HIEROFF + 2 * sizeof(muelem)); mpend = HxX(MENULIST, mulist) + HIEROFF / sizeof(muelem); mpend->muhandle = RM(mh); mpend->muleft = 0; } else { bindex = 0; mpend = HxX(MENULIST, mulist) + Hx(MENULIST, muoff) / sizeof(muelem); for (mp = HxX(MENULIST, mulist); mp != mpend; mp++) { if ((mid2 = CW(STARH(MR(mp->muhandle))->menuID)) == mid1) /*-->*/ return; if (mid2 == before) bindex = mp; } newmuelem.muhandle = RM(mh); if (bindex == 0) { newmuelem.muleft = HxX(MENULIST, muright); Munger(MR(MenuList), Hx(MENULIST, muoff) + sizeof(muelem), (Ptr) 0,(LONGINT) 0, (Ptr) &newmuelem, (LONGINT) sizeof(newmuelem)); binoff = Hx(MENULIST, muoff); } else { newmuelem.muleft = bindex->muleft; binoff = (char *) bindex - (char *) STARH(MR(MenuList)); Munger(MR(MenuList), binoff, (Ptr) 0, (LONGINT) 0, (Ptr) &newmuelem, (LONGINT) sizeof(newmuelem)); } HxX(MENULIST, muoff) = CW(Hx(MENULIST, muoff) + sizeof(muelem)); MBDFCALL(mbCalc, 0, binoff); } HIEROFFX = CW(HIEROFF + sizeof(muelem)); } } P1 (PUBLIC pascal trap, void, DeleteMenu, int16, mid) { muelem *mp, *mpend; int32 deleteloc; menu_delete_entries (mid); mpend = HxX(MENULIST, mulist) + Hx(MENULIST, muoff) / sizeof(muelem); for (mp = HxX(MENULIST, mulist); mp != mpend && CW(STARH(MR(mp->muhandle))->menuID) != mid; mp++) ; if (mp != mpend) { deleteloc = (LONGINT) ((char *)mp - (char *)STARH(MR(MenuList))); Munger (MR (MenuList), deleteloc, (Ptr) 0, (int32) sizeof (muelem), (Ptr) "", (int32) 0); HxX(MENULIST, muoff) = CW(Hx(MENULIST, muoff) - sizeof(muelem)); MBDFCALL(mbCalc, 0, deleteloc); } else { mpend = HxX(MENULIST, mulist) + HIEROFF / sizeof(muelem); for (mp = FIRSTHIER; mp != mpend && (CW(STARH(MR(mp->muhandle))->menuID) != mid); mp++) ; if (mp == mpend) /*-->*/ return; /* not there */ Munger(MR(MenuList), (int32) ((char *)mp - (char *) STARH (MR (MenuList))), (Ptr) 0, (int32) sizeof(muelem), (Ptr) "", (int32) 0); } HIEROFFX = CW (HIEROFF - sizeof (muelem)); } typedef struct { INTEGER nmen; INTEGER mrid[1]; } mbartype; typedef mbartype *mbarptr; typedef struct { mbarptr p PACKED_P; } HIDDEN_mbarptr; typedef HIDDEN_mbarptr *mbarhandle; P1(PUBLIC pascal trap, Handle, GetNewMBar, INTEGER, mbarid) { mbarhandle mb; mlhandle saveml; INTEGER *ip, *ep; MenuHandle mh; Handle retval; mb = (mbarhandle) GetResource(TICK("MBAR"), mbarid); if (!mb) retval = 0; else { if (!(*mb).p) LoadResource((Handle) mb); LOCK_HANDLE_EXCURSION_1 (mb, { ip = HxX(mb, mrid); ep = ip + Hx(mb, nmen); saveml = MENULIST; MenuList = 0; ClearMenuBar(); retval = MR(MenuList); HxX(MENULIST, mufu) = HxX(saveml, mufu); /* int 3 */ while (ip != ep) { mh = GetMenu(Cx(*ip)); InsertMenu(mh, 0); ip++; } }); MenuList = RM((Handle) saveml); } return retval; } P0(PUBLIC pascal trap, Handle, GetMenuBar) { HIDDEN_Handle retval; retval.p = MR(MenuList); HandToHand(&retval); return retval.p; } P1(PUBLIC pascal trap, void, SetMenuBar, Handle, ml) { HIDDEN_Handle temph; DisposHandle(MR(MenuList)); temph.p = ml; HandToHand(&temph); MenuList = RM(temph.p); } typedef struct { muelem *startp; muelem *endp; } startendpairs[2]; enum { nonhier = 0, hier = 1 }; A1(PRIVATE, void, initpairs, startendpairs, pairs) { pairs[(int)nonhier].startp = HxX(MENULIST, mulist); pairs[(int)nonhier].endp = HxX(MENULIST, mulist) + Hx(MENULIST, muoff) / sizeof(muelem); pairs[(int)hier].startp = FIRSTHIER; pairs[(int)hier].endp = HxX(MENULIST, mulist) + HIEROFF / sizeof(muelem); } static boolean_t menu_id_exists_p (int id) { muelem *mp; startendpairs mps; initpairs (mps); for (mp = mps[nonhier].startp; mp != mps[nonhier].endp; mp ++) { if (CW (STARH (MR (mp->muhandle))->menuID) == id) return TRUE; } return FALSE; } A1(PUBLIC, INTEGER, ROMlib_mentosix, INTEGER, menuid) { muelem *mp, *mpend; startendpairs mps; INTEGER i; initpairs(mps); for (i = (int) nonhier; i <= (int) hier; i++) { for (mp = mps[i].startp, mpend = mps[i].endp; mp < mpend && CW(STARH(MR(mp->muhandle))->menuID) != menuid; mp++) ; if (mp < mpend) /*-->*/ return (char *) mp - (char *) STARH(MR(MenuList)); } return -1; } A2(PRIVATE, BOOLEAN, mtoggle, INTEGER, mid, highstate, h) { LONGINT l; l = ROMlib_mentosix(mid); if (l != -1) { l |= (LONGINT) h << 16; MBDFCALL(mbHilite, 0, l); /*-->*/ return TRUE; } return FALSE; } P1 (PUBLIC pascal trap, void, HiliteMenu, INTEGER, mid) { if (mid != CW (TheMenu)) { if (TheMenu) mtoggle (CW (TheMenu), RESTORE); if (! menu_id_exists_p (mid)) mid = 0; if (mid) { if (mid == Hx (HxP (MENULIST, mulist[0].muhandle), menuID)) ROMlib_alarmoffmbar (); mtoggle (mid, HILITE); } } TheMenu = CW (mid); } typedef pascal void (*menuhookp)( void ); #if !defined(BINCOMPAT) typedef pascal void (*mbarhookp)( Rect *rp ); #else /* defined(BINCOMPAT) */ typedef pascal LONGINT (*mbarhookp)( Rect *rp ); #endif /* defined(BINCOMPAT) */ #define CALLMENUHOOK(fp) ROMlib_CALLMENUHOOK((menuhookp)(fp)) A1(static inline, void, ROMlib_CALLMENUHOOK, menuhookp, fp) { ROMlib_hook(menu_menuhooknumber); CALL_EMULATOR((syn68k_addr_t) US_TO_SYN68K((long) fp)); } #define CALLMBARHOOK(arg, fp) ROMlib_CALLMBARHOOK(arg, (mbarhookp)(fp)) A2(static inline, LONGINT, ROMlib_CALLMBARHOOK, Rect *,rp, mbarhookp, fp) { ROMlib_hook(menu_mbarhooknumber); PUSHADDR((LONGINT) US_TO_SYN68K((long) rp)); CALL_EMULATOR((syn68k_addr_t) US_TO_SYN68K((long) fp)); return EM_D0; } A1(PRIVATE, INTEGER, wheretowhich, LONGINT, offset) { mbdfentry *p, *ep; ep = (mbdfentry *) STARH(MR(MBSaveLoc)); for (p = (mbdfentry *) ((char *) STARH(MR(MBSaveLoc)) + Hx(MBSAVELOC, lastMBSave)); p != ep && Cx(p->mbMLOffset) != offset; p--) ; return p - ep; } A1(PRIVATE, void, shadowrect, Rect *, rp) { rp->top = CW(CW(rp->top) - 1); rp->left = CW(CW(rp->left) - 1); rp->bottom = CW(CW(rp->bottom) + 2); rp->right = CW(CW(rp->right) + 2); } A3(PRIVATE, void, restoren, INTEGER, ntodrop, RgnHandle, restoredrgn, Rect *, rp) { mbdfentry *p; RgnHandle tmprgn; if (restoredrgn) { p = (mbdfentry *) ((char *) STARH(MR(MBSaveLoc)) + Hx(MBSAVELOC, lastMBSave)); RectRgn(restoredrgn, &p->mbRectSave); shadowrect(&HxX(restoredrgn, rgnBBox)); } #if !defined (LETGCCWAIL) else p = (mbdfentry *) -1; #endif /* LETGCCWAIL */ MBDFCALL(mbRestore, 0, 0L); while (--ntodrop > 0) { if (restoredrgn) { --p; tmprgn = NewRgn(); RectRgn(tmprgn, &p->mbRectSave); shadowrect(&HxX(tmprgn, rgnBBox)); UnionRgn(restoredrgn, tmprgn, restoredrgn); DisposeRgn(tmprgn); } MBDFCALL(mbRestore, 0, 0L); } if (restoredrgn && rp) *rp = p[-1].mbRectSave; } A2(PRIVATE, MenuHandle, menunumtomh, INTEGER, mid, INTEGER *, sixp) { muelem *mp, *mpend; mpend = HxX(MENULIST, mulist) + HIEROFF / sizeof(muelem); for (mp = FIRSTHIER; mp != mpend && CW(STARH(MR(mp->muhandle))->menuID) != mid; mp++) ; if (mp != mpend) { *sixp = (char *) mp - (char *)STARH(MR(MenuList)); /*-->*/ return MR(mp->muhandle); } return 0; } A3(PRIVATE, MenuHandle, itemishierarchical, MenuHandle, mh, INTEGER, item, INTEGER *, sixp) { mextp mep; if ((mep = ROMlib_mitemtop(mh, item, (StringPtr *) 0)) && Cx(mep->mkeyeq) == 0x1B) /*-->*/ return menunumtomh(Cx(mep->mmarker), sixp); return 0; } #define HIERRECTBIT (1L<<16) int32 ROMlib_menuhelper (MenuHandle mh, Rect *saverp, int32 oldwhere, BOOLEAN ispopup, int16 nmenusdisplayed) { mbdfentry *oldentry, *newentry; Rect r, r2; Point dummy_pt; Point tempp; INTEGER mid, item, olditem, tempi, oldtopmenuitem; INTEGER firstitem; MenuHandle newmh; int i; LONGINT pointaslong; LONGINT where, templ; RgnHandle saveclip, restoredrgn; BOOLEAN changedmenus; INTEGER oldwhichmenuhit, whichmenuhit; HIDDEN_GrafPtr saveport; EventRecord ev; Point pt; LONGINT myd0; boolean_t seen_up_already, done; GetPort (&saveport); saveport.p = MR(saveport.p); SetPort (MR (wmgr_port)); olditem = -1; item = 0; if (!ispopup) firstitem = 0; else firstitem = -1; changedmenus = FALSE; r = *saverp; memset (&dummy_pt, 0xFF, sizeof dummy_pt); oldwhichmenuhit = whichmenuhit = wheretowhich(oldwhere); restoredrgn = NewRgn(); seen_up_already = FALSE; done = FALSE; goto enter; while (!done) { GetMouse (&pt); pt.h = CW (pt.h); pt.v = CW (pt.v); pointaslong = ((int32) pt.v << 16) | (unsigned short) pt.h; where = MBDFCALL (mbHit, 0, pointaslong); if (MenuHook) CALLMENUHOOK (MR (MenuHook)); if (where == oldwhere) { if (mh) { PORT_TX_FACE_X (MR (wmgr_port)) = (Style) CB (0); PORT_TX_FONT_X (MR (wmgr_port)) = CWC (0); item = CW(item); MENUCALL (mChooseMsg, mh, &r, pt, &item); item = CW(item); if (item != olditem || changedmenus) { if (firstitem == -1) firstitem = item; changedmenus = FALSE; if ((i = nmenusdisplayed - whichmenuhit)) { restoren(i, restoredrgn, &r); nmenusdisplayed -= i; saveclip = PORT_CLIP_REGION_X (MR (wmgr_port)); PORT_CLIP_REGION_X (MR (wmgr_port)) = RM (NewRgn ()); RectRgn (PORT_CLIP_REGION (MR (wmgr_port)), &r); if (item == 0) { /* may have been 'cause of */ pt.v = 32767; /* scrolling, in which case */ pt.h = 32767; /* we don't want to scroll */ /* a messed clip region */ } item = olditem; PORT_TX_FACE_X (MR (wmgr_port)) = (Style) CB (0); PORT_TX_FONT_X (MR (wmgr_port)) = CWC (0); item = CW(item); MENUCALL (mChooseMsg, mh, &r, pt, &item); item = CW(item); DisposeRgn (PORT_CLIP_REGION (MR (wmgr_port))); PORT_CLIP_REGION_X (MR (wmgr_port)) = saveclip; } if ((newmh = itemishierarchical(mh, item, &tempi))) { int16 saveatmenubottom; r2 = * (Rect *) (long) MBDFCALL (mbRect, 0, tempi | HIERRECTBIT); MBDFCALL(mbSave, tempi, (LONGINT) (long) &r2); if (MBarHook) { myd0 = CALLMBARHOOK(&r2, MR(MBarHook)); if (myd0 != 0) goto out; } ((mbdfentry *)STARH(MR(MBSaveLoc))) [wheretowhich(tempi)].mbReserved = CLC(0); oldtopmenuitem = TopMenuItem; saveatmenubottom = AtMenuBottom; TopMenuItem = r2.top; PORT_TX_FACE_X (MR (wmgr_port)) = (Style) CB (0); PORT_TX_FONT_X (MR (wmgr_port)) = CWC (0); saveclip = PORT_CLIP_REGION_X (thePort); PORT_CLIP_REGION_X (thePort) = RM (NewRgn ()); RectRgn(PORT_CLIP_REGION (thePort), &r2); MENUCALL(mDrawMsg, newmh, &r2, dummy_pt, (INTEGER *) 0); DisposeRgn (PORT_CLIP_REGION (thePort)); PORT_CLIP_REGION_X (thePort) = saveclip; nmenusdisplayed++; MBDFCALL(mbSaveAlt, 0, tempi); TopMenuItem = oldtopmenuitem; AtMenuBottom = saveatmenubottom; } olditem = item; } } } else { if (pt.v < Cx(MBarHeight) && !ispopup) { if (nmenusdisplayed) { restoren(nmenusdisplayed, (RgnHandle) 0, 0); nmenusdisplayed = 0; } whichmenuhit = CRACKER_ZERO; if (where == NOTHITINMBAR) { mh = NULL; HiliteMenu(0); } else { mh = MR(((muelem *) ((char *)STARH(MR(MenuList)) + where))->muhandle); HiliteMenu(Hx(mh, menuID)); r = * (Rect *) (long) MBDFCALL(mbRect, 0, where); MBDFCALL(mbSave, where, (LONGINT) (long) &r); if (MBarHook) { myd0 = CALLMBARHOOK(&r, MR(MBarHook)); if (myd0 != 0) goto out; } olditem = item = 0; TopMenuItem = MBarHeight; PORT_TX_FACE_X (MR (wmgr_port)) = (Style) CB (0); PORT_TX_FONT_X (MR (wmgr_port)) = CWC (0); saveclip = PORT_CLIP_REGION_X (thePort); /* ick */ PORT_CLIP_REGION_X (thePort) = RM (NewRgn ()); RectRgn(PORT_CLIP_REGION (thePort), &r); MENUCALL(mDrawMsg, mh, &r, dummy_pt, (INTEGER *) 0); DisposeRgn (PORT_CLIP_REGION (thePort)); PORT_CLIP_REGION_X (thePort) = saveclip; nmenusdisplayed++; whichmenuhit = wheretowhich(where); } } else if (where == NOTHIT || (ispopup && pt.v < Cx(MBarHeight))) { if ((i = nmenusdisplayed - whichmenuhit)) { restoren(i, (RgnHandle) 0, 0); nmenusdisplayed -= i; } if (mh) { MR (wmgr_port)->txFace = (Style) 0; MR (wmgr_port)->txFont = 0; item = CW(item); MENUCALL(mChooseMsg, mh, &r, pt, &item); item = CW(item); } else item = CRACKER_ZERO; where = oldwhere; olditem = 0; } else { whichmenuhit = wheretowhich(where); newentry = (mbdfentry *)STARH(MR(MBSaveLoc)) + whichmenuhit; oldentry = (mbdfentry *)STARH(MR(MBSaveLoc)) + oldwhichmenuhit; oldentry->mbReserved = CL((ULONGINT)item); olditem = item = CL(newentry->mbReserved); changedmenus = TRUE; mh = MR(((muelem *) ((char *)STARH(MR(MenuList)) + where))->muhandle); templ = where; if (where > Hx(MENULIST, muoff)) templ |= HIERRECTBIT; r = * (Rect *) (long) MBDFCALL(mbRect, 0, templ); whichmenuhit = wheretowhich(where); MBDFCALL(mbSaveAlt, 0, oldwhere); MBDFCALL(mbResetAlt, 0, where); } oldwhere = where; oldwhichmenuhit = whichmenuhit; } /* we're done if we get our first mouse-up while item is non-zero, or when we get our first mouse-down while item is non-zero or when we get our second mouse-up, no matter what */ enter: if (!ROMlib_sticky_menus_p) done = !StillDown (); else { if (OSEventAvail (mUpMask, &ev)) { if (seen_up_already || (item != firstitem && firstitem != -1)) done = TRUE; else { GetOSEvent (mUpMask, &ev); seen_up_already = TRUE; } } if (!done && OSEventAvail (mDownMask, &ev)) { GetOSEvent (mDownMask, &ev); done = item != 0; } } } while (!GetOSEvent(mUpMask, &ev)) ; out: if (mh) { if (item) { mid = Hx(mh, menuID); tempi = item; tempp.v = 0; tempp.h = 0; PORT_TX_FACE_X (MR (wmgr_port)) = (Style) CB (0); PORT_TX_FONT_X (MR (wmgr_port)) = CWC (0); tempi = CW(tempi); MENUCALL(mChooseMsg, mh, &r, tempp, &tempi); tempi = CW(tempi); #if !defined(NEXTSTEP) if (MenuFlash) { for (i = 0; i < Cx(MenuFlash); i++) { Delay(3L, (LONGINT *) 0); PORT_TX_FACE_X (MR (wmgr_port)) = (Style) CB (0); PORT_TX_FONT_X (MR (wmgr_port)) = CWC (0); tempi = CW(tempi); MENUCALL(mChooseMsg, mh, &r, pt, &tempi); tempi = CW(tempi); Delay(3L, (LONGINT *) 0); PORT_TX_FACE_X (MR (wmgr_port)) = (Style) CB (0); PORT_TX_FONT_X (MR (wmgr_port)) = CWC (0); tempi = CW(tempi); MENUCALL(mChooseMsg, mh, &r, tempp, &tempi); tempi = CW(tempi); } Delay(3L, (LONGINT *) 0); } #endif } else mid = 0; if (nmenusdisplayed) restoren(nmenusdisplayed, (RgnHandle) 0, 0); } else { mid = 0; item = 0; } if (!mid) HiliteMenu(0); SetPort (saveport.p); /* Does SystemMenu() expect the WMgrPort also? */ /* Illustrator 5.5 behavior suggests that hits on hierarchical menus * for non leaf-node menus are handled differently. [PR #1683]. * Returning the "correct" mid/item for a non-leaf-node menu causes * Illustrator to crash when a routine of theirs that looks up some * value fails to find a match and doesn't fill in a value via * reference. This is a workaround, but it's known to be incorrect. * On a real Mac, choosing a non-leaf node menu for a font name in * the Character window switches to that font. This patch, as well * as one trying to use newmh's menu id, causes such a selection to * be ignored. */ newmh = itemishierarchical (mh, item, &tempi); if (newmh) { mid = 0; item = 0; } if (MBarEnable) { SystemMenu(((LONGINT) mid << 16) | (unsigned short) item); return 0; } else return ((LONGINT) mid << 16) | (unsigned short) item; } P1(PUBLIC pascal trap, LONGINT, MenuSelect, Point, p) { Rect spooeyr; LONGINT retval; TopMenuItem = MBarHeight; retval = ROMlib_menuhelper((MenuHandle) 0, &spooeyr, 0, FALSE, 0); #if defined (DISPLAY_DEMO_ON_MENU_BAR) if (retval == 0 && PtInRect (p, &menu_demo_text_rect)) do_about_box (); #endif return retval; } P1(PUBLIC pascal trap, void, FlashMenuBar, INTEGER, mid) { LONGINT l; if (mid == 0 || (l = ROMlib_mentosix(mid)) == -1) l = 0; else if (mid == Cx(TheMenu)) { l |= (LONGINT) RESTORE << 16; TheMenu = 0; } else { l |= (LONGINT) HILITE << 16; TheMenu = CW(mid); } MBDFCALL(mbHilite, 0, l); } #if 1 || !defined (DISABLE_COMMAND_KEY_EQUIVS) A2(PRIVATE, BOOLEAN, findroot, INTEGER, menuid, INTEGER *, root_unswp) { INTEGER loopcount, i, maxi; enum { noparent, hierparent, nonhierparent } partype; startendpairs mps; muelem *mp, *mpend; MenuHandle mh; unsigned char *p; mextp mxp; INTEGER mitem; initpairs(mps); maxi = mps[(int)hier].endp - mps[(int)nonhier].startp;/* upper bound */ for (partype = hierparent, loopcount = 0; partype == hierparent && loopcount < maxi ; loopcount++) { for (i = (int)nonhier; i <= (int)hier; i++) { for (mp = mps[i].startp, mpend = mps[i].endp; mp != mpend ; mp++) { mh = MR(mp->muhandle); p = (unsigned char *)STARH(mh) + SIZEOFMINFO + *(char *)(HxX(mh, menuData)); mitem = 1; while (*p != 0) { mxp = (mextp)(p + *p + 1); if (mxp->mkeyeq == 0x1B && mxp->mmarker == menuid) { menuid = Hx(mh, menuID); partype = i == (int) hier ? hierparent : nonhierparent; goto out; } mitem++; p += *p + SIZEOFMEXT; } } } out:; } if (loopcount == maxi) gui_assert(0); /* should be SysError */ if (partype == nonhierparent) { *root_unswp = menuid; /*-->*/ return TRUE; } return FALSE; } #endif /* !defined (DISABLE_COMMAND_KEY_EQUIVS) */ P1(PUBLIC pascal trap, LONGINT, MenuKey, CHAR, thec) { #if defined (DISABLE_COMMAND_KEY_EQUIVS) if (!ROMlib_disable_command_key_equivsp || !ROMlib_disable_command_key_equivsp->val) #endif { muelem *mp, *mpend; startendpairs mps; unsigned char *p; MenuHandle mh; int mitem; mextp mxp; LONGINT e, retval; Byte c; INTEGER i, menuid; if (thec >= 0x1B && thec <= 0x1F) /*-->*/ return 0; c = thec; if (c >= 'a' && c <= 'z') c = 'A' + c - 'a'; initpairs(mps); for (i = (int) nonhier; i <= (int) hier; i++) { for (mpend = mps[i].startp - 1, mp = mps[i].endp - 1; mp != mpend ; mp--) { mh = MR(mp->muhandle); p = (unsigned char *) STARH(mh) + SIZEOFMINFO + *(unsigned char *)(HxX(mh, menuData)); mitem = 1; while (*p != 0) { mxp = (mextp)(p + U(*p) + 1); if (mxp->mkeyeq == c && ((e = Hx(mh, enableFlags)) & 1) && e & ((LONGINT)1 << mitem)) { if (i == (int) nonhier) menuid = Hx(mh, menuID); else if (!findroot(Hx(mh, menuID), &menuid)) /*-->*/ return 0L; retval = ((LONGINT)Hx(mh, menuID) << 16) | (unsigned short) mitem; FlashMenuBar(menuid); if (Hx(mh, menuID) < 0) { SystemMenu(retval); retval = 0; } /*-->*/ return retval; } mitem++; p += U(*p) + SIZEOFMEXT; } } } } #if defined (DISABLE_COMMAND_KEY_EQUIVS) else system_error ("Menu command-key equivalents are disabled in the " "demo version of Executor. You must use the mouse " "to select menu items.", 0, "OK", NULL, NULL, NULL, NULL, NULL); #endif /* defined (DISABLE_COMMAND_KEY_EQUIVS) */ return(0L); } P3(PUBLIC pascal trap, void, SetItem, MenuHandle, mh, INTEGER, item, StringPtr, str) { int oldsize, newsize, growth; Size hsize, nbyte; int start, soff; char *sb; StringPtr stashstring; if (ROMlib_mitemtop(mh, item, &stashstring)) { soff = (char *)stashstring - (char *) STARH(mh); oldsize = U(stashstring[0]); newsize = U(str[0]); if (oldsize != newsize) { growth = newsize - oldsize; hsize = GetHandleSize((Handle) mh); start = ((char *) stashstring + U(stashstring[0])+1) - (char *) STARH(mh); nbyte = hsize - start; hsize += growth; if (growth > 0) { SetHandleSize((Handle) mh, hsize); sb = (char *) STARH(mh) + start; BlockMove((Ptr) sb, (Ptr) sb + growth, (Size) nbyte); } else { sb = (char *) STARH(mh) + start; BlockMove((Ptr) sb, (Ptr) sb + growth, (Size) nbyte); SetHandleSize((Handle) mh, hsize); } } str255assign((char *) STARH(mh) + soff, str); dirtymenusize(mh); } } P3(PUBLIC pascal trap, void, GetItem, MenuHandle, mh, INTEGER, item, StringPtr, str) { StringPtr stashstring; if (ROMlib_mitemtop(mh, item, &stashstring)) str255assign(str, stashstring); else str[0] = 0; } P2(PUBLIC pascal trap, void, DisableItem, MenuHandle, mh, INTEGER, item) { if (mh) HxX(mh, enableFlags) = CL(Hx(mh, enableFlags) & ~((LONGINT)1<mmarker = cflag ? checkMark : 0; } } P3(PUBLIC pascal trap, void, SetItemMark, MenuHandle, mh, INTEGER, item, CHAR, mark) { mextp mep; if ((mep = ROMlib_mitemtop(mh, item, (StringPtr *) 0))) mep->mmarker = mark; } P3(PUBLIC pascal trap, void, GetItemMark, MenuHandle, mh, INTEGER, item, INTEGER *, markp) { mextp mep; if ((mep = ROMlib_mitemtop(mh, item, (StringPtr *) 0))) *markp = CW((INTEGER) (unsigned char) mep->mmarker); } P3(PUBLIC pascal trap, void, SetItemIcon, MenuHandle, mh, INTEGER, item, Byte, icon) { mextp mep; if ((mep = ROMlib_mitemtop(mh, item, (StringPtr *) 0))) { mep->micon = icon; dirtymenusize(mh); } } P3(PUBLIC pascal trap, void, GetItemIcon, MenuHandle, mh, INTEGER, item, INTEGER *, iconp) { mextp mep; if ((mep = ROMlib_mitemtop(mh, item, (StringPtr *) 0))) *iconp = CW((INTEGER) (unsigned char) Cx(mep->micon)); } P3(PUBLIC pascal trap, void, SetItemStyle, MenuHandle, mh, INTEGER, item, INTEGER, style) { mextp mep; if ((mep = ROMlib_mitemtop(mh, item, (StringPtr *) 0))) { mep->mstyle = style; dirtymenusize(mh); } } P3(PUBLIC pascal trap, void, GetItemStyle, MenuHandle, mh, INTEGER, item, INTEGER *, stylep) { mextp mep; if ((mep = ROMlib_mitemtop(mh, item, (StringPtr *) 0))) *stylep = CW((INTEGER) (unsigned char) Cx(mep->mstyle)); } P1(PUBLIC pascal trap, INTEGER, CountMItems, MenuHandle, mh) { endinfo endinf; if (mh) { toend(mh, &endinf); /*-->*/ return endinf.menitem; } else return 0; } P1(PUBLIC pascal trap, MenuHandle, GetMHandle, INTEGER, mid) { MenuHandle retval; if (!MenuList) retval = 0; else { muelem *mp, *mpend; mpend = HxX(MENULIST, mulist) + HIEROFF / sizeof(muelem); for (mp = FIRSTHIER; mp != mpend && CW(STARH(MR(mp->muhandle))->menuID) != mid; mp++) ; if (mp != mpend) retval = MR(mp->muhandle); else { mpend = HxX(MENULIST, mulist) + Hx(MENULIST, muoff) / sizeof(muelem); for (mp = HxX(MENULIST, mulist); mp != mpend && CW(STARH(MR(mp->muhandle))->menuID) != mid; mp++) ; if (mp != mpend) retval = MR(mp->muhandle); else return(0); } } return retval; } P1(PUBLIC pascal trap, void, SetMenuFlash, INTEGER, i) { MenuFlash = CW(i); } A0(PUBLIC, BOOLEAN, ROMlib_shouldalarm) { return MENULIST && Hx(HxP(MENULIST, mulist[0].muhandle), menuData[0]) == 1; } void ROMlib_menucall (INTEGER mess, MenuHandle themenu, Rect * menrect, Point hit, INTEGER * which) { Handle defproc; menuprocp mp; defproc = HxP (themenu, menuProc); if (defproc) { if (defproc->p == NULL) LoadResource (defproc); mp = (menuprocp) STARH (defproc); if (mp == P_mdef0) { C_mdef0 (mess, themenu, menrect, hit, which); } else { ROMlib_hook (menu_mdefnumber); LOCK_HANDLE_EXCURSION_1 (defproc, { CToPascalCall ((menuprocp) STARH (defproc), CTOP_mdef0, mess, themenu, menrect, hit, which); }); } } } LONGINT ROMlib_mbdfcall (INTEGER msg, INTEGER param1, LONGINT param2) { Handle defproc; int32 retval; mbdfprocp mp; defproc = MR (MBDFHndl); switch (msg) { case mbSave: case mbMenuRgn: param2 = US_TO_SYN68K(param2); break; default: break; } if (defproc->p == NULL) LoadResource (defproc); mp = (mbdfprocp) STARH (defproc); if (mp == P_mbdf0) retval = C_mbdf0 ((Hx (MENULIST, mufu) & 7), msg, param1, param2); else { ROMlib_hook (menu_mbdfnumber); LOCK_HANDLE_EXCURSION_1 (defproc, { retval = CToPascalCall (STARH (defproc), CTOP_mbdf0, (Hx (MENULIST, mufu) & 7), msg, param1, param2); }); } switch (msg) { case mbRect: case mbMenuRgn: retval = (int32) SYN68K_TO_US (retval); break; default: break; } return retval; }