Модуль ввода для Эсперанто

Исходный код: Esperanto filter

В алфавите Эсперанто отсутствуют некоторые буквы латиницы, зато есть шесть букв с диактрическими знаками: пять с циркумфлексом (ĵ, ĥ, ŝ, ĉ и ĝ) и одна с бреве (ŭ). По звучанию и значению буквы с диактрическим знаком, разумеется, отличаются от букв без него; к примеру, если j звучит как «й», то ĵ — это «ж», и если komenciĝis означает «начался» (сам по себе), то komencigis, без циркумфлекса над g, это «был начат кем-то», в страдательном залоге.

В Haiku, конечно, есть поддержка Эсперанто, и есть даже специальная системная раскладка клавиатуры для Эсперанто, которую можно добавить в переключатель раскладок:

Системная клавиатурная раскладка Эсперанто

Стоит ли ради шести букв добавлять ещё одну раскладку, когда у меня их и так уже три (русская, английская и ивритская)? Тем более, что расположены они в самых непредсказуемых местах, и на клавишах не подписаны? Разумеется, нет. Для Windows эта проблема решена уже давно, — существует бесплатная программа Tajpi, которая позволяет добавлять диактрические знаки к буквам, набранным в английской раскладке, достаточно всего лишь набрать после буквы знак «^». Почему бы не сделать такую же утилиту для Haiku?

Так родился input server add-on для простого набора букв Эсперанто.

Input server add-on — это фильтр, через который проходят все сообщения от устройств ввода. Нажатия клавиш клавиатуры, движения мыши, наклоны джойстика и сила давления стилуса передаются в операционную систему через input server в сообщениях, которые входят в единый FIFO-буфер. А add-on имеет доступ к этим сообщениям и может их менять, добавлять новые сообщения в этот буфер или удалять старые.

Я заранее перехватил и сохранил сообщения, которые драйвер клавиатуры посылает при наборе букв с диактрическими знаками, и вдобавок сообщение, соответствующее клавише Backspace. Затем осталось просто набросать конечный автомат: если пришла буква, у которой может быть диактрический знак, переходим в режим ожидания, если затем пришёл знак «^», вносим в очередь два сообщения: сначала — что был нажат Backspace, а затем — что была нажата буква с диактрическим знаком, и переходим в дополнительный режим ожидания. Если снова пришёл знак «^», снова посылаем Backspace, а затем посылаем оригинальное сообщение (букву без диактрического знака).

Вот как это выглядит в использовании:

Пример работы Эсперанто-фильтра

А уж затем я подумал, что можно бы сделать и панель настроек:

Панель настроек Эсперанто-фильтра

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

Самой большой проблемой в окне настроек было создание окна для direct keys, — букв, которые автоматически будут заменяться на буквы с диактрическими знаками. Там одновременно используется и окно ввода текста, и маска, позволяющая вводить только буквы, и только одну, и перевод текста в нижний регистр, и игра с enable/disable в зависимости от галочки, и косая красная черта, если данная буква не используется, и подсветка другого окошка, если юзер по ошибке пытается потребовать от системы переводить одну и ту же букву в две разные буквы Эсперанто. Думаю, три четверти всего кода работают именно с этими полями.

Исходный код: Esperanto filter