Столкнулся давно с проблемой: приложения написанные с использованием только Xlib и Xt, например,xclock, xfontsel, или удобная тюнинговалка xvidtune, или мелкая оповещалка xmessage, очень долго запускаются, до 15-20 секунд, при этом давая значительную нагрузку на процессор. Если запускать в терминале, то обычно получаем, среди прочего, такую строку:
Warning: Missing charsets in String to FontSet conversion
Так как эти приложения использовал достаточно редко, то не обращал внимание, но сегодня что-то достало, решил разобраться. Беглый поиск привел на эту страницу: http://www.holoweb.net/~liam/fonts/common-linux-font-problems.html (искать по фразе “Everything starts up really slowly”). Информация старая, ещё для XFree86, ориентировочно 2002 года, но, с небольшими поправками, не потерявшая актуальность и сегодня.
В общих чертах: проблема в fontconfig и локалях Xorg, где указаны кодировки для шрифтов, которых нет в системе. Путей решения получается три:
- Запускать через приведенный там скрипт nolocale, добавив туда ещё сточку:
bashexport LANG=
- Поставить шрифты со всеми нужными кодировками
- Отредактировать файл локали, убрав (закоментировав) использование несуществующих кодировок
Так как первый способ неудобен, а второй накладен, решил сделать по последнему варианту. Итак, рецепт для ArchLinux (с небольшой адаптацией последнего пункта подходит и для любого другого дистрибутива)
Для начала нужно понять шрифтов в каких кодировках у нас нет.
Для этого бредём в директорию /usr/share/X11/locale/<ВАША_ЛОКАЛЬ>. У меня локаль ru_RU.UTF-8
, поэтому директория: /usr/share/X11/locale/ru_RU.UTF-8 и выполним там команду:
cat XLC_LOCALE | grep name | grep -v 'object_name<br/>|encoding_name'
В результате получим примерно такой вывод:
name ISO8859-1:GL
name ISO8859-1:GR
name KOI8-R:GR
name MICROSOFT-CP1251:GR
name ISO8859-5:GR
name JISX0208.1983-0:GL
name KSC5601.1987-0:GL
name GB2312.1980-0:GL
name JISX0201.1976-0:GR
name ISO10646-1
На то, что после двоеточия не обращаем внимания, итого, кодировка состоит из двух частей, разделенных “-”: CHARSET_REGISTRY и CHARSET_ENCODING (за подробностями сюда: http://lesstif.sourceforge.net/doc/super-ux/g1ae04e/chap5.html)
Теперь запускаем программку xfontsel, придется подождать малость (с чем собственно мы сейчас и боремся).
Итак, шрифты в X11 издревле задавались хитрой строчкой, поля в которой были разделены знаком “-”, последние два элемента как раз и есть CHARSET_REGISTRY и CHARSET_ENCODING (в терминах xfontsel: rgstry и encdng соответственно). Теперь просто проверяем по последним двум полям, что есть все комбинации из вышеполученных rgstry-encdng (на регистр внимания не обращаем), те, которые не находим помечаем.
Теперь возвращаемся в каталог с локалью, открываем файл XLC_LOCALE на редактирование находим секцию с несуществующей кодировкой и комментируем её.
У себя я не нашел шрифтов в кодировке microsoft-cp1251
(есть только cp1252), поэтому полностью закомментированная секция выглядит теперь так:
# fs3 class (MICROSOFT-CP1251)
#fs3 {
# charset {
# name MICROSOFT-CP1251:GR
# }
# font {
# primary MICROSOFT-CP1251:GR
# }
#}
Все, сохраняемся и выходим. Проверяем, приложения должны стартовать практически мгновенно.
Ну и последний штрих для ArhLinux. Дабы уберечь от перезаписывания этого файла при обновлениях пакета libx11 (а именно ему принадлежат эти файлы локали), его нужно “замаскировать”. Для чего открываем на редактирование файл /etc/pacman.conf, находим параметр NoUpgrade и приводим его примерно к такому виду:
NoUpgrade = usr/share/X11/locale/ru_RU.UTF-8/XLC_LOCALE
Теперь при обновлениях, если файл в пакете изменился, он будет ставиться под именем XLC_LOCALE.pacnew и соответствующим предупреждением на экране и в логе. Дальнейшие шаги по поддержанию в актуальном состоянии зависят от вас.
Ну и последнее замечание, описанной процедурой можно и просто найти шрифтов в каких кодировках нет в системе и просто поставить их, если они у вас имеются :)