#include <X11/GLw/GLwMDrawA.h>
ld ... -lGLw -lGL -lXm -lXext -lXt -lX11 -lm
GLwDrawingArea はいかなるウィジェットセットの一部でもないが、Xt だけに は依存する。 GLwDrawingArea はどんなウィジェットセットと組み合わせても使える。 GLwMDrawingArea は GLwDrawingArea とほぼ同じであるが、MotifTm のウィジェットクラスである XmPrimitive のサブクラスであり、デフォルト 状態が Motif に適したようになっている。例えば、GLwMDrawingArea は Motif のデフォルトの前景色と背景色をリソースに持ち、キーボードの移動も よりうまく扱える。 GLwDrawingArea を Motif のプログラムで使えるが、GLwMDrawingArea を使う 方が推奨される。
GLwDrawingArea と GLwMDrawingArea はほとんど同じ動作なので、この オンラインマニュアルの残りの部分では、動作が異なる部分を除いて GLwDrawingArea だけを説明する。明示的に述べない限り、GLwDrawingArea に 関する全ての説明は GLwMDrawingArea にも当てはまる。
GLwDrawingArea を生成する時に与える情報の中でも、特に重要なのは ビジュアルを決めるために必要な情報である。 これを与える方法は 3 つあり、そのいずれもリソース経由で行われる。 特定の visualInfo 構造体を渡すこともできる。 (この visualInfo は既に別のところで取得していなければならない。 アプリケーションが行う OpenGL の描画とこの visualInfo の互換性を保証す るのはアプリケーション設計者の責任である)。 別の方法として、属性リストを与えることもできる。この属性リストは、 直接 OpenGL プログラミングを行う場合に使われるものと全く同じ書式である。 最後に、それぞれの属性を個別のリソースとして指定することもできる。 最後の方法が最も単純であり、リソースファイルから操作できる唯一の方法であ る。
ビジュアルの割り当て以外にも、GLwDrawingArea は アプリケーションに割り当てられなければカラーマップの割り当ても行う (カラーマップが割り当てられる場合、カラーマップとビジュアルの互換性を 保証するのはアプリケーション設計者の責任である。) アプリケーションが同じビジュアルから複数個の GLwDrawingAreas を生成す る場合、同じカラーマップが使われる(ただし異なるアプリケーション間では カラーマップは共有されない)。
ウィジェットを生成しても、ウィジェットがリアライズされるまではウィンドウ は生成されない。したがってアプリケーションはウィンドウに対する OpenGL の操作をウィジェットの生成直後に行ってはならない。 アプリケーションはウィンドウがリアライズされるのを待たなければならない。 そこでこれに代わる方法として、ウィンドウが生成されたことを示す ginit コールバック を使ってもよい。このコールバックを受け取れば、アプリケーションは そのウィンドウに対して全ての OpenGL 初期化処理を行い、それからその他の 操作を行うことができる。初期化については後で詳しく説明する。
アプリケーションは glXMakeCurrent または簡易関数 GLwDrawingAreaMakeCurrent を使って、アクセスする GLwDrawingArea を選択する。 GLwDrawingAreaMakeCurrent はディスプレイとウィンドウの代わりに ウィジェットを引き数に取る。 これらの関数は、GLwDrawingArea が一つしかなければ一度だけ呼べばよいが、 複数の GLwDrawingArea がある場合は、それぞれのコールバックの先頭で呼ば なければならない。 ここで言うコールバックには、ウィジェット自身が与えるコールバックだけで なく、GL の動作に影響を与える全てのコールバック(タイムアウトや作業手続き等) も含まれる。
アプリケーションがダブルバッファリングを使っている場合は、 glXSwapBuffers ではなく GLwDrawingAreaSwapBuffers を呼ぶとよい。 この関数を使うとディスプレイとウィンドウの代わりにウィジェットを指定す ることができる。
名前 | クラス | 型 | OpenGL 属性 |
GLwNbufferSize | GLwCBufferSize | int | GLX_BUFFER_SIZE |
GLwNlevel | GLwCLevel | int | GLX_LEVEL |
GLwNrgba | GLwCRgba | Boolean | GLX_RGBA |
GLwNdoublebuffer | GLwCDoublebuffer | Boolean | GLX_DOUBLEBUFFER |
GLwNstereo | GLwCStereo | Boolean | GLX_STEREO |
GLwNauxBuffers | GLwCAuxBuffers | Boolean | GLX_AUX_BUFFERS |
GLwNredSize | GLwCColorSize | int | GLX_RED_SIZE |
GLwNgreenSize | GLwCColorSize | int | GLX_GREEN_SIZE |
GLwNblueSize | GLwCColorSize | int | GLX_BLUE_SIZE |
GLwNalphaSize | GLwCAlphaSize | int | GLX_ALPHA_SIZE |
GLwNdepthSize | GLwCDepthSize | int | GLX_DEPTH_SIZE |
GLwNstencilSize | GLwCStencilSize | int | GLX_STENCIL_SIZE |
GLwNaccumRedSize | GLwCAccumColorSize | int | GLX_ACCUM_RED_SIZE |
GLwNaccumGreenSize | GLwCAccumColorSize | int | GLX_ACCUM_GREEN_SIZE |
GLwNaccumBlueSize | GLwCAccumColorSize | int | GLX_ACCUM_BLUE_SIZE |
GLwNaccumAlphaSize | GLwCAccumAlphaSize | int | GLX_ACCUM_ALPHA_SIZE |
以下の表は GLwDrawingArea ウィジェットのその他のリソースを列挙したもの である。それぞれについての詳しい説明は後で述べる。 「アクセス」カラムのコードの意味は以下の通りである: 指定されたリソースが生成時に設定される(C)、 XtSetValues を使って設定される(S)、 XtGetValues を使って取得される(G)、 適用されない(N/A)。
名前 | クラス | 型 | 初期値 | アクセス |
GLwNallocateBackground | GLwCAllocateColors | Boolean | F | CG |
GLwNallocateOtherColors | GLwCAllocateColors | Boolean | F | CG |
GLwNattribList | GLwCAttribList | int * | NULL | CG |
GLwNexposeCallback | GLwCCallback | XtCallbackList | NULL | C |
GLwNginitCallback | GLwCCallback | XtCallbackList | NULL | C |
GLwNinputCallback | GLwCCallback | XtCallbackList | NULL | C |
GLwNinstallBackground | GLwCInstallBackground | Boolean | T | CG |
GLwNinstallColormap | GLwCInstallColormap | Boolean | T | CG |
GLwNresizeCallback | GLwCCallback | XtCallbackList | NULL | C |
GLwNvisualInfo | GLwCVisualInfo | XVisualInfo* | NULL | CG |
これに加えて、Motif 版の GLwMDrawingArea は XmPrimitive も継承している。 色リソースの動作については既に説明した。 このウィジェットでは TraversalOn リソースは無効にされているが、 キーボード入力が必要なら有効にすべきである(また、アプリケーションは ウィジェット内でマウスのボタン 1 が押される度に XmProcessTraversal(widget, XmTRAVERSE_CURRENT) を呼ぶべきである。これは Motif の描画領域で必要なことと同様である)。 Motif は一つのトップレベルシェルが複数個のビジュアルを持つと混乱するの で、XmNhighlightOnEnter は無効にされており、 XmNhighlightThickness には 0 が設定されている。
typedef struct { int reason; XEvent *event; Dimension width, height; } GLwDrawingAreaCallbackStruct;
<KeyDown>: glwInput() <KeyUp>: glwInput() <BtnDown>: glwInput() <BtnUp>: glwInput() <BtnMotion>: glwInput()
GLwMDrawingArea はさらに以下のトランスレーションを持つ:
<Key>osfHelp: PrimitiveHelp()
アプリケーションでデフォルト値以外のイベントを受け取りたければ、 別のトランスレーションテーブルをインストールすることで実現できる。
ウィジェットが最初に生成された時(例えば XtCreateWidget(3X) を使用)、 ウィジェットに対応するウィンドウは自動的には生成されない。 実際にはウィンドウの生成はウィジェットがリアライズするまで待たされる。 しかし、glXchooseVisual はすぐに呼ばれるので、その結果を元にした 情報は利用できる。
ウィジェット生成とリアライズの間は以下のようになる:
ウィジェットがリアライズすると、以下の動作が起きる:
入力コールバックを使ってキーボード入力を受け取る場合、イベント内の キーコードを KeySym に変換しなければならない。 変換には XLookupKeysym(3X) または XLookupString(3X) を使う こと。 キーボード入力はトランスレーションでも扱える。こちらの場合には変換は 不要である。
Motif プログラマは、OSF がキーの仮想割り当てを使っていて、いくつかの キー割り当てを置き換えていることを意識しておくべきである。 一般的な例としては、(GL プログラムでよくするように)ESC キーを使って プログラムを終了させる場合には、トランスレーションには <key>Escape で なく <key>osfCancel を指定すべきである。
Motif プログラマは、Motif スタイルの GLwCreateMDrawingArea を使っ て GLwMDrawingArea を生成してもよい。
#include <stdlib.h> #include <X11/GLw/GLwDrawA.h> static GLXContext glx_context; . . . main() { Arg args[10]; int n; Widget parent; Widget glw; . . . n = 0; XtSetArg(args[n], GLwNrgba, True); n++; glw = XtCreateManagedWidget("glw", glwDrawingAreaWidgetClass, parent, args, n); XtAddCallback(glw, GLwNexposeCallback, exposeCB, NULL); XtAddCallback(glw, GLwNresizeCallback, resizeCB, NULL); XtAddCallback(glw, GLwNginitCallback, ginitCB, NULL); . . . } static void exposeCB(Widget w, XtPointer client_data, GLwDrawingAreaCallbackStruct *call_data) { GLwDrawingAreaMakeCurrent(w, glx_context); } static void resizeCB(Widget w, XtPointer client_data, GLwDrawingAreaCallbackStruct *call_data) { GLwDrawingAreaMakeCurrent(w, glx_context); } static void ginitCB(Widget w, XtPointer client_data, GLwDrawingAreaCallbackStruct *call_data) { Arg args[1]; XVisualInfo *vi; XtSetArg(args[0], GLwNvisualInfo, &vi); XtGetValues(w, args, 1); glx_context = glXCreateContext(XtDisplay(w), vi, NULL, GL_FALSE); GLwDrawingAreaMakeCurrent(w, glx_context); }Motif プログラムで必要となる相違点は、 GLwDrawingArea.h ではなく GLwMDrawingArea.h を使い、 GLwDrawingAreaWidgetClass 型でなく GLwMDrawingAreaWidgetClass 型の ウィジェットを生成することだけである。 これらを行う代わりに、Motif プログラムでは GLwCreateMDraw(3X) を 使ってもよい。
GLwDrawingArea が既にリアライズされているウィジェットの子として生成さ れた場合、GLwDrawingArea は即座に生成され、ユーザには ginit を 追加する機会が与えられない。このような場合には、初期化にはコールバック を使わず、ウィジェット生成の直後に行うべきである。
非 Motif の GLwDrawingArea ウィジェットを Motif プログラムで使い、さら にキーボードの遷移も行う場合には、ユーザが GLwDrawingArea へ遷移した場 合の動作は未定義である。