/*
 * dbox.h
 *
 * [Generated from dbox, 25 September 1996]
 */

#if !defined(__CC_NORCROFT) || !defined(__arm)
  #error You must use the Norcroft ARM Compiler for Sapphire programs
#endif

#pragma include_only_once
#pragma force_top_level

#ifndef __dbox_h
#define __dbox_h

#ifndef __sapphire_h
  #include "sapphire.h"
#endif

/*----- Overview ----------------------------------------------------------*
 *
 * Functions provided:
 *
 *  dbox_create
 *  dbox_fromEmbedded
 *  dbox_fromDefn
 *  dbox_destroy
 *  dbox_init
 *  dbox_open
 *  dbox_close
 *  dbox_writePos
 *  dbox_select
 *  dbox_shade
 *  dbox_selectMany
 *  dbox_shadeMany
 *  dbox_isSelected
 *  dbox_radio
 *  dbox_slab
 *  dbox_unslab
 *  dbox_setField
 *  dbox_getField
 *  dbox_eventHandler
 *  dbox_renderTitle
 *  dbox_setEmbeddedTitle
 *  dbox_setClickDrag
 *  dbox_hasTitle
 *  dbox_window
 *  dbox_help
 */

/* --- dbox_create --- *
 *
 * On entry:	R0 == pointer to dialogue template name
 *
 * On exit:	R0 == dialogue box handle for the dialogue
 *		May return an error
 *
 * Use:		Creates a dialogue box from a template definition.
 */

extern routine dbox_create;

/* --- dbox_fromEmbedded --- *
 *
 * On entry:	R0 == pointer to an embedded template
 *
 * On exit:	R0 == dialogue box handle
 *		May return an error
 *
 * Use:		Creates a dialogue box from an embedded template definition.
 */

extern routine dbox_fromEmbedded;

/* --- dbox_fromDefn --- *
 *
 * On entry:	R0 == pointer to a window definition
 *
 * On exit:	R0 == dialogue box handle for the dialogue
 *		May return an error
 *
 * Use:		Creates a dialogue box from an immediate window definition,
 *		rather than a template.  There are several things you need
 *		to be aware of when you use this call to create a dialogue
 *		box:
 *
 *		* The window definition is not copied, but used directly
 *		  for the duration the dialogue box exists.  It must
 *		  not move for this duration.  When the dialogue is
 *		  destroyed, you can release the memory for the definition,
 *		  although this is your responsibility.
 *
 *		* The indirected data is not copied either, so you'll have
 *		  to copy it yourself if you want multiple dialogues from
 *		  the same window definition.
 *
 *		* The window definition and the indirected data must both
 *		  be writable.
 */

extern routine dbox_fromDefn;

/* --- dbox_destroy --- *
 *
 * On entry:	R0 == dialogue box handle
 *
 * On exit:	--
 *
 * Use:		Destroys a dialogue box, freeing all the memory it took
 *		up etc.
 */

extern routine dbox_destroy;

/* --- dbox_init --- *
 *
 * On entry:	--
 *
 * On exit:	--
 *
 * Use:		Initialises the dbox system.
 */

extern routine dbox_init;

/* --- dbox_open --- *
 *
 * On entry:	R0 == dialogue box handle
 *		R1 == how to open the dialogue box
 *		Other registers depend on R1, and are described at the end
 *		of this header file
 *
 * On exit:	--
 *
 * Use:		Displays the dialogue box on the screen in the given manner.
 */

extern routine dbox_open;

/* --- dbox_close --- *
 *
 * On entry:	R0 == dialogue box handle
 *
 * On exit:	--
 *
 * Use:		Closes a dialogue box, by clearing the current menu if
 *		necessary.
 */

extern routine dbox_close;

/* --- dbox_writePos --- *
 *
 * On entry:	R0 == dialogue box handle
 *
 * On exit:	--
 *
 * Use:		Saves the dialogue's current position so that it will be
 *		opened here the next time it is created.  If the dialogue
 *		box was created from a template, the template is updated.
 *		Otherwise, the new state is written back to the definition
 *		supplied to dbox_fromDefn.
 */

extern routine dbox_writePos;

/* --- dbox_select --- *
 *
 * On entry:	R0 == dialogue box handle
 *		R1 == icon number
 *		R2 == 0 to deselect the icon, 1 to select it, 2 to toggle
 *		      its current selected state
 *
 * On exit:	--
 *
 * Use:		Selects or deselects the specified icon in the Acorn sense
 *		(i.e. by flipping its selected bit).  The state is only
 *		changed if required, to reduce flicker.
 */

extern routine dbox_select;

