Библиотека сайта rus-linux.net
Previos | Contents | Next |
Файл, типа xkb_compat.
В этом файле описывается поведение клавиш модификаторов - какие изменения происходят в состоянии клавиатуры (изменения битов-модификаторов и "номера группы") при нажатии этих клавиш.
Напомню, что внутри XKB существует структура (таблица) - Xkb Compability Map, которая состоит из двух частей
- набора (массива) "интерпретаций" (interpret)
- четырех переменных, которые определяют - какие "реальные" модификаторы (модификаторы "традиционного" клаватурного модуля X-сервера) будут отображать изменение "номера группы".
Для выполнения такого "переноса" и используется Xkb Compability Map.
В файле типа xkb_compat могут встречаться объявления
- Объявление виртуальных модификаторов.
- Описание "интерпретации".
- Объявление "отображения номера группы в модификатор".
- Описание поведения индикатора.
- Объявление "умолчания".
Объявление виртуальных модификаторов.
Как и в файле типа xkb_types, прежде всего должны быть объявлены виртуальные модификаторы, которые могут встречаться в дальнейших описаниях. Реальные модификаторы (если они также используются) описывать не надо, поскольку, они имеют стандартные названия. А вот виртуальные модификаторы могут иметь произвольные названия, поэтому, для правильной интерпретации остальных записей необходимо сообщить программе, которая будет "разбирать" этот файл, что соответствующие слова являются названиями виртуальных модификаторов.
Объявление виртуальных модификаторов имеет вид
'virtual_modifiers' список модификаторов ';'Например,
virtual_modifiers NumLock, AltGr ;
Описание "интерпретации".
Каждая "интерпретация" (interpretation) устанавливает соответствие между кодом какго-нибудь "управляющего" символа (symbol) и "действием" (action), которое должен будет выполнить модуль XKB при нажатии клавиши к которой "привязан" этот символ.
Полностью внутренняя структура, описывающая интерпретацию, состоит из
- кода символа
- "действия"
- набора реальных модификаторов
- "критерия соответствия" модификаторам
- флагов ("автоповтор" и "залипание")
- виртуального модификатора для клавиши
Естественно, не все эти поля обязательно должны быть заполнены.
Итак, поле "код символа", естественно, определяет символ, к которому "привязывается" "действие", а поле "действие" - само это "действие".
Также, в "интерпретации" могут быть заданы поля "реальные модификаторы" и "критерий соответствия".
Для чего нужны эти поля?
Напомню, что к любому скан-коду может быть "привязан" один или несколько
реальных модификаторов. При поиске подходящего места для "действия",
XKB может использовать не только код символа, но и расположение этих
реальных модификаторов.
Если эти поля НЕ заданы, то XKB, при изменнии "привязки" символа к скан-коду, просто перенесет туда же соответствующее "действие".
А вот если эти поля заданы, то прежде чем выполнить перенос, XKB
сравнивает набор реальных модификаторов, привязанных к скан-коду и
набор реальных модификаторов, указанный в "интерпретации". "Критерий
соответствия" определяет - как сравнивать эти два набора (см. ниже).
Если условие выполняется, "действие" переносится.
Кстати, если используются эти два поля (набор модификаторов и "критерий соответствия"), то кода символа может в интерпретации и не быть.
При этом, поиск подходящего места делается XKB только на сравнении наборов модификаторов. Например - найти тот скан-код, к которому "привязан" реальный модификатор Lock, и перенести туда "действие", независимо от того, какой код символа соответствует этому скан-коду.
Итак. Поле "реальные модификаторы" представляет собой просто один или
несколько битов модификаторов.
А "критерий соответствия" представляет собой одно из условий
- AnyOfOrNone (любой из... или ни одного) - практически означает, что поле "модификаторов" не имеет никагого смысла, условие выполняется, если совпадает любой из модификаторов или никакой;
- NoneOf (ни один из...) - у скан-кода не должно быть ни одного из указанных модификаторов;
- AnyOf (любой из...) - у скан-кода должен быть хотя бы один из указанных модификаторов;
- AllOf (все из...) - должны совпасть все указанные модификаторы;
- Exactly (точно) - то же, что и AllOf, но при этом у скан-кода не должно быть ни одного модификатора, не попавшего в список.
- LevelOneOnly (только первый уровень) - условие выполняется, если символ привязывается к первому уровню первой группы в соответствующем скан-коде. Выполнение этого условия также требуется, для переноса "флагов" и "виртуального модификатора".
Естественно, "по умолчанию" поле модификаторов пустое, а "критерий" - "любой из.. или ни одного".
Поле флагов и виртуальный модификатор (он должен быть только один), могут быть тоже "перенесены" в описание скан-кода, если символ "переносится" в первый уровень первой группы таблицы, привязанной к скан-коду.
Флаги добавляются в поле "поведение клавиши", а модификатор в поле "виртуальные модификаторы" (эти поля есть у каждого описания скан-кода).
"По умолчанию" поле "флаги" содержит флаг "автоповтор", а поле "виртуальный модификатор" - пустое. Итак. Описание "интерпретации" имеет вид
'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 {...};означает, что эта "интерпретация" применяется ко всем клавишам, у которых есть реальные модификаторы.
Внутри описания "интерпретации" могут быть строчки типа оператора присваивания
- useModMapMods = ...; или useModMap = ...;
- repeat = ...;
- locking = ...;
- virtualModifier = ...; или virtualMod = ...;
- action = ...;
useModMapMods
Служит для указания "критерия" LevelOneOnly. Если справа стоит слово "level1" или "levelone", то "критерий" проверяется. Если слова "anylevel" или "any" - игнорируется. Кстати, "по умолчанию" он игнорируется, так что строчки вида
useModMapMods = anylevel;особого смысла не имеют.
repeat и locking
Устанавливают значения для флагов "автоповтор" и "залипание".
Справа от присваивания должно быть логическое значение - True или False.
Например,
repeat = True; locking = False;
virtualModifier
Указывает виртуальный модификатор. Напомню, что этот модификатор тоже може быть добавлен к описанию скан-кода, если символ переносится в "первый уровень первой группы" таблицы значений для скан-кода.
Справа от присваивания просто указывается название виртуального
модификатора.
Например,
virtualModifier = AltGr;
action
Описывает "действие". Подробнее об этом читайте
"Описание действий".
Здесь замечу, что "действие" также может быть "пустым".
Если "интерпретация" нужна для того, чтобы перенести не "действие",
а только "флаги" или "виртуальный модификатор", то ее описание
может выглядеть как
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).
В этих "описаниях" могут встретиться строчки типа
- modifiers = ...; или mods = ...;
- groups = ...;
- controls = ...; или ctrls = ...;
- whichModState = ...; или whichModifierState = ...;
- whichGroupState = ...;
- allowExplicit = ...;
- drivesKeyboard = ...; (имеет кучу "синонимов", см. ниже)
- index = ...;
modifiers, groups и controls
Определяют - какие компоненты "состояния" должен отслеживать индикатор.
Естественно, справа от знака присваивания должен быть ...
- для modifiers - название модификатора или нескольких модификаторов через знак "+";
- для groups - номера групп;
- для controls - название "управляющего флага" (флагов).
Надо отметить, что номер группы можно задавать
- просто числовым значением
- в виде - group1, group2 и т.п.;
- можно использовать слова "none" (0) и "all" (0xFF);
- и, наконец, с помощью простых арифметических выражений, например, All-1 ("все, кроме первой")
whichModState и whichGroupState
Поскольку набор модификаторов и номер группы "размазаны" по трем переменным (base, locked, latched), эти инструкции уточняют - в каких переменных надо отслеживать модификаторы и номер группы, соответственно.
Справа от присваивания может быть слово
- base - отслеживать изменение в переменных base (base Group или base Modifiers, соответственно)
- locked - то же самое, в переменных locked
- latched - то же самое, в переменных latched
- effective - отслеживать изменения "эффективных" номера групп или модификаторов (то есть в суммарных значениях всех трех переменных)
- any - отслеживать изменения во всех трех переменных (то есть, индикатор будет включаться/выключаться, если указанное значение модификатора или группы будет меняться в любой из трех переменных); надо заметить, что для модификаторов (whichModState) это значение эквивалентно effective, поскольку "включение" модификатора в любой из трех переменных, неизбежно "включит" его и в "эффективном" наборе модификаторов;
- none - "ни в каком"; особого смысла не имеет, поскольку при этом просто не отслеживаются модификаторы и/или номер группы.
allowExplicit
Логический флаг, который разрешает (запрещает) прикладным программам включать/выключать индикатор. Обратите внимание, конечно, для включения/выключения индикатора прикладная программа посылает специальные запросы к XKB. Но XKB по этим командам только меняет (если это разрешено) только состояние индикатора, не затрагивая свое "состояние". Естественно, при этом состояние индикатор может не соответствовать состоянию XKB.
Поскольку allowExplicit является логической переменной, справа от присваивания должно быть только True или False.
Можно также использовать другую форму этой инструкции. Так, просто указание
allowExplicit;эквивалентно
allowExplicit = True;а строчка
!allowExplicit;эквивалентна
allowExplicit = False;По умолчанию этот "флажок" - True. То есть, прикладным программам разрешено менять состяние индикатора, помимо "состояния клавиатуры".
drivesKeyboard
Имеет много синонимов - drivesKbd, ledDrivesKbd, ledDrivesKkeyboard, indicatorDrivesKbd, indicatorDrivesKeyboard.
Это тоже логический флаг, который заставляет XKB устанавливать "обратную связь" между индикатором и "состянием клавиатуры". То есть, если это флаг "взведен" (и разрешено allowExplicit), то, при изменении прикладной программой состяния индикатора, XKB должен изменить и связанные с ним компоненты "состяния клавиатуры".
Обратите внимание, что
- меняться должны те компонеты, которые заданы инструкциями modifiers, group и controls (обычно задан только один из компонентов);
- инструкции whichModState и whichGroupState указывают - в каких из трех переменных (base, locked, latched) следует поменять модификатор или группу.
При этом, если "which...state" - none, base или any, никакого эффекта не будет. А effective эквивалентно locked. Напомню, что по умолчанию подразумевается значение effective, следовательно - если инструкций вида "which...state" в описании нет, то изменения будут делаться в locked Group или locked Modifiers, соответственно.
Как и в случае с флагом allowExplicit, объявление drivesKeyboard должно иметь вид
drivesKeyboard = True; ( эквивалент - drivesKeyboard;)или
drivesKeyboard = False; ( эквивалент - !drivesKeyboard;)
index
Позволяет указать номер индикатора (физического или виртуально). Вообще-то, номер индикатора связывается с "именем индикатора" в файле типа xkb_keycodes. Но можно указать его явно здесь.
Объявление "умолчания".
Это объявление является воспомогательным и позволяет определить какое-нибудь поле (инструкцию) для всех записей типа interpret или indicator. Естественно, обычно эти объявления помещаются в начале файла (или блока в файле).
Они меют вид оператора присваивания, где в левой части указывается
конструкция типа "поля структуры" в языке C.
Например,
indicator.allowExplicit = False;что означает - во всех дальнейших описаниях индикаторов (indicator) подразумевается "allowExplicit = False;", если конечно, эта инструкция не указана явно.
Первым словом в левой части (то, что до точки) должно быть
- interpret - "умолчания" для описания "интерпретаций";
- indicator - "умолчания" для описания индикаторов;
- название "действия", встречающегося в описаниях interpret - задает "умолчание" для соответствующих полей "действия", которое может встретиться в дальнейших описаниях "интерпретаций".
Иван Паскаль pascal@tsu.ru
Previos | Contents | Next |