@(#)xgemfast.txt, SozobonX library docs Mar 29 1995

The XGemFast Library

     The XGemFast library is based on version 1.41/1.5 of the GemFast
library, by Ian Lepore.  To avoid naming conflicts for those who wish
to use another library, and because significant changes have been made
to the original, the name of this library has been changed from GemFast
to XGemFast.  Accordingly, the name of the header file that you must
#include has been changed from GEMFAST.H to XGEMFAST.H.  All of the
functions in this library are written entirely in assembly language.

     It has been optimized by Holger Weets, and bugs have been fixed by
both Holger Weets and Jerry Geiger.

                      XVDIFAST   Library
                      XAESFAST   Library
                      XGEMFAST.H Header File

                      Variable:  short _xvdifast
                      Variable:  char __Ident_vdilib[]
                      Variable:  char _xvdifast_date[]
                      Variable:  short _xaesfast
                      Variable:  char __Ident_aeslib[]
                      Variable:  char _xaesfast_date[]

short _xaesfast
     extern short _xaesfast

     This is a BCD (Binary Coded Decimal) short integer representing
the version/revision of the XAESFAST library.  The low byte is the
revision number, and the high byte is the version number.

     There is a macro (_XAESFAST) in the XGEMFAST.H header file which
should have the same value.

__Ident_aeslib
     char __Ident_aeslib[];

     An 'ident' string for the XAESFAST library.

_xaesfast_date
     char _xaesfast_date[]

     A string containing the version date of XAESFAST.

__Ident_vdilib
     char __Ident_vdilib[];

     An 'ident' string for the XVDIFAST library.

_xvdifast_date
     char _xvdifast_date[]

     A string containing the version date of XAESFAST.

short _xvdifast
     extern short _xvdifast

     This is a BCD (Binary Coded Decimal) short integer representing
the version/revision of the XVDIFAST library.  The low byte is the
revision number, and the high byte is the version number.

     There is a macro (_XVDIFAST) in the XGEMFAST.H header file which
should have the same value.

XVDIFAST   Library
     For a complete list of functions found in this library, examine
the Atari Developer Documentation (GEM Programmer's Guide Volume 1:
VDI).  Only functions and variables specific to this library are
discussed in this reference text.

                         Function:  vq_gdos()
                         Function:  vq_vgdos()
                         Function:  vqt_name()
                         Function:  vqt_nvdi_name()
                         Function:  vqt_x_name()
                         Function:  c_vdi()

vq_gdos()
     short vq_gdos(void)

     This function returns 0 if GDOS is not present, otherwise it will
return any other value.

vq_vgdos()
     long vq_vgdos(void)

     This function returns -2 if GDOS is not present, otherwise it will
return any value. This value might be something like
     '_FSM' (0x5F46534D)
     '_FNT' (0x5F464E54)
which are GDOS types, or an undefined value != -2L.


vqt_name()
     short vqt_name(short handle, short index, char *name)

     A standard function, but to prevent problems with e.g. NVDI
<name> should be a pointer to an array like char name[33]. With NVDI
name[32] is a vector-font-flag. To get this information set name[32]
to '\0' before calling the function. To avoid problems set the null Byte
before using <name> as string again.

     See vqt_nvdi_name(), vqt_x_name()

vqt_nvdi_name()
     short vqt_nvdi_name(short handle, short index, char *name,
        char *face, unsigned short *vecflag, unsigned short *font_format,
        unsigned short *flags);

     This is vqt_name() according to NVDI docs.
<name> and <face> should be pointers to strings of 17 bytes length, like
char name[17]. The font name string is splitt according to NVDI docs,
null bytes are added in name[16] and face[16].
     The flags will be returned if NVDI or some compatible VDI is running,
if not they will be set to 0.

     See vqt_name(), vqt_x_name()

vqt_x_name()
     short vqt_x_name(short handle, short index, char *name,
        unsigned short *vecflag, unsigned short *font_format,
        unsigned short *flags);

     This is vqt_name() according to NVDI docs, but without splitting
the fontname. So <name> should be a pointer to a string like
char name[33]. The ending null byte is always added in name[32].
     The flags' values are set to 0 if no information is available.

     See vqt_nvdi_name(), vqt_name()

c_vdi()
     void c_vdi(short *pb[5])

     This function is an interface that will allow you to create your
own VDI functions (just in case they are not supported by this
library).  All registers except D0 are saved by this function.

     Usage:

     Because all VDI arrays are some dynamic binding (on the stack),
you have to create your own arrays when using this function:

     short control[12];
     short intin[1];  /* Set to what you need. */
     short intout[1]; /* Set to what you need. */
     short ptsin[1];  /* Set to what you need. */
     short ptsout[1]; /* Set to what you need. */

     short *PB[5];    /* Where: */

     PB[0] = control;
     PB[1] = intin;
     PB[2] = ptsin;
     PB[3] = intout;
     PB[4] = ptsout;

     /* Fill in the values from parameters shown in reference guide. */

     control[0] = opcode
     control[1] = #ptsin  /* (number of pairs in ptsin) */
     control[2] = 0
     control[3] = #intin  /* (number of values in intin) */
     control[4] = 0
     control[5] = sub_opcode
     control[6] = vdi_handle
     [...]

     c_vdi(PB);

     /* Maybe have some code for getting the return values. */

     /* The called VDI function tells you: */
     /* in control[2]     number of pairs in ptsout */
     /* in control[4]     number of values in intout */

     return(intout[0]); /* This is the default. */

XAESFAST   Library
     For a complete list of functions found in this library, examine
the Atari Developer Documentation (GEM Programmer's Guide Volume 2:
AES). MultiTOS AES functions (AES 4.00) and MagiC AES functions are
included, too. See the distributed file 'xgemfast.h', the MultiTOS and
the MagiC documentation for more information. Structures and
definitions are to find in XGEMFAST.H.

      Variable:  short _xaesfast         Variable:  short global[15]

     For a direct AES call and access to contrl[] and AES
      parameter block see AES interface.

     The following functions are extensions to a standard AES library:

      Function:  int fsel_input()      Function:  int fsel_exinput()
      Function:  int fsel_sm()         Function:  int fsel_emulation()
      Function:  int evnx_multi()      Function:  void rsc_treefix()
      Function:  void rsc_gstrings()   Function:  void rsc_sstrings()
      Function:  long rsc_gspec()      Function:  char *rsc_gpointer()
      Function:  void rsc_sspec()      Function:  void rsc_spointer()
      Function:  GRECT *rc_gadjust()   Function:  VRECT *rc_vadjust()
      Function:  GRECT *rc_vtog()      Function:  VRECT *rc_gtov()
      Function:  void rc_union()       Function:  int rc_intersect()
      Function:  void rc_copy()        Function:  int rc_equal()
      Function:  void objcl_calc()     Function:  void obj_flchange()
      Function:  void obj_stchange()   Function:  void obj_offxywh()
      Function:  void obj_xywh()       Function:  int obj_xtfind()
      Function:  int obj_rbfind()      Function:  int obj_rbselect()
      Function:  int obj_parent()      Function:  int frmx_center()
      Function:  int winx_calc()       Function:  int winx_get()
      Function:  void do_bell()
       List of supported MagiC AES functions

int global[15]
     int global[15];

     This is the global array, and is aliased by the following
variables:

                      Variable:  short  gl_apversion
                      Variable:  short  gl_apcount
                      Variable:  short  gl_apid
                      Variable:  long   gl_apprivate
                      Variable:  OBJECT **gl_apptree
                      Variable:  short  gl_ap1resv
                      Variable:  RSHDR  *gl_apprshdr
                      Variable:  short  gl_ap2resv[6]
                      Variable:  short  gl_chheight
                      Variable:  short  gl_smchheight


int gl_apversion
     int gl_apversion;

     This variable contains the AES version (BCD).

     Alias:  global[0]

     != 0 IF ANY AES IS PRESENT (after appl_init() call).

int gl_apcount
     int gl_apcount;

     This variable contains the maximum number of concurrent AES
     applications.

     Alias:  global[1]

     -1 = MultiTOS/Geneva/Mag!x

int gl_apid
     int gl_apid;

     AES Application Identification of the current application.  This
is the value returned by the appl_init() function.

     Alias:  global[2]

long gl_apprivate
     long gl_apprivate;

     This variable can hold anything you want it to.

     Alias:  global[3,4]

OBJECT **gl_apptree
     OBJECT **gl_apptree;

     This is a pointer to an array of object tree pointers.

     Alias:  global[5,6]

gl_ap1resv
  global[7], global8]
  see RSHDR *gl_apprshdr

