The TextArea gadget has a boxed display area in which a block of text
is displayed and, if the appropriate flag is set, edited by the user.
The contents of the gadget can be set and read using the TextArea_SetText
and TextArea_GetText methods. The contents can be modified by inserting and
replacing text with the TextArea_InsertText and TextArea_ReplaceText methods.

There are no limits on the line length and overall text size, apart from
memory constraints.

The user can click the mouse in a text area and enter its value from the
keyboard. Dragging the mouse over the text with SELECT or ADJUST held down
selects text in the usual RISC OS manner. When the mouse is near the edges
of the gadget with a mouse button held down, the gadget will automatically
scroll.

The text for all gadgets is kept internally in a single dynamic area to
reduce overheads on the RMA. Since the text is multi-line, all strings are
NULL terminated, and can include carriage returns or linefeeds. Note that
a line terminator of CR/LF will [probably] be treated as two line feeds.

??? Should up arrow on top line move to the previous writable icon/text area?
??? (and same for down arrow on bottom line)

??? Should shift-TAB/TAB move to next/previous?

Bits in the flags word for a text area have the following meaning:

	Bit	Meaning when set
	0	gadget has a vertical scrollbar
	1	gadget has a horizontal scrollbar

The TextArea gadget requires the Window module, version 1.32 or greater.

Text area methods
=================

TextArea_GetState
-----------------
On entry
	R0 = flags
	R1 = Window object id
	R2 = ???
	R3 = Gadget component id

On exit
	R0 = state
		bit 0 set means gadget has a vertical scrollbar
		bit 1 set means gadget has a horizontal scrollbar

C veneer
extern _kernel_oserror *textarea_get_state(unsigned int flags,
			ObjectId object_id, ComponentId component_id,
			unsigned int *state);

TextArea_SetState
-----------------
On entry
	R0 = flags
	R1 = Window object id
	R2 = ???
	R3 = Gadget component id
	R4 = state
		bit 0 set means gadget has a vertical scrollbar
		bit 1 set means gadget has a horizontal scrollbar

On exit
	R1-R9 preserved

C veneer
extern _kernel_oserror *textarea_set_state(unsigned int flags,
			ObjectId object_id, ComponentId component_id,
			unsigned int state);

TextArea_SetText
----------------
On entry
	R0 = flags
	R1 = Window object id
	R2 = ???
	R3 = Gadget component id
	R4 = text

On exit
	R1-R9 preserved

C veneer
extern _kernel_oserror *textarea_set_text(unsigned int flags,
			ObjectId object_id, ComponentId component_id,
			const char *text);

TextArea_GetText
----------------
On entry
	R0 = flags
	R1 = Window object id
	R2 = ???
	R3 = Gadget component id
	R4 = pointer to buffer
	R5 = size of buffer

On exit
	R5 = size of buffer required to hold text (if R4 was 0)
		else buffer pointed at by R4 holds text
		R5 holds number of bytes written to buffer

C veneer
extern _kernel_oserror *textarea_get_text(unsigned int flags,
			ObjectId object_id, ComponentId component_id,
			char *buffer, int buff_size, int *nbytes);

TextArea_InsertText
-------------------
On entry
	R0 = flags
	R1 = Window object id
	R2 = ???
	R3 = Gadget component id
	R4 = index into text
	R5 = pointer to buffer

On exit
	R1-R9 preserved

C veneer
extern _kernel_oserror *textarea_insert_text(unsigned int flags,
			ObjectId object_id, ComponentId component_id,
			unsigned int index, const char *text);

TextArea_ReplaceText
--------------------
On entry
	R0 = flags
	R1 = Window object id
	R2 = ???
	R3 = Gadget component id
	R4 = selection start
	R5 = selection end
	R6 = pointer to buffer

On exit
	R1-R9 preserved

C veneer
extern _kernel_oserror *textarea_replace_text(unsigned int flags,
			ObjectId object_id, ComponentId component_id,
			unsigned int index_start, unsigned int index_end,
			const char *text);

TextArea_GetSelection
---------------------
On entry
	R0 = flags
		bit 0 set means return text rather than indexes
	R1 = Window object id
	R2 = ???
	R3 = Gadget component id
	R4 = pointer to buffer (only if bit 0 of R0 set)
	R5 = size of buffer (only if bit 0 of R0 set)

On exit
	R4 = index to start of selection (if bit 0 in R0 was set)
	R5 = index to end of selection (if bit 0 in R0 was set)
	else
	R5 = size of buffer required to hold selected text (if R4 was 0)
		else buffer pointed at by R4 holds selected text
		R5 holds number of bytes written to buffer

