NAMING CONVENTION:
------------------
All symbols defined start with either MX or mx.

Prefix determines the suggested access for the symbol:
MX_*    -> public type or macro
mx_     -> public function of macro wrapper for function
MX*     -> public macro for type conversion
mx__    -> private function
MX__	-> private macro

Struct elements beginning with an underscore should be considered private.

----------------------------------------------------------------------------
    DEGFX
----------------------------------------------------------------------------

Choosing a video driver
-----------------------
If you want to choose the default driver you can define MX_DRIVER_*.  If no
driver is chosen, of if the driver is not available on the compiling 
platform then another suitable driver will be chosen for you,  If you 
define MX_DRIVER_ALL then all drivers are available.

Possible drivers:
MX_DRIVER_FULLSCREEN -> mx_driver_fullscreen
MX_DRIVER_WINDOWED   -> mx_driver_windowed
MX_DRIVER_VGA        -> mx_driver_vga
MX_DRIVER_13H        -> mx_driver_13h

If you define any one of these, then only that driver will be included in 
the executable.  If you define none of these, a default driver will be used.


MX_FONT: A letter type
----------------------
If you are using font to draw text you need to define
MX_NEED_DEGFX_FONTDRAW.

Any font function called with 0 as the font will use the default font.

When setting a font to be the default font, using the mx_font_default 
function, the system takes over ownership of the font.  If its an allocated 
font loaded with mx_font_bitmap or mx_font_pcx then there is no need to 
delete the font later, the system will.

If you want to choose the default font at compile time you can define 
MX_FONT_*.  If no font has been chosen, one will be chosen for you.  If you 
define MX_FONT_ALL then all the fonts are available.

Possible compiled fonts:
MX_FONT_8X8      -> mx_font_8x8
MX_FONT_8X14     -> mx_font_8x14
MX_FONT_8X16     -> mx_font_8x16

If you define any one of these, then only the fonts defined will be included 
in the executable.


MX_GFX_ARGS: Setting the GFX mode and getting mode information
--------------------------------------------------------------
You set the graphics mode and get the mode information with the MX_GFX_ARGS
struct.  Its useful elements are:

typedef struct MX_GFX_ARGS {
    int w, h, c;               <-- Width, height and bpp of the mode.  If
                                   these are zero mx_gfx_start() will use a
                                   default value.
    
    const char *title;         <-- When mx_gfx_start() is called this
                                   contains the text you want to have at the
                                   top of the window for a windowed platform.
                                   
                                   When mx_gfx_info() is called this points
                                   to a string containing some information
                                   about the current platform driver.
                                   
    MX_REDRAW_FUNC redraw;     <-- This is a pointer to the drawing callback
                                   function.  The user fills this in for a
                                   call to mx_gfx_start().
    
    struct MX_BITMAP *buffer;  <-- This is the double buffer for screen
                                   drawing.  You can set it for a call to
                                   mx_gfx_start() or read information from
                                   the current buffer by calling
                                   mx_gfx_info().  If this is zero,
                                   mx_gfx_start() will make the buffer.
                                   
    struct MX_DRIVER *driver;  <-- This is a pointer to the current platform
                                   driver.  It depends on what drivers are
                                   available (See: Choosing a video driver).
                                   If this is zero, mx_gfx_start() will
                                   choose a driver for you.

    MX_RECT screen;            <-- This is filled in by mx_gfx_info() as a
                                   helper variable for the size fo the
                                   graphics screen.
                                   
    unsigned int session;      <-- This number is incremented every time
                                   mx_gfx_start() is called.  If you monitor
                                   this variable you can find out if some
                                   other portion of code has changed the
                                   video mode.
                                   
    unsigned pointer:1;        <-- This is filled in by mx_gfx_info() and
                                   tells whether the platform has its own
                                   mouse.  If not, the DEGFX draws the mouse.
} MX_GFX_ARGS;

