Работа с символами с помощью curses

Вводить символы в окно curses можно с клавиатуры или из приложения. В этом разделе описаны способы добавления, удаления и изменения символов в окне curses.

Размер символов

Некоторые наборы включают символы, занимающие несколько столбцов на экране.

Вывод символа, ширина которого превышает ширину целевого окна, приводит к ошибке.

Добавление символов к изображению на экране

Библиотека curses содержит набор функций, позволяющих изменять текст в окне и выделять область, которая должна быть обновлена при следующем вызове функции wrefresh.

Функции waddch

Функции waddch заменяют символ в текущей позиции логического курсора на указанный символ. После этого логический курсор перемещается на одну позицию вправо. На правой границе окна функции waddch автоматически добавляют символ новой строки. Кроме того, если курсор находится на нижней границе и применяется функция scrollok, то область прокручивается на одну строку вверх. Это происходит, например, при добавлении новой строки к последней строке окна.

При добавлении символа табуляции, новой строки или забоя библиотека curses соответственно обновляет позицию курсора в окне. Позиции табуляции расположены через каждые восемь символов. При выводе символа новой строки curses сначала вызывает функцию wclrtoeol, удаляющую все символы строки начиная с текущего положения курсора и до конца строки, а затем перемещает курсор. Семейство waddch состоит из следующих элементов:
Функция Описание
Макрокоманда addch Выводит символ в stdscr
Макрокоманда mvaddch Перемещает курсор, а затем выводит символ в позиции курсора в stdscr
Макрокоманда mvwaddch Перемещает курсор, а затем выводит символ в позиции курсора в пользовательское окно
Функция waddch Выводит символ в пользовательское окно

Применяя совместно функции семейств winch и waddch, можно скопировать текст и атрибуты видеоизображения из одной области окна в другую. Функции семейства winch позволяют получать символы и атрибуты из окна или экрана, а функции waddch - выводить символы на экран.

Кроме того, функции waddch позволяют выводить управляющие символы. Эти символы будут показаны в виде ^X.

Прим.: Если позиция, для которой вызвана функция winch, содержит управляющий символ, тот этот символ не возвращается. Вместо него будет возвращен символ, представляющий управляющий символ на экране.

Вывод символов, отличных от управляющих

Для вывода отдельных символов, отличных от управляющих, рекомендуется использовать функции wechochar, которые дают значительный выигрыш в производительности. Эти функции по своему действию равносильны соответствующим парам функций waddchr и wrefresh. В семейство wechochar входят функция wechochar, макроопределение echochar и функция pechochar.

Некоторые наборы символов содержат невидимые символы. (Невидимыми называются отличные от ('\0') символы, для которых функция wcwidth возвращает нулевую ширину.) Приложение может выводить такие символы в окно. Каждый невидимый символ связан с обычным символом и изменяет его определенным образом. Невидимые символы в окне не адресуются непосредственно. Они неявно адресуются при выполнении операций curses над обычными символами, с которыми связаны невидимые символы.

С невидимыми символами не связаны атрибуты. Если в интерфейсе поддерживаются широкие символы и атрибуты, то атрибуты, связанные с невидимыми широкими символами игнорируются. При выводе широких символов для всех столбцов определен единый набор атрибутов. Приложение может управлять соотношением между невидимыми символами и обычными символами с помощью интерфейса широких символов. Это соотношение зависит от конкретного набора символов.

Обычно невидимый символ действует на обычный символ (назовем его c) одним из следующих способов:

  • Невидимый символ может изменить вид символа c. (Например, некоторые невидимые символы добавляют к обычным символам диакритические знаки. В то же время, некоторые символы содержат собственные диакритические знаки.)
  • Невидимый символ может объединить символ c со следующим за ним символом. Примером может служить образование лигатур и преобразование символов в составные изображения, слова или идеограммы.

Максимальное число невидимых символов, которые могут быть связаны с одним обычным символом, зависит от конкретной реализации, но всегда не меньше 5.

Составные символы

