MadMan

A manual for MAD

Introduction

MAD is a simple 'inter-library' based on GEM, which sits above a real library. It was originally written as a more entertaining way of porting an ST program with a large rsc-file to svgalib in Linux than a line-by-line translation of the source, but it has been used for several of my programs and may be of more general use.

The current version uses Allegro, which is a very useful multi-platform graphics library, and has been tested in Windos and Linux.

The basic theory behind MAD is that you can do most of what you want in an application by using plain C for data manipulation and GEM for the GUI functions, if your application can call routines in some other library to mimic the effect of the GEM calls, and the other library needs to be no more visible than the TOS.

Handles and windows are not properly supported because I am only working at the application level, but all the GEM calls I used on the ST have near equivalents in MAD.
 

Legalities

Use of MAD is under my BeWare License; if this restricts your use of it, let me know.
 

Structures and Routines

Many of these are boring and old hat to long-time ST users, but, after all, that's the whole idea.
 

Tos and General

short Getrez()

char *Physbase()

char *Logbase()

void Setscreen(int, int)

Palette Routines

Palette overview

void Setpalette()

int Getpalette()

int Resetpalette(int number)

int Setcolor(int colorno, unsigned char *color)

void Palettize(int lemgth, unsigned char *index, unsigned char *palette)

void Storepalette(short from, short total, char *colors)

void Forcepalette(short from, short total, char *colors)

void Defaultpalette()

void Getcolor(int colno, unsigned char *savecolor)

int Grabpalette(unsigned char *savepalette)
 

VDI Routines

Under TOS, the handle, which is the first parameter in all the VDI routines is assigned to a workstation by the operating system, and used by the operating system to determine which workstation the operation takes effect in, but there is no easy way to translate this to other systems, so the only use MAD makes of handles is to decide which screen to operate on.

int vsl_color(int handle, int color)

int vsf_color(int handle, int color)

int vst_color(int handle, int color)

int vst_effects(int handle, int effects)

int vst_font(int handle, int fontno)

int vst_load_font(int handle, const char *fontname)

int vst_user_font(int handle, GFONT *font)

int vst_unload_font(int handle, int fontno)

void v_gtext(int handle, int ox, int oy, const char *text)

void v_pline(int handle, int count, short *pxy)

void v_bar(int handle, short *pxy)

int v_opnvwk(int *handle);

void v_clrwk(int handle)

void v_clsvwk(int handle)

void vs_clip(int handle, int flag, short *pxy);

void v_hide_c(int handle);

void v_show_c(int handle, int count)

void vq_mouse(int handle, short *butn, short *x, short *y)

void vq_key_s(int handle, short *kbstat)

int vq_keybd(int handle)

void vro_cpyfm(int handle, int mode, short *pxy, FDB *src, FDB *dest)

AES Routines

The AES holds the highest level of user interface routines and a surprising number of them were built entirely from other MAD routines, which makes them instantly portable to other platforms when you have puzzled your way through translating the lower routines.
 

Initialization and Exit

int appl_init(int res)

int appl_exit()

Resource routines

Resource description

int rsrc_load(const char *filename)

int rsrc_free()

int rsrc_include(void *array)

int rsrc_gaddr(int type, int index, void *address)

int objc_draw(OBJECT *dialog, int startobj, int depth, int clipx, int clipy, int clipw, int cliph)

int objc_find(OBJECT *dialog, int seekobj, int depth, int mx, int my)

int objc_offset(OBJECT *dialog, int seekobj, int depth, short *screenx, short *screeny)

int graf_rubberbox(int ox, int oy, int minw, int minh, short *lastw, short *lasth)

int graf_dragbox(int movew, int moveh, int ox, int oy, int bordx, int bordy, int bordw, int bordh, short *lastx, short *lasty)

int graf_slidebox(OBJECT *slider, int S_Gauge, int S_Slide, int slvh)
 

Form Routines

These handle interaction with whatever resource is on the screen.

int form_center(OBJECT *dialog, short *x, short *y, short *w, short *h)

int form_dial(int fo_diflag, int fo_dilittx, int fo_dilitty, int fo_dilittw,
int fo_dilitth, int dix, int diy, int diw, int dih)

