Настройка XKB.

При старте X-сервера, модуль XKB зачитывает все необходимые данные из текстовых файлов, которые образуют "базу данных" настроек XKB.

Строго говоря, большинство из этих файлов сам модуль XKB не читает. Он вызывает программу xkbcomp, которая переводит содержимое этих файлов в двоичный формат, понятный непосредственно модулю XKB.

Но для настройки это не так уж важно, поскольку вызов xkbcomp происходит автоматически, незаметно для пользователя.

База данных, необходимых XKB, состоит из 5 компонентов

keycodes
таблицы, которые просто задают символические имена для скан-кодов.
Например
<TLDE>= 49;
<AE01> = 10;
types
описывает типы клавиш. Тип клавиши определяет - как должно меняться значение, выдаваемое клавишей в зависимости от модификаторов (Control, Shift и т.п.). Так, например, "буквенные" клавиши относятся к типу ALPHABETIC, что означает, что они имеют разное значение в зависимости от состояния Shift и CapsLock. А клавиша [Enter] имеет тип - ONE_LEVEL, что означает, что ее значение всегда одно и то же, независимо от состояния модификаторов.
compat (сокращенное от compability)
описывает "поведение" модификаторов. В XKB имеется несколько внутренних переменных, которые, в конечном счете, и определяют - какой символ будет генерироваться при нажатии клавиши в конкретной ситуации. Так вот, в compat как-раз описывается - как должны меняться эти переменные при нажатии различных клавиш-модификаторов. В этом же разделе обычно описывается и поведение "лампочек"-индикаторов на клавиатуре.
symbols
таблицы, в которых для каждого скан-кода (имени скан-кода, определенного в keycodes) перечисляются все значения (symbols), которые должна выдавать клавиша. Естественно, количество различных значений зависит от типа клавиши (котрые описываются в types), а какое именно значение будет выдано в конкретной ситуации, определяется состоянием модификаторов и их "поведением" (которое описывается в compat)
geometry
описывает "геометрию" клавиатуры - то есть расположение клавиш на клавиатуре. Эти описания нужны не столько самому X-серверу, сколько прикладным программам, которые рисуют изображение клавиатуры.

Все эти компоненты разложены по одноименным директориям в директории {XROOT}/lib/X11/xkb (в дальнейшем, я буду обозначать ее {XKBROOT}).

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

   тип_компонента "имя_блока" {........};

Поэтому, для того, чтобы выбрать конкретную настройку, ее обычно указывают в виде
имя_файла(имя_блока)
например,
us(pc104)

В тоже время, обычно один из блоков в файле (не обязательно самый первый) помечается флагом default, например

        xkb_symbols "pc101" {...};
default xkb_symbols "pc101euro" {...};
        xkb_symbols "pc102" {...};
        xkb_symbols "pc102euro" {...};

Это означает, что если указать только имя файла, то будет выбран именно этот блок.

Три способа задания полной конфигурации XKB.

Весь набор компонентов, необходимых для настройки XKB, описывается в файле конфигурации X-сервера в секции Keyboard.

Первый способ.

Первый способ задания конфигурации заключается в том, что вы можете указать непосредственно каждый из компонентов, например

XkbKeycodes	"xfree86"
XkbTypes	"default"
XkbCompat	"default"
XkbSymbols	"us(pc104)"
XkbGeometry	"pc(pc104)"

Как легко догадаться, это означает, что

Надо заметить, что в любом блоке (в любых компонентах) может встретиться инструкция

include "имя_файла(имя_блока)" (естественно, имя_блока может отсутствовать)

что, как нетрудно догадаться, означает, что в текущий блок должно быть вставлено другое описание из указанного файла (указанного блока).

Поэтому полное описание может неявно включать в себя данные из многих других файлов, кроме тех, которые вы явно укажете в файле конфигурации X-сервера.

Второй способ.

Второй способ заключается в том, что вы можете указать одной инструкцией сразу полный набор настроек. Такие наборы называются keymaps и, также как и обычные компоненты конфигурации XKB, располагаются в отдельных файлах (которые, тоже содержат в себе несколько именованных блоков) в директории {XKBROOT}/keymap.

