ncurses-intro.html revision 166124
162449Speter<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
262449Speter<!--
3166124Srafan  $Id: ncurses-intro.html,v 1.41 2005/12/24 15:47:05 tom Exp $
4166124Srafan  ****************************************************************************
5166124Srafan  * Copyright (c) 1998-2004,2005 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
91762449SpeterA resize operation in X sends SIGWINCH to the application running under xterm.
91862449SpeterThe <CODE>ncurses</CODE> library provides an experimental signal
91962449Speterhandler, but in general does not catch this signal, because it cannot
92062449Speterknow how you want the screen re-painted.  You will usually have to write the
92162449SpeterSIGWINCH handler yourself.  Ncurses can give you some help. <P>
92262449Speter
92362449SpeterThe easiest way to code your SIGWINCH handler is to have it do an
92462449Speter<CODE>endwin</CODE>, followed by an <CODE>refresh</CODE> and a screen repaint you code
92562449Speteryourself.  The <CODE>refresh</CODE> will pick up the new screen size from the
92662449Speterxterm's environment. <P>
92762449Speter
92862449SpeterThat is the standard way, of course (it even works with some vendor's curses
92962449Speterimplementations).
93062449SpeterIts drawback is that it clears the screen to reinitialize the display, and does
93162449Speternot resize subwindows which must be shrunk.
93262449Speter<CODE>Ncurses</CODE> provides an extension which works better, the
93362449Speter<CODE>resizeterm</CODE> function.  That function ensures that all windows
93462449Speterare limited to the new screen dimensions, and pads <CODE>stdscr</CODE>
93562449Speterwith blanks if the screen is larger. <P>
93662449Speter
93762449SpeterFinally, ncurses can be configured to provide its own SIGWINCH handler,
93862449Speterbased on <CODE>resizeterm</CODE>.
93962449Speter
94062449Speter<H3><A NAME="screens">Handling Multiple Terminal Screens</A></H3>
94162449Speter
94262449SpeterThe <CODE>initscr()</CODE> function actually calls a function named
94362449Speter<CODE>newterm()</CODE> to do most of its work.  If you are writing a program that
94462449Speteropens multiple terminals, use <CODE>newterm()</CODE> directly. <P>
94562449Speter
94662449SpeterFor each call, you will have to specify a terminal type and a pair of file
94762449Speterpointers; each call will return a screen reference, and <CODE>stdscr</CODE> will be
94862449Speterset to the last one allocated.  You will switch between screens with the
94962449Speter<CODE>set_term</CODE> call.  Note that you will also have to call
95062449Speter<CODE>def_shell_mode</CODE> and <CODE>def_prog_mode</CODE> on each tty yourself.
95162449Speter
95262449Speter<H3><A NAME="testing">Testing for Terminal Capabilities</A></H3>
95362449Speter
95462449SpeterSometimes you may want to write programs that test for the presence of various
95562449Spetercapabilities before deciding whether to go into <CODE>ncurses</CODE> mode.  An easy
95662449Speterway to do this is to call <CODE>setupterm()</CODE>, then use the functions
95762449Speter<CODE>tigetflag()</CODE>, <CODE>tigetnum()</CODE>, and <CODE>tigetstr()</CODE> to do your
95862449Spetertesting. <P>
95962449Speter
96062449SpeterA particularly useful case of this often comes up when you want to
96162449Spetertest whether a given terminal type should be treated as `smart'
96262449Speter(cursor-addressable) or `stupid'.  The right way to test this is to see
96362449Speterif the return value of <CODE>tigetstr("cup")</CODE> is non-NULL.  Alternatively,
96462449Speteryou can include the <CODE>term.h</CODE> file and test the value of the
96562449Spetermacro <CODE>cursor_address</CODE>.
96662449Speter
96762449Speter<H3><A NAME="tuning">Tuning for Speed</A></H3>
96862449Speter
96962449SpeterUse the <CODE>addchstr()</CODE> family of functions for fast
97062449Speterscreen-painting of text when you know the text doesn't contain any
97162449Spetercontrol characters.  Try to make attribute changes infrequent on your
97262449Speterscreens.  Don't use the <CODE>immedok()</CODE> option!
97362449Speter
97462449Speter<H3><A NAME="special">Special Features of NCURSES</A></H3>
97562449Speter
97662449SpeterThe <CODE>wresize()</CODE> function allows you to resize a window in place.
97762449SpeterThe associated <CODE>resizeterm()</CODE> function simplifies the construction
97862449Speterof <a HREF="#xterm">SIGWINCH</a> handlers, for resizing all windows.  <P>
97962449Speter
98062449SpeterThe <CODE>define_key()</CODE> function allows you
98162449Speterto define at runtime function-key control sequences which are not in the
98262449Speterterminal description.
98362449SpeterThe <CODE>keyok()</CODE> function allows you to temporarily
98462449Speterenable or disable interpretation of any function-key control sequence. <P>
98562449Speter
98662449SpeterThe <CODE>use_default_colors()</CODE> function allows you to construct
98762449Speterapplications which can use the terminal's default foreground and
98862449Speterbackground colors as an additional "default" color.
98962449SpeterSeveral terminal emulators support this feature, which is based on ISO 6429. <P>
99062449Speter
99162449SpeterNcurses supports up 16 colors, unlike SVr4 curses which defines only 8.
99262449SpeterWhile most terminals which provide color allow only 8 colors, about
99362449Spetera quarter (including XFree86 xterm) support 16 colors.
99462449Speter
99562449Speter<H2><A NAME="compat">Compatibility with Older Versions</A></H2>
99662449Speter
99762449SpeterDespite our best efforts, there are some differences between <CODE>ncurses</CODE>
99862449Speterand the (undocumented!) behavior of older curses implementations.  These arise
99962449Speterfrom ambiguities or omissions in the documentation of the API.
100062449Speter
100162449Speter<H3><A NAME="refbug">Refresh of Overlapping Windows</A></H3>
100262449Speter
100362449SpeterIf you define two windows A and B that overlap, and then alternately scribble
100462449Speteron and refresh them, the changes made to the overlapping region under historic
100562449Speter<CODE>curses</CODE> versions were often not documented precisely. <P>
100662449Speter
100762449SpeterTo understand why this is a problem, remember that screen updates are
100862449Spetercalculated between two representations of the <EM>entire</EM> display. The
1009166124Srafandocumentation says that when you refresh a window, it is first copied to the
101062449Spetervirtual screen, and then changes are calculated to update the physical screen
101162449Speter(and applied to the terminal).  But "copied to" is not very specific, and
101262449Spetersubtle differences in how copying works can produce different behaviors in the
101362449Spetercase where two overlapping windows are each being refreshed at unpredictable
101462449Speterintervals. <P>
101562449Speter
101662449SpeterWhat happens to the overlapping region depends on what <CODE>wnoutrefresh()</CODE>
101762449Speterdoes with its argument -- what portions of the argument window it copies to the
101862449Spetervirtual screen.  Some implementations do "change copy", copying down only
101962449Speterlocations in the window that have changed (or been marked changed with
102062449Speter<CODE>wtouchln()</CODE> and friends).  Some implementations do  "entire copy",
102162449Spetercopying <EM>all</EM> window locations to the virtual screen whether or not
102262449Speterthey have changed. <P>
102362449Speter
102462449SpeterThe <CODE>ncurses</CODE> library itself has not always been consistent on this
102562449Speterscore.  Due to a bug, versions 1.8.7 to 1.9.8a did entire copy.  Versions
102662449Speter1.8.6 and older, and versions 1.9.9 and newer, do change copy. <P>
102762449Speter
102862449SpeterFor most commercial curses implementations, it is not documented and not known
102962449Speterfor sure (at least not to the <CODE>ncurses</CODE> maintainers) whether they do
103062449Speterchange copy or entire copy.  We know that System V release 3 curses has logic
103162449Speterin it that looks like an attempt to do change copy, but the surrounding logic
103262449Speterand data representations are sufficiently complex, and our knowledge
103362449Spetersufficiently indirect, that it's hard to know whether this is reliable.
103462449Speter
103562449SpeterIt is not clear what the SVr4 documentation and XSI standard intend.  The XSI
103662449SpeterCurses standard barely mentions wnoutrefresh(); the SVr4 documents seem to be
103762449Speterdescribing entire-copy, but it is possible with some effort and straining to
103862449Speterread them the other way. <P>
103962449Speter
104062449SpeterIt might therefore be unwise to rely on either behavior in programs that might
104162449Speterhave to be linked with other curses implementations.  Instead, you can do an
104262449Speterexplicit <CODE>touchwin()</CODE> before the <CODE>wnoutrefresh()</CODE> call to
104362449Speterguarantee an entire-contents copy anywhere. <P>
104462449Speter
104562449SpeterThe really clean way to handle this is to use the panels library.  If,
104662449Speterwhen you want a screen update, you do <CODE>update_panels()</CODE>, it will
1047166124Srafando all the necessary <CODE>wnoutrefresh()</CODE> calls for whatever panel
104862449Speterstacking order you have defined.  Then you can do one <CODE>doupdate()</CODE>
104962449Speterand there will be a <EM>single</EM> burst of physical I/O that will do
105062449Speterall your updates.
105162449Speter
105262449Speter<H3><A NAME="backbug">Background Erase</A></H3>
105362449Speter
105462449SpeterIf you have been using a very old versions of <CODE>ncurses</CODE> (1.8.7 or
105562449Speterolder) you may be surprised by the behavior of the erase functions.  In older
105662449Speterversions, erased areas of a window were filled with a blank modified by the
105762449Speterwindow's current attribute (as set by <STRONG>wattrset()</STRONG>, <STRONG>wattron()</STRONG>,
105862449Speter<STRONG>wattroff()</STRONG> and friends). <P>
105962449Speter
106062449SpeterIn newer versions, this is not so.  Instead, the attribute of erased blanks
106162449Speteris normal unless and until it is modified by the functions <CODE>bkgdset()</CODE>
106262449Speteror <CODE>wbkgdset()</CODE>. <P>
106362449Speter
106462449SpeterThis change in behavior conforms <CODE>ncurses</CODE> to System V Release 4 and
106562449Speterthe XSI Curses standard.
106662449Speter
106762449Speter<H2><A NAME="xsifuncs">XSI Curses Conformance</A></H2>
106862449Speter
106962449SpeterThe <CODE>ncurses</CODE> library is intended to be base-level conformant with the
107062449SpeterXSI Curses standard from X/Open.  Many extended-level features (in fact, almost
107162449Speterall features not directly concerned with wide characters and
107262449Speterinternationalization) are also supported. <P>
107362449Speter
107462449SpeterOne effect of XSI conformance is the change in behavior described under
107562449Speter<A HREF="#backbug">"Background Erase -- Compatibility with Old Versions"</A>. <P>
107662449Speter
107762449SpeterAlso, <CODE>ncurses</CODE> meets the XSI requirement that every macro
107862449Speterentry point have a corresponding function which may be linked (and
107962449Speterwill be prototype-checked) if the macro definition is disabled with
108062449Speter<CODE>#undef</CODE>.
108162449Speter
108262449Speter<H1><A NAME="panels">The Panels Library</A></H1>
108362449Speter
108462449SpeterThe <CODE>ncurses</CODE> library by itself provides good support for screen
108562449Speterdisplays in which the windows are tiled (non-overlapping).  In the more
108662449Spetergeneral case that windows may overlap, you have to use a series of
108762449Speter<CODE>wnoutrefresh()</CODE> calls followed by a <CODE>doupdate()</CODE>, and be
108862449Spetercareful about the order you do the window refreshes in.  It has to be
108962449Speterbottom-upwards, otherwise parts of windows that should be obscured will
109062449Spetershow through. <P>
109162449Speter
109262449SpeterWhen your interface design is such that windows may dive deeper into the
109362449Spetervisibility stack or pop to the top at runtime, the resulting book-keeping
109462449Spetercan be tedious and difficult to get right.  Hence the panels library. <P>
109562449Speter
109662449SpeterThe <CODE>panel</CODE> library first appeared in AT&amp;T System V.  The
109762449Speterversion documented here is the <CODE>panel</CODE> code distributed
109862449Speterwith <CODE>ncurses</CODE>.
109962449Speter
110062449Speter<H2><A NAME="pcompile">Compiling With the Panels Library</A></H2>
110162449Speter
110262449SpeterYour panels-using modules must import the panels library declarations with
110362449Speter
110462449Speter<PRE>
110562449Speter	  #include &lt;panel.h&gt;
110662449Speter</PRE>
110762449Speter
110862449Speterand must be linked explicitly with the panels library using an
110962449Speter<CODE>-lpanel</CODE> argument.  Note that they must also link the
111062449Speter<CODE>ncurses</CODE> library with <CODE>-lncurses</CODE>.  Many linkers
111162449Speterare two-pass and will accept either order, but it is still good practice
111262449Speterto put <CODE>-lpanel</CODE> first and <CODE>-lncurses</CODE> second.
111362449Speter
111462449Speter<H2><A NAME="poverview">Overview of Panels</A></H2>
111562449Speter
111662449SpeterA panel object is a window that is implicitly treated as part of a
111762449Speter<DFN>deck</DFN> including all other panel objects.  The deck has an implicit
111862449Speterbottom-to-top visibility order.  The panels library includes an update
111962449Speterfunction (analogous to <CODE>refresh()</CODE>) that displays all panels in the
112062449Speterdeck in the proper order to resolve overlaps.  The standard window,
112162449Speter<CODE>stdscr</CODE>, is considered below all panels. <P>
112262449Speter
112362449SpeterDetails on the panels functions are available in the man pages.  We'll just
112462449Speterhit the highlights here. <P>
112562449Speter
112662449SpeterYou create a panel from a window by calling <CODE>new_panel()</CODE> on a
112762449Speterwindow pointer.  It then becomes the top of the deck.  The panel's window
112862449Speteris available as the value of <CODE>panel_window()</CODE> called with the
112962449Speterpanel pointer as argument.<P>
113062449Speter
113162449SpeterYou can delete a panel (removing it from the deck) with <CODE>del_panel</CODE>.
113262449SpeterThis will not deallocate the associated window; you have to do that yourself.
113362449Speter
113462449SpeterYou can replace a panel's window with a different window by calling
113562449Speter<CODE>replace_window</CODE>.  The new window may be of different size;
113662449Speterthe panel code will re-compute all overlaps.  This operation doesn't
113762449Speterchange the panel's position in the deck. <P>
113862449Speter
113962449SpeterTo move a panel's window, use <CODE>move_panel()</CODE>.  The
114062449Speter<CODE>mvwin()</CODE> function on the panel's window isn't sufficient because it
114162449Speterdoesn't update the panels library's representation of where the windows are.
114262449SpeterThis operation leaves the panel's depth, contents, and size unchanged. <P>
114362449Speter
114462449SpeterTwo functions (<CODE>top_panel()</CODE>, <CODE>bottom_panel()</CODE>) are
114562449Speterprovided for rearranging the deck.  The first pops its argument window to the
114662449Spetertop of the deck; the second sends it to the bottom.  Either operation leaves
114762449Speterthe panel's screen location, contents, and size unchanged. <P>
114862449Speter
114962449SpeterThe function <CODE>update_panels()</CODE> does all the
115062449Speter<CODE>wnoutrefresh()</CODE> calls needed to prepare for
115162449Speter<CODE>doupdate()</CODE> (which you must call yourself, afterwards). <P>
115262449Speter
115362449SpeterTypically, you will want to call <CODE>update_panels()</CODE> and
115462449Speter<CODE>doupdate()</CODE> just before accepting command input, once in each cycle
115562449Speterof interaction with the user.  If you call <CODE>update_panels()</CODE> after
115662449Spetereach and every panel write, you'll generate a lot of unnecessary refresh
115762449Speteractivity and screen flicker.
115862449Speter
115962449Speter<H2><A NAME="pstdscr">Panels, Input, and the Standard Screen</A></H2>
116062449Speter
116162449SpeterYou shouldn't mix <CODE>wnoutrefresh()</CODE> or <CODE>wrefresh()</CODE>
116262449Speteroperations with panels code; this will work only if the argument window
116362449Speteris either in the top panel or unobscured by any other panels. <P>
116462449Speter
116562449SpeterThe <CODE>stsdcr</CODE> window is a special case.  It is considered below all
116662449Speterpanels.  Because changes to panels may obscure parts of <CODE>stdscr</CODE>,
116762449Speterthough, you should call <CODE>update_panels()</CODE> before
116862449Speter<CODE>doupdate()</CODE> even when you only change <CODE>stdscr</CODE>. <P>
116962449Speter
117062449SpeterNote that <CODE>wgetch</CODE> automatically calls <CODE>wrefresh</CODE>.
117162449SpeterTherefore, before requesting input from a panel window, you need to be sure
117262449Speterthat the panel is totally unobscured. <P>
117362449Speter
117462449SpeterThere is presently no way to display changes to one obscured panel without
117562449Speterrepainting all panels.
117662449Speter
117762449Speter<H2><A NAME="hiding">Hiding Panels</A></H2>
117862449Speter
117962449SpeterIt's possible to remove a panel from the deck temporarily; use
118062449Speter<CODE>hide_panel</CODE> for this.  Use <CODE>show_panel()</CODE> to render it
118162449Spetervisible again.  The predicate function <CODE>panel_hidden</CODE>
118262449Spetertests whether or not a panel is hidden. <P>
118362449Speter
118462449SpeterThe <CODE>panel_update</CODE> code ignores hidden panels.  You cannot do
118562449Speter<CODE>top_panel()</CODE> or <CODE>bottom_panel</CODE> on a hidden panel().
118662449SpeterOther panels operations are applicable.
118762449Speter
118862449Speter<H2><A NAME="pmisc">Miscellaneous Other Facilities</A></H2>
118962449Speter
119062449SpeterIt's possible to navigate the deck using the functions
119162449Speter<CODE>panel_above()</CODE> and <CODE>panel_below</CODE>.  Handed a panel
119262449Speterpointer, they return the panel above or below that panel.  Handed
119362449Speter<CODE>NULL</CODE>, they return the bottom-most or top-most panel. <P>
119462449Speter
119562449SpeterEvery panel has an associated user pointer, not used by the panel code, to
119662449Speterwhich you can attach application data.  See the man page documentation
119762449Speterof <CODE>set_panel_userptr()</CODE> and <CODE>panel_userptr</CODE> for
119862449Speterdetails.
119962449Speter
120062449Speter<H1><A NAME="menu">The Menu Library</A></H1>
120162449Speter
120262449SpeterA menu is a screen display that assists the user to choose some subset
120362449Speterof a given set of items.  The <CODE>menu</CODE> library is a curses
120462449Speterextension that supports easy programming of menu hierarchies with a
120562449Speteruniform but flexible interface. <P>
120662449Speter
120762449SpeterThe <CODE>menu</CODE> library first appeared in AT&amp;T System V.  The
120862449Speterversion documented here is the <CODE>menu</CODE> code distributed
120962449Speterwith <CODE>ncurses</CODE>.
121062449Speter
121162449Speter<H2><A NAME="mcompile">Compiling With the menu Library</A></H2>
121262449Speter
121362449SpeterYour menu-using modules must import the menu library declarations with
121462449Speter
121562449Speter<PRE>
121662449Speter	  #include &lt;menu.h&gt;
121762449Speter</PRE>
121862449Speter
121962449Speterand must be linked explicitly with the menus library using an
122062449Speter<CODE>-lmenu</CODE> argument.  Note that they must also link the
122162449Speter<CODE>ncurses</CODE> library with <CODE>-lncurses</CODE>.  Many linkers
122262449Speterare two-pass and will accept either order, but it is still good practice
122362449Speterto put <CODE>-lmenu</CODE> first and <CODE>-lncurses</CODE> second.
122462449Speter
122562449Speter<H2><A NAME="moverview">Overview of Menus</A></H2>
122662449Speter
122762449SpeterThe menus created by this library consist of collections of
122862449Speter<DFN>items</DFN> including a name string part and a description string
122962449Speterpart.  To make menus, you create groups of these items and connect
123062449Speterthem with menu frame objects. <P>
123162449Speter
123262449SpeterThe menu can then by <DFN>posted</DFN>, that is written to an
123362449Speterassociated window.  Actually, each menu has two associated windows; a
123462449Spetercontaining window in which the programmer can scribble titles or
123562449Speterborders, and a subwindow in which the menu items proper are displayed.
123662449SpeterIf this subwindow is too small to display all the items, it will be a
123762449Speterscrollable viewport on the collection of items. <P>
123862449Speter
123962449SpeterA menu may also be <DFN>unposted</DFN> (that is, undisplayed), and finally
124062449Speterfreed to make the storage associated with it and its items available for
124162449Speterre-use. <P>
124262449Speter
124362449SpeterThe general flow of control of a menu program looks like this:
124462449Speter
124562449Speter<OL>
124662449Speter<LI>Initialize <CODE>curses</CODE>.
124762449Speter<LI>Create the menu items, using <CODE>new_item()</CODE>.
124862449Speter<LI>Create the menu using <CODE>new_menu()</CODE>.
1249166124Srafan<LI>Post the menu using <CODE>post_menu()</CODE>.
125062449Speter<LI>Refresh the screen.
125162449Speter<LI>Process user requests via an input loop.
1252166124Srafan<LI>Unpost the menu using <CODE>unpost_menu()</CODE>.
125362449Speter<LI>Free the menu, using <CODE>free_menu()</CODE>.
125462449Speter<LI>Free the items using <CODE>free_item()</CODE>.
125562449Speter<LI>Terminate <CODE>curses</CODE>.
125662449Speter</OL>
125762449Speter
125862449Speter<H2><A NAME="mselect">Selecting items</A></H2>
125962449Speter
126062449SpeterMenus may be multi-valued or (the default) single-valued (see the manual
126162449Speterpage <CODE>menu_opts(3x)</CODE> to see how to change the default).
126262449SpeterBoth types always have a <DFN>current item</DFN>. <P>
126362449Speter
126462449SpeterFrom a single-valued menu you can read the selected value simply by looking
126562449Speterat the current item.  From a multi-valued menu, you get the selected set
126662449Speterby looping through the items applying the <CODE>item_value()</CODE>
126762449Speterpredicate function.  Your menu-processing code can use the function
126862449Speter<CODE>set_item_value()</CODE> to flag the items in the select set. <P>
126962449Speter
127062449SpeterMenu items can be made unselectable using <CODE>set_item_opts()</CODE>
127162449Speteror <CODE>item_opts_off()</CODE> with the <CODE>O_SELECTABLE</CODE>
127262449Speterargument.  This is the only option so far defined for menus, but it
127362449Speteris good practice to code as though other option bits might be on.
127462449Speter
127562449Speter<H2><A NAME="mdisplay">Menu Display</A></H2>
127662449Speter
127762449SpeterThe menu library calculates a minimum display size for your window, based
127862449Speteron the following variables:
127962449Speter
128062449Speter<UL>
128162449Speter<LI>The number and maximum length of the menu items
128262449Speter<LI>Whether the O_ROWMAJOR option is enabled
128362449Speter<LI>Whether display of descriptions is enabled
128462449Speter<LI>Whatever menu format may have been set by the programmer
128562449Speter<LI>The length of the menu mark string used for highlighting selected items
128662449Speter</UL>
128762449Speter
128862449SpeterThe function <CODE>set_menu_format()</CODE> allows you to set the
128962449Spetermaximum size of the viewport or <DFN>menu page</DFN> that will be used
129062449Speterto display menu items.  You can retrieve any format associated with a
129162449Spetermenu with <CODE>menu_format()</CODE>. The default format is rows=16,
129262449Spetercolumns=1. <P>
129362449Speter
129462449SpeterThe actual menu page may be smaller than the format size.  This depends
129562449Speteron the item number and size and whether O_ROWMAJOR is on.  This option
129662449Speter(on by default) causes menu items to be displayed in a `raster-scan'
129762449Speterpattern, so that if more than one item will fit horizontally the first
129862449Spetercouple of items are side-by-side in the top row.  The alternative is
129962449Spetercolumn-major display, which tries to put the first several items in
130062449Speterthe first column. <P>
130162449Speter
130262449SpeterAs mentioned above, a menu format not large enough to allow all items to fit
130362449Speteron-screen will result in a menu display that is vertically scrollable. <P>
130462449SpeterYou can scroll it with requests to the menu driver, which will be described
130562449Speterin the section on <A HREF="#minput">menu input handling</A>. <P>
130662449Speter
130762449SpeterEach menu has a <DFN>mark string</DFN> used to visually tag selected items;
130862449Spetersee the <CODE>menu_mark(3x)</CODE> manual page for details.  The mark
130962449Speterstring length also influences the menu page size. <P>
131062449Speter
131162449SpeterThe function <CODE>scale_menu()</CODE> returns the minimum display size
131262449Speterthat the menu code computes from all these factors.
131362449Speter
131462449SpeterThere are other menu display attributes including a select attribute,
131562449Speteran attribute for selectable items, an attribute for unselectable items,
131662449Speterand a pad character used to separate item name text from description
131762449Spetertext.  These have reasonable defaults which the library allows you to
131862449Speterchange (see the <CODE>menu_attribs(3x)</CODE> manual page.
131962449Speter
132062449Speter<H2><A NAME="mwindows">Menu Windows</A></H2>
132162449Speter
132262449SpeterEach menu has, as mentioned previously, a pair of associated windows.
132362449SpeterBoth these windows are painted when the menu is posted and erased when
132462449Speterthe menu is unposted. <P>
132562449Speter
132662449SpeterThe outer or frame window is not otherwise touched by the menu
132762449Speterroutines.  It exists so the programmer can associate a title, a
132862449Speterborder, or perhaps help text with the menu and have it properly
132962449Speterrefreshed or erased at post/unpost time.  The inner window or
133062449Speter<DFN>subwindow</DFN> is where the current menu page is displayed. <P>
133162449Speter
133262449SpeterBy default, both windows are <CODE>stdscr</CODE>.  You can set them with the
133362449Speterfunctions in <CODE>menu_win(3x)</CODE>. <P>
133462449Speter
1335166124SrafanWhen you call <CODE>post_menu()</CODE>, you write the menu to its
1336166124Srafansubwindow.  When you call <CODE>unpost_menu()</CODE>, you erase the
133762449Spetersubwindow, However, neither of these actually modifies the screen.  To
133862449Speterdo that, call <CODE>wrefresh()</CODE> or some equivalent.
133962449Speter
134062449Speter<H2><A NAME="minput">Processing Menu Input</A></H2>
134162449Speter
134262449SpeterThe main loop of your menu-processing code should call
134362449Speter<CODE>menu_driver()</CODE> repeatedly. The first argument of this routine
134462449Speteris a menu pointer; the second is a menu command code.  You should write an
134562449Speterinput-fetching routine that maps input characters to menu command codes, and
134662449Speterpass its output to <CODE>menu_driver()</CODE>.  The menu command codes are
134762449Speterfully documented in <CODE>menu_driver(3x)</CODE>. <P>
134862449Speter
134962449SpeterThe simplest group of command codes is <CODE>REQ_NEXT_ITEM</CODE>,
135062449Speter<CODE>REQ_PREV_ITEM</CODE>, <CODE>REQ_FIRST_ITEM</CODE>,
135162449Speter<CODE>REQ_LAST_ITEM</CODE>, <CODE>REQ_UP_ITEM</CODE>,
135262449Speter<CODE>REQ_DOWN_ITEM</CODE>, <CODE>REQ_LEFT_ITEM</CODE>,
135362449Speter<CODE>REQ_RIGHT_ITEM</CODE>.  These change the currently selected
135462449Speteritem.  These requests may cause scrolling of the menu page if it only
135562449Speterpartially displayed. <P>
135662449Speter
135762449SpeterThere are explicit requests for scrolling which also change the
135862449Spetercurrent item (because the select location does not change, but the
135962449Speteritem there does).  These are <CODE>REQ_SCR_DLINE</CODE>,
136062449Speter<CODE>REQ_SCR_ULINE</CODE>, <CODE>REQ_SCR_DPAGE</CODE>, and
136162449Speter<CODE>REQ_SCR_UPAGE</CODE>. <P>
136262449Speter
136362449SpeterThe <CODE>REQ_TOGGLE_ITEM</CODE> selects or deselects the current item.
136462449SpeterIt is for use in multi-valued menus; if you use it with <CODE>O_ONEVALUE</CODE>
136562449Speteron, you'll get an error return (<CODE>E_REQUEST_DENIED</CODE>). <P>
136662449Speter
136762449SpeterEach menu has an associated pattern buffer.  The
136862449Speter<CODE>menu_driver()</CODE> logic tries to accumulate printable ASCII
136962449Spetercharacters passed in in that buffer; when it matches a prefix of an
137062449Speteritem name, that item (or the next matching item) is selected.  If
137162449Speterappending a character yields no new match, that character is deleted
137262449Speterfrom the pattern buffer, and <CODE>menu_driver()</CODE> returns
137362449Speter<CODE>E_NO_MATCH</CODE>. <P>
137462449Speter
137562449SpeterSome requests change the pattern buffer directly:
137662449Speter<CODE>REQ_CLEAR_PATTERN</CODE>, <CODE>REQ_BACK_PATTERN</CODE>,
137762449Speter<CODE>REQ_NEXT_MATCH</CODE>, <CODE>REQ_PREV_MATCH</CODE>.  The latter
137862449Spetertwo are useful when pattern buffer input matches more than one item
137962449Speterin a multi-valued menu. <P>
138062449Speter
138162449SpeterEach successful scroll or item navigation request clears the pattern
138262449Speterbuffer.  It is also possible to set the pattern buffer explicitly
138362449Speterwith <CODE>set_menu_pattern()</CODE>. <P>
138462449Speter
138562449SpeterFinally, menu driver requests above the constant <CODE>MAX_COMMAND</CODE>
138662449Speterare considered application-specific commands.  The <CODE>menu_driver()</CODE>
138762449Spetercode ignores them and returns <CODE>E_UNKNOWN_COMMAND</CODE>.
138862449Speter
138962449Speter<H2><A NAME="mmisc">Miscellaneous Other Features</A></H2>
139062449Speter
139162449SpeterVarious menu options can affect the processing and visual appearance
139262449Speterand input processing of menus.  See <CODE>menu_opts(3x) for
139362449Speterdetails.</CODE> <P>
139462449Speter
139562449SpeterIt is possible to change the current item from application code; this
139662449Speteris useful if you want to write your own navigation requests.  It is
139762449Speteralso possible to explicitly set the top row of the menu display.  See
139862449Speter<CODE>mitem_current(3x)</CODE>.
139962449Speter
140062449SpeterIf your application needs to change the menu subwindow cursor for
140162449Speterany reason, <CODE>pos_menu_cursor()</CODE> will restore it to the
140262449Spetercorrect location for continuing menu driver processing. <P>
140362449Speter
140462449SpeterIt is possible to set hooks to be called at menu initialization and
140562449Speterwrapup time, and whenever the selected item changes.  See
140662449Speter<CODE>menu_hook(3x)</CODE>. <P>
140762449Speter
140862449SpeterEach item, and each menu, has an associated user pointer on which you
140962449Spetercan hang application data.  See <CODE>mitem_userptr(3x)</CODE> and
141062449Speter<CODE>menu_userptr(3x)</CODE>.
141162449Speter
141262449Speter<H1><A NAME="form">The Forms Library</A></H1>
141362449Speter
141462449SpeterThe <CODE>form</CODE> library is a curses extension that supports easy
141562449Speterprogramming of on-screen forms for data entry and program control. <P>
141662449Speter
141762449SpeterThe <CODE>form</CODE> library first appeared in AT&amp;T System V.  The
141862449Speterversion documented here is the <CODE>form</CODE> code distributed
141962449Speterwith <CODE>ncurses</CODE>.
142062449Speter
142162449Speter<H2><A NAME="fcompile">Compiling With the form Library</A></H2>
142262449Speter
142362449SpeterYour form-using modules must import the form library declarations with
142462449Speter
142562449Speter<PRE>
142662449Speter	  #include &lt;form.h&gt;
142762449Speter</PRE>
142862449Speter
142962449Speterand must be linked explicitly with the forms library using an
143062449Speter<CODE>-lform</CODE> argument.  Note that they must also link the
143162449Speter<CODE>ncurses</CODE> library with <CODE>-lncurses</CODE>.  Many linkers
143262449Speterare two-pass and will accept either order, but it is still good practice
143362449Speterto put <CODE>-lform</CODE> first and <CODE>-lncurses</CODE> second.
143462449Speter
143562449Speter<H2><A NAME="foverview">Overview of Forms</A></H2>
143662449Speter
143762449SpeterA form is a collection of fields; each field may be either a label
143862449Speter(explanatory text) or a data-entry location.  Long forms may be
143962449Spetersegmented into pages; each entry to a new page clears the screen. <P>
144062449SpeterTo make forms, you create groups of fields and connect them with form
144162449Speterframe objects; the form library makes this relatively simple. <P>
144262449Speter
144362449SpeterOnce defined, a form can be <DFN>posted</DFN>, that is written to an
144462449Speterassociated window.  Actually, each form has two associated windows; a
144562449Spetercontaining window in which the programmer can scribble titles or
144662449Speterborders, and a subwindow in which the form fields proper are displayed. <P>
144762449Speter
144862449SpeterAs the form user fills out the posted form, navigation and editing
144962449Speterkeys support movement between fields, editing keys support modifying
145062449Speterfield, and plain text adds to or changes data in a current field.  The
145162449Speterform library allows you (the forms designer) to bind each navigation
145262449Speterand editing key to any keystroke accepted by <CODE>curses</CODE>
145362449Speter
145462449SpeterFields may have validation conditions on them, so that they check input
145562449Speterdata for type and value.  The form library supplies a rich set of
145662449Speterpre-defined field types, and makes it relatively easy to define new ones. <P>
145762449Speter
145862449SpeterOnce its transaction is completed (or aborted), a form may be
145962449Speter<DFN>unposted</DFN> (that is, undisplayed), and finally freed to make
146062449Speterthe storage associated with it and its items available for re-use. <P>
146162449Speter
146262449SpeterThe general flow of control of a form program looks like this:
146362449Speter
146462449Speter<OL>
146562449Speter<LI>Initialize <CODE>curses</CODE>.
146662449Speter<LI>Create the form fields, using <CODE>new_field()</CODE>.
146762449Speter<LI>Create the form using <CODE>new_form()</CODE>.
1468166124Srafan<LI>Post the form using <CODE>post_form()</CODE>.
146962449Speter<LI>Refresh the screen.
147062449Speter<LI>Process user requests via an input loop.
1471166124Srafan<LI>Unpost the form using <CODE>unpost_form()</CODE>.
147262449Speter<LI>Free the form, using <CODE>free_form()</CODE>.
147362449Speter<LI>Free the fields using <CODE>free_field()</CODE>.
147462449Speter<LI>Terminate <CODE>curses</CODE>.
147562449Speter</OL>
147662449Speter
147762449SpeterNote that this looks much like a menu program; the form library handles
147862449Spetertasks which are in many ways similar, and its interface was obviously
147962449Speterdesigned to resemble that of the <A HREF="#menu">menu library</A>
148062449Speterwherever possible. <P>
148162449Speter
148262449SpeterIn forms programs, however, the `process user requests' is somewhat more
148362449Spetercomplicated than for menus.  Besides menu-like navigation operations,
148462449Speterthe menu driver loop has to support field editing and data validation.
148562449Speter
148662449Speter<H2><A NAME="fcreate">Creating and Freeing Fields and Forms</A></H2>
148762449Speter
148862449SpeterThe basic function for creating fields is <CODE>new_field()</CODE>:
148962449Speter
149062449Speter<PRE>
149162449SpeterFIELD *new_field(int height, int width,   /* new field size */
149262449Speter                 int top, int left,       /* upper left corner */
149362449Speter                 int offscreen,           /* number of offscreen rows */
149462449Speter                 int nbuf);               /* number of working buffers */
149562449Speter</PRE>
149662449Speter
149762449SpeterMenu items always occupy a single row, but forms fields may have
149862449Spetermultiple rows.  So <CODE>new_field()</CODE> requires you to specify a
149962449Speterwidth and height (the first two arguments, which mist both be greater
150062449Speterthan zero). <P>
150162449Speter
150262449SpeterYou must also specify the location of the field's upper left corner on
150362449Speterthe screen (the third and fourth arguments, which must be zero or
150462449Spetergreater). Note that these coordinates are relative to the form
150562449Spetersubwindow, which will coincide with <CODE>stdscr</CODE> by default but
150662449Speterneed not be <CODE>stdscr</CODE> if you've done an explicit
1507166124Srafan<CODE>set_form_win()</CODE> call. <P>
150862449Speter
150962449SpeterThe fifth argument allows you to specify a number of off-screen rows.  If
151062449Speterthis is zero, the entire field will always be displayed.  If it is
151162449Speternonzero, the form will be scrollable, with only one screen-full (initially
151262449Speterthe top part) displayed at any given time.  If you make a field dynamic
151362449Speterand grow it so it will no longer fit on the screen, the form will become
151462449Speterscrollable even if the <CODE>offscreen</CODE> argument was initially zero. <P>
151562449Speter
151662449SpeterThe forms library allocates one working buffer per field; the size of
151762449Spetereach buffer is <CODE>((height + offscreen)*width + 1</CODE>, one character
151862449Speterfor each position in the field plus a NUL terminator.  The sixth
151962449Speterargument is the number of additional data buffers to allocate for the
152062449Speterfield; your application can use them for its own purposes.
152162449Speter
152262449Speter<PRE>
152362449SpeterFIELD *dup_field(FIELD *field,            /* field to copy */
152462449Speter                 int top, int left);      /* location of new copy */
152562449Speter</PRE>
152662449Speter
152762449SpeterThe function <CODE>dup_field()</CODE> duplicates an existing field at a
152862449Speternew location.  Size and buffering information are copied; some
152962449Speterattribute flags and status bits are not (see the
153062449Speter<CODE>form_field_new(3X)</CODE> for details).
153162449Speter
153262449Speter<PRE>
153362449SpeterFIELD *link_field(FIELD *field,           /* field to copy */
153462449Speter                  int top, int left);     /* location of new copy */
153562449Speter</PRE>
153662449Speter
153762449SpeterThe function <CODE>link_field()</CODE> also duplicates an existing field
153862449Speterat a new location.  The difference from <CODE>dup_field()</CODE> is that
153962449Speterit arranges for the new field's buffer to be shared with the old one. <P>
154062449Speter
154162449SpeterBesides the obvious use in making a field editable from two different
154262449Speterform pages, linked fields give you a way to hack in dynamic labels.  If
154362449Speteryou declare several fields linked to an original, and then make them
154462449Speterinactive, changes from the original will still be propagated to the
154562449Speterlinked fields. <P>
154662449Speter
154762449SpeterAs with duplicated fields, linked fields have attribute bits separate
154862449Speterfrom the original. <P>
154962449Speter
155062449SpeterAs you might guess, all these field-allocations return <CODE>NULL</CODE> if
155162449Speterthe field allocation is not possible due to an out-of-memory error or
155262449Speterout-of-bounds arguments. <P>
155362449Speter
155462449SpeterTo connect fields to a form, use
155562449Speter
155662449Speter<PRE>
155762449SpeterFORM *new_form(FIELD **fields);
155862449Speter</PRE>
155962449Speter
156062449SpeterThis function expects to see a NULL-terminated array of field pointers.
156162449SpeterSaid fields are connected to a newly-allocated form object; its address
156262449Speteris returned (or else NULL if the allocation fails).   <P>
156362449Speter
156462449SpeterNote that <CODE>new_field()</CODE> does <EM>not</EM> copy the pointer array
156562449Speterinto private storage; if you modify the contents of the pointer array
156662449Speterduring forms processing, all manner of bizarre things might happen.  Also
156762449Speternote that any given field may only be connected to one form. <P>
156862449Speter
156962449SpeterThe functions <CODE>free_field()</CODE> and <CODE>free_form</CODE> are available
157062449Speterto free field and form objects.  It is an error to attempt to free a field
157162449Speterconnected to a form, but not vice-versa; thus, you will generally free
157262449Speteryour form objects first.
157362449Speter
157462449Speter<H2><A NAME="fattributes">Fetching and Changing Field Attributes</A></H2>
157562449Speter
157662449SpeterEach form field has a number of location and size attributes
157762449Speterassociated with it. There are other field attributes used to control
157862449Speterdisplay and editing of the field.  Some (for example, the <CODE>O_STATIC</CODE> bit)
157962449Speterinvolve sufficient complications to be covered in sections of their own
158062449Speterlater on.  We cover the functions used to get and set several basic
158162449Speterattributes here. <P>
158262449Speter
158362449SpeterWhen a field is created, the attributes not specified by the
158462449Speter<CODE>new_field</CODE> function are copied from an invisible system
158562449Speterdefault field.  In attribute-setting and -fetching functions, the
158662449Speterargument NULL is taken to mean this field.  Changes to it persist
158762449Speteras defaults until your forms application terminates.
158862449Speter
158962449Speter<H3><A NAME="fsizes">Fetching Size and Location Data</A></H3>
159062449Speter
159162449SpeterYou can retrieve field sizes and locations through:
159262449Speter
159362449Speter<PRE>
159462449Speterint field_info(FIELD *field,              /* field from which to fetch */
159562449Speter               int *height, *int width,   /* field size */
159662449Speter               int *top, int *left,       /* upper left corner */
159762449Speter               int *offscreen,            /* number of offscreen rows */
159862449Speter               int *nbuf);                /* number of working buffers */
159962449Speter</PRE>
160062449Speter
160162449SpeterThis function is a sort of inverse of <CODE>new_field()</CODE>; instead of
160262449Spetersetting size and location attributes of a new field, it fetches them
160362449Speterfrom an existing one.
160462449Speter
160562449Speter<H3><A NAME="flocation">Changing the Field Location</A></H3>
160662449Speter
160762449SpeterIt is possible to move a field's location on the screen:
160862449Speter
160962449Speter<PRE>
161062449Speterint move_field(FIELD *field,              /* field to alter */
161162449Speter               int top, int left);        /* new upper-left corner */
161262449Speter</PRE>
161362449Speter
161462449SpeterYou can, of course. query the current location through <CODE>field_info()</CODE>.
161562449Speter
161662449Speter<H3><A NAME="fjust">The Justification Attribute</A></H3>
161762449Speter
161862449SpeterOne-line fields may be unjustified, justified right, justified left,
161962449Speteror centered.  Here is how you manipulate this attribute:
162062449Speter
162162449Speter<PRE>
162262449Speterint set_field_just(FIELD *field,          /* field to alter */
162362449Speter                   int justmode);         /* mode to set */
162462449Speter
162562449Speterint field_just(FIELD *field);             /* fetch mode of field */
162662449Speter</PRE>
162762449Speter
162862449SpeterThe mode values accepted and returned by this functions are
162962449Speterpreprocessor macros <CODE>NO_JUSTIFICATION</CODE>, <CODE>JUSTIFY_RIGHT</CODE>,
163062449Speter<CODE>JUSTIFY_LEFT</CODE>, or <CODE>JUSTIFY_CENTER</CODE>.
163162449Speter
163262449Speter<H3><A NAME="fdispatts">Field Display Attributes</A></H3>
163362449Speter
163462449SpeterFor each field, you can set a foreground attribute for entered
163562449Spetercharacters, a background attribute for the entire field, and a pad
163662449Spetercharacter for the unfilled portion of the field.  You can also
163762449Spetercontrol pagination of the form. <P>
163862449Speter
163962449SpeterThis group of four field attributes controls the visual appearance
164062449Speterof the field on the screen, without affecting in any way the data
164162449Speterin the field buffer.
164262449Speter
164362449Speter<PRE>
164462449Speterint set_field_fore(FIELD *field,          /* field to alter */
164562449Speter                   chtype attr);          /* attribute to set */
164662449Speter
164762449Speterchtype field_fore(FIELD *field);          /* field to query */
164862449Speter
164962449Speterint set_field_back(FIELD *field,          /* field to alter */
165062449Speter                   chtype attr);          /* attribute to set */
165162449Speter
165262449Speterchtype field_back(FIELD *field);          /* field to query */
165362449Speter
165462449Speterint set_field_pad(FIELD *field,           /* field to alter */
165562449Speter                 int pad);                /* pad character to set */
165662449Speter
165762449Speterchtype field_pad(FIELD *field);
165862449Speter
165962449Speterint set_new_page(FIELD *field,            /* field to alter */
166062449Speter                 int flag);               /* TRUE to force new page */
166162449Speter
166262449Speterchtype new_page(FIELD *field);            /* field to query */
166362449Speter</PRE>
166462449Speter
166562449SpeterThe attributes set and returned by the first four functions are normal
166662449Speter<CODE>curses(3x)</CODE> display attribute values (<CODE>A_STANDOUT</CODE>,
166762449Speter<CODE>A_BOLD</CODE>, <CODE>A_REVERSE</CODE> etc).
166862449Speter
166962449SpeterThe page bit of a field controls whether it is displayed at the start of
167062449Spetera new form screen.
167162449Speter
167262449Speter<H3><A NAME="foptions">Field Option Bits</A></H3>
167362449Speter
167462449SpeterThere is also a large collection of field option bits you can set to control
167562449Spetervarious aspects of forms processing.  You can manipulate them with these
167662449Speterfunctions:
167762449Speter
167862449Speter<PRE>
167962449Speterint set_field_opts(FIELD *field,          /* field to alter */
168062449Speter                   int attr);             /* attribute to set */
168162449Speter
168262449Speterint field_opts_on(FIELD *field,           /* field to alter */
168362449Speter                  int attr);              /* attributes to turn on */
168462449Speter
168562449Speterint field_opts_off(FIELD *field,          /* field to alter */
168662449Speter                   int attr);             /* attributes to turn off */
168762449Speter
168862449Speterint field_opts(FIELD *field);             /* field to query */
168962449Speter</PRE>
169062449Speter
169162449SpeterBy default, all options are on.  Here are the available option bits:
169262449Speter<DL>
169362449Speter<DT> O_VISIBLE
169462449Speter<DD> Controls whether the field is visible on the screen.  Can be used
169562449Speterduring form processing to hide or pop up fields depending on the value
169662449Speterof parent fields.
169762449Speter<DT> O_ACTIVE
169862449Speter<DD> Controls whether the field is active during forms processing (i.e.
169962449Spetervisited by form navigation keys).  Can be used to make labels or derived
170062449Speterfields with buffer values alterable by the forms application, not the user.
170162449Speter<DT> O_PUBLIC
170262449Speter<DD> Controls whether data is displayed during field entry.  If this option is
170362449Speterturned off on a field, the library will accept and edit data in that field,
170462449Speterbut it will not be displayed and the visible field cursor will not move.
170562449SpeterYou can turn off the O_PUBLIC bit to define password fields.
170662449Speter<DT> O_EDIT
170762449Speter<DD> Controls whether the field's data can be modified.  When this option is
170862449Speteroff, all editing requests except <CODE>REQ_PREV_CHOICE</CODE> and
170962449Speter<CODE>REQ_NEXT_CHOICE</CODE> will fail.  Such read-only fields may be useful for
171062449Speterhelp messages.
171162449Speter<DT> O_WRAP
171262449Speter<DD> Controls word-wrapping in multi-line fields.  Normally, when any
171362449Spetercharacter of a (blank-separated) word reaches the end of the current line, the
171462449Speterentire word is wrapped to the next line (assuming there is one).  When this
171562449Speteroption is off, the word will be split across the line break.
171662449Speter<DT> O_BLANK
171762449Speter<DD> Controls field blanking.  When this option is on, entering a character at
171862449Speterthe first field position erases the entire field (except for the just-entered
171962449Spetercharacter).
172062449Speter<DT> O_AUTOSKIP
172162449Speter<DD> Controls automatic skip to next field when this one fills.  Normally,
172262449Speterwhen the forms user tries to type more data into a field than will fit,
172362449Speterthe editing location jumps to next field.  When this option is off, the
172462449Speteruser's cursor will hang at the end of the field.  This option is ignored
172562449Speterin dynamic fields that have not reached their size limit.
172662449Speter<DT> O_NULLOK
172762449Speter<DD> Controls whether <A HREF="#fvalidation">validation</A> is applied to
172862449Speterblank fields.  Normally, it is not; the user can leave a field blank
172962449Speterwithout invoking the usual validation check on exit.  If this option is
173062449Speteroff on a field, exit from it will invoke a validation check.
173162449Speter<DT> O_PASSOK
173262449Speter<DD> Controls whether validation occurs on every exit, or only after
173362449Speterthe field is modified.  Normally the latter is true.  Setting O_PASSOK
173462449Spetermay be useful if your field's validation function may change during
173562449Speterforms processing.
173662449Speter<DT> O_STATIC
173762449Speter<DD> Controls whether the field is fixed to its initial dimensions.  If you
173862449Speterturn this off, the field becomes <A HREF="#fdynamic">dynamic</A> and will
173962449Speterstretch to fit entered data.
174062449Speter</DL>
174162449Speter
174262449SpeterA field's options cannot be changed while the field is currently selected.
174362449SpeterHowever, options may be changed on posted fields that are not current. <P>
174462449Speter
174562449SpeterThe option values are bit-masks and can be composed with logical-or in
174662449Speterthe obvious way.
174762449Speter
174862449Speter<H2><A NAME="fstatus">Field Status</A></H2>
174962449Speter
175062449SpeterEvery field has a status flag, which is set to FALSE when the field is
175162449Spetercreated and TRUE when the value in field buffer 0 changes.  This flag can
175262449Speterbe queried and set directly:
175362449Speter
175462449Speter<PRE>
175562449Speterint set_field_status(FIELD *field,      /* field to alter */
175662449Speter                   int status);         /* mode to set */
175762449Speter
175862449Speterint field_status(FIELD *field);         /* fetch mode of field */
175962449Speter</PRE>
176062449Speter
176162449SpeterSetting this flag under program control can be useful if you use the same
176262449Speterform repeatedly, looking for modified fields each time. <P>
176362449Speter
176462449SpeterCalling <CODE>field_status()</CODE> on a field not currently selected
176562449Speterfor input will return a correct value.  Calling <CODE>field_status()</CODE> on a
176662449Speterfield that is currently selected for input may not necessarily give a
176762449Spetercorrect field status value, because entered data isn't necessarily copied to
176862449Speterbuffer zero before the exit validation check.
176962449Speter
177062449SpeterTo guarantee that the returned status value reflects reality, call
177162449Speter<CODE>field_status()</CODE> either (1) in the field's exit validation check
177262449Speterroutine, (2) from the field's or form's initialization or termination
177362449Speterhooks, or (3) just after a <CODE>REQ_VALIDATION</CODE> request has been
177462449Speterprocessed by the forms driver.
177562449Speter
177662449Speter<H2><A NAME="fuser">Field User Pointer</A></H2>
177762449Speter
177862449SpeterEach field structure contains one character pointer slot that is not used
177962449Speterby the forms library.  It is intended to be used by applications to store
178062449Speterprivate per-field data.  You can manipulate it with:
178162449Speter
178262449Speter<PRE>
178362449Speterint set_field_userptr(FIELD *field,       /* field to alter */
178462449Speter                   char *userptr);        /* mode to set */
178562449Speter
178662449Speterchar *field_userptr(FIELD *field);        /* fetch mode of field */
178762449Speter</PRE>
178862449Speter
178962449Speter(Properly, this user pointer field ought to have <CODE>(void *)</CODE> type.
179062449SpeterThe <CODE>(char *)</CODE> type is retained for System V compatibility.) <P>
179162449Speter
179262449SpeterIt is valid to set the user pointer of the default field (with a
179362449Speter<CODE>set_field_userptr()</CODE> call passed a NULL field pointer.)
179462449SpeterWhen a new field is created, the default-field user pointer is copied
179562449Speterto initialize the new field's user pointer.
179662449Speter
179762449Speter<H2><A NAME="fdynamic">Variable-Sized Fields</A></H2>
179862449Speter
179962449SpeterNormally, a field is fixed at the size specified for it at creation
180062449Spetertime.  If, however, you turn off its O_STATIC bit, it becomes
180162449Speter<DFN>dynamic</DFN> and will automatically resize itself to accommodate
180262449Speterdata as it is entered.  If the field has extra buffers associated with it,
180362449Speterthey will grow right along with the main input buffer.  <P>
180462449Speter
180562449SpeterA one-line dynamic field will have a fixed height (1) but variable
180662449Speterwidth, scrolling horizontally to display data within the field area as
180762449Speteroriginally dimensioned and located.  A multi-line dynamic field will
180862449Speterhave a fixed width, but variable height (number of rows), scrolling
180962449Spetervertically to display data within the field area as originally
181062449Speterdimensioned and located. <P>
181162449Speter
181262449SpeterNormally, a dynamic field is allowed to grow without limit.  But it is
181362449Speterpossible to set an upper limit on the size of a dynamic field.  You do
181462449Speterit with this function:
181562449Speter
181662449Speter<PRE>
181762449Speterint set_max_field(FIELD *field,     /* field to alter (may not be NULL) */
181862449Speter                   int max_size);   /* upper limit on field size */
181962449Speter</PRE>
182062449Speter
182162449SpeterIf the field is one-line, <CODE>max_size</CODE> is taken to be a column size
182262449Speterlimit; if it is multi-line, it is taken to be a line size limit.  To disable
182362449Speterany limit, use an argument of zero.  The growth limit can be changed whether
182462449Speteror not the O_STATIC bit is on, but has no effect until it is. <P>
182562449Speter
182662449SpeterThe following properties of a field change when it becomes dynamic:
182762449Speter
182862449Speter<UL>
182962449Speter<LI>If there is no growth limit, there is no final position of the field;
183062449Spetertherefore <CODE>O_AUTOSKIP</CODE> and <CODE>O_NL_OVERLOAD</CODE> are ignored.
183162449Speter<LI>Field justification will be ignored (though whatever justification is
183262449Speterset up will be retained internally and can be queried).
183362449Speter<LI>The <CODE>dup_field()</CODE> and <CODE>link_field()</CODE> calls copy
183462449Speterdynamic-buffer sizes.  If the <CODE>O_STATIC</CODE> option is set on one of a
183562449Spetercollection of links, buffer resizing will occur only when the field is
183662449Speteredited through that link.
183762449Speter<LI>The call <CODE>field_info()</CODE> will retrieve the original static size of
183862449Speterthe field; use <CODE>dynamic_field_info()</CODE> to get the actual dynamic size.
183962449Speter</UL>
184062449Speter
184162449Speter<H2><A NAME="fvalidation">Field Validation</A></H2>
184262449Speter
184362449SpeterBy default, a field will accept any data that will fit in its input buffer.
184462449SpeterHowever, it is possible to attach a validation type to a field.  If you do
184562449Speterthis, any attempt to leave the field while it contains data that doesn't
184662449Spetermatch the validation type will fail.  Some validation types also have a
184762449Spetercharacter-validity check for each time a character is entered in the field. <P>
184862449Speter
184962449SpeterA field's validation check (if any) is not called when
185062449Speter<CODE>set_field_buffer()</CODE> modifies the input buffer, nor when that buffer
185162449Speteris changed through a linked field. <P>
185262449Speter
185362449SpeterThe <CODE>form</CODE> library provides a rich set of pre-defined validation
185462449Spetertypes, and gives you the capability to define custom ones of your own.  You
185562449Spetercan examine and change field validation attributes with the following
185662449Speterfunctions:
185762449Speter
185862449Speter<PRE>
185962449Speterint set_field_type(FIELD *field,          /* field to alter */
186062449Speter                   FIELDTYPE *ftype,      /* type to associate */
186162449Speter                   ...);                  /* additional arguments*/
186262449Speter
186362449SpeterFIELDTYPE *field_type(FIELD *field);      /* field to query */
186462449Speter</PRE>
186562449Speter
186662449SpeterThe validation type of a field is considered an attribute of the field.  As
186762449Speterwith other field attributes, Also, doing <CODE>set_field_type()</CODE> with a
186862449Speter<CODE>NULL</CODE> field default will change the system default for validation of
186962449Speternewly-created fields. <P>
187062449Speter
187162449SpeterHere are the pre-defined validation types:
187262449Speter
187362449Speter<H3><A NAME="ftype_alpha">TYPE_ALPHA</A></H3>
187462449Speter
187562449SpeterThis field type accepts alphabetic data; no blanks, no digits, no special
187662449Spetercharacters (this is checked at character-entry time).  It is set up with:
187762449Speter
187862449Speter<PRE>
187962449Speterint set_field_type(FIELD *field,          /* field to alter */
188062449Speter                   TYPE_ALPHA,            /* type to associate */
188162449Speter                   int width);            /* maximum width of field */
188262449Speter</PRE>
188362449Speter
188462449SpeterThe <CODE>width</CODE> argument sets a minimum width of data.  Typically
188562449Speteryou'll want to set this to the field width; if it's greater than the
188662449Speterfield width, the validation check will always fail.  A minimum width
188762449Speterof zero makes field completion optional.
188862449Speter
188962449Speter<H3><A NAME="ftype_alnum">TYPE_ALNUM</A></H3>
189062449Speter
189162449SpeterThis field type accepts alphabetic data and digits; no blanks, no special
189262449Spetercharacters (this is checked at character-entry time).  It is set up with:
189362449Speter
189462449Speter<PRE>
189562449Speterint set_field_type(FIELD *field,          /* field to alter */
189662449Speter                   TYPE_ALNUM,            /* type to associate */
189762449Speter                   int width);            /* maximum width of field */
189862449Speter</PRE>
189962449Speter
190062449SpeterThe <CODE>width</CODE> argument sets a minimum width of data.  As with
190162449SpeterTYPE_ALPHA, typically you'll want to set this to the field width; if it's
190262449Spetergreater than the field width, the validation check will always fail.  A
190362449Speterminimum width of zero makes field completion optional.
190462449Speter
190562449Speter<H3><A NAME="ftype_enum">TYPE_ENUM</A></H3>
190662449Speter
190762449SpeterThis type allows you to restrict a field's values to be among a specified
190862449Speterset of string values (for example, the two-letter postal codes for U.S.
190962449Speterstates).  It is set up with:
191062449Speter
191162449Speter<PRE>
191262449Speterint set_field_type(FIELD *field,          /* field to alter */
191362449Speter                   TYPE_ENUM,             /* type to associate */
191462449Speter                   char **valuelist;      /* list of possible values */
191562449Speter                   int checkcase;         /* case-sensitive? */
191662449Speter                   int checkunique);      /* must specify uniquely? */
191762449Speter</PRE>
191862449Speter
191962449SpeterThe <CODE>valuelist</CODE> parameter must point at a NULL-terminated list of
192062449Spetervalid strings.  The <CODE>checkcase</CODE> argument, if true, makes comparison
192162449Speterwith the string case-sensitive. <P>
192262449Speter
192362449SpeterWhen the user exits a TYPE_ENUM field, the validation procedure tries to
192462449Spetercomplete the data in the buffer to a valid entry.  If a complete choice string
192562449Speterhas been entered, it is of course valid.  But it is also possible to enter a
192662449Speterprefix of a valid string and have it completed for you. <P>
192762449Speter
192862449SpeterBy default, if you enter such a prefix and it matches more than one value
192962449Speterin the string list, the prefix will be completed to the first matching
193062449Spetervalue.  But the <CODE>checkunique</CODE> argument, if true, requires prefix
193162449Spetermatches to be unique in order to be valid. <P>
193262449Speter
193362449SpeterThe <CODE>REQ_NEXT_CHOICE</CODE> and <CODE>REQ_PREV_CHOICE</CODE> input requests
193462449Spetercan be particularly useful with these fields.
193562449Speter
193662449Speter<H3><A NAME="ftype_integer">TYPE_INTEGER</A></H3>
193762449Speter
193862449SpeterThis field type accepts an integer.  It is set up as follows:
193962449Speter
194062449Speter<PRE>
194162449Speterint set_field_type(FIELD *field,          /* field to alter */
194262449Speter                   TYPE_INTEGER,          /* type to associate */
194362449Speter                   int padding,           /* # places to zero-pad to */
194462449Speter                   int vmin, int vmax);   /* valid range */
194562449Speter</PRE>
194662449Speter
194762449SpeterValid characters consist of an optional leading minus and digits.
194862449SpeterThe range check is performed on exit.  If the range maximum is less
194962449Speterthan or equal to the minimum, the range is ignored. <P>
195062449Speter
195162449SpeterIf the value passes its range check, it is padded with as many leading
195262449Speterzero digits as necessary to meet the padding argument. <P>
195362449Speter
195462449SpeterA <CODE>TYPE_INTEGER</CODE> value buffer can conveniently be interpreted
195562449Speterwith the C library function <CODE>atoi(3)</CODE>.
195662449Speter
195762449Speter<H3><A NAME="ftype_numeric">TYPE_NUMERIC</A></H3>
195862449Speter
195962449SpeterThis field type accepts a decimal number.  It is set up as follows:
196062449Speter
196162449Speter<PRE>
196262449Speterint set_field_type(FIELD *field,              /* field to alter */
196362449Speter                   TYPE_NUMERIC,              /* type to associate */
196462449Speter                   int padding,               /* # places of precision */
196562449Speter                   double vmin, double vmax); /* valid range */
196662449Speter</PRE>
196762449Speter
196862449SpeterValid characters consist of an optional leading minus and digits. possibly
196962449Speterincluding a decimal point. If your system supports locale's, the decimal point
197062449Spetercharacter used must be the one defined by your locale. The range check is
197162449Speterperformed on exit. If the range maximum is less than or equal to the minimum,
197262449Speterthe range is ignored. <P>
197362449Speter
197462449SpeterIf the value passes its range check, it is padded with as many trailing
197562449Speterzero digits as necessary to meet the padding argument. <P>
197662449Speter
197762449SpeterA <CODE>TYPE_NUMERIC</CODE> value buffer can conveniently be interpreted
197862449Speterwith the C library function <CODE>atof(3)</CODE>.
197962449Speter
198062449Speter<H3><A NAME="ftype_regexp">TYPE_REGEXP</A></H3>
198162449Speter
198262449SpeterThis field type accepts data matching a regular expression.  It is set up
198362449Speteras follows:
198462449Speter
198562449Speter<PRE>
198662449Speterint set_field_type(FIELD *field,          /* field to alter */
198762449Speter                   TYPE_REGEXP,           /* type to associate */
198862449Speter                   char *regexp);         /* expression to match */
198962449Speter</PRE>
199062449Speter
199162449SpeterThe syntax for regular expressions is that of <CODE>regcomp(3)</CODE>.
199262449SpeterThe check for regular-expression match is performed on exit.
199362449Speter
199462449Speter<H2><A NAME="fbuffer">Direct Field Buffer Manipulation</A></H2>
199562449Speter
199662449SpeterThe chief attribute of a field is its buffer contents.  When a form has
199762449Speterbeen completed, your application usually needs to know the state of each
199862449Speterfield buffer.  You can find this out with:
199962449Speter
200062449Speter<PRE>
200162449Speterchar *field_buffer(FIELD *field,          /* field to query */
200262449Speter                   int bufindex);         /* number of buffer to query */
200362449Speter</PRE>
200462449Speter
200562449SpeterNormally, the state of the zero-numbered buffer for each field is set by
200662449Speterthe user's editing actions on that field.  It's sometimes useful to be able
200762449Speterto set the value of the zero-numbered (or some other) buffer from your
200862449Speterapplication:
200962449Speter
201062449Speter<PRE>
201162449Speterint set_field_buffer(FIELD *field,        /* field to alter */
201262449Speter                   int bufindex,          /* number of buffer to alter */
201362449Speter                   char *value);          /* string value to set */
201462449Speter</PRE>
201562449Speter
201662449SpeterIf the field is not large enough and cannot be resized to a sufficiently
201762449Speterlarge size to contain the specified value, the value will be truncated
201862449Speterto fit. <P>
201962449Speter
202062449SpeterCalling <CODE>field_buffer()</CODE> with a null field pointer will raise an
202162449Spetererror.  Calling <CODE>field_buffer()</CODE> on a field not currently selected
202262449Speterfor input will return a correct value.  Calling <CODE>field_buffer()</CODE> on a
202362449Speterfield that is currently selected for input may not necessarily give a
202462449Spetercorrect field buffer value, because entered data isn't necessarily copied to
202562449Speterbuffer zero before the exit validation check.
202662449Speter
202762449SpeterTo guarantee that the returned buffer value reflects on-screen reality,
202862449Spetercall <CODE>field_buffer()</CODE> either (1) in the field's exit validation
202962449Spetercheck routine, (2) from the field's or form's initialization or termination
203062449Speterhooks, or (3) just after a <CODE>REQ_VALIDATION</CODE> request has been processed
203162449Speterby the forms driver.
203262449Speter
203362449Speter<H2><A NAME="formattrs">Attributes of Forms</A></H2>
203462449Speter
203562449SpeterAs with field attributes, form attributes inherit a default from a
203662449Spetersystem default form structure.  These defaults can be queried or set by
203762449Speterof these functions using a form-pointer argument of <CODE>NULL</CODE>. <P>
203862449Speter
203962449SpeterThe principal attribute of a form is its field list.  You can query
204062449Speterand change this list with:
204162449Speter
204262449Speter<PRE>
204362449Speterint set_form_fields(FORM *form,           /* form to alter */
204462449Speter                    FIELD **fields);      /* fields to connect */
204562449Speter
204662449Speterchar *form_fields(FORM *form);            /* fetch fields of form */
204762449Speter
204862449Speterint field_count(FORM *form);              /* count connect fields */
204962449Speter</PRE>
205062449Speter
205162449SpeterThe second argument of <CODE>set_form_fields()</CODE> may be a
205262449SpeterNULL-terminated field pointer array like the one required by
205362449Speter<CODE>new_form()</CODE>. In that case, the old fields of the form are
205462449Speterdisconnected but not freed (and eligible to be connected to other
205562449Speterforms), then the new fields are connected. <P>
205662449Speter
205762449SpeterIt may also be null, in which case the old fields are disconnected
205862449Speter(and not freed) but no new ones are connected. <P>
205962449Speter
206062449SpeterThe <CODE>field_count()</CODE> function simply counts the number of fields
206162449Speterconnected to a given from.  It returns -1 if the form-pointer argument
206262449Speteris NULL.
206362449Speter
206462449Speter<H2><A NAME="fdisplay">Control of Form Display</A></H2>
206562449Speter
206662449SpeterIn the overview section, you saw that to display a form you normally
206762449Speterstart by defining its size (and fields), posting it, and refreshing
206862449Speterthe screen.  There is an hidden step before posting, which is the
206962449Speterassociation of the form with a frame window (actually, a pair of
207062449Speterwindows) within which it will be displayed.  By default, the forms
207162449Speterlibrary associates every form with the full-screen window
207262449Speter<CODE>stdscr</CODE>. <P>
207362449Speter
207462449SpeterBy making this step explicit, you can associate a form with a declared
207562449Speterframe window on your screen display.  This can be useful if you want to
207662449Speteradapt the form display to different screen sizes, dynamically tile
207762449Speterforms on the screen, or use a form as part of an interface layout
207862449Spetermanaged by <A HREF="#panels">panels</A>. <P>
207962449Speter
208062449SpeterThe two windows associated with each form have the same functions as
208162449Spetertheir analogues in the <A HREF="#menu">menu library</A>.  Both these
208262449Speterwindows are painted when the form is posted and erased when the form
208362449Speteris unposted. <P>
208462449Speter
208562449SpeterThe outer or frame window is not otherwise touched by the form
208662449Speterroutines.  It exists so the programmer can associate a title, a
208762449Speterborder, or perhaps help text with the form and have it properly
208862449Speterrefreshed or erased at post/unpost time. The inner window or subwindow
208962449Speteris where the current form page is actually displayed. <P>
209062449Speter
209162449SpeterIn order to declare your own frame window for a form, you'll need to
209262449Speterknow the size of the form's bounding rectangle.  You can get this
209362449Speterinformation with:
209462449Speter
209562449Speter<PRE>
209662449Speterint scale_form(FORM *form,                /* form to query */
209762449Speter               int *rows,                 /* form rows */
209862449Speter               int *cols);                /* form cols */
209962449Speter</PRE>
210062449Speter
210162449SpeterThe form dimensions are passed back in the locations pointed to by
210262449Speterthe arguments.  Once you have this information, you can use it to
210362449Speterdeclare of windows, then use one of these functions:
210462449Speter
210562449Speter<PRE>
210662449Speterint set_form_win(FORM *form,              /* form to alter */
210762449Speter                 WINDOW *win);            /* frame window to connect */
210862449Speter
210962449SpeterWINDOW *form_win(FORM *form);             /* fetch frame window of form */
211062449Speter
211162449Speterint set_form_sub(FORM *form,              /* form to alter */
211262449Speter                 WINDOW *win);            /* form subwindow to connect */
211362449Speter
211462449SpeterWINDOW *form_sub(FORM *form);             /* fetch form subwindow of form */
211562449Speter</PRE>
211662449Speter
211762449SpeterNote that curses operations, including <CODE>refresh()</CODE>, on the form,
211862449Spetershould be done on the frame window, not the form subwindow. <P>
211962449Speter
212062449SpeterIt is possible to check from your application whether all of a
212162449Speterscrollable field is actually displayed within the menu subwindow.  Use
212262449Speterthese functions:
212362449Speter
212462449Speter<PRE>
212562449Speterint data_ahead(FORM *form);               /* form to be queried */
212662449Speter
212762449Speterint data_behind(FORM *form);              /* form to be queried */
212862449Speter</PRE>
212962449Speter
213062449SpeterThe function <CODE>data_ahead()</CODE> returns TRUE if (a) the current
213162449Speterfield is one-line and has undisplayed data off to the right, (b) the current
213262449Speterfield is multi-line and there is data off-screen below it. <P>
213362449Speter
213462449SpeterThe function <CODE>data_behind()</CODE> returns TRUE if the first (upper
213562449Speterleft hand) character position is off-screen (not being displayed). <P>
213662449Speter
213762449SpeterFinally, there is a function to restore the form window's cursor to the
213862449Spetervalue expected by the forms driver:
213962449Speter
214062449Speter<PRE>
214162449Speterint pos_form_cursor(FORM *)               /* form to be queried */
214262449Speter</PRE>
214362449Speter
214462449SpeterIf your application changes the form window cursor, call this function before
214562449Speterhanding control back to the forms driver in order to re-synchronize it.
214662449Speter
214762449Speter<H2><A NAME="fdriver">Input Processing in the Forms Driver</A></H2>
214862449Speter
214962449SpeterThe function <CODE>form_driver()</CODE> handles virtualized input requests
215062449Speterfor form navigation, editing, and validation requests, just as
215162449Speter<CODE>menu_driver</CODE> does for menus (see the section on <A
215262449SpeterHREF="#minput">menu input handling</A>).
215362449Speter
215462449Speter<PRE>
215562449Speterint form_driver(FORM *form,               /* form to pass input to */
215662449Speter                int request);             /* form request code */
215762449Speter</PRE>
215862449Speter
215962449SpeterYour input virtualization function needs to take input and then convert it
216062449Speterto either an alphanumeric character (which is treated as data to be
216162449Speterentered in the currently-selected field), or a forms processing request. <P>
216262449Speter
216362449SpeterThe forms driver provides hooks (through input-validation and
216462449Speterfield-termination functions) with which your application code can check
216562449Speterthat the input taken by the driver matched what was expected.
216662449Speter
216762449Speter<H3><A NAME="fpage">Page Navigation Requests</A></H3>
216862449Speter
216962449SpeterThese requests cause page-level moves through the form,
217062449Spetertriggering display of a new form screen.
217162449Speter
217262449Speter<DL>
217362449Speter<DT> <CODE>REQ_NEXT_PAGE</CODE>
217462449Speter<DD> Move to the next form page.
217562449Speter<DT> <CODE>REQ_PREV_PAGE</CODE>
217662449Speter<DD> Move to the previous form page.
217762449Speter<DT> <CODE>REQ_FIRST_PAGE</CODE>
217862449Speter<DD> Move to the first form page.
217962449Speter<DT> <CODE>REQ_LAST_PAGE</CODE>
218062449Speter<DD> Move to the last form page.
218162449Speter</DL>
218262449Speter
218362449SpeterThese requests treat the list as cyclic; that is, <CODE>REQ_NEXT_PAGE</CODE>
218462449Speterfrom the last page goes to the first, and <CODE>REQ_PREV_PAGE</CODE> from
218562449Speterthe first page goes to the last.
218662449Speter
218762449Speter<H3><A NAME="#ffield">Inter-Field Navigation Requests</A></H3>
218862449Speter
218962449SpeterThese requests handle navigation between fields on the same page.
219062449Speter
219162449Speter<DL>
219262449Speter<DT> <CODE>REQ_NEXT_FIELD</CODE>
219362449Speter<DD> Move to next field.
219462449Speter<DT> <CODE>REQ_PREV_FIELD</CODE>
219562449Speter<DD> Move to previous field.
219662449Speter<DT> <CODE>REQ_FIRST_FIELD</CODE>
219762449Speter<DD> Move to the first field.
219862449Speter<DT> <CODE>REQ_LAST_FIELD</CODE>
219962449Speter<DD> Move to the last field.
220062449Speter<DT> <CODE>REQ_SNEXT_FIELD</CODE>
220162449Speter<DD> Move to sorted next field.
220262449Speter<DT> <CODE>REQ_SPREV_FIELD</CODE>
220362449Speter<DD> Move to sorted previous field.
220462449Speter<DT> <CODE>REQ_SFIRST_FIELD</CODE>
220562449Speter<DD> Move to the sorted first field.
220662449Speter<DT> <CODE>REQ_SLAST_FIELD</CODE>
220762449Speter<DD> Move to the sorted last field.
220862449Speter<DT> <CODE>REQ_LEFT_FIELD</CODE>
220962449Speter<DD> Move left to field.
221062449Speter<DT> <CODE>REQ_RIGHT_FIELD</CODE>
221162449Speter<DD> Move right to field.
221262449Speter<DT> <CODE>REQ_UP_FIELD</CODE>
221362449Speter<DD> Move up to field.
221462449Speter<DT> <CODE>REQ_DOWN_FIELD</CODE>
221562449Speter<DD> Move down to field.
221662449Speter</DL>
221762449Speter
221862449SpeterThese requests treat the list of fields on a page as cyclic; that is,
221962449Speter<CODE>REQ_NEXT_FIELD</CODE> from the last field goes to the first, and
222062449Speter<CODE>REQ_PREV_FIELD</CODE> from the first field goes to the last. The
222162449Speterorder of the fields for these (and the <CODE>REQ_FIRST_FIELD</CODE> and
222262449Speter<CODE>REQ_LAST_FIELD</CODE> requests) is simply the order of the field
222362449Speterpointers in the form array (as set up by <CODE>new_form()</CODE> or
222462449Speter<CODE>set_form_fields()</CODE> <P>
222562449Speter
222662449SpeterIt is also possible to traverse the fields as if they had been sorted in
222762449Speterscreen-position order, so the sequence goes left-to-right and top-to-bottom.
222862449SpeterTo do this, use the second group of four sorted-movement requests.  <P>
222962449Speter
223062449SpeterFinally, it is possible to move between fields using visual directions up,
223162449Speterdown, right, and left.  To accomplish this, use the third group of four
223262449Speterrequests.  Note, however, that the position of a form for purposes of these
223362449Speterrequests is its upper-left corner. <P>
223462449Speter
223562449SpeterFor example, suppose you have a multi-line field B, and two
223662449Spetersingle-line fields A and C on the same line with B, with A to the left
223762449Speterof B and C to the right of B.  A <CODE>REQ_MOVE_RIGHT</CODE> from A will
223862449Spetergo to B only if A, B, and C <EM>all</EM> share the same first line;
223962449Speterotherwise it will skip over B to C.
224062449Speter
224162449Speter<H3><A NAME="#fifield">Intra-Field Navigation Requests</A></H3>
224262449Speter
224362449SpeterThese requests drive movement of the edit cursor within the currently
224462449Speterselected field.
224562449Speter
224662449Speter<DL>
224762449Speter<DT> <CODE>REQ_NEXT_CHAR</CODE>
224862449Speter<DD> Move to next character.
224962449Speter<DT> <CODE>REQ_PREV_CHAR</CODE>
225062449Speter<DD> Move to previous character.
225162449Speter<DT> <CODE>REQ_NEXT_LINE</CODE>
225262449Speter<DD> Move to next line.
225362449Speter<DT> <CODE>REQ_PREV_LINE</CODE>
225462449Speter<DD> Move to previous line.
225562449Speter<DT> <CODE>REQ_NEXT_WORD</CODE>
225662449Speter<DD> Move to next word.
225762449Speter<DT> <CODE>REQ_PREV_WORD</CODE>
225862449Speter<DD> Move to previous word.
225962449Speter<DT> <CODE>REQ_BEG_FIELD</CODE>
226062449Speter<DD> Move to beginning of field.
226162449Speter<DT> <CODE>REQ_END_FIELD</CODE>
226262449Speter<DD> Move to end of field.
226362449Speter<DT> <CODE>REQ_BEG_LINE</CODE>
226462449Speter<DD> Move to beginning of line.
226562449Speter<DT> <CODE>REQ_END_LINE</CODE>
226662449Speter<DD> Move to end of line.
226762449Speter<DT> <CODE>REQ_LEFT_CHAR</CODE>
226862449Speter<DD> Move left in field.
226962449Speter<DT> <CODE>REQ_RIGHT_CHAR</CODE>
227062449Speter<DD> Move right in field.
227162449Speter<DT> <CODE>REQ_UP_CHAR</CODE>
227262449Speter<DD> Move up in field.
227362449Speter<DT> <CODE>REQ_DOWN_CHAR</CODE>
227462449Speter<DD> Move down in field.
227562449Speter</DL>
227662449Speter
227762449SpeterEach <EM>word</EM> is separated from the previous and next characters
227862449Speterby whitespace.  The commands to move to beginning and end of line or field
227962449Speterlook for the first or last non-pad character in their ranges.
228062449Speter
228162449Speter<H3><A NAME="fscroll">Scrolling Requests</A></H3>
228262449Speter
228362449SpeterFields that are dynamic and have grown and fields explicitly created
228462449Speterwith offscreen rows are scrollable.  One-line fields scroll horizontally;
228562449Spetermulti-line fields scroll vertically.  Most scrolling is triggered by
228662449Speterediting and intra-field movement (the library scrolls the field to keep the
228762449Spetercursor visible).  It is possible to explicitly request scrolling with the
228862449Speterfollowing requests:
228962449Speter
229062449Speter<DL>
229162449Speter<DT> <CODE>REQ_SCR_FLINE</CODE>
229262449Speter<DD> Scroll vertically forward a line.
229362449Speter<DT> <CODE>REQ_SCR_BLINE</CODE>
229462449Speter<DD> Scroll vertically backward a line.
229562449Speter<DT> <CODE>REQ_SCR_FPAGE</CODE>
229662449Speter<DD> Scroll vertically forward a page.
229762449Speter<DT> <CODE>REQ_SCR_BPAGE</CODE>
229862449Speter<DD> Scroll vertically backward a page.
229962449Speter<DT> <CODE>REQ_SCR_FHPAGE</CODE>
230062449Speter<DD> Scroll vertically forward half a page.
230162449Speter<DT> <CODE>REQ_SCR_BHPAGE</CODE>
230262449Speter<DD> Scroll vertically backward half a page.
230362449Speter<DT> <CODE>REQ_SCR_FCHAR</CODE>
230462449Speter<DD> Scroll horizontally forward a character.
230562449Speter<DT> <CODE>REQ_SCR_BCHAR</CODE>
230662449Speter<DD> Scroll horizontally backward a character.
230762449Speter<DT> <CODE>REQ_SCR_HFLINE</CODE>
230862449Speter<DD> Scroll horizontally one field width forward.
230962449Speter<DT> <CODE>REQ_SCR_HBLINE</CODE>
231062449Speter<DD> Scroll horizontally one field width backward.
231162449Speter<DT> <CODE>REQ_SCR_HFHALF</CODE>
231262449Speter<DD> Scroll horizontally one half field width forward.
231362449Speter<DT> <CODE>REQ_SCR_HBHALF</CODE>
231462449Speter<DD> Scroll horizontally one half field width backward.
231562449Speter</DL>
231662449Speter
231762449SpeterFor scrolling purposes, a <EM>page</EM> of a field is the height
231862449Speterof its visible part.
231962449Speter
232062449Speter<H3><A NAME="fedit">Editing Requests</A></H3>
232162449Speter
232262449SpeterWhen you pass the forms driver an ASCII character, it is treated as a
232362449Speterrequest to add the character to the field's data buffer.  Whether this
232462449Speteris an insertion or a replacement depends on the field's edit mode
232562449Speter(insertion is the default. <P>
232662449Speter
232762449SpeterThe following requests support editing the field and changing the edit
232862449Spetermode:
232962449Speter
233062449Speter<DL>
233162449Speter<DT> <CODE>REQ_INS_MODE</CODE>
233262449Speter<DD> Set insertion mode.
233362449Speter<DT> <CODE>REQ_OVL_MODE</CODE>
233462449Speter<DD> Set overlay mode.
233562449Speter<DT> <CODE>REQ_NEW_LINE</CODE>
233662449Speter<DD> New line request (see below for explanation).
233762449Speter<DT> <CODE>REQ_INS_CHAR</CODE>
233862449Speter<DD> Insert space at character location.
233962449Speter<DT> <CODE>REQ_INS_LINE</CODE>
234062449Speter<DD> Insert blank line at character location.
234162449Speter<DT> <CODE>REQ_DEL_CHAR</CODE>
234262449Speter<DD> Delete character at cursor.
234362449Speter<DT> <CODE>REQ_DEL_PREV</CODE>
234462449Speter<DD> Delete previous word at cursor.
234562449Speter<DT> <CODE>REQ_DEL_LINE</CODE>
234662449Speter<DD> Delete line at cursor.
234762449Speter<DT> <CODE>REQ_DEL_WORD</CODE>
234862449Speter<DD> Delete word at cursor.
234962449Speter<DT> <CODE>REQ_CLR_EOL</CODE>
235062449Speter<DD> Clear to end of line.
235162449Speter<DT> <CODE>REQ_CLR_EOF</CODE>
235262449Speter<DD> Clear to end of field.
235362449Speter<DT> <CODE>REQ_CLEAR_FIELD</CODE>
235462449Speter<DD> Clear entire field.
235562449Speter</DL>
235662449Speter
235762449SpeterThe behavior of the <CODE>REQ_NEW_LINE</CODE> and <CODE>REQ_DEL_PREV</CODE> requests
235862449Speteris complicated and partly controlled by a pair of forms options.
235962449SpeterThe special cases are triggered when the cursor is at the beginning of
236062449Spetera field, or on the last line of the field. <P>
236162449Speter
236262449SpeterFirst, we consider <CODE>REQ_NEW_LINE</CODE>: <P>
236362449Speter
236462449SpeterThe normal behavior of <CODE>REQ_NEW_LINE</CODE> in insert mode is to break the
236562449Spetercurrent line at the position of the edit cursor, inserting the portion of
236662449Speterthe current line after the cursor as a new line following the current
236762449Speterand moving the cursor to the beginning of that new line (you may think
236862449Speterof this as inserting a newline in the field buffer). <P>
236962449Speter
237062449SpeterThe normal behavior of <CODE>REQ_NEW_LINE</CODE> in overlay mode is to clear the
237162449Spetercurrent line from the position of the edit cursor to end of line.
237262449SpeterThe cursor is then moved to the beginning of the next line. <P>
237362449Speter
237462449SpeterHowever, <CODE>REQ_NEW_LINE</CODE> at the beginning of a field, or on the
237562449Speterlast line of a field, instead does a <CODE>REQ_NEXT_FIELD</CODE>.
237662449Speter<CODE>O_NL_OVERLOAD</CODE> option is off, this special action is
237762449Speterdisabled. <P>
237862449Speter
237962449SpeterNow, let us consider <CODE>REQ_DEL_PREV</CODE>: <P>
238062449Speter
238162449SpeterThe normal behavior of <CODE>REQ_DEL_PREV</CODE> is to delete the previous
238262449Spetercharacter.  If insert mode is on, and the cursor is at the start of a
238362449Speterline, and the text on that line will fit on the previous one, it
238462449Speterinstead appends the contents of the current line to the previous one
238562449Speterand deletes the current line (you may think of this as deleting a
238662449Speternewline from the field buffer). <P>
238762449Speter
238862449SpeterHowever, <CODE>REQ_DEL_PREV</CODE> at the beginning of a field is instead
238962449Spetertreated as a <CODE>REQ_PREV_FIELD</CODE>. <P> If the
239062449Speter<CODE>O_BS_OVERLOAD</CODE> option is off, this special action is
239162449Speterdisabled and the forms driver just returns <CODE>E_REQUEST_DENIED</CODE>. <P>
239262449Speter
239362449SpeterSee <A HREF="#frmoptions">Form Options</A> for discussion of how to set
239462449Speterand clear the overload options.
239562449Speter
239662449Speter<H3><A NAME="forder">Order Requests</A></H3>
239762449Speter
239862449SpeterIf the type of your field is ordered, and has associated functions
239962449Speterfor getting the next and previous values of the type from a given value,
240062449Speterthere are requests that can fetch that value into the field buffer:
240162449Speter
240262449Speter<DL>
240362449Speter<DT> <CODE>REQ_NEXT_CHOICE</CODE>
240462449Speter<DD> Place the successor value of the current value in the buffer.
240562449Speter<DT> <CODE>REQ_PREV_CHOICE</CODE>
240662449Speter<DD> Place the predecessor value of the current value in the buffer.
240762449Speter</DL>
240862449Speter
240962449SpeterOf the built-in field types, only <CODE>TYPE_ENUM</CODE> has built-in successor
241062449Speterand predecessor functions.  When you define a field type of your own
241162449Speter(see <A HREF="#fcustom">Custom Validation Types</A>), you can associate
241262449Speterour own ordering functions.
241362449Speter
241462449Speter<H3><A NAME="fappcmds">Application Commands</A></H3>
241562449Speter
241662449SpeterForm requests are represented as integers above the <CODE>curses</CODE> value
241762449Spetergreater than <CODE>KEY_MAX</CODE> and less than or equal to the constant
241862449Speter<CODE>MAX_COMMAND</CODE>.  If your input-virtualization routine returns a
241962449Spetervalue above <CODE>MAX_COMMAND</CODE>, the forms driver will ignore it.
242062449Speter
242162449Speter<H2><A NAME="fhooks">Field Change Hooks</A></H2>
242262449Speter
242362449SpeterIt is possible to set function hooks to be executed whenever the
242462449Spetercurrent field or form changes.  Here are the functions that support this:
242562449Speter
242662449Speter<PRE>
242762449Spetertypedef void	(*HOOK)();       /* pointer to function returning void */
242862449Speter
242962449Speterint set_form_init(FORM *form,    /* form to alter */
243062449Speter                  HOOK hook);    /* initialization hook */
243162449Speter
243262449SpeterHOOK form_init(FORM *form);      /* form to query */
243362449Speter
243462449Speterint set_form_term(FORM *form,    /* form to alter */
243562449Speter                  HOOK hook);    /* termination hook */
243662449Speter
243762449SpeterHOOK form_term(FORM *form);      /* form to query */
243862449Speter
243962449Speterint set_field_init(FORM *form,   /* form to alter */
244062449Speter                  HOOK hook);    /* initialization hook */
244162449Speter
244262449SpeterHOOK field_init(FORM *form);     /* form to query */
244362449Speter
244462449Speterint set_field_term(FORM *form,   /* form to alter */
244562449Speter                  HOOK hook);    /* termination hook */
244662449Speter
244762449SpeterHOOK field_term(FORM *form);     /* form to query */
244862449Speter</PRE>
244962449Speter
245062449SpeterThese functions allow you to either set or query four different hooks.
245162449SpeterIn each of the set functions, the second argument should be the
245262449Speteraddress of a hook function.  These functions differ only in the timing
245362449Speterof the hook call.
245462449Speter
245562449Speter<DL>
245662449Speter<DT> form_init
245762449Speter<DD> This hook is called when the form is posted; also, just after
245862449Spetereach page change operation.
245962449Speter<DT> field_init
246062449Speter<DD> This hook is called when the form is posted; also, just after
246162449Spetereach field change
246262449Speter<DT> field_term
246362449Speter<DD> This hook is called just after field validation; that is, just before
246462449Speterthe field is altered.  It is also called when the form is unposted.
246562449Speter<DT> form_term
246662449Speter<DD> This hook is called when the form is unposted; also, just before
246762449Spetereach page change operation.
246862449Speter</DL>
246962449Speter
247062449SpeterCalls to these hooks may be triggered
247162449Speter<OL>
247262449Speter<LI>When user editing requests are processed by the forms driver
247362449Speter<LI>When the current page is changed by <CODE>set_current_field()</CODE> call
247462449Speter<LI>When the current field is changed by a <CODE>set_form_page()</CODE> call
247562449Speter</OL>
247662449Speter
247762449SpeterSee <A NAME="ffocus">Field Change Commands</A> for discussion of the latter
247862449Spetertwo cases. <P>
247962449Speter
248062449SpeterYou can set a default hook for all fields by passing one of the set functions
248162449Spetera NULL first argument. <P>
248262449Speter
248362449SpeterYou can disable any of these hooks by (re)setting them to NULL, the default
248462449Spetervalue.
248562449Speter
248662449Speter<H2><A HREF="#ffocus">Field Change Commands</A></H2>
248762449Speter
248862449SpeterNormally, navigation through the form will be driven by the user's
248962449Speterinput requests.  But sometimes it is useful to be able to move the
249062449Speterfocus for editing and viewing under control of your application, or
249162449Speterask which field it currently is in.  The following functions help you
249262449Speteraccomplish this:
249362449Speter
249462449Speter<PRE>
249562449Speterint set_current_field(FORM *form,         /* form to alter */
249662449Speter                      FIELD *field);      /* field to shift to */
249762449Speter
249862449SpeterFIELD *current_field(FORM *form);         /* form to query */
249962449Speter
250062449Speterint field_index(FORM *form,               /* form to query */
250162449Speter                FIELD *field);            /* field to get index of */
250262449Speter</PRE>
250362449Speter
250462449SpeterThe function <CODE>field_index()</CODE> returns the index of the given field
250562449Speterin the given form's field array (the array passed to <CODE>new_form()</CODE> or
250662449Speter<CODE>set_form_fields()</CODE>). <P>
250762449Speter
250862449SpeterThe initial current field of a form is the first active field on the
250962449Speterfirst page. The function <CODE>set_form_fields()</CODE> resets this.<P>
251062449Speter
251162449SpeterIt is also possible to move around by pages.
251262449Speter
251362449Speter<PRE>
251462449Speterint set_form_page(FORM *form,             /* form to alter */
251562449Speter                  int page);              /* page to go to (0-origin) */
251662449Speter
251762449Speterint form_page(FORM *form);                /* return form's current page */
251862449Speter</PRE>
251962449Speter
252062449SpeterThe initial page of a newly-created form is 0.  The function
252162449Speter<CODE>set_form_fields()</CODE> resets this.
252262449Speter
252362449Speter<H2><A NAME="frmoptions">Form Options</A></H2>
252462449Speter
252562449SpeterLike fields, forms may have control option bits.  They can be changed
252662449Speteror queried with these functions:
252762449Speter
252862449Speter<PRE>
252962449Speterint set_form_opts(FORM *form,             /* form to alter */
253062449Speter                  int attr);              /* attribute to set */
253162449Speter
253262449Speterint form_opts_on(FORM *form,              /* form to alter */
253362449Speter                 int attr);               /* attributes to turn on */
253462449Speter
253562449Speterint form_opts_off(FORM *form,             /* form to alter */
253662449Speter                  int attr);              /* attributes to turn off */
253762449Speter
253862449Speterint form_opts(FORM *form);                /* form to query */
253962449Speter</PRE>
254062449Speter
254162449SpeterBy default, all options are on.  Here are the available option bits:
254262449Speter
254362449Speter<DL>
254462449Speter<DT> O_NL_OVERLOAD
254562449Speter<DD> Enable overloading of <CODE>REQ_NEW_LINE</CODE> as described in <A
2546166124Srafanhref="#fedit">Editing Requests</A>.  The value of this option is
254762449Speterignored on dynamic fields that have not reached their size limit;
254862449Speterthese have no last line, so the circumstances for triggering a
254962449Speter<CODE>REQ_NEXT_FIELD</CODE> never arise.
255062449Speter<DT> O_BS_OVERLOAD
255162449Speter<DD> Enable overloading of <CODE>REQ_DEL_PREV</CODE> as described in
2552166124Srafan<A href="#fedit">Editing Requests</A>.
255362449Speter</DL>
255462449Speter
255562449SpeterThe option values are bit-masks and can be composed with logical-or in
255662449Speterthe obvious way.
255762449Speter
255862449Speter<H2><A NAME="fcustom">Custom Validation Types</A></H2>
255962449Speter
256062449SpeterThe <CODE>form</CODE> library gives you the capability to define custom
256162449Spetervalidation types of your own.  Further, the optional additional arguments
256262449Speterof <CODE>set_field_type</CODE> effectively allow you to parameterize validation
256362449Spetertypes.  Most of the complications in the validation-type interface have to
256462449Speterdo with the handling of the additional arguments within custom validation
256562449Speterfunctions.
256662449Speter
256762449Speter<H3><A NAME="flinktypes">Union Types</A></H3>
256862449Speter
256962449SpeterThe simplest way to create a custom data type is to compose it from two
257062449Speterpreexisting ones:
257162449Speter
257262449Speter<PRE>
257362449SpeterFIELD *link_fieldtype(FIELDTYPE *type1,
257462449Speter                      FIELDTYPE *type2);
257562449Speter</PRE>
257662449Speter
257762449SpeterThis function creates a field type that will accept any of the values
257862449Speterlegal for either of its argument field types (which may be either
257962449Speterpredefined or programmer-defined).
258062449Speter
258162449SpeterIf a <CODE>set_field_type()</CODE> call later requires arguments, the new
258262449Spetercomposite type expects all arguments for the first type, than all arguments
258362449Speterfor the second.  Order functions (see <A HREF="#forder">Order Requests</A>)
258462449Speterassociated with the component types will work on the composite; what it does
258562449Speteris check the validation function for the first type, then for the second, to
258662449Speterfigure what type the buffer contents should be treated as.
258762449Speter
258862449Speter<H3><A NAME="fnewtypes">New Field Types</A></H3>
258962449Speter
259062449SpeterTo create a field type from scratch, you need to specify one or both of the
259162449Speterfollowing things:
259262449Speter
259362449Speter<UL>
259462449Speter<LI>A character-validation function, to check each character as it is entered.
259562449Speter<LI>A field-validation function to be applied on exit from the field.
259662449Speter</UL>
259762449Speter
259862449SpeterHere's how you do that:
259962449Speter<PRE>
260062449Spetertypedef int	(*HOOK)();       /* pointer to function returning int */
260162449Speter
260262449SpeterFIELDTYPE *new_fieldtype(HOOK f_validate, /* field validator */
260362449Speter                         HOOK c_validate) /* character validator */
260462449Speter
260562449Speter
260662449Speterint free_fieldtype(FIELDTYPE *ftype);     /* type to free */
260762449Speter</PRE>
260862449Speter
260962449SpeterAt least one of the arguments of <CODE>new_fieldtype()</CODE> must be
261062449Speternon-NULL.  The forms driver will automatically call the new type's
261162449Spetervalidation functions at appropriate points in processing a field of
261262449Speterthe new type. <P>
261362449Speter
261462449SpeterThe function <CODE>free_fieldtype()</CODE> deallocates the argument
261562449Speterfieldtype, freeing all storage associated with it. <P>
261662449Speter
261762449SpeterNormally, a field validator is called when the user attempts to
261862449Speterleave the field.  Its first argument is a field pointer, from which it
261962449Spetercan get to field buffer 0 and test it.  If the function returns TRUE,
262062449Speterthe operation succeeds; if it returns FALSE, the edit cursor stays in
262162449Speterthe field. <P>
262262449Speter
262362449SpeterA character validator gets the character passed in as a first argument.
262462449SpeterIt too should return TRUE if the character is valid, FALSE otherwise.
262562449Speter
262662449Speter<H3><A NAME="fcheckargs">Validation Function Arguments</A></H3>
262762449Speter
262862449SpeterYour field- and character- validation functions will be passed a
262962449Spetersecond argument as well.  This second argument is the address of a
263062449Speterstructure (which we'll call a <EM>pile</EM>) built from any of the
263162449Speterfield-type-specific arguments passed to <CODE>set_field_type()</CODE>.  If
263262449Speterno such arguments are defined for the field type, this pile pointer
263362449Speterargument will be NULL. <P>
263462449Speter
263562449SpeterIn order to arrange for such arguments to be passed to your validation
263662449Speterfunctions, you must associate a small set of storage-management functions
263762449Speterwith the type.  The forms driver will use these to synthesize a pile
263862449Speterfrom the trailing arguments of each <CODE>set_field_type()</CODE> argument, and
263962449Spetera pointer to the pile will be passed to the validation functions. <P>
264062449Speter
264162449SpeterHere is how you make the association:
264262449Speter
264362449Speter<PRE>
264462449Spetertypedef char	*(*PTRHOOK)();    /* pointer to function returning (char *) */
264562449Spetertypedef void	(*VOIDHOOK)();    /* pointer to function returning void */
264662449Speter
264762449Speterint set_fieldtype_arg(FIELDTYPE *type,    /* type to alter */
264862449Speter                      PTRHOOK make_str,   /* make structure from args */
264962449Speter                      PTRHOOK copy_str,   /* make copy of structure */
265062449Speter                      VOIDHOOK free_str); /* free structure storage */
265162449Speter</PRE>
265262449Speter
265362449SpeterHere is how the storage-management hooks are used:
265462449Speter
265562449Speter<DL>
265662449Speter<DT> <CODE>make_str</CODE>
265762449Speter<DD> This function is called by <CODE>set_field_type()</CODE>.  It gets one
265862449Speterargument, a <CODE>va_list</CODE> of the type-specific arguments passed to
265962449Speter<CODE>set_field_type()</CODE>.  It is expected to return a pile pointer to a data
266062449Speterstructure that encapsulates those arguments.
266162449Speter<DT> <CODE>copy_str</CODE>
266262449Speter<DD> This function is called by form library functions that allocate new
266362449Speterfield instances.  It is expected to take a pile pointer, copy the pile
266462449Speterto allocated storage, and return the address of the pile copy.
266562449Speter<DT> <CODE>free_str</CODE>
266662449Speter<DD> This function is called by field- and type-deallocation routines in the
266762449Speterlibrary.  It takes a pile pointer argument, and is expected to free the
266862449Speterstorage of that pile.
266962449Speter</DL>
267062449Speter
267162449SpeterThe <CODE>make_str</CODE> and <CODE>copy_str</CODE> functions may return NULL to
267262449Spetersignal allocation failure.  The library routines will that call them will
267362449Speterreturn error indication when this happens.  Thus, your validation functions
267462449Spetershould never see a NULL file pointer and need not check specially for it.
267562449Speter
267662449Speter<H3><A NAME="fcustorder">Order Functions For Custom Types</A></H3>
267762449Speter
267862449SpeterSome custom field types are simply ordered in the same well-defined way
267962449Speterthat <CODE>TYPE_ENUM</CODE> is.  For such types, it is possible to define
268062449Spetersuccessor and predecessor functions to support the <CODE>REQ_NEXT_CHOICE</CODE>
268162449Speterand <CODE>REQ_PREV_CHOICE</CODE> requests. Here's how:
268262449Speter
268362449Speter<PRE>
268462449Spetertypedef int	(*INTHOOK)();     /* pointer to function returning int */
268562449Speter
268662449Speterint set_fieldtype_arg(FIELDTYPE *type,    /* type to alter */
268762449Speter                      INTHOOK succ,       /* get successor value */
268862449Speter                      INTHOOK pred);      /* get predecessor value */
268962449Speter</PRE>
269062449Speter
269162449SpeterThe successor and predecessor arguments will each be passed two arguments;
269262449Spetera field pointer, and a pile pointer (as for the validation functions).  They
269362449Speterare expected to use the function <CODE>field_buffer()</CODE> to read the
269462449Spetercurrent value, and <CODE>set_field_buffer()</CODE> on buffer 0 to set the next
269562449Speteror previous value.  Either hook may return TRUE to indicate success (a
269662449Speterlegal next or previous value was set) or FALSE to indicate failure.
269762449Speter
269862449Speter<H3><A NAME="fcustprobs">Avoiding Problems</A></H3>
269962449Speter
270062449SpeterThe interface for defining custom types is complicated and tricky.
270162449SpeterRather than attempting to create a custom type entirely from scratch,
270262449Speteryou should start by studying the library source code for whichever of
270362449Speterthe pre-defined types seems to be closest to what you want. <P>
270462449Speter
270562449SpeterUse that code as a model, and evolve it towards what you really want.
270662449SpeterYou will avoid many problems and annoyances that way.  The code
270762449Speterin the <CODE>ncurses</CODE> library has been specifically exempted from
270862449Speterthe package copyright to support this. <P>
270962449Speter
271062449SpeterIf your custom type defines order functions, have do something intuitive
271162449Speterwith a blank field.  A useful convention is to make the successor of a
271262449Speterblank field the types minimum value, and its predecessor the maximum.
271362449Speter</BODY>
271462449Speter</HTML>
2715