Рейтинг@Mail.ru
[Войти] [Зарегистрироваться]

Наши друзья и партнеры

UnixForum
Беспроводные выключатели nooLite

Lines Club

Ищем достойных соперников.




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

Библиотека сайта или "Мой Linux Documentation Project"


Previos Contents Next

Добавляем новую "старую" раскладку клавиатуры.

Рассмотрим - как добавить еще одну группу с другой расскладкой клавиатуры.

Зачем это может понадобится?

Ну, например, проблема (описанная в "Почему руссификация не работает?") - у вас есть программы, в "бинарниках", статически слинкованные, которые напрочь отказываются понимать коды типа Cyrillic_*. Можно специально для них изготовить раскладку, в которой будут не двубайтные коды русских букв, а однобайтные коды KOI8-R.

Возможно, вам захочется добавить раскладку в кодировке cp1251 или еще какой-нибудь, которая отличается от стандартной расположением русских букв.

(Надо заметить, что этот путь (добавление новой кодировки русских букв с помощью дополнительной группы) - в общем-то, плохое решение. Тем более, если вы не используете новую locale. Правильно было бы - добавить соответствующую таблицу перекодировки в Xlib и изготовить подходящую "иксовую" locale.
Но, как я уже сказал, я не предлагаю правильные решения :-), а только привожу примеры - как это можно сделать.)

Итак, давайте в этом примере сосредоточимся на задаче - добавление "однобайтной koi8-r кодировки" для "старых" или "тупых" клиентских программ.

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

Новую группу надо добавлять не "в конец" (как третью), а "в середину" - так чтобы она была второй, а "правильная" кириллица - третьей.

Почему? Потому, что "традиционные" программы (со старой Xlib) понимают только первую и вторую группу. Причем, вторую выбирают тогда, когда установлен модификатор, соответствующий символу Mode_switch. Ну, об установке модификатора позаботится "таблица" совместимости XKB. Если она у вас стандартная, то соответствующий модификатор будет выставляться для всех групп, кроме первой (то есть, в нашем случае и для "старой" кодировки и для "новой").

А вот искать символы "старые" программы будут всегда только во второй группе (об остальных они даже не подозревают). А "новые" программы, совместимые с XKB и так найдут свою раскладку, будь она во второй, третей, или даже в четвертой группе.

Еще одно замечание. Естественно, добавлять новые символы мы будем в xkb_symbols. При этом будет логично не писать ее "с нуля", а взять за основу уже существующий файл symbols/ru и дополнить его. Если мы наш файл "приплюсуем" к соответствующему описанию xkb_symbols, то у нас получится два фйла описания одних и тех же клавиш, при этом второй полностью переписывает первый.

Поэтому, логично, если мы из описания вообще выкинем "стандартный" файл "ru", а оставим только свой.

То есть соответствующая строчка в нашем "полном описании конфигурации" будет выглядеть не как

xkb_symbols { include "en_US(105)+ru+new-ru" };
а немного короче
xkb_symbols { include "en_US(105)+new-ru" };

Итак. Берем в свою директорию файл symbols/ru и начинаем его "корежить".
Надо заметить, что, скорее всего в нем вы обнаружите три блока -

xkb_symbols "toggle" {...};
xkb_symbols "shift_toggle" {...};
xkb_symbols "basic" {...};

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

Обычно, если у вас в полной конфигурации указан просто файл ru, загружается первый блок. И переключателем "рус/лат" становится клавиша CapsLock.

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

А сейчас я предлагаю просто выкинуть ("вычистить") два первых блока и оставить только блок "basic". А переключатель допишем потом прямо в блок "basic", или "приплюсуем" подходящий блок из файла symbols/group (в нем описано аж шесть разных способов переключения).

Итак. Выкинули два первых блока и начали исправлять/дополнять блок "basic".
Нам нужно для каждой кнопки, которая в описаниях содержит символы Cyrillic, дописать в середину (второй группой) еще одну группу с однобайтными символами в кодировке koi8. Напомню, что символы можно задавать не только символическими именами (типа Cyrillic_*), а просто цифровым кодом. Например, клавишу