RSHDR *gl_apprshdr
     RSHDR *gl_aprshdr;

     This variable is a pointer to the head of resource file
data.  This is the new name for the gl_ap1resv variable.

     Alias:  global[7,8]

gl_ap2resv
 global[9] to global[14]
 see short gl_chheight and 
 short gl_smchheight

short
    short gl_chheight

    in global[13] which is gl_ap2resv[5]
    you can can find in newer AES versions
    the AES' font's char height.

short
     short gl_chheight

    in global[14] which is gl_ap2resv[6]
    you can can find in newer AES versions
    the AES' small font's char height.

AES interface
     There are three functions with different parameters for access
of a direct AES call in xaesfast library. You can use that one you like
best.
                         Function: void c_aes()
                         Function: void call_aes()
                         Function: void callaes()

      Variable:  void *aespb[]           Variable:  short aescontrol[5]

aespb
 the AES paramter block is
 any array of pointers to
 contrl[], global[],
 int_in[], int_out[], 
 addr_in[]  and addrout[]

aescontrol
 this is the name for the
 AES contrl[] array used
 by xaesfast.

c_aes()
     void c_aes(unsigned long control, short *int_in, short *int_out,
                              void *addr_in, void *addr_out);

     This function is similiar to c_vdi(), all parameters may be local
to your calling functions. You will have to define the arrays according
to AES manual, and fill in values according to the function you want
to call, except for the contrl[] array. It's values are passed to this
function by encoding them into a long value, where contrl[0] gets the
highest byte and contrl[3] the lowest one.
     Example for appl_init():

     short appl_init()
     {
          short     my_int_in[16]; /* you need as much elements as    */
          short     my_int_out[7]; /* claimed in contrl[] values */
          long my_addr_in[2]; /* but at least one for any of     */
          long my_addr_out[2];     /* these arrays     */

          c_aes(0x0a000100, my_int_in, my_int_out, my_addr_in,
                     my_addr_out);

          if(gl_apversion) /* test wether AES are running     */
               return(my_int_out[0]);
          else
               return(-1);
     }

     See: call_aes(), callaes()

call_aes()
     void call_aes(unsigned long control)

     You will have define global known arrays using this function.

     short     int_in[16];
     short     int_out[7];
     long addr_in[2];
     long addr_out[2];

     Fill in the values you have to for calling the AES function.
You don't need the contrl[] array, it is already included in xaesfast.
It is filled using the encoded contrl[] array value wich is the function's
parameter. Then use the call_aes() function, and get the return value
from int_out[0].
     Example for appl_init():

     short appl_init()
     {
          gl_apversion = 0;
          call_aes(0x0a000100);
          if(gl_apversion) /* test wether AES are running     */
               return(int_out[0]);
          else
               return(-1);
     }
     See: c_aes(), callaes()

callaes()
     void callaes(void)

     You will have define global known arrays using this function. To
have acces to the contrl[] array use the following define:

     #define contrl aescontrol

     short     int_in[16];
     short     int_out[7];
     long addr_in[2];
     long addr_out[2];

     Fill in the values you have to for calling the AES function, call the
function, and get the reurn value from int_out[0] - if there is any.
     Example for appl_init():

     short appl_init()
     {
          gl_apversion = 0;
          contrl[0] = 10;          /* 0x0a   */
          contrl[1] = 0;      /* no int_in value  */
          contrl[2] = 1;      /* one int_out value     */
          contrl[3] = 0;      /* no addr_in value */
          contrl[4] = 0;      /* no addr_out value     */

          callaes();

          if(gl_apversion) /* test wether AES are running     */
               return(int_out[0]);
          else
               return(-1);
     }
     See: c_aes(), call_aes()

fsel_input()
     int fsel_input(char *PATH, char *name, int *button)

     Call the AES fsel_input() function.

     SEE:  fsel_sm() fsel_exinput() fsel_emulation()

fsel_exinput()
     int fsel_exinput(char *PATH, char *name, int *button, char *title)

     This function replaces the function in AESFAST which tested for
the presence of >= TOS 1.4 and (if not found) simulated the modern file
selector.  This function only tests wether to call fsel_exinput() or
fsel_input() depending on the AES version.

     SEE:  fsel_sm() fsel_input() fsel_emulation()

