;
; drag.s
;
; Support code for dragging operations (MDW)
;
;  1995-1998 Straylight
;

;----- Licensing note -------------------------------------------------------
;
; This file is part of Straylight's Sapphire library.
;
; Sapphire is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2, or (at your option)
; any later version.
;
; Sapphire is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with Sapphire.  If not, write to the Free Software Foundation,
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

;----- Standard header ------------------------------------------------------

		GET	libs:header
		GET	libs:swis

		GET	libs:stream

;----- External dependencies ------------------------------------------------

		GET	sapphire:akbd
		GET	sapphire:idle
		GET	sapphire:intKeys
		GET	sapphire:sapphire
		GET	sapphire:screen
		GET	sapphire:win

;----- Main code ------------------------------------------------------------

		AREA	|Sapphire$$Code|,CODE,READONLY

; --- drag_start ---
;
; On entry:	R0 == window containing the drag
;		R1 == flags word (see flags below)
;		R2 == pointer to drag routine
;		R3 == magic number to pass in R9
;		R4 == value to pass to routine in R10
;		R5 == value to pass to routine in R12
;
; On exit:	--
;
; Use:		Starts a drag operation.  Any outstanding drag operation
;		is cancelled on the assumption that someone stole our
;		UserDragBox event.

		EXPORT	drag_start
