Настройка и работа в Linux
adb5321d

Процедуры Xlib для преобразования кодов


Для такого преобразования в Xlib существует две процедуры - XLookupString

и XmbLookupString (mb означает - "multi byte"). В качестве аргумента этим подпрограммам передается "сообщение о нажатии" (или отпускании) клавиши (Key Press Event), а "на выходе" должен получаться однобайтный код символа.
(Строго говоря, есть еще одна аналогичная процедура - XwcLookupString

(wc означает - "wide char"). Но она используется крайне редко.)

Надо отметить, что в большинстве современных программ выбор конкретной процедуры происходит следующим образом.

Процедура XLookupString более "древняя" и более "глупая". Процедура XmbLookupString более сложная и более гибкая, но в своей работе пользуется "input context'ом" текущего "окна". Не вдаваясь в подробности, можно сказать, что "input context" - это некий объект, описывающий особенности ввода (input) в "свое окно", и содержащий список "методов" для различных преобразований входных цепочек символов.

Поэтому, большинство "иксовых" программ пытаются создать для своих "окон" input context. И, если им это удается, используют XmbLookupString, а если по каким-то причинам input context не может быть создан, то используют XLookupString.

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

Если вы не знаете - что такое locale, могу порекомендовать сайт - "Locale AS IS", где это об этом рассказано достаточно подробно (и по русски!).

Здесь замечу только, что ...

  • программы обычно узнают о текущей locale из "переменных окружения" (environment) LANG, или LC_ALL, LC_CTYPE и т.п.;
  • для каждой locale в системе существует набор файлов, в которых содержится вся информация "зависящая от языка" (и, соответствено - алфавита);
  • в системе X-Window (а ее можно рассматривать как отдельную ОС), основными файлами, описывающим "категории locale" является файлы XLC_LOCALE, разложенные по отдельным поддиректориям в директории X11R6/lib/X11/locale. Каждая поддиректория соответствует одной конкретной locale.
  • процедуры Xlib в своей работе используют некоторые значения (какие именно - рассмотрим чуть позже), описанные в файле XLC_LOCALE.


Кроме того надо заметить, что не бывает "никакой locale". Если locale не задана "переменными окружения" или задана, но такая, что система затрудняется найти нужные файлы, то будет использоваться locale - "C".

Так вот. При старте программа должна установить нужную locale (ниже мы поговорим об этом немного подробнее). Библиотека Xlib найдет соответствующий файл, описывающий эту locale. Процедуры *LookupString по этому описанию будут принимать решение - как преобразовать двубайтные коды (в нашем случае - Cyrillic коды) в однобайтные символы.

Если заглянуть немного глубже в работу этих процедур, то можно заметить, что


  • обе процедуры ориентируются на параметр locale (точнее, он назывется - класс) - encoding_name;
  • значение этого класса (для работы с Cyrillic) должно быть KOI8-R или ISO8859-5;
  • в зависимости от значения этого класса...


  • если он KOI8-R - Cyrillic превращаются в однобайтные коды koi8-r


  • если ISO8859-5 - Cyrillic превращаются в коды iso8859-5
  • если ни то ни другое - Cyrillic вообще ни во что не преобразуется. То есть "на выход" выдается строчка нулевой длины. Это и выглядит как "русские буквы не вводятся".


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

Кстати, если locale "никакая" (то есть - C), или encoding_name не определен, то нормально вводятся коды "национальных алфавитов Западной Европы", которые занимают то же место в кодовой таблице, что и koi8-r. А если нормально преобразуются коды Cyrillic, то наоборот - "подавляется" ввод "западноевропейских" символов.

Кроме того, есть отличия в работе двух *LookupString.


  • XLookupString прежде всего пытается взять encoding_name из "переменной окружения" _XKB_CHARSET. Если такая переменная есть, то используется ее значение и locale устанавливать не нужно.
  • XmbLookupString, напротив, не только обязательно требует правильной locale, но и еще использует в своей работе значение двух классов - encoding_name и ct_encoding (ct - "compaund text"). Поэтому, для ее нормальной работы, значения этих двух классов должно совпадать (по крайней мере - для "кириллицы").



Содержание раздела