"Иксовая" setlocale()
Дело в том, что процедуры Xlib для того, чтобы узнать название "текущей locale" используют "третью форму" вызова "libc'ишной" setlocale().
Но, на тот случай, если в "системной" libc нет такой процедуры, в Xlib
существует "заглушка" - (вообще-то, она называется_Xsetlocale()), которая может вызываться вместо системной setlocale().
Для того, чтобы работала "заглушка", библиотека Xlib должна быть собрана с "опцией"
#define X_LOCALE
(при этом вызовы setlocale() автоматически заменяются на вызовы _Xsetlocale())
Надо заметить, что "иксовая" setlocale(), хотя и вызывается точно так же, как и "системная" (те же три формы вызова), имеет некоторые отличия во "второй форме" (наиболее популярном способе установки "текущей locale").
- Категории (первый аргумент) могут быть только LC_ALL или LC_CTYPE.
- При этом название locale она пытается взять из переменных окружения LC_CTYPE и, если не получилось - LANG.
- На переменную окружения LC_ALL она внимания не обращает (даже если первый аргумент - "категория" LC_ALL).
Ну и, естественно, эта "заглушка" устанавливает только "иксовые" параметры locale, а не "libc'ишные".
Так вот. Проблемы могут возникнуть, если у вас в системе Xlib почему-то собрана с "опцией" X_LOCALE, хотя в libc соответствующая процедура имеется.
Тогда вызов setlocale() из libc запомнит название locale в своих внутренних переменных, а процедуры Xlib будут спрашивать "текущую locale" у своей "заглушки", которая, естественно, ее не знает.
Если уж у вас Xlib собрана с X_LOCALE, то и программы должны вызывать не "системную" setlocale(), а "иксовую".
Для этого перед вызовом setlocale() должно стоять
#define X_LOCALE #include <X11/Xlocale.h>
Если Xlib "нормальная" (то есть ориентруется на "системную" setlocale), то этих строчек не нужно. (Хотя, конечно, понадобится #include <locale.h>)