@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.0.00 AnsiCmd Library:  - - - - - - - - - - - - - - - - - - - - - - - - - -
@c         Description of primary methods and data - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node AnsiCmd Library
@unnumbered AnsiCmd Library
@cindex 03.0.00 AnsiCmd Library

@menu
* Introductory Notes::           Overview of the working environment
* ANSI Escape Sequences::        Physical structure and use
* Terminal Configuration::       Configuring I/O streams and more
* AnsiCmd Class Methods::        Public methods and data members
@end menu


@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@lowersections
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.1.00 Introductory Notes: - - - - - - - - - - - - - - - - - - - - - - - - -
@c         Overview of the working environment   - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Introductory Notes
@unnumbered Introductory Notes
@cindex 03.1.00 Introductory Notes

For those who are new to the terminal (emulator) environment, or for those 
who are interested in the technical details of terminal configuration, 
this chapter provides an overview of the challenges the author faced 
during development of this project, and our responses to those challenges.

@Subheading{Terminal Environment,
            --------------------}

A common saying in Linux is that @LDQ{}Everything is a file.@RDQ{} While 
it is true in general that most things are @emph{acessed} as if they were 
files, many of the underlying targets are not actually files on the storage 
media. This is nowhere more apparent than with the input and output data 
streams of the terminal emulator. Generically, these are known as 
@w{Standard Input(stdin)}, @w{Standard Output(stdout)} and 
@w{Standard Error(stderr)}.

Within the @t{AnsiCmd} library, these are referred to by their so-called 
file handles which are named by the @t{'TermStream'} enumerated type:
@example
Name   Handle
stdIn    0
stdOut   1
stdErr   2
@end example

These streams are not actual files, but the terminal's @b{@emph{VIRTUAL}} 
configuration files. Therefore, practically speaking, when modifying 
terminal settings, it doesn't matter whether the stdIn, stdOut or stdErr 
stream is referenced because they are not actual file descriptors. Instead, 
they reference the underlying terminal-attributes structure.@*
For more information, @pxref{Terminal Configuration}.


@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.2.00 ANSI Escape Sequences:  - - - - - - - - - - - - - - - - - - - - - - -
@c         Physical structure and use  - - - - - - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node ANSI Escape Sequences
@unnumbered ANSI Escape Sequences
@cindex 03.2.00 ANSI Escape Sequences

@t{ANSI} (American National Standards Institute) escape sequences are simply a 
well-defined set of byte sequences that may be used to communicate with 
the host terminal. They are hopelessly old-fashioned, slow, unreliable, 
difficut to use and all-around relics from the mid-20th century. That being 
said, they are also widely supported and a lot of fun to play with.

@t{ANSI} escape sequences include functionality for cursor positioning, erasing 
blocks of text, setting color attributes and text modifiers such as bold, 
italic etc., and all other attributes defined by the @w{ECMA-48, ANSI X3.64} 
standard. See also @w{ISO/IEC 6429}, @w{FIPS 86}, @w{ISO/IEC 2022}, @w{JIS X 0211}.

