LibGGI API Manual

Steve Cheng

Hartmut Niemann

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.


Table of Contents
Preface
1. Introduction
2. General
3. Library control
ggiInit — Initialize and uninitialize LibGGI
ggiPanic — Exit LibGGI programs for fatal errors
4. Visual management
ggiOpen — Open and close a visual
5. Mode management
The ggi_mode struct
ggi_graphtype
GGI_AUTO
Mode negotiation
Functions
ggiSetMode — Set, check or get a mode on a visual
ggiSetGraphMode — Set and check a text/graphics mode on a visual
ggiParseMode — Operate on formatted strings specifying LibGGI modes
6. Frame management
ggiSetDisplayFrame — Set or get the current frame for display, writing and reading
7. Color and palette
Basic data types
ggi_color
ggi_pixel
Color functions
ggiMapColor — Convert from ggi_color(s) to ggi_pixel(s) and vice versa
ggiSetPalette — Manipulate the palette of a visual
ggiSetColorfulPalette — Set a palette with a full range of all colors
ggiSetGamma — Manipulate the gamma maps and the gamma correction of a visual
8. ggi_pixelformat
ggiGetPixelFormat — Get a structure describing the format of a pixelvalue from a visual
9. Graphics context
ggiSetGCForeground — Set or get the foreground and background colors used in drawing operations in a visual
ggiSetGCClipping — Set or get the clipping rectangle for a visual
10. Primitives
ggiDrawPixel — Draw, put, and get a single pixel from a visual
ggiDrawHLine — Draw, put, and get a horizontal line from a visual
ggiDrawVLine — Draw, put, and get a vertical line from a visual
ggiDrawBox — Draw, put, and get a rectangle from a visual
ggiFillscreen — Fills the entire virtual screen
ggiDrawLine — Draw a line on a visual
11. DirectBuffer
Types of Buffers
Framebuffer
Pixel Linear Buffer
Accessing the Buffer
Paged Buffers
DirectBuffer Structures
Getting DirectBuffers
ggiDBGetBuffer — Get DirectBuffers from a visual
12. Miscellaneous functions
ggiResourceAcquire — Acquire and release a LibGGI resource
ggiSetFlags — Set or get flags affecting operation on a visual
ggiFlush — Flush pending output
13. Blits
ggiCopyBox — Copy a rectangular area
ggiCrossBlit — Copy a rectangular area between two visuals
14. Origin
ggiSetOrigin — Set and get origin of virtual screen
15. Character Output
ggiPutc — Draw one or more characters on visual
16. Event handling
ggiEventPoll — Event management for LibGGI visual
ggiGetc — Convenience functions for simplistic keyboard input

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 , 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 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.


Chapter 1. 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 (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.


Chapter 2. General

To use LibGGI, #include ggi/ggi.h in a C program. LibGGI functions are prefixed with ggi, and other #defines are prefixed with GGI_.

Most LibGGI functions return 0 to indicate success, and a negative error code to indicate errors. 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.


Chapter 3. Library control

ggiInit

Name

ggiInit, ggiExit — Initialize and uninitialize LibGGI

#include <ggi/ggi.h>

int ggiInit(void);

int ggiExit(void);

Description

ggiInit initalizes the library. This function must be called before using other LibGGI functions; otherwise the results will be undefined.

ggiExit uninitializes the library (after being initalized by 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.

ggiInit allows multiple invocations. A reference count is maintained, and to completely uninitialize the library, ggiExit must be called as many times as ggiInit has been called beforehand.

Return value

ggiInit returns 0 for OK, otherwise an error code.

ggiExit returns:

0

after successfully cleaning up,

> 0

the number of 'open' ggiInit calls, if there has been more than one call to ggiInit. As ggiInit and ggiExit must be used in properly nested pairs, e.g. the first ggiExit after two ggiInits will return 1.

< 0

error, especially if more ggiExit calls have been done than ggiInit calls.

Examples

Example 3-1. Initialize and uninitialize LibGGI

if (ggiInit() != 0)
{
        exit(1);  /* can't start! */
}

/* Do some LibGGI stuff */

ggiExit();

ggiPanic

Name

ggiPanic — Exit LibGGI programs for fatal errors

#include <ggi/ggi.h>

int ggiPanic(const char *format, ...);

Description

ggiPanic does a graceful shutdown, with 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.

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.

Return value

Never returns.

Examples

Example 3-1. An unrecoverable error


if (my_important_struct->magic != MAGIC) {
	ggiPanic("Fatal error: magic corrupted\n");
}

Chapter 4. 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 ggi_visual_t, which is given to all drawing functions to indicate which visual to operate on.

Note: 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 ggiOpen to know where they should operate on.

ggi_visual_t is opaque to the user. Do not try to access any part of the structure directly. It may change without notice.

ggiOpen

Name

ggiOpen, ggiClose — Open and close a visual

#include <ggi/ggi.h>

ggi_visual_t ggiOpen(const char *display, ...);

int ggiClose(ggi_visual_t vis);

Description

ggiOpen opens a visual (along with associated inputs). The visual is specified as a display string, followed by NULL. If only 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 argptr, used to pass driver-specific, non-textual information to the driver.

ggiClose releases and destroys an open visual and its associated internal control structures. This will close X windows, return consoles to text-mode, etc.

Return value

ggiOpen returns the opened visual (ggi_visual_t), or NULL for error.

ggiClose returns 0 for OK, otherwise an error code.

Examples

Example 4-1. Open default visual

ggi_visual_t vis = ggiOpen(NULL);

if(vis==NULL)
{
	ggiPanic("Couldn't open default visual!\n");
}

Example 4-2. Open a memory visual

ggi_visual_t memvis = ggiOpen("display-memory", NULL);

if(memvis==NULL) {
	return -1;
}

Example 4-3. Closing visuals

ggiClose(memvis);
ggiClose(vis);

See Also

, libggi(7)

Chapter 5. 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.


The ggi_mode struct

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.

ggi_coord

ggi_coord represents any (x,y) coordinate.

frames

Use of multiple buffering is specified in the frames member of the ggi_mode struct, as the number of screen buffers needed.

Tip: 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.

visible

visible area represents the area of the visual that is visible to the user at any time.


ggi_graphtype

ggi_graphtype specifies the graphic type:

depth

Number of significant bits (e.g. bits representing the actual color or some other property of the pixel)

Applications can use GT_AUTO in any of these fields to get a 'recommended' setting.

The four aspects of a graphic type above are packed into a ggi_graphtype. See ggi/types.h for details about the possible schemes and subschemes.

There are also macros which represent some common ggi_graphtypes, mainly for compatibility:

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.

GT_TEXT16, GT_TEXT32

text modes with word- and longword-aligned characters and attributes.

GT_1BIT, GT_4BIT, GT_8BIT

(these modes use a palette.)

GT_15BIT, GT_16BIT, GT_24BIT, 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.


GGI_AUTO

If a given ggi_mode is set or checked, any size parameter may be GGI_AUTO (defined in ggi/types.h). It is a placeholder.

When GGI_AUTO is encountered in a parameter, it is replaced with corresponding values specified by GGI_DEFMODE variable.

If the corresponding value is not found in GGI_DEFMODE or that value is also GGI_AUTO, then the driver should select a reasonable value satisfying as many of the given constraints as possible. The following are some recommendations:

  • 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.

  • dpp.x and dpp.y will be 1 for graphics. For text modes the largest possible dpp.x and dpp.y (the most fine-grained font) should be used.

  • frames will be 1 if not specified.

Note: The rules above are only recommendations (which are hoped to best capture user expectations) to the driver implementer and in no way guaranteed.


Mode negotiation

There are three types of mode calls:

  • The ggiCheck*Mode functions test whether a given mode is acceptable or suggest a better one,

  • The ggiSet*Mode functions try to set the specified mode and fail if that is impossible. ggiSetMode then returns a better suggestion, as ggiCheck*Mode do. (The suggested mode is not silently set.)

  • ggiGetMode returns the mode that is currently set.

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 ggiCheckMode is minimally valid.

  • 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:

    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 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.

  • It is possible to pass GGI_AUTO as any of the parameters. GGI_AUTO is a placeholder (e.g. the program does not care about a specific parameter). The display target will reset GGI_AUTO parameter to a default, such as the maximum, preferred, or GGI_DEFMODE resolution, while being compatible with the other settings. The presence of GGI_AUTO is not flagged as an error.

    If ggiSet{Graph,Text}Mode is given GGI_AUTO as one or more of its arguments, it will silently set a mode. To get back this mode, you must use ggiGetMode.

Note: 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.


Functions

ggiSetMode

Name

ggiSetMode, ggiCheckMode, ggiGetMode — Set, check or get a mode on a visual

#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);

Description

ggiSetMode sets any mode (text or graphics).

ggiCheckMode checks whether or not the given mode (text or graphics) will work on the visual.

For both ggiSetMode and 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 GGI_AUTO (or GT_AUTO for the graphtype) is specified for any of the members of *tm, these are filled in with the recommended parameters.

For ggiSetMode, if the mode cannot be set, a mode is suggested in *tm, but it will not be silently set. However, you'll probably want to use the convenience functions ggiSetTextMode and ggiSetGraphMode instead of ggiSetMode.

ggiGetMode gets the current mode set on the visual.

Return value

ggiSetMode returns 0 if the mode is set successfully, otherwise an error code.

For ggiCheckMode, a return of 0 means that a 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 should work.)

For both functions, if the only modifications made to the structure is filling GGI_AUTO parameters, it is still considered as success.

ggiGetMode gets the current mode. tm will be filled with the current mode on return.

See Also

,

ggiSetGraphMode

Name

ggiSetTextMode, ggiCheckTextMode, ggiSetGraphMode, ggiCheckGraphMode, ggiSetSimpleMode, ggiCheckSimpleMode — Set and check a text/graphics mode on a visual

#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);

Description

The ggiCheck{Text,Graph,Simple}Mode and ggiSet{Text,Graph,Simple}Mode are convenient versions of ggiSetMode. They accept the mode parameters as integer arguments rather than as a ggi_mode struct that the application has to fill out. Otherwise, they are functionally equivalent to the 'master' ggiCheckMode and ggiSetMode functions, and the same mode-setting semantics apply.

ggiSetTextMode sets a textmode with given columns and rows, virtual columns and rows and a font of the given size.

ggiCheckTextMode checks a textmode with given columns and rows, virtual columns and rows and a font of the given size.

ggiSetGraphMode sets a graphics mode with a visible area of size x,y and a virtual area of size xvyv and the specified graphics type. (You can pan around the virtual area using ggiSetOrigin.)

ggiCheckGraphMode checks a graphics mode with the specified mode features.

ggiSetSimpleMode sets a graphics mode with a visible area of size xy and frames number of frames and the specified graphics type.

ggiCheckSimpleMode checks a graphics mode with the specified mode features.

If suggested_mode is not NULL, then it will be filled with the suggested mode, as documented under ggiCheckMode.

In text modes, the font size is the size of the pixel (ggi_mode.dpp).

Return value

For ggiCheckTextMode and ggiCheckGraphMode, a return of 0 means that a ggiSet*Mode call for this mode would succeed. Otherwise, the mode given cannot be set. In this case, suggested_mode is changed to the suggested mode.

For ggiSetTextMode and ggiSetGraphMode, a return of 0 indicates success, while any other value indicates an error.

Examples

Example 5-1. Try 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 Also

,

ggiParseMode

Name

ggiParseMode, ggiPrintMode, ggiSPrintMode, ggiFPrintMode — Operate on formatted strings specifying LibGGI modes

#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);

Description

ggiParseMode parses a string into a ggi_mode.

The ggi*PrintMode functions print all the members of ggi_mode in a human-readable form. ggiSPrintMode outputs to a preallocated string buffer, ggiFPrintMode outputs to a stdio FILE, and ggiPrintMode outputs to standard output. These functions correspond to sprintf(3), fprintf(3), 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.

Return value

ggiParseMode returns:

0

on success, i.e. the string was correct. However, errors involving GT_*, position information, or mismatched brackets do not make it fail; these errors are simply ignored.

<0

if there is text that can not be parsed. This text is printed to stderr. All parameters parsed so far are written into m.

So m contains all parameters that have been successfully parsed. For most applications there will be no need for testing ggiParseMode for failure.

See Also

libggi(7)

Chapter 6. Frame management

ggiSetDisplayFrame

Name

ggiSetDisplayFrame, ggiSetWriteFrame, ggiSetReadFrame, ggiGetDisplayFrame, ggiGetWriteFrame, ggiGetReadFrame — Set or get the current frame for display, writing and reading

#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);

Description

These functions are used for selecting or getting the current buffers, when using the multiple buffering function of LibGGI.

ggiSetDisplayFrame sets the frame that gets displayed.

ggiSetWriteFrame sets the frame for write operations such as ggiPuts and ggiHLine.

ggiSetReadFrame sets the frame for read operations, like ggiGetPixel and the ggiCrossBlit source.

ggiGetDisplayFrame reports the frame currently displayed.

ggiGetWriteFrame reports the frame currently written to.

ggiSetReadFrame reports the frame currently read from.

Frames are numbered from 0 to the number of frames requested - 1.

Return value

The ggiSet*Frame functions return 0 if they succeed, and <0 if they fail.

The ggiGet*Frame functions never fail.


Chapter 7. 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 types

ggi_color

The ggi_color struct has 16 bit wide entries for red (.r), green (.g), and blue (.b) values. It also has an alpha value (.a>) 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 ggi_pixel, or the pixelvalue is a hardware-dependent representation of a color. A pixelvalue is usually obtained from a ggi_color by ggiMapColor or read from the visual by ggiGetPixel. You can safely assume that the relationship between a ggi_color and its associated ggi_pixel value does not change unless you change the visual or the mode or the palette.

You can also do calculations with ggi_pixel values. Their format is defined in Chapter 8.


Color functions

ggiMapColor

Name

ggiMapColor, ggiUnmapPixel, ggiPackColors, ggiUnpackPixels — Convert from ggi_color(s) to ggi_pixel(s) and vice versa

#include <ggi/ggi.h>

ggi_pixel ggiMapColor(ggi_visual_t vis, ggi_color *col);

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);

