2007 年 1 月 8 日 23 時 58 分

ClientCutText メッセージ


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


今日は ClientCutText メッセージだ。
これは種類 6 番のクライアントメッセージで、
クリップボードに含まれるテキストが、
クライアント側の操作により内容が変化した際に送られる。

VNC で遠隔操作をしていると、
VNC の外の画面でコピーしたテキストを、
VNC の中(操作しているサーバ上)に貼り付けたい事がある。

ClientCutText メッセージを使うと、
RFB サーバが知らないところで、
クリップボードの内容が変化したことを通知する事ができる。

このメッセージは可変長で、以下のような構造を持つ。

    U8 messageType; // 常に 6
    U8 reserved[3]; // 3 バイトの詰め物
    String text; // クリップボードの文字列

text には、コピーされた文字列が入る。
仕様書には書いていないが、長さ 0 の文字列を指定すれば、
クリップボードに文字列がなくなった事を示すことになる。

text には複数行の文字列を指定することができるが、
改行コードは、LF (line-feed #10) 単独に正規化する。
例えば Windows クライアントの場合、
CRLF を LF 1 つに変換して送ることになる。

また、これはかなり痛い仕様なのだが、
text に指定できる文字列は、
ISO 8859-1 (Latin 1) で表現できるものだけに限定される。
UTF-8 にすれば良かったのだろうが、
ISO-8859-1 になってしまったため日本語が扱えないのだ。

まあ、文字列の実体はただの U8 の配列なので、
サーバやクライアントによっては ISO-8859-1 ではなく、
システム既定の文字列表現をそのまま乗せることもある。
この場合、両者の仕様が一致すれば、
日本語を通せる可能性は少しはある事になる。

=========== ClientCutText.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;

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

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

    /**
     * ClientCutText メッセージを作成。
     * @param text サーバのクリップボードに送る文字列。
     */
    public ClientCutTextMessage(String text) {
        this.text = text;
    }

    /**
     * 文字列を取得。
     * @return text。
     */
    public String getText() {
        return text;
    }

    /**
     * @see ClientMessage#getType()
     */
    public int getType() {
        return ClientMessage.CLIENT_CUT_TEXT;
    }

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

    /**
     * @see ClientMessage#write(RFBContext, RFBOutputStream)
     */
    @Override
    public void write(RFBContext context, RFBOutputStream out) throws IOException {
        super.write(context, out);
        out.writeU8(0);
        out.writeU8(0);
        out.writeU8(0);
        out.writeString(text);
    }
   
    private String text;

}

========== end of ClientCutText.java ==========

RFB クライアントは、ユーザのクリップボードを監視し、
その内容が変化した際に、ClientCutText を送りだす。

それを受け取った RFB サーバは、
自身のシステムのクリップボードまたは、
サーバでログイン中のユーザのクリップボードを、
クライアントから受け取ったテキストに置き換える。

そして、この後にクライアントが、
「Ctrl + V」等の KeyEvent メッセージを送ると、
サーバはクリップボードの内容を知っているので、
その内容を貼り付ける処理を行う事ができるのである。



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