@ifnothtml
@uref{https://en.wikipedia.org/wiki/ANSI_escape_code}
@end ifnothtml
@ifhtml
@html
<p style="margin-left:2.5em;">Wikipedia:&nbsp;&nbsp;
<a href="https://en.wikipedia.org/wiki/ANSI_escape_code" 
target="_blank">https://en.wikipedia.org/wiki/ANSI_escape_code</a><br>
@end html
@end ifhtml
@sp 2

@cindex aeSeq enumerated type
@Subsubheading{Escape-sequence Definitions,
               ...........................}

Within the AnsiCmd library, the individual @t{ANSI} escape sequences are 
referenced by the @LDQ{}@b{@t{enum aeSeq}}@RDQ{} enumerated type. 

@t{aeSeq} @i{(ANSI Escape Sequence)} is located in the @t{AnsiCmdDef.hpp} 
header file and includes all the @t{ANSI} escape sequences defined by the 
@w{@t{ECMA-48, ISO/IEC-6429}} standard.

Note that each member begins with @LDQ{}@b{@t{aes}}@RDQ{} to indicate that 
it belongs specifically to this enumerated type. The short example below 
should give the basic idea of how @t{aeSeq} is constructed.
@c smallverbatim
@verbatim

enum aeSeq : short
{
   //** Text Modification Options. **
   aesRESET = 0,              // reset all attributes
   aesBOLD,                   // bold (increase intensity)
   aesFAINT,                  // faint/dim (decrease intensity)
   aesITALIC,                 // italic (or inverse)
   . . .
   //** Foreground Color Attributes (3-bit and 4-bit color selection) **
   aesFG_BLACK,               // set foreground color to black (i==24)
   aesFG_RED,                 // set foreground color to red
   aesFG_GREEN,               // set foreground color to green
   . . .
   //** Background Color Attributes (3-bit and 4-bit color selection) **
   aesBG_BLACK,               // set background color to black (i==41)
   aesBG_RED,                 // set background color to red
   aesBG_GREEN,               // set background color to green
   . . .
   //** Indexed Color Attribute Options (8-bit color and greyscale) **
   aesFG_INDEX,               // set foreground color by lookup table index (0-255)
   aesBG_INDEX,               // set background color by lookup table index (0-255)

   //** Red/Green/Blue Color Attribute Options (24-bit color) **
   aesFG_RGB,                 // set foreground color by r/g/b register number
   aesBG_RGB,                 // set background color by r/g/b register number

   //* Cursor-positioning Options *
   aesCUR_HOME,               // set cursor at 1,1
   aesCUR_ABSPOS,             // set (absolute) cursor at specified row;column position
   aesCUR_ROWSUP,             // move cursor upward by specified number of rows
   . . .
   //* Text Erasure Options *
   aesERASE_BOW,              // erase from cursor to bottom of window
   aesERASE_TOW,              // erase from cursor to top of window
   aesERASE_WIN,              // erase entire window ('clear')
   . . .
   //* Alternate Font group *
   aesPRIMARY_FONT,           // primary font      (font 0)
   aesALTERNATE_FONT,         // alternate fonts (font 1 through font 9)

   //* ASCII Control Codes. *
   aesBELL,                   // '\a' terminal "bell" (beep, ping, etc.)
   aesBKSP,                   // '\b' backspace
   aesHTAB,                   // '\t' horizontal tab
   . . .
   //* Ideogram (logogram) group of options *
   aesIDEO_UNDER,             // ideogram underlined
   aesIDEO_UDOUBLE,           // ideogram double-underlined
   aesIDEO_OVER,              // ideogram overlined
   . . .
   //** Aixterm codes are not part of the    **
   //** ANSI standard, but may be supported. **
   aesAIXFGb_BLACK,           // set foreground color to bright black (grey)
   aesAIXFGb_RED,             // set foreground color to bright red
   aesAIXFGb_GREEN,           // set foreground color to bright green
   . . .
   aesCOUNT                   // number of items in enumerated type list
} ;   // enum aeSeq
@end verbatim

@cindex ANSI escape sequence
The members of @t{aeSeq} index the corresponding byte sequences which are 
private data located in the @t{AnsiCmd.cpp} source module.@*
@b{@verb{|    static const wchar_t *ansiSeq[aesCOUNT];|}}

A majority of the element of this array are constant byte sequences; however, 
the sequences which require parameters are defined as formatting templates 
as shown in these examples.

Constant byte sequence:@*
@b{@verb{|    L"\x1B[22;31m"|}} @verb{|     // aesFG_RED|}@*
Formatting template:@*
@b{@verb{|    L"\x1B[38;5;%hhum"|}} @verb{| // aesFG_INDEX|}

Note that these sequences are defined as @emph{wide} character strings 
because as explained elsewhere (@ref{Terminal Configuration}), 
8-bit character streams are so very 1970s.



@cindex multi-threading
@Subsubheading{Multi-threading,
               ...............}

ANSI escape sequences should not be used in multi-threaded applications due 
to timing issues and resource conflicts. For multi-threaded applications, 
the author recommends our @t{NcDialog API}, which is a fully thread-safe 
ncurses-based library for creating formatted-text console applications.

One practical effect of avoiding multi-threading is in the area of library 
functions which handle timing and delays.

In C++, the accepted way to delay the action is to use the 'chrono' class 
to define the delay, and the 'sleep_for' method to execute it. However, 
@t{ANSI} escape sequences are inherently incompatible with a multi-threaded 
environment. For this reason, the AnsiCmd class uses the C-language nanosleep() 
function. This function is technically sophisticated, but clunky in 
implementation; so please refer to our iplementation of nanosleep(): nsleep() 
for details. (@pxref{nsleep})


@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.3.00 Terminal Configuration: - - - - - - - - - - - - - - - - - - - - - - -
@c         Configuring I/O streams and more  - - - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Terminal Configuration
@unnumbered Terminal Configuration
@cindex 03.3.00 Terminal Configuration
@cindex terminal configuration
@cindex configuration, terminal

Initial terminal configuration is specified by passing an initialized 
@t{TermConfig} object to the AnsiCmd constructor.@*
@ @ @ @xref{TermConfig Class}.

Subsequent modifications to the terminal environment are specified by calling 
the associated AnsiCmd-class method(s).@*
@ @ @ @xref{AnsiCmd Class Methods}.

The actual configuration commands are issued by the @t{TermSet} object, 
which is a private member of the @t{AnsiCmd} class as described below.@*
@ @ @ @xref{TermSet Class}.
@sp 1


@anchor{TermConfig Class}
@cindex TermConfig class
@cindex class, TermConfig
@Subheading{TermConfig Class,
            ----------------}

Initialization of the @t{TermConfig} object may be done directly by the 
application when invoking the AnsiCmd constructor:@*
@ @ @ @ref{AnsiCmd constructor},@*
or may be performed by the user through command-line options:@*
@ @ @ @ref{Invoking - Terminal Setup}.@*
The options provided by the user are validated and stored in the data 
members of the TermConfig object.

@ifnothtml
@Subsubheading{Data Members,............}
@end ifnothtml
@ifhtml
@Subsubheading{@ @ @ @ @ @ Data Members,............}
@end ifhtml

@itemize @BDISC
@item @t{TermStream termStream}@*
Specify the target I/O stream as a member of enum TermStream:@*
@t{@ @ @ stdIn (stdin), stdOut (stdout), stdErr (stderr)}

@b{Note:} In practical terms, the selection of the target stream is not 
important because changes made to one stream are reflected in all streams. 
Internally, @t{'stdIn'} is used when not specified otherwise.

@item @t{char configFile[gsMAXBYTES]}@*
@t{NOT YET IMPLEMENTED}@*
Name of configuration file (default @LDQ{}ansicmd.cfg@RDQ{}) which specifies 
all terminal configuration options.

@cindex locale name
@item @t{char localeName[LOCALE_LEN]}@*
Filename of alternate locale (null string by default). If not specified, 
locale will be taken from terminal environment.

For those not familiar with the purpose of the @t{'locale'} specification, 
the locale selected controls how characters are encoded, formatting of 
numbers, timestamps and currency, interpretation of punctuation, comparisons 
of text strings and other text formatting decisions. By default, applications 
start in the so-called @LDQ{}C-locale@RDQ{} which is not really a locale, but 
a lack of locale which interprets everything in terms of @t{ASCII} and English, 
rendering the application basically useless. For this reason, it is 
@b{@emph{strongly}} recommended that all application set the locale for the 
language, character set and text conventions in use by the target system.@*
Please refer to the @ref{acSetLocale} method for additional information.

@item @t{EchoOpt echoOption}@*
The selected Echo Option specifies how the data input stream is to be managed. 

Characters received through @t{'stdin'} will be echoed (displayed) in the 
terminal window according to the specified member of enum EchoOpt.

When system buffering of input is active, the application has no direct 
control over input echo, so this option will be ignored. However, when 
input buffering is disabled (see the @t{'bufferInput'} variable, 
below), the specified echo option will be used:@*
   @itemize @BCIRCLE
   @item noEcho : input data are not echoed to the display. 
   @item termEcho: terminal automatically echoes input@*
   The terminal always controls input echo when input buffering is enabled, 
   and @emph{may be} allowed to control input echo when buffering is 
   disabled.
   @item softEcho[A|B|C|D|E]: the @ref{acRead} input methods echo (display) 
   all graphing (printing) characters to the terminal window as they arrive. 
   The @LDQ{}special@RDQ{} keys (cursor movement, text selection, clipboard 
   access and backspace, delete, insert) 
   are processed according to specified soft-echo sub-option.@*
      @itemize @BSQUARE
      @item softEchoA - All special keys are captured, decoded and available 
      to the application.@*
      @item softEchoB - Basic group of special keys. (Text selection keys 
      and Copy/Cut/Paste/Undo keys are excluded.)@*
      @item softEchoC - Cursor keys only: UpArrow, DownArrow, LeftArrow, RightArrow,
      Home, End, PageUp, PageDown, Tab and Shift+Tab. (Edit keycodes are excluded.)@*
      @item softEchoD - Disable (capture and discard) all special keycodes.@*
      @item softEchoE - Edit keys Backspace, Delete and Insert, @emph{plus} 
      Tab and Shift+Tab. (Cursor movement keycodes are discarded.)
      @end itemize
   The keycodes in each special-key group may be adjusted, as we receive more 
   feedback from users about how they uses these options.

   Please @pxref{Soft Echo Options} below for more information.
   @end itemize

@cindex input buffering
@cindex buffering, input
@item @t{bool bufferInput}@*
Specify whether data from @t{'stdin'} will be buffered by the system or 
whether it will be sent directly to the application as soon as it arrives 
in the input stream.@*
@verb{|   'false' : disable input buffering|}@*
@verb{|   'true;  : input buffering enabled (default)|}@*
Note that both the soft-echo options (described above) and non-blocking 
read of the input stream require that input buffering be disabled.

@item @t{bool wideStream}@*
Select the character width of the input/output streams.@*
@verb{|   'true'  : wide (32-bit) I/O streams, wcin and wcout|}@*
@verb{|   'false' : narrow (87-bit) I/O streams, cin and cout|}@*
Please @pxref{acSetStreamWidth} for additional information.

@item @t{bool nonStandard}@*
Specify whether the host terminal is ANSI compliant.@*
A compliant terminal supports all of the common commands of @t{ANSI} standard 
@t{(ANSI X3.64 (ISO/IEC6429))}.
@verb{|   'true'  : non-standard terminal emulator|}@*
@verb{|   'false' : ANSI compliant terminal emulator (default)|}@*
The three terminal emulators used during development, Gnometerm, Konsole 
and XTerm are all fully compliant with the standard. To determine whether 
your preferred terminal supports all the @t{ANSI} escape sequences defined 
by the standard, run the full set of tests provided with this library. 
@ifnothtml
@*
@end ifnothtml
Please @pxref{Development and Testing} for full information.

@item @t{CCH_Type bcType}@*
Capture the Panic Button (CTRL+C key). The signal-capture type is specified 
as a member of enum CCH_Type:@*
   @itemize @BCIRCLE
   @item @t{cchtTerm } @ @ -@ Terminal handles CTRL+C break-signal.
   @item @t{cchtExit } @ @ -@ The application terminates execution in an orderly way.
   @item @t{cchtUser } @ @ -@ Ask user whether to exit or discard the signal.
   @item @t{cchtCopy } @ @ -@ Convert the break signal to an ordinary keycode.
   @item @t{cchtIgnore} - Ignore (discard) the break signal.
   @end itemize
   
@xref{Capturing the Break Signal} below for more information.

@anchor{bcAlert}
@item @t{bool bcAlert}@*
For @t{'bcType' == cchtIgnore} ONLY: Specify whether the application should 
sound an audible alert when the break signal is captured and discarded. 
(This is a polite way of telling the user to stop pressing the Panic Button.)@*
@verb{|   'true' : sound the alert when break is captured and discarded|}@*
@verb{|   'false': silently discard the captured break signal|}

@item @t{CurStyle cursorStyle}@*
Select cursor style. The cursor style is specified as a member of enum CurStyle:@*
   @itemize @BCIRCLE
   @item @t{csDflt @ @ } Terminal default cursor style.
   @item @t{csBblock } The shape of the cursor is a full-character cell, 
   @b{@emph{blinking}} block. (This is also generally the terminal default shape.)
   @item @t{csSblock } The shape of the cursor is a full-character cell, 
   @b{@emph{steady}} (non-blinking) block.
   @item @t{csBuline } The shape of the cursor is a @b{@emph{blinking}} underline 
   i.e. one or two pixel rows at the bottom of the character cell.
   @item @t{csSuline } The shape of the cursor is a @b{@emph{steady}} underline 
   i.e. one or two pixel rows at the bottom of the character cell.
   @item @t{csBvbar @ } The shape of the cursor is a @b{@emph{blinking}} vertical 
   bar i.e. one or two pixel columns at the left edge of the character cell.
   @item @t{csSvbar @ } The shape of the cursor is a @b{@emph{steady}} vertical 
   bar i.e. one or two pixel columns at the left edge of the character cell.
   @item @t{csHide @ @ } Hide the cursor i.e. make it @b{@emph{invisible}}.
   Note that the previouly selected cursor shape will be retained.
   @item @t{csShow @ @ } Show the cursor i.e. make it @b{@emph{visible}}. 
   @end itemize

@item suspendSignal@*
Specify whether the Suspend signal is captured by the application.@*
The system uses the suspend signal to put the active process into hibernation. 

By default, the @t{AnsiCmd} library captures this signal and converts it to an 
ordinary keycode (wcsCTL_Z). Under most circumstances, this is the desired 
action; however, if specified, the system can be allowed to retain control 
of this signal.@*
@verb{|   'false' : the system retains control of the suspend signal|}@*
@verb{|   'true'  : the suspend signal is captured and disabled (default)|}@*
Please @pxref{acCaptureSuspendSignal} for additional information.

@item quitSignal@*
Specify whether the Quit signal is captured by the application.@*
The system uses the quit signal to immediately kill the application and then 
produce what is known as a @LDQ{}core dump@RDQ{} which is a file that contains 
information about the final state of the application.@*
@verb{|   'false' : the system retains control of the quit signal|}@*
@verb{|   'true'  : the quit signal is captured and an orderly|}@*
@verb{|             shutdown is executed (default)|}@*
Please @pxref{acCaptureQuitSignal} for additional information.

@item @t{aeSeq foreground}@*
Specify the initial foreground (text) color attribute.@*
This is a member of the 4-bit foreground color group within 
@ifnothtml
@*
@end ifnothtml
@t{enum aeSeq: aesFG_xxxx (default:aesFG_DFLT)}@*
Please @pxref{ANSI Escape Sequences} for examples.

@item @t{aeSeq background}@*
This is a member of the 4-bit foreground color group within 
@ifnothtml
@*
@end ifnothtml
@t{enum aeSeq: aesBG_xxxx (default:aesBG_DFLT)}@*
Please @pxref{ANSI Escape Sequences} for examples.
@end itemize
@sp 1

@anchor{Capturing the Break Signal}
@cindex break signal
@cindex Control_C
@Subheading{Capturing the Break Signal (CTRL+C),
            -----------------------------------}

The break signal is generated by the user pressing the @b{@t{Control+C}} key 
combination. By default, the break signal is captured by the terminal which 
then sends the kill signal to the application running within the terminal window. 
It is often useful, however, to redirect the break signal to application 
control. The AnsiCmd library can perform this redirection in either of two ways.

@enumerate 1
@item Activate the break-signal handler during instantiation of the AnsiCmd 
class by setting the @t{'bcType'} member of The TermConfig object which is 
passed as the argument to the AnsiCmd constructor.@*
Please @pxref{TermConfig Class} and @ref{Invoking - Terminal Setup} 
for detailed instructions on specifying a break-signal handler using this method.

@item Specify redirection of the break signal to application control through 
a call to the @ref{acCaptureBreakSignal} method.

While the first option always invokes the AnsiCmd library's default handler, 
the @t{'acCaptureBreakSignal'} call can specify either the default handler 
@b{@emph{or}} an alternate handler provided by the application.

The @t{'acCaptureBreakSignal'} method can also be used to return control to 
the terminal's signal handler.
@end enumerate

The mechanics of transferring control of the break signal to the application 
are straightforward, but non-trivial. It is accomplished by 
@LDQ{}registering@RDQ{} a signal-handler function with the system using the 
C-library function:@*
@verb{|   'signal( int SIGNUM, sighandler_t ACTION )'|}.@*
This function is defined in the @t{'signal.h'} header file.@*
The SIGNUM parameter in this case is the macro @t{'SIGINT'} (the interrupt signal). 
The ACTION parameter is the address (name) of the function to which the break 
signal will be directed.

The terminal's signal handler is defined by the macro @t{'SIG_DFL'}, while 
the application's handler may be specified by the name of any (non-member) 
function in the application which is configured to process the signal.

The non-member function in the AnsiCmd library is cryptically named 
@t{'BreakSignal_Handler'}. The system call is then:@*
@b{@verb{|   signal ( SIGINT, BreakSignal_Handler );|}}

Because we want to provide for potential user interaction when the break 
signal is received, we perform the slightly dangerous operation of allowing 
the non-member function to call an AnsiCmd-class member method:@*
@b{@verb{|   breaksignalReceived ( int sigNum );|}}@*
This is where the action takes place.

The type of operation to perform has been specified during handler setup, and 
is a member of enum @b{@t{CCH_Type}} (@b{C}ontrol_@b{C}_@b{H}andler @b{Type}).

@itemize @BCIRCLE
@item @t{@b{cchtTerm} -} Terminal handles CTRL+C break-signal by issuing 
the kill signal to the application running within the terminal. Generally, 
this can be done without serious consequences; however, it may be necessary 
to manually reset the terminal by calling the @t{'reset'} utility to return 
the terminal configuration to a known state. For instance, if the application 
is terminated using CTRL+C, the current terminal attributes will still be 
active when the terminal shell regains control.

@item @t{@b{cchtExit} -} The application will perform any specified housekeeping 
tasks, and then immediately terminate execution, returning control to the 
terminal shell program. For the AnsiCmd class, @LDQ{}@i{housekeeping tasks}@RDQ{} 
include returning the terminal configuration to its original state, deleting 
all allocated objects by calling the destructors for the objects in the 
proper order, setting the exit code and executing the C-library exit sequence.

@item @t{@b{cchtUser} -} Prompt user for whether to exit the application or to 
discard the break signal and continue execution.@*
@ifnothtml
@b{@verb{|      Break Detected. Exit? (N/y): _|}}@*
@end ifnothtml
@ifhtml
@html
<span style="margin-left: 6em; font-weight: bold; color: whitesmoke; 
background-color: black;">
&nbsp;&nbsp;&nbsp;Break Detected. Exit? (N / y): _&nbsp;&nbsp;&nbsp;</span><br>
@end html
@end ifhtml
This message is written to the upper-right corner of the terminal window 
and uses a blinking text attribute to draw the user's attention.

@item @t{@b{cchtCopy} -} Convert the captured break signal to the keycode 
@t{wcsCTL_C} (Ctrl+C). The application can then process the keycode or 
discard it as desired. For instance, the ACWin class recognizes this keycode 
as the @LDQ{}Copy@RDQ{} command, and copies the selected text to the clipboard.

@item @t{@b{cchtIgnore} -} Ignore (discard) the break signal and continue 
execution of the application; optionally, sounding an audible alert so 
the user knows that the signal was received, but discarded. 
(@pxref{bcAlert} member of the TermConfig class for enabling the audible alert.)
@end itemize

@sp 1


@anchor{Soft Echo Options}
@cindex soft-echo options
@cindex echo options
@cindex options, echo
@Subheading{Soft Echo Options,
            -----------------}

@LDQ{}Soft Echo@RDQ{} options define a range of ways in which keyboard input 
can be captured and filtered before it is echoed (written) to the terminal 
window.

The primary method for selecting the the soft-echo option is to specify it 
during a call to the @ref{acBufferedInput} method which disables input 
buffering and optionally specifies the character-echo option and whether the 
input stream uses a blocking or non-blocking read.

The soft-echo option may also be specified as a command-line option. 
See the @t{'@b{echoOption}'} member in the discussion of the 
@ifhtml
@*
@end ifhtml
@ref{TermConfig Class}, above.

If the echo option is @b{@t{termEcho}}, then the terminal decides what input is 
echoed to the display. If the echo option is @b{@t{noEcho}}, then keyboard 
input is not written to the display.

Specifying one of the soft-echo options disables automatic echo of keyboard 
input to the display, and then sorts the incomming keycodes into two main groups: 
graphing (printing) characters and non-printing control codes.

Graphing (printing) characters are written to the display in the usual way, but 
control codes are captured, and either converted to one of the @LDQ{}special@RDQ{} 
keys or discarded according to the selected soft-echo option.

@itemize @BSQUARE
@item softEchoA - All special keys are captured, decoded and available 
to the application, which can then interpret the keycode or discard it.@*
This is the default soft-echo option.
@item softEchoB - Basic set of special keys including the cursor keycodes, 
and the edit keycodes, but excludes the text-selection and clipboard-access 
keycodes.
@item softEchoC - Cursor keys only: UpArrow, DownArrow, LeftArrow, RightArrow,
Home, End, PageUp, PageDown, Tab and Shift+Tab.@*
@ifhtml
@verb{|         |}
@end ifhtml
(Edit keycodes are excluded.)@*
@item softEchoD - Disable (capture and discard) all special keycodes.@*
@item softEchoE - Edit keys Backspace, Delete, Insert, AltEnter, @emph{plus} 
Tab and Shift+Tab. (Cursor movement keycodes are discarded.)
@end itemize

See the next section for more information on the @LDQ{}special@RDQ{} keycodes.
@ifnothtml
@sp 1
@end ifnothtml

@indentedblock
@cindex special keys
@anchor{Decoding the Special Keys}
@Subsubheading{Decoding the @LDQ{}Special@RDQ{} Keys,
               ...........................}

The @LDQ{}special@RDQ{} keycodes consist of certain keycodes which are presented 
to a console application in the form of escape sequences. An escape sequence 
is a sequence of bytes beginning with the the escape character (0Bh). 
The number of bytes in an escape sequence varies from two bytes to seven bytes 
(or more on some systems).

Many keyboard keys are encoded in this way: the Function Keys, the Cursor 
Positioning keys, the Backspace/Delete/Insert keys, and most of the keycodes 
generated in combination with the so-called @emph{conditioning} keys: 
Shift, Control, Alt.

For a (nearly) complete list of keystrokes that generate escape sequences and 
the sequences they generate, please download the author's NcDialog API package 
and study the source files @t{NCursesKeyDef.hpp} and @t{NCursesKeyDef_auto.hpp}.

For the AnsiCmd library, only a subset of these escape sequences are 
captured and decoded. These include the @LDQ{}special@RDQ{} keys listed in 
the table below, as well as combination-keys discussed in the following sections:@*
@ref{ASCII Control Codes} and @ref{GUI Keys}.

@multitable {xxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxx} {xxxxxxxxxxxx}
@headitem @ Key Function @ @tab @ Esc Seq (hex) @ @tab @ Key Name @ @tab Glyph/Keycode
@item @ @ Up Arrow         @tab @ 1B 5B 41            @tab @ wcsUARROW  @tab @verb{|  ↑ |} 2091h
@item @ @ Down Arrow       @tab @ 1B 5B 42            @tab @ wcsDARROW  @tab @verb{|  ↓ |} 2093h
@item @ @ Right Arrow      @tab @ 1B 5B 43            @tab @ wcsRARROW  @tab @verb{|  → |} 2192h
@item @ @ Left Arrow       @tab @ 1B 5B 44            @tab @ wcsLARROW  @tab @verb{|  ← |} 2190h
@item @ @ Home Key         @tab @ 1B 5B 48            @tab @ wcsHOME    @tab @verb{|  ↖ |} 2196h
@item @ @ End Key          @tab @ 1B 5B 46            @tab @ wcsEND     @tab @verb{|  ↘ |} 2198h
@item @ @ Page Up          @tab @ 1B 5B 35 7E         @tab @ wcsPGUP    @tab @verb{|  ↗ |} 2197h
@item @ @ Page Down        @tab @ 1B 5B 36 7E         @tab @ wcsPGDN    @tab @verb{|  ↙ |} 2199h
@item @ @ Tab              @tab @ 09                  @tab @ wcsTAB     @tab @verb{|  ↱ |} 211Bh
@item @ @ Shift+Tab        @tab @ 1B 5B 5A            @tab @ wcsSTAB    @tab @verb{|  ↲ |} 21B2h
@item @ @ Backspace        @tab @ 7F                  @tab @ wcsBKSP    @tab @verb{|  ↰ |} 21B0h
@item @ @ Delete           @tab @ 1B 5B 33 7E         @tab @ wcsDELETE  @tab @verb{|  ↳ |} 21B3h
@item @ @ Insert           @tab @ 1B 5B 32 7E         @tab @ wcsINSERT  @tab @verb{|  ↥ |} 21A5h
@item @ @ Alt+Enter        @tab @ 1B 0A               @tab @ wcsAENTER  @tab @verb{|  ↧ |} 21A7h
@item @ @ Shift+Up         @tab @ 1B 5B 31 3B 32 41   @tab @ wcsSUP     @tab @verb{|  ↾ |} 21BEh
@item @ @ Shift+Down       @tab @ 1B 5B 31 3B 32 42   @tab @ wcsSDOWN   @tab @verb{|  ⇂ |} 21C2h
@item @ @ Shift+Right      @tab @ 1B 5B 31 3B 32 43   @tab @ wcsSRIGHT  @tab @verb{|  ⇀ |} 21C0h
@item @ @ Shift+Left       @tab @ 1B 5B 31 3B 32 44   @tab @ wcsSLEFT   @tab @verb{|  ↼ |} 21BCh
@item @ @ Shift+Home       @tab @ 1B 5B 31 3B 32 48   @tab @ wcsSHOME   @tab @verb{|  ⇇ |} 21C7h
@item @ @ Shift+End        @tab @ 1B 5B 31 3B 32 46   @tab @ wcsSEND    @tab @verb{|  ⇉ |} 21C9h
@item @ @ Ctrl+Home        @tab @ 1B 5B 31 3B 35 48   @tab @ wcsCHOME   @tab @verb{|  ⇈ |} 21C8h
@item @ @ Ctrl+End         @tab @ 1B 5B 31 3B 35 46   @tab @ wcsCEND    @tab @verb{|  ⇊ |} 21CAh
@item @ @ Ctrl+C           @tab @ 03                  @tab @ wcsCOPY    @tab @verb{|  ∽ |} 223Dh
@item @ @ Ctrl+X           @tab @ 18                  @tab @ wcsCUT     @tab @verb{|  ≒ |} 2252h
@item @ @ Ctrl+V           @tab @ 16                  @tab @ wcsPASTE   @tab @verb{|  ≐ |} 2250h
@item @ @ Ctrl+A           @tab @ 01                  @tab @ wcsSELECT  @tab @verb{|  ∻ |} 223Bh
@item @ @ Ctrl+Z           @tab @ 1A                  @tab @ wcsUNDO    @tab @verb{|  ≔ |} 2254h
@end multitable
@ifnothtml
@verb{|    *|} Note: Encoding of Backspace and Delete keys@*
@verb{|     |} are specified in terminal settings.
@end ifnothtml
@ifhtml
@html
<span style="font-size:80%; font-weight:bolder;">&nbsp;&nbsp;&nbsp;Note: Encoding of Backspace and Delete keys are specified in terminal settings.</span>
@end html
@end ifhtml

The Copy/Cut/Paste keys (@t{Ctrl+C, Ctrl+X, Ctrl+V}) and the other @t{ASCII} 
control codes are described below: 
@ifhtml
@*
@end ifhtml
(@pxref{ASCII Control Codes}).

Taken together, these keycodes comprise all the standard keycodes used to edit 
text within an individual field or on a form consisting of multiple fields.@*
Please @pxref{skForm Class} for a description of how these keycodes are 
interpreted within a form or a field.

Also, please @pxref{GUI Keys} for keycodes which are commonly used 
as user-interface commands.
@end indentedblock
@sp 2

@anchor{ASCII Control Codes}
@cindex ASCII codes
@cindex control codes
@Subheading{ASCII Control Codes,
            -------------------}

@t{ASCII} control codes are generated by pressing and holding either CTRL 
key and then pressing one of the alphabetic keys: @t{'a'} through @t{'z'}, 
@t{'A'} through @t{'Z'}, or @t{'4', '5', '6', '7'}.

@example
HEX BYTE    HEX BYTE    HEX BYTE    HEX BYTE
---------   ---------   ---------   ----------
01 Ctrl+A   0B Ctrl+K   15 Ctrl+U   1D Ctrl+5 (Ctrl+])
02 Ctrl+B   0C Ctrl+L   16 Ctrl+V   1E Ctrl+6 (Ctrl+^)
03 Ctrl+C   0E Ctrl+N   17 Ctrl+W   1F Ctrl+7 (Ctrl+_)
04 Ctrl+D   0F Ctrl+O   18 Ctrl+X
05 Ctrl+E   10 Ctrl+P   19 Ctrl+Y
06 Ctrl+F   12 Ctrl+R   1A Ctrl+Z
07 Ctrl+G   14 Ctrl+T

Exceptions:
08 Ctrl+H  Backspace, decoded as wcsBKSP (21B0h)
09 Ctrl+I  Tab,       decoded as wcsTAB  (21B1h)
0A Ctrl+J  Enter key i.e. newline
0D Ctrl+M  (reported as Ctrl+J, newline)
11 Ctrl+Q  Captured by the terminal (release terminal output)
           This signal is disabled when setting unbuffered input.
13 Ctrl+S  Captured by the terminal (pause terminal output)
           This signal is disabled when setting unbuffered input.
1A Ctrl+Z  This generates the SIGTSTP "Stop" signal which puts the
           current process to sleep. (wake using the 'fg' utility)
           This signal is captured and converted to wcsCTL_Z.
1B  ---    Escape
1C Ctrl+4  This generates the SIGQUIT "Quit" signal which kills the
           current application. This signal is captured and handled as
           if it were the break signal, implementing an orderly shutdown.
@end example

@c Ctrl+Alt+a through Ctrl+Alt+z support may be added in a later release.
@c Ctrl+Alt+ a-z and Ctrl+Alt+ A-Z sequences:
@c The following are reported as two-byte esccape sequences.
@c These codes are the same regardless of the state of the Shift key.
@c Ctrl+Alt+a (1B 01)  Ctrl+Alt+i (1B 09)  Ctrl+Alt+t (1B 14)
@c Ctrl+Alt+b (1B 02)  Ctrl+Alt+k (1B 0B)  Ctrl+Alt+u (1B 15)
@c Ctrl+Alt+d (1B 04)  Ctrl+Alt+l (1B 0C)  Ctrl+Alt+v (1B 16)
@c Ctrl+Alt+e (1B 05)  Ctrl+Alt+n (1B 0E)  Ctrl+Alt+w (1B 17)
@c Ctrl+Alt+f (1B 06)  Ctrl+Alt+o (1B 0F)  Ctrl+Alt+x (1B 18)
@c Ctrl+Alt+g (1B 07)  Ctrl+Alt+p (1B 10)  Ctrl+Alt+y (1B 19)
@c Ctrl+Alt+h (1B 08)  Ctrl+Alt+r (1B 12)
@c 
@c Unavailable sequences:
@c Ctrl+Alt+c  (same as Ctrl+C)
@c Ctrl+Alt+j  (same as wcsAENTER)
@c Ctrl+Alt+m  (same as wcsAENTER)
@c Ctrl+Alt+z  (same as Ctrl+z signal code)
@c Ctrl+Alt+q  (same as Ctrl+q signal)
@c Ctrl+Alt+s  (same as Ctrl+s signal)

Note that the Shift key is ignored when the CTRL key is pressed. 
Both the uppercase and lowercase alpha characters produce the same values, 
and the Ctrl+[4 | 5 | 6 | 7] produce the same values regardless of whether 
the Shift key is pressed. Examples:@*
@verb{|      Ctrl+a == Ctrl+Shift+A|}@*
@verb{|      Ctrl+5 == CTRL+Shift+5 ('%')|}

The Ctrl+C key @emph{should be} 0x03 in the sequence, but that code is tied 
to the Break Signal. To recapture Ctrl+C it is necessary for 
the break handler to capture the signal and push the code back into 
the input stream. The Break signal handler type @LDQ{}cchtCopy@RDQ{} 
performs this conversion.@*
Please @pxref{Capturing the Break Signal} for a discussion of 
capturing and re-purposing the break signal.@*
@xref{acCaptureBreakSignal} which implements the signal capture.

The @b{@t{Ctrl+Z}} key @emph{should be} 0x1A in the sequence, but that 
code is tied to the Suspend Signal. To recapture Ctrl+Z it is necessary for 
the suspend handler to capture the signal and push the code back into 
the input stream. The suspend signal handler performs this conversion.@*
@xref{acCaptureSuspendSignal} which implements the signal capture.

The @b{@t{Ctrl+4}} key @emph{should be} 0x1C in the sequence, but that 
code is tied to the Quit Signal (with core dump). To recapture Ctrl+4 
it is necessary for the quit handler to capture the signal and provide 
for an orderly termination of the application. (Ctrl+4 @emph{is not} 
associated with an application-level keycode.) Note that the @b{@t{Ctrl+\}} 
key combination is equivalent to Ctrl+4.@*
@xref{acCaptureQuitSignal} which implements the signal capture.

The @b{@t{Ctrl+S}} and @b{@t{Ctrl+Q}} keys @emph{should be} 0x13 and 0x11, 
respectively, but these codes are tied to the Pause/Resume output stream 
signals. At a terminal configuration level, the flow-control flag, @t{IXON} 
handles @t{stdout} flow control. This flag is automatically @b{@emph{reset}} 
when configuring the terminal for unbuffered input. This frees the Ctrl+S 
and Ctrl+Q key combinations for application-specific purposes.@*
Please @pxref{acBufferedInput} for additional information.

Certain Control-key combinations are reserved for use by the desktop 
environment or by the terminal emulator program. For instance, @t{Ctrl+PageUp} 
and @t{Ctrl+PageDown} are used to navigate among terminal tabs. Most of these 
so-called shortcut keys may be disabled in the terminal's preferences/settings 
page.
@sp 2

@anchor{GUI Keys}
@cindex GUI keys
@cindex Alt keys
@Subheading{The @t{GUI} Keys,
            ------------}

The @t{GUI} keys (Graphical User Interface keys) are keycodes that are commonly 
used by applications as command shortcut keys. These keycodes are generated 
by pressing one or more of the @LDQ{}conditioning keys@RDQ{} in combination 
with another key. The conditioning keys are the SHIFT key, the CONTROL keys 
and the left-side ALT key. 

With the exception of the @t{ASCII} control codes, these keycodes are reported 
to the application as escape sequences.

The @t{GUI} keycodes fall into these general categories:
@enumerate 1
@item Key combinations using the CTRL key and an alphanumeric key.@*
@t{  a-z and 4-7}@*
These combinations generate the ASCII control codes.@*
@item The SHIFT key in combination with one of the cursor navigation keys.@*
@t{  UpArrow, DownArrow, RightArrow, LeftArrow}@*
@item The left-side ALT key in combination with another key, @emph{or}@*
both ALT and SHIFT keys in combination with another key.@*
@t{  a-z and A-Z and punctuation characters:}@*
@t{  ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ @{ | @}}@*
@t{  UpArrow, DownArrow, RightArrow, LeftArrow, Home, End, PageUp, PageDown}@*
@item Both the CTRL and ALT keys in combination with another key.@*
@t{  a-z}@*
@i{Note that when using the CTRL key, the state of the SHIFT key 
is generally ignored by the keyboard controller.}
@item The Function Key group: F01-F12 alone or in combination with the 
SHIFT and/or CTRL conditioning keys. (ALT+Fnn combinations are not supported.)
@end enumerate

All key combinations which are captured are converted to constant values 
defined in @t{AnsiCmdDef.hpp}.

@quotation
@i{@b{Technical Notes:}@*
@minus{} To use key combinations, first press and hold the conditioning key(s), 
@ifnothtml
@* @ 
@end ifnothtml
@b{@emph{then}} press the other key, and release them all together.@*
@minus{} Note that by default, the right-side ALT key is configured for entering 
@ifnothtml
@ 
@end ifnothtml
keycodes that are not directly available from the keyboard.}
@end quotation

@sp 2


@anchor{TermSet Class}
@cindex TermSet class
@cindex class, TermSet
@cindex streams, i/o
@cindex i/o streams
@Subheading{TermSet Class,
            -------------}

The @t{TermSet} class encapsulates the low-level access to terminal-configuration 
options. The AnsiCmd class methods calls the @b{@emph{private}} TermSet object 
@w{(@t{'tset' member)}} for configuration options such as input buffering, 
input-echo options, cursor style, blocking vs. non-blocking input, flushing 
the @t{I/O} buffers and capture of the break signal (CTRL+C).

All methods and data members of the @t{TermSet} class are private, and are 
accessed only by the AnsiCmd @i{(or ACWin)} class. This ensures that there 
is only one point of access to the terminal configuration in order to avoid 
unfortunate configuration conflicts.

Although the functionality discussed here is not directly available to the 
application, it is interesting and educational to understand what is going 
on under the floorboards, so-to-speak.

The application may request a copy of the current terminal settings to 
verify that the terminal is configured as desired. The data consist of 
the bitfields defined in the C-language @t{termios} structure.@*
@xref{acGetTermInfo} for details.


@ifnothtml
@Subsubheading{Data Members,............}
@end ifnothtml
@ifhtml
@Subsubheading{@ @ @ @ @ @ Data Members,............}
@end ifhtml

@itemize @BDISC
@item @t{TermIos strOrig}@*
This is a copy of the @t{I/O} stream setting captured during application 
startup, when the AnsiCmd/TermSet classes are first instantiated. 

This data set is used to return the terminal settings to their original values 
when the application exits, i.e when the AnsiCmd/TermSet destructors are 
called.

Please @pxref{AnsiCmd constructor} for additional information.

@item @t{TermIos strMods}@*
This member contains data for the current terminal configuration. It is updated 
whenever the configuration is modified.@*
@ifhtml
@sp 1
@end ifhtml

@item @t{TermStream aStr}@*
This is the (virtual) file handle for the @LDQ{}active@RDQ{} (most recently 
modified) @t{I/O} stream. it is a member of enum TermStream, consisting of 
stdIn (stdin), stdOut (stdout) and stdErr (stdErr).@*
Note that stdErr is not referenced within the AnsiCmd/TermSet code, but is 
included for completeness.

As noted elsewhere (@pxref{Introductory Notes}), this has little practical 
value as a file handle because it references a @b{@emph{virtual file}} which 
manages all three streams as a unit.

@item @t{CurStyle curStyle}@*
The cursor style currently applied to the visible cursor. This is a member 
of enum CurStyle.

Please @pxref{S option} for specifying the cursor style as a command line 
option, and the @ref{TermConfig Class} for a detailed description of 
cursor styles.

@item @t{CCH_Type cchType}@*
This is a member of enum CCH_Type and specifies the type of 
@w{@b{C}ontrol_@b{C}_@b{H}andler} (break signal handler) currently in use.

Please @pxref{Capturing the Break Signal} for a discussion of the 
break-signal handlers built into the AnsiCmd library.

@item @t{EchoOpt inpEch}@*
This is a member of enum EchoOpt and specifies whether and how keyboard 
input is echoed (displayed) in the terminal window.

Please @pxref{Soft Echo Options} and @ref{TermConfig Class} for 
a discussion of input-echo options.

@item @t{bool inpBuf}@*
This flag indicates whether input buffering is currently enabled.@*
@b{@verb{|   true|}} == buffering enabled@*
@b{@verb{|  false|}} == buffering disabled

Please @pxref{B option} for specifying the input buffering option as 
a command line option, and the @ref{TermConfig Class} for a description
of input buffering.
@ifnothtml
@*
@end ifnothtml
See also, the @ref{acBufferedInput} method.

@item @t{bool inpBlk}@*
This flag indicates whether blocking read is active for the input stream.

The term @LDQ{}blocking read@RDQ{} refers to whether the execution thread 
should go to sleep while waiting for keyboard input. 

By default, blocking read is active, meaning that when the application 
requests keyboard input from the user (@pxref{acRead}), the execution 
thread goes into a hibernation state until the terminal signals that input 
is available in the buffer.

When blocking read is disabled, a request for user input will return the 
first keycode in the buffer, @b{@emph{or}} will @b{@emph{immediately}} 
return a @t{"WEOF"} (zero) if no data are available in the input buffer.

The AnsiCmd library uses non-blocking read primarily for receiving escape 
sequences from the terminal program and for flushing the input buffer. 
The @ref{acBlockingInput} method makes non-blocking input available 
in case the application needs similar functionality.@*
@b{@t{NOTE:}} This functionality can be dangerous, so use it wisely.

@item @t{bool cchAlert}@*
This flag indicates whether an audible @LDQ{}beep@RDQ{} is enabled to alert 
the user when the break signal (@t{CTRL+C)} has been received.

Please @pxref{Capturing the Break Signal}, and also the 
@ref{acCaptureBreakSignal} method for a discussion of the 
break-signal handlers.

@item @t{bool quitCap}@*
This flag indicates whether the Quit signal has been captured.@*
The Quit signal is generated by either the @t{Ctrl+4} key or @t{Ctrl+\} key 
combination.@*
@b{@verb{|   true|}} == signal has been captured and will be handled locally.@*
@b{@verb{|  false|}} == terminal handles the signal@*
@xref{acCaptureQuitSignal} method for further information.

@item @t{bool suspCap}@*
This flag indicates whether the Suspend signal has been captured.@*
The Suspend signal is generated by the @t{Ctrl+Z} key combination.@*
@b{@verb{|   true|}} == signal has been captured and will be handled locally.@*
@b{@verb{|  false|}} == terminal handles the signal@*
@xref{acCaptureSuspendSignal} method for further information.

@item @t{bool strCap}@*
This flag indicates whether the @t{'strOrig'} member (see above) has been 
initialized.@*
@b{@verb{|   true|}} == member initialized@*
@b{@verb{|  false|}} == member not initialized

@item @t{bool inpMod}@*
This flag indicates whether the @t{'strMods'} member (see above) has been 
initialized.@*
@b{@verb{|   true|}} == member initialized@*
@b{@verb{|  false|}} == member not initialized
@end itemize

For additional information on terminal configuration please refer to the 
documentation for the C-library functions: @t{tcgetattr, fcntl, signal} and the 
@t{termios} structure and related macro definitions defined in 
@t{termios.h and unistd.h}
@sp 2


@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.4.00 AnsiCmd Class Methods:  - - - - - - - - - - - - - - - - - - - - - - -
@c         Public methods and data members   - - - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node AnsiCmd Class Methods
@unnumbered AnsiCmd Class Methods
@cindex 03.4.00 AnsiCmd Class Methods
@cindex class, AnsiCmd

@menu
* Table of Public Methods::      _
* Configuration Methods::        _
* Color Attributes::             _
* Text Modifiers::               _
* Cursor Positioning::           _
* Input Methods::                _
* Output Methods::               _
* Text Erase::                   _
* Misc Methods::                 _
* API Methods::                  _
* Development Support::          _
* Coding Example::               _
@end menu
@ifnothtml
@sp 3
@end ifnothtml

@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@lowersections
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.4.01 Table of Public Methods:  - - - - - - - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Table of Public Methods
@unnumbered Table of Public Methods
@cindex 03.4.01 Table of Public Methods
@cindex list of methods
@cindex method list

The following is a list of AnsiCmd public methods, grouped by function.@*
Most public methods begin with the letters @LDQ{}ac@RDQ{} (Ansi Command).

The basic methods use @t{ANSI} escape sequences directly. Some of these 
methods use C-library function calls to perform terminal configuration.

A few methods are implemented at a higher abstraction level (API level). 
These are referred to in the documentation as Application-Program-Interface 
@t{API} methods. These methods typically do not use the @t{ANSI} escape 
sequences directly, but instead call a sequence of low-level (primitive) 
methods to provide a less cluttered interface between the application and 
the AnsiCmd library.

See also the @ref{ACWin Class} in the next chapter which provides a more 
sophisticated user interface whose functionality lies somewhere between the 
raw @t{ANSI} escape sequences and the dialog-oriented interface of the 
author's @b{@t{NcDialog API}}.@*
Please @pxref{By the Same Author} for more information.
@ifnothtml
@sp 1
@end ifnothtml

@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
@headitem @ Method Name                   @tab @ Description
@item @t{────} Configuration @t{──────}   @tab @t{ ─────────────────────────────────────────}
@item @ @ref{AnsiCmd constructor}         @tab @ Constructors
@item @ @ref{AnsiCmd destructor}          @tab @ Destructor
@item @ @ref{acGetTermSize}               @tab @ Calculate size of terminal window
@item @ @ref{acGetTermDimensions}         @tab @ Get a copy of stored terminal size
@item @ @ref{acGetTermInfo}               @tab @ Get current terminal configuration
@item @ @ref{acSetLocale}                 @tab @ Specify a non-default locale
@item @ @ref{acGetLocale}                 @tab @ Get current locale setting
@item @ @ref{acSetStreamWidth}            @tab @ Lock in wide or narrow I/O streams
@item @ @ref{acBufferedInput}             @tab @ Configure input-stream buffering
@item @ @ref{acSetEchoOption}             @tab @ Echo option (unbuffered input only)
@item @ @ref{acGetEchoOption}             @tab @ Report current echo option
@item @ @ref{acBlockingInput}             @tab @ Input blocking (unbuffered input only)
@item @ @ref{acCaptureSignals}            @tab @ Enable Ctrl+C Ctrl+4 Ctrl+Z signals
@item @ @ref{acReleaseSignals}            @tab @ Disable Ctrl+C Ctrl+4 Ctrl+Z signals
@item @ @ref{acCaptureBreakSignal}        @tab @ Enable/disable capture of Ctrl+C
@item @ @ref{acCaptureQuitSignal}         @tab @ Enable/disable capture of Ctrl+4
@item @ @ref{acCaptureSuspendSignal}      @tab @ Enable/disable capture of Ctrl+Z
@item @ @ref{acRestoreTermInfo}           @tab @ Set terminal configuration to defaults
@item @ @ref{breaksignalReceived}         @tab @ default break-signal handler
@item @ @ref{suspendsignalReceived}       @tab @ default suspend-signal handler
@item @ @ref{quitsignalReceived}          @tab @ default quit-signal handler
@item @                                   @tab @ 
@item @t{────} Color Attributes @t{───}   @tab @t{ ─────────────────────────────────────────}
@item @ @ref{acSetFg}                     @tab @ Set text foreground (3-bit, 4-bit, AIX)
@item @ @ref{acSetBg}                     @tab @ Set text background (3-bit, 4-bit, AIX)
@item @ @ref{acSetFgBg}                   @tab @ Set text fgnd and bkgnd (3/4-bit, AIX)
@item @ @ref{acSet8bitFg}                 @tab @ Set text foreground (8-bit color)
@item @ @ref{acSet8bitBg}                 @tab @ Set text background (8-bit color)
@item @ @ref{acSetRgbFg}                  @tab @ Set text foreground (r/g/b color)
@item @ @ref{acSetRgbBg}                  @tab @ Set text background (r/g/b color)
@item @ @ref{acSetWebFg}                  @tab @ Set text foreground (web-safe r/g/b)
@item @ @ref{acSetWebBg}                  @tab @ Set text background (web-safe r/g/b)
@item @ @ref{acSetGreyscaleFg}            @tab @ Set text foreground (greyscale)
@item @ @ref{acSetGreyscaleBg}            @tab @ Set text background (greyscale)
@item @ @ref{acReset}                     @tab @ Reset attributes and tracking data
@item @                                   @tab @ 
@item @t{────} Text Modifiers @t{─────}   @tab @t{ ─────────────────────────────────────────}
@item @ @ref{acSetMod}                    @tab @ Set or reset a text modifier
@item @ @ref{acResetMods}                 @tab @ Reset all text modifiers
@item @ @ref{acFullReset}                 @tab @ Reset all colors and text modifiers
@item @                                   @tab @ 
@item @t{───} Cursor Position @t{─────}   @tab @t{ ─────────────────────────────────────────}
@item @ @ref{acSetCursor}                 @tab @ Position the visible cursor
@item @ @ref{acGetCursor}                 @tab @ Get current cursor position
@item @ @ref{acSetCursorStyle}            @tab @ Specify cursor shape
@item @                                   @tab @ 
@item @t{─────} Input Methods @t{─────}   @tab @t{ ─────────────────────────────────────────}
@item @ @ref{acRead}                      @tab @ Read from stdin
@item @ @ref{acPause}                     @tab @ Read and discard next keystroke
@item @ @ref{acWait}                      @tab @ Pause for timeout or keystroke
@item @ @ref{acFlushIn}                   @tab @ Flush the input stream (stdin)
@item @                                   @tab @ 
@item @t{────} Output Methods @t{─────}   @tab @t{ ─────────────────────────────────────────}
@item @ @ref{acWrite}                     @tab @ Write formatted data to stdout
@item @ @ref{ttyWrite}                    @tab @ Write unformatted data (TTY style)
@item @ @ref{acFlushOut}                  @tab @ Flush the output stream (stdout)
@item @ @ref{acFlushStreams}              @tab @ Flush both input and output streams
@item @                                   @tab @ 
@item @t{────} Text Erase @t{─────────}   @tab @t{ ─────────────────────────────────────────}
@item @ @ref{acEraseArea}                 @tab @ Erase specified area of terminal window
@item @                                   @tab @ 
@item @t{────} Misc Methods @t{───────}   @tab @t{ ─────────────────────────────────────────}
@item @ @ref{acBeep}                      @tab @ Make some noise
@item @ @ref{nsleep}                      @tab @ Put thread to sleep
@item @ @ref{acVersion}                   @tab @ Get AnsiCmd class version number
@item @ @ref{acSetFont}                   @tab @ Seldom supported alternate font
@item @ @ref{acSetIdeogram}               @tab @ Seldom supported line drawing
@item @                                   @tab @ 
@item @t{────} API Methods @t{────────}   @tab @t{ ─────────────────────────────────────────}
@item @ @ref{acSetAttributes}             @tab @ Set bit-field color and text-mod data
@item @ @ref{acComposeAttributes}         @tab @ Encode bit-field color and text-mods
@item @ @ref{acGetAttributes}             @tab @ Get decoded bit-field color/text-mods
@item @ @ref{acClearScreen}               @tab @ Erase all data from terminal window
@item @ @ref{acClearArea}                 @tab @ Erase specified area of terminal window
@item @ @ref{acFormatParagraph}           @tab @ Automatic text formatting
@item @ @ref{acShellOut}                  @tab @ Temporarily return to shell program
@item @ @ref{acDrawLine}                  @tab @ Draw a horizontal or vertical line
@item @ @ref{acDrawBox}                   @tab @ Draw a rectangle in the terminal window
@item @ @ref{acEraseBox}                  @tab @ Erase a rectangular area of terminal
@item @ @ref{acBoxDraw}                   @tab @ Display an AC_Box object in terminal
@item @ @ref{acBoxErase}                  @tab @ Erase an AC_Box object from terminal
@item @ @ref{acBoxClear}                  @tab @ Clear the interior of an AC_Box object
@item @ @ref{isSpecialKey}                @tab @ Compare to list of special keycodes
@item @ @ref{isCommandKey}                @tab @ Compare to list of command keycodes
@item @ @ref{acCreateTemppath}            @tab @ Enable support for temporary files
@item @ @ref{acDeleteTemppath}            @tab @ Disable support for temporary files
@item @ @ref{acCreateTempfile}            @tab @ Create a temporary file
@item @ @ref{acDeleteTempfile}            @tab @ Delete a temporary file
@item @ @ref{acClipboardEnable}           @tab @ Establish communications with clipboard
@item @ @ref{acClipboardDisable}          @tab @ Terminate communications with clipboard
@item @ @ref{acClipboardTest}             @tab @ Test communications with clipboard
@item @ @ref{acClipboardGetText}          @tab @ Retrieve data from the clipboard
@item @ @ref{acClipboardSetText}          @tab @ Copy data to the clipboard
@item @ @ref{acClipboardCharCnt}          @tab @ Reports number of chars on clipboard
@item @ @ref{acClipboardByteCnt}          @tab @ Reports number of bytes on clipboard
@item @                                   @tab @ 
@item @t{──} Development Support @t{──}   @tab @t{ ─────────────────────────────────────────}
@item @ @ref{ansiTest}                    @tab @ Manage AnsiCmd library testing
@item @ @ref{getDataMembers}              @tab @ Get a copy of internal data members
@item @ @ref{getConfig}                   @tab @ Get a copy of terminal configuration
@item @ @ref{tseReport}                   @tab @ Report keycode processing
@end multitable
@sp 2

@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.4.02 Configuration Methods:  - - - - - - - - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Configuration Methods
@unnumbered Configuration Methods
@cindex 03.4.02 Configuration Methods
@cindex configuraton

@anchor{AnsiCmd constructor}
@cindex AnsiCmd constructor
@itemize @BSQUARE
@item @b{AnsiCmd ( void );}

@verbatim
  Input  : none

  Returns: implicitly returns a pointer to object
@end verbatim

Default Constructor: Terminal configuration parameters are set to default 
values.@*
Please @pxref{TermConfig Class} for details on default values.

The usefulness of the default constructor is miniscule, and possibly full 
of surprises for the programmer and the user alike. It is @b{@emph{strongly}} 
recommended that the initialization constructor (see below) be used for all 
non-trivial applications.
@spi

@item @b{AnsiCmd ( const TermConfig& tCfg );}
@verbatim
  Input  : tCfg : (by reference) terminal configuration parameters 

  Returns: implicitly returns a pointer to object
@end verbatim

Initialization Constructor: Terminal configuration parameters are passed 
in the TermConfig object.

Configuration options can be established directly by the application startup 
code, or if preferred, can be specified by the user as command-line options, 
@pxref{Invoking}.

Please @pxref{TermConfig Class} for details on parameter values passed 
to the constructor.

Programmer's Note: The AnsiCmd class should be instantiated before any data 
is sent to the terminal's output stream. This is because the first output 
may override any subsequent output-stream width designation for the current 
session. Note that the wide (32-bit character) stream is strongly recommended 
for all modern applications. The narrow stream is outdated due to its close 
ties to ASCII text (and to 1970).
@spi

@anchor{AnsiCmd destructor}
@cindex AnsiCmd destructor
@item @b{virtual ~AnsiCmd ( void );}
@verbatim
  Input  : none

  Returns: nothing
@end verbatim

Destructor. Return all resources to the system before exit.

The destructor is invoked either by deleting the object:@*
@b{@verb{|    AnsiCmd *ansicmdPtr = new AnsiCmd( termConfig );|}}@*
@b{@verb{|    delete ansicmdPtr;|}}@*
OR when the object goes out-of-scope.
@spi

@anchor{acGetTermSize}
@cindex acGetTermSize
@item @b{WinSize acGetTermSize ( void );}
@verbatim
  Input  : none

  Returns: current terminal dimensions in a WinSize object
@end verbatim

Returns the terminal dimensions in both character cells and pixels.

The WinSize structure is defined in @t{/usr/include/bits/ioctl-types.h}, 
and is one of the many system configuration parameters handled by the 
C-library @b{@t{ioctl}} function.
@verbatim
   struct winsize
   {
      unsigned short int ws_row;
      unsigned short int ws_col;
      unsigned short int ws_xpixel;
      unsigned short int ws_ypixel;
   };
@end verbatim

Note on terminal dimensions: Although the environment may contain the 
terminal dimensions when the application was invoked, this is a _copy_ of 
the environment, not the active environment, and therefore will not reflect 
user changes to the terminal window size while the application is active.

The @t{$LINES} and @t{$COLUMNS} are available from the environment at the 
command line (@LDQ{}@t{echo $LINES}@RDQ{} and @LDQ{}@t{echo $COLUMNS}@RDQ{}), 
but are not exported to programs running in the terminal window.

Note also that the pixel dimensions will probably be returned as zeros 
because under Wayland, the terminal program likely doesn't know the 
screen resolution.
@spi

@anchor{acGetTermDimensions}
@cindex acGetTermDimensions
@item @b{bool acGetTermDimensions ( short& rows, short& cols );}

@verbatim
  Input  : rows  : (by reference) receives number of terminal rows
           cols  : (by reference) receives number of terminal columns

  Returns: 'true'  if terminal dimensions are known
           'false' if system call to get terminal dimensions failed
@end verbatim

Reports the dimensions of the terminal window in rows and columns.
@spi

@anchor{acGetTermInfo}
@cindex acGetTermInfo
@item @b{bool acGetTermInfo ( TermStream tStream, }
@ifnothtml
@*@verb{|                    |}
@end ifnothtml
@b{TermIos& tIos, bool orig = false );}

@verbatim
  Input  : tStream : one of stdIn, stdOut, stdErr
           tios    : (by reference) receives settings
           orig    : (optional, 'false' by default)
                     'false': the current terminal settings are returned
                     'true' : the original terminal settings are returned

  Returns: 'true'  if settings captured
           'false' if system error
@end verbatim

Get a copy of the current terminal I/O stream configuration (or the 
original settings captured on application start-up).

This is a pass-through to the private TermSet method.

@i{(This method is primarily for development and debugging.)}

@example
Terminal I/O Setting structure (defined in C library, termios.h)

struct termios
@{
   tcflag_t c_iflag ;    /* input mode flags   */
   tcflag_t c_oflag ;    /* output mode flags  */
   tcflag_t c_cflag ;    /* control mode flags */
   tcflag_t c_lflag ;    /* local mode flags   */
   cc_t     c_line ;     /* line discipline    */
   cc_t     c_cc[NCCS] ; /* control characters */
@} ;

tcflag_t is an unsigned integer (uint16_t) bit-field type.
cc_t     is an unsigned integer type (uint8_t) representing characters
         associated with various terminal control functions.
'NCCS'   is a macro indicating the number of elements in the c_cc[] array.
         (this is 19 in /usr/include/asm-generic/termbits.h
@end example
@spi

@anchor{acSetLocale}
@cindex acSetLocale
@item @b{bool acSetLocale ( const char * localeName = NULL );}

@verbatim
  Input  : (optional, null pointer by default)
            If specified, pointer to name of UTF-8 compliant locale filename.
            If null pointer (or empty string: "\0"), set locale from terminal
            environment.

  Returns: 'true'
            Currently, we do not verify that 'localeName' is a valid UTF-8
            compliant locale filename.
@end verbatim

Set the "locale" for the application.@*
By default, the application locale is taken from terminal environment.

Type: @b{@t{echo $LANG}} at the command prompt to get the terminal's locale. 
If desired, an alternate locale may be specified.

For a complete listing of locales supported by your system, at the 
command prompt, type: @b{@t{locale -a}}
@spi

@anchor{acGetLocale}
@cindex acGetLocale
@item @b{const char* acGetLocale ( void );}

@verbatim
  Input  : none

  Returns: pointer to locale name
@end verbatim

Returns a pointer to the name of the current locale.
@spi

@anchor{acSetStreamWidth}
@cindex acSetStreamWidth
@item @b{bool acSetStreamWidth ( bool widechar );}

@verbatim
  Input  : widechar : select 'true' (wide stream) or 'false' (narrow stream)

  Returns: current state of character-width flag
@end verbatim

Set input/output streams' character width.@*
This determines which input/output streams will be used:
@example
wide stream: wcin/wcout
narrow stream: cin/cout
@end example

IMPORTANT NOTE: This method will have no effect if called after the 
@ifnothtml
@*@verb{|               |}
@end ifnothtml
application has performed I/O.@*
The first input or output performed by the application locks in the 
character-stream width used for the application.@*
C++ offers a way to set stream width directly (std::freopen), but it's 
better to get it right the first time.
@spi

@anchor{acBufferedInput}
@cindex acBufferedInput
@cindex buffered input
@cindex input, buffered
@item @b{bool acBufferedInput ( bool buffered, EchoOpt echoType, bool block = true );}

@verbatim
  Input  : buffered : if 'true',  enable input buffering by the terminal
                      if 'false', disable buffering and allow local control
                                  over the input stream
           echoType : member of enum EchoOpt:
                      referenced ONLY when 'buffered' == false
                      noEcho  : data from the stdin stream will not be echoed
                                to the terminal window
                      termEcho: terminal echoes all stdin data to the window
                      softEchoA, softEchoC, softEchoD, softEchoE:
                                terminal echo is disabled, but the acRead()
                                methods will echo PRINTING characters to the
                                terminal window according to the specific
                                soft-echo sub-option.
           block    : (optional, 'true' by default)
                      enable or disable blocking-read of input stream
                      referenced ONLY when 'buffered' == false
                      if 'true',  enable blocking read of stdin
                      if 'false', disable blocking read of stdin

  Returns: current state of the 'buffered-input' flag (inpBuf).
@end verbatim

Disable buffering so each keystroke can be received as soon as the key is 
pressed, or restore terminal's control over input buffering.

Normally, user input to the terminal (stdin) is buffered. That is, typed 
characters are stored in the terminal's private input buffer and are returned 
to the application only when the ENTER key is pressed.

In some circumstances, however, when a @w{@LDQ{}Press any key to continue...@RDQ{}} 
functionality is desired. Local control of the input buffer is also necessary 
when capturing ANSI sequences transmitted from the terminal in order to prevent 
cluttering the window with data which is meaningless to the user.@*
@xref{acRead} for additional info.

IMPORTANT NOTE: When buffering is enabled (buffered!=false), then the 
@t{'echoType'} and @t{'block'} parameters are ignored.
@itemize @EMDASH
@item When buffering is enabled, termEcho is always enabled.
@item When buffering is enabled, blocking read of input is always enabled. 
Consequently, if modifying the echo option (@ref{acSetEchoOption}) and/or 
the input-blocking option (@ref{acBlockingInput}), then input buffering 
must have been disabled.
@end itemize

@Subsubheading{Notes:,......}

@enumerate 1
@item The 'ICANON' flag actually controls whether the terminal references 
@t{'VTIME'} and @t{'VMIN'} and how those values are interpreted.
@item Buffering has no direct dependence on whether or not the characters 
are echoed when they arrive, and again, the 'ICANON' flag determines 
whether the terminal references the 'ECHO' flag'.
@item Traditionally (and logically) echo is disabled when buffering is 
disabled. However, we provide an option to keep echo active while 
buffering is disabled.
@item Echo should be disabled if the system is queried for a response in the 
form of an escape sequence (for instance, asking for the current cursor 
position). If echo is active, then it is likely that the printing 
characters in the the escape sequence will inappropriately be echoed 
to the screen.

To bake a cake and eat it too, see the soft-echo option.
@end enumerate
@spi

@anchor{acSetEchoOption}
@cindex acSetEchoOption
@item @b{bool acSetEchoOption ( EchoOpt echoType );}
@verbatim
  Input  : echoType: member of enum EchoOpt: 
                     noEcho   : data from the stdin stream will not be
                                echoed to the terminal window
                     termEcho : terminal echoes all stdin data to the window

                     For the soft-echo options, terminal echo is disabled,
                     and echo of input characters to the display is
                     handled locally by the acRead() methods which will
                     echo all PRINTING characters to the display, and
                     will decode the "special keys" (cursor keys, etc.)
                     according to the specific soft-echo sub-option.
                     softEchoA: all special keys (default soft-echo option)
                     softEchoB: basic set of special keys
                     softEchoC: cursor-movement keys only
                     softEchoD: disable all special keys
                     softEchoE: edit keys only: Backspace, Delete, Insert,
                                plus the Tab and Shift+Tab keys

  Returns: 'true'  if echo option modified
           'false' if input buffering currently enabled (or invalid type)
@end verbatim

Select the input character echo type. (enum EchoOpt).

Echo of user keyboard input (writing the received keycode to the display 
can be handled in a number of ways as listed above. The terminal can be 
allowed to decide what key input is echoed to the display, or the 
application can take control of key input to provide a smoother user interface.

The @LDQ{}soft-echo@RDQ{} options are available for customizing the 
user interface.@*
Please @pxref{Decoding the Special Keys} for more information on 
the soft-echo options.

This option is available ONLY when input buffering has been disabled. 
@ifnothtml
@*
@end ifnothtml
Please @pxref{acBufferedInput} method for additional information.
@spi

@anchor{acGetEchoOption}
@cindex acGetEchoOption
@item @b{EchoOpt acGetEchoOption ( void );}
@verbatim
  Input  : none

  Returns: current echo option: member of enum EchoOpt
@end verbatim

Get the current input-echo setting which describes how data from the input 
stream is processed.@*
@xref{TermConfig Class} for a discussion of input-stream configuration options.
@spi

@anchor{acBlockingInput}
@cindex acBlockingInput
@item @b{bool acBlockingInput ( bool block );}
@verbatim
  Input  : block : if 'true',  enable blocking read of input stream
                   if 'false', disable blocking read of input stream

  Returns: current state of the inpBlk flag
           'true'  == blocking-read of stdin
           'false' == non-blocking read of stdin
  Returns: 
@end verbatim

Enable or disable blocking read from the input stream (stdin).@*
This is a pass-through method for the TermSet function which sets/resets 
The blocking/non-blocking functionality.

IMPORTANT NOTE: Non-blocking input requires that unbuffered input be 
enabled. If not already enabled, unbuffered input (with 'noEcho') will 
be automatically enabled.
@spi

@anchor{acCaptureSignals}
@cindex acCaptureSignals
@item @b{bool acCaptureSignals ( EchoOpt eopt = softEchoA );}

@verbatim
  Input  : eopt  : (optional, softEchoA by default)
                    specify one of the soft-echo options (enum EchoOpt)

  Returns: 'true'  if all settings successful
           'false' if one or more settings failed
@end verbatim

Disable input buffering and capture all system signals generated by keyboard input.

This method is provided as a housekeeping convenience, performing a common 
sequence of terminal setup operations:
@enumerate 1
@item If input buffering has not yet been disabled, it will be disabled using 
the specified soft-echo option, and with non-blocking read of the input stream. 
@item The output flow control signals will be disabled.@*
The Ctrl+S (stop flow) and Ctrl+Q (resume flow) control codes become 
ordinary keycodes: wcsCTL_S and wcsCTL_Q, respectively.
@item The Break signal will be captured and converted to an ordinary keycode:@*
@verb{|   Break Signal  : SIGINT  - Ctrl+C|}  becomes wcsCTL_C
@item The Suspend signal will be captured and converted to an ordinary keycode:@*
@verb{|   Suspend Signal: SIGTSTP - Ctrl+Z|}  becomes wcsCTL_Z
@item The Quit signal will be captured so that the application will be 
terminated in an orderly manner.@*
@verb{|   Quit Signal : SIGQUIT - Ctrl+4|} performs an orderly application shutdown
@end enumerate
@format
Refer to the individual capture methods for details:
   acBufferedInput()
   acCaptureBreakSignal()
   acCaptureSuspendSignal()
   acCaptureQuitSignal()
@end format
@spi

@anchor{acReleaseSignals}
@cindex acReleaseSignals
@item @b{void acReleaseSignals ( void );}

@verbatim
  Input  : none

  Returns: nothing
@end verbatim

Release all captured signals. Return control to the terminal software.
@format
Releases the following signals:
   @t{1) Break Signal  : SIGINT  - Ctrl+C}
   @t{2) Suspend Signal: SIGTSTP - Ctrl+Z}
   @t{3) Quit Signal   : SIGQUIT - Ctrl+4}
@end format
@spi

@anchor{acCaptureBreakSignal}
@cindex acCaptureBreakSignal
@cindex breaksignalReceived
@item @b{bool acCaptureBreakSignal ( bool enable, CCH_Type handlerType,}
@ifnothtml
@*@verb{|                           |}
@end ifnothtml
@b{bool alert, void* handlerAddr = NULL );}

@verbatim
  Input  : enable : if 'true',  enable application capture of the break key
                    if 'false', disable application capture of the break key
                                terminal handles the break signal
           handlerType: (optional, cctDefault by default)
                        member of enum CCH_Type, specify the break-handler type.
           alert      : (optional, 'false' by default)
                        Referenced only when 'handlerType' == cchIgnore.
                        Optionally sound a beep when the break signal is
                        received and discarded.
                        if 'false', silently discard the break signal.
                        if 'true',  beep when discarding the break signal.
           handlerAddr: (optional, null pointer by default)
                        - by default, the internal AnsiCmd method,
                          BreakSignal_Handler() will provide an orderly response
                          to receipt of the break signal. See below for details.
                        - if the address of a handler method is specified, that
                          method will be activated by the break signal. That
                          method controls the response (if any) to the signal.
                          Note: The name of the target method is the address of
                                that method.
                        This argument is referenced only if 'enable' is set.

  Returns: current state of capture flag
           'true'  break key will be captured by the application
           'false' break key will be handled by the terminal program
@end verbatim

Enable or disable application-level capture and processing of the BREAK key 
@t{(CTRL+C)}.

By default, the terminal software processes the break signal by immediately 
killing the application which is running in the terminal window. 
While this is certainly an efficient and reliable way to terminate an 
application, it is grossly messy and potentially dangerous. For instance, 
what if the application is editing a critical system file when it is 
terminated in mid-update? Chaos.

In contrast, if the application itself captures the break signal, the 
application can shut down in an orderly manner, ask the user what to do, or 
simply ignore the break signal.
@hr40{}
When local capture of the break signal is active, by default, the signal 
will be handled by the default (non-member) method, BreakSignal_Handler().

The handler type is specified by the 'ccType' member variable which is 
initialized here.

@Subsubheading{Valid Handler Types:,
               ....................}
@itemize @BDISC
@item cchtIgnore: Ignore the Ctrl+C key (default, cctDefault)@*
Application will continue as if the signal had not been received.

@item cchtExit : Exit the application in an orderly way:
   @enumerate a
   @item the cursor will be placed on the bottom row of the terminal window 
   and the row will be cleared,
   @item the terminal bell will sound,
   @item a short message will be displayed, 
   @item the AnsiCmd destructor will be called, and
   @item the application will be terminated with a minus-one (-1) exit code.
   @end enumerate

@item cchtUser : Ask the user if they really want to exit the application:
   @enumerate a
   @item the terminal bell will sound,
   @item Clear a small area in the upper-right-hand corner of the 
   terminal window. (This is assumed to be the least cluttered, 
   least used area of the window.)
   @item Display a message asking the user to answer:@*
         @verb{|   Exit? 'y'es or 'n'o: _|}
   @item Wait for the user's response.
   @end enumerate

@item cchtCopy : Convert the break signal to an ordinary keycode (wcsCTL_C) 
which may then be used in the common copy-and-paste sequence: 
@w{@t{Ctrl+C --> Ctrl+V}.}

@item cchtTerm : Local handler is disabled, so the local handler is not called.
@end itemize
@spi

@anchor{acCaptureQuitSignal}
@cindex acCaptureQuitSignal
@item @b{bool acCaptureQuitSignal ( bool enable );}
@verbatim
  Input  : enable : if 'true',  enable application capture of the quit key
                    if 'false', disable application capture of the quit key
                                terminal handles the signal

  Returns: current state of capture flag
           'true'  quit key will be captured by the application
           'false' quit key will be handled by the terminal program
@end verbatim
Pressing the @b{@t{CTRL+4 key}} @i{(or the CTRL+\ key)} generates the 
system Quit signal. If the system receives the Quit signal, it will 
immediately terminate the application and generate a @LDQ{}core dump@RDQ{} file.

Core dump files are created in @w{@t{/var/lib/systemd/coredump}} by default. 
The format of the file should be ELF (Executable and Linkable) format, but 
could be an older format. An explanation of core dump files is beyond the 
scope of this document, but see the @t{'gdb'} (GNU Debugger) utility, which 
may be used to decode the contents of core-dump files.

The Quit Signal is captured by default during configuration of the 
AnsiCmd class and its derived classes. Then when the Quit signal is received, 
@b{@t{(CTRL+4 key)}} the application is shut down in an orderly manner, and 
a core dump @b{@emph{is not}} generated.@*
The local Quit signal handler deletes the temporary files, releases dynamic 
memory allocations and performs general housekeeping chores. Before exiting 
the application, the bottom two rows of the terminal window are cleared and 
a message is written indicating that the application has been terminated.@* 
After all, we're not just wild animals pooping in the forest. 
@ifnothtml
@*
@end ifnothtml
(well, most of us anyway :-)

@xref{Q option} for specifying this option as a command line parameter.

@i{@b{Technical Note:}@*
This signal is sometimes referred to as the Kill signal, but note that the 
Quit signal is technically different from the Kill signal in that the Kill 
signal cannot be captured or modified. It is an absolute command, and in 
fact, failure to respond to the Kill signal would be considered as a 
major system bug.}
@spi

@anchor{acCaptureSuspendSignal}
@cindex acCaptureSuspendSignal
@cindex Control_Z
@item @b{bool acCaptureSuspendSignal ( bool enable );}
@verbatim
  Input  : enable : if 'true',  enable application capture of the suspend key
                    if 'false', disable application capture of the suspend key
                                terminal handles the suspend signal

  Returns: current state of capture flag
           'true'  suspend key will be captured by the application
           'false' suspend key will be handled by the terminal program
@end verbatim

Enable or disable application-level capture and processing of the SUSPEND key CTRL+Z. Signal name: SIGTSTP.

If this signal is seen by the terminal program, it will suspend the active 
process. That is, it will put the process into the background and disable 
direct access to it. A different process may then occupy the foreground, 
interacting with the input and output streams.@*
Use the 'fg' utility to restore the hibernating process.

Because Ctrl+Z is often used as a command (undo) within an application, this 
signal is captured by default and converted to an ordinary keycode: wcsCTL_Z.
@spi

@anchor{acRestoreTermInfo}
@cindex acRestoreTermInfo
@item @b{bool acRestoreTermInfo ( bool restoreAll );}
@verbatim
  Input  : restoreAll : (optional, 'false' by default)
                        if 'false' this method restores input buffering,
                           input echo, and blocking-read settings only.
                           Break-handler, cursor style, and other terminal
                           configuration options are not affected.
                        if 'true',  all terminal setting under control of
                           the TermSet object will be returned to the states
                           when the object was instantiated. (see list below)

  Returns: 'true' if settings restored
           'false' if original settings not previously saved
                   or if system error
@end verbatim

Restore terminal stream settings to original values captured during the 
first access to the terminal settings. This probably occurred during 
creation of the TermSet-class object which is done as part of the 
AnsiCmd-class constructor sequence. The TermSet object manages the the 
current terminal settings. The settings restored depend on the state of 
the @t{'restoreAll'} flag, and include:

@enumerate a
@item Buffering of input stream.
@item Echo option (see enum EchoOpt).
@item Blocking vs. non-blocking read of input stream.
@item Disable local break-key handler, if active.
@item Set cursor style to terminal default.
@end enumerate
@spi

@anchor{breaksignalReceived}
@cindex breaksignalReceived
@item @b{void breaksignalReceived ( int sigNum );}
@verbatim
  Input  : sigNum: signal number to be handled
                   Currently, only the SIGINT (interrupt) is handled.
  Returns: nothing
@end verbatim

When the break signal has been captured, 
@ifnothtml
@*
@end ifnothtml
(@pxref{Capturing the Break Signal}), 
this method is called by a non-member method specified as the dedicated 
CTRL+C signal handler. The handler type is specified by the 'ccType' member 
variable which is set to one of the following:
@format
cchtIgnore: Ignore the Ctrl+C key (default, cctDefault)
cchtExit  : Exit the application in an orderly way.
cchtUser  : Ask the user if they really want to exit the application.
cchtCopy  : Push the literal value for Ctrl+C (0x03) back into the input stream.
cchtTerm  : Local handler is disabled, so this method is not called.
@end format
@center @t{─ ─ ─ ─ ─ ─ ─ ─ ─ ─}
This is technically a public method; however, it is called ONLY by the 
non-member method which handles receipt of the break-signal (CTRL+C).
@spi

@anchor{suspendsignalReceived}
@cindex suspendsignalReceived
@item @b{void suspendsignalReceived ( int sigNum );}
@verbatim
  Input  : sigNum: signal number to be handled
                   Currently, only the SIGSTP (suspend) is handled.
  Returns: nothing
@end verbatim

When the suspend signal has been captured, (@pxref{acCaptureSuspendSignal}), 
this method is called by a non-member method specified as the dedicated 
@t{CTRL+Z} signal handler.

This method captures the signal and converts it to an ordinary keycode: wcsCTL_Z.
@center @t{─ ─ ─ ─ ─ ─ ─ ─ ─ ─}
This is technically a public method; however, it is called ONLY by the 
non-member method which handles receipt of the suspend-signal (CTRL+Z).
@spi

@anchor{quitsignalReceived}
@cindex quitsignalReceived
@item @b{void quitsignalReceived ( int sigNum );}
@verbatim
  Input  : sigNum: signal number to be handled
                   Currently, only the SIGQUIT (quit) is handled.
  Returns: nothing
@end verbatim

When the quit signal has been captured, (@pxref{acCaptureQuitSignal}), 
this method is called by a non-member method specified as the dedicated 
@t{CTRL+4} signal handler. The handler will then perform an orderly shutdown 
of the application, returning all resources to the system.
@center @t{─ ─ ─ ─ ─ ─ ─ ─ ─ ─}
This is technically a public method; however, it is called ONLY by the 
non-member method which handles receipt of the quit-signal (CTRL+4 or CTRL+\).
@end itemize
@sp 2

@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.4.03 Color Attributes: - - - - - - - - - - - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Color Attributes
@unnumbered Color Attributes
@cindex 03.4.03 Color Attributes
@cindex color attributes
@cindex attributes, color

@anchor{acSetFg}
@cindex acSetFg
@itemize @BSQUARE
@item @b{bool acSetFg ( aeSeq fg );}
@verbatim
  Input  : fg   : foreground color attribute (member of aeSeq)

  Returns: 'true'  if valid color attributes specified and set
           'false' if invalid parameter(s) specified
                   (attributes will not be modified)
@end verbatim

Set text foreground color attribute (3-bit and 4-bit color).

This includes both the standard 3-bit and 4-bit attributes, as well as 
the non-standard IBM Corp. AIX extensions.

@cindex AIX extensions
@cindex IBM Aixterm
@cindex Aixterm, IBM
@display
@b{Note:}
The AIX color attributes were defined by IBM to provide interoperability 
of the terminal interface between their proprietary systems (Aixterm) 
and the Linux/UNIX world. Although these attributes are not part of the 
@t{ANSI} standard, they are widely supported and provide basic foreground 
and background colors using a slightly different (brighter) combination 
of Red/Green/Blue register values.

The differences are demonstrated in the color-attribute tests included 
with the AnsiCmd library.
@xref{Development and Testing} for more information.
@end display
@spi

@anchor{acSetBg}
@cindex acSetBg
@item @b{bool acSetBg ( aeSeq bg, bool synth );}
@verbatim
  Input  : bg   : background color attribute (member of aeSeq)
           synth: (optional, 'true' by default)
                  if 'true',  use synthesized background color attributes
                  if 'false', use standard ANSI background color attributes

  Returns: 'true'  if valid color attributes specified and set
           'false' if invalid parameter(s) specified
                   (attributes will not be modified)
@end verbatim

Set text background color attribute (3-bit and 4-bit color).

This includes both the standard 3-bit and 4-bit attributes, as well as the 
non-standard IBM Corp. AIX extensions.@*
(See note on AIX attributes, above.)

@indentedblock
@Subsubheading{Note on synthesis of intense background color attributes,
               ........................................................}

The default color attributes for intense (bold) backgrounds are inadequate
because the 
@ifhtml
@*
@end ifhtml
@t{'intense'} (@t{'bold'}) bit affects only the foreground color.

@LDQ{}Synthesized@RDQ{} bold backgrounds are used by default, which bypasses 
the 'bold' flag problem by 
@ifhtml
@*
@end ifhtml
using a member from the color lookup table which is outside the basic 
sixteen color (4-bit) group.
@end indentedblock
@spi

@anchor{acSetFgBg}
@cindex acSetFgBg
@item @b{bool acSetFgBg ( aeSeq fg, aeSeq bg );}
@verbatim
  Input  : fg   : foreground color attribute (member of aeSeq)
           bg   : background color attribute (member of aeSeq)

  Returns: 'true'  if valid color attributes specified and set
           'false' if invalid parameter(s) specified
                   (attributes will not be modified)
@end verbatim

Set text foreground AND background colors (3-bit and 4-bit color).

This includes both the standard 3-bit and 4-bit attributes, as well as the 
non-standard IBM Corp. AIX extensions.@*
(See note on AIX attributes, above.)

@ifnothtml
@verbatim
  ┌────────────────────────────────────────────────────────────────┐
  │ Programmer's Note: The foreground is set AFTER the background  │
  │ so that if the 'bold' flag is used in the foreground escape    │
  │ sequence, it will not be masked by a subsequent non-bold       │
  │ background.                                                    │
  │                                                                │
  │ Note also that bold background color escape sequences include  │
  │ the bold flag, but unfortunately, because of the way the       │
  │ terminal interprets this flag, it affects only the foreground  │
  │ attribute.                                                     │
  │                                                                │
  │ Exception: "synthesized" bold backgrounds are used by default, │
  │ which bypasses the 'bold' flag problem by using a different    │
  │ member from the color lookup table which is outside the basic  │
  │ sixteen (4-bit) color group.                                   │
  └────────────────────────────────────────────────────────────────┘
@end verbatim
@end ifnothtml
@ifhtml
@sp 1
@cartouche
Programmer's Note: The foreground is set AFTER the background so that if 
the @LSQ{}@b{bold}@RSQ{} flag is used in the foreground escape sequence, it will not be masked 
by a subsequent non-bold background.@*

Note also that bold background color escape sequences include the @LSQ{}@b{bold}@RSQ{} flag, 
but unfortunately, because of the way the terminal interprets this flag, it affects 
only the foreground attribute.@*

Exception: "synthesized" bold backgrounds are used by default, which bypasses 
the 'bold' flag problem by using a different member from the color lookup table 
which is outside the basic sixteen (4-bit) color group.
@end cartouche
@end ifhtml
@spi

@item @b{bool acSetFgBg ( acAttr fgbg );}
@verbatim
  Input  : 
     fgbg : foreground/background/modifiers 
            encoded as an acAttr bitfield

  Returns: 'true'
@end verbatim

Set text foreground/background colors using a value encoded as an 
acAttr bitfield value.@*
Although the acAttr group of color attribute bitfields is defined for use 
within the AnsiCmd API; this method allows for color attributes to be 
specified using these encoded bitfield attributes regardless of whether 
the API code is compiled into the library.

The specified value may be created directly as a logical OR of multiple 
members of the @LDQ{}@b{acAttr}@RDQ{} enumerated type.@*
Example: @t{acAttr( acaFG_GREEN | acaBG_BLACK | acaUNDERLINE)}

The bitfield value may also be built by a call to one of the acaExpand-class 
methods. @xref{acaExpand class}, for details.

@ifnothtml
@indentedblock
@verbatim
┌───────────────────────────────────────────────────────────┐
│ Note that this is a simplified version of the API method: │
│ 'acSetAttributes' which is preferred when the API methods │
│ are available.                                            │
│ This method should be used only if the library has been   │
│ compiled without the API method group.                    │
└───────────────────────────────────────────────────────────┘
@end verbatim
@end indentedblock
@end ifnothtml
@ifhtml
@CartHtml{@embedTOKEN{ai}Note that this is a simplified version of the API method: 'acSetAttributes', 
which is preferred when the API methods are available.
This method should be used only if the library has been compiled without the API method group.}
@end ifhtml
@sp 2


@anchor{acSet8bitFg}
@cindex acSet8bitFg
@item @b{bool acSet8bitFg ( uint8_t fg );}
@verbatim
  Input  : fg : index into the lookup table for 8-bit color attributes

  Returns: 'true'  if valid color attribute specified and set
           'false' if invalid parameter(s) specified
                   (attributes will not be modified)
@end verbatim

Set foreground color from 8-bit-color lookup table.@*
Select an index number between min8BIT through max8BIT (16-231).
@spi

@anchor{acSet8bitBg}
@cindex acSet8bitBg
@item @b{bool acSet8bitBg ( uint8_t bg );}
@verbatim
  Input  : bg : index into the lookup table for 8-bit color attributes

  Returns: 'true'  if valid color attribute specified and set
           'false' if invalid parameter(s) specified
                   (attributes will not be modified)
@end verbatim

Set background color from 8-bit-color lookup table.@*
Select an index number between min8BIT through max8BIT (16-231).
@spi

@anchor{acSetRgbFg}
@cindex acSetRgbFg
@item @b{bool acSetRgbFg ( uint8_t rReg, uint8_t gReg, uint8_t bReg );}
@verbatim
  Input  : rReg : red value
           gReg : green value
           bReg : blue value

  Returns: 'true'  if valid R/G/B registers specified and set
           'false' if specified parameters are out-of-range
                   (attribute will not be modified)
@end verbatim

Set foreground color using R/G/B register numbers.

Each of the basic Red, Green and Blue color attributes may be displayed 
in any of 216 shades, and the color values may be in any combination.

Each of the values may be specified as any register number between 
minRGB (16) and maxRGB (231).

Smaller values indicate less saturation (darker colors), and larger 
values indicate greater saturation (lighter, more intense colors).
If desired, the special value zero (0) may be used to indicate minimum 
saturation.
@spi

@anchor{acSetRgbBg}
@cindex acSetRgbBg
@item @b{bool acSetRgbBg ( uint8_t rReg, uint8_t gReg, uint8_t bReg );}
@verbatim
  Input  : rReg : red value
           gReg : green value
           bReg : blue value

  Returns: 'true'  if valid R/G/B registers specified and set
           'false' if specified parameters are out-of-range
                   (attribute will not be modified)
@end verbatim

Set background color using R/G/B register numbers.

Each of the basic Red, Green and Blue color attributes may be displayed 
in any of 216 shades, and the color values may be in any combination.

Each of the values may be specified as any register number between 
minRGB (16) and maxRGB (231).

Smaller values indicate less saturation (darker colors), and larger 
values indicate greater saturation (lighter, more intense colors).

If desired, the special value zero (0) may be used to indicate minimum 
saturation.
@spi

@anchor{acSetWebFg}
@cindex acSetWebFg
@item @b{bool acSetWebFg ( WebSafeRGB hue, uint8_t shade );}
@verbatim
  Input  : hue   : member of enum WebSafeRGB
                   wsrgbBLACK   : black color index
                   wsrgbRED     : base color index (red color block)
                   wsrgbGREEN   : base color index (green color block)
                   wsrgbBLUE    : base color index (blue color block)
                   wsrgbBROWN   : base color index (brown color block)
                   wsrgbMAGENTA : base color index (magenta color block)
                   wsrgbCYAN    : base color index (cyan color block)
                   wsrgbGREY    : base color index (grey color block)
                   Remaining members of WebSafeRGB are reserved for other
                   purposes.
           shade : intensity of the color specified by 'hue'
                   wsrgbSHADE_MIN <= shade <= wsrgbSHADE_MAX
                   where:
                   wsrgbSHADE_MIN == minimum saturation (subdued)
                   wsrgbSHADE_MAX == maximum saturation (brightest)

  Returns: 'true'  if valid hue and shade values specified
           'false' if specified parameters are out-of-range
                   (attribute not be modified)
@end verbatim

Set foreground color using "web-safe" R/G/B register value combinations.

@Subsubheading{What's a Web Safe? Spiderman's closet?,
               ......................................}

In the early days of the internet and using early versions of color display 
hardware, it was necessary to define a set of color attributes that could 
be reliably duplicated on any standard hardware with any of the early 
graphics-based web browsers. (Yes, we used to surf the web using text-only 
browsers; but you must remember that like Mister Spock, we were trying to 
build a mnemonic memory circuit using stone knives and bear skins.)

The solution was to create the so-called @LDQ{}web-safe@RDQ{} set of color 
attributes. This was done by creating a @w{6 x 6 x 6} matrix of Red/Green/Blue 
register values yielding 216 discrete colors. Conceptually, each color can 
take one of six hex values: @w{@t{00 33 66 99 CC FF}}. For each color, the 
actual index into the 256 entry color lookup table is selected according 
to this model. See @t{enum WebSafeRGB} for the way this mapping is done.

In the modern world of @LDQ{}true-color@RDQ{} computing, the idea of web-safe 
colors is a bit outdated, but it is still a valid concept in the simpler 
world of console applications, where we are limited to the palette specified 
by the terminal configuration.

Please @pxref{Development and Testing} for a fuller discussion of the 
color attributes available to console applications.
@spi

@anchor{acSetWebBg}
@cindex acSetWebBg
@item @b{bool acSetWebBg ( WebSafeRGB hue, uint8_t shade );}
@verbatim
  Input  : hue   : member of enum WebSafeRGB
                   wsrgbBLACK   : black color index
                   wsrgbRED     : base color index (red color block)
                   wsrgbGREEN   : base color index (green color block)
                   wsrgbBLUE    : base color index (blue color block)
                   wsrgbBROWN   : base color index (brown color block)
                   wsrgbMAGENTA : base color index (magenta color block)
                   wsrgbCYAN    : base color index (cyan color block)
                   wsrgbGREY    : base color index (grey color block)
                   Remaining members of WebSafeRGB are reserved for other
                   purposes.
           shade : intensity of the color specified by 'hue'
                   wsrgbSHADE_MIN <= shade <= wsrgbSHADE_MAX
                   where:
                   wsrgbSHADE_MIN == minimum saturation (subdued)
                   wsrgbSHADE_MAX == maximum saturation (brightest)

  Returns: 'true'  if valid hue and shade values specified
           'false' if specified parameters are out-of-range
                   (attribute not be modified)
@end verbatim

Set background color using "web-safe" R/G/B register value combinations.

@xref{acSetWebFg}, above for a description of @LDQ{}web-safe@RDQ{} colors.
@spi

@anchor{acSetGreyscaleFg}
@cindex acSetGreyscaleFg
@item @b{bool acSetGreyscaleFg ( uint8_t shade );}
@verbatim
  Input  : shade : brightness of grey color: minGSCALE <= shade <= maxGSCALE
                   example: acSetGreyscaleFg ( minGSCALE + 2 ) ;

  Returns: 'true'  if valid greyscale attribute specified and set
           'false' if invalid parameter(s) specified
                   (attributes will not be modified)
@end verbatim

Set Greyscale foreground color attribute. (background unchanged)

For systems that have at least 256 colors, 24 shades of greyscale intensity 
are available. 
@ifhtml
@*
@end ifhtml
These are accessed through indices 232-255 of the terminal's 
256-color lookup table.
@spi

@anchor{acSetGreyscaleBg}
@cindex acSetGreyscaleBg
@item @b{bool acSetGreyscaleBg ( uint8_t shade );}
@verbatim
  Input  : shade : brightness of grey color: minGSCALE <= shade <= maxGSCALE
                   example: acSetGreyscaleBg ( minGSCALE + 2 ) ;

  Returns: 'true'  if valid greyscale attribute specified and set
           'false' if invalid parameter(s) specified
                   (attributes will not be modified)
@end verbatim

Set Greyscale background color attribute. (foreground unchanged)

For systems that have at least 256 colors, 24 shades of greyscale intensity 
are available. 
@ifhtml
@*
@end ifhtml
These are accessed through indices 232-255 of the terminal's 
256-color lookup table.
@spi

@c @anchor{acSetAixFg}
@cindex acSetAixFg
@item @b{bool acSetAixFg ( aeSeq fg );}
@verbatim
  Input  : fg   : AIX foreground color attribute (member of aeSeq)

  Returns: 'true'  if valid color attributes specified and set
           'false' if invalid parameter(s) specified
                   (attributes will not be modified)
@end verbatim

NOTE: This method is obsolete. @xref{acSetFg}.
@spi

@c @anchor{acSetAixBg}
@cindex acSetAixBg
@item @b{bool acSetAixBg ( aeSeq bg );}
@verbatim
  Input  : bg   : AIX background color attribute (member of aeSeq)

  Returns: 'true'  if valid color attributes specified and set
           'false' if invalid parameter(s) specified
                   (attributes will not be modified)
@end verbatim

NOTE: This method is obsolete. @xref{acSetBg}.
@spi

@anchor{acReset}
@cindex acReset
@item @b{bool acReset ( void );}
@verbatim
  Input  : none

  Returns: 'true'
@end verbatim

Return all ANSI attributes to terminal defaults. Set all tracking members 
to their default values. Flush the input and output buffers.

This method does not modify the terminal configuration. It resets only 
the ANSI control environment as defined by the set of escape sequences.

Programmer's Note: It is not possible to programatically check whether 
each attribute was actually reset; however, the ANSI reset escape sequence 
should be trustworthy.
@end itemize
@sp 2

@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.4.04 Text Modifiers: - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Text Modifiers
@unnumbered Text Modifiers
@cindex 03.4.04 Text Modifiers
@cindex text modifiers
@cindex modifiers, text

@anchor{acSetMod}
@cindex acSetMod
@itemize @BSQUARE
@item @b{bool acSetMod ( aeSeq mod );}
@verbatim
  Input  : mod  : text modification attribute (member of aeSeq)

  Returns: 'true'  if valid modifier attributes specified and set
           'false' if invalid parameter(s) specified
                 (attributes will not be modified)
@end verbatim

Set or reset the specified text modifier.

Any text written after setting a modifier using this command will be displayed 
using the specified modifier (bold, italic, etc.). Any text written after 
resetting a modifier will be displayed @b{@emph{without}} the specified 
modifier.

See @ref{acResetMods} method below for a list of valid text modifiers.
@spi

@anchor{acResetMods}
@cindex acResetMods
@item @b{void acResetMods ( bool full );}
@verbatim
  Input  : full: (optional, 'false' by default)
                 if 'true',  write a reset command instead of writing 
                             the ANSI modifier-off sequences.
                             This option is available in case the host 
                             terminal does not support some or all of the 
                             modifier-off sequences.
                             NOTE: this ALSO resets the color attributes.
                 if 'false', write only the individual modifier commands,
                             do not write the reset command

  Returns: nothing
@end verbatim

Reset all text modifiers, leaving the base foreground and background color 
attributes unchanged.

The text modifier attributes are:
@c smallverbatim
@verbatim
  aesBOLD,          // bold (increase intensity)
  aesFAINT,         // faint/dim (decrease intensity)
  aesITALIC,        // italic (or inverse)
  aesUNDERLINE,     // underline
  aesBLINK_SLOW,    // slow blink
  aesBLINK_FAST,    // fast blink
  aesREVERSE,       // reverse foreground and background colors
  aesCONCEAL,       // hide text
  aesXOUT,          // crossed out text (marked for deletion)
  aesFRACTUR,       // a variety of German calligraphy
  aesDBL_UNDERLINE, // double-underline (or bold off)
  aesFRAMED,        // "frame" the text
  aesENCIRCLE,      // "encircle" the text
  aesOVERLINE,      // overlined text
@end verbatim

Calling this method is equivalent to calling acSetMod() nine times, 
once for each of the modifer resets.
@c smallverbatim
@verbatim
  aesBOLD_OFF,      // normal intensity (neither bold nor faint)
  aesITALIC_OFF,    // italic off (and Fractur off)
  aesUNDERLINE_OFF, // not underlined
  aesBLINK_OFF,     // not blinking
  aesREVERSE_OFF,   // not reversed
  aesCONCEAL_OFF,   // conceal off
  aesXOUT_OFF,      // not crossed out
  aesFRM_ENC_OFF,   // not framed, not encircled
  aesOVERLINE_OFF,  // overline off
@end verbatim
@spi

@anchor{acFullReset}
@cindex acFullReset
@item @b{bool acFullReset ( bool enable );}
@verbatim
  Input  : enable : 'true' to enable full reset for attribute modifications
                    'false' to disable full reset and rely upon the
                            setting/resetting the flag which controls the
                            specific attribute being modified

  Returns: current state of the full-reset flag
@end verbatim

Enable or disable reset of @b{@emph{all}} ANSI display attributes before 
modifying a text attribute.

The AnsiCmd class is constructed so that when modifying an ANSI parameter 
other parameters will be affected as little as possible. Specifically, 
when enabling or disabling an attribute such as Bold, Underline, etc., 
the intent is to avoid disturbing the existing forground and background 
color settings.

However, some console software or their underlying system software may 
not support all of the single-attribute commands such as aesBOLD_OFF, 
aesITALIC_OFF, aesUNDERLINE_OFF, aesBLINK_OFF aesREVERSE_OFF, 
aesCONCEAL_OFF, aesXOUT_OFF, aesFRM_ENC_OFF, aesOVERLINE_OFF, aesIDEO_OFF.

If these reset commands are not supported on a given platform, then set 
the 'fullReset' flag, and the AnsiCmd class will use the full reset 
command, aesRESET when changing terminal settings. The aesRESET command 
is supported by nearly all terminal emulators.

@xref{Invoking - Terminal Setup} (@t{-A option}) which enables the 
full-reset flag as part of the startup sequence.
@end itemize
@sp 2


@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.4.05 Cursor Positioning: - - - - - - - - - - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Cursor Positioning
@unnumbered Cursor Positioning
@cindex 03.4.05 Cursor Positioning
@cindex cursor position

@indentedblock
@anchor{cursor offsets}
@cindex cursor offsets
@cindex offsets, cursor
@Subsubheading{Important Note On Cursor Positioning,
               ....................................}
Cursor positions within a terminal window are always defined as 
@b{@emph{offsets}} from some reference position. In general, offsets 
are relative to the upper-left corner of the terminal window, also known 
as the @LDQ{}@b{origin}@RDQ{}.@*
The terminal window origin is defined as position @b{@t{1:1}} 
@i{(not the logically correct @t{0:0})}.

Unfortunately, the developers of terminal software and the authors of 
the @t{ANSI} commands and other utilities are not always on the same page 
regarding whether cursor offsets should be @t{0-based} or @t{1-based}. 
Be aware that a zero(0) value may be silently converted to a one(1) value, 
OR it may cause an operation to fail, or worse, produce unexpected results.

The AnsiCmd cursor-positioning methods will accept an @LDQ{}absolute@RDQ{} 
value of zero and silently convert it to a one(1). This prevents artifacts 
such as unexpected scrolling or pushing text out of the window. However, be 
aware that not all utilities are so user friendly. Be aware!
@end indentedblock

@anchor{acSetCursor}
@cindex acSetCursor
@itemize @BSQUARE
@item @b{bool AnsiCmd::acSetCursor ( aeSeq curcmd, short arga, short argb ) const;}
@verbatim
  Input  : curcmd: one of the members of the cursor-positioning group which
                   are included in enum aeSeq.
                   Example: acSetCursor ( aesCUR_HOME ) ;
           arga  : (optional, 1 by default)
                   for options which require arguments, 'arga' specifies the
                   first argument.
                   Example: acSetCursor ( aesCUR_ABSCOL, 30 ) ;
           argb  : (optional, 1 by default)
                   for options which require arguments, 'argb' specifies the
                   second argument.
                   Example: acSetCursor ( aesCUR_ABSPOS, 12, 60 ) ;

  Returns: 'true'  if valid cursor command (and valid arguments, if required)
           'false' if invalid parameter(s) specified
                   (position will not be modified)
@end verbatim

Set cursor position within terminal window.

Some ANSI cursor commands perform cursor movements relative to the current 
position, while other commands set the cursor at an absolute position within 
the terminal window.

@xref{cursor offsets} above regarding 1-based vs. 0-based cursor positioning.

This method invokes the specified @t{ANSI} escape sequence directly; however, 
there are two variations on this method, described below, which may also 
be used to set the cursor position. Please choose the one that best suits 
your needs.

@ifnothtml
@quotation NOTE
One member of the cursor-positioning group: aesCUR_REPORT,@*
is not handled by this method. Instead please @ref{acGetCursor}.@*
If aesCUR_REPORT is received, it will be ignored and 'false' will@*
be returned to indicate that the request was not handled.

Also:@*
Digital Equipment Corporation (DEC) and the SCO Group (UnixWare)@* 
defined some of the cursor-management commands differently.@*
On our test systems, the SCO commands work correctly, while@*
the DEC commands do not. Your mileage may vary.
@end quotation
@end ifnothtml
@ifhtml
@quotation NOTE
One member of the cursor-positioning group: aesCUR_REPORT, is not 
handled by this method.@*
Instead please see @ref{acGetCursor}. If aesCUR_REPORT is received, it will be 
ignored and 'false' will be@*
returned to indicate that the request was not handled.

@b{Also:}@*
Digital Equipment Corporation (DEC) and the SCO Group (UnixWare) 
defined some of the@*
cursor-management commands differently. On our test systems, the 
SCO commands work correctly,@*
while the DEC commands do not. Your mileage may vary.
@end quotation
@end ifhtml
@spi

@item @b{bool AnsiCmd::acSetCursor ( short row, short col ) const;}
@item @b{bool AnsiCmd::acSetCursor ( const WinPos& wp ) const;}
@verbatim
  Input  : One of the following:
              row : target row 
              col : target column
           or:
              wp  : (by reference) target row and column

  Returns: 'true'  if specified row/column are within the terminal window
           'false' if invalid position (cursor position not modified)
@end verbatim

Set absolute cursor position within terminal window.

These methods reformat the parameters and call the low-level acSetCursor 
method described above.
@spi

@anchor{acGetCursor}
@cindex acGetCursor
@item @b{WinPos acGetCursor ( void ) const;}
@verbatim
  Input  : none

  Returns: an initialized WinPos object
           (If system error or parsing error, window origin is returned.)
@end verbatim

Get the current cursor position within terminal window.

@Subsubheading{Technical Notes,...............}

This method requires that input buffering be disabled and that input echo 
be set to 'noEcho'. The reason for this is that when buffering is active, 
the response from the terminal will not become available to the 
application until the Enter key is detected in the input stream.@*
In addition, echo of input characters to the terminal window must also 
be disabled because when the system writes the response to the position 
query, it is written to stdin, which if echo were enabled would likely 
trash the currently-displayed text, or at minimum would move the cursor, 
causing a big surprise at the application level. While setting and 
restoring the buffering/echo options is an expensive operation in terms 
of CPU cycles, it is necessary for smooth operation at the application level.

@verbatim
-- Write the ANSI sequence requesting the current cursor position.
-- Read the response (binary data) from stdin.
-- Decode the response which is of the form: 1B 5B (row) 3B (col) 52
     1B       escape character
     5B       left square bracket
     row      one or more ASCII numeric chars indicating row number
     3B       ';' (ASCII semicolon)
     col      one or more ASCII nummeric chars indicating column number
     52       ASCII 'R'
@end verbatim
@spi

@anchor{acSetCursorStyle}
@cindex acSetCursorStyle
@item @b{bool acSetCursorStyle ( CurStyle style, aeSeq color );}
@verbatim
  Input  : style : member of enum CurStyle
           color : (optional, default from terminal profile)
                   member of aeSeq, foreground attribute group: aesFG_xxx
                   color attribute for cursor [CURRENTLY IGNORED]

  Returns: 'true' if valid argument(s), else 'false'
@end verbatim

Set cursor type i.e. the shape of the cursor.

Three basic cursor shapes are available in either a steady state or blinking:@*
@verb{| Block:'█'  Underline:'▁'  Vertical Bar:'▎'|}

In addition, the cursor can be made invisible. The style is specified as 
a member of @w{@b{@t{enum CurStyle}}} which is the parameter for 
the escape sequence to be transmitted. 
@ifnothtml
@*
@end ifnothtml
(Note that cursor style settings are not part of the @t{ANSI} standard.)

@verbatim
  csBblock = 0,  // Full-character cell, blinking block
  csDflt   = 1,  // Cursor type defined by terminal configuration
  csSblock = 2,  // Full-character cell, steady (non-blinking) block
  csBuline = 3,  // Blinking underline
  csSuline = 4,  // Steady underline
  csBvbar  = 5,  // Blinking vertical bar
  csSvbar  = 6,  // Steady vertical bar
  csHide   = 7,  // Hide cursor (make it invisible)
  csShow   = 8,  // Show cursor (make it visible)
@end verbatim

@cindex blink timeout
@cindex timeout, blink
@ifnothtml
@verbatim
  ┌─────────────────────────────────────────────────────────────────────┐
  │ Note on cursor blink timeout:                                       │
  │ Although the cursor shape and blinking/steady status can be         │
  │ specified using this method, the terminal settings specify a        │
  │ timeout on the blinking status. For instance, the Gnometerm         │
  │ terminal emulator specifies a default timeout on the cursor's       │
  │ blink status of ten(10) seconds. This timeout can be adjusted       │
  │ using the @LDQ{}@b{gsettings}@RDQ{} utility. Example:               │
  │ Get current settings:                                               │
  │   gsettings get org.gnome.desktop.interface cursor-blink-timeout    │
  │ Report the range of valid values:                                   │
  │   gsettings range org.gnome.desktop.interface cursor-blink-timeout  │
  │ Set a new timeout of 25 seconds:                                    │
  │   gsettings set org.gnome.desktop.interface cursor-blink-timeout 25 │
  └─────────────────────────────────────────────────────────────────────┘
@end verbatim
@end ifnothtml
@ifhtml
@cartouche
@i{@b{Note on cursor blink timeout:}}
Although the cursor shape and blinking/steady status can be specified using 
this method, the terminal settings specify a timeout on the blinking status.
For instance, the Gnometerm terminal emulator specifies a default timeout 
on the cursor's blink status of ten(10) seconds. This timeout can be adjusted 
using the @LDQ{}@b{gsettings}@RDQ{} utility. Example:
Get current settings:
@ @ @ gsettings get org.gnome.desktop.interface cursor-blink-timeout
Report the range of valid values:
@ @ @ gsettings range org.gnome.desktop.interface cursor-blink-timeout
Set a new timeout of 25 seconds:
@ @ @ gsettings set org.gnome.desktop.interface cursor-blink-timeout 25
@end cartouche
@end ifhtml

@i{Note: The cursor color attribute is automatically set by the terminal to 
the same color as the text. Theoretically, the @t{"gsettings"} utility and 
other utilities can also be used to set the cursor color, but early testing 
shows that such commands are ignored. Testing continues.}
@end itemize
@sp 2


@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.4.06 Input Methods:  - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Input Methods
@unnumbered Input Methods
@cindex 03.4.06 Input Methods
@cindex input methods

@anchor{acRead}
@cindex acRead
@itemize @BSQUARE
@item @b{short acRead ( gString& gsIn, short limit ) const;}
@verbatim
  Input  : gsIn  : (by reference) receives captured text (null terminated)
           limit : (optional, size of gString object by default)
                   If specified, 'limit' indicates the maximum number of
                   characters (wide-stream input) OR the maximum number of
                   bytes (narrow-stream input) that will be extracted from
                   the stdin buffer.
                   Important Note: This argument is referenced only when
                   unbuffered input is active. This argument is ignored
                   when input-stream buffering is enabled.

  Returns: number of characters captured (NOT the number of bytes)
@end verbatim

Capture user input as a sequence of characters terminated by the Enter key, 
OR when input buffering is disabled @emph{and} the number of characters 
specified by the @t{'limit'} parameter has been reached.

Internally, this method loops a call to the single-character @t{acRead} 
(see below). The called method contains most of the intelligence of the 
operation.

@Subsubheading{Note on capture of the Enter key,................................}
@itemize @EMDASH
@item If the Enter key is the first and only keycode captured, the Enter 
keycode is returned and the character count returned will be one(1).

@item If the input is terminated by the Enter key, the characters captured 
@b{@emph{before}} the Enter key are returned. The Enter keycode will not be 
returned and is not included in the character total.
@end itemize

Please @pxref{Soft Echo Options} for a discussion of when and how key 
input is echoed to the display.
@spi

@item @b{wchar_t @ acRead ( void ) const;}
@verbatim
  Input  : none

  Returns: keycode from user
@end verbatim

Capture a single keystroke from the user.

The functionality of this method is dependent upon three factors:@*
@verb{| 1) |}Whether input buffering is enabled,@*
@verb{|    |}(@pxref{acBufferedInput})@*
@verb{| 2) |}The active input echo option,@*
@verb{|    |}(@pxref{Soft Echo Options})@*
@verb{| 3) |}Whether input is configured for blocking or non-blocking read.@*
@verb{|    |}(@pxref{acBlockingInput})@*
Please study these options carefully and configure the input stream according 
to the needs of your application. A good place to start would be with 
@w{1) unbuffered input,} @w{2) softEchoA,} and @w{3) blocking read}.
@spi

