Cover V01, I01
Article
Listing 1
Listing 2

may92.tar


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).