2007 年 1 月 7 日 23 時 58 分

PointerEvent メッセージ


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


今日は PointerEvent メッセージだ。
これは種類 5 番のクライアントメッセージで、
クライアント上でマウス入力が発生した際に送られる。

RFB が取り扱うマウス入力はボタンのクリックと座標移動だ。
そのため、マウスだけでなく、ペンやタッチパネルなど、
ポインティングデバイス全般に対応する事ができる。

このメッセージは 6 バイト固定長で、
以下のような構造を持つ。

    U8 messageType; // 常に 5
    U8 mask; // 押されたボタンの組み合わせ
    U16 x; // X 座標
    U16 y; // Y 座標

mask は押されたボタンの組み合わせだ。
RFB ではボタンの状態を 8 ビットで表現するため、
最大 8 個のボタンを識別する事ができる。
5 個のボタンはその役割が定義済みだが、
残りの 3 個はボタンが多いデバイスで利用可能だ。

では、最初にボタンを表す定数を定義しよう。

=========== PointerEvent.java ===========

package jp.loafer.rfb;

/**
* マウスボタン定数。
* @author kes
*/
public final class MouseButton {
   
    /**
     * 左ボタン。
     */
    static public final int LEFT   = 1 << 0;

    /**
     * 中央ボタン。
     */
    static public final int MIDDLE = 1 << 1;

    /**
     * 右ボタン。
     */
    static public final int RIGHT  = 1 << 2;
   
    /**
     * ホイールマウスの垂直上回転。
     */
    static public final int WHEEL_UP  = 1 << 3;

    /**
     * ホイールマウスの垂直下回転。
     */
    static public final int WHEEL_DOWN = 1 << 4;
   
   
    private MouseButton() {
        //
    }

}

=========== end of PointerEvent.java ===========

では、PointerEvent メッセージのクラスを作ろう。

========== PointerEventMessage.java ==========

package jp.loafer.rfb.message.client;

import java.io.IOException;

import jp.loafer.rfb.RFBContext;
import jp.loafer.rfb.io.RFBInputStream;
import jp.loafer.rfb.io.RFBOutputStream;

/**
* PointerEvent クライアントメッセージ。
* @author kes
*/
public class PointerEventMessage extends BaseClientMessage {

    /**
     * 永続化用既定コンストラクタ。
     */
    public PointerEventMessage() {
        //
    }

    /**
     * PointerEvent メッセージを作成。
     * @param mask ボタンの状態。
     * @param x X 座標。
     * @param y Y 座標。
     */
    public PointerEventMessage(int mask, int x, int y) {
        this.mask = mask;
        this.x = x;
        this.y = y;
    }

    /**
     * ボタンの状態を取得。
     * @return ボタンを表す {@Link MouseButton}.XXX 定数の組み合わせ。
     */
    public int getMask() {
        return mask;
    }

    /**
     * X 座標を取得。
     * @return X 座標。
     */
    public int getX() {
        return x;
    }

    /**
     * Y 座標を取得。
     * @return Y 座標。
     */
    public int getY() {
        return y;
    }
   
    /**
     * @see ClientMessage#getType()
     */
    public int getType() {
        return ClientMessage.POINTER_EVENT;
    }

    /**
     * @see ClientMessage#read(RFBContext, RFBInputStream)
     */
    @Override
    public void read(RFBContext context, RFBInputStream in) throws IOException {
        super.read(context, in);
        mask = in.readU8();
        x = in.readU16();
        y = in.readU16();
       
    }

    /**
     * @see ClientMessage#write(RFBContext, RFBOutputStream)
     */
    @Override
    public void write(RFBContext context, RFBOutputStream out) throws IOException {
        super.write(context, out);
        out.writeU8(mask);
        out.writeU16(x);
        out.writeU16(y);
    }

    private int mask;
    private int x;
    private int y;

}

========== end of KeyEventMessage.java ==========

まあ、こんな所か。

RFB の仕様書には、複数のボタンが同時に押されている時、
どのようなマスク値が渡されるかや、
移動とクリックを識別する方法などは書いていないので、
これらは後で調べる必要があるようである。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.