X11: ロケール

ロケール
入力メソッドや、ロケール文字列を扱う X 関数を使う場合、通常のロケール設定に加えて、X のロケールを設定する必要があります。

基本的には、以下のように設定します。

setlocale(LC_ALL, "");

if(XSupportsLocale())
    XSetLocaleModifiers("");
プログラム
X ロケールを設定します。

<21-locale.c>
#include <stdio.h>
#include <locale.h>
#include <X11/Xlib.h>

int main(int argc,char **argv)
{
    Display *disp;
    char *ret;
    
    disp = XOpenDisplay(NULL);
    if(!disp) return 1;

    ret = setlocale(LC_ALL, "");
    printf("locale: '%s'\n", ret);

    if(XSupportsLocale())
    {
        ret = XSetLocaleModifiers("");
        if(ret) printf("modifiers: '%s'\n", ret);
    }

    XCloseDisplay(disp);

    return 0;
}

locale: 'ja_JP.UTF-8'
modifiers: '@im=fcitx5'
解説
X のロケールを設定する前に、setlocale() で C のロケールを設定します。
空文字列を指定することで、LANG 環境変数などから取得して設定します。
戻り値は、現在のロケールを表す文字列です。

X では、LC_CTYPE のカテゴリが現在のロケールとして扱われます。
XSupportsLocale
Bool XSupportsLocale(void);

現在のロケールを X がサポートしているかどうかが返ります。
True でサポートされています。
XSetLocaleModifiers
char *XSetLocaleModifiers(char *modifier_list);

現在のロケール設定における X ロケール修飾子を設定します。
ロケールに関する追加の情報となり、現在では「@im=...」のみ対応しています。

modifier_list が NULL の場合、設定を変更せず、現在の文字列を返します。
それ以外の場合 (空文字列も含む)、modifier_list の後に、デフォルト値として、XMODIFIERS 環境変数の文字列が追加されます。
デフォルト値だけ設定したい場合は、空文字列 ("") を指定します。

例えば、~/.xprofile で以下のように環境変数を設定していると、"@im=fcitx5" の文字列が設定されることになります。

export XMODIFIERS=@im=fcitx5

「@im=...」で、X で使用する入力メソッドを指定することができます。

戻り値は、環境変数の値も含めた、完全な修飾子文字列のポインタです。
このポインタは Xlib によって所有されているので、変更したり解放したりしないでください。
現在のロケールまたは X ロケール修飾子が変更された場合、ポインタは解放される可能性があります。

無効な値が指定された場合は、NULL が返ります。