supermario/base/SuperMarioProj.1994-02-09/Toolbox/DialogMgr/DialogDispatch.a
2019-06-29 23:17:50 +08:00

953 lines
36 KiB
Plaintext
Raw 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: 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? Lets 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 cant be command period and cant 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 doesnt 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