| Каталог | Индекс раздела |
| Назад | Оглавление | Вперед |
1. Введение
1.1. Что такое curses?
1.2. Что такое terminfo?
1.3. Взаимодействие curses и terminfo
1.4. Другие компоненты пакета управления терминалом
2. Использование подпрограмм пакета curses
2.1. Что нужно программе для работы с curses
2.1.1. Файл <curses.h>
2.1.2. Подпрограммы initscr(), refresh() и endwin()
2.2. Компиляция программы, которая использует curses
2.3. Выполнение программы, которая использует curses
2.4. Еще о строках, столбцах и подпрограмме initscr()
2.5. Еще об окнах и подпрограмме refresh()
2.6. Несложный ввод/вывод
2.6.1. Вывод
2.6.2. Ввод
2.7. Управление вводом/выводом
2.7.1. Атрибуты вывода
2.7.2. Звонки, свист, вспышки
2.7.3. Опции ввода
2.8. Работа с окнами
2.8.1. Ввод/вывод
2.8.2. Подпрограммы wnoutrefresh() и doupdate()
2.8.3. Новые окна
2.9. Прочие возможности пакета curses
2.9.1. Линии на экране и прочая графика
2.9.2. Использование программируемых меток
2.9.3. Работа с несколькими терминалами сразу
3. Использование подпрограмм пакета terminfo
3.1. Что нужно программе для работы с terminfo
3.2. Компиляция и выполнение программ, которые используют terminfo
3.3. Пример программы, работающей с terminfo
4. Использование базы данных terminfo
4.1. Создание описания терминала
4.1.1. Название терминала
4.1.2. Выяснение характеристик терминала
4.1.3. Указание характеристик терминала
4.1.3.1. Основные характеристики
4.1.3.2. Характеристики экрана
4.1.3.3. Характеристики клавиатуры
4.1.3.4. Параметризованные цепочки
4.1.4. Компиляция описания
4.1.5. Тестирование описания
4.2. Печать и сравнение описаний в базе данных terminfo
4.3. Преобразование termcap-описания в terminfo-описание
5. Примеры программ, работающих с curses
5.1. Программа editor
5.2. Программа highlight
5.3. Программа scatter
5.4. Программа show
5.5. Программа two
5.6. Программа window
Многие коммерческие программные системы имеют в своем составе программы, управляющие вводом и выводом на терминал. Такая программа может перемещать курсор, показывать меню, делить экран терминала на окна или форматировать экран для облегчения ввода и извлечения информации из базы данных.
В этой главе объясняется, как разрабатывать программы, работающие с терминалом в системе UNIX, используя пакет подпрограмм, называемый cursescurses/terminfo . Этот пакет включает библиотеку подпрограмм на языке C, базу данных и набор вспомогательных средств системы UNIX. Назначение данной главы - не описание всех компонент пакета, а предоставление пользователю возможности немедленно приступить к написанию программ, работающих с терминалом. Здесь рассматриваются только наиболее часто используемые подпрограммы, в отношении же остальных делается ссылка на curses(3X) и terminfo(4) в Справочнике программиста. Держите эту книгу под рукой на случай, если Вам нужно будет узнать подробности о какой-либо из описанных (или не описанных) здесь подпрограмм.
Для использования cursescurses/terminfo нужно быть знакомым с языком программирования C, так как подпрограммы пакета написаны именно на нем. Кроме того, необходимо знать стандартный пакет средств ввода/вывода системы UNIX для языка C [см. stdio(3S)]. Вы сможете создавать разнообразные программы для работы с терминалом, пользуясь этими знаниями и пониманием принятого в системе UNIX принципа опоры на работу, уже сделанную другими.
Данная глава делится на пять разделов:
Curses(3X) - это библиотека подпрограмм, которые используются для разработки программ, осуществляющих ввод/вывод на экран терминала в системе UNIX. Эти подпрограммы являются функциями C или макросами. Многие из них напоминают подпрограммы из стандартной библиотеки языка C. Например, имеется подпрограмма printw(), весьма похожая на printf(3S) и подпрограмма getch(), подобная getc(3S). В Вашем банке программа - автоматический кассир может использовать printw() для вывода меню и getch() для приема Ваших запросов на изъятие сумм (или, что даже лучше, на их вклад). Экранный текстовый редактор - такой, например, как редактор vi(1) системы UNIX, также может использовать эти и другие подпрограммы пакета curses.
Название curses принято из-за того, что данная библиотека подпрограмм оптимизирует движение курсора, то есть минимизирует это движение в процессе обновления экрана. Например, если (используя подпрограммы пакета curses) Вы разработали текстовый редактор и редактируете фразу
curses/terminfo - отличный пакет для работы с экраном
так, чтобы она читалась:
curses/terminfo - лучший пакет для работы с экраном
то программа выведет только 'лучший' вместо 'отличный', остальные символы останутся без изменений. Оптимизация управления курсором называется еще оптимизацией вывода, поскольку минимизируется объем передаваемых данных, то есть вывод.
При оптимизации управления курсором запись на экран производится таким способом, который соответствует терминалу, с которым работает программа, использующая пакет curses. Таким образом, библиотека curses позволяет делать все необходимое на терминалах различных типов. Подпрограммы пакета просматривают базу данных terminfo (подробно описывается ниже), чтобы найти подходящее описание терминала.
Чем будет полезна оптимизация управления курсором Вам и тем, кто будет пользоваться Вашими программами? Во-первых, она сэкономит Ваше время, затрачиваемое на описание того, как именно Вы хотите изменять содержимое экрана. Во-вторых, она сохранит время пользователя за счет уменьшения времени, необходимого для переписывания экрана. В-третьих, она уменьшит загрузку линий связи системы UNIX в период обновления экрана. В-четвертых, Вам не придется задумываться об огромном количестве терминалов, на которых Ваша программа, быть может, будет работать.
Далее приводится текст простой программы, работающей с curses. Она обращается к нескольким подпрограммам curses для того, чтобы передвинуть курсор на середину экрана и вывести цепочку символов BullsEye. Все эти подпрограммы описываются в следующем разделе, который называется Использование подпрограмм пакета curses. Чтобы понять, что делают эти подпрограммы, Вам достаточно взглянуть на их имена.
#include <curses.h>
main ()
{
initscr ();
move (LINES/2 - 1, COLS/2 - 4);
addstr ("Bulls");
refresh ();
addstr ("Eye");
refresh ();
endwin ();
}
Далее приводится простая командная процедура, использующая базу данных terminfo.
# Очистить экран и показать позицию 0,0
#
tput clear
tput cup 0 0 # или tput home
echo "<- это позиция 0 0"
#
# Показать позицию 5,10
#
tput cup 5 10
echo "<- это позиция 5 10"
Подпрограммы пакета curses извлекают из базы данных terminfo информацию о том типе терминала, на котором программа выполняется. В дальнейшем этот терминал мы будем называть текущим терминалом.
Предположим, что программа, текст которой приведен в конце раздела Что такое curses?, выполняется на терминале AT&T Teletype 5425. Чтобы отработать должным образом, то есть вывести BullsEye в центр экрана, программа должна иметь информацию о количестве строк и столбцов на экране. Эти данные хранятся в описании терминала AT&T Teletype 5425 в базе данных terminfo. Чтобы получить их, программе, работающей с curses, достаточно знать только название терминала, на котором она выполняется. Можно передать ей это название, поместив его в переменную окружения $TERM при подключении к системе UNIX, или путем присвоения значения и помещения в окружение переменной $TERM в Вашем файле .profile [см. profile(4)]. Располагая значением $TERM, программа, использующая curses, может извлечь описание текущего терминала из базы данных terminfo.
Пусть, например, в .profile включены следующие строки:
TERM=5425
export TERM
tput init
В первой строке устанавливается название терминала, а во второй
оно помещается в окружение. Третья строка примера требует от
системы UNIX проинициализировать текущий терминал, то есть
обеспечить соответствие состояния терминала его описанию в базе
данных terminfo. (Порядок этих строк
важен. Чтобы при вызове
tput произошла правильная инициализация текущего терминала,
$TERM должна быть уже установлена и помещена в окружение).
Если, имея такие строки в файле .profile, Вы запустите программу,
работающую с curses, она получит нужную ей информацию
о терминале из файла, соответствующего значению $TERM,
то есть из файла /usr/lib/terminfo/a/att5425.
Как было сказано выше, пакет управления терминалом обычно называют
curses/terminfo. Однако, в
нем есть и другие компоненты,
из которых мы уже упомянули, в частности, tic(1M). Далее
приводится полный список компонент, рассматриваемых в этом руководстве:
1.4. Другие компоненты пакета управления терминалом
| captoinfo(1M) | Средство для перевода описаний терминалов, созданных под ранними версиями системы UNIX, в формат terminfo. |
| curses(3X) infocmp(1M) |
Средство для печати и сравнения скомпилированных описаний терминалов. |
| tabs(1) | Средство для установки нестандартных позиций табуляции. |
| terminfo(4) tic(1M) |
Компилятор описаний терминалов для базы данных terminfo. |
| tput(1) | Средство для установки позиций табуляции на терминале и получения значений его характеристик. |
См. также profile(4), scr_dump(4), term(4) и term(5). Более подробную информацию об этих компонентах см. в Справочнике программиста и Справочнике пользователя.
В этом разделе рассматриваются основные подпрограммы пакета curses, которые используются при создании интерактивных терминальных программ. В начале раздела описаны подпрограммы (и другие компоненты), которые нужны для нормальной работы любой программе, работающей с пакетом (в дальнейшем мы для краткости будем иногда называть такие программы curses-программами). В оставшейся части раздела рассказывается о том, как компилировать и выполнять такую программу. Наконец, описываются наиболее часто применяемые подпрограммы, которые делают следующее:
По мере описания подпрограмм мы приводим простые программы, иллюстрирующие
их применение. Кроме того, мы ссылаемся на группу
более значительных примеров, находящихся в разделе Примеры
программ, работающих с curses. Эти последние
программы более
глубоки и зачастую используют подпрограммы, которые здесь не
обсуждаются, поэтому держите под рукой справочник
curses(3X).
Если программа использует пакет curses,
она должна включать
файл <curses.h> и вызывать подпрограммы
initscr(), refresh(),
или им подобные, а также endwin().
В файле <curses.h> определяются
несколько глобальных переменных
и структур данных, а также те из подпрограмм пакета, которые в
действительности являются макросами.
Начнем с рассмотрения определяемых в файле переменных и структур
данных. В файле <curses.h> определены
параметры всех подпрограмм, входящих в пакет curses.
Кроме того, определяются целочисленные переменные
LINES и COLS, которым при выполнении
программы назначаются значения соответственно вертикального и
горизонтального размера экрана. Это делается при вызове описываемой
ниже подпрограммы initscr(). В файле определяются также
константы OK и ERR. Большинство
подпрограмм curses возвращают
OK при нормальном завершении и ERR при возникновении ошибки.
Примечание
Рассмотрим теперь макроопределения. Многие подпрограммы
curses
определены в <curses.h> как
макросы, которые обращаются к другим подпрограммам и макросам
из curses. Например, refresh()
является макросом. Определение
показывает, что вызов refresh расширяется в обращение к также
входящей в curses подпрограмме wrefresh().
Эта последняя, в свою очередь, вызывает две другие подпрограммы
curses: wnoutrefresh() и
doupdate(). Многие подпрограммы обеспечивают
нужный результат, группируя два-три обращения к другим.
Предостережение
Одно последнее замечание о <curses.h>: он
автоматически включает <stdio.h>, файл интерфейса с
драйвером tty, <termio.h>. Повторное
включение в программу этих файлов безвредно, но и бессмысленно.
Подпрограммы initscr(), refresh() и
endwin() приводят терминал
в состояние "работа с curses", обновляют
содержимое экрана и
восстанавливают терминал в состоянии "вне curses"
соответственно. Для уяснения действия каждой из этих подпрограмм
воспользуемся еще раз нашим простым примером.
Curses-программа начинается обычно с вызова
initscr(); это достаточно сделать один раз. Подпрограмма
initscr() определяет тип
терминала, на котором выполняется программа, по значению переменной
окружения $TERM, как это описано в разделе Взаимодействие
curses и terminfo. Затем
подпрограмма инициализирует все
переменные и структуры данных, описанные в
файле <curses.h>.
initscr() присваивает переменным LINES
и COLS значения, соответствующие терминалу,
на котором выполняется программа. Например, если используется
Teletype 5425, она присвоит значение 24 переменной LINES,
а значение COLS станет равным 80. Если возникает ошибка,
подпрограмма записывает сообщение об этом в stderr
и завершает работу.
Ввод/вывод при выполнении программы производится подпрограммами, подобными
использующимся в примере move() и addstr(). Например,
требует перемещения курсора в точку, находящуюся несколько
левее центра экрана. Затем
Внимание!
При вызове подпрограмм типа move() и addstr()
содержимое физического экрана терминала не меняется. Экран обновляется
только при вызове refresh(). До такого вызова изменяется
только внутреннее представление экрана, которое называется окном. Эту
весьма важную концепцию мы обсудим далее в разделе Еще об окнах
и подпрограмме refresh().
В заключение отметим, что программа, работающая
с curses, заканчивается
вызовом endwin(). Эта подпрограмма восстанавливает
прежнее состояние терминала и помещает курсор в левый нижний
угол экрана.
Компилируйте такую программу, как обычную программу на языке C,
командой cc(1) (см. Справочник программиста), которая вызывает
компилятор языка C.
Подпрограммы обычно хранятся в библиотеке
/usr/lib/libcurses.a. Чтобы редактор внешних связей
просматривал эту
библиотеку, в команде cc необходимо указать опцию -l.
Общий формат командной строки для компиляции программы,
работающей с curses, таков:
Файл.c - это имя файла с исходным текстом программы;
файл - имя выполнимого объектного файла.
В процессе своей работы подпрограммы curses
опираются на информацию из окружения пользователя. В
частности, пользователю такой программы обычно нужно включить в свой
файл .profile следующие три строки:
Смысл этих строк объясняется в разделе Взаимодействие
curses и terminfo. Пользователи
curses-программы могут, кроме того, установить в файле
.profile значения переменных окружения $LINES,
$COLUMNS и $TERMINFO, однако, в отличие от
случая с $TERM, делать это не обязательно.
Если Ваша curses-программа не работает
должным образом, Вы,
возможно, попытаетесь ее отладить с помощью sdb(1), как это
описывается в Справочнике программиста. Пользуясь sdb,
нужно учитывать ряд обстоятельств. Во-первых,
curses-программа интерактивна
и контролирует положение курсора. Однако, интерактивный
отладчик, подобный sdb, может произвести на экране
изменения, о которых не будет знать отлаживаемая программа.
Во-вторых, программа, работающая с curses,
выводит в окно до
тех пор, пока не будет вызвана refresh() или подобная ей
подпрограмма. В связи с такой задержкой вывода на экран, отладка
его правильности может быть затруднена.
В-третьих, во входящих в curses
макросах нельзя установить точки прерывания. Вместо макросов нужно
использовать подпрограммы,
к которым эти макросы обращаются - например, к wrefresh()
вместо refresh(), Более подробную информацию о макросах см. выше в
разделе Файл <curses.h>.
Как указывалось ранее, подпрограммы curses не
обновляют экран, пока не будет вызвана refresh(). Когда
refresh() вызывается, все данные, накопленные для вывода,
пересылаются на экран текущего терминала.
Эффект использования окна во многом подобен эффекту использования
буфера при работе с редактором системы UNIX. Например, когда Вы
редактируете файл при помощи vi(1), все изменения содержимого
файла отражаются в буфере, а сам файл изменяется только
после выдачи команд w или zz. Аналогично, когда Вы вызываете
программу, работающую с экраном через пакет curses,
изменяется
содержимое окна, а сам экран терминала перерисовывается только
при вызове refresh().
В <curses.h> содержится описание принятого
по умолчанию окна stdscr (стандартное окно), размеры
которого совпадают с размерами экрана терминала. В
<curses.h> stdscr имеет
тип WINDOW*,
указатель на структуру языка C, которую пользователь может
представлять себе в виде двумерного массива символов, соответствующего
экрану терминала. Программа всегда отслеживает как
состояние stdscr, так и состояние физического экрана.
refresh(), когда вызывается, сравнивает их и посылает на
терминал последовательность символов, приводящий его экран в
соответствующий содержимому stdscr вид. При этом выбирается один из
многих способов сделать это, с учетом характеристик терминала и
возможного сходства того, что есть на экране и того, что содержится
в окне. Выходной поток оптимизируется таким образом, чтобы он
содержал как можно меньше символов. На рисунке ниже показано, что
происходит при работе программы, выводящей BullsEye в
центре экрана (см. раздел Что такое curses?).
Обратите внимание, что, какой бы мусор ни был на экране, он там и останется,
пока не будет вызвана refresh(). При этом вызове экран очищается
и заполняется текущим содержимым stdscr.
Вместо stdscr Вы можете создавать и использовать другие окна.
Окна полезны для одновременного ведения нескольких образов экрана.
Например, во многих приложениях для ввода и вывода данных
используются два окна: одно для ввода/вывода собственно данных,
а другое - для вывода сообщений об ошибках, чтобы эти сообщения
не портили содержимое основного окна.
Можно разделить экран на большое количество окон, обновляя по
желанию то или иное из них. Если окна перекрываются, на экран
выводится содержимое того окна, которое обновлялось позже. Можно
также создать одно окно внутри другого (первое мы будем
иногда называть подокном). Допустим, разрабатываемое Вами приложение
использует в качестве интерфейса с пользователем экранные
формы, например, для изображения на экране расписки. Тогда
можно использовать меньшие, находящиеся внутри основного, окна
для управления доступом к отдельным полям такой формы.
Некоторые подпрограммы пакета curses
предназначены для работы с
окнами особого типа, которые мы будем называть спецокнами. Спецокно
- это такое окно, размер которого не ограничивается размером
экрана и которое не связано с каким-либо определенным
местом на экране. Их можно применять, если Вам нужны очень
большие окна, или же такие, которые нужно отображать на экран
частями. Спецокна могут, например, понадобиться при работе с
электронными таблицами.
Ниже показаны взаимосвязи между несколькими окнами, подокнами и
спецокнами и экраном терминала.
В разделе Работа с окнами описываются подпрограммы, необходимые
для создания и использования окон. Если Вы хотите сейчас увидеть
программу, работающую с окнами средствами curses, см.
программу window в разделе Примеры программ, работающих с
curses.
curses содержит подпрограммы для записи в
stdscr, похожие на
подпрограммы из stdio(3S) для записи в файл. Они позволяют:
Далее следуют описания и примеры применения этих подпрограмм.
Предостережение
addch( )
2.1. Что нужно программе для работы с curses
2.1.1. Файл <curses.h>
#define refresh() wrefresh(stdscr)
2.1.2. Подпрограммы initscr( ), refresh( ) и endwin( )
#include <curses.h>
main ()
{
initscr (); /* Инициализируем терминал и
переменные и структуры данных
из <curses.h> */
move (LINES/2 - 1, COLS/2 - 4);
addstr ("Bulls");
refresh (); /* Выводим данные на экран
терминала */
addstr ("Eye");
refresh (); /* Выводим еще на экран
терминала */
endwin (); /* Восстанавливаем состояние
терминала */
}
move (LINES/2 - 1, COLS/2 - 4);
addstr ("Bulls");
требует вывести цепочку символов Bulls. Если программа
выполняется на терминале Teletype 5425, эта цепочка будет выведена,
начиная с позиции (11, 36).
2.2. Компиляция программы, которая использует curses
cc файл.c -lcurses -o файл
2.3. Выполнение программы, которая использует curses
TERM=тип_текущего_терминала
export TERM
tput init
2.4. Еще о строках, столбцах и подпрограмме initscr( )
Определив размеры экрана терминала, initscr() присваивает
значения переменным LINES и COLS. Эти значения
берутся из переменных terminfo, называемых lines
и columns. Последние, в свою
очередь, извлекаются из базы данных terminfo,
если не установлены значения переменных окружения $LINES
и $COLUMNS.
2.5. Еще об окнах и подпрограмме refresh( )
2.6. Несложный ввод/вывод
2.6.1. Вывод
| СИНТАКСИС | |
#include <curses.h>
int addch (ch)
chtype ch; | |
| ОПИСАНИЕ | |
| addch() записывает один символ в stdscr.
Этот символ имеет тип chtype, который определяется в <curses.h>. chtype содержит данные и атрибуты (об атрибутах см. ниже в разделе Атрибуты вывода). Работая с переменными этого типа, объявляйте их принадлежащими именно к типу chtype, а не к тому основному типу (скажем, short), через который объявляется chtype в <curses.h>. Это обеспечит совместимость с будущими версиями. addch() производит некоторую перекодировку. Так, она преобразует:
addch() обычно возвращает OK, за исключением случая вывода символа в правом нижнем углу нероллируемого окна, когда возвращается ERR. addch() является макросом. | |
| ПРИМЕР | |
#include <curses.h>
main ()
{
initscr ();
addch ('a');
refresh ();
endwin ();
}
Эта программа выводит следующее:
См. также программу show в разделе Примеры программ, работающих с curses. | |
addstr( )
| СИНТАКСИС | |
#include <curses.h>
int addstr (str)
char *str;
| |
| ОПИСАНИЕ | |
| addstr() выводит цепочку символов в stdscr.
addstr() вызывает addch() для вывода каждого символа. addstr() производит ту же перекодировку, что и addch(). addstr() возвращает OK при успешном завершении и ERR при ошибке. addstr() является макросом. | |
| ПРИМЕР | |
| См. примеры программ во Введении. | |
printw( )
| СИНТАКСИС | |
#include <curses.h>
int printw(fmt [,arg...])
char *fmt; | |
| ОПИСАНИЕ | |
| printw() осуществляет форматированный вывод в stdscr.
Подобно printf(3S), printw() получает формат и переменное количество аргументов. Подобно addstr(), printw() обращается к addch() для вывода каждого символа. printw() возвращает OK при успешном завершении и ERR при ошибке. | |
| ПРИМЕР | |
#include <curses.h>
main ()
{
char *title = "Не указано";
int no = 0;
. . .
initscr ();
. . .
printw ("%s отсутствует на складе.", title);
printw ("Попросите кассира заказать %d для Вас.\n", no);
refresh ();
endwin ();
}
Эта программа выводит следующее:
| |
move( )
| СИНТАКСИС | |
#include <curses.h>
int move (y, x);
int y, x; | |
| ОПИСАНИЕ | |
| move() устанавливает курсор в позицию "строка y,
колонка x" окна stdscr.
Обратите внимание, что первым аргументом move() является координата y, а вторым - x. Координаты левого верхнего угла stdscr равны (0, 0), а правого нижнего - (LINES-1, COLS-1). Подробнее см. в разделе Подпрограммы initscr(), refresh() и endwin(). Перемещение курсора можно производить одновременно с выводом данных, а именно:
move() возвращает OK при нормальном завершении и ERR при ошибке. К ошибке приводит попытка сдвинуть курсор в позицию, не находящуюся между (0, 0) и (LINES-1, COLS-1). move() является макросом. | |
| ПРИМЕР | |
#include <curses.h>
main()
{
initscr ();
addstr ("Курсор должен быть здесь -->");
addstr (" если move () работает.");
printw ("\n\n\nНажмите <CR> для завершения теста.");
move (0, 28);
refresh ();
getch (); /* Вводит <CR>, см. ниже */
endwin ();
}
Эта программа выводит следующее:
После нажатия возврата каретки экран будет выглядеть так:
Другой пример использования move() можно найти в программе scatter в разделе Примеры программ, работающих с curses. | |
clear( ), erase( )
| СИНТАКСИС | |
#include <curses.h>
int clear ( )
int erase ( ) | |
| ОПИСАНИЕ | |
| Обе подпрограммы заполняют все окно stdscr пробелами.
clear() допускает наличие на экране мусора, о котором она не знает; эта подпрограмма вызывает сначала erase(), а затем clearok(), что приводит к полной очистке физического экрана при следующем вызове refresh() для stdscr. Подробнее о clearok() см. curses(3X). initscr() автоматически вызывает clear(). clear() всегда возвращает OK, erase() не возвращает ничего полезного. И clear(), и erase() являются макросами. | |
clrtoeol( ), clrtobot( )
| СИНТАКСИС | |
#include <curses.h>
int clrtoeol ( )
int clrtobot ( ) | |
| ОПИСАНИЕ | |
| clrtoeol() заменяет остаток строки пробелами.
clrtobot() заменяет остаток экрана пробелами. Обе подпрограммы выполняют свои действия с позиции, в которой находится курсор (включительно). Ни одна из подпрограмм не возвращает ничего полезного. | |
| ПРИМЕР | |
Приведем текст программы, использующей clrtobot().
#include <curses.h>
main ()
{
initscr ();
addstr ("Нажмите <CR> для удаления отсюда ");
addstr ("до конца строки и далее.");
addstr ("\nУдалите это тоже.\nИ это.");
move (0, 32);
refresh ();
getch ();
clrtobot ();
refresh ();
endwin ();
}
Эта программа выводит следующее:
Обратите внимание на два вызова refresh() - первый выводит этот текст на экран, второй очищает экран с отмеченного курсором места до конца. После нажатия возврата каретки экран будет выглядеть так:
Примеры использования clrtoeol() см. в программах show и two в разделе Примеры программ, работающих с curses. | |
Подпрограммы curses, предназначенные для чтения с текущего терминала, подобны тем, которые содержатся в stdio(3S) и читают из файла. Они позволяют:
Первичной подпрограммой является getch(), которая обрабатывает и возвращает значение одного введенного символа. Она подобна подпрограмме getchar(3S) из библиотеки языка C, за исключением того, что она может производить некоторые зависящие от системы или терминала действия, которые не выполняет getchar(). Например, getch() можно использовать совместно с подпрограммой keypad() из библиотеки curses. Это позволяет программе распознавать и обрабатывать, как один символ, последовательности, начинающиеся с ESC, которые передаются, например, при нажатии клавиш управления курсором или функциональных клавиш. Дополнительную информацию о keypad() см. в описаниях getch() и keypad() в curses(3X).
Ниже описываются основные подпрограммы для ввода с терминала и даются примеры их использования.
getch( )
| СИНТАКСИС | |
#include <curses.h>
int getch ( ) | |
| ОПИСАНИЕ | |
| getch() читает один символ с текущего терминала.
getch() возвращает значение этого символа или ERR при возникновении ситуации "конец файла", получении сигнала, или при чтении без ожидания, если символ еще не введен. getch() является макросом. См. далее, а также в curses(3X) описания echo(), noecho(), cbreak(), nocbreak(), raw(), noraw(), halfdelay(), nodelay() и keypad(). | |
| ПРИМЕР | |
#include <curses.h>
main ()
{
int ch;
initscr ();
cbreak (); /* Пояснения см. в
разделе "Опции ввода" */
addstr ("Введите любой символ: ");
refresh ();
ch=getch ();
printw ("\n\n\nВы ввели '%c'.\n", ch);
refresh ();
endwin ();
}
Посмотрим, что выводит эта программа. Первый refresh() выводит цепочку символов, указанную в addstr(), из stdscr на экран терминала:
Пусть на клавиатуре нажали w. getch() принимает символ и его значение присваивается ch. Наконец, второй раз вызывается refresh() и экран становится таким:
Другой пример использования getch() см. в программе show в разделе Примеры программ, работающих с curses. | |
getstr( )
| СИНТАКСИС | |
#include <curses.h>
int getstr (str)
char *str; | |
| ОПИСАНИЕ | |
| getstr() читает символы и сохраняет их в буфере до тех
пор, пока не будет нажат возврат каретки, перевод строки или клавиша ввода.
getstr() не проверяет буфер на переполнение. Прочитанные символы пересылаются в цепочку str. getstr() является макросом и вызывает getch() для чтения каждого символа. getstr() возвращает ERR только тогда, когда getch() возвращает ERR. В остальных случаях возвращается OK. См. далее, а также в curses(3X) описания echo(), noecho(), cbreak(), nocbreak(), raw(), noraw(), halfdelay(), nodelay() и keypad(). | |
| ПРИМЕР | |
#include <curses.h>
main ()
{
char str [256];
initscr ();
cbreak (); /* Пояснения см. в
разделе "Опции ввода" */
addstr ("Введите строку символов,");
addstr (" оканчивающуюся <CR>:\n\n");
refresh ();
getstr (str);
printw ("\n\n\nВы ввели \n'%s'\n", str);
refresh ();
endwin ();
}
Допустим, Вы ввели строку "Мне нравится изучать систему UNIX". После нажатия возврата каретки экран будет выглядеть так:
| |
scanw( )
| СИНТАКСИС | |
#include <curses.h>
int scanw (fmt [,arg...])
char *fmt; | |
| ОПИСАНИЕ | |
| scanw() вызывает getstr() и сканирует введенную строку.
Подобно scanf(3S), scanw() использует формат для преобразования введенной строки и присваивает значения переменному количеству аргументов. scanw() возвращает те же значения, что и scanf(). Дополнительную информацию см. в описании scanf(3S). | |
| ПРИМЕР | |
include <curses.h>
main ()
{
char string [100];
float number;
initscr ();
cbreak (); /* Пояснения см.
в разделе "Опции ввода" */
echo ();
addstr ("Введите число и текст,");
addstr (" разделенные запятой:");
refresh ();
scanw ("%f,%s", &number, string);
clear ();
printw ("Вы ввели текст \"%s\" и число %f.",
string, number);
refresh ();
endwin ();
}
Обратите внимание на два вызова refresh(). После первого вызова на экране появляется строка, переданная addstr(), после второго - строка, которую возвращает scanw(). Кроме того, обратите внимание на вызов clear(). Допустим, Вы ввели строку 2,twin. После выполнения программы экран терминала будет выглядеть так:
| |
Рассказывая об addch(), мы упомянули, что эта подпрограмма выводит в stdscr один знак типа chtype. chtype состоит из двух частей: информации о самом символе и информации о наборе атрибутов, связанных с этим символом. Эти атрибуты позволяют отображать символ с повышенной яркостью, подчеркнутым, инвертированным и т.д.
С stdscr всегда связан набор атрибутов, которые автоматически присваиваются каждому выводимому символу. Вы можете изменить текущие значения атрибутов, используя attrset() или другие подпрограммы пакета curses, которые описаны ниже. Приведем здесь список атрибутов и их описания:
Эти атрибуты можно передавать в качестве аргумента подпрограмме attrset() или ей подобным. Им можно передавать комбинации атрибутов, объединенные операцией дизъюнкции (|).
Примечание
Рассмотрим использование одного из этих атрибутов. Следующий фрагмент программы обеспечивает отображение слова с повышенной яркостью:
. . .
printw ("Яркое ");
attrset (A_BOLD);
printw ("слово");
attrset (0);
printw (" бросается в глаза.\n");
. . .
refresh ();
Атрибуты можно включать по одному, как в примере: attrset (A_BOLD), или в комбинации. Например, чтобы вывести яркий мерцающий текст, Вы можете использовать attrset (A_BOLD | A_BLINK). Те или иные атрибуты включаются и выключаются подпрограммами attron() и attroff() без какого-либо влияния на остальные атрибуты отображения. attrset (0) отключает все атрибуты.
Заметьте, что в набор атрибутов входит A_STANDOUT, который можно применять для привлечения внимания пользователя. Для физической реализации этого атрибута используется наиболее визуально выразительный способ отображения, возможный на данном терминале. Обычно это повышенная яркость или инверсия. Если нужно просто выделить часть текста, все равно, подсветкой, инверсией или как-либо еще, лучше использовать A_STANDOUT. Для его включения и выключения удобны функции standout() и standend() соответственно. Фактически, standend() отключает все атрибуты. Кроме перечисленных атрибутов, имеется еще две битовые маски, а именно A_CHARTEXT и A_ATTRIBUTES. Их можно использовать для извлечения только символа или только атрибутов из значения, возвращаемого входящей в curses функцией inch(), путем их конъюнкции (операция & языка C) с этим значением. См. описание inch() в curses(3X).
Приведем описание attrset() и других подпрограмм curses, которые используются для управления атрибутами вывода.
attron( ), attroff( ), attrset( )
| СИНТАКСИС | |
#include <curses.h>
int attron (attrs)
chtype attrs;
int attrset (attrs)
chtype attrs;
int attroff (attrs)
chtype attrs; | |
| ОПИСАНИЕ | |
| attron() включает запрошенные атрибуты attrs, сохраняя
те, которые уже включены. attrs принадлежит к типу
chtype, определяемому во включаемом файле <curses.h>.
attrset() включает запрошенные атрибуты attrs вместо тех, которые включены в момент обращения к ней. attroff() выключает запрошенные атрибуты attrs, если они включены. Атрибуты могут объединятся при помощи побитной операции ИЛИ (|). Все подпрограммы возвращают OK. | |
| ПРИМЕР | |
| См. программу highlight в разделе Примеры программ, работающих с curses. | |
standout( ), standend( )
| СИНТАКСИС | |
#include <curses.h>
int standout ( )
int standend ( ) | |
| ОПИСАНИЕ | |
| standout() включает атрибут A_STANDOUT и эквивалентен
вызову attron (A_STANDOUT).
standend() выключает все атрибуты и эквивалентен вызову attrset (0). Обе подпрограммы всегда возвращают OK. | |
| ПРИМЕР | |
| См. программу highlight в разделе Примеры программ, работающих с curses. | |
Иногда бывает нужно привлечь внимание пользователя. Для этого в пакет curses включены две подпрограммы, которые могут заставить терминал звенеть, а его экран - вспыхивать.
flash() заставляет экран терминала вспыхнуть, если это возможно, если же нет - включает звуковой сигнал. Вспышка является альтернативой звуковому сигналу и особенно полезна, когда звук мешает кому-либо, сидящему неподалеку от терминала. Подпрограмма beep() вызывается, когда нужно подать звуковой сигнал (если это почему-либо невозможно на данном терминале, beep() пытается произвести вспышку).
beep( ), flash( )
| СИНТАКСИС | |
#include <curses.h>
int flash ( )
int beep ( ) | |
| ОПИСАНИЕ | |
| flash() пытается заставить вспыхнуть экран терминала.
Если это невозможно, flash() пытается включить на
терминале звуковой сигнал.
beep() пытается включить на терминале звуковой сигнал. Если это невозможно, beep() пытается заставить вспыхнуть экран терминала. Ни одна из подпрограмм не возвращает какого-либо осмысленного значения. | |
Система UNIX производит множество действий с символами, вводимыми пользователем. Среди прочего, система выполняет следующее:
Curses полностью берет на себя управление экраном терминала, поэтому его подпрограммы отключают эхо, производимое системой UNIX, и делают его самостоятельно. Временами бывает необходимо программно отключать стандартную для системы UNIX обработку символов. Для этого предназначены некоторые подпрограммы curses, например, noecho() и cbreak(). Используя такие подпрограммы, можно управлять интерпретацией вводимых символов. В приведенной ниже таблице перечислены основные подпрограммы, предназначенные для управления режимом ввода.
Если программа использует curses и вводит с терминала, она должна установить некоторые опции ввода. Это связано с тем, что при старте программы терминал может оказаться в любом из режимов cbreak(), raw(), nocbreak(), или noraw(). Как показано в таблице, при запуске программы гарантируется только наличие режима echo().
Как правило, в интерактивной терминальной программе используются комбинация режимов noecho() и cbreak(). Пусть, например, нужно отображать вводимые символы не там, где находится курсор, а в нижней строке экрана. Для этого предназначена подпрограмма noecho(). Однако, хотя noecho() и подавляет отображение вводимых символов, символы забоя и уничтожения обрабатываются обычным образом. Для отключения этого режима используется подпрограмма cbreak().
| Опции ввода | Символы | Интерпретируются | Не интерпретируются |
| Нормальное состояние "вне curses" | прерывание, выход, сброс бита четности, <CR> в <NL>, забой, уничтожение, конец файла | |
| Нормальное состояние "старт curses-программы" | эхо (заменяет эхо системы UNIX) | все остальное не определено |
| cbreak () и echo () | прерывание, выход, сброс бита четности эхо | забой, уничтожение, конец файла |
| cbreak () и noecho () | прерывание, выход, сброс бита четности | забой, уничтожение, конец файла, эхо |
| nocbreak () и noecho () | разрыв, выход, сброс бита четности, забой, уничтожение, конец файла | эхо |
| nocbreak () и echo () | См. предостережение ниже | |
| nl () | <CR> в <NL> | |
| nonl () | <CR> в <NL> | |
| raw () [вместо cbreak ()] | разрыв, выход, сброс бита четности | |
Предостережение
Помимо подпрограмм, перечисленных в таблице, для управления вводом используются следующие подпрограммы curses: noraw(), halfdelay(), nodelay(). Они обсуждаются в curses(3X).
Далее подробнее описываются подпрограммы noecho(), cbreak() и связанные с ними echo() и nocbreak().
echo( ), noecho( )
| СИНТАКСИС | |
#include <curses.h>
int echo ( )
int noecho ( ) | |
| ОПИСАНИЕ | |
| echo() устанавливает режим "эхо" - отображение символов
на экране по мере их ввода. При старте программы этот
режим установлен.
noecho() отключает режим "эхо". Ни та, ни другая подпрограмма не возвращают полезных значений. curses-программы могут работать неправильно, если эхо установлено одновременно с nocbreak(). См. таблицу выше и последующее предостережение. После отключения эха вводимые символы можно отображать посредством addch(). | |
| ПРИМЕР | |
| См. программы editor и show в разделе Примеры программ, работающих с curses. | |
cbreak( ), nocbreak( )
| СИНТАКСИС | |
#include <curses.h>
int cbreak ( )
int nocbreak ( ) | |
| ОПИСАНИЕ | |
| cbreak() включает режим "прерывание при вводе каждого
символа". Программа получает каждый символ сразу после
его ввода, но символы забоя, уничтожения и конца файла
не обрабатываются.
nocbreak() возвращает к обычному режиму "построчный ввод". Обычно этот режим установлен при запуске прог- раммы. Ни одна из подпрограмм не возвращает полезных значений. curses-программы могут работать неправильно, если cbreak() включается и отключается в пределах одной программы, либо если используется комбинация nocbreak() и echo(). См. таблицу выше и последующее предостережение. | |
| ПРИМЕР | |
| См. программы editor и show в разделе Примеры программ, работающих с curses. | |
Ранее, в разделе Еще об окнах и подпрограмме refresh(),
объяснялось, что такое окна и спецокна и для чего они могут Вам
понадобиться. В этом разделе описываются подпрограммы
curses,
предназначенные для создания окон и спецокон и управления ими.
Для ввода и вывода данных в окна и спецокна используются
подпрограммы, похожие на те, которые работают с stdscr.
Единственная разница состоит в том, что необходимо указать окно, к
которому относится операция. Как правило, имена этих подпрограмм
получаются путем добавления буквы w в начало названия соответствующей
подпрограммы для stdscr, а также имени окна в качестве
первого параметра. Например, если нужно вывести символ c
в окно mywin, addch ('c') превращается
в waddch (mywin,'c').
Далее приводится список работающих с окнами подпрограмм,
соответствующих тем, которые были описаны в разделе Несложный
ввод/вывод.
Как видно из описаний, эти подпрограммы отличаются от тех, которые
работают с stdscr, только своими именами и добавлением
аргумента win. Заметьте, что у подпрограмм, чьи имена
начинаются на mvw, аргумент win
предшествует координатам y, x, хотя,
судя по их именам, следовало бы ожидать обратного. См. в
curses(3X) дополнительные данные об
этих подпрограммах, вариантах подпрограмм
getch(), getstr() и другую информацию,
касающуюся работы с окнами.
Все подпрограммы с буквой w в имени могут использоваться и со
спецокнами, за исключением wrefresh() и
wnoutrefresh() (см. ниже). Вместо
них со спецокнами нужно использовать соответственно
prefresh() и pnoutrefresh().
Как было сказано ранее, подпрограмма refresh() пересылает
данные с stdscr на экран терминала. refresh() является макросом,
который расширяется в wrefresh (stdscr), о чем также
упоминалось в разделах Что нужно программе
для работы с curses и Еще
об окнах и подпрограмме refresh().
Подпрограмма wrefresh() предназначена для пересылки данных из
окна (будь то stdscr или созданное пользователем) на экран
терминала; она вызывает подпрограммы
wnoutrefresh() и doupdate().
Аналогичным образом, prefresh() пересылает данные из спецокна
на экран, обращаясь к pnoutrefresh() и doupdate().
Пользуясь wnoutrefresh() или
pnoutrefresh() (здесь мы для простоты
рассмотрим только первую из них) и
doupdate(), Вы можете
обновлять экран с большей эффективностью, чем обращаясь к
wrefresh(). wrefresh() сначала вызывает
wnoutrefresh(), которая
копирует указанное окно в структуру данных, называемую виртуальным
экраном. Виртуальный экран содержит то, что программа
собирается вывести на терминал. Вызвав
wnoutrefresh(),
wrefresh() затем обращается к
doupdate(), которая сравнивает
виртуальный экран с физическим и производит обновление последнего.
Если Вы хотите отобразить содержимое сразу нескольких
окон, вызовы wrefresh() приведут к нескольким обращениям к
wnoutrefresh() и doupdate(),
то есть к нескольким актам вывода
данных на экран. Однако, вызвав wnoutrefresh()
для каждого окна, а затем один раз doupdate(),
можно уменьшить общее количество передаваемых символов и необходимого
для передачи времени процессора. Нижеследующая программа использует
doupdate()
лишь однажды.
объявляют два окна, которые называются w1 и w2,
передавая
некоторые описания подпрограмме newwin(), которая подробнее описана
ниже.
Ниже показано действие wnoutrefresh() и
doupdate() на эти два
окна и на виртуальный и физический экраны.
newwin( )
Аргументы nlines и ncols задают размер нового окна.
Аргументы begin_y и begin_x задают координаты точки на
экране [относительно (0, 0)], на которую отображается
левый верхний угол окна. subwin( )
2.8.1. Ввод/вывод
waddch (win, ch)
mvwaddch (win, y, x, ch)
waddstr (win, str)
mvwaddstr (win, y, x, str)
wprintw (win, fmt[,arg...])
mvwprintw (win, y, x, fmt[,arg...])
wmove (win, y, x)
wclear (win)
werase (win)
wclrtoeol (win)
wclrtobot (win)
wrefresh (win)
2.8.2. Подпрограммы wnoutrefresh( ) и doupdate( )
#include <curses.h>
main ()
{
WINDOW *w1, *w2;
initscr ();
w1 = newwin (2, 6, 0, 3);
w2 = newwin (1, 4, 5, 4);
waddstr (w1, "Bulls");
wnoutrefresh (w1);
waddstr (w2, "Eye");
wnoutrefresh (w2);
doupdate ();
endwin ();
}
В начале этой программы объявляются новые окна. Операторы
w1 = newwin (2, 6, 0, 3);
w2 = newwin (1, 4, 5, 4);

