LibGGI API ManualLibGGI API
Steve Cheng (steve@ggi-project.org)
likes to hack GGI.
Hartmut Niemann maintains documentation for
the GGI Project.
This document describes the application programming interface for LibGGI,
an extremely flexible and extensible, dynamic drawing library developed
by the GGI project.
For libggi 2.0, imminent release
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.
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
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
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.
Introduction
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 (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.
GeneralTo use LibGGI, #include ggi/ggi.h in a C program.
LibGGI functions are prefixed with Most LibGGI functions return 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
ggi/errors.h file, which is part of the
LibGGI/LibGG package.
Library controlggiInit3ggiGGIggiInitggiExitInitialize and uninitialize LibGGI#include <ggi/ggi.h>int int DescriptionReturn value
after successfully cleaning up,
the number of 'open'
error, especially if more ExamplesInitialize and uninitialize LibGGI
if (ggiInit() != 0)
{
exit(1); /* can't start! */
}
/* Do some LibGGI stuff */
ggiExit();
ggiPanic3ggiGGIggiPanicExit LibGGI programs for fatal errors#include <ggi/ggi.h>int const char *Description
-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.
Return valueNever returns.
ExamplesAn unrecoverable error
if (my_important_struct->magic != MAGIC) {
ggiPanic("Fatal error: magic corrupted\n");
}
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
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 ggiOpen3ggiGGIggiOpenggiCloseOpen and close a visual#include <ggi/ggi.h>ggi_visual_t const char *int ggi_visual_t DescriptionThe other arguments are for internal purposes only, such as
Return valueExamplesOpen default visual
ggi_visual_t vis = ggiOpen(NULL);
if(vis==NULL)
{
ggiPanic("Couldn't open default visual!\n");
}
Open a memory visual
ggi_visual_t memvis = ggiOpen("display-memory", NULL);
if(memvis==NULL) {
return -1;
}
Closing visuals
ggiClose(memvis);
ggiClose(vis);
See AlsoMode 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.
The
This structure defines a visual's (graphics) mode.
The definition in ggi/ggi.h is:
typedef struct { sint16 x, y; } ggi_coord;
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;
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.
Use of multiple buffering is specified in the
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.
Both the visible and virtual size are given in
pixels, not dots. This makes a difference for text
modes, because a character is treated as one pixel, but consists of a
Number of significant bits
(e.g. bits representing the actual color or some
other property of the pixel)
(access)
Number of physical bits per pixel.
Only the Mode 'category':
(text modes),(pixel is a direct RGB value),(grayscale :-), (each pixel is an index to a colormap)
Miscellaneous info. Indicates whether the pixel values are
in reverse byte or bit order, etc.
Applications can use
The four aspects of a graphic type above are packed into a
ggi/types.h for details
about the possible schemes and subschemes.
There are also macros which represent some common
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.
text modes with word- and longword-aligned characters and attributes.
(these modes use a palette.)
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.
If a given ggi/types.h>).
It is a placeholder.
When GGI_DEFMODE variable.
If the corresponding value is not found in GGI_DEFMODE
or that value is also If a visible size is given but no virtual, the lowest reasonable
(taking alignment and accelleration constraints into account)
should be used.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.If a virtual size is given but no visible, the highest possible
visible size is selected.If no size is given, the driver uses some builtin default.If the graphtype is unspecified, the highest possible graphtype
that meets the geometry constraints is set/suggested.
The rules above are only Mode negotiation
There are three types of mode calls:
The The
If a given mode can not be set, the structure passed
is changed to the suggested mode as follows:
Resolutions are always adjusted 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 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.
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 Font sizes (i.e. the size of the pixel in textmodes) are handled the
other way round: they are adjusted down except when there is nothing
below.
Graphtype:
This doesn't make sense: "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 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
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.
It is possible to pass GGI_DEFMODE resolution, while being compatible with the other
settings. The presence of not
flagged as an error.
If
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.
FunctionsggiSetMode3ggiGGIggiSetModeggiCheckModeggiGetModeSet, check or get a mode on a visual#include <ggi/ggi.h>int ggi_visual_t int ggi_visual_t int ggi_visual_t Description
For both
For Return value
For should work.)
For both functions, if the only modifications made to the
structure is filling See AlsoggiSetGraphMode3ggiGGIggiSetTextModeggiCheckTextModeggiSetGraphModeggiCheckGraphModeggiSetSimpleModeggiCheckSimpleModeSet and check a text/graphics mode on a visual
#include <ggi/ggi.h>int
ggi_visual_t int
ggi_visual_t int
ggi_visual_t int
ggi_visual_t int
ggi_visual_t int
ggi_visual_t Description
The
If
In text modes, the font size is the size of the pixel
(Return value
For
For ExamplesTry a 320x200x8 mode
err = ggiCheckGraphMode(vis, 320, 200, GGI_AUTO, GGI_AUTO, GT_8BIT,
&sug_mode, NULL);
if(err) {
/* Check if returned mode is ok... /*
}
else {
ggiSetMode(&sug_mode);
}
See AlsoggiParseMode3ggiGGIggiParseModeggiPrintModeggiSPrintModeggiFPrintModeOperate on formatted strings specifying LibGGI modes#include <ggi/ggi.h>int const char *int ggi_mode *int char *int FILE *Description
The ,
,
,
respectively.
The format of the string used by these functions is exactly the same as the one used in
environment variables.
Return valueon success, i.e. the string was correct.
However, errors involving <0
if there is text that can not be parsed.
This text is printed to stderr.
All parameters parsed so far are written into
So See AlsoFrame managementggiSetDisplayFrame3ggiGGIggiSetDisplayFrameggiSetWriteFrameggiSetReadFrameggiGetDisplayFrameggiGetWriteFrameggiGetReadFrameSet or get the current frame for display, writing and reading
#include <ggi/ggi.h>int ggi_visual_t int ggi_visual_t int ggi_visual_t int ggi_visual_t int ggi_visual_t int ggi_visual_t DescriptionThese functions are used for selecting or getting the current
buffers, when using the multiple buffering function of LibGGI.
Frames are numbered from 0 to the number of frames requested - 1.
Return valueThe <0 if they fail.
The 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.
Basic data typesggi_color
The ) which is unused in
libggi, but allow LibGGI extensions to store an alpha value there.
Please scale your palette values as necessary.
ggi_pixel
The
You can also do calculations with .
Color functionsggiMapColor3ggiGGIggiMapColorggiUnmapPixelggiPackColorsggiUnpackPixelsConvert from ggi_color(s) to ggi_pixel(s) and vice versa
#include <ggi/ggi.h>ggi_pixel ggi_visual_t int
ggi_visual_t int
ggi_visual_t int
ggi_visual_t Description
The buffers output from Return valueggiSetPalette3ggiGGIggiSetPaletteggiGetPaletteManipulate the palette of a visual
#include <ggi/ggi.h>int
ggi_visual_t int
ggi_visual_t Description
LibGGI visuals in Return valueSee AlsoggiSetColorfulPalette3ggiGGIggiSetColorfulPaletteSet a palette with a full range of all colors
#include <ggi/ggi.h>int ggi_visual_t 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 Return valueSee AlsoggiSetGamma3ggiGGIggiSetGammaMapggiGetGammaMapggiSetGammaggiGetGammaManipulate the gamma maps and the gamma correction of a visual
#include <ggi/ggi.h>int
ggi_visual_t int
ggi_visual_t int
ggi_visual_t int
ggi_visual_t 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.
Return valueAll four functions ggi_pixelformatggiGetPixelFormat3ggiGGIggiGetPixelFormatGet a structure describing the format of a pixelvalue from a visual#include <ggi/ggi.h>ggi_pixelformat *ggi_visual_t DescriptionThis function obtains the default pixel format for the given visual.
Return valueReturns a pointer to the
Modifying the structure returned is not allowed. Do not attempt to free
the pointer returned.
Structures
The
Other than the parameters of a
/* 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 */
The above is used to describe a pixel simply. More detailed information, if
required, can be obtained from the following fields. See
ggi/ggi.h for a listing of bitmeanings.
/*
* 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 ...
*/
} ggi_pixelformat;
/* Pixelformat flags */
#define GGI_PF_REVERSE_ENDIAN 0x01
#define GGI_PF_HIGHBIT_RIGHT 0x02
#define GGI_PF_HAM 0x04
#define GGI_PF_EXTENDED 0x08
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.
ggiSetGCForeground3ggiGGIggiSetGCForegroundggiGetGCForegroundggiSetGCBackgroundggiGetGCBackgroundSet or get the foreground and background colors used in drawing
operations in a visual#include <ggi/ggi.h>int ggi_visual_t int ggi_visual_t int ggi_visual_t int ggi_visual_t DescriptionReturn valueAll four functions ggiSetGCClipping3ggiGGIggiSetGCClippingggiGetGCClippingSet or get the clipping rectangle for a visual
#include <ggi/ggi.h>int
ggi_visual_t int
ggi_visual_t DescriptionInitially the clipping rectangle is the whole virtual screen.
All LibGGI drawing primitives obey the clipping rectangle.
Return valueBoth functions 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:
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).Put: Fill the area with pixels of different value from a buffer.Get: Read pixels from the screen into such a buffer.Get/Put buffers are buffers used by the functions
The format of the individual pixels in get/put buffers are defined by
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.
(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
size+7)/8)
bytes.
(That is, the pixel size is obtained from
Note:
We need to care for strange things like 5x7 rectangles in 2bpp modes!
Does the stride need to be an integral byte count?
ggiDrawPixel3ggiGGIggiDrawPixelggiPutPixelggiGetPixelDraw, put, and get a single pixel from a visual#include <ggi/ggi.h>int ggi_visual_t int ggi_visual_t int
ggi_visual_t Description
Draw, put, or get a single pixelvalue at (Return valueAll three functions return ggiDrawHLine3ggiGGIggiDrawHLineggiPutHLineggiGetHLineDraw, put, and get a horizontal line from a visual#include <ggi/ggi.h>int ggi_visual_t int
ggi_visual_t int
ggi_visual_t Description
Draw, put, or get a horizontal line from (Return valueAll three functions return See AlsoggiDrawVLine3ggiGGIggiDrawVLineggiPutVLineggiGetVLineDraw, put, and get a vertical line from a visual#include <ggi/ggi.h>int ggi_visual_t int
ggi_visual_t int
ggi_visual_t Description
Draw, put, or get a vertical line from (Return valueAll three functions return See AlsoggiDrawBox3ggiGGIggiDrawBoxggiPutBoxggiGetBoxDraw, put, and get a rectangle from a visual#include <ggi/ggi.h>int
ggi_visual_t int
ggi_visual_t int
ggi_visual_t Description
Draw, put, or get a rectangle at (Return valueAll three functions return See AlsoggiFillscreen3ggiGGIggiFillscreenFills the entire virtual screen#include <ggi/ggi.h>int ggi_visual_t Description
Fills the entire virtual screen with the current foreground color. It maybe
more efficient than the corresponding call to Return valueThis function returns ggiDrawLine3ggiGGIggiDrawLineDraw a line on a visual#include <ggi/ggi.h>int
ggi_visual_t Description
Draws any line, using the current foreground color, from
(Return valueThis function returns See AlsoDirectBuffer
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.
Types of Buffers
Only the framebuffer is defined currently.
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.
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:
In any case both
A certain number 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 specified in the
Read operations should be performed using the
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
and it is released by calling
You can determine whether the DirectBuffer needs to be acquired by using
Be aware that the Paged Buffers
Paged buffers are indicated with
Successive access to addresses
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.
DirectBuffer Structures
typedef enum {
blPixelLinearBuffer,
blPixelPlanarBuffer,
blExtended,
blLastBufferLayout
} ggi_bufferlayout;
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;
is the frame number as used in multiple buffering. Note that each
frame can export more than one DirectBuffer.is an enumeration specifying whether the buffer is
pixel-linear, planar, etc.is a union of all buffer info. Check the
Please see for information on
Getting DirectBuffersggiDBGetBuffer3ggiGGIggiDBGetNumBuffersggiDBGetBufferGet DirectBuffers from a visual#include <ggi/ggi.h>int ggi_visual_t const ggi_directbuffer *ggi_visual_t Description
Use
Pixel-linear buffers have
DirectBuffers where
is true need to be 'acquired' (i.e. locked) before using. An acquire is done by using
and it is released by calling
Beware that the Return valueExamplesHow to obtain a DirectBuffer
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(ggiInit())
{
/* Failed to initialize library. Bomb out. */
}
vis = ggiOpen(NULL);
if(!vis)
{
/* Opening default visual failed, quit. */
}
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))
{
/* We don't handle anything but simple pixel-linear buffers.
Fall back to ggiPutBox() or something. */
continue;
>
}
frameno = db->frame;
if(readptr[frameno] != NULL &&
(db->buffer.plb.pixelformat->flags & GGI_PF_REVERSE_ENDIAN))
{
continue;
}
fbptr[frameno] = db->write; /* read == write for simple plbs */
/* Stride of framebuffer (in bytes). */
stride[frameno] = db->buffer.plb.stride;
/* Check pixel format, be portable.... */>
Miscellaneous functionsggiResourceAcquire3ggiGGIggiResourceAcquireggiResourceReleaseggiResourceMustAcquireAcquire and release a LibGGI resource#include <ggi/ggi.h>int ggi_resource_t int ggi_resource_t int ggi_resource_t Descriptionread access to the resourcewrite access to the resourceReturn Value<0 on failure.
ExamplesUsing DirectBuffers
const ggi_directbuffer *dbuf;
/* Acquire DirectBuffer before we use it. */
if (ggiResourceAcquire(dbuf->resource, GGI_ACTYPE_WRITE) != 0) {
fail("Error acquiring DirectBuffer\n");
}
/* Do framebuffer rendering here... */
/* Release DirectBuffer when done with it. */
ggiResourceRelease(dbuf->resource);
ggiSetFlags3ggiGGIggiSetFlagsggiGetFlagsggiAddFlagsggiRemoveFlagsSet or get flags affecting operation on a visual#include <ggi/ggi.h>int ggi_visual_t ggi_flags ggi_visual_t int ggi_visual_t int ggi_visual_t DescriptionReturn Value<0 on failure.Synchronous and Asynchronous drawing modes
Some visuals allow different modes with regard to when the screen is updated
and the actual drawing takes place.
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.
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
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
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
Setting up asynchronous mode
ggiAddFlags(vis, GGIFLAG_ASYNC); /* switches to asynchronous mode */
ggiFlush(vis); /* updates the screen */
ggiRemoveFlags(vis, GGIFLAG_ASYNC); /* switches to synchronous mode */
See AlsoggiFlush3ggiGGIggiFlushggiFlushRegionFlush pending output#include <ggi/ggi.h>int ggi_visual_t int ggi_visual_t DescriptionThese functions are not needed if the visual is in synchronous mode.
Return Value
No meaningful return value.
See AlsoBlitsggiCopyBox3ggiGGIggiCopyBoxCopy a rectangular area#include <ggi/ggi.h>int
ggi_visual_t Description
This is a area-to-area-blit, all in the same visual. Copy the box
described by Return valueSee AlsoggiCrossBlit3ggiGGIggiCrossBlitCopy a rectangular area between two visuals#include <ggi/ggi.h>int
ggi_visual *Description
Blits a rectangular memory area from one visual to another. It handles
colorspace-conversion. (Though it can be quite expensive, so take care.)
This function does not perform stretching.
Return valueSee AlsoOriginggiSetOrigin3ggiGGIggiSetOriginggiGetOriginSet and get origin of virtual screen#include <ggi/ggi.h>int ggiSetOriginggi_visual_t int ggi_visual_t Description
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
This call takes dot coordinates, not
pixel coordinates as all other drawing primitives do. There is no
difference in graphics modes because by definition
Due to rounding to the hardware's capabilities, the values
retrieved by a subsequent Return valueExamplesPan from the top to the bottom of the virtual screen
for(i = 0; i < virt_y-visible_y; i++) {
ggiSetOrigin(vis, 0, i);
}
Character OutputggiPutc3ggiGGIggiPutcggiPutsDraw one or more characters on visual#include <ggi/ggi.h>int
ggi_visual_t int
ggi_visual_t int ggi_visual_t 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.
The values returned by Return valueEvent handlingggiEventPoll3ggiGGIggiJoinInputsggiEventPollggiEventsQueuedggiEventReadggiEventSendggiSetEventMaskggiGetEventMaskggiAddEventMaskggiRemoveEventMask#include <ggi/ggi.h>gii_input_t ggi_visual_t gii_event_mask
ggi_visual_t int ggi_visual_t int ggi_visual_t int ggi_visual_t int ggi_visual_t gii_event_mask ggi_visual_t int ggi_visual_t int ggi_visual_t Description
LibGGI provides input facilities through an auxiliary library,
LibGGI visuals open the appropriate inputs already, including mouse
and keyboard, or the inputs are 'intrinsic' to the visual, e.g. X mouse
and keyboard events. Thus in the usual cases there is no need to open a
LibGII See AlsoggiGetc3ggiGGIggiGetcggiKbhitConvenience functions for simplistic keyboard input#include <ggi/ggi.h>int ggiGetcggi_visual_t int ggi_visual_t DescriptionReturn value
For a fuller definition of characters, please consult
ggi/keyboard.h and the