aboutsummaryrefslogtreecommitdiffstats
path: root/java/com/tigervnc/rfb
diff options
context:
space:
mode:
authorDRC <dcommander@users.sourceforge.net>2011-10-07 05:38:00 +0000
committerDRC <dcommander@users.sourceforge.net>2011-10-07 05:38:00 +0000
commitc19ab9ec7f3ac4823802388ac953e9494c613575 (patch)
tree63513ffd7ce0b3ab3de2d9b619cc4e5b892eea31 /java/com/tigervnc/rfb
parentbba54b0b14fded1d457f426cdc8843a34d6c9dc5 (diff)
downloadtigervnc-c19ab9ec7f3ac4823802388ac953e9494c613575.tar.gz
tigervnc-c19ab9ec7f3ac4823802388ac953e9494c613575.zip
Move Java source up one level and allow Java viewer to be built as a standalone project (per community request)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4715 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'java/com/tigervnc/rfb')
-rw-r--r--java/com/tigervnc/rfb/AliasParameter.java35
-rw-r--r--java/com/tigervnc/rfb/AuthFailureException.java23
-rw-r--r--java/com/tigervnc/rfb/BoolParameter.java51
-rw-r--r--java/com/tigervnc/rfb/CConnection.java356
-rw-r--r--java/com/tigervnc/rfb/CMsgHandler.java88
-rw-r--r--java/com/tigervnc/rfb/CMsgReader.java179
-rw-r--r--java/com/tigervnc/rfb/CMsgReaderV3.java155
-rw-r--r--java/com/tigervnc/rfb/CMsgWriter.java171
-rw-r--r--java/com/tigervnc/rfb/CMsgWriterV3.java68
-rw-r--r--java/com/tigervnc/rfb/CSecurity.java46
-rw-r--r--java/com/tigervnc/rfb/CSecurityIdent.java58
-rw-r--r--java/com/tigervnc/rfb/CSecurityManaged.java76
-rw-r--r--java/com/tigervnc/rfb/CSecurityNone.java27
-rw-r--r--java/com/tigervnc/rfb/CSecurityPlain.java57
-rw-r--r--java/com/tigervnc/rfb/CSecurityStack.java69
-rw-r--r--java/com/tigervnc/rfb/CSecurityTLS.java251
-rw-r--r--java/com/tigervnc/rfb/CSecurityVeNCrypt.java199
-rw-r--r--java/com/tigervnc/rfb/CSecurityVncAuth.java66
-rw-r--r--java/com/tigervnc/rfb/Configuration.java91
-rw-r--r--java/com/tigervnc/rfb/ConnFailedException.java23
-rw-r--r--java/com/tigervnc/rfb/ConnParams.java171
-rw-r--r--java/com/tigervnc/rfb/Cursor.java34
-rw-r--r--java/com/tigervnc/rfb/Decoder.java51
-rw-r--r--java/com/tigervnc/rfb/DesCipher.java496
-rw-r--r--java/com/tigervnc/rfb/Encoder.java25
-rw-r--r--java/com/tigervnc/rfb/Encodings.java70
-rw-r--r--java/com/tigervnc/rfb/Exception.java23
-rw-r--r--java/com/tigervnc/rfb/Hextile.java27
-rw-r--r--java/com/tigervnc/rfb/HextileDecoder.java101
-rw-r--r--java/com/tigervnc/rfb/Hostname.java41
-rw-r--r--java/com/tigervnc/rfb/IntParameter.java44
-rw-r--r--java/com/tigervnc/rfb/Keysyms.java88
-rw-r--r--java/com/tigervnc/rfb/LogWriter.java99
-rw-r--r--java/com/tigervnc/rfb/ManagedPixelBuffer.java38
-rw-r--r--java/com/tigervnc/rfb/MsgTypes.java40
-rw-r--r--java/com/tigervnc/rfb/PixelBuffer.java116
-rw-r--r--java/com/tigervnc/rfb/PixelFormat.java163
-rw-r--r--java/com/tigervnc/rfb/Point.java40
-rw-r--r--java/com/tigervnc/rfb/RREDecoder.java46
-rw-r--r--java/com/tigervnc/rfb/RawDecoder.java45
-rw-r--r--java/com/tigervnc/rfb/Rect.java89
-rw-r--r--java/com/tigervnc/rfb/Screen.java48
-rw-r--r--java/com/tigervnc/rfb/ScreenSet.java89
-rw-r--r--java/com/tigervnc/rfb/Security.java195
-rw-r--r--java/com/tigervnc/rfb/SecurityClient.java85
-rw-r--r--java/com/tigervnc/rfb/StringParameter.java46
-rw-r--r--java/com/tigervnc/rfb/TightDecoder.java426
-rw-r--r--java/com/tigervnc/rfb/UnicodeToKeysym.java795
-rw-r--r--java/com/tigervnc/rfb/UserMsgBox.java27
-rw-r--r--java/com/tigervnc/rfb/UserPasswdGetter.java27
-rw-r--r--java/com/tigervnc/rfb/VncAuth.java67
-rw-r--r--java/com/tigervnc/rfb/VoidParameter.java41
-rw-r--r--java/com/tigervnc/rfb/ZRLEDecoder.java166
-rw-r--r--java/com/tigervnc/rfb/screenTypes.java36
54 files changed, 5984 insertions, 0 deletions
diff --git a/java/com/tigervnc/rfb/AliasParameter.java b/java/com/tigervnc/rfb/AliasParameter.java
new file mode 100644
index 00000000..2570b877
--- /dev/null
+++ b/java/com/tigervnc/rfb/AliasParameter.java
@@ -0,0 +1,35 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 AliasParameter extends VoidParameter {
+ public AliasParameter(String name_, String desc_, VoidParameter v) {
+ super(name_, desc_);
+ param = v;
+ }
+
+ public boolean setParam(String v) { return param.setParam(v); }
+ public boolean setParam() { return param.setParam(); }
+
+ public String getDefaultStr() { return param.getDefaultStr(); }
+ public String getValueStr() { return param.getValueStr(); }
+ public boolean isBool() { return param.isBool(); }
+
+ protected VoidParameter param;
+}
diff --git a/java/com/tigervnc/rfb/AuthFailureException.java b/java/com/tigervnc/rfb/AuthFailureException.java
new file mode 100644
index 00000000..35fabef0
--- /dev/null
+++ b/java/com/tigervnc/rfb/AuthFailureException.java
@@ -0,0 +1,23 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 AuthFailureException extends Exception {
+ public AuthFailureException(String s) { super(s); }
+}
diff --git a/java/com/tigervnc/rfb/BoolParameter.java b/java/com/tigervnc/rfb/BoolParameter.java
new file mode 100644
index 00000000..06c6ed79
--- /dev/null
+++ b/java/com/tigervnc/rfb/BoolParameter.java
@@ -0,0 +1,51 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 BoolParameter extends VoidParameter {
+ public BoolParameter(String name_, String desc_, boolean v) {
+ super(name_, desc_);
+ value = v;
+ defValue = v;
+ }
+
+ public boolean setParam(String v) {
+ if (v.equals("1") || v.equalsIgnoreCase("on") ||
+ v.equalsIgnoreCase("true") || v.equalsIgnoreCase("yes"))
+ value = true;
+ else if (v.equals("0") || v.equalsIgnoreCase("off") ||
+ v.equalsIgnoreCase("false") || v.equalsIgnoreCase("no"))
+ value = false;
+ else
+ return false;
+ return true;
+ }
+
+ public boolean setParam() { setParam(true); return true; }
+ public void setParam(boolean b) { value = b; }
+
+ public String getDefaultStr() { return defValue ? "1" : "0"; }
+ public String getValueStr() { return value ? "1" : "0"; }
+ public boolean isBool() { return true; }
+
+ final public boolean getValue() { return value; }
+
+ protected boolean value;
+ protected boolean defValue;
+}
diff --git a/java/com/tigervnc/rfb/CConnection.java b/java/com/tigervnc/rfb/CConnection.java
new file mode 100644
index 00000000..15e19896
--- /dev/null
+++ b/java/com/tigervnc/rfb/CConnection.java
@@ -0,0 +1,356 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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;
+
+import java.util.*;
+
+import com.tigervnc.rdr.*;
+
+abstract public class CConnection extends CMsgHandler {
+
+ public CConnection() {
+ security = new SecurityClient();
+ }
+
+ // setStreams() sets the streams to be used for the connection. These must
+ // be set before initialiseProtocol() and processMsg() are called. The
+ // CSecurity object may call setStreams() again to provide alternative
+ // streams over which the RFB protocol is sent (i.e. encrypting/decrypting
+ // streams). Ownership of the streams remains with the caller
+ // (i.e. SConnection will not delete them).
+ public void setStreams(InStream is_, OutStream os_) {
+ is = is_;
+ os = os_;
+ }
+
+ // initialiseProtocol() should be called once the streams and security
+ // types are set. Subsequently, processMsg() should be called whenever
+ // there is data to read on the InStream.
+ public void initialiseProtocol() {
+ state_ = RFBSTATE_PROTOCOL_VERSION;
+ }
+
+ // processMsg() should be called whenever there is data to read on the
+ // InStream. You must have called initialiseProtocol() first.
+ public void processMsg() {
+ switch (state_) {
+
+ case RFBSTATE_PROTOCOL_VERSION: processVersionMsg(); break;
+ case RFBSTATE_SECURITY_TYPES: processSecurityTypesMsg(); break;
+ case RFBSTATE_SECURITY: processSecurityMsg(); break;
+ case RFBSTATE_SECURITY_RESULT: processSecurityResultMsg(); break;
+ case RFBSTATE_INITIALISATION: processInitMsg(); break;
+ case RFBSTATE_NORMAL: reader_.readMsg(); break;
+ case RFBSTATE_UNINITIALISED:
+ throw new Exception("CConnection.processMsg: not initialised yet?");
+ default:
+ throw new Exception("CConnection.processMsg: invalid state");
+ }
+ }
+
+ private void processVersionMsg() {
+ vlog.debug("reading protocol version");
+ Boolean done = new Boolean(true);
+ if (!cp.readVersion(is, done)) {
+ state_ = RFBSTATE_INVALID;
+ throw new Exception("reading version failed: not an RFB server?");
+ }
+ if (!done.booleanValue()) return;
+
+ vlog.info("Server supports RFB protocol version "+cp.majorVersion+"."+
+ cp.minorVersion);
+
+ // The only official RFB protocol versions are currently 3.3, 3.7 and 3.8
+ if (cp.beforeVersion(3,3)) {
+ String msg = ("Server gave unsupported RFB protocol version "+
+ cp.majorVersion+"."+cp.minorVersion);
+ vlog.error(msg);
+ state_ = RFBSTATE_INVALID;
+ throw new Exception(msg);
+ } else if (useProtocol3_3 || cp.beforeVersion(3,7)) {
+ cp.setVersion(3,3);
+ } else if (cp.afterVersion(3,8)) {
+ cp.setVersion(3,8);
+ }
+
+ cp.writeVersion(os);
+ state_ = RFBSTATE_SECURITY_TYPES;
+
+ vlog.info("Using RFB protocol version "+
+ cp.majorVersion+"."+cp.minorVersion);
+ }
+
+ private void processSecurityTypesMsg() {
+ vlog.info("processing security types message");
+
+ int secType = Security.secTypeInvalid;
+
+ List<Integer> secTypes = new ArrayList<Integer>();
+ secTypes = security.GetEnabledSecTypes();
+ //for (Iterator i = secTypes.iterator(); i.hasNext(); )
+ // vlog.info(((Integer)i.next()).toString());
+
+ if (cp.isVersion(3,3)) {
+
+ // legacy 3.3 server may only offer "vnc authentication" or "none"
+
+ secType = is.readU32();
+ if (secType == Security.secTypeInvalid) {
+ throwConnFailedException();
+
+ } else if (secType == Security.secTypeNone || secType == Security.secTypeVncAuth) {
+ Iterator i;
+ for (i = secTypes.iterator(); i.hasNext(); ) {
+ int refType = (Integer)i.next();
+ if (refType == secType) {
+ secType = refType;
+ break;
+ }
+ if (!i.hasNext())
+ secType = Security.secTypeInvalid;
+ }
+
+ } else {
+ vlog.error("Unknown 3.3 security type "+secType);
+ throw new Exception("Unknown 3.3 security type");
+ }
+
+ } else {
+
+ // 3.7 server will offer us a list
+
+ int nServerSecTypes = is.readU8();
+ if (nServerSecTypes == 0)
+ throwConnFailedException();
+
+ for (int i = 0; i < nServerSecTypes; i++) {
+ int serverSecType = is.readU8();
+ vlog.info("Server offers security type "+
+ Security.secTypeName(serverSecType)+"("+serverSecType+")");
+
+ /*
+ * Use the first type sent by server which matches client's type.
+ * It means server's order specifies priority.
+ */
+ if (secType == Security.secTypeInvalid) {
+ for (Iterator j = secTypes.iterator(); j.hasNext(); ) {
+ int refType = (Integer)j.next();
+ if (refType == serverSecType) {
+ secType = refType;
+ break;
+ }
+ }
+ }
+ }
+
+ // Inform the server of our decision
+ if (secType != Security.secTypeInvalid) {
+ os.writeU8(secType);
+ os.flush();
+ vlog.info("Choosing security type "+Security.secTypeName(secType)+
+ "("+secType+")");
+ }
+ }
+
+ if (secType == Security.secTypeInvalid) {
+ state_ = RFBSTATE_INVALID;
+ vlog.error("No matching security types");
+ throw new Exception("No matching security types");
+ }
+
+ state_ = RFBSTATE_SECURITY;
+ csecurity = security.GetCSecurity(secType);
+ processSecurityMsg();
+ }
+
+ private void processSecurityMsg() {
+ vlog.debug("processing security message");
+ if (csecurity.processMsg(this)) {
+ state_ = RFBSTATE_SECURITY_RESULT;
+ processSecurityResultMsg();
+ }
+ }
+
+ private void processSecurityResultMsg() {
+ vlog.debug("processing security result message");
+ int result;
+ if (cp.beforeVersion(3,8) && csecurity.getType() == Security.secTypeNone) {
+ result = Security.secResultOK;
+ } else {
+ if (!is.checkNoWait(1)) return;
+ result = is.readU32();
+ }
+ switch (result) {
+ case Security.secResultOK:
+ securityCompleted();
+ return;
+ case Security.secResultFailed:
+ vlog.debug("auth failed");
+ break;
+ case Security.secResultTooMany:
+ vlog.debug("auth failed - too many tries");
+ break;
+ default:
+ throw new Exception("Unknown security result from server");
+ }
+ String reason;
+ if (cp.beforeVersion(3,8))
+ reason = "Authentication failure";
+ else
+ reason = is.readString();
+ state_ = RFBSTATE_INVALID;
+ throw new AuthFailureException(reason);
+ }
+
+ private void processInitMsg() {
+ vlog.debug("reading server initialisation");
+ reader_.readServerInit();
+ }
+
+ private void throwConnFailedException() {
+ state_ = RFBSTATE_INVALID;
+ String reason;
+ reason = is.readString();
+ throw new ConnFailedException(reason);
+ }
+
+ private void securityCompleted() {
+ state_ = RFBSTATE_INITIALISATION;
+ reader_ = new CMsgReaderV3(this, is);
+ writer_ = new CMsgWriterV3(cp, os);
+ vlog.debug("Authentication success!");
+ authSuccess();
+ writer_.writeClientInit(shared);
+ }
+
+ // Methods to initialise the connection
+
+ // setServerName() is used to provide a unique(ish) name for the server to
+ // which we are connected. This might be the result of getPeerEndpoint on
+ // a TcpSocket, for example, or a host specified by DNS name & port.
+ // The serverName is used when verifying the Identity of a host (see RA2).
+ public void setServerName(String name) {
+ serverName = name;
+ }
+
+ public void setServerPort(int port) {
+ serverPort = port;
+ }
+
+ public void initSecTypes() {
+ nSecTypes = 0;
+ }
+
+ // setShared sets the value of the shared flag which will be sent to the
+ // server upon initialisation.
+ public void setShared(boolean s) { shared = s; }
+
+ // setProtocol3_3 configures whether or not the CConnection should
+ // only ever support protocol version 3.3
+ public void setProtocol3_3(boolean s) { useProtocol3_3 = s; }
+
+ // Methods to be overridden in a derived class
+
+ // getCSecurity() gets the CSecurity object for the given type. The type
+ // is guaranteed to be one of the secTypes passed in to addSecType(). The
+ // CSecurity object's destroy() method will be called by the CConnection
+ // from its destructor.
+ //abstract public CSecurity getCSecurity(int secType);
+
+ // getCurrentCSecurity() gets the CSecurity instance used for this
+ // connection.
+ //public CSecurity getCurrentCSecurity() { return security; }
+
+ // setClientSecTypeOrder() determines whether the client should obey the
+ // server's security type preference, by picking the first server security
+ // type that the client supports, or whether it should pick the first type
+ // that the server supports, from the client-supported list of types.
+ public void setClientSecTypeOrder( boolean csto ) {
+ clientSecTypeOrder = csto;
+ }
+
+ // authSuccess() is called when authentication has succeeded.
+ public void authSuccess() {}
+
+ // serverInit() is called when the ServerInit message is received. The
+ // derived class must call on to CConnection::serverInit().
+ public void serverInit() {
+ state_ = RFBSTATE_NORMAL;
+ vlog.debug("initialisation done");
+ }
+
+ // Other methods
+
+ public CMsgReaderV3 reader() { return reader_; }
+ public CMsgWriterV3 writer() { return writer_; }
+
+ public InStream getInStream() { return is; }
+ public OutStream getOutStream() { return os; }
+
+ public String getServerName() { return serverName; }
+ public int getServerPort() { return serverPort; }
+
+ public static final int RFBSTATE_UNINITIALISED = 0;
+ public static final int RFBSTATE_PROTOCOL_VERSION = 1;
+ public static final int RFBSTATE_SECURITY_TYPES = 2;
+ public static final int RFBSTATE_SECURITY = 3;
+ public static final int RFBSTATE_SECURITY_RESULT = 4;
+ public static final int RFBSTATE_INITIALISATION = 5;
+ public static final int RFBSTATE_NORMAL = 6;
+ public static final int RFBSTATE_INVALID = 7;
+
+ public int state() { return state_; }
+
+ protected void setState(int s) { state_ = s; }
+
+ private void throwAuthFailureException() {
+ String reason;
+ vlog.debug("state="+state()+", ver="+cp.majorVersion+"."+cp.minorVersion);
+ if (state() == RFBSTATE_SECURITY_RESULT && !cp.beforeVersion(3,8)) {
+ reason = is.readString();
+ } else {
+ reason = "Authentication failure";
+ }
+ state_ = RFBSTATE_INVALID;
+ vlog.error(reason);
+ throw new AuthFailureException(reason);
+ }
+
+ InStream is = null;
+ OutStream os = null;
+ CMsgReaderV3 reader_ = null;
+ CMsgWriterV3 writer_ = null;
+ boolean shared = false;
+ public CSecurity csecurity;
+ public SecurityClient security;
+ public static final int maxSecTypes = 8;
+ int nSecTypes;
+ int[] secTypes;
+ int state_ = RFBSTATE_UNINITIALISED;
+ String serverName;
+ int serverPort;
+ boolean useProtocol3_3 = false;
+ boolean clientSecTypeOrder;
+ public static java.net.Socket sock;
+
+ public static java.net.Socket getSocket() { return sock; }
+ public static void setSocket(java.net.Socket sock_) { sock = sock_; }
+
+ static LogWriter vlog = new LogWriter("CConnection");
+}
diff --git a/java/com/tigervnc/rfb/CMsgHandler.java b/java/com/tigervnc/rfb/CMsgHandler.java
new file mode 100644
index 00000000..81fd2a1b
--- /dev/null
+++ b/java/com/tigervnc/rfb/CMsgHandler.java
@@ -0,0 +1,88 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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.
+ */
+
+//
+// CMsgHandler
+//
+
+package com.tigervnc.rfb;
+
+public class CMsgHandler {
+
+ public CMsgHandler() {
+ cp = new ConnParams();
+ }
+
+ public void setDesktopSize(int width, int height)
+ {
+ cp.width = width;
+ cp.height = height;
+ }
+
+ public void setExtendedDesktopSize(int reason, int result,
+ int width, int height,
+ ScreenSet layout)
+ {
+ cp.supportsSetDesktopSize = true;
+
+ if ((reason == screenTypes.reasonClient) && (result != screenTypes.resultSuccess))
+ return;
+
+ if (!layout.validate(width, height))
+ vlog.error("Server sent us an invalid screen layout");
+
+ cp.width = width;
+ cp.height = height;
+ cp.screenLayout = layout;
+ }
+
+ public void setPixelFormat(PixelFormat pf)
+ {
+ cp.setPF(pf);
+ }
+
+ public void setName(String name)
+ {
+ cp.setName(name);
+ }
+
+ public void clientRedirect(int port, String host,
+ String x509subject) {}
+
+ public void setCursor(int width, int height, Point hotspot,
+ int[] data, byte[] mask) {}
+ public void serverInit() {}
+
+ public void framebufferUpdateStart() {}
+ public void framebufferUpdateEnd() {}
+ public void beginRect(Rect r, int encoding) {}
+ public void endRect(Rect r, int encoding) {}
+
+ public void setColourMapEntries(int firstColour, int nColours,
+ int[] rgbs) { }
+ public void bell() {}
+ public void serverCutText(String str, int len) {}
+
+ public void fillRect(Rect r, int pix) {}
+ public void imageRect(Rect r, int[] pixels) {}
+ public void copyRect(Rect r, int srcX, int srcY) {}
+
+ public ConnParams cp;
+
+ static LogWriter vlog = new LogWriter("CMsgHandler");
+}
diff --git a/java/com/tigervnc/rfb/CMsgReader.java b/java/com/tigervnc/rfb/CMsgReader.java
new file mode 100644
index 00000000..41230560
--- /dev/null
+++ b/java/com/tigervnc/rfb/CMsgReader.java
@@ -0,0 +1,179 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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.
+ */
+
+//
+// CMsgReader - class for reading RFB messages on the client side
+// (i.e. messages from server to client).
+//
+
+package com.tigervnc.rfb;
+
+import com.tigervnc.rdr.*;
+
+abstract public class CMsgReader {
+
+ protected CMsgReader(CMsgHandler handler_, InStream is_)
+ {
+ imageBufIdealSize = 0;
+ handler = handler_;
+ is = is_;
+ imageBuf = null;
+ imageBufSize = 0;
+ decoders = new Decoder[Encodings.encodingMax+1];
+ }
+
+ protected void readSetColourMapEntries()
+ {
+ is.skip(1);
+ int firstColour = is.readU16();
+ int nColours = is.readU16();
+ int[] rgbs = new int[nColours * 3];
+ for (int i = 0; i < nColours * 3; i++)
+ rgbs[i] = is.readU16();
+ handler.setColourMapEntries(firstColour, nColours, rgbs);
+ }
+
+ protected void readBell()
+ {
+ handler.bell();
+ }
+
+ protected void readServerCutText()
+ {
+ is.skip(3);
+ int len = is.readU32();
+ if (len > 256*1024) {
+ is.skip(len);
+ vlog.error("cut text too long ("+len+" bytes) - ignoring");
+ return;
+ }
+ byte[] buf = new byte[len];
+ is.readBytes(buf, 0, len);
+ String str = new String();
+ try {
+ str = new String(buf,"UTF8");
+ } catch(java.io.UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ handler.serverCutText(str, len);
+ }
+
+ protected void readFramebufferUpdateStart()
+ {
+ handler.framebufferUpdateStart();
+ }
+
+ protected void readFramebufferUpdateEnd()
+ {
+ handler.framebufferUpdateEnd();
+ }
+
+ protected void readRect(Rect r, int encoding)
+ {
+ if ((r.br.x > handler.cp.width) || (r.br.y > handler.cp.height)) {
+ vlog.error("Rect too big: "+r.width()+"x"+r.height()+" at "+
+ r.tl.x+","+r.tl.y+" exceeds "+handler.cp.width+"x"+
+ handler.cp.height);
+ throw new Exception("Rect too big");
+ }
+
+ if (r.is_empty())
+ vlog.error("Ignoring zero size rect");
+
+ handler.beginRect(r, encoding);
+
+ if (encoding == Encodings.encodingCopyRect) {
+ readCopyRect(r);
+ } else {
+
+ if (decoders[encoding] == null) {
+ decoders[encoding] = Decoder.createDecoder(encoding, this);
+ if (decoders[encoding] == null) {
+ vlog.error("Unknown rect encoding "+encoding);
+ throw new Exception("Unknown rect encoding");
+ }
+ }
+ decoders[encoding].readRect(r, handler);
+ }
+
+ handler.endRect(r, encoding);
+ }
+
+ protected void readCopyRect(Rect r)
+ {
+ int srcX = is.readU16();
+ int srcY = is.readU16();
+ handler.copyRect(r, srcX, srcY);
+ }
+
+ protected void readSetCursor(int width, int height, Point hotspot)
+ {
+ int data_len = width * height;
+ int mask_len = ((width+7)/8) * height;
+ int[] data = new int[data_len];
+ byte[] mask = new byte[mask_len];
+
+ is.readPixels(data, data_len, (handler.cp.pf().bpp/8), handler.cp.pf().bigEndian);
+ is.readBytes(mask, 0, mask_len);
+
+ handler.setCursor(width, height, hotspot, data, mask);
+ }
+
+ public int[] getImageBuf(int required) { return getImageBuf(required, 0, 0); }
+
+ public int[] getImageBuf(int required, int requested, int nPixels)
+ {
+ int requiredBytes = required * (handler.cp.pf().bpp / 8);
+ int requestedBytes = requested * (handler.cp.pf().bpp / 8);
+ int size = requestedBytes;
+ if (size > imageBufIdealSize) size = imageBufIdealSize;
+
+ if (size < requiredBytes)
+ size = requiredBytes;
+
+ if (imageBufSize < size) {
+ imageBufSize = size;
+ imageBuf = new int[imageBufSize];
+ }
+ if (nPixels != 0)
+ nPixels = imageBufSize / (handler.cp.pf().bpp / 8);
+ return imageBuf;
+ }
+
+ public final int bpp()
+ {
+ return handler.cp.pf().bpp;
+ }
+
+ abstract public void readServerInit();
+
+ // readMsg() reads a message, calling the handler as appropriate.
+ abstract public void readMsg();
+
+ public InStream getInStream() { return is; }
+
+ public int imageBufIdealSize;
+
+ protected CMsgHandler handler;
+ protected InStream is;
+ protected Decoder[] decoders;
+ protected int[] imageBuf;
+ protected int imageBufSize;
+
+ static LogWriter vlog = new LogWriter("CMsgReader");
+}
diff --git a/java/com/tigervnc/rfb/CMsgReaderV3.java b/java/com/tigervnc/rfb/CMsgReaderV3.java
new file mode 100644
index 00000000..6d9e254b
--- /dev/null
+++ b/java/com/tigervnc/rfb/CMsgReaderV3.java
@@ -0,0 +1,155 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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;
+
+import com.tigervnc.rdr.*;
+
+public class CMsgReaderV3 extends CMsgReader {
+
+ public CMsgReaderV3(CMsgHandler handler_, InStream is_)
+ {
+ super(handler_, is_);
+ nUpdateRectsLeft = 0;
+ }
+
+ public void readServerInit()
+ {
+ int width = is.readU16();
+ int height = is.readU16();
+ handler.setDesktopSize(width, height);
+ PixelFormat pf = new PixelFormat();
+ pf.read(is);
+ handler.setPixelFormat(pf);
+ String name = is.readString();
+ handler.setName(name);
+ handler.serverInit();
+ }
+
+ public void readMsg()
+ {
+ if (nUpdateRectsLeft == 0) {
+
+ int type = is.readU8();
+ switch (type) {
+ case MsgTypes.msgTypeFramebufferUpdate: readFramebufferUpdate(); break;
+ case MsgTypes.msgTypeSetColourMapEntries: readSetColourMapEntries(); break;
+ case MsgTypes.msgTypeBell: readBell(); break;
+ case MsgTypes.msgTypeServerCutText: readServerCutText(); break;
+ default:
+ vlog.error("unknown message type "+type);
+ throw new Exception("unknown message type");
+ }
+
+ } else {
+
+ int x = is.readU16();
+ int y = is.readU16();
+ int w = is.readU16();
+ int h = is.readU16();
+ int encoding = is.readS32();
+
+ switch (encoding) {
+ case Encodings.pseudoEncodingDesktopSize:
+ handler.setDesktopSize(w, h);
+ break;
+ case Encodings.pseudoEncodingExtendedDesktopSize:
+ readExtendedDesktopSize(x, y, w, h);
+ break;
+ case Encodings.pseudoEncodingDesktopName:
+ readSetDesktopName(x, y, w, h);
+ break;
+ case Encodings.pseudoEncodingCursor:
+ readSetCursor(w, h, new Point(x,y));
+ break;
+ case Encodings.pseudoEncodingLastRect:
+ nUpdateRectsLeft = 1; // this rectangle is the last one
+ break;
+ case Encodings.pseudoEncodingClientRedirect:
+ readClientRedirect(x, y, w, h);
+ break;
+ default:
+ readRect(new Rect(x, y, x+w, y+h), encoding);
+ break;
+ }
+
+ nUpdateRectsLeft--;
+ if (nUpdateRectsLeft == 0) handler.framebufferUpdateEnd();
+ }
+ }
+
+ void readFramebufferUpdate()
+ {
+ is.skip(1);
+ nUpdateRectsLeft = is.readU16();
+ handler.framebufferUpdateStart();
+ }
+
+ void readSetDesktopName(int x, int y, int w, int h)
+ {
+ String name = is.readString();
+
+ if (x != 0 || y != 0 || w != 0 || h != 0) {
+ vlog.error("Ignoring DesktopName rect with non-zero position/size");
+ } else {
+ handler.setName(name);
+ }
+
+ }
+
+ void readExtendedDesktopSize(int x, int y, int w, int h)
+ {
+ int screens, i;
+ int id, flags;
+ int sx, sy, sw, sh;
+ ScreenSet layout = new ScreenSet();
+
+ screens = is.readU8();
+ is.skip(3);
+
+ for (i = 0;i < screens;i++) {
+ id = is.readU32();
+ sx = is.readU16();
+ sy = is.readU16();
+ sw = is.readU16();
+ sh = is.readU16();
+ flags = is.readU32();
+
+ layout.add_screen(new Screen(id, sx, sy, sw, sh, flags));
+ }
+
+ handler.setExtendedDesktopSize(x, y, w, h, layout);
+ }
+
+ void readClientRedirect(int x, int y, int w, int h)
+ {
+ int port = is.readU16();
+ String host = is.readString();
+ String x509subject = is.readString();
+
+ if (x != 0 || y != 0 || w != 0 || h != 0) {
+ vlog.error("Ignoring ClientRedirect rect with non-zero position/size");
+ } else {
+ handler.clientRedirect(port, host, x509subject);
+ }
+ }
+
+ int nUpdateRectsLeft;
+
+ static LogWriter vlog = new LogWriter("CMsgReaderV3");
+}
diff --git a/java/com/tigervnc/rfb/CMsgWriter.java b/java/com/tigervnc/rfb/CMsgWriter.java
new file mode 100644
index 00000000..7cafddde
--- /dev/null
+++ b/java/com/tigervnc/rfb/CMsgWriter.java
@@ -0,0 +1,171 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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;
+
+import com.tigervnc.rdr.*;
+
+abstract public class CMsgWriter {
+
+ abstract public void writeClientInit(boolean shared);
+
+ public void writeSetPixelFormat(PixelFormat pf)
+ {
+ startMsg(MsgTypes.msgTypeSetPixelFormat);
+ os.pad(3);
+ pf.write(os);
+ endMsg();
+ }
+
+ public void writeSetEncodings(int nEncodings, int[] encodings)
+ {
+ startMsg(MsgTypes.msgTypeSetEncodings);
+ os.skip(1);
+ os.writeU16(nEncodings);
+ for (int i = 0; i < nEncodings; i++)
+ os.writeU32(encodings[i]);
+ endMsg();
+ }
+
+ // Ask for encodings based on which decoders are supported. Assumes higher
+ // encoding numbers are more desirable.
+
+ public void writeSetEncodings(int preferredEncoding, boolean useCopyRect)
+ {
+ int nEncodings = 0;
+ int[] encodings = new int[Encodings.encodingMax+3];
+ if (cp.supportsLocalCursor)
+ encodings[nEncodings++] = Encodings.pseudoEncodingCursor;
+ if (cp.supportsDesktopResize)
+ encodings[nEncodings++] = Encodings.pseudoEncodingDesktopSize;
+ if (cp.supportsExtendedDesktopSize)
+ encodings[nEncodings++] = Encodings.pseudoEncodingExtendedDesktopSize;
+ if (cp.supportsDesktopRename)
+ encodings[nEncodings++] = Encodings.pseudoEncodingDesktopName;
+ if (cp.supportsClientRedirect)
+ encodings[nEncodings++] = Encodings.pseudoEncodingClientRedirect;
+ if (Decoder.supported(preferredEncoding)) {
+ encodings[nEncodings++] = preferredEncoding;
+ }
+ if (useCopyRect) {
+ encodings[nEncodings++] = Encodings.encodingCopyRect;
+ }
+
+ /*
+ * Prefer encodings in this order:
+ *
+ * Tight, ZRLE, Hextile, *
+ */
+
+ if ((preferredEncoding != Encodings.encodingTight) &&
+ Decoder.supported(Encodings.encodingTight))
+ encodings[nEncodings++] = Encodings.encodingTight;
+
+ if ((preferredEncoding != Encodings.encodingZRLE) &&
+ Decoder.supported(Encodings.encodingZRLE))
+ encodings[nEncodings++] = Encodings.encodingZRLE;
+
+ if ((preferredEncoding != Encodings.encodingHextile) &&
+ Decoder.supported(Encodings.encodingHextile))
+ encodings[nEncodings++] = Encodings.encodingHextile;
+
+ // Remaining encodings
+ for (int i = Encodings.encodingMax; i >= 0; i--) {
+ switch (i) {
+ case Encodings.encodingTight:
+ case Encodings.encodingZRLE:
+ case Encodings.encodingHextile:
+ break;
+ default:
+ if ((i != preferredEncoding) && Decoder.supported(i))
+ encodings[nEncodings++] = i;
+ }
+ }
+
+ encodings[nEncodings++] = Encodings.pseudoEncodingLastRect;
+ if (cp.customCompressLevel && cp.compressLevel >= 0 && cp.compressLevel <= 9)
+ encodings[nEncodings++] = Encodings.pseudoEncodingCompressLevel0 + cp.compressLevel;
+ if (!cp.noJpeg && cp.qualityLevel >= 0 && cp.qualityLevel <= 9)
+ encodings[nEncodings++] = Encodings.pseudoEncodingQualityLevel0 + cp.qualityLevel;
+
+ writeSetEncodings(nEncodings, encodings);
+ }
+
+ public void writeFramebufferUpdateRequest(Rect r, boolean incremental)
+ {
+ startMsg(MsgTypes.msgTypeFramebufferUpdateRequest);
+ os.writeU8(incremental?1:0);
+ os.writeU16(r.tl.x);
+ os.writeU16(r.tl.y);
+ os.writeU16(r.width());
+ os.writeU16(r.height());
+ endMsg();
+ }
+
+ public void writeKeyEvent(int key, boolean down)
+ {
+ startMsg(MsgTypes.msgTypeKeyEvent);
+ os.writeU8(down?1:0);
+ os.pad(2);
+ os.writeU32(key);
+ endMsg();
+ }
+
+ public void writePointerEvent(Point pos, int buttonMask)
+ {
+ Point p = new Point(pos.x,pos.y);
+ if (p.x < 0) p.x = 0;
+ if (p.y < 0) p.y = 0;
+ if (p.x >= cp.width) p.x = cp.width - 1;
+ if (p.y >= cp.height) p.y = cp.height - 1;
+
+ startMsg(MsgTypes.msgTypePointerEvent);
+ os.writeU8(buttonMask);
+ os.writeU16(p.x);
+ os.writeU16(p.y);
+ endMsg();
+ }
+
+ public void writeClientCutText(String str, int len)
+ {
+ startMsg(MsgTypes.msgTypeClientCutText);
+ os.pad(3);
+ os.writeU32(len);
+ try {
+ byte[] utf8str = str.getBytes("UTF8");
+ os.writeBytes(utf8str, 0, len);
+ } catch(java.io.UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ endMsg();
+ }
+
+ abstract public void startMsg(int type);
+ abstract public void endMsg();
+
+ public void setOutStream(OutStream os_) { os = os_; }
+
+ ConnParams getConnParams() { return cp; }
+ OutStream getOutStream() { return os; }
+
+ protected CMsgWriter(ConnParams cp_, OutStream os_) {cp = cp_; os = os_;}
+
+ ConnParams cp;
+ OutStream os;
+ static LogWriter vlog = new LogWriter("CMsgWriter");
+}
diff --git a/java/com/tigervnc/rfb/CMsgWriterV3.java b/java/com/tigervnc/rfb/CMsgWriterV3.java
new file mode 100644
index 00000000..ec30a826
--- /dev/null
+++ b/java/com/tigervnc/rfb/CMsgWriterV3.java
@@ -0,0 +1,68 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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;
+
+import com.tigervnc.rdr.*;
+import java.util.*;
+
+public class CMsgWriterV3 extends CMsgWriter {
+
+ public CMsgWriterV3(ConnParams cp_, OutStream os_) { super(cp_, os_); }
+
+ public void writeClientInit(boolean shared) {
+ os.writeU8(shared?1:0);
+ endMsg();
+ }
+
+ public void startMsg(int type) {
+ os.writeU8(type);
+ }
+
+ public void endMsg() {
+ os.flush();
+ }
+
+ public void writeSetDesktopSize(int width, int height,
+ ScreenSet layout)
+ {
+ if (!cp.supportsSetDesktopSize)
+ throw new Exception("Server does not support SetDesktopSize");
+
+ startMsg(MsgTypes.msgTypeSetDesktopSize);
+ os.pad(1);
+
+ os.writeU16(width);
+ os.writeU16(height);
+
+ os.writeU8(layout.num_screens());
+ os.pad(1);
+
+ for (Iterator iter = layout.screens.iterator(); iter.hasNext(); ) {
+ Screen refScreen = (Screen)iter.next();
+ os.writeU32(refScreen.id);
+ os.writeU16(refScreen.dimensions.tl.x);
+ os.writeU16(refScreen.dimensions.tl.y);
+ os.writeU16(refScreen.dimensions.width());
+ os.writeU16(refScreen.dimensions.height());
+ os.writeU32(refScreen.flags);
+ }
+
+ endMsg();
+ }
+}
diff --git a/java/com/tigervnc/rfb/CSecurity.java b/java/com/tigervnc/rfb/CSecurity.java
new file mode 100644
index 00000000..e5b300f6
--- /dev/null
+++ b/java/com/tigervnc/rfb/CSecurity.java
@@ -0,0 +1,46 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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.
+ */
+
+//
+// CSecurity - class on the client side for handling security handshaking. A
+// derived class for a particular security type overrides the processMsg()
+// method. processMsg() is called first when the security type has been
+// decided on, and will keep being called whenever there is data to read from
+// the server until either it returns 0, indicating authentication/security
+// failure, or it returns 1, to indicate success. A return value of 2
+// (actually anything other than 0 or 1) indicates that it should be called
+// back when there is more data to read.
+//
+// Note that the first time processMsg() is called, there is no guarantee that
+// there is any data to read from the CConnection's InStream, but subsequent
+// calls guarantee there is at least one byte which can be read without
+// blocking.
+
+package com.tigervnc.rfb;
+
+abstract public class CSecurity {
+ abstract public boolean processMsg(CConnection cc);
+ abstract public int getType();
+ abstract public String description();
+
+ /*
+ * Use variable directly instead of dumb get/set methods.
+ * It MUST be set by viewer.
+ */
+ static UserPasswdGetter upg;
+}
diff --git a/java/com/tigervnc/rfb/CSecurityIdent.java b/java/com/tigervnc/rfb/CSecurityIdent.java
new file mode 100644
index 00000000..6523e411
--- /dev/null
+++ b/java/com/tigervnc/rfb/CSecurityIdent.java
@@ -0,0 +1,58 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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;
+
+import java.io.IOException;
+
+import com.tigervnc.rdr.*;
+import com.tigervnc.vncviewer.*;
+
+public class CSecurityIdent extends CSecurity {
+
+ public CSecurityIdent() { }
+
+ public boolean processMsg(CConnection cc) {
+ InStream is = cc.getInStream();
+ OutStream os = cc.getOutStream();
+
+ StringBuffer username = new StringBuffer();
+
+ CConn.upg.getUserPasswd(username, null);
+
+ // Return the response to the server
+ os.writeU32(username.length());
+ try {
+ byte[] utf8str = username.toString().getBytes("UTF8");
+ os.writeBytes(utf8str, 0, username.length());
+ } catch(java.io.UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ os.flush();
+ return true;
+ }
+
+ public int getType() { return Security.secTypeIdent; }
+
+ java.net.Socket sock;
+ UserPasswdGetter upg;
+
+ static LogWriter vlog = new LogWriter("Ident");
+ public String description() { return "No Encryption"; }
+
+}
diff --git a/java/com/tigervnc/rfb/CSecurityManaged.java b/java/com/tigervnc/rfb/CSecurityManaged.java
new file mode 100644
index 00000000..2461682d
--- /dev/null
+++ b/java/com/tigervnc/rfb/CSecurityManaged.java
@@ -0,0 +1,76 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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;
+
+import java.io.IOException;
+
+import com.tigervnc.rdr.*;
+import com.tigervnc.vncviewer.*;
+
+public class CSecurityManaged extends CSecurity {
+
+ public CSecurityManaged() { }
+
+ public boolean processMsg(CConnection cc) {
+ InStream is = cc.getInStream();
+ OutStream os = cc.getOutStream();
+
+ StringBuffer username = new StringBuffer();
+
+ CConn.upg.getUserPasswd(username, null);
+
+ // Return the response to the server
+ os.writeU8(username.length());
+ try {
+ byte[] utf8str = username.toString().getBytes("UTF8");
+ os.writeBytes(utf8str, 0, username.length());
+ } catch(java.io.UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ os.flush();
+ int serverPort = is.readU16();
+ //if (serverPort==0) { return true; };
+ String serverName = cc.getServerName();
+ vlog.debug("Redirected to "+serverName+" port "+serverPort);
+ try {
+ CConn.getSocket().close();
+ cc.setServerPort(serverPort);
+ sock = new java.net.Socket(serverName, serverPort);
+ sock.setTcpNoDelay(true);
+ sock.setTrafficClass(0x10);
+ CConn.setSocket(sock);
+ vlog.debug("connected to host "+serverName+" port "+serverPort);
+ cc.setStreams(new JavaInStream(sock.getInputStream()),
+ new JavaOutStream(sock.getOutputStream()));
+ cc.initialiseProtocol();
+ } catch (java.io.IOException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ public int getType() { return Security.secTypeManaged; }
+
+ java.net.Socket sock;
+ UserPasswdGetter upg;
+
+ static LogWriter vlog = new LogWriter("Managed");
+ public String description() { return "No Encryption"; }
+
+}
diff --git a/java/com/tigervnc/rfb/CSecurityNone.java b/java/com/tigervnc/rfb/CSecurityNone.java
new file mode 100644
index 00000000..e31056da
--- /dev/null
+++ b/java/com/tigervnc/rfb/CSecurityNone.java
@@ -0,0 +1,27 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 CSecurityNone extends CSecurity {
+
+ public boolean processMsg(CConnection cc) { return true; }
+ public int getType() { return Security.secTypeNone; }
+ public String description() { return "No Encryption"; }
+ static LogWriter vlog = new LogWriter("CSecurityNone");
+}
diff --git a/java/com/tigervnc/rfb/CSecurityPlain.java b/java/com/tigervnc/rfb/CSecurityPlain.java
new file mode 100644
index 00000000..707915cc
--- /dev/null
+++ b/java/com/tigervnc/rfb/CSecurityPlain.java
@@ -0,0 +1,57 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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;
+
+import com.tigervnc.rdr.*;
+import com.tigervnc.vncviewer.*;
+
+public class CSecurityPlain extends CSecurity {
+
+ public CSecurityPlain() { }
+
+ public boolean processMsg(CConnection cc)
+ {
+ OutStream os = cc.getOutStream();
+
+ StringBuffer username = new StringBuffer();
+ StringBuffer password = new StringBuffer();
+
+ CConn.upg.getUserPasswd(username, password);
+
+ // Return the response to the server
+ os.writeU32(username.length());
+ os.writeU32(password.length());
+ byte[] utf8str;
+ try {
+ utf8str = username.toString().getBytes("UTF8");
+ os.writeBytes(utf8str, 0, username.length());
+ utf8str = password.toString().getBytes("UTF8");
+ os.writeBytes(utf8str, 0, password.length());
+ } catch(java.io.UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ os.flush();
+ return true;
+ }
+
+ public int getType() { return Security.secTypePlain; }
+ public String description() { return "ask for username and password"; }
+
+ static LogWriter vlog = new LogWriter("Plain");
+}
diff --git a/java/com/tigervnc/rfb/CSecurityStack.java b/java/com/tigervnc/rfb/CSecurityStack.java
new file mode 100644
index 00000000..5886268e
--- /dev/null
+++ b/java/com/tigervnc/rfb/CSecurityStack.java
@@ -0,0 +1,69 @@
+/* Copyright (C) 2005 Martin Koegler
+ * Copyright (C) 2010 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
+ * 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 CSecurityStack extends CSecurity {
+
+ public CSecurityStack(int Type, String Name, CSecurity s0,
+ CSecurity s1)
+ {
+ name = Name;
+ type = Type;
+ state = 0;
+ state0 = s0;
+ state1 = s1;
+ }
+
+ public boolean processMsg(CConnection cc)
+ {
+ boolean res = true;
+ if (state == 0) {
+ if (state0 != null)
+ res = state0.processMsg(cc);
+
+ if (!res)
+ return res;
+
+ state++;
+ }
+
+ if (state == 1) {
+ if(state1 != null)
+ res = state1.processMsg(cc);
+
+ if(!res)
+ return res;
+
+ state++;
+ }
+
+ return res;
+ }
+
+ public final int getType() { return type; }
+ public final String description() { return name; }
+
+ private int state;
+ private CSecurity state0;
+ private CSecurity state1;
+ private String name;
+ private int type;
+
+}
diff --git a/java/com/tigervnc/rfb/CSecurityTLS.java b/java/com/tigervnc/rfb/CSecurityTLS.java
new file mode 100644
index 00000000..73eb6199
--- /dev/null
+++ b/java/com/tigervnc/rfb/CSecurityTLS.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2003 Sun Microsystems, Inc.
+ *
+ * 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;
+
+import javax.net.ssl.*;
+import java.security.*;
+import java.security.cert.*;
+import java.security.KeyStore;
+import java.io.File;
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import javax.swing.JOptionPane;
+
+import com.tigervnc.vncviewer.UserPrefs;
+import com.tigervnc.rdr.*;
+
+public class CSecurityTLS extends CSecurity {
+
+ public static StringParameter x509ca
+ = new StringParameter("x509ca",
+ "X509 CA certificate", "");
+ public static StringParameter x509crl
+ = new StringParameter("x509crl",
+ "X509 CRL file", "");
+
+ private void initGlobal()
+ {
+ try {
+ SSLSocketFactory sslfactory;
+ SSLContext ctx = SSLContext.getInstance("TLS");
+ if (anon) {
+ ctx.init(null, null, null);
+ } else {
+ TrustManager[] myTM = new TrustManager[] {
+ new MyX509TrustManager()
+ };
+ ctx.init (null, myTM, null);
+ }
+ sslfactory = ctx.getSocketFactory();
+ try {
+ ssl = (SSLSocket)sslfactory.createSocket(cc.sock,
+ cc.sock.getInetAddress().getHostName(),
+ cc.sock.getPort(), true);
+ } catch (java.io.IOException e) {
+ throw new Exception(e.toString());
+ }
+
+ if (anon) {
+ String[] supported;
+ ArrayList<String> enabled = new ArrayList<String>();
+
+ supported = ssl.getSupportedCipherSuites();
+
+ for (int i = 0; i < supported.length; i++)
+ if (supported[i].matches("TLS_DH_anon.*"))
+ enabled.add(supported[i]);
+
+ ssl.setEnabledCipherSuites(enabled.toArray(new String[0]));
+ } else {
+ ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites());
+ }
+
+ ssl.setEnabledProtocols(new String[]{"SSLv3","TLSv1"});
+ ssl.addHandshakeCompletedListener(new MyHandshakeListener());
+ }
+ catch (java.security.GeneralSecurityException e)
+ {
+ vlog.error ("TLS handshake failed " + e.toString ());
+ return;
+ }
+ }
+
+ public CSecurityTLS(boolean _anon)
+ {
+ anon = _anon;
+ setDefaults();
+ cafile = x509ca.getData();
+ crlfile = x509crl.getData();
+ }
+
+ public static void setDefaults()
+ {
+ String homeDir = null;
+
+ if ((homeDir=UserPrefs.getHomeDir()) == null) {
+ vlog.error("Could not obtain VNC home directory path");
+ return;
+ }
+
+ String vnchomedir = homeDir+UserPrefs.getFileSeparator()+".vnc"+
+ UserPrefs.getFileSeparator();
+ String caDefault = new String(vnchomedir+"x509_ca.pem");
+ String crlDefault = new String(vnchomedir+"x509_crl.pem");
+
+ if (new File(caDefault).exists())
+ x509ca.setDefaultStr(caDefault);
+ if (new File(crlDefault).exists())
+ x509crl.setDefaultStr(crlDefault);
+ }
+
+ public boolean processMsg(CConnection cc) {
+ is = cc.getInStream();
+ os = cc.getOutStream();
+
+ initGlobal();
+
+ if (!is.checkNoWait(1))
+ return false;
+
+ if (is.readU8() == 0) {
+ int result = is.readU32();
+ String reason;
+ if (result == Security.secResultFailed ||
+ result == Security.secResultTooMany)
+ reason = is.readString();
+ else
+ reason = new String("Authentication failure (protocol error)");
+ throw new AuthFailureException(reason);
+ }
+
+ // SSLSocket.getSession blocks until the handshake is complete
+ session = ssl.getSession();
+ if (!session.isValid())
+ throw new Exception("TLS Handshake failed!");
+
+ try {
+ cc.setStreams(new JavaInStream(ssl.getInputStream()),
+ new JavaOutStream(ssl.getOutputStream()));
+ } catch (java.io.IOException e) {
+ throw new Exception("Failed to set streams");
+ }
+
+ return true;
+ }
+
+ class MyHandshakeListener implements HandshakeCompletedListener {
+ public void handshakeCompleted(HandshakeCompletedEvent e) {
+ vlog.info("Handshake succesful!");
+ vlog.info("Using cipher suite: " + e.getCipherSuite());
+ }
+ }
+
+ class MyX509TrustManager implements X509TrustManager
+ {
+
+ X509TrustManager tm;
+
+ MyX509TrustManager() throws java.security.GeneralSecurityException
+ {
+ TrustManagerFactory tmf =
+ TrustManagerFactory.getInstance("PKIX");
+ KeyStore ks = KeyStore.getInstance("JKS");
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ try {
+ ks.load(null, null);
+ File cacert = new File(cafile);
+ if (!cacert.exists() || !cacert.canRead())
+ return;
+ InputStream caStream = new FileInputStream(cafile);
+ X509Certificate ca = (X509Certificate)cf.generateCertificate(caStream);
+ ks.setCertificateEntry("CA", ca);
+ PKIXBuilderParameters params = new PKIXBuilderParameters(ks, new X509CertSelector());
+ File crlcert = new File(crlfile);
+ if (!crlcert.exists() || !crlcert.canRead()) {
+ params.setRevocationEnabled(false);
+ } else {
+ InputStream crlStream = new FileInputStream(crlfile);
+ Collection<? extends CRL> crls = cf.generateCRLs(crlStream);
+ CertStoreParameters csp = new CollectionCertStoreParameters(crls);
+ CertStore store = CertStore.getInstance("Collection", csp);
+ params.addCertStore(store);
+ params.setRevocationEnabled(true);
+ }
+ tmf.init(new CertPathTrustManagerParameters(params));
+ } catch (java.io.FileNotFoundException e) {
+ vlog.error(e.toString());
+ } catch (java.io.IOException e) {
+ vlog.error(e.toString());
+ }
+ tm = (X509TrustManager)tmf.getTrustManagers()[0];
+ }
+
+ public void checkClientTrusted(X509Certificate[] chain, String authType)
+ throws CertificateException
+ {
+ tm.checkClientTrusted(chain, authType);
+ }
+
+ public void checkServerTrusted(X509Certificate[] chain, String authType)
+ throws CertificateException
+ {
+ try {
+ tm.checkServerTrusted(chain, authType);
+ } catch (CertificateException e) {
+ Object[] answer = {"Proceed", "Exit"};
+ int ret = JOptionPane.showOptionDialog(null,
+ e.getCause().getLocalizedMessage()+"\n"+
+ "Continue connecting to this host?",
+ "Confirm certificate exception?",
+ JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
+ null, answer, answer[0]);
+ if (ret == JOptionPane.NO_OPTION)
+ System.exit(1);
+ } catch (java.lang.Exception e) {
+ throw new Exception(e.toString());
+ }
+ }
+
+ public X509Certificate[] getAcceptedIssuers ()
+ {
+ return tm.getAcceptedIssuers();
+ }
+ }
+
+ public final int getType() { return anon ? Security.secTypeTLSNone : Security.secTypeX509None; }
+ public final String description()
+ { return anon ? "TLS Encryption without VncAuth" : "X509 Encryption without VncAuth"; }
+
+
+ //protected void setParam();
+ //protected void checkSession();
+ protected CConnection cc;
+
+ private boolean anon;
+ private SSLSession session;
+ private String cafile, crlfile;
+ private InStream is;
+ private OutStream os;
+ private SSLSocket ssl;
+
+ static LogWriter vlog = new LogWriter("CSecurityTLS");
+}
diff --git a/java/com/tigervnc/rfb/CSecurityVeNCrypt.java b/java/com/tigervnc/rfb/CSecurityVeNCrypt.java
new file mode 100644
index 00000000..ae758e7f
--- /dev/null
+++ b/java/com/tigervnc/rfb/CSecurityVeNCrypt.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2003 Sun Microsystems, Inc.
+ *
+ * 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;
+
+import java.util.*;
+
+import com.tigervnc.rdr.*;
+
+public class CSecurityVeNCrypt extends CSecurity {
+
+ public CSecurityVeNCrypt(SecurityClient sec)
+ {
+ haveRecvdMajorVersion = false;
+ haveRecvdMinorVersion = false;
+ haveSentVersion = false;
+ haveAgreedVersion = false;
+ haveListOfTypes = false;
+ haveNumberOfTypes = false;
+ haveChosenType = false;
+ majorVersion = 0;
+ minorVersion = 0;
+ chosenType = Security.secTypeVeNCrypt;
+ nAvailableTypes = 0;
+ availableTypes = null;
+ iAvailableType = 0;
+ security = sec;
+ }
+
+ public boolean processMsg(CConnection cc) {
+ InStream is = cc.getInStream();
+ OutStream os = cc.getOutStream();
+
+ /* get major, minor versions, send what we can support (or 0.0 for can't support it) */
+ if (!haveRecvdMinorVersion) {
+ minorVersion = is.readU8();
+ haveRecvdMinorVersion = true;
+
+ return false;
+ }
+
+ if (!haveRecvdMajorVersion) {
+ majorVersion = is.readU8();
+ haveRecvdMajorVersion = true;
+ }
+
+ /* major version in upper 8 bits and minor version in lower 8 bits */
+ int Version = (majorVersion << 8) | minorVersion;
+
+ if (!haveSentVersion) {
+ /* Currently we don't support former VeNCrypt 0.1 */
+ if (Version >= 0x0002) {
+ majorVersion = 0;
+ minorVersion = 2;
+ os.writeU8(majorVersion);
+ os.writeU8(minorVersion);
+ os.flush();
+ } else {
+ /* Send 0.0 to indicate no support */
+ majorVersion = 0;
+ minorVersion = 0;
+ os.writeU8(majorVersion);
+ os.writeU8(minorVersion);
+ os.flush();
+ throw new Exception("Server reported an unsupported VeNCrypt version");
+ }
+
+ haveSentVersion = true;
+ return false;
+ }
+
+ /* Check that the server is OK */
+ if (!haveAgreedVersion) {
+ if (is.readU8() != 0)
+ throw new Exception("Server reported it could not support the VeNCrypt version");
+
+ haveAgreedVersion = true;
+ return false;
+ }
+
+ /* get a number of types */
+ if (!haveNumberOfTypes) {
+ nAvailableTypes = is.readU8();
+ iAvailableType = 0;
+
+ if (nAvailableTypes <= 0)
+ throw new Exception("The server reported no VeNCrypt sub-types");
+
+ availableTypes = new int[nAvailableTypes];
+ haveNumberOfTypes = true;
+ return false;
+ }
+
+ if (nAvailableTypes > 0) {
+ /* read in the types possible */
+ if (!haveListOfTypes) {
+ if (is.checkNoWait(4)) {
+ availableTypes[iAvailableType++] = is.readU32();
+ haveListOfTypes = (iAvailableType >= nAvailableTypes);
+ vlog.debug("Server offers security type "+
+ Security.secTypeName(availableTypes[iAvailableType - 1])+" ("+
+ availableTypes[iAvailableType - 1]+")");
+
+ if (!haveListOfTypes)
+ return false;
+
+ } else
+ return false;
+ }
+
+ /* make a choice and send it to the server, meanwhile set up the stack */
+ if (!haveChosenType) {
+ chosenType = Security.secTypeInvalid;
+ int i;
+ Iterator j;
+ List<Integer> secTypes = new ArrayList<Integer>();
+
+ secTypes = security.GetEnabledExtSecTypes();
+
+ /* Honor server's security type order */
+ for (i = 0; i < nAvailableTypes; i++) {
+ for (j = secTypes.iterator(); j.hasNext(); ) {
+ int refType = (Integer)j.next();
+ if (refType == availableTypes[i]) {
+ chosenType = refType;
+ break;
+ }
+ }
+
+ if (chosenType != Security.secTypeInvalid)
+ break;
+ }
+
+ vlog.debug("Choosing security type "+Security.secTypeName(chosenType)+
+ " ("+chosenType+")");
+
+ /* Set up the stack according to the chosen type: */
+ if (chosenType == Security.secTypeInvalid || chosenType == Security.secTypeVeNCrypt)
+ throw new AuthFailureException("No valid VeNCrypt sub-type");
+
+ csecurity = security.GetCSecurity(chosenType);
+
+ /* send chosen type to server */
+ os.writeU32(chosenType);
+ os.flush();
+
+ haveChosenType = true;
+ }
+ } else {
+ /*
+ * Server told us that there are 0 types it can support - this should not
+ * happen, since if the server supports 0 sub-types, it doesn't support
+ * this security type
+ */
+ throw new AuthFailureException("The server reported 0 VeNCrypt sub-types");
+ }
+
+ return csecurity.processMsg(cc);
+ }
+
+ public final int getType() { return chosenType; }
+ public final String description() { return Security.secTypeName(chosenType); }
+
+ public static StringParameter secTypesStr;
+
+ private CSecurity csecurity;
+ SecurityClient security;
+ private boolean haveRecvdMajorVersion;
+ private boolean haveRecvdMinorVersion;
+ private boolean haveSentVersion;
+ private boolean haveAgreedVersion;
+ private boolean haveListOfTypes;
+ private boolean haveNumberOfTypes;
+ private boolean haveChosenType;
+ private int majorVersion, minorVersion;
+ private int chosenType;
+ private int nAvailableTypes;
+ private int[] availableTypes;
+ private int iAvailableType;
+ //private final String desc;
+
+ static LogWriter vlog = new LogWriter("CSecurityVeNCrypt");
+}
diff --git a/java/com/tigervnc/rfb/CSecurityVncAuth.java b/java/com/tigervnc/rfb/CSecurityVncAuth.java
new file mode 100644
index 00000000..405e79fa
--- /dev/null
+++ b/java/com/tigervnc/rfb/CSecurityVncAuth.java
@@ -0,0 +1,66 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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;
+
+import com.tigervnc.rdr.*;
+import com.tigervnc.vncviewer.*;
+
+public class CSecurityVncAuth extends CSecurity {
+
+ public CSecurityVncAuth() { }
+
+ private static final int vncAuthChallengeSize = 16;
+
+ public boolean processMsg(CConnection cc)
+ {
+ InStream is = cc.getInStream();
+ OutStream os = cc.getOutStream();
+
+ // Read the challenge & obtain the user's password
+ byte[] challenge = new byte[vncAuthChallengeSize];
+ is.readBytes(challenge, 0, vncAuthChallengeSize);
+ StringBuffer passwd = new StringBuffer();
+ CConn.upg.getUserPasswd(null, passwd);
+
+ // Calculate the correct response
+ byte[] key = new byte[8];
+ int pwdLen = passwd.length();
+ byte[] utf8str = new byte[pwdLen];
+ try {
+ utf8str = passwd.toString().getBytes("UTF8");
+ } catch(java.io.UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ for (int i=0; i<8; i++)
+ key[i] = i<pwdLen ? utf8str[i] : 0;
+ DesCipher des = new DesCipher(key);
+ for (int j = 0; j < vncAuthChallengeSize; j += 8)
+ des.encrypt(challenge,j,challenge,j);
+
+ // Return the response to the server
+ os.writeBytes(challenge, 0, vncAuthChallengeSize);
+ os.flush();
+ return true;
+ }
+
+ public int getType() { return Security.secTypeVncAuth; }
+ public String description() { return "No Encryption"; }
+
+ static LogWriter vlog = new LogWriter("VncAuth");
+}
diff --git a/java/com/tigervnc/rfb/Configuration.java b/java/com/tigervnc/rfb/Configuration.java
new file mode 100644
index 00000000..bc676087
--- /dev/null
+++ b/java/com/tigervnc/rfb/Configuration.java
@@ -0,0 +1,91 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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.
+ */
+
+//
+// Configuration - class for dealing with configuration parameters.
+//
+
+package com.tigervnc.rfb;
+
+public class Configuration {
+
+ // - Set named parameter to value
+ public static boolean setParam(String name, String value) {
+ VoidParameter param = getParam(name);
+ if (param == null) return false;
+ return param.setParam(value);
+ }
+
+ // - Set parameter to value (separated by "=")
+ public static boolean setParam(String config) {
+ boolean hyphen = false;
+ if (config.charAt(0) == '-') {
+ hyphen = true;
+ if (config.charAt(1) == '-')
+ config = config.substring(2); // allow gnu-style --<option>
+ else
+ config = config.substring(1);
+ }
+ int equal = config.indexOf('=');
+ if (equal != -1) {
+ return setParam(config.substring(0, equal), config.substring(equal+1));
+ } else if (hyphen) {
+ VoidParameter param = getParam(config);
+ if (param == null) return false;
+ return param.setParam();
+ }
+ return false;
+ }
+
+ // - Get named parameter
+ public static VoidParameter getParam(String name) {
+ VoidParameter current = head;
+ while (current != null) {
+ if (name.equalsIgnoreCase(current.getName()))
+ return current;
+ current = current.next;
+ }
+ return null;
+ }
+
+ public static String listParams() {
+ StringBuffer s = new StringBuffer();
+
+ VoidParameter current = head;
+ while (current != null) {
+ String def_str = current.getDefaultStr();
+ String desc = current.getDescription();
+ s.append(" "+current.getName()+" - "+desc+" (default="+def_str+")\n");
+ current = current.next;
+ }
+
+ return s.toString();
+ }
+
+ public static void readAppletParams(java.applet.Applet applet) {
+ VoidParameter current = head;
+ while (current != null) {
+ String str = applet.getParameter(current.getName());
+ if (str != null)
+ current.setParam(str);
+ current = current.next;
+ }
+ }
+
+ public static VoidParameter head;
+}
diff --git a/java/com/tigervnc/rfb/ConnFailedException.java b/java/com/tigervnc/rfb/ConnFailedException.java
new file mode 100644
index 00000000..d1ddcb4e
--- /dev/null
+++ b/java/com/tigervnc/rfb/ConnFailedException.java
@@ -0,0 +1,23 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 ConnFailedException extends Exception {
+ public ConnFailedException(String s) { super(s); }
+}
diff --git a/java/com/tigervnc/rfb/ConnParams.java b/java/com/tigervnc/rfb/ConnParams.java
new file mode 100644
index 00000000..70d6114f
--- /dev/null
+++ b/java/com/tigervnc/rfb/ConnParams.java
@@ -0,0 +1,171 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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;
+
+import com.tigervnc.rdr.*;
+
+public class ConnParams {
+ static LogWriter vlog = new LogWriter("ConnParams");
+
+ public ConnParams() {
+ majorVersion = 0; minorVersion = 0;
+ width = 0; height = 0; useCopyRect = false;
+ supportsLocalCursor = false; supportsLocalXCursor = false;
+ supportsDesktopResize = false; supportsExtendedDesktopSize = false;
+ supportsDesktopRename = false; supportsLastRect = false;
+ supportsSetDesktopSize = false; supportsClientRedirect = false;
+ customCompressLevel = false; compressLevel = 6;
+ noJpeg = false; qualityLevel = -1;
+ name_ = null; nEncodings_ = 0; encodings_ = null;
+ currentEncoding_ = Encodings.encodingRaw; verStrPos = 0;
+ screenLayout = new ScreenSet();
+
+ setName("");
+ }
+
+ public boolean readVersion(InStream is, Boolean done)
+ {
+ if (verStrPos >= 12) return false;
+ verStr = new StringBuilder(13);
+ while (verStrPos < 12 && is.checkNoWait(1)) {
+ verStr.insert(verStrPos++,(char)is.readU8());
+ }
+
+ if (verStrPos < 12) {
+ done = Boolean.valueOf(false);
+ return true;
+ }
+ done = Boolean.valueOf(true);
+ verStr.insert(12,'0');
+ verStrPos = 0;
+ if (verStr.toString().matches("RFB \\d{3}\\.\\d{3}\\n0")) {
+ majorVersion = Integer.parseInt(verStr.substring(4,7));
+ minorVersion = Integer.parseInt(verStr.substring(8,11));
+ return true;
+ }
+ return false;
+ }
+
+ public void writeVersion(OutStream os) {
+ String str = String.format("RFB %03d.%03d\n", majorVersion, minorVersion);
+ os.writeBytes(str.getBytes(), 0, 12);
+ os.flush();
+ }
+
+ public int majorVersion;
+ public int minorVersion;
+
+ public void setVersion(int major, int minor) {
+ majorVersion = major; minorVersion = minor;
+ }
+ public boolean isVersion(int major, int minor) {
+ return majorVersion == major && minorVersion == minor;
+ }
+ public boolean beforeVersion(int major, int minor) {
+ return (majorVersion < major ||
+ (majorVersion == major && minorVersion < minor));
+ }
+ public boolean afterVersion(int major, int minor) {
+ return !beforeVersion(major,minor+1);
+ }
+
+ public int width;
+ public int height;
+ public ScreenSet screenLayout;
+
+ public PixelFormat pf() { return pf_; }
+ public void setPF(PixelFormat pf) {
+ pf_ = pf;
+ if (pf.bpp != 8 && pf.bpp != 16 && pf.bpp != 32) {
+ throw new Exception("setPF: not 8, 16 or 32 bpp?");
+ }
+ }
+
+ public String name() { return name_; }
+ public void setName(String name)
+ {
+ name_ = name;
+ }
+
+ public int currentEncoding() { return currentEncoding_; }
+ public int nEncodings() { return nEncodings_; }
+ public int[] encodings() { return encodings_; }
+ public void setEncodings(int nEncodings, int[] encodings)
+ {
+ if (nEncodings > nEncodings_) {
+ encodings_ = new int[nEncodings];
+ }
+ nEncodings_ = nEncodings;
+ useCopyRect = false;
+ supportsLocalCursor = false;
+ supportsDesktopResize = false;
+ customCompressLevel = false;
+ compressLevel = -1;
+ noJpeg = true;
+ qualityLevel = -1;
+ 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.pseudoEncodingDesktopSize)
+ supportsDesktopResize = true;
+ else if (encodings[i] == Encodings.pseudoEncodingClientRedirect)
+ supportsClientRedirect = true;
+ else if (encodings[i] >= Encodings.pseudoEncodingCompressLevel0 &&
+ encodings[i] <= Encodings.pseudoEncodingCompressLevel9) {
+ customCompressLevel = true;
+ compressLevel = encodings[i] - Encodings.pseudoEncodingCompressLevel0;
+ } else if (encodings[i] >= Encodings.pseudoEncodingQualityLevel0 &&
+ encodings[i] <= Encodings.pseudoEncodingQualityLevel9) {
+ noJpeg = false;
+ qualityLevel = encodings[i] - Encodings.pseudoEncodingQualityLevel0;
+ } else if (encodings[i] <= Encodings.encodingMax &&
+ Encoder.supported(encodings[i]))
+ currentEncoding_ = encodings[i];
+ }
+ }
+ public boolean useCopyRect;
+
+ public boolean supportsLocalCursor;
+ public boolean supportsLocalXCursor;
+ public boolean supportsDesktopResize;
+ public boolean supportsExtendedDesktopSize;
+ public boolean supportsDesktopRename;
+ public boolean supportsClientRedirect;
+ public boolean supportsLastRect;
+
+ public boolean supportsSetDesktopSize;
+
+ public boolean customCompressLevel;
+ public int compressLevel;
+ public boolean noJpeg;
+ public int qualityLevel;
+
+ private PixelFormat pf_;
+ private String name_;
+ private int nEncodings_;
+ private int[] encodings_;
+ private int currentEncoding_;
+ private StringBuilder verStr;
+ private int verStrPos;
+}
diff --git a/java/com/tigervnc/rfb/Cursor.java b/java/com/tigervnc/rfb/Cursor.java
new file mode 100644
index 00000000..420eb82a
--- /dev/null
+++ b/java/com/tigervnc/rfb/Cursor.java
@@ -0,0 +1,34 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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;
+
+import java.awt.*;
+
+public class Cursor extends ManagedPixelBuffer {
+
+ public void setSize(int w, int h) {
+ super.setSize(w, h);
+ if (mask == null || mask.length < maskLen())
+ mask = new byte[maskLen()];
+ }
+ public int maskLen() { return (width() + 7) / 8 * height(); }
+
+ public Point hotspot;
+ public byte[] mask;
+}
diff --git a/java/com/tigervnc/rfb/Decoder.java b/java/com/tigervnc/rfb/Decoder.java
new file mode 100644
index 00000000..8d42ea5e
--- /dev/null
+++ b/java/com/tigervnc/rfb/Decoder.java
@@ -0,0 +1,51 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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;
+
+abstract public class Decoder {
+
+ abstract public void readRect(Rect r, CMsgHandler handler);
+
+ static public boolean supported(int encoding)
+ {
+/*
+ return encoding <= Encodings.encodingMax && createFns[encoding];
+*/
+ return (encoding == Encodings.encodingRaw ||
+ encoding == Encodings.encodingRRE ||
+ encoding == Encodings.encodingHextile ||
+ encoding == Encodings.encodingTight ||
+ encoding == Encodings.encodingZRLE);
+ }
+ static public Decoder createDecoder(int encoding, CMsgReader reader) {
+/*
+ if (encoding <= Encodings.encodingMax && createFns[encoding])
+ return (createFns[encoding])(reader);
+ return 0;
+*/
+ switch(encoding) {
+ case Encodings.encodingRaw: return new RawDecoder(reader);
+ case Encodings.encodingRRE: return new RREDecoder(reader);
+ case Encodings.encodingHextile: return new HextileDecoder(reader);
+ case Encodings.encodingTight: return new TightDecoder(reader);
+ case Encodings.encodingZRLE: return new ZRLEDecoder(reader);
+ }
+ return null;
+ }
+}
diff --git a/java/com/tigervnc/rfb/DesCipher.java b/java/com/tigervnc/rfb/DesCipher.java
new file mode 100644
index 00000000..f7ae9db9
--- /dev/null
+++ b/java/com/tigervnc/rfb/DesCipher.java
@@ -0,0 +1,496 @@
+//
+// This DES class has been extracted from package Acme.Crypto for use in VNC.
+// The bytebit[] array has been reversed so that the most significant bit
+// in each byte of the key is ignored, not the least significant. Also the
+// unnecessary odd parity code has been removed.
+//
+// These changes are:
+// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
+//
+// 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.
+//
+
+// DesCipher - the DES encryption method
+//
+// The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is:
+//
+// Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
+//
+// Permission to use, copy, modify, and distribute this software
+// and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
+// without fee is hereby granted, provided that this copyright notice is kept
+// intact.
+//
+// WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
+// OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE
+// FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+// DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
+//
+// THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
+// CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
+// PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
+// NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
+// SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
+// SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
+// PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP
+// SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
+// HIGH RISK ACTIVITIES.
+//
+//
+// The rest is:
+//
+// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+//
+// Visit the ACME Labs Java page for up-to-date versions of this and other
+// fine Java utilities: http://www.acme.com/java/
+
+
+/// The DES encryption method.
+// <P>
+// This is surprisingly fast, for pure Java. On a SPARC 20, wrapped
+// in Acme.Crypto.EncryptedOutputStream or Acme.Crypto.EncryptedInputStream,
+// it does around 7000 bytes/second.
+// <P>
+// Most of this code is by Dave Zimmerman <dzimm@widget.com>, and is
+// Copyright (c) 1996 Widget Workshop, Inc. See the source file for details.
+// <P>
+// <A HREF="/resources/classes/Acme/Crypto/DesCipher.java">Fetch the software.</A><BR>
+// <A HREF="/resources/classes/Acme.tar.Z">Fetch the entire Acme package.</A>
+// <P>
+// @see Des3Cipher
+// @see EncryptedOutputStream
+// @see EncryptedInputStream
+
+package com.tigervnc.rfb;
+
+public class DesCipher
+ {
+
+ // Constructor, byte-array key.
+ public DesCipher( byte[] key )
+ {
+ setKey( key );
+ }
+
+ // Key routines.
+
+ private int[] encryptKeys = new int[32];
+ private int[] decryptKeys = new int[32];
+
+ /// Set the key.
+ public void setKey( byte[] key )
+ {
+ deskey( key, true, encryptKeys );
+ deskey( key, false, decryptKeys );
+ }
+
+ // Turn an 8-byte key into internal keys.
+ private void deskey( byte[] keyBlock, boolean encrypting, int[] KnL )
+ {
+ int i, j, l, m, n;
+ int[] pc1m = new int[56];
+ int[] pcr = new int[56];
+ int[] kn = new int[32];
+
+ for ( j = 0; j < 56; ++j )
+ {
+ l = pc1[j];
+ m = l & 07;
+ pc1m[j] = ( (keyBlock[l >>> 3] & bytebit[m]) != 0 )? 1: 0;
+ }
+
+ for ( i = 0; i < 16; ++i )
+ {
+ if ( encrypting )
+ m = i << 1;
+ else
+ m = (15-i) << 1;
+ n = m+1;
+ kn[m] = kn[n] = 0;
+ for ( j = 0; j < 28; ++j )
+ {
+ l = j+totrot[i];
+ if ( l < 28 )
+ pcr[j] = pc1m[l];
+ else
+ pcr[j] = pc1m[l-28];
+ }
+ for ( j=28; j < 56; ++j )
+ {
+ l = j+totrot[i];
+ if ( l < 56 )
+ pcr[j] = pc1m[l];
+ else
+ pcr[j] = pc1m[l-28];
+ }
+ for ( j = 0; j < 24; ++j )
+ {
+ if ( pcr[pc2[j]] != 0 )
+ kn[m] |= bigbyte[j];
+ if ( pcr[pc2[j+24]] != 0 )
+ kn[n] |= bigbyte[j];
+ }
+ }
+ cookey( kn, KnL );
+ }
+
+ private void cookey( int[] raw, int KnL[] )
+ {
+ int raw0, raw1;
+ int rawi, KnLi;
+ int i;
+
+ for ( i = 0, rawi = 0, KnLi = 0; i < 16; ++i )
+ {
+ raw0 = raw[rawi++];
+ raw1 = raw[rawi++];
+ KnL[KnLi] = (raw0 & 0x00fc0000) << 6;
+ KnL[KnLi] |= (raw0 & 0x00000fc0) << 10;
+ KnL[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
+ KnL[KnLi] |= (raw1 & 0x00000fc0) >>> 6;
+ ++KnLi;
+ KnL[KnLi] = (raw0 & 0x0003f000) << 12;
+ KnL[KnLi] |= (raw0 & 0x0000003f) << 16;
+ KnL[KnLi] |= (raw1 & 0x0003f000) >>> 4;
+ KnL[KnLi] |= (raw1 & 0x0000003f);
+ ++KnLi;
+ }
+ }
+
+
+ // Block encryption routines.
+
+ private int[] tempInts = new int[2];
+
+ /// Encrypt a block of eight bytes.
+ public void encrypt( byte[] clearText, int clearOff, byte[] cipherText, int cipherOff )
+ {
+ squashBytesToInts( clearText, clearOff, tempInts, 0, 2 );
+ des( tempInts, tempInts, encryptKeys );
+ spreadIntsToBytes( tempInts, 0, cipherText, cipherOff, 2 );
+ }
+
+ /// Decrypt a block of eight bytes.
+ public void decrypt( byte[] cipherText, int cipherOff, byte[] clearText, int clearOff )
+ {
+ squashBytesToInts( cipherText, cipherOff, tempInts, 0, 2 );
+ des( tempInts, tempInts, decryptKeys );
+ spreadIntsToBytes( tempInts, 0, clearText, clearOff, 2 );
+ }
+
+ // The DES function.
+ private void des( int[] inInts, int[] outInts, int[] keys )
+ {
+ int fval, work, right, leftt;
+ int round;
+ int keysi = 0;
+
+ leftt = inInts[0];
+ right = inInts[1];
+
+ work = ((leftt >>> 4) ^ right) & 0x0f0f0f0f;
+ right ^= work;
+ leftt ^= (work << 4);
+
+ work = ((leftt >>> 16) ^ right) & 0x0000ffff;
+ right ^= work;
+ leftt ^= (work << 16);
+
+ work = ((right >>> 2) ^ leftt) & 0x33333333;
+ leftt ^= work;
+ right ^= (work << 2);
+
+ work = ((right >>> 8) ^ leftt) & 0x00ff00ff;
+ leftt ^= work;
+ right ^= (work << 8);
+ right = (right << 1) | ((right >>> 31) & 1);
+
+ work = (leftt ^ right) & 0xaaaaaaaa;
+ leftt ^= work;
+ right ^= work;
+ leftt = (leftt << 1) | ((leftt >>> 31) & 1);
+
+ for ( round = 0; round < 8; ++round )
+ {
+ work = (right << 28) | (right >>> 4);
+ work ^= keys[keysi++];
+ fval = SP7[ work & 0x0000003f ];
+ fval |= SP5[(work >>> 8) & 0x0000003f ];
+ fval |= SP3[(work >>> 16) & 0x0000003f ];
+ fval |= SP1[(work >>> 24) & 0x0000003f ];
+ work = right ^ keys[keysi++];
+ fval |= SP8[ work & 0x0000003f ];
+ fval |= SP6[(work >>> 8) & 0x0000003f ];
+ fval |= SP4[(work >>> 16) & 0x0000003f ];
+ fval |= SP2[(work >>> 24) & 0x0000003f ];
+ leftt ^= fval;
+ work = (leftt << 28) | (leftt >>> 4);
+ work ^= keys[keysi++];
+ fval = SP7[ work & 0x0000003f ];
+ fval |= SP5[(work >>> 8) & 0x0000003f ];
+ fval |= SP3[(work >>> 16) & 0x0000003f ];
+ fval |= SP1[(work >>> 24) & 0x0000003f ];
+ work = leftt ^ keys[keysi++];
+ fval |= SP8[ work & 0x0000003f ];
+ fval |= SP6[(work >>> 8) & 0x0000003f ];
+ fval |= SP4[(work >>> 16) & 0x0000003f ];
+ fval |= SP2[(work >>> 24) & 0x0000003f ];
+ right ^= fval;
+ }
+
+ right = (right << 31) | (right >>> 1);
+ work = (leftt ^ right) & 0xaaaaaaaa;
+ leftt ^= work;
+ right ^= work;
+ leftt = (leftt << 31) | (leftt >>> 1);
+ work = ((leftt >>> 8) ^ right) & 0x00ff00ff;
+ right ^= work;
+ leftt ^= (work << 8);
+ work = ((leftt >>> 2) ^ right) & 0x33333333;
+ right ^= work;
+ leftt ^= (work << 2);
+ work = ((right >>> 16) ^ leftt) & 0x0000ffff;
+ leftt ^= work;
+ right ^= (work << 16);
+ work = ((right >>> 4) ^ leftt) & 0x0f0f0f0f;
+ leftt ^= work;
+ right ^= (work << 4);
+ outInts[0] = right;
+ outInts[1] = leftt;
+ }
+
+
+ // Tables, permutations, S-boxes, etc.
+
+ private static byte[] bytebit = {
+ (byte)0x01, (byte)0x02, (byte)0x04, (byte)0x08,
+ (byte)0x10, (byte)0x20, (byte)0x40, (byte)0x80
+ };
+ private static int[] bigbyte = {
+ 0x800000, 0x400000, 0x200000, 0x100000,
+ 0x080000, 0x040000, 0x020000, 0x010000,
+ 0x008000, 0x004000, 0x002000, 0x001000,
+ 0x000800, 0x000400, 0x000200, 0x000100,
+ 0x000080, 0x000040, 0x000020, 0x000010,
+ 0x000008, 0x000004, 0x000002, 0x000001
+ };
+ private static byte[] pc1 = {
+ (byte)56, (byte)48, (byte)40, (byte)32, (byte)24, (byte)16, (byte) 8,
+ (byte) 0, (byte)57, (byte)49, (byte)41, (byte)33, (byte)25, (byte)17,
+ (byte) 9, (byte) 1, (byte)58, (byte)50, (byte)42, (byte)34, (byte)26,
+ (byte)18, (byte)10, (byte) 2, (byte)59, (byte)51, (byte)43, (byte)35,
+ (byte)62, (byte)54, (byte)46, (byte)38, (byte)30, (byte)22, (byte)14,
+ (byte) 6, (byte)61, (byte)53, (byte)45, (byte)37, (byte)29, (byte)21,
+ (byte)13, (byte) 5, (byte)60, (byte)52, (byte)44, (byte)36, (byte)28,
+ (byte)20, (byte)12, (byte) 4, (byte)27, (byte)19, (byte)11, (byte)3
+ };
+ private static int[] totrot = {
+ 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
+ };
+
+ private static byte[] pc2 = {
+ (byte)13, (byte)16, (byte)10, (byte)23, (byte) 0, (byte) 4,
+ (byte) 2, (byte)27, (byte)14, (byte) 5, (byte)20, (byte) 9,
+ (byte)22, (byte)18, (byte)11, (byte)3 , (byte)25, (byte) 7,
+ (byte)15, (byte) 6, (byte)26, (byte)19, (byte)12, (byte) 1,
+ (byte)40, (byte)51, (byte)30, (byte)36, (byte)46, (byte)54,
+ (byte)29, (byte)39, (byte)50, (byte)44, (byte)32, (byte)47,
+ (byte)43, (byte)48, (byte)38, (byte)55, (byte)33, (byte)52,
+ (byte)45, (byte)41, (byte)49, (byte)35, (byte)28, (byte)31,
+ };
+
+ private static int[] SP1 = {
+ 0x01010400, 0x00000000, 0x00010000, 0x01010404,
+ 0x01010004, 0x00010404, 0x00000004, 0x00010000,
+ 0x00000400, 0x01010400, 0x01010404, 0x00000400,
+ 0x01000404, 0x01010004, 0x01000000, 0x00000004,
+ 0x00000404, 0x01000400, 0x01000400, 0x00010400,
+ 0x00010400, 0x01010000, 0x01010000, 0x01000404,
+ 0x00010004, 0x01000004, 0x01000004, 0x00010004,
+ 0x00000000, 0x00000404, 0x00010404, 0x01000000,
+ 0x00010000, 0x01010404, 0x00000004, 0x01010000,
+ 0x01010400, 0x01000000, 0x01000000, 0x00000400,
+ 0x01010004, 0x00010000, 0x00010400, 0x01000004,
+ 0x00000400, 0x00000004, 0x01000404, 0x00010404,
+ 0x01010404, 0x00010004, 0x01010000, 0x01000404,
+ 0x01000004, 0x00000404, 0x00010404, 0x01010400,
+ 0x00000404, 0x01000400, 0x01000400, 0x00000000,
+ 0x00010004, 0x00010400, 0x00000000, 0x01010004
+ };
+ private static int[] SP2 = {
+ 0x80108020, 0x80008000, 0x00008000, 0x00108020,
+ 0x00100000, 0x00000020, 0x80100020, 0x80008020,
+ 0x80000020, 0x80108020, 0x80108000, 0x80000000,
+ 0x80008000, 0x00100000, 0x00000020, 0x80100020,
+ 0x00108000, 0x00100020, 0x80008020, 0x00000000,
+ 0x80000000, 0x00008000, 0x00108020, 0x80100000,
+ 0x00100020, 0x80000020, 0x00000000, 0x00108000,
+ 0x00008020, 0x80108000, 0x80100000, 0x00008020,
+ 0x00000000, 0x00108020, 0x80100020, 0x00100000,
+ 0x80008020, 0x80100000, 0x80108000, 0x00008000,
+ 0x80100000, 0x80008000, 0x00000020, 0x80108020,
+ 0x00108020, 0x00000020, 0x00008000, 0x80000000,
+ 0x00008020, 0x80108000, 0x00100000, 0x80000020,
+ 0x00100020, 0x80008020, 0x80000020, 0x00100020,
+ 0x00108000, 0x00000000, 0x80008000, 0x00008020,
+ 0x80000000, 0x80100020, 0x80108020, 0x00108000
+ };
+ private static int[] SP3 = {
+ 0x00000208, 0x08020200, 0x00000000, 0x08020008,
+ 0x08000200, 0x00000000, 0x00020208, 0x08000200,
+ 0x00020008, 0x08000008, 0x08000008, 0x00020000,
+ 0x08020208, 0x00020008, 0x08020000, 0x00000208,
+ 0x08000000, 0x00000008, 0x08020200, 0x00000200,
+ 0x00020200, 0x08020000, 0x08020008, 0x00020208,
+ 0x08000208, 0x00020200, 0x00020000, 0x08000208,
+ 0x00000008, 0x08020208, 0x00000200, 0x08000000,
+ 0x08020200, 0x08000000, 0x00020008, 0x00000208,
+ 0x00020000, 0x08020200, 0x08000200, 0x00000000,
+ 0x00000200, 0x00020008, 0x08020208, 0x08000200,
+ 0x08000008, 0x00000200, 0x00000000, 0x08020008,
+ 0x08000208, 0x00020000, 0x08000000, 0x08020208,
+ 0x00000008, 0x00020208, 0x00020200, 0x08000008,
+ 0x08020000, 0x08000208, 0x00000208, 0x08020000,
+ 0x00020208, 0x00000008, 0x08020008, 0x00020200
+ };
+ private static int[] SP4 = {
+ 0x00802001, 0x00002081, 0x00002081, 0x00000080,
+ 0x00802080, 0x00800081, 0x00800001, 0x00002001,
+ 0x00000000, 0x00802000, 0x00802000, 0x00802081,
+ 0x00000081, 0x00000000, 0x00800080, 0x00800001,
+ 0x00000001, 0x00002000, 0x00800000, 0x00802001,
+ 0x00000080, 0x00800000, 0x00002001, 0x00002080,
+ 0x00800081, 0x00000001, 0x00002080, 0x00800080,
+ 0x00002000, 0x00802080, 0x00802081, 0x00000081,
+ 0x00800080, 0x00800001, 0x00802000, 0x00802081,
+ 0x00000081, 0x00000000, 0x00000000, 0x00802000,
+ 0x00002080, 0x00800080, 0x00800081, 0x00000001,
+ 0x00802001, 0x00002081, 0x00002081, 0x00000080,
+ 0x00802081, 0x00000081, 0x00000001, 0x00002000,
+ 0x00800001, 0x00002001, 0x00802080, 0x00800081,
+ 0x00002001, 0x00002080, 0x00800000, 0x00802001,
+ 0x00000080, 0x00800000, 0x00002000, 0x00802080
+ };
+ private static int[] SP5 = {
+ 0x00000100, 0x02080100, 0x02080000, 0x42000100,
+ 0x00080000, 0x00000100, 0x40000000, 0x02080000,
+ 0x40080100, 0x00080000, 0x02000100, 0x40080100,
+ 0x42000100, 0x42080000, 0x00080100, 0x40000000,
+ 0x02000000, 0x40080000, 0x40080000, 0x00000000,
+ 0x40000100, 0x42080100, 0x42080100, 0x02000100,
+ 0x42080000, 0x40000100, 0x00000000, 0x42000000,
+ 0x02080100, 0x02000000, 0x42000000, 0x00080100,
+ 0x00080000, 0x42000100, 0x00000100, 0x02000000,
+ 0x40000000, 0x02080000, 0x42000100, 0x40080100,
+ 0x02000100, 0x40000000, 0x42080000, 0x02080100,
+ 0x40080100, 0x00000100, 0x02000000, 0x42080000,
+ 0x42080100, 0x00080100, 0x42000000, 0x42080100,
+ 0x02080000, 0x00000000, 0x40080000, 0x42000000,
+ 0x00080100, 0x02000100, 0x40000100, 0x00080000,
+ 0x00000000, 0x40080000, 0x02080100, 0x40000100
+ };
+ private static int[] SP6 = {
+ 0x20000010, 0x20400000, 0x00004000, 0x20404010,
+ 0x20400000, 0x00000010, 0x20404010, 0x00400000,
+ 0x20004000, 0x00404010, 0x00400000, 0x20000010,
+ 0x00400010, 0x20004000, 0x20000000, 0x00004010,
+ 0x00000000, 0x00400010, 0x20004010, 0x00004000,
+ 0x00404000, 0x20004010, 0x00000010, 0x20400010,
+ 0x20400010, 0x00000000, 0x00404010, 0x20404000,
+ 0x00004010, 0x00404000, 0x20404000, 0x20000000,
+ 0x20004000, 0x00000010, 0x20400010, 0x00404000,
+ 0x20404010, 0x00400000, 0x00004010, 0x20000010,
+ 0x00400000, 0x20004000, 0x20000000, 0x00004010,
+ 0x20000010, 0x20404010, 0x00404000, 0x20400000,
+ 0x00404010, 0x20404000, 0x00000000, 0x20400010,
+ 0x00000010, 0x00004000, 0x20400000, 0x00404010,
+ 0x00004000, 0x00400010, 0x20004010, 0x00000000,
+ 0x20404000, 0x20000000, 0x00400010, 0x20004010
+ };
+ private static int[] SP7 = {
+ 0x00200000, 0x04200002, 0x04000802, 0x00000000,
+ 0x00000800, 0x04000802, 0x00200802, 0x04200800,
+ 0x04200802, 0x00200000, 0x00000000, 0x04000002,
+ 0x00000002, 0x04000000, 0x04200002, 0x00000802,
+ 0x04000800, 0x00200802, 0x00200002, 0x04000800,
+ 0x04000002, 0x04200000, 0x04200800, 0x00200002,
+ 0x04200000, 0x00000800, 0x00000802, 0x04200802,
+ 0x00200800, 0x00000002, 0x04000000, 0x00200800,
+ 0x04000000, 0x00200800, 0x00200000, 0x04000802,
+ 0x04000802, 0x04200002, 0x04200002, 0x00000002,
+ 0x00200002, 0x04000000, 0x04000800, 0x00200000,
+ 0x04200800, 0x00000802, 0x00200802, 0x04200800,
+ 0x00000802, 0x04000002, 0x04200802, 0x04200000,
+ 0x00200800, 0x00000000, 0x00000002, 0x04200802,
+ 0x00000000, 0x00200802, 0x04200000, 0x00000800,
+ 0x04000002, 0x04000800, 0x00000800, 0x00200002
+ };
+ private static int[] SP8 = {
+ 0x10001040, 0x00001000, 0x00040000, 0x10041040,
+ 0x10000000, 0x10001040, 0x00000040, 0x10000000,
+ 0x00040040, 0x10040000, 0x10041040, 0x00041000,
+ 0x10041000, 0x00041040, 0x00001000, 0x00000040,
+ 0x10040000, 0x10000040, 0x10001000, 0x00001040,
+ 0x00041000, 0x00040040, 0x10040040, 0x10041000,
+ 0x00001040, 0x00000000, 0x00000000, 0x10040040,
+ 0x10000040, 0x10001000, 0x00041040, 0x00040000,
+ 0x00041040, 0x00040000, 0x10041000, 0x00001000,
+ 0x00000040, 0x10040040, 0x00001000, 0x00041040,
+ 0x10001000, 0x00000040, 0x10000040, 0x10040000,
+ 0x10040040, 0x10000000, 0x00040000, 0x10001040,
+ 0x00000000, 0x10041040, 0x00040040, 0x10000040,
+ 0x10040000, 0x10001000, 0x10001040, 0x00000000,
+ 0x10041040, 0x00041000, 0x00041000, 0x00001040,
+ 0x00001040, 0x00040040, 0x10000000, 0x10041000
+ };
+
+ // Routines taken from other parts of the Acme utilities.
+
+ /// Squash bytes down to ints.
+ public static void squashBytesToInts( byte[] inBytes, int inOff, int[] outInts, int outOff, int intLen )
+ {
+ for ( int i = 0; i < intLen; ++i )
+ outInts[outOff + i] =
+ ( ( inBytes[inOff + i * 4 ] & 0xff ) << 24 ) |
+ ( ( inBytes[inOff + i * 4 + 1] & 0xff ) << 16 ) |
+ ( ( inBytes[inOff + i * 4 + 2] & 0xff ) << 8 ) |
+ ( inBytes[inOff + i * 4 + 3] & 0xff );
+ }
+
+ /// Spread ints into bytes.
+ public static void spreadIntsToBytes( int[] inInts, int inOff, byte[] outBytes, int outOff, int intLen )
+ {
+ for ( int i = 0; i < intLen; ++i )
+ {
+ outBytes[outOff + i * 4 ] = (byte) ( inInts[inOff + i] >>> 24 );
+ outBytes[outOff + i * 4 + 1] = (byte) ( inInts[inOff + i] >>> 16 );
+ outBytes[outOff + i * 4 + 2] = (byte) ( inInts[inOff + i] >>> 8 );
+ outBytes[outOff + i * 4 + 3] = (byte) inInts[inOff + i];
+ }
+ }
+ }
diff --git a/java/com/tigervnc/rfb/Encoder.java b/java/com/tigervnc/rfb/Encoder.java
new file mode 100644
index 00000000..0964f88e
--- /dev/null
+++ b/java/com/tigervnc/rfb/Encoder.java
@@ -0,0 +1,25 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 Encoder {
+ static public boolean supported(int encoding) {
+ return false;
+ }
+}
diff --git a/java/com/tigervnc/rfb/Encodings.java b/java/com/tigervnc/rfb/Encodings.java
new file mode 100644
index 00000000..493d5488
--- /dev/null
+++ b/java/com/tigervnc/rfb/Encodings.java
@@ -0,0 +1,70 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 Encodings {
+
+ public static final int encodingRaw = 0;
+ public static final int encodingCopyRect = 1;
+ public static final int encodingRRE = 2;
+ public static final int encodingCoRRE = 4;
+ public static final int encodingHextile = 5;
+ public static final int encodingTight = 7;
+ public static final int encodingZRLE = 16;
+
+ public static final int encodingMax = 255;
+
+ public static final int pseudoEncodingXCursor = -240;
+ public static final int pseudoEncodingCursor = -239;
+ public static final int pseudoEncodingDesktopSize = -223;
+ public static final int pseudoEncodingExtendedDesktopSize = -308;
+ public static final int pseudoEncodingDesktopName = -307;
+ public static final int pseudoEncodingClientRedirect = -311;
+
+ // TightVNC-specific
+ public static final int pseudoEncodingLastRect = -224;
+ public static final int pseudoEncodingQualityLevel0 = -32;
+ public static final int pseudoEncodingQualityLevel9 = -23;
+ public static final int pseudoEncodingCompressLevel0 = -256;
+ public static final int pseudoEncodingCompressLevel9 = -247;
+
+ public static int encodingNum(String name) {
+ if (name.equalsIgnoreCase("raw")) return encodingRaw;
+ if (name.equalsIgnoreCase("copyRect")) return encodingCopyRect;
+ if (name.equalsIgnoreCase("RRE")) return encodingRRE;
+ if (name.equalsIgnoreCase("coRRE")) return encodingCoRRE;
+ if (name.equalsIgnoreCase("hextile")) return encodingHextile;
+ if (name.equalsIgnoreCase("Tight")) return encodingTight;
+ if (name.equalsIgnoreCase("ZRLE")) return encodingZRLE;
+ return -1;
+ }
+
+ public static String encodingName(int num) {
+ switch (num) {
+ case encodingRaw: return "raw";
+ case encodingCopyRect: return "copyRect";
+ case encodingRRE: return "RRE";
+ case encodingCoRRE: return "CoRRE";
+ case encodingHextile: return "hextile";
+ case encodingTight: return "Tight";
+ case encodingZRLE: return "ZRLE";
+ default: return "[unknown encoding]";
+ }
+ }
+}
diff --git a/java/com/tigervnc/rfb/Exception.java b/java/com/tigervnc/rfb/Exception.java
new file mode 100644
index 00000000..26ac355b
--- /dev/null
+++ b/java/com/tigervnc/rfb/Exception.java
@@ -0,0 +1,23 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 Exception extends com.tigervnc.rdr.Exception {
+ public Exception(String s) { super(s); }
+}
diff --git a/java/com/tigervnc/rfb/Hextile.java b/java/com/tigervnc/rfb/Hextile.java
new file mode 100644
index 00000000..9c05b729
--- /dev/null
+++ b/java/com/tigervnc/rfb/Hextile.java
@@ -0,0 +1,27 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 Hextile {
+ public static final int raw = (1 << 0);
+ public static final int bgSpecified = (1 << 1);
+ public static final int fgSpecified = (1 << 2);
+ public static final int anySubrects = (1 << 3);
+ public static final int subrectsColoured = (1 << 4);
+}
diff --git a/java/com/tigervnc/rfb/HextileDecoder.java b/java/com/tigervnc/rfb/HextileDecoder.java
new file mode 100644
index 00000000..4c32b52c
--- /dev/null
+++ b/java/com/tigervnc/rfb/HextileDecoder.java
@@ -0,0 +1,101 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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;
+
+import com.tigervnc.rdr.*;
+
+public class HextileDecoder extends Decoder {
+
+ public HextileDecoder(CMsgReader reader_) { reader = reader_; }
+
+ public void readRect(Rect r, CMsgHandler handler) {
+ InStream is = reader.getInStream();
+ int bytesPerPixel = handler.cp.pf().bpp / 8;
+ boolean bigEndian = handler.cp.pf().bigEndian;
+
+ int[] buf = reader.getImageBuf(16 * 16 * 4);
+
+ Rect t = new Rect();
+ int bg = 0;
+ int fg = 0;
+
+ for (t.tl.y = r.tl.y; t.tl.y < r.br.y; t.tl.y += 16) {
+
+ t.br.y = Math.min(r.br.y, t.tl.y + 16);
+
+ for (t.tl.x = r.tl.x; t.tl.x < r.br.x; t.tl.x += 16) {
+
+ t.br.x = Math.min(r.br.x, t.tl.x + 16);
+
+ int tileType = is.readU8();
+
+ if ((tileType & Hextile.raw) != 0) {
+ is.readPixels(buf, t.area(), bytesPerPixel, bigEndian);
+ handler.imageRect(t, buf);
+ continue;
+ }
+
+ if ((tileType & Hextile.bgSpecified) != 0)
+ bg = is.readPixel(bytesPerPixel, bigEndian);
+
+ int len = t.area();
+ int ptr = 0;
+ while (len-- > 0) buf[ptr++] = bg;
+
+ if ((tileType & Hextile.fgSpecified) != 0)
+ fg = is.readPixel(bytesPerPixel, bigEndian);
+
+ if ((tileType & Hextile.anySubrects) != 0) {
+ int nSubrects = is.readU8();
+
+ for (int i = 0; i < nSubrects; i++) {
+
+ if ((tileType & Hextile.subrectsColoured) != 0)
+ fg = is.readPixel(bytesPerPixel, bigEndian);
+
+ int xy = is.readU8();
+ int wh = is.readU8();
+
+/*
+ Rect s = new Rect();
+ s.tl.x = t.tl.x + ((xy >> 4) & 15);
+ s.tl.y = t.tl.y + (xy & 15);
+ s.br.x = s.tl.x + ((wh >> 4) & 15) + 1;
+ s.br.y = s.tl.y + (wh & 15) + 1;
+*/
+ int x = ((xy >> 4) & 15);
+ int y = (xy & 15);
+ int w = ((wh >> 4) & 15) + 1;
+ int h = (wh & 15) + 1;
+ ptr = y * t.width() + x;
+ int rowAdd = t.width() - w;
+ while (h-- > 0) {
+ len = w;
+ while (len-- > 0) buf[ptr++] = fg;
+ ptr += rowAdd;
+ }
+ }
+ }
+ handler.imageRect(t, buf);
+ }
+ }
+ }
+
+ CMsgReader reader;
+}
diff --git a/java/com/tigervnc/rfb/Hostname.java b/java/com/tigervnc/rfb/Hostname.java
new file mode 100644
index 00000000..42fda537
--- /dev/null
+++ b/java/com/tigervnc/rfb/Hostname.java
@@ -0,0 +1,41 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 Hostname {
+
+ public static String getHost(String vncServerName) {
+ int colonPos = vncServerName.indexOf(':');
+ if (colonPos == 0)
+ return "localhost";
+ if (colonPos == -1)
+ colonPos = vncServerName.length();
+ return vncServerName.substring(0, colonPos);
+ }
+
+ public static int getPort(String vncServerName) {
+ int colonPos = vncServerName.indexOf(':');
+ if (colonPos == -1 || colonPos == vncServerName.length()-1)
+ return 5900;
+ if (vncServerName.charAt(colonPos+1) == ':') {
+ return Integer.parseInt(vncServerName.substring(colonPos+2));
+ }
+ return Integer.parseInt(vncServerName.substring(colonPos+1)) + 5900;
+ }
+}
diff --git a/java/com/tigervnc/rfb/IntParameter.java b/java/com/tigervnc/rfb/IntParameter.java
new file mode 100644
index 00000000..877063e7
--- /dev/null
+++ b/java/com/tigervnc/rfb/IntParameter.java
@@ -0,0 +1,44 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 IntParameter extends VoidParameter {
+ public IntParameter(String name_, String desc_, int v) {
+ super(name_, desc_);
+ value = v;
+ defValue = v;
+ }
+
+ public boolean setParam(String v) {
+ try {
+ value = Integer.parseInt(v);
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ return true;
+ }
+
+ public String getDefaultStr() { return Integer.toString(defValue); }
+ public String getValueStr() { return Integer.toString(value); }
+
+ public int getValue() { return value; }
+
+ protected int value;
+ protected int defValue;
+}
diff --git a/java/com/tigervnc/rfb/Keysyms.java b/java/com/tigervnc/rfb/Keysyms.java
new file mode 100644
index 00000000..6bfafeaf
--- /dev/null
+++ b/java/com/tigervnc/rfb/Keysyms.java
@@ -0,0 +1,88 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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.
+ */
+
+//
+// Keysyms - defines X keysyms for non-character keys. All keysyms
+// corresponding to characters should be generated by calling
+// UnicodeToKeysym.translate().
+//
+
+package com.tigervnc.rfb;
+
+public class Keysyms {
+
+ public static final int BackSpace = 0xFF08;
+ public static final int Tab = 0xFF09;
+ public static final int Linefeed = 0xFF0A;
+ public static final int Clear = 0xFF0B;
+ public static final int Return = 0xFF0D;
+ public static final int Pause = 0xFF13;
+ public static final int Scroll_Lock = 0xFF14;
+ public static final int Sys_Req = 0xFF15;
+ public static final int Escape = 0xFF1B;
+ public static final int Delete = 0xFFFF;
+
+ public static final int Home = 0xFF50;
+ public static final int Left = 0xFF51;
+ public static final int Up = 0xFF52;
+ public static final int Right = 0xFF53;
+ public static final int Down = 0xFF54;
+ public static final int Prior = 0xFF55;
+ public static final int Page_Up = 0xFF55;
+ public static final int Next = 0xFF56;
+ public static final int Page_Down = 0xFF56;
+ public static final int End = 0xFF57;
+ public static final int Begin = 0xFF58;
+
+ public static final int Select = 0xFF60;
+ public static final int Print = 0xFF61;
+ public static final int Execute = 0xFF62;
+ public static final int Insert = 0xFF63;
+ public static final int Undo = 0xFF65;
+ public static final int Redo = 0xFF66;
+ public static final int Menu = 0xFF67;
+ public static final int Find = 0xFF68;
+ public static final int Cancel = 0xFF69;
+ public static final int Help = 0xFF6A;
+ public static final int Break = 0xFF6B;
+ public static final int Mode_switch = 0xFF7E;
+ public static final int script_switch = 0xFF7E;
+ public static final int Num_Lock = 0xFF7F;
+
+ public static final int F1 = 0xFFBE;
+ public static final int F2 = 0xFFBF;
+ public static final int F3 = 0xFFC0;
+ public static final int F4 = 0xFFC1;
+ public static final int F5 = 0xFFC2;
+ public static final int F6 = 0xFFC3;
+ public static final int F7 = 0xFFC4;
+ public static final int F8 = 0xFFC5;
+ public static final int F9 = 0xFFC6;
+ public static final int F10 = 0xFFC7;
+ public static final int F11 = 0xFFC8;
+ public static final int F12 = 0xFFC9;
+
+ public static final int Shift_L = 0xFFE1;
+ public static final int Shift_R = 0xFFE2;
+ public static final int Control_L = 0xFFE3;
+ public static final int Control_R = 0xFFE4;
+ public static final int Meta_L = 0xFFE7;
+ public static final int Meta_R = 0xFFE8;
+ public static final int Alt_L = 0xFFE9;
+ public static final int Alt_R = 0xFFEA;
+}
diff --git a/java/com/tigervnc/rfb/LogWriter.java b/java/com/tigervnc/rfb/LogWriter.java
new file mode 100644
index 00000000..c5730531
--- /dev/null
+++ b/java/com/tigervnc/rfb/LogWriter.java
@@ -0,0 +1,99 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 LogWriter {
+
+ public LogWriter(String name_) {
+ name = name_;
+ level = globalLogLevel;
+ next = log_writers;
+ log_writers = this;
+ }
+
+ public void setLevel(int level_) { level = level_; }
+
+ public void write(int level, String str) {
+ if (level <= this.level) {
+ System.err.println(name+": "+str);
+ }
+ }
+
+ public void error(String str) { write(0, str); }
+ public void status(String str) { write(10, str); }
+ public void info(String str) { write(30, str); }
+ public void debug(String str) { write(100, str); }
+
+ public static boolean setLogParams(String params) {
+ globalLogLevel = Integer.parseInt(params);
+ LogWriter current = log_writers;
+ while (current != null) {
+ current.setLevel(globalLogLevel);
+ current = current.next;
+ }
+ return true;
+// int colon = params.indexOf(':');
+// String logwriter_name = params.substring(0, colon);
+// params = params.substring(colon+1);
+// colon = params.indexOf(':');
+// String logger_name = params.substring(0, colon);
+// params = params.substring(colon+1);
+// int level = Integer.parseInt(params);
+// // XXX ignore logger name for the moment
+
+// System.err.println("setting level to "+level);
+// System.err.println("logwriters is "+log_writers);
+// if (logwriter_name.equals("*")) {
+// LogWriter current = log_writers;
+// while (current != null) {
+// //current.setLog(logger);
+// System.err.println("setting level of "+current.name+" to "+level);
+// current.setLevel(level);
+// current = current.next;
+// }
+// return true;
+// }
+
+// LogWriter logwriter = getLogWriter(logwriter_name);
+// if (logwriter == null) {
+// System.err.println("no logwriter found: "+logwriter_name);
+// return false;
+// }
+
+// //logwriter.setLog(logger);
+// logwriter.setLevel(level);
+// return true;
+ }
+
+
+ static LogWriter getLogWriter(String name) {
+ LogWriter current = log_writers;
+ while (current != null) {
+ if (name.equalsIgnoreCase(current.name)) return current;
+ current = current.next;
+ }
+ return null;
+ }
+
+ String name;
+ int level;
+ LogWriter next;
+ static LogWriter log_writers;
+ static int globalLogLevel = 30;
+}
diff --git a/java/com/tigervnc/rfb/ManagedPixelBuffer.java b/java/com/tigervnc/rfb/ManagedPixelBuffer.java
new file mode 100644
index 00000000..46b5acf7
--- /dev/null
+++ b/java/com/tigervnc/rfb/ManagedPixelBuffer.java
@@ -0,0 +1,38 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 ManagedPixelBuffer extends PixelBuffer {
+ public void setSize(int w, int h) {
+ width_ = w;
+ height_ = h;
+ checkDataSize();
+ }
+ public void setPF(PixelFormat pf) {
+ super.setPF(pf);
+ checkDataSize();
+ }
+
+ public int dataLen() { return area(); }
+
+ final void checkDataSize() {
+ if (data == null || data.length < dataLen())
+ data = new int[dataLen()];
+ }
+}
diff --git a/java/com/tigervnc/rfb/MsgTypes.java b/java/com/tigervnc/rfb/MsgTypes.java
new file mode 100644
index 00000000..a009b396
--- /dev/null
+++ b/java/com/tigervnc/rfb/MsgTypes.java
@@ -0,0 +1,40 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 MsgTypes {
+ // server to client
+
+ public static final int msgTypeFramebufferUpdate = 0;
+ public static final int msgTypeSetColourMapEntries = 1;
+ public static final int msgTypeBell = 2;
+ public static final int msgTypeServerCutText = 3;
+
+ // client to server
+
+ public static final int msgTypeSetPixelFormat = 0;
+ public static final int msgTypeFixColourMapEntries = 1;
+ public static final int msgTypeSetEncodings = 2;
+ public static final int msgTypeFramebufferUpdateRequest = 3;
+ public static final int msgTypeKeyEvent = 4;
+ public static final int msgTypePointerEvent = 5;
+ public static final int msgTypeClientCutText = 6;
+
+ public static final int msgTypeSetDesktopSize = 251;
+}
diff --git a/java/com/tigervnc/rfb/PixelBuffer.java b/java/com/tigervnc/rfb/PixelBuffer.java
new file mode 100644
index 00000000..f87fead8
--- /dev/null
+++ b/java/com/tigervnc/rfb/PixelBuffer.java
@@ -0,0 +1,116 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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.
+ */
+
+//
+// PixelBuffer - note that this code is only written for the 8, 16, and 32 bpp cases at the
+// moment.
+//
+
+package com.tigervnc.rfb;
+
+import java.awt.image.*;
+
+public class PixelBuffer {
+
+ public PixelBuffer() {
+ setPF(new PixelFormat());
+ }
+
+ public void setPF(PixelFormat pf) {
+ if (!(pf.bpp == 32) && !(pf.bpp == 16) && !(pf.bpp == 8))
+ throw new Exception("Internal error: bpp must be 8, 16, or 32 in PixelBuffer ("+pf.bpp+")");
+ format = pf;
+ switch (pf.depth) {
+ 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));
+ break;
+ case 16:
+ cm = new DirectColorModel(32, 0xF800, 0x07C0, 0x003E, (0xff << 24));
+ break;
+ case 24:
+ cm = new DirectColorModel(32, (0xff << 16), (0xff << 8), 0xff, (0xff << 24));
+ break;
+ }
+ }
+ public PixelFormat getPF() { return format; }
+
+ public final int width() { return width_; }
+ public final int height() { return height_; }
+ public final int area() { return width_ * height_; }
+
+ public void fillRect(int x, int y, int w, int h, int pix) {
+ for (int ry = y; ry < y + h; ry++)
+ for (int rx = x; rx < x + w; rx++)
+ data[ry * width_ + rx] = pix;
+ }
+
+ public void imageRect(int x, int y, int w, int h, int[] pix) {
+ for (int j = 0; j < h; j++)
+ System.arraycopy(pix, (w * j), data, width_ * (y + j) + x, w);
+ }
+
+ public void copyRect(int x, int y, int w, int h, int srcX, int srcY) {
+ int dest = (width_ * y) + x;
+ int src = (width_ * srcY) + srcX;
+ int inc = width_;
+
+ if (y > srcY) {
+ src += (h-1) * inc;
+ dest += (h-1) * inc;
+ inc = -inc;
+ }
+ int destEnd = dest + h * inc;
+
+ while (dest != destEnd) {
+ System.arraycopy(data, src, data, dest, w);
+ src += inc;
+ dest += inc;
+ }
+ }
+
+ public void maskRect(int x, int y, int w, int h, int[] pix, byte[] mask) {
+ int maskBytesPerRow = (w + 7) / 8;
+
+ for (int j = 0; j < h; j++) {
+ int cy = y + j;
+
+ if (cy < 0 || cy >= height_)
+ continue;
+
+ for (int i = 0; i < w; i++) {
+ int cx = x + i;
+
+ if (cx < 0 || cx >= width_)
+ continue;
+
+ int byte_ = j * maskBytesPerRow + i / 8;
+ int bit = 7 - i % 8;
+
+ if ((mask[byte_] & (1 << bit)) != 0)
+ data[cy * width_ + cx] = pix[j * w + i];
+ }
+ }
+ }
+
+ public int[] data;
+ public ColorModel cm;
+
+ protected PixelFormat format;
+ protected int width_, height_;
+}
diff --git a/java/com/tigervnc/rfb/PixelFormat.java b/java/com/tigervnc/rfb/PixelFormat.java
new file mode 100644
index 00000000..a8ab5f11
--- /dev/null
+++ b/java/com/tigervnc/rfb/PixelFormat.java
@@ -0,0 +1,163 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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.
+ */
+
+//
+// PixelFormat
+//
+
+package com.tigervnc.rfb;
+
+import com.tigervnc.rdr.*;
+
+public class PixelFormat {
+
+ public PixelFormat(int b, int d, boolean e, boolean t) {
+ bpp = b;
+ depth = d;
+ bigEndian = e;
+ trueColour = t;
+ }
+ public PixelFormat(int b, int d, boolean e, boolean t,
+ int rm, int gm, int bm, int rs, int gs, int bs) {
+ this(b, d, e, t);
+ redMax = rm;
+ greenMax = gm;
+ blueMax = bm;
+ redShift = rs;
+ greenShift = gs;
+ blueShift = bs;
+ }
+ public PixelFormat() { this(8,8,false,true,7,7,3,0,3,6); }
+
+ public boolean equal(PixelFormat x) {
+ return (bpp == x.bpp &&
+ depth == x.depth &&
+ (bigEndian == x.bigEndian || bpp == 8) &&
+ trueColour == x.trueColour &&
+ (!trueColour || (redMax == x.redMax &&
+ greenMax == x.greenMax &&
+ blueMax == x.blueMax &&
+ redShift == x.redShift &&
+ greenShift == x.greenShift &&
+ blueShift == x.blueShift)));
+ }
+
+ public void read(InStream is) {
+ bpp = is.readU8();
+ depth = is.readU8();
+ bigEndian = is.readU8()!=0;
+ trueColour = is.readU8()!=0;
+ redMax = is.readU16();
+ greenMax = is.readU16();
+ blueMax = is.readU16();
+ redShift = is.readU8();
+ greenShift = is.readU8();
+ blueShift = is.readU8();
+ is.skip(3);
+ }
+
+ public void write(OutStream os) {
+ os.writeU8(bpp);
+ os.writeU8(depth);
+ os.writeU8(bigEndian?1:0);
+ os.writeU8(trueColour?1:0);
+ os.writeU16(redMax);
+ os.writeU16(greenMax);
+ os.writeU16(blueMax);
+ os.writeU8(redShift);
+ os.writeU8(greenShift);
+ os.writeU8(blueShift);
+ os.pad(3);
+ }
+
+ public final boolean is888() {
+ if(!trueColour)
+ return false;
+ if(bpp != 32)
+ return false;
+ if(depth != 24)
+ return false;
+ if(redMax != 255)
+ return false;
+ if(greenMax != 255)
+ return false;
+ if(blueMax != 255)
+ return false;
+
+ return true;
+ }
+
+ public void bufferFromRGB(int dst, byte[] src) {
+ if (bigEndian) {
+ dst =
+ (src[0] & 0xFF) << 16 | (src[1] & 0xFF) << 8 | (src[2] & 0xFF) | 0xFF << 24;
+ } else {
+ dst =
+ (src[2] & 0xFF) << 16 | (src[1] & 0xFF) << 8 | (src[0] & 0xFF) | 0xFF << 24;
+ }
+ }
+
+ public String print() {
+ StringBuffer s = new StringBuffer();
+ s.append("depth "+depth+" ("+bpp+"bpp)");
+ if (bpp != 8) {
+ if (bigEndian)
+ s.append(" big-endian");
+ else
+ s.append(" little-endian");
+ }
+
+ if (!trueColour) {
+ s.append(" colour-map");
+ return s.toString();
+ }
+
+ if (blueShift == 0 && greenShift > blueShift && redShift > greenShift &&
+ blueMax == (1 << greenShift) - 1 &&
+ greenMax == (1 << (redShift-greenShift)) - 1 &&
+ redMax == (1 << (depth-redShift)) - 1)
+ {
+ s.append(" rgb"+(depth-redShift)+(redShift-greenShift)+greenShift);
+ return s.toString();
+ }
+
+ if (redShift == 0 && greenShift > redShift && blueShift > greenShift &&
+ redMax == (1 << greenShift) - 1 &&
+ greenMax == (1 << (blueShift-greenShift)) - 1 &&
+ blueMax == (1 << (depth-blueShift)) - 1)
+ {
+ s.append(" bgr"+(depth-blueShift)+(blueShift-greenShift)+greenShift);
+ return s.toString();
+ }
+
+ s.append(" rgb max "+redMax+","+greenMax+","+blueMax+" shift "+redShift+
+ ","+greenShift+","+blueShift);
+ return s.toString();
+ }
+
+ public int bpp;
+ public int depth;
+ public boolean bigEndian;
+ public boolean trueColour;
+ public int redMax;
+ public int greenMax;
+ public int blueMax;
+ public int redShift;
+ public int greenShift;
+ public int blueShift;
+}
diff --git a/java/com/tigervnc/rfb/Point.java b/java/com/tigervnc/rfb/Point.java
new file mode 100644
index 00000000..25de8c20
--- /dev/null
+++ b/java/com/tigervnc/rfb/Point.java
@@ -0,0 +1,40 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 Point {
+
+ // Point
+ //
+ // Represents a point in 2D space, by X and Y coordinates.
+ // Can also be used to represent a delta, or offset, between
+ // two Points.
+ // Functions are provided to allow Points to be compared for
+ // equality and translated by a supplied offset.
+ // Functions are also provided to negate offset Points.
+
+ public Point() {x=0; y=0;}
+ public Point(int x_, int y_) { x=x_; y=y_;}
+ public final Point negate() {return new Point(-x, -y);}
+ public final boolean equals(Point p) {return (x==p.x && y==p.y);}
+ public final Point translate(Point p) {return new Point(x+p.x, y+p.y);}
+ public final Point subtract(Point p) {return new Point(x-p.x, y-p.y);}
+ public int x, y;
+
+}
diff --git a/java/com/tigervnc/rfb/RREDecoder.java b/java/com/tigervnc/rfb/RREDecoder.java
new file mode 100644
index 00000000..e0ff5cfe
--- /dev/null
+++ b/java/com/tigervnc/rfb/RREDecoder.java
@@ -0,0 +1,46 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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;
+
+import com.tigervnc.rdr.*;
+
+public class RREDecoder extends Decoder {
+
+ public RREDecoder(CMsgReader reader_) { reader = reader_; }
+
+ public void readRect(Rect r, CMsgHandler handler) {
+ InStream is = reader.getInStream();
+ int bytesPerPixel = handler.cp.pf().bpp / 8;
+ boolean bigEndian = handler.cp.pf().bigEndian;
+ int nSubrects = is.readU32();
+ int bg = is.readPixel(bytesPerPixel, bigEndian);
+ handler.fillRect(r, bg);
+
+ for (int i = 0; i < nSubrects; i++) {
+ int pix = is.readPixel(bytesPerPixel, bigEndian);
+ int x = is.readU16();
+ int y = is.readU16();
+ int w = is.readU16();
+ int h = is.readU16();
+ handler.fillRect(new Rect(r.tl.x+x, r.tl.y+y, r.tl.x+x+w, r.tl.y+y+h), pix);
+ }
+ }
+
+ CMsgReader reader;
+}
diff --git a/java/com/tigervnc/rfb/RawDecoder.java b/java/com/tigervnc/rfb/RawDecoder.java
new file mode 100644
index 00000000..79db8260
--- /dev/null
+++ b/java/com/tigervnc/rfb/RawDecoder.java
@@ -0,0 +1,45 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 RawDecoder extends Decoder {
+
+ public RawDecoder(CMsgReader reader_) { reader = reader_; }
+
+ public void readRect(Rect r, CMsgHandler handler) {
+ int x = r.tl.x;
+ int y = r.tl.y;
+ int w = r.width();
+ int h = r.height();
+ int[] imageBuf = reader.getImageBuf(w * h);
+ int nPixels = imageBuf.length / (reader.bpp() / 8);
+ int bytesPerRow = w * (reader.bpp() / 8);
+ while (h > 0) {
+ int nRows = nPixels / w;
+ if (nRows > h) nRows = h;
+ reader.is.readPixels(imageBuf, w * h, (reader.bpp() / 8), handler.cp.pf().bigEndian);
+ handler.imageRect(new Rect(x, y, x+w, y+nRows), imageBuf);
+ h -= nRows;
+ y += nRows;
+ }
+ }
+
+ CMsgReader reader;
+ static LogWriter vlog = new LogWriter("RawDecoder");
+}
diff --git a/java/com/tigervnc/rfb/Rect.java b/java/com/tigervnc/rfb/Rect.java
new file mode 100644
index 00000000..fab4f5dd
--- /dev/null
+++ b/java/com/tigervnc/rfb/Rect.java
@@ -0,0 +1,89 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 Rect {
+
+ // Rect
+ //
+ // Represents a rectangular region defined by its top-left (tl)
+ // and bottom-right (br) Points.
+ // Rects may be compared for equality, checked to determine whether
+ // or not they are empty, cleared (made empty), or intersected with
+ // one another. The bounding rectangle of two existing Rects
+ // may be calculated, as may the area of a Rect.
+ // Rects may also be translated, in the same way as Points, by
+ // an offset specified in a Point structure.
+
+ public Rect() {
+ tl=new Point(0,0);
+ br=new Point(0,0);
+ }
+ public Rect(Point tl_, Point br_) {
+ tl=new Point(tl_.x, tl_.y);
+ br=new Point(br_.x,br_.y);
+ }
+ public Rect(int x1, int y1, int x2, int y2) {
+ tl=new Point(x1, y1);
+ br=new Point(x2, y2);
+ }
+ public final void setXYWH(int x, int y, int w, int h) {
+ tl.x = x; tl.y = y; br.x = x+w; br.y = y+h;
+ }
+ public final Rect intersect(Rect r) {
+ Rect result = new Rect();
+ result.tl.x = Math.max(tl.x, r.tl.x);
+ result.tl.y = Math.max(tl.y, r.tl.y);
+ result.br.x = Math.max(Math.min(br.x, r.br.x), result.tl.x);
+ result.br.y = Math.max(Math.min(br.y, r.br.y), result.tl.y);
+ return result;
+ }
+ public final Rect union_boundary(Rect r) {
+ if (r.is_empty()) return this;
+ if (is_empty()) return r;
+ Rect result = new Rect();
+ result.tl.x = Math.min(tl.x, r.tl.x);
+ result.tl.y = Math.min(tl.y, r.tl.y);
+ result.br.x = Math.max(br.x, r.br.x);
+ result.br.y = Math.max(br.y, r.br.y);
+ return result;
+ }
+ public final Rect translate(Point p) {
+ return new Rect(tl.translate(p), br.translate(p));
+ }
+ public final boolean equals(Rect r) {return r.tl.equals(tl) && r.br.equals(br);}
+ public final boolean is_empty() {return (tl.x >= br.x) || (tl.y >= br.y);}
+ public final void clear() {tl = new Point(); br = new Point();}
+ public final boolean enclosed_by(Rect r) {
+ return (tl.x>=r.tl.x) && (tl.y>=r.tl.y) && (br.x<=r.br.x) && (br.y<=r.br.y);
+ }
+ public final boolean overlaps(Rect r) {
+ return tl.x < r.br.x && tl.y < r.br.y && br.x > r.tl.x && br.y > r.tl.y;
+ }
+ public final int area() {return is_empty() ? 0 : (br.x-tl.x)*(br.y-tl.y);}
+ public final Point dimensions() {return new Point(width(), height());}
+ public final int width() {return br.x-tl.x;}
+ public final int height() {return br.y-tl.y;}
+ public final boolean contains(Point p) {
+ return (tl.x<=p.x) && (tl.y<=p.y) && (br.x>p.x) && (br.y>p.y);
+ }
+ public Point tl;
+ public Point br;
+
+}
diff --git a/java/com/tigervnc/rfb/Screen.java b/java/com/tigervnc/rfb/Screen.java
new file mode 100644
index 00000000..90b22b6d
--- /dev/null
+++ b/java/com/tigervnc/rfb/Screen.java
@@ -0,0 +1,48 @@
+/* Copyright 2009 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.
+ */
+
+// Represents a single RFB virtual screen, which includes
+// coordinates, an id and flags.
+
+package com.tigervnc.rfb;
+
+public class Screen {
+
+ public Screen() { id=0; flags=0; dimensions = new Rect(); }
+
+ public Screen(int id_, int x_, int y_, int w_, int h_, int flags_) {
+ id = id_;
+ dimensions = new Rect(x_, y_, x_+w_, y_+h_);
+ flags = flags_;
+ }
+
+ public final static boolean operator(Screen r) {
+ if (id != r.id)
+ return false;
+ if (!dimensions.equals(r.dimensions))
+ return false;
+ if (flags != r.flags)
+ return false;
+ return true;
+ }
+
+ public static int id;
+ public static Rect dimensions;
+ public static int flags;
+
+}
diff --git a/java/com/tigervnc/rfb/ScreenSet.java b/java/com/tigervnc/rfb/ScreenSet.java
new file mode 100644
index 00000000..071282ff
--- /dev/null
+++ b/java/com/tigervnc/rfb/ScreenSet.java
@@ -0,0 +1,89 @@
+/* Copyright 2009 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.
+ */
+
+// Management class for the RFB virtual screens
+
+package com.tigervnc.rfb;
+
+import java.util.*;
+
+public class ScreenSet {
+
+ // Represents a complete screen configuration, excluding framebuffer
+ // dimensions.
+
+ public ScreenSet() {
+ screens = new ArrayList<Screen>();
+ }
+
+ public static final int num_screens() { return screens.size(); }
+
+ public static final void add_screen(Screen screen) { screens.add(screen); }
+ public static final void remove_screen(int id) {
+ for (Iterator iter = screens.iterator(); iter.hasNext(); ) {
+ Screen refScreen = (Screen)iter.next();
+ if (refScreen.id == id)
+ iter.remove();
+ }
+ }
+
+ public static final boolean validate(int fb_width, int fb_height) {
+ List<Integer> seen_ids = new ArrayList<Integer>();
+ Rect fb_rect = new Rect();
+
+ if (screens.isEmpty())
+ return false;
+ if (num_screens() > 255)
+ return false;
+
+ fb_rect.setXYWH(0, 0, fb_width, fb_height);
+
+ for (Iterator iter = screens.iterator(); iter.hasNext(); ) {
+ Screen refScreen = (Screen)iter.next();
+ if (refScreen.dimensions.is_empty())
+ return false;
+ if (!refScreen.dimensions.enclosed_by(fb_rect))
+ return false;
+ //if (seen_ids.lastIndexOf(refScreen.id) != seen_ids.get(-1))
+ // return false;
+ seen_ids.add(refScreen.id);
+ }
+
+ return true;
+ }
+
+ public final void debug_print() {
+ for (Iterator iter = screens.iterator(); iter.hasNext(); ) {
+ Screen refScreen = (Screen)iter.next();
+ vlog.error(" "+refScreen.id+" (0x"+refScreen.id+"): "+
+ refScreen.dimensions.width()+"x"+refScreen.dimensions.height()+
+ "+"+refScreen.dimensions.tl.x+"+"+refScreen.dimensions.tl.y+
+ " (flags 0x"+refScreen.flags+")");
+ }
+ }
+
+ // FIXME: List order shouldn't matter
+ //inline bool operator(const ScreenSet& r) const { return screens == r.screens; }
+ //inline bool operator(const ScreenSet& r) const { return screens != r.screens; }
+
+ public static List<Screen> screens;
+
+ static LogWriter vlog = new LogWriter("ScreenSet");
+
+}
+
diff --git a/java/com/tigervnc/rfb/Security.java b/java/com/tigervnc/rfb/Security.java
new file mode 100644
index 00000000..379851d8
--- /dev/null
+++ b/java/com/tigervnc/rfb/Security.java
@@ -0,0 +1,195 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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.
+ */
+
+//
+// SecTypes.java - constants for the various security types.
+//
+
+package com.tigervnc.rfb;
+import java.util.*;
+
+public class Security {
+
+ public static final int secTypeInvalid = 0;
+ public static final int secTypeNone = 1;
+ public static final int secTypeVncAuth = 2;
+
+ public static final int secTypeRA2 = 5;
+ public static final int secTypeRA2ne = 6;
+
+ public static final int secTypeSSPI = 7;
+ public static final int secTypeSSPIne = 8;
+
+ public static final int secTypeTight = 16;
+ public static final int secTypeUltra = 17;
+ public static final int secTypeTLS = 18;
+ public static final int secTypeVeNCrypt = 19;
+
+ /* VeNCrypt subtypes */
+ public static final int secTypePlain = 256;
+ public static final int secTypeTLSNone = 257;
+ public static final int secTypeTLSVnc = 258;
+ public static final int secTypeTLSPlain = 259;
+ public static final int secTypeX509None = 260;
+ public static final int secTypeX509Vnc = 261;
+ public static final int secTypeX509Plain = 262;
+ public static final int secTypeIdent = 265;
+ public static final int secTypeTLSIdent = 266;
+ public static final int secTypeX509Ident = 267;
+
+ // result types
+
+ public static final int secResultOK = 0;
+ public static final int secResultFailed = 1;
+ public static final int secResultTooMany = 2; // deprecated
+
+ public Security(StringParameter secTypes)
+ {
+ String secTypesStr;
+
+ secTypesStr = secTypes.getData();
+ enabledSecTypes = parseSecTypes(secTypesStr);
+
+ secTypesStr = null;
+ }
+
+ public static List<Integer> enabledSecTypes = new ArrayList<Integer>();
+
+ public static final List<Integer> GetEnabledSecTypes()
+ {
+ List<Integer> result = new ArrayList<Integer>();
+
+ result.add(secTypeVeNCrypt);
+ for (Iterator i = enabledSecTypes.iterator(); i.hasNext(); ) {
+ int refType = (Integer)i.next();
+ if (refType < 0x100)
+ result.add(refType);
+ }
+
+ return (result);
+ }
+
+ public static final List<Integer> GetEnabledExtSecTypes()
+ {
+ List<Integer> result = new ArrayList<Integer>();
+
+ for (Iterator i = enabledSecTypes.iterator(); i.hasNext(); ) {
+ int refType = (Integer)i.next();
+ if (refType != secTypeVeNCrypt) /* Do not include VeNCrypt to avoid loops */
+ result.add(refType);
+ }
+
+ return (result);
+ }
+
+ public static final void EnableSecType(int secType)
+ {
+
+ for (Iterator i = enabledSecTypes.iterator(); i.hasNext(); )
+ if ((Integer)i.next() == secType)
+ return;
+
+ enabledSecTypes.add(secType);
+ }
+
+ public boolean IsSupported(int secType)
+ {
+ Iterator i;
+
+ for (i = enabledSecTypes.iterator(); i.hasNext(); )
+ if ((Integer)i.next() == secType)
+ return true;
+ if (secType == secTypeVeNCrypt)
+ return true;
+
+ return false;
+ }
+
+ public static void DisableSecType(int secType) { enabledSecTypes.remove((Object)secType); }
+
+ public static int secTypeNum(String name) {
+ if (name.equalsIgnoreCase("None")) return secTypeNone;
+ if (name.equalsIgnoreCase("VncAuth")) return secTypeVncAuth;
+ if (name.equalsIgnoreCase("Tight")) return secTypeTight;
+ if (name.equalsIgnoreCase("RA2")) return secTypeRA2;
+ if (name.equalsIgnoreCase("RA2ne")) return secTypeRA2ne;
+ if (name.equalsIgnoreCase("SSPI")) return secTypeSSPI;
+ if (name.equalsIgnoreCase("SSPIne")) return secTypeSSPIne;
+ //if (name.equalsIgnoreCase("ultra")) return secTypeUltra;
+ //if (name.equalsIgnoreCase("TLS")) return secTypeTLS;
+ if (name.equalsIgnoreCase("VeNCrypt")) return secTypeVeNCrypt;
+
+ /* VeNCrypt subtypes */
+ if (name.equalsIgnoreCase("Plain")) return secTypePlain;
+ if (name.equalsIgnoreCase("Ident")) return secTypeIdent;
+ if (name.equalsIgnoreCase("TLSNone")) return secTypeTLSNone;
+ if (name.equalsIgnoreCase("TLSVnc")) return secTypeTLSVnc;
+ if (name.equalsIgnoreCase("TLSPlain")) return secTypeTLSPlain;
+ if (name.equalsIgnoreCase("TLSIdent")) return secTypeTLSIdent;
+ if (name.equalsIgnoreCase("X509None")) return secTypeX509None;
+ if (name.equalsIgnoreCase("X509Vnc")) return secTypeX509Vnc;
+ if (name.equalsIgnoreCase("X509Plain")) return secTypeX509Plain;
+ if (name.equalsIgnoreCase("X509Ident")) return secTypeX509Ident;
+
+ return secTypeInvalid;
+ }
+
+ public static String secTypeName(int num) {
+ switch (num) {
+ case secTypeNone: return "None";
+ case secTypeVncAuth: return "VncAuth";
+ case secTypeTight: return "Tight";
+ case secTypeRA2: return "RA2";
+ case secTypeRA2ne: return "RA2ne";
+ case secTypeSSPI: return "SSPI";
+ case secTypeSSPIne: return "SSPIne";
+ //case secTypeUltra: return "Ultra";
+ //case secTypeTLS: return "TLS";
+ case secTypeVeNCrypt: return "VeNCrypt";
+
+ /* VeNCrypt subtypes */
+ case secTypePlain: return "Plain";
+ case secTypeIdent: return "Ident";
+ case secTypeTLSNone: return "TLSNone";
+ case secTypeTLSVnc: return "TLSVnc";
+ case secTypeTLSPlain: return "TLSPlain";
+ case secTypeTLSIdent: return "TLSIdent";
+ case secTypeX509None: return "X509None";
+ case secTypeX509Vnc: return "X509Vnc";
+ case secTypeX509Plain: return "X509Plain";
+ case secTypeX509Ident: return "X509Ident";
+ default: return "[unknown secType]";
+ }
+ }
+
+ public final static List<Integer> parseSecTypes(String types_)
+ {
+ List<Integer> result = new ArrayList<Integer>();
+ String[] types = types_.split(",");
+ for (int i = 0; i < types.length; i++) {
+ int typeNum = secTypeNum(types[i]);
+ if (typeNum != secTypeInvalid)
+ result.add(typeNum);
+ }
+ return (result);
+ }
+
+ public final void SetSecTypes(List<Integer> secTypes) { enabledSecTypes = secTypes; }
+
+ static LogWriter vlog = new LogWriter("Security");
+}
diff --git a/java/com/tigervnc/rfb/SecurityClient.java b/java/com/tigervnc/rfb/SecurityClient.java
new file mode 100644
index 00000000..a8abd9e1
--- /dev/null
+++ b/java/com/tigervnc/rfb/SecurityClient.java
@@ -0,0 +1,85 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright (C) 2010 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
+ * 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;
+
+import com.tigervnc.vncviewer.CConn;
+
+public class SecurityClient extends Security {
+
+ public SecurityClient() { super(secTypes); }
+
+ public CSecurity GetCSecurity(int secType)
+ {
+ assert (CConn.upg != null); /* (upg == null) means bug in the viewer */
+ assert (msg != null);
+
+ if (!IsSupported(secType))
+ throw new Exception("Security type not supported");
+
+ switch (secType) {
+ case Security.secTypeNone: return (new CSecurityNone());
+ case Security.secTypeVncAuth: return (new CSecurityVncAuth());
+ case Security.secTypeVeNCrypt: return (new CSecurityVeNCrypt(this));
+ case Security.secTypePlain: return (new CSecurityPlain());
+ case Security.secTypeIdent: return (new CSecurityIdent());
+ case Security.secTypeTLSNone:
+ return (new CSecurityStack(secTypeTLSNone, "TLS with no password",
+ new CSecurityTLS(true), null));
+ case Security.secTypeTLSVnc:
+ return (new CSecurityStack(secTypeTLSVnc, "TLS with VNCAuth",
+ new CSecurityTLS(true), new CSecurityVncAuth()));
+ case Security.secTypeTLSPlain:
+ return (new CSecurityStack(secTypeTLSPlain, "TLS with Username/Password",
+ new CSecurityTLS(true), new CSecurityPlain()));
+ case Security.secTypeTLSIdent:
+ return (new CSecurityStack(secTypeTLSIdent, "TLS with username only",
+ new CSecurityTLS(true), new CSecurityIdent()));
+ case Security.secTypeX509None:
+ return (new CSecurityStack(secTypeX509None, "X509 with no password",
+ new CSecurityTLS(false), null));
+ case Security.secTypeX509Vnc:
+ return (new CSecurityStack(secTypeX509Vnc, "X509 with VNCAuth",
+ new CSecurityTLS(false), new CSecurityVncAuth()));
+ case Security.secTypeX509Plain:
+ return (new CSecurityStack(secTypeX509Plain, "X509 with Username/Password",
+ new CSecurityTLS(false), new CSecurityPlain()));
+ case Security.secTypeX509Ident:
+ return (new CSecurityStack(secTypeX509Ident, "X509 with username only",
+ new CSecurityTLS(false), new CSecurityIdent()));
+ default:
+ throw new Exception("Security type not supported");
+ }
+
+ }
+
+ public static void setDefaults()
+ {
+ CSecurityTLS.setDefaults();
+ }
+
+ //UserPasswdGetter upg = null;
+ String msg = null;
+
+ static StringParameter secTypes
+ = new StringParameter("SecurityTypes",
+ "Specify which security scheme to use (None, VncAuth)",
+ "Ident,TLSIdent,X509Ident,X509Plain,TLSPlain,X509Vnc,TLSVnc,X509None,TLSNone,VncAuth,None");
+
+}
diff --git a/java/com/tigervnc/rfb/StringParameter.java b/java/com/tigervnc/rfb/StringParameter.java
new file mode 100644
index 00000000..d7fd1a51
--- /dev/null
+++ b/java/com/tigervnc/rfb/StringParameter.java
@@ -0,0 +1,46 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 StringParameter extends VoidParameter {
+ public StringParameter(String name_, String desc_, String v) {
+ super(name_, desc_);
+ value = v;
+ defValue = v;
+ }
+
+ public boolean setParam(String v) {
+ value = v;
+ return value != null;
+ }
+
+ public boolean setDefaultStr(String v) {
+ value = defValue = v;
+ return defValue != null;
+ }
+
+ public String getDefaultStr() { return defValue; }
+ public String getValueStr() { return value; }
+
+ public String getValue() { return value; }
+ public String getData() { return value; }
+
+ protected String value;
+ protected String defValue;
+}
diff --git a/java/com/tigervnc/rfb/TightDecoder.java b/java/com/tigervnc/rfb/TightDecoder.java
new file mode 100644
index 00000000..5cce3a93
--- /dev/null
+++ b/java/com/tigervnc/rfb/TightDecoder.java
@@ -0,0 +1,426 @@
+/* Copyright (C) 2000-2003 Constantin Kaplinsky. All Rights Reserved.
+ * Copyright 2004-2005 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;
+
+import com.tigervnc.rdr.InStream;
+import com.tigervnc.rdr.ZlibInStream;
+import java.awt.image.PixelGrabber;
+import java.awt.Image;
+import java.util.ArrayList;
+
+public class TightDecoder extends Decoder {
+
+ final static int TIGHT_MAX_WIDTH = 2048;
+
+ // Compression control
+ final static int rfbTightExplicitFilter = 0x04;
+ final static int rfbTightFill = 0x08;
+ final static int rfbTightJpeg = 0x09;
+ final static int rfbTightMaxSubencoding = 0x09;
+
+ // Filters to improve compression efficiency
+ final static int rfbTightFilterCopy = 0x00;
+ final static int rfbTightFilterPalette = 0x01;
+ final static int rfbTightFilterGradient = 0x02;
+ final static int rfbTightMinToCompress = 12;
+
+ public TightDecoder(CMsgReader reader_) {
+ reader = reader_;
+ zis = new ZlibInStream[4];
+ for (int i = 0; i < 4; i++)
+ zis[i] = new ZlibInStream();
+ }
+
+ public void readRect(Rect r, CMsgHandler handler)
+ {
+ InStream is = reader.getInStream();
+ int[] buf = reader.getImageBuf(r.width() * r.height());
+ boolean cutZeros = false;
+ PixelFormat myFormat = handler.cp.pf();
+ int bpp = handler.cp.pf().bpp;
+ if (bpp == 32) {
+ if (myFormat.is888()) {
+ cutZeros = true;
+ }
+ }
+
+ int comp_ctl = is.readU8();
+
+ int bytesPerPixel = handler.cp.pf().bpp / 8;
+ boolean bigEndian = handler.cp.pf().bigEndian;
+
+ // Flush zlib streams if we are told by the server to do so.
+ for (int i = 0; i < 4; i++) {
+ if ((comp_ctl & 1) != 0) {
+ zis[i].reset();
+ }
+ comp_ctl >>= 1;
+ }
+
+ // "Fill" compression type.
+ if (comp_ctl == rfbTightFill) {
+ int pix;
+ if (cutZeros) {
+ byte[] elem = new byte[3];
+ is.readBytes(elem, 0, 3);
+ if (bigEndian) {
+ pix =
+ (elem[2] & 0xFF) << 16 | (elem[1] & 0xFF) << 8 | (elem[0] & 0xFF) | 0xFF << 24;
+ } else {
+ pix =
+ (elem[0] & 0xFF) << 16 | (elem[1] & 0xFF) << 8 | (elem[2] & 0xFF) | 0xFF << 24;
+ }
+ } else {
+ pix = (bpp == 8) ? is.readOpaque8() : is.readOpaque24B();
+ }
+ handler.fillRect(r, pix);
+ return;
+ }
+
+ // "JPEG" compression type.
+ if (comp_ctl == rfbTightJpeg) {
+ // Read length
+ int compressedLen = is.readCompactLength();
+ if (compressedLen <= 0)
+ vlog.info("Incorrect data received from the server.");
+
+ // Allocate netbuf and read in data
+ byte[] netbuf = new byte[compressedLen];
+ is.readBytes(netbuf, 0, compressedLen);
+
+ // Create an Image object from the JPEG data.
+ Image jpeg = java.awt.Toolkit.getDefaultToolkit().createImage(netbuf);
+ PixelGrabber pg = new PixelGrabber(jpeg, 0, 0, r.width(), r.height(), true);
+ try {
+ boolean ret = pg.grabPixels();
+ if (!ret)
+ vlog.info("failed to grab pixels");
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ Object pixels = pg.getPixels();
+ buf = (pixels instanceof byte[]) ?
+ convertByteArrayToIntArray((byte[])pixels) : (int[])pixels;
+ handler.imageRect(r, buf);
+ return;
+ }
+
+ // Quit on unsupported compression type.
+ if (comp_ctl > rfbTightMaxSubencoding) {
+ throw new Exception("TightDecoder: bad subencoding value received");
+ }
+
+ // "Basic" compression type.
+ int palSize = 0;
+ int[] palette = new int[256];
+ boolean useGradient = false;
+
+ if ((comp_ctl & rfbTightExplicitFilter) != 0) {
+ int filterId = is.readU8();
+
+ switch (filterId) {
+ case rfbTightFilterPalette:
+ palSize = is.readU8() + 1;
+ if (cutZeros) {
+ byte[] elem = new byte[3];
+ for (int i = 0; i < palSize; i++) {
+ is.readBytes(elem, 0, 3);
+ if (bigEndian) {
+ palette[i] =
+ (elem[2] & 0xFF) << 16 | (elem[1] & 0xFF) << 8 | (elem[0] & 0xFF) | 0xFF << 24;
+ } else {
+ palette[i] =
+ (elem[0] & 0xFF) << 16 | (elem[1] & 0xFF) << 8 | (elem[2] & 0xFF) | 0xFF << 24;
+ }
+ }
+ } else {
+ for (int i = 0; i < palSize; i++) {
+ palette[i] = (bpp == 8) ? is.readOpaque8() : is.readOpaque24B();
+ }
+ }
+ break;
+ case rfbTightFilterGradient:
+ useGradient = true;
+ break;
+ case rfbTightFilterCopy:
+ break;
+ default:
+ throw new Exception("TightDecoder: unknown filter code recieved");
+ }
+ }
+
+ int bppp = bpp;
+ if (palSize != 0) {
+ bppp = (palSize <= 2) ? 1 : 8;
+ } else if (cutZeros) {
+ bppp = 24;
+ }
+
+ // Determine if the data should be decompressed or just copied.
+ int rowSize = (r.width() * bppp + 7) / 8;
+ int dataSize = r.height() * rowSize;
+ int streamId = -1;
+ InStream input;
+ if (dataSize < rfbTightMinToCompress) {
+ input = is;
+ } else {
+ int length = is.readCompactLength();
+ streamId = comp_ctl & 0x03;
+ zis[streamId].setUnderlying(is, length);
+ input = (ZlibInStream)zis[streamId];
+ }
+
+ if (palSize == 0) {
+ // Truecolor data.
+ if (useGradient) {
+ vlog.info("useGradient");
+ if (bpp == 32 && cutZeros) {
+ vlog.info("FilterGradient24");
+ FilterGradient24(r, input, dataSize, buf, handler);
+ } else {
+ vlog.info("FilterGradient");
+ FilterGradient(r, input, dataSize, buf, handler);
+ }
+ } else {
+ if (cutZeros) {
+ byte[] elem = new byte[3];
+ for (int i = 0; i < r.area(); i++) {
+ input.readBytes(elem, 0, 3);
+ if (bigEndian) {
+ buf[i] =
+ (elem[2] & 0xFF) << 16 | (elem[1] & 0xFF) << 8 | (elem[0] & 0xFF) | 0xFF << 24;
+ } else {
+ buf[i] =
+ (elem[0] & 0xFF) << 16 | (elem[1] & 0xFF) << 8 | (elem[2] & 0xFF) | 0xFF << 24;
+ }
+ }
+ } else {
+ for (int ptr=0; ptr < dataSize; ptr++)
+ buf[ptr] = input.readU8();
+ }
+ }
+ } else {
+ int x, y, b;
+ int ptr = 0;
+ int bits;
+ if (palSize <= 2) {
+ // 2-color palette
+ for (y = 0; y < r.height(); y++) {
+ for (x = 0; x < r.width() / 8; x++) {
+ bits = input.readU8();
+ for(b = 7; b >= 0; b--) {
+ buf[ptr++] = palette[bits >> b & 1];
+ }
+ }
+ if (r.width() % 8 != 0) {
+ bits = input.readU8();
+ for (b = 7; b >= 8 - r.width() % 8; b--) {
+ buf[ptr++] = palette[bits >> b & 1];
+ }
+ }
+ }
+ } else {
+ // 256-color palette
+ for (y = 0; y < r.height(); y++) {
+ for (x = 0; x < r.width(); x++) {
+ buf[ptr++] = palette[input.readU8()];
+ }
+ }
+ }
+ }
+
+ handler.imageRect(r, buf);
+
+ if (streamId != -1) {
+ zis[streamId].reset();
+ }
+ }
+
+ private CMsgReader reader;
+ private ZlibInStream[] zis;
+ static LogWriter vlog = new LogWriter("TightDecoder");
+
+ private static int convertByteArrayToInt(byte[] bytes) {
+ return (bytes[0] << 32) | (bytes[1] << 24) | (bytes[2] << 16) | (bytes[3] << 8) | bytes[4];
+ }
+
+ private static byte[] convertIntToByteArray(int integer) {
+ byte[] bytes = new byte[4];
+ bytes[0] =(byte)( integer >> 24 );
+ bytes[1] =(byte)( (integer << 8) >> 24 );
+ bytes[2] =(byte)( (integer << 16) >> 24 );
+ bytes[3] =(byte)( (integer << 24) >> 24 );
+ return bytes;
+ }
+ private static int[] convertByteArrayToIntArray(byte[] bytes) {
+ vlog.info("convertByteArrayToIntArray");
+ ArrayList<Integer> integers = new ArrayList<Integer>();
+ for (int index = 0; index < bytes.length; index += 4) {
+ byte[] fourBytes = new byte[4];
+ fourBytes[0] = bytes[index];
+ fourBytes[1] = bytes[index+1];
+ fourBytes[2] = bytes[index+2];
+ fourBytes[3] = bytes[index+3];
+ int integer = convertByteArrayToInt(fourBytes);
+ integers.add(new Integer(integer));
+ }
+ int[] ints = new int[bytes.length/4];
+ for (int index = 0; index < integers.size() ; index++) {
+ ints[index] = (integers.get(index)).intValue();
+ }
+ return ints;
+ }
+
+ private static byte[] convertIntArrayToByteArray(int[] integers) {
+ byte[] bytes = new byte[integers.length*4];
+ for (int index = 0; index < integers.length; index++) {
+ byte[] integerBytes = convertIntToByteArray(integers[index]);
+ bytes[index*4] = integerBytes[0];
+ bytes[1 + (index*4)] = integerBytes[1];
+ bytes[2 + (index*4)] = integerBytes[2];
+ bytes[3 + (index*4)] = integerBytes[3];
+ }
+ return bytes;
+ }
+
+ //
+ // Decode data processed with the "Gradient" filter.
+ //
+
+ final private void FilterGradient24(Rect r, InStream is, int dataSize, int[] buf, CMsgHandler handler) {
+
+ int x, y, c;
+ int[] prevRow = new int[TIGHT_MAX_WIDTH * 3];
+ int[] thisRow = new int[TIGHT_MAX_WIDTH * 3];
+ int[] pix = new int[3];
+ int[] est = new int[3];
+
+ // Allocate netbuf and read in data
+ int[] netbuf = new int[dataSize];
+ for (int i = 0; i < dataSize; i++)
+ netbuf[i] = is.readU8();
+ //is.readBytes(netbuf, 0, dataSize);
+
+ PixelFormat myFormat = handler.cp.pf();
+ int rectHeight = r.height();
+ int rectWidth = r.width();
+
+ for (y = 0; y < rectHeight; y++) {
+ /* First pixel in a row */
+ for (c = 0; c < 3; c++) {
+ pix[c] = netbuf[y*rectWidth*3+c] + prevRow[c];
+ thisRow[c] = pix[c];
+ }
+ if (myFormat.bigEndian) {
+ buf[y*rectWidth] =
+ (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF) | 0xFF << 24;
+ } else {
+ buf[y*rectWidth] =
+ (pix[2] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[0] & 0xFF) | 0xFF << 24;
+ }
+
+ /* Remaining pixels of a row */
+ for (x = 1; x < rectWidth; x++) {
+ for (c = 0; c < 3; c++) {
+ est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c];
+ if (est[c] > 0xFF) {
+ est[c] = 0xFF;
+ } else if (est[c] < 0) {
+ est[c] = 0;
+ }
+ pix[c] = netbuf[(y*rectWidth+x)*3+c] + est[c];
+ thisRow[x*3+c] = pix[c];
+ }
+ if (myFormat.bigEndian) {
+ buf[y*rectWidth] =
+ (pix[2] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[0] & 0xFF) | 0xFF << 24;
+ } else {
+ buf[y*rectWidth] =
+ (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF) | 0xFF << 24;
+ }
+ }
+
+ System.arraycopy(thisRow, 0, prevRow, 0, prevRow.length);
+ }
+ }
+
+ final private void FilterGradient(Rect r, InStream is, int dataSize, int[] buf, CMsgHandler handler) {
+
+ int x, y, c;
+ int[] prevRow = new int[TIGHT_MAX_WIDTH];
+ int[] thisRow = new int[TIGHT_MAX_WIDTH];
+ int[] pix = new int[3];
+ int[] est = new int[3];
+
+ // Allocate netbuf and read in data
+ int[] netbuf = new int[dataSize];
+ for (int i = 0; i < dataSize; i++)
+ netbuf[i] = is.readU8();
+ //is.readBytes(netbuf, 0, dataSize);
+
+ PixelFormat myFormat = handler.cp.pf();
+ int rectHeight = r.height();
+ int rectWidth = r.width();
+
+ for (y = 0; y < rectHeight; y++) {
+ /* First pixel in a row */
+ if (myFormat.bigEndian) {
+ buf[y*rectWidth] =
+ (pix[2] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[0] & 0xFF) | 0xFF << 24;
+ } else {
+ buf[y*rectWidth] =
+ (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF) | 0xFF << 24;
+ }
+ for (c = 0; c < 3; c++)
+ pix[c] += prevRow[c];
+
+ /* Remaining pixels of a row */
+ for (x = 1; x < rectWidth; x++) {
+ for (c = 0; c < 3; c++) {
+ est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c];
+ if (est[c] > 255) {
+ est[c] = 255;
+ } else if (est[c] < 0) {
+ est[c] = 0;
+ }
+ }
+
+ // FIXME?
+ System.arraycopy(pix, 0, netbuf, 0, netbuf.length);
+ for (c = 0; c < 3; c++)
+ pix[c] += est[c];
+
+ System.arraycopy(thisRow, x*3, pix, 0, pix.length);
+
+ if (myFormat.bigEndian) {
+ buf[y*rectWidth+x] =
+ (pix[2] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[0] & 0xFF) | 0xFF << 24;
+ } else {
+ buf[y*rectWidth+x] =
+ (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF) | 0xFF << 24;
+ }
+
+ }
+
+ System.arraycopy(thisRow, 0, prevRow, 0, prevRow.length);
+ }
+ }
+
+}
diff --git a/java/com/tigervnc/rfb/UnicodeToKeysym.java b/java/com/tigervnc/rfb/UnicodeToKeysym.java
new file mode 100644
index 00000000..44f61ba6
--- /dev/null
+++ b/java/com/tigervnc/rfb/UnicodeToKeysym.java
@@ -0,0 +1,795 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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.
+ */
+//
+// UnicodeToKeysym - provides a translate() method to convert from unicode
+// characters to the equivalent X keysym.
+//
+
+package com.tigervnc.rfb;
+
+public class UnicodeToKeysym {
+
+ public static short[][] table = {
+ { 0x03c0, 0x0100 },
+ { 0x03e0, 0x0101 },
+ { 0x01c3, 0x0102 },
+ { 0x01e3, 0x0103 },
+ { 0x01a1, 0x0104 },
+ { 0x01b1, 0x0105 },
+ { 0x01c6, 0x0106 },
+ { 0x01e6, 0x0107 },
+ { 0x02c6, 0x0108 },
+ { 0x02e6, 0x0109 },
+ { 0x02c5, 0x010a },
+ { 0x02e5, 0x010b },
+ { 0x01c8, 0x010c },
+ { 0x01e8, 0x010d },
+ { 0x01cf, 0x010e },
+ { 0x01ef, 0x010f },
+ { 0x01d0, 0x0110 },
+ { 0x01f0, 0x0111 },
+ { 0x03aa, 0x0112 },
+ { 0x03ba, 0x0113 },
+ { 0x03cc, 0x0116 },
+ { 0x03ec, 0x0117 },
+ { 0x01ca, 0x0118 },
+ { 0x01ea, 0x0119 },
+ { 0x01cc, 0x011a },
+ { 0x01ec, 0x011b },
+ { 0x02d8, 0x011c },
+ { 0x02f8, 0x011d },
+ { 0x02ab, 0x011e },
+ { 0x02bb, 0x011f },
+ { 0x02d5, 0x0120 },
+ { 0x02f5, 0x0121 },
+ { 0x03ab, 0x0122 },
+ { 0x03bb, 0x0123 },
+ { 0x02a6, 0x0124 },
+ { 0x02b6, 0x0125 },
+ { 0x02a1, 0x0126 },
+ { 0x02b1, 0x0127 },
+ { 0x03a5, 0x0128 },
+ { 0x03b5, 0x0129 },
+ { 0x03cf, 0x012a },
+ { 0x03ef, 0x012b },
+ { 0x03c7, 0x012e },
+ { 0x03e7, 0x012f },
+ { 0x02a9, 0x0130 },
+ { 0x02b9, 0x0131 },
+ { 0x02ac, 0x0134 },
+ { 0x02bc, 0x0135 },
+ { 0x03d3, 0x0136 },
+ { 0x03f3, 0x0137 },
+ { 0x03a2, 0x0138 },
+ { 0x01c5, 0x0139 },
+ { 0x01e5, 0x013a },
+ { 0x03a6, 0x013b },
+ { 0x03b6, 0x013c },
+ { 0x01a5, 0x013d },
+ { 0x01b5, 0x013e },
+ { 0x01a3, 0x0141 },
+ { 0x01b3, 0x0142 },
+ { 0x01d1, 0x0143 },
+ { 0x01f1, 0x0144 },
+ { 0x03d1, 0x0145 },
+ { 0x03f1, 0x0146 },
+ { 0x01d2, 0x0147 },
+ { 0x01f2, 0x0148 },
+ { 0x03bd, 0x014a },
+ { 0x03bf, 0x014b },
+ { 0x03d2, 0x014c },
+ { 0x03f2, 0x014d },
+ { 0x01d5, 0x0150 },
+ { 0x01f5, 0x0151 },
+ { 0x13bc, 0x0152 },
+ { 0x13bd, 0x0153 },
+ { 0x01c0, 0x0154 },
+ { 0x01e0, 0x0155 },
+ { 0x03a3, 0x0156 },
+ { 0x03b3, 0x0157 },
+ { 0x01d8, 0x0158 },
+ { 0x01f8, 0x0159 },
+ { 0x01a6, 0x015a },
+ { 0x01b6, 0x015b },
+ { 0x02de, 0x015c },
+ { 0x02fe, 0x015d },
+ { 0x01aa, 0x015e },
+ { 0x01ba, 0x015f },
+ { 0x01a9, 0x0160 },
+ { 0x01b9, 0x0161 },
+ { 0x01de, 0x0162 },
+ { 0x01fe, 0x0163 },
+ { 0x01ab, 0x0164 },
+ { 0x01bb, 0x0165 },
+ { 0x03ac, 0x0166 },
+ { 0x03bc, 0x0167 },
+ { 0x03dd, 0x0168 },
+ { 0x03fd, 0x0169 },
+ { 0x03de, 0x016a },
+ { 0x03fe, 0x016b },
+ { 0x02dd, 0x016c },
+ { 0x02fd, 0x016d },
+ { 0x01d9, 0x016e },
+ { 0x01f9, 0x016f },
+ { 0x01db, 0x0170 },
+ { 0x01fb, 0x0171 },
+ { 0x03d9, 0x0172 },
+ { 0x03f9, 0x0173 },
+ { 0x13be, 0x0178 },
+ { 0x01ac, 0x0179 },
+ { 0x01bc, 0x017a },
+ { 0x01af, 0x017b },
+ { 0x01bf, 0x017c },
+ { 0x01ae, 0x017d },
+ { 0x01be, 0x017e },
+ { 0x08f6, 0x0192 },
+ { 0x01b7, 0x02c7 },
+ { 0x01a2, 0x02d8 },
+ { 0x01ff, 0x02d9 },
+ { 0x01b2, 0x02db },
+ { 0x01bd, 0x02dd },
+ { 0x07ae, 0x0385 },
+ { 0x07a1, 0x0386 },
+ { 0x07a2, 0x0388 },
+ { 0x07a3, 0x0389 },
+ { 0x07a4, 0x038a },
+ { 0x07a7, 0x038c },
+ { 0x07a8, 0x038e },
+ { 0x07ab, 0x038f },
+ { 0x07b6, 0x0390 },
+ { 0x07c1, 0x0391 },
+ { 0x07c2, 0x0392 },
+ { 0x07c3, 0x0393 },
+ { 0x07c4, 0x0394 },
+ { 0x07c5, 0x0395 },
+ { 0x07c6, 0x0396 },
+ { 0x07c7, 0x0397 },
+ { 0x07c8, 0x0398 },
+ { 0x07c9, 0x0399 },
+ { 0x07ca, 0x039a },
+ { 0x07cb, 0x039b },
+ { 0x07cc, 0x039c },
+ { 0x07cd, 0x039d },
+ { 0x07ce, 0x039e },
+ { 0x07cf, 0x039f },
+ { 0x07d0, 0x03a0 },
+ { 0x07d1, 0x03a1 },
+ { 0x07d2, 0x03a3 },
+ { 0x07d4, 0x03a4 },
+ { 0x07d5, 0x03a5 },
+ { 0x07d6, 0x03a6 },
+ { 0x07d7, 0x03a7 },
+ { 0x07d8, 0x03a8 },
+ { 0x07d9, 0x03a9 },
+ { 0x07a5, 0x03aa },
+ { 0x07a9, 0x03ab },
+ { 0x07b1, 0x03ac },
+ { 0x07b2, 0x03ad },
+ { 0x07b3, 0x03ae },
+ { 0x07b4, 0x03af },
+ { 0x07ba, 0x03b0 },
+ { 0x07e1, 0x03b1 },
+ { 0x07e2, 0x03b2 },
+ { 0x07e3, 0x03b3 },
+ { 0x07e4, 0x03b4 },
+ { 0x07e5, 0x03b5 },
+ { 0x07e6, 0x03b6 },
+ { 0x07e7, 0x03b7 },
+ { 0x07e8, 0x03b8 },
+ { 0x07e9, 0x03b9 },
+ { 0x07ea, 0x03ba },
+ { 0x07eb, 0x03bb },
+ { 0x07ec, 0x03bc },
+ { 0x07ed, 0x03bd },
+ { 0x07ee, 0x03be },
+ { 0x07ef, 0x03bf },
+ { 0x07f0, 0x03c0 },
+ { 0x07f1, 0x03c1 },
+ { 0x07f3, 0x03c2 },
+ { 0x07f2, 0x03c3 },
+ { 0x07f4, 0x03c4 },
+ { 0x07f5, 0x03c5 },
+ { 0x07f6, 0x03c6 },
+ { 0x07f7, 0x03c7 },
+ { 0x07f8, 0x03c8 },
+ { 0x07f9, 0x03c9 },
+ { 0x07b5, 0x03ca },
+ { 0x07b9, 0x03cb },
+ { 0x07b7, 0x03cc },
+ { 0x07b8, 0x03cd },
+ { 0x07bb, 0x03ce },
+ { 0x06b3, 0x0401 },
+ { 0x06b1, 0x0402 },
+ { 0x06b2, 0x0403 },
+ { 0x06b4, 0x0404 },
+ { 0x06b5, 0x0405 },
+ { 0x06b6, 0x0406 },
+ { 0x06b7, 0x0407 },
+ { 0x06b8, 0x0408 },
+ { 0x06b9, 0x0409 },
+ { 0x06ba, 0x040a },
+ { 0x06bb, 0x040b },
+ { 0x06bc, 0x040c },
+ { 0x06be, 0x040e },
+ { 0x06bf, 0x040f },
+ { 0x06e1, 0x0410 },
+ { 0x06e2, 0x0411 },
+ { 0x06f7, 0x0412 },
+ { 0x06e7, 0x0413 },
+ { 0x06e4, 0x0414 },
+ { 0x06e5, 0x0415 },
+ { 0x06f6, 0x0416 },
+ { 0x06fa, 0x0417 },
+ { 0x06e9, 0x0418 },
+ { 0x06ea, 0x0419 },
+ { 0x06eb, 0x041a },
+ { 0x06ec, 0x041b },
+ { 0x06ed, 0x041c },
+ { 0x06ee, 0x041d },
+ { 0x06ef, 0x041e },
+ { 0x06f0, 0x041f },
+ { 0x06f2, 0x0420 },
+ { 0x06f3, 0x0421 },
+ { 0x06f4, 0x0422 },
+ { 0x06f5, 0x0423 },
+ { 0x06e6, 0x0424 },
+ { 0x06e8, 0x0425 },
+ { 0x06e3, 0x0426 },
+ { 0x06fe, 0x0427 },
+ { 0x06fb, 0x0428 },
+ { 0x06fd, 0x0429 },
+ { 0x06ff, 0x042a },
+ { 0x06f9, 0x042b },
+ { 0x06f8, 0x042c },
+ { 0x06fc, 0x042d },
+ { 0x06e0, 0x042e },
+ { 0x06f1, 0x042f },
+ { 0x06c1, 0x0430 },
+ { 0x06c2, 0x0431 },
+ { 0x06d7, 0x0432 },
+ { 0x06c7, 0x0433 },
+ { 0x06c4, 0x0434 },
+ { 0x06c5, 0x0435 },
+ { 0x06d6, 0x0436 },
+ { 0x06da, 0x0437 },
+ { 0x06c9, 0x0438 },
+ { 0x06ca, 0x0439 },
+ { 0x06cb, 0x043a },
+ { 0x06cc, 0x043b },
+ { 0x06cd, 0x043c },
+ { 0x06ce, 0x043d },
+ { 0x06cf, 0x043e },
+ { 0x06d0, 0x043f },
+ { 0x06d2, 0x0440 },
+ { 0x06d3, 0x0441 },
+ { 0x06d4, 0x0442 },
+ { 0x06d5, 0x0443 },
+ { 0x06c6, 0x0444 },
+ { 0x06c8, 0x0445 },
+ { 0x06c3, 0x0446 },
+ { 0x06de, 0x0447 },
+ { 0x06db, 0x0448 },
+ { 0x06dd, 0x0449 },
+ { 0x06df, 0x044a },
+ { 0x06d9, 0x044b },
+ { 0x06d8, 0x044c },
+ { 0x06dc, 0x044d },
+ { 0x06c0, 0x044e },
+ { 0x06d1, 0x044f },
+ { 0x06a3, 0x0451 },
+ { 0x06a1, 0x0452 },
+ { 0x06a2, 0x0453 },
+ { 0x06a4, 0x0454 },
+ { 0x06a5, 0x0455 },
+ { 0x06a6, 0x0456 },
+ { 0x06a7, 0x0457 },
+ { 0x06a8, 0x0458 },
+ { 0x06a9, 0x0459 },
+ { 0x06aa, 0x045a },
+ { 0x06ab, 0x045b },
+ { 0x06ac, 0x045c },
+ { 0x06ae, 0x045e },
+ { 0x06af, 0x045f },
+ { 0x0ce0, 0x05d0 },
+ { 0x0ce1, 0x05d1 },
+ { 0x0ce2, 0x05d2 },
+ { 0x0ce3, 0x05d3 },
+ { 0x0ce4, 0x05d4 },
+ { 0x0ce5, 0x05d5 },
+ { 0x0ce6, 0x05d6 },
+ { 0x0ce7, 0x05d7 },
+ { 0x0ce8, 0x05d8 },
+ { 0x0ce9, 0x05d9 },
+ { 0x0cea, 0x05da },
+ { 0x0ceb, 0x05db },
+ { 0x0cec, 0x05dc },
+ { 0x0ced, 0x05dd },
+ { 0x0cee, 0x05de },
+ { 0x0cef, 0x05df },
+ { 0x0cf0, 0x05e0 },
+ { 0x0cf1, 0x05e1 },
+ { 0x0cf2, 0x05e2 },
+ { 0x0cf3, 0x05e3 },
+ { 0x0cf4, 0x05e4 },
+ { 0x0cf5, 0x05e5 },
+ { 0x0cf6, 0x05e6 },
+ { 0x0cf7, 0x05e7 },
+ { 0x0cf8, 0x05e8 },
+ { 0x0cf9, 0x05e9 },
+ { 0x0cfa, 0x05ea },
+ { 0x05ac, 0x060c },
+ { 0x05bb, 0x061b },
+ { 0x05bf, 0x061f },
+ { 0x05c1, 0x0621 },
+ { 0x05c2, 0x0622 },
+ { 0x05c3, 0x0623 },
+ { 0x05c4, 0x0624 },
+ { 0x05c5, 0x0625 },
+ { 0x05c6, 0x0626 },
+ { 0x05c7, 0x0627 },
+ { 0x05c8, 0x0628 },
+ { 0x05c9, 0x0629 },
+ { 0x05ca, 0x062a },
+ { 0x05cb, 0x062b },
+ { 0x05cc, 0x062c },
+ { 0x05cd, 0x062d },
+ { 0x05ce, 0x062e },
+ { 0x05cf, 0x062f },
+ { 0x05d0, 0x0630 },
+ { 0x05d1, 0x0631 },
+ { 0x05d2, 0x0632 },
+ { 0x05d3, 0x0633 },
+ { 0x05d4, 0x0634 },
+ { 0x05d5, 0x0635 },
+ { 0x05d6, 0x0636 },
+ { 0x05d7, 0x0637 },
+ { 0x05d8, 0x0638 },
+ { 0x05d9, 0x0639 },
+ { 0x05da, 0x063a },
+ { 0x05e0, 0x0640 },
+ { 0x05e1, 0x0641 },
+ { 0x05e2, 0x0642 },
+ { 0x05e3, 0x0643 },
+ { 0x05e4, 0x0644 },
+ { 0x05e5, 0x0645 },
+ { 0x05e6, 0x0646 },
+ { 0x05e7, 0x0647 },
+ { 0x05e8, 0x0648 },
+ { 0x05e9, 0x0649 },
+ { 0x05ea, 0x064a },
+ { 0x05eb, 0x064b },
+ { 0x05ec, 0x064c },
+ { 0x05ed, 0x064d },
+ { 0x05ee, 0x064e },
+ { 0x05ef, 0x064f },
+ { 0x05f0, 0x0650 },
+ { 0x05f1, 0x0651 },
+ { 0x05f2, 0x0652 },
+ { 0x0da1, 0x0e01 },
+ { 0x0da2, 0x0e02 },
+ { 0x0da3, 0x0e03 },
+ { 0x0da4, 0x0e04 },
+ { 0x0da5, 0x0e05 },
+ { 0x0da6, 0x0e06 },
+ { 0x0da7, 0x0e07 },
+ { 0x0da8, 0x0e08 },
+ { 0x0da9, 0x0e09 },
+ { 0x0daa, 0x0e0a },
+ { 0x0dab, 0x0e0b },
+ { 0x0dac, 0x0e0c },
+ { 0x0dad, 0x0e0d },
+ { 0x0dae, 0x0e0e },
+ { 0x0daf, 0x0e0f },
+ { 0x0db0, 0x0e10 },
+ { 0x0db1, 0x0e11 },
+ { 0x0db2, 0x0e12 },
+ { 0x0db3, 0x0e13 },
+ { 0x0db4, 0x0e14 },
+ { 0x0db5, 0x0e15 },
+ { 0x0db6, 0x0e16 },
+ { 0x0db7, 0x0e17 },
+ { 0x0db8, 0x0e18 },
+ { 0x0db9, 0x0e19 },
+ { 0x0dba, 0x0e1a },
+ { 0x0dbb, 0x0e1b },
+ { 0x0dbc, 0x0e1c },
+ { 0x0dbd, 0x0e1d },
+ { 0x0dbe, 0x0e1e },
+ { 0x0dbf, 0x0e1f },
+ { 0x0dc0, 0x0e20 },
+ { 0x0dc1, 0x0e21 },
+ { 0x0dc2, 0x0e22 },
+ { 0x0dc3, 0x0e23 },
+ { 0x0dc4, 0x0e24 },
+ { 0x0dc5, 0x0e25 },
+ { 0x0dc6, 0x0e26 },
+ { 0x0dc7, 0x0e27 },
+ { 0x0dc8, 0x0e28 },
+ { 0x0dc9, 0x0e29 },
+ { 0x0dca, 0x0e2a },
+ { 0x0dcb, 0x0e2b },
+ { 0x0dcc, 0x0e2c },
+ { 0x0dcd, 0x0e2d },
+ { 0x0dce, 0x0e2e },
+ { 0x0dcf, 0x0e2f },
+ { 0x0dd0, 0x0e30 },
+ { 0x0dd1, 0x0e31 },
+ { 0x0dd2, 0x0e32 },
+ { 0x0dd3, 0x0e33 },
+ { 0x0dd4, 0x0e34 },
+ { 0x0dd5, 0x0e35 },
+ { 0x0dd6, 0x0e36 },
+ { 0x0dd7, 0x0e37 },
+ { 0x0dd8, 0x0e38 },
+ { 0x0dd9, 0x0e39 },
+ { 0x0dda, 0x0e3a },
+ { 0x0ddf, 0x0e3f },
+ { 0x0de0, 0x0e40 },
+ { 0x0de1, 0x0e41 },
+ { 0x0de2, 0x0e42 },
+ { 0x0de3, 0x0e43 },
+ { 0x0de4, 0x0e44 },
+ { 0x0de5, 0x0e45 },
+ { 0x0de6, 0x0e46 },
+ { 0x0de7, 0x0e47 },
+ { 0x0de8, 0x0e48 },
+ { 0x0de9, 0x0e49 },
+ { 0x0dea, 0x0e4a },
+ { 0x0deb, 0x0e4b },
+ { 0x0dec, 0x0e4c },
+ { 0x0ded, 0x0e4d },
+ { 0x0df0, 0x0e50 },
+ { 0x0df1, 0x0e51 },
+ { 0x0df2, 0x0e52 },
+ { 0x0df3, 0x0e53 },
+ { 0x0df4, 0x0e54 },
+ { 0x0df5, 0x0e55 },
+ { 0x0df6, 0x0e56 },
+ { 0x0df7, 0x0e57 },
+ { 0x0df8, 0x0e58 },
+ { 0x0df9, 0x0e59 },
+ { 0x0ed4, 0x11a8 },
+ { 0x0ed5, 0x11a9 },
+ { 0x0ed6, 0x11aa },
+ { 0x0ed7, 0x11ab },
+ { 0x0ed8, 0x11ac },
+ { 0x0ed9, 0x11ad },
+ { 0x0eda, 0x11ae },
+ { 0x0edb, 0x11af },
+ { 0x0edc, 0x11b0 },
+ { 0x0edd, 0x11b1 },
+ { 0x0ede, 0x11b2 },
+ { 0x0edf, 0x11b3 },
+ { 0x0ee0, 0x11b4 },
+ { 0x0ee1, 0x11b5 },
+ { 0x0ee2, 0x11b6 },
+ { 0x0ee3, 0x11b7 },
+ { 0x0ee4, 0x11b8 },
+ { 0x0ee5, 0x11b9 },
+ { 0x0ee6, 0x11ba },
+ { 0x0ee7, 0x11bb },
+ { 0x0ee8, 0x11bc },
+ { 0x0ee9, 0x11bd },
+ { 0x0eea, 0x11be },
+ { 0x0eeb, 0x11bf },
+ { 0x0eec, 0x11c0 },
+ { 0x0eed, 0x11c1 },
+ { 0x0eee, 0x11c2 },
+ { 0x0ef8, 0x11eb },
+ { 0x0ef9, 0x11f0 },
+ { 0x0efa, 0x11f9 },
+ { 0x0aa2, 0x2002 },
+ { 0x0aa1, 0x2003 },
+ { 0x0aa3, 0x2004 },
+ { 0x0aa4, 0x2005 },
+ { 0x0aa5, 0x2007 },
+ { 0x0aa6, 0x2008 },
+ { 0x0aa7, 0x2009 },
+ { 0x0aa8, 0x200a },
+ { 0x0abb, 0x2012 },
+ { 0x0aaa, 0x2013 },
+ { 0x0aa9, 0x2014 },
+ { 0x07af, 0x2015 },
+ { 0x0cdf, 0x2017 },
+ { 0x0ad0, 0x2018 },
+ { 0x0ad1, 0x2019 },
+ { 0x0afd, 0x201a },
+ { 0x0ad2, 0x201c },
+ { 0x0ad3, 0x201d },
+ { 0x0afe, 0x201e },
+ { 0x0af1, 0x2020 },
+ { 0x0af2, 0x2021 },
+ { 0x0ae6, 0x2022 },
+ { 0x0aaf, 0x2025 },
+ { 0x0aae, 0x2026 },
+ { 0x0ad6, 0x2032 },
+ { 0x0ad7, 0x2033 },
+ { 0x0afc, 0x2038 },
+ { 0x047e, 0x203e },
+ { 0x0eff, 0x20a9 },
+ { 0x20ac, 0x20ac },
+ { 0x0ab8, 0x2105 },
+ { 0x06b0, 0x2116 },
+ { 0x0afb, 0x2117 },
+ { 0x0ad4, 0x211e },
+ { 0x0ac9, 0x2122 },
+ { 0x0ab0, 0x2153 },
+ { 0x0ab1, 0x2154 },
+ { 0x0ab2, 0x2155 },
+ { 0x0ab3, 0x2156 },
+ { 0x0ab4, 0x2157 },
+ { 0x0ab5, 0x2158 },
+ { 0x0ab6, 0x2159 },
+ { 0x0ab7, 0x215a },
+ { 0x0ac3, 0x215b },
+ { 0x0ac4, 0x215c },
+ { 0x0ac5, 0x215d },
+ { 0x0ac6, 0x215e },
+ { 0x08fb, 0x2190 },
+ { 0x08fc, 0x2191 },
+ { 0x08fd, 0x2192 },
+ { 0x08fe, 0x2193 },
+ { 0x08ce, 0x21d2 },
+ { 0x08cd, 0x21d4 },
+ { 0x08ef, 0x2202 },
+ { 0x08c5, 0x2207 },
+ { 0x0bca, 0x2218 },
+ { 0x08d6, 0x221a },
+ { 0x08c1, 0x221d },
+ { 0x08c2, 0x221e },
+ { 0x08de, 0x2227 },
+ { 0x08df, 0x2228 },
+ { 0x08dc, 0x2229 },
+ { 0x08dd, 0x222a },
+ { 0x08bf, 0x222b },
+ { 0x08c0, 0x2234 },
+ { 0x08c8, 0x223c },
+ { 0x08c9, 0x2243 },
+ { 0x08bd, 0x2260 },
+ { 0x08cf, 0x2261 },
+ { 0x08bc, 0x2264 },
+ { 0x08be, 0x2265 },
+ { 0x08da, 0x2282 },
+ { 0x08db, 0x2283 },
+ { 0x0bfc, 0x22a2 },
+ { 0x0bdc, 0x22a3 },
+ { 0x0bce, 0x22a4 },
+ { 0x0bc2, 0x22a5 },
+ { 0x0bd3, 0x2308 },
+ { 0x0bc4, 0x230a },
+ { 0x0afa, 0x2315 },
+ { 0x08a4, 0x2320 },
+ { 0x08a5, 0x2321 },
+ { 0x0abc, 0x2329 },
+ { 0x0abe, 0x232a },
+ { 0x0bcc, 0x2395 },
+ { 0x08ab, 0x239b },
+ { 0x08ac, 0x239d },
+ { 0x08ad, 0x239e },
+ { 0x08ae, 0x23a0 },
+ { 0x08a7, 0x23a1 },
+ { 0x08a8, 0x23a3 },
+ { 0x08a9, 0x23a4 },
+ { 0x08aa, 0x23a6 },
+ { 0x08af, 0x23a8 },
+ { 0x08b0, 0x23ac },
+ { 0x08a1, 0x23b7 },
+ { 0x09ef, 0x23ba },
+ { 0x09f0, 0x23bb },
+ { 0x09f2, 0x23bc },
+ { 0x09f3, 0x23bd },
+ { 0x09e2, 0x2409 },
+ { 0x09e5, 0x240a },
+ { 0x09e9, 0x240b },
+ { 0x09e3, 0x240c },
+ { 0x09e4, 0x240d },
+ { 0x09e8, 0x2424 },
+ { 0x09f1, 0x2500 },
+ { 0x09f8, 0x2502 },
+ { 0x09ec, 0x250c },
+ { 0x09eb, 0x2510 },
+ { 0x09ed, 0x2514 },
+ { 0x09ea, 0x2518 },
+ { 0x09f4, 0x251c },
+ { 0x09f5, 0x2524 },
+ { 0x09f7, 0x252c },
+ { 0x09f6, 0x2534 },
+ { 0x09ee, 0x253c },
+ { 0x09e1, 0x2592 },
+ { 0x0ae7, 0x25aa },
+ { 0x0ae1, 0x25ab },
+ { 0x0adb, 0x25ac },
+ { 0x0ae2, 0x25ad },
+ { 0x0adf, 0x25ae },
+ { 0x0acf, 0x25af },
+ { 0x0ae8, 0x25b2 },
+ { 0x0ae3, 0x25b3 },
+ { 0x0add, 0x25b6 },
+ { 0x0acd, 0x25b7 },
+ { 0x0ae9, 0x25bc },
+ { 0x0ae4, 0x25bd },
+ { 0x0adc, 0x25c0 },
+ { 0x0acc, 0x25c1 },
+ { 0x09e0, 0x25c6 },
+ { 0x0ace, 0x25cb },
+ { 0x0ade, 0x25cf },
+ { 0x0ae0, 0x25e6 },
+ { 0x0ae5, 0x2606 },
+ { 0x0af9, 0x260e },
+ { 0x0aca, 0x2613 },
+ { 0x0aea, 0x261c },
+ { 0x0aeb, 0x261e },
+ { 0x0af8, 0x2640 },
+ { 0x0af7, 0x2642 },
+ { 0x0aec, 0x2663 },
+ { 0x0aee, 0x2665 },
+ { 0x0aed, 0x2666 },
+ { 0x0af6, 0x266d },
+ { 0x0af5, 0x266f },
+ { 0x0af3, 0x2713 },
+ { 0x0af4, 0x2717 },
+ { 0x0ad9, 0x271d },
+ { 0x0af0, 0x2720 },
+ { 0x04a4, 0x3001 },
+ { 0x04a1, 0x3002 },
+ { 0x04a2, 0x300c },
+ { 0x04a3, 0x300d },
+ { 0x04de, 0x309b },
+ { 0x04df, 0x309c },
+ { 0x04a7, 0x30a1 },
+ { 0x04b1, 0x30a2 },
+ { 0x04a8, 0x30a3 },
+ { 0x04b2, 0x30a4 },
+ { 0x04a9, 0x30a5 },
+ { 0x04b3, 0x30a6 },
+ { 0x04aa, 0x30a7 },
+ { 0x04b4, 0x30a8 },
+ { 0x04ab, 0x30a9 },
+ { 0x04b5, 0x30aa },
+ { 0x04b6, 0x30ab },
+ { 0x04b7, 0x30ad },
+ { 0x04b8, 0x30af },
+ { 0x04b9, 0x30b1 },
+ { 0x04ba, 0x30b3 },
+ { 0x04bb, 0x30b5 },
+ { 0x04bc, 0x30b7 },
+ { 0x04bd, 0x30b9 },
+ { 0x04be, 0x30bb },
+ { 0x04bf, 0x30bd },
+ { 0x04c0, 0x30bf },
+ { 0x04c1, 0x30c1 },
+ { 0x04af, 0x30c3 },
+ { 0x04c2, 0x30c4 },
+ { 0x04c3, 0x30c6 },
+ { 0x04c4, 0x30c8 },
+ { 0x04c5, 0x30ca },
+ { 0x04c6, 0x30cb },
+ { 0x04c7, 0x30cc },
+ { 0x04c8, 0x30cd },
+ { 0x04c9, 0x30ce },
+ { 0x04ca, 0x30cf },
+ { 0x04cb, 0x30d2 },
+ { 0x04cc, 0x30d5 },
+ { 0x04cd, 0x30d8 },
+ { 0x04ce, 0x30db },
+ { 0x04cf, 0x30de },
+ { 0x04d0, 0x30df },
+ { 0x04d1, 0x30e0 },
+ { 0x04d2, 0x30e1 },
+ { 0x04d3, 0x30e2 },
+ { 0x04ac, 0x30e3 },
+ { 0x04d4, 0x30e4 },
+ { 0x04ad, 0x30e5 },
+ { 0x04d5, 0x30e6 },
+ { 0x04ae, 0x30e7 },
+ { 0x04d6, 0x30e8 },
+ { 0x04d7, 0x30e9 },
+ { 0x04d8, 0x30ea },
+ { 0x04d9, 0x30eb },
+ { 0x04da, 0x30ec },
+ { 0x04db, 0x30ed },
+ { 0x04dc, 0x30ef },
+ { 0x04a6, 0x30f2 },
+ { 0x04dd, 0x30f3 },
+ { 0x04a5, 0x30fb },
+ { 0x04b0, 0x30fc },
+ { 0x0ea1, 0x3131 },
+ { 0x0ea2, 0x3132 },
+ { 0x0ea3, 0x3133 },
+ { 0x0ea4, 0x3134 },
+ { 0x0ea5, 0x3135 },
+ { 0x0ea6, 0x3136 },
+ { 0x0ea7, 0x3137 },
+ { 0x0ea8, 0x3138 },
+ { 0x0ea9, 0x3139 },
+ { 0x0eaa, 0x313a },
+ { 0x0eab, 0x313b },
+ { 0x0eac, 0x313c },
+ { 0x0ead, 0x313d },
+ { 0x0eae, 0x313e },
+ { 0x0eaf, 0x313f },
+ { 0x0eb0, 0x3140 },
+ { 0x0eb1, 0x3141 },
+ { 0x0eb2, 0x3142 },
+ { 0x0eb3, 0x3143 },
+ { 0x0eb4, 0x3144 },
+ { 0x0eb5, 0x3145 },
+ { 0x0eb6, 0x3146 },
+ { 0x0eb7, 0x3147 },
+ { 0x0eb8, 0x3148 },
+ { 0x0eb9, 0x3149 },
+ { 0x0eba, 0x314a },
+ { 0x0ebb, 0x314b },
+ { 0x0ebc, 0x314c },
+ { 0x0ebd, 0x314d },
+ { 0x0ebe, 0x314e },
+ { 0x0ebf, 0x314f },
+ { 0x0ec0, 0x3150 },
+ { 0x0ec1, 0x3151 },
+ { 0x0ec2, 0x3152 },
+ { 0x0ec3, 0x3153 },
+ { 0x0ec4, 0x3154 },
+ { 0x0ec5, 0x3155 },
+ { 0x0ec6, 0x3156 },
+ { 0x0ec7, 0x3157 },
+ { 0x0ec8, 0x3158 },
+ { 0x0ec9, 0x3159 },
+ { 0x0eca, 0x315a },
+ { 0x0ecb, 0x315b },
+ { 0x0ecc, 0x315c },
+ { 0x0ecd, 0x315d },
+ { 0x0ece, 0x315e },
+ { 0x0ecf, 0x315f },
+ { 0x0ed0, 0x3160 },
+ { 0x0ed1, 0x3161 },
+ { 0x0ed2, 0x3162 },
+ { 0x0ed3, 0x3163 },
+ { 0x0eef, 0x316d },
+ { 0x0ef0, 0x3171 },
+ { 0x0ef1, 0x3178 },
+ { 0x0ef2, 0x317f },
+ { 0x0ef3, 0x3181 },
+ { 0x0ef4, 0x3184 },
+ { 0x0ef5, 0x3186 },
+ { 0x0ef6, 0x318d },
+ { 0x0ef7, 0x318e }
+ };
+
+ public static int translate(int unicode) {
+ if ((unicode >= 0x20 && unicode <= 0x7e) ||
+ (unicode >= 0xa0 && unicode <= 0xff))
+ return unicode;
+
+ int min = 0;
+ int max = table.length - 1;
+ int mid;
+
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (table[mid][1] < unicode)
+ min = mid + 1;
+ else if (table[mid][1] > unicode)
+ max = mid - 1;
+ else
+ return table[mid][0];
+ }
+
+ /* no matching Unicode value found */
+ return -1;
+ }
+}
diff --git a/java/com/tigervnc/rfb/UserMsgBox.java b/java/com/tigervnc/rfb/UserMsgBox.java
new file mode 100644
index 00000000..e83d9956
--- /dev/null
+++ b/java/com/tigervnc/rfb/UserMsgBox.java
@@ -0,0 +1,27 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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.
+ */
+
+// getUserPasswd() gets the username and password. This might involve a
+// dialog, getpass(), etc. The user buffer pointer can be null, in which case
+// no user name will be retrieved.
+
+package com.tigervnc.rfb;
+
+public interface UserMsgBox {
+ public boolean showMsgBox(int flags,String title, String text);
+}
diff --git a/java/com/tigervnc/rfb/UserPasswdGetter.java b/java/com/tigervnc/rfb/UserPasswdGetter.java
new file mode 100644
index 00000000..9796b66f
--- /dev/null
+++ b/java/com/tigervnc/rfb/UserPasswdGetter.java
@@ -0,0 +1,27 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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.
+ */
+
+// getUserPasswd() gets the username and password. This might involve a
+// dialog, getpass(), etc. The user buffer pointer can be null, in which case
+// no user name will be retrieved.
+
+package com.tigervnc.rfb;
+
+public interface UserPasswdGetter {
+ public boolean getUserPasswd(StringBuffer user, StringBuffer password);
+}
diff --git a/java/com/tigervnc/rfb/VncAuth.java b/java/com/tigervnc/rfb/VncAuth.java
new file mode 100644
index 00000000..cce8d81c
--- /dev/null
+++ b/java/com/tigervnc/rfb/VncAuth.java
@@ -0,0 +1,67 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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 VncAuth {
+
+ public static final int ok = 0;
+ public static final int failed = 1;
+ public static final int tooMany = 2; // deprecated
+
+ public static final int challengeSize = 16;
+
+ public static void encryptChallenge(byte[] challenge, String passwd) {
+ byte[] key = new byte[8];
+ for (int i = 0; i < 8 && i < passwd.length(); i++) {
+ key[i] = (byte)passwd.charAt(i);
+ }
+
+ DesCipher des = new DesCipher(key);
+
+ for (int j = 0; j < challengeSize; j += 8)
+ des.encrypt(challenge,j,challenge,j);
+ }
+
+ void obfuscatePasswd(String passwd, byte[] obfuscated) {
+ for (int i = 0; i < 8; i++) {
+ if (i < passwd.length())
+ obfuscated[i] = (byte)passwd.charAt(i);
+ else
+ obfuscated[i] = 0;
+ }
+ DesCipher des = new DesCipher(obfuscationKey);
+ des.encrypt(obfuscated,0,obfuscated,0);
+ }
+
+ String unobfuscatePasswd(byte[] obfuscated) {
+ DesCipher des = new DesCipher(obfuscationKey);
+ des.decrypt(obfuscated,0,obfuscated,0);
+ int len;
+ for (len = 0; len < 8; len++) {
+ if (obfuscated[len] == 0) break;
+ }
+ char[] plain = new char[len];
+ for (int i = 0; i < len; i++) {
+ plain[i] = (char)obfuscated[i];
+ }
+ return new String(plain);
+ }
+
+ static byte[] obfuscationKey = {23,82,107,6,35,78,88,7};
+}
diff --git a/java/com/tigervnc/rfb/VoidParameter.java b/java/com/tigervnc/rfb/VoidParameter.java
new file mode 100644
index 00000000..f41f4c84
--- /dev/null
+++ b/java/com/tigervnc/rfb/VoidParameter.java
@@ -0,0 +1,41 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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;
+
+abstract public class VoidParameter {
+ public VoidParameter(String name_, String desc_) {
+ name = name_;
+ description = desc_;
+ next = Configuration.head;
+ Configuration.head = this;
+ }
+
+ final public String getName() { return name; }
+ final public String getDescription() { return description; }
+
+ abstract public boolean setParam(String value);
+ public boolean setParam() { return false; }
+ abstract public String getDefaultStr();
+ abstract public String getValueStr();
+ public boolean isBool() { return false; }
+
+ VoidParameter next;
+ protected String name;
+ protected String description;
+}
diff --git a/java/com/tigervnc/rfb/ZRLEDecoder.java b/java/com/tigervnc/rfb/ZRLEDecoder.java
new file mode 100644
index 00000000..4f740f9d
--- /dev/null
+++ b/java/com/tigervnc/rfb/ZRLEDecoder.java
@@ -0,0 +1,166 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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;
+
+import com.tigervnc.rdr.*;
+
+public class ZRLEDecoder extends Decoder {
+
+ public ZRLEDecoder(CMsgReader reader_) {
+ reader = reader_;
+ zis = new ZlibInStream();
+ }
+
+ public void readRect(Rect r, CMsgHandler handler) {
+ InStream is = reader.getInStream();
+ int[] buf = reader.getImageBuf(64 * 64 * 4);
+ int bytesPerPixel = handler.cp.pf().bpp / 8;
+ boolean bigEndian = handler.cp.pf().bigEndian;
+
+ int length = is.readU32();
+ zis.setUnderlying(is, length);
+ Rect t = new Rect();
+
+ for (t.tl.y = r.tl.y; t.tl.y < r.br.y; t.tl.y += 64) {
+
+ t.br.y = Math.min(r.br.y, t.tl.y + 64);
+
+ for (t.tl.x = r.tl.x; t.tl.x < r.br.x; t.tl.x += 64) {
+
+ t.br.x = Math.min(r.br.x, t.tl.x + 64);
+
+ int mode = zis.readU8();
+ boolean rle = (mode & 128) != 0;
+ int palSize = mode & 127;
+ int[] palette = new int[128];
+
+ if (bytesPerPixel > 1) {
+ zis.readPixels(palette, palSize, 3, bigEndian);
+ } else {
+ for (int i = 0; i < palSize; i++) {
+ palette[i] = zis.readPixel(bytesPerPixel, bigEndian);
+ }
+ }
+
+ if (palSize == 1) {
+ int pix = palette[0];
+ handler.fillRect(t, pix);
+ continue;
+ }
+
+ if (!rle) {
+ if (palSize == 0) {
+
+ // raw
+
+ if (bytesPerPixel > 1) {
+ zis.readPixels(buf, t.area(), 3, bigEndian);
+ } else {
+ zis.readPixels(buf, t.area(), bytesPerPixel, bigEndian);
+ }
+
+ } else {
+
+ // packed pixels
+ int bppp = ((palSize > 16) ? 8 :
+ ((palSize > 4) ? 4 : ((palSize > 2) ? 2 : 1)));
+
+ int ptr = 0;
+
+ for (int i = 0; i < t.height(); i++) {
+ int eol = ptr + t.width();
+ int b = 0;
+ int nbits = 0;
+
+ while (ptr < eol) {
+ if (nbits == 0) {
+ b = zis.readU8();
+ nbits = 8;
+ }
+ nbits -= bppp;
+ int index = (b >> nbits) & ((1 << bppp) - 1) & 127;
+ buf[ptr++] = palette[index];
+ }
+ }
+ }
+
+ } else {
+
+ if (palSize == 0) {
+
+ // plain RLE
+
+ int ptr = 0;
+ int end = ptr + t.area();
+ while (ptr < end) {
+ int pix = (bytesPerPixel > 1 ? zis.readPixel(3, bigEndian) :
+ zis.readPixel(bytesPerPixel, bigEndian));
+ int len = 1;
+ int b;
+ do {
+ b = zis.readU8();
+ len += b;
+ } while (b == 255);
+
+ if (!(len <= end - ptr))
+ throw new Exception("ZRLEDecoder: assertion (len <= end - ptr)"
+ +" failed");
+
+ while (len-- > 0) buf[ptr++] = pix;
+ }
+ } else {
+
+ // palette RLE
+
+ int ptr = 0;
+ int end = ptr + t.area();
+ while (ptr < end) {
+ int index = zis.readU8();
+ int len = 1;
+ if ((index & 128) != 0) {
+ int b;
+ do {
+ b = zis.readU8();
+ len += b;
+ } while (b == 255);
+
+ if (!(len <= end - ptr))
+ throw new Exception("ZRLEDecoder: assertion "
+ +"(len <= end - ptr) failed");
+ }
+
+ index &= 127;
+
+ int pix = palette[index];
+
+ while (len-- > 0) buf[ptr++] = pix;
+ }
+ }
+ }
+
+ handler.imageRect(t, buf);
+ }
+ }
+
+ zis.reset();
+ }
+
+ CMsgReader reader;
+ ZlibInStream zis;
+}
diff --git a/java/com/tigervnc/rfb/screenTypes.java b/java/com/tigervnc/rfb/screenTypes.java
new file mode 100644
index 00000000..d46741c6
--- /dev/null
+++ b/java/com/tigervnc/rfb/screenTypes.java
@@ -0,0 +1,36 @@
+/* Copyright 2009 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 screenTypes {
+
+ // Reasons
+ public static final int reasonServer = 0;
+ public static final int reasonClient = 1;
+ public static final int reasonOtherClient = 2;
+
+ // Result codes
+ public static final int resultSuccess = 0;
+ public static final int resultProhibited = 1;
+ public static final int resultNoResources = 2;
+ public static final int resultInvalid = 3;
+
+ public static final int resultUnsolicited = 0xffff; // internal code used for server changes
+
+}