LibGAlloc External API Functions
================================

A few functions are missing here, namely `ggiGAReleaseVis`,
`ggiGATruncateList`, `ggiGAClearMotorProperties`,
`ggiGAClearCarbProperties`, `ggiGAClearTankProperties`,
`ggiGAMotorGetTank`, `ggiGATankGetCarb` and `ggiGATagOnto`.  Moreover,
ggiGAClearProperties seems to be removed.

Extension management
~~~~~~~~~~~~~~~~~~~~

.. manpage:: 3 ggiGAInit ggiGAExit ggiGAAttach ggiGADetach


Synopsis
--------

::

  #include <ggi/galloc.h>

  int ggiGAInit(void);

  int ggiGAExit(void);

  int ggiGAAttach(ggi_visual_t vis);

  int ggiGADetach(ggi_visual_t vis);


Description
-----------

These are the standard LibGGI extension management functions for the
LibGAlloc extension.  They allow initialization and deinitialization
of the extension as a whole and of individual visuals.

`ggiGAInit` will initialize an instance of the LibGAlloc extension and
prepare it to attach to visuals.

`ggiGAAttach`, if successful, will allow LibGAlloc functions to
operate on the named visual.

`ggiGADetach`, if successful, will clean up all resources involved in
providing the named visual with the LibGAlloc API.


`ggiGAExit` will free all resources associated with an instance of
LibGAlloc.


Return Value
------------

All four functions return zero for success, and an error code on
failure.


Examples
--------


ggiGAInit/ggiGAAttach/ggiGADetach/ggiGAExit Example::

        ggi_visual_t vis;
        ggiInit();
        ggiGAInit();
        vis = ggiOpen(NULL);
        ggiGAAttach(vis);

	/* ... */

	ggiGADetach(vis);
	ggiGAExit();
	ggiExit();




Add a resource given properties to a LibGAlloc request list
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


.. manpage:: 3 ggiGAAdd ggiGAAddMode


Synopsis
--------

::

  #include <ggi/galloc.h>

  int ggiGAAdd(ggiGA_resource_list *reqlist,
	       struct ggiGA_resource_props *props, 
	       enum ggiGA_resource_type t, ggiGA_resource_handle *handle);

  int ggiGAAddMode(ggi_visual_t vis, ggiGA_resource_list *reqlist, 
		   ggi_mode *mode, ggi_directbuffer *db,
		   ggiGA_resource_handle *handle);


Description
-----------


`ggiGAAdd` places a resource of type t with a copy of the properties
pointed to by :p:`props` at the end of a request list.  If not
``NULL``, the parameter :p:`res` contains a handle to the resource in
the request list, for use retreiving information from it later.


Usually instead of `ggiGAAdd`, extensions will provide their own
function to add a request for the type of objects that they manage.


`ggiGAAddMode` places a resource of type `GA_RT_FRAME` with a copy of
the ggi_mode pointed to by :p:`mode` at the end of a request list. If
not ``NULL``, the parameter :p:`res` is set to a handle to the
framebuffer resource in the request list, for use retreiving
information from it later.


An optional ggi_directbuffer may be supplied to `ggiAddMode` via the
pointer :p:`db`.  If :p:`db` is not ``NULL``, the contents of that
structure will also be copied into the resource.  Doing so constitutes
the initiation of advanced mode layout negotiation, so don't do that
unless you really want to negotiate mode layout. (Note: LibGAlloc
currently does not allow use of the GGI *extended* pixelformat, which
noone seems to be using anyway.)


Return value
------------

Returns `GALLOC_OK` (== `0`) on success, or an error code if the
addition fails or the supplied parameters are invalid.


Example
-------

ggiGAAdd/ggiGAAddMode Example::

        ggi_visual_t vis;
	ggiGA_resource_list request, result;
	ggiGA_ResourceProperties props;
	ggi_mode mode;
	ggiGA_resource_handle res;
        ggiInit();
        vis = ggiOpen(NULL);
        ggiGAAttach(vis);

	ggiCheckMode(vis, 640, 480, 640, 480, &mode);

	props.size.area.x     = 320;
	props.size.area.y     = 200;
	props.sub.tank.graphtype  = GT_AUTO;

	ggiGAAdd(&request, &props, GA_RT_SPRITE_SPRITE, &res);
	ggiGAAddMode(vis, &request, mode, NULL, NULL);

	if (ggiGACheck(vis, request, &result)) {
   	      print("Check failed\n");
	      autopsy(result);
	}
	else if (ggiGASet(vis, request, &result)) {
   	      print("Unexpected failure to Set\n");
	      autopsy(result);
        }
	ggiGADetach(vis);
	ggiGAExit();
	ggiExit();


