まだあるX Window Systemのツールキット

第18回は、再びX Window System(以下X)のHello Worldです。Xでは、ツールキットごとに異なるプログラムを作成できますが、今回は、第10回で取り上げたXaw、GTK+、Qt以外のツールキットを使ったHello Worldを作成します。

Xtを単独で使う方法

Xに標準で付属しているXaw(Athenaウィジェット)は、ツールキット・イントリンシクス(Xt)の上に構築されたウィジェットです(本稿では触れていませんが、Motifも同様にXtベースのウィジェットです)。そして、実はXawやMotifを使わずに、Xtだけを単独で使っても、Hello Worldのプログラムを作成することが可能です(リスト1)。

Xt単独のプログラムは、Xawのプログラムに似ています。しかし、Xawで使えるラベルウィジェット(labelWidgetClass)は、Xt単独では使えないため、代わりに、基本のウィジェットであるコアウィジェット(coreWidgetClass)を使います。この、coreWidgetClassでは、表示幅と高さは指定できますが、これだけでは文字列は表示できません。そこで、Exposeイベント発生時に呼ばれるコールバック関数を設定し、この関数内でXDrawString()を使ってウィンドウに文字列を描画するようにします。なお、Exposeイベントは、ウィンドウの再描画が必要になった時に適宜発生します。

リスト1 Xtを単独で使う方法(x11_xt.c)

Xtを使ったプログラムは、実行例1のようにコンパイルします。コマンドラインでは、Xのインクルードファイルとライブラリの存在するディレクトリを、それぞれ-Iと-Lオプションで指定します。ただし、Xが/usr/X11R6ではなく/usr以下にインストールされている環境では、-Iと-Lのオプションは省略できます。リンクするライブラリはXtとX11なので、それぞれ-lオプションで指定します。

実行例1 Xtを使ったプログラムのコンパイル

xmkmfを使う場合は、リスト2のようなImakefileをソースファイルと同じディレクトリに作成し、「xmkmf; make」と実行すればコンパイルできます。xmkmf方式では、gccに付加するオプション等は環境に合わせて自動設定されます。

リスト2 XtのためのImakefile

このプログラムを実行すると、図1のようなウィンドウが表示されます。

図1 Xtを単独で使ったHello World

wxGTKを使う方法

次はwxGTKです(リスト3、図2)。プログラムはC++です。wxGTKでは、wxAppクラスを、適当な名前(MyApp)のクラスとして継承し、そのメンバ関数OnInit()を再定義して、実際のプログラムを記述します。ここで、念のため継承元のwxAppクラスのOnInit()も呼び出しておきます。

OnInit()内では、フレームとパネルを作成し、その中に文字列を表示しています。文字列は、wxString型に変換して用意する必要があります。

main()関数では、継承したMyAppクラスのインスタンスを作成した後、wxEntry()を呼び出すだけで処理が完了します。

リスト3 wxGTKを使う方法(x11_wx.cc)

wxGTKを使ったプログラムは、実行例2のようにコンパイルします。ここで、wx-configは、wxGTKのプログラムのコンパイルに必要なオプションを出力してくれるコマンドです。このwx-configの出力は、シェルのコマンド置換(バッククォート)で取り込んで利用します。

実行例2 wxGTKを使ったプログラムのコンパイル

図2 wxGTKを使ったHello World

SDLを使う方法

SDLを使う方法は、リスト4、図3のとおりです。ここでは、SDLの基本ライブラリ(libSDL)のほか、文字列の描画のために、SDL_ttfライブラリ(libSDL_ttf)を使用します。

SDLでは、デフォルトではウィンドウのバックが黒色になるため、これを白色で塗りつぶす処理も行います。

フォントは、ほかのツールキットとは異なり、フォントファイル自体の絶対パスを直接指定する方式になっています。フォントにはTrueTypeフォントが使えますが、ここではビットマップフォント(pcf)を指定しています。フォントの絶対パスは、OS環境によって修正してください。

表示する文字列は、TTF_RenderText_Solid()を使ってSDL_Surfaceとしてレンダリングしてから、それをSDL_BlitSurface()でウィンドウ上に描き加えます。

メインループでは、SDL_WaitEvent()を呼び出しながらループします。ここで、最低限SDL_QUITのイベントだけは対応する必要があり、SDL_QUITイベントが発生したらループを終了します。

リスト4 SDLを使う方法(x11_sdl.c)

SDLを使ったプログラムは、実行例3のようにコンパイルします。SDLのプログラムのコンパイルに必要なオプションは、sdl-configコマンドで出力できるため、これをシェルのコマンド置換(バッククォート)で取り込んで利用します。ここではさらにSDL_ttfも利用しているため、-lSDL_ttfのオプションを別途追加します。

実行例3 SDL(SDL_ttf)を使ったプログラムのコンパイル

図3 SDLを使ったHello World

ツールキットを使わない方法

どのようなツールキットを使ったプログラムでも、XのプログラムはすべてXの基本ライブラリであるXlib(libX11)を使用しています。実は、このXlibだけを使って、ツールキットを使わずにHello Worldのプログラムを作成することも可能です(リスト5、図4)。

Xlibは、もっとも低レベルのライブラリのため、XOpenDisplay()でXサーバに接続することから記述する必要があります。ウィンドウはXCreateSimpleWindow()で作成しますが、ここで指定する「ボーダ」は、ウィンドウマネージャを使用している環境では結果的に関係なくなります。

メインループでは、XNextEvent()でイベントを待ちながらループします。ここではXt単独のプログラムと同様に、Exposeイベントが発生したらXDrawString()で文字列を描画するようにしています。

リスト5 Xlibのみを使ったHello World(x11_xlib.c)

Xlibのみを使ったプログラムのコンパイル方法は実行例4のとおりです。コマンドラインはXtのプログラムのコンパイルとほとんど同じで、ライブラリとして-lX11のみを指定する点が異なります。

実行例4 Xlibのみを使ったプログラムのコンパイル

Imakefileを作成する場合はリスト6のとおりです。内容は、ライブラリ指定が$(XLIB)のみになる点を除いてXtの場合と同じです。

リスト6 Xlib単独のImakefile

図4 Xlib単独のHello World