線を引く

対角線を引きます.

0001: /*
0002:   drawline-x.c
0003:   gcc drawline-x.c -I/usr/X11R6/include -L/usr/X11R6/lib -lX11
0004: */
0005: 
0006: #include <X11/Xlib.h>
0007: 
0008: int main( int argc, char *argv[] )
0009: {
0010:   Display *dpy;
0011:   int screen;
0012:   Window win;
0013:   GC gc;
0014:   
0015:   dpy = XOpenDisplay( NULL );  /* Xサーバに接続する */
0016: 
0017:   screen = DefaultScreen( dpy );  /* スクリーン設定 */
0018:   
0019:   win = XCreateSimpleWindow(   /* ウィンドウを開く */
0020:           dpy,                      /* Xサーバ */
0021:           RootWindow(dpy,screen),   /* 親ウィンドウ */
0022:           0, 0,                     /* 表示時の左上隅の座標 x, y */
0023:           256, 256,                 /* ウィンドウの幅と高さ */
0024:           1, BlackPixel(dpy,screen),/* ボーダーの幅と色 */
0025:           WhitePixel(dpy,screen)    /* ウィンドウの背景色 */
0026:           );
0027: 
0028:   XMapWindow( dpy, win );  /* ウィンドウのマッピング */
0029:   XFlush( dpy );  /* バッファのフラッシュ */
0030: 
0031:   gc = DefaultGC( dpy, screen ); /* グラフィックコンテキストの設定 */
0032:   XSetForeground( dpy, gc, BlackPixel(dpy,screen) ); /* 描画色設定 */
0033:   XDrawLine( dpy, win, gc, 0, 0, 256, 256 ); /* 線を描く */
0034:   XFlush( dpy );  /* バッファのフラッシュ */
0035:   
0036:   sleep( 10 );  /* 10秒間表示を保持 */
0037:   XDestroyWindow( dpy, win ); /* ウインドウの開放 */
0038:   XCloseDisplay( dpy );  /* Xサーバを切断する */
0039: 
0040:   return 0;
0041: }

ウインドウを開くプログラムに5行増えただけです.

0013:   GC gc;

GCはGraphics Context といい,描画属性を保持す るリソースです.WindowがキャンバスならばGCは筆や鉛筆などのセットに相当します.

0031:   gc = DefaultGC( dpy, screen ); /* グラフィックコンテキストの設定 */
0032:   XSetForeground( dpy, gc, BlackPixel(dpy,screen) ); /* 描画色設定 */
0033:   XDrawLine( dpy, win, gc, 0, 0, 256, 256 ); /* 線を描く */
0034:   XFlush( dpy );  /* バッファのフラッシュ */

       GC DefaultGC(display, screen_number)
             Display *display,
             intscreen_number;

DefaultGCは,display上のscreen_number におけるデフォルトGCを取得するためのマクロです.

       int XSetForeground(display, gc, foreground)
             Display *dpy,
             GC gc,
             unsigned long foreground;

XSetForegroundは描画色を設定します.gcで指定した属性を持つ筆に絵の具をつける感じでしょ うか.色はforegroundにピクセル値を与えます. ここでは,既に使ったマクロBlackPixelで黒色 を指定しています.

       int XDrawLine(display, d, gc, x1, y1, x2, y2)
             Display *dpy,
             Drawable d,
             GC gc,
             int x1, y1, x2, y2;

XDrawLineDrawablegcの属性で線分を 引きます.ここでDrawableとは文字どおり描画可能 なもので,具体的にはWindowまたはPixmapが指定できます.x1, y1が線分の始点,x2, y2が終点になります.

XFlushで実際に描画されます.

さて,対角線が引かれなかった,という人はいないでしょうか? ウインドウマネー ジャが介入した場合,29行目のXFlushの時点で 即座にウインドウが表示されない場合があります.例えば,ウインドウの枠がゴー スト状態で,位置を決められるのを待っている場合などです.この時,ウインド ウはマップされていませんが,ウインドウの実体は存在します.そして,マップ されていないウインドウへの描画リクエストは無視されてしまいます.

さらに,ウインドウが自分で持っているのは背景だけで,その上に描かれたもの は覚えていません.そのため,画面に現れた時は背景を表示します.今回,線の 描画は一回きりしかしていませんので,ウインドウがマップされた後に描かれる と線は見えますが,その前に描いてしまうと,マップされた時には背景だけになっ てしまいます.このことは他のウインドウによって隠された場合も同様で,隠さ れた部分がまた見えるようになった時には背景しか復活しません.

描いたはずのものが消えてしまうのを解決するにはどうすればいいかというと,

  1. ウインドウがマップされてから描く
  2. バッキングストアを使う
  3. 消えたら描き直す

という方法があります.しかし,1.は書いた後に他のウインドウに消される可能 性がありますし,2.は全てのサーバが持っている機能ではありません.結局は3. に行き着くのですが,いずれにせよ,「イベント」について理解する必要があ ります.

Back to TOP