Simplified forms of ggiGAAddMode
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. manpage:: 3 ggiGAAddSimpleMode ggiGAAddTextMode ggiGAAddGraphMode

Synopsis
--------

::

  #include <ggi/galloc.h>

  int ggiGAAddSimpleMode(ggi_visual_t vis, ggiGA_resource_list *reqlist,
                         int xsize, int ysize,
                         int frames,
                         ggi_graphtype type,
                         ggiGA_resource_handle *handle);

  int ggiGAAddTextMode(ggi_visual_t vis, ggiGA_resource_list *reqlist,
		       int cols, int rows,
		       int vcols, int vrows,
		       int fontsizex, int fontsizey,
		       ggi_graphtype type,
		       ggiGA_resource_handle *handle);

  int ggiGAAddGraphMode(ggi_visual_t vis, ggiGA_resource_list *reqlist,
                        int xsize, int ysize,
                        int xvirtual, int yvirtual, ggi_graphtype type,
                        ggiGA_resource_handle *handle);


Description
-----------

These functions are to `ggiGAAddMode` what 
`ggiSetTextMode`, `ggiSetGraphMode` and 
`ggiSetSimpleMode` are to `ggiSetMode`.
See the related manual pages.


See Also
--------

:man:`ggiGGAddMode(3)`, :man:`ggiGGAddMode(3)`


Send and retreive a LibGAlloc request list to/from a visual
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. manpage:: 3 ggiGAGet ggiGACheck ggiGASet ggiGAHandle

Synopsis
--------

::

  #include <ggi/galloc.h>

  int ggiGACheck(ggi_visual_t vis, ggiGA_resource_list request,
	         ggiGA_resource_list *result);

  int ggiGASet(ggi_visual_t vis, ggiGA_resource_list request,
	       ggiGA_resource_list *result);

  #define ggiGAGet(vis, result)	ggiGACheck(vis, NULL, result);

  ggiGA_resource_handle ggiGAHandle(ggiGA_resource_list reslist,
				    ggiGA_resource_list reqlist,
				    ggiGA_resource_handle reqhandle);


Description
-----------

These functions allow a LibGAlloc request list to be gotten, verified,
and actuated.  The first three functions take the visual being
manipulated as the first argument :p:`vis`.


`ggiGACheck` will ask the visual if it can support all the resources
listed in :p:`request`.  If not ``NULL``, :p:`result` will be pointed
to a new list filled with descriptions of the resources and whether
they can or cannot be allocated.  If :p:`result` was already pointing
at a list (make sure to initialize it!) that list will be gracefully
emptied.  As a special case, if :p:`result` points to :p:`request`,
the results will be placed into the given list without changing any
handle values in the list.


In `ggiGACheck`'s result list, properties of the resources may have
been adjusted according to LibGAlloc's rules for request list
processing and automatic sizing: in a successful resource, only
``GGI_AUTO``\ s and values in resources with caps will have been
adjusted.  In a failed resource, other values are adjusted.  However,
the properties of resources that have been flagged immutable will not
be altered.


In the event that the list contains a resource request which cannot be
honored, that resource is marked as a failure and any resources after
it (excepting their own cap, if they have one) may or may not have
been checked, and their properties are not altered.  However, you are
guaranteed even in the presence of a failure that a list consisting of
all the requests before the first failure in the list would succeed if
passed to `ggiGASet`.  (As long as there is at least one successful
``GA_RT_FRAME`` resource in the list, and provided nothing is done to
alter the visual in the meantime.)


`ggiGASet` will `ggiGACheck` a list, and, if there are no failures, it
will allocate resources for any requests in the list.  It will not
initialize any of these resources, except for those directly relevant
to the core LibGGI API (the main video mode and accelerator resources
for the basic set of LibGGI drawing operations).  Look to extensions
supporting the given resource type to provide initialization and
activation API functions for the given resource once it has been
allocated, LibGAlloc does not do that.