@anchor{acPause}
@cindex acPause
@item @b{wchar_t acPause ( bool nl = false ) const;}
@verbatim
  Input  : nl : (optional, default: false)
                if 'true',  after user keypress, output a newline character
                if 'false', no output will be written to display

  Returns: keycode from user
@end verbatim

Wait for user to press a key. This is an unbuffered read, with no echo of 
the keycode to the display. Typically, this method would be used after the 
application displays a 'press any key' or similar message.

The optional @t{'nl'} parameter may be used to write a newline character 
@t{(NEWLINE (0x000A)} to the display after the user presses any key. This 
will move the cursor to the leftmost column of the next row. This option 
should be used only when the application is writing directly to the 
terminal window, and not when formatted (ACWin-class) data are being displayed.
@ifnothtml
@sp 2
@end ifnothtml

@b{Technical Note:} After the keycode is received, the input stream is flushed, 
that is, any data remaining in the input buffer is read and discarded. 
This is done to protect against stale data being left in the buffer 
in case the key pressed by the user generates an escape sequence or 
another multi-byte sequence. If the initial keycode received is the Escape 
keycode @t{(0x001B)}, the keycode for the space key @t{wcsSPACE (0x0020)} will 
be returned instead.

@spi

@anchor{acWait}
@cindex acWait
@item @b{void acWait ( uint16_t seconds ) const;}
@verbatim
  Input  :
     seconds : specifies the sleep interval in seconds (1 minute max)
               0 <= seconds <= 60

  Returns: nothing
@end verbatim

Pause for a specified amount of time OR until user presses a key.@*
This can be thought of as a combination of the @t{acPause} and 
@t{nsleep} methods.

The specified delay is broken into segments and after each delay segment, 
the input stream is pinged to determine whether user has pressed a key.@*
The pause continues until either the full pause interval is complete, or 
until user presses any key, whichever comes first.

Any keycode received is discarded, and before return, the input stream is 
flushed to avoid abandoning any stale data in the input stream.
@spi

@anchor{acFlushIn}
@cindex acFlushIn
@item @b{void acFlushIn ( void ) const;}
@verbatim
  Input  : none

  Returns: nothing
@end verbatim

Flush stdin, (the active input stream, wcin or cin).@*
Any data still in the input stream will be discarded.

@Subsubheading{Note On Performance,...................}
Flushing the input buffer relies on an @b{@emph{unbuffered}} input stream 
to reliably extract the stale data from the stream. If input buffering is 
enabled when this method is called, this method disables buffering before 
the flush and re-enables buffering after the flush.@*
While this is effective, it does produce a small performance hit. 
For this reason, it is recommended that unless there is a clear reason 
to do otherwise, the application should disable input buffering during 
startup and then re-enable buffering just before exit.@*
Please @pxref{acBufferedInput} for more information.

See also @ref{acFlushStreams}, below.
@end itemize
@sp 2


@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.4.07 Output Methods:   - - - - - - - - - - - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Output Methods
@unnumbered Output Methods
@cindex 03.4.07 Output Methods
@cindex output methods

@anchor{acWrite}
@cindex acWrite
@itemize @BSQUARE
@item @b{WinPos @ acWrite ( WinPos wp, const gString& gsTxt, }
@ifnothtml
@*@verb{|                 |}
@end ifnothtml
@b{bool flush = true ) const;}

@item @b{WinPos @ acWrite ( short row, short col, const gString& gsTxt, }
@ifnothtml
@*@verb{|                 |}
@end ifnothtml
@b{bool flush = true ) const;}

@item @b{WinPos @ acWrite ( WinPos wp, const wchar_t* wTxt, }
@ifnothtml
@*@verb{|                 |}
@end ifnothtml
@b{bool flush = true ) const;}

@item @b{WinPos @ acWrite ( short row, short col, const wchar_t* wTxt, }
@ifnothtml
@*@verb{|                 |}
@end ifnothtml
@b{bool flush = true ) const;}

@item @b{WinPos @ acWrite ( WinPos wp, const char* cTxt, }
@ifnothtml
@*@verb{|                 |}
@end ifnothtml
@b{bool flush = true ) const;}

@item @b{WinPos @ acWrite ( WinPos wp, wchar_t wchar, }
@ifnothtml
@*@verb{|                 |}
@end ifnothtml
@b{bool flush = true ) const;}

@item @b{WinPos @ acWrite ( short row, short col, wchar_t wchar, }
@ifnothtml
@*@verb{|                 |}
@end ifnothtml
@b{bool flush = true ) const;}

@item @b{WinPos @ acWrite ( WinPos wp, char cbyte, bool flush, bool newln ) const;}

@item @b{WinPos @ acWrite ( short row, short col, char cbyte, }
@ifnothtml
@*@verb{|                 |}
@end ifnothtml
@b{bool flush = true ) const;}

@verbatim
  Input  : starting cursor position in one of the following formats:
              wp    : a WinPos object (by reference)
                    OR
              row   : target row
              col   : target column

           text data to be written in one of the following formats:
              gsTxt : (by reference) a gString object
                    OR
              wTxt  : a wchar_t string (32-bit characters)
                    OR
              cTxt  : a char (byte) string
                    OR
              wchar : a single wchar_t (wide) character
                    OR
              cbyte : a single byte

           flush : (optional, default: 'true')
                   if 'true,   flush the output buffer before return
                   if 'false', do not flush the output buffer

  Returns: current cursor position (WinPos object)
@end verbatim

Write text data to @t{stdout} beginning at the specified cursor position. 
The final cursor position is at the end of the output. This is the return value.

@indentedblock
@ifnothtml
@verbatim
┌──────────────────────────────────────────────────────┐
│ This method is not reliable for writing ANSI escape  │
│ sequences and ASCII control codes. For these special │
│ cases, use the 'ttyWrite' method below.              │
└──────────────────────────────────────────────────────┘
@end verbatim
@end ifnothtml
@ifhtml
@indentedblock
@CartHtml{@embedTOKEN{ai}This method is not reliable for writing ANSI escape sequences and ASCII 
control codes. For these special cases, use the @t{'@b{ttyWrite}'} method below.}
@end indentedblock
@end ifhtml
@end indentedblock

The primary difference between this method and traditional TTY-style output 
is that @b{@emph{newline} (@t{'\n'})} characters are handled as a special case. 
When a newline character is encountered in the output stream, it causes the 
cursor to be placed on the next row at the @b{@emph{same column}} as 
the first column of the previous row. This automatic formatting allows the 
application to write formatted paragraph data without the painful task of 
having to count columns. @w{(@LDQ{}You'll thank me later.@RDQ{} --- Adrian Monk)}

This method is actually a group of overloaded methods which provide flexibility 
in the way parameters are passed.

Cursor position may be specified either as a WinPos object or as seperate 
row and column values.

The source text may be formatted as:
@enumerate
@item a gString object,
@item a wchar_t (UTF-32) character array,
@item a char (UTF-8) character array, or
@item a single character
@end enumerate

By default, the output buffer is flushed after all data have been written. 
This is equivalent to the C++ sequence:@*
@b{@verb{|   wcout << "text_data" ;|}}@*
@b{@verb{|   wcout.flush() ;|}}@*
However, flushing the output buffer is a slow operation (relatively speaking), 
so if multiple writes are performed in sequence, it is more efficient to 
flush the stream only once, after the last write of the sequence. For example, 
the following sequence writes three text strings, each in a different color, 
with the @t{'flush'} flag set (default value) for the last write.@*
@b{@verb{|   WinPos wp( 4, 30 ) ;|}}@*
@b{@verb{|   acSetFg ( aesFG_RED ) ;|}}@*
@b{@verb{|   wp = acWrite ( wp, "Red textdata.\n", false ) ;|}}@*
@b{@verb{|   acSetFg ( aesFG_BLUE ) ;|}}@*
@b{@verb{|   wp = acWrite ( wp, "Blue text data.\n", false ) ;|}}@*
@b{@verb{|   acSetFg ( aesFG_GREEN ) ;|}}@*
@b{@verb{|   wp = acWrite ( wp, "Green text data.\n" ) ;|}}@*

Note that this method is aware of the terminal window dimensions.
@enumerate a
@item Text rows which would overrun the right edge of the terminal window are 
truncated, 
@ifhtml
@*
@end ifhtml
that is, automatic line wrap does not occur.
@item Text data that would overrun the bottom edge of the terminal window 
will be ignored. 
@ifhtml
@*
@end ifhtml
Scrolling of the window contents @b{@emph{WILL NOT}} occur.
@end enumerate

If automatic scrolling or automatic line wrap are desired, then call 
the @ref{ttyWrite} method instead.

Note that the width of the output stream (wide or narrow stream) is 
established during the application startup sequence; therefore, regardless 
of the width of the source data, it will be transmitted using the established 
stream width.@*
Please @pxref{acSetStreamWidth}, or the 
@ifnothtml
@*
@end ifnothtml
@ref{W option} command-line option for more information on stream 
configuration.
@spi

@anchor{ttyWrite}
@cindex ttyWrite
@item @b{void @ ttyWrite ( const gString& gsTxt, 
@ifnothtml
@*@verb{|                |}
@end ifnothtml
bool flush = true, bool nl = false ) const;}
@item @b{void @ ttyWrite ( const wchar_t* wTxt, 
@ifnothtml
@*@verb{|                |}
@end ifnothtml
bool flush = true, bool nl = false ) const;}
@item @b{void @ ttyWrite ( const char* cTxt, 
@ifnothtml
@*@verb{|                |}
@end ifnothtml
bool flush = true, bool nl = false ) const;}
@item @b{void @ ttyWrite ( const uint_8* uTxt, 
@ifnothtml
@*@verb{|                |}
@end ifnothtml
bool flush = true, bool nl = false ) const;}
@item @b{void @ ttyWrite ( wchar_t wchar, 
@ifnothtml
@*@verb{|                |}
@end ifnothtml
bool flush = true, bool nl = false ) const;}
@item @b{void @ ttyWrite ( char cbyte, 
@ifnothtml
@*@verb{|                |}
@end ifnothtml
bool flush = true, bool nl = false ) const;}

@verbatim
  Input  : text data to be written in one of the following formats:
              gsTxt : (by reference) a gString object
                    OR
              wTxt  : a wchar_t string (32-bit characters)
                    OR
              cTxt  : a char (byte) string
                    OR
              uTxt  : a UTF-8 (byte) string
                    OR
              wchar : a single UTF-32 character
                    OR
              cbyte : a single byte (generally: an ASCII control code)
           flush : (optional, 'true' by default)
                   if 'true,   flush the output buffer before return
                   if 'false', do not flush the output buffer
           nl    : (optional, default: 'false')
                   append a newline character to the output

  Returns: nothing
@end verbatim

Write text data (or ANSI sequence) to stdout beginning at the current 
cursor position. This emulates the action of a teletype machine (TTY).@*
(If you don't know what a teletype machine is, your grandparents will 
explain it to you.)

Any newline characters encountered will cause the cursor to be positioned 
on the first (leftmost) column of the line below, and if on the last line 
in the window, all data will be scrolled upward.@*
Text will automatically wrap at the right edge of the window.

This method is actually a group of overloaded methods which provide flexibility 
in the way parameters are passed. The source text may be formatted as 
@enumerate 1
@item a gString object,
@item a wchar_t (UTF-32) character array,
@item a char (UTF-8) character array, or
@item a single character
@end enumerate

By default, the output buffer is flushed after all data have been written. 
This is equivalent to the C++ sequence:@*
@b{@verb{|   wcout << "text_data" ;|}}@*
@b{@verb{|   wcout.flush() ;|}}@*
However, flushing the output buffer is a slow operation (relatively speaking), 
so if multiple writes are performed in sequence, it is more efficient to 
flush the stream only once, after the last write of the sequence. For example, 
the following sequence writes three text strings, each in a different color, 
with the @t{'flush'} flag set (default value) for the last write.@*
@b{@verb{|   acSetCursor ( 4, 1 ) ;|}}@*
@b{@verb{|   acSetFg ( aesFG_RED ) ;|}}@*
@b{@verb{|   ttyWrite ( "Red textdata.\n", false ) ;|}}@*
@b{@verb{|   acSetFg ( aesFG_BLUE ) ;|}}@*
@b{@verb{|   ttyWrite ( "Blue text data.\n", false ) ;|}}@*
@b{@verb{|   acSetFg ( aesFG_GREEN ) ;|}}@*
@b{@verb{|   ttyWrite ( "Green text data.\n" ) ;|}}@*

Note that the width of the output stream (wide or narrow stream) is 
established during the application startup sequence; therefore, regardless 
of the width of the source data, it will be transmitted using the established 
stream width.@*
Please @pxref{acSetStreamWidth}, or the 
@ifnothtml
@*
@end ifnothtml
@ref{W option} command-line option for more information on stream 
configuration.
@spi

@anchor{acFlushOut}
@cindex acFlushOut
@item @b{void acFlushOut ( void ) const;}

@verbatim
  Input  : none

  Returns: nothing
@end verbatim

Flush stdout, (the active output stream, wcout or cout).@*
Any data still in the output stream will be written to the terminal window.

Note that the output methods @ref{acWrite} and @ref{ttyWrite} 
by default, flush the output stream at the end of each write. The @t{acFlushOut} 
method may be used to explicitly flush the data from the stream.

See also @ref{acFlushStreams}, below.
@spi

@anchor{acFlushStreams}
@cindex acFlushStreams
@item @b{void acFlushStreams ( void ) const;}
@verbatim
  Input  : none

  Returns: nothing
@end verbatim

Flush (write) any data in the @t{stdout} stream and discard an stale 
data in the @t{stdin} stream.

This method combines calls to @ref{acFlushIn} and @ref{acFlushOut} 
as described above.

@i{@b{Technical Note:} Although every effort has been made to clear the 
@t{I/O} buffers as needed, transmission and receipt of @t{ANSI} escape 
sequences can be interrupted or broken, causing display artifacts or 
other problems. Explicitly flushing the buffers at critical moments can 
help to reduce such accidents.}
@end itemize
@sp 2


@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.4.08 Text Erase:   - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Text Erase
@unnumbered Text Erase
@cindex 03.4.08 Text Erase
@cindex text erase
@cindex erase, text

@anchor{acEraseArea}
@cindex acEraseArea
@itemize @BSQUARE
@item @b{bool acEraseArea ( aeSeq area, short rowOff, short colOff );}
@verbatim
  Input  : cur   : one of the members of the text-erasure group within
                   enum aeSeq.
                   example: acEraseArea ( aesERASE_WIN ) ;
           rowOff: (optional, ZERO by default) If a non-zero value is
                   specified, the cursor will be shifted upward (negative
                   values) or downward (positive values) from the current
                   cursor position before the erasure occurs.
           colOff: (optional, ZERO by default) If a non-zero value is
                   specified, the cursor will be shifted leftward (negative
                   values) or rightward (positive values) from the current
                   cursor position before the erasure occurs.

  Returns: 'true' if successful
           'false' if invalid parameter(s) specified
@end verbatim

Erase the specified area of the terminal window.@*
The area to be erased is specified by one of the ANSI erasure commands.@*
@verb{|  aesERASE_BOW,   //|} erase from cursor to bottom of window@*
@verb{|  aesERASE_TOW,   //|} erase from cursor to top of window@*
@verb{|  aesERASE_WIN,   //|} erase entire window ('clear')@*
@verb{|  aesERASE_SAVED, //|} erase "saved" lines@*
@verb{|  aesERASE_EOL,   //|} erase from cursor to end of line@*
@verb{|  aesERASE_BOL,   //|} erase from cursor to beginning of line@*
@verb{|  aesERASE_LINE,  //|} erase entire line@*
The specified erasure is performed relative to the current cursor position 
UNLESS an offset is specified:@*
@verb{|  rowOff :|} row offset from current row@*
@verb{|  colOff :|} column offset from current column@*
Important Note: If the specified offset moves the cursor beyond the 
edge of the terminal window, unexpected side-effects may occur.

See also the direct erasure method, @ref{acClearArea}.
@end itemize
@sp 2


@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.4.09 Misc Methods  - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Misc Methods
@unnumbered Misc Methods
@cindex 03.4.09 Misc Methods
@cindex misc methods

@anchor{acBeep}
@cindex acBeep
@itemize @BSQUARE
@item @b{void AnsiCmd::acBeep ( short repeat, short delay, int freq ) const;}
@verbatim
  Input  : repeat : (optional, 1 by default) repeat count
                    Range: 1 - 32,767
           delay  : (optional, 5 by default i.e. 1/2 second)
                    delay between successive beeps in tenths of a second
                    in the range: 2 - 600 (0.2sec through 1.0min)
                    Note: The system is unable to handle short delays, so
                          a delay of two-tenths second is the safe minimum.
           freq   : (optional, -1 by default)
                    if specified, this is the auditory frequency of the beep
                    [CURRENTLY IGNORED]

  Returns: nothing
@end verbatim

Invoke the console's default auditory alert (beep).

When called without parameters, the @t{acBeep} method produces a single 
beep (or whatever sound your terminal is set up to produce when the 
@t{ASCII Bell} control code is received.

Three optional parameters are available: @t{'repeat', 'delay', and freq'} 
as shown above. 

The @b{@t{repeat}} parameter is straightforward, specifying the number 
of individual beeps to produce from 1 (default) to 32,767, although we 
can attest that anything over about 200 will cause everyone in your 
household to toss the nearest loose object in your direction.

The @b{@t{delay}} parameter specifies the (approximate) pause between beeps.
The quality and repeatability of the tone is heavily dependent upon the 
delay between beeps. This is because the the actual physical timer used and 
the system code which controls it are both shared resources.@*
The delay interval may be specified as a multiple of 0.10 (1 tenth) second, 
with the default being 0.5 (5 tenths) second, and the maximum being one 
minute (600 tenths). For a stable repeatable sound, the @b{@emph{practical}} 
minimum is two or three tenths (0.2 - 0.3) of a second.

The @b{@t{freq}} parameter specifies the frequency of the tone that will 
be produced. For the current (pre)release, this parameter is ignored, and the 
tone is produced by simply issuing the @t{ASCII Bell} control code.@*
For the production release, however, we hope to implement a more robust and 
flexible sound control.
@spi

@anchor{nsleep}
@cindex nsleep
@item @b{void AnsiCmd::nsleep ( uint16_t tenths, uint16_t millisec,} 
@ifnothtml
@*@verb{|      |}
@end ifnothtml
@b{time_t nanosec ) const;}

@verbatim
  Input  : tenths  : specifies the sleep interval in tenths of a second
                     (1/10 sec == 0.10 sec)
           millisec: (optional, zero by default) for finer control over the
                     length of the delay, specify a delay in milliseconds.
           nanosec : (optional, zero by default) for even finer control over
                     the length of the delay, specify a delay in nanoseconds.
                     [CURRENTLY IGNORED]

  Returns: nothing
@end verbatim

Sleep (pause) execution for the specified time period. This method 
encapsulates access to the C-language @b{@t{'nanosleep'}} function. 
It is intended to simplify the the interface and replaces direct calls to 
the obsolete C-language @t{sleep} and @t{usleep} functions.

The primary delay value is specified in tenths of a second (0.10sec), with 
a secondary delay specification in milliseconds (0.001sec).
The sum of the two values specifies the total duration of the delay.@*
Thus the effective minimum delay is 1 millisecond, while the theoretical 
maximum delay is: 65535/10 or 6553 minutes + 65535 milliseconds or 
approximately 6618 minutes.This is an impractically large number, so we 
arbitrarily limit the maximum delay to 61 minutes, which is approximately 
60 minutes more than anyone will likely ever need.@*
@verb{|              1 millisecond <= delay <= 61.0 minutes|}@*
Note that the @t{'nanosec'} parameter is currently ignored. (see tech notes below)

The philosophy here is that delays of less than one tenth of a second are 
not very useful for a human interface, while smaller delays are oriented 
toward computer-oriented tasks and which are limited only by the resolution 
of the clock referenced by the called function.

@ifnothtml
@sp 1
@end ifnothtml
@cindex chrono
@cindex sleep_for
@cindex nanosleep
@Subsubheading{Technical Notes,.............}

In C++, the cosmopolitan way to delay the action is to use the @t{'chrono'} 
class to define the delay, and the @t{'sleep_for'} 
@ifhtml
@*
@end ifhtml
method to execute it.@*
@verb{|Example: chrono::duration<short>aWhile( 10 );|}@*
@verb{|         this_thread::sleep_for( aWhile );|}@*
@verb{|Example: chrono::duration<short, std::milli>aMoment( 250 );|}@*
@verb{|         this_thread::sleep_for( aMoment );|}@*
The @t{chrono/sleep_for} C++ implementation is much cleaner and more 
intuitive than nanosleep(); however, @t{ANSI} escape sequences are by 
definition incompatible with multi-threaded environments, so we do 
not introduce multi-threading in the AnsiCmd class.@*
Instead, we use the @t{'nanosleep'} function which is technically 
sophisticated, but clunky in implementation. That is why we isolate it 
here to avoid cluttering up our otherwise lovely code.

The @b{@t{nanosleep}} C-library function is defined in @t{time.h} and 
takes as parameters two @t{'timespec'} structures as shown.

@example
#include <time.h>
struct timespec
@{
   time_t tv_sec ;  /* seconds */
   long   tv_nsec ; /* nanoseconds */
@};
nanosleep ( const struct timespec *req, struct timespec *rem ) ;
@end example

The first parameter @t{'req'} (the @LSQ{}request@RSQ{}) specifies the 
duration of the sleep interval in seconds and nanoseconds. Note that 
the @t{nanosleep} function rounds the nanosecond value @t{('tv_nsec')} 
upward to the resolution of the clock. Note also that the @t{('tv_nsec')} 
value is limited to 9,000,000,000 (nine billion nanoseconds). Any larger 
value will generate an error.

If the requested interval is completed without interruption, the second 
parameter @t{('rem')} (the @LSQ{}remainder@RSQ{}) remains unused. 
If however, the sleep interval is interrupted by some system event, then 
the second parameter receives the remainder of the delay so that 
@t{nanosleep} can be called again to complete the specified sleep interval.

The resolution of the clock used for this interval is also a significant 
factor in the accuracy of the operation.@*
It is important to keep in mind that although @t{nanosleep} claims to 
be accurate in the nanosecond range, a number of factors may affect 
the results. For instance, the default Linux scheduler is based on 
ten-millisecond intervals, so sequential calls may be limited to 
this resolution. Some newer systems with newer kernel support may 
be able to provide a resolution of one(1) millisecond.

See the documentation for the C-library @t{'clock_getres'} function for 
more information on the clocks available on the host system.@*
See also: @t{"man 7 time"}, which indicates that the @b{@emph{effective}} 
resolution is between 1 and 10 milliseconds.@*
Also see the resolutions specified in the file: @t{"/proc/timer_list"}. 
Most of the entries in that file specify a resolution of 1 nanosecond, 
but we see this as more aspirational, than mathematical.

While the @t{nanosleep} function cannot be relied upon by timing-critical 
operations which may be affected by these factors, for user-oriented delays, 
into the tens-of--milliseconds range, however, the @t{nanosleep} function 
is a welcome addition to the C-language library.
@spi

@anchor{acVersion}
@cindex acVersion
@item @b{const char * acVersion ( void ) const;}
@verbatim
  Input  : none

  Returns: pointer to version string
@end verbatim

This method return a const pointer to a string containing the AnsiCmd class 
version number. The version number takes the form: @w{@t{x.y.zz}}, where 
@t{'x'} is the major version, @t{'y'} is the minor version and @t{'zz'} 
is the step version.@*
Example: @t{0.0.03}

Unlike some other developers whom we will politely not name @i{(Firefox)}, 
this author does not advance the major or minor version number without a 
very good reason. Therefore, even packages we have had in circulation 
for twenty years seldom advance beyond version @t{0.2.00}. For instance, 
the @t{gString class} distributed with package, which we first released 
in 2011 is now at version @t{0.0.32}, and yes, it is absolutely solid.
@spi

@anchor{acSetFont}
@cindex acSetFont
@item @b{bool AnsiCmd::acSetFont ( aeSeq font, uint8_t fontnum );}
@verbatim
  Input  : font   : one of aesPRIMARY_FONT or aesALTERNATE_FONT which are
                    members of enum eSeq.
           fontnum: (optional, zero(0) by default)
                    specify the alternate font, range: 1 through 9

  Returns: 'true'  if valid greyscale attribute specified and set
           'false' if invalid parameter(s) specified
                   (attributes will not be modified)
@end verbatim

Specify the terminal font used to write subsequent text data.

Specify the @t{'font'} parameter as a member of enum aeSeq:@*
@example
@b{aesPRIMARY_FONT}   set the primary font as the active font
                  ('fontnum' parameter is ignored)
@b{aesALTERNATE_FONT} set one of the alternate fonts as the active font
      USER#   1  2  3  4  5  6  7  8  9  translates to:
      ANSI#  11 12 13 14 15 16 17 18 19
@end example

These commands are not recognized on any of our development platforms, 
but the font test is available for testing them on your particular system: 
(@pxref{Test_AltFonts}).
@spi

@anchor{acSetIdeogram}
@cindex acSetIdeogram
@item @b{bool acSetIdeogram ( aeSeq idea );}
@verbatim
  Input  : idea  : member of enum aeSeq within the ideogram-command group.

  Returns: 'true'  if valid argument
           'false' if invalid parameter(s) specified
                   (attribute will not be modified)
@end verbatim

Interface to the seldom-supported and little-used "ideogram" (logogram) 
group of @t{ANSI} commands.

It is unclear what this group of commands was originally intended to do. 
Presumably they were intended to provide some kind of border or 
highlighting around a block of text.@*
@verb{|  aesIDEO_UNDER       //|} ideogram underlined@*
@verb{|  aesIDEO_UDOUBLE     //|} ideogram double-underlined@*
@verb{|  aesIDEO_OVER        //|} ideogram overlined@*
@verb{|  aesIDEO_ODOUBLE     //|} ideogram double-overlined@*
@verb{|  aesIDEO_STRESS      //|} ideogram stress marking (italic?)@*
@verb{|  aesIDEO_OFF         //|} all ideogram attributes off@*
These are probably non-functional, but they can be tested using this method.

@xref{acDrawBox} and @ref{acDrawLine} methods for line drawing options.
@end itemize
@sp 2


@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.4.10 API Methods:  - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node API Methods
@unnumbered API Methods
@cindex 03.4.10 API Methods
@cindex api methods

The @t{API} (Application Programming Interface) methods are designed to 
encapsulate some of the more common operations performed as a sequence of 
calls to the low-level primitive methods. Using the @t{API} methods 
reduces code clutter at the application level, which will hopefully 
reduce development and debugging time for the application.

@b{@ref{Color Attribute Methods}}@*
The most significant difference between the @t{ANSI} primitives and the 
@t{API} layer is the way color attributes are encoded. While the terminal 
emulator program interprets the @t{ANSI} escape sequences to set color 
attributes and text modifiers, it is rather inconvenient to work with them 
directly. Internally, the @t{AnsiCmd} library encodes color attributes as 
32-bit bit fields.@*
@verb{|   |} @ref{List of Attribute Names}@*
@verb{|   |} @ref{Attribute Bitfield Definitions}

@b{@ref{Display Formatting Methods}}@*
Erase the current data displayed in the specified area of the terminal 
window, or format text paragraph data to fit within a specified area.

@b{@ref{Line Drawing Methods}}@*
Draw horizontal and vertical lines or draw rectangles in the terminal window.

@b{@ref{Identify "Special" Keycodes}}@*
Identify whether a given keycode matches one of the defined @LDQ{}special@RDQ{} 
or @LDQ{}command-key@RDQ{} keycodes.

@b{@ref{Temporary File Management}}@*
Create and manage temporary files for useby the application.

@b{@ref{Communicate With System Clipboard}}@*
Establish a communications channel with the system clipboard and exchange 
text data with the clipboard.@*
@verb{|   |} @ref{AnsiCmd Clipboard Access}

@hr40

@c - - - Subheading  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@anchor{Color Attribute Methods} @c ===== Sub-Group =====
@anchor{acSetAttributes}
@cindex acSetAttributes
@Subsubheading{Color Attribute Methods,
               .......................}

@itemize @BSQUARE
@item @b{bool AnsiCmd::acSetAttributes ( acAttr newAttr, bool resetAll = false );}

@verbatim
  Input  : newAttr : bitfield containing the logical OR of the desired
                     foreground/background attributes and text modifiers.
           resetAll: (optional, 'false' by default)
                     if 'false', only the the attributes specified by
                                 'newAttr' will be modified.
                     if 'true',  all attributes and modifiers will be reset
                                 to their default values before the new
                                 attributes are applied.

  Returns: 'true' if successful, else 'false' (currently always 'true')
@end verbatim

Modify or replace the current color attributes and/or text modifiers.

The basic group of AnsiCmd methods set or reset one attribute per call by 
issuing the corresponding @t{ANSI} escape sequence designated as a member 
of @t{enum aeSeq} (@b{a}nsi @b{e}scape @b{Seq}uence). The @t{acSetAttributes} 
method, by contrast, takes as a parameter the @b{@emph{logical OR}} of 
an arbitrary number of attributes designated as members of @t{enum acAttr} 
(@b{a}nsi @b{c}md @b{Attr}ibute). Arguably, this provides a cleaner interface 
between the application layer and the display-formatting functionality.

The individual @t{enum acAttr} members are @t{OR'd} together to produce 
the @t{'newAttr'} parameter sent to @t{acSetAttributes}.

The examples below demonstrate how a @b{@t{logical OR of acAttr values}} 
specifies the attribute(s) to be modified.

Note that when performing any mathematical operation using members of an 
enumerated type such as @t{enum acAttr}, the compiler will complain. 
For instance, when performing a @t{logical OR} using members of @t{enum acAttr}, 
the compiler insists that the result be cast back into the @t{acAttr} type. 
For example, the compiler will complain about this assigment:@*
@b{@verb{!   acAttr newAttr = acaFG_BLUE | acaBG_GREEN ;!}}@*
so to make the compiler happy we perform a cast back to the type:@*
@b{@verb{!   acAttr newAttr = acAttr(acaFG_BLUE | acaBG_GREEN) ;!}}@*
Please @pxref{enum acAttr}, below for more detailed information.

@itemize @BCIRCLE
@item To set the foreground color attribute to blue text:@*
@verb{!   acSetAttributes ( acaFG_BLUE ) ;!}

@item To set the background color attribute to green:@*
@verb{!   acSetAttributes ( acaBG_GREEN ) ;!}

@item To simultaneously set both foreground and background color attributes:@*
@verb{!   acSetAttributes ( acAttr(acaFG_BLUE | acaBG_GREEN) ) ;!}

@item To set Bold and Italic text modifiers:@*
@verb{!   acSetAttributes ( acAttr(acaBOLD | acaITALIC) ) ;!}

@item To reset only a specific text modifier (or modifiers) combine the modifier(s) 
with the @LDQ{}acaCLEAR_MODS@RDQ{} member:@*
@verb{!   acSetAttributes ( acAttr(acaCLEAR_MODS | acaBOLD) ) ;!}

@item To reset all text modifiers (i.e. plain text), call with @b{@emph{only}} the 
@LDQ{}acaCLEAR_MODS@RDQ{} member:@*
@verb{!   acSetAttributes ( acaCLEAR_MODS ) ;!}

@item To set Bold, blue foreground text, either specify a blue foreground in 
combination with the Bold attribute, or specify the bold blue attribute directly:@*
@verb{!   acSetAttributes ( acAttr(acaBOLD | acaFG_BLUE) ) ;!}@*
@b{@verb{!   or!}}@*
@verb{!   acSetAttributes ( acaFGb_BLUE ) ;!}

@item RGB (Red/Green/Blue) or 8-bit color foreground and background attributes are 
specified as index values rather than as individual members of enum acAttr. 
For this reason, setting RGB or 8-bit attributes is a two-step process.@*
First, call @t{acComposeAttributes} (described below) to construct the 
bitfield value, then call acSetAttributes with the resulting value.

RGB attribute values combine @t{'acaFG_RBG'} and/or @t{'acaBG_RGB'} with 
@LDQ{}web-safe@RDQ{} color indices in the range: @w{wsrgbMIN <= index <= wsrgbMAX}. 
This example sets both foreground and background to web-safe RGB attributes:@*
@verb{!acAttr aca = acComposeAttributes( 14, 221, true, true );!}@*
@verb{!acSetAttributes ( aca );!}

Eight-bit attributes combine @t{'acaFG_INDEX'} and/or @t{'acaBG_INDEX'} with
8-bit color indices in the range: @w{min8BIT <= index <= max8BIT}. 
This example sets both foreground and background to 8-bit attributes:@*
@verb{!acAttr aca = acComposeAttributes( 32, 112, false, false );!}@*
@verb{!acSetAttributes ( aca );!}@*
@xref{acComposeAttributes} below for additional examples.

@item To reset all attributes and modifiers to their default values,
and then set new fgnd/bgnd attributes and text modifiers, call with the 
@t{'resetAll'} flag set:@*
@verb{!   acSetAttributes ( acAttr(acaFG_BLUE | acaBG_GREY | acaUNDERLINE), true ) ;!}

@item To reset all attributes and modifiers to their default values, use the 
@LDQ{}acaATTR_DFLT@RDQ{} member in combination with the @t{'resetAll'} flag:@*
@verb{!   acSetAttributes ( acaATTR_DFLT, true ) ;!}
@end itemize
@spi

@anchor{acComposeAttributes}
@cindex acComposeAttributes
@item @b{acAttr acComposeAttributes ( uint8_t fgVal, uint8_t bgVal, bool rgbfg,} 
@ifnothtml
@*@verb{|                            |}
@end ifnothtml
@b{bool rgbbg, acAttr mods = acaPLAINTXT )}
@verbatim
  Input  : fgVal  : foreground index (8-bit index or web-safe RGB index)
                    -- if 'rgb' reset, then value interpreted as 8-bit index.
                       Range: 16-231 (or greyscale:232-255)
                    -- if 'rgb' set, then value interpreted as web-safe RGB
                       index. Range: 0-252
                    -- if 'rgb' reset AND 'fgVal' 0-15, then assume 4-bit color
           bgVal  : background index (8-bit index or web-safe RGB index)
                    -- if 'rgb' reset, then value interpreted as 8-bit index.
                       Range: 16-231 (or greyscale:232-255)
                    -- if 'rgb' set, then value interpreted as web-safe RGB
                       index. Range: 0-252
                    -- if 'rgb' reset AND 'fgVal' 0-15, then assume 4-bit color
           rgbfg  : if set, fgVal is interpreted as a (web-safe) RGB index
                    if reset, fgVal is interpreted as a 4/8-bit index
           rgbbg  : if set, bgVal is interpreted as a (web-safe) RGB index
                    if reset, bgVal is interpreted as a 4/8-bit index
           mods   : (optional, acaPLAINTXT by default)
                    logical OR of acAttr text-modifier flags)

  Returns: the constructed acAttr value
           (if a value is out-of-range, terminal default will be used)
@end verbatim

Construct an acAttr attribute bitmap from component values:@*
Call this method when composing attributes with 8-bit fgnd/bgnd indices or 
web-safe RGB fgnd/bgnd indices.

Use the constructed value as the parameter for a call to 
@ifnothtml
@*
@end ifnothtml
@ref{acSetAttributes}, above.
@spi

@H5heading{Examples:,▔▔▔▔▔▔▔▔▔}
@verbatim
acAttr aca ;      // receives the constructed value

Construct an 8-bit foreground and background value:
  aca = acComposeAttributes ( min8BIT + 2, min8BIT + 27, false, false );
Construct a value with a 4-bit foreground on an 8-bit background:
  aca = acComposeAttributes ( 3, max8BIT - 32, false, false );
Construct the same attribute value, but adding italic text.
  aca = acComposeAttributes ( 3, max8BIT - 32, false, false, acaITALIC );
Construct a web-safe RGB foreground and background value:
  aca = acComposeAttributes ( wsrgbMIN + 16, wsrgbMAX - 32, true, true );
Construct a value with an 8-bit foreground on an RGB background.
  aca = acComposeAttributes ( 201, wsrgbMIN + 32, false, true );
Construct the same attribute value, but adding underlined text.
  aca = acComposeAttributes ( 201, wsrgbMIN + 32, false, true, acaUNDERLINE );
Construct the same attribute value, but with italic _and_ underlined text.
  aca = acComposeAttributes ( 201, wsrgbMIN + 32, false, true, 
                              acAttr(acaITALIC | acaUNDERLINE) );

Use the constructed value to set the specified attributes:
  acSetAttributes ( aca );
    or
  acSetAttributes ( acAttr(aca | acaITALIC | acaUNDERLINE) );
@end verbatim

Note on 4-bit values:@*
The 4-bit color attributes are individually named, so the attributes may be 
specified directly.@*
@verb{|Examples: acSetAttributes( acAttr(acaFG_BLUE | acaBGb_BROWN) );|}@*
@verb{|          acSetAttributes( acAttr(acaFG_DFLT | acaBGb_BLUE) );|}@*
@verb{|          acSetAttributes( acAttr(acaFG_DFLT | acaBG_DFLT) );|}@*
Although this method is not designed to configure 4-bit color indices (0-15), 
they will be handled correctly, EXCEPT THAT it is not possible to specify 
terminal default foreground or background using this method.@*
@verb{!  aca = acComposeAttributes ( 3, 12, false, false );!}
@c Undocumented:@*
@c We document that this method may not be used 
@c to set terminal-default attributes; however, 
@c it is _possible_ to do so by intentionally 
@c specifying an out-of-range RGB value which 
@c will cause the terminal default to be used:
@c acComposeAttributes( wsrgbMAX+1, wsrgbMAX+1, true, true );
@spi

@anchor{acGetAttributes}
@cindex acGetAttributes
@item @b{void acGetAttributes ( acaExpand& decodedAttr );}

@verbatim
  Input  : decodedAttr: (by reference) instance of an acaExpand object 
                        to receive data.

  Returns: nothing
@end verbatim

Get a decoded copy of the current color attributes and text modifier flags.

The bitfield containing the attributes is decoded into it component values.

Refer to the description of the @ref{acaExpand class} data members 
for more information.
@end itemize

@c - - - Subheading  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@hr40
@indentedblock
@anchor{List of Attribute Names}
@anchor{enum acAttr}
@cindex enum acAttr
@cindex acAttr, enum
@Subsubheading{Technical Notes on the acAttr Enumerated Type,
               .............................................}

The @t{acAttr} (AnsiCmd Attributes) enumerated type provides application-level 
color-attribute and text-modifier configuration for terminal applications. 
@ifnothtml
@*
@end ifnothtml
The enumerated list, @b{@t{enum acAttr}} is defined in @t{AnsiCmdDef.hpp}.

Members of this type specify color attributes and text modifiers in a 
consistent format which encapsulates the primitive @t{ANSI} escape sequences 
defined for terminal-window text formatting. (see enum aeSeq). 

Within the AnsiCmd class, these values are decoded and mapped to their 
corresponding @t{ANSI} escape sequences (or group of sequences). This 
allows the application to focus on algorithms and user interaction 
rather than reading and writing binary data within the terminal window.

Although @t{acAttr} is defined as an enumerated type, is constructed 
as a group of macros defining bitfields. This allows the macros to be 
grouped in a coherent manner while also allowing bitwise OR operations 
for the desired foreground, background and text-modifier attributes.
For example, combine foreground, background attributes PLUS the 
@LDQ{}bold@RDQ{} and @LDQ{}italic@RDQ{} text attributes, then pass the 
value as an argument to one of the application-level methods.@*
@verb{!   acAttr txtAttr = acAttr(acaFG_GREEN | acaBG_GREY | acaBOLD | acaITALIC) ;!}@*
@verb{!   acSetAttributes ( txtAttr ) ;!}

Technical Note: The compiler will complain when performing any mathematical 
operations on members of an enumerated type; therefore, be sure to cast the 
OR'd value back to the acAttr type. For instance, the following would cause 
a compiler warning: @t{acAttr a;  a |= acaBOLD;}@*
Instead, use the following syntax: @t{a = acAttr(a | acaBOLD);}

See also the @b{@t{acaExpand class}} below for more information 
on encoding and decoding the bitfield values.


@c - - - Subheading  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@hr40
@anchor{Attribute Bitfield Definitions}
@anchor{acaExpand class}
@cindex acaExpand class
@cindex class, acaExpand
@Subsubheading{Bit Twiddling @EMDASH the acaExpand Class,
               ....................................}

@i{Late Night} host, Seth Meyers once defined nerds as people 
@LDQ{}with coffee-breath and crippling anxiety.@RDQ{} While that 
characterization was a bit rude, he actually wasn't wrong. For all OCD 
sufferers, (otherwise known as technically proficient people), having 
more information is like having a mug of hot cocoa and a warm blanket.

So, while accessing the @t{API} method group (which includes the ACWin class), 
does not require an understanding of the bit manipulations that occur 
within the AnsiCmd library, our nerd DNA insists that we have at least a 
general idea what's going on in the binary jungle.

All significant bit-oriented operations are encapsulated within 
the @t{acaExpand} class. The data managed by the @t{acaExpand} class 
are derived from the @b{@t{acAttr}} enumerated type and the @b{@t{WebSafeRGB}} 
enumerated type. These are both defined in @t{AnsiCmdDef.hpp}. 

The @t{acaExpand} class is also defined in @t{AnsiCmdDef.hpp}, and is 
implemented in the @t{AnsiCmdAca.cpp} source module.

All methods and data members of the @t{acaExpand} class are @LDQ{}public@RDQ{}; 
however, the live data are not available to the application (Duh!). If desired, 
however, @b{@emph{a copy of the live data}} data may be retrieved and studied.@*
Please @pxref{acGetAttributes}, above.

@H6heading{acaExpand Methods,▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔}

@b{@verb{|~acaExpand ( void ) ;|}}   // destructor

@b{@verb{|acaExpand ( void ) ;|}}   // default constructor

@b{@verb{|acaExpand ( acAttr bits ) ;|}}@*
Initialization Constructor:@*
The @t{'bits'} parameter consists of one or more members of enum acAttr 
combined using a logical OR. Example:@*
@smallverbatim{
   acaExpand aca( acAttr(acaFG_RED | acaBG_GREY) );}

@b{@verb{|void decode ( acAttr bits ) ;|}}@*
Decode the specified bitfield value into it component parts and store 
them in the data members.
@smallverbatim{
   acaExpand aca;
   aca.decode( acAttr(acaFG_RED | acaBG_GREY) );}

@b{@verb{|acAttr modify ( acAttr acaValue, bool add ) ;|}}@*
Add (or remove) one or more elements to (from) the bitfield value.@*
@verb{|   'acaValue' |} specifies the item(s) to be modified.@*
@verb{|        'add' |} (optional, 'true' by default)@*
@verb{|              |} referenced ONLY for text modifiers, not color attributes@*
@verb{|              |} if true, add the 'acaValue' items to the existing bitfield@*
@verb{|              |} if false, remove (reset) the specified items@*
@smallverbatim{
   acaEx.modify( acaBOLD, true );
   acaEx.modify( acaBOLD, false );
   acaEx.modify( acAttr(acaFGb_RED | acaBG_BLUE) );}

@b{@verb{|void update ( aeSeq aesValue, uint8_t colorIndx = ZERO );|}}@*
Update attribute tracking data by converting the provided member of@*
enum aeSeq to the equivalent acAttr bitfield value.@*
@verb{|   'aesValue' |} aeSeq item specifying attribute to be updated@*
@verb{|  'colorIndx' |} for aeSeq items requiring a color-attribute index value@*
(Used internally, but not really useful at the application level.)

@b{@verb{|acAttr compose ( void );|}}@*
Construct an acAttr attribute bitmap from the data in the data members:@*
fgIndex, bgIndex and the boolean (flag) members. This is the reverse of the 
@t{'decode'} method, above, and is used to encode 8-bit and RGB attribute 
indices. (Used internally, but not really useful at the application level.)@*
Please refer to the API-level method @ref{acComposeAttributes} which calls 
the 'compose' method with consistent formatting.

@b{@verb{|bool swap ( void );|}}@*
Swap (exchange) the foreground and background attributes.@*
Text modifiers are not affected.

@b{@verb{|acAttr buildRgb ( bool fg, WebSafeRGB fgVal, |}}@*
@b{@verb{|                  bool bg = false, WebSafeRGB bgVal = wsrgbMIN ) const|}}@*
Construct an acAttr bitfield from web-safe RGB color indices.@*
Specify RGB values for foreground and/or background color attributes. 
The values are members of enum WebSafeRGB which encode the RGB @t{'@b{hue}'} and 
@t{'@b{shade}'} used to initialize the Red/Green/Blue register values.@*
@verb{|   'fg'    |} 'true' @ if foreground value specified in 'fgVal'@*
@verb{|           |} 'false' if 'fgVal' is to be ignored@*
@verb{|   'fgVal' |} member of enum WebSafeRGB@*
@verb{|           |} if 'fg' flag is set, web-safe RGB foreground value@*
@verb{|           |} if 'fg' flag is reset, this value is ignored@*
@verb{|   'bg'    |} 'true' @ if background value specified in 'bgVal'@*
@verb{|           |} 'false' if 'bgVal' is to be ignored@*
@verb{|   'bgVal' |} member of enum WebSafeRGB@*
@verb{|           |} if 'bg' flag is set, web-safe RGB background value@*
@verb{|           |} if 'bg' flag is reset, this value is ignored@*
Returns: the constructed acAttr bitfield (If one or more parameters 
out-of-range, acaATTR_DFLT is returned.

Examples:
@smallverbatim{
1) Construct a bitfield with medium red foreground and dark blue background.
   acaExpand aca ;
   acAttr newVal =
         aca.buildRgbVal ( true, WebSafeRGB(wsrgbRED + wsrgbSHADE_MED),
                          true, wsrgbBLUE );
   aca.decode( newVal );

2) Construct a bitfield with bright cyan background, and with a standard 
   4-bit (non-RGB) blue foreground.
   acaExpand aca ;
   acAttr newVal =
         aca.buildRgbVal ( false, wsrgbMIN,
                           true, WebSafeRGB(wsrgbCYAN + wsrgbSHADES - 1) );
   newVal = acAttr(newVal | acaFG_BLUE);
   aca.decode( newVal );

3) Construct a bitfield with bright magenta foreground, and a medium blue 
   background shade.
   acaExpand aca ;
   acAttr newVal =
         aca.buildRgb ( true, WebSafeRGB(wsrgbMAGENTA + wsrgbSHADE_MAX), 
                        true, WebSafeRGB(wsrgbBLUE + wsrgbSHADE_MED / 2) );
         aca.decode( newVal );

4) Construct a bitfield with bright yellow foreground and a medium blue
   background.
   acaExpand aca ;
   acAttr newVal =
         acaBld.buildRgb( true, WebSafeRGB(wsrgbBROWN + wsrgbSHADE_MAX),
                          true, WebSafeRGB(wsrgbBLUE + wsrgbSHADE_MAX * 0.65) );
   aca.decode( newVal );}

@b{@verb{|acAttr build8Bit ( bool fg, uint8_t fgVal, bool bg, uint8_t bgVal ) const|}}@*
@verb{|   'fg'    |} 'true' @ if foreground value specified in 'fgVal'@*
@verb{|           |} 'false' if 'fgVal' is to be ignored@*
@verb{|   'fgVal' |} index of foreground attribute, range: min8BIT - max8BIT@*
@verb{|           |} if 'fg' flag is set, calculate foreground bitfield@*
@verb{|           |} if 'fg' flag is reset, this value is ignored@*
@verb{|                   |} and foreground bits are initialized as reset@*
@verb{|   'bg'    |} (optional, 'false' by default)@*
@verb{|           |} 'true' @ if background value specified in 'bgVal'@*
@verb{|           |} 'false' if 'bgVal' is to be ignored@*
@verb{|   'bgVal' |} (optional, min8BIT by default)@*
@verb{|           |} index of background attribute, range: min8BIT - max8BIT@*
@verb{|           |} if 'bg' flag is set, calculate background bitfield@*
@verb{|           |} if 'bg' flag is reset, this value is ignored@*
@verb{|                   |} and background bits are initialized as reset@*
Returns: the constructed acAttr bitfield

@smallverbatim{
   acaExpand acaBld ;
   acAttr pbAttr = acaBld.build8Bit( true, 160, true, 82 ) ;
   acAttr sbAttr = acaBld.build8Bit( true, 16, true, 219 ) ;
   acAttr rbAttr = acaBld.build8Bit( false, 0, true, 219 ) ;
   acAttr sbAttr = acaBld.build8Bit( true, 16 ) ;
}

@b{@verb{|aeSeq bits2aeseq ( acAttr acaBits, uint8_t byteIndx, bool isFgnd, bool isRgb );|}}@*
Convert between acAttr (bitfield) and aeSeq (ANSI escape sequence).@*
Note: If the aeSeq value is one of the 4-bit "bold" foreground attributes, 
the 'boldMod' flag is set. Otherwise the flag is not modified.@*
@verb{|    'acaBits' |} acAttr bitfields to be converted@*
@verb{|   'byteIndx' |} byte index value (either foreground or background index)@*
@verb{|              |} (currently unused)@*
@verb{|     'isFgnd' |} true if foreground target, false if background target@*
@verb{|      'isRgb' |} (optional, false by default)@*
@verb{|              |} true if @t{'acaBits'} references one of the@*
@verb{|                   |} web-safeRGB register indices, minRGB-maxRGB.@*
@verb{|              |} 'false if 'acaBits' is a lookup table index:@*
@verb{|                    |} 0-15 : 4-bit color index@*
@verb{|                  |} 16-231 : 8-bit color index@*
@verb{|                 |} 232-255 : greyscale index@*
Returns: member of enum aeSeq

@smallverbatim{
   acAttr attrBits = acAttr(acaFG_CYAN | acaBG_BLUE) ;
   WebSafeRGB attrRgb = wsrgbBLUE + wsrgbSHADE_MED ;
   acaExpand acax ;
   // 8-bit background
   aeSeq attrSeq = acaex.bits2aeseq ( attrBits, 0, false );
   // RGB foreground
   attrSeq = acaex.bits2aeseq ( attrRgb, 0, true, true );
}

@b{@verb{|acAttr aeseq2bits ( aeSeq aesCmd, bool& setFlag );|}}@*
Convert between aeSeq (ANSI escape sequence) and acAttr (bitfield).@*
For named escape sequences only; specifically:@*
@ @ @ a) 4-bit foreground@*
@ @ @ b) 4-bit background@*
@ @ @ c) text modifier flags@*
All other aeSeq values return acaPLAINTXT (i.e. zero).@*
Note: If the aeSeq value is one of the 4-bit "bold" foreground or background 
attributes, the 'boldMod' flag is set. 
@ifhtml
@*
@end ifhtml
Otherwise the flag is not modified.@*
@verb{|     'aesCmd' |} member of enum aeSeq to be converted@*
@verb{|    'setFlag' |} (by reference) receives the state of the internal@*
@verb{|              |} set/reset flag associated with the attribute@*
Returns: member of enum acAttr

@smallverbatim{
   aeSeq fgnd = aesFGb_BLUE ;
   bool flag ;
   acaExpand acax ;
   acAttr convAttr = acax.aeseq2bits( fgnd, flag ) ;

   Returns:
   convAttr == acaFGb_BLUE  and  flag == true
}

@b{@verb{|bool web2regs ( uint8_t webrgb, bool fgnd );|}}@*
Convert web-safe RGB index into red/green/blue RGB register values.@*
@verb{|     'webrgb' |} value indicating one of the web-safe RGB register groups@*
@verb{|              |} in the range: wsrgbMIN <= webrgb <= wsrgbMAX.@*
@verb{|       'fgnd' |} true if fgnd attributes, false if bgnd attributes@*
@cindex web-safe indices
216 web-safe colors are defined by the standard, which are mapped to the 
256 color indices defined for terminal color attributes and are then 
translated to individual R, G and B register values as shown.
@verbatim
                DARK >>>> LIGHT   CORRESPONDING RGB REGISTER INDICES
 Black        :    0               16;16;16
 Red group    :    1      36       22;16;16  >>>>  231;16;16
 Green group  :   37      72       16;22;16  >>>>  16;231;16
 Blue group   :   73     108       16;16;22  >>>>  16;16;231
 Brown group  :  109     144       22;22;16  >>>>  231;231;16
 Magenta group:  145     180       22;16;22  >>>>  231;16;231
 Cyan group   :  181     216       16;22;22  >>>>  16;231;231
 Grey group   :  217     231       22;22;22  >>>>  231;231;231
@end verbatim

@b{@verb{|void reset ( bool modsOnly = false ) ;|}}@*
Reset (clear) all data members. Optionally, reset text-mod flags only.@*
@verb{|   'modsOnly' |} if true, reset only the text-modifier attributes@*
@verb{|              |} if false, reset all color and text-modifier attributes


@H6heading{acaExpand Data Members,▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔}

Note that while there is some redundancy among the members, the layout 
of the data members is constructed for speed of access and to minimize 
the need for higher-level methods to perform bitwise operations. This 
in turn reduces the chance of processing errors.

@b{@verb{|acAttr    acaVal;   |}} full, encoded acAttr value@*
@b{@verb{|uint32_t  fgBits;   |}} nine bits defining foreground: 
@ifnothtml
@*@verb{|                    |} 
@end ifnothtml
index byte + fg default flag@*
@b{@verb{|uint32_t  bgBits;   |}} nine bits defining background: 
@ifnothtml
@*@verb{|                    |} 
@end ifnothtml
index byte + bg default flag@*
@b{@verb{|uint32_t  allFlags; |}} all binary flags (excludes fg/bg indices)@*
@b{@verb{|uint32_t  modFlags; |}} text-modification flags (subset of 'allFlags')@*
@b{@verb{|acAttr    acaFgnd;  |}} 8-bit field defining the foreground index@*
@b{@verb{|acAttr    acaBgnd;  |}} 8-bit field defining the background index@*
@b{@verb{|aeSeq     aesFgType;|}} Foreground attribute @emph{type}:@*
   @verb{|                     aesFG_DFLT: |} 4-bit color@*
   @verb{|                     aesFG_INDEX:|} 8-bit color@*
   @verb{|                     aesFG_RGB:  |} r/g/b color@*
@b{@verb{|aeSeq     aesBgType;|}} Background attribute @emph{type}:@*
   @verb{|                     aesBG_DFLT: |} 4-bit color@*
   @verb{|                     aesBG_INDEX:|} 8-bit color@*
   @verb{|                     aesBG_RGB:  |} r/g/b color@*
@b{@verb{|aeSeq     aesFgnd;  |}} 4-bit foreground (member of enum aeSeq)@*
@b{@verb{|aeSeq     aesBgnd;  |}} 4-bit background (member of enum aeSeq)@*
@b{@verb{|uint8_t   fgIndex;  |}} foreground byte index@*
@b{@verb{|uint8_t   bgIndex;  |}} background byte index@*
@b{@verb{|uint8_t   rgbFgR;   |}} if RGB foreground, Red register value@*
@b{@verb{|uint8_t   rgbFgG;   |}} if RGB foreground, Green register value@*
@b{@verb{|uint8_t   rgbFgB;   |}} if RGB foreground, Blue register value@*
@b{@verb{|uint8_t   rgbBgR;   |}} if RGB background, Red register value@*
@b{@verb{|uint8_t   rgbBgG;   |}} if RGB background, Green register value@*
@b{@verb{|uint8_t   rgbBgB;   |}} if RGB background, Blue register value@*
@b{@verb{|bool      fgDflt;   |}} if set, terminal default foreground 
@ifnothtml
@*@verb{|                    |}
@end ifnothtml
(ignore fg index bits)@*
@b{@verb{|bool      bgDflt;   |}} if set, terminal default background 
@ifnothtml
@*@verb{|                    |}
@end ifnothtml
(ignore bg index bits)@*
@b{@verb{|bool      boldMod;  |}} if set, Bold (intense) text@*
@b{@verb{|bool      italicMod;|}} if set, Italic text@*
@b{@verb{|bool      ulineMod; |}} if set, Underlined text@*
@b{@verb{|bool      olineMod; |}} if set, Overlined text@*
@b{@verb{|bool      xoutMod;  |}} if set, X-out (strikethrough) text@*
@b{@verb{|bool      blinkMod; |}} if set, Blinking text@*
@b{@verb{|bool      invisMod; |}} if set, Invisible (concealed) text@*
@b{@verb{|bool      revMod;   |}} if set, Reversed foreground and background@*
@b{@verb{|bool      clrMods;  |}} if set, Clear existing mods before setting new mods@*
@b{@verb{|bool      fgRgb;    |}} if set, rgbFgR, rgbFgG and rgbFgB contain 
@ifnothtml
@*@verb{|                    |}
@end ifnothtml
the foreground color@*
@b{@verb{|bool      bgRgb;    |}} if set, rgbGbR, rgbBgG, and rgbBgB contain 
@ifnothtml
@*@verb{|                    |}
@end ifnothtml
the background color
@spi

@H6heading{acaExpand Decoding Examples,▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔}

@verbatim
AnsiCmd (enum acAttr) color-attribute bit fields:
0x000000FF  index for foreground color
            ......00-......0F  16  4-bit color attributes
            ......10-......E7  216 8-bit color attributes
            ......E8-......FF  24  greyscale color attributes
            ......00-......FC  232 RGB color attributes
0x0000FF00  index for background color
            ....00..-....0F..  16  4-bit color attributes
            ....10..-....E7..  216 8-bit color attributes
            ....E8..-....FF..  24  greyscale color attributes
            ....00..-....FC..  232 RGB color attributes
0x00FF0000  text modifier flags
            ..00....   plain text (no modifiers)
            ..01....   bold (intense)
            ..02....   italic
            ..04....   underline
            ..08....   overline
            ..10....   x-out (strike-through)
            ..20....   blink
            ..40....   concealed (invisible)
            ..80....   reversed fg/bg
0xFF000000  additional flags
            01......   clear existing modifiers before setting the new ones
            02......   use terminal default foreground attribute
                       (foreground index ignored)
            04......   if set, it indicates that foreground index is the
                       index of a "web-safe" RGB foreground color attribute
                       with a range of: minRGB <= value <= maxRGB
            08......   use terminal default background attribute
                       (background index ignored)
            10......   if set, it indicates that background index is the
                       index of a "web-safe" RGB background color attribute
                       with a range of: minRGB <= value <= maxRGB
            20......   (reserved)
            40......   (reserved)
            80......   (reserved as internal placeholder value)

The following shows some examples of how the bitfield is constructed.
The contruction is performed by creating a logical OR of enum acAttr members;
or in the case of 8-bit and RGB color attributes by using the 'compose' method
described above.
See also the AnsiCmd 'acComposeAttributes' public method.

To specify the terminal default foreground attribute, set the acaFG_DFLT flag.
The foreground index value will be ignored.
   Fgnd:  xxxx-x01x-xxxx-xxxx-xxxx-xxxx-....-....

To specify the terminal default background attribute, set the acaBG_DFLT flag. 
The background index value will be ignored.
   Bgnd:  xxx0-1xxx-xxxx-xxxx-....-....-xxxx-xxxx

To specify a 4-bit foreground attribute, _reset_ the acaFG_DFLT and
acaFG_RGB flags and insert the desired member of enum acAttr in the range:
acaFG_BLACK through acaFGb_GREY inclusive.

To specify a 4-bit background attribute, _reset_ the acaBG_DFLT and
acaBG_RGB flags and insert the desired member of enum acAttr in the range:
acaBG_BLACK through acaBGb_GREY inclusive.

To specify an 8-bit indexed color foreground attribute, initialize the
foreground index and _reset_ both the acaFG_DFLT and acaFG_RGB flags.
   Fgnd:  xxxx-x00x-xxxx-xxxx-xxxx-xxxx-nnnn-nnnn

To specify an 8-bit indexed color background attribute, initialize the
background index and _reset_ both the acaBG_DFLT and acaBG_RGB flags.
   Bgnd:  xxx0-0xxx-xxxx-xxxx-nnnn-nnnn-xxxx-xxxx

To specify one of the "web-safe" RGB register combinations, initialize
the foreground or background index and set the acaFG_RGB or acaBG_RGB 
flag, respectively. 
   Fgnd:  xxxx-x10x-xxxx-xxxx-xxxx-xxxx-nnnn-nnnn
   Bgnd:  xxx1-0xxx-xxxx-xxxx-nnnn-nnnn-xxxx-xxxx

To set one or more text modifiers, _reset_ the acaCLEAR_MODS flag and
create a logical OR of the desired attributes. (include existing fg/bg bits.)
Ex: acAttr fgbg = acAttr(acaFG_BLUE | acaBGb_RED);
    acAttr((fgbg |acaBOLD | acaITALIC | acaUNDERLINE) & ~acaCLEAR_MODS)
   Mods:  xxxx-xxx0-xxxx-x111-xxxx-xxxx-xxxx-xxxx

To reset one or more text modifier, set the acaCLEAR_MODS flag and _set_
the flag(s) for the modfier(s) to be reset. (include existing fg/bg bits.)
Ex: acAttr(fgbg | acaITALIC | acaCLEAR_MODS)
   Mods:  xxxx-xxx1-0000-0010-xxxx-xxxx-xxxx-xxxx
@end verbatim
@end indentedblock

@hr90

@c - - - Subheading  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@anchor{Display Formatting Methods}
@anchor{acClearScreen}
@cindex acClearScreen
@Subsubheading{Display Formatting Methods,
               ..........................}

@itemize @BSQUARE
@item @b{void acClearScreen ( wchar_t fillchar = L@t{' '}, 
@ifnothtml
@*@verb{|                    |}
@end ifnothtml
acAttr fillattr = acaUSEDFLT );}

@verbatim
  Input  : fillchar: (optional, space character ' ' by default)
                     specify a (single-column) character to be written to
                     each character cell of the terminal window
           fillattr: (optional, default: terminal default attribute)
                     color attribute for clearing the terminal window.
                     Note: If a non-default attribute is specified, that will
                           be the current fg/bg attribute on return.

  Returns: nothing
@end verbatim

Clear the entire terminal window using the specified fill character and 
color attribute.

On return, the visible cursor will be at the HOME position (1,1).
@spi

@anchor{acClearArea}
@cindex acClearArea
@c @ifnothtml
@item @b{bool acClearArea ( short row, short col, short height, short width, } 
@*@verb{|               |}
@ifnothtml
@verb{|  |}
@end ifnothtml
@b{wchar_t fillchar = L@t{' '}, @ 
@ifnothtml
@*@verb{|                  |}
@end ifnothtml
acAttr fillattr = acaUSEDFLT );}
@item @b{bool acClearArea ( WinPos wpOrig, short height, short width, }
@*@verb{|               |}
@ifnothtml
@verb{|  |}
@end ifnothtml
@b{wchar_t fillchar = L@t{' '}, @ 
@ifnothtml
@*@verb{|                  |}
@end ifnothtml
acAttr fillattr = acaUSEDFLT );}
@c @end ifnothtml
@c @ifhtml
@c @end ifhtml

@verbatim
  Input  : row     : top row of target area
           col     : left column of target area
                  OR
           wpOrig  : top row and left column of target area

           height  : number of rows in target area
           width   : number of columns in target area
           fillchar: (optional, ' ' by default)
                     specify a (single-column) character to be written to
                     each character cell in the target area
           fillattr: (optional, default: terminal default attribute)
                     color attribute for clearing the target area.
                     Note: If a non-default attribute is specified, that will
                           be the current fg/bg attribute on return.

  Returns: 'true'  if successful
           'false' if parameter(s) out-of-range
@end verbatim

Clear the specified rectangular area using spaces (default), or using the 
specified fill character.@*
@xref{acDrawLine} below for an example invocation.

Position, height and width of the area are adjusted as necessary to remain 
within the terminal window.@*
See also the note in @ref{cursor offsets} regarding 1-based vs. 0-based 
cursor positioning.

@b{Note:} On return, the cursor position within the window will be indeterminate, 
so it is caller's responsibility to adjust cursor position.
@spi

@anchor{acFormatParagraph}
@cindex acFormatParagraph
@item @b{short acFormatParagraph ( gString& gsTxt, short maxRows, short maxCols, @*
@ifnothtml
@verb{|                         |}
@end ifnothtml
@ifhtml
@verb{|                       |}
@end ifhtml
bool trunc = true, bool hypenbrk = false, 
@ifnothtml
@*@verb{|                         |}
@end ifnothtml
short *truncIndex = NULL );}
@item @b{short acFormatParagraph ( wchar_t* wTxt, short maxRows, short maxCols, @*
@ifnothtml
@verb{|                         |}
@end ifnothtml
@ifhtml
@verb{|                       |}
@end ifhtml
bool trunc = true, bool hypenbrk = false, 
@ifnothtml
@*@verb{|                         |}
@end ifnothtml
short *truncIndex = NULL );}

@verbatim
  Input  : on entry, contains raw message text and
           on return, contains formatted message text
           gsTxt    : (by reference) a gString Object
                    OR
           wTxt     : a wchar_t string (32-bit characters)

           maxRows  : maximum rows for message
           maxCols  : maximum columns on any message row
           trunc    : (optional, 'true' by default)
                      if 'true',  truncate the data if necessary to ensure
                                  that the data do not extend beyond the
                                  specified target area
                      if 'false', format the entire source text array, even
                                  if doing so requires violating the specified
                                  height of the target area (maxRows).
                                  (see also 'truncIndx' parameter)
           hyphenbrk: (optional, 'false' by default)
                      if 'false', automatic line breaks occur after space 
                                  characters only.
                                   ASCII space   (U+0020)
                                   CJK space     (U+3000)
                                   CJK comma     (U+3001) (see notes)
                                   CJK full stop (U+3002) (see notes)
                      if 'true',  in addition to the space ' ' characters,
                                  enable line break at:
                                   ASCII hyphen    '-' (U+002D)
                                   Unicode &mdash; '—' (U+2014)
                                   Unicode &ndash; '–' (U+2013)
                                   Unicode &minus; '−' (U+2212)
           truncIndx: (optional, null pointer by default)
                       -- referenced _only_ when the 'trunc' flag is reset
                       if specified, points to a variable to receive the
                       index at which the data _would_have_been_ truncted to
                       fit the specified height of the target area if the
                       'trunc' flag had been set.
                       a) A positive value indicates that the data have not
                          been truncated, AND that the data extend beyond the
                          the specified target area.
                       b) A negative value indicates that it was not necessary
                          to truncate the data i.e. the data fit entirely
                          within the target area.

  Returns: number of text rows in formatted paragraph
@end verbatim

Reformat the provided text to fit within the specified dimensions.

@ @ 1) Remove all newlines.@*
@ @ 2) Perform word wrap to limit width of each row of the paragraph.@*
@ @ 3) If necessary, truncate the text to limit height of the paragraph.@*
@verb{|     |}(but see the 'trunc' and 'truncIndx' parameters)

This method is used internally by the ACWin-class objects when writing text 
in the window and when creating dialogs within the window, but may be used 
freely when sizing text for display.

Both single-width and CJK double-width (two column) characters are handled by 
the this method.@*
Note: @LDQ{}CJK@RDQ{} indicates the Chinese, Japanese, Korean 
(and historically, Vietnamese) character sets.

@H5heading{Notes on automatic word wrap:,
           ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔}

@enumerate 1
@item Line breaks occur @emph{after} the space character at the end of a token, 
(word). This means that the line is broken by placing the newline 
@emph{after} the identified space character.@*
Note: Currently the ASCII space character (20h) and the two-column 
CJK space (U+3000) are the only whitespace characters recognized.

Special Case: In every-day use, CJK text seldom contains any spaces at all 
within a sentence, or even between sentences. Two-column punctuation is 
designed to provide a visual spacing effect. For this reason, we have made the 
design decision to process the following CJK ideographs as whitespace:@*
@verb{|        '、'|} comma U+3001  and @t{'。'} full stop U+3002

Caution: Tab characters @t{('\t')} @b{@emph{are not}} recognized as whitespace 
characters because they are effectively variable width characters. Don't use them!

Optionally, the ASCII hyphen and the Unicode hyphen-like characters 
can be treated as if they were whitespace for purposes of calculating where 
to break a line. See the @t{'hyphenbrk'} parameter.

@item When reformatting the data, it is possible that the text will be pushed 
beyond the specified number of rows. In this case, we have two options:
@enumerate a
@item Truncate the text after the last specified row is filled.
@item Alert the caller about the number of rows actually required. 
Optionally, we can indicate the index at which the text would have been 
truncated so that caller can manually truncate the text if desired. 
(see the @t{'truncIndx'} parameter)
@end enumerate

@item It is possible that a single token (word) will be longer than the width 
of the target area. Handling this (unlikely) scenario complicates the 
line-break algorithm, but could come into play; for instance: filespecs, 
URLs, or German words. :-)@*
Filespecs and URLs should be parsed using specialized formatting methods. 
Long words, especially hyphenated words can be a problem. This method 
can optionally break after hyphens (see the @t{'hyphenbrk'} parameter).

@item Notes on automatic hyphenation at mid-word line breaks:@*
Technically, hyphens should be placed between syllables, but that would require 
a full dictionary of the target language.@*
@LDQ{}Can open... worms everywhere.@RDQ{} @i{(Thank you, Chandler Bing.)}
@itemize @minus
@item The hyphen used is the the Unicode &ndash; U+2013. This facilitates 
stripping them from the text if the text is copied and pasted elsewhere.@*
Note the ideally we would use the so-called @LDQ{}soft hyphen,@RDQ{} Unicode &shy; 
U+00AD, but unfortunately the terminal sees that as a zero-width character 
making it invisible under most circumstances.@*
Example of stripping characters using the gString utility:@*
@verb{| gString gsTxt(|} 
@ifnothtml
@*
@verb{|    |}
@end ifnothtml
@verb{| "Dashing–through–the–snow–in–a–one-horse–open–sleigh." );|}@*
@verb{| short sindx = ZERO ;|}@*
@verb{| while ( (sindx = gsTxt.find( nDASH, sindx )) >= ZERO )|}@*
@verb{|    gsTxt.erase( sindx, 1 ) ;|}@*
Yields: @verb{|"Dashing through the snow in a one-horse open sleigh."|}@*
Note that the ASCII hyphen between 'one' and 'horse' is not affected.@*
Please @pxref{gString Text Tool} for more information on the 
gString text internationalization utility.

@item Programmer's Note: If the current character is the same width as the 
hyphen, then the hyphen will be at the right edge of the target area.
Otherwise there will be a one-column gap at the end of the line.
@item Special case: For multi-column characters, it is assumed that the 
characters belong to one of the CJK character sets. (This may not be true, 
but multi-column characters seldom appear in Romance languages.@*
Therefore, for multi-column characters only, hyphens @b{@emph{are not}} inserted 
after mid-token line breaks because there is no way of knowing if we 
are breaking in mid-word or between words unless we have access to 
dictionaries for those languages.@*
(Again, @LDQ{}...worms everywhere.@RDQ{})
@end itemize
@end enumerate
@spi

@anchor{acShellOut}
@cindex acShellOut
@item @b{int acShellOut ( const char* cmd = NULL, bool clrWin = false, 
@ifnothtml
@*@verb{|                |}
@end ifnothtml
acAttr txtAttr = acaUSEDFLT );}

@verbatim
  Input  :
     cmd    : (optional, default: null pointer) command to be executed
              -- any valid command, or sequence of commands may be
                 specified, using the syntax recognized by the shell
                 program.
              -- if a command is not specified, the default shell
                 program is invoked with a message similar to:
                 "type 'exit' to return."
     clrWin : (optional, default: false)
              if 'false', the called application begins output at the
                          at the current cursor position
              if 'true',  clear the terminal window before invoking the
                          command. The command will appear at the top
                          of the terminal window
     txtAttr: (optional, default: acaUSEDFLT)
              -- if the default value is seen, the the current color
                 attribute settings will be used for both the optional
                 clear of the window and for the text written by the
                 called terminal application.
              -- if a non-default value is specified, it is used for
                 both clearing the terminal window ('clrWin' parameter)
                 and as the color attributes used by the called program
                 for writing text to the window.
                 Note: Many console utilities override the existing
                       terminal attributes, so the specified attribute
                       may be ignored.

  Returns: exit code of child process
     Ideally, this is the exit code of the last utility run in the
     child process, but this cannot be guaranteed.
@end verbatim

Temporarily return control to terminal shell program.
@enumerate 1
@item If specified, set foreground/background color attributes.
@item If specified, clear the terminal window.
@item Return I/O buffering and input echo settings to the terminal defaults.
@item Any signal handlers which have been set within the application will 
become inactive while the shell program is in control. These signals will 
become available to the shell program and any utilities executing 
within the shell.@*
Please @pxref{acCaptureSignals} for a discussion of available signal 
handlers.
@item When the application regains control, the previous I/O buffering, 
echo option and color attributes will be restored.
@end enumerate

This method uses the standard library @t{'@b{system}'} function which in 
turn uses members of the @t{'@b{exec}'} function group to format and 
execute the command and its arguments.@*
Refer to standard library docs for details:@*
@verb{|    info system|}@*
@verb{|    man 3 system|}

See also the @t{ACWin-class} @ref{ShellOut} method.
@end itemize
@hr90

@c - - - Subheading  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@anchor{Line Drawing Methods}
@anchor{acDrawLine}
@cindex acDrawLine
@Subsubheading{Line Drawing Methods,
               ....................}

@itemize @BSQUARE
@item @b{WinPos acDrawLine ( const WinPos& wpOrig, short length, bool vertical, 
@ifnothtml
@*@verb{|                   |}
@end ifnothtml
LineType lType = ltSINGLE, 
@ifnothtml
@*@verb{|                   |}
@end ifnothtml
@ifhtml
@*@verb{|                  |}
@end ifhtml
wchar_t begChar = L@t{'\0'}, wchar_t endChar = L@t{'\0'} );}

@verbatim
  Input  : pos     : offset from upper-left corner of terminal window to
                     upper-left corner of box (1-based)
           length  : length of the line: number of number of rows (vertical),
                     or number of columns (horizontal).
           vertical: 'true'  : vertical line
                     'false' : horizontal line
           lType   : (optional, ltSINGLE by default) line style
                      member of enum LineType: either ltSINGLE or ltDUAL
           begChar : (optional, null character by default)
                      specify the beginning endpoint character
           endChar : (optional, null character by default)
                      specify the final endpoint character

  Returns: cursor position at the end of the line:
           For horizontal lines, this is the column following the last character.
           For vertical lines, this is the column below the last character.
@end verbatim

Draw a horizontal or vertical line in the terminal window.@*
Horizontal lines are drawn left-to-right.@*
Vertical lines are drawn top-to-bottom.

Optionally, the endpoint character(s) may be specified for the beginning 
and/or end of the line. The valid endpoint characters include any of the 
line-drawing glyphs defined in @t{AnsiCmdDef.hpp}. Note however, that the 
@t{'begChar'} and @t{'endChar'} parameter are not range checked, so the 
character specified (if any), will be written. (Use single-column characters only.)
If the endpoint(s) are not specified, the line-drawing character is used 
as the endpoint character. 

@verbatim
Example:
   // define the dimensions of the box
   short hgt = 9, wid = 25 ;
   // define the upper left corner of the box object
   WinPos wp( 9, 9 ) ;
   // clear target area using optional color attributes, and note that
   // on return, the specified colors are still active.
   acClearArea ( wp, hgt, wid, L' ', acAttr(acaFGb_CYAN | acaBG_BLUE) ) ;
   // draw the box
   acDrawBox ( wp, hgt, wid, ltDUAL ) ;
   // move downward to start position of first line
   wp.row += 4 ;
   // draw a line the full width of the box with connections on each end
   acDrawLine ( wp, 25, false, ltSINGLE, wcsLTEEdv, wcsRTEEdv ) ;
   // move to the top center of the box
   wp = { 9, 21 } ;
   // draw a line that connects with the box at the top and terminates
   // with a line-intersection character
   wp = acDrawLine ( wp, 5, true, ltSINGLE, wcsTTEEdh, wcsINSECT ) ;
   // draw a line from below the intersect character to the bottom
   // of the box, and which terminates with a connector character
   acDrawLine ( wp, 4, true, ltSINGLE, NULLCHAR, wcsBTEEdh ) ;

        ╔═══════════╤═══════════╗
        ║           │           ║
        ║           │           ║
        ║           │           ║
        ╟───────────┼───────────╢
        ║           │           ║
        ║           │           ║
        ║           │           ║
        ╚═══════════╧═══════════╝
@end verbatim
@spi

@anchor{acDrawBox}
@cindex acDrawBox
@item @b{WinPos acDrawBox ( WinPos pos, short height, short width,} 
@ifnothtml
@*@verb{|                  |}
@end ifnothtml
@b{LineType lType = ltSINGLE, const char *text = NULL );}

@verbatim
  Input  : pos   : offset from upper-left corner of terminal window to
                   upper-left corner of box (1-based)
           height: number of rows for box
           width : number of columns for box
           lType : (optional, ltSINGLE by default) line style
                   member of enum LineType: either ltSINGLE or ltDUAL
           text  : (optional, null pointer by default)
                   If specified, text to be written to interior of box.

  Returns: current cursor position within the box
@end verbatim

Draw a box in the terminal window and optionally write text in the box.

This is a greatly simplified form of drawing a window. It simply draws a 
rectangle in the terminal window at the specified position and of the 
specified dimensions.@*
The box is drawn using the currently active foreground and background colors.

If parameters are out-of-range, the position and dimensions will be 
modified as necessary to fit within the terminal window.

The position of the visible cursor is returned.@*
If the @t{'text'} parameter specifies text data to be written into the box, 
then the cursor will be positioned at the end of the text. Otherwise, the 
cursor will be positioned at the top-left corner of the interior of the box.@*
@xref{acDrawLine} above for an example invocation.
@spi

@anchor{acEraseBox}
@cindex acEraseBox
@item @b{void acEraseBox ( WinPos wpOrig, short height, short width );}

@verbatim
  Input  : pos   : offset from upper-left corner of terminal window to
                   upper-left corner of box (1-based)
           height: number of rows for box
           width : number of columns for box

  Returns: nothing
@end verbatim

Erase the specified area. This is a companion method to the @t{acDrawBox} 
method above. @t{acEraseBox} simply calls the low-level method to clear the 
text from the specified area.
@spi

@anchor{AC_Box Class}
@cindex AC_Box Class
@Subsubheading{The AC_Box Class,................}

@anchor{acBoxDraw}
@cindex acBoxDraw
@item @b{WinPos acBoxDraw ( AC_Box& box, const char* text = NULL );}

@verbatim
  Input  : box : (by reference) configuration parameters for the object
           text: (optional, null pointer by default)
                 If specified, text to be written to interior of box.

  Returns: coordinates of upper-left corner of text area within the box
           (These coordinates are the one-based offset from the )
           (upper-left corner of the terminal window.           )
@end verbatim

Display the data of an AC_Box object in the terminal window.

@enumerate 1
@item Clear the target area.
@item Draw the box.
@item Initialize the interior of the box to the specified background color.
@item If specified, write the initial text to the interior of the box.
   @enumerate a
   @item Text will be written using the foreground and background attributes 
         specified for the interior.
   @item Caller is responsible for ensuring that the text fits entirely 
         within the interior area, AND that the final cursor position also 
         lies within the interior area. Automatic text formatting is not 
         performed.
   @end enumerate
@item On return, the visible cursor will be positioned at the origin 
(upper-left corner) of the text area @b{@emph{unless}} initial text data 
were specified, in which case the visible cursor will be positioned at the 
end-of-text.
@item On return, color attributes will have been set to terminal defaults.
@end enumerate
@spi

@H5heading{AC_Box Example,▔▔▔▔▔▔▔▔▔▔▔▔▔▔}

@c smallverbatim
@verbatim
WinPos boxOrigin( 1, 16 ) ;
short  boxHEIGHT = 11 ;
short  boxWIDTH  = 48 ;
LineType lType   = ltSINGLE ;
aeSeq  borderFg  = aesFGb_GREY ;
aeSeq  borderBg  = aesBG_BLUE ;
aeSeq  textFg    = aesFG_BLUE ;
aeSeq  textBg    = aesBG_CYAN ;
const char* title = "  Life Is A.. What?!  " ;

AC_Box box( boxOrigin, boxHEIGHT, boxWIDTH, lType, 
            borderFg, borderBg, textFg, textBg, title ) ;
acBoxDraw ( box, "\n\n     Life is like a box of chocolates.\n"
                     "     You never know what you're gonna get.\n"
                     "      -- Forrest G." ) ;
@end verbatim
@ifnothtml
@verbatim

      ┌───────────┤  Life Is A.. What?!  ├───────────┐
      │                                              │
      │                                              │
      │     Life is like a box of chocolates.        │
      │     You never know what you're gonna get.    │
      │      -- Forrest G.                           │
      │                                              │
      │                                              │
      │                                              │
      │                                              │
      └──────────────────────────────────────────────┘
@end verbatim
@end ifnothtml
@ifhtml
@html
<div class="tscap" style="background-color:#009999; max-width:28.80em; line-height:1.165em;"><span class="gybl">┌───────────┤  Life Is A.. What?!  ├───────────┐</span>
<span class="gybl">│</span><span class="blcy">                                              </span><span class="gybl">│</span>
<span class="gybl">│</span><span class="blcy">                                              </span><span class="gybl">│</span>
<span class="gybl">│</span><span class="blcy">     Life is like a box of chocolates.        </span><span class="gybl">│</span>
<span class="gybl">│</span><span class="blcy">     You never know what you're gonna get.    </span><span class="gybl">│</span>
<span class="gybl">│</span><span class="blcy">      -- Forrest G.                           </span><span class="gybl">│</span>
<span class="gybl">│</span><span class="blcy">                                              </span><span class="gybl">│</span>
<span class="gybl">│</span><span class="blcy">                                              </span><span class="gybl">│</span>
<span class="gybl">│</span><span class="blcy">                                              </span><span class="gybl">│</span>
<span class="gybl">│</span><span class="blcy">                                              </span><span class="gybl">│</span>
<span class="gybl">└──────────────────────────────────────────────┘</span>
</div><br>
@end html
@end ifhtml
@spi

@anchor{acBoxErase}
@cindex acBoxErase
@item @b{void acBoxErase ( const AC_Box& box );}

@verbatim
  Input  : box : (by reference) configuration parameters for the object
  Returns: nothing
@end verbatim

Erase the rectangular area drawn by the @t{acBoxDraw} method, above.

The current color attributes will be used to clear the area.
@spi

@anchor{acBoxClear}
@cindex acBoxClear
@item @b{WinPos acBoxClear ( const AC_Box& box );}

@verbatim
  Input  : box : (by reference) configuration parameters for the object
  Returns: coordinates of upper-left corner of text area within the box
@end verbatim

Erase the text area of of an AC_Box object.

@enumerate 1
@item On return, the foreground/background color attributes are set to the 
colors specified for the interior of the object.
@item On return, the visible cursor is set to the upper-left corner of the 
text area.
@end enumerate
@end itemize

@hr90

@c - - - Subheading  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@anchor{Identify "Special" Keycodes}
@anchor{isSpecialKey}
@cindex isSpecialKey

@Subsubheading{Identify "Special" Keycodes,
               ...........................}

@itemize @BSQUARE
@item @b{bool isSpecialKey ( wchar_t& wkey, bool alert = false, 
@ifnothtml
@*@verb{|                   |}
@end ifnothtml
EchoOpt *eopt = NULL ) const;}

@verbatim
  Input  : wkey : (by reference) keycode to be tested

           alert: (optional, 'false' by default) audible alert
                  'true'  execute a terminal beep if keycode under test
                          IS one of the supported soft-echo keycodes, but
                          IS NOT not included in the active soft-echo group.
                  'false' do not execute an audible alert
           eopt : (optional, null pointer by default)
                  If specified, this is a pointer to an alternate soft-echo
                  option to be used for the test.
                     (used internally for special-key verification)

  Returns: 'true'  if key is one of the ACTIVE special keys
           'false' if key is not one of the active special keys
                   If the caller's keycode is a Special key that IS NOT a
                   member of the active group. the keycode will be set to
                   the null character (NULLCHAR) on return.
@end verbatim

Determine whether the specified keycode is one of the "special" keys, AND 
whether that keycode is a member of the active soft-echo sub-group.

The test is performed against the soft-echo option specified by the prior 
terminal setup, (but see the 'eopt' argument).

The available character-echo options are members of enum EchoOpt.@*
Please refer to @ref{TermConfig Class}, and specifically the @t{'echoOption'} 
member variable for terminal setup information.

Each of the soft-echo options encompasses a subset of the supported 
"special" keycodes.@*
Please @pxref{Soft Echo Options} for a description of the soft-echo groups.

@b{NOTE:} This method should not be called when the echo option is not one 
of the soft-echo options, but if it is, it will only result in a harmess 
waste of CPU cycles.
@spi

@anchor{isCommandKey}
@cindex isCommandKey
@item @b{bool isCommandKey ( wchar_t& wkey, bool all = false ) const;}

@verbatim
  Input  : wkey : (by reference) keycode to be tested
           all  : (optional, 'false' by default)
                  if 'true', include the "special" keycodes as command keycodes*
                  if 'false, "special" keycodes are excluded

  Returns: 'true' if keycode is one of the command keycodes, else 'false'
@end verbatim

@format
Determine whether the specified keycode is one of the converted keycodes:
 1) ASCII control codes: Ctrl+A - Ctrl+Z, Ctrl+4, Ctrl+5, Ctrl+6, Ctrl+7.
 2) "GUI" command keys: Alt+A - Alt+Z, Alt+punctuation characters.
 3) Ctrl + navigation keys.
 4) Left Alt + navigation keys
 5) Function keys: wcsF01-fcsF12, wcsSF01-wcsSF12, wcsCF01-wcsCF12
@end format

By default, this test @emph{excludes} the @LDQ{}special@RDQ{} keycodes. 
(@pxref{isSpecialKey}), however, this method may optionally @emph{include} 
the @LDQ{}special@RDQ{} keycodes within the command-key group by setting 
the @t{'all'} flag.

@quotation Technical Note
These keycodes have been converted from escape sequences or ASCII 
control codes to graphing characters; however, they should not be 
echoed to the display. They would just look like garbage from the 
user's point of view. If the keycode is not associated with an 
action within the application, it should be discarded. See the 
(protected) @t{normalkeyProc} method for additional information.
@end quotation
@end itemize

@hr90

@c - - - Subheading  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@anchor{Temporary File Management}
@cindex temporary files
@Subsubheading{Temporary File Management,
               .........................}

Temporary files are an integral part of any application which needs to 
interact with the host system or with other applications. The @t{AnsiCmd} 
library provides full support for creating and managing temporary files 
within the system temporary directory. 

Although the @t{AnsiCmd} library does not make use of temporary files 
internally; most non-trivial applications do. For this reason, management 
of temporary files for applications based on the @t{AnsiCmd} library is 
encapsulated here to provide a clean interface to the compiler's standard 
library functions for creating and deleting temporary files.

These methods, in turn, rely on the author's @b{@t{TFMan class}} which is a 
stand-alone class included in, but functionally seperate from the 
@t{AnsiCmd/ACWin/ACDlg} group.@*
Please @pxref{TFMan Class} for a full description of this class 
and the associated test utility @ref{TFMTest Demo App}.
@sp 1
@hr40

@anchor{acCreateTemppath}
@cindex acCreateTemppath
@itemize @BSQUARE
@item @b{bool acCreateTemppath ( const char* prefix = NULL );}

@verbatim
  Input  : prefix : (optional, default: null pointer)
                    specify a constant token which will prefix the name of the
                    temporary sub-directory in which temp files will be created.
                    If a prefix is not specified, then the default "ANSICMD_"
                    prefix token is used.
                    Important Note: Use only valid filename characters 
                                    (not "special" chars) for the prefix string

  Returns: 'true'  if path/dirname created successfully
           'false' if call to standard library function failed
@end verbatim

Enable support for temporary files:@*
Create a unique sub-directory within the system's temp-file directory 
to contain the application's temporary files.

Internally, this is implemented by creating an instance of the 
@t{'@b{TFMan}'} class. The @b{T}emp @b{F}ile @b{Man}ager class encapsulates 
creation and deletion of temporary files. This prevents one of the most 
common programmer errors, namely exiting the application and leaving orphaned 
temp files for the system to clean up. This can be especially important if 
your temp files contain sensitive information.

The optional @t{'prefix'} parameter is used as the leading substring for 
the filename to be constructed. A unique six-character sequence will be 
appended to this sequence to form the name of the subdirectory.
@example
Example:
   AnsiCmd *acptr = new AnsiCmd() ;
   acptr->acCreateTemppath ( "MyApp_" ) ;
will result in a directory name of the form:
   MyApp_rPuyzA
@end example
This name is guaranteed to be unique within the system's temporary directory.

If no prefix is specified, then the default prefix (@t{"ANSICMD_"}) will be used.
@spi

@anchor{acDeleteTemppath}
@cindex acDeleteTemppath
@item @b{void acDeleteTemppath ( void );}

@verbatim
  Input  : none
  Returns: nothing 
@end verbatim

Disable support for temporary files.@*
Delete the sub-directory containing the application's temporary files and 
any files remaining in that subdirectory.

@verb{|  1)|} May be called directly by the application layer, or else@*
@verb{|  2)|} Will be called by the AnsiCmd-class destructor.
@spi

