
/* ggi.q: a portable graphics interface
   $Id: ggi.q,v 1.12 2006/01/25 05:50:34 agraef Exp $ */

/* This file is part of the Q programming system.

   The Q programming system is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   The Q programming system is distributed in the hope that it will be
   useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

/* This module implements an interface to the GGI portable graphics library
   (http://www.ggi-project.org/). Not all features of GGI are implemented at
   this time, but we provide the necessary operations to open a visual,
   configure its display mode and other parameters, and perform basic graphics
   operations and event handling. Support for the GGI buffer extension is also
   provided. */

import clib;

/* Manifest constants. ******************************************************/

/* The following values, bitwise or'ed together, are used as flag values in
   the ggi_set_flags and ggi_get_flags operations. See ggiSetFlags(3) for an
   explanation of these values. */

public var const GGI_FLAG_ASYNC;

/* The following values describe various types of events and event masks. See
   gii_event(3) for a description of these. */

public var const GGI_EV_NOTHING, GGI_EV_COMMAND, GGI_EV_INFORMATION,
  GGI_EV_EXPOSE, GGI_EV_KEYPRESS, GGI_EV_KEYRELEASE, GGI_EV_KEYREPEAT,
  GGI_EV_PTRRELATIVE, GGI_EV_PTRABSOLUTE, GGI_EV_PTRBUTTONPRESS,
  GGI_EV_PTRBUTTONRELEASE, GGI_EV_VALRELATIVE, GGI_EV_VALABSOLUTE;

public var const GGI_EM_COMMAND, GGI_EM_INFORMATION, GGI_EM_EXPOSE,
  GGI_EM_KEYPRESS, GGI_EM_KEYRELEASE, GGI_EM_KEYREPEAT, GGI_EM_KEY,
  GGI_EM_PTRRELATIVE, GGI_EM_PTRABSOLUTE, GGI_EM_PTRBUTTONPRESS,
  GGI_EM_PTRBUTTONRELEASE, GGI_EM_PTRMOVE, GGI_EM_PTRBUTTON, GGI_EM_POINTER,
  GGI_EM_VALRELATIVE, GGI_EM_VALABSOLUTE, GGI_EM_VALUATOR,
  GGI_EM_ALL, GGI_EM_NOTHING;

/* Special event origin and target indicators. */

public var const GGI_EV_ORIGIN_NONE, GGI_EV_ORIGIN_SENDEVENT,
  GGI_EV_TARGET_QUEUE, GGI_EV_TARGET_ALL;

/* Modifiers for key events, see gii_key_event(3). */

public var const GGI_MOD_SHIFT, GGI_MOD_CTRL, GGI_MOD_ALT, GGI_MOD_META,
  GGI_MOD_SUPER, GGI_MOD_HYPER, GGI_MOD_ALTGR, GGI_MOD_CAPS, GGI_MOD_NUM,
  GGI_MOD_SCROLL;

/* Mouse button values for pointer events. */

public var const GGI_PBUTTON_LEFT, GGI_PBUTTON_MIDDLE, GGI_PBUTTON_RIGHT;

/* Known command codes and flags in command events. */

public var const GGI_CMDCODE_EVENTLOST, GGI_CMDCODE_PREFER_ABSPTR,
  GGI_CMDCODE_PREFER_RELPTR, GGI_CMDCODE_GETDEVINFO, GGI_CMDCODE_GETVALINFO,
  GGI_CMDFLAG_NODATA, GGI_CMDFLAG_PRIVATE, GGI_CMDFLAG_EXTERNAL;

/* Valuator types. */

