コンテンツにスキップ

X Window Programming/イベント

出典: フリー教科書『ウィキブックス(Wikibooks)』

X Window Systemにおいて、「イベント」はアプリケーションとユーザー、または他のプログラムとの間で情報をやり取りするための重要な仕組みです。Xサーバーは、ユーザーの操作やウィンドウの状態変化などのイベントをクライアントプログラムに通知します。本章では、Xのイベントモデルとその処理方法について解説します。

イベントの概要

[編集]

Xのイベントは、Xサーバーからクライアントに送信されるメッセージとして表現されます。これらのイベントには以下のような種類があります:

  • 入力イベント: キーボードやマウスからの入力(例: キー入力、マウスクリック、移動など)。
  • ウィンドウイベント: ウィンドウの状態変化(例: リサイズ、表示、非表示など)。
  • 通知イベント: システムまたは他のクライアントからの通知(例: セレクション通知)。

イベントの種類

[編集]

代表的なイベントの種類を以下に示します:

キーボードイベント

[編集]

キーボード入力に関連するイベントです。

  • KeyPress: キーが押されたときに発生。
  • KeyRelease: キーが離されたときに発生。

マウスイベント

[編集]

マウスの操作に関連するイベントです。

  • ButtonPress: マウスボタンが押されたときに発生。
  • ButtonRelease: マウスボタンが離されたときに発生。
  • MotionNotify: マウスが移動したときに発生。

ウィンドウイベント

[編集]

ウィンドウの状態変化に関連するイベントです。

  • Expose: ウィンドウが再描画される必要があるときに発生。
  • ConfigureNotify: ウィンドウのサイズや位置が変更されたときに発生。
  • MapNotify: ウィンドウがマップされた(表示された)ときに発生。
  • UnmapNotify: ウィンドウがアンマップされた(非表示になった)ときに発生。

クライアント間通信イベント

[編集]

クライアント間でデータをやり取りするためのイベントです。

  • ClientMessage: 他のクライアントから送信されたメッセージ。
  • SelectionNotify: クリップボードや選択内容が変更されたときに発生。

イベントの処理

[編集]

Xクライアントプログラムでは、以下の手順でイベントを処理します。

1. イベントマスクの設定

[編集]

Xクライアントは、受け取るイベントの種類を「イベントマスク」として指定します。イベントマスクはXSelectInput関数を使用して設定します。

XSelectInput(display, window, ExposureMask | KeyPressMask | ButtonPressMask);

この例では、再描画イベント(Expose)、キー押下イベント(KeyPress)、およびボタン押下イベント(ButtonPress)を受け取るよう設定しています。

2. イベントループの作成

[編集]

Xクライアントは、イベントループを使用してサーバーからのイベントを待機し、処理します。

while (1) {
    XEvent event;
    XNextEvent(display, &event);

    switch (event.type) {
        case Expose:
            // 再描画処理
            break;
        case KeyPress:
            // キー入力処理
            break;
        case ButtonPress:
            // ボタン押下処理
            break;
    }
}

3. イベントの内容を取得して処理

[編集]

イベントの内容はXEvent構造体で取得できます。例えば、KeyPressイベントの場合、押下されたキーコードは以下のように取得できます。

KeySym keysym = XLookupKeysym(&event.xkey, 0);
if (keysym == XK_Escape) {
    printf("Escapeキーが押されました\n");
}

イベントのサンプルプログラム

[編集]

以下は、シンプルなイベント処理を行うXプログラムの例です。

#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    // Xサーバーへの接続
    Display *display = XOpenDisplay(NULL);
    if (display == NULL) {
        fprintf(stderr, "Xサーバーに接続できません\n");
        exit(1);
    }

    int screen = DefaultScreen(display);

    // ウィンドウの作成
    Window window = XCreateSimpleWindow(display, RootWindow(display, screen),
                                 10, 10, 800, 600, 1,
                                 BlackPixel(display, screen),
                                 WhitePixel(display, screen));

    // イベントマスクの設定
    XSelectInput(display, window, ExposureMask | KeyPressMask | ButtonPressMask);

    // ウィンドウの表示
    XMapWindow(display, window);

    // イベントループ
    for (;;) {
        XEvent event;
        XNextEvent(display, &event);
        switch (event.type) {
            case Expose:
                printf("ウィンドウが再描画されました\n");
                break;
            case KeyPress:
                if (XLookupKeysym(&event.xkey, 0) == XK_Escape) {
                    printf("Escapeキーが押されました。終了します。\n");
                    XCloseDisplay(display);
                    exit(0);
                }
                break;
            case ButtonPress:
                printf("マウスボタンが押されました\n");
                break;
        }
    }

    return 0;
}

まとめ

[編集]

X Window Systemのイベントモデルは、柔軟で強力なイベント駆動型プログラミングを可能にします。本章で学んだ基本的なイベントの仕組みと処理方法を活用して、インタラクティブなXアプリケーションを構築してください。