mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-27 10:29:32 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
4582 lines
181 KiB
Plaintext
4582 lines
181 KiB
Plaintext
;
|
|
; 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>
|
|
|
|
move.l a1, MenuCInfo ; store the color table too <FJL C408>
|
|
IMPORT GetMBColors
|
|
bsr GetMBColors ; get menubar color info from the system <FJL C408>
|
|
|
|
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
|
|
|
|
RTS ; <SM13> this was mistakenly deleted at some point
|
|
|
|
; InitMList allocÕs a menuList with no menus and no hierarchical menus <FJL C222>
|
|
ENTRY InitMList
|
|
InitMList
|
|
moveq #mctEntrySize, d0 ; allocate one record in the color tbl <FJL C408>
|
|
_NewHandle ; <FJL C408>
|
|
move.l (a0), a1 ; dereference
|
|
move #mctLastIDIndic, mctID(a1) ; store -99 as ID ==> last entry <FJL C408>
|
|
move.l a0, -(SP) ; store it on the stack temporarily <FJL C408>
|
|
|
|
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)
|
|
|
|
move.l (SP)+, a1 ; get the color tbl handle in a1 <FJL C408>
|
|
|
|
rts
|
|
ENDPROC
|
|
|
|
|
|
GetMBColors PROC ENTRY
|
|
;-----------------------------------------------
|
|
; Utility -- GetMBColors
|
|
;-----------------------------------------------
|
|
; See if there is a menubar color table entry. It will automatically look for one in <FJL C408>
|
|
; the applications resfile then in the system res file. <FJL C408>
|
|
;
|
|
move.b #1, -(SP) ; force Resource Load to true
|
|
_SetResLoad
|
|
|
|
subq #4, SP ; make room for the result
|
|
move.l #'mctb', -(SP) ; push resource type
|
|
clr.w -(SP) ; push menuID 0 = menu bar
|
|
_GetResource ; get the resource
|
|
move.l (SP)+, a0 ; get the handle in a0
|
|
move.l a0, d0 ; set z-flag
|
|
beq.s @1 ; handle is nil, so no color table
|
|
|
|
_HGetState ; get state of resource
|
|
move.b d0, -(SP) ; store them on the stack
|
|
move.l a0, -(SP) ; store handle on stack too
|
|
_HLock ; lock the handle down temporarily
|
|
|
|
move.l (a0), a0 ; get ptr to resource
|
|
move (a0)+, -(SP) ; push number of table entries
|
|
move.l a0, -(SP) ; push base address of table
|
|
_SetMCEntries ; call trap
|
|
|
|
move.l (SP)+, a0 ; get handle
|
|
move.b (SP)+, d0 ; and previous state
|
|
_HSetState ; return handle to previous state
|
|
|
|
@1 rts
|
|
ENDPROC
|
|
|
|
CLEARMENUBAR PROC EXPORT
|
|
;
|
|
; PROCEDURE ClearMenuBar -- clear the menuBar/menuList data structure
|
|
;
|
|
|
|
;¥HMClearMenuBarPatch roll in from BalloonPatch28.a
|
|
IMPORT ptchHMGetBalloons
|
|
JSR ptchHMGetBalloons ; what is the state of What Is? mode?
|
|
BEQ.S @BalloonsOff ; EQ means no, so, let's not do anything.
|
|
SUBQ #2,SP ; remove any balloons that might have been up
|
|
_HMRemoveBalloon ; do the remove
|
|
TST.W (SP)+ ; toss result
|
|
|
|
@BalloonsOff
|
|
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>
|
|
|
|
move.l MenuCInfo, a0 ; get handle to color tbl <FJL C408>
|
|
_DisposHandle ; and toss it <FJL C408>
|
|
|
|
IMPORT InitMList
|
|
bsr InitMList ; init a new one <FJL C222>
|
|
move.l a0, menuList ; and store it <FJL C222>
|
|
|
|
move.l a1, MenuCInfo ; and store it too <FJL C408>
|
|
IMPORT GetMBColors
|
|
bsr GetMBColors ; get menubar color info from the system <FJL C408>
|
|
|
|
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>
|
|
|
|
move 4(SP), -(SP) ; push the menuID <FJL C408>
|
|
move #mctAllItems, -(SP) ; push flag meaning all items <FJL C408>
|
|
_DelMCEntries ; call delete routine <FJL C408>
|
|
|
|
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>
|
|
|
|
; Roll in PatchInsertMenu in SystemMenuPatch.a
|
|
; When this patch sees a system menu (-16385 thru -32768), it adds it to the system menu bar.
|
|
; If the system menu bar doen't exist, this patch creates it.
|
|
; If the menu is not a system menu, ensure that the beforeID is modified so that the
|
|
; menu is inserted before the system menu partition.
|
|
IMPORT FindFirstSystemMenu6BO
|
|
InsertStack RECORD {base},DECR
|
|
ParamBegin: EQU * ; start parameters after this point
|
|
menuHdl DS.L 1
|
|
beforeID DS.W 1
|
|
ParamSize: EQU ParamBegin-*
|
|
retAddr DS.L 1
|
|
base DS.W 0
|
|
LocalSize: EQU *
|
|
ENDR
|
|
|
|
WITH InsertStack
|
|
CMP.W #$FFFF, beforeID(SP) ; beforeID = -1 ==> H Menu
|
|
beq OldInsertMenu
|
|
|
|
; If a system menu is being inserted, put it into the System Menu Bar
|
|
|
|
MOVE.L menuHdl(SP), A0 ; Get the MenuHandle
|
|
MOVE.L (A0), A0 ; dereference
|
|
SUBQ.L #4,SP ; Make Room for result & VAR
|
|
MOVE.W menuID(A0),-(SP) ; Push the menuID
|
|
PEA 4(SP) ; Point to VAR
|
|
_IsSystemMenu ; Do it the standard way
|
|
ADDQ.L #2,SP ; Eat the result
|
|
TST.B (SP)+ ; Is it a system menu?
|
|
BNE.S @DoSystemMenu ; EQ means it is a system menu
|
|
|
|
; Menu for main list, be sure it is inserted before all the system menus
|
|
BSR FindFirstSystemMenu6BO ; Find the system menu partition
|
|
beq OldInsertMenu ; Do old stuff if no system menus
|
|
MOVE.W D0, D1 ; Save off 6BO of 1st system menu
|
|
MOVE.W beforeID(SP), D0 ; Get the beforeID
|
|
BEQ.S @forceBeforeSys ; branch if zero
|
|
BSR Find6BOFromID ; Find its offset
|
|
BEQ.S @forceBeforeSys ; branch if the beforeID not in list
|
|
CMP.W D1, D0 ; Is it after the system partition?
|
|
ble OldInsertMenu ; No, do as caller wanted
|
|
MOVE.W D0, D1 ; It is after the system partition
|
|
|
|
@forceBeforeSys ; the beforeID must be changed to before the 1st system menu
|
|
MOVE.L MenuList, A0 ; get the menulist
|
|
MOVE.L (A0), A0 ; deref
|
|
MOVE.L menuOH(A0,D1.W), A0 ; get the menuhandle to insert before
|
|
MOVE.L (A0), A0 ; deref
|
|
MOVE.W menuID(A0), beforeID(SP) ; Make beforeID be 1st system menu
|
|
bra OldInsertMenu ; Now go do it
|
|
|
|
@DoSystemMenu
|
|
; If menuID already exists in system menulist, we're done!
|
|
MOVE.L MenuList, A1 ; Save Menulist
|
|
MOVE.L SystemMenuList, MenuList ; Store system as menulist
|
|
JSR Find6BOFromID ; Is this menuID already in the list?
|
|
MOVE.L A1, MenuList ; Restore Menulist
|
|
TST.W D0 ; Was the menuID found?
|
|
BNE.S @Done ; Don't double insert it, done.
|
|
|
|
; Swap the two menu lists so this menu inserts into the system menu
|
|
MOVE.W beforeID(SP), D0 ; Get the beforeID
|
|
BEQ.S @AddAtEnd ; Yes, branch
|
|
MOVE.L MenuList, A1 ; Save Menulist
|
|
MOVE.L SystemMenuList, MenuList ; Store system as menulist
|
|
JSR Find6BOFromID ; Look up the beforeID
|
|
MOVE.L A1, MenuList ; Restore Menulist
|
|
TST.W D0 ; Was the menuID found?
|
|
BNE.S @DoTheAdd
|
|
@AddAtEnd
|
|
MOVE.L SystemMenuList, A0 ; Get system menulist
|
|
MOVE.L (A0), A0 ; deref
|
|
MOVE.W lastMenu(A0), D0 ; Get last menu
|
|
ADDQ.W #6, D0 ; Insert "before" the end
|
|
@DoTheAdd
|
|
SUBQ.L #4, SP ; Make room for result
|
|
MOVE.L SystemMenuList, -(SP) ; handle
|
|
MOVE.W D0, -(SP) ; Move the offset
|
|
CLR.W -(SP) ; as a long with high cleared
|
|
CLR.L -(SP) ; ptr1 = 0
|
|
CLR.L -(SP) ; len1 = 0
|
|
PEA 6+20(SP) ; ptr2 = menuhandle parameter
|
|
MOVEQ.L #6, D0
|
|
MOVE.L D0, -(SP) ; len2 = 6
|
|
_Munger ; Munge away! Left coord will be junk.
|
|
ADDQ.L #4, SP ; Dump result
|
|
; Remember to update the lastMenu field
|
|
MOVE.L SystemMenuList, A0 ; Get system menulist
|
|
MOVE.L (A0), A0 ; handle -> ptr
|
|
ADDQ.W #6, lastMenu(A0) ; Bump the count
|
|
@Done
|
|
MOVE.L (SP)+, A0 ; Get the return address
|
|
ADDQ.L #ParamSize, SP ; Cut back the parameters
|
|
JMP (A0)
|
|
|
|
OldInsertMenu
|
|
|
|
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 @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.
|
|
|
|
; <SM17> CSS
|
|
;Roll in SynchKeyboardMenuState Ñ Make sure the keyboard menu state corresponds to the
|
|
; applicationÕs desired setting (enable/disable) in the
|
|
; application-specific global flag, scriptDisableKybds
|
|
; from MenuMgrPatch.a, this patch says that it shouldn't be rolled in because the
|
|
; it should be in the process manager. Well, for 7.1 it is not in the process manager,
|
|
; so I am rolling it in anyways.
|
|
moveq #smKeySynchKbdMenuState,d0 ; Set up the KeyScript verb
|
|
move.w d0,-(sp) ; to just synchronize the keyboard menu
|
|
_KeyScript ; Do it.
|
|
;end Roll in SyncKeyboardMenuState
|
|
|
|
;Roll in ValidateMenuBarWhenDrawing
|
|
bclr #MenuBarInvalidBit,MenuBarInvalidByte ; clear the local invalid bit
|
|
bclr #MenuBarGlobalInvalidBit,MenuBarGlobalInvalidByte ; clear the global invalid bit <6>
|
|
;Roll in PatchMDDrawMenuBar from ModialDiaglogMenuPatches.a <PN> <SM5>
|
|
import PushMenuState,PopMenuState ;<PN> <SM5>
|
|
jsr PushMenuState ; Potentially save off the menu state <PN> <SM5>
|
|
|
|
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.
|
|
|
|
; HiliteMenu draw menu bar if invalid
|
|
; ROLL IN ValidateMenuBarWhenDrawing
|
|
IMPORT ValidateMenuBar
|
|
jsr ValidateMenuBar
|
|
|
|
; Roll in PatchMDHiliteMenu
|
|
; The saves menus state, calls old HiliteMenu, then restores state
|
|
import PushMenuState,PopMenuState ;<SM5> <PN>
|
|
|
|
parametersStackFrame
|
|
menuID ds.w 1 ; the menuID <SM5> <PN>
|
|
endStackFrame
|
|
|
|
linkSave
|
|
jsr PushMenuState ; Potentially save off the menu state <SM5> <PN>
|
|
move.w menuID(a6),-(sp) ; Push the parameter <SM5> <PN>
|
|
|
|
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 (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 (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.W (SP)+,theMenu ; update theMenu <FJL C175>
|
|
bra Done
|
|
; donÕt store the menuID if we couldnÕt find the index. No index means the <FJL C175>
|
|
; menuID doesnÕt exist on the menu bar, and storing a non-existent menuID <FJL C175>
|
|
; in theMenu global causes the next HiliteMenu(0) to flip the bar (ugh-ly). <FJL C175>
|
|
HLNone ; get the return address <FJL C175>
|
|
addq.l #2, SP ; throw away the parameter <FJL C175>
|
|
clr.w theMenu ; update theMenu <FJL C175>
|
|
Done
|
|
jsr PopMenuState ; Restore the menu state if it was saved <SM5> <PN>
|
|
restoreUnlinkReturn
|
|
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 ; 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
|
|
|
|
; MenuSelect draw menu bar if invalid
|
|
; ROLL IN DrawMenuBarIfInvalidOnMenuSelect
|
|
IMPORT ValidateMenuBar
|
|
IMPORT ptchHMUpdateHelpMenu
|
|
IMPORT ptchHMShowHelpAboutDialog
|
|
IMPORT ptchHMToggleWhatIs
|
|
|
|
jsr ValidateMenuBar
|
|
;Roll in PatchMDMenuSelect
|
|
;The saves menus state, calls old MenuSelect, then restores state
|
|
import PushMenuState,PopMenuState ;<PN> <SM5>
|
|
|
|
resultsStackFrame
|
|
result ds.l 1 ; the MenuSelect result <PN> <SM5>
|
|
parametersStackFrame
|
|
startPt ds.l 1 ; the start point <PN> <SM5>
|
|
endStackFrame
|
|
|
|
linkSave A2 ; <SM15> To preserve A2!
|
|
MOVE.L MenuList,D0 ; check if menu list is nil. <SM12> rb, start
|
|
BEQ.S @CallOldCode ; if NIL just call the old trap
|
|
|
|
JSR ptchHMUpdateHelpMenu ; update the menu checked status
|
|
|
|
MOVE.L ExpandMem,A2 ; <33> point to the expand mem ptr
|
|
MOVE.L ExpandMemRec.emHelpGlobals(A2),A2 ; <33> A2 = global ptr
|
|
CLR.W hmgSystemMenuID(A2) ; <33> clear the last system menu ID
|
|
CLR.W hmgSystemMenuItem(A2) ; <33> clear the last system menu item
|
|
ST hmgInMenuSelectFlag(A2) ; <33> say that we're in MenuSelect
|
|
@CallOldCode ; <SM12> rb, end
|
|
|
|
jsr PushMenuState ; Potentially save off the menu state <PN> <SM5>
|
|
subq #4,sp ; Make room for result <PN> <SM5>
|
|
move.l startPt(a6),-(sp) ; Push the parameter <PN> <SM5>
|
|
|
|
jsr OrigninalMenuSelect ;<PN> <SM5>
|
|
move.l (sp)+,result(a6) ; Store the result <PN> <SM5>
|
|
jsr PopMenuState ; Restore the menu state if it was saved <PN> <SM5>
|
|
|
|
MOVE.L result(a6),D0 ; get the result of the _MenuSelect call <SM12> rb, start
|
|
MOVE.L ExpandMem,A2 ; <33> point to the expand mem ptr
|
|
MOVE.L ExpandMemRec.emHelpGlobals(A2),A2 ; <33> A2 = global ptr
|
|
|
|
SWAP D0 ; put menu ID in low word for test
|
|
TST.W D0 ; was the menu ID non-zero?
|
|
BNE.S @NormalMenuSelect ; yes, so just return result of _MenuSelect
|
|
|
|
MOVE.W hmgSystemMenuID(A2),D1 ; return the last system menu ID
|
|
BEQ.S @NormalMenuSelect ; if zero then the menu wasn't the help menu
|
|
|
|
SWAP D1 ; put menu ID in hiword
|
|
MOVE.W hmgSystemMenuItem(A2),D1 ; return the last help menu item
|
|
|
|
@HandleHelpMenu
|
|
CMP #kHMAboutHelpItem,D1 ; was it the about item
|
|
BNE.S @TryShowBalloonsItem ; no, check for Show/Hide Balloons item
|
|
|
|
JSR ptchHMShowHelpAboutDialog ; show the about dialog
|
|
BRA.S @HelpMenuHandled ; exit w/ zeroed menu result long
|
|
|
|
@TryShowBalloonsItem
|
|
CMP.W #kHMShowBalloonsItem,D1 ; was the selection Show/Hide Balloons??
|
|
BNE.S @DoneHelpMenu ; no, it was some other item
|
|
|
|
JSR ptchHMToggleWhatIs ; toggles state of "Show Balloons" global,
|
|
BRA.S @HelpMenuHandled ; exit w/ zeroed menu result long
|
|
|
|
@DoneHelpMenu
|
|
MOVE.L D1,D0 ; put the setup menu result in D0 for result(A6)
|
|
BRA.S @CorrectedResult ; exit
|
|
|
|
@HelpMenuHandled
|
|
MOVEQ #0,D0 ; say that hi and lo words are zero
|
|
@NormalMenuSelect
|
|
SWAP D0 ; put item number back in lo word
|
|
@CorrectedResult
|
|
MOVE.L D0,result(a6) ; stuff the non-corrected result
|
|
|
|
CLR.W hmgInMenuSelectFlag(A2) ; <33> say that we're out of MenuSelect
|
|
|
|
restoreUnlinkReturn
|
|
|
|
OrigninalMenuSelect
|
|
|
|
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 wMgrCPort, a2 ; get color 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>
|
|
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)
|
|
|
|
IMPORT SetTickCounters ; <SM13> call SetTickCounters after
|
|
; menuDelaySave and menuDragSave are set up
|
|
bsr SetTickCounters ; set DelayTicks and DragTicks <FJL C222>
|
|
|
|
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 wMgrCPort, a2 ; get color 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)
|
|
|
|
; Alter WMgr portRect to point to the rect of the device the cursor is on
|
|
MOVE.L CrsrDevice, A1 ; Get the cursor GDevice <PMAB364 23Jan88 EMT>
|
|
MOVE.L (A1), A1 ; Dereference <PMAB364 23Jan88 EMT>
|
|
MOVE.L gdRect+topLeft(A1), portRect+topLeft(A2) ; Copy to <PMAB364 23Jan88 EMT>
|
|
MOVE.L gdRect+botRight(A1), portRect+botRight(A2) ; WMgr portRect <PMAB364 23Jan88 EMT>
|
|
|
|
IMPORT DirtyHMenus
|
|
BSR DirtyHMenus ; Dirty size of all hierchical menus <PMAB364 23Jan88 EMT>
|
|
MOVE.L PopUpMenuH(A6), -(SP) ; Push the menuHandle <PMAB539 19Jul88 EMT>
|
|
_CalcMenuSize ; And recalculate it <PMAB539 19Jul88 EMT>
|
|
|
|
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
|
|
; Restore WMgr portRect. WMgrCPort is in A2
|
|
MOVE.L WMgrPort, A0 ; Get b&w WMgrPort <PMAB364 23Jan88 EMT>
|
|
MOVE.L portRect+topLeft(A0), portRect+topLeft(A2) ; Copy to <PMAB364 23Jan88 EMT>
|
|
MOVE.L portRect+botRight(A0), portRect+botRight(A2) ; WMgr portRect <PMAB364 23Jan88 EMT>
|
|
|
|
IMPORT DirtyHMenus
|
|
BSR DirtyHMenus ; Dirty size of all hierchical menus <PMAB364 23Jan88 EMT>
|
|
|
|
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 WMgrCPort, A1 ; Get color 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
|
|
|
|
; Some programmers are pretty slimy and load a MDEF that is empty. They then <LW4> fau
|
|
; stuff some code into it. However, since HLOCK does not flush the cache anymore, <LW4> fau
|
|
; the code that they stuff into it might not get written back to memory. To solve this, <LW4> fau
|
|
; we check here whether the MDEF resource size is less than, say, 32 bytes. If so, we <LW5> chp
|
|
; assume that they have already loaded the MDEF and modified it, so we flush the cache <LW4> fau
|
|
; for them.
|
|
|
|
_GetHandleSize ; How big is our MDEF Handle <LW4> fau
|
|
cmp.l #32,D0 ; Is it "small" <LW5> chp
|
|
bhi.s @RealMDEF ; no, don't flush the cache <LW4> fau
|
|
jsr ([jCacheFlush]) ; else, flush the caches. <LW4> fau
|
|
@RealMDEF ; <LW4> fau
|
|
_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>
|
|
|
|
MOVE.L a0,D0 ; Get result
|
|
BEQ.S @done ; EQ means no menulist or memfull
|
|
|
|
; Call the MBDF to put in the system menus
|
|
MOVEQ #2,D0 ; set up for the menu-edge-calc msg
|
|
CLR.L D1 ; calc entire bar
|
|
IMPORT CallMBarProc
|
|
jsr CallMBarProc
|
|
@done
|
|
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>
|
|
|
|
; Roll in PatchMDMenuKey <SM5> <PN>
|
|
import PushMenuState,PopMenuState ;<SM5> <PN>
|
|
|
|
resultsStackFrame
|
|
result ds.l 1 ; the menukey result <SM5> <PN>
|
|
parametersStackFrame
|
|
ch ds.w 1 ; the char to pass thru <SM5> <PN>
|
|
endStackFrame
|
|
|
|
linkSave
|
|
jsr PushMenuState ; Potentially save off the menu state <SM5> <PN>
|
|
subq #4,sp ; Make room for MenuKey result <SM5> <PN>
|
|
move.w ch(a6),-(sp) ; Push the character <SM5> <PN>
|
|
|
|
jsr OriginalMenuKey ;<SM5> <PN>
|
|
|
|
move.l (sp)+,result(a6) ; Save off the result <SM5> <PN>
|
|
jsr PopMenuState ; Restore the menu state if it was saved <SM5> <PN>
|
|
restoreUnlinkReturn
|
|
OriginalMenuKey
|
|
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
|
|
|
|
; begin by removing itemÕs entry in menu color table <FJL C408>
|
|
|
|
MOVE.L 30(SP),A3 ; get menu handle <FJL C408>
|
|
MOVE.L (A3),A0 ; get menu ptr <FJL C408>
|
|
move menuID(a0), -(sp) ; push menuID on stack <FJL C408>
|
|
MOVE.W 30(SP),-(sp) ; push itemNum on stack <FJL C408>
|
|
_DelMCEntries ; and remove item's menu color entry <FJL C408>
|
|
|
|
; 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
|