int form_do(OBJECT *dialog, int editobj)

int form_alert(int dfault, const char *alert)

int form_error(int number)

int form_error_text(char *text)

int form_infobox(OBJECT *dialog)

int form_input(int length, char *ptmplt, int default, char *label)

void form_input_text(int length, char *ptemplate, char *text, char *label)
 

Menu Routines

Menus are special dialogs which sit up at the top of the screen, and also a major mess. They need their own routines because GEM, and therefore MAD, doesn't recognise them as a special case. Sigh.

int menu_bar(OBJECT *menu, int flag)

int menu_tnormal(OBJECT *menu, int title, int norm)

int menu_icheck(OBJECT *menu, int title, int check)

int menu_ienable(OBJECT *menu, int title, int enable)
 

Event Routines

These are the mouse and keyboard operations and, in general, have fairly complicated conditions and results, built round a generic mouse/keyboard event which tries to encapsulate the different rules of different systems and return predictable results.

int evnt_timer(int locount, int hicount)

int evnt_mouse(int mflags, int mx, int my, int mwidth, int mheight,
 short *x, short *y, short *butn, short *kstate)

int evnt_keybd()

int evnt_button(int bmaxclicks, int bmask, int bstate, short *x, short *y, short *butn, short *kstate)

int evnt_mesag(short *msgbuff)

int evnt_multi(int aflags, int bmaxclicks, int bmask, int bstate,
int m1flags, int m1x, int m1y, int m1width, int m1height,
int m2flags, int m2x, int m2y, int m2width, int m2height,
short *msgbuff, int locount, int hicount, short *x, short *y,
short *butn, short *kstate, short *kreturn, short *breturn)
 

Mouse Shape Routine

int graf_mouse(int mode, void *shape)
 

File Selector Routines

int fsel_exinput(char *path, char *selfile, short *button, const char *label)

int fsel_input(char *path, char *selfile, short *button)

void fsel_set_extn(char *type)
 

Useful Macros

These are definitions and mnemonics understood by MAD I haven't referred to. A full list is in the header files.
 

Key definitions across libraries

Once you leave the elegant simplicity of the ST, keyboards become a real pain. MAD translates the actual key returns to the following numbers.

CARRET 13 /*Return key*/
AKEY 'a'
BKEY 'b'
CKEY 'c'
DKEY 'd'
EKEY 'e'
FKEY 'f'
GKEY 'g'
IKEY 'i'
LKEY 'l'
NKEY 'n'
PKEY 'p'
QKEY 'q'
RKEY 'r'
SKEY 's'
UKEY 'u'
XKEY 'x'
YKEY 'y'
COMMAKEY ','
STOPKEY '.'
SLASHKEY '/'
SPACEKEY ' '
ESCKEY 27
TABKEY 9
BCKKEY 127 /*Backspace*/
DELKEY 128 /*Delete*/
F1KEY 323 /*F1*/
F2KEY 324
F3KEY 325
F4KEY 326
/*Spot what's missing*/
UAKEY 354 /*Up arrow*/
DAKEY 360
RAKEY 358
LAKEY 356
STLBUT 1 /*Right mouse button*/
STRBUT 2 /*Left mouse button*/
 

Color Handling Generalities

Color manipulation in MAD had to be changed considerably or restricted to constant reuse of the first 16 colors of the palette, so there is a lot of difference in the color routines from the 16-color originals.
The first 16 colors of the MAD palette are the 16 default colors of the ST palette, with black and white transposed between resolutions 0 and 1. These can be changed, other colors can be added and pictures mapped to already used colors.
Each color is expressed as 3 bytes of RGB, and color 0 is always treated as transparent.
WHITE 0
BLACK 1
RED 2
GREEN 3
BLUE 4
CYAN 5
YELLOW 6
MAGENTA 7
LWHITE 8
LBLACK 9
LRED 10
LGREEN 11
LBLUE 12
LCYAN 13
LYELLOW 14
LMAGENTA 15
 

The Components of the MAD Resource

The GEM resource or rsc-file is a description of a dialog through which instructions can be sent to the program. The resource is made up of 'objects', separated into hierarchical 'trees', and associated texts. The MAD version is slightly cut down, but handles everything I use, including long filenames and paths in the file selector.

