summaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorBrian Hinz <bphinz@users.sourceforge.net>2011-06-30 13:24:24 +0000
committerBrian Hinz <bphinz@users.sourceforge.net>2011-06-30 13:24:24 +0000
commit882a1d897aaf1f964f733fdcc39146b519626aa7 (patch)
tree7f75282dfa7c3b4066bd5e9b3eb2dbaaa217caa3 /java
parent5f75df117f188870ae670a6f0f7f544c46cce01b (diff)
downloadtigervnc-882a1d897aaf1f964f733fdcc39146b519626aa7.tar.gz
tigervnc-882a1d897aaf1f964f733fdcc39146b519626aa7.zip
corrected all inconsistent eol-styles and set eol-style:native on *.java. Also set svn:ignore on *.class
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4574 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'java')
-rw-r--r--java/src/com/tigervnc/rfb/CSecurityTLS.java500
-rw-r--r--java/src/com/tigervnc/rfb/CSecurityVncAuth.java116
-rw-r--r--java/src/com/tigervnc/rfb/StringParameter.java90
-rw-r--r--java/src/com/tigervnc/vncviewer/CConn.java2326
-rw-r--r--java/src/com/tigervnc/vncviewer/DesktopWindow.java948
-rw-r--r--java/src/com/tigervnc/vncviewer/OptionsDialog.java752
-rw-r--r--java/src/com/tigervnc/vncviewer/ServerDialog.java348
7 files changed, 2540 insertions, 2540 deletions
diff --git a/java/src/com/tigervnc/rfb/CSecurityTLS.java b/java/src/com/tigervnc/rfb/CSecurityTLS.java
index 977987ea..355d08f4 100644
--- a/java/src/com/tigervnc/rfb/CSecurityTLS.java
+++ b/java/src/com/tigervnc/rfb/CSecurityTLS.java
@@ -1,251 +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.
- */
-
+/*
+ * 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 enabled = new ArrayList();
-
- supported = ssl.getSupportedCipherSuites();
-
- for (int i = 0; i < supported.length; i++)
- if (supported[i].matches("TLS_DH_anon.*"))
- enabled.add(supported[i]);
-
- ssl.setEnabledCipherSuites((String[])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.getFileSeperator()+".vnc"+
- UserPrefs.getFileSeperator();
- 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");
-}
+
+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 enabled = new ArrayList();
+
+ supported = ssl.getSupportedCipherSuites();
+
+ for (int i = 0; i < supported.length; i++)
+ if (supported[i].matches("TLS_DH_anon.*"))
+ enabled.add(supported[i]);
+
+ ssl.setEnabledCipherSuites((String[])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.getFileSeperator()+".vnc"+
+ UserPrefs.getFileSeperator();
+ 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/src/com/tigervnc/rfb/CSecurityVncAuth.java b/java/src/com/tigervnc/rfb/CSecurityVncAuth.java
index 75673d51..405e79fa 100644
--- a/java/src/com/tigervnc/rfb/CSecurityVncAuth.java
+++ b/java/src/com/tigervnc/rfb/CSecurityVncAuth.java
@@ -1,66 +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.
- */
-
+/* 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.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();
+
+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");
-}
+ 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/src/com/tigervnc/rfb/StringParameter.java b/java/src/com/tigervnc/rfb/StringParameter.java
index 4f704d9b..d7fd1a51 100644
--- a/java/src/com/tigervnc/rfb/StringParameter.java
+++ b/java/src/com/tigervnc/rfb/StringParameter.java
@@ -1,46 +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.
- */
-
+/* 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;
-}
+
+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/src/com/tigervnc/vncviewer/CConn.java b/java/src/com/tigervnc/vncviewer/CConn.java
index 9224aa17..9ce75fc6 100644
--- a/java/src/com/tigervnc/vncviewer/CConn.java
+++ b/java/src/com/tigervnc/vncviewer/CConn.java
@@ -1,287 +1,287 @@
-/* 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.
- */
-
-//
-// CConn
-//
-// Methods on CConn are called from both the GUI thread and the thread which
-// processes incoming RFB messages ("the RFB thread"). This means we need to
-// be careful with synchronization here.
-//
-// Any access to writer() must not only be synchronized, but we must also make
-// sure that the connection is in RFBSTATE_NORMAL. We are guaranteed this for
-// any code called after serverInit() has been called. Since the DesktopWindow
-// isn't created until then, any methods called only from DesktopWindow can
-// assume that we are in RFBSTATE_NORMAL.
-
-package com.tigervnc.vncviewer;
-
+/* 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.
+ */
+
+//
+// CConn
+//
+// Methods on CConn are called from both the GUI thread and the thread which
+// processes incoming RFB messages ("the RFB thread"). This means we need to
+// be careful with synchronization here.
+//
+// Any access to writer() must not only be synchronized, but we must also make
+// sure that the connection is in RFBSTATE_NORMAL. We are guaranteed this for
+// any code called after serverInit() has been called. Since the DesktopWindow
+// isn't created until then, any methods called only from DesktopWindow can
+// assume that we are in RFBSTATE_NORMAL.
+
+package com.tigervnc.vncviewer;
+
import java.awt.Color;
import java.awt.Graphics;
-import java.awt.event.*;
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.Event;
-import java.awt.Frame;
-import java.awt.ScrollPane;
-
-import java.io.*;
-import javax.net.ssl.*;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.File;
-import java.util.jar.Attributes;
-import java.util.jar.Manifest;
-import javax.swing.*;
-import javax.swing.filechooser.*;
-import javax.swing.ImageIcon;
-import java.net.URL;
-import java.net.ServerSocket;
-import javax.swing.border.*;
-import java.util.*;
+import java.awt.event.*;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Event;
+import java.awt.Frame;
+import java.awt.ScrollPane;
+
+import java.io.*;
+import javax.net.ssl.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.File;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import javax.swing.*;
+import javax.swing.filechooser.*;
+import javax.swing.ImageIcon;
+import java.net.URL;
+import java.net.ServerSocket;
+import javax.swing.border.*;
+import java.util.*;
import com.tigervnc.rdr.*;
import com.tigervnc.rfb.*;
import com.tigervnc.rfb.Exception;
import com.tigervnc.rfb.Point;
import com.tigervnc.rfb.Rect;
-
-class ViewportFrame extends JFrame
-{
- public ViewportFrame(String name, CConn cc_) {
- cc = cc_;
- setTitle("TigerVNC: "+name);
- setFocusable(false);
- setFocusTraversalKeysEnabled(false);
- addWindowFocusListener(new WindowAdapter() {
- public void windowGainedFocus(WindowEvent e) {
- sp.getViewport().getView().requestFocusInWindow();
- }
- });
- addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- cc.close();
- }
- });
- }
-
- public void addChild(DesktopWindow child) {
- sp = new JScrollPane(child);
- child.setBackground(Color.BLACK);
- child.setOpaque(true);
- sp.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
- getContentPane().add(sp);
- }
-
- public void setChild(DesktopWindow child) {
+
+class ViewportFrame extends JFrame
+{
+ public ViewportFrame(String name, CConn cc_) {
+ cc = cc_;
+ setTitle("TigerVNC: "+name);
+ setFocusable(false);
+ setFocusTraversalKeysEnabled(false);
+ addWindowFocusListener(new WindowAdapter() {
+ public void windowGainedFocus(WindowEvent e) {
+ sp.getViewport().getView().requestFocusInWindow();
+ }
+ });
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ cc.close();
+ }
+ });
+ }
+
+ public void addChild(DesktopWindow child) {
+ sp = new JScrollPane(child);
+ child.setBackground(Color.BLACK);
+ child.setOpaque(true);
+ sp.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
+ getContentPane().add(sp);
+ }
+
+ public void setChild(DesktopWindow child) {
getContentPane().removeAll();
addChild(child);
- }
-
- public void setGeometry(int x, int y, int w, int h) {
- pack();
- if (cc.fullScreen) setSize(w, h);
- setLocation(x, y);
- setBackground(Color.BLACK);
- }
-
-
- CConn cc;
- Graphics g;
- JScrollPane sp;
- static LogWriter vlog = new LogWriter("ViewportFrame");
-}
-
-public class CConn extends CConnection
- implements UserPasswdGetter, UserMsgBox, OptionsDialogCallback
-{
- ////////////////////////////////////////////////////////////////////
- // The following methods are all called from the RFB thread
-
- public CConn(VncViewer viewer_, java.net.Socket sock_,
- String vncServerName, boolean reverse)
- {
- serverHost = null; serverPort = 0; sock = sock_; viewer = viewer_;
- currentEncoding = Encodings.encodingTight; lastServerEncoding = -1;
- fullColour = viewer.fullColour.getValue();
- lowColourLevel = 2;
- autoSelect = viewer.autoSelect.getValue();
- shared = viewer.shared.getValue(); formatChange = false;
- encodingChange = false; sameMachine = false;
- fullScreen = viewer.fullScreen.getValue();
- menuKey = Keysyms.F8;
- options = new OptionsDialog(this);
- clipboardDialog = new ClipboardDialog(this);
- firstUpdate = true; pendingUpdate = false;
-
- setShared(shared);
- upg = this;
- msg = this;
-
- String encStr = viewer.preferredEncoding.getValue();
- int encNum = Encodings.encodingNum(encStr);
- if (encNum != -1) {
- currentEncoding = encNum;
- }
- cp.supportsDesktopResize = true;
- cp.supportsExtendedDesktopSize = true;
- cp.supportsDesktopRename = true;
- cp.supportsLocalCursor = viewer.useLocalCursor.getValue();
- cp.customCompressLevel = viewer.customCompressLevel.getValue();
- cp.compressLevel = viewer.compressLevel.getValue();
- cp.noJpeg = viewer.noJpeg.getValue();
- cp.qualityLevel = viewer.qualityLevel.getValue();
- initMenu();
-
- if (sock != null) {
- String name = sock.getRemoteSocketAddress()+"::"+sock.getPort();
- vlog.info("Accepted connection from "+name);
- } else {
- if (vncServerName != null) {
- serverHost = Hostname.getHost(vncServerName);
- serverPort = Hostname.getPort(vncServerName);
- } else {
- ServerDialog dlg = new ServerDialog(options, vncServerName, this);
- if (!dlg.showDialog() || dlg.server.getSelectedItem().equals("")) {
- System.exit(1);
- }
- vncServerName = (String)dlg.server.getSelectedItem();
- serverHost = Hostname.getHost(vncServerName);
- serverPort = Hostname.getPort(vncServerName);
- }
-
- try {
- sock = new java.net.Socket(serverHost, serverPort);
- } catch (java.io.IOException e) {
- throw new Exception(e.toString());
- }
- vlog.info("connected to host "+serverHost+" port "+serverPort);
- }
-
- sameMachine = (sock.getLocalSocketAddress() == sock.getRemoteSocketAddress());
- try {
- sock.setTcpNoDelay(true);
- sock.setTrafficClass(0x10);
- setServerName(serverHost);
- jis = new JavaInStream(sock.getInputStream());
- jos = new JavaOutStream(sock.getOutputStream());
- } catch (java.net.SocketException e) {
- throw new Exception(e.toString());
- } catch (java.io.IOException e) {
- throw new Exception(e.toString());
- }
- setStreams(jis, jos);
- initialiseProtocol();
- }
-
- public boolean showMsgBox(int flags, String title, String text)
- {
- StringBuffer titleText = new StringBuffer("VNC Viewer: "+title);
-
- return true;
- }
-
- // deleteWindow() is called when the user closes the desktop or menu windows.
-
- void deleteWindow() {
- if (viewport != null)
- viewport.dispose();
- viewport = null;
- }
-
- // getUserPasswd() is called by the CSecurity object when it needs us to read
- // a password from the user.
-
- public final boolean getUserPasswd(StringBuffer user, StringBuffer passwd) {
- String title = ("VNC Authentication ["
- +csecurity.description() + "]");
- PasswdDialog dlg;
- if (user == null) {
- dlg = new PasswdDialog(title, (user == null), (passwd == null));
- } else {
- if ((passwd == null) && viewer.sendLocalUsername.getValue()) {
- user.append((String)System.getProperties().get("user.name"));
- return true;
- }
- dlg = new PasswdDialog(title, viewer.sendLocalUsername.getValue(),
- (passwd == null));
- }
- if (!dlg.showDialog()) return false;
- if (user != null) {
- if (viewer.sendLocalUsername.getValue()) {
- user.append((String)System.getProperties().get("user.name"));
- } else {
- user.append(dlg.userEntry.getText());
- }
- }
- if (passwd != null)
- passwd.append(dlg.passwdEntry.getText());
- return true;
- }
-
- // CConnection callback methods
-
- // serverInit() is called when the serverInit message has been received. At
- // this point we create the desktop window and display it. We also tell the
- // server the pixel format and encodings to use and request the first update.
- public void serverInit() {
- super.serverInit();
-
- // If using AutoSelect with old servers, start in FullColor
- // mode. See comment in autoSelectFormatAndEncoding.
- if (cp.beforeVersion(3, 8) && autoSelect) {
- fullColour = true;
- }
-
- serverPF = cp.pf();
- desktop = new DesktopWindow(cp.width, cp.height, serverPF, this);
- //desktopEventHandler = desktop.setEventHandler(this);
- //desktop.addEventMask(KeyPressMask | KeyReleaseMask);
- fullColourPF = desktop.getPF();
- if (!serverPF.trueColour)
- fullColour = true;
- recreateViewport();
- formatChange = true; encodingChange = true;
- requestNewUpdate();
- }
-
- // setDesktopSize() is called when the desktop size changes (including when
- // it is set initially).
- public void setDesktopSize(int w, int h) {
- super.setDesktopSize(w,h);
- resizeFramebuffer();
- }
-
- // setExtendedDesktopSize() is a more advanced version of setDesktopSize()
- public void setExtendedDesktopSize(int reason, int result, int w, int h,
- ScreenSet layout) {
- super.setExtendedDesktopSize(reason, result, w, h, layout);
-
- if ((reason == screenTypes.reasonClient) &&
- (result != screenTypes.resultSuccess)) {
- vlog.error("SetDesktopSize failed: "+result);
- return;
- }
-
+ }
+
+ public void setGeometry(int x, int y, int w, int h) {
+ pack();
+ if (cc.fullScreen) setSize(w, h);
+ setLocation(x, y);
+ setBackground(Color.BLACK);
+ }
+
+
+ CConn cc;
+ Graphics g;
+ JScrollPane sp;
+ static LogWriter vlog = new LogWriter("ViewportFrame");
+}
+
+public class CConn extends CConnection
+ implements UserPasswdGetter, UserMsgBox, OptionsDialogCallback
+{
+ ////////////////////////////////////////////////////////////////////
+ // The following methods are all called from the RFB thread
+
+ public CConn(VncViewer viewer_, java.net.Socket sock_,
+ String vncServerName, boolean reverse)
+ {
+ serverHost = null; serverPort = 0; sock = sock_; viewer = viewer_;
+ currentEncoding = Encodings.encodingTight; lastServerEncoding = -1;
+ fullColour = viewer.fullColour.getValue();
+ lowColourLevel = 2;
+ autoSelect = viewer.autoSelect.getValue();
+ shared = viewer.shared.getValue(); formatChange = false;
+ encodingChange = false; sameMachine = false;
+ fullScreen = viewer.fullScreen.getValue();
+ menuKey = Keysyms.F8;
+ options = new OptionsDialog(this);
+ clipboardDialog = new ClipboardDialog(this);
+ firstUpdate = true; pendingUpdate = false;
+
+ setShared(shared);
+ upg = this;
+ msg = this;
+
+ String encStr = viewer.preferredEncoding.getValue();
+ int encNum = Encodings.encodingNum(encStr);
+ if (encNum != -1) {
+ currentEncoding = encNum;
+ }
+ cp.supportsDesktopResize = true;
+ cp.supportsExtendedDesktopSize = true;
+ cp.supportsDesktopRename = true;
+ cp.supportsLocalCursor = viewer.useLocalCursor.getValue();
+ cp.customCompressLevel = viewer.customCompressLevel.getValue();
+ cp.compressLevel = viewer.compressLevel.getValue();
+ cp.noJpeg = viewer.noJpeg.getValue();
+ cp.qualityLevel = viewer.qualityLevel.getValue();
+ initMenu();
+
+ if (sock != null) {
+ String name = sock.getRemoteSocketAddress()+"::"+sock.getPort();
+ vlog.info("Accepted connection from "+name);
+ } else {
+ if (vncServerName != null) {
+ serverHost = Hostname.getHost(vncServerName);
+ serverPort = Hostname.getPort(vncServerName);
+ } else {
+ ServerDialog dlg = new ServerDialog(options, vncServerName, this);
+ if (!dlg.showDialog() || dlg.server.getSelectedItem().equals("")) {
+ System.exit(1);
+ }
+ vncServerName = (String)dlg.server.getSelectedItem();
+ serverHost = Hostname.getHost(vncServerName);
+ serverPort = Hostname.getPort(vncServerName);
+ }
+
+ try {
+ sock = new java.net.Socket(serverHost, serverPort);
+ } catch (java.io.IOException e) {
+ throw new Exception(e.toString());
+ }
+ vlog.info("connected to host "+serverHost+" port "+serverPort);
+ }
+
+ sameMachine = (sock.getLocalSocketAddress() == sock.getRemoteSocketAddress());
+ try {
+ sock.setTcpNoDelay(true);
+ sock.setTrafficClass(0x10);
+ setServerName(serverHost);
+ jis = new JavaInStream(sock.getInputStream());
+ jos = new JavaOutStream(sock.getOutputStream());
+ } catch (java.net.SocketException e) {
+ throw new Exception(e.toString());
+ } catch (java.io.IOException e) {
+ throw new Exception(e.toString());
+ }
+ setStreams(jis, jos);
+ initialiseProtocol();
+ }
+
+ public boolean showMsgBox(int flags, String title, String text)
+ {
+ StringBuffer titleText = new StringBuffer("VNC Viewer: "+title);
+
+ return true;
+ }
+
+ // deleteWindow() is called when the user closes the desktop or menu windows.
+
+ void deleteWindow() {
+ if (viewport != null)
+ viewport.dispose();
+ viewport = null;
+ }
+
+ // getUserPasswd() is called by the CSecurity object when it needs us to read
+ // a password from the user.
+
+ public final boolean getUserPasswd(StringBuffer user, StringBuffer passwd) {
+ String title = ("VNC Authentication ["
+ +csecurity.description() + "]");
+ PasswdDialog dlg;
+ if (user == null) {
+ dlg = new PasswdDialog(title, (user == null), (passwd == null));
+ } else {
+ if ((passwd == null) && viewer.sendLocalUsername.getValue()) {
+ user.append((String)System.getProperties().get("user.name"));
+ return true;
+ }
+ dlg = new PasswdDialog(title, viewer.sendLocalUsername.getValue(),
+ (passwd == null));
+ }
+ if (!dlg.showDialog()) return false;
+ if (user != null) {
+ if (viewer.sendLocalUsername.getValue()) {
+ user.append((String)System.getProperties().get("user.name"));
+ } else {
+ user.append(dlg.userEntry.getText());
+ }
+ }
+ if (passwd != null)
+ passwd.append(dlg.passwdEntry.getText());
+ return true;
+ }
+
+ // CConnection callback methods
+
+ // serverInit() is called when the serverInit message has been received. At
+ // this point we create the desktop window and display it. We also tell the
+ // server the pixel format and encodings to use and request the first update.
+ public void serverInit() {
+ super.serverInit();
+
+ // If using AutoSelect with old servers, start in FullColor
+ // mode. See comment in autoSelectFormatAndEncoding.
+ if (cp.beforeVersion(3, 8) && autoSelect) {
+ fullColour = true;
+ }
+
+ serverPF = cp.pf();
+ desktop = new DesktopWindow(cp.width, cp.height, serverPF, this);
+ //desktopEventHandler = desktop.setEventHandler(this);
+ //desktop.addEventMask(KeyPressMask | KeyReleaseMask);
+ fullColourPF = desktop.getPF();
+ if (!serverPF.trueColour)
+ fullColour = true;
+ recreateViewport();
+ formatChange = true; encodingChange = true;
+ requestNewUpdate();
+ }
+
+ // setDesktopSize() is called when the desktop size changes (including when
+ // it is set initially).
+ public void setDesktopSize(int w, int h) {
+ super.setDesktopSize(w,h);
resizeFramebuffer();
- }
-
+ }
+
+ // setExtendedDesktopSize() is a more advanced version of setDesktopSize()
+ public void setExtendedDesktopSize(int reason, int result, int w, int h,
+ ScreenSet layout) {
+ super.setExtendedDesktopSize(reason, result, w, h, layout);
+
+ if ((reason == screenTypes.reasonClient) &&
+ (result != screenTypes.resultSuccess)) {
+ vlog.error("SetDesktopSize failed: "+result);
+ return;
+ }
+
+ resizeFramebuffer();
+ }
+
// clientRedirect() migrates the client to another host/port
public void clientRedirect(int port, String host,
String x509subject) {
@@ -301,899 +301,899 @@ public class CConn extends CConnection
}
}
- // setName() is called when the desktop name changes
- public void setName(String name) {
- super.setName(name);
-
- if (viewport != null) {
- viewport.setTitle("TigerVNC: "+name);
- }
- }
-
- // framebufferUpdateStart() is called at the beginning of an update.
- // Here we try to send out a new framebuffer update request so that the
- // next update can be sent out in parallel with us decoding the current
- // one. We cannot do this if we're in the middle of a format change
- // though.
- public void framebufferUpdateStart() {
- if (!formatChange) {
- pendingUpdate = true;
- requestNewUpdate();
- } else
- pendingUpdate = false;
- }
-
- // framebufferUpdateEnd() is called at the end of an update.
- // For each rectangle, the FdInStream will have timed the speed
- // of the connection, allowing us to select format and encoding
- // appropriately, and then request another incremental update.
- public void framebufferUpdateEnd() {
- desktop.framebufferUpdateEnd();
-
- if (firstUpdate) {
- int width, height;
-
- if (cp.supportsSetDesktopSize &&
- viewer.desktopSize.getValue() != null &&
- viewer.desktopSize.getValue().split("x").length == 2) {
- width = Integer.parseInt(viewer.desktopSize.getValue().split("x")[0]);
- height = Integer.parseInt(viewer.desktopSize.getValue().split("x")[1]);
- ScreenSet layout;
-
- layout = cp.screenLayout;
-
- if (layout.num_screens() == 0)
- layout.add_screen(new Screen());
- else if (layout.num_screens() != 1) {
-
- while (true) {
- Iterator iter = layout.screens.iterator();
- Screen screen = (Screen)iter.next();
-
- if (!iter.hasNext())
- break;
-
- layout.remove_screen(screen.id);
- }
- }
-
- Screen screen0 = (Screen)layout.screens.iterator().next();
- screen0.dimensions.tl.x = 0;
- screen0.dimensions.tl.y = 0;
- screen0.dimensions.br.x = width;
- screen0.dimensions.br.y = height;
-
- writer().writeSetDesktopSize(width, height, layout);
- }
-
- firstUpdate = false;
- }
-
- // A format change prevented us from sending this before the update,
- // so make sure to send it now.
- if (formatChange && !pendingUpdate)
- requestNewUpdate();
-
- // Compute new settings based on updated bandwidth values
- if (autoSelect)
- autoSelectFormatAndEncoding();
- }
-
- // The rest of the callbacks are fairly self-explanatory...
-
- public void setColourMapEntries(int firstColour, int nColours, int[] rgbs) {
- desktop.setColourMapEntries(firstColour, nColours, rgbs);
- }
-
- public void bell() { desktop.getToolkit().beep(); }
-
- public void serverCutText(String str, int len) {
- if (viewer.acceptClipboard.getValue())
- clipboardDialog.serverCutText(str, len);
- }
-
- // We start timing on beginRect and stop timing on endRect, to
- // avoid skewing the bandwidth estimation as a result of the server
- // being slow or the network having high latency
- public void beginRect(Rect r, int encoding) {
- ((JavaInStream)getInStream()).startTiming();
- if (encoding != Encodings.encodingCopyRect) {
- lastServerEncoding = encoding;
- }
- }
-
- public void endRect(Rect r, int encoding) {
- ((JavaInStream)getInStream()).stopTiming();
- }
-
- public void fillRect(Rect r, int p) {
- desktop.fillRect(r.tl.x, r.tl.y, r.width(), r.height(), p);
- }
- public void imageRect(Rect r, int[] p) {
- desktop.imageRect(r.tl.x, r.tl.y, r.width(), r.height(), p);
- }
- public void copyRect(Rect r, int sx, int sy) {
- desktop.copyRect(r.tl.x, r.tl.y, r.width(), r.height(), sx, sy);
- }
-
- public void setCursor(int width, int height, Point hotspot,
- int[] data, byte[] mask) {
- desktop.setCursor(width, height, hotspot, data, mask);
- }
-
- private void resizeFramebuffer()
- {
- if ((cp.width == 0) && (cp.height == 0))
- return;
- if (desktop == null)
- return;
- if ((desktop.width() == cp.width) && (desktop.height() == cp.height))
- return;
-
- desktop.resize();
- recreateViewport();
- }
-
- // recreateViewport() recreates our top-level window. This seems to be
- // better than attempting to resize the existing window, at least with
- // various X window managers.
-
- private void recreateViewport()
- {
- if (viewport != null) viewport.dispose();
- viewport = new ViewportFrame(cp.name(), this);
- viewport.setUndecorated(fullScreen);
+ // setName() is called when the desktop name changes
+ public void setName(String name) {
+ super.setName(name);
+
+ if (viewport != null) {
+ viewport.setTitle("TigerVNC: "+name);
+ }
+ }
+
+ // framebufferUpdateStart() is called at the beginning of an update.
+ // Here we try to send out a new framebuffer update request so that the
+ // next update can be sent out in parallel with us decoding the current
+ // one. We cannot do this if we're in the middle of a format change
+ // though.
+ public void framebufferUpdateStart() {
+ if (!formatChange) {
+ pendingUpdate = true;
+ requestNewUpdate();
+ } else
+ pendingUpdate = false;
+ }
+
+ // framebufferUpdateEnd() is called at the end of an update.
+ // For each rectangle, the FdInStream will have timed the speed
+ // of the connection, allowing us to select format and encoding
+ // appropriately, and then request another incremental update.
+ public void framebufferUpdateEnd() {
+ desktop.framebufferUpdateEnd();
+
+ if (firstUpdate) {
+ int width, height;
+
+ if (cp.supportsSetDesktopSize &&
+ viewer.desktopSize.getValue() != null &&
+ viewer.desktopSize.getValue().split("x").length == 2) {
+ width = Integer.parseInt(viewer.desktopSize.getValue().split("x")[0]);
+ height = Integer.parseInt(viewer.desktopSize.getValue().split("x")[1]);
+ ScreenSet layout;
+
+ layout = cp.screenLayout;
+
+ if (layout.num_screens() == 0)
+ layout.add_screen(new Screen());
+ else if (layout.num_screens() != 1) {
+
+ while (true) {
+ Iterator iter = layout.screens.iterator();
+ Screen screen = (Screen)iter.next();
+
+ if (!iter.hasNext())
+ break;
+
+ layout.remove_screen(screen.id);
+ }
+ }
+
+ Screen screen0 = (Screen)layout.screens.iterator().next();
+ screen0.dimensions.tl.x = 0;
+ screen0.dimensions.tl.y = 0;
+ screen0.dimensions.br.x = width;
+ screen0.dimensions.br.y = height;
+
+ writer().writeSetDesktopSize(width, height, layout);
+ }
+
+ firstUpdate = false;
+ }
+
+ // A format change prevented us from sending this before the update,
+ // so make sure to send it now.
+ if (formatChange && !pendingUpdate)
+ requestNewUpdate();
+
+ // Compute new settings based on updated bandwidth values
+ if (autoSelect)
+ autoSelectFormatAndEncoding();
+ }
+
+ // The rest of the callbacks are fairly self-explanatory...
+
+ public void setColourMapEntries(int firstColour, int nColours, int[] rgbs) {
+ desktop.setColourMapEntries(firstColour, nColours, rgbs);
+ }
+
+ public void bell() { desktop.getToolkit().beep(); }
+
+ public void serverCutText(String str, int len) {
+ if (viewer.acceptClipboard.getValue())
+ clipboardDialog.serverCutText(str, len);
+ }
+
+ // We start timing on beginRect and stop timing on endRect, to
+ // avoid skewing the bandwidth estimation as a result of the server
+ // being slow or the network having high latency
+ public void beginRect(Rect r, int encoding) {
+ ((JavaInStream)getInStream()).startTiming();
+ if (encoding != Encodings.encodingCopyRect) {
+ lastServerEncoding = encoding;
+ }
+ }
+
+ public void endRect(Rect r, int encoding) {
+ ((JavaInStream)getInStream()).stopTiming();
+ }
+
+ public void fillRect(Rect r, int p) {
+ desktop.fillRect(r.tl.x, r.tl.y, r.width(), r.height(), p);
+ }
+ public void imageRect(Rect r, int[] p) {
+ desktop.imageRect(r.tl.x, r.tl.y, r.width(), r.height(), p);
+ }
+ public void copyRect(Rect r, int sx, int sy) {
+ desktop.copyRect(r.tl.x, r.tl.y, r.width(), r.height(), sx, sy);
+ }
+
+ public void setCursor(int width, int height, Point hotspot,
+ int[] data, byte[] mask) {
+ desktop.setCursor(width, height, hotspot, data, mask);
+ }
+
+ private void resizeFramebuffer()
+ {
+ if ((cp.width == 0) && (cp.height == 0))
+ return;
+ if (desktop == null)
+ return;
+ if ((desktop.width() == cp.width) && (desktop.height() == cp.height))
+ return;
+
+ desktop.resize();
+ recreateViewport();
+ }
+
+ // recreateViewport() recreates our top-level window. This seems to be
+ // better than attempting to resize the existing window, at least with
+ // various X window managers.
+
+ private void recreateViewport()
+ {
+ if (viewport != null) viewport.dispose();
+ viewport = new ViewportFrame(cp.name(), this);
+ viewport.setUndecorated(fullScreen);
desktop.setViewport(viewport);
- ClassLoader loader = this.getClass().getClassLoader();
- URL url = loader.getResource("com/tigervnc/vncviewer/tigervnc.ico");
- ImageIcon icon = null;
- if (url != null) {
- icon = new ImageIcon(url);
- viewport.setIconImage(icon.getImage());
- }
- viewport.addChild(desktop);
- reconfigureViewport();
- viewport.setVisible(true);
- desktop.initGraphics();
- desktop.requestFocusInWindow();
- }
-
- private void reconfigureViewport()
- {
- //viewport->setMaxSize(cp.width, cp.height);
- if (fullScreen) {
- Dimension dpySize = viewport.getToolkit().getScreenSize();
- viewport.setExtendedState(JFrame.MAXIMIZED_BOTH);
- viewport.setGeometry(0, 0, dpySize.width, dpySize.height);
- } else {
- int w = cp.width;
- int h = cp.height;
- Dimension dpySize = viewport.getToolkit().getScreenSize();
- int wmDecorationWidth = 0;
- int wmDecorationHeight = 24;
- if (w + wmDecorationWidth >= dpySize.width)
- w = dpySize.width - wmDecorationWidth;
- if (h + wmDecorationHeight >= dpySize.height)
- h = dpySize.height - wmDecorationHeight;
-
- int x = (dpySize.width - w - wmDecorationWidth) / 2;
- int y = (dpySize.height - h - wmDecorationHeight)/2;
-
- viewport.setExtendedState(JFrame.NORMAL);
- viewport.setGeometry(x, y, w, h);
- }
- }
-
- // autoSelectFormatAndEncoding() chooses the format and encoding appropriate
- // to the connection speed:
- //
- // First we wait for at least one second of bandwidth measurement.
- //
- // Above 16Mbps (i.e. LAN), we choose the second highest JPEG quality,
- // which should be perceptually lossless.
- //
- // If the bandwidth is below that, we choose a more lossy JPEG quality.
- //
- // If the bandwidth drops below 256 Kbps, we switch to palette mode.
- //
- // Note: The system here is fairly arbitrary and should be replaced
- // with something more intelligent at the server end.
- //
- private void autoSelectFormatAndEncoding() {
- long kbitsPerSecond = ((JavaInStream)getInStream()).kbitsPerSecond();
- long timeWaited = ((JavaInStream)getInStream()).timeWaited();
- boolean newFullColour = fullColour;
- int newQualityLevel = cp.qualityLevel;
-
- // Always use Tight
- if (currentEncoding != Encodings.encodingTight) {
- currentEncoding = Encodings.encodingTight;
- encodingChange = true;
- }
-
- // Check that we have a decent bandwidth measurement
- if ((kbitsPerSecond == 0) || (timeWaited < 10000))
- return;
-
- // Select appropriate quality level
- if (!cp.noJpeg) {
- if (kbitsPerSecond > 16000)
- newQualityLevel = 8;
- else
- newQualityLevel = 6;
-
- if (newQualityLevel != cp.qualityLevel) {
- vlog.info("Throughput "+kbitsPerSecond+
- " kbit/s - changing to quality "+newQualityLevel);
- cp.qualityLevel = newQualityLevel;
- viewer.qualityLevel.setParam(Integer.toString(newQualityLevel));
- encodingChange = true;
- }
- }
-
- if (cp.beforeVersion(3, 8)) {
- // Xvnc from TightVNC 1.2.9 sends out FramebufferUpdates with
- // cursors "asynchronously". If this happens in the middle of a
- // pixel format change, the server will encode the cursor with
- // the old format, but the client will try to decode it
- // according to the new format. This will lead to a
- // crash. Therefore, we do not allow automatic format change for
- // old servers.
- return;
- }
-
- // Select best color level
- newFullColour = (kbitsPerSecond > 256);
- if (newFullColour != fullColour) {
- vlog.info("Throughput "+kbitsPerSecond+
- " kbit/s - full color is now "+
- (newFullColour ? "enabled" : "disabled"));
- fullColour = newFullColour;
- formatChange = true;
- }
- }
-
- // requestNewUpdate() requests an update from the server, having set the
- // format and encoding appropriately.
- private void requestNewUpdate()
- {
- if (formatChange) {
+ ClassLoader loader = this.getClass().getClassLoader();
+ URL url = loader.getResource("com/tigervnc/vncviewer/tigervnc.ico");
+ ImageIcon icon = null;
+ if (url != null) {
+ icon = new ImageIcon(url);
+ viewport.setIconImage(icon.getImage());
+ }
+ viewport.addChild(desktop);
+ reconfigureViewport();
+ viewport.setVisible(true);
+ desktop.initGraphics();
+ desktop.requestFocusInWindow();
+ }
+
+ private void reconfigureViewport()
+ {
+ //viewport->setMaxSize(cp.width, cp.height);
+ if (fullScreen) {
+ Dimension dpySize = viewport.getToolkit().getScreenSize();
+ viewport.setExtendedState(JFrame.MAXIMIZED_BOTH);
+ viewport.setGeometry(0, 0, dpySize.width, dpySize.height);
+ } else {
+ int w = cp.width;
+ int h = cp.height;
+ Dimension dpySize = viewport.getToolkit().getScreenSize();
+ int wmDecorationWidth = 0;
+ int wmDecorationHeight = 24;
+ if (w + wmDecorationWidth >= dpySize.width)
+ w = dpySize.width - wmDecorationWidth;
+ if (h + wmDecorationHeight >= dpySize.height)
+ h = dpySize.height - wmDecorationHeight;
+
+ int x = (dpySize.width - w - wmDecorationWidth) / 2;
+ int y = (dpySize.height - h - wmDecorationHeight)/2;
+
+ viewport.setExtendedState(JFrame.NORMAL);
+ viewport.setGeometry(x, y, w, h);
+ }
+ }
+
+ // autoSelectFormatAndEncoding() chooses the format and encoding appropriate
+ // to the connection speed:
+ //
+ // First we wait for at least one second of bandwidth measurement.
+ //
+ // Above 16Mbps (i.e. LAN), we choose the second highest JPEG quality,
+ // which should be perceptually lossless.
+ //
+ // If the bandwidth is below that, we choose a more lossy JPEG quality.
+ //
+ // If the bandwidth drops below 256 Kbps, we switch to palette mode.
+ //
+ // Note: The system here is fairly arbitrary and should be replaced
+ // with something more intelligent at the server end.
+ //
+ private void autoSelectFormatAndEncoding() {
+ long kbitsPerSecond = ((JavaInStream)getInStream()).kbitsPerSecond();
+ long timeWaited = ((JavaInStream)getInStream()).timeWaited();
+ boolean newFullColour = fullColour;
+ int newQualityLevel = cp.qualityLevel;
+
+ // Always use Tight
+ if (currentEncoding != Encodings.encodingTight) {
+ currentEncoding = Encodings.encodingTight;
+ encodingChange = true;
+ }
+
+ // Check that we have a decent bandwidth measurement
+ if ((kbitsPerSecond == 0) || (timeWaited < 10000))
+ return;
+
+ // Select appropriate quality level
+ if (!cp.noJpeg) {
+ if (kbitsPerSecond > 16000)
+ newQualityLevel = 8;
+ else
+ newQualityLevel = 6;
+
+ if (newQualityLevel != cp.qualityLevel) {
+ vlog.info("Throughput "+kbitsPerSecond+
+ " kbit/s - changing to quality "+newQualityLevel);
+ cp.qualityLevel = newQualityLevel;
+ viewer.qualityLevel.setParam(Integer.toString(newQualityLevel));
+ encodingChange = true;
+ }
+ }
+
+ if (cp.beforeVersion(3, 8)) {
+ // Xvnc from TightVNC 1.2.9 sends out FramebufferUpdates with
+ // cursors "asynchronously". If this happens in the middle of a
+ // pixel format change, the server will encode the cursor with
+ // the old format, but the client will try to decode it
+ // according to the new format. This will lead to a
+ // crash. Therefore, we do not allow automatic format change for
+ // old servers.
+ return;
+ }
+
+ // Select best color level
+ newFullColour = (kbitsPerSecond > 256);
+ if (newFullColour != fullColour) {
+ vlog.info("Throughput "+kbitsPerSecond+
+ " kbit/s - full color is now "+
+ (newFullColour ? "enabled" : "disabled"));
+ fullColour = newFullColour;
+ formatChange = true;
+ }
+ }
+
+ // requestNewUpdate() requests an update from the server, having set the
+ // format and encoding appropriately.
+ private void requestNewUpdate()
+ {
+ if (formatChange) {
/* Catch incorrect requestNewUpdate calls */
assert(pendingUpdate == false);
- if (fullColour) {
- desktop.setPF(fullColourPF);
- } else {
- if (lowColourLevel == 0) {
- desktop.setPF(new PixelFormat(8,3,false,true,1,1,1,2,1,0));
- } else if (lowColourLevel == 1) {
- desktop.setPF(new PixelFormat(8,6,false,true,3,3,3,4,2,0));
- } else {
- desktop.setPF(new PixelFormat(8,8,false,true,7,7,3,0,3,6));
- }
- }
- String str = desktop.getPF().print();
- vlog.info("Using pixel format "+str);
- cp.setPF(desktop.getPF());
- synchronized (this) {
- writer().writeSetPixelFormat(cp.pf());
- }
- }
- checkEncodings();
- synchronized (this) {
- writer().writeFramebufferUpdateRequest(new Rect(0,0,cp.width,cp.height),
- !formatChange);
- }
- formatChange = false;
- }
-
-
- ////////////////////////////////////////////////////////////////////
- // The following methods are all called from the GUI thread
-
- // close() closes the socket, thus waking up the RFB thread.
- public void close() {
- try {
- shuttingDown = true;
- sock.close();
- } catch (java.io.IOException e) {
- e.printStackTrace();
- }
- }
-
- // Menu callbacks. These are guaranteed only to be called after serverInit()
- // has been called, since the menu is only accessible from the DesktopWindow
-
- private void initMenu() {
- menu = new F8Menu(this);
- }
-
- void showMenu(int x, int y) {
- String os = System.getProperty("os.name");
- if (os.startsWith("Windows"))
- com.sun.java.swing.plaf.windows.WindowsLookAndFeel.setMnemonicHidden(false);
- menu.show(desktop, x, y);
- }
-
- void showAbout() {
- InputStream stream = cl.getResourceAsStream("com/tigervnc/vncviewer/timestamp");
- String pkgDate = "";
- String pkgTime = "";
- try {
- Manifest manifest = new Manifest(stream);
- Attributes attributes = manifest.getMainAttributes();
- pkgDate = attributes.getValue("Package-Date");
- pkgTime = attributes.getValue("Package-Time");
- } catch (IOException e) { }
- JOptionPane.showMessageDialog((viewport != null ? viewport : null),
- VncViewer.about1+"\n"
- +"Built on "+pkgDate+" at "+pkgTime+"\n"
- +VncViewer.about2+"\n"
- +VncViewer.about3,
- "About TigerVNC Viewer for Java",
- JOptionPane.INFORMATION_MESSAGE,
- logo);
- }
-
- void showInfo() {
- JOptionPane.showMessageDialog(viewport,
- "Desktop name: "+cp.name()+"\n"
- +"Host: "+serverHost+":"+sock.getPort()+"\n"
- +"Size: "+cp.width+"x"+cp.height+"\n"
- +"Pixel format: "+desktop.getPF().print()+"\n"
- +"(server default "+serverPF.print()+")\n"
- +"Requested encoding: "+Encodings.encodingName(currentEncoding)+"\n"
- +"Last used encoding: "+Encodings.encodingName(lastServerEncoding)+"\n"
- +"Line speed estimate: "+((JavaInStream)getInStream()).kbitsPerSecond()+" kbit/s"+"\n"
- +"Protocol version: "+cp.majorVersion+"."+cp.minorVersion+"\n"
- +"Security method: "+Security.secTypeName(csecurity.getType())
- +" ["+csecurity.description()+"]",
- "VNC connection info",
- JOptionPane.PLAIN_MESSAGE);
- }
-
- synchronized public void refresh() {
- writer().writeFramebufferUpdateRequest(new Rect(0,0,cp.width,cp.height), false);
+ if (fullColour) {
+ desktop.setPF(fullColourPF);
+ } else {
+ if (lowColourLevel == 0) {
+ desktop.setPF(new PixelFormat(8,3,false,true,1,1,1,2,1,0));
+ } else if (lowColourLevel == 1) {
+ desktop.setPF(new PixelFormat(8,6,false,true,3,3,3,4,2,0));
+ } else {
+ desktop.setPF(new PixelFormat(8,8,false,true,7,7,3,0,3,6));
+ }
+ }
+ String str = desktop.getPF().print();
+ vlog.info("Using pixel format "+str);
+ cp.setPF(desktop.getPF());
+ synchronized (this) {
+ writer().writeSetPixelFormat(cp.pf());
+ }
+ }
+ checkEncodings();
+ synchronized (this) {
+ writer().writeFramebufferUpdateRequest(new Rect(0,0,cp.width,cp.height),
+ !formatChange);
+ }
+ formatChange = false;
+ }
+
+
+ ////////////////////////////////////////////////////////////////////
+ // The following methods are all called from the GUI thread
+
+ // close() closes the socket, thus waking up the RFB thread.
+ public void close() {
+ try {
+ shuttingDown = true;
+ sock.close();
+ } catch (java.io.IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // Menu callbacks. These are guaranteed only to be called after serverInit()
+ // has been called, since the menu is only accessible from the DesktopWindow
+
+ private void initMenu() {
+ menu = new F8Menu(this);
+ }
+
+ void showMenu(int x, int y) {
+ String os = System.getProperty("os.name");
+ if (os.startsWith("Windows"))
+ com.sun.java.swing.plaf.windows.WindowsLookAndFeel.setMnemonicHidden(false);
+ menu.show(desktop, x, y);
+ }
+
+ void showAbout() {
+ InputStream stream = cl.getResourceAsStream("com/tigervnc/vncviewer/timestamp");
+ String pkgDate = "";
+ String pkgTime = "";
+ try {
+ Manifest manifest = new Manifest(stream);
+ Attributes attributes = manifest.getMainAttributes();
+ pkgDate = attributes.getValue("Package-Date");
+ pkgTime = attributes.getValue("Package-Time");
+ } catch (IOException e) { }
+ JOptionPane.showMessageDialog((viewport != null ? viewport : null),
+ VncViewer.about1+"\n"
+ +"Built on "+pkgDate+" at "+pkgTime+"\n"
+ +VncViewer.about2+"\n"
+ +VncViewer.about3,
+ "About TigerVNC Viewer for Java",
+ JOptionPane.INFORMATION_MESSAGE,
+ logo);
+ }
+
+ void showInfo() {
+ JOptionPane.showMessageDialog(viewport,
+ "Desktop name: "+cp.name()+"\n"
+ +"Host: "+serverHost+":"+sock.getPort()+"\n"
+ +"Size: "+cp.width+"x"+cp.height+"\n"
+ +"Pixel format: "+desktop.getPF().print()+"\n"
+ +"(server default "+serverPF.print()+")\n"
+ +"Requested encoding: "+Encodings.encodingName(currentEncoding)+"\n"
+ +"Last used encoding: "+Encodings.encodingName(lastServerEncoding)+"\n"
+ +"Line speed estimate: "+((JavaInStream)getInStream()).kbitsPerSecond()+" kbit/s"+"\n"
+ +"Protocol version: "+cp.majorVersion+"."+cp.minorVersion+"\n"
+ +"Security method: "+Security.secTypeName(csecurity.getType())
+ +" ["+csecurity.description()+"]",
+ "VNC connection info",
+ JOptionPane.PLAIN_MESSAGE);
+ }
+
+ synchronized public void refresh() {
+ writer().writeFramebufferUpdateRequest(new Rect(0,0,cp.width,cp.height), false);
pendingUpdate = true;
- }
-
-
- // OptionsDialogCallback. setOptions() sets the options dialog's checkboxes
- // etc to reflect our flags. getOptions() sets our flags according to the
- // options dialog's checkboxes. They are both called from the GUI thread.
- // Some of the flags are also accessed by the RFB thread. I believe that
- // reading and writing boolean and int values in java is atomic, so there is
- // no need for synchronization.
-
- public void setOptions() {
- int digit;
- options.autoSelect.setSelected(autoSelect);
- options.fullColour.setSelected(fullColour);
- options.veryLowColour.setSelected(!fullColour && lowColourLevel == 0);
- options.lowColour.setSelected(!fullColour && lowColourLevel == 1);
- options.mediumColour.setSelected(!fullColour && lowColourLevel == 2);
- options.tight.setSelected(currentEncoding == Encodings.encodingTight);
- options.zrle.setSelected(currentEncoding == Encodings.encodingZRLE);
- options.hextile.setSelected(currentEncoding == Encodings.encodingHextile);
- options.raw.setSelected(currentEncoding == Encodings.encodingRaw);
-
- options.customCompressLevel.setSelected(viewer.customCompressLevel.getValue());
- digit = 0 + viewer.compressLevel.getValue();
- options.compressLevel.setSelectedItem(digit);
- options.noJpeg.setSelected(!viewer.noJpeg.getValue());
- digit = 0 + viewer.qualityLevel.getValue();
- options.qualityLevel.setSelectedItem(digit);
-
- options.viewOnly.setSelected(viewer.viewOnly.getValue());
- options.acceptClipboard.setSelected(viewer.acceptClipboard.getValue());
- options.sendClipboard.setSelected(viewer.sendClipboard.getValue());
- options.menuKey.setSelectedIndex(menuKey-0xFFBE);
-
- if (state() == RFBSTATE_NORMAL) {
- options.shared.setEnabled(false);
- options.secVeNCrypt.setEnabled(false);
- options.encNone.setEnabled(false);
- options.encTLS.setEnabled(false);
- options.encX509.setEnabled(false);
- options.ca.setEnabled(false);
- options.crl.setEnabled(false);
- options.secIdent.setEnabled(false);
- options.secNone.setEnabled(false);
- options.secVnc.setEnabled(false);
- options.secPlain.setEnabled(false);
- options.sendLocalUsername.setEnabled(false);
- } else {
- options.shared.setSelected(shared);
-
- /* Process non-VeNCrypt sectypes */
- java.util.List<Integer> secTypes = new ArrayList<Integer>();
- secTypes = security.GetEnabledSecTypes();
- for (Iterator i = secTypes.iterator(); i.hasNext();) {
- switch ((Integer)i.next()) {
- case Security.secTypeVeNCrypt:
- options.secVeNCrypt.setSelected(true);
- break;
- case Security.secTypeNone:
- options.encNone.setSelected(true);
- options.secNone.setSelected(true);
- break;
- case Security.secTypeVncAuth:
- options.encNone.setSelected(true);
- options.secVnc.setSelected(true);
- break;
- }
- }
-
- /* Process VeNCrypt subtypes */
- if (options.secVeNCrypt.isSelected()) {
- java.util.List<Integer> secTypesExt = new ArrayList<Integer>();
- secTypesExt = security.GetEnabledExtSecTypes();
- for (Iterator iext = secTypesExt.iterator(); iext.hasNext();) {
- switch ((Integer)iext.next()) {
- case Security.secTypePlain:
- options.secPlain.setSelected(true);
- options.sendLocalUsername.setSelected(true);
- break;
- case Security.secTypeIdent:
- options.secIdent.setSelected(true);
- options.sendLocalUsername.setSelected(true);
- break;
- case Security.secTypeTLSNone:
- options.encTLS.setSelected(true);
- options.secNone.setSelected(true);
- break;
- case Security.secTypeTLSVnc:
- options.encTLS.setSelected(true);
- options.secVnc.setSelected(true);
- break;
- case Security.secTypeTLSPlain:
- options.encTLS.setSelected(true);
- options.secPlain.setSelected(true);
- options.sendLocalUsername.setSelected(true);
- break;
- case Security.secTypeTLSIdent:
- options.encTLS.setSelected(true);
- options.secIdent.setSelected(true);
- options.sendLocalUsername.setSelected(true);
- break;
- case Security.secTypeX509None:
- options.encX509.setSelected(true);
- options.secNone.setSelected(true);
- break;
- case Security.secTypeX509Vnc:
- options.encX509.setSelected(true);
- options.secVnc.setSelected(true);
- break;
- case Security.secTypeX509Plain:
- options.encX509.setSelected(true);
- options.secPlain.setSelected(true);
- options.sendLocalUsername.setSelected(true);
- break;
- case Security.secTypeX509Ident:
- options.encX509.setSelected(true);
- options.secIdent.setSelected(true);
- options.sendLocalUsername.setSelected(true);
- break;
- }
- }
- }
- options.sendLocalUsername.setEnabled(options.secPlain.isSelected()||
- options.secIdent.isSelected());
- }
-
- options.fullScreen.setSelected(fullScreen);
- options.useLocalCursor.setSelected(viewer.useLocalCursor.getValue());
- options.fastCopyRect.setSelected(viewer.fastCopyRect.getValue());
- }
-
- public void getOptions() {
- autoSelect = options.autoSelect.isSelected();
- if (fullColour != options.fullColour.isSelected())
- formatChange = true;
- fullColour = options.fullColour.isSelected();
- if (!fullColour) {
- int newLowColourLevel = (options.veryLowColour.isSelected() ? 0 :
- options.lowColour.isSelected() ? 1 : 2);
- if (newLowColourLevel != lowColourLevel) {
- lowColourLevel = newLowColourLevel;
- formatChange = true;
- }
- }
- int newEncoding = (options.zrle.isSelected() ? Encodings.encodingZRLE :
- options.hextile.isSelected() ? Encodings.encodingHextile :
- options.tight.isSelected() ? Encodings.encodingTight :
- Encodings.encodingRaw);
- if (newEncoding != currentEncoding) {
- currentEncoding = newEncoding;
- encodingChange = true;
- }
-
- viewer.customCompressLevel.setParam(options.customCompressLevel.isSelected());
- if (cp.customCompressLevel != viewer.customCompressLevel.getValue()) {
- cp.customCompressLevel = viewer.customCompressLevel.getValue();
- encodingChange = true;
- }
- viewer.compressLevel.setParam(options.compressLevel.getSelectedItem().toString());
- if (cp.compressLevel != viewer.compressLevel.getValue()) {
- cp.compressLevel = viewer.compressLevel.getValue();
- encodingChange = true;
- }
- viewer.noJpeg.setParam(!options.noJpeg.isSelected());
- if (cp.noJpeg != viewer.noJpeg.getValue()) {
- cp.noJpeg = viewer.noJpeg.getValue();
- encodingChange = true;
- }
- viewer.qualityLevel.setParam(options.qualityLevel.getSelectedItem().toString());
- if (cp.qualityLevel != viewer.qualityLevel.getValue()) {
- cp.qualityLevel = viewer.qualityLevel.getValue();
- encodingChange = true;
- }
- viewer.sendLocalUsername.setParam(options.sendLocalUsername.isSelected());
-
- viewer.viewOnly.setParam(options.viewOnly.isSelected());
- viewer.acceptClipboard.setParam(options.acceptClipboard.isSelected());
- viewer.sendClipboard.setParam(options.sendClipboard.isSelected());
- clipboardDialog.setSendingEnabled(viewer.sendClipboard.getValue());
- menuKey = (int)(options.menuKey.getSelectedIndex()+0xFFBE);
- F8Menu.f8.setLabel("Send F"+(menuKey-Keysyms.F1+1));
-
- shared = options.shared.isSelected();
- setShared(shared);
- viewer.useLocalCursor.setParam(options.useLocalCursor.isSelected());
- if (cp.supportsLocalCursor != viewer.useLocalCursor.getValue()) {
- cp.supportsLocalCursor = viewer.useLocalCursor.getValue();
- encodingChange = true;
- if (desktop != null)
- desktop.resetLocalCursor();
- }
-
- checkEncodings();
-
- if (state() != RFBSTATE_NORMAL) {
- /* Process security types which don't use encryption */
- if (options.encNone.isSelected()) {
- if (options.secNone.isSelected())
- Security.EnableSecType(Security.secTypeNone);
- if (options.secVnc.isSelected())
- Security.EnableSecType(Security.secTypeVncAuth);
- if (options.secPlain.isSelected())
- Security.EnableSecType(Security.secTypePlain);
- if (options.secIdent.isSelected())
- Security.EnableSecType(Security.secTypeIdent);
- } else {
- Security.DisableSecType(Security.secTypeNone);
- Security.DisableSecType(Security.secTypeVncAuth);
- Security.DisableSecType(Security.secTypePlain);
- Security.DisableSecType(Security.secTypeIdent);
- }
-
- /* Process security types which use TLS encryption */
- if (options.encTLS.isSelected()) {
- if (options.secNone.isSelected())
- Security.EnableSecType(Security.secTypeTLSNone);
- if (options.secVnc.isSelected())
- Security.EnableSecType(Security.secTypeTLSVnc);
- if (options.secPlain.isSelected())
- Security.EnableSecType(Security.secTypeTLSPlain);
- if (options.secIdent.isSelected())
- Security.EnableSecType(Security.secTypeTLSIdent);
- } else {
- Security.DisableSecType(Security.secTypeTLSNone);
- Security.DisableSecType(Security.secTypeTLSVnc);
- Security.DisableSecType(Security.secTypeTLSPlain);
- Security.DisableSecType(Security.secTypeTLSIdent);
- }
-
- /* Process security types which use X509 encryption */
- if (options.encX509.isSelected()) {
- if (options.secNone.isSelected())
- Security.EnableSecType(Security.secTypeX509None);
- if (options.secVnc.isSelected())
- Security.EnableSecType(Security.secTypeX509Vnc);
- if (options.secPlain.isSelected())
- Security.EnableSecType(Security.secTypeX509Plain);
- if (options.secIdent.isSelected())
- Security.EnableSecType(Security.secTypeX509Ident);
- } else {
- Security.DisableSecType(Security.secTypeX509None);
- Security.DisableSecType(Security.secTypeX509Vnc);
- Security.DisableSecType(Security.secTypeX509Plain);
- Security.DisableSecType(Security.secTypeX509Ident);
- }
-
- /* Process *None security types */
- if (options.secNone.isSelected()) {
- if (options.encNone.isSelected())
- Security.EnableSecType(Security.secTypeNone);
- if (options.encTLS.isSelected())
- Security.EnableSecType(Security.secTypeTLSNone);
- if (options.encX509.isSelected())
- Security.EnableSecType(Security.secTypeX509None);
- } else {
- Security.DisableSecType(Security.secTypeNone);
- Security.DisableSecType(Security.secTypeTLSNone);
- Security.DisableSecType(Security.secTypeX509None);
- }
-
- /* Process *Vnc security types */
- if (options.secVnc.isSelected()) {
- if (options.encNone.isSelected())
- Security.EnableSecType(Security.secTypeVncAuth);
- if (options.encTLS.isSelected())
- Security.EnableSecType(Security.secTypeTLSVnc);
- if (options.encX509.isSelected())
- Security.EnableSecType(Security.secTypeX509Vnc);
- } else {
- Security.DisableSecType(Security.secTypeVncAuth);
- Security.DisableSecType(Security.secTypeTLSVnc);
- Security.DisableSecType(Security.secTypeX509Vnc);
- }
-
- /* Process *Plain security types */
- if (options.secPlain.isSelected()) {
- if (options.encNone.isSelected())
- Security.EnableSecType(Security.secTypePlain);
- if (options.encTLS.isSelected())
- Security.EnableSecType(Security.secTypeTLSPlain);
- if (options.encX509.isSelected())
- Security.EnableSecType(Security.secTypeX509Plain);
- } else {
- Security.DisableSecType(Security.secTypePlain);
- Security.DisableSecType(Security.secTypeTLSPlain);
- Security.DisableSecType(Security.secTypeX509Plain);
- }
-
- /* Process *Ident security types */
- if (options.secIdent.isSelected()) {
- if (options.encNone.isSelected())
- Security.EnableSecType(Security.secTypeIdent);
- if (options.encTLS.isSelected())
- Security.EnableSecType(Security.secTypeTLSIdent);
- if (options.encX509.isSelected())
- Security.EnableSecType(Security.secTypeX509Ident);
- } else {
- Security.DisableSecType(Security.secTypeIdent);
- Security.DisableSecType(Security.secTypeTLSIdent);
- Security.DisableSecType(Security.secTypeX509Ident);
- }
-
- CSecurityTLS.x509ca.setParam(options.ca.getText());
- CSecurityTLS.x509crl.setParam(options.crl.getText());
- }
- }
-
- public void toggleFullScreen() {
- fullScreen = !fullScreen;
- if (!fullScreen) menu.fullScreen.setSelected(false);
- recreateViewport();
- }
-
- // writeClientCutText() is called from the clipboard dialog
- synchronized public void writeClientCutText(String str, int len) {
- if (state() != RFBSTATE_NORMAL) return;
- writer().writeClientCutText(str,len);
- }
-
- synchronized public void writeKeyEvent(int keysym, boolean down) {
- if (state() != RFBSTATE_NORMAL) return;
- writer().writeKeyEvent(keysym, down);
- }
-
- synchronized public void writeKeyEvent(KeyEvent ev) {
- if (ev.getID() != KeyEvent.KEY_PRESSED && !ev.isActionKey())
- return;
-
- int keysym;
-
- if (!ev.isActionKey()) {
- vlog.debug("key press "+ev.getKeyChar());
- if (ev.getKeyChar() < 32) {
- // if the ctrl modifier key is down, send the equivalent ASCII since we
- // will send the ctrl modifier anyway
-
- if ((ev.getModifiers() & KeyEvent.CTRL_MASK) != 0) {
- if ((ev.getModifiers() & KeyEvent.SHIFT_MASK) != 0) {
- keysym = ev.getKeyChar() + 64;
- if (keysym == -1)
- return;
- } else {
- keysym = ev.getKeyChar() + 96;
- if (keysym == 127) keysym = 95;
- }
- } else {
- switch (ev.getKeyCode()) {
- case KeyEvent.VK_BACK_SPACE: keysym = Keysyms.BackSpace; break;
- case KeyEvent.VK_TAB: keysym = Keysyms.Tab; break;
- case KeyEvent.VK_ENTER: keysym = Keysyms.Return; break;
- case KeyEvent.VK_ESCAPE: keysym = Keysyms.Escape; break;
- default: return;
- }
- }
-
- } else if (ev.getKeyChar() == 127) {
- keysym = Keysyms.Delete;
-
- } else {
- keysym = UnicodeToKeysym.translate(ev.getKeyChar());
- if (keysym == -1)
- return;
- }
-
- } else {
- // KEY_ACTION
- vlog.debug("key action "+ev.getKeyCode());
- switch (ev.getKeyCode()) {
- case KeyEvent.VK_HOME: keysym = Keysyms.Home; break;
- case KeyEvent.VK_END: keysym = Keysyms.End; break;
- case KeyEvent.VK_PAGE_UP: keysym = Keysyms.Page_Up; break;
- case KeyEvent.VK_PAGE_DOWN: keysym = Keysyms.Page_Down; break;
- case KeyEvent.VK_UP: keysym = Keysyms.Up; break;
- case KeyEvent.VK_DOWN: keysym = Keysyms.Down; break;
- case KeyEvent.VK_LEFT: keysym = Keysyms.Left; break;
- case KeyEvent.VK_RIGHT: keysym = Keysyms.Right; break;
- case KeyEvent.VK_F1: keysym = Keysyms.F1; break;
- case KeyEvent.VK_F2: keysym = Keysyms.F2; break;
- case KeyEvent.VK_F3: keysym = Keysyms.F3; break;
- case KeyEvent.VK_F4: keysym = Keysyms.F4; break;
- case KeyEvent.VK_F5: keysym = Keysyms.F5; break;
- case KeyEvent.VK_F6: keysym = Keysyms.F6; break;
- case KeyEvent.VK_F7: keysym = Keysyms.F7; break;
- case KeyEvent.VK_F8: keysym = Keysyms.F8; break;
- case KeyEvent.VK_F9: keysym = Keysyms.F9; break;
- case KeyEvent.VK_F10: keysym = Keysyms.F10; break;
- case KeyEvent.VK_F11: keysym = Keysyms.F11; break;
- case KeyEvent.VK_F12: keysym = Keysyms.F12; break;
- case KeyEvent.VK_PRINTSCREEN: keysym = Keysyms.Print; break;
- case KeyEvent.VK_PAUSE: keysym = Keysyms.Pause; break;
- case KeyEvent.VK_INSERT: keysym = Keysyms.Insert; break;
- default: return;
- }
- }
-
- writeModifiers(ev.getModifiers());
- writeKeyEvent(keysym, true);
- writeKeyEvent(keysym, false);
- writeModifiers(0);
- }
-
-
- synchronized public void writePointerEvent(MouseEvent ev) {
- if (state() != RFBSTATE_NORMAL) return;
- int x, y;
-
- switch (ev.getID()) {
- case MouseEvent.MOUSE_PRESSED:
- buttonMask = 1;
- if ((ev.getModifiers() & KeyEvent.ALT_MASK) != 0) buttonMask = 2;
- if ((ev.getModifiers() & KeyEvent.META_MASK) != 0) buttonMask = 4;
- break;
- case MouseEvent.MOUSE_RELEASED:
- buttonMask = 0;
- break;
- }
-
- writeModifiers(ev.getModifiers() & ~KeyEvent.ALT_MASK & ~KeyEvent.META_MASK);
-
- x = ev.getX();
- y = ev.getY();
- if (x < 0) x = 0;
- if (x > cp.width-1) x = cp.width-1;
- if (y < 0) y = 0;
- if (y > cp.height-1) y = cp.height-1;
-
- writer().writePointerEvent(new Point(x, y), buttonMask);
-
- if (buttonMask == 0) writeModifiers(0);
- }
-
-
- synchronized public void writeWheelEvent(MouseWheelEvent ev) {
- if (state() != RFBSTATE_NORMAL) return;
- int x, y;
- int clicks = ev.getWheelRotation();
- if (clicks < 0) {
- buttonMask = 8;
- } else {
- buttonMask = 16;
- }
- writeModifiers(ev.getModifiers() & ~KeyEvent.ALT_MASK & ~KeyEvent.META_MASK);
- for (int i=0;i<java.lang.Math.abs(clicks);i++) {
- x = ev.getX();
- y = ev.getY();
- writer().writePointerEvent(new Point(x, y), buttonMask);
- buttonMask = 0;
- writer().writePointerEvent(new Point(x, y), buttonMask);
- }
- writeModifiers(0);
-
- }
-
-
- void writeModifiers(int m) {
- if ((m & Event.SHIFT_MASK) != (pressedModifiers & Event.SHIFT_MASK))
- writeKeyEvent(Keysyms.Shift_L, (m & Event.SHIFT_MASK) != 0);
- if ((m & Event.CTRL_MASK) != (pressedModifiers & Event.CTRL_MASK))
- writeKeyEvent(Keysyms.Control_L, (m & Event.CTRL_MASK) != 0);
- if ((m & Event.ALT_MASK) != (pressedModifiers & Event.ALT_MASK))
- writeKeyEvent(Keysyms.Alt_L, (m & Event.ALT_MASK) != 0);
- if ((m & Event.META_MASK) != (pressedModifiers & Event.META_MASK))
- writeKeyEvent(Keysyms.Meta_L, (m & Event.META_MASK) != 0);
- pressedModifiers = m;
- }
-
-
- ////////////////////////////////////////////////////////////////////
- // The following methods are called from both RFB and GUI threads
-
- // checkEncodings() sends a setEncodings message if one is needed.
- synchronized private void checkEncodings() {
- if (encodingChange && state() == RFBSTATE_NORMAL) {
- vlog.info("Using "+Encodings.encodingName(currentEncoding)+" encoding");
- writer().writeSetEncodings(currentEncoding, true);
- encodingChange = false;
- }
- }
-
- // the following never change so need no synchronization:
- JavaInStream jis;
- JavaOutStream jos;
-
-
- // viewer object is only ever accessed by the GUI thread so needs no
- // synchronization (except for one test in DesktopWindow - see comment
- // there).
- VncViewer viewer;
-
- // access to desktop by different threads is specified in DesktopWindow
-
- // the following need no synchronization:
-
- ClassLoader cl = this.getClass().getClassLoader();
- ImageIcon logo = new ImageIcon(cl.getResource("com/tigervnc/vncviewer/tigervnc.png"));
- public static UserPasswdGetter upg;
- public UserMsgBox msg;
-
- // shuttingDown is set by the GUI thread and only ever tested by the RFB
- // thread after the window has been destroyed.
- boolean shuttingDown;
-
- // reading and writing int and boolean is atomic in java, so no
- // synchronization of the following flags is needed:
- int currentEncoding, lastServerEncoding;
-
- int lowColourLevel;
-
-
- // All menu, options, about and info stuff is done in the GUI thread (apart
- // from when constructed).
- F8Menu menu;
- OptionsDialog options;
-
- // clipboard sync issues?
- ClipboardDialog clipboardDialog;
-
- // the following are only ever accessed by the GUI thread:
- int buttonMask;
- int pressedModifiers;
-
- public String serverHost;
- public int serverPort;
- public int menuKey;
- PixelFormat serverPF;
- ViewportFrame viewport;
- DesktopWindow desktop;
- PixelFormat fullColourPF;
- boolean fullColour;
- boolean autoSelect;
- boolean shared;
- boolean formatChange;
- boolean encodingChange;
- boolean sameMachine;
- boolean fullScreen;
- boolean reverseConnection;
- boolean firstUpdate;
- boolean pendingUpdate;
-
- static LogWriter vlog = new LogWriter("CConn");
-}
+ }
+
+
+ // OptionsDialogCallback. setOptions() sets the options dialog's checkboxes
+ // etc to reflect our flags. getOptions() sets our flags according to the
+ // options dialog's checkboxes. They are both called from the GUI thread.
+ // Some of the flags are also accessed by the RFB thread. I believe that
+ // reading and writing boolean and int values in java is atomic, so there is
+ // no need for synchronization.
+
+ public void setOptions() {
+ int digit;
+ options.autoSelect.setSelected(autoSelect);
+ options.fullColour.setSelected(fullColour);
+ options.veryLowColour.setSelected(!fullColour && lowColourLevel == 0);
+ options.lowColour.setSelected(!fullColour && lowColourLevel == 1);
+ options.mediumColour.setSelected(!fullColour && lowColourLevel == 2);
+ options.tight.setSelected(currentEncoding == Encodings.encodingTight);
+ options.zrle.setSelected(currentEncoding == Encodings.encodingZRLE);
+ options.hextile.setSelected(currentEncoding == Encodings.encodingHextile);
+ options.raw.setSelected(currentEncoding == Encodings.encodingRaw);
+
+ options.customCompressLevel.setSelected(viewer.customCompressLevel.getValue());
+ digit = 0 + viewer.compressLevel.getValue();
+ options.compressLevel.setSelectedItem(digit);
+ options.noJpeg.setSelected(!viewer.noJpeg.getValue());
+ digit = 0 + viewer.qualityLevel.getValue();
+ options.qualityLevel.setSelectedItem(digit);
+
+ options.viewOnly.setSelected(viewer.viewOnly.getValue());
+ options.acceptClipboard.setSelected(viewer.acceptClipboard.getValue());
+ options.sendClipboard.setSelected(viewer.sendClipboard.getValue());
+ options.menuKey.setSelectedIndex(menuKey-0xFFBE);
+
+ if (state() == RFBSTATE_NORMAL) {
+ options.shared.setEnabled(false);
+ options.secVeNCrypt.setEnabled(false);
+ options.encNone.setEnabled(false);
+ options.encTLS.setEnabled(false);
+ options.encX509.setEnabled(false);
+ options.ca.setEnabled(false);
+ options.crl.setEnabled(false);
+ options.secIdent.setEnabled(false);
+ options.secNone.setEnabled(false);
+ options.secVnc.setEnabled(false);
+ options.secPlain.setEnabled(false);
+ options.sendLocalUsername.setEnabled(false);
+ } else {
+ options.shared.setSelected(shared);
+
+ /* Process non-VeNCrypt sectypes */
+ java.util.List<Integer> secTypes = new ArrayList<Integer>();
+ secTypes = security.GetEnabledSecTypes();
+ for (Iterator i = secTypes.iterator(); i.hasNext();) {
+ switch ((Integer)i.next()) {
+ case Security.secTypeVeNCrypt:
+ options.secVeNCrypt.setSelected(true);
+ break;
+ case Security.secTypeNone:
+ options.encNone.setSelected(true);
+ options.secNone.setSelected(true);
+ break;
+ case Security.secTypeVncAuth:
+ options.encNone.setSelected(true);
+ options.secVnc.setSelected(true);
+ break;
+ }
+ }
+
+ /* Process VeNCrypt subtypes */
+ if (options.secVeNCrypt.isSelected()) {
+ java.util.List<Integer> secTypesExt = new ArrayList<Integer>();
+ secTypesExt = security.GetEnabledExtSecTypes();
+ for (Iterator iext = secTypesExt.iterator(); iext.hasNext();) {
+ switch ((Integer)iext.next()) {
+ case Security.secTypePlain:
+ options.secPlain.setSelected(true);
+ options.sendLocalUsername.setSelected(true);
+ break;
+ case Security.secTypeIdent:
+ options.secIdent.setSelected(true);
+ options.sendLocalUsername.setSelected(true);
+ break;
+ case Security.secTypeTLSNone:
+ options.encTLS.setSelected(true);
+ options.secNone.setSelected(true);
+ break;
+ case Security.secTypeTLSVnc:
+ options.encTLS.setSelected(true);
+ options.secVnc.setSelected(true);
+ break;
+ case Security.secTypeTLSPlain:
+ options.encTLS.setSelected(true);
+ options.secPlain.setSelected(true);
+ options.sendLocalUsername.setSelected(true);
+ break;
+ case Security.secTypeTLSIdent:
+ options.encTLS.setSelected(true);
+ options.secIdent.setSelected(true);
+ options.sendLocalUsername.setSelected(true);
+ break;
+ case Security.secTypeX509None:
+ options.encX509.setSelected(true);
+ options.secNone.setSelected(true);
+ break;
+ case Security.secTypeX509Vnc:
+ options.encX509.setSelected(true);
+ options.secVnc.setSelected(true);
+ break;
+ case Security.secTypeX509Plain:
+ options.encX509.setSelected(true);
+ options.secPlain.setSelected(true);
+ options.sendLocalUsername.setSelected(true);
+ break;
+ case Security.secTypeX509Ident:
+ options.encX509.setSelected(true);
+ options.secIdent.setSelected(true);
+ options.sendLocalUsername.setSelected(true);
+ break;
+ }
+ }
+ }
+ options.sendLocalUsername.setEnabled(options.secPlain.isSelected()||
+ options.secIdent.isSelected());
+ }
+
+ options.fullScreen.setSelected(fullScreen);
+ options.useLocalCursor.setSelected(viewer.useLocalCursor.getValue());
+ options.fastCopyRect.setSelected(viewer.fastCopyRect.getValue());
+ }
+
+ public void getOptions() {
+ autoSelect = options.autoSelect.isSelected();
+ if (fullColour != options.fullColour.isSelected())
+ formatChange = true;
+ fullColour = options.fullColour.isSelected();
+ if (!fullColour) {
+ int newLowColourLevel = (options.veryLowColour.isSelected() ? 0 :
+ options.lowColour.isSelected() ? 1 : 2);
+ if (newLowColourLevel != lowColourLevel) {
+ lowColourLevel = newLowColourLevel;
+ formatChange = true;
+ }
+ }
+ int newEncoding = (options.zrle.isSelected() ? Encodings.encodingZRLE :
+ options.hextile.isSelected() ? Encodings.encodingHextile :
+ options.tight.isSelected() ? Encodings.encodingTight :
+ Encodings.encodingRaw);
+ if (newEncoding != currentEncoding) {
+ currentEncoding = newEncoding;
+ encodingChange = true;
+ }
+
+ viewer.customCompressLevel.setParam(options.customCompressLevel.isSelected());
+ if (cp.customCompressLevel != viewer.customCompressLevel.getValue()) {
+ cp.customCompressLevel = viewer.customCompressLevel.getValue();
+ encodingChange = true;
+ }
+ viewer.compressLevel.setParam(options.compressLevel.getSelectedItem().toString());
+ if (cp.compressLevel != viewer.compressLevel.getValue()) {
+ cp.compressLevel = viewer.compressLevel.getValue();
+ encodingChange = true;
+ }
+ viewer.noJpeg.setParam(!options.noJpeg.isSelected());
+ if (cp.noJpeg != viewer.noJpeg.getValue()) {
+ cp.noJpeg = viewer.noJpeg.getValue();
+ encodingChange = true;
+ }
+ viewer.qualityLevel.setParam(options.qualityLevel.getSelectedItem().toString());
+ if (cp.qualityLevel != viewer.qualityLevel.getValue()) {
+ cp.qualityLevel = viewer.qualityLevel.getValue();
+ encodingChange = true;
+ }
+ viewer.sendLocalUsername.setParam(options.sendLocalUsername.isSelected());
+
+ viewer.viewOnly.setParam(options.viewOnly.isSelected());
+ viewer.acceptClipboard.setParam(options.acceptClipboard.isSelected());
+ viewer.sendClipboard.setParam(options.sendClipboard.isSelected());
+ clipboardDialog.setSendingEnabled(viewer.sendClipboard.getValue());
+ menuKey = (int)(options.menuKey.getSelectedIndex()+0xFFBE);
+ F8Menu.f8.setLabel("Send F"+(menuKey-Keysyms.F1+1));
+
+ shared = options.shared.isSelected();
+ setShared(shared);
+ viewer.useLocalCursor.setParam(options.useLocalCursor.isSelected());
+ if (cp.supportsLocalCursor != viewer.useLocalCursor.getValue()) {
+ cp.supportsLocalCursor = viewer.useLocalCursor.getValue();
+ encodingChange = true;
+ if (desktop != null)
+ desktop.resetLocalCursor();
+ }
+
+ checkEncodings();
+
+ if (state() != RFBSTATE_NORMAL) {
+ /* Process security types which don't use encryption */
+ if (options.encNone.isSelected()) {
+ if (options.secNone.isSelected())
+ Security.EnableSecType(Security.secTypeNone);
+ if (options.secVnc.isSelected())
+ Security.EnableSecType(Security.secTypeVncAuth);
+ if (options.secPlain.isSelected())
+ Security.EnableSecType(Security.secTypePlain);
+ if (options.secIdent.isSelected())
+ Security.EnableSecType(Security.secTypeIdent);
+ } else {
+ Security.DisableSecType(Security.secTypeNone);
+ Security.DisableSecType(Security.secTypeVncAuth);
+ Security.DisableSecType(Security.secTypePlain);
+ Security.DisableSecType(Security.secTypeIdent);
+ }
+
+ /* Process security types which use TLS encryption */
+ if (options.encTLS.isSelected()) {
+ if (options.secNone.isSelected())
+ Security.EnableSecType(Security.secTypeTLSNone);
+ if (options.secVnc.isSelected())
+ Security.EnableSecType(Security.secTypeTLSVnc);
+ if (options.secPlain.isSelected())
+ Security.EnableSecType(Security.secTypeTLSPlain);
+ if (options.secIdent.isSelected())
+ Security.EnableSecType(Security.secTypeTLSIdent);
+ } else {
+ Security.DisableSecType(Security.secTypeTLSNone);
+ Security.DisableSecType(Security.secTypeTLSVnc);
+ Security.DisableSecType(Security.secTypeTLSPlain);
+ Security.DisableSecType(Security.secTypeTLSIdent);
+ }
+
+ /* Process security types which use X509 encryption */
+ if (options.encX509.isSelected()) {
+ if (options.secNone.isSelected())
+ Security.EnableSecType(Security.secTypeX509None);
+ if (options.secVnc.isSelected())
+ Security.EnableSecType(Security.secTypeX509Vnc);
+ if (options.secPlain.isSelected())
+ Security.EnableSecType(Security.secTypeX509Plain);
+ if (options.secIdent.isSelected())
+ Security.EnableSecType(Security.secTypeX509Ident);
+ } else {
+ Security.DisableSecType(Security.secTypeX509None);
+ Security.DisableSecType(Security.secTypeX509Vnc);
+ Security.DisableSecType(Security.secTypeX509Plain);
+ Security.DisableSecType(Security.secTypeX509Ident);
+ }
+
+ /* Process *None security types */
+ if (options.secNone.isSelected()) {
+ if (options.encNone.isSelected())
+ Security.EnableSecType(Security.secTypeNone);
+ if (options.encTLS.isSelected())
+ Security.EnableSecType(Security.secTypeTLSNone);
+ if (options.encX509.isSelected())
+ Security.EnableSecType(Security.secTypeX509None);
+ } else {
+ Security.DisableSecType(Security.secTypeNone);
+ Security.DisableSecType(Security.secTypeTLSNone);
+ Security.DisableSecType(Security.secTypeX509None);
+ }
+
+ /* Process *Vnc security types */
+ if (options.secVnc.isSelected()) {
+ if (options.encNone.isSelected())
+ Security.EnableSecType(Security.secTypeVncAuth);
+ if (options.encTLS.isSelected())
+ Security.EnableSecType(Security.secTypeTLSVnc);
+ if (options.encX509.isSelected())
+ Security.EnableSecType(Security.secTypeX509Vnc);
+ } else {
+ Security.DisableSecType(Security.secTypeVncAuth);
+ Security.DisableSecType(Security.secTypeTLSVnc);
+ Security.DisableSecType(Security.secTypeX509Vnc);
+ }
+
+ /* Process *Plain security types */
+ if (options.secPlain.isSelected()) {
+ if (options.encNone.isSelected())
+ Security.EnableSecType(Security.secTypePlain);
+ if (options.encTLS.isSelected())
+ Security.EnableSecType(Security.secTypeTLSPlain);
+ if (options.encX509.isSelected())
+ Security.EnableSecType(Security.secTypeX509Plain);
+ } else {
+ Security.DisableSecType(Security.secTypePlain);
+ Security.DisableSecType(Security.secTypeTLSPlain);
+ Security.DisableSecType(Security.secTypeX509Plain);
+ }
+
+ /* Process *Ident security types */
+ if (options.secIdent.isSelected()) {
+ if (options.encNone.isSelected())
+ Security.EnableSecType(Security.secTypeIdent);
+ if (options.encTLS.isSelected())
+ Security.EnableSecType(Security.secTypeTLSIdent);
+ if (options.encX509.isSelected())
+ Security.EnableSecType(Security.secTypeX509Ident);
+ } else {
+ Security.DisableSecType(Security.secTypeIdent);
+ Security.DisableSecType(Security.secTypeTLSIdent);
+ Security.DisableSecType(Security.secTypeX509Ident);
+ }
+
+ CSecurityTLS.x509ca.setParam(options.ca.getText());
+ CSecurityTLS.x509crl.setParam(options.crl.getText());
+ }
+ }
+
+ public void toggleFullScreen() {
+ fullScreen = !fullScreen;
+ if (!fullScreen) menu.fullScreen.setSelected(false);
+ recreateViewport();
+ }
+
+ // writeClientCutText() is called from the clipboard dialog
+ synchronized public void writeClientCutText(String str, int len) {
+ if (state() != RFBSTATE_NORMAL) return;
+ writer().writeClientCutText(str,len);
+ }
+
+ synchronized public void writeKeyEvent(int keysym, boolean down) {
+ if (state() != RFBSTATE_NORMAL) return;
+ writer().writeKeyEvent(keysym, down);
+ }
+
+ synchronized public void writeKeyEvent(KeyEvent ev) {
+ if (ev.getID() != KeyEvent.KEY_PRESSED && !ev.isActionKey())
+ return;
+
+ int keysym;
+
+ if (!ev.isActionKey()) {
+ vlog.debug("key press "+ev.getKeyChar());
+ if (ev.getKeyChar() < 32) {
+ // if the ctrl modifier key is down, send the equivalent ASCII since we
+ // will send the ctrl modifier anyway
+
+ if ((ev.getModifiers() & KeyEvent.CTRL_MASK) != 0) {
+ if ((ev.getModifiers() & KeyEvent.SHIFT_MASK) != 0) {
+ keysym = ev.getKeyChar() + 64;
+ if (keysym == -1)
+ return;
+ } else {
+ keysym = ev.getKeyChar() + 96;
+ if (keysym == 127) keysym = 95;
+ }
+ } else {
+ switch (ev.getKeyCode()) {
+ case KeyEvent.VK_BACK_SPACE: keysym = Keysyms.BackSpace; break;
+ case KeyEvent.VK_TAB: keysym = Keysyms.Tab; break;
+ case KeyEvent.VK_ENTER: keysym = Keysyms.Return; break;
+ case KeyEvent.VK_ESCAPE: keysym = Keysyms.Escape; break;
+ default: return;
+ }
+ }
+
+ } else if (ev.getKeyChar() == 127) {
+ keysym = Keysyms.Delete;
+
+ } else {
+ keysym = UnicodeToKeysym.translate(ev.getKeyChar());
+ if (keysym == -1)
+ return;
+ }
+
+ } else {
+ // KEY_ACTION
+ vlog.debug("key action "+ev.getKeyCode());
+ switch (ev.getKeyCode()) {
+ case KeyEvent.VK_HOME: keysym = Keysyms.Home; break;
+ case KeyEvent.VK_END: keysym = Keysyms.End; break;
+ case KeyEvent.VK_PAGE_UP: keysym = Keysyms.Page_Up; break;
+ case KeyEvent.VK_PAGE_DOWN: keysym = Keysyms.Page_Down; break;
+ case KeyEvent.VK_UP: keysym = Keysyms.Up; break;
+ case KeyEvent.VK_DOWN: keysym = Keysyms.Down; break;
+ case KeyEvent.VK_LEFT: keysym = Keysyms.Left; break;
+ case KeyEvent.VK_RIGHT: keysym = Keysyms.Right; break;
+ case KeyEvent.VK_F1: keysym = Keysyms.F1; break;
+ case KeyEvent.VK_F2: keysym = Keysyms.F2; break;
+ case KeyEvent.VK_F3: keysym = Keysyms.F3; break;
+ case KeyEvent.VK_F4: keysym = Keysyms.F4; break;
+ case KeyEvent.VK_F5: keysym = Keysyms.F5; break;
+ case KeyEvent.VK_F6: keysym = Keysyms.F6; break;
+ case KeyEvent.VK_F7: keysym = Keysyms.F7; break;
+ case KeyEvent.VK_F8: keysym = Keysyms.F8; break;
+ case KeyEvent.VK_F9: keysym = Keysyms.F9; break;
+ case KeyEvent.VK_F10: keysym = Keysyms.F10; break;
+ case KeyEvent.VK_F11: keysym = Keysyms.F11; break;
+ case KeyEvent.VK_F12: keysym = Keysyms.F12; break;
+ case KeyEvent.VK_PRINTSCREEN: keysym = Keysyms.Print; break;
+ case KeyEvent.VK_PAUSE: keysym = Keysyms.Pause; break;
+ case KeyEvent.VK_INSERT: keysym = Keysyms.Insert; break;
+ default: return;
+ }
+ }
+
+ writeModifiers(ev.getModifiers());
+ writeKeyEvent(keysym, true);
+ writeKeyEvent(keysym, false);
+ writeModifiers(0);
+ }
+
+
+ synchronized public void writePointerEvent(MouseEvent ev) {
+ if (state() != RFBSTATE_NORMAL) return;
+ int x, y;
+
+ switch (ev.getID()) {
+ case MouseEvent.MOUSE_PRESSED:
+ buttonMask = 1;
+ if ((ev.getModifiers() & KeyEvent.ALT_MASK) != 0) buttonMask = 2;
+ if ((ev.getModifiers() & KeyEvent.META_MASK) != 0) buttonMask = 4;
+ break;
+ case MouseEvent.MOUSE_RELEASED:
+ buttonMask = 0;
+ break;
+ }
+
+ writeModifiers(ev.getModifiers() & ~KeyEvent.ALT_MASK & ~KeyEvent.META_MASK);
+
+ x = ev.getX();
+ y = ev.getY();
+ if (x < 0) x = 0;
+ if (x > cp.width-1) x = cp.width-1;
+ if (y < 0) y = 0;
+ if (y > cp.height-1) y = cp.height-1;
+
+ writer().writePointerEvent(new Point(x, y), buttonMask);
+
+ if (buttonMask == 0) writeModifiers(0);
+ }
+
+
+ synchronized public void writeWheelEvent(MouseWheelEvent ev) {
+ if (state() != RFBSTATE_NORMAL) return;
+ int x, y;
+ int clicks = ev.getWheelRotation();
+ if (clicks < 0) {
+ buttonMask = 8;
+ } else {
+ buttonMask = 16;
+ }
+ writeModifiers(ev.getModifiers() & ~KeyEvent.ALT_MASK & ~KeyEvent.META_MASK);
+ for (int i=0;i<java.lang.Math.abs(clicks);i++) {
+ x = ev.getX();
+ y = ev.getY();
+ writer().writePointerEvent(new Point(x, y), buttonMask);
+ buttonMask = 0;
+ writer().writePointerEvent(new Point(x, y), buttonMask);
+ }
+ writeModifiers(0);
+
+ }
+
+
+ void writeModifiers(int m) {
+ if ((m & Event.SHIFT_MASK) != (pressedModifiers & Event.SHIFT_MASK))
+ writeKeyEvent(Keysyms.Shift_L, (m & Event.SHIFT_MASK) != 0);
+ if ((m & Event.CTRL_MASK) != (pressedModifiers & Event.CTRL_MASK))
+ writeKeyEvent(Keysyms.Control_L, (m & Event.CTRL_MASK) != 0);
+ if ((m & Event.ALT_MASK) != (pressedModifiers & Event.ALT_MASK))
+ writeKeyEvent(Keysyms.Alt_L, (m & Event.ALT_MASK) != 0);
+ if ((m & Event.META_MASK) != (pressedModifiers & Event.META_MASK))
+ writeKeyEvent(Keysyms.Meta_L, (m & Event.META_MASK) != 0);
+ pressedModifiers = m;
+ }
+
+
+ ////////////////////////////////////////////////////////////////////
+ // The following methods are called from both RFB and GUI threads
+
+ // checkEncodings() sends a setEncodings message if one is needed.
+ synchronized private void checkEncodings() {
+ if (encodingChange && state() == RFBSTATE_NORMAL) {
+ vlog.info("Using "+Encodings.encodingName(currentEncoding)+" encoding");
+ writer().writeSetEncodings(currentEncoding, true);
+ encodingChange = false;
+ }
+ }
+
+ // the following never change so need no synchronization:
+ JavaInStream jis;
+ JavaOutStream jos;
+
+
+ // viewer object is only ever accessed by the GUI thread so needs no
+ // synchronization (except for one test in DesktopWindow - see comment
+ // there).
+ VncViewer viewer;
+
+ // access to desktop by different threads is specified in DesktopWindow
+
+ // the following need no synchronization:
+
+ ClassLoader cl = this.getClass().getClassLoader();
+ ImageIcon logo = new ImageIcon(cl.getResource("com/tigervnc/vncviewer/tigervnc.png"));
+ public static UserPasswdGetter upg;
+ public UserMsgBox msg;
+
+ // shuttingDown is set by the GUI thread and only ever tested by the RFB
+ // thread after the window has been destroyed.
+ boolean shuttingDown;
+
+ // reading and writing int and boolean is atomic in java, so no
+ // synchronization of the following flags is needed:
+ int currentEncoding, lastServerEncoding;
+
+ int lowColourLevel;
+
+
+ // All menu, options, about and info stuff is done in the GUI thread (apart
+ // from when constructed).
+ F8Menu menu;
+ OptionsDialog options;
+
+ // clipboard sync issues?
+ ClipboardDialog clipboardDialog;
+
+ // the following are only ever accessed by the GUI thread:
+ int buttonMask;
+ int pressedModifiers;
+
+ public String serverHost;
+ public int serverPort;
+ public int menuKey;
+ PixelFormat serverPF;
+ ViewportFrame viewport;
+ DesktopWindow desktop;
+ PixelFormat fullColourPF;
+ boolean fullColour;
+ boolean autoSelect;
+ boolean shared;
+ boolean formatChange;
+ boolean encodingChange;
+ boolean sameMachine;
+ boolean fullScreen;
+ boolean reverseConnection;
+ boolean firstUpdate;
+ boolean pendingUpdate;
+
+ static LogWriter vlog = new LogWriter("CConn");
+}
diff --git a/java/src/com/tigervnc/vncviewer/DesktopWindow.java b/java/src/com/tigervnc/vncviewer/DesktopWindow.java
index 7a8cda84..5e2764bc 100644
--- a/java/src/com/tigervnc/vncviewer/DesktopWindow.java
+++ b/java/src/com/tigervnc/vncviewer/DesktopWindow.java
@@ -1,485 +1,485 @@
-/* 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.
- */
-
-//
-// DesktopWindow is an AWT Canvas representing a VNC desktop.
-//
-// Methods on DesktopWindow are called from both the GUI thread and the thread
-// which processes incoming RFB messages ("the RFB thread"). This means we
-// need to be careful with synchronization here.
-//
-
-package com.tigervnc.vncviewer;
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.image.*;
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.Transferable;
+/* 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.
+ */
+
+//
+// DesktopWindow is an AWT Canvas representing a VNC desktop.
+//
+// Methods on DesktopWindow are called from both the GUI thread and the thread
+// which processes incoming RFB messages ("the RFB thread"). This means we
+// need to be careful with synchronization here.
+//
+
+package com.tigervnc.vncviewer;
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.*;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.Clipboard;
import javax.swing.*;
-
+
import com.tigervnc.rfb.*;
-import com.tigervnc.rfb.Cursor;
+import com.tigervnc.rfb.Cursor;
import com.tigervnc.rfb.Exception;
import com.tigervnc.rfb.Point;
-
-class DesktopWindow extends JPanel implements
- Runnable,
- MouseListener,
- MouseMotionListener,
- MouseWheelListener,
- KeyListener
-{
-
- ////////////////////////////////////////////////////////////////////
- // The following methods are all called from the RFB thread
-
- public DesktopWindow(int width, int height, PixelFormat serverPF, CConn cc_) {
- cc = cc_;
- setSize(width, height);
- im = new PixelBufferImage(width, height, cc, this);
-
- cursor = new Cursor();
- cursorBacking = new ManagedPixelBuffer();
- addMouseListener(this);
- addMouseWheelListener(this);
- addMouseMotionListener(this);
- addKeyListener(this);
- addFocusListener(new FocusAdapter() {
- public void focusGained(FocusEvent e) {
- checkClipboard();
- }
- });
- setFocusTraversalKeysEnabled(false);
- setFocusable(true);
- setDoubleBuffered(true);
- }
-
- public int width() {
- return getWidth();
- }
-
- public int height() {
- return getHeight();
- }
-
- // initGraphics() is needed because for some reason you can't call
- // getGraphics() on a newly-created awt Component. It is called when the
- // DesktopWindow has actually been made visible so that getGraphics() ought
- // to work.
-
- public void initGraphics() {
- cc.viewport.g = cc.viewport.getGraphics();
- graphics = getComponentGraphics(cc.viewport.g);
- prepareImage(im.image, -1, -1, this);
- }
-
- final public PixelFormat getPF() { return im.getPF(); }
-
- synchronized public void setPF(PixelFormat pf) {
- im.setPF(pf);
- }
-
+
+class DesktopWindow extends JPanel implements
+ Runnable,
+ MouseListener,
+ MouseMotionListener,
+ MouseWheelListener,
+ KeyListener
+{
+
+ ////////////////////////////////////////////////////////////////////
+ // The following methods are all called from the RFB thread
+
+ public DesktopWindow(int width, int height, PixelFormat serverPF, CConn cc_) {
+ cc = cc_;
+ setSize(width, height);
+ im = new PixelBufferImage(width, height, cc, this);
+
+ cursor = new Cursor();
+ cursorBacking = new ManagedPixelBuffer();
+ addMouseListener(this);
+ addMouseWheelListener(this);
+ addMouseMotionListener(this);
+ addKeyListener(this);
+ addFocusListener(new FocusAdapter() {
+ public void focusGained(FocusEvent e) {
+ checkClipboard();
+ }
+ });
+ setFocusTraversalKeysEnabled(false);
+ setFocusable(true);
+ setDoubleBuffered(true);
+ }
+
+ public int width() {
+ return getWidth();
+ }
+
+ public int height() {
+ return getHeight();
+ }
+
+ // initGraphics() is needed because for some reason you can't call
+ // getGraphics() on a newly-created awt Component. It is called when the
+ // DesktopWindow has actually been made visible so that getGraphics() ought
+ // to work.
+
+ public void initGraphics() {
+ cc.viewport.g = cc.viewport.getGraphics();
+ graphics = getComponentGraphics(cc.viewport.g);
+ prepareImage(im.image, -1, -1, this);
+ }
+
+ final public PixelFormat getPF() { return im.getPF(); }
+
+ synchronized public void setPF(PixelFormat pf) {
+ im.setPF(pf);
+ }
+
public void setViewport(ViewportFrame viewport)
{
viewport.setChild(this);
}
- // Methods called from the RFB thread - these need to be synchronized
- // wherever they access data shared with the GUI thread.
-
- public void setCursor(int w, int h, Point hotspot,
- int[] data, byte[] mask) {
- // strictly we should use a mutex around this test since useLocalCursor
- // might be being altered by the GUI thread. However it's only a single
- // boolean and it doesn't matter if we get the wrong value anyway.
-
- synchronized(this) {
- if (!cc.viewer.useLocalCursor.getValue()) return;
-
- hideLocalCursor();
-
- cursor.hotspot = hotspot;
-
- Dimension bsc = tk.getBestCursorSize(w, h);
-
- cursor.setSize(((int)bsc.getWidth() > w ? (int)bsc.getWidth() : w),
- ((int)bsc.getHeight() > h ? (int)bsc.getHeight() : h));
- cursor.setPF(getPF());
-
- cursorBacking.setSize(cursor.width(), cursor.height());
- cursorBacking.setPF(getPF());
-
- cursor.data = new int[cursor.width() * cursor.height()];
- cursor.mask = new byte[cursor.maskLen()];
-
- // set the masked pixels of the cursor transparent by using an extra bit in
- // the colormap. We'll OR this into the data based on the values in the mask.
- if (cursor.getPF().bpp == 8) {
- cursor.cm = new DirectColorModel(9, 7, (7 << 3), (3 << 6), (1 << 8));
- }
-
- int maskBytesPerRow = (w + 7) / 8;
- for (int y = 0; y < h; y++) {
- for (int x = 0; x < w; x++) {
- int byte_ = y * maskBytesPerRow + x / 8;
- int bit = 7 - x % 8;
- if ((mask[byte_] & (1 << bit)) > 0) {
- cursor.data[y * cursor.width() + x] = (cursor.getPF().bpp == 8) ?
- data[y * w + x] | (1 << 8) : data[y * w + x];
- }
- }
- System.arraycopy(mask, y * maskBytesPerRow, cursor.mask,
- y * ((cursor.width() + 7) / 8), maskBytesPerRow);
- }
-
- MemoryImageSource bitmap =
- new MemoryImageSource(cursor.width(), cursor.height(), cursor.cm,
- cursor.data, 0, cursor.width());
- softCursor =
- tk.createCustomCursor(tk.createImage(bitmap), new java.awt.Point(hotspot.x,hotspot.y), "Cursor");
- }
-
- if (softCursor != null) {
- setCursor(softCursor);
- cursorAvailable = true;
- return;
- }
-
- if (!cursorAvailable) {
- cursorAvailable = true;
- }
-
- showLocalCursor();
- return;
- }
-
- // setColourMapEntries() changes some of the entries in the colourmap.
- // Unfortunately these messages are often sent one at a time, so we delay the
- // settings taking effect unless the whole colourmap has changed. This is
- // because getting java to recalculate its internal translation table and
- // redraw the screen is expensive.
-
- synchronized public void setColourMapEntries(int firstColour, int nColours,
- int[] rgbs) {
- im.setColourMapEntries(firstColour, nColours, rgbs);
- if (nColours <= 256) {
- im.updateColourMap();
- im.put(0, 0, im.width(), im.height(), graphics);
- } else {
- if (setColourMapEntriesTimerThread == null) {
- setColourMapEntriesTimerThread = new Thread(this);
- setColourMapEntriesTimerThread.start();
- }
- }
- }
-
-// Update the actual window with the changed parts of the framebuffer.
-
- public void framebufferUpdateEnd()
- {
- drawInvalidRect();
- }
-
- // resize() is called when the desktop has changed size
- synchronized public void resize() {
- int w = cc.cp.width;
- int h = cc.cp.height;
- hideLocalCursor();
- setSize(w, h);
- im.resize(w, h);
- }
-
- final void drawInvalidRect() {
- if (!invalidRect) return;
- int x = invalidLeft;
- int w = invalidRight - x;
- int y = invalidTop;
- int h = invalidBottom - y;
- invalidRect = false;
-
- synchronized (this) {
- im.put(x, y, w, h, graphics);
- }
- }
-
- final void invalidate(int x, int y, int w, int h) {
- if (invalidRect) {
- if (x < invalidLeft) invalidLeft = x;
- if (x + w > invalidRight) invalidRight = x + w;
- if (y < invalidTop) invalidTop = y;
- if (y + h > invalidBottom) invalidBottom = y + h;
- } else {
- invalidLeft = x;
- invalidRight = x + w;
- invalidTop = y;
- invalidBottom = y + h;
- invalidRect = true;
- }
-
- if ((invalidRight - invalidLeft) * (invalidBottom - invalidTop) > 100000)
- drawInvalidRect();
- }
-
- public void beginRect(int x, int y, int w, int h, int encoding) {
- invalidRect = false;
- }
-
- public void endRect(int x, int y, int w, int h, int encoding) {
- drawInvalidRect();
- }
-
- synchronized final public void fillRect(int x, int y, int w, int h, int pix)
- {
- if (overlapsCursor(x, y, w, h)) hideLocalCursor();
- im.fillRect(x, y, w, h, pix);
- invalidate(x, y, w, h);
- if (softCursor == null)
- showLocalCursor();
- }
-
- synchronized final public void imageRect(int x, int y, int w, int h,
- int[] pix) {
- if (overlapsCursor(x, y, w, h)) hideLocalCursor();
- im.imageRect(x, y, w, h, pix);
- invalidate(x, y, w, h);
- if (softCursor == null)
- showLocalCursor();
- }
-
- synchronized final public void copyRect(int x, int y, int w, int h,
- int srcX, int srcY) {
- if (overlapsCursor(x, y, w, h) || overlapsCursor(srcX, srcY, w, h))
- hideLocalCursor();
- im.copyRect(x, y, w, h, srcX, srcY);
- if (!cc.viewer.fastCopyRect.getValue()) {
- invalidate(x, y, w, h);
- }
- }
-
-
- // mutex MUST be held when overlapsCursor() is called
- final boolean overlapsCursor(int x, int y, int w, int h) {
- return (x < cursorBackingX + cursorBacking.width() &&
- y < cursorBackingY + cursorBacking.height() &&
- x+w > cursorBackingX && y+h > cursorBackingY);
- }
-
-
- ////////////////////////////////////////////////////////////////////
- // The following methods are all called from the GUI thread
-
- synchronized void resetLocalCursor() {
- hideLocalCursor();
- cursorAvailable = false;
- }
-
- synchronized public Dimension getPreferredSize() {
- return new Dimension(im.width(), im.height());
- }
-
- synchronized public Dimension getMinimumSize() {
- return new Dimension(im.width(), im.height());
- }
-
- public void update(Graphics g) {
- //repaint();
- }
-
- synchronized public void paintComponent(Graphics g) {
- Graphics2D g2 = (Graphics2D) g;
- g2.drawImage(im.image, 0, 0, this);
- }
-
-
- String oldContents = "";
-
- synchronized public void checkClipboard() {
+ // Methods called from the RFB thread - these need to be synchronized
+ // wherever they access data shared with the GUI thread.
+
+ public void setCursor(int w, int h, Point hotspot,
+ int[] data, byte[] mask) {
+ // strictly we should use a mutex around this test since useLocalCursor
+ // might be being altered by the GUI thread. However it's only a single
+ // boolean and it doesn't matter if we get the wrong value anyway.
+
+ synchronized(this) {
+ if (!cc.viewer.useLocalCursor.getValue()) return;
+
+ hideLocalCursor();
+
+ cursor.hotspot = hotspot;
+
+ Dimension bsc = tk.getBestCursorSize(w, h);
+
+ cursor.setSize(((int)bsc.getWidth() > w ? (int)bsc.getWidth() : w),
+ ((int)bsc.getHeight() > h ? (int)bsc.getHeight() : h));
+ cursor.setPF(getPF());
+
+ cursorBacking.setSize(cursor.width(), cursor.height());
+ cursorBacking.setPF(getPF());
+
+ cursor.data = new int[cursor.width() * cursor.height()];
+ cursor.mask = new byte[cursor.maskLen()];
+
+ // set the masked pixels of the cursor transparent by using an extra bit in
+ // the colormap. We'll OR this into the data based on the values in the mask.
+ if (cursor.getPF().bpp == 8) {
+ cursor.cm = new DirectColorModel(9, 7, (7 << 3), (3 << 6), (1 << 8));
+ }
+
+ int maskBytesPerRow = (w + 7) / 8;
+ for (int y = 0; y < h; y++) {
+ for (int x = 0; x < w; x++) {
+ int byte_ = y * maskBytesPerRow + x / 8;
+ int bit = 7 - x % 8;
+ if ((mask[byte_] & (1 << bit)) > 0) {
+ cursor.data[y * cursor.width() + x] = (cursor.getPF().bpp == 8) ?
+ data[y * w + x] | (1 << 8) : data[y * w + x];
+ }
+ }
+ System.arraycopy(mask, y * maskBytesPerRow, cursor.mask,
+ y * ((cursor.width() + 7) / 8), maskBytesPerRow);
+ }
+
+ MemoryImageSource bitmap =
+ new MemoryImageSource(cursor.width(), cursor.height(), cursor.cm,
+ cursor.data, 0, cursor.width());
+ softCursor =
+ tk.createCustomCursor(tk.createImage(bitmap), new java.awt.Point(hotspot.x,hotspot.y), "Cursor");
+ }
+
+ if (softCursor != null) {
+ setCursor(softCursor);
+ cursorAvailable = true;
+ return;
+ }
+
+ if (!cursorAvailable) {
+ cursorAvailable = true;
+ }
+
+ showLocalCursor();
+ return;
+ }
+
+ // setColourMapEntries() changes some of the entries in the colourmap.
+ // Unfortunately these messages are often sent one at a time, so we delay the
+ // settings taking effect unless the whole colourmap has changed. This is
+ // because getting java to recalculate its internal translation table and
+ // redraw the screen is expensive.
+
+ synchronized public void setColourMapEntries(int firstColour, int nColours,
+ int[] rgbs) {
+ im.setColourMapEntries(firstColour, nColours, rgbs);
+ if (nColours <= 256) {
+ im.updateColourMap();
+ im.put(0, 0, im.width(), im.height(), graphics);
+ } else {
+ if (setColourMapEntriesTimerThread == null) {
+ setColourMapEntriesTimerThread = new Thread(this);
+ setColourMapEntriesTimerThread.start();
+ }
+ }
+ }
+
+// Update the actual window with the changed parts of the framebuffer.
+
+ public void framebufferUpdateEnd()
+ {
+ drawInvalidRect();
+ }
+
+ // resize() is called when the desktop has changed size
+ synchronized public void resize() {
+ int w = cc.cp.width;
+ int h = cc.cp.height;
+ hideLocalCursor();
+ setSize(w, h);
+ im.resize(w, h);
+ }
+
+ final void drawInvalidRect() {
+ if (!invalidRect) return;
+ int x = invalidLeft;
+ int w = invalidRight - x;
+ int y = invalidTop;
+ int h = invalidBottom - y;
+ invalidRect = false;
+
+ synchronized (this) {
+ im.put(x, y, w, h, graphics);
+ }
+ }
+
+ final void invalidate(int x, int y, int w, int h) {
+ if (invalidRect) {
+ if (x < invalidLeft) invalidLeft = x;
+ if (x + w > invalidRight) invalidRight = x + w;
+ if (y < invalidTop) invalidTop = y;
+ if (y + h > invalidBottom) invalidBottom = y + h;
+ } else {
+ invalidLeft = x;
+ invalidRight = x + w;
+ invalidTop = y;
+ invalidBottom = y + h;
+ invalidRect = true;
+ }
+
+ if ((invalidRight - invalidLeft) * (invalidBottom - invalidTop) > 100000)
+ drawInvalidRect();
+ }
+
+ public void beginRect(int x, int y, int w, int h, int encoding) {
+ invalidRect = false;
+ }
+
+ public void endRect(int x, int y, int w, int h, int encoding) {
+ drawInvalidRect();
+ }
+
+ synchronized final public void fillRect(int x, int y, int w, int h, int pix)
+ {
+ if (overlapsCursor(x, y, w, h)) hideLocalCursor();
+ im.fillRect(x, y, w, h, pix);
+ invalidate(x, y, w, h);
+ if (softCursor == null)
+ showLocalCursor();
+ }
+
+ synchronized final public void imageRect(int x, int y, int w, int h,
+ int[] pix) {
+ if (overlapsCursor(x, y, w, h)) hideLocalCursor();
+ im.imageRect(x, y, w, h, pix);
+ invalidate(x, y, w, h);
+ if (softCursor == null)
+ showLocalCursor();
+ }
+
+ synchronized final public void copyRect(int x, int y, int w, int h,
+ int srcX, int srcY) {
+ if (overlapsCursor(x, y, w, h) || overlapsCursor(srcX, srcY, w, h))
+ hideLocalCursor();
+ im.copyRect(x, y, w, h, srcX, srcY);
+ if (!cc.viewer.fastCopyRect.getValue()) {
+ invalidate(x, y, w, h);
+ }
+ }
+
+
+ // mutex MUST be held when overlapsCursor() is called
+ final boolean overlapsCursor(int x, int y, int w, int h) {
+ return (x < cursorBackingX + cursorBacking.width() &&
+ y < cursorBackingY + cursorBacking.height() &&
+ x+w > cursorBackingX && y+h > cursorBackingY);
+ }
+
+
+ ////////////////////////////////////////////////////////////////////
+ // The following methods are all called from the GUI thread
+
+ synchronized void resetLocalCursor() {
+ hideLocalCursor();
+ cursorAvailable = false;
+ }
+
+ synchronized public Dimension getPreferredSize() {
+ return new Dimension(im.width(), im.height());
+ }
+
+ synchronized public Dimension getMinimumSize() {
+ return new Dimension(im.width(), im.height());
+ }
+
+ public void update(Graphics g) {
+ //repaint();
+ }
+
+ synchronized public void paintComponent(Graphics g) {
+ Graphics2D g2 = (Graphics2D) g;
+ g2.drawImage(im.image, 0, 0, this);
+ }
+
+
+ String oldContents = "";
+
+ synchronized public void checkClipboard() {
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
- if (cb != null && cc.viewer.sendClipboard.getValue()) {
- Transferable t = cb.getContents(null);
- if ((t != null) && t.isDataFlavorSupported(DataFlavor.stringFlavor)) {
- try {
- String newContents = (String)t.getTransferData(DataFlavor.stringFlavor);
- if (newContents != null && !newContents.equals(oldContents)) {
- cc.writeClientCutText(newContents, newContents.length());
- oldContents = newContents;
- cc.clipboardDialog.setContents(newContents);
- }
- } catch (java.lang.Exception e) {
- System.out.println("Exception getting clipboard data: " + e.getMessage());
- }
- }
- }
- }
-
- /** Mouse-Motion callback function */
- private void mouseMotionCB(MouseEvent e) {
- if (!cc.viewer.viewOnly.getValue())
- cc.writePointerEvent(e);
- // - If local cursor rendering is enabled then use it
- synchronized(this) {
- if (cursorAvailable) {
- // - Render the cursor!
- if (e.getX() != cursorPosX || e.getY() != cursorPosY) {
- hideLocalCursor();
- if (e.getX() >= 0 && e.getX() < im.width() &&
- e.getY() >= 0 && e.getY() < im.height()) {
- cursorPosX = e.getX();
- cursorPosY = e.getY();
- if (softCursor == null)
- showLocalCursor();
- }
- }
- }
- }
- lastX = e.getX();
- lastY = e.getY();
- }
- public void mouseDragged(MouseEvent e) { mouseMotionCB(e);}
- public void mouseMoved(MouseEvent e) { mouseMotionCB(e);}
-
- /** Mouse callback function */
- private void mouseCB(MouseEvent e) {
- if (!cc.viewer.viewOnly.getValue())
- cc.writePointerEvent(e);
- lastX = e.getX();
- lastY = e.getY();
- }
- public void mouseReleased(MouseEvent e){ mouseCB(e);}
- public void mousePressed(MouseEvent e) { mouseCB(e);}
- public void mouseClicked(MouseEvent e){}
- public void mouseEntered(MouseEvent e){}
- public void mouseExited(MouseEvent e){}
-
- /** MouseWheel callback function */
- private void mouseWheelCB(MouseWheelEvent e) {
- if (!cc.viewer.viewOnly.getValue())
- cc.writeWheelEvent(e);
- }
- public void mouseWheelMoved(MouseWheelEvent e){
- mouseWheelCB(e);
- }
-
- /** Handle the key-typed event. */
- public void keyTyped(KeyEvent e) {}
- /** Handle the key-released event. */
- public void keyReleased(KeyEvent e) {}
- /** Handle the key-pressed event. */
- public void keyPressed(KeyEvent e) {
- if (e.getKeyCode() ==
- (KeyEvent.VK_F1+cc.menuKey-Keysyms.F1)) {
- cc.showMenu(lastX, lastY);
- return;
- }
- if (!cc.viewer.viewOnly.getValue())
- cc.writeKeyEvent(e);
- }
-
- ////////////////////////////////////////////////////////////////////
- // The following methods are called from both RFB and GUI threads
-
- // Note that mutex MUST be held when hideLocalCursor() and showLocalCursor()
- // are called.
-
- private void hideLocalCursor() {
- // - Blit the cursor backing store over the cursor
- if (cursorVisible) {
- cursorVisible = false;
- im.imageRect(cursorBackingX, cursorBackingY, cursorBacking.width(),
- cursorBacking.height(), cursorBacking.data);
- im.put(cursorBackingX, cursorBackingY, cursorBacking.width(),
- cursorBacking.height(), graphics);
- }
- }
-
- private void showLocalCursor() {
- if (cursorAvailable && !cursorVisible) {
- if (!im.getPF().equal(cursor.getPF()) ||
- cursor.width() == 0 || cursor.height() == 0) {
- vlog.debug("attempting to render invalid local cursor");
- cursorAvailable = false;
- return;
- }
- cursorVisible = true;
- if (softCursor != null) return;
-
- int cursorLeft = (int)cursor.hotspot.x;
- int cursorTop = (int)cursor.hotspot.y;
- int cursorRight = cursorLeft + cursor.width();
- int cursorBottom = cursorTop + cursor.height();
-
- int x = (cursorLeft >= 0 ? cursorLeft : 0);
- int y = (cursorTop >= 0 ? cursorTop : 0);
- int w = ((cursorRight < im.width() ? cursorRight : im.width()) - x);
- int h = ((cursorBottom < im.height() ? cursorBottom : im.height()) - y);
-
- cursorBackingX = x;
- cursorBackingY = y;
- cursorBacking.setSize(w, h);
-
- for (int j = 0; j < h; j++)
- System.arraycopy(im.data, (y+j) * im.width() + x,
- cursorBacking.data, j*w, w);
-
- im.maskRect(cursorLeft, cursorTop, cursor.width(), cursor.height(),
- cursor.data, cursor.mask);
- im.put(x, y, w, h, graphics);
- }
- }
-
-
- // run() is executed by the setColourMapEntriesTimerThread - it sleeps for
- // 100ms before actually updating the colourmap.
- public void run() {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {}
- synchronized (this) {
- im.updateColourMap();
- im.put(0, 0, im.width(), im.height(), graphics);
- setColourMapEntriesTimerThread = null;
- }
- }
-
- // access to cc by different threads is specified in CConn
- CConn cc;
-
- // access to the following must be synchronized:
- PixelBufferImage im;
- Graphics graphics;
- Thread setColourMapEntriesTimerThread;
-
- Cursor cursor;
- boolean cursorVisible; // Is cursor currently rendered?
- boolean cursorAvailable; // Is cursor available for rendering?
- int cursorPosX, cursorPosY;
- ManagedPixelBuffer cursorBacking;
- int cursorBackingX, cursorBackingY;
- java.awt.Cursor softCursor;
- static Toolkit tk = Toolkit.getDefaultToolkit();
-
- // the following are only ever accessed by the RFB thread:
- boolean invalidRect;
- int invalidLeft, invalidRight, invalidTop, invalidBottom;
-
- // the following are only ever accessed by the GUI thread:
- int lastX, lastY;
-
- static LogWriter vlog = new LogWriter("DesktopWindow");
-}
+ if (cb != null && cc.viewer.sendClipboard.getValue()) {
+ Transferable t = cb.getContents(null);
+ if ((t != null) && t.isDataFlavorSupported(DataFlavor.stringFlavor)) {
+ try {
+ String newContents = (String)t.getTransferData(DataFlavor.stringFlavor);
+ if (newContents != null && !newContents.equals(oldContents)) {
+ cc.writeClientCutText(newContents, newContents.length());
+ oldContents = newContents;
+ cc.clipboardDialog.setContents(newContents);
+ }
+ } catch (java.lang.Exception e) {
+ System.out.println("Exception getting clipboard data: " + e.getMessage());
+ }
+ }
+ }
+ }
+
+ /** Mouse-Motion callback function */
+ private void mouseMotionCB(MouseEvent e) {
+ if (!cc.viewer.viewOnly.getValue())
+ cc.writePointerEvent(e);
+ // - If local cursor rendering is enabled then use it
+ synchronized(this) {
+ if (cursorAvailable) {
+ // - Render the cursor!
+ if (e.getX() != cursorPosX || e.getY() != cursorPosY) {
+ hideLocalCursor();
+ if (e.getX() >= 0 && e.getX() < im.width() &&
+ e.getY() >= 0 && e.getY() < im.height()) {
+ cursorPosX = e.getX();
+ cursorPosY = e.getY();
+ if (softCursor == null)
+ showLocalCursor();
+ }
+ }
+ }
+ }
+ lastX = e.getX();
+ lastY = e.getY();
+ }
+ public void mouseDragged(MouseEvent e) { mouseMotionCB(e);}
+ public void mouseMoved(MouseEvent e) { mouseMotionCB(e);}
+
+ /** Mouse callback function */
+ private void mouseCB(MouseEvent e) {
+ if (!cc.viewer.viewOnly.getValue())
+ cc.writePointerEvent(e);
+ lastX = e.getX();
+ lastY = e.getY();
+ }
+ public void mouseReleased(MouseEvent e){ mouseCB(e);}
+ public void mousePressed(MouseEvent e) { mouseCB(e);}
+ public void mouseClicked(MouseEvent e){}
+ public void mouseEntered(MouseEvent e){}
+ public void mouseExited(MouseEvent e){}
+
+ /** MouseWheel callback function */
+ private void mouseWheelCB(MouseWheelEvent e) {
+ if (!cc.viewer.viewOnly.getValue())
+ cc.writeWheelEvent(e);
+ }
+ public void mouseWheelMoved(MouseWheelEvent e){
+ mouseWheelCB(e);
+ }
+
+ /** Handle the key-typed event. */
+ public void keyTyped(KeyEvent e) {}
+ /** Handle the key-released event. */
+ public void keyReleased(KeyEvent e) {}
+ /** Handle the key-pressed event. */
+ public void keyPressed(KeyEvent e) {
+ if (e.getKeyCode() ==
+ (KeyEvent.VK_F1+cc.menuKey-Keysyms.F1)) {
+ cc.showMenu(lastX, lastY);
+ return;
+ }
+ if (!cc.viewer.viewOnly.getValue())
+ cc.writeKeyEvent(e);
+ }
+
+ ////////////////////////////////////////////////////////////////////
+ // The following methods are called from both RFB and GUI threads
+
+ // Note that mutex MUST be held when hideLocalCursor() and showLocalCursor()
+ // are called.
+
+ private void hideLocalCursor() {
+ // - Blit the cursor backing store over the cursor
+ if (cursorVisible) {
+ cursorVisible = false;
+ im.imageRect(cursorBackingX, cursorBackingY, cursorBacking.width(),
+ cursorBacking.height(), cursorBacking.data);
+ im.put(cursorBackingX, cursorBackingY, cursorBacking.width(),
+ cursorBacking.height(), graphics);
+ }
+ }
+
+ private void showLocalCursor() {
+ if (cursorAvailable && !cursorVisible) {
+ if (!im.getPF().equal(cursor.getPF()) ||
+ cursor.width() == 0 || cursor.height() == 0) {
+ vlog.debug("attempting to render invalid local cursor");
+ cursorAvailable = false;
+ return;
+ }
+ cursorVisible = true;
+ if (softCursor != null) return;
+
+ int cursorLeft = (int)cursor.hotspot.x;
+ int cursorTop = (int)cursor.hotspot.y;
+ int cursorRight = cursorLeft + cursor.width();
+ int cursorBottom = cursorTop + cursor.height();
+
+ int x = (cursorLeft >= 0 ? cursorLeft : 0);
+ int y = (cursorTop >= 0 ? cursorTop : 0);
+ int w = ((cursorRight < im.width() ? cursorRight : im.width()) - x);
+ int h = ((cursorBottom < im.height() ? cursorBottom : im.height()) - y);
+
+ cursorBackingX = x;
+ cursorBackingY = y;
+ cursorBacking.setSize(w, h);
+
+ for (int j = 0; j < h; j++)
+ System.arraycopy(im.data, (y+j) * im.width() + x,
+ cursorBacking.data, j*w, w);
+
+ im.maskRect(cursorLeft, cursorTop, cursor.width(), cursor.height(),
+ cursor.data, cursor.mask);
+ im.put(x, y, w, h, graphics);
+ }
+ }
+
+
+ // run() is executed by the setColourMapEntriesTimerThread - it sleeps for
+ // 100ms before actually updating the colourmap.
+ public void run() {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {}
+ synchronized (this) {
+ im.updateColourMap();
+ im.put(0, 0, im.width(), im.height(), graphics);
+ setColourMapEntriesTimerThread = null;
+ }
+ }
+
+ // access to cc by different threads is specified in CConn
+ CConn cc;
+
+ // access to the following must be synchronized:
+ PixelBufferImage im;
+ Graphics graphics;
+ Thread setColourMapEntriesTimerThread;
+
+ Cursor cursor;
+ boolean cursorVisible; // Is cursor currently rendered?
+ boolean cursorAvailable; // Is cursor available for rendering?
+ int cursorPosX, cursorPosY;
+ ManagedPixelBuffer cursorBacking;
+ int cursorBackingX, cursorBackingY;
+ java.awt.Cursor softCursor;
+ static Toolkit tk = Toolkit.getDefaultToolkit();
+
+ // the following are only ever accessed by the RFB thread:
+ boolean invalidRect;
+ int invalidLeft, invalidRight, invalidTop, invalidBottom;
+
+ // the following are only ever accessed by the GUI thread:
+ int lastX, lastY;
+
+ static LogWriter vlog = new LogWriter("DesktopWindow");
+}
diff --git a/java/src/com/tigervnc/vncviewer/OptionsDialog.java b/java/src/com/tigervnc/vncviewer/OptionsDialog.java
index 98198158..f38a1e65 100644
--- a/java/src/com/tigervnc/vncviewer/OptionsDialog.java
+++ b/java/src/com/tigervnc/vncviewer/OptionsDialog.java
@@ -1,380 +1,380 @@
-/* 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.
- */
-
+/* 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.vncviewer;
-
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.*;
-import javax.swing.border.*;
-import javax.swing.filechooser.*;
-import javax.swing.ImageIcon;
-import java.net.URL;
-import java.io.IOException;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.filechooser.*;
+import javax.swing.ImageIcon;
+import java.net.URL;
+import java.io.IOException;
import com.tigervnc.rfb.*;
import com.tigervnc.rfb.Exception;
-
-class OptionsDialog extends Dialog implements
- ActionListener,
- ItemListener
-{
-
- // Constants
- // Static variables
- static LogWriter vlog = new LogWriter("OptionsDialog");
-
- OptionsDialogCallback cb;
- JPanel FormatPanel, InputsPanel, MiscPanel, DefaultsPanel, SecPanel;
- JCheckBox autoSelect, customCompressLevel, noJpeg;
- JComboBox menuKey, compressLevel, qualityLevel ;
- ButtonGroup encodingGroup, colourGroup;
- JRadioButton zrle, hextile, tight, raw;
- JRadioButton fullColour, mediumColour, lowColour, veryLowColour;
- JCheckBox viewOnly, acceptClipboard, sendClipboard;
- JCheckBox fullScreen, shared, useLocalCursor, fastCopyRect;
- JCheckBox secVeNCrypt, encNone, encTLS, encX509;
- JCheckBox secNone, secVnc, secPlain, secIdent, sendLocalUsername;
- JButton okButton, cancelButton;
- JButton ca, crl;
- JButton defSaveButton;
- boolean encryption = true;
- UserPrefs defaults;
-
- public OptionsDialog(OptionsDialogCallback cb_) {
- super(false);
- cb = cb_;
- setResizable(false);
- setTitle("VNC Viewer Options");
- defaults = new UserPrefs("vncviewer");
-
- getContentPane().setLayout(
- new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
-
- JTabbedPane tabPane = new JTabbedPane();
-
- ButtonGroup encodingGroup = new ButtonGroup();
- ButtonGroup colourGroup = new ButtonGroup();
-
- // Colour & Encoding tab
- FormatPanel=new JPanel(new GridBagLayout());
-
- autoSelect = new JCheckBox("Auto Select");
- autoSelect.addItemListener(this);
-
- JPanel encodingPanel = new JPanel(new GridBagLayout());
- encodingPanel.setBorder(BorderFactory.createTitledBorder("Preferred encoding"));
- zrle = addRadioCheckbox("ZRLE", encodingGroup, encodingPanel);
- hextile = addRadioCheckbox("Hextile", encodingGroup, encodingPanel);
- tight = addRadioCheckbox("Tight", encodingGroup, encodingPanel);
- raw = addRadioCheckbox("Raw", encodingGroup, encodingPanel);
-
- JPanel tightPanel = new JPanel(new GridBagLayout());
- customCompressLevel = new JCheckBox("Custom Compression Level");
- customCompressLevel.addItemListener(this);
- Object[] compressionLevels = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
- compressLevel = new JComboBox(compressionLevels);
- JLabel compressionLabel = new JLabel("Level (1=fast, 9=best)");
- noJpeg = new JCheckBox("Allow JPEG Compression");
- noJpeg.addItemListener(this);
- Object[] qualityLevels = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
- qualityLevel = new JComboBox(qualityLevels);
- JLabel qualityLabel = new JLabel("Level (1=poor, 9=best)");
- addGBComponent(customCompressLevel, tightPanel, 0, 0, 2, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(0,2,0,0));
- addGBComponent(compressLevel, tightPanel, 0, 1, 1, 1, 2, 2, 0, 0, GridBagConstraints.NONE, GridBagConstraints.FIRST_LINE_START, new Insets(0,20,0,0));
- addGBComponent(compressionLabel, tightPanel, 1, 1, 1, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(0,5,0,0));
- addGBComponent(noJpeg, tightPanel, 0, 2, 2, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(0,2,0,0));
- addGBComponent(qualityLevel, tightPanel, 0, 3, 1, 1, 2, 2, 0, 0, GridBagConstraints.NONE, GridBagConstraints.FIRST_LINE_START, new Insets(0,20,0,0));
- addGBComponent(qualityLabel, tightPanel, 1, 3, 1, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(0,5,0,0));
-
-
- JPanel colourPanel = new JPanel(new GridBagLayout());
- colourPanel.setBorder(BorderFactory.createTitledBorder("Colour level"));
- fullColour = addRadioCheckbox("Full (all available colours)", colourGroup, colourPanel);
- mediumColour = addRadioCheckbox("Medium (256 colours)", colourGroup, colourPanel);
- lowColour = addRadioCheckbox("Low (64 colours)", colourGroup, colourPanel);
- veryLowColour = addRadioCheckbox("Very low(8 colours)", colourGroup, colourPanel);
-
- addGBComponent(autoSelect,FormatPanel, 0, 0, 2, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(0,2,0,0));
- addGBComponent(encodingPanel,FormatPanel, 0, 1, 1, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(0,2,0,0));
- addGBComponent(colourPanel,FormatPanel, 1, 1, 1, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_END, new Insets(0,2,0,0));
- addGBComponent(tightPanel,FormatPanel, 0, 2, 2, GridBagConstraints.REMAINDER, 2, 2, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(0,2,0,0));
-
- // Inputs tab
- InputsPanel=new JPanel(new GridBagLayout());
-
- viewOnly = new JCheckBox("View Only (ignore mouse & keyboard)");
- viewOnly.addItemListener(this);
- acceptClipboard = new JCheckBox("Accept clipboard from server");
- acceptClipboard.addItemListener(this);
- sendClipboard = new JCheckBox("Send clipboard to server");
- sendClipboard.addItemListener(this);
- JLabel menuKeyLabel = new JLabel("Menu Key");
- String[] menuKeys =
- { "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12" };
- menuKey = new JComboBox(menuKeys);
- menuKey.addItemListener(this);
- addGBComponent(viewOnly,InputsPanel, 0, 0, 2, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
- addGBComponent(acceptClipboard,InputsPanel, 0, 1, 2, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
- addGBComponent(sendClipboard,InputsPanel, 0, 2, 2, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
- addGBComponent(menuKeyLabel,InputsPanel, 0, 3, 1, GridBagConstraints.REMAINDER, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(8,10,0,4));
- addGBComponent(menuKey,InputsPanel, 1, 3, 1, GridBagConstraints.REMAINDER, 0, 0, 2, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(4,4,0,125));
- //((javax.swing.plaf.basic.BasicComboBoxRenderer)menuKey.getRenderer()).setBorder(new EmptyBorder(0,3,0,3));
-
- // Misc tab
- MiscPanel=new JPanel(new GridBagLayout());
-
- fullScreen = new JCheckBox("Full-screen mode");
- fullScreen.addItemListener(this);
- shared = new JCheckBox("Shared connection (do not disconnect other viewers)");
- shared.addItemListener(this);
- useLocalCursor = new JCheckBox("Render cursor locally");
- useLocalCursor.addItemListener(this);
- fastCopyRect = new JCheckBox("Fast CopyRect");
- fastCopyRect.addItemListener(this);
- addGBComponent(fullScreen,MiscPanel, 0, 0, 1, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
- addGBComponent(shared,MiscPanel, 0, 1, 1, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
- addGBComponent(useLocalCursor,MiscPanel, 0, 2, 1, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
- addGBComponent(fastCopyRect,MiscPanel, 0, 3, 1, GridBagConstraints.REMAINDER, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(4,4,0,4));
-
- // load/save tab
- DefaultsPanel=new JPanel(new GridBagLayout());
-
- JPanel configPanel = new JPanel(new GridBagLayout());
- configPanel.setBorder(BorderFactory.createTitledBorder("Configuration File"));
- JButton cfReloadButton = new JButton("Reload");
- cfReloadButton.addActionListener(this);
- addGBComponent(cfReloadButton,configPanel, 0, 0, 1, 1, 0, 0, 0, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(4,8,4,8));
- JButton cfSaveButton = new JButton("Save");
- cfSaveButton.addActionListener(this);
- addGBComponent(cfSaveButton,configPanel, 0, 1, 1, 1, 0, 0, 0, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(4,8,4,8));
- JButton cfSaveAsButton = new JButton("Save As...");
- cfSaveAsButton.addActionListener(this);
- addGBComponent(cfSaveAsButton,configPanel, 0, 2, 1, 1, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(4,8,4,8));
- cfReloadButton.setEnabled(false);
- cfSaveButton.setEnabled(false);
-
- JPanel defaultsPanel = new JPanel(new GridBagLayout());
- defaultsPanel.setBorder(BorderFactory.createTitledBorder("Defaults"));
- JButton defReloadButton = new JButton("Reload");
- defReloadButton.addActionListener(this);
- addGBComponent(defReloadButton,defaultsPanel, 0, 0, 1, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(4,8,4,8));
- defSaveButton = new JButton("Save");
- defSaveButton.addActionListener(this);
- addGBComponent(defSaveButton,defaultsPanel, 0, 1, 1, 1, 0, 0, 0, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(4,8,4,8));
-
- addGBComponent(configPanel,DefaultsPanel, 0, 0, 1, GridBagConstraints.REMAINDER, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.PAGE_START, new Insets(4,4,4,4));
- addGBComponent(defaultsPanel,DefaultsPanel, 1, 0, 1, GridBagConstraints.REMAINDER, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.PAGE_START, new Insets(4,4,4,4));
-
- // security tab
- SecPanel=new JPanel(new GridBagLayout());
-
- JPanel encryptionPanel = new JPanel(new GridBagLayout());
- encryptionPanel.setBorder(BorderFactory.createTitledBorder("Session Encryption"));
- encNone = addCheckbox("None", null, encryptionPanel);
- encTLS = addCheckbox("Anonymous TLS", null, encryptionPanel);
- encX509 = addJCheckBox("TLS with X.509 certificates", null, encryptionPanel, new GridBagConstraints(0,2,1,1,1,1,GridBagConstraints.LINE_START,GridBagConstraints.REMAINDER,new Insets(0,0,0,60),0,0));
-
- JPanel x509Panel = new JPanel(new GridBagLayout());
- x509Panel.setBorder(BorderFactory.createTitledBorder("X.509 certificates"));
- ca = new JButton("Load CA certificate");
- ca.setPreferredSize(new Dimension(145,25));
- ca.addActionListener(this);
- crl = new JButton("Load CRL certificate");
- crl.setPreferredSize(new Dimension(145,25));
- crl.addActionListener(this);
- addGBComponent(ca, x509Panel, 0, 0, 1, 1, 2, 2, 0, 1, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(2,2,2,2));
- addGBComponent(crl, x509Panel, 1, 0, 1, 1, 2, 2, 1, 1, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(2,2,2,2));
-
- JPanel authPanel = new JPanel(new GridBagLayout());
- authPanel.setBorder(BorderFactory.createTitledBorder("Authentication"));
- secNone = addCheckbox("None", null, authPanel);
- secVnc = addCheckbox("Standard VNC", null, authPanel);
- secPlain = addJCheckBox("Plaintext", null, authPanel, new GridBagConstraints(0,2,1,1,1,1,GridBagConstraints.LINE_START,GridBagConstraints.NONE,new Insets(0,0,0,5),0,0));
- secIdent = addJCheckBox("Ident", null, authPanel, new GridBagConstraints(0,3,1,1,1,1,GridBagConstraints.LINE_START,GridBagConstraints.NONE,new Insets(0,0,0,5),0,0));
- sendLocalUsername = new JCheckBox("Send Local Username");
- sendLocalUsername.addItemListener(this);
- addGBComponent(sendLocalUsername, authPanel, 1, 2, 1, 2, 0, 0, 2, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(0,20,0,0));
-
- secVeNCrypt = new JCheckBox("Extended encryption and authentication methods (VeNCrypt)");
- secVeNCrypt.addItemListener(this);
- addGBComponent(secVeNCrypt,SecPanel, 0, 0, 1, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(0,2,0,20));
- addGBComponent(encryptionPanel,SecPanel, 0, 1, 1, 1, 2, 2, 1, 0, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(0,4,2,4));
- addGBComponent(x509Panel,SecPanel, 0, 2, 1, 1, 2, 2, 1, 0, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(2,4,2,4));
- addGBComponent(authPanel,SecPanel, 0, 3, 1, 1, 2, 2, 1, 1, GridBagConstraints.NONE, GridBagConstraints.FIRST_LINE_START, new Insets(2,4,2,4));
-
- tabPane.add(FormatPanel);
- tabPane.add(InputsPanel);
- tabPane.add(MiscPanel);
- tabPane.add(DefaultsPanel);
- tabPane.add(SecPanel);
- tabPane.addTab("Colour & Encoding", FormatPanel);
- tabPane.addTab("Inputs", InputsPanel);
- tabPane.addTab("Misc", MiscPanel);
- tabPane.addTab("Load / Save", DefaultsPanel);
- tabPane.addTab("Security", SecPanel);
- tabPane.setBorder(BorderFactory.createEmptyBorder(4,4,0,4));
-
- okButton = new JButton("OK");
- okButton.setPreferredSize(new Dimension(90,30));
- okButton.addActionListener(this);
- cancelButton = new JButton("Cancel");
- cancelButton.setPreferredSize(new Dimension(90,30));
- cancelButton.addActionListener(this);
-
- JPanel buttonPane = new JPanel();
- buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));
- buttonPane.setBorder(BorderFactory.createEmptyBorder(4,0,0,0));
- buttonPane.add(Box.createHorizontalGlue());
- buttonPane.add(okButton);
- buttonPane.add(Box.createRigidArea(new Dimension(4,0)));
- buttonPane.add(cancelButton);
- buttonPane.add(Box.createRigidArea(new Dimension(4,0)));
-
- this.getContentPane().add(tabPane);
- this.getContentPane().add(buttonPane);
-
- pack();
-
- }
-
- public void initDialog() {
- if (cb != null) cb.setOptions();
- zrle.setEnabled(!autoSelect.isSelected());
- hextile.setEnabled(!autoSelect.isSelected());
- tight.setEnabled(!autoSelect.isSelected());
- raw.setEnabled(!autoSelect.isSelected());
- fullColour.setEnabled(!autoSelect.isSelected());
- mediumColour.setEnabled(!autoSelect.isSelected());
- lowColour.setEnabled(!autoSelect.isSelected());
- veryLowColour.setEnabled(!autoSelect.isSelected());
- compressLevel.setEnabled(customCompressLevel.isSelected());
- qualityLevel.setEnabled(noJpeg.isSelected());
- sendLocalUsername.setEnabled(secVeNCrypt.isEnabled()&&
- (secPlain.isSelected()||secIdent.isSelected()));
- }
-
- JRadioButton addRadioCheckbox(String str, ButtonGroup group, JPanel panel) {
- JRadioButton c = new JRadioButton(str);
- GridBagConstraints gbc = new GridBagConstraints();
- gbc.anchor = GridBagConstraints.LINE_START;
- gbc.gridwidth = GridBagConstraints.REMAINDER;
- gbc.weightx = 1;
- gbc.weighty = 1;
- panel.add(c,gbc);
- group.add(c);
- c.addItemListener(this);
- return c;
- }
-
- JCheckBox addCheckbox(String str, ButtonGroup group, JPanel panel) {
- JCheckBox c = new JCheckBox(str);
- GridBagConstraints gbc = new GridBagConstraints();
- gbc.anchor = GridBagConstraints.LINE_START;
- gbc.gridwidth = GridBagConstraints.REMAINDER;
- gbc.weightx = 1;
- gbc.weighty = 1;
- panel.add(c,gbc);
- if (group != null)
- group.add(c);
- c.addItemListener(this);
- return c;
- }
-
- JCheckBox addJCheckBox(String str, ButtonGroup group, JPanel panel,
- GridBagConstraints gbc) {
- JCheckBox c = new JCheckBox(str);
- panel.add(c,gbc);
- if (group != null)
- group.add(c);
- c.addItemListener(this);
-
- return c;
- }
-
- public void actionPerformed(ActionEvent e) {
- Object s = e.getSource();
- if (s instanceof JButton && (JButton)s == okButton) {
- ok = true;
- if (cb != null) cb.getOptions();
- endDialog();
- } else if (s instanceof JButton && (JButton)s == cancelButton) {
- ok = false;
- endDialog();
- } else if (s instanceof JButton && (JButton)s == defSaveButton) {
- try {
- defaults.Save();
- } catch (java.lang.Exception x) { }
- } else if (s instanceof JButton && (JButton)s == ca) {
- JFileChooser fc = new JFileChooser();
- fc.setDialogTitle("Path to X509 CA certificate");
- int ret = fc.showOpenDialog(this);
- if (ret == JFileChooser.APPROVE_OPTION)
- CSecurityTLS.x509ca.setParam(fc.getSelectedFile().toString());
- } else if (s instanceof JButton && (JButton)s == crl) {
- JFileChooser fc = new JFileChooser();
- fc.setDialogTitle("Path to X509 CRL file");
- int ret = fc.showOpenDialog(this);
- if (ret == JFileChooser.APPROVE_OPTION)
- CSecurityTLS.x509crl.setParam(fc.getSelectedFile().toString());
- }
- }
-
- public void itemStateChanged(ItemEvent e) {
- Object s = e.getSource();
- if (s instanceof JCheckBox && (JCheckBox)s == autoSelect) {
- zrle.setEnabled(!autoSelect.isSelected());
- hextile.setEnabled(!autoSelect.isSelected());
- tight.setEnabled(!autoSelect.isSelected());
- raw.setEnabled(!autoSelect.isSelected());
- fullColour.setEnabled(!autoSelect.isSelected());
- mediumColour.setEnabled(!autoSelect.isSelected());
- lowColour.setEnabled(!autoSelect.isSelected());
- veryLowColour.setEnabled(!autoSelect.isSelected());
- defaults.setPref("autoSelect",(autoSelect.isSelected()) ? "on" : "off");
- }
- if (s instanceof JCheckBox && (JCheckBox)s == customCompressLevel) {
- compressLevel.setEnabled(customCompressLevel.isSelected());
- defaults.setPref("customCompressLevel",(customCompressLevel.isSelected()) ? "on" : "off");
- }
- if (s instanceof JCheckBox && (JCheckBox)s == noJpeg) {
- qualityLevel.setEnabled(noJpeg.isSelected());
- defaults.setPref("noJpeg",(noJpeg.isSelected()) ? "on" : "off");
- }
- if (s instanceof JCheckBox && (JCheckBox)s == sendLocalUsername) {
- defaults.setPref("sendLocalUsername",(sendLocalUsername.isSelected()) ? "on" : "off");
- }
- if (s instanceof JCheckBox && (JCheckBox)s == secVeNCrypt) {
- encNone.setEnabled(secVeNCrypt.isSelected());
- encTLS.setEnabled(secVeNCrypt.isSelected());
- encX509.setEnabled(secVeNCrypt.isSelected());
- ca.setEnabled(secVeNCrypt.isSelected());
- crl.setEnabled(secVeNCrypt.isSelected());
- secIdent.setEnabled(secVeNCrypt.isSelected());
- secNone.setEnabled(secVeNCrypt.isSelected());
- secVnc.setEnabled(secVeNCrypt.isSelected());
- secPlain.setEnabled(secVeNCrypt.isSelected());
- sendLocalUsername.setEnabled(secVeNCrypt.isSelected());
- }
- if (s instanceof JCheckBox && (JCheckBox)s == secIdent ||
- s instanceof JCheckBox && (JCheckBox)s == secPlain) {
- sendLocalUsername.setEnabled(secIdent.isSelected()||secPlain.isSelected());
- }
- }
-
-}
+
+class OptionsDialog extends Dialog implements
+ ActionListener,
+ ItemListener
+{
+
+ // Constants
+ // Static variables
+ static LogWriter vlog = new LogWriter("OptionsDialog");
+
+ OptionsDialogCallback cb;
+ JPanel FormatPanel, InputsPanel, MiscPanel, DefaultsPanel, SecPanel;
+ JCheckBox autoSelect, customCompressLevel, noJpeg;
+ JComboBox menuKey, compressLevel, qualityLevel ;
+ ButtonGroup encodingGroup, colourGroup;
+ JRadioButton zrle, hextile, tight, raw;
+ JRadioButton fullColour, mediumColour, lowColour, veryLowColour;
+ JCheckBox viewOnly, acceptClipboard, sendClipboard;
+ JCheckBox fullScreen, shared, useLocalCursor, fastCopyRect;
+ JCheckBox secVeNCrypt, encNone, encTLS, encX509;
+ JCheckBox secNone, secVnc, secPlain, secIdent, sendLocalUsername;
+ JButton okButton, cancelButton;
+ JButton ca, crl;
+ JButton defSaveButton;
+ boolean encryption = true;
+ UserPrefs defaults;
+
+ public OptionsDialog(OptionsDialogCallback cb_) {
+ super(false);
+ cb = cb_;
+ setResizable(false);
+ setTitle("VNC Viewer Options");
+ defaults = new UserPrefs("vncviewer");
+
+ getContentPane().setLayout(
+ new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
+
+ JTabbedPane tabPane = new JTabbedPane();
+
+ ButtonGroup encodingGroup = new ButtonGroup();
+ ButtonGroup colourGroup = new ButtonGroup();
+
+ // Colour & Encoding tab
+ FormatPanel=new JPanel(new GridBagLayout());
+
+ autoSelect = new JCheckBox("Auto Select");
+ autoSelect.addItemListener(this);
+
+ JPanel encodingPanel = new JPanel(new GridBagLayout());
+ encodingPanel.setBorder(BorderFactory.createTitledBorder("Preferred encoding"));
+ zrle = addRadioCheckbox("ZRLE", encodingGroup, encodingPanel);
+ hextile = addRadioCheckbox("Hextile", encodingGroup, encodingPanel);
+ tight = addRadioCheckbox("Tight", encodingGroup, encodingPanel);
+ raw = addRadioCheckbox("Raw", encodingGroup, encodingPanel);
+
+ JPanel tightPanel = new JPanel(new GridBagLayout());
+ customCompressLevel = new JCheckBox("Custom Compression Level");
+ customCompressLevel.addItemListener(this);
+ Object[] compressionLevels = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ compressLevel = new JComboBox(compressionLevels);
+ JLabel compressionLabel = new JLabel("Level (1=fast, 9=best)");
+ noJpeg = new JCheckBox("Allow JPEG Compression");
+ noJpeg.addItemListener(this);
+ Object[] qualityLevels = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ qualityLevel = new JComboBox(qualityLevels);
+ JLabel qualityLabel = new JLabel("Level (1=poor, 9=best)");
+ addGBComponent(customCompressLevel, tightPanel, 0, 0, 2, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(0,2,0,0));
+ addGBComponent(compressLevel, tightPanel, 0, 1, 1, 1, 2, 2, 0, 0, GridBagConstraints.NONE, GridBagConstraints.FIRST_LINE_START, new Insets(0,20,0,0));
+ addGBComponent(compressionLabel, tightPanel, 1, 1, 1, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(0,5,0,0));
+ addGBComponent(noJpeg, tightPanel, 0, 2, 2, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(0,2,0,0));
+ addGBComponent(qualityLevel, tightPanel, 0, 3, 1, 1, 2, 2, 0, 0, GridBagConstraints.NONE, GridBagConstraints.FIRST_LINE_START, new Insets(0,20,0,0));
+ addGBComponent(qualityLabel, tightPanel, 1, 3, 1, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(0,5,0,0));
+
+
+ JPanel colourPanel = new JPanel(new GridBagLayout());
+ colourPanel.setBorder(BorderFactory.createTitledBorder("Colour level"));
+ fullColour = addRadioCheckbox("Full (all available colours)", colourGroup, colourPanel);
+ mediumColour = addRadioCheckbox("Medium (256 colours)", colourGroup, colourPanel);
+ lowColour = addRadioCheckbox("Low (64 colours)", colourGroup, colourPanel);
+ veryLowColour = addRadioCheckbox("Very low(8 colours)", colourGroup, colourPanel);
+
+ addGBComponent(autoSelect,FormatPanel, 0, 0, 2, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(0,2,0,0));
+ addGBComponent(encodingPanel,FormatPanel, 0, 1, 1, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(0,2,0,0));
+ addGBComponent(colourPanel,FormatPanel, 1, 1, 1, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_END, new Insets(0,2,0,0));
+ addGBComponent(tightPanel,FormatPanel, 0, 2, 2, GridBagConstraints.REMAINDER, 2, 2, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(0,2,0,0));
+
+ // Inputs tab
+ InputsPanel=new JPanel(new GridBagLayout());
+
+ viewOnly = new JCheckBox("View Only (ignore mouse & keyboard)");
+ viewOnly.addItemListener(this);
+ acceptClipboard = new JCheckBox("Accept clipboard from server");
+ acceptClipboard.addItemListener(this);
+ sendClipboard = new JCheckBox("Send clipboard to server");
+ sendClipboard.addItemListener(this);
+ JLabel menuKeyLabel = new JLabel("Menu Key");
+ String[] menuKeys =
+ { "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12" };
+ menuKey = new JComboBox(menuKeys);
+ menuKey.addItemListener(this);
+ addGBComponent(viewOnly,InputsPanel, 0, 0, 2, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
+ addGBComponent(acceptClipboard,InputsPanel, 0, 1, 2, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
+ addGBComponent(sendClipboard,InputsPanel, 0, 2, 2, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
+ addGBComponent(menuKeyLabel,InputsPanel, 0, 3, 1, GridBagConstraints.REMAINDER, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(8,10,0,4));
+ addGBComponent(menuKey,InputsPanel, 1, 3, 1, GridBagConstraints.REMAINDER, 0, 0, 2, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(4,4,0,125));
+ //((javax.swing.plaf.basic.BasicComboBoxRenderer)menuKey.getRenderer()).setBorder(new EmptyBorder(0,3,0,3));
+
+ // Misc tab
+ MiscPanel=new JPanel(new GridBagLayout());
+
+ fullScreen = new JCheckBox("Full-screen mode");
+ fullScreen.addItemListener(this);
+ shared = new JCheckBox("Shared connection (do not disconnect other viewers)");
+ shared.addItemListener(this);
+ useLocalCursor = new JCheckBox("Render cursor locally");
+ useLocalCursor.addItemListener(this);
+ fastCopyRect = new JCheckBox("Fast CopyRect");
+ fastCopyRect.addItemListener(this);
+ addGBComponent(fullScreen,MiscPanel, 0, 0, 1, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
+ addGBComponent(shared,MiscPanel, 0, 1, 1, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
+ addGBComponent(useLocalCursor,MiscPanel, 0, 2, 1, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
+ addGBComponent(fastCopyRect,MiscPanel, 0, 3, 1, GridBagConstraints.REMAINDER, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(4,4,0,4));
+
+ // load/save tab
+ DefaultsPanel=new JPanel(new GridBagLayout());
+
+ JPanel configPanel = new JPanel(new GridBagLayout());
+ configPanel.setBorder(BorderFactory.createTitledBorder("Configuration File"));
+ JButton cfReloadButton = new JButton("Reload");
+ cfReloadButton.addActionListener(this);
+ addGBComponent(cfReloadButton,configPanel, 0, 0, 1, 1, 0, 0, 0, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(4,8,4,8));
+ JButton cfSaveButton = new JButton("Save");
+ cfSaveButton.addActionListener(this);
+ addGBComponent(cfSaveButton,configPanel, 0, 1, 1, 1, 0, 0, 0, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(4,8,4,8));
+ JButton cfSaveAsButton = new JButton("Save As...");
+ cfSaveAsButton.addActionListener(this);
+ addGBComponent(cfSaveAsButton,configPanel, 0, 2, 1, 1, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(4,8,4,8));
+ cfReloadButton.setEnabled(false);
+ cfSaveButton.setEnabled(false);
+
+ JPanel defaultsPanel = new JPanel(new GridBagLayout());
+ defaultsPanel.setBorder(BorderFactory.createTitledBorder("Defaults"));
+ JButton defReloadButton = new JButton("Reload");
+ defReloadButton.addActionListener(this);
+ addGBComponent(defReloadButton,defaultsPanel, 0, 0, 1, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(4,8,4,8));
+ defSaveButton = new JButton("Save");
+ defSaveButton.addActionListener(this);
+ addGBComponent(defSaveButton,defaultsPanel, 0, 1, 1, 1, 0, 0, 0, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(4,8,4,8));
+
+ addGBComponent(configPanel,DefaultsPanel, 0, 0, 1, GridBagConstraints.REMAINDER, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.PAGE_START, new Insets(4,4,4,4));
+ addGBComponent(defaultsPanel,DefaultsPanel, 1, 0, 1, GridBagConstraints.REMAINDER, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.PAGE_START, new Insets(4,4,4,4));
+
+ // security tab
+ SecPanel=new JPanel(new GridBagLayout());
+
+ JPanel encryptionPanel = new JPanel(new GridBagLayout());
+ encryptionPanel.setBorder(BorderFactory.createTitledBorder("Session Encryption"));
+ encNone = addCheckbox("None", null, encryptionPanel);
+ encTLS = addCheckbox("Anonymous TLS", null, encryptionPanel);
+ encX509 = addJCheckBox("TLS with X.509 certificates", null, encryptionPanel, new GridBagConstraints(0,2,1,1,1,1,GridBagConstraints.LINE_START,GridBagConstraints.REMAINDER,new Insets(0,0,0,60),0,0));
+
+ JPanel x509Panel = new JPanel(new GridBagLayout());
+ x509Panel.setBorder(BorderFactory.createTitledBorder("X.509 certificates"));
+ ca = new JButton("Load CA certificate");
+ ca.setPreferredSize(new Dimension(145,25));
+ ca.addActionListener(this);
+ crl = new JButton("Load CRL certificate");
+ crl.setPreferredSize(new Dimension(145,25));
+ crl.addActionListener(this);
+ addGBComponent(ca, x509Panel, 0, 0, 1, 1, 2, 2, 0, 1, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(2,2,2,2));
+ addGBComponent(crl, x509Panel, 1, 0, 1, 1, 2, 2, 1, 1, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(2,2,2,2));
+
+ JPanel authPanel = new JPanel(new GridBagLayout());
+ authPanel.setBorder(BorderFactory.createTitledBorder("Authentication"));
+ secNone = addCheckbox("None", null, authPanel);
+ secVnc = addCheckbox("Standard VNC", null, authPanel);
+ secPlain = addJCheckBox("Plaintext", null, authPanel, new GridBagConstraints(0,2,1,1,1,1,GridBagConstraints.LINE_START,GridBagConstraints.NONE,new Insets(0,0,0,5),0,0));
+ secIdent = addJCheckBox("Ident", null, authPanel, new GridBagConstraints(0,3,1,1,1,1,GridBagConstraints.LINE_START,GridBagConstraints.NONE,new Insets(0,0,0,5),0,0));
+ sendLocalUsername = new JCheckBox("Send Local Username");
+ sendLocalUsername.addItemListener(this);
+ addGBComponent(sendLocalUsername, authPanel, 1, 2, 1, 2, 0, 0, 2, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(0,20,0,0));
+
+ secVeNCrypt = new JCheckBox("Extended encryption and authentication methods (VeNCrypt)");
+ secVeNCrypt.addItemListener(this);
+ addGBComponent(secVeNCrypt,SecPanel, 0, 0, 1, 1, 2, 2, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(0,2,0,20));
+ addGBComponent(encryptionPanel,SecPanel, 0, 1, 1, 1, 2, 2, 1, 0, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(0,4,2,4));
+ addGBComponent(x509Panel,SecPanel, 0, 2, 1, 1, 2, 2, 1, 0, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(2,4,2,4));
+ addGBComponent(authPanel,SecPanel, 0, 3, 1, 1, 2, 2, 1, 1, GridBagConstraints.NONE, GridBagConstraints.FIRST_LINE_START, new Insets(2,4,2,4));
+
+ tabPane.add(FormatPanel);
+ tabPane.add(InputsPanel);
+ tabPane.add(MiscPanel);
+ tabPane.add(DefaultsPanel);
+ tabPane.add(SecPanel);
+ tabPane.addTab("Colour & Encoding", FormatPanel);
+ tabPane.addTab("Inputs", InputsPanel);
+ tabPane.addTab("Misc", MiscPanel);
+ tabPane.addTab("Load / Save", DefaultsPanel);
+ tabPane.addTab("Security", SecPanel);
+ tabPane.setBorder(BorderFactory.createEmptyBorder(4,4,0,4));
+
+ okButton = new JButton("OK");
+ okButton.setPreferredSize(new Dimension(90,30));
+ okButton.addActionListener(this);
+ cancelButton = new JButton("Cancel");
+ cancelButton.setPreferredSize(new Dimension(90,30));
+ cancelButton.addActionListener(this);
+
+ JPanel buttonPane = new JPanel();
+ buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));
+ buttonPane.setBorder(BorderFactory.createEmptyBorder(4,0,0,0));
+ buttonPane.add(Box.createHorizontalGlue());
+ buttonPane.add(okButton);
+ buttonPane.add(Box.createRigidArea(new Dimension(4,0)));
+ buttonPane.add(cancelButton);
+ buttonPane.add(Box.createRigidArea(new Dimension(4,0)));
+
+ this.getContentPane().add(tabPane);
+ this.getContentPane().add(buttonPane);
+
+ pack();
+
+ }
+
+ public void initDialog() {
+ if (cb != null) cb.setOptions();
+ zrle.setEnabled(!autoSelect.isSelected());
+ hextile.setEnabled(!autoSelect.isSelected());
+ tight.setEnabled(!autoSelect.isSelected());
+ raw.setEnabled(!autoSelect.isSelected());
+ fullColour.setEnabled(!autoSelect.isSelected());
+ mediumColour.setEnabled(!autoSelect.isSelected());
+ lowColour.setEnabled(!autoSelect.isSelected());
+ veryLowColour.setEnabled(!autoSelect.isSelected());
+ compressLevel.setEnabled(customCompressLevel.isSelected());
+ qualityLevel.setEnabled(noJpeg.isSelected());
+ sendLocalUsername.setEnabled(secVeNCrypt.isEnabled()&&
+ (secPlain.isSelected()||secIdent.isSelected()));
+ }
+
+ JRadioButton addRadioCheckbox(String str, ButtonGroup group, JPanel panel) {
+ JRadioButton c = new JRadioButton(str);
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.anchor = GridBagConstraints.LINE_START;
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.weightx = 1;
+ gbc.weighty = 1;
+ panel.add(c,gbc);
+ group.add(c);
+ c.addItemListener(this);
+ return c;
+ }
+
+ JCheckBox addCheckbox(String str, ButtonGroup group, JPanel panel) {
+ JCheckBox c = new JCheckBox(str);
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.anchor = GridBagConstraints.LINE_START;
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.weightx = 1;
+ gbc.weighty = 1;
+ panel.add(c,gbc);
+ if (group != null)
+ group.add(c);
+ c.addItemListener(this);
+ return c;
+ }
+
+ JCheckBox addJCheckBox(String str, ButtonGroup group, JPanel panel,
+ GridBagConstraints gbc) {
+ JCheckBox c = new JCheckBox(str);
+ panel.add(c,gbc);
+ if (group != null)
+ group.add(c);
+ c.addItemListener(this);
+
+ return c;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ Object s = e.getSource();
+ if (s instanceof JButton && (JButton)s == okButton) {
+ ok = true;
+ if (cb != null) cb.getOptions();
+ endDialog();
+ } else if (s instanceof JButton && (JButton)s == cancelButton) {
+ ok = false;
+ endDialog();
+ } else if (s instanceof JButton && (JButton)s == defSaveButton) {
+ try {
+ defaults.Save();
+ } catch (java.lang.Exception x) { }
+ } else if (s instanceof JButton && (JButton)s == ca) {
+ JFileChooser fc = new JFileChooser();
+ fc.setDialogTitle("Path to X509 CA certificate");
+ int ret = fc.showOpenDialog(this);
+ if (ret == JFileChooser.APPROVE_OPTION)
+ CSecurityTLS.x509ca.setParam(fc.getSelectedFile().toString());
+ } else if (s instanceof JButton && (JButton)s == crl) {
+ JFileChooser fc = new JFileChooser();
+ fc.setDialogTitle("Path to X509 CRL file");
+ int ret = fc.showOpenDialog(this);
+ if (ret == JFileChooser.APPROVE_OPTION)
+ CSecurityTLS.x509crl.setParam(fc.getSelectedFile().toString());
+ }
+ }
+
+ public void itemStateChanged(ItemEvent e) {
+ Object s = e.getSource();
+ if (s instanceof JCheckBox && (JCheckBox)s == autoSelect) {
+ zrle.setEnabled(!autoSelect.isSelected());
+ hextile.setEnabled(!autoSelect.isSelected());
+ tight.setEnabled(!autoSelect.isSelected());
+ raw.setEnabled(!autoSelect.isSelected());
+ fullColour.setEnabled(!autoSelect.isSelected());
+ mediumColour.setEnabled(!autoSelect.isSelected());
+ lowColour.setEnabled(!autoSelect.isSelected());
+ veryLowColour.setEnabled(!autoSelect.isSelected());
+ defaults.setPref("autoSelect",(autoSelect.isSelected()) ? "on" : "off");
+ }
+ if (s instanceof JCheckBox && (JCheckBox)s == customCompressLevel) {
+ compressLevel.setEnabled(customCompressLevel.isSelected());
+ defaults.setPref("customCompressLevel",(customCompressLevel.isSelected()) ? "on" : "off");
+ }
+ if (s instanceof JCheckBox && (JCheckBox)s == noJpeg) {
+ qualityLevel.setEnabled(noJpeg.isSelected());
+ defaults.setPref("noJpeg",(noJpeg.isSelected()) ? "on" : "off");
+ }
+ if (s instanceof JCheckBox && (JCheckBox)s == sendLocalUsername) {
+ defaults.setPref("sendLocalUsername",(sendLocalUsername.isSelected()) ? "on" : "off");
+ }
+ if (s instanceof JCheckBox && (JCheckBox)s == secVeNCrypt) {
+ encNone.setEnabled(secVeNCrypt.isSelected());
+ encTLS.setEnabled(secVeNCrypt.isSelected());
+ encX509.setEnabled(secVeNCrypt.isSelected());
+ ca.setEnabled(secVeNCrypt.isSelected());
+ crl.setEnabled(secVeNCrypt.isSelected());
+ secIdent.setEnabled(secVeNCrypt.isSelected());
+ secNone.setEnabled(secVeNCrypt.isSelected());
+ secVnc.setEnabled(secVeNCrypt.isSelected());
+ secPlain.setEnabled(secVeNCrypt.isSelected());
+ sendLocalUsername.setEnabled(secVeNCrypt.isSelected());
+ }
+ if (s instanceof JCheckBox && (JCheckBox)s == secIdent ||
+ s instanceof JCheckBox && (JCheckBox)s == secPlain) {
+ sendLocalUsername.setEnabled(secIdent.isSelected()||secPlain.isSelected());
+ }
+ }
+
+}
diff --git a/java/src/com/tigervnc/vncviewer/ServerDialog.java b/java/src/com/tigervnc/vncviewer/ServerDialog.java
index 86160f80..e38085a1 100644
--- a/java/src/com/tigervnc/vncviewer/ServerDialog.java
+++ b/java/src/com/tigervnc/vncviewer/ServerDialog.java
@@ -1,178 +1,178 @@
-/* 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.
- */
-
+/* 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.vncviewer;
-
-import java.awt.*;
-import java.awt.image.*;
-import java.awt.event.*;
-import javax.swing.*;
-import javax.swing.border.*;
-import java.net.URL;
-import java.io.File;
-import java.util.*;
+
+import java.awt.*;
+import java.awt.image.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import java.net.URL;
+import java.io.File;
+import java.util.*;
import com.tigervnc.rfb.*;
import com.tigervnc.rfb.Exception;
-
-class ServerDialog extends Dialog implements
- ActionListener,
- ItemListener
-{
-
- public ServerDialog(OptionsDialog options_,
- String defaultServerName, CConn cc_) {
-
- super(true);
- cc = cc_;
- setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
- setResizable(false);
- setSize(new Dimension(340, 135));
- setTitle("VNC Viewer : Connection Details");
-
- options = options_;
- getContentPane().setLayout(new GridBagLayout());
-
- JLabel serverLabel = new JLabel("Server:", JLabel.RIGHT);
- if (options.defaults.getString("server") != null) {
- server = new JComboBox(options.defaults.getString("server").split(","));
- } else {
- server = new JComboBox();
- }
-
- // Hack to set the left inset on editable JComboBox
- if (UIManager.getLookAndFeel().getID() == "Windows") {
- server.setBorder(BorderFactory.createCompoundBorder(server.getBorder(),
- BorderFactory.createEmptyBorder(0,2,0,0)));
- } else {
- ComboBoxEditor editor = server.getEditor();
- JTextField jtf = (JTextField)editor.getEditorComponent();
- jtf.setBorder(new CompoundBorder(jtf.getBorder(), new EmptyBorder(0,2,0,0)));
- }
-
- server.setEditable(true);
- editor = server.getEditor();
- JLabel encryptionLabel = new JLabel("Encryption:");
- encryption = new JComboBox();
- serverLabel.setPreferredSize(encryptionLabel.getPreferredSize());
-
- JPanel topPanel = new JPanel(new GridBagLayout());
-
- addGBComponent(new JLabel(cc.logo),topPanel, 0, 0, 1, 1, 0, 0, 0, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(5,5,5,15));
- addGBComponent(serverLabel,topPanel, 1, 0, 1, 1, 0, 0, 0, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_END, new Insets(10,0,5,5));
- addGBComponent(server,topPanel, 2, 0, 1, 1, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(10,0,5,40));
-
- optionsButton = new JButton("Options...");
- aboutButton = new JButton("About...");
- okButton = new JButton("OK");
- cancelButton = new JButton("Cancel");
- JPanel buttonPanel = new JPanel(new GridBagLayout());
- buttonPanel.setPreferredSize(new Dimension(340, 40));
- addGBComponent(aboutButton,buttonPanel, 0, 3, 1, 1, 0, 0, 0.2, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(0,5,0,5));
- addGBComponent(optionsButton,buttonPanel, 1, 3, 1, 1, 0, 0, 0, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(0,5,0,5));
- addGBComponent(okButton,buttonPanel, 2, 3, 1, 1, 0, 0, 0.8, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(0,5,0,5));
- addGBComponent(cancelButton,buttonPanel, 3, 3, 1, 1, 0, 0, 0.5, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(0,5,0,5));
-
- GridBagConstraints gbc = new GridBagConstraints();
- gbc.anchor = GridBagConstraints.LINE_START;
- gbc.fill = GridBagConstraints.BOTH;
- gbc.gridwidth = GridBagConstraints.REMAINDER;
- gbc.gridheight = 1;
- gbc.insets = new Insets(0,0,0,0);
- gbc.ipadx = 0;
- gbc.ipady = 0;
- gbc.weightx = 1;
- gbc.weighty = 1;
- getContentPane().add(topPanel,gbc);
- getContentPane().add(buttonPanel);
-
- server.addActionListener(this);
- optionsButton.addActionListener(this);
- aboutButton.addActionListener(this);
- okButton.addActionListener(this);
- cancelButton.addActionListener(this);
-
- pack();
- }
-
- public void itemStateChanged(ItemEvent e) {
- Object s = e.getSource();
- if (s instanceof JComboBox && (JComboBox)s == encryption) {
- options.encryption=(encryption.getSelectedIndex()==1) ? false : true;
- }
- }
-
- public void actionPerformed(ActionEvent e) {
- Object s = e.getSource();
- if (s instanceof JButton && (JButton)s == okButton) {
- ok = true;
- endDialog();
- } else if (s instanceof JButton && (JButton)s == cancelButton) {
- ok = false;
- endDialog();
- } else if (s instanceof JButton && (JButton)s == optionsButton) {
- options.showDialog();
- } else if (s instanceof JButton && (JButton)s == aboutButton) {
- cc.showAbout();
- } else if (s instanceof JComboBox && (JComboBox)s == server) {
- if (e.getActionCommand().equals("comboBoxEdited")) {
- server.insertItemAt(editor.getItem(), 0);
- server.setSelectedIndex(0);
- ok = true;
- endDialog();
- }
- }
- }
-
- public void endDialog() {
- if (ok) {
- options.defaults.setPref("encryption",(encryption.getSelectedIndex()==1) ? "off" : "on");
- if (!server.getSelectedItem().toString().equals("")) {
- String t = (options.defaults.getString("server")==null) ? "" : options.defaults.getString("server");
- StringTokenizer st = new StringTokenizer(t, ",");
- StringBuffer sb = new StringBuffer().append((String)server.getSelectedItem());
- while (st.hasMoreTokens()) {
- String s = st.nextToken();
- if (!s.equals((String)server.getSelectedItem()) && !s.equals("")) {
- sb.append(',');
- sb.append(s);
- }
- }
- options.defaults.setPref("server", sb.toString());
- }
- try {
- options.defaults.Save();
- } catch (java.lang.Exception x) { }
- }
- done = true;
- if (modal) {
- synchronized (this) {
- notify();
- }
- }
- this.dispose();
- }
-
- CConn cc;
- JComboBox encryption, server;
- ComboBoxEditor editor;
- JButton aboutButton, optionsButton, okButton, cancelButton;
- OptionsDialog options;
- static LogWriter vlog = new LogWriter("ServerDialog");
-
-}
+
+class ServerDialog extends Dialog implements
+ ActionListener,
+ ItemListener
+{
+
+ public ServerDialog(OptionsDialog options_,
+ String defaultServerName, CConn cc_) {
+
+ super(true);
+ cc = cc_;
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ setResizable(false);
+ setSize(new Dimension(340, 135));
+ setTitle("VNC Viewer : Connection Details");
+
+ options = options_;
+ getContentPane().setLayout(new GridBagLayout());
+
+ JLabel serverLabel = new JLabel("Server:", JLabel.RIGHT);
+ if (options.defaults.getString("server") != null) {
+ server = new JComboBox(options.defaults.getString("server").split(","));
+ } else {
+ server = new JComboBox();
+ }
+
+ // Hack to set the left inset on editable JComboBox
+ if (UIManager.getLookAndFeel().getID() == "Windows") {
+ server.setBorder(BorderFactory.createCompoundBorder(server.getBorder(),
+ BorderFactory.createEmptyBorder(0,2,0,0)));
+ } else {
+ ComboBoxEditor editor = server.getEditor();
+ JTextField jtf = (JTextField)editor.getEditorComponent();
+ jtf.setBorder(new CompoundBorder(jtf.getBorder(), new EmptyBorder(0,2,0,0)));
+ }
+
+ server.setEditable(true);
+ editor = server.getEditor();
+ JLabel encryptionLabel = new JLabel("Encryption:");
+ encryption = new JComboBox();
+ serverLabel.setPreferredSize(encryptionLabel.getPreferredSize());
+
+ JPanel topPanel = new JPanel(new GridBagLayout());
+
+ addGBComponent(new JLabel(cc.logo),topPanel, 0, 0, 1, 1, 0, 0, 0, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(5,5,5,15));
+ addGBComponent(serverLabel,topPanel, 1, 0, 1, 1, 0, 0, 0, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_END, new Insets(10,0,5,5));
+ addGBComponent(server,topPanel, 2, 0, 1, 1, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(10,0,5,40));
+
+ optionsButton = new JButton("Options...");
+ aboutButton = new JButton("About...");
+ okButton = new JButton("OK");
+ cancelButton = new JButton("Cancel");
+ JPanel buttonPanel = new JPanel(new GridBagLayout());
+ buttonPanel.setPreferredSize(new Dimension(340, 40));
+ addGBComponent(aboutButton,buttonPanel, 0, 3, 1, 1, 0, 0, 0.2, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(0,5,0,5));
+ addGBComponent(optionsButton,buttonPanel, 1, 3, 1, 1, 0, 0, 0, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(0,5,0,5));
+ addGBComponent(okButton,buttonPanel, 2, 3, 1, 1, 0, 0, 0.8, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(0,5,0,5));
+ addGBComponent(cancelButton,buttonPanel, 3, 3, 1, 1, 0, 0, 0.5, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(0,5,0,5));
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.anchor = GridBagConstraints.LINE_START;
+ gbc.fill = GridBagConstraints.BOTH;
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.gridheight = 1;
+ gbc.insets = new Insets(0,0,0,0);
+ gbc.ipadx = 0;
+ gbc.ipady = 0;
+ gbc.weightx = 1;
+ gbc.weighty = 1;
+ getContentPane().add(topPanel,gbc);
+ getContentPane().add(buttonPanel);
+
+ server.addActionListener(this);
+ optionsButton.addActionListener(this);
+ aboutButton.addActionListener(this);
+ okButton.addActionListener(this);
+ cancelButton.addActionListener(this);
+
+ pack();
+ }
+
+ public void itemStateChanged(ItemEvent e) {
+ Object s = e.getSource();
+ if (s instanceof JComboBox && (JComboBox)s == encryption) {
+ options.encryption=(encryption.getSelectedIndex()==1) ? false : true;
+ }
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ Object s = e.getSource();
+ if (s instanceof JButton && (JButton)s == okButton) {
+ ok = true;
+ endDialog();
+ } else if (s instanceof JButton && (JButton)s == cancelButton) {
+ ok = false;
+ endDialog();
+ } else if (s instanceof JButton && (JButton)s == optionsButton) {
+ options.showDialog();
+ } else if (s instanceof JButton && (JButton)s == aboutButton) {
+ cc.showAbout();
+ } else if (s instanceof JComboBox && (JComboBox)s == server) {
+ if (e.getActionCommand().equals("comboBoxEdited")) {
+ server.insertItemAt(editor.getItem(), 0);
+ server.setSelectedIndex(0);
+ ok = true;
+ endDialog();
+ }
+ }
+ }
+
+ public void endDialog() {
+ if (ok) {
+ options.defaults.setPref("encryption",(encryption.getSelectedIndex()==1) ? "off" : "on");
+ if (!server.getSelectedItem().toString().equals("")) {
+ String t = (options.defaults.getString("server")==null) ? "" : options.defaults.getString("server");
+ StringTokenizer st = new StringTokenizer(t, ",");
+ StringBuffer sb = new StringBuffer().append((String)server.getSelectedItem());
+ while (st.hasMoreTokens()) {
+ String s = st.nextToken();
+ if (!s.equals((String)server.getSelectedItem()) && !s.equals("")) {
+ sb.append(',');
+ sb.append(s);
+ }
+ }
+ options.defaults.setPref("server", sb.toString());
+ }
+ try {
+ options.defaults.Save();
+ } catch (java.lang.Exception x) { }
+ }
+ done = true;
+ if (modal) {
+ synchronized (this) {
+ notify();
+ }
+ }
+ this.dispose();
+ }
+
+ CConn cc;
+ JComboBox encryption, server;
+ ComboBoxEditor editor;
+ JButton aboutButton, optionsButton, okButton, cancelButton;
+ OptionsDialog options;
+ static LogWriter vlog = new LogWriter("ServerDialog");
+
+}