fsel_sm()
     int fsel_sm(char *PATH, char *name, int *button, char *title)

     This function (small emulation) replaces the AES call fsel_exinput(),
testing for the presence of >= TOS 1.4 and (if not found) simulated the
modern file selector.  This function does the same thing, like
fsel_emulation() but has a new binding and is considerably smaller.  It
should reduce the size of any program using the old binding by 700 bytes.

     SEE:  fsel_exinput() fsel_input() fsel_emulation()
           fsel() fsel_e() fsel_ex()


fsel_emulation()
     int fsel_emulation(char *PATH, char *name, int *button, char *title)

     This function is the original AESFAST function in which tested for
the presence of >= TOS 1.4 and (if not found) simulated the modern file
selector.

     SEE:  fsel_sm(), fsel_input(), fsel_emulation() fsel() fsel_e()
           fsel_ex()

evnx_multi()
int evnx_multi(XMULTI *xm);

     Call evnt_multi() passing just a single pointer.

Input:
     The xm parameter is a pointer to an XMULTI structure.

Returns:
     The mask of events which occurred; xm->mwhich.

Details:
     This function keeps all the input and output parms for an
evnt_multi() call in a single structure.  This is more efficient than
stacking and unstacking 50-some bytes of parameters on each call, and
it also allows you to "pass off" event handling to a series of event
handlers by passing a single pointer to each handler.  GemFast 2.0 will
make heavy use of the latter technique.

rsc_treefix()
void rsc_treefix(OBJECT *ptree)

     Performs xywh fixup on all objects in a tree.

Input:
     The ptree parameter is a pointer to the tree which needs
     resolution fixup.

Details:
     This function calls rsrc_obfix() for every object in the tree.  It's
just a shortcut for calling the GEM object fixup for all objects in a tree,
and does not provide any custom resolution fixup, scaling, etc.

     Use this function to do fixup on resource trees which are embedded
in your source code.  Do NOT use this function on trees loaded via
rsrc_load(), since that function automatically applies resolution fixup
as it loads the resource data.

rsc_gstrings()
void rsc_gstrings(OBJECT *ptree, int object, char **ppstr, ...)

     Get the string pointers for one or more string-related
objects in a dialog tree.

Input:
     The ptree parameter is a pointer to the dialog tree
     containing the string-related objects.
     The object parameter is the index of the first object for which you
     want to retrieve the string pointer.
     The ppstr parameter is a pointer to your variable (char* type). The
     string pointer for the object is stored here.
     The ... parameters are additional object/ppstr pairs.  Use an object
     number of -1 to indicate the end of the list.

Details:
     This allows you to easily initialize your local string pointers to
point at string-related objects in a dialog tree.  The description of
the obj_ppstring() function contains details on what objects are
string-related.

     You must specify at least one object/ppstr pair following the
tree pointer in the call.  You can specify any number of pairs
following the first one to retrieve the pointers for more than one
object with a single call.  Specify -1 for the index following the last
pair.  (There is no need to supply a pointer to go with the -1 object
index.)

    This function understands how to find the real string pointer for
each of string-related object type.  It copes with the INDIRECT flag.
It understands extended G_USERDEF objects, where ob_spec has been moved
into the XUSERBLK.

     This function gives you pointers which point into the resource
data area.  If you modify the strings using these pointers, please
remember that your resource editor has only allocated enough space in
the resource data to hold the strings as you typed them when you built
the object.  In other words, you can define a button as "OK", and then
at runtime use this function to get a pointer to the button text.  But,
if you do something like strcpy(buttonptr, "Not Okay"); then you end up
corrupting the resource data, because you copied an 8-character string
into a space only 2 characters wide.

     You can avoid this modify-in-place problem by defining your
strings big enough in the resource editor, or by using rsc_sstrings()
to make the objects point to strings allocated within your program
rather than working with the strings directly in the resource data
area.  In this case, you can define dummy strings (I use "x") in the
resource editor to avoid wasting space, since the strings you define
are not used at runtime anyway after you use rsc_sstrings() to point
objects at your program-defined strings.

rsc_sstrings()
void rsc_sstrings(OBJECT *ptree, int object, char *pstr, ...)

     Set the string pointers for one or more string-related objects in a
dialog tree.

Input:
     The ptree parameter is a pointer to the dialog tree containing
     the string-related objects.
     The object parameter is the index of the first object for which
     you want to set the string pointer.
     The pstr parameter is a pointer to your string variable (char
     [] or "" type). This pointer is copied into the string object's
     string pointer field (ob_spec, te_ptext, etc).

     The ... parameters are additional object/pstr pairs.  Use an
     object number of -1 to indicate the end of the list.

Details:
     This allows you to easily initialize string-related objects in a
dialog tree to point at strings defined within your program.  The
description of the obj_ppstring() function contains details on what
objects are string-related.

     You must specify at least one object/pstr pair following the
tree pointer in the call.  You can specify any number of pairs
following the first one to retrieve the pointers for more than one
object with a single call.  Specify -1 for the index following the last
pair.  (There is no need to supply a pointer to go with the -1 object
index.)

      This function understands how to find the real string pointer for
each of string-related object type.  It copes with the INDIRECT flag.
It understands extended G_USERDEF objects, where ob_spec has been moved
into the XUSERBLK.

      This function attaches string data defined in your program to
string-related objects in your dialog trees.  This is especially handy
for editable text objects, because some resource editors don't allocate
enough space for the object in the resource data.  If you define an
editable text object and supply a te_pvalid string that allows 20 chars
of input, but you define an initial string of "abc" for the field, some
resource editors will only allocate 3 bytes of resource string space
for the field.  When the user enters 20 chars of data into the 3-byte
field, other resource data gets corrupted.  To avoid this, you can
allocate a 20-byte character array in your program, and use this
function to make the editable field's te_ptext pointer point at your
array instead of the 3-byte area in the resource data.

rsc_gspec()
long rsc_gspec(OBJECT *tree, short object);

     Get ob_spec value from an object within a tree.

Input:

     The <tree> parameter is a pointer to an AES OBJECT tree.

     The <object> parameter is the index of the object to get the
ob_spec value for.

Details:

    This function gets one string ob_spec from within a resource tree.  It
knows the difference between text and non-text objects, and gets the ob_spec
value as appropriate.  It also understands INDIRECT objects.

rsc_gpointer()
char *rsc_gpointer (OBJECT *tree, short object);

     Get pointer to single string within a tree.

Input:
     The <tree> parameter is a pointer to an AES OBJECT tree.

     The <object> parameter is the index of the object to get the