Description

ggiMapColor gets the pixelvalue for the given color.

ggiUnmapPixel gets the color associated with the given pixelvalue.

ggiPackColors converts the colors in cols to pixelvalues in buf. The output from this function is suitable for input to the ggiPut{HLine,VLine,Box} functions.

ggiUnpackPixels converts the pixelvalues in buf to individual elements of cols. This function maybe used to convert buffers output by the ggiGet{HLine,VLine,Box} functions from the pixelvalue representation to their actual colors.

The buffers output from ggiPackColors and the input to ggiUnpackPixels are in the same format as the get/put buffers. Their format is defined in ggi_pixelformat.

Return value

ggiMapColor returns a ggi_pixel.

ggiUnmapPixel, ggiPackColors, and ggiUnpackPixels returns 0 for OK, otherwise an error code.

ggiSetPalette

Name

ggiSetPalette, ggiGetPalette — Manipulate the palette of a visual

#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);

Description

LibGGI visuals in GT_PALETTE mode maps all pixelvalues to the corresponding ggi_color entry in the visual's palette (also known as a colormap or CLUT).

ggiSetPalette sets a range of palette values, of length len, starting at index number s. The index can be 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.

ggiGetPalette copies the specified colors (starting from s, for len colors) from the visual's palette to the array pointed by cmap.