@anchor{acCreateTempfile}
@cindex acCreateTempfile
@item @b{bool acCreateTempfile ( gString& tempPath );}

@verbatim
  Input  :
     tmpPath: (by reference) receives the path/filename of the new file
  Returns:
     'true'  if file created successfully
     'false' if library call failed
@end verbatim

Create a unique path/filename for a temporary file, then create the file.@*
The file will have been closed and will be empty (will contain no data).

@example
gString tmpPath ;
ACWin* win = new ACWin( ... );
...
win->acCreateTempname ( "SAM_" ) ;
if ( (win->acCreateTempfile ( tmpPath )) )
@{
   ofstream ofs ( tmpPath.ustr(), ofstream::out | ofstream::app ) ;
   if ( (ofs.is_open()) )
   @{
      ofs << "Write some data to the temp file." << endl ;
      ofs.close() ;
   @}
@}
// This is optional. If this method is not explicitly called by 
// the application, it will be called by the ACWin/AnsiCmd destructor.
win->acDeleteTempname () ;
@end example
@spi

@anchor{acDeleteTempfile}
@cindex acDeleteTempfile
@item @b{bool acDeleteTempfile ( const gString& tempPath );}

@verbatim
  Input  :
   tmpPath : full path/filename specification of source
  Returns:
     'true'  if successfully deleted
     'false' if library call failed