public var const
  GGI_PT_UNKNOWN,		/* unknown */
  GGI_PT_TIME,			/* base unit s (second) */
  GGI_PT_FREQUENCY,		/* base unit 1/s (Hz) */
  GGI_PT_LENGTH,		/* base unit m (meter) */
  GGI_PT_VELOCITY,		/* base unit m/s */
  GGI_PT_ACCELERATION,		/* base unit m/s^2 */
  GGI_PT_ANGLE,			/* base unit radian */
  GGI_PT_ANGVELOCITY,		/* base unit radian/s */
  GGI_PT_ANGACCELERATION,	/* base unit radian/s^2 */
  GGI_PT_AREA,			/* base unit m^2 */
  GGI_PT_VOLUME,		/* base unit m^3 */
  GGI_PT_MASS,			/* base unit kg */
  GGI_PT_FORCE,			/* base unit N (kg*m/s^2) */
  GGI_PT_PRESSURE,		/* base unit N/m^2 (Pa) */
  GGI_PT_TORQUE,		/* base unit Nm */
  GGI_PT_ENERGY,		/* base unit Nm, VAs, J */
  GGI_PT_POWER,			/* base unit Nm/s, VA, W */
  GGI_PT_TEMPERATURE,		/* base unit K */
  GGI_PT_CURRENT,		/* base unit A */
  GGI_PT_VOLTAGE,		/* base unit V (kg*m^2/(As^3)) */
  GGI_PT_RESISTANCE,		/* base unit V/A (Ohm) */
  GGI_PT_CAPACITY,		/* base unit As/V (Farad) */
  GGI_PT_INDUCTIVITY;		/* base unit Vs/A (Henry) */

/* The following FreeType2 flag values describe various font properties. These
   values, bitwise or'ed together, are returned by ggi_get_font_info in the
   FACE_FLAGS and STYLE_FLAGS fields of a font info structure.  */

public var const
  FT_FACE_FLAG_SCALABLE,
  FT_FACE_FLAG_FIXED_SIZES,
  FT_FACE_FLAG_FIXED_WIDTH,
  FT_FACE_FLAG_SFNT,
  FT_FACE_FLAG_HORIZONTAL,
  FT_FACE_FLAG_VERTICAL,
  FT_FACE_FLAG_KERNING,
  FT_FACE_FLAG_FAST_GLYPHS,
  FT_FACE_FLAG_MULTIPLE_MASTERS,
  FT_FACE_FLAG_GLYPH_NAMES,
  FT_FACE_FLAG_EXTERNAL_STREAM,
  FT_STYLE_FLAG_ITALIC,
  FT_STYLE_FLAG_BOLD;

private extern ggi_vars;

def (/* visual flags */
     GGI_FLAG_ASYNC,
     /* events */
     GGI_EV_NOTHING, GGI_EV_COMMAND, GGI_EV_INFORMATION,
     GGI_EV_EXPOSE, GGI_EV_KEYPRESS, GGI_EV_KEYRELEASE, GGI_EV_KEYREPEAT,
     GGI_EV_PTRRELATIVE, GGI_EV_PTRABSOLUTE, GGI_EV_PTRBUTTONPRESS,
     GGI_EV_PTRBUTTONRELEASE, GGI_EV_VALRELATIVE, GGI_EV_VALABSOLUTE,
     /* event masks */
     GGI_EM_COMMAND, GGI_EM_INFORMATION, GGI_EM_EXPOSE,
     GGI_EM_KEYPRESS, GGI_EM_KEYRELEASE, GGI_EM_KEYREPEAT, GGI_EM_KEY,
     GGI_EM_PTRRELATIVE, GGI_EM_PTRABSOLUTE, GGI_EM_PTRBUTTONPRESS,
     GGI_EM_PTRBUTTONRELEASE, GGI_EM_PTRMOVE, GGI_EM_PTRBUTTON, GGI_EM_POINTER,
     GGI_EM_VALRELATIVE, GGI_EM_VALABSOLUTE, GGI_EM_VALUATOR,
     GGI_EM_ALL, GGI_EM_NOTHING,
     /* special event origins and targets */
     GGI_EV_ORIGIN_NONE, GGI_EV_ORIGIN_SENDEVENT,
     GGI_EV_TARGET_QUEUE, GGI_EV_TARGET_ALL,
     /* modifiers */
     GGI_MOD_SHIFT, GGI_MOD_CTRL, GGI_MOD_ALT, GGI_MOD_META,
     GGI_MOD_SUPER, GGI_MOD_HYPER, GGI_MOD_ALTGR, GGI_MOD_CAPS, GGI_MOD_NUM,
     GGI_MOD_SCROLL,
     /* mouse buttons */
     GGI_PBUTTON_LEFT, GGI_PBUTTON_MIDDLE, GGI_PBUTTON_RIGHT,
     /* command codes and flags */
     GGI_CMDCODE_EVENTLOST, GGI_CMDCODE_PREFER_ABSPTR,
     GGI_CMDCODE_PREFER_RELPTR, GGI_CMDCODE_GETDEVINFO, GGI_CMDCODE_GETVALINFO,
     GGI_CMDFLAG_NODATA, GGI_CMDFLAG_PRIVATE, GGI_CMDFLAG_EXTERNAL,
     /* valuator types */
     GGI_PT_UNKNOWN, GGI_PT_TIME, GGI_PT_FREQUENCY, GGI_PT_LENGTH,
     GGI_PT_VELOCITY, GGI_PT_ACCELERATION, GGI_PT_ANGLE, GGI_PT_ANGVELOCITY,
     GGI_PT_ANGACCELERATION, GGI_PT_AREA, GGI_PT_VOLUME, GGI_PT_MASS,
     GGI_PT_FORCE, GGI_PT_PRESSURE, GGI_PT_TORQUE, GGI_PT_ENERGY,
     GGI_PT_POWER, GGI_PT_TEMPERATURE, GGI_PT_CURRENT, GGI_PT_VOLTAGE,
     GGI_PT_RESISTANCE, GGI_PT_CAPACITY, GGI_PT_INDUCTIVITY,
     /* font properties */
     FT_FACE_FLAG_SCALABLE, FT_FACE_FLAG_FIXED_SIZES,
     FT_FACE_FLAG_FIXED_WIDTH, FT_FACE_FLAG_SFNT,
     FT_FACE_FLAG_HORIZONTAL, FT_FACE_FLAG_VERTICAL,
     FT_FACE_FLAG_KERNING, FT_FACE_FLAG_FAST_GLYPHS,
     FT_FACE_FLAG_MULTIPLE_MASTERS, FT_FACE_FLAG_GLYPH_NAMES,
     FT_FACE_FLAG_EXTERNAL_STREAM, FT_STYLE_FLAG_ITALIC,
     FT_STYLE_FLAG_BOLD
    ) = ggi_vars;