Return value

ggiSetPalette returns the number of the first entry changed. Negative values indicate error (codes).

ggiGetPalette returns 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.

See Also

ggiSetColorfulPalette

Name

ggiSetColorfulPalette — Set a palette with a full range of all colors

#include <ggi/ggi.h>

int ggiSetColorfulPalette(ggi_visual_t vis);

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 ggiSetColorfulPalette after mode set. This function uses a smarter color allocation scheme, causing good colors but still minimal flashing in windowed targets.

Return value

ggiSetColorfulPalette returns the number of the first entry changed. Negative values indicate error (codes).

See Also

ggiSetGamma

Name

ggiSetGammaMap, ggiGetGammaMap, ggiSetGamma, ggiGetGamma — Manipulate the gamma maps and the gamma correction of a visual

#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);

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.

ggiSetGammaMap and ggiGetGammaMap sets or gets the gamma map, for len colors starting at s.

ggiSetGamma and ggiGetGamma sets or gets the gamma correction for the visual.

Return value

All four functions 0 for OK, otherwise an error code.


Chapter 8. ggi_pixelformat

ggiGetPixelFormat

Name

ggiGetPixelFormat — Get a structure describing the format of a pixelvalue from a visual

#include <ggi/ggi.h>

ggi_pixelformat *ggiGetPixelFormat(ggi_visual_t vis);

Description

This function obtains the default pixel format for the given visual.

Return value

Returns a pointer to the ggi_pixelformat structure.

Modifying the structure returned is not allowed. Do not attempt to free the pointer returned.

Structures

The ggi_pixelformat structure describes the format of a ggi_pixel. An application would use this if it wanted to directly output pixelvalues, rather than calling ggiMapColor or ggiPackColors to convert a ggi_color to a ggi_pixel value.

