sys7.1-doc-wip/Toolbox/MenuMgr/StandardMBDF.a
2020-04-26 16:46:44 +08:00

3131 lines
120 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;
; Hacks to match MacOS (most recent first):
;
; <Sys7.1> 8/3/92 Reverted <SM3>: changed back to short branches
; 9/2/94 SuperMario ROM source dump (header preserved below)
;
;
; File: StandardMBDF.a
;
; Contains: menu bar definition procedure
;
; Written by: David Fung
;
; Copyright: © 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 doesnt 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
; didnt 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 Kevins 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.
; <•1.2> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
; <•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.
;
;————————————————————————————————————————————————————————————————————————————————————————————————————
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, dont 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.s DrawDone ; branch if none <FJL A428> ex<SM3> CSS <Sys7.1>
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) ; heres 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 its 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 dont 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 dont 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 its 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.S SystemMenusAreIN ; Well, there aren't any -- so they are all in! ex<SM3> CSS <Sys7.1>
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, dont add system menus
_HLock ; Lock SysList before munging (were 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 ; Dont 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 menus 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: were 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 weve 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 were 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.S FlipBar ; if index = 0 then flip bar <FJL C175><35> ex<SM3> CSS <Sys7.1>
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. Dont 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
;————————————————————————————————————————————————————————————————————————————————————————————————————
END