#include <ggi/ggi.h> int ggiDBGetNumBuffers(ggi_visual_t vis); const ggi_directbuffer *ggiDBGetBuffer(ggi_visual_t vis, int bufnum);
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.
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 ggiResourceAcquire(3) and 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.
ggiDBGetBuffer returns a pointer to a DirectBuffer structure.
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.
A framebuffer is denoted by ggi_directbuffer.type`==`GGI_DB_NORMAL. Each frame has its own buffer, and its number is indicated in ggi_directbuffer.frame.
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... */