In the event of a failure when it calls `ggiGACheck`, the returned
results of `ggiGASet` differ subtly from those that would be returned
by calling `ggiGACheck` directly.  Mainly, `ggiGASet` does not honor
immutable resources, and the resulting resources will no longer be
marked as immutable and the properties therein may have been altered.


`ggiGAGet` will get a copy of the last request list successfully
set. The list passed back will be identical to the one which would
have been returned in the :p:`result` parameter from the last
successful call to `ggiGASet`.


As long as no modifications are made to either the request list or the
result after a call to `ggiGACheck` or `ggiGASet`, or between a call
to `ggiSetMode` and `ggiGAGet`, a handle to a resource in result
corresponding to a handle to the same resource in request may be
obtained from result list using `ggiGAHandle`.


Return value
------------


`ggiGACheck` returns `GALLOC_OK` (== `0`) for success.  `GGI_ENOMEM`
may be returned if the system is out of memory, the return value
`GALLOC_ESPECIFY` indicates that one of the requests failed due to
incomplete information or there was no `GA_RT_FRAME` request in the
list.

`ggiGASet` returns `GALLOC_OK` (== `0`) for success.  It should never
fail except for running out of memory, in which case it returns
`GGI_ENOMEM`.  If it is passed a list that would not successfully
verify with `ggiGACheck`, `ggiGASet` behaves exactly like `ggiGACheck`
would with the exception of the handling of immutable resources.


`ggiGAGet` returns `GALLOC_OK` (== `0`) for success or an error code
on failure.


`ggiGAHandle` returns `NULL` if it could not find handle in
:p:`reqlist` matching handle, or if it could not find a resource
corresponding to handle in :p:`reslist`, or if fed any invalid
parameters.


Examples
--------

ggiGAGet/ggiGACheck/ggiGASet Example::

        ggi_visual_t vis;
	ggiGA_resource_list request, result;
	ggiGA_resource_handle reqmode, resmode;
        ggiInit();
        vis = ggiOpen(NULL);
        ggiGAAttach(vis);
	ggiSetSimpleMode(vis, 640, 480, 640, 480, NULL);

	/* Other features may be allocated */

	ggiGAGet(vis, &request);
	ggiGAAddSimpleMode(vis, &request, 640, 480, 
	                   GGI_AUTO, GGI_AUTO, &reqmode);
	if (ggiGACheck(vis, request, &result)) {
   	      print("Unknown error in check for more virt\n");
	      autopsy(result);
	}
	else if (ggiGASet(vis, request, &result)) {
   	      print("Unexpected failure to allocate more virt\n");
	      autopsy(result);
        }
	resmode = ggiGAHandle(reslist, reqlist, reqmode);
	fprintf(stderr, "Requested mode was:");
	ggiFPrintMode(stderr, ggiGAGetggiMode(reqmode));
	fprintf(stderr, "Resulting mode was:");
	ggiFPrintMode(stderr, ggiGAGetggiMode(resmode));
	ggiGADetach(vis);
	ggiGAExit();
	ggiExit();




Get a human readable string from a LibGAlloc resource list
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. manpage:: 3 ggiGAanprintf

Synopsis
--------

::

  #include <ggi/galloc.h>

  int ggiGAanprintf(ggi_visual_t vis, ggiGA_resource_list list, 
		    size_t size, char *format, char **out);

Description
-----------

Allocates a string of maximum length :p:`size` + 1, and puts in it
zero terminated string with a textual representation of the resource
:p:`list` pointed to by request.  The format argument is for future
expansion.  :p:`out` is pointed to the newly allocated string.


Return value
------------

The length of the generated string is returned, less the terminating
``\0``.


Example
-------

::

  ggi_visual_t vis;

  void sub autopsy(ggiGA_resquest_list req) {
       char *str;
       ggiGAanprintf(vis, req, 1024, NULL, &str);
       fprintf(stderr, "Resource list contained:\n%s\n", str);
       free(str);
       exit(-1);
  }


Free LibGAlloc resource list structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. manpage:: 3 ggiGAEmptyList ggiGAEmptyFailures

Synopsis
--------

::

  #include <ggi/galloc.h>

  int ggiGAEmptyList(ggiGA_resource_list *list);

  int ggiGAEmptyFailures(ggiGA_resource_list *list);

Description
-----------


`ggiGAEmptyList` frees the request list linked list structures and all
attached properties, modes, and private structure members.
`ggiGAEmptyFailures` empties the rest of the list starting at the
first failed resource.

