Решил сделать так, чтобы терминал (gnome-terminal), когда открывается, ставил себя в режим кодировки cp1251 по умолчанию.
А то он по умолчанию выбирает кодировку текущей локали, которая у меня вообще что-то дико-дифолтное. Пытаюсь выставить нужный LC_CTYPE - ничего не меняется. Тыкаюсь в меню - нигде нет чего-то типа "set default character coding". Думаю, может, в меню нет, но в конфигурации где-то сохраняется; лезу в .gconf/apps/gnome-terminal/ и читаю вручную .xml-файлы, ничего не нахожу (потом уже понял, что вместо чтения вручную надо идти в гномовский Application->System Tools->Configuration Editor). Смотрю на опции командной строки, нахожу опцию геометрии (чтобы запускать его сразу 80x40, а не 80x24, как по умолчанию, удобо), а кодировок нет.
Лезу в исходники gnome-terminal, блуждаю по encoding.c. terminal_encoding_init()... но нет, она создаёт список кодировок, но в этом списке никак не указано, какая текущая. grep encoding *.c . Ага, есть есть вызов terminal_widget_set_encoding() в terminal-window.c, внутри функции change_encoding_callback(). Очевидно, эта функция вызывается, когда я в меню меняю кодировку. Больше
terminal_widget_set_encoding нигде не вызывается, значит, change_encoding_callback() должен кто-то вызвать, когда программа начинает работать, чтобы поставить первоначальный дифолтный выбор. grep change_encoding_callback *.c . Ага, это происходит в fill_in_encodings_menu(), при инициализации меню. Где там ставится первоначальный выбор? charset = terminal_widget_get_encoding (w);
Т.е. первоначальную кодировку мы берём у библиотеки терминала. Смотрим, что это за функции terminal_widget_get_encoding() и terminal_widget_set_encoding(). Они определяются два раза: в terminal-widget-vte.c и terminal-widget-zvt.c . Смотрим на эти файлы - судя по всему, две разных имплементации виджета терминала. Та, которая zvt, попроще, и в terminal_widget_set_encoding() ничего не делает. Т.к. я могу менять кодировку, очевидно, мой gnome-terminal был построен с terminal-widget-vte.c, которая пользуется функциями vte_terminal_get_encoding() и vte_terminal_set_encoding(). Их в исходниках нет... это какая-то библиотека. Ищем vte... ага, есть такая библиотека гномовская, распакуем её исходники и посмотрим на эти функции. Из них становится понятно, что именно vte занимается перекодировкой входа/выхода, используя функции iconv. Откуда vte берёт первоначальный charset, к-й она использует? vte_terminal_get_encoding() читает кодировку из внутренней структуры терминала: terminal->pvt->encoding; значит, надо искать, кто её туда ставит. grep encoding *.c . Никто не трогает это поле, кроме vte_terminal_set_encoding(), странно; ага, эта функция принимает имя кодировки, но если вместо него передаётся NULL, то она вызывает g_get_charset(), и ставит кодировку, к-ю возвращает эта функция. Проверяем, где вызывается vte_terminal_set_encoding(), и да, действительно, во время инициализации терминала есть вызов с аргументом NULL. Т.е. надо искать, что такое g_get_charset(), похоже, что-то гномовское, но (grep g_get_charset *.c) в vte такой функции нет. find /usr/include -exec grep -q g_get_charset {} \; -print . Ага, /usr/include/glib-2.0/glib/gunicode.h .
Полезли распаковывать исходники glib2. g_get_charset() нашлась в glib/gutf8.c ; вначале вызывает _g_locale_charset_raw() - судя по имени, эта фунцкия наконец доходит до локали - но потом пользуется ещё каким-то внутренним кэшем для алиасов и канонизации имён кодировок, для чего использует g_utf8_get_charset_internal(), передавая ей полученную от _g_locale_charset_raw() строку и получая обратно имя кодировки, к-е сохраняет в кэше и возвращает наружу. Смотрим в _g_locale_charset_raw, она внутри glib/libcharset/libcharset.c ; ага, полезли кучи #define'ов на разные операционные системы и вызовы функций типа langinfo() и других функций локали. Здесь я ничего не добьюсь, чтобы разобраться, как мне грамотно выставить локаль, чтобы g_get_charset() получила 'cp1251', мне нужно лезть в исходники glibc, или искать грамотную документацию по локали (не-на-ви-жу). Смотрю в g_utf8_get_charset_internal(), и вот наконец приятный сюрприз:
const char *charset = getenv("CHARSET"); если это выставлено, она игнорирует то, что даёт локаль, и использует эту кодировку.
Уф. До свидания, исходники. "CHARSET=cp1251 gnome_terminal" - работает! Пытаюсь прописать это в шорткате, который я себе поставил для вызова терминала - фиг, говорит, не может запустить программу, значит, не пользуется он шеллом. Ищу где-то в опциях шортката (который здесь launcher называется) место для определения переменных среды - фигвам, хижина такая у эскимосов. Ладно, надоело: cat >~/scripts/gnome-terminal-cp1251
#!/bin/bash
export CHARSET=cp1251
exec gnome-terminal $*
Выставляю нужные разрешения на файл, ставлю его имя в launcher ($HOME он тоже не понимает, дубина... а где этому гному сказать, чтобы $HOME/scripts в $PATH добавил? Ладно, лень разбираться, в следующий раз, прописываю полный путь). Всё.
Это было такое экспериментальное описание "рабочего процесса".
Всё это сделать было быстрее, чем описать сейчас. Интересно, если бы я разбирался в локали, знал бы заранее, что можно CHARSET поставить? Или если бы в правильное место полез RTFMить, не пришлось бы по исходникам бегать? Очень вероятно, но, в конце концов, мне сам этот процесс нравится. Надо не увлекаться, однако, слишком легко много времени потерять.
Теперь программа терминала запускается с кодировкой cp1251, и mutt тоже (после того, как я прописал set charset=cp1251 в .muttrc), так что для чтение русских писем ничего дополнительного не надо делать.
no subject
Date: 2003-08-09 10:41 am (UTC)no subject
Date: 2003-08-09 11:50 am (UTC)no subject
Date: 2003-08-09 12:01 pm (UTC)no subject
Date: 2003-08-09 12:12 pm (UTC)no subject
Date: 2003-08-09 12:17 pm (UTC)no subject
Date: 2003-08-09 12:53 pm (UTC)VmWare?
Date: 2003-08-09 06:41 pm (UTC)Re: VmWare?
Date: 2003-08-10 03:04 am (UTC)Я пробовал все варианты - самый удобный выходит отдельный компьютер все-таки (или даже два, если драйверы писать)
no subject
Date: 2003-08-10 04:33 am (UTC)no subject
Date: 2003-08-10 10:14 am (UTC)Пожалуйста, если хотите чтобы я прочитал, пишите или по русски, или по английски, а не этой галиматьей.
no subject
Date: 2003-08-10 03:04 pm (UTC)У меня на домашней машине стоит программулька, позволяющая (правда, RO) просматривать разделы в ext3, а равно и ext2.
no subject
Date: 2003-08-10 03:35 pm (UTC)no subject
Date: 2003-08-09 12:11 pm (UTC)no subject
Date: 2003-08-09 12:21 pm (UTC)