Составной символ - это набор связанных символов, который может включать один обычный символ, а также некоторое количество невидимых символов. Видимый составной символ обязательно содержит один обычный символ. Составные символы встречаются, например, в наборе символов ISO/IEC 10646-1:1993.

Составной символ может быть выведен на экран. Если составной символ не включает обычный символ, то все его невидимые символы связываются с обычным символом, находящимся в указанной точке экрана. При считывании информации с экрана приложение получает только видимые составные символы.

Тип данных cchar_t содержит описание и представление составного символа. Если cchar_t соответствует невидимому составному символу (в котором отсутствует обычный символ), то представление символа игнорируется. При выводе используется представление видимого символа, уже показанного на экране.

Объект типа cchar_t можно инициализировать с помощью функции setchar, а его содержимое можно получить с помощью функции getchar. Результат применения функций к объекту cchar_t, который не был инициализирован указанным способом или получен от функции curses типа cchar_t, не определен.

Специальные символы

Некоторые функции могут обрабатывать специальные символы. В функциях, не перемещающих курсор на основании содержимого окна, специальные символы будут влиять только на расположение последующих символов в строке. Любая заданная впоследствии операция перемещения курсора не повлияет на положение видимого курсора. В функциях, не перемещающих курсор, эти специальные символы могут применяться для управления положением последующих символов и перемещения физического курсора.

Символ Описание
Забой Символ Забой перемещает курсор на один столбец к началу строки, если только он уже не находится в нулевом столбце; все дальнейшие символы добавляются с новой позиции курсора.
Возврат каретки Символ Возврат каретки перемещает курсор в начало текущей строки. Все дальнейшие символы добавляются с новой позиции курсора.
Новая строка В операции добавления функция curses заполняет пробелами текущую строку до конца. Затем выполняется прокрутка, курсор перемещается в начало новой строки и все последующие символы добавляются с новой позиции курсора.

В операции вставки функция curses очищает текущую строку до конца с помощью функции wclrtoeol , а затем помещает курсор в начало следующей строки. Переход курсора на следующую строку может вызвать прокрутку, если она разрешена. Все последующие символы вставляются с новой позиции курсора.

Такой способ обработки можно подавить с помощью функции filter.

Табуляция Символ табуляции в тексте сдвигает следующие за ним символы до очередной позиции табуляции. По умолчанию позиции табуляции расположены в столбцах 0, 8, 16 ...

В операции вставки или добавления функция curses соответственно вставляет или добавляет пробелы в последовательные столбцы до очередной позиции табуляции. Если до конца текущей строки позиции табуляции отсутствуют, выполняется перевод строки и прокрутка.

Управляющие символы

Функции curses, обрабатывающие специальные символы, заменяют их на символ '^' и обычный символ (если это буква, то она будет прописной). Функциям получения текста из окна передается указанная пара символов, а не код специального символа.

Псевдографика:

Ниже описаны переменные и функции waddch, с помощью которых вы можете выводить на экран символы псевдографики. Для применения символов из дополнительной части кодового набора нужно установить разряд A_ALTCHARSET. В противном случае будут выведены символы из основной части набора (см. столбец Символ по умолчанию в следующей таблице).

Имя переменной Символ по умолчанию Описание символа
ACS_ULCORNER + левый верхний угол
ACS_LLCORNER + левый нижний угол
ACS_URCORNER + правый верхний угол
ACS_LRCORNER + правый нижний угол
ACS_RTEE + правый тройник
ACS_LTEE + левый тройник
ACS_BTEE + нижний тройник
ACS_TTEE + верхний тройник
ACS_HLINE горизонтальная линия
ACS_VLINE | вертикальная линия
ACS_PLUS + знак плюс
ACS_S1 - верхняя линия
ACS_S9 _ нижняя линия
ACS_DIAMOND + ромб
ACS_CKBOARD : штриховка
ACS_DEGREE , символ градуса
ACS_PLMINUS # знак плюс-минус
ACS_BULLET o жирная точка
ACS_LARROW < стрелка влево
ACS_RARROW > стрелка вправо
ACS_DARROW v стрелка вниз
ACS_UARROW ^ стрелка вверх
ACS_BOARD # жирная штриховка
ACS_LANTERN # "солнышко"
ACS_BLOCK # закрашенный квадрат

