Adds support for fence & continuous updates extensions to java viewer. Adds low level hooks for TurboVNC fine grained quality controls.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4847 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/java/com/tigervnc/rfb/CMsgHandler.java b/java/com/tigervnc/rfb/CMsgHandler.java
index 3118200..533bfbc 100644
--- a/java/com/tigervnc/rfb/CMsgHandler.java
+++ b/java/com/tigervnc/rfb/CMsgHandler.java
@@ -61,6 +61,16 @@
cp.setName(name);
}
+ public void fence(int flags, int len, byte[] data)
+ {
+ cp.supportsFence = true;
+ }
+
+ public void endOfContinuousUpdates()
+ {
+ cp.supportsContinuousUpdates = true;
+ }
+
public void clientRedirect(int port, String host,
String x509subject) {}
diff --git a/java/com/tigervnc/rfb/CMsgReaderV3.java b/java/com/tigervnc/rfb/CMsgReaderV3.java
index 6d9e254..915b1e0 100644
--- a/java/com/tigervnc/rfb/CMsgReaderV3.java
+++ b/java/com/tigervnc/rfb/CMsgReaderV3.java
@@ -51,6 +51,8 @@
case MsgTypes.msgTypeSetColourMapEntries: readSetColourMapEntries(); break;
case MsgTypes.msgTypeBell: readBell(); break;
case MsgTypes.msgTypeServerCutText: readServerCutText(); break;
+ case MsgTypes.msgTypeServerFence: readFence(); break;
+ case MsgTypes.msgTypeEndOfContinuousUpdates: readEndOfContinuousUpdates(); break;
default:
vlog.error("unknown message type "+type);
throw new Exception("unknown message type");
@@ -136,6 +138,33 @@
handler.setExtendedDesktopSize(x, y, w, h, layout);
}
+ void readFence()
+ {
+ int flags;
+ int len;
+ byte[] data = new byte[64];
+
+ is.skip(3);
+
+ flags = is.readU32();
+
+ len = is.readU8();
+ if (len > data.length) {
+ System.out.println("Ignoring fence with too large payload\n");
+ is.skip(len);
+ return;
+ }
+
+ is.readBytes(data, 0, len);
+
+ handler.fence(flags, len, data);
+ }
+
+ void readEndOfContinuousUpdates()
+ {
+ handler.endOfContinuousUpdates();
+ }
+
void readClientRedirect(int x, int y, int w, int h)
{
int port = is.readU16();
diff --git a/java/com/tigervnc/rfb/CMsgWriter.java b/java/com/tigervnc/rfb/CMsgWriter.java
index 7cafddd..c4f4355 100644
--- a/java/com/tigervnc/rfb/CMsgWriter.java
+++ b/java/com/tigervnc/rfb/CMsgWriter.java
@@ -59,9 +59,16 @@
encodings[nEncodings++] = Encodings.pseudoEncodingDesktopName;
if (cp.supportsClientRedirect)
encodings[nEncodings++] = Encodings.pseudoEncodingClientRedirect;
+
+ encodings[nEncodings++] = Encodings.pseudoEncodingLastRect;
+ encodings[nEncodings++] = Encodings.pseudoEncodingContinuousUpdates;
+ encodings[nEncodings++] = Encodings.pseudoEncodingFence;
+
+
if (Decoder.supported(preferredEncoding)) {
encodings[nEncodings++] = preferredEncoding;
}
+
if (useCopyRect) {
encodings[nEncodings++] = Encodings.encodingCopyRect;
}
diff --git a/java/com/tigervnc/rfb/CMsgWriterV3.java b/java/com/tigervnc/rfb/CMsgWriterV3.java
index ec30a82..430c374 100644
--- a/java/com/tigervnc/rfb/CMsgWriterV3.java
+++ b/java/com/tigervnc/rfb/CMsgWriterV3.java
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2009-2011 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -65,4 +66,42 @@
endMsg();
}
+
+ public void writeFence(int flags, int len, byte[] data)
+ {
+ if (!cp.supportsFence)
+ throw new Exception("Server does not support fences");
+ if (len > 64)
+ throw new Exception("Too large fence payload");
+ if ((flags & ~fenceTypes.fenceFlagsSupported) != 0)
+ throw new Exception("Unknown fence flags");
+
+ startMsg(MsgTypes.msgTypeClientFence);
+ os.pad(3);
+
+ os.writeU32(flags);
+
+ os.writeU8(len);
+ os.writeBytes(data, 0, len);
+
+ endMsg();
+ }
+
+ public void writeEnableContinuousUpdates(boolean enable,
+ int x, int y, int w, int h)
+ {
+ if (!cp.supportsContinuousUpdates)
+ throw new Exception("Server does not support continuous updates");
+
+ startMsg(MsgTypes.msgTypeEnableContinuousUpdates);
+
+ os.writeU8((enable?1:0));
+
+ os.writeU16(x);
+ os.writeU16(y);
+ os.writeU16(w);
+ os.writeU16(h);
+
+ endMsg();
+ }
}
diff --git a/java/com/tigervnc/rfb/ConnParams.java b/java/com/tigervnc/rfb/ConnParams.java
index 70d6114..7fac126 100644
--- a/java/com/tigervnc/rfb/ConnParams.java
+++ b/java/com/tigervnc/rfb/ConnParams.java
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright (C) 2012 TigerVNC Team.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,9 +30,12 @@
supportsLocalCursor = false; supportsLocalXCursor = false;
supportsDesktopResize = false; supportsExtendedDesktopSize = false;
supportsDesktopRename = false; supportsLastRect = false;
- supportsSetDesktopSize = false; supportsClientRedirect = false;
+ supportsSetDesktopSize = false; supportsFence = false;
+ supportsContinuousUpdates = false;
+ supportsClientRedirect = false;
customCompressLevel = false; compressLevel = 6;
- noJpeg = false; qualityLevel = -1;
+ noJpeg = false; qualityLevel = -1; fineQualityLevel = -1;
+ subsampling = "SUBSAMP_UNDEFINED";
name_ = null; nEncodings_ = 0; encodings_ = null;
currentEncoding_ = Encodings.encodingRaw; verStrPos = 0;
screenLayout = new ScreenSet();
@@ -115,20 +119,38 @@
useCopyRect = false;
supportsLocalCursor = false;
supportsDesktopResize = false;
+ supportsExtendedDesktopSize = false;
+ supportsLocalXCursor = false;
+ supportsLastRect = false;
customCompressLevel = false;
compressLevel = -1;
noJpeg = true;
qualityLevel = -1;
+ fineQualityLevel = -1;
+ subsampling = "SUBSAMP_UNDEFINED";
currentEncoding_ = Encodings.encodingRaw;
for (int i = nEncodings-1; i >= 0; i--) {
encodings_[i] = encodings[i];
+
if (encodings[i] == Encodings.encodingCopyRect)
useCopyRect = true;
else if (encodings[i] == Encodings.pseudoEncodingCursor)
supportsLocalCursor = true;
+ else if (encodings[i] == Encodings.pseudoEncodingXCursor)
+ supportsLocalXCursor = true;
else if (encodings[i] == Encodings.pseudoEncodingDesktopSize)
supportsDesktopResize = true;
+ else if (encodings[i] == Encodings.pseudoEncodingExtendedDesktopSize)
+ supportsExtendedDesktopSize = true;
+ else if (encodings[i] == Encodings.pseudoEncodingDesktopName)
+ supportsDesktopRename = true;
+ else if (encodings[i] == Encodings.pseudoEncodingLastRect)
+ supportsLastRect = true;
+ else if (encodings[i] == Encodings.pseudoEncodingFence)
+ supportsFence = true;
+ else if (encodings[i] == Encodings.pseudoEncodingContinuousUpdates)
+ supportsContinuousUpdates = true;
else if (encodings[i] == Encodings.pseudoEncodingClientRedirect)
supportsClientRedirect = true;
else if (encodings[i] >= Encodings.pseudoEncodingCompressLevel0 &&
@@ -143,6 +165,20 @@
Encoder.supported(encodings[i]))
currentEncoding_ = encodings[i];
}
+
+ // If the TurboVNC fine quality/subsampling encodings exist, let them
+ // override the coarse TightVNC quality level
+ for (int i = nEncodings-1; i >= 0; i--) {
+ if (encodings[i] >= Encodings.pseudoEncodingFineQualityLevel0 + 1 &&
+ encodings[i] <= Encodings.pseudoEncodingFineQualityLevel100) {
+ noJpeg = false;
+ fineQualityLevel = encodings[i] - Encodings.pseudoEncodingFineQualityLevel0;
+ } else if (encodings[i] >= Encodings.pseudoEncodingSubsamp1X &&
+ encodings[i] <= Encodings.pseudoEncodingSubsampGray) {
+ noJpeg = false;
+ subsampling = JpegCompressor.subsamplingName(encodings[i] - Encodings.pseudoEncodingSubsamp1X);
+ }
+ }
}
public boolean useCopyRect;
@@ -152,6 +188,8 @@
public boolean supportsExtendedDesktopSize;
public boolean supportsDesktopRename;
public boolean supportsClientRedirect;
+ public boolean supportsFence;
+ public boolean supportsContinuousUpdates;
public boolean supportsLastRect;
public boolean supportsSetDesktopSize;
@@ -160,6 +198,8 @@
public int compressLevel;
public boolean noJpeg;
public int qualityLevel;
+ public int fineQualityLevel;
+ public String subsampling;
private PixelFormat pf_;
private String name_;
diff --git a/java/com/tigervnc/rfb/Encodings.java b/java/com/tigervnc/rfb/Encodings.java
index 493d548..4dc129f 100644
--- a/java/com/tigervnc/rfb/Encodings.java
+++ b/java/com/tigervnc/rfb/Encodings.java
@@ -1,4 +1,6 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright (C) 2011 D. R. Commander. All Rights Reserved.
+ * Copyright (C) 2012 TigerVNC Team.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,6 +38,8 @@
public static final int pseudoEncodingExtendedDesktopSize = -308;
public static final int pseudoEncodingDesktopName = -307;
public static final int pseudoEncodingClientRedirect = -311;
+ public static final int pseudoEncodingFence = -312;
+ public static final int pseudoEncodingContinuousUpdates = -313;
// TightVNC-specific
public static final int pseudoEncodingLastRect = -224;
@@ -44,6 +48,16 @@
public static final int pseudoEncodingCompressLevel0 = -256;
public static final int pseudoEncodingCompressLevel9 = -247;
+ // TurboVNC-specific
+ public static final int pseudoEncodingFineQualityLevel0 = -512;
+ public static final int pseudoEncodingFineQualityLevel100 = -412;
+ public static final int pseudoEncodingSubsamp1X = -768;
+ public static final int pseudoEncodingSubsamp4X = -767;
+ public static final int pseudoEncodingSubsamp2X = -766;
+ public static final int pseudoEncodingSubsampGray = -765;
+ public static final int pseudoEncodingSubsamp8X = -764;
+ public static final int pseudoEncodingSubsamp16X = -763;
+
public static int encodingNum(String name) {
if (name.equalsIgnoreCase("raw")) return encodingRaw;
if (name.equalsIgnoreCase("copyRect")) return encodingCopyRect;
diff --git a/java/com/tigervnc/rfb/JpegCompressor.java b/java/com/tigervnc/rfb/JpegCompressor.java
new file mode 100644
index 0000000..929aa4e
--- /dev/null
+++ b/java/com/tigervnc/rfb/JpegCompressor.java
@@ -0,0 +1,48 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright (C) 2011 D. R. Commander. All Rights Reserved.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+package com.tigervnc.rfb;
+
+public class JpegCompressor {
+
+ public static final int SUBSAMP_UNDEFINED = -1;
+ public static final int SUBSAMP_NONE = 0;
+ public static final int SUBSAMP_420 = 1;
+ public static final int SUBSAMP_422 = 2;
+ public static final int SUBSAMP_GRAY = 3;
+
+ public static int subsamplingNum(String name) {
+ if (name.equalsIgnoreCase("SUBSAMP_UNDEFINED")) return SUBSAMP_UNDEFINED;
+ if (name.equalsIgnoreCase("SUBSAMP_NONE")) return SUBSAMP_NONE;
+ if (name.equalsIgnoreCase("SUBSAMP_420")) return SUBSAMP_420;
+ if (name.equalsIgnoreCase("SUBSAMP_422")) return SUBSAMP_422;
+ if (name.equalsIgnoreCase("SUBSAMP_GRAY")) return SUBSAMP_GRAY;
+ return SUBSAMP_UNDEFINED;
+ }
+
+ public static String subsamplingName(int num) {
+ switch (num) {
+ case SUBSAMP_UNDEFINED: return "SUBSAMP_UNDEFINED";
+ case SUBSAMP_NONE: return "SUBSAMP_NONE";
+ case SUBSAMP_420: return "SUBSAMP_420";
+ case SUBSAMP_422: return "SUBSAMP_422";
+ case SUBSAMP_GRAY: return "SUBSAMP_GRAY";
+ default: return "SUBSAMP_UNDEFINED";
+ }
+ }
+}
diff --git a/java/com/tigervnc/rfb/MsgTypes.java b/java/com/tigervnc/rfb/MsgTypes.java
index a009b39..2d452c8 100644
--- a/java/com/tigervnc/rfb/MsgTypes.java
+++ b/java/com/tigervnc/rfb/MsgTypes.java
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright (C) 2012 TigerVNC Team.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,6 +27,10 @@
public static final int msgTypeBell = 2;
public static final int msgTypeServerCutText = 3;
+ public static final int msgTypeEndOfContinuousUpdates = 150;
+
+ public static final int msgTypeServerFence = 248;
+
// client to server
public static final int msgTypeSetPixelFormat = 0;
@@ -36,5 +41,9 @@
public static final int msgTypePointerEvent = 5;
public static final int msgTypeClientCutText = 6;
+ public static final int msgTypeEnableContinuousUpdates = 150;
+
+ public static final int msgTypeClientFence = 248;
+
public static final int msgTypeSetDesktopSize = 251;
}
diff --git a/java/com/tigervnc/rfb/PixelBuffer.java b/java/com/tigervnc/rfb/PixelBuffer.java
index 2712ba9..4371355 100644
--- a/java/com/tigervnc/rfb/PixelBuffer.java
+++ b/java/com/tigervnc/rfb/PixelBuffer.java
@@ -36,9 +36,17 @@
throw new Exception("Internal error: bpp must be 8, 16, or 32 in PixelBuffer ("+pf.bpp+")");
format = pf;
switch (pf.depth) {
+ case 3:
+ // Fall-through to depth 8
+ case 6:
+ // Fall-through to depth 8
case 8:
- //cm = new IndexColorModel(8, 256, new byte[256], new byte[256], new byte[256]);
- cm = new DirectColorModel(8, 7, (7 << 3), (3 << 6));
+ int rmask = pf.redMax << pf.redShift;
+ int gmask = pf.greenMax << pf.greenShift;
+ int bmask = pf.blueMax << pf.blueShift;
+ cm = new DirectColorModel(8, rmask, gmask, bmask);
+ if (pf.depth == 8 && !pf.trueColour)
+ cm = new IndexColorModel(8, 256, new byte[256], new byte[256], new byte[256]);
break;
case 16:
cm = new DirectColorModel(32, 0xF800, 0x07C0, 0x003E, (0xff << 24));
diff --git a/java/com/tigervnc/rfb/fenceTypes.java b/java/com/tigervnc/rfb/fenceTypes.java
new file mode 100644
index 0000000..a8e32d3
--- /dev/null
+++ b/java/com/tigervnc/rfb/fenceTypes.java
@@ -0,0 +1,31 @@
+/* Copyright 2011 Pierre Ossman for Cendio AB
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+package com.tigervnc.rfb;
+
+public class fenceTypes {
+ public static final int fenceFlagBlockBefore = 1<<0;
+ public static final int fenceFlagBlockAfter = 1<<1;
+ public static final int fenceFlagSyncNext = 1<<2;
+
+ public static final int fenceFlagRequest = 1<<31;
+
+ public static final int fenceFlagsSupported = (fenceFlagBlockBefore |
+ fenceFlagBlockAfter |
+ fenceFlagSyncNext |
+ fenceFlagRequest);
+}