Upgrade Guide

Appendix B . JAM Documentation: Internal I/O Processing

This chapter describes the following:

All user input to a Panther application is processed through a keyboard translation file or table before being handled by Panther. All output to a character-mode display monitor is processed through a video mapping table.

This translation of input and output is done to avoid code specific to particular displays or terminals, and thereby preserve terminal independence. Panther and Panther applications can run on a variety of terminals, provided that the appropriate keyboard and video configuration files are identified. These configuration files are used by the application at initialization to establish the keyboard and video translation.

Processing Keyboard Input

Keystrokes are processed in three steps:

  1. The sequence of characters generated by one key is identified.
  2. The sequence is translated to an internal value, or logical character.
  3. The internal value is either acted upon or returned to the application (key routing).

All three steps, described in this section, are table-driven. Hooks are provided at several points for application processing; refer to Chapter 44, "Installed Event Functions," in Application Development Guide.

Logical Keys

Panther processes characters internally as logical values, which usually correspond to the physical ASCII codes used by terminal keyboards and displays. Panther uses the key translation file to map specific physical keys or sequences of physical keys to logical values, and the video file's MODE and GRAPH entries to map logical characters to video output. For most keys, such as displayable data characters, no explicit mapping is necessary. Certain ranges of logical characters are interpreted specially by Panther:

0x0100 to 0x01ff

Operations such as tab, scrolling, cursor motion

0x6101 to 0x7801

Function keys PF1 to PF24

0x4101 to 0x5801

Shifted function keys SPF1 to SPF24

0x4103 to 0x5a03


0x6102 to 0x7802

Application keys APP1 to APP24

Key Translation

The first two steps in Panther's processing of keyboard input–identification and translation–are controlled by the binary key translation file, loaded at initialization. Panther finds the file's name in a setup file or in the environment (refer to the Configuration Guide for details). The binary file is derived from an ASCII file that you can modify with any text editor.

Panther assumes that the first input character of a multi-character key sequence is a control character in the ASCII chart (0x00-0x1f, 0x7f, 0x80-0x9f, or 0xff) and attempts to translate the character to a single logical key. Characters outside this range are assumed to be displayable characters and are not translated.

Note: This algorithm assumes that a timing interval (KBD_DELAY entry in the video file) has not been specified. For more information, refer to KBD_DELAY in Configuration Guide.

On receiving a control character, the keyboard input function sm_getkey searches the key translation file for a sequence beginning with that character. If no match is found on the first character, Panther accepts the key without translation. If a match is found on the first character, an exact match, sm_getkey returns the indicated value. The search continues through subsequent characters until one of the following conditions is true:

The latter condition is of some importance: if the user presses a function key that is not defined in the file, Panther must know where the key sequence ends. The following algorithm is then used:

With Timing Interval Set

If you have a KBD_DELAY entry in your video file, you can specify key sequences in the key translation file that are substrings of other sequences. For example, the sequences ESC and ESC [ C can both have logical values, even though one is a substring of the other. In this case, Panther waits the specified timing interval, as indicated in the KBD_DELAY entry, between processing characters to determine if a character is a single keystroke or belongs to a sequence of keystrokes.

Key Routing

The third step in processing keyboard input is handled by the library function sm_input. This function calls sm_getkey to obtain the translated value of the key. It then decides what to do based on the following rules:

Value Greater Than 0x1ff

If the logical value is greater than 0x1ff, sm_input returns the value as the return code.

Value Between 0x01 and 0x1ff

If the value is between 0x01 and 0x1ff, the key is translated via the key translation file. The processing of the key is then determined by a routing table. You can alter the default behavior of keys (cursor control) within this range with the library function sm_keyoption as well as set the routing information for a particular key. The routing value consists of two bits, examined independently, so four different actions are possible:

The default settings are ignored for ASCII and extended ASCII control characters (0x01 - 0x1f, 0x7f, 0x80 - 0x9f, 0xff), and EXECUTE only for all others. The default setting for displayable characters is EXECUTE. All other ASCII and extended ASCII characters are ignored. The function keys (PF1 to PF24, SPF1 to SPF24, APP1 to APP24, and ABORT) are not handled through the routing table. Their routing is always RETURN, and cannot be altered. All other function keys (EXIT, SPGU etc.) are initially set to EXECUTE.

Changing Key Actions at Runtime

You can program your application to change key actions at runtime by using sm_keyoption. For example, to disable the Backtab key, you execute the following function:

call sm_keyoption(status, BACK, KEY_ROUTING, KEY_IGNORE giving status)

To make the field erase key return to the application program, use:

call sm_keyoption(status, FERA, KEY_ROUTING, RETURN giving status)

Logical key mnemonics are defined in the smkeys.h file in the include directory.

Processing Terminal Output

Panther defines a set of logical screen operations (such as positioning the cursor) and stores the character sequences for performing these operations in a video file specific to the display. Logical display operations and the coding of sequences are described in Chapter 7, "Video File," in Configuration Guide.

This section describes the ways in which Panther uses and ultimately, the way applications use the information encoded in the video files to determine how and what output your terminal displays.

How Panther Handles Output

Panther uses a delayed write output scheme to minimize unnecessary and redundant output to the display. No output at all is done until the display must be updated, either because keyboard input is solicited or the library function sm_flush is called. Instead, the runtime system does screen updates in memory and keeps track of the display positions. Flushing begins when the keyboard is opened; but if you type a character while flushing is in progress, the runtime system processes it before sending any more output to the display. Therefore, you can type ahead on slow displays. You can force the display to be updated by calling sm_flush.

Graphics Characters and Alternate Character Sets

Many terminals support the display of graphics or special characters through alternate character sets. Panther provides 8-bit alternate character sets–for example, those that translate from IBM PC extended character to Latin-1. These tables can be installed by calling the library function sm_xlate_table. Control sequences switch the terminal among the various sets, and characters in the standard ASCII range are displayed differently in different sets. Panther supports 8-bit to 7-bit translations via the MODEx and GRAPH entries in the video file.

The seven MODEx sequences (where x is 0 to 6) switch the terminal into a particular character set. MODE0 must be the normal character set. The GRAPH command maps logical characters to the mode and physical character necessary to display them. It consists of a number of entries whose form is logical value = mode physical-character.

When Panther needs to output logical value it first transmits the sequence that switches to mode, then transmits physical-character. It keeps track of the current mode to avoid redundant mode switches when a string of characters in one mode (such as a graphics border) is being written. MODE4 through MODE6 switch the mode for a single character only.