| GRAPHICS(3) | GRAPHICS(3)
| NAME
| Display, Point, Rectangle, Cursor, initdraw, geninitdraw, drawerror, initdisplay, closedisplay, getdefont, getwindow, gengetwindow, flushimage, bufimage, lockdisplay, unlockdisplay, cursorswitch, cursorset, openfont, buildfont, freefont, Pfmt, Rfmt, strtochan, chantostr, chantodepth – interactive graphics
SYNOPSIS
| `#include <u.h> #include <libc.h> #include <draw.h> #include <cursor.h>
` `int initdraw(void (*errfun)(Display*, char*), char *font,
| char *label)
`
`int geninitdraw(char *devdir, void(*errfun)(Display*, char*),
`
| `char *font, char *label, char *mousedir, char *windir, int ref)
`
`int newwindow(char *str)
` `void drawerror(Display *d, char *msg)
` `Display*initdisplay(char *devdir, char *win, void(*errfun)(Display*, char*))
` `void closedisplay(Display *d)
` `Font* getdefont(Display *d)
` `int flushimage(Display *d, int vis)
` `int bufimage(Display *d, int n)
` `int lockdisplay(Display *d)
` `int unlockdisplay(Display *d)
` `int getwindow(Display *d, int ref)
` `int gengetwindow(Display *d, char *winname,
| Image **ip, Screen **sp, int ref)
`
`int scalesize(Display *d, int n)
` `void cursorswitch(Cursor *curs)
` `void cursorset(Point p)
` `Font* openfont(Display *d, char *name)
` `Font* buildfont(Display *d, char *desc, char *name)
` `void freefont(Font *f)
` `int Pfmt(Fmt*)
` `int Rfmt(Fmt*)
` `ulong strtochan(char *s)
` `char* chantostr(char *s, ulong chan)
` `int chantodepth(ulong chan)
` `extern Display *display
` `extern Image *screen
` `extern Screen *_screen
` `extern Font *font`
DESCRIPTION
| A `Display` structure represents a connection to the graphics device, draw(3), holding all graphics resources associated with the connection, including in particular raster image data in use by the client program. The structure is defined (in part) as:
| `typedef struct Display {
| ... void (*error)(Display*, char*); ... Image *black; Image *white; Image *opaque; Image *transparent; Image *image; Font *defaultfont; Subfont *defaultsubfont; ...
};
`
A `Point` is a location in an Image (see below and draw(3)), such as the display, and is defined as:
| `typedef struct Point {
| int x; int y;
} Point;
`
The coordinate system has x increasing to the right and y increasing down.
A `Rectangle` is a rectangular area in an image.
| `typedef struct Rectangle {
| Point min; /* upper left */ Point max; /* lower right */
} Rectangle;
`
By definition, `min.x`≤`max.x` and `min.y`≤`max.y`. By convention, the right (maximum x) and bottom (maximum y) edges are excluded from the represented rectangle, so abutting rectangles have no points in common. Thus, `max` contains the coordinates of the first point beyond the rectangle.
The `Image` data structure is defined in draw(3).
A `Font` is a set of character images, indexed by runes (see utf(7)). The images are organized into `Subfonts`, each containing the images for a small, contiguous set of runes. The detailed format of these data structures, which are described in detail in cachechars(3), is immaterial for most applications. `Font` and `Subfont` structures contain two interrelated fields: `ascent`, the distance from the top of the highest character (actually the top of the image holding all the characters) to the baseline, and `height`, the distance from the top of the highest character to the bottom of the lowest character (and hence, the interline spacing). See cachechars(3) for more details.
Buildfont parses the font description in the buffer `desc`, returning a `Font*` pointer that can be used by `string` (see draw(3)) to draw characters from the font. Openfont does the same, but reads the description from the named file. Freefont frees a font. The convention for naming font files is:
| `/lib/font/bit/`name`/`range`.`size`.font
`
where size is approximately the height in pixels of the lower case letters (without ascenders or descenders). Range gives some indication of which characters will be available: for example `ascii`, `latin1`, `euro`, or `unicode`. `Euro` includes most European languages, punctuation marks, the International Phonetic Alphabet, etc., but no Oriental languages. `Unicode` includes every character for which appropriate-sized images exist on the system.
A Cursor is defined:
| `typedef struct Cursor {
| Point offset; uchar clr[2*16]; uchar set[2*16];
} Cursor;
`
The arrays are arranged in rows, two bytes per row, left to right in big-endian order to give 16 rows of 16 bits each. A cursor is displayed on the screen by adding `offset` to the current mouse position, using `clr` as a mask to draw white at the pixels where `clr` is one, and then drawing black at the pixels where `set` is one.
The routine initdraw connects to the display; it returns –1 if it fails and sets the error string. Initdraw sets up the global variables `display` (the `Display` structure representing the connection), `screen` (an `Image` representing the display memory itself or, if rio(1) is running, the client’s window), and `font` (the default font for text). The arguments to initdraw include a label, which is written to `/dev/label` if non-nil so that it can be used to identify the window when hidden (see rio(1)). The font is created by reading the named font file. If `font` is null, initdraw reads the file named in the environment variable `$font`; if `$font` is not set, it imports the default (usually minimal) font from the operating system. The global font will be set to point to the resulting `Font` structure. The errfun argument is a graphics error function to call in the event of a fatal error in the library; it must never return. Its arguments are the display pointer and an error string. If errfun is nil, the library provides a default, called drawerror. Another effect of initdraw is that it installs print(3) formats Pfmt and Rfmt as `%P` and `%R` for printing `Points` and `Rectangles`.
The geninitdraw function provides a less automated way to establish a connection, for programs that wish to connect to multiple displays. Devdir is the name of the directory containing the device files for the display (if nil, default `/dev`); errfun, font, and label are as in initdraw; mousedir and windir are the directories holding the `mouse` and `winname` files; and ref specifies the refresh function to be used to create the window, if running under rio(1) (see window(3)).
Initdisplay is part of geninitdraw; it sets up the display structures but does not allocate any fonts or call getwindow. The arguments are similar to those of initdraw; win names the directory, default `/dev`, in which the files associated with the window reside. Closedisplay disconnects the display and frees the associated data structures. Getdefont builds a `Font` structure from in-core data describing a default font. None of these routines is needed by most programs, since initdraw calls them as needed.
The data structures associated with the display must be protected in a multi-process program, because they assume only one process will be using them at a time. Multi-process programs should set `display−>locking` to `1`, to notify the library to use a locking protocol for its own accesses, and call lockdisplay and unlockdisplay around any calls to the graphics library that will cause messages to be sent to the display device. Initdraw and geninitdraw initialize the display to the locked state.
Getwindow returns a pointer to the window associated with the application; it is called automatically by initdraw to establish the `screen` pointer but must be called after each resizing of the window to restore the library’s connection to the window. If `rio` is not running, it returns `display−>image`; otherwise it negotiates with `rio` by looking in `/dev/winname` to find the name of the window and opening it using `namedimage` (see allocimage(3)). The resulting window will be created using the refresh method ref (see window(3)); this should almost always be `Refnone` because `rio` provides backing store for the window.
Getwindow overwrites the global variables `screen`, a pointer to the `Image` defining the window (or the overall display, if no window system is running); and `_screen`, a pointer to the `Screen` representing the root of the window’s hierarchy. (See window(3). The overloading of the `screen` word is an unfortunate historical accident.) Getwindow arranges that `screen` point to the portion of the window inside the border; sophisticated clients may use `_screen` to make further subwindows. Gengetwindow’s extra arguments are the full path of the window’s `winname` file and pointers to be overwritten with the values of the ‘global’ `Image` and `Screen` variables for the new window.
Historically, Plan 9 graphics programs have used fixed-size graphics features that assume a narrow range of display densities, around 100 dpi: pixels (or dots) per inch. The new field `display−>dpi` contains the display’s actual density if known, or else `DefaultDPI` (100). Scalesize scales the fixed pixel count n by `display−>dpi`/`DefaultDPI`, rounding appropriately.
The mouse cursor is always displayed. The initial cursor is an arrow. Cursorswitch causes the argument cursor to be displayed instead. A zero argument causes a switch back to the arrow cursor. Cursorset moves the mouse cursor to position p, provided (if in a window) that the requesting program is executing in the current window and the mouse is within the window boundaries; otherwise cursorset is a no-op.
The graphics functions described in draw(3), allocimage(3), cachechars(3), and subfont(3) are implemented by writing commands to files under `/dev/draw` (see draw(3)); the writes are buffered, so the functions may not take effect immediately. Flushimage flushes the buffer, doing all pending graphics operations. If vis is non-zero, any changes are also copied from the ‘soft screen’ (if any) in the driver to the visible frame buffer. The various allocation routines in the library flush automatically, as does the event package (see event(3)); most programs do not need to call flushimage. It returns –1 on error.
Bufimage is used to allocate space for n bytes in the display buffer. It is used by all the graphics routines to send messages to the display.
The functions strtochan and chantostr convert between the channel descriptor strings used by image(7) and the internal `ulong` representation used by the graphics protocol (see draw(3)’s `b` message). `Chantostr` writes at most nine bytes into the buffer pointed at by s and returns s on success, 0 on failure. `Chantodepth` returns the number of bits per pixel used by the format specified by chan. Both `chantodepth` and `strtochan` return 0 when presented with bad input.
EXAMPLES
| To reconnect to the window after a resize event,
| `if(getwindow(display, Refnone) < 0)
| sysfatal("resize failed: %r");
`
To create and set up a new rio(1) window,
| `Image *screen2; Screen *_screen2; srvwsys = getenv("wsys"); if(srvwsys == nil)
| sysfatal("can't find $wsys: %r");
rfork(RFNAMEG); /* keep mount of rio private */ fd = open(srvwsys, ORDWR); if(fd < 0)
| sysfatal("can't open $wsys: %r");
/* mount creates window; see` rio`(4) */ if(mount(fd, −1, "/tmp", MREPL, "new −dx 300−dy 200") < 0)
| sysfatal("can't mount new window: %r");
if(gengetwindow(display, "/tmp/winname",
| &screen2, &_screen2, Refnone) < 0) sysfatal("resize failed: %r");
/* now open /tmp/cons, /tmp/mouse */ ...`
FILES
| `/usr/local/plan9port/font/bit` directory of fonts
SOURCE
| `/usr/local/plan9port/src/libdraw`
SEE ALSO
| rio(1), addpt(3), allocimage(3), cachechars(3), subfont(3), draw(3), event(3), frame(3), print(3), window(3), draw(3), image(7), font(7)
DIAGNOSTICS
| An error function may call errstr(3) for further diagnostics.
BUGS
| The names `clr` and `set` in the `Cursor` structure are reminders of an archaic color map and might be more appropriately called `white` and `black`.
These manual pages contain many references to the now-fictitious `/dev/draw`.