X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=doc%2Fhtml%2Fncurses-intro.html;fp=misc%2Fncurses-intro.html;h=05c756e0e8b4474eb84fb8309af8c22868166e8f;hp=d01c65e6e52d6d88268f770ebdf4fe079bca9b1a;hb=b1f61d9f3aa244512045a6b02e759825d7049d34;hpb=0eb88fc5281804773e2a0c7a488a4452463535ce diff --git a/misc/ncurses-intro.html b/doc/html/ncurses-intro.html similarity index 96% rename from misc/ncurses-intro.html rename to doc/html/ncurses-intro.html index d01c65e6..05c756e0 100644 --- a/misc/ncurses-intro.html +++ b/doc/html/ncurses-intro.html @@ -1,6 +1,6 @@ @@ -169,7 +169,7 @@ API has the advantage of (a) back-portability to character-cell terminals, and (b) simplicity. For an application that does not require bit-mapped graphics and multiple fonts, an interface implementation using curses will typically be a great deal simpler and less expensive than one using an -X toolkit.

+X toolkit.

A Brief History of Curses

@@ -186,19 +186,19 @@ extensions. Parameterized capabilities strings were introduced, making it possible to describe multiple video attributes, and colors and to handle far more unusual terminals than possible with termcap. In the later AT&T System V releases, curses evolved to use more facilities and offer -more capabilities, going far beyond BSD curses in power and flexibility.

+more capabilities, going far beyond BSD curses in power and flexibility.

Scope of This Document

This document describes ncurses, a free implementation of the System V curses API with some clearly marked extensions. -It includes the following System V curses features:

+It includes the following System V curses features:

@@ -225,7 +225,7 @@ and wrote most of this introduction. wrote all of the menu and forms code as well as the Ada95 binding. Ongoing work is being done by -Thomas Dickey +Thomas Dickey and Jürgen Pfeifer. Florian La Roche @@ -244,7 +244,7 @@ their visibility in the natural way (handling window overlaps).

Finally, this document describes in detail the menus and forms extension libraries, also cloned from System V, which support easy construction and sequences of menus and fill-in -forms.

+forms.

Terminology

@@ -257,12 +257,12 @@ consistency:
A data structure describing a sub-rectangle of the screen (possibly the entire screen). You can write to a window as though it were a miniature -screen, scrolling independently of other windows on the physical screen.

+screen, scrolling independently of other windows on the physical screen.

screens
A subset of windows which are as large as the terminal screen, i.e., they start at the upper left hand corner and encompass the lower right hand corner. One -of these, stdscr, is automatically provided for the programmer.

+of these, stdscr, is automatically provided for the programmer.

terminal screen
The package's idea of what the terminal display currently looks like, i.e., @@ -316,7 +316,7 @@ A given physical screen section may be within the scope of any number of overlapping windows. Also, changes can be made to windows in any order, without regard to motion efficiency. Then, at will, the programmer can effectively say ``make it look like this,'' and let the package implementation -determine the most efficient way to repaint the screen.

+determine the most efficient way to repaint the screen.

Standard Windows and Function Naming Conventions

@@ -368,7 +368,7 @@ can be replaced by Note that the window description pointer (win) comes before the added (y, x) coordinates. If a function requires a window pointer, it is always the first -parameter passed.

+parameter passed.

Variables

@@ -405,7 +405,7 @@ updating, reading, etc. is applied to stdscr. These instructions w work on any window, providing you change the function names and parameters as mentioned above.

-Here is a sample program to motivate the discussion:

+Here is a sample program to motivate the discussion:

 #include <curses.h>
@@ -413,8 +413,11 @@ Here is a sample program to motivate the discussion: 

