Next Previous Contents

3. LibGGI Functions

3.1 Library control

int ggiInit(void);

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

Return: 0 for OK, otherwise an error code.

Example:


ggiInit();
/* do some libggi stuff */
ggiExit();

void ggiExit(void);

Uninitializes the library and automatically cleanup. This should be called after an application is finished with the library. If any GGI functions are called after the use of ggiExit the results will be undefined.

Return: None

Example:


ggiInit();
/* do some libggi stuff */
ggiExit();

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

Graceful shutdown for fatal errors with reporting. May be used like printf(3). It will shut down the graphics modes active, close all visuals, print the error message given 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 it should be used in rare situations such as corruption of critical data structures.

Return: never returns.

Example:


ggiPanic("Aiee! Penguin on fire! ;-) Error code: %d", err);

3.2 Visual management

A visual is simply a thing you can draw on. For example, a VT in fullscreen-mode, an X window, an invisible memory area, and 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.

Each visual is completely independent of each other. 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.

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

In the older static GGI library, drawing functions operated on one single default visual. (i.e. the library was quite single-headed.) Focus functions were used to select an opened visual to operate on. They now have no effect and will never do anything, but are kept for compability.

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

Opens a visual. This function is given a null terminated list of the names of the display targets to open (i.e. the type of visual).

Return: The opened visual, or NULL for error.

Example:


memory_visual = ggiOpen("display-memory", NULL);

/* Get from LIBGGI_DISPLAY enviroment variable */
default_visual = ggiOpen(NULL); 

if(!memory_visual || !default_visual)
        return EXIT_FAILURE;

int ggiClose(ggi_visual_t vis);

Releases and destroys the visual and the associated internal control structures. This will close X windows, return KGI-consoles to text-mode, etc.

If focus is on the closed visual, focus is set to NULL.

Return: 0 for OK, otherwise an error code.

Example:


memory_visual = ggiOpen("display-memory", NULL);

/* do some drawing, save image, etc. */

ggiClose(memory_visual);

3.3 Mode management

The ggi_mode struct

The definition in 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      text;      /* fontsize                         */
} ggi_mode;

You don't need to care about the internal definition, if you want to set a mode, but it is necessary if you want to find out the mode actually set.

Please note that 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 text.x*text.y sized matrix of dots.

int ggiSetMode(ggi_visual_t visual, ggi_mode *tm);

Set any mode (text or graphics).

Return: 0 for OK, otherwise could not set mode.

Use this function only if you want something really strange that the specific SetModes below cannot give you. You usually do not want to do this, unless you really know what you are doing and understand the values in ggi_mode.

int ggiGetMode(ggi_visual_t visual, ggi_mode *tm);

Get the current mode. tm will be filled with the current mode on return.

Return: 0 for OK, otherwise an error code.

int ggiCheckMode(ggi_visual_t visual, ggi_mode *tm);

Check any mode (text or graphics).

Return: A return of 0 means that a setmode call for this mode would succeed. Otherwise, the mode is given cannot be set.

Please note that the following changes in the mode do not make ggiCheckMode fail, as it is assumed that the changes do not affect usage of the mode:

If the mode can not be set, tm is changed to the suggested mode as follows:

int ggiSetTextMode(ggi_visual_t visual, int cols, int rows, int vcols, int vrows, int fontx, int fonty);

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

Return: 0 for OK, otherwise could not set mode.

int ggiCheckTextMode(ggi_visual_t visual, int cols, int rows, intvcols, int vrows, fontx, int fonty, ggi_mode *suggested_mode, ...);

Check a text mode, with a null-terminated list of mode features. The last argument must be NULL.

Return: A return of 0 means that a setmode call for this mode would succeed. Otherwise, the mode is given cannot be set. In this case, tm is changed to the suggested mode:

If suggested_mode is not NULL, then it will be filled with the suggested mode, as documented under ggiCheckMode(). The ... is reserved for future arguments, but currently there is nothing that may be put between the final NULL and suggested_mode.

int ggiSetGraphMode(ggi_visual_t visual, int x, int y, int xv,int yv, ggi_graphtype type);

Set a graphics mode with a visible area of size x/y and a virtual area of size vx/vy (you can pan aound the virtual area using the SetOrigin command) and the specified graphics type.

Return: 0 for OK, otherwise could not set mode.

