162449Speter<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
262449Speter<!--
3174993Srafan  $Id: ncurses-intro.html,v 1.43 2007/03/03 19:31:50 tom Exp $
4166124Srafan  ****************************************************************************
5174993Srafan  * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc.              *
6166124Srafan  *                                                                          *
7166124Srafan  * Permission is hereby granted, free of charge, to any person obtaining a  *
8166124Srafan  * copy of this software and associated documentation files (the            *
9166124Srafan  * "Software"), to deal in the Software without restriction, including      *
10166124Srafan  * without limitation the rights to use, copy, modify, merge, publish,      *
11166124Srafan  * distribute, distribute with modifications, sublicense, and/or sell       *
12166124Srafan  * copies of the Software, and to permit persons to whom the Software is    *
13166124Srafan  * furnished to do so, subject to the following conditions:                 *
14166124Srafan  *                                                                          *
15166124Srafan  * The above copyright notice and this permission notice shall be included  *
16166124Srafan  * in all copies or substantial portions of the Software.                   *
17166124Srafan  *                                                                          *
18166124Srafan  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
19166124Srafan  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
20166124Srafan  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
21166124Srafan  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
22166124Srafan  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
23166124Srafan  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
24166124Srafan  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
25166124Srafan  *                                                                          *
26166124Srafan  * Except as contained in this notice, the name(s) of the above copyright   *
27166124Srafan  * holders shall not be used in advertising or otherwise to promote the     *
28166124Srafan  * sale, use or other dealings in this Software without prior written       *
29166124Srafan  * authorization.                                                           *
30166124Srafan  ****************************************************************************
3162449Speter-->
3262449Speter<HTML>
3362449Speter<HEAD>
3462449Speter<TITLE>Writing Programs with NCURSES</TITLE>
3562449Speter<link rev="made" href="mailto:bugs-ncurses@gnu.org">
36166124Srafan<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
3762449Speter</HEAD>
3862449Speter<BODY>
3962449Speter
4062449Speter<H1>Writing Programs with NCURSES</H1>
4162449Speter
4262449Speter<BLOCKQUOTE>
4362449Speterby Eric S. Raymond and Zeyd M. Ben-Halim<BR>
4462449Speterupdates since release 1.9.9e by Thomas Dickey
4562449Speter</BLOCKQUOTE>
4662449Speter
4762449Speter<H1>Contents</H1>
4862449Speter<UL>
4962449Speter<LI><A HREF="#introduction">Introduction</A>
5062449Speter<UL>
5162449Speter<LI><A HREF="#history">A Brief History of Curses</A>
5262449Speter<LI><A HREF="#scope">Scope of This Document</A>
5362449Speter<LI><A HREF="#terminology">Terminology</A>
5462449Speter</UL>
5562449Speter<LI><A HREF="#curses">The Curses Library</A>
5662449Speter<UL>
5762449Speter<LI><A HREF="#overview">An Overview of Curses</A>
5862449Speter<UL>
5962449Speter<LI><A HREF="#compiling">Compiling Programs using Curses</A>
6062449Speter<LI><A HREF="#updating">Updating the Screen</A>
6162449Speter<LI><A HREF="#stdscr">Standard Windows and Function Naming Conventions</A>
6262449Speter<LI><A HREF="#variables">Variables</A>
6362449Speter</UL>
6462449Speter<LI><A HREF="#using">Using the Library</A>
6562449Speter<UL>
6662449Speter<LI><A HREF="#starting">Starting up</A>
6762449Speter<LI><A HREF="#output">Output</A>
6862449Speter<LI><A HREF="#input">Input</A>
6962449Speter<LI><A HREF="#formschars">Using Forms Characters</A>
7062449Speter<LI><A HREF="#attributes">Character Attributes and Color</A>
7162449Speter<LI><A HREF="#mouse">Mouse Interfacing</A>
7262449Speter<LI><A HREF="#finishing">Finishing Up</A>
7362449Speter</UL>
7462449Speter<LI><A HREF="#functions">Function Descriptions</A>
7562449Speter<UL>
7662449Speter<LI><A HREF="#init">Initialization and Wrapup</A>
7762449Speter<LI><A HREF="#flush">Causing Output to the Terminal</A>
7862449Speter<LI><A HREF="#lowlevel">Low-Level Capability Access</A>
7962449Speter<LI><A HREF="#debugging">Debugging</A>
8062449Speter</UL>
8162449Speter<LI><A HREF="#hints">Hints, Tips, and Tricks</A>
8262449Speter<UL>
8362449Speter<LI><A HREF="#caution">Some Notes of Caution</A>
8462449Speter<LI><A HREF="#leaving">Temporarily Leaving ncurses Mode</A>
8562449Speter<LI><A HREF="#xterm">Using <CODE>ncurses</CODE> under <CODE>xterm</CODE></A>
8662449Speter<LI><A HREF="#screens">Handling Multiple Terminal Screens</A>
8762449Speter<LI><A HREF="#testing">Testing for Terminal Capabilities</A>
8862449Speter<LI><A HREF="#tuning">Tuning for Speed</A>
8962449Speter<LI><A HREF="#special">Special Features of <CODE>ncurses</CODE></A>
9062449Speter</UL>
9162449Speter<LI><A HREF="#compat">Compatibility with Older Versions</A>
9262449Speter<UL>
9362449Speter<LI><A HREF="#refbug">Refresh of Overlapping Windows</A>
9462449Speter<LI><A HREF="#backbug">Background Erase</A>
9562449Speter</UL>
9662449Speter<LI><A HREF="#xsifuncs">XSI Curses Conformance</A>
9762449Speter</UL>
9862449Speter<LI><A HREF="#panels">The Panels Library</A>
9962449Speter<UL>
10062449Speter<LI><A HREF="#pcompile">Compiling With the Panels Library</A>
10162449Speter<LI><A HREF="#poverview">Overview of Panels</A>
10262449Speter<LI><A HREF="#pstdscr">Panels, Input, and the Standard Screen</A>
10362449Speter<LI><A HREF="#hiding">Hiding Panels</A>
10462449Speter<LI><A HREF="#pmisc">Miscellaneous Other Facilities</A>
10562449Speter</UL>
10662449Speter<LI><A HREF="#menu">The Menu Library</A>
10762449Speter<UL>
10862449Speter<LI><A HREF="#mcompile">Compiling with the menu Library</A>
10962449Speter<LI><A HREF="#moverview">Overview of Menus</A>
11062449Speter<LI><A HREF="#mselect">Selecting items</A>
11162449Speter<LI><A HREF="#mdisplay">Menu Display</A>
11262449Speter<LI><A HREF="#mwindows">Menu Windows</A>
11362449Speter<LI><A HREF="#minput">Processing Menu Input</A>
11462449Speter<LI><A HREF="#mmisc">Miscellaneous Other Features</A>
11562449Speter</UL>
11662449Speter<LI><A HREF="#form">The Forms Library</A>
11762449Speter<UL>
11862449Speter<LI><A HREF="#fcompile">Compiling with the forms Library</A>
11962449Speter<LI><A HREF="#foverview">Overview of Forms</A>
12062449Speter<LI><A HREF="#fcreate">Creating and Freeing Fields and Forms</A>
12162449Speter<LI><A HREF="#fattributes">Fetching and Changing Field Attributes</A>
12262449Speter<UL>
12362449Speter<LI><A HREF="#fsizes">Fetching Size and Location Data</A>
12462449Speter<LI><A HREF="#flocation">Changing the Field Location</A>
12562449Speter<LI><A HREF="#fjust">The Justification Attribute</A>
12662449Speter<LI><A HREF="#fdispatts">Field Display Attributes</A>
12762449Speter<LI><A HREF="#foptions">Field Option Bits</A>
12862449Speter<LI><A HREF="#fstatus">Field Status</A>
12962449Speter<LI><A HREF="#fuser">Field User Pointer</A>
13062449Speter</UL>
13162449Speter<LI><A HREF="#fdynamic">Variable-Sized Fields</A>
13262449Speter<LI><A HREF="#fvalidation">Field Validation</A>
13362449Speter<UL>
13462449Speter<LI><A HREF="#ftype_alpha">TYPE_ALPHA</A>
13562449Speter<LI><A HREF="#ftype_alnum">TYPE_ALNUM</A>
13662449Speter<LI><A HREF="#ftype_enum">TYPE_ENUM</A>
13762449Speter<LI><A HREF="#ftype_integer">TYPE_INTEGER</A>
13862449Speter<LI><A HREF="#ftype_numeric">TYPE_NUMERIC</A>
13962449Speter<LI><A HREF="#ftype_regexp">TYPE_REGEXP</A>
14062449Speter</UL>
14162449Speter<LI><A HREF="#fbuffer">Direct Field Buffer Manipulation</A>
14262449Speter<LI><A HREF="#formattrs">Attributes of Forms</A>
14362449Speter<LI><A HREF="#fdisplay">Control of Form Display</A>
14462449Speter<LI><A HREF="#fdriver">Input Processing in the Forms Driver</A>
14562449Speter<UL>
14662449Speter<LI><A HREF="#fpage">Page Navigation Requests</A>
14762449Speter<LI><A HREF="#ffield">Inter-Field Navigation Requests</A>
14862449Speter<LI><A HREF="#fifield">Intra-Field Navigation Requests</A>
14962449Speter<LI><A HREF="#fscroll">Scrolling Requests</A>
15062449Speter<LI><A HREF="#fedit">Field Editing Requests</A>
15162449Speter<LI><A HREF="#forder">Order Requests</A>
15262449Speter<LI><A HREF="#fappcmds">Application Commands</A>
15362449Speter</UL>
15462449Speter<LI><A HREF="#fhooks">Field Change Hooks</A>
15562449Speter<LI><A HREF="#ffocus">Field Change Commands</A>
15662449Speter<LI><A HREF="#frmoptions">Form Options</A>
15762449Speter<LI><A HREF="#fcustom">Custom Validation Types</A>
15862449Speter<UL>
15962449Speter<LI><A HREF="#flinktypes">Union Types</A>
16062449Speter<LI><A HREF="#fnewtypes">New Field Types</A>
16162449Speter<LI><A HREF="#fcheckargs">Validation Function Arguments</A>
16262449Speter<LI><A HREF="#fcustorder">Order Functions For Custom Types</A>
16362449Speter<LI><A HREF="#fcustprobs">Avoiding Problems</A>
16462449Speter</UL>
16562449Speter</UL>
16662449Speter</UL>
16762449Speter
16862449Speter<HR>
16962449Speter<H1><A NAME="introduction">Introduction</A></H1>
17062449Speter
17162449SpeterThis document is an introduction to programming with <CODE>curses</CODE>. It is
17262449Speternot an exhaustive reference for the curses Application Programming Interface
17362449Speter(API); that role is filled by the <CODE>curses</CODE> manual pages.  Rather, it
17462449Speteris intended to help C programmers ease into using the package. <P>
17562449Speter
17662449SpeterThis document is aimed at C applications programmers not yet specifically
17762449Speterfamiliar with ncurses.  If you are already an experienced <CODE>curses</CODE>
17862449Speterprogrammer, you should nevertheless read the sections on
17962449Speter<A HREF="#mouse">Mouse Interfacing</A>, <A HREF="#debugging">Debugging</A>,
18062449Speter<A HREF="#compat">Compatibility with Older Versions</A>,
18162449Speterand <A HREF="#hints">Hints, Tips, and Tricks</A>.  These will bring you up
18262449Speterto speed on the special features and quirks of the <CODE>ncurses</CODE>
18362449Speterimplementation.  If you are not so experienced, keep reading. <P>
18462449Speter
18562449SpeterThe <CODE>curses</CODE> package is a subroutine library for
18662449Speterterminal-independent screen-painting and input-event handling which
18762449Speterpresents a high level screen model to the programmer, hiding differences
18862449Speterbetween terminal types and doing automatic optimization of output to change
18962449Speterone screen full of text into another.  <CODE>Curses</CODE> uses terminfo, which
19062449Speteris a database format that can describe the capabilities of thousands of
19162449Speterdifferent terminals. <P>
19262449Speter
19362449SpeterThe <CODE>curses</CODE> API may seem something of an archaism on UNIX desktops
19462449Speterincreasingly dominated by X, Motif, and Tcl/Tk.  Nevertheless, UNIX still
19562449Spetersupports tty lines and X supports <EM>xterm(1)</EM>; the <CODE>curses</CODE>
19662449SpeterAPI has the advantage of (a) back-portability to character-cell terminals,
19762449Speterand (b) simplicity.  For an application that does not require bit-mapped
19862449Spetergraphics and multiple fonts, an interface implementation using <CODE>curses</CODE>
19962449Speterwill typically be a great deal simpler and less expensive than one using an
20062449SpeterX toolkit.
20162449Speter
20262449Speter<H2><A NAME="history">A Brief History of Curses</A></H2>
20362449Speter
20462449SpeterHistorically, the first ancestor of <CODE>curses</CODE> was the routines written to
20562449Speterprovide screen-handling for the game <CODE>rogue</CODE>; these used the
20662449Speteralready-existing <CODE>termcap</CODE> database facility for describing terminal
20762449Spetercapabilities.  These routines were abstracted into a documented library and
20862449Speterfirst released with the early BSD UNIX versions. <P>
20962449Speter
21062449SpeterSystem III UNIX from Bell Labs featured a rewritten and much-improved
21162449Speter<CODE>curses</CODE> library.  It introduced the terminfo format.  Terminfo is based
21262449Speteron Berkeley's termcap database, but contains a number of improvements and
21362449Speterextensions. Parameterized capabilities strings were introduced, making it
21462449Speterpossible to describe multiple video attributes, and colors and to handle far
21562449Spetermore unusual terminals than possible with termcap.  In the later AT&amp;T
21662449SpeterSystem V releases, <CODE>curses</CODE> evolved to use more facilities and offer
21762449Spetermore capabilities, going far beyond BSD curses in power and flexibility.
21862449Speter
21962449Speter<H2><A NAME="scope">Scope of This Document</A></H2>
22062449Speter
22162449SpeterThis document describes <CODE>ncurses</CODE>, a free implementation of
22262449Speterthe System V <CODE>curses</CODE> API with some clearly marked extensions.
22362449SpeterIt includes the following System V curses features:
22462449Speter<UL>
22562449Speter<LI>Support for multiple screen highlights (BSD curses could only
22662449Speterhandle one `standout' highlight, usually reverse-video).
22762449Speter<LI>Support for line- and box-drawing using forms characters.
22862449Speter<LI>Recognition of function keys on input.
22962449Speter<LI>Color support.
23062449Speter<LI>Support for pads (windows of larger than screen size on which the
23162449Speterscreen or a subwindow defines a viewport).
23262449Speter</UL>
23362449Speter
23462449SpeterAlso, this package makes use of the insert and delete line and character
23562449Speterfeatures of terminals so equipped, and determines how to optimally use these
23662449Speterfeatures with no help from the programmer.  It allows arbitrary combinations of
23762449Spetervideo attributes to be displayed, even on terminals that leave ``magic
23862449Spetercookies'' on the screen to mark changes in attributes. <P>
23962449Speter
24062449SpeterThe <CODE>ncurses</CODE> package can also capture and use event reports from a
24162449Spetermouse in some environments (notably, xterm under the X window system).  This
24262449Speterdocument includes tips for using the mouse. <P>
24362449Speter
24462449SpeterThe <CODE>ncurses</CODE> package was originated by Pavel Curtis.  The original
24562449Spetermaintainer of this package is
24662449Speter<A HREF="mailto:zmbenhal@netcom.com">Zeyd Ben-Halim</A>
24762449Speter&lt;zmbenhal@netcom.com&gt;.
24862449Speter<A HREF="mailto:esr@snark.thyrsus.com">Eric S. Raymond</A>
24962449Speter&lt;esr@snark.thyrsus.com&gt;
25062449Speterwrote many of the new features in versions after 1.8.1
25162449Speterand wrote most of this introduction.
252166124SrafanJ&uuml;rgen Pfeifer
25362449Speterwrote all of the menu and forms code as well as the
25462449Speter<A HREF="http://www.adahome.com">Ada95</A> binding.
25562449SpeterOngoing work is being done by
256166124Srafan<A HREF="mailto:dickey@invisible-island.net">Thomas Dickey</A> (maintainer).
25762449SpeterContact the current maintainers at
25862449Speter<A HREF="mailto:bug-ncurses@gnu.org">bug-ncurses@gnu.org</A>.
25962449Speter<P>
26062449Speter
26162449SpeterThis document also describes the <A HREF="#panels">panels</A> extension library,
26262449Spetersimilarly modeled on the SVr4 panels facility.  This library allows you to
26362449Speterassociate backing store with each of a stack or deck of overlapping windows,
26462449Speterand provides operations for moving windows around in the stack that change
26562449Spetertheir visibility in the natural way (handling window overlaps). <P>
26662449Speter
26762449SpeterFinally, this document describes in detail the <A HREF="#menu">menus</A> and <A
26862449SpeterHREF="#form">forms</A> extension libraries, also cloned from System V,
26962449Speterwhich support easy construction and sequences of menus and fill-in
27062449Speterforms.
27162449Speter
27262449Speter
27362449Speter<H2><A NAME="terminology">Terminology</A></H2>
27462449Speter
27562449SpeterIn this document, the following terminology is used with reasonable
27662449Speterconsistency:
27762449Speter
27862449Speter<DL>
27962449Speter<DT> window
28062449Speter<DD>
28162449SpeterA data structure describing a sub-rectangle of the screen (possibly the
28262449Speterentire screen).  You can write to a window as though it were a miniature
28362449Speterscreen, scrolling independently of other windows on the physical screen.
28462449Speter<DT> screens
28562449Speter<DD>
28662449SpeterA subset of windows which are as large as the terminal screen, i.e., they start
28762449Speterat the upper left hand corner and encompass the lower right hand corner.  One
28862449Speterof these, <CODE>stdscr</CODE>, is automatically provided for the programmer.
28962449Speter<DT> terminal screen
29062449Speter<DD>
29162449SpeterThe package's idea of what the terminal display currently looks like, i.e.,
29262449Speterwhat the user sees now.  This is a special screen.
29362449Speter</DL>
29462449Speter
29562449Speter<H1><A NAME="curses">The Curses Library</A></H1>
29662449Speter
29762449Speter<H2><A NAME="overview">An Overview of Curses</A></H2>
29862449Speter
29962449Speter<H3><A NAME="compiling">Compiling Programs using Curses</A></H3>
30062449Speter
30162449SpeterIn order to use the library, it is necessary to have certain types and
30262449Spetervariables defined.  Therefore, the programmer must have a line:
30362449Speter
30462449Speter<PRE>
30562449Speter	  #include &lt;curses.h&gt;
30662449Speter</PRE>
30762449Speter
30862449Speterat the top of the program source.  The screen package uses the Standard I/O
30962449Speterlibrary, so <CODE>&lt;curses.h&gt;</CODE> includes
31062449Speter<CODE>&lt;stdio.h&gt;</CODE>. <CODE>&lt;curses.h&gt;</CODE> also includes
31162449Speter<CODE>&lt;termios.h&gt;</CODE>, <CODE>&lt;termio.h&gt;</CODE>, or
31262449Speter<CODE>&lt;sgtty.h&gt;</CODE> depending on your system.  It is redundant (but
31362449Speterharmless) for the programmer to do these includes, too. In linking with
31462449Speter<CODE>curses</CODE> you need to have <CODE>-lncurses</CODE> in your LDFLAGS or on the
31562449Spetercommand line.  There is no need for any other libraries.
31662449Speter
31762449Speter<H3><A NAME="updating">Updating the Screen</A></H3>
31862449Speter
31962449SpeterIn order to update the screen optimally, it is necessary for the routines to
32062449Speterknow what the screen currently looks like and what the programmer wants it to
32162449Speterlook like next. For this purpose, a data type (structure) named WINDOW is
32262449Speterdefined which describes a window image to the routines, including its starting
32362449Speterposition on the screen (the (y, x) coordinates of the upper left hand corner)
32462449Speterand its size.  One of these (called <CODE>curscr</CODE>, for current screen) is a
32562449Speterscreen image of what the terminal currently looks like.  Another screen (called
32662449Speter<CODE>stdscr</CODE>, for standard screen) is provided by default to make changes
32762449Speteron. <P>
32862449Speter
32962449SpeterA window is a purely internal representation. It is used to build and store a
33062449Speterpotential image of a portion of the terminal.  It doesn't bear any necessary
33162449Speterrelation to what is really on the terminal screen; it's more like a
33262449Speterscratchpad or write buffer. <P>
33362449Speter
33462449SpeterTo make the section of physical screen corresponding to a window reflect the
33562449Spetercontents of the window structure, the routine <CODE>refresh()</CODE> (or
33662449Speter<CODE>wrefresh()</CODE> if the window is not <CODE>stdscr</CODE>) is called. <P>
33762449Speter
33862449SpeterA given physical screen section may be within the scope of any number of
33962449Speteroverlapping windows.  Also, changes can be made to windows in any order,
34062449Speterwithout regard to motion efficiency.  Then, at will, the programmer can
34162449Spetereffectively say ``make it look like this,'' and let the package implementation
34262449Speterdetermine the most efficient way to repaint the screen.
34362449Speter
34462449Speter<H3><A NAME="stdscr">Standard Windows and Function Naming Conventions</A></H3>
34562449Speter
34662449SpeterAs hinted above, the routines can use several windows, but two are
34762449Speterautomatically given: <CODE>curscr</CODE>, which knows what the terminal looks like,
34862449Speterand <CODE>stdscr</CODE>, which is what the programmer wants the terminal to look
34962449Speterlike next.  The user should never actually access <CODE>curscr</CODE> directly.
35062449SpeterChanges should be made to through the API, and then the routine
35162449Speter<CODE>refresh()</CODE> (or <CODE>wrefresh()</CODE>) called. <P>
35262449Speter
35362449SpeterMany functions are defined to use <CODE>stdscr</CODE> as a default screen.  For
35462449Speterexample, to add a character to <CODE>stdscr</CODE>, one calls <CODE>addch()</CODE> with
35562449Speterthe desired character as argument.  To write to a different window. use the
35662449Speterroutine <CODE>waddch()</CODE> (for `w'indow-specific addch()) is provided.  This
35762449Speterconvention of prepending function names with a `w' when they are to be
35862449Speterapplied to specific windows is consistent.  The only routines which do not
35962449Speterfollow it are those for which a window must always be specified. <P>
36062449Speter
36162449SpeterIn order to move the current (y, x) coordinates from one point to another, the
36262449Speterroutines <CODE>move()</CODE> and <CODE>wmove()</CODE> are provided.  However, it is
36362449Speteroften desirable to first move and then perform some I/O operation.  In order to
36462449Speteravoid clumsiness, most I/O routines can be preceded by the prefix 'mv' and
36562449Speterthe desired (y, x) coordinates prepended to the arguments to the function.  For
36662449Speterexample, the calls
36762449Speter
36862449Speter<PRE>
36962449Speter	  move(y, x);
37062449Speter	  addch(ch);
37162449Speter</PRE>
37262449Speter
37362449Spetercan be replaced by
37462449Speter
37562449Speter<PRE>
37662449Speter	  mvaddch(y, x, ch);
37762449Speter</PRE>
37862449Speter
37962449Speterand
38062449Speter
38162449Speter<PRE>
38262449Speter	  wmove(win, y, x);
38362449Speter	  waddch(win, ch);
38462449Speter</PRE>
38562449Speter
38662449Spetercan be replaced by
38762449Speter
38862449Speter<PRE>
38962449Speter	  mvwaddch(win, y, x, ch);
39062449Speter</PRE>
39162449Speter
39262449SpeterNote that the window description pointer (win) comes before the added (y, x)
39362449Spetercoordinates.  If a function requires a window pointer, it is always the first
39462449Speterparameter passed.
39562449Speter
39662449Speter<H3><A NAME="variables">Variables</A></H3>
39762449Speter
39862449SpeterThe <CODE>curses</CODE> library sets some variables describing the terminal
39962449Spetercapabilities.
40062449Speter
40162449Speter<PRE>
40262449Speter      type   name      description
40362449Speter      ------------------------------------------------------------------
40462449Speter      int    LINES     number of lines on the terminal
40562449Speter      int    COLS      number of columns on the terminal
40662449Speter</PRE>
40762449Speter
40862449SpeterThe <CODE>curses.h</CODE> also introduces some <CODE>#define</CODE> constants and types
40962449Speterof general usefulness:
41062449Speter
41162449Speter<DL>
41262449Speter<DT> <CODE>bool</CODE>
41362449Speter<DD> boolean type, actually a `char' (e.g., <CODE>bool doneit;</CODE>)
41462449Speter<DT> <CODE>TRUE</CODE>
41562449Speter<DD> boolean `true' flag (1).
41662449Speter<DT> <CODE>FALSE</CODE>
41762449Speter<DD> boolean `false' flag (0).
41862449Speter<DT> <CODE>ERR</CODE>
41962449Speter<DD> error flag returned by routines on a failure (-1).
42062449Speter<DT> <CODE>OK</CODE>
42162449Speter<DD> error flag returned by routines when things go right.
42262449Speter</DL>
42362449Speter
42462449Speter<H2><A NAME="using">Using the Library</A></H2>
42562449Speter
42662449SpeterNow we describe how to actually use the screen package.  In it, we assume all
42762449Speterupdating, reading, etc. is applied to <CODE>stdscr</CODE>.  These instructions will
42862449Speterwork on any window, providing you change the function names and parameters as
42962449Spetermentioned above. <P>
43062449Speter
43162449SpeterHere is a sample program to motivate the discussion:
43262449Speter
43362449Speter<PRE>
43462449Speter#include &lt;curses.h&gt;
43562449Speter#include &lt;signal.h&gt;
43662449Speter
43762449Speterstatic void finish(int sig);
43862449Speter
43962449Speterint
44062449Spetermain(int argc, char *argv[])
44162449Speter{
44262449Speter    int num = 0;
44362449Speter
44462449Speter    /* initialize your non-curses data structures here */
44562449Speter
44662449Speter    (void) signal(SIGINT, finish);      /* arrange interrupts to terminate */
44762449Speter
44862449Speter    (void) initscr();      /* initialize the curses library */
44962449Speter    keypad(stdscr, TRUE);  /* enable keyboard mapping */
45062449Speter    (void) nonl();         /* tell curses not to do NL-&gt;CR/NL on output */
45162449Speter    (void) cbreak();       /* take input chars one at a time, no wait for \n */
45262449Speter    (void) echo();         /* echo input - in color */
45362449Speter
45462449Speter    if (has_colors())
45562449Speter    {
45662449Speter        start_color();
45762449Speter
45862449Speter        /*
45962449Speter         * Simple color assignment, often all we need.  Color pair 0 cannot
46062449Speter	 * be redefined.  This example uses the same value for the color
46162449Speter	 * pair as for the foreground color, though of course that is not
46262449Speter	 * necessary:
46362449Speter         */
46462449Speter        init_pair(1, COLOR_RED,     COLOR_BLACK);
46562449Speter        init_pair(2, COLOR_GREEN,   COLOR_BLACK);
46662449Speter        init_pair(3, COLOR_YELLOW,  COLOR_BLACK);
46762449Speter        init_pair(4, COLOR_BLUE,    COLOR_BLACK);
46862449Speter        init_pair(5, COLOR_CYAN,    COLOR_BLACK);
46962449Speter        init_pair(6, COLOR_MAGENTA, COLOR_BLACK);
47062449Speter        init_pair(7, COLOR_WHITE,   COLOR_BLACK);
47162449Speter    }
47262449Speter
47362449Speter    for (;;)
47462449Speter    {
47562449Speter        int c = getch();     /* refresh, accept single keystroke of input */
47662449Speter	attrset(COLOR_PAIR(num % 8));
47762449Speter	num++;
47862449Speter
47962449Speter        /* process the command keystroke */
48062449Speter    }
48162449Speter
48262449Speter    finish(0);               /* we're done */
48362449Speter}
48462449Speter
48562449Speterstatic void finish(int sig)
48662449Speter{
48762449Speter    endwin();
48862449Speter
48962449Speter    /* do your non-curses wrapup here */
49062449Speter
49162449Speter    exit(0);
49262449Speter}
49362449Speter</PRE>
49462449Speter
49562449Speter<H3><A NAME="starting">Starting up</A></H3>
49662449Speter
49762449SpeterIn order to use the screen package, the routines must know about terminal
49862449Spetercharacteristics, and the space for <CODE>curscr</CODE> and <CODE>stdscr</CODE> must be
49962449Speterallocated.  These function <CODE>initscr()</CODE> does both these things. Since it
50062449Spetermust allocate space for the windows, it can overflow memory when attempting to
50162449Speterdo so. On the rare occasions this happens, <CODE>initscr()</CODE> will terminate
50262449Speterthe program with an error message.  <CODE>initscr()</CODE> must always be called
50362449Speterbefore any of the routines which affect windows are used.  If it is not, the
50462449Speterprogram will core dump as soon as either <CODE>curscr</CODE> or <CODE>stdscr</CODE> are
50562449Speterreferenced.  However, it is usually best to wait to call it until after you are
50662449Spetersure you will need it, like after checking for startup errors.  Terminal status
50762449Speterchanging routines like <CODE>nl()</CODE> and <CODE>cbreak()</CODE> should be called
50862449Speterafter <CODE>initscr()</CODE>. <P>
50962449Speter
51062449SpeterOnce the screen windows have been allocated, you can set them up for
51162449Speteryour program.  If you want to, say, allow a screen to scroll, use
51262449Speter<CODE>scrollok()</CODE>.  If you want the cursor to be left in place after
51362449Speterthe last change, use <CODE>leaveok()</CODE>.  If this isn't done,
51462449Speter<CODE>refresh()</CODE> will move the cursor to the window's current (y, x)
51562449Spetercoordinates after updating it. <P>
51662449Speter
51762449SpeterYou can create new windows of your own using the functions <CODE>newwin()</CODE>,
51862449Speter<CODE>derwin()</CODE>, and <CODE>subwin()</CODE>.  The routine <CODE>delwin()</CODE> will
51962449Speterallow you to get rid of old windows.  All the options described above can be
52062449Speterapplied to any window.
52162449Speter
52262449Speter<H3><A NAME="output">Output</A></H3>
52362449Speter
52462449SpeterNow that we have set things up, we will want to actually update the terminal.
52562449SpeterThe basic functions used to change what will go on a window are
52662449Speter<CODE>addch()</CODE> and <CODE>move()</CODE>.  <CODE>addch()</CODE> adds a character at the
52762449Spetercurrent (y, x) coordinates.  <CODE>move()</CODE> changes the current (y, x)
52862449Spetercoordinates to whatever you want them to be.  It returns <CODE>ERR</CODE> if you
52962449Spetertry to move off the window.  As mentioned above, you can combine the two into
53062449Speter<CODE>mvaddch()</CODE> to do both things at once. <P>
53162449Speter
53262449SpeterThe other output functions, such as <CODE>addstr()</CODE> and <CODE>printw()</CODE>,
53362449Speterall call <CODE>addch()</CODE> to add characters to the window. <P>
53462449Speter
53562449SpeterAfter you have put on the window what you want there, when you want the portion
53662449Speterof the terminal covered by the window to be made to look like it, you must call
53762449Speter<CODE>refresh()</CODE>.  In order to optimize finding changes, <CODE>refresh()</CODE>
53862449Speterassumes that any part of the window not changed since the last
53962449Speter<CODE>refresh()</CODE> of that window has not been changed on the terminal, i.e.,
54062449Speterthat you have not refreshed a portion of the terminal with an overlapping
54162449Speterwindow.  If this is not the case, the routine <CODE>touchwin()</CODE> is provided
54262449Speterto make it look like the entire window has been changed, thus making
54362449Speter<CODE>refresh()</CODE> check the whole subsection of the terminal for changes. <P>
54462449Speter
54562449SpeterIf you call <CODE>wrefresh()</CODE> with <CODE>curscr</CODE> as its argument, it will
54662449Spetermake the screen look like <CODE>curscr</CODE> thinks it looks like.  This is useful
54762449Speterfor implementing a command which would redraw the screen in case it get messed
54862449Speterup.
54962449Speter
55062449Speter<H3><A NAME="input">Input</A></H3>
55162449Speter
55262449SpeterThe complementary function to <CODE>addch()</CODE> is <CODE>getch()</CODE> which, if
55362449Speterecho is set, will call <CODE>addch()</CODE> to echo the character.  Since the
55462449Speterscreen package needs to know what is on the terminal at all times, if
55562449Spetercharacters are to be echoed, the tty must be in raw or cbreak mode.  Since
55662449Speterinitially the terminal has echoing enabled and is in ordinary ``cooked'' mode,
55762449Speterone or the other has to changed before calling <CODE>getch()</CODE>; otherwise,
55862449Speterthe program's output will be unpredictable. <P>
55962449Speter
56062449SpeterWhen you need to accept line-oriented input in a window, the functions
56162449Speter<CODE>wgetstr()</CODE> and friends are available.  There is even a <CODE>wscanw()</CODE>
56262449Speterfunction that can do <CODE>scanf()</CODE>(3)-style multi-field parsing on window
56362449Speterinput.  These pseudo-line-oriented functions turn on echoing while they
56462449Speterexecute. <P>
56562449Speter
56662449SpeterThe example code above uses the call <CODE>keypad(stdscr, TRUE)</CODE> to enable
56762449Spetersupport for function-key mapping.  With this feature, the <CODE>getch()</CODE> code
56862449Speterwatches the input stream for character sequences that correspond to arrow and
56962449Speterfunction keys.  These sequences are returned as pseudo-character values.  The
57062449Speter<CODE>#define</CODE> values returned are listed in the <CODE>curses.h</CODE> The
57162449Spetermapping from sequences to <CODE>#define</CODE> values is determined by
57262449Speter<CODE>key_</CODE> capabilities in the terminal's terminfo entry.
57362449Speter
57462449Speter<H3><A NAME="formschars">Using Forms Characters</A></H3>
57562449Speter
57662449SpeterThe <CODE>addch()</CODE> function (and some others, including <CODE>box()</CODE> and
57762449Speter<CODE>border()</CODE>) can accept some pseudo-character arguments which are specially
57862449Speterdefined by <CODE>ncurses</CODE>.  These are <CODE>#define</CODE> values set up in
57962449Speterthe <CODE>curses.h</CODE> header; see there for a complete list (look for
58062449Speterthe prefix <CODE>ACS_</CODE>). <P>
58162449Speter
58262449SpeterThe most useful of the ACS defines are the forms-drawing characters.  You can
58362449Speteruse these to draw boxes and simple graphs on the screen.  If the terminal
58462449Speterdoes not have such characters, <CODE>curses.h</CODE> will map them to a
58562449Speterrecognizable (though ugly) set of ASCII defaults.
58662449Speter
58762449Speter<H3><A NAME="attributes">Character Attributes and Color</A></H3>
58862449Speter
58962449SpeterThe <CODE>ncurses</CODE> package supports screen highlights including standout,
59062449Speterreverse-video, underline, and blink.  It also supports color, which is treated
59162449Speteras another kind of highlight. <P>
59262449Speter
59362449SpeterHighlights are encoded, internally, as high bits of the pseudo-character type
59462449Speter(<CODE>chtype</CODE>) that <CODE>curses.h</CODE> uses to represent the contents of a
59562449Speterscreen cell.  See the <CODE>curses.h</CODE> header file for a complete list of
59662449Speterhighlight mask values (look for the prefix <CODE>A_</CODE>).<P>
59762449Speter
59862449SpeterThere are two ways to make highlights.  One is to logical-or the value of the
59962449Speterhighlights you want into the character argument of an <CODE>addch()</CODE> call,
60062449Speteror any other output call that takes a <CODE>chtype</CODE> argument. <P>
60162449Speter
60262449SpeterThe other is to set the current-highlight value.  This is logical-or'ed with
60362449Speterany highlight you specify the first way.  You do this with the functions
60462449Speter<CODE>attron()</CODE>, <CODE>attroff()</CODE>, and <CODE>attrset()</CODE>; see the manual
60562449Speterpages for details.
60662449Speter
60762449SpeterColor is a special kind of highlight.  The package actually thinks in terms
60862449Speterof color pairs, combinations of foreground and background colors.  The sample
60962449Spetercode above sets up eight color pairs, all of the guaranteed-available colors
61062449Speteron black.  Note that each color pair is, in effect, given the name of its
61162449Speterforeground color.  Any other range of eight non-conflicting values could
61262449Speterhave been used as the first arguments of the <CODE>init_pair()</CODE> values. <P>
61362449Speter
61462449SpeterOnce you've done an <CODE>init_pair()</CODE> that creates color-pair N, you can
61562449Speteruse <CODE>COLOR_PAIR(N)</CODE> as a highlight that invokes that particular
61662449Spetercolor combination.  Note that <CODE>COLOR_PAIR(N)</CODE>, for constant N,
61762449Speteris itself a compile-time constant and can be used in initializers.
61862449Speter
61962449Speter<H3><A NAME="mouse">Mouse Interfacing</A></H3>
62062449Speter
62162449SpeterThe <CODE>ncurses</CODE> library also provides a mouse interface.
62262449Speter<!-- The 'note' tag is not portable enough -->
62362449Speter<blockquote>
62462449Speter<strong>NOTE:</strong> this facility is specific to <CODE>ncurses</CODE>, it is not part of either
62562449Speterthe XSI Curses standard, nor of System V Release 4, nor BSD curses.
62662449SpeterSystem V Release 4 curses contains code with similar interface definitions,
62762449Speterhowever it is not documented.  Other than by disassembling the library, we
62862449Speterhave no way to determine exactly how that mouse code works.
62962449SpeterThus, we recommend that you wrap mouse-related code in an #ifdef using the
63062449Speterfeature macro NCURSES_MOUSE_VERSION so it will not be compiled and linked
63162449Speteron non-ncurses systems.
63262449Speter</blockquote>
63362449Speter
63462449SpeterPresently, mouse event reporting works in the following environments:
63562449Speter<ul>
63662449Speter<li>xterm and similar programs such as rxvt.
63762449Speter<li>Linux console, when configured with <CODE>gpm</CODE>(1), Alessandro
63862449SpeterRubini's mouse server.
639166124Srafan<li>FreeBSD sysmouse (console)
64062449Speter<li>OS/2 EMX
64162449Speter</ul>
64262449Speter<P>
64362449SpeterThe mouse interface is very simple.  To activate it, you use the function
64462449Speter<CODE>mousemask()</CODE>, passing it as first argument a bit-mask that specifies
64562449Speterwhat kinds of events you want your program to be able to see.  It will
64662449Speterreturn the bit-mask of events that actually become visible, which may differ
64762449Speterfrom the argument if the mouse device is not capable of reporting some of
64862449Speterthe event types you specify. <P>
64962449Speter
65062449SpeterOnce the mouse is active, your application's command loop should watch
65162449Speterfor a return value of <CODE>KEY_MOUSE</CODE> from <CODE>wgetch()</CODE>.  When
65262449Speteryou see this, a mouse event report has been queued.  To pick it off
65362449Speterthe queue, use the function <CODE>getmouse()</CODE> (you must do this before
65462449Speterthe next <CODE>wgetch()</CODE>, otherwise another mouse event might come
65562449Speterin and make the first one inaccessible). <P>
65662449Speter
65762449SpeterEach call to <CODE>getmouse()</CODE> fills a structure (the address of which you'll
65862449Speterpass it) with mouse event data.  The event data includes zero-origin,
65962449Speterscreen-relative character-cell coordinates of the mouse pointer.  It also
66062449Speterincludes an event mask.  Bits in this mask will be set, corresponding
66162449Speterto the event type being reported. <P>
66262449Speter
66362449SpeterThe mouse structure contains two additional fields which may be
66462449Spetersignificant in the future as ncurses interfaces to new kinds of
66562449Speterpointing device.  In addition to x and y coordinates, there is a slot
66662449Speterfor a z coordinate; this might be useful with touch-screens that can
66762449Speterreturn a pressure or duration parameter.  There is also a device ID
66862449Speterfield, which could be used to distinguish between multiple pointing
66962449Speterdevices. <P>
67062449Speter
67162449SpeterThe class of visible events may be changed at any time via <CODE>mousemask()</CODE>.
67262449SpeterEvents that can be reported include presses, releases, single-, double- and
67362449Spetertriple-clicks (you can set the maximum button-down time for clicks).  If
67462449Speteryou don't make clicks visible, they will be reported as press-release
67562449Speterpairs.  In some environments, the event mask may include bits reporting
67662449Speterthe state of shift, alt, and ctrl keys on the keyboard during the event. <P>
67762449Speter
67862449SpeterA function to check whether a mouse event fell within a given window is
67962449Speteralso supplied.  You can use this to see whether a given window should
68062449Speterconsider a mouse event relevant to it. <P>
68162449Speter
68262449SpeterBecause mouse event reporting will not be available in all
68362449Speterenvironments, it would be unwise to build <CODE>ncurses</CODE>
68462449Speterapplications that <EM>require</EM> the use of a mouse.  Rather, you should
68562449Speteruse the mouse as a shortcut for point-and-shoot commands your application
68662449Speterwould normally accept from the keyboard.  Two of the test games in the
68762449Speter<CODE>ncurses</CODE> distribution (<CODE>bs</CODE> and <CODE>knight</CODE>) contain
68862449Spetercode that illustrates how this can be done. <P>
68962449Speter
69062449SpeterSee the manual page <CODE>curs_mouse(3X)</CODE> for full details of the
69162449Spetermouse-interface functions.
69262449Speter
69362449Speter<H3><A NAME="finishing">Finishing Up</A></H3>
69462449Speter
69562449SpeterIn order to clean up after the <CODE>ncurses</CODE> routines, the routine
69662449Speter<CODE>endwin()</CODE> is provided.  It restores tty modes to what they were when
69762449Speter<CODE>initscr()</CODE> was first called, and moves the cursor down to the
69862449Speterlower-left corner.  Thus, anytime after the call to initscr, <CODE>endwin()</CODE>
69962449Spetershould be called before exiting.
70062449Speter
70162449Speter<H2><A NAME="functions">Function Descriptions</A></H2>
70262449Speter
70362449SpeterWe describe the detailed behavior of some important curses functions here, as a
70462449Spetersupplement to the manual page descriptions.
70562449Speter
70662449Speter<H3><A NAME="init">Initialization and Wrapup</A></H3>
70762449Speter
70862449Speter<DL>
70962449Speter<DT> <CODE>initscr()</CODE>
71062449Speter<DD> The first function called should almost always be <CODE>initscr()</CODE>.
71162449SpeterThis will determine the terminal type and
71262449Speterinitialize curses data structures. <CODE>initscr()</CODE> also arranges that
71362449Speterthe first call to <CODE>refresh()</CODE> will clear the screen.  If an error
71462449Speteroccurs a message is written to standard error and the program
71562449Speterexits. Otherwise it returns a pointer to stdscr.  A few functions may be
71662449Spetercalled before initscr (<CODE>slk_init()</CODE>, <CODE>filter()</CODE>,
717166124Srafan<CODE>ripoffline()</CODE>, <CODE>use_env()</CODE>, and, if you are using multiple
71862449Speterterminals, <CODE>newterm()</CODE>.)
71962449Speter<DT> <CODE>endwin()</CODE>
72062449Speter<DD> Your program should always call <CODE>endwin()</CODE> before exiting or
72162449Spetershelling out of the program. This function will restore tty modes,
72262449Spetermove the cursor to the lower left corner of the screen, reset the
72362449Speterterminal into the proper non-visual mode.  Calling <CODE>refresh()</CODE>
72462449Speteror <CODE>doupdate()</CODE> after a temporary escape from the program will
72562449Speterrestore the ncurses screen from before the escape.
72662449Speter<DT> <CODE>newterm(type, ofp, ifp)</CODE>
72762449Speter<DD> A program which outputs to more than one terminal should use
72862449Speter<CODE>newterm()</CODE> instead of <CODE>initscr()</CODE>.  <CODE>newterm()</CODE> should
72962449Speterbe called once for each terminal.  It returns a variable of type
73062449Speter<CODE>SCREEN *</CODE> which should be saved as a reference to that
73197049Speterterminal.
73297049Speter(NOTE: a SCREEN variable is not a <em>screen</em> in the sense we
73397049Speterare describing in this introduction, but a collection of 
73497049Speterparameters used to assist in optimizing the display.)
73597049SpeterThe arguments are the type of the terminal (a string) and
73662449Speter<CODE>FILE</CODE> pointers for the output and input of the terminal.  If
73762449Spetertype is NULL then the environment variable <CODE>$TERM</CODE> is used.
73862449Speter<CODE>endwin()</CODE> should called once at wrapup time for each terminal
73962449Speteropened using this function.
74062449Speter<DT> <CODE>set_term(new)</CODE>
74162449Speter<DD> This function is used to switch to a different terminal previously
74262449Speteropened by <CODE>newterm()</CODE>.  The screen reference for the new terminal
74362449Speteris passed as the parameter.  The previous terminal is returned by the
74462449Speterfunction.  All other calls affect only the current terminal.
74562449Speter<DT> <CODE>delscreen(sp)</CODE>
74662449Speter<DD> The inverse of <CODE>newterm()</CODE>; deallocates the data structures
74762449Speterassociated with a given <CODE>SCREEN</CODE> reference.
74862449Speter</DL>
74962449Speter
75062449Speter<H3><A NAME="flush">Causing Output to the Terminal</A></H3>
75162449Speter
75262449Speter<DL>
75362449Speter<DT> <CODE>refresh()</CODE> and <CODE>wrefresh(win)</CODE>
75462449Speter<DD> These functions must be called to actually get any output on
75562449Speterthe  terminal,  as  other  routines  merely  manipulate data
75662449Speterstructures.  <CODE>wrefresh()</CODE> copies the named window  to the physical
75762449Speterterminal screen,  taking  into account  what is already
75862449Speterthere in  order to  do optimizations.  <CODE>refresh()</CODE> does a
759166124Srafanrefresh of <CODE>stdscr</CODE>.   Unless <CODE>leaveok()</CODE> has been
76062449Speterenabled, the physical cursor of the terminal is left at  the
76162449Speterlocation of the window's cursor.
76262449Speter<DT> <CODE>doupdate()</CODE> and <CODE>wnoutrefresh(win)</CODE>
76362449Speter<DD> These two functions allow multiple updates with more efficiency
76462449Speterthan wrefresh.  To use them, it is important to understand how curses
76562449Speterworks.  In addition to all the window structures, curses keeps two
76662449Speterdata structures representing the terminal screen: a physical screen,
76762449Speterdescribing what is actually on the screen, and a virtual screen,
76862449Speterdescribing what the programmer wants to have on the screen.  wrefresh
76962449Speterworks by first copying the named window to the virtual screen
77062449Speter(<CODE>wnoutrefresh()</CODE>), and then calling the routine to update the
77162449Speterscreen (<CODE>doupdate()</CODE>).  If the programmer wishes to output
77262449Speterseveral windows at once, a series of calls to <CODE>wrefresh</CODE> will result
77362449Speterin alternating calls to <CODE>wnoutrefresh()</CODE> and <CODE>doupdate()</CODE>,
77462449Spetercausing several bursts of output to the screen.  By calling
77562449Speter<CODE>wnoutrefresh()</CODE> for each window, it is then possible to call
77662449Speter<CODE>doupdate()</CODE> once, resulting in only one burst of output, with
77762449Speterfewer total characters transmitted (this also avoids a visually annoying
77862449Speterflicker at each update).
77962449Speter</DL>
78062449Speter
78162449Speter<H3><A NAME="lowlevel">Low-Level Capability Access</A></H3>
78262449Speter
78362449Speter<DL>
78462449Speter<DT> <CODE>setupterm(term, filenum, errret)</CODE>
78562449Speter<DD> This routine is called to initialize a terminal's description, without setting
78662449Speterup the curses screen structures or changing the tty-driver mode bits.
78762449Speter<CODE>term</CODE> is the character string representing the name of the terminal
78862449Speterbeing used.  <CODE>filenum</CODE> is the UNIX file descriptor of the terminal to
78962449Speterbe used for output.  <CODE>errret</CODE> is a pointer to an integer, in which a
79062449Spetersuccess or failure indication is returned.  The values returned can be 1 (all
79162449Speteris well), 0 (no such terminal), or -1 (some problem locating the terminfo
79262449Speterdatabase). <P>
79362449Speter
79462449SpeterThe value of <CODE>term</CODE> can be given as NULL, which will cause the value of
79562449Speter<CODE>TERM</CODE> in the environment to be used.  The <CODE>errret</CODE> pointer can
79662449Speteralso be given as NULL, meaning no error code is wanted.  If <CODE>errret</CODE> is
79762449Speterdefaulted, and something goes wrong, <CODE>setupterm()</CODE> will print an
79862449Speterappropriate error message and exit, rather than returning.  Thus, a simple
79962449Speterprogram can call setupterm(0, 1, 0) and not worry about initialization
80062449Spetererrors. <P>
80162449Speter
80262449SpeterAfter the call to <CODE>setupterm()</CODE>, the global variable <CODE>cur_term</CODE> is
80362449Speterset to point to the current structure of terminal capabilities. By calling
80462449Speter<CODE>setupterm()</CODE> for each terminal, and saving and restoring
80562449Speter<CODE>cur_term</CODE>, it is possible for a program to use two or more terminals at
80662449Speteronce.  <CODE>Setupterm()</CODE> also stores the names section of the terminal
80762449Speterdescription in the global character array <CODE>ttytype[]</CODE>.  Subsequent calls
80862449Speterto <CODE>setupterm()</CODE> will overwrite this array, so you'll have to save it
80962449Speteryourself if need be.
81062449Speter</DL>
81162449Speter
81262449Speter<H3><A NAME="debugging">Debugging</A></H3>
81362449Speter
81462449Speter<!-- The 'note' tag is not portable enough -->
81562449Speter<blockquote>
81662449Speter<strong>NOTE:</strong> These functions are not part of the standard curses API!
81762449Speter</blockquote>
81862449Speter
81962449Speter<DL>
82062449Speter<DT> <CODE>trace()</CODE>
82162449Speter<DD>
82262449SpeterThis function can be used to explicitly set a trace level.  If the
82362449Spetertrace level is nonzero, execution of your program will generate a file
82462449Spetercalled `trace' in the current working directory containing a report on
82562449Speterthe library's actions.  Higher trace levels enable more detailed (and
82662449Speterverbose) reporting -- see comments attached to <CODE>TRACE_</CODE> defines
82762449Speterin the <CODE>curses.h</CODE> file for details.  (It is also possible to set
82862449Spetera trace level by assigning a trace level value to the environment variable
82962449Speter<CODE>NCURSES_TRACE</CODE>).
83062449Speter<DT> <CODE>_tracef()</CODE>
83162449Speter<DD>
83262449SpeterThis function can be used to output your own debugging information.  It is only
83362449Speteravailable only if you link with -lncurses_g.  It can be used the same way as
83462449Speter<CODE>printf()</CODE>, only it outputs a newline after the end of arguments.
83562449SpeterThe output goes to a file called <CODE>trace</CODE> in the current directory.
83662449Speter</DL>
83762449Speter
83862449SpeterTrace logs can be difficult to interpret due to the sheer volume of
83962449Speterdata dumped in them.  There is a script called <STRONG>tracemunch</STRONG>
84062449Speterincluded with the <CODE>ncurses</CODE> distribution that can alleviate
84162449Speterthis problem somewhat; it compacts long sequences of similar operations into
84262449Spetermore succinct single-line pseudo-operations. These pseudo-ops can be
84362449Speterdistinguished by the fact that they are named in capital letters.
84462449Speter
84562449Speter<H2><A NAME="hints">Hints, Tips, and Tricks</A></H2>
84662449Speter
84762449SpeterThe <CODE>ncurses</CODE> manual pages are a complete reference for this library.
84862449SpeterIn the remainder of this document, we discuss various useful methods that
84962449Spetermay not be obvious from the manual page descriptions.
85062449Speter
85162449Speter<H3><A NAME="caution">Some Notes of Caution</A></H3>
85262449Speter
85362449SpeterIf you find yourself thinking you need to use <CODE>noraw()</CODE> or
85462449Speter<CODE>nocbreak()</CODE>, think again and move carefully.  It's probably
85562449Speterbetter design to use <CODE>getstr()</CODE> or one of its relatives to
85662449Spetersimulate cooked mode.  The <CODE>noraw()</CODE> and <CODE>nocbreak()</CODE>
85762449Speterfunctions try to restore cooked mode, but they may end up clobbering
85862449Spetersome control bits set before you started your application.  Also, they
85962449Speterhave always been poorly documented, and are likely to hurt your
86062449Speterapplication's usability with other curses libraries. <P>
86162449Speter
86262449SpeterBear in mind that <CODE>refresh()</CODE> is a synonym for <CODE>wrefresh(stdscr)</CODE>.
86362449SpeterDon't try to mix use of <CODE>stdscr</CODE> with use of windows declared
86462449Speterby <CODE>newwin()</CODE>; a <CODE>refresh()</CODE> call will blow them off the
86562449Speterscreen.  The right way to handle this is to use <CODE>subwin()</CODE>, or
86662449Speternot touch <CODE>stdscr</CODE> at all and tile your screen with declared
86762449Speterwindows which you then <CODE>wnoutrefresh()</CODE> somewhere in your program
86862449Speterevent loop, with a single <CODE>doupdate()</CODE> call to trigger actual
86962449Speterrepainting. <P>
87062449Speter
87162449SpeterYou are much less likely to run into problems if you design your screen
87262449Speterlayouts to use tiled rather than overlapping windows.  Historically,
87362449Spetercurses support for overlapping windows has been weak, fragile, and poorly
87462449Speterdocumented.  The <CODE>ncurses</CODE> library is not yet an exception to this
87562449Speterrule. <P>
87662449Speter
87762449SpeterThere is a panels library included in the <CODE>ncurses</CODE>
87862449Speterdistribution that does a pretty good job of strengthening the
87962449Speteroverlapping-windows facilities. <P>
88062449Speter
88162449SpeterTry to avoid using the global variables LINES and COLS.  Use
88262449Speter<CODE>getmaxyx()</CODE> on the <CODE>stdscr</CODE> context instead.  Reason:
88362449Speteryour code may be ported to run in an environment with window resizes,
88462449Speterin which case several screens could be open with different sizes.
88562449Speter
88662449Speter<H3><A NAME="leaving">Temporarily Leaving NCURSES Mode</A></H3>
88762449Speter
88862449SpeterSometimes you will want to write a program that spends most of its time in
88962449Speterscreen mode, but occasionally returns to ordinary `cooked' mode.  A common
89062449Speterreason for this is to support shell-out.  This behavior is simple to arrange
89162449Speterin <CODE>ncurses</CODE>. <P>
89262449Speter
89362449SpeterTo leave <CODE>ncurses</CODE> mode, call <CODE>endwin()</CODE> as you would if you
89462449Speterwere intending to terminate the program.  This will take the screen back to
89562449Spetercooked mode; you can do your shell-out.  When you want to return to
89662449Speter<CODE>ncurses</CODE> mode, simply call <CODE>refresh()</CODE> or <CODE>doupdate()</CODE>.
89762449SpeterThis will repaint the screen. <P>
89862449Speter
89962449SpeterThere is a boolean function, <CODE>isendwin()</CODE>, which code can use to
90062449Spetertest whether <CODE>ncurses</CODE> screen mode is active.  It returns <CODE>TRUE</CODE>
90162449Speterin the interval between an <CODE>endwin()</CODE> call and the following
90262449Speter<CODE>refresh()</CODE>, <CODE>FALSE</CODE> otherwise.  <P>
90362449Speter
90462449SpeterHere is some sample code for shellout:
90562449Speter
90662449Speter<PRE>
90762449Speter    addstr("Shelling out...");
90862449Speter    def_prog_mode();           /* save current tty modes */
90962449Speter    endwin();                  /* restore original tty modes */
91062449Speter    system("sh");              /* run shell */
91162449Speter    addstr("returned.\n");     /* prepare return message */
91262449Speter    refresh();                 /* restore save modes, repaint screen */
91362449Speter</PRE>
91462449Speter
91562449Speter<H3><A NAME="xterm">Using NCURSES under XTERM</A></H3>
91662449Speter
917174993SrafanA resize operation in X sends <CODE>SIGWINCH</CODE> to the application running
918174993Srafanunder xterm.
91962449Speter
920174993SrafanThe easiest way to handle <CODE>SIGWINCH</CODE>
921174993Srafanis to do an <CODE>endwin</CODE>,
922174993Srafanfollowed by an <CODE>refresh</CODE> and a screen repaint you code
923174993Srafanyourself.
924174993SrafanThe <CODE>refresh</CODE> will pick up the new screen size from the
92562449Speterxterm's environment. <P>
92662449Speter
92762449SpeterThat is the standard way, of course (it even works with some vendor's curses
92862449Speterimplementations).
92962449SpeterIts drawback is that it clears the screen to reinitialize the display, and does
93062449Speternot resize subwindows which must be shrunk.
93162449Speter<CODE>Ncurses</CODE> provides an extension which works better, the
93262449Speter<CODE>resizeterm</CODE> function.  That function ensures that all windows
93362449Speterare limited to the new screen dimensions, and pads <CODE>stdscr</CODE>
93462449Speterwith blanks if the screen is larger. <P>
93562449Speter
936174993SrafanThe <CODE>ncurses</CODE> library provides a SIGWINCH signal handler,
937174993Srafanwhich pushes a <CODE>KEY_RESIZE</CODE> via the wgetch() calls.
938174993SrafanWhen <CODE>ncurses</CODE> returns that code,
939174993Srafanit calls <code>resizeterm</CODE>
940174993Srafanto update the size of the standard screen's window, repainting that
941174993Srafan(filling with blanks or truncating as needed).
942174993SrafanIt also resizes other windows,
943174993Srafanbut its effect may be less satisfactory because it cannot
944174993Srafanknow how you want the screen re-painted.
945174993SrafanYou will usually have to write special-purpose code to handle
946174993Srafan<CODE>KEY_RESIZE</CODE> yourself.
94762449Speter
94862449Speter<H3><A NAME="screens">Handling Multiple Terminal Screens</A></H3>
94962449Speter
95062449SpeterThe <CODE>initscr()</CODE> function actually calls a function named
95162449Speter<CODE>newterm()</CODE> to do most of its work.  If you are writing a program that
95262449Speteropens multiple terminals, use <CODE>newterm()</CODE> directly. <P>
95362449Speter
95462449SpeterFor each call, you will have to specify a terminal type and a pair of file
95562449Speterpointers; each call will return a screen reference, and <CODE>stdscr</CODE> will be
95662449Speterset to the last one allocated.  You will switch between screens with the
95762449Speter<CODE>set_term</CODE> call.  Note that you will also have to call
95862449Speter<CODE>def_shell_mode</CODE> and <CODE>def_prog_mode</CODE> on each tty yourself.
95962449Speter
96062449Speter<H3><A NAME="testing">Testing for Terminal Capabilities</A></H3>
96162449Speter
96262449SpeterSometimes you may want to write programs that test for the presence of various
96362449Spetercapabilities before deciding whether to go into <CODE>ncurses</CODE> mode.  An easy
96462449Speterway to do this is to call <CODE>setupterm()</CODE>, then use the functions
96562449Speter<CODE>tigetflag()</CODE>, <CODE>tigetnum()</CODE>, and <CODE>tigetstr()</CODE> to do your
96662449Spetertesting. <P>
96762449Speter
96862449SpeterA particularly useful case of this often comes up when you want to
96962449Spetertest whether a given terminal type should be treated as `smart'
97062449Speter(cursor-addressable) or `stupid'.  The right way to test this is to see
97162449Speterif the return value of <CODE>tigetstr("cup")</CODE> is non-NULL.  Alternatively,
97262449Speteryou can include the <CODE>term.h</CODE> file and test the value of the
97362449Spetermacro <CODE>cursor_address</CODE>.
97462449Speter
97562449Speter<H3><A NAME="tuning">Tuning for Speed</A></H3>
97662449Speter
97762449SpeterUse the <CODE>addchstr()</CODE> family of functions for fast
97862449Speterscreen-painting of text when you know the text doesn't contain any
97962449Spetercontrol characters.  Try to make attribute changes infrequent on your
98062449Speterscreens.  Don't use the <CODE>immedok()</CODE> option!
98162449Speter
98262449Speter<H3><A NAME="special">Special Features of NCURSES</A></H3>
98362449Speter
98462449SpeterThe <CODE>wresize()</CODE> function allows you to resize a window in place.
98562449SpeterThe associated <CODE>resizeterm()</CODE> function simplifies the construction
98662449Speterof <a HREF="#xterm">SIGWINCH</a> handlers, for resizing all windows.  <P>
98762449Speter
98862449SpeterThe <CODE>define_key()</CODE> function allows you
98962449Speterto define at runtime function-key control sequences which are not in the
99062449Speterterminal description.
99162449SpeterThe <CODE>keyok()</CODE> function allows you to temporarily
99262449Speterenable or disable interpretation of any function-key control sequence. <P>
99362449Speter
99462449SpeterThe <CODE>use_default_colors()</CODE> function allows you to construct
99562449Speterapplications which can use the terminal's default foreground and
99662449Speterbackground colors as an additional "default" color.
99762449SpeterSeveral terminal emulators support this feature, which is based on ISO 6429. <P>
99862449Speter
99962449SpeterNcurses supports up 16 colors, unlike SVr4 curses which defines only 8.
100062449SpeterWhile most terminals which provide color allow only 8 colors, about
100162449Spetera quarter (including XFree86 xterm) support 16 colors.
100262449Speter
100362449Speter<H2><A NAME="compat">Compatibility with Older Versions</A></H2>
100462449Speter
100562449SpeterDespite our best efforts, there are some differences between <CODE>ncurses</CODE>
100662449Speterand the (undocumented!) behavior of older curses implementations.  These arise
100762449Speterfrom ambiguities or omissions in the documentation of the API.
100862449Speter
100962449Speter<H3><A NAME="refbug">Refresh of Overlapping Windows</A></H3>
101062449Speter
101162449SpeterIf you define two windows A and B that overlap, and then alternately scribble
101262449Speteron and refresh them, the changes made to the overlapping region under historic
101362449Speter<CODE>curses</CODE> versions were often not documented precisely. <P>
101462449Speter
101562449SpeterTo understand why this is a problem, remember that screen updates are
101662449Spetercalculated between two representations of the <EM>entire</EM> display. The
1017166124Srafandocumentation says that when you refresh a window, it is first copied to the
101862449Spetervirtual screen, and then changes are calculated to update the physical screen
101962449Speter(and applied to the terminal).  But "copied to" is not very specific, and
102062449Spetersubtle differences in how copying works can produce different behaviors in the
102162449Spetercase where two overlapping windows are each being refreshed at unpredictable
102262449Speterintervals. <P>
102362449Speter
102462449SpeterWhat happens to the overlapping region depends on what <CODE>wnoutrefresh()</CODE>
102562449Speterdoes with its argument -- what portions of the argument window it copies to the
102662449Spetervirtual screen.  Some implementations do "change copy", copying down only
102762449Speterlocations in the window that have changed (or been marked changed with
102862449Speter<CODE>wtouchln()</CODE> and friends).  Some implementations do  "entire copy",
102962449Spetercopying <EM>all</EM> window locations to the virtual screen whether or not
103062449Speterthey have changed. <P>
103162449Speter
103262449SpeterThe <CODE>ncurses</CODE> library itself has not always been consistent on this
103362449Speterscore.  Due to a bug, versions 1.8.7 to 1.9.8a did entire copy.  Versions
103462449Speter1.8.6 and older, and versions 1.9.9 and newer, do change copy. <P>
103562449Speter
103662449SpeterFor most commercial curses implementations, it is not documented and not known
103762449Speterfor sure (at least not to the <CODE>ncurses</CODE> maintainers) whether they do
103862449Speterchange copy or entire copy.  We know that System V release 3 curses has logic
103962449Speterin it that looks like an attempt to do change copy, but the surrounding logic
104062449Speterand data representations are sufficiently complex, and our knowledge
104162449Spetersufficiently indirect, that it's hard to know whether this is reliable.
104262449Speter
104362449SpeterIt is not clear what the SVr4 documentation and XSI standard intend.  The XSI
104462449SpeterCurses standard barely mentions wnoutrefresh(); the SVr4 documents seem to be
104562449Speterdescribing entire-copy, but it is possible with some effort and straining to
104662449Speterread them the other way. <P>
104762449Speter
104862449SpeterIt might therefore be unwise to rely on either behavior in programs that might
104962449Speterhave to be linked with other curses implementations.  Instead, you can do an
105062449Speterexplicit <CODE>touchwin()</CODE> before the <CODE>wnoutrefresh()</CODE> call to
105162449Speterguarantee an entire-contents copy anywhere. <P>
105262449Speter
105362449SpeterThe really clean way to handle this is to use the panels library.  If,
105462449Speterwhen you want a screen update, you do <CODE>update_panels()</CODE>, it will
1055166124Srafando all the necessary <CODE>wnoutrefresh()</CODE> calls for whatever panel
105662449Speterstacking order you have defined.  Then you can do one <CODE>doupdate()</CODE>
105762449Speterand there will be a <EM>single</EM> burst of physical I/O that will do
105862449Speterall your updates.
105962449Speter
106062449Speter<H3><A NAME="backbug">Background Erase</A></H3>
106162449Speter
106262449SpeterIf you have been using a very old versions of <CODE>ncurses</CODE> (1.8.7 or
106362449Speterolder) you may be surprised by the behavior of the erase functions.  In older
106462449Speterversions, erased areas of a window were filled with a blank modified by the
106562449Speterwindow's current attribute (as set by <STRONG>wattrset()</STRONG>, <STRONG>wattron()</STRONG>,
106662449Speter<STRONG>wattroff()</STRONG> and friends). <P>
106762449Speter
106862449SpeterIn newer versions, this is not so.  Instead, the attribute of erased blanks
106962449Speteris normal unless and until it is modified by the functions <CODE>bkgdset()</CODE>
107062449Speteror <CODE>wbkgdset()</CODE>. <P>
107162449Speter
107262449SpeterThis change in behavior conforms <CODE>ncurses</CODE> to System V Release 4 and
107362449Speterthe XSI Curses standard.
107462449Speter
107562449Speter<H2><A NAME="xsifuncs">XSI Curses Conformance</A></H2>
107662449Speter
107762449SpeterThe <CODE>ncurses</CODE> library is intended to be base-level conformant with the
107862449SpeterXSI Curses standard from X/Open.  Many extended-level features (in fact, almost
107962449Speterall features not directly concerned with wide characters and
108062449Speterinternationalization) are also supported. <P>
108162449Speter
108262449SpeterOne effect of XSI conformance is the change in behavior described under
108362449Speter<A HREF="#backbug">"Background Erase -- Compatibility with Old Versions"</A>. <P>
108462449Speter
108562449SpeterAlso, <CODE>ncurses</CODE> meets the XSI requirement that every macro
108662449Speterentry point have a corresponding function which may be linked (and
108762449Speterwill be prototype-checked) if the macro definition is disabled with
108862449Speter<CODE>#undef</CODE>.
108962449Speter
109062449Speter<H1><A NAME="panels">The Panels Library</A></H1>
109162449Speter
109262449SpeterThe <CODE>ncurses</CODE> library by itself provides good support for screen
109362449Speterdisplays in which the windows are tiled (non-overlapping).  In the more
109462449Spetergeneral case that windows may overlap, you have to use a series of
109562449Speter<CODE>wnoutrefresh()</CODE> calls followed by a <CODE>doupdate()</CODE>, and be
109662449Spetercareful about the order you do the window refreshes in.  It has to be
109762449Speterbottom-upwards, otherwise parts of windows that should be obscured will
109862449Spetershow through. <P>
109962449Speter
110062449SpeterWhen your interface design is such that windows may dive deeper into the
110162449Spetervisibility stack or pop to the top at runtime, the resulting book-keeping
110262449Spetercan be tedious and difficult to get right.  Hence the panels library. <P>
110362449Speter
110462449SpeterThe <CODE>panel</CODE> library first appeared in AT&amp;T System V.  The
110562449Speterversion documented here is the <CODE>panel</CODE> code distributed
110662449Speterwith <CODE>ncurses</CODE>.
110762449Speter
110862449Speter<H2><A NAME="pcompile">Compiling With the Panels Library</A></H2>
110962449Speter
111062449SpeterYour panels-using modules must import the panels library declarations with
111162449Speter
111262449Speter<PRE>
111362449Speter	  #include &lt;panel.h&gt;
111462449Speter</PRE>
111562449Speter
111662449Speterand must be linked explicitly with the panels library using an
111762449Speter<CODE>-lpanel</CODE> argument.  Note that they must also link the
111862449Speter<CODE>ncurses</CODE> library with <CODE>-lncurses</CODE>.  Many linkers
111962449Speterare two-pass and will accept either order, but it is still good practice
112062449Speterto put <CODE>-lpanel</CODE> first and <CODE>-lncurses</CODE> second.
112162449Speter
112262449Speter<H2><A NAME="poverview">Overview of Panels</A></H2>
112362449Speter
112462449SpeterA panel object is a window that is implicitly treated as part of a
112562449Speter<DFN>deck</DFN> including all other panel objects.  The deck has an implicit
112662449Speterbottom-to-top visibility order.  The panels library includes an update
112762449Speterfunction (analogous to <CODE>refresh()</CODE>) that displays all panels in the
112862449Speterdeck in the proper order to resolve overlaps.  The standard window,
112962449Speter<CODE>stdscr</CODE>, is considered below all panels. <P>
113062449Speter
113162449SpeterDetails on the panels functions are available in the man pages.  We'll just
113262449Speterhit the highlights here. <P>
113362449Speter
113462449SpeterYou create a panel from a window by calling <CODE>new_panel()</CODE> on a
113562449Speterwindow pointer.  It then becomes the top of the deck.  The panel's window
113662449Speteris available as the value of <CODE>panel_window()</CODE> called with the
113762449Speterpanel pointer as argument.<P>
113862449Speter
113962449SpeterYou can delete a panel (removing it from the deck) with <CODE>del_panel</CODE>.
114062449SpeterThis will not deallocate the associated window; you have to do that yourself.
114162449Speter
114262449SpeterYou can replace a panel's window with a different window by calling
114362449Speter<CODE>replace_window</CODE>.  The new window may be of different size;
114462449Speterthe panel code will re-compute all overlaps.  This operation doesn't
114562449Speterchange the panel's position in the deck. <P>
114662449Speter
114762449SpeterTo move a panel's window, use <CODE>move_panel()</CODE>.  The
114862449Speter<CODE>mvwin()</CODE> function on the panel's window isn't sufficient because it
114962449Speterdoesn't update the panels library's representation of where the windows are.
115062449SpeterThis operation leaves the panel's depth, contents, and size unchanged. <P>
115162449Speter
115262449SpeterTwo functions (<CODE>top_panel()</CODE>, <CODE>bottom_panel()</CODE>) are
115362449Speterprovided for rearranging the deck.  The first pops its argument window to the
115462449Spetertop of the deck; the second sends it to the bottom.  Either operation leaves
115562449Speterthe panel's screen location, contents, and size unchanged. <P>
115662449Speter
115762449SpeterThe function <CODE>update_panels()</CODE> does all the
115862449Speter<CODE>wnoutrefresh()</CODE> calls needed to prepare for
115962449Speter<CODE>doupdate()</CODE> (which you must call yourself, afterwards). <P>
116062449Speter
116162449SpeterTypically, you will want to call <CODE>update_panels()</CODE> and
116262449Speter<CODE>doupdate()</CODE> just before accepting command input, once in each cycle
116362449Speterof interaction with the user.  If you call <CODE>update_panels()</CODE> after
116462449Spetereach and every panel write, you'll generate a lot of unnecessary refresh
116562449Speteractivity and screen flicker.
116662449Speter
116762449Speter<H2><A NAME="pstdscr">Panels, Input, and the Standard Screen</A></H2>
116862449Speter
116962449SpeterYou shouldn't mix <CODE>wnoutrefresh()</CODE> or <CODE>wrefresh()</CODE>
117062449Speteroperations with panels code; this will work only if the argument window
117162449Speteris either in the top panel or unobscured by any other panels. <P>
117262449Speter
117362449SpeterThe <CODE>stsdcr</CODE> window is a special case.  It is considered below all
117462449Speterpanels.  Because changes to panels may obscure parts of <CODE>stdscr</CODE>,
117562449Speterthough, you should call <CODE>update_panels()</CODE> before
117662449Speter<CODE>doupdate()</CODE> even when you only change <CODE>stdscr</CODE>. <P>
117762449Speter
117862449SpeterNote that <CODE>wgetch</CODE> automatically calls <CODE>wrefresh</CODE>.
117962449SpeterTherefore, before requesting input from a panel window, you need to be sure
118062449Speterthat the panel is totally unobscured. <P>
118162449Speter
118262449SpeterThere is presently no way to display changes to one obscured panel without
118362449Speterrepainting all panels.
118462449Speter
118562449Speter<H2><A NAME="hiding">Hiding Panels</A></H2>
118662449Speter
118762449SpeterIt's possible to remove a panel from the deck temporarily; use
118862449Speter<CODE>hide_panel</CODE> for this.  Use <CODE>show_panel()</CODE> to render it
118962449Spetervisible again.  The predicate function <CODE>panel_hidden</CODE>
119062449Spetertests whether or not a panel is hidden. <P>
119162449Speter
119262449SpeterThe <CODE>panel_update</CODE> code ignores hidden panels.  You cannot do
119362449Speter<CODE>top_panel()</CODE> or <CODE>bottom_panel</CODE> on a hidden panel().
119462449SpeterOther panels operations are applicable.
119562449Speter
119662449Speter<H2><A NAME="pmisc">Miscellaneous Other Facilities</A></H2>
119762449Speter
119862449SpeterIt's possible to navigate the deck using the functions
119962449Speter<CODE>panel_above()</CODE> and <CODE>panel_below</CODE>.  Handed a panel
120062449Speterpointer, they return the panel above or below that panel.  Handed
120162449Speter<CODE>NULL</CODE>, they return the bottom-most or top-most panel. <P>
120262449Speter
120362449SpeterEvery panel has an associated user pointer, not used by the panel code, to
120462449Speterwhich you can attach application data.  See the man page documentation
120562449Speterof <CODE>set_panel_userptr()</CODE> and <CODE>panel_userptr</CODE> for
120662449Speterdetails.
120762449Speter
120862449Speter<H1><A NAME="menu">The Menu Library</A></H1>
120962449Speter
121062449SpeterA menu is a screen display that assists the user to choose some subset
121162449Speterof a given set of items.  The <CODE>menu</CODE> library is a curses
121262449Speterextension that supports easy programming of menu hierarchies with a
121362449Speteruniform but flexible interface. <P>
121462449Speter
121562449SpeterThe <CODE>menu</CODE> library first appeared in AT&amp;T System V.  The
121662449Speterversion documented here is the <CODE>menu</CODE> code distributed
121762449Speterwith <CODE>ncurses</CODE>.
121862449Speter
121962449Speter<H2><A NAME="mcompile">Compiling With the menu Library</A></H2>
122062449Speter
122162449SpeterYour menu-using modules must import the menu library declarations with
122262449Speter
122362449Speter<PRE>
122462449Speter	  #include &lt;menu.h&gt;
122562449Speter</PRE>
122662449Speter
122762449Speterand must be linked explicitly with the menus library using an
122862449Speter<CODE>-lmenu</CODE> argument.  Note that they must also link the
122962449Speter<CODE>ncurses</CODE> library with <CODE>-lncurses</CODE>.  Many linkers
123062449Speterare two-pass and will accept either order, but it is still good practice
123162449Speterto put <CODE>-lmenu</CODE> first and <CODE>-lncurses</CODE> second.
123262449Speter
123362449Speter<H2><A NAME="moverview">Overview of Menus</A></H2>
123462449Speter
123562449SpeterThe menus created by this library consist of collections of
123662449Speter<DFN>items</DFN> including a name string part and a description string
123762449Speterpart.  To make menus, you create groups of these items and connect
123862449Speterthem with menu frame objects. <P>
123962449Speter
124062449SpeterThe menu can then by <DFN>posted</DFN>, that is written to an
124162449Speterassociated window.  Actually, each menu has two associated windows; a
124262449Spetercontaining window in which the programmer can scribble titles or
124362449Speterborders, and a subwindow in which the menu items proper are displayed.
124462449SpeterIf this subwindow is too small to display all the items, it will be a
124562449Speterscrollable viewport on the collection of items. <P>
124662449Speter
124762449SpeterA menu may also be <DFN>unposted</DFN> (that is, undisplayed), and finally
124862449Speterfreed to make the storage associated with it and its items available for
124962449Speterre-use. <P>
125062449Speter
125162449SpeterThe general flow of control of a menu program looks like this:
125262449Speter
125362449Speter<OL>
125462449Speter<LI>Initialize <CODE>curses</CODE>.
125562449Speter<LI>Create the menu items, using <CODE>new_item()</CODE>.
125662449Speter<LI>Create the menu using <CODE>new_menu()</CODE>.
1257166124Srafan<LI>Post the menu using <CODE>post_menu()</CODE>.
125862449Speter<LI>Refresh the screen.
125962449Speter<LI>Process user requests via an input loop.
1260166124Srafan<LI>Unpost the menu using <CODE>unpost_menu()</CODE>.
126162449Speter<LI>Free the menu, using <CODE>free_menu()</CODE>.
126262449Speter<LI>Free the items using <CODE>free_item()</CODE>.
126362449Speter<LI>Terminate <CODE>curses</CODE>.
126462449Speter</OL>
126562449Speter
126662449Speter<H2><A NAME="mselect">Selecting items</A></H2>
126762449Speter
126862449SpeterMenus may be multi-valued or (the default) single-valued (see the manual
126962449Speterpage <CODE>menu_opts(3x)</CODE> to see how to change the default).
127062449SpeterBoth types always have a <DFN>current item</DFN>. <P>
127162449Speter
127262449SpeterFrom a single-valued menu you can read the selected value simply by looking
127362449Speterat the current item.  From a multi-valued menu, you get the selected set
127462449Speterby looping through the items applying the <CODE>item_value()</CODE>
127562449Speterpredicate function.  Your menu-processing code can use the function
127662449Speter<CODE>set_item_value()</CODE> to flag the items in the select set. <P>
127762449Speter
127862449SpeterMenu items can be made unselectable using <CODE>set_item_opts()</CODE>
127962449Speteror <CODE>item_opts_off()</CODE> with the <CODE>O_SELECTABLE</CODE>
128062449Speterargument.  This is the only option so far defined for menus, but it
128162449Speteris good practice to code as though other option bits might be on.
128262449Speter
128362449Speter<H2><A NAME="mdisplay">Menu Display</A></H2>
128462449Speter
128562449SpeterThe menu library calculates a minimum display size for your window, based
128662449Speteron the following variables:
128762449Speter
128862449Speter<UL>
128962449Speter<LI>The number and maximum length of the menu items
129062449Speter<LI>Whether the O_ROWMAJOR option is enabled
129162449Speter<LI>Whether display of descriptions is enabled
129262449Speter<LI>Whatever menu format may have been set by the programmer
129362449Speter<LI>The length of the menu mark string used for highlighting selected items
129462449Speter</UL>
129562449Speter
129662449SpeterThe function <CODE>set_menu_format()</CODE> allows you to set the
129762449Spetermaximum size of the viewport or <DFN>menu page</DFN> that will be used
129862449Speterto display menu items.  You can retrieve any format associated with a
129962449Spetermenu with <CODE>menu_format()</CODE>. The default format is rows=16,
130062449Spetercolumns=1. <P>
130162449Speter
130262449SpeterThe actual menu page may be smaller than the format size.  This depends
130362449Speteron the item number and size and whether O_ROWMAJOR is on.  This option
130462449Speter(on by default) causes menu items to be displayed in a `raster-scan'
130562449Speterpattern, so that if more than one item will fit horizontally the first
130662449Spetercouple of items are side-by-side in the top row.  The alternative is
130762449Spetercolumn-major display, which tries to put the first several items in
130862449Speterthe first column. <P>
130962449Speter
131062449SpeterAs mentioned above, a menu format not large enough to allow all items to fit
131162449Speteron-screen will result in a menu display that is vertically scrollable. <P>
131262449SpeterYou can scroll it with requests to the menu driver, which will be described
131362449Speterin the section on <A HREF="#minput">menu input handling</A>. <P>
131462449Speter
131562449SpeterEach menu has a <DFN>mark string</DFN> used to visually tag selected items;
131662449Spetersee the <CODE>menu_mark(3x)</CODE> manual page for details.  The mark
131762449Speterstring length also influences the menu page size. <P>
131862449Speter
131962449SpeterThe function <CODE>scale_menu()</CODE> returns the minimum display size
132062449Speterthat the menu code computes from all these factors.
132162449Speter
132262449SpeterThere are other menu display attributes including a select attribute,
132362449Speteran attribute for selectable items, an attribute for unselectable items,
132462449Speterand a pad character used to separate item name text from description
132562449Spetertext.  These have reasonable defaults which the library allows you to
132662449Speterchange (see the <CODE>menu_attribs(3x)</CODE> manual page.
132762449Speter
132862449Speter<H2><A NAME="mwindows">Menu Windows</A></H2>
132962449Speter
133062449SpeterEach menu has, as mentioned previously, a pair of associated windows.
133162449SpeterBoth these windows are painted when the menu is posted and erased when
133262449Speterthe menu is unposted. <P>
133362449Speter
133462449SpeterThe outer or frame window is not otherwise touched by the menu
133562449Speterroutines.  It exists so the programmer can associate a title, a
133662449Speterborder, or perhaps help text with the menu and have it properly
133762449Speterrefreshed or erased at post/unpost time.  The inner window or
133862449Speter<DFN>subwindow</DFN> is where the current menu page is displayed. <P>
133962449Speter
134062449SpeterBy default, both windows are <CODE>stdscr</CODE>.  You can set them with the
134162449Speterfunctions in <CODE>menu_win(3x)</CODE>. <P>
134262449Speter
1343166124SrafanWhen you call <CODE>post_menu()</CODE>, you write the menu to its
1344166124Srafansubwindow.  When you call <CODE>unpost_menu()</CODE>, you erase the
134562449Spetersubwindow, However, neither of these actually modifies the screen.  To
134662449Speterdo that, call <CODE>wrefresh()</CODE> or some equivalent.
134762449Speter
134862449Speter<H2><A NAME="minput">Processing Menu Input</A></H2>
134962449Speter
135062449SpeterThe main loop of your menu-processing code should call
135162449Speter<CODE>menu_driver()</CODE> repeatedly. The first argument of this routine
135262449Speteris a menu pointer; the second is a menu command code.  You should write an
135362449Speterinput-fetching routine that maps input characters to menu command codes, and
135462449Speterpass its output to <CODE>menu_driver()</CODE>.  The menu command codes are
135562449Speterfully documented in <CODE>menu_driver(3x)</CODE>. <P>
135662449Speter
135762449SpeterThe simplest group of command codes is <CODE>REQ_NEXT_ITEM</CODE>,
135862449Speter<CODE>REQ_PREV_ITEM</CODE>, <CODE>REQ_FIRST_ITEM</CODE>,
135962449Speter<CODE>REQ_LAST_ITEM</CODE>, <CODE>REQ_UP_ITEM</CODE>,
136062449Speter<CODE>REQ_DOWN_ITEM</CODE>, <CODE>REQ_LEFT_ITEM</CODE>,
136162449Speter<CODE>REQ_RIGHT_ITEM</CODE>.  These change the currently selected
136262449Speteritem.  These requests may cause scrolling of the menu page if it only
136362449Speterpartially displayed. <P>
136462449Speter
136562449SpeterThere are explicit requests for scrolling which also change the
136662449Spetercurrent item (because the select location does not change, but the
136762449Speteritem there does).  These are <CODE>REQ_SCR_DLINE</CODE>,
136862449Speter<CODE>REQ_SCR_ULINE</CODE>, <CODE>REQ_SCR_DPAGE</CODE>, and
136962449Speter<CODE>REQ_SCR_UPAGE</CODE>. <P>
137062449Speter
137162449SpeterThe <CODE>REQ_TOGGLE_ITEM</CODE> selects or deselects the current item.
137262449SpeterIt is for use in multi-valued menus; if you use it with <CODE>O_ONEVALUE</CODE>
137362449Speteron, you'll get an error return (<CODE>E_REQUEST_DENIED</CODE>). <P>
137462449Speter
137562449SpeterEach menu has an associated pattern buffer.  The
137662449Speter<CODE>menu_driver()</CODE> logic tries to accumulate printable ASCII
137762449Spetercharacters passed in in that buffer; when it matches a prefix of an
137862449Speteritem name, that item (or the next matching item) is selected.  If
137962449Speterappending a character yields no new match, that character is deleted
138062449Speterfrom the pattern buffer, and <CODE>menu_driver()</CODE> returns
138162449Speter<CODE>E_NO_MATCH</CODE>. <P>
138262449Speter
138362449SpeterSome requests change the pattern buffer directly:
138462449Speter<CODE>REQ_CLEAR_PATTERN</CODE>, <CODE>REQ_BACK_PATTERN</CODE>,
138562449Speter<CODE>REQ_NEXT_MATCH</CODE>, <CODE>REQ_PREV_MATCH</CODE>.  The latter
138662449Spetertwo are useful when pattern buffer input matches more than one item
138762449Speterin a multi-valued menu. <P>
138862449Speter
138962449SpeterEach successful scroll or item navigation request clears the pattern
139062449Speterbuffer.  It is also possible to set the pattern buffer explicitly
139162449Speterwith <CODE>set_menu_pattern()</CODE>. <P>
139262449Speter
139362449SpeterFinally, menu driver requests above the constant <CODE>MAX_COMMAND</CODE>
139462449Speterare considered application-specific commands.  The <CODE>menu_driver()</CODE>
139562449Spetercode ignores them and returns <CODE>E_UNKNOWN_COMMAND</CODE>.
139662449Speter
139762449Speter<H2><A NAME="mmisc">Miscellaneous Other Features</A></H2>
139862449Speter
139962449SpeterVarious menu options can affect the processing and visual appearance
140062449Speterand input processing of menus.  See <CODE>menu_opts(3x) for
140162449Speterdetails.</CODE> <P>
140262449Speter
140362449SpeterIt is possible to change the current item from application code; this
140462449Speteris useful if you want to write your own navigation requests.  It is
140562449Speteralso possible to explicitly set the top row of the menu display.  See
140662449Speter<CODE>mitem_current(3x)</CODE>.
140762449Speter
140862449SpeterIf your application needs to change the menu subwindow cursor for
140962449Speterany reason, <CODE>pos_menu_cursor()</CODE> will restore it to the
141062449Spetercorrect location for continuing menu driver processing. <P>
141162449Speter
141262449SpeterIt is possible to set hooks to be called at menu initialization and
141362449Speterwrapup time, and whenever the selected item changes.  See
141462449Speter<CODE>menu_hook(3x)</CODE>. <P>
141562449Speter
141662449SpeterEach item, and each menu, has an associated user pointer on which you
141762449Spetercan hang application data.  See <CODE>mitem_userptr(3x)</CODE> and
141862449Speter<CODE>menu_userptr(3x)</CODE>.
141962449Speter
142062449Speter<H1><A NAME="form">The Forms Library</A></H1>
142162449Speter
142262449SpeterThe <CODE>form</CODE> library is a curses extension that supports easy
142362449Speterprogramming of on-screen forms for data entry and program control. <P>
142462449Speter
142562449SpeterThe <CODE>form</CODE> library first appeared in AT&amp;T System V.  The
142662449Speterversion documented here is the <CODE>form</CODE> code distributed
142762449Speterwith <CODE>ncurses</CODE>.
142862449Speter
142962449Speter<H2><A NAME="fcompile">Compiling With the form Library</A></H2>
143062449Speter
143162449SpeterYour form-using modules must import the form library declarations with
143262449Speter
143362449Speter<PRE>
143462449Speter	  #include &lt;form.h&gt;
143562449Speter</PRE>
143662449Speter
143762449Speterand must be linked explicitly with the forms library using an
143862449Speter<CODE>-lform</CODE> argument.  Note that they must also link the
143962449Speter<CODE>ncurses</CODE> library with <CODE>-lncurses</CODE>.  Many linkers
144062449Speterare two-pass and will accept either order, but it is still good practice
144162449Speterto put <CODE>-lform</CODE> first and <CODE>-lncurses</CODE> second.
144262449Speter
144362449Speter<H2><A NAME="foverview">Overview of Forms</A></H2>
144462449Speter
144562449SpeterA form is a collection of fields; each field may be either a label
144662449Speter(explanatory text) or a data-entry location.  Long forms may be
144762449Spetersegmented into pages; each entry to a new page clears the screen. <P>
144862449SpeterTo make forms, you create groups of fields and connect them with form
144962449Speterframe objects; the form library makes this relatively simple. <P>
145062449Speter
145162449SpeterOnce defined, a form can be <DFN>posted</DFN>, that is written to an
145262449Speterassociated window.  Actually, each form has two associated windows; a
145362449Spetercontaining window in which the programmer can scribble titles or
145462449Speterborders, and a subwindow in which the form fields proper are displayed. <P>
145562449Speter
145662449SpeterAs the form user fills out the posted form, navigation and editing
145762449Speterkeys support movement between fields, editing keys support modifying
145862449Speterfield, and plain text adds to or changes data in a current field.  The
145962449Speterform library allows you (the forms designer) to bind each navigation
146062449Speterand editing key to any keystroke accepted by <CODE>curses</CODE>
146162449Speter
146262449SpeterFields may have validation conditions on them, so that they check input
146362449Speterdata for type and value.  The form library supplies a rich set of
146462449Speterpre-defined field types, and makes it relatively easy to define new ones. <P>
146562449Speter
146662449SpeterOnce its transaction is completed (or aborted), a form may be
146762449Speter<DFN>unposted</DFN> (that is, undisplayed), and finally freed to make
146862449Speterthe storage associated with it and its items available for re-use. <P>
146962449Speter
147062449SpeterThe general flow of control of a form program looks like this:
147162449Speter
147262449Speter<OL>
147362449Speter<LI>Initialize <CODE>curses</CODE>.
147462449Speter<LI>Create the form fields, using <CODE>new_field()</CODE>.
147562449Speter<LI>Create the form using <CODE>new_form()</CODE>.
1476166124Srafan<LI>Post the form using <CODE>post_form()</CODE>.
147762449Speter<LI>Refresh the screen.
147862449Speter<LI>Process user requests via an input loop.
1479166124Srafan<LI>Unpost the form using <CODE>unpost_form()</CODE>.
148062449Speter<LI>Free the form, using <CODE>free_form()</CODE>.
148162449Speter<LI>Free the fields using <CODE>free_field()</CODE>.
148262449Speter<LI>Terminate <CODE>curses</CODE>.
148362449Speter</OL>
148462449Speter
148562449SpeterNote that this looks much like a menu program; the form library handles
148662449Spetertasks which are in many ways similar, and its interface was obviously
148762449Speterdesigned to resemble that of the <A HREF="#menu">menu library</A>
148862449Speterwherever possible. <P>
148962449Speter
149062449SpeterIn forms programs, however, the `process user requests' is somewhat more
149162449Spetercomplicated than for menus.  Besides menu-like navigation operations,
149262449Speterthe menu driver loop has to support field editing and data validation.
149362449Speter
149462449Speter<H2><A NAME="fcreate">Creating and Freeing Fields and Forms</A></H2>
149562449Speter
149662449SpeterThe basic function for creating fields is <CODE>new_field()</CODE>:
149762449Speter
149862449Speter<PRE>
149962449SpeterFIELD *new_field(int height, int width,   /* new field size */
150062449Speter                 int top, int left,       /* upper left corner */
150162449Speter                 int offscreen,           /* number of offscreen rows */
150262449Speter                 int nbuf);               /* number of working buffers */
150362449Speter</PRE>
150462449Speter
150562449SpeterMenu items always occupy a single row, but forms fields may have
150662449Spetermultiple rows.  So <CODE>new_field()</CODE> requires you to specify a
150762449Speterwidth and height (the first two arguments, which mist both be greater
150862449Speterthan zero). <P>
150962449Speter
151062449SpeterYou must also specify the location of the field's upper left corner on
151162449Speterthe screen (the third and fourth arguments, which must be zero or
151262449Spetergreater). Note that these coordinates are relative to the form
151362449Spetersubwindow, which will coincide with <CODE>stdscr</CODE> by default but
151462449Speterneed not be <CODE>stdscr</CODE> if you've done an explicit
1515166124Srafan<CODE>set_form_win()</CODE> call. <P>
151662449Speter
151762449SpeterThe fifth argument allows you to specify a number of off-screen rows.  If
151862449Speterthis is zero, the entire field will always be displayed.  If it is
151962449Speternonzero, the form will be scrollable, with only one screen-full (initially
152062449Speterthe top part) displayed at any given time.  If you make a field dynamic
152162449Speterand grow it so it will no longer fit on the screen, the form will become
152262449Speterscrollable even if the <CODE>offscreen</CODE> argument was initially zero. <P>
152362449Speter
152462449SpeterThe forms library allocates one working buffer per field; the size of
152562449Spetereach buffer is <CODE>((height + offscreen)*width + 1</CODE>, one character
152662449Speterfor each position in the field plus a NUL terminator.  The sixth
152762449Speterargument is the number of additional data buffers to allocate for the
152862449Speterfield; your application can use them for its own purposes.
152962449Speter
153062449Speter<PRE>
153162449SpeterFIELD *dup_field(FIELD *field,            /* field to copy */
153262449Speter                 int top, int left);      /* location of new copy */
153362449Speter</PRE>
153462449Speter
153562449SpeterThe function <CODE>dup_field()</CODE> duplicates an existing field at a
153662449Speternew location.  Size and buffering information are copied; some
153762449Speterattribute flags and status bits are not (see the
153862449Speter<CODE>form_field_new(3X)</CODE> for details).
153962449Speter
154062449Speter<PRE>
154162449SpeterFIELD *link_field(FIELD *field,           /* field to copy */
154262449Speter                  int top, int left);     /* location of new copy */
154362449Speter</PRE>
154462449Speter
154562449SpeterThe function <CODE>link_field()</CODE> also duplicates an existing field
154662449Speterat a new location.  The difference from <CODE>dup_field()</CODE> is that
154762449Speterit arranges for the new field's buffer to be shared with the old one. <P>
154862449Speter
154962449SpeterBesides the obvious use in making a field editable from two different
155062449Speterform pages, linked fields give you a way to hack in dynamic labels.  If
155162449Speteryou declare several fields linked to an original, and then make them
155262449Speterinactive, changes from the original will still be propagated to the
155362449Speterlinked fields. <P>
155462449Speter
155562449SpeterAs with duplicated fields, linked fields have attribute bits separate
155662449Speterfrom the original. <P>
155762449Speter
155862449SpeterAs you might guess, all these field-allocations return <CODE>NULL</CODE> if
155962449Speterthe field allocation is not possible due to an out-of-memory error or
156062449Speterout-of-bounds arguments. <P>
156162449Speter
156262449SpeterTo connect fields to a form, use
156362449Speter
156462449Speter<PRE>
156562449SpeterFORM *new_form(FIELD **fields);
156662449Speter</PRE>
156762449Speter
156862449SpeterThis function expects to see a NULL-terminated array of field pointers.
156962449SpeterSaid fields are connected to a newly-allocated form object; its address
157062449Speteris returned (or else NULL if the allocation fails).   <P>
157162449Speter
157262449SpeterNote that <CODE>new_field()</CODE> does <EM>not</EM> copy the pointer array
157362449Speterinto private storage; if you modify the contents of the pointer array
157462449Speterduring forms processing, all manner of bizarre things might happen.  Also
157562449Speternote that any given field may only be connected to one form. <P>
157662449Speter
157762449SpeterThe functions <CODE>free_field()</CODE> and <CODE>free_form</CODE> are available
157862449Speterto free field and form objects.  It is an error to attempt to free a field
157962449Speterconnected to a form, but not vice-versa; thus, you will generally free
158062449Speteryour form objects first.
158162449Speter
158262449Speter<H2><A NAME="fattributes">Fetching and Changing Field Attributes</A></H2>
158362449Speter
158462449SpeterEach form field has a number of location and size attributes
158562449Speterassociated with it. There are other field attributes used to control
158662449Speterdisplay and editing of the field.  Some (for example, the <CODE>O_STATIC</CODE> bit)
158762449Speterinvolve sufficient complications to be covered in sections of their own
158862449Speterlater on.  We cover the functions used to get and set several basic
158962449Speterattributes here. <P>
159062449Speter
159162449SpeterWhen a field is created, the attributes not specified by the
159262449Speter<CODE>new_field</CODE> function are copied from an invisible system
159362449Speterdefault field.  In attribute-setting and -fetching functions, the
159462449Speterargument NULL is taken to mean this field.  Changes to it persist
159562449Speteras defaults until your forms application terminates.
159662449Speter
159762449Speter<H3><A NAME="fsizes">Fetching Size and Location Data</A></H3>
159862449Speter
159962449SpeterYou can retrieve field sizes and locations through:
160062449Speter
160162449Speter<PRE>
160262449Speterint field_info(FIELD *field,              /* field from which to fetch */
160362449Speter               int *height, *int width,   /* field size */
160462449Speter               int *top, int *left,       /* upper left corner */
160562449Speter               int *offscreen,            /* number of offscreen rows */
160662449Speter               int *nbuf);                /* number of working buffers */
160762449Speter</PRE>
160862449Speter
160962449SpeterThis function is a sort of inverse of <CODE>new_field()</CODE>; instead of
161062449Spetersetting size and location attributes of a new field, it fetches them
161162449Speterfrom an existing one.
161262449Speter
161362449Speter<H3><A NAME="flocation">Changing the Field Location</A></H3>
161462449Speter
161562449SpeterIt is possible to move a field's location on the screen:
161662449Speter
161762449Speter<PRE>
161862449Speterint move_field(FIELD *field,              /* field to alter */
161962449Speter               int top, int left);        /* new upper-left corner */
162062449Speter</PRE>
162162449Speter
162262449SpeterYou can, of course. query the current location through <CODE>field_info()</CODE>.
162362449Speter
162462449Speter<H3><A NAME="fjust">The Justification Attribute</A></H3>
162562449Speter
162662449SpeterOne-line fields may be unjustified, justified right, justified left,
162762449Speteror centered.  Here is how you manipulate this attribute:
162862449Speter
162962449Speter<PRE>
163062449Speterint set_field_just(FIELD *field,          /* field to alter */
163162449Speter                   int justmode);         /* mode to set */
163262449Speter
163362449Speterint field_just(FIELD *field);             /* fetch mode of field */
163462449Speter</PRE>
163562449Speter
163662449SpeterThe mode values accepted and returned by this functions are
163762449Speterpreprocessor macros <CODE>NO_JUSTIFICATION</CODE>, <CODE>JUSTIFY_RIGHT</CODE>,
163862449Speter<CODE>JUSTIFY_LEFT</CODE>, or <CODE>JUSTIFY_CENTER</CODE>.
163962449Speter
164062449Speter<H3><A NAME="fdispatts">Field Display Attributes</A></H3>
164162449Speter
164262449SpeterFor each field, you can set a foreground attribute for entered
164362449Spetercharacters, a background attribute for the entire field, and a pad
164462449Spetercharacter for the unfilled portion of the field.  You can also
164562449Spetercontrol pagination of the form. <P>
164662449Speter
164762449SpeterThis group of four field attributes controls the visual appearance
164862449Speterof the field on the screen, without affecting in any way the data
164962449Speterin the field buffer.
165062449Speter
165162449Speter<PRE>
165262449Speterint set_field_fore(FIELD *field,          /* field to alter */
165362449Speter                   chtype attr);          /* attribute to set */
165462449Speter
165562449Speterchtype field_fore(FIELD *field);          /* field to query */
165662449Speter
165762449Speterint set_field_back(FIELD *field,          /* field to alter */
165862449Speter                   chtype attr);          /* attribute to set */
165962449Speter
166062449Speterchtype field_back(FIELD *field);          /* field to query */
166162449Speter
166262449Speterint set_field_pad(FIELD *field,           /* field to alter */
166362449Speter                 int pad);                /* pad character to set */
166462449Speter
166562449Speterchtype field_pad(FIELD *field);
166662449Speter
166762449Speterint set_new_page(FIELD *field,            /* field to alter */
166862449Speter                 int flag);               /* TRUE to force new page */
166962449Speter
167062449Speterchtype new_page(FIELD *field);            /* field to query */
167162449Speter</PRE>
167262449Speter
167362449SpeterThe attributes set and returned by the first four functions are normal
167462449Speter<CODE>curses(3x)</CODE> display attribute values (<CODE>A_STANDOUT</CODE>,
167562449Speter<CODE>A_BOLD</CODE>, <CODE>A_REVERSE</CODE> etc).
167662449Speter
167762449SpeterThe page bit of a field controls whether it is displayed at the start of
167862449Spetera new form screen.
167962449Speter
168062449Speter<H3><A NAME="foptions">Field Option Bits</A></H3>
168162449Speter
168262449SpeterThere is also a large collection of field option bits you can set to control
168362449Spetervarious aspects of forms processing.  You can manipulate them with these
168462449Speterfunctions:
168562449Speter
168662449Speter<PRE>
168762449Speterint set_field_opts(FIELD *field,          /* field to alter */
168862449Speter                   int attr);             /* attribute to set */
168962449Speter
169062449Speterint field_opts_on(FIELD *field,           /* field to alter */
169162449Speter                  int attr);              /* attributes to turn on */
169262449Speter
169362449Speterint field_opts_off(FIELD *field,          /* field to alter */
169462449Speter                   int attr);             /* attributes to turn off */
169562449Speter
169662449Speterint field_opts(FIELD *field);             /* field to query */
169762449Speter</PRE>
169862449Speter
169962449SpeterBy default, all options are on.  Here are the available option bits:
170062449Speter<DL>
170162449Speter<DT> O_VISIBLE
170262449Speter<DD> Controls whether the field is visible on the screen.  Can be used
170362449Speterduring form processing to hide or pop up fields depending on the value
170462449Speterof parent fields.
170562449Speter<DT> O_ACTIVE
170662449Speter<DD> Controls whether the field is active during forms processing (i.e.
170762449Spetervisited by form navigation keys).  Can be used to make labels or derived
170862449Speterfields with buffer values alterable by the forms application, not the user.
170962449Speter<DT> O_PUBLIC
171062449Speter<DD> Controls whether data is displayed during field entry.  If this option is
171162449Speterturned off on a field, the library will accept and edit data in that field,
171262449Speterbut it will not be displayed and the visible field cursor will not move.
171362449SpeterYou can turn off the O_PUBLIC bit to define password fields.
171462449Speter<DT> O_EDIT
171562449Speter<DD> Controls whether the field's data can be modified.  When this option is
171662449Speteroff, all editing requests except <CODE>REQ_PREV_CHOICE</CODE> and
171762449Speter<CODE>REQ_NEXT_CHOICE</CODE> will fail.  Such read-only fields may be useful for
171862449Speterhelp messages.
171962449Speter<DT> O_WRAP
172062449Speter<DD> Controls word-wrapping in multi-line fields.  Normally, when any
172162449Spetercharacter of a (blank-separated) word reaches the end of the current line, the
172262449Speterentire word is wrapped to the next line (assuming there is one).  When this
172362449Speteroption is off, the word will be split across the line break.
172462449Speter<DT> O_BLANK
172562449Speter<DD> Controls field blanking.  When this option is on, entering a character at
172662449Speterthe first field position erases the entire field (except for the just-entered
172762449Spetercharacter).
172862449Speter<DT> O_AUTOSKIP
172962449Speter<DD> Controls automatic skip to next field when this one fills.  Normally,
173062449Speterwhen the forms user tries to type more data into a field than will fit,
173162449Speterthe editing location jumps to next field.  When this option is off, the
173262449Speteruser's cursor will hang at the end of the field.  This option is ignored
173362449Speterin dynamic fields that have not reached their size limit.
173462449Speter<DT> O_NULLOK
173562449Speter<DD> Controls whether <A HREF="#fvalidation">validation</A> is applied to
173662449Speterblank fields.  Normally, it is not; the user can leave a field blank
173762449Speterwithout invoking the usual validation check on exit.  If this option is
173862449Speteroff on a field, exit from it will invoke a validation check.
173962449Speter<DT> O_PASSOK
174062449Speter<DD> Controls whether validation occurs on every exit, or only after
174162449Speterthe field is modified.  Normally the latter is true.  Setting O_PASSOK
174262449Spetermay be useful if your field's validation function may change during
174362449Speterforms processing.
174462449Speter<DT> O_STATIC
174562449Speter<DD> Controls whether the field is fixed to its initial dimensions.  If you
174662449Speterturn this off, the field becomes <A HREF="#fdynamic">dynamic</A> and will
174762449Speterstretch to fit entered data.
174862449Speter</DL>
174962449Speter
175062449SpeterA field's options cannot be changed while the field is currently selected.
175162449SpeterHowever, options may be changed on posted fields that are not current. <P>
175262449Speter
175362449SpeterThe option values are bit-masks and can be composed with logical-or in
175462449Speterthe obvious way.
175562449Speter
175662449Speter<H2><A NAME="fstatus">Field Status</A></H2>
175762449Speter
175862449SpeterEvery field has a status flag, which is set to FALSE when the field is
175962449Spetercreated and TRUE when the value in field buffer 0 changes.  This flag can
176062449Speterbe queried and set directly:
176162449Speter
176262449Speter<PRE>
176362449Speterint set_field_status(FIELD *field,      /* field to alter */
176462449Speter                   int status);         /* mode to set */
176562449Speter
176662449Speterint field_status(FIELD *field);         /* fetch mode of field */
176762449Speter</PRE>
176862449Speter
176962449SpeterSetting this flag under program control can be useful if you use the same
177062449Speterform repeatedly, looking for modified fields each time. <P>
177162449Speter
177262449SpeterCalling <CODE>field_status()</CODE> on a field not currently selected
177362449Speterfor input will return a correct value.  Calling <CODE>field_status()</CODE> on a
177462449Speterfield that is currently selected for input may not necessarily give a
177562449Spetercorrect field status value, because entered data isn't necessarily copied to
177662449Speterbuffer zero before the exit validation check.
177762449Speter
177862449SpeterTo guarantee that the returned status value reflects reality, call
177962449Speter<CODE>field_status()</CODE> either (1) in the field's exit validation check
178062449Speterroutine, (2) from the field's or form's initialization or termination
178162449Speterhooks, or (3) just after a <CODE>REQ_VALIDATION</CODE> request has been
178262449Speterprocessed by the forms driver.
178362449Speter
178462449Speter<H2><A NAME="fuser">Field User Pointer</A></H2>
178562449Speter
178662449SpeterEach field structure contains one character pointer slot that is not used
178762449Speterby the forms library.  It is intended to be used by applications to store
178862449Speterprivate per-field data.  You can manipulate it with:
178962449Speter
179062449Speter<PRE>
179162449Speterint set_field_userptr(FIELD *field,       /* field to alter */
179262449Speter                   char *userptr);        /* mode to set */
179362449Speter
179462449Speterchar *field_userptr(FIELD *field);        /* fetch mode of field */
179562449Speter</PRE>
179662449Speter
179762449Speter(Properly, this user pointer field ought to have <CODE>(void *)</CODE> type.
179862449SpeterThe <CODE>(char *)</CODE> type is retained for System V compatibility.) <P>
179962449Speter
180062449SpeterIt is valid to set the user pointer of the default field (with a
180162449Speter<CODE>set_field_userptr()</CODE> call passed a NULL field pointer.)
180262449SpeterWhen a new field is created, the default-field user pointer is copied
180362449Speterto initialize the new field's user pointer.
180462449Speter
180562449Speter<H2><A NAME="fdynamic">Variable-Sized Fields</A></H2>
180662449Speter
180762449SpeterNormally, a field is fixed at the size specified for it at creation
180862449Spetertime.  If, however, you turn off its O_STATIC bit, it becomes
180962449Speter<DFN>dynamic</DFN> and will automatically resize itself to accommodate
181062449Speterdata as it is entered.  If the field has extra buffers associated with it,
181162449Speterthey will grow right along with the main input buffer.  <P>
181262449Speter
181362449SpeterA one-line dynamic field will have a fixed height (1) but variable
181462449Speterwidth, scrolling horizontally to display data within the field area as
181562449Speteroriginally dimensioned and located.  A multi-line dynamic field will
181662449Speterhave a fixed width, but variable height (number of rows), scrolling
181762449Spetervertically to display data within the field area as originally
181862449Speterdimensioned and located. <P>
181962449Speter
182062449SpeterNormally, a dynamic field is allowed to grow without limit.  But it is
182162449Speterpossible to set an upper limit on the size of a dynamic field.  You do
182262449Speterit with this function:
182362449Speter
182462449Speter<PRE>
182562449Speterint set_max_field(FIELD *field,     /* field to alter (may not be NULL) */
182662449Speter                   int max_size);   /* upper limit on field size */
182762449Speter</PRE>
182862449Speter
182962449SpeterIf the field is one-line, <CODE>max_size</CODE> is taken to be a column size
183062449Speterlimit; if it is multi-line, it is taken to be a line size limit.  To disable
183162449Speterany limit, use an argument of zero.  The growth limit can be changed whether
183262449Speteror not the O_STATIC bit is on, but has no effect until it is. <P>
183362449Speter
183462449SpeterThe following properties of a field change when it becomes dynamic:
183562449Speter
183662449Speter<UL>
183762449Speter<LI>If there is no growth limit, there is no final position of the field;
183862449Spetertherefore <CODE>O_AUTOSKIP</CODE> and <CODE>O_NL_OVERLOAD</CODE> are ignored.
183962449Speter<LI>Field justification will be ignored (though whatever justification is
184062449Speterset up will be retained internally and can be queried).
184162449Speter<LI>The <CODE>dup_field()</CODE> and <CODE>link_field()</CODE> calls copy
184262449Speterdynamic-buffer sizes.  If the <CODE>O_STATIC</CODE> option is set on one of a
184362449Spetercollection of links, buffer resizing will occur only when the field is
184462449Speteredited through that link.
184562449Speter<LI>The call <CODE>field_info()</CODE> will retrieve the original static size of
184662449Speterthe field; use <CODE>dynamic_field_info()</CODE> to get the actual dynamic size.
184762449Speter</UL>
184862449Speter
184962449Speter<H2><A NAME="fvalidation">Field Validation</A></H2>
185062449Speter
185162449SpeterBy default, a field will accept any data that will fit in its input buffer.
185262449SpeterHowever, it is possible to attach a validation type to a field.  If you do
185362449Speterthis, any attempt to leave the field while it contains data that doesn't
185462449Spetermatch the validation type will fail.  Some validation types also have a
185562449Spetercharacter-validity check for each time a character is entered in the field. <P>
185662449Speter
185762449SpeterA field's validation check (if any) is not called when
185862449Speter<CODE>set_field_buffer()</CODE> modifies the input buffer, nor when that buffer
185962449Speteris changed through a linked field. <P>
186062449Speter
186162449SpeterThe <CODE>form</CODE> library provides a rich set of pre-defined validation
186262449Spetertypes, and gives you the capability to define custom ones of your own.  You
186362449Spetercan examine and change field validation attributes with the following
186462449Speterfunctions:
186562449Speter
186662449Speter<PRE>
186762449Speterint set_field_type(FIELD *field,          /* field to alter */
186862449Speter                   FIELDTYPE *ftype,      /* type to associate */
186962449Speter                   ...);                  /* additional arguments*/
187062449Speter
187162449SpeterFIELDTYPE *field_type(FIELD *field);      /* field to query */
187262449Speter</PRE>
187362449Speter
187462449SpeterThe validation type of a field is considered an attribute of the field.  As
187562449Speterwith other field attributes, Also, doing <CODE>set_field_type()</CODE> with a
187662449Speter<CODE>NULL</CODE> field default will change the system default for validation of
187762449Speternewly-created fields. <P>
187862449Speter
187962449SpeterHere are the pre-defined validation types:
188062449Speter
188162449Speter<H3><A NAME="ftype_alpha">TYPE_ALPHA</A></H3>
188262449Speter
188362449SpeterThis field type accepts alphabetic data; no blanks, no digits, no special
188462449Spetercharacters (this is checked at character-entry time).  It is set up with:
188562449Speter
188662449Speter<PRE>
188762449Speterint set_field_type(FIELD *field,          /* field to alter */
188862449Speter                   TYPE_ALPHA,            /* type to associate */
188962449Speter                   int width);            /* maximum width of field */
189062449Speter</PRE>
189162449Speter
189262449SpeterThe <CODE>width</CODE> argument sets a minimum width of data.  Typically
189362449Speteryou'll want to set this to the field width; if it's greater than the
189462449Speterfield width, the validation check will always fail.  A minimum width
189562449Speterof zero makes field completion optional.
189662449Speter
189762449Speter<H3><A NAME="ftype_alnum">TYPE_ALNUM</A></H3>
189862449Speter
189962449SpeterThis field type accepts alphabetic data and digits; no blanks, no special
190062449Spetercharacters (this is checked at character-entry time).  It is set up with:
190162449Speter
190262449Speter<PRE>
190362449Speterint set_field_type(FIELD *field,          /* field to alter */
190462449Speter                   TYPE_ALNUM,            /* type to associate */
190562449Speter                   int width);            /* maximum width of field */
190662449Speter</PRE>
190762449Speter
190862449SpeterThe <CODE>width</CODE> argument sets a minimum width of data.  As with
190962449SpeterTYPE_ALPHA, typically you'll want to set this to the field width; if it's
191062449Spetergreater than the field width, the validation check will always fail.  A
191162449Speterminimum width of zero makes field completion optional.
191262449Speter
191362449Speter<H3><A NAME="ftype_enum">TYPE_ENUM</A></H3>
191462449Speter
191562449SpeterThis type allows you to restrict a field's values to be among a specified
191662449Speterset of string values (for example, the two-letter postal codes for U.S.
191762449Speterstates).  It is set up with:
191862449Speter
191962449Speter<PRE>
192062449Speterint set_field_type(FIELD *field,          /* field to alter */
192162449Speter                   TYPE_ENUM,             /* type to associate */
192262449Speter                   char **valuelist;      /* list of possible values */
192362449Speter                   int checkcase;         /* case-sensitive? */
192462449Speter                   int checkunique);      /* must specify uniquely? */
192562449Speter</PRE>
192662449Speter
192762449SpeterThe <CODE>valuelist</CODE> parameter must point at a NULL-terminated list of
192862449Spetervalid strings.  The <CODE>checkcase</CODE> argument, if true, makes comparison
192962449Speterwith the string case-sensitive. <P>
193062449Speter
193162449SpeterWhen the user exits a TYPE_ENUM field, the validation procedure tries to
193262449Spetercomplete the data in the buffer to a valid entry.  If a complete choice string
193362449Speterhas been entered, it is of course valid.  But it is also possible to enter a
193462449Speterprefix of a valid string and have it completed for you. <P>
193562449Speter
193662449SpeterBy default, if you enter such a prefix and it matches more than one value
193762449Speterin the string list, the prefix will be completed to the first matching
193862449Spetervalue.  But the <CODE>checkunique</CODE> argument, if true, requires prefix
193962449Spetermatches to be unique in order to be valid. <P>
194062449Speter
194162449SpeterThe <CODE>REQ_NEXT_CHOICE</CODE> and <CODE>REQ_PREV_CHOICE</CODE> input requests
194262449Spetercan be particularly useful with these fields.
194362449Speter
194462449Speter<H3><A NAME="ftype_integer">TYPE_INTEGER</A></H3>
194562449Speter
194662449SpeterThis field type accepts an integer.  It is set up as follows:
194762449Speter
194862449Speter<PRE>
194962449Speterint set_field_type(FIELD *field,          /* field to alter */
195062449Speter                   TYPE_INTEGER,          /* type to associate */
195162449Speter                   int padding,           /* # places to zero-pad to */
195262449Speter                   int vmin, int vmax);   /* valid range */
195362449Speter</PRE>
195462449Speter
195562449SpeterValid characters consist of an optional leading minus and digits.
195662449SpeterThe range check is performed on exit.  If the range maximum is less
195762449Speterthan or equal to the minimum, the range is ignored. <P>
195862449Speter
195962449SpeterIf the value passes its range check, it is padded with as many leading
196062449Speterzero digits as necessary to meet the padding argument. <P>
196162449Speter
196262449SpeterA <CODE>TYPE_INTEGER</CODE> value buffer can conveniently be interpreted
196362449Speterwith the C library function <CODE>atoi(3)</CODE>.
196462449Speter
196562449Speter<H3><A NAME="ftype_numeric">TYPE_NUMERIC</A></H3>
196662449Speter
196762449SpeterThis field type accepts a decimal number.  It is set up as follows:
196862449Speter
196962449Speter<PRE>
197062449Speterint set_field_type(FIELD *field,              /* field to alter */
197162449Speter                   TYPE_NUMERIC,              /* type to associate */
197262449Speter                   int padding,               /* # places of precision */
197362449Speter                   double vmin, double vmax); /* valid range */
197462449Speter</PRE>
197562449Speter
197662449SpeterValid characters consist of an optional leading minus and digits. possibly
197762449Speterincluding a decimal point. If your system supports locale's, the decimal point
197862449Spetercharacter used must be the one defined by your locale. The range check is
197962449Speterperformed on exit. If the range maximum is less than or equal to the minimum,
198062449Speterthe range is ignored. <P>
198162449Speter
198262449SpeterIf the value passes its range check, it is padded with as many trailing
198362449Speterzero digits as necessary to meet the padding argument. <P>
198462449Speter
198562449SpeterA <CODE>TYPE_NUMERIC</CODE> value buffer can conveniently be interpreted
198662449Speterwith the C library function <CODE>atof(3)</CODE>.
198762449Speter
198862449Speter<H3><A NAME="ftype_regexp">TYPE_REGEXP</A></H3>
198962449Speter
199062449SpeterThis field type accepts data matching a regular expression.  It is set up
199162449Speteras follows:
199262449Speter
199362449Speter<PRE>
199462449Speterint set_field_type(FIELD *field,          /* field to alter */
199562449Speter                   TYPE_REGEXP,           /* type to associate */
199662449Speter                   char *regexp);         /* expression to match */
199762449Speter</PRE>
199862449Speter
199962449SpeterThe syntax for regular expressions is that of <CODE>regcomp(3)</CODE>.
200062449SpeterThe check for regular-expression match is performed on exit.
200162449Speter
200262449Speter<H2><A NAME="fbuffer">Direct Field Buffer Manipulation</A></H2>
200362449Speter
200462449SpeterThe chief attribute of a field is its buffer contents.  When a form has
200562449Speterbeen completed, your application usually needs to know the state of each
200662449Speterfield buffer.  You can find this out with:
200762449Speter
200862449Speter<PRE>
200962449Speterchar *field_buffer(FIELD *field,          /* field to query */
201062449Speter                   int bufindex);         /* number of buffer to query */
201162449Speter</PRE>
201262449Speter
201362449SpeterNormally, the state of the zero-numbered buffer for each field is set by
201462449Speterthe user's editing actions on that field.  It's sometimes useful to be able
201562449Speterto set the value of the zero-numbered (or some other) buffer from your
201662449Speterapplication:
201762449Speter
201862449Speter<PRE>
201962449Speterint set_field_buffer(FIELD *field,        /* field to alter */
202062449Speter                   int bufindex,          /* number of buffer to alter */
202162449Speter                   char *value);          /* string value to set */
202262449Speter</PRE>
202362449Speter
202462449SpeterIf the field is not large enough and cannot be resized to a sufficiently
202562449Speterlarge size to contain the specified value, the value will be truncated
202662449Speterto fit. <P>
202762449Speter
202862449SpeterCalling <CODE>field_buffer()</CODE> with a null field pointer will raise an
202962449Spetererror.  Calling <CODE>field_buffer()</CODE> on a field not currently selected
203062449Speterfor input will return a correct value.  Calling <CODE>field_buffer()</CODE> on a
203162449Speterfield that is currently selected for input may not necessarily give a
203262449Spetercorrect field buffer value, because entered data isn't necessarily copied to
203362449Speterbuffer zero before the exit validation check.
203462449Speter
203562449SpeterTo guarantee that the returned buffer value reflects on-screen reality,
203662449Spetercall <CODE>field_buffer()</CODE> either (1) in the field's exit validation
203762449Spetercheck routine, (2) from the field's or form's initialization or termination
203862449Speterhooks, or (3) just after a <CODE>REQ_VALIDATION</CODE> request has been processed
203962449Speterby the forms driver.
204062449Speter
204162449Speter<H2><A NAME="formattrs">Attributes of Forms</A></H2>
204262449Speter
204362449SpeterAs with field attributes, form attributes inherit a default from a
204462449Spetersystem default form structure.  These defaults can be queried or set by
204562449Speterof these functions using a form-pointer argument of <CODE>NULL</CODE>. <P>
204662449Speter
204762449SpeterThe principal attribute of a form is its field list.  You can query
204862449Speterand change this list with:
204962449Speter
205062449Speter<PRE>
205162449Speterint set_form_fields(FORM *form,           /* form to alter */
205262449Speter                    FIELD **fields);      /* fields to connect */
205362449Speter
205462449Speterchar *form_fields(FORM *form);            /* fetch fields of form */
205562449Speter
205662449Speterint field_count(FORM *form);              /* count connect fields */
205762449Speter</PRE>
205862449Speter
205962449SpeterThe second argument of <CODE>set_form_fields()</CODE> may be a
206062449SpeterNULL-terminated field pointer array like the one required by
206162449Speter<CODE>new_form()</CODE>. In that case, the old fields of the form are
206262449Speterdisconnected but not freed (and eligible to be connected to other
206362449Speterforms), then the new fields are connected. <P>
206462449Speter
206562449SpeterIt may also be null, in which case the old fields are disconnected
206662449Speter(and not freed) but no new ones are connected. <P>
206762449Speter
206862449SpeterThe <CODE>field_count()</CODE> function simply counts the number of fields
206962449Speterconnected to a given from.  It returns -1 if the form-pointer argument
207062449Speteris NULL.
207162449Speter
207262449Speter<H2><A NAME="fdisplay">Control of Form Display</A></H2>
207362449Speter
207462449SpeterIn the overview section, you saw that to display a form you normally
207562449Speterstart by defining its size (and fields), posting it, and refreshing
207662449Speterthe screen.  There is an hidden step before posting, which is the
207762449Speterassociation of the form with a frame window (actually, a pair of
207862449Speterwindows) within which it will be displayed.  By default, the forms
207962449Speterlibrary associates every form with the full-screen window
208062449Speter<CODE>stdscr</CODE>. <P>
208162449Speter
208262449SpeterBy making this step explicit, you can associate a form with a declared
208362449Speterframe window on your screen display.  This can be useful if you want to
208462449Speteradapt the form display to different screen sizes, dynamically tile
208562449Speterforms on the screen, or use a form as part of an interface layout
208662449Spetermanaged by <A HREF="#panels">panels</A>. <P>
208762449Speter
208862449SpeterThe two windows associated with each form have the same functions as
208962449Spetertheir analogues in the <A HREF="#menu">menu library</A>.  Both these
209062449Speterwindows are painted when the form is posted and erased when the form
209162449Speteris unposted. <P>
209262449Speter
209362449SpeterThe outer or frame window is not otherwise touched by the form
209462449Speterroutines.  It exists so the programmer can associate a title, a
209562449Speterborder, or perhaps help text with the form and have it properly
209662449Speterrefreshed or erased at post/unpost time. The inner window or subwindow
209762449Speteris where the current form page is actually displayed. <P>
209862449Speter
209962449SpeterIn order to declare your own frame window for a form, you'll need to
210062449Speterknow the size of the form's bounding rectangle.  You can get this
210162449Speterinformation with:
210262449Speter
210362449Speter<PRE>
210462449Speterint scale_form(FORM *form,                /* form to query */
210562449Speter               int *rows,                 /* form rows */
210662449Speter               int *cols);                /* form cols */
210762449Speter</PRE>
210862449Speter
210962449SpeterThe form dimensions are passed back in the locations pointed to by
211062449Speterthe arguments.  Once you have this information, you can use it to
211162449Speterdeclare of windows, then use one of these functions:
211262449Speter
211362449Speter<PRE>
211462449Speterint set_form_win(FORM *form,              /* form to alter */
211562449Speter                 WINDOW *win);            /* frame window to connect */
211662449Speter
211762449SpeterWINDOW *form_win(FORM *form);             /* fetch frame window of form */
211862449Speter
211962449Speterint set_form_sub(FORM *form,              /* form to alter */
212062449Speter                 WINDOW *win);            /* form subwindow to connect */
212162449Speter
212262449SpeterWINDOW *form_sub(FORM *form);             /* fetch form subwindow of form */
212362449Speter</PRE>
212462449Speter
212562449SpeterNote that curses operations, including <CODE>refresh()</CODE>, on the form,
212662449Spetershould be done on the frame window, not the form subwindow. <P>
212762449Speter
212862449SpeterIt is possible to check from your application whether all of a
212962449Speterscrollable field is actually displayed within the menu subwindow.  Use
213062449Speterthese functions:
213162449Speter
213262449Speter<PRE>
213362449Speterint data_ahead(FORM *form);               /* form to be queried */
213462449Speter
213562449Speterint data_behind(FORM *form);              /* form to be queried */
213662449Speter</PRE>
213762449Speter
213862449SpeterThe function <CODE>data_ahead()</CODE> returns TRUE if (a) the current
213962449Speterfield is one-line and has undisplayed data off to the right, (b) the current
214062449Speterfield is multi-line and there is data off-screen below it. <P>
214162449Speter
214262449SpeterThe function <CODE>data_behind()</CODE> returns TRUE if the first (upper
214362449Speterleft hand) character position is off-screen (not being displayed). <P>
214462449Speter
214562449SpeterFinally, there is a function to restore the form window's cursor to the
214662449Spetervalue expected by the forms driver:
214762449Speter
214862449Speter<PRE>
214962449Speterint pos_form_cursor(FORM *)               /* form to be queried */
215062449Speter</PRE>
215162449Speter
215262449SpeterIf your application changes the form window cursor, call this function before
215362449Speterhanding control back to the forms driver in order to re-synchronize it.
215462449Speter
215562449Speter<H2><A NAME="fdriver">Input Processing in the Forms Driver</A></H2>
215662449Speter
215762449SpeterThe function <CODE>form_driver()</CODE> handles virtualized input requests
215862449Speterfor form navigation, editing, and validation requests, just as
215962449Speter<CODE>menu_driver</CODE> does for menus (see the section on <A
216062449SpeterHREF="#minput">menu input handling</A>).
216162449Speter
216262449Speter<PRE>
216362449Speterint form_driver(FORM *form,               /* form to pass input to */
216462449Speter                int request);             /* form request code */
216562449Speter</PRE>
216662449Speter
216762449SpeterYour input virtualization function needs to take input and then convert it
216862449Speterto either an alphanumeric character (which is treated as data to be
216962449Speterentered in the currently-selected field), or a forms processing request. <P>
217062449Speter
217162449SpeterThe forms driver provides hooks (through input-validation and
217262449Speterfield-termination functions) with which your application code can check
217362449Speterthat the input taken by the driver matched what was expected.
217462449Speter
217562449Speter<H3><A NAME="fpage">Page Navigation Requests</A></H3>
217662449Speter
217762449SpeterThese requests cause page-level moves through the form,
217862449Spetertriggering display of a new form screen.
217962449Speter
218062449Speter<DL>
218162449Speter<DT> <CODE>REQ_NEXT_PAGE</CODE>
218262449Speter<DD> Move to the next form page.
218362449Speter<DT> <CODE>REQ_PREV_PAGE</CODE>
218462449Speter<DD> Move to the previous form page.
218562449Speter<DT> <CODE>REQ_FIRST_PAGE</CODE>
218662449Speter<DD> Move to the first form page.
218762449Speter<DT> <CODE>REQ_LAST_PAGE</CODE>
218862449Speter<DD> Move to the last form page.
218962449Speter</DL>
219062449Speter
219162449SpeterThese requests treat the list as cyclic; that is, <CODE>REQ_NEXT_PAGE</CODE>
219262449Speterfrom the last page goes to the first, and <CODE>REQ_PREV_PAGE</CODE> from
219362449Speterthe first page goes to the last.
219462449Speter
2195174993Srafan<H3><A NAME="ffield">Inter-Field Navigation Requests</A></H3>
219662449Speter
219762449SpeterThese requests handle navigation between fields on the same page.
219862449Speter
219962449Speter<DL>
220062449Speter<DT> <CODE>REQ_NEXT_FIELD</CODE>
220162449Speter<DD> Move to next field.
220262449Speter<DT> <CODE>REQ_PREV_FIELD</CODE>
220362449Speter<DD> Move to previous field.
220462449Speter<DT> <CODE>REQ_FIRST_FIELD</CODE>
220562449Speter<DD> Move to the first field.
220662449Speter<DT> <CODE>REQ_LAST_FIELD</CODE>
220762449Speter<DD> Move to the last field.
220862449Speter<DT> <CODE>REQ_SNEXT_FIELD</CODE>
220962449Speter<DD> Move to sorted next field.
221062449Speter<DT> <CODE>REQ_SPREV_FIELD</CODE>
221162449Speter<DD> Move to sorted previous field.
221262449Speter<DT> <CODE>REQ_SFIRST_FIELD</CODE>
221362449Speter<DD> Move to the sorted first field.
221462449Speter<DT> <CODE>REQ_SLAST_FIELD</CODE>
221562449Speter<DD> Move to the sorted last field.
221662449Speter<DT> <CODE>REQ_LEFT_FIELD</CODE>
221762449Speter<DD> Move left to field.
221862449Speter<DT> <CODE>REQ_RIGHT_FIELD</CODE>
221962449Speter<DD> Move right to field.
222062449Speter<DT> <CODE>REQ_UP_FIELD</CODE>
222162449Speter<DD> Move up to field.
222262449Speter<DT> <CODE>REQ_DOWN_FIELD</CODE>
222362449Speter<DD> Move down to field.
222462449Speter</DL>
222562449Speter
222662449SpeterThese requests treat the list of fields on a page as cyclic; that is,
222762449Speter<CODE>REQ_NEXT_FIELD</CODE> from the last field goes to the first, and
222862449Speter<CODE>REQ_PREV_FIELD</CODE> from the first field goes to the last. The
222962449Speterorder of the fields for these (and the <CODE>REQ_FIRST_FIELD</CODE> and
223062449Speter<CODE>REQ_LAST_FIELD</CODE> requests) is simply the order of the field
223162449Speterpointers in the form array (as set up by <CODE>new_form()</CODE> or
223262449Speter<CODE>set_form_fields()</CODE> <P>
223362449Speter
223462449SpeterIt is also possible to traverse the fields as if they had been sorted in
223562449Speterscreen-position order, so the sequence goes left-to-right and top-to-bottom.
223662449SpeterTo do this, use the second group of four sorted-movement requests.  <P>
223762449Speter
223862449SpeterFinally, it is possible to move between fields using visual directions up,
223962449Speterdown, right, and left.  To accomplish this, use the third group of four
224062449Speterrequests.  Note, however, that the position of a form for purposes of these
224162449Speterrequests is its upper-left corner. <P>
224262449Speter
224362449SpeterFor example, suppose you have a multi-line field B, and two
224462449Spetersingle-line fields A and C on the same line with B, with A to the left
224562449Speterof B and C to the right of B.  A <CODE>REQ_MOVE_RIGHT</CODE> from A will
224662449Spetergo to B only if A, B, and C <EM>all</EM> share the same first line;
224762449Speterotherwise it will skip over B to C.
224862449Speter
2249174993Srafan<H3><A NAME="fifield">Intra-Field Navigation Requests</A></H3>
225062449Speter
225162449SpeterThese requests drive movement of the edit cursor within the currently
225262449Speterselected field.
225362449Speter
225462449Speter<DL>
225562449Speter<DT> <CODE>REQ_NEXT_CHAR</CODE>
225662449Speter<DD> Move to next character.
225762449Speter<DT> <CODE>REQ_PREV_CHAR</CODE>
225862449Speter<DD> Move to previous character.
225962449Speter<DT> <CODE>REQ_NEXT_LINE</CODE>
226062449Speter<DD> Move to next line.
226162449Speter<DT> <CODE>REQ_PREV_LINE</CODE>
226262449Speter<DD> Move to previous line.
226362449Speter<DT> <CODE>REQ_NEXT_WORD</CODE>
226462449Speter<DD> Move to next word.
226562449Speter<DT> <CODE>REQ_PREV_WORD</CODE>
226662449Speter<DD> Move to previous word.
226762449Speter<DT> <CODE>REQ_BEG_FIELD</CODE>
226862449Speter<DD> Move to beginning of field.
226962449Speter<DT> <CODE>REQ_END_FIELD</CODE>
227062449Speter<DD> Move to end of field.
227162449Speter<DT> <CODE>REQ_BEG_LINE</CODE>
227262449Speter<DD> Move to beginning of line.
227362449Speter<DT> <CODE>REQ_END_LINE</CODE>
227462449Speter<DD> Move to end of line.
227562449Speter<DT> <CODE>REQ_LEFT_CHAR</CODE>
227662449Speter<DD> Move left in field.
227762449Speter<DT> <CODE>REQ_RIGHT_CHAR</CODE>
227862449Speter<DD> Move right in field.
227962449Speter<DT> <CODE>REQ_UP_CHAR</CODE>
228062449Speter<DD> Move up in field.
228162449Speter<DT> <CODE>REQ_DOWN_CHAR</CODE>
228262449Speter<DD> Move down in field.
228362449Speter</DL>
228462449Speter
228562449SpeterEach <EM>word</EM> is separated from the previous and next characters
228662449Speterby whitespace.  The commands to move to beginning and end of line or field
228762449Speterlook for the first or last non-pad character in their ranges.
228862449Speter
228962449Speter<H3><A NAME="fscroll">Scrolling Requests</A></H3>
229062449Speter
229162449SpeterFields that are dynamic and have grown and fields explicitly created
229262449Speterwith offscreen rows are scrollable.  One-line fields scroll horizontally;
229362449Spetermulti-line fields scroll vertically.  Most scrolling is triggered by
229462449Speterediting and intra-field movement (the library scrolls the field to keep the
229562449Spetercursor visible).  It is possible to explicitly request scrolling with the
229662449Speterfollowing requests:
229762449Speter
229862449Speter<DL>
229962449Speter<DT> <CODE>REQ_SCR_FLINE</CODE>
230062449Speter<DD> Scroll vertically forward a line.
230162449Speter<DT> <CODE>REQ_SCR_BLINE</CODE>
230262449Speter<DD> Scroll vertically backward a line.
230362449Speter<DT> <CODE>REQ_SCR_FPAGE</CODE>
230462449Speter<DD> Scroll vertically forward a page.
230562449Speter<DT> <CODE>REQ_SCR_BPAGE</CODE>
230662449Speter<DD> Scroll vertically backward a page.
230762449Speter<DT> <CODE>REQ_SCR_FHPAGE</CODE>
230862449Speter<DD> Scroll vertically forward half a page.
230962449Speter<DT> <CODE>REQ_SCR_BHPAGE</CODE>
231062449Speter<DD> Scroll vertically backward half a page.
231162449Speter<DT> <CODE>REQ_SCR_FCHAR</CODE>
231262449Speter<DD> Scroll horizontally forward a character.
231362449Speter<DT> <CODE>REQ_SCR_BCHAR</CODE>
231462449Speter<DD> Scroll horizontally backward a character.
231562449Speter<DT> <CODE>REQ_SCR_HFLINE</CODE>
231662449Speter<DD> Scroll horizontally one field width forward.
231762449Speter<DT> <CODE>REQ_SCR_HBLINE</CODE>
231862449Speter<DD> Scroll horizontally one field width backward.
231962449Speter<DT> <CODE>REQ_SCR_HFHALF</CODE>
232062449Speter<DD> Scroll horizontally one half field width forward.
232162449Speter<DT> <CODE>REQ_SCR_HBHALF</CODE>
232262449Speter<DD> Scroll horizontally one half field width backward.
232362449Speter</DL>
232462449Speter
232562449SpeterFor scrolling purposes, a <EM>page</EM> of a field is the height
232662449Speterof its visible part.
232762449Speter
232862449Speter<H3><A NAME="fedit">Editing Requests</A></H3>
232962449Speter
233062449SpeterWhen you pass the forms driver an ASCII character, it is treated as a
233162449Speterrequest to add the character to the field's data buffer.  Whether this
233262449Speteris an insertion or a replacement depends on the field's edit mode
233362449Speter(insertion is the default. <P>
233462449Speter
233562449SpeterThe following requests support editing the field and changing the edit
233662449Spetermode:
233762449Speter
233862449Speter<DL>
233962449Speter<DT> <CODE>REQ_INS_MODE</CODE>
234062449Speter<DD> Set insertion mode.
234162449Speter<DT> <CODE>REQ_OVL_MODE</CODE>
234262449Speter<DD> Set overlay mode.
234362449Speter<DT> <CODE>REQ_NEW_LINE</CODE>
234462449Speter<DD> New line request (see below for explanation).
234562449Speter<DT> <CODE>REQ_INS_CHAR</CODE>
234662449Speter<DD> Insert space at character location.
234762449Speter<DT> <CODE>REQ_INS_LINE</CODE>
234862449Speter<DD> Insert blank line at character location.
234962449Speter<DT> <CODE>REQ_DEL_CHAR</CODE>
235062449Speter<DD> Delete character at cursor.
235162449Speter<DT> <CODE>REQ_DEL_PREV</CODE>
235262449Speter<DD> Delete previous word at cursor.
235362449Speter<DT> <CODE>REQ_DEL_LINE</CODE>
235462449Speter<DD> Delete line at cursor.
235562449Speter<DT> <CODE>REQ_DEL_WORD</CODE>
235662449Speter<DD> Delete word at cursor.
235762449Speter<DT> <CODE>REQ_CLR_EOL</CODE>
235862449Speter<DD> Clear to end of line.
235962449Speter<DT> <CODE>REQ_CLR_EOF</CODE>
236062449Speter<DD> Clear to end of field.
236162449Speter<DT> <CODE>REQ_CLEAR_FIELD</CODE>
236262449Speter<DD> Clear entire field.
236362449Speter</DL>
236462449Speter
236562449SpeterThe behavior of the <CODE>REQ_NEW_LINE</CODE> and <CODE>REQ_DEL_PREV</CODE> requests
236662449Speteris complicated and partly controlled by a pair of forms options.
236762449SpeterThe special cases are triggered when the cursor is at the beginning of
236862449Spetera field, or on the last line of the field. <P>
236962449Speter
237062449SpeterFirst, we consider <CODE>REQ_NEW_LINE</CODE>: <P>
237162449Speter
237262449SpeterThe normal behavior of <CODE>REQ_NEW_LINE</CODE> in insert mode is to break the
237362449Spetercurrent line at the position of the edit cursor, inserting the portion of
237462449Speterthe current line after the cursor as a new line following the current
237562449Speterand moving the cursor to the beginning of that new line (you may think
237662449Speterof this as inserting a newline in the field buffer). <P>
237762449Speter
237862449SpeterThe normal behavior of <CODE>REQ_NEW_LINE</CODE> in overlay mode is to clear the
237962449Spetercurrent line from the position of the edit cursor to end of line.
238062449SpeterThe cursor is then moved to the beginning of the next line. <P>
238162449Speter
238262449SpeterHowever, <CODE>REQ_NEW_LINE</CODE> at the beginning of a field, or on the
238362449Speterlast line of a field, instead does a <CODE>REQ_NEXT_FIELD</CODE>.
238462449Speter<CODE>O_NL_OVERLOAD</CODE> option is off, this special action is
238562449Speterdisabled. <P>
238662449Speter
238762449SpeterNow, let us consider <CODE>REQ_DEL_PREV</CODE>: <P>
238862449Speter
238962449SpeterThe normal behavior of <CODE>REQ_DEL_PREV</CODE> is to delete the previous
239062449Spetercharacter.  If insert mode is on, and the cursor is at the start of a
239162449Speterline, and the text on that line will fit on the previous one, it
239262449Speterinstead appends the contents of the current line to the previous one
239362449Speterand deletes the current line (you may think of this as deleting a
239462449Speternewline from the field buffer). <P>
239562449Speter
239662449SpeterHowever, <CODE>REQ_DEL_PREV</CODE> at the beginning of a field is instead
239762449Spetertreated as a <CODE>REQ_PREV_FIELD</CODE>. <P> If the
239862449Speter<CODE>O_BS_OVERLOAD</CODE> option is off, this special action is
239962449Speterdisabled and the forms driver just returns <CODE>E_REQUEST_DENIED</CODE>. <P>
240062449Speter
240162449SpeterSee <A HREF="#frmoptions">Form Options</A> for discussion of how to set
240262449Speterand clear the overload options.
240362449Speter
240462449Speter<H3><A NAME="forder">Order Requests</A></H3>
240562449Speter
240662449SpeterIf the type of your field is ordered, and has associated functions
240762449Speterfor getting the next and previous values of the type from a given value,
240862449Speterthere are requests that can fetch that value into the field buffer:
240962449Speter
241062449Speter<DL>
241162449Speter<DT> <CODE>REQ_NEXT_CHOICE</CODE>
241262449Speter<DD> Place the successor value of the current value in the buffer.
241362449Speter<DT> <CODE>REQ_PREV_CHOICE</CODE>
241462449Speter<DD> Place the predecessor value of the current value in the buffer.
241562449Speter</DL>
241662449Speter
241762449SpeterOf the built-in field types, only <CODE>TYPE_ENUM</CODE> has built-in successor
241862449Speterand predecessor functions.  When you define a field type of your own
241962449Speter(see <A HREF="#fcustom">Custom Validation Types</A>), you can associate
242062449Speterour own ordering functions.
242162449Speter
242262449Speter<H3><A NAME="fappcmds">Application Commands</A></H3>
242362449Speter
242462449SpeterForm requests are represented as integers above the <CODE>curses</CODE> value
242562449Spetergreater than <CODE>KEY_MAX</CODE> and less than or equal to the constant
242662449Speter<CODE>MAX_COMMAND</CODE>.  If your input-virtualization routine returns a
242762449Spetervalue above <CODE>MAX_COMMAND</CODE>, the forms driver will ignore it.
242862449Speter
242962449Speter<H2><A NAME="fhooks">Field Change Hooks</A></H2>
243062449Speter
243162449SpeterIt is possible to set function hooks to be executed whenever the
243262449Spetercurrent field or form changes.  Here are the functions that support this:
243362449Speter
243462449Speter<PRE>
243562449Spetertypedef void	(*HOOK)();       /* pointer to function returning void */
243662449Speter
243762449Speterint set_form_init(FORM *form,    /* form to alter */
243862449Speter                  HOOK hook);    /* initialization hook */
243962449Speter
244062449SpeterHOOK form_init(FORM *form);      /* form to query */
244162449Speter
244262449Speterint set_form_term(FORM *form,    /* form to alter */
244362449Speter                  HOOK hook);    /* termination hook */
244462449Speter
244562449SpeterHOOK form_term(FORM *form);      /* form to query */
244662449Speter
244762449Speterint set_field_init(FORM *form,   /* form to alter */
244862449Speter                  HOOK hook);    /* initialization hook */
244962449Speter
245062449SpeterHOOK field_init(FORM *form);     /* form to query */
245162449Speter
245262449Speterint set_field_term(FORM *form,   /* form to alter */
245362449Speter                  HOOK hook);    /* termination hook */
245462449Speter
245562449SpeterHOOK field_term(FORM *form);     /* form to query */
245662449Speter</PRE>
245762449Speter
245862449SpeterThese functions allow you to either set or query four different hooks.
245962449SpeterIn each of the set functions, the second argument should be the
246062449Speteraddress of a hook function.  These functions differ only in the timing
246162449Speterof the hook call.
246262449Speter
246362449Speter<DL>
246462449Speter<DT> form_init
246562449Speter<DD> This hook is called when the form is posted; also, just after
246662449Spetereach page change operation.
246762449Speter<DT> field_init
246862449Speter<DD> This hook is called when the form is posted; also, just after
246962449Spetereach field change
247062449Speter<DT> field_term
247162449Speter<DD> This hook is called just after field validation; that is, just before
247262449Speterthe field is altered.  It is also called when the form is unposted.
247362449Speter<DT> form_term
247462449Speter<DD> This hook is called when the form is unposted; also, just before
247562449Spetereach page change operation.
247662449Speter</DL>
247762449Speter
247862449SpeterCalls to these hooks may be triggered
247962449Speter<OL>
248062449Speter<LI>When user editing requests are processed by the forms driver
248162449Speter<LI>When the current page is changed by <CODE>set_current_field()</CODE> call
248262449Speter<LI>When the current field is changed by a <CODE>set_form_page()</CODE> call
248362449Speter</OL>
248462449Speter
248562449SpeterSee <A NAME="ffocus">Field Change Commands</A> for discussion of the latter
248662449Spetertwo cases. <P>
248762449Speter
248862449SpeterYou can set a default hook for all fields by passing one of the set functions
248962449Spetera NULL first argument. <P>
249062449Speter
249162449SpeterYou can disable any of these hooks by (re)setting them to NULL, the default
249262449Spetervalue.
249362449Speter
249462449Speter<H2><A HREF="#ffocus">Field Change Commands</A></H2>
249562449Speter
249662449SpeterNormally, navigation through the form will be driven by the user's
249762449Speterinput requests.  But sometimes it is useful to be able to move the
249862449Speterfocus for editing and viewing under control of your application, or
249962449Speterask which field it currently is in.  The following functions help you
250062449Speteraccomplish this:
250162449Speter
250262449Speter<PRE>
250362449Speterint set_current_field(FORM *form,         /* form to alter */
250462449Speter                      FIELD *field);      /* field to shift to */
250562449Speter
250662449SpeterFIELD *current_field(FORM *form);         /* form to query */
250762449Speter
250862449Speterint field_index(FORM *form,               /* form to query */
250962449Speter                FIELD *field);            /* field to get index of */
251062449Speter</PRE>
251162449Speter
251262449SpeterThe function <CODE>field_index()</CODE> returns the index of the given field
251362449Speterin the given form's field array (the array passed to <CODE>new_form()</CODE> or
251462449Speter<CODE>set_form_fields()</CODE>). <P>
251562449Speter
251662449SpeterThe initial current field of a form is the first active field on the
251762449Speterfirst page. The function <CODE>set_form_fields()</CODE> resets this.<P>
251862449Speter
251962449SpeterIt is also possible to move around by pages.
252062449Speter
252162449Speter<PRE>
252262449Speterint set_form_page(FORM *form,             /* form to alter */
252362449Speter                  int page);              /* page to go to (0-origin) */
252462449Speter
252562449Speterint form_page(FORM *form);                /* return form's current page */
252662449Speter</PRE>
252762449Speter
252862449SpeterThe initial page of a newly-created form is 0.  The function
252962449Speter<CODE>set_form_fields()</CODE> resets this.
253062449Speter
253162449Speter<H2><A NAME="frmoptions">Form Options</A></H2>
253262449Speter
253362449SpeterLike fields, forms may have control option bits.  They can be changed
253462449Speteror queried with these functions:
253562449Speter
253662449Speter<PRE>
253762449Speterint set_form_opts(FORM *form,             /* form to alter */
253862449Speter                  int attr);              /* attribute to set */
253962449Speter
254062449Speterint form_opts_on(FORM *form,              /* form to alter */
254162449Speter                 int attr);               /* attributes to turn on */
254262449Speter
254362449Speterint form_opts_off(FORM *form,             /* form to alter */
254462449Speter                  int attr);              /* attributes to turn off */
254562449Speter
254662449Speterint form_opts(FORM *form);                /* form to query */
254762449Speter</PRE>
254862449Speter
254962449SpeterBy default, all options are on.  Here are the available option bits:
255062449Speter
255162449Speter<DL>
255262449Speter<DT> O_NL_OVERLOAD
255362449Speter<DD> Enable overloading of <CODE>REQ_NEW_LINE</CODE> as described in <A
2554166124Srafanhref="#fedit">Editing Requests</A>.  The value of this option is
255562449Speterignored on dynamic fields that have not reached their size limit;
255662449Speterthese have no last line, so the circumstances for triggering a
255762449Speter<CODE>REQ_NEXT_FIELD</CODE> never arise.
255862449Speter<DT> O_BS_OVERLOAD
255962449Speter<DD> Enable overloading of <CODE>REQ_DEL_PREV</CODE> as described in
2560166124Srafan<A href="#fedit">Editing Requests</A>.
256162449Speter</DL>
256262449Speter
256362449SpeterThe option values are bit-masks and can be composed with logical-or in
256462449Speterthe obvious way.
256562449Speter
256662449Speter<H2><A NAME="fcustom">Custom Validation Types</A></H2>
256762449Speter
256862449SpeterThe <CODE>form</CODE> library gives you the capability to define custom
256962449Spetervalidation types of your own.  Further, the optional additional arguments
257062449Speterof <CODE>set_field_type</CODE> effectively allow you to parameterize validation
257162449Spetertypes.  Most of the complications in the validation-type interface have to
257262449Speterdo with the handling of the additional arguments within custom validation
257362449Speterfunctions.
257462449Speter
257562449Speter<H3><A NAME="flinktypes">Union Types</A></H3>
257662449Speter
257762449SpeterThe simplest way to create a custom data type is to compose it from two
257862449Speterpreexisting ones:
257962449Speter
258062449Speter<PRE>
258162449SpeterFIELD *link_fieldtype(FIELDTYPE *type1,
258262449Speter                      FIELDTYPE *type2);
258362449Speter</PRE>
258462449Speter
258562449SpeterThis function creates a field type that will accept any of the values
258662449Speterlegal for either of its argument field types (which may be either
258762449Speterpredefined or programmer-defined).
258862449Speter
258962449SpeterIf a <CODE>set_field_type()</CODE> call later requires arguments, the new
259062449Spetercomposite type expects all arguments for the first type, than all arguments
259162449Speterfor the second.  Order functions (see <A HREF="#forder">Order Requests</A>)
259262449Speterassociated with the component types will work on the composite; what it does
259362449Speteris check the validation function for the first type, then for the second, to
259462449Speterfigure what type the buffer contents should be treated as.
259562449Speter
259662449Speter<H3><A NAME="fnewtypes">New Field Types</A></H3>
259762449Speter
259862449SpeterTo create a field type from scratch, you need to specify one or both of the
259962449Speterfollowing things:
260062449Speter
260162449Speter<UL>
260262449Speter<LI>A character-validation function, to check each character as it is entered.
260362449Speter<LI>A field-validation function to be applied on exit from the field.
260462449Speter</UL>
260562449Speter
260662449SpeterHere's how you do that:
260762449Speter<PRE>
260862449Spetertypedef int	(*HOOK)();       /* pointer to function returning int */
260962449Speter
261062449SpeterFIELDTYPE *new_fieldtype(HOOK f_validate, /* field validator */
261162449Speter                         HOOK c_validate) /* character validator */
261262449Speter
261362449Speter
261462449Speterint free_fieldtype(FIELDTYPE *ftype);     /* type to free */
261562449Speter</PRE>
261662449Speter
261762449SpeterAt least one of the arguments of <CODE>new_fieldtype()</CODE> must be
261862449Speternon-NULL.  The forms driver will automatically call the new type's
261962449Spetervalidation functions at appropriate points in processing a field of
262062449Speterthe new type. <P>
262162449Speter
262262449SpeterThe function <CODE>free_fieldtype()</CODE> deallocates the argument
262362449Speterfieldtype, freeing all storage associated with it. <P>
262462449Speter
262562449SpeterNormally, a field validator is called when the user attempts to
262662449Speterleave the field.  Its first argument is a field pointer, from which it
262762449Spetercan get to field buffer 0 and test it.  If the function returns TRUE,
262862449Speterthe operation succeeds; if it returns FALSE, the edit cursor stays in
262962449Speterthe field. <P>
263062449Speter
263162449SpeterA character validator gets the character passed in as a first argument.
263262449SpeterIt too should return TRUE if the character is valid, FALSE otherwise.
263362449Speter
263462449Speter<H3><A NAME="fcheckargs">Validation Function Arguments</A></H3>
263562449Speter
263662449SpeterYour field- and character- validation functions will be passed a
263762449Spetersecond argument as well.  This second argument is the address of a
263862449Speterstructure (which we'll call a <EM>pile</EM>) built from any of the
263962449Speterfield-type-specific arguments passed to <CODE>set_field_type()</CODE>.  If
264062449Speterno such arguments are defined for the field type, this pile pointer
264162449Speterargument will be NULL. <P>
264262449Speter
264362449SpeterIn order to arrange for such arguments to be passed to your validation
264462449Speterfunctions, you must associate a small set of storage-management functions
264562449Speterwith the type.  The forms driver will use these to synthesize a pile
264662449Speterfrom the trailing arguments of each <CODE>set_field_type()</CODE> argument, and
264762449Spetera pointer to the pile will be passed to the validation functions. <P>
264862449Speter
264962449SpeterHere is how you make the association:
265062449Speter
265162449Speter<PRE>
265262449Spetertypedef char	*(*PTRHOOK)();    /* pointer to function returning (char *) */
265362449Spetertypedef void	(*VOIDHOOK)();    /* pointer to function returning void */
265462449Speter
265562449Speterint set_fieldtype_arg(FIELDTYPE *type,    /* type to alter */
265662449Speter                      PTRHOOK make_str,   /* make structure from args */
265762449Speter                      PTRHOOK copy_str,   /* make copy of structure */
265862449Speter                      VOIDHOOK free_str); /* free structure storage */
265962449Speter</PRE>
266062449Speter
266162449SpeterHere is how the storage-management hooks are used:
266262449Speter
266362449Speter<DL>
266462449Speter<DT> <CODE>make_str</CODE>
266562449Speter<DD> This function is called by <CODE>set_field_type()</CODE>.  It gets one
266662449Speterargument, a <CODE>va_list</CODE> of the type-specific arguments passed to
266762449Speter<CODE>set_field_type()</CODE>.  It is expected to return a pile pointer to a data
266862449Speterstructure that encapsulates those arguments.
266962449Speter<DT> <CODE>copy_str</CODE>
267062449Speter<DD> This function is called by form library functions that allocate new
267162449Speterfield instances.  It is expected to take a pile pointer, copy the pile
267262449Speterto allocated storage, and return the address of the pile copy.
267362449Speter<DT> <CODE>free_str</CODE>
267462449Speter<DD> This function is called by field- and type-deallocation routines in the
267562449Speterlibrary.  It takes a pile pointer argument, and is expected to free the
267662449Speterstorage of that pile.
267762449Speter</DL>
267862449Speter
267962449SpeterThe <CODE>make_str</CODE> and <CODE>copy_str</CODE> functions may return NULL to
268062449Spetersignal allocation failure.  The library routines will that call them will
268162449Speterreturn error indication when this happens.  Thus, your validation functions
268262449Spetershould never see a NULL file pointer and need not check specially for it.
268362449Speter
268462449Speter<H3><A NAME="fcustorder">Order Functions For Custom Types</A></H3>
268562449Speter
268662449SpeterSome custom field types are simply ordered in the same well-defined way
268762449Speterthat <CODE>TYPE_ENUM</CODE> is.  For such types, it is possible to define
268862449Spetersuccessor and predecessor functions to support the <CODE>REQ_NEXT_CHOICE</CODE>
268962449Speterand <CODE>REQ_PREV_CHOICE</CODE> requests. Here's how:
269062449Speter
269162449Speter<PRE>
269262449Spetertypedef int	(*INTHOOK)();     /* pointer to function returning int */
269362449Speter
269462449Speterint set_fieldtype_arg(FIELDTYPE *type,    /* type to alter */
269562449Speter                      INTHOOK succ,       /* get successor value */
269662449Speter                      INTHOOK pred);      /* get predecessor value */
269762449Speter</PRE>
269862449Speter
269962449SpeterThe successor and predecessor arguments will each be passed two arguments;
270062449Spetera field pointer, and a pile pointer (as for the validation functions).  They
270162449Speterare expected to use the function <CODE>field_buffer()</CODE> to read the
270262449Spetercurrent value, and <CODE>set_field_buffer()</CODE> on buffer 0 to set the next
270362449Speteror previous value.  Either hook may return TRUE to indicate success (a
270462449Speterlegal next or previous value was set) or FALSE to indicate failure.
270562449Speter
270662449Speter<H3><A NAME="fcustprobs">Avoiding Problems</A></H3>
270762449Speter
270862449SpeterThe interface for defining custom types is complicated and tricky.
270962449SpeterRather than attempting to create a custom type entirely from scratch,
271062449Speteryou should start by studying the library source code for whichever of
271162449Speterthe pre-defined types seems to be closest to what you want. <P>
271262449Speter
271362449SpeterUse that code as a model, and evolve it towards what you really want.
271462449SpeterYou will avoid many problems and annoyances that way.  The code
271562449Speterin the <CODE>ncurses</CODE> library has been specifically exempted from
271662449Speterthe package copyright to support this. <P>
271762449Speter
271862449SpeterIf your custom type defines order functions, have do something intuitive
271962449Speterwith a blank field.  A useful convention is to make the successor of a
272062449Speterblank field the types minimum value, and its predecessor the maximum.
272162449Speter</BODY>
272262449Speter</HTML>
2723