drag_start	ROUT

		STMFD	R13!,{R0-R7,R12,R14}	;Save some registers
		WSPACE	drag__wSpace		;Find my workspace address

		; --- Cancel any current drag operation ---

		LDR	R14,drag__window	;Load current window
		CMP	R14,#0			;Is there one defined?
		BLNE	drag_cancel		;Yes -- cancel it then

		; --- Ensure that this isn't a silly ---
		;
		; Rather irritatingly, the WIMP's drag-detection is a little
		; suspect; it thinks that moving the pointer outside of
		; a window while the button is held down is actually a drag.
		; We try to hack around this little problem.

		SWI	OS_Mouse		;Read the current mouse pos.
		CMP	R2,#0			;Are any buttons pressed?
		LDMEQFD	R13!,{R0-R7,R12,PC}^	;No -- do nothing then

		; --- Set up handlers for new drag op ---

		MOV	R0,#0			;Call me very often please
		ADR	R1,drag__idles		;Point to the handler
		MOV	R2,#0			;Nothing to pass in R10
		MOV	R3,R12			;Pass workspace in R12
		BL	idle_handler		;Install the handler
		LDMVSFD	R13!,{R0-R7,R12,PC}^	;If it failed, return now

		; --- Set up all the new information ---

		LDMIA	R13,{R0-R3}		;Load information off stack
		STMIA	R12,{R0-R5}		;Save all that lot away

		MOV	R0,#&3F	 		;Reset the dash pattern
		STRB	R0,drag__dash		;This is the current dash
		STRB	R0,drag__oldDash	;And the previous one
		BL	drag_setDash		;Make it the current pattern

		SWI	OS_ReadMonotonicTime	;Find the current time
		STR	R0,drag__lastTime	;And store that away too

		; --- Now read the current position of the drag ---

		SUB	R13,R13,#44		;Make space for window state
		LDR	R14,drag__window	;Load the window handle
		STR	R14,[R13,#0]		;Save it in the block
		MOV	R1,R13			;Point to this block
		SWI	Wimp_GetWindowState	;Read the window's position

		BL	drag__find		;Find the current position
		ADR	R14,drag__startPos	;Point to the current posn
		STMIA	R14!,{R4,R5}		;Load the coordinates out
		STMIA	R14!,{R4,R5}		;Store them in start position

		MOV	R0,#drEvent_draw	;Do some drawing please
		BL	drag__draw		;And draw the dash box
		ADD	R13,R13,#44		;Restore the stack pointer
		LDMFD	R13!,{R0-R7,R12,PC}^	;Return to caller finally

		LTORG

; --- drag_scroll ---
;
; On entry:	R1 == pointer to window state block
;
; On exit:	R2,R3 == new scroll positions to set
;		R14 == R1+20 (pointer to scroll offsets)
;
; Use:		Works out the scroll positions which should be set to auto-
;		scroll the window.  The algorithm is simple: the window is
;		scrolled so that the point beneath the mouse pointer is
;		within the window's visible work area.

		EXPORT	drag_scroll
drag_scroll	ROUT

		STMFD	R13!,{R0,R1,R4-R7,R14}	;Save some registers

		; --- Find the mouse pointer position ---

		LDMIB	R1!,{R4-R7}		;Load the bounding box out
		LDMIB	R1!,{R2,R3}		;And the current scroll pos
		SUB	R13,R13,#20		;Make a PointerInfo block
		MOV	R1,R13			;Point at this
		SWI	Wimp_GetPointerInfo	;Read the information
		LDMIA	R13,{R0,R1}		;Load the current position

		; --- Now fiddle the scroll positions ---

		SUBS	R14,R0,R4		;Compare x to left side
		ADDLT	R2,R2,R14		;If too far left, then scroll
		SUBS	R14,R1,R5		;Compare y to bottom
		ADDLT	R3,R3,R14		;If too low, then scroll
		SUBS	R14,R0,R6		;Compare x to right side
		ADDGT	R2,R2,R14		;If too far right, scroll
		SUBS	R14,R1,R7		;Compare y to top
		ADDGT	R3,R3,R14		;If too high, then scroll

		; --- Return everything to caller ---

		ADD	R13,R13,#20		;Restore the stack pointer
		LDR	R14,[R13,#4]		;Load the pointer out
		ADD	R14,R14,#20		;Point to scroll offsets
		LDMFD	R13!,{R0,R1,R4-R7,PC}^	;And return to caller

		LTORG

; --- drag__dispatch ---
;
; On entry:	R0 == event code
;		R1-R7 depend on event
;
; On exit:	--
;
; Use:		Dispatches a drag event to the current handler.

drag__dispatch	ROUT

		STMFD	R13!,{R8-R10,R12,R14}	;Save some registers
		ADR	R14,drag__handler	;Point to the handler
		LDMIA	R14,{R8-R10,R12}	;Load the registers out
		MOV	R14,PC			;Set up return address
		MOV	PC,R8			;Call the routine nicely
		LDMFD	R13!,{R8-R10,R12,PC}^	;And return to caller

		LTORG

; --- drag__draw ---
;
; On entry:	R0 == event code to pass
;		R1 == pointer to window state block (44 bytes required)
;
; On exit:	--
;
; Use:		Updates a window using the given event.

drag__draw	ROUT

		STMFD	R13!,{R0-R9,R14}	;Save some registers
		MOV	R8,R0			;Look after the event code
		LDR	R9,[R1,#28]		;Load the `behind' pointer

		; --- Build the update block ---

		LDMIB	R1,{R2-R5,R7,R14}	;Load the values out of it

		SUB	R6,R2,R7		;Find the x origin position
		SUB	R4,R4,R2		;Find the window width
		MOV	R2,R7			;Get left side of update box
		ADD	R4,R2,R4		;Get right side of update box

		SUB	R7,R5,R14		;Find the y origin position
		SUB	R3,R5,R3		;Find the window height
		MOV	R5,R14			;Get top of update box
		SUB	R3,R5,R3		;Get bottom of update box

		STMIB	R1,{R2-R5}		;Save the box back

		; --- Set up other registers for the job ---

		ADR	R14,drag__startPos	;Find the start position
		LDMIA	R14,{R2-R5}		;Load the positions out

		; --- Finally do the actual update ---

		SWI	Wimp_UpdateWindow	;Start the update job
		CMP	R0,#0			;Is there anything to do?
		BEQ	%90drag__draw		;No -- then skip ahead

00		MOV	R0,R8			;Get caller's event code
		BL	drag__dispatch		;Call the event handler
		SWI	Wimp_GetRectangle	;Get the next rectangle
		CMP	R0,#0			;Is there anything left?
		BNE	%b00			;Yes -- loop back to do it

		; --- Tidy up and return to caller ---

90drag__draw	STR	R9,[R1,#28]		;Store `behind' pointer back
		LDMFD	R13!,{R0-R9,PC}^	;And return to caller

		LTORG

; --- drag__find ---
;
; On entry:	R1 == pointer to window state block
;
; On exit:	R4,R5 == coordinates, suitably transformed
;		R6,R7 == window origin coordinates
;		CS if mouse button still down, else CC
;
; Use:		Locates the mouse pointer within the window.

drag__find	ROUT

		STMFD	R13!,{R0-R3,R14}	;Save some registers
		MOV	R2,R1			;Remember initial pointer
		SUB	R13,R13,#20		;Make space for pointer info
		MOV	R1,R13			;Point to this block
		SWI	Wimp_GetPointerInfo	;Find the pointer position
		MOV	R1,R2			;Point to original block

		; --- Set up for calling event handler ---

		LDR	R2,[R1,#4]		;Load the left hand side
		ADD	R14,R1,#16		;Find top and scroll position
		LDMIA	R14,{R5-R7}		;Load them out nicely
		SUB	R6,R2,R6		;Find the x origin position
		SUB	R7,R5,R7		;And the y origin position

		LDMIA	R13,{R4,R5}		;Load the coordinates out
		SUB	R4,R4,R6		;Translate to window coords
		SUB	R5,R5,R7		;Do that to y coord too
		MOV	R0,#drEvent_trans	;Get handler to translate
		BL	drag__dispatch		;Go and do that then

		; --- Tidy up and return ---

		LDR	R14,[R13,#8]		;Load the mouse status
		CMP	R14,#0			;Are all buttons released?
		ADD	R13,R13,#20		;Restore the stack block
		LDMFD	R13!,{R0-R3,R14}	;Restore registers
		ORRNES	PC,R14,#C_flag		;If button pressed, return CS
		BICEQS	PC,R14,#C_flag		;Else return CC

		LTORG

; --- drag__getPosition ---
;
; On entry:	R1 == pointer to window state block
;		R4,R5 == new position
;		R6,R7 == window origin position
;
; On exit:	R4,R5 == new position, translated further
;
; Use:		Reads the position of the current drag operation.  This
;		allows the client to do clever things like gridlocking and
;		autoscrolling.

drag__getPosition ROUT

		STMFD	R13!,{R0,R2,R3,R14}	;Save some registers
		ADR	R14,drag__startPos	;Find the start position
		LDMIA	R14,{R2,R3}		;Load those coordinates out
		MOV	R0,#drEvent_getPos	;Tell client to translate
		BL	drag__dispatch		;Send the event off
		LDMFD	R13!,{R0,R2,R3,PC}^	;And return to caller

		LTORG

; --- drag_setDash ---
;
; On entry:	R0 == dash pattern byte
;
; On exit:	--
;
; Use:		Sets the dash pattern to be the given value.

		EXPORT	drag_setDash
drag_setDash	ROUT

		STMFD	R13!,{R0-R2,R14}	;Save some registers

		; --- Build VDU block ---

		AND	R0,R0,#&FF		;Clear top bits of R0
		ORR	R1,R0,R0,LSL #8		;Duplicate the byte
		ORR	R1,R1,R1,LSL #16	;Fill a word with it
		MOV	R0,#23			;Get the VDU command code
		ORR	R0,R0,#6<<8		;OR in the command type
		ORR	R0,R0,R1,LSL #16	;Put in first two patterns
		MOV	R2,R1,LSR #16		;Put in last two patterns
		STMIA	R11,{R0-R2}		;Save that on the stack

		; --- Set the dash pattern length ---

		MOV	R0,#163			;Write general graphics info
		MOV	R1,#242			;Set dash pattern length
		MOV	R2,#8			;Set the repeat length
		SWI	OS_Byte			;Set the length then

		; --- Now set the dash pattern itself ---

		MOV	R0,R11			;Point to my VDU block
		MOV	R1,#10			;Size of block in bytes
		SWI	OS_WriteN		;Write that to the VDU things
		LDMFD	R13!,{R0-R2,PC}^	;And return to caller

		LTORG

; --- drag__idles ---
;
; On entry:	--
;
; On exit:	--
;
; Use:		Handles idle events during a drag operation.

drag__idles	ROUT

		STMFD	R13!,{R0-R7,R14}	;Save some registers

		; --- Check for a cancelled drag ---

		MOV	R0,#intk_Esc		;Get the Escape kep code
		BL	akbd_test		;Test the key
		BCS	%70drag__idles		;Cancelled -- abort it then

		; --- Update the dash pattern ---

		SWI	OS_ReadMonotonicTime	;Read the current time
		LDR	R14,drag__lastTime	;Load the old time nicely
		SUB	R0,R0,R14		;Find the difference
		MOV	R0,R0,LSR #2		;Divide by 4
		ADD	R14,R14,R0,LSL #2	;Add on rounded value
		STR	R14,drag__lastTime	;Save that back

		LDRB	R14,drag__dash		;Load the dash position
		STRB	R14,drag__oldDash	;This is now the old one
		MOV	R0,R0,LSL #1		;Multiply difference by 2
		MOV	R0,R14,ROR R0		;Rotate the dash pattern
		ORR	R0,R0,R0,ROR #24	;Fake an 8-bit rotate
		ORR	R0,R0,R0,ROR #16	;Make sure it's done properly
		STRB	R0,drag__dash		;This is the new pattern

		; --- Read the new position ---

		SUB	R13,R13,#44		;Make a window state block
		LDR	R14,drag__window	;Load the window handle out
		STR	R14,[R13,#0]		;Store handle in there
		MOV	R1,R13			;Point to the block
		SWI	Wimp_GetWindowState	;Read the window information

		BL	drag__find		;Find the new position
		BL	drag__getPosition	;Do any exra processing reqd
		BCC	%50drag__idles		;If done, skip onwards

		; --- Work out what needs to be done ---

		ADR	R14,drag__currPos	;Find the current position
		LDMIA	R14,{R2,R3}		;Load that out
		CMP	R2,R4			;Has the drag box moved?
		CMPEQ	R3,R5			;Check both coordinates
		BEQ	%30drag__idles		;No -- handle speciallt

		; --- Force the update of the drag box ---

		LDRB	R0,drag__oldDash	;Get the old dash pattern
		BL	drag_setDash		;Set this as the pattern
		MOV	R0,#drEvent_undraw	;Tell client to undraw
		BL	drag__draw		;Go and do that then

		; --- Now draw the new one ---

		ADR	R14,drag__currPos	;Find the current position
		STMIA	R14,{R4,R5}		;Save new position in there
		LDRB	R0,drag__dash		;Load the new dash pattern
		BL	drag_setDash		;Set this as the pattern
		MOV	R0,#drEvent_draw	;Tell client to draw
		BL	drag__draw		;Go and do that then
		B	%90drag__idles		;Now go and tidy up

		; --- Update the drag box in place ---

30drag__idles	LDR	R14,drag__flags		;Load any interesting flags
		TST	R14,#drFlag_noUpdate	;Do we send update events?
		BNE	%90drag__idles		;No -- then do nothing

		LDR	R0,drag__oldDash	;Load the two dash patterns
		EOR	R0,R0,R0,LSR #8		;Exclusive OR them together
		BL	drag_setDash		;Set this as the pattern
		MOV	R0,#drEvent_update	;Tell client to update drag
		BL	drag__draw		;Go and do that then
		B	%90drag__idles		;Now go and tidy up

		; --- Tidy up at the end of the drag ---

50drag__idles	LDRB	R0,drag__oldDash	;Get the old dash pattern
		BL	drag_setDash		;Set this as the pattern
		MOV	R0,#drEvent_undraw	;Now remove the drag box
		BL	drag__draw		;Go and do that then

		ADR	R14,drag__startPos	;Point to start position
		LDMIA	R14,{R2-R5}		;Load all that lot
		MOV	R0,#drEvent_done	;Say it's all over
		BL	drag__dispatch		;Send that to the user

		; --- Remove this idle handler ---

		MOV	R0,#0			;We're called very often
		ADR	R1,drag__idles		;Point to the handler
		MOV	R2,#0			;Passed nothing in R10
		MOV	R3,R12			;Passed workspace in R12
		BL	idle_removeHandler	;Remove the handler

		MOV	R14,#0			;A convenient zero
		STR	R14,drag__window	;Clear the window handle

		B	%90drag__idles		;Now go and tidy up

		; --- Cancel the drag ---

70drag__idles	BL	drag_cancel		;Cancel the drag
		B	%95drag__idles		;Now go and tidy up

		; --- Now tidy up and go home ---

90drag__idles	ADD	R13,R13,#44		;Recover any lost stack space
95drag__idles	LDMFD	R13!,{R0-R7,PC}^	;And return to caller

		LTORG

; --- drag_cancel ---
;
; On entry:	--
;
; On exit:	--
;
; Use:		Cancels the current drag operation.

		EXPORT	drag_cancel
drag_cancel	ROUT

		STMFD	R13!,{R0-R3,R12,R14}	;Save some registers
		WSPACE	drag__wSpace		;Find my workspace

		; --- Make sure this is worth it ---

		LDR	R14,drag__window	;Load current drag window
		CMP	R14,#0			;Is it defined?
		LDMEQFD	R13!,{R0-R3,R12,PC}^	;No -- then do nothing

		; --- Undraw the drag box ---

		SUB	R13,R13,#44		;Drop the stack by a bit
		LDR	R14,drag__window	;Load the window handle out
		STR	R14,[R13,#0]		;Store handle in there
		MOV	R1,R13			;Point to the block
		SWI	Wimp_GetWindowState	;Read the window information
		LDR	R0,drag__dash		;Load the current dash pos
		BL	drag_setDash		;Set the dash pattern
		MOV	R0,#drEvent_undraw	;Undraw the drag box
		BL	drag__draw		;Go and do that then
		MOV	R0,#drEvent_cancel	;Say the drag was cancelled
		BL	drag__dispatch		;Inform the client of this

		; --- Now tidy up and return ---

		MOV	R0,#0			;We're called very often
		ADR	R1,drag__idles		;Point to the handler
		MOV	R2,#0			;Passed nothing in R10
		MOV	R3,R12			;Passed workspace in R12
		BL	idle_removeHandler	;Remove the handler

		MOV	R14,#0			;A convenient zero
		STR	R14,drag__window	;Clear the window handle

		ADD	R13,R13,#44		;Restore the stack pointer
		LDMFD	R13!,{R0-R3,R12,PC}^	;And return to caller

		LTORG

; --- drag_redraw ---
;
; On entry:	R1 == pointer to redraw block
;
; On exit:	--
;
; Use:		Redraws the drag box, if the redraw takes place in the
;		currently dragging window.

		EXPORT	drag_redraw
drag_redraw	ROUT

		STMFD	R13!,{R0-R7,R12,R14}	;Save some registers
		WSPACE	drag__wSpace		;Find the workspace address

		; --- Make sure there's something to do ---

		LDR	R0,[R1,#0]		;Load the window handle
		LDR	R14,drag__window	;Load current drag window
		CMP	R0,R14			;Do these match up?
		LDMNEFD	R13!,{R0-R7,R12,PC}^	;No -- do nothing then

		; --- Set up registers ---

		LDR	R2,[R1,#4]		;Load left hand side
		ADD	R14,R1,#16		;Find top and scroll
		LDMIA	R14,{R5-R7}		;Load that lot out
		SUB	R6,R2,R6		;Find the x origin pos
		SUB	R7,R5,R7		;And the y origin pos
		ADR	R14,drag__startPos	;Find the start position
		LDMIA	R14,{R2-R5}		;Load position out nicely

		; --- Now do the drawing ---

		LDRB	R0,drag__dash		;Load current dash pattern
		BL	drag_setDash		;Set the dash pattern
		MOV	R0,#drEvent_draw	;Now do some drawing
		BL	drag__dispatch		;Send to event handler
		LDMFD	R13!,{R0-R7,R12,PC}^	;Now return to caller

		LTORG

; --- drag_eorColour ---
;
; On entry:	R0 == colour A
;		R1 == colour B
;
; On exit:	--
;
; Use:		Sets the foreground colour to be an EOR colour such that
;		when painted over Wimp colour A, it appears as Wimp colour B.

		EXPORT	drag_eorColour
drag_eorColour	ROUT

		STMFD	R13!,{R0-R3,R14}	;Save some registers
		MOV	R2,R0,LSL #2		;Keep the background colour
		MOV	R3,R1,LSL #2		;And the foreground colour
		MOV	R1,R11			;Point to the block
		SWI	Wimp_ReadPalette	;Read the current palette
		LDR	R0,[R11,R2]		;Load the fore palette entry
		SWI	ColourTrans_ReturnColourNumber
		MOV	R2,R0			;Save the colour number
		LDR	R0,[R11,R3]		;Load the back palette entry
		SWI	ColourTrans_ReturnColourNumber
		EOR	R1,R0,R2		;Get the EOR colour number
		MOV	R0,#3			;Set EOR colour please
		SWI	XOS_SetColour		;Set the colour, please
		BVC	%90drag_eorColour	;If it worked, return

		; --- We must be running RISC OS 2 ---
		;
		; This is very tedious -- we have to set the colour by hand.

		BL	screen_getInfo		;Read the screen cache
		LDR	R0,[R0,#screen_bpp]	;Load the current BPP
		CMP	R0,#8			;Are we in a 256 colour mode?
		BEQ	%50drag_eorColour	;Yes -- handle it specially

		; --- Just set the GCOL from R1 ---

		SWI	OS_WriteI+18		;Set graphics colour
		SWI	OS_WriteI+3		;Use XOR colour
		MOV	R0,R1			;Get the colour to set
		SWI	OS_WriteC		;Set the colour
		B	%90drag_eorColour	;Return -- we did it

		; --- Set the colour in a 256 colour mode ---

50		MOV	R0,R1			;Get colour in R0
		SWI	ColourTrans_ColourNumberToGCOL
		MOV	R1,R0			;Keep the GCOL safe
		SWI	OS_WriteI+18		;Set graphics colour
		SWI	OS_WriteI+3		;Use XOR colour
		MOV	R0,R1,LSR #2		;Get the GCOL part of it
		SWI	OS_WriteC		;Set the colour

		; --- Now set the tint ---

		MOV	R0,#23			;VDU code for tint setting
		ORR	R0,R0,#17<<8		;Subreason code for tint
		ORR	R0,R0,#2<<16		;Set the graphics foreground
		ORR	R0,R0,R1,LSL #30	;Get the tint bits in too
		MOV	R1,#0			;Other bytes are all 0
		MOV	R2,#0			;Two words of them
		STMIA	R11,{R0-R2}		;Save them in scratchpad
		MOV	R0,R11			;Point at them
		MOV	R1,#10			;VDU 23 is 10 bytes long
		SWI	OS_WriteN		;Write the whole lot out

90		LDMFD	R13!,{R0-R3,PC}^

		LTORG

drag__wSpace	DCD	0

;----- Flags ----------------------------------------------------------------

drFlag_noUpdate	EQU	(1<<0)			;Don't generate update events

;----- Drag handler events --------------------------------------------------

; --- Note ---
;
; The events which request that you draw something are called for each
; rectangle of the draw operation -- i.e. do not call Wimp_GetRectangle
; because this is done for you.

		^	0
drEvent_draw	#	1			;Draw dragged object
						;R1 == pointer to redraw blk
						;R2,R3 == drag start posn
						;R4,R5 == drag current posn
						;R6,R7 == window origin
						;Dash pattern set up

drEvent_undraw	#	1			;Undraw dragged object
						;Regs as for drEvent_draw
						;Normally use the same code

drEvent_update	#	1			;Redraw dragged object in
						;place
						;Regs as for drEvent_draw
						;Dash pattern set up so that
						;single plot will rotate box,
						;so may share code with
						;drEvent_draw

drEvent_trans	#	1			;Translate coordinates
						;R1 == ptr to window state
						;R4,R5 == pointer position
						;R6,R7 == window origin
						;Translate pointer position
						;to internal coordinates if
						;this is useful to you.
						;Return new coords in R4,R5

drEvent_getPos	#	1			;Read pointer position
						;R1 == ptr to window state
						;R2,R3 == start position
						;R4,R5 == pointer position
						;R6,R7 == window origin
						;Used to read pointer posn.
						;Do any grid snapping here
						;and return with R4,R5 as
						;coords to use.

drEvent_done	#	1			;Drag operation completed
						;R1 == ptr to window state
						;R2,R3 == drag start posn
						;R4,R5 == drag current posn

drEvent_cancel	#	1			;Drag operation aborted
						;No other registers set up

;----- Workspace ------------------------------------------------------------

		^	0,R12
drag__wStart	#	0

drag__window	#	4			;Window handle of drag
drag__flags	#	4			;Various interesting flags
drag__handler	#	16			;All the handler information
drag__oldDash	#	1			;The old dash pattern
drag__dash	#	1			;The current dash pattern
		#	2			;Align to word boundary
drag__lastTime	#	4			;Last time we changed pattern
drag__startPos	#	8			;Find the start position
drag__currPos	#	8			;Find the end position

drag__wSize	EQU	{VAR}-drag__wStart

		AREA	|Sapphire$$LibData|,CODE,READONLY

		DCD	drag__wSize
		DCD	drag__wSpace
		DCD	0
		DCD	0

;----- That's all, folks ----------------------------------------------------

		END