static void finish(int sig); +int main(int argc, char *argv[]) { + int num = 0; + /* initialize your non-curses data structures here */ (void) signal(SIGINT, finish); /* arrange interrupts to terminate */ @@ -423,28 +426,32 @@ main(int argc, char *argv[]) keypad(stdscr, TRUE); /* enable keyboard mapping */ (void) nonl(); /* tell curses not to do NL->CR/NL on output */ (void) cbreak(); /* take input chars one at a time, no wait for \n */ - (void) noecho(); /* don't echo input */ + (void) echo(); /* echo input - in color */ if (has_colors()) { start_color(); /* - * Simple color assignment, often all we need. + * Simple color assignment, often all we need. Color pair 0 cannot + * be redefined. This example uses the same value for the color + * pair as for the foreground color, though of course that is not + * necessary: */ - init_pair(COLOR_BLACK, COLOR_BLACK, COLOR_BLACK); - init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK); - init_pair(COLOR_RED, COLOR_RED, COLOR_BLACK); - init_pair(COLOR_CYAN, COLOR_CYAN, COLOR_BLACK); - init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK); - init_pair(COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK); - init_pair(COLOR_BLUE, COLOR_BLUE, COLOR_BLACK); - init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK); + init_pair(1, COLOR_RED, COLOR_BLACK); + init_pair(2, COLOR_GREEN, COLOR_BLACK); + init_pair(3, COLOR_YELLOW, COLOR_BLACK); + init_pair(4, COLOR_BLUE, COLOR_BLACK); + init_pair(5, COLOR_CYAN, COLOR_BLACK); + init_pair(6, COLOR_MAGENTA, COLOR_BLACK); + init_pair(7, COLOR_WHITE, COLOR_BLACK); } for (;;) { int c = getch(); /* refresh, accept single keystroke of input */ + attrset(COLOR_PAIR(num % 8)); + num++; /* process the command keystroke */ } @@ -487,7 +494,7 @@ coordinates after updating it.

You can create new windows of your own using the functions newwin(), derwin(), and subwin(). The routine delwin() will allow you to get rid of old windows. All the options described above can be -applied to any window.

+applied to any window.

Output

@@ -515,7 +522,7 @@ to make it look like the entire window has been changed, thus making If you call wrefresh() with curscr as its argument, it will make the screen look like curscr thinks it looks like. This is useful for implementing a command which would redraw the screen in case it get messed -up.

+up.

Input

@@ -539,7 +546,7 @@ watches the input stream for character sequences that correspond to arrow and function keys. These sequences are returned as pseudo-character values. The #define values returned are listed in the curses.h The mapping from sequences to #define values is determined by -key_ capabilities in the terminal's terminfo entry.

+key_ capabilities in the terminal's terminfo entry.

Using Forms Characters

@@ -552,7 +559,7 @@ the prefix ACS_).

The most useful of the ACS defines are the forms-drawing characters. You can use these to draw boxes and simple graphs on the screen. If the terminal does not have such characters, curses.h will map them to a -recognizable (though ugly) set of ASCII defaults.

+recognizable (though ugly) set of ASCII defaults.

Character Attributes and Color

@@ -584,7 +591,7 @@ have been used as the first arguments of the init_pair() values.

init_pair() that creates color-pair N, you can use COLOR_PAIR(N) as a highlight that invokes that particular color combination. Note that COLOR_PAIR(N), for constant N, -is itself a compile-time constant and can be used in initializers.

+is itself a compile-time constant and can be used in initializers.

Mouse Interfacing

@@ -657,7 +664,7 @@ would normally accept from the keyboard. Two of the test games in the code that illustrates how this can be done.

See the manual page curs_mouse(3X) for full details of the -mouse-interface functions.

+mouse-interface functions.

Finishing Up

@@ -665,7 +672,7 @@ In order to clean up after the ncurses routines, the routine endwin() is provided. It restores tty modes to what they were when initscr() was first called, and moves the cursor down to the lower-left corner. Thus, anytime after the call to initscr, endwin() -should be called before exiting.

+should be called before exiting.

Function Descriptions

@@ -684,14 +691,14 @@ occurs a message is written to standard error and the program exits. Otherwise it returns a pointer to stdscr. A few functions may be called before initscr (slk_init(), filter(), ripofflines(), use_env(), and, if you are using multiple -terminals, newterm().)

+terminals, newterm().)

endwin()
Your program should always call endwin() before exiting or shelling out of the program. This function will restore tty modes, move the cursor to the lower left corner of the screen, reset the terminal into the proper non-visual mode. Calling refresh() or doupdate() after a temporary escape from the program will -restore the ncurses screen from before the escape.

+restore the ncurses screen from before the escape.

newterm(type, ofp, ifp)
A program which outputs to more than one terminal should use newterm() instead of initscr(). newterm() should @@ -701,12 +708,12 @@ terminal. The arguments are the type of the terminal (a string) and FILE pointers for the output and input of the terminal. If type is NULL then the environment variable $TERM is used. endwin() should called once at wrapup time for each terminal -opened using this function.

+opened using this function.

set_term(new)
This function is used to switch to a different terminal previously opened by newterm(). The screen reference for the new terminal is passed as the parameter. The previous terminal is returned by the -function. All other calls affect only the current terminal.

+function. All other calls affect only the current terminal.

