はじめに

編集

X Window System (X11) は、Unix系オペレーティングシステム上でグラフィカルユーザーインターフェース (GUI) を提供する基盤システムです。本ガイドでは、現代のX11プログラミングにおいて推奨される XCB (X protocol C-language Binding) を使用したアプローチを解説します。

なぜXCBか

編集

従来のXlibに代わり、XCBが推奨される理由は以下の通りです:

  • 軽量で効率的なプロトコル実装
  • 非同期操作のより良いサポート
  • スレッドセーフな設計
  • 明確なAPIと予測可能な動作
  • モダンなX11アプリケーション開発における事実上の標準

基本的なXCBプログラミング

編集

最初のウィンドウを作成する

編集

以下は、XCBを使用して基本的なウィンドウを作成する例です:

#include <xcb/xcb.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    // X サーバーへの接続を確立
    xcb_connection_t *conn = xcb_connect(NULL, NULL);
    if (xcb_connection_has_error(conn)) {
        fprintf(stderr, "X サーバーへの接続に失敗しました\n");
        return 1;
    }

    // スクリーン情報の取得
    const xcb_setup_t *setup = xcb_get_setup(conn);
    xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
    xcb_screen_t *screen = iter.data;

    // ウィンドウの作成
    xcb_window_t window = xcb_generate_id(conn);
    uint32_t mask = XCB_CW_BACK_PIXEL || XCB_CW_EVENT_MASK;
    uint32_t values[2] = {
        screen->white_pixel,
        XCB_EVENT_MASK_EXPOSURE || XCB_EVENT_MASK_KEY_PRESS
    };

    xcb_create_window(conn,
                     XCB_COPY_FROM_PARENT,    // depth
                     window,                   // ウィンドウID
                     screen->root,            // 親ウィンドウ
                     0, 0,                    // x, y
                     400, 300,                // width, height
                     0,                       // border width
                     XCB_WINDOW_CLASS_INPUT_OUTPUT,
                     screen->root_visual,
                     mask, values);

    // ウィンドウのマッピング(表示)
    xcb_map_window(conn, window);
    xcb_flush(conn);

    // イベントループ
    xcb_generic_event_t *event;
    while ((event = xcb_wait_for_event(conn))) {
        switch (event->response_type & ~0x80) {
            case XCB_EXPOSE:
                // 描画処理をここに
                break;
            case XCB_KEY_PRESS:
                free(event);
                goto cleanup;
        }
        free(event);
    }

cleanup:
    xcb_disconnect(conn);
    return 0;
}

このコードは以下の手順で動作します:

  1. XCBを使用してXサーバーに接続
  2. スクリーン情報の取得
  3. 新しいウィンドウの作成
  4. イベントマスクの設定
  5. ウィンドウの表示
  6. イベントループの実行

グラフィックスの描画

編集

XCBでは、グラフィックス描画も効率的に行えます。以下は基本的な描画操作の例です:

void draw_rectangle(xcb_connection_t *conn, xcb_window_t window, 
                   int16_t x, int16_t y, uint16_t width, uint16_t height) {
    xcb_gcontext_t gc = xcb_generate_id(conn);
    uint32_t mask = XCB_GC_FOREGROUND || XCB_GC_LINE_WIDTH;
    uint32_t values[2] = {0x000000, 1};  // 黒色、線幅1

    xcb_create_gc(conn, gc, window, mask, values);
    xcb_rectangle_t rect = {x, y, width, height};
    xcb_poly_rectangle(conn, window, gc, 1, &rect);
    xcb_flush(conn);
    xcb_free_gc(conn, gc);
}

イベント処理

編集

XCBのイベント処理は非同期で効率的です:

void handle_events(xcb_connection_t *conn, xcb_window_t window) {
    xcb_generic_event_t *event;
    
    while ((event = xcb_wait_for_event(conn))) {
        switch (event->response_type & ~0x80) {
            case XCB_BUTTON_PRESS: {
                xcb_button_press_event_t *bp = (xcb_button_press_event_t *)event;
                printf("マウスクリック: (%d, %d)\n", bp->event_x, bp->event_y);
                break;
            }
            case XCB_KEY_PRESS: {
                xcb_key_press_event_t *kp = (xcb_key_press_event_t *)event;
                printf("キー押下: keycode = %d\n", kp->detail);
                break;
            }
            case XCB_EXPOSE: {
                // 再描画処理
                break;
            }
        }
        free(event);
    }
}

モダンなGUIアプリケーション開発

編集

実践的なアプリケーション開発では、以下のアプローチを推奨します:

  1. コンポーネント指向設計: ウィジェットやコントロールを再利用可能なコンポーネントとして実装
  2. 非同期イベント処理: XCBの非同期機能を活用し、レスポンシブなUIを実現
  3. エラー処理: 適切なエラーチェックとリソース管理
  4. モダンなツールキットとの統合: GTK4やQt6などの現代的なツールキットとの連携

コンパイルと実行

編集

XCBプログラムのコンパイル:

clang -o program program.c -lxcb

まとめ

編集

現代のX11プログラミングでは、XCBを使用することで効率的で保守性の高いコードを書くことができます。本ガイドで示したアプローチを基に、実際のアプリケーション開発に活かしてください。