changeset 59:433c79184c05

merge version2.7.2
author Taninari YU <you@cr.ie.u-ryukyu.ac.jp>
date Tue, 17 Dec 2013 20:16:48 +0900
parents 9d4c4b64acb5 (current diff) 913d0f663e74 (diff)
children ac6f9e46566f
files .DS_Store .classpath .gradle/1.4/taskArtifacts/fileHashes.bin .gradle/1.4/taskArtifacts/outputFileStates.bin build.gradle build/libs/tightvnc-jviewer.jar build/resources/main/com/glavsoft/viewer/images/button-alt.png build/resources/main/com/glavsoft/viewer/images/button-close.png build/resources/main/com/glavsoft/viewer/images/button-ctrl-alt-del.png build/resources/main/com/glavsoft/viewer/images/button-ctrl.png build/resources/main/com/glavsoft/viewer/images/button-file-transfer.png build/resources/main/com/glavsoft/viewer/images/button-fullscreen.png build/resources/main/com/glavsoft/viewer/images/button-info.png build/resources/main/com/glavsoft/viewer/images/button-new-connection.png build/resources/main/com/glavsoft/viewer/images/button-options.png build/resources/main/com/glavsoft/viewer/images/button-rec.png build/resources/main/com/glavsoft/viewer/images/button-refresh.png build/resources/main/com/glavsoft/viewer/images/button-save.png build/resources/main/com/glavsoft/viewer/images/button-win.png build/resources/main/com/glavsoft/viewer/images/button-zoom-100.png build/resources/main/com/glavsoft/viewer/images/button-zoom-fit.png build/resources/main/com/glavsoft/viewer/images/button-zoom-in.png build/resources/main/com/glavsoft/viewer/images/button-zoom-out.png build/resources/main/com/glavsoft/viewer/images/tightvnc-logo-16x16.png build/resources/main/com/glavsoft/viewer/images/tightvnc-logo-32x32.png build/tmp/jar/MANIFEST.MF src/main/java/com/glavsoft/drawing/AbstructRenderer.java src/main/java/com/glavsoft/drawing/Renderer.java src/main/java/com/glavsoft/rfb/RfbCapabilityInfo.java src/main/java/com/glavsoft/rfb/client/FramebufferUpdateRequestMessage.java src/main/java/com/glavsoft/rfb/encoding/EncodingType.java src/main/java/com/glavsoft/rfb/encoding/ServerInitMessage.java src/main/java/com/glavsoft/rfb/encoding/decoder/DecodersContainer.java src/main/java/com/glavsoft/rfb/encoding/decoder/FramebufferUpdateRectangle.java src/main/java/com/glavsoft/rfb/encoding/decoder/TightDecoder.java src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java src/main/java/com/glavsoft/rfb/encoding/decoder/ZlibDecoder.java src/main/java/com/glavsoft/rfb/protocol/NullRenderer.java src/main/java/com/glavsoft/rfb/protocol/Protocol.java src/main/java/com/glavsoft/rfb/protocol/ProtocolContext.java src/main/java/com/glavsoft/rfb/protocol/ProtocolSettings.java src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java src/main/java/com/glavsoft/rfb/protocol/auth/SecurityType.java src/main/java/com/glavsoft/rfb/protocol/state/HandshakeState.java src/main/java/com/glavsoft/rfb/protocol/state/InitState.java src/main/java/com/glavsoft/transport/Reader.java src/main/java/com/glavsoft/transport/Writer.java src/main/java/jp/ac/u_ryukyu/treevnc/MyRfbProto.java src/main/java/jp/ac/u_ryukyu/treevnc/client/EchoClient.java src/main/java/jp/ac/u_ryukyu/treevnc/client/MyVncClient.java src/main/java/jp/ac/u_ryukyu/treevnc/client/WaitReply.java src/main/java/jp/ac/u_ryukyu/treevnc/server/VncProxyService.java src/viewer_swing/java/com/glavsoft/viewer/TreeConnectionManager.java src/viewer_swing/java/com/glavsoft/viewer/Viewer.java src/viewer_swing/java/com/glavsoft/viewer/swing/ParametersHandler.java src/viewer_swing/java/com/glavsoft/viewer/swing/RendererImpl.java src/viewer_swing/java/com/glavsoft/viewer/swing/Surface.java
diffstat 83 files changed, 4698 insertions(+), 73 deletions(-) [+]
line wrap: on
line diff
Binary file .DS_Store has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.classpath	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/main/java"/>
+	<classpathentry kind="src" path="src/viewer_swing/java"/>
+	<classpathentry kind="src" path="src/viewer_swing/resources"/>
+	<classpathentry exported="true" kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry kind="lib" path="/Users/you/temp/TreeViewer2/src/libs/jsch-0.1.50.jar"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk7u6"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
Binary file .gradle/1.4/taskArtifacts/fileHashes.bin has changed
Binary file .gradle/1.4/taskArtifacts/outputFileStates.bin has changed
--- a/.settings/org.eclipse.jdt.core.prefs	Mon Dec 16 17:06:19 2013 +0900
+++ b/.settings/org.eclipse.jdt.core.prefs	Tue Dec 17 20:16:48 2013 +0900
@@ -1,13 +1,11 @@
-#
-#Sun Jun 24 14:19:09 JST 2012
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
 eclipse.preferences.version=1
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
 org.eclipse.jdt.core.compiler.source=1.6
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Todo.txt	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,11 @@
+Wed Aug 29 23:32:36 JST 2012
+
+  ReceiverTask の framebufferUpdateMessage を、TreeTask に再現しないとだめ。
+
+Wed Aug 29 22:27:25 JST 2012
+
+  MyRfbProxy の os が初期化されていない (削除する方が良い)
+
+  initData が null ( 設定された時に、設定するべき)
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WifiBroadCast.mm	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,58 @@
+<map version="0.9.0">
+<!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net -->
+<node CREATED="1375862208091" ID="ID_1435980750" MODIFIED="1375862329668" TEXT="WifiBroadCast">
+<node CREATED="1375862227074" ID="ID_1671888494" MODIFIED="1375862235198" POSITION="right" TEXT="&#x5b9f;&#x9a13;&#x306e;&#x76ee;&#x7684;">
+<node CREATED="1375862255760" ID="ID_159564438" MODIFIED="1375862324968" TEXT="TreeVNC&#x306b;Multicast&#x304c;&#x4f7f;&#x7528;&#x3067;&#x304d;&#x308b;&#x304b;&#x3069;&#x3046;&#x304b;&#x3092;&#x8abf;&#x3079;&#x308b;"/>
+</node>
+<node CREATED="1375862332655" ID="ID_675436470" MODIFIED="1375862894097" POSITION="left" TEXT="&#x5b9f;&#x9a13;&#x898f;&#x6a21;">
+<node CREATED="1375862337823" ID="ID_1026201136" MODIFIED="1375862805948" TEXT="&#x7121;&#x7dda;&#x30b9;&#x30c6;&#x30fc;&#x30b7;&#x30e7;&#x30f3;&#xff08;802.11a/g/b)&#xff09;">
+<node CREATED="1375862792648" ID="ID_1054538330" MODIFIED="1375862800938" TEXT="AirStation"/>
+<node CREATED="1375862807503" ID="ID_1441557306" MODIFIED="1375862824694" TEXT="AirMacStation"/>
+</node>
+<node CREATED="1375862422679" ID="ID_187514466" MODIFIED="1375862643954" TEXT="&#x30af;&#x30e9;&#x30a4;&#x30a2;&#x30f3;&#x30c8;&#x6570;">
+<node CREATED="1375862437097" ID="ID_1909771864" MODIFIED="1375862454492" TEXT="iMac"/>
+<node CREATED="1375862455240" ID="ID_1182721233" MODIFIED="1375862459019" TEXT="Mac pro"/>
+<node CREATED="1375862460975" ID="ID_60013417" MODIFIED="1375862471852" TEXT="Mac mini * 3"/>
+<node CREATED="1375862472495" ID="ID_848088782" MODIFIED="1375862483276" TEXT="Mac Book Pro * 10"/>
+</node>
+<node CREATED="1375862628620" ID="ID_1279234975" MODIFIED="1375862638705" TEXT="&#x76ee;&#x6a19;&#x6570;">
+<node CREATED="1375862694318" ID="ID_711725119" MODIFIED="1375862773148" TEXT="70(321&#x306e;&#x5b66;&#x751f;&#x6570;)"/>
+</node>
+<node CREATED="1375862895728" ID="ID_1713124083" MODIFIED="1375862931230" TEXT="&#x96fb;&#x6ce2;&#x306e;&#x72b6;&#x6cc1;">
+<node CREATED="1375862964723" ID="ID_248823562" MODIFIED="1375862987663" TEXT="&#x59a8;&#x5bb3;&#x96fb;&#x6ce2;&#x306e;&#x3042;&#x308b;&#x306a;&#x3057;"/>
+<node CREATED="1375863003123" ID="ID_1972998265" MODIFIED="1375863008536" TEXT="&#x30c8;&#x30e9;&#x30d5;&#x30a3;&#x30c3;&#x30af;&#x72b6;&#x6cc1;"/>
+<node CREATED="1375863024852" ID="ID_1727488162" MODIFIED="1375863121139" TEXT="&#x5834;&#x6240;(321&#x3068;611&#x3068;406)"/>
+</node>
+</node>
+<node CREATED="1375863131964" ID="ID_497519094" MODIFIED="1375863136962" POSITION="right" TEXT="&#x5b9f;&#x9a13;&#x5185;&#x5bb9;">
+<node CREATED="1375863157718" ID="ID_587883160" MODIFIED="1375863216132" TEXT="&#x30d1;&#x30b1;&#x30c3;&#x30c8;&#x306e;&#x30b5;&#x30a4;&#x30ba;(128byte~512Kbyte&#x307e;&#x3067;)"/>
+<node CREATED="1375863239656" ID="ID_1702750962" MODIFIED="1375863257171" TEXT="&#x30d1;&#x30b1;&#x30c3;&#x30c8;&#x306e;&#x500b;&#x6570;(10~100)"/>
+<node CREATED="1375863257798" ID="ID_1454190239" MODIFIED="1375863265065" TEXT="&#x30d7;&#x30ed;&#x30c8;&#x30b3;&#x30eb;">
+<node CREATED="1375863265066" ID="ID_763089742" MODIFIED="1375863272539" TEXT="Broadcast">
+<node CREATED="1375865442473" ID="ID_1358563788" MODIFIED="1375865453726" TEXT="&#xff13;"/>
+</node>
+<node CREATED="1375863273327" ID="ID_793864869" MODIFIED="1375865397800" TEXT="Multicast">
+<node CREATED="1375865397801" ID="ID_237048050" MODIFIED="1375865434158" TEXT="&#xff11;"/>
+</node>
+<node CREATED="1375863277191" ID="ID_677403240" MODIFIED="1375863279251" TEXT="TCP">
+<node CREATED="1375865422433" ID="ID_649935149" MODIFIED="1375865427182" TEXT="&#xff12;"/>
+</node>
+</node>
+<node CREATED="1375863294783" ID="ID_339954849" MODIFIED="1375863299829" TEXT="&#x6e2c;&#x5b9a;">
+<node CREATED="1375863303683" ID="ID_1050197818" MODIFIED="1375863308509" TEXT="&#x30d1;&#x30b1;&#x30c3;&#x30c8;&#x30ed;&#x30b9;&#x30c8;&#x7387;">
+<node CREATED="1375864091904" ID="ID_795745337" MODIFIED="1375864099068" TEXT="PC&#x5074;"/>
+<node CREATED="1375864099471" ID="ID_224074828" MODIFIED="1375864645981" TEXT="Switch&#x5074;"/>
+</node>
+<node CREATED="1375863309121" ID="ID_76819691" MODIFIED="1375863345502" TEXT="&#x30b9;&#x30eb;&#x30fc;&#x30d7;&#x30c3;&#x30c8;"/>
+<node CREATED="1375864647755" ID="ID_1762535066" MODIFIED="1375864653726" TEXT="&#x30d0;&#x30c3;&#x30d5;&#x30a1;&#x306e;&#x5927;&#x304d;&#x3055;"/>
+</node>
+</node>
+<node CREATED="1375864918215" ID="ID_1961357787" MODIFIED="1375864933425" POSITION="right" TEXT="TreeVNC&#x306e;&#x5909;&#x66f4;">
+<node CREATED="1375864933426" ID="ID_1171105144" MODIFIED="1375865060269" TEXT="Blocking(64K~)">
+<node CREATED="1375865060270" ID="ID_1594748367" MODIFIED="1375865064727" TEXT="&#x901f;&#x5ea6;"/>
+<node CREATED="1375865521003" ID="ID_1497362366" MODIFIED="1375865525104" TEXT="&#x4e26;&#x5217;&#x5316;"/>
+<node CREATED="1375865731959" ID="ID_1664410067" MODIFIED="1375865897884" TEXT="&#x5727;&#x7e2e;&#x306b;&#x4e92;&#x63db;&#x6027;&#x306e;&#x3042;&#x308b;&#x30a2;&#x30eb;&#x30b4;&#x30ea;&#x30ba;&#x30e0;&#x3092;&#x66f8;&#x304f;"/>
+</node>
+</node>
+</node>
+</map>
Binary file build/libs/tightvnc-jviewer.jar has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-alt.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-close.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-ctrl-alt-del.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-ctrl.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-file-transfer.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-fullscreen.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-info.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-new-connection.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-options.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-rec.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-refresh.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-save.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-win.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-zoom-100.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-zoom-fit.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-zoom-in.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/button-zoom-out.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/tightvnc-logo-16x16.png has changed
Binary file build/resources/main/com/glavsoft/viewer/images/tightvnc-logo-32x32.png has changed
--- a/build/tmp/jar/MANIFEST.MF	Mon Dec 16 17:06:19 2013 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-Manifest-Version: 1.0
-Main-Class: com.glavsoft.viewer.Viewer
-Implementation-Version: 2.5.0
-
Binary file doc/change VNCServer1.asta has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/com/glavsoft/drawing/AbstructRenderer.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,299 @@
+package com.glavsoft.drawing;
+
+import java.util.Arrays;
+
+import com.glavsoft.exceptions.TransportException;
+import com.glavsoft.rfb.encoding.PixelFormat;
+import com.glavsoft.rfb.encoding.decoder.FramebufferUpdateRectangle;
+import com.glavsoft.transport.Reader;
+
+public abstract class AbstructRenderer extends Renderer {
+
+	protected Reader reader;
+
+	public abstract void drawJpegImage(byte[] bytes, int offset,
+			int jpegBufferLength, FramebufferUpdateRectangle rect);
+
+	protected int width;
+	protected int height;
+	protected int bytesPerPixel;
+	protected int bytesPerPixelSignificant;
+	protected int[] pixels;
+	protected SoftCursor cursor;
+	protected PixelFormat pixelFormat;
+	private ColorDecoder colorDecoder;
+
+	protected void init(Reader reader, int width, int height, PixelFormat pixelFormat) {
+		this.reader = reader;
+		this.width = width;
+		this.height = height;
+		initPixelFormat(pixelFormat);
+		pixels = new int[width * height];
+		Arrays.fill(pixels, 0);
+	}
+
+	public synchronized void initPixelFormat(PixelFormat pixelFormat) {
+		this.pixelFormat = pixelFormat;
+		bytesPerPixel = pixelFormat.bitsPerPixel / 8;
+		bytesPerPixelSignificant =
+				24 == pixelFormat.depth && 32 == pixelFormat.bitsPerPixel ? 3 : bytesPerPixel;
+		colorDecoder = new ColorDecoder(pixelFormat);
+	}
+
+	/**
+	 * Draw byte array bitmap data
+	 *
+	 * @param bytes bitmap data
+	 * @param x bitmap x position
+	 * @param y bitmap y position
+	 * @param width bitmap width
+	 * @param height bitmap height
+	 */
+	public void drawBytes(byte[] bytes, int x, int y, int width, int height) {
+		int i = 0;
+		for (int ly = y; ly < y + height; ++ly) {
+			int end = ly * this.width + x + width;
+			for (int pixelsOffset = ly * this.width + x; pixelsOffset < end; ++pixelsOffset) {
+				pixels[pixelsOffset] = getPixelColor(bytes, i);
+				i += bytesPerPixel;
+			}
+		}
+	}
+
+	/**
+	 * Draw byte array bitmap data (for ZRLE)
+	 */
+	public synchronized int  drawCompactBytes(byte[] bytes, int offset, int x, int y, int width, int height) {
+		int i = offset;
+		for (int ly = y; ly < y + height; ++ly) {
+			int end = ly * this.width + x + width;
+			for (int pixelsOffset = ly * this.width + x; pixelsOffset < end; ++pixelsOffset) {
+				pixels[pixelsOffset] = getCompactPixelColor(bytes, i);
+				i += bytesPerPixelSignificant;
+			}
+		}
+		return i - offset;
+	}
+
+	/**
+	 * Draw int (colors) array bitmap data (for ZRLE)
+	 */
+	public synchronized void  drawColoredBitmap(int[] colors, int x, int y, int width, int height) {
+		int i = 0;
+		for (int ly = y; ly < y + height; ++ly) {
+			int end = ly * this.width + x + width;
+			for (int pixelsOffset = ly * this.width + x; pixelsOffset < end; ++pixelsOffset) {
+				pixels[pixelsOffset] = colors[i++];
+			}
+		}
+	}
+
+	/**
+	 * Draw byte array bitmap data (for Tight)
+	 */
+	public synchronized int drawTightBytes(byte[] bytes, int offset, int x, int y, int width, int height) {
+		int i = offset;
+		for (int ly = y; ly < y + height; ++ly) {
+			int end = ly * this.width + x + width;
+			for (int pixelsOffset = ly * this.width + x; pixelsOffset < end; ++pixelsOffset) {
+				pixels[pixelsOffset] = colorDecoder.getTightColor(bytes, i);
+				i += bytesPerPixelSignificant;
+			}
+		}
+		return i - offset;
+	}
+
+	/**
+	 * Draw byte array bitmap data (from array with plain RGB color components. Assumed)
+	 */
+	public synchronized void drawUncaliberedRGBLine(byte[] bytes, int x, int y, int width) {
+		int end = y * this.width + x + width;
+		for (int i=3, pixelsOffset = y * this.width + x; pixelsOffset < end; ++pixelsOffset) {
+			pixels[pixelsOffset] =
+//					(0xff & bytes[i++]) << 16 |
+//					(0xff & bytes[i++]) << 8 |
+//					0xff & bytes[i++];
+					(0xff & 255 * (colorDecoder.redMax & bytes[i++]) / colorDecoder.redMax) << 16 |
+					(0xff & 255 * (colorDecoder.greenMax & bytes[i++]) / colorDecoder.greenMax) << 8 |
+					0xff & 255 * (colorDecoder.blueMax & bytes[i++]) / colorDecoder.blueMax;
+		}
+	}
+
+	/**
+	 * Draw paletted byte array bitmap data
+	 *
+	 * @param buffer bitmap data
+	 * @param rect bitmap location and dimensions
+	 * @param palette colour palette
+	 */
+	public synchronized void drawBytesWithPalette(byte[] buffer, FramebufferUpdateRectangle rect,
+			int[] palette) {
+				// 2 colors
+				if (palette.length == 2) {
+					int dx, dy, n;
+					int i = rect.y * this.width + rect.x;
+					int rowBytes = (rect.width + 7) / 8;
+					byte b;
+
+					for (dy = 0; dy < rect.height; dy++) {
+						for (dx = 0; dx < rect.width / 8; dx++) {
+							b = buffer[dy * rowBytes + dx];
+							for (n = 7; n >= 0; n--) {
+								pixels[i++] = palette[b >> n & 1];
+							}
+						}
+						for (n = 7; n >= 8 - rect.width % 8; n--) {
+							pixels[i++] = palette[buffer[dy * rowBytes + dx] >> n & 1];
+						}
+						i += this.width- rect.width;
+					}
+				} else {
+					// 3..255 colors (assuming bytesPixel == 4).
+					int i = 0;
+					for (int ly =  rect.y; ly < rect.y + rect.height; ++ly) {
+						for (int lx = rect.x; lx < rect.x + rect.width; ++lx) {
+							int pixelsOffset = ly * this.width + lx;
+							pixels[pixelsOffset] = palette[buffer[i++] & 0xFF];
+						}
+					}
+				}
+
+			}
+
+	/**
+	 * Copy rectangle region from one position to another. Regions may be overlapped.
+	 *
+	 * @param srcX source rectangle x position
+	 * @param srcY source rectangle y position
+	 * @param dstRect destination rectangle
+	 */
+	public synchronized void copyRect(int srcX, int srcY, FramebufferUpdateRectangle dstRect) {
+		int startSrcY, endSrcY, dstY, deltaY;
+		if (srcY > dstRect.y) {
+			startSrcY = srcY;
+			endSrcY = srcY + dstRect.height;
+			dstY = dstRect.y;
+			deltaY = +1;
+		} else {
+			startSrcY = srcY + dstRect.height - 1;
+			endSrcY = srcY -1;
+			dstY = dstRect.y + dstRect.height - 1;
+			deltaY = -1;
+		}
+		for (int y = startSrcY; y != endSrcY; y += deltaY) {
+			System.arraycopy(pixels, y * width + srcX,
+					pixels, dstY * width + dstRect.x, dstRect.width);
+			dstY += deltaY;
+		}
+	}
+
+	/**
+	 * Fill rectangle region with specified colour
+	 *
+	 * @param color colour to fill with
+	 * @param rect rectangle region posions and dimensions
+	 */
+	public void fillRect(int color, FramebufferUpdateRectangle rect) {
+		fillRect(color, rect.x, rect.y, rect.width, rect.height);
+	}
+
+	/**
+	 * Fill rectangle region with specified colour
+	 *
+	 * @param color colour to fill with
+	 * @param x rectangle x position
+	 * @param y rectangle y position
+	 * @param width rectangle width
+	 * @param height rectangle height
+	 */
+	public synchronized void fillRect(int color, int x, int y, int width, int height) {
+		int sy = y * this.width + x;
+		int ey = sy + height * this.width;
+		for (int i = sy; i < ey; i += this.width) {
+			Arrays.fill(pixels, i, i + width, color);
+		}
+	}
+
+	/**
+	 * Reads color bytes (PIXEL) from reader, returns int combined RGB
+	 * value consisting of the red component in bits 16-23, the green component
+	 * in bits 8-15, and the blue component in bits 0-7. May be used directly for
+	 * creation awt.Color object
+	 */
+	public int readPixelColor(Reader reader) throws TransportException {
+		return colorDecoder.readColor(reader);
+	}
+
+	public int readTightPixelColor(Reader reader) throws TransportException {
+		return colorDecoder.readTightColor(reader);
+	}
+
+	public ColorDecoder getColorDecoder() {
+		return colorDecoder;
+	}
+
+	public int getCompactPixelColor(byte[] bytes, int offset) {
+		return colorDecoder.getCompactColor(bytes, offset);
+	}
+
+	public int getPixelColor(byte[] bytes, int offset) {
+		return colorDecoder.getColor(bytes, offset);
+	}
+
+	public int getBytesPerPixel() {
+		return bytesPerPixel;
+	}
+
+	public int getBytesPerPixelSignificant() {
+		return bytesPerPixelSignificant;
+	}
+
+	public void fillColorBitmapWithColor(int[] bitmapData, int decodedOffset, int rlength, int color) {
+		while (rlength-- > 0) {
+			bitmapData[decodedOffset++] = color;
+		}
+	}
+
+	/**
+	 * Width of rendered image
+	 *
+	 * @return width
+	 */
+	public int getWidth() {
+		return width;
+	}
+
+	/**
+	 * Height of rendered image
+	 *
+	 * @return height
+	 */
+	public int getHeight() {
+		return height;
+	}
+
+	/**
+	 * Read and decode cursor image
+	 *
+	 * @param rect new cursor hot point position and cursor dimensions
+	 * @throws TransportException
+	 */
+	public void createCursor(int[] cursorPixels, FramebufferUpdateRectangle rect)
+		throws TransportException {
+		synchronized (cursor) {
+			cursor.createCursor(cursorPixels, rect.x, rect.y, rect.width, rect.height);
+		}
+	}
+
+	/**
+	 * Read and decode new cursor position
+	 *
+	 * @param rect cursor position
+	 */
+	public void decodeCursorPosition(FramebufferUpdateRectangle rect) {
+		synchronized (cursor) {
+			cursor.updatePosition(rect.x, rect.y);
+		}
+	}
+
+}
--- a/src/main/java/com/glavsoft/drawing/Renderer.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/drawing/Renderer.java	Tue Dec 17 20:16:48 2013 +0900
@@ -24,12 +24,13 @@
 
 package com.glavsoft.drawing;
 