@end verbatim

Delete the specified temporary file.

This method will delete the specified file @emph{ONLY} if 
the file resides within the temporary subdirectory created by 
@t{acCreateTemppath}.
@end itemize

@hr90

@c - - - Subheading  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@anchor{Communicate With System Clipboard}
@anchor{acClipboardEnable}
@cindex acClipboardEnable
@Subsubheading{Communicate With System Clipboard,
               .................................}

@itemize @BSQUARE
@item @b{bool acClipboardEnable ( gString* version = NULL  );}

@verbatim
  Input  :
     version : (optional, default: null pointer) if specified, 
                pointer to gString object which receives version 
                number of the WaylandCB class _and_ if available, 
                the version number of the wl-clipboard utility.

  Returns: 
     'true'  if system clipboard connection established
     'false' if unable to connect: wl-clipboard utilities 
             not installed or inaccessable, or system error
@end verbatim

Establish communications with the system clipboard.@*
It is assumed that the system clipboard is managed by the Wayland protocol, 
which is the case for most modern Linux distributions.

Create a temporary file in the system temp directory. This file is used for 
communications with the external @LDQ{}@b{@t{wl-clipboard}}@RDQ{} utilities, 
@LDQ{}@b{@t{wl-copy}}@RDQ{} and @LDQ{}@b{@t{wl-paste}}@RDQ{}.@*
Please @pxref{AnsiCmd Clipboard Access} for a discussion of these utilities.

