Что делать с "неправильными" программами?

Вообще-то, первый ответ - узнайте - не решены ли эти проблемы в последней версии данной программы. Возможно "бороться" уже не надо. И только если проблемы остались, то ...

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

Программы в "исходниках".

Если программы доступны в "исходниках", то их можно исправить. Обычно для этого достаточно вставить вызов setlocale() где нибудь в самом начале программы (и уговорить авторов или maintainer'ов - включить этот вызов в официальный дистрибутив).

Не забудьте при этом о "иксовой заглушке" setlocale().
Если у вас Xlib собрана с X_LOCALE, то ...

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

Естественно, программы использующие эти "тулкиты" лучше исправлять с помощью "родной" подпрограммы настройки locale.

Например. Своя собственная процедура для установки locale в приложении имеется в библиотеке Xt, которая работает "поверх" Xlib и, в свою очередь, является основой для популярных "тулкитов" Xaw* и Motif (lesstif).

Поэтому, как сказано в документации Андрея Чернова (о "коификации" всего и вся):

Если программа использует один из перечисленных "тулкитов" (Xt, Xaw*, Motif/lesstif), то для ее исправления лучше вставить вызов процедуры XtSetLanguageProc, например в таком виде

XtSetLanguageProc(NULL, NULL, NULL);

Также своя процедура имеется и в библиотеке GTK - gtk_set_locale() (без аргументов). Хотя она делает практически то же, что и обычная setlocale(...), но по крайней мере еще и выдает разнообразную диагностику, "если что не так".

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

К сожалению, никаких общих рекомендаций для этого случая я дать не могу. Замечу только, что ...

И наконец, особые проблемы могут возникнуть с "мультиязыковыми" программами ...

Мультиязыковые программы.

Это программы, которые пытаются обеспечить ввод на нескольких языках и, соответственно, ввод символов из нескольких "несовместимых" алфавитов (западноевропейского, русского, греческого и т.п.). Обычно, это - разнообразные редакторы и "текстпроцессоры" (Lyx, emacs и т.п.)

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

Поэтому, многоязыковые программы просто игнорируют однобайтные коды, которые им возвращают процедуры X*LookupString, а используют двубайтные коды клавиш (symbols в терминах XKB) и интерпретируют непосредственно их в меру своего понимания.

К сожалению, далеко не все из этих программ правильно понимаю - что делать с кодами типа Cyrillic_*.

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

К сожалению, общих рецептов и в этом случае нет. Но, с другой стороны, некоторые из таких и программ и не надо "патчить". Им можно объяснить, что "Cyrillic коды" - это обычные "буквенные" коды, с помощью их же файлов конфигурации.

Некоторые решения можно найти ...

Кстати, исправления для популярного "тулкита" Tcl/Tk можно найти на сайте Виктора Вагнера - http://www.ice.ru/~vitus/tcl/locale-tcl.html.

Программы в "бинарниках".

Что делать, если программы имеются только в "бинарниках"?

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

В этом случае, самое правильное - попробовать уговорить авторов на соответствующую правку.

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

Методы "грубого хака".

Первый метод - самый плохой.

Можно "откатиться" к методам, которые использует xmodmap.

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

А чтобы "правильные" программы их не "давили", нужно "испортить" XLC_LOCALE для koi8. Для этого достаточно "закомментарить" (или вообще выкинуть) строчку с encoding_name в файле koi8-r/XLC_LOCALE.

Этот метод будет работать почти со всеми приложениями. Даже со "статически слинкованными бинарниками". Хотя могут возникнуть проблемы с некоторыми мультиязыковыми программами. Но он же, как я уже сказал - самый плохой. По сути, это "возврат к старому". Ради нескольких старых "глупых" программ, придется обманывать все новые "правильные" программы.

Второй метод - намного лучше.

Идея этого метода принадлежит Александру Канавину (хотя реализовал он его немного по-другому).

Поскольку "неправильные" программы, забывая установить нужную locale, используют locale "C", можно им вместо C "подсунуть" русскую locale, например - ru_RU.KOI8-R.

Для этого достаточно в файле "алиасов локалей" (X11R6/lib/X11/locale/locale.alias) добавить строчку

C                        ru_RU.KOI8-R

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

К сожалению, и этот способ неидеальный.

Третий способ - самый правильный.

Еще один способ описан в "Примеры: Новая 'старая' раскладка".
В нем вводятся две русские раскладки - одна для "неправильных" программ, другая - для "правильных".

Эту раскладку можно положить в X11R6/lib/X11/xkb/symbols, переименовав ее в ru (или подправить название русской раскладки в других файлах конфигурации XKB).

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

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


Иван Паскаль [email protected]