Функции waddstr

Функции waddstr добавляют в окно строку, оканчивающуюся символом NULL, начиная с текущего символа. Для добавления одного символа эффективнее функция waddch. Функции waddstr предназначены для вывода строк символов. Семейство waddstr состоит из следующих элементов:
Функция Описание
Макрокоманда addstr Выводит строку символов в stdscr
Макрокоманда mvaddstr Перемещает логический курсор в заданную позицию, а затем добавляет строку символов в stdscr
Функция waddstr Выводит строку символов в пользовательское окно
Макрокоманда wmvaddstr Перемещает логический курсор в заданную позицию, а затем выводит строку символов в пользовательское окно

Функции winsch

Функции winsch вставляют символ перед текущим символом в окне. Все символы справа от вставленного сдвигаются на один столбец вправо. Такой сдвиг может привести к потере крайнего правого символа. Положения логических и физических курсоров не меняются. Семейство winsch включает следующие элементы:

Функция Описание
Функция insch Вставляет символ в stdscr
Макрокоманда mvinsch Перемещает логический курсор в указанную позицию, а затем вставляет символ в stdscr
Макрокоманда mvwinsch Перемещает логический курсор в указанную позицию, а затем вставляет символ в пользовательское окно
Функция winsch Вставляет символ в пользовательское окно

Функции winsertln

Функции winsertln вставляют пустую строку перед следующей. Функция insertln вставляет строку в stdscr. Нижняя строка окна удаляется. Функция winsertln выполняет аналогичную операцию с пользовательским окном.

Функции wprintw

Функции wprintw заменяют последовательность символов (начиная с текущего) форматированным выводом. Применяется тот же формат, что и в команде printf. Семейство printw состоит из следующих элементов:

Функция Описание
Макрокоманда mvprintw Перемещает логический курсор в указанную позицию, а затем заменяет последовательность символов в stdscr
Макрокоманда mvwprintw Перемещает логический курсор в указанную позицию, а затем заменяет последовательность символов в пользовательском окне
Макрокоманда printw Заменяет последовательность символов в stdscr
Функция wprintw Заменяет последовательность символов в пользовательском окне

Функции wprintw для замены символов вызывают функции waddch.

Макрокоманда unctrl

Макрокоманда unctrl возвращает печатное представление управляющих символов в формате ^X. Печатные символы макрокоманда unctrl оставляет без изменений.

Прокрутка текста

Следующие функции предназначены для прокрутки:
Функция Описание
idlok Разрешает библиотеке curses применять аппаратные функции вставки и удаления строк
scrollok Разрешает прокрутку окна при выходе курсора за правую границу последней строки
setscrreg и wsetscrreg Задает область программной прокрутки в окне

Если пользователь или приложение перемещают курсор за нижний край окна, то может быть выполнена прокрутка. Прокрутка должна быть разрешена функцией scrollok. Прокрутка выполняется, если она разрешена указанной функцией и происходит одно из следующих событий:

  • Курсор выходит за край окна.
  • К последней строке добавляется символ новой строки.
  • В последнюю позицию последней строки вставляется символ.

При прокрутке окна функции curses обновляют как окно, так и экран. Однако для того чтобы прокрутка была видна, необходимо вызвать функцию idlok с параметром Флаг, равным TRUE (истина).

Если прокрутка запрещена, то курсор остается на последней строке в позиции последнего введенного символа.

Если прокрутка окна разрешена, то с помощью функций setscrreg в нем можно создать программную область прокрутки. Вызываемым функциям setscrreg необходимо передать номера верхней и нижней строк области. После этого любая попытка вывести курсор за указанную нижнюю строку будет приводить к прокрутке всей области на одну строку вверх. Макроопределение setscrreg позволяет создать область прокрутки в stdscr. Для создания областей прокрутки в пользовательских окнах применяется функция wsetscrreg.