+import java.util.Arrays;
+
 import com.glavsoft.exceptions.TransportException;
 import com.glavsoft.rfb.encoding.PixelFormat;
 import com.glavsoft.rfb.encoding.decoder.FramebufferUpdateRectangle;
 import com.glavsoft.transport.Reader;
 
-import java.util.Arrays;
 
 /**
  * Render bitmap data
@@ -344,4 +345,15 @@
     public Object getLock() {
         return lock;
     }
-}
\ No newline at end of file
+
+	public int getBytesPerPixelSignificant() {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public void drawBytesWithPalette(byte[] buffer,
+			FramebufferUpdateRectangle rect, int[] palette) {
+		// TODO Auto-generated method stub
+		
+	}
+}
--- a/src/main/java/com/glavsoft/rfb/RfbCapabilityInfo.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/rfb/RfbCapabilityInfo.java	Tue Dec 17 20:16:48 2013 +0900
@@ -51,6 +51,7 @@
 
 	public static final String AUTHENTICATION_NO_AUTH = "NOAUTH__";
 	public static final String AUTHENTICATION_VNC_AUTH ="VNCAUTH_";
+	public static final String AUTHENTICATION_REQ_AUTH ="REQAUTH_";
 
 	public static final String ENCODING_COPYRECT = "COPYRECT";
 	public static final String ENCODING_HEXTILE = "HEXTILE_";
--- a/src/main/java/com/glavsoft/rfb/client/FramebufferUpdateRequestMessage.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/rfb/client/FramebufferUpdateRequestMessage.java	Tue Dec 17 20:16:48 2013 +0900
@@ -24,6 +24,9 @@
 
 package com.glavsoft.rfb.client;
 
+import java.util.Timer;
+import java.util.TimerTask;
+
 import com.glavsoft.exceptions.TransportException;
 import com.glavsoft.transport.Writer;
 
@@ -34,7 +37,9 @@
 	private final int width;
 	private final int y;
 	private final int x;
-
+	
+	private boolean sendFullScreenFlag;
+	
 	public FramebufferUpdateRequestMessage(int x, int y, int width,
 			int height, boolean incremental) {
 		this.x = x;
@@ -42,12 +47,18 @@
 		this.width = width;
 		this.height = height;
 		this.incremental = incremental;
+//		sendFullScreenRequest();
 	}
 
 	@Override
 	public void send(Writer writer) throws TransportException {
 		writer.writeByte(FRAMEBUFFER_UPDATE_REQUEST);
-		writer.writeByte(incremental ? 1 : 0);
+		if(sendFullScreenFlag) {
+			writer.writeByte(0);
+			sendFullScreenFlag = false;
+		} else {
+			writer.writeByte(incremental ? 1 : 0);
+		}
 		writer.writeInt16(x);
 		writer.writeInt16(y);
 		writer.writeInt16(width);
@@ -61,5 +72,17 @@
 		+ " width: " + width + " height: " + height +
 		" incremental: " + incremental + "]";
 	}
-
+	
+	public void sendFullScreenRequest() {
+		int sendFullScreenTimer = 5 * 1000;
+		TimerTask tt = new TimerTask() {
+			@Override
+			public void run() {
+				System.out.println("fullscreen");
+				sendFullScreenFlag = true;
+			}
+		};
+		Timer timer = new Timer();
+		timer.schedule(tt, 0, sendFullScreenTimer);
+	}
 }
--- a/src/main/java/com/glavsoft/rfb/encoding/EncodingType.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/rfb/encoding/EncodingType.java	Tue Dec 17 20:16:48 2013 +0900
@@ -60,6 +60,11 @@
     ZRLE(16, "ZRLE"),
 
     /**
+	 * ZRLEE Encoding is extends ZRLE. ZRLEE have flush().   
+	 */
+    ZRLEE(15, "ZRLEE"),
+    
+    /**
      * Rich Cursor pseudo encoding which allows to transfer cursor shape
      * with transparency
      */
@@ -116,6 +121,7 @@
 		ordinaryEncodings.add(TIGHT);
 		ordinaryEncodings.add(HEXTILE);
 		ordinaryEncodings.add(ZRLE);
+		ordinaryEncodings.add(ZRLEE);
 		ordinaryEncodings.add(ZLIB);
 		ordinaryEncodings.add(RRE);
 		ordinaryEncodings.add(COPY_RECT);
--- a/src/main/java/com/glavsoft/rfb/encoding/ServerInitMessage.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/rfb/encoding/ServerInitMessage.java	Tue Dec 17 20:16:48 2013 +0900
@@ -40,8 +40,10 @@
     protected int frameBufferHeight;
     protected PixelFormat pixelFormat;
     protected String name;
+    protected byte[] initData;
 
 	public ServerInitMessage(Reader reader) throws TransportException {
+		readServerInit(reader);
 		frameBufferWidth = reader.readUInt16();
 		frameBufferHeight = reader.readUInt16();
 		pixelFormat = new PixelFormat();
@@ -64,6 +66,10 @@
 	public PixelFormat getPixelFormat() {
 		return pixelFormat;
 	}
+	
+	public byte[] getInitData() {
+		return initData;
+	}
 
 	public String getName() {
 		return name;
@@ -77,4 +83,17 @@
     	", server-pixel-format: " + pixelFormat +
     	"]";
     }
+    
+	public void readServerInit(Reader reader) throws TransportException {
+		reader.mark(255);
+		reader.skypBytes(20);
+		int nlen = reader.readInt32();
+		int blen = 20 + 4 + nlen;
+		initData = new byte[blen];
+		reader.reset();
+
+		reader.mark(blen);
+		reader.readBytes(initData);
+		reader.reset();
+	}
 }
--- a/src/main/java/com/glavsoft/rfb/encoding/decoder/DecodersContainer.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/DecodersContainer.java	Tue Dec 17 20:16:48 2013 +0900
@@ -45,6 +45,7 @@
 		knownDecoders.put(EncodingType.ZLIB, ZlibDecoder.class);
 		knownDecoders.put(EncodingType.RRE, RREDecoder.class);
 		knownDecoders.put(EncodingType.COPY_RECT, CopyRectDecoder.class);
+		knownDecoders.put(EncodingType.ZRLEE, ZRLEDecoder.class);
 //		knownDecoders.put(EncodingType.RAW_ENCODING, RawDecoder.class);
 	}
 	private final Map<EncodingType, Decoder> decoders =
@@ -82,6 +83,10 @@
 		return decoders.get(type);
 	}
 
+	public void setDecoderByType(EncodingType type, Decoder decoder) {
+		decoders.put(type, decoder);
+	}
+	
 	public void resetDecoders() {
 		for (Decoder decoder : decoders.values()) {
 			if (decoder != null) {
--- a/src/main/java/com/glavsoft/rfb/encoding/decoder/TightDecoder.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/TightDecoder.java	Tue Dec 17 20:16:48 2013 +0900
@@ -91,8 +91,12 @@
 			processJpegType(reader, renderer, rect);
 			break;
 		default:
-			assert compType <= JPEG_TYPE : "Compression control byte is incorrect!";
-			processBasicType(compControl, reader, renderer, rect);
+			if (compType > JPEG_TYPE) {
+//				throw new EncodingException(
+//						"Compression control byte is incorrect!");
+			} else {
+				processBasicType(compControl, reader, renderer, rect);
+			}
 		}
 	}
 
--- a/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java	Tue Dec 17 20:16:48 2013 +0900
@@ -39,7 +39,7 @@
 		int zippedLength = (int) reader.readUInt32();
 		if (0 == zippedLength) return;
 		int length = rect.width * rect.height * renderer.getBytesPerPixel();
-		byte[] bytes = unzip(reader, zippedLength, length);
+		byte[] bytes = unzip(reader, zippedLength, length, rect.getEncodingType());
 		int offset = zippedLength;
 		int maxX = rect.x + rect.width;
 		int maxY = rect.y + rect.height;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEESender.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,50 @@
+package com.glavsoft.rfb.encoding.decoder;
+
+import jp.ac.u_ryukyu.treevnc.MyRfbProto;
+import jp.ac.u_ryukyu.treevnc.client.MyRfbProtoClient;
+
+import com.glavsoft.drawing.Renderer;
+import com.glavsoft.exceptions.TransportException;
+import com.glavsoft.rfb.encoding.EncodingType;
+import com.glavsoft.transport.Reader;
+
+public class ZRLEESender extends Decoder {
+	
+	private MyRfbProto rfb;
+
+	public ZRLEESender(MyRfbProto rfb) {
+		this.rfb = rfb;
+	}
+	
+	public ZRLEESender(MyRfbProtoClient rfb) {
+	}
+	
+	@Override
+	public void decode(Reader reader, Renderer renderer,
+			FramebufferUpdateRectangle rect) throws TransportException {
+		int dataLen = getZrleLength(rect,reader);
+		reader.reset();
+		rfb.readSendData(dataLen, reader);
+		if(rfb instanceof MyRfbProtoClient) {
+			reader.readByte();// message
+			reader.readByte();// padding 
+			reader.readUInt16();// numberOfRectangle
+			rect.fill(reader);// fill
+			Decoder decoder = new ZRLEDecoder();
+			decoder.decode(reader,renderer,rect);
+		}
+	}
+
+	private int getZrleLength(FramebufferUpdateRectangle rect,Reader reader)
+			throws TransportException {
+		int zrleLength = 0;
+		if (rect.getEncodingType() == EncodingType.ZRLE
+				|| rect.getEncodingType() == EncodingType.ZRLEE
+				|| rect.getEncodingType() == EncodingType.ZLIB) {
+			zrleLength = reader.readInt32();
+		}
+		return zrleLength + 20;
+	}
+
+
+}
--- a/src/main/java/com/glavsoft/rfb/encoding/decoder/ZlibDecoder.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZlibDecoder.java	Tue Dec 17 20:16:48 2013 +0900
@@ -26,6 +26,7 @@
 
 import com.glavsoft.drawing.Renderer;
 import com.glavsoft.exceptions.TransportException;
+import com.glavsoft.rfb.encoding.EncodingType;
 import com.glavsoft.transport.Reader;
 
 import java.io.ByteArrayInputStream;
@@ -41,20 +42,21 @@
 		int zippedLength = (int) reader.readUInt32();
 		if (0 == zippedLength) return;
 		int length = rect.width * rect.height * renderer.getBytesPerPixel();
-		byte[] bytes = unzip(reader, zippedLength, length);
+		byte[] bytes = unzip(reader, zippedLength, length, rect.getEncodingType());
 		Reader unzippedReader =
 			new Reader(
 					new ByteArrayInputStream(bytes, zippedLength, length));
 		RawDecoder.getInstance().decode(unzippedReader, renderer, rect);
 	}
 
