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()を使用します。残りのコードは、クローズボックスをクリックされたときの処理です。これが意外に面倒。