Other than the parameters of a ggi_graphtype that you can specifically request at mode setting, there is no other way to change the parameters of 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 ggiMapColor, ggiPackColors or ggiCrossBlit.

/* 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

depth and size are same as the depth and access size information specified in the ggi_graphtype.

clut_mask is used in GT_PALETTE modes, indicating which bits correspond to an index to the CLUT (color look-up table).

fg_mask, bg_mask, and texture_mask are for text modes only, indicating the parts of the text-mode character.


Chapter 9. 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.

ggiSetGCForeground

Name

ggiSetGCForeground, ggiGetGCForeground, ggiSetGCBackground, ggiGetGCBackground — Set or get the foreground and background colors used in drawing operations in a visual

#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);

Description

ggiSetGCForeground and ggiGetGCForeground set or reads the current colors for the foreground, used in all normal drawing functions.

ggiSetGCBackground and ggiGetGCBackground set or reads the current colors for the background, used in two-color operations like drawing text.

Return value

All four functions 0 for OK, otherwise an error code.

ggiSetGCClipping

Name

ggiSetGCClipping, ggiGetGCClipping — Set or get the clipping rectangle for a visual

#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);

Description

ggiSetGCClipping sets the the current clipping rectangle to (left,top)-(right,bottom). right and 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.

ggiGetGCClipping reads the coordinates of the current clipping rectangle.

Return value

Both functions 0 for OK, otherwise an error code.


Chapter 10. 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:

Get/Put buffers are buffers used by the functions ggiGet*, ggiPut*, ggiPackColors and ggiUnpackPixels.

The format of the individual pixels in get/put buffers are defined by 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: (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 * ((ggiGetPixelFormat()->size+7)/8) bytes.

(That is, the pixel size is obtained from ggi_pixelformat.size, rounded to a multiple of 8 bits (one byte), and is multiplied by the width and the height of the buffer.)

ggiDrawPixel

Name

ggiDrawPixel, ggiPutPixel, ggiGetPixel — Draw, put, and get a single pixel from a visual

#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 ggiGetPixel(ggi_visual_t vis, int x, int y, ggi_pixel *col);

Description

Draw, put, or get a single pixelvalue at (x,y).

Return value

All three functions return 0 to indicate success. Any other value indicates an error.

ggiDrawHLine

Name

ggiDrawHLine, ggiPutHLine, ggiGetHLine — Draw, put, and get a horizontal line from a visual

#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);

Description

Draw, put, or get a horizontal line from (x,y), extending w pixels in the positive x direction (normally right). The height is one pixel.

Return value

All three functions return 0 to indicate success. Any other value indicates an error.

See Also

, ,

ggiDrawVLine

Name

ggiDrawVLine, ggiPutVLine, ggiGetVLine — Draw, put, and get a vertical line from a visual

#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);

Description

Draw, put, or get a vertical line from (x,y), extending h pixels in the positive y direction (normally down). The width of the line is one pixel.

Return value

All three functions return 0 to indicate success. Any other value indicates an error.

See Also

, ,

ggiDrawBox

Name

ggiDrawBox, ggiPutBox, ggiGetBox — Draw, put, and get a rectangle from a visual

#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);

Description

Draw, put, or get a rectangle at (x,y), extending w pixels in the positive x direction and h pixels in the positive y direction.

Return value

All three functions return 0 to indicate success. Any other value indicates an error.

See Also

, ,

ggiFillscreen

Name

ggiFillscreen — Fills the entire virtual screen

#include <ggi/ggi.h>

int ggiFillscreen(ggi_visual_t vis);

Description

Fills the entire virtual screen with the current foreground color. It maybe more efficient than the corresponding call to ggiDrawBox().

Return value

This function returns 0 to indicate success. Any other value indicates an error.

ggiDrawLine

Name

ggiDrawLine — Draw a line on a visual

#include <ggi/ggi.h>

int ggiDrawLine(ggi_visual_t vis, int x, int y, int xe, int ye);

Description

Draws any line, using the current foreground color, from (x,y) to (xe,ye). The line is exact; the pixel set is no more than 0.5 pixels off the place it should be.

Return value

This function returns 0 to indicate success. Any other value indicates an error.

See Also

,

Chapter 11. 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.


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: 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 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.


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 ggi_directbuffer structure.

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 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 ggiResourceAcquire(3) and it is released by calling ggiResourceRelease(3) You can determine whether the DirectBuffer needs to be acquired by using ggiResourceMustAcquire(3)

Be aware that the read, write and stride fields of the DirectBuffer may be changed by an acquire, and that they may be NULL or invalid when the DirectBuffer is not acquired.


Paged Buffers

Paged buffers are indicated with page_size != 0 in 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.


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;

frame

is the frame number as used in multiple buffering. Note that each frame can export more than one DirectBuffer.

layout

is an enumeration specifying whether the buffer is pixel-linear, planar, etc.

layout

is a union of all buffer info. Check the layout member to see which member of use.

Please see Chapter 8 for information on ggi_pixelformat struct, which describes the format of the pixels for pixel-linear buffers.


Getting DirectBuffers

ggiDBGetBuffer

Name

ggiDBGetNumBuffers, ggiDBGetBuffer — Get DirectBuffers from a visual

#include <ggi/ggi.h>

int ggiDBGetNumBuffers(ggi_visual_t vis);

const ggi_directbuffer *ggiDBGetBuffer(ggi_visual_t vis, int bufnum);

Description

ggiDBGetNumBuffers returns the number of DirectBuffers available to the application. ggiDBGetBuffer obtains the DirectBuffer at the specified position.

Use ggiDBGetBuffer to obtain the DirectBuffers at 0 to n-1, where n is the number returned by ggiDBGetNumBuffers.

Pixel-linear buffers have type==GGI_DB_SIMPLE_PLB | GGI_DB_NORMAL. You're on your own now.

DirectBuffers where ggiResourceMustAcquire(3) is true need to be 'acquired' (i.e. locked) before using. An acquire is done by using ggiResourceAcquire(3) and it is released by calling ggiResourceRelease(3) Beware that the read, write and stride fields of the DirectBuffer may be changed by an acquire, and that they may be NULL or invalid when the DirectBuffer is not acquired.

Return value

ggiDBGetNumBuffers returns the number of DirectBuffers available. 0 indicates that no DirectBuffers are available.

ggiDBGetBuffer returns a pointer to a DirectBuffer structure.

Examples

Example 11-1. How 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.... */

