Section 24.1. Input Handling


24.1. Input Handling

Terminal input-handling is one of the least portable subsystems in the Unix world. BSD sgtty, System V termio, and POSIX termios have all been widely used. The S-Lang library hides this complexity through a few functions designed to make keyboard handling more straightforward and portable.

Writing a program to read one character at a time from the terminal and print each character onto its own line is fairly straightforward:

  1: /* slecho.c */  2:  3: #include <ctype.h>  4: #include <slang/slang.h>  5: #include <stdio.h>  6:  7: int main(void) {  8:     char ch = '\0';  9: 10:     /* 11:        Start SLANG tty handling, with: 12:         -1 default interrupt character (normally, Ctrl-C) 13:          0 no flow control, allowing all characters (except 14:            interrupt) to pass through to the program 15:          1 enable OPOST output processing of escape sequences 16:     */ 17:     SLang_init_tty(-1, 0, 1); 18: 19:     while (ch != 'q') { 20:         ch = SLang_getkey(); 21:         printf("read: %c 0x%x\n", isprint(ch) ? ch: ' ', ch); 22:     } 23: 24:     SLang_reset_tty(); 25: 26:     return 0; 27: } 

This program assumes that /usr/include/slang contains all the S-Lang header files. If this is not the case for your system, you need to change the code (and all other examples in this chapter) appropriately. When you compile and link this sample program, be sure to add -lslang to the link command so that the linker finds the S-Lang functions.

24.1.1. Initializing S-Lang Input Handling

Before any other input handling functions can work, the terminal must be placed in the state that S-Lang expects through the SLang_init_tty() function:

 int SLang_init_tty(int abort_char, int flow_ctrl, int opost); 

The first parameter to SLang_init_tty() is an abort character to use. If -1 is passed, the current tty interrupt character (usually, Ctrl-C) is retained; otherwise, the interrupt character is set to the value passed. Whenever the abort character is entered on the terminal, the kernel sends a SIGINT to the process, which normally terminates the application. Chapter 12 discusses how to handle signals such as SIGINT.

The next parameter turns flow control on and off. Terminal-level flow control allows the user to pause output to the terminal to prevent scrolling and then restart it. Normally, Ctrl-S is used to suspend terminal output and Ctrl-Q enables it. Although this feature is convenient for some line-oriented utilities, programs that take advantage of S-Lang are normally screen-oriented, so it may not be necessary. S-Lang allows applications to turn off this capability, which allows the program to use the Stop and Start keystrokes for other commands. To enable flow control, pass a nonzero value as the second parameter to SLang_init_tty().

The final parameter enables output post processing on the terminal. All the kernel's post processing mechanisms are enabled if the final parameter is nonzero. See page 380 for information on output processing.

24.1.2. Restoring the Terminal State

Once the terminal state has been modified by SLang_init_tty(), the program must explicitly restore the terminal to its original state before exiting. If you do not do this, the terminal will be extremely difficult to use after your program exits. SLang_reset_tty() does not take any arguments, nor does it return one.

If you are writing a program that should suspend properly (normally when the user presses Ctrl-Z), this function also needs to be called when SIGTSTP is received. For more information on handling SIGTSTP properly, see Chapter 15.

When you are developing programs with S-Lang, the program will likely crash more than once during your development, leaving your terminal in a nonstandard state. You can easily fix this by running the command stty sane.

24.1.3. Reading Characters from the Terminal

Once the terminal has been initialized properly, reading single keystrokes is straightforward. The function SLang_getkey() returns a single character from the terminal. However, that does not mean it returns a single keystroke in Unix, many keystrokes return multiple characters. For example, on a VT100 terminal (as well as on many other terminals, including the Linux console) pressing F1 sends four characters to the screen ESC [ [ A (try running slecho and pressing F1 to see what characters it received). Those multiple-character sequences can be mapped to keystrokes via the terminfo database [Strang, 1991B].

SLang_getkey() waits indefinitely for a character to be present before returning. If an error occurs, the function returns 0xFFFF rather than a valid character.[3]

[3] An error occurs if a signal is received while S-Lang is waiting for a keystroke.

24.1.4. Checking for Pending Input

In many cases, you want to check for available characters without blocking. This is handy whenever a program needs to do background processing while polling the user for input (this is especially popular in video games). SLang_input_pending() is defined as follows:

 int SLang_input_pending(int timeout); 

SLang_input_pending() returns true if characters become available within n tenths of seconds. It returns as soon as the characters are available; it returns false if no characters become available within the timeout period. If a timeout period of zero is given, SLang_input_pending() tells whether characters are currently available.

This behavior is easy to see. Just replace the test on the while loop in slecho.c with

 while (ch != 'q' && SLang_input_pending(20)) 

The program now waits a maximum of two seconds for more input. Once two seconds pass without any input, it exits.


    Linux Application Development
    Linux Application Development (paperback) (2nd Edition)
    ISBN: 0321563220
    EAN: 2147483647
    Year: 2003
    Pages: 168 © 2008-2017.
    If you may any questions please contact us: