Appendix ( 付録 )

○ はじめに

ここまでの LECTURE で紹介しなかった話題について、いくつか紹介しています。ちょっとしたメモ代わりとして読んでみて下さい。

○ select() による多重入力処理

複数のソケットやデバイスからの入力を並列に扱いたい場合、Unix では select() システムコールがよく使われます。select() システムコールを使って各ファイル記述子をチェックし、読み込み可能と判断されたファイル記述子について順次読み込み処理を行えば、複数の入力を並列に処理することができます。

これは Xlib を使った GUI アプリケーションにおいても同様で、X サーバとの通信に使用しているファイル記述子 ( ソケット )を取得した上で通常の select() 処理と同様に処理することで実現できます。

X サーバとの通信に用いているファイル記述子を取得するには、ConnectionNumber() ディスプレイマクロを使います。

int fd; /* ファイル記述子 */

fd = ConnectionNumber( dpy );

ファイル記述子を取得した後は通常の select() 処理を行い、 X サーバからの入力があった場合には Xのイベント処理を行い、その他の入力 ( ネットワーク越しのクライアントからのアクセスなど ) があった場合はそれらの入力受信処理を行います。

--- コード例 ---

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int    fd_x; /* X サーバとの通信 */
int    fd_o; /* その他の入力 */
fd_set set;  /* select() で監視するファイル記述子を設定 */

/* X サーバとの通信用ソケットを取得 */
fd_x = ConnectionNumber( dpy );

while( 1 ) {
  /* 監視対象に fd_x と fd_o を設定 */
  FD_ZERO( &set );
  FD_SET( fd_x, &set );
  FD_SET( fd_o, &set );

  /* fd_x > fd_o と仮定する。引数は select() のマニュアル参照のこと */
  select( fd_x + 1, &set, NULL, NULL, NULL ); /* 

  if ( FD_ISSET( fd_x, &set ) ) {

    /* X サーバからの入力有り */
    while( XPending( dpy ) ) {
       XNextEvent( dpy, &event );

       /* 通常のイベント処理 */
    }
  }

  if ( FD_ISSET( fd_o, &set ) ) {
    /* ネットワーククライアントからの入力有り */

  }
}

○ リソースファイル( $HOME/.Xdefaults ) の簡単な使用法

リソースファイル( $HOME/.Xdefaults )に記述されたクライアント用のリソース値を簡単に読み込むために、XGetDefault() という関数が用意されています。

char* XGetDefault( Display* dpy, char* program, char* option );

program : アプリケーション名
option  : リソース名

program にはアプリケーション名 ( クライアント名、通常はコマンド名 argv[0] でよい ) を指定します。option は値を読み込みたいリソース名です。この関数を実行することで、$HOME/.Xdefaults ファイルに "アプリケーション名"*"リソース名" : リソース値 の形式で記述されているリソースのリソース値が文字列で返ってきます。値が指定されていない場合には NULL が返されます。なお、リソースの管理に xrdb を使っている場合はリソースデータベースのリソースを読みにいきます。

ちなみに、この関数は X ウィンドウシステムのリリース 5 以降では推奨されていないようです ( リソースファイルやプロパティを全て読みこむわけではないから )。が、xrdb を使わず $HOME/.Xdefaults 内でちょこちょこっとリソースを扱いたい時には充分使えるのではないかと思っています。正式なリソース管理用には、低リソースマネージャ関数と呼ばれる関数群を使用してください ( 僕はまだ勉強してません。。。)。

○ ビットマップデータからピクスマップを作成

XCreatePixmapFromBitmapData() を使うと、bitmap クライアントなどで作成した X ビットマップデータからピクスマップを作成することができます。

Pixmap XCreatePixmapFromBitmapData( Display*      dpy, 
                                    Drawable      d,
                                    char*         data, 
                                    unsigned int  width, 
                                    unsigned int  height, 
                                    unsigned long fg, 
                                    unsigned long bg, 
                                    unsigned int  depth 
                                  );

data          : ビットマップデータ
width, height : dataの幅と高さ
fg            : フォアグラウンドカラー
bg            : バックグラウンドカラー
depth         : 生成するピクスマップの深さ

data で指定した X ビットマップデータから、幅 width、高さ height、深さ depth のピクスマップを生成します。生成されたピクスマップはビットマップの 1 の部分が fg、0 の部分が bg で塗られます。

なおビットマップデータから深さ 1 のピクスマップ、すなわちビットマップを生成する関数として、XCreateBitmapFromData() があります。

Pixmap XCreateBitmapFromData( Display*     dpy, 
                              Drawable     d, 
                              char*        data, 
                              unsigned int width, 
                              unsigned int height 
                            );