delscreen(sp)
The inverse of newterm(); deallocates the data structures associated with a given SCREEN reference. @@ -723,7 +730,7 @@ terminal screen, taking into account what is already there in order to do optimizations. refresh() does a refresh of stdscr(). Unless leaveok() has been enabled, the physical cursor of the terminal is left at the -location of the window's cursor.

+location of the window's cursor.

doupdate() and wnoutrefresh(win)
These two functions allow multiple updates with more efficiency than wrefresh. To use them, it is important to understand how curses @@ -805,13 +812,13 @@ data dumped in them. There is a script called tracemunch included with the ncurses distribution that can alleviate this problem somewhat; it compacts long sequences of similar operations into more succinct single-line pseudo-operations. These pseudo-ops can be -distinguished by the fact that they are named in capital letters.

+distinguished by the fact that they are named in capital letters.

Hints, Tips, and Tricks

The ncurses manual pages are a complete reference for this library. In the remainder of this document, we discuss various useful methods that -may not be obvious from the manual page descriptions.

+may not be obvious from the manual page descriptions.

Some Notes of Caution

@@ -846,7 +853,7 @@ overlapping-windows facilities.

Try to avoid using the global variables LINES and COLS. Use getmaxyx() on the stdscr context instead. Reason: your code may be ported to run in an environment with window resizes, -in which case several screens could be open with different sizes.

+in which case several screens could be open with different sizes.

Temporarily Leaving NCURSES Mode

@@ -912,7 +919,7 @@ For each call, you will have to specify a terminal type and a pair of file pointers; each call will return a screen reference, and stdscr will be set to the last one allocated. You will switch between screens with the set_term call. Note that you will also have to call -def_shell_mode and def_prog_mode on each tty yourself.

+def_shell_mode and def_prog_mode on each tty yourself.

Testing for Terminal Capabilities

@@ -927,14 +934,14 @@ test whether a given terminal type should be treated as `smart' (cursor-addressable) or `stupid'. The right way to test this is to see if the return value of tigetstr("cup") is non-NULL. Alternatively, you can include the term.h file and test the value of the -macro cursor_address.

+macro cursor_address.

Tuning for Speed

Use the addchstr() family of functions for fast screen-painting of text when you know the text doesn't contain any control characters. Try to make attribute changes infrequent on your -screens. Don't use the immedok() option!

+screens. Don't use the immedok() option!

Special Features of NCURSES

@@ -1012,7 +1019,7 @@ when you want a screen update, you do update_panels(), it will do all the necessary wnoutrfresh() calls for whatever panel stacking order you have defined. Then you can do one doupdate() and there will be a single burst of physical I/O that will do -all your updates.

+all your updates.

Background Erase

@@ -1027,7 +1034,7 @@ is normal unless and until it is modified by the functions bkgdset()wbkgdset().

This change in behavior conforms ncurses to System V Release 4 and -the XSI Curses standard.

+the XSI Curses standard.

XSI Curses Conformance

@@ -1042,7 +1049,7 @@ One effect of XSI conformance is the change in behavior described under Also, ncurses meets the XSI requirement that every macro entry point have a corresponding function which may be linked (and will be prototype-checked) if the macro definition is disabled with -#undef.

+#undef.

The Panels Library

@@ -1119,7 +1126,7 @@ Typically, you will want to call update_panels() and doupdate() just before accepting command input, once in each cycle of interaction with the user. If you call update_panels() after each and every panel write, you'll generate a lot of unnecessary refresh -activity and screen flicker.

+activity and screen flicker.

Panels, Input, and the Standard Screen

@@ -1137,7 +1144,7 @@ Therefore, before requesting input from a panel window, you need to be sure that the panel is totally unobscured.

There is presently no way to display changes to one obscured panel without -repainting all panels.

+repainting all panels.

Hiding Panels

@@ -1148,7 +1155,7 @@ tests whether or not a panel is hidden.

The panel_update code ignores hidden panels. You cannot do top_panel() or bottom_panel on a hidden panel(). -Other panels operations are applicable.

+Other panels operations are applicable.

Miscellaneous Other Facilities

@@ -1160,7 +1167,7 @@ pointer, they return the panel above or below that panel. Handed Every panel has an associated user pointer, not used by the panel code, to which you can attach application data. See the man page documentation of set_panel_userptr() and panel_userptr for -details.

+details.

The Menu Library

@@ -1171,7 +1178,7 @@ uniform but flexible interface.

The menu library first appeared in AT&T System V. The version documented here is the menu code distributed -with ncurses.

+with ncurses.

Compiling With the menu Library