-	protected byte[] unzip(Reader reader, int zippedLength, int length)
+	protected byte[] unzip(Reader reader, int zippedLength, int length,EncodingType encodingType)
 			throws TransportException {
 		byte [] bytes = ByteBuffer.getInstance().getBuffer(zippedLength + length);
 		reader.readBytes(bytes, 0, zippedLength);
-		if (null == decoder) {
+		if (null == decoder || encodingType == EncodingType.ZRLEE) {
+		//if (null == decoder) {
 			decoder = new Inflater();
-		}
+		} 
 		decoder.setInput(bytes, 0, zippedLength);
 		try {
 			decoder.inflate(bytes, zippedLength, length);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/com/glavsoft/rfb/protocol/NullRenderer.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,137 @@
+package com.glavsoft.rfb.protocol;
+
+import com.glavsoft.drawing.ColorDecoder;
+import com.glavsoft.drawing.Renderer;
+import com.glavsoft.exceptions.TransportException;
+import com.glavsoft.rfb.encoding.decoder.FramebufferUpdateRectangle;
+import com.glavsoft.transport.Reader;
+
+public class NullRenderer extends Renderer {
+
+	@Override
+	public void drawJpegImage(byte[] bytes, int offset, int jpegBufferLength,
+			FramebufferUpdateRectangle rect) {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	public void copyRect(int srcX, int srcY, FramebufferUpdateRectangle rect) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public int readPixelColor(Reader reader) throws TransportException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public void fillRect(int i, int tileX, int tileY, int tileWidth,
+			int tileHeight) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public int getBytesPerPixel() {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public void drawBytes(byte[] bytes, int x, int y, int width, int height) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public int getPixelColor(byte[] buffer, int i) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public void createCursor(int[] cursorPixels, FramebufferUpdateRectangle rect) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void fillRect(int color, FramebufferUpdateRectangle rect) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public int getBytesPerPixelSignificant() {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public int readTightPixelColor(Reader reader) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public int drawTightBytes(byte[] buffer, int i, int x, int y, int width,
+			int height) {
+		return 0;
+	}
+
+	@Override
+	public void drawBytesWithPalette(byte[] buffer,
+			FramebufferUpdateRectangle rect, int[] palette) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public ColorDecoder getColorDecoder() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void drawUncaliberedRGBLine(byte[] thisRow, int x, int i, int width) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public int getCompactPixelColor(byte[] bytes, int index) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public void fillColorBitmapWithColor(int[] decodedBitmap,
+			int decodedOffset, int rlength, int color) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void drawColoredBitmap(int[] decodedBitmap, int tileX, int tileY,
+			int tileWidth, int tileHeight) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public int drawCompactBytes(byte[] bytes, int offset, int tileX, int tileY,
+			int tileWidth, int tileHeight) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public void decodeCursorPosition(FramebufferUpdateRectangle rect) {
+		// TODO Auto-generated method stub
+		
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/com/glavsoft/rfb/protocol/NullRepaintController.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,48 @@
+package com.glavsoft.rfb.protocol;
+
+import com.glavsoft.core.SettingsChangedEvent;
+import com.glavsoft.drawing.Renderer;
+import com.glavsoft.rfb.IRepaintController;
+import com.glavsoft.rfb.encoding.PixelFormat;
+import com.glavsoft.rfb.encoding.decoder.FramebufferUpdateRectangle;
+import com.glavsoft.transport.Reader;
+
+public class NullRepaintController implements IRepaintController {
+
+	@Override
+	public void settingsChanged(SettingsChangedEvent event) {
+
+	}
+
+	@Override
+	public void repaintBitmap(FramebufferUpdateRectangle rect) {
+
+	}
+
+	@Override
+	public void repaintBitmap(int x, int y, int width, int height) {
+
+	}
+
+	@Override
+	public void repaintCursor() {
+
+	}
+
+	@Override
+	public void updateCursorPosition(short x, short y) {
+
+	}
+
+	@Override
+	public Renderer createRenderer(Reader reader, int width, int height,
+			PixelFormat pixelFormat) {
+		return new NullRenderer();
+	}
+
+	@Override
+	public void setPixelFormat(PixelFormat pixelFormat) {
+
+	}
+
+}
--- a/src/main/java/com/glavsoft/rfb/protocol/Protocol.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/rfb/protocol/Protocol.java	Tue Dec 17 20:16:48 2013 +0900
@@ -37,9 +37,15 @@
 import com.glavsoft.rfb.protocol.state.ProtocolState;
 import com.glavsoft.transport.Reader;
 import com.glavsoft.transport.Writer;
+import com.glavsoft.viewer.swing.ClipboardControllerImpl;
+import com.glavsoft.viewer.swing.Surface;
 
 import java.util.logging.Logger;
 
+import jp.ac.u_ryukyu.treevnc.MyRfbProto;
+import jp.ac.u_ryukyu.treevnc.server.MyRfbProtoProxy;
+import jp.ac.u_ryukyu.treevnc.server.VncProxyService;
+
 public class Protocol implements ProtocolContext, IChangeSettingsListener {
 	private ProtocolState state;
 	private final Logger logger;
@@ -60,8 +66,10 @@
 	private PixelFormat serverPixelFormat;
 	private Thread senderThread;
 	private Thread receiverThread;
-    private boolean isTight;
-    private String protocolVersion;
+        private boolean isTight;
+        private String protocolVersion;
+	private byte[] initData;
+	private boolean isRetina = false;
 
     public Protocol(Reader reader, Writer writer,
 			IPasswordRetriever passwordRetriever, ProtocolSettings settings) {
@@ -87,7 +95,7 @@
 		}
 		this.messageQueue = new MessageQueue();
 	}
-
+	
 	@Override
 	public PixelFormat getPixelFormat() {
 		return pixelFormat;
@@ -118,7 +126,8 @@
 
 	@Override
 	public void setFbWidth(int fbWidth) {
-		this.fbWidth = fbWidth;
+		if(!isRetina)
+			this.fbWidth = fbWidth;
 	}
 
 	@Override
@@ -126,9 +135,20 @@
 		return fbHeight;
 	}
 
+	@Override 
+	public byte[] getInitData() {
+		return initData;
+	}
+	
+	@Override
+	public void setInitData(byte[] initData) {
+		this.initData = initData;
+	}
+	
 	@Override
 	public void setFbHeight(int fbHeight) {
-		this.fbHeight = fbHeight;
+		if(!isRetina)
+			this.fbHeight = fbHeight;
 	}
 
 	@Override
@@ -179,7 +199,6 @@
 		sendSupportedEncodingsMessage(settings);
 		settings.addListener(this); // to support pixel format (color depth), and encodings changes
 		settings.addListener(repaintController);
-
 		sendRefreshMessage();
 		senderTask = new SenderTask(messageQueue, writer, this);
 		senderThread = new Thread(senderTask, "RfbSenderTask");
@@ -308,4 +327,72 @@
         return protocolVersion;
     }
 
+	public void startNormalHandling(VncProxyService vncProxyService,
+			Surface surface, ClipboardControllerImpl clipboardController,
+			MyRfbProtoProxy rfb) 
+	{
+		this.rfbSessionListener = vncProxyService;
+		this.repaintController = surface;
+//		if (settings.getBitsPerPixel() == 0) {
+//			settings.setBitsPerPixel(pixelFormat.bitsPerPixel); // the same the server sent when not initialized yet
+//		}
+		serverPixelFormat = pixelFormat;
+		serverPixelFormat.trueColourFlag = 1; // correct flag - we don't support color maps
+		setPixelFormat(createPixelFormat(settings));
+		sendMessage(new SetPixelFormatMessage(pixelFormat));
+		logger.fine("sent: "+pixelFormat);
+
+		sendSupportedEncodingsMessage(settings);
+		settings.addListener(this); // to support pixel format (color depth), and encodings changes
+		settings.addListener(surface);
+		sendRefreshMessage();
+		senderTask = new SenderTask(messageQueue, writer, this);
+		senderThread = new Thread(senderTask);
+		senderThread.start();
+		decoders.resetDecoders();
+		receiverTask = new TreeTask(
+				reader, repaintController,
+				clipboardController,
+				decoders, this, rfb);
+		receiverThread = new Thread(receiverTask);
+		receiverThread.start();
+	}
+
+	
+	public void startTreeClientHandling(IRfbSessionListener rfbSessionListener,
+			IRepaintController repaintController, 
+			ClipboardController clipboardController, MyRfbProto rfb) {
+		this.rfbSessionListener = rfbSessionListener;
+		this.repaintController = repaintController;
+//		if (settings.getBitsPerPixel() == 0) {
+//			settings.setBitsPerPixel(pixelFormat.bitsPerPixel); // the same the server sent when not initialized yet
+//		}
+		serverPixelFormat = pixelFormat;
+		serverPixelFormat.trueColourFlag = 1; // correct flag - we don't support color maps
+		setPixelFormat(createPixelFormat(settings));
+		sendMessage(new SetPixelFormatMessage(pixelFormat));
+		logger.fine("sent: "+pixelFormat);
+
+		sendSupportedEncodingsMessage(settings);
+		settings.addListener(this); // to support pixel format (color depth), and encodings changes
+		settings.addListener(repaintController);
+
+		sendRefreshMessage();
+		senderTask = new SenderTask(messageQueue, writer, this);
+		senderThread = new Thread(senderTask);
+		senderThread.start();
+		decoders.resetDecoders();
+		receiverTask = new TreeTask(
+				reader, repaintController,
+				clipboardController,
+				decoders, this, rfb);
+		receiverThread = new Thread(receiverTask);
+		receiverThread.start();
+	}
+	
+	public void setScreenSizeRetina(int fbWidth, int fbHeight) {
+		isRetina = true;
+		this.fbWidth = fbWidth;
+		this.fbHeight = fbHeight;
+	}
 }
--- a/src/main/java/com/glavsoft/rfb/protocol/ProtocolContext.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/rfb/protocol/ProtocolContext.java	Tue Dec 17 20:16:48 2013 +0900
@@ -43,6 +43,8 @@
 
     Writer getWriter();
 	Reader getReader();
+	
+	byte[] getInitData();
 
 	int getFbWidth();
 	void setFbWidth(int frameBufferWidth);
@@ -69,4 +71,6 @@
     void setProtocolVersion(String protocolVersion);
     String getProtocolVersion();
 
-}
\ No newline at end of file
+	void setInitData(byte[] initData);
+	
+}
--- a/src/main/java/com/glavsoft/rfb/protocol/ProtocolSettings.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/rfb/protocol/ProtocolSettings.java	Tue Dec 17 20:16:48 2013 +0900
@@ -158,6 +158,8 @@
 				RfbCapabilityInfo.VENDOR_STANDARD, RfbCapabilityInfo.AUTHENTICATION_NO_AUTH);
 		cc.addEnabled(SecurityType.VNC_AUTHENTICATION.getId(),
 				RfbCapabilityInfo.VENDOR_STANDARD, RfbCapabilityInfo.AUTHENTICATION_VNC_AUTH);
+		cc.addEnabled(SecurityType.REQUIRE_AUTHENTICATION.getId()
+				, RfbCapabilityInfo.VENDOR_STANDARD, RfbCapabilityInfo.AUTHENTICATION_REQ_AUTH);
 	    //cc.addEnabled( 19, "VENC", "VENCRYPT");
 	    //cc.addEnabled( 20, "GTKV", "SASL____");
 	    //cc.addEnabled(129, RfbCapabilityInfo.TIGHT_VNC_VENDOR, "ULGNAUTH");
--- a/src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java	Tue Dec 17 20:16:48 2013 +0900
@@ -44,6 +44,10 @@
 import java.io.StringWriter;
 import java.util.logging.Logger;
 
+import jp.ac.u_ryukyu.treevnc.MyRfbProto;
+import jp.ac.u_ryukyu.treevnc.client.EchoClient;
+import jp.ac.u_ryukyu.treevnc.client.MyRfbProtoClient;
+
 public class ReceiverTask implements Runnable {
 	private static final byte FRAMEBUFFER_UPDATE = 0;
 	private static final byte SET_COLOR_MAP_ENTRIES = 1;
@@ -57,12 +61,25 @@
 	private Renderer renderer;
 	private final IRepaintController repaintController;
 	private final ClipboardController clipboardController;
-	private final DecodersContainer decoders;
-	private FramebufferUpdateRequestMessage fullscreenFbUpdateIncrementalRequest;
-	private final ProtocolContext context;
-	private PixelFormat pixelFormat;
-	private boolean needSendPixelFormat;
-
+	protected final DecodersContainer decoders;
+	protected FramebufferUpdateRequestMessage fullscreenFbUpdateIncrementalRequest;
+	protected final ProtocolContext context;
+	protected PixelFormat pixelFormat;
+	protected boolean needSendPixelFormat;
+	private MyRfbProto rfb;
+	
+	public ReceiverTask(Reader reader,
+            IRepaintController repaintController, ClipboardController clipboardController,
+            DecodersContainer decoders, ProtocolContext context,
+            MyRfbProto _rfb) {
+		this(reader,repaintController,clipboardController,decoders,context);
+		rfb = _rfb;
+		if(!(rfb instanceof MyRfbProtoClient)) {
+			fullscreenFbUpdateIncrementalRequest.sendFullScreenRequest();
+		}
+	}
+	
+	
 	public ReceiverTask(Reader reader,
 	                    IRepaintController repaintController, ClipboardController clipboardController,
 	                    DecodersContainer decoders, ProtocolContext context) {
@@ -76,12 +93,13 @@
 		fullscreenFbUpdateIncrementalRequest =
 			new FramebufferUpdateRequestMessage(0, 0, context.getFbWidth(), context.getFbHeight(), true);
 	}
-
+	
 	@Override
 	public void run() {
 		isRunning = true;
 		while (isRunning) {
 			try {
+				reader.mark(20);
 				byte messageId = reader.readByte();
 				switch (messageId) {
 				case FRAMEBUFFER_UPDATE:
@@ -94,8 +112,8 @@
 					break;
 				case BELL:
 					logger.fine("Server message: Bell");
-					System.out.print("\0007");
-				    System.out.flush();
+//					System.out.print("\0007");
+//				    System.out.flush();
 					break;
 				case SERVER_CUT_TEXT:
 					logger.fine("Server message: CutText (3)");
@@ -105,9 +123,23 @@
 					logger.severe("Unsupported server message. Id = " + messageId);
 				}
 			} catch (TransportException e) {
-				if (isRunning) {
-                    logger.severe("Close session: " + e.getMessage());
-					context.cleanUpSession("Connection closed.");
+				logger.severe("Close session: " + e.getMessage());
+				if(rfb instanceof MyRfbProtoClient && !(rfb.getTerminationType())) {
+					System.out.println("task stop");
+					int counter = 0;
+					EchoClient echo = rfb.getEcho();
+					echo.openport();
+					while(true) {
+						// after set time out. not counter. 
+						if(counter > 3) {
+							echo.notfoundParent();
+						}
+						if(echo.lostHost()) break;
+						counter++;
+					}
+				} else if (isRunning) {
+//					logger.severe("Close proxy: ");
+//					context.cleanUpSession("Connection closed.");
 				}
 				stopTask();
 			} catch (ProtocolException e) {
@@ -205,5 +237,4 @@
 	public void stopTask() {
 		isRunning = false;
 	}
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/com/glavsoft/rfb/protocol/TreeTask.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,42 @@
+package com.glavsoft.rfb.protocol;
+
+import jp.ac.u_ryukyu.treevnc.MyRfbProto;
+
+import com.glavsoft.rfb.ClipboardController;
+import com.glavsoft.rfb.IRepaintController;
+import com.glavsoft.rfb.encoding.EncodingType;
+import com.glavsoft.rfb.encoding.decoder.Decoder;
+import com.glavsoft.rfb.encoding.decoder.DecodersContainer;
+import com.glavsoft.transport.Reader;
+import com.glavsoft.rfb.encoding.decoder.ZRLEESender;
+
+public class TreeTask extends ReceiverTask {
+	//final static String versionMsg_3_855 = "RFB 003.855\n";
+	final static String versionMsg_3_856 = "RFB 003.856\n";
+
+	public TreeTask(Reader reader, IRepaintController repaintController,
+			ClipboardController clipboardController,
+			DecodersContainer decoders, ProtocolContext context, MyRfbProto rfb) {
+		super(reader, repaintController, clipboardController, decoders, context, rfb);
+		//super(reader, new NullRepaintController(), clipboardController, decoders,context, true);
+		Decoder decoder = new ZRLEESender(rfb);
+		decoders.setDecoderByType(EncodingType.ZLIB, decoder);
+		decoders.setDecoderByType(EncodingType.ZRLE, decoder);
+		decoders.setDecoderByType(EncodingType.ZRLEE, decoder);
+	}
+	
+	/*  public void framebufferUpdateMessage() throws CommonException {
+	 * 
+	 *  (non-Javadoc)
+	 *  proxy
+	 *  	no Repaint
+	 *  	decoder!=0 ZRLE -> ZRLEE
+	 *  	readSendData();
+	 *  client 
+	 *  	Repaint
+	 *  	no context.send();
+	 *  	if necessary ZRLEE -> ZRLE
+	 *  	readSendData();    
+	 *  	
+	 */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/com/glavsoft/rfb/protocol/auth/RequireAuthentication.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,40 @@
+package com.glavsoft.rfb.protocol.auth;
+
+import com.glavsoft.exceptions.TransportException;
+import com.glavsoft.rfb.CapabilityContainer;
+import com.glavsoft.rfb.IPasswordRetriever;
+import com.glavsoft.transport.Reader;
+import com.glavsoft.transport.Writer;
+
+public class RequireAuthentication extends AuthHandler {
+	@Override
+	public boolean authenticate(Reader reader, Writer writer,
+			CapabilityContainer authCaps, IPasswordRetriever passwordRetriever) throws TransportException {
+		byte[] headBuf = new byte[2];
+		reader.readBytes(headBuf);
+		if (headBuf[1] == 2) {
+			byte[] b = new byte[258];
+			reader.readBytes(b);
+
+			byte[] outBuf = new byte[256];
+			writer.write(outBuf);
+			writer.flush();
+		} else if (headBuf[1] == 23) {
+			byte[] b = new byte[130];
+			reader.readBytes(b);
+			byte[] outBuf = new byte[192];
+			writer.write(outBuf);
+			writer.flush();
+		}
+
+
+
+		return false;
+	}
+
+	@Override
+	public SecurityType getType() {
+		return SecurityType.REQUIRE_AUTHENTICATION;
+	}
+}
+
--- a/src/main/java/com/glavsoft/rfb/protocol/auth/SecurityType.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/rfb/protocol/auth/SecurityType.java	Tue Dec 17 20:16:48 2013 +0900
@@ -37,11 +37,13 @@
 	VNC_AUTHENTICATION(2),
 //	int RA2_AUTHENTICATION = 5;
 //	int RA2NE_AUTHENTICATION = 6;
-	TIGHT_AUTHENTICATION(16);
+	TIGHT_AUTHENTICATION(16),
+	REQUIRE_AUTHENTICATION(32);
 //	int ULTRA_AUTHENTICATION = 17;
 //	int TLS_AUTHENTICATION = 18;
 //	int VENCRYPT_AUTHENTICATION = 19;
 
+
 	private int id;
 	private SecurityType(int id) {
 		this.id = id;
@@ -58,6 +60,7 @@
 			put(TIGHT_AUTHENTICATION.getId(), new TightAuthentication());
 			put(VNC_AUTHENTICATION.getId(), new VncAuthentication());
 			put(NONE_AUTHENTICATION.getId(), new NoneAuthentication());
+			put(REQUIRE_AUTHENTICATION.getId(), new RequireAuthentication());
 	}};
 
 	public static AuthHandler getAuthHandlerById(int id) throws UnsupportedSecurityTypeException {
--- a/src/main/java/com/glavsoft/rfb/protocol/state/HandshakeState.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/rfb/protocol/state/HandshakeState.java	Tue Dec 17 20:16:48 2013 +0900
@@ -74,7 +74,7 @@
 			major = MAX_SUPPORTED_VERSION_MAJOR;
 			minor = MAX_SUPPORTED_VERSION_MINOR;
 		}
-
+		
 		if (minor >= MIN_SUPPORTED_VERSION_MINOR && minor < 7) {
 			changeStateTo(new SecurityType33State(context));
 			context.setProtocolVersion(PROTOCOL_VERSION_3_3);
--- a/src/main/java/com/glavsoft/rfb/protocol/state/InitState.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/rfb/protocol/state/InitState.java	Tue Dec 17 20:16:48 2013 +0900
@@ -44,16 +44,16 @@
  * to share the desktop by leaving other clients connected, or give exclusive
  * access to this client by disconnecting all other clients.
  *
- * 1 - U8 - shared-flag
+ * 1 - U8 - shared-���ag
  *
- * Shared-flag is non-zero (true) if the server should try to share the desktop by leaving
+ * Shared-���ag is non-zero (true) if the server should try to share the desktop by leaving
  * other clients connected, zero (false) if it should give exclusive access to this client by
  * disconnecting all other clients.
  *
  * ServerInit
  *
  * After receiving the ClientInit message, the server sends a ServerInit message. This
- * tells the client the width and height of the server’s framebuffer, its pixel format and the
+ * tells the client the width and height of the server���s framebuffer, its pixel format and the
  * name associated with the desktop.
  */
 public class InitState extends ProtocolState {
@@ -81,12 +81,13 @@
 		context.setFbWidth(serverInitMessage.getFrameBufferWidth());
 		context.setFbHeight(serverInitMessage.getFrameBufferHeight());
 		context.setRemoteDesktopName(serverInitMessage.getName());
-        Logger.getLogger(getClass().getName()).fine(serverInitMessage.toString());
+		context.setInitData(serverInitMessage.getInitData());
 	}
 
 	protected ServerInitMessage getServerInitMessage() throws TransportException {
 		writer.write(context.getSettings().getSharedFlag());
-        return new ServerInitMessage(reader);
+		ServerInitMessage serverInitMessage = new ServerInitMessage(reader);
+		return serverInitMessage;
 	}
 
 
--- a/src/main/java/com/glavsoft/transport/Reader.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/transport/Reader.java	Tue Dec 17 20:16:48 2013 +0900
@@ -48,7 +48,6 @@
 		} catch (IOException e) {
 			throw new TransportException("Cannot read byte", e);
 		}
-
 	}
 
 	public int readUInt8() throws TransportException {
@@ -103,7 +102,7 @@
 	 * @return String read
 	 */
 	public String readString(int length) throws TransportException {
-        return new String(readBytes(length));
+		return new String(readBytes(length));
 	}
 
 	/**
@@ -150,7 +149,61 @@
 		} catch (EOFException e) {
 			throw new ClosedConnectionException(e);
 		} catch (IOException e) {
-			throw new TransportException("Cannot read " + length + " bytes array", e);
+			throw new TransportException("Cannot read " + length
+					+ " bytes array", e);
+		}
+	}
+
+	public byte[] readBytes(byte[] b) throws TransportException {
+		byte[] result = readBytes(b, 0, b.length);
+		return result;
+	}
+
+	public void reset() throws TransportException {
+		try {
+			is.reset();
+		} catch (IOException e) {
+			throw new TransportException("Cannot reset", e);
+		}
+	}
+
+	public void mark(int readLimit) {
+		is.mark(readLimit);
+	}
+
+	public int readByte(byte[] b) throws TransportException {
+		int result = 0;
+		try {
+			result = is.read(b);
+			return result;
+		} catch (IOException e) {
+			return 0;
+//			throw new TransportException("Cannot readByte", e);
+		}
+	}
+
+	public void close() throws TransportException {
+		try {
+			is.close();
+		} catch (IOException e) {
+			throw new TransportException("Cannot close", e);
+		}
+	}
+
+	public void read(byte[] b) throws TransportException {
+		try {
+			is.read(b);
+		} catch (IOException e) {
+			throw new TransportException("Cannot read", e);
+		}
+	}
+
+	public int skypBytes(int n) throws TransportException {
+		try {
+			int r = is.skipBytes(n);
+			return r;
+		} catch (IOException e) {
+			throw new TransportException("Cannot skipBytes", e);
 		}
 	}
 
@@ -163,4 +216,4 @@
 			throw new TransportException("Cannot skip " + length + " bytes", e);
 		}
 	}
-}
\ No newline at end of file
+}
--- a/src/main/java/com/glavsoft/transport/Writer.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/main/java/com/glavsoft/transport/Writer.java	Tue Dec 17 20:16:48 2013 +0900
@@ -92,7 +92,7 @@
 	public void write(byte[] b) throws TransportException {
 		write(b, 0, b.length);
 	}
-
+	
 	public void write(byte[] b, int length) throws TransportException {
 		write(b, 0, length);
 	}
@@ -105,4 +105,17 @@
 			throw new TransportException("Cannot write " + length + " bytes", e);
 		}
 	}
+
+	public void close() throws IOException {
+		os.close();
+	}
+	
+	public void writeInt(int i) throws TransportException {
+		try {
+			os.write(i);
+		} catch (IOException e) {
+			throw new TransportException("Cannot write int", e);
+		}
+	}
+	
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/AcceptThread.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,64 @@
+package jp.ac.u_ryukyu.treevnc;
+import java.net.Socket;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import com.glavsoft.transport.Reader;
+import com.glavsoft.transport.Writer;
+
+public class AcceptThread implements Runnable {
+        public MyRfbProto rfb = null;
+        byte[] imageBytes;
+        int port;
+        public boolean flag = false;
+        
+        public AcceptThread(MyRfbProto _rfb) {
+                rfb = _rfb;
+        }
+
+
+        public AcceptThread(MyRfbProto _rfb, int p) {
+            rfb = _rfb;
+            port = p;
+        }
+       
+	public void changeRfb(MyRfbProto _rfb) {
+		rfb = _rfb;
+	}
+
+	public void run() {
+		rfb.selectPort(port);
+
+		while (true) {
+			try {
+				Socket newCli = rfb.accept();
+				if(flag) throw new IOException();
+				OutputStream os = newCli.getOutputStream();
+				InputStream is = newCli.getInputStream();
+//				if(confirmHalt(is)) break;
+				rfb.newClient(this, newCli, new Writer(os), new Reader(is));
+			} catch (IOException e) {
+				break;
+			}
+		}
+	}
+	
+
+	
+	
+	/**
+	 * Instruction stop if you come from if WaitReply.
+	 * @return if return true. This Thread halt.
+	 */
+	/*
+	private boolean confirmHalt(InputStream is) throws IOException {
+		byte[] b = new byte[4];
+		is.mark(4);
+		is.read(b);
+		if(String.valueOf(b).equals("halt")) return true;
+		is.reset();
+		return false;
+	}
+	*/
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/InterfaceForViewer.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,30 @@
+package jp.ac.u_ryukyu.treevnc;
+
+import java.awt.Image;
+import java.net.Socket;
+
+import jp.ac.u_ryukyu.treevnc.client.*;
+
+public interface InterfaceForViewer extends java.lang.Runnable{
+
+	public void setEchoValue(EchoClient value);
+	public String readParameter(String name, boolean required);
+	
+	public void getParentName();
+	// synchronized
+	public void disconnect();
+	public void fatalError(String str);
+	public void fatalError(String str, Exception e);
+
+	
+	public void destroy();
+	
+	public void enableInput(boolean enable);
+	
+
+	public void setClientSocket(Socket sock);
+	public void close();
+	public Image getScreenImage();
+	public void writeScreenData(byte[] b, String imageFormat);
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/MostRecentMultiCast.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,27 @@
+package jp.ac.u_ryukyu.treevnc;
+
+import java.util.LinkedList;
+
+
+public class MostRecentMultiCast<T> extends MulticastQueue<T> {
+
+	LinkedList<Node<T>> alive;
+	int count = 0;
+	MostRecentMultiCast(int limit) {
+		count = limit;
+		this.alive = new LinkedList<Node<T>>();
+	}
+
+	@Override
+	public synchronized void put(T item)
+	{
+		Node<T> next = new Node<T>(item);
+		tail.set(next);
+		tail = next;
+		alive.addLast(next);
+		if (alive.size()>count) {
+			Node<T> old = alive.getFirst();
+			old.clear();
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/MulticastQueue.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,87 @@
+package jp.ac.u_ryukyu.treevnc;
+
+import java.util.concurrent.CountDownLatch;
+
+public class MulticastQueue<T>
+{
+	
+	Node<T> tail;
+	
+	public MulticastQueue()
+	{
+		tail = new Node<T>(null);
+	}
+
+	public synchronized void put(T item)
+	{
+		Node<T> next = new Node<T>(item);
+		tail.set(next);
+		tail = next;
+	}
+	
+	public Client<T> newClient()
+	{
+		return new Client<T>(tail);
+	}
+	
+	public static class Client<T>
+	{
+		Node<T> node;
+		
+		Client(Node<T> tail)
+		{
+			node = tail;
+		}
+		
+		synchronized public T poll()
+		{
+			Node<T> next = null;
+			T item = null;
+			do {
+				try {
+					next = node.next();
+				}catch(InterruptedException _e){
+					continue;
+				}
+//				item = node.getItem();
+				item = next.getItem();				
+				node = next;
+			} while ( item == null);
+			return item;
+		}
+	}
+	
+	static class Node<T>
+	{
+		private T item;
+		private Node<T> next;
+		private CountDownLatch latch;
+		
+		public Node(T item)
+		{
+			this.item = item;
+			this.next = null;
+			latch = new CountDownLatch(1);
+		}
+		
+		synchronized public T getItem() {
+			return item;
+		}
+
+		public void set(Node<T> next)
+		{
+			this.next = next;
+			latch.countDown();
+		}
+		
+		public Node<T> next() throws InterruptedException
+		{
+			latch.await();
+			return next;
+		}
+
+		synchronized public void clear() {
+			item = null;
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/MyRfbProto.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,367 @@
+package jp.ac.u_ryukyu.treevnc;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jp.ac.u_ryukyu.treevnc.client.EchoClient;
+import jp.ac.u_ryukyu.treevnc.server.RequestScreenThread;
+
+import com.glavsoft.exceptions.TransportException;
+import com.glavsoft.rfb.protocol.Protocol;
+import com.glavsoft.rfb.protocol.ProtocolContext;
+import com.glavsoft.transport.Reader;
+import com.glavsoft.transport.Writer;
+import com.glavsoft.viewer.Viewer;
+
+public class MyRfbProto {
+	final static int FramebufferUpdateRequest = 3;
+	final static int CheckDelay = 11;
+	final static int FramebufferUpdate = 0;
+	private ProtocolContext context;
+	//final static String versionMsg_3_855 = "RFB 003.855\n";
+	final static String versionMsg_3_856 = "RFB 003.856\n";
+	private int clients;
+	protected MulticastQueue<LinkedList<ByteBuffer>> multicastqueue = new MulticastQueue<LinkedList<ByteBuffer>>();
+	private RequestScreenThread rThread;
+	private boolean proxyFlag = true;
+	private EchoClient echo;
+	private String proxyAddr;
+	
+	public MyRfbProto() {
+		rThread = new RequestScreenThread(this);
+	}
+
+	
+	public void newClient(AcceptThread acceptThread, final Socket newCli,
+			final Writer os, final Reader is) throws IOException {
+		// createBimgFlag = true;
+		// rfb.addSockTmp(newCli);
+		// addSock(newCli);
+		final int myId = clients;
+		final MulticastQueue.Client<LinkedList<ByteBuffer>> c = multicastqueue.newClient();
+		final AtomicInteger writerRunning = new AtomicInteger();
+		writerRunning.set(1);
+		/**
+		 * Timeout thread. If a client is suspended, it has top of queue
+		 * indefinitely, which caused memory overflow. After the timeout, we
+		 * poll the queue and discard it. Start long wait if writer is running.
+		 */
+		final Runnable timer = new Runnable() {
+			public void run() {
+				int count = 0;
+				for (;;) {
+					long timeout = 50000 / 8;
+					try {
+						synchronized (this) {
+							int state, flag;
+							writerRunning.set(0);
+							wait(timeout);
+							flag = 0;
+							while ((state = writerRunning.get()) == 0) {
+								c.poll(); // discard, should be timeout
+								count++;
+								if (flag == 0) {
+									System.out.println("Discarding " + myId
+											+ " count=" + count);
+									flag = 1;
+								}
+								wait(10); // if this is too short, writer cannot
+											// take the poll, if this is too
+											// long, memory will overflow...
+							}
+							if (flag == 1)
+								System.out.println("Resuming " + myId
+										+ " count=" + count);
+							if (state != 1) {
+								System.out.println("Client died " + myId);
+								break;
+							}
+						}
+					} catch (InterruptedException e) {
+					}
+				}
+			}
+		};
+		new Thread(timer).start();
+		/**
+		 * discard all incoming from clients
+		 */
+		final Runnable reader = new Runnable() {
+			public void run() {
+				byte b[] = new byte[4096];
+				for (;;) {
+					try {
+						int c = is.readByte(b);
+						if (c <= 0)
+							throw new IOException();
+						// System.out.println("client read "+c);
+					} catch (IOException e) {
+						try {
+							writerRunning.set(2);
+							os.close();
+							is.close();
+							break;
+						} catch (IOException e1) {
+						} catch (TransportException e1) {
+							e1.printStackTrace();
+						}
+						return;
+					} catch (TransportException e) {
+						e.printStackTrace();
+					}
+				}
+			}
+		};
+		/**
+		 * send packets to a client
+		 */
+		Runnable sender = new Runnable() {
+			public void run() {
+				writerRunning.set(1);
+				try {
+					requestThreadNotify();
+					// rThread.checkDelay();
+
+					/**
+					 * initial connection of RFB protocol
+					 */
+					sendRfbVersion(os);
+					// readVersionMsg(is);
+					readVersionMsg(is, os);
+					sendSecurityType(os);
+					readSecType(is);
+					sendSecResult(os);
+					readClientInit(is);
+					sendInitData(os);
+					new Thread(reader).start(); // discard incoming packet here
+												// after.
+					// writeFramebufferUpdateRequest(0,0, framebufferWidth,
+					// framebufferHeight, false );
+					for (;;) {
+						LinkedList<ByteBuffer> bufs = c.poll();
+						int inputIndex = 0;
+						ByteBuffer header = bufs.get(inputIndex);
+						if (header == null)
+							continue;
+						else if (header.get(0) == CheckDelay) {
+							writeToClient(os, bufs, inputIndex);
+							continue;
+						} else if (header.get(0) == FramebufferUpdate) {
+							// System.out.println("client "+ myId);
+						}
+						/*
+						 * if(i%20==0){ sendDataCheckDelay(); } i++;
+						 */
+						writeToClient(os, bufs, inputIndex);
+						writerRunning.set(1); // yes my client is awaking.
+					}
+				} catch (IOException e) {
+					try {
+						writerRunning.set(2);
+						os.close();
+					} catch (IOException e1) {
+					}
+					/* if socket closed cliList.remove(newCli); */
+				} catch (TransportException e) {
+					e.printStackTrace();
+				}
+			}
+
+			public void writeToClient(final Writer os,
+					LinkedList<ByteBuffer> bufs, int inputIndex)
+					throws TransportException {
+				while (inputIndex < bufs.size()) {
+					ByteBuffer b = bufs.get(inputIndex++);
+					os.write(b.array(), b.position(), b.limit());
+				}
+				os.flush();
+			}
+		};
+		clients++;
+		new Thread(sender).start();
+
+	}
+	
+	public synchronized void requestThreadNotify() {
+		rThread.reStart();
+	}
+	
+	private void sendRfbVersion(Writer writer) throws IOException, TransportException {
+		// os.write(versionMsg_3_8.getBytes());
+		writer.write(versionMsg_3_856.getBytes());
+	}
+	
+	private int readVersionMsg(Reader reader, Writer writer) throws IOException, TransportException {
+
+		byte[] b = new byte[12];
+
+		reader.readBytes(b);
+
+		if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ')
+				|| (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9')
+				|| (b[6] < '0') || (b[6] > '9') || (b[7] != '.')
+				|| (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9')
+				|| (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) {
+			throw new IOException("this is not an RFB server");
+		}
+
+		int rfbMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0');
+		int rfbMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0');
+
+		if (rfbMajor < 3) {
+			throw new IOException(
+					"RFB server does not support protocol version 3");
+		}
+
+		if (rfbMinor == 855) {
+			sendProxyFlag(writer);
+			if (proxyFlag)
+				sendPortNumber(writer);
+		}
+		return rfbMinor;
+	}
+		
+	public void screenChangeRequest() throws IOException {
+		Socket echoSocket;
+		echoSocket = new Socket(proxyAddr, 10001);
+		DataOutputStream os = new DataOutputStream(echoSocket.getOutputStream());
+		os.writeBytes(echo.getMyAddress()+"\n");
+		//os.writeBytes(String.valueOf(echo.client.getFrameWidth())+"\n"); temp comment out for rebuild
+		//os.writeBytes(String.valueOf(echo.client.getFrameHeight())+"\n"); temp comment out for rebuild
+		System.out.println("---------push-------");
+		// os.writeBytes("1240\n");
+		// os.writeBytes("880\n");
+		os.close();
+	}
+	
+	private void sendProxyFlag(Writer writer) throws TransportException {
+		if (proxyFlag)
+			writer.writeInt(1);
+		else
+			writer.writeInt(0);
+	}
+
+	private void sendPortNumber(Writer writer) throws TransportException {
+		byte[] b = new byte[4];
+		//b = castIntByte(getHost.getPort());
+		b = castIntByte(9999);
+		writer.write(b);
+	}
+	
+	private byte[] castIntByte(int len) {
+		byte[] b = new byte[4];
+		b[0] = (byte) ((len >>> 24) & 0xFF);
+		b[1] = (byte) ((len >>> 16) & 0xFF);
+		b[2] = (byte) ((len >>> 8) & 0xFF);
+		b[3] = (byte) ((len >>> 0) & 0xFF);
+		return b;
+	}
+	
+	
+	private void readSecType(Reader reader) throws TransportException {
+		byte[] b = new byte[1];
+		reader.read(b);
+	}
+	
+	private void sendSecurityType(Writer os) throws TransportException {
+		// number-of-security-types
+		os.writeInt(1);
+		// security-types
+		// 1:None
+		os.writeInt(1);
+
+		/*
+		 * os.write(4); os.write(30); os.write(31); os.write(32); os.write(35);
+		 * os.flush();
+		 */
+	}
+	
+	private void sendSecResult(Writer os) throws TransportException {
+		byte[] b = castIntByte(0);
+		os.write(b);
+	}
+
+	private void readClientInit(Reader in) throws TransportException {
+		byte[] b = new byte[0];
+		in.readBytes(b);
+	}
+	
+	private void sendInitData(Writer os) throws TransportException {
+		os.write(context.getInitData());
+	}
+	
+    public void setProtocolContext(Protocol workingProtocol) {
+        context = workingProtocol;
+    }
+
+
+	public void readSendData(int dataLen, Reader reader) throws TransportException {
+		
+	}
+
+	public Socket accept() throws IOException {
+		return null;
+	}
+
+	public int selectPort(int port) {
+		return port;
+	}
+
+
+	public void writeFramebufferUpdateRequest(int x, int y, int w, int h,
+			boolean incremental) throws TransportException {
+		byte[] b = new byte[10];
+
+		b[0] = (byte) FramebufferUpdateRequest; // 3 is FrameBufferUpdateRequest
+		b[1] = (byte) (incremental ? 1 : 0);
+		b[2] = (byte) ((x >> 8) & 0xff);
+		b[3] = (byte) (x & 0xff);
+		b[4] = (byte) ((y >> 8) & 0xff);
+		b[5] = (byte) (y & 0xff);
+		b[6] = (byte) ((w >> 8) & 0xff);
+		b[7] = (byte) (w & 0xff);
+		b[8] = (byte) ((h >> 8) & 0xff);
+		b[9] = (byte) (h & 0xff);
+
+//		os.write(b);
+	}
+	
+	public void notProxy() {
+		proxyFlag = false;
+	}
+
+	public void setEcho(EchoClient _echo) {
+		echo = _echo;
+	}
+	
+	public void setViewer(Viewer v) {
+		echo.setViewer(v);
+	}
+	
+	public EchoClient getEcho() {
+		return echo;
+	}
+
+	public void setTerminationType(boolean setType) {
+		/*nop*/
+	}
+
+	public boolean getTerminationType() {
+		/*nop*/
+		return true;
+	}
+
+	public void setProxyAddr(String proxyAddr) {
+		this.proxyAddr = proxyAddr;
+	}
+
+
+	public void close() {
+		//nothing
+	}
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/client/EchoClient.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,301 @@
+package jp.ac.u_ryukyu.treevnc.client;
+
+import java.io.*;
+import java.net.*;
+
+import com.glavsoft.viewer.Viewer;
+
+public class EchoClient {
+	private String proxyName;
+	private BufferedReader is = null;
+	private DataOutputStream os = null;
+	private Socket echoSocket = null;
+	private boolean runflag = false;
+	private WaitReply waitReply;
+	private Socket clientSocket = null;
+	private int echoPort = 9999;
+	public Viewer client;
+	private String parentAddress;
+	public String parentNum;
+	public String treeNum;
+	public String leaderFlag;
+	private String myAddress;
+
+	public EchoClient(String name, int echoPort) {
+		this.echoPort = echoPort;
+		this.proxyName = name;
+	}
+
+	public void openport() {
+		try {
+			// if(echoSocket==null)
+			echoSocket = new Socket(proxyName, echoPort);
+			echoSocket.setReuseAddress(true);
+			os = new DataOutputStream(echoSocket.getOutputStream());
+			is = new BufferedReader(new InputStreamReader(
+					echoSocket.getInputStream()));
+		} catch (UnknownHostException e) {
+			System.err.println("Don't know about host: localhost");
+		} catch (IOException e) {
+			System.out.println(proxyName + " Connection Faild");
+			System.exit(0);
+		}
+
+	}
+
+	/**
+	 * @param args
+	 *            select connect port
+	 * @return
+	 */
+	public EchoClient requestHostName(String args) {
+		if (echoSocket != null && os != null && is != null) {
+			try {
+
+				InetAddress addr = InetAddress.getLocalHost();
+				myAddress = new String(addr.getHostAddress());
+				// add = getIpV6();
+
+				os.writeBytes(myAddress + "\n");
+				os.writeBytes(args + "\n");
+				getProxyData(is);
+
+				streamClose();
+			} catch (UnknownHostException e) {
+				System.err.println("Trying to connect to unknown host: " + e);
+			} catch (IOException e) {
+				System.err.println("IOException: " + e);
+			}
+			waitReply = new WaitReply(treeNum, this);
+			waitReply.start();
+		}
+		return this;
+	}
+
+	/**
+	 * Call at lost host
+	 */
+	public boolean lostHost() {
+		if (echoSocket != null && os != null && is != null) {
+			try {
+				if (runflag) {
+					return true;
+				}
+				sendDataProxy();
+				reConnectionMain(echoSocket);
+				streamClose();
+			} catch (UnknownHostException e) {
+				System.err.println("Trying to connect to unknown host: " + e);
+			} catch (IOException e) {
+				return false;
+			} catch (NullPointerException e) {
+				openport();
+				System.out.println("notFoundParents");
+				notfoundParent();
+			}
+		}
+		return true;
+	}
+
+	public boolean notfoundParent() {
+		if (echoSocket != null && os != null && is != null) {
+			runflag = true;
+			try {
+				sendDataProxy("2", parentNum, null);
+				getProxyData(is);
+				reConnectionMain(echoSocket);
+				streamClose();
+			} catch (UnknownHostException e) {
+				System.err.println("Trying to connect to unknown host: " + e);
+			} catch (IOException e) {
+				System.err.println("IOException: " + e);
+			}
+		}
+		return true;
+	}
+
+	public EchoClient Interruption(Socket _clientSocket) {
+		clientSocket = _clientSocket;
+		BufferedReader lostis = null;
+
+		try {
+			lostis = new BufferedReader(new InputStreamReader(
+					clientSocket.getInputStream()));
+			getProxyData(lostis);
+			clientSocket.close();
+		} catch (IOException e) {
+			System.out.println(e);
+		}
+		return this;
+	}
+
+	void getProxyData(BufferedReader is) throws IOException {
+		if ((parentAddress = is.readLine()) != null) {
+			System.out.println("Server: " + parentAddress);
+		}
+		if ((parentNum = is.readLine()) != null) {
+			System.out.println("parent: " + parentNum);
+		}
+		if ((treeNum = is.readLine()) != null) {
+			System.out.println("treenum: " + treeNum);
+		}
+		if ((leaderFlag = is.readLine()) != null) {
+			System.out.println("leaderflag: " + leaderFlag);
+		}
+	}
+
+	String getProxyData2(BufferedReader is) throws IOException {
+		String checkRepetition = null;
+		if (!("1".equals(leaderFlag))) {
+			ServerSocket waitReplyServer = new ServerSocket(9999);
+			Socket socketForWait = waitReplyServer.accept();
+			BufferedReader isNotLeader = new BufferedReader(new InputStreamReader(
+					socketForWait.getInputStream()));
+			System.out.println("-------------------renode----------------------------");
+			if ((parentAddress = isNotLeader.readLine()) != null) {
+				System.out.println("Server: " + parentAddress);
+			}
+			if ((parentNum = isNotLeader.readLine()) != null) {
+				System.out.println("parent:test " + parentNum);
+			}
+			if ((checkRepetition = isNotLeader.readLine()) != null) {
+				System.out.println("checkRepetition: " + checkRepetition);
+			}
+			try {
+				Thread.sleep(1000);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		} else {
+			System.out.println("-------------------re----------------------------");
+			if ((parentAddress = is.readLine()) != null) {
+				System.out.println("Server: " + parentAddress);
+			}
+			if ((parentNum = is.readLine()) != null) {
+				System.out.println("parent:test " + parentNum);
+			}
+			if ((checkRepetition = is.readLine()) != null) {
+				System.out.println("checkRepetition: " + checkRepetition);
+			}
+		}
+		return checkRepetition;
+	}
+
+	void reConnectionMain(Socket echoSocket) {
+		while (true) {
+			try {
+				client.closeApp();
+				// set Socket for connection in VncViewer.
+				Socket soc = createSocketForClient(echoSocket,false);
+				client.setSocket(soc);
+				if(soc != null)
+					client.run();
+				break;
+			} catch (IOException e) {
+				break;
+				//continue;
+			}
+		}
+	}
+
+	void streamClose() throws IOException {
+		os.close();
+		is.close();
+		echoSocket.close();
+	}
+
+	void sendDataProxy() {
+		if ("1".equals(leaderFlag)) {
+			sendDataProxy("1", parentNum, treeNum);
+			System.out.println("---------------------------------------------");
+		} else {
+			// sendDataProxy("3", parentNum, treeNum);
+			// System.out.println("---------------------------------------------");
+		}
+	}
+
+	void sendDataProxy(String type, String num, String treenum) {
+		try {
+			if (treenum != null) {
+				os.writeBytes(type + "\n");
+				os.writeBytes(num + "\n");
+				os.writeBytes(treenum + "\n");
+			} else {
+				os.writeBytes(type + "\n");
+				os.writeBytes(num + "\n");
+			}
+		} catch (UnknownHostException e) {
+			System.err.println("Trying to connect to unknown host: " + e);
+		} catch (IOException e) {
+			System.err.println("IOException: " + e);
+		}
+	}
+
+	public void getParentName() {
+		if (clientSocket == null) {
+			// echo = new EchoClient(pHost, this);
+			openport();
+			requestHostName("1"); // 1 is normal connection type.
+		} else {
+			Interruption(clientSocket);
+		}
+	}
+
+	public void setViewer(Viewer v) {
+		client = v;
+	}
+
+	public String getMyAddress() {
+		return myAddress;
+	}
+
+	// create socket for ReConnection.
+	public Socket createSocketForClient(Socket soc,boolean flag) throws IOException {
+		Socket socket  = null;
+		String parentAddress;
+		int count = 0; 
+		
+		System.out.println("########################PATH************************");
+
+		BufferedReader is = new BufferedReader(new InputStreamReader(
+				soc.getInputStream()));
+		parentAddress = is.readLine();
+		String port = is.readLine();
+		// It is called when the screen changes.
+		if ("reconnection".equals(parentAddress)) {
+			while (true) {
+				try {
+					client.setOpenPort(Integer.parseInt(port));
+					return new Socket(this.parentAddress,
+							Integer.parseInt(port));
+				} catch (IOException e) {
+					try {
+						Thread.sleep(1000);
+					} catch (InterruptedException e1) {
+						e1.printStackTrace();
+					}
+					if (count++ > 5)
+						break;
+					continue;
+				}
+			}
+		} else { 
+			System.out.println("###########################faild"+parentAddress);
+			if(parentAddress==null) 
+				return null;
+			is.readLine();// parentNum
+		}
+		socket = new Socket(parentAddress,Integer.parseInt(port));
+		socket.setReuseAddress(true);
+		return socket;
+	}
+
+	public String getParentsAddress() {
+		return parentAddress;
+	}
+	
+	public void reportConnectionFinished(Socket soc) throws IOException {
+		DataOutputStream os = new DataOutputStream(soc.getOutputStream());
+		os.writeBytes("finished");
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/client/GetDataClient.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,77 @@
+package jp.ac.u_ryukyu.treevnc.client;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+
+public class GetDataClient implements Runnable {
+	private ServerSocket server = null;
+	private BufferedReader is;
+	private int port = 8182;
+	private boolean stopFlag;
+	private TextBoxClient text = new TextBoxClient();
+	private String proxyAddr;
+		
+	
+	public String textAddress() {
+		return text.getAddress();
+	}
+	
+	public String  textPort() {
+		return text.getPort();
+	}
+	
+	void socketClose() {
+		try {
+			text.unVisible();
+			is.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	@Override
+	public void run() {
+		try {
+			//TODO create selectPort();
+			server = new ServerSocket(port);
+			while(!stopFlag) {
+				Socket socket = server.accept();  
+				is = new BufferedReader(new InputStreamReader(
+						socket.getInputStream()));
+				proxyAddr = is.readLine();
+				if(proxyAddr!=null)
+					text.checkBox(proxyAddr);
+				text.setButton();
+				text.visible();
+			}
+			System.out.println("stop");
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	public void setStopFlag(boolean stopFlag) {
+		this.stopFlag = stopFlag;
+		
+	}
+	
+	public void interrupt() {
+		Thread.currentThread().interrupt();
+	}
+
+	public boolean isStopFlag() {
+		return stopFlag;
+	}
+	
+	public void ipRegister() {
+		text.ipRegister();
+	}
+
+	public String getProxyAddr() {
+		return proxyAddr;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/client/GetHostClient.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,46 @@
+package jp.ac.u_ryukyu.treevnc.client;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+
+public class GetHostClient {
+	final int BUFSIZE = 1024;
+	final String MCASTADDR = "224.0.0.1";
+	final int PORT = 8183;
+	private byte[] buf = new byte[BUFSIZE];
+	private InetAddress mAddr;
+	private MulticastSocket soc;
+	private String str;
+
+	public GetHostClient(String _str) {
+		str = _str;
+	}
+
+	public void createSocket() {
+		try {
+			mAddr = InetAddress.getByName(MCASTADDR);
+			soc = new MulticastSocket();
+			soc.setTimeToLive(1);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	public void sendData() {
+		buf = str.getBytes();
+		DatagramPacket sendPacket = new DatagramPacket(buf, str.length(),
+				mAddr, PORT);
+		try {
+				soc.send(sendPacket);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	public void getHost() {
+		createSocket();
+		sendData();
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/client/MyRfbProtoClient.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,391 @@
+package jp.ac.u_ryukyu.treevnc.client;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.BindException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+
+import jp.ac.u_ryukyu.treevnc.MyRfbProto;
+
+import com.glavsoft.exceptions.TransportException;
+import com.glavsoft.rfb.encoding.EncodingType;
+import com.glavsoft.rfb.protocol.ProtocolContext;
+import com.glavsoft.transport.Reader;
+
+public class MyRfbProtoClient extends MyRfbProto {
+	final static int FramebufferUpdate = 0;
+	final static int CheckDelay = 11;
+	//final static String versionMsg_3_855 = "RFB 003.855\n";
+	final static String versionMsg_3_856 = "RFB 003.856\n";
+	private static final int INFLATE_BUFSIZE = 1024 * 100;
+	private Reader reader;
+	private String host;
+	private int port;
+	Socket clientSocket, sock;
+	DataInputStream is;
+	OutputStream os;
+	private ServerSocket servSock;
+	private ProtocolContext context;
+	boolean proxyFlag = false;
+	int serverMajor, serverMinor;
+	int clientMajor, clientMinor;
+	private boolean normalTermination;
+
+	private Inflater inflater = new Inflater();
+	private Deflater deflater = new Deflater();
+
+	public MyRfbProtoClient() {
+
+	}
+
+	public MyRfbProtoClient(Reader reader, String host, String port) {
+		this.reader = reader;
+	}
+
+
+	public boolean readProxyFlag() throws TransportException {
+		int flag = reader.readUInt8();
+		if (flag == 1)
+			return true;
+		else
+			return false;
+	}
+
+	public byte[] readEchoPort() throws Exception {
+		byte[] b = new byte[4];
+		reader.readBytes(b, 0, b.length);
+		return b;
+	}
+
+
+	int castByteInt(byte[] b) {
+		ByteBuffer bb = ByteBuffer.wrap(b);
+		int value = bb.getInt();
+		return value;
+	}
+
+	@Override
+	public Socket accept() throws IOException {
+		servSock.setReuseAddress(true);
+		return servSock.accept();
+	}
+
+	void initServSock(int port) throws IOException {
+		servSock = new ServerSocket(port);
+//		acceptPort = port;
+	}
+
+	@Override
+	public int selectPort(int p) {
+		int port = p;
+		while (true) {
+			try {
+//				Thread.sleep(1000);
+				initServSock(port);
+				break;
+			} catch (BindException e) {
+				port++;
+				continue;
+			} catch (IOException e) {
+
+			}
+		}
+		System.out.println("accept port = " + port);
+		return port;
+	}
+
+	void sendRfbVersion(OutputStream os) throws IOException {
+		os.write(versionMsg_3_856.getBytes());
+		// os.write(versionMsg_3_8.getBytes());
+	}
+
+	int readVersionMsg(InputStream is, OutputStream os) throws IOException {
+
+		byte[] b = new byte[12];
+
+		is.read(b);
+
+		if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ')
+				|| (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9')
+				|| (b[6] < '0') || (b[6] > '9') || (b[7] != '.')
+				|| (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9')
+				|| (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) {
+			throw new IOException("Host " + host + " port " + port
+					+ " is not an RFB server");
+		}
+
+		int rfbMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0');
+		int rfbMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0');
+
+		if (rfbMajor < 3) {
+			throw new IOException(
+					"RFB server does not support protocol version 3");
+		}
+
+		if (rfbMinor == 855) {
+			sendProxyFlag(os);
+			// if(proxyFlag)sendPortNumber(os);
+		}
+		return rfbMinor;
+
+	}
+
+	void readVersionMsg(InputStream is) throws IOException {
+
+		byte[] b = new byte[12];
+
+		is.read(b);
+
+		if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ')
+				|| (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9')
+				|| (b[6] < '0') || (b[6] > '9') || (b[7] != '.')
+				|| (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9')
+				|| (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) {
+			throw new IOException("Host " + host + " port " + port
+					+ " is not an RFB server");
+		}
+
+		serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0');
+		serverMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0');
+
+		if (serverMajor < 3) {
+			throw new IOException(
+					"RFB server does not support protocol version 3");
+		}
+
+	}
+
+	void sendSecurityType(OutputStream os) throws IOException {
+		// number-of-security-types
+		os.write(1);
+		// security-types
+		// 1:None
+		os.write(1);
+	}
+
+	void readSecType(InputStream is) throws IOException {
+		byte[] b = new byte[1];
+		is.read(b);
+
+	}
+
+	void sendSecResult(OutputStream os) throws IOException {
+		byte[] b = castIntByte(0);
+		os.write(b);
+	}
+
+	void readClientInit(InputStream in) throws IOException {
+		byte[] b = new byte[0];
+		in.read(b);
+	}
+
+	void sendInitData(OutputStream os) throws IOException {
+		os.write(context.getInitData());
+	}
+
+	void sendProxyFlag(OutputStream os) throws IOException {
+		if (proxyFlag)
+			os.write(1);
+		else
+			os.write(0);
+	}
+
+	byte[] castIntByte(int len) {
+		byte[] b = new byte[4];
+		b[0] = (byte) ((len >>> 24) & 0xFF);
+		b[1] = (byte) ((len >>> 16) & 0xFF);
+		b[2] = (byte) ((len >>> 8) & 0xFF);
+		b[3] = (byte) ((len >>> 0) & 0xFF);
+		return b;
+	}
+
+	/**
+	 * gzip byte arrays
+	 * 
+	 * @param deflater
+	 * @param inputs
+	 *            byte data[]
+	 * @param inputIndex
+	 * @param outputs
+	 *            byte data[]
+	 * @return byte length in last byte array
+	 * @throws IOException
+	 */
+	public int zip(Deflater deflater, LinkedList<ByteBuffer> inputs,
+			int inputIndex, LinkedList<ByteBuffer> outputs) throws IOException {
+		int len = 0;
+		ByteBuffer c1 = ByteBuffer.allocate(INFLATE_BUFSIZE);
+		while (inputIndex < inputs.size()) {
+			ByteBuffer b1 = inputs.get(inputIndex++);
+			deflater.setInput(b1.array(), b1.position(), b1.remaining());
+			/**
+			 * If we finish() stream and reset() it, Deflater start new gzip
+			 * stream, this makes continuous zlib reader unhappy. if we remove
+			 * finish(), Deflater.deflate() never flushes its output. The
+			 * original zlib deflate has flush flag. I'm pretty sure this a kind
+			 * of bug of Java library.
+			 */
+			if (inputIndex == inputs.size())
+				deflater.finish();
+			int len1 = 0;
+			do {
+				len1 = deflater.deflate(c1.array(), c1.position(),
+						c1.remaining());
+				if (len1 > 0) {
+					len += len1;
+					c1.position(c1.position() + len1);
+					if (c1.remaining() == 0) {
+						c1.flip();
+						outputs.addLast(c1);
+						c1 = ByteBuffer.allocate(INFLATE_BUFSIZE);
+					}
+				}
+			} while (len1 > 0 || !deflater.needsInput()); // &&!deflater.finished());
+		}
+		if (c1.position() != 0) {
+			c1.flip();
+			outputs.addLast(c1);
+		}
+		deflater.reset();
+		return len;
+	}
+
+	/**
+	 * gunzip byte arrays
+	 * 
+	 * @param inflater
+	 * @param inputs
+	 *            byte data[]
+	 * @param outputs
+	 *            byte data[]
+	 * @return number of total bytes
+	 * @throws IOException
+	 */
+	public int unzip(Inflater inflater, LinkedList<ByteBuffer> inputs,
+			int inputIndex, LinkedList<ByteBuffer> outputs, int bufSize)
+			throws DataFormatException {
+		int len = 0;
+		ByteBuffer buf = ByteBuffer.allocate(bufSize);
+		while (inputIndex < inputs.size()) {
+			ByteBuffer input = inputs.get(inputIndex++);
+			inflater.setInput(input.array(), input.position(), input.limit());
+			// if (inputIndex==inputs.size()) if inflater/deflater has symmetry,
+			// we need this
+			// inflater.end(); but this won't work
+			do {
+				int len0 = inflater.inflate(buf.array(), buf.position(),
+						buf.remaining());
+				if (len0 > 0) {
+					buf.position(buf.position() + len0);
+					len += len0;
+					if (buf.remaining() == 0) {
+						buf.flip();
+						outputs.addLast(buf);
+						buf = ByteBuffer.allocate(bufSize);
+					}
+				}
+			} while (!inflater.needsInput());
+		}
+		if (buf.position() != 0) {
+			buf.flip();
+			outputs.addLast(buf);
+		}
+		return len;
+	}
+
+	public void readSendData(int dataLen, Reader reader)
+			throws TransportException {
+		LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>();
+		ByteBuffer header = ByteBuffer.allocate(16);
+		reader.mark(dataLen);
+		reader.readBytes(header.array(), 0, 16);
+		header.limit(16);
+		if (header.get(0) == FramebufferUpdate) {
+			int encoding = header.getInt(12);
+			if (encoding == EncodingType.ZRLE.getId()
+					|| encoding == EncodingType.ZLIB.getId()) { // ZRLEE is
+																// already
+																// recompressed
+				ByteBuffer len = ByteBuffer.allocate(4);
+				reader.readBytes(len.array(), 0, 4);
+				len.limit(4);
+				ByteBuffer inputData = ByteBuffer.allocate(dataLen - 20);
+				reader.readBytes(inputData.array(), 0, inputData.capacity());
+				inputData.limit(dataLen - 20);
+				LinkedList<ByteBuffer> inputs = new LinkedList<ByteBuffer>();
+				inputs.add(inputData);
+
+				header.putInt(12, EncodingType.ZRLEE.getId()); // means
+																// recompress
+																// every time
+				// using new Deflecter every time is incompatible with the
+				// protocol, clients have to be modified.
+				Deflater nDeflater = deflater; // new Deflater();
+				LinkedList<ByteBuffer> out = new LinkedList<ByteBuffer>();
+				try {
+					unzip(inflater, inputs, 0, out, INFLATE_BUFSIZE);
+					// dump32(inputs);
+					int len2 = zip(nDeflater, out, 0, bufs);
+					ByteBuffer blen = ByteBuffer.allocate(4);
+					blen.putInt(len2);
+					blen.flip();
+					bufs.addFirst(blen);
+
+					bufs.addFirst(header);
+					multicastqueue.put(bufs);
+					reader.reset();
+				} catch (DataFormatException e) {
+					throw new TransportException(e);
+				} catch (IOException e) {
+					throw new TransportException(e);
+				}
+				return;
+			}
+		}
+		bufs.add(header);
+		if (dataLen > 16) {
+			ByteBuffer b = ByteBuffer.allocate(dataLen - 16);
+			reader.readBytes(b.array(), 0, dataLen - 16);
+			b.limit(dataLen - 16);
+			bufs.add(b);
+		}
+		multicastqueue.put(bufs);
+		reader.reset();
+		// It may be compressed. We can inflate here to avoid repeating clients
+		// decompressing here,
+		// but it may generate too many large data. It is better to do it in
+		// each client.
+		// But we have do inflation for all input data, so we have to do it
+		// here.
+	}
+	
+	@Override
+	public void setTerminationType(boolean setType) {
+		normalTermination = setType;
+	}
+	
+	@Override
+	public boolean getTerminationType() {
+		return normalTermination;
+	}
+	
+	@Override
+	public void close() {
+		try {
+			servSock.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/client/MyVncClient.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,125 @@
+package jp.ac.u_ryukyu.treevnc.client;
+
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.util.logging.Logger;
+
+import com.glavsoft.core.SettingsChangedEvent;
+import com.glavsoft.rfb.IChangeSettingsListener;
+import com.glavsoft.rfb.IRfbSessionListener;
+import com.glavsoft.rfb.protocol.ProtocolSettings;
+import com.glavsoft.viewer.TreeConnectionManager;
+import com.glavsoft.viewer.Viewer;
+import com.glavsoft.viewer.cli.Parser;
+import com.glavsoft.viewer.swing.ParametersHandler;
+
+// "Viewer.java" location is src/viewer_swing/java/com/glavsoft/viewer.
+public class MyVncClient extends Viewer implements IRfbSessionListener,
+	WindowListener, IChangeSettingsListener {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	public static final int DEFAULT_PORT = 5900;
+	public static Logger logger = Logger.getLogger("com.glavsoft");
+	private final ProtocolSettings settings;
+	private TreeConnectionManager treeConnectionManager;
+	
+	
+	public MyVncClient() {
+		settings = ProtocolSettings.getDefaultSettings();
+		//treeConnectionManager = new TreeConnectionManager(this, isApplet);
+	}
+	
+	public MyVncClient(Parser parser) {
+		this();
+		ParametersHandler.completeSettingsFromCLI(parser, connectionParams, settings, uiSettings);
+		passwordFromParams = parser.getValueFor(ParametersHandler.ARG_PASSWORD);
+		logger.info("TightVNC Viewer version " + ver());
+		isApplet = false;
+	}
+
+	public void treeVncClient(String[] argv) {
+		new MyVncClient();
+	}
+
+	public static void main(String[] argv) {
+		String[] mainArgs = argv;
+		System.out.println(mainArgs.length);
+		Parser parser = new Parser();
+		ParametersHandler.completeParserOptions(parser);
+
+		parser.parse(argv);
+		if (parser.isSet(ParametersHandler.ARG_HELP)) {
+			printUsage(parser.optionsUsage());
+			System.exit(0);
+		}
+		MyVncClient myClient = new MyVncClient(parser);
+		myClient.setType();
+		//SwingUtilities.invokeLater(myClient);
+		new Thread(myClient).start();
+	}
+	
+	public void setType() {
+		super.setType(treeConnectionManager,new MyRfbProtoClient());
+	}
+	
+	
+	public void startClient(String[] argv) {
+		String[] mainArgs = argv;
+		System.out.println(mainArgs.length);
+		Parser parser = new Parser();
+		ParametersHandler.completeParserOptions(parser);
+
+		parser.parse(argv);
+		if (parser.isSet(ParametersHandler.ARG_HELP)) {
+			printUsage(parser.optionsUsage());
+			System.exit(0);
+		}
+		MyVncClient myClient = new MyVncClient(parser);
+		myClient.setType();
+		//SwingUtilities.invokeLater(myClient);
+		new Thread(myClient).start();
+	}
+	
+
+	@Override
+	public void windowClosing(WindowEvent e) {
+		if (e != null && e.getComponent() != null) {
+			e.getWindow().setVisible(false);
+		}
+		closeApp();
+	}
+
+	@Override
+	public void windowActivated(WindowEvent e) { /*nop*/ }
+
+	@Override
+	public void windowClosed(WindowEvent e) { /*nop*/ }
+
+	@Override
+	public void windowDeactivated(WindowEvent e) { /*nop*/ }
+
+	@Override
+	public void windowDeiconified(WindowEvent e) { /*nop*/ }
+
+	@Override
+	public void windowIconified(WindowEvent e) { /*nop*/ }
+
+	@Override
+	public void windowOpened(WindowEvent e) { /*nop*/ }
+
+	@Override
+	public void settingsChanged(SettingsChangedEvent event) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void rfbSessionStopped(String reason) {
+		// TODO Auto-generated method stub
+		
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/client/TextBoxClient.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,181 @@
+package jp.ac.u_ryukyu.treevnc.client;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.ArrayList;
+
+public class TextBoxClient extends JFrame implements ActionListener,
+		ItemListener {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private JPanel panel = new JPanel();
+	private JButton button = new JButton("Connect");
+	private TextField t1;
+	private TextField t2;
+	private double width = 750;
+	private double height = 500;
+	private JLabel label;
+	private boolean flag;
+	private ArrayList<String> temp = new ArrayList<String>();
+	private int counter = 0;
+	// private JCheckBox[] check = new JCheckBox[20];
+	private Checkbox[] check = new Checkbox[20];
+	private boolean firstFlag = true;
+	private String hostAddress;
+	private String port;
+	private CheckboxGroup ch = new CheckboxGroup();
+	private Container contentPane = getContentPane();
+
+	public TextBoxClient() {
+		setTitle("Informatin Connection Address");
+		setResizable(false);
+		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+	}
+
+	public void ipRegister() {
+		setSize();
+		setText();
+		setButton();
+		visible();
+	}
+
+	private void setSize() {
+		Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
+		width = (d.getWidth() / 2);
+		height = (d.getHeight() / 2);
+	}
+
+	public void visible() {
+		Point point = new Point();
+		point.setLocation(width - 250, height - 80);
+		setLocation(point.getLocation());
+		pack();
+		setVisible(true);
+	}
+
+	public void unVisible() {
+		setVisible(false);
+	}
+
+	private  void setText() {
+		t1 = new TextField("Address", 30);
+		t2 = new TextField("5999", 5);
+		panel.add(t1);
+		panel.add(t2);
+		//panel.add(button);
+		//button.addActionListener(this);
+		label = new JLabel();
+		contentPane.add(panel, BorderLayout.CENTER);
+		contentPane.add(label, BorderLayout.SOUTH);
+	}
+
+	public void checkBox(String str) {
+		if (counter == 0)
+			check[counter] = new Checkbox(str, true, ch);
+		else
+			check[counter] = new Checkbox(str, false, ch);
+		check[counter].addItemListener(this);
+		panel.add(check[counter]);
+		panel.setLayout(new GridLayout(counter + 2, 0));
+		panel.setLocation((int) width - 250, (int) height - 80);
+		counter++;
+	}
+
+	public void setButton() {
+		panel.add(button);
+		button.addActionListener(this);
+		contentPane.add(panel, BorderLayout.CENTER);
+	}
+
+	public String getAddressOption() {
+		while (!(flag)) {
+			try {
+				Thread.sleep(500);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+		return t1.getText();
+	}
+
+	public String getAddress() {
+		int i = 0;
+		while (!(flag)) {
+			if (i >= 50) {
+				return "notFound";
+			}
+			try {
+				Thread.sleep(500);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+			i++;
+		}
+		return hostAddress;
+	}
+
+	public String getPortOption() {
+		return t2.getText();
+	}
+
+	public String getPort() {
+		return port;
+	}
+
+	public void actionPerformed(ActionEvent e) {
+		flag = true;
+		for (int t = 0; t < counter; t++) {
+			if (check[t].getState()) {
+				System.out.println(check[t].getLabel());
+				setStatus(check[t].getLabel());
+				unVisible();
+			}
+		}
+	}
+
+	private void setStatus(String str) {
+		String[] temp = str.split(":");
+		if (temp.length == 2) {
+			hostAddress = temp[0];
+			port = temp[1];
+		} else {
+			port = temp[0];
+			System.out.println("port=" + port);
+			hostAddress = temp[3];
+		}
+	}
+
+	String splitString(String str) {
+		String[] split = str.split("\\*");
+		String comper;
+		if (split.length > 4) {
+			split[4] = null;
+		}
+		comper = split[1] + split[3];
+		if (firstFlag) {
+			temp.add(comper);
+			firstFlag = false;
+			return "port:" + split[0] + ":host:" + split[1] + ":proxy:"
+					+ split[3];
+		}
+		for (int t = 0; t < temp.size(); t++) {
+			if (!(comper.equals(temp.get(t)))) {
+				if (t == temp.size() - 1) {
+					temp.add(comper);
+					return "port:" + split[0] + ":host:" + split[1] + ":proxy:"
+							+ split[3];
+				}
+			} else {
+				break;
+			}
+		}
+		return null;
+	}
+
+	public void itemStateChanged(ItemEvent e) {
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/client/WaitReply.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,63 @@
+package jp.ac.u_ryukyu.treevnc.client;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.BindException;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+
+/**
+ * this Class get top(Proxy) Instruction. 
+ * Type of Instruction is ReConnection and SocketClose.
+ */
+public class WaitReply extends Thread {
+	private boolean passflag;
+	private EchoClient echo;
+	
+	public WaitReply(String treenum, EchoClient echo) {
+		this.echo = echo;
+	}
+	
+	public boolean checkPath() {
+		return passflag;
+	}
+	
+	public void run() {
+		Socket clientSocket = null;
+		ServerSocket echoServer = null;
+		while (true) {
+			try {
+				echoServer = new ServerSocket(10001);
+				clientSocket = echoServer.accept();
+				if (clientSocket != null) {
+					echo.client.setTeminationType(true);
+					echo.client.stop();
+					echo.client.closeApp();
+					passflag = true;
+					echo.client.setSocket(echo.createSocketForClient(clientSocket,true));
+					echo.client.run();
+					echoServer.close();
+					//report finished connection to server.
+					echo.reportConnectionFinished(clientSocket);
+					clientSocket.close();
+
+				}
+			} catch (BindException e) {
+				break;
+			} catch (IOException e) {
+				System.out.println("Error in WaitReply L47");
+				System.out.println(e);
+			} 
+		}
+	}
+	
+	/*
+	private void hult() throws IOException {
+		Socket socket = new Socket("localhsot",	echo.client.getPort());
+		OutputStream stream = socket.getOutputStream();
+		stream.write("halt".getBytes());
+		stream.flush();
+	}
+	*/
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/AcceptClient.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,321 @@
+package jp.ac.u_ryukyu.treevnc.server;
+
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+public class AcceptClient {
+	private int nodeCounter = 0, parentnum = 0;
+	private LinkedList<String> ls = new LinkedList<String>();
+	private boolean addrRegistor = true;
+	// private int passNumber=0,numberZone;
+	boolean runflag = false;
+	private int passCheck = 0;
+	private final int treebranch = 2;
+	private String newparent, request, myAddress;
+	private String leaderflag = "0", sendleaderflag = "0";
+	private final int intv_time = 100;
+	private String port = "5999";
+
+	public AcceptClient() {
+		// this.name = name;
+	}
+
+	/*
+	 * public AcceptClient() { new CreateThread(this); }
+	 */
+
+	public void transferParentAddrerss(BufferedReader is, PrintStream os) {
+		try {
+			while (true) {
+				String line = is.readLine();
+				String port = is.readLine();
+				myAddress = getMyAddress();
+				if ("1".equals(line) || "3".equals(line)) {
+					String treeNumber = is.readLine();
+					// reply to Parents lost node
+					checkWait(os, is, port, Integer.parseInt(treeNumber));
+
+				} else if ("2".equals(line)) {
+					// reply to not Found Parents
+					replyNodeInformation(port);
+					listupdate(port, newparent);
+					outputStream(os, newparent, String.valueOf(parentnum),
+							port, leaderflag);
+					os.close();
+					is.close();
+				} else if (line != null) {
+					// connection First time
+					if (checkAddress(line)) {
+						outputStream(os, myAddress, "0", "0", "0");
+						break;
+					} else {
+						if (replyCreateTree(os, port, line)) {
+							break;
+						} else {
+							break;
+						}
+					}
+				}
+			}
+		} catch (IOException e) {
+			System.out.println(e);
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+	}
+
+	private boolean checkAddress(String line) {
+		String test[] = line.split("\\.");
+		int a = Integer.parseInt(test[0]);
+		int b = Integer.parseInt(test[1]);
+		if ((192 == a && b == 168) || (172 == a && (b > 15 || b < 32))
+				|| 10 == a) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * @param port
+	 *            parent value
+	 */
+	private synchronized void listupdate(String port) {
+		ls.remove(Integer.parseInt(port));
+		ls.add(Integer.parseInt(port), ls.getLast());
+		ls.removeLast();
+	}
+
+	private synchronized void listupdate(String port, String myaddr) {
+		ls.remove(Integer.parseInt(port));
+		ls.add(Integer.parseInt(port), myaddr);
+		ls.removeLast();
+	}
+
+	private void outputStream(PrintStream os, String request, String parentnum,
+			String treenum, String leaderflag) {
+		os.println(request);
+		os.println(parentnum);
+		os.println(treenum);
+		os.println(leaderflag);
+	}
+
+	private void checkParameter(int parent, int counter, String leaderflag) {
+		System.out.println("number p =" + parentnum);
+		System.out.println("number i =" + counter);
+		System.out.println("leaderflag=" + leaderflag + "\n");
+	}
+
+	private synchronized void addClientAdress(String line, LinkedList<String> ls) {
+		if (line != null) {
+			ls.add(line);
+		}
+		// displyLinkedList(ls);
+	}
+
+	private String decisionLeader(int counter, int treebranch) {
+		if ((counter - 1) % treebranch == 1) { // children in most young treenum
+												// have leaderflag 1 other 0
+			return "0";
+		} else {
+			return "1";
+		}
+	}
+
+	String getMyAddress() {
+		InetAddress addr = null;
+		try {
+			addr = InetAddress.getLocalHost();
+		} catch (UnknownHostException e) {
+			e.printStackTrace();
+		}
+		return new String(addr.getHostAddress());
+	}
+
+	private void replyNodeInformation(String port) {
+		parentnum = (Integer.parseInt(port) - 1) / treebranch;
+		newparent = ls.get(parentnum);
+		sendleaderflag = decisionLeader(Integer.parseInt(port), treebranch);
+		// leaderflag = decisionLeader(Integer.parseInt(port),treebranch);
+	}
+
+	private void replyLeaderNode(PrintStream os, BufferedReader is, String port, int treeNumber) throws IOException,
+			InterruptedException {
+		String lastNode = ls.getLast();
+		if(lastNode != ls.get(treeNumber)){
+			os.println(lastNode);
+		}
+		replyNodeInformation(port);
+		nodeCounter--;
+		passCheck = 1;
+		reportLastNode(lastNode, newparent, port, String.valueOf(parentnum), sendleaderflag);
+		listupdate(port);
+		if(lastNode != ls.get(treeNumber)) {
+			os.println(port);
+			os.println(treeNumber);
+		}
+		leaderflag = decisionLeader(treeNumber, treebranch);
+		lostNodeConnection(treeNumber, lastNode, port);
+		Thread.sleep(intv_time);
+		is.close();
+		os.close();
+	}
+
+	private void lostNodeConnection(int treeNum, String hostNode, String port)
+			throws UnknownHostException, IOException {
+		for (int i = 1; i < treebranch; i++) {
+			String host = ls.get(treeNum + i);
+			if (host != hostNode) {
+				System.out.println("connection socket for-------------------- " + host);
+				Socket clients = new Socket(host, 10001);
+				clients.setReuseAddress(true);
+				DataOutputStream os = new DataOutputStream(clients.getOutputStream());
+				System.out.println("hostnode" + hostNode + "::port" + port);
+				os.writeBytes(hostNode + "\n");
+				// os.writeBytes(port+"\n");
+				os.writeBytes(String.valueOf(treeNum + 1) + "\n");
+				os.close();
+			}
+		}
+	}
+
+	private void replyNormalChildren(PrintStream os, BufferedReader is,
+			String port, String treeNumber, boolean flag) throws IOException,
+			InterruptedException {
+		if (flag)
+			notifyThread();
+		else
+			waitThread();
+		if (Integer.parseInt(treeNumber) == ls.size())
+			return;
+		os.println(ls.get(Integer.parseInt(port)));
+		os.println(port);
+		if (ls.size() - 1 + passCheck == Integer.parseInt(treeNumber))
+			treeNumber = "skip";
+		passCheck = 0;
+		os.println(treeNumber);
+		System.out.println("num4=" + ls.get(Integer.parseInt(port)));
+		runflag = false;
+		is.close();
+		os.close();
+	}
+
+	private synchronized boolean replyCreateTree(PrintStream os, String port,
+			String line) throws InterruptedException {
+		if (addrRegistor == true) {
+			ls.add(myAddress);
+			addrRegistor = false;
+		}
+
+		if (line != null) {
+			addClientAdress(line, ls);
+			nodeCounter++;
+		} else {
+			return true;
+		}
+
+		if (nodeCounter >= treebranch + 1) {
+			leaderflag = decisionLeader(nodeCounter, treebranch);
+			parentnum = (nodeCounter - 1) / treebranch;
+			request = ls.get(parentnum);
+			System.out.println(parentnum);
+			outputStream(os, request, String.valueOf(parentnum),
+					String.valueOf(nodeCounter), leaderflag);
+			checkParameter(parentnum, nodeCounter, leaderflag);
+		} else {
+			outputStream(os, myAddress, "0", String.valueOf(nodeCounter),
+					leaderflag);
+		}
+		Thread.sleep(intv_time);
+		return false;
+	}
+
+	void reportLastNode(String newchild, String newparent, String newtreenum,
+			String newpnum, String newleaderflag) throws IOException {
+		try {
+			Socket echoSocket;
+			System.out.println(newchild + "connect");
+			// echoSocket = new Socket(newchild, 10001 + (i + 1));
+			echoSocket = new Socket(newchild, 10001);
+			DataOutputStream os = new DataOutputStream(
+					echoSocket.getOutputStream());
+			BufferedReader is = new BufferedReader(new InputStreamReader(
+					echoSocket.getInputStream()));
+			os.writeBytes(newparent + "\n");
+			os.writeBytes(this.port+"\n");
+			os.writeBytes(newpnum + "\n");
+			// os.writeBytes(newtreenum + "\n");
+			// os.writeBytes(newleaderflag + "\n");
+			// wait for last node connection.
+			is.readLine();
+			is.close();
+			os.close();
+		} catch (UnknownHostException e) {
+			System.err.println("Don't know about host: localhost");
+		} catch (IOException e) {
+			System.err
+					.println("Couldn't get I/O for the connection to: localhost");
+		}
+	}
+
+	void reportFinishFlag(String nextLastNode) {
+		Socket echoSocket;
+		try {
+			echoSocket = new Socket(nextLastNode, 10001);
+			DataOutputStream os = new DataOutputStream(
+					echoSocket.getOutputStream());
+			os.writeBytes("lastnode" + "\n");
+		} catch (UnknownHostException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+	}
+
+	/*
+	 * // previous viersion for reconnection. synchronized void
+	 * checkWait(PrintStream os,BufferedReader is,String port,int treeNum)
+	 * throws InterruptedException, IOException { final int TIMEOUT = 3000; if
+	 * (passNumber == 0) { passNumber++; numberZone = ((treeNum - 1) /
+	 * treebranch); replyLeaderNode(os,is,port,String.valueOf(treeNum));
+	 * notifyAll(); passNumber = 0; } else if (numberZone == ((treeNum - 1) /
+	 * treebranch)) { if (++passNumber == treebranch) { passNumber = 0;
+	 * replyNormalChildren(os,is,port,String.valueOf(treeNum),true); } else {
+	 * replyNormalChildren(os,is,port,String.valueOf(treeNum),false);
+	 * wait(TIMEOUT); } } else { wait(); checkWait(os,is,port,treeNum); } }
+	 */
+
+	synchronized void checkWait(PrintStream os, BufferedReader is, String port,
+			int treeNum) throws InterruptedException, IOException {
+		replyLeaderNode(os, is, port, treeNum);
+	}
+
+	private void waitThread() {
+		final int TIMEOUT = 3000;
+		try {
+			wait(TIMEOUT);
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+	}
+
+	private void notifyThread() {
+		notifyAll();
+	}
+
+	public LinkedList<String> getList() {
+		return ls;
+	}
+
+	public void setList(LinkedList<String> _ls) {
+		ls = _ls;
+	}
+
+	public int getTreeBranch() {
+		return treebranch;
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/BroadCastProxy.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,36 @@
+package jp.ac.u_ryukyu.treevnc.server;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.Socket;
+
+public class BroadCastProxy {
+	private String str;
+	private Socket socket = null;
+	private PrintStream os = null;
+	private int port = 8182;
+
+	public BroadCastProxy(String _str) {
+		str = _str;
+	}
+
+	void createSocket(String addr) {
+		// while (true) {
+		try {
+			Thread.sleep(1000);
+			socket = new Socket(addr, port);
+			os = new PrintStream(socket.getOutputStream());
+			os.println(str);
+			System.out.println(str);
+			os.close();
+			socket.close();
+			//break;
+		} catch (IOException e) {
+			System.out.println("Connection faild");
+			//continue;
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+		// }
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/CreateThread.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,89 @@
+package jp.ac.u_ryukyu.treevnc.server;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.net.BindException;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+public class CreateThread implements Runnable {
+	ServerSocket echoServer;
+	AcceptClient acceptClient;
+	private int port;
+	private boolean stopFlag;
+	
+	public CreateThread(AcceptClient _acc) {
+		acceptClient = _acc;
+		port = 9999;
+	}
+
+	
+	public CreateThread(int port,AcceptClient _acc) {
+		acceptClient = _acc;
+		this.port = port; 
+	}
+	
+
+	void newEchoClient(final BufferedReader is,final PrintStream os) {
+		Runnable echoSender = new Runnable() {
+			public void run() {
+		//		AcceptClient acceptClient = new AcceptClient();
+				// acceptClient new
+				acceptClient.transferParentAddrerss(is,os);
+			}
+		};
+		new Thread(echoSender).start();
+	}
+
+	void selectPort(int p) {
+		int port = p;
+		while (true) {
+			try {
+				initServSock(port);
+				break;
+			} catch (BindException e) {
+				port++;
+				continue;
+			} catch (IOException e) {
+
+			}
+		}
+		System.out.println("accept Echo port = " + port);
+	}
+	
+	void initServSock(int port) throws IOException {
+		echoServer = new ServerSocket(port);
+		this.port = port;
+	}
+	
+	public int getPort() {
+		return port;
+	}
+	
+	
+	public void run() {
+		selectPort(port);
+		
+		while (true) {
+			try {
+//				echoServer = new ServerSocket(9999);
+				Socket clientSocket = echoServer.accept();
+				if(stopFlag) break;
+				BufferedReader is = new BufferedReader(new InputStreamReader(
+						clientSocket.getInputStream()));
+				PrintStream os = new PrintStream(clientSocket.getOutputStream());
+				newEchoClient(is,os);
+//				acceptClient.transferParentAddrerss(is, os);
+			} catch (IOException e) {
+				System.out.println(e);
+			}
+		}
+
+	}
+	public void setStopFlag(boolean flag){
+		stopFlag = flag;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/GetBroadCastProxy.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,96 @@
+package jp.ac.u_ryukyu.treevnc.server;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
+
+//import TextBoxProxy;
+
+public class GetBroadCastProxy implements Runnable {
+	static final String McastAddr = "224.0.0.1";
+	static final int Port = 8183;
+	static final int BufSize = 1024;
+	private ByteArrayInputStream inputStream;
+	private boolean stopFlag = false;
+	private VncProxyService vps;
+	private BroadCastProxy bCast;
+	private String address;
+
+	public GetBroadCastProxy(VncProxyService _vps,String desktopName,String host){
+		vps = _vps;
+		bCast = new BroadCastProxy(vps.rfb.acceptPort+":"+host+":"
+				+desktopName+":"+getMyAddress()+":");
+	}
+	
+	private synchronized void getData() {
+		byte[] buf = new byte[BufSize];
+		byte[] resorve = new byte[BufSize];
+		try {
+			InetAddress mAddr = InetAddress.getByName(McastAddr);
+			MulticastSocket soc = new MulticastSocket(Port);
+			DatagramPacket recvPacket = new DatagramPacket(buf, BufSize);
+			soc.joinGroup(mAddr);
+			while (!stopFlag) {
+				soc.receive(recvPacket);
+				address = getAddress(recvPacket.getSocketAddress());
+				inputStream = new ByteArrayInputStream(recvPacket.getData());
+				inputStream.read(resorve);
+				if("who".equals(castString(resorve))){
+						replyBroadCast();
+				}
+				if(stopFlag) break;
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	private void replyBroadCast() {
+		Runnable sender = new Runnable() {
+			public void run() {
+				bCast.createSocket(address);
+			}
+		};
+		new Thread(sender).start();
+	}
+
+	private String getAddress(SocketAddress addr) {
+		String str = addr.toString();
+		str = str.substring(1,str.indexOf(":"));
+		return str;
+	}
+	
+	private String castString(byte[] a) {
+		String recover = new String(a);
+		recover = recover.replace("��n", "");
+		recover = recover.trim();
+		return recover;
+	}
+	
+	
+	public void run() {
+		getData();
+	}
+
+	public void setStopFlag(boolean stopFlag) {
+		this.stopFlag = stopFlag;
+	}
+
+	public boolean isStopFlag() {
+		return stopFlag;
+	}
+	
+	String getMyAddress () {
+		InetAddress addr = null;
+		try {
+			addr = InetAddress.getLocalHost();
+		} catch (UnknownHostException e) {
+			e.printStackTrace();
+		}
+		return new String(addr.getHostAddress());
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/MyRfbProtoProxy.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,526 @@
+package jp.ac.u_ryukyu.treevnc.server;
+
+//import static org.junit.Assert.*;
+//import org.junit.Test;
+
+import java.io.IOException;
+import java.net.BindException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import com.glavsoft.exceptions.TransportException;
+import com.glavsoft.rfb.encoding.EncodingType;
+import com.glavsoft.transport.Reader;
+import com.glavsoft.transport.Writer;
+import java.util.concurrent.ExecutorService;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+
+import jp.ac.u_ryukyu.treevnc.MyRfbProto;
+
+public class MyRfbProtoProxy extends MyRfbProto {
+	//final static String versionMsg_3_855 = "RFB 003.855\n";
+	final static String versionMsg_3_856 = "RFB 003.856\n";
+	/**
+	 * CheckMillis is one of new msgType for RFB 3.855 and 3.856.
+	 */
+	final static byte SpeedCheckMillis = 4;
+	final static int FramebufferUpdate = 0;
+	final static int CheckDelay = 11;
+	final static int FramebufferUpdateRequest = 3;
+
+	// Secyrity type of OS X
+	final static int SecTypeReqAccess = 32;
+
+	// Supported authentication types
+	final static int AuthAccess = 32;
+
+	private static final int INFLATE_BUFSIZE = 1024 * 100;
+	boolean printStatusFlag = false;
+	long startCheckTime;
+
+	private ServerSocket servSock;
+	protected int acceptPort;
+	// private byte initData[];
+	private LinkedList<Socket> cliListTmp;
+	private LinkedList<Socket> cliList;
+	boolean createBimgFlag;
+	boolean proxyFlag = true;
+	ExecutorService executor;
+
+	byte[] pngBytes;
+
+	// private MulticastQueue<LinkedList<ByteBuffer>> multicastqueue = new
+	// MostRecentMultiCast<LinkedList<ByteBuffer>>(10);
+	// private MulticastQueue<LinkedList<ByteBuffer>> multicastqueue = new
+	// MulticastQueue<LinkedList<ByteBuffer>>();
+	private Inflater inflater = new Inflater();
+	private Deflater deflater = new Deflater();
+	// private Thread requestThread;
+	private RequestScreenThread rThread;
+	private Thread requestThread;
+
+	public MyRfbProtoProxy() {
+		rThread = new RequestScreenThread(this);
+		requestThread = new Thread(rThread);
+	}
+
+	public void setStream(Writer _writer) {
+		// os = _writer;
+	}
+
+	void initServSock(int port) throws IOException {
+		servSock = new ServerSocket(port);
+		acceptPort = port;
+	}
+
+	/*
+	 * default port number is 5999.
+	 */
+	public int selectPort(int p) {
+		if (servSock != null)
+			return 0;
+		int port = p;
+		while (true) {
+			try {
+				initServSock(port);
+				break;
+			} catch (BindException e) {
+				port++;
+				continue;
+			} catch (IOException e) {
+
+			}
+		}
+		System.out.println("accept port = " + port);
+		return port;
+	}
+
+	int getAcceptPort() {
+		return acceptPort;
+	}
+
+	void setSoTimeout(int num) throws IOException {
+		servSock.setSoTimeout(num);
+	}
+
+	public Socket accept() throws IOException {
+		return servSock.accept();
+	}
+
+	public void socketClose() throws IOException {
+		servSock.close();
+	}
+
+	void addSock(Socket sock) {
+		cliList.add(sock);
+	}
+
+	void addSockTmp(Socket sock) {
+		System.out.println("connected " + sock.getInetAddress());
+		cliListTmp.add(sock);
+	}
+
+	synchronized void changeStatusFlag() {
+		printStatusFlag = true;
+	}
+
+	void printMills() {
+		if (printStatusFlag) {
+
+			changeStatusFlag();
+		} else {
+			changeStatusFlag();
+		}
+	}
+
+	void requestThreadStart() {
+		requestThread.start();
+	}
+
+	public synchronized void requestThreadNotify() {
+		rThread.reStart();
+	}
+
+	/**
+	 * gzip byte arrays
+	 * 
+	 * @param deflater
+	 * @param inputs
+	 *            byte data[]
+	 * @param inputIndex
+	 * @param outputs
+	 *            byte data[]
+	 * @return byte length in last byte array
+	 * @throws IOException
+	 */
+	public int zip(Deflater deflater, LinkedList<ByteBuffer> inputs,
+			int inputIndex, LinkedList<ByteBuffer> outputs) throws IOException {
+		int len = 0;
+		ByteBuffer c1 = ByteBuffer.allocate(INFLATE_BUFSIZE);
+		while (inputIndex < inputs.size()) {
+			ByteBuffer b1 = inputs.get(inputIndex++);
+			deflater.setInput(b1.array(), b1.position(), b1.remaining());
+			/**
+			 * If we finish() stream and reset() it, Deflater start new gzip
+			 * stream, this makes continuous zlib reader unhappy. if we remove
+			 * finish(), Deflater.deflate() never flushes its output. The
+			 * original zlib deflate has flush flag. I'm pretty sure this a kind
+			 * of bug of Java library.
+			 */
+			if (inputIndex == inputs.size())
+				deflater.finish();
+			int len1 = 0;
+			do {
+				len1 = deflater.deflate(c1.array(), c1.position(),
+						c1.remaining());
+				if (len1 > 0) {
+					len += len1;
+					c1.position(c1.position() + len1);
+					if (c1.remaining() == 0) {
+						c1.flip();
+						outputs.addLast(c1);
+						c1 = ByteBuffer.allocate(INFLATE_BUFSIZE);
+					}
+				}
+			} while (len1 > 0 || !deflater.needsInput()); // &&!deflater.finished());
+		}
+		if (c1.position() != 0) {
+			c1.flip();
+			outputs.addLast(c1);
+		}
+		deflater.reset();
+		return len;
+	}
+
+	/**
+	 * gunzip byte arrays
+	 * 
+	 * @param inflater
+	 * @param inputs
+	 *            byte data[]
+	 * @param outputs
+	 *            byte data[]
+	 * @return number of total bytes
+	 * @throws IOException
+	 */
+	public int unzip(Inflater inflater, LinkedList<ByteBuffer> inputs,
+			int inputIndex, LinkedList<ByteBuffer> outputs, int bufSize)
+			throws DataFormatException {
+		int len = 0;
+		ByteBuffer buf = ByteBuffer.allocate(bufSize);
+		while (inputIndex < inputs.size()) {
+			ByteBuffer input = inputs.get(inputIndex++);
+			inflater.setInput(input.array(), input.position(), input.limit());
+			// if (inputIndex==inputs.size()) if inflater/deflater has symmetry,
+			// we need this
+			// inflater.end(); but this won't work
+			do {
+				int len0 = inflater.inflate(buf.array(), buf.position(),
+						buf.remaining());
+				if (len0 > 0) {
+					buf.position(buf.position() + len0);
+					len += len0;
+					if (buf.remaining() == 0) {
+						buf.flip();
+						outputs.addLast(buf);
+						buf = ByteBuffer.allocate(bufSize);
+					}
+				}
+			} while (!inflater.needsInput());
+		}
+		if (buf.position() != 0) {
+			buf.flip();
+			outputs.addLast(buf);
+		}
+		return len;
+	}
+
+	float maxMag = 1;
+
+	/**
+	 * send data to clients
+	 * 
+	 * @param dataLen
+	 * @param is
+	 * @throws IOException
+	 * @throws DataFormatException
+	 * 
+	 *             Zlibed packet is compressed in context dependent way, that
+	 *             is, it have to send from the beginning. But this is
+	 *             impossible. So we have to compress it again for each clients.
+	 *             Separate deflater for each clients is necessary.
+	 * 
+	 *             Java's deflater does not support flush. This means to get the
+	 *             result, we have to finish the compression. Reseting start new
+	 *             compression, but it is not accepted well in zlib continuous
+	 *             reading. So we need new Encoding ZRLEE which reset decoder
+	 *             for each packet. ZRLEE can be invisible from user, but it
+	 *             have to be implemented in the clients. ZRLEE compression is
+	 *             not context dependent, so no recompression is necessary.
+	 * @throws TransportException
+	 */
+
+	public void readSendData(int dataLen, Reader is) throws TransportException {
+		LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>();
+		ByteBuffer header = ByteBuffer.allocate(16);
+		is.readBytes(header.array(), 0, 16);
+		header.limit(16);
+		if (header.get(0) == FramebufferUpdate) {
+			int encoding = header.getInt(12);
+			if (encoding == EncodingType.ZRLE.getId()
+					|| encoding == EncodingType.ZLIB.getId()) { // ZRLEE is
+																// already
+				// recompressed
+				ByteBuffer len = ByteBuffer.allocate(4);
+				is.readBytes(len.array(), 0, 4);
+				len.limit(4);
+				ByteBuffer inputData = ByteBuffer.allocate(dataLen - 20);
+
+				is.readBytes(inputData.array(), 0, inputData.capacity());
+				// System.out.println(dataLen);
+				inputData.limit(dataLen - 20);
+
+				LinkedList<ByteBuffer> inputs = new LinkedList<ByteBuffer>();
+				inputs.add(inputData);
+
+				header.putInt(12, EncodingType.ZRLEE.getId()); // means
+																// recompress
+																// every time
+				// using new Deflecter every time is incompatible with the
+				// protocol, clients have to be modified.
+				Deflater nDeflater = deflater; // new Deflater();
+				LinkedList<ByteBuffer> out = new LinkedList<ByteBuffer>();
+				int len2 = 0;
+				try {
+					unzip(inflater, inputs, 0, out, INFLATE_BUFSIZE);
+					len2 = zip(nDeflater, out, 0, bufs);
+				} catch (DataFormatException e) {
+					throw new TransportException(e);
+				} catch (IOException e) {
+					throw new TransportException(e);
+				}
+
+				ByteBuffer blen = ByteBuffer.allocate(4);
+				blen.putInt(len2);
+				blen.flip();
+				bufs.addFirst(blen);
+
+				bufs.addFirst(header);
+				// if(dataLen<=64000)
+				multicastqueue.put(bufs);
+				// is.reset();
+
+				/*
+				 * System.out.println("ZRLE = "+dataLen);
+				 * System.out.println("ZRLEE = "+(len2+20)); float mag =
+				 * (float)dataLen / (float)(len2 + 20);
+				 * System.out.println("ZRLE / ZRLEE = "+ mag); if(mag > maxMag)
+				 * maxMag = mag; System.out.println("maxMag = "+maxMag);
+				 */
+				return;
+			}
+			bufs.add(header);
+			if (dataLen > 16) {
+				ByteBuffer b = ByteBuffer.allocate(dataLen - 16);
+				is.readBytes(b.array(), 0, dataLen - 16);
+				b.limit(dataLen - 16);
+				bufs.add(b);
+			}
+			multicastqueue.put(bufs);
+			// is.reset();
+			return;
+		}
+		is.reset();
+
+		// It may be compressed. We can inflate here to avoid repeating clients
+		// decompressing here,
+		// but it may generate too many large data. It is better to do it in
+		// each client.
+		// But we have do inflation for all input data, so we have to do it
+		// here.
+	}
+
+	public void dump32(LinkedList<ByteBuffer> bufs) {
+		int len = 0;
+		for (ByteBuffer b : bufs)
+			len += b.remaining();
+		ByteBuffer top = bufs.getFirst();
+		ByteBuffer end = bufs.getLast();
+		System.err.println("length: " + len);
+		System.err.print("head 0: ");
+		for (int i = 0; i < 16 && i < top.remaining(); i++) {
+			System.err.print(" " + top.get(i));
+		}
+		System.err.print("tail 0: ");
+		for (int i = 0; i < 16 && i < end.remaining(); i++) {
+			System.err.print(" " + end.get(i));
+		}
+		System.err.println();
+	}
+
+	/*
+	 * @Test public void test1() { try { LinkedList<ByteBuffer> in = new
+	 * LinkedList<ByteBuffer>(); LinkedList<ByteBuffer> out = new
+	 * LinkedList<ByteBuffer>(); LinkedList<ByteBuffer> out2 = new
+	 * LinkedList<ByteBuffer>(); // if (false) { // for(int i=0;i<10;i++) { //
+	 * in.add(ByteBuffer.wrap("test1".getBytes())); //
+	 * in.add(ByteBuffer.wrap("test2".getBytes())); //
+	 * in.add(ByteBuffer.wrap("test3".getBytes())); //
+	 * in.add(ByteBuffer.wrap("test44".getBytes())); // } // } else { String t =
+	 * ""; for (int i = 0; i < 10; i++) { t += "test1"; t += "test2"; t +=
+	 * "test3"; t += "test44"; } in.add(ByteBuffer.wrap(t.getBytes())); }
+	 * 
+	 * LinkedList<ByteBuffer> in1 = clone(in);
+	 * 
+	 * Deflater deflater = new Deflater(); zip(deflater, in, 0, out); //
+	 * LinkedList<ByteBuffer> out3 = clone(out); zipped result is depend // on
+	 * deflator's state unzip(inflater, out, 0, out2, INFLATE_BUFSIZE); //
+	 * inflater.reset(); equalByteBuffers(in1, out2); LinkedList<ByteBuffer>
+	 * out4 = new LinkedList<ByteBuffer>(); deflater = new Deflater();
+	 * zip(deflater, out2, 0, out4); LinkedList<ByteBuffer> out5 = new
+	 * LinkedList<ByteBuffer>(); unzip(inflater, out4, 0, out5,
+	 * INFLATE_BUFSIZE); int len = equalByteBuffers(in1, out5);
+	 * 
+	 * System.out.println("Test Ok. " + len); } catch (Exception e) {
+	 * assertEquals(0, 1); } }
+	 */
+
+	/*
+	 * public int equalByteBuffers(LinkedList<ByteBuffer> in,
+	 * LinkedList<ByteBuffer> out2) { int len = 0; Iterable<Byte> i =
+	 * byteBufferIterator(in); Iterator<Byte> o =
+	 * byteBufferIterator(out2).iterator();
+	 * 
+	 * for (int b : i) { len++; if (o.hasNext()) { int c = o.next();
+	 * assertEquals(b, c); } else assertEquals(0, 1); } if (o.hasNext())
+	 * assertEquals(0, 1); // System.out.println(); return len; }
+	 */
+
+	void sendRfbVersion(Writer writer) throws IOException, TransportException {
+		// os.write(versionMsg_3_8.getBytes());
+		writer.write(versionMsg_3_856.getBytes());
+	}
+
+	int readVersionMsg(Reader reader, Writer writer) throws IOException,
+			TransportException {
+
+		byte[] b = new byte[12];
+
+		reader.readBytes(b);
+
+		if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ')
+				|| (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9')
+				|| (b[6] < '0') || (b[6] > '9') || (b[7] != '.')
+				|| (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9')
+				|| (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) {
+			throw new IOException("this is not an RFB server");
+		}
+
+		int rfbMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0');
+		int rfbMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0');
+
+		if (rfbMajor < 3) {
+			throw new IOException(
+					"RFB server does not support protocol version 3");
+		}
+
+		if (rfbMinor == 855) {
+			sendProxyFlag(writer);
+			if (proxyFlag)
+				sendPortNumber(writer);
+		}
+		return rfbMinor;
+	}
+
+	void sendProxyFlag(Writer writer) throws TransportException {
+		if (proxyFlag)
+			writer.writeInt(1);
+		else
+			writer.writeInt(0);
+	}
+
+	void sendPortNumber(Writer writer) throws TransportException {
+		byte[] b = new byte[4];
+		// b = castIntByte(getHost.getPort());
+		b = castIntByte(9999);
+		writer.write(b);
+	}
+
+	void sendSecurityType(Writer os) throws TransportException {
+		// number-of-security-types
+		os.writeInt(1);
+		// security-types
+		// 1:None
+		os.writeInt(1);
+
+		/*
+		 * os.write(4); os.write(30); os.write(31); os.write(32); os.write(35);
+		 * os.flush();
+		 */
+	}
+
+	void readSecType(Reader reader) throws TransportException {
+		byte[] b = new byte[1];
+		reader.read(b);
+	}
+
+	void readSecType(Reader is, Writer os) throws TransportException {
+		byte[] b = new byte[1];
+		is.readBytes(b);
+
+		int count = 260;
+		int[] data = { 0, 2, 0, -128, -1, -1, -1, -1, -1, -1, -1, -1, -55, 15,
+				-38, -94, 33, 104, -62, 52, -60, -58, 98, -117, -128, -36, 28,
+				-47, 41, 2, 78, 8, -118, 103, -52, 116, 2, 11, -66, -90, 59,
+				19, -101, 34, 81, 74, 8, 121, -114, 52, 4, -35, -17, -107, 25,
+				-77, -51, 58, 67, 27, 48, 43, 10, 109, -14, 95, 20, 55, 79,
+				-31, 53, 109, 109, 81, -62, 69, -28, -123, -75, 118, 98, 94,
+				126, -58, -12, 76, 66, -23, -90, 55, -19, 107, 11, -1, 92, -74,
+				-12, 6, -73, -19, -18, 56, 107, -5, 90, -119, -97, -91, -82,
+				-97, 36, 17, 124, 75, 31, -26, 73, 40, 102, 81, -20, -26, 83,
+				-127, -1, -1, -1, -1, -1, -1, -1, -1, -111, 73, -29, 30, 57,
+				-67, -75, -77, -49, -50, -99, -76, -80, -80, 14, 65, 57, -105,
+				-103, -54, -102, 3, 39, -44, 39, 35, 118, -84, -64, 37, -117,
+				-21, 89, -31, -68, 70, 5, 122, -92, -119, 9, 121, 63, -112,
+				-60, 122, -46, -69, -36, 92, -103, -92, 74, 92, -73, 87, 120,
+				-8, 116, -47, 111, 20, -41, 110, 122, -3, -94, 14, 42, -51,
+				-59, 48, -54, -125, 117, 60, 77, -52, -31, 98, 32, -2, -102,
+				-15, -29, 58, -14, -106, -116, -32, -86, 50, -32, -16, -3,
+				-123, 87, 88, -118, 10, 120, -107, -37, 125, -110, 59, 87, 93,
+				-24, 124, -99, 18, 78, -13, -49, -34, -24, -27, 1, 114, -67,
+				-98, -56, -3, 85, -67, -126, 77 };
+		for (int i = 0; i < count; i++) {
+			os.write((byte) data[i]);
+			os.flush();
+		}
+
+		byte[] c = new byte[256];
+		is.readBytes(c);
+
+		System.out.println(new String(c));
+
+	}
+
+	void sendSecResult(Writer os) throws TransportException {
+		byte[] b = castIntByte(0);
+		os.write(b);
+	}
+
+	byte[] castIntByte(int len) {
+		byte[] b = new byte[4];
+		b[0] = (byte) ((len >>> 24) & 0xFF);
+		b[1] = (byte) ((len >>> 16) & 0xFF);
+		b[2] = (byte) ((len >>> 8) & 0xFF);
+		b[3] = (byte) ((len >>> 0) & 0xFF);
+		return b;
+	}
+
+	void readClientInit(Reader in) throws TransportException {
+		byte[] b = new byte[0];
+		in.readBytes(b);
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/RequestScreenThread.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,42 @@
+package jp.ac.u_ryukyu.treevnc.server;
+
+import jp.ac.u_ryukyu.treevnc.MyRfbProto;
+
+import com.glavsoft.rfb.protocol.Protocol;
+
+public class RequestScreenThread implements Runnable {
+	MyRfbProto rfb;
+	Protocol protocol;
+
+	public RequestScreenThread(MyRfbProto _rfb) {
+		rfb = _rfb;
+	}
+
+	public void run() {
+		while (true) {
+			try {
+				waitThread();
+				Thread.sleep(3000);
+				rfb.writeFramebufferUpdateRequest(0, 0, protocol.getFbWidth(),
+						protocol.getFbHeight(), false);
+
+			} catch (Exception e) {
+				e.printStackTrace();
+				break;
+			}
+		}
+	}
+	
+    public synchronized void waitThread() {
+    	try{
+    		wait();
+        }catch(InterruptedException e) {
+        	e.printStackTrace();
+    	}
+    }
+
+    public synchronized void reStart() {
+    	notify();
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/VncProxyService.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,370 @@
+package jp.ac.u_ryukyu.treevnc.server;
+
+import java.awt.event.*;
+import java.io.*;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.LinkedList;
+import java.util.logging.Logger;
+
+import jp.ac.u_ryukyu.treevnc.AcceptThread;
+import jp.ac.u_ryukyu.treevnc.server.state.ChangeHost;
+
+import com.glavsoft.core.SettingsChangedEvent;
+import com.glavsoft.exceptions.AuthenticationFailedException;
+import com.glavsoft.exceptions.FatalException;
+import com.glavsoft.exceptions.TransportException;
+import com.glavsoft.exceptions.UnsupportedProtocolVersionException;
+import com.glavsoft.exceptions.UnsupportedSecurityTypeException;
+import com.glavsoft.rfb.IChangeSettingsListener;
+import com.glavsoft.rfb.IRfbSessionListener;
+import com.glavsoft.rfb.protocol.Protocol;
+import com.glavsoft.rfb.protocol.ProtocolSettings;
+import com.glavsoft.transport.Reader;
+import com.glavsoft.transport.Writer;
+import com.glavsoft.viewer.Viewer;
+import com.glavsoft.viewer.cli.Parser;
+import com.glavsoft.viewer.swing.ClipboardControllerImpl;
+import com.glavsoft.viewer.swing.ParametersHandler;
+import com.glavsoft.viewer.swing.Surface;
+
+public class VncProxyService extends Viewer implements Runnable,
+		IRfbSessionListener, IChangeSettingsListener {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	public MyRfbProtoProxy rfb;
+	
+	public static final int DEFAULT_PORT = 5900;
+	public static Logger logger = Logger.getLogger("com.glavsoft");
+	private boolean forceReconnection;
+	private String reconnectionReason;
+	private final ProtocolSettings settings;
+	private AcceptThread acceptThread;
+	private GetBroadCastProxy getCast;
+	public AcceptClient aClient;
+	public int opendPort;
+
+	private VncProxyService prevVps;
+	static VncProxyService currentVps;
+	private int fbWidth = 0;
+	private int fbHeight = 0;
+
+	private void initProxy(Parser parser) {
+		aClient = new AcceptClient();
+		ParametersHandler.completeSettingsFromCLI(parser, connectionParams,
+				settings, uiSettings);
+		passwordFromParams = parser.getValueFor(ParametersHandler.ARG_PASSWORD);
+		logger.info("TightVNC Viewer version " + ver());
+		isApplet = false;
+	}
+
+	public VncProxyService() {
+		settings = ProtocolSettings.getDefaultSettings();
+		uiSettings = super.uiSettings;
+		connectionParams.hostName = "localhost";
+	}
+
+
+
+	public VncProxyService(VncProxyService vps, String hostName) {
+		this();
+		connectionParams.hostName = hostName;
+		rfb = vps.rfb;
+		forceReconnection = vps.forceReconnection;
+		reconnectionReason = vps.reconnectionReason;
+		acceptThread = vps.acceptThread;
+		getCast = vps.getCast;
+		aClient = vps.aClient;
+		opendPort = vps.opendPort;
+		prevVps = vps;
+	}
+
+	public static void main(String[] argv) {
+		String[] mainArgs = argv;
+		System.out.println(mainArgs.length);
+		// input into arguments Decision
+		
+		Parser parser = new Parser();
+		ParametersHandler.completeParserOptions(parser);
+
+		parser.parse(argv);
+		if (parser.isSet(ParametersHandler.ARG_HELP)) {
+			printUsage(parser.optionsUsage());
+			System.exit(0);
+		}
+		VncProxyService vps = new VncProxyService();
+		vps.initProxy1(argv, mainArgs, parser);
+	}
+
+	private void initProxy1(String[] argv, String[] mainArgs,
+			Parser parser) {
+		initProxy(parser);
+		if (mainArgs.length != 0) {
+			for (int i = 0; i < argv.length; i++) {
+				setArguments(mainArgs);
+				// write later
+			}
+		} else {
+			// getHostData();
+		}
+		//run1();
+		createConnectionAndStart();
+		getChangeScreenRequest(); // Should be used Client Socket.
+		try {
+			threadSetAndStart();
+		} catch (UnknownHostException e) {
+			
+		} catch (IOException e) {
+
+		}
+	}
+
+	private void setArguments(String[] mainArgs) {
+	}
+	
+	/*
+	public boolean run1() {
+		rfb = new MyRfbProtoProxy();
+		// getHostData();
+		if (forceReconnection) {
+			connectionManager.showReconnectDialog("Connection lost",
+					prevVps.reconnectionReason);
+			forceReconnection = false;
+		}
+		tryAgain = true;
+		while (tryAgain) {
+			workingSocket = connectionManager.connectToHost(connectionParams,
+					settings, rfb);
+			if (null == workingSocket) {
+				closeApp();
+				break;
+			}
+			logger.info("Connected");
+			try {
+				workingSocket.setTcpNoDelay(true); // disable Nagle algorithm
+				Reader reader = new Reader(workingSocket.getInputStream());
+				Writer writer = new Writer(workingSocket.getOutputStream());
+				// rfb.setStream(reader,writer);
+				workingProtocol = new Protocol(reader, writer,
+						new PasswordChooser(passwordFromParams,
+								connectionParams, containerFrame, this),
+						settings);
+//				if(fbWidth!=0)
+				workingProtocol.setScreenSizeRetina(1080, 1080);
+				workingProtocol.handshake();
+				rfb.setProtocolContext(workingProtocol);
+				// input into change parents
+				ClipboardControllerImpl clipboardController = new ClipboardControllerImpl(
+						workingProtocol, settings.getRemoteCharsetName());
+				clipboardController.setEnabled(settings
+						.isAllowClipboardTransfer());
+				settings.addListener(clipboardController);
+				surface = new Surface(workingProtocol, this,
+						uiSettings.getScaleFactor()); // this method
+				settings.addListener(this);
+				uiSettings.addListener(surface);
+				containerFrame = createContainer();
+				connectionManager.setContainerFrame(containerFrame);
+				updateFrameTitle();
+				containerFrame.dispose();
+				containerFrame = null;
+				if (prevVps != null) {
+					prevVps.cleanUpSession();
+					prevVps = null;
+				}
+				currentVps = this;
+				workingProtocol.startNormalHandling(this, surface,
+						clipboardController, rfb);
+				// rfb.setInitData(workingProtocol.getInitData()); too early
+				// workingProtocol.startNormalHandling(this, surface,
+				// clipboardController);
+				tryAgain = false;
+			} catch (UnsupportedProtocolVersionException e) {
+				connectionManager.showReconnectDialog(
+						"Unsupported Protocol Version", e.getMessage());
+				logger.severe(e.getMessage());
+			} catch (UnsupportedSecurityTypeException e) {
+				connectionManager.showReconnectDialog(
+						"Unsupported Security Type", e.getMessage());
+				logger.severe(e.getMessage());
+			} catch (AuthenticationFailedException e) {
+				passwordFromParams = null;
+				connectionManager.showReconnectDialog("Authentication Failed",
+						e.getMessage());
+				logger.severe(e.getMessage());
+			} catch (TransportException e) {
+				connectionManager.showReconnectDialog("Connection Error",
+						"Connection Error" + ": " + e.getMessage());
+				logger.severe(e.getMessage());
+			} catch (IOException e) {
+				connectionManager.showReconnectDialog("Connection Error",
+						"Connection Error" + ": " + e.getMessage());
+				logger.severe(e.getMessage());
+			} catch (FatalException e) {
+				connectionManager.showReconnectDialog("Connection Error",
+						"Connection Error" + ": " + e.getMessage());
+				logger.severe(e.getMessage());
+			}
+		}
+		return !tryAgain;
+	}
+*/
+	private void cleanUpSession() {
+		if (prevVps != null) {
+			prevVps.cleanUpSession();
+			prevVps = null;
+		}
+//		workingProtocol.cleanUpSession();
+	}
+
+	public void createConnectionAndStart() {
+		Thread thread;
+		opendPort = rfb.selectPort(5999);
+		acceptThread = new AcceptThread(rfb, opendPort);
+		thread = new Thread(acceptThread);
+		thread.start();
+//		getCast = new GetBroadCastProxy(this,
+//				workingProtocol.getRemoteDesktopName(),
+//				this.connectionParams.hostName);
+//		thread = new Thread(getCast);
+//		thread.start();
+	}
+	
+
+	public void proxyStart(String[] argv,int width,int height) {
+		fbWidth = width;
+		fbHeight = height;
+		proxyStart(argv);
+	}
+	
+	public void proxyStart(String[] argv) {
+		String[] mainArgs = argv;
+		System.out.println(mainArgs.length);
+		// input into arguments Decision
+		Parser parser = new Parser();
+		ParametersHandler.completeParserOptions(parser);
+		if(fbWidth==0)
+			parser.parse(argv);
+		if (parser.isSet(ParametersHandler.ARG_HELP)) {
+			printUsage(parser.optionsUsage());
+			System.exit(0);
+		}
+		initProxy1(argv, mainArgs, parser);
+	}
+
+	@Override
+	public void destroy() {
+
+	}
+
+	@Override
+	public void windowClosing(WindowEvent e) {
+		if (e != null && e.getComponent() != null) {
+			e.getWindow().setVisible(false);
+		}
+		closeApp();
+	}
+
+	private void threadSetAndStart() throws UnknownHostException, IOException {
+		CreateThread createThread = new CreateThread(aClient);
+		Thread thread = new Thread(createThread);
+		thread.start();
+		Thread thread2 = new Thread(new ChangeHost(this, forceReconnection));
+		thread2.start();
+	}
+
+
+	private void getChangeScreenRequest() {
+		Thread th = new Thread(new Runnable() {
+			@Override
+			public void run() {
+				while (true) {
+					try {
+						Socket clientSocket = null;
+						ServerSocket echoServer = new ServerSocket(10001);
+						while (true) {
+							clientSocket = echoServer.accept();
+							BufferedReader is = new BufferedReader(
+									new InputStreamReader(
+											clientSocket.getInputStream()));
+							String newHostName = is.readLine();
+							int width = Integer.parseInt(is.readLine());
+							int height = Integer.parseInt(is.readLine());
+							// String screenSize = is.readLine();
+							if(permitChangeScreen()) {
+								changeVNCServer(newHostName,width,height);
+							} else {
+								continue;
+							}
+							clientSocket.close();
+						}
+					} catch (IOException e) {
+						continue; // log  
+					}
+				}
+			}
+		});
+		th.start();
+	}
+	
+	private boolean permitChangeScreen() {
+		
+		return true;
+	}
+
+	protected void socketClose() {
+	}
+
+	@Override
+	public void rfbSessionStopped(final String reason) {
+
+	}
+
+	private void createSocketAndSend(LinkedList<String> clientList, String host, String port)
+			throws UnknownHostException, IOException {
+		boolean passFlag = false;
+		for (String client : clientList) {
+			if (passFlag) {
+				Socket echoSocket;
+				echoSocket = new Socket(client, 10001);
+				DataOutputStream os = new DataOutputStream(
+						echoSocket.getOutputStream());
+				os.writeBytes("reconnection\n");
+				os.writeBytes(port + "\n");
+				os.close();
+			}
+			passFlag = true;
+		}
+	}
+	
+	/**
+	 *  chnageVNCServer is called when host change.
+	 *  @param hostName HostAddress
+	 *  @param width FrameWidth
+	 *  @param height FrameHeight
+	 */
+	public void changeVNCServer(String hostName, int width, int height) throws UnknownHostException,
+			IOException {
+		// sender and reader stop
+		VncProxyService newVps = new VncProxyService(this,hostName);
+//		newVps.fbWidth = width;
+//		newVps.fbHeight = height;
+		// run call and change workingProtocol
+		newVps.connectionParams.hostName = hostName;
+			socketClose();
+			newVps.createConnectionAndStart();
+			newVps.createSocketAndSend(aClient.getList(), hostName, String.valueOf(newVps.opendPort));
+	}
+
+	@Override
+	public void settingsChanged(SettingsChangedEvent event) {
+		// TODO Auto-generated method stub
+		
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/state/ChangeHost.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,67 @@
+package jp.ac.u_ryukyu.treevnc.server.state;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.UnknownHostException;
+import jp.ac.u_ryukyu.treevnc.server.VncProxyService;
+
+public class ChangeHost implements Runnable,ScreenChanges {
+
+	private VncProxyService vps;
+	private ScreenChanges screenChange;
+	
+
+	public ChangeHost(VncProxyService _vps, boolean isApplet) {
+		vps = _vps;
+		screenChange = this;
+	}
+
+
+	String str;
+
+	@Override
+	public void run() {
+		try {
+			while(screenChange.next());
+		} catch (UnknownHostException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	public String getHost() {
+		return str;
+	}
+
+	private void waitingInput() {
+		try {
+			while(true) {
+				BufferedReader br = new BufferedReader(new InputStreamReader(
+						System.in));
+				str = br.readLine();
+				// param hostAddress,width,height 
+				vps.changeVNCServer(str,1000,1000);
+			}
+//			vps.createConnectionAndStart();
+//			vps.aClient.setList(prevVps.aClient.getList());
+//			clientList = prevVps.aClient.getList();
+//			createSocketAndSend(clientList,String.valueOf(port));
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	
+	@Override
+	public boolean next() {
+		waitingInput();
+		changeState(new ReconnectionRequest(vps));
+		return true;
+	}
+
+	public void changeState(ScreenChanges change) {
+		screenChange = change;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/state/ReconnectionRequest.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,38 @@
+package jp.ac.u_ryukyu.treevnc.server.state;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import jp.ac.u_ryukyu.treevnc.server.VncProxyService;
+
+public class ReconnectionRequest implements ScreenChanges {
+	private VncProxyService vps;
+//	private String host;
+	
+	public ReconnectionRequest(VncProxyService vps) {
+		this.vps = vps;
+	}
+
+	@Override
+	public boolean next() throws UnknownHostException, IOException {
+		createSocketAndSend(String.valueOf(vps.opendPort));
+		return false;
+	}
+	
+	private void createSocketAndSend(String port) throws UnknownHostException, IOException {
+		int i = 0;
+		for(String client : vps.aClient.getList()) {
+			if(i!=0) {
+				Socket echoSocket;
+				echoSocket = new Socket(client, 10001);
+				DataOutputStream os = new DataOutputStream(echoSocket.getOutputStream());
+				os.writeBytes("reconnection\n");
+				os.writeBytes(port+"\n");
+				os.close();
+			}
+			i++;
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/state/ScreenChanges.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,10 @@
+package jp.ac.u_ryukyu.treevnc.server.state;
+
+import java.io.IOException;
+import java.net.UnknownHostException;
+
+public interface ScreenChanges {
+	
+	boolean next() throws UnknownHostException, IOException;
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/test/TestTextBox.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,17 @@
+package jp.ac.u_ryukyu.treevnc.test;
+
+import jp.ac.u_ryukyu.treevnc.client.TextBoxClient;
+
+public class TestTextBox {
+	TextBoxClient text = new TextBoxClient();
+	public static void main(String[] args) {
+			TestTextBox t = new TestTextBox();
+			t.testText();
+	}
+	
+	public void testText() {
+		text.checkBox("line");
+		text.setButton();
+		text.visible();	
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/test/ThreadTest.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,19 @@
+package jp.ac.u_ryukyu.treevnc.test;
+
+public class ThreadTest {
+	// exit(0) forces other threads 
+	// if there is no exit(0), main routine wait to join other threads implicitly.  
+	public static void main(String[] args) {
+		Thread th = new Thread(new Runnable(){
+			@Override
+			public void run() {
+				for(int i = 0;i < 10; ) {
+					System.out.println(i);
+				}				
+			}
+		
+		});
+		th.start();
+		System.exit(0);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/viewer_swing/java/com/glavsoft/viewer/TreeConnectionManager.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,70 @@
+package com.glavsoft.viewer;
+
+import java.awt.event.WindowListener;
+import java.io.IOException;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import jp.ac.u_ryukyu.treevnc.MyRfbProto;
+import jp.ac.u_ryukyu.treevnc.client.GetDataClient;
+import jp.ac.u_ryukyu.treevnc.client.GetHostClient;
+import jp.ac.u_ryukyu.treevnc.client.EchoClient;
+
+import com.glavsoft.rfb.protocol.ProtocolSettings;
+import com.glavsoft.viewer.swing.ParametersHandler;
+
+public class TreeConnectionManager {
+	
+	/*
+	private static final long serialVersionUID = 1L;
+	
+	public TreeConnectionManager(WindowListener appWindowListener,
+			boolean isApplet) {
+		super(appWindowListener, isApplet);
+	}
+	
+	@Override
+	public Socket connectToHost(final ParametersHandler.ConnectionParams connectionParams, 
+			ProtocolSettings settings, MyRfbProto rfb) {
+		Socket socket = null;
+		GetHostClient bCast = new GetHostClient("who");
+		bCast.getHost();
+        GetDataClient getBcast = new GetDataClient();
+        Thread runBcast = new Thread(getBcast);
+        runBcast.start();
+		connectionParams.hostName = getBcast.textAddress();
+		getBcast.interrupt();
+		if("notFound".equals(connectionParams.hostName)) {
+			// connectionParams.portNumber = Integer.parseInt(getBcast.textPort());
+			connectionParams.portNumber = 5900;
+		} else {
+			// getBcast.ipRegister();
+			EchoClient echo = new EchoClient(getBcast.textAddress(),9999);
+			rfb.setEcho(echo);
+			rfb.setProxyAddr(getBcast.textAddress());
+			echo.getParentName();
+			connectionParams.hostName = echo.getParentsAddress();
+			connectionParams.portNumber = Integer.parseInt(getBcast.textPort()); // I should get port number 
+			// connectionParams.hostName = getBcast.textAddress();
+			// connectionParams.portNumber = Integer.parseInt(getBcast.textPort());
+			// connectionParams.portNumber = 5900;
+		}
+			Viewer.logger.info("Connecting to host " + connectionParams.hostName + ":" + connectionParams.portNumber);
+			try {
+				socket = new Socket(connectionParams.hostName, connectionParams.portNumber);
+				socket.setReuseAddress(true);
+			} catch (UnknownHostException e) {
+				Viewer.logger.severe("Unknown host: " + connectionParams.hostName);
+				showConnectionErrorDialog("Unknown host: '" + connectionParams.hostName + "'");
+			} catch (IOException e) {
+				Viewer.logger.severe("Couldn't connect to: " +
+						connectionParams.hostName + ":" + connectionParams.portNumber +
+						": " + e.getMessage());
+				showConnectionErrorDialog("Couldn't connect to: '" + connectionParams.hostName +
+						"'\n" + e.getMessage());
+			}
+		return socket;
+	}
+	*/
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/viewer_swing/java/com/glavsoft/viewer/TreeViewer.java	Tue Dec 17 20:16:48 2013 +0900
@@ -0,0 +1,75 @@
+package com.glavsoft.viewer;
+
+import jp.ac.u_ryukyu.treevnc.client.MyVncClient;
+import jp.ac.u_ryukyu.treevnc.server.VncProxyService;
+
+public class TreeViewer {
+	private boolean treeProxy;
+	private boolean viewer;
+	private int width;
+	private int height;
+
+	public static void main(String[] args) {
+		new TreeViewer().vncStart(args);
+	}
+
+	private void vncStart(String[] args) {
+		modeSelect(args);
+		if (treeProxy) {
+			VncProxyService vps = new VncProxyService();
+			vps.proxyStart(args,width,height);
+		} else if (viewer) {
+			Viewer v = new Viewer();
+			v.startViewer(args);
+		} else {
+			MyVncClient mvc = new MyVncClient();
+			mvc.startClient(args);
+		}
+	}
+
+	private void modeSelect(String[] args) {
+		for (int i = 0; i < args.length; i++) {
+			if ("-p".equals(args[i])) {
+				treeProxy = true;
+			} else if ("-v".equals(args[i])) {
+				viewer = true;
+			} else if ("-r".equals(args[i])) {
+				treeProxy = true;
+			} else if ("--version".equals(args[i])) {
+				System.out.println("version :" + VncProxyService.ver());
+				System.exit(0);
+			} else if ("-retina".equals(args[i])) {
+				treeProxy = true;
+				if(getParameter(args,i))
+					i = i + 2;
+			} else {
+				System.out.println("(default) TreeVNCClient\n"
+								+ "-p:       TreeVNCProxy\n"
+								+ "-v:      VNCViewer\n"
+								+ "-r:      TreeVNCProxy for RemoteHost. you should input parameter host and port\n"
+								+ "-retina whidth heght:    TreeVNC proxy for retina.this mode can select screen range.");
+			}
+		}
+	}
+	
+	private boolean getParameter(String[] args, int i) {
+		if(isInteger(args[++i])&&isInteger(args[++i])) {
+			width = Integer.parseInt(args[--i]);
+			height = Integer.parseInt(args[++i]);
+			return true;
+		} else {
+			width = 1920;
+			height = 1080;
+			return false;
+		}
+	}
+	
+	private boolean isInteger(String num) {
+		try {
+			Integer.parseInt(num);
+			return true;
+		} catch (NumberFormatException e) {
+			return false;
+		}
+	}
+}
--- a/src/viewer_swing/java/com/glavsoft/viewer/Viewer.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/viewer_swing/java/com/glavsoft/viewer/Viewer.java	Tue Dec 17 20:16:48 2013 +0900
@@ -39,10 +39,15 @@
 import java.awt.event.WindowListener;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.Socket;
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
 import java.util.logging.*;
 
+import jp.ac.u_ryukyu.treevnc.client.GetDataClient;
+import jp.ac.u_ryukyu.treevnc.client.GetHostClient;
+import jp.ac.u_ryukyu.treevnc.client.MyRfbProtoClient;
+
 @SuppressWarnings("serial")
 public class Viewer extends JApplet implements Runnable, WindowListener {
 
@@ -50,12 +55,12 @@
     private int paramsMask;
     private boolean allowAppletInteractiveConnections;
 
-    private final ConnectionParams connectionParams;
-    private String passwordFromParams;
+    protected final ConnectionParams connectionParams;
+    protected String passwordFromParams;
     boolean isSeparateFrame = true;
-    boolean isApplet = true;
+    protected boolean isApplet = true;
     private final ProtocolSettings settings;
-    private final UiSettings uiSettings;
+    protected UiSettings uiSettings;
     private volatile boolean isAppletStopped = false;
     private ConnectionPresenter connectionPresenter;
 
@@ -73,12 +78,12 @@
 	}
 
     public static void printUsage(String additional) {
-		System.out.println("Usage: java -jar (progfilename) [hostname [port_number]] [Options]\n" +
-				"    or\n"+
-				" java -jar (progfilename) [Options]\n" +
-				"    or\n java -jar (progfilename) -help\n    to view this help\n\n" +
-				"Where Options are:\n" + additional +
-				"\nOptions format: -optionName=optionValue. Ex. -host=localhost -port=5900 -viewonly=yes\n" +
+		System.out.println("Usage: java -jar (progfilename) [hostname [port_number]] [Options]¥n" +
+				"    or¥n"+
+				" java -jar (progfilename) [Options]¥n" +
+				"    or¥n java -jar (progfilename) -help¥n    to view this help¥n¥n" +
+				"Where Options are:¥n" + additional +
+				"¥nOptions format: -optionName=optionValue. Ex. -host=localhost -port=5900 -viewonly=yes¥n" +
 				"Both option name and option value are case insensitive.");
 	}
 
@@ -201,7 +206,6 @@
 
     @Override
 	public void run() {
-
         final boolean hasJsch = checkJsch();
         final boolean allowInteractive = allowAppletInteractiveConnections || ! isApplet;
         connectionPresenter = new ConnectionPresenter(hasJsch, allowInteractive);
@@ -261,4 +265,134 @@
 		}
 	}
 
+	public void setType(TreeConnectionManager treeConnectionManager,
+			MyRfbProtoClient myRfbProtoClient) {
+		// must write
+	}
+
+	public void setSocket(Socket soc) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	public void setOpenPort(int parseInt) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	public void setTeminationType(boolean b) {
+		// TODO Auto-generated method stub
+	}
+	
+	public void startViewer(String[] args) {
+		GetHostClient bCast = new GetHostClient("who");
+		bCast.getHost();
+        GetDataClient getBcast = new GetDataClient();
+        Thread runBcast = new Thread(getBcast);
+        runBcast.start();
+		connectionParams.hostName = getBcast.textAddress();
+		getBcast.interrupt();
+		Viewer viewer = new Viewer();
+		SwingUtilities.invokeLater(viewer);
+	}
+
 }
+
+    
+	/*
+    @Override
+	public void run() {
+
+        final boolean hasJsch = checkJsch();
+        final boolean allowInteractive = allowAppletInteractiveConnections || ! isApplet;
+        connectionPresenter = new ConnectionPresenter(hasJsch, allowInteractive);
+        connectionPresenter.addModel("ConnectionParamsModel", connectionParams);
+        final ConnectionView connectionView = new ConnectionView(
+                Viewer.this, // appWindowListener
+                connectionPresenter, hasJsch);
+        connectionPresenter.addView(ConnectionPresenter.CONNECTION_VIEW, connectionView);
+        if (isApplet) {
+            connectionPresenter.addView("AppletStatusStringView", new View() {
+                @Override
+                public void showView() { / }
+                @Override
+                public void closeView() {  }
+                @SuppressWarnings("UnusedDeclaration")
+                public void setMessage(String message) {
+                    Viewer.this.getAppletContext().showStatus(message);
+                }
+            });
+        }
+		if (forceReconnection) {
+			System.out.println("error10#####################");
+			connectionManager.showReconnectDialog("Connection lost", reconnectionReason);
+			forceReconnection = false;
+		}
+
+	
+		tryAgain = true;
+		while (tryAgain) {
+			if(workingSocket==null)
+				workingSocket = connectionManager.connectToHost(connectionParams, settings, rfb);
+			if (null == workingSocket) {
+				closeApp();
+				break;
+			}
+			logger.info("Connected");
+			System.out.println("connection-----------" + workingSocket.getInetAddress());
+			try {
+				workingSocket.setTcpNoDelay(true); // disable Nagle algorithm
+				Reader reader = new Reader(workingSocket.getInputStream());
+				Writer writer = new Writer(workingSocket.getOutputStream());
+
+				workingProtocol = new Protocol(reader, writer,
+						new PasswordChooser(passwordFromParams, connectionParams, containerFrame, this),
+						settings);
+				workingProtocol.handshake();
+
+                ClipboardControllerImpl clipboardController =
+		                new ClipboardControllerImpl(workingProtocol, settings.getRemoteCharsetName());
+				clipboardController.setEnabled(settings.isAllowClipboardTransfer());
+				settings.addListener(clipboardController);
+
+				surface = new Surface(workingProtocol, this, uiSettings.getScaleFactor());
+				settings.addListener(this);
+				uiSettings.addListener(surface);
+				containerFrame = createContainer();
+				connectionManager.setContainerFrame(containerFrame);
+				updateFrameTitle();
+				if(rfb != null) {
+					rfb.setViewer(this);
+					runAcceptThread();
+					rfb.setProtocolContext(workingProtocol);
+					rfb.notProxy();
+					workingProtocol.startTreeClientHandling(this,surface, clipboardController,rfb);
+				} else {
+					workingProtocol.startNormalHandling(this, surface, clipboardController);					
+				}
+				tryAgain = false;
+			} catch (UnsupportedProtocolVersionException e) {
+				connectionManager.showReconnectDialog("Unsupported Protocol Version", e.getMessage());
+				logger.severe(e.getMessage());
+			} catch (UnsupportedSecurityTypeException e) {
+				connectionManager.showReconnectDialog("Unsupported Security Type", e.getMessage());
+				logger.severe(e.getMessage());
+			} catch (AuthenticationFailedException e) {
+				passwordFromParams = null;
+				connectionManager.showReconnectDialog("Authentication Failed", e.getMessage());
+				logger.severe(e.getMessage());
+			} catch (TransportException e) {
+				connectionManager.showReconnectDialog("Connection Error", "Connection Error" + ": " + e.getMessage());
+				logger.severe(e.getMessage());
+			} catch (IOException e) {
+				connectionManager.showReconnectDialog("Connection Error", "Connection Error" + ": " + e.getMessage());
+				logger.severe(e.getMessage());
+			} catch (FatalException e) {
+				connectionManager.showReconnectDialog("Connection Error", "Connection Error" + ": " + e.getMessage());
+				logger.severe(e.getMessage());
+			}
+		}
+	}
+		*/
+
+
--- a/src/viewer_swing/java/com/glavsoft/viewer/swing/ParametersHandler.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/viewer_swing/java/com/glavsoft/viewer/swing/ParametersHandler.java	Tue Dec 17 20:16:48 2013 +0900
@@ -62,6 +62,7 @@
 
 	public static boolean isSeparateFrame;
     public static boolean allowAppletInteractiveConnections;
+	public static Object showControls;
 
     public static void completeParserOptions(Parser parser) {
 		parser.addOption(ARG_HELP, null, "Print this help.");
--- a/src/viewer_swing/java/com/glavsoft/viewer/swing/RendererImpl.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/viewer_swing/java/com/glavsoft/viewer/swing/RendererImpl.java	Tue Dec 17 20:16:48 2013 +0900
@@ -38,7 +38,8 @@
 
 public class RendererImpl extends Renderer implements ImageObserver {
     CyclicBarrier barrier = new CyclicBarrier(2);
-    private final Image offscreanImage;
+	private final Image offscreanImage;
+
 	public RendererImpl(Reader reader, int width, int height, PixelFormat pixelFormat) {
 		if (0 == width) width = 1;
 		if (0 == height) height = 1;
--- a/src/viewer_swing/java/com/glavsoft/viewer/swing/Surface.java	Mon Dec 16 17:06:19 2013 +0900
+++ b/src/viewer_swing/java/com/glavsoft/viewer/swing/Surface.java	Tue Dec 17 20:16:48 2013 +0900
@@ -34,6 +34,7 @@
 import com.glavsoft.rfb.protocol.ProtocolSettings;
 import com.glavsoft.transport.Reader;
 import com.glavsoft.viewer.UiSettings;
+import com.glavsoft.viewer.Viewer;
 
 import javax.swing.*;
 import java.awt.*;
@@ -54,7 +55,6 @@
     private SwingViewerWindow viewerWindow;
     private double scaleFactor;
 	public Dimension oldSize;
-
 	@Override
 	public boolean isDoubleBuffered() {
 		// TODO returning false in some reason may speed ups drawing, but may
@@ -68,7 +68,7 @@
 		init(context.getFbWidth(), context.getFbHeight());
 		oldSize = getPreferredSize();
 
-		if ( ! context.getSettings().isViewOnly()) {
+		if (!context.getSettings().isViewOnly()) {
 			setUserInputEnabled(true, context.getSettings().isConvertToAscii());
 		}
 		showCursor = context.getSettings().isShowRemoteCursor();
@@ -245,7 +245,6 @@
     @Override
 	public void setPixelFormat(PixelFormat pixelFormat) {
 		if (renderer != null) {
-			renderer.initPixelFormat(pixelFormat);
 		}
 	}