mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 16:31:01 +00:00
1758 lines
65 KiB
Plaintext
1758 lines
65 KiB
Plaintext
;
|
|
; File: ControlMgr.a
|
|
;
|
|
; Contains: Control Manager for Macintosh User Interface ToolBox
|
|
;
|
|
; Written by: Andy Hertzfeld August 4, 1982
|
|
;
|
|
; Copyright: © 1982-1993 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM20> 6/17/93 KW (LW9 fau) Clear the emControlHandle pointer after executing
|
|
; DragTheRgn, so it doesn't stick around. (LW8 fau) When setting
|
|
; DragFlag, only a byte was being set, and it is a word lowmem.
|
|
; <SM19> 6/14/93 kc Roll in Ludwig.
|
|
; <LW6> 5/3/93 chp Flush the caches for CDEF handles smaller than 32 bytes. It used
|
|
; to be 16 bytes, but a 22-byte, unflushed, fake defproc has been
|
|
; discovered in Software Ventures Microphone II and Microphone
|
|
; Pro. (RADAR #1082386)
|
|
; <LW3> 3/8/93 fau Modified the previous fix to do a flush if the handle is less or
|
|
; equal to 16 bytes. See the comment for more description.
|
|
; <LW2> 1/15/93 fau In the routine CallControl, added a cache flush if the Control
|
|
; Def Proc routine code is not in ROM. Some third party apps (bug
|
|
; #1059553 and #1060508) pass a CDEF Proc Handle to a jump table
|
|
; that relied on Hlock performing a cache flush. We test for a
|
|
; ROM address so as not to impact performance when the CDEF proc
|
|
; is ID 0 or 1, which are fairly commone ones!.
|
|
; <SM18> 6/7/93 CSS In DragControl, stash the control handle in expandmem so when we
|
|
; call DragTheRgn we will have it to call back to the control if
|
|
; we need to (i.e. only if it is a thumb).
|
|
; <SM17> 4/30/93 CSS We are using DragFlag in DragTheRgn to know if we should use
|
|
; special means to drag the control for the thumb. We need to
|
|
; clear it once we are done with it.
|
|
; <SM16> 4/21/93 CSS _TrackControl calls dragcontrol to implement the dragging of a
|
|
; thumb. If there is a custom drag message in the CDEF,
|
|
; dragcontrol returns to trackcontrol saying that the thumb didn't
|
|
; move and the application isn't notified to update the content
|
|
; affected by the control. Fix _TrackControl, if dragcontrol says
|
|
; no movement occured, to also check if the value of the control
|
|
; changed. If the value of the control changed then return to the
|
|
; app without clearing the part number (and therefore the app will
|
|
; update the content correctly).
|
|
; <SM15> 1/29/93 RB <LW2> 1/15/93 fau In the routine CallControl, added a cache
|
|
; flush if the Control Def Proc routine code is not in ROM. Some
|
|
; third party apps (bug #1059553 and #1060508) pass a CDEF Proc
|
|
; Handle to a jump table that relied on Hlock performing a cache
|
|
; flush. We test for a ROM address so as not to impact performance
|
|
; when the CDEF proc is ID 0 or 1, which are fairly commone ones!.
|
|
; <SM14> 7/23/92 fau Fixed a bug in TrackControl when using a custom tracking
|
|
; procedure: The ThrottleScrollingSpeed patch was blowing away
|
|
; D0, where the procedure's address was stored and the call to the
|
|
; procedure was using the globals value (which is -1 for a custom
|
|
; tracking procedure). I now save D0 before the patch and then
|
|
; restore it afterwards.
|
|
; <SM13> 7/15/92 RB Fixed a bug in DisposeControl where the control handle needed to
|
|
; be tested specifically, instead of counting on the status
|
|
; register being setup by a move to an address register.
|
|
; <3> 7/1/92 JSM Merge changes from SuperMario: roll-in FixNewControl32Bit,
|
|
; PatchDisposeControlForCorrectLayer,
|
|
; PatchDisposeControlForInvisibleControlsIIci,
|
|
; CheckMemErrInSetCTitle, and ThrottleScrollingSpeed from
|
|
; ControlMgrPatches.a.
|
|
; <2> 9/30/91 JSM Add a header, donÕt use hasCQD conditional - all future ROMs
|
|
; will have color QuickDraw, donÕt use is32BitClean conditional -
|
|
; all future ROMs will be.
|
|
; <1.3> 10/31/89 dba concatenated source files ControlMgr1.a and ControlMgr2.a to
|
|
; this one
|
|
;
|
|
; Note: This file used to be split into three pieces. Here are the modification histories for each:
|
|
;
|
|
;----------------------------------------------------------------------------------------------------
|
|
; Modification History for ControlMgr.a
|
|
;----------------------------------------------------------------------------------------------------
|
|
;
|
|
; 1.3 dba 10/31/1989 concatenated source files ControlMgr1.a and ControlMgr2.a to this one
|
|
; 1.2 SES 08/22/1989 Removed references to nFiles.
|
|
; 1.1 CCH 11/10/1988 Fixed Header.
|
|
; 1.0 CCH 11/ 9/1988 Adding to EASE.
|
|
;¥1.1 CCH 9/23/1988 Got rid of inc.sum.d and empty nFiles
|
|
; 1.0 BBM 2/11/88 Adding file for the first time into EASEÉ
|
|
;
|
|
; 01-Sep-82 AJH Added "PlotSymbol" entry point
|
|
; 20-Sep-82 AJH got rid of DragThumb
|
|
; 29-Sep-82 AJH Added CheckBoxProc
|
|
; 26-Sep-82 AJH Added KillControls
|
|
; 10-Oct-82 AJH Converted for QuickDraw Trap Interface
|
|
; 01-Nov-82 AJH changed FindWindow to FindControl
|
|
; 28-Dec-82 AJH made defProcs resources
|
|
;
|
|
;-----------------------------------------------------------------------
|
|
; 23 Jan 83 LAK Adapted for new equate files.
|
|
; 27-Apr-85 EHB only CallDControl if the control is in portRect
|
|
; don't test for visible in DrawControls, done in CallDControl
|
|
; Added UpdateControls(w:windowPtr;u:RgnHandle), which only updates
|
|
; the controls in the update region.
|
|
; 9-Jul-85 EHB Added setup of ROMMapInsert for ROM resources
|
|
; 15-Jul-85 EHB No longer rely on D0,D1 being preserved in calls to SetPort/GetPort (in ownerPort)
|
|
; 15-Oct-85 EHB Added routine DrawOneControl which somehow fell through the cracks earlier
|
|
;_______________________________________________________________________
|
|
;
|
|
; Post Lonely Hearts
|
|
;_______________________________________________________________________
|
|
;
|
|
; <19feb86> BBM Made some modifications to work under MPW
|
|
; <C59/30Jun86> DAF added two new color calls to control manager
|
|
; For code sharing, these routines are in the
|
|
; window manager (WindowMgr3.a).
|
|
;<C491/08Dec86> DAF added GetCVariant.
|
|
;<C949/08Nov87> DAF Fixed CallControl to SystemError if CDEF not loaded by LoadResource. This
|
|
; is because Juggler can gracefully terminate the app without killing all.
|
|
;
|
|
;----------------------------------------------------------------------------------------------------
|
|
; Modification History for ControlMgr1.a
|
|
;----------------------------------------------------------------------------------------------------
|
|
;
|
|
; 1.6 SES 08/22/1989 Removed references to nFiles. Updated equates accordingly.
|
|
; 1.5 DAF 07/13/1989 FOR AURORA BUILD - fixed 32-bit register trashing
|
|
; problem in DisposControl.
|
|
; 1.4 DAF 06/14/1989 Corrected auxCtlRec disposal in 32-bit addressing mode
|
|
; (DisposControl)
|
|
; 1.3 EMT 02/22/1989 Uses is32BitClean conditional; only uses new message in 32 bit mode.
|
|
; 1.2 EMT 02/09/1989 dded new messages for 32-bit clean Control Manager.
|
|
; 1.1 CCH 11/10/1988 Fixed Header.
|
|
; 1.0 CCH 11/ 9/1988 Adding to EASE.
|
|
; 1.1 GGD 11/ 2/1988 Got rid of machine specific conditionals in favor of
|
|
; feature based conditionals.
|
|
; 1.0 BBM 2/11/88 Adding file for the first time into EASEÉ
|
|
;
|
|
; 22-Aug-82 AJH Added DragControl
|
|
; 29-Aug-82 AJH Added hilite parameter to draw message
|
|
; 29-Aug-82 AJH Implemented hilite state "-1"
|
|
; 30-Aug-82 AJH Fixed SetCtlValue to use max and min when value is
|
|
; out of bounds
|
|
; 31-Aug-82 AJH Added slopRect parameter to dragging
|
|
; 09-Sep-82 AJH Fixed register trashing bug in NewControl
|
|
; 20-Sep-82 AJH Made TrackControl handle indicators
|
|
; 22-Sep-82 AJH Integrated list routines
|
|
; 25-Sep-82 AJH Made NewControl ensure high byte of controlHandle is zero
|
|
; 26-Sep-82 AJH Added KillControls, made drawControls preserve penState
|
|
; 27-Sep-82 AJH Fixed bug in DeleteList
|
|
; 05-Oct-82 AJH Added some code-saving optimizations; added actionProc field
|
|
; 10-Oct-82 AJH Converted for QuickDraw Trap Interface
|
|
; 18-OCt-82 AJH Fixed bug in SetCtlMax/Min
|
|
; 14-Nov-82 AJH Made unHiliting use part codes to avoid flashing
|
|
; 30-Nov-82 AJH Made TrackControl pass controlHandle to actionProc
|
|
; 21-Dec-82 AJH Fixed TrackControl result when tracking indicator
|
|
; 21-Dec-82 AJH Fixed failure to dispose old string in SetCTitle bug
|
|
; 28-Dec-82 AJH made defProcs resources; string at end instead of handle
|
|
; 24-Jan-83 AJH made CallDControl do nothing if the control is invisible
|
|
; 24-Jan-83 AJH made SetCtlMin/Max do range checking
|
|
; 31-Jan-83 AJH clear high byte in CallControl before calling LoadResource
|
|
; 05-Feb-83 AJH made TrackControl for indicator use actionProc
|
|
; 13-Feb-83 AJH made SetCtlValue not draw when pinned against min or max
|
|
; 09-Mar-83 AJH cleaned up custom drag interface
|
|
; 16-Mar-83 AJH fixed contrlAction bug in TrackControl with indicators
|
|
; 03-Apr-83 AJH made NewControl use defProc 0 when it cant find requested one
|
|
; 08-Jun-83 AJH changed a bunch of internal BSRs to traps
|
|
; 15-Aug-83 AJH monster code krunch after code review (Capps, Jerome)
|
|
; 29-Aug-83 AJH/SC if local actionProc odd, send a track message
|
|
; 09-Sep-83 AJH hilite before calling actionProc in TrackControl
|
|
;
|
|
;----------------------------------------------------------
|
|
;
|
|
; 27-Apr-85 EHB only CallDControl if the control is in portRect
|
|
; don't test for visible in DrawControls, done in CallDControl
|
|
; Added UpdateControls(w:windowPtr;u:RgnHandle), which only updates
|
|
; the controls in the update region.
|
|
; 9-Jul-85 EHB Added setup of ROMMapInsert for ROM resources
|
|
; 15-Jul-85 EHB No longer rely on D0,D1 being preserved in calls to SetPort/GetPort (in ownerPort)
|
|
; 15-Oct-85 EHB Added routine DrawOneControl which somehow fell through the cracks earlier
|
|
;
|
|
;----------------------------- Lonely Heifer ROMs -------------------------------------
|
|
;
|
|
; 16-Jan-86 EHB Removed SectRect in CallDControl because it broke MacExpress
|
|
;<C407/16Nov86> DAF Made DisposeControl dispose of auxCtlRec and colortable.
|
|
;<C424/18Nov86> DAF Made some 32/24-bit corrections in callControl.
|
|
;<C491/08Dec86> DAF Added GetCVariant. Changed callControl to use this new call
|
|
;<C575/30Dec86> DAF saved D1 across NewControl for Insight G/L 's Notes DA.
|
|
; It expects the hi half of D1 to be unchanged.
|
|
;<C678/23Jan87> DAF Set contrlVis FALSE in EraseControl to fix MSWord's ruler. Moved this
|
|
; code from HideControl (which uses EraseControl).
|
|
;<C777/09Feb87> DAF Fixed 32-bit stuff to look at MMU32Bit rather than MMUFlags (to be
|
|
; consistant with wmgr.
|
|
;<C914/29Oct87> rwh Port to Modern Victorian
|
|
;<C949/08Nov87> DAF Fixed CallControl to SystemError if CDEF not loaded by LoadResource. This
|
|
; is because Juggler can gracefully terminate the app without killing all.
|
|
;
|
|
;----------------------------------------------------------------------------------------------------
|
|
; Modification History for ControlMgr2.a
|
|
;----------------------------------------------------------------------------------------------------
|
|
;
|
|
; 1.1 CCH 11/10/1988 Fixed Header.
|
|
; 1.0 CCH 11/ 9/1988 Adding to EASE.
|
|
; 1.0 BBM 2/11/88 Adding file for the first time into EASEÉ
|
|
;
|
|
; 20-Sep-82 AJH Fixed "thePort" trash bug in FindWindow
|
|
; 28-Sep-82 AJH Made FindWindow use CallWindow to save code
|
|
; 10-Oct-82 AJH Converted for QuickDraw Trap Interface
|
|
; 01-Nov-82 AJH Removed FindWindow, added FindControl
|
|
; 28-Dec-82 AJH Removed control defProcs from control manager
|
|
; 11-Feb-83 AJH Made FindControl return last one for overlapping controls
|
|
; 07-Mar-83 AJH Fixed bug in FindControl with 255-hiliting
|
|
;
|
|
|
|
LOAD 'StandardEqu.d'
|
|
INCLUDE 'ControlPriv.a' ; <3>
|
|
INCLUDE 'LayerEqu.a' ; <3>
|
|
INCLUDE 'SysEqu.a' ; <LW2> fau
|
|
|
|
MACHINE MC68020 ; needed for cache flush <LW2> fau
|
|
|
|
CMGR PROC EXPORT
|
|
|
|
; Macintosh Control Manager External Definitions
|
|
|
|
EXPORT NewControl
|
|
EXPORT DisposeControl
|
|
EXPORT KillControls
|
|
|
|
EXPORT MoveControl
|
|
EXPORT SizeControl
|
|
EXPORT DragControl
|
|
EXPORT ShowControl
|
|
EXPORT HideControl
|
|
|
|
EXPORT SetCTitle
|
|
EXPORT GetCTitle
|
|
EXPORT HiliteControl
|
|
EXPORT SetCRefCon
|
|
EXPORT GetCRefCon
|
|
|
|
EXPORT GetCtlValue
|
|
EXPORT GetCtlMin
|
|
EXPORT GetCtlMax
|
|
EXPORT SetCtlValue
|
|
EXPORT SetCtlMin
|
|
EXPORT SetCtlMax
|
|
|
|
EXPORT GetCtlAction
|
|
EXPORT SetCtlAction
|
|
|
|
EXPORT TestControl
|
|
EXPORT TrackControl
|
|
|
|
EXPORT FindControl
|
|
EXPORT DrawControls
|
|
EXPORT UpdtControls
|
|
EXPORT DrawOneControl
|
|
|
|
EXPORT GetCVariant ; <C491/08Dec86> DAF
|
|
|
|
EXPORT cmgrend
|
|
|
|
;
|
|
; External Routines used by Control Manager
|
|
;
|
|
IMPORT GetNewRgn
|
|
IMPORT FlushCRange
|
|
|
|
;
|
|
; FUNCTION NewControl( window: windowPtr;
|
|
; boundsRect: Rect;
|
|
; Title: String255;
|
|
; VisFlag: Boolean;
|
|
; Value: INTEGER;
|
|
; minValue: INTEGER;
|
|
; maxValue: INTEGER;
|
|
; ctlProcID INTEGER;
|
|
; refCon: LongInt): ControlHandle;
|
|
;
|
|
; NewControl allocates and initializes a new control data structure. The ctlProc
|
|
; parameter determines the type of control (button, scrollBar, etc.)
|
|
;
|
|
; Parameter definition equates
|
|
;
|
|
|
|
NCRefCon EQU 8
|
|
NCCDefID EQU 12
|
|
NCMaxValue EQU 14
|
|
NCMinValue EQU 16
|
|
NCValue EQU 18
|
|
NCVisFlag EQU 20
|
|
NCTitle EQU 22
|
|
NCBoundsRect EQU 26
|
|
NCWindow EQU 30
|
|
NCFResult EQU 34
|
|
;
|
|
NewControl
|
|
LINK A6,#0 ;make a stack frame
|
|
MOVEM.L D1/A2-A4,-(SP) ;save work registers <C575/30Dec86> DAF
|
|
LEA NCFResult(A6),A4 ;use A4 to get at parameters
|
|
;
|
|
; allocate memory for the control data structure
|
|
;
|
|
MOVEQ #ContrlSize+1,D0 ;get size of control data structure
|
|
MOVEQ #0,D1 ;clear out high part
|
|
MOVE.L NCTitle(A6),A0 ;get pointer to title string
|
|
MOVE.B (A0),D1 ;get length of title
|
|
ADD.L D1,D0 ;compute length of control block
|
|
_NEWHANDLE ;allocate some memory
|
|
;
|
|
MOVE.L A0,A3 ;keep control handle in A3
|
|
MOVE.L A0,(A4) ;also, its the function result
|
|
MOVE.L (A3),A2 ;handle -> pointer
|
|
|
|
SF.B contrlVis(A2) ; set this temporarily, so SetCtlColor won't try to draw <C612/12Jan87> DAF
|
|
MOVE.L A3,-(SP) ; push controlHandle <C612/12Jan87> DAF
|
|
MOVE.L #-1,-(SP) ; push -1 to make a new rec with default CTab <C612/12Jan87> DAF
|
|
|
|
; begin roll-in FixNewControl32Bit patch <3>
|
|
|
|
move.l 30(a6),contrlOwner(a2) ; copy the owner into the field <3>
|
|
_SetCtlColor ; make one <C612/12Jan87> DAF
|
|
move.l (a3),a2 ; re-dereference the control handle <3>
|
|
|
|
; end roll-in FixNewControl32Bit patch <3>
|
|
|
|
@1
|
|
;
|
|
; insert it into the controlList of the owning window
|
|
;
|
|
MOVE.L -(A4),A1 ;get owning window pointer
|
|
MOVE.L A1,ContrlOwner(A2) ;initialize owner field
|
|
MOVE.L WControlList(A1),NextControl(A2) ;link old 1st one
|
|
MOVE.L A3,WControlList(A1) ;make new one first
|
|
;
|
|
; initialize the bounding rectangle
|
|
;
|
|
LEA ContrlRect(A2),A1 ;get destination
|
|
MOVE.L -(A4),A0 ;get ptr to bounding rectangle
|
|
MOVE.L (A0)+,(A1)+ ;move in the topLeft
|
|
MOVE.L (A0),(A1) ;move in the bottomRight
|
|
;
|
|
; initialize the control title. Use the standard SetCTitle call to save code.
|
|
;
|
|
CLR.B ContrlVis(A2) ;pretend its hidden
|
|
MOVE.L A3,-(SP) ;push control handle
|
|
MOVE.L -(A4),-(SP) ;push pointer to new title
|
|
_SetCTitle ;initialize the title field
|
|
;
|
|
; copy parameters into control data structure
|
|
;
|
|
MOVE.L (A3),A2 ;better rebuild pointer from handle
|
|
LEA ContrlVis(A2),A0 ;point to visible flag byte
|
|
SUBQ #2,A4 ;point A4 at visFlag boolean
|
|
TST.B (A4) ;check out the parameter
|
|
SNE (A0)+ ;set the visFlag byte accordingly
|
|
CLR.B (A0)+ ;initial hilite state is 0
|
|
;
|
|
MOVE.W -(A4),(A0)+ ;init value
|
|
MOVE.W -(A4),(A0)+ ;init minimum value
|
|
MOVE.W -(A4),(A0)+ ;init max value
|
|
;
|
|
; initialize definition proc
|
|
;
|
|
MOVE.W -(A4),D0 ;get the resource ID
|
|
LSR #4,D0 ;divide by 16
|
|
GetCDefProc
|
|
SUBQ #4,SP ;make room for function result
|
|
MOVE.L #('CDEF'),-(SP) ;push resource type CDef
|
|
MOVE.W D0,-(SP) ;push mapped resource ID
|
|
MOVE.W #MapTRUE,ROMMapInsert ; set flag to load from ROM <8 july 85>
|
|
_GetResource ;get the CDef handle
|
|
|
|
MOVEQ #0,D0 ;assume we couldnÕt get it
|
|
MOVE.L (A3),A0 ;get the control ptr
|
|
LEA ContrlDefHandle(A0),A0 ;point to defHandle
|
|
MOVE.L (SP)+,(A0) ;move it in
|
|
BEQ.S GetCDefProc ;if we couldnt find it, try 0
|
|
|
|
MOVE.W (A4),D0 ;get resource ID
|
|
AND #$000F,D0 ;use only low 4 bits
|
|
MOVE.L A0,-(SP) ; save A0 <C612/12Jan87> DAF
|
|
MOVE.L D0,-(SP) ; save D0 too <C612/12Jan87> DAF
|
|
SUBQ #6,SP ; get placeholder for auxCtlHndl, and boolean result <C612/12Jan87> DAF
|
|
MOVE.L A3,-(SP) ; push controlhandle <C612/12Jan87> DAF
|
|
PEA 6(SP) ; point to longword placeholder <C612/12Jan87> DAF
|
|
_GetAuxCtl ; get this windowÕs auxRec <C612/12Jan87> DAF
|
|
ADDQ #2,SP ; flush boolean <C612/12Jan87> DAF
|
|
MOVE.L (SP)+,A0 ; get auxCtlHndl <C612/12Jan87> DAF
|
|
MOVE.L (A0),A0 ; get auxCtlPtr <C612/12Jan87> DAF
|
|
MOVE.L (SP)+,D0 ; restore D0 (with variant) <C612/12Jan87> DAF
|
|
MOVE.B D0,acReserved(A0) ; put variant in auxRec <C612/12Jan87> DAF<1.6>
|
|
MOVE.L (SP)+,A0 ; restore A0 <C612/12Jan87> DAF
|
|
|
|
ADDQ #4,A0 ;bump to next field
|
|
|
|
CLR.L (A0)+ ;init dataHandle
|
|
CLR.L (A0)+ ;clear actionProc
|
|
MOVE.L -(A4),(A0)+ ;init reference constant
|
|
;
|
|
; all the fields of the data structure are now initialized. Send the controlProc
|
|
; the "init" message
|
|
;
|
|
MOVEQ #NewCtlMsg,D0 ;message is "new"
|
|
BSR.S CallControl ;tell the controlProc to init
|
|
;
|
|
; tell the control to draw itself if its visible
|
|
;
|
|
TST.B NCVisFlag(A6) ;is it visible
|
|
BEQ.S NCDone ;if not, weÕre done
|
|
;
|
|
MOVEQ #0,D1 ;tell it to draw everything
|
|
BSR.S CallDControl ;tell the control to draw itself
|
|
;
|
|
; all done with NewControl -- restore registers and return to caller
|
|
;
|
|
NCDone
|
|
MOVEM.L (SP)+,D1/A2-A4 ;restore work registers <C575/30Dec86> DAF
|
|
UNLK A6 ;unbuild stack frame
|
|
MOVE.L (SP)+,A0 ;get return address
|
|
ADD #26,SP ;strip parameters
|
|
JMP (A0) ;return to caller
|
|
;
|
|
; CallControl is a utility used to send a message to a controlÕs definitions
|
|
; procedure. On entry, the controlHandle is in A3, the message number is in
|
|
; D0 while D1 contains an optional parameter (used for hit & calc messages).
|
|
; CallControl makes sure that the controlÕs window is the current grafPort at
|
|
; the time the control definition procedure is invoked. On return, D0 contains
|
|
; the result from the definition procedure. The entry point CallDControl
|
|
; is used for draw messages to save code; it preloads D0 with the draw message,
|
|
; tests to see if the control should be drawn, and if so falls through to CallControl
|
|
;
|
|
CallDControl
|
|
MOVEQ #DrawCtlMsg,D0 ;get the draw message
|
|
MOVE.L (A3),A0 ;get control pointer
|
|
TST.B ContrlVis(A0) ;is it visible?
|
|
BEQ.S NoDControl ;donÕt draw invisible ones
|
|
|
|
; only draw the control if itÕs in the portrect
|
|
; Removed 14Jan86 because it didnÕt work with MacExpress
|
|
|
|
; MOVEM.L D0-D1,-(SP) ; save message, param <EHB 27-Apr-85>
|
|
; SUBA.L #10,SP ; make room for rect, result <EHB 27-Apr-85>
|
|
; PEA ContrlRect(A0) ; push address of controlÕs rect <EHB 27-Apr-85>
|
|
; MOVE.L ContrlOwner(A0),A1 ; get pointer to owning window <EHB 27-Apr-85>
|
|
; PEA PortRect(A1) ; push address of windowÕs portRect <EHB 27-Apr-85>
|
|
; PEA 10(SP) ; point to temp rect <EHB 27-Apr-85>
|
|
; _SectRect ; should we draw it? <EHB 27-Apr-85>
|
|
; TST.B (SP)+ ; NE if we should <EHB 27-Apr-85>
|
|
; ADDA.L #8,SP ; strip the rect <EHB 27-Apr-85>
|
|
; MOVEM.L (SP)+,D0-D1 ; restore message, param <EHB 27-Apr-85>
|
|
; BEQ.S NoDControl ; => donÕt draw remote ones <EHB 27-Apr-85>
|
|
;
|
|
CallControl
|
|
;
|
|
; set the grafPort to be the owning window
|
|
;
|
|
BSR OwnerPort ;save old one, too
|
|
|
|
;
|
|
; push parameters and invoke the control definition routine
|
|
;
|
|
CLR.L -(SP) ;make room for function result
|
|
|
|
CLR.W -(SP) ;make room for variant code <C491/08Dec86> DAF
|
|
MOVE.L A3,-(SP) ;push control handle
|
|
MOVE.W D0,-(SP) ;push message index
|
|
MOVE.L D1,-(SP) ;push parameter
|
|
|
|
SUBQ #2,SP ; make room for GetCVariant return <C491/08Dec86> DAF
|
|
MOVE.L A3,-(SP) ; get variation code <C491/08Dec86> DAF
|
|
_GetCVariant ; leave word result on stack <C491/08Dec86> DAF
|
|
MOVE.W (SP)+,10(SP) ; move from top of stack to placeholder <C491/08Dec86> DAF
|
|
|
|
MOVE.L (A3),A0 ;get pointer to control structure
|
|
MOVE.L ContrlDefHandle(A0),A0 ;get handle of controlProc <C491/08Dec86> DAF
|
|
TST.L (A0) ;needs reloading?
|
|
BNE.S SkipCLoad ;if not,skip
|
|
|
|
MOVE.L A0,-(SP) ;push control handle
|
|
MOVE.W #MapTrue,ROMMapInsert ; get it from ROM if possible <10 Jul 85>
|
|
_LoadResource ;load it in again
|
|
|
|
TST.L (A0) ;did we get it this time? <C949/08Nov87> DAF
|
|
BNE.S SkipCLoad ;yup, keep going <C949/08Nov87> DAF
|
|
MOVE.W #CDEFnFnd,D0 ;get error code <C949/08Nov87> DAF
|
|
_SysError ;and croak <C949/08Nov87> DAF
|
|
|
|
SkipCLoad
|
|
|
|
; Some programmers are pretty slimy and load a CDEF that is empty. They then <LW3> fau
|
|
; stuff some code into it. However, since HLOCK does not flush the cache anymore, <LW3> fau
|
|
; the code that they stuff into it might not get written back to memory. To solve this, <LW3> fau
|
|
; we check here whether the CDEF resource size is less than, say, 32 bytes. If so, we <LW6> chp
|
|
; assume that they have already loaded the CDEF and modified it, so we flush the cache <LW3> fau
|
|
; for them.
|
|
|
|
_GetHandleSize ; How big is our CDEF Handle <LW3> fau
|
|
cmp.l #32,D0 ; Is it "small" <LW6> chp
|
|
bhi.s @RealCDEF ; no, don't flush the cache <LW3> fau
|
|
move.l A0,-(SP)
|
|
move.l (A0),A0
|
|
move.l D0,A1
|
|
bsr.l FlushCRange ; else, flush the caches. <LW3> fau
|
|
move.l (SP)+,A0
|
|
|
|
@RealCDEF ; <LW3> fau
|
|
_HLock ; lock it down <C424/18Nov86>
|
|
MOVE.L (A0),A0 ;get cDefProc ptr
|
|
JSR (A0) ;call it
|
|
MOVE.L (A3),A0 ;get pointer back
|
|
MOVE.L ContrlDefHandle(A0),A0 ;get defProc handle back
|
|
_HUnlock ;unlock it <C424/18Nov86> DAF
|
|
MOVE.L (SP)+,D0 ;get function result
|
|
|
|
;
|
|
; restore original grafPort and return to caller
|
|
;
|
|
RPortExit
|
|
_SetPort ;restore original grafPort
|
|
NoDControl
|
|
RTS ;return to caller
|
|
|
|
;
|
|
; function GetCVariant ( whichControl : controlHandle ) : integer;
|
|
;
|
|
; GetCVariant returns the control variant code of the control whose
|
|
; handle is whichControl. Variant codes are 4-bit values returned
|
|
; right-justified in the word result. In case you are wondering
|
|
; the result is word rather than byte because itÕs less complicated
|
|
; for this stack-based routine, and the variant is passed to the
|
|
; defprocs as a word.
|
|
|
|
GetCVariant ; <C491/08Dec86> DAF
|
|
MOVE.L 4(SP),A0 ; get ctl handle
|
|
SUBQ #6,SP ; leave room for result and boolean <C612/12Jan87> DAF
|
|
MOVE.L A0,-(SP) ; push the controlHandle <C612/12Jan87> DAF
|
|
PEA 6(SP) ; point to result placeholder <C612/12Jan87> DAF
|
|
_GetAuxCtl ; get the controlÕs auxRec <C612/12Jan87> DAF
|
|
ADDQ #2,SP ; flush the boolean <C612/12Jan87> DAF
|
|
MOVE.L (SP)+,A0 ; get the auxCtlHndl <C612/12Jan87> DAF
|
|
MOVE.L (A0),A0 ; get the auxRecPtr <C612/12Jan87> DAF
|
|
CLR.W D0 ; clear top byte <C612/12Jan87> DAF
|
|
MOVE.B acReserved(A0),D0 ; get variant code <C612/12Jan87> DAF<1.6>
|
|
|
|
MOVE.W D0,8(SP) ; return result
|
|
MOVE.L (SP)+,A0 ; get return addr
|
|
ADDQ #4,SP ; flush parameters
|
|
JMP (A0) ; and return to caller
|
|
|
|
|
|
;
|
|
; Utility EraseControl -- utility for erasing a control from its window. The
|
|
; control handle is passed in A3
|
|
;
|
|
EraseControl
|
|
|
|
; get into the window that owns this control
|
|
|
|
BSR OwnerPort ;save port on stack, get into this on
|
|
|
|
MOVEM.L A1-A4,-(SP) ;save work registers
|
|
;
|
|
; allocate a temporary region and ask the control definition procedure for the
|
|
; controlÕs bounding region. The above move multiple pushed an extra register
|
|
; to make room for the NewRgn function result
|
|
;
|
|
_NewRgn ;allocate a new region
|
|
MOVE.L (SP),A4 ;keep the region in A4, keep on stack
|
|
|
|
MOVEQ #CalcWholeCtlMsg,D0 ;message is calculate whole regions <1.2>
|
|
MOVE.L A4,D1 ;the region is the parameter <1.2>
|
|
BSR CallControl ;send it the message <1.2>
|
|
|
|
;
|
|
; paint white to erase control and add it to the windowÕs update region
|
|
;
|
|
_EraseRgn ;erase it from the window
|
|
;
|
|
MOVE.L A4,-(SP) ;push region
|
|
_InvalRgn ;add to update region
|
|
;
|
|
; dispose of the temporary region
|
|
;
|
|
MOVE.L A4,-(SP) ;push region
|
|
_DisposRgn ;return it to the free list
|
|
|
|
; set the vis field false. This was moved up from HideControl so that DisposeControl
|
|
; (who also uses this utility) will do the right thing when de-allocating an auxWinRec
|
|
; on nuMac. This is in support of the ruler in Microsoft Word (1.05/3.0) <C678/23Jan87> DAF
|
|
|
|
MOVE.L (A3),A0 ;better rebuild pointer from handle
|
|
CLR.B ContrlVis(A0) ;mark it hidden
|
|
|
|
;
|
|
; restore original grafPort and weÕre done!
|
|
;
|
|
MOVEM.L (SP)+,A2-A4 ;restore work registers
|
|
BRA.S RPortExit ;use common code
|
|
|
|
;
|
|
; PROCEDURE DisposeControl(theControl: controlHandle);
|
|
;
|
|
; This routine disposes of a control. It deallocates its storage, removes it from the
|
|
; windowÕs controlList and removes it from the screen.
|
|
;
|
|
DisposeControl
|
|
MOVEM.L A2/A3,-(SP) ;preserve a work register <1.5>
|
|
MOVE.L 12(SP),A3 ;get the control handle <1.5>
|
|
|
|
; begin roll-in PatchDisposeControlForCorrectLayer patch <3>
|
|
|
|
tst.l 12(sp) ; is there a control handle ? <SM13> rb
|
|
beq DisposeNilControl ;if handle is NIL, exit <3>
|
|
|
|
move.l (a3), a0 ; get pointer <3>
|
|
subq.l #4, sp ; room for result <3>
|
|
subq.l #4, sp ; room for result for _SwapCurLayer <3>
|
|
move.l contrlOwner(a0), -(sp) ; setup for _GetParent <3>
|
|
_GetParent ; <3>
|
|
_SwapCurLayer ; swap for parent, leaves original layer on stack <3>
|
|
|
|
; end roll-in PatchDisposeControlForCorrectLayer patch <3>
|
|
|
|
; begin roll-in PatchDisposeControlForInvisibleControlsIIci patch <3>
|
|
|
|
move.l (a3),a0 ;get the control pointer <3>
|
|
tst.b contrlVis(A0) ;is the control visible? <3>
|
|
beq.s DontEraseControl ;no, skip erasing <3>
|
|
|
|
BSR.S EraseControl ;erase it from the screen
|
|
|
|
DontEraseControl ; <3>
|
|
|
|
; end roll-in PatchDisposeControlForInvisibleControlsIIci patch <3>
|
|
|
|
; dispose of auxCtlRec, if present. To do this, do a SetCtlColor with the request being the
|
|
; default control colortable (which deletes the auxCtlRec).
|
|
|
|
MOVE.L A3,-(SP) ; push handle for SetCtlColor later
|
|
CLR.L -(SP) ; return the default cTabHndl here
|
|
CLR.B -(SP) ; make room for a function return from GetAuxCtl
|
|
CLR.L -(SP) ; push the control Handle
|
|
PEA 6(SP) ; push a pointer to the cTabHndl placeholder
|
|
_GetAuxCtl ; get the default cTabHndl
|
|
ADDQ #2,SP ; dump the function result
|
|
MOVE.L (SP)+,A0 ; get the auxCtlRec handle
|
|
MOVE.L (A0),A0 ; get auxCtlRec ptr
|
|
MOVE.L acCTable(A0),-(SP) ; push default colors hndl <1.6>
|
|
|
|
LEA AuxCtlHead,A1 ; get the head of the auxCtlList (offset is zero so this works!)
|
|
@10
|
|
MOVE.L (A1),A2 ; get the handle to the auxCtlRec
|
|
MOVE.L (A2),A0 ; get the pointer to the auxCtlRec
|
|
CMP.L acOwner(A0),A3 ; is this the one?
|
|
BEQ.S @20 ; yes, so remove it
|
|
LEA acNext(A0),A1 ; get the next one
|
|
BRA.S @10
|
|
|
|
@20 MOVE.L acNext(A0),(A1) ; link around the closing control
|
|
MOVE.L A2,A1 ; copy the dead auxCtlRec handle
|
|
MOVE.L (A1),A1 ; get a pointer to it
|
|
MOVE.L acCTable(A1),D0 ; get the doomed color table handle
|
|
CMP.L (SP)+,D0 ; does this doomed record have the same color table as the default?
|
|
BEQ.S @30 ; if so, then donÕt delete it
|
|
MOVE.L D0,A0 ; get the doomed ctab handle in A0
|
|
_HGetState ; get the tag bits of this color table
|
|
BTST #resource,D0 ; is the resource bit set?
|
|
BNE.S @30 ; if so, donÕt delete it (it the appÕs responsibility)
|
|
_DisposHandle ; kill the color table
|
|
@30
|
|
MOVE.L A2,A0 ; release the auxCtlRec
|
|
_DisposHandle ;
|
|
ADDQ #4,SP ; get rid of the extra window pointer pushed above
|
|
|
|
;
|
|
; delete it from the windowÕs controlList
|
|
;
|
|
MOVE.L A3,A0 ;DeleteList needs handle in A0
|
|
MOVE.L (A3),A1 ;get control pointer
|
|
MOVE.L ContrlOwner(A1),A1 ;get windowPtr of owning window
|
|
LEA WControlList(A1),A1 ;A1 points to list header
|
|
BSR DeleteList ;delete it
|
|
;
|
|
; deallocate the data handle by sending a message to the definition proc
|
|
;
|
|
NoString1
|
|
MOVEQ #DispCtlMsg,D0 ;send the dispose message
|
|
BSR CallControl ;tell it to dispose its dataHandle
|
|
;
|
|
; deallocate the data structure itself, and weÕre done
|
|
;
|
|
MOVE.L A3,A0
|
|
_DisposHandle ;dispose of the control data structure
|
|
|
|
; begin roll-in PatchDisposeControlForCorrectLayer patch <3>
|
|
|
|
_SetCurLayer ; original layer should be on stack <3>
|
|
; waiting for us from _SwapCurLayer <3>
|
|
|
|
DisposeNilControl ; <3>
|
|
|
|
; end roll-in PatchDisposeControlForCorrectLayer patch <3>
|
|
|
|
MOVEM.L (SP)+,A2/A3 ; restore work registers <1.5>
|
|
MOVE.L (SP)+,(SP) ; strip parameter <1.5>
|
|
RTS ; <1.5>
|
|
|
|
;
|
|
; PROCEDURE KillControls(theWindow: WindowPtr);
|
|
;
|
|
; Dispose all controls associated with a given window
|
|
;
|
|
KillControls
|
|
MOVE.L A3,-(SP) ;save work register
|
|
MOVE.L 8(SP),A3 ;get window pointer
|
|
;
|
|
; Here is the loop that disposes the controls. It simply disposes the first one
|
|
; in the list
|
|
;
|
|
KillCLoop
|
|
MOVE.L WControlList(A3),D0 ;get next one in list
|
|
BEQ.S CShowDone ;if NIL, weÕre done
|
|
;
|
|
MOVE.L D0,-(SP) ;push the control handle
|
|
_DisposControl ;dispose of it
|
|
BRA.S KillCLoop ;loop till done
|
|
|
|
|
|
; PROCEDURE ShowOneControl(theControl: controlHandle);
|
|
;
|
|
; ShowOneControl draws a single control. The control is only drawn if visible
|
|
|
|
DrawOneControl MOVE.L A3,-(SP) ; save work register <EHB 15Oct85>
|
|
MOVE.L 8(SP),A3 ; get control handle <EHB 15Oct85>
|
|
MOVE.L (A3),A0 ; handle -> pointer <EHB 15Oct85>
|
|
TST.B contrlVis(A0) ; is the control visible? <C616/12Jan87> DAF
|
|
BEQ.S CShowDone ; if FALSE, then quit using common code <C616/12Jan87> DAF
|
|
BRA.S ShowCommon ; => use common code <EHB 15Oct85>
|
|
|
|
;
|
|
; PROCEDURE ShowControl(theControl: controlHandle);
|
|
;
|
|
; ShowControl makes a control visible if it is currently hidden. It causes it to
|
|
; be redrawn on the screen.
|
|
;
|
|
ShowControl
|
|
MOVE.L A3,-(SP) ;save work register
|
|
MOVE.L 8(SP),A3 ;get control handle
|
|
MOVE.L (A3),A0 ;handle -> pointer
|
|
;
|
|
; is it already visible?
|
|
;
|
|
TST.B ContrlVis(A0) ;already visible?
|
|
BNE.S CShowDone ;if so, thereÕs nothing to do
|
|
;
|
|
; make it visible
|
|
;
|
|
ST ContrlVis(A0) ;set the visible flag
|
|
ShowCommon ; <EHB 15Oct85>
|
|
MOVEQ #0,D1 ;all it of!
|
|
BSR CallDControl ;tell control to draw itself
|
|
;
|
|
; all done with ShowControl (code also shared with HideControl)
|
|
;
|
|
CShowDone
|
|
MOVE.L (SP)+,A3 ;restore work register
|
|
MOVE.L (SP)+,(SP) ;strip parameter
|
|
RTS
|
|
;
|
|
; PROCEDURE HideControl(theControl: controlHandle);
|
|
;
|
|
; HideControl makes a control hidden if it is currently visible. It causes it to
|
|
; be erased from the screen.
|
|
;
|
|
HideControl
|
|
MOVE.L A3,-(SP) ;save work register
|
|
MOVE.L 8(SP),A3 ;get control handle
|
|
MOVE.L (A3),A0 ;handle -> pointer
|
|
;
|
|
; is it already hidden?
|
|
;
|
|
TST.B ContrlVis(A0) ;already hidden?
|
|
BEQ.S CShowDone ;if so, thereÕs nothing to do
|
|
;
|
|
; hide the control
|
|
;
|
|
BSR EraseControl ;erase it (controlHandle in A3)
|
|
;
|
|
;+++ MOVE.L (A3),A0 ;better rebuild pointer from handle <C678/23Jan87> DAF
|
|
;+++ CLR.B ContrlVis(A0) ;mark it hidden <C678/23Jan87> DAF
|
|
BRA.S CShowDone ;all done!
|
|
;
|
|
; PROCEDURE MoveControl(theControl:controlHandle; h,v: INTEGER);
|
|
;
|
|
; MoveControl moves a control to the position specified by the (h,v) parameters.
|
|
; The (h,v) parameter is intepreted to be in the local coordinates of the controlÕs
|
|
; owning window and is the coordinate of the topLeft of the bounding rectangle
|
|
;
|
|
MoveControl
|
|
MOVEM.L D3/A3,-(SP) ;save work registers
|
|
MOVE.L 16(SP),A3 ;get the control handle
|
|
MOVE.L (A3),A0 ;get pointer to control
|
|
MOVE.B ContrlVis(A0),D3 ;remember visible state
|
|
;
|
|
MOVE.L A3,-(SP) ;push control handle
|
|
_HideControl ;hide it if its visible
|
|
;
|
|
; compute the difference of old position and new position
|
|
;
|
|
MOVE.L (A3),A0 ;get pointer to control data structure
|
|
ADDQ #ContrlRect,A0 ;point it at the rectangle
|
|
MOVE 12(SP),D0 ;get vertical coordinate
|
|
SUB (A0),D0 ;compute delta vertical
|
|
MOVE 14(SP),D1 ;get horizontal coordinate
|
|
SUB Left(A0),D1 ;compute delta horizontal
|
|
;
|
|
; offset the bounding rectangle to its new position
|
|
;
|
|
MOVE.L A0,-(SP) ;push pointer to old rectangle
|
|
MOVE D1,-(SP) ;push horizontal offset
|
|
MOVE D0,-(SP) ;push vertical offset
|
|
_OffsetRect ;offset to new position
|
|
;
|
|
; show the control if used to be visible
|
|
;
|
|
DoneMC0
|
|
TST.B D3 ;test the old visFlag
|
|
BEQ.S DoneMC ;if not visible, weÕre done
|
|
;
|
|
; show the control again
|
|
;
|
|
DoneMC1
|
|
MOVE.L A3,-(SP) ;push controlHandle
|
|
_ShowControl ;show it
|
|
;
|
|
DoneMC MOVEM.L (SP)+,D3/A3 ;restore work registers
|
|
EightBytExit MOVE.L (SP)+,A0 ;get return address
|
|
ADDQ #8,SP ;strip parameters
|
|
JMP (A0) ;return to caller
|
|
;
|
|
; FUNCTION GetCRefCon(theControl: controlHandle): LongInt;
|
|
;
|
|
; get the reference constant of a control
|
|
;
|
|
GetCRefCon
|
|
MOVEQ #ContrlRfCon,D1 ;get offset to refCon
|
|
GetCCommon
|
|
MOVE.L (SP)+,A0 ;get return address
|
|
MOVE.L (SP)+,A1 ;get controlHandle
|
|
MOVE.L (A1),A1 ;handle -> pointer
|
|
MOVE.L 0(A1,D1),(SP) ;return refCon as function result
|
|
JMP (A0) ;return to caller
|
|
;
|
|
; PROCEDURE SetCRefCon(theControl: controlHandle; data: LongInt);
|
|
;
|
|
; set the reference constant of a control to a specified value
|
|
;
|
|
SetCRefCon
|
|
MOVEQ #ContrlRfCon,D1 ;get offset to refCon
|
|
SetCCommon
|
|
MOVE.L (SP)+,A0 ;get return address
|
|
MOVE.L (SP)+,D0 ;get new refCon
|
|
MOVE.L (SP)+,A1 ;get controlHandle
|
|
MOVE.L (A1),A1 ;handle -> pointer
|
|
MOVE.L D0,0(A1,D1) ;set the refCon
|
|
JMP (A0) ;return to caller
|
|
;
|
|
; FUNCTION GetCtlAction(theControl: ControlHandle): ProcPtr
|
|
;
|
|
; access routine to find out the current local actionProc of a control
|
|
;
|
|
GetCtlAction
|
|
MOVEQ #ContrlAction,D1
|
|
BRA.S GetCCommon
|
|
;
|
|
; PROCEDURE SetCtlAction(theControl: ControlHandle; newProc: ProcPtr);
|
|
;
|
|
; access routine to set the actionProc of a control
|
|
;
|
|
SetCtlAction
|
|
MOVEQ #ContrlAction,D1
|
|
BRA.S SetCCommon
|
|
;
|
|
;
|
|
; PROCEDURE SizeControl(theControl: controlHandle; width,heigth: INTEGER);
|
|
;
|
|
; change the size of a controlÕs bounding box to the specified width and height
|
|
;
|
|
SizeControl
|
|
MOVEM.L D3/A3,-(SP) ;save work registers
|
|
MOVE.L 16(SP),A3 ;get control handle
|
|
MOVE.L (A3),A0 ;handle -> pointer
|
|
MOVE.B ContrlVis(A0),D3 ;remember visible state
|
|
;
|
|
MOVE.L A3,-(SP) ;push control handle
|
|
_HideControl ;hide the control
|
|
;
|
|
; get the width and height parameters
|
|
;
|
|
MOVE 12(SP),D0 ;get height parameter
|
|
MOVE 14(SP),D1 ;get width parameter
|
|
;
|
|
; resize the controlÕs bounding rectangle
|
|
;
|
|
@2 MOVE.L (A3),A0 ;get pointer to control
|
|
|
|
ADDQ #ContrlRect,A0 ;get pointer to boundsRect
|
|
ADD.W (A0)+,D0 ;bottom := top + height
|
|
ADD.W (A0)+,D1 ;right := left + width
|
|
MOVE D0,(A0)+ ;update bottom
|
|
MOVE D1,(A0)+ ;update right
|
|
;
|
|
; if its used to be visible, we better show it again
|
|
;
|
|
BRA.S DoneMC0 ;let common code do the work
|
|
;
|
|
; PROCEDURE HiliteControl(theControl: controlHandle; fHilite: INTEGER);
|
|
;
|
|
; HiliteControl will hilite a portion of a control according to the value of
|
|
; fHilite. fHilite is an integer between 0 and 255; 0 always means unhilited
|
|
; while other values hilite various parts of the control as defined by its definition
|
|
; procedure. Value 255 is special -- it means "obscure" the control and make it
|
|
; inactive and unselectable.
|
|
;
|
|
HiliteControl
|
|
MOVE.L A3,-(SP) ;save work register
|
|
MOVE.L 10(SP),A3 ;get the control handle
|
|
MOVE.L (A3),A0 ;get control pointer
|
|
MOVEQ #0,D1 ;clear out D1
|
|
MOVEQ #0,D0 ;ditto for D0
|
|
;
|
|
; get the value of hilite; if thatÕs the state the control is already in, we have
|
|
; nothing to do.
|
|
;
|
|
MOVE.B 9(SP),D1 ;get low byte of fHilite
|
|
MOVE.B ContrlHilite(A0),D0 ;remember old HiliteState
|
|
CMP.B D0,D1 ;are they the same?
|
|
BEQ.S DoneHiControl ;if they are, weÕre done
|
|
;
|
|
; the hilite state has changed so update the control data structure and redraw it
|
|
;
|
|
MOVE.B D1,ContrlHilite(A0) ;update hilite state
|
|
BNE.S @1 ;skip if non-zero
|
|
MOVE.W D0,D1 ;unhilite old part code
|
|
@1 BSR CallDControl ;tell control to draw itself
|
|
;
|
|
DoneHiControl
|
|
MOVE.L (SP)+,A3 ;restore work register
|
|
SixBytExit
|
|
MOVE.L (SP)+,A0 ;get return address
|
|
ADDQ #6,SP ;strip parameters
|
|
JMP (A0) ;return to caller
|
|
;
|
|
; PROCEDURE GetCTitle(theControl:ControlHandle; VAR theTitle: Str255);
|
|
;
|
|
; GetCTitle returns the current title of a control in the string passed in
|
|
; theTitle.
|
|
;
|
|
GetCTitle
|
|
MOVE.L (SP)+,D0 ;remember return address
|
|
MOVE.L (SP)+,A1 ;get destination string pointer
|
|
MOVE.L (SP)+,A0 ;get control handle
|
|
MOVE.L D0,-(SP) ;replace return address
|
|
;
|
|
; point A0 at the title string
|
|
;
|
|
MOVE.L (A0),A0 ;handle -> pointer
|
|
LEA ContrlTitle(A0),A0 ;point to title handle
|
|
;
|
|
; at this point A0 points to the string. Figure out its length and call blockMove to
|
|
; move it into the result string
|
|
;
|
|
MOVEQ #0,D0 ;clear high part
|
|
MOVE.B (A0),D0 ;get length of string
|
|
ADDQ.L #1,D0 ;include the length byte, too
|
|
_BLOCKMOVEDATA ;move it in place
|
|
RTS ;all done!
|
|
;
|
|
; PROCEDURE SetCTitle(theControl: controlHandle; theTitle: Str255);
|
|
;
|
|
; SetCTitle is used to set the title of a control.
|
|
;
|
|
SetCTitle
|
|
MOVEM.L D3/A3-A4,-(SP) ;save work register
|
|
MOVE.L 20(SP),A3 ;get control handle
|
|
MOVE.L (A3),A0 ;handle -> pointer
|
|
MOVE.B ContrlVis(A0),D3 ;remember visible state
|
|
;
|
|
; hide the control first
|
|
;
|
|
MOVE.L A3,-(SP) ;push control handle
|
|
_HideControl ;hide it
|
|
;
|
|
; resize the control to its new size
|
|
;
|
|
MOVE.L 16(SP),A4 ;get pointer to new title
|
|
MOVEQ #0,D0 ;clear out high part of D0
|
|
MOVE.B (A4),D0 ;get length word
|
|
MOVE.L D0,-(SP) ;remember it
|
|
ADD #ContrlSize+1,D0 ;compute the new size
|
|
MOVE.L A3,A0 ;get handle in A0
|
|
_SetHandleSize ;resize it
|
|
|
|
; begin roll-in CheckMemErrInSetCTitle patch <3>
|
|
|
|
beq.s CopyCTitle ; if no error, continue <3>
|
|
addq.w #4,sp ; otherwise, pop off the size <3>
|
|
bra.s GoTstVis ; and forget the _BlockMove <3>
|
|
|
|
CopyCTitle ; <3>
|
|
|
|
; end roll-in CheckMemErrInSetCTitle patch <3>
|
|
|
|
MOVE.L (SP)+,D0 ;recall the size
|
|
MOVE.L A4,A0 ;get pointer to source
|
|
MOVE.L (A3),A1 ;get control pointer
|
|
LEA ContrlTitle(A1),A1 ;point to title string
|
|
ADDQ #1,D0 ;dont forget the length byte
|
|
_BlockMoveData ;move it in
|
|
;
|
|
; make it visible if it used to be
|
|
;
|
|
GoTstVis
|
|
TST.B D3 ;was it visible?
|
|
BEQ.S DoneSetCString ;if not, weÕre done
|
|
MOVE.L A3,-(SP) ;push control handle
|
|
_ShowControl ;make it visible
|
|
;
|
|
; restore registers and go home
|
|
;
|
|
DoneSetCString
|
|
MOVEM.L (SP)+,D3/A3-A4 ;restore work registers
|
|
BRA EightBytExit ;standard exit saves code
|
|
|
|
;
|
|
; FUNCTION GetCtlValue(theControl: controlHandle): INTEGER;
|
|
;
|
|
; GetCtlValue returns the current value of the specified control. To save code,
|
|
; it shares code with GetCtlMin and GetCtlMax
|
|
;
|
|
GetCtlValue
|
|
MOVEQ #ContrlValue,D0 ;get value index into D0
|
|
;
|
|
; Here is the common code for GetCtlValue, GetCtlMin and GetCtlMax
|
|
;
|
|
GetCtlCommon
|
|
MOVE.L (SP)+,A1 ;get return address
|
|
MOVE.L (SP)+,A0 ;get control handle
|
|
MOVE.L (A0),A0 ;get control pointer
|
|
MOVE 0(A0,D0),(SP) ;move value into function result
|
|
JMP (A1) ;all done -- return to caller
|
|
;
|
|
; FUNCTION GetCtlMin(theControl:controlHandle): INTEGER;
|
|
;
|
|
; Get the current minimum value of the control
|
|
;
|
|
GetCtlMin
|
|
MOVEQ #ContrlMin,D0 ;get min index into D0
|
|
BRA.S GetCtlCommon ;let common code do all the work
|
|
;
|
|
; FUNCTION GetCtlMax(theControl:controlHandle): INTEGER;
|
|
;
|
|
; Get the current maximum value of the control
|
|
;
|
|
GetCtlMax
|
|
MOVEQ #ContrlMax,D0 ;get max index into D0
|
|
BRA.S GetCtlCommon ;let common code do all the work
|
|
;
|
|
; PROCEDURE SetCtlValue(theControl:controlHandle; value: INTEGER);
|
|
;
|
|
; Change the current value of a control, redrawing it if necessary. To save code,
|
|
; it shares code with SetCtlMin and SetCtlMax.
|
|
;
|
|
SetCtlValue
|
|
MOVEQ #ContrlValue,D0 ;get value index in D0
|
|
;
|
|
; Here is the common code shared by SetCtlValue, SetCtlMin and SetCtlMax
|
|
;
|
|
SetCtlCommon
|
|
MOVE.L A3,-(SP) ;save work register
|
|
MOVE.L 10(SP),A3 ;get the controlHandle
|
|
MOVE 8(SP),D1 ;get the value/min/max
|
|
MOVE.L (A3),A0 ;get pointer to control
|
|
;
|
|
; if the new value is the same as the current one, we have nothing to do
|
|
;
|
|
CMP.W 0(A0,D0),D1 ;has it changed?
|
|
BEQ.S ValSetDone ;if not, weÕre done
|
|
|
|
; update the new value
|
|
|
|
MOVE.W D1,0(A0,D0) ;update the new value/min/max
|
|
MOVE.W ContrlValue(A0),D1 ;get the value
|
|
|
|
; make sure its in range
|
|
|
|
CMP ContrlMin(A0),D1 ;compare with min
|
|
BGE.S @1 ;if > min, go check other bounds
|
|
MOVE ContrlMin(A0),D1 ;use the min if its less than min
|
|
;
|
|
@1 CMP ContrlMax(A0),D1 ;compare with max
|
|
BLE.S @2 ;if in range, set it
|
|
MOVE ContrlMax(A0),D1 ;use the max
|
|
|
|
; move in the range-checked value and redraw the control
|
|
|
|
@2
|
|
MOVE.W D1,ContrlValue(A0) ;move in the new value
|
|
MOVE #inThumb,D1 ;tell defProc weÕre changing thumb
|
|
BSR CallDControl ;tell control to redraw itself
|
|
;
|
|
; all done -- restore A3, strip parameters and return
|
|
;
|
|
ValSetDone
|
|
MOVE.L (SP)+,A3 ;restore work register
|
|
BRA SixBytExit ;standard exit saves code
|
|
;
|
|
; PROCEDURE SetCtlMin(theControl:controlHandle; minVal: INTEGER);
|
|
;
|
|
; Change the current minimum of a control, redrawing it if necessary.
|
|
;
|
|
SetCtlMin
|
|
MOVEQ #ContrlMin,D0 ;get value index in D0
|
|
BRA.S SetCtlCommon ;let common code do the work
|
|
;
|
|
; PROCEDURE SetCtlMax(theControl:controlHandle; maxVal: INTEGER);
|
|
;
|
|
; Change the current maximum of a control, redrawing it if necessary.
|
|
;
|
|
SetCtlMax
|
|
MOVEQ #ContrlMax,D0 ;get value index in D0
|
|
BRA.S SetCtlCommon ;let common code do the work
|
|
;
|
|
; FUNCTION TestControl(theControl: controlHandle; thePt: Point): INTEGER;
|
|
;
|
|
; TestControl tests to see if a given point is inside a given control. The point
|
|
; is assumed to be in the local coordinates of the controlÕs owning window. It
|
|
; returns an integer which is 0 if the point is not in the control at all or some
|
|
; small integer indicating what part of the control the button is in.
|
|
;
|
|
TestControl
|
|
MOVE.L A3,-(SP) ;preserve work register
|
|
MOVE.L 12(SP),A3 ;get control handle
|
|
MOVE.L (A3),A0 ;get control pointer
|
|
;
|
|
; if the control isnÕt visible, return 0
|
|
;
|
|
CLR.W 16(SP) ;assume its not in the control
|
|
MOVE.B ContrlVis(A0),D1 ;is it visible?
|
|
BEQ.S DoneTControl ;if not visible, weÕre done
|
|
;
|
|
; if its hilite state is 255, pretend its invisible
|
|
;
|
|
CMP.B #$FF,ContrlHilite(A0) ;is it selectable?
|
|
BEQ.S DoneTControl ;if not, donÕt really check it
|
|
;
|
|
; test the control by sending the control definition routine the "hit-test" message
|
|
;
|
|
MOVE.L 8(SP),D1 ;get point parameter in D1
|
|
MOVEQ #HitCtlMsg,D0 ;the message is hit-test
|
|
BSR CallControl ;invoke the definition routine
|
|
;
|
|
; the result is in D0; return this as the function result
|
|
;
|
|
MOVE D0,16(SP) ;return hit test result
|
|
;
|
|
DoneTControl
|
|
MOVE.L (SP)+,A3 ;restore work register
|
|
BRA EightBytExit ;standard exit saves code
|
|
;
|
|
; PROCEDURE DragControl(theControl:controlHandle; startPt: Point;
|
|
; boundRect: Rect; slopRect: Rect; axis: INTEGER);
|
|
;
|
|
; drag a flickering outline of control until the mouse button goes up. Make
|
|
; sure it stays within the bounding rectangle. The axis parameter is a constaint
|
|
; on the visual picture; if 0, no constraint, 1 = horizontal only, 2 = vertical only
|
|
; The slopRect is a rectangle for some hysterisis when dragging -- things pin to
|
|
; the bounding rect but are acceptable if the mouse goes up in the slopRect (which
|
|
; always contains the boundsRect)
|
|
;
|
|
DragControl CLR.W DragFlag ;flag where weÕre coming from
|
|
;
|
|
DragCon1
|
|
LINK A6,#0 ;estblish stack frame
|
|
MOVEM.L D3-D4/A3-A4,-(SP) ;save work registers
|
|
MOVEM.L 14(A6),D3-D4/A3 ;suck up the parameters
|
|
;
|
|
; save current grafPort and get into the control ownerÕs port
|
|
;
|
|
BSR OwnerPort
|
|
;
|
|
; issue the "custom drag" message -- if the control definition proc "accepts" it
|
|
; by returning a non-zero result, thereÕs nothing more to do
|
|
;
|
|
MOVE DragFlag,D1 ;get indicator boolean as parameter
|
|
MOVEQ #DragCtlMsg,D0 ;its a drag, man...
|
|
BSR CallControl ;tell the defProc about it
|
|
TST D0 ;did the defProc implement it?
|
|
BNE.S DoneDC1 ;if so, weÕre done (clear offset)
|
|
;
|
|
;
|
|
; allocate a region and ask the control definition procedure to update it
|
|
;
|
|
JSR GetNewRgn ;allocate a new region
|
|
|
|
MOVEQ #CalcWholeCtlMsg,D0 ;message is calculate whole regions <1.2>
|
|
TST.W DragFlag ;if weÕre called as real MoveControl, <1.2>
|
|
BEQ.S @0 ;then we picked the right message <1.2>
|
|
MOVEQ #CalcThumbCtlMsg,D0 ;else message is calculate thumb regions <1.2>
|
|
@0 ; <1.2>
|
|
MOVE.L (SP),D1 ;the region is the parameter <1.2>
|
|
BSR.S CallControl ;send it the message <1.2>
|
|
|
|
MOVE.L (SP)+,A4 ;keep it in A4
|
|
;
|
|
; set up the parameters for dragging the region around (careful -- extra reg
|
|
; in MOVEM reserves space for function result)
|
|
;
|
|
MOVEM.L D3-D4/A4-A5,-(SP) ;push the parameters
|
|
MOVE.L 10(A6),-(SP) ;push the slopRect
|
|
MOVE.W 8(A6),-(SP) ;push axis parameter
|
|
|
|
MOVE.L ExpandMem,a0
|
|
move.l a3,ExpandMemRec.emControlHandle(a0)
|
|
;
|
|
; set up the actionProc parameter
|
|
;
|
|
MOVE.L CurDragAction,-(SP) ;push the action proc
|
|
TST.W DragFlag ;are we tracking an indicator?
|
|
BNE.S @1 ;if so, weÕre cool
|
|
CLR.L (SP) ;no actionProc for DragControl
|
|
@1 _DragTheRgn ;use window manager drag routine
|
|
|
|
MOVE.L ExpandMem,a0 ; Now, clear the parameter we passed to <LW9>
|
|
Clr.l ExpandMemRec.emControlHandle(a0) ; DragTheRgn <LW9>
|
|
;
|
|
; dispose of the region -- we donÕt need it anymore
|
|
;
|
|
MOVE.L A4,-(SP) ;push the region
|
|
_DisposRgn ;dispose it
|
|
;
|
|
; get the motion offset and, if its non-zero, send a message to the control
|
|
;
|
|
MOVE.L (SP)+,D3 ;get the delta it was moved
|
|
BEQ.S DoneDrgControl ;if zero, donÕt move it
|
|
CMP.W #$8000,D3 ;was it aborted?
|
|
BNE.S DCMoveIt ;if not, skip
|
|
DoneDC1
|
|
MOVEQ #0,D3 ;pretend it was 0
|
|
BRA.S DoneDrgControl ;and weÕre done
|
|
|
|
DCMoveIt
|
|
TST.W DragFlag ;called from real MoveControl?
|
|
BNE.S DoneDrgControl ;if not, donÕt move
|
|
;
|
|
; call MoveControl to move it to its new position
|
|
;
|
|
MOVE.L (A3),A0 ;get control pointer
|
|
MOVE.L ContrlRect(A0),D0 ;get current topLeft
|
|
ADD D3,D0 ;compute new x position
|
|
SWAP D0 ;get y in low part
|
|
SWAP D3 ;ditto for curPosition
|
|
ADD D3,D0 ;compute new y position
|
|
SWAP D0 ;get x in low part
|
|
;
|
|
; call MoveControl
|
|
;
|
|
MOVE.L A3,-(SP) ;push control handle
|
|
MOVE.L D0,-(SP) ;push new position
|
|
_MoveControl ;move it
|
|
;
|
|
; all done -- restore port, restore registers and go home
|
|
;
|
|
DoneDrgControl
|
|
_SetPort ;restore old port
|
|
;
|
|
MOVE.L D3,D1 ;remember delta in D1
|
|
MOVEM.L (SP)+,D3-D4/A3-A4 ;restore work registers
|
|
UNLK A6 ;deallocate stack frame
|
|
MOVE.L (SP)+,A0 ;get return address
|
|
ADD #18,SP ;strip parameters
|
|
JMP (A0) ;return to caller
|
|
;
|
|
; Utility OwnerPort -- a utility used to save code. It saves the current grafPort
|
|
; on the stack and then enters the owning port of the control in A3
|
|
; WARNING: CallControl depends on D0, D1 not being trashed.
|
|
;
|
|
OwnerPort
|
|
MOVE.L (SP)+,D2 ;get the return address
|
|
|
|
SUBQ #4,SP ;allocate space on stack for result <16 Jul 85>
|
|
MOVE.L D2,-(SP) ;replace the return address <16 Jul 85>
|
|
MOVEM.L D0-D1,-(SP) ;we rely on D0 and D1 <16 Jul 85>
|
|
|
|
PEA 12(SP) ;point to space on stack <16 Jul 85>
|
|
_GetPort ;remember the port on the stack
|
|
|
|
MOVE.L (A3),A0 ;get pointer to control data structure
|
|
MOVE.L ContrlOwner(A0),-(SP) ;push owning windowPtr
|
|
_SetPort ;make that the current port
|
|
|
|
MOVEM.L (SP)+,D0-D1 ;restore the regs <16 Jul 85>
|
|
RTS ;and return w/result on stack
|
|
;
|
|
; FUNCTION TrackControl(theControl: controlHandle; mousePt: Point;
|
|
; actionProc: ProcPtr): INTEGER;
|
|
;
|
|
; TrackControl is called when the mouse button goes down inside a control. It
|
|
; hilites the appropriate section of the control and retains control until the mouse
|
|
; button goes up. While looping, it calls the actionProc to allow the application
|
|
; to perform some action while the control is active (like smooth scrolling, or beeping,
|
|
; etc.). It returns a position code indicating where the mouse was in the control when
|
|
; the button when up (useful for momentary buttons).
|
|
;
|
|
; If the actionProc parameter is NIL, it wonÕt call any actionProc. If its -1 (actually,
|
|
; any odd number) it will use the local actionProc that is part of the control data
|
|
; structure. If the local actionProc is odd, donÕt use it... instead, send a message
|
|
; to the defProc.
|
|
;
|
|
; If the classification code of the part of the control weÕre in is > 128, then
|
|
; weÕre in an indicator part of a dial. If so, case out and drag the indicator
|
|
; around.
|
|
;
|
|
TrackControl
|
|
LINK A6,#-28 ;get space for locals
|
|
MOVEM.L D3/A3,-(SP) ;save a work register
|
|
MOVE.L 16(A6),A3 ;keep the controlHandle in A3
|
|
MOVE.L 12(A6),-8(A6) ;initialize mouse position
|
|
|
|
; begin roll-in ThrottleScrollingSpeed patch <3>
|
|
|
|
; set up startTicks for UseGAction below, even though we may not need it <3>
|
|
|
|
SUBQ.L #4, SP ; <3>
|
|
_TickCount ; Get a time stamp. <3>
|
|
move.l ExpandMem,a0 ; <3>
|
|
move.l ExpandMemRec.emScrollSpeedGlobals(a0),a0 ; <3>
|
|
MOVE.L (SP)+,ScrollSpeedGlobals.startTicks(A0) ; And save it. <3>
|
|
|
|
; end roll-in ThrottleScrollingSpeed patch <3>
|
|
|
|
;
|
|
; preserve the current grafPort and enter the window that owns the control
|
|
;
|
|
BSR.S OwnerPort
|
|
MOVEQ #0,D3 ;mark initial code
|
|
;
|
|
; here is the main loop of trackControl. It reads the mouse position, tests the control,
|
|
; hilites the control based on the results of test control, calls the actionProc and
|
|
; repeats all this until the mouse button goes up.
|
|
;
|
|
TrkCtlLoop
|
|
MOVE.L A3,-(SP) ;push control handle for later hilite
|
|
CLR.W -(SP) ;make room for TestControl result
|
|
MOVE.L A3,-(SP) ;push control handle
|
|
MOVE.L -8(A6),-(SP) ;push the mouse point
|
|
_TestControl ;test the control
|
|
;
|
|
; make sure we only track the first section of a multi-part object (like a dial)
|
|
; that we go into
|
|
;
|
|
NoAction
|
|
TST D3 ;got anything yet?
|
|
BNE.S CheckCPart ;if so, make sure its the right part
|
|
MOVE (SP),D3 ;get this part as the one
|
|
TST.B D3 ;indicator part?
|
|
BPL.S CheckAction ;if not indicator, go handle it
|
|
BRA DoTheThumb ;go handle dragging the thumb
|
|
;
|
|
; only hilite parts that match the code in D3
|
|
;
|
|
CheckCPart
|
|
CMP (SP),D3 ;do they match
|
|
BEQ.S CheckAction ;if so, its cool
|
|
CLR (SP) ;pretend its out of range
|
|
|
|
;
|
|
; call the actionProc with the test result as the parameter, after hiliting
|
|
; the control
|
|
;
|
|
CheckAction
|
|
MOVE.W (SP),20(A6) ;save as result
|
|
_HiliteControl ;hilite it
|
|
|
|
MOVE.L 8(A6),D0 ;is there an actionProc?
|
|
BEQ.S TCNextMouse ;"ThereÕs no action..." (E. Costello)
|
|
;
|
|
; is it odd? if so, use the local one
|
|
;
|
|
BTST #0,D0 ;is it odd?
|
|
BEQ.S UseGAction ;if not, use global actionProc
|
|
;
|
|
; the actionProc is odd so use the local one (if any)
|
|
;
|
|
MOVE.L (A3),A0 ;get control pointer
|
|
MOVE.L ContrlAction(A0),D0 ;get local action proc
|
|
BEQ.S TCNextMouse ;if none, skip it
|
|
|
|
BTST #0,D0 ;is the built in one odd?
|
|
BEQ.S UseGAction ;is not, use it
|
|
|
|
MOVEQ #TrackCtlMsg,D0 ;invoke actionProc in defProc
|
|
MOVE 20(A6),D1 ;get part code as parameter
|
|
BSR CallControl ;ask the control to do it
|
|
BRA.S TCNextMouse ;now go hilite it
|
|
;
|
|
UseGAction
|
|
Move.l D0,-(SP) ; Save our action proc 'cause TickCount trashes it <SM14>
|
|
|
|
; begin roll-in ThrottleScrollingSpeed patch <3>
|
|
|
|
; set up actionTicks for _ScrollDelay, even though we may not need it <3>
|
|
|
|
SUBQ.L #4, SP ; <3>
|
|
_TickCount ; Get a time stamp. <3>
|
|
|
|
move.l ExpandMem,a0 ; <3>
|
|
move.l ExpandMemRec.emScrollSpeedGlobals(a0),a0 ; <3>
|
|
MOVE.L (SP)+,ScrollSpeedGlobals.actionTicks(A0) ; Save it <3>
|
|
|
|
Move.l (SP)+,D0 ; get back our action proc <SM14>
|
|
|
|
; call action proc that was passed in <3>
|
|
|
|
MOVE.L A3,-(SP) ;pass control handle
|
|
MOVE.W 20(A6),-(SP) ;duplicate test result
|
|
MOVE.L D0,A0 ;get actionProc ptr <SM14>
|
|
JSR (A0) ;call it
|
|
|
|
; see if we need to delay <3>
|
|
|
|
MOVE.W 20(A6), D0 ; get part code <3>
|
|
CMP.W #inUpButton, D0 ; < up button? <3>
|
|
BLT.S @noDelay ; Skip if so. <3>
|
|
CMP.W #inPageDown, D0 ; > page down? <3>
|
|
BGT.S @noDelay ; Skip if so. <3>
|
|
|
|
; we need a delay <3>
|
|
|
|
SUBQ.L #2, SP ; Room for result. <3>
|
|
move.l ExpandMem,a0 ; <3>
|
|
move.l ExpandMemRec.emScrollSpeedGlobals(a0),a0 ; <3>
|
|
MOVE.L ScrollSpeedGlobals.startTicks(a0), -(SP) ; <3>
|
|
MOVE.L ScrollSpeedGlobals.actionTicks(a0), -(SP) ; <3>
|
|
CLR.W -(SP) ; itemsVisible is unknown. <3>
|
|
_ScrollDelay
|
|
ADDQ.L #2, SP ; Toss result. <3>
|
|
|
|
@noDelay
|
|
|
|
; end roll-in ThrottleScrollingSpeed patch <3>
|
|
|
|
;
|
|
; read next mouse position and loop while the mouse button is still down
|
|
;
|
|
TCNextMouse
|
|
PEA -8(A6) ;push mousePt buffer location
|
|
_GetMouse ;read the mouse in local coordinates
|
|
;
|
|
CLR.W -(SP) ;make room for function result
|
|
_WaitMouseUp ;is mouse button still down?
|
|
TST.B (SP)+ ;examine result
|
|
BNE.S TrkCtlLoop ;if so, continue to loop
|
|
;
|
|
; unhilite the control
|
|
;
|
|
MOVE.L A3,-(SP) ;push the control handle
|
|
CLR.W -(SP) ;0 means unhilite
|
|
_HiliteControl ;unhilite it
|
|
;
|
|
; restore grafPort, registers and return to caller
|
|
;
|
|
TrackDone
|
|
_SetPort ;restore original grafPort
|
|
;
|
|
MOVEM.L (SP)+,D3/A3 ;restore work registers
|
|
UNLK A6 ;de-allocate stack frame
|
|
MOVE.L (SP)+,A0 ;get return address
|
|
ADD #12,SP ;strip parameters
|
|
JMP (A0) ;return to caller
|
|
|
|
;
|
|
; DoTheThumb handles the case when the FindWindow code is greater than 127. It drags
|
|
; the indicator by issuing a "ThumbDrag" message to get the rectangles and then calling
|
|
; DragControl with the implicit dragFlag parameter set. Finally, issue the move command
|
|
; to actually update the dial
|
|
;
|
|
DoTheThumb
|
|
MOVE (SP)+,20(A6) ;return code as result
|
|
ADDQ #4,SP ;pop off control handle
|
|
LEA -28(A6),A0 ;get address of parameter block
|
|
MOVE.L 12(A6),(A0) ;set it up with the mousePt
|
|
MOVE.L A0,D1 ;thatÕs the parameter block
|
|
MOVEQ #ThumbCtlMsg,D0 ;calculate the boxes
|
|
BSR CallControl ;ask the control to do it
|
|
;
|
|
Move.w #$FFFF,DragFlag ;mark it as a call from thumb-drag <LW8>
|
|
MOVE.L 8(A6),D0 ;get the actionProc
|
|
|
|
BTST #0,D0 ;is it odd?
|
|
BEQ.S @1 ;if not, we got it
|
|
MOVE.L (A3),A0 ;get the control pointer
|
|
MOVE.L ContrlAction(A0),D0 ;get the builtin one
|
|
|
|
BTST #0,D0 ;is the built-in one odd?
|
|
BEQ.S @1 ;if not, use it
|
|
|
|
MOVEQ #0,D0 ;otherwise, donÕt use it
|
|
@1
|
|
MOVE.L D0,CurDragAction ;set up implicit actionProc param
|
|
|
|
SUBQ #2,SP ;make room for return value <SM16> CSS
|
|
MOVE.L A3,-(SP) ;push the control handle <SM16> CSS
|
|
_GetCtlValue ;get the current control value (leave on stack) <SM16> CSS
|
|
MOVE.L A3,-(SP) ;push the control handle
|
|
MOVE.L 12(A6),-(SP) ;push the mouse point
|
|
LEA -28(A6),A0 ;get thumb parameter block
|
|
MOVE.L A0,-(SP) ;push pointer to boundsRect
|
|
PEA 8(A0) ;push pointer to slopRect
|
|
MOVE.W 16(A0),-(SP) ;push axis parameter
|
|
BSR DragCon1 ;drag the outline around
|
|
CLR.W DragFlag ;clear the drag flag <SM17> CSS
|
|
;
|
|
TST.L D1 ;did it move at all?
|
|
BEQ.S ReturnZero ;if not, weÕre done
|
|
ADD #2,SP ;remove saved value of control as DragControl <SM16> CSS
|
|
;told us the truth.
|
|
;
|
|
; OK, now we have the delta to move by in D1. Issue the pos message to actually
|
|
; set the dial to its new value.
|
|
;
|
|
MOVEQ #PosCtlMsg,D0 ;position message
|
|
BSR CallControl ;tell it to position itself
|
|
;
|
|
; all done with the indicator
|
|
;
|
|
BRA.S TrackDone
|
|
|
|
ReturnZero
|
|
; <SM16> CSS
|
|
; we may be here because a custom drag was done and drag control lied to us. We need to
|
|
; return the right thing to the caller of trackcontrol so if the control moved we don't
|
|
; clear the return value.
|
|
SUBQ #2,SP ; make room for return value <SM16> CSS
|
|
MOVE.L A3,-(SP) ; get control handle <SM16> CSS
|
|
_GetCtlValue ; get new control value <SM16> CSS
|
|
MOVE.W (SP)+,D1 ; get new value of control <SM16> CSS
|
|
MOVE.W (SP)+,D0 ; get old value of control <SM16> CSS
|
|
CMP.W D1,D0 ; did a custom drag do something out from <SM16> CSS
|
|
; under us? <SM16> CSS
|
|
BNE.S TrackDone ; yes - don't zero return value. <SM16> CSS
|
|
CLR.W 20(A6) ;return zero
|
|
BRA.S TrackDone ;all done
|
|
|
|
; PROCEDURE UpdateControls(theWindow: windowPtr; update: RgnHandle);
|
|
;
|
|
; UpdateControls is used to draw all the controls of a given window
|
|
; that are in the specified update region. Most useful for scrolling
|
|
; windows that contain controls.
|
|
|
|
DrawSW EQU 4 ; also # bytes of params for DrawC
|
|
UpdateSW EQU 8 ; also # bytes of params for UpdateC
|
|
|
|
UpdtControls
|
|
LINK A6,#-24 ; set up stack frame
|
|
MOVEM.L D7/A3,-(SP) ; save work registers
|
|
MOVE.L 12(A6),A3 ; get the window pointer
|
|
MOVEQ #updateSW,D7 ; signal update (#bytes of params too)
|
|
BRA.S DCCommon ; and use common code
|
|
|
|
|
|
; PROCEDURE DrawControls(theWindow: windowPtr);
|
|
;
|
|
; DrawControls is used to draw all the controls of a given window
|
|
; DonÕt call the defProc for controls that arenÕt in the portRect
|
|
|
|
DrawControls
|
|
LINK A6,#-24 ; set up stack frame
|
|
MOVEM.L D7/A3,-(SP) ; save work registers
|
|
MOVE.L 8(A6),A3 ; get the window pointer
|
|
MOVEQ #drawSW,D7 ; signal draw (#bytes of params too)
|
|
|
|
DCCommon
|
|
|
|
; preserve the pen state and set the pen to normal
|
|
|
|
SUBQ #4,SP ;get some space
|
|
MOVE.L SP,-(SP) ;push ptr to it
|
|
_GetPort
|
|
MOVE.L A3,-(SP) ;push current window
|
|
_SetPort ;make it the port
|
|
;
|
|
PEA -24(A6) ;get address of penState buffer
|
|
MOVE.L (SP),-(SP) ;save ptr for restore later
|
|
_GetPenState ;save the current penState
|
|
_PenNormal ;set the pen to normal
|
|
;
|
|
MOVE.L WControlList(A3),D0 ;get 1st control in list
|
|
BEQ.S DoneDrwCtls ;if NIL, weÕre done
|
|
;
|
|
; Here is the loop that issues the "draw yourself" message to each control in the list.
|
|
; If it is UpdateControls, it only issues message to controls in update region.
|
|
;
|
|
DCLoop
|
|
MOVE.L D0,A3 ;get controlHandle in A3
|
|
|
|
CMP.W #updateSW,D7 ; is it update?
|
|
BNE.S DoDC ; => no, donÕt check region
|
|
|
|
SUBQ #2,SP ; room for result
|
|
MOVE.L (A3),A0 ; handle -> pointer
|
|
PEA contrlRect(A0) ; push the controlÕs rect
|
|
MOVE.L 8(A6),-(SP) ; push the region handle
|
|
_RectInRgn ; does the item need to be updated?
|
|
TST.B (SP)+ ; NE if update needed
|
|
BEQ.S SkipDC ; => control not in update region
|
|
DoDC
|
|
MOVEQ #0,D1 ;draw all
|
|
BSR CallDControl ;issue the draw message
|
|
SkipDC
|
|
MOVE.L (A3),A0 ;get control pointer
|
|
MOVE.L NextControl(A0),D0 ;get next one in list
|
|
BNE.S DCLoop ;loop till we get a NIL one
|
|
;
|
|
DoneDrwCtls
|
|
_SetPenState ;restore the pen state
|
|
_SetPort ;restore grafPort
|
|
;
|
|
MOVE.L D7,D0 ; get params to strip
|
|
MOVEM.L (SP)+,D7/A3 ; restore work registers
|
|
UNLK A6 ; unbuild stack frame
|
|
MOVE.L (SP)+,A0 ; get return address
|
|
ADDA.L D0,SP ; strip parameters
|
|
JMP (A0)
|
|
;
|
|
;
|
|
; DELETELIST -- delete an element from a list. On entry, A0 contains the
|
|
; handle of the element to be deleted while A1 contains the address of the
|
|
; list header. On exit, D0 contains zero if the deletion was successful
|
|
; and -1 if the element to be deleted couldnÕt be found
|
|
;
|
|
;
|
|
DeleteList
|
|
MOVEM.L D1/A2-A3,-(SP) ;save some A-regs to play with
|
|
MOVEQ #-1,D0 ;assume we canÕt find it
|
|
TST.L (A1) ;is the list empty?
|
|
BEQ.S DELDONE ;if so, weÕre done
|
|
MOVE.L (A1),A2 ;get handle of 1st element
|
|
MOVE.L A1,A3 ;header is "prev" element
|
|
BRA.S DeleteNext ;dive right in
|
|
;
|
|
; here is the loop where we search for the element to be deleted
|
|
;
|
|
DELETELOOP MOVE.L (A2),A3 ;get pointer to current element
|
|
MOVE.L (A3),A2 ;get handle to next one
|
|
MOVE.L A2,D1 ;is it NIL?
|
|
BEQ.S DELDONE ;if so, weÕre done
|
|
DeleteNext
|
|
CMP.L A0,A2 ;is it the one we want?
|
|
BNE.S DELETELOOP ;if at first you donÕt succeed...
|
|
;
|
|
; delete the element pointed to by A2. A3 points to itÕs predecessor
|
|
;
|
|
MOVE.L (A2),A2 ;get pointer to one to be deleted
|
|
MOVE.L (A2),(A3) ;delete it!
|
|
MOVEQ #0,D0 ;flag the successful deletion
|
|
;
|
|
; all done so restore registers and return to caller
|
|
;
|
|
DELDONE MOVEM.L (SP)+,D1/A2-A3 ;restore registers
|
|
RTS
|
|
|
|
;
|
|
; FUNCTION FindControl( thePoint: Point;
|
|
; theWindow: WindowPtr;
|
|
; VAR theControl: ControlHandle): INTEGER;
|
|
;
|
|
; FindControl is the routine that correlates a mouse position with the logical
|
|
; data structure in that position. The mouse point is passed in the local coordinates
|
|
; of the window and it returns the control handle of the control the point is in,
|
|
; as well as a classification code further classifying the position.
|
|
;
|
|
FindControl
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
LINK A6,#-4 ;reserve space for locals
|
|
MOVEM.L D2-D3/A3,-(SP) ;save work registers (one extra)
|
|
;
|
|
; assume classification code is zero (inDesk) and the controlHandle is NIL.
|
|
;
|
|
LEA 8(A6),A0 ;point to control handle
|
|
MOVE.L (A0)+,A1 ;get pointer to controlHandle
|
|
CLR.L (A1) ;make it NIL
|
|
MOVE.L (A0)+,A3 ;get the windowPtr
|
|
MOVE.L (A0)+,D3 ;get the mouse point
|
|
CLR.W (A0) ;set classification code to zero
|
|
;
|
|
; save the current grafPort and set the parameter window as the new one
|
|
;
|
|
MOVE.L SP,-(SP) ;point to savePort buffer
|
|
_GetPort ;save the port in it
|
|
|
|
MOVE.L A3,-(SP) ;make the port the current window
|
|
_SetPort
|
|
;
|
|
; first make sure the window is visible and the point is somewhere inside the window
|
|
;
|
|
TST.B WVisible(A3) ;is this window visible?
|
|
BEQ TrackDone ;if not, don't test it, return 0
|
|
;
|
|
; check to see if its in the portRect of the window
|
|
;
|
|
CLR.W -(SP) ;make room for function result
|
|
MOVE.L D3,-(SP) ;push the point
|
|
PEA PortRect(A3) ;push the portRect of the window
|
|
_PtInRect ;is the point in the window?
|
|
TST.B (SP)+ ;examine result
|
|
BEQ TrackDone ;if its not, return 0
|
|
;
|
|
; its in the content area of the window so waltz through the controlList to see
|
|
; if its in any of the controls. Start with the first item in the control list
|
|
;
|
|
MOVE.L WControlList(A3),D0 ;get 1st control handle
|
|
BEQ.S TrackDone ;if NIL, its not in any
|
|
MOVE.L D0,A3 ;get control handle in A3
|
|
;
|
|
FControlLoop
|
|
MOVE.L (A3),A0 ;handle -> pointer
|
|
CMP.B #255,ContrlHilite(A0) ;is it 255-hilited?
|
|
BEQ.S SkipControl ;is so, skip it
|
|
|
|
CLR.W -(SP) ;make room for function result
|
|
MOVE.L A3,-(SP) ;push control handle
|
|
MOVE.L D3,-(SP) ;push the point
|
|
_TestControl ;ask the control what's up
|
|
MOVE.W (SP)+,D0 ;get the result of the test
|
|
BNE.S GotFControl ;if non-zero, then we found something
|
|
;
|
|
; its not in this control, so try the next one in the list
|
|
;
|
|
SkipControl
|
|
MOVE.L (A3),A0 ;handle -> pointer
|
|
MOVE.L NextControl(A0),A3 ;get the next one
|
|
MOVE.L A3,D0 ;is it NIL
|
|
BNE.S FControlLoop ;loop till we find one
|
|
;
|
|
; its not in any control, so just return
|
|
;
|
|
BRA TrackDone
|
|
;
|
|
; at this point, we know we're in some control. A3 has the control handle while D0 has
|
|
; the classification code. Update the controlHandle result and let common code finish
|
|
; up the rest
|
|
;
|
|
GotFControl
|
|
MOVE.L 8(A6),A0 ;get pointer to control result
|
|
MOVE.L A3,(A0) ;update with control handle
|
|
MOVE D0,20(A6) ;update classification code result
|
|
BRA.S SkipControl ;go see if its in any others
|
|
|
|
cmgrEnd
|
|
END
|
|
|