Xlib.hを探して。

昨晩ヒューマンインタフェースのレポート*1をやろうかと思って、実験第二のGUIのプリントを発掘してきて、プログラム作ってみた。とりあえず、●が動く感じ。一度隠れると●が欠けるとかいう、「イベントって何?」なプログラム。しんぷるいずべすとですよ、とか言い訳てみる。(この下に書こうかと思ったけど、長いので後ろの方に。)
で、それをコンパイルしようと思ったのだけど、新JEDの/usr/X11R6/include/X11にXlib.hが無かったのですよ。それで、Xlib.hを求めてそれっぽい所を探してみたけど、どこにもなぁい、でいつの間にか寝てしまって、気づいたら午後と。そんな土曜日の目覚め。
一晩*2寝て、頭がすっきりしたらしく、findを使う気になって*3検索してみたら、数分であっさり発見。*4

$ find / -name Xlib.h -print > xlib.where
「find: 〜: 許可がありません」がたっぷり。
$ cat xlib.where
/home/staff/xakaike/include/X11/Xlib.h

なぁんだぁ、そんなとこにあったのかぁ、それじゃあ見つからないわけだぁ、…、って、xakaike! いいのかなぁ、勝手に使っても。まぁ、いっか。
libX11.soも近くにあったので、それも含めてこんぱいるぅ。

$ cc hi-3.a-1.c -I/home/staff/xakaike/include -L/home/staff/xakaike/lib/X11 -lX11

後ろに/X11を付けるかどうかで引っかかったり。
とりあえず、出力の方はこんな感じでいいや、後は入力の方をがんばるべさ。

hi-3.a-1.c
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>

// nanosleep用。
#include <time.h>

// gettimeofday用。
#include <sys/time.h>

#define WIDTH 400	 // ウィンドウの幅。
#define HEIGHT 200	 // ウィンドウの高さ。
#define R 10		 // 円の半径。
#define V 5		 // 1回の移動の距離。
#define INTERVAL 300	 // 移動の間隔。(ms)

main(){
  Display *d;
  int screen;
  Window root, window;
  unsigned long black, white;
  XGCValues xgcv;
  GC gc;
  char s[5];
  Window circle[2];	 // 0が右、1が左。
  int cx[2], cy[2];
  struct timespec interval;
  interval.tv_sec = 0;
  interval.tv_nsec = INTERVAL * 1000;

  if( (d = XOpenDisplay( NULL )) == NULL ){
    fprintf( stderr, "can't open display.\n" );
    exit(1);
  }

  screen = DefaultScreen(d);
  root = DefaultRootWindow(d);
  white = WhitePixel(d, screen);
  black = BlackPixel(d, screen);

  window = XCreateSimpleWindow(d, root, 0, 0, WIDTH, HEIGHT, 1, black, white);
  gc = XCreateGC(d, window, 0, NULL);

  cx[0] = WIDTH - 2*R;
  cy[0] = HEIGHT/2 - R;
  cx[1] = WIDTH/2 - 2*R;
  cy[1] = HEIGHT/2 - R;
  circle[0] = XCreateSimpleWindow(d, window, cx[0], cy[0], 2*R, 2*R, 0, black, white);
  circle[1] = XCreateSimpleWindow(d, window, cx[1], cy[1], 2*R, 2*R, 0, black, white);

  XMapWindow(d, window);
  XMapWindow(d, circle[0]);
  XMapWindow(d, circle[1]);
  XFlush(d);
  fgets(s, 5, stdin);

  XFillArc(d, circle[0], gc, 0, 0, 2*R, 2*R, 0, 360*64);
  XFillArc(d, circle[1], gc, 0, 0, 2*R, 2*R, 0, 360*64);

  XFlush(d);
  nanosleep( &interval, NULL );
  int lr = 1;			 // 右向きの時 lr =1, 左向きの時 lr = -1
  int i = 0;			 // 円[i]
  while( 1 ){
    if( cx[0] >= WIDTH-2*R ){
      lr = -1;
    }else if( cx[0] <= WIDTH/2  &&  lr == -1 ){
      i = 1;
    }
    if( cx[1] <= 0 ){
      lr = 1;
    }else if( cx[1] >= WIDTH/2 - 2*R  &&  lr == 1 ){
      i = 0;
    }
    cx[i] += lr * V;

    XMoveWindow(d, circle[0], cx[0], cy[0]);
    XMoveWindow(d, circle[1], cx[1], cy[1]);
    XFlush(d);
    nanosleep( &interval, NULL );
  }
}

おなか空いた。なんか食うか。

*1:hi-3のA-1

*2:晩じゃない気がしないでもない。ロックマンとか見てたし(ぇ。

*3:はじめから使えよ。

*4:以前使った時にものすごく時間がかかったから、それでちょっと躊躇してたってのもあるのだけど。