avva: (Default)
[personal profile] avva


Решил сделать так, чтобы терминал (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), так что для чтение русских писем ничего дополнительного не надо делать.

Date: 2003-08-09 12:17 pm (UTC)
From: [identity profile] nice-beaver.livejournal.com
Не пройдет. У меня расчетная программа, считается долго даже на хорошем компе. А чем плох Dual Boot?

Date: 2003-08-09 12:53 pm (UTC)
From: [identity profile] msh.livejournal.com
Чем плох dual boot начинаешь понимать после 8-го "ой, это было в письме, которое я не скопировал на общий раздел"

VmWare?

Date: 2003-08-09 06:41 pm (UTC)
From: [identity profile] cema.livejournal.com
VmWare. Run them together.

Re: VmWare?

Date: 2003-08-10 03:04 am (UTC)
From: [identity profile] msh.livejournal.com
Даже если не учитывать то, что VmWare стоит денег, она дает заметный overhead. То есть для короткого тестирования на разных системах это еще куда ни шло (если программа совсем-совсем прикладная и ни от какого железа не зависит), но при разработке второй компьютер окупится очень быстро

Я пробовал все варианты - самый удобный выходит отдельный компьютер все-таки (или даже два, если драйверы писать)

Date: 2003-08-10 04:33 am (UTC)
From: [identity profile] pechkin.livejournal.com
A tut-to kakaja problema? Vrode zhe mozhno smontirovat' fat[32] pod linuxom i suw,estvujut smotrelki ext2fs pod windoj?

Date: 2003-08-10 10:14 am (UTC)
From: [identity profile] msh.livejournal.com
Обычная fs под Linux сейчас или ext3 или reiser, под Windows - NTFS.

Пожалуйста, если хотите чтобы я прочитал, пишите или по русски, или по английски, а не этой галиматьей.

Date: 2003-08-10 03:04 pm (UTC)
From: [identity profile] pechkin.livejournal.com
Тысяча пардонов, не знал, что у вас аллергия на транслит. Писал из школы, где моих разрешений не хватает на установку соответствующих прилад.

У меня на домашней машине стоит программулька, позволяющая (правда, RO) просматривать разделы в ext3, а равно и ext2.

Date: 2003-08-10 03:35 pm (UTC)
From: [identity profile] msh.livejournal.com
Да все можно. Прочитать, сконвертировать, вытащить. Только надоедает. Жалко время-то тратить на борьбу со всей этой ерундой

December 2025

S M T W T F S
  123 4 56
78 9 10 11 1213
1415 1617181920
21 22 23 24 2526 27
2829 30 31   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 1st, 2026 06:21 pm
Powered by Dreamwidth Studios