string for.

Details:

     This function gets one string pointerfrom within a resource tree.  It
knows the difference between text and non-text objects, and gets the
te_ptext value as appropriate.  It also understands INDIRECT objects.

rsc_sspec()
void rsc_sspec(OBJECT *tree, short object, long obspec_value);

     This function sets one ob_spec from an object within
a resource tree.

Input:

     This function sets one ob_spec from within a resource tree.  It knows
the difference between text and non-text objects, and sets the ob_spec value
as appropriate.  It also understands INDIRECT objects.

rsc_spointer()
void rsc_spointer(OBJECT *tree, short object, char *pointer);

     This function sets one string pointer from an object within
a resource tree.

Input:

     This function sets one string pointer from within a resource tree.  It
knows the difference between text and non-text objects, and sets the
te_ptext value as appropriate.  It also understands INDIRECT objects.

rc_gadjust()
GRECT *rc_gadjust(GRECT *prect, int hadjust, int vadjust)

     Adjust the size of a GRECT rectangle.

Input:
     The prect parameter is a pointer to the rectangle to be adjusted.

     The hadjust parameter is the number of pixels to adjust by in the
     horizontal direction.  Positive values enlarge the rectangle;  negative
     values shrink it.

     The vadjust parameter is the number of pixels to adjust by in the
     vertical direction.  Positive values enlarge the rectangle;  negative
     values shrink it.

Returns:
     The pointer to the rectangle.

Details:
     This function makes a GRECT rectangle describe a larger or smaller
area.  The rectangle remains centered on its original location, and grows or
shrinks equally on each side in the adjusted dimension(s).

     The x/y locations are never allowed to go negative (they are
clipped to zero). The w/h sizes are never allowed to fall below 1.

rc_vadjust()
VRECT *rc_vadjust(VRECT *prect, int hadjust, int vadjust)

     Adjust the size of a VRECT rectangle.

Input:
     The prect parameter is a pointer to the rectangle to be adjusted.

     The hadjust parameter is the number of pixels to adjust by in the
     horizontal direction.  Positive values enlarge the rectangle;  negative
     values shrink it.

     The vadjust parameter is the number of pixels to adjust by in the

     vertical direction.  Positive values enlarge the rectangle;  negative
     values shrink it.

Returns:
     The pointer to the rectangle.

Details:
     This function makes a VRECT rectangle describe a larger or smaller
area.  The rectangle remains centered on its original location, and grows or
shrinks equally on each side in the adjusted dimension(s).

     The x/y locations are never allowed to go negative (they are
clipped to zero). The w/h sizes are never allowed to fall below 1.

rc_vtog()
GRECT *rc_vtog(VRECT *pvrect, GRECT *pgrect)

    Convert a VRECT rectangle to a GRECT rectangle.

Input:
    The pvrect parameter is a pointer to the source VRECT.
    The pgrect parameter is a pointer to the destination GRECT.

Details:
    The source VRECT is converted to the equivalent GRECT. Do NOT
specify the same rectangle for source and destination.

     A VRECT describes an area by the x and y coordinates of diagonally
opposite corners.  A GRECT describes an area by x, y, width and height.
This function translates a VRECT to a GRECT as follows:

     pgrect->g_x = pvrect->v_x1;
     pgrect->g_y = pvrect->v_y1;
     pgrect->g_w = pvrect->v_x1 - pvrect->g_x2 + 1;
     pgrect->g_h = pvrect->v_y1 - pvrect->g_y2 + 1;

rc_gtov()
VRECT *rc_gtov(GRECT *pgrect, VRECT *pvrect)

     Convert a GRECT rectangle to a VRECT rectangle.

Input:
     The pgrect parameter is a pointer to the source GRECT.
     The pvrect parameter is a pointer to the destination VRECT.

Returns:
     The pointer to the destination VRECT.

Details:
     The source GRECT is converted to the equivalent VRECT. Do NOT specify
the same rectangle for source and destination.
     A GRECT describes an area by x, y, width and height.  A VRECT describes
an area by the x and y coordinates of diagonally opposite corners.  This
function translates a GRECT to a VRECT as follows:

              pvrect->v_x1 = pgrect->g_x;
              pvrect->v_y1 = pgrect->g_y;
              pvrect->v_x2 = pgrect->g_x + pgrect->g_w - 1;
              pvrect->v_y2 = pgrect->g_y + pgrect->g_h - 1;

rc_union()
void rc_union(GRECT *sourcerect, GRECT *destrect)

     Computes a single rectangle that encompasses the area of
both the original rectangles.

Input:
     The sourcerect parameter is a pointer to the source rectangle.

     The destrect parameter is a pointer to the destination rectangle.  The
     destination rectangle is used for input and output.

Details:
     This function calculates the single large rectangle that encompasses
all the area of both rectangles.
     This function does NOT clip to the physical screen automatically.
Negative values in the returned x and y coordinates are possible if negative
values existed in the inputs.

rc_intersect()
int rc_intersect(GRECT *sourcerect, GRECT *destrect)

     Calculate the intersecting portion of two rectangles.

Input:
     The sourcerect parameter is a pointer to the source (or
     clipping) rectangle.

     The destrect parameter is a pointer to the destination
     rectangle.  The destination rectangle is used for input and output.

Returns:
     TRUE (1) if the two rectangles intersect, or FALSE (0) if they do not
     intersect.  When the return value is FALSE, the contents of the
     destination rectangle are undetermined.

Details:
     You can think of this function as clipping the destination rectangle
against the area of the source.
     On entry, the destination rectangle describes an area that may or may
not have pixels in common with the source (or clipping) rectangle.  This
function modifies the destination rectangle to describe the area where the
two rectangles intersect.  If they don't intersect at all, this function
returns FALSE, and the destination rectangle is left in an undetermined
state.

     This function is typically used in window redraw loops, to process the
window rectangle list.  It can also be used in general-purpose drawing
situations, especially to generate a clip rectangle to keep a blit from
going outside the window work area or off the screen.

     This function does NOT clip to the physical screen automatically.
Negative values in the returned x and y coordinates are possible if negative
values existed in the inputs.

rc_copy()
void rc_copy(void *sourcerect, void *destrect)

    Copy the source rectangle to the destination rectangle.

Input:
    The sourcerect parameter is a pointer to the source
    rectangle.

    The destrect parameter is a pointer to the destination
    rectangle.

Details:
    This copies a rectangle, or more accurately, 8 bytes of