/* Visuals. *****************************************************************/

/* Visuals are GGI's abstraction of graphics I/O devices. They allow you to
   access, in a portable and transparent manner, different kinds of graphics
   screens and corresponding input devices like mouse and keyboard. In order
   to employ a graphics device, you first have to open a visual and then
   establish its display mode. */

/* The visual type. Visuals are created with ggi_open and closed automatically
   when garbage-collected, or explicitly with the ggi_close function. This
   type provides handles to GGI visual objects which are used with the
   remaining operations of this module. In the following, visual parameters
   are always denoted VIS. */

public extern type GGIVisual;

/* Open and close a visual. For ggi_open, the DPY argument is a string in the
   same format as the GGI_DISPLAY variable, see libggi(7). It can also be (),
   in which case the default display is used. After a visual is closed with
   ggi_close, all subsequent operations on it will fail. */

public extern ggi_open DPY, ggi_close VIS;

/* Check, set and get the display mode of a visual. The mode must be set
   before the visual can be used for any graphics operations. Mode values are
   specified as strings in the same format as the GGI_DEFMODE environment
   variable, see libggi(7). A typical mode string looks like

	"1152x921.V1152x921.F1.D1x1.[C24/32]"

   specifying, respectively, the real dimensions (1152x921), the virtual
   dimensions (same as real dimensions in this example, must always be >= the
   real size), the number of frames (1 in the example; can be >1 to provide
   for multiple buffers, but only for certain devices), the pixel size (1x1
   for graphic modes, can also be WxH to denote the size of a character cell
   in text modes), and the colorspace (C=truecolor, color depth 24, pixel size
   32 in this example; other supported color schemes are P=palette,
   K=greyscale and T=text).

   The mode string can also specify an alpha buffer which is to be attached to
   the visual. E.g.:

	"1152x921.V1152x921.F1.D1x1.[C24/32].A8"

   This means that the visual will be "clad" with an alpha buffer of the
   requested bit depth (8 in this example), and subsequent graphics operations
   will transparently perform alpha blending when pixels are written to the
   visual. This is useful for handling graphics involving transparent or
   translucent pixels. Please note that in the current implementation only the
   depths 0, 8 and 16 are supported. Also note that since this a Q-GGI
   specific extension, the .A mode cannot be used in the GGI_DEFMODE
   environment variable.

   If the MODE argument of ggi_check_mode or ggi_set_mode is () then the
   default mode is used. The ggi_check_mode function can be used to negotiate
   a graphics mode; it modifies the given mode as necessary to be compatible
   with the given visual. The ggi_set_mode function sets the given mode for
   the given visual, if possible. The ggi_get_mode function returns the
   current mode of the given visual. */

