Testing Capabilities in Terminals and Emulators
G. Clark Brown
Introduction
Whether you are configuring an application to work with
ASCII terminals,
PC-based terminal emulators, or terminal windows on
workstations,
you must be able to create accurate terminal entries
in some terminal
capabilities database. This article describes a method
and two tools
for testing the control characters and escape sequences
that are used
to manage the terminal display. With these resources,
you can build
termcap, terminfo, and similar database entries that
work.
Databases of Capabilities
Application programs use terminal capabilities to move
the
cursor around the screen, change character attributes,
read and program
function keys, display special characters, and clear
parts of the
screen. These capabilities are described in a database
that the program
can read to find out what control characters or escape
sequence to
send to perform a particular function. There are three
types of databases
for terminal capabilities used by applications under
UNIX and the
other Open Systems operating systems.
The oldest UNIX terminal capabilities database is termcap.
This database is implemented as a file, usually /etc/termcap,
that has a text entry for each type of terminal or emulator.
The first
line of each entry must start in column one and consists
of several
names for the terminal type separated by vertical bars
(|). When the
application program starts, it uses the environment
variable TERM
to get the name of the user's terminal type. The application
then
finds this name in the termcap file and uses the capabilities
on that and succeeding lines. Some versions of XENIX,
instead, make
the entire termcap file entry available in the environment
variable TERMCAP.
The second type of "standard" UNIX terminal
capabilities database
is terminfo (an updated version of termcap). In this
database, each terminal entry is kept in a separate
binary file, usually
in the /usr/lib/terminfo directory. These entries are
stored
in the database using the tic(1M) (terminfo compile)
command. On most systems the database entries can be
listed using
the infocmp(1), untic(1), or tid(1) commands.
Even on systems without a command to list entries, you
can look at
individual capabilities by examining the source listings
in the terminfo.src
files. terminfo is usually used for system programs
like the
vi(1) editor. Again, the application program uses the
TERM
environment variable to find the appropriate entry.
However, with
terminfo the entry will be a file like /usr/lib/terminfo/v/vt100
that contains the escape codes and control characters
in binary form.
On some systems, the name of the actual directory will
be loaded in
the TERMINFO environment variable.
While most system programs use either the termcap or
terminfo
databases, many third-party applications use a private
format database,
for example, WordPerfect's *.trs files, the dBase IV
*.trm files,
and Uniplex's UAP/term directory. Sometimes these files
have the same
format as termcap, but usually they are in some proprietary
format. Sometimes, as in the case of WordPerfect, the
application
package includes a special program for editing the entries
in the
database.
Mismatch Problems
When the terminal or emulator mimics exactly the terminal
the O.S.
vendor used when testing the standard distribution database
entry,
your application will work perfectly (unless the O.S.
vendor made
a mistake). This is not a perfect world, however, and
it is not uncommon
for an application with a "vt220" terminal
entry and the vt220
terminal emulator on your PC or workstation to disagree
about how
a DEC vt220 terminal really behaves. You are faced with
a similar
mismatch when the application package has a database
entry for the
Wyse 60 terminal, but you have a similar terminal that
does not have
all of the same capabilities.
The symptoms of this type of mismatch vary. Sometimes
the screens
will appear so confused that you cannot use the program.
Sometimes
there will be some stray characters on the screen or
the screen will
be shifted up one line. Often, the screen will be correct,
but the
function keys or the arrow keys will not work. In every
case, to correct
the problem, you must make an appropriate new terminal
entry in each
and every functional terminal capabilities database.
Trial and Error Approach
You respond to these mismatches by trying variations
on just the capabilities
you suspect are wrong. Copy the original terminal's
entry to a new
name, edit the new database entry to match the capabilities
of the
new terminal, set the TERM variable for the users that
have
the similar terminal or emulator to this new name, and
then test your
changes by running the application program using the
modified entry.
This approach has several problems. First, the edit-test-edit
cycle
is time-consuming. You must change the database entry
and then run
the application to the point that it failed. Second,
and more important,
it is not always clear which capability in the entry
is causing a
particular problem symptom. Third, if the test application
doesn't
use all of the defined capabilities, the entry may still
fail when
the user attempts to use untested capabilities by running
another
program or a seldom-used part of the same program.
Analytical Approach
For these reasons, it is better to take the analytical
approach of
testing and setting the capabilities one by one. You
can find a description
of each capability in the documentation for termcap,
terminfo,
or the specific application package. You can learn how
to perform
that action on the problem terminal by reading the manual
that comes
with it. If you do not have a manual, or have only the
"User's
Guide" (which usually does not include control
characters and
escape sequences), you should contact the manufacturer
to get a "Technical
Reference" if one is available.
If you cannot get a list of the escape codes that should
work with
this terminal or emulator, you can often use a database
entry for
a similar terminal as a starting point. In either case,
be certain
to test each of the capabilities in the entry on the
target terminal
or emulator. Even when an escape sequence is documented,
you should
test it to be sure that it works the way you think it
does and to
find out what side effects it has.
Problems in Testing
The easiest way to test the action of control characters
and escape
sequences on a terminal or emulator is to sit down at
the screen in
question and type the sequences on the keyboard. This
allows you to
get immediate answers to the question: "How does
this work in
this situation?" and lets you easily set up new
tests based on
those answers.
Unfortunately, the system's line discipline and the
limits of the
shell interfere with this strategy. The line discipline
tends to translate
characters coming from the terminal, and when they are
echoed, it
translates them again on the way back to the terminal.
Consequently,
eight-bit characters, ctrl-S and ctrl-Q, carriage returns,
line feeds, tabs, and others will not always be echoed
back to the
terminal exactly as they were typed. Also, you cannot
use the shell
to echo the characters because many shell programs (like
ksh
and csh) will not echo all characters. If the shell
"eats"
escapes and some control characters, the terminal will
never see them.
A Tool to Echo Characters
The echotest program (Listing 1) disables selected parts
of
the line discipline, enabling it to echo characters
faithfully. Thus,
as long as echotest is running, you should be able to
press
the "Escape" "[" "0" "m"
keys to turn
off character attributes on an ansi terminal, for instance.
On most UNIX and Open Systems operating systems echotest
should
compile and link without changes. (Use the command cc
echotest.c
-o echotest.) Run it by typing echotest on the shell
command
line. echotest -7 will cause it to run in the seven-bit
mode
needed for some communication lines. echotest -x will
enable
xon-xoff flow control. With flow control enabled, the
terminal will
not be overrun, but you will not be able to echo ctrl-Q
and
ctrl-S.
After invoking echotest, begin your test by entering
the escape
sequence to home the cursor and clear the screen. This
sequence is
cl, clear, or clear_screen capability in termcap
and terminfo. To test other capabilities, type in several
lines
of text (using return for carriage return and ctrl-J
for
line feed), then use the cup (cursor_address) sequence
to move back into the middle of the text. Now you should
be able to
erase some of the text with clr_eol (clear to end of
line)
and clr_eos (clear to end of screen). Use smso to start
standout, type some text, use rmso to stop, type some
more
text, etc.
Use this type of testing to try all of the capabilities
in the database.
If you see something in the terminal manual, always
test it by hand
to make sure that it works as advertised. Test for interactions
between
the different capabilities. Questions like "Does
rmso turn
off color?" can be answered quickly and easily.
Keyboard Layout
Special keys like function keys, arrow keys, page up,
print screen,
etc. usually send a series of several characters. These
behaviors
can be included in the database entry to make these
keys work reasonably
in the application program that uses this database.
ANSI terminals like the DEC vt100, the DEC vt220, the
SCO console,
the Dejavu (ICE-10) terminal emulator, and others are
not standardized
in the matter of codes sent by keys. The databases usually
have an
entry for the function and arrow keys at least, and
sometimes also
for the shift-, control-, and even alt-combinations
of function keys.
ANSI terminals usually have two modes for the keypad
and cursor keys:
normal and application. An escape sequence from the
host can switch
the keypad or arrow keys into application mode and then
redefine the
sequences sent by these keys when pressed.
To further complicate this, DEC terminals and compatibles
often have
seven-bit and eight-bit controls mode selection. In
seven-bit controls
mode (not to be confused with seven-bit communications
mode), the
sequences that the keys press are often prefixed with
"Escape"
"[". In eight-bit controls mode, this two-character
sequence
is replaced with the single \0233 character (CSI).
A Tool to Read Keys
To answer the question "What does this key send?"
you need
a simple program that will read the keys you press and
echo back a
text representation of the characters read. This program
must put
the terminal line into raw mode and support seven-bit
mode or xon-xoff
flow control if necessary.
The keytest program (Listing 2) meets these requirements.
It
uses the termio_init and termio_set functions from the
echotest program. Once the line is set correctly, it
reads
the keys you press and echoes them back as text. If
you press ctrl-G,
it will echo "^" "G" (^G). With
keytest
you can quickly determine what sequences to put in the
database under
kf1, khome, etc.
To help keep the output on the screen, keytest echos
a real
carriage return and line feed after it echos "\r"
for a carriage
return pressed. The escape character will display as
"\E";
most control characters show as "^" followed
by the base character.
The DEL character will display as "^?". Printable
characters
are sent through as-is, and most other characters show
as a backslash
followed by the octal value of the character.
When testing the keyboard, keep in mind that many application
programs
reprogram function keys (and even other keys) to send
strings that
are different from the default. This means that you
may have to test
the terminal after the application has completed its
initialization
to get an accurate picture of what is being sent.
Conclusion
These tools and techniques will greatly simplify the
problem of configuring
applications to work with specific terminals or emulators.
For additional
information on terminfo and termcap, see Strang, Mui,
and O'Reilly, termcap & terminfo (O'Reilly &
Associates, Inc.,
1991). Of course, you should also study the manuals
for your version
of UNIX and for your terminal.
About the Author
G. Clark Brown is a senior software engineer at Structured
Software Solutions Inc. in Plano, TX. As developer/support
contact
for SSSI's FacetTerm and Facet/PC products, he deals
with a variety
of installation and configuration problems that relate
to connecting
ASCII terminals to UNIX and making them work with applications.
Clark
has been doing this with applications that he has written
for 16 years
(nine years with UNIX).
|