word-aligned data.

rc_equal()
int rc_equal(void *rect1, void *rect2)

    Returns TRUE if two rectangles are identical.

Input:
    The rect1 and rect2 parameters are pointers to the
    rectangles to be compared.

Returns:
    TRUE (non-zero) if the rectangles are identical, FALSE (0)
    if they're not.

Details:
    For the rectangles to be identical, all four values (xywh) must be
equal.  More accurately, this function compares 8 bytes of word-aligned
data.

objcl_calc()
void objcl_calc (OBJECT *tree, short object, GRECT *grect, VRECT *vrect);

     This routine simultaneously calculates the GRECT and VRECT clipping
rectangles that describe an object.

Input:
      grect: A pointer to a GRECT structure or NULL.
      vrect: A pointer to a VRECT structure or NULL.

Details:
     If object has outside borders or is OUTLINED and/or SHADOWED,
clipping sizes are calculated accordingly.

obj_flchange()
void obj_flchange(OBJECT *ptree, int object, int newflags,
                        int drawflag [ ,GRECT *cliprect ])

     Change an object's flags, with optional redraw.

Input:
    The ptree parameter is a pointer to the tree containing the
    object to change.

    The object parameter is the index of the object to change.

    The newflags parameter specifies which object flag bits to
    change; details below.

    The drawflag parameter specifies whether the object is to be
    visually updated on the screen, use one of the following:

    OBJ_NODRAW   (0) -    Don't update the screen.
    OBJ_WITHDRAW (1) -    Update the screen.
    OBJ_CLIPDRAW (2) -    Update the screen with clipping.

    The cliprect parameter is an optional pointer to a rectangle
    which will be used to clip the redraw of the object.  This
    parameter is only used when the drawflag parameter is equal
    to OBJ_CLIPDRAW.

Details:
    This function provides a simple way to change the object flag bits
for any object.

    If the high bit of the newflags parameter is set, an AND is used to mask
off bits in the object flags.  If the high bit is not set, an OR is used to
set bits in the object flags.  This allows a newflags value of DEFAULT to
set the default bit, and a value of ~DEFAULT to unset it.

    When the drawflag parameter is non-zero, an objc_draw() call is
automatically done after the flags are changed.  The objc_draw() is always
done starting at the root object and drawing to MAX_DEPTH, and the draw is
clipped to the on- screen rectangle of the object being changed.  This
allows a change that sets HIDETREE to properly hide the object visually,
because the parent of the object is redrawn, but the object itself is not.

    When your dialog is in a window or another situation in which you might
need to clip the redraw, use the OBJ_CLIPDRAW option, and provide a pointer
to the clipping rectangle.  If the draw option is not CLIPDRAW, the clip
pointer need not be specified.

obj_stchange()
void obj_stchange(OBJECT *ptree, int object, int newstate,
                        int drawflag [, GRECT *cliprect ])

    Change an object's state, with optional redraw.

Input:
    The ptree parameter is a pointer to the tree containing the
    object to change.

    The object parameter is the index of the object to change.

    The newstate parameter specifies which object state bits to
    change; details below.

    The drawflag parameter specifies whether the object is to be
    visually updated on the screen, use one of the following:

    OBJ_NODRAW   (0) -    Don't update the screen.
    OBJ_WITHDRAW (1) -    Update the screen.
    OBJ_CLIPDRAW (2) -    Update the screen with clipping.

    The cliprect parameter is an optional pointer to a rectangle
    which will be used to clip the redraw of the object.  This
    parameter is only used when the drawflag parameter is equal
    to OBJ_CLIPDRAW.

Details:
    This function provides a simple way to change the object state bits
for any object.

    If the high bit of the newstate parameter is set, an AND is used to mask
off bits in the object flags.  If the high bit is not set, an OR is used to
set bits in the object flags.  This allows a newstate value of SELECTED to
set the bit, and a value of ~SELECTED to unset it.

    When the drawflag parameter is non-zero, an objc_draw() call is
automatically done after the flags are changed.  The objc_draw() is always
done starting at object and drawing to MAX_DEPTH, and the draw is clipped to
the on-screen rectangle of the dialog that contains it.

    When your dialog is in a window or another situation in which you might
need to clip the redraw, use the OBJ_CLIPDRAW option, and provide a pointer
to the clipping rectangle.  If the draw option is not CLIPDRAW, the clip
pointer need not be specified.

obj_offxywh()
void obj_offxywh(OBJECT *ptree, int object, GRECT *prect)

    Get the screen-adjusted xywh values for an object.

Input:
    The ptree parameter is a pointer to the object tree.

    The object parameter is the index of the object.

    The prect parameter is a pointer to the rectangle into which
    the object's xywh values are returned.

Details:
    This function gets the screen-adjusted xywh values for the object.
It does NOT take into account that some objects are visually larger
than their xywh values imply (ie, OUTLINED objects). Use the
obj_clcalc() function if you need to account for the actual visual area
an object occupies on the screen.

obj_xywh()
void obj_xywh(OBJECT *ptree, int object, GRECT *prect)

    Get the xywh values for an object.

Input:
    The ptree parameter is a pointer to the object tree.

    The object parameter is the index of the object.

    The prect parameter is a pointer to the rectangle into which
    the object's xywh values are returned.

Details:
    This function gets the xywh values for the object.  The values
returned are straight from the object;  they are relative to the
object's parent, not to the screen.

       SEE: obj_offxywh() obj_clcalc()

obj_xtfind()
int obj_xtfind(OBJECT *ptree, int parent, int xtype)

    Finds the object with the specified extended object type.

Input:
    The ptree parameter is a pointer to the tree.

    The parent parameter is the index of the parent which
    contains the objects to be scanned.

    The xtype parameter specifies the extended object type to
    search for.

Returns:
    The index of the object having the specified extended type,
    or NO_OBJECT (-1) if nothing was found.

Details:
    This function scans the children of the specified parent object.  It
compares the extended object type in each child to the specified xtype,
and returns the index of the first object which matches.  If none of
the children have the specified extended type, NO_OBJECT is returned.

    Extended object types are stored in the upper byte of the ob_type
word. GEM only uses the lower 8 bits of the ob_type value, and ignores
any value in the upper 8 bits.  All GemFast library routines which look
at or set the ob_type field also work with the lower 8 bits, and ignore
(or preserve) the upper 8 bits.

    So, you can store any information you want into the upper 8 bits of
