Features


A Simple Line Input Function

Philip J. Erdelsky


Phillip J. Erdelsky is an R&D engineer with over eigth years experience in C programming. He can be reached at Data/Ware Development, Inc., 9449 Carroll Park Dr., San Diego, CA 92121, or on Compuserve at 75746,3411.

Prompting the operator for a line of text, such as a name or number, is part of nearly every user interface, even the GUI-est. Often only a small area of the screen can be dedicated to this purpose, but the interface must occasionally accept more text than can fit into the area. Text that won't fit usually must be scrolled horizontally.

A function called line_input() should perform this task just about anywhere. It requires only two interface functions: key(), which returns a code for each key the operator strikes, without echoing it, and display(), which sends a character to the screen. The function was written for MS-DOS, but can be adapted to other environments by changing the interface functions and the codes used for control keys. The key() function is called from only one place and may be coded in-line. You can easily remove unneeded line editing features.

The only control character that display() must recognize is the backspace ('\b'), which moves the cursor one place to the left. In the accompanying example, it also recognizes three non-ASCII characters, but these can be removed if suitable substitutes can be found. The key() function must recognize several control keys and will probably have to be modified if used in other environments. With regard to non-control characters, key() and display() must be compatible with each other — i.e., display (key()) must display the character on the key that was struck.

In Listing 1, key() and display() MS-DOS function calls number 8 and 2, respectively. They have all the required properties, although they are rather slow and have some features, such as the use of Ctrl-C as a break character, that make them unsuitable for some applications. For each special key, MS-DOS function 8 returns a two-byte sequence that key() collapses into a single integer code. The code was compiled with Turbo C 2.0, but bdos() is also available with other compilers.

The display area begins wherever the cursor is when line_input() is called, and it extends to the right the number of spaces specified by the display_length parameter. The text buffer supplies the text that is to be shown in the display area initially, and receives the edited input. The buffer must be large enough to hold the number of characters specified by the text_length parameter, plus a terminating zero, and will ordinarily be larger than the width of the display area.

Because operator input is an inherently slow operation, the function was written to minimize the code size, not to maximize execution speed. It redisplays the entire display area after each keystroke. Consequently, its response can be quite slow if the display area is wide and output to the screen is slow.

The function displays a pair of arrows at each end of the display area to indicate when text has been scrolled off that end. However, this feature is easy to remove if it interferes with the rest of the display.

A special character is substituted for each space in the display (but not in the text buffer) to make spaces visible. This feature is also easy to remove.

Of course, the display area and the arrows at each end must fit on the screen. At the right end, you usually need to leave one space between the arrows and the right edge of the screen so the cursor will not drop to the next line when the arrows are displayed.

The Home, End and Del keys and the left and right arrow keys are used for line editing. The Enter key is used to terminate the editing. It is easy, however, to add other terminator keys. Line_input() returns the code for the terminator key as its functional value.

The initial value of k in the function must be the code for either the Home or End key. The initial contents of the text buffer will then be displayed either left justified or right justified, and the cursor will be positioned either at the beginning or end of the text, respectively.

An alternate form of line_input() for PCs uses BIOS calls for keyboard input and direct screen access for screen output. The first parameter is a pointer to the left end of the display area. This form is so much faster that it gives good results on the slowest PCs, even though the object code is no larger. However, it is not portable, except perhaps to another system that also features direct screen access.

The alternate form does not use the cursor. Instead, it makes its own cursor by displaying the character under the cursor in reverse video. The arrows at each end are brighter than other characters. The choice of display attributes presumes a monochrome monitor, but you can substitute other attributes if you're using a color monitor.

Listing 2