Resources can be built and re-edited with Madorcs.

The various structures and macros used are:

typedef struct rshdr {
unsigned short rsh_rssize; /* total bytes in resource */
unsigned short rsh_tedinfo; /* offset to tedinfo[] */
unsigned short rsh_object; /* offset to object[] */
unsigned short rsh_trindex; /* offset to object tree index */
short rsh_nteds; /* number of tedinfos */
short rsh_nobs; /* number of objects */
short rsh_ntrees; /* number of trees */
} RSHDR;
The header for a resource.

typedef struct object {
short ob_next;
short ob_head;
short ob_tail;
unsigned char ob_type;
unsigned char ob_flags;
unsigned char ob_colbyte;
unsigned char ob_font;
unsigned char ob_border;
unsigned char ob_fill;
char *ob_spec;
short ob_x;
short ob_y;
short ob_width;
short ob_height;
} OBJECT;

typedef struct tedinfo {
char *te_ptext;
char *te_ptmplt;
short te_pvalid;
short te_ptxtlen;
} TEDINFO;

Most of the detail here should be irrelevant even to the programmer, once the resource is set up. The coordinates are simple pixel measurements with respect to the object directly above in the hierarchy. The flags are detailed below. The ob_spec contains the single character for R_CHAR, the address of a tedinfo for R_FTEXT and R_STEXT, and the text address for the other text types.

MAX_DEPTH 8
The maximum depth of search or draw

Resource Types
R_BLOCK 20 A rectangle of the background color
R_IBOX 25 A notional rectangle, ie you can see through it
R_CHAR 27 A single character
R_TEXT 28 A simple string, neither editable nor formatted
R_FTEXT 29 A string which will be printed with certain formatting rules
R_ETEXT 30 A text which can be edited by the user
R_STEXT 31 An editable text which can scroll, used in the file selector
R_TITLE 32 A string used in menu headings

Object Flags
NONE    0
DEFAULT    1    Pressing return equals clicking on this
EXIT    2    Resource handling is terminated
CHECKED     4    Object is checked
LASTOB    8    The last object in a tree (set of objects}
HIDETREE    16    This object and any contained in it are neither drawn nor available
SELECTED    32    Object has been selected and is shown recolored
DISABLED    64    Object can't be selected and is shown feint
OUTLINED    128    Object is outlined
 

The definition of a GEM font, as used for text in MAD

typedef struct GFONT {
short font_id; /* Font face identifier, 1 -> system font */
short size; /* Font size in points */
char name[32]; /* Font name */
short first_ade; /* Lowest ADE value in the face */
short last_ade; /* Highest ADE value in the face */
short top; /* Distance of top line relative to baseline*/
short ascent; /* Distance of ascent line relative to baseline*/
short half; /* Distance of half line relative to baseline*/
short descent; /* Distance of decent line relative to baseline*/
short bottom; /* Distance of bottom line relative to baseline*/
/* All distances are measured in absolute values */
/* rather than as offsets. They are always +ve */
short max_char_width; /* Width of the widest character in font */
short max_cell_width; /* Width of the widest character cell in face */
short loffset; /* Left Offset see Vdi appendix G */
short roffset; /* Right offset " " " */
short thicken; /* Number of pixels by which to thicken characters*/
short ul_size; /* Width in pixels of the underline */
short lighten; /* The mask used to lighten characters */
short skew; /* The mask used to determine when to perform */
/* additional rotation on the character to perform skewing */
short flags; /* Flags */
/* $01 default system font */
/* 02 horiz offset table should be used */
/* 04 byte-swap flag (thanks to Intel idiots) */
/* 08 mono spaced font */
short * hoff_base; /* Offset to horizontal offset table */
short * coff_base; /* Offset to character offset table */
/* font bitmap is byte[width][height], width must be even */
short * form_base; /* Offset to font data */
short form_width; /* Form width (#of bytes/scanline in font data) */
short form_height; /* Form height (#of scanlines in font data) */
char * next_font; /* Pointer to next font in face */
} GFONT;

short Getrez()
Returns the resolution for the console or the window size in X.
The resolutions used are:
0: 320*200
1: 640*480
2: 800*600
All screens are 8-bit, 256 colors.

