SewiGの日記
2006-05-27 [土] [長年日記]
■ [Programming] X11プログラミングメモ(1)
とりあえず、ウィンドウを開いてみる。
#include <stdio.h> #include <X11/Xlib.h> #include <X11/Xutil.h> Display *display; Window root, window; int screen; XEvent event; int main(int argc, char *argv[]) { display = XOpenDisplay(NULL); screen = DefaultScreen(display); root = RootWindow(display, screen); window = XCreateSimpleWindow(display, root, 100, 100, 640, 480, 4, BlackPixel(display, screen), WhitePixel(display, window)); XStoreName(display, window, "Hello, X11 world"); Atom atom1, atom2; atom1 = XInternAtom(display, "WM_PROTOCOLS", False); atom2 = XInternAtom(display, "WM_DELETE_WINDOW", False); XSetWMProtocols(display, window, &atom2, 1); XMapWindow(display, window); XFlush(display); XSelectInput(display, window, ExposureMask | ButtonPressMask | UnmapNotify); for(;;) { XNextEvent(display, &event); switch (event.type) { case Expose: break; case ButtonPressMask: if (event.xbutton.button == 1) { XDestroyWindow(display, window); XCloseDisplay(display); exit(0); } break; case ClientMessage: if (event.xclient.message_type == atom1 && event.xclient.data.l[0] == atom2) { XDestroyWindow(display, window); XCloseDisplay(display); exit(0); } } } }
まず、#include <X11/Xlib.h>と#include <X11/Xutil.h>は、お ま じ な い。Xプログラミングでは、XOpenDisplay()によりXサーバに接続するという一見すると大掛かりなことをします。でも複数のDisplayが扱えて弁理だったりします。接続したらディスプレイのIDを取得します。ハンドルみたいなもんです。使い終わったらXCloseDisplay()で閉じます。
そして、Window型にrootとwindowと2つありますが、XにはDisplayごとに1つrootwindowという一番親となるウィンドウがあります。GNOMEや、KDEなんかはrootwindow上でうまく動いています。なのでウィンドウもrootwindowから作成できます。XCreateSimpleWindow()でウィンドウを作成してウィンドウのIDを取得します。
作成したウィンドウはXMapWindow()で表示準備をして、XFlush()でバッファに溜まったメッセージを送信します。
あとはプログラムが終了するまでメッセージ処理をするだけです。使用しないメッセージまで受信したら無駄なのでXSelectInput()で受信したいメッセージを選択します。Exposeでウィンドウの再描画をしたり、ButtonPressMaskでマウスの処理をしたり、ClientMessageでウィンドウに関する処理をします。ほかにもいろんなメッセージがあります。終了するときは、XDestroyWindow()とXCloseDisplay()を使用します。残りのコードは、クローズボックスをクリックされたときの処理です。これが意外に面倒。