``USC'' -- UNIFY(r) Screens using Curses
UNIFY(r) is a registered trademark of Unify Corporation.

THIS PROGRAM IS NOT BASED ON COPYRIGHTED CODE OF UNIFY CORPORATION, AND
IS HEREBY PLACED IN THE PUBLIC DOMAIN.

This is a short description of the extended functionality of USC.  The
functions are source-level compatible with the standard UNIFY calls, but NOT
compatible with the special internal calls used in ENTER.  This code is known
to work with UNIFY 3.2, it will probably work with UNIFY 3.1, I have no idea
how compatible it is with UNIFY 4.0.  INCLUDE THE COMPILER DIRECTIVE -DUNIFY32
TO ENABLE USE OF ADVANCED FIELD ATTRIBUTES IN UNIFY 3.2.

All the I/O functions use curses.  Provision is made only for stdscr; use of
other windows must be made at the curses level.  For the low-level UNIFY
functions which expect an fd argument, the provided fd MUST BE 1 or the USC
routines will print an error message and dump core.

Input functions support the following special keys:

^H	delete character before cursor
^F	move cursor forward; wraps to beginning of field
^B	move cursor backward; wraps to end of field
^A	move cursor to beginning of field
^N	move cursor to end of field
^O	insert a space
^D	delete character after cursor
^K	clear to end of field
^X	immediate program exit
^L, ^R	redisplay screen
^P	push a shell
^U, TAB	return -2
^M, ^J	return -3 or 0 depending on input state

If the "look" capability is enabled, the following character may be used:

^V	view parent record

If extended return codes are enabled (see below), the following may be used:

^E, ESC	return -5 or -6 depending on input state
^U, TAB	return -2 or -7 depending on input state

The input routines check to see if the buffer has been filled; if extended
return codes are enabled, special codes are returned when ^E or ^U are done
on fields after data is entered in them.  This allows the user to type
something before a ^U or ^E and have it accepted.

Extended return codes are processed via the setxrc() function.  To use this
function, #include the file "xrc.h" in your program and invoke setxrc() with
an integer containing a combination of zero or more of the following flags:

	XRC_GO		allow the ^E key to cause end of input
	XRC_XOK		return special values if data entered in field
	XRC_LOOK	on screen fields in explicit relationships,
			allow ^V to display parent record

THE USE OF XRC_XOK WILL BREAK PROGRAMS NOT EXPECTING IT!!!  Use of XRC_GO may
also break programs; but XRC_LOOK alone will NEVER return an unexpected return
code.

For each input function in the UNIFY manual, there is an update function; the
name of the update function is the name with the leading `g' replaced with a
`up'.  Thus, the update version of gtube() is uptube().  The update functions
are called in the same way as the input functions, but they start with the
existing data values, and if XRC_XOK is enabled the -2, -3, and -5 return
codes will NEVER be returned.

Input which can be related to a database field (primarily gdata()) will do
some extra work for you.  If write passwords are enabled and gdata() is
invoked on a write-protected field, USC will ask for the modify password and
retry the pfield(); if the password is incorrect, the operation fails.  If the
record is locked, the program will ask you if you wish to retry the pfield()
or abort the operation.  Both of these make life easier on a programmer.  Note
that gdata() is called internally by input() and upfield() [the update form of
input(); update() is used].

Screen fields may be enhanced by a program by setting special flags; in
particular, the UPCASE flag may be set to force USC to force all input to
uppercase for the field.  NO PROVISION IS MADE TO STORE THIS IN UNIFY SCREEN
FILES, AS THIS WOULD BREAK EXISTING UNIFY PROGRAMS.  To use this feature,
#include the file "xsfldesc.h" and call the function xsfldesc(sfield).  This
functioon returns a pointer to the internal screen field structure, which
contains *all* of the information for the screen field (not just the x, y,
field information in Unify's sfdesc structure).  THIS IS NOT A COPY OF THE
DATA; CORRUPTING THIS INFORMATION MAY CAUSE A CORE DUMP.  The UPCASE flag may
then be ORed in with the structure member xsf_typ to force uppercase input.

Some new functions are provided as well; in particular, ringmenu() will
execute a ring menu at the top of the screen.  (For the more eclectic members
of the audience, think of Informix-4GL's menus.)  The menu is defined as an
array of structures; the structure is defined in "ringmenu.h".  An example of
a ring menu might be:

#include "ringmenu.h"

struct ringmenu mymenu[] = {
	'A',	"Add",		"Add a new order.",
	'D',	"Delete",	"Delete an order.",
	'M',	"Modify",	"Modify an existing order.",
	'E',	"Exit",		"Exit the order maintenance.",
	EOM,
};

...
ringmenu("ORDERS", mymenu);

Many of the function keys used in field I/O have similar meanings in a ring
menu.  In particular, since a ring menu may be larger than the screen width
the ^F and ^B keys move by "pages"; and ^V pops up a full-screen listing of
all selections on the menu.

Since the *error() routines had to be replaced anyway to insure that curses
I/O is reset, I provide 3.2-compatible error routines... which use an error
log even under UNIFY 3.1, so you get a bonus.  There are some added features:

extern void (*errexit)();

Set this function to some function to execute after displaying the error
message but before final program exit.  Curses mode is turned off before the
function is called.  I most commonly point this to abort() so I have more
information to work with when a program bombs.

int xerror(ier, id, format[, args ...])
int ier;
char *id, *format;

This function is the lowest-level interface to the error mechanism; it
*should* be the highest, but....  The argument "ier" becomes the "Status" in
the error log; "id" is the offending function (the calling function is
"xerror"); the notes are built from the printf-style format and its arguments.

extern char errcall[30];

This string contains "xerror" initially; it is the value printed for "calling
function" in the error log.  It is changed by the standard error routines to
name themselves; you can change it in a custom error function if you wish.

