FRAME(2)                                                 FRAME(2)

     NAME
          frinit, frsetrects, frinittick, frclear, frcharofpt,
          frptofchar, frinsert, frdelete, frselect, frtick,
          frselectpaint, frdrawsel, frdrawsel0, frgetmouse - frames of
          text

     SYNOPSIS
          #include <u.h>
          #include <libc.h>
          #include <draw.h>
          #include <thread.h>
          #include <mouse.h>
          #include <frame.h>

          void  frinit(Frame *f, Rectangle r, Font *ft, Image *b, Image **cols)

          void  frsetrects(Frame *f, Rectangle r, Image *b)

          void  frinittick(Frame *f)

          void  frclear(Frame *f, int resize)

          ulong frcharofpt(Frame *f, Point pt)

          Point frptofchar(Frame *f, ulong p)

          void  frinsert(Frame *f, Rune *r0, Rune *r1, ulong p)

          int   frdelete(Frame *f, ulong p0, ulong p1)

          void  frselect(Frame *f, Mousectl *m)

          void  frtick(Frame *f, Point pt, int up)

          void  frselectpaint(Frame *f, Point p0, Point p1, Image *col)

          void  frdrawsel(Frame *f, Point pt0, ulong p0, ulong p1,
                    int highlighted)

          void  frdrawsel0(Frame *f, Point pt0, ulong p0, ulong p1,
                    Image *back, Image *text)

          enum{
               BACK,
               HIGH,
               BORD,
               TEXT,
               HTEXT,
               NCOL
          };

     Page 1                       Plan 9             (printed 3/28/24)

     FRAME(2)                                                 FRAME(2)

     DESCRIPTION
          This library supports frames of editable text in a single
          font on raster displays, such as in sam(1) and rio(1).
          Frames may hold any character except NUL (0).  Long lines
          are folded and tabs are at fixed intervals.

          The user-visible data structure, a Frame, is defined in
          <frame.h>:

               typedef struct Frame Frame;
               struct Frame
               {
                     Font      *font;          /* of chars in the frame */
                     Display   *display;       /* on which frame appears */
                     Image     *b;             /* on which frame appears */
                     Image     *cols[NCOL];    /* text and background colors */
                     Rectangle r;              /* in which text appears */
                     Rectangle entire;         /* of full frame */
                     Frbox     *box;
                     ulong     p0, p1;         /* selection */
                     ushort    nbox, nalloc;
                     ushort    maxtab;         /* max size of tab, in pixels */
                     ushort    nchars;         /* # runes in frame */
                     ushort    nlines;         /* # lines with text */
                     ushort    maxlines;       /* total # lines in frame */
                     ushort    lastlinefull;   /* last line fills frame */
                     ushort    modified;       /* changed since frselect() */
                     Image     *tick;          /* typing tick */
                     Image     *tickback;      /* saved image under tick */
                     int       ticked;         /* flag: is tick onscreen? */
               };

          Frbox is an internal type and is not used by the interface.
          P0 and p1 may be changed by the application provided the
          selection routines are called afterwards to maintain a con-
          sistent display.  Maxtab determines the size of tab stops.
          Frinit sets it to 8 times the width of a 0 (zero) character
          in the font; it may be changed before any text is added to
          the frame.  The other elements of the structure are main-
          tained by the library and should not be modified directly.

          The text within frames is not directly addressable; instead
          frames are designed to work alongside another structure that
          holds the text.  The typical application is to display a
          section of a longer document such as a text file or terminal
          session.  Usually the program will keep its own copy of the
          text in the window (probably as an array of Runes) and pass
          components of this text to the frame routines to display the
          visible portion.  Only the text that is visible is held by
          the Frame; the application must check maxlines, nlines, and
          lastlinefull to determine, for example, whether new text
          needs to be appended at the end of the Frame after calling

     Page 2                       Plan 9             (printed 3/28/24)

     FRAME(2)                                                 FRAME(2)

          frdelete (q.v.).

          There are no routines in the library to allocate Frames;
          instead the interface assumes that Frames will be components
          of larger structures.  Frinit prepares the Frame f so char-
          acters drawn in it will appear in the single Font ft. It
          then calls frsetrects and frinittick to initialize the geom-
          etry for the Frame.  The Image b is where the Frame is to be
          drawn; Rectangle r defines the limit of the portion of the
          Image the text will occupy.  The Image pointer may be null,
          allowing the other routines to be called to maintain the
          associated data structure in, for example, an obscured win-
          dow.

          The array of Images cols sets the colors in which text and
          borders will be drawn.  The background of the frame will be
          drawn in cols[BACK]; the background of highlighted text in
          cols[HIGH]; borders and scroll bar in cols[BORD]; regular
          text in cols[TEXT]; and highlighted text in cols[HTEXT].

          Frclear frees the internal structures associated with f,
          permitting another frinit or frsetrects on the Frame.  It
          does not clear the associated display.  If f is to be deal-
          located, the associated Font and Image must be freed sepa-
          rately.  The resize argument should be non-zero if the frame
          is to be redrawn with a different font; otherwise the frame
          will maintain some data structures associated with the font.

          To resize a Frame, use frclear and frinit and then frinsert
          (q.v.) to recreate the display.  If a Frame is being moved
          but not resized, that is, if the shape of its containing
          rectangle is unchanged, it is sufficient to use draw(2) to
          copy the containing rectangle from the old to the new loca-
          tion and then call frsetrects to establish the new geometry.
          (It is unnecessary to call frinittick unless the font size
          has changed.)  No redrawing is necessary.

          Frames hold text as runes, not as bytes.  Frptofchar returns
          the location of the upper left corner of the p'th rune,
          starting from 0, in the Frame f. If f holds fewer than p
          runes, frptofchar returns the location of the upper right
          corner of the last character in f. Frcharofpt is the
          inverse: it returns the index of the closest rune whose
          image's upper left corner is up and to the left of pt.

          Frinsert inserts into Frame f starting at rune index p the
          runes between r0 and r1. If a NUL (0) character is inserted,
          chaos will ensue.  Tabs and newlines are handled by the
          library, but all other characters, including control charac-
          ters, are just displayed.  For example, backspaces are
          printed; to erase a character, use frdelete.

     Page 3                       Plan 9             (printed 3/28/24)

     FRAME(2)                                                 FRAME(2)

          Frdelete deletes from the Frame the text between p0 and p1;
          p1 points at the first rune beyond the deletion.

          Frselect tracks the mouse to select a contiguous string of
          text in the Frame.  When called, a mouse button is typically
          down.  Frselect will return when the button state has
          changed (some buttons may still be down) and will set f->p0
          and f->p1 to the selected range of text.

          Programs that wish to manage the selection themselves have
          several routines to help.  They involve the maintenance of
          the `tick', the vertical line indicating a null selection
          between characters, and the colored region representing a
          non-null selection.  Frtick draws (if up is non-zero) or
          removes (if up is zero) the tick at the screen position
          indicated by pt. Frdrawsel repaints a section of the frame,
          delimited by character positions p0 and p1, either with
          plain background or entirely highlighted, according to the
          flag highlighted, managing the tick appropriately.  The
          point pt0 is the geometrical location of p0 on the screen;
          like all of the selection-helper routines' Point arguments,
          it must be a value generated by frptofchar. Frdrawsel0 is a
          lower-level routine, taking as arguments a background color,
          back, and text color, text. It assumes that the tick is
          being handled (removed beforehand, replaced afterwards, as
          required) by its caller.  Frselectpaint uses a solid color,
          col, to paint a region of the frame defined by the Points p0
          and p1.

     SOURCE
          /sys/src/libframe

     SEE ALSO
          graphics(2), draw(2), cachechars(2).

     Page 4                       Plan 9             (printed 3/28/24)