приложений обычно используют только некоторые из этих функций, а остальные вызываются внутри самой библиотеки S-Lang.
Семейство SLsmg
предлагает высокий уровень абстракции терминала. Хотя эти функции используют функции семейства SLtt
для управления терминалом, они предлагают разработчикам приложений интерфейс с более широкими возможностями.
Эти функции отвечают за вывод строк, рисование линий и отправку запросов к экрану. Чтобы не допустить снижения производительности, эти подпрограммы осуществляют запись во внутренний буфер, а не напрямую на терминал. Когда приложение посылает библиотеке S-Lang запрос на обновление физического терминала, она сравнивает новое содержимое с исходным и соответствующим образом оптимизирует последовательность выходных данных.
24.2.1. Инициализация управления экраном
Прежде чем использовать функции библиотеки S-Lang для вывода данных на терминал, программа должна послать S-Lang запрос на поиск текущего терминала (как это определено в переменной окружения TERM
) в терминальной базе данных. Это осуществляется следующим образом:
void SLtt_get_terminfo(void);
Одной из главных задач функции SLtt_get_terminfo()
является установка физического размера экрана в соответствии с размером, указанным в базе данных терминала. Информация о количестве строк и колонок в терминале хранится, соответственно, в SLtt_Screen_Rows
и SLtt_Screen_Cols
. Хотя данные в терминальной базе данных обычно корректны, в настоящее время широкую популярность приобрели терминалы с изменяемыми размерами (например, xterms
). После того как размер такого терминала будет изменен по отношению к размеру, принятому по умолчанию, терминальная база данных не будет содержать корректной информации о размерах терминала. Для компенсации этой неточности библиотека S-Lang позволяет программам восстанавливать исходные значения SLtt_Screen_Rows
и SLtt_Screen_Cols
после вызова функции SLtt_get_terminfo()
. В системе Unix текущие размеры терминала всегда можно узнать с помощью команды TIOCGWINSZ
управления вводом-выводом, которая подробно описана в главе 16.
Инициализировать уровень управления экраном в S-Lang можно очень просто:
void SLsmg_init_smg(void);
SLsmg_init_smg()
24.2.2. Обновление экрана
Прежде чем результаты выполнения последовательности подпрограмм SLsmg
смогут быть отражены на физическом терминале, необходимо вызвать функцию SLsmg_refresh()
. Эта функция не принимает аргументы и не возвращает значения, а обновляет физический терминал по результатам рисования чего-либо на экране, которое было выполнено со времени ее последнего вызова.
24.2.3. Перемещение курсора
Как и в большинстве программ, курсор терминала используется библиотекой S-Lang для обозначения позиции, принятой по умолчанию, для ввода текста и для подсказки пользователю. Программы S-Lang могут перемещать курсор с помощью показанной ниже функции.
extern void SLsmg_gotorc(int row, int column);
Имейте в виду, что верхний левый угол экрана определяется координатами (0, 0
), а нижний правый угол — (SLtt_Screen_Rows - 1, SLtt_Screen_Cols - 1
).
24.2.4. Завершение управления экраном
Когда программа, использующая SLsmg
, завершает свою работу, она должна послать библиотеке S-Lang соответствующее сообщение об этом, после чего библиотека освободит буферы и восстановит состояние терминала. Прежде чем сделать это, будет правильным переместить курсор вниз экрана и обновить дисплей, чтобы пользователь смог увидеть все выводимые данные.
24.2.5. Скелет программы управления экраном
Ниже приведен пример программы, которая сначала инициализирует возможности библиотеки S- Lang для управления экраном, а затем закрывает их. Хотя эта программа выполняет лишь некоторые действия, она иллюстрирует основы использования функциональных возможностей SLsmg
библиотеки S-Lang.
1: /* slinit.с */
2:
3: #include <slang/slang.h>
4: #include <stdio.h>
5: #include <sys/ioctl.h>
6: #include <termios.h>
7:
8: int main(void) {
9: struct winsize ws;
10:
11: /* получение размеров терминала, подключенного к stdout */
12: if (ioctl(1, TIOCGWINSZ, &ws)) {
13: perror('сбой при получении размеров окна');
14: return 1;
15: }
16:
17: SLtt_get_terminfo();
18:
19: SLtt_Screen_Rows = ws.ws_row;
20: SLtt_Screen_Cols = ws.ws_col;
21:
22: SLsmg_init_smg();
23:
24: /* здесь находится ядро программы */
25:
26: SLsmg_gotorc(SLtt_Screen_Rows - 1, 0);