@@ -1235,12 +1242,12 @@ predicate function. Your menu-processing code can use the function Menu items can be made unselectable using set_item_opts() or item_opts_off() with the O_SELECTABLE argument. This is the only option so far defined for menus, but it -is good practice to code as though other option bits might be on.

+is good practice to code as though other option bits might be on.

Menu Display

The menu library calculates a minimum display size for your window, based -on the following variables:

+on the following variables:

  • The number and maximum length of the menu items @@ -1280,7 +1287,7 @@ There are other menu display attributes including a select attribute, an attribute for selectable items, an attribute for unselectable items, and a pad character used to separate item name text from description text. These have reasonable defaults which the library allows you to -change (see the menu_attribs(3x) manual page.

    +change (see the menu_attribs(3x) manual page.

    Menu Windows

    @@ -1300,7 +1307,7 @@ functions in menu_win(3x).

    When you call menu_post(), you write the menu to its subwindow. When you call menu_unpost(), you erase the subwindow, However, neither of these actually modifies the screen. To -do that, call wrefresh() or some equivalent.

    +do that, call wrefresh() or some equivalent.

    Processing Menu Input

    @@ -1372,7 +1379,7 @@ wrapup time, and whenever the selected item changes. See Each item, and each menu, has an associated user pointer on which you can hang application data. See mitem_userptr(3x) and -menu_userptr(3x).

    +menu_userptr(3x).

    The Forms Library

    @@ -1381,7 +1388,7 @@ programming of on-screen forms for data entry and program control.

    The form library first appeared in AT&T System V. The version documented here is the form code distributed -with ncurses.

    +with ncurses.

    Compiling With the form Library

    @@ -1395,7 +1402,7 @@ and must be linked explicitly with the forms library using an -lform argument. Note that they must also link the ncurses library with -lncurses. Many linkers are two-pass and will accept either order, but it is still good practice -to put -lform first and -lncurses second.

    +to put -lform first and -lncurses second.

    Overview of Forms

    @@ -1446,11 +1453,11 @@ wherever possible.

    In forms programs, however, the `process user requests' is somewhat more complicated than for menus. Besides menu-like navigation operations, -the menu driver loop has to support field editing and data validation.

    +the menu driver loop has to support field editing and data validation.

    Creating and Freeing Fields and Forms

    -The basic function for creating fields is new_field():

    +The basic function for creating fields is new_field():

     FIELD *new_field(int height, int width,   /* new field size */
    @@ -1482,7 +1489,7 @@ The forms library allocates one working buffer per field; the size of
     each buffer is ((height + offscreen)*width + 1, one character
     for each position in the field plus a NUL terminator.  The sixth
     argument is the number of additional data buffers to allocate for the
    -field; your application can use them for its own purposes. 

    +field; your application can use them for its own purposes.

     FIELD *dup_field(FIELD *field,            /* field to copy */
    @@ -1492,7 +1499,7 @@ FIELD *dup_field(FIELD *field,            /* field to copy */
     The function dup_field() duplicates an existing field at a
     new location.  Size and buffering information are copied; some
     attribute flags and status bits are not (see the
    -form_field_new(3X) for details). 

    +form_field_new(3X) for details).

     FIELD *link_field(FIELD *field,           /* field to copy */
    @@ -1516,7 +1523,7 @@ As you might guess, all these field-allocations return NULL if
     the field allocation is not possible due to an out-of-memory error or
     out-of-bounds arguments. 

    -To connect fields to a form, use

    +To connect fields to a form, use

     FORM *new_form(FIELD **fields);
    @@ -1534,7 +1541,7 @@ note that any given field may only be connected to one form. 

    The functions free_field() and free_form are available to free field and form objects. It is an error to attempt to free a field connected to a form, but not vice-versa; thus, you will generally free -your form objects first.

    +your form objects first.

    Fetching and Changing Field Attributes

    @@ -1549,11 +1556,11 @@ When a field is created, the attributes not specified by the new_field function are copied from an invisible system default field. In attribute-setting and -fetching functions, the argument NULL is taken to mean this field. Changes to it persist -as defaults until your forms application terminates.

    +as defaults until your forms application terminates.

    Fetching Size and Location Data

    -You can retrieve field sizes and locations through:

    +You can retrieve field sizes and locations through:

     int field_info(FIELD *field,              /* field from which to fetch */
    @@ -1565,11 +1572,11 @@ int field_info(FIELD *field,              /* field from which to fetch */
     
     This function is a sort of inverse of new_field(); instead of
     setting size and location attributes of a new field, it fetches them
    -from an existing one.  

    +from an existing one.

    Changing the Field Location

    -It is possible to move a field's location on the screen:

    +It is possible to move a field's location on the screen:

     int move_field(FIELD *field,              /* field to alter */
    @@ -1581,7 +1588,7 @@ You can, of course. query the current location through field_info()
     

    The Justification Attribute

    One-line fields may be unjustified, justified right, justified left, -or centered. Here is how you manipulate this attribute:

    +or centered. Here is how you manipulate this attribute:

     int set_field_just(FIELD *field,          /* field to alter */
    @@ -1592,7 +1599,7 @@ int field_just(FIELD *field);             /* fetch mode of field */
     
     The mode values accepted and returned by this functions are
     preprocessor macros NO_JUSTIFICATION, JUSTIFY_RIGHT,
    -JUSTIFY_LEFT, or JUSTIFY_CENTER. 

    +JUSTIFY_LEFT, or JUSTIFY_CENTER.

    Field Display Attributes

    @@ -1603,7 +1610,7 @@ control pagination of the form.

    This group of four field attributes controls the visual appearance of the field on the screen, without affecting in any way the data -in the field buffer.

    +in the field buffer.

     int set_field_fore(FIELD *field,          /* field to alter */
    @@ -1632,7 +1639,7 @@ The attributes set and returned by the first four functions are normal
     A_BOLD, A_REVERSE etc).
     
     The page bit of a field controls whether it is displayed at the start of
    -a new form screen. 

    +a new form screen.

    Field Option Bits

    @@ -1708,13 +1715,13 @@ A field's options cannot be changed while the field is currently selected. However, options may be changed on posted fields that are not current.

    The option values are bit-masks and can be composed with logical-or in -the obvious way.

    +the obvious way.

    Field Status

    Every field has a status flag, which is set to FALSE when the field is created and TRUE when the value in field buffer 0 changes. This flag can -be queried and set directly:

    +be queried and set directly:

     int set_field_status(FIELD *field,      /* field to alter */
    @@ -1736,7 +1743,7 @@ To guarantee that the returned status value reflects reality, call
     field_status() either (1) in the field's exit validation check
     routine, (2) from the field's or form's initialization or termination
     hooks, or (3) just after a REQ_VALIDATION request has been
    -processed by the forms driver. 

    +processed by the forms driver.

    Field User Pointer

    @@ -1757,7 +1764,7 @@ The (char *) type is retained for System V compatibility.)

    It is valid to set the user pointer of the default field (with a set_field_userptr() call passed a NULL field pointer.) When a new field is created, the default-field user pointer is copied -to initialize the new field's user pointer.

    +to initialize the new field's user pointer.

    Variable-Sized Fields

    @@ -1776,7 +1783,7 @@ dimensioned and located.

    Normally, a dynamic field is allowed to grow without limit. But it is possible to set an upper limit on the size of a dynamic field. You do -it with this function:

    +it with this function:

     int set_max_field(FIELD *field,     /* field to alter (may not be NULL) */
    @@ -1818,7 +1825,7 @@ is changed through a linked field. 

    The form library provides a rich set of pre-defined validation types, and gives you the capability to define custom ones of your own. You can examine and change field validation attributes with the following -functions:

    +functions:

     int set_field_type(FIELD *field,          /* field to alter */
    @@ -1833,12 +1840,12 @@ with other field attributes, Also, doing set_field_type() with a
     NULL field default will change the system default for validation of
     newly-created fields. 

    -Here are the pre-defined validation types:

    +Here are the pre-defined validation types:

    TYPE_ALPHA

    This field type accepts alphabetic data; no blanks, no digits, no special -characters (this is checked at character-entry time). It is set up with:

    +characters (this is checked at character-entry time). It is set up with:

     int set_field_type(FIELD *field,          /* field to alter */
    @@ -1849,12 +1856,12 @@ int set_field_type(FIELD *field,          /* field to alter */
     The width argument sets a minimum width of data.  Typically
     you'll want to set this to the field width; if it's greater than the
     field width, the validation check will always fail.  A minimum width
    -of zero makes field completion optional. 

    +of zero makes field completion optional.

    TYPE_ALNUM

    This field type accepts alphabetic data and digits; no blanks, no special -characters (this is checked at character-entry time). It is set up with:

    +characters (this is checked at character-entry time). It is set up with:

     int set_field_type(FIELD *field,          /* field to alter */
    @@ -1865,13 +1872,13 @@ int set_field_type(FIELD *field,          /* field to alter */
     The width argument sets a minimum width of data.  As with
     TYPE_ALPHA, typically you'll want to set this to the field width; if it's
     greater than the field width, the validation check will always fail.  A
    -minimum width of zero makes field completion optional. 

    +minimum width of zero makes field completion optional.

    TYPE_ENUM

    This type allows you to restrict a field's values to be among a specified set of string values (for example, the two-letter postal codes for U.S. -states). It is set up with:

    +states). It is set up with:

     int set_field_type(FIELD *field,          /* field to alter */
    @@ -1896,11 +1903,11 @@ value.  But the checkunique argument, if true, requires prefix
     matches to be unique in order to be valid. 

    The REQ_NEXT_CHOICE and REQ_PREV_CHOICE input requests -can be particularly useful with these fields.

    +can be particularly useful with these fields.

    TYPE_INTEGER

    -This field type accepts an integer. It is set up as follows:

    +This field type accepts an integer. It is set up as follows:

     int set_field_type(FIELD *field,          /* field to alter */
    @@ -1921,7 +1928,7 @@ with the C library function atoi(3).
     
     

    TYPE_NUMERIC

    -This field type accepts a decimal number. It is set up as follows:

    +This field type accepts a decimal number. It is set up as follows:

     int set_field_type(FIELD *field,              /* field to alter */
    @@ -1945,7 +1952,7 @@ with the C library function atof(3).
     

    TYPE_REGEXP

    This field type accepts data matching a regular expression. It is set up -as follows:

    +as follows:

     int set_field_type(FIELD *field,          /* field to alter */
    @@ -1960,7 +1967,7 @@ The check for regular-expression match is performed on exit.
     
     The chief attribute of a field is its buffer contents.  When a form has
     been completed, your application usually needs to know the state of each
    -field buffer.  You can find this out with: 

    +field buffer. You can find this out with:

     char *field_buffer(FIELD *field,          /* field to query */
    @@ -1993,7 +2000,7 @@ To guarantee that the returned buffer value reflects on-screen reality,
     call field_buffer() either (1) in the field's exit validation
     check routine, (2) from the field's or form's initialization or termination
     hooks, or (3) just after a REQ_VALIDATION request has been processed
    -by the forms driver. 

    +by the forms driver.

    Attributes of Forms

    @@ -2002,7 +2009,7 @@ system default form structure. These defaults can be queried or set by of these functions using a form-pointer argument of NULL.

    The principal attribute of a form is its field list. You can query -and change this list with:

    +and change this list with:

     int set_form_fields(FORM *form,           /* form to alter */
    @@ -2024,7 +2031,7 @@ It may also be null, in which case the old fields are disconnected
     
     The field_count() function simply counts the number of fields
     connected to a given from.  It returns -1 if the form-pointer argument
    -is NULL. 

    +is NULL.

    Control of Form Display

    @@ -2055,7 +2062,7 @@ is where the current form page is actually displayed.

    In order to declare your own frame window for a form, you'll need to know the size of the form's bounding rectangle. You can get this -information with:

    +information with:

     int scale_form(FORM *form,                /* form to query */
    @@ -2084,7 +2091,7 @@ should be done on the frame window, not the form subwindow. 

    It is possible to check from your application whether all of a scrollable field is actually displayed within the menu subwindow. Use -these functions:

    +these functions:

     int data_ahead(FORM *form);               /* form to be queried */
    @@ -2100,21 +2107,21 @@ The function data_behind() returns TRUE if the first (upper
     left hand) character position is off-screen (not being displayed). 

    Finally, there is a function to restore the form window's cursor to the -value expected by the forms driver:

    +value expected by the forms driver:

     int pos_form_cursor(FORM *)               /* form to be queried */
     
    If your application changes the form window cursor, call this function before -handing control back to the forms driver in order to re-synchronize it.

    +handing control back to the forms driver in order to re-synchronize it.

    Input Processing in the Forms Driver

    The function form_driver() handles virtualized input requests for form navigation, editing, and validation requests, just as menu_driver does for menus (see the section on menu input handling).

    +HREF="#minput">menu input handling).

     int form_driver(FORM *form,               /* form to pass input to */
    @@ -2127,12 +2134,12 @@ entered in the currently-selected field), or a forms processing request. 

    The forms driver provides hooks (through input-validation and field-termination functions) with which your application code can check -that the input taken by the driver matched what was expected.

    +that the input taken by the driver matched what was expected.

    Page Navigation Requests

    These requests cause page-level moves through the form, -triggering display of a new form screen.

    +triggering display of a new form screen.

    REQ_NEXT_PAGE @@ -2147,11 +2154,11 @@ triggering display of a new form screen.

    These requests treat the list as cyclic; that is, REQ_NEXT_PAGE from the last page goes to the first, and REQ_PREV_PAGE from -the first page goes to the last.

    +the first page goes to the last.

    Inter-Field Navigation Requests

    -These requests handle navigation between fields on the same page.

    +These requests handle navigation between fields on the same page.

    REQ_NEXT_FIELD @@ -2162,7 +2169,6 @@ These requests handle navigation between fields on the same page.

    Move to the first field.
    REQ_LAST_FIELD
    Move to the last field. -

    REQ_SNEXT_FIELD
    Move to sorted next field.
    REQ_SPREV_FIELD @@ -2171,7 +2177,6 @@ These requests handle navigation between fields on the same page.

    Move to the sorted first field.
    REQ_SLAST_FIELD
    Move to the sorted last field. -

    REQ_LEFT_FIELD
    Move left to field.
    REQ_RIGHT_FIELD @@ -2203,12 +2208,12 @@ For example, suppose you have a multi-line field B, and two single-line fields A and C on the same line with B, with A to the left of B and C to the right of B. A REQ_MOVE_RIGHT from A will go to B only if A, B, and C all share the same first line; -otherwise it will skip over B to C.

    +otherwise it will skip over B to C.

    Intra-Field Navigation Requests

    These requests drive movement of the edit cursor within the currently -selected field.

    +selected field.

    REQ_NEXT_CHAR @@ -2243,7 +2248,7 @@ selected field.

    Each word is separated from the previous and next characters by whitespace. The commands to move to beginning and end of line or field -look for the first or last non-pad character in their ranges.

    +look for the first or last non-pad character in their ranges.

    Scrolling Requests

    @@ -2253,7 +2258,6 @@ multi-line fields scroll vertically. Most scrolling is triggered by editing and intra-field movement (the library scrolls the field to keep the cursor visible). It is possible to explicitly request scrolling with the following requests: -

    REQ_SCR_FLINE @@ -2283,7 +2287,7 @@ following requests:
    For scrolling purposes, a page of a field is the height -of its visible part.

    +of its visible part.

    Editing Requests

    @@ -2293,7 +2297,7 @@ is an insertion or a replacement depends on the field's edit mode (insertion is the default.

    The following requests support editing the field and changing the edit -mode:

    +mode:

    REQ_INS_MODE @@ -2359,13 +2363,13 @@ treated as a REQ_PREV_FIELD.

    If the disabled and the forms driver just returns E_REQUEST_DENIED.

    See Form Options for discussion of how to set -and clear the overload options.

    +and clear the overload options.

    Order Requests

    If the type of your field is ordered, and has associated functions for getting the next and previous values of the type from a given value, -there are requests that can fetch that value into the field buffer:

    +there are requests that can fetch that value into the field buffer:

    REQ_NEXT_CHOICE @@ -2377,19 +2381,19 @@ there are requests that can fetch that value into the field buffer:

    Of the built-in field types, only TYPE_ENUM has built-in successor and predecessor functions. When you define a field type of your own (see Custom Validation Types), you can associate -our own ordering functions.

    +our own ordering functions.

    Application Commands

    Form requests are represented as integers above the curses value greater than KEY_MAX and less than or equal to the constant MAX_COMMAND. If your input-virtualization routine returns a -value above MAX_COMMAND, the forms driver will ignore it.

    +value above MAX_COMMAND, the forms driver will ignore it.

    Field Change Hooks

    It is possible to set function hooks to be executed whenever the -current field or form changes. Here are the functions that support this:

    +current field or form changes. Here are the functions that support this:

     typedef void	(*HOOK)();       /* pointer to function returning void */
    @@ -2418,7 +2422,7 @@ HOOK field_term(FORM *form);     /* form to query */
     These functions allow you to either set or query four different hooks.
     In each of the set functions, the second argument should be the
     address of a hook function.  These functions differ only in the timing
    -of the hook call. 

    +of the hook call.

    form_init @@ -2429,7 +2433,7 @@ each page change operation. each field change
    field_term
    This hook is called just after field validation; that is, just before -the field is altered. It is also called when the form is unposted.

    +the field is altered. It is also called when the form is unposted.

    form_term
    This hook is called when the form is unposted; also, just before each page change operation. @@ -2449,7 +2453,7 @@ You can set a default hook for all fields by passing one of the set functions a NULL first argument.

    You can disable any of these hooks by (re)setting them to NULL, the default -value.

    +value.

    Field Change Commands

    @@ -2457,7 +2461,7 @@ Normally, navigation through the form will be driven by the user's input requests. But sometimes it is useful to be able to move the focus for editing and viewing under control of your application, or ask which field it currently is in. The following functions help you -accomplish this:

    +accomplish this:

     int set_current_field(FORM *form,         /* form to alter */
    @@ -2476,7 +2480,7 @@ in the given form's field array (the array passed to new_form() or
     The initial current field of a form is the first active field on the
     first page. The function set_form_fields() resets this.

    -It is also possible to move around by pages.

    +It is also possible to move around by pages.

     int set_form_page(FORM *form,             /* form to alter */
    @@ -2486,12 +2490,12 @@ int form_page(FORM *form);                /* return form's current page */
     
    The initial page of a newly-created form is 0. The function -set_form_fields() resets this.

    +set_form_fields() resets this.

    Form Options

    Like fields, forms may have control option bits. They can be changed -or queried with these functions:

    +or queried with these functions:

     int set_form_opts(FORM *form,             /* form to alter */
    @@ -2521,7 +2525,7 @@ these have no last line, so the circumstances for triggering a
     
    The option values are bit-masks and can be composed with logical-or in -the obvious way.

    +the obvious way.

    Custom Validation Types

    @@ -2530,12 +2534,12 @@ validation types of your own. Further, the optional additional arguments of set_field_type effectively allow you to parameterize validation types. Most of the complications in the validation-type interface have to do with the handling of the additional arguments within custom validation -functions.

    +functions.

    Union Types

    The simplest way to create a custom data type is to compose it from two -preexisting ones:

    +preexisting ones:

     FIELD *link_fieldtype(FIELDTYPE *type1,
    @@ -2551,19 +2555,19 @@ composite type expects all arguments for the first type, than all arguments
     for the second.  Order functions (see Order Requests)
     associated with the component types will work on the composite; what it does
     is check the validation function for the first type, then for the second, to
    -figure what type the buffer contents should be treated as. 

    +figure what type the buffer contents should be treated as.

    New Field Types

    To create a field type from scratch, you need to specify one or both of the -following things:

    +following things:

    • A character-validation function, to check each character as it is entered.
    • A field-validation function to be applied on exit from the field.
    -Here's how you do that:

    +Here's how you do that:

     typedef int	(*HOOK)();       /* pointer to function returning int */
     
    @@ -2589,7 +2593,7 @@ the operation succeeds; if it returns FALSE, the edit cursor stays in
     the field. 

    A character validator gets the character passed in as a first argument. -It too should return TRUE if the character is valid, FALSE otherwise.

    +It too should return TRUE if the character is valid, FALSE otherwise.

    Validation Function Arguments

    @@ -2606,7 +2610,7 @@ with the type. The forms driver will use these to synthesize a pile from the trailing arguments of each set_field_type() argument, and a pointer to the pile will be passed to the validation functions.

    -Here is how you make the association:

    +Here is how you make the association:

     typedef char	*(*PTRHOOK)();    /* pointer to function returning (char *) */
    @@ -2618,7 +2622,7 @@ int set_fieldtype_arg(FIELDTYPE *type,    /* type to alter */
                           VOIDHOOK free_str); /* free structure storage */
     
    -Here is how the storage-management hooks are used:

    +Here is how the storage-management hooks are used:

    make_str @@ -2639,14 +2643,14 @@ storage of that pile. The make_str and copy_str functions may return NULL to signal allocation failure. The library routines will that call them will return error indication when this happens. Thus, your validation functions -should never see a NULL file pointer and need not check specially for it.

    +should never see a NULL file pointer and need not check specially for it.

    Order Functions For Custom Types

    Some custom field types are simply ordered in the same well-defined way that TYPE_ENUM is. For such types, it is possible to define successor and predecessor functions to support the REQ_NEXT_CHOICE -and REQ_PREV_CHOICE requests. Here's how:

    +and REQ_PREV_CHOICE requests. Here's how:

     typedef int	(*INTHOOK)();     /* pointer to function returning int */
    @@ -2661,7 +2665,7 @@ a field pointer, and a pile pointer (as for the validation functions).  They
     are expected to use the function field_buffer() to read the
     current value, and set_field_buffer() on buffer 0 to set the next
     or previous value.  Either hook may return TRUE to indicate success (a
    -legal next or previous value was set) or FALSE to indicate failure. 

    +legal next or previous value was set) or FALSE to indicate failure.

    Avoiding Problems