Previous Page TOC Next Page

Character User Interface (FMLI and ETI)

Other ETI Routines

Introduction


Knowing how to use the basic ETI routines to get output and input and to work with windows, panels, menus, and forms, you can design screen management programs that meet the needs of many users. The ETI library, however, has routines that let you do still more in your program. The following few pages briefly describe some of these routines and what they can help you do-namely, draw simple graphics, use a terminal's soft labels, and work with more than one terminal in a single ETI program.

You should be comfortable using the routines previously discussed and the other routines for I/O and window manipulation discussed on the curses(3X) manual pages before you try to use the following ETI features.

Routines for Drawing Lines and Other Graphics


Many terminals have an alternate character set for drawing simple graphics (or glyphs or graphic symbols). You can use this character set in ETI programs. ETI uses the same names for glyphs as the VT100 line drawing character set.

To use the alternate character set in an ETI program, you pass a set of variables whose names begin with ACS_ to the ETI routine waddch or a related routine. For example,ACS_ULCORNER is the variable for the upper left corner glyph. If a terminal has a line drawing character for this glyph, ACS_ULCORNER's value is the terminal's character for that glyph OR'd ( | ) with the bit-mask A_ALTCHARSET. If no line drawing character is available for that glyph, a standard ASCII character that approximates the glyph is stored in its place. For example, the default character for ACS_HLINE, a horizontal line, is a - (minus sign). When a close approximation is not available, a + (plus sign) is used. All the standard ACS_ names and their defaults are listed on the curses(3X) manual pages.

Part of an example program that uses line drawing characters follows. The example uses the ETI routine box(3X) to draw a box around a menu on a screen. box uses the line drawing characters by default or when | (the pipe) and - are chosen. Up and down more indicators are drawn on the box border (using ACS_UARROW and ACS_DARROW) if the menu contained within the box continues above or below the screen:


Here's another example. Because a default down arrow (like the lowercase letter v) isn't very discernible on a screen with many lowercase characters on it, you can change it to an uppercase V.


For more information, see the curses(3X) pages in this guide.

Routines for Using Soft Labels


Another feature available on most terminals is a set of soft labels across the bottom of their screens. A terminal's soft labels are usually matched with a set of hard function keys on the keyboard. There are usually eight of these labels, each of which is usually eight characters wide and one or two lines high.

The ETI library has routines that provide a uniform model of eight soft labels on the screen. If a terminal does not have soft labels, the bottom line of its screen is converted into a soft label area. It is not necessary for the keyboard to have hard function keys to match the soft labels for an ETI program to make use of them.

Let's briefly discuss most of the ETI routines needed to use soft labels: slk_init, slk_set, slk_refresh, and slk_noutrefresh,slk_clear, and slk_restore.

When you use soft labels in an ETI program, you have to call the routine slk_init before initscr. This sets an internal flag for initscr to look at that says to use the soft labels. If initscr discovers that there are fewer than eight soft labels on the screen, that they are smaller than eight characters in size, or that there is no way to program them, then it will remove a line from the bottom of stdscr to use for the soft labels. The size of stdscr and the LINES variable will be reduced by one to reflect this change. A properly written program, one that is written to use the LINES and COLS variables, will continue to run as if the line had never existed on the screen.

slk_init takes a single argument. It determines how the labels are grouped on the screen should a line get removed from stdscr. The choices are between a 3-2-3 arrangement as appears on NCR terminals, or a 4-4 arrangement as appears on Hewlett-Packard terminals. The ETI routines adjust the width and placement of the labels to maintain the pattern. The widest label generated is eight characters.

The routine slk_set takes three arguments, the label number (1-8), the string to go on the label (up to eight characters), and the justification within the label (0 = left justified, 1 = centered, and 2 = right justified).

The routine slk_noutrefresh is comparable to wnoutrefresh in that it copies the label information onto the internal screen image, but it does not cause the screen to be updated. Since a slk_refresh commonly follows, slk_noutrefresh is the function that is most commonly used to output the labels.

Just as wrefresh is equivalent to a wnoutrefresh followed by a doupdate, so too the function slk_refresh is equivalent to a slk_noutrefresh followed by a doupdate.

To prevent the soft labels from getting in the way of a shell escape, slk_clear may be called before doing the endwin.This clears the soft labels off the screen and does a doupdate. The function slk_restore may be used to restore them to the screen. See the curses(3X) manual pages for more information about the routines for using soft labels.

Working with More Than One Terminal


An ETI program can produce output on more than one terminal at the same time. This is useful for single process programs that access a common database, such as multi-player games.

Writing programs that output to multiple terminals is a difficult business, and the ETI library does not solve all the problems you might encounter. For instance, the programs-not the library routines-must determine the file name of each terminal line, and what kind of terminal is on each of those lines. The standard method, checking $TERM in the environment, does not work, because each process can only examine its own environment.

Another problem you might face is that of multiple programs reading from one line. This situation produces a race condition and should be avoided. However, a program trying to take over another terminal cannot just shut off whatever program is currently running on that line. (Usually, security reasons would also make this inappropriate. But, for some applications, such as an inter-terminal communication program, or a program that takes over unused terminal lines, it would be appropriate.) A typical solution to this problem requires each user logged in on a line to run a program that notifies a master program that the user is interested in joining the master program and tells it the notification program's process ID, the name of the tty line, and the type of terminal being used. Then the program goes to sleep until the master program finishes. When done, the master program wakes up the notification program and all programs exit.

An ETI program handles multiple terminals by always having a current terminal. All function calls always affect the current terminal. The master program should set up each terminal, saving a reference to the terminals in its own variables. When it wishes to affect a terminal, it should set the current terminal as desired, and then call ordinary ETI routines.

References to terminals in an ETI program have the type SCREEN*. A new terminal is initialized by calling newterm(type, outfd, infd). newterm returns a screen reference to the terminal being set up. type is a character string, naming the kind of terminalbeing used. outfd is a stdio(3S) file pointer (FILE*) used for output to the terminal and infd a file pointer for input from the terminal. This call replaces the normal call to initscr, which calls newterm(getenv(''TERM''), stdout, stdin).

To change the current terminal, call set_term(sp) where sp is the screen reference to be made current. set_term returns a reference to the previous terminal.

It is important to realize that each terminal has its own set of windows and options. Each terminal must be initialized separately with newterm. Options such as cbreak and noecho must be set separately for each terminal. The functions endwin and refresh must be called separately for each terminal. The following example shows a typical scenario to output a message to several terminals.

Sending a Message to Several Terminals


See the "The two Program" in Appendix D for a more complete example.

Previous Page Page Top TOC Next Page