public extern ggi_check_mode VIS MODE, ggi_set_mode VIS MODE,
  ggi_get_mode VIS;

/* Set and get flag values of a visual; see ggiSetFlags(3). */

public extern ggi_set_flags VIS FLAGS, ggi_get_flags VIS;

/* Set and get the display/read/write frames of a visual. The argument N is
   the frame number. These settings affect the source and destination of some
   of the graphics operations below. They are useful if multiple frames have
   been set with ggi_set_mode, in order to implement double or triple
   buffering. */

public extern ggi_set_display_frame VIS N, ggi_set_read_frame VIS N,
  ggi_set_write_frame VIS N;
public extern ggi_get_display_frame VIS, ggi_get_read_frame VIS,
  ggi_get_write_frame VIS;

/* Set and get the current clip area and the origin of the virtual screen. The
   clip area is given as a rectangle R = (X1,Y1,X2,Y2), where (X1,Y1) denotes
   the top-left corner *inside* the clip area, and (X2,Y2) is the bottom-right
   corner *outside* the clip area. The origin of the virtual screen is given
   by a point P = (X,Y) which denotes the top-left corner of the real inside
   the virtual display. */

public extern ggi_set_clip VIS R, ggi_get_clip VIS;
public extern ggi_set_orig VIS P, ggi_get_orig VIS;

/* Colors and pixels. No matter what the actual internal pixel encoding of a
   visual looks like, the operations of this module always represent pixels as
   byte strings of normalized 16 bit RGBA values. (This corresponds to what
   GGI itself uses as its device-independent, "unpacked" pixel representation
   embodied by the ggi_color type.) The ggi_pixel function can be used to
   convert an (R,G,B,A) tuple of 16 bit values into the corresponding byte
   string, or pack a list of such values into a single byte string. (The alpha
   component A can also be omitted, in which case the default 0xffff is used,
   which denotes a fully opaque pixel. Also note that the alpha value will
   only have an effect on visuals with an alpha buffer.) The result of
   ggi_pixel can be used as the PIXELS argument of the ggi_put_* operations
   (see below). The ggi_color function converts a byte string representing a
   single pixel or a sequence of pixel values back into an (R,G,B,A) value or
   a list of such values, respectively. */

public extern ggi_pixel COLOR, ggi_color PIXEL;

/* Set and get the current foreground and background colors used in drawing
   operations, specified as pixel values or (R,G,B[,A]) tuples. */

public extern ggi_set_foreground VIS PIXEL, ggi_set_background VIS PIXEL;
public extern ggi_get_foreground VIS, ggi_get_background VIS;

ggi_set_foreground VIS:GGIVisual COLOR:Tuple
		  = ggi_set_foreground VIS PIXEL
		      where PIXEL:ByteStr = ggi_pixel COLOR;

ggi_set_background VIS:GGIVisual COLOR:Tuple
		  = ggi_set_background VIS PIXEL
		      where PIXEL:ByteStr = ggi_pixel COLOR;

/* Advanced text rendering using FreeType2. *********************************/

/* This is another Q-GGI specific extension which allows you to set the font
   used for text rendering in a GGI visual. The FreeType2 library is required
   to make this work. */

/* Reset a visual to the default builtin font. */

public extern ggi_set_default_font VIS;

/* Set a font on a visual, given by the full pathname of the font file and a
   zero-based index of the desired face (0 always works). Once the font has
   been loaded, you can query the visual for information about it, such as the
   available bitmap sizes, and whether the font is scalable. Before the font
   is used, you must also set the desired character size and resolution. */

public extern ggi_set_font VIS NAME INDEX;

/* Set the font metrics of a font, given by the full pathname of the font
   metric file. The font metric data is needed to do proper kerning in
   proportional fonts, and should be loaded immediately after calling
   ggi_set_font. Note that this is only necessary for some types of fonts which
   have their metrics in a separate file. A typical example are Type 1 font
   files, which have the font data in a file with extension .pfa or .pfb, and
   the kerning metrics in an additional file with extension .afm or .pfm. */

public extern ggi_set_font_metrics VIS NAME;