Обычно, каждом блоке keymap просто указывается - из каких файлов XKB должен извлечь соответствующие компоненты (хотя, в принципе, там может быть и полное описание всех компонентов), например

xkb_keymap "ru"	{
    xkb_keycodes	{ include "xfree86"		};
    xkb_types		{ include "default"		};
    xkb_compatibility	{ include "default"		};
    xkb_symbols		{ include "en_US(pc105)+ru"	};
    xkb_geometry 	{ include "pc(pc102)"		};
};
Обратите внимание, что в одной инструкции include может быть указано несколько файлов (блоков) через знак "+". Понятно, что это означает, что должны быть вставлены последовательно все указанные файлы.

Таким образом, в файле конфигурации X-сервера можно вместо пяти компонентов указать сразу один их готовых наборов - keymap'ов, например

XkbKeymap	"xfree86(ru)"
Кроме того, эти два способа можно комбинировать. Например, если вы выбрали одну из подходящих keymap, но вас не устраивает один из компонентов, например geometry, то в файле конфигурации можно указать
XkbKeymap	"xfree86(ru)"
XkbGeometry	"pc(pc104)"

При этом, в соответствии с первой инструкцией, все компоненты будут взяты из keymap "xfree86(ru)", а вторая инструкция "перепишет" geometry, не затрагивая остальные компоненты (хотя я в этом не уверен :)

Третий способ.

И, наконец, третий способ. Он несколько отличается от предыдущих.

Набор настроек можно указывать не перечислением компонентов, а с помощью задания "правил" (Rules), "модели" (Model), "схемы" (Layout), "варианта" (Variant) и "опций" (Option). В этом наборе только Rules представляют собой некий файл, в котором находится таблица правил - "как выбрать все пять компонентов настроек XKB в зависимости от значений Model, Layout и т.д.".

Все остальные параметры представляют собой просто "ключевые слова" по которым в таблицах "правил" ищутся подходящие файлы настроек (keycodes, types, compat, symbols и geometry). Естественно, искать будет сам модуль XKB при старте.

Другими словами, Rules определяет некоторую функцию, аргументами которой являются Model, Layout, Variant и Options, а значение, которое возвращает эта функция представляет собой полный набор из компонентов настроек XKB - keycodes, types, compat, symbols и geometry (или полная keymap).

Если рассмотреть какой-нибудь файл rules (эти файлы тоже находятся в {XKBROOT} в поддиректории rules), то можно заметить, что в них есть строчки, начинающиеся со знака "!". Это "шаблоны", которые описывают - как интерпретировать следующие за ними строчки "правил".

Например, "шаблон"

! model = keycodes	geometry
говорит о том, что в следующих строках описываются правила - как по имени "модели" XKB должен выбрать файлы keycodes и geometry. Например,
pc104 = xfree86 pc(pc104)
надо понимать так, что если значение аргумента Model - слово "pc104", то keycodes надо взять из файла {XKBROOT}/keycodes/xfree86, а geometry - из файла {XKBROOT}/geometry/pc, блок с именем "pc104".
А, например, "шаблон"
! model	layout	=	symbols
говорит о том, что следующие за ним правила описывают - как по названию "модели" и "схемы" выбрать файл (и блок), с нужными symbols.

Рассматривая файл rules можно заметить, что в нем также есть строчки с wildcards - знаком "*". То есть, в качестве аргументов можно использовать не только те слова, которые встречаются в "правилах". Если программа не найдет указанные вами слова в левой части правила, то все равно подберет какие-нибудь названия для файлов - компонентов настройки.
Например, правило

! model	layout	=	symbols
....
   *	  *	=	en_US(pc102)+%l%(v)
означает, что если указанные вами Model и Layout не были найдены в предыдущих правилах, то в качестве symbols надо взять блок pc102 из файла en_US, и добавить к нему блок, название которого задано параметром Variant из файла, название которого задано аргументом Layout. (Таким образом, в некоторых случаях, некоторые из параметров могут являться и названиями файлов или блоков. Но в общем случае это все-таки просто "ключевые слова").

