2007 年 2 月 11 日 23 時 54 分

SetColourMapEntries メッセージ


このアーカイブは同期化されません。 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 による表現を使った場合よりも、
送信するデータが多くなってしまう可能性もある。



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