Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net


Previos Contents Next

Файл, типа xkb_compat.

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

Напомню, что внутри XKB существует структура (таблица) - Xkb Compability Map, которая состоит из двух частей

  • набора (массива) "интерпретаций" (interpret)
  • четырех переменных, которые определяют - какие "реальные" модификаторы (модификаторы "традиционного" клаватурного модуля X-сервера) будут отображать изменение "номера группы".
Если прикладные программы обращаются к X-серверу не специальными XKB-запросами, а запросами к "традиционному" клавиатурному модулю X-сервера, которые должны поменять "привязку" кодов символов (или реальных модификаторов) к скан-кодам, то модуль XKB, выполнив требуемый перенос, пытается также пренести и "действия", "привязанные" к скан-кодам (и некоторые другие параметры клавиши).
Для выполнения такого "переноса" и используется 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

Служит для указания "критерия" 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" "размазаны" по трем переменным (base, locked, latched), поведение индикаторы можно связать с любой из указанных переменных или с их "эффективным" (суммарным) значением.

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

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

Итак. Описание поведения индикатора имеет вид

'indicator' имя_индикатора '{' описание  '};'

Здесь "имя_индикатора" - это то символическое имя (строка символов в двойных кавычках), которое было дано ему в файле xkb_keycodes.

А "описание" обычно имеет вид оператора присваивания (исключение - логические переменные-флаги, которые могут принимать значения только True/False).

В этих "описаниях" могут встретиться строчки типа

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 - "ни в каком"; особого смысла не имеет, поскольку при этом просто не отслеживаются модификаторы и/или номер группы.
По умолчанию (то есть, если which...State явно не указаны) подразумевается effective.

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