Можно также заметить, что...
Во-первых, не все параметры обязательно задавать для выбора всех компонентов. Обычно достаточно указать Model и Layout (ну и, естественно, Rules), а Variant и Options нужны только в некоторых случаях.
А во-вторых, что

Кстати, заметьте также, что хотя Options как правило состоят из двух слов, разделенных двоеточием, это не означает, что вы можете самостоятельно комбинировать левую и правую часть (двоеточие в данном случае просто делает их более понятными). Так, например, в rules есть правила для значений Options "grp:toggle" и "ctrl:ctrl_aa". Но если вы попробуете "сконструировать" что-то типа "ctrl:toggle", ничего хорошего из этого не получится, поскольку такого слова в правилах нет.

Итак, если вы используете третий способ указания конфигурации XKB, то в файле конфигурации X-сервера, надо задать параметры XkbRules, XkbModel, XkbLayout и, если вам нужно что-то не совсем стандартное - XkbVariant и XkbOptions.
Например,

XkbRules	"xfree86"
XkbModel	"pc104"
XkbLayout	"ru"
XkbVariant	""
XkbOptions	"ctrl:ctrl_ac"
означает, что XKB должен

Кстати, что означают различные опции, а также - какие "модели" и "схемы" определены в "правилах" (и что они означают) можно посмотреть в файле xfree86.lst (или другом файле *.lst, если вы выбрали "правила" не xfree86), который находится в той же директории, что и файл "правил", то есть - {XKBROOT}/rules.

Несколько практических рекомендаций.

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

Но, если вы захотите вписать эти строчки самостоятельно, могу дать несколько советов.

Прежде всего, надо сказать, что "ключевыми словами" в этих настройках будут

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

Итак. Начнем со второго способа - полная keymap. В файлах конфигурации есть набор "полных keymap'ов" для архитектуры xfree86, отличающися "языком". Все они лежат в файле xfree86, а название блока внутри файла отражает название "языка" (точнее - алфавита) - xfree86(us), xfree86(fr), xfree86(ru) и т.д. Полный список keymap'ов можно посмотреть в файле {XKBROOT}/keymap.dir.

Для "руссифицированной" клавиатуры вполне подойдет

XkbKeymap	"xfree86(ru)"

Если вы выбираете третий способ - через "правила", "модель", "схему" и т.д.

Как я уже говорил,

Поэтому, подходящая конфигурация будет выглядеть примерно так -
XkbRules	"xfree86"
XkbModel	"pc104"
XkbLayout	"ru"
С помощью XkbOptions можно подобрать "поведение" управляющих клавиш. Возможные значения XkbOptions и их смысл можно подсмотреть в файле {XKBROOT}/rules/xfree86.lst.

И, наконец, первый способ - описание отдельных компонентов настройки (keycodes, compat, types, symbols, geometry).

Если вы не знаете с чего начать, подсмотрите соответствующий набор в keymap. Или попробуйте "вычислить" его "вручную" через rules/model/layout. (Подробнее об этом можно прочитать в "Примеры: Где будем экспериментировать?")

Могу посоветовать

А вот на symbols обратите особое внимание. Файл symbols/ru описывает только "буквенные" клавиши. Если вы укажете только его, то у вас не будут работать все остальные кнопки (включая Enter, Shift/Ctrl/Alt, F1-F12 и т.д.).

Поэтому symbols должен состоять по крайней мере из двух файлов - en_US(pc101) (в скобках - тип клавиатуры) и, собственно, ru.
Полный список symbols в файле {XKBROOT}/symbols.dir.

Итак. Для первого метода список может выглядеть так -

XkbKeycodes	"xfree86"
XkbTypes	"complete"
XkbCompat	"complete"
XkbSymbols	"en_US(pc101)+ru"
XkbGeometry	"pc(pc101)"
Если вам хочется дополнительные изменения "поведения" управляющих клавиш (то, что в третьем методе задается XkbOptions), то подсмотрите подходящую "добавку" в {XKBROOT}/rules/xfree86.lst и "приплюсуйте" ее в строчку XkbSymbols. Например,
XkbSymbols	"en_US(pc101)+ru+group(shift_toggle)+ctrl(ctrl_ac)"

Иван Паскаль pascal@tsu.ru