Прим.: В отличие от функции idlok, функции setscrreg не используют аппаратную прокрутку, даже если терминал обладает такой возможностью.

Удаление символов

Удаление символов может быть выполнено путем замены их пробелами или сдвига строки влево.

Функции werase

Макрокоманда erase заменяет пробелами все символы stdscr. Функция werase заменяет пробелами все символы пользовательского окна. Для удаления одного символа из окна воспользуйтесь функцией wdelch.

Функции wclear

Следующие функции предназначены для очистки экрана:
Функция Описание
clear или wclear Очищает экран и устанавливает флаг clear для следующего обновления.
clearok Определяет, будет ли выполнена очистка окна при следующем вызове функции refresh или wrefresh.

Функции wclear аналогичны функциям werase. Однако после замены всех символов окна пробелами функции wclear дополнительно вызывают функцию clearok. В результате при следующем вызове функции wrefresh экран автоматически очищается.

Семейство функций wclear включает функцию wclear, макрокоманду clear и функцию clearok. Макрокоманда clear заменяет пробелами все символы stdscr.

Функции wclrtoeol

Макрокоманда clrtoeol работает с stdscr, тогда как функция wclrtoeol выполняет те же действия в пользовательском окне.

Функции wclrtobot

Макрокоманда clrtobot работает с stdscr, тогда как функция wclrtobot выполняет те же действия в пользовательском окне.

Функции wdelch

Следующие функции предназначены для удаления символов с экрана:
Функция Описание
Макрокоманда delch Удаляет текущий символ из stdscr
Макрокоманда mvdelch Перемещает логический курсор в указанную позицию, а затем удаляет символ из stdscr
Макрокоманда mvwdelch Перемещает логический курсор в указанную позицию, а затем удаляет символ из пользовательского окна
Функция wdelch Удаляет текущий символ из пользовательского окна

Функции wdelch удаляют текущий символ и смещают все последующие символы текущей строки на одну позицию влево. Последний символ строки заменяется пробелом. Семейство функций delch состоит из следующих элементов:

Функции wdeleteln

Функции deleteln удаляют текущую строку и перемещают все последующие строки на одну строку вверх. Нижняя строка окна при этом очищается.

Получение символов

Программы могут получать символы как с клавиатуры, так и с экрана. Функции wgetch получают символы с клавиатуры, а функции winch - с экрана.

Функции wgetch

Функции wgetch получают символы, введенные с клавиатуры, подключенной к текущему терминалу. Если содержимое окна или положение курсора изменилось, то перед получением символа эти функции вызывают функции wrefresh. Дополнительная информация приведена в описании функции wgetch в Технический справочник: базовая операционная система и расширения, том 2.

Семейство wgetch состоит из следующих элементов:

Функция Описание
Макрокоманда getch Получает символ из stdscr
Макрокоманда mvgetch Перемещает логический курсор в указанную позицию, а затем получает символ из stdscr
Макрокоманда mvwgetch Перемещает логический курсор в указанную позицию, а затем получает символ из пользовательского окна
Функция wgetch Получает символ из пользовательского окна

Для того чтобы поместить символ, полученный с помощью функции wgetch, обратно в очередь ввода, вызовите функцию ungetch. Этот символ будет получен при следующем вызове функции wgetch.

Режимы работы терминала

Результат работы функции wgetch зависит от режима работы терминала. Ниже описаны действия, выполняемые функциями wgetch в каждом из режимов:

Функция Описание
Режим DELAY Приостанавливает считывание до тех пор, пока программа не обработает текст. Если включен режим CBREAK, то программа останавливается после чтения одного символа. Если режим CBREAK выключен (режим NOCBREAK), то функция wgetch прекращает чтение символов после обнаружения первого символа новой строки. Если включен режим ECHO, считанные символы отображаются в окне.
Режим HALF-DELAY Приостанавливает считывание до ввода символа или наступления заданного тайм-аута. Если включен режим ECHO, считанные символы отображаются в окне.
Режим NODELAY Возвращает значение ERR, если ввод отсутствует.
Прим.: В случае применения функций wgetch не устанавливайте одновременно режимы NOCBREAK и ECHO. Это может привести к непредсказуемым результатам, зависящим от состояния драйвера терминала в момент ввода каждого символа.

