mirror of
https://github.com/elliotnunn/sys7.1-doc-wip.git
synced 2024-06-12 14:29:29 +00:00
4231 lines
166 KiB
Plaintext
4231 lines
166 KiB
Plaintext
;
|
||
; Hacks to match MacOS (most recent first):
|
||
;
|
||
; <Sys7.1> 8/3/92 Elliot make this change
|
||
; 9/2/94 SuperMario ROM source dump (header preserved below)
|
||
;
|
||
|
||
;
|
||
; File: MenuMgr.a
|
||
;
|
||
; Contains: Menu Manager for MacIntosh User Interface ToolBox
|
||
;
|
||
; This file contains the MacIntosh menu manager, which is based on Bill Atkinson’s
|
||
; Lisa menu manager.
|
||
;
|
||
; Written by: Andy Hertzfeld
|
||
;
|
||
; Copyright: © 1982-1993 by Apple Computer, Inc. All rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <20> 11/5/93 IH Sync with Excelsior.
|
||
; <SM19> 6/14/93 kc Roll in Ludwig (this replaces SM16).
|
||
; <LW5> 5/3/93 chp Flush the caches for MDEF handles smaller than 32 bytes. It used
|
||
; to be 16 bytes, but a 22-byte, unflushed, fake defproc has been
|
||
; discovered in Software Ventures Microphone II and Microphone
|
||
; Pro. (RADAR #1082386)
|
||
; <LW4> 3/8/93 fau Modified the <SM16> checkin to only flush the cache for those
|
||
; MDEFs that are only 16 bytes or less in size. See the comment
|
||
; for more description.
|
||
; <SM18> 5/21/93 CSS Remove call and import of SMgrCalcRect in InitMenus routine per
|
||
; P. Edberg's review.
|
||
; <SM17> 1/12/93 CSS Rollin a patch from MenuMgrPatch.a to syncronize the keyboard
|
||
; menu within draw menubar. Fixes Radar bug #1057927.
|
||
; <SM16> 11/18/92 CSS Cache flush hack to get Persuasion to work without putting
|
||
; cache flushing back in hlock. I am cache flushing when I
|
||
; call the MDEF.
|
||
; <SM15> 11-06-92 jmp MenuSelect was NOT preserving A2, so I fixed it.
|
||
; <SM14> 11/5/92 SWC Changed PackMacs.a->Packages.a.
|
||
; <SM13> 8/13/92 JSM Changes from where no man has gone before: change references to
|
||
; MrMacHook to MBarHook to avoid confusing future generations,
|
||
; move call to SetTickCounters in MenuSelect after menuDelaySave
|
||
; and menuDragSave are set up, get rid of unused local tRect1 in
|
||
; MenuSelect, put back in the RTS at the end of InitMenus that was
|
||
; mysteriously deleted long ago.
|
||
; <SM12> 6/22/92 RB Rolled-in the Help Manager patch to MenuSelect from
|
||
; BalloonPthc28.a, HMMenuSelectPatch and cleaned up MenuSelect a
|
||
; little bit.
|
||
; <SM11> 6/12/92 CS Roll-in Reality Changes:
|
||
; <31> 6/12/92 FM Remove obsolete call to the internal ScriptMgr routine SwapIcon.
|
||
; <30> 6/1/92 DTY Remove InsrtResMenu from this file. Always use the one from
|
||
; MenuMgr.c. Make GetIndex an Exported procedure so that it can
|
||
; be used from MenuDispatch.a in the ROM build.
|
||
; <29> 5/24/92 JSM Don’t use forTesting (always false), TearOffMenus (always
|
||
; false), or ScriptMgrKeyboardMenu (always true) conditionals.
|
||
; <28> 5/14/92 KSM #1028474,<DCC>: Speed up MenuKey by not upper-casing the command
|
||
; key character for a menu item when there isn’t one (ASCII NULL).
|
||
; <27> 5/14/92 KSM #1029927,<DCC>: Roll back to version <19> (what an unbelievable
|
||
; mess!).
|
||
; <SM10> 5/27/92 JSM Changes from Reality: Don’t use forTesting (always false) or
|
||
; TearOffMenus (always false). NOTE: Before this file is rolled
|
||
; back into Reality, someone needs to put back in all the forROM
|
||
; and hasCQD conditionals Philip deleted. This file •is• used in
|
||
; System builds, and is patched in on non-color QD machines.
|
||
; <SM9> 4/8/92 PN Fix previous header
|
||
; <SM8> 4/8/92 PN Throw out extraneous push and pop stackpointer in SetMenuBar
|
||
; <SM7> 4/6/92 PN Change GetMenuBar to the way it was. forROM condition does
|
||
; belong here after all. ScriptMgrKeyboardMenu condition needs to
|
||
; be investigated and either put back in or leave out .
|
||
; <SM6> 4/3/92 PN Clean up patch roll-ins to make them more readable. Changes are
|
||
; in DrawMenuBar/HiliteMenu/GetMenubar/SetMenuBar and alse get rid
|
||
; of forROM and hasCQD conditions since this file is used in ROM
|
||
; only
|
||
; <5> 3/24/92 PN Back out FixBTSTBugInMenuKey since it's been rolled in already.
|
||
; Eliminate the forROM condition
|
||
; in Upchar to use only the correct version. Roll in
|
||
; PatchMDDrawMenuBar,PatchMDHiliteMenu, PatchMDMenuKey,
|
||
; PatchMDMenuSelect from ModalDialogMenuPatches.a.
|
||
; <4> 3/9/92 PN Roll in HMClearMenuBarPatch PatchProc _ClearMenuBar from
|
||
; Balloonptch28.a
|
||
; <2> 2/13/92 PN ; Roll in FixBTSTbuginMenuKey, SetMenuBarAddsSystemMenus,
|
||
; GetMenuBarDoesNotReturnSystemMenus, Savea5AroundCallMDEFPRoc,
|
||
; DrawMenuBarIfInvalidOnMenuSelect,
|
||
; DrawMenuBarIfInvalidOnHiliteMenu, ValidateMenuBarWhenDrawing,
|
||
; PatchInsertMenu in SystemMenuPatch.a
|
||
; <> • HMClearMenuBarPatch still needs to be rolled in •
|
||
; <1> • Pre-SuperMario comments follow •
|
||
; <26> 1/25/92 csd In order to let Cube-E go alpha, I’m reversing the change to
|
||
; GetMenuBar that was made in <22> (the change history says it was
|
||
; made in <24>) since it doesn’t work.
|
||
; <25> 1/21/92 PN Get rid of duplicate EQU in MenuMgr.a
|
||
; (CmdChar,MenuResult,mItemResult,searchMenu HorRMenus,KeyFrame)
|
||
; <24> 1/21/92 PN Rolled in SetMenuBarAddsSystemMenus from SystemMenusPatch.a
|
||
; Rolled in GetMenuBarDoesNotReturnSystemMenus from
|
||
; SystemMenusPatch.a
|
||
; Rolled in PatchInsertMenu from SystemMenusPatch.a
|
||
; Rolled in ValidateMenuBarWhenDrawing from InvalMenuBarPatch.a
|
||
; Rolled in DrawMenuBarIfInvalidOnHiliteMenu from
|
||
; InvalMenuBarPatch.a
|
||
; Rolled in FixBTSTBugInMenuKey from MenuMgrPatch.a
|
||
; <23> 1/20/92 PN Roll in patches into MenuMgr.a, in this file using the routine
|
||
; InsrResMenu from MenuMgr.c
|
||
; <22> 1/20/92 PN Roll-in all the linked patches into MenuMgr.a
|
||
; <21> 12/31/91 RB Undo change <20>, I tell you.. you gotta read the change
|
||
; history...nice try
|
||
; <20> 12/31/91 RB Added an END directive to get rid of the warning.
|
||
; <19> 10/10/91 PKE #1012672, For Cube-E (and Bruges): Use new SCUpperText routine
|
||
; in MenuKey instead of UpperText, so we are independent of any
|
||
; grafPort font.
|
||
; <18> 8/28/91 JSM Leave InsrtResMenu here for ROM builds for now.
|
||
; <17> 8/22/91 KSM csd,#Bruges: Change MenuKey to call _UpperText instead of
|
||
; _UprString,MARKS (in the subroutine UpChar). This is the
|
||
; internationally correct routine (new for 7.0). 2) Conditionalize
|
||
; out InsertResMenu here, now in MenuMgr.c
|
||
; <16> 7/9/91 JSM Remove obsolete 7.0 related SysVers conditionals.
|
||
; <15> 3/31/91 dba gbm, csd: change DisposeMenu so it handles properly the case
|
||
; when a resource-based menu has been purged
|
||
; <12> 3/6/91 gbm dba: Take out change <11>, because Philip didn’t understand that
|
||
; this would break the system build.
|
||
; <11> 3/5/91 PN Fix the warning by putting back the END statement at the end
|
||
; <10> 12/14/90 KSM <dba>Fix bug in MenuKey where it is BTSTing a register for each
|
||
; item, but when the item is greater than 31, the BTST instruction
|
||
; wraps and we get flags for previous items.
|
||
; <9> 9/28/90 KSM <dba>Guarantee A5 world for calls into MDEFs.
|
||
; <8> 9/15/90 KSM Patch InsMenuItem to fix a PixelPaint bug!!*!
|
||
; <7> 7/30/90 KSM On the first day Ed was gone, we found a bug he created in
|
||
; version 2. An arbitrary line in “MenuChanged” was commented out.
|
||
; <6> 7/26/90 KSM fix Darin’s stupid STRING ASIS bug
|
||
; <5> 7/23/90 dba change name of GetItemStyle so it doesn’t conflict with glue
|
||
; <4> 5/13/90 SMB Removed SMgr patches in InitMenus and DrawMenuBar if not
|
||
; ‘ForROM’ since adding the Keyboard Menu. Will not patch out the
|
||
; ROM version of InitMenus since its call to SMgrCalcRect is
|
||
; harmless. However, am patching the SMgr's SwapIcon routine
|
||
; (called by DrawMenuBar) to do nothing. Need ScriptPriv.a all the
|
||
; time now due to the new flag used here.
|
||
; <3> 4/29/90 KSM Fix a bug in SetItemProperty which only is a bug if we turn on
|
||
; TearOffMenus again…
|
||
; <2> 12/19/89 EMT PROCize for more efficient dead code stripping. Nuked
|
||
; GetMenuInfo. Rearranged procedures for better branches. Renamed
|
||
; topEdge and leftEdge to not conflict with ColorEqu.a
|
||
; <1.9> 11/17/89 dba got rid of checks for 64K ROMs
|
||
; <1.8> 10/31/89 dba concatenated source files MenuMgr1.a and MenuMgr2.a to this one
|
||
; <2.7> 8/29/89 KSM Uses new vector routines to call Script Manager from RAM
|
||
; <1.9> 8/22/89 SES Changed mctSanityChk (which was in nFiles) to mctReserved (which
|
||
; is the official equ).
|
||
; <1.6> 8/22/89 SES removed references to nFiles.
|
||
; <2.5> 8/16/89 dba NEEDED FOR 6.0.4: InitProcMenu bug fixed: MBDF ID was not put in
|
||
; MenuList if MenuList was already allocated (InitMenus already
|
||
; called)
|
||
; <2.4> 8/8/89 dba NEEDED FOR 6.0.4: used TearOffMenus conditional; fixed
|
||
; InitProcMenu
|
||
; <2.3> 7/11/89 EMT Backed out 07Sep88 change to InitProcMenu to make Excel 2.2
|
||
; happy. Needed for Aurora, Esprit, and 6.0.4.
|
||
; <2.2> 6/14/89 JSM Fixed System 7.0 IF statement (700 => $700).
|
||
; <2.1> 6/14/89 KSM Fixed stack handling.
|
||
; <2.0> 6/14/89 DAF Added missing Big Bang conditional.
|
||
; <1.9> 6/14/89 KSM Added command key tear off method
|
||
; <1.7> 6/14/89 KSM Fixed incorrect branch offset
|
||
; <1.4> 6/5/89 CCH Conditionalized out include of MenuDispatch.a.
|
||
; <1.8> 6/2/89 KSM Changed all (NOT forRAM) to (forROM).
|
||
; <1.6> 6/2/89 KSM Updated conditionals for ROM/SYS build
|
||
; <1.3> 6/2/89 KSM Added include for MenuDispatch.
|
||
; <1.5> 6/1/89 KSM TEAR OFF MENU feature added.
|
||
; <1.4> 4/29/89 KSM Updated comments for 1.3
|
||
; <1.3> 4/25/89 KSM Fixed GetMenuBar bug <BRC#41545> to check for NIL MenuList and
|
||
; returns NIL instead of crashing. This problem exists because
|
||
; MultiFinder "faceless" applications don’t call
|
||
; InitWindows/InitMenus, but they do call SystemTask or
|
||
; WaitNextEvent which allows drivers to run. Drivers (like Deneba
|
||
; Software’s Spelling Coach) which call GetMenuBar when the
|
||
; Backgrounder is running - CRASH.
|
||
; Also Fixed DelMCEntries bug <BRC#40826> to correctly delete
|
||
; the entries in the table correctly (not just 1st one). Also
|
||
; keeps it from running rampant thru memory if next to last was
|
||
; deleted.
|
||
; <1.2> 2/20/89 rwh re-spelled conditional in comment, won’t show up in searches.
|
||
; <1.1> 11/10/88 CCH Fixed Header.
|
||
; <1.0> 11/9/88 CCH Adding to EASE.
|
||
; <1.5> 11/2/88 GGD Got rid of machine specific conditionals in favor of feature
|
||
; based conditionals.
|
||
; <1.4> 10/27/88 PKE added script manager support for initmenus
|
||
; <1.3> 10/7/88 rwh make NuMac support work for MvMac as well
|
||
; <•1.2> 10/3/88 EMT Roll in latest bug fixes.
|
||
; <•1.2> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
|
||
; PMAB568> 9/7/88 EMT Fix DeleteMenu so that highlighted menus are unhighlighted
|
||
; before being deleted. Custom menus should blink; fix ill-fated
|
||
; C222. Call MenuHook in CheckDragging And some miscellaneous code
|
||
; cleanup.
|
||
; PMAB568> 9/7/88 EMT AppendMenu calls CharByte to make sure meta characters are real.
|
||
; PMAB539> 7/19/88 EMT PopUpMenuSelect will now call CalcMenuSize when it invalidates
|
||
; sizes.
|
||
; <PP467> 4/18/88 DHD Fix InsertMenu patch to compare with -1 instead of checking
|
||
; negative for BeforeID’s throughout the code. This was already
|
||
; done for the first test, but subsequent ones were missed. See
|
||
; PMAB214.
|
||
; <•1.1> 3/22/88 EMT Roll in menu manager patches from 6.0 system.
|
||
; PMAB417> 3/3/88 EMT Patch GetMenuBar and SetMenuBar to handle saved bits correctly.
|
||
; <PB403> 2/24/88 DBG Fixed bug in PMAB364 which caused crash in PopupMenuSelect.
|
||
; PMAB364> 1/23/88 EMT Fix Pop-up menus to come up on any screen
|
||
; PMAB303> 11/21/87 EMT Use ROM override to install MBDF from S297 instead of
|
||
; MBDFPatchHndl.
|
||
; PMAB282> 9/20/87 FJL Don’t let DelMenuItem fool with EnableBits when item > 31.
|
||
; PMAB280> 9/18/87 FJL Set MBarEnable around SystemMenu call only if MBar not already
|
||
; owned by DA.
|
||
; PMAB280> 9/18/87 FJL Removed some overzealous lines added in PMAB255
|
||
; PMAB255> 9/1/87 FJL Call HiliteMenu around DrawMenuBar so don’t leave any bits
|
||
; behind dangling.
|
||
; PMAB255> 8/31/87 FJL Don’t insert enable bit if item is > 31
|
||
; PMAB233> 8/7/87 FJL HiliteMenu must do nothing if MBarHeight <= 3.
|
||
; PMAB214> 7/20/87 FJL InsertMenu inserts in HMenuList if (beforeID == -1) rather than
|
||
; (<= -1)
|
||
; <PM213> 7/20/87 FJL Check HwCfgFlags for valid PRAM when getting HMenu drag and
|
||
; delay settings
|
||
;
|
||
; System 4.2
|
||
;
|
||
; 3/26/87 FJL Changed MenuKey so that popups may have menu keys.
|
||
; <PMA133> 3/24/87 DAF Fixed DelMenuItem to call DelMCEntry only on nuMac.
|
||
; 3/6/87 FJL Clean up all NuMac conditionals for System Disk <1.2>
|
||
; <C844> 2/22/87 FJL New routines, GetItemCmd, SetItemCmd, PopUpMenuSelect
|
||
; <C826> 2/17/87 FJL Fixed FlashMenuBar to pass MenuList offset to mbarproc rather
|
||
; than menuID.
|
||
; <C808> 2/13/87 FJL Changed AddResMenu to call IUMagString. To do so needed to lock
|
||
; the menuHandle. This causes problems with Munger since it can’t
|
||
; relocate the locked block. Therefore only lock the handle around
|
||
; the IUMagString call.
|
||
; <C466> 12/2/86 FJL EnableItem and DisableItem now ignore items > 31.
|
||
; <A428> 11/20/86 FJL Interesting problem in HiliteMenu
|
||
; <C408> 11/15/86 FJL Added support for color menus
|
||
; <A/C391> 11/10/86 FJL Use GetResource to get the mbarproc each time we call it.
|
||
; <C341> 11/2/86 RDC Added pad char to menu table for asm problem
|
||
; <C338> 11/2/86 RDC Changed equ name to fix asm problem
|
||
; <A278> 10/27/86 FJL The application OVERVUE assumed D1 was clear on exit from
|
||
; MenuSelect, so we clear it for them (cough cough)
|
||
; <C222> 10/15/86 FJL Added hierarchical menus.
|
||
; <C175> 10/1/86 FJL Exported InitProcMenu.See notes in MenuMgr1.a for fix to
|
||
; MenuSelect bug, etc.
|
||
; <C174> 9/24/86 DAF New menuBar defproc menu manager. See StandardMBDF.a also
|
||
; <C174> 9/24/86 DAF Updated MenuSelect for menuBar defproc
|
||
; <C169> JTC Cleaned up GetTheMDef/UnlkMDef for 32-bit robustness.
|
||
; 8/20/86 DAF Menu Bar DefProc modifications (see StandardMBDF.a)
|
||
; <C175> 8/8/86 FJL Fix to InitProcMenu and InitMenus for possible _GetResource
|
||
; error. Problem when moved mouse out of menu bar quickly, fixed
|
||
; with change in MenuSelect. Scrolling menus were drawing outside
|
||
; of their region, so set ClipRect in DrawTheMenu. Changed
|
||
; InitMenus so doesn’t realloc menu struct if global menuList is
|
||
; not NIL (this allows InitWindows to call InitMenus to get
|
||
; MBarHeight without reallocing space when user calls InitMenus).
|
||
; Fix to _HiliteMenu -- when HiliteMenu was called with a
|
||
; non-existent menuID it would store that ID in theMenu global and
|
||
; cause the mbarproc to flip the bar when HiliteMenu(0) was next
|
||
; called.
|
||
; <C60> 6/30/86 EHB Made MenuSelect save off more bits for color.
|
||
; 4/10/86 SAB rolled in a patch from ROM75 to fix inserting into the middle of
|
||
; a resmenu.
|
||
; 2/19/86 BBM Made some modifications to work under MPW
|
||
;
|
||
; Lonely Hearts ROMs (Macintosh Plus)
|
||
;
|
||
; 11/2/85 EHB Reinstated call to _TextFont in InsertMenu (no one should change
|
||
; it, but...).
|
||
; 9/30/85 EHB Removed underline of FONDs in AddResMenu (put back CalcMenuSize)
|
||
; 9/6/85 EHB GetItemProperty was clearing a word result instead of a byte.
|
||
; 8/5/85 EHB .DEF CalcMBHeight for use by wmgr
|
||
; 8/5/85 EHB Modified for variable sized system font
|
||
; 7/9/85 EHB Get MDEF 0 from ROM map
|
||
; 5/21/85 EHB Made AddResMenu, InsertResMenu sort items as they go in
|
||
; 5/9/85 EHB Added new procedure InsMenuItem -- like append menu, but inserts
|
||
; anywhere. Now AppendMenu,InsMenuItem,AddResMenu,InsrtResMenu all
|
||
; share same insert code.
|
||
; 5/7/85 EHB In AddResMenu, make sure each name added is unique. Compare is
|
||
; done using CompString, also used by the Res Manager for
|
||
; getNamedResource.
|
||
; 5/3/85 EHB Oops! forgot to delete enable bits in DelMenuItem. All better
|
||
; now.
|
||
; 4/23/85 EHB In Insert/AddResMenu, if adding 'FONT', add 'FOND' too.
|
||
; 4/15/85 EHB Added new procedure DelMenuItem -- remove a menu item from its
|
||
; menu
|
||
; 4/15/85 EHB In routine MenuKey, use UprString to upshift the passed
|
||
; keystroke.
|
||
; 4/11/85 EHB Check for purged menuList and menu on all internal references If
|
||
; purged, I generate DS #54 (MenuPrgErr).
|
||
; 4/11/85 EHB Made menus of 0 size work. To do this, tweaked DirtyMenuSize to
|
||
; invalidate size with -1 instead of 0.
|
||
; 4/9/85 EHB Do GetMouse after WaitMouseUp to avoid invalid flashes CLR.L
|
||
; FuncResult(A6) to avoid returning invalid items
|
||
; 3/13/85 EHB Fixed stack frame for MenuSelect
|
||
; 3/13/85 EHB Fixed stack offset in DirtyMenuSize (oops!)
|
||
; 3/6/85 EHB Use update to restore menus if out of memory
|
||
; 3/5/85 EHB Added Routine DirtyMenuSize so that CalcMenuSize only gets
|
||
; called before drawing.
|
||
; 3/5/85 EHB Call CalcMenuSize, if necessary, before drawing
|
||
; 3/5/85 EHB In AddResMenu, preserve state of resLoad
|
||
; 1/24/85 EHB In SetItemProperty, don’t CalcMenuSize if item = check mark
|
||
; 1/24/85 EHB Preserved the clip region in FlashMenuBar
|
||
; 1/24/85 EHB Tweaked DrawTheMenu to not save the menu bar
|
||
; 1/24/85 EHB Reset alarm parity in DrawMenuBar
|
||
; 9/7/83 AJH save in DrawMBar
|
||
; 8/27/83 AJH saved a little code in CalcMenuSize (use common subroutine)
|
||
; 8/27/83 AJH Made it include "SysErr"
|
||
; 8/27/83 AJH handled out of memory case in SaveBits by deep-shitting
|
||
; 8/23/83 BLH (with LAK) Fixed bug in GetMHandle (didn’t return result!)
|
||
; 8/19/83 AJH Moved loc of menu flash bits.
|
||
; 8/13/83 SC The code scrunch-a-matic pass... Made NoIndex fall into GotIndex
|
||
; Moved getIndex, invertTitle. Added utility GetNInvert. Made
|
||
; saveBits inline.
|
||
; 8/9/83 AJH Made it reference "WmgrGray"
|
||
; 6/30/83 AJH fixed bug in InsrtResMenu when there’s none of that type
|
||
; 6/15/83 AJH Added InsrtResMenu
|
||
; 6/14/83 AJH made SetItem call CalcMenuSize
|
||
; 5/18/83 AJH fixed GetMHandle bug
|
||
; 5/11/83 AJH Added CountMItems
|
||
; 5/6/83 AJH fixed PlotIcon bug (didnt set up topLeft)
|
||
; 4/28/83 AJH moved calcMenuSize into the defProc
|
||
; 4/21/83 AJH Made CalcMenuSize add some extra for command line
|
||
; 4/17/83 AJH Made MenuKey know about desk ornament menus
|
||
; 4/13/83 AJH Tweaked MBarEnable logic in MenuSelect
|
||
; 4/4/83 AJH Made it get menuFlash from parameter RAM
|
||
; 3/18/83 AJH Made InvertTitle go one pixel higher
|
||
; 3/16/83 AJH Made CalcMenuSize not bold disabled items
|
||
; 3/15/83 AJH Made Enable/DisableItem not recalc menu size
|
||
; 2/13/83 AJH Made PlotIcon use copyBits instead of XferRect
|
||
; 2/5/83 AJH Changed "AddRsrcMenu" to "AddResMenu" to keep Caroline happy
|
||
; 2/5/83 AJH AddRsrcMenu -> AddResMenu; made it not load the objects
|
||
; 1/28/83 AJH Added "FlashMenuBar"
|
||
; 1/28/83 AJH Improved CalcMenuSize
|
||
; 1/25/83 AJH Fixed outline/shadow reversal bug
|
||
; 1/25/83 AJH Fixed MenuSelect mouse-ahead problem
|
||
; 1/24/83 AJH Added support for deskOrns stealing the menuBar
|
||
; 1/23/83 LAK Adapted for new equate files.
|
||
; 1/21/83 AJH Fixed bug in GetSizeLeft in SetItem
|
||
; 1/20/83 AJH Fixed purged defProc problem (lock after LoadResource)
|
||
; 12/27/82 AJH Moved menuData to end of block; defProc as resource
|
||
; 12/19/82 AJH Added "AddRsrcMenu" call
|
||
; 12/11/82 AJH Made space between menus less wide (14 pixels)
|
||
; 11/22/82 AJH Made TextMenuProc and CalcMenuSize externally accessible
|
||
; 11/16/82 AJH Made the menuBar 4 pixels wider
|
||
; 11/7/82 AJH Made menuKey case insensitive
|
||
; 10/25/82 AJH Made space between menus wider for 512 dots (12 -> 18)
|
||
; 10/16/82 AJH Made it independent of screen size (use wmgr^.portRect)
|
||
; 10/10/82 AJH Converted to QuickDraw Trap Interface
|
||
; 9/20/82 AJH Fixed problem in DeleteMenu
|
||
; 9/7/82 AJH Added "DrawMBar" entry point
|
||
; 9/7/82 AJH Made DrawMBar a separate routine to save code
|
||
; 8/22/82 AJH Got rid of menu manager dependency on icon manager
|
||
; 8/2/82 AJH Converted for new memory manager; no more oh’s!
|
||
; 7/24/82 AJH Fixed left corner problem in DrawMenuBar
|
||
; 6/29/82 AJH New today.
|
||
;
|
||
|
||
;-------------------------------------------------------------------------
|
||
;
|
||
; Conditional Definitions and Includes
|
||
;
|
||
;-------------------------------------------------------------------------
|
||
|
||
string asis
|
||
|
||
LOAD 'StandardEqu.d'
|
||
include 'InternalMacros.a' ;<SM5> <PN>
|
||
include 'DialogsPriv.a' ;<SM5> <PN>
|
||
INCLUDE 'ColorEqu.a'
|
||
INCLUDE 'MenuMgrPriv.a'
|
||
INCLUDE 'Packages.a' ; for IUMagString
|
||
INCLUDE 'ScriptPriv.a' ; <1.7> for Ram vectors to ScriptMgr internal routines
|
||
INCLUDE 'Balloons.a' ;
|
||
INCLUDE 'BalloonsPriv.a' ;
|
||
|
||
IMPORT Find6BOFromID
|
||
|
||
MACHINE MC68020 ; needed for cache flush <LW2> fau
|
||
|
||
GetParamRamData PROC ENTRY
|
||
;------------------------------------------------
|
||
; Utility -- GetParamRamData <FJL C222>
|
||
;------------------------------------------------
|
||
; Get menuDelay and menuDrag tick counts from
|
||
; parameter ram and store in mbSaveLoc
|
||
;
|
||
; Trashes: A0, D0
|
||
move.l mbSaveLoc, a0 ; get mbSaveLoc lo-mem
|
||
move.l (a0), a0 ; dereference
|
||
|
||
move.b #0, mbMenuDelay(a0) ; set default in case no new pram <FJL PM213>
|
||
move.b #0, mbMenuDrag(a0) ; ditto
|
||
|
||
btst #5, HwCfgFlags ; is larger pram valid ?
|
||
beq.s @SetLowMem ; no -> branch, no pram
|
||
|
||
lea mbMenuDelay(a0), a0 ; a0 has address of buffer
|
||
moveq #1, d0 ; want one byte
|
||
swap d0 ; put #1 in hi-byte
|
||
move #menuDelay, d0 ; param ram address in lo-byte
|
||
_ReadXPRam
|
||
|
||
move.l mbSaveLoc, a0 ; get mbSaveLoc lo-mem
|
||
move.l (a0), a0 ; dereference
|
||
lea mbMenuDrag(a0), a0 ; a0 has address of buffer
|
||
moveq #1, d0 ; want one byte
|
||
swap d0 ; put #1 in hi-byte
|
||
move #menuDrag, d0 ; param ram address in lo-byte
|
||
_ReadXPRam
|
||
|
||
@SetLowMem move.l mbSaveLoc, a0 ; see if need to set defaults
|
||
move.l (a0), a0 ; dereference
|
||
tst.b mbMenuDelay(a0)
|
||
bne.s @1 ; not zero --> don’t set default
|
||
addi.b #8, mbMenuDelay(a0) ; default == 8 Ticks (tried and true by FJL)
|
||
|
||
@1 tst.b mbMenuDrag(a0)
|
||
bne.s @GetParmDone ; not zero --> don’t set default
|
||
addi.b #60, mbMenuDrag(a0) ; default == 1 second (no reason not to be huge
|
||
; default value because of way dragging works)
|
||
@GetParmDone
|
||
rts
|
||
ENDPROC
|
||
|
||
InitProcMenu PROC EXPORT
|
||
; Begin <2.3 EMT>
|
||
|
||
;
|
||
; procedure InitProcMenu ( mbResID : integer);
|
||
;
|
||
; The resID is stored in the MenuList header as a word at location $4. <FJL C428>
|
||
; The low 3 bits of mbResID are used as the variant!! The whole mbResID <FJL 23Jan87>
|
||
; is used as the resID.
|
||
;
|
||
; This routine performs the same function as InitMenus, except it allows
|
||
; specification of the MBDF resID rather than assuming MBDF=0.
|
||
;
|
||
;
|
||
|
||
; MBarProc routine <C175>
|
||
;
|
||
move.l (sp)+,a0 ; get the return address <2.4>
|
||
move.w (sp)+,d1 ; get the MBDF resource ID <2.4>
|
||
move.l a0,-(sp) ; put return address back on the stack <2.4>
|
||
IMPORT IMCommon
|
||
bra IMCommon ; go join InitMenus <2.4>
|
||
|
||
; End <2.3 EMT>
|
||
ENDPROC
|
||
|
||
INITMENUS PROC EXPORT
|
||
;
|
||
; PROCEDURE InitMenus -- initialize the menu manager by allocating an empty menuList
|
||
;
|
||
|
||
MOVEQ #0,D1 ; standard rom based MBDF is #0 <DAF 20Aug86>
|
||
|
||
ENTRY IMCommon
|
||
IMCommon ; D0 contains resID now. <PMAB568 07Sep88 EMT> <2.4>
|
||
|
||
MOVE.W #MapTRUE,ROMMapInsert ; set flag to load from ROM <DAF 20Aug86>
|
||
|
||
SUBQ #4,SP ; make room for function return <DAF 20Aug86>
|
||
MOVE.L #'MBDF',-(SP) ; load the standard menu bar defProc <DAF 20Aug86>
|
||
MOVE.W D1,-(SP) ; push the resID <DAF 20Aug86>
|
||
_GetResource ; load it <DAF 20Aug86>
|
||
move.l (SP)+, MBDFHndl ; save defproc handle in lomem <C175 FJL>
|
||
bne.s @gotIt ; if handle not NIL, then continue <C175 FJL> <PMAB568 07Sep88 EMT>
|
||
|
||
TST.W D1 ; standard rom based MBDF is #0 <PMAB568 07Sep88 EMT>
|
||
|
||
BNE.S INITMENUS ; Try the default <PMAB568 07Sep88 EMT>
|
||
|
||
MOVE.W #dsMBarNFnd,D0 ; if defproc could not be loaded, die <DAF 20Aug86>
|
||
_SysError ;
|
||
|
||
@gotIt ; <PMAB568 07Sep88 EMT>
|
||
; InitApplZone clears MenuList global. <C175 FJL>
|
||
; If it is NIL, then init data structures, <C175 FJL>
|
||
; else they are already inited, so return. <C175 FJL>
|
||
move.l MenuList,d0 ; test the menu list handle <2.5>
|
||
ble.s CreateMenuList ; if NIL then menu list needs to be created <2.5>
|
||
|
||
move.l d0,a0 ; get the menu list; it already exists <2.5>
|
||
move.l (a0),a0 ; dereference the menu list <2.5>
|
||
move.w d1,mbResID(a0) ; store MBDF ID <2.5>
|
||
bra.s IMDone ; now, we’re done <2.5>
|
||
|
||
CreateMenuList
|
||
|
||
bsr.s InitMList ;allocate and initialize a menuList block <FJL C222>
|
||
MOVE.L A0,MENULIST ;make it the current menuList
|
||
MOVE.L (A0), A0 ; get the menuPtr <PMAB568 07Sep88 EMT>
|
||
move.w D1, mbResID(a0) ; store resID <FJL C428> <PMAB568 07Sep88 EMT>
|
||
|
||
clr theMenu ; clear lo mem so no hilited menu <FJL C222>
|
||
|
||
MOVEQ #$0C,D0 ;only use 2 bits worth
|
||
AND.B SPMisc2,D0 ;get pRam flags
|
||
LSR #2,D0 ;get menuFlash in the low bits
|
||
MOVE D0,MenuFlash ;set up menuFlash field
|
||
|
||
CLR.W MBarEnable ;initally, application owns MBar
|
||
CLR.L MBarHook ;<SM13> init MBarHook
|
||
CLR.L MENUHOOK ;init user hook
|
||
|
||
; tell the MBarProc to init any data structures
|
||
MOVEQ #3,D0 ; set up for the init message <DAF 20Aug86>
|
||
MOVE.L #0,D1 ; parameter is 0 for cleared bar only <DAF 20Aug86>
|
||
IMPORT CallMBarProc
|
||
BSR CallMBarProc ; execute the defproc,ignoring the result <DAF 20Aug86>
|
||
IMPORT GETPARAMRAMDATA
|
||
bsr GETPARAMRAMDATA ;read MenuDrag/MenuDelay into mbSaveLoc
|
||
_ClearMenuBar ;initialize menuBar parameters and clear it
|
||
_DrawMenuBar
|
||
|
||
IMDone
|
||
|
||
; InitMList alloc’s a menuList with no menus and no hierarchical menus <FJL C222>
|
||
ENTRY InitMList
|
||
InitMList
|
||
moveq #InitMListSize, d0 ; get size of menuList d.s.
|
||
_NewHandle CLEAR ; alloc it
|
||
move.l (a0), a1 ; dereference the handle
|
||
|
||
;set up the menu header
|
||
move.w #mbMenu1Loc, lastRight(a1) ; set lastRight to ten (decimal)
|
||
|
||
rts
|
||
ENDPROC
|
||
|
||
|
||
CLEARMENUBAR PROC EXPORT
|
||
;
|
||
; PROCEDURE ClearMenuBar -- clear the menuBar/menuList data structure
|
||
;
|
||
|
||
IMPORT GetA0List
|
||
BSR GetA0List ; check for purged list <EHB 11-Apr-85>
|
||
|
||
MOVE.L MENULIST,A0 ; get handle to menuList
|
||
_DisposHandle ; dispose of the handle <FJL C222>
|
||
|
||
IMPORT InitMList
|
||
bsr InitMList ; init a new one <FJL C222>
|
||
move.l a0, menuList ; and store it <FJL C222>
|
||
|
||
CLR.W THEMENU ; no menu is hilited
|
||
|
||
RTS
|
||
ENDPROC
|
||
|
||
GetMenuRgn Proc Export
|
||
; Utility GetMenuRgn -- returns the region occupied by the MenuBar.
|
||
;
|
||
Move.l (Sp)+,D0 ; Save the return address.
|
||
Move.l (Sp)+,D1 ; Get the caller’s RgnHandle.
|
||
Move.l D0,-(Sp) ; Restore return address.
|
||
Moveq #12,D0 ; Call MBarProc to return RgnHandle.
|
||
Import CallMBarProc
|
||
Bsr CallMBarProc ; Call the DefProc.
|
||
Rts
|
||
Endproc
|
||
|
||
|
||
CalcMBHeight PROC EXPORT ; <EHB 5 Aug 85>
|
||
; call MBarProc to calc height <FJL 11Mar87>
|
||
MOVEQ #6,D0 ; set up for the height message, no params
|
||
|
||
EXPORT CallMBarProc ; <FJL C222>
|
||
CallMBarProc
|
||
;-------------------------------------------------------------------------------------------
|
||
;
|
||
; Utility -- CallMBarProc
|
||
;
|
||
; On Entry: d0 lo-word=message number, hi-word=parameter1 <FJL 3Feb87>
|
||
; d1 parameter2
|
||
; Use: a0
|
||
; On Exit: d0 return value
|
||
;
|
||
; mbResID: comes from menuList
|
||
; mbVariant: the low 3 bits of mbResID are the variant
|
||
;
|
||
; Note that we store the MBDF’s Hndl in low memory location MBDFHndl but this is for
|
||
; convenience only. We do not count on its being there between calls to this utility.
|
||
;
|
||
;-------------------------------------------------------------------------------------------
|
||
movem.l d4, -(SP) ; save work register
|
||
|
||
CLR.L -(SP) ; make room for defproc return <DAF 20Aug86>
|
||
MOVE.L MenuList,A0 ; get the menuList head <DAF 20Aug86>
|
||
MOVE.L (A0),A0 ; handle->pointer <DAF 20Aug86>
|
||
|
||
move mbResID(a0), -(SP) ; get resource ID <FJL C428><24Jan87>
|
||
andi.w #0007, (SP) ; use low 3 bits only <FJL 24Jan87>
|
||
MOVE.W D0,-(SP) ; push the message number <DAF 20Aug86>
|
||
swap d0 ; get parameter1 in lo-word
|
||
move.w d0, -(SP) ; push parameter1 <FJL 3Feb87>
|
||
MOVE.L D1,-(SP) ; push parameter2 <DAF 20Aug86>
|
||
;
|
||
; get the mbarproc each time we call it instead of counting on low mem to be correct <FJL A/C391>
|
||
;
|
||
subq #4, SP ; space for return result
|
||
move.l #'MBDF', -(SP)
|
||
|
||
move mbResID(a0), -(SP) ; get resource ID
|
||
|
||
MOVE.W #MapTRUE,ROMMapInsert ; set flag to load from ROM <DAF 20Aug86>
|
||
_GetResource
|
||
move.l (SP)+, MBDFHndl
|
||
|
||
MOVE.L MBDFHndl,A0 ; get the menu bar defproc handle
|
||
_HGetState ; get the current state
|
||
move.l d0, d4 ; save state in d4
|
||
_HLock ; lock it
|
||
MOVE.L (A0),A0 ; get a pointer to it
|
||
JSR (A0) ; jump to it
|
||
|
||
; returned from defproc, return handle to previous state before exiting
|
||
|
||
MOVE.L MBDFHndl,A0 ; get the handle
|
||
move.l d4, d0 ; get previous state from d4
|
||
_HSetState ; reset previous state
|
||
MOVE.L (SP)+,D0 ; get the defproc return
|
||
|
||
movem.l (SP)+, d4 ; restore work register
|
||
RTS ; and return
|
||
ENDPROC
|
||
|
||
DELETEMENU PROC EXPORT
|
||
;
|
||
; PROCEDURE DeleteMenu(menuID: INTEGER) -- delete a given menu from the menuList.
|
||
; Note that deleteMenu will not de-allocate the menu, since it may be in other
|
||
; menuLists.
|
||
;
|
||
; Look first in the Hmenu list, then in the regular menu list <FJL C222><FJL 4Mar87>
|
||
; Delete all color table entries for this menuID <FJL C408>
|
||
MOVE.W theMenu, D0 ; Get the currently highlighted menu <PMAB568 07Sep88 EMT>
|
||
CMP.W 4(SP), D0 ; Is it this one? <PMAB568 07Sep88 EMT>
|
||
BNE.S @NotHilited ; Nope, skip <PMAB568 07Sep88 EMT>
|
||
CLR.W -(SP) ; <PMAB568 07Sep88 EMT>
|
||
_HiliteMenu ; Unhighlight it <PMAB568 07Sep88 EMT>
|
||
@NotHilited ; <PMAB568 07Sep88 EMT>
|
||
|
||
moveq #0, d1 ; clear d1 for GetHIndex <FJL C222>
|
||
MOVE.W 4(SP),D1 ; get the menuID
|
||
IMPORT GetHIndex
|
||
bsr GetHIndex ; try H Menu <FJL C222>
|
||
bne.s @FoundHMenu ; found a HMenu so delete it <FJL C222>
|
||
|
||
IMPORT GetIndex
|
||
BSR GETINDEX ; get the index into D0
|
||
beq.s TwoBytExit ; didn’t find either, so nada to delete <FJL C222>
|
||
|
||
@FoundMenu
|
||
IMPORT GetA1List
|
||
BSR GetA1List ; get menuList into A1 <EHB 11-Apr-85>
|
||
CMP.W LASTMENU(A1),D0 ;is this one the last one?
|
||
BNE.S @OneLessMenu ;if not, go and delete it
|
||
; special case deleting the last menu
|
||
; make lastRight = old menuLeft
|
||
MOVE.W MenuLeft(A1,D0),lastRight(A1) ;set new lastRight
|
||
|
||
@OneLessMenu SUBQ #6,LASTMENU(A1) ; one less menu in list
|
||
bra.s @MungeIt ; and delete it <FJL C222>
|
||
|
||
@FoundHMenu
|
||
IMPORT GetHA1List
|
||
bsr GetHA1List ; get HMenuList into A1 <FJL C222>
|
||
subq #6, lastHMenu(a1) ; one less menu in list <FJL C222>
|
||
|
||
@MungeIt moveq #0, d1 ; clear all of d1
|
||
move.w d0, d1 ; move low word of d0 only, hiword has garbage
|
||
move.l menuList, a0 ; get menuList handle
|
||
move.l (a0), a0 ; dereference
|
||
adda.l d1, a0 ; get pointer to 6 bytes to be deleted
|
||
|
||
subq #4, SP ; space for result
|
||
move.l menuList, -(SP) ; move the menuList handle onto the stack
|
||
move.l d1, -(SP) ; d1 has offset into menuList or HMenuList
|
||
move.l a0, -(SP) ; ptr to target string
|
||
moveq #6, d0 ; len1 = 6 bytes
|
||
move.l d0, -(SP)
|
||
moveq #4, d0
|
||
move.l d0, -(SP) ; make replacement string non-NIL so deletes properly
|
||
; just point at an even byte in low-mem
|
||
clr.l -(SP) ; and its length is zero ===> delete
|
||
_Munger ; oooohhh -- aaaahhh -- do it baby
|
||
addq #4, SP ; ignore dem results
|
||
|
||
MOVEQ #2,D0 ; set up for the menu-edge-calc msg
|
||
CLR.L D1 ; calc entire bar
|
||
IMPORT CallMBarProc
|
||
BSR CallMBarProc ; execute the defproc
|
||
|
||
; Now delete all of the entries in the color table for this
|
||
ENTRY TwoBytExit
|
||
TWOBYTEXIT MOVE.L (SP)+,A0 ;get return address
|
||
ADDQ #2,SP ;strip parameter
|
||
JMP (A0) ;return to caller
|
||
ENDPROC
|
||
|
||
GetHIndex PROC ENTRY
|
||
;---------------------------------------------------------------------------------------------
|
||
;
|
||
; GetHIndex is similar to GetIndex but it looks thru the hierarchical menu list for a <FJL C222>
|
||
; menu of the given menuID. The menuID is passed in D1 and the index is returned in <FJL C222>
|
||
; D0. If the menuID can’t be found, D0 returns zero. If D1 = $FFFFFFFF then D0 returns <FJL C222>
|
||
; the index to the HMenu header info. The z-flag can be used to determine if one was <FJL C222>
|
||
; found.
|
||
;
|
||
move.l d3, -(SP) ; save work register
|
||
|
||
tst.l d1 ; is index 0?
|
||
beq.s @HNotFound ; if so, return 0
|
||
|
||
IMPORT GetA1List
|
||
bsr GetA1List ; get menuList ptr into a1
|
||
move lastMenu(a1), d2 ; get # regular menus
|
||
addq #6, d2 ; now d2 has index to H Menu header info
|
||
cmpi.l #$FFFFFFFF, d1 ; is index = $FFFFFFFF?
|
||
beq.s @GotHIndex ; yes, so return index to H Menu info
|
||
|
||
; no, so look thru H Menus
|
||
move (a1,d2), d3 ; get # hierarchical menus
|
||
beq.s @HNotFound ; if none then H Menu not found
|
||
|
||
; there are H Menus, so search them for the rsrcID in D1
|
||
add d2, d3 ; d3 is now index to last H Menu
|
||
exg d2, d3 ; d2 - index to last H Menu
|
||
; d3 - index to H Menu header info
|
||
@GetHILoop move.l menuHOH(a1,d2), a0 ; get the handle
|
||
move.l (a0), a0 ; get the pointer
|
||
cmp menuID(a0), d1 ; is this the right menuID
|
||
beq.s @GotHIndex ; yes, so return
|
||
@ChkNxtIndex subq #6, d2 ; bump down to next entry
|
||
cmp d2, d3 ; are we at the H Menu header info?
|
||
bne.s @GetHILoop ; no, so continue checking
|
||
; yes, drop thru and return 0 meaning not found
|
||
@HNotFound moveq #0, d2
|
||
;
|
||
; take the index in d2 and return it in d0
|
||
;
|
||
@GotHIndex move.l (SP)+, d3 ; restore work register
|
||
move d2, d0 ; get index in d0 and set z-flag
|
||
rts
|
||
ENDPROC
|
||
|
||
EXPORT GETINDEX
|
||
GETINDEX PROC ENTRY
|
||
;---------------------------------------------------------------------------------------------
|
||
;
|
||
; GetIndex is a utility routine that returns an index into the menuList given a
|
||
; menuId. The menuId is passed in D1 while the index is returned in D0. If the
|
||
; menuId can't be found, D0 will return a zero. A0, A1 and D2 are trashed.
|
||
; The Z-flag can be used to determine if one was found. As a special bonus, on
|
||
; exit A0 points to the menu, if a menu was found.
|
||
;
|
||
TST D1 ; is index 0?
|
||
BEQ.S NOINDEX ; if so, return 0
|
||
IMPORT GetA1List
|
||
BSR GetA1List ; get menuList into A1 <EHB 11-Apr-85>
|
||
MOVE LASTMENU(A1),D2 ; get # of menus
|
||
BEQ.S NOINDEX ; if none, say we can't find it
|
||
;
|
||
; here is the search loop. Get the next handle, and check the menuID
|
||
;
|
||
GILOOP MOVE.L MENUOH(A1,D2),D0 ; get the handle
|
||
MOVE.L D0,A0 ; get handle in A-reg
|
||
MOVE.L (A0),A0 ; handle -> pointer
|
||
CMP MENUID(A0),D1 ; is this the one?
|
||
BEQ.S GOTINDEX ; if they match, we're done
|
||
;
|
||
NEXTINDEX SUBQ #6,D2 ; bump to next entry
|
||
BNE.S GILOOP ; loop if there's more to do
|
||
;
|
||
; we couldn't find it so return zero in D0
|
||
;
|
||
NOINDEX MOVEQ #0,D2 ; return 0
|
||
;
|
||
; we found it so return index in D0
|
||
;
|
||
GOTINDEX MOVE D2,D0 ; get index in D0
|
||
RTS
|
||
ENDPROC
|
||
|
||
INSERTMENU PROC EXPORT
|
||
;
|
||
; PROCEDURE InsertMenu(menu: menuInfoHandle; beforeId: INTEGER);
|
||
;
|
||
; insert a menu into the menuList. beforeID is the menuID of the menu
|
||
; that the new menu should be inserted before. If beforeID can’t be found,
|
||
; the new menu is inserted at the end of the list. If the menu is already
|
||
; in the list, don’t insert it
|
||
;
|
||
; If beforeID = -1 then insert menu at front of HMenuList <FJL C222>
|
||
; Used < 0 as the criteria for inserting in HMenus, changed to = -1 <FJL 8May87>
|
||
|
||
movem.l d3/a3-a4,-(SP) ; save working registers
|
||
|
||
cmp.w #$FFFF, 16(SP) ; beforeID = -1 ==> H Menu <FJL 8May87>
|
||
beq.s @InsertHMenu ; yes, so branch <FJL C222>
|
||
|
||
IMPORT GetA0List
|
||
BSR GetA0List ; get menuList into A0 <EHB 11-Apr-85>
|
||
MOVE.L A0,A3 ; get pointer into A3 <EHB 11-Apr-85>
|
||
|
||
move.l 18(SP),a0 ; get menuInfoHandle
|
||
move.l (a0),a0 ; get ptr to menu block
|
||
MOVE menuID(a0), d1 ; get menuId of menu to be installed
|
||
IMPORT GetIndex
|
||
BSR GETINDEX ; is it already in the list?
|
||
BNE.S @DONEINSERT ; don’t insert same one twice
|
||
|
||
move.w 16(SP),d1 ; get beforeID
|
||
BSR GETINDEX ; get index into menuList of beforeID menu
|
||
bne.s @AllocEntry ; if we found one, branch and insert it
|
||
|
||
; the "beforeID" menu was not in the list, so insert this one at the end of the list
|
||
|
||
MOVE LASTMENU(A3),D0 ; get # of menus in menuList.
|
||
addq #6, d0 ; and insert this one AFTER it <FJL C222>
|
||
BRA.S @AllocEntry ; go insert it
|
||
;
|
||
; insert a H Menu at the front of the HMenuList if id not already in the HMenuList <FJL C222>
|
||
@InsertHMenu
|
||
IMPORT GetHA0List
|
||
bsr GetHA0List ; get ptr to HMenuList in A0
|
||
move.l a0, a3 ; and save it in a3
|
||
|
||
move.l 18(SP), a0 ; get menuInfoHandle
|
||
move.l (a0),a0 ; get ptr to menu block
|
||
moveq #0, d1 ; clear d1 (for GetHIndex call)
|
||
move menuID(a0), d1 ; get menuId of menu to be installed
|
||
IMPORT GetHIndex
|
||
bsr GetHIndex ; is it already in the list?
|
||
bne.s @DoneInsert ; don’t insert same one twice
|
||
|
||
addq #6, lastHMenu(a3) ; bump total of HMenus
|
||
move.l MinusOne, d1 ; set up for GetHIndex call
|
||
bsr GetHIndex ; get index to HMenuList header info in d0
|
||
addq #6, d0 ; point to first entry in HMenuList
|
||
;
|
||
; Now, use _Munger to insert space into the new, wild and wooly, dynamic menuList.
|
||
;
|
||
; allocate 6 bytes and store the menuInfoHandle in it
|
||
@AllocEntry moveq #0, d3 ; clear d3
|
||
move.w d0, d3 ; store menuList offset in d3
|
||
clr.l TempRect ; use TempRect for temp data
|
||
clr.l TempRect+4 ; clear temp data loc first
|
||
lea TempRect, a0
|
||
|
||
move.l 18(SP), menuOH(a0) ; init regular menu, store the menuInfoHandle <PP467 18Apr88>
|
||
cmp.w #$FFFF, 16(SP) ; beforeID = -1 ==> H Menu <PP467 18Apr88>
|
||
;// tst.w 16(SP) ; is this a H Menu? <PP467 18Apr88>
|
||
beq.s @InitHEntry ; yes, so init header info differently <PP467 18Apr88>
|
||
|
||
IMPORT GetA1List
|
||
bsr GetA1List ; get menuList ptr in A1, A3 could be bad! <FJL CXXX>
|
||
addq #6, lastMenu(A1) ; bump total number of menus
|
||
;// bra.s @MungeIt ; and continue <DHD PP467>
|
||
|
||
@InitHEntry ;////move.l 18(SP), menuHoH(a0) ; store menuInfoHandle <PP467 18Apr88>
|
||
|
||
;
|
||
; now Munge those 6 bytes into the menuList
|
||
;
|
||
@MungeIt subq #4, SP ; space for result
|
||
move.l menuList, -(SP) ; move the menuList handle onto the stack
|
||
move.l d3, -(SP) ; d3 has offset into menuList
|
||
clr.l -(SP) ; no target string
|
||
clr.l -(SP) ; len1 = 0 ===> want an insert
|
||
move.l a0, -(SP) ; push replacement string
|
||
move.l #6, -(SP) ; and it’s length
|
||
_Munger ; oooohhh -- aaaahhh -- do it baby
|
||
addq #4, SP ; ignore dem results
|
||
|
||
cmp.w #$FFFF, 16(SP) ; beforeID = -1 ==> H Menu <PP467 18Apr88>
|
||
;// tst.w 16(SP) ; is this a H Menu? <DHD PP467>
|
||
beq.s @DoneInsert ; yes, so no need for menu-edge recalc <DHD PP467>
|
||
|
||
MOVEQ #2,D0 ; set up for the menu-edge-calc msg <DAF 20Aug86>
|
||
CLR.L D1 ; calc entire bar
|
||
IMPORT CallMBarProc
|
||
BSR CallMBarProc ; execute the defproc <DAF 20Aug86>
|
||
|
||
@DONEINSERT movem.l (SP)+,d3/a3-a4 ; restore registers
|
||
ENTRY SixBytExit
|
||
SIXBYTEXIT MOVE.L (SP)+,A0 ; get return address
|
||
ADDQ #6,SP ; strip parameters
|
||
JMP (A0) ; return to caller
|
||
ENDPROC
|
||
|
||
DrawMBar PROC EXPORT
|
||
; Utility DrawMBar -- clear the menuBar and draw the line underneath it, leaving
|
||
; the wmgrPort clipRgn clipped to it. This is a separate routine so InitWindows
|
||
; can call it to save code.
|
||
MOVEQ #0,D0 ; set up for the draw message <DAF 20Aug86>
|
||
MOVE.L #-1,D1 ; parameter is -1 for cleared bar only <DAF 20Aug86>
|
||
IMPORT CallMBarProc
|
||
BSR CallMBarProc ; execute the defproc <DAF 20Aug86>
|
||
RTS
|
||
ENDPROC
|
||
|
||
DRAWMENUBAR PROC EXPORT
|
||
;
|
||
; PROCEDURE DrawMenuBar -- draw the current menuList on the menuBar
|
||
;
|
||
; Call HiliteMenu around DrawMenuBar so that don’t have dangling bits behind all around <FJL PMAB255>
|
||
; Clear the low memory bits whenever we draw the menu bar.
|
||
|
||
Move.W TheMenu, -(SP) ; save off currently hilited menu <FJL PMAB255>
|
||
Clr.W -(SP) ; call HiliteMenu(0)
|
||
_HiliteMenu
|
||
|
||
BSET #7,AlarmState ; reset alarm parity <EHB 1/24/85>
|
||
|
||
MOVEQ #0,D0 ; set up for the draw message <DAF 20Aug86>
|
||
MOVE.L #0,D1 ; parameter is non-neg to draw bar text <DAF 20Aug86>
|
||
IMPORT CallMBarProc
|
||
BSR CallMBarProc ; execute the defproc <DAF 20Aug86>
|
||
|
||
_HiliteMenu ; TheMenu is already on the stack. <FJL PMAB255>
|
||
;jsr PopMenuState ; Restore the menu state if it was saved <PN> <SM5>
|
||
|
||
RTS
|
||
ENDPROC
|
||
|
||
FlashMenuBar PROC EXPORT
|
||
;------------------------------------------------------------------------------------
|
||
;
|
||
; FlashMenuBar
|
||
;
|
||
;------------------------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE FlashMenuBar(menuID: INTEGER);
|
||
;
|
||
; FlashMenuBar inverts the title of a given menu item. If the menuID is 0,
|
||
; it inverts the whole menu bar.
|
||
;
|
||
; No longer is it possible to have more than one menu hilited at once due to saving <FJL 28Jan87>
|
||
; the bits behind the menu title. This routine has been changed so that when
|
||
; menuID <> 0 if TheMenu=MenuID then it clears that menu, else it just uses the HilitMenu code.
|
||
;
|
||
tst 4(SP) ; test menuID
|
||
beq.s @FlashWholeBar ; menuID == 0 ==> flip bar
|
||
move theMenu, d0 ; get currently hilited menu
|
||
beq.s @DoHiliteMenu ; if no menu hilited, then use HiliteMenu code
|
||
cmp 4(SP), d0 ; flashing currently hilited menu ?
|
||
bne.s @DoHiliteMenu ; no ==> so use HiliteMenu code
|
||
|
||
; yes ==> so turn this title off
|
||
move 4(SP), d1 ; get menuID of new selection <FJL C826>
|
||
IMPORT GetIndex
|
||
bsr GetIndex ; convert ID to offset in menuList <FJL C826>
|
||
beq.s @FlashExit ; couldn’t find in list, so exit <FJL C826>
|
||
IMPORT TurnIndexOff
|
||
bsr TurnIndexOff ; MenuList offset is in D0 <FJL C826>
|
||
clr theMenu ; clear low-mem theMenu to show no menu hilited
|
||
IMPORT TwoBytExit
|
||
bra TwoBytExit
|
||
|
||
@DoHiliteMenu
|
||
IMPORT HiliteMenu
|
||
bra HiliteMenu ; menuID <> 0 ==> use HiliteMenu code
|
||
@FlashWholeBar ; call mbarproc to invert menu.
|
||
MOVEQ #0,D0 ; menuIndex = 0 ==> flip bar
|
||
IMPORT TurnIndexOn
|
||
BSR TurnIndexOn ; call mbarproc
|
||
@FlashExit BRA TwoBytExit ; save code by returning thru common label
|
||
ENDPROC
|
||
|
||
TurnIndexOff PROC ENTRY
|
||
;--------------------------------------------------------------------------------------------
|
||
; TurnIndexOff and TurnIndexOn take a menuIndex in D0 and set it’s hilite state
|
||
; to the appropriate level. These calls replace InvertTitle.
|
||
;
|
||
; On Entry: D0 Offset into MenuList of menu to be hilited/unhilited
|
||
;
|
||
MOVEQ #0,D1 ; set hi word to 0 for normal text <DAF 20Aug86>
|
||
BRA TurnIndexCom ;
|
||
|
||
ENTRY TurnIndexOn
|
||
TurnIndexOn
|
||
MOVEQ #1,D1 ; set hi word to one for selected text <DAF 20Aug86>
|
||
|
||
TurnIndexCom
|
||
SWAP D1 ;
|
||
MOVE.W D0,D1 ; set lo word to new selection <DAF 20Aug86>
|
||
MOVEQ #5,D0 ; set up the hilite message <DAF 20Aug86>
|
||
; fall thru to execute the defproc <DAF 20Aug86>
|
||
; returns to caller directly
|
||
IMPORT CallMBarProc
|
||
BRA CallMBarProc
|
||
ENDPROC
|
||
|
||
HILITEMENU PROC EXPORT
|
||
;
|
||
; PROCEDURE HiliteMenu(menuID: INTEGER); -- hilite the title of the menu with the
|
||
; specified menuID. Since only one menu can be hilited at a time, unhilite any other one
|
||
;
|
||
; if MBarHeight <= 3 then don’t hilite. Otherwise MBarProc will save off a VERY LARGE
|
||
; handle for the bits behind the menu title.
|
||
|
||
Cmpi.W #3, MBarHeight ; is height > 3 <PMAB233 FJL>
|
||
Bgt.S @HeightOK ; yes -> ok
|
||
Bra.S HLNone ; no -> nope, skip entirely
|
||
|
||
; first, turn off the current hilited title if present
|
||
|
||
@HeightOK MOVE.W theMenu,D1 ; get the currently hilited menu
|
||
BEQ.S HLOn ; if theMenu is 0, then don’t unhilite <DAF 20Aug86>
|
||
CMP.W 4(SP),D1 ; is this the currently hilited menu <DAF 20Aug86>
|
||
BEQ.S HLDone ; already hilited, so skip <DAF 20Aug86>
|
||
|
||
IMPORT GetIndex
|
||
BSR GetIndex ; convert to menuIndex
|
||
beq.s HLOn ; if zero, invalid menuID <FJL A466>
|
||
MOVEQ #0,D1 ; clear hi half for normal text
|
||
MOVE.W D0,D1 ; move to D1
|
||
|
||
MOVEQ #5,D0 ; set up the hilite message <DAF 20Aug86>
|
||
IMPORT CallMBarProc
|
||
BSR CallMBarProc ; execute the defproc <DAF 20Aug86>
|
||
|
||
; now, turn on the selected menu
|
||
|
||
HLOn
|
||
MOVE.W 4(SP),D1 ; get menuID of new selection <DAF 20Aug86>
|
||
BSR GetIndex ; convert to menuIndex
|
||
BEQ.S HLNone ; if zero, invalid menuID <FJL C175>
|
||
SWAP D0 ; save menuIndex in hi half
|
||
MOVE.W #1,D0 ; set hi word to one for selected text <DAF 20Aug86>
|
||
SWAP D0 ; flip half back to correct positions
|
||
MOVE.L D0,D1 ; copy to D1 for CallMBarProc
|
||
MOVEQ #5,D0 ; set up the hilite message <DAF 20Aug86>
|
||
BSR CallMBarProc ; execute the defproc <DAF 20Aug86>
|
||
HLDone
|
||
MOVE.L (SP)+,A0
|
||
MOVE.W (SP)+,theMenu ; update theMenu <FJL C175>
|
||
JMP (A0)
|
||
HLNone ; get the return address <FJL C175>
|
||
move.l (sp)+,a0
|
||
addq.l #2, SP ; throw away the parameter <FJL C175>
|
||
clr.w theMenu ; update theMenu <FJL C175>
|
||
Done
|
||
JMP (A0)
|
||
ENDPROC
|
||
|
||
ENABLEITEM PROC EXPORT
|
||
; PROCEDURE EnableItem(menuHandle,item) -- enable an item in a menu or, if the item
|
||
; number is zero, enable the entire menu. It has no effect if the item is already
|
||
; enabled.
|
||
;
|
||
IMPORT EnableFetch
|
||
BSR ENABLEFETCH ;set up registers with shared code
|
||
|
||
cmp #31, d0 ; is the item > 31 ? <FJL C466>
|
||
bhi.s EnableDone ; yes, so leave without updating flags <FJL C466>
|
||
|
||
BSET D0,D1 ;enable the item
|
||
|
||
ENTRY EnableCom
|
||
ENABLECOM
|
||
|
||
MOVE.L D1,MENUENABLE(A0) ; update the menu’s flags
|
||
|
||
ENTRY EnableDone
|
||
EnableDone
|
||
IMPORT SixBytExit
|
||
BRA SIXBYTEXIT ; common exit saves code
|
||
ENDPROC
|
||
|
||
ENABLEFETCH PROC ENTRY
|
||
MOVE.L 10(SP),A0 ; get the menu handle
|
||
MOVE.L (A0),A0 ; handle to pointer
|
||
MOVE 8(SP),D0 ; get bit index
|
||
MOVE.L MENUENABLE(A0),D1 ; pick up current state of flags
|
||
RTS
|
||
ENDPROC
|
||
|
||
DISABLEITEM PROC EXPORT
|
||
;
|
||
; PROCEDURE DisableItem(menuHandle, item) -- disable an item in a menu, or if the item
|
||
; is zero, disable the entire menu. Shares code with EnableItem to stay small
|
||
;
|
||
IMPORT EnableFetch
|
||
BSR ENABLEFETCH ;set up registers
|
||
|
||
cmp #31, d0 ; is the item > 31 ? <FJL C466>
|
||
bls.s @ok
|
||
IMPORT EnableDone
|
||
jmp EnableDone ; yes, so leave without updating flags <FJL C466>
|
||
@ok
|
||
BCLR D0,D1 ;disable the item
|
||
IMPORT EnableCom
|
||
BRA ENABLECOM ;go update flags and return
|
||
ENDPROC
|
||
|
||
GETMENUPTR PROC ENTRY
|
||
;-------------------------------------------------------------------------------------------
|
||
; GetMenuPtr is a utility routine that given an index into the current menuList in D5,
|
||
; returns a pointer to the menu in A0. It returns a handle to the same menu in A1.
|
||
;
|
||
BSR.S GetA0List ; get menuList pointer into A0 <EHB 11-Apr-85>
|
||
MOVE.L MENUOH(A0,D5),A1 ; get menu handle
|
||
GMPContinue TST.L (A1) ; has menu been purged? <EHB 11-Apr-85>
|
||
BEQ.S ListPurged ; => yes, go to purgeatory <EHB 11-Apr-85>
|
||
MOVE.L (A1),A0 ; handle -> pointer
|
||
RTS
|
||
|
||
ENTRY GetA0List
|
||
GetA0List
|
||
;-------------------------------------------------------------------------------------------
|
||
; GetA0List is a routine to get the menuList pointer into A0. GetA1List is a routine to
|
||
; get the menuList pointer into A1. The reason for two routines is due to the complexity
|
||
; and risk of getting the dozen routines that get menuList pointer to agree with each other.
|
||
|
||
; These routines check to see if the menuList has been purged. If it has it generates
|
||
; a DS #54 (MenuPrgErr).
|
||
|
||
MOVE.L MenuList,A0 ; get the menuList handle <EHB 11-Apr-85>
|
||
TST.L (A0) ; has it been purged? <EHB 11-Apr-85>
|
||
BEQ.S ListPurged ; => yes, go to purgeatory <EHB 11-Apr-85>
|
||
MOVE.L (A0),A0 ; else get the pointer <EHB 11-Apr-85>
|
||
RTS ; and return <EHB 11-Apr-85>
|
||
|
||
ENTRY GetA1List
|
||
GetA1List
|
||
MOVE.L MenuList,A1 ; get the menuList handle <EHB 11-Apr-85>
|
||
TST.L (A1) ; has it been purged? <EHB 11-Apr-85>
|
||
BEQ.S ListPurged ; => yes, go to purgeatory <EHB 11-Apr-85>
|
||
MOVE.L (A1),A1 ; else get the pointer <EHB 11-Apr-85>
|
||
RTS ; and go to heaven
|
||
|
||
ListPurged
|
||
MOVEQ #MenuPrgErr,D0 ; get our error code <EHB 11-Apr-85>
|
||
_SysError ; and roast in eternal damnation <EHB 11-Apr-85>
|
||
|
||
ENTRY GetHA0List
|
||
GetHA0List
|
||
;-------------------------------------------------------------------------------------------
|
||
; GetHA0List is a routine to get the HMenuList pointer into A0. GetHA1List is a routine to
|
||
; get the HMenuList pointer into A1. The reason for two routines is due to the complexity
|
||
; and risk of getting the dozen routines that get HMenuList pointer to agree with each other.
|
||
; These routines check to see if the menuList has been purged. If it has it generates
|
||
; a DS #54 (MenuPrgErr).
|
||
; <FJL C222>
|
||
bsr.s GetA0List ; get the menuList ptr in a0
|
||
adda.w lastMenu(a0), a0 ; a0 now points at last regular menu
|
||
addq #6, a0 ; a0 now points at HMenuList header info
|
||
rts
|
||
|
||
ENTRY GetHA1List
|
||
GetHA1List
|
||
bsr.s GetA1List ; get the menuList ptr in a1 <FJL C222>
|
||
adda.w lastMenu(a1), a1 ; a1 now points at last regular menu
|
||
addq #6, a1 ; a1 now points at HMenuList header info
|
||
rts
|
||
|
||
ENDPROC
|
||
|
||
;-----------------------------------------------
|
||
; Stack Frame Definitions for MenuSelect and PopUpMenuSelect
|
||
;-----------------------------------------------
|
||
|
||
STARTPT EQU 8 ; 1st parameter is 8, and is 4 bytes long
|
||
FUNCRESULT EQU 12 ; longword function result (menu,item)
|
||
ITEMRESULT EQU 14 ; item portion of funcResult
|
||
|
||
MENURECT EQU -8 ; rectangle (8 bytes) <C60/30JUN86>
|
||
MSavePort EQU MENURECT-4 ; saved grafPort <C60/30JUN86>
|
||
|
||
msLastMenu EQU MSavePort-2 ; how many menus are on the screen <FJL C222>
|
||
DelayTicks EQU msLastMenu - 4 ; how long mouse in HItem <FJL C222>
|
||
DragTicks EQU DelayTicks - 4 ; how long mouse moving towards HMenu <FJL C222>
|
||
menuDelaySave EQU DragTicks - 1 ; store menuDelay from param ram <FJL C222>
|
||
menuDragSave EQU menuDelaySave - 1 ; store menuDrag from param ram <FJL C222>
|
||
lastFuncResult EQU menuDragSave - 2 ; funcResult last time thru MSLoop <FJL C222>
|
||
lastItemResult EQU lastFuncResult - 2 ; itemResult last time thru MSLoop <FJL C222>
|
||
firstMenuID EQU lastItemResult - 2 ; ID of REGULAR menu up <FJL C222>
|
||
NewHMenuOffset EQU firstMenuID - 2 ; offset into MenuList of new HMenu <FJL C222>
|
||
SelectFrame EQU NewHMenuOffset-8 ; number of bytes to save <FJL C222>
|
||
|
||
msHMenuStorage EQU 4 ; 4 bytes per menu needed for temp storage <FJL C222>
|
||
|
||
MENUSELECT PROC EXPORT
|
||
;------------------------------------------------------------------------------------------------
|
||
;
|
||
; MenuSelect -- main loop that tracks mouse in title bar and thru hierarchical menus
|
||
;
|
||
;------------------------------------------------------------------------------------------------
|
||
;
|
||
; FUNCTION MenuSelect(mousePt:Point): LongInt -- MenuSelect is the most important
|
||
; routine in the menu manager. It is called when the application receives a
|
||
; mouse button down event on the menuBar and retains control until the mouse button
|
||
; goes up. It returns a long integer contain 2 16 bit values. The high word
|
||
; is called "whichMenu" and holds the menuId of the menu that was chosen; if its
|
||
; zero, no menu was chosen. The low word is called "whichItem" and contains the item
|
||
; number of the selected item. If no choice was selected, the longWord result is zero
|
||
|
||
LINK A6,#SelectFrame ;set up a stack frame
|
||
MOVEM.L D2-D7/A2-a4,-(SP) ;save work registers
|
||
|
||
CLR.W -(SP) ;push zero for this
|
||
_HiliteMenu ;make sure no menu is hilited
|
||
CLR.L FUNCRESULT(A6) ;assume nothing will be selected
|
||
clr.l MenuDisable ; clear the low-memory location MenuDisable
|
||
|
||
; <1.9 KSM> Removed this check to allow double-click processing to work properly
|
||
; Double-click is one possibility for tearing off menus. (Kevin, I think that this
|
||
; WaitMouseUp should still be here. You should find another way to keep the guy here
|
||
; in MenuSelect for the double-click case.) <dba>
|
||
|
||
CLR.W -(SP) ;push zero for this
|
||
_WaitMouseUp ;is the mouse still down?
|
||
TST.B (SP)+ ;examine result
|
||
BEQ DONEMSELECT ;if not still down, don’t bother
|
||
|
||
; need to set the port here else ClipRects do not work
|
||
|
||
PEA MSavePort(A6)
|
||
_GetPort
|
||
|
||
move.l wMgrPort, a2 ; get port
|
||
|
||
move.l a2, -(SP) ; set the port
|
||
_SetPort
|
||
;
|
||
; during the main loop of menuSelect, D3 holds the mouse point, D4 holds the old
|
||
; menuIndex into the menuList and D5 holds the current menuIndex. A4 holds handle to
|
||
; HMenu ID storage (of menus currently up).
|
||
;
|
||
; First initialize these variables
|
||
;
|
||
CLR D5 ; current menuIndex is empty
|
||
CLR D4 ; oldMenuIndex is empty
|
||
clr msLastMenu(a6) ; clear msLastMenu index <FJL C222>
|
||
IMPORT SetTickCounters
|
||
bsr SetTickCounters ; set DelayTicks and DragTicks
|
||
clr.l lastItemResult(a6) ; clear both lastFuncResult and lastItemResult
|
||
clr firstMenuID(a6) ; no menu selected at start
|
||
|
||
move.l mbSaveLoc, a0 ; store MenuDrag and MenuDelay in stackframe
|
||
move.l (a0), a0
|
||
move.b mbMenuDelay(a0), menuDelaySave(a6)
|
||
move.b mbMenuDrag(a0), menuDragSave(a6)
|
||
|
||
MOVE.L STARTPT(A6),D3 ; start off with initial mouse point
|
||
|
||
move.l #5*msHMenuStorage, d0 ; alloc space for 5 menuIndices [words] <FJL C222>
|
||
; and 5 items [words] <FJL C222>
|
||
_NewHandle
|
||
move.l a0, a4 ; store it in a4 for the duration of MenuSelect
|
||
; NOTE: a4 is used as an implicit parameter
|
||
; to MenuSelect subroutines
|
||
|
||
;------------------------------------------------
|
||
; Menu Select Loop
|
||
;------------------------------------------------
|
||
; Call the mBar defProc’s hit routine to see where the mouse is.
|
||
; Major revisions for hierarchical menus. <FJL C222>
|
||
|
||
MSLoop
|
||
MOVEQ #1,D0 ; hit message is #1
|
||
MOVE.L D3,D1 ; send point in parameter
|
||
IMPORT CallMBarProc
|
||
BSR CallMBarProc ; execute the defproc <DAF 20Aug86>
|
||
|
||
TST.L D0 ; where is the hit?
|
||
BMI.s SameMenu ; branch if its not in a title or any menu
|
||
beq.s InTitleNoMenu ; branch if its IN the menubar but NOT IN a title
|
||
|
||
MOVE.w D0,D5 ; move result to D5
|
||
BSR GetMenuPtr ; get the menuData handle
|
||
move menuID(a0),funcResult(a6) ;return which Menu the mouse is currently in
|
||
bra.s ChgMenu
|
||
;
|
||
; if in menu bar but not in a title, want to bring down all menus
|
||
; no menus and no funcResult
|
||
;
|
||
InTitleNoMenu clr d5 ; no menu
|
||
clr funcResult(a6) ; no menu, so no result either
|
||
|
||
; At this point, D5 contains the menuIndex of the menu that the mouse points at,
|
||
; or a zero if no menu is pointed at. Check to see if this menu is different than
|
||
; the previous one pointed at
|
||
|
||
ChgMenu cmp d5, d4 ; menuIndex = oldMenuIndex ?
|
||
beq.s SameMenu ; if the same, nothing to pull down
|
||
IMPORT MenuChanged
|
||
bsr MenuChanged ; change variables that affect current menu
|
||
bmi DoneMS ; n-flag set means that MBarHook aborted MenuSelect
|
||
|
||
|
||
SameMenu tst d5 ; examine menu index
|
||
beq.s NextMouse ; don’t choose an item unless there’s one down
|
||
IMPORT ResetRectScrollData
|
||
bsr ResetRectScrollData ; before choosing item be sure menuRect(a6) is
|
||
; correct as are scrolling globals
|
||
IMPORT ChooseItem
|
||
bsr ChooseItem ; choose item by calling mdefproc
|
||
IMPORT CheckHItem
|
||
bsr CheckHItem ; check for hierarchical stuff
|
||
|
||
; I put GetMouse after WaitMouseUp. This ensures that FlashTheMenu is called with the <EHB 9-Apr-85>
|
||
; same mouse position that was processed above.
|
||
|
||
NextMouse ; I Put GetMouse after WaitMouseUp <EHB 9-Apr-85>
|
||
|
||
MUpEntryPt
|
||
CLR.W -(SP) ;make room for stillDown result
|
||
_WaitMouseUp ;is the button still down?
|
||
TST.B (SP)+ ;test _WaitMouseUp result
|
||
BEQ.S @MouseUp ; => if up, flash user (oh Mr. Mac!)
|
||
|
||
; mouse still down, so get the mouse position and store in D3
|
||
|
||
SUBQ #4,SP ;allocate place to get mouse
|
||
MOVE.L SP,-(SP) ;use temp buffer for mouse point
|
||
_GetMouse ;get mouse in wmgr coordinates
|
||
MOVE.L (SP)+,D3 ;keep mouse point in D3
|
||
|
||
|
||
; The mouse button is still down. We’ve read the mouse position already,
|
||
; so call the user hook (if its installed) and loop.
|
||
|
||
MOVE.L MENUHOOK,D0
|
||
BEQ.S @NoMenuHook
|
||
MOVE.L D0,A0
|
||
JSR (A0)
|
||
@NoMenuHook
|
||
BRA.s MSLOOP ; => continue tracking mouse
|
||
|
||
;------------------------------------------------
|
||
; End of Menu Select Loop
|
||
;------------------------------------------------
|
||
|
||
@MouseUp
|
||
; the mouse button went up. Give feedback to the user if she made a choice
|
||
|
||
TST D5 ;was one selected?
|
||
BEQ.S NOFLASH ;if not, dont bother
|
||
;
|
||
; If the item has a hierarchical menu attached DO NOT return the menu or item
|
||
;
|
||
bsr GetMenuPtr ; get ptr to chosen menu in a0 (which we want for
|
||
; GetItemRecord call)
|
||
move itemResult(a6), d0
|
||
IMPORT GetItemRecord
|
||
bsr GetItemRecord ; on return a1 points to items property bytes
|
||
beq.s @FlashIt ; if z-flag set then item not found <PMAB568 07Sep88 EMT>
|
||
cmpi.b #HMenuCmd, itemCmd(a1) ; does this item have a hierarchical menu?
|
||
bne.s @FlashIt ; no, so branch and flash
|
||
clr itemResult(a6) ; yes, so clear the item
|
||
bra.s @JustRestore ; and skip the flashing
|
||
|
||
@FlashIt
|
||
IMPORT FlashFeedback
|
||
BSR FLASHFEEDBACK ;flash the choice for feedback
|
||
@JustRestore
|
||
IMPORT RestoreAllBits
|
||
BSR RestoreAllBits ;restore bits under all menus <FJL C222>
|
||
|
||
; if no item selected, then no menu either
|
||
;
|
||
NOFLASH TST ITEMRESULT(A6) ; was an item selected?
|
||
BNE.S @SetTheMenu ; if so, we’re cool
|
||
CLR.W FUNCRESULT(A6) ; otherwise, no menu was either
|
||
|
||
MOVE firstMenuID(a6),D0 ; better make sure no menu hilited in menu bar
|
||
BEQ.S @SetTheMenu ; if it’s zero, then we can skip unhiliting it
|
||
move d5, d0 ; set up for TurnIndexOff
|
||
;*** WRONG WRONG WRONG; the only reason this works is that the MBDF ignores the index
|
||
;*** this value is always wrong once a hierarchical menu has been tracked
|
||
IMPORT TurnIndexOff
|
||
BSR TurnIndexOff ; otherwise turn it off
|
||
clr firstMenuID(a6) ; and remember that no menu hilited in title bar
|
||
|
||
@SetTheMenu MOVE firstMenuID(a6),TheMenu ;remember menuID of hilited menu
|
||
|
||
;+++ tst funcResult(a6) ; is it a system menu?
|
||
; Can’t just use funcResult(a6) since could<FJL 09Mar87>
|
||
; be a HMenu associated with the desk acc<FJL 09Mar87>
|
||
tst TheMenu ; Is it a system menu? <FJL 09Mar87>
|
||
BMI.s DoSysMenu ; if < 0 then handle it
|
||
|
||
TST.W MBarEnable ;does deskOrn own the menuBar?
|
||
BMI.s DoSysMenu ;if so, go tell it about it
|
||
|
||
ENTRY DoneMS
|
||
DONEMS move.l a4, a0 ; set up for DisposHandle
|
||
_DisposHandle ; and toss temp storage
|
||
|
||
MOVE.L MSavePort(A6),-(SP) ;get old port
|
||
_SetPort ;restore callers grafPort
|
||
|
||
ENTRY DoneMSelect
|
||
DONEMSELECT
|
||
|
||
MOVEM.L (SP)+,D2-D7/A2-a4 ;restore registers
|
||
UNLK A6 ;dismantle stack frame
|
||
MOVE.L (SP)+,(SP) ;strip sole parameter
|
||
clr.l d1 ; clear D1 because some stupid app <FJL A278>
|
||
; assumes it is zero <FJL A278>
|
||
|
||
; the next 3 lines are a little kludge. Infrequently lastMBSave is non-zero when exiting
|
||
; MenuSelect, though it should always be zero. Just to be safe force it to be zero.
|
||
move.l mbSaveLoc, a0 ; get mbSaveLoc
|
||
move.l (a0), a0 ; dereference
|
||
clr lastMBSave(a0) ; force no menus down
|
||
|
||
RTS ;return to caller
|
||
|
||
;-----------------------------------------------
|
||
; Utility -- DoSysMenu
|
||
;-----------------------------------------------
|
||
;
|
||
; handle system menus
|
||
;
|
||
; HMenus cause problems here. Since the menu ID (funcResult) is not = to the DA’s <FJL 09Mar87>
|
||
; menu ID, SystemMenu will never find the DA in the DA list. To force it to pass
|
||
; the HMenu ID we can set MBarEnable temporarily.
|
||
;
|
||
; Need to allow a DA that owns the menu bar to reset MBarEnable in the middle of _SystemMenu <FJL PMAB280>
|
||
; Had to move around some parts of this routine. Only set/clear MBarEnable when MBar not
|
||
; already owned by DA.
|
||
;
|
||
DoSysMenu
|
||
tst.w MBarEnable ; who owns menu bar?
|
||
bmi.s @1 ; desk acc ==> we’re cool
|
||
|
||
move TheMenu, MBarEnable ; set MBarEnable with DA’s ID
|
||
move.l FuncResult(a6),-(SP) ; push the result
|
||
_SystemMenu ; invoke desk manager
|
||
clr.l FuncResult(a6) ; pretend we didn’t get anything
|
||
; NOTE: clears funcResult AND itemResult !!!
|
||
clr.w MBarEnable ; clear MBarEnable
|
||
bra.s @Done
|
||
|
||
@1 move.l FuncResult(a6),-(SP) ; push the result
|
||
_SystemMenu ; invoke desk manager
|
||
clr.l FuncResult(a6) ; pretend we didn’t get anything
|
||
; NOTE: clears funcResult AND itemResult !!!
|
||
@Done BRA.S DoneMS ;let common code finish up
|
||
|
||
;------------------------------------------------------------------------------------------------
|
||
; End of MenuSelect
|
||
;------------------------------------------------------------------------------------------------
|
||
ENDPROC
|
||
|
||
; PopUpMenuSelect Equates:
|
||
|
||
PopUpMenuH EQU StartPt ; menu handle parameter, same offset as StartPt
|
||
; after the stack is fixed
|
||
PopUpItem EQU SelectFrame - 2 ; PopUpItem parameter
|
||
msTopEdge EQU PopUpItem - 2 ; Top parameter
|
||
msLeftEdge EQU msTopEdge - 2 ; Left parameter
|
||
msTopLeft EQU msLeftEdge ; Top left point of menu
|
||
PopUpSelectFrame EQU msLeftEdge
|
||
|
||
PopUpMenuSelect PROC EXPORT ;;<FJL C844>
|
||
;------------------------------------------------------------------------------------------------
|
||
;
|
||
; PopUpMenuSelect -- brings up a menu in a user-specified location, then
|
||
; tracks mouse in the menu and thru any hierarchical menus
|
||
;
|
||
;------------------------------------------------------------------------------------------------
|
||
;
|
||
; FUNCTION PopUpMenuSelect(theMenu: menuHandle; top, left, PopUpItem: integer): LongInt
|
||
;
|
||
; PopUpMenuSelect is called when an application receives a mouse down in a pop-up menu area.
|
||
; A pop-up menu area is typically a box with a shadow. It first brings up the menu with
|
||
; the left edge given by the parameter Left, and the top of PopUpItem at Top. It tracks the
|
||
; mouse just like MenuSelect, allowing five levels of hierarchical menus. It ignores
|
||
; mouse movement into the menubar by changing the low-memory location MBHeight to zero before
|
||
; it starts (it does so so that it can call the mbarproc with a HitMessage, and have the
|
||
; mbarproc ignore the menubar area). It returns a LongInt that has the same meaning as
|
||
; MenuSelect.
|
||
|
||
; Begin by removing parameters so that we are left with the same parameter setup as MenuSelect.
|
||
; This allows us to use all of the subroutines from MenuSelect.
|
||
|
||
move 4(SP), d0 ; save PopUpItem
|
||
move.l 6(SP), d1 ; save left, top
|
||
move.l (SP), 6(SP) ; move RTS, leave 4 bytes of parameter on the stack
|
||
addq #6, SP ; and update stack ptr
|
||
|
||
link a6,#PopUpSelectFrame ; set up a stack frame
|
||
movem.l d2-d7/a2-a4,-(SP) ; save work registers
|
||
move d0, PopUpItem(a6) ; store parameters in stackframe
|
||
move.l d1, msTopLeft(a6) ; store Left and Top in one instruction
|
||
|
||
clr.l funcResult(A6) ; assume nothing will be selected
|
||
clr.l MenuDisable ; clear the low-memory location MenuDisable
|
||
|
||
subq #2, SP ; leave room for result
|
||
_WaitMouseUp ; is the mouse still down?
|
||
tst.b (SP)+ ; examine result
|
||
beq @EndPopUpMS ; if not StillDown, don’t bother
|
||
|
||
; need to set the port here else ClipRects do not work
|
||
|
||
PEA MSavePort(A6)
|
||
_GetPort
|
||
|
||
move.l wMgrPort, a2 ; get port
|
||
|
||
move.l a2, -(SP) ; set the port
|
||
_SetPort
|
||
;
|
||
; during the main loop of PopUpMenuSelect, D3 holds the mouse point, D4 holds the old
|
||
; menuIndex into the menuList and D5 holds the current menuIndex. A4 holds handle to
|
||
; HMenu ID storage (of menus currently up).
|
||
;
|
||
; First initialize these variables
|
||
;
|
||
clr d5 ; current menuIndex is empty
|
||
clr d4 ; oldMenuIndex is empty
|
||
clr msLastMenu(a6) ; clear msLastMenu index
|
||
IMPORT SetTickCounters
|
||
bsr SetTickCounters ; set DelayTicks and DragTicks
|
||
clr.l lastItemResult(a6) ; clear both lastFuncResult and lastItemResult
|
||
|
||
move.l mbSaveLoc, a0 ; store MenuDrag and MenuDelay in stackframe
|
||
move.l (a0), a0
|
||
move.b mbMenuDelay(a0), menuDelaySave(a6)
|
||
move.b mbMenuDrag(a0), menuDragSave(a6)
|
||
|
||
move.l #5*msHMenuStorage, d0 ; alloc space for 5 menuIndices [words]
|
||
; and 5 items [words]
|
||
_NewHandle
|
||
move.l a0, a4 ; store it in a4 for the duration of MenuSelect
|
||
; NOTE: a4 is used as an implicit parameter
|
||
; to PopUpMenuSelect subroutines
|
||
|
||
;------------------------------------------------
|
||
; PopUpMenuSelect Loop
|
||
;------------------------------------------------
|
||
; First bring up the pop-up menu, then track it.
|
||
|
||
move.l PopUpMenuH(a6), a0 ; get menuID
|
||
move.l (a0), a0 ; dereference menuHandle
|
||
move menuID(a0), d1 ; store the menuID in D1 for GetHIndex call
|
||
IMPORT GetHIndex
|
||
bsr GetHIndex ; convert ID to index
|
||
move d0, d4 ; save index in D4 <PMAB364 23Jan88 EMT>
|
||
beq @EndPopUpMS ; zero index ==> couldn’t find it (shouldn’t happen)
|
||
|
||
move d4, d5 ; copy saved index to D5 <PMAB364 23Jan88 EMT>
|
||
|
||
IMPORT DrawFirstMenu
|
||
bsr DrawFirstMenu ; use special routine to place first menu
|
||
|
||
move MBarHeight, -(SP) ; save MBarHeight on the stack
|
||
clr MBarHeight ; clear MBarHeight so Hit Message to mbarproc
|
||
; ignores menu bar.
|
||
@PopUpMSLoop
|
||
moveq #1, d0 ; hit message is #1
|
||
move.l d3, d1 ; send point in parameter
|
||
IMPORT CallMBarProc
|
||
bsr CallMBarProc ; execute the defproc
|
||
|
||
tst.l d0 ; where is the hit?
|
||
bmi.s @SameMenu ; branch if its not in a title or any menu
|
||
|
||
; else it’s in a menu
|
||
move d0, d5 ; move result to D5
|
||
bsr GetMenuPtr ; get the menuData handle
|
||
move menuID(a0),funcResult(a6) ;return which Menu the mouse is currently in
|
||
|
||
; At this point, D5 contains the menuIndex of the menu that the mouse points at,
|
||
; or a zero if no menu is pointed at. Check to see if this menu is different than
|
||
; the previous one pointed at
|
||
|
||
cmp d5, d4 ; menuIndex = oldMenuIndex ?
|
||
beq.s @SameMenu ; if the same, nothing to pull down
|
||
IMPORT MenuChanged
|
||
bsr MenuChanged ; change variables that affect current menu
|
||
bmi.s @DonePopUpMS ; n-flag set means that MBarHook aborted MenuSelect
|
||
|
||
|
||
@SameMenu tst d5 ; examine menu index
|
||
beq.s @NextMouse ; don’t choose an item unless there’s one down
|
||
IMPORT ResetRectScrollData
|
||
bsr ResetRectScrollData ; before choosing item be sure menuRect(a6) is
|
||
; correct as are scrolling globals
|
||
IMPORT ChooseItem
|
||
bsr ChooseItem ; choose item by calling mdefproc
|
||
IMPORT CheckHItem
|
||
bsr CheckHItem ; check for hierarchical stuff
|
||
|
||
@NextMouse clr -(SP) ; make room for stillDown result
|
||
_WaitMouseUp ; is the button still down?
|
||
tst.b (SP)+ ; test _WaitMouseUp result
|
||
beq.s @MouseUp ; => if up, flash user (oh Mr. Mac!)
|
||
|
||
; mouse still down, so get the mouse position and store in D3
|
||
|
||
subq #4,SP ; allocate place to get mouse
|
||
move.l SP,-(SP) ; use temp buffer for mouse point
|
||
_GetMouse ; get mouse in wmgr coordinates
|
||
move.l (SP)+,d3 ; keep mouse point in D3
|
||
|
||
|
||
; The mouse button is still down. We’ve read the mouse position already,
|
||
; so call the user hook (if its installed) and loop.
|
||
|
||
move.l MenuHook, d0
|
||
beq.s @NoMenuHook
|
||
move.l d0, a0
|
||
jsr (a0)
|
||
@NoMenuHook
|
||
bra.s @PopUpMSLoop ; => continue tracking mouse
|
||
|
||
;------------------------------------------------
|
||
; End of PopUpMenuSelect Loop
|
||
;------------------------------------------------
|
||
|
||
@MouseUp
|
||
; the mouse button went up. Give feedback to the user if she made a choice
|
||
|
||
tst d5 ;was one selected?
|
||
beq.s @NoFlash ;if not, dont bother
|
||
;
|
||
; If the item has a hierarchical menu attached DO NOT return the menu or item
|
||
;
|
||
bsr GetMenuPtr ; get ptr to chosen menu in a0 (which we want for
|
||
; GetItemRecord call)
|
||
move ItemResult(a6), d0
|
||
IMPORT GetItemRecord
|
||
bsr GetItemRecord ; on return a1 points to item’s property bytes
|
||
beq.s @FlashIt ; if z-flag set then item not found <PMAB568 07Sep88 EMT>
|
||
cmpi.b #HMenuCmd, itemCmd(a1) ; does this item have a hierarchical menu?
|
||
bne.s @FlashIt ; no ==> branch and flash
|
||
clr ItemResult(a6) ; yes ==> so clear the item
|
||
bra.s @JustRestore ; and skip the flashing
|
||
|
||
@FlashIt
|
||
IMPORT FlashFeedback
|
||
bsr FlashFeedBack ; flash the choice for feedback
|
||
@JustRestore
|
||
IMPORT RestoreAllBits
|
||
bsr RestoreAllBits ; restore bits under all menus
|
||
|
||
; if no item selected, then no menu either
|
||
|
||
@NoFlash tst ItemResult(a6) ; any Item? (we could get here several ways,
|
||
; so do it this way)
|
||
bne.s @DonePopUpMS ; yes ==> then leave Func alone
|
||
clr funcResult(A6) ; no Item ==> so clear Func too
|
||
|
||
@DonePopUpMS move (SP)+, MBarHeight ; restore previous MBarHeight saved on the stack
|
||
|
||
IMPORT DoneMS
|
||
bra DoneMS ; use common code
|
||
|
||
@EndPopUpMS
|
||
IMPORT DoneMSelect
|
||
bra DoneMSelect ; use common end code
|
||
ENDPROC
|
||
|
||
DirtyHMenus PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility -- DirtyHMenus <PMAB364 23Jan88 EMT>
|
||
;-----------------------------------------------
|
||
;
|
||
; Mark the size of all hierchical menus as dirty. Used by PopUpMenuSelect.
|
||
;
|
||
IMPORT GetHA0List
|
||
BSR GetHA0List ; get HMenuList ptr in A0
|
||
MOVE.W lastHMenu(a0), d5 ; get #HMenus
|
||
; we know there are HMenus so check them backwards
|
||
MOVE.L MinusOne, d1 ; set up for GetHIndex
|
||
IMPORT GetHIndex
|
||
BSR GetHIndex ; d0 now has index to HMenuList header info
|
||
ADD.W d0, d5 ; d5 has index to last HMenu
|
||
MOVE.W d0, d6 ; d6 has index to HMenuList header
|
||
@MenuLoop
|
||
BSR GetMenuPtr ; get menu ptr in A0 from ID in D5
|
||
; PB403: use A1 (handle), not A0 (pointer)
|
||
MOVE.L A1,-(SP) ; push menu handle <PB403 24Feb88>
|
||
BSR.S DirtyMenuSize ; invalidate size
|
||
SUBQ.W #6, d5 ; bump to next menu
|
||
CMP.W d6, d5 ; at end of list?
|
||
BGT.S @MenuLoop ; no, so try the next menu
|
||
|
||
RTS
|
||
|
||
ENTRY DirtyMenuSize
|
||
DirtyMenuSize ; <EHB 5-Mar-85>
|
||
;-----------------------------------------------
|
||
; Utility -- DirtyMenuSize
|
||
;-----------------------------------------------
|
||
;
|
||
; Utility DirtyMenuSize(menuHandle) -- Say that the menu’s size is no longer valid by
|
||
; setting the width and height to -1.
|
||
MOVE.L 4(SP),A0 ; get menuHandle
|
||
MOVE.L (A0),A0 ; get menuPointer
|
||
MOVE.L #-1,MenuWidth(A0) ; clear size
|
||
|
||
MOVE.L (SP)+,(SP) ;strip parameter
|
||
RTS ;return to caller
|
||
ENDPROC
|
||
|
||
CALCMENUSIZE PROC EXPORT
|
||
; PROCEDURE CalcMenuSize(menuHandle) -- scan the menuData of a menu and set the menu’s
|
||
; width and heigth fields accordingly, by invoking the menu definition proc
|
||
SUBQ.L #4, SP ; <PMAB364 23Jan88 EMT>
|
||
MOVE.L SP, -(SP) ; <PMAB364 23Jan88 EMT>
|
||
_GetPort ; <PMAB364 23Jan88 EMT>
|
||
|
||
MOVE.L WMgrPort, A1 ; Get port <PMAB364 23Jan88 EMT>
|
||
|
||
MOVE.L A1, -(SP) ; Set the port <PMAB364 23Jan88 EMT>
|
||
_SetPort ; <PMAB364 23Jan88 EMT>
|
||
|
||
MOVE #2,-(SP) ; Tell mProc to calc size
|
||
MOVE.L 10(SP),A0 ; Get the menu handle <PMAB364 23Jan88 EMT>
|
||
MOVE.L A0,-(SP) ; Push it
|
||
CLR.L -(SP) ; Pass 12 bytes of bogus addresses/junk
|
||
CLR.L -(SP)
|
||
CLR.L -(SP)
|
||
MOVE.L (A0),A0 ; Get the menu ptr
|
||
IMPORT CallMDefProc
|
||
BSR CallMDefProc ; Call the menu definition proc <PMAB364 23Jan88 EMT>
|
||
|
||
_SetPort ; Restore the port (on stack) <PMAB364 23Jan88 EMT>
|
||
|
||
ENTRY StripIt
|
||
StripIt
|
||
MOVE.L (SP)+,(SP) ;strip parameter
|
||
RTS ;return to caller
|
||
ENDPROC
|
||
|
||
SetTickCounters PROC ENTRY
|
||
;------------------------------------------------
|
||
; Utility -- SetTickCounters <FJL C222>
|
||
;------------------------------------------------
|
||
; Set (Reset) stackframe tick counters DelayTicks
|
||
; and DragTicks. Get counts from parameter ram
|
||
; data that has been stored in stackframe.
|
||
;
|
||
subq #4, SP ; space for result
|
||
_TickCount ; get tick count
|
||
|
||
move.l (SP), DelayTicks(a6) ; set DelayTicks
|
||
clr.l d0
|
||
move.b menuDelaySave(a6), d0 ; get delta from param ram
|
||
add.l d0, DelayTicks(a6)
|
||
|
||
move.l (SP)+, DragTicks(a6) ; set DragTicks
|
||
move.b menuDragSave(a6), d0 ; get delta from param ram
|
||
add.l d0, DragTicks(a6)
|
||
rts
|
||
ENDPROC
|
||
|
||
ResetRectScrollData PROC ENTRY
|
||
;------------------------------------------------
|
||
; Utility -- ResetRectScrollData <FJL C222>
|
||
;------------------------------------------------
|
||
;
|
||
; The mouse is in a menu or title. If the last time thru MSLoop a HMenu was
|
||
; brought up, then menuRect(a6) will have the HMenu’s rect and not the rect
|
||
; the mouse is currently in, so ask the MBarProc to give us the rect the
|
||
; mouse is in. Next ask the mbarproc to restore the scrolling globals
|
||
; topMenuItem, atMenuBottom for the menu the mouse is in.
|
||
;
|
||
moveq #9, d0 ; rect message is #9
|
||
moveq #0, d1 ; clear hi-word of d1 since mbarproc WILL
|
||
; have this menu in its data structure already
|
||
move d5, d1 ; send 6 byte offset in parameter
|
||
IMPORT CallMBarProc
|
||
bsr CallMBarProc ; execute the defproc
|
||
|
||
move.l d0, a0 ; move ptr into a0
|
||
move.l Top(a0), menuRect(a6) ; move Top, Left
|
||
move.l Bottom(a0), menuRect+4(a6) ; move Bottom, Right
|
||
|
||
moveq #11, d0 ; reset scroll globals message is #11
|
||
move d5, d1 ; send 6 byte offset in parameter
|
||
bsr CallMBarProc ; execute the defproc
|
||
|
||
rts
|
||
ENDPROC
|
||
|
||
MenuChanged PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility -- MenuChanged
|
||
;-----------------------------------------------
|
||
; 1. If mouse moved into a new menu title then:
|
||
; A. restore all menus on the screen
|
||
; B. draw a new one
|
||
; C. reset stackframe data for the new menu.
|
||
; 2. If just move into a menu that is already down then:
|
||
; A. just reset stackframe data for the new menu
|
||
;
|
||
; On entry: d4 has index to last menu
|
||
; d5 has index to new menu
|
||
; On exit: d4 == d5 == index to new menu
|
||
;
|
||
|
||
; start by clearing stackframe variables
|
||
clr.w itemResult(A6) ; no item chosen... <FJL C175>
|
||
|
||
tst d4 ; was there one up already?
|
||
beq.s @SkipRestore ; if not, skip restoring
|
||
|
||
IMPORT GetA0List
|
||
bsr GetA0List ; get menuList ptr into a0
|
||
cmp lastMenu(a0), d5 ; is the new menu in regular menuList?
|
||
bgt.s @EndMenuChg ; no, its a HMenu that’s already down:
|
||
; so... 1) don’t restore any menus
|
||
; 2) don’t pull a new one down
|
||
; 3) don’t call MBarHook
|
||
;
|
||
; if we got to here ==> mouse in the title of a NEW 'regular' menu, so restore all
|
||
; of the menus that are currently showing on the screen
|
||
;
|
||
tst d5 ; a menu chosen ?
|
||
beq.s @1 ; no, so skip resetting data
|
||
IMPORT ResetRectScrollData
|
||
bsr ResetRectScrollData ; before choosing item be sure menuRect(a6) is
|
||
; correct as are scrolling globals
|
||
@1
|
||
IMPORT RestoreSomeBits
|
||
BSR RestoreSomeBits ; restore bits under menus <FJL C222>
|
||
IMPORT SetTickCounters
|
||
bsr SetTickCounters ; set tick counters for HMenus <FJL 26Jan87>
|
||
; did RestoreSomeBits leave exactly one menu up ?
|
||
cmpi #msHMenuStorage, msLastMenu(a6)
|
||
beq.s @EndMenuChg ; yes, so skip menu draw
|
||
|
||
MOVE D4,D0 ; get menuIndex for title invert
|
||
IMPORT TurnIndexOff
|
||
BSR TurnIndexOff ; unhilite old title
|
||
@SkipRestore
|
||
|
||
; if the new menuIndex is non-zero (i.e., one was chosen), pull down the menu.
|
||
|
||
move.w funcResult(a6), firstMenuID(a6) ; save ID of first menu down (for TheMenu)
|
||
|
||
tst d5 ;is there a new one chosen?
|
||
beq.s @EndMenuChg ;if not, go read the mouse again
|
||
|
||
MOVE D5,D0 ; get menu index
|
||
IMPORT TurnIndexOn
|
||
BSR TurnIndexOn ; hilite the menu bar
|
||
|
||
MOVE.L MBarHook,D0 ;<SM13> is MBarHook installed?
|
||
BEQ.S @DoTheDraw ;too bad, he’s not
|
||
|
||
;
|
||
; ask the mbarproc for the menu’s rectangle since MBarHook needs it. Remember that MBarHook
|
||
; is only called before regular menus go up, never HMenus.
|
||
;
|
||
moveq #9, d0 ; rect message is #9
|
||
moveq #0, d1 ; clear d1 since this menu is a regular menu,
|
||
; not a HMenu
|
||
move d5, d1 ; send 6 byte offset in parameter
|
||
IMPORT CallMBarProc
|
||
bsr CallMBarProc ; execute the defproc
|
||
move.l d0, a0 ; get address of rectangle in a0
|
||
move.l (a0), menuRect(a6) ; move top,left into stackframe
|
||
move.l 4(a0), menuRect+4(a6) ; move bottom, right into stackframe
|
||
|
||
|
||
MOVE.L MBarHook,A0 ;<SM13>get address in register
|
||
PEA MENURECT(A6) ;tell the hook where to draw
|
||
JSR (A0) ;call it
|
||
TST D0 ;did it get him?
|
||
; <FJL C222>
|
||
beq.s @DoTheDraw ; yes, and he says to continue with MenuSelect
|
||
move #-1, d5 ; oops, he told us to abort, so set n-flag
|
||
bra.s @EndMenuChg ; and leave without drawing anything
|
||
|
||
@DoTheDraw
|
||
IMPORT DrawTheMenu
|
||
bsr DrawTheMenu ; draw the menu
|
||
|
||
@EndMenuChg MOVE D5, D4 ;old menuIndex = current menuIndex
|
||
rts
|
||
ENDPROC
|
||
|
||
ChooseItem PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility -- ChooseItem
|
||
;-----------------------------------------------
|
||
;
|
||
PEA MENURECT(A6) ;don’t let menuProc write outside of rect
|
||
_ClipRect ;clip to menuRect
|
||
BSR GETMENUPTR ;get handle to menu in A1
|
||
;
|
||
MOVE #MCHOOSEMSG,-(SP) ;tell menu to choose itself
|
||
MOVE.L A1,-(SP) ;push menu handle
|
||
PEA MENURECT(A6) ;push menuRect
|
||
MOVE.L D3,-(SP) ;push mouse point
|
||
PEA ITEMRESULT(A6) ;push place to stick result
|
||
IMPORT CallMDefProc
|
||
BSR CallMDefProc ; Call the menu definition proc <PMAB364 23Jan88 EMT>
|
||
;
|
||
; every time the menu is chosen it could have scrolled, so re-save the scrolling data
|
||
;
|
||
moveq #10, d0 ; set up for "save alt data" call
|
||
move d5, d1 ; param is menuIndex of menu the mouse is in
|
||
IMPORT CallMBarProc
|
||
bsr CallMBarProc ; execute mbar defproc (ignore result in d0)
|
||
|
||
rts
|
||
ENDPROC
|
||
|
||
CheckHItem PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility -- CheckHItem
|
||
;-----------------------------------------------
|
||
; Check if itemResult(a6) has a hierarchical menu, and if so update various stackframe <FJL C222>
|
||
; structures. If user has delayed in item long enough then put up the hier menu. <FJL C222>
|
||
;
|
||
; On Entry: A1 ptr to item’s property bytes
|
||
;
|
||
; If no item selected then reset stackframe data and leave, but DON’T restore any HMenus
|
||
; that might be up. (If no item selected then mouse is in the menu bar or outside all menus)
|
||
;
|
||
bsr GetMenuPtr ; get ptr to menuInfo into a0 from index in d5
|
||
move itemResult(a6), d0 ; set up for GetItemRecord call, move item to d0
|
||
beq.s @NoItem ; if no item currently selected then leave
|
||
|
||
;
|
||
; If item does not have a hierarchical item then reset stackframe data,
|
||
; restore any HMenus up to the menu the mouse pt is in
|
||
;
|
||
IMPORT GetItemRecord
|
||
bsr GetItemRecord ; ptr to item’s record returned in a0
|
||
; its properties in a1
|
||
cmpi.b #HMenuCmd, itemCmd(a1) ; does it have a hierarchical menu?
|
||
bne.s @NotHItem ; no, then leave
|
||
|
||
;
|
||
; If funcResult or itemResult are not the same as last time thru the MSLoop then reset
|
||
; stackframe data and restore any HMenus up to the menu the mouse pt is in
|
||
;
|
||
|
||
move funcResult(a6), d0 ; do this for "cmp" to work
|
||
cmp lastFuncResult(a6), d0 ; is it the same menu as last time thru?
|
||
bne.s @NotSameItem ; no, so reset data and menus
|
||
|
||
move itemResult(a6), d0 ; do this for "cmp" to work
|
||
cmp lastItemResult(a6), d0 ; is it the same item as last time thru?
|
||
bne.s @NotSameItem ; no, so reset data
|
||
|
||
move.l a1, -(SP) ; store work register on the stack
|
||
subq #4, SP ; space for result
|
||
_TickCount ; get current Ticks
|
||
move.l (SP)+, d0 ; get Ticks in d0
|
||
move.l (SP)+, a1 ; restore work register
|
||
|
||
cmp.l DelayTicks(a6), d0 ; have we reached right number of ticks ?
|
||
blt.s @EndChkHItem ; no, so continue
|
||
;
|
||
; N ticks have passed with mouse in same item that has hierarchical menu, so bring
|
||
; the dang thing up. A1 has ptr to item’s properties.
|
||
;
|
||
moveq #0, d1 ; clear out d1 for GetHIndex
|
||
move.b itemMark(a1), d1 ; set up for GetHIndex -- move HMenu ID into d1
|
||
IMPORT GetHIndex
|
||
bsr GetHIndex ; get the index in menuList in d0
|
||
beq.s @NotHItem ; oops, got invalid HMenu ID, so just ignore it
|
||
|
||
move d0, d5 ; set up for DrawTheMenu
|
||
IMPORT DrawTheMenu
|
||
bsr DrawTheMenu ; and draw it
|
||
move d5, NewHMenuOffset(a6) ; save d5 in stackframe
|
||
move d4, d5 ; set up for call to ResetScrollRect
|
||
IMPORT ResetRectScrollData
|
||
bsr ResetRectScrollData ; and reset the scroll/rect for menu mouse is in
|
||
IMPORT CheckDragging
|
||
bsr CheckDragging ; check for mouse dragging towards HMenu
|
||
|
||
; If we get thru CheckDragging three states can exist:
|
||
; 1) The mouse is now in the HMenu --> select an item there
|
||
; 2) The mouse is in another menu item in the original menu --> bring HMenu down
|
||
; 3) The mouse has moved out of the menu --> bring HMenu down
|
||
|
||
bra.s @EndChkHItem
|
||
@NoItem
|
||
@NotHItem
|
||
@NotSameItem
|
||
;
|
||
; now restore bits behind any menus up
|
||
;
|
||
IMPORT RestoreSomeBits
|
||
bsr RestoreSomeBits ; Restore the bits behind all menus up to the
|
||
; one the mouse is currently in.
|
||
IMPORT SetTickCounters
|
||
bsr SetTickCounters ; reset tick counters
|
||
|
||
@EndChkHItem move itemResult(a6), lastItemResult(a6) ; save values from this time thru
|
||
move funcResult(a6), lastFuncResult(a6)
|
||
rts
|
||
ENDPROC
|
||
|
||
CheckDragging PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility -- CheckDragging
|
||
;-----------------------------------------------
|
||
; Allow the user to move the mouse towards the hierarchical
|
||
; menu for DragTicks.
|
||
; Wait for the mouse to leave the item, when it does, look
|
||
; to see if it is moving towards the menu. If it is moving
|
||
; towards the HMenu then wait MenuDrag ticks.
|
||
;
|
||
; On Entry: D5 Offset of newly drawn HMenu in MenuList.
|
||
; We need lots of registers, so save D5 in stackframe
|
||
|
||
movem.l d4, -(SP) ; save d4 on stack
|
||
|
||
subq #4, SP ; get mouse pt in D3
|
||
move.l SP, -(SP) ; temp mouse buffer on stack
|
||
_GetMouse
|
||
move.l (SP)+, d3
|
||
|
||
@InRectLoop
|
||
; see if mouse up yet
|
||
clr -(SP) ; make room for stilldown result
|
||
_WaitMouseUp ; is the button still down?
|
||
tst.b (SP)+ ; test result
|
||
beq @DoneDragging ; if up then done dragging
|
||
|
||
; call the mbarproc to see if mouse has entered the new HMenu
|
||
moveq #1, d0 ; hit message is #1
|
||
move.l d3, d1 ; send point in parameter
|
||
IMPORT CallMBarProc
|
||
bsr CallMBarProc ; execute the defproc
|
||
cmp NewHMenuOffset(a6), d0 ; is the hit in the newly drawn HMenu?
|
||
beq @DoneDragging ; yes, so no more dragging needed
|
||
|
||
; not in new HMenu, so see if it is still in the item’s rect
|
||
subq #2, SP ; save space for PtInRect result
|
||
subq #4, SP ; space for GetMouse result
|
||
move.l SP, -(SP) ; temp mouse buffer on stack
|
||
_GetMouse ; point is on the stack
|
||
move.l (SP), d3 ; store pt in d3 and leave on stack for PtInRect
|
||
|
||
; The mouse button is still down. We’ve read the mouse position already,
|
||
; so call the user hook (if its installed) and loop.
|
||
MOVE.L MENUHOOK,D0 ; <PMAB568 07Sep88 EMT>
|
||
BEQ.S @NoMHook ; <PMAB568 07Sep88 EMT>
|
||
MOVE.L D0,A0 ; <PMAB568 07Sep88 EMT>
|
||
JSR (A0) ; <PMAB568 07Sep88 EMT>
|
||
@NoMHook ; <PMAB568 07Sep88 EMT>
|
||
move.l mbSaveLoc, a0 ; get item’s rect from mbSaveLoc
|
||
move.l (a0), a0 ; dereference
|
||
pea mbItemRect(a0) ; push rect
|
||
_PtInRect
|
||
move.b (SP)+, d0 ; get boolean result
|
||
bne.s @InRectLoop ; still in rect, wait for it to leave
|
||
|
||
; if get here then mouse has moved out of itemRect but not into HMenu.
|
||
; First get menurect of HMenu by calling mbarproc. D3 has latest mouse pt from
|
||
; which we will draw the triangle allowing mouse to move towards HMenu.
|
||
|
||
moveq #9, d0 ; CalcRect message is #9
|
||
moveq #0, d1 ; clear hi-word of d1 since mbarproc WILL
|
||
; have this menu in its data structure already
|
||
move NewHMenuOffset(a6), d1 ; send MenuList offset as parameter
|
||
IMPORT CallMBarProc
|
||
bsr CallMBarProc ; execute the defproc
|
||
move.l d0, a0
|
||
move.l (a0), d4 ; store top, left in d4
|
||
move Bottom(a0), d5 ; store bottom, left in d5
|
||
swap d5
|
||
move Left(a0), d5
|
||
|
||
cmp d3, d4 ; if horizontal of D4 < D3 then menu to left
|
||
bgt.s @1 ; yes --> menu to left
|
||
; if menu is to the left then want to use
|
||
; right edge for angle calculations, otherwise
|
||
; will get angles too close to 90 degrees
|
||
move Right(a0), d4 ; store top, right in d4
|
||
move Right(a0), d5 ; store bottom, right in d5
|
||
|
||
; reset MenuDrag as of when mouse left the item’s rect
|
||
@1
|
||
IMPORT SetTickCounters
|
||
bsr SetTickCounters
|
||
|
||
; On Entry: D3 original mouse pt
|
||
; D4 top, left edge of HMenu
|
||
; D5 bottom, left edge of HMenu
|
||
; D7 hi-word has right pixel of newly drawn HMenu
|
||
; Used: D6 latest mouse pt
|
||
; D7 for intermediate calculations
|
||
|
||
@DragLoop
|
||
|
||
; see if mouse up yet
|
||
clr -(SP) ; make room for stilldown result
|
||
_WaitMouseUp ; is the button still down?
|
||
tst.b (SP)+ ; test result
|
||
beq @DoneDragging ; if up then done dragging
|
||
|
||
; see if have returned to the item rect, if so return to @InRectLoop, otherwise the same
|
||
; HMenu that is currently up will appear again. At the same time we are getting the mouse
|
||
; pt in D6.
|
||
subq #2, SP ; save space for PtInRect result
|
||
subq #4, SP ; space for GetMouse result
|
||
move.l SP, -(SP) ; temp mouse buffer on stack
|
||
_GetMouse ; point is on the stack
|
||
move.l (SP), d6 ; store pt in d6 and leave on stack for PtInRect
|
||
|
||
; The mouse button is still down. We’ve read the mouse position already,
|
||
; so call the user hook (if its installed) and loop.
|
||
MOVE.L MENUHOOK,D0 ; <PMAB568 07Sep88 EMT>
|
||
BEQ.S @NoMHook2 ; <PMAB568 07Sep88 EMT>
|
||
MOVE.L D0,A0 ; <PMAB568 07Sep88 EMT>
|
||
JSR (A0) ; <PMAB568 07Sep88 EMT>
|
||
@NoMHook2 ; <PMAB568 07Sep88 EMT>
|
||
move.l mbSaveLoc, a0 ; get item’s rect from mbSaveLoc
|
||
move.l (a0), a0 ; dereference
|
||
pea mbItemRect(a0) ; push rect
|
||
_PtInRect
|
||
move.b (SP)+, d0 ; get boolean result
|
||
bne.s @InRectLoop ; BACK IN ITEM’S RECT, WAIT FOR IT TO LEAVE AGAIN!!!
|
||
|
||
; call the mbarproc to see if mouse has entered the new HMenu
|
||
moveq #1, d0 ; hit message is #1
|
||
move.l d6, d1 ; send point in parameter
|
||
IMPORT CallMBarProc
|
||
bsr CallMBarProc ; execute the defproc
|
||
cmp NewHMenuOffset(a6), d0 ; is the hit in the newly drawn HMenu?
|
||
beq.s @DoneDragging ; yes, so no more dragging needed
|
||
|
||
; see if current mouse pt (D6) is within triangle bounded by D3, D4 and D5
|
||
;
|
||
; /D4
|
||
; / |
|
||
; / |
|
||
; / |
|
||
; D3 D6 | An obvious place to save code, but not on ROM build day!! <FJL 27Jan87>
|
||
; \ |
|
||
; \ |
|
||
; \ |
|
||
; \D5
|
||
;
|
||
; first check whether menu’s direction was right or left or previous menu
|
||
@ChkToRight
|
||
|
||
cmp d3, d4 ; if horizontal of D4 < D3 then menu to left
|
||
blt.s @ChkToLeft
|
||
|
||
; first see if D6 < D3 horizontally
|
||
cmp d3, d6 ; is D6 < D3
|
||
blt.s @DoneDragging ; yes, so moving wrong way
|
||
|
||
;draw a line from D3 to D6, calculate its slope and from that its angle
|
||
MOVE.L D6, D1 ; <PMAB568 07Sep88 EMT>
|
||
MOVE.L D3, D0 ; <PMAB568 07Sep88 EMT>
|
||
BSR.S @SlopeFromLine ; <PMAB568 07Sep88 EMT>
|
||
move d0, d7 ; <PMAB568 07Sep88 EMT>
|
||
|
||
;draw a line from D3 to D4, calculate its slope and from that its angle
|
||
MOVE.L D4, D1 ; <PMAB568 07Sep88 EMT>
|
||
MOVE.L D3, D0 ; <PMAB568 07Sep88 EMT>
|
||
BSR.S @SlopeFromLine ; <PMAB568 07Sep88 EMT>
|
||
cmp d0, d7 ; is angle to mouse >= angle to D4 ? <PMAB568 07Sep88 EMT>
|
||
blt.s @DoneDragging ; no, so mouse outside triangle
|
||
|
||
;draw a line from D3 to D5, calculate its slope and from that its angle
|
||
MOVE.L D5, D1 ; <PMAB568 07Sep88 EMT>
|
||
MOVE.L D3, D0 ; <PMAB568 07Sep88 EMT>
|
||
BSR.S @SlopeFromLine ; <PMAB568 07Sep88 EMT>
|
||
cmp d0, d7 ; is angle to mouse >= angle to D4 ? <PMAB568 07Sep88 EMT>
|
||
bgt.s @DoneDragging ; yes, so mouse outside triangle
|
||
bra.s @ChkTimeOut
|
||
|
||
;draw a line from D0 to D1, calculate its slope and from that its angle. Returned in D0.
|
||
@SlopeFromLine ; <PMAB568 07Sep88 EMT>
|
||
LEA -10(SP), SP ; 2 (AngleFromSlope) + 4 (FixRatio) + 4 (DeltaPoint)
|
||
MOVE.L D1, -(SP)
|
||
MOVE.L D0, -(SP)
|
||
_DeltaPoint ; now have dv and dh on the stack
|
||
_FixRatio
|
||
_AngleFromSlope
|
||
MOVE.W (SP)+, D0
|
||
RTS
|
||
|
||
@ChkToLeft
|
||
; first see if D6 > D3 horizontally
|
||
cmp d3, d6 ; is D6 > D3
|
||
bgt.s @DoneDragging ; yes, so moving wrong way
|
||
|
||
;draw a line from D3 to D6, calculate its slope and from that its angle
|
||
MOVE.L D3, D1 ; <PMAB568 07Sep88 EMT>
|
||
MOVE.L D6, D0 ; <PMAB568 07Sep88 EMT>
|
||
BSR.S @SlopeFromLine ; <PMAB568 07Sep88 EMT>
|
||
move d0, d7 ; <PMAB568 07Sep88 EMT>
|
||
|
||
;draw a line from D3 to D4, calculate its slope and from that its angle
|
||
MOVE.L D3, D1 ; <PMAB568 07Sep88 EMT>
|
||
MOVE.L D4, D0 ; <PMAB568 07Sep88 EMT>
|
||
BSR.S @SlopeFromLine ; <PMAB568 07Sep88 EMT>
|
||
cmp d0, d7 ; is angle to mouse <= angle to D4 ? <PMAB568 07Sep88 EMT>
|
||
bgt.s @DoneDragging ; no, so mouse outside triangle
|
||
|
||
;draw a line from D3 to D5, calculate its slope and from that its angle
|
||
MOVE.L D3, D1 ; <PMAB568 07Sep88 EMT>
|
||
MOVE.L D5, D0 ; <PMAB568 07Sep88 EMT>
|
||
BSR.S @SlopeFromLine ; <PMAB568 07Sep88 EMT>
|
||
cmp d0, d7 ; is angle to mouse <= angle to D4 ? <PMAB568 07Sep88 EMT>
|
||
blt.s @DoneDragging ; yes, so mouse outside triangle
|
||
; fall thru to @ChkTimeOut
|
||
|
||
@ChkTimeOut
|
||
; mouse is still moving towards HMenu, see if timeout yet
|
||
subq #4, SP ; space for result
|
||
_TickCount ; get current Ticks
|
||
move.l (SP)+, d0 ; get Ticks in d0
|
||
cmp.l DragTicks(a6), d0 ; have we reached DragTicks ?
|
||
bge.s @DoneDragging ; yes, so quit dragging
|
||
bra.s @DragLoop ; no, so keep dragging
|
||
|
||
@DoneDragging movem.l (SP)+, d4 ; restore work register
|
||
move d4, d5 ; restore d5 (since d4==d5 before HMenu was drawn)
|
||
rts
|
||
ENDPROC
|
||
|
||
RestoreBits PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility -- RestoreBits
|
||
;-----------------------------------------------
|
||
;
|
||
; RESTOREBITS is a utility that takes the bits that were saved by SaveBits and <FJL C222>
|
||
; puts them back on the screen.
|
||
;
|
||
subq #msHMenuStorage, msLastMenu(a6) ; reduce counter <FJL C222>
|
||
|
||
MOVEQ #8,D0 ; set restore message
|
||
IMPORT CallMBarProc
|
||
BRA CallMBarProc ; execute the defproc (result in D0)
|
||
; and let CallMBarProc return
|
||
ENDPROC
|
||
|
||
RestoreSomeBits PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility -- RestoreSomeBits
|
||
;-----------------------------------------------
|
||
; RestoreSomeBits loops thru each menu up on the screen looking to see if it should
|
||
; be restored, and if it should be, restoring it. The condition for restoration is
|
||
; if the mouse pt is in the current menu then don’t restore it.
|
||
;
|
||
move.l (a4), a0 ; get ptr to temp storage
|
||
move msLastMenu(a6), d0 ; get offset to last menu on screen
|
||
beq.s @RSBNone ; if no menus then exit (should never happen but...)
|
||
cmp -4(a0, d0), d5 ; is the 'last' menu the one the mouse is in?
|
||
beq.s @RSBNone ; yes, so don’t restore any, and don’t redraw menu
|
||
|
||
@RSBLoop move.l (a4), a0 ; get ptr to temp storage
|
||
move msLastMenu(a6), d0 ; get offset to last menu on screen
|
||
beq.s @RSBNone ; if no menus then exit
|
||
cmp -4(a0, d0), d5 ; is the 'last' menu the one the mouse is in?
|
||
beq.s @RSBDone ; yes, so done restoring
|
||
move -2(a0, d0), itemResult(a6) ; no, so restore previous selected item
|
||
IMPORT RestoreBits
|
||
bsr RestoreBits ; restore dem bits
|
||
bra.s @RSBLoop ; and loop
|
||
|
||
@RSBDone
|
||
;
|
||
; If here then at least one menu was restored, and as a result of the HMenu
|
||
; overlap the menu has strange black and white patches. Calling ChooseItem
|
||
; with the item that was selected in the menu before the HMenu was
|
||
; brought up will cause both old and new items to be redrawn.
|
||
tst msLastMenu(a6) ; any menus left up ?
|
||
beq.s @RSBNone ; no, so don’t choose anything
|
||
IMPORT ChooseItem
|
||
bsr ChooseItem ; tell MDEF to choose after redraw
|
||
@RSBNone RTS
|
||
ENDPROC
|
||
|
||
RestoreAllBits PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility -- RestoreAllBits
|
||
;-----------------------------------------------
|
||
; RestoreAllBits loops thru every menu up on the screen and restores the bits <FJL C222>
|
||
; behind each in turn. It is called when 1) the mouse button has gone up, or 2) the mouse
|
||
; has gone into another menu title.
|
||
;
|
||
tst msLastMenu(a6) ; could have already restored all
|
||
beq.s @RestoreDone ; the menus ?
|
||
|
||
IMPORT RestoreBits
|
||
bsr RestoreBits ; restore dem bits
|
||
bra.s RestoreAllBits ; yes, so loop
|
||
|
||
@RestoreDone RTS
|
||
ENDPROC
|
||
|
||
DrawFirstMenu PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility -- DrawFirstMenu
|
||
;-----------------------------------------------
|
||
; DrawFirstMenu draws the first pop-up menu. This is separate because of the special placement
|
||
; needed for the pop-up menu. The top left edge of the item PopUpItem must match the parameters
|
||
; Top and Left. All subsequent menus are drawn using the same routines that MenuSelect uses.
|
||
;
|
||
; TODO: Call MBarHook after sending msg #3 to MDEF but before drawing menu.
|
||
|
||
addq #msHMenuStorage, msLastMenu(a6) ; bump up counter <FJL C222>
|
||
move msLastMenu(a6), d0 ; get offset into temp storage
|
||
move.l (a4), a0 ; get ptr to temp storage
|
||
move d5, -4(a0, d0) ; store MenuList offset
|
||
move itemResult(a6), -2(a0,d0) ; and item number
|
||
|
||
; Call MDEF to calculate where pop-up menu should go. This is a new message to the MDEF.
|
||
; Pass: MenuHandle, Top, Left, Item
|
||
; Return: MenuRect, TopMenuItem
|
||
|
||
move #3, -(SP) ; message = calc item top
|
||
bsr GetMenuPtr ; get a handle to the menu record into A1 using
|
||
; menuIndex in D5, and ptr in A0
|
||
move.l a1,-(SP) ; push menu handle
|
||
pea menuRect(a6) ; push menuRect pointer
|
||
move.l msTopLeft(a6), -(SP) ; push left and top at same time
|
||
pea PopUpItem(a6) ; push the item’s address
|
||
IMPORT CallMDefProc
|
||
BSR CallMDefProc ; Call the menu definition proc <PMAB364 23Jan88 EMT>
|
||
|
||
; Call MBDF to save bits behind and draw the drop shadow
|
||
|
||
MOVEQ #7, D0 ; set up for save message
|
||
SWAP D0 ; put parameter1 in hi-word of D0
|
||
MOVE D5, D0 ; parameter1 is menuList offset
|
||
SWAP D0
|
||
LEA menuRect(a6), A0 ; parameter2 is address of menuRect
|
||
MOVE.L A0, D1 ; put in D1 for CallMBarProc
|
||
IMPORT CallMBarProc
|
||
BSR CallMBarProc ; tell it to save. No result.
|
||
|
||
; MDEF returns TopMenuItem in WhichItem parameter, store it in low-memory
|
||
|
||
move PopUpItem(a6), TopMenuItem
|
||
IMPORT CallDrawMDEF
|
||
bsr CallDrawMDEF ; ask the MDEF to draw the menu
|
||
|
||
@DoneDraw RTS
|
||
ENDPROC
|
||
|
||
DRAWTHEMENU PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility -- DrawTheMenu
|
||
;-----------------------------------------------
|
||
; DrawTheMenu is an internal utility that draws the structure of a menu. It uses
|
||
; the menu whose index is in D5.
|
||
;
|
||
; call the mBar defproc to draw the pulldown and save the bits
|
||
; behind.
|
||
;
|
||
cmpi #5*msHMenuStorage, msLastMenu(a6) ; are there 5 menus up already??? <FJL C222>
|
||
beq.s @DoneDraw ; yes, so leave without doing anything <FJL C222>
|
||
|
||
addq #msHMenuStorage, msLastMenu(a6) ; bump up counter <FJL C222>
|
||
move msLastMenu(a6), d0 ; get offset into temp storage
|
||
move.l (a4), a0 ; get ptr to temp storage
|
||
move d5, -4(a0, d0) ; store menuID
|
||
move itemResult(a6), -2(a0,d0) ; and item number
|
||
|
||
clr.l d1 ; clear out d1 for mbarproc call <FJL C222>
|
||
cmpi #msHMenuStorage, msLastMenu(a6) ; is this a hierarchical menu?
|
||
; If so, we need to send the vertical
|
||
; mouse pt to mbarproc
|
||
beq.s @NotHMenu ; no, so just do normal stuff
|
||
move.l d3, d1 ; yes, so move mouse pt into d1. Vertical
|
||
; mouse pt is in hi-word of d3
|
||
|
||
@NotHMenu MOVEQ #9,D0 ; set up for the rect message
|
||
MOVE.w D5,D1 ; parameter is the menuIndex (affects lo-word
|
||
; of D1 only, hi-word still has vert mouse pt)
|
||
IMPORT CallMBarProc
|
||
BSR CallMBarProc ; execute the defproc (result in D0)
|
||
|
||
MOVE.L D0,A0 ; move menuRect ptr to A-reg
|
||
MOVE.L (A0),menuRect(A6) ; copy the rect
|
||
MOVE.L 4(A0),menuRect+4(A6) ;
|
||
|
||
MOVEQ #7, D0 ; set up for save message
|
||
SWAP D0 ; put parameter1 in hi-word of D0
|
||
MOVE D5, D0 ; parameter1 is menuList offset
|
||
SWAP D0
|
||
LEA menuRect(a6), A0 ; parameter2 is address of menuRect
|
||
MOVE.L A0, D1 ; put in D1 for CallMBarProc
|
||
BSR CallMBarProc ; tell it to save. No result.
|
||
|
||
move menuRect+Top(a6), TopMenuItem ; tell MDEF to draw from top of menu
|
||
IMPORT CallDrawMDEF
|
||
bsr CallDrawMDEF ; ask the MDEF to draw the menu
|
||
|
||
@DoneDraw RTS
|
||
ENDPROC
|
||
|
||
CallDrawMDEF PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility -- CallDrawMDEF
|
||
;-----------------------------------------------
|
||
; CallDrawMDEF is an internal utility that asks the MDEF
|
||
; to draw the menu whose offset is in D5. Immediately after
|
||
; the menu is drawn the MBDF is told to save the two scrolling
|
||
; globals topMenuItem and atMenuBottom. See note in MBDF
|
||
; about why this was done this way.
|
||
;
|
||
; before drawing, clip to intersection of menuRect and portRect in case user has multiple screens
|
||
; Just clip to menuRect now. <PMAB364 23Jan88 EMT>
|
||
|
||
; subq #2, SP ; space for boolean result
|
||
; pea menuRect(a6) ; push src rectangle 1
|
||
; pea portRect(a2) ; push src rectangle 2
|
||
; pea tRect1(a6) ; push dest rectangle
|
||
; _SectRect
|
||
; addq #2, SP ; ignore result
|
||
;
|
||
; PEA tRect1(a6) ;don’t let menuProc write outside of rect <FJL C175>
|
||
PEA menuRect(A6) ; Just use menuRect now. <PMAB364 23Jan88 EMT>
|
||
_ClipRect ;clip to menuRect <FJL C175>
|
||
|
||
CLR.W -(SP) ;message = draw
|
||
BSR GETMENUPTR ;get a handle to the menu record into A1 using
|
||
; menuIndex in D5
|
||
MOVE.L A1,-(SP) ;push menu handle
|
||
PEA menuRect(A6) ;push menuRect pointer
|
||
SUBQ #8,SP ;point and whichItem are not looked at
|
||
IMPORT CallMDefProc
|
||
BSR CallMDefProc ; Call the menu definition proc <PMAB364 23Jan88 EMT>
|
||
|
||
moveq #10, d0 ; set up for "save alt data" call
|
||
move d5, d1 ; param is menuIndex of menu the mouse is in
|
||
IMPORT CallMBarProc
|
||
bsr CallMBarProc ; execute mbar defproc (ignore result in d0)
|
||
|
||
rts
|
||
ENDPROC
|
||
|
||
CallMDefProc PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility -- CallMDefProc(message: INTEGER; theMenu: MenuHandle; VAR menuRec:
|
||
; Rect; hitPt: Point; VAR whichItem: INTEGER); <PMAB364 23Jan88 EMT>
|
||
; (menuRecord pointer in A0)
|
||
;-----------------------------------------------
|
||
; Utility CallMDefProc -- given a menuRecord pointer in A0, calls the menu definition
|
||
; procedure. It does this by de-referencing the defProc handle, reloading it into
|
||
; memory if necessary. If there is no MenuDefProc, it simply cleans up the stack and returns.
|
||
; This routine replaces GetTheMProc UnlockMProc, and UnlkMDef.
|
||
|
||
paramSize EQU 18
|
||
|
||
MOVEM.L D3/A5, -(SP) ; Save some registers
|
||
MOVE.L MenuDefHandle(A0),D3 ; get the handle
|
||
BEQ.S @NoMenuDef ; Skip if there is none.
|
||
|
||
LEA 8+4(SP), A0 ; Original parameters
|
||
MOVEQ #paramSize, D0 ; Size of parameters
|
||
SUB.L D0, SP ; Prepare to make a copy of the parameters
|
||
MOVE.L SP, A1 ; Copy
|
||
_BlockMove ; Do it.
|
||
|
||
MOVE.L D3,-(SP) ; get the MDEF handle
|
||
_LoadResource ; load it
|
||
MOVE.L D3, A0 ; get the MDEF handle
|
||
|
||
_HLock ; lock it the gentleman’s way <C169>
|
||
MOVE.L (A0),A0 ; handle -> pointer
|
||
|
||
MOVE.L CurrentA5, A5 ; fix up his A5 world
|
||
JSR (A0) ; call it
|
||
|
||
MOVE.L D3, A0 ; get the MDEF handle
|
||
_HUnlock ; unlock the gentleman’s way <C169>
|
||
|
||
@NoMenuDef
|
||
MOVEM.L (SP)+, D3/A5 ; Restore some registers
|
||
MOVE.L (SP)+, A0 ; get the return address
|
||
LEA paramSize(SP), SP ; strip off the parameters
|
||
JMP (A0) ; and return
|
||
|
||
ENDPROC
|
||
|
||
CALLCHOOSE PROC EXPORT
|
||
;
|
||
; CallChoose is a utility procedure to call a menu’s menuProc to select an item
|
||
;
|
||
MOVE #MCHOOSEMSG,-(SP) ;the message is choose
|
||
BSR GETMENUPTR ;get handle to menu specified by D5
|
||
MOVE.L A1,-(SP) ;push menuHandle
|
||
PEA MENURECT(A6) ;push rectangle of current menu
|
||
MOVE.L D1,-(SP) ;mouse point
|
||
PEA TOOLSCRATCH ;scratch location to store result
|
||
|
||
IMPORT CallMDefProc
|
||
BSR CallMDefProc ; Call the menu definition proc <PMAB364 23Jan88 EMT>
|
||
;
|
||
; delay based on TICKS
|
||
;
|
||
move.l #3, a0 ; 1/20 second delay (tune it!) <FJL CXXX>
|
||
_Delay ; for the Unix folks <FJL CXXX>
|
||
|
||
RTS
|
||
ENDPROC
|
||
|
||
FLASHFEEDBACK PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility -- FlashFeedBack
|
||
;-----------------------------------------------
|
||
;
|
||
; FlashFeedBack is a utility routine that implements flash feedback on menu selections.
|
||
; tThe "MenuFlash" global determines the number of flashes
|
||
;
|
||
MOVE D4,-(SP) ;save work register
|
||
MOVE MENUFLASH,D4 ;get menu flash count
|
||
BEQ.S FLASHDONE ;if zero, no flashing at all
|
||
MOVE ITEMRESULT(A6),TOOLSCRATCH ;was anything selected?
|
||
BEQ.S FLASHDONE ;if not, don’t give feedback
|
||
|
||
PEA MENURECT(A6) ;clip to the menu
|
||
_ClipRect
|
||
;
|
||
; Here is the flash loop. It uses TICKS for timing.
|
||
;
|
||
FLASHLOOP MOVEQ #0,D1 ;zero point to force selection off
|
||
IMPORT CallChoose
|
||
BSR CALLCHOOSE ;call the menuProc to turn it off
|
||
MOVE.L D3,D1 ;now use real point to turn it on
|
||
BSR CALLCHOOSE ;call menuProc to turn it on
|
||
|
||
SUBQ #1,D4 ;any more times?
|
||
BNE.S FLASHLOOP ;do it flashCount times
|
||
|
||
IMPORT FullClip
|
||
BSR FULLCLIP ;restore full screen clipping
|
||
|
||
FLASHDONE MOVE (SP)+,D4 ;restore D4
|
||
RTS ;return to caller
|
||
ENDPROC
|
||
|
||
FULLCLIP PROC EXPORT
|
||
;-----------------------------------------------
|
||
; Utility -- FullClip
|
||
;-----------------------------------------------
|
||
; FullClip is a utility that sets the clipping region of the wmgrPort to the portRect
|
||
; It is used to save code.
|
||
;
|
||
; Note: It is not really necessary to set clip full open here because the mbarproc is
|
||
; called after this to restore the menu, and it sets the clip full open. But
|
||
; because it is so close to ROM build we won’t take it out. <FJL 8Feb87>
|
||
;
|
||
MOVE.L GrafGlobals(A5), A0 ; <PMAB364 23Jan88 EMT>
|
||
MOVE.L wideOpen(A0), -(SP) ; set the clip to wide open <PMAB364 23Jan88 EMT>
|
||
_SetClip ; <PMAB364 23Jan88 EMT>
|
||
|
||
RTS
|
||
ENDPROC
|
||
|
||
MenuChoice PROC EXPORT
|
||
;------------------------------------------------------------------------------------
|
||
;
|
||
; FUNCTION MenuChoice : LONGINT; <FJL CXXX>
|
||
;
|
||
;------------------------------------------------------------------------------------
|
||
; FUNCTION MenuChoice : LONGINT;
|
||
;
|
||
; Returns the menuID in the hi-word and menu Item in the lo-word from the lo-mem location
|
||
; MenuDisable ($B54). This feature was requested by User-Ed who want to use
|
||
; it with training programs.
|
||
;
|
||
move.l MenuDisable, 4(SP) ; set function result
|
||
rts
|
||
ENDPROC
|
||
|
||
GetMenuBar PROC EXPORT
|
||
;------------------------------------------------------------------------------------
|
||
;
|
||
; GetMenuBar
|
||
; do not return system menus in the returned menu list <22> PN
|
||
;------------------------------------------------------------------------------------
|
||
;
|
||
; FUNCTION GetMenuBar: MenuListHandle -- allocate a menuList data structure and copy
|
||
; the current menuList into it
|
||
;
|
||
;• <start> roll in GetMenuBarDoesNotReturnSystemMenus from SystemMenuPatches.a
|
||
; GetMenuBarDoesNotReturnSystemMenus — do not return system menus in the returned menu list
|
||
|
||
IF forROM THEN
|
||
IMPORT FindFirstSystemMenu6BO
|
||
jsr FindFirstSystemMenu6BO ; Are there any system menus?
|
||
beq OriginalTrap
|
||
|
||
MOVE.L d3,-(SP) ; Save off a work register
|
||
|
||
MOVEQ #0,D3
|
||
MOVE.W D0,D3 ; Save off index
|
||
SUBQ.L #4,SP ; Make room for result
|
||
JSR OriginalTrap
|
||
MOVE.L (SP)+,A0 ; Get copy of menulist
|
||
MOVE.L A0,8(SP) ; Return as result
|
||
BEQ.S @done ; EQ means no menulist or memfull
|
||
; Munger(menuH, d3, NIL, d1, POINTER(-1), 0);
|
||
|
||
MOVE.L (A0),A1 ; Get copymenulist ptr
|
||
moveq #0,d1 ; clear out high word <10>
|
||
MOVE.W lastMenu(A1),D1 ; Offset to last menu (could be zero but we’ve chkd that)
|
||
ADDQ.W #6,D1 ; Offset past last menu entry
|
||
SUB.W d3,D1 ; D1 = Offset to last menu - Offset to 1st sysmenu
|
||
; (i.e., # bytes for system menus)
|
||
SUB.W D1,lastMenu(A1) ; Set new count for the list
|
||
|
||
SUBQ.L #4,SP ; Make room for Munger result
|
||
MOVE.L A0,-(SP) ; Push the handle
|
||
MOVE.L d3,-(SP) ; offset=first system menu offset
|
||
CLR.L -(SP) ; ptr1=NIL <10>
|
||
MOVE.L D1,-(SP) ; len1=# of bytes to delete
|
||
MOVE.L A0,-(SP) ; ptr2=anything non-nil will do
|
||
CLR.L -(SP) ; len2=0 means delete
|
||
_Munger ; Rip out system menus
|
||
ADDQ.L #4,SP ; ignore Munger result
|
||
@done
|
||
MOVE.L (SP)+,d3 ; Restore work register
|
||
RTS
|
||
OriginalTrap
|
||
ENDIF
|
||
;• <end> roll in GetMenuBarDoesNotReturnSystemMenus from SystemMenuPatches.a
|
||
|
||
move.l menuList, a0 ; get the menuList handle <FJL C222>
|
||
MOVE.L A0, 4(SP) ; Is this NIL? If yes, return as function result <KSM BRC41545>
|
||
beq.s @1 ; YES, - faceless MF app is running <KSM BRC41545>
|
||
_HandToHand ; make a copy of it <FJL C222>
|
||
move.l a0, 4(SP) ; return it as the function result <FJL C222>
|
||
MOVE.L (A0), A0 ; Dereference it <PMAB417 03Mar88 EMT>
|
||
MOVE.W lastMenu(A0), D0 ; Get last regular menu <PMAB417 03Mar88 EMT>
|
||
CLR.L menuTitleSave+6(A0, D0) ; Clear out saved handle <PMAB417 03Mar88 EMT>
|
||
@1 ; Branch here when menulist is NIL <KSM BRC41545>
|
||
rts ; <FJL C222>
|
||
ENDPROC
|
||
|
||
GetMCInfo PROC EXPORT ; <FJL C408>
|
||
;------------------------------------------------------------------------------------
|
||
;
|
||
; GetMCInfo <FJL C408>
|
||
;
|
||
;------------------------------------------------------------------------------------
|
||
;
|
||
; FUNCTION GetMCInfo: MenuCTblHandle -- allocate a new color table, and copy the
|
||
; current one into it.
|
||
;
|
||
move.l MenuCInfo, a0 ; get the color table handle
|
||
_HandToHand ; make a copy of it
|
||
beq.s @OK ; check error result
|
||
moveq #0, a0 ; on error return zero
|
||
|
||
@OK move.l a0, 4(SP) ; return it as the function result
|
||
rts
|
||
ENDPROC
|
||
|
||
SetMenuBar PROC EXPORT
|
||
;------------------------------------------------------------------------------------
|
||
;
|
||
; SetMenuBar
|
||
;
|
||
;------------------------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE SetMenuBar(menuListHandle) -- copy the parameter menu list into the current
|
||
; menu List.
|
||
|
||
; SetMenuBarAddsSystemMenus — SetMenuBar should add the system menus to the current menu list
|
||
; Roll in SetMenuBarAddsSystemMenus from SystemMenuPatch.a
|
||
|
||
CLR.W -(SP) ; A new menu bar invalidates the <PMAB417 03Mar88 EMT>
|
||
_HiliteMenu ; currently selected title <PMAB417 03Mar88 EMT>
|
||
|
||
move.l menuList, a0 ; get the old menuList <FJL C222>
|
||
_DisposHandle ; and dispose of it <FJL C222>
|
||
move.l 4(SP), a0 ; get the parameter menuList handle <FJL C222>
|
||
move.l (SP)+, (SP) ; strip the parameter <FJL C222>
|
||
_HandToHand ; make a copy of the parameter list <FJL C222>
|
||
move.l a0, menuList ; store the new menuList <FJL C222>
|
||
|
||
RTS
|
||
ENDPROC
|
||
|
||
SetMCInfo PROC EXPORT ; <FJL C408>
|
||
;------------------------------------------------------------------------------------
|
||
;
|
||
; SetMCInfo <FJL C408>
|
||
;
|
||
;------------------------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE SetMCInfo(menuCTblHandle) -- copy the parameter menu color table into the
|
||
; current menu color table. MemErr will be set for caller if HandToHand failed.
|
||
move.l 4(SP), a0 ; get the parameter menuList handle
|
||
move.l (SP)+, (SP) ; strip the parameter
|
||
_HandToHand ; make a copy of the parameter list
|
||
bne.s @NoMemory ; check error result
|
||
; on error do not change color table
|
||
|
||
@OK move.l MenuCInfo, a1 ; get the old color table
|
||
move.l a0, MenuCInfo ; store the new menuList
|
||
move.l a1, a0 ; move old color table handle to a0
|
||
_DisposHandle ; and dispose of it
|
||
|
||
IMPORT MenuCTblSanityChk
|
||
bsr MenuCTblSanityChk ; check the table for consistency
|
||
|
||
@NoMemory rts ; return
|
||
ENDPROC
|
||
|
||
DISPOSEMENU PROC EXPORT
|
||
;------------------------------------------------------------------------------------
|
||
;
|
||
; DisposeMenu
|
||
;
|
||
;------------------------------------------------------------------------------------
|
||
; PROCEDURE DisposeMenu(menuHandle) -- dispose of the dynamic storage used by the
|
||
; menu data structure
|
||
|
||
; <15> DisposeMenu supports disposing both menus that are resource handles and other menus.
|
||
; Thus, it has the responsibility of disposing the handle and removing it from the
|
||
; resource map. One way to do this would be to call DetachResource and then DisposeHandle,
|
||
; since the Resource Manager is tolerant of non-resource handles, and would just return
|
||
; an error. However, the Process Manager depends on ReleaseResource to keep track of
|
||
; Apple menu handles, so we instead do a ReleaseResource, followed by a DisposeHandle if
|
||
; the ReleaseResource returns resNotFound (which is what it will do if you pass it something
|
||
; other than a resource handle).
|
||
|
||
move.l 4(sp),-(sp) ; first, call ReleaseResource on the menu handle
|
||
_ReleaseResource
|
||
subq #2,sp ; check the error
|
||
_ResError
|
||
cmp.w #resNotFound,(sp)+ ; did ReleaseResource dispose the handle?
|
||
bne.s Done ; yes, we are done
|
||
|
||
move.l 4(sp),a0 ; now call DisposeHandle on the menu handle
|
||
_DisposeHandle
|
||
|
||
Done
|
||
move.l (sp)+,(sp) ; strip menu handle parameter
|
||
rts
|
||
|
||
ENDPROC
|
||
|
||
DispMCInfo PROC EXPORT ; <FJL C408>
|
||
;------------------------------------------------------------------------------------
|
||
;
|
||
; DispMCInfo <FJL C408>
|
||
;
|
||
;------------------------------------------------------------------------------------
|
||
; PROCEDURE DispMCInfo(menuCTblHandle) -- dispose of the dynamic storage used by the
|
||
; menu color table
|
||
MOVE.L 4(SP),A0 ; get menu color table Handle
|
||
_DisposHandle ; it’s not a resource, so just toss it
|
||
move.l (SP)+, (SP) ; strip parameter
|
||
|
||
RTS
|
||
ENDPROC
|
||
|
||
CHECKITEM PROC EXPORT
|
||
;
|
||
; PROCEDURE CheckItem(menuHandle,itemNumber, checked: BOOLEAN) -- check or unCheck
|
||
; an item. Strategy: transform the boolean into the proper char right on the stack
|
||
;
|
||
TST.B 4(SP) ;test the boolean
|
||
BEQ.S CNOMARK ;go use noMark symbol
|
||
MOVE #CHECKMARK,4(SP)
|
||
IMPORT SetItemMark
|
||
BRA SETITEMMARK ;go mark it
|
||
|
||
CNOMARK MOVE #NOMARK,4(SP) ;unCheck it
|
||
BRA SETITEMMARK ;go do it
|
||
ENDPROC
|
||
|
||
GETITEMMARK PROC EXPORT
|
||
;
|
||
; PROCEDURE GetItemMark(menuHandle,itemNumber,VAR markChar) -- get the current value of
|
||
; an item’s markfield. Use GetItemProperty.
|
||
;
|
||
MOVEQ #ITEMMARK,D2 ;set up property selector
|
||
IMPORT GetItemProperty
|
||
BRA GETITEMPROPERTY ;do it!
|
||
ENDPROC
|
||
|
||
GETITEMICON PROC EXPORT
|
||
;
|
||
; PROCEDURE GetItemIcon(menuHandle,itemNumber,VAR iconChar) -- get the current value of
|
||
; an item’s icon field. Use GetItemProperty.
|
||
;
|
||
MOVEQ #ITEMICON,D2 ;set up property selector
|
||
IMPORT GetItemProperty
|
||
BRA GETITEMPROPERTY ;do it!
|
||
ENDPROC
|
||
|
||
GETITEMCMD PROC EXPORT ;<FJL C844>
|
||
;
|
||
; PROCEDURE GetItemCmd(menuHandle,itemNumber,VAR cmdChar) -- get the current value of <FJL C844>
|
||
; an item’s cmd field. Use GetItemProperty. Needed for hierarchical menus.
|
||
;
|
||
MOVEQ #ITEMCMD,D2 ;set up property selector
|
||
IMPORT GetItemProperty
|
||
BRA GETITEMPROPERTY ;do it!
|
||
ENDPROC
|
||
|
||
__GETITEMSTYLE PROC EXPORT
|
||
;
|
||
; PROCEDURE GetItemStyle(menuHandle,itemNumber,VAR styleChar) -- get the current value of
|
||
; an item’s style field. Use GetItemProperty.
|
||
;
|
||
MOVEQ #ITEMSTYLE,D2 ;set up property selector
|
||
IMPORT GetItemProperty
|
||
BRA GETITEMPROPERTY ;do it!
|
||
ENDPROC
|
||
|
||
SETITEMMARK PROC EXPORT
|
||
;
|
||
; PROCEDURE SetItemMark(menuHandle,itemNumber,markChar) -- set the current value of an
|
||
; item’s mark field. Use SetItemProperty.
|
||
;
|
||
MOVEQ #ITEMMARK,D2 ;set up property selector
|
||
IMPORT SetItemProperty
|
||
BRA SETITEMPROPERTY
|
||
ENDPROC
|
||
|
||
SETITEMICON PROC EXPORT
|
||
;
|
||
; PROCEDURE SetItemIcon(menuHandle,itemNumber, iconChar) -- set the current value of
|
||
; an item’s icon field. Use SetItemProperty.
|
||
;
|
||
MOVEQ #ITEMICON,D2 ;set up property selector
|
||
IMPORT SetItemProperty
|
||
BRA SETITEMPROPERTY ;do it!
|
||
ENDPROC
|
||
|
||
SETITEMCMD PROC EXPORT ;<FJL C844>
|
||
;
|
||
; PROCEDURE SetItemCmd(menuHandle,itemNumber, cmdChar) -- set the current value of <FJL C844>
|
||
; an item’s cmd field. Use SetItemProperty. Needed for hierarchical menus.
|
||
;
|
||
MOVEQ #ITEMCMD,D2 ;set up property selector
|
||
IMPORT SetItemProperty
|
||
BRA SETITEMPROPERTY ;do it!
|
||
ENDPROC
|
||
|
||
SETITEMSTYLE PROC EXPORT
|
||
;
|
||
; PROCEDURE SetItemStyle(menuHandle,itemNumber,styleChar) -- set the current value of
|
||
; an item’s style field. Use SetItemProperty.
|
||
;
|
||
MOVEQ #ITEMSTYLE,D2 ;set up property selector
|
||
IMPORT SetItemProperty
|
||
BRA SETITEMPROPERTY ;do it!
|
||
ENDPROC
|
||
|
||
GETITEMPROPERTY PROC ENTRY
|
||
;
|
||
; PROCEDURE GetItemProperty(menuHandle,itemNumber, VAR propertyValue) -- is an internal
|
||
; routine similar to SetItemProperty that gets a property of a requested item.
|
||
; The property is selected by the small integer in D2.
|
||
;
|
||
MOVE.L 10(SP),A0 ;get menuHandle
|
||
MOVE.L (A0),A0 ;turn into menu pointer
|
||
MOVE 8(SP),D0 ;get item number
|
||
IMPORT GetItemRecord
|
||
BSR GETITEMRECORD ;look it up
|
||
|
||
MOVE.L 4(SP),A0 ;get result pointer
|
||
CLR.B (A0) ;assume result of zero <EHB 6-Sep-85>
|
||
MOVE.L A1,D0 ;did we find the item?
|
||
BEQ.S TENBYTEXIT ;if not, we’re done
|
||
|
||
MOVE.B 0(A1,D2),1(A0) ;move the requested property byte
|
||
ENTRY TenBytExit
|
||
TENBYTEXIT MOVE.L (SP)+,A0 ;get return address
|
||
ADD #10,SP ;strip 10 bytes of parameters
|
||
JMP (A0) ;return to caller
|
||
ENDPROC
|
||
|
||
SETITEMPROPERTY PROC ENTRY
|
||
;
|
||
; PROCEDURE SetItemProperty(menuHandle,itemNumber,propertyValue) -- an internal routine
|
||
; to set a property byte of an item. A small integer offset in D2 determines
|
||
; which property.
|
||
;
|
||
MOVE.L 8(SP),A0 ;get menuHandle
|
||
MOVE.L (A0),A0 ;handle -> pointer
|
||
MOVE 6(SP),D0 ;get item number
|
||
IMPORT GetItemRecord
|
||
BSR GETITEMRECORD ;find the item
|
||
BEQ.S TWOPARMEXIT ;if not, skip
|
||
|
||
MOVE.B 5(SP),0(A1,D2) ;move in the property byte
|
||
|
||
SUBQ #ItemMark,D2 ; is it the check mark? <EHB 1/24/85>
|
||
BEQ.S TwoParmExit ; yes, don’t recalculate <EHB 1/24/85>
|
||
|
||
MOVE.L 8(SP),-(SP) ;push the menuHandle
|
||
IMPORT DirtyMenuSize
|
||
BSR DirtyMenuSize ; invalidate size <EHB 5-Mar-85>
|
||
|
||
ENTRY TwoParmExit
|
||
TWOPARMEXIT MOVE.L (SP)+,A0 ;get return address
|
||
ADDQ #8,SP ;strip 8 bytes of parameters
|
||
JMP (A0) ;return to caller
|
||
ENDPROC
|
||
|
||
GETITEMRECORD PROC ENTRY
|
||
;
|
||
; GetItemRecord is the main utility used for accessing the menu item data structure.
|
||
; It has a register interface to save code. On entry, A0 points to a menuInfo block,
|
||
; while D0 has the item number of interest. On exit, A0 points to the item string
|
||
; of interest while A1 points to that item’s attribute byte list. If the item can’t
|
||
; be found, A0 and A1 both return NIL and the z-flag is set.
|
||
;
|
||
TST D0 ; make sure item number is valid
|
||
BLE.S NOITEM ; => invalid, don’t bother
|
||
|
||
DOITEM MOVEQ #0,D1 ; clear D1 for byte arithmetic
|
||
LEA MENUDATA(A0),A1 ; get menuData ptr
|
||
MOVE.B (A1)+,D1 ; get title length
|
||
ADD D1,A1 ; skip over title string
|
||
;
|
||
; here is the item search loop. A1 points to the beginning of the next item.
|
||
;
|
||
GETILOOP SUBQ #1,D0 ; is this the one we’re looking for?
|
||
BEQ.S GOTITEM ; if so, we got it
|
||
MOVE.B (A1),D1 ; get length of current item <EHB 8-May-85>
|
||
BEQ.S NOITEM ; length zero marks end of list
|
||
|
||
ADDQ #5,D1 ; 4 bytes of properties + 1 length <EHB 8-May-85>
|
||
ADD D1,A1 ; bump to next item
|
||
BRA.S GETILOOP ; loop till done
|
||
;
|
||
; the item couldn’t be found so return NIL
|
||
; put string pointer into D1 in case we want to find end byte
|
||
;
|
||
NOITEM
|
||
MOVE.L A1,D1 ; return pointer to 0 byte in D1 <EHB 8-May-85>
|
||
SUB.L A0,A0 ;zero A0
|
||
MOVE.L A0,A1 ;and A1 too
|
||
MOVE.L A0,D0 ;set the z-flag
|
||
RTS ;return to caller
|
||
;
|
||
; we found the item so return a pointer to it in A0 and a pointer to the item properties in A1
|
||
;
|
||
GOTITEM TST.B (A1) ;is this the NIL item?
|
||
BEQ.S NOITEM ;if so, we really didn’t get one
|
||
|
||
MOVE.L A1,A0 ;A0 points to item string
|
||
MOVE.B (A1)+,D1 ;get length
|
||
ADD D1,A1 ;bump to item properties
|
||
RTS ;return to caller (z-clear)
|
||
ENDPROC
|
||
|
||
GetMCEntry PROC EXPORT ; <FJL C408>
|
||
;------------------------------------------------------------------------------------
|
||
;
|
||
; GetMCEntry <FJL C408>
|
||
;
|
||
;------------------------------------------------------------------------------------
|
||
; FUNCTION GetMCEntry(ID, Item : integer) : CMenuStruct --
|
||
; Find a color table entry for the given ID/Item combination. Return an index into
|
||
; the color table, or a zero if the entry wasn’t found.
|
||
;
|
||
move.l d2, -(sp) ; save work register
|
||
|
||
move.l MenuCInfo, a0 ; get color table handle
|
||
move.l (a0), a0 ; dereference
|
||
|
||
move 8(sp), d0 ; get Item
|
||
move 10(sp), d1 ; get ID
|
||
clr d2 ; start search at beginning of the table
|
||
|
||
IMPORT FindCEntry
|
||
bsr FindCEntry ; do the search
|
||
beq.s @NotFound ; oops couldn’t find it
|
||
|
||
lea (a0,d2), a0 ; get the table entry address in a0
|
||
move.l a0, 12(sp) ; return it as the result
|
||
bra.s @GetDone ; and return
|
||
|
||
@NotFound move.l #0, 12(sp) ; return zero as result
|
||
|
||
@GetDone move.l (sp)+, d2 ; restore work register
|
||
move.l (sp)+, a0 ; get return address
|
||
addq #4, sp ; strip the parameters
|
||
jmp (a0) ; and return
|
||
ENDPROC
|
||
|
||
DelMCEntries PROC EXPORT
|
||
;-------------------------------------------------------------------------------------
|
||
;
|
||
; DelMCEntries <FJL C408>
|
||
;
|
||
;-------------------------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE DelMCEntries (ID, Item : integer)
|
||
;
|
||
; Given an ID and Item number, this routine will find the appropriate
|
||
; entry in the menu color table and delete it. If the item number is
|
||
; equal to #mbAllItems (-98), then all items for the given ID will be deleted.
|
||
;
|
||
movem.l d2-d4, -(SP) ; save work registers
|
||
|
||
move 16(SP), d3 ; get Item number
|
||
move 18(SP), d4 ; get menuID
|
||
|
||
clr.l d2 ; start search at beginning of table
|
||
|
||
@DeleteLoop move d3, d0 ; set up for FindCEntry
|
||
move d4, d1
|
||
; Get MenuCInfo each time since munger chgs it <KSM BRC40826>
|
||
move.l MenuCInfo, a0 ; get handle to color table <KSM BRC40826>
|
||
move.l (a0), a0 ; dereference <KSM BRC40826>
|
||
IMPORT FindCEntry
|
||
bsr FindCEntry; find the entry
|
||
beq.s @DoneDelete ; z-flag set ==> couldn’t find it
|
||
|
||
; we have a match on both ID and Item so delete it using Munger
|
||
|
||
@DeleteIt subq #4, SP ; space for result
|
||
move.l MenuCInfo, -(SP) ; move the color table handle onto the stack
|
||
move.l d2, -(SP) ; d2 is offset into color table
|
||
pea (a0,d2) ; push ptr to target string
|
||
move.l #mctEntrySize, -(SP) ; len1 = 6 bytes
|
||
moveq #4, d0
|
||
move.l d0, -(SP) ; make replacement string non-NIL so deletes
|
||
; properly, point at an even byte in lo-mem
|
||
clr.l -(SP) ; and its length is zero ==> delete
|
||
_Munger
|
||
addq #4, SP ; ignore the result
|
||
|
||
; Don’t need to bump D2 because munger moved data down to where D2 points <KSM BRC40826>
|
||
; addi #mctEntrySize, d2 ; start looking at next table entry <KSM BRC40826>
|
||
cmpi #mctAllItems, d3 ; is the Item = "all items" flag?
|
||
beq.s @DeleteLoop ; yes, so loop
|
||
|
||
@DoneDelete
|
||
IMPORT MenuCTblSanityChk
|
||
bsr MenuCTblSanityChk ; check the table for consistency
|
||
movem.l (SP)+, d2-d4 ; restore work registers
|
||
move.l (SP)+, a0 ; get return address
|
||
addq #4, SP ; strip parameters
|
||
jmp (a0)
|
||
ENDPROC
|
||
|
||
FindCEntry PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility -- FindCEntry <FJL C408>
|
||
;-----------------------------------------------
|
||
; This utility will find the color table entry for the
|
||
; given ID and Item and table offset.
|
||
;
|
||
; Special case seaching: if ID = mctAllIds (=-97) ===> return any ID with correct Item
|
||
; if Item = mctAllItems (=-98) ===> return any Item with correct ID
|
||
;
|
||
; 1) If it finds the entry the z-flag will not be set and
|
||
; it returns an index into the table in d2.
|
||
; 2) If it doesn’t find the entry the z-flag will be set,
|
||
; and d2 will be the offset to the end of the table.
|
||
;
|
||
; On Entry: A0 ptr pointer to color table
|
||
; D0 Item item number looking for, if = mctAllItems (-98) then any item number
|
||
; D1 ID ID of menu looking for, if = mctAllIds (-97) then any ID number
|
||
; D2 offset offset into the table where we should start looking
|
||
;
|
||
; On Exit: D2 offset offset into the color table where the given ID/Item was found
|
||
; z-flag set if not found
|
||
;
|
||
; Called From:
|
||
cmpi #mctLastIDIndic, mctID(a0,d2) ; are we at the last entry?
|
||
beq.s @DoneFind ; yes, so branch
|
||
cmpi #mctAllIds, d1 ; are we finding all IDs for the given Item?
|
||
beq.s @CheckItem ; yes, so go and check Item for this entry
|
||
cmp mctID(a0,d2), d1 ; do we have a match with the given ID?
|
||
bne.s @CheckNextID ; no, so branch and try some more
|
||
|
||
; we have a match on the ID, so check if the Item matches
|
||
|
||
@CheckItem cmpi #mctAllItems, d0 ; are we finding all items for the given ID?
|
||
beq.s @DoneFind ; yes, so just grab this entry
|
||
cmp mctItem(a0,d2), d0 ; do we have a match with the Item?
|
||
beq.s @DoneFind ; yes, so branch and try some more
|
||
|
||
; didn’t find it so try the next item
|
||
|
||
@CheckNextID addi #mctEntrySize, d2 ; offset to next color table entry
|
||
bra FindCEntry ; and loop
|
||
|
||
@DoneFind cmpi #mctLastIDIndic, mctID(a0, d2) ; set z-flag if didn’t find the entry
|
||
rts ; (check if at last entry flag)
|
||
ENDPROC
|
||
|
||
SetMCEntries PROC EXPORT ; <FJL C408>
|
||
;------------------------------------------------------------------------------------
|
||
;
|
||
; SetMCEntries <FJL C408>
|
||
;
|
||
;------------------------------------------------------------------------------------
|
||
; PROCEDURE SetMCEntries(numEntries: integer; colorEntries: CMenuStruct) --
|
||
; Enter all of the given color entries in the menu color table. If an entry
|
||
; exists it will be replaced, if it’s new it will be added.
|
||
;
|
||
movem.l d2-d3, -(sp) ; save work register
|
||
move 16(sp), d3 ; get numEntries
|
||
subq #1, d3 ; sub 1 to get right offset to end of table
|
||
mulu #mctEntrySize, d3 ; start at last entry
|
||
|
||
; reuse the following code to reset registers that may have been trashed by Munger
|
||
; it’s just as easy to reset these each time thru, shouldn’t be a speed hit
|
||
|
||
@FindItLoop move.l 12(sp), a1 ; get ptr to colorEntries
|
||
|
||
move.l MenuCInfo, a0 ; get handle to color table
|
||
move.l (a0), a0 ; dereference
|
||
|
||
; first see if the entry exists in the table already
|
||
|
||
move mctID(a1,d3), d1 ; set up d0, d1 for FindCEntry call
|
||
move mctItem(a1,d3), d0
|
||
clr.l d2 ; d2 = 0 ===> start at top of table
|
||
IMPORT FindCEntry
|
||
bsr FindCEntry
|
||
beq.s @InsertEntry ; couldn’t find it so insert it
|
||
|
||
; found it in the table, so change the entry in place (table offset was returned in d2)
|
||
; store RGB1, 2, 3 and 4
|
||
add.l d3, a1
|
||
add.l d2, a0
|
||
exg a0, a1
|
||
moveq #mctEntrySize, d0
|
||
_BlockMove
|
||
|
||
;+++ move.l mctRGB1(a1,d3), mctRGB1(a0,d2) ; store RGB1
|
||
;+++ move mctRGB1+4(a1,d3), mctRGB1+4(a0,d2)
|
||
;+++ move.l mctRGB2(a1,d3), mctRGB2(a0,d2) ; store RGB2
|
||
;+++ move mctRGB2+4(a1,d3), mctRGB2+4(a0,d2)
|
||
;+++ move.l mctRGB3(a1,d3), mctRGB3(a0,d2) ; store RGB3
|
||
;+++ move mctRGB3+4(a1,d3), mctRGB3+4(a0,d2)
|
||
;+++ move.l mctRGB4(a1,d3), mctRGB4(a0,d2) ; store background color, don’t worry
|
||
;+++ move mctRGB4+4(a1,d3), mctRGB4+4(a0,d2) ; if this is wrong here, since we
|
||
; will make a sanity check later
|
||
bra.s @DoNextEntry ; loop to the next entry
|
||
|
||
; didn’t find entry so insert it at the end of the table, this is good because this forces the
|
||
; first entry to always be the menubar entry (if there is one) and since that is the most
|
||
; frequently accessed entry it is best to have it in the front.
|
||
|
||
@InsertEntry subq #4, sp ; save space for result
|
||
move.l MenuCInfo, -(sp) ; move the color table handle onto the stack
|
||
move.l d2, -(sp) ; d2 is offset to the end of the color table
|
||
clr.l -(sp) ; no target string
|
||
clr.l -(sp) ; len1 = 0 ===> want to insert
|
||
pea (a1,d3) ; push ptr to insertion string
|
||
move.l #mctEntrySize, -(sp) ; and it’s length
|
||
_Munger
|
||
addq #4, sp ; ignore the result
|
||
|
||
@DoNextEntry subi #mctEntrySize, d3 ; go to next entry
|
||
bge.s @FindItLoop ; if > or = 0 then continue
|
||
|
||
@SetMenuColorDone
|
||
IMPORT MenuCTblSanityChk
|
||
bsr MenuCTblSanityChk ; look thru color table and clean it all up
|
||
movem.l (sp)+, d2-d3 ; restore work register
|
||
move.l (sp)+, a0 ; get return address
|
||
addq #6, sp ; strip parameters
|
||
jmp (a0) ; and return
|
||
ENDPROC
|
||
|
||
ClearSanityChks PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility within a Utility -- ClearSanityChks <FJL C408>
|
||
;-----------------------------------------------
|
||
; Cruise thru the color table, and clear the mctSanityChk
|
||
; field for every entry. Later we will set this field as
|
||
; we update entries during the sanity chk. Ones that
|
||
; weren’t checked were missed, and will be handled in a
|
||
; second pass where default colors will be entered.
|
||
move.l MenuCInfo, a0 ; get color table handle
|
||
move.l (a0), a0 ; dereference
|
||
clr d2 ; start at top of table
|
||
|
||
@ClearLoop cmpi #mctLastIDIndic, mctID(a0,d2) ; are we at the last entry?
|
||
beq.s @ClearDone ; yes, so we’re done
|
||
clr mctReserved(a0,d2) ; no, so clear the sanity check field <1.9>
|
||
addi #mctEntrySize, d2 ; bump index to next entry
|
||
bra.s @ClearLoop ; and loop
|
||
|
||
@ClearDone rts
|
||
ENDPROC
|
||
|
||
MenuCTblSanityChk PROC ENTRY
|
||
;-----------------------------------------------
|
||
; Utility -- MenuCTblSanityChk <FJL C408>
|
||
;-----------------------------------------------
|
||
; Check thru the whole color table and be sure all
|
||
; of the entries are consistent:
|
||
; 1) Item = 0 ===> title, so store menu bar color in mctRGB2 slot
|
||
; 2) Item != 0 ==> not title, so store menu background color in mctRGB4 slot
|
||
;
|
||
CkMBColor EQU -6 ; RGB for menu bar
|
||
CkBackColor EQU CkMBColor - 6 ; RGB for current ID’s background color
|
||
CkIDSave EQU CkBackColor - 2 ; save d2 as we loop thru Items for an ID
|
||
CkFrame EQU CkIDSave ; size of stackframe
|
||
|
||
link a6, #CkFrame ; set up a stack frame
|
||
move.l d2, -(sp) ; save work register
|
||
|
||
IMPORT ClearSanityChks
|
||
bsr ClearSanityChks ; clear sanity checks for all table entries
|
||
|
||
move.l MenuCInfo, a0 ; get table handle
|
||
move.l (a0), a0 ; dereference
|
||
|
||
; 1) Find menubar color. Menubar has ID == 0, Item == 0, and menubar color is stored in
|
||
; mctRGB4 field. It should be copied to RGB2 field for every title entry (Item == 0)
|
||
|
||
clr d0 ; Item 0
|
||
clr d1 ; ID 0
|
||
clr d2 ; start at beginning of table
|
||
IMPORT FindCEntry
|
||
bsr FindCEntry
|
||
bne.s @GotMBColor ; found it so get color
|
||
|
||
; didn’t find menu bar entry, so use default menubar color -- white
|
||
|
||
moveq #-1, d0
|
||
move.l d0, CkMBColor(a6) ; set RG
|
||
move d0, CkMBColor+4(a6) ; set B
|
||
bra.s @1 ; and branch
|
||
|
||
; get color we found
|
||
|
||
@GotMBColor move.l mctRGB4(a0,d2), CkMBColor(a6) ; set R & G
|
||
move mctRGB4+4(a0,d2), CkMBColor+4(a6) ; set B
|
||
|
||
@1 addq.w #1, mctReserved(a0,d2) ; set sanity check field <1.9>
|
||
|
||
; 2) Find each title entry (Item = 0), set its menubar color, get its background color and
|
||
; save it in the stackframe, then find each of its items and set their background colors
|
||
|
||
clr CkIDSave(a6) ; start at top of table
|
||
|
||
@IDLoop clr d0 ; Item 0
|
||
move #mctAllIds, d1 ; any ID
|
||
move CkIDSave(a6), d2 ; get saved d2 value
|
||
bsr FindCEntry ; look for the next title entry in the table
|
||
beq.s @SecondPass ; z-flag set means we hit the end of the table
|
||
|
||
move d2, CkIDSave(a6) ; save d2 since we’ll want to start there next time
|
||
addi #mctEntrySize, CkIDSave(a6) ; actually want to start at NEXT entry!
|
||
addq #1, mctReserved(a0,d2) ; set sanity check field <1.9>
|
||
|
||
tst mctID(a0,d2) ; did we get the menu bar entry?
|
||
beq.s @IDLoop ; yes, skip it and continue
|
||
|
||
move.l CkMBColor(a6), mctRGB2(a0,d2) ; set title menubar color R & G
|
||
move CkMBColor+4(a6), mctRGB2+4(a0,d2) ; set title menubar color B
|
||
move.l mctRGB4(a0,d2), CkBackColor(a6) ; get menu background color R & G
|
||
move mctRGB4+4(a0,d2), CkBackColor+4(a6) ; get menu background color B
|
||
|
||
move mctID(a0,d2), d1 ; put ID we found in d1
|
||
move #mctAllItems, d0 ; find any Item with that ID
|
||
clr d2 ; start at beginning of the table
|
||
|
||
@ItemLoop bsr FindCEntry ; look for an entry
|
||
beq.s @IDLoop ; got the end of the table, so find the next ID
|
||
addq.w #1, mctReserved(a0,d2) ; set sanity check field <1.9>
|
||
|
||
tst mctItem(a0,d2) ; did we get the title entry?
|
||
beq.s @NextItemSetUp ; yes, so skip this entry and continue
|
||
|
||
move.l CkBackColor(a6), mctRGB4(a0,d2) ; set Item background R & G
|
||
move CkBackColor+4(a6), mctRGB4+4(a0,d2) ; set Item background B
|
||
|
||
@NextItemSetUp addi #mctEntrySize, d2 ; start next Item search at NEXT table entry
|
||
bra.s @ItemLoop
|
||
|
||
; 3) It’s possible that there are Items in the table that have no title entry -- these
|
||
; items would have zero in the SanityCheck field. So for every entry with SanityCheck = 0
|
||
; set the background color to the menu bar default, or white if there is no default.
|
||
|
||
@SecondPass
|
||
clr d0 ; Item 0
|
||
clr d1 ; ID 0
|
||
clr d2 ; start at beginning of table
|
||
bsr FindCEntry
|
||
bne.s @GotMBColor2 ; found it so get color
|
||
|
||
; didn’t find menu bar entry, so use default background color -- white
|
||
|
||
moveq #-1, d0
|
||
move.l d0, CkBackColor(a6) ; set RG
|
||
move d0, CkBackColor+4(a6) ; set B
|
||
bra.s @2 ; and branch
|
||
|
||
; save the color we found in the stackframe
|
||
|
||
@GotMBColor2 move.l mctRGB2(a0,d2), CkBackColor(a6) ; set R & G
|
||
move mctRGB2+4(a0,d2), CkBackColor+4(a6) ; set B
|
||
|
||
@2 clr d2 ; start search at beginning of color table
|
||
@SecondPassLoop
|
||
bsr.s FindSanityChks ; get the next one that wasn’t set
|
||
beq.s @SanityDone ; z-flag set means end of table, so done
|
||
|
||
; found one, so set its background color
|
||
move.l CkBackColor(a6), mctRGB4(a0,d2) ; set R & G
|
||
move CkBackColor+4(a6), mctRGB4+4(a0,d2) ; set B
|
||
|
||
addi #mctEntrySize, d2 ; skip to next table entry
|
||
bra.s @SecondPassLoop ; and find the next one
|
||
|
||
@SanityDone move.l (sp)+, d2 ; restore work register
|
||
unlk a6 ; toss the stack frame
|
||
rts
|
||
|
||
FindSanityChks
|
||
;-----------------------------------------------
|
||
; Utility within a Utility -- FindSanityChks <FJL C408>
|
||
;-----------------------------------------------
|
||
; Cruise thru the color table, and find the next
|
||
; entry whose SanityCheck field in zero.
|
||
cmpi #mctLastIDIndic, mctID(a0,d2) ; are we at the last entry?
|
||
beq.s @FindDone ; yes, so we’re done
|
||
tst mctReserved(a0,d2) ; is the sanity field set? <1.9>
|
||
beq.s @FoundEntry ; nope, so branch
|
||
addi #mctEntrySize, d2 ; yes, so bump index to next entry
|
||
bra.s FindSanityChks ; and loop
|
||
|
||
@FoundEntry moveq #1, d0 ; z-flag not set tells caller that we found an entry
|
||
|
||
@FindDone rts
|
||
ENDPROC
|
||
|
||
PROC
|
||
|
||
;-----------------------------------------------
|
||
; MenuKey Stack Frame Definitions
|
||
;-----------------------------------------------
|
||
;
|
||
CmdChar EQU 9 ; command char is in lo-byte of param [byte/word]
|
||
MenuResult EQU 10 ; menu ID part of result
|
||
mItemResult EQU 12 ; Item part of result
|
||
|
||
searchMenu EQU -8 ; looking for the parent of...
|
||
HorRMenus EQU searchMenu - 2 ; looking thru HMenus (=0), or Regular Menus (=1)
|
||
KeyFrame EQU HorRMenus - 2
|
||
|
||
; Utility UpChar -- Upshift the character in D0
|
||
; Given a character in D0, it uses the UprString routine to upshift the char
|
||
; (stripping diacriticals) and returns it in D0
|
||
UpChar
|
||
MOVE.B D0,-(SP) ; push character <EHB 15-Apr-85>
|
||
|
||
;<SM5> <PN> Use the following for SuperMario
|
||
move.l sp,-(sp) ; push text ptr <19>
|
||
move.w #1,-(sp) ; push length <19>
|
||
move.w #smSystemScript,-(sp) ; use system script, ignore port <19>
|
||
_SCUpperText ; (stack based!) <19>
|
||
|
||
MOVE.B (SP)+,D0 ; return shifted character <EHB 15-Apr-85>
|
||
RTS
|
||
|
||
EXPORT MENUKEY
|
||
MENUKEY
|
||
;------------------------------------------------------------------------------------------------
|
||
;
|
||
; MenuKey -- determine if a command key is valid and if so what menu and item it refers to
|
||
;
|
||
;------------------------------------------------------------------------------------------------
|
||
;
|
||
; FUNCTION MenuKey(commandChr): LongInt -- menuKey is kind of a companion routine to
|
||
; MenuSelect; it is called when a command character is typed and scans the current
|
||
; menu data structure, returning a (whichMenu, whichItem) pair that corresponds to the
|
||
; selected command. If a command is not recognized, the result returned is zero
|
||
;
|
||
; Check thru the regular menus first, then the hierarchical menus. Use D6 as flag <FJL C222>
|
||
; so we know whether checking regular or H Menus
|
||
;
|
||
; Hilite the "parent" menu when a hierarchical menu is chosen. <FJL C222>
|
||
|
||
link a6, #KeyFrame ; set up stackframe
|
||
MOVEM.L D3-D6/A3,-(SP) ;save work registers
|
||
|
||
move.b CmdChar(a6), d0 ; get character to search for
|
||
BSR.S UpChar ; upshift in D0 <EHB 15-Apr-85>
|
||
MOVE.B D0,D4 ; and save in D4 <EHB 15-Apr-85>
|
||
|
||
IMPORT GetA0List
|
||
bsr GetA0List ; get menuList pointer into A0
|
||
move lastMenu(a0), d5 ; go to last menu
|
||
clr d6 ; zero flag == checking regular menus <FJL C222>
|
||
|
||
; here is the outer loop where each menu in the menuList is considered
|
||
|
||
KEYBARLOOP BSR GETMENUPTR ;get menu pointer in A0 from index in D5
|
||
MOVE.L A0,A3 ;stash in A3 for safe keeping
|
||
BTST #0,MENUENABLE+3(A3) ;is this menu enabled?
|
||
BEQ.S NEXTBAR ;if not, skip it
|
||
MOVEQ #1,D3 ;start with item number 1
|
||
;
|
||
; here is the inner loop where each item is considered
|
||
;
|
||
KEYITEMLOOP MOVE.L MENUENABLE(A3),D0 ;get enable flags
|
||
BTST D3,D0 ;make sure this item is enabled
|
||
BEQ.S KEYNEXTITEM ;if not, skip it
|
||
|
||
EnabledKeyItemLoop ; <10> Loops to here when item in D3 > 31
|
||
MOVE.L A3,A0 ;get menuPtr in A0
|
||
MOVE D3,D0 ;get item number in D0
|
||
IMPORT GetItemRecord
|
||
BSR GETITEMRECORD ;search for item
|
||
BEQ.S NEXTBAR ;if not, this menu is exhausted
|
||
|
||
MOVE.B ItemCmd(A1),D0 ;get the command char
|
||
BEQ.S KEYNEXTITEM ; don’t upshift if there is no cmd-key
|
||
BSR.S UpChar ; upshift it in D0 <EHB 11-Apr-85>
|
||
|
||
;NOTE: We’ve reserved the values $1B thru $1F in cmdItem as having meanings other than <FJL C222>
|
||
; than that of a command key.
|
||
; Value: $1B (HMenuCmd) - item has hierarchical menu
|
||
; (menuID of HMenu is in itemMark field)
|
||
; $1C (ScriptMenuCmd) - item has script defined
|
||
; (script number is in itemIcon field)
|
||
; $1D - $1F - undefined at this time
|
||
;
|
||
|
||
cmpi.b #FirstAltMenuCmd, d0 ; item between $1B and $1F? <FJL C222>
|
||
blt.s @DoCompare ; no, so continue <FJL C222>
|
||
cmpi.b #LastAltMenuCmd, d0 ; <FJL C222>/<C338>
|
||
bhi.s @DoCompare ; no, so continue <FJL C222>
|
||
bra.s KeyNextItem ; if here then cmdItem is between <FJL C222>
|
||
; $1B and $1F so skip comparison <FJL C222>
|
||
|
||
@DoCompare CMP.B D0,D4 ;do they match?
|
||
BEQ.S GOTMKEY ;if they do, we’ve found it!
|
||
|
||
KEYNEXTITEM ADDQ #1,D3 ;bump to next item
|
||
CMPI.W #31,D3 ;<10> items > 31 are always enabled
|
||
BHI.S EnabledKeyItemLoop ;<10> so skip moving the flags and the btst
|
||
BRA.S KEYITEMLOOP ;loop till we find it or no more
|
||
|
||
NEXTBAR subq #6, d5 ; bump to next item
|
||
cmp d6, d5 ; have we reached the value in d6?
|
||
bgt.s KeyBarLoop ; loop till we reach it
|
||
|
||
tst d6 ; does d6 have a value? <FJL C222>
|
||
bne.s KeyNotFound ; yes, so have checked regular AND HMenus <FJL C222>
|
||
;
|
||
; d6 was equal to zero, so now check thru the hierarchical menus
|
||
;
|
||
IMPORT GetHA0List
|
||
bsr GetHA0List ; get HMenuList ptr in A0
|
||
move lastHMenu(a0), d5 ; get #HMenus
|
||
beq.s KeyNotFound ; none, so don’t check ’em
|
||
|
||
; yes there are menus so check them backwards
|
||
move.l MinusOne, d1 ; set up for GetHIndex call
|
||
IMPORT GetHIndex
|
||
bsr GetHIndex ; d0 now has ptr to HMenuList header info
|
||
add d0, d5 ; d5 points at last HMenu
|
||
move d0, d6 ; d6 points at HMenuList header
|
||
bra.s KeyBarLoop ; and start checking
|
||
;
|
||
; no corresponding command key was found, so return zero as the result
|
||
;
|
||
KEYNOTFOUND clr.l menuResult(a6) ; clear the function result -- menu and item
|
||
MKEYDONE MOVEM.L (SP)+,D3-D6/A3 ; restore work registers
|
||
unlk a6 ; dismantle the stack frame
|
||
IMPORT TwoBytExit
|
||
BRA TWOBYTEXIT ; standard exit saves code
|
||
;
|
||
; we got a good key so return the result (whichMenu, whichItem)
|
||
;
|
||
GOTMKEY BSR GETMENUPTR ;get pointer to correct menuID
|
||
|
||
move menuID(a0), menuResult(a6) ; store the menuID <FJL C222>
|
||
move d3, mItemResult(a6) ; and the Item <FJL C222>
|
||
|
||
move menuResult(a6), searchMenu(a6) ; init searchMenu(a6) <FJL C222>
|
||
tst d6 ; is d6 clear? <FJL C222>
|
||
beq.s @HiliteMBar ; yes, so was a regular menu <FJL C222>
|
||
|
||
clr HorRMenus(a6) ; init HorRMenus(a6) to HMenus <FJL C222>
|
||
moveq #8, d4 ; d4 is recursive test counter
|
||
bsr.s FindParentMenu ; no, so find the HMenu’s parent <FJL C222>
|
||
|
||
@HiliteMBar MOVE searchMenu(a6),-(SP) ;push menuID as parameter <FJL C222>
|
||
_HiliteMenu ;hilite it
|
||
;
|
||
; check to see if this one belongs to a desk ornament
|
||
;
|
||
TST MBarEnable ;does desk ornament own menuBar?
|
||
BMI.S @DeskMKey ;if so, handle it
|
||
|
||
;+++ move.l menuResult(a6), d0 ; if theMenu negative?
|
||
; Can’t just use menuResult(a6) since could<FJL 09Mar87>
|
||
; be a HMenu associated with the desk acc<FJL 09Mar87>
|
||
tst TheMenu ; Is it a system menu? <FJL 09Mar87>
|
||
BPL.S MKEYDONE ;if not, we’re done
|
||
;
|
||
; the menu belonged to a desk ornament so tell the desk manager about it
|
||
;
|
||
; HMenus cause problems here. Since the menu ID (funcResult) is not = to the DA’s <FJL 09Mar87>
|
||
; menu ID, SystemMenu will never find the DA in the DA list. To force it to pass
|
||
; the HMenu ID we can set MBarEnable temporarily.
|
||
;
|
||
; Need to allow a DA that owns the menu bar to reset MBarEnable in the middle of _SystemMenu <FJL PMAB280>
|
||
; Had to move around some parts of this routine. Only set/clear MBarEnable when MBar not
|
||
; already owned by DA.
|
||
;
|
||
@DeskMKey
|
||
tst.w MBarEnable ; who owns menu bar?
|
||
bmi.s @1 ; desk acc ==> we’re cool
|
||
|
||
move TheMenu, MBarEnable ; set MBarEnable with DA’s ID
|
||
move.l menuResult(a6),-(sp) ; push the result
|
||
_SystemMenu ; invoke desk manager
|
||
clr.l menuResult(a6) ; pretend we didn’t get anything
|
||
; NOTE: clears funcResult AND itemResult !!!
|
||
clr.w MBarEnable ; clear MBarEnable
|
||
bra.s MKeyDone
|
||
|
||
@1 move.l menuResult(a6),-(sp) ; push the result
|
||
_SystemMenu ; invoke desk manager
|
||
clr.l menuResult(a6) ; pretend we didn’t get anything
|
||
; NOTE: clears funcResult AND itemResult !!!
|
||
BRA.S MKEYDONE ;all done
|
||
|
||
FindParentMenu
|
||
;-----------------------------------------------
|
||
; Utility -- FindParentMenu <FJL C222>
|
||
;-----------------------------------------------
|
||
;
|
||
; We have a hierarchical menu, so we need to find its regular menu "parent" and hilite it.
|
||
; It could be several levels of hierarchy deep, so look thru the HMenus until
|
||
; we don’t find it, then look thru the regular menus to get the parent. This code
|
||
; doesn’t allow recursively defined menus, it stops looking after 8 menus (I didn’t want
|
||
; to test the boundary condition of whether it is 5 or 6 or 7 that should stop at with
|
||
; five levels of hierarchy, so just made it 8 to be safe).
|
||
;
|
||
; Allowed a hierarchical menu to not have a parent in the menubar. Did this so <FJL 26Mar87>
|
||
; that could have menu keys on popup menus.
|
||
;
|
||
subq #1, d4 ; reduce recursive count
|
||
beq.s @NoParent ; got to zero, so must be recursive
|
||
|
||
IMPORT GetHA0List
|
||
bsr GetHA0List ; get HMenuList ptr in A0
|
||
move lastHMenu(a0), d5 ; get #HMenus
|
||
; we know there are HMenus so check them backwards
|
||
move.l MinusOne, d1 ; set up for GetHIndex
|
||
IMPORT GetHIndex
|
||
bsr GetHIndex ; d0 now has index to HMenuList header info
|
||
add d0, d5 ; d5 has index to last HMenu
|
||
move d0, d6 ; d6 has index to HMenuList header
|
||
@MenuLoop
|
||
bsr GetMenuPtr ; get menu ptr in A0 from ID in D5
|
||
move.l a0, a3 ; stash in A3 for safe keeping
|
||
moveq #1, d3 ; start with item number 1
|
||
;
|
||
; inner loop where each item is considered
|
||
;
|
||
@ItemLoop move.l a3, a0 ; set up for GetItemRecord, put menuPtr in a0
|
||
move.l d3, d0 ; and put item number in d0
|
||
IMPORT GetItemRecord
|
||
bsr GetItemRecord ; search for item
|
||
beq.s @NextMenu ; if not, this menu is exhausted
|
||
|
||
cmpi.b #HMenuCmd, itemCmd(a1) ; does this menu have a HMenu?
|
||
bne.s @NextItem ; no, so keep looking
|
||
|
||
moveq #0, d1 ; clear d1
|
||
move.b itemMark(a1), d1 ; get menuID of HMenu for this item
|
||
cmp searchMenu(a6), d1 ; is this the menu we are looking for?
|
||
bne.s @NextItem ; no, so keep looking
|
||
|
||
move menuID(a3), searchMenu(a6) ; found a parent so save it
|
||
tst HorRMenus(a6) ; still searching HMenus?
|
||
beq.s FindParentMenu ; yes, so try again with the parent menuID
|
||
bra.s @FindParentEnd ; no, so found oldest ancestor amongst regular menus
|
||
|
||
@NextItem addq #1, d3 ; go to next item
|
||
bra.s @ItemLoop
|
||
|
||
@NextMenu subq #6, d5 ; bump to next menu
|
||
cmp d6, d5 ; at end of list?
|
||
bgt.s @MenuLoop ; no, so try the next menu
|
||
;
|
||
; if we’re here then have exhausted HMenuList without finding a parent, so we now search
|
||
; the regular menu list to find the oldest ancestor of the HMenu being returned as the result.
|
||
;
|
||
tst HorRMenus(a6) ; HorRMenus = 0 means just finished checking
|
||
; hierarchical menus, try regular menus <FJL 26Mar87>
|
||
beq.s @WereOK
|
||
bra.s @FindParentEnd ; HorRMenus = 1 means finished checking <FJL 26Mar87>
|
||
; regular menus, stop trying, and return
|
||
|
||
@NoParent move #dsHMenuFindErr, d0 ; error code for recursive menus <FJL 26Mar87>
|
||
_SysError
|
||
|
||
@WereOK addq #1, HorRMenus(a6) ; flag that searching regular menus
|
||
IMPORT GetA0List
|
||
bsr GetA0List ; get menuList ptr into A0
|
||
move lastMEnu(a0), d5 ; go to last regular menu
|
||
clr d6 ; stop searching when index == 0
|
||
bra.s @MenuLoop ; go find it
|
||
|
||
@FindParentEnd
|
||
rts
|
||
ENDPROC
|
||
|
||
GETITEM PROC EXPORT
|
||
;
|
||
; PROCEDURE GetItem(menuHandle,itemNumber,VAR string); -- get the text of a menu item
|
||
;
|
||
MOVE.L 10(SP),A0 ;get menuInfo handle
|
||
MOVE.L (A0),A0 ;handle to pointer
|
||
MOVE.W 8(SP),D0 ;get item number
|
||
IMPORT GetItemRecord
|
||
BSR GETITEMRECORD ;look it up
|
||
;
|
||
MOVE.L 4(SP),A1 ;get result stringPtr,(zflag preserved)
|
||
BEQ.S NOITEM1 ;if not, return empty string
|
||
;
|
||
; use blockMove to copy the string
|
||
;
|
||
MOVEQ #0,D0 ;clear out D0
|
||
MOVE.B (A0),D0 ;get length of string
|
||
ADDQ #1,D0 ;move length byte, too
|
||
_BLOCKMOVE ;let memory manager move it fast
|
||
DONEGI
|
||
IMPORT TenBytExit
|
||
BRA TENBYTEXIT ;standard exit saves code
|
||
;
|
||
; item not found, so return the null string
|
||
;
|
||
NOITEM1 CLR.B (A1) ;set result string length to zero
|
||
BRA.S DONEGI ;standard exit saves code
|
||
ENDPROC
|
||
|
||
NEWMENU PROC EXPORT
|
||
;
|
||
; FUNCTION NewMenu(menuID,titleString):menuHandle -- allocate a new menu block with
|
||
; the specified menuID and title.
|
||
;
|
||
MOVEQ #0,D1 ;clear out the high part
|
||
MOVEQ #MenuBlkSize+2,D0 ;get size of menuInfo block
|
||
MOVE.L 4(SP),A0 ;point to the title string
|
||
MOVE.B (A0),D1 ;get its length
|
||
ADD.W D1,D0 ;compute real length
|
||
_NEWHANDLE ;allocate it
|
||
MOVE.L A0,10(SP) ;return menuHandle as result
|
||
MOVE.L (A0),A1 ;get menu pointer
|
||
|
||
MOVE.W D1,-(SP) ;save title size for later
|
||
;
|
||
; initialize the fields of the menu definition record
|
||
;
|
||
MOVE.W 10(SP),(A1)+ ;init menuID
|
||
CLR.L (A1)+ ;zero width and heigth initially
|
||
|
||
; initialize the menu defProc handle
|
||
|
||
MOVEQ #0,D0 ; standard rom based MDEF is #0
|
||
|
||
SUBQ #4,SP ;make room for function result
|
||
MOVE.L #'MDEF',-(SP) ;push MDEF resource type
|
||
move.W d0, -(SP) ;push the rsrcID <TESTX>
|
||
MOVE.W #MapTRUE,ROMMapInsert ;get MDEF 0 from the ROM Map <9 July 85>
|
||
_GetResource ;get it
|
||
MOVE.L (SP)+,A0 ;get mDef handle in A0
|
||
|
||
; since GetResource can allocate memory, better rebuild the ptr from its handle
|
||
|
||
MOVE.L 12(SP),A1 ;get menuHandle
|
||
MOVE.L (A1),A1 ;get menuPtr
|
||
ADDQ #MenuDefHandle,A1 ;bump to defHandle
|
||
MOVE.L A0,(A1)+ ;install menuProc
|
||
|
||
MOVE.L MinusOne,(A1)+ ;everything’s enabled to start
|
||
;
|
||
; move in the title string
|
||
|
||
MOVE.W (SP)+,D1 ;get length of string
|
||
MOVE.L 4(SP),A0 ;get string ptr
|
||
|
||
@1 MOVE.B (A0)+,(A1)+ ;move in the string
|
||
DBRA D1,@1 ;loop till done
|
||
;
|
||
; add the string of length zero on the end
|
||
;
|
||
CLR.B (A1)+ ;string of length zero
|
||
IMPORT SixBytExit
|
||
BRA SIXBYTEXIT ;all done -- standard exit saves code
|
||
ENDPROC
|
||
;
|
||
; AppendMenu Stack Frame Definition
|
||
;
|
||
ITEMPROPERTIES EQU -280 ;4 attribute bytes of item
|
||
ITEMSTATE EQU ITEMPROPERTIES+4 ;one byte parse state field
|
||
ITEMFLAGS EQU ITEMSTATE+1 ;one byte enable flag field
|
||
ITEMCOUNT EQU ITEMFLAGS+1 ;integer -- number of chars in buffer
|
||
ITEMBUFFER EQU ITEMCOUNT+2 ;256 byte buffer for items
|
||
;+4 for copying properties
|
||
ItemFontNum EQU ItemProperties - 2 ; use for GetFNum call <FJL CXXX>
|
||
FontFondFlag EQU ItemFontNum - 2 ; 0 = not font/fond, 1 = font/fond <FJL CXXX>
|
||
ItemLinkSize EQU FontFondFlag ; <FJL CXXX>
|
||
|
||
APPENDMENU PROC EXPORT
|
||
;
|
||
; PROCEDURE AppendMenu(menuHandle,itemString) -- add the list of items represented by
|
||
; the item string to the menu. The itemString may contain one or more items, seperated
|
||
; by carriage returns or semicolon characters. The item strings are also scanned for
|
||
; special meta-characters that change their initial properties.
|
||
|
||
MOVE.L (SP)+,A0 ; add an "afterItem" param so <EHB 8-May-85>
|
||
MOVE.W #999,-(SP) ; it looks like an InsMenuItem call <EHB 8-May-85>
|
||
MOVE.L A0,-(SP) ; and fall into InsMenuItem <EHB 8-May-85>
|
||
|
||
EXPORT INSMENUITEM
|
||
INSMENUITEM ; <EHB 8-May-85>
|
||
; PROCEDURE InsMenuItems(MenuHandle: Handle; itemstring: str255; itemNum: INTEGER)
|
||
; -- insert the items in the itemstring after the specified item (to insert at
|
||
; beginning, pass item of 0). ItemString is parsed just like the itemstring in
|
||
; AppendMenu. Multiple items are inserted in the reverse of their order in the
|
||
; string.
|
||
IMPORT TenBytExit
|
||
TST.L 6(SP) ; Is the StringPtr NIL? <8>
|
||
BEQ.S @PixelPaintError ; EQ means it is - BAIL <8>
|
||
MOVE.L 10(SP),D0 ; Is the menuHandle NIL? <8>
|
||
BEQ.S @PixelPaintError ; EQ means it is, bail <8>
|
||
BTST #0,D0 ; Is the handle odd? <8>
|
||
BNE.S @PixelPaintError ; NE means it is odd, bail <8>
|
||
|
||
LINK A6,#ItemLinkSize ; allocate local space
|
||
MOVEM.L D3-D7/A2-A4,-(SP) ; save some work registers
|
||
|
||
MOVE.L 10(A6),A4 ; get itemString ptr in A4
|
||
MOVE.L 14(A6),A3 ; get menuHandle in A3
|
||
MOVE.W 8(A6),D6 ; get insert point in D6
|
||
ADDQ #1,D6 ; make it a true index
|
||
IMPORT AddString
|
||
BSR AddString ; make menu items out of the string
|
||
|
||
MOVEM.L (SP)+,D3-D7/A2-A4 ; restore the registers
|
||
UNLK A6 ; unbuild the stack frame
|
||
@PixelPaintError ; <6>
|
||
BRA TenBytExit ; standard exit save code
|
||
ENDPROC
|
||
|
||
AddString PROC ENTRY
|
||
; AddString parses the specified string, placing it into the ITEMBUFFER, and setting up
|
||
; the other item properties. When it encounters the end of an item, it transfers
|
||
; it from the buffer into the menu.
|
||
|
||
; On Entry: A3 MenuHandle
|
||
; A4 ItemString pointer
|
||
; D6 Item to insert before
|
||
|
||
; CLR D3 ; <PMAB568 07Sep88 EMT>
|
||
; MOVE.B (A4)+,D3 ;get length of itemString <PMAB568 07Sep88 EMT>
|
||
|
||
IMPORT InitItem
|
||
BSR INITITEM ; initialize local buffer for new item
|
||
; SUBQ #1,D3 ; bias for DBRA loop <PMAB568 07Sep88 EMT>
|
||
MOVEQ.L #0, D3 ; Initialize counter <PMAB568 07Sep88 EMT>
|
||
BRA.S EndApLoop ; Go to end of loop <PMAB568 07Sep88 EMT>
|
||
;
|
||
; process each character in the itemString, one character at a time
|
||
;
|
||
APLOOP
|
||
SUBQ.L #2, SP ; Make room for result <PMAB568 07Sep88 EMT>
|
||
MOVE.L A4, -(SP) ; textBuf pointer <PMAB568 07Sep88 EMT>
|
||
MOVE.W D3, -(SP) ; textOffset <PMAB568 07Sep88 EMT>
|
||
_CharByte ; <PMAB568 07Sep88 EMT>
|
||
MOVE.W (SP)+, D2 ; Stuff result into D2 <PMAB568 07Sep88 EMT>
|
||
MOVE.B (A4, D3), D0 ;get next character <PMAB568 07Sep88 EMT>
|
||
IMPORT AppendChar
|
||
BSR APPENDCHAR ;process it
|
||
|
||
; DBRA D3,APLOOP ;process each character <PMAB568 07Sep88 EMT>
|
||
EndApLoop ; <PMAB568 07Sep88 EMT>
|
||
ADDQ.L #1, D3 ; Increment character index <PMAB568 07Sep88 EMT>
|
||
CMP.B (A4), D3 ; Done yet? <PMAB568 07Sep88 EMT>
|
||
BLS.S APLOOP ; Nope, continue <PMAB568 07Sep88 EMT>
|
||
|
||
IMPORT CloseItem
|
||
BSR CLOSEITEM ;close out any item that may be open
|
||
|
||
MOVE.L A3,-(SP) ; push menu handle
|
||
IMPORT DirtyMenuSize
|
||
BSR DirtyMenuSize ; invalidate size <EHB 5-Mar-85>
|
||
RTS
|
||
ENDPROC
|
||
|
||
INITITEM PROC ENTRY
|
||
;
|
||
; InitItem initializes the item buffer
|
||
;
|
||
LEA ITEMPROPERTIES(A6),A0 ;get address of item properties
|
||
CLR.L (A0)+ ;clear property parameters
|
||
CLR.L (A0) ;clear out state/flags/count
|
||
RTS
|
||
ENDPROC
|
||
|
||
APPENDCHAR PROC ENTRY
|
||
; AppendChar does all the real work. It processes the character in D0 by checking out
|
||
; what state its in. If in a command state, it uses the character to update a
|
||
; property byte. In normal state, characters go into a buffer that is added to the
|
||
; menu when a carriage return or semicolon is scanned
|
||
;
|
||
MOVEQ #0,D1
|
||
MOVE.B ITEMSTATE(A6),D1 ;get current state
|
||
BEQ.S NORMSTATE ;if normal state, go handle it
|
||
;
|
||
CMP.B #ITEMICON+1,D1 ;is it an icon item?
|
||
BNE.S @1 ;if not,skip
|
||
SUB #$30,D0 ;adjust ASCII
|
||
;
|
||
@1 CMP.B #ITEMSTYLE+1,D1 ;is it a style?
|
||
BNE.S UPDATEPROP ;handle style characters special
|
||
;
|
||
; handle style properties special by scanning table and oring bits
|
||
;
|
||
MOVEQ #4,D2 ;start at last one
|
||
@2 CMP.B STYLECHRTAB(D2),D0 ;is it in the table?
|
||
BEQ.S ADDTOSTYLE ;if so, modify D0
|
||
DBRA D2,@2 ;bump to next one
|
||
;
|
||
; if its not in table, just ignore it
|
||
;
|
||
RTS
|
||
;
|
||
; Meta character definition table -- this table defines which meta-character
|
||
; perform what functions; the order is icon,command,mark,style,delimiter,delimiter,
|
||
; disable.
|
||
;
|
||
MCHARTABLE DC.B '^' ;arrow is the icon character
|
||
DC.B '/' ;slash is command character
|
||
DC.B '!' ;exclamation point is mark character
|
||
DC.B '<' ;less-than is the style character
|
||
DC.B $0D ;carriage return is one delimiter
|
||
DC.B ';' ;semi-colon is the other
|
||
DC.B '(' ;leftParen is disable character
|
||
dc.b HMenuCmd ;hierarchical menu character ($1B) <FJL C222>
|
||
|
||
;****** BE SURE THE ABOVE TABLE IS OF EVEN LENGTH IF YOU ADD NEW SYMBOLS *********
|
||
|
||
;
|
||
; style character table
|
||
;
|
||
STYLECHRTAB DC.B 'BIUOS' ;bold,italic,underline,outline,shadow
|
||
ALIGN
|
||
|
||
ADDTOSTYLE LEA ITEMPROPERTIES-1(A6),A0 ;get property table address
|
||
MOVE.B 0(A0,D1),D0 ;get current property
|
||
BSET D2,D0 ;set appropriate property
|
||
|
||
UPDATEPROP LEA ITEMPROPERTIES-1(A6),A0 ;get address of item property table
|
||
cmp #8, d1 ; do we have a hierarchical menu here? <FJL C222>
|
||
bne.s @NotHierMenu ; no, so branch <FJL C222>
|
||
|
||
move.w #2, d1 ; for a HMenu <FJL C222>
|
||
move.b #HMenuCmd, 0(a0, d1) ; ==> itemCmd (byte 2) = $1B(HMenuCmd) <FJL C222>
|
||
move.w #3, d1 ; ==> itemMark(byte 3) = char in d0 <FJL C222>
|
||
|
||
@NotHierMenu MOVE.B D0,0(A0,D1) ;update the property <FJL C222>
|
||
CLR.B ITEMSTATE(A6) ;return state to normal
|
||
RTS
|
||
;
|
||
; Handle the normal state by scanning for any of the 8 (not 7) special characters <FJL C222>
|
||
;
|
||
NORMSTATE
|
||
TST.W D2 ; See if it is a single byte character <PMAB568 07Sep88 EMT>
|
||
BNE.S MultiChar ; Skip if not <PMAB568 07Sep88 EMT>
|
||
LEA MCHARTABLE,A0 ;get address of character table
|
||
MOVEQ #7,D1 ;scan it backwards, 8 characters now <FJL C222>
|
||
NSLOOP CMP.B 0(A0,D1),D0 ;is it one of the special ones?
|
||
BNE.S @loop
|
||
IMPORT SpecialChar
|
||
JMP SPECIALCHAR ;if so, go handle it
|
||
@loop
|
||
DBRA D1,NSLOOP
|
||
;
|
||
; it wasn’t in the exception table so it must be a normal character. Just append it
|
||
; to the item buffer.
|
||
;
|
||
MultiChar ; <PMAB568 07Sep88 EMT>
|
||
MOVE ITEMCOUNT(A6),D1 ;get total number of characters
|
||
LEA ITEMBUFFER(A6),A0 ;get address of buffer
|
||
MOVE.B D0,0(A0,D1) ;stick character in buffer
|
||
ADDQ #1,ITEMCOUNT(A6) ;bump buffer index
|
||
RTS
|
||
ENDPROC
|
||
;
|
||
; it was one of the special characters -- first see if its a property command -- ^ / ! < $1B
|
||
;
|
||
SPECIALCHAR PROC ENTRY ; Get around bug in assembler with short branches.
|
||
CMP #3,D1 ; which char was it?
|
||
BLE.S @PropertyChar ; if 0 through 3, is a property cmd
|
||
cmp #7, d1 ; is it the hierarchical menu character?
|
||
bne.s CheckTerm ; not a hierarchical item
|
||
;
|
||
; it was a property meta-character so update the state accordingly
|
||
;
|
||
@PropertyChar ADDQ #1,D1 ;bump state
|
||
MOVE.B D1,ITEMSTATE(A6) ;update state
|
||
RTS
|
||
;
|
||
; check for termination characters like carriage return or semicolon
|
||
;
|
||
CHECKTERM SUBQ #6,D1 ;was it enable character?
|
||
BNE.S CLOSEITEM ;it must have been a termination character
|
||
;
|
||
; disable the item
|
||
;
|
||
ST ITEMFLAGS(A6) ;flag the item to be disabled
|
||
RTS
|
||
|
||
ENTRY CloseItem
|
||
CLOSEITEM
|
||
;
|
||
; CloseItem is called to add the item in the buffer (and its associated properties) to
|
||
; the actual menu data structure. After this is done, re-initialize for the next item
|
||
; On entry, the item insertion index is in D6
|
||
;
|
||
MOVE ITEMCOUNT(A6),D0 ;get the # of characters in buffer
|
||
BEQ.S CLOSEDONE ;if none, we’re done
|
||
IMPORT InsertTheItem
|
||
BSR InsertTheItem ; put the new item into the menu <EHB 8-May-85>
|
||
IMPORT InitItem
|
||
BSR INITITEM ; prepare for next item
|
||
CLOSEDONE RTS
|
||
ENDPROC
|
||
|
||
GetGoodIndex PROC ENTRY
|
||
; ---------------
|
||
; Utility GetGoodIndex -- takes an index into the menu list in D6 and a menu handle in A3.
|
||
; Returns a valid insertion index in D5. Trashes D0-D2, A0-A1
|
||
; <PMAB280>
|
||
MOVE.W D6,D5 ; get proposed index
|
||
SUBQ #2,SP ; count menu items
|
||
MOVE.L A3,-(SP) ; push menu handle
|
||
_CountMItems
|
||
MOVE.W (SP)+,D0 ; get count
|
||
ADDQ #1,D0 ; make it an insertion index
|
||
CMP.W D0,D5 ; if D5 is bigger
|
||
BLE.S @0 ; then use count+1
|
||
MOVE.W D0,D5 ; preserve in D5
|
||
@0 Rts
|
||
ENDPROC
|
||
|
||
InsertTheItem PROC ENTRY ; <EHB 8-May-85>
|
||
; InsertTheItem -- inserts the item in the item buffer before the item designated by D6.
|
||
; If D6 is bigger than the last item, append the item to the end of the list. Keeps true
|
||
; insertion item # in D5
|
||
IMPORT GetGoodIndex
|
||
BSR GetGoodIndex ; index in D6 -> good index in D5
|
||
MOVE.W D5,D0 ; get insertion index
|
||
MOVE.L (A3),A0 ; get menu pointer
|
||
IMPORT GetItemRecord
|
||
BSR GetItemRecord ; point to item’s string
|
||
BEQ.S @1 ; => out of range. End pointer in D1
|
||
MOVE.L A0,D1 ; else get pointer in D1
|
||
|
||
; only need to insert enable bit if insert within range. (bits at end are all alike)
|
||
|
||
MOVE.L (A3),A0 ; get menu list pointer
|
||
IMPORT InsertEnableBit
|
||
BSR InsertEnableBit ; insert bit in pos’n in D5
|
||
@1
|
||
LEA ITEMBUFFER(A6),A0 ; point to string data
|
||
MOVE.L A0,A2 ; save insertion string in A2
|
||
MOVE.W ITEMCOUNT(A6),D2 ; get the string length
|
||
ADDA.W D2,A0 ; point past end of string
|
||
|
||
LEA ITEMPROPERTIES(A6),A1 ; get address of properties
|
||
MOVEQ #3,D0 ; and move in 4 property bytes
|
||
@2 MOVE.B (A1)+,(A0)+ ; move a byte
|
||
DBRA D0,@2 ; loop till done
|
||
|
||
SUBQ #1,A2 ; point to insertion count byte
|
||
ADD.W #5,D2 ; get length of data into D2
|
||
EXT.L D2 ; (itemCount + 1 length + 4 property)
|
||
|
||
MOVE.L D1,A1 ; get address of data
|
||
SUB.L (A3),A1 ; get offset into menu list
|
||
|
||
SUBQ #4,SP ; we’re here to get results
|
||
MOVE.L A3,-(SP) ; push handle to menu list
|
||
MOVE.L A1,-(SP) ; push offset into menu list
|
||
CLR.L -(SP) ; no source string
|
||
CLR.L -(SP)
|
||
MOVE.L A2,-(SP) ; just an insertion string
|
||
MOVE.L D2,-(SP) ; and its length
|
||
_Munger
|
||
|
||
ADDQ #4,SP ; ignore results
|
||
|
||
TST.B ITEMFLAGS(A6) ; was it disabled?
|
||
BEQ.S InsertDone ; => no, don’t need to disable
|
||
MOVE.L A3,-(SP) ; push menu handle
|
||
MOVE.W D5,-(SP) ; and item number
|
||
BSR DisableItem ; and disable it
|
||
InsertDone
|
||
RTS
|
||
ENDPROC
|
||
|
||
InsertEnableBit PROC ENTRY
|
||
; InsertEnableBit -- insert a bit into the MenuEnable byte, turned on.
|
||
; Index is in D5, menulist pointer is in A0.
|
||
; Trashes D0,D2.
|
||
;
|
||
;DONE: don’t do this if D5 > 31 otherwise we wind up screwing up the rotation.
|
||
; Recall that all items > 31 are always enabled
|
||
cmp #31, d5 ; is the item > 31 ? <FJL PMAB255>
|
||
bhi.s @DoneInsert ; yes, so leave without updating flags <FJL PMAB255>
|
||
MOVE.L MenuEnable(A0),D2 ; get current enable flags
|
||
ROR.L D5,D2 ; rotate n bits <EHB 3-May-85>
|
||
MOVE.W D5,D0 ; get 32-n with extend
|
||
SUB.W #32,D0 ; by negating n-32
|
||
NEG.W D0 ; extend is inserted 1 bit
|
||
ROXR.L D0,D2 ; rotate in others
|
||
MOVE.L D2,MenuEnable(A0) ; replace the flags <EHB 3-May-85>
|
||
@DoneInsert RTS
|
||
ENDPROC
|
||
|
||
GETMHANDLE PROC EXPORT
|
||
; FUNCTION GetMHandle(menuID): menuHandle -- convenience procedure which returns
|
||
; a menuHandle given a menuID. If the menuID cannot be found in the current menuList,
|
||
; NIL is returned
|
||
;
|
||
; Look in HMenu list first, then in regular portion of MenuList <FJL C222>
|
||
;
|
||
CLR.L 6(SP) ;set result to NIL
|
||
moveq #0, d1 ;clear hi-word for GetHIndex call <FJL C222>
|
||
MOVE 4(SP),D1 ;get menuID
|
||
|
||
IMPORT GetHIndex
|
||
bsr GetHIndex ; look in H Menus for the menuID <FJL C222>
|
||
bne.s @GotRMenu ; branch if menuID in HMenus <FJL C222>
|
||
|
||
IMPORT GetIndex
|
||
BSR GETINDEX ; get menuIndex
|
||
beq.s @1 ; branch if couldn’t find it at all <FJL C222>
|
||
|
||
@GotRMenu MOVE D5,-(SP) ;preserve D5
|
||
MOVE D0,D5 ;get menuIndex in D5
|
||
BSR GETMENUPTR ;get handle to menu in A1
|
||
MOVE (SP)+,D5 ;restore D5
|
||
MOVE.L A1,6(SP) ;set function result
|
||
IMPORT TwoBytExit
|
||
@1 BRA TWOBYTEXIT ;standard exit saves code
|
||
ENDPROC
|
||
|
||
DELMENUITEM PROC EXPORT ; <EHB 15-Apr-85>
|
||
; PROCEDURE DelMenuItem(MenuHandle:Handle; itemNum: INTEGER) -- delete the specified
|
||
; item from the specified menu. Shoves an extra return address on the stack to
|
||
; make stack parallel with SetItem, below.
|
||
MOVE.L (SP),-(SP) ; old RTS -> phony newItem
|
||
MOVEM.L D3-D4/A2-A4,-(SP) ; save work registers
|
||
|
||
; set up for rest of DelMenuItem
|
||
|
||
MOVE.L 30(SP),A3 ; get menu handle
|
||
MOVE.L (A3),A0 ; get menu for GetItemRecord
|
||
MOVE.W 28(SP),D0 ; get item for GetItemRecord
|
||
|
||
; need to delete the item’s enable bit from MenuEnable
|
||
|
||
Cmpi.W #31, D0 ; item number > 31 ? <FJL PMAB282>
|
||
Bhi.S @1 ; yes -> skip enable bits stuff <FJL PMAB282>
|
||
|
||
MOVE.L MenuEnable(A0),D1 ; get enable bits for menu items <EHB 3-May-85>
|
||
MOVE.W D0,D2 ; get 32-n with extend set
|
||
SUB.W #32,D2 ; by negating n-32
|
||
NEG.W D2
|
||
ROXL.L D2,D1 ; shift in new high bit (set)
|
||
ROL.L D0,D1 ; leave deleted bit in extend
|
||
MOVE.L D1,MenuEnable(A0) ; and save updated enable bits
|
||
|
||
@1
|
||
IMPORT GetItemRecord
|
||
BSR GetItemRecord ; look up the specified
|
||
BNE.S @continue
|
||
IMPORT SetIDone
|
||
JMP SetIDone ; => item not found
|
||
@continue
|
||
MOVEQ #5,D4 ; 4 property bytes + 1 length byte
|
||
MOVEQ #0,D2 ; length of replacement string
|
||
MOVE.L D2,A2 ; and NIL replacement string
|
||
IMPORT SICommon
|
||
BRA SICommon ; go parasitize host...
|
||
ENDPROC
|
||
|
||
SETITEM PROC EXPORT
|
||
; PROCEDURE SetItem(menuHandle:Handle; itemNum: INTEGER; newItem: String) -- change
|
||
; the specified item to the new string, keeping the same attributes as the old one
|
||
MOVEM.L D3-D4/A2-A4,-(SP) ;save work registers
|
||
MOVE.L 30(SP),A3 ;get menu handle
|
||
MOVE.W 28(SP),D3 ;get item number
|
||
MOVE.L 24(SP),A2 ;get string pointer
|
||
|
||
MOVE.W D3,D0 ;get item in D0
|
||
MOVE.L (A3),A0 ;get menu ptr in A0
|
||
IMPORT GetItemRecord
|
||
BSR GETITEMRECORD ;find our entry
|
||
BEQ.S SETIDONE ;if not, we’re done
|
||
|
||
MOVEQ #1,D4 ; get 1 for length byte
|
||
MOVEQ #1,D2 ; get 1 for length byte
|
||
ADD.B (A2),D2 ; add in length of new string
|
||
|
||
ENTRY SICommon
|
||
SICommon
|
||
MOVE.L A0,A4 ; remember item ptr in A4
|
||
SUB.L (A3),A4 ; offset = item pointer - menu start
|
||
ADD.B (A0),D4 ; Length = D4 + menuString length
|
||
|
||
SUBQ #4,SP ; make room for result
|
||
MOVE.L A3,-(SP) ; push menu handle
|
||
MOVE.L A4,-(SP) ; offset to string to be replaced
|
||
CLR.L -(SP) ; no search string
|
||
MOVE.L D4,-(SP) ; old length
|
||
MOVE.L A2,-(SP) ; ptr to new
|
||
MOVE.L D2,-(SP) ; length of new
|
||
_Munger
|
||
ADDQ #4,SP ; ignore result
|
||
|
||
MOVE.L A3,-(SP) ; push the menu handle
|
||
IMPORT DirtyMenuSize
|
||
BSR DirtyMenuSize ; invalidate size <EHB 5-Mar-85>
|
||
|
||
;
|
||
; all done with SetItem
|
||
;
|
||
ENTRY SetIDone
|
||
SETIDONE MOVEM.L (SP)+,D3-D4/A2-A4 ;restore work registers
|
||
IMPORT TenBytExit
|
||
BRA TENBYTEXIT ;standard exit saves code
|
||
ENDPROC
|
||
|
||
SETMENUFLASH PROC EXPORT
|
||
;
|
||
; PROCEDURE SetMenuFlash(flashCount: INTEGER) -- set the system global "flashCount" to
|
||
; a new value, controlling the duration of the flash feedback given when a menu item
|
||
; is selected
|
||
;
|
||
MOVE.W 4(SP),MENUFLASH ;update flashcount
|
||
IMPORT TwoBytExit
|
||
BRA TWOBYTEXIT ;standard exit saves code
|
||
ENDPROC
|
||
|
||
AddResMenu PROC EXPORT
|
||
IMPORT InsrtResMenu
|
||
|
||
;
|
||
; PROCEDURE AddResMenu(theMenu: menuHandle; theType: RsrcType);
|
||
;
|
||
; AddResMenu appends all the names of a given resource type class
|
||
; to the menu passed as a parameter. It ignores names with a period or
|
||
; percent sign as their first character. It is simply a cover for InsrtResMenu,
|
||
; which it falls into.
|
||
;
|
||
MOVE.L (SP)+,A0 ; get return address
|
||
MOVE.W #999,-(SP) ; push large "afterItem"
|
||
MOVE.L A0,-(SP) ; restore return address
|
||
|
||
JMP InsrtResMenu
|
||
ENDPROC
|
||
|
||
CountMItems PROC EXPORT
|
||
; FUNCTION CountMItems(mHandle: MenuHandle): INTEGER
|
||
;
|
||
; CountMItems returns the number of items in a given menu
|
||
;
|
||
; TODO: Do not call GetItemRecord, since this just loops again! Stupid way to do it.
|
||
;
|
||
MOVEQ #0,D2 ;start with item 0
|
||
CountMLoop
|
||
ADDQ #1,D2 ;bump item number
|
||
MOVE.L 4(SP),A0 ;get menu handle
|
||
MOVE.L (A0),A0 ;handle -> pointer
|
||
MOVE.W D2,D0 ;get item number in D0
|
||
IMPORT GetItemRecord
|
||
BSR GetItemRecord ;look it up
|
||
BNE.S CountMLoop ;if we got it, bump count and try again
|
||
|
||
; we couldn’t get the item in D2, so D2 must have the number of items + 1
|
||
|
||
SUBQ #1,D2 ;get number of items
|
||
MOVE.W D2,8(SP) ;return it as the result
|
||
|
||
MOVE.L (SP)+,(SP) ;strip the parameter
|
||
RTS ;return to caller
|
||
ENDPROC
|
||
|
||
PlotIcon PROC EXPORT
|
||
;-----------------------------------------------------------------------------------------------
|
||
; PROCEDURE PlotIcon(theRect: Rect; theIcon: IconHandle)
|
||
;
|
||
; Plots a given icon at a given place in your local coordinate system.
|
||
; theMode is the LisaGraf penMode for the transfer
|
||
;
|
||
LEA ICONBITMAP,A1 ;get address of icon mgr bitMap
|
||
MOVE.L 4(SP),D0 ;get the icon handle
|
||
BEQ.S DONEIPLOT ;if NIL, dont plot
|
||
MOVE.L D0,A0 ;get iconHandle in address reg
|
||
|
||
MOVE.L (A0),(A1)+ ;icon mptr is the base address
|
||
MOVE #4,(A1)+ ;set up rowBytes
|
||
CLR.L (A1)+ ;set up topLeft
|
||
MOVE.L #$00200020,(A1) ;set up botRight
|
||
|
||
MOVE.L 8(SP),D1 ;get theRect
|
||
LEA IconBitMap,A1 ;point A1 at bitmap again
|
||
;
|
||
; push parameters for copyBits call
|
||
;
|
||
MOVE.L A1,-(SP) ;source bitMap is iconBitMap
|
||
MOVE.L GrafGLOBALS(A5),A0 ;get lisaGraf global baseaddress
|
||
MOVE.L THEPORT(A0),A0 ;get thePort
|
||
PEA PORTBITS(A0) ;that’s the destination bitmap
|
||
|
||
PEA BOUNDS(A1) ;boundsRect of bitmap is source
|
||
MOVE.L D1,-(SP) ;theRect is the destination
|
||
CLR.W -(SP) ;theMode is srcCopy (0)
|
||
CLR.L -(SP) ;no mask region
|
||
_CopyBits ;let Bill blit those bits
|
||
DONEIPLOT
|
||
IMPORT TwoParmExit
|
||
BRA TWOPARMEXIT ;standard exit saves code
|
||
ENDPROC
|