このアーカイブは同期化されません。 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 メッセージを送ると、
サーバはクリップボードの内容を知っているので、
その内容を貼り付ける処理を行う事ができるのである。