LINUX.ORG.RU

Terminal input


0

0

Вообщем такая беда. Я пишу либу, которая является альтернативой ncurses. Основная задача вполне простая - забить на всякого рода переносимость и реализовать её хотя бы под линукс для нескольких мажорных эмуляторов терминалов (urxvt, xterm).

Если с выводом особо проблем нет. То input это настоящий АД. Я хочу handle'ить инпут в нормальном гуевом стиле, т.е. с знанием того, что такое modifier (ctrl, shift, alt), что такое ESC и функциональные кнопки (tab, insert, delete, f1, fN, pgdn, pgup, etc.) и что такое unicode конечно же.

А что мы имеем в терминале? Терминал посылает очереди символов (сиквенсы), в которых что-то там закодировано. Причем он якобы понятия не имеет, что такое модификаторы. Ctrl+<letter> имеют свои коды, Ctrl+A, Ctrl+B ... Ctrl+Z мапятся в 1,2,3,etc. Далее, ESC и Alt посылают один и тот же код, о таких фичах как Ctrl+Shift+<letter> можно сразу забыть, функциональные кнопки тоже не особо хорошо работают с модификаторами, например Ctrl+Arrow_left не проканает (на некоторых терминалах работает).

Вообщем это настоящий ад. Ещё всё отягощает тот факт, что ввод приходит не отдельными сообщениями, а потоком байтов. Получается такая ситуация, что однозначно трактовать поток байтов невозможно. Типичный пример, Left_arrow присылает <ESC>[D, т.е. можно с таким же успехом набрать <Alt>+[ <Shift>+D и если прога не видит разницу во времени нажатия клавишь, то различить их просто не возможно.

В итоге я пришел к выводу, что ввод в терминале полное говно и нужно искать решение для его замены. Тут могут некоторые возразить, мол нафига тебе вообще этот терминал сдался, типа на дворе век GUI. Пожалуйста думайте как хотите, но лично мне сделать GUI в терминале проще для некоторых случаев.

Итак что я хочу? Я хочу найти решение этой проблемы. Вот некоторые пути, которые я вижу:

1. Модифицировать эмулятор терминала, добавив в него новый RAW input mode, который вместо символов будет присылать структуры прямиком из X events или с некоторыми простыми преобразованиями. Как многие наверняка знают, в эмуляторах терминала есть уже управляемые режимы (terminfo: enter_ca_mode, exit_ca_mode). Так вот, я сделал патч для urxvt пробный, который добавляет ещё один такой режим. Есть рабочая демка, всё работает как надо. Из проблем - возможные нарушения совместимости с такими штуками как gnu screen, однако и это можно исправить, если кодировать данные в каком-нить base64. Т.е. вполне реальный и действенный вариант, но он требует написания патчей для всех популярных терминалов и навязывания его разработчикам.

2. Попытаться обойти каким-нибудь образом ввод терминала. Например перехватить id X окошка терминала и брать из него input на прямую. Пока не придумал как реализовать (есть идеи, но сумасшедшие). Или заюзать скажем input из линукса напрямую (evdev), но будут проблемы с переключением раскладок и вообще в целом с key mapping'ом.

3. Убиться об стену/поставить windows (в котором кстати _нормальный_ консольный GUI api/сделать в либе кривой ввод, как это все делают/ваш вариант-шутка.

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

PS2. Если что не понятно из моих слов, спросите, я поясню.

nsf

anonymous

Re: Terminal input

Пусть либа хоть как-нибудь работает в случае неподдерживаемого терминала и работает хорошо в случае похаканного терминала.

Варианты с иксами идут лесом, ибо терминалы, вообще говоря, штука безиксовая, и я хочу иметь возможность писать в обычном линуксовом терминале. Т.е. придётся патчить и ядро.

В связи с этим либо новый режим должен быть backward compatible со старым (т.е. все существующие приложения работают на нём без изменений, как - не знаю), либо дополнять базу terminfo.

Проблема, безусловно, есть. Честно говоря, не уверен, что её реально решить, с учётом всего исторического груза. Если получится - будет здорово.

Legioner ★★★★★ ()
Ответ на: Re: Terminal input от Legioner

Re: Terminal input

>В связи с этим либо новый режим должен быть backward compatible со старым (т.е. все существующие приложения работают на нём без изменений, как - не знаю), либо дополнять базу terminfo.

Обратную совместимость я думаю можно осилить если хакать именно терминал. Но вот насчет gnu screen я всё ещё не уверен, скорее всего она сломается или её тоже придется пропатчить. Хотя, что тут думать, gnu screen вообщем-то и является полноправным эмулятором терминала, т.е. его однозначно придется патчить.

>Пусть либа хоть как-нибудь работает в случае неподдерживаемого терминала и работает хорошо в случае похаканного терминала.

Да, я тоже думаю, что придется делать два варианта реализации, один сломанный какой он есть сейчас в тех же ncurses и другой который работает с патчеными терминалами и выбирать наилучший из доступных.

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

Вообщем я и попробую этот вариант, но если кто ещё может что предложить или у кого имеются какие-нибудь мысли по теме - пишите!

nsf

anonymous ()

Re: Terminal input

IMHO проще взять готовый терминал ([amx]term по желанию) и допилить его до желаемого вида. естественно, это сугубо локальный вариант i.e. в аппаратном терминале не работает [в принципе пофигу] и, что самое хреновое, не будет работать over ssh :-/

// wbr

klalafuda ★☆☆ ()
Ответ на: Re: Terminal input от klalafuda

Re: Terminal input

Вообщем потыкался я потыкался, и решил написать простую либу - альтернативу ncurses, пусть и с обрезаным вводом. Как мне кажется она имеет лучший API, в некоторых случаях работает быстрее и имеет чёткую логику. Однако конечно не лишена и недостатков, скорее всего она будет работать далеко не на всех терминалах. Потому что я жестоко определил те возможности, которые терминал должен предоставлять, опираясь на самые популярные терминалы.

Если у кого-то есть интерес к такой штуке, а если более точнее к разработке такой штуки (ну и последующем использовании, ибо либа она не либа, если на ней ничего не написано), welcome в IRC, я есть в IRCNET.RU и на Freenode, ник nsf. Найдете меня, я дам линки и отвечу на вопросы если надо.

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

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.