В этом файле описывается поведение клавиш модификаторов - какие изменения происходят в состоянии клавиатуры (изменения битов-модификаторов и "номера группы") при нажатии этих клавиш.
Напомню, что внутри XKB существует структура (таблица) - Xkb Compability Map, которая состоит из двух частей
В файле типа xkb_compat могут встречаться объявления
Как и в файле типа xkb_types, прежде всего должны быть объявлены виртуальные модификаторы, которые могут встречаться в дальнейших описаниях. Реальные модификаторы (если они также используются) описывать не надо, поскольку, они имеют стандартные названия. А вот виртуальные модификаторы могут иметь произвольные названия, поэтому, для правильной интерпретации остальных записей необходимо сообщить программе, которая будет "разбирать" этот файл, что соответствующие слова являются названиями виртуальных модификаторов.
Объявление виртуальных модификаторов имеет вид
'virtual_modifiers' список модификаторов ';'Например,
virtual_modifiers NumLock, AltGr ;
Каждая "интерпретация" (interpretation) устанавливает соответствие между кодом какго-нибудь "управляющего" символа (symbol) и "действием" (action), которое должен будет выполнить модуль XKB при нажатии клавиши к которой "привязан" этот символ.
Полностью внутренняя структура, описывающая интерпретацию, состоит из
Естественно, не все эти поля обязательно должны быть заполнены.
Итак, поле "код символа", естественно, определяет символ, к которому "привязывается" "действие", а поле "действие" - само это "действие".
Также, в "интерпретации" могут быть заданы поля "реальные модификаторы" и "критерий соответствия".
Для чего нужны эти поля?
Напомню, что к любому скан-коду может быть "привязан" один или несколько
реальных модификаторов. При поиске подходящего места для "действия",
XKB может использовать не только код символа, но и расположение этих
реальных модификаторов.
Если эти поля НЕ заданы, то XKB, при изменнии "привязки" символа к скан-коду, просто перенесет туда же соответствующее "действие".
А вот если эти поля заданы, то прежде чем выполнить перенос, XKB
сравнивает набор реальных модификаторов, привязанных к скан-коду и
набор реальных модификаторов, указанный в "интерпретации". "Критерий
соответствия" определяет - как сравнивать эти два набора (см. ниже).
Если условие выполняется, "действие" переносится.
Кстати, если используются эти два поля (набор модификаторов и "критерий соответствия"), то кода символа может в интерпретации и не быть.
При этом, поиск подходящего места делается XKB только на сравнении наборов модификаторов. Например - найти тот скан-код, к которому "привязан" реальный модификатор Lock, и перенести туда "действие", независимо от того, какой код символа соответствует этому скан-коду.
Итак. Поле "реальные модификаторы" представляет собой просто один или
несколько битов модификаторов.
А "критерий соответствия" представляет собой одно из условий
Естественно, "по умолчанию" поле модификаторов пустое, а "критерий" - "любой из.. или ни одного".
Поле флагов и виртуальный модификатор (он должен быть только один), могут быть тоже "перенесены" в описание скан-кода, если символ "переносится" в первый уровень первой группы таблицы, привязанной к скан-коду.
Флаги добавляются в поле "поведение клавиши", а модификатор в поле "виртуальные модификаторы" (эти поля есть у каждого описания скан-кода).
"По умолчанию" поле "флаги" содержит флаг "автоповтор", а поле "виртуальный модификатор" - пустое. Итак. Описание "интерпретации" имеет вид
'interpret' символ '{' описание '};'или
'interpret' символ '+' модификатор '{' описание '};'или
'interpret' символ '+' критерий '(' модификаторы ') {' описание '};'Например
interpret Nun_Lock {...}; interpret ISO_Level2 + Shift {...}; interpret ISO_Lock + AnyOf(Lock+shift) {...};
Если в заголовке указан только код символа, критерий - AnyOfOrNone, поле модификаторов - пустое.
Если указан, код символа и название модификатора (не указан "критерий"), то "критерий" - Exactly.
Если указан "критерий", то в скобках вместо списка модификаторов может стоять слово all. Понятно, что это означает - все модификаторы.
Кроме того, вместо "критерия" и списка модификаторов может использоваться слово Any. Это означает - AnyOf(all).
Наконец, как уже говорилось, если есть набор модификаторов и "критерий",
то кода символа может и не быть ("привязка" осуществляется путем сравнения
наборов модификаторов). В этом случае, вместо кода символа также ставится
слово - Any.
Например,
interpret Any + Any {...};означает, что эта "интерпретация" применяется ко всем клавишам, у которых есть реальные модификаторы.
Внутри описания "интерпретации" могут быть строчки типа оператора присваивания
Служит для указания "критерия" LevelOneOnly. Если справа стоит слово "level1" или "levelone", то "критерий" проверяется. Если слова "anylevel" или "any" - игнорируется. Кстати, "по умолчанию" он игнорируется, так что строчки вида
useModMapMods = anylevel;особого смысла не имеют.
Устанавливают значения для флагов "автоповтор" и "залипание".
Справа от присваивания должно быть логическое значение - True или False.
Например,
repeat = True; locking = False;
Указывает виртуальный модификатор. Напомню, что этот модификатор тоже може быть добавлен к описанию скан-кода, если символ переносится в "первый уровень первой группы" таблицы значений для скан-кода.
Справа от присваивания просто указывается название виртуального
модификатора.
Например,
virtualModifier = AltGr;
Описывает "действие". Подробнее об этом читайте
"Описание действий".
Здесь замечу, что "действие" также может быть "пустым".
Если "интерпретация" нужна для того, чтобы перенести не "действие",
а только "флаги" или "виртуальный модификатор", то ее описание
может выглядеть как
interpret ... { repeat = False; locking = True; action = NoAction(); };
Напомню, что в "состоянии XKB" (которое может быть "считано" прикладной программой) есть специальное двухбитное поле, в котором указан текущий номер группы. В "традиционном" "состоянии клавиатуры" такого поля нет, а смена группы индицируется одним из модификаторов.
Поэтому, для программ, понимающих только "традиционное состояние клавиатуры", XKB преобразует номер группы в активное состояние какого-нибудь модификатора.
Для каждого из четырех номеров групп может быть объявлен отдельный модификатор (хотя обычно, используется один для всех групп, отличных от первой).
Это объявление имеет очень простой вид.
'group' номер группы '=' модификатор ';'Например,
group 2 = AltGr;
В файлах типа xkb_compat также описывается "поведение индикаторов", хотя к "таблице совместимости" (compability) они отношения не имеют.
Напомню, что в XKB можно определить до 32 индикаторов. Первые 3-4 (в зависимости от типа клавиатуры) отображаются реальными "лампочками" на клавиатуре, а остальные считаются "виртуальными" и могут отображаться специальными программами.
В файле типа xkb_keycodes индикаторам даются символические имена (связыватся номера индикаторов и "имя индикатора").
А в файле xkb_compat описывается - как эти индикаторы ведут себя
в зависимости от "состояния клавиатуры". Напомню, что...
Во-первых, индикаторы могут отображать состояние
Надо отметить, что один и тот же индикатор может одновременно "отслеживать" изменения и "своего" модификатора, и какого-нибудь номера группы, и управляющего флага (хотя, зачем это нужно?).
Во-вторых, индикатор может не только "отслеживать" состяние XKB, но и включаться/выключаться прикладными программами. При этом, в описании индикатора можно разрешить/запретить такое включение/выключение или установить "обратную связь" (то есть, при включении/выключении индикатора будут происходить соответствующие изменения в состоянии XKB).
Итак. Описание поведения индикатора имеет вид
'indicator' имя_индикатора '{' описание '};'
Здесь "имя_индикатора" - это то символическое имя (строка символов в двойных кавычках), которое было дано ему в файле xkb_keycodes.
А "описание" обычно имеет вид оператора присваивания (исключение - логические переменные-флаги, которые могут принимать значения только True/False).
В этих "описаниях" могут встретиться строчки типа
Определяют - какие компоненты "состояния" должен отслеживать индикатор.
Естественно, справа от знака присваивания должен быть ...
Надо отметить, что номер группы можно задавать
Поскольку набор модификаторов и номер группы "размазаны" по трем переменным (base, locked, latched), эти инструкции уточняют - в каких переменных надо отслеживать модификаторы и номер группы, соответственно.
Справа от присваивания может быть слово
Логический флаг, который разрешает (запрещает) прикладным программам включать/выключать индикатор. Обратите внимание, конечно, для включения/выключения индикатора прикладная программа посылает специальные запросы к XKB. Но XKB по этим командам только меняет (если это разрешено) только состояние индикатора, не затрагивая свое "состояние". Естественно, при этом состояние индикатор может не соответствовать состоянию XKB.
Поскольку allowExplicit является логической переменной, справа от присваивания должно быть только True или False.
Можно также использовать другую форму этой инструкции. Так, просто указание
allowExplicit;эквивалентно
allowExplicit = True;а строчка
!allowExplicit;эквивалентна
allowExplicit = False;По умолчанию этот "флажок" - True. То есть, прикладным программам разрешено менять состяние индикатора, помимо "состояния клавиатуры".
Имеет много синонимов - drivesKbd, ledDrivesKbd, ledDrivesKkeyboard, indicatorDrivesKbd, indicatorDrivesKeyboard.
Это тоже логический флаг, который заставляет XKB устанавливать "обратную связь" между индикатором и "состянием клавиатуры". То есть, если это флаг "взведен" (и разрешено allowExplicit), то, при изменении прикладной программой состяния индикатора, XKB должен изменить и связанные с ним компоненты "состяния клавиатуры".
Обратите внимание, что
При этом, если "which...state" - none, base или any, никакого эффекта не будет. А effective эквивалентно locked. Напомню, что по умолчанию подразумевается значение effective, следовательно - если инструкций вида "which...state" в описании нет, то изменения будут делаться в locked Group или locked Modifiers, соответственно.
Как и в случае с флагом allowExplicit, объявление drivesKeyboard должно иметь вид
drivesKeyboard = True; ( эквивалент - drivesKeyboard;)или
drivesKeyboard = False; ( эквивалент - !drivesKeyboard;)
Позволяет указать номер индикатора (физического или виртуально). Вообще-то, номер индикатора связывается с "именем индикатора" в файле типа xkb_keycodes. Но можно указать его явно здесь.
Это объявление является воспомогательным и позволяет определить какое-нибудь поле (инструкцию) для всех записей типа interpret или indicator. Естественно, обычно эти объявления помещаются в начале файла (или блока в файле).
Они меют вид оператора присваивания, где в левой части указывается
конструкция типа "поля структуры" в языке C.
Например,
indicator.allowExplicit = False;что означает - во всех дальнейших описаниях индикаторов (indicator) подразумевается "allowExplicit = False;", если конечно, эта инструкция не указана явно.
Первым словом в левой части (то, что до точки) должно быть
Иван Паскаль [email protected]