supermario/base/SuperMarioProj.1994-02-09/Toolbox/DialogMgr/DialogDispatch.a

953 lines
36 KiB
Plaintext
Raw Normal View History

2019-06-29 15:17:50 +00:00
;
; 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