/* -> H.Arthur
 *
 *      Arthur specific functions for sound and window management
 *
 */

/******************************************************************************

        Graphics and general routines

******************************************************************************/
/* First structure def's */

typedef struct reg_set
{
        int r[10];               /* only r0 - r9 matter for swi's */
} reg_set;

typedef struct osfile_block
{
        int action;             /* action or object type if output data */
        char * name;            /* pointer to filename or pathname */
        int loadaddr, execaddr; /* load, exec addresses */
        int start, end;         /* start address/length, end add./attributes */
        int reserved[4];        /* space to allow treatment as reg_block */
} osfile_block;

typedef struct osgbpb_block
{
        int action;             /* specifies action of osgbpb */
        int file_handle;        /* file handle, but may be used as a char *
                                 * pointing to wildcarded dir-name */
        void * data_addr;       /* memory address of data */
        int number, seq_point, buf_len;
        char * wild_fld;        /* points to wildcarded filename to match */
        int reserved[3];        /* space to allow treatment as reg_block */
} osgbpb_block;

typedef struct error
{
        int errnum;             /* error number */
        char errmess[252];      /* error message (zero terminated) */
} error;


/*****************************************************************************/
/* Now the actual functions */

int adval(int);

void clg(void);

void cls(void);

void circle(int,int,int);

void circlefill(int,int,int);

void colour(int);

void draw(int,int);

void drawby(int,int);

void fill(int,int);

int get(void);

void gcol(int,int);

void gwindow(int,int,int,int);

int inkey(int);

void mode(int);

void move(int,int);

void moveby(int,int);

/* Note: the next 3 mouse functions should not be used with the wimp - use
 * the special ones provided with this */

int mouseX(void);

int mouseY(void);

int mouseB(void);

void cursor(int);

void origin(int,int);

void palette(int,int,int,int,int);

void plot(int,int,int);

int point(int,int);
 
int pos(void);

void rectangle(int,int,int,int);

void rectanglefill(int,int,int,int);

unsigned rnd(unsigned);

void stringprint(char *);

void tab(int,int);

void tint(int,int);

void vdu(int);

void vduw(int);

void vduq(int,...); 

int vpos(void);

reg_set swi(int, reg_set *);    /* general access to swi routines */

/* The following functions return a pointer to an error if it has occurred,
 * otherwise return NULL (0) */

error * swix(int, reg_set *);       /* as swi, but 1 reg. set, return error *
                                 * if error detected */

error * osbyte(reg_set *);

error * osword(int,void *);

error * osgbpb(osgbpb_block *);

error * osfile(osfile_block *);

error * osargs(reg_set *);

error * osfind(reg_set *);

/******************************************************************************

                Sound management

******************************************************************************/

void sound(int, int, int, int, int); /* make or schedule a sound - parameters
                                      * are channel, amplitude, pitch,
                                      * duration, future time -as basic, except
                                      * f. time = -2 implies unsynchronised */

void sound_on(void);            /* activate sound system */

void sound_off(void);           /* deactivate sound system */

void voices(int);               /* set number of sound channels (1,2,4 or 8 )*/

void stereo(int, int);          /* set stereo position for specified channel */

void set_beats(int);            /* set beat counter cycle length */

int get_beats(void);            /* read beat counter cycle length */

int get_beat(void);             /* read current beat value */

void set_tempo(int);            /* set rate at which beat counter counts */

int get_tempo(void);            /* read rate at which beat counter counts */



/******************************************************************************

        Window management

******************************************************************************/
/* #defines first */

/* The next #define defines the maximum number of items in a menu */

#define MAXITEMS        20              /* only 20 menu items allowed */

/* The following #defines define component bits of wind_block->flags */

#define TITLE_BAR       0x00000001      /* has title bar */
#define MOVEABLE        0x00000002      /* is moveable */
#define V_SCROLL_BAR    0x00000004      /* has vertical scroll bar */
#define H_SCROLL_BAR    0x00000008      /* has horizontal scroll bar */
#define REDRAW_OK       0x00000010      /* can be redrawn entirely by wimp
                                         * ie. no user graphics */
#define PANE            0x00000020      /* window is stuck over tool window */
#define TRESPASS        0x00000040      /* window is allowed to go outside
                                         * main area */
#define NO_BOXES        0x00000080      /* no back/quit boxes (title OK) */
#define SCROLL_R1       0x00000100      /* scroll request returned when
                                         * scroll button clicked- auto repeat*/