To set the graphics mode you call mx_gfx_start() with a pointer to a
filled-in copy of the struct (or NULL).  If mx_gfx_start() returns zero the
struct contains information about the successfully set graphics mode.  You
might want to check to make sure you got the mode that you expected.  Some
platforms are very limited as to available graphics modes.  If mx_gfx_start()
returns non-zero then no graphics mode was available and you probably just
need to exit the program.

You can get information about the state of DEGFX by calling the mx_gfx_info()
function.  This returns a pointer to a MX_GFX_ARGS struct where the current
graphics system information can be read from. 


MX_BITMAP: A rectangular bitmap
-------------------------------
Bitmaps are created using the mx_bitmap function.  The pixel format is always
32 bit RGBA, actually in the form TRGB, where T is the pixel transparency.
The pixel type is MX_PIXEL which is really just a typedef for a 32 bit 
unsigned long.  Some macros for pixels are:
MXRGB()     <- Make a MX_PIXEL from red, green and blue components
MXRGBT()    <- Make a MX_PIXEL from red, green, blue and transparency 
MXR()       <- Get the red component (0-255)
MXG()       <- Get the green component (0-255)
MXB()       <- Get the blue component (0-255) 
MXT()       <- Get the transparency component (0-255)
MXTRANS()   <- Set the transparency of a pixel
MXBLEND()   <- Blend two pixels, the transparency of the first one is used
MXBLENDT()  <- Blend two pixels with a given transparency

Bitmaps can have a non-zero offset.  

The main bitmap functions have the form mx_bitmap_*(), for example 
mx_bitmap_blit().  When drawing to the screen there are some convenience 
macros in the similar form mx_*(), for example mx_blit().


DRAWING FUNCTION: How to draw on the screen
-------------------------------------------
DEGFX uses a drawing callback function for screen drawing.  All functions 
that draw onto the screen must ONLY be done in this function.  You can set 
it at the same time as the mode set in mx_gfx_start() function as the 
MX_GFX_ARGS struct element 'redraw'.  You can also use the mx_gfx_redraw() 
function to set the redraw callback.

You dont need to erase/draw the mouse when drawing on the screen, this is 
done automatically for you.  

If the platform draws its own mouse, for example by WIN32 GDI, then the user
has no control over how the mouse is displayed.  This can be found out by 
checking the MX_GFX_ARGS struct element 'pointer'.  If this is non-zero then 
the platform driver draws its own mouse and the DEGFX user has no control 
over the pointer.  

If the MX_GFX_ARGS struct element 'pointer' is false, then DEGFX draws the 
pointer on screen.  In this case the pointer can be hidden or drawn by 
calling mx_gfx_hidepointer().  This function just marks the pointer to be
drawn or not.  The actual pointer drawing occurs after the redraw callback 
function.


----------------------------------------------------------------------------
    DEPUI
----------------------------------------------------------------------------

Depending on what underlying platform you wish for DEPUI to use you can set
a define to make sure the right close is included in the executable.  If 
none of these symbols are defined then the DEGFX platform will be used.

Possible platforms:
MX_PLATFORM_ALLEGRO -> Use Allegro as underlying platform
MX_PLATFORM_DEGFX   -> Use DEGFX as underlying platform (default)

If you use MX_PLATFORM_ALLEGRO then the executable must be linked with the
Allegro library.  No external library is needed if DEGFX is the platform.


MX_THEME: A gui theme
---------------------
If you want to choose the default theme you can define MX_THEME_*.  If no
theme has chosen, then the default theme will be chosen for you,  If you 
define MX_THEME_ALL then all themes are available.

Possible themes:
MX_THEME_DEFAULT -> mx_theme_default
MX_THEME_WIN95   -> mx_theme_win95
MX_THEME_MONO    -> mx_theme_mono
MX_THEME_ROUNDED -> mx_theme_rounded

If you define any one of these, then only the themes defined will be 
included in the executable.  If you define none of these, then only the
mx_theme_default will be available.

You can change the theme at runtime by using the mx_theme function.


MX_OBJ: The base object
-----------------------
This is the base object.  All objects are derived from this one.

All objects are associated with a window.  If no window is given during 
object construction/creation (i.e. NULL), then they are associated with the 
root window.

