rxvt игнорирует последовательность DECCKM
Я пишу сервер CLI. В моем проекте я делаю следующее (упрощение):
curses.setupterm("rxvt")
smkx = curses.tigetstr("smkx")
write_to_terminal_client(smkx)
Обнаруженная последовательность smkx - это только "\E=", что соответствует "infocmp rxvt" (плохая запись terminfo?).
Теперь, когда я запускаю свой CLI-сервер и подключаюсь к нему через telnet, запущенный на терминале rxvt, терминал получает последовательность smkx. Когда пользователь на терминале rxvt нажимает клавишу со стрелкой влево, я ожидаю, что последовательность "\E[D" будет отправлена на сервер CLI (поскольку был установлен режим приложения). К сожалению, последовательность всегда "\EOD", когда последовательность smkx была и не была отправлена клиенту терминала.
Я попытался жестко закодировать последовательность smkx в "\E[?1h\E=" и отправить ее клиенту, но это ничего не изменило.
Также терминал не отвечает на запрос DECRQM.
Моя полная картина такова, что мое приложение узнает имя терминала и запрашивает базу данных terminfo для кодов ключей и других возможностей. Я бегу Ubuntu 13.10. Rxvt терминал "2.7.10"
Вопросы:
- Я делаю что-то не так?
- Если нет, то как я должен понимать smkx="\E=", а не "\E[?1h\E=" (DECCKM не поддерживается?)
- Как правильно обнаруживать такие ситуации и справляться с ними (откат к последовательностям курсора ANSI?)
С уважением
1 ответ
Проблема заключается в том, что ваша программа отправляет smkx
(хорошо), но при условии, что он знает строки, которые будут отправлены для различных специальных ключей (не хорошо). В правильно построенном описании терминала также перечислены специальные ключи (см. Terminfo (5)):
key_up kcuu1 ku up-arrow key key_down kcud1 kd down-arrow key key_left kcub1 kl left-arrow key key_right kcuf1 kr right-arrow key
Так что вместо того, чтобы искать \E[D
ваша программа должна искать что угодно tigetstr
говорит, что строка для kcub1
,
относительно DECRQM
rxvt может не реализовывать это, потому что это не последовательность управления "VT100". Что касается последовательности управления XTerm, то есть "Для VT300 и выше", а на странице руководства rxvt написано "терминал vt102".
Хотя иногда сообщается о проблемах, база данных терминала во многом отражает компромиссы между соглашениями пользователей и фактическими возможностями терминала. Некоторые пользователи (в частности, пользователи Linux с bash
) предпочитаю не использовать режим приложения терминала. За пределами этой ниши давним соглашением было использование режима приложения. Руководство xterm предоставляет дополнительное обсуждение по этой теме.
В курсах, infocmp
команда имеет особенность (опция -i
), который позволяет вам (более) ясно видеть эффект строк инициализации. Он не разлагает rmkx/smkx, но это легко добавляется. Сделав это, он сообщит для rxvt:
is1: {DEC-47}{DECPAM}{DEC-CKM}
is2: {RSR}{SGR0}\E[2J{home}{DEC+AWM}{DEC-CKM;COLM;SCLM;OM}{rmir}
rs1: {rmkx}{ECMA-1;3;IRM;5;6}{DEC+AWM}{SGR0}{RSR}\E[2J{home}
rs2: {is2}{rmkx}{DEC-1000}{cnorm}
smcup: {sc}{DEC+47}
rmcup: \E[2J{DEC-47}{rc}
smkx: {DECPAM}
rmkx: {DECPNM}
и xterm:
is2: \E[!p{DEC-COLM;SCLM}{rmir}{DECPNM}
rs1: {RIS}
rs2: {is2}
smcup: {DEC+1049}
rmcup: {DEC-1049}
smkx: {DEC+CKM}{DECPAM}
rmkx: {DEC-CKM}{DECPNM}
То есть описание терминала для поворотов xterm DECCKM
(клавиши курсора) вкл / выкл с помощью smkx/rmkx, в то время как для rxvt - нет. Кроме того, строка инициализации rxvt превращается DECCKM
выкл.