#define SCROLL_R2       0x00000200      /* as SCROLL_R1, debounced, no auto */

/* The following define status component bits of wind_block->flags */

#define OPEN            0x00010000      /* window is open */
#define TOP             0x00020000      /* window is top (not covered) */
#define FULL_SIZE       0x00040000      /* window is toggled to full size */

/* The following #defines define component bits of icon_block->flags */
/* Note that as well as the single bit flags defined in the first group */
/* of #defines below, there are flags made up of groups of bits, which */
/* contain type information - these are explained but not defined below */
/* the following #defines. */

#define TEXT            0x00000001      /* icon contains text */
#define SPRITE          0x00000002      /* icon is a sprite */
#define BORDER          0x00000004      /* icon has a border */
#define HOR_CENTRE      0x00000008      /* text is horizontally centred */
#define VER_CENTRE      0x00000010      /* text is vertically centred */
#define FILLED          0x00000020      /* icon has a filled background */
#define AA_FONT         0x00000040      /* text is an anti-aliased font */
#define AP_REDRAW       0x00000080      /* redraw needs application's help */
#define INDIRECT        0x00000100      /* icon data is 'indirected' */
#define RHT_JUST        0x00000200      /* text right justified in box */
#define ESG_NOCANCELL   0x00000400      /* if selected by right button, don't
                                         * cancel other icons in same ESG */
#define SELECTED        0x00200000      /* icon selected by user (inverted) */
#define NOSELECT        0x00400000      /* icon cannot be selected (shaded) */
#define DELETED         0x00800000      /* icon has been deleted */

/* The above #defines do not define all the bits in the icon_block->flags 
   integer - the rest have the following meanings:

Bits set in mask 0x0000F000: Button type - way icon responds to mouse clicks.
                             (See 'WIMPS' chapter in Technical Ref. Guide)

Bits set in mask 0x001F0000: Exclusive Selection Group number

Bits set in mask 0x0F000000: Foreground icon colour (or, with next, font no.).

Bits set in mask 0xF0000000: Background icon colour (or, with last, font no.).

*/

/* The following 3 #defines define the button status bits for get_point_info */

#define R_PRESSED       0x00000001      /* right hand button pressed */
#define M_PRESSED       0x00000002      /* middle button pressed */
#define L_PRESSED       0x00000004      /* left hand button pressed */

/* The following 7 #defines define the drag_type in drag_box */

#define MOVE_WIND       1               /* change position of window */
#define SIZE_WIND       2               /* change size of window */
#define DRAG_HBAR       3               /* drag horizontal scroll bar */
#define DRAG_VBAR       4               /* drag vertical scroll bar */
#define USER_FIXED      5               /* user drag box - fixed size */
#define USER_RUBBER     6               /* user drag box  - rubber box */
#define USER_HIDDEN     7               /* user drag box - invisible box */

/* The following 3 #defines define the menu flags for create_menu */

#define LEFT_TICK       1               /* Wimp will display 'tick' to left
                                         * of item in menu */
#define DOT_LINE        2               /* dotted line seperators */
#define MENU_WRIT       4               /* writeable item in menu */
#define LAST_ITEM       0x00000080      /* last item in this menu */




/*****************************************************************************/
/* Now for structure definitions */

typedef struct wind_block
{
        int x0, y0, x1, y1;     /* work area coordinates */
        int scx, scy;           /* scroll bar positions */
        int wind_behind;        /* handle to open window behind */
        int flags;              /* word of flag bits defined above */
        char colours[7];        /* colours: foreground, background,
                                 * work area foreground, background,
                                 * scroll bar outer/inner, title background
                                 * if window has highlight colour */
        char reservedb;         /* reserved byte */
        int exx0, exy0, exx1, exy1; /* extent coordinates */
        int title_icon, work_icon; /* icon flags for title bar, work area */
        int reservedw[2];       /* reserved space */
        char title[12];         /* title string */
        int initial_icons;      /* no. of icons in initial definition - should
                                 * be 0 from C */
} wind_block;

typedef union icon_data
{
        char text[12];          /* up to 12 bytes of text */
        char sprite_name[12];   /* up to 12 bytes of sprite name */
        struct writeable        /* if writeable... */
        {
                char * text_buff;       /* pointer to text buffer */
                char * val_string;      /* pointer to validation string */
                int bufflen;            /* length of text buffer */
        } writeable;
} icon_data;