/* --- dbox_shade --- *
 *
 * On entry:	R0 == dialogue box handle
 *		R1 == icon number
 *		R2 == 0 to unshade the icon, 1 to shade it, 2 to toggle its
 *		      current shaded state
 *
 * On exit:	--
 *
 * Use:		Makes the icon look dimmer, to indicate that it is not
 *		available.  It uses its own shading algorithms, rather than
 *		the WindowManager's, so there are some things you must watch
 *		out for:
 *
 *		* Don't use any other method of shading icons
 *
 *		* Don't assume that a shaded icon isn't going to give you
 *		  events.  At the user level, this should have been tidied
 *		  up, but at the Sapphire level, it's still a problem.
 *		  There is a routine in winUtils which will tell you if an
 *		  icon is shaded.
 *
 *		This routine has been written so that it only flickers icons
 *		when they actually need it.
 */

extern routine dbox_shade;

/* --- dbox_selectMany --- *
 *
 * On entry:	R0 == dialogue box handle
 *		R1 == pointer to icon handle list, -1 terminated
 *		R2 == select action (0 == unselect, 1 == select, 2 == toggle)
 *
 * On exit:	--
 *
 * Use:		Changes the select state of a group of icons.
 */

extern routine dbox_selectMany;

/* --- dbox_shadeMany --- *
 *
 * On entry:	R0 == dialogue box handle
 *		R1 == pointer to icon handle list, -1 terminated
 *		R2 == shade action (0 == unshade, 1 == shade, 2 == toggle)
 *
 * On exit:	--
 *
 * Use:		Changes the shade state of a group of icons.
 */

extern routine dbox_shadeMany;

/* --- dbox_isSelected --- *
 *
 * On entry:	R0 == dialogue box handle
 *		R1 == icon number
 *
 * On exit:	CS if the icon is selected, CC otherwise
 *
 * Use:		Returns whether an icon is currently selected.
 */

extern routine dbox_isSelected;

/* --- dbox_radio --- *
 *
 * On entry:	R0 == dialogue box handle
 *		R1 == icon handle
 *
 * On exit:	--
 *
 * Use:		Checks to see if the icon is a radio button as defined by
 *		Sapphire, i.e. button type 3 (debounced) and non-zero ESG.
 *		If it is, it selects it, and deselects all other icons with
 *		this ESG.
 */

extern routine dbox_radio;

/* --- dbox_slab --- *
 *
 * On entry:	R0 == dialogue box handle
 *		R1 == icon handle
 *
 * On exit:	May return an error
 *
 * Use:		Slabs an icon in properly, to give visual feedback when you
 *		click it.
 */

extern routine dbox_slab;

/* --- dbox_unslab --- *
 *
 * On entry:	--
 *
 * On exit:	CS if there are no more slabbed icons after this one, CC
 *		if there are more left.
 *
 * Use:		Unslabs an icon slabbed with dbox_slab.  Icons are unslabbed
 *		in reverse order to that in which they were slabbed.  The
 *		carry flag is returned as an indication of whether there
 *		are any more icons left in the list -- you can unslab all
 *		icons in one go by doing:
 *
 *				BL	dbox_unslab
 *				SUBCC	PC,PC,#12	;Avoids a label!
 *
 *		It is recommended that, if you are going to close a window,
 *		you unslab icons within it *after* you close, but before you
 *		actually destroy it, e.g.
 *
 *				LDR	R0,my_dbox
 *				BL	dbox_close
 *				BL	dbox_unslab
 *				BL	dbox_destroy
 */

extern routine dbox_unslab;

/* --- dbox_setField --- *
 *
 * On entry:	R0 == dialogue box handle
 *		R1 == icon number to write to (may be -1 for title)
 *		      flags in top byte if not -1:
 *			dbFlag_dots (bit 31) == add `...' if text overflows
 *		R2 == pointer to string to use
 *
 * On exit:	--
 *
 * Use:		Writes the string specified into the indirection buffer
 *		for the given icon.  If the icon is not indirected, an
 *		error is generated.  If the indirected buffer is too small,
 *		the string is shortened by chopping off the beginning or
 *		the end, according to the setting of the icon's right
 *		justify flag.
 *
 *		The icon is only flickered if the text has actually changed.
 *		The caret is moved correctly if it is within the icon to
 *		prevent it `falling off' the end and deleting the validation
 *		string, or being positioned incorrectly in centred icons if
 *		the length changes.
 *
 *		Note that this routine requires a string to already be in
 *		the buffer, and doesn't perform any substitution or other
 *		transformations.  This helps to prevent buffer full errors
 *		and similar problems.
 */

extern routine dbox_setField;