the ob_type word.  There are many things that can be done with it.

       SEE: obj_bmbuttons() rsc_sxtypes()

obj_rbfind()
int obj_rbfind(OBJECT *ptree, int parent, int rbstate)

    Finds the selected button in a group of radio buttons.

Input:
    The ptree parameter is a pointer to the object tree.

    The parent parameter is the index of the parent which
    contains the radio buttons.

    The rbstate parameter is the ob_state mask to look for.

Returns:
    The index of the selected object, or NO_OBJECT (-1) if no
    radio buttons are in the desired state.

Details:
    This function walks through the children of the specified parent.
For each child object with the RBUTTON bit set in the ob_flags, it does
an AND of the child's ob_state against the rbstate parameter.  It
returns the index of the first child object which has a non-zero result
from the AND. It returns NO_OBJECT if the result was zero for all
children.

    The most common use of this function is to pass SELECTED for the
rbstate parameter.  Sometimes it's handy to use OUTLINED or another
state to indicate selection of an object, so this function allows any
state bit(s) to be specified.  If you pass a combination of bits, (ie,
(SELECTED|OUTLINED)), then this function finds the first radio button
with either (not both) of those bits set.

       SEE: obj_rbselect()

obj_rbselect()
int obj_rbselect(OBJECT *ptree, int selobj, int selstate)

    Deselect the current radio button, and select a new one.

Input:
    The ptree parameter is a pointer to the object tree.

    The selobj parameter is the index of the new radio button to
    be selected.

    The selstate parameter specifies the ob_state bits which are
    turned off in the current radio button and turned on in the
    new one.

Returns:
    The index of the radio button that was selected before the
    call, or NO_OBJECT if no buttons were previously selected.

Details:
    This function is the easiest way to set a given radio button to a
selected state.  If a button in the group is already selected, this function
de-selects it before selecting the new button.

    Note that this function does NOT update the buttons on-screen, it
only changes the ob_state words.  Use this for setting up a dialog
before displaying it.  After that, the GEM forms manager updates the
ob_state and the on-screen object during dialog processing.

       SEE: obj_rbfind()

obj_parent()
int obj_parent(OBJECT *ptree, int object)

    Return the parent object for the specified object.

Input:
    The ptree parameter is a pointer to the object tree.

    The object parameter is the index of the object.

Returns:
    The index of the parent object.

Details:
    By definition, the root object has no parent.  If you try to get the
parent of the root, zero is returned, as if the root were the
parent of itself.

frmx_center()
int frmx_center(OBJECT *ptree, GRECT *prect)

    Call form_center() passing a single pointer for the return
values.

Input:
    The ptree parameter is a pointer to the object tree to be
    centered.

    The prect parameter is a pointer to a GRECT structure into
    which the on-screen sizes of the dialog are returned.

Returns:
    TRUE (1)

Details:
    This function allows you to pass a single pointer to an output
rectangle, instead of the four pointers required by the standard
form_center() function.

       SEE: frm_sizes()

winx_calc()
int winx_calc(int type, int kind, GRECT inrect, GRECT *outrect)

    Call wind_calc() passing a single pointer to the output.

Input:
    The type, kind, and inrect parameters are identical to the
    corresponding wind_calc() parameters.

    The outrect parameter is a pointer to the output rectangle
    where the results of the calculation are stored.

Returns:
    Zero on error, or non-zero on success.

Details:

    Please note that the inrect parameter is a structure passed by value (4
values stacked) not a pointer to a rectangle.

winx_get()
int winx_get(int whandle, int field, GRECT *outrect)

    Call wind_get() passing a single output pointer.

Input:
    The whandle and field parameters are identical to the
    corresponding wind_get() parameters.

    The outrect parameter is a pointer to the output rectangle
    where the results of the query are stored.

Returns:
    Zero on error or non-zero on success.

Details:
    Please note that this function will always write 8 bytes of output to
the memory location indicated by outrect even if the type of query you're
doing normally returns less information that.  (IE, don't use
&integer_variable for this parameter, or the memory following the integer
variable will be overwritten as well.)

do_bell()
     void do_bell(short reserved, void *reserved2);

     For AES Applications are not allowed to access any console files
usually, this function allows to beep using the soundchip function
Dosound().


MagiC AES functions
     This is a list of currently supported MagiC AES Functions.
Some of them are GEM 2.x/3.x Functions. See MagiC docs for usage.
Only call with a value in _magx.

     short     form_xdial(short flag,
                    short littlx, short littly, short littlw, short littlh,
                    short bigx, short bigy, short bigw, short bigh,
                    void **flydial, void *dummy);
          There seems to be a bug in MagiC docs. Please add this
          'dummy', it maybe a 'NULL'.

     short     form_xdo( OBJECT *form, short start, short *lastcrsr,
                              XDO_INF *tabs, void *flydial);
     short     form_xerr(long errcode, char *errfile);
     short     form_popup(OBJECT *tree, short x, short y);
     short     scrp_clear();
     void shel_rdef(char *lpcmd, char *lpdir);
     void shel_xrdef(char *lpcmd, char *lpdir, char **buffer);
          You'll get the pointer to the shell's name buffer as documented
          by MagiC with this special binding of shel_rdef().
     void shel_wdef(char *lpcmd, char *lpdir);
     short     menu_click(short val, short setit);
     short     menu_unregister(short mid);


XGEMFAST.H
     Header File:  XGEMFAST.H

     This file contains definitions, structure declarations, external
variable declarations, and enumerations related to the AES/VDI.
The function prototypes of all not standard AES functions are included,
too. And you'll find some hints how to use the shel_write() call with
TOS, MultiTOS and MagiC there.

      Structure GRECT                Structure VRECT
      Structure RSHDR                Structure OBJECT
      Structure PARMBLK              Structure USERBLK
      Structure BITBLK               Structure ICONBLK, XICONBLK
      Structure TEDINFO, XTEDINFO    Structure MFORM
      Structure MENU                 Structure MN_SET
      Structure CICON                Structure CICONBLK
      Structure MFDB, FDB

     Non-Standard Extensions:

      Union     OBSPEC               Bitfield  bfOBSPEC
      Bitfield  bfIBCHAR             Bitfield  bfTECOLOR
      Structure SH_WPCMD             Structure XMULTI
      Structure XMOUSE

      Macro:    _XAESFAST            Macro:    _XVDIFAST
      Macro:    _XAESFASTVERSION     Macro:    _XVDIFASTVERSION
      Macro:    _XGEMFAST            Variable: short global[15]

      Variable: short gl_apversion   Variable: short gl_apcount
      Variable: short gl_apid        Variable: long gl_apprivate
      Variable: OBJECT **gl_apptree  Variable: RSHDR *gl_aprshdr
      Variable: RSHDR *gl_ap1resv    Variable: int gl_ap2resv[6]

