changeset 39:7afe8d10ad66

merge
author Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
date Tue, 24 Apr 2012 20:24:10 +0900
parents 1257c9e46975 (current diff) 0809b3005687 (diff)
children 816cdfe3a129
files
diffstat 8 files changed, 396 insertions(+), 234 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Apr 24 19:28:13 2012 +0900
+++ b/.hgtags	Tue Apr 24 20:24:10 2012 +0900
@@ -9,3 +9,4 @@
 2858fe757f0e635eec5a06ff3d0fb6e71485467d TreeVNC-Version-1.0
 23b3df33b4c50c371da60e72b6423c5b0dfd9552 TreeVNC-Version-1.1
 a477a210a39a99e06f0ea6eb19f7eb06dab5fc98 TreeVNC-Version-1.2
+cca2a548ed95e77f6baeef4c0629ce016b1e1e68 TreeVNC-Version-1.3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/treeVnc/DataInputStream1.java	Tue Apr 24 20:24:10 2012 +0900
@@ -0,0 +1,64 @@
+package treeVnc;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+
+public class DataInputStream1 implements MyDataInputStream {
+	DataInputStream is;
+	public DataInputStream1(BufferedInputStream bufferedInputStream) {
+		is = new DataInputStream(bufferedInputStream);
+	}
+
+	@Override
+	public void readFully(byte[] b, int off, int len) throws IOException {
+		is.readFully(b, off, len);
+	}
+
+	@Override
+	public int available() throws IOException {
+		return is.available();
+	}
+
+	@Override
+	public int skipBytes(int n) throws IOException {
+		return is.skipBytes(n);
+	}
+
+	@Override
+	public int readUnsignedByte() throws IOException {
+		return is.readUnsignedByte();
+	}
+
+	@Override
+	public int readUnsignedShort() throws IOException {
+		return is.readUnsignedShort();
+	}
+
+	@Override
+	public int readInt() throws IOException {
+		return is.readInt();
+	}
+
+	@Override
+	public void read(byte[] headBuf) throws IOException {
+		is.read(headBuf);		
+	}
+
+	@Override
+	public boolean markSupported() {
+		return is.markSupported();
+	}
+
+	@Override
+	public void mark(int i) {
+		is.mark(i);
+	}
+
+	@Override
+	public void reset() {
+		// TODO Auto-generated method stub
+		
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/treeVnc/MyDataInputStream.java	Tue Apr 24 20:24:10 2012 +0900
@@ -0,0 +1,25 @@
+package treeVnc;
+
+import java.io.IOException;
+
+public interface MyDataInputStream {
+	void readFully(byte[] b, int off, int len) throws IOException;
+
+	int available() throws IOException;
+
+	int skipBytes(int n) throws IOException;
+
+	int readUnsignedByte() throws IOException;
+
+	int readUnsignedShort() throws IOException;
+
+	int readInt() throws IOException;
+
+	void read(byte[] headBuf) throws IOException;
+
+	boolean markSupported();
+
+	void mark(int i);
+
+	void reset();
+}
--- a/src/treeVnc/MyRfbProtoClient.java	Tue Apr 24 19:28:13 2012 +0900
+++ b/src/treeVnc/MyRfbProtoClient.java	Tue Apr 24 20:24:10 2012 +0900
@@ -161,7 +161,7 @@
 		port = p;
 		
 		sock = new Socket(host, port);
-		is = new DataInputStream(new BufferedInputStream(sock.getInputStream(),
+		is = new DataInputStream1(new BufferedInputStream(sock.getInputStream(),
 				16384));
 		os = sock.getOutputStream();
 
@@ -390,10 +390,10 @@
 		cliListTmp.clear();
 	}
 
-	boolean ready() throws IOException {
-		BufferedReader br = new BufferedReader(new InputStreamReader(is));
-		return br.ready();
-	}
+//	boolean ready() throws IOException {
+//		BufferedReader br = new BufferedReader(new InputStreamReader(is));
+//		return br.ready();
+//	}
 
 	int cliSize() {
 		return cliList.size();
--- a/src/treeVnc/MyRfbProtoProxy.java	Tue Apr 24 19:28:13 2012 +0900
+++ b/src/treeVnc/MyRfbProtoProxy.java	Tue Apr 24 20:24:10 2012 +0900
@@ -398,10 +398,10 @@
 		cliListTmp.clear();
 	}
 
-	boolean ready() throws IOException {
-		BufferedReader br = new BufferedReader(new InputStreamReader(is));
-		return br.ready();
-	}
+//	boolean ready() throws IOException {
+//		BufferedReader br = new BufferedReader(new InputStreamReader(is));
+//		return br.ready();
+//	}
 
 	int cliSize() {
 		return cliList.size();
--- a/src/treeVnc/ProxyVncCanvas.java	Tue Apr 24 19:28:13 2012 +0900
+++ b/src/treeVnc/ProxyVncCanvas.java	Tue Apr 24 20:24:10 2012 +0900
@@ -361,13 +361,13 @@
 		// main dispatch loop
 		//
 		
-		long count = 0;
+//		long count = 0;
 		long buf = 0;
 		while (true) {
 //			System.out.println("\ncount=" + count);
 			
 			
-			count++;
+//			count++;
 			
 			/**
 			 *  read Data from parents and send Data to Client.
@@ -388,202 +388,7 @@
 				continue;
 			}
 
-
-
-			long numBytesRead = rfb.getNumBytesRead();
-			
-			// Read message type from the server. 
-			int msgType = rfb.readServerMessageType();
-
-			// Process the message depending on its type.
-			switch (msgType) {
-			case MyRfbProtoProxy.SpeedCheckMillis:
-				rfb.readSpeedCheck();
-				break;
-			case RfbProto.FramebufferUpdate:
-
-				if(msgType == RfbProto.FramebufferUpdate){ 
-					rfb.is.reset();
-					break;
-				}
-
-				if (statNumUpdates == viewer.debugStatsExcludeUpdates
-						&& !statsRestarted) {
-					resetStats();
-					statsRestarted = true;
-				} else if (statNumUpdates == viewer.debugStatsMeasureUpdates
-						&& statsRestarted) {
-					viewer.disconnect();
-				}
-
-				rfb.readFramebufferUpdate();
-				statNumUpdates++;
-//				System.out.println("NRects = "+ rfb.updateNRects);
-
-				boolean cursorPosReceived = false;
-
-				for (int i = 0; i < rfb.updateNRects; i++) {
-
-					rfb.readFramebufferUpdateRectHdr();
-					statNumTotalRects++;
-					int rx = rfb.updateRectX, ry = rfb.updateRectY;
-					int rw = rfb.updateRectW, rh = rfb.updateRectH;
-					System.out.println("rx = "+ rx + "  ry = "+ry+"\nrw = "+rw+"  rh = "+rh);
-					System.out.println("encoding = "+ rfb.updateRectEncoding);
-					
-					if (rfb.updateRectEncoding == rfb.EncodingLastRect)
-						break;
-
-					if (rfb.updateRectEncoding == rfb.EncodingNewFBSize) {
-						rfb.setFramebufferSize(rw, rh);
-						updateFramebufferSize();
-						break;
-					}
-
-					if (rfb.updateRectEncoding == rfb.EncodingXCursor
-							|| rfb.updateRectEncoding == rfb.EncodingRichCursor) {
-						handleCursorShapeUpdate(rfb.updateRectEncoding, rx, ry,
-								rw, rh);
-						continue;
-					}
-
-					if (rfb.updateRectEncoding == rfb.EncodingPointerPos) {
-						softCursorMove(rx, ry);
-						cursorPosReceived = true;
-						continue;
-					}
-
-					long numBytesReadBefore = rfb.getNumBytesRead();
-
-					rfb.startTiming();
-
-					switch (rfb.updateRectEncoding) {
-					case RfbProto.EncodingRaw:
-						statNumRectsRaw++;
-						handleRawRect(rx, ry, rw, rh);
-						break;
-					case RfbProto.EncodingCopyRect:
-						statNumRectsCopy++;
-						handleCopyRect(rx, ry, rw, rh);
-						break;
-					case RfbProto.EncodingRRE:
-						handleRRERect(rx, ry, rw, rh);
-						break;
-					case RfbProto.EncodingCoRRE:
-						handleCoRRERect(rx, ry, rw, rh);
-						break;
-					case RfbProto.EncodingHextile:
-						statNumRectsHextile++;
-						handleHextileRect(rx, ry, rw, rh);
-						break;
-					case RfbProto.EncodingZRLE:
-					case RfbProto.EncodingZRLEE:
-						statNumRectsZRLE++;
-						handleZRLERect(rx, ry, rw, rh);
-						break;
-					case RfbProto.EncodingZlib:
-						handleZlibRect(rx, ry, rw, rh);
-						break;
-					case RfbProto.EncodingTight:
-						statNumRectsTight++;
-						handleTightRect(rx, ry, rw, rh);
-						break;
-					default:
-						throw new Exception("Unknown RFB rectangle encoding "
-								+ rfb.updateRectEncoding);
-					}
-
-					rfb.stopTiming();
-//					long kbitsPerSecond = rfb.kbitsPerSecond(); 
-//					System.out.println("Throughput " + kbitsPerSecond + " kbit/s");
-
-					
-					statNumPixelRects++;
-					statNumBytesDecoded += rw * rh * bytesPixel;
-					statNumBytesEncoded += (int) (rfb.getNumBytesRead() - numBytesReadBefore);
-				}
-
-				boolean fullUpdateNeeded = false;
-
-				// Start/stop session recording if necessary. Request full
-				// update if a new session file was opened.
-				if (viewer.checkRecordingStatus())
-					fullUpdateNeeded = true;
-
-				// Defer framebuffer update request if necessary. But wake up
-				// immediately on keyboard or mouse event. Also, don't sleep
-				// if there is some data to receive, or if the last update
-				// included a PointerPos message.
-				if (viewer.deferUpdateRequests > 0 && rfb.available() == 0
-						&& !cursorPosReceived) {
-					synchronized (rfb) {
-						try {
-							rfb.wait(viewer.deferUpdateRequests);
-						} catch (InterruptedException e) {
-						}
-					}
-				}
-
-				viewer.autoSelectEncodings();
-
-				// Before requesting framebuffer update, check if the pixel
-				// format should be changed.
-/*
-				if (viewer.options.eightBitColors != (bytesPixel == 1)) {
-					// Pixel format should be changed.
-					setPixelFormat();
-					fullUpdateNeeded = true;
-				}
-*/
-				// Request framebuffer update if needed.
-				int w = rfb.framebufferWidth;
-				int h = rfb.framebufferHeight;
-				rfb.writeFramebufferUpdateRequest(0, 0, w, h, !fullUpdateNeeded);
-				//rfb.checkDelayData();
-
-				break;
-
-			case RfbProto.SetColourMapEntries:
-				throw new Exception("Can't handle SetColourMapEntries message");
-
-			case RfbProto.Bell:
-//				Toolkit.getDefaultToolkit().beep(); // OS X Lion VNC server send bell. Caused feed back view bell. 
-				break;
-
-			case RfbProto.ServerCutText:
-				String s = rfb.readServerCutText();
-				viewer.clipboard.setCutText(s);
-				break;
-				
-			case RfbProto.CheckDelay:
-				rfb.checkDelayData();
-				break;
-			
-			default:
-				throw new Exception("Unknown RFB message type " + msgType);
-			}
-			
-			
-
-//			int bufSize = (int)(rfb.getNumBytesRead() - numBytesRead);
-			long bufSize = rfb.getNumBytesRead() - numBytesRead;
-//			System.out.println("bufSize="+bufSize);
-
-			buf += rfb.getNumBytesRead() - numBytesRead;
-//			System.out.println("total buf = " + buf);
-//			rfb.bufResetSend(bufSize);
-
-
-
-			if(rfb.createBimgFlag){
-//				bimg = createBufferedImage(rawPixelsImage);
-				bimg = createBufferedImage(memImage);
-				//bimg(BufferedImage) -> rfb.pngBytes(byte[])
-				rfb.createPngBytes(bimg);
-				rfb.sendPngImage();	
-				rfb.createBimgFlag = false;
-			}
-
+			buf = decodePacket(rfb,statsRestarted,buf);
 			
 /*
 			boolean result = false;
@@ -596,6 +401,204 @@
 */
 		}
 	}
+	
+	long decodePacket(MyRfbProtoProxy rfb, boolean statsRestarted,long buf) throws Exception { 
+		long numBytesRead = rfb.getNumBytesRead();
+		
+		// Read message type from the server. 
+		int msgType = rfb.readServerMessageType();
+
+		// Process the message depending on its type.
+		switch (msgType) {
+		case MyRfbProtoProxy.SpeedCheckMillis:
+			rfb.readSpeedCheck();
+			break;
+		case RfbProto.FramebufferUpdate:
+
+			if(msgType == RfbProto.FramebufferUpdate){ 
+				rfb.is.reset();
+				break;
+			}
+
+			if (statNumUpdates == viewer.debugStatsExcludeUpdates
+					&& !statsRestarted) {
+				resetStats();
+				statsRestarted = true;
+			} else if (statNumUpdates == viewer.debugStatsMeasureUpdates
+					&& statsRestarted) {
+				viewer.disconnect();
+			}
+
+			rfb.readFramebufferUpdate();
+			statNumUpdates++;
+//			System.out.println("NRects = "+ rfb.updateNRects);
+
+			boolean cursorPosReceived = false;
+
+			for (int i = 0; i < rfb.updateNRects; i++) {
+
+				rfb.readFramebufferUpdateRectHdr();
+				statNumTotalRects++;
+				int rx = rfb.updateRectX, ry = rfb.updateRectY;
+				int rw = rfb.updateRectW, rh = rfb.updateRectH;
+				System.out.println("rx = "+ rx + "  ry = "+ry+"\nrw = "+rw+"  rh = "+rh);
+				System.out.println("encoding = "+ rfb.updateRectEncoding);
+				
+				if (rfb.updateRectEncoding == RfbProto.EncodingLastRect)
+					break;
+
+				if (rfb.updateRectEncoding == RfbProto.EncodingNewFBSize) {
+					rfb.setFramebufferSize(rw, rh);
+					updateFramebufferSize();
+					break;
+				}
+
+				if (rfb.updateRectEncoding == RfbProto.EncodingXCursor
+						|| rfb.updateRectEncoding == RfbProto.EncodingRichCursor) {
+					handleCursorShapeUpdate(rfb.updateRectEncoding, rx, ry,
+							rw, rh);
+					continue;
+				}
+
+				if (rfb.updateRectEncoding == RfbProto.EncodingPointerPos) {
+					softCursorMove(rx, ry);
+					cursorPosReceived = true;
+					continue;
+				}
+
+				long numBytesReadBefore = rfb.getNumBytesRead();
+
+				rfb.startTiming();
+
+				switch (rfb.updateRectEncoding) {
+				case RfbProto.EncodingRaw:
+					statNumRectsRaw++;
+					handleRawRect(rx, ry, rw, rh);
+					break;
+				case RfbProto.EncodingCopyRect:
+					statNumRectsCopy++;
+					handleCopyRect(rx, ry, rw, rh);
+					break;
+				case RfbProto.EncodingRRE:
+					handleRRERect(rx, ry, rw, rh);
+					break;
+				case RfbProto.EncodingCoRRE:
+					handleCoRRERect(rx, ry, rw, rh);
+					break;
+				case RfbProto.EncodingHextile:
+					statNumRectsHextile++;
+					handleHextileRect(rx, ry, rw, rh);
+					break;
+				case RfbProto.EncodingZRLE:
+				case RfbProto.EncodingZRLEE:
+					statNumRectsZRLE++;
+					handleZRLERect(rx, ry, rw, rh);
+					break;
+				case RfbProto.EncodingZlib:
+					handleZlibRect(rx, ry, rw, rh);
+					break;
+				case RfbProto.EncodingTight:
+					statNumRectsTight++;
+					handleTightRect(rx, ry, rw, rh);
+					break;
+				default:
+					throw new Exception("Unknown RFB rectangle encoding "
+							+ rfb.updateRectEncoding);
+				}
+
+				rfb.stopTiming();
+//				long kbitsPerSecond = rfb.kbitsPerSecond(); 
+//				System.out.println("Throughput " + kbitsPerSecond + " kbit/s");
+
+				
+				statNumPixelRects++;
+				statNumBytesDecoded += rw * rh * bytesPixel;
+				statNumBytesEncoded += (int) (rfb.getNumBytesRead() - numBytesReadBefore);
+			}
+
+			boolean fullUpdateNeeded = false;
+
+			// Start/stop session recording if necessary. Request full
+			// update if a new session file was opened.
+			if (viewer.checkRecordingStatus())
+				fullUpdateNeeded = true;
+
+			// Defer framebuffer update request if necessary. But wake up
+			// immediately on keyboard or mouse event. Also, don't sleep
+			// if there is some data to receive, or if the last update
+			// included a PointerPos message.
+			if (viewer.deferUpdateRequests > 0 && rfb.available() == 0
+					&& !cursorPosReceived) {
+				synchronized (rfb) {
+					try {
+						rfb.wait(viewer.deferUpdateRequests);
+					} catch (InterruptedException e) {
+					}
+				}
+			}
+
+			viewer.autoSelectEncodings();
+
+			// Before requesting framebuffer update, check if the pixel
+			// format should be changed.
+/*
+			if (viewer.options.eightBitColors != (bytesPixel == 1)) {
+				// Pixel format should be changed.
+				setPixelFormat();
+				fullUpdateNeeded = true;
+			}
+*/
+			// Request framebuffer update if needed.
+			int w = rfb.framebufferWidth;
+			int h = rfb.framebufferHeight;
+			rfb.writeFramebufferUpdateRequest(0, 0, w, h, !fullUpdateNeeded);
+			//rfb.checkDelayData();
+
+			break;
+
+		case RfbProto.SetColourMapEntries:
+			throw new Exception("Can't handle SetColourMapEntries message");
+
+		case RfbProto.Bell:
+//			Toolkit.getDefaultToolkit().beep(); // OS X Lion VNC server send bell. Caused feed back view bell. 
+			break;
+
+		case RfbProto.ServerCutText:
+			String s = rfb.readServerCutText();
+			viewer.clipboard.setCutText(s);
+			break;
+			
+		case RfbProto.CheckDelay:
+			rfb.checkDelayData();
+			break;
+		
+		default:
+			throw new Exception("Unknown RFB message type " + msgType);
+		}
+		
+		
+
+//		int bufSize = (int)(rfb.getNumBytesRead() - numBytesRead);
+//		long bufSize = rfb.getNumBytesRead() - numBytesRead;
+//		System.out.println("bufSize="+bufSize);
+
+		buf += rfb.getNumBytesRead() - numBytesRead;
+//		System.out.println("total buf = " + buf);
+//		rfb.bufResetSend(bufSize);
+
+
+
+		if(rfb.createBimgFlag){
+//			bimg = createBufferedImage(rawPixelsImage);
+			bimg = createBufferedImage(memImage);
+			//bimg(BufferedImage) -> rfb.pngBytes(byte[])
+			rfb.createPngBytes(bimg);
+			rfb.sendPngImage();	
+			rfb.createBimgFlag = false;
+			
+		}
+		return buf;
+}
 
 	//
 	// Handle a raw rectangle. The second form with paint==false is used
@@ -799,14 +802,14 @@
 		}
 
 		// Is it a raw-encoded sub-rectangle?
-		if ((subencoding & rfb.HextileRaw) != 0) {
+		if ((subencoding & RfbProto.HextileRaw) != 0) {
 			handleRawRect(tx, ty, tw, th, false);
 			return;
 		}
 
 		// Read and draw the background if specified.
 		byte[] cbuf = new byte[bytesPixel];
-		if ((subencoding & rfb.HextileBackgroundSpecified) != 0) {
+		if ((subencoding & RfbProto.HextileBackgroundSpecified) != 0) {
 			rfb.readFully(cbuf);
 			if (bytesPixel == 1) {
 				hextile_bg = colors[cbuf[0] & 0xFF];
@@ -822,7 +825,7 @@
 		memGraphics.fillRect(tx, ty, tw, th);
 
 		// Read the foreground color if specified.
-		if ((subencoding & rfb.HextileForegroundSpecified) != 0) {
+		if ((subencoding & RfbProto.HextileForegroundSpecified) != 0) {
 			rfb.readFully(cbuf);
 			if (bytesPixel == 1) {
 				hextile_fg = colors[cbuf[0] & 0xFF];
@@ -836,12 +839,12 @@
 		}
 
 		// Done with this tile if there is no sub-rectangles.
-		if ((subencoding & rfb.HextileAnySubrects) == 0)
+		if ((subencoding & RfbProto.HextileAnySubrects) == 0)
 			return;
 
 		int nSubrects = rfb.readU8();
 		int bufsize = nSubrects * 2;
-		if ((subencoding & rfb.HextileSubrectsColoured) != 0) {
+		if ((subencoding & RfbProto.HextileSubrectsColoured) != 0) {
 			bufsize += nSubrects * bytesPixel;
 		}
 		byte[] buf = new byte[bufsize];
@@ -854,7 +857,7 @@
 		int b1, b2, sx, sy, sw, sh;
 		int i = 0;
 
-		if ((subencoding & rfb.HextileSubrectsColoured) == 0) {
+		if ((subencoding & RfbProto.HextileSubrectsColoured) == 0) {
 
 			// Sub-rectangles are all of the same color.
 			memGraphics.setColor(hextile_fg);
@@ -1002,7 +1005,7 @@
 	}
 
 	void readPixels(InStream is, int[] dst, int count) throws Exception {
-		int pix;
+	//	int pix;
 		if (bytesPixel == 1) {
 			byte[] buf = new byte[count];
 			is.readBytes(buf, 0, count);
@@ -1200,8 +1203,8 @@
 
 		int comp_ctl = rfb.readU8();
 		if (rfb.rec != null) {
-			if (rfb.recordFromBeginning || comp_ctl == (rfb.TightFill << 4)
-					|| comp_ctl == (rfb.TightJpeg << 4)) {
+			if (rfb.recordFromBeginning || comp_ctl == (RfbProto.TightFill << 4)
+					|| comp_ctl == (RfbProto.TightJpeg << 4)) {
 				// Send data exactly as received.
 				rfb.rec.writeByte(comp_ctl);
 			} else {
@@ -1219,12 +1222,12 @@
 		}
 
 		// Check correctness of subencoding value.
-		if (comp_ctl > rfb.TightMaxSubencoding) {
+		if (comp_ctl > RfbProto.TightMaxSubencoding) {
 			throw new Exception("Incorrect tight subencoding: " + comp_ctl);
 		}
 
 		// Handle solid-color rectangles.
-		if (comp_ctl == rfb.TightFill) {
+		if (comp_ctl == RfbProto.TightFill) {
 
 			if (bytesPixel == 1) {
 				int idx = rfb.readU8();
@@ -1248,7 +1251,7 @@
 
 		}
 
-		if (comp_ctl == rfb.TightJpeg) {
+		if (comp_ctl == RfbProto.TightJpeg) {
 
 			statNumRectsTightJPEG++;
 
@@ -1292,12 +1295,12 @@
 		byte[] palette8 = new byte[2];
 		int[] palette24 = new int[256];
 		boolean useGradient = false;
-		if ((comp_ctl & rfb.TightExplicitFilter) != 0) {
+		if ((comp_ctl & RfbProto.TightExplicitFilter) != 0) {
 			int filter_id = rfb.readU8();
 			if (rfb.rec != null) {
 				rfb.rec.writeByte(filter_id);
 			}
-			if (filter_id == rfb.TightFilterPalette) {
+			if (filter_id == RfbProto.TightFilterPalette) {
 				numColors = rfb.readU8() + 1;
 				if (rfb.rec != null) {
 					rfb.rec.writeByte(numColors - 1);
@@ -1324,9 +1327,9 @@
 				}
 				if (numColors == 2)
 					rowSize = (w + 7) / 8;
-			} else if (filter_id == rfb.TightFilterGradient) {
+			} else if (filter_id == RfbProto.TightFilterGradient) {
 				useGradient = true;
-			} else if (filter_id != rfb.TightFilterCopy) {
+			} else if (filter_id != RfbProto.TightFilterCopy) {
 				throw new Exception("Incorrect tight filter id: " + filter_id);
 			}
 		}
@@ -1335,7 +1338,7 @@
 
 		// Read, optionally uncompress and decode data.
 		int dataSize = h * rowSize;
-		if (dataSize < rfb.TightMinToCompress) {
+		if (dataSize < RfbProto.TightMinToCompress) {
 			// Data size is small - not compressed with zlib.
 			if (numColors != 0) {
 				// Indexed colors.
@@ -1737,7 +1740,7 @@
 			int bytesPerRow = (width + 7) / 8;
 			int bytesMaskData = bytesPerRow * height;
 
-			if (encodingType == rfb.EncodingXCursor) {
+			if (encodingType == RfbProto.EncodingXCursor) {
 				rfb.skipBytes(6 + bytesMaskData * 2);
 			} else {
 				// rfb.EncodingRichCursor
@@ -1777,7 +1780,7 @@
 
 		int[] softCursorPixels = new int[width * height];
 
-		if (encodingType == rfb.EncodingXCursor) {
+		if (encodingType == RfbProto.EncodingXCursor) {
 
 			// Read foreground and background colors of the cursor.
 			byte[] rgb = new byte[6];
@@ -1829,7 +1832,7 @@
 			rfb.readFully(maskBuf);
 
 			// Decode pixel data into softCursorPixels[].
-			byte pixByte, maskByte;
+			byte maskByte;
 			int x, y, n, result;
 			int i = 0;
 			for (y = 0; y < height; y++) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/treeVnc/ReadHandler.java	Tue Apr 24 20:24:10 2012 +0900
@@ -0,0 +1,22 @@
+package treeVnc;
+
+import java.nio.channels.spi.AbstractSelectableChannel;
+
+public class ReadHandler {
+
+	private AbstractSelectableChannel channel;
+
+	public ReadHandler(RfbProto rfbProto, AbstractSelectableChannel ssChannel) {
+		this.setChannel(ssChannel);
+		
+	}
+
+	public AbstractSelectableChannel getChannel() {
+		return channel;
+	}
+
+	public void setChannel(AbstractSelectableChannel channel) {
+		this.channel = channel;
+	}
+
+}
--- a/src/treeVnc/RfbProto.java	Tue Apr 24 19:28:13 2012 +0900
+++ b/src/treeVnc/RfbProto.java	Tue Apr 24 20:24:10 2012 +0900
@@ -27,7 +27,15 @@
 
 import java.io.*;
 import java.awt.event.*;
+import java.net.DatagramSocket;
+import java.net.InetSocketAddress;
 import java.net.Socket;
+import java.net.SocketException;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.spi.AbstractSelector;
+import java.nio.channels.spi.SelectorProvider;
 import java.util.zip.*;
 
 public class RfbProto {
@@ -112,6 +120,7 @@
 			TightFilterCopy = 0x00, TightFilterPalette = 0x01,
 			TightFilterGradient = 0x02;
 
+	static AbstractSelector selector;
 	String host;
 	int port;
 	Socket sock;
@@ -125,7 +134,7 @@
 	// only via RfbProto methods. We have to do this because we want to
 	// count how many bytes were read.
 //	private DataInputStream is;
-	protected DataInputStream is;
+	protected MyDataInputStream is;
 //	private long numBytesRead = 0;
 	protected long numBytesRead = 0;
 
@@ -188,7 +197,7 @@
 		port = p;
 
 		if (viewer.socketFactory == null) {
-			sock = new Socket(host, port);
+			sock = newSocket(host, port);
 		} else {
 			try {
 				Class factoryClass = Class.forName(viewer.socketFactory);
@@ -203,7 +212,7 @@
 				throw new IOException(e.getMessage());
 			}
 		}
-		is = new DataInputStream(new BufferedInputStream(sock.getInputStream(),
+		is = new DataInputStream1(new BufferedInputStream(sock.getInputStream(),
 				16384));
 		os = sock.getOutputStream();
 
@@ -216,8 +225,8 @@
 		host = h;
 		port = p;
 
-		sock = new Socket(host, port);
-		is = new DataInputStream(new BufferedInputStream(sock.getInputStream(),
+		sock = newSocket(host, port);
+		is = new DataInputStream1(new BufferedInputStream(sock.getInputStream(),
 				16384));
 		os = sock.getOutputStream();
 
@@ -226,15 +235,53 @@
 		timedKbits = 0;
 	}
 	
+	private Socket newSocket(String host, int port) throws IOException {
+		SocketChannel ssChannel = SelectorProvider.provider().openSocketChannel();
+		ssChannel.socket().setReuseAddress(true);
+		// this should work for IPv6/IPv4 dual stack
+		// check this using netstat -an result tcp46.
+		try {
+			InetSocketAddress address = new InetSocketAddress(host, port);
+			ssChannel.socket().bind(address);
+		} catch (SocketException e) {
+			// for some bad IPv6 implementation
+			ssChannel.socket().bind(new InetSocketAddress(port));
+		}
+		ssChannel.configureBlocking(false);
+		ssChannel.register(selector, SelectionKey.OP_READ, new ReadHandler(this, ssChannel));
+		return ssChannel.socket();
+	}
+	
+	public DatagramSocket newDatagramSocket(String host, int port) throws IOException {
+		DatagramChannel ssChannel = SelectorProvider.provider().openDatagramChannel();
+		ssChannel.socket().setReuseAddress(true);
+		// this should work for IPv6/IPv4 dual stack
+		// check this using netstat -an result tcp46.
+		try {
+			InetSocketAddress address = new InetSocketAddress(host, port);
+			ssChannel.socket().bind(address);
+		} catch (SocketException e) {
+			// for some bad IPv6 implementation
+			ssChannel.socket().bind(new InetSocketAddress(port));
+		}
+		ssChannel.configureBlocking(false);
+		ssChannel.register(selector, SelectionKey.OP_READ, new ReadHandler(this, ssChannel));
+		return ssChannel.socket();
+	}
+	
 	public RfbProto() {
 		
 	}
 	
+	public void initOnce() throws IOException {
+		selector = SelectorProvider.provider().openSelector();
+	}
+	
 	public void changeRfbProto(String h,int port) throws IOException {
 		host = h;
 		sock=null;
-		sock = new Socket(host, port);
-		is = new DataInputStream(new BufferedInputStream(sock.getInputStream(),
+		sock = newSocket(host, port);
+		is = new DataInputStream1(new BufferedInputStream(sock.getInputStream(),
 				16384));
 		os = sock.getOutputStream();