/* --- dbox_getField --- *
 *
 * On entry:	R0 == dialogue box handle
 *		R1 == icon number to interrogate
 *
 * On exit:	R0, R1 preserved
 *		R2 == pointer to the icon text
 *
 * Use:		Returns a pointer to the text associated with an icon.
 *		Note that if the icon is *not* indirected, the text will
 *		be copied into the scratchpad.  Otherwise you get a pointer
 *		to the actual indirected data.  You shouldn't write to the
 *		string returned at all -- dbox_setField is specially
 *		designed to do that sort of thing very well (i.e. not
 *		flickering the text unless it has to, truncating if it's too
 *		long, and handling the caret correctly).  You *are* allowed
 *		to zero	terminate the string if you want to, though.
 *
 *		Despite all the PRM's assurances to the contrary, chances
 *		are the text will be terminated by some weird control char,
 *		so you'll have to handle this, and not just assume it's
 *		going to be null-terminated.
 *
 *		Note: The indirected case is immensely quick -- just load a
 *		pointer.  The non-indirected case has been optimised as much
 *		as possible.
 */

extern routine dbox_getField;

/* --- dbox_eventHandler --- *
 *
 * On entry:	R0 == dialogue box handle
 *		R1 == pointer to handler routine
 *		R2 == value to pass to handler in R10
 *		R3 == value to pass to handler in R12
 *
 * On exit:	R0 preserved
 *		R1 == pointer to old handler
 *		R2 == old R10 value
 *		R3 == old R12 value
 *
 * Use:		Sets up an event handler for a dialogue box, and returns
 *		the previous one.  If the pointer to handler is 0, there is
 *		no dialogue box event handler.
 */

extern routine dbox_eventHandler;

/* --- dbox_renderTitle --- *
 *
 * On entry:	R0 == dialogue box handle
 *		R1 == pointer to redraw block
 *
 * On exit:	--
 *
 * Use:		Renders a dialogue box's embedded title if there is one.
 */

extern routine dbox_renderTitle;

/* --- dbox_setEmbeddedTitle --- *
 *
 * On entry:	R0 == dialogue box handle
 *		R1 == icon which should contain the embedded title
 *
 * On exit:	--
 *
 * Use:		Declares a given dialogue box as requiring an embedded title
 *		(rather than the one the WindowManager put on).
 */

extern routine dbox_setEmbeddedTitle;

/* --- dbox_setClickDrag --- *
 *
 * On entry:	R0 == dialogue box handle
 *
 * On exit:	--
 *
 * Use:		Sets a given dialogue box so that the user can move it by
 *		dragging from any part of the window, not just the title
 *		bar.
 */

extern routine dbox_setClickDrag;

/* --- dbox_hasTitle --- *
 *
 * On entry:	R0 == dialogue box handle
 *
 * On exit:	CS if the dialogue box has a title bar, CC if not
 *
 * Use:		Informs the caller whether the dialogue box has a title bar.
 *		This is mainly useful for other library sections which
 *		conditionally add in embedded titles etc.
 */

extern routine dbox_hasTitle;

/* --- dbox_window --- *
 *
 * On entry:	R0 == dialogue box handle
 *
 * On exit:	R0 == the dialogue box's window handle
 *
 * Use:		Returns the Wimp window handle associated with a dialogue
 *		box.  This may be useful if you want to perform lowlevel
 *		Wimp operation on it, or to subclass it using win.
 */

extern routine dbox_window;

/* --- dbox_help --- *
 *
 * On entry:	--
 *
 * On exit:	--
 *
 * Use:		Adds a help line to the current help message, read by
 *		scanning the icon to which the help was sent for an `H'
 *		validation string.
 */

extern routine dbox_help;

/*----- Useful constants --------------------------------------------------*/

/* --- Ways of opening dialogue boxes --- */

#define dbOpen_current 0
#define dbOpen_centre 1
#define dbOpen_pointer 2
#define dbOpen_givenY 3
#define dbOpen_givenXY 4

#define dbOpen_trans (0x00)
#define dbOpen_persist (0x80)
#define dbOpen_nonSub (0x40)

/* --- Dialogue box event codes --- */

#define dbEvent_close (-2)

#define dbEvent_help (-3)

#define dbEvent_OK (-4)

#define dbEvent_cancel (-5)

#define dbEvent_redraw (-6)

#define dbEvent_menu (-7)

#define dbEvent_drag (-8)

#define dbEvent_save (-9)

#define dbEvent_load (-10)

#define dbEvent_key (-11)

#define dbEvent_hint (-12)

#define dbEvent_enter (-13)

#define dbEvent_leave (-14)

/* --- Other values --- */

#define dbFlag_dots ((1<<31))

/*----- That's all, folks -------------------------------------------------*/

#endif