2.8.3. Новые окна
Далее следуют описания подпрограмм newwin() и subwin(), которые
применяются для создания новых окон. В curses(3X) описаны подп-
рограммы newpad() и subpad()
для создания новых спецокон.
СИНТАКСИС
#include <curses.h>
WINDOW *newwin (nlines, ncols, begin_y, begin_x)
int nlines, ncols, begin_y, begin_x;
ОПИСАНИЕ
newwin() возвращает указатель на новое
окно с новой областью данных.
ПРИМЕР
См. пример программы, работающей с двумя окнами и рисунок выше. См. также
программу window в разделе Примеры
программ, работающих с curses.
| СИНТАКСИС | |
#include <curses.h>
WINDOW *subwin (orig, nlines, ncols, begin_y, begin_x)
WINDOW *orig;
int nlines, ncols, begin_y, begin_x; | |
| ОПИСАНИЕ | |
| subwin() возвращает указатель на новое окно, которое
является частью ранее определенного окна, orig.
Аргументы nlines и ncols задают размер нового окна. Аргументы begin_y и begin_x задают координаты левого верхнего угла окна на экране терминала. Как подокна, так и сами окна могут перекрываться. Предостережение | |
| ПРИМЕР | |
#include <curses.h>
main()
{
WINDOW *sub;
initscr ();
box (stdscr, 'w', 'w'); /* О box() см. curses(3X) */
mvaddstr (stdscr, 7, 10, "------- это 10,10");
mvaddch (stdscr, 8, 10, '');
mvaddch (stdscr, 9, 10, 'v');
sub = subwin (stdscr, 10, 20, 10, 10);
box (sub, 's', 's');
wnoutrefresh (stdscr);
wrefresh (sub);
endwin ();
}
Эта программа заполняет границу stdscr (то есть края экрана терминала) символами w, а границу подокна sub - символами s. Другой пример см. в программе window раздела Примеры программ, работающих с curses. | |
Умея пользоваться основными подпрограммами curses для ввода/вывода на экран и управления окнами, можно создавать терминальные программы, удовлетворяющие потребности большинства пользователей. Вместе с тем, в curses имеются подпрограммы, которые позволяют делать больше, чем просто вводить и выводить символы и работать с окнами. На следующих нескольких страницах кратко описываются некоторые из этих подпрограмм, которые помогут Вам выводить простые графические изображения, использовать программируемые метки терминала и обращаться из одной программы к нескольким терминалам.
Прежде, чем использовать эти возможности, следует освоить подпрограммы ввода/вывода и управления окнами, которые были рассмотрены выше в этой главе, а также в руководстве curses(3X).
Предостережение
Многие терминалы поддерживают альтернативную кодировку для простых графических изображений (графические символы, или глифы). Этим набором символов можно пользоваться и в программах, работающих с curses. В curses используются те же названия глифов, что и в графическом наборе символов VT100.
Для работы с альтернативной кодировкой в curses-программе, необходимо передать подпрограмме waddch() (или подобной) последовательность символов, чьи имена начинаются с ACS_. Например, ACS_ULCORNER - это переменная для символа, изображающего левый верхний угол. Если терминал поддерживает этот символ, то в ACS_ULCORNER будет результат операции ИЛИ (|) соответствующего значения и битной маски A_ALTCHARSET. Если такого графического символа нет, используется символ из стандартного набора ASCII, аппроксимирующий требуемое изображение. Например, для аппроксимации ACS_HLINE, горизонтальной черты, используется - (знак минус). Если близкая аппроксимация невозможна, используется +, знак плюс. Все стандартные имена ACS_ и аппроксимирующие их символы перечислены в curses(3X).
Мы приведем часть текста программы, которая использует графические символы. В примере вызывается подпрограмма box(), входящая в пакет curses, для того, чтобы окружить меню на экране рамкой. По умолчанию box() использует графические символы, но по выбору пользователя может рисовать знаками и - [см. curses(3X)]. Если меню, изображенное в рамке, имеет продолжение вверх или вниз за пределы рамки, то для указания этого выводятся стрелки соответственно вверх или вниз (ACS_UARROW и ACS_DARROW).
box (menuwin, ACS_VLINE, ACS_HLINE);
...
/* Вывод стрелок вверх/вниз */
wmove (menuwin, maxy, maxx - 5);
/* вывод стрелки вверх или горизонтальной черты */
if (moreabove)
waddch(menuwin, ASC_UARROW);
else
waddch (menuwin, ACS_HLINE);
/* вывод стрелки вниз или горизонтальной черты */
if (morebelow)
waddch (menuwin, ASC_DARROW);
else
waddch (menuwin, ACS_HLINE);
Приведем еще один пример. Поскольку символ для стрелки вниз (например, строчная v) не очень выделяется на экране, если на нем много строчных букв, этот символ можно заменить на прописную V.
if ( ! (ACS_DARROW & A_ALTCHARSET))
ACS_DARROW = 'V';
Более подробную информацию см. в Справочнике программиста,
curses(3X).
Большинство терминалов поддерживает программируемые метки в
нижней части своего экрана. На клавиатуре этим меткам обычно
соответствует функциональные клавиши. Меток обычно восемь, каждая
длиной в восемь знаков и высотой в одну-две строки.
Библиотека curses содержит подпрограммы, поддерживающие
единую модель из восьми программируемых меток. Если терминал их не
имеет, нижняя строка его экрана превращается в область программируемых
меток. Для использования в curses-программах таких
меток, нет необходимости иметь на клавиатуре соответствующие им
функциональные клавиши.
Далее кратко описываются большинство подпрограмм
curses, применяющихся при работе
с программируемыми метками: slk_init(),
slk_set(), slk_refresh(),
slk_noutrefresh(), slk_clear() и
slk_restore().
Если Вы пользуетесь программируемыми метками в
curses-программе,
Вам необходимо перед initscr() вызвать подпрограмму
slk_init().
При этом устанавливается внутренний флаг, указывающий
initscr(), что программируемые метки используются. Если
initscr() обнаружит, что программируемые метки отсутствуют на
терминале, либо их меньше восьми, либо их длина менее восьми
символов, она удаляет нижнюю строку stdscr, чтобы использовать
ее для размещения программируемых меток. При этом размер stdscr
и значение переменной LINES уменьшается на единицу. Разумно
написанная программа, использующая переменные LINES
и COLS, будет
выполняться правильно, как если бы этой строки вообще не было
бы на экране.
slk_init() имеет один аргумент, определяющий способ размещения
меток на экране в случае использования для этого строки из
stdscr. Выбор возможен между размещением группами 3-2-3, как
это принято на терминалах AT&T, либо 4-4, как на терминалах
Хьюлетт-Паккард. Подпрограммы curses
определяют положение и
размер меток в соответствии с указанным способом, причем максимально
возможная длина метки - восемь символов.
Подпрограмма slk_set() имеет три аргумента: номер метки (1-8),
текст, помещаемый в метку (не более восьми символов), выравнивание
этого текста в поле метки (0 - выравнивание влево, 1 -
центрирование, 2 - выравнивание вправо).
Подпрограмма slk_noutrefresh() подобна
wnoutrefresh() тем, что
она обновляет содержимое внутреннего образа экрана, но не выводит
данные на реальный экран. Поскольку после ее вызова обычно
вызывают wrefresh(), именно
slk_noutrefresh(), как правило, используется
для вывода меток на экран терминала.
Подобно тому, как wrefresh() эквивалентна последовательным
вызовам wnoutrefresh() и doupdate(),
подпрограмма slk_refresh()
эквивалентна последовательным вызовам
slk_noutrefresh() и
doupdate().
Чтобы программируемые метки не мешали работе в среде shell, перед
обращением к endwin() можно вызвать
slk_clear(), которая
удаляет программируемые метки с экрана и вызывает
doupdate().
Программируемые метки можно восстановить на экране функцией
slk_restore(). Подробнее о подпрограммах для работы
с программируемыми метками см. curses(3X).
Curses-программа может выводить данные
сразу на несколько терминалов. Это может оказаться полезным при
разработке программ,
которые представляют собой один процесс и обращаются к одной
базе данных, например, игр для нескольких участников.
Писать программы, работающие с несколькими терминалами, - дело
нелегкое, и подпрограммы curses не решают
всех возникающих при
этом проблем. Например, сами программы, а не подпрограммы
библиотеки, должны определять имена файлов для терминалов и типы
этих терминалов. Стандартный способ с использованием переменной
окружения $TERM не срабатывает, поскольку каждый процесс может
знать только о своем собственном окружении.
Другая проблема возникает, когда несколько программ пытаются
читать данные с одного и того же терминала. Следует избегать
ситуации, когда программы перехватывают данные друг у друга. В
то же время, программа, которая пытается занять дополнительный
терминал, не должна просто прерывать программу, которая уже
работает на нем. (Обычно это также неприемлемо из соображений
безопасности, но бывают случаи, когда это может оказаться
полезным, например, если терминал не используется, либо для
разработки программ связи между терминалами). Типичным решением
проблемы является запуск каждым пользователем программы,
уведомляющей главную программу о желании с ней работать и передающей
главной программе идентификатор процесса уведомляющей программы,
имя линии и тип используемого терминала. Затем уведомляющая
программа переходит в неактивное состояние до окончания
работы главной. Перед своим завершением, главная программа активизирует
все уведомляющие программы, после чего все они завершаются.
Концепция работы curses со многими терминалами
заключается в
поддержании текущего терминала. Все обращения к подпрограммам
относятся к этому текущему терминалу. Главная программа должна
описать каждый терминал и сохранить ссылку на него в своих
переменных. Когда программе нужно работать с некоторым терминалом,
ей следует установить его в качестве текущего и вызывать
обычные подпрограммы curses.
Ссылки на терминал в curses-программе
имеют тип *SCREEN. Новый
терминал инициализируется путем обращения к newterm (type,
outfd, infd). newterm возвращает указатель на новый терминал,
type - это цепочка символов, содержащая тип используемого
терминала. outfd является указателем на файл
[*FILE, stdio(3S)],
который используется для вывода на терминал, а infd указывает
на файл для ввода с терминала. Вызов newterm() заменяет обычное
обращение к initscr(), которое расширяется в newterm (getenv
("TERM"), stdout, stdin).
Для изменения текущего терминала необходимо вызвать set_term (sp),
где sp указывает на терминал, который должен стать текущим.
set_term() возвращает указатель на терминал, который был
текущим на момент ее вызова.
Важно понять, что каждый терминал будет иметь свои собственные
режимы работы и окна. Каждый терминал должен быть проинициализирован
соответствующим вызовом newterm(). Для каждого терминала
отдельно должны быть установлены режимы работы, например,
cbreak() или noecho(). Равным образом для каждого
терминала отдельно должны вызываться endwin() и
refresh(). Ниже изображен
типичный сценарий рассылки сообщения на несколько терминалов.
Более подробный пример см. в программе two раздела Примеры
программ, работающих с curses.
Иногда могут понадобиться подпрограммы более низкого уровня,
чем те, которые предлагает пакет curses.
Такие подпрограммы содержатся в пакете terminfo.
Они не работают непосредственно с
экраном терминала, а дают пользователю возможность узнать значения
характеристик терминала и последовательности символов,
которые терминалом управляют.
Подпрограммы terminfo полезно использовать
в трех случаях. Вопервых, если Вам нужны только некоторые возможности
терминала,
например, выделение текста на экране. Во-вторых, если нужно
написать фильтр. Типичный фильтр только преобразует входной
поток, без очистки экрана или перемещения курсора. Если вид
преобразования зависит от терминала, и экран не должен очищаться,
то стоит воспользоваться подпрограммами terminfo.
В-третьих,
если Вы пишете специальную программу для посылки специальной
строки на терминал, например, для программирования функциональной
клавиатуры, установки позиций табуляции, передачи данных на
принтер, или для работы со строкой состояния. За исключением
этих трех случаев, Вам лучше не пользоваться подпрограммами
terminfo: curses
содержит подпрограммы более высокого уровня,
использование которых повысит степень переносимости Ваших
программ на другие системы UNIX и другие терминалы.
Примечание
Как правило, программа, работающая с terminfo,
включает файлы и
подпрограммы, которые перечислены ниже:
Файлы <curses.h> и <term.h>
нужны, поскольку они содержат определения текстовых объектов,
чисел и флагов, которые используются подпрограммами
terminfo. setupterm()
занимается инициализацией. Передача ей значений
(char*) 0, 1 и (int*) 0 обеспечивает
установку разумных режимов. Если setupterm() не
может распознать тип используемого терминала, она выводит сообщение об
ошибке и завершается. reset_shell_mode()
делает примерно то же, что и endwin(),
и должна вызываться перед завершением terminfo-программы.
При вызове setupterm() определяются значения глобальных
переменных, например clear_screen. Их значения могут
быть выведены
на экран входящими в terminfo подпрограммами
putp() или
tputs(), что обеспечивает пользователю дополнительные
возможности по контролю терминала. Такую строку не следует выводить
подпрограммой printf(3S) из библиотеки языка C, поскольку в ней
содержится информация об использовании символов-заполнителей.
Программа, пытающаяся вывести ее таким образом, может завершиться
аварийно, если терминал требует использования заполнителей,
или если он использует протокол xon/xoff.
На уровне terminfo подпрограммы более
высокого уровня, например, addch() и
getch(), недоступны. Вам придется самостоятельно
решать проблему вывода на экран. Список характеристик и их описаний
см. в terminfo(4), список подпрограмм
terminfo см. в
curses(3X).
Общий формат командной строки для компиляции, как и особенности
запуска программ, использующих terminfo, те же,
что и для любой
другой curses-программы. Подробности см. в
разделах Компиляция
программы, которая использует curses и
Выполнение программы,
которая использует curses.
Познакомимся поближе с подпрограммами terminfo
на примере использования функции tputs (cap, affcnt, outc)
в этой программе.
tputs() добавляет символы-заполнители. Некоторые терминалы
имеют возможность задерживать вывод. Их описания в базе данных
terminfo, быть может, содержат цепочки, подобные
$<20>, что означает задержку на 20 миллисекунд (см.
ниже раздел Указание характеристик терминала). tputs генерирует
достаточное для задержки на это время количество символов-заполнителей.
tputs() имеет три параметра. Первый является цепочкой символов,
определяющей характеристику (атрибут вывода), которую необходимо реализовать. Второй - количество затрагиваемых этим строк.
(Некоторые запросы требуют добавления символов-заполнителей в
количестве, зависящем от этого параметра. Например, запрос на
вставку строки, insert_line, может привести к копированию всех
строк ниже текущей, для чего нужно время, пропорциональное количеству
копируемых строк. Если ни одна строка не затрагивается, в качестве
affcnt используется 1. Единица вместо нуля берется
для надежности, так как affcnt умножается на некоторый
интервал времени, а умножение чего-либо на 0 дает 0). Третий
параметр - это подпрограмма, вызываемая для вывода каждого символа.
Для понимания желательности использования подпрограмм уровня
curses вместо подпрограмм уровня
terminfo (там, где это возможно), полезно
обратить внимание на проверку значения underline_char
в примере. Некоторые терминалы имеют управляющий символ,
указывающий начало подчеркивания, и еще один символ, указывающий
конец подчеркивания. Другим необходимо указание кода
подчеркивания при выводе каждого символа. Программа termhl
хранит значение этого режима, и, если необходимо, выводит
underline_char для подчеркивания очередного символа.
Из-за наличия такого рода мелких деталей, с которыми программы уровня
terminfo
должны разбираться самостоятельно, и предпочтительнее работать
на уровне curses.
Программа termhl была написана для иллюстрации применения
подпрограмм terminfo, поэтому она получилась сложнее,
чем могла бы
быть. Вместо непосредственного вывода enter_bold_mode,
enter_underline_mode и
exit_attribute_mode можно было бы использовать подпрограмму
vidattr [см. curses(3X)]. Фактически, в
последнем случае программа была бы более надежна, поскольку
существует несколько способов изменения атрибутов вывода.
База данных terminfo содержит описания многих
терминалов, с которыми могут работать как подпрограммы
curses, так и некоторые
средства системы UNIX, например vi(1). Каждое описание
терминала представляет собой скомпилированный файл, содержащий имена,
под которыми этот терминал известен, и группу разделенных запятыми полей,
описывающих возможные действия и характеристики
терминала. В этом разделе описываются база данных
terminfo,
средства для работы с ней и ее связь с библиотекой curses.
База данных terminfo содержит описания многих наиболее часто
применяющихся терминалов. Может, однако, оказаться, что Вы пожелаете
написать curses-программу, предназначенную для
выполнения на терминале, который еще не описан. В этом случае Вам
придется создать его описание.
В общем случае для генерации описания терминала необходимо:
Иногда генерировать и тестировать описание терминала легче по
частям. Такие последовательные тесты помогут выявить Ваши слабые
стороны в работе по описанию терминалов. Кроме того, можно
облегчить генерацию, корректируя уже существующее описание похожего
терминала (не следует забывать девиз системы UNIX: опираться на работу других).
Далее мы опишем каждый шаг построения описания некоторого
условного терминала myterm.
Название терминала - это информация, с которой начинается его
описание в terminfo. В действительности, название
может включать несколько имен, разделенных вертикальной чертой
(|). Первое имя должно представлять собой наиболее
часто используемое
сокращение. Последним должно указываться имя, полностью
идентифицирующее терминал. Обычно, это название, которым пользуется
фирма-производитель. Все имена между первым и последним должны
быть известными синонимами имени терминала. Все имена, кроме
последнего, записываются строчными буквами и не должны содержать
пробелов. Естественно, последнее имя как можно более точно
воспроизводит название фирмы-производителя.
Приведем название из описания терминала AT&T Teletype 5420:
Обратите внимание, что в начале идет наиболее часто используемое
сокращение, а в конце - официальное название терминала.
Заметьте также, что название оканчивается запятой.
Приведем название для нашего условного терминала myterm:
Имена терминалов должны удовлетворять обычным соглашениям об
именах. Эти соглашения касаются, в частности, начального имени,
например, 5425 или myterm. Это имя не должно содержать странных
символов (например, минусов), которые могут не быть распознаны
как часть синонима имени терминала. Возможные режимы оборудования
и предпочтения пользователя указываются путем добавления
имени и "индикатора режима" в конце имени. Например, для нашего
фиктивного терминала режим с большим числом символов в строке
(что обозначается через -w) будет записан в виде myterm-w.
Другие индикаторы подробно обсуждаются в term(5).
После создания цепочки имен, для правильного описания нового
терминала следует выяснить значения его характеристик. Для этого
Вам надлежит сделать следующее:
После того, как Вы уяснили характеристики терминала, их необходимо
указать в его описании. Описание имеет вид последовательности
разделенных запятыми полей, каждое из которых содержит
принятое в terminfo сокращение названия
характеристики и, в некоторых случаях, ее значение для данного терминала.
Например,
для указания способности терминала подавать звуковой сигнал
используется сокращение bel. На большинстве терминалов
инструкцией, передаваемой для подачи звукового сигнала, является CTRL+G.
Таким образом, характеристика возможности подачи звукового
сигнала изображается в описании терминала в виде bel=^G,.
Описание характеристики может занимать несколько строк. В отличие
от первой строки, строки продолжения должны начинаться с
символа табуляции или пробела. В описание можно включать комментарии,
которые выделяются символом # в начале строки.
Полный список характеристик, которые можно указывать в описании
терминала см. в terminfo(4). В этом списке
приводятся название
характеристики, сокращенное название, которое используется в
базе данных, двухбуквенный код, соответствующий этой характеристике
в устаревшей базе данных termcap, а также краткое описание
характеристики. Сокращение, которое необходимо указать в
описании терминала см. в колонке "Сокращение".
Примечание
Значение характеристики может задаваться клавишей (например,
CTRL+G), числом, или цепочкой символов, определяющей
последовательность операций, которые нужно выполнить, чтобы добиться
необходимого эффекта. Для указания типа значения после названия
характеристики в описании терминала могут использоваться
некоторые специальные символы, а именно:
Иногда бывает необходимо отключить некоторую характеристику в
описании терминала. Это можно сделать, поместив точку (.) перед
сокращенным названием характеристики, тогда она воспринимается
как комментарий. Например, чтобы закомментировать характеристику
звукового сигнала, необходимо записать ее так:
4.1.3.1. Основные характеристики
Следующие характеристики являются общими для большинства терминалов:
звуковой сигнал, колонки и строки на экране, возможность
надпечатывания символов. Пусть наш гипотетический терминал имеет
эти и некоторые другие перечисленные ниже возможности. Заметьте,
что в скобках после каждой характеристики следует ее
сокращение для terminfo:
Объединив последовательность имен (см. раздел Название терминала)
и описание упомянутых характеристик, мы получим следующее
описание для базы данных terminfo:
4.1.3.2. Характеристики экрана
Эти характеристики управляют содержимым экрана. Пусть терминал
myterm имеет перечисленные ниже характеристики. Опять-таки, в
скобках после описания характеристики дается ее сокращение.
Описание терминала myterm, включающее эти характеристики, будет
выглядеть так:
4.1.3.3. Характеристики клавиатуры
Эти характеристики представляют собой последовательности симво-
лов, генерируемые при нажатии клавиш на клавиатуре терминала.
Большинство терминалов имеет ряд специальных клавиш, по меньшей
мере, стрелки и клавиши забоя. Пусть наш гипотетический терми-
нал имеет несколько таких клавиш, которые генерируют следующие
последовательности:
Добавим эту информацию к нашему описанию:
4.1.3.4. Параметризованные цепочки
Характеристики, значения которых задаются параметризованными
цепочками, могут иметь параметры. Например, таковы характеристики,
описывающие позиционирование курсора на экране, или включение
комбинации режимов отображения. Для позиционирования курсора
используется характеристика cup, при этом передаются два
параметра: номер строки и номер столбца. В случае таких характеристик,
как cup или sgr (установка атрибутов), параметры передаются через входящую в
terminfo подпрограмму tparm().
Аргументы параметрических характеристик обрабатываются согласно
включенным в описания этих характеристик специальным последова-
тельностям символов, которые начинаются с %. Эти
последовательности похожи на те, которые используются в
printf(3S). Кроме
того, данные можно записать в стек и производить над ними операции,
которые записываются в виде, близком к обратной польской
записи. Как мы упомянули, cup имеет два аргумента: номер строки
и номер столбца. sgr имеет девять аргументов, по одному на каждый
из атрибутов отображения. Список аргументов sgr и порядок
их следования, а также примеры см. в terminfo(4).
Пусть на нашем терминале курсор позиционируется последовательностью,
состоящей из символов ESC [, за которыми следуют номера
строки и столбца, разделенные точкой с запятой, а в конце идет
H. Координаты задаются относительно 1, а не нуля. Так, чтобы
передвинуть курсор в позицию (5, 18) относительно (0, 0), необ-
ходимо передать последовательность \E[6;19H.
Целочисленные аргументы записываются в стек последовательностью
%p, за которой следует номер аргумента, например, %p2 для
записи в стек второго аргумента. %i - это краткая
запись для увеличения первых двух аргументов. Для вывода числа из вершины стека
в десятичном виде используется %d, как и в
printf. Последовательность cup нашего терминала
строится следующим образом:
или
Добавив это к нашему описанию, получим:
Подробнее о параметризованных цепочках см. terminfo(4).
Описания терминалов в базе данных terminfo
переводятся из исходного в компилированный формат компилятором
tic(1M).
Исходный файл с описанием обычно имеет расширение .ti.
Например, описание myterm будет называться myterm.ti.
Скомпилированное описание myterm обычно помещается в
/usr/lib/terminfo/m/ myterm, так как название терминала
начинается на m. myterm будет также иметь синонимы, например,
/f/fancy. Если перед компиляцией установлено и помещено в
окружение значение переменной
$TERMINFO, скомпилированное описание будет помещено в каталог
$TERMINFO. В этом случае все программы будут искать описание
терминала сначала в каталоге $TERMINFO, а затем уже в
подразумеваемом каталоге /usr/lib/terminfo. Общий формат командной
строки для запуска компилятора tic таков:
Опция -v требует выводи трассировочной информации о ходе
компиляции файла. Опция -c задает поиск ошибок в описании,
она может использоваться одновременно с -v. Если нужно
скомпилировать
сразу несколько файлов, следует прежде воспользоваться командой
cat(1) для их объединения. Приведенная ниже командная
строка задает компиляцию описания
terminfo для нашего гипотетического
терминала:
Подробную информацию о компиляторе см. в Справочнике
администратора, tic(1M).
Рассмотрим три способа тестирования описания терминала. Во-первых,
можно установить значение переменной окружения $TERMINFO
равным имени каталога, содержащего это описание. Если программы
выполняются на новом терминале так же, как они делали это на
других терминалах, новое описание пригодно для использования.
Во-вторых, можно проверить правильность заполнения экрана при
вставке строк, для чего закомментировать характеристику xon в
описании терминала и редактировать при помощи vi(1) большой
файл (не менее ста строк) при скорости передачи 9600 бод, если
это возможно. Удалите около 15 строк в середине экрана и быстро
нажмите несколько раз u (отменить операцию). Если содержимое
экрана портится, то, вероятно, нужно увеличить время задержки.
Примерно такой же тест можно использовать для проверки вставки
символа.
В-третьих, можно воспользоваться командой tput(1). Эта команда
выводит значение характеристики - числовое или текстовое, в зависимости
от ее типа. Если характеристика булева, tput ничего
не выводит, но возвращает код завершения (0, если истина, 1,
если ложь). Общий формат команды tput таков:
Следующая командная строка показывает, как выводится на экран
последовательность для очистки экрана:
Следующая командная строка показывает, как отобразить на
терминале количество колонок, имеющихся на его экране:
Более подробную информацию о команде tput и выводимых ей
сообщениях см. в Справочнике пользователя, tput(1).
Иногда бывает необходимо сравнить описания двух терминалов или
просмотреть описание, не обращаясь к каталогу, содержащему исходные тексты
описаний terminfo. В обоих случаях можно
воспользоваться командой infocmp(1M). Сравнить два описания одного и
того же терминала можно, например, так:
Эта последовательность команд сравнивает старое и новое
описания терминала 5420.
Чтобы получить исходный текст описания
terminfo для 5420, введите
Предостережение
преобразует файл /etc/termcap в исходный текст в формате
terminfo, с сохранением комментариев и другой информации, не
относящейся собственно к описанию, если она присутствует. Командная строка
ищет описание текущего терминала в базе данных termcap (они
задаются значениями переменных окружения $TERM
и $TERMCAP соответственно) и преобразует его в формат terminfo.
Если нужны описания терминала как в формате termcap, так и в
формате terminfo, можно хранить только описание
terminfo и использовать infocmp -C
для получения описания в формате termcap.
Если Вы компилировали программы командой cc(1) с опциями
-ltermcap или -ltermlib,
они будут работоспособны и в дальнейшем.
Однако, вместо этих опций следует использовать -lcurses.
2.9.2. Использование программируемых меток
2.9.3. Работа с несколькими терминалами сразу
for (i=0; i<nterm; i++) {
set_term (terms[i]);
mvaddstr (0, 0, "Важное сообщение");
refresh ();
}
3. ИСПОЛЬЗОВАНИЕ ПОДПРОГРАММ ПАКЕТА TERMINFO
3.1. Что нужно программе для работы с terminfo
#include <curses.h>
#include <term.h>
. . .
setupterm ((char*) 0, 1, (int*) 0);
. . .
putp (clear_screen);
. . .
reset_shell_mode ();
exit (0);
3.2. Компиляция и выполнение программ,
которые используют terminfo
3.3. Пример программы, работающей с terminfo
Программа termhl - это простой пример использования подпрограмм
terminfo. Она является вариантом программы
highlight (см. раздел Примеры программ, работающих с
curses), в котором не используются возможности
curses более высокого уровня. Программу
termhl можно использовать в качестве фильтра, вставляющего
последовательности символов, необходимые для включения режимов
подсветки и подчеркивания и для отключения всех атрибутов.
/* Версия программы highlight уровня terminfo */
#include <curses.h>
#include <term.h>
int ulmode = 0; /* Режим подчеркивания */
main (argc, argv)
int argc;
char **argv;
{
FILE *fd;
int c, c2;
int outch();
if (argc > 2) {
fprintf (stderr, "Откуда: 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);
}
/* Функция putch подобна putchar, */
/* но проверяет необходимость подчеркивания */
putch (c)
int c;
{
outch (c);
if (ulmode && underline_char) {
outch ('\b');
tputs (underlihe_char, 1, outch);
}
}
/* outchar передается tputs в качестве параметра */
/* как функция, которую нужно вызывать вместо putchar */
outch (c)
int c;
{
putchar (c);
}
4. ИСПОЛЬЗОВАНИЕ БАЗЫ ДАННЫХ TERMINFO
4.1. Создание описания терминала
4.1.1. Название терминала
5420|att5420|AT&T Teletype 5420,
myterm|mytm|mine|fancy|terminal|My FANCY Terminal,
4.1.2. Выяснение характеристик терминала
stty -echo; cat -vu
нажмите тестируемые клавиши,
например, стрелку вправо.
<CR>
CTRL+D
stty echo
или
cat >dev/null
нажмите клавиши тестируемой
управляющей последовательности,
например, \E[H.
CTRL+D
4.1.3. Указание характеристик терминала
#
Указывает, что далее следует числовое значение характеристики.
Например, количество столбцов может
определяться в виде cols#80. =
Указывает, что значение характеристики является
цепочкой символов. Эта цепочка в действительности
может быть последовательностью команд, требующих
от терминала выполнения определенных действий. В
таких цепочках могут использоваться некоторые специальные
символы, а именно:
^
Обозначает управляющий символ. Например,
звуковой сигнал подается передачей CTRL+G,
что записывается в виде ^G. \e
или \E
В сопровождении еще каких-либо символов
обозначают escape-последовательности. Например,
\EC передается на терминал в виде ESC C. \n
Обозначает перевод строки. \l
Обозначает переход к новой строке. \r
Обозначает возврат каретки. \t
Обозначает горизонтальную табуляцию. \b
Обозначает возврат на символ назад. \f
Обозначает переход к новой странице. \s
Обозначает пробел. \nnn
Обозначает символ с восьмеричным кодом nnn,
где nnn может иметь от одной до трех цифр.
$< >
Эти символы используются для обозначения задержки в
миллисекундах. Длительность задержки заключается в
угловые скобки (<>). Она
может быть целым или десятичным числом с одной
цифрой после точки. После числа может
следовать звездочка (*). Звездочка указывает,
что длительность задержки пропорциональна количеству
вовлеченных в операцию строк.
Например, задержка в 20 миллисекунд на строку указывается в виде
$<20*>. Более подробную информацию о задержке и
символах-заполнителях см. в terminfo(4).
.bel=^G,
Теперь, когда мы узнали, как описываются характеристики терминала,
опишем их для myterm. Мы рассмотрим характеристики экрана, клавиатуры,
основные и параметрические характеристики.
mytermmytmminefancyterminalMy FANCY Terminal,
am, bel=^G, cols#80, lines#30, xon,
mytermmytmminefancyterminalMy FANCY Terminal,
am, bel=^G, cols#80, lines#30, xon,
cr=^M, cuu1=^K, cud1=^G, cub1=^H, cuf1=^L,
smso=\ED, rmso=\EZ, el=\EK$<3>, ind=\n,
mytermmytmminefancyterminalMy FANCY Terminal,
am, bel=^G, cols#80, lines#30, xon,
cr=^M, cuu1=^K, cud1=^G, cub1=^H, cuf1=^L,
smso=\ED, rmso=\EZ, el=\EK$<3>, ind=\n,
kbs=^H, kcuu1=\E[A, kcud1=\E[B, kcuf1=\E[C,
kcub1=\E[D, khome=\E[H,
cup=
Пояснения \E[
вывести ESC [
%i
увеличить оба аргумента
%p1
записать первый аргумент (номер строки) в стек
%d
вывести номер строки в десятичном виде
;
вывести точку с запятой
%p2
записать второй аргумент (номер столбца в стек)
%d
вывести номер столбца в десятичном виде
H
вывести завершающий цепочку символ H
cup=\E[%i%p1%d;%p2%dH,
mytermmytmminefancyterminalMy FANCY Terminal,
am, bel=^G, cols#80, lines#30, xon,
cr=^M, cuu1=^K, cud1=^G, cub1=^H, cuf1=^L,
smso=\ED, rmso=\EZ, el=\EK$<3>, ind=\n,
kbs=^H, kcuu1=\E[A, kcud1=\E[B, kcuf1=\E[C,
kcub1=\E[D, khome=\E[H,
cup=\E[%i%p1%d;%p2%dH,
4.1.4. Компиляция описания
tic [-v[число]] [-c] файл
tic -v myterm.ti
# в ходе компиляции выдается трассировочная информация
4.1.5. Тестирование описания
tput [-T тип] характеристика
Опция -Tтип задает тип терминала, о котором
вы запрашиваете информацию. Обычно эту опцию указывать не требуется,
так как по
умолчанию в качестве имени терминала берется значение переменной
окружения $TERM. Поле характеристика указывает, значение
какой характеристики надо извлечь из базы данных terminfo.
tput clear
# экран терминала очищается
tput cols
# здесь появится количество колонок
4.2. Печать и сравнение описаний
в базе данных terminfo
mkdir /tmp/old /tmp/new
TERMINFO=/tmp/old tic old5420.ti
TERMINFO=/tmp/new tic new5420.ti
infocmp -A /tmp/old -B /tmp/new -d 5420 5420
infocmp -I 5420
4.3. Преобразование termcap-описания
в terminfo-описание
captoinfo /etc/termcap
captoinfo
5. ПРИМЕРЫ ПРОГРАММ, РАБОТАЮЩИХ С CURSES