\input texinfo
@titlepage
@title LibGGI API Manual
@subtitle For libggi 2.0, imminent release
@author Steve Cheng
@author Hartmut Niemann
@page
@vskip 0pt plus 1fill
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@end titlepage
@node top
@top LibGGI API Manual
This document describes the application programming interface for LibGGI,
an extremely flexible and extensible, dynamic drawing library developed
by the GGI project.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@node Preface
@chapter Preface
There should not be any more changes to the LibGGI API until the next
major version. Unfortunately, implementation and documentation do not
always match; if you encounter any such differences
or have any other questions or comments on this documentation, please mail us
at @email{steve@@ggi-project.org}, or the GGI mailing list. Thank you.
For other developers: if you want to change this manual and do not know
DocBook/SGML, just mail me the ASCII version and I will gladly format
and include it for you.
This manual is primarily written as a reference to the user-visible API
of LibGGI. However, it is being
expanded to cover basic graphics concepts as well. It will not be a
full tutorial, as actual working code (as found in the
@file{demos/} directory of the LibGGI distribution) serves
that function better. This manual is also not intended to be an LibGGI
internals guide, although implementation hints are dropped throughout
the manual :)
This documentation is written in DocBook. The SGML source
can be used to generate Unix manpages, HTML and text formats automatically.
@node Introduction
@chapter Introduction
LibGGI, the dynamic GGI (General Graphics Interface) library
is a flexible drawing library.
It provides an opaque interface to the display's acceleration functions. It
was originally intended to allow user programs to interface with KGI, the
GGI Kernel Graphics Interface, but other display types can be easily used by
loading the appropriate "display target" (e.g. X, memory).
LibGGI consists of a main library (@file{libggi.so}) and a multitude of
dynamic drivers. The library then loads the necessary "drivers" for the
requested mode, taking hints from the graphics device if necessary.
LibGGI can also load extension libraries, e.g. to provide enhanced 2D and 3D
functions.
It has been designed after having a look at several existing libraries,
and so far we have found porting to be quite simple from and to most of
them.
@node General
@chapter General
To use LibGGI, #include @file{ggi/ggi.h} in a C program.
LibGGI functions are prefixed with @samp{ggi}, and other #defines are
prefixed with @samp{GGI_}.
Most LibGGI functions return @code{0} to indicate success, and
a negative error code to indicate errors. @code{Return codes greater than
0} are usually additional hints or other non-negative integer data.
A list of error codes and descriptions can be found in the
@file{ggi/errors.h} file, which is part of the
LibGGI/LibGG package.
@node Library control
@chapter Library control
@menu
* ggiInit::
* ggiPanic::
@end menu
@node ggiInit
@section ggiInit
@menu
@end menu
@subheading Name
ggiInit, ggiExit --- Initialize and uninitialize LibGGI
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiInit(void);
int ggiExit(void);
@end example
@subheading Description
@code{ggiInit} initalizes the library. This function must be called
before using other LibGGI functions; otherwise the results will be undefined.
@code{ggiExit} uninitializes the library (after being initalized by
@code{ggiInit}) and automatically cleanup if necessary. This should be
called after an application is finished with the library. If any GGI
functions are called after the library has been uninitialized, the results
will be undefined.
@code{ggiInit} allows multiple invocations. A reference count is
maintained, and to completely uninitialize the library, @code{ggiExit}
must be called as many times as @code{ggiInit} has been called
beforehand.
@subheading Return value
@code{ggiInit} returns @code{0} for OK, otherwise an error code.
@code{ggiExit} returns:
@table @asis
@item @code{0}
after successfully cleaning up,
@item @code{> 0}
the number of 'open' @code{ggiInit} calls,
if there has been more than one call to @code{ggiInit}.
As @code{ggiInit} and @code{ggiExit} must be used in
properly nested pairs, e.g. the first @code{ggiExit}
after two @code{ggiInit}s will return 1.
@item @code{< 0}
error, especially if more @code{ggiExit} calls have
been done than @code{ggiInit} calls.
@end table
@subheading Examples
Initialize and uninitialize LibGGI
@sp 1
@example
if (!ggiInit())
@{
exit(1); /* can't start! */
@}
@var{/* Do some LibGGI stuff */}
ggiExit();
@end example
@node ggiPanic
@section ggiPanic
@menu
@end menu
@subheading Name
ggiPanic --- Exit LibGGI programs for fatal errors
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiPanic(const char *format, ...);
@end example
@subheading Description
@code{ggiPanic} does a graceful shutdown, with
@code{printf}(3)
-style
reporting, taking a format string and any additional variables. It will shut
down the graphics modes active, close all visuals, print the given error message
to stderr, and then exit the application.
@code{ggiPanic} should only be used by usermode programs when something
is really screwed, and they do not know what to do. The same applies for
libraries, but might be used in rare situations such as corruption of
critical data structures.
@subheading Return value
Never returns.
@subheading Examples
An unrecoverable error
@sp 1
@example
if (my_important_struct->magic != MAGIC) @{
ggiPanic("Fatal error: magic corrupted\n");
@}
@end example
@node Visual management
@chapter Visual management
A visual is simply a thing you can draw on. For example, a Virtual Console in
fullscreen-mode, an X window, an invisible memory area, or a printer. It is
identified by its handle of type @code{ggi_visual_t}, which is given to all
drawing functions to indicate which visual to operate on.
Note:
@sp 1
Some functions involving drawing, color, palette and frames
do not work until you have set a mode on a visual.
Each visual is completely independent of other visuals. You can use these
visuals to display on multiple monitors and/or in multiple windows or to
work on "virtual" graphics devices like in-memory pixmaps or even PPM files
on disk.
Most LibGGI functions are passed a visual returned by @code{ggiOpen} to know
where they should operate on.
@code{ggi_visual_t} is opaque to the user. Do not try to access any part of
the structure directly. It may change without notice.
@menu
* ggiOpen::
@end menu
@node ggiOpen
@section ggiOpen
@menu
@end menu
@subheading Name
ggiOpen, ggiClose --- Open and close a visual
@subheading Synopsis
@example
#include <ggi/ggi.h>
ggi_visual_t ggiOpen(const char *display, ...);
int ggiClose(ggi_visual_t vis);
@end example
@subheading Description
@code{ggiOpen} opens a visual (along with associated inputs).
The visual is specified as a display string, followed by @code{NULL}.
If only @code{NULL} is specified, the default display target is
opened. (This may be specified by the user.)
The other arguments are for internal purposes only, such as
@code{argptr}, used to pass driver-specific, non-textual information to
the driver.
@code{ggiClose} releases and destroys an open visual and its associated
internal control structures. This will close X windows, return consoles to
text-mode, etc.
@subheading Return value
@code{ggiOpen} returns the opened visual (@code{ggi_visual_t}), or
@code{NULL} for error.
@code{ggiClose} returns @code{0} for OK, otherwise an error
code.
@subheading Examples
Open default visual
@sp 1
@example
ggi_visual_t vis = ggiOpen(NULL);
if(vis==NULL)
@{
ggiPanic("Couldn't open default visual!\n");
@}
@end example
Open a memory visual
@sp 1
@example
ggi_visual_t memvis = ggiOpen("display-memory", NULL);
if(memvis==NULL) @{
return -1;
@}
@end example
Closing visuals
@sp 1
@example
ggiClose(memvis);
ggiClose(vis);
@end example
@subheading See Also
@ref{ggiInit}, libggi(7)
@node Mode management
@chapter Mode management
After opening the visual, you must set a mode (specifying e.g. the dimensions, how many
colors, etc.) before you can do anything useful with it, such as drawing.
@menu
* The @code{ggi_mode} struct: The ggi_mode struct.
* @code{ggi_graphtype}: ggi_graphtype.
* @code{GGI_AUTO}: GGI_AUTO.
* Mode negotiation::
* Functions::
@end menu
@node The ggi_mode struct
@section The @code{ggi_mode} struct
This structure defines a visual's (graphics) mode.
typedef struct /* requested by user and changed by driver */
@{
uint32 frames; /* frames needed */
ggi_coord visible; /* vis. pixels, may change slightly */
ggi_coord virt; /* virtual pixels, may change */
ggi_coord size; /* size of visible in mm */
ggi_graphtype graphtype; /* which mode ? */
ggi_coord dpp; /* dots per pixel */
@} ggi_mode;
@end example
You usually don't need to care about the definition, if you want to set a
mode, but it is necessary if you want to find out the mode actually
being set.
@table @asis
@item @code{ggi_coord}
@code{ggi_coord} represents any (x,y) coordinate.
@item @code{frames}
Use of multiple buffering is specified in the @code{frames} member of
the @code{ggi_mode} struct, as the number of screen buffers needed.
Tip:
@sp 1
Multiple buffering is the allocation of multiple framebuffers and
drawing on/reading/displaying them independently. Applications use
double-buffering to prepare a picture offline and switching display to it.
@item @code{visible}
@code{visible} area represents the area of the visual that is visible
to the user at any time.
@item @code{virtual}
@code{virtual} area represents all the available area for drawing
operations.
@item @code{dpp}
@code{dpp} specifies the number of dots per pixel. For graphic
modes, it is 1 (@code{x} and @code{y}) by definition. In text
modes, it is the font size (each character in text modes is a pixel).
Both the visible and virtual size are given in
@emph{pixels}, not dots. This makes a difference for text
modes, because a character is treated as one pixel, but consists of a
dpp.x * dpp.y sized matrix of dots.
@end table
@node ggi_graphtype
@section @code{ggi_graphtype}
@code{ggi_graphtype} specifies the graphic type:
@table @asis
@item depth
Number of significant bits
(e.g. bits representing the actual color or some
other property of the pixel)
@item (access) size
Number of physical bits per pixel.
Only the depth number of bits is significant; other bits are
padding.
@item scheme
Mode 'category':
@table @asis
@item @code{GT_TEXT}
(text modes),
@item @code{GT_TRUECOLOR}
(pixel is a direct RGB value),
@item @code{GT_GREYSCALE}
(grayscale :-),
@item @code{GT_PALETTE}
(each pixel is an index to a colormap)
@end table
@item subscheme
Miscellaneous info. Indicates whether the pixel values are
in reverse byte or bit order, etc.
@end table
Applications can use @code{GT_AUTO} in any of these fields to get a
'recommended' setting.
The four aspects of a graphic type above are packed into a
@code{ggi_graphtype}. See @file{ggi/types.h} for details
about the possible schemes and subschemes.
There are also macros which represent some common @code{ggi_graphtype}s,
mainly for compatibility:
@table @asis
@item @code{GT_AUTO}
equivalent to the GGI_AUTO (see next section) for graphic types.
It indincates that any default value may be taken. Where
possible this is currently a graphics mode, often the
highest.
@item @code{GT_TEXT16}
@itemx @code{GT_TEXT32}
text modes with word- and longword-aligned characters and attributes.
@item @code{GT_1BIT}
@itemx @code{GT_4BIT}
@itemx @code{GT_8BIT}
(these modes use a palette.)
@item @code{GT_15BIT}
@itemx @code{GT_16BIT}
@itemx @code{GT_24BIT}
@itemx @code{GT_32BIT}
graphics modes with the respective bits per pixel. Note that
for 32-bit modes, only the size (bits per pixel) is 32-bits, the depth
(significant bits) is 24-bit.
@end table
@node GGI_AUTO
@section @code{GGI_AUTO}
If a given @code{ggi_mode} is set or checked, any size parameter
may be @code{GGI_AUTO} (defined in @file{ggi/types.h}).
It is a placeholder.
When @code{GGI_AUTO} is encountered in a parameter, it is replaced
with corresponding values specified by @code{GGI_DEFMODE} variable.
If the corresponding value is not found in @code{GGI_DEFMODE}
or that value is also @code{GGI_AUTO}, then the driver should select a
reasonable value satisfying as many of the given constraints as
possible. The following are some recommendations:
@itemize @bullet
@item
If a visible size is given but no virtual, the lowest reasonable
(taking alignment and accelleration constraints into account)
should be used.
@item
If either visible x or y is given, the other one should give
a x/y ratio close to that of the screen size, so normally about
4/3.
@item
If a virtual size is given but no visible, the highest possible
visible size is selected.
@item
If no size is given, the driver uses some builtin default.
@item
If the graphtype is unspecified, the highest possible graphtype
that meets the geometry constraints is set/suggested.
@item
@code{dpp.x} and @code{dpp.y} will be 1 for
graphics. For text modes the largest possible
@code{dpp.x} and @code{dpp.y} (the most
fine-grained font) should be used.
@item
@code{frames} will be 1 if not specified.
@end itemize
Note:
@sp 1
The rules above are only @emph{recommendations} (which are hoped to
best capture user expectations) to the driver implementer and in no way
guaranteed.
@node Mode negotiation
@section Mode negotiation
There are three types of mode calls:
@itemize @bullet
@item
The @code{ggiCheck*Mode} functions test whether a given
mode is acceptable or suggest a better one,
@item
The @code{ggiSet*Mode} functions try to set the
specified mode and fail if that is impossible. @code{ggiSetMode}
then returns a better suggestion, as ggiCheck*Mode do.
(The suggested mode is not silently set.)
@item
@code{ggiGetMode} returns the mode that is currently set.
@end itemize
If a given mode can not be set, the structure passed
is changed to the suggested mode as follows:
@itemize @bullet
@item
Resolutions are always adjusted @emph{up}. If you want the
next lower, start out at 1,1 (or somewhere else reasonable) and jump up the
ladder.
Only if the maximum resolution would be exceeded, resolutions are
adjusted @emph{down} to the maximum.
The above applies to visible and virtual size. If there is interference
between them, the visible size is satified first if possible, then the
virtual size.
@item
Note that the adjustment of one value do not normally affect other
values. For example, if (visible) 320x100 (virtual 320x200) is
requested, the visible size may be adjusted to 320x200, but virtual size
will be left alone. Of course, if the virtual size becomes less than
visible size, then it will be adjusted as well. A good rule of thumb is
that anything returned by @code{ggiCheckMode} is minimally valid.
@item
Font sizes (i.e. the size of the pixel in textmodes) are handled the
other way round: they are adjusted @emph{down} except when there is nothing
below.
@item
Graphtype: Modes are normally card-dependant and not too
dependant on size (except for maximum size limits etc.)
The basic rationale is to change graphtype only, if the card does not
support it @emph{at all}. If the maximum resolution is exceeded, then
that is adjusted down and not the graphtype. This assumes, that if you
request true-color, you really want that and not so badly the resolution you
requested. If this is not the case, you can still retry with another
graphtype or @code{GT_AUTO}.
If it is necessary to change to change the graphtype, the order
should be ascending (if possible), i.e. 1->4->8->15->16->24/32 bit. So you
always get a mode which can do more than you requested. Only when no better
modes are available, the type is adjusted down.
@item
It is possible to pass @code{GGI_AUTO} as any of the parameters.
@code{GGI_AUTO} is a placeholder (e.g. the program does not care about a
specific parameter). The display target will reset @code{GGI_AUTO}
parameter to a default, such as the maximum, preferred, or
@code{GGI_DEFMODE} resolution, while being compatible with the other
settings. The presence of @code{GGI_AUTO} is @emph{not}
flagged as an error.
If @code{ggiSet@{Graph,Text@}Mode} is given
@code{GGI_AUTO} as one or more of its arguments, it will silently set a
mode. To get back this mode, you must use @code{ggiGetMode}.
@end itemize
Note:
@sp 1
The resulting mode is guaranteed to be valid; if not, the application
can assume that it cannot set any mode on the given visual and give up.
@node ggiSetMode
@subsection ggiSetMode
@menu
@end menu
@subsubheading Name
ggiSetMode, ggiCheckMode, ggiGetMode --- Set, check or get a mode on a visual
@subsubheading Synopsis
@example
#include <ggi/ggi.h>
int ggiSetMode(ggi_visual_t vis, ggi_mode *tm);
int ggiCheckMode(ggi_visual_t vis, ggi_mode *tm);
int ggiGetMode(ggi_visual_t vis, ggi_mode *tm);
@end example
@subsubheading Description
@code{ggiSetMode} sets any mode (text or graphics).
@code{ggiCheckMode} checks whether or not the given mode (text or
graphics) will work on the visual.
For both @code{ggiSetMode} and @code{ggiCheckMode}, normal mode
negotiation is performed, and if the given mode is not possible,
modifications will be made to the passed structure to make it work.
If @code{GGI_AUTO} (or @code{GT_AUTO} for the graphtype) is specified
for any of the members of @code{*tm}, these are filled in with the
recommended parameters.
For @code{ggiSetMode}, if the mode cannot be set, a mode is
suggested in @code{*tm}, but it will not be silently set.
However, you'll probably want to use the convenience functions
@code{ggiSetTextMode} and @code{ggiSetGraphMode} instead of
@code{ggiSetMode}.
@code{ggiGetMode} gets the current mode set on the visual.
@subsubheading Return value
@code{ggiSetMode} returns @code{0} if the mode is set
successfully, otherwise an error code.
For @code{ggiCheckMode}, a return of @code{0} means that a
@code{ggiSetMode} call for the given mode mode would succeed. Otherwise,
the mode given cannot be set. (But the modified mode passed back to the
application @emph{should} work.)
For both functions, if the only modifications made to the
structure is filling @code{GGI_AUTO} parameters, it is still
considered as success.
@code{ggiGetMode} gets the current mode. @code{tm} will be filled with
the current mode on return.
@subsubheading See Also
@ref{ggiOpen}, @ref{ggiSetGraphMode}
@node ggiSetGraphMode
@subsection ggiSetGraphMode
@menu
@end menu
@subsubheading Name
ggiSetTextMode, ggiCheckTextMode, ggiSetGraphMode, ggiCheckGraphMode, ggiSetSimpleMode, ggiCheckSimpleMode --- Set and check a text/graphics mode on a visual
@subsubheading Synopsis
@example
#include <ggi/ggi.h>
int ggiSetTextMode(ggi_visual_t visual,
int cols, int rows,
int vcols, int vrows,
int fontx, int fonty);
int ggiCheckTextMode(ggi_visual_t visual,
int cols, int rows,
int vcols, int vrows,
int fontx, int fonty,
ggi_mode *suggested_mode, ...);
int ggiSetGraphMode(ggi_visual_t visual,
int x, int y,
int xv, int yv,
ggi_graphtype type);
int ggiCheckGraphMode(ggi_visual_t visual,
int x, int y,
int xv, int yv,
ggi_graphtype type,
ggi_mode *suggested_mode, ...);
int ggiSetSimpleMode(ggi_visual_t visual,
int x, int y,
int frames,
ggi_graphtype type);
int ggiCheckSimpleMode(ggi_visual_t visual,
int x, int y,
int frames,
ggi_graphtype type,
ggi_mode *suggested_mode);
@end example
@subsubheading Description
The @code{ggiCheck@{Text,Graph,Simple@}Mode} and
@code{ggiSet@{Text,Graph,Simple@}Mode} are convenient versions of
@code{ggiSetMode}. They accept the mode parameters as integer arguments
rather than as a @code{ggi_mode} struct that the application has to
fill out. Otherwise, they are functionally equivalent to the 'master'
@code{ggiCheckMode} and @code{ggiSetMode} functions, and the same
mode-setting semantics apply.
@code{ggiSetTextMode} sets a textmode with given columns and rows,
virtual columns and rows and a font of the given size.
@code{ggiCheckTextMode} checks a textmode with given columns and rows,
virtual columns and rows and a font of the given size.
@code{ggiSetGraphMode} sets a graphics mode with a visible area of size
@code{x},@code{y} and a virtual area of size @code{xv}@code{yv}
and the specified graphics type. (You can pan around the virtual area using
@code{ggiSetOrigin}.)
@code{ggiCheckGraphMode} checks a graphics mode with the specified mode
features.
@code{ggiSetSimpleMode} sets a graphics mode with a visible area of size
@code{x}@code{y} and @code{frames} number of frames and the specified
graphics type.
@code{ggiCheckSimpleMode} checks a graphics mode with the specified
mode features.
If @code{suggested_mode} is not @code{NULL}, then it will be filled
with the suggested mode, as documented under @code{ggiCheckMode}.
In text modes, the font size is the size of the pixel
(@code{ggi_mode.dpp}).
@subsubheading Return value
For @code{ggiCheckTextMode} and @code{ggiCheckGraphMode}, a return
of @code{0} means that a @code{ggiSet*Mode} call for this mode
would succeed. Otherwise, the mode given cannot be set. In this case,
@code{suggested_mode} is changed to the suggested mode.
For @code{ggiSetTextMode} and @code{ggiSetGraphMode}, a return of
@code{0} indicates success, while any other value indicates an error.
@subsubheading Examples
Try a 320x200x8 mode
@sp 1
@example
err = ggiCheckGraphMode(vis, 320, 200, GGI_AUTO, GGI_AUTO, GT_8BIT,
&sug_mode, NULL);
if(err) @{
@var{/* Check if returned mode is ok... /*}
@}
else @{
ggiSetMode(&sug_mode);
@}
@end example
@subsubheading See Also
@ref{ggiOpen}, @ref{ggiSetMode}
@node ggiParseMode
@subsection ggiParseMode
@menu
@end menu
@subsubheading Name
ggiParseMode, ggiPrintMode, ggiSPrintMode, ggiFPrintMode --- Operate on formatted strings specifying LibGGI modes
@subsubheading Synopsis
@example
#include <ggi/ggi.h>
int ggiParseMode( const char *s, ggi_mode *m);
int ggiPrintMode(ggi_mode *m);
int ggiSPrintMode(char *s, ggi_mode *m);
int ggiFPrintMode(FILE *s, ggi_mode *m);
@end example
@subsubheading Description
@code{ggiParseMode} parses a string into a @code{ggi_mode}.
The @code{ggi*PrintMode} functions print all the members of @code{ggi_mode} in a
human-readable form. @code{ggiSPrintMode} outputs to a preallocated
string buffer, @code{ggiFPrintMode} outputs to a stdio @code{FILE}, and
@code{ggiPrintMode} outputs to standard output. These functions
correspond to
@code{sprintf}(3),
@code{fprintf}(3),
@code{printf}(3),
respectively.
The format of the string used by these functions is exactly the same as the one used in
libggi(7)
environment variables.
@subsubheading Return value
@code{ggiParseMode} returns:
@table @asis
@item @code{0}
on success, i.e. the string was correct.
However, errors involving @code{GT_*}, position
information, or mismatched brackets do not make it fail;
these errors are simply ignored.
@item @code{<0}
if there is text that can not be parsed.
This text is printed to stderr.
All parameters parsed so far are written into @code{m}.
@end table
So @code{m} contains all parameters that have been successfully parsed.
For most applications there will be no need for testing
@code{ggiParseMode} for failure.
@node ggiSetDisplayFrame
@section ggiSetDisplayFrame
@menu
@end menu
@subheading Name
ggiSetDisplayFrame, ggiSetWriteFrame, ggiSetReadFrame, ggiGetDisplayFrame, ggiGetWriteFrame, ggiGetReadFrame --- Set or get the current frame for display, writing and reading
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiSetDisplayFrame(ggi_visual_t vis, int frameno);
int ggiSetWriteFrame(ggi_visual_t vis, int frameno);
int ggiSetReadFrame(ggi_visual_t vis, int frameno);
int ggiGetDisplayFrame(ggi_visual_t vis);
int ggiGetWriteFrame(ggi_visual_t vis);
int ggiGetReadFrame(ggi_visual_t vis);
@end example
@subheading Description
These functions are used for selecting or getting the current
buffers, when using the multiple buffering function of LibGGI.
@code{ggiSetDisplayFrame} sets the frame that gets displayed.
@code{ggiSetWriteFrame} sets the frame for write operations such as
@code{ggiPuts} and @code{ggiHLine}.
@code{ggiSetReadFrame} sets the frame for read operations, like
@code{ggiGetPixel} and the @code{ggiCrossBlit} source.
@code{ggiGetDisplayFrame} reports the frame currently displayed.
@code{ggiGetWriteFrame} reports the frame currently written to.
@code{ggiSetReadFrame} reports the frame currently read from.
Frames are numbered from 0 to the number of frames requested - 1.
@subheading Return value
The @code{ggiSet*Frame} functions return @code{0} if they
succeed, and @code{<0} if they fail.
The @code{ggiGet*Frame} functions never fail.
@node Color and palette
@chapter Color and palette
Visuals may have an indirect mapping off the pixel-value to a color via a
programmable palette. This is e.g. true for the 8 bit IBM VGA modes. But
even for "direct-mapped" modes, you will need to know which color maps to
which pixel-value.
Try to cache the results of palette lookups in your application for
efficiency purposes.
@menu
* Basic data types::
* Color functions::
@end menu
@node Basic data types
@section Basic data types
@menu
* ggi_color::
* ggi_pixel::
@end menu
@node ggi_color
@subsection ggi_color
The @code{ggi_color} struct has 16 bit wide entries for red
(@code{.r}), green (@code{.g}), and blue (@code{.b})
values. It also has an alpha value (@code{.a}>) which is unused in
libggi, but allow LibGGI extensions to store an alpha value there.
Please scale your palette values as necessary.
@node ggi_pixel
@subsection ggi_pixel
The @code{ggi_pixel}, or the pixelvalue is a hardware-dependent
representation of a color. A pixelvalue is usually obtained from a
@code{ggi_color} by @code{ggiMapColor} or read from the visual by
@code{ggiGetPixel}. You can safely assume that the relationship
between a @code{ggi_color} and its associated @code{ggi_pixel} value
does not change unless you change the visual or the mode or the palette.
You can also do calculations with @code{ggi_pixel} values. Their format is
defined in @ref{ggi_pixelformat}.
@node Color functions
@section Color functions
@menu
* ggiMapColor::
* ggiSetPalette::
* ggiSetColorfulPalette::
* ggiSetGamma::
@end menu
@node ggiMapColor
@subsection ggiMapColor
@menu
@end menu
@subsubheading Name
ggiMapColor, ggiUnmapPixel, ggiPackColors, ggiUnpackPixels --- Convert from ggi_color(s) to ggi_pixel(s) and vice versa
int ggiUnmapPixel(ggi_visual_t vis,
ggi_pixel pixel, ggi_color *col);
int ggiPackColors(ggi_visual_t vis,
void *buf,
ggi_color *cols,
int len);
int ggiUnpackPixels(ggi_visual_t vis,
void *buf,
ggi_color *cols,
int len);
@end example
@subsubheading Description
@code{ggiMapColor} gets the pixelvalue for the given color.
@code{ggiUnmapPixel} gets the color associated with the given
pixelvalue.
@code{ggiPackColors} converts the colors in @code{cols} to pixelvalues
in @code{buf}. The output from this function is suitable for input to the
@code{ggiPut@{HLine,VLine,Box@}} functions.
@code{ggiUnpackPixels} converts the pixelvalues in @code{buf} to
individual elements of @code{cols}. This function maybe used to convert
buffers output by the @code{ggiGet@{HLine,VLine,Box@}} functions from the
pixelvalue representation to their actual colors.
The buffers output from @code{ggiPackColors} and the input to
@code{ggiUnpackPixels} are in the same format as the get/put buffers.
Their format is defined in @code{ggi_pixelformat}.
@subsubheading Return value
@code{ggiMapColor} returns a @code{ggi_pixel}.
@code{ggiUnmapPixel}, @code{ggiPackColors}, and
@code{ggiUnpackPixels} returns @code{0} for OK, otherwise an
error code.
@node ggiSetPalette
@subsection ggiSetPalette
@menu
@end menu
@subsubheading Name
ggiSetPalette, ggiGetPalette --- Manipulate the palette of a visual
@subsubheading Synopsis
@example
#include <ggi/ggi.h>
int ggiGetPalette(ggi_visual_t vis,
int s,
int len,
ggi_color *cmap);
int ggiSetPalette(ggi_visual_t vis,
int s,
int len,
ggi_color *cmap);
@end example
@subsubheading Description
LibGGI visuals in @code{GT_PALETTE} mode maps all pixelvalues to the
corresponding @code{ggi_color} entry in the visual's palette (also
known as a colormap or CLUT).
@code{ggiSetPalette} sets a range of palette values, of length
@code{len}, starting at index number @code{s}. The index can be
@code{GGI_PALETTE_DONTCARE} to indicate to indicate that the palette can be
installed anywhere in the CLUT.
This allows optimised use in windowing environments (to minimize color
flashing between windows) and should be used if possible.
@code{ggiGetPalette} copies the specified colors (starting from
@code{s}, for @code{len} colors) from the visual's palette to the array
pointed by @code{cmap}.
@subsubheading Return value
@code{ggiSetPalette} returns the number of the first entry
changed. Negative values indicate error (codes).
@code{ggiGetPalette} returns @code{0} for OK, otherwise
an error code. When called with len=0 this function will not
automatically succeed, but the return code will indicate whether there
is a readable CLUT.
@subsubheading See Also
@ref{ggiSetColorfulPalette}
@node ggiSetColorfulPalette
@subsection ggiSetColorfulPalette
@menu
@end menu
@subsubheading Name
ggiSetColorfulPalette --- Set a palette with a full range of all colors
@subsubheading Synopsis
@example
#include <ggi/ggi.h>
int ggiSetColorfulPalette(ggi_visual_t vis);
@end example
@subsubheading Description
LibGGI guarantees that there will be a default palette when a palettized mode is
set. What this default is, however, is dependent on the visual.
For example, the X target deliberately avoids setting all colors
to avoid color-flashing when moving between windows.
Applications that want to ensure that they have a full scale of all colors
can call @code{ggiSetColorfulPalette} after mode set. This function uses a
smarter color allocation scheme, causing good colors but still minimal
flashing in windowed targets.
@subsubheading Return value
@code{ggiSetColorfulPalette} returns the number of the first entry
changed. Negative values indicate error (codes).
@subsubheading See Also
@ref{ggiSetPalette}
@node ggiSetGamma
@subsection ggiSetGamma
@menu
@end menu
@subsubheading Name
ggiSetGammaMap, ggiGetGammaMap, ggiSetGamma, ggiGetGamma --- Manipulate the gamma maps and the gamma correction of a visual
@subsubheading Synopsis
@example
#include <ggi/ggi.h>
int ggiSetGammaMap(ggi_visual_t vis,
int s, int len,
ggi_color *gammamap);
int ggiGetGammaMap(ggi_visual_t vis,
int s, int len,
ggi_color *gammamap);
int ggiSetGamma(ggi_visual_t vis,
ggi_float r,
ggi_float g,
ggi_float b);
int ggiGetGamma(ggi_visual_t vis,
ggi_float *r,
ggi_float *g,
ggi_float *b);
@end example
@subsubheading Description
Some truecolor modes on some hardware can use the DAC's palette to lookup
the values before sending to the monitor. Generally this is used for gamma
correction by filling the lookup table with a curve, hence the name "gamma
map", but it could be used for other things e.g. special effects in games.
@code{ggiSetGammaMap} and @code{ggiGetGammaMap} sets or gets the
gamma map, for @code{len} colors starting at @code{s}.
@code{ggiSetGamma} and @code{ggiGetGamma} sets or gets the gamma
correction for the visual.
@subsubheading Return value
All four functions @code{0} for OK, otherwise an
error code.
@node ggi_pixelformat
@chapter ggi_pixelformat
@menu
* ggiGetPixelFormat::
@end menu
@node ggiGetPixelFormat
@section ggiGetPixelFormat
@menu
@end menu
@subheading Name
ggiGetPixelFormat --- Get a structure describing the format of a pixelvalue from a visual
@subheading Description
This function obtains the default pixel format for the given visual.
@subheading Return value
Returns a pointer to the @code{ggi_pixelformat} structure.
Modifying the structure returned is not allowed. Do not attempt to free
the pointer returned.
@subheading Structures
The @code{ggi_pixelformat} structure describes the format of a
@code{ggi_pixel}. An application would use this if it wanted to
directly output pixelvalues, rather than calling @code{ggiMapColor}
or @code{ggiPackColors} to convert a @code{ggi_color} to a
@code{ggi_pixel} value.
Other than the parameters of a @code{ggi_graphtype} that you can
specifically request at mode setting, there is no other way to change the
parameters of @code{ggi_pixelformat}. An application must not assume
the presence of any particular pixelformat. If the application cannot
handle a particular pixelformat, it should fall back on
@code{ggiMapColor}, @code{ggiPackColors} or @code{ggiCrossBlit}.
@example
/* Pixelformat for ggiGet/Put* buffers and pixellinearbuffers */
typedef struct @{
int depth; /* Number of significant bits */
int size; /* Physical size in bits */
/*
* Simple and common things first :
*
* Usage of the mask/shift pairs:
* If new_value is the _sizeof(ggi_pixel)*8bit_ value of the thing
* you want to set, you do
*
* *pointer &= ~???_mask; // Mask out old bits
* *pointer |= (new_value>>shift) & ???_mask;
*
* The reason to use 32 bit and "downshifting" is alignment
* and extensibility. You can easily adjust to other datasizes
* with a simple addition ...
*/
/* Simple colors:
*/
ggi_pixel red_mask; /* Bitmask of red bits */
int red_shift; /* Shift for red bits */
ggi_pixel green_mask; /* Bitmask of green bits */
int green_shift; /* Shift for green bits */
ggi_pixel blue_mask; /* Bitmask of blue bits */
int blue_shift; /* Shift for blue bits */
/* A few common attributes :
*/
ggi_pixel alpha_mask; /* Bitmask of alphachannel bits */
int alpha_shift; /* Shift for alpha bits */
ggi_pixel clut_mask; /* Bitmask of bits for the clut */
int clut_shift; /* Shift for bits for the clut*/
ggi_pixel fg_mask; /* Bitmask of foreground color */
int fg_shift; /* Shift for foreground color */
ggi_pixel bg_mask; /* Bitmask of background color */
int bg_shift; /* Shift for background color */
ggi_pixel texture_mask; /* Bitmask of the texture (for
textmodes - the actual character)
*/
int texture_shift; /* Shift for texture */
@end example
The above is used to describe a pixel simply. More detailed information, if
required, can be obtained from the following fields. See
@file{ggi/ggi.h} for a listing of bitmeanings.
@example
/*
* Now if this doesn't suffice you might want to parse the following
* to find out what each bit does:
*/
uint32 bitmeaning[sizeof(ggi_pixel)*8];
/* Shall we keep those ?
*/
uint32 flags; /* Pixelformat flags */
uint32 stdformat; /* Standard format identifier */
/* This one has only one use for the usermode application:
* To quickly check, if two buffers are identical. If both
* stdformats are the same and _NOT_ 0 (which means "WEIRD"),
* you may use things like memcpy between them which will have
* the desired effect ...
*/
@code{depth} and @code{size} are same as the depth and access
size information specified in the @code{ggi_graphtype}.
@code{clut_mask} is used in GT_PALETTE modes, indicating which bits
correspond to an index to the CLUT (color look-up table).
@code{fg_mask}, @code{bg_mask}, and @code{texture_mask}
are for text modes only, indicating the parts of the text-mode character.
@node Graphics context
@chapter Graphics context
LibGGI has a current context associated with each visual. This is done for
performance reasons, as LibGGI can set up pointers to optimized functions
when the GC changes (which can be monitored, as it may only be changed by
the functions mentioned below), or switch the hardware state efficiently.
@menu
* ggiSetGCForeground::
* ggiSetGCClipping::
@end menu
@node ggiSetGCForeground
@section ggiSetGCForeground
@menu
@end menu
@subheading Name
ggiSetGCForeground, ggiGetGCForeground, ggiSetGCBackground, ggiGetGCBackground --- Set or get the foreground and background colors used in drawing operations in a visual
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiSetGCForeground(ggi_visual_t vis, ggi_pixel color);
int ggiGetGCForeground(ggi_visual_t vis, ggi_pixel *color);
int ggiSetGCBackground(ggi_visual_t vis, ggi_pixel color);
int ggiGetGCBackground(ggi_visual_t vis, ggi_pixel *color);
@end example
@subheading Description
@code{ggiSetGCForeground} and @code{ggiGetGCForeground} set or reads
the current colors for the foreground, used in all normal drawing
functions.
@code{ggiSetGCBackground} and @code{ggiGetGCBackground} set or reads
the current colors for the background, used in two-color operations like
drawing text.
@subheading Return value
All four functions @code{0} for OK, otherwise an
error code.
@node ggiSetGCClipping
@section ggiSetGCClipping
@menu
@end menu
@subheading Name
ggiSetGCClipping, ggiGetGCClipping --- Set or get the clipping rectangle for a visual
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiSetGCClipping(ggi_visual_t vis,
int left, int top,
int right, int bottom);
int ggiGetGCClipping(ggi_visual_t vis,
int *left, int *top,
int *right, int *bottom);
@end example
@subheading Description
@code{ggiSetGCClipping} sets the the current clipping rectangle to
(left,top)-(right,bottom). @code{right} and @code{bottom} are the
bottom right corner of the rectangle + 1.
Initially the clipping rectangle is the whole virtual screen.
All LibGGI drawing primitives obey the clipping rectangle.
@code{ggiGetGCClipping} reads the coordinates of the current clipping
rectangle.
@subheading Return value
Both functions @code{0} for OK, otherwise an error code.
@node Primitives
@chapter Primitives
LibGGI has three basic types of primitives when it comes to filling
rectangular areas (including the degenerate cases of horizontal and vertical
lines and single pixels).
We have found three operations commonly performed on such areas:
@itemize @bullet
@item
Draw: This means you set all contained pixels to the current
foreground color (maybe modified by the update operations as set in the
current graphics context).
@item
Put: Fill the area with pixels of different value from a buffer.
@item
Get: Read pixels from the screen into such a buffer.
@end itemize
Get/Put buffers are buffers used by the functions @code{ggiGet*},
@code{ggiPut*}, @code{ggiPackColors} and @code{ggiUnpackPixels}.
The format of the individual pixels in get/put buffers are defined by
@code{ggi_pixelformat} (see the ggi_pixelformat section above).
Pixels are stored linearly, e.g. a rectangle with a width of three and a
height of two will be stored with pixels (0,0) (1,0) (2,0) (0,1) (1,1),
(2,1) in that order.
Get/put buffers use chunky pixels, unpacked, even if their representation in
the framebuffer is packed (i.e. pixel size not multiple of 8 bits) or
non-linear. Thus, the application does not need to know how to use planar or
packed pixels for non-direct acccess.
Note:
@sp 1
(You may specify use of packed buffers using the GT_SUB_PACKED_GETPUT
ggi_graphtype flag, but as of this writing, no targets implement that yet.)
The get/put buffer passed to the LibGGI functions should be allocated
for at least
width * height *
((@code{ggiGetPixelFormat()}->size+7)/8)
bytes.
(That is, the pixel size is obtained from
@code{ggi_pixelformat.size}, rounded to a multiple of 8 bits (one
byte), and is multiplied by the width and the height of the buffer.)
@node ggiDrawPixel
@section ggiDrawPixel
@menu
@end menu
@subheading Name
ggiDrawPixel, ggiPutPixel, ggiGetPixel --- Draw, put, and get a single pixel from a visual
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiDrawPixel(ggi_visual_t vis,
int x,
int y);
int ggiPutPixel(ggi_visual_t vis,
int x,
int y,
ggi_pixel col);
int ggiGutPixel(ggi_visual_t vis,
int x,
int y,
ggi_pixel *col);
@end example
@subheading Description
Draw, put, or get a single pixelvalue at (@code{x},@code{y}).
@subheading Return value
All three functions return @code{0} to indicate success.
Any other value indicates an error.
@node ggiDrawHLine
@section ggiDrawHLine
@menu
@end menu
@subheading Name
ggiDrawHLine, ggiPutHLine, ggiGetHLine --- Draw, put, and get a horizontal line from a visual
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiDrawHLine(ggi_visual_t vis, int x, int y, int w);
int ggiPutHLine(ggi_visual_t vis, int x, int y, int w, void *buf);
int ggiGetHLine(ggi_visual_t vis, int x, int y, int w, void *buf);
@end example
@subheading Description
Draw, put, or get a horizontal line from (@code{x},@code{y}), extending
@code{w} pixels in the positive x direction (normally right). The height
is one pixel.
@subheading Return value
All three functions return @code{0} to indicate success.
Any other value indicates an error.
@subheading See Also
@ref{ggiDrawVLine}, @ref{ggiDrawBox}, @ref{ggiDrawLine}
@node ggiDrawVLine
@section ggiDrawVLine
@menu
@end menu
@subheading Name
ggiDrawVLine, ggiPutVLine, ggiGetVLine --- Draw, put, and get a vertical line from a visual
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiDrawVLine(ggi_visual_t vis, int x, int y, int h);
int ggiPutVLine(ggi_visual_t vis, int x, int y, int h, void *buf);
int ggiGetVLine(ggi_visual_t vis, int x, int y, int h, void *buf);
@end example
@subheading Description
Draw, put, or get a vertical line from (@code{x},@code{y}), extending
@code{h} pixels in the positive y direction (normally down).
The width of the line is one pixel.
@subheading Return value
All three functions return @code{0} to indicate success.
Any other value indicates an error.
@subheading See Also
@ref{ggiDrawHLine}, @ref{ggiDrawBox}, @ref{ggiDrawLine}
@node ggiDrawBox
@section ggiDrawBox
@menu
@end menu
@subheading Name
ggiDrawBox, ggiPutBox, ggiGetBox --- Draw, put, and get a rectangle from a visual
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiDrawBox(ggi_visual_t vis, int x, int y, int w, int h);
int ggiPutBox(ggi_visual_t vis,
int x, int y, int w, int h,
void *buf);
int ggiGetBox(ggi_visual_t vis,
int x, int y, int w, int h,
void *buf);
@end example
@subheading Description
Draw, put, or get a rectangle at (@code{x},@code{y}), extending
@code{w} pixels in the positive x direction and @code{h} pixels in the
positive y direction.
@subheading Return value
All three functions return @code{0} to indicate success.
Any other value indicates an error.
@subheading See Also
@ref{ggiDrawHLine}, @ref{ggiDrawVLine}, @ref{ggiDrawLine}
@node ggiFillscreen
@section ggiFillscreen
@menu
@end menu
@subheading Name
ggiFillscreen --- Fills the entire virtual screen
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiFillscreen(ggi_visual_t vis);
@end example
@subheading Description
Fills the entire virtual screen with the current foreground color. It maybe
more efficient than the corresponding call to @code{ggiDrawBox()}.
@subheading Return value
This function returns @code{0} to indicate success.
Any other value indicates an error.
@node ggiDrawLine
@section ggiDrawLine
@menu
@end menu
@subheading Name
ggiDrawLine --- Draw a line on a visual
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiDrawLine(ggi_visual_t vis, int x, int y, int xe, int ye);
@end example
@subheading Description
Draws any line, using the current foreground color, from
(@code{x},@code{y}) to (@code{xe},@code{ye}). The line is exact; the
pixel set is no more than 0.5 pixels off the place it should be.
@subheading Return value
This function returns @code{0} to indicate success.
Any other value indicates an error.
@subheading See Also
@ref{ggiDrawHLine}, @ref{ggiDrawVLine}
@node DirectBuffer
@chapter DirectBuffer
Dependent on the visual and runtime environment found,
applications may be granted direct access to hardware and/or
library internal buffers. This may significantly enhance
performance for certain pixel oriented applications or libraries.
The DirectBuffer is a mechanism in which a LibGGI program can use to
determine all the characteristics of these buffers (typically the
framebuffer), including the method of addressing, the stride, alignment
requirements, and endianness.
However, use not conforming to this specification will have undefined
effects and may cause data loss or corruption, program malfunction or
abnormal program termination. So you don't really want to do this.
@menu
* Types of Buffers::
* Accessing the Buffer::
* DirectBuffer Structures::
* Getting DirectBuffers::
@end menu
@node Types of Buffers
@section Types of Buffers
Only the framebuffer is defined currently.
@menu
* Framebuffer::
* Pixel Linear Buffer::
@end menu
@node Framebuffer
@subsection Framebuffer
A frame buffer may be organized as several distinct buffers.
Each buffer may have a different layout. This means both the
addressing scheme to be used as well as the addressing
parameters may differ from buffer to buffer.
LibGGI currently has support for pixel-linear buffers, bit-planar buffers,
and interleaved planar buffers.
@node Pixel Linear Buffer
@subsection Pixel Linear Buffer
A linear buffer is a region in the application's virtual memory address
space. A pixel with the pixel coordinates (<x>,<y>) is assigned
a pixel number according to the following formula:
pixel_number = (origin_y + y) *
stride + origin_x + x;
In any case both x and y must not be negative,
x must be less than size_x and y must be
less than size_y. For top-left-origin screen coordinates,
stride and origin_y will both be positive. For
bottom-left-origin screen coordinates, stride and
origin_y will both be negative. This will result in the correct
pixel number with the same formula in both cases. The pixel number will be
used to address the pixel.
A certain number bpp of bits is stored per pixel, and this is
indicated in the @code{ggi_pixelformat.access} field.
For some visuals, the buffer might not be in host CPU native format and
swapping operations need to be performed before writes or after reads.
@node Accessing the Buffer
@section Accessing the Buffer
Read and write access to the buffer is done using load and store
instructions of the host CPU. The access width and alignment requirements
are assumed to be the same as the host CPU.
Read operations should be performed using the read buffer and write
operations should be performed using the write buffer. These might
be the same, but need not. If they are, read/write may be done to either
buffer. Please note, that either read or write may be @code{NULL}. These are
write-only or read-only buffers, which might be caused by hardware
limitations. Such buffers are not suited to do Read-Modify-Write operations,
so take care.
More importantly, certain DirectBuffers need to be explicitly acquired
(i.e. locked) before using (accessing their pointers).
Such a situation may arise if the underlying visual supports mixed
acceleration and framebuffer access, but they cannot occur at the same
time. In that case, LibGGI needs to be informed when the application is using the
framebuffer. An acquire is done by using
@xref{ggiResourceAcquire, ggiResourceAcquire3}.
and it is released by calling
@xref{ggiResourceAcquire, ggiResourceRelease3}.
You can determine whether the DirectBuffer needs to be acquired by using
@xref{ggiResourceAcquire, ggiResourceMustAcquire3}.
Be aware that the @code{read}, @code{write} and @code{stride}
fields of the DirectBuffer may be changed by an acquire, and that they may be
@code{NULL} or invalid when the DirectBuffer is not acquired.
@menu
* Paged Buffers::
@end menu
@node Paged Buffers
@subsection Paged Buffers
Paged buffers are indicated with page_size != 0 in
@code{ggi_directbuffer}.
Successive access to addresses addr0 and addr1 of
either read or write buffers with
addr0 / page_size !=
addr1 / page_size
may be very expensive compared to successive accesses with
addr0 / page_size ==
addr1 / page_size.
On i386 the penalty will be about 1500 cycles plus 4 cycles per
to be remapped. Because of this, block transfer operations might
become very inefficient for paged buffers. If there are two
different buffers provided for read and write operations,
you should do successive reads from one and do successive writes
to the other. If not, it is recommended to copy pagewise into
a temporary buffer and then to copy this temporary buffer
back to screen.
typedef struct @{
int stride; /* bytes per row */
ggi_pixelformat *pixelformat; /* format of the pixels */
@} ggi_pixellinearbuffer;
typedef struct @{
int next_line; /* bytes until next line */
int next_plane; /* bytes until next plane */
ggi_pixelformat *pixelformat; /* format of the pixels ??? */
/* shouldn't that rather describe the _planes_, then ??? becka */
@} ggi_pixelplanarbuffer;
/* Buffer types */
#define GGI_DB_NORMAL 0x0001 /* "frame" is valid when set */
#define GGI_DB_EXTENDED 0x0002
#define GGI_DB_MULTI_LEFT 0x0004
#define GGI_DB_MULTI_RIGHT 0x0008
/* Flags that may be or'ed with the buffer type */
#define GGI_DB_SIMPLE_PLB 0x00010000
/* GGI_DB_SIMPLE_PLB means that the buffer has the following properties:
type=GGI_DB_NORMAL
read=write
layout=blPixelLinearBuffer
*/
typedef struct @{
uint32 type; /* buffer type */
int frame; /* framenumber (GGI_DB_NORMAL) */
/* access info */
void *read; /* buffer address for reads */
void *write; /* buffer address for writes */
unsigned int page_size; /* zero for true linear buffers */
uint32 noaccess;
/* bitfield. bit x set means you may _not_ access this DB at the
width of 2^x bytes. Usually 0, but _check_ it. */
uint32 align;
/* bitfield. bit x set means you may only access this DB at the
width of 2^x bytes, when the access is aligned to a multiple
of 2^x. Note that bit 0 is a bit bogus here, but it should
be always 0, as then ((noaccess|align)==0) is a quick check
for "no restrictions". */
ggi_bufferlayout layout;
/* The actual buffer info. Depends on layout. */
union @{
ggi_pixellinearbuffer plb;
ggi_pixelplanarbuffer plan;
void *extended;
@} buffer;
@} ggi_directbuffer;
@end example
@table @asis
@item @code{frame}
is the frame number as used in multiple buffering. Note that each
frame can export more than one DirectBuffer.
@item @code{layout}
is an enumeration specifying whether the buffer is
pixel-linear, planar, etc.
@item @code{layout}
is a union of all buffer info. Check the @code{layout} member
to see which member of use.
@end table
Please see @ref{ggi_pixelformat} for information on
@code{ggi_pixelformat} struct, which describes the format of the
pixels for pixel-linear buffers.
@node ggiDBGetBuffer
@subsection ggiDBGetBuffer
@menu
@end menu
@subsubheading Name
ggiDBGetNumBuffers, ggiDBGetBuffer --- Get DirectBuffers from a visual
@subsubheading Synopsis
@example
#include <ggi/ggi.h>
int ggiDBGetNumBuffers(ggi_visual_t vis);
const ggi_directbuffer *ggiDBGetBuffer(ggi_visual_t vis, int bufnum);
@end example
@subsubheading Description
@code{ggiDBGetNumBuffers} returns the number of DirectBuffers available
to the application.
@code{ggiDBGetBuffer} obtains the DirectBuffer at the specified
position.
Use @code{ggiDBGetBuffer} to obtain the DirectBuffers at 0 to
n-1, where n is the number returned by @code{ggiDBGetNumBuffers}.
Pixel-linear buffers have @samp{type==GGI_DB_SIMPLE_PLB | GGI_DB_NORMAL}.
You're on your own now.
DirectBuffers where
@xref{ggiResourceAcquire, ggiResourceMustAcquire3}.
is true need to be 'acquired' (i.e. locked) before using. An acquire is done by using
@xref{ggiResourceAcquire, ggiResourceAcquire3}.
and it is released by calling
@xref{ggiResourceAcquire, ggiResourceRelease3}.
Beware that the @code{read}, @code{write} and
@code{stride} fields of the DirectBuffer may be changed by an acquire, and that they
may be @code{NULL} or invalid when the DirectBuffer is not acquired.
@subsubheading Return value
@code{ggiDBGetNumBuffers} returns the number of DirectBuffers
available. @code{0} indicates that no DirectBuffers are available.
@code{ggiDBGetBuffer} returns a pointer to a DirectBuffer
structure.
@subsubheading Examples
How to obtain a DirectBuffer
@sp 1
@example
ggi_visual_t vis;
ggi_mode mode;
int i;
/* Framebuffer info */
unsigned char *fbptr[2];
int stride[2];
int numbufs;
mode.frames = 2; /* Double-buffering */
mode.visible.x = 640; /* Screen res */
mode.visible.y = 480;
mode.virt.x = GGI_AUTO; /* Any virtual resolution. Will usually be set
mode.virt.y = GGI_AUTO; to be the same as visible but some targets may
have restrictions on virtual size. */
mode.graphtype = GT_8BIT; /* Depend on 8-bit palette. */
mode.dpp.x = mode.dpp.y = GGI_AUTO; /* Always 1x1 but we don't care. */
if(ggiSetMode(vis, &mode))
@{
/* Set mode has failed, should check if suggested mode
is o.k. for us, and try the call again. */
@}
numbufs = ggiDBGetNumBuffers(vis);
for(i = 0; i < numbufs; i++)
@{
ggi_directbuffer *db;
int frameno;
db = ggiDBGetBuffer(vis, i);
if(!(db->type & GGI_DB_SIMPLE_PLB))
@{
@var{ /* We don't handle anything but simple pixel-linear buffers.
Fall back to ggiPutBox() or something. */
continue;}
@}
@node ggiResourceAcquire
@section ggiResourceAcquire
@menu
@end menu
@subheading Name
ggiResourceAcquire, ggiResourceRelease, ggiResourceMustAcquire --- Acquire and release a LibGGI resource
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiResourceAcquire(ggi_resource_t res, uint32 actype);
int ggiResourceRelease(ggi_resource_t res);
int ggiResourceMustAcquire(ggi_resource_t res);
@end example
@subheading Description
@code{ggiResourceAcquire} acquires (locks) a LibGGI resource, typically a
DirectBuffer (see examples below). The @code{actype} indicates the
desired access type for the operation. The following flags may be
bitwise-or'ed together:
@table @asis
@item @code{GGI_ACTYPE_READ}
read access to the resource
@item @code{GGI_ACTYPE_WRITE}
write access to the resource
@end table
@code{ggiResourceRelease} releases (unlocks) an already-acquired
resource.
@code{ggiResourceMustAcquire} determines whether or not the
specified resource needs to be acquired before using.
@subheading Return Value
@code{ggiResourceAcquire} and @code{ggiResourceRelease}
return @code{0} on success, @code{<0} on failure.
@code{ggiResourceMustAcquire} is simply a macro that returns true
if the resource must be explicitly acquired and released, or false if not.
However, it is still safe to call @code{ggiResourceAcquire} or
@code{ggiResourceRelease} even in the latter case -- it would be a no-op.
@subheading Examples
Using DirectBuffers
@sp 1
@example
const ggi_directbuffer *dbuf;
/* Acquire DirectBuffer before we use it. */
if (ggiResourceAcquire(dbuf->resource, GGI_ACTYPE_WRITE) != 0) @{
fail("Error acquiring DirectBuffer\n");
@}
@var{/* Do framebuffer rendering here... */}
/* Release DirectBuffer when done with it. */
ggiResourceRelease(dbuf->resource);
@end example
@node ggiSetFlags
@section ggiSetFlags
@menu
@end menu
@subheading Name
ggiSetFlags, ggiGetFlags, ggiAddFlags, ggiRemoveFlags --- Set or get flags affecting operation on a visual
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiSetFlags(ggi_visual_t vis, ggi_flags flags);
ggi_flags ggiGetFlags(ggi_visual_t vis);
int ggiAddFlags(ggi_visual_t vis, ggi_flags flags);
int ggiRemoveFlags(ggi_visual_t vis, ggi_flags flags);
@end example
@subheading Description
@code{ggiSetFlags} sets the specified flags (bitwise OR'd together) on a
visual. This function is usually used to set async mode on a visual (see
below).
@code{ggiGetFlags} obtains the flags currently in effect.
@code{ggiAddFlags} and @code{ggiRemoveFlags} are macros that
set or unsets the specified flags.
@subheading Return Value
@code{ggiSetFlags}, @code{ggiAddFlags}, and
@code{ggiRemoveFlags} return @code{0} on success,
@code{<0} on failure.
@code{ggiGetFlags} returns the current flags.
@subheading Synchronous and Asynchronous drawing modes
Some visuals allow different modes with regard to when the screen is updated
and the actual drawing takes place.
@itemize @bullet
@item
In synchronous mode when the drawing command returns, it is already or
will be executed very shortly. So the visible effect is that everything
is drawn immediately. (It is not guaranteed in the strict sense in that
it is already drawn when the function call returns, but almost.)
This is the default mode for all visuals.
@item
The asynchronous mode does not guarantee that drawing commands are
executed immediately, but is faster on many targets.
If the visual does not support asynchronous mode, setting it has no
effect.
To make sure that all pending graphics operations are actually done and
the screen is updated, you need to call @code{ggiFlush}.
(@code{ggiFlush} is not needed in synchronous mode.)
@end itemize
Warning:
@sp 1
The screen refresh the X target does every 1/20 s to fake a real SYNC mode
can take about half the execution time of a program. So using synchronous mode can
@emph{really} slow things down.
The synchronous mode is default because it is what most programmers
expect.
All operations are guaranteed to be performed in the
order given in both modes. Reordering is not done.
So the recommendation for all graphics applications is to set the
asynchronous mode. It will be far more efficient on some platforms and will
@emph{never} be worse.
Setting up asynchronous mode
@sp 1
@example
ggiAddFlags(vis, GGIFLAG_ASYNC); /* switches to asynchronous mode */
ggiFlush(vis); /* updates the screen */
ggiRemoveFlags(vis, GGIFLAG_ASYNC); /* switches to synchronous mode */
@end example
@subheading See Also
@ref{ggiFlush}
@node ggiFlush
@section ggiFlush
@menu
@end menu
@subheading Name
ggiFlush, ggiFlushRegion --- Flush pending output
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiFlush(ggi_visual_t vis);
int ggiFlushRegion(ggi_visual_t vis,
int x, int y,
int w, int h);
@end example
@subheading Description
@code{ggiFlush} waits for the visual to finish pending accelerator
commands, and in some targets, it refreshes the framebuffer.
@code{ggiFlushRegion} performs the flush function
only in the specified region if it would improve performance.
These functions are not needed if the visual is in synchronous mode.
@subheading Return Value
No meaningful return value.
@node ggiCopyBox
@section ggiCopyBox
@menu
@end menu
@subheading Name
ggiCopyBox --- Copy a rectangular area
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiCopyBox(ggi_visual_t vis,
int x, int y,
int w, int h,
int nx, int ny);
@end example
@subheading Description
This is a area-to-area-blit, all in the same visual. Copy the box
described by @code{x},@code{y},@code{w},@code{h}
to the new location @code{nx},@code{ny}. This automatically takes
care of overlaps and optimizes for the given visual (e.g. uses HW-accel or
intermediate buffers as appropriate).
@code{ggiCopyBox} will transfer an area between frames when the read frame is
not the same as the write frame.
@subheading Return value
@code{0} for OK, otherwise an error code.
@subheading See Also
@ref{ggiCrossBlit}
@node ggiCrossBlit
@section ggiCrossBlit
@menu
@end menu
@subheading Name
ggiCrossBlit --- Copy a rectangular area between two visuals
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiCrossBlit(ggi_visual *src,
int sx, int sy,
int sw, int sh,
ggi_visual *dst,
int dx, int dy);
@end example
@subheading Description
Blits a rectangular memory area from one visual to another. It handles
colorspace-conversion. (Though it can be quite expensive, so take care.)
@code{ggiCrossBlit} will transfer an area from the source visual's read frame
to the destination visual's write frame.
This function does not perform stretching.
@subheading Return value
@code{0} for OK, otherwise an error code.
@subheading See Also
@ref{ggiCopyBox}
@node Origin
@chapter Origin
@menu
* ggiSetOrigin::
@end menu
@node ggiSetOrigin
@section ggiSetOrigin
@menu
@end menu
@subheading Name
ggiSetOrigin, ggiGetOrigin --- Set and get origin of virtual screen
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiSetOrigin(ggi_visual_t vis, int x, int y);
int ggiGetOrigin(ggi_visual_t vis, int *x, int *y);
@end example
@subheading Description
@code{ggiSetOrigin} sets the top-left corner of the displayed area to
(@code{x}, @code{y}).
When using a larger virtual area, you can pan the visible area over the
virtual one to do scrolling. Some targets have extemely efficient means to
do this (i.e. they do it in hardware).
Large virtual areas are also commonly used for buffering the display
contents, but that is usually more easily accomplished by requesting a
specific number of frames when setting a mode.
This call takes @emph{dot} coordinates, not
pixel coordinates as all other drawing primitives do. There is no
difference in graphics modes because by definition dpp is
1x1, in text modes the application can do smooth scrolling.
@code{ggiGetOrigin} gets the current top-left corner of the displayed
area into (@code{x}, @code{y}).
Due to rounding to the hardware's capabilities, the values
retrieved by a subsequent @code{ggiGetOrigin} may not necessarily match
those passed to @code{ggiSetOrigin} previously.
@subheading Return value
@code{0} for OK, otherwise an error code.
@subheading Examples
Pan from the top to the bottom of the virtual screen
@sp 1
@example
for(i = 0; i < virt_y-visible_y; i++) @{
ggiSetOrigin(vis, 0, i);
@}
@end example
@node Character Output
@chapter Character Output
@menu
* ggiPutc::
@end menu
@node ggiPutc
@section ggiPutc
@menu
@end menu
@subheading Name
ggiPutc, ggiPuts --- Draw one or more characters on visual
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiPutc(ggi_visual_t vis,
int x, int y,
char c);
int ggiPuts(ggi_visual_t vis,
int x, int y,
const char *str);
int ggiGetCharSize(ggi_visual_t vis, int *width,int *height);
@end example
@subheading Description
LibGGI provides a few functions to do basic character output. They are
intended for debugging and simple GUI applications. They are simple on
purpose: there is only one fixed-width font and its size cannot be
changed. Only the standard ASCII character set (\0x20 to \0x7f) is
supported, with no internationalization features. All more complex
character functions go beyond the scope of this base library.
@code{ggiPutc} puts a single character on a graphical visual.
@code{ggiPuts} puts multiple characters (of a C-style @code{NULL}-terminated
string) at once. No special handling is applied to control
characters like CR or LF. The associated glyph for control characters
will be displayed. @code{ggiPuts} also only clips text at
the clipping rectangle and does not wrap text.
@code{ggiGetCharSize} obtains the size of the character cell, in
pixels. This function allows the application to position the text
output accurately.
Note:
@sp 1
The values returned by @code{ggiGetCharSize} is not the
same as the values of @code{dpp} of the current
@code{ggi_mode}, which is in dots. In graphics modes are 1x1 dpp
by definition and use at least 8x8-pixel fonts. In text mode, the
character cell is 1x1 pixels by definition and the dpp value
is the actual size of the font.
@subheading Return value
@code{0} for OK, otherwise an error code.
int ggiEventsQueued(ggi_visual_t vis, gii_event_mask mask);
int ggiEventRead(ggi_visual_t vis, gii_event *ev, gii_event_mask mask);
int ggiEventSend(ggi_visual_t vis, gii_event *ev);
int ggiSetEventMask(ggi_visual_t vis, gii_event_mask evm);
gii_event_mask ggiGetEventMask(ggi_visual_t vis);
int giiAddEventMask(ggi_visual_t vis, gii_event_mask mask);
int giiRemoveEventMask(ggi_visual_t vis, gii_event_mask mask);
@end example
@subheading Description
LibGGI provides input facilities through an auxiliary library,
LibGII.
Each LibGGI visual internally contains a @code{gii_input_t} input, and
all LibGII functions are available to manipulate and process inputs.
The LibGGI version of LibGII functions simply take a @code{ggi_visual_t}
rather than @code{gii_input_t}. Events are LibGII types. All other
semantics are the same; see the @cite{LibGII API Manual} for details.
@subheading See Also
@code{giiJoinInputs}(3), @code{giiEventPoll}(3), @code{giiEventsQueued}(3), @code{giiEventRead}(3<), @code{giiEventSend}(3<), @code{giiSetEventMask}(3), @code{giiGetEventMask}(3), @code{giiAddEventMask}(3), @code{giiRemoveEventMask}(3)
@node ggiGetc
@section ggiGetc
@menu
@end menu
@subheading Name
ggiGetc, ggiKbhit --- Convenience functions for simplistic keyboard input
@subheading Synopsis
@example
#include <ggi/ggi.h>
int ggiGetc(ggi_visual_t vis);
int ggiKbhit(ggi_visual_t vis);
@end example
@subheading Description
@code{ggiGetc} gets a character from the keyboard,
and blocks if there is no key immediately available.
@code{ggiKbhit} checks if a key has been hit on the keyboard. This
does not consume the key. It is used for easy porting of old DOS
applications.
Important:
@sp 1
@emph{Do not} poll like this: @samp{do while( ! ggiKbhit(vis) );}
On a multitasking OS you would be wasting a lot of resources which could be
available to other processes. If you want to wait for a key, use the
@code{ggiGetc} call.
@subheading Return value
@code{ggiKbhit} returns @code{0} if no key has been received
yet, otherwise there is a key to be consumed.
@code{ggiGetc} returns a Unicode character in canonical form.
For a fuller definition of characters, please consult
@file{ggi/keyboard.h} and the @cite{LibGII API Manual}.