mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 16:31:01 +00:00
0ba83392d4
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
955 lines
34 KiB
Plaintext
955 lines
34 KiB
Plaintext
;
|
|
; File: ButtonCDEF.a
|
|
;
|
|
; Contains: Standard Button Definition Procedure for the MacIntosh Control Manager
|
|
; This file contains the control definition procedures that define
|
|
; the standard "button" type controls. These include PushButtons,
|
|
; CheckBoxes, and a checkBox variant called RadioButton.
|
|
;
|
|
; Written by: Andy Hertzfeld August, 1982
|
|
;
|
|
; Copyright: © 1982-1992 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; This file is used in these builds: Mac32 HcMac MacPP BigBang Sys606
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM2> 10/22/92 CSS Change short branches to word branches.
|
|
; <14> 4/11/91 gbm csd, KSM, BRC#86464: Fix many references to the control
|
|
; rectangle which are invalid because the control handle can be
|
|
; unlocked.
|
|
; <13> 3/4/91 dba dty: get rid of SysVers conditionals
|
|
; <12> 12/14/90 VL (ksm) Use PaintRoundRect instead of PaintRect for dithering
|
|
; text. Also, changed PenMode to TextMode since grayishTextOr is a
|
|
; text mode.
|
|
; <11> 8/23/90 SAM Removed the MoveHHi from the DrawPBut routine so that MacApp
|
|
; will work (it assumes that handles will be ok across calls to
|
|
; DrawControl -- idiots!)
|
|
; <10> 8/17/90 dvb Change grayish textMode pnMode to txMode
|
|
; <9> 8/13/90 VL Fixed test for portVersion to avoid trashing portVersion's
|
|
; value.
|
|
; <8> 8/2/90 VL Replaced SysVers switch with UseTrueGrayText (for ROM build).
|
|
; <7> 8/1/90 VL Make text to be drawn in TrueGray when disabled (in a color
|
|
; grafport).
|
|
; <6> 6/14/90 DDG NEEDED FOR SIXPACK: Moved the control manager handle with
|
|
; _MoveHHi before we lock it down while we are drawing. This
|
|
; should prevent out-of memory problems.
|
|
; <5> 5/29/90 DDG NEEDED FOR SIXPACK: Added the proper tag to the previous
|
|
; comment.
|
|
; <4> 5/29/90 DDG NEEDED FOR SIXPACK: Fix a bug where the button title is left
|
|
; unlocked for the duration of the drawing call.
|
|
; <3> 5/1/90 DDG Removed the temporary conditionals that I added for Sys605.
|
|
; <2> 3/2/90 DDG Adding conditionals for Sys605
|
|
; <1.4> 11/17/89 dba took out checks for 64K ROMs
|
|
; <1.3> 8/22/89 SES removed references to nFiles; updated equates accordingly
|
|
; <1.2> 2/9/89 EMT added new messages for 32-bit clean Control Manager.
|
|
; <1.1> 11/11/88 CCH Fixed Header.
|
|
; <1.0> 11/9/88 CCH adding to EASE.
|
|
; <¥1.1> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
|
|
; <1.0> 2/12/88 BBM Adding file for the first time into EASEÉ
|
|
; <C948> 11/8/87 DAF Updated romres sources from system disk sources
|
|
; SMAB156> 3/30/87 DAF Tested ROM version before using teSysJust.
|
|
; <C818> 2/14/87 DAF Converted nuMac PaintRoundRgn to be unified with other MacsÕ
|
|
; Erase stopped setting backColor when drawing text.
|
|
; <C700> 1/26/87 DAF Universal version of ButtonCDEF.a (version 10)
|
|
; <C637> 1/14/87 DAF Changed textMode back to srcOR from srcCopy (sigh...)
|
|
; <C560> 12/21/86 DAF Added Mark DavisÕ code to allow reversed checkmarks for intl
|
|
; <C424> 11/18/86 DAF converted a BSET/BCLR to an HLock/HUnlock, in CalcPBut
|
|
; <C407> 11/16/86 DAF changed textMode (again) to srcCopy, as per CaryÕs
|
|
; recommendation
|
|
; <C203> 10/8/86 DAF updated color support on nuMac for RGBColors changed textMode to
|
|
; srcOr.
|
|
; <C59> 6/30/86 DAF added color support for nuMac (mucho chango)
|
|
; <v4> 8/26/85 EHB made variable sized fonts work (ROM85>0 only)
|
|
; <v3> 5/20/85 EHB implemented Multi-Line buttons
|
|
; <v2> 5/16/85 EHB only return "254" if point in control!
|
|
; 3/12/85 JTC changed occurrences of LGlobals to GrafGlobals
|
|
; 2/14/85 JTC added res name
|
|
; 1/14/85 JTC convert to MDS
|
|
; 12/31/83 AJH made text of checkBox/radioButtons grayed out if disabled
|
|
; 10/17/83 AJH back to "gray-out" button disabling
|
|
; 10/12/83 AJH changed button disabling
|
|
; 9/27/83 AJH made variants > 7 not force the system font
|
|
; 8/29/83 AJH fixed scrambling bug in CalcPBut
|
|
; 6/7/83 AJH fixed scrambling bug, changed check draw for new QuickDraw
|
|
; 4/4/83 AJH made it force size 12 for text
|
|
; 4/1/83 AJH made it use hardwired gray
|
|
; 3/27/83 AJH made it respect initial clip in button drawing
|
|
; 3/11/83 AJH fixed up check box drawing
|
|
; 12/28/82 AJH Put button definitions in their own file
|
|
; 11/16/82 AJH Made branch tables offset based
|
|
; 11/14/82 AJH Improved PushButton roundness scaling; removed box in arrowBits
|
|
; 10/17/82 AJH Made controlProcs preserve A1
|
|
; 10/10/82 AJH Converted for QuickDraw Trap Interface
|
|
; 10/5/82 AJH Fixed checkBox flashing, added code saving optimizations
|
|
; 10/3/82 AJH Fixed bug in scrollBar positioning -- wasnÕt ctl relative
|
|
; 9/29/82 AJH Added CheckBox control definition procedure
|
|
; 8/29/82 AJH Added "255" hiliting,
|
|
; 8/25/82 AJH Fixed corner-clobber bug in pushButProc
|
|
; 8/22/82 AJH Added clipping, centering to PushButProc
|
|
;
|
|
; To Do:
|
|
;
|
|
|
|
PRINT PUSH,OFF
|
|
LOAD 'StandardEqu.d'
|
|
INCLUDE 'ColorEqu.a'
|
|
PRINT POP
|
|
|
|
;----------------------------------------------------------------------------------------------------
|
|
|
|
CDEF0 PROC EXPORT
|
|
|
|
; FUNCTION PushButProc( selector: INTEGER; 18
|
|
; theControl: ControlHandle; 14
|
|
; message: INTEGER; 12
|
|
; param: LongInt): LongInt; 8 : 20
|
|
;
|
|
; PushButProc is the control definition procedure for simple pushButtons, one of the
|
|
; standard control types supported by the user interface toolBox.
|
|
|
|
; And a stack frame definition
|
|
|
|
CtlHndl EQU 14 ;incoming control handle param <C59/30Jun86> DAF
|
|
SavePen EQU -20
|
|
Align EQU -21 ;a dead byte for IsColor <C700/26Jan87> DAF
|
|
IsColor EQU -22 ;do we have colorQD and toolbox [boolean] <C700/26Jan87> DAF
|
|
IndicatorRect EQU -30
|
|
AuxCtlHndl EQU -34 ;handle of auxCtl ColorTable <C59/30Jun86> DAF
|
|
AuxCtlPtr EQU -38 ;ptr to auxCtl ColorTable <C59/30Jun86> DAF
|
|
ContentRGB EQU -44 ;window content color <C59/30Jun86> DAF
|
|
SavFgCol EQU -50 ;window portÕs RGBFgColor <Cxxx/06Oct86> DAF
|
|
SavBkCol EQU -56 ;window portÕs RGBBkColor <Cxxx/06Oct86> DAF
|
|
useGrayText EQU -58
|
|
FrameSize EQU -58
|
|
|
|
BRA.S @0 ; skip header
|
|
|
|
; standard header
|
|
|
|
DC.W 0 ; flags
|
|
DC.L ('CDEF')
|
|
DC.W 0
|
|
DC.W 11 ; version #
|
|
|
|
@0
|
|
LINK A6,#FrameSize ; set up a stack frame to address parameters <C59/30Jun86> DAF
|
|
|
|
MOVEM.L D3-D7/A1-A4,-(SP) ; save work registers
|
|
;
|
|
; buttons only handle messages 0,1,2,10,11 <1.2>
|
|
;
|
|
CMP.W #calcCtlMsg,12(A6) ; inspect message value <1.2>
|
|
BLS.S @MsgOK ; if <2, itÕs OK <1.2>
|
|
CMP.W #calcWholeCtlMsg,12(A6) ; <1.2>
|
|
BEQ.S @MsgOK ; 10 is OK too <1.2>
|
|
CMP.W #calcThumbCtlMsg,12(A6) ; <1.2>
|
|
BNE DoneP1 ; And 11 <1.2>
|
|
@MsgOK
|
|
;
|
|
; save the penState and set it our way
|
|
;
|
|
PEA SavePen(A6) ; push pointer to savePenState
|
|
_GetPenState ; remember current penState
|
|
_PenNormal ; set the pen the way we want it
|
|
|
|
|
|
; Determine type of system. We need to know if we have color QuickDraw and a color
|
|
; window manager port.
|
|
|
|
CMP.W #$3FFF,ROM85 ; do we have color QD?
|
|
SLS IsColor(A6) ; set boolean depending on color or B&W system
|
|
BHI @BWSys ; no, this system has B&W QD <SM2> CSS
|
|
|
|
; save the current portÕs colors and textMode <C59/30Jun86> DAF
|
|
|
|
MOVE.L GrafGlobals(A5),A0 ; get pointer to grafGlobals <C407/16Nov86> DAF
|
|
MOVE.L thePort(A0),A0 ; get pointer to thePort <C407/16Nov86> DAF
|
|
MOVE.W txMode(A0),-(SP) ; save the current text mode <C407/16Nov86> DAF
|
|
|
|
MOVE.W #srcOR,-(SP) ; push text mode <C637/16Nov86> DAF
|
|
_TextMode ; <C407/16Nov86> DAF
|
|
|
|
PEA SavFgCol(A6) ; save foreColor
|
|
_GetForeColor ;
|
|
PEA SavBkCol(A6) ; save backColor too
|
|
_GetBackColor ;
|
|
|
|
;
|
|
; get the CtlAuxRec for this guy and lock its colortable <C59/30Jun86> DAF
|
|
;
|
|
CLR.L -(SP) ; return the handle here
|
|
CLR.B -(SP) ; space for boolean func return
|
|
MOVE.L CtlHndl(A6),-(SP) ; push the control handle
|
|
PEA 6(SP) ; push a pointer to placeholder
|
|
_GetAuxCtl ; get its auxRec
|
|
ADDQ #2,SP ; donÕt need boolean result
|
|
MOVE.L (SP)+,A0 ; get auxCtl handle
|
|
MOVE.L (A0),A0 ; a pointer to the auxCtlRec
|
|
MOVE.L acCTable(A0),A0 ; get colortableÕs handle <1.3>
|
|
MOVE.L A0,AuxCtlHndl(A6) ; save the handle
|
|
_HLock ; lock the handle
|
|
MOVE.L (A0),AuxCtlPtr(A6) ; save a pointer
|
|
|
|
;
|
|
; get the WinAuxRec that this control is in and copy its content color to
|
|
; the stack frame.
|
|
;
|
|
|
|
CLR.L -(SP) ; make a placeholder for a handle
|
|
CLR.B -(SP) ; room for a boolean result
|
|
MOVE.L CtlHndl(A6),A0 ; get the controlHandle again
|
|
MOVE.L (A0),A0 ; get a pointer
|
|
MOVE.L contrlOwner(A0),-(SP) ; push the owning window pointer
|
|
PEA 6(SP) ; pointer to the placeholder
|
|
_GetAuxWin ; get the window auxRec
|
|
ADDQ #2,SP ; bag the boolean
|
|
MOVE.L (SP)+,A0 ; get the WinAuxRec handle
|
|
MOVE.L (A0),A0 ; handle->ptr
|
|
MOVE.L awCTable(A0),A0 ; get the colortable handle <1.3>
|
|
MOVE.L (A0),A0 ; handle->ptr
|
|
|
|
MOVE.W CTSize(A0),D0 ; get the table count
|
|
MULU.W #8,D0 ; get a table index
|
|
@1
|
|
TST.W CTTable+value(A0,D0) ; is it wContentColor (=0)?
|
|
BEQ.S @2 ;
|
|
SUBQ #8,D0 ; move to previous colorSpec
|
|
BGE.S @1 ; and loop back
|
|
CLR.L D0 ; if not found, just use the first one
|
|
@2
|
|
MOVE.L CTTable+rgb(A0,D0),ContentRGB(A6) ; copy the color over
|
|
MOVE.W CTTable+rgb+4(A0,D0),ContentRGB+4(A6) ;
|
|
|
|
@BWSys
|
|
|
|
;
|
|
; fetch the parameters into registers
|
|
;
|
|
LEA 8(A6),A0 ; get ptr to first parameter
|
|
MOVE.L (A0)+,D3 ; get param in D3
|
|
MOVE.W (A0)+,D0 ; get message
|
|
MOVE.L (A0)+,A3 ; get the control handle
|
|
MOVE.W (A0)+,D6 ; get selection index
|
|
MOVE.W D6,D7 ; remember raw selection code
|
|
AND #7,D6 ; strip high part of selection code
|
|
|
|
CLR.L (A0) ; clear out function result
|
|
MOVE.L (A3),A0 ; get control pointer in A0
|
|
;
|
|
; case out on the message number
|
|
;
|
|
msgAdjust EQU calcWholeCtlMsg-calcCtlMsg-1 ; So that 10 becomes 3, 11 becomes 4 <1.2>
|
|
CMP.W #calcCtlMsg, D0 ; Does message need adjusting? <1.2>
|
|
BLS @LoMsg ; DonÕt adjust if not. <1.2>
|
|
SUBQ.W #msgAdjust, D0 ; Adjust message for address calculation <1.2>
|
|
@LoMsg
|
|
ADD D0,D0 ; double for word index
|
|
LEA GoPushBut,A1 ; get table address
|
|
ADD 0(A1,D0),A1 ; compute dispatch address
|
|
JSR (A1) ; dispatch to appropriate routine
|
|
|
|
;
|
|
; clean up color stuff
|
|
|
|
TST.B IsColor(A6) ; are we on a color system?
|
|
BEQ.S @NoColor1 ; if on B&W, then skip
|
|
|
|
MOVE.L AuxCtlHndl(A6),A0 ; unlock the CDEF
|
|
_HUnlock
|
|
PEA SavFgCol(A6) ; restore the port colors
|
|
_RGBForeColor ;
|
|
PEA SavBkCol(A6) ;
|
|
_RGBBackColor ;
|
|
|
|
_TextMode ; restore the textMode <C407/16Nov86> DAF
|
|
|
|
@noColor1 ; END OF A COLOR-ONLY SECTION
|
|
|
|
;
|
|
; restore original pen state
|
|
;
|
|
PEA SavePen(A6) ; push savePenState
|
|
_SetPenState ; restore original pen state
|
|
;
|
|
; weÕre done -- restore registers and return to caller
|
|
;
|
|
DoneP1
|
|
MOVEM.L (SP)+,D3-D7/A1-A4 ; restore work registers
|
|
UNLK A6 ; unlink stack frame
|
|
TenBytExit MOVE.L (SP)+,A0 ; get return address
|
|
ADD #12,SP ; strip parameters
|
|
JMP (A0) ; return to caller
|
|
;
|
|
; PushButProc dispatch table -- entries must be long branches!
|
|
;
|
|
GoPushBut
|
|
DC.W DrawPBut-GoPushBut ; draw is message 0
|
|
DC.W HitPBut-GoPushBut ; hit test is message 1
|
|
DC.W CalcPBut-GoPushBut ; calc regions is message 2
|
|
DC.W CalcWholePBut-GoPushBut ; calc whole regions is message 10 <1.2>
|
|
DC.W CalcThumbPBut-GoPushBut ; calc thumb regions is message 11 <1.2>
|
|
|
|
ButStub RTS
|
|
|
|
|
|
; SetUpColor takes a window part identifier in D0, finds the corresponding
|
|
; part in the AuxWinTable (the part code is in the .value field) and returns
|
|
; a pointer to its RGB on the stack. If the requested part is not found,
|
|
; the first color table element is used (IÕd use frameColor, but that might
|
|
; not be there!). Trashes A0/D0.
|
|
|
|
SetUpColor
|
|
MOVE.L D1,-(SP) ; save a register
|
|
MOVE.L AuxCtlPtr(A6),A0 ; get the color table pointer
|
|
MOVE.W CTSize(A0),D1 ; get the color table size
|
|
MULU #8,D1 ; convert to color table index
|
|
LegalIndex
|
|
CMP.W CTTable+value(A0,D1),D0 ; is this the one?
|
|
BEQ.S FoundIt ; if equal, then done
|
|
SUB.W #8,D1 ; try the previous one
|
|
BGE.S LegalIndex ; loop while index positive
|
|
MOVEQ #0,D1 ; OK, use the first one
|
|
FoundIt
|
|
LEA CTTable+rgb(A0,D1),A0 ; get the address of the color to use
|
|
MOVE.L A0,D0 ; weÕll need A0 in a second
|
|
MOVE.L (SP)+,D1 ; restore the register
|
|
MOVE.L (SP)+,A0 ; get the return address
|
|
MOVE.L D0,-(SP) ; push the rgb addr on the stack
|
|
JMP (A0) ; return to caller
|
|
|
|
|
|
;
|
|
; DrawPBut draws the pushButton
|
|
;
|
|
DrawPBut
|
|
TST.B ContrlVis(A0) ; is it visible?
|
|
BEQ.S ButStub ; if not, weÕre done
|
|
;
|
|
; calculate roundness as function of rectangle size
|
|
;
|
|
BSR RoundCalc ; compute roundNess factor in D4
|
|
|
|
TST.B IsColor(A6) ; are we on a color system?
|
|
BEQ.S @NoColor2 ; if on B&W, then skip
|
|
|
|
;
|
|
; if pushbutton, paint bk to body color; if checkmark then erase to window content <C59/30Jun86> DAF
|
|
;
|
|
@9 TST.B D6 ; is it a pushButton?
|
|
BEQ.S @4 ;
|
|
|
|
; set the window content color to the back for the eraseRRect <C59/30Jun86> DAF
|
|
|
|
PEA ContentRGB(A6) ; push the pointer to content color
|
|
BRA.S @5
|
|
|
|
; set the body color for button <C59/30Jun86> DAF
|
|
@4
|
|
MOVE.L (A3),A0 ; get control rec pointer
|
|
MOVE.B contrlHilite(A0),D0 ; get the hilite byte
|
|
SUBQ.B #1,D0 ; make 0->$FF
|
|
CMP.B #$FD,D0 ; is the control hilited?
|
|
BHS.S @8 ; no, so continue
|
|
MOVEQ #cTextColor,D0 ; if it is, paint the button in text color
|
|
BRA.S @0
|
|
@8 MOVEQ #cBodyColor,D0 ; if its not, then paint body color
|
|
@0 BSR.S SetUpColor ; get info on the stack
|
|
;
|
|
; erase the bounding rectangle (if necessary)
|
|
;
|
|
@5
|
|
_RGBBackColor ; set it
|
|
MOVE.L (A3),A0 ; get controlHandle again
|
|
|
|
@NoColor2 ; END OF A COLOR-ONLY SECTION
|
|
|
|
LEA ContrlRect(A0),A4 ; get pointer to bounding rect
|
|
TST.B D6 ; is it a pushButton?
|
|
BEQ.S EraseCBound ; push buttons are always erased
|
|
TST.B D3 ; draw all?
|
|
BNE.S SkipCErase ; if not, donÕt bother to erase
|
|
;
|
|
EraseCBound
|
|
MOVE.L A4,-(SP) ; push rect
|
|
MOVE.L D4,-(SP) ; push rounding factor
|
|
|
|
_EraseRoundRect ; paint it the background color
|
|
|
|
;
|
|
; save the current font and force the system font
|
|
;
|
|
SkipCErase MOVE.L GrafGlobals(A5),A0 ; get GrafGlobals base
|
|
MOVE.L ThePort(A0),A0 ; get current port
|
|
MOVE.L txFont(A0),-(SP) ; remember the font,face
|
|
MOVE.W txSize(A0),-(SP) ; remember the size
|
|
|
|
SUBQ #8,D7 ; was code 8 or greater?
|
|
BGE.S @gotFont ; if so, use windowÕs font
|
|
|
|
CLR.L txFont(A0) ; force system font, normal face
|
|
MOVE.W SysFontSize,D0 ; get default size <EHB 26Aug85>
|
|
BNZ.S @gotSize ; => itÕs 0! <EHB 26Aug85>
|
|
MOVE.B FMDefaultSize,D0 ; get default size <EHB 26Aug85>
|
|
@gotSize
|
|
MOVE.W D0,txSize(A0) ; set size of font <EHB 26Aug85>
|
|
@gotFont
|
|
MOVE.L ClipRgn(A0),-(SP) ; push the current clipRgn handle
|
|
|
|
; save old clip region and clip to the bounding rectangle sected with oldClip
|
|
|
|
CLR.L -(SP) ; make space for region handle
|
|
_NewRgn ; allocate a region
|
|
MOVE.L (SP),A2 ; remember region but leave on stack
|
|
_GetClip ; remember the current clipRgn
|
|
MOVE.L (A3),A0 ; get control pointer
|
|
PEA ContrlRect(A0) ; push pointer to its bounding rect
|
|
_ClipRect ; make that the clipping region
|
|
|
|
MOVE.L A2,-(SP) ; push the old ClipRgn
|
|
MOVE.L 4(SP),-(SP) ; the answer goes into current clip
|
|
_SectRgn ; intersect new and old
|
|
|
|
; Save off some registers for mondo button title calculations, then
|
|
; set them up for our use
|
|
|
|
MOVE.L A3,A0 ; copy control handle to A0 for memory calls
|
|
_HGetState
|
|
MOVE.L D0,-(SP) ; save the state of the control handle for later
|
|
;;; _MoveHHi ; move it up, before we lock it down <11> SAM (Removed)
|
|
_HLock ; lock it down
|
|
|
|
MOVEM.L D4/A2-A3,-(SP) ; save registers <EHB 20-May-85>
|
|
MOVE.L (A3),A0 ; get pointer to control
|
|
LEA contrlTitle(A0),A2 ; get title into A2
|
|
LEA contrlRect(A0),A4 ; get rect into A4 <EHB 20-May-85>
|
|
|
|
MOVEQ #0,D7 ; <EHB 20-May-85>
|
|
MOVE.B (A2),D7 ; get string length into D7 <EHB 20-May-85>
|
|
BEQ NoTitle ; quick check for nothing <EHB 20-May-85>
|
|
|
|
; now count the number of lines in the title. Lines are separated by CRÕs
|
|
|
|
MOVEQ #0,D4 ; save number of lines in D4 <EHB 20-May-85>
|
|
@2
|
|
ADDQ #1,D4 ; count next line <EHB 20-May-85>
|
|
BSR Pt2Next ; point to next line (index in D7) <EHB 20-May-85>
|
|
TST.B D7 ; D7 < 0 if done <EHB 20-May-85>
|
|
BPL.S @2 ; => get next line <EHB 20-May-85>
|
|
|
|
MOVE.B (A2),D7 ; get string length back <EHB 20-May-85>
|
|
|
|
; now get a font info record on stack, pointer to it in A3
|
|
|
|
SUBQ #8,SP ; make room for 4 INTEGERS <EHB 20-May-85>
|
|
MOVE.L SP,A3 ; save pointer in A3 <EHB 20-May-85>
|
|
MOVE.L A3,-(SP) ; push pointer to record <EHB 20-May-85>
|
|
_GetFontInfo ; and fill the record <EHB 20-May-85>
|
|
|
|
; Set up D5 to point to the baseline of the last line
|
|
|
|
BSR GetHeight ; get height of line into D0 <EHB 20-May-85>
|
|
MULU D4,D0 ; #lines times height <EHB 20-May-85>
|
|
MOVE.W bottom(A4),D1 ; get bottom of rect <EHB 20-May-85>
|
|
MOVE.W D1,D5 ; D5 will be baseline <EHB 20-May-85>
|
|
SUB.W top(A4),D1 ; get height of rect <EHB 20-May-85>
|
|
SUB.W D0,D1 ; get unused space <EHB 20-May-85>
|
|
ASR.W #1,D1 ; and DIV by 2 <EHB 20-May-85>
|
|
SUB.W D1,D5 ; move up from bottom <EHB 20-May-85>
|
|
SUB.W leading(A3),D5 ; to bottom of descender <EHB 20-May-85>
|
|
SUB.W descent(A3),D5 ; to first baseline <EHB 20-May-85>
|
|
DoNextLine
|
|
|
|
; get the width of the current line into D0
|
|
|
|
BSR Pt2Next ; next line in D7, len in D3 <EHB 20-May-85>
|
|
CLR.W -(SP) ; make room for result <EHB 20-May-85>
|
|
MOVE.L A2,-(SP) ; push title pointer <EHB 20-May-85>
|
|
MOVE.W D7,D0 ; get our offset into string <EHB 20-May-85>
|
|
ADDQ.B #2,D0 ; bump past length (or CR) <EHB 20-May-85>
|
|
MOVE.W D0,-(SP) ; push true offset into string <EHB 20-May-85>
|
|
MOVE.W D3,-(SP) ; push number of bytes <EHB 20-May-85>
|
|
_TextWidth ; get the stringÕs width <EHB 20-May-85>
|
|
MOVE.W (SP)+,D0 ; and save result in D0 <EHB 20-May-85>
|
|
|
|
; if itÕs a checkbox, donÕt center it, just move to right a little
|
|
|
|
TST.B D6 ; is it a check box?
|
|
BEQ.S ElCentro ; => no, go center the string <EHB 20-May-85>
|
|
|
|
; adjust positioning for push button
|
|
|
|
tst.w teSysJust ; right to left? <MED 27-Aug-86>
|
|
beq.s LeftBox ; no, normal case <MED 27-Aug-86>
|
|
|
|
RightBox
|
|
MOVE.W right(A4),D1 ; get the right edge <MED 27-Aug-86>
|
|
SUB.W left(A4),D1 ; get the width <MED 27-Aug-86>
|
|
SUB.W D0,D1 ; subtract stringÕs width <MED 27-Aug-86>
|
|
sub.w #18,d1 ; subtract room for box <MED 27-Aug-86>
|
|
ADD.W left(A4),D1 ; and add into left <MED 27-Aug-86>
|
|
BRA.S DrawBTitle ; back to common code <MED 27-Aug-86>
|
|
|
|
LeftBox
|
|
MOVE.W Left(A4),D1 ; get the left edge
|
|
ADD.W #18,D1 ; leave room for check box
|
|
BRA.S DrawBTitle ; back to common code
|
|
|
|
ElCentro
|
|
; center the line in the rect
|
|
|
|
MOVE.W right(A4),D1 ; get the right edge
|
|
SUB.W left(A4),D1 ; get the width
|
|
SUB.W D0,D1 ; subtract stringÕs width
|
|
ASR.W #1,D1 ; get centering offset
|
|
ADD.W left(A4),D1 ; and add into left
|
|
|
|
DrawBTitle
|
|
MOVE.W D1,-(SP) ; push horizontal position
|
|
MOVE.W D5,-(SP) ; and vertical position <EHB 20-May-85>
|
|
_MoveTo ; move the pen there
|
|
|
|
; now that registers are free, push colors on stack <C59/30Jun86> DAF
|
|
|
|
MOVE.L GrafGlobals(A5),A0 ; Save the pen mode
|
|
MOVE.L thePort(A0),A0 ;
|
|
MOVE.W txMode(A0),-(SP) ; <12>
|
|
TST.B IsColor(A6) ; are we on a color system?
|
|
BEQ.S @notColor ; no, skip the gray text checking stuff totally
|
|
MOVE.W portVersion(A0),D0 ; get portVersion into D0 for comparison
|
|
AND.W #$C000,D0 ; are we using a color grafport?
|
|
SNE useGrayText(A6) ; yes, set boolean useGrayText to true for future reference
|
|
BRA.S @doneCheckingForGrayText
|
|
@notColor ;
|
|
MOVE.B #0,useGrayText(A6) ; set boolean useGrayText to false
|
|
@doneCheckingForGrayText
|
|
TST.B IsColor(A6) ; are we on a color system?
|
|
BEQ.S @NoColor4 ; if on B&W, then skip
|
|
|
|
MOVE.L CtlHndl(A6),A0 ; get the control handle (not A3 in this section) <DAF 29Apr86>
|
|
MOVE.L (A0),A0 ; get control pointer
|
|
MOVE.B ContrlHilite(A0),D0 ; need to handle the case of 254/5 hiliting
|
|
BEQ.S @1 ; skip if hiliteValue == 0
|
|
CMP.B #$FE,D0 ; Is the button hilited?
|
|
BHS.S @Hilited ; skip if hiliteValue > 254 (i.e. disabled)
|
|
TST.B D6 ; Is it a check box or radio button?
|
|
BNE.S @1 ; yes => Want to set the forecolor to CTextColor in 7.0
|
|
MOVE.W #cBodyColor,D0 ; no => use cBodyColor as ForeColor in 6.0
|
|
BRA.S @4 ; (because BackColor is cTextColor)
|
|
@Hilited ;
|
|
TST.B useGrayText(A6) ; can we use GrayText?
|
|
BEQ.S @1 ;
|
|
MOVE.W #grayishTextOr,-(SP) ; yes => set the pen mode to grayishTextCopy
|
|
_TextMode ;
|
|
@1
|
|
MOVE.W #cTextColor,D0 ; use cTextColor as ForeColor
|
|
@4
|
|
BSR SetUpColor ; deposit appropriate values on stack
|
|
_RGBForeColor
|
|
@NoColor4
|
|
|
|
MOVE.L A2,-(SP) ; point to string <EHB 20-May-85>
|
|
MOVE.W D7,D0 ; get our offset into string <EHB 20-May-85>
|
|
ADDQ.B #2,D0 ; bump past length (or CR) <EHB 20-May-85>
|
|
MOVE.W D0,-(SP) ; push true offset into string <EHB 20-May-85>
|
|
MOVE.W D3,-(SP) ; push length in bytes <EHB 20-May-85>
|
|
_DrawText ; this is where we draw the line
|
|
|
|
_TextMode ; <12>
|
|
|
|
; bump baseline point up to next line, test for end
|
|
|
|
BSR GetHeight ; get line height into D0 <EHB 20-May-85>
|
|
SUB.W D0,D5 ; go up to next base line <EHB 20-May-85>
|
|
TST.B D7 ; done yet? <EHB 20-May-85>
|
|
BPL DoNextLine ; => nope <EHB 20-May-85>
|
|
|
|
ADDQ #8,SP ; strip font record <EHB 20-May-85>
|
|
NoTitle
|
|
MOVEM.L (SP)+,D4/A2-A3 ; and all those registers <EHB 20-May-85>
|
|
|
|
MOVE.L A3,A0 ; copy control handle to A0 for HSetState
|
|
MOVE.L (SP)+,D0 ; get the state off the stack and set it back
|
|
_HSetState
|
|
|
|
; <14>
|
|
; WARNING! Setting the state of the control record handle here may leave it unlocked! Several
|
|
; references are made below to items in the control record (mostly the control rect).
|
|
; Each reference must include reloading the control record pointer from the control
|
|
; record handle contained in register a3.
|
|
;
|
|
; We now return you to your regularly scheduled program.
|
|
; <14>
|
|
|
|
; restore original font, face and size
|
|
|
|
MOVE.L GrafGlobals(A5),A0 ; get GrafGlobals base
|
|
MOVE.L ThePort(A0),A0 ; get current port
|
|
MOVE.W (SP)+,txSize(A0) ; restore the size
|
|
MOVE.L (SP)+,txFont(A0) ; restore the font,face
|
|
|
|
;
|
|
; set the pen color to FrameColor <C59/30Jun86> DAF
|
|
;
|
|
|
|
TST.B IsColor(A6) ; are we on a color system?
|
|
BEQ.S @NoColor5 ; if on B&W, then skip
|
|
|
|
MOVEQ #cFrameColor,D0 ;
|
|
BSR SetUpColor ;
|
|
_RGBForeColor ;
|
|
|
|
@NoColor5 ; END OF A COLOR-ONLY SECTION
|
|
|
|
TST.B D6 ; is it a checkBox?
|
|
BNE PlotCheck ; if so, go draw it
|
|
|
|
move.l (a3), a0 ; get control pointer <14>
|
|
lea contrlRect(a0), a4 ; point to the control rect <14>
|
|
MOVE.L A4,-(SP) ; push the rectangle pointer
|
|
MOVE.L D4,-(SP) ; push rounding factor
|
|
_FrameRoundRect ; frame the button
|
|
|
|
;
|
|
; perform SpecialHilite if necessary
|
|
;
|
|
TST.B IsColor(A6) ; are we on a color system?
|
|
BEQ.S @NoColor6 ; if on B&W, then skip
|
|
|
|
TST.B useGrayText(A6) ; did we use GrayText?
|
|
BNE.S @skipSpecialHilite ; yes => skip SpecialHilite since GrayText represents hilite state already
|
|
MOVE.L (A3),A0 ; get control pointer
|
|
CMP.B #$FE,ContrlHilite(A0) ; is it the special hilite state?
|
|
BHS.S SpecialHilite ; if so, go do it
|
|
@skipSpecialHilite
|
|
BRA.S @Common6 ; and continue...
|
|
|
|
@NoColor6
|
|
;
|
|
; hilite the button if necessary
|
|
;
|
|
MOVE.L (A3),A0 ; get control pointer
|
|
MOVE.B ContrlHilite(A0),D0 ; is it hilited?
|
|
BEQ.S DoneDrwBut ; if not, weÕre done
|
|
;
|
|
TST.B useGrayText(A6) ; did we use GrayText?
|
|
BNE.S @Common6 ; yes, skip SpecialHilite since GrayText represents hilite state already
|
|
CMP.B #$FE,D0 ; is it the special hilite state?
|
|
BHS.S SpecialHilite ; if so, go do it
|
|
;
|
|
lea contrlRect(a0), a4 ; point to the control rect <14>
|
|
MOVE.L A4,-(SP) ; push rectangle
|
|
MOVE.L D4,-(SP) ; push rounding factor
|
|
_InverRoundRect ; hilite by inverting
|
|
|
|
@Common6
|
|
|
|
;
|
|
; restore original clipping region and weÕre done
|
|
;
|
|
DoneDrwBut
|
|
_PenNormal ; set the pen back to normal
|
|
MOVE.L A2,-(SP) ; push old clip region
|
|
_SetClip ; restore it
|
|
MOVE.L A2,-(SP) ; dispose of temporary region
|
|
_DisposRgn ; de-allocate it
|
|
RTS ; all done!
|
|
|
|
;------------
|
|
; Utility Pt2Next -- Point to next line within the title
|
|
; On Entry: A2 Title pointer
|
|
; D7 offset to end of next line to do
|
|
; On Exit: D7 offset to next line-2 (D7<0 if last line)
|
|
; D3 length of next line
|
|
|
|
CR EQU $0D ; CR = carriage return
|
|
|
|
Pt2Next
|
|
MOVEQ #0,D3 ; clear out count <EHB 20-May-85>
|
|
TST.B D7 ; pointing at count? <EHB 20-May-85>
|
|
BEQ.S @2 ; => yes, a leading CR <EHB 20-May-85>
|
|
@1
|
|
CMP.B #CR,0(A2,D7) ; is char a CR? <EHB 20-May-85>
|
|
BEQ.S @2 ; => yes, all done <EHB 20-May-85>
|
|
ADDQ #1,D3 ; else bump count by one <EHB 20-May-85>
|
|
SUBQ.B #1,D7 ; and move back in string <EHB 20-May-85>
|
|
BNE.S @1 ; => not end of string <EHB 20-May-85>
|
|
@2
|
|
SUBQ.B #1,D7 ; prepare for next string <EHB 20-May-85>
|
|
RTS ; D7 < 0 if last line <EHB 20-May-85>
|
|
|
|
;------------
|
|
; Utility GetHeight -- return in D0 the height of on line
|
|
; On Entry: A3 Font Record
|
|
; On Exit: D0 Line height
|
|
|
|
GetHeight
|
|
MOVEQ #0,D0 ; clear out height <EHB 20-May-85>
|
|
ADD.W ascent(A3),D0 ; height = ascent + descent + leading <EHB 20-May-85>
|
|
ADD.W descent(A3),D0 ; <EHB 20-May-85>
|
|
ADD.W leading(A3),D0 ; <EHB 20-May-85>
|
|
RTS
|
|
|
|
; SpecialHilite handles drawing the disabled button
|
|
|
|
SpecialHilite
|
|
BSR.S DisableText
|
|
BRA.S DoneDrwBut
|
|
DisableText
|
|
TST.B IsColor(A6) ; are we on a color system?
|
|
BEQ.S @NoColor7 ; if on B&W, then skip
|
|
|
|
TST.B D6 ; is it a pushbutton?
|
|
BNE.S @NoColor7 ; a checkbox, so go
|
|
MOVEQ #cTextColor,D0 ; set the colors apropos
|
|
BSR SetUpColor ;
|
|
_RGBForeColor ;
|
|
MOVEQ #cBodyColor,D0 ;
|
|
BSR SetUpColor ;
|
|
_RGBBackColor ;
|
|
|
|
@NoColor7 ; END OF A COLOR-ONLY SECTION
|
|
|
|
move.l (a3), a0 ; get control pointer <14>
|
|
lea contrlRect(a0), a4 ; point to the control rect <14>
|
|
MOVE.L A4,-(SP) ; push rectangle
|
|
MOVE.L #$00010001,-(SP) ; <12>
|
|
_InsetRect
|
|
|
|
MOVE.L A4,-(SP) ; push rectangle
|
|
MOVE.L D4,-(SP) ; push the rounding factor <12>
|
|
|
|
MOVE.L (A5),A0
|
|
PEA Gray(A0)
|
|
_PenPat
|
|
MOVE #patBIC,-(SP)
|
|
_PenMode
|
|
|
|
_PaintRoundRect ; gray it out <12>
|
|
_PenNormal
|
|
|
|
move.l (a3), a0 ; get control pointer <14>
|
|
lea contrlRect(a0), a4 ; point to the control rect <14>
|
|
MOVE.L A4,-(SP)
|
|
MOVE.L #$FFFFFFFF,-(SP) ; <12>
|
|
_InsetRect
|
|
|
|
RTS
|
|
|
|
; RoundCalc calculates the rounding factor in D4 based on the controlÕs rect
|
|
|
|
RoundCalc
|
|
TST.B D6 ; is it a checkBox?
|
|
BNE.S CheckRound ; if so, special case it
|
|
;
|
|
MOVE.W ContrlRect+Bottom(A0),D4 ; get bottom coordinate
|
|
SUB.W ContrlRect+Top(A0),D4 ; figure out vertical height
|
|
LSR #1,D4 ; scale it down by a factor of 2
|
|
MOVE D4,D0 ; fill both halves with it
|
|
SWAP D4 ; get in high part
|
|
MOVE D0,D4 ; and in low part
|
|
RTS
|
|
;
|
|
CheckRound MOVEQ #0,D4 ; checkBoxes are square!
|
|
RTS
|
|
;
|
|
; HitPBut handles the button hit-test
|
|
;
|
|
HitPBut
|
|
MOVE.B ContrlHilite(A0),D4 ; get hiliteState <EHB 16-May-85>
|
|
ADDQ.B #1,D4 ; is it 255? <EHB 16-May-85>
|
|
BEQ.S @1 ; if so, skip
|
|
|
|
CLR.W -(SP) ; make room for function result
|
|
MOVE.L D3,-(SP) ; push the point
|
|
PEA ContrlRect(A0) ; push address of rect
|
|
_PtInRect ; in the rectangle?
|
|
TST.B (SP)+ ; examine result
|
|
BEQ.S @1 ; if not, weÕre done
|
|
|
|
ADDQ.B #1,D4 ; 254 hiliting? <EHB 16-May-85>
|
|
BEQ.S Return254 ; => say it is so <EHB 16-May-85>
|
|
|
|
MOVE #inButton,22(A6) ; return that it was
|
|
TST.B D6 ; a checkBox?
|
|
BEQ.S @1 ; if not, weÕre done
|
|
ADDQ #1,22(A6) ; if so, flag it
|
|
@1 RTS
|
|
|
|
Return254
|
|
MOVE #254,22(A6) ; indicate its 254-disabled
|
|
RTS
|
|
|
|
CalcWholePBut
|
|
CalcThumbPBut
|
|
MOVE.B #1, 23(A6) ; return 1 to show that we respond <V1.2>
|
|
;
|
|
; CalcPBut returns the bounding region of the button
|
|
;
|
|
CalcPBut
|
|
TST.B D6 ; is it a checkBox?
|
|
BNE.S CalcSquare ; check box bounds are just rects
|
|
;
|
|
BSR.S RoundCalc ; calculate rounding factor
|
|
_HidePen ; dont draw anything
|
|
_OpenRgn
|
|
|
|
MOVE.L A3,A0 ; copy to A0 for HLock <C424/18Nov86> DAF
|
|
_HLock ; lock it down <C424/18Nov86> DAF
|
|
|
|
MOVE.L (A3),A0 ; get pointer to control
|
|
PEA ContrlRect(A0) ; push rectangle pointer
|
|
MOVE.L D4,-(SP) ; push rounding factor
|
|
_FrameRoundRect ; frame the button
|
|
|
|
MOVE.L D3,-(SP) ; push the region
|
|
_CloseRgn ; make the rounded rectangular region
|
|
_ShowPen
|
|
|
|
MOVE.L A3,A0 ; copy to A0 for HLock <C424/18Nov86> DAF
|
|
_HUnlock ; unlock the control <C424/18Nov86> DAF
|
|
|
|
;
|
|
; set the pattern for indicator dragging
|
|
;
|
|
DragGray
|
|
MOVE.L (A5),A0 ; get qDraw globals
|
|
LEA Gray(A0),A0 ; point to gray pattern
|
|
MOVE.L (A0)+,DragPattern ; move in the 1st half
|
|
MOVE.L (A0),DragPattern+4 ; move in the 2nd half
|
|
RTS ; all done!
|
|
;
|
|
CalcSquare
|
|
MOVE.L D3,-(SP) ; push the region
|
|
PEA ContrlRect(A0) ; push the rectangle pointer
|
|
_RectRgn ; make a rectangular region
|
|
BRA.S DragGray ; all done -- go set drag pattern
|
|
;
|
|
; PlotCheck takes care of drawing the actual check box of the check box button. It
|
|
; figures out where to draw the box, draws it, and then checks it or not based on
|
|
; the current value and hilite state of the button
|
|
;
|
|
PlotCheck
|
|
|
|
; first set the window content color <C59/30Jun86> DAF
|
|
TST.B IsColor(A6) ; are we on a color system?
|
|
BEQ.S @NoColor8 ; if on B&W, then skip
|
|
|
|
PEA ContentRGB(A6)
|
|
_RGBBackColor ;
|
|
@NoColor8 ; END OF A COLOR-ONLY SECTION
|
|
|
|
move.l (a3), a0 ; get control pointer <14>
|
|
lea contrlRect(a0), a4 ; point to the control rect <14>
|
|
SUBQ #8,SP ; allocate a rectangle on the stack
|
|
MOVE.W bottom(A4),D0 ; get rect height <EHB 20-May-85>
|
|
MOVE.W D0,D1 ; save a copy <EHB 20-May-85>
|
|
SUB.W top(A4),D0 ; get height <EHB 20-May-85>
|
|
SUB.W #12,D0 ; sub box height <EHB 20-May-85>
|
|
ASR.W #1,D0 ; div by 2 <EHB 20-May-85>
|
|
SUB.W D0,D1 ; get offset from bottom <EHB 20-May-85>
|
|
MOVE D1,Bottom(SP) ; set up the bottom <EHB 20-May-85>
|
|
SUB #12,D1 ; compute the top <EHB 20-May-85>
|
|
MOVE D1,Top(SP) ; set up the top <EHB 20-May-85>
|
|
|
|
tst.w teSysJust ; right to left? <MED 27-Aug-86>
|
|
beq.s LeftBoxTitle ; no, normal case <MED 27-Aug-86>
|
|
|
|
RightBoxTitle
|
|
MOVE Right(A4),D1 ; get left edge of boundsRect <MED 27-Aug-86>
|
|
subq #2,D1 ; indent 2 pixels <MED 27-Aug-86>
|
|
MOVE D1,Right(SP) ; thatÕs the left of the checkRect <MED 27-Aug-86>
|
|
sub #12,D1 ; compute right edge <MED 27-Aug-86>
|
|
MOVE D1,Left(SP) ; update the right edge <MED 27-Aug-86>
|
|
bra.s EraseCheck ; continue <MED 27-Aug-86>
|
|
|
|
LeftBoxTitle
|
|
MOVE Left(A4),D1 ; get left edge of boundsRect <EHB 20-May-85>
|
|
ADDQ #2,D1 ; indent 2 pixels <EHB 20-May-85>
|
|
MOVE D1,Left(SP) ; thatÕs the left of the checkRect <EHB 20-May-85>
|
|
ADD #12,D1 ; compute right edge <EHB 20-May-85>
|
|
MOVE D1,Right(SP) ; update the right edge <EHB 20-May-85>
|
|
|
|
EraseCheck
|
|
;
|
|
; erase the check box
|
|
;
|
|
MOVE.L SP,-(SP) ; push rectangle pointer
|
|
_EraseRect ; erase it
|
|
;
|
|
; OK, now we must fill in the checkBox rectangle based on the value and hilite state
|
|
; of the control
|
|
;
|
|
MOVE.L (A3),A0 ; get control pointer <14>
|
|
MOVE.W ContrlValue(A0),D5 ; get the value
|
|
MOVE.B ContrlHilite(A0),D0 ; is it hilited?
|
|
BEQ.S FrameCheck ; if not, skip
|
|
;
|
|
; its hilited so up the penSize to indicate its hilited
|
|
;
|
|
CMP.B #$FE,D0 ; disabled?
|
|
BLO.S SkipDis ; if so, skip doubling
|
|
;
|
|
TST.B useGrayText(A6) ; did we use GrayText?
|
|
BNE.S FrameCheck ; yes => skip DisableText since GrayText represents disabled state
|
|
BSR DisableText
|
|
BRA.S FrameCheck
|
|
|
|
SkipDis
|
|
MOVE.L #$00020002,-(SP)
|
|
_PenSize ; up the penSize
|
|
FrameCheck
|
|
MOVE.L SP,-(SP) ; push the rectangle
|
|
|
|
CMP.B #2,D6 ; test for radio button
|
|
BEQ.S @1 ; if its a radio button, go do it
|
|
_FrameRect ; frame it
|
|
BRA.S @2
|
|
@1
|
|
_FrameOval
|
|
@2
|
|
_PenNormal
|
|
;
|
|
; now we can draw the check if weÕre supposed to
|
|
;
|
|
LSR #1,D5 ; check out the low bit of D5
|
|
BCC.S DonePCheck ; if its off, weÕre done
|
|
;
|
|
CMP.W #2,D6 ; test for radio button
|
|
BEQ.S DrawRButton ; if its a radio button, go do it
|
|
;
|
|
MOVE.L SP,-(SP) ; push the rectangle pointer
|
|
MOVE.L OneOne,-(SP) ; push the inset factor
|
|
_InsetRect ; inset the rectangle
|
|
|
|
MOVE.L TopLeft(SP),-(SP) ; push top left
|
|
_MoveTo ; move to it
|
|
MOVE.L BotRight(SP),-(SP) ; push bottom right
|
|
_LineTo ; draw one line of the cross
|
|
;
|
|
MOVE Right(SP),-(SP) ; push right
|
|
MOVE Top+2(SP),-(SP) ; push top
|
|
SUBQ #1,(SP) ; bias the top
|
|
_MoveTo ; move to it
|
|
MOVE Left(SP),-(SP) ; push left
|
|
SUBQ #1,(SP) ; bias the left
|
|
MOVE Bottom+2(SP),-(SP) ; push bottom
|
|
_LineTo ; draw the line
|
|
BRA.S DonePCheck
|
|
;
|
|
; draw the radio button check mark -- a little circle
|
|
;
|
|
DrawRButton
|
|
MOVE.L SP,-(SP) ; push pointer to rect
|
|
MOVE.L #$00030003,-(SP) ; push inset factor
|
|
_InsetRect ; inset it
|
|
MOVE.L SP,-(SP) ; push rect again
|
|
_PaintOval ; draw the circle?
|
|
;
|
|
DonePCheck
|
|
ADDQ #8,SP ; pop off the rectangle
|
|
BRA DoneDrwBut ; all done!
|
|
|
|
END
|
|
|