mac-rom/Toolbox/MenuMgr/StandardMBDF.a

3124 lines
119 KiB
Plaintext
Raw Normal View History

;
; File: StandardMBDF.a
;
; Contains: menu bar definition procedure
;
; Written by: David Fung
;
; Copyright: <09> 1986-1992 by Apple Computer, Inc., all rights reserved.
;
;
; Change History (most recent first):
;
; <SM3> 10/22/92 CSS Change some branch short instructions to word branches.
; <49> 4/30/92 DTY #1027995 <KSM>: SetTitleColor expects a4 to point to a MenuInfo
; record on entry. The BannerMsg routine calls SetTitleColor
; without setting up a4. This kinda makes sense, since the menu
; bar doesn<73>t have a MenuInfo record. However, if A4 contains
; trash, an error will occur. Make a4 nil in BannerMsg, and have
; SetTitleColor check to see if A4 contains nil. If it is, jump
; directly to @TryMenuBar.
; <48> 4/4/92 KSM #1019367,<DTY>: Allow for slop factor before dropping System
; menus when app menus are too long.
; <47> 10/28/91 SAM/KSM Rolled in Regatta file.
;
; Regatta Change History:
;
; <3> 8/8/91 SAM Adding HardwarePrivateEqu.a
; <2> 5/28/91 SAM Removed Gestalt check for Square menu bar cuz this code gets called
; so frquently. Replaced it with a slightly less cool lomem check.
; <1> 8/8/91 SAM Split off from 7.0 GM sources.
;
; 7.0 Change History:
;
; <46> 6/11/91 gbm Take out conditional for Regatta... we want that to be
; "standard" now
; <45> 4/3/91 SAM Added GestaltEqu.a to the list of includes (for the Regatta
; build).
; <44> 4/2/91 SAM Changed the "If we have a Portable ROM then dont round the menu
; bar corners" check to ask Gestalt if there should be square menu
; bars (for the Regatta build).
; <43> 4/2/91 VL KSM,#86088: Fixed the problem of a crash drawing an icon to the
; Application Menu when the Application Menu is not in the
; MenuList. This is done by adding another exit condition to the
; loop finding the Application Menu.
; <42> 3/21/91 KSM dty,#84128: If DrawMenuBar is called with a hilited title, it
; will only restore the bits of the hilited menu.
; <41> 3/19/91 KSM ngk,#83253: BUT Gifford showed why letting the TITLE bits be
; purgable was not too swift.
; <40> 3/13/91 KSM ddc,#83253: Call SaveRestoreBits with purgable bits option (why
; didn<64>t we do this before?)
; <39> 3/4/91 dba dty: get rid of SysVers conditionals
; <38> 2/22/91 VL KSM, #82413: ClipToTempRect didn't respect MBarHeight and that
; caused icons to be drawn even when the MBar is not visible (i.e.
; MBarHeight = 0). Fixed ClipToTempRect to use the minimum of
; MBarHeight and actual height of TempRect.
; <37> 1/21/91 DFH (KSM) Process Menu is now called Application Menu.
; <36> 1/7/91 JDR (dba) Changing the includes of Icons.a to IconUtilsPriv.a.
; <35> 11/13/90 KSM <dcc>Remove some deadwood (redundant compare).
; <34> 9/23/90 KSM <smb>Fix a hit testing bug when no system menus are installed.
; <33> 9/19/90 KSM Fix MBDF to not call PenMode (supposed to call TextMode).
; <32> 9/15/90 KSM Better plotting of color apple menu icon.
; <31> 9/11/90 KSM Fix to BannerMsg- calls HiliteMenu(0) before drawing the menubar
; string to prevent the flash of dehiliting the menu later.
; <30> 9/6/90 KSM Change CALC (#2) message to add system menus iff there is an
; apple menu. Fix up some TO DO's to be current.
; <29> 8/17/90 dvb grayishTextCopy->grayishTextOr
; <28> 8/14/90 KSM Oops, fix the previous fix.
; <27> 8/10/90 PN Fix graying for non-color machines since drawstring on these
; machines does not recognize _PenPat(grayishtext).
; <26> 8/9/90 DC changed apple menu to use Icon Suite in stead of cicn. Fixed up
; color handling of icons again.
; <25> 8/6/90 DC fixed color environment arount ploticonsuite to allow for menu
; colorizers (Kolor, et al.)
; <24> 7/26/90 KSM fix hierarchical menu title hiliting bug by ignoring the
; parameter when told to unhilite a menu title
; <23> 7/20/90 DVB Fix for classic machines...
; <22> 7/17/90 DVB Add grayish items
; <21> 7/16/90 VL Added new messages (MoveICSToAM, MoveSICNToPM and MoveICSToPM)
; for Notification Mgr. MoveSIcon is renamed to MoveSICNToAM.
; <20> 6/8/90 dba use Begin/EndDrawingOffscreen
; <19> 6/8/90 dba create code for buffering redraws of the whole menu bar to avoid
; flicker; made many branches short ones
; <18> 6/5/90 KSM FIx bug in drawing menu items when 2 (or more) system menus are
; not draw because the app menus have encroached upon it (A11
; fix).
; <17> 5/31/90 KSM Bug fix in HitBar-high word of D4 not cleared. Tweek system
; menus left 1 pixel for rt just. Also fixed A10 bugs MF(A6).
; Fixed IconUtils to be Icons.a
; <16> 5/31/90 KSM Bug fix in HitBar-high word of D4 not cleared. Tweek system
; menus left 1 pixel for rt just. Also fixed A10 bugs MF(A6).
; Fixed IconUtils to be Icons.a
; <15> 5/22/90 DC Changed name of PlotBestIcon to PlotIconSuite
; <14> 5/9/90 KSM New message (#15): BannerMsg (for Finder).
; <13> 5/9/90 KSM New message (#14) added: GetTitleRect.
; <12> 5/7/90 KSM Rect for system menus are now aligned with right side of title
; hilite.
; <11> 4/30/90 KSM Handle all the nasty issues when the app menus begin to encroach
; on system menus.
; <10> 4/29/90 KSM Changed the routine dispatch table to use the stack frame macros
; (since I'm about to add new calls). Forced drawing apple in B&W
; when monitor is in multi-bit B&W mode to avoid the ugly, striped
; apple. Cleaned up rectangle calcs for hilighting titles. Apple
; menu and Application Menu are now perfectly symmetrical.
; <9> 4/24/90 dba fix error I made in previous change (move addq.w inside the
; conditional)
; <8> 4/21/90 dba I is a idiot; it instead of if
; <7> 4/20/90 dba get rid of the two special anti-aliased color icons for apple on
; black and apple on white
; <6> 4/20/90 KSM Fix bug munging locked menulist handle. Use new interface to
; SaveRestoreBits calls.
; <5> 4/13/90 DFH Fixed DrawCommon to properly transform iconic title
; when hilighted.
; <4> 4/11/90 KSM Update calls to _GetAuxMenuItem to include itemnum param and add
; support for color icons.
; <3> 4/10/90 dba use SaveBits and RestoreBits; use fancy color Apple icons;
; include Kevin<69>s changes to support system menus; added support
; for icon menu titles; put in stupid kludge to make things work
; on the Mac II
; <2> 1/31/90 RLC Update HelpMgr calls and conditionally build in macros.
; <2.2> 9/26/89 CCH Added conditionals around references to SysVers equate for ROM.
; Minor fixes to changes from version 2.1 (hierarchical menu
; placement).
; <2.1> 9/25/89 DFH Added ExpandItem to get extra menu item information.
; <2.0> 8/29/89 RLC Changed calling structure to the HelpMgr (_Pack14).
; <1.9> 8/22/89 SES Removed references to nFiles.
; <1.8> 8/12/89 dba NEEDED FOR 6.0.4: reintroduced a bug fix lost in the transition
; from 6.0.3 sources; fixes problems with hierarchical menus above
; the menu bar
; <1.7> 8/10/89 RLC Changed selector message to Help Mgr Pack to MOVEQ #select,D0
; <1.6> 6/2/89 KSM Updated conditionals for ROM/SYS build AGAIN.
; <1.5> 6/2/89 KSM Updated conditionals for ROM/SYS build.
; <1.4> 6/1/89 KSM BALLOON HELP support added.
; <1.3> 3/1/89 MSH Dave F provided the first pass at external video support
; (Topanga) and I tweaked it until it worked.
; <1.4> 2/10/89 DAF Modified MBDF for Harpo. This includes a number of
; modifications: 1) onLCDMac stack variable created to identify
; Harpo. 2) Rounded corner framing draws white or black depending
; on video mode iff on Harpo 3) Menubar is framed if on Harpo
; internal display, is one pixel taller, and titles start one
; pixel in.
; <1.2> 2/9/89 EMT Courtesy Walter Smith, fixed bug in GetMenuAscent.
; <1.1> 11/11/88 CCH Fixed Header.
; <1.0> 11/9/88 CCH Adding to EASE.
; <<3C>1.2> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
; <<3C>1.1> 3/22/88 EMT Roll in menu manager patches from 6.0 system.
; <S423> 3/9/88 EMT Fix empty menu bug
; PMAB364> 1/23/88 EMT Fix Pop-up menus to come up on any screen
; <S358> 1/12/88 EMT Fix orphaned handles in MBDF
; <S334> 12/15/87 EMT Remove call to PurgeSpace in MBDF
; <S321> 12/3/87 EMT MBDF now uses MultiFinder temporary memory allocation.
; <S297> 10/20/87 EMT Change FullClip to use QD wideOpen region. Modify Draw message
; to include single title draw. Added MoveSIcon message for
; Notification Manager. Miscellaneous optimizations.
;
; System 4.2
;
; 7/20/87 FJL MoveQ #0,D0 in several places to ensure parameter to _NewHandle
; is ok.
; 3/26/87 FJL Save and restore pen state for the application Tempo.
; 3/6/87 FJL Clean up all OnNuMac conditionals for System Disk --> Universal
; defproc
; 2/10/87 FJL C784 Leave TextMode srcOr, fixes BusFileVision
; 11/18/86 FJL A428 Lock handle for non-nuMac in SaveDemBits. Change
; DrawMenuBar so draws selected item after all titles are drawn,
; rather than in loop.
; 11/15/86 FJL C408 Added support for color menus
; 11/5/86 FJL CXXX General clean up and documentation.
; 10/27/86 FJL A278 Force menu font to be system font at all times. Hacked up
; HiliteMenu so it inverts/inverts on menu select/unselect for
; Alladin. (removed during clean up)
; 10/8/86 FJL C175 Expanded stackframe. Lock and unlock MenuList handle.
; Utility GetAscent. Fixed DrawMenu loop, and HiliteBar. Added
; 4-bit color apple. Utility CheckForApple. Fixed SaveBits
; problem. Fixed incorrect rect size in MakeUpdate.
; 9/15/86 DAF New today
;
; FUNCTION MenuBarProc ( selector: INTEGER;
; message: INTEGER;
; parameter1: INTEGER;
; parameter2: LONGINT): LONGINT
;
; Msg Selector Param1 Param2 Result
;--------- -------------- -------------- -------------- -------------
; 0 Draw mbVariant none -1 = clear none
; 0 = all none
; <pos> = 6 B.O. none
; 1 Hit mbVariant none mouse point 0 = in bar, no hit
; -1= not in bar
; <pos> = 6 B.O.
; 2 Calc mbVariant none 0 = all none
; <pos> = 6 B.O. none
; 3 Init mbVariant none size none
; 4 Dispos mbVariant none none none
; 5 Hilite mbVariant none <packed> none
; 6 Height mbVariant none none none
; 7 Save mbVariant 6 B.O. ptr to menuRect none
; 8 Restor mbVariant none none none
; 9 GetRect mbVariant none <packed2> ptr to menuRect
;10 SaveAlt mbVariant none 6 B.O. none
;11 ResetScroll mbVariant none 6 B.O. none
;12 GetMenuRgn mbVariant none region handle region handle
;13 MoveSICNToAM mbVariant distance sicon handle 0 = keep current icon
; 0=replace 0 = use title -1 = go to next icon
;14 GetTRect mbVariant <pos> = 6 B.O. ptr-to-menuRect none
; 0 = MenuBarRect
; -1 = Rect enclosing visible app menus
; -2 = Rect enclosing visible system menus
;15 BannerMsg mbVariant <special> ptr to pString none
; lo byte=scriptID
; hi byte=teJust for textbox
;16 MoveICSToPM mbVariant distance ics handle 0 = keep current icon
; 0=replace 0 = use title -1 = go to next icon
;17 MoveICSToAM mbVariant distance ics handle 0 = keep current icon
; 0=replace 0 = use title -1 = go to next icon
;18 MoveSICNToPM mbVariant distance SICN handle 0 = keep current icon
; 0=replace 0 = use title -1 = go to next icon
;
; NOTES: 6 B.O. == 6 byte offset into menuList
; <packed> == hiword -- 0=normal, 1=selected, 2=disabled, 3=busy,
; 128+=SICN rsrcID to be blitted
; loword -- 0=flip bar, positive value=6 byte offset
; <packed2> == hiword -- if =0 then is normal menu,
; else contains vertical mouse pt for HMenu top calc
; loword -- 6 B.O.
;
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
LOAD 'StandardEqu.d'
INCLUDE 'InternalMacros.a'
INCLUDE 'MFPrivate.a'
INCLUDE 'IconUtilsPriv.a'
INCLUDE 'MenuMgrPriv.a'
INCLUDE 'Balloons.a'
INCLUDE 'GestaltEqu.a'
INCLUDE 'HardwarePrivateEqu.a'
selectBeginDrawingOffscreen EQU 4
paramWordsBeginDrawingOffscreen EQU 4
MACRO
_BeginDrawingOffscreen
DoDispatch _SaveRestoreBits,selectBeginDrawingOffscreen,paramWordsBeginDrawingOffscreen
ENDM
selectEndDrawingOffscreen EQU 5
paramWordsEndDrawingOffscreen EQU 2
MACRO
_EndDrawingOffscreen
DoDispatch _SaveRestoreBits,selectEndDrawingOffscreen,paramWordsEndDrawingOffscreen
ENDM
if &type('useAntiAliasedApples') = 'UNDEFINED' then
useAntiAliasedApples: equ 0
endif
MACRO
_DMSG &msg
if &msg = '' then
_Debugger
else
BRA.S @overstring
@dbgStrBase:
DC.B &msg
ALIGN 2
@overstring:
PEA @dbgStrBase
_DebugStr
endif
ENDM
;--------------------------------------------------------------------------------------------
; value for itemIconSize (but not itemCmd) <2.1>
LargeIconCmd EQU $1F ; large icon plotted
; special values of the itemCmd field before expansion <2.1>
ShrunkenIconCmd EQU $1D ; itemCmd == $1D ==> large icon plotted in 16x16
SmallIconCmd EQU $1E ; itemCmd == $1E ==> small icon plotted
; resource IDs of color icons that look like the Apple logo
;rAppleOnWhite equ -16385 ; anti-aliased apple on a white background
;rAppleOnBlack equ -16386 ; anti-aliased apple on a black background
rAppleSuite equ -16386 ; I'm hijacking the assigned resource number of rAppleOnBlack <DCC 8/8/90>
rAppleWithMask equ 20 ; less attractive apple that works on any background
; Switches for drawing the icons
; bit 0 is for icon type and bit 1 is for menu type
SICNInAppleMenu equ $00
SICNInApplicationMenu equ $02
ICSInAppleMenu equ $01
ICSInApplicationMenu equ $03
;____________________________________________________________________________________________
;
; StackFrame and Global Definitions
;
;____________________________________________________________________________________________
MenuBarDefProc PROC EXPORT
MBDFRegSave REG D3-D6/A2-A4
mTitleSpace EQU 13 ; Space between menu titles in menu bar
; Stack Frame Definition for MBarProc
; FUNCTION MenuBarProc ( selector: INTEGER; message: INTEGER;
; parameter1: INTEGER; parameter2: LONGINT): LONGINT;
resultsStackFrame
Result DS.L 1
parametersStackFrame
Selector DS.W 1
Message DS.W 1
Param1 DS.W 1
Param2 DS.L 1
localsStackFrame
MenuRect DS.W 4
colorPortP DS.L 1
appleRect DS.W 4
applePixMapH DS.L 1
SelectFlag DS.W 1
TitleBackFlag DS.W 1
PixelDepth DS.W 1
theGDColorTbl DS.L 1
MenuDir DS.W 1
VMousePt DS.W 1
saveBackColor DS.W 3
saveForeColor DS.W 3
tempHandle DS.L 1
saveD3 DS.W 1
onLCDMac DS.B 1 ; if high bit is set, then internal Harpo display active<DAF 10Feb89><v1.4>
onColorMachine DS.B 1 ; <FJL 96Mar87>
; the following are for offscreen buffering of the menu in response to the draw message
menuBarBuffer ds.l 1 ; handle to the offscreen buffer
; The following defines are for GetItemHeight which was copied from MDEF (UGGHHLLYYYY!)
MFHeight DS.W 1
MWidMax DS.W 1
MDescent DS.W 1
MAscent DS.W 1
MInfoRec EQU MAscent ; <1Aug85>
; Extensions to a menu item <2.1>
itemScript DS.W 1 ; item text script code
itemIconGray DS.W 1 ; whether icon should be grayed
itemIconSize DS.W 1 ; full-sized/small/shrunken
itemIconHandle DS.L 1 ; handle to icon (or nil)
itemHierarchicalID DS.W 1 ; hierarchical menu ID
itemOrigAttrs DS.B 4 ; original attributes
itemStackBase EQU *
endStackFrame
; -------------------------------------------------------------------------------------
FirstMBMsg EQU 0
LastMBMsg EQU 18 ; <EMT S297>
;--------------------------------------------------------------------------------------------
;
; Start of Code -- save work registers and dispatch on message number.
;
; Set up: A2 -- WMgrPort
; A3 -- ptr to menu list
;
;--------------------------------------------------------------------------------------------
BRA.S StartMBDF
; Standard Header
MBDFFlags DC.W 0 ; flags word
DC.l ('MBDF') ; resource type
DC.W 0 ; resource ID
DC.W 13 ; version 0 = onNuMac ROM
; version 10 = Universal
; version 12 = Universal 6.0 <PMAB364 23Jan88 EMT>
; version 13 = System 7.0
StartMBDF
linksave MBDFRegSave
subq.l #4,sp ; make room for saved port on the stack
move.l sp,-(sp) ; Point to that result
_GetPort
clr onColorMachine(a6) ; clear color machine flag (and onLCDMac) <FJL 06Mar87> <DAF 10Feb89><v1.4>
cmpi.w #$3FFF, ROM85 ; color machine ?
sls onColorMachine(a6) ; set byte to 1s if yes
MOVE.W HwCfgFlags,D0 ; Get them Hardware Config Flags
BTST.L #hwCbPwrMgr,D0 ; Do we have a PowerMgr?
BEQ.S @100 ; -> Nope, assume rounded menu bar
TST.B NTSC ; is it on the internal display? <DAF 10Feb89>
BNE.S @100 ; nope, so skip this <DAF 10Feb89>
BSET #7,onLCDMac(A6) ; set high-bit to mark internal display <DAF 10Feb89>
@100
tst.b onColorMachine(a6)
beq.s @SetBWPort
move.l WMgrCPort,a2 ; get color port
bra.s @SetPort
@SetBWPort
MOVE.L WMgrPort,a2 ; get non-color port
@SetPort
MOVE.L A2,-(SP) ; set the WMgrPort
_SetPort
; start by setting the window manager font to the system font
clr.l -(sp) ; clear stack for next 2 calls <FJL A278>
_TextFont ; set font to system font <FJL A278>
_TextFace ; set style to plain <FJL A278>
MOVE.L MenuList,A0 ; get the menuList handle <FJL C175>
TST.L (A0) ; has it been purged? <FJL C175>
BNE.S @menuListOK ; => yes, go to purgeatory
MOVEQ #MenuPrgErr,D0 ; get our error code
_SysError ; and roast in eternal damnation
@menuListOK ; lock the MenuList so a3 ptr doesn't move <FJL C175>
_HLock ; lots of alloc'ing in color apple routines <FJL C175>
MOVE.L (A0),A3 ; and get the pointer
LEA GoBarProc,A0 ; get the dispatch table base
MOVE.W message(A6),D0 ; get the message number
cmpi #LastMBMsg, d0 ; is the message within bounds?
bhi.s @InvalidMsg ; oops, its too high
cmpi #FirstMBMsg, d0 ;
blo.s @InvalidMsg ; oops, its too low
ADD.W D0,D0 ; double to get words
ADD.W GoBarProc(D0.w),A0 ; compute the dispatch address
JSR (A0) ; do the routine
@InvalidMsg
_SetPort ; restore the caller's port
move.l menuList, a0 ; set up to unlock menuList handle <FJL C175>
_HUnlock ; and unlock it <FJL C175>
restoreUnlinkReturn
GoBarProc Table
DT.W DrawBar ; draw is message #0
DT.W HitBar ; hit test is message #1
DT.W CalcBar ; calculate menu edges #2
DT.W InitBar ; init is message #3
DT.W DisposeBar ; dispose is message #4
DT.W HiliteBar ; hilite a title #5
DT.W HeightBar ; calculate mBar height #6
DT.W SaveBitsBar ; save menuBits #7
DT.W RestoreBitsBar ; restore menuBits #8
DT.W GetRectBar ; get menu's rectangle #9
DT.W SaveAltBar ; save other data #10
DT.W ResetScrollBar ; reset scrolling globals #11
DT.W ReturnMenuRgn ; return menu's region #12
DT.W MoveSICNToAM ; move small icon #13 <EMT S297>
DT.W GetTRect ; return title rect #14 <KSM><13>
DT.W BannerMsg ; Use menubar as banner #15 <KSM><14>
DT.W MoveICSToPM ; Move icon suite #16
DT.W MoveICSToAM ; Move icon suite to Apple Menu #17
DT.W MoveSICNToPM ; Move SICN to Application Menu #18
;******************************************************************************************
;* *
;* IF YOU ADD ANOTHER MESSAGE YOU MUST UPDATE THE VARIABLE "LastMBMsg" FOUND ABOVE !!!!!! *
;* *
;******************************************************************************************
;-----------------------------------------------
; FullClip -- set clip wide open
;-----------------------------------------------
FullClip
MOVE.L GrafGlobals(A5), A0 ; <EMT S297>
MOVE.L wideOpen(A0), -(SP) ; set the clip to wide open <EMT S297>
_SetClip ; <EMT S297>
rts
;--------------------------------------------------------------------------------------------
;
; Msg #3 -- Init -- allocate storage for saving bits behind for up to 5 menus
;
;--------------------------------------------------------------------------------------------
; <FJL C222>
; The Init Message initializes a data structure in which it stores information
; on up to 5 menus showing on the screen at once. This structure is documented
; in nToolEqu.a. It is allocated only once, the first time this message is passed
; after system startup.
InitBar
cmpi.l #-1, mbSaveLoc ; If first time after system start up, mbSaveLoc
; will have -1 in it
bne.s @clearIt ; if not first time then just clear lastMBSave
; else, alloc space
move.l #mbSaveSize, d0 ; alloc space for x-byte header plus
; 5 x-byte menu entries
_NewHandle SYS,CLEAR ; alloc handle on system heap and clear it
move.l a0, mbSaveLoc ; store the handle in low memory
@clearIt move.l mbSaveLoc, a0 ; get mbSaveLoc
move.l (a0), a0 ; dereference
clr lastMBSave(a0) ; ===> no menus showing
RTS
;--------------------------------------------------------------------------------------------
;
; Msg #4 -- Dispose -- nothing for now since we leave mbSaveLoc handle in sys heap all the
; time, never mind the fact that no one sends this message.
;
;--------------------------------------------------------------------------------------------
DisposeBar ; <FJL C222>
RTS
;--------------------------------------------------------------------------------------------
;
; Msg #6 -- Calc MB Height -- get MB Height into low memory global MBarHeight.
;
;--------------------------------------------------------------------------------------------
;
; the Height Message just calculates the lomem variable MBarHeight
; It's here for backward compatibility with the original ROM usage.
HeightBar
BSR.S GetMenuInfo ; get font info for wmgr port
MOVEQ #3,D1 ; get white space into D1
ADD.W D0,D1 ; add descent
SWAP D0 ; get ascent
ADD.W D0,D1 ; add ascent
MOVE.W D1,MBarHeight ; save it in low memory
RTS
;-----------------------------------------------
; Utility -- GetMenuInfo
;-----------------------------------------------
;
; GetMenuInfo is a utility that returns the ascent of the window manager's font in the high
; half of D0, and the descent in the low half. It trashes only insignificant registers.
GetMenuInfo
SUBQ #8,SP ; make room for a font info record
MOVE.L SP,-(SP) ; point to 8 byte info record
_GetFontInfo ; get font info for the system font
MOVE.L (SP)+,D0 ; return ascent, descent in D0
SWAP D0 ; get ascent in lo-word <FJL 22Jan87>
ADD 2(SP), D0 ; add leading to ascent <FJL 22Jan87>
ADDQ #1, D0 ; add one for good measure <FJL 22Jan87>
SWAP D0 ; restore D0 <FJL 22Jan87>
ADDQ #4,SP ; flush record
RTS
;-----------------------------------------------
; Utility -- GetMenuAscent
;-----------------------------------------------
;
; GetMenuAscent is a utility that returns the y-value for drawing the <FJL C175>
; font above the menu bar in D4.
GetMenuAscent
BSR.S GetMenuInfo ; get the font ascent
SWAP D0 ; get ascent in lo half
ADD.W portRect+top(A2),D0 ; add in portRect offset <1.2>
MOVEQ #0,D4 ; clear hi half of register
MOVE.W D0,D4 ; get the ascent + leading <FJL 22Jan87>
RTS
;-----------------------------------------------
; Utility -- ClipMBar
;-----------------------------------------------
;
; ClipMBar is a utility that sets the port's clipRgn to the menu bar.
; <EMT S297>
ClipMBar
MOVE.L CLIPRGN(A2),-(SP) ; push a handle to the clipRgn
; use portRect instead of assuming topLeft is (0,0) <FJL CXXX>
move portRect+Left(a2), -(sp); left
move portRect+Top(a2), -(sp) ; top
move PortRect+Right(A2),-(SP); right
move portRect+Top(a2), -(sp) ; bottom = top + mBarHeight
move MBarHeight, d0
add d0, (sp)
_SetRecRgn ; clip to the menu bar
RTS
;-----------------------------------------------
; Utility -- ClipToTempRect <11>
;-----------------------------------------------
;
; ClipToTempRect is a utility that sets the port's clipRgn to the application's menu area.
ClipToTempRect
LEA TempRect, A0 ; Get the base address of TempRect
MOVE.L CLIPRGN(A2),-(SP) ; push a handle to the clipRgn
MOVE.W left(A0), -(sp) ; left
MOVE.W top(A0), -(sp) ; top
move.w MBarHeight,d0 ; MBarBottom = top+MBarHeight <38>
move.w bottom(a0),d1 ; bottom <38>
add.w (sp),d0 ; sp points to top of TempRect <38>
cmp.w d1,d0 ; use MIn(bottom,MBarBottom) <38>
blt.s @useMBarHeight ; <38>
move.w d1,d0 ; <38>
@useMBarHeight ; <38>
MOVE.W right(A0), -(sp) ; right
move.w d0,-(sp) ; <38>
_SetRecRgn ; clip to TempRect
RTS
;--------------------------------------------------------------------------------------------
;
; Msg #0 -- Draw the MB
;
;--------------------------------------------------------------------------------------------
;
; the Draw Message simply(!) draws the entire menu bar, if parameter is 0. If parameter is -1,
; then draw just a cleared menu bar. Otherwise, draw one title. No result is returned
DrawBar
; Set the clip region to the menu bar. If we are called to just clear the menu bar
; then the clip will stay set to this, else it will be set wide open
BSR.s ClipMBar ; <EMT S297>
MOVE.L Param2(A6), D3 ; Get the parameter <EMT S297>
BGT Its1Title ; Skip if it's a 1 Title draw <EMT S297>
cmp.l #-1,d3 ; if clear, don<6F>t use buffer <19>
beq.s @skipBuffering ; ignore the error <19>
rsrv.w ; room for error <20>
move.l clipRgn(a2),a0 ; start with the clipRgn <20>
move.l (a0),a0 ; dereference it <20>
pea rgnBBox(a0) ; pass the bounding box <20>
pea menuBarBuffer(a6) ; pass place for buffer <20>
_BeginDrawingOffscreen ; make the buffer <20>
free.w ; ignore the error <20>
@skipBuffering
; start by clearing the menubar area to the proper background color
tst.b onColorMachine(a6)
beq.s @DoErase
bsr SaveCurrentColors ; save current colors in stackframe
bsr GetPixelDepth ; put the current pixel depth in the stack frame
cmpi.w #2, PixelDepth(a6) ; is this 2+ mode, and color ?
blt.s @DoErase ; no, its 1 bit mode, so don't set color
subq #4, sp ; save space for result
clr.l -(sp) ; ID=0, Item=0 ===> menubar entry
_GetMCEntry ; get the color entry
move.l (sp)+, d0 ; get the result, and set z-flag if necessary
beq.s @DoDefault ; zero ===> no entry so use default
; we got a menu bar entry from the color table, so use it to color the menu bar
;
; normally we would set the forecolor to black for the erase rounded corners, but Quickdraw now
; assumes that if both fore/back "revert" to black (or white) in one bit mode then it reverses
; the backcolor, so we have to set the forecolor to the default title color here, then reset
; the colors for the rounded corner erase.
move.l d0, a0 ; get ptr to color entry in a0
pea mctRGB1(a0) ; push fore color
pea mctRGB4(a0) ; push back color
_RGBBackColor ; set the back color
_RGBForeColor ; set the fore color
bra.s @DoErase
@DoDefault ; default is always black on white
pea RGBBlack
pea RGBWhite
_RGBBackColor
_RGBForeColor
@DoErase
PEA PORTRECT(A2) ; push a pointer to full screen rectangle
BTST #7,onLCDMac(A6) ; is this Harpo <DAF 10Feb89><v1.4>
BZ.S @regErase ; if so, then do usual <DAF 10Feb89>
_EraseRect
BRA.S @doneErase
@regErase
MOVE.L #SCREENRADIUS,-(SP) ; push roundRect parameter
_EraseRoundRect ; paint the menuBar white
@doneErase
; erase around rounded corners because multiple screens leave little pieces of deskpat there
tst.b onColorMachine(a6)
beq.s @notColor
pea RGBBlack ; set black on white for erasing rounded corners
pea RGBWhite
_RGBBackColor
_RGBForeColor
@notColor
move.l portRect(a2), TempRect ; copy top, left
move.l portRect+Bottom(a2), TempRect+Bottom ; copy bottom, right
LEA TempRect,A0 ; get temp rect address
BTST #7,onLCDMac(A6) ; is this Harpo <DAF 10Feb89><v1.4>
BNZ.S @skipFrame ; if so, then no framing <DAF 10Feb89>
MOVE.L A0,-(SP) ; push the temp rect
MOVE.L #$FFFDFFFD,-(SP) ; and make it bigger
_InsetRect ; by 3 pixels on each side
MOVE.L #$00030003,-(SP) ; get a wider pen
_PenSize
LEA TempRect, A0 ; get temp rect address again
MOVE.L A0,-(SP) ; push the temp rect
MOVE.L #$00160016,-(SP) ; and a radius for nice rounding
_FrameRoundRect ; and black out the corners
@skipFrame
_PenNormal ; fix the pen back up <v1.4>
; use portRect instead of assuming topLeft is (0,0) <FJL CXXX>
MOVE.W PortRect+Right(A2),-(SP) ; push extreme right
move portRect+Left(a2), d0 ; get left in lo-byte
swap d0 ; put it in hi-byte
move portRect+Top(a2), d0 ; get top
add MBarHeight,D0 ; add menu bar height to get bottom
SUBQ.W #1,D0 ; need bottom-1
MOVE.W D0,-(SP) ; push vertical for LineTo
SWAP D0 ; get vertical in high word
MOVE.L D0,-(SP) ; and push point for MoveTo
_MoveTo ; move to left of line
_LineTo ; draw the line
bsr ResetPreviousColors ; reset colors before leaving
; if the parameter is -1, then return (just clear the bar). LEAVE CLIP SET TO MENU BAR !!!
CMP.L #-1,Param2(A6)
BEQ DrawDoneNoUnclipNoBuffering
; get ready to draw the menuList on the menuBar
TST.W (A3) ; any menus in the menuList?
BEQ DrawDone ; if not, we're done
clr.w saveD3(a6) ; assume no title hilited <FJL A428>
MOVEQ #6,D3 ; start with first (leftmost) entry
;---------------------------------------------------------
; main drawing loop
;---------------------------------------------------------
;
; This is the loop that draws the titles on the menu bar. It handles hiliting
; and graying out.
;
; on entry A3 MenuListP menu list pointer. Note: handle is locked
; D3 index index into menu list (#6 byte offsets)
; calc'ed A4 MenuInfoP Ptr into menu data for currently drawn menu.
;
; TODO: DrawMenuBar with a hilited menu leaves a handle around. The handle
; contains the bits behind the previously hilited menu! The reason is that
; Excel was screwing around with the menubar and we couldn't be sure that
; the handle in mbBitsBehind actually contained a handle to the bits behind
; the hilited menu. So, we couldn't dispose of the menu without Excel
; blowing up every time. Aaghhh!!!
DrawMLoop
move d3, d0 ; set up for GetTitleRect <FJL C175>
BSR GetTitleRect ; get this title's rect in TempRect <FJL C175>
move.l menuOH(A3,D3),A0 ; get the selected menuHandle <FJL C175>
_HLock ; lock it down <FJL C175>
MOVE.L (A0),A4 ; and dereference handle <FJL C175>
BSR Draw1Title ; use utility to draw text and <FJL C175>
; disable if necessary <FJL C175>
move.w theMenu, d0 ; get ID of hilited menu <FJL C175>
move.l menuOH(A3,D3),A4 ; reset a4, get the selected menuHandle <FJL C175>
MOVE.L (A4),A4 ; dereference handle <FJL C175>
cmp.w menuID(a4), d0 ; should this one be hilited? <FJL C175>
bne.s NextDraw ; no, then branch <FJL C175>
move d3, saveD3(a6) ; save d3 on the stack for use later <FJL A428>
; we're done processing one menu -- bump to the next one and loop if there's more to do
NEXTDRAW
move.l menuOH(A3,D3),A0 ; get the selected menuHandle <FJL C175>
_HUnlock ; unlock it <FJL C175>
SkipSysLoop
ADDQ #6,D3 ;bump index to next in list
CMP (A3),D3 ;compare d3 with lastMenu. Are we done?
BGT.S DONEDRAWMLOOP ; we're done
MOVE.L menuOH(A3,D3), A0 ; get the selected menuHandle <18>
MOVE.L (A0), A0 ; Get the menuptr
MOVE.W menuID(A0), D0 ; Get the menuID
CMP.W #-16384,D0 ; Is it a system menu
BGE.S DrawMLoop ; Nope, keep going
MOVE.W lastRight(A3), D0 ; Find right edge of reg menus
CMP.W menuLeft(A3,D3), D0 ; Is it after right edge?
BLE.S DrawMLoop ; Yes, it is
BRA.S SkipSysLoop ; Skip this menu
; select the item that is selected (if any) now, AFTER drawing all the titles
DONEDRAWMLOOP
BSR ClipMBar ; Restore the clip to the whole menu bar <10>
move saveD3(a6), d0 ; get savedID of hilited menu <FJL A428>
beq DrawDone ; branch if none <FJL A428> <SM3> CSS
move d0,d3 ; and put it in d3 too <FJL A428>
bsr GetTitleRect ; get selected title's rect <FJL A428>
move.l menuOH(a3,d3),a0 ; get selected menuHandle <FJL A428>
_HLock ; lock it down <FJL A428>
move.l (a0), a4 ; dereference <FJL A428>
bsr DoSelected ; and select it <FJL A428>
move.l menuOH(a3,d3),a0 ; get selected menuHandle <FJL A428>
_HUnlock ; unlock it <FJL A428>
BSR ClipMBar ; Restore the clip to the whole menu bar <42>
BRA.S DrawDone ; <EMT S297>
Its1Title ; <EMT S297>
CMP.W (A3), D3 ; Is it in the legal range? <EMT S297>
BGT.S DrawDone ; Skip if not <EMT S297>
MOVE.L D3, D0 ; Set up for GetTitleRect <EMT S297>
BSR GetTitleRect ; Get this title's rect in TempRect <EMT S297>
lea TempRect,a0 ; pass the item rectangle <19>
bsr BeginMenuBuffering ; make a buffer for this item <19>
MOVE.L menuOH(A3, D3), A0 ; Get the selected menuHandle <EMT S297>
_HLock ; Lock it down <EMT S297>
MOVE.L (A0), A4 ; And dereference handle <EMT S297>
BSR.S Draw1Title ; Draw it <EMT S297>
MOVE.W theMenu, D0 ; Get ID of highlighted menu <EMT S297>
CMP.W menuID(A4), D0 ; Should it be highlighted? <EMT S297>
BNE.S Its1Done ; Skip if not <EMT S297>
BSR DoSelected ; Select it <EMT S297>
Its1Done ; <EMT S297>
MOVE.L menuOH(A3, D3), A0 ; Get the menuHandle <EMT S297>
_HUnlock ; Unlock it <EMT S297>
; be a good citizen and set the clip rgn to full open
DrawDone
rsrv.w ; make room for error <20>
push.l menuBarBuffer(a6) ; here<72>s where we stored it <20>
_EndDrawingOffscreen ; finish buffering, and draw something <20>
free.w ; discard error <20>
bsr FullClip
DrawDoneNoUnclipNoBuffering
RTS
;--------------------------------------------------------------
; Utility -- Draw1Title -- draw one title in the menu bar
;--------------------------------------------------------------
;
; Here is the code that draws a title on the menu bar. It handles
; hiliting and graying out. It shares DrawCommon with DoSelected.
; It also sets the proper title colors for color and black/white
; machines.
;
; on entry A3 MenuList menu list pointer!
; A4 menu ptr selected menu pointer
; D3 index index into menu list (#6 offsets)
; D0 param2
; calc here D4 font info font ascent + leading (see GetMenuInfo)
Draw1Title
clr.w SelectFlag(a6) ; clear select flag ==> draw normal mode
CMP.W #6, D3 ; Is it the apple menu? <EMT S297>
BNE.S DrawCommon ; Skip if not <EMT S297>
MOVE.L mbSaveLoc, A0 ; Get handle to save data <EMT S297>
MOVE.L (A0), A0 ; Dereference it <EMT S297>
MOVE.W #-1, mbIconState(A0) ; Reset icon rotation <EMT S297>
DrawCommon
bsr GetMenuAscent ; returns y-val in D4
MOVE MENULEFT(A3,D3),-(SP) ; x coordinate is menuLeft[index]+8
move portRect+Left(a2), d0 ; <FJL CXXX>
add d0, (sp) ; adjust for portRect <FJL CXXX>
ADDQ #8,(SP) ; indent a little
MOVE.W D4,-(SP) ; set y coordinate
_MoveTo ; position the point to start drawing
clr TitleBackFlag(a6) ; calling SetTitleColor from DrawTitle
bsr SetTitleColor ; set color for title/background
pea TempRect ; clear the title rect to the backColor
_EraseRect
; DrawSimple is a simplified DrawCommon. It draws the title at the given pen point.
DrawSimple
bsr ClipToTempRect ; Keep drawing contained <11>
move.w #srcOr, -(sp) ; set text mode to srcOr
_TextMode
tst.b onColorMachine(a6)
beq.s DrawATitle
cmpi.w #$0114, menudata(a4) ; is the title the AppleMark?
bne.s DrawATitle ; no, so branch
BSR GetPixelDepth ; Get the current pixel depth <EMT S297>
CMP.W #4, PixelDepth(A6) ; 4+ pixel depth? <EMT S297>
BLT.S DrawATitle ; Wrong depth, use system font <EMT S297>
BSR IsBWMode ; Check to see if we are in B&W mode <10>
BEQ.S DrawATitle
if useAntiAliasedApples then
subq.w #6,sp ; make room for a color
move.l sp,-(sp)
_GetBackColor ; check background color
cmp.l #$FFFFFFFF,(sp) ; is it white?
bne.s @notWhite
cmp.w #$FFFF,4(sp) ; is it white?
bne.s @notWhite
@white
move.w #rAppleOnWhite,d0 ; get the apple on white
bra.s @gotID
@notWhite
tst.l (sp) ; is it black?
bne.s @notBlack
tst.w 4(sp) ; is it black?
bne.s @notBlack
@black
move.w #rAppleOnBlack,d0 ; get the apple on black
bra.s @gotID
@notBlack
moveq #rAppleWithMask,d0 ; get the (less attractive) apple for any background
@gotID
addq.w #6,sp ; get rid of the color
endif
BSR CalcRightRectSize
SUBQ.L #2, SP ; Make room for return value <DCC 8/8/90>
PEA TempRect ; push the address of the dest rectangle <DCC 8/8/90>
MOVEQ #atCenterTop, D0 ; get the alignment code <DCC 8/8/90>
MOVE.W D0, -(SP) ; push it. <DCC 8/8/90>
BTST #0, menuEnable+3(a4) ; is the title disabled? <DCC 8/8/90>
BNE.S @notGray ; if not, then don't use a transform <DCC 8/8/90>
MOVEQ #ttDisabled, D0 ; else use ttDisabled <DCC 8/8/90>
BRA.S @transform ; <DCC 8/8/90>
@notGray MOVEQ #ttNone, D0 ; <DCC 8/8/90>
@transform MOVE.W D0, -(SP) ; push the transform <DCC 8/8/90>
MOVE.W #rAppleSuite, -(SP) ; push the id of the color apple icon suite <DCC 8/8/90>
_PlotIconID ; plot the puppy <DCC 8/8/90>
ADDQ.L #2, SP ; Don't care about the result <DCC 8/8/90>
bsr ResetPreviousColors ; reset to original fore/back colors
rts ; and return
DrawATitle
cmp.b #5,menuData(a4) ; is the string at least 5 bytes long?
blo.s @notIcon
cmp.b #1,menuData+1(a4) ; is the first character a 1?
bne.s @notIcon
BSR.S CalcRightRectSize
subq #2, SP ; make room for result
PEA TempRect ; push the title rect
move.w #atAbsoluteCenter, -(sp) ; No need to do centering since the rect is of the right size
btst #0, menuEnable+3(a4) ; is the title disabled? <DCC 8/06/90>
bne.s @noTransform ; if not, then don't use a transform <DCC 8/06/90>
moveq #ttDisabled, d0 ; else use ttDisabled <DCC 8/06/90>
bra.s @pushTransform ; <DCC 8/06/90>
@noTransform moveq #ttNone, d0 ; <DCC 8/06/90>
@pushTransform move.w d0, -(sp) ; push the transform <DCC 8/06/90>
move.l menuData+2(a4), -(sp) ; push the icon handle
; bsr ResetPreviousColors ; Reset the title colors <DCC 8/06/90>
; tst.w selectFlag(a6) ; Is this sucker selected <DCC 8/06/90>
; beq.s @colorsOK ; if not, go ahead and plot <DCC 8/06/90>
; bsr ResetPreviousColors ; restore the old colors so they will be saved by setTitleColor <DCC 8/06/90>
; clr.w selectFlag(a6) ; lie about the select state <DCC 8/06/90>
; bsr SetTitleColor
; not.w selectFlag(a6) ; restore the select state <DCC 8/06/90>
@colorsOK
_PlotIconSuite
addq #2, SP ; dump the result
bsr ResetPreviousColors ; set up old colors <DCC 8/06/90>
rts ; run away <DCC 8/06/90>
; bra.s ChkDisable ; <DCC 8/06/90>
@notIcon
PEA MenuData(A4) ; push pointer to title string
MOVE #srcOr,-(SP) ; Just to be sure grayish isnt happening
_TextMode
TST.B onColorMachine(A6)
BNE.S @DrawStringOnColorMachine
_DrawString
btst #0, menuEnable+3(a4) ; is the title disabled?
bne.s dontchk ; no, continue
bsr PaintTitleDisable ; disable the title by painting with gray
bra.s dontchk
@DrawStringOnColorMachine
btst #0, menuEnable+3(a4) ; is the title disabled?
bne.s @notDisabledOnColorMachine
MOVE #grayishTextOr,-(SP) ; special funny mode
_TextMode
@notDisabledOnColorMachine
_DrawString
MOVE #srcOr,-(SP) ; should be txMode!!!
_TextMode
dontchk
bsr ResetPreviousColors ; reset to original fore/back colors
rts ; and return
CalcRightRectSize
MOVEM.L A0/D0, -(SP)
LEA TempRect,A0
move.w right(A0), D0 ; Get the right side
sub.w left(a0), D0 ; find the width
cmp.w #$10, D0 ; Is it big enough to fit a small icon?
ble.s @tooSmall
asr.w #2, D0 ; Divide the gap in half
add.w left(A0), D0 ; offset the left side
move.w D0,left(A0) ; update Left
add.w #1, top(A0) ; Tweek the top a bit
@tooSmall
move.l topLeft(A0),D0 ; get the top and left
swap D0 ; put top in low word
add.w #16, D0 ; add 16
swap D0 ; put left in low word
add.w #16, D0 ; add 16
move.l D0, botRight(A0) ; Update bottom and right
MOVEM.L (SP)+, A0/D0
RTS
;-----------------------------------------------
; Utility -- SaveCurrentColors
;-----------------------------------------------
SaveCurrentColors
pea saveBackColor(a6) ; push address of var parm
_GetBackColor ; get the background color
pea saveForeColor(a6) ; push address of var parm
_GetForeColor ; get foreground color
rts
;-----------------------------------------------
; Utility -- SetTitleColor
;-----------------------------------------------
; Set the foreground/background color for this
; title. If has colorQD then use real colors
; else just use black/white
;
SetTitleColor
tst.b onColorMachine(a6)
beq @SetBW
BSR.S SaveCurrentColors ; Save current colors in stack frame <EMT S297>
TST.W TitleBackFlag(A6) ; DrawTitle = 0, DrawStruct = 1 <PMAB364 23Jan88 EMT>
BEQ.S @FromTitle0 ; Branch if from DrawTitle <PMAB364 23Jan88 EMT>
LEA menuRect(A6), A0 ; RGetPixelDepth uses menu rect <PMAB364 23Jan88 EMT>
BRA.S @GetDepth ; Go get depth <PMAB364 23Jan88 EMT>
@FromTitle0
LEA portRect(A2), A0 ; RGetPixelDepth uses menu bar <PMAB364 23Jan88 EMT>
@GetDepth
BSR RGetPixelDepth ; Get the current pixel depth <PMAB364 23Jan88 EMT>
cmpi.w #2, PixelDepth(a6) ; is this 2+ mode, and color ?
blt.s @DefaultColors ; no, its 1 bit mode or mono
move.l a4,d0 ; <49> Are we pointing to a MenuInfo record?
bz.s @TryMenuBar ; <49> No. Get the color entry for the menu bar
subq #4, sp ; save space for result
move menuID(a4), -(sp) ; push ID
clr -(sp) ; push Item=0 ===> title entry
_GetMCEntry ; get the color entry
move.l (sp)+, d0 ; get the result, and set z-flag if necessary
beq.s @TryMenuBar ; nope no title entry, try menu bar entry
; got menu title entry, so put colors on stack
move.l d0, a0 ; get entry address in a0
tst TitleBackFlag(a6) ; called from DrawTitle = 0, DrawStruct = 1
beq.s @FromTitle1 ; branch if from DrawTitle
pea mctRGB1(a0) ; foreground unimportant for DrawStruct
pea mctRGB4(a0) ; get specified background color
bra.s @SetColors
@FromTitle1
pea mctRGB1(a0) ; push title color
pea mctRGB2(a0) ; push menu bar color
bra.s @SetColors
; didn't get title entry, so try to get menu bar entry for menu color
@TryMenuBar
subq #4, sp ; save space for result
clr.l -(sp) ; ID=0, Item=0 ===> menubar entry
_GetMCEntry ; get the color entry
move.l (sp)+, d0 ; get the result, and set z-flag if necessary
beq.s @DefaultColors ; zero ===> no entry so use default
; got menu bar entry, so set colors
move.l d0, a0 ; get entry address in a0
tst TitleBackFlag(a6) ; called from DrawTitle = 0, DrawStruct = 1
beq.s @FromTitle2
pea mctRGB3(a0) ; foreground unimportant for DrawStruct
pea mctRGB2(a0) ; get default background from menubar entry
bra.s @SetColors
@FromTitle2
pea mctRGB1(a0) ; push default title color
pea mctRGB4(a0) ; push menu bar color
bra.s @SetColors
; set colors for default title
@DefaultColors
pea RGBBlack ; set foreground color to black
pea RGBWhite ; set background color to white
; colors are on the stack for normal title, switch them if this is a selected title
@SetColors tst.w selectFlag(a6) ; normal or selected?
beq.s @1 ; normal ===> addresses ok on stack
move.l (sp), a0 ; selected ===> switch addresses on stack
move.l 4(sp), (sp)
move.l a0, 4(sp)
@1 _RGBBackColor ; color addresses are on the stack
_RGBForeColor
bra.s @DoneSetTitleColor
; set colors for selected title
@SetBW moveq #WhiteColor, d0 ; set foreground color to white
move.l d0, -(sp)
moveq #BlackColor, d0 ; set background color to black
move.l d0, -(sp)
tst.w selectFlag(a6) ; normal or selected?
beq.s @BWNormal ; normal, so branch
_BackColor ; colors are on the stack
_ForeColor
bra.s @DoneSetTitleColor
@BWNormal
_ForeColor ; do calls in reverse if normal
_BackColor
@DoneSetTitleColor
rts
;-----------------------------------------------
BeginMenuBuffering
; Create an off-screen buffer for the menu bar, or a part of it.
; Then, attach this buffer to the port passed.
; The bits in the buffer are not initialized (must draw over the whole thing).
; This must be balanced by an EndMenuBuffering, which will blast the bits onto the screen.
;
; In:
; a0 pointer to rectangle for size of buffer
rts
;-----------------------------------------------
; Utility -- ResetPreviousColors
;-----------------------------------------------
; Reset the foreground/background color for this
; title. If has colorQD then use saved colors
; else just use black/white
;
ResetPreviousColors
tst.b onColorMachine(a6)
beq.s @ResetBW
pea saveForeColor(a6) ; push addresses of color records
pea saveBackColor(a6)
_RGBBackColor ; set the background color
_RGBForeColor ; get the foreground color
bra.s @ResetDone
@ResetBW
moveq #BlackColor, d0 ; force foreground color to black
move.l d0, -(sp)
moveq #WhiteColor, d0 ; force background color to white
move.l d0, -(sp)
_BackColor
_ForeColor
@ResetDone
rts
;-----------------------------------------------
; Utility -- PaintTitleDisable
;-----------------------------------------------
; If the title is disabled and there is no
; colorQD then paint TempRect with Gray
;
; Save and restore pen state for the application Tempo. <FJL 26Mar87>
PaintTitleDisable
btst #0, menuEnable+3(a4) ; is the title disabled?
bne.s @EndCheck ; no, so just return
suba #psRec, sp ; save space for pen state on the stack
move.l sp, -(sp) ; push pen state rec address
_GetPenState ; get the pen state
MOVE.L (A5),A0 ; get QuickDraw globals
PEA Gray(A0) ; push gray
_PenPat ; make that the pen pattern
move #PatBIC,-(SP) ; set bit clear mode
_PenMode ; set the penMode
pea TempRect ; push the rect addr
_PaintRect ; bit clear with gray
move.l sp, -(sp) ; push pen state rec address
_SetPenState ; reset to previous pen state
adda #psRec, sp ; remove pen state rec from stack
@EndCheck
rts
;-----------------------------------------------
; Utility -- GetPixelDepth
;-----------------------------------------------
;
; Utility to get current pixel depth and put it in the stack frame.
; RGetPixelDepth uses the rectangle pointed to by A0. <PMAB364 23Jan88 EMT>
GetPixelDepth
LEA portRect(A2), A0 ; Use WMgr's portRect <PMAB364 23Jan88 EMT>
RGetPixelDepth ; <PMAB364 23Jan88 EMT>
subq #4, sp ; space for GDHandle return
MOVE.L A0, -(SP) ; rect for GetMaxDevice <PMAB364 23Jan88 EMT>
_GetMaxDevice ; get max pixel device
MOVE.L (sp)+, A0 ; get the grafDevice
MOVE.L (A0),A1 ; hndl->ptr <PMAB364 23Jan88 EMT>
MOVE.L GDPMap(A1),A1 ; get the device's pixmap <PMAB364 23Jan88 EMT>
MOVE.L (A1),A1 ; hndl->ptr
move.w pmPixelSize(a1), PixelDepth(a6) ; and store the value
rts
;-----------------------------------------------
; Utility -- IsBWMode
;-----------------------------------------------
;
; Utility to test the monochrome/color information for the menu's monitor.
; Returns: Z-Flag means Monochrome, otherwise not B&W
IsBWMode
subq #2+4, sp ; space for boolean and for GDHandle <19>
PEA portRect(A2) ; Use WMgr's portRect
_GetMaxDevice ; get max pixel device
MOVE.W #gdDevType,-(SP) ; And we want to test the gdDevType
_TestDeviceAttribute ; Go get it
TST.B (SP)+ ; Set the Z-flag
RTS
;--------------------------------------------------------------------------------------------
;
; Msg #1 -- Hit Test -- is the mouse in the title bar, or in a menu, or in neither.
;
;--------------------------------------------------------------------------------------------
;
; The Hit Message takes a point in parameter, and determines whether the mouse
; point is in a title rect of the MenuBar.
; 1. If point in title or menu return menu's index
; 2. If point in title bar but not in title return 0
; 3. If point not in any title or menu then return -1
;
; To allow for multiple screens the menu bar extends for the width of the portRect only <FJL CXXX>
; Don't include the line under the menu bar as a hit, otherwise it is possible to <FJL CXXX>
; to choose the first menu item immediately <FJL CXXX>
;
HitBar
MOVE.L Param2(A6),D1 ; get the point
SWAP D1 ; get the vert coord in lo word
move portRect+Top(a2),d0 ; get top of menu bar in d0 <FJL CXXX>
cmp d0, d1 ; above menu bar ?
blt @NotInBar
add MBarHeight, d0 ; get bottom of menu bar in d0
cmp d0, d1 ; below menu bar ?
bge.s @NotInBar ; don't include line at bottom of menu <FJL CXXX>
; else can choose first item immediately
; Check the left and right sides of the menu bar
SWAP D1 ; get the horiz coord in lo word
move portRect+Left(a2),d0 ; get left of menu bar in d0 <FJL CXXX>
cmp d0, d1 ; to the left of the menu bar ?
blt.s @NotInBar
move portRect+Right(a2),d0 ; get right of menu bar in d0
cmp d0, d1 ; to the right of the menu bar ?
bgt.s @NotInBar
; it's in the bar, check if it's in a menu title
; NOTE: all title bounds (e.g. lastRight and menuLeft) are zero-based offsets, before <FJL CXXX>
; we start checking D1 against these we must first adjust it for portRect+Left(a2) <FJL CXXX>
MOVE.W portRect+Right(a2), D0 ; Right edge of menu bar
SUB.W #mbMenu1Loc,D0 ; Right edge of right-hand system menu ;<KSM <4>>
CMP.W D0, D1 ; Is point to the right of it? ;<KSM <4>>
BGT.S @NoTitle ; No way it<69>s in a title ;<KSM <4>>
SUB.W portRect+Left(a2), D1 ; adjust D1 for portRect+Left
CMP.W #mbMenu1Loc, D1 ; is it to the left of the first title ?
BLT.S @NoTitle
;______________________<11>
; Notes on new hit testing:
; 1) We don<6F>t return a hit on a system menu whose left edge is <= lastRight (it "fell off").
; CalcBar set lastRight to the left edge of the last system menu if there were too many
; application menus, thus the last system menu can never "fall off."
; 2) We don<6F>t return a hit on any application menu whose left edge is past lastRight, but if
; if lastRight is somewhere in the middle of the menu, it will be allowed to hit in
; the area from it<69>s left up to lastRight.
; Check either system set or application set
; _DMSG 'Welcome to Hitbar'
MOVEQ #0,D4 ; Courtesy Microsoft Corp., Excel Division <16>
MOVE.W lastMenu(A3), D4 ; D4 = lastMenu
BEQ.S @NoTitle
MOVE.W lastRight(A3), D3 ; D3 = lastRight
BSR FindFirstSystemMenu6BO ; Put offset to first system menu in D0
BEQ.S @NoSystemMenusHitEntry ; OOPS, no system menus!
CMP.W D3, D1 ; IF pt.h <= lastRight THEN
BLE.S @CheckAppMenus ; Hit was in app list somewhere
; Check system menus for allowable hit range
@sysChkLoop
MOVE.W menuLeft(A3,D0.W), D2 ; Get the menu.left
CMP.W D3, D2 ; WHILE menu.left < lastRight
BGE.S @HitLoop ; Found 1st visible title, regs set up already
CMP.W D4, D0 ; Is this the last menu?
BGE.S @NoTitle ; If not, there are no visible system menus(?)
ADD.W #6, D0 ; go to next menu
BRA.S @sysChkLoop
; Check application menus for allowable hit range
@regChkLoop
MOVE.W menuLeft(A3,D0.W), D2 ; Get the menu.left
CMP.W D3, D2 ; WHILE menu.left >= lastRight
BLT.S @foundLastVisRegMenu ; Found last visible title
@CheckAppMenus
SUB.W #6, D0 ; Move to the previous menu
BNE.S @regChkLoop ; And loop
BRA.S @NoTitle ; Well, we put the check in for this above...
@foundLastVisRegMenu
; We want to hit test from D0 -(downto)-> firstmenu
MOVE.W D0, D4 ; D0 is where we want to start
@NoSystemMenusHitEntry
CMP.W D3, D1 ; IF pt.h <= lastRight THEN
BGT.S @NoTitle ; bra if no sysmenus but hit beyond app menus
MOVEQ #6, D0 ; the first menu 6BO
; Hit loop: loop D4 downto D0
@HitLoop
CMP.W menuLeft(A3,D4), D1 ; IF pt.h >= menu.left THEN we got it!
BGE.S @HitThisOne ; Yeah!
CMP.W D0,D4 ; Are we done?
BEQ.S @NoTitle ; Yep
SUB.W #6, D4
BRA.S @HitLoop
;______________________<11>
@HitThisOne
MOVE.L D4,result(A6) ; return the menu
@HitDone
RTS
@NoTitle
CLR.L result(A6) ; if in menubar but no title, return menu number 0
BRA.S @HitDone ; and return
; Point not in bar, so check if in the rectangle of any menu on screen. Notice that this <FJL C222>
; loop checks thru the menus backwards, starting with the last one up, which is correct. <FJL C222>
@NotInBar
move.l mbSaveLoc, a0 ; get handle to mbar's save data
move.l (a0), a3 ; dereference
move.w lastMBSave(a3),d3 ; are there any menus?
beq.s @NotInAnyMenu ; no, so return -1
@RectLoop
clr.w -(sp) ; make room for PtInRect result
move.l param2(a6), -(sp) ; push the point
pea mbRectSave(a3,d3) ; push the rect address
_PtInRect ; test if point in rect
tst.b (sp)+ ; was it?
bne.s @FoundMenu ; yes, so return menuIndex (6 byte offset)
subi #mbEntrySize, d3 ; move to next index
beq.s @NotInAnyMenu ; if index == 0 then checked them all
bra.s @RectLoop ; index != 0 so check some more
; return the menuIndex in the lo-word of the result
@FoundMenu
clr.l result(a6) ; clear hi-word of result
move.w mbMLOffset(a3,d3), result+2(a6)
bra.s @HitDone ; and return
@NotInAnyMenu
MOVE.L MinusOne,result(A6) ; if not in bar return -1
BRA.S @HitDone
;--------------------------------------------------------------------------------------------
;
; Msg #2 -- Calc -- Calculate left edges for some or all Menus in menuList data structure
;
;--------------------------------------------------------------------------------------------
;
; The Calc Message recalculates left edge starting points for each menu,
; starting at the menuIndex passed in parameter. If parameter is zero,
; the entire menu structure is recalculated. Other than updating the MenuList,
; this routine returns no result.
; NOTE: These calculations are all zero-based. That is, if portRect+Left(a2) is non-zero
; the values calculated here are unaffected. Adjustments are made for portRect+Left
; when the values are used.
; Dave found a bug in this due to assumption of D4's value at start of routine
; now D4 is set explicitly (somebody used D0, then changed to D4 without proper initialization)
CalcBar
tst lastMenu(a3) ; are there any menus to calculate ?
beq CalcDone ; no, so nothing to calculate
MOVE.L SystemMenuList, A0 ; Get system menulist
MOVE.L (A0), A1 ; deref system menulist handle
TST.W lastMenu(A1) ; Are there any system menus?
BEQ SystemMenusAreIN ; Well, there aren't any -- so they are all in! <SM3> CSS
BSR FindFirstSystemMenu6BO ; See if the system menus are in.
BNE.S SystemMenusAreIN ; Yes, they are (D0 is offset to 1st one)
MOVEQ #6,D0
MOVE.L menuOH(A3,D0.W),A1 ; Get menuhandle of leftmost menu
MOVE.L (A1),A1 ; menuhandle -> menuptr
CMPI.W #$0114,menuData(A1) ; Is it an apple menu?
BNE.S SystemMenusAreIN ; NE means no apple menu, don<6F>t add system menus
_HLock ; Lock SysList before munging (we<77>re pointing into it)
MOVE.L (A0),A1 ; handle -> ptr
MOVEQ #0, D1 ; Clear the high word
MOVE.W lastMenu(A1),D1 ; Get # of bytes of system menus
ADDQ.L #6, A1 ; Point A1 to first system menu entry
MOVEQ #6, D0 ; Get offset of 1st menu entry
ADD.W lastMenu(A3), D0 ; D1 = Offset past lastMenu entry
; long = Munger(menulist, offset past regular menus, NIL, 0, ptr to 1st system menu, len sys menus)
SUBQ.L #4, SP ; Make room for result
MOVE.L MenuList,A0 ; Get the menulist
MOVE.L A0, -(SP) ; handle -- Menulist handle pushed
MOVE.L D0, -(SP) ; offset = past last one in existing list
MOVE.L #0, -(SP) ; ptr1 = NIL
MOVE.L #0, -(SP) ; len1 = 0 -- means insert (ptr2,len2) at offset
MOVE.L A1, -(SP) ; ptr2 = first system menu
MOVE.L D1, -(SP) ; len2 = #Bytes of system menus
ADD.W D1, lastMenu(A3) ; Just for luck, add up the new stuff we're adding
_HUnlock ; Don<6F>t Munge locked handles!
_Munger ; oooh baby, munge me!
MOVE.L MenuList, A0 ; Get (potentially) new menulist handle
_HLock
MOVE.L (A0), A3 ; Restore A3 to new value
MOVE.L SystemMenuList, A0 ; Get system menulist
_HUnlock ; Unlock it
ADDQ.L #4, SP ; Ignore the results
; BRA.S MenusExist ; There are menus in the menulist now
SystemMenusAreIN
; Now start the regular calc stuff
; tst lastMenu(a3) ; are there any menus to calculate ?
; beq CalcDone ; no, so nothing to calculate
MenusExist
MOVE.L Param2(A6),D4 ; get the menuIndex to start in
TST.W D4 ; pick up as long, but treat as word <FJL C222>
BEQ.S @entireBar ; if it's zero, then do entire bar
CMP.W (A3),D4 ; is it in the legal range?
BGT CalcDone ; if greater, then skip
MOVE.W menuLeft(A3,D4),D3 ; get the left edge for the starting title
BRA.S CalcLoop ; and continue
@entireBar
MOVEQ #mbMenu1Loc,D3 ; first menu starts ten pixels in
MOVEQ #6,D4 ; first menu's info starts at byte 6
MOVE.W D3,menuLeft(A3,D4) ; write it's menuLeft into the MenuList
; get the menu title string and measure it
CalcLoop
MOVE.L menuOH(A3,D4),A0 ; get the menuHandle
MOVE.L (A0),A0 ; dereference it
cmp.b #1,menuData+1(a0) ; is the first character a 1?
bne.s @notSysMenu
add.w #15,d3 ; all icons are 16 pixels wide, but do 15 <10>
bra.s @done
@notSysMenu
SUBQ.L #2,SP ; make room for function return
PEA menuData(A0) ; push a pointer to the menu text
_StringWidth ; get the size of it
ADD.W (SP)+,D3 ; add to this item's left edge
@done
ADD.W #mTitleSpace,D3 ; add space (determined empirically)
ADDQ #6,D4 ; move to the next menu
CMP.W (A3),D4 ; was this the last menu
BGT.S CalcLoopDone ; it is, so leave this loop
MOVE.W D3,menuLeft(A3,D4) ; place in the left edge of next
BRA.S CalcLoop ; loop back
CalcLoopDone
MOVE.W D3,lastRight(A3) ; set right edge always (even tho we may update it)
BSR FindFirstSystemMenu6BO ; Find first system menu
MOVE.W D0,D4 ; Are there any? (Save offset in D4)
BEQ CalcDone
MOVE.W menuLeft(A3,D0.w), D0 ; Get the 1st system menu's left
MOVE.W D0, lastRight(A3) ; Make that the last right of regular menus
; Compute the distance by which the last system menu's left edge should be adjusted
; and add this to each left edge of system menus, thereby right justifing them.
MOVE.W lastMenu(A3),D0 ; Get the last system menu offset
MOVE.W menuLeft(A3,D0),D0 ; Get the last system menuLeft as calculated
MOVEQ #0, D1 ; Clear out high word
SUB.W D0, D3 ; Last.right - Last.left + 1 [width of menu]
ADD.W #1, D3 ; Width of menu as computed elsewhere (it guides this)
ADD.W #mbMenu1Loc, D3 ; Width + mbMenu1Loc [symmetrical offset from right edge]
MOVE.W portRect+right(A2),D1 ; Get the right edge of the world
SUB.W D3, D1 ; Where the actual left edge should be
SUB.W D0, D1 ; Distance between computed and actual lefts
MOVE.W menuLeft(A3,D4), D0 ; Get left edge of the menu we are moving
; MOVE.W D0, lastRight(A3) ; Save as new last right (last one is correct)
SysOffsetLoop
ADD.W D1, menuLeft(A3,D4) ; Offset system menu<6E>s left edge (D4 is 1st sys)
CMP.W lastMenu(A3),D4 ; was this the last menu
BEQ.S SysOffsetLoopDone ; it is, so leave this loop
ADDQ.W #6, D4 ; go to next one
BRA.S SysOffsetLoop
SysOffsetLoopDone ; <48> (the rest of this routine)
; At this point, D1 is the pixels we moved the system menus
; If D1 >= 0 then they moved right and there is space between
; the app menus and the system menus, so no overlap checking is necessary
; and lastRight is correct.
TST.W D1
BGE.S CalcDone ; D1 > 0, there is no overlap: we<77>re done.
; Bummer, app menus overlap the system menus.
; Find the "hard lastRight" - the left edge of the leftmost system menu we must keep
BSR.S FindFirstSystemMenu6BO ; Find first system menu
MOVE.W D0,D3
MOVE.W lastMenu(A3),D4 ; Must keep the app menu no matter what
MOVE.W MBDFFlags,D1 ; Get the flags
BEQ.S D4IsHardEdge6BO ; No special case
LSR.W #4,D1 ; Only "keep count" bits
ANDI.W #$F,D1
BEQ.S D4IsHardEdge6BO ; And we<77>ve got the 6B0 of the menu containing the hard edge
ADD.W D1,D1 ; 2x
MOVE.W D1,D0 ; 2x copy
ADD.W D0,D0 ; 2x + 2x = 4x
ADD.W D1,D0 ; 4x + 2x = 6x
SUB.W D0,D4 ; lastMenu - 6B0 of savings
CMP.W D3,D4 ; is computed menu < 1st system menu
BGE.S D4IsHardEdge6BO ; no, use computed menu as hard right
MOVE.W menuLeft(A3,D3), D0 ; Get 1st system menu left edge
D0IsNewLR MOVE.W D0, lastRight(A3) ; Left edge is this
; So there's not much else to say, App menus overlap
; and we have to keep all the system menus....
CalcDone RTS
D4IsHardEdge6BO
MOVE.W lastRight(A3),D1 ; cache last right
MOVE.W menuLeft(A3,D4),D2 ; prime menuLeft
transSearchLoop MOVE.W menuLeft(A3,D4),D0 ; get menuLeft
CMP.W D1,D0 ; Is menuLeft < lastRight?
BLT.S foundTransMenu
MOVE.W D0,D2 ; Save this one
SUBQ #6,D4 ; Point to next previous system menu
CMP.W D3,D4 ; At the last one?
BGE.S transSearchLoop
foundTransMenu
MOVE.W MBDFFlags,D1 ; Get the flags
ANDI.W #$F,D1 ; Only slop bits
LSL.W #1,D1 ; Two pixel increments
ADD.W D0,D1 ; menuLeft = menuLeft + slop
CMP.W lastRight(A3),D1 ; Is menuLeft + slop >= lastRight ?
BGE.S D0IsNewLR ; Keep this menu (above slop threshold)
MOVE.W D2,D0 ; menuLeft is new last right
BRA.S D0IsNewLR
;______________________________________________________________________________________________
; Utility -- FindFirstSystemMenu6BO
; Returns the 6B0 of the 1st system menu found in the menulist in D0 (conditions set).
; Returns zero if no system menus are in the current menu bar.
; All registers (except D0 of course) are preserved.
; NOTE: We walk from last menu -> first since there usually are fewer system menus
; and they are at the end of the menu list
FFSMSaveReg REG A0/A1
FindFirstSystemMenu6BO
MOVEM.L FFSMSaveReg, -(SP) ; Save our regs
MOVE.L MenuList, A0 ; Get the current menulist
MOVE.L (A0), A0 ; dereference
MOVEQ #0, D0 ; Clear high word
MOVE.W lastMenu(A0), D0 ; Get the last menu offset
BEQ.S @done ; If there are none, done
@nextMenu
MOVE.L menuOH(A0,D0.w), A1 ; Get the menu handle
MOVE.L (A1), A1 ; dereference
CMP.W #-16384, menuID(A1) ; IF menuID >= -16384 THEN
BGE.S @pastSysMenus ; GOTO pastSysMenus
SUBQ #6, D0 ; point to the next one in the menulist
BNE.S @nextMenu ; and continue
; Falling out of loop, D0=0 and 1st is system menu
@bumpAndExit
ADDQ #6, D0 ; Bump D0 to point to next entry
BRA.S @done ; And we<77>re outa here
@pastSysMenus
CMP.W lastMenu(A0), D0 ; were there any system menus at all?
BLT.S @bumpAndExit ; D0 moved, so we found at least 1 system menu
MOVEQ #0,D0 ; Show that there is no partition
@done
MOVEM.L (SP)+, FFSMSaveReg ; Restore our regs
RTS
;--------------------------------------------------------------------------------------------
;
; Msg #5 -- Hilite -- do the indicated menu hiliting
;
;--------------------------------------------------------------------------------------------
;
; The Hilite message redraws a single title to the hilite state specified
; in the hi word of parameter. States are:
; 0 unhilited/normal appearance --
; restore the bits behind the title rect
; 1 selected appearance --
; save the bits behind the menu title and draw the selected title
; 2 disabled appearance --
; redraw the title using the "disabled" pattern as an overlay
; NOT SUPPORTED CURRENTLY
; 3 busy appearance --
; redraw the title using the "busy" pattern as an overlay
; NOT SUPPORTED CURRENTLY
; 128+ blit SICN resource onto screen --
; NOT SUPPORTED CURRENTLY
;
; The index of the title to perform hiliting on is in the lo-word of parameter
; (if 0, then the whole bar is hilited).
;
; NOTICE: The way we handle normal and selected menu titles is very different now.
; On MacPlus selecting a menu caused the menu title to be inverted, and
; unselecting it (HiliteMenu(0)) just inverted it again. This meant that
; menu titles were unreadable on programs that use the full screen. In this
; new model when a menu is selected the bits behind are saved, and the
; title is drawn in the reverse colors (e.g. white on black). HiliteMenu(0)
; then causes the bits behind to be restored.
; INTERESTING...: Because most apps that play with multiple heaps (e.g. TurboPascal) already
; know about the menuList, the handle to the bits behind a hilited title
; are saved in the menuList rather than the mbarproc private data. That
; way we don't have to worry about having multiple menus hilited under
; twitcher either (though we still can't have menus down across several
; apps at the same time)
;
; ASSUMPTIONS:
; 1. The menuID is valid, i.e. the menu is found in the menuList.
;
; On entry A3 MenuList menu list pointer. Its handle is locked.
;
; Calc values for A4 menu ptr selected/unselected menu ptr
; D3 index index into menu list (#6 offsets)
; D4 font info font ascent + leading (see GetMenuInfo)
HiliteBar
BSR ClipMBar ; <EMT S297>
MOVE.W param2+2(A6),D0 ; get the hilite selector
BEQ FlipBar ; if index = 0 then flip bar <FJL C175><35> <SM3> CSS
CMP.W #1,param2(a6) ; hi-word has hilite
BGT.S DoneHilite ; if not in range we support then bye-bye
blt.s Unhilite ; unhiliting is totally different from hiliting
CMP.W lastMenu(A3),D0 ; is it a legal menu title? <10>(lastRight->lastMenu)
BGT.S DoneHilite ; nope, so return
moveq #0, d3 ; clear d3 <FJL C175>
move.w d0, d3 ; keep 6 byte offset here
BSR GetTitleRect ; get this title's rect in TempRect
; If we got here then everything is valid, so lock down the selected menuHandle
MOVE.L menuOH(A3,D3),A0 ; get the selected menuHandle <FJL C175>
_HLock ; lock it down <FJL C175>
move.l (a0), a4 ; get selected menu ptr
bsr.s DoSelected ; call save bits and draw routine
move.l menuOH(A3,D3),A0 ; get the selected menuHandle <FJL C175>
_HUnlock ; and unlock it <FJL C175>
; be a good citizen and set clip full open before we leave
DoneHilite
bsr FullClip ; set clip wide open <FJL C428>
RTS
; unhiliting works no matter what menu offset is passed in, since we just restore the bits
Unhilite
bsr DoNormal
bra.s DoneHilite
;-------------------------------------------------------------------
; Hilite State is 0 -- unhilited/normal appearance -- restore bits
;-------------------------------------------------------------------
DoNormal
; we clear TheMenu here because DrawMenuBar may be called by
; RestoreBits and we don't want to draw and later un-hilite the bits
clr.w TheMenu
move lastMenu(a3), d0 ; get last regular menu
addq #6, d0 ; offset to HMenu header info
subq #2, sp ; make room for result
move.l menuTitleSave(a3,d0.w),-(sp) ; get title handle
clr.l menuTitleSave(a3,d0.w) ; and clear out saved handle
_RestoreBits
addq #2, sp ; ignore the result
clr.l SavedHandle ; set lomem to NIL
rts
;-------------------------------------------------------------------
; Hilite State is 1 -- selected appearance -- save bits, draw title <FJL C222>
;-------------------------------------------------------------------
DoSelected
moveq #0,d0 ; Title bits should NEVER be purgable <41>
; title rect is already in TempRect
bsr SaveDemBits ; get the bits behind the title rect
move lastMenu(a3), d0 ; get last regular menu
addq #6, d0 ; offset to HMenu header info
move.l SavedHandle, menuTitleSave(a3,d0.w) ; store new handle
clr.l SavedHandle ; clear out lomem
move.w #1, SelectFlag(a6) ; set select flag <FJL C175>
bsr DrawCommon ; use common code to draw
rts
;-----------------------------------------------
; Utility -- FlipBar
;-----------------------------------------------
; use the hilite color to flip the bar to be sure hiliting happens
FlipBar
tst.b onColorMachine(a6)
beq.s @DoInvert
bsr SaveCurrentColors ; save current colors in stackframe
bsr GetPixelDepth ; put the current pixel depth in the stack frame
cmpi.w #2, PixelDepth(a6) ; is this 2+ mode, and color ?
blt.s @DoInvert ; no, its 1 bit mode, so don't set color
subq #4, sp ; save space for result
clr.l -(sp) ; ID=0, Item=0 ===> menubar entry
_GetMCEntry ; get the color entry
move.l (sp)+, d0 ; get the result, and set z-flag if necessary
beq.s @DoDefault ; zero ===> no entry so use default
; we got a menu bar entry from the color table, so use it to color the menu bar
move.l d0, a0 ; get ptr to color entry in a0
pea mctRGB1(a0) ; push fore color
pea mctRGB4(a0) ; push back color
bra.s @DoColorSet
@DoDefault ; default is always black on white
pea RGBBlack
pea RGBWhite
@DoColorSet _RGBBackColor
_HiliteColor
bclr #HiliteBit, HiliteMode ; set hilite bit so uses hilite color
@DoInvert ; finally we can invert the dang thing
; Set clip to intersection of screen's round rect and menu bar rect
subq #4, sp ; alloc space for rgn handle
_NewRgn ; alloc and leave on the stack
_OpenRgn ; create rgn containing rounded screen
pea portRect(a2) ; push portRect
BTST #7,onLCDMac(A6) ; is this Harpo <DAF 10Feb89><v1.3>
BZ.S @2 ; if not, then skip this <DAF 10Feb89>
_FrameRect
BRA.S @3
@2 move.l #ScreenRadius, -(sp) ; push rounding factor
_FrameRoundRect
@3 move.l (sp), -(sp) ; push rgn handle
_CloseRgn ; close and rgn on the stack
move.l (sp), -(sp) ; srcA is rounded screen
move.l clipRgn(a2), -(sp) ; srcB is currently set to menu bar rect
move.l clipRgn(a2), -(sp) ; dest is same as srcB
_SectRgn ; do intersect
_DisposRgn ; rgn is on the stack
PEA portRect(A2) ; push screen bounds rect
_InverRect
bsr ResetPreviousColors ; and restore colors before leaving
BRA DoneHilite
;-----------------------------------------------
; Utility -- GetTitleRect
;-----------------------------------------------
;
; GetTitleRect is a utility that returns the adjusted bounding rect of the
; title whose menu title number is in the lo half of D0.
; The resultant rect is returned in TempRect. For titles, the rect is
; not the full bounds of the title, but the portion that is modified
; by hilite. If the requested title is 0, then the entire menu bar rect is
; returned including the topmost and bottommost lines.
;
; use portRect instead of assuming topLeft is (0,0) <FJL CXXX>
GetTitleRect
TST.W D0 ; superflous test, but just to be safe
BEQ WholeBar ; if 0, then return entire MBar rect
LEA TEMPRECT,A0 ; get address of the rectangle
move portRect+Top(a2), (a0) ; get top of menubar <FJL CXXX>
addq #1,(A0)+ ; top is one <FJL CXXX>
MOVE MENULEFT(A3,D0),(A0) ; left is menuLeft[index]
move portRect+Left(a2), d1 ; <FJL CXXX>
add d1, (a0) ; offset from portRect properly <FJL CXXX>
SUBQ #1,(A0)+ ; really want left-1
move portRect+Top(a2), (a0) ; get top of menu bar <FJL CXXX>
move MBarHeight, d1 ; <FJL CXXX>
add d1,(A0) ; bottom = top + mbarheight <FJL CXXX>
SUBQ #1,(A0)+ ; need bottom-1
; _DMSG 'Welcome to GetTitleRect'
move portRect+Left(a2), (a0) ; set up for menu right <FJL CXXX>
MOVE.L A0, -(SP) ; Save A0
MOVE.L menuOH(a3,d0), A0 ; get the menu handle
MOVE.L (A0), A0 ; handle -> ptr
CMP.W #-16384, menuID(A0) ; Is it a system menu?
MOVE.L (SP)+,A0 ; Restore A0
BGE.S @notSysMenu ; Wasn't a system menu
CMP LASTMENU(A3),D0 ; is it the last one?
BEQ.S @DoLastSysMenu ; The last one is a sys menu (use portRect.right)
MOVE.W menuLeft(a3,d0), d1 ; get the left of this menu
ADDQ #6,D0 ; bump to next slot
MOVE.W menuLeft(a3,d0), d0 ; get the left of next menu
CMP.W lastRight(a3), d1 ; Is menu.left < lastRight?
BLT.S GTDone ; No, all or part is obscured
BRA.S @useD0 ; Otherwise use menu.right
@notSysMenu
MOVE.W D0, D1 ; Save off 6B0 target
BSR FindFirstSystemMenu6BO ; Get the 1st system menu
BNE.S @1 ; There are system menus, so prev is last
MOVE.W LASTMENU(A3), D0 ; DO the comparison against last
bra.s @2
@1
SUB.W #6, D0 ; Bump down the comparison
@2
EXG D0, D1 ; d0<=target d1<=6B0 of last reg menu
CMP D0, D1 ; is it the last regular menu?
BEQ.S @useLastRight ; The last one is a regular menu (use lastRight)
@notLast
move menuLeft(a3,d0), d1 ; get the left of this menu
ADDQ #6,D0 ; bump to next slot
move menuLeft(a3,d0), d0 ; get the left of next menu
cmp.w lastRight(a3), d1 ; Is menu.left > lastRight?
bgt.s GTDone ; Yes, the menu is into the last system menu
cmp.w lastRight(a3), d0 ; Is menu.right > lastRight?
ble.s @useD0 ; No, use menu.right else use lastRight
@useLastRight
move.w lastRight(a3), d0 ; use lastRight
bra.s @useD0
@DoLastSysMenu
move portRect+right(a2), d0 ; Get the right edge of the screen
sub.w #mbMenu1Loc, d0 ; symmetrical w/ apple menu
move D0, (A0) ; Slam the value
bra.s GTDone ; And we're outa here
@useD0
ADDQ #4,(A0) ; leave some margin on right
add d0,(A0) ; right is lastRight <FJL CXXX>
GTDone RTS ; return to caller
WholeBar
LEA TempRect,A0 ; get address of the rectangle
move portRect+Top(a2), (a0)+ ; top <FJL CXXX>
move portRect+Left(a2),(a0)+ ; left <FJL CXXX>
move portRect+Top(a2), (a0) ; bottom = top + mbarheight <FJL CXXX>
move MBarHeight, d1 ; <FJL CXXX>
add d1,(A0)+ ; <FJL CXXX>
MOVE.W PortRect+Right(A2),(A0) ; right is screen right
BRA.S GTDone ; all done...
;--------------------------------------------------------------------------------------------
;
; Msg #7 -- SaveBitsBar -- save bits behind menu, clear to proper color, and draw struct
;
;--------------------------------------------------------------------------------------------
;
; The SaveBitsBar call saves the bits in a pulldown's menuRect,
; then clears and frames the rect. It takes the menuIndex to act on in
; param. This code now stores the menu's menuRect and SavedHandle in the structure
; inited by the mbarproc (see InitBar msg above), and returns a pointer to the
; menuRect field in that structure.
SaveBitsBar
bsr FullClip ; set clip wide open <FJL C428>
BSR RemoveAnyBalloon ; remove any help balloons that are showing
; Copy the passed menu rectangle into the stackframe
move.l param2(a6), a0
lea menuRect(a6), a1
move.l Top(a0), Top(a1)
move.l Bottom(a0), Bottom(a1)
; Copy the menu's rectangle to TempRect, and expand it by 4 pixels so that we save the bits
; behind the structure too. SaveDemBits expects the expanded rect in TempRect.
LEA TEMPRECT,A0 ;point to the rectangle
LEA menuRect(A6),A1 ;get menuRect of current menu
MOVE.L A0,-(SP) ;push pointer to tempRect, too
MOVE.W Top(A1),Top(A0) ; copy menuRect into tempRect
ADDQ.W #3,Top(A0) ; save bottommost pixel in menu bar <FJL C222>
MOVE.W Left(A1),Left(A0) ; copy left
MOVE.L Bottom(A1),Bottom(A0) ; copy botRight,too
MOVE.L #$FFFCFFFC,-(SP) ; push -4,-4
_InsetRect ; expand saveRect by 4 pixels
moveq #1,d0 ; Allow these bits to be purgable <41>
bsr SaveDemBits ; save the bits into a bitmap or pixmap <FJL C222>
DrawStruct
SUBQ #2,SP ; make room for result
PEA menuRect(a6) ; push pointer to menuRect <S423 09Mar88 EMT>
_EmptyRect ; look for an empty menu
TST.B (SP)+ ; otherwise nothing will cast a shadow
BNE SaveBitsDone ; => and we wouldn't want that to happen
tst.b onColorMachine(a6)
beq.s @DoErase
move param1(a6), D0 ; get menuList offset from param1
MOVE.L menuOH(A3,D0),A1 ; get the menuData handle
move.l (a1), a4 ; get menu ptr in a4 for SetTitleColor
move #1, TitleBackFlag(a6) ; message that calling SetTitleColor from here
clr selectFlag(a6) ; drawing normal (unselected) object
bsr SetTitleColor ; set the proper background color
@DoErase lea menuRect(a6), a4 ; load address of menuRect into a4
move.l a4, -(sp) ; push pointer to menuRect
_EraseRect ; erase the menuRect
tst.b onColorMachine(a6)
beq.s @noColor
bsr ResetPreviousColors ; and reset the previous colors
@noColor
; paint the boundary and shadow -- first set up the pen
_PenNormal
move Left(a4), -(sp) ;
subq #1, (sp) ; want Left-1
move (sp), -(sp) ; push it again
move (sp), -(sp) ; and again
move Top(a4), -(sp) ;
_MoveTo ; MoveTo(Left-1, Top)
move Bottom(a4), -(sp) ; push
_LineTo ; LineTo(Left-1, Bottom)
move Right(a4), -(sp)
move Bottom(a4), -(sp)
_LineTo ; LineTo(Right, Bottom)
move Right(a4), -(sp)
move Top(a4), -(sp)
subq #1, (sp) ; want Top-1
_LineTo ; LineTo(Top-1, Right)
move Top(a4), -(sp)
subq #1, (sp) ; want Top-1
_LineTo ; LineTo(Left-1, Top-1)
; paint a drop shadow for the menu
MOVE.L #$00020002,-(SP) ;push shadow factor
_PenSize ;make penSize = shadow factor
MOVE RIGHT(A4),D0 ;get right of menuRect
MOVE D0,-(SP) ;push right
MOVE TOP(A4),-(SP) ;push top
ADD #2,(SP) ;want top+shadow
MOVE D0,-(SP) ;push right
MOVE BOTTOM(A4),D0 ;get bottom
MOVE D0,-(SP) ;push bottom
MOVE LEFT(A4),-(SP) ;push left
ADD #2,(SP) ;want left+shadow
MOVE D0,-(SP) ;push bottom
_MoveTo ;MoveTo(left+shadow,bottom)
_LineTo ;LineTo(right,bottom)
_LineTo ;LineTo(right,top+shadow)
_PenNormal ;restore normal pen
SaveBitsDone
; First need to calculate MenuDir in stackframe <FJL 03Mar87>
move #mbRightDir, MenuDir(a6) ; assume it went "right"
move.l mbSaveLoc, a0 ; get handle to mbarproc data storage
move.l (a0), a0 ; dereference
move lastMBSave(a0), d0 ; any menus saved yet?
beq.s @gotDir ; no ==> therefore store "right"
move mbRectSave+Left(a0,d0), d1 ; get left edge of previous menu
cmp menuRect+Left(a6), d1 ; left of prev. menu < current menu left?
blt.s @gotDir ; yes ==> menu went "right"
move #mbLeftDir, MenuDir(a6) ; no ==> menu went "left"
@gotDir
; Place the menuRect and SavedHandle in the mbar's structure. <FJL C222>
addi.w #mbEntrySize, lastMBSave(a0) ; update count of num menus on screen
move.w lastMBSave(a0), d0 ; get num menus
move.l menuRect(a6), mbRectSave(a0,d0.w) ; copy adjusted menuRect into save area
move.l menuRect+4(a6), mbRectSave+4(a0,d0.w)
move.l SavedHandle, mbBitsSave(a0,d0.w) ; copy handle to bits behind
move.w MenuDir(a6), mbMenuDir(a0,d0.w) ; copy menu direction
move.w Param1(a6), d1
move.w d1, mbMLOffset(a0,d0.w) ; copy menuList offset
move.l menuOH(a3,d1.w), mbMLHandle(a0,d0.w) ; copy menuList handle
RTS
;-----------------------------------------------
; Utility -- CalcMenuRect
;-----------------------------------------------
; Utility shared with msg #9 GetRect when the
; rect needs to calculated rather than just
; retrieved from the mbarproc data structure
CalcMenuRect
MOVE.L param2(A6),D0 ; get the param (6 byte offset into menuList)
move.w param2(a6), VMousePt(a6); store vertical mouse pt in stackframe <FJL C222>
; notice that it is move.w not move.l !!<FJL C222>
MOVE.L menuOH(A3,D0),A1 ; get the menuData handle
MOVE.W menuLeft(A3,D0),D3 ; get the menuLeft too
add portRect+Left(a2), d3 ; adjust for portRect <FJL CXXX>
MOVE.L (A1),A0 ; dereference it
TST.L MENUWIDTH(A0) ; is size valid?
BPL.S @SkipCalcSize ; yes, no need to recalc
MOVE.L A1,-(SP) ; save menu record handle <FJL C175>
MOVE.L A1,-(SP) ; push handle for calc
_CalcMenuSize ; get valid MENUWIDTH,MENUHEIGHT
MOVE.L (SP)+,A0 ; get handle to menuRecord again <FJL C175>
move.l (a0), a0 ; and get the pointer for MakeMRect <FJL C175>
@SkipCalcSize
BSR.s MakeMRect ; calc the MenuRect in stack frame
rts
;-----------------------------------------------
; Utility -- MakeMRect
;-----------------------------------------------
;
; MakeMRect is a utility which calculates the boundsRect for the menu whose
; menuLeft is in D3, and whose menuData pointer is in A0. It returns
; this rect in the stack frame. It trashes D0-D1/A1 and modifies D3.
;
; use portRect instead of assuming topLeft is (0,0) <FJL CXXX>
MakeMRect
; set up the menuRect -- first adjust menuLeft to ensure the menu stays on the screen
MOVE.W VMousePt(a6), d1 ; if != 0 ===> is a hierarchical menu <FJL C222>
BNE MakeHMRect ; branch if hierarchical menu <FJL C222>
MOVE.W #mbRightDir, MenuDir(a6); assume menu going right <FJL C222>
MOVE.W portRect+Top(a2), d1 ; get top of menubar <FJL CXXX>
add MBarHeight,D1 ; bottom = top + mbarheight <FJL CXXX>
MOVE.W D3,D0 ; get menuLeft in D0
ADD MENUWIDTH(A0),D0 ; get right edge
ADDQ #8,D0 ; leave a little margin
CMP PortRect+Right(A2),D0 ; compare with size of screen
BLE.S StoreRect ; if smaller, we're cool
; adjust menuLeft so the menu fits on the screen
MOVE.W #mbLeftDir, MenuDir(a6) ; change menu's direction <FJL C222>
; <11>
MOVE.W menuID(A0), D0 ; Get this menuID
CMP.W #-16384, D0 ; Is it a system menu ( < 16384 )
BLT.S @AdjustMenuForSystemLook
MOVE.W PortRect+Right(A2),D3 ; get right edge
SUBQ #8,D3 ; leave some margin
SUB MENUWIDTH(A0),D3 ; compute where left should be
BRA.S StoreRect
@AdjustMenuForSystemLook
; GetTitleRect writes into TempRect, so save off a copy first...
LEA TempRect, A1 ; Get TempRect
MOVE.L topLeft(A1), -(SP) ; Save topLeft
MOVE.L botRight(A1), -(SP) ; Save botRight
MOVE.L param2(A6), D0 ; Get the 6B0 into low word
MOVEM.L A0/D1, -(SP) ; Save off regs for a sec
BSR GetTitleRect ; Get the title rect into temprect
MOVEM.L (SP)+, A0/D1 ; Restore regs
MOVE.W right(A1), D3 ; Get the right edge of the title
SUB.W MENUWIDTH(A0),D3 ; compute where left should be
SUB.W #1,D3 ; the Pauline tweek <16>
MOVE.L (SP)+, botRight(A1) ; Restore botRight
MOVE.L (SP)+, topLeft(A1) ; Restore topLeft
CMP.W PortRect+Left(A2),D3 ; IF assumedLeft <= portRect.left THEN
BGT.S StoreRect ; Don't branch
MOVE.W PortRect+Left(A2),D3 ; Get a new left
ADD.W #4, D3 ; Add a slop factor
StoreRect
LEA MenuRect(A6),A1 ; get address of rectangle
MOVE.W D1,(A1)+ ; set up top of menuRect <EHB 5Aug85>
MOVE.W D3,(A1)+ ; set up menuLeft
ADD.W MENUHEIGHT(A0),D1 ; get height
MOVE.W D1,(A1)+ ; set up bottom
ADD.W MENUWIDTH(A0),D3 ; compute right of menuRect
MOVE.W D3,(A1) ; move in right point
RTS
;-----------------------------------------------
; Utility within a utility -- MakeHMRect
;-----------------------------------------------
;
; This is for a hierarchical menu, so do the following:
; 1. Make top line up with previous item unless menu hits bottom of the screen
; 2. Go same direction as last menu up
; 3. If hit edge of screen try to go in other direction
; 4. If hit edge of screen then give up and just plop it on the screen any old place
; On Entry: A0 ptr points to menuRecord for current menu
; d1 pt vertical mouse pt
;
MakeHMRect
; d1 has vertical mouse pt when we get here. Stabilize menu so top item lines up
; with selected item on previous menu. If menu is too long then move top up until
; either the bottom is 8 pixels above the bottom of the screen or top comes within
; 7 pixels of the menu bar.
movem.l d2-d5/a0-a3, -(sp) ; save work registers
move.l d1, d5 ; move vertical mouse pt into d5
bsr GetSizes ; get font info in stackframe
bsr GetA1SaveData ; get ptr to previous menu's data in a1
move mbTopScroll(a1), d2 ; get previous menu's top
move.l mbMLHandle(a1), a3 ; get previous menu's handle
moveq #1, d4 ; start with first item
@ItemLoop
move d4, d0 ; get item
bsr GetItemRecord ; look it up, put item's string ptr in a0,
; properties ptr in a1
bsr GetItemHeight ; get item height in d0
add d0, d2 ; d2 now has bottom of item
cmp d5, d2 ; is bottom of item below mouse pt ?
bgt.s @FoundItem ; yes, so we found the item
addq #1, d4 ; go to next item
bra.s @ItemLoop ; and try next item
@FoundItem
sub d0, d2 ; d2 now has top of item to line up with
move d2, d1 ; put it in d1 for rest of this routine
movem.l (sp)+, d2-d5/a0-a3 ; restore work registers
SUBQ.W #7, D1 ; move item top up 7 pixels (tune it!) <1.8>
MOVE.W portRect+top(A2), D0 ; menu bar height is relative <1.8>
ADD.W MBarHeight, D0 ; to top of portRect <1.8>
CMP.W D0, D1 ; compare with menu bar height <1.8>
bge.s @SetBottom ; if top not in menu bar then don't reset top
MOVE.W D0, D1 ; top is in menu bar <1.8>
@SetBottom
addq.w #7, d1 ; Move top down 7 pixels.
move d1, d0 ; get top in d0 temporarily
add.w menuHeight(a0), d0 ; find menu bottom
addi #12, d0 ; add 12 pixels so don't hit screen bottom exactly
cmp.w portRect+Bottom(a2), d0 ; compare it to the bottom of the screen
BLE.S @BottomOK ; if < or = to bottom then we are ok <1.8>
; menu extends beyond the bottom of the screen so recalc top
MOVEQ.L #-12, D0 ; move it up 12 pixels from screen bottom <1.8>
ADD.W portRect+Bottom(a2), d0 ; get screen bottom <1.8>
sub.w menuHeight(a0), d0 ; d0 now has correct height
move d0, d1 ; put it in back in d1
@BottomOK
; now calculate left, right and bottom
bsr GetA1SaveData ; get ptr to previous menu's data in a1
move.w mbMenuDir(a1), MenuDir(a6) ; assume direction of last menu
cmpi.w #mbLeftDir, MenuDir(a6) ; if going left then branch
beq.s @MenuToLeft
; menu going right. Menuleft starts 4 pixels in from previous menu's right hand edge.
@MenuToRight move.w mbRectSave+Right(a1), d0; get previous menu's right edge
subi.w #4, d0 ; overlap 4 pixels
move.w d0, d3 ; save location in d3 for StoreRect
add menuWidth(a0), d0 ; get right edge by adding menu's width
addq #8, d0 ; leave a little margin
cmp PortRect+Right(a2), d0 ; compare with size of screen
ble.s @DoneMakeH ; if smaller we're cool
; oops, menu needs to go left instead of right,
; menuRight starts 4 pixels from left edge of previous menu.
move.w #mbLeftDir, MenuDir(a6) ; change direction in stackframe
move.w mbRectSave+Left(a1), d0 ; get previous menu's left edge
sub menuWidth(a0), d0 ; shift left edge to the left where it should be
add.w #8, d0 ; overlap 8 pixels going left !!!
move.w d0, d3 ; save location in d3 for StoreRect
; one last check, if left edge of menu flops over left edge of screen then bring
; it back onto the screen
subq #8, d0 ; leave a little margin
cmp PortRect+Left(a2), d0 ; compare with size of screen
bge.s @DoneMakeH ; we're cool
move PortRect+Left(a2), d0 ; damn, we need to reset rect again
addq #8, d0 ; leave a little margin
move d0, d3 ; and put loc in d3 for StoreRect
move #mbRightDir, MenuDir(a6); change direction one last time
bra.s @DoneMakeH ; done...
; menu going left. MenuRight starts 8 pixels in from previous menu's left hand edge.
@MenuToLeft
move.w mbRectSave+Left(a1), d0 ; get previous menu's left edge
addi.w #8, d0 ; overlap 8 pixels going left
sub menuWidth(a0), d0 ; shift left edge to the left where it should be
move.w d0, d3 ; save location in d3 for StoreRect
subq #8, d0 ; leave a little margin
cmp PortRect+Left(a2), d0 ; compare with size of screen
bgt.s @DoneMakeH ; if smaller we're cool
; oops, menu needs to go right instead of left,
; menuRight starts 4 pixels from right edge of previous menu.
move.w #mbRightDir, MenuDir(a6); change direction in stackframe
move.w mbRectSave+Right(a1), d0; get previous menu's right edge
sub.w #4, d0 ; overlap 4 pixels
move.w d0, d3 ; save location in d3 for StoreRect
; one last check, if right edge of menu flops over right edge of screen then bring
; it back onto the screen
add.w menuWidth(a0), d0 ; get right edge of HMenu
addq #8, d0 ; leave a little margin
cmp PortRect+Right(a2), d0 ; compare with size of screen
ble.s @DoneMakeH ; we're cool
move PortRect+Right(a2), d0 ; damn, we need to reset rect again
sub menuWidth(a0), d0 ; move it in from right edge of screen
subq #8, d0 ; and a little more for good luck
move d0, d3 ; and put loc in d3 for StoreRect
move #mbLeftDir, MenuDir(a6) ; change direction one last time
@DoneMakeH
bra StoreRect ; and continue
;---------------------------------------
; Utility -- GetItemRecord <Taken from MDEF, FJL 12-29-86>
;---------------------------------------
; GetItemRecord is the main utility used for accessing the menu item data structure.
; It has a register interface to save code. On entry, A3 handles 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.
GetItemRecord
MOVE.L (A3),A0 ; get menu ptr <2.2>
TST.w D0 ; make sure item number is valid
BLE.S NOITEM ; if it's not, don't bother
MOVEQ #0,D1 ; clear D1 for byte arithmetic
LEA MENUDATA(A0),A1 ; get menuData handle
MOVE.B (A1)+,D1 ; get title length
ADD.w 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
BEQ.S NOITEM ; length zero marks end of list
ADDQ #4,D1 ; there are 4 bytes of item properties
ADD.w D1,A1 ; bump to next item
BRA.S GETILOOP ; loop till done
; the item couldn't be found so return NIL
NoItem
SUB.L A0,A0 ; zero A0
MOVE.L A0,A1 ; and A1 too
Exit
MOVE.L A0,D0 ; and 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
bsr.s ExpandItem ; puff item up to full size <2.1>
bra.s EXIT ; and leave
; ExpandItem. Take basic menu item data and fill in more with _GetAuxMenuItem.
; New in <2.1>.
; On entry: A1 points to a menu item
; A3 is the menu handle
;
; On exit: A0 points to the item string of interest
; A1 points to that item's attribute byte list (on the stack)
; Eats D0, D1
ExpandItem
; copy menu item attributes to stack, split into distinct fields (unroll the
; variant in itemCmd).
movem.l d2/a2,-(sp) ; save regs <2.2>
move.l a1,a2 ; move pointer to safe register
moveq #0,D1 ; clear D1 for byte arithmetic
move.b (a1)+,d1 ; get length
add d1,a1 ; bump to item properties
lea itemStackBase(a6),a0 ; address of working copy
; set defaults (one at a time, to avoid odd-address problems since string be any length)
move.b (a1)+,(a0)+ ; copy attribute byte
move.b (a1)+,(a0)+ ; copy attribute byte
move.b (a1)+,(a0)+ ; copy attribute byte
move.b (a1)+,(a0)+ ; copy attribute byte
clr.l (a0)+ ; set defaults
clr.l (a0)+ ; set defaults
clr.l (a0) ; set defaults
lea itemStackBase(a6),a0 ; address of working copy, again
; check for script code
moveq #0,d1 ; clear the air
move.b itemCmd(a0),d1 ; get record variant field
cmp.w #ScriptMenuCmd,d1 ; is there a script code?
bne.s notScripted ; jump if not
move.b itemIcon(a0),itemScript+1(a6) ; if scripted, icon has script number
clr.b itemIcon(a0) ; reset field to say "no icon"
bra.s doneConvert ; rejoin
; check for hierarchical item
notScripted
cmp.w #HMenuCmd,d1 ; hierarchical menu?
bne.s notHierarchical ; jump if not
move.b itemMark(a0),itemHierarchicalID+1(a6)
clr.b itemMark(a0) ; reset to say "no mark"
bra.s doneConvert ; rejoin
; check for icon and icon type
notHierarchical
cmp.w #ShrunkenIconCmd,d1 ; shrunken icon?
beq.s sizedIcon ; jump if so
cmp.w #SmallIconCmd,d1 ; small icon?
beq.s sizedIcon ; jump if so
tst.b itemIcon(a0) ; is there an icon?
beq.s getAuxdata ; jump if not
move.w #LargeIconCmd,itemIconSize(a6) ; save default icon type
bra.s getAuxData ; and continue (don't clear itemCmd!)
sizedIcon
move.w d1,itemIconSize(a6) ; copy type to proper field
doneConvert
clr.b itemCmd(a0) ; reset field to say "no command key"
getAuxData
subq.l #2,sp ; room for return result
move.l a3,-(sp) ; push menu handle
move.l a2,-(sp) ; push pointer to menu item
pea itemIconHandle(a6) ; push buffer address
move.l #Sizeof_auxdata,-(sp) ; push buffer size
_GetAuxMenuItem ; get the extra info
addq.l #2,sp ; dump result
move.l a2,a0 ; point at name (in list item)
lea itemStackBase(a6),a1 ; point at the (extended) attributes
tst.l itemIconHandle(a6) ; icon handle known now?
beq.s doneExpand ; jump if not
clr.b itemIcon(a1) ; nuke unneeded resource #
doneExpand
movem.l (sp)+,d2/a2 ; restore regs <2.2>
rts ; return to sender
;---------------------------------------
; Utility -- GetSizes <Taken from MDEF, FJL 12-29-86>
;---------------------------------------
; GetSizes reads the size of the current font into the stack frame. It puts
; ascent+descent+leading into the leading field and tweaks width for chicago
GetSizes LEA MInfoRec(A6),A2 ; point to our info rec <1Aug85>
MOVE.L A2,-(SP) ; push a pointer <1Aug85>
_GetFontInfo ; and get the font's info <1Aug85>
MOVE.W (A2)+,D0 ; get ascent <1Aug85>
ADD.W (A2)+,D0 ; add descent <1Aug85>
CMP.W #14,(A2) ; fudge width for chicago <1Aug85>
BNE.S @notChicago ; => not chicago <1Aug85>
SUBQ #2,(A2) ; <1Aug85>
@notChicago
ADDQ #2,A2 ; skip over widmax <1Aug85>
ADD.W D0,(A2) ; store total height in MFHeight(A6) <1Aug85>
RTS
;---------------------------------------
; Utility -- GetItemHeight <Taken from MDEF, FJL 12-29-86>
;---------------------------------------
; GetItemHeight gets the height of the current menu item into D0.
; The item pointer is in A1.
GetItemHeight
MOVE.W MFHeight(A6),D0 ; get menu item height <1Aug85>
TST.W itemIconSize(A6) ; does it have an icon? <2.2>
BEQ.S @gotHeight ; jump if not <2.2>
MOVE #34,D1 ; size of large icon <2.2>
CMP.W #LargeIconCmd,itemIconSize(a6) ; large icon? <2.2>
BEQ.S @isLarge ; jump if so <2.2>
MOVEQ #18,D1 ; else set to 18 <2.2>
@isLarge
CMP.W D0,D1 ; Is icon height > text height? <2.2>
BLT.S @gotHeight ; Nope, skip around <2.2>
MOVE.W D1,D0 ; Yes, use icon height instead <2.2>
@gotHeight
RTS
;-----------------------------------------------
; Utility -- SaveDemBits
;-----------------------------------------------
;
; Utility to create a bitmap or pixmap in which to save the bits in TempRect.
; Used by SaveBitsBar and HiliteMenu.
;
; On entry: TempRect has rectangle of bits to be saved.
; D0.b 1 if bits should be purgable, 0 if not <41>
;
; On exit: SavedHandle Has handle to bitmap or pixmap.
; If == 0 then couldn't alloc space.
SaveDemBits
subq #2,sp ; make room for error result
pea TempRect
move.b d0,-(sp) ; WITH purging <40><41>
pea SavedHandle
_SaveBits
tst.w (sp)+ ; ignore error
rts
;-----------------------------------------------
; Utility -- GetA0SaveData
;-----------------------------------------------
;
; utility to get pointer to last menu's save data in a0.
GetA0SaveData
move.l mbSaveLoc, a0 ; get handle to saved area
move.l (a0), a0 ; dereference
add.w lastMBSave(a0), a0 ; a0 points to last menu's data storage
rts
;-----------------------------------------------
; Utility -- GetA1SaveData
;-----------------------------------------------
;
; Utility to get pointer to last menu's save data (from mbarproc struct) into a1.
GetA1SaveData move.l mbSaveLoc, a1 ; get handle to saved area
move.l (a1), a1 ; dereference
add.w lastMBSave(a1), a1 ; a1 points to last menu's data storage
rts
;-----------------------------------------------
; Utility -- RemoveAnyBalloon
;-----------------------------------------------
RemoveAnyBalloon
SUBQ #2,SP ; room for Boolean
_HMGetBalloons ; what is the state of What Is? mode?
TST.B (SP)+
BEQ.S @noHelper
CLR.W -(SP) ; remove any balloons that are showing
_HMRemoveBalloon
TST (SP)+
@noHelper
RTS
;--------------------------------------------------------------------------------------------
;
; Msg #8 -- Restore -- retore bits behind a menu
;
;--------------------------------------------------------------------------------------------
;
; This call restores the bits that were saved under a menu pulldown.
; If there was insufficient memory to save the bits, then an appropriate
; update event is posted. This call takes the menuIndex of the menu to be
; restored in parameter (this is only needed if data was not saved).
;
RestoreBitsBar
bsr FullClip ; set clip wide open
BSR.s RemoveAnyBalloon ; remove any help balloons that are showing
bsr.s GetA0SaveData ; get ptr to last menu's save data
subq #2, sp ; make room the result
move.l mbBitsSave(a0), -(sp) ; get handle to saved "bits-behind"
_RestoreBits
addq #2, sp ; ignore the result
; update number of menus on screen
move.l mbSaveLoc, a0 ; get handle
move.l (a0), a0 ; dereference
subi.w #mbEntrySize, lastMBSave(a0) ; one fewer menu showing on screen
RTS
;--------------------------------------------------------------------------------------------
;
; Msg #9 -- GetRect -- return a ptr to a menuRect and reset other data needed by multiple
; menus.
;
;--------------------------------------------------------------------------------------------
;
; This call returns a ptr to a menu's rectangle. The menuIndex (6 byte offset) is in
; the lo-word of of param. If it can't find the menuIndex, it calculates the menuRect.
;
; This routine is called by MenuSelect every time it loops thru. It needs to do this because
; if a HMenu was just displayed the last loop thru, then MenuSelect's menuRect will
; be incorrect.
;
; This routine is also called just before MrMacHook is called since MrMacHook needs the
; menu's rectangle and we normally don't have the rectangle until after the menu is drawn.
;
; This routine is now called by MenuSelect before executing the Save Msg. This way we
; isolate the calculation of the menu's rectangle from the code that save the bits and
; draws the menu structure. This allows PopUpMenuSelect to use the Save Msg.
GetRectBar
move.l Param2(a6), d0 ; get the param
move.l mbSaveLoc, a0 ; get handle to mbar's save data
move.l (a0), a0 ; dereference
move.w lastMBSave(a0), d1 ; are there any menus?
beq.s @MenuNotFound ; no, so go calculate size instead
@MenuLoop
cmp.w mbMLOffset(a0,d1), d0 ; did we find the menuID?
beq.s @MenuFound ; yes, so branch
subi #mbEntrySize, d1 ; move to next index
beq.s @MenuNotFound ; if at end of list then didn't find menu
bra.s @MenuLoop ; loop if more
@MenuFound
lea mbRectSave(a0,d1), a1 ; get address of rect
move.l a1, Result(a6) ; and return it as the Result
@RectBarDone
rts
@MenuNotFound
bsr CalcMenuRect ; calculate the menu rectangle since we couldn't
; find it in the mbarproc data structure
lea TempRect, a0 ; move rect into TempRect for result
lea menuRect(a6), a1
move.l (a1), (a0) ; move Top/Left
move.l 4(a1), 4(a0) ; move Bottom/Right
move.l a0, Result(a6) ; return address of TempRect
bra.s @RectBarDone
;--------------------------------------------------------------------------------------------
;
; Msg #10 -- SaveAlt -- save other data pertinent to the menu after it is drawn
;
;--------------------------------------------------------------------------------------------
;
; This message is called directly after the MDEF has drawn a menu. At that time the two
; scrolling globals topMenuItem and atMenuBottom are known.
;
; The reason the mbar proc saves these globals instead of having MenuSelect do it is because
; the mbarproc is already set up to save info about each menu (its rect, direction and offset)
; and so it is trivial to save two more words about each menu. The alternative would have
; been to have MenuSelect reproduce a lot of the code that the mbarproc has to manipulate this
; saved data.
SaveAltBar
move.l Param2(a6), d0 ; get the param
move.l mbSaveLoc, a0 ; get handle to mbar's save data
move.l (a0), a0 ; dereference
move.w lastMBSave(a0), d1 ; are there any menus?
beq.s @SaveAltBarDone ; no, so return
@MenuLoop
cmp.w mbMLOffset(a0,d1), d0 ; did we find the menuID?
beq.s @MenuFound ; yes, so branch
subi #mbEntrySize, d1 ; move to next index
beq.s @SaveAltBarDone ; if at end of list then didn't find menu
bra.s @MenuLoop ; loop if more
@MenuFound
move topMenuItem, mbTopScroll(a0,d1.w) ; save scrolling globals
move atMenuBottom, mbBotScroll(a0,d1.w)
@SaveAltBarDone
rts
;--------------------------------------------------------------------------------------------
;
; Msg #11 -- ResetScroll -- reset the scrolling globals for the given menu
;
;--------------------------------------------------------------------------------------------
;
; Reset the global variables topMenuItem and atMenuBottom.
;
; This routine is called by MenuSelect every time it loops thru. It needs to do this because
; if a HMenu was just displayed the last loop thru, then not only will MenuSelects menuRect
; be incorrect, but the two scrolling globals are reset by the MDEF when it is asked to
; draw the menu and these must be reset.
ResetScrollBar
move.l Param2(a6), d0 ; get the param
move.l mbSaveLoc, a0 ; get handle to mbar's save data
move.l (a0), a0 ; dereference
move.w lastMBSave(a0), d1 ; are there any menus?
beq.s @ResetBarDone ; no, so return
@MenuLoop
cmp.w mbMLOffset(a0,d1.w), d0 ; did we find the menuID?
beq.s @MenuFound ; yes, so branch
subi #mbEntrySize, d1 ; move to next index
beq.s @ResetBarDone ; if at end of list then didn't find menu
bra.s @MenuLoop ; loop if more
@MenuFound
move mbTopScroll(a0,d1.w), topMenuItem ; reset scrolling globals for this menu
move mbBotScroll(a0,d1.w), atMenuBottom
@ResetBarDone
rts
;--------------------------------------------------------------------------------------------
;
; Msg #12 -- GetMenuRgn -- return the menu bar's region
;
;--------------------------------------------------------------------------------------------
;
;
ReturnMenuRgn
move.l Param2(a6), -(sp) ; push the param on the stack
; use portRect instead of assuming topLeft is (0,0) <FJL CXXX>
move portRect+Left(a2), -(sp); left
move portRect+Top(a2), -(sp) ; top
move PortRect+Right(A2),-(SP); right
move portRect+Top(a2), -(sp) ; bottom = top + mBarHeight
move MBarHeight, d0
add d0, (sp)
_SetRecRgn ; clip to the menu bar
move.l Param2(a6), Result(a6) ; return handle passed in as the result
@ReturnRgnDone
rts
;--------------------------------------------------------------------------------------------
;
; Msg #13 -- MoveSIcon -- move small icon into title of apple menu
;
;--------------------------------------------------------------------------------------------
MoveSICNToAM MOVE.B #SICNInAppleMenu, D6 ; Entry for moving SICN to Apple Menu
BRA.S MoveIcon
MoveSICNToPM MOVE.B #SICNInApplicationMenu, D6 ; Entry for moving SICN to Application Menu
BRA.S MoveIcon
MoveICSToAM MOVE.B #ICSInAppleMenu, D6 ; Entry for moving icon suite to Apple Menu
BRA.S MoveIcon
MoveICSToPM MOVE.B #ICSInApplicationMenu, D6 ; Entry for moving icon suite to Application Menu
MoveIcon
CLR.L Result(A6) ; Return 0 on (possible) failures
MOVEQ #6, D3 ; 6 B.O. = 6 (first title)
CMP.W (A3), D3 ; Is it in the legal range?
BGT NoMoveS ; Skip if not
MOVE.W lastMenu(A3), D0 ; Get last regular menu
ADDQ.W #6, D0 ; Get to HMenu header
TST.L menuTitleSave(A3, D0) ; Is a title highlighted?
BNE NoMoveS ; Skip if so
BTST #1, D6 ; if Apple Menu
BNE.S @FindApplicationMenu
MOVE.L menuOH(A3, D3), A0 ; Get handle to first menu
MOVE.L (A0), A4 ; Get ptr to first menu
CMP.W #$0114, menuData(A4) ; if (menuData != apple sign)
BNE NoMoveS ; exit
BRA.S @MenuFound
@FindApplicationMenu ; else
bsr FindFirstSystemMenu6BO ; See whether we have a system menu <43>
beq NoMoveS ; if no system menu, exit <43>
move.l d0,d3 ; put 6BO into our offset (d3) <43>
@FindAppMenuLoop ; <43>
cmp.w lastMenu(a3),d3 ; Is current menu is in menulist <43>
bgt NoMoveS ; no => exit <43>
MOVE.L menuOH(A3, D3), A0 ; Is current menu the Application menu? <43>
MOVE.L (A0), A4
CMP.W #kApplicationMenuID, menuID(A4)
BEQ.S @MenuFound
ADDQ #6, D3 ; go to the next menu
BRA.S @FindAppMenuLoop ; end while
@MenuFound ; end if
_HLock ; lock the menuhandle
BSR ClipMBar ; Set clipRgn to menu bar
CLR.W SelectFlag(A6) ; Draw normal mode
CLR.W TitleBackFlag(A6)
BSR SetTitleColor ; Set the colors (also saves current colors)
MOVE.L D3, D0
BSR GetTitleRect
BSR.S CalcRightRectSize ; grow or shrink TempRect to 16x16
MOVE.W Param1(A6), D4 ; Get the scroll distance
BEQ.S @NoScroll ; Skip if no scroll
SUBQ.L #4, SP ; Make room for the Update Rgn
_NewRgn
MOVE.L (SP)+, D5
PEA TempRect ; theRect
MOVE.W D4, -(SP) ; dh = Param1
CLR.W -(SP) ; dv = 0
MOVE.L D5, -(SP) ; updateRgn
_ScrollRect ; Scroll it
MOVE.L D5, -(SP) ; rgn
_SetClip ; Clip to the updateRgn
MOVE.L D5, -(SP) ; rgn
_DisposRgn
BRA.S @ScrollDone
@NoScroll
PEA TempRect ; theRect
_EraseRect
@ScrollDone
; The IconState variable keeps track of where the current icon/title is. Currently it
; is interpreted to be the number of pixels left to shift in.
MOVE.L mbSaveLoc, A0 ; Get handle to save data
MOVE.L (A0), A0 ; Dereference it
MOVE.W mbIconState(A0), D5 ; Get the icon state
BGT.S @SameOld ; Still working on same icon
; A new icon is coming in. Reset the icon state to the title width
MOVE.W TempRect+right, D5 ; Width of title
SUB.W TempRect+left, D5 ; is width of TempRect
@SameOld
MOVE.W TempRect+left, D1 ; Pen normally based upon left edge of TempRect
TST.L Param2(A6) ; Using an icon?
BNE.S @anIcon ; Skip if so
MOVE.W menuLeft(A3, D3), D1 ; Menu title based upon menuleft[index]
ADD.W portRect+left(A2), D1 ; + portRect.left
ADDQ.W #8, D1 ; + 8
@anIcon
MOVE.W D4, D0 ; Get the shift distance
BLT.S @ShiftLeft
BGT.S @ShiftRight
; The icon/title is to be replaced in its entirety.
MOVEQ #0, D5 ; Set icon state to 0
BRA.S @ShiftCommon
@ShiftLeft
; The icon/title is moving left.
ADD.W D0, D5 ; Decrement the icon state (D0<0)
ADD.W D5, D1 ; Add it to pen
BRA.S @ShiftCommon
@ShiftRight
; The icon/title is moving right.
SUB.W D0, D5 ; Decrement the icon state (D0>0)
SUB.W D5, D1 ; Subtract it from pen
@ShiftCommon
MOVE.L clipRgn(A2), A0 ; Get the clip region
MOVE.L (A0), A0 ; Dereference it
MOVE.W D1, -(SP) ; x coordinate for pen
BSR GetMenuAscent ; Returns value in D4
MOVE.W D4, -(SP) ; y coordinate for pen
_MoveTo ; Set the pen location
TST.L param2(A6) ; Get the icon handle
BEQ.S @NoIcon ; Skip if none
MOVE.L #$FFF40000, appleRect+topLeft(A6) ; top = -12, left = 0
MOVE.L #$00040010, appleRect+botRight(A6) ; bottom = 4, right = 16
PEA appleRect(A6) ; theRect for OffsetRect
SUBQ.L #4, -(SP) ; Make room for pen
MOVE.L SP, -(SP) ; Point to it
_GetPen
_OffsetRect ; Offset icon's rect by pen position
BTST #0, D6
BEQ.S @IsaSICN
SUBQ #2, SP ; make room for result
PEA appleRect(a6) ; push the title rect
MOVE.W #atAbsoluteCenter, -(SP) ; No need to do centering since the rect is of the right size
MOVE.W #ttNone, -(SP) ; assume no transformation needed
MOVE.L param2(A6), -(SP) ; push the icon handle
_PlotIconSuite
ADDQ #2, SP ; dump the result
BRA.S MoveSDone
@IsaSICN
PEA appleRect(A6) ; theRect for PlotSIcon
MOVE.L param2(a6), -(SP) ; theSIcon for PlotSIcon
BSR.S PlotSIcon ; Plot it
BRA.S MoveSDone
@NoIcon
BSR DrawSimple ; Draw the regular title
MoveSDone
MOVEQ #0, D0 ; Assume same icon
MOVE.L mbSaveLoc, A0 ; Get handle to save data
MOVE.L (A0), A0 ; Dereference it
MOVE.W D5, mbIconState(A0) ; Save the icon state
BGT.S @SameIcon ; Skip if still positive
MOVEQ #-1, D0 ; Flag new icon needed
@SameIcon
MOVE.L D0, Result(A6) ; Return the result
BSR ResetPreviousColors ; Restore the colors
BSR FullClip ; Set the clipRgn back to full open
MOVE.L menuOH(A3, D3), A0 ; Get the menuHandle
_HUnlock ; Unlock it
NoMoveS
RTS
;--------------------------------------------------------------------------------------------
; PROCEDURE PlotSIcon(theRect: Rect; theIcon: SIconHandle)
PlotSIcon
LEA IconBitMap, A1 ; Get address of the icon mgr bitMap
MOVE.L 4(SP), D0 ; Get the icon handle
BEQ.S DoneIPlot ; If nil, don't plot
MOVE.L D0, A0 ; Get the Icon Handle in address reg
MOVE.L (A0), (A1)+ ; baseAddr = master pointer
MOVE.W #2, (A1)+ ; rowBytes = 2
CLR.L (A1)+ ; topLeft = 0, 0
MOVE.L #$00100010, (A1) ; botRight = 16, 16
MOVE.L 8(SP), D1 ; Get theRect
LEA IconBitMap, A1 ; Point A1 at the bitMap again
MOVE.L A1, -(SP) ; srcBits = iconBitMap
MOVE.L GrafGlobals(A5), A0
MOVE.L thePort(A0), A0
PEA portBits(A0) ; dstBits = portBits
PEA bounds(A1) ; srcRect = iconBitMap.bounds
MOVE.L D1, -(SP) ; dstRect = theRect
CLR.W -(SP) ; srcCopy
CLR.L -(SP) ; maskRgn = nil
_CopyBits
DoneIPlot
MOVE.L (SP)+, A0 ; Get return address
ADDQ.L #8, SP ; Strip parameters
JMP (A0) ; And return to caller
;--------------------------------------------------------------------------------------------
;
; Msg #14 -- GetTRect -- Return the title rect of the menu given in param2
;
;--------------------------------------------------------------------------------------------
;
; Return the rectangle enclosing the area specified.
; NOTE: This call depends entirely on the GetTitleRect routine to calculate the
; bounding rectangle for each menu. Don<6F>t change it without changing this.
; It also assumes lastRight is the right edge of the visible app menus.
;
; Param1 Result
; ------------- ------------------------------------------------------------------
; <pos> = 6 B.O. Return the title rect for that menu
; = 0 Return the rectangle enclosing the menu bar
; -1 Return the rectangle enclosing the system menus which are visible
; -2 Return the rectangle enclosing the apps menus which are visible
;
GetTRect
MOVE.L #0, result(A6) ; We always return zero
LEA TempRect, A1 ; Get the address of tempRect
MOVE.W param1(A6), D0 ; Which part of the menubar should we return?
BMI.S @specialRect ; Wants special rect information
CMP.W lastMenu(A3), D0 ; Is this a valid offset?
BGT.S @returnEmptyRect ; Bail if someone is trying to run us off the road
BSR GetTitleRect ; Puts the title rect into tempRect
@StuffFromTemp
MOVE.L param2(A6), A0 ; Get the address of the rectangle
MOVE.L (A1)+, (A0)+ ; Copy topLeft
MOVE.L (A1)+, (A0)+ ; Copy bottomRight
RTS
@specialRect
TST.W lastMenu(A3) ; Are there any menus?
BEQ.S @returnEmptyRect ; OH, NO! there are none!
ADDQ #1, D0 ; Is it -1 (App menu case) ?
BEQ.S @AppRect
ADDQ #1, D0 ; Is it -2 (System menu case) ?
BEQ.S @SystemRect
@returnEmptyRect
MOVEQ #0,D0 ; Get a zero
MOVE.L D0, topLeft(A1) ; Set topLeft(TempRect)
MOVE.L D0, botRight(A1) ; Set botRight(TempRect)
BRA.S @StuffFromTemp ; Return that empty rect
@SystemRect
MOVEQ #0, D0 ; Clear out high word
BSR FindFirstSystemMenu6BO ; Find the first system menu
BEQ.S @returnEmptyRect ; Equal if no system menus
@nextSysLoop
MOVE.L D0, -(SP) ; Save across GetTitleRect call
BSR GetTitleRect ; Get its title rect (left >= right if obscured)
MOVE.L (SP)+, D0 ; Restore it
MOVE.W left(A1), D1 ; Get the left side
CMP.W right(A1), D1 ; IF left < right THEN {empty}
BLT.S @foundVisSys ; found 1st visible system menu
ADDQ #6, D0
CMP.W lastMenu(A3), D0 ; IF D0 <= lastMenu THEN
BLE.S @nextSysLoop ; goto nextSysLoop
BRA.S @returnEmptyRect ; We should never get here since the last system menu
; was never supposed to be obscured (BUT...)
@foundVisSys
MOVE.W left(A1), -(SP) ; Save the left side of visible system area
MOVE.W lastMenu(A3), D0 ; Get the last menu 6 B.O.
BSR GetTitleRect ; Get its title rect
MOVE.W (SP)+, D0 ; Restore first vis menu.left from stack
MOVE.W D0, left(A1) ; Force in the new left side
BRA.S @StuffFromTemp ; And return this rect
@AppRect
MOVEQ #6, D0 ; Get the 1st menu 6 B.O.
BSR GetTitleRect ; Get its title rect
MOVE.W lastRight(A3), D0 ; Get the last right
MOVE.W D0, right(A1) ; Stuff right with lastRight
BRA.S @StuffFromTemp ; And return this rect
;--------------------------------------------------------------------------------------------
;
; Msg #15 -- BannerMsg -- Draw the given string in the given script in the menubar
;
;--------------------------------------------------------------------------------------------
;
; Erase the menu bar area and TextBox in the given string in the menu bar.
;
; Param1 Param2
; -------------------------- -------------------------
; <special> ptr to pString none
; lo byte=scriptID
; hi byte=teJust for textbox
;
BannerMsg
moveq #0,a4 ; <49> Zero it out for the call to SetTitleColor
CLR.W -(SP) ; Unhilite any hilited menu
_HiliteMenu
MOVE.L param2(A6), -(SP) ; Save off the old parameter value before clearing
MOVE.L #-1, param2(A6) ; -1 is the clear indicator
BSR DrawBar ; Draw a cleared menubar
MOVE.L (SP)+, param2(A6) ; Restore the old parameter value
MOVE.W param1(A6), D0 ; Get param1
TST.B D0 ; Is it script?
BGE.S @noScript ; Nope
AND.W #$7F, D0 ; Mask out the junk
SUBQ #4, SP ; Make room for script result
MOVE.W D0, -(SP) ; Push script ID
MOVE.W #smScriptSysFondSize, -(SP)
_GetScript
_TextFont
_TextSize
@noScript
move.w #srcOr, -(sp) ; set text mode to srcOr
_TextMode
MOVEQ #0, D0 ; Zero get the entire menubar rect
BSR GetTitleRect ; Put rect into temprect
PEA TempRect ; Get the address of tempRect
MOVE.W #mbMenu1Loc, -(SP) ; This will be the horz inset
MOVE.W #1, -(SP)
_InsetRect ; TempRect has the TextBox rect
MOVEQ #0, D0 ; Clear all bytes
MOVE.W D0, SelectFlag(a6) ; clear select flag ==> draw normal mode
MOVE.W D0, TitleBackFlag(a6) ; calling SetTitleColor from DrawTitle
BSR SetTitleColor ; set color for title/background
;TextBox(p, size, r, style);
MOVE.W param1(A6), D1 ; Get param1
ASR #8, D1 ; Roll down to the teJust
MOVE.L param2(A6), A0 ; Get the stringPointer
MOVE.B (A0), D0 ; Copy the length byte
ADDQ #1, A0 ; Skip the length byte
MOVE.L A0, -(SP) ; Pointer to text
MOVE.L D0, -(SP) ; Length
PEA TempRect ; the rect address
MOVE.W D1, -(SP) ; the teJust
_TextBox
BSR ResetPreviousColors ; reset to original fore/back colors
RTS
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
END