このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
今日は SetColourMapEntries メッセージだ。
これは種類 1 番のサーバメッセージで、
通信に非 TrueColor の画素表現を使用している際に、
サーバが決定したカラーテーブルの一部または全部を、
クライアントに通知する際に送られる。
このメッセージの役割は、クライアントが送る、
FixColourMapEntries メッセージに似ている。
FixColourMapEntries は、クライアントが、
カラーテーブルの一部を固定(強制指定)するためにあるが、
SetColourMapEntries はサーバがカラーテーブルを決定する。
サーバが画面データを非 TrueColor で送信する場合、
インデックスカラーにマッピングする必要があるのだが、
事前に FixColourMapEntries で固定されていない限りは、
サーバはカラーテーブルを好きに編集することができる。
このメッセージは可変長で、以下のような構造を持つ。
FixColourMapEntries メッセージと同じ構造だ。
U8 messageType; // 常に 1
U8 reserved; // 1 バイトの詰め物
U16 firstColor; // 範囲の最初のインデックス
U16 count; // メッセージに含まれる色の数
ColorEntry colors[]; // カラーテーブル
firstColor と count は、カラーテーブルの
どの部分を固定するかどうかを示している。
firstIndex = 10, count = 4 ならば、
カラーテーブルの 10 番から 13 番までを示すことになる。
colors 配列には count の数の色情報が入る。
ColorEntry は、RGB 各 U16 で構成される組み合わせだ。
このクラスは、FixColourMapEntries の時に定義した。
http://mixi.jp/view_diary.pl?id=314992260&owner_id=2300658
では、メッセージクラスを作る。
========== SetColorMapEntriesMessage.java ==========
package jp.loafer.rfb.message.server;
import java.io.IOException;
import java.util.Arrays;
import jp.loafer.rfb.RFBContext;
import jp.loafer.rfb.io.RFBInputStream;
import jp.loafer.rfb.io.RFBOutputStream;
import jp.loafer.rfb.message.ColorEntry;
/**
* SetColourMapEntries サーバメッセージ。
* @author kes
*/
public class SetColorMapEntriesMessage extends BaseServerMessage {
/**
* 永続化用既定コンストラクタ。
*/
public SetColorMapEntriesMessage() {
//
}
/**
* SetColorMapEntries メッセージを作成。
* @param firstIndex カラーテーブルが示す色の最初のインデックス。
* @param colors カラーテーブルの配列。
*/
public SetColorMapEntriesMessage(int firstIndex, ColorEntry[] colors) {
this.firstIndex = firstIndex;
this.colors = colors;
}
/**
* カラーテーブルが示す色の最初のインデックスを取得。
* @return 最初のインデックス。
*/
public int getFirstIndex() {
return firstIndex;
}
/**
* カラーテーブルの配列を取得。
* @return カラーテーブルの配列。
*/
public ColorEntry[] getColors() {
return colors.clone();
}
/**
* カラーテーブルの要素を取得。
* インデックスは {@link #getFirstIndex()} の値に関係なく 0 を基準とする。
* @param index 0 ベースのインデックス。
* @return カラーテーブルの要素。
*/
public ColorEntry getColors(int index) {
return colors[index];
}
/**
* @see ServerMessage#getType()
*/
public int getType() {
return ServerMessage.SET_COLOR_MAP_ENTRIES;
}
/**
* @see ServerMessage#read(RFBContext, RFBInputStream)
*/
@Override
public void read(RFBContext context, RFBInputStream in) throws IOException {
super.read(context, in);
in.readU8();
int length = in.readU16();
colors = new ColorEntry[length];
for (int i = 0; i < length; ++i) {
colors[i] = in.readMessage(context, ColorEntry.class);
}
}
/**
* @see ServerMessage#write(RFBContext, RFBOutputStream)
*/
@Override
public void write(RFBContext context, RFBOutputStream out) throws IOException {
super.write(context, out);
out.writeU8(0);
out.writeU16(colors.length);
for (int i = 0; i < colors.length; ++i) {
out.writeMessage(context, colors[i]);
}
}
/**
* @see Object#toString()
*/
@Override
public String toString() {
return getClass().getName()
+ "[firstIndex=" + firstIndex
+ ",colors=" + Arrays.toString(colors) + "]";
}
private int firstIndex;
private ColorEntry[] colors;
}
========== end of SetColorMapEntriesMessage.java ==========
FixColourMapEntries とほとんど同じだ。
このメッセージは FixColourMapEntries と違い、
RFB 3.8 でも非推奨とはなっていない。
とはいうものの、サーバのカラーテーブルが変われば、
既にクライアントが受信した画面データに影響を及ぼす上に、
クライアント側の実装が複雑になるため、
カラーテーブルをサポートしないクライアントもあるため、
このメッセージや非 TrueColor はあまり使われていない。
また、画面にもよるが、最悪全体を再描画する必要が生じ、
結果的にTrueColor による表現を使った場合よりも、
送信するデータが多くなってしまう可能性もある。