If the @t{wl-clipboard} utilities are installed and accessible, establish 
the connection with the system clipboard.

This is done through a simple handshake sequence which writes a short text 
string to the system clipboard, then reads it back. If the received data 
equal the transmitted data, the connection is verified.

@b{Technical Note:} If the connection was previously established, then the 
call to @t{acClipboardEnable} will reset and re-initialize the connection.

@H5heading{Note on version number report:,▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔}
If the optional version number parameter is included in the call, 
the two version-number sub-strings are returned in the gString object, 
separated by a newline character ('\n') as shown:@*
@verb{|  "x.y.zz\na.b.c"|}@*
where @t{"x.y.zz"} is the WaylandCB version, and @t{"a.b.c"} is the 
reported wl-copy/wl-paste version. Example:@*
@verb{|  0.0.06\n2.2.1|}@*
If communication with the @t{wl-clipboard} utilities cannot be established, 
the version number will be of the form: @LDQ{}@t{0.0.06\nunknown}@RDQ{}
@spi

@anchor{acClipboardDisable}
@cindex acClipboardDisable
@item @b{void acClipboardDisable ( void );}

@verbatim
  Input  : none

  Returns: nothing
@end verbatim

Terminate the connection to system clipboard.

1) Delete the temp files used for communication.@*
2) Delete the WaylandCB-class object.@*
3) Return all resources to the system.