char *Physbase()
Actually returns NULL. The copying routines use this to signal the need to switch to screen manipulation functions.

char *Logbase()
Returns the address of a pre-allocated virtual screen. This facilitates performing all the graphics operations off-screen and page-flipping.

void Setscreen(int, int)
If the first parameter is -1, the second parameter is the resolution that will be set, otherwise the second parameter is ignored.
0 copies the virtual screen to the physical screen, and sets the handle to point to the physical screen.
1 copies the physical screen to the virtual screen, and sets the handle to the virtual screen.

void Setpalette()
Refreshes the screen palette to the MAD palette.
Setpallete is defined to this; the original C compiler for the ST misspelled the word and people grew accustomed to it.

int Getpalette()
Returns the number of colors which are currently assigned.

int Resetpalette(int number)
If the parameter is 256, the number of colors is reset to the starting number, actually 16. Otherwise it is set to the parameter. The return is the actual number of colors now recognized.
Note that this routine does not change the screen colors.

int Setcolor(int colorno, unsigned char *color)
If the first parameter is less than 256, the color at that point in the MAD palette is changed to the second parameter and the first parameter is returned.
Otherwise, the second parameter is checked against the used palette. If one of the used colors is no more than 1 point each of RGB away, its number is returned.
Failing this, if there is room, a new color is added and the return is its number.
If all else fails, the number of the nearest color is returned.

void Palettize(int lemgth, unsigned char *index, unsigned char *palette)
This routine is passed a length and an index array and color array of that length. It puts the colors into the MAD palette using Setcolor and stores the assigned palette numbers in the index.
The index can now be used to map a picture's pixels onto the screen or into memory.

void Storepalette(short from, short total, char *colors)
This routine puts the colors in the array into the palette, starting at a point, for a length, ignoring any duplicates or already assigned colors.
It does not change the screen palette.

void Forcepalette(short from, short total, char *colors)
This routine does change the screen palette.

void Defaultpalette()
Restores all palette conditions to what they were at startup.

void Getcolor(int colno, unsigned char *savecolor)
Atari Setcolor returns the old color; mine returns the number.
Palettize means I don't know my actual colors, so this tells me what color I have in a slot.

int Grabpalette(unsigned char *savepalette)
Copies the whole palette to savepalette, so it can be restored.
Returns the number of colors actually used.

int vsl_color(int handle, int color)
Sets the color, ie palette number, with which lines are drawn.

int vsf_color(int handle, int color)
Sets the color for fills.

int vst_color(int handle, int color)
Sets the color of text.

int vst_effects(int handle, int effects)
Sets the text effects used by v_gtext.
NORMAL 0 No effects
THICKENED 1 The text is 1 pixel thicker, giving a bolder look
SHADED 2 Only odd pixels are printed, giving a feint look
SLANTED 4 The top of the text is displaced to the right
UNDERLINED 8 The text is underlined, apart from spaces
DOUBLED 16 The text is twice as thick, at the original height

int vst_font(int handle, int fontno)
There are 3 fonts in MAD as standard, and more may be loaded up to a total of 8. This routine sets the font used to one of them.

int vst_load_font(int handle, const char *fontname)
Loads from disk a font by name for the next available slot, and returns the font number, or -1 if it fails.

int vst_user_font(int handle, GFONT *font)
For convenience, this routine can take the address of a font file that has been compiled into an application, assign it as a usable font and return the font number. Again, -1 indicates a failure.

int vst_unload_font(int handle, int fontno)
Clears a font slot (not the 3 defaults) and moves fonts up to fill the gap. Returns the new number of fonts or -1.

void v_gtext(int handle, int ox, int oy, const char *text)
This routine prints a string in the set font, in the chosen color, with the chosen effects. Printing starts at ox, oy, and will be clipped if necessary.

void v_pline(int handle, int count, short *pxy)
Draws a set of connected lines. The second parameter is the number of points, and the third is an array of xy screen coordinates.

void v_bar(int handle, short *pxy)
Fills a rectangle. The array of 4 shorts gives the top left and bottom right points of the rectangle.
vr_recfl is defined to this.

int v_opnvwk(int *handle);
This should open a virtual workstation, set up certain parameters of it, fill an array with useful data about it and return a handle to it. In practice it doesn't do any harm.