/* Set the character size SIZE (in pt = 1/72 of an inch, this can be a
   floating point value to denote fractional sizes) and display resolution RES
   (in dpi = dots per inch). The actual display size of the characters in
   pixels will be calculated from these values according to the formula
   PIXEL_SIZE = SIZE*RES/72. SIZE and RES can also be specified as pairs of
   values, to indicate different values for the x and y direction. Moreover, a
   SIZE value of 0 means "same as the other dimension", whereas a RES value of
   0 indicates the default value (72 dpi). */

public extern ggi_set_char_size VIS SIZE RES;

/* Specify whether the font should be antialiased. If true (which is the
   default), text will be rendered in up to 256 different shades of the
   foreground color, to give it a smoother appearance. The ggi_get_antialias
   function is used to retrieve the current setting. */

public extern ggi_set_antialias VIS FLAG, ggi_get_antialias VIS;

/* Specify an affine transformation to be applied before a string is rendered
   on the visual. The font must be scalable for this to work. This can be used
   to print translated, rotated and stretched text. The transformation is
   given by a translation vector VECTOR = (X,Y) and a 2x2 matrix MATRIX =
   (XX,XY,YX,YY). E.g., to rotate text by an angle A counter-clockwise, you
   would use a transform matrix of the form (cos A, -sin A, sin A, cos A). */

public extern ggi_set_transform VIS VECTOR MATRIX;

/* The following functions can be used to retrieve the current transform
   vector and matrix. */

public extern ggi_get_transform_vector VIS;
public extern ggi_get_transform_matrix VIS;

/* Retrieve general information about the loaded font. The ggi_get_font_info
   function returns a tuple with the following information:

   - NFACES, INDEX: The total number of faces in this font, and the index of
     the selected face.

   - FACE_FLAGS: A bitset (bitwise or'ed FT_FACE_FLAG_* values) describing
     various properties of the face. The most interesting one is
     FT_FACE_FLAG_SCALABLE which is set for scalable fonts.

   - STYLE_FLAGS: A bitset (bitwise or'ed FT_STYLE_FLAG_* values) describing
     various style properties of the face (bold, italic, etc.).

   - FAMILY, STYLE: These are string values describing the family and style of
     the font.

   - SIZES: A list of character sizes ((W,H) in pixels) of included bitmap
     fonts.

   The remaining fields are only available for scalable fonts. Please refer to
   the FreeType2 documentation for a closer description of these values. Note
   that all given dimensions, with the exception of X_PPEM and Y_PPEM, are in
   design a.k.a. font units; once the actual character size has been set with
   ggi_set_char_size, you can translate these values to pixels according to
   the formula PIXELS = FONT_UNITS*PPEM/UNITS_PER_EM.

   - UNITS_PER_EM: The size of the EM square for the font face.

   - X_PPEM, Y_PPEM: The horizontal and vertical size of the EM square in
     pixels. These values are meaningful only after a character size has been
     set.

   - BBOX: A tuple (XMIN,XMAX,YMIN,YMAX) describing the maximum bounding box
     for all glyphs in the font

   - ASCENDER, DESCENDER: The vertical distance from the horizontal baseline
     to the highest and lowest "character" coordinate in a font face,
     respectively. (Unfortunately, just what "character" means in this context
     is defined differently for different fonts.)

   - HEIGHT: The default line spacing (baseline-to-baseline distance) for the
     font.

   - MAX_ADVANCE_WIDTH, MAX_ADVANCE_HEIGHT: The maximum horizontal and
     vertical cursor advance for all glyphs in the font. (Note that the latter
     is only defined for vertical fonts which currently aren't supported
     anyway.)

   - UNDERLINE_POSITION, UNDERLINE_THICKNESS: The vertical position, relative
     to the baseline, of the underline bar, and its vertical thickness. */

public extern ggi_get_font_info VIS;

/* Graphics operations. *****************************************************/

/* Clear the screen. That is, fill the current clip area (the entire virtual
   screen by default) with the current background color. Also clear the
   clip area of an attached alpha buffer. */

public extern ggi_clear VIS;

/* Clear the alpha buffer only. This works like ggi_clear but only affects the
   alpha buffer of a visual. */

public extern ggi_clear_alpha VIS;

