|
NAME
| |
Display, Point, Rectangle, Cursor, initdraw, geninitdraw, drawerror,
initdisplay, closedisplay, 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,
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)
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 {
} 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 font. Freefont frees a font. In contrast
to Plan 9, font names in Plan 9 from User Space are a small language
describing the
desired font. See font(7) for details.
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. (See font(7) for a full discussion of font syntaxes.)
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.
Neither 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.
If getwindow is being called due to a resizing of the window,
the resize may be accompanied by a change in screen pixel density
(DPI), in which case the value of the Display’s dpi field and
any open Font’s height
and ascent fields may be updated during the call to getwindow.
Programs should discard any cached information about display or
font sizes. 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
SOURCE
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.
|
|
|