@b{Technical Note:} If the application forgets to call @t{acClipboardDisable} 
on exit, the @t{AnsiCmd} destructor will release the system resources.
@spi

@anchor{acClipboardTest}
@cindex acClipboardTest
@item @b{bool acClipboardTest ( void );}

@verbatim
  Input  : none

  Returns: 'true'  if connection verified, else 'false'
@end verbatim

Test the connection with the Wayland clipboard.

Send a short message to the clipboard, then retrieve the data and compare 
the results.
@spi

@anchor{acClipboardGetText}
@cindex acClipboardGetText
@item @b{int acClipboardGetText ( gString& gsTxt );}

@verbatim
  Input  : gsTxt : (by reference) receives contents of clipboard

  Returns: number of characters returned
@end verbatim

Get a copy of the text data on the clipboard.

@b{Technical Note:} If communication with the system (Wayland) clipboard has 
been established (@pxref{acClipboardEnable}), the data are copied from 
the system clipboard to the local clipboard buffer, and a copy is then 
returned to caller.@*
If communication with the system clipboard has not been established, the 
data currently in the local clipboard buffer are returned.

@display
Within a high-level window (ACWin) or dialog (ACDlg) context, 
copy/cut/paste operations are handled by the @t{skForm/skField} class.
@xref{AnsiCmd Clipboard Access}, below for more information.
@end display
@spi

