; ; 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): ; ; 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. ; 8/28/92 CSS Update from Reality: ; <18> 8/25/92 DTY Save D3 in StdFilter to make Tom happy. ; 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,: 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 call it DialogDispatch instead of DialogMgrDispatch ; <11> 12/3/90 RLC Get rid of IsÅWindowModal routines and replace them with a ; GetModalClass and GetFrontModalClass routines. ; <10> 11/13/90 KSM Make 32-bit clean... ; <9> 10/29/90 KSM Use emulateOrigFilterBit to emulate ROM filter proc, but with ; bug fix. ; <8> 10/29/90 ngk add ROM bind for portable ; <7> 10/29/90 ngk 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 ! 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<