Do not worry: if you have used `ggiGASet` successfully on the list,
then GAlloc is keeping an internal copy which you can get back with
`ggiGAGet`.


Do worry: If you have gotten any handles, properties, modes,
directbuffer structures, or private data structures from the destroyed
resources, then they are now pointing at invalid memory addresses.  If
you want to keep them, you must copy them before calling
`ggiGAEmptyList`.


Return value
------------

Returns `GALLOC_OK` (== `0`) on success, or a non-zero error if passed
an invalid list.


Example
-------

::

        ggi_visual_t vis;
	ggiGA_resource_list list;
	ggiGA_resource_handle handle;
	struct ggiGA_ResourceProperties *props, copy;

	ggiGAGet(vis, &list);
	handle = ggiGetHandle(list, oldrequesthandle);
	props = ggiGetProperties(handle);
	if (handle != NULL)
  	   memcpy(&copy, props, sizeof(struct ggiGA_ResourceProperties));
	ggiEmptyList(list);
	list == NULL;


Release resources allocated by LibGAlloc
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. manpage:: 3 ggiGARelease ggiGAReleaseList

Synopsis
--------

::

  #include <ggi/galloc.h>

  int ggiGARelease(ggi_visual_t vis, ggiGA_resource_list *list,
		   ggiGA_resource_handle *handle);

  int ggiGAReleaseList(ggi_visual_t vis, ggiGA_resource_list *list,
		       ggiGA_resource_handle *handle);

Description
-----------


`ggiGARelease` finds the internal resource corresponding to the
resource in reqlist referenced by handle, deallocates it, and then
removes the resource from reqlist.  Resources of type ``GA_RT_FRAME``
are simply removed, unless they are the last such in the list, in
which case they represent the active video mode and cannot be removed
(requests to do this are ignored.)


`ggiGAReleaseList` does the same for all the resources in reqlist.


Care must be taken that the reqlist used has not been altered with any
`Add` functions since it was used to set the mode, or that it is a
result list that was gotten during or since the last call to
`ggiGASet` or `ggiGARelease`, in which case the handle must belong to
said result list.


Return value
------------

Returns `0` on success, or an error code if the removal fails or the
supplied parameters are invalid.


Example
-------

::

        ggi_visual_t vis;
	ggiGA_resource_list request, result;
	ggiGA_ResourceProperties props;
	ggi_mode mode;
	ggiGA_resource_handle req, res;
        ggiInit();
        vis = ggiOpen(NULL);
        ggiGAAttach(vis);

	ggiCheckMode(vis, 640, 480, 640, 480, &mode);

	props.size.x     = 320;
	props.size.y     = 200;
	props.graphtype  = GT_AUTO;

	ggiGAAdd(&request, &props, GA_RT_VIDEO_MOTION, &req);
	ggiGAAddMode(vis, &request, mode, NULL, NULL);

	if (ggiGACheck(vis, request, &result)) {
   	      print("Check failed\n");
	      autopsy(result);
	}
	else if (ggiGASet(vis, request, &result)) {
   	      print("Unexpected failure to Set\n");
	      autopsy(result);
        }

        ggiGARelease(vis, request, req);
	/* Or:

	   res = ggiGAHandle(result, request, req);
           ggiGARelease(vis, result, res);

	*/

	ggiGADetach(vis);
	ggiGAExit();
	ggiExit();




Get a pointer to properties in a LibGAlloc request list
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


.. manpage:: 3 ggiGAGetProperties ggiGAGetGGIMode ggiGAGetGGIDB


Synopsis
--------

::

  #include <ggi/galloc.h>

  struct ggiGA_resource_props *ggiGAGetProperties(ggiGA_resource_handle handle);
  ggi_mode *ggiGAGetGGIMode(ggiGA_resource_handle handle);

  ggi_directbuffer *ggiGAGetGGIDB(ggiGA_resource_handle handle);


Description
-----------

These functions allow data contained in the resource with handle res
to be accessed.  What is given back is a pointer to a structure inside
the resource, so modifying the contents will modify the
resource/resource list, but care must be taken not to try to
dereference this pointer after the list has been emptied.


`ggiGAGetProperties` gives back the current properties of the resource with
the given handle.

`ggiGAGetGGIMode` gives back the current mode of the resource of type
``GA_RT_FRAME`` with the given handle.


