LibGGI API Manual LibGGI 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. General To 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 control ggiInit 3ggi GGI ggiInit ggiExit Initialize and uninitialize LibGGI #include <ggi/ggi.h> int int Description Return value after successfully cleaning up, the number of 'open' error, especially if more Examples Initialize and uninitialize LibGGI if (ggiInit() != 0) { exit(1); /* can't start! */ } /* Do some LibGGI stuff */ ggiExit(); ggiPanic 3ggi GGI ggiPanic Exit 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 value Never returns. Examples An 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 ggiOpen 3ggi GGI ggiOpen ggiClose Open and close a visual #include <ggi/ggi.h> ggi_visual_t const char * int ggi_visual_t Description The other arguments are for internal purposes only, such as Return value Examples Open 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 Also 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 <StructName/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. 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 <Type/ggi_graphtype/ 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. <Symbol/GGI_AUTO/ 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. Functions ggiSetMode 3ggi GGI ggiSetMode ggiCheckMode ggiGetMode Set, 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 Also ggiSetGraphMode 3ggi GGI ggiSetTextMode ggiCheckTextMode ggiSetGraphMode ggiCheckGraphMode ggiSetSimpleMode ggiCheckSimpleMode Set 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 Examples 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 3ggi GGI ggiParseMode ggiPrintMode ggiSPrintMode ggiFPrintMode Operate 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 value on 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 Also Frame management ggiSetDisplayFrame 3ggi GGI ggiSetDisplayFrame ggiSetWriteFrame ggiSetReadFrame ggiGetDisplayFrame ggiGetWriteFrame ggiGetReadFrame Set 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 Description These 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 value The <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 types ggi_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 functions ggiMapColor 3ggi GGI ggiMapColor ggiUnmapPixel ggiPackColors ggiUnpackPixels Convert 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 value ggiSetPalette 3ggi GGI ggiSetPalette ggiGetPalette Manipulate the palette of a visual #include <ggi/ggi.h> int ggi_visual_t int ggi_visual_t Description LibGGI visuals in Return value See Also ggiSetColorfulPalette 3ggiGGI ggiSetColorfulPalette Set 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 value See Also ggiSetGamma 3ggi GGI ggiSetGammaMap ggiGetGammaMap ggiSetGamma ggiGetGamma Manipulate 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 value All four functions ggi_pixelformat ggiGetPixelFormat 3ggi GGI ggiGetPixelFormat Get a structure describing the format of a pixelvalue from a visual #include <ggi/ggi.h> ggi_pixelformat * ggi_visual_t Description This function obtains the default pixel format for the given visual. Return value Returns 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. ggiSetGCForeground 3ggi GGI ggiSetGCForeground ggiGetGCForeground ggiSetGCBackground ggiGetGCBackground Set 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 Description Return value All four functions ggiSetGCClipping 3ggi GGI ggiSetGCClipping ggiGetGCClipping Set or get the clipping rectangle for a visual #include <ggi/ggi.h> int ggi_visual_t int ggi_visual_t Description Initially the clipping rectangle is the whole virtual screen. All LibGGI drawing primitives obey the clipping rectangle. Return value Both 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? ggiDrawPixel 3ggi GGI ggiDrawPixel ggiPutPixel ggiGetPixel Draw, 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 value All three functions return ggiDrawHLine 3ggi GGI ggiDrawHLine ggiPutHLine ggiGetHLine Draw, 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 value All three functions return See Also ggiDrawVLine 3ggi GGI ggiDrawVLine ggiPutVLine ggiGetVLine Draw, 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 value All three functions return See Also ggiDrawBox 3ggi GGI ggiDrawBox ggiPutBox ggiGetBox Draw, 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 value All three functions return See Also ggiFillscreen 3ggi GGI ggiFillscreen Fills 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 value This function returns ggiDrawLine 3ggi GGI ggiDrawLine Draw a line on a visual #include <ggi/ggi.h> int ggi_visual_t Description Draws any line, using the current foreground color, from ( Return value This function returns See Also 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: 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 DirectBuffers ggiDBGetBuffer 3ggi GGI ggiDBGetNumBuffers ggiDBGetBuffer Get 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 value Examples 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.... */ Miscellaneous functions ggiResourceAcquire 3ggi GGI ggiResourceAcquire ggiResourceRelease ggiResourceMustAcquire Acquire and release a LibGGI resource #include <ggi/ggi.h> int ggi_resource_t int ggi_resource_t int ggi_resource_t Description read access to the resource write access to the resource Return Value <0 on failure. Examples 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 3ggi GGI ggiSetFlags ggiGetFlags ggiAddFlags ggiRemoveFlags Set 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 Description Return 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 Also ggiFlush 3ggi GGI ggiFlush ggiFlushRegion Flush pending output #include <ggi/ggi.h> int ggi_visual_t int ggi_visual_t Description These functions are not needed if the visual is in synchronous mode. Return Value No meaningful return value. See Also Blits ggiCopyBox 3ggi GGI ggiCopyBox Copy 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 value See Also ggiCrossBlit 3ggi GGI ggiCrossBlit Copy 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 value See Also Origin ggiSetOrigin 3ggi GGI ggiSetOrigin ggiGetOrigin Set and get origin of virtual screen #include <ggi/ggi.h> int ggiSetOrigin ggi_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 value Examples Pan from the top to the bottom of the virtual screen for(i = 0; i < virt_y-visible_y; i++) { ggiSetOrigin(vis, 0, i); } Character Output ggiPutc 3ggi GGI ggiPutc ggiPuts Draw 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 value Event handling ggiEventPoll 3ggi GGI ggiJoinInputs ggiEventPoll ggiEventsQueued ggiEventRead ggiEventSend ggiSetEventMask ggiGetEventMask ggiAddEventMask ggiRemoveEventMask #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 Also ggiGetc 3ggi GGI ggiGetc ggiKbhit Convenience functions for simplistic keyboard input #include <ggi/ggi.h> int ggiGetc ggi_visual_t int ggi_visual_t Description Return value For a fuller definition of characters, please consult ggi/keyboard.h and the