| .TH GRAPHICS 3 |
| .SH 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 |
| .SH SYNOPSIS |
| .nf |
| .PP |
| .ft L |
| #include <u.h> |
| #include <libc.h> |
| #include <draw.h> |
| #include <cursor.h> |
| .ft P |
| .PP |
| .ta \w'\fLFont* 'u |
| .B |
| int initdraw(void (*errfun)(Display*, char*), char *font, |
| .B |
| char *label) |
| .PP |
| .B |
| int geninitdraw(char *devdir, void(*errfun)(Display*, char*), |
| .PP |
| .B |
| char *font, char *label, char *mousedir, char *windir, |
| .B |
| int ref) |
| .PP |
| .B |
| int newwindow(char *str) |
| .PP |
| .B |
| void drawerror(Display *d, char *msg) |
| .PP |
| .B |
| Display* initdisplay(char *devdir, char *win, void(*errfun)(Display*, char*)) |
| .PP |
| .B |
| void closedisplay(Display *d) |
| .PP |
| .B |
| Font* getdefont(Display *d) |
| .PP |
| .B |
| int flushimage(Display *d, int vis) |
| .PP |
| .B |
| int bufimage(Display *d, int n) |
| .PP |
| .B |
| int lockdisplay(Display *d) |
| .PP |
| .B |
| int unlockdisplay(Display *d) |
| .PP |
| .B |
| int getwindow(Display *d, int ref) |
| .PP |
| .B |
| int gengetwindow(Display *d, char *winname, |
| .br |
| .B |
| Image **ip, Screen **sp, int ref) |
| .PP |
| .B |
| int scalesize(Display *d, int n) |
| .PP |
| .B |
| void cursorswitch(Cursor *curs) |
| .PP |
| .B |
| void cursorset(Point p) |
| .PP |
| .B |
| Font* openfont(Display *d, char *name) |
| .PP |
| .B |
| Font* buildfont(Display *d, char *desc, char *name) |
| .PP |
| .B |
| void freefont(Font *f) |
| .PP |
| .B |
| int Pfmt(Fmt*) |
| .PP |
| .B |
| int Rfmt(Fmt*) |
| .PP |
| .B |
| ulong strtochan(char *s) |
| .PP |
| .B |
| char* chantostr(char *s, ulong chan) |
| .PP |
| .B |
| int chantodepth(ulong chan) |
| .PP |
| .B |
| extern Display *display |
| .PP |
| .B |
| extern Image *screen |
| .PP |
| .B |
| extern Screen *_screen |
| .PP |
| .B |
| extern Font *font |
| .fi |
| .SH DESCRIPTION |
| A |
| .B Display |
| structure represents a connection to the graphics device, |
| .IR 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: |
| .IP |
| .EX |
| .ta 6n +10n |
| typedef |
| struct Display |
| { |
| ... |
| void (*error)(Display*, char*); |
| ... |
| Image *black; |
| Image *white; |
| Image *opaque; |
| Image *transparent; |
| Image *image; |
| Font *defaultfont; |
| Subfont *defaultsubfont; |
| ... |
| }; |
| .EE |
| .PP |
| A |
| .B Point |
| is a location in an Image |
| (see below and |
| .IR draw (3)), |
| such as the display, and is defined as: |
| .IP |
| .EX |
| .ta 6n |
| typedef |
| struct Point { |
| int x; |
| int y; |
| } Point; |
| .EE |
| .PP |
| The coordinate system has |
| .I x |
| increasing to the right and |
| .I y |
| increasing down. |
| .PP |
| A |
| .B Rectangle |
| is a rectangular area in an image. |
| .IP |
| .EX |
| .ta 6n |
| typedef |
| struct Rectangle { |
| Point min; /* upper left */ |
| Point max; /* lower right */ |
| } Rectangle; |
| .EE |
| .PP |
| By definition, |
| .BR min.x ≤ max.x |
| and |
| .BR min.y ≤ max.y . |
| By convention, the right (maximum |
| .IR x ) |
| and bottom (maximum |
| .IR y ) |
| edges are |
| excluded from the represented rectangle, so abutting rectangles have no |
| points in common. |
| Thus, |
| .B max |
| contains the coordinates of the first point beyond the rectangle. |
| .PP |
| The |
| .B Image |
| data structure is defined in |
| .IR draw (3). |
| .PP |
| A |
| .B Font |
| is a set of character images, indexed by runes (see |
| .IR utf (7)). |
| The images are organized into |
| .BR 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 |
| .IR cachechars (3), |
| is immaterial for most applications. |
| .B Font |
| and |
| .B Subfont |
| structures contain two interrelated fields: |
| .LR ascent , |
| the distance from the top of the highest character |
| (actually the top of the image holding all the characters) |
| to the baseline, |
| and |
| .LR height , |
| the distance from the top of the highest character to the bottom of |
| the lowest character (and hence, the interline spacing). |
| See |
| .IR cachechars (3) |
| for more details. |
| .PP |
| .I Buildfont |
| parses the font description in the buffer |
| .BR desc , |
| returning a |
| .B Font* |
| pointer that can be used by |
| .B string |
| (see |
| .IR draw (3)) |
| to draw characters from the font. |
| .I Openfont |
| does the same, but reads the description |
| from the named font. |
| .I 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 |
| .IR font (7) |
| for details. |
| .PP |
| A |
| .I Cursor |
| is defined: |
| .IP |
| .EX |
| .ta 6n +\w'Point 'u |
| typedef struct |
| Cursor { |
| Point offset; |
| uchar clr[2*16]; |
| uchar set[2*16]; |
| } Cursor; |
| .EE |
| .PP |
| 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 |
| .B offset |
| to the current mouse position, using |
| .B clr |
| as a mask to draw white at the pixels where |
| .B clr |
| is one, and then drawing black at the pixels where |
| .B set |
| is one. |
| .PP |
| The routine |
| .I initdraw |
| connects to the display; it returns \-1 if it fails and sets the error string. |
| .I Initdraw |
| sets up the global variables |
| .B display |
| (the |
| .B Display |
| structure representing the connection), |
| .B screen |
| (an |
| .B Image |
| representing the display memory itself or, if |
| .IR rio (1) |
| is running, the client's window), |
| and |
| .B font |
| (the default font for text). |
| The arguments to |
| .I initdraw |
| include a |
| .IR label , |
| which is written to |
| .B /dev/label |
| if non-nil |
| so that it can be used to identify the window when hidden (see |
| .IR rio (1)). |
| The font is created by reading the named |
| .I font |
| file. If |
| .B font |
| is null, |
| .I initdraw |
| reads the file named in the environment variable |
| .BR $font ; |
| if |
| .B $font |
| is not set, it imports the default (usually minimal) |
| font from the operating system. |
| (See |
| .IR font (7) |
| for a full discussion of font syntaxes.) |
| The global |
| .I font |
| will be set to point to the resulting |
| .B Font |
| structure. |
| The |
| .I errfun |
| argument is a |
| .I 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 |
| .I errfun |
| is nil, the library provides a default, called |
| .IR drawerror . |
| Another effect of |
| .I initdraw |
| is that it installs |
| .IR print (3) |
| formats |
| .I Pfmt |
| and |
| .I Rfmt |
| as |
| .L %P |
| and |
| .L %R |
| for printing |
| .B Points |
| and |
| .BR Rectangles . |
| .PP |
| The |
| .I geninitdraw |
| function provides a less automated way to establish a connection, for programs |
| that wish to connect to multiple displays. |
| .I Devdir |
| is the name of the directory containing the device files for the display |
| (if nil, default |
| .BR /dev ); |
| .IR errfun , |
| .IR font , |
| and |
| .I label |
| are as in |
| .IR initdraw ; |
| .I mousedir |
| and |
| .I windir |
| are the directories holding the |
| .B mouse |
| and |
| .B winname |
| files; and |
| .I ref |
| specifies the refresh function to be used to create the window, if running under |
| .IR rio (1) |
| (see |
| .IR window (3)). |
| .\" .PP |
| .\" The function |
| .\" .I newwindow |
| .\" may be called before |
| .\" .I initdraw |
| .\" or |
| .\" .IR geninitdraw |
| .\" to cause the program to occupy a newly created window rather than take over the one in |
| .\" which it is running when it starts. |
| .\" The |
| .\" .I str |
| .\" argument, if non-null, is concatenated to the string \f5\&"new\ "\fP |
| .\" that is used to create the window (see |
| .\" .IR rio (4)). |
| .\" For example, |
| .\" .B newwindow("-hide -dy 100") |
| .\" will cause the program to run in a newly created, hidden window |
| .\" 100 pixels high. |
| .PP |
| .I Initdisplay |
| is part of |
| .IR geninitdraw ; |
| it sets up the display structures but does not allocate any fonts or call |
| .IR getwindow . |
| The arguments are similar to those of |
| .IR initdraw ; |
| .I win |
| names the directory, default |
| .BR /dev , |
| in which the files associated with the window reside. |
| .I Closedisplay |
| disconnects the display and frees the associated data structures. |
| .I Getdefont |
| builds a |
| .B Font |
| structure from in-core data describing a default font. |
| None of these routines is needed by most programs, since |
| .I initdraw |
| calls them as needed. |
| .PP |
| 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 |
| .B display->locking |
| to |
| .BR 1 , |
| to notify the library to use a locking protocol for its own accesses, |
| and call |
| .I lockdisplay |
| and |
| .I unlockdisplay |
| around any calls to the graphics library that will cause messages to be sent to the display device. |
| .I Initdraw |
| and |
| .I geninitdraw |
| initialize the display to the locked state. |
| .PP |
| .I Getwindow |
| returns a pointer to the window associated with the application; it is called |
| automatically by |
| .I initdraw |
| to establish the |
| .B screen |
| pointer but must be called after each resizing of the window to restore |
| the library's connection to the window. |
| If |
| .B rio |
| is not running, it returns |
| .BR display->image ; |
| otherwise it negotiates with |
| .B rio |
| by looking in |
| .B /dev/winname |
| to find the name of the window and opening it using |
| .B namedimage |
| (see |
| .IR allocimage (3)). |
| The resulting window will be created using the refresh method |
| .I ref |
| (see |
| .IR window (3)); |
| this should almost always be |
| .B Refnone |
| because |
| .B rio |
| provides backing store for the window. |
| .PP |
| .I Getwindow |
| overwrites the global variables |
| .BR screen , |
| a pointer to the |
| .B Image |
| defining the window (or the overall display, if no window system is running); and |
| .BR _screen , |
| a pointer to the |
| .B Screen |
| representing the root of the window's hierarchy. (See |
| .IR window (3). |
| The overloading of the |
| .B screen |
| word is an unfortunate historical accident.) |
| .I Getwindow |
| arranges that |
| .B screen |
| point to the portion of the window inside the border; |
| sophisticated clients may use |
| .B _screen |
| to make further subwindows. |
| If |
| .I 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 |
| .BR Display 's |
| .B dpi |
| field and any open |
| .BR Font 's |
| .B height |
| and |
| .B ascent |
| fields may be updated during the call to |
| .IR getwindow . |
| Programs should discard any cached information about display or font sizes. |
| .\" Programs desiring multiple independent windows |
| .\" may use the mechanisms of |
| .\" .IR rio (4) |
| .\" to create more windows (usually by a fresh mount of the window sytem |
| .\" in a directory other than |
| .\" .BR /dev ), |
| .\" then use |
| .\" .I gengetwindow |
| .\" to connect to them. |
| .IR Gengetwindow 's |
| extra arguments are the full path of the window's |
| .B winname |
| file and pointers to be overwritten with the values of the `global' |
| .B Image |
| and |
| .B Screen |
| variables for the new window. |
| .PP |
| 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 |
| .B display->dpi |
| contains the display's actual density if known, or else |
| .B DefaultDPI |
| (100). |
| .I Scalesize |
| scales the fixed pixel count |
| .I n |
| by |
| .BR display->dpi / DefaultDPI , |
| rounding appropriately. |
| .PP |
| The mouse cursor is always displayed. |
| The initial cursor is an arrow. |
| .I Cursorswitch |
| causes the argument cursor to be displayed instead. |
| A zero argument causes a switch back to the arrow cursor. |
| .I Cursorset |
| moves the mouse cursor to position |
| .IR 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 |
| .I cursorset |
| is a no-op. |
| .PP |
| The graphics functions described in |
| .IR draw (3), |
| .IR allocimage (3), |
| .IR cachechars (3), |
| and |
| .IR subfont (3) |
| are implemented by writing commands to files under |
| .B /dev/draw |
| (see |
| .IR draw (3)); |
| the writes are buffered, so the functions may not take effect immediately. |
| .I Flushimage |
| flushes the buffer, doing all pending graphics operations. |
| If |
| .I 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 |
| .IR event (3)); |
| most programs do not need to call |
| .IR flushimage . |
| It returns \-1 on error. |
| .PP |
| .I Bufimage |
| is used to allocate space for |
| .I n |
| bytes in the display buffer. |
| It is used by all the graphics routines to send messages to the display. |
| .PP |
| The functions |
| .I strtochan |
| and |
| .I chantostr |
| convert between the channel descriptor strings |
| used by |
| .IR image (7) |
| and the internal |
| .B ulong |
| representation |
| used by the graphics protocol |
| (see |
| .IR draw (3)'s |
| .B b |
| message). |
| .B Chantostr |
| writes at most nine bytes into the buffer pointed at by |
| .I s |
| and returns |
| .I s |
| on success, |
| 0 |
| on failure. |
| .B Chantodepth |
| returns the number of bits per pixel used by the |
| format specified by |
| .IR chan . |
| Both |
| .B chantodepth |
| and |
| .B strtochan |
| return 0 when presented |
| with bad input. |
| .SH EXAMPLES |
| To reconnect to the window after a resize event, |
| .IP |
| .EX |
| if(getwindow(display, Refnone) < 0) |
| sysfatal("resize failed: %r"); |
| .EE |
| .PP |
| To create and set up a new |
| .IR rio (1) |
| window, |
| .IP |
| .EX |
| 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 \f2rio\fP(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 */ |
| \&... |
| .EE |
| .SH FILES |
| .BR \*9/font/bit " directory of fonts |
| .SH SOURCE |
| .B \*9/src/libdraw |
| .SH "SEE ALSO" |
| .IR rio (1), |
| .IR addpt (3), |
| .IR allocimage (3), |
| .IR cachechars (3), |
| .IR subfont (3), |
| .IR draw (3), |
| .IR event (3), |
| .IR frame (3), |
| .IR print (3), |
| .IR window (3), |
| .IR draw (3), |
| .\" .IR rio (4), |
| .IR image (7), |
| .IR font (7) |
| .SH DIAGNOSTICS |
| An error function may call |
| .IR errstr (3) |
| for further diagnostics. |
| .SH BUGS |
| The names |
| .B clr |
| and |
| .B set |
| in the |
| .B Cursor |
| structure are reminders of an archaic color map |
| and might be more appropriately called |
| .B white |
| and |
| .BR black . |
| .PP |
| These manual pages contain many references to |
| the now-fictitious |
| .BR /dev/draw . |