ログイン
編集不可のページディスカッション情報添付ファイル
"clear/wm_devel/2012-12-14"の差分

MMA
2と3のリビジョン間の差分
2012-12-14 00:47:49時点のリビジョン2
サイズ: 3591
編集者: clear
コメント:
2012-12-14 00:48:52時点のリビジョン3
サイズ: 3714
編集者: clear
コメント:
削除された箇所はこのように表示されます。 追加された箇所はこのように表示されます。
行 12: 行 12:
   * エラーはいきなり天から降ってくる
行 15: 行 16:
    * エラー取得のタイミングを自分で制御できる

XCBの基本

XCBのチュートリアルを見ながら写経。

Xlibと何が違うのか

今のところの理解。

  • Xlibよりダイレクトにプロトコルを操作する
    • 後発だがより低レイヤー
    • ライブラリの実装自体が仕様(xcb-proto)から自動生成されているらしい
  • 同期/非同期の違い
    • Xlib: リクエストに対するレスポンスは同期(リクエストを行う関数の戻り値)、エラー通知は非同期(エラーハンドラ)
      • エラーはいきなり天から降ってくる
    • XCB: リクエストに対して、レスポンスもエラー通知も非同期
      • リクエストを投げる際に関数の戻り値としてcookieを得る
      • cookieを使ってレスポンスあるいはエラーを得る
        • エラー取得のタイミングを自分で制御できる
  • 適切に使えばXlibよりかなり速い
    • ここにある500個のアトム値を作るサンプルだと、手元の環境ではXCBの方が10から20倍速かった

  • そもそも今のXlibはXCBの上に互換レイヤーとして実装されているとかいないとか

矩形を描画するだけの何の面白みもないプログラム

   1 #include <stdio.h>
   2 #include <stdlib.h>
   3 #include <xcb/xcb.h>
   4 
   5 xcb_connection_t *conn;
   6 xcb_screen_t *screen;
   7 xcb_window_t win;
   8 xcb_gcontext_t gc;
   9 
  10 int main(void)
  11 {
  12     int screen_num, i;
  13     xcb_screen_iterator_t iter;
  14     uint32_t mask, values[10];
  15 
  16     conn = xcb_connect(NULL, &screen_num);
  17 
  18     /* get screen information */
  19     iter = xcb_setup_roots_iterator(xcb_get_setup(conn));
  20     for (i = 0; i < screen_num; ++i)
  21         xcb_screen_next(&iter);
  22     screen = iter.data;
  23     puts("screen information:");
  24     printf("%dx%d, root = %x\n", screen->width_in_pixels,
  25         screen->height_in_pixels, screen->root);
  26 
  27     /* create gc */
  28     gc = xcb_generate_id(conn);
  29     mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
  30     values[0] = screen->black_pixel;
  31     values[1] = 0;
  32     xcb_create_gc(conn, gc, screen->root, mask, values);
  33 
  34     /* create window */
  35     win = xcb_generate_id(conn);
  36     mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
  37     values[0] = screen->white_pixel;
  38     values[1] = XCB_EVENT_MASK_EXPOSURE;
  39     xcb_create_window(conn, XCB_COPY_FROM_PARENT,
  40         win, screen->root, 0, 0, 200, 100, 1,
  41         XCB_WINDOW_CLASS_INPUT_OUTPUT,
  42         screen->root_visual, mask, values);
  43 
  44     /* show window */
  45     xcb_map_window(conn, win);
  46     xcb_flush(conn);
  47 
  48     xcb_generic_event_t *event;
  49     while (event = xcb_wait_for_event(conn)) {
  50         /* この~0x80は何なのだろう */
  51         switch (event->response_type & ~0x80) {
  52         case XCB_EXPOSE:
  53             xcb_poly_rectangle(conn, win, gc, 1,
  54                 &(xcb_rectangle_t){ 10, 10, 100, 50 }); /* C99の複合リテラル */
  55             /* どうやらXCBでもリクエストはバッファリングされるらしい
  56                この場合特にバッファをフラッシュする要因が無いようなので、
  57                明示的にxcb_flushしないとリクエストがサーバに送られない = 描画されない */
  58             xcb_flush(conn);
  59             break;
  60         default:
  61             break;
  62         }
  63         free(event);
  64     }
  65     xcb_disconnect(conn);
  66     return 0;
  67 }
  • ウィンドウやGCのためのXIDは先にxcb_generate_idによって自分で作る

  • valuesはただの配列なので値の順序が重要(maskの値の小さい順に並べる)

clear/wm_devel/2012-12-14 (最終更新日時 2013-03-07 16:57:27 更新者 clear)