sys7.1-doc-wip/Toolbox/MenuMgr/SystemMenusPatch.a
2019-07-27 22:37:48 +08:00

308 lines
12 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.

;
; File: SystemMenusPatch.a
;
; Contains: patches to the Menu Manager to support system menus
;
; Written by: Kevin S. MacDonell
;
; Copyright: © 1990, 1992 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <11> 1/20/92 PN Roll in patches into MenuMgr.a
; <10> 10/8/90 dba make simpler Munger call in GetMenuBar to shrink the code a bit;
; also fix potential bug where high word was not cleared
; <9> 9/6/90 KSM System Menus are installed ONLY if (and whent) you install an
; Apple Menu. Get/SetMenuBar remove and insert System Menus,
; respectively. Insert patch calls _IsSystemMenu for consistency.
; <8> 7/10/90 KSM Roll out Help Mgr setup code.
; <7> 7/9/90 KSM Roll in HelpMgr menu setup code. Bug fix in system menu
; insertion code. Use new system menu range checking.
; <6> 6/8/90 KSM Move equates to MenuMgrPriv.a and include here.
; <5> 4/29/90 KSM Remove debug messages.
; <4> 4/29/90 KSM Update the utilities.
; <3> 4/17/90 KSM Commented out GetMenuBar Patch (*** need to just nuke this at
; some point!)
; <2> 4/10/90 KSM Update GetMenuBar patch.
; <1> 4/9/90 dba integrated with the new MBDF; checked in for the first time
; 4/6/90 KSM New today.
;
load 'StandardEqu.d'
include 'LinkedPatchMacros.a'
include 'MenuMgrPriv.a'
MACRO
_DMSG &msg
if &msg = '' then
_Debugger
else
PEA @dbgStrBase
_DebugStr
BRA.S @overstring
@dbgStrBase:
DC.B &msg
ALIGN 2
@overstring:
endif
ENDM
;————————————————————————————————————————————————————————————————————————————————————————————————————
; InitSystemMenuList — Clear out system menu list global.
InitSystemMenuList InstallProc (Plus,SE,II,Portable,IIci)
MOVE.L SystemMenuList, A0 ; Dump the switcherTpr table
_DisposPtr
MOVEQ #InitMListSize, D0 ; Get size of menuList
_NewHandle ,SYS,CLEAR ; Allocate it in system heap
MOVE.L A0, SystemMenuList ; Save off the new handle
RTS
ENDPROC
;————————————————————————————————————————————————————————————————————————————————————————————————————
; GetMenuBarDoesNotReturnSystemMenus — do not return system menus in the returned menu list
GetMenuBarDoesNotReturnSystemMenus PatchProc _GetMenuBar,(Plus,SE,II,Portable,IIci)
IMPORT FindFirstSystemMenu6BO
jsr FindFirstSystemMenu6BO ; Are there any system menus?
beqOLD ; EQ means no system menus, do the original thing
MOVE.L d3,-(SP) ; Save off a work register
MOVEQ #0,D3
MOVE.W D0,D3 ; Save off index
SUBQ.L #4,SP ; Make room for result
jsrOLD ; Call thru
MOVE.L (SP)+,A0 ; Get copy of menulist
MOVE.L A0,8(SP) ; Return as result
BEQ.S @done ; EQ means no menulist or memfull
; Munger(menuH, d3, NIL, d1, POINTER(-1), 0);
MOVE.L (A0),A1 ; Get copymenulist ptr
moveq #0,d1 ; clear out high word <10>
MOVE.W lastMenu(A1),D1 ; Offset to last menu (could be zero but weve chkd that)
ADDQ.W #6,D1 ; Offset past last menu entry
SUB.W d3,D1 ; D1 = Offset to last menu - Offset to 1st sysmenu
; (i.e., # bytes for system menus)
SUB.W D1,lastMenu(A1) ; Set new count for the list
SUBQ.L #4,SP ; Make room for Munger result
MOVE.L A0,-(SP) ; Push the handle
MOVE.L d3,-(SP) ; offset=first system menu offset
CLR.L -(SP) ; ptr1=NIL <10>
MOVE.L D1,-(SP) ; len1=# of bytes to delete
MOVE.L A0,-(SP) ; ptr2=anything non-nil will do
CLR.L -(SP) ; len2=0 means delete
_Munger ; Rip out system menus
ADDQ.L #4,SP ; ignore Munger result
@done
MOVE.L (SP)+,d3 ; Restore work register
RTS
ENDPROC
;————————————————————————————————————————————————————————————————————————————————————————————————————
; SetMenuBarAddsSystemMenus — SetMenuBar should add the system menus to the current menu list
SetMenuBarAddsSystemMenus PatchProc _SetMenuBar,(Plus,SE,II,Portable,IIci)
MOVE.L 4(SP),-(SP) ; Copy params
jsrOLD ; Call old one, but come back here
MOVE.L MenuList,D0 ; Get result
BEQ.S @done ; EQ means no menulist or memfull
; Call the MBDF to put in the system menus
MOVEQ #2,D0 ; set up for the menu-edge-calc msg
CLR.L D1 ; calc entire bar
IMPORT CallMBarProc
jsr CallMBarProc
@done
MOVE.L (SP)+,(SP) ; Eat param (handle)
RTS
ENDPROC
;————————————————————————————————————————————————————————————————————————————————————————————————————
; PatchInsertMenu
; When this patch sees a system menu (-16385 thru -32768), it adds it to the system menu bar.
; If the system menu bar doen't exist, this patch creates it.
; If the menu is not a system menu, ensure that the beforeID is modified so that the
; menu is inserted before the system menu partition.
PatchInsertMenu PatchProc _InsertMenu,(Plus,SE,II,Portable,IIci)
EXPORT FindFirstSystemMenu6BO
InsertStack RECORD {base},DECR
ParamBegin: EQU * ; start parameters after this point
menuHdl DS.L 1
beforeID DS.W 1
ParamSize: EQU ParamBegin-*
retAddr DS.L 1
base DS.W 0
LocalSize: EQU *
ENDR
WITH InsertStack
CMP.W #$FFFF, beforeID(SP) ; beforeID = -1 ==> H Menu
beqOld
; If a system menu is being inserted, put it into the System Menu Bar
MOVE.L menuHdl(SP), A0 ; Get the MenuHandle
MOVE.L (A0), A0 ; dereference
SUBQ.L #4,SP ; Make Room for result & VAR
MOVE.W menuID(A0),-(SP) ; Push the menuID
PEA 4(SP) ; Point to VAR
_IsSystemMenu ; Do it the standard way
ADDQ.L #2,SP ; Eat the result
TST.B (SP)+ ; Is it a system menu?
BNE.S @DoSystemMenu ; EQ means it is a system menu
; Menu for main list, be sure it is inserted before all the system menus
BSR FindFirstSystemMenu6BO ; Find the system menu partition
beqOld ; Do old stuff if no system menus
MOVE.W D0, D1 ; Save off 6BO of 1st system menu
MOVE.W beforeID(SP), D0 ; Get the beforeID
BEQ.S @forceBeforeSys ; branch if zero
BSR Find6BOFromID ; Find its offset
BEQ.S @forceBeforeSys ; branch if the beforeID not in list
CMP.W D1, D0 ; Is it after the system partition?
bleOld ; No, do as caller wanted
MOVE.W D0, D1 ; It is after the system partition
@forceBeforeSys ; the beforeID must be changed to before the 1st system menu
MOVE.L MenuList, A0 ; get the menulist
MOVE.L (A0), A0 ; deref
MOVE.L menuOH(A0,D1.W), A0 ; get the menuhandle to insert before
MOVE.L (A0), A0 ; deref
MOVE.W menuID(A0), beforeID(SP) ; Make beforeID be 1st system menu
braOld ; Now go do it
@DoSystemMenu
; If menuID already exists in system menulist, we're done!
MOVE.L MenuList, A1 ; Save Menulist
MOVE.L SystemMenuList, MenuList ; Store system as menulist
BSR Find6BOFromID ; Is this menuID already in the list?
MOVE.L A1, MenuList ; Restore Menulist
TST.W D0 ; Was the menuID found?
BNE.S @Done ; Don't double insert it, done.
; Swap the two menu lists so this menu inserts into the system menu
MOVE.W beforeID(SP), D0 ; Get the beforeID
BEQ.S @AddAtEnd ; Yes, branch
MOVE.L MenuList, A1 ; Save Menulist
MOVE.L SystemMenuList, MenuList ; Store system as menulist
BSR.S Find6BOFromID ; Look up the beforeID
MOVE.L A1, MenuList ; Restore Menulist
TST.W D0 ; Was the menuID found?
BNE.S @DoTheAdd
@AddAtEnd
MOVE.L SystemMenuList, A0 ; Get system menulist
MOVE.L (A0), A0 ; deref
MOVE.W lastMenu(A0), D0 ; Get last menu
ADDQ.W #6, D0 ; Insert "before" the end
@DoTheAdd
SUBQ.L #4, SP ; Make room for result
MOVE.L SystemMenuList, -(SP) ; handle
MOVE.W D0, -(SP) ; Move the offset
CLR.W -(SP) ; as a long with high cleared
CLR.L -(SP) ; ptr1 = 0
CLR.L -(SP) ; len1 = 0
PEA 6+20(SP) ; ptr2 = menuhandle parameter
MOVEQ.L #6, D0
MOVE.L D0, -(SP) ; len2 = 6
_Munger ; Munge away! Left coord will be junk.
ADDQ.L #4, SP ; Dump result
; Remember to update the lastMenu field
MOVE.L SystemMenuList, A0 ; Get system menulist
MOVE.L (A0), A0 ; handle -> ptr
ADDQ.W #6, lastMenu(A0) ; Bump the count
@Done
MOVE.L (SP)+, A0 ; Get the return address
ADDQ.L #ParamSize, SP ; Cut back the parameters
JMP (A0)
;______________________________________________________________________________________________
; 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
EXPORT FIND6BOFROMID
;______________________________________________________________________________________________
; Utility -- Find6BOFromID
; Find and return six byte offset of menuID in D0.
; Returns in D0 the 6B0 in D0 (with condition codes set) or zero if not found.
; All registers (except D0 of course) are preserved.
F6B0SaveReg REG D1/A0/A1
Find6BOFromID
MOVEM.L F6B0SaveReg, -(SP) ; Save our regs
MOVE.L MenuList, A0 ; Get the current menulist
MOVE.L (A0), A0 ; dereference
MOVE.W D0, D1 ; Save the item were looking for
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 menuID(A1), D1 ; Is this the one?
BEQ.S @foundIt ; Branch if it is.
SUBQ #6, D0 ; point to the next one in the menulist
BNE.S @nextMenu ; If more menus, branch...
@foundIt
TST.W D0 ; Return the 6B0 as promised (w/cond. codes)
@done
MOVEM.L (SP)+, F6B0SaveReg ; Restore our regs
RTS
EndProc
;————————————————————————————————————————————————————————————————————————————————————————————————————
end