typedef struct icon_block
{
        int wind_handle;        /* window handle */
        int ix0, iy0, ix1, iy1; /* icon bounding box - relative to
                                 * window origin (work area top left) */
        int flags;              /* word of flag bits defined above */
        icon_data data;         /* union of bits & bobs as above */
} icon_block;

typedef struct open_block
{
        int wind_handle;        /* window handle */
        int x0, y0, x1, y1;     /* position on screen of visible work area */
        int x, y;               /* 'real' coordinates of visible work area */
        int n_handle;           /* handle of window to go behind (-1 = top,
                                 * -2 = bottom) */
        int flags;              /* not always needed - here to allow to be used
                                 * by get_wind_state */
} open_block;

typedef union univ_block
{
        open_block w;           /* if window operation needed, use like this */
        int a[16];              /* otherwise, just use as big enough array */
} univ_block;

typedef struct redraw_block
{
        int wind_handle;        /* window handle */
        int x0, y0, x1, y1;     /* work area coordinates */
        int scx, scy;           /* scroll bar positions */
        int gx0, gy0, gx1, gy1; /* current graphics window */
} redraw_block;

typedef struct istate_block
{
        int wind_handle, icon_handle; /* handles */
        int a[5];               /* enough space for new icon state,mask or
                                 * bounding box coordinates, flags */
        icon_data data;         /* sprite name or text from get_icon_info */
} istate_block;

typedef struct mouse_block
{
        int mx, my, button_state; /* mouse x, y, and button state (as #def) */
        int wind_handle, icon_handle; /* handles, either -1 if not applying */
} mouse_block;

typedef struct drag_block
{
        int wind_handle, drag_type; /* handle, drag type (as #def's) */
        int x0, y0, x1, y1;     /* initial position for drag box */
        int px0, py0, px1, py1; /* parent box for drag box */
} drag_block;

typedef struct caret_block
{
        int wind_handle, icon_handle; /* handles */
        int cx, cy;             /* pos. of caret relative to window origin */
        int height, index;      /* caret height, index into string */
} caret_block;

typedef struct menu_items
{
        int menu_flags;         /* menu flags as #defined above */
        struct menu_block * sub_menu; /* pointer to sub menu */
        int icon_flags;         /* flags as for normal icon */
        icon_data data;         /* icon data as for normal icon */
} menu_items;

typedef struct menu_block
{
        char title[12];         /* menu title (optional) */
        char tit_fcol, tit_bcol, work_fcol, work_bcol; /* colours */
        int menu_width, menu_height; /* size of following menu items */
        int vert_gap;           /* vertical gap between items */
        menu_items m[MAXITEMS]; /* allow MAXITEMS menu items */
} menu_block;

typedef struct textbuf
{
        char a[168];            /* sensible text buffer size */
} textbuf;

typedef struct which_block
{
        int wind_handle;        /* handle */
        int bit_mask;           /* bit set => consider this bit */
        int bit_set;            /* desired bit setting */
} which_block;

typedef struct icon_list
{
        int a[128];             /* space for 127 icons, plus terminator */
} icon_list;

typedef struct pshape_block
{
        int shape_num;          /* pointer shape number (0 turn off pointer) */
        char * shape_data;      /* shape data, NULL pointer implies existing
                                 * shape */
        int width, height;      /* Width and height in pixels. Width = 4 * n,
                                 * where n is an integer. */
        int activex, activey;   /* active point (pixels from top left) */
} pshape_block;

typedef struct template_buf
{
        char a[2048];           /* suitable space to put template */
} template_buf;

typedef struct font_array
{
        char f[256];            /* initialise all to zero before using for
                                 * first load_template, then just use
                                 * repeatedly without altering */
} font_array;

typedef struct name_buf
{
        char n[12];             /* put name in this */
} name_buf;

typedef struct temp_block
{
        int reserved;           /* ignore - implementation detail */
        template_buf * buf;     /* pointer to space for putting template in */
        char * work_free;       /* pointer to start of free wimp workspace -
                                 * you have to provide the wimp system with
                                 * workspace to store its redirected icons in*/
        char * work_end;        /* end of workspace you are offerring to wimp*/
        font_array * font;      /* points to font reference count array, NULL
                                 * pointer implies fonts not allowed */
        name_buf * name;        /* name to match with (can be wildcarded) */
        int index;              /* pos. in index to search from (0 = start) */
} temp_block;