/* Basic drawing operations. These functions always use the foreground color
   currently set on the visual. You can draw single pixels, horizontal/
   vertical/arbitrary lines, and boxes (filled rectangles). The parameters
   are: P = (X,Y) = the location of a pixel, start point of a line, or
   top-left corner of a rectangle; Q = (X,Y) = end point of a line, W = width,
   H = height of a horizontal/vertical line, DIM = (W,H) = dimensions (width,
   height) of a rectangle. */

public extern ggi_draw_pixel VIS P;
public extern ggi_draw_hline VIS P W;
public extern ggi_draw_vline VIS P H;
public extern ggi_draw_line VIS P Q;
public extern ggi_draw_box VIS P DIM;

/* Drawing text on a visual. These operations use the current font (GGI's
   builtin font by default) and the current foreground and background colors
   to render text on a visual. Individual characters and character strings can
   be placed at the given position P = (X,Y) with the ggi_putc and ggi_puts
   operations, respectively.

   The range of available characters depends on the chosen font. With the
   builtin GGI font, you only get the 7 bit ASCII characters, with no special
   effects like scaling, rotation etc. With FreeType rendering, you get full
   Unicode (if and to the extent the font supports it). Note that when using
   the FreeType renderer, the text will always be rendered as Unicode,
   regardless of the current system encoding. For this to work, the font must
   provide a Unicode charmap (most fonts nowadays do).

   Also note that control characters in the text are *not* interpreted, and
   *no* word wrap is performed. So the entire layout of the text is up to
   you. Additional operations are provided to help with this, see below. */

public extern ggi_putc VIS P C, ggi_puts VIS P S;

/* The following operations can be used to handle the layout of text in a
   visual. Both operations take into account the current text transform set on
   a visual. Thus, if the transform specifies a translation, rotation or
   stretching of the text, the returned figures will change accordingly.

   The ggi_get_string_size function allows you to calculate the dimensions of
   the bounding box of a rendered string, which is useful, e.g., for centering
   text. It returns a pair (W,H), where W denotes the width and H the height
   of the rendered text.

   The ggi_get_string_bbox function gives you finer control over the layout
   process. It returns four values (XMIN,XMAX,YMIN,YMAX) which describe the
   bounding box of the string in relationship to the baseline. For the default
   font, the XMIN and YMIN values are always zero, and the XMAX and YMAX
   values correspond to the width and height of the rendered string. For
   FreeType-managed fonts, the XMIN value describes the initial offset of the
   first character in the string from adjacent characters. The YMIN value
   specifies the amount of vertical space between the lowest pixel in the
   rendered string and the baseline of the text; note that this value can be
   negative, indicating that the string extends *below* the baseline. The YMIN
   value is useful, in particular, if text is to be aligned properly w.r.t.
   the baseline. */

public extern ggi_get_string_bbox VIS S;
public ggi_get_string_size VIS S;

ggi_get_string_size VIS:GGIVisual S:String
		  = (XMAX-XMIN,YMAX-YMIN)
  where (XMIN,XMAX,YMIN,YMAX) = ggi_get_string_bbox VIS S;

/* Get and put operations. The get operations allow you to retrieve a pixel,
   line or rectangle from a visual as an RGBA byte string. The retrieved value
   can then be placed back into another or the same visual with the
   corresponding put operations (performing alpha blending if the target
   visual has an alpha buffer). For the put operations, pixels can also be
   specified as a color tuple or list of color tuples, respectively. */

public extern ggi_get_pixel VIS P, ggi_put_pixel VIS P PIXEL;
public extern ggi_get_hline VIS P W, ggi_put_hline VIS P W PIXELS;
public extern ggi_get_vline VIS P H, ggi_put_vline VIS P H PIXELS;
public extern ggi_get_box VIS P DIM, ggi_put_box VIS P DIM PIXELS;

ggi_put_pixel VIS:GGIVisual (X:Int,Y:Int) COLOR:Tuple
		  = ggi_put_pixel VIS (X,Y) PIXEL
		      where PIXEL:ByteStr = ggi_pixel COLOR;

ggi_put_hline VIS:GGIVisual (X:Int,Y:Int) W:Int COLORS:List
		  = ggi_put_hline VIS (X,Y) W PIXELS
		      where PIXELS:ByteStr = ggi_pixel COLORS;

ggi_put_vline VIS:GGIVisual (X:Int,Y:Int) H:Int COLORS:List
		  = ggi_put_vline VIS (X,Y) H PIXELS
		      where PIXELS:ByteStr = ggi_pixel COLORS;