int ggiCheckGraphMode(ggi_visual_t visual, int x, int y, int xv,int yv, ggi_graphtype type, ggi_mode *suggested_mode, ...);

Check a graphics mode, with a null-terminated list of mode features. The last argument must be NULL.

Return: A return of 0 means that a setmode call for this mode would succeed. Otherwise, the mode is given cannot be set. In this case, tm is changed to the suggested mode:

If suggested_mode is not NULL, then it will be filled with the suggested mode, as documented under ggiCheckMode(). The ... is reserved for future arguments, but currently there is nothing that may be put between the final NULL and suggested_mode.

Example:


/* Use only my mode... but you really should try to negotiate though */
err = ggiCheckGraphMode(vis, 320, 200, 320, 200, GT_8BIT, NULL, NULL);
if(err)
        return EXIT_FAILURE;

/* OR use a suggested mode */
err = ggiCheckGraphMode(vis, 320, 200, 320, 200, GT_8BIT, &sug_mode, NULL);
ggiSetMode(&sug_mode);

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

int ggiSetGCForeground(ggi_visual_t vis, ggi_pixel color);

Sets the current colors for the foreground, used in all normal graphics functions.

Return: 0 for OK, otherwise an error code.

int ggiSetGCBackground(ggi_visual_t vis, ggi_pixel color);

Sets the current colors for the background, used in some 2-color operations like drawing text.

Return: 0 for OK, otherwise an error code.

int ggiGetGCForeground(ggi_visual_t vis, ggi_pixel * color);

Reads the current foreground color.

Return: 0 for OK, otherwise an error code.

int ggiGetGCBackground(ggi_visual_t vis, ggi_pixel * color);

Reads the current background color.

Return: 0 for OK, otherwise an error code.

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

Please note that palette lookups can be quite expensive (especially for palettized modes) and should thus be avoided e.g. by caching earlier results.

The ggi_color struct has 16 bit wide entries for red (.r), green (.g), and blue (.b) values. Please scale your palette values as necessary.

The ggi_pixel is a hardware-dependent representation of a color. It is usually calculated from a ggi_color by ggiMapColor or read from the visual by ggiGetPixel, and you can safely assume that the relationship between a ggi_color and it's associated ggi_pixel value does not change unless you change the visual or the mode the current visual is in. You can not do calculations with ggi_pixel values. Well, you can, but you should not. The results would be unpredictable and system dependent.

ggi_pixel ggiMapColor(ggi_visual_t vis, ggi_color * col);

Gets the pixelvalue for the given color.

Return: 0 for OK, otherwise an error code.

int ggiUnmapPixel(ggi_visual_t vis, ggi_pixel pixel, ggi_color *col);

Gets the color associated with a given pixelvalue.

Return: 0 for OK, otherwise an error code.

int ggiPackColors(ggi_visual_t vis, void *buf, ggi_color *cols,int len);

Converts the colors in cols to pixelvalues in buf.

Return: 0 for OK, otherwise an error code.

int ggiUnpackPixels(ggi_visual_t vis, void *buf, ggi_color *cols,int len);

Converts pixelvalues in buf to individual elements of cols.

Return: 0 for OK, otherwise an error code.

int ggiSetPaletteVec(ggi_visual_t vis, int s, int len, ggi_color*cmap);

Sets a range of palette values, of length len, starting at index number s.

Return: 0 for OK, otherwise an error code.

int ggiGetPaletteVec(ggi_visual_t vis, int s, int len, ggi_color*cmap);

Gets a range of palette values, of length len, starting at index number s.

Return: 0 for OK, otherwise an error code.

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

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

Draws/Puts/Gets a single pixel at x/y.

Return: 0 for OK, otherwise an error code.

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

Draws/Puts/Gets a horizontal line from x/y, extending w pixels in the positive x direction (normally left).

Return: 0 for OK, otherwise an error code.

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

Draws/Puts/Gets a vertical line from x/y, extending h pixels in the positive y direction (normally down).

Return: 0 for OK, otherwise an error code.

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

Draws/Gets/Puts a filled rectangle at x/y and extending w pixels in the positive x direction and h in the positive y direction.

Return: 0 for OK, otherwise an error code.

The buffers are filled with the x coordinate walking first.

int ggiFillscreen(ggi_visual_t vis);

Fills the entire virtual screen. May be more efficient than the corresponding call to ggiDrawBox().

Return: 0 for OK, otherwise an error code.

