term% ls -F
term% cat index.txt
PLINIT(2)                     System Calls Manual                    PLINIT(2)

       Panel, Rtext, plpack, plmove, pldraw, plfree, plgrabkb, plkeyboard, pl‐
       mouse, plscroll, plentryval, plsetbutton, plsetslider, pleget,  plelen,
       plegetsel,   plepaste,  plesel,  plescroll,  plgetscroll,  plsetscroll,
       plplacelabel,  plrtstr,  plrtbitmap,  plrtpanel,  plrtfree,   plgetpos‐
       textview, plsetpostextview - Panel manipulation functions

       #include <u.h>
       #include <libg.h>
       #include <panel.h>

       int plinit(int ldepth)

       int plpack(Panel *p, Rectangle r)

       void plmove(Panel *p, Point loc)

       void pldraw(Panel *p, Bitmap *b)

       void plfree(Panel *p)

       void plgrabkb(Panel *p)

       void plkeyboard(Rune c)

       void plmouse(Panel *p, Mouse m)

       void plscroll(Panel *scrollee, Panel *xscroller, Panel *yscroller)

       char *plentryval(Panel *entry)

       void plsetbutton(Panel *button, int value)

       void plsetslider(Panel *slider, int value, int range)

       Rune *pleget(Panel *edit)

       int plelen(Panel *edit)

       void plegetsel(Panel *edit, int *start, int *end)

       void plepaste(Panel *edit, Rune *text, int ntext)

       void plesel(Panel *edit, int start, int end)

       void plescroll(Panel *edit, int index)

       Scroll plgetscroll(Panel *p)

       void plsetscroll(Panel *p, Scroll s)

       void plplacelabel(Panel *p, int loc)

       Rtext *plrtstr(Rtext **head, int space, int indent,
                      Font *font, char *str, int hot, void *user)

       Rtext *plrtbitmap(Rtext **head, int space, int indent,
                         Bitmap *image, int hot, void *user)

       Rtext *plrtpanel(Rtext **head, int space, int indent,
                        Panel *panel, int hot, void *user)

       void plrtfree(Rtext *text)

       Rtext *plgetpostextview(Panel *view)

       void plsetpostextview(Panel *view, Rtext *text)

       The panel library assists in making simple graphical control panels for
       interactive applications.  As drawn on the screen, a panel is a collec‐
       tion  of  nested rectangles with things drawn in them, representing la‐
       bels, buttons, editable text displays, scroll bars, and other user  in‐
       terface  features.   Corresponding  to  the  nest of boxes is a tree of
       Panel structures.  A node's children are drawn nested inside their par‐
       ent.  The publicly visible part of a Panel structure looks like this

              typedef struct Panel Panel;
              struct Panel{
                   Point ipad, pad; /* extra space inside and outside */
                   Point fixedsize; /* size of Panel, if FIXED */
                   int user;        /* available for user */
                   void *userp;     /* available for user */
                   Rectangle r;     /* where the Panel goes */
                   ...              /* more private fields follow */

       Rectangle  r  is  the  box containing this Panel node and its children.
       Its value is computed by plpack.  The user and  userp  fields  are  not
       used by the panel library.  They are provided so that user code can at‐
       tach data to a Panel node.  The Points ipad, pad, and fixedsize may  be
       set by user code and are examined by plpack.

       This  manual  page  catalogs those panel library functions not directly
       concerned with creating or reinitializing Panel data  structures.   See
       plbutton(2)  and  plinitbutton(2) for those.  The Panel library memo in
       Volume 2 of this manual contains a more detailed description  of  these
       functions, illustrated with examples.

       The plinit function initializes panel library data structures.  Its ar‐
       gument is the ldepth of the bitmaps on which panels will be drawn.  The
       panel  library  draws  things differently on one-bit and multi-bit-per-
       pixel displays.

       There is usually no need to specify exact sizes and screen locations of
       Panel nodes.

       Screen layout is computed by plpack, whose arguments are a pointer to a
       Panel tree and a Rectangle in which the layout should fit.  Plpack  re‐
       turns  1  if  it  could  fit everything into the rectangle, and 0 if it
       could not.  Briefly, plpack processes a Panel tree in two passes.   The
       first,  bottom-up  pass  computes the amount of space required to house
       the children of each panel.  The second pass proceeds top-down and  di‐
       vides  the  space  available  to  each panel among its children.  Every
       Panel has some minimum space requirement — for example, a  button  must
       be  big  enough to fit its label inside its border, and a group must be
       large enough to hold its children.  Space is  allocated  to  a  Panel's
       children  in eldest to youngest order by slicing an appropriately sized
       piece off one of the four sides of the available rectangle.  Each Panel
       has  a  flag  word  (specified  when  the Panel is created — see plbut‐
       ton(2)), one of whose fields can have the value PACKN, PACKE, PACKS  or
       PACKW  (default  PACKN),  specifying  from which side to cut the piece.
       Other flags are:

              The rectangle that plpack slices off for a Panel may  be  larger
              than the Panel needs.  For example, if a small button with PACKW
              set is packed inside a large rectangle, plpack will slice off  a
              piece  that fits snugly in the x direction, but that will likely
              be too big in the y direction.  Specifying  instead  PACKW|FILLY
              will grow the button in the y direction to fill the extra space.

              If  a  Panel  is not expanded to fill the slack, these flags can
              specify where in the available space to place it.   The  default
              is  PLACECEN, which centers the panel in the space allocated for
              it.  The other PLACE flags place the Panel at one of  the  eight
              compass points.

              A user's code can override whatever size calculation plpack per‐
              forms by setting the FIXED flag  and  storing  a  value  in  the
              Panel's fixedsize field.  FIXED is the conjunction of FIXEDX and
              FIXEDY, which fix a Panel's horizontal and vertical extent inde‐

       MAXX MAXY
              If  either  of  these  flags is set, the Panel's x or y size re‐
              quirement is increased to be equal to that of its  largest  sib‐

       Once a Panel tree is packed, it can be moved to a different location by
       calling plmove, whose arguments are the panel to be moved and the upper
       left-hand corner of its destination.

       Pldraw  displays  its  Panel  argument in the given Bitmap.  Since each
       Panel's children are drawn nested inside it, programs  can  do  partial
       screen  updates  by  calling  pldraw on interior nodes of a Panel tree.
       For example, after calling plinitlabel to change the text of  a  label,
       calling pldraw on the label will redisplay it, without having to update
       the rest of the display.  An application that wishes to discard a Panel
       tree should pass it to plfree to release the storage.

       Three functions control how a Panel processes mouse and keyboard input:

              takes  two  arguments,  a Panel pointer and a Mouse structure as
              returned by emouse (see  event(2)).   Plmouse  determines  which
              node  of the Panel tree should receive the mouse event and calls
              panel-specific code to process the event.  That code may in turn
              call  back  to  user-supplied functions to register button hits,
              slider movement, etc.  Hit routines are generally specified when
              panel-creation functions are called.

              takes one argument, a pointer to a Panel to which keyboard input
              should be directed.  We say that this panel ``has  the  keyboard
              focus.''   Passing  a null pointer to plgrabkb causes subsequent
              keyboard input to be ignored.

              takes one argument, a Rune, presumably obtained from ekbd or its
              equivalent  and  sends it to the panel that has the keyboard fo‐
              cus, if any.

       Programs that use scroll  bars  created  with  plscrollbar  to  control
       scrollable  panels  (currently  pledit,  pllist, and pltextview panels)
       must call plscroll to indicate to the panel library  which  scroll  bar
       adjusts  which  panel.  Its arguments are three pointers to panels: the
       panel to be scrolled, the panel that scrolls it in the x direction, and
       the panel that scrolls it in the y direction.  Either of the latter two
       may be null, indicating no control in  that  direction.   Currently  no
       panel responds to scrolling in x; that option is for future expansion.

       The  rest  of  the functions test or set values hidden in certain Panel
       types or perform other miscellaneous manipulations such as  saving  and
       restoring scroll points.

       The  plentryval  entry  returns  a pointer to the string entered into a
       plentry panel (q.v.).  Its argument is the panel in question.

       Plsetbutton takes two arguments.  The first must point to a plcheckbut‐
       ton  or  plradiobutton panel.  The function sets or clears the button's
       checkmark, depending on whether its second argument is 0 or 1.

       Plsetslider adjusts the position of the  slider,  its  first  argument.
       The  value argument gives the setting, in units such that the range ar‐
       gument gives full scale.  For example

              plsetslider(s, 50, 100);
              plsetslider(s, 1, 2);
              plsetslider(s, 17, 34);

       each set slider s to the 50% mark.

       The following functions all manipulate the editable text panels created
       by pledit.  The first argument of each is a pointer to the edit panel.

       pleget returns  a pointer to an array of Runes containing the edit win‐
              dow's text.

       plelen returns the number of Runes in the text.

              stores in *start and *end the endpoints  of  the  edit  window's
              current selection.

              replaces the current selection with the text pointed to by text,
              whose length is ntext Runes.

       plesel sets the endpoints of the selection to start and end.

              scrolls the edit window so that the  line  containing  the  Rune
              with the given index is at the top of the screen.

       The  arguments of plplacelabel are a pointer to a pllabel panel and one
       CENW,  PLACESE, or PLACESW.  This function indicates where in the space
       allocated for the label the label's text should be drawn.  The text  is
       centered by default.

       The  argument  of  plgetscroll should point to a scrollable Panel.  The
       return value is a magic cookie (of type Scroll) that indicates where it
       is  scrolled  to.   When the panel pointer and the cookie are passed to
       plsetscroll, it will scroll the panel back to the place it was at  when
       plgetscroll  was  called.  The magic cookie encodes the scroll position
       on a percentage basis, so all bets are off if the contents of the panel
       are different at the calls to plgetscroll and plsetscroll.

       Plgetpostextview  and  plsetpostextview perform a similar function, but
       they only work on pltextview panels.  However,  since  plgetpostextview
       returns a pointer to the Rtext that is displayed in the upper left-hand
       corner of the panel and plsetpostextview scrolls the given  Rtext  back
       to  the upper left-hand corner, the caveat mentioned above does not ap‐

       Finally, there is a group of functions that create the Rtext lists that
       are displayed by pltextview panels.  Line breaks can occur only between
       the members of an Rtext list.  An individual Rtext structure  describes
       a  bitmap,  or  a string of text to be drawn in a single call to string
       (see bitblt(2)), or a Panel to be drawn inline.  The  publicly  visible
       parts of an Rtext look like this:

              typedef struct Rtext Rtext;
              struct Rtext{
                   int hot;     /* responds to hits? */
                   void *user;  /* user data */
                   int space;   /* how much space before, if no break */
                   int indent;  /* how much space before, after a break */
                   Bitmap *b;   /* what to display, if nonzero */
                   Panel *p;    /* what to display, if nonzero and b==0 */
                   Font *font;  /* font in which to draw text */
                   char *text;  /* what to display, if b==0 and p==0 */
                   Rtext *next; /* next piece */
                   ...          /* more private fields follow */

       The fields are:

       hot    indicates whether or not this Rtext is sensitive to mouse hits.

       user   points  to  user  data not used by the panel library.  User code
              may use this pointer to annotate an Rtext.

       space  how much space to leave to the left of this Rtext if it  appears
              on  the  same line as the previous one.  To allow the display of
              words with internal font changes, if space is zero,  there  will
              never be a line break between this Rtext and the previous one.

       indent How  much space to leave between this Rtext and the left margin,
              if it is the first one on the line.

       b      a bitmap to be displayed, if non-null.

       p      a panel to be displayed, if non-null and b==0.

       font   the font in which text is to be drawn.

       text   the string to be displayed, if b==0 and p==0.

       next   the next Rtext on the list.

       The functions plrtstr, plrtbitmap, and plrtpanel  create  nodes  in  an
       Rtext  list,  returning  a  pointer to the newly created node.  For all
       three functions, the space, indent, hot, and user arguments  initialize
       the  corresponding  field of the Rtext, and head points to a pointer to
       the head of the list, which the functions  will  update  appropriately.
       The pointer in *head should be initialized to a null pointer before the
       first call to any of these functions.

       The plrtfree function will dispose of a Rtext list that  is  no  longer
       needed.   The  user's  code  is responsible for discarding any strings,
       bitmaps, panels, or user data that the list may point to.


       plbutton(2), plinitbutton(2), graphics(2)
       Tom Duff, ``A quick introduction to the panel library''.