ggi_put_box VIS:GGIVisual (X:Int,Y:Int) (W:Int,H:Int) COLORS:List
		  = ggi_put_box VIS (X,Y) (W,H) PIXELS
		      where PIXELS:ByteStr = ggi_pixel COLORS;

/* Blitting operations. These operations allow you to copy rectangles inside a
   visual VIS or from a source visual PVIS to a target visual QVIS. The
   rectangle is denoted by its source position P = (X1,Y1), dimensions DIM =
   (H,W) and target position Q = (X2,Y2). The rectangle is copied from the
   read frame of the source visual to the write frame of the target visual. */

public ggi_copy_box VIS P DIM Q;
public ggi_cross_blit PVIS P DIM QVIS Q;

ggi_copy_box VIS P DIM Q
		  = ()
  where () = ggi_put_box VIS Q DIM (ggi_get_box VIS P DIM);

ggi_cross_blit PVIS P DIM QVIS Q
		  = ()
  where () = ggi_put_box QVIS Q DIM (ggi_get_box PVIS P DIM);

/* Flush the display. This causes pending output operations to be completed
   immediately and refreshes the display. This is only necessary if the
   display is operated in asynchronous mode (i.e., if the GGI_FLAG_ASYNC flag
   is set on the visual). You can either flush the entire screen, or a region
   of the screen specified using the top-left corner P = (X,Y) and dimensions
   DIM = (W,H). */

public extern ggi_flush VIS, ggi_flush_region VIS P DIM;

/* Event handling. **********************************************************/

/* The following operations allow you to access a visual as an input source
   which delivers various kinds of generic events for different input devices
   such as a mouse or a keyboard. GGI's abstraction of input devices
   encompasses buttons (keys, mouse and joystick buttons, etc.), current
   position (on pointer devices such as a mouse), and valuators (additional
   axes of a device such as a joystick, which are associated with different
   physical quantities such as force or energy). */

/* Event type. This type encodes the various kinds of events described in
   gii_event(3) and related man pages. The supported event types are:

  - "any" events (GGI_EV_NOTHING, anything unrecognized which is not
    classified otherwise)

  - key events (GGI_EV_KEYPRESS, GGI_EV_KEYRELEASE, GGI_EV_KEYREPEAT, generated
    for keyboard events)

  - pointer move events (GGI_EV_PTRRELATIVE, GGI_EV_PTRABSOLUTE, generated
    when a pointer device moves relatively or absolutely, respectively)

  - pointer button events (GGI_EV_PTRBUTTONPRESS, GGI_EV_PTRBUTTONRELEASE,
    generated when buttons on a pointer device change state)

  - command events (GGI_EV_COMMAND, GGI_EV_INFORMATION, generated internally
    by GGI or the application)

  - valuator events (GGI_EV_VALRELATIVE, GGI_EV_VALABSOLUTE, generated if some
    quantity of an input device changes relatively or absolutely, respectively)

  - expose events (GGI_EV_EXPOSE, generated when an application gains focus
    again and needs to redisplay).

  All event types have the following fields:

  - TYPE: the type of event (GGI_EV_* value)

  - ERROR: an error code set by a device when replying to a command (integer)

  - ORIGIN: the number of the device (integer) that generated this event; can
    also be GGI_EV_ORIGIN_NONE to denote an anonymous event or
    GGI_EV_ORIGIN_SENDEVENT to denote an event sent with ggi_send

  - TARGET: the number of the device (integer) that the event is to be send to
    with ggi_send; can also be GGI_EV_TARGET_QUEUE to denote the event queue
    associated with the visual or GGI_EV_TARGET_ALL if the event is to be sent
    to all devices

  - TIME: timestamp indicating when the event was delivered (floating point
    value in seconds)

  - PARAM: any additional parameters associated with the event, either a
    singleton (integer) value, tuple, or () if no additional parameters are
    present; this value depends on the specific type of event

  The different event types have the following PARAM field:

  - any events: PARAM = ()

  - key events: PARAM = (MODIFIERS,SYM,LABEL,BUTTON) where MODIFIERS is the
    set of modifiers (integer, bitwise or of GGI_MOD_* values) that were
    active when the event was received; SYM is the resultant character
    (integer); LABEL is the label on the key (integer, can be used as a
    portable scan code); and BUTTON is the scan code of the key (integer)

  - move events: PARAM = (X,Y,Z,WHEEL), the pointer motion on all axes (all
    values integer), given either relatively or absolutely, depending on the
    event type

  - button events: PARAM = BUTTON, where BUTTON is the number of the button
    (integer) that changed status (the constants GGI_PBUTTON_LEFT,
    GGI_PBUTTON_MIDDLE, GGI_PBUTTON_RIGHT are defined for mouse devices)

  - command events: either PARAM = CODE in the case of a parameterless
    command, or PARAM = (CODE,DATA) where CODE is the command or request
    number (integer, GGI_CMDCODE_* values bitwise or'ed with GGI_CMDFLAG_*
    values) and DATA is the data related to the command, encoded as a byte
    string

  - valuator events: PARAM = (FIRST,VAL1,VAL2,...) where FIRST is the number
    of the first valuator reported (integer) and VAL1, VAL2, ... are the
    reported values, given either relatively or absolutely, depending on the
    event type; usually either all valuators (where FIRST=0) or only a single
    valuator (where FIRST is the number of the valuator) will be reported in a
    single event

  - expose events: PARAM = (X,Y,W,H) (all values integer), describing the
    region to be redrawn */

