38173
**目標**  
Xlibで作成したウィンドウ上に、XmbDrawStringで日本語の文字列を表示する。

**状況**  
Xlibを使用したソフトウェアの開発過程で日本語の描画方法の確認として、[あるサイト上](http://rio.la.coocan.jp/lab/xlib/011mbcs.htm)で紹介されていた以下のサンプルコードを実行しました。

```

            #include <X11/Xlib.h>
        2   #include <X11/Xlocale.h> /* ロケール用ヘッダーファイル */
        3   #include <stdio.h>
        4   #include <string.h>
        5   
        6   #define WIN_W  350  /* ウィンドウの幅   */
        7   #define WIN_H  250  /* ウィンドウの高さ */
        8   #define WIN_X  100  /* ウィンドウ表示位置(X) */
        9   #define WIN_Y  100  /* ウィンドウ表示位置(Y) */
       10   #define BORDER 2    /* ボーダの幅 */
       11   
       12   
       13   int
       14   main( void )
       15   {
       16       Display*      dpy;            /* ディスプレイ変数 */
       17       Window        root;           /* ルートウィンドウ */
       18       Window        win;            /* 表示するウィンドウ */
       19       int           screen;         /* スクリーン */
       20       unsigned long black,white;    /* 黒と白のピクセル値 */
       21       GC            gc;             /* グラフィックスコンテキスト */
       22       XEvent        evt;            /* イベント構造体 */
       23   
       24       XFontSet      fs;             /* フォントセット */
       25       int           missing_count;  /* 存在しない文字集合の数 */
       26       char**        missing_list;   /* 存在しない文字集合 */
       27       char*         def_string;     /* ↑に対して描画される文字列 */
       28   
       29   
       30       /* 描画する全角文字列 */
       31       char*         string = "こんにちは、お元気ですか？";
       32   
       33   
       34       /* ロケールを設定する(現在システムに設定されているロケールを使用) */
       35       if ( setlocale( LC_CTYPE, "" ) == NULL ) {
       36           printf( "Can't set locale\n" );
       37           return 1;
       38       }
       39   
       40       /* Xlib が現在のロケールを扱えるかどうかを判断する */
       41       if ( ! XSupportsLocale() ) {
       42           printf( "Current locale is not supported\n" );
       43           return 1;
       44       }
       45   
       46   
       47       dpy = XOpenDisplay( "" );
       48   
       49       root   = DefaultRootWindow( dpy );
       50       screen = DefaultScreen( dpy );
       51       white  = WhitePixel( dpy, screen );
       52       black  = BlackPixel( dpy, screen );
       53   
       54   
       55       win = XCreateSimpleWindow( dpy, root,
       56              WIN_X, WIN_Y, WIN_W, WIN_H, BORDER, black, white );
       57   
       58   
       59       gc = XCreateGC( dpy, win, 0, NULL );
       60       XSetBackground( dpy, gc, white );
       61       XSetForeground( dpy, gc, black );
       62   
       63   
       64       /* フォントセットを生成する */
       65       fs = XCreateFontSet( dpy, "-*-fixed-medium-r-normal--16-*-*-*", 
       66                    &missing_list, &missing_count, &def_string );
       67   
       68       if ( fs == NULL ) {
       69           printf( "Failed to create fontset\n" );
       70           return 1;
       71       }
       72   
       73       XFreeStringList( missing_list );
       74   
       75       XSelectInput( dpy, win, ExposureMask | KeyPressMask );
       76       XMapWindow( dpy, win );
       77   
       78   
       79       while( 1 ) {
       80           XNextEvent( dpy, &evt );
       81   
       82           switch( evt.type ) {
       83               case Expose:
       84                   if( evt.xexpose.count == 0 ) {
       85                       XmbDrawString( dpy, win, fs, gc, 
       86                           50, 50, string, strlen( string ) );
       87                   }
       88                   break;
       89   
       90               case KeyPress:
       91                   XFreeGC( dpy, gc );
       92                   XFreeFontSet( dpy, fs );
       93                   XDestroyWindow( dpy, win );
       94                   XCloseDisplay( dpy );
       95                   return 0;
       96           }
       97       }
       98   }
       99   
    
```

しかし、日本語が文字化けしてしまいます。  
文字列の描画自体は実行されているので、ロケールやフォントの読み込みは問題なく実行されており、プログラムと実行環境の文字コードが原因だと認識しています。

実行環境に問題があるのかと`locale`コマンドで確認しましたが、

```

    LANG="ja_JP.UTF-8"
    LC_CTYPE="ja_JP.UTF-8"
    LC_NUMERIC="ja_JP.UTF-8"
    LC_TIME="ja_JP.UTF-8"
    LC_COLLATE="ja_JP.UTF-8"
    LC_MONETARY="ja_JP.UTF-8"
    LC_MESSAGES="ja_JP.UTF-8"
    LC_ALL="ja_JP.UTF-8"
    
```

のように、UTF-8となっています。  
また、ファイルの文字コードもUTF-8となっています。

**質問**  
文字化けの原因として、どのようなものが考えられるでしょうか？  
また、これ以外に日本語を表示する方法はあるでしょうか？  
ご協力をお願いします。

**追記**  
以下が文字化けのスクリーンショットです。[![enter image description
here](https://i.stack.imgur.com/X8AKr.jpg)](https://i.stack.imgur.com/X8AKr.jpg)
CC BY-SA 3.0
2017-09-24T07:14:47.627
38153
2017-09-25T09:19:56.057
2017-09-25T07:32:53.300
25443
25443
question
linux c x11
Xlibでの日本語の表示について
環境に`fixed`のフォントがインストールされていないため、と予想します。

```

        xlsfonts -fn '-*-fixed-medium-r-normal--16-*-*-*'
    
```

と実行し、何も出力されなければ予想通りと思います。

Xlibで日本語表示させるのであれば、RHEL/CentOSであれば、`xorg-x11-fonts-misc`の  
パッケージをインストールすると表示されるようになるかと思います。  
(他のディストリビューションも似たような感じ)

＊

なお、Xlibだとttf等のアンチエイリアシングフォントは表示できなかったと思います。  
表示したい場合「fontconfig」関連のAPIで実装することになると思います。
CC BY-SA 3.0
2017-09-25T09:19:56.057
38173
2017-09-25T09:19:56.057
20098
38153
answer