void v_clrwk(int handle)
This clears the current screen.

void v_clsvwk(int handle)
This should close the virtual workstation.

void vs_clip(int handle, int flag, short *pxy);
if the second parameter is 1, the clipping rectangle is defined by the 4 points of the array. If it is 0, clipping is disabled.

void v_hide_c(int handle);
This hides the mouse cursor, unless it is already hidden, and keeps track of how often it has been called.

void v_show_c(int handle, int count)
If v_hide_c has not been called, this routines returns immediately, as there is nothing for it to do.
If the second parameter is 1, it cancels out one v_hide_c; if it is 0, it cancels all of them.
If all v_hide_c calls have been cancelled, it shows the cursor.

void vq_mouse(int handle, short *butn, short *x, short *y)
This returns immediately with the current state of the mouse button and the x and y positions of the cursor in its pointers.

void vq_key_s(int handle, short *kbstat)
This returns immediately with the pointer holding part or all of the following bit pattern.
1 Right Shift was pressed
2 Left Shift was pressed
4 A Control key was pressed
8 Alt was pressed

int vq_keybd(int handle)
If a key has been pressed, this returns the key value. Otherwise it returns 0. Note: the keypress is no longer available after this routine.

void vro_cpyfm(int handle, int mode, short *pxy, FDB *src, FDB *dest)
A versatile blitting routine.
The array of 8 shorts gives the coordinates of top left/bottom right of a source rectangle and a destination rectangle with respect to the top left of the Frame they are contained by.
The second parameter is the mode, the blitting operation itself. 4 types are supported:
ALL_WHITE      0    The source rectangle is filled with color 0
S_ONLY             3    The source is blitted to the destination
D_ONLY            5    The source is blitted to the destination, except for pixels which are color 0 in the source
ALL_BLACK   15    The source rectangle is filled with color 1

The last 2 parameters are pointers to a source and destination Frame Definition Block, a structure with the following definition:
void *fd_addr;
short fd_w;
short fd_h;
short fd_wdwidth;
short fd_stand;
short fd_nplanes;
short fd_r1;
short fd_r2;
short fd_r3;
Only the first 3 elements are used. The first is the starting address of the frame; if this is NULL, it is assumed that the physical screen is being referred to. fd_w and fd_h are the width and height of the frame.

int appl_init(int res)
This has to be called at the beginning of a program, with the desired resolution as the parameter.
It sets up the standard fonts and the error-message and file-selector resources, initializes the mouse and clears the screen.

int appl_exit()
This tidies up anything which needs tidying and exits.

int rsrc_load(const char *filename)
Loads a resource. If it fails, there is no point in continuing, so it reports this and closes down the program.

int rsrc_free()
Frees up the resource.

int rsrc_include(void *array)
Makes a compiled-in array into the user resource. A convenience when you decide you no longer need to re-edit the resource.

int rsrc_gaddr(int type, int index, void *address)
This is normally used to get into an OBJECT pointer the address of a tree in the resource, in which case the first parameter is 0, the second the number of the tree in the resource's list (more usually a macro produced by the resource editor).
Theoretically, it can also get the address of any object or tedinfo.

int objc_draw(OBJECT *dialog, int startobj, int depth, int clipx, int clipy, int clipw, int cliph)
This draws an object (generally a full tree), from a starting object within it (generally 0), to a depth (generally MAX_DEPTH as the routine will stop when it runs out of objects anyway). I don't use the last 4 parameters.

int objc_find(OBJECT *dialog, int seekobj, int depth, int mx, int my)
This finds the deepest object in a dialog under the given co-ordinates and returns its number, or -1 if there is no such object. Depth is currently ignored.

int objc_offset(OBJECT *dialog, int seekobj, int depth, short *screenx, short *screeny)
This puts the screen co-ordinates of the sought object in screenx, screeny. Depth is currently ignored.

int graf_rubberbox(int ox, int oy, int minw, int minh, short *lastw, short *lasth)
Draws a box right and down from ox, oy, with a minimum width, minw, and height, minh, to the mouse position while the left button is held down.  The final width and height are returned in lastw, lasth.