Функциональные клавиши

Функциональные клавиши определены в файле curses.h. Они могут быть получены функцией wgetch, если будут набраны с дополнительной клавиатуры. Терминал может поддерживать не все функциональные клавиши. Информация о поддержке клавиш приведена в базе данных terminfo. Список функциональных клавиш приведен в описании функций getch, mvgetch, mvwgetch и wgetch , приведенном в книге Технический справочник: базовая операционная система и расширения, том 2.

Получение кодов функциональных клавиш

Если программа вызывает функцию keypad и пользователь нажимает функциональную клавишу, то вместо соответствующей этой клавише последовательности символов возвращается код нажатой функциональной клавиши. Файл /usr/include/curses.h содержит определения возможных функциональных клавиш. Каждое определение начинается с префикса KEY_, а коды клавиш представляют собой целые числа, начинающиеся с 03510.

При получении символа, который может быть началом последовательности символов функциональной клавиши (например, символа Escape), curses устанавливает таймер (структуру типа timeval, определенную в файле /usr/include/sys/time.h). Если оставшаяся часть последовательности не поступает за отведенное время, то символ передается для дальнейшей обработки. В противном случае возвращается код функциональной клавиши. По этой причине программы реагируют на нажатие клавиши Esc с задержкой. В связи с этим не рекомендуется назначать какие-либо действия на клавишу Esc, если ввод считывается с клавиатуры функцией wgetch. Параметры таймера можно изменить с помощью переменной среды ESCDELAY.

Переменная среды ESCDELAY задает время ожидания дополнительных символов, по истечении которого вызывающей программе код клавиши Escape. ESCDELAY=1 означает задержку в 1/5000 с. Если переменная ESCDELAY равна нулю, то система передает код клавиши Escape, не ожидая появления в буфере дополнительной информации. Допустимы значения от 0 до 99999. По умолчанию значение ESCDELAY равно 500 (0,1 с).

Для того чтобы запретить функции wgetch устанавливать таймер, вызовите функцию notimeout. В этом случае curses не будет делать различия между функциональными и обычными клавишами.

Функция keyname

Функция keyname возвращает указатель на имя клавиши, код которой указан в аргументе Клавиша. Значение Клавиша может быть получено от любой из функций wgetch, getch, mvgetch или mvwgetch.

Функции winch

Функции winch считывают текущий символ. Если с символом связаны атрибуты, то они объединяются с полученным значением с помощью двоичной дизъюнкции. С помощью функций winch можно узнать код символа или его атрибуты. Для этого следует вычислить значение A_CHARTEXT & A_ATTRIBUTES. Указанные константы определены в файле curses.h. Семейство winch содержит следующие элементы:

Функция Описание
Макрокоманда inch Получает текущий символ из stdscr
Макрокоманда mvinch Перемещает логический курсор, а затем считывает символ из stdscr с помощью функции inch
Макрокоманда mvwinch Перемещает логический курсор, а затем вызывает функцию winch для считывания символа из пользовательского окна
Функция winch Получает текущий символ из пользовательского окна

Функции wscanw

Функции wscanw считывают символьные данные, интерпретируют их в соответствии с заданной спецификацией преобразования и сохраняют результат. Для считывания символов функции wscanw пользуются функциями wgetstr. Семейство wscanw состоит из следующих элементов:

Функция Описание
Макрокоманда mvscanw Перемещает логический курсор, а затем получает и обрабатывает данные из stdscr
Макрокоманда mvwscanw Перемещает логический курсор, а затем получает и обрабатывает данные из пользовательского окна
Макрокоманда scanw Получает и обрабатывает данные из stdscr
Функция wscanw Получает и обрабатывает данные из пользовательского окна

Функция vwscanw просматривает содержимое окна, получая список аргументов переменной длины. Информация о работе со списками аргументов переменной длины приведена в описании макрокоманд varargs в книге Технический справочник: базовая операционная система и расширения, том 2.