]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - misc/ncurses-intro.doc
ncurses 5.1
[ncurses.git] / misc / ncurses-intro.doc
diff --git a/misc/ncurses-intro.doc b/misc/ncurses-intro.doc
deleted file mode 100644 (file)
index e45ca35..0000000
+++ /dev/null
@@ -1,2530 +0,0 @@
-
-                         Writing Programs with NCURSES
-                                       
-     by Eric S. Raymond and Zeyd M. Ben-Halim
-     updates since release 1.9.9e by Thomas Dickey
-     
-                                   Contents
-                                       
-     * Introduction
-          + A Brief History of Curses
-          + Scope of This Document
-          + Terminology
-     * The Curses Library
-          + An Overview of Curses
-               o Compiling Programs using Curses
-               o Updating the Screen
-               o Standard Windows and Function Naming Conventions
-               o Variables
-          + Using the Library
-               o Starting up
-               o Output
-               o Input
-               o Using Forms Characters
-               o Character Attributes and Color
-               o Mouse Interfacing
-               o Finishing Up
-          + Function Descriptions
-               o Initialization and Wrapup
-               o Causing Output to the Terminal
-               o Low-Level Capability Access
-               o Debugging
-          + Hints, Tips, and Tricks
-               o Some Notes of Caution
-               o Temporarily Leaving ncurses Mode
-               o Using ncurses under xterm
-               o Handling Multiple Terminal Screens
-               o Testing for Terminal Capabilities
-               o Tuning for Speed
-               o Special Features of ncurses
-          + Compatibility with Older Versions
-               o Refresh of Overlapping Windows
-               o Background Erase
-          + XSI Curses Conformance
-     * The Panels Library
-          + Compiling With the Panels Library
-          + Overview of Panels
-          + Panels, Input, and the Standard Screen
-          + Hiding Panels
-          + Miscellaneous Other Facilities
-     * The Menu Library
-          + Compiling with the menu Library
-          + Overview of Menus
-          + Selecting items
-          + Menu Display
-          + Menu Windows
-          + Processing Menu Input
-          + Miscellaneous Other Features
-     * The Forms Library
-          + Compiling with the forms Library
-          + Overview of Forms
-          + Creating and Freeing Fields and Forms
-          + Fetching and Changing Field Attributes
-               o Fetching Size and Location Data
-               o Changing the Field Location
-               o The Justification Attribute
-               o Field Display Attributes
-               o Field Option Bits
-               o Field Status
-               o Field User Pointer
-          + Variable-Sized Fields
-          + Field Validation
-               o TYPE_ALPHA
-               o TYPE_ALNUM
-               o TYPE_ENUM
-               o TYPE_INTEGER
-               o TYPE_NUMERIC
-               o TYPE_REGEXP
-          + Direct Field Buffer Manipulation
-          + Attributes of Forms
-          + Control of Form Display
-          + Input Processing in the Forms Driver
-               o Page Navigation Requests
-               o Inter-Field Navigation Requests
-               o Intra-Field Navigation Requests
-               o Scrolling Requests
-               o Field Editing Requests
-               o Order Requests
-               o Application Commands
-          + Field Change Hooks
-          + Field Change Commands
-          + Form Options
-          + Custom Validation Types
-               o Union Types
-               o New Field Types
-               o Validation Function Arguments
-               o Order Functions For Custom Types
-               o Avoiding Problems
-     _________________________________________________________________
-   
-                                 Introduction
-                                       
-   This document is an introduction to programming with curses. It is not
-   an exhaustive reference for the curses Application Programming
-   Interface (API); that role is filled by the curses manual pages.
-   Rather, it is intended to help C programmers ease into using the
-   package.
-   
-   This document is aimed at C applications programmers not yet
-   specifically familiar with ncurses. If you are already an experienced
-   curses programmer, you should nevertheless read the sections on Mouse
-   Interfacing, Debugging, Compatibility with Older Versions, and Hints,
-   Tips, and Tricks. These will bring you up to speed on the special
-   features and quirks of the ncurses implementation. If you are not so
-   experienced, keep reading.
-   
-   The curses package is a subroutine library for terminal-independent
-   screen-painting and input-event handling which presents a high level
-   screen model to the programmer, hiding differences between terminal
-   types and doing automatic optimization of output to change one screen
-   full of text into another. Curses uses terminfo, which is a database
-   format that can describe the capabilities of thousands of different
-   terminals.
-   
-   The curses API may seem something of an archaism on UNIX desktops
-   increasingly dominated by X, Motif, and Tcl/Tk. Nevertheless, UNIX
-   still supports tty lines and X supports xterm(1); the curses API has
-   the advantage of (a) back-portability to character-cell terminals, and
-   (b) simplicity. For an application that does not require bit-mapped
-   graphics and multiple fonts, an interface implementation using curses
-   will typically be a great deal simpler and less expensive than one
-   using an X toolkit.
-   
-A Brief History of Curses
-
-   Historically, the first ancestor of curses was the routines written to
-   provide screen-handling for the game rogue; these used the
-   already-existing termcap database facility for describing terminal
-   capabilities. These routines were abstracted into a documented library
-   and first released with the early BSD UNIX versions.
-   
-   System III UNIX from Bell Labs featured a rewritten and much-improved
-   curses library. It introduced the terminfo format. Terminfo is based
-   on Berkeley's termcap database, but contains a number of improvements
-   and extensions. Parameterized capabilities strings were introduced,
-   making it possible to describe multiple video attributes, and colors
-   and to handle far more unusual terminals than possible with termcap.
-   In the later AT&T System V releases, curses evolved to use more
-   facilities and offer more capabilities, going far beyond BSD curses in
-   power and flexibility.
-   
-Scope of This Document
-
-   This document describes ncurses, a free implementation of the System V
-   curses API with some clearly marked extensions. It includes the
-   following System V curses features:
-   
-     * Support for multiple screen highlights (BSD curses could only
-       handle one `standout' highlight, usually reverse-video).
-     * Support for line- and box-drawing using forms characters.
-     * Recognition of function keys on input.
-     * Color support.
-     * Support for pads (windows of larger than screen size on which the
-       screen or a subwindow defines a viewport).
-       
-   Also, this package makes use of the insert and delete line and
-   character features of terminals so equipped, and determines how to
-   optimally use these features with no help from the programmer. It
-   allows arbitrary combinations of video attributes to be displayed,
-   even on terminals that leave ``magic cookies'' on the screen to mark
-   changes in attributes.
-   
-   The ncurses package can also capture and use event reports from a
-   mouse in some environments (notably, xterm under the X window system).
-   This document includes tips for using the mouse.
-   
-   The ncurses package was originated by Pavel Curtis. The original
-   maintainer of this package is Zeyd Ben-Halim <zmbenhal@netcom.com>.
-   Eric S. Raymond <esr@snark.thyrsus.com> wrote many of the new features
-   in versions after 1.8.1 and wrote most of this introduction. Jürgen
-   Pfeifer wrote all of the menu and forms code as well as the Ada95
-   binding. Ongoing work is being done by Thomas Dickey and Jürgen
-   Pfeifer. Florian La Roche acts as the maintainer for the Free Software
-   Foundation, which holds the copyright on ncurses. Contact the current
-   maintainers at bug-ncurses@gnu.org.
-   
-   This document also describes the panels extension library, similarly
-   modeled on the SVr4 panels facility. This library allows you to
-   associate backing store with each of a stack or deck of overlapping
-   windows, and provides operations for moving windows around in the
-   stack that change their visibility in the natural way (handling window
-   overlaps).
-   
-   Finally, this document describes in detail the menus and forms
-   extension libraries, also cloned from System V, which support easy
-   construction and sequences of menus and fill-in forms.
-   
-Terminology
-
-   In this document, the following terminology is used with reasonable
-   consistency:
-   
-   window
-          A data structure describing a sub-rectangle of the screen
-          (possibly the entire screen). You can write to a window as
-          though it were a miniature screen, scrolling independently of
-          other windows on the physical screen.
-          
-   screens
-          A subset of windows which are as large as the terminal screen,
-          i.e., they start at the upper left hand corner and encompass
-          the lower right hand corner. One of these, stdscr, is
-          automatically provided for the programmer.
-          
-   terminal screen
-          The package's idea of what the terminal display currently looks
-          like, i.e., what the user sees now. This is a special screen.
-          
-                              The Curses Library
-                                       
-An Overview of Curses
-
-  Compiling Programs using Curses
-  
-   In order to use the library, it is necessary to have certain types and
-   variables defined. Therefore, the programmer must have a line:
-          #include <curses.h>
-
-   at the top of the program source. The screen package uses the Standard
-   I/O library, so <curses.h> includes <stdio.h>. <curses.h> also
-   includes <termios.h>, <termio.h>, or <sgtty.h> depending on your
-   system. It is redundant (but harmless) for the programmer to do these
-   includes, too. In linking with curses you need to have -lncurses in
-   your LDFLAGS or on the command line. There is no need for any other
-   libraries.
-   
-  Updating the Screen
-  
-   In order to update the screen optimally, it is necessary for the
-   routines to know what the screen currently looks like and what the
-   programmer wants it to look like next. For this purpose, a data type
-   (structure) named WINDOW is defined which describes a window image to
-   the routines, including its starting position on the screen (the (y,
-   x) coordinates of the upper left hand corner) and its size. One of
-   these (called curscr, for current screen) is a screen image of what
-   the terminal currently looks like. Another screen (called stdscr, for
-   standard screen) is provided by default to make changes on.
-   
-   A window is a purely internal representation. It is used to build and
-   store a potential image of a portion of the terminal. It doesn't bear
-   any necessary relation to what is really on the terminal screen; it's
-   more like a scratchpad or write buffer.
-   
-   To make the section of physical screen corresponding to a window
-   reflect the contents of the window structure, the routine refresh()
-   (or wrefresh() if the window is not stdscr) is called.
-   
-   A given physical screen section may be within the scope of any number
-   of overlapping windows. Also, changes can be made to windows in any
-   order, without regard to motion efficiency. Then, at will, the
-   programmer can effectively say ``make it look like this,'' and let the
-   package implementation determine the most efficient way to repaint the
-   screen.
-   
-  Standard Windows and Function Naming Conventions
-  
-   As hinted above, the routines can use several windows, but two are
-   automatically given: curscr, which knows what the terminal looks like,
-   and stdscr, which is what the programmer wants the terminal to look
-   like next. The user should never actually access curscr directly.
-   Changes should be made to through the API, and then the routine
-   refresh() (or wrefresh()) called.
-   
-   Many functions are defined to use stdscr as a default screen. For
-   example, to add a character to stdscr, one calls addch() with the
-   desired character as argument. To write to a different window. use the
-   routine waddch() (for `w'indow-specific addch()) is provided. This
-   convention of prepending function names with a `w' when they are to be
-   applied to specific windows is consistent. The only routines which do
-   not follow it are those for which a window must always be specified.
-   
-   In order to move the current (y, x) coordinates from one point to
-   another, the routines move() and wmove() are provided. However, it is
-   often desirable to first move and then perform some I/O operation. In
-   order to avoid clumsiness, most I/O routines can be preceded by the
-   prefix 'mv' and the desired (y, x) coordinates prepended to the
-   arguments to the function. For example, the calls
-          move(y, x);
-          addch(ch);
-
-   can be replaced by
-          mvaddch(y, x, ch);
-
-   and
-          wmove(win, y, x);
-          waddch(win, ch);
-
-   can be replaced by
-          mvwaddch(win, y, x, ch);
-
-   Note that the window description pointer (win) comes before the added
-   (y, x) coordinates. If a function requires a window pointer, it is
-   always the first parameter passed.
-   
-  Variables
-  
-   The curses library sets some variables describing the terminal
-   capabilities.
-      type   name      description
-      ------------------------------------------------------------------
-      int    LINES     number of lines on the terminal
-      int    COLS      number of columns on the terminal
-
-   The curses.h also introduces some #define constants and types of
-   general usefulness:
-   
-   bool
-          boolean type, actually a `char' (e.g., bool doneit;)
-          
-   TRUE
-          boolean `true' flag (1).
-          
-   FALSE
-          boolean `false' flag (0).
-          
-   ERR
-          error flag returned by routines on a failure (-1).
-          
-   OK
-          error flag returned by routines when things go right.
-          
-Using the Library
-
-   Now we describe how to actually use the screen package. In it, we
-   assume all updating, reading, etc. is applied to stdscr. These
-   instructions will work on any window, providing you change the
-   function names and parameters as mentioned above.
-   
-   Here is a sample program to motivate the discussion:
-   
-#include <curses.h>
-#include <signal.h>
-
-static void finish(int sig);
-
-main(int argc, char *argv[])
-{
-    /* initialize your non-curses data structures here */
-
-    (void) signal(SIGINT, finish);      /* arrange interrupts to terminate */
-
-    (void) initscr();      /* initialize the curses library */
-    keypad(stdscr, TRUE);  /* enable keyboard mapping */
-    (void) nonl();         /* tell curses not to do NL->CR/NL on output */
-    (void) cbreak();       /* take input chars one at a time, no wait for \n */
-    (void) noecho();       /* don't echo input */
-
-    if (has_colors())
-    {
-        start_color();
-
-        /*
-         * Simple color assignment, often all we need.
-         */
-        init_pair(COLOR_BLACK, COLOR_BLACK, COLOR_BLACK);
-        init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK);
-        init_pair(COLOR_RED, COLOR_RED, COLOR_BLACK);
-        init_pair(COLOR_CYAN, COLOR_CYAN, COLOR_BLACK);
-        init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK);
-        init_pair(COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
-        init_pair(COLOR_BLUE, COLOR_BLUE, COLOR_BLACK);
-        init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK);
-    }
-
-    for (;;)
-    {
-        int c = getch();     /* refresh, accept single keystroke of input */
-
-        /* process the command keystroke */
-    }
-
-    finish(0);               /* we're done */
-}
-
-static void finish(int sig)
-{
-    endwin();
-
-    /* do your non-curses wrapup here */
-
-    exit(0);
-}
-
-  Starting up
-  
-   In order to use the screen package, the routines must know about
-   terminal characteristics, and the space for curscr and stdscr must be
-   allocated. These function initscr() does both these things. Since it
-   must allocate space for the windows, it can overflow memory when
-   attempting to do so. On the rare occasions this happens, initscr()
-   will terminate the program with an error message. initscr() must
-   always be called before any of the routines which affect windows are
-   used. If it is not, the program will core dump as soon as either
-   curscr or stdscr are referenced. However, it is usually best to wait
-   to call it until after you are sure you will need it, like after
-   checking for startup errors. Terminal status changing routines like
-   nl() and cbreak() should be called after initscr().
-   
-   Once the screen windows have been allocated, you can set them up for
-   your program. If you want to, say, allow a screen to scroll, use
-   scrollok(). If you want the cursor to be left in place after the last
-   change, use leaveok(). If this isn't done, refresh() will move the
-   cursor to the window's current (y, x) coordinates after updating it.
-   
-   You can create new windows of your own using the functions newwin(),
-   derwin(), and subwin(). The routine delwin() will allow you to get rid
-   of old windows. All the options described above can be applied to any
-   window.
-   
-  Output
-  
-   Now that we have set things up, we will want to actually update the
-   terminal. The basic functions used to change what will go on a window
-   are addch() and move(). addch() adds a character at the current (y, x)
-   coordinates. move() changes the current (y, x) coordinates to whatever
-   you want them to be. It returns ERR if you try to move off the window.
-   As mentioned above, you can combine the two into mvaddch() to do both
-   things at once.
-   
-   The other output functions, such as addstr() and printw(), all call
-   addch() to add characters to the window.
-   
-   After you have put on the window what you want there, when you want
-   the portion of the terminal covered by the window to be made to look
-   like it, you must call refresh(). In order to optimize finding
-   changes, refresh() assumes that any part of the window not changed
-   since the last refresh() of that window has not been changed on the
-   terminal, i.e., that you have not refreshed a portion of the terminal
-   with an overlapping window. If this is not the case, the routine
-   touchwin() is provided to make it look like the entire window has been
-   changed, thus making refresh() check the whole subsection of the
-   terminal for changes.
-   
-   If you call wrefresh() with curscr as its argument, it will make the
-   screen look like curscr thinks it looks like. This is useful for
-   implementing a command which would redraw the screen in case it get
-   messed up.
-   
-  Input
-  
-   The complementary function to addch() is getch() which, if echo is
-   set, will call addch() to echo the character. Since the screen package
-   needs to know what is on the terminal at all times, if characters are
-   to be echoed, the tty must be in raw or cbreak mode. Since initially
-   the terminal has echoing enabled and is in ordinary ``cooked'' mode,
-   one or the other has to changed before calling getch(); otherwise, the
-   program's output will be unpredictable.
-   
-   When you need to accept line-oriented input in a window, the functions
-   wgetstr() and friends are available. There is even a wscanw() function
-   that can do scanf()(3)-style multi-field parsing on window input.
-   These pseudo-line-oriented functions turn on echoing while they
-   execute.
-   
-   The example code above uses the call keypad(stdscr, TRUE) to enable
-   support for function-key mapping. With this feature, the getch() code
-   watches the input stream for character sequences that correspond to
-   arrow and function keys. These sequences are returned as
-   pseudo-character values. The #define values returned are listed in the
-   curses.h The mapping from sequences to #define values is determined by
-   key_ capabilities in the terminal's terminfo entry.
-   
-  Using Forms Characters
-  
-   The addch() function (and some others, including box() and border())
-   can accept some pseudo-character arguments which are specially defined
-   by ncurses. These are #define values set up in the curses.h header;
-   see there for a complete list (look for the prefix ACS_).
-   
-   The most useful of the ACS defines are the forms-drawing characters.
-   You can use these to draw boxes and simple graphs on the screen. If
-   the terminal does not have such characters, curses.h will map them to
-   a recognizable (though ugly) set of ASCII defaults.
-   
-  Character Attributes and Color
-  
-   The ncurses package supports screen highlights including standout,
-   reverse-video, underline, and blink. It also supports color, which is
-   treated as another kind of highlight.
-   
-   Highlights are encoded, internally, as high bits of the
-   pseudo-character type (chtype) that curses.h uses to represent the
-   contents of a screen cell. See the curses.h header file for a complete
-   list of highlight mask values (look for the prefix A_).
-   
-   There are two ways to make highlights. One is to logical-or the value
-   of the highlights you want into the character argument of an addch()
-   call, or any other output call that takes a chtype argument.
-   
-   The other is to set the current-highlight value. This is logical-or'ed
-   with any highlight you specify the first way. You do this with the
-   functions attron(), attroff(), and attrset(); see the manual pages for
-   details. Color is a special kind of highlight. The package actually
-   thinks in terms of color pairs, combinations of foreground and
-   background colors. The sample code above sets up eight color pairs,
-   all of the guaranteed-available colors on black. Note that each color
-   pair is, in effect, given the name of its foreground color. Any other
-   range of eight non-conflicting values could have been used as the
-   first arguments of the init_pair() values.
-   
-   Once you've done an init_pair() that creates color-pair N, you can use
-   COLOR_PAIR(N) as a highlight that invokes that particular color
-   combination. Note that COLOR_PAIR(N), for constant N, is itself a
-   compile-time constant and can be used in initializers.
-   
-  Mouse Interfacing
-  
-   The ncurses library also provides a mouse interface.
-   
-     NOTE: this facility is specific to ncurses, it is not part of
-     either the XSI Curses standard, nor of System V Release 4, nor BSD
-     curses. System V Release 4 curses contains code with similar
-     interface definitions, however it is not documented. Other than by
-     disassembling the library, we have no way to determine exactly how
-     that mouse code works. Thus, we recommend that you wrap
-     mouse-related code in an #ifdef using the feature macro
-     NCURSES_MOUSE_VERSION so it will not be compiled and linked on
-     non-ncurses systems.
-     
-   Presently, mouse event reporting works in the following environments:
-     * xterm and similar programs such as rxvt.
-     * Linux console, when configured with gpm(1), Alessandro Rubini's
-       mouse server.
-     * OS/2 EMX
-       
-   The mouse interface is very simple. To activate it, you use the
-   function mousemask(), passing it as first argument a bit-mask that
-   specifies what kinds of events you want your program to be able to
-   see. It will return the bit-mask of events that actually become
-   visible, which may differ from the argument if the mouse device is not
-   capable of reporting some of the event types you specify.
-   
-   Once the mouse is active, your application's command loop should watch
-   for a return value of KEY_MOUSE from wgetch(). When you see this, a
-   mouse event report has been queued. To pick it off the queue, use the
-   function getmouse() (you must do this before the next wgetch(),
-   otherwise another mouse event might come in and make the first one
-   inaccessible).
-   
-   Each call to getmouse() fills a structure (the address of which you'll
-   pass it) with mouse event data. The event data includes zero-origin,
-   screen-relative character-cell coordinates of the mouse pointer. It
-   also includes an event mask. Bits in this mask will be set,
-   corresponding to the event type being reported.
-   
-   The mouse structure contains two additional fields which may be
-   significant in the future as ncurses interfaces to new kinds of
-   pointing device. In addition to x and y coordinates, there is a slot
-   for a z coordinate; this might be useful with touch-screens that can
-   return a pressure or duration parameter. There is also a device ID
-   field, which could be used to distinguish between multiple pointing
-   devices.
-   
-   The class of visible events may be changed at any time via
-   mousemask(). Events that can be reported include presses, releases,
-   single-, double- and triple-clicks (you can set the maximum
-   button-down time for clicks). If you don't make clicks visible, they
-   will be reported as press-release pairs. In some environments, the
-   event mask may include bits reporting the state of shift, alt, and
-   ctrl keys on the keyboard during the event.
-   
-   A function to check whether a mouse event fell within a given window
-   is also supplied. You can use this to see whether a given window
-   should consider a mouse event relevant to it.
-   
-   Because mouse event reporting will not be available in all
-   environments, it would be unwise to build ncurses applications that
-   require the use of a mouse. Rather, you should use the mouse as a
-   shortcut for point-and-shoot commands your application would normally
-   accept from the keyboard. Two of the test games in the ncurses
-   distribution (bs and knight) contain code that illustrates how this
-   can be done.
-   
-   See the manual page curs_mouse(3X) for full details of the
-   mouse-interface functions.
-   
-  Finishing Up
-  
-   In order to clean up after the ncurses routines, the routine endwin()
-   is provided. It restores tty modes to what they were when initscr()
-   was first called, and moves the cursor down to the lower-left corner.
-   Thus, anytime after the call to initscr, endwin() should be called
-   before exiting.
-   
-Function Descriptions
-
-   We describe the detailed behavior of some important curses functions
-   here, as a supplement to the manual page descriptions.
-   
-  Initialization and Wrapup
-  
-   initscr()
-          The first function called should almost always be initscr().
-          This will determine the terminal type and initialize curses
-          data structures. initscr() also arranges that the first call to
-          refresh() will clear the screen. If an error occurs a message
-          is written to standard error and the program exits. Otherwise
-          it returns a pointer to stdscr. A few functions may be called
-          before initscr (slk_init(), filter(), ripofflines(), use_env(),
-          and, if you are using multiple terminals, newterm().)
-          
-   endwin()
-          Your program should always call endwin() before exiting or
-          shelling out of the program. This function will restore tty
-          modes, move the cursor to the lower left corner of the screen,
-          reset the terminal into the proper non-visual mode. Calling
-          refresh() or doupdate() after a temporary escape from the
-          program will restore the ncurses screen from before the escape.
-          
-   newterm(type, ofp, ifp)
-          A program which outputs to more than one terminal should use
-          newterm() instead of initscr(). newterm() should be called once
-          for each terminal. It returns a variable of type SCREEN * which
-          should be saved as a reference to that terminal. The arguments
-          are the type of the terminal (a string) and FILE pointers for
-          the output and input of the terminal. If type is NULL then the
-          environment variable $TERM is used. endwin() should called once
-          at wrapup time for each terminal opened using this function.
-          
-   set_term(new)
-          This function is used to switch to a different terminal
-          previously opened by newterm(). The screen reference for the
-          new terminal is passed as the parameter. The previous terminal
-          is returned by the function. All other calls affect only the
-          current terminal.
-          
-   delscreen(sp)
-          The inverse of newterm(); deallocates the data structures
-          associated with a given SCREEN reference.
-          
-  Causing Output to the Terminal
-  
-   refresh() and wrefresh(win)
-          These functions must be called to actually get any output on
-          the terminal, as other routines merely manipulate data
-          structures. wrefresh() copies the named window to the physical
-          terminal screen, taking into account what is already there in
-          order to do optimizations. refresh() does a refresh of
-          stdscr(). Unless leaveok() has been enabled, the physical
-          cursor of the terminal is left at the location of the window's
-          cursor.
-          
-   doupdate() and wnoutrefresh(win)
-          These two functions allow multiple updates with more efficiency
-          than wrefresh. To use them, it is important to understand how
-          curses works. In addition to all the window structures, curses
-          keeps two data structures representing the terminal screen: a
-          physical screen, describing what is actually on the screen, and
-          a virtual screen, describing what the programmer wants to have
-          on the screen. wrefresh works by first copying the named window
-          to the virtual screen (wnoutrefresh()), and then calling the
-          routine to update the screen (doupdate()). If the programmer
-          wishes to output several windows at once, a series of calls to
-          wrefresh will result in alternating calls to wnoutrefresh() and
-          doupdate(), causing several bursts of output to the screen. By
-          calling wnoutrefresh() for each window, it is then possible to
-          call doupdate() once, resulting in only one burst of output,
-          with fewer total characters transmitted (this also avoids a
-          visually annoying flicker at each update).
-          
-  Low-Level Capability Access
-  
-   setupterm(term, filenum, errret)
-          This routine is called to initialize a terminal's description,
-          without setting up the curses screen structures or changing the
-          tty-driver mode bits. term is the character string representing
-          the name of the terminal being used. filenum is the UNIX file
-          descriptor of the terminal to be used for output. errret is a
-          pointer to an integer, in which a success or failure indication
-          is returned. The values returned can be 1 (all is well), 0 (no
-          such terminal), or -1 (some problem locating the terminfo
-          database).
-          
-          The value of term can be given as NULL, which will cause the
-          value of TERM in the environment to be used. The errret pointer
-          can also be given as NULL, meaning no error code is wanted. If
-          errret is defaulted, and something goes wrong, setupterm() will
-          print an appropriate error message and exit, rather than
-          returning. Thus, a simple program can call setupterm(0, 1, 0)
-          and not worry about initialization errors.
-          
-          After the call to setupterm(), the global variable cur_term is
-          set to point to the current structure of terminal capabilities.
-          By calling setupterm() for each terminal, and saving and
-          restoring cur_term, it is possible for a program to use two or
-          more terminals at once. Setupterm() also stores the names
-          section of the terminal description in the global character
-          array ttytype[]. Subsequent calls to setupterm() will overwrite
-          this array, so you'll have to save it yourself if need be.
-          
-  Debugging
-  
-     NOTE: These functions are not part of the standard curses API!
-     
-   trace()
-          This function can be used to explicitly set a trace level. If
-          the trace level is nonzero, execution of your program will
-          generate a file called `trace' in the current working directory
-          containing a report on the library's actions. Higher trace
-          levels enable more detailed (and verbose) reporting -- see
-          comments attached to TRACE_ defines in the curses.h file for
-          details. (It is also possible to set a trace level by assigning
-          a trace level value to the environment variable NCURSES_TRACE).
-          
-   _tracef()
-          This function can be used to output your own debugging
-          information. It is only available only if you link with
-          -lncurses_g. It can be used the same way as printf(), only it
-          outputs a newline after the end of arguments. The output goes
-          to a file called trace in the current directory.
-          
-   Trace logs can be difficult to interpret due to the sheer volume of
-   data dumped in them. There is a script called tracemunch included with
-   the ncurses distribution that can alleviate this problem somewhat; it
-   compacts long sequences of similar operations into more succinct
-   single-line pseudo-operations. These pseudo-ops can be distinguished
-   by the fact that they are named in capital letters.
-   
-Hints, Tips, and Tricks
-
-   The ncurses manual pages are a complete reference for this library. In
-   the remainder of this document, we discuss various useful methods that
-   may not be obvious from the manual page descriptions.
-   
-  Some Notes of Caution
-  
-   If you find yourself thinking you need to use noraw() or nocbreak(),
-   think again and move carefully. It's probably better design to use
-   getstr() or one of its relatives to simulate cooked mode. The noraw()
-   and nocbreak() functions try to restore cooked mode, but they may end
-   up clobbering some control bits set before you started your
-   application. Also, they have always been poorly documented, and are
-   likely to hurt your application's usability with other curses
-   libraries.
-   
-   Bear in mind that refresh() is a synonym for wrefresh(stdscr). Don't
-   try to mix use of stdscr with use of windows declared by newwin(); a
-   refresh() call will blow them off the screen. The right way to handle
-   this is to use subwin(), or not touch stdscr at all and tile your
-   screen with declared windows which you then wnoutrefresh() somewhere
-   in your program event loop, with a single doupdate() call to trigger
-   actual repainting.
-   
-   You are much less likely to run into problems if you design your
-   screen layouts to use tiled rather than overlapping windows.
-   Historically, curses support for overlapping windows has been weak,
-   fragile, and poorly documented. The ncurses library is not yet an
-   exception to this rule.
-   
-   There is a panels library included in the ncurses distribution that
-   does a pretty good job of strengthening the overlapping-windows
-   facilities.
-   
-   Try to avoid using the global variables LINES and COLS. Use getmaxyx()
-   on the stdscr context instead. Reason: your code may be ported to run
-   in an environment with window resizes, in which case several screens
-   could be open with different sizes.
-   
-  Temporarily Leaving NCURSES Mode
-  
-   Sometimes you will want to write a program that spends most of its
-   time in screen mode, but occasionally returns to ordinary `cooked'
-   mode. A common reason for this is to support shell-out. This behavior
-   is simple to arrange in ncurses.
-   
-   To leave ncurses mode, call endwin() as you would if you were
-   intending to terminate the program. This will take the screen back to
-   cooked mode; you can do your shell-out. When you want to return to
-   ncurses mode, simply call refresh() or doupdate(). This will repaint
-   the screen.
-   
-   There is a boolean function, isendwin(), which code can use to test
-   whether ncurses screen mode is active. It returns TRUE in the interval
-   between an endwin() call and the following refresh(), FALSE otherwise.
-   
-   Here is some sample code for shellout:
-    addstr("Shelling out...");
-    def_prog_mode();           /* save current tty modes */
-    endwin();                  /* restore original tty modes */
-    system("sh");              /* run shell */
-    addstr("returned.\n");     /* prepare return message */
-    refresh();                 /* restore save modes, repaint screen */
-
-  Using NCURSES under XTERM
-  
-   A resize operation in X sends SIGWINCH to the application running
-   under xterm. The ncurses library provides an experimental signal
-   handler, but in general does not catch this signal, because it cannot
-   know how you want the screen re-painted. You will usually have to
-   write the SIGWINCH handler yourself. Ncurses can give you some help.
-   
-   The easiest way to code your SIGWINCH handler is to have it do an
-   endwin, followed by an refresh and a screen repaint you code yourself.
-   The refresh will pick up the new screen size from the xterm's
-   environment.
-   
-   That is the standard way, of course (it even works with some vendor's
-   curses implementations). Its drawback is that it clears the screen to
-   reinitialize the display, and does not resize subwindows which must be
-   shrunk. Ncurses provides an extension which works better, the
-   resizeterm function. That function ensures that all windows are
-   limited to the new screen dimensions, and pads stdscr with blanks if
-   the screen is larger.
-   
-   Finally, ncurses can be configured to provide its own SIGWINCH
-   handler, based on resizeterm.
-   
-  Handling Multiple Terminal Screens
-  
-   The initscr() function actually calls a function named newterm() to do
-   most of its work. If you are writing a program that opens multiple
-   terminals, use newterm() directly.
-   
-   For each call, you will have to specify a terminal type and a pair of
-   file pointers; each call will return a screen reference, and stdscr
-   will be set to the last one allocated. You will switch between screens
-   with the set_term call. Note that you will also have to call
-   def_shell_mode and def_prog_mode on each tty yourself.
-   
-  Testing for Terminal Capabilities
-  
-   Sometimes you may want to write programs that test for the presence of
-   various capabilities before deciding whether to go into ncurses mode.
-   An easy way to do this is to call setupterm(), then use the functions
-   tigetflag(), tigetnum(), and tigetstr() to do your testing.
-   
-   A particularly useful case of this often comes up when you want to
-   test whether a given terminal type should be treated as `smart'
-   (cursor-addressable) or `stupid'. The right way to test this is to see
-   if the return value of tigetstr("cup") is non-NULL. Alternatively, you
-   can include the term.h file and test the value of the macro
-   cursor_address.
-   
-  Tuning for Speed
-  
-   Use the addchstr() family of functions for fast screen-painting of
-   text when you know the text doesn't contain any control characters.
-   Try to make attribute changes infrequent on your screens. Don't use
-   the immedok() option!
-   
-  Special Features of NCURSES
-  
-   The wresize() function allows you to resize a window in place. The
-   associated resizeterm() function simplifies the construction of
-   SIGWINCH handlers, for resizing all windows.
-   
-   The define_key() function allows you to define at runtime function-key
-   control sequences which are not in the terminal description. The
-   keyok() function allows you to temporarily enable or disable
-   interpretation of any function-key control sequence.
-   
-   The use_default_colors() function allows you to construct applications
-   which can use the terminal's default foreground and background colors
-   as an additional "default" color. Several terminal emulators support
-   this feature, which is based on ISO 6429.
-   
-   Ncurses supports up 16 colors, unlike SVr4 curses which defines only
-   8. While most terminals which provide color allow only 8 colors, about
-   a quarter (including XFree86 xterm) support 16 colors.
-   
-Compatibility with Older Versions
-
-   Despite our best efforts, there are some differences between ncurses
-   and the (undocumented!) behavior of older curses implementations.
-   These arise from ambiguities or omissions in the documentation of the
-   API.
-   
-  Refresh of Overlapping Windows
-  
-   If you define two windows A and B that overlap, and then alternately
-   scribble on and refresh them, the changes made to the overlapping
-   region under historic curses versions were often not documented
-   precisely.
-   
-   To understand why this is a problem, remember that screen updates are
-   calculated between two representations of the entire display. The
-   documentation says that when you refresh a window, it is first copied
-   to to the virtual screen, and then changes are calculated to update
-   the physical screen (and applied to the terminal). But "copied to" is
-   not very specific, and subtle differences in how copying works can
-   produce different behaviors in the case where two overlapping windows
-   are each being refreshed at unpredictable intervals.
-   
-   What happens to the overlapping region depends on what wnoutrefresh()
-   does with its argument -- what portions of the argument window it
-   copies to the virtual screen. Some implementations do "change copy",
-   copying down only locations in the window that have changed (or been
-   marked changed with wtouchln() and friends). Some implementations do
-   "entire copy", copying all window locations to the virtual screen
-   whether or not they have changed.
-   
-   The ncurses library itself has not always been consistent on this
-   score. Due to a bug, versions 1.8.7 to 1.9.8a did entire copy.
-   Versions 1.8.6 and older, and versions 1.9.9 and newer, do change
-   copy.
-   
-   For most commercial curses implementations, it is not documented and
-   not known for sure (at least not to the ncurses maintainers) whether
-   they do change copy or entire copy. We know that System V release 3
-   curses has logic in it that looks like an attempt to do change copy,
-   but the surrounding logic and data representations are sufficiently
-   complex, and our knowledge sufficiently indirect, that it's hard to
-   know whether this is reliable. It is not clear what the SVr4
-   documentation and XSI standard intend. The XSI Curses standard barely
-   mentions wnoutrefresh(); the SVr4 documents seem to be describing
-   entire-copy, but it is possible with some effort and straining to read
-   them the other way.
-   
-   It might therefore be unwise to rely on either behavior in programs
-   that might have to be linked with other curses implementations.
-   Instead, you can do an explicit touchwin() before the wnoutrefresh()
-   call to guarantee an entire-contents copy anywhere.
-   
-   The really clean way to handle this is to use the panels library. If,
-   when you want a screen update, you do update_panels(), it will do all
-   the necessary wnoutrfresh() calls for whatever panel stacking order
-   you have defined. Then you can do one doupdate() and there will be a
-   single burst of physical I/O that will do all your updates.
-   
-  Background Erase
-  
-   If you have been using a very old versions of ncurses (1.8.7 or older)
-   you may be surprised by the behavior of the erase functions. In older
-   versions, erased areas of a window were filled with a blank modified
-   by the window's current attribute (as set by wattrset(), wattron(),
-   wattroff() and friends).
-   
-   In newer versions, this is not so. Instead, the attribute of erased
-   blanks is normal unless and until it is modified by the functions
-   bkgdset() or wbkgdset().
-   
-   This change in behavior conforms ncurses to System V Release 4 and the
-   XSI Curses standard.
-   
-XSI Curses Conformance
-
-   The ncurses library is intended to be base-level conformant with the
-   XSI Curses standard from X/Open. Many extended-level features (in
-   fact, almost all features not directly concerned with wide characters
-   and internationalization) are also supported.
-   
-   One effect of XSI conformance is the change in behavior described
-   under "Background Erase -- Compatibility with Old Versions".
-   
-   Also, ncurses meets the XSI requirement that every macro entry point
-   have a corresponding function which may be linked (and will be
-   prototype-checked) if the macro definition is disabled with #undef.
-   
-                              The Panels Library
-                                       
-   The ncurses library by itself provides good support for screen
-   displays in which the windows are tiled (non-overlapping). In the more
-   general case that windows may overlap, you have to use a series of
-   wnoutrefresh() calls followed by a doupdate(), and be careful about
-   the order you do the window refreshes in. It has to be bottom-upwards,
-   otherwise parts of windows that should be obscured will show through.
-   
-   When your interface design is such that windows may dive deeper into
-   the visibility stack or pop to the top at runtime, the resulting
-   book-keeping can be tedious and difficult to get right. Hence the
-   panels library.
-   
-   The panel library first appeared in AT&T System V. The version
-   documented here is the panel code distributed with ncurses.
-   
-Compiling With the Panels Library
-
-   Your panels-using modules must import the panels library declarations
-   with
-          #include <panel.h>
-
-   and must be linked explicitly with the panels library using an -lpanel
-   argument. Note that they must also link the ncurses library with
-   -lncurses. Many linkers are two-pass and will accept either order, but
-   it is still good practice to put -lpanel first and -lncurses second.
-   
-Overview of Panels
-
-   A panel object is a window that is implicitly treated as part of a
-   deck including all other panel objects. The deck has an implicit
-   bottom-to-top visibility order. The panels library includes an update
-   function (analogous to refresh()) that displays all panels in the deck
-   in the proper order to resolve overlaps. The standard window, stdscr,
-   is considered below all panels.
-   
-   Details on the panels functions are available in the man pages. We'll
-   just hit the highlights here.
-   
-   You create a panel from a window by calling new_panel() on a window
-   pointer. It then becomes the top of the deck. The panel's window is
-   available as the value of panel_window() called with the panel pointer
-   as argument.
-   
-   You can delete a panel (removing it from the deck) with del_panel.
-   This will not deallocate the associated window; you have to do that
-   yourself. You can replace a panel's window with a different window by
-   calling replace_window. The new window may be of different size; the
-   panel code will re-compute all overlaps. This operation doesn't change
-   the panel's position in the deck.
-   
-   To move a panel's window, use move_panel(). The mvwin() function on
-   the panel's window isn't sufficient because it doesn't update the
-   panels library's representation of where the windows are. This
-   operation leaves the panel's depth, contents, and size unchanged.
-   
-   Two functions (top_panel(), bottom_panel()) are provided for
-   rearranging the deck. The first pops its argument window to the top of
-   the deck; the second sends it to the bottom. Either operation leaves
-   the panel's screen location, contents, and size unchanged.
-   
-   The function update_panels() does all the wnoutrefresh() calls needed
-   to prepare for doupdate() (which you must call yourself, afterwards).
-   
-   Typically, you will want to call update_panels() and doupdate() just
-   before accepting command input, once in each cycle of interaction with
-   the user. If you call update_panels() after each and every panel
-   write, you'll generate a lot of unnecessary refresh activity and
-   screen flicker.
-   
-Panels, Input, and the Standard Screen
-
-   You shouldn't mix wnoutrefresh() or wrefresh() operations with panels
-   code; this will work only if the argument window is either in the top
-   panel or unobscured by any other panels.
-   
-   The stsdcr window is a special case. It is considered below all
-   panels. Because changes to panels may obscure parts of stdscr, though,
-   you should call update_panels() before doupdate() even when you only
-   change stdscr.
-   
-   Note that wgetch automatically calls wrefresh. Therefore, before
-   requesting input from a panel window, you need to be sure that the
-   panel is totally unobscured.
-   
-   There is presently no way to display changes to one obscured panel
-   without repainting all panels.
-   
-Hiding Panels
-
-   It's possible to remove a panel from the deck temporarily; use
-   hide_panel for this. Use show_panel() to render it visible again. The
-   predicate function panel_hidden tests whether or not a panel is
-   hidden.
-   
-   The panel_update code ignores hidden panels. You cannot do top_panel()
-   or bottom_panel on a hidden panel(). Other panels operations are
-   applicable.
-   
-Miscellaneous Other Facilities
-
-   It's possible to navigate the deck using the functions panel_above()
-   and panel_below. Handed a panel pointer, they return the panel above
-   or below that panel. Handed NULL, they return the bottom-most or
-   top-most panel.
-   
-   Every panel has an associated user pointer, not used by the panel
-   code, to which you can attach application data. See the man page
-   documentation of set_panel_userptr() and panel_userptr for details.
-   
-                               The Menu Library
-                                       
-   A menu is a screen display that assists the user to choose some subset
-   of a given set of items. The menu library is a curses extension that
-   supports easy programming of menu hierarchies with a uniform but
-   flexible interface.
-   
-   The menu library first appeared in AT&T System V. The version
-   documented here is the menu code distributed with ncurses.
-   
-Compiling With the menu Library
-
-   Your menu-using modules must import the menu library declarations with
-          #include <menu.h>
-
-   and must be linked explicitly with the menus library using an -lmenu
-   argument. Note that they must also link the ncurses library with
-   -lncurses. Many linkers are two-pass and will accept either order, but
-   it is still good practice to put -lmenu first and -lncurses second.
-   
-Overview of Menus
-
-   The menus created by this library consist of collections of items
-   including a name string part and a description string part. To make
-   menus, you create groups of these items and connect them with menu
-   frame objects.
-   
-   The menu can then by posted, that is written to an associated window.
-   Actually, each menu has two associated windows; a containing window in
-   which the programmer can scribble titles or borders, and a subwindow
-   in which the menu items proper are displayed. If this subwindow is too
-   small to display all the items, it will be a scrollable viewport on
-   the collection of items.
-   
-   A menu may also be unposted (that is, undisplayed), and finally freed
-   to make the storage associated with it and its items available for
-   re-use.
-   
-   The general flow of control of a menu program looks like this:
-    1. Initialize curses.
-    2. Create the menu items, using new_item().
-    3. Create the menu using new_menu().
-    4. Post the menu using menu_post().
-    5. Refresh the screen.
-    6. Process user requests via an input loop.
-    7. Unpost the menu using menu_unpost().
-    8. Free the menu, using free_menu().
-    9. Free the items using free_item().
-   10. Terminate curses.
-       
-Selecting items
-
-   Menus may be multi-valued or (the default) single-valued (see the
-   manual page menu_opts(3x) to see how to change the default). Both
-   types always have a current item.
-   
-   From a single-valued menu you can read the selected value simply by
-   looking at the current item. From a multi-valued menu, you get the
-   selected set by looping through the items applying the item_value()
-   predicate function. Your menu-processing code can use the function
-   set_item_value() to flag the items in the select set.
-   
-   Menu items can be made unselectable using set_item_opts() or
-   item_opts_off() with the O_SELECTABLE argument. This is the only
-   option so far defined for menus, but it is good practice to code as
-   though other option bits might be on.
-   
-Menu Display
-
-   The menu library calculates a minimum display size for your window,
-   based on the following variables:
-   
-     * The number and maximum length of the menu items
-     * Whether the O_ROWMAJOR option is enabled
-     * Whether display of descriptions is enabled
-     * Whatever menu format may have been set by the programmer
-     * The length of the menu mark string used for highlighting selected
-       items
-       
-   The function set_menu_format() allows you to set the maximum size of
-   the viewport or menu page that will be used to display menu items. You
-   can retrieve any format associated with a menu with menu_format(). The
-   default format is rows=16, columns=1.
-   
-   The actual menu page may be smaller than the format size. This depends
-   on the item number and size and whether O_ROWMAJOR is on. This option
-   (on by default) causes menu items to be displayed in a `raster-scan'
-   pattern, so that if more than one item will fit horizontally the first
-   couple of items are side-by-side in the top row. The alternative is
-   column-major display, which tries to put the first several items in
-   the first column.
-   
-   As mentioned above, a menu format not large enough to allow all items
-   to fit on-screen will result in a menu display that is vertically
-   scrollable.
-   
-   You can scroll it with requests to the menu driver, which will be
-   described in the section on menu input handling.
-   
-   Each menu has a mark string used to visually tag selected items; see
-   the menu_mark(3x) manual page for details. The mark string length also
-   influences the menu page size.
-   
-   The function scale_menu() returns the minimum display size that the
-   menu code computes from all these factors. There are other menu
-   display attributes including a select attribute, an attribute for
-   selectable items, an attribute for unselectable items, and a pad
-   character used to separate item name text from description text. These
-   have reasonable defaults which the library allows you to change (see
-   the menu_attribs(3x) manual page.
-   
-Menu Windows
-
-   Each menu has, as mentioned previously, a pair of associated windows.
-   Both these windows are painted when the menu is posted and erased when
-   the menu is unposted.
-   
-   The outer or frame window is not otherwise touched by the menu
-   routines. It exists so the programmer can associate a title, a border,
-   or perhaps help text with the menu and have it properly refreshed or
-   erased at post/unpost time. The inner window or subwindow is where the
-   current menu page is displayed.
-   
-   By default, both windows are stdscr. You can set them with the
-   functions in menu_win(3x).
-   
-   When you call menu_post(), you write the menu to its subwindow. When
-   you call menu_unpost(), you erase the subwindow, However, neither of
-   these actually modifies the screen. To do that, call wrefresh() or
-   some equivalent.
-   
-Processing Menu Input
-
-   The main loop of your menu-processing code should call menu_driver()
-   repeatedly. The first argument of this routine is a menu pointer; the
-   second is a menu command code. You should write an input-fetching
-   routine that maps input characters to menu command codes, and pass its
-   output to menu_driver(). The menu command codes are fully documented
-   in menu_driver(3x).
-   
-   The simplest group of command codes is REQ_NEXT_ITEM, REQ_PREV_ITEM,
-   REQ_FIRST_ITEM, REQ_LAST_ITEM, REQ_UP_ITEM, REQ_DOWN_ITEM,
-   REQ_LEFT_ITEM, REQ_RIGHT_ITEM. These change the currently selected
-   item. These requests may cause scrolling of the menu page if it only
-   partially displayed.
-   
-   There are explicit requests for scrolling which also change the
-   current item (because the select location does not change, but the
-   item there does). These are REQ_SCR_DLINE, REQ_SCR_ULINE,
-   REQ_SCR_DPAGE, and REQ_SCR_UPAGE.
-   
-   The REQ_TOGGLE_ITEM selects or deselects the current item. It is for
-   use in multi-valued menus; if you use it with O_ONEVALUE on, you'll
-   get an error return (E_REQUEST_DENIED).
-   
-   Each menu has an associated pattern buffer. The menu_driver() logic
-   tries to accumulate printable ASCII characters passed in in that
-   buffer; when it matches a prefix of an item name, that item (or the
-   next matching item) is selected. If appending a character yields no
-   new match, that character is deleted from the pattern buffer, and
-   menu_driver() returns E_NO_MATCH.
-   
-   Some requests change the pattern buffer directly: REQ_CLEAR_PATTERN,
-   REQ_BACK_PATTERN, REQ_NEXT_MATCH, REQ_PREV_MATCH. The latter two are
-   useful when pattern buffer input matches more than one item in a
-   multi-valued menu.
-   
-   Each successful scroll or item navigation request clears the pattern
-   buffer. It is also possible to set the pattern buffer explicitly with
-   set_menu_pattern().
-   
-   Finally, menu driver requests above the constant MAX_COMMAND are
-   considered application-specific commands. The menu_driver() code
-   ignores them and returns E_UNKNOWN_COMMAND.
-   
-Miscellaneous Other Features
-
-   Various menu options can affect the processing and visual appearance
-   and input processing of menus. See menu_opts(3x) for details.
-   
-   It is possible to change the current item from application code; this
-   is useful if you want to write your own navigation requests. It is
-   also possible to explicitly set the top row of the menu display. See
-   mitem_current(3x). If your application needs to change the menu
-   subwindow cursor for any reason, pos_menu_cursor() will restore it to
-   the correct location for continuing menu driver processing.
-   
-   It is possible to set hooks to be called at menu initialization and
-   wrapup time, and whenever the selected item changes. See
-   menu_hook(3x).
-   
-   Each item, and each menu, has an associated user pointer on which you
-   can hang application data. See mitem_userptr(3x) and menu_userptr(3x).
-   
-                               The Forms Library
-                                       
-   The form library is a curses extension that supports easy programming
-   of on-screen forms for data entry and program control.
-   
-   The form library first appeared in AT&T System V. The version
-   documented here is the form code distributed with ncurses.
-   
-Compiling With the form Library
-
-   Your form-using modules must import the form library declarations with
-          #include <form.h>
-
-   and must be linked explicitly with the forms library using an -lform
-   argument. Note that they must also link the ncurses library with
-   -lncurses. Many linkers are two-pass and will accept either order, but
-   it is still good practice to put -lform first and -lncurses second.
-   
-Overview of Forms
-
-   A form is a collection of fields; each field may be either a label
-   (explanatory text) or a data-entry location. Long forms may be
-   segmented into pages; each entry to a new page clears the screen.
-   
-   To make forms, you create groups of fields and connect them with form
-   frame objects; the form library makes this relatively simple.
-   
-   Once defined, a form can be posted, that is written to an associated
-   window. Actually, each form has two associated windows; a containing
-   window in which the programmer can scribble titles or borders, and a
-   subwindow in which the form fields proper are displayed.
-   
-   As the form user fills out the posted form, navigation and editing
-   keys support movement between fields, editing keys support modifying
-   field, and plain text adds to or changes data in a current field. The
-   form library allows you (the forms designer) to bind each navigation
-   and editing key to any keystroke accepted by curses Fields may have
-   validation conditions on them, so that they check input data for type
-   and value. The form library supplies a rich set of pre-defined field
-   types, and makes it relatively easy to define new ones.
-   
-   Once its transaction is completed (or aborted), a form may be unposted
-   (that is, undisplayed), and finally freed to make the storage
-   associated with it and its items available for re-use.
-   
-   The general flow of control of a form program looks like this:
-    1. Initialize curses.
-    2. Create the form fields, using new_field().
-    3. Create the form using new_form().
-    4. Post the form using form_post().
-    5. Refresh the screen.
-    6. Process user requests via an input loop.
-    7. Unpost the form using form_unpost().
-    8. Free the form, using free_form().
-    9. Free the fields using free_field().
-   10. Terminate curses.
-       
-   Note that this looks much like a menu program; the form library
-   handles tasks which are in many ways similar, and its interface was
-   obviously designed to resemble that of the menu library wherever
-   possible.
-   
-   In forms programs, however, the `process user requests' is somewhat
-   more complicated than for menus. Besides menu-like navigation
-   operations, the menu driver loop has to support field editing and data
-   validation.
-   
-Creating and Freeing Fields and Forms
-
-   The basic function for creating fields is new_field():
-   
-FIELD *new_field(int height, int width,   /* new field size */
-                 int top, int left,       /* upper left corner */
-                 int offscreen,           /* number of offscreen rows */
-                 int nbuf);               /* number of working buffers */
-
-   Menu items always occupy a single row, but forms fields may have
-   multiple rows. So new_field() requires you to specify a width and
-   height (the first two arguments, which mist both be greater than
-   zero).
-   
-   You must also specify the location of the field's upper left corner on
-   the screen (the third and fourth arguments, which must be zero or
-   greater). Note that these coordinates are relative to the form
-   subwindow, which will coincide with stdscr by default but need not be
-   stdscr if you've done an explicit set_form_window() call.
-   
-   The fifth argument allows you to specify a number of off-screen rows.
-   If this is zero, the entire field will always be displayed. If it is
-   nonzero, the form will be scrollable, with only one screen-full
-   (initially the top part) displayed at any given time. If you make a
-   field dynamic and grow it so it will no longer fit on the screen, the
-   form will become scrollable even if the offscreen argument was
-   initially zero.
-   
-   The forms library allocates one working buffer per field; the size of
-   each buffer is ((height + offscreen)*width + 1, one character for each
-   position in the field plus a NUL terminator. The sixth argument is the
-   number of additional data buffers to allocate for the field; your
-   application can use them for its own purposes.
-   
-FIELD *dup_field(FIELD *field,            /* field to copy */
-                 int top, int left);      /* location of new copy */
-
-   The function dup_field() duplicates an existing field at a new
-   location. Size and buffering information are copied; some attribute
-   flags and status bits are not (see the form_field_new(3X) for
-   details).
-   
-FIELD *link_field(FIELD *field,           /* field to copy */
-                  int top, int left);     /* location of new copy */
-
-   The function link_field() also duplicates an existing field at a new
-   location. The difference from dup_field() is that it arranges for the
-   new field's buffer to be shared with the old one.
-   
-   Besides the obvious use in making a field editable from two different
-   form pages, linked fields give you a way to hack in dynamic labels. If
-   you declare several fields linked to an original, and then make them
-   inactive, changes from the original will still be propagated to the
-   linked fields.
-   
-   As with duplicated fields, linked fields have attribute bits separate
-   from the original.
-   
-   As you might guess, all these field-allocations return NULL if the
-   field allocation is not possible due to an out-of-memory error or
-   out-of-bounds arguments.
-   
-   To connect fields to a form, use
-   
-FORM *new_form(FIELD **fields);
-
-   This function expects to see a NULL-terminated array of field
-   pointers. Said fields are connected to a newly-allocated form object;
-   its address is returned (or else NULL if the allocation fails).
-   
-   Note that new_field() does not copy the pointer array into private
-   storage; if you modify the contents of the pointer array during forms
-   processing, all manner of bizarre things might happen. Also note that
-   any given field may only be connected to one form.
-   
-   The functions free_field() and free_form are available to free field
-   and form objects. It is an error to attempt to free a field connected
-   to a form, but not vice-versa; thus, you will generally free your form
-   objects first.
-   
-Fetching and Changing Field Attributes
-
-   Each form field has a number of location and size attributes
-   associated with it. There are other field attributes used to control
-   display and editing of the field. Some (for example, the O_STATIC bit)
-   involve sufficient complications to be covered in sections of their
-   own later on. We cover the functions used to get and set several basic
-   attributes here.
-   
-   When a field is created, the attributes not specified by the new_field
-   function are copied from an invisible system default field. In
-   attribute-setting and -fetching functions, the argument NULL is taken
-   to mean this field. Changes to it persist as defaults until your forms
-   application terminates.
-   
-  Fetching Size and Location Data
-  
-   You can retrieve field sizes and locations through:
-   
-int field_info(FIELD *field,              /* field from which to fetch */
-               int *height, *int width,   /* field size */
-               int *top, int *left,       /* upper left corner */
-               int *offscreen,            /* number of offscreen rows */
-               int *nbuf);                /* number of working buffers */
-
-   This function is a sort of inverse of new_field(); instead of setting
-   size and location attributes of a new field, it fetches them from an
-   existing one.
-   
-  Changing the Field Location
-  
-   It is possible to move a field's location on the screen:
-   
-int move_field(FIELD *field,              /* field to alter */
-               int top, int left);        /* new upper-left corner */
-
-   You can, of course. query the current location through field_info().
-   
-  The Justification Attribute
-  
-   One-line fields may be unjustified, justified right, justified left,
-   or centered. Here is how you manipulate this attribute:
-   
-int set_field_just(FIELD *field,          /* field to alter */
-                   int justmode);         /* mode to set */
-
-int field_just(FIELD *field);             /* fetch mode of field */
-
-   The mode values accepted and returned by this functions are
-   preprocessor macros NO_JUSTIFICATION, JUSTIFY_RIGHT, JUSTIFY_LEFT, or
-   JUSTIFY_CENTER.
-   
-  Field Display Attributes
-  
-   For each field, you can set a foreground attribute for entered
-   characters, a background attribute for the entire field, and a pad
-   character for the unfilled portion of the field. You can also control
-   pagination of the form.
-   
-   This group of four field attributes controls the visual appearance of
-   the field on the screen, without affecting in any way the data in the
-   field buffer.
-   
-int set_field_fore(FIELD *field,          /* field to alter */
-                   chtype attr);          /* attribute to set */
-
-chtype field_fore(FIELD *field);          /* field to query */
-
-int set_field_back(FIELD *field,          /* field to alter */
-                   chtype attr);          /* attribute to set */
-
-chtype field_back(FIELD *field);          /* field to query */
-
-int set_field_pad(FIELD *field,           /* field to alter */
-                 int pad);                /* pad character to set */
-
-chtype field_pad(FIELD *field);
-
-int set_new_page(FIELD *field,            /* field to alter */
-                 int flag);               /* TRUE to force new page */
-
-chtype new_page(FIELD *field);            /* field to query */
-
-   The attributes set and returned by the first four functions are normal
-   curses(3x) display attribute values (A_STANDOUT, A_BOLD, A_REVERSE
-   etc). The page bit of a field controls whether it is displayed at the
-   start of a new form screen.
-   
-  Field Option Bits
-  
-   There is also a large collection of field option bits you can set to
-   control various aspects of forms processing. You can manipulate them
-   with these functions:
-int set_field_opts(FIELD *field,          /* field to alter */
-                   int attr);             /* attribute to set */
-
-int field_opts_on(FIELD *field,           /* field to alter */
-                  int attr);              /* attributes to turn on */
-
-int field_opts_off(FIELD *field,          /* field to alter */
-                   int attr);             /* attributes to turn off */
-
-int field_opts(FIELD *field);             /* field to query */
-
-   By default, all options are on. Here are the available option bits:
-   
-   O_VISIBLE
-          Controls whether the field is visible on the screen. Can be
-          used during form processing to hide or pop up fields depending
-          on the value of parent fields.
-          
-   O_ACTIVE
-          Controls whether the field is active during forms processing
-          (i.e. visited by form navigation keys). Can be used to make
-          labels or derived fields with buffer values alterable by the
-          forms application, not the user.
-          
-   O_PUBLIC
-          Controls whether data is displayed during field entry. If this
-          option is turned off on a field, the library will accept and
-          edit data in that field, but it will not be displayed and the
-          visible field cursor will not move. You can turn off the
-          O_PUBLIC bit to define password fields.
-          
-   O_EDIT
-          Controls whether the field's data can be modified. When this
-          option is off, all editing requests except REQ_PREV_CHOICE and
-          REQ_NEXT_CHOICE will fail. Such read-only fields may be useful
-          for help messages.
-          
-   O_WRAP
-          Controls word-wrapping in multi-line fields. Normally, when any
-          character of a (blank-separated) word reaches the end of the
-          current line, the entire word is wrapped to the next line
-          (assuming there is one). When this option is off, the word will
-          be split across the line break.
-          
-   O_BLANK
-          Controls field blanking. When this option is on, entering a
-          character at the first field position erases the entire field
-          (except for the just-entered character).
-          
-   O_AUTOSKIP
-          Controls automatic skip to next field when this one fills.
-          Normally, when the forms user tries to type more data into a
-          field than will fit, the editing location jumps to next field.
-          When this option is off, the user's cursor will hang at the end
-          of the field. This option is ignored in dynamic fields that
-          have not reached their size limit.
-          
-   O_NULLOK
-          Controls whether validation is applied to blank fields.
-          Normally, it is not; the user can leave a field blank without
-          invoking the usual validation check on exit. If this option is
-          off on a field, exit from it will invoke a validation check.
-          
-   O_PASSOK
-          Controls whether validation occurs on every exit, or only after
-          the field is modified. Normally the latter is true. Setting
-          O_PASSOK may be useful if your field's validation function may
-          change during forms processing.
-          
-   O_STATIC
-          Controls whether the field is fixed to its initial dimensions.
-          If you turn this off, the field becomes dynamic and will
-          stretch to fit entered data.
-          
-   A field's options cannot be changed while the field is currently
-   selected. However, options may be changed on posted fields that are
-   not current.
-   
-   The option values are bit-masks and can be composed with logical-or in
-   the obvious way.
-   
-Field Status
-
-   Every field has a status flag, which is set to FALSE when the field is
-   created and TRUE when the value in field buffer 0 changes. This flag
-   can be queried and set directly:
-   
-int set_field_status(FIELD *field,      /* field to alter */
-                   int status);         /* mode to set */
-
-int field_status(FIELD *field);         /* fetch mode of field */
-
-   Setting this flag under program control can be useful if you use the
-   same form repeatedly, looking for modified fields each time.
-   
-   Calling field_status() on a field not currently selected for input
-   will return a correct value. Calling field_status() on a field that is
-   currently selected for input may not necessarily give a correct field
-   status value, because entered data isn't necessarily copied to buffer
-   zero before the exit validation check. To guarantee that the returned
-   status value reflects reality, call field_status() either (1) in the
-   field's exit validation check routine, (2) from the field's or form's
-   initialization or termination hooks, or (3) just after a
-   REQ_VALIDATION request has been processed by the forms driver.
-   
-Field User Pointer
-
-   Each field structure contains one character pointer slot that is not
-   used by the forms library. It is intended to be used by applications
-   to store private per-field data. You can manipulate it with:
-int set_field_userptr(FIELD *field,       /* field to alter */
-                   char *userptr);        /* mode to set */
-
-char *field_userptr(FIELD *field);        /* fetch mode of field */
-
-   (Properly, this user pointer field ought to have (void *) type. The
-   (char *) type is retained for System V compatibility.)
-   
-   It is valid to set the user pointer of the default field (with a
-   set_field_userptr() call passed a NULL field pointer.) When a new
-   field is created, the default-field user pointer is copied to
-   initialize the new field's user pointer.
-   
-Variable-Sized Fields
-
-   Normally, a field is fixed at the size specified for it at creation
-   time. If, however, you turn off its O_STATIC bit, it becomes dynamic
-   and will automatically resize itself to accommodate data as it is
-   entered. If the field has extra buffers associated with it, they will
-   grow right along with the main input buffer.
-   
-   A one-line dynamic field will have a fixed height (1) but variable
-   width, scrolling horizontally to display data within the field area as
-   originally dimensioned and located. A multi-line dynamic field will
-   have a fixed width, but variable height (number of rows), scrolling
-   vertically to display data within the field area as originally
-   dimensioned and located.
-   
-   Normally, a dynamic field is allowed to grow without limit. But it is
-   possible to set an upper limit on the size of a dynamic field. You do
-   it with this function:
-   
-int set_max_field(FIELD *field,     /* field to alter (may not be NULL) */
-                   int max_size);   /* upper limit on field size */
-
-   If the field is one-line, max_size is taken to be a column size limit;
-   if it is multi-line, it is taken to be a line size limit. To disable
-   any limit, use an argument of zero. The growth limit can be changed
-   whether or not the O_STATIC bit is on, but has no effect until it is.
-   
-   The following properties of a field change when it becomes dynamic:
-     * If there is no growth limit, there is no final position of the
-       field; therefore O_AUTOSKIP and O_NL_OVERLOAD are ignored.
-     * Field justification will be ignored (though whatever justification
-       is set up will be retained internally and can be queried).
-     * The dup_field() and link_field() calls copy dynamic-buffer sizes.
-       If the O_STATIC option is set on one of a collection of links,
-       buffer resizing will occur only when the field is edited through
-       that link.
-     * The call field_info() will retrieve the original static size of
-       the field; use dynamic_field_info() to get the actual dynamic
-       size.
-       
-Field Validation
-
-   By default, a field will accept any data that will fit in its input
-   buffer. However, it is possible to attach a validation type to a
-   field. If you do this, any attempt to leave the field while it
-   contains data that doesn't match the validation type will fail. Some
-   validation types also have a character-validity check for each time a
-   character is entered in the field.
-   
-   A field's validation check (if any) is not called when
-   set_field_buffer() modifies the input buffer, nor when that buffer is
-   changed through a linked field.
-   
-   The form library provides a rich set of pre-defined validation types,
-   and gives you the capability to define custom ones of your own. You
-   can examine and change field validation attributes with the following
-   functions:
-   
-int set_field_type(FIELD *field,          /* field to alter */
-                   FIELDTYPE *ftype,      /* type to associate */
-                   ...);                  /* additional arguments*/
-
-FIELDTYPE *field_type(FIELD *field);      /* field to query */
-
-   The validation type of a field is considered an attribute of the
-   field. As with other field attributes, Also, doing set_field_type()
-   with a NULL field default will change the system default for
-   validation of newly-created fields.
-   
-   Here are the pre-defined validation types:
-   
-  TYPE_ALPHA
-  
-   This field type accepts alphabetic data; no blanks, no digits, no
-   special characters (this is checked at character-entry time). It is
-   set up with:
-   
-int set_field_type(FIELD *field,          /* field to alter */
-                   TYPE_ALPHA,            /* type to associate */
-                   int width);            /* maximum width of field */
-
-   The width argument sets a minimum width of data. Typically you'll want
-   to set this to the field width; if it's greater than the field width,
-   the validation check will always fail. A minimum width of zero makes
-   field completion optional.
-   
-  TYPE_ALNUM
-  
-   This field type accepts alphabetic data and digits; no blanks, no
-   special characters (this is checked at character-entry time). It is
-   set up with:
-   
-int set_field_type(FIELD *field,          /* field to alter */
-                   TYPE_ALNUM,            /* type to associate */
-                   int width);            /* maximum width of field */
-
-   The width argument sets a minimum width of data. As with TYPE_ALPHA,
-   typically you'll want to set this to the field width; if it's greater
-   than the field width, the validation check will always fail. A minimum
-   width of zero makes field completion optional.
-   
-  TYPE_ENUM
-  
-   This type allows you to restrict a field's values to be among a
-   specified set of string values (for example, the two-letter postal
-   codes for U.S. states). It is set up with:
-   
-int set_field_type(FIELD *field,          /* field to alter */
-                   TYPE_ENUM,             /* type to associate */
-                   char **valuelist;      /* list of possible values */
-                   int checkcase;         /* case-sensitive? */
-                   int checkunique);      /* must specify uniquely? */
-
-   The valuelist parameter must point at a NULL-terminated list of valid
-   strings. The checkcase argument, if true, makes comparison with the
-   string case-sensitive.
-   
-   When the user exits a TYPE_ENUM field, the validation procedure tries
-   to complete the data in the buffer to a valid entry. If a complete
-   choice string has been entered, it is of course valid. But it is also
-   possible to enter a prefix of a valid string and have it completed for
-   you.
-   
-   By default, if you enter such a prefix and it matches more than one
-   value in the string list, the prefix will be completed to the first
-   matching value. But the checkunique argument, if true, requires prefix
-   matches to be unique in order to be valid.
-   
-   The REQ_NEXT_CHOICE and REQ_PREV_CHOICE input requests can be
-   particularly useful with these fields.
-   
-  TYPE_INTEGER
-  
-   This field type accepts an integer. It is set up as follows:
-   
-int set_field_type(FIELD *field,          /* field to alter */
-                   TYPE_INTEGER,          /* type to associate */
-                   int padding,           /* # places to zero-pad to */
-                   int vmin, int vmax);   /* valid range */
-
-   Valid characters consist of an optional leading minus and digits. The
-   range check is performed on exit. If the range maximum is less than or
-   equal to the minimum, the range is ignored.
-   
-   If the value passes its range check, it is padded with as many leading
-   zero digits as necessary to meet the padding argument.
-   
-   A TYPE_INTEGER value buffer can conveniently be interpreted with the C
-   library function atoi(3).
-   
-  TYPE_NUMERIC
-  
-   This field type accepts a decimal number. It is set up as follows:
-   
-int set_field_type(FIELD *field,              /* field to alter */
-                   TYPE_NUMERIC,              /* type to associate */
-                   int padding,               /* # places of precision */
-                   double vmin, double vmax); /* valid range */
-
-   Valid characters consist of an optional leading minus and digits.
-   possibly including a decimal point. If your system supports locale's,
-   the decimal point character used must be the one defined by your
-   locale. The range check is performed on exit. If the range maximum is
-   less than or equal to the minimum, the range is ignored.
-   
-   If the value passes its range check, it is padded with as many
-   trailing zero digits as necessary to meet the padding argument.
-   
-   A TYPE_NUMERIC value buffer can conveniently be interpreted with the C
-   library function atof(3).
-   
-  TYPE_REGEXP
-  
-   This field type accepts data matching a regular expression. It is set
-   up as follows:
-   
-int set_field_type(FIELD *field,          /* field to alter */
-                   TYPE_REGEXP,           /* type to associate */
-                   char *regexp);         /* expression to match */
-
-   The syntax for regular expressions is that of regcomp(3). The check
-   for regular-expression match is performed on exit.
-   
-Direct Field Buffer Manipulation
-
-   The chief attribute of a field is its buffer contents. When a form has
-   been completed, your application usually needs to know the state of
-   each field buffer. You can find this out with:
-   
-char *field_buffer(FIELD *field,          /* field to query */
-                   int bufindex);         /* number of buffer to query */
-
-   Normally, the state of the zero-numbered buffer for each field is set
-   by the user's editing actions on that field. It's sometimes useful to
-   be able to set the value of the zero-numbered (or some other) buffer
-   from your application:
-int set_field_buffer(FIELD *field,        /* field to alter */
-                   int bufindex,          /* number of buffer to alter */
-                   char *value);          /* string value to set */
-
-   If the field is not large enough and cannot be resized to a
-   sufficiently large size to contain the specified value, the value will
-   be truncated to fit.
-   
-   Calling field_buffer() with a null field pointer will raise an error.
-   Calling field_buffer() on a field not currently selected for input
-   will return a correct value. Calling field_buffer() on a field that is
-   currently selected for input may not necessarily give a correct field
-   buffer value, because entered data isn't necessarily copied to buffer
-   zero before the exit validation check. To guarantee that the returned
-   buffer value reflects on-screen reality, call field_buffer() either
-   (1) in the field's exit validation check routine, (2) from the field's
-   or form's initialization or termination hooks, or (3) just after a
-   REQ_VALIDATION request has been processed by the forms driver.
-   
-Attributes of Forms
-
-   As with field attributes, form attributes inherit a default from a
-   system default form structure. These defaults can be queried or set by
-   of these functions using a form-pointer argument of NULL.
-   
-   The principal attribute of a form is its field list. You can query and
-   change this list with:
-   
-int set_form_fields(FORM *form,           /* form to alter */
-                    FIELD **fields);      /* fields to connect */
-
-char *form_fields(FORM *form);            /* fetch fields of form */
-
-int field_count(FORM *form);              /* count connect fields */
-
-   The second argument of set_form_fields() may be a NULL-terminated
-   field pointer array like the one required by new_form(). In that case,
-   the old fields of the form are disconnected but not freed (and
-   eligible to be connected to other forms), then the new fields are
-   connected.
-   
-   It may also be null, in which case the old fields are disconnected
-   (and not freed) but no new ones are connected.
-   
-   The field_count() function simply counts the number of fields
-   connected to a given from. It returns -1 if the form-pointer argument
-   is NULL.
-   
-Control of Form Display
-
-   In the overview section, you saw that to display a form you normally
-   start by defining its size (and fields), posting it, and refreshing
-   the screen. There is an hidden step before posting, which is the
-   association of the form with a frame window (actually, a pair of
-   windows) within which it will be displayed. By default, the forms
-   library associates every form with the full-screen window stdscr.
-   
-   By making this step explicit, you can associate a form with a declared
-   frame window on your screen display. This can be useful if you want to
-   adapt the form display to different screen sizes, dynamically tile
-   forms on the screen, or use a form as part of an interface layout
-   managed by panels.
-   
-   The two windows associated with each form have the same functions as
-   their analogues in the menu library. Both these windows are painted
-   when the form is posted and erased when the form is unposted.
-   
-   The outer or frame window is not otherwise touched by the form
-   routines. It exists so the programmer can associate a title, a border,
-   or perhaps help text with the form and have it properly refreshed or
-   erased at post/unpost time. The inner window or subwindow is where the
-   current form page is actually displayed.
-   
-   In order to declare your own frame window for a form, you'll need to
-   know the size of the form's bounding rectangle. You can get this
-   information with:
-   
-int scale_form(FORM *form,                /* form to query */
-               int *rows,                 /* form rows */
-               int *cols);                /* form cols */
-
-   The form dimensions are passed back in the locations pointed to by the
-   arguments. Once you have this information, you can use it to declare
-   of windows, then use one of these functions:
-int set_form_win(FORM *form,              /* form to alter */
-                 WINDOW *win);            /* frame window to connect */
-
-WINDOW *form_win(FORM *form);             /* fetch frame window of form */
-
-int set_form_sub(FORM *form,              /* form to alter */
-                 WINDOW *win);            /* form subwindow to connect */
-
-WINDOW *form_sub(FORM *form);             /* fetch form subwindow of form */
-
-   Note that curses operations, including refresh(), on the form, should
-   be done on the frame window, not the form subwindow.
-   
-   It is possible to check from your application whether all of a
-   scrollable field is actually displayed within the menu subwindow. Use
-   these functions:
-   
-int data_ahead(FORM *form);               /* form to be queried */
-
-int data_behind(FORM *form);              /* form to be queried */
-
-   The function data_ahead() returns TRUE if (a) the current field is
-   one-line and has undisplayed data off to the right, (b) the current
-   field is multi-line and there is data off-screen below it.
-   
-   The function data_behind() returns TRUE if the first (upper left hand)
-   character position is off-screen (not being displayed).
-   
-   Finally, there is a function to restore the form window's cursor to
-   the value expected by the forms driver:
-   
-int pos_form_cursor(FORM *)               /* form to be queried */
-
-   If your application changes the form window cursor, call this function
-   before handing control back to the forms driver in order to
-   re-synchronize it.
-   
-Input Processing in the Forms Driver
-
-   The function form_driver() handles virtualized input requests for form
-   navigation, editing, and validation requests, just as menu_driver does
-   for menus (see the section on menu input handling).
-   
-int form_driver(FORM *form,               /* form to pass input to */
-                int request);             /* form request code */
-
-   Your input virtualization function needs to take input and then
-   convert it to either an alphanumeric character (which is treated as
-   data to be entered in the currently-selected field), or a forms
-   processing request.
-   
-   The forms driver provides hooks (through input-validation and
-   field-termination functions) with which your application code can
-   check that the input taken by the driver matched what was expected.
-   
-  Page Navigation Requests
-  
-   These requests cause page-level moves through the form, triggering
-   display of a new form screen.
-   
-   REQ_NEXT_PAGE
-          Move to the next form page.
-          
-   REQ_PREV_PAGE
-          Move to the previous form page.
-          
-   REQ_FIRST_PAGE
-          Move to the first form page.
-          
-   REQ_LAST_PAGE
-          Move to the last form page.
-          
-   These requests treat the list as cyclic; that is, REQ_NEXT_PAGE from
-   the last page goes to the first, and REQ_PREV_PAGE from the first page
-   goes to the last.
-   
-  Inter-Field Navigation Requests
-  
-   These requests handle navigation between fields on the same page.
-   
-   REQ_NEXT_FIELD
-          Move to next field.
-          
-   REQ_PREV_FIELD
-          Move to previous field.
-          
-   REQ_FIRST_FIELD
-          Move to the first field.
-          
-   REQ_LAST_FIELD
-          Move to the last field.
-          
-   REQ_SNEXT_FIELD
-          Move to sorted next field.
-          
-   REQ_SPREV_FIELD
-          Move to sorted previous field.
-          
-   REQ_SFIRST_FIELD
-          Move to the sorted first field.
-          
-   REQ_SLAST_FIELD
-          Move to the sorted last field.
-          
-   REQ_LEFT_FIELD
-          Move left to field.
-          
-   REQ_RIGHT_FIELD
-          Move right to field.
-          
-   REQ_UP_FIELD
-          Move up to field.
-          
-   REQ_DOWN_FIELD
-          Move down to field.
-          
-   These requests treat the list of fields on a page as cyclic; that is,
-   REQ_NEXT_FIELD from the last field goes to the first, and
-   REQ_PREV_FIELD from the first field goes to the last. The order of the
-   fields for these (and the REQ_FIRST_FIELD and REQ_LAST_FIELD requests)
-   is simply the order of the field pointers in the form array (as set up
-   by new_form() or set_form_fields()
-   
-   It is also possible to traverse the fields as if they had been sorted
-   in screen-position order, so the sequence goes left-to-right and
-   top-to-bottom. To do this, use the second group of four
-   sorted-movement requests.
-   
-   Finally, it is possible to move between fields using visual directions
-   up, down, right, and left. To accomplish this, use the third group of
-   four requests. Note, however, that the position of a form for purposes
-   of these requests is its upper-left corner.
-   
-   For example, suppose you have a multi-line field B, and two
-   single-line fields A and C on the same line with B, with A to the left
-   of B and C to the right of B. A REQ_MOVE_RIGHT from A will go to B
-   only if A, B, and C all share the same first line; otherwise it will
-   skip over B to C.
-   
-  Intra-Field Navigation Requests
-  
-   These requests drive movement of the edit cursor within the currently
-   selected field.
-   
-   REQ_NEXT_CHAR
-          Move to next character.
-          
-   REQ_PREV_CHAR
-          Move to previous character.
-          
-   REQ_NEXT_LINE
-          Move to next line.
-          
-   REQ_PREV_LINE
-          Move to previous line.
-          
-   REQ_NEXT_WORD
-          Move to next word.
-          
-   REQ_PREV_WORD
-          Move to previous word.
-          
-   REQ_BEG_FIELD
-          Move to beginning of field.
-          
-   REQ_END_FIELD
-          Move to end of field.
-          
-   REQ_BEG_LINE
-          Move to beginning of line.
-          
-   REQ_END_LINE
-          Move to end of line.
-          
-   REQ_LEFT_CHAR
-          Move left in field.
-          
-   REQ_RIGHT_CHAR
-          Move right in field.
-          
-   REQ_UP_CHAR
-          Move up in field.
-          
-   REQ_DOWN_CHAR
-          Move down in field.
-          
-   Each word is separated from the previous and next characters by
-   whitespace. The commands to move to beginning and end of line or field
-   look for the first or last non-pad character in their ranges.
-   
-  Scrolling Requests
-  
-   Fields that are dynamic and have grown and fields explicitly created
-   with offscreen rows are scrollable. One-line fields scroll
-   horizontally; multi-line fields scroll vertically. Most scrolling is
-   triggered by editing and intra-field movement (the library scrolls the
-   field to keep the cursor visible). It is possible to explicitly
-   request scrolling with the following requests:
-   
-   REQ_SCR_FLINE
-          Scroll vertically forward a line.
-          
-   REQ_SCR_BLINE
-          Scroll vertically backward a line.
-          
-   REQ_SCR_FPAGE
-          Scroll vertically forward a page.
-          
-   REQ_SCR_BPAGE
-          Scroll vertically backward a page.
-          
-   REQ_SCR_FHPAGE
-          Scroll vertically forward half a page.
-          
-   REQ_SCR_BHPAGE
-          Scroll vertically backward half a page.
-          
-   REQ_SCR_FCHAR
-          Scroll horizontally forward a character.
-          
-   REQ_SCR_BCHAR
-          Scroll horizontally backward a character.
-          
-   REQ_SCR_HFLINE
-          Scroll horizontally one field width forward.
-          
-   REQ_SCR_HBLINE
-          Scroll horizontally one field width backward.
-          
-   REQ_SCR_HFHALF
-          Scroll horizontally one half field width forward.
-          
-   REQ_SCR_HBHALF
-          Scroll horizontally one half field width backward.
-          
-   For scrolling purposes, a page of a field is the height of its visible
-   part.
-   
-  Editing Requests
-  
-   When you pass the forms driver an ASCII character, it is treated as a
-   request to add the character to the field's data buffer. Whether this
-   is an insertion or a replacement depends on the field's edit mode
-   (insertion is the default.
-   
-   The following requests support editing the field and changing the edit
-   mode:
-   
-   REQ_INS_MODE
-          Set insertion mode.
-          
-   REQ_OVL_MODE
-          Set overlay mode.
-          
-   REQ_NEW_LINE
-          New line request (see below for explanation).
-          
-   REQ_INS_CHAR
-          Insert space at character location.
-          
-   REQ_INS_LINE
-          Insert blank line at character location.
-          
-   REQ_DEL_CHAR
-          Delete character at cursor.
-          
-   REQ_DEL_PREV
-          Delete previous word at cursor.
-          
-   REQ_DEL_LINE
-          Delete line at cursor.
-          
-   REQ_DEL_WORD
-          Delete word at cursor.
-          
-   REQ_CLR_EOL
-          Clear to end of line.
-          
-   REQ_CLR_EOF
-          Clear to end of field.
-          
-   REQ_CLEAR_FIELD
-          Clear entire field.
-          
-   The behavior of the REQ_NEW_LINE and REQ_DEL_PREV requests is
-   complicated and partly controlled by a pair of forms options. The
-   special cases are triggered when the cursor is at the beginning of a
-   field, or on the last line of the field.
-   
-   First, we consider REQ_NEW_LINE:
-   
-   The normal behavior of REQ_NEW_LINE in insert mode is to break the
-   current line at the position of the edit cursor, inserting the portion
-   of the current line after the cursor as a new line following the
-   current and moving the cursor to the beginning of that new line (you
-   may think of this as inserting a newline in the field buffer).
-   
-   The normal behavior of REQ_NEW_LINE in overlay mode is to clear the
-   current line from the position of the edit cursor to end of line. The
-   cursor is then moved to the beginning of the next line.
-   
-   However, REQ_NEW_LINE at the beginning of a field, or on the last line
-   of a field, instead does a REQ_NEXT_FIELD. O_NL_OVERLOAD option is
-   off, this special action is disabled.
-   
-   Now, let us consider REQ_DEL_PREV:
-   
-   The normal behavior of REQ_DEL_PREV is to delete the previous
-   character. If insert mode is on, and the cursor is at the start of a
-   line, and the text on that line will fit on the previous one, it
-   instead appends the contents of the current line to the previous one
-   and deletes the current line (you may think of this as deleting a
-   newline from the field buffer).
-   
-   However, REQ_DEL_PREV at the beginning of a field is instead treated
-   as a REQ_PREV_FIELD.
-   
-   If the O_BS_OVERLOAD option is off, this special action is disabled
-   and the forms driver just returns E_REQUEST_DENIED.
-   
-   See Form Options for discussion of how to set and clear the overload
-   options.
-   
-  Order Requests
-  
-   If the type of your field is ordered, and has associated functions for
-   getting the next and previous values of the type from a given value,
-   there are requests that can fetch that value into the field buffer:
-   
-   REQ_NEXT_CHOICE
-          Place the successor value of the current value in the buffer.
-          
-   REQ_PREV_CHOICE
-          Place the predecessor value of the current value in the buffer.
-          
-   Of the built-in field types, only TYPE_ENUM has built-in successor and
-   predecessor functions. When you define a field type of your own (see
-   Custom Validation Types), you can associate our own ordering
-   functions.
-   
-  Application Commands
-  
-   Form requests are represented as integers above the curses value
-   greater than KEY_MAX and less than or equal to the constant
-   MAX_COMMAND. If your input-virtualization routine returns a value
-   above MAX_COMMAND, the forms driver will ignore it.
-   
-Field Change Hooks
-
-   It is possible to set function hooks to be executed whenever the
-   current field or form changes. Here are the functions that support
-   this:
-   
-typedef void    (*HOOK)();       /* pointer to function returning void */
-
-int set_form_init(FORM *form,    /* form to alter */
-                  HOOK hook);    /* initialization hook */
-
-HOOK form_init(FORM *form);      /* form to query */
-
-int set_form_term(FORM *form,    /* form to alter */
-                  HOOK hook);    /* termination hook */
-
-HOOK form_term(FORM *form);      /* form to query */
-
-int set_field_init(FORM *form,   /* form to alter */
-                  HOOK hook);    /* initialization hook */
-
-HOOK field_init(FORM *form);     /* form to query */
-
-int set_field_term(FORM *form,   /* form to alter */
-                  HOOK hook);    /* termination hook */
-
-HOOK field_term(FORM *form);     /* form to query */
-
-   These functions allow you to either set or query four different hooks.
-   In each of the set functions, the second argument should be the
-   address of a hook function. These functions differ only in the timing
-   of the hook call.
-   
-   form_init
-          This hook is called when the form is posted; also, just after
-          each page change operation.
-          
-   field_init
-          This hook is called when the form is posted; also, just after
-          each field change
-          
-   field_term
-          This hook is called just after field validation; that is, just
-          before the field is altered. It is also called when the form is
-          unposted.
-          
-   form_term
-          This hook is called when the form is unposted; also, just
-          before each page change operation.
-          
-   Calls to these hooks may be triggered
-    1. When user editing requests are processed by the forms driver
-    2. When the current page is changed by set_current_field() call
-    3. When the current field is changed by a set_form_page() call
-       
-   See Field Change Commands for discussion of the latter two cases.
-   
-   You can set a default hook for all fields by passing one of the set
-   functions a NULL first argument.
-   
-   You can disable any of these hooks by (re)setting them to NULL, the
-   default value.
-   
-Field Change Commands
-
-   Normally, navigation through the form will be driven by the user's
-   input requests. But sometimes it is useful to be able to move the
-   focus for editing and viewing under control of your application, or
-   ask which field it currently is in. The following functions help you
-   accomplish this:
-   
-int set_current_field(FORM *form,         /* form to alter */
-                      FIELD *field);      /* field to shift to */
-
-FIELD *current_field(FORM *form);         /* form to query */
-
-int field_index(FORM *form,               /* form to query */
-                FIELD *field);            /* field to get index of */
-
-   The function field_index() returns the index of the given field in the
-   given form's field array (the array passed to new_form() or
-   set_form_fields()).
-   
-   The initial current field of a form is the first active field on the
-   first page. The function set_form_fields() resets this.
-   
-   It is also possible to move around by pages.
-   
-int set_form_page(FORM *form,             /* form to alter */
-                  int page);              /* page to go to (0-origin) */
-
-int form_page(FORM *form);                /* return form's current page */
-
-   The initial page of a newly-created form is 0. The function
-   set_form_fields() resets this.
-   
-Form Options
-
-   Like fields, forms may have control option bits. They can be changed
-   or queried with these functions:
-   
-int set_form_opts(FORM *form,             /* form to alter */
-                  int attr);              /* attribute to set */
-
-int form_opts_on(FORM *form,              /* form to alter */
-                 int attr);               /* attributes to turn on */
-
-int form_opts_off(FORM *form,             /* form to alter */
-                  int attr);              /* attributes to turn off */
-
-int form_opts(FORM *form);                /* form to query */
-
-   By default, all options are on. Here are the available option bits:
-   
-   O_NL_OVERLOAD
-          Enable overloading of REQ_NEW_LINE as described in Editing
-          Requests. The value of this option is ignored on dynamic fields
-          that have not reached their size limit; these have no last
-          line, so the circumstances for triggering a REQ_NEXT_FIELD
-          never arise.
-          
-   O_BS_OVERLOAD
-          Enable overloading of REQ_DEL_PREV as described in Editing
-          Requests.
-          
-   The option values are bit-masks and can be composed with logical-or in
-   the obvious way.
-   
-Custom Validation Types
-
-   The form library gives you the capability to define custom validation
-   types of your own. Further, the optional additional arguments of
-   set_field_type effectively allow you to parameterize validation types.
-   Most of the complications in the validation-type interface have to do
-   with the handling of the additional arguments within custom validation
-   functions.
-   
-  Union Types
-  
-   The simplest way to create a custom data type is to compose it from
-   two preexisting ones:
-   
-FIELD *link_fieldtype(FIELDTYPE *type1,
-                      FIELDTYPE *type2);
-
-   This function creates a field type that will accept any of the values
-   legal for either of its argument field types (which may be either
-   predefined or programmer-defined). If a set_field_type() call later
-   requires arguments, the new composite type expects all arguments for
-   the first type, than all arguments for the second. Order functions
-   (see Order Requests) associated with the component types will work on
-   the composite; what it does is check the validation function for the
-   first type, then for the second, to figure what type the buffer
-   contents should be treated as.
-   
-  New Field Types
-  
-   To create a field type from scratch, you need to specify one or both
-   of the following things:
-   
-     * A character-validation function, to check each character as it is
-       entered.
-     * A field-validation function to be applied on exit from the field.
-       
-   Here's how you do that:
-   
-typedef int     (*HOOK)();       /* pointer to function returning int */
-
-FIELDTYPE *new_fieldtype(HOOK f_validate, /* field validator */
-                         HOOK c_validate) /* character validator */
-
-
-int free_fieldtype(FIELDTYPE *ftype);     /* type to free */
-
-   At least one of the arguments of new_fieldtype() must be non-NULL. The
-   forms driver will automatically call the new type's validation
-   functions at appropriate points in processing a field of the new type.
-   
-   The function free_fieldtype() deallocates the argument fieldtype,
-   freeing all storage associated with it.
-   
-   Normally, a field validator is called when the user attempts to leave
-   the field. Its first argument is a field pointer, from which it can
-   get to field buffer 0 and test it. If the function returns TRUE, the
-   operation succeeds; if it returns FALSE, the edit cursor stays in the
-   field.
-   
-   A character validator gets the character passed in as a first
-   argument. It too should return TRUE if the character is valid, FALSE
-   otherwise.
-   
-  Validation Function Arguments
-  
-   Your field- and character- validation functions will be passed a
-   second argument as well. This second argument is the address of a
-   structure (which we'll call a pile) built from any of the
-   field-type-specific arguments passed to set_field_type(). If no such
-   arguments are defined for the field type, this pile pointer argument
-   will be NULL.
-   
-   In order to arrange for such arguments to be passed to your validation
-   functions, you must associate a small set of storage-management
-   functions with the type. The forms driver will use these to synthesize
-   a pile from the trailing arguments of each set_field_type() argument,
-   and a pointer to the pile will be passed to the validation functions.
-   
-   Here is how you make the association:
-   
-typedef char    *(*PTRHOOK)();    /* pointer to function returning (char *) */
-typedef void    (*VOIDHOOK)();    /* pointer to function returning void */
-
-int set_fieldtype_arg(FIELDTYPE *type,    /* type to alter */
-                      PTRHOOK make_str,   /* make structure from args */
-                      PTRHOOK copy_str,   /* make copy of structure */
-                      VOIDHOOK free_str); /* free structure storage */
-
-   Here is how the storage-management hooks are used:
-   
-   make_str
-          This function is called by set_field_type(). It gets one
-          argument, a va_list of the type-specific arguments passed to
-          set_field_type(). It is expected to return a pile pointer to a
-          data structure that encapsulates those arguments.
-          
-   copy_str
-          This function is called by form library functions that allocate
-          new field instances. It is expected to take a pile pointer,
-          copy the pile to allocated storage, and return the address of
-          the pile copy.
-          
-   free_str
-          This function is called by field- and type-deallocation
-          routines in the library. It takes a pile pointer argument, and
-          is expected to free the storage of that pile.
-          
-   The make_str and copy_str functions may return NULL to signal
-   allocation failure. The library routines will that call them will
-   return error indication when this happens. Thus, your validation
-   functions should never see a NULL file pointer and need not check
-   specially for it.
-   
-  Order Functions For Custom Types
-  
-   Some custom field types are simply ordered in the same well-defined
-   way that TYPE_ENUM is. For such types, it is possible to define
-   successor and predecessor functions to support the REQ_NEXT_CHOICE and
-   REQ_PREV_CHOICE requests. Here's how:
-   
-typedef int     (*INTHOOK)();     /* pointer to function returning int */
-
-int set_fieldtype_arg(FIELDTYPE *type,    /* type to alter */
-                      INTHOOK succ,       /* get successor value */
-                      INTHOOK pred);      /* get predecessor value */
-
-   The successor and predecessor arguments will each be passed two
-   arguments; a field pointer, and a pile pointer (as for the validation
-   functions). They are expected to use the function field_buffer() to
-   read the current value, and set_field_buffer() on buffer 0 to set the
-   next or previous value. Either hook may return TRUE to indicate
-   success (a legal next or previous value was set) or FALSE to indicate
-   failure.
-   
-  Avoiding Problems
-  
-   The interface for defining custom types is complicated and tricky.
-   Rather than attempting to create a custom type entirely from scratch,
-   you should start by studying the library source code for whichever of
-   the pre-defined types seems to be closest to what you want.
-   
-   Use that code as a model, and evolve it towards what you really want.
-   You will avoid many problems and annoyances that way. The code in the
-   ncurses library has been specifically exempted from the package
-   copyright to support this.
-   
-   If your custom type defines order functions, have do something
-   intuitive with a blank field. A useful convention is to make the
-   successor of a blank field the types minimum value, and its
-   predecessor the maximum.