int graf_dragbox(int movew, int moveh, int ox, int oy, int bordx, int bordy, int bordw, int bordh, short *lastx, short *lasty)
Drags a box of size movew, moveh, starting at ox, oy, around the screen between the boundaries given by bordx, bordy, bordw and bordh, as long as the left mouse button is held down.  The top left corner of the final position is returned in lastx, lasty.

int graf_slidebox(OBJECT *slider, int S_Gauge, int S_Slide, int slvh)
Moves an object within the limits of another object, either vertically  (slvh==1) or horizontally (slvh==0).
Returns the position of the center of the slider relative to the gauge.

int form_center(OBJECT *dialog, short *x, short *y, short *w, short *h)
This does nothing but work out the x and y coordinates for the top left of an object that will center it on the screen, and pass them with the object's width and height to the parameters and to the dialog itself.
If you want to do your own placement, you can ignore this; the width and height are already correct in the dialog.

int form_dial(int fo_diflag, int fo_dilittx, int fo_dilitty, int fo_dilittw,
int fo_dilitth, int dix, int diy, int diw, int dih)
This prepares for drawing the form or undraws it.
If the first parameter is less than 2, a section of the screen with coordinates given by the last four parameters (usually those set by form_center) is saved.
Otherwise, the previously saved screen is blitted back in, erasing the form.

int form_do(OBJECT *dialog, int editobj)
The actual messing with the dialog (but not the drawing - that has to be done with objc_draw).
If the second parameter is non-zero, the text cursor is positioned in the text of the object with that number. Otherwise, the text cursor goes in the first editable object it can find.
Tab cycles through the editables. Backspace and delete both delete from the end of the text. Escape deletes the entire text.
Clicking on an object with EXIT in its flags or pressing return terminates this routine, and the return is either the number of the clicked object or that of the default object.

int form_alert(int dfault, const char *alert)
This on its own calls up a small dialog with limited but useful functionality, using up to 3 buttons and up to 5 lines of text.
The int is the number of the button which pressing return will simulate; this will be shown as the default.
The string is of the form [number][text|text|...][button|button...], where number is the number of buttons, text stands for a line of text and button stands for a button text.
The return is the button, 1-3, actually pressed.

int form_error(int number)
The ST form_error returned a report of violations of the underlying operating system. I can't manage that so this is basically a debugging device which shows a message with the parameter included and waits.

int form_error_text(char *text)
Like form_error, but puts up a message instead of a number.

int form_infobox(OBJECT *dialog)
 Puts up a user-created dialog with only one exit button, mainly to  present information to the user. The dialog can contain editable strings, but reading them must be handled explicitly by the program

int form_input(int length, char *ptmplt, int default, char *label)
Pops up a little dialog box in which you can type a number of length digits on a line starting with the template. The default is the default number given. The label is optional.
The return is the number you typed.

void form_input_text(int length, char *ptemplate, char *text, char *label)
Gets  a string in text. The label is, again, optional. The text should be at least length+1 characters long, to allow for the terminator.

int menu_bar(OBJECT *menu, int flag)
If the flag is 1, the menu headings are put at the top of the screen, and the pixels they displace are saved.
Otherwise (assuming one was actually drawn earlier) the menu is erased.

int menu_tnormal(OBJECT *menu, int title, int norm)
The first int is an object number within the menu.
If the second is 0, this object is written as SELECTED, otherwise it is un-marked.

int menu_icheck(OBJECT *menu, int title, int check)
The first int is an object number within the menu.
If the second is 1, this object  is marked as CHECKED, otherwise it is un-marked.

int menu_ienable(OBJECT *menu, int title, int enable)
The first int is an object number within the menu.
If the second is 1, this object can be selected, otherwise it is written FEINT and can't be selected. As MAD doesn't distinguish menus from other dialogs, this can be useful in ordinary dialogs as well.

int evnt_timer(int locount, int hicount)
The precision of this is implementation dependent. locount/hicount is in milleseconds

int evnt_mouse(int mflags, int mx, int my, int mwidth, int mheight,
 short *x, short *y, short *butn, short *kstate)
 If mflags is set, this returns 1 when the mouse leaves a rectangle;  otherwise it returns 1 when it enters. The mouse coordinates and button state are passed in the pointers.

