Основы программирования в Linux
el1=\E[1K$<3>, enacs=\E(B\E)0, home=\E[H, ht=\t,hts=\EH, ind=\n, ka1=\EOq, ka3=\EOs, kb2=\EOr, kbs=\b,kc1=\EOp, kc3=\EOn, kcub1=\EOD, kcud1=\EOB,kcuf1=\EOC, kcuu1=\EOA, kent=\EOM, kf0=\EOy, kf1=\EOP,kf10=\EOx, kf2=\EOQ, kf3=\EOR, kf4=\EOS, kf5=\EOt,kf6=\EOu, kf7=\EOv, kf8=\EOl, kf9=\EOw, rc=\E8,rev=\E[7m$<2>, ri=\EM$<5>, rmacs=^O, rmkx=\E[?11\E>,rmso=\E[m$<2>, rmul=\E[m$<2>,rs2=\E>\E[?31\E[?41\E[?51\E[?7h\E[?8h, sc=\E7,sgr=\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t^N%e^O%;,sgr0=\E[m^0$<2>, smacs=^N, smkx=\E[?1h\E=,smso=\E[1;7m$<2>; smul=\E[4m$<2>, tbc=\E[3g,Каждое определение в
состоит из трех типов элементов. Каждый элемент называетсяterminfo(имя характеристики) и определяет характеристику терминала.capnameБулевы или логические характеристики просто обозначают наличие или отсутствие поддержки терминалом конкретного свойства. Например, булева характеристика
присутствует, если терминал поддерживает управление потокомxon.XON/XOFFЧисловые характеристики определяют размеры или объемы, например
— это количество строк на экране, alines— количество столбцов. Число отделяется от имени характеристики символомcols. Для описания терминала с 80 столбцами и 24 строками следует написать#.cols#80, lines#24Строковые характеристики немного сложнее. Они применяются для двух разных типов характеристик: определения строк вывода, необходимых для доступа к функциям терминала, и определения строк ввода, которые будут получены, когда пользователь нажмет определенные клавиши, обычно функциональные или специальные клавиши на цифровой клавиатуре. Некоторые строковые параметры очень просты, например
, что означает "стереть до конца строки". Для того чтобы сделать это на терминале VT100, потребуется escape-последовательностьel. В исходном формате terminfo это записывается какEsc, [, K.еl=\Е[KСпециальные клавиши определены аналогичным образом. Например, функциональная клавиша <F1> на терминале VT100 посылает последовательность
, которая определяется какEsc, O, P.kf1=\EOPВсе несколько усложняется, если escape-последовательности требуются какие-либо параметры. Большинство терминалов могут перемещать курсор в заданные строку и столбец. Ясно, что неразумно хранить отдельную характеристику для каждой точки экрана, в которую можно переместить курсор, поэтому применяется общая строковая характеристика с параметрами, определяющими значения, которые вставляются при использовании характеристики. Например, терминал VT100 использует последовательность
для перемещения курсора в заданную позицию. В исходном формате terminfo это записывается довольно устрашающе:Esc, [, <row>, <col>, H.cup=\E[%i%p1%d;%p2%dH$<5>Эта строка означает следующее:
□
— послать escape-символ;\E□
— послать символ[;[□
— дать приращение аргументам;%i□
— поместить первый аргумент в стек;%p1□
— вывести число из стека как десятичное;%d□
— послать символ;;;□
— поместить второй аргумент в стек;%р2□
— вывести число из стека как десятичное;%d□
—послать символH.HДанная запись кажется сложной, но позволяет задавать параметры в строгом порядке, не зависящем от порядка, в котором терминал ожидает их появления в финальной escape-последовательности. Приращение аргументов
необходимо, поскольку стандартная адресация курсора задается, начиная от верхнего левого угла экрана (0, 0), а терминал VT100 обозначает начальную позицию курсора как (1, 1). Заключительные символы%iозначают, что для обработки терминалом перемещения курсора требуется задержка, эквивалентная времени вывода пяти символов.$<5>ПримечаниеМы могли бы описывать огромное множество характеристик, но, к счастью, в основном системы UNIX и Linux приходят с большинством предопределенных терминалов. Если нужно добавить новую модель терминала, вы можете найти полный список характеристик на странице интерактивного справочного руководства, посвященной terminfo. Лучше всего начать с поиска включенного в базу данных терминала, похожего на ваш новый, и затем создания описания новой модели как вариации существующего, т. е. осуществить последовательный просмотр характеристик, одну за другой, и исправление нуждающихся в корректировке.
Применение характеристик terminfo
Теперь, когда вы знаете, как определить характеристики терминала, нужно научиться обращаться к ним. Когда используется terminfo, прежде всего вам нужно задать тип терминала, вызвав функцию
. Она инициализирует структуруsetuptermдля текущего типа терминала. После этого вы сможете запрашивать характеристики терминала и применять его функциональные возможности. Делается это с помощью вызоваTERMINAL, подобного приведенному далее:setupterm<b>#include <term.h></b><b>int setupterm(char *term, int fd, int *errret);</b>Библиотечная функция
задает текущий тип терминала в соответствии с заданным параметромsetupterm. Еслиterm— пустой указатель, применяется переменная окруженияterm. Открытый дескриптор файла, предназначенный для записи на терминал, должен передаваться в параметреTERM. Результат функции хранится в целой переменной, на которую указываетfd, если это не пустой указатель. Могут быть записаны следующие значения:errret□ -1 — нет базы данных terminfo;
□ 0 — нет совпадающего элемента в базе данных terminfo;
□ 1 — успешное завершение.
Функция
возвращает константуsetuptermв случае успешного завершения иOKв случае сбоя. Если на параметрERRустановлен как пустой указатель,errretвыведет диагностическое сообщение и завершит программу в случае своего аварийного завершения, как в следующем примере:setupterm