_XVDIFASTVERSION
     Macro:  _XVDIFASTVERSION

     This is the version number string of _XVDIFAST.

_XAESFASTVERSION
     Macro:  _XAESFASTVERSION

     This is the version number string of _XAESFAST.

_XGEMFAST
     Macro:  _XGEMFAST

     This macro is always TRUE.  GEMFAST_H/AESUTIL_A are als
GEMF_VERSION is set to 0x0141 because XGemFast is based on t
of the GemFast library.

GRECT
     This structure represents a GEM rectangle with the upper-left
corner placed at g_x, g_y, a width of g_w, and a height of g_h.

typedef struct grect {
     short g_x;
     short g_y;
     short g_w;
     short g_h;
} GRECT;

VRECT
     This structure represents a VDI rectangle with the upper-left
corner placed at v_x1, v_y1 and the lower-right corner placed at v_x2,
v_y2.  This type of rectangle is used by VDI functions - not as
a structure but as an array 'pxyarray' You can use this structure
where you VDI docs mention these pxyarrays.

typedef struct vrect {
     short v_x1;
     short v_y1;
     short v_x2;
     short v_y2;
} VRECT;

MFDB
     The VDI Memory Form Definition Block. It describes a raster, and
is used by the VDI raster handling functions.  To perform a screen to
screen raster copy, set the source and destination fd_addr to NULL.
The VDI will fill in the appropriate values.  When performing a screen
to memory raster copy, please remember that high resolution screens
with many colours (such as Falcon TrueColour) can use massive ammounts
of memory.

typedef struct mfdbstr {
     FDADDR         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;
} MFDB;

RSHDR
typedef struct rshdr {
     short            rsh_vrsn;      /* Resource Structure Version #   */
     unsigned short   rsh_object;    /* Offset To First OBJECT         */
     unsigned short   rsh_tedinfo;   /* Offset To First TEDINFO        */
     unsigned short   rsh_iconblk;   /* Offset To First ICONBLK        */
     unsigned short   rsh_bitblk;    /* Offset To First BITBLK         */
     unsigned short   rsh_frstr;     /* Offset To Free String index    */
     unsigned short   rsh_string;    /* Offset To String Data          */
     unsigned short   rsh_imdata;    /* Offset To Image Data           */
     unsigned short   rsh_frimg;     /* Offset To Free Image index     */
     unsigned short   rsh_trindex;   /* Offset To Tree index           */
     unsigned short   rsh_nobs;      /* Number Of OBJECTs              */
     unsigned short   rsh_ntree;     /* Number OBJECT Trees            */
     unsigned short   rsh_nted;      /* Number Of TEDINFO Structures   */
     unsigned short   rsh_nib;       /* Number Of ICONBLK Structures   */
     unsigned short   rsh_nbb;       /* Number Of BITBLK Structures    */
     unsigned short   rsh_nstring;   /* Number Of Free Strings         */
     unsigned short   rsh_nimages;   /* Number Of Free Images          */
     unsigned short   rsh_rssize;    /* Total Bytes In Resource        */
} RSHDR;

OBJECT
typedef struct object {
     short            ob_next;   /* -> OBJECT's Next Sibling      */
     short            ob_head;   /* -> Head Of OBJECT's Children  */
     short            ob_tail;   /* -> Tail Of OBJECT's Children  */
     unsigned short   ob_type;   /* Type Of OBJECT                */
     unsigned short   ob_flags;  /* Flags                         */
     unsigned short   ob_state;  /* State                         */
     OBSPEC           ob_spec;   /* A UNION!  See: OBSPEC         */
     short            ob_x;      /* Upper Left Corner Of OBJECT   */
     short            ob_y;      /* Upper Left Corner Of OBJECT   */
     short            ob_width;  /* Width Of OBJECT               */
     short            ob_height; /* Height Of OBJECT              */
} OBJECT;

OBSPEC
     The UNION declaration for 'ob_spec' in the OBJECT structure.

typedef union Obspec {
     long      obspec;
     bfOBSPEC  bfobspec;   /*  A Bitfield!  See:  bfOBSPEC  */
     TEDINFO   *tedinfo;
     ICONBLK   *iconblk;
     BITBLK    *bitblk;
     USERBLK   *userblk;
     char      *free_string;
} OBSPEC;

bfOBSPEC
     The bitfield declaration for 'bfobspec' in the OBSPEC union, from
the OBJECT structure.

typedef struct bfObspec {
    unsigned character:8;
    signed   framesize:8;
    unsigned framecol:4;
    unsigned textcol:4;
    unsigned textmode:1;
    unsigned fillpat:3;
    unsigned innercol:4;
} bfOBSPEC;

     This is not the order it appears in the XGEMFAST.H header file!

     The following is an example of the correct way to use this powerful
structure:

     OBJECT *ob;
     rsrc_gaddr(R_TREE, MYTREE, &ob);

     ob->ob_spec.bfobspec.innercol=dialog_background_colour;
     ob->ob_spec.bfobspec.fillpat=dialog_fill_pattern;

     /*  A complex operation becomes simple.  */


PARMBLK
typedef struct parm_blk {
     OBJECT      *pb_tree;
     short       pb_obj;
     short       pb_prevstate;
     short       pb_currstate;
     short       pb_x,  pb_y,  pb_w,  pb_h;
     short       pb_xc, pb_yc, pb_wc, pb_hc;
     long        pb_parm;
} PARMBLK;

USERBLK
typedef struct user_blk {
     long (*ub_code)();
     long ub_parm;
} USERBLK;

BITBLK
typedef struct bit_block {
     short  *bi_pdata;          /* Pointer To Bit Forms Data     */
     short  bi_wb;              /* Width Of Form In Bytes        */
     short  bi_hl;              /* Height In Lines               */
     short  bi_x;               /* Source X In Bit Form          */
     short  bi_y;               /* Source Y In Bit Form          */
     short  bi_color;           /* Foreground Color Of Bit Form  */
} BITBLK;