/*****************************************************************************/
/* Now the actual user functions */

/* All the following functions have, as an argument, an error * to show
   where to put error data if an error is generated - if no error, 
   error.errnum = 0 on return */


int w_initialise(error *);    /* close & delete all windows, return wimp
                               * version number */

int create_wind(wind_block *, error *); /* define (but not display) window,
                                         * return window handle */

int create_icon(icon_block *, error *); /* add icon definition to that of
                                         * window, return icon handle */

void delete_wind(int, error *); /* delete window indicated by handle in
                                 * integer arguament */

void delete_icon(int, int, error *); /* delete icon, first arguament window
                                      * handle, second icon handle */

void open_wind(open_block *, error *); /* make window appear on screen */

void close_wind(int, error *);  /* remove from active list the window
                                 * with handle in integer arguament */

int poll_wimp(int, univ_block *, error *); /* ask for what to do next, the
                                   * returned int showing category of action,
                                   * and the univ_block structure being used to
                                   * return more details - see the 'WIMP'
                                   * chapter in the Technical ref. guide. */

int redraw_wind(redraw_block *, error *); /* draw window outline and icons.
                                  * The window redrawn is indicated by the
                                  * window handle in the redraw_block. The int
                                  * contains false if there are no rectangles
                                  * to be drawn. */

int update_wind(redraw_block *, error *); /* return visible portion of window*/

int get_rectangle(redraw_block *, error *); /* return next rectangle in list */

void get_wind_state(int, open_block *, error *); /* read current window state -
                                        * information returned in open_block */

void set_icon_state(istate_block *, error *); /* set some/all of the icon's
                                               * flags */

void get_icon_state(istate_block *, error *); /* return icon def. in
                                               * istate_block */

void get_point_info(mouse_block *, error *); /* return info about mouse
                                              * pointer */

void drag_box(drag_block *, error *); /* start the wimp dragging a box */

void force_redraw(redraw_block *, error *); /* force redraw of an area of the
                                    * screen. Only the first 5 ints in the
                                    * redraw_block have significance */

void set_caret_pos(caret_block *, error *); /* set pos./size of text caret */

void get_caret_pos(caret_block *, error *); /* get pos./size of text caret */

void create_menu(menu_block *, int, int, error *); /*'pop up' menu structure */

void decode_menu(menu_block *, univ_block *, textbuf *, error *); /* decode
                                                           * menu selection */

void which_icon(which_block *, icon_list *, error *); /* look for icons with
                                               * particular flag settings */

void set_extent(redraw_block *, error *); /* alter extent of a window's work
                                           * area - only handle and 1st set of
                                           * 4 coordinates are looked at */

void set_point_shape(pshape_block *, error *); /* set pointer shape on screen*/

void open_template(char *, error *); /* opens file with name pointed to by
                                      * first arg to allow load_template to
                                      * read a template from the file */

void close_template(error *);   /* close currently open template file */

void load_template(temp_block *, error *); /* load a window template from open
                                            * file into buffer pointed to by
                                            * temp_blockname.buf
                                            * This pointer to a buffer can be
                                            * cast to a wind_block * and then
                                            * used to create a window using
                                            * create_wind() */


/******************************************************************************

        Some useful #defines of SWI numbers

******************************************************************************/

/* Mask with SWI number to make error return with V set - Arthur feature */

#define XOS_MASK              0x00020000

/* Brazil and Arthur SWI's */

#define OS_WriteC             0x00000000
#define OS_WriteS             0x00000001
#define OS_Write0             0x00000002
#define OS_NewLine            0x00000003
#define OS_ReadC              0x00000004
#define OS_CLI                0x00000005
#define OS_Byte               0x00000006
#define OS_Word               0x00000007
#define OS_File               0x00000008
#define OS_Args               0x00000009
#define OS_BGet               0x0000000A
#define OS_BPut               0x0000000B
#define OS_GBPB               0x0000000C
#define OS_Find               0x0000000D
#define OS_ReadLine           0x0000000E
#define OS_Control            0x0000000F
#define OS_GetEnv             0x00000010
#define OS_Exit               0x00000011
#define OS_SetEnv             0x00000012
#define OS_IntOn              0x00000013
#define OS_IntOff             0x00000014
#define OS_CallBack           0x00000015
#define OS_EnterOS            0x00000016
#define OS_BreakPt            0x00000017
#define OS_BreakCtrl          0x00000018
#define OS_UnusedSWI          0x00000019
#define OS_UpdateMEMC         0x0000001A
#define OS_SetCallBack        0x0000001B
#define OS_Mouse              0x0000001C

