Вообщем такая беда. Я пишу либу, которая является альтернативой 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