LibGGI Functions ================ Initialize and uninitialize LibGGI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiInit ggiExit Synopsis -------- :: #include <ggi/ggi.h> int ggiInit(void); int ggiExit(void); Description ----------- `ggiInit` initializes the library. This function must be called before using other LibGGI functions; otherwise the results will be undefined. `ggiExit` uninitializes the library (after being initialized by `ggiInit`) and automatically cleans up if necessary. This should be called after an application finished using 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 a :man:`ggi-error(3)` 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 `ggiInit`'s will return `1`. `<0` :man:`ggi-error(3)`, especially if more `ggiExit` calls have been done than `ggiInit` calls. Examples -------- Initialize and uninitialize LibGGI:: if (ggiInit() < 0) { fprintf(stderr, "Cannot initialize LibGGI!\n"); exit(1); } /* Do some LibGGI stuff */ ggiExit(); See Also -------- :man:`ggiOpen(3)` Exit LibGGI programs for fatal errors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiPanic Synopsis -------- :: #include <ggi/ggi.h> void ggiPanic(const char *format, ...); Description ----------- `ggiPanic` shuts down the application, closing all visuals, with :man:`printf(3)`-style reporting to stderr, taking a format string and any additional variables. `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 -------- An unrecoverable error:: if (my_important_struct->magic != MAGIC) { ggiPanic("Fatal error: structure is corrupted\n"); } Open and close a visual ~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiOpen ggiClose Synopsis -------- :: #include <ggi/ggi.h> ggi_visual_t ggiOpen(const char *display, ...); int ggiClose(ggi_visual_t vis); Description ----------- `ggiOpen` opens a visual. The visual is specified as a display string, followed by `NULL`. If only `NULL` is specified, the default display target is opened, which means first examining `GGI_DISPLAY`, then invoking :man:`display-auto(7)`. The other arguments are for internal purposes only, such as :p:`argptr`, used to pass driver-specific, non-textual information to the driver. `ggiClose` releases and destroys an open visual. This will close X windows, return consoles to text-mode, etc. Return value ------------ `ggiOpen` returns the opened visual or `NULL` for error. The `ggi_visual_t` is opaque to the programmer and should only be used through GGI functions. `ggiClose` returns `0` for OK, otherwise a :man:`ggi-error(3)` code. Examples -------- Open and closing default visual:: ggi_visual_t vis = ggiOpen(NULL); if(vis==NULL) { ggiPanic("Couldn't open default visual!\n"); } /* do stuff */ ggiClose(vis); Open and closing a memory visual:: ggi_visual_t memvis = ggiOpen("display-memory", NULL); if(memvis==NULL) { return -1; } /* do stuff */ ggiClose(memvis); See Also -------- :man:`display-auto(7)`, :man:`ggiInit(3)`, :man:`libggi(7)` Check or negotiate a text/graphics mode on a visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiCheckMode ggiCheckTextMode ggiCheckGraphMode ggiCheckSimpleMode Synopsis -------- :: int ggiCheckMode(ggi_visual_t visual, ggi_mode *tm); int ggiCheckTextMode(ggi_visual_t visual, int cols, int rows, int vcols, int vrows, int fontx, int fonty, ggi_graphtype type, ggi_mode *suggested_mode); int ggiCheckGraphMode(ggi_visual_t visual, int x, int y, int xv, int yv, ggi_graphtype type, ggi_mode *suggested_mode); int ggiCheckSimpleMode(ggi_visual_t visual, int xsize, int ysize, int frames, ggi_graphtype type, ggi_mode *md); Description ----------- `ggiCheckMode` checks whether or not the given mode will work on the visual. If it does not work, it will modify the values of passed `ggi_mode` structure so that the mode works. This mode negotiation allows the application to discover modes that are both supported by the visual and suitable to the application. `ggiCheckTextMode` checks whether the text mode with the given visible and virtual dimensions and the font size is supported. `ggiCheckGraphMode` checks whether the graphics mode with the given visible and virtual dimensions and type is supported. `ggiCheckSimpleMode` checks whether the graphics mode with the given visible dimensions, type, and number of buffers is supported. This is used in lieu of `ggiCheckGraphMode` if multiple buffering is desired. For `ggiCheckTextMode`, `ggiCheckGraphMode` and `ggiCheckSimpleMode`, :p:`suggested_mode` is either `NULL` or a pointer to a `ggi_mode` which will be filled in with the negotiated mode parameters. Return value ------------ For `ggiCheckTextMode` and `ggiCheckGraphMode`, a return of `0` means that the corresponding set mode call for this mode would succeed. Otherwise, the mode given cannot be set. In this case, :p:`suggested_mode` is changed to the suggested mode. If the only modifications made to the structure is replacing `GGI_AUTO` or `GT_AUTO` value, the functions return success. Rules for mode negotiation -------------------------- First, if `GGI_AUTO` (or `GT_AUTO` for the graphtype) is specified for any of the members of :p:`tm`, these are filled in with the recommended values. The values could be to a maximum, preferred, or `GGI_DEFMODE` resolution, and will be compatible with any other constraints. An application that does not care about a specific parameter should always specify `GGI_AUTO` or `GT_AUTO` for it. 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. The suggested mode is derived as follows: 1. Resolutions are always adjusted *up*. If you want the next lower, start out at 1x1 (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 satisfied first if possible, then the virtual size. 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. 2. Font sizes are handled the other way round: they are adjusted *down* except when there is nothing below. 3. A specific graphtype is changed 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 graphtype is changed, it is adjusted in ascending order if possible: e.g. 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. Examples -------- Try a 320x200x8 mode:: ggi_mode sug_mode; err = ggiCheckGraphMode(vis, 320, 200, GGI_AUTO, GGI_AUTO, GT_8BIT, &sug_mode); if(err) { /* Check if returned mode is ok... */ } else { ggiSetMode(vis, &sug_mode); } See Also -------- :man:`ggiOpen(3)`, :man:`ggiSetMode(3)`, :man:`ggi_mode(3)` Set or get a mode on a visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiSetMode ggiGetMode Synopsis -------- :: #include <ggi/ggi.h> int ggiSetMode(ggi_visual_t visual, ggi_mode *tm); int ggiGetMode(ggi_visual_t visual, ggi_mode *tm); Description ----------- `ggiSetMode` sets any mode (text or graphics). It also performs mode negotiation like :man:`ggiCheckMode(3)`, but if any non-`GGI_AUTO`/`GT_AUTO` parameters are changed from the original mode, the new mode will not be silently set. `ggiGetMode` fills out the passed `ggi_mode` with the parameters of the current mode of the visual. Return value ------------ `ggiSetMode` returns `0` if the mode is set successfully, otherwise an :man:`ggi-error(3)` code. Notes ----- Do not set a mode before checking it. You may be able to set up a certain mode on one target, but not other targets. See the example in :man:`ggiCheckMode(3)`. .. important:: Note that the :man:`ggiSetTextMode(3)`, :man:`ggiSetGraphMode(3)` and :man:`ggiSetSimpleMode(3)` functions are **deprecated**. Use :man:`ggiCheckMode(3)` and similar functions, and then use :man:`ggiSetMode(3)` on the resulting adjusted :man:`ggi_mode(3)`, once you have checked it yourself. See Also -------- :man:`ggiCheckMode(3)`, :man:`ggiOpen(3)`, :man:`ggi_mode(3)` Set a specific type of mode on a visual [DEPRECATED] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiSetTextMode ggiSetGraphMode ggiSetSimpleMode Synopsis -------- :: #include <ggi/ggi.h> int ggiSetTextMode(ggi_visual_t visual, int cols, int rows, int vcols, int vrows, int fontx, int fonty, ggi_graphtype type); int ggiSetGraphMode(ggi_visual_t visual, int x, int y, int xv, int yv, ggi_graphtype type); int ggiSetSimpleMode(ggi_visual_t visual, int xsize, int ysize, int frames, ggi_graphtype type); Description ----------- .. important:: These functions are DEPRECATED and may be removed from a future version of GGI. `ggiSetTextMode`, `ggiSetGraphMode` and `ggiSetSimpleMode` are convenient versions of `ggiSetMode` that take 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 `ggiSetMode` function, and the same mode-setting semantics apply, except the changed `ggi_mode` cannot be seen. Return value ------------ The functions return `0` if the mode is set successfully, otherwise an :man:`ggi-error(3)` code. Notes ----- Do not set a mode before checking it. You may be able to set up a certain mode on one target, but not other targets. See the example in :man:`ggiCheckMode(3)`. See Also -------- :man:`ggiCheckMode(3)`, :man:`ggiGetMode(3)`, :man:`ggiOpen(3)`, :man:`ggiSetMode(3)`, :man:`ggi_mode(3)` Parse and print formatted strings specifying modes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiParseMode ggiPrintMode ggiSPrintMode ggiFPrintMode Synopsis -------- :: #include <ggi/ggi.h> int ggiParseMode(const char *s, ggi_mode *m); #define ggiPrintMode(m) ggiFPrintMode(stdout,(m)) int ggiSPrintMode(char *s, const ggi_mode *m); int ggiFPrintMode(FILE *s, const 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 :man:`sprintf(3)`, :man:`fprintf(3)` and :man:`printf(3)` respectively. The format of the string used by these functions is exactly the same as the one used in the `GGI_DEFMODE` environment variable described in :man:`libggi(7)`. The string returned by both `ggiSPrintMode` and `ggiFPrintMode` does *not* contain a trailing newline. 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 :p:`m`. So :p:`m` contains all parameters that have been successfully parsed. For most applications there will be no need for testing `ggiParseMode` for failure. See Also -------- :man:`libggi(7)`, :man:`ggi-error(3)` Set or get the current frame for display, writing and reading ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiSetDisplayFrame ggiSetWriteFrame ggiSetReadFrame ggiGetDisplayFrame ggiGetWriteFrame ggiGetReadFrame Synopsis -------- :: #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 :man:`ggiPuts(3)` and :man:`ggiPutHLine(3)`. `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 minus 1. Return value ------------ The `ggiSet*Frame` functions return `0` if they succeed, and an :man:`ggi-error(3)` on failure. The `ggiGet*Frame` functions never fail. Working with frames ------------------- People report about heavy flickering, they can't solve. This is because they display the frame *during* rendering. Unless you know what you do, never set the same frame to write and display mode. Wrong (causes flickering):: ggiSetWriteFrame(vis, framenr); ggiSetDisplayFrame(vis, framenr); /* render here */ Right:: ggiSetWriteFrame(vis, framenr); /* render here */ ggiSetDisplayFrame(vis, framenr); See Also -------- :man:`ggi_mode(3)` Convert from ggi_color(s) to ggi_pixel(s) and vice versa ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiMapColor ggiUnmapPixel ggiPackColors ggiUnpackPixels Synopsis -------- :: #include <ggi/ggi.h> ggi_pixel ggiMapColor(ggi_visual_t vis, const ggi_color *col); int ggiUnmapPixel(ggi_visual_t vis, ggi_pixel pixel, ggi_color *col); int ggiPackColors(ggi_visual_t vis, void *buf, const ggi_color *cols, int len); int ggiUnpackPixels(ggi_visual_t vis, const 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 :p:`cols` to pixelvalues in :p:`buf`. The output from this function is suitable for input to the `ggiPut{HLine,VLine,Box}` functions. `ggiUnpackPixels` converts the pixelvalues in :p:`buf` to individual elements of :p:`cols`. This function may be used to convert buffers output by the `ggiGet{HLine,VLine,Box}` functions from the pixelvalue representation to their actual colors as defined by :man:`ggi_color(3)`. 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 :man:`ggi_pixelformat(3)`. Try to cache the results of color lookups in your application for efficiency purposes. Return value ------------ `ggiMapColor` returns a :man:`ggi_pixel(3)`. `ggiUnmapPixel`, `ggiPackColors` and `ggiUnpackPixels` returns `0` for OK, otherwise a :man:`ggi-error(3)` code. See Also -------- :man:`ggiGetPixelFormat(3)`, :man:`ggi_color(3)`, :man:`ggi_pixelformat(3)` Manipulate the palette of a visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiSetPalette ggiGetPalette Synopsis -------- :: #include <ggi/ggi.h> int ggiSetPalette(ggi_visual_t vis, int s, int len, const ggi_color *cmap); int ggiGetPalette(ggi_visual_t vis, int s, int len, ggi_color *cmap); Description ----------- LibGGI visuals in `GT_PALETTE` mode map all pixelvalues to the corresponding `ggi_color` entry in the visual's palette. `ggiSetPalette` sets a range of palette values of length :p:`len`, starting at index number :p:`s`. The index can be `GGI_PALETTE_DONTCARE` to indicate that the palette can be installed anywhere in the CLUT. This allows optimized use in windowing environments (to minimize color flashing between windows) and should be used if possible. `ggiGetPalette` copies the specified colors (starting from :p:`s`, for :p:`len` colors) from the visual's palette to the array pointed by :p:`cmap`. Return value ------------ `ggiSetPalette` returns the number of the first entry changed. `<0` indicate a :man:`ggi-error(3)`. `ggiGetPalette` returns `0` for OK, otherwise a :man:`ggi-error(3)` code. When called with len=0 this function will not automatically succeed, but the return code will indicate whether there is a readable CLUT. Palette in GGI -------------- Write something useful here. See Also -------- :man:`ggiSetColorfulPalette(3)` Set a palette with a full range of all colors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiSetColorfulPalette Synopsis -------- :: #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, 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. `<0` indicate a :man:`ggi-error(3)`. See Also -------- :man:`ggiSetPalette(3)` Manipulate the gamma maps and the gamma correction of a visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiGetGamma ggiSetGamma ggiGetGammaMap ggiSetGammaMap ggiGammaMax Synopsis -------- :: #include <ggi/ggi.h> int ggiGetGamma(ggi_visual_t vis, ggi_float *r, ggi_float *g, ggi_float *b); int ggiSetGamma(ggi_visual_t vis, ggi_float r, ggi_float g, ggi_float b); int ggiGetGammaMap(ggi_visual_t vis, int s, int len, ggi_color *gammamap); int ggiSetGammaMap(ggi_visual_t vis, int s, int len, const ggi_color *gammamap); int ggiGammaMax(ggi_visual_t vis, uint32_t bitmeaning, int *max_r, int *max_w); Description ----------- Some modes on some hardware can use a per-channel 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. Truecolor modes with gamma maps are sometimes referred to as "directcolor". `ggiSetGammaMap` and `ggiGetGammaMap` set or get the gamma map, for :p:`len` colors starting at :p:`s`. In the event that there are more map entries for some channels than others, values for the upper indices of the map in the shallow channels are ignored on write, and undefined on read. The `ggiGammaMax` function is used in order to find out how many readable and writeable entries are in the map (returned in the integers referenced by :p:`max_w` and :p:`max_r`). This must be done once for each channel. The parameter :p:`bitmeaning` should be set to the bit meaning (e.g. `GGI_BM_TYPE_COLOR` | `GGI_BM_SUB_BLUE`) of the channel of which you are inquiring. If `ggiGammaMax` returns an :man:`ggi-error(3)`, you cannot set the gamma map on this visual. If `ggiGammaMax` succeeds, but :p:`max_w` is -1 on return, this means that `ggiSetGamma` will work, but that `ggiSetGammaMap` will not. `ggiSetGamma` and `ggiGetGamma` sets or gets the gamma correction for the visual according to the usual curve associated with the given values for each channel, which should be positive. Return value ------------ All five functions `0` for OK, otherwise a :man:`ggi-error(3)` code. Get a structure describing the format of a pixelvalue from a visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiGetPixelFormat Synopsis -------- :: #include <ggi/ggi.h> const 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. .. important:: Modifying the structure returned is not allowed. Do **not** attempt to free the pointer returned. See Also -------- :man:`ggiMapColor(3)`, :man:`ggi_pixelformat(3)` Set or get the foreground or background color used in drawing operations in a visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiSetGCForeground ggiGetGCForeground ggiSetGCBackground ggiGetGCBackground Synopsis -------- :: #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. See Also -------- :man:`ggi_pixel(3)` Set or get the clipping rectangle for a visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiSetGCClipping ggiGetGCClipping Synopsis -------- :: #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 (:p:`left`, :p:`top`) - (:p:`right`-1, :p:`bottom`-1), inclusive. Initially the clipping rectangle is the whole virtual screen. All LibGGI drawing primitives obey the clipping rectangle. Negative coordinates given to LibGGI drawing functions will be clipped correctly. `ggiGetGCClipping` reads the coordinates of the current clipping rectangle. Return value ------------ Both functions `0` for OK, ggiSetGCClipping returns a :man:`ggi-error(3)`. Draw, put, and get a single pixel from a visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiDrawPixel ggiPutPixel ggiGetPixel Synopsis -------- :: #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 pixel); int ggiGetPixel(ggi_visual_t vis, int x, int y, ggi_pixel *pixel); Description ----------- Draw, put, or get a single pixelvalue at (:p:`x`, :p:`y`). Return value ------------ All three functions return `0` to indicate success. Draw, put, and get a horizontal line from a visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiDrawHLine ggiPutHLine ggiGetHLine Synopsis -------- :: #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, const 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 (:p:`x`, :p:`y`), extending :p:`w` pixels in the positive x direction (normally right). The height is one pixel. The :p:`buf` parameter in Get/Put functions points to a buffer from which the pixels will be read, or to which they will be written (it must be correctly allocated), respectively. See :man:`ggiPackColors(3)` and :man:`ggiUnmapPixel(3)` functions for details on how to deal with pixels. Return value ------------ All three functions return `0` to indicate success. See Also -------- :man:`ggiDrawBox(3)`, :man:`ggiDrawLine(3)`, :man:`ggiDrawVLine(3)`, :man:`ggiMapColor(3)`, :man:`ggi_pixelformat(3)` Draw, put, and get a vertical line from a visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiDrawVLine ggiPutVLine ggiGetVLine Synopsis -------- :: #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, const 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 (:p:`x`, :p:`y`), extending :p:`h` pixels in the positive y direction (normally down). The width of the line is one pixel. The :p:`buf` parameter in Get/Put functions points to a buffer from which the pixels will be read, or to which they will be written (it must be correctly allocated), respectively. See :man:`ggiPackColors(3)` and :man:`ggiUnmapPixel(3)` functions for details on how to deal with pixels. Return value ------------ All three functions return `0` to indicate success. See Also -------- :man:`ggiDrawBox(3)`, :man:`ggiDrawHLine(3)`, :man:`ggiDrawLine(3)`, :man:`ggiMapColor(3)`, :man:`ggi_pixelformat(3)` Draw, put, and get a rectangle from a visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiDrawBox ggiPutBox ggiGetBox Synopsis -------- :: #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, const 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 (:p:`x`, :p:`y`), extending :p:`w` pixels in the positive x direction and :p:`h` pixels in the positive y direction. The :p:`buf` parameter in Get/Put functions points to a buffer from which the pixels will be read, or to which they will be written (it must be correctly allocated), respectively. See :man:`ggiPackColors(3)` and :man:`ggiUnmapPixel(3)` functions for details on how to deal with pixels. Return value ------------ All three functions return `0` to indicate success. See Also -------- :man:`ggiDrawHLine(3)`, :man:`ggiDrawLine(3)`, :man:`ggiDrawVLine(3)`, :man:`ggiMapColor(3)`, :man:`ggi_pixelformat(3)` Fill the entire virtual screen ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiFillscreen Synopsis -------- :: #include <ggi/ggi.h> int ggiFillscreen(ggi_visual_t vis); Description ----------- Fills the current clipping rectangle (usually the entire virtual screen) with the current foreground color. It may be more efficient than the corresponding call to :man:`ggiDrawBox(3)`. To set a clipping rectangle, see :man:`ggiSetGCClipping(3)`. Return value ------------ This function returns `0` to indicate success. Draw a line on a visual ~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiDrawLine Synopsis -------- :: #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 set by :man:`ggiSetGCForeground(3)`, from (:p:`x`, :p:`y`) to (:p:`xe`, :p:`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. See Also -------- :man:`ggiDrawHLine(3)`, :man:`ggiDrawVLine(3)` Copy a rectangular area ~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiCopyBox Synopsis -------- :: #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 :p:`x`, :p:`y`, :p:`w`, :p:`h` to the new location :p:`nx`, :p:`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 a :man:`ggi-error(3)` code. See Also -------- :man:`ggiCrossBlit(3)` Copy a rectangular area between two visuals ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiCrossBlit Synopsis -------- :: #include <ggi/ggi.h> int ggiCrossBlit(ggi_visual_t src, int sx, int sy, int w, int h, ggi_visual_t 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 a :man:`ggi-error(3)` code. See Also -------- :man:`ggiCopyBox(3)`, :man:`ggiSetReadFrame(3)`, :man:`ggiSetWriteFrame(3)` Set and get origin of virtual screen ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiSetOrigin ggiGetOrigin Synopsis -------- :: #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 (:p:`x`, :p:`y`). When using a larger virtual area, you can pan the visible area over the virtual one to do scrolling. Some targets have extremely 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 (see :man:`ggi_mode(3)`), not pixel coordinates as all other drawing primitives do. There is no difference in graphic modes because by definition *dpp* is 1x1, but in text modes the application can do smooth scrolling. When `ggiSetOrigin` returns, the screen reflects the new origin. It is not necessary to call ggiFlush. `ggiGetOrigin` gets the current top-left corner of the displayed area into (:p:`x`, :p:`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 a :man:`ggi-error(3)` code. 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); } Draw one or more characters on visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiPutc ggiPuts ggiGetCharSize Synopsis -------- :: #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 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 (from 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 correctly position the text output. Character size must always be checked and application should not assume that it will be constant across targets or even modes. Visuals must have a mode set before querying the character size. It means that if you want to use a visual size which depends on the character size, you might have to iterate over :man:`ggiSetMode(3)` and `ggiGetCharSize` to get it right. .. note:: The values returned by `ggiGetCharSize` is not the same as the values of `dpp` of the current 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 success. Set or get flags affecting operation on a visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiSetFlags ggiGetFlags ggiAddFlags ggiRemoveFlags Synopsis -------- :: #include <ggi/ggi.h> int ggiSetFlags(ggi_visual_t vis, ggi_flags flags); ggi_flags ggiGetFlags(ggi_visual_t vis); #define ggiAddFlags(vis,flags) \ ggiSetFlags((vis), ggiGetFlags((vis)) | (flags)) #define ggiRemoveFlags(vis,flags) \ ggiSetFlags((vis), ggiGetFlags((vis)) & ~(flags)) Description ----------- `ggiSetFlags` sets the specified flags (bitwise OR'd together) on a visual. `ggiGetFlags` obtains the flags currently in effect. `ggiAddFlags` and `ggiRemoveFlags` are macros that set or unset the specified flags. Flags are used to alter a visual's underlying behavior. All flags default to an unset value. Flags which are not supported by a given visual will remain unset even when an attempt is made to raise them. Thus, it is possible to tell by reading back the flags whether or not each of the flags is supported by the given visual. .. note:: It is recommended to set the flags *before* setting a mode, i.e. right after :man:`ggiOpen(3)`. Return Value ------------ `ggiSetFlags`, `ggiAddFlags`, and `ggiRemoveFlags` return `0` on success, a :man:`ggi-error(3)` code on failure. This will only happen if the failure of a target to support the addition or removal of a flag will cause the target to behave in a way that the application is not expecting. As of this writing there are no such cases. On visuals where certain flags are unsupported but are inconsequential, these functions will return a successful return code, but will not actually set or clear the flag. `ggiGetFlags` returns the current flags. This can be used by the curious to check whether a flag is being silently ignored as per above. 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 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, attempting to set it has no effect. Code written for asynchronous visuals will always perform correctly on synchronous visuals (but not vice-versa), so it is not necessary to adapt a program's behavior if this flag is not available. To make sure that all pending graphics operations are actually done and the screen is updated, you need to call :man:`ggiFlush(3)`. This call is not needed in synchronous mode. .. important:: On some targets such as the X target there is no real synchronous mode, so LibGGI fakes one by periodically calling :man:`ggiFlush(3)` in the background. This process can take about half the execution time of a program. So using synchronous mode can *really* slow things down. However, the synchronous mode is the default, because it is what most programmers expect. In either mode, all operations are guaranteed to be performed in the order in which they are called. Reordering is not done. GGI guarantees that the effects of drawing operations on the final state of the buffer are consistant with the order in which they were invoked, but as to what order the operations visibly appear during a flush, that is entirely up to the target. You could draw a red square with the GPU (through the target), and then draw a green square inside it via software -- you will always end up with a red square inside a green square, but the user may see the red square appear first. When it comes to directbuffer, though, that is the problem that the TIDYBUF flag is meant to fix. Or at least, the TIDYBUF flag fixes a problem with the way GGI fixes the serialization problem. The display is flushed entirely before the acquire completes, and then the db is flushed entirely before the db is released, so that is serialized. The TIDYBUF stuff lets you bypass this serialization for efficiency. 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. 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 */ Tidy buffer mode ---------------- Some visuals allow applications to manage their own dirty regions when using the directbuffer. - In the default dirty-buffering mode, visuals which use backbuffers to render to a display system will refresh the entire screen when the resource lock is held and then released for the write frame's directbuffer. This happens in both async and sync modes. In syncronous modes this full-screen refresh may be performed at regular intervals. This can be very inefficient, but it guarantees that naive applications will be rendered correctly even though they were not written with a backbuffered display in mind. These visuals may also perform dirty-region tracking, such that if the directbuffer is used, altered data may never reach the screen until the lock is released, because the visual does not know that a certain area of the backbuffer contains new (dirty) data. Even explicitly calling :man:`ggiFlushRegion(3)` on the affected area may not cause the data to be sent to the screen. - In tidy-buffering mode, which is set by raising the flag GGIFLAG_TIDYBUF, visuals do not synchronize the screen at all when the write frame's directbuffer lock is held or upon its release. However, in this mode, :man:`ggiFlushRegion(3)` will always cause the requested region of the screen to be updated. Note that this means that, as long as the lock is held, affected regions may also have to be flushed (and thus, should be flushed) after normal drawing primitives are called. Before releasing the lock, applications should be sure to flush all affected regions, because the visual may revert to its default dirty-region management behavior after the lock is released. Do note, also, that in multi-frame displays `ggiFlushRegion` affects only the current write frame, so even though it is possible to use a directbuffer to alter a different frame, you must call :man:`ggiSetWriteFrame(3)` to tell the visual that you will be altering the frame. The GGIFLAG_TIDYBUF flag is not available on all visuals, but it is safe to attempt to set it whether or not it is available. Code written for the tidy-buffering mode will display correctly on visuals which do not have a tidy-buffering mode (but not vice-versa), so it is not necessary to adapt program behavior to its non-presence. It is recommended that, if an application must use directbuffer, the application should attempt to place the visual in tidy-buffered mode. Do note, though, that many applications that use the directbuffer do not actually need to do so and probably should not, as it reduces portability. See Also -------- :man:`ggiFlush(3)`, :man:`ggiFlushRegion(3)` Flush pending output ~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiFlush ggiFlushRegion Synopsis -------- :: #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 -------- :man:`ggiSetFlags(3)` Acquire and release a LibGGI resource ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiResourceAcquire ggiResourceRelease ggiResourceMustAcquire Synopsis -------- :: #include <ggi/ggi.h> int ggiResourceAcquire(ggi_resource_t res, uint32_t 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 :p:`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, an :man:`ggi-error(3)` code 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 -------- 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); See Also -------- :man:`ggi_directbuffer(3)` Get DirectBuffers from a visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiDBGetNumBuffers ggiDBGetBuffer Synopsis -------- :: #include <ggi/ggi.h> int ggiDBGetNumBuffers(ggi_visual_t vis); const ggi_directbuffer *ggiDBGetBuffer(ggi_visual_t vis, int bufnum); Description ----------- 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. `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` is true need to be 'acquired' (i.e. locked) before using. An acquire is done by using `ggiResourceAcquire` and is released by calling `ggiResourceRelease`. 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. Types of Buffers ---------------- Only the framebuffer is defined currently. Other types of buffers, such as stencil, z will be defined by appropriate GGI extensions. 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`. 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... */ See Also -------- :man:`ggi_directbuffer(3)`, :man:`ggiResourceAcquire(3)` Event management for LibGGI visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiJoinInputs ggiEventPoll ggiEventSelect ggiEventsQueued ggiEventRead ggiSetEventMask ggiGetEventMask ggiAddEventMask ggiRemoveEventMask Synopsis -------- :: #include <ggi/ggi.h> 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 ggiSetEventMask(ggi_visual_t vis, gii_event_mask evm); gii_event_mask ggiGetEventMask(ggi_visual_t vis); gii_input_t ggiJoinInputs(ggi_visual_t vis, gii_input_t inp); #define ggiAddEventMask(vis,mask) \ ggiSetEventMask((vis), ggiGetEventMask((vis)) | (mask)) #define ggiRemoveEventMask(vis,mask) \ ggiSetEventMask((vis), ggiGetEventMask((vis)) & ~(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 versions provided of most LibGII functions simply take a `ggi_visual_t` rather than `gii_input_t` for convenience during everyday usage. Events are LibGII types. All other semantics are the same; see :man:`libgii(7)` for details. .. important:: By default LibGGI visuals autodetect and open the appropriate inputs, including mouse and keyboard and any other inputs that are 'intrinsic' to the visual e.g. any registered X11 input device under the X target. 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 *must* be used to do event handling with LibGGI visuals, and provide adequate support for most everyday, single-visual usage. Advanced management of input sources is accomplished by detaching the input from the visual and using LibGII functions on the separate visual handle (see :man:`ggiDetachInput(3)`). This is encouraged, for example, when joining inputs from multiple visuals, because when two visuals share the same joined input, you cannot ggiClose both of the visuals (a fatal error will result, because closing the first visual closes both of the joined inputs and leaves the second closed visual with a stale input handle.) Return value ------------ See return values of :man:`giiJoinInputs(3)`, :man:`giiEventPoll(3)`, :man:`giiEventSelect(3)`, :man:`giiEventsQueued(3)`, :man:`giiEventRead(3)`, :man:`giiSetEventMask(3)`, :man:`giiGetEventMask(3)`, :man:`giiAddEventMask(3)`, :man:`giiRemoveEventMask(3)` See Also -------- :man:`ggiGetInput(3)`, :man:`giiEventPoll(3)`, :man:`giiSetEventMask(3)` Functions to translate from GGI visuals to GII input ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiGetInput ggiDetachInput Synopsis -------- :: #include <ggi/ggi.h> #define ggiGetInput(vis) ggiJoinInputs(vis, NULL) gii_input_t ggiDetachInput(ggi_visual_t vis); Description ----------- `ggiGetInput` returns the underlying input-handle associated with a LibGGI visual, for use with the LibGII API. `ggiDetachInput` also returns the underlying input-handle, but in addition, it breaks the association between the given visual and that input handle. After this has been done, no LibGGI event routines may be called on that visual handle, and when the visual handle is closed, the input will remain unaffected. See Also -------- :man:`ggiJoinInputs(3)`, :man:`giiOpen(3)` Send commands and events to a LibGGI visual ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiEventSend Synopsis -------- :: #include <ggi/ggi.h> int ggiEventSend(ggi_visual_t vis, gii_event *ev); Description ----------- `ggiEventSend` injects an event into the queue. Controlling VT switching behavior --------------------------------- If an application wants to continue running after its VT is switched away, it should make a call `ggiEventSend` to the visual with an `evCommand` event with code `GGICMD_NOHALT_ON_UNMAP`. To disable this behavior, use a command event with code `GGICMD_HALT_ON_UNMAP`. The latter is the default. See Also -------- :man:`ggiEventPoll(3)`, :man:`giiEventSend(3)` Convenience functions for simplistic keyboard input ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. manpage:: 3 ggiGetc ggiKbhit Synopsis -------- :: #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 more detailed definition of characters, see :man:`gii_key_event(3)`. See Also -------- :man:`ggiEventPoll(3)`