key <AB01> {	[		z,		 Z	],
		[     Cyrillic_ya,     Cyrillic_YA	]	};

мы должны описать как
key <AB01> {	[		z,		 Z	],
		[            0xd1,            0xf1	],
		[     Cyrillic_ya,     Cyrillic_YA	]	};
Естественно, первый код соответсвует маленькой букве, а второй - большой.

Как подобрать коды? Ну, во-первых, по названию букв можно догадаться - какую русскую букву они имеют ввиду и, если у вас есть под рукой табличка - какой русской букве, какой код koi8-r соответствует, просто переписать оттуда.

А во-вторых, могу подсказать, что младший байт кода Cyrillic на самом деле соответствует коду этой буквы в koi8, а в старшем байте всегда шестерка.

Поэтому, можно взять файл, в котором описываются числовые значения для кодов типа Cyrillic_* - это файл /usr/X11R6/include/X11/keysymdef.h. И списать соответствующие коды оттуда, отбрасывая первую шестерку.

Особо ленивые могут взять готовый файл здесь.

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

Во-первых, надо заметить, что все варианты переключателей используют для своих целей специальный символ - ISO_Next_Group, а его семантика, описанная в xkb_compat такова, что он просто перебирает все возможные группы. То есть, при нажатии клавиши (или комбинации клавиш) с таким символом просто текущее значение группы увеличивается на единицу, а когда счетчик доходит до последней группы, он просто возвращается на первую (см. "Внутренности":"Методы выравнивания номера группы").

Таким образом тем же самым перключателем "рус/лат" мы можем последовательно перебирать все три группы.

Вы можете выбрать ваш любимый способ переключения из файла symbols/group и "приплюсовать" его к описанию xkb_symbols, например,

xkb_symbols { include "en_US(105)+new_ru+group(shift_toggle)" };

Только одно замечание о переключении клавишей CapsLock.
Дело в том, что традиционно на эту же клавишу "подвешивают" и символ Caps_Lock, чтобы она могла выполнять и свою основную функцию (нажатая с Shift'ом).

Проблема в том, что к этому символу присоединен реальный модификатор Lock. При этом, в конечном счете, XKB привязывает реальные модификаторы не к символу, а к скан-коду клавиши. Поэтому при нажатии этой клавиши в "состоянии модификаторов" появится не только модификатор, который указывает на то, что выбрана альтернативная группа, но и реальный модификатор Lock (хотя вы нажимаете клавишу как ISO_Next_Group, а не как Caps_Lock).

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

Для того, чтобы этого не происходило, надо бы "отцепить" реальный модификатор Lock от этой клавиши. К сожалению, "привязка" модификатора к символу Caps_Lock "зарыта" глубоко в файлах, которые "инклюдятся" в en_US. А отменить это присвоение в дополнительных файлах уже нельзя.

Поэтому, чтобы не "перелопачивать" все файлы, которые неявно включаются в нашу полную конфигурацию, лучше просто убрать символ Caps_Lock из описания клавиши <CAPS>.

Если вам жалко расставаться с этой функцией - "подвесьте" ее на какую-нибудь другую клавишу. А если вы используете для "рус/лат" другой способ - то и описанной проблемы у вас не будет.

Итак. Если ваш любимый способ переключения - клавиша CapsLock, то последнее, что нам надо сделать - не "приплюсовывать" этот способ из файла symbols/group (там эта клавиша с кодом Caps_Lock), а просто вписать в нашу новую раскладку определение для клавиши <CAPS> -

key <CAPS> { [ISO_Next_Group] };

Теперь можно прегрузить конфигурацию программой xkbcomp и посмотреть результат.

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

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

А вот о том, как сделать переключение между тремя (и больше) группами более приятным, мы рассмотрим в следующем примере -

"Вариации на тему" - переключатели "рус/лат" (и еще раз - "рус").


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


Previos Contents Next


Эта статья еще не оценивалась
Вы сможете оценить статью и оставить комментарий, если войдете или зарегистрируетесь.
Только зарегистрированные пользователи могут оценивать и комментировать статьи.

Комментарии отсутствуют