All children of an object are destroyed BEFORE the object is destroyed.

All objects have a class which is a function that handles events.  It has 
the form void mx_*_class(void).  Within the class function the object can be
accessed as mx.obj, the event type as mx.event and any data attached to the 
event is at mx.data.  If an object wants to send an answer to the event then
they call mx_answer() with a void * for the data.  The last call to 
mx_answer() sets the response to the event.

You can't walk through all the children of an object.  There is no direct 
access to the root object.  This was intended for security reasons but 
actually forces applications to be written more clearly.

Some object positioning functions set the position relative to its parent.
mx_x
mx_y
mx_move

Some object positioning functions set the position relative to the screen.
mx_x1
mx_y1
mx_x2
mx_y2
mx_place

Some other object positioning functions:
mx_layout
mx_resize      -> Change the object size
mx_defaultrect -> Either let the object choose its own size or just return
                  the area that the object would prefer and dont change size.
mx_geometry    -> Sends a MX_GEOMETRY event which lets the object organise
                  itself for the current position and size.

On object creation you can set the objects id number which is just an integer
that lets you identify the object.  This is mostly useful in handlers where 
messages for many objects are handeled and you might need to identify a 
specific one.  You get a n object ID with the MXID() macro.  The default id is 
0 and id numbers higher than 0xf000 are reserved for internal use.  


MX_EVENT: The event type
------------------------
There are different kinds of events that can be sent to an objects class
handler function.

You can send events to an object with the mx_event() function.  You should only
send your own event types and not use any of the predefined types.  They are
for internal use only.

MX_DESTROY:
The objects class handler function is called with this event when the object 
should cleanup any resources it has.  It is always the last event sent to any
object.

MX_EXPOSE:
Expose events get sent direct to object class functions, bypassing window 
handlers.  This makes sure redrawing goes as fast as possible.  And it makes 
it a bit harder for application code to access platform dependent graphics
functions.  You can get the area being exposed using mx_expose_area().

The expose event assumes that the object is rectangular and opaque.  If the
object is transparent or not rectangular, the extra area must be drawn using
mx_expose_background().

The MX_EXPOSE event is also used internally to determine the area that an
object has on the screen.  In that case the clipping area is set to make sure
nothing will get drawn on screen, and the expose events are gathered to
determine the visible parts of the object on screen.  To make sure this
process goes as fast as possible, objects can call mx_exposing() while handling
and MX_EXPOSE event.  If mx_exposing() return true then the object can draw on 
the screen.  If it return false, then we are just figuring out the area of the
object on screen.  Then you only need to call whatever mx_expose_background()
the object needs (if any) and can skip any functions to draw on the screen,
since the clipping area will have been set to make sure nothing would have
been drawn anyway.

MX_DEFAULTRECT:
This event gets sent when mx_defaultrect gets called.  The object can then
indicate what size/position it would prefer to have.  It does this by
modifying the MX_RECT returned by mx_defaultrect_data().  The object should
not change its size/position during this event as it will be likely be set
either by the mx_defaultrect function of by the user soon after.

MX_GEOMETRY:
The event gets sent to an object when the mx_geometry function is called.  It
is intended to allow the object to set is internal positioning based on it
current state etc.  For example this messages is used by MX_SCROLL objects to
determine the necessary size of the scroll area and place its scrollbars (if
necessary) into the correct position.


MX_WIN: The window
------------------
Windows have objects as children.  The child objects are associated with the 
window.

The window handler acts like a class function but recieves messages for all
objects associated with the window.  This allows the window to intercept
messages to objects and perform actions.  A user handler can pass the event
along to the intended object by calling mx_win_handler().

A window can have 'child' windows which are just like normal windows except 
that they are guaranteed to get destroyed before the parent.  This is useful
for popup windows or toolbars.

MODAL WINDOWS:
When a modal window is open, all the objects of the target window are disabled 
and interactive events (mouse and keyboard) are blocked to the target window.
When the modal window is destroyed, then the target window objects are enabled
again.
