|
|
The example program termhl shown in ``Example of terminfo program'' shows a simple use of terminfo routines. It is a version of ``The highlight program'' that does not use the higher level curses routines. termhl can be used as a filter. It includes the strings to enter bold and underline mode and to turn off all attributes.
/* * A terminfo level version of the highlight program. */#include <ocurses.h> #include <oterm.h>
int ulmode = 0; /* Currently underlining */
main(argc, argv) int argc; char **argv; { FILE *fd; int c, c2; int outch();
if (argc > 2) { fprintf(stderr, "Usage: termhl [file]\n"); exit(1); }
if (argc == 2) { fd = fopen(argv[1], "r"); if (fd == NULL) { perror(argv[1]); exit(2); } } else { fd = stdin; } setupterm((char*)0, 1, (int*)0);
for (;;) { c = getc(fd); if (c == EOF) break; if (c == '\') { c2 = getc(fd); switch (c2) { case 'B': tputs(enter_bold_mode, 1, outch); continue; case 'U': tputs(enter_underline_mode, 1, outch); ulmode = 1; continue; case 'N': tputs(exit_attribute_mode, 1, outch); ulmode = 0; continue; } putch(c); putch(c2); } else putch(c); } fclose(fd); fflush(stdout); resetterm(); exit(0); }
/* * This function is like putchar, but it checks for underlining. */ putch(c) int c; { outch(c); if (ulmode && underline_char) { outch('\b'); tputs(underline_char, 1, outch); } }
/* * Outchar is a function version of putchar that can be passed to * tputs as a routine to call. */ outch(c) int c; { putchar(c); }
Example of terminfo program
Let us discuss the use of the function tputs(cap, affcnt, outc) in this program to gain some insight into the terminfo routines. tputs applies padding information. Some terminals have the capability to delay output. Their terminal descriptions in the terminfo database probably contain strings like $<20>, which means to pad for 20 milliseconds (see ``3. Specify capabilities''). tputs generates enough pad characters to delay for the appropriate time.
tput has three parameters. The first parameter is the string capability to be output. The second is the number of lines affected by the capability. (Some capabilities may require padding that depends on the number of lines affected. For example, insert_line may have to copy all lines below the current line, and may require time proportional to the number of lines copied. By convention affcnt is 1 if no lines are affected. The value 1 is used, rather than 0, for safety, since affcnt is multiplied by the amount of time per item, and anything multiplied by 0 is 0.) The third parameter is a routine to be called with each character.
For many simple programs, affcnt is always 1 and outc always calls putchar. For these programs, the routine putp(cap) is a convenient abbreviation. termhl could be simplified by using putp.
Now to understand why you should use the curses level routines instead of terminfo level routines whenever possible, note the special check for the underline_char capability in this sample program. Some terminals, rather than having a code to start underlining and a code to stop underlining, have a code to underline the current character. termhl keeps track of the current mode, and if the current character is supposed to be underlined, outputs underline_char, if necessary. Low level details such as this are precisely why the curses level is recommended over the terminfo level. curses takes care of terminals with different methods of underlining and other terminal functions. Programs at the terminfo level must handle such details themselves.
termhl was written to illustrate a typical use of the terminfo
routines.
It is more complex than it need be in order to illustrate
some properties of terminfo programs.
The routine
vidattr
(see
curses(3ocurses))
could
have been used instead of directly outputting
enter_bold_mode,
enter_underline_mode,
and
exit_attribute_mode.
In fact, the program would be more robust if it did, since there are
several ways to change video attribute modes.