int ggiDrawCircle(ggi_visual_t vis, int x, int y, int r);

Draws a circle of given radius r around x/y.

Return: 0 for OK, otherwise an error code.

This will be removed and replaced by a circle routine in libggi2d. It gives already a warning.

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

Draws any line 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: 0 for OK, otherwise an error code.

3.7 Blits

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

This is a screen-to-screen-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 target (e.g. uses HW-accel or intermediate buffers as appropriate).

Return: 0 for OK, otherwise an error code.

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

Blits a rectangular memory area from one visual to another. This is a very complex function as it handles stretching and colorspace-conversion.

Return: 0 for OK, otherwise an error code.

We try hard to optimize this, but avoid using it if possible. And try to keep its work easy. If possible, do not copy between different colorspaces or do any stretching.

This will most probably be removed and replaced by a routine in libggi2d.

3.8 Origin and splitline

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

Set the top-left corner of the displayed area to x/y.

Return: 0 for OK, otherwise an error code.

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

Thus this is commonly used for double-buffering by requesting a double- height virtual screen (i.e. virtual size is double of the visible size), and then drawing on the upper/lower half alternatingly and displaying the currently "steady" buffer (the one which is not drawn to) using SetOrigin().

Example: Pan from the top to the bottom of the virtual screen


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

Note that this call takes dot coordinates, not pixel coordinates as the drawing primitives do. This makes a difference in text mode.

int ggiSetSplitline(ggi_visual_t vis, int y);

Splitline is a feature which originated from the IBM VGA which is able to display the start of the display-memory (i.e. position 0/0) at some arbitrary line. This is a hardware feature but may be emulated by some other targets (e.g. X).

Return: 0 for OK, otherwise an error code.

In other words, splitline is an IBM VGA feature which allows to overlay the lower parts of the screen with the graphics at 0/0. This is nice to e.g. scroll in status lines or the like. It is not guaranteed to work and will return an error code stating this, if it is not supported. Please note, that there are some broken VGA clones which will silently ignore the command.

In emulated splitlines, the image from the point specified by ggiSetOrigin is displayed at the top part of the image before the splitline.

Example:


for (i=vy;i>=0;i--)
{
        ggiSetSplitline(vis,i);
        usleep(10000);
        if (ggiKbhit(vis)) break;
}

Note that this call takes a dot line, not a pixel value as the drawing primitives do. This make a difference in text mode.

3.9 Event handling

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

Check if any of the events given in EvMask is available. Using the struct timeval *t, you can control the action to be taken, if none is available, just as you would do when using select(). Give NULL to wait indefinitely or a filled out struct to wait for a given time (which may be 0 to get non-blocking behaviour).

Return: a mask of events which are available (within the limits set by the mask parameter).

int ggiEventRead(ggi_visual_t vis, ggi_event *ev, ggi_event_maskmask);

Read an Event from the queue. This call blocks, If there is no such Event present.

3.10 Input and Output

LibGGI provides means to do basic graphical input and output. If you need more complex things, use the event interface described in the previous section and the text-rendering functions of a future LibGGI2D extension.

int ggiKbhit(ggi_visual_t vis);

Checks if a key has been hit on the keyboard. This does not consume the key. It is basically for easy porting of old DOS applications.

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

DO NOT poll like this: do while( ! ggiKbhit(vis) );. On a multitasking OS you are wasting ressources which could be available to other processes. If you want to wait for a key, use the ggiGetc() call.

int ggiGetc(ggi_visual_t vis);

Gets a character from the keyboard. Blocks if no key is available.

Return: a 16-bit Unicode character.

As a simple heuristic, you may use 0xff to convert the return code to ISO-Latin-1 for quickly porting an old application. Please do that right later using the K_* symbols.

int ggiPutc(ggi_visual_t vis, int x, int y, char c);

Puts a single character on a graphical visual. This is only a very simple routine using a fixed-width 8x8 font. See the libGGI-2D manual for enhanced font rendering support.

Return: 0 for OK, otherwise an error code.

int ggiPuts(ggi_visual_t vis, int x, int y, const char *str);

Puts multiple characters at once. No special handling is applied to control characters like CR or LF. You will see the associated glyph being displayed, so do this yourself if you need.

Return: 0 for OK, otherwise an error code.

Don't use ggiPutc() repeatedly for multiple characters, as ggiPuts() might be able to optimize the output of muliple chars at once.


Next Previous Contents