⌨️UVftdanEvdevremap

evdevremap — попытка реализовать софтину для выполнения раскладок (и других преобразований событий устройств ввода) на уровне evdev (возможно реализовать адаптации под ОС, не использующие данный механизм). Мысли для себя я накидываю в гугл док. Комментировать можно тут, в гугл доке или в чатах сообщества клававики (в которых я есть). Данный проект похож на NOMK.

Составляющие исполняемые файлы

  • Исполнитель — демон, предположительно написанный на низкоуровневом языке (C), считывающий бинарное описание раскладки, перехватывающий и генерирующий события

  • Компилятор — утилита, на высокоуровневом языке (Python, Java, возможно с использованием ANTLR или другого компилятора компиляторов), преобразует правила с человекочитаемого языка в удобный для низкоуровневой программы бинарный файл

Источники вдохновения

Vim

Имеет режимы (к сожалению, захардкожены) + маппинг одних последовательностей нажатий в другие (предположительно, тьюринг полный, см. Нормальный алгоритм Маркова).

Xkb

Стандартный инструмент для задания раскладок в X11, имеет много ограничений, напр. около 255 кодов клавиш, очень малое количество из которох не распределены и подходят для внутреннего использования.

Требования

Тьюринг-полнота

Нужна для возможности задать произвольные правила.

Желательно, не должна быть императивной. Вариация Нормального алгоритма Маркова должна подойти.

Режимы (слои)

Могут быть реализованы без специального механизма (сохранять префикс из одного/нескольких токенов), но это не удобно.

Должна быть возможность применить несколько преобразований из разных режимов по очереди. Предлагается представить раскладку как граф, по рёбрам которого движутся события, узлы которого выполняют различные действия (направляют их на разные выходы, меняют своё внутреннее состояние, заменяют последовательности). Нужно продумать такую реализацию, в которой будет гарантироваться порядок исполнения (режимы должны переключаться до обработки последующих событий).

Позже я наткнулся на этот язык, работающий по похожим принципам (такое представление на плоскости нам не нужно):

Типы данных

(under construction)

  • EventCode — одно или два числа (минимум по 16 бит) (одно из них является идентификатором узла графа, чтобы поддерживать локальную для узлов нумерацию и обрабатывать события в соответствии с источником).

  • Modifier — одно натуральное число. Описывает один модификатор (Shift, Alt, ...) или другой булев аттрибут, который нужно передавать вместе с кодом события для внутренней логики. В конце модификаторы должны быть преобразованы в отдельные события зажатия и отпускания клавиши-модификатора.

  • Event — структура: EventCode, Set<Modifier>, int ttl, number value, long creation_time

    • ttl нужен, чтобы предотвратить зацикливания, но не должен доходить до нуля в данной раскладке, если она корректно написана

    • value используется для вычислений и для хранения такой информации, как смещение мыши и состояние клавиши (при преобразовании из формата evdev и обратно)

    • creation_time не содержит настоящего времени, а служит для сортировки событий по времени создания (граница целочисленного переполнения постепенно сдвигается из предположения, что не хранится событий старше 263)