/* Arthur OS SWI's */

#define OS_Heap               0x0000001D
#define OS_Module             0x0000001E
#define OS_Claim              0x0000001F
#define OS_Release            0x00000020
#define OS_ReadUnsigned       0x00000021
#define OS_GenerateEvent      0x00000022
#define OS_ReadVarVal         0x00000023
#define OS_SetVarVal          0x00000024
#define OS_GSInit             0x00000025
#define OS_GSRead             0x00000026
#define OS_GSTrans            0x00000027
#define OS_BinaryToDecimal    0x00000028
#define OS_FSControl          0x00000029
#define OS_ChangeDynamicArea  0x0000002A
#define OS_GenerateError      0x0000002B
#define OS_ReadEscapeState    0x0000002C
#define OS_EvaluateExpression 0x0000002D
#define OS_SpriteOp           0x0000002E
#define OS_ReadPalette        0x0000002F
#define OS_ServiceCall        0x00000030
#define OS_ReadVduVariables   0x00000031
#define OS_ReadPoint          0x00000032
#define OS_UpCall             0x00000033
#define OS_CallAVector        0x00000034
#define OS_ReadModeVariable   0x00000035
#define OS_RemoveCursors      0x00000036
#define OS_RestoreCursors     0x00000037
#define OS_SWINumberToString  0x00000038
#define OS_SWINumberFromString 0x00000039
#define OS_ValidateAddress    0x0000003A
#define OS_CallAfter          0x0000003B
#define OS_CallEvery          0x0000003C
#define OS_RemoveTickerEvent  0x0000003D
#define OS_InstallKeyHandler  0x0000003E
#define OS_CheckModeValid     0x0000003F
#define OS_ChangeEnvironment  0x00000040
#define OS_ClaimScreenMemory  0x00000041
#define OS_ReadMonotonicTime  0x00000042

#define OS_ConvertStandardDateAndTime 0xC0
#define OS_ConvertDateAndTime         0xC1

#define OS_WriteI,         0x100

#define OS_UserSWI,        0x200


/* sound SWI's */

#define  Configure            0x00040140
#define  Enable               0x00040141
#define  Stereo               0x00040142
#define  Speaker              0x00040143


#define  Volume               0x00040180
#define  SoundLog             0x00040181
#define  LogScale             0x00040182
#define  InstallVoice         0x00040183
#define  RemoveVoice          0x00040184
#define  AttachVoice          0x00040185
#define  Sound                0x00040186
#define  Tuning               0x00040187
#define  Pitch                0x00040188
#define  Control              0x00040189
#define  AttachNamedVoice     0x0004018a


#define  QInit                0x000401c0
#define  QSchedule            0x000401c1
#define  QRemove              0x000401c2
#define  QSpace               0x000401c3
#define  QDispatch            0x000401c4
#define  QTempo               0x000401c5
#define  QBeats               0x000401c6


/* wimp SWI's */


#define Initialise          0x000400c0
#define CreateWindow        0x000400c1
#define CreateIcon          0x000400c2
#define DeleteWindow        0x000400c3
#define DeleteIcon          0x000400c4
#define OpenWindow          0x000400c5
#define CloseWindow         0x000400c6
#define Poll                0x000400c7
#define RedrawWindow        0x000400c8
#define UpdateWindow        0x000400c9
#define GetRectangle        0x000400ca
#define GetWindowState      0x000400cb
#define GetWindowInfo       0x000400cc
#define SetIconState        0x000400cd
#define GetIconState        0x000400ce
#define GetPointerInfo      0x000400cf
#define DragBox             0x000400d0
#define ForceRedraw         0x000400d1
#define SetCaretPosition    0x000400d2
#define GetCaretPosition    0x000400d3
#define CreateMenu          0x000400d4
#define DecodeMenu          0x000400d5
#define WhichIcon           0x000400d6
#define SetExtent           0x000400d7
#define SetPointerShape     0x000400d8
#define OpenTemplate        0x000400d9
#define CloseTemplate       0x000400da
#define LoadTemplate        0x000400db