`ggiGAGetGGIDB` gives back the current directbuffer structure of the
resource of type ``GA_RT_FRAME`` with the given handle.


Return value
------------

All three functions return a pointer to the requested data, or
``NULL`` if there is no such data with that handle.


Example
-------

::

        ggi_visual_t vis;
	ggiGA_resource_list request, result;
	ggiGA_ResourceProperties props, *propsp;
	ggi_mode mode, *modep;
	ggi_directbuffer db, *dbp;
	ggiGA_resource_handle hnd, modehnd;

        ggiInit();
        vis = ggiOpen(NULL);
        ggiGAAttach(vis);

	ggiCheckMode(vis, 640, 480, 640, 480, &mode);

	props.size.area.x     = 300;
	props.size.area.y     = 200;
	props.sub.tank.graphtype  = GT_8BIT;

	db.type = GGI_DB_NORMAL;

	ggiGAAdd(&request, &props, GA_RT_SPRITE_SPRITE, &hnd);
	ggiGAAddMode(vis, &request, &mode, &db, &modehnd);

	propsp = ggiGetProperties(hnd);
	modep = ggiGAGetGGIMode(request, modehnd);
	dbp = ggiGAGetGGIDB(modehnd);
	if (!ggiGACheck(vis, request, NULL)) goto done;
	propsp->graphtype = GT_AUTO;
	if (!ggiGACheck(vis, request, NULL)) goto done;
	if (dbp->type != GGI_DB_NORMAL) goto fail;
	modep->visible.x = GGI_AUTO;
	modep->visible.y = GGI_AUTO;
	if (!ggiGACheck(vis, request, &request)) goto done;
        print("Check failed\n");
	autopsy(request);
	goto fail;

  done:
	if (ggiGASet(vis, request, &result)) {
   	      print("Unexpected failure to Set\n");
	      autopsy(result);
        }
	/* [...] */
  fail:
        ggiEmptyList(reqlist);
	ggiGADetach(vis);
	ggiGAExit();
	ggiExit();




Get pieces of information from a LibGAlloc resource handle
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. manpage:: 3 ggiGAIsFailed ggiGAIsModified ggiGAIsMotor ggiGAIsTank ggiGAIsCarb ggiGAGetVisual

Synopsis
--------

::

  #include <ggi/galloc.h>

  int ggiGAIsFailed(ggiGA_resource_handle handle);

  int ggiGAIsModified(ggiGA_resource_handle handle);

  int ggiGAIsMotor(ggiGA_resource_handle handle);

  int ggiGAIsTank(ggiGA_resource_handle handle);

  int ggiGAIsCarb(ggiGA_resource_handle handle);

  ggi_visual_t ggiGAGetVisual(ggiGA_resource_handle handle);



Description
-----------

These functions allow data contained in the resource with handle
:p:`handle` to be accessed.


`ggiGAIsFailed` tells you whether the given resource was the reason
why a `ggiGACheck` call failed.  The first resource for which this
returns true is the one that caused the failure.


`ggiGAIsModified` tells you whether the properties of the given
resource were modified during the last call to `ggiGACheck` or
`ggiGASet`.  This could have happenned because the resource failed, or
it could just have been that the resource held fields with default
values like ``GGI_AUTO``, which were filled by a suggestion.


`ggiGAIsMotor` tells you whether the given resource is a motor
resource or not.  `ggiGAIsCarb` tells you whether the given resource
is a carb resource or not.  `ggiGAIsTank` tells you whether the given
resource is a tank resource or not.


`ggiGAGetVisual` returns a handle to the visual that the resource belongs
to, and can only be determined for result handles returned by `ggiGAGet`,
`ggiGACheck`, or `ggiGASet`.


Return value
------------

`ggiGAIsFailed` returns `1` if the resource failed, a negative value if
there was an error, or `0` if the resource was successful.


`ggiGAIsModified` returns `1` if the resource has been modified, a
negative value if there was an error, or `0` if there were no
suggestions made for this resource.


`ggiGAIsMotor` returns `1` if the resource is a motor resource, or `0`
if the resource is a tank or carb.  `ggiGAIsCarb` returns `1` if the
resource is a carb resource, or `0` if the resource is a tank or
motor.  `ggiGAIsTank` returns 1 if the resource is a tank resource, or
`0` if the resource is a motor or tank.

`ggiGAGetVisual` returns `NULL` if there is any error, otherwise it
returns a visual as noted above.