C veneers
extern _kernel_oserror *textarea_get_selection_text(unsigned int flags,
			ObjectId object_id, ComponentId component_id,
			char *buffer, int size, unsigned int *nbytes);

extern _kernel_oserror *textarea_get_selection_points(unsigned int flags,
			ObjectId object_id, ComponentId component_id,
			unsigned int *index_start, unsigned int *index_end);

TextArea_SetSelection
---------------------
On entry
	R0 = flags
	R1 = Window object id
	R2 = ???
	R3 = Gadget component id
	R4 = index to start of selection
	R5 = index to end of selection

On exit
	R1-R9 preserved

C veneer
extern _kernel_oserror *textarea_set_selection(unsigned int flags,
			ObjectId object_id, ComponentId component_id,
			unsigned int index_start, unsigned int index_end);

TextArea_SetFont
----------------
On entry
	R0 = flags
	R1 = Window object id
	R2 = ???
	R3 = Gadget component id
	R4 = pointer to font name to use
	R5 = width in 16th of a point
	R6 = height in 16th of a point

On exit
	R1-R9 preserved

Use

This method makes the text area use an anti-aliased font. If the font
name is NULL, then the text area will use the current desktop font (or
system font if unset)

C veneer
extern _kernel_oserror *textarea_set_font(unsigned int flags,
			ObjectId object_id, ComponentId component_id,
			const char *font, unsigned int width,
			unsigned int height);

TextArea_SetColour
------------------
On entry
	R0 = flags
		bit 0 set means use desktop colours rather than
			real colours (in the form &BBGGRR00)
	R1 = Window object id
	R2 = ???
	R3 = Gadget component id
	R4 = Colour value for foreground text (in the form &BBGGRR00,
		unless bit 0 of R0 is set)
	R5 = Colour value for background (in the form &BBGGRR00,
		unless bit 0 of R0 is set)

On exit
	R1-R9 preserved

C veneer
extern _kernel_oserror *textarea_set_colour(unsigned int flags,
			ObjectId object_id, ComponentId component_id,
			unsigned int foreground, unsigned int background);

TextArea_GetColour
------------------
On entry
	R0 = flags
	R1 = Window object id
	R2 = ???
	R3 = Gadget component id

On exit
	R0 = Colour value (in the form &BBGGRR00) of foreground
	R1 = Colour value (in the form &BBGGRR00) of background


C veneer
extern _kernel_oserror *textarea_get_colour(unsigned int flags,
			ObjectId object_id, ComponentId component_id,
			unsigned int *foreground, unsigned int *background);

TextArea_SetCursorPosition
--------------------------
On entry
	R0 = flags
	R1 = Window object id
	R2 = ???
	R3 = Gadget component id
	R4 = index into text for cursor

On exit
	R4 = old index

Use

This methods sets the cursor position in a TextArea, you pass it the
index you want to change to, and it will pass back the old index value.

If Bit 0 of the flags word is set the setting of the caret position is
forced.  If Bit 1 is set, the caret is set invisibly.

C veneer
extern _kernel_oserror *textarea_set_cursor_position(unsigned int flags,
			ObjectId object_id, ComponentId component_id,
			unsigned int index, unsigned int *new_index);


TextArea_GetCursorPosition
--------------------------
On entry
	R0 = flags
	R1 = Window object id
	R2 = ???
	R3 = Gadget component id

On exit
	R4 = index

Gets the index of the current cursor position in a TextArea.

C veneer
extern _kernel_oserror *textarea_get_cursor_position(unsigned int flags,
			ObjectId object_id, ComponentId component_id,
			unsigned int *index);


TextArea_SetTextBorder
----------------------
On entry
	R0 = flags
	R1 = Window object id
	R2 = ???
	R3 = Gadget component id
	R4 = Border size in OS units

On exit
	R1-R9 preserved

C veneer
extern _kernel_oserror *textarea_set_text_border(unsigned int flags,
			ObjectId object_id, ComponentId component_id,
			unsigned int border_size);

Bugs
----

Amongst many others, TextArea shares a bug in common with ScrollList.

Whilst the gadget reads the current mode's scale factors and the size of
the current Wimp tool sprites to accurately position its embedded window
within the defined gadget bounding box at create-time, it does not notice
if these values change. If tools or Desktop scaling alter, the gadget
will only notice when a new instance of a ScrollList is created. At this
point, existing ScrollLists will not resize, but will start using the new
values (since they're global to the module). At such a time as an interface
exists which allows external gadget modules to be told about Wimp messages,
this all gets fixed, as all gadgets can be resized appropriately - hence a
gadget-global record of the relevant details is OK.