int evnt_keybd()
Waits for a keypress and returns it.

int evnt_button(int bmaxclicks, int bmask, int bstate, short *x, short *y, short *butn, short *kstate)
Waits for the number of clicks set in the first parameter, and returns that number.
The next parameter is the buttons which will register as clicks; 1 is left, 2 is right, 3 is either. The third parameter sets whether button up (0) or button down (1, 2 or 3) is counted.
When the routine exits, the 4th and 5th parameters contain the x and y of the mouse position, the 6th the button states, in the same form as the second parameter aand the last the same information as is returned by vq_key_s.

int evnt_mesag(short *msgbuff)
This routine is only partially implemented, and used for menu operations.
If the mouse moves to the top menu, the dropdown menus appear. A click in one of them will result in the message buffer (an array of 8 shorts) containing:
short 0: 10 (a macro, MN_SELECTED, is the mnemonic for this)
short 3: The object index of the menu title
short 4: The object index of the menu entry
Moving outside the active menu area sets the 1st short to 0, and undraws the menu box

int evnt_multi(int aflags, int bmaxclicks, int bmask, int bstate,
int m1flags, int m1x, int m1y, int m1width, int m1height,
int m2flags, int m2x, int m2y, int m2width, int m2height,
short *msgbuff, int locount, int hicount, short *x, short *y,
short *butn, short *kstate, short *kreturn, short *breturn)
This routine is only partially implemented, but is basically a conflation of all the other event routines.
The first parameter is the types of event expected, and the return is the types which actually occurred, using the following flags:
MU_KEYBD 1 keyboard event
MU_BUTTON 2 button event
MU_M1 4 mouse rectangle event 1
MU_M2 8 mouse rectangle event 2
MU_MESAG 16 message event
MU_TIMER 32 timer event

The next 3 have the same meaning as in evnt_button.
The next 10 (to the short pointer) are 2 images of the evnt_mouse function.
The msgbuff is as in evnt_mesag.
The locount and hicount are the low word and high word of the number of milliseconds that the routine will wait for an event. Take this with a large grain of salt; I've tried for an approximation to equivalence to ST timings.
The next 4 pointers are as in evnt_button.
The penultimate is the key pressed or 0.
The last is the number of clicks as for evnt_button.
In use, all of the last set of pointers which are unnecessary can be the same variable.

int graf_mouse(int mode, void *shape)
This routine carries out 2 quite distinct functions, depending on the mode, which can be one of:
ARROW 0
TEXT_CRSR 1
HOURGLASS 2
POINT_HAND 3
FLAT_HAND 4
THIN_CROSS 5
THICK_CROSS 6
OUTLN_CROSS 7
USER_DEF 255
M_OFF 256
M_ON 257

M_OFF and M_ON function like v_hide_c and v_show_c. Note that the GEM strictures against mixing VDI and AES do not apply in MAD.
The other modes change the cursor. There are 8 predefined shapes and USER_DEF can access new shapes attached to the program. The structure of a shape is:
short hot_x, hot_y The active point of the cursor
short foreground, background Mouse colors; 255 is invalid
short shape[16] The central shape; foreground color
short mask[16] The surrounding mask; background color
For every set bit in the shape and mask a pixel is set to the foreground or background color in the cursor.
The shape parameter is normally set to NULL, except for USER_DEF.

int fsel_exinput(char *path, char *selfile, short *button, const char *label)
MAD comes with a default file selector which can handle long filenames.
The path is the name of the directory, and should have space for 256 (FMSIZE) characters. The selfile is the name of the file, and should have space for 128 (FNSIZE) characters. You might get away with less, but don't blame me if you don't.
The label is a message which appears at the top of the file selector.
On return, the button contains 0 for selection cancelled, or 1 for selection. In the latter case, the path contains the full pathname of the selected directory, the selfile the filename within the directory.
There is a set of 6 default clickable extensions which will stay throughout a session and include the extensions of files already selected.
The Dos/Windows version comes with a few drive buttons.

int fsel_input(char *path, char *selfile, short *button)
The same as fsel_exinput, but with a default message.

void fsel_set_extn(char *type)
A convenience to let you add an extension to the list of default extensions.
 
 

Back to the Introduction