ICONBLK
typedef struct icon_block {
     short  *ib_pmask;
     short  *ib_pdata;
     char   *ib_ptext;
     short  ib_char;
     short  ib_xchar;
     short  ib_ychar;
     short  ib_xicon;
     short  ib_yicon;
     short  ib_wicon;
     short  ib_hicon;
     short  ib_xtext;
     short  ib_ytext;
     short  ib_wtext;
     short  ib_htext;
} ICONBLK;

     SEE: XICONBLK

XICONBLK
typedef struct Xicon_block {
     short  *ib_pmask;
     short  *ib_pdata;
     char   *ib_ptext;
     bfIBCHAR  ib_char;     /* A Bitfield!  SEE:  bfIBCHAR */
     short  ib_xchar;
     short  ib_ychar;
     short  ib_xicon;
     short  ib_yicon;
     short  ib_wicon;
     short  ib_hicon;
     short  ib_xtext;
     short  ib_ytext;
     short  ib_wtext;
     short  ib_htext;
} XICONBLK;

     This structure is the same as the ICONBLK structure, but it has an
ib_char bitfield.

     SEE:  ICONBLK

bfIBCHAR
     This is the bitfield declaration for 'ib_char', from the XICONBLK
structure.

typedef struct bfibchar {
    unsigned iconcolor:4;
    unsigned bgcolor:4;
    unsigned iconchar:8;
} bfIBCHAR

This is not the order it appears in the XGEMFAST.H header file!

CICON
typedef struct cicon_data {
     /* Number Of Planes In The Following Data */
     short num_planes;

     /* Pointer -> Color Bitmap In Standard Form */
     short *col_data

     /* Pointer -> Single Plane Mask Of col_data */
     short *col_mask;

     /* Pointer -> Single Plane Mask Of Selected Icon */
     short *sel_data;
     short *sel_mask;

     /* Pointer -> Next Icon For A Different Resolution */
     struct cicon_data *next_res;
} CICON;

typedef struct cicon_blk {
    ICONBLK monoblk; /* Default Monochrome Icon */
    CICON *mainlist; /* List Of Color Icons For Different Resolutions */
} CICONBLK;

TEDINFO
typedef struct text_edinfo {
     char   *te_ptext;     /* Pointer To Text                    */
     char   *te_ptmplt;    /* Pointer To Template                */
     char   *te_pvalid;    /* Pointer To Validation Characters   */
     short  te_font;       /* Font                               */
     short  te_junk1;      /* Junk                               */
     short  te_just;       /* Justification                      */
     short  te_color;      /* Color Information Word             */
     short  te_junk2;      /* Junk                               */
     short  te_thickness;  /* Border Thickness                   */
     short  te_txtlen;     /* Length Of Text String              */
     short  te_tmplen;     /* Length Of Template String          */
} TEDINFO;

     SEE:  XTEDINFO

XTEDINFO
typedef struct Xtext_edinfo {
    char   *te_ptext;             /* Ptr -> Text               */
    char   *te_ptmplt;            /* Ptr -> Template           */
    char   *te_pvalid;            /* Ptr -> Validation Chrs.   */
    short  te_font;               /* Font                      */
    short  te_junk1;              /* Junk Word                 */
    short  te_just;               /* Justification             */
    bfTECOLOR  te_color;          /* Color Information Word    */
    short  te_junk2;              /* Junk Word                 */
    short  te_thickness;          /* Border Thickness          */
    short  te_txtlen;             /* Length Of Text String     */
    short  te_tmplen;             /* Length Of Template String */
} XTEDINFO;

     This structure makes use of the bfTECOLOR bitfield.

     SEE:  TEDINFO

bfTECOLOR
     This is the bitfield declaration for 'te_color', from the XTEDINFO
structure.

typedef struct bftecolor {
    unsigned framecolor:4;
    unsigned textcolor:4;
    unsigned textmode:1;
    unsigned fillpat:3;
    unsigned innercol:4;
}bfTECOLOR;

     This is not the order it appears in the XGEMFAST.H header file!

MFORM
     A Mouse Form Definition Block, as used by AES to change the mouse.

typedef struct mfstr {
     short mf_xhot;
     short mf_yhot;
     short mf_nplanes;
     short mf_fg;
     short mf_bg;
     short mf_mask[16];
     short mf_data[16];
} MFORM;

MENU
typedef struct _menu
{
    OBJECT *mn_tree;     /*  - the object tree of the menu   */
    short  mn_menu;      /* - the parent object of the menu items    */
    short  mn_item;      /* - the starting menu item */
    short  mn_scroll;    /* - the scroll field status of the menu    */
                    /* 0    - The menu will not scroll
                     * !0 - it will scroll if the number of menu
                     *   items exceed the menu scroll height. The
                     * NOTE: If the scroll field status is !0, the menu
                     *   items must consist entirely of G_STRINGS.
                     */
    short  mn_keystate;
              /* - The CTRL, ALT, SHIFT Key state at the time the */
} MENU;

MN_SET
typedef struct _mn_set {
    long    Display;    /* - the submenu display delay  */
    long    Drag;       /* - the submenu drag delay */
    long    Delay;      /* - the single-click scroll delay  */
    long    Speed;      /* - the continuous scroll delay    */
    short   Height;     /*  - the menu scroll height    */
} MN_SET;

SH_WPCMD
     A structure for the new shel_write call (AES 4.00). This is a xgemfast
extension to the GEM manual

typedef struct  Sh_wpcmd {
    char    *cmd;           /* the command, needs no path or extension  */
    long    psetlimit;
    long    prenice;
    char    *cwd;           /* the process' cwd or NULL */
    char    *env;
} SH_WPCMD;

     Use a this structur's pointer as argument for parameter sh_wpcmd
with the extension bits set in sh_wdoex.

     I have defined some sh_wdoex values as constants in the XGEMFAST.H
header file, though these are not official Atari declarations.

XMULTI
     The XMULTI structure for a faster evnt_multi call using function

     int evnx_multi(XMULTI *xm);

typedef struct xmulti {
    short   msgbuf[8];
    short   mflags,
            mbclicks,
            mbmask,
            mbstate,
            mm1flags;
    GRECT   mm1rect;
    short   mm2flags;
    GRECT   mm2rect;
    short   mtlocount,
            mthicount;
    short   mwhich,
            mmox,
            mmoy,
            mmobutton,
            mmokstate,
            mkreturn,
            mbreturn;
} XMULTI;

XMOUSE
typedef struct xmouse {
     short retval;
     short bclicks;
     short mask;
     short state;
     short status;
     short mousex;
     short mousey;
     short mouseb;
     short keystate;
} XMOUSE;

-eof
