$ cc -о badterm badterm.с -lncurses
$ ./badterm
'unlisted': unknown terminal type.
$
Обратите внимание на строку компиляции в примере: в этой системе Linux мы используем реализацию ncurses библиотеки curses со стандартным заголовочным файлом, находящимся в стандартном каталоге. В таких системах вы можете просто включить файл curses.h и задать -lncurses
для библиотеки.
В функции выбора пункта меню хорошо было бы иметь возможность очищать экран, перемещать курсор по экрану и записывать его положение на экране. После вызова функции setupterm
вы можете обращаться к характеристикам базы данных terminfo с помощью вызовов трех функций, по одной на каждый тип характеристики:
#include
int tigetflag(char *capname);
int tigetnum(char *capname);
char *tigetstr(char *capname);
Функции tigetflag
, tigetnum
и tigetstr
возвращают значения характеристик terminfo булева или логического, числового и строкового типов соответственно. В случае сбоя (например, характеристика не представлена) tigetflag
вернет -1, tigetnum
— -2, a tigetstr
— (char*)-1.
Вы можете применять базу данных terminfo для определения размера экрана терминала, извлекая характеристики cols
и lines
с помощью следующей программы sizeterm.c:
#include
#include
#include
#include
int main {
int nrows, ncolumns;
setupterm(NULL, fileno(stdout), (int *)0);
nrows = tigetnum("lines");
ncolumns = tigetnum("cols");
printf("This terminal has %d columns and %d rows\n", ncolumns, nrows);
exit(0);
}
$ echo $TERM
vt100
$ ./sizeterm
This terminal has 80 columns and 24 rows
Если запустить эту программу в окне рабочей станции, вы получите результат, отражающий размер текущего окна:
$ echo $TERM
xterm
$ ./sizeterm
This terminal has 88 columns and 40 rows
$
Если применить функцию tigetstr
для получения характеристики перемещения курсора (cup
) терминала типа xterm, вы получите параметризованный ответ: \Е[%p1%d;%p2%dH
.
Этой характеристике требуются два параметра: номер строки и номер столбца, в которые перемещается курсор. Обе координаты измеряются, начиная от нулевого значения в левом верхнем углу экрана.
Вы можете заменить параметры в характеристике реальными значениями с помощью функции tparm
. До девяти параметров можно заменить значениями и получить в результате применяемую escape-последовательность символов.
#include
char *tparm(char *cap, long p1, long p2, ..., long p9);
После формирования escape-последовательности с помощью tparm
, ее нужно отправить на терминал. Для корректной обработки этой последовательности не следует пересылать строку на терминал с помощью функции printf
. Вместо нее примените одну из специальных функций, обеспечивающих корректную обработку любых задержек, необходимых для завершения операции, выполняемой терминалом. К ним относятся следующие:
#include
int putp(char *const str);
int tputs(char *const str, int affcnt, int (*putfunc)(int));
В случае успешного завершения функция putp
вернет константу OK
,в противном случае — ERR
. Эта функция принимает управляющую строку терминала и посылает ее в стандартный вывод stdout.
Итак, для перемещения в строку 5 и столбец 30 на экране можно применить блок программного кода, подобный приведенному далее:
char *cursor;
char *esc_sequence;
cursor = tigetstr("cup");
esc_sequence = tparm(cursor, 5, 30);
putp(esc_sequence);
Функция tputs
предназначена для ситуаций, в которых терминал не доступен через стандартный вывод stdout
, и позволяет задать функцию, применяемую для вывода символов. Она возвращает результат заданной пользователем функции putfunc
. Параметр affcnt
предназначен для обозначения количества строк, подвергшихся изменению. Обычно он устанавливается равным 1. Функция, используемая для вывода строки, должна иметь те же параметры и возвращать тип значения как у функции putfunc
. В действительности putp(string)
эквивалентна вызову tputs (string, 1, putchar)
. В следующем примере вы увидите применение функции tputs
, используемой с функцией вывода, определенной пользователем.