Chapter 12. Miscellaneous functions

ggiResourceAcquire

Name

ggiResourceAcquire, ggiResourceRelease, ggiResourceMustAcquire — Acquire and release a LibGGI resource

#include <ggi/ggi.h>

int ggiResourceAcquire(ggi_resource_t res, uint32 actype);

int ggiResourceRelease(ggi_resource_t res);

int ggiResourceMustAcquire(ggi_resource_t res);

Description

ggiResourceAcquire acquires (locks) a LibGGI resource, typically a DirectBuffer (see examples below). The actype indicates the desired access type for the operation. The following flags may be bitwise-or'ed together:

GGI_ACTYPE_READ

read access to the resource

GGI_ACTYPE_WRITE

write access to the resource

ggiResourceRelease releases (unlocks) an already-acquired resource.

ggiResourceMustAcquire determines whether or not the specified resource needs to be acquired before using.

Return Value

ggiResourceAcquire and ggiResourceRelease return 0 on success, <0 on failure.

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 ggiResourceAcquire or ggiResourceRelease even in the latter case -- it would be a no-op.

Examples

Example 12-1. Using 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);

ggiSetFlags

Name

ggiSetFlags, ggiGetFlags, ggiAddFlags, ggiRemoveFlags — Set or get flags affecting operation on a visual

#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);

Description

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).

ggiGetFlags obtains the flags currently in effect.

ggiAddFlags and ggiRemoveFlags are macros that set or unsets the specified flags.

Return Value

ggiSetFlags, ggiAddFlags, and ggiRemoveFlags return 0 on success, <0 on failure.

ggiGetFlags returns the current flags.

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 ggiFlush. (ggiFlush is not needed in synchronous mode.)

Warning

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 never be worse.

Example 12-1. 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 Also

ggiFlush

Name

ggiFlush, ggiFlushRegion — Flush pending output

#include <ggi/ggi.h>

int ggiFlush(ggi_visual_t vis);

int ggiFlushRegion(ggi_visual_t vis, int x, int y, int w, int h);

Description

ggiFlush waits for the visual to finish pending accelerator commands, and in some targets, it refreshes the framebuffer.

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.

Return Value

No meaningful return value.

See Also


Chapter 13. Blits

ggiCopyBox

Name

ggiCopyBox — Copy a rectangular area

