Майкл Джонсон - Разработка приложений в среде Linux. Второе издание
Одной из главных задач функции 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);
27: SLsmg_refresh();
28: SLsmg_reset_smg();
29: SLang_reset_tty();
30:
31: return 0;
32: }
24.2.6. Переключение наборов символов
Большинство современных терминалов (включая VT100, который достаточно точно эмулирует консоль Linux) поддерживают как минимум два набора символов. Основным набором обычно является ISO-8859-1 или ему подобный; другой набор используется главным образом для линейных символов. Библиотека S-Lang позволяет выбирать набор тех символов, которые будут применяться для вычерчивания символов.
void SLsmg_set_char_set(int useAlternate)
Если функцию SLsmg_set_char_set() вызвать с ненулевым аргументом, на экране будут выводиться новые символы, отображаемые с применением альтернативного набора символов. Если функцию SLsmg_set_char_set() вызвать с нулевым аргументом, то это отображение использоваться не будет, вследствие чего на экране будут появляться обычные символы.
S-Lang определяет набор символических имен для наиболее часто используемых линейных символов, входящих в альтернативный набор. В табл. 24.1 перечислены доступные линейные символы и имена S-Lang для каждого из них.
Таблица 24.1. Линейные символы
Глиф Символическая константа ─ SLSMG_HLINE_CHAR │ SLSMG_VLINE_CHAR ┌ SLSMG_ULCORN_CHAR ┐ SLSMG_URCORN_CHAR └ SLSMG_LLCORN_CHAR ┘ SLSMG_LRCORN_CHAR ┤ SLSMG_RTEE_CHAR ├ SLSMG_LTEE_CHAR ┬ SLSMG_UTEE_CHAR ┴ SLSMG_DTEE_CHAR ┼ SLSMG_PLUS_CHAR24.2.7. Запись на экран
Записать строки на экран под управлением S-Lang можно несколькими различными способами, суть которых одинакова. Далее приводится полный список функций, предназначенных для этой цели.
void SLsmg_write_char(char ch);
void SLsmg_write_string(char * str);
void SLsmg_write_nchars(char * chars, int length);
void SLsmg_write_nstring(char * str, int length);
void SLsmg_printf(char * format, ...);
void SLsmg_vprintf(char * format, va_list args);
void SLsmg_write_wrapped_string(char * str, int row, int column, int height,
int width, int fill);
Каждая из этих функций, за исключением SLsmg_write_wrapped_string(), записывает требуемую строку в буфер экрана[170] в текущую позицию курсора, используя текущий цвет и набор символов. Однако все они по-разному определяют, какую строку необходимо записать. После того как информация будет записана, курсор переместится в конец выделенной для этого области, как и на обычном терминале. Любая строка, выходящая за пределы правого края экрана, усекается, а не переносится на другую строку. Хотя этот способ отличается от обычного вывода на терминал, он подходит для большинства полноэкранных приложений, в которых текст, переводимый на новую строку, искажает содержимое экрана.
SLsmg_write_char() Среди всех функций вывода данных на экран это самая простая функция. Она записывает передаваемый символ в текущую позицию курсора и перемещает курсор. SLsmg_write_string() Выводит на экран передаваемую ей строку. SLsmg_write_nchars() Выводит на экран символы length, на которые указывает chars. Символ конца строки NULL игнорируется — если он будет найден, выводится комбинация ' ' и подпрограмма продолжает работу после окончания строки. SLsmg_write_nstring() Выводит на экран не более length символов из str. Если str содержит менее length символов, оставшееся пространство заполняется пробелами. SLsmg_printf() Как можно судить из имени функции, она работает подобно стандартной функции printf(), форматируя первый аргумент, а остальные аргументы используются в качестве параметров для форматирования. После этого на экран выводится сформатированная строка. SLsmg_vprintf() Подобно функции vfprintf() из библиотеки С. Эта функция ожидает получение аргумента va_arg, который она использует для форматирования первого параметра. Затем на экран выводится сформатированная строка. SLsmg_write_wrapped_string() Хотя S-Lang отсекает строки, а не переносит их на следующие строки, она предлагает простую функцию для записи строк, перенесенных в произвольную прямоугольную область экрана. Функция SLsmg_write_wrapped_string() записывает строку str в прямоугольную область, которая начинается в row и column и имеет размеры height и width. Несмотря на то что эта подпрограмма осуществляет перенос границ слов, последовательность n указывает на необходимость перехода на следующую строку. Если последний параметр fill имеет ненулевое значение, то каждая строка будет заполнена по всей ширине прямоугольной области, а при необходимости будут добавляться пробелы.24.2.8. Рисование линий и прямоугольников