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)

     Page 1                       Plan 9            (printed 12/22/24)

     GRAPHICS(3)                                           GRAPHICS(3)

          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 {

     Page 2                       Plan 9            (printed 12/22/24)

     GRAPHICS(3)                                           GRAPHICS(3)

                     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 rectan-
          gles have no points in common.  Thus, max contains the coor-
          dinates 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 con-
          taining 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 dis-
          tance 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;

     Page 3                       Plan 9            (printed 12/22/24)

     GRAPHICS(3)                                           GRAPHICS(3)

          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 win-
          dow), 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 dis-
          play 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 con-
          taining 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 describ-
          ing 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 pro-
          tected 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

     Page 4                       Plan 9            (printed 12/22/24)

     GRAPHICS(3)                                           GRAPHICS(3)

          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 win-
          dow 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 unfortu-
          nate historical accident.)  Getwindow arranges that screen
          point to the portion of the window inside the border;
          sophisticated clients may use _screen to make further sub-
          windows.  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 den-
          sities, 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 appropri-
          ately.

          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 posi-
          tion p, provided (if in a window) that the requesting pro-
          gram is executing in the current window and the mouse is
          within the window boundaries; otherwise cursorset is a no-

     Page 5                       Plan 9            (printed 12/22/24)

     GRAPHICS(3)                                           GRAPHICS(3)

          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 immedi-
          ately.  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 pack-
          age (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 dis-
          play 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)

     Page 6                       Plan 9            (printed 12/22/24)

     GRAPHICS(3)                                           GRAPHICS(3)

                     sysfatal("resize failed: %r");

               /* now open /tmp/cons, /tmp/mouse */
               ...

     FILES
          /usr/local/plan9/font/bit    directory of fonts

     SOURCE
          /usr/local/plan9/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 diagnos-
          tics.

     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.

     Page 7                       Plan 9            (printed 12/22/24)