#include <ggi/ggi.h>

int ggiCopyBox(ggi_visual_t vis, int x, int y, int w, int h, int nx, int ny);

Description

This is a area-to-area-blit, all in the same visual. Copy the box described by x,y,w,h to the new location nx,ny. This automatically takes care of overlaps and optimizes for the given visual (e.g. uses HW-accel or intermediate buffers as appropriate).

ggiCopyBox will transfer an area between frames when the read frame is not the same as the write frame.

Return value

0 for OK, otherwise an error code.

See Also

ggiCrossBlit

Name

ggiCrossBlit — Copy a rectangular area between two visuals

#include <ggi/ggi.h>

int ggiCrossBlit(ggi_visual *src, int sx, int sy, int sw, int sh, ggi_visual *dst, int dx, int dy);

Description

Blits a rectangular memory area from one visual to another. It handles colorspace-conversion. (Though it can be quite expensive, so take care.)

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.

Return value

0 for OK, otherwise an error code.

See Also


Chapter 14. Origin

ggiSetOrigin

Name

ggiSetOrigin, ggiGetOrigin — Set and get origin of virtual screen

#include <ggi/ggi.h>

int ggiSetOrigin(ggi_visual_t vis, int x, int y);

int ggiGetOrigin(ggi_visual_t vis, int *x, int *y);

Description

ggiSetOrigin sets the top-left corner of the displayed area to (x, 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 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.

ggiGetOrigin gets the current top-left corner of the displayed area into (x, y).

Due to rounding to the hardware's capabilities, the values retrieved by a subsequent ggiGetOrigin may not necessarily match those passed to ggiSetOrigin previously.

Return value

0 for OK, otherwise an error code.

Examples

Example 14-1. Pan from the top to the bottom of the virtual screen

for(i = 0; i < virt_y-visible_y; i++) {
        ggiSetOrigin(vis, 0, i);
}

Chapter 15. Character Output

ggiPutc

Name

ggiPutc, ggiPuts — Draw one or more characters on visual

#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);

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.

ggiPutc puts a single character on a graphical visual.

ggiPuts puts multiple characters (of a C-style 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. ggiPuts also only clips text at the clipping rectangle and does not wrap text.

ggiGetCharSize obtains the size of the character cell, in pixels. This function allows the application to position the text output accurately.

Note: The values returned by ggiGetCharSize is not the same as the values of dpp of the current 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.

Return value

0 for OK, otherwise an error code.


Chapter 16. Event handling

ggiEventPoll

Name

ggiJoinInputs, ggiEventPoll, ggiEventsQueued, ggiEventRead, ggiEventSend, ggiSetEventMask, ggiGetEventMask, ggiAddEventMask, ggiRemoveEventMask — Event management for LibGGI visual

#include <ggi/ggi.h>

gii_input_t ggiJoinInputs(ggi_visual_t vis, gii_input_t inp);

gii_event_mask ggiEventPoll(ggi_visual_t vis, gii_event_mask mask, struct timeval *t);

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);

Description

LibGGI provides input facilities through an auxiliary library, LibGII. Each LibGGI visual internally contains a gii_input_t input, and all LibGII functions are available to manipulate and process inputs. The LibGGI version of LibGII functions simply take a ggi_visual_t rather than gii_input_t. Events are LibGII types. All other semantics are the same; see the LibGII API Manual for details.

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 gii_input_t directly (and that may in fact fail because an input device is already open). The LibGGI ggiEvent* functions should be used to do event handling in LibGGI.

See Also

giiJoinInputs(3), giiEventPoll(3), giiEventsQueued(3), giiEventRead(3), giiEventSend(3<), giiSetEventMask(3), giiGetEventMask(3), giiAddEventMask(3), giiRemoveEventMask(3)

ggiGetc

Name

ggiGetc, ggiKbhit — Convenience functions for simplistic keyboard input

#include <ggi/ggi.h>

int ggiGetc(ggi_visual_t vis);

int ggiKbhit(ggi_visual_t vis);

Description

ggiGetc gets a character from the keyboard, and blocks if there is no key immediately available.

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: Do not poll like this: 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 ggiGetc call.

Return value

ggiKbhit returns 0 if no key has been received yet, otherwise there is a key to be consumed.

ggiGetc returns a Unicode character in canonical form.

For a fuller definition of characters, please consult ggi/keyboard.h and the LibGII API Manual.