mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-26 01:49:19 +00:00
953 lines
36 KiB
Plaintext
953 lines
36 KiB
Plaintext
;
|
||
; File: DialogDispatch.a
|
||
;
|
||
; Contains: Dispatcher to new Dialog Manager calls.
|
||
;
|
||
; Written by: Kevin S. MacDonell
|
||
;
|
||
; Copyright: © 1989-1990, 1992 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM8> 12/18/92 CSS Update from Reality:
|
||
; <19> 12/17/92 JSM Fix some StdFilter bugs relating to cursor tracking over edit
|
||
; text items, use dlgFlagsByte and bits equates consistently, and
|
||
; add comments about some non-obvious implications of calling
|
||
; ClaimEvent in StdFilter.
|
||
; <SM8> 8/28/92 CSS Update from Reality:
|
||
; <18> 8/25/92 DTY Save D3 in StdFilter to make Tom happy.
|
||
; <SM7> 7/29/92 RB The routine GetWindowModalClass calls GetResInfo on a WDEF,
|
||
; which when it ROM is not found to belong to any resource map
|
||
; anymore. The problem here is that the Installer comes later on
|
||
; and finds ResErr set to resNotFound, forcing the Installer to
|
||
; bail out from an installation even tough there is no real
|
||
; problem. To avoid this problem, we set ROMMapInsert to true
|
||
; before doing the GetResInfo on the WDEF, which may be in ROM.
|
||
; <17> 6/11/92 JSM Roll-in changes from SuperMario so this file can be used in the
|
||
; ROM build: rename ROMFrameOut and ROMClaimEvent ROMBinds to
|
||
; FrameOut and ClaimEvent to match DialogMgr.a in the ROM.
|
||
; <16> 3/31/92 KSM #1021993,<DTY>: Exported CitationsCH call - now returns OSErr
|
||
; (for dispatcher). Created new calls: Cite4 for easy-of-use, and
|
||
; the fully generic CitationsSH.
|
||
; <15> 3/6/91 dba handle NIL event passed into GetNextUserCancelEvent
|
||
; <14> 3/5/91 dba csd, #dba030501: fix GetUserCancelEvent
|
||
; <13> 1/14/91 dba (ksm) Add IsUserCancelEvent and GetUserCancelEvent.
|
||
; <12> 12/14/90 dba <JDR> call it DialogDispatch instead of DialogMgrDispatch
|
||
; <11> 12/3/90 RLC <ksm> Get rid of Is≈WindowModal routines and replace them with a
|
||
; GetModalClass and GetFrontModalClass routines.
|
||
; <10> 11/13/90 KSM <dba>Make 32-bit clean...
|
||
; <9> 10/29/90 KSM <ngk>Use emulateOrigFilterBit to emulate ROM filter proc, but with
|
||
; bug fix.
|
||
; <8> 10/29/90 ngk <KSM>add ROM bind for portable
|
||
; <7> 10/29/90 ngk <KSM>roll in new StdFilterProc and related functions to dialog
|
||
; dispatch
|
||
; <6> 7/13/90 RLC Provide an interface for Push/Pop MenuState for Help.
|
||
; <5> 7/2/90 KSM Add interface to the new standard filter proc.
|
||
; <4> 6/8/90 KSM Fix stack frame for IsFrontWindowModal.
|
||
; <3> 6/8/90 KSM Add Is[Front]WindowModal calls.
|
||
; <2> 6/7/90 KSM Check in ate my “load 'StandardEqu.d'”.
|
||
; <1> 6/7/90 KSM First checked in.
|
||
; <0> 6/7/90 KSM New today.
|
||
;
|
||
|
||
load 'StandardEqu.d'
|
||
include 'InternalMacros.a'
|
||
include 'LinkedPatchMacros.a'
|
||
include 'ScriptPriv.a'
|
||
include 'DialogsPriv.a'
|
||
|
||
; location of private fields in dialog record
|
||
dlgFlagsByte EQU wZoom ; = $71 where in dialog record byte of flags is stored
|
||
dlgDefaultButtonItem EQU aDefItem ; = $A8 where in dialog record item# for default button stored
|
||
dlgCancelButtonItem EQU editOpen ; = $A6 where in dialog record item# for cancel button stored
|
||
|
||
DEBUG default false
|
||
|
||
ROMs Plus,SE,II,IIci,Portable
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; DialogMgrDispatch $AA68
|
||
;
|
||
; The dispatcher to the new dialog manager routines <16>
|
||
|
||
DialogMgrDispatch BeginDispatcher _DialogDispatch
|
||
DispatchSelectors DMgrCite4
|
||
DispatchSelectors DMgrCitationsSH
|
||
DispatchSelectors DMgrCitationsCH
|
||
DispatchSelectors DMgrPopMenuState
|
||
DispatchSelectors DMgrPushMenuState
|
||
DispatchSelectors GetFrontWindowModalClass
|
||
DispatchSelectors GetWindowModalClass
|
||
DispatchSelectors GetStdFilterProc
|
||
DispatchSelectors SetDialogTracksCursor
|
||
DispatchSelectors SetDialogDefaultItem
|
||
DispatchSelectors SetDialogCancelItem
|
||
DispatchSelectors IsUserCancelEvent
|
||
DispatchSelectors GetNextUserCancelEvent
|
||
EndDispatcher
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; PRIVATE ROUTINES (negative selectors)
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; DMgrPushMenuState
|
||
|
||
; PROCEDURE DMgrPushMenuState;
|
||
|
||
|
||
DMgrPushMenuState PROC EXPORT
|
||
IMPORT PushMenuState
|
||
JMP PushMenuState
|
||
ENDPROC
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; DMgrPopMenuState
|
||
|
||
; PROCEDURE DMgrPopMenuState;
|
||
|
||
|
||
DMgrPopMenuState PROC EXPORT
|
||
IMPORT PopMenuState
|
||
JMP PopMenuState
|
||
ENDPROC
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; DMgrCitationsCH <16>
|
||
|
||
; FUNCTION CitationsCH(baseString: CharsHandle;offset: LONGINT;
|
||
; numCitations: INTEGER; citations: CiteListPtr): OSErr;
|
||
|
||
|
||
DMgrCitationsCH PROC EXPORT
|
||
IMPORT __CitationsCH
|
||
JMP __CitationsCH
|
||
ENDPROC
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; DMgrCitationsSH <16>
|
||
|
||
; FUNCTION CitationsSH(baseString: CharsHandle;
|
||
; numCitations: INTEGER; citations: CiteListPtr): OSErr;
|
||
|
||
|
||
DMgrCitationsSH PROC EXPORT
|
||
IMPORT __CitationsSH
|
||
JMP __CitationsSH
|
||
ENDPROC
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; DMgrCite4 <16>
|
||
|
||
; FUNCTION Cite4(baseString: StringHandle; p0,p1,p2,p3: StringPtr): OSErr;
|
||
|
||
|
||
DMgrCite4 PROC EXPORT
|
||
IMPORT __Cite4
|
||
JMP __Cite4
|
||
ENDPROC
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; PUBLIC ROUTINES (non-negative selectors)
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; GetFrontWindowModalClass
|
||
;
|
||
; FUNCTION GetFrontWindowModalClass(VAR modalClass: INTEGER): OSErr;
|
||
|
||
|
||
GetFrontWindowModalClass PROC EXPORT
|
||
IMPORT GetWindowModalClass
|
||
|
||
subq #4,sp
|
||
_FrontWindow
|
||
move.l (sp), a0
|
||
move.l 4(sp), (sp)
|
||
move.l 8(sp), 4(sp)
|
||
move.l a0, 8(sp)
|
||
jmp GetWindowModalClass
|
||
|
||
ENDPROC
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; GetWindowModalClass
|
||
;
|
||
; FUNCTION GetWindowModalClass(theWindow: WindowPtr; VAR modalClass: INTEGER): OSErr;
|
||
|
||
|
||
GetWindowModalClass PROC EXPORT
|
||
|
||
resultsStackFrame
|
||
result ds.w 1 ; The result
|
||
parametersStackFrame
|
||
theWindow ds.l 1 ; the window pointer to check
|
||
modalClass ds.l 1 ; the integer address
|
||
localsStackFrame
|
||
id ds.w 1 ; resID
|
||
rType ds.l 1 ; resType
|
||
rName ds.b 256 ; resName
|
||
endStackFrame
|
||
|
||
|
||
linkSave D3/A3-A4
|
||
move.l modalClass(a6),a3 ; Get the modal class address into A3
|
||
move.l theWindow(A6),a4 ; Get the windowptr into A4
|
||
move.l a4,d0 ; Is there a window?
|
||
beq.s @badWindow ; the window was NIL so return paramErr
|
||
|
||
btst #cannotTwitchOutOfDialogBit,dlgFlagsByte(a4) ; is this a modal dialog?
|
||
bne.s @wasModal ; ne means that is was a modal dialog (return dBoxProc)
|
||
|
||
subq #2,sp ; leave space for variant
|
||
move.l a4,-(sp) ; push window pointer
|
||
_GetWVariant ; get variant code
|
||
move.w (sp)+,d3 ; put in D3
|
||
|
||
clr.w (a3) ; clear returned modal class
|
||
|
||
cmp.w #dBoxProc,d3 ; dBoxProc=1; variant for dialog box no titleBar I-272
|
||
beq.s @wasPossiblyModal
|
||
|
||
cmp.w #movableDBoxProc,d3 ; movableDBoxProc=5; variant for movable modal
|
||
bne.s @returnWithNoErr
|
||
|
||
|
||
; The variant is dBoxProc or movableDBoxProc, but of which WDEF? Let’s find out…
|
||
;
|
||
@wasPossiblyModal
|
||
|
||
move.l windowDef(a4),d0 ; Get the defproc handle
|
||
_StripAddress ; Get rid of variant kept in hi byte (to be clean)
|
||
move.w #MapTrue,ROMMapInsert ; this WDEF could be in ROM ! <SM7> rb
|
||
move.l d0,-(sp) ; Push the handle
|
||
pea id(a6) ; VAR id
|
||
pea rType(a6) ; VAR type
|
||
pea rName(a6) ; VAR name
|
||
_GetResInfo
|
||
tst.w ResErr ; Was it a resource?
|
||
bne.s @returnWithNoErr
|
||
|
||
cmp.l #'WDEF',rType(a6) ; Is type = WDEF?
|
||
bne.s @returnWithNoErr
|
||
|
||
tst.w id(a6) ; Is ID = 0?
|
||
bne.s @returnWithNoErr
|
||
|
||
; If we get here, then the window defproc was the system WDEF ID = 0
|
||
;
|
||
; Now if the variant was dBoxProc then set the cannotTwitchOutOfDialogBit (modal) bit
|
||
; else just return the window's variant
|
||
;
|
||
move.w d3,(a3) ; stuff the variant as the modal class
|
||
|
||
cmp.w #dBoxProc,d3 ; dBoxProc=1; variant for dialog box no titleBar I-272
|
||
bne.s @returnWithNoErr
|
||
|
||
bset #cannotTwitchOutOfDialogBit,dlgFlagsByte(a4) ; this IS a modal dialog.
|
||
bra.s @returnWithNoErr
|
||
|
||
@badWindow
|
||
move.w #paramErr,d1 ; Return paramErr if a NIL window was passed
|
||
bra.s @exit
|
||
@wasModal
|
||
move.w #dBoxProc,(a3) ; Return modal result
|
||
@returnWithNoErr
|
||
move.w #noErr,d1
|
||
@exit
|
||
move.w d1,result(a6) ; Return result code
|
||
restoreUnlinkReturn
|
||
|
||
ENDPROC
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; GetStdFilterProc
|
||
;
|
||
; FUNCTION GetStdFilterProc(VAR proc: ProcPtr): OSErr;
|
||
|
||
|
||
GetStdFilterProc PROC EXPORT
|
||
IMPORT StdFilter
|
||
|
||
resultsStackFrame
|
||
result ds.w 1 ; The result
|
||
parametersStackFrame
|
||
proc ds.l 1 ; the window pointer to check
|
||
endStackFrame
|
||
|
||
linkSave
|
||
move.l proc(A6),A1
|
||
lea StdFilter, A0
|
||
move.l A0,(A1)
|
||
clr.w result(A6)
|
||
restoreunlinkreturn
|
||
|
||
ENDPROC
|
||
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; SetDialogDefaultItem
|
||
;
|
||
; FUNCTION SetDialogDefaultItem(theDialog: DialogPtr; newItem: INTEGER): OSErr;
|
||
;
|
||
SetDialogDefaultItem PROC EXPORT
|
||
|
||
resultsStackFrame
|
||
result ds.w 1 ; The result
|
||
parametersStackFrame
|
||
theDialog ds.l 1 ; the window pointer to check
|
||
newItem ds.w 1 ; the new default item
|
||
endStackFrame
|
||
|
||
linkSave
|
||
move.l theDialog(a6),a0 ; get dialog ptr
|
||
clr.w result(A6) ; return noErr
|
||
bset #systemHandlesDefaultButtonBit,dlgFlagsByte(a0) ; assume newItem is non-zero
|
||
move.w newItem(a6),dlgDefaultButtonItem(a0) ; set current default item in dialog
|
||
bne.s @done ; if non-zero then done
|
||
bclr #systemHandlesDefaultButtonBit,dlgFlagsByte(a0) ; else remeber there is no default item
|
||
@done restoreunlinkreturn
|
||
|
||
ENDPROC
|
||
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; SetDialogCancelItem
|
||
;
|
||
; FUNCTION SetDialogCancelItem(theDialog: DialogPtr; newItem: INTEGER): OSErr;
|
||
|
||
SetDialogCancelItem PROC EXPORT
|
||
|
||
resultsStackFrame
|
||
result ds.w 1 ; The result
|
||
parametersStackFrame
|
||
theDialog ds.l 1 ; the window pointer to check
|
||
newItem ds.w 1 ; the new Cancel item
|
||
endStackFrame
|
||
|
||
linkSave
|
||
move.l theDialog(a6),a0 ; get dialog ptr
|
||
clr.w result(A6) ; return noErr
|
||
bset #systemHandlesCancelButtonBit,dlgFlagsByte(a0) ; assume newItem is non-zero
|
||
move.w newItem(a6),dlgCancelButtonItem(a0) ; set current Cancel item in dialog
|
||
bne.s @done ; if non-zero then done
|
||
bclr #systemHandlesCancelButtonBit,dlgFlagsByte(a0) ; else remeber there is no default item
|
||
@done restoreunlinkreturn
|
||
|
||
ENDPROC
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; SetDialogTracksCursor
|
||
;
|
||
; FUNCTION SetDialogTracksCursor(theDialog: DialogPtr; tracks: Boolean): OSErr;
|
||
|
||
SetDialogTracksCursor PROC EXPORT
|
||
|
||
resultsStackFrame
|
||
result ds.w 1 ; The result
|
||
parametersStackFrame
|
||
theDialog ds.l 1 ; the window pointer to check
|
||
tracks ds.w 1 ; whether to turn tracking on or off
|
||
endStackFrame
|
||
|
||
linkSave
|
||
clr.w result(a6) ; return noErr
|
||
move.l theDialog(a6),a0 ; get dialog ptr
|
||
bset #systemTracksCursorBit,dlgFlagsByte(a0) ; assume track is true
|
||
tst.b tracks(a6) ; to track or not to track
|
||
bne.s @done ; if assumtion correct, we are done
|
||
bclr #systemTracksCursorBit,dlgFlagsByte(a0) ; oops, fix assumption
|
||
@done restoreunlinkreturn
|
||
|
||
ENDPROC
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
ClaimEvent ROMBIND (Plus, $14B48), (SE, $0F16A), (II, $13B98), (Portable, $12E6C), (IIci, $19C4E)
|
||
FrameOut ROMBIND (Plus, $15508), (SE, $0FB36), (II, $14882), (Portable, $13872), (IIci, $1A98E)
|
||
|
||
;-------------------------------------------------
|
||
;
|
||
; FUNCTION StdFilter(theDialog: DialogPtr; VAR theEvent: EventRecord;
|
||
; VAR itemHit: INTEGER): BOOLEAN;
|
||
;
|
||
; This function is used with ModalDialog. It does nothing, unless flags are set
|
||
; in the dialog record telling what it can do. It operates on both deactive
|
||
; and active windows - as long as they have the flags set. It handles the
|
||
; default button (draws halo, maps CR and ENTER, enables and disables), the
|
||
; cancel key (maps ESC, Cmd-Period, enables and disables), and adjusts the
|
||
; cursor (I-beam over TE items, otherwise an arrow).
|
||
;
|
||
; See also: SetDialogDefault, SetDialogCancelItem, and SetDialogFlags.
|
||
;
|
||
|
||
; Equates moved outside filter proc to make global to this file (?)
|
||
chPeriod EQU '.'
|
||
chCR EQU $0D
|
||
chEnter EQU $03
|
||
chESC EQU $1B
|
||
kcESC EQU $35 ; key code for ESC key
|
||
|
||
StdFilter PROC EXPORT
|
||
|
||
|
||
DialogInfo RECORD 0
|
||
itemNo DS.W 1
|
||
kind DS.W 1
|
||
handle DS.L 1
|
||
rect DS.W 4
|
||
ENDR
|
||
|
||
resultsStackFrame
|
||
result ds.w 1 ; The result
|
||
parametersStackFrame
|
||
theDialog ds.l 1 ; the window pointer to check cached in a4
|
||
theEvent ds.l 1 ; pointer to event record cached in a2
|
||
itemHit ds.l 1 ; pointer to item hit
|
||
localsStackFrame
|
||
defaultBtn ds DialogInfo
|
||
cancelBtn ds DialogInfo
|
||
anItem ds DialogInfo
|
||
cursorLocation ds.w 2
|
||
savedPort ds.l 1
|
||
theFlags ds.l 1
|
||
dlgBackColor ds.w 3
|
||
savedForeColor ds.w 3
|
||
dlgGrayColor ds.w 3
|
||
endStackFrame
|
||
|
||
; d4.w = event.message
|
||
; d6.b = dialog feature flags
|
||
|
||
|
||
|
||
kBOThickness EQU 3 ; Thickness of the bold outline
|
||
kBOOutset EQU 4 ; Outset for outline rect
|
||
kBOCorner EQU 16 ; Radius for outline frame
|
||
|
||
|
||
|
||
linkSave A2-A4/D3-D7 ; link and save the registers to be used
|
||
move.l theEvent(a6),a2
|
||
move.l evtMessage(a2),d4 ; cache event.message
|
||
|
||
; get dialog this event is about
|
||
jsrROM ClaimEvent ; gets dialog ptr into a4 base on event in a2, trashes d3
|
||
|
||
; set up default return values
|
||
moveq #0,d3 ; d3 will hold itemHit
|
||
move.b d3,result(a6) ; assume filter does nothing
|
||
|
||
; get feature flags
|
||
; Note: If this is an update or activate event, ClaimEvent may not
|
||
; have returned the front most window (i.e. our dialog). In fact,
|
||
; A4 may not point to a dialog at all. This is OK, though, since
|
||
; dlgFlagsByte will always be 0 in this case and StdFilterUpdateEvent and
|
||
; StdFilterActivateEvent won't do anything. Of course, if this is
|
||
; a deactivate event for a modal dialog behind us, the right thing
|
||
; will also happen.
|
||
move.b dlgFlagsByte(a4),d6
|
||
|
||
; case off of theEvent.what
|
||
move.w evtNum(a2),d0
|
||
beq @handleNullEvent
|
||
subq.w #3,d0
|
||
beq.s @handleKeyDown
|
||
subq.w #3,d0
|
||
beq @handleUpdateEvent
|
||
subq.w #2,d0
|
||
beq @handleActivateEvent
|
||
bra @done
|
||
|
||
@handleKeyDown
|
||
; does caller want me to map keys to default button?
|
||
btst #emulateOrigFilterBit,d6 ; Set if we should emulate old filter proc
|
||
bne.s @doKeyCheck
|
||
btst #systemHandlesDefaultButtonBit,d6
|
||
beq.s @chkCancelKey
|
||
@doKeyCheck
|
||
cmp.b #chCR,d4 ; is it the CR key
|
||
beq.s @doDefault
|
||
cmp.b #chEnter,d4 ; is it the Enter key
|
||
bne.s @chkCancelKey
|
||
@doDefault bsr GetDefaultBtnInfo
|
||
move.b defaultBtn.kind+1(a6),d0 ; only want to test high bit of low byte
|
||
bmi.s @doneKey ; if button is disabled, do nothing
|
||
;*** we may need to check for picbtns here someday
|
||
cmpi.b #ctrlItem+btnCtrl,d0 ; only "push" regular buttons
|
||
bne.s @doneKey
|
||
move.w defaultBtn.itemNo(a6),d3 ; default button item number
|
||
move.l defaultBtn.handle(a6),a0 ; default button handle
|
||
|
||
; return which item was hit and flash it
|
||
@hitButton push.l a0 ; for second HiliteControl (cause Hilite trashes a0)
|
||
push.w #0 ; for second HiliteControl, normalize button
|
||
push.l a0 ; control to set
|
||
push.w #1 ; invert button
|
||
_HiliteControl
|
||
move.w #8,a0
|
||
_Delay ; wait 8 ticks (_Delay takes input in a0)
|
||
_HiliteControl
|
||
bra.s @doneKey
|
||
|
||
@chkCancelKey
|
||
; does caller want me to map keys to cancel button?
|
||
btst #systemHandlesCancelButtonBit,d6
|
||
beq.s @doneKey
|
||
|
||
cmp.w #(kcESC*$100)+chESC,d4 ; do charCode and KeyCode both say ESC key was hit?
|
||
beq.s @doCancel ; if so then do cancel key
|
||
move.w evtMeta(a2),d0
|
||
btst #cmdKey,d0 ; is command key down?
|
||
beq.s @doneKey ; if not, then can't be command-period
|
||
|
||
subq #2,sp
|
||
push.l a2 ; keyEvent: EventRecord
|
||
push.w #chPeriod ; test: CHAR (actually has to be a word, with high byte = 0)
|
||
_IsCmdChar
|
||
tst.b (sp)+ ; is it command-period?
|
||
beq.s @doneKey ; if not, then done checking for cancel
|
||
|
||
@doCancel bsr GetCancelBtnInfo
|
||
tst.b cancelBtn.kind+1(a6) ; only want to test high bit of low byte
|
||
bmi.s @doneKey ; if cancel is disabled (?!?) then do nothing
|
||
move.l cancelBtn.handle(a6),a0 ; cancel button control handle
|
||
move.w cancelBtn.itemNo(a6),d3 ; return cancel button item number
|
||
bra.s @hitButton
|
||
|
||
@doneKey bra @done
|
||
|
||
|
||
@handleNullEvent
|
||
btst #systemHandlesDefaultButtonBit,d6
|
||
beq.s @checkCursor
|
||
|
||
; see if Hilite/Enabling is mismatched. if so, follow hilite to fix state
|
||
bsr GetDefaultBtnInfo
|
||
move.w defaultBtn.kind(a6),d2 ; really only use low byte
|
||
btst #7,d2 ; see if disabled
|
||
sne d1 ; if disabled d1=$FF, else d1=$00
|
||
; used to check here if item was a button, but now assume if flags bit is set it is a button
|
||
move.l defaultBtn.handle(a6),a0; get button's control handle
|
||
move.l (a0),a0
|
||
move.b contrlHilite(a0),d0 ; get button's hilite state
|
||
cmp.b d0,d1 ; compare button's hilite state to enable state
|
||
beq.s @checkCursor ; if it matches enable state, go on
|
||
|
||
; Hilite/Enabling is mismatched, set enable bit to match hilite state
|
||
bchg #7,d2 ; toggle disable bit
|
||
move.w d2,defaultBtn.kind(a6) ; remember new state
|
||
push.l a4 ; theDialog: DialogPtr
|
||
push.w defaultBtn.itemNo(a6) ; itemNo: INTEGER
|
||
push.w defaultBtn.kind(a6) ; itemType: INTEGER
|
||
push.l defaultBtn.handle(a6) ; item: Handle
|
||
pea defaultBtn.rect(a6) ; box: Rect;
|
||
_SetDItem
|
||
bra.s @handleUpdateEvent ; need to update the border around default button
|
||
|
||
@checkCursor btst #systemTracksCursorBit,d6
|
||
beq.s @doneIdle
|
||
|
||
; if cursor is over a TE field, then turn cursor to an I-beam, else the arrow
|
||
|
||
; Note: the current port may not be our dialog, we need to set it before <19>
|
||
; calling GetMouse since it returns the mouse in local coordinates. <19>
|
||
|
||
pea savedPort(a6) ; <19>
|
||
_GetPort ; <19>
|
||
push.l a4 ; switch current port to get right coordinates <19>
|
||
_SetPort ; <19>
|
||
pea cursorLocation(a6)
|
||
_GetMouse ; get currect mouse position in local coordinates
|
||
push.l savedPort(a6) ; <19>
|
||
_SetPort ; restore port <19>
|
||
subq #2,sp
|
||
push.l a4 ; this is assumed to be the front window, because of how ClaimEvent works
|
||
push.l cursorLocation(a6)
|
||
_FindDItem
|
||
pop.w d0
|
||
bmi.s @useArrow ; returning -1 => mouse not over any item
|
||
addq.w #1,d0
|
||
lea anItem(a6),a0
|
||
bsr GetDialogInfo ; get all kinds of info about the item we are over
|
||
move.w anItem.kind(a6),d0 ; really only use low byte
|
||
and.w #editText,d0 ; is mouse over an edit text item?
|
||
beq.s @useArrow ; if not change to arrow
|
||
|
||
; change cursor to the I-beam
|
||
@useIBeam subq #4,sp
|
||
push.w #iBeamCursor
|
||
_GetCursor ; get I-Beam cursor resource
|
||
pop.l a0
|
||
push.l (a0) ; dereference cursor handle
|
||
_SetCursor ; set I-Beam
|
||
bra.s @doneIdle
|
||
|
||
@useArrow _InitCursor ; Set the arrow cursor
|
||
@doneIdle bra @done
|
||
|
||
|
||
@handleUpdateEvent
|
||
; does caller want me to draw a ring around the default button?
|
||
btst #systemHandlesDefaultButtonBit,d6
|
||
beq @doneUpdate
|
||
|
||
pea savedPort(a6)
|
||
_GetPort
|
||
push.l a4 ; switch current port to draw in right window
|
||
_SetPort
|
||
_PenNormal
|
||
|
||
bsr GetDefaultBtnInfo
|
||
moveq #0,d5 ; d5 is flag of whether using truegray
|
||
tst.b defaultBtn.kind+1(a6) ; is default button enabled?
|
||
bpl.s @patSet ; if so,l just draw
|
||
|
||
cmp.w #$3FFF,ROM85 ; if (not on a color system)
|
||
bhi.s @bwGrafPort ; or
|
||
move.w portVersion(a4),d0 ;
|
||
and.w #$C000,d0 ; (not a color grafport)
|
||
bne.s @colorGrafport ;
|
||
@bwGrafPort move.l GrafGlobals(A5),A0 ; get Grafglobals
|
||
pea gray(A0) ; Get gray address
|
||
_PenPat ; Set the pen pattern to gray
|
||
bra.s @patSet ;
|
||
|
||
@colorGrafport pea dlgBackColor(a6)
|
||
_GetBackColor ; get back color, for GetGray()
|
||
pea savedForeColor(a6)
|
||
_GetForeColor ; remember fore color, for restoring
|
||
pea dlgGrayColor(a6)
|
||
_GetForeColor ; get fore color, for GetGray()
|
||
|
||
subq #2,sp ; room for GetGray result
|
||
subq #4,sp ; room for device handle ### this should be window's device
|
||
_GetMainDevice
|
||
pea dlgBackColor(a6) ; in: backColor
|
||
pea dlgGrayColor(a6) ; in: foreColor, out: grayColor (mix of fore and back)
|
||
_GetGray
|
||
pop.b d5 ; returns true if made gray
|
||
beq.s @bwGrafPort ; if true gray failed, fall back to pattern gray
|
||
pea dlgGrayColor(a6)
|
||
_RGBForeColor ; set foreground to draw in gray
|
||
|
||
@patSet moveq #kBOThickness,d0 ; pen size
|
||
moveq #kBOCorner,d1 ; roundness factor ### this should be calculated?
|
||
moveq #kBOOutset,d2 ; outset value
|
||
lea defaultBtn.rect(a6),a0 ; pointer to rect
|
||
jsrROM FrameOut ; do halo frame
|
||
|
||
tst.l d5
|
||
beq.s @doneDraw
|
||
pea savedForeColor(a6)
|
||
_RGBForeColor ; restore foreground color
|
||
|
||
@doneDraw _PenNormal
|
||
push.l savedPort(a6)
|
||
_SetPort
|
||
|
||
@doneUpdate
|
||
; If this is an update event for another window, it will never get cleared until the modal dialog <19>
|
||
; is dismissed. So, we'll never see a null event, which means we need to track the cursor here as <19>
|
||
; well as for null events. Also, A4 points to the window the update event is for, so we need to <19>
|
||
; call FrontWindow to get the dialog we're really interested in. <19>
|
||
subq #4,sp ; room for frontmost window <19>
|
||
_FrontWindow ; <19>
|
||
pop.l a4 ; get frontmost window into a4 <19>
|
||
move.b dlgFlagsByte(a4),d6 ; and get the flags into d6 <19>
|
||
bra.s @checkCursor ; track cursor in case this update event is always <19>
|
||
; pending and we never get a null event <19>
|
||
|
||
|
||
|
||
@handleActivateEvent
|
||
moveq #0,d5 ; d5 will hold hilite state for button
|
||
btst #activeFlag,evtMeta+1(a2) ; is this an activate or deactive event
|
||
seq d5 ; want d5 to be 0(if activating) or 255(if deactivating)
|
||
|
||
; does caller want me to take care of cancel button?
|
||
btst #systemHandlesCancelButtonBit,d6
|
||
beq.s @chkDefaultAct
|
||
|
||
bsr.s GetCancelBtnInfo
|
||
push.l cancelBtn.handle(a6); cancel button handle
|
||
push.w d5 ; force button dim or noraml
|
||
_HiliteControl
|
||
|
||
@chkDefaultAct
|
||
; does caller want me to take care of ring around the default button?
|
||
btst #systemHandlesDefaultButtonBit,d6
|
||
beq.s @doneActivate
|
||
|
||
bsr.s GetDefaultBtnInfo
|
||
push.l defaultBtn.handle(a6); default button handle
|
||
push.w d5 ; force button dim or noraml
|
||
_HiliteControl
|
||
bra @handleNullEvent ; now reset item disable and redraw ring
|
||
@doneActivate
|
||
|
||
|
||
@done tst.w d3 ; see if we mapped event to an item
|
||
beq.s @return
|
||
move.l itemHit(a6),a0 ; if so, set VAR itemHit: INTEGER
|
||
move.w d3,(a0)
|
||
addq.b #1,result(a6) ; change default of false, to true
|
||
@return restoreunlinkreturn
|
||
|
||
|
||
|
||
; get info about what the default button
|
||
GetDefaultBtnInfo
|
||
move.w dlgDefaultButtonItem(a4),d0; get default button according to dialog record
|
||
lea defaultBtn(a6),a0
|
||
bra.s GetDialogInfo ; get all kinds of info about default button
|
||
|
||
|
||
; get info about what the cancel button;
|
||
GetCancelBtnInfo
|
||
move.w dlgCancelButtonItem(a4),d0 ; get which button is cancel from caller
|
||
lea cancelBtn(a6),a0
|
||
;bra.s GetDialogInfo ; get all kinds of info about cancel button
|
||
|
||
|
||
;
|
||
; in: a4 = dialog ptr
|
||
; a0 = DialogInfoPtr
|
||
; d0 = itemNo
|
||
GetDialogInfo move.w d0,DialogInfo.itemNo(a0)
|
||
push.l a4 ; theDialog: DialogPtr
|
||
push.w d0 ; itemNo: INTEGER
|
||
pea DialogInfo.kind(a0) ; VAR itemType: INTEGER
|
||
pea DialogInfo.handle(a0) ; VAR item: Handle
|
||
pea DialogInfo.rect(a0) ; VAR box: Rect;
|
||
_GetDItem
|
||
rts
|
||
|
||
|
||
ENDPROC
|
||
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; GetDialogDefaultItem
|
||
;
|
||
; FUNCTION GetDialogDefaultItem(theDialog: DialogPtr; VAR curItem: INTEGER): OSErr;
|
||
|
||
GetDialogDefaultItem PROC EXPORT
|
||
|
||
resultsStackFrame
|
||
result ds.w 1 ; The result
|
||
parametersStackFrame
|
||
theDialog ds.l 1 ; the window pointer to check
|
||
curItem ds.l 1 ; the place to put current default item
|
||
endStackFrame
|
||
|
||
linkSave
|
||
move.l theDialog(a6),a0 ; get dialog ptr
|
||
move.l curItem(a6),a1 ; get place to return default item
|
||
clr.w result(A6) ; return noErr
|
||
clr.w (a1) ; assume default not handled
|
||
btst #systemHandlesDefaultButtonBit,dlgFlagsByte(a0) ; does system handle default?
|
||
beq.s @done ; if not return with curItem = 0
|
||
move.w dlgDefaultButtonItem(a0),(a1) ; return current default item from dialog
|
||
@done restoreunlinkreturn
|
||
|
||
ENDPROC
|
||
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; GetDialogCancelItem
|
||
;
|
||
; FUNCTION GetDialogCancelItem(theDialog: DialogPtr; VAR curItem: INTEGER): OSErr;
|
||
|
||
GetDialogCancelItem PROC EXPORT
|
||
|
||
resultsStackFrame
|
||
result ds.w 1 ; The result
|
||
parametersStackFrame
|
||
theDialog ds.l 1 ; the window pointer to check
|
||
curItem ds.l 1 ; the place to put current Cancel item
|
||
endStackFrame
|
||
|
||
linkSave
|
||
move.l theDialog(a6),a0 ; get dialog ptr
|
||
move.l curItem(a6),a1 ; get place to return Cancel item
|
||
clr.w result(A6) ; return noErr
|
||
clr.w (a1) ; assume Cancel not handled
|
||
btst #systemHandlesCancelButtonBit,dlgFlagsByte(a0) ; does system handle Cancel?
|
||
beq.s @done ; if not return with curItem = 0
|
||
move.w dlgCancelButtonItem(a0),(a1) ; return current Cancel item from dialog
|
||
@done restoreunlinkreturn
|
||
|
||
ENDPROC
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; GetDialogFlags
|
||
;
|
||
; FUNCTION GetDialogFlags(theDialog: DialogPtr; VAR curFlags: LONGINT): OSErr;
|
||
|
||
GetDialogFlags PROC EXPORT
|
||
|
||
resultsStackFrame
|
||
result ds.w 1 ; The result
|
||
parametersStackFrame
|
||
theDialog ds.l 1 ; the window pointer to check
|
||
curFlags ds.l 1 ; the place to put flags
|
||
endStackFrame
|
||
|
||
linkSave
|
||
move.l theDialog(a6),a0 ; get dialog ptr
|
||
move.l curFlags(a6),a1 ; get place to return flags
|
||
moveq #0,D0
|
||
move.w D0,result(A6) ; return noErr
|
||
move.b dlgFlagsByte(a0),d0 ; get byte of flags into zeroed long
|
||
move.l d0,(a1) ; return long flags
|
||
restoreunlinkreturn
|
||
|
||
ENDPROC
|
||
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; SetDialogFlags
|
||
;
|
||
; FUNCTION SetDialogFlags(theDialog: DialogPtr; newFlags: LONGINT): OSErr;
|
||
|
||
SetDialogFlags PROC EXPORT
|
||
|
||
resultsStackFrame
|
||
result ds.w 1 ; The result
|
||
parametersStackFrame
|
||
theDialog ds.l 1 ; the window pointer to check
|
||
newFlags ds.l 1 ; the new flags to use
|
||
endStackFrame
|
||
|
||
linkSave
|
||
move.l theDialog(a6),a0 ; get dialog ptr
|
||
clr.w result(A6) ; return noErr
|
||
move.l newFlags(a6),d0 ; get new flags
|
||
move.b d0,dlgFlagsByte(a0) ; set byte of flags into dialog record
|
||
restoreunlinkreturn
|
||
|
||
ENDPROC
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; IsUserCancelEvent
|
||
;
|
||
; FUNCTION IsUserCancelEvent(event: EventRecord): Boolean;
|
||
|
||
IsUserCancelEvent PROC EXPORT
|
||
|
||
resultsStackFrame
|
||
result ds.w 1 ; the result
|
||
parametersStackFrame
|
||
event ds.l 1 ; the event record to check
|
||
endStackFrame
|
||
|
||
linkSave
|
||
|
||
clr.w result(a6) ; assume we will return false
|
||
|
||
move.l event(a6),a0 ; get pointer to event record
|
||
|
||
cmp.w #keyDwnEvt,evtNum(a0) ; only key down events are cancel events
|
||
bne.s ReturnFalse
|
||
|
||
move.l evtMessage(a0),d0
|
||
cmp.w #(kcESC*$100)+chESC,d0 ; do charCode and keyCode say ESC key was hit?
|
||
beq.s ReturnTrue ; if so then this is a cancel key
|
||
move.w evtMeta(a0),d0
|
||
btst #cmdKey,d0 ; is command key down?
|
||
beq.s ReturnFalse ; if not, then can’t be command period and can’t be cancel
|
||
|
||
subq #2,sp
|
||
push.l a0 ; keyEvent: EventRecord
|
||
push.w #chPeriod ; test: CHAR (actually has to be a word, with high byte = 0)
|
||
_IsCmdChar
|
||
tst.b (sp)+ ; is it command period?
|
||
beq.s ReturnFalse ; if not, then done checking for cancel
|
||
ReturnTrue
|
||
move.b #1,result(a6) ; set result (boolean in high byte)
|
||
ReturnFalse
|
||
restoreUnlinkReturn
|
||
|
||
ENDPROC
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; GetNextUserCancelEvent
|
||
;
|
||
; FUNCTION GetNextUserCancelEvent(VAR event: EventRecord): Boolean;
|
||
|
||
userEventsMask equ (1<<mButDwnEvt)|(1<<mButUpEvt)|(1<<keyDwnEvt)|(1<<keyUpEvt)|(1<<autoKeyEvt)
|
||
|
||
GetNextUserCancelEvent PROC EXPORT
|
||
|
||
resultsStackFrame
|
||
result ds.w 1 ; the result
|
||
parametersStackFrame
|
||
event ds.l 1 ; place to return the result event record
|
||
localsStackFrame
|
||
localEvent ds.b evtBlkSize ; local event record to use if none is passed
|
||
endStackFrame
|
||
|
||
linkSave a2
|
||
|
||
clr.w result(a6) ; clear both bytes
|
||
|
||
move.w sr,-(sp) ; save interrupt state
|
||
or.w #$0700,sr ; no interrupts while we mess with the queue
|
||
|
||
lea EventQueue,a2 ; get address of event queue
|
||
|
||
move.l qHead(a2),d0 ; get address of 1st element
|
||
beq.s Done ; there is no Cancel event
|
||
@loop
|
||
move.l d0,a2 ; get pointer to event
|
||
lea evtQWhat(a2),a0 ; point at event part of the event queue
|
||
bsr.s EventIsUserCanceled ; is it a user canceled event?
|
||
bne.s GotUserCanceled ; we got one!
|
||
move.l qLink(a2),d0 ; follow the link to the next one
|
||
bne.s @loop ; if we got one, check it out
|
||
Done
|
||
move.w (sp)+,sr ; restore interrupt state
|
||
|
||
restoreUnlinkReturn
|
||
|
||
GotUserCanceled
|
||
|
||
@loop
|
||
move.l event(a6),a0 ; get parameter (pointer to place to put result event)
|
||
move.l a0,d0 ; test it for nil
|
||
bnz.s @gotEventRecord
|
||
lea localEvent(a6),a0 ; get local place to use for event instead
|
||
@gotEventRecord
|
||
moveq.l #userEventsMask,d0 ; tell it which events to get
|
||
_GetOSEvent
|
||
tst.b d0
|
||
bne.s Done ; no event, so the world doesn’t make sense, get out though
|
||
bsr.s EventIsUserCanceled ; is it the user canceled event we found earlier?
|
||
beq.s @loop ; no, continue looping and trying to get it
|
||
|
||
move.b #1,result(a6) ; function result is true since we found an event
|
||
bra.s Done
|
||
|
||
EventIsUserCanceled
|
||
subq #2,sp ; make room for result
|
||
move.l a0,-(sp) ; call to see if it is user canceled
|
||
jsr IsUserCancelEvent ; is it?
|
||
tst.b (sp)+ ; check the result
|
||
rts
|
||
|
||
ENDPROC
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
END
|