@anchor{acClipboardSetText}
@cindex acClipboardSetText
@item @b{int acGetClipboardSetText ( const gString& gsTxt );}

@verbatim
  Input  : gsTxt : (by reference) contains data to be written

  Returns: number of characters written
@end verbatim

Write the specified text data to the clipboard.

@b{Technical Note:} The data are first written to the local clipboard 
buffer; then, if communication with the system (Wayland) clipboard has 
been previously established, the data are copied to the system clipboard.

@display
Within a high-level window (ACWin) or dialog (ACDlg) context, 
copy/cut/paste operations are handled by the @t{skForm/skField} class.
@xref{AnsiCmd Clipboard Access}, below for more information.
@end display
@spi

@anchor{acClipboardCharCnt}
@cindex acClipboardCharCnt
@item @b{int acClipboardCharCnt ( void );}

@verbatim
  Input  : none

  Returns: number of (wchar_t) characters (including NULLCHAR)
           Note that a value of one(1) indicates an empty string.
@end verbatim

Returns the number of UTF-32 characters currently in the local clipboard buffer.

@enumerate 1
@item If connected to the system (Wayland) clipboard, return size of 
system clipboard data.@*
Note: This operation will refresh the contents of the local clipboard buffer.
@item If NOT connected to the system clipboard, value returned is the 
number of UTF-32 characters stored on the local clipboard.
@end enumerate

Important Note: It can @b{@strong{NEVER}} be assumed that one 
character equals one byte.
@spi

@anchor{acClipboardByteCnt}
@cindex acClipboardByteCnt
@item @b{int acClipboardByteCnt ( void );}

@verbatim
  Input  : none

  Returns: number of data bytes (including NULLCHAR)
           Note that a value of one(1) indicates an empty string.
@end verbatim

Returns the number of UTF-8 bytes of data on the clipboard.

@enumerate 1
@item If connected to the system (Wayland) clipboard, return size of 
system clipboard data.@*
Note: This operation will refresh the contents of the local clipboard buffer.
@item If NOT connected to the system clipboard, value returned is the 
number of UTF-8 data bytes stored on the local clipboard.
@end enumerate
@c Additional "utility method" descriptions would go here...
@end itemize

@hr40

@c - - - Subheading  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@anchor{AnsiCmd Clipboard Access}
@subheading AnsiCmd Clipboard Access

@enumerate 1
@item The @LDQ{}clipboard@RDQ{} is an area of system memory which can 
be used to transfer text, images and other data among the active 
applications and system processes, @emph{or} between segments of a single 
application.

@item Under most modern flavors of Linux, the @LDQ{}Wayland Protocol@RDQ{} 
manages communications among the system server and its clients, which 
includes the system clipboard.

@item While terminal applications are @b{@emph{technically}} able to 
handle any type of data on the clipboard, practically speaking, 
only text data should be transferred between the terminal window and 
the clipboard.

@item The @t{AnsiCmd} library implements a @LDQ{}@b{@emph{local clipboard}}@RDQ{} 
which performs copy-and-paste operations within the application. The local 
clipboard is under the @t{INCLUDE_API} conditional compile directive.

@item The @t{AnsiCmd} library is built specifically to avoid third-party 
tools; and therefore @emph{direct} communication between the library and 
the @b{@emph{system clipboard}} is not provided; however, an @emph{indirect} 
communications channel to the system clipboard is available, as follows:

@enumerate a
@item The @t{AnsiCmd} interface with the system clipboard is is included 
in this package and is under the @t{INCLUDE_WAYLANDCB} conditional-compilation 
directive which enables this author's (@b{very simple}) @t{WaylandCB} class.@*
Please @pxref{Build Options} for information on including the @t{WaylandCB} 
module in the build.@*

@item The @t{WaylandCB} class object communicates with the system clipboard 
through the Linux utility package, @b{@t{wl-clipboard}}. The @t{wl-clipboard} 
suite was written by Sergey Bugaev and is available on most Linux mirror sites:@*
@b{@verb{|   sudo dnf install 'wl-clipboard'|}} or@*
@b{@verb{|   sudo apt-get install 'wl-clipboard'|}}@*
If the @t{wl-clipboard} utility has been installed on the system and its 
component interface modules (@b{@t{wl-copy}} and @b{@t{wl-paste}}) are 
visible on the path, then the WaylandCB object may be initialized at any time 
after the AnsiCmd (or ACWin) object has been instantiated.@*
@verb{|   AnsiCmd* acptr = new AnsiCmd( ... );|}@*
@verb{|   acptr->acClipboardEnable();|}

@item If communication between the system (Wayland) clipboard and the 
@t{AnsiCmd} local clipboard has been established, then data may be 
exchanged between the current application and all other processes which 
use the system clipboard.

@item If @t{wl-clipboard} is not installed, or if communication cannot 
be established, then the application will be limited to the local clipboard.
@end enumerate

@b{Technical Note:} The standalone @t{WaylandCB} module 
@ifnothtml
@*
@end ifnothtml
(@pxref{By the Same Author}) 
may be compiled directly into the application instead. If needed, this 
would provide the application more direct control of the clipboard interface. 
In that case, to avoid resource conflicts, the @t{AnsiCmd} instance of the 
class should should not be enabled.@*
For full details on the WaylandCB class and the associated test app, 
please visit the author's website.

@cindex copy to cb
@cindex cut to cb
@cindex paste from cb
@cindex clipboard, copy/paste
@item Clipboard operations Within an @t{skForm} object.@*
The @t{AnsiCmd} methods (@ref{acClipboardSetText}, etc.) which send data 
to the clipboard and retrieve data from the clipboard are for use outside 
any window (@t{ACWin} object) or dialog (@t{ACDlg} object).

Within an @t{ACWin} or @t{ACDlg} object, data are exchanged with the 
clipboard via protected member methods: (@t{'cbCopy' and 'cbPaste'}). 
Text selection, Copy, Cut are Paste operations are initiated using the 
@LDQ{}@b{@i{special}}@RDQ{} key associated with the operation while a 
Textbox (ftTB) control has the input focus.@*
@example
Ctrl+C            wcsCOPY    Copy selected text to clipboard
Ctrl+X            wcsCUT     Copy selected text, then delete source text
Ctrl+V            wcsPASTE   Paste text at the IP position
Ctrl+A            wcsSELECT  Select or deselect all
Shift+RightArrow  wcsSRIGHT  Select text moving rightward
Shift+LeftArrow   wcsSLEFT   Select text moving leftward
Shift+UpArrow     wcsSUP     Select text moving upward
Shift+DownArrow   wcsSDOWN   Select text moving downward
@end example
Please @pxref{Decoding the Special Keys} for a complete list of defined 
@LDQ{}special keys@RDQ{}. 

Invoking the @LDQ{}Copy@RDQ{} or @LDQ{}Cut@RDQ{} operation will copy the 
@LDQ{}selected@RDQ{} text of the Textbox field with input focus to the 
clipboard. Note that selected text is 
@uline{underlined} within the field.@*
The data is first copied to the local (@t{AnsiCmd}) clipboard, and then 
if the application has enabled communications with the system clipboard, 
(@pxref{acClipboardEnable}), the data are copied from the local clipboard 
to the system clipboard, where it will be available to all processes of the system.

@i{(If no text within the field has been @LDQ{}selected@RDQ{}, then the Copy/Cut 
command will be ignored.)}

Invoking the @LDQ{}Paste@RDQ{} operation will copy the text stored on the 
clipboard to the @t{IP} (insertion point, i.e. the current cursor position) 
within the Textbox field which has the input focus.@*
If the application has enabled communications with the system clipboard, 
data is first copied from the system clipboard to the local (@t{AnsiCmd}) 
clipboard. Then a copy of the data on the local clipboard is written to 
the target Textbox field.

If there is @LDQ{}selected@RDQ{} text within the target field the selected 
text will be replaced by the clipboard data. Otherwise the clipboard data 
will be inserted into the existing text (if any) of the field.@*
Technical Note: The Paste operation ignores the current state of the 
Insert/Overstrike flag when inserting text.

@i{(If the field with input focus is not a Textbox field, then the Paste 
command will be ignored.)}
@end enumerate
@sp 2

@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.4.11 Development Support:  - - - - - - - - - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Development Support
@unnumbered Development Support
@cindex 03.4.11 Development Support
@cindex support methods

@anchor{ansiTest}
@cindex ansiTest
@itemize @BSQUARE
@item @b{void ansiTest ( dbgArgs& args );}
@verbatim
  Input  : args : (by reference) test to perform and test options
                  major   : specifies the test to perform
                  minor   : specifies test sub-section
                  supp    : specifies sub-test for RGB, etc.

  Returns: nothing
@end verbatim

This method is a gateway to the debugging code. If debugging disabled 
(DEBUG_ANSICMD == 0), then a warning message is displayed.

Perform the specified test of terminal functionality. This functionality 
is divided into different groups. @xref{ansiTest_Menu} method for details.
@spi

@anchor{getDataMembers}
@cindex getDataMembers
@item @b{void getDataMembers ( acaExpand* ab, locale* lo, short& tr, short& tc, 
@ifnothtml
@*@verb{|                     |}
@end ifnothtml
short& fn, bool& fr, bool& ws ) const}

@verbatim
  Input  : lo : receives a pointer to current locale structure
           tr : (by reference) receives terminal rows
           tc : (by reference) receives terminal columns
           fn : (by reference) receives current font number
           fr : (by reference) receives the 'full-reset' flag value
           ws : (by reference) receives the 'wide-stream' flag value

  Returns: nothing
@end verbatim

Returns a copy of the protected data members of the class.

Used primarily by the ACWin class to synchronize terminal configuration, 
but may be used by the curious app designer.
@spi

@anchor{getConfig}
@cindex getConfig
void getConfig ( termConfig& tCfg ) ;

@verbatim
  Input  : tCfg : (by reference) receives configuration data
  Returns: nothing
@end verbatim

For use during development: 
The terminal-configuration data used by the @t{AnsiCmd} class are private 
members; however, during development, it is often useful to retrieve a 
snapshot of the current terminal configuration to verify that the terminal 
is configured as intended. 

@spi

@anchor{tseReport}
@cindex tseReport
void tseReport ( const skForm& skf, const WinPos& wpRpt, uint8_t secret_code ) ;

Although this method is @emph{"technically"} a public method, it is called 
@emph{ONLY} by the test method, Test_SoftEcho() (and its callback function) 
to report user input and keycode processing.                                                      *
@end itemize
@sp 2

@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c 03.4.12 Coding Example: - - - - - - - - - - - - - - - - - - - - - - - - - - -
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Coding Example
@unnumbered Coding Example
@cindex 03.4.11 Coding Example
@cindex code example
@cindex example, coding

The following example demonstrates application startup including creation of 
an @t{AnsiCmd}-class object which provides terminal setup and color attribute 
control capabilities.

Under C++, the @b{@t{'main'}} function does as little as possible.@*
It simply passes the command-line arguments and terminal environment to the 
application class, which returns to @b{@t{'main'}} only when it is time to exit.

The application class is unique to each application, allocating data storage 
and providing the functionality and user interface needed to complete the 
tasks for which it was designed.

The EarthPoints application class is typical of such classes in that it 
leverages well-established classes and library functions to do most of the 
work of the application. The application class provides coordination 
among the various components to produce the desired results. A really good 
application will also add something the world has never seen before.

The EarthPoints application does not aim so high. It is simply a vehicle for 
development and testing of the AnsiCmd class library, which is itself 
interesting, but not particulary innovative. The AnsiCmd library could be 
characterized as a nerd's version of binge-watching a Netflix series during 
a long, long Covid-19 lockdown while on vacation in Guangxi Province.

@example
int main ( int argc, char* argv[], char* argenv[] )
@{
   //* For capture and parsing of command-line arguments.*
   //* (includes the application environment variables)  *
   commArgs ca( argc, argv, argenv ) ;

   //* Instantiate the application class *
   @b{EarthPoints *ep = new EarthPoints ( ca ) ;}

   //* Save a local copy of the exit code, then invoke *
   //* the EarthPoints destructor. This returns all    *
   //* allocated resources to the system, including    *
   //* the allocated AnsiCmd object.                   *
   xCode xcode = ep->exitCode ;
   @b{delete ep ;}

   //* Exit, returning control to the shell.*
   exit ( xcode ) ;

@}  //* End main() *

//* The EarthPoints constructor gathers the command-line arguments, *
//* creates an AnsiCmd class object and exercises its functionality.*
EarthPoints::EarthPoints ( commArgs& ca )
@{
   gString gsOut ;                        // text formatting

   //* Initialize all class data members.*
   this->reset () ;

   //* Parse command-line arguments *
   clArgs userOption = this->GetCommandLineArgs ( ca ) ;

   //* Create the AnsiCmd object and configure terminal settings.*
   //* Note that color attributes are set during initialization. *
   @b{this->ansi = new AnsiCmd ( ca.tConfig ) ;}

   //* Exercise the AnsiCmd library functionality. (sample) *
   @b{this->ColorTheEarth () ;}

   this->ansi->acFlushStreams () ;     // flush the I/O streams

@}  //* End EarthPoints() *

//* The EarthPoint destructor releases the statically *
//* allocated resources back to the system.           *
EarthPoints::~EarthPoints ( void )
@{
   //* Restore original terminal settings *
   if ( this->ansi != NULL )
      delete ( this->ansi ) ;

@}  //* End ~EarthPoints() *

//* This method exercises a sample of  *
//* the AnsiCmd library functionality. *
void EarthPoints::@b{ColorTheEarth ( void )}
@{
   //* Configure the input stream ('stdin') for unbuffered input.*
   this->ansi->@b{acBufferedInput ( false, softEchoA ) ;}

   this->ansi->@b{acEraseArea ( aesERASE_WIN ) ;} // clear the terminal window

   //* The title will be displayed using the color attributes *
   //* specified when creating the AnsiCmd object.            *
   //* (If not specified, then this is the terminal defaults.)*
   WinPos wp( 1, 1 ) ;     // cursor position is window origin
   wp = this->ansi->@b{acWrite ( wp,} "Welcome to Earth!\n"
                                  "-----------------\n\n" ) ;
   // (wp now contains terminal offset 4;1)

   //* Set color attributes and write some text.*
   this->ansi->@b{acSetFgBg ( aesFGb_BLUE, aesBG_MAGENTA ) ;}
   this->ansi->@b{ttyWrite (} "This text is bright blue on a magenta background.\n" ) ;

   this->ansi->@b{acSetMod ( aesUNDERLINE ) ;} // set the 'underline' text modifier
   this->ansi->@b{ttyWrite (} "This text uses the existing color attributes,\n"
                          "with the addition of the 'underline' modifier.\n" ) ;

   this->ansi->@b{acSetMod ( aesUNDERLINE_OFF ) ;} // reset underline modifier

   short termRows, termCols ;
   gString gs ;
   this->ansi->@b{acGetTermDimensions ( termRows, termCols ) ;}
   gs.compose( "Terminal window size is %hd rows by %hd columns.\n",
               &termRows, &termCols ) ;
   this->ansi->@b{ttyWrite ( gs ) ;}

   this->ansi->@b{acSetBg ( aesBG_GREEN ) ;} // set a new background color
   this->ansi->@b{ttyWrite ( "  Press Any Key To Exit... " ) ;}

   this->ansi->@b{acRead () ;}             // wait for user response

   //* Reset color attributes to terminal defaults *
   this->ansi->@b{acReset () ;}

   //* Set the cursor position to the saved position,  *
   //* then erase all text from the cursor position to *
   //* the Bottom Of the Window.                       *
   this->ansi->@b{acSetCursor ( wp ) ;}
   this->ansi->@b{acEraseArea ( aesERASE_BOW ) ;}

   //* Goodbye! *
   this->ansi->@b{acWrite ( wp,} "Thanks for visiting Earth.\n"
                             "Preparing to leave orbit.\n\n" ) ;

   //* Restore all terminal settings to defaults *
   this->ansi->@b{acRestoreTermInfo ( true ) ;}

@}   //* ColorTheEarth() *
@end example
@sp 2
@raisesections
@raisesections