public type GGIEvent = const ggi_event TYPE ERROR ORIGIN TARGET TIME PARAM;

/* The following operations can be used to determine information about input
   devices and valuators. The ggi_devices function returns a list with all
   available input devices (ORIGIN values). The ggi_device_info function
   returns a tuple (LONG_NAME, SHORT_NAME, EVENTS, N_BUTTONS, N_AXES) with
   information about the given device number ORIGIN, denoting, respectively,
   the long and short name of the device (strings), the mask of events
   supported by the device, and its numbers of buttons and valuator axes.

   The ggi_val_info function returns a tuple (LONG_NAME, SHORT_NAME, MIN,
   CENTER, MAX, PHYS_TYPE, SI_ADD, SI_MUL, SI_DIV, SI_SHIFT) with information
   about the given valuator number N (ranging from 0 to N_AXES-1, where N_AXES
   is the number of axes of the device as reported by ggi_device_info) on the
   given device number ORIGIN. LONG_NAME and SHORT_NAME are the long and short
   name of the device. The integer values MIN, CENTER, MAX denote the
   valuator's range and center position. PHYS_TYPE gives the physical quantity
   the device measures (GGI_PT_* constants). SI_ADD, SI_MUL, SI_DIV, SI_SHIFT
   are integer parameters describing the calibration of the device. The actual
   (floating point) value SI_VAL of the valuator in terms of the physical
   quantity described by PHYS_TYPE can then be determined from the current
   (integer) value VAL of the valuator as follows: SI_VAL =
   (SI_ADD+VAL)*SI_MUL/SI_DIV*2^SI_SHIFT. */

public extern ggi_devices VIS, ggi_device_info VIS ORIGIN,
  ggi_val_info VIS ORIGIN N;

/* The following operations are provided to configure the event handling of a
   visual and perform input operations. With the ggi_set_mask and ggi_get_mask
   functions you can modify and retrieve the mask of events accepted by the
   visual.

   The ggi_poll operation polls the visual for input until either an event in
   the specified event mask becomes available, or the specified timeout
   expires; it returns a mask of available events (which may be 0 if the
   timeout expired before any events became available). The timeout is an
   integer or floating point value denoting the seconds to wait (which may be
   0 to indicate that the function is to return immediately, after checking
   the input queue, or () to disable the timeout and block until an event is
   available).

   With the ggi_queued and ggi_read functions you can check for available
   events and read the next event in the input queue of a visual,
   respectively. You can also send an event to the input queue of a visual
   with ggi_send. Finally, ggi_getc and ggi_kbhit are provided as convenience
   functions to obtain the next character typed on the keyboard, and to check
   whether keyboard input is available, respectively. Note that ggi_getc
   returns the typed key as an integer denoting a Unicode character in
   canonical form; codes in the range 0..255 are for the extended ASCII
   characters, codes above 255 for special keys. */

public extern ggi_set_mask VIS MASK, ggi_get_mask VIS;
public extern ggi_poll VIS MASK TIMEOUT;
public extern ggi_queued VIS MASK, ggi_read VIS MASK, ggi_send VIS EVENT;
public extern ggi_getc VIS, ggi_kbhit VIS;
