Настройка и работа в Linux
adb5321d

Таблица "совместимости"


Как уже упоминалось, XKB вынужден решать "проблему совместимости" с программами, которые не подозревают о существовании XKB и обращаются с запросами к "core-модулю" X-сервера.

Естественно, модуль XKB может обработать эти запросы, но основная проблема, возникающая при этом, состоит в том, что в модуле XKB вводятся некоторые новые понятия (новые относительно core protocol'а), которые никак не отражены в "традиционных" запросах к клавиатурному модулю.

  • Во-первых, в XKB больше модификаторов и их поведение может гибко перестраиваться. Поэтому, как уже упоминалось, для совместимости модулю XKB приходится поддерживать восемь "традиционных" модификаторов и осуществлять отображение (преобразование) своих модификаторов в "традиционные".
  • Более того. XKB вынужден поддерживать "традиционный" формат "сообщения о нажатии/отпускании" клавиши, в котором передается "состояние" клавиатурного модуля, состоящее из набора реальных модификаторов. Даже если модуль XKB общается с XKB-совместимой Xlib, он вынужден, для передачи ей информации о состоянии своих виртуальных модификаторов, "превращать" их в реальные.
    (Поэтому, кстати, виртуальный модификатор не оказывает никакого эффекта, если он не "отображен" в какой-нибудь реальный).

  • Во-вторых, в core protocol "номер группы" имеет другой смысл. Как уже говорилось - групп всего две, переключаются они символом Mode_Switch и в "состоянии клавиатуры" переключение на "дополнительную" группу отображается одним из модификаторов Mod1-Mod5 - тем, который связан с символом Mode_Switch.
  • Таким образом, в "традиционном" протоколе номер группы отображается одним из модификаторов - "основная группа/альтернативная группа", а в модуле XKB, в "состоянии клавиатуры" явно существует двухбитное поле - "номер группы" (которое, к тому же, не "перекрывается" с набором модификаторов).


    Кроме того, в "традиционном" модуле клавиатуры каждая группа состоит ровно из двух "уровней". Хотя при этом допускается, что каждому скан-коду может быть сопоставлен одномерный массив символов длиной до 256. Первые четыре ячейки в нем соответствуют "двум группам, в каждой по два уровня". Остальные ячейки "клиентская" программа может выбирать сама, в зависимости от состояния модификаторов Mod1-Mod5.
    Поэтому, для совместимости модуль XKB, при общении со "старыми" программами, вынужден ...

    • Во-первых, "размазывать" свои подтаблицы-группы в одну строчку "традиционной" таблицы символов (честно говоря, я так и не понял общий алгоритм этого действия, кроме тривиального случая, когда скан-коду соответствует две группы, каждая из двух уровней).
    • Во-вторых, отображать свой "номер группы" в состояние какого-нибудь "реального" модификатора.

  • Наконец, в core-модуле отсутствуют "действия" - основной механизм, обеспечивающий "гибкость поведения" XKB. В связи с этим возникает проблема - "старая" программа может поменять "привязку" символов к скан-кодам, но, поскольку она не подозревает о том, что к скан-кодам могут быть "привязаны" также и "действия", может возникнуть ситуация, когда такая программа переместить, например, символ "переключатель РУС/ЛАТ" на другую клавишу, а соответствующее "действие" (которое в XKB реально осуществляет это переключение) останется на старом месте.

  • Для решения этой проблемы в XKB хранится таблица "интерпретаций" (interpretation) управляющих символов. Эта таблица связывает коды символов и вызовы соответствующих "действий" (actions). Естественно, в этой таблице присутствуют только специальные "управляющие" символы ( Caps_Lock, Shift, Num_Lock, "переключатель РУС/ЛАТ" и т.п.).
    Кроме самих символов и "действий" в таблице интерпретаций хранится также дополнительная информация - список "реальных модификаторов" и "критерий соответствия" ("любой из модификаторов", "все указанные модификаторы", "только указанные модификаторы" и т.п.).


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

    Содержание раздела