]> source.dussan.org Git - tigervnc.git/commitdiff
Major overhaul of java viewer.
authorBrian P. Hinz <bphinz@users.sf.net>
Sun, 7 Aug 2016 12:44:46 +0000 (08:44 -0400)
committerBrian P. Hinz <bphinz@users.sf.net>
Sun, 7 Aug 2016 12:44:46 +0000 (08:44 -0400)
This is the first of several large commits intended to resolve a
number of problems and add new capabilities to the java viewer.
Among the most significant changes are a complete re-design of
the options dialog, which has been converted to a callback style
interface.  The look & feel of all dialogs are now similar to
the style of the native viewer now.  Also, the process by which
new viewers are spawned has changed and each viewer is a completely
separate process, allowing for runtime arguments to be handled
statically.

java/com/tigervnc/vncviewer/ExtProcess.java [new file with mode: 0644]
java/com/tigervnc/vncviewer/Parameters.java [new file with mode: 0644]

diff --git a/java/com/tigervnc/vncviewer/ExtProcess.java b/java/com/tigervnc/vncviewer/ExtProcess.java
new file mode 100644 (file)
index 0000000..730a742
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ *  Copyright (C) 2016 Brian P. Hinz. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ *  USA.
+ */
+
+package com.tigervnc.vncviewer;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.*;
+
+import com.tigervnc.rdr.*;
+import com.tigervnc.rfb.*;
+import com.tigervnc.rfb.Exception;
+import com.tigervnc.network.*;
+
+import static com.tigervnc.vncviewer.Parameters.*;
+
+public class ExtProcess implements Runnable {
+
+  private String cmd = null;
+  private LogWriter vlog = null;
+  private boolean shutdown = false;
+  private Process pid = null;
+
+  private static class MyProcessLogger extends Thread {
+    private final BufferedReader err;
+    private final LogWriter vlog;
+
+    public MyProcessLogger(Process p, LogWriter vlog) {
+      InputStreamReader reader = 
+        new InputStreamReader(p.getErrorStream());
+      err = new BufferedReader(reader);
+      this.vlog = vlog;
+    }
+
+    @Override
+    public void run() {
+      try {
+        while (true) {
+          String msg = err.readLine();
+          if (msg != null)
+            vlog.info(msg);
+        }
+      } catch(java.io.IOException e) {
+        vlog.info(e.getMessage());
+      } finally {
+        try {
+          if (err != null)
+            err.close();
+        } catch (java.io.IOException e ) { }
+      }
+    }
+  }
+
+  private static class MyShutdownHook extends Thread {
+
+    private Process proc = null;
+
+    public MyShutdownHook(Process p) {
+      proc = p;
+    }
+
+    @Override
+    public void run() {
+      try {
+        proc.exitValue();
+      } catch (IllegalThreadStateException e) {
+        try {
+          // wait for CConn to shutdown the socket
+          Thread.sleep(500);
+        } catch(InterruptedException ie) { }
+        proc.destroy();
+      }
+    }
+  }
+
+  public ExtProcess(String command, LogWriter vlog, boolean shutdown) {
+    cmd = command;  
+    this.vlog = vlog;
+    this.shutdown = shutdown;
+  }
+
+  public ExtProcess(String command, LogWriter vlog) {
+    this(command, vlog, false);
+  }
+
+  public ExtProcess(String command) {
+    this(command, null, false);
+  }
+
+  public void run() {
+    try {
+      Runtime runtime = Runtime.getRuntime();
+      pid = runtime.exec(cmd);
+      if (shutdown)
+        runtime.addShutdownHook(new MyShutdownHook(pid));
+      if (vlog != null)
+        new MyProcessLogger(pid, vlog).start();
+      pid.waitFor();
+    } catch(InterruptedException e) {
+      vlog.info(e.getMessage());
+    } catch(java.io.IOException e) {
+      vlog.info(e.getMessage());
+    }
+  }
+
+  //static LogWriter vlog = new LogWriter("ExtProcess");
+}
diff --git a/java/com/tigervnc/vncviewer/Parameters.java b/java/com/tigervnc/vncviewer/Parameters.java
new file mode 100644 (file)
index 0000000..e6b91c3
--- /dev/null
@@ -0,0 +1,648 @@
+/* Copyright (C) 2016 Brian P. Hinz
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+package com.tigervnc.vncviewer;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.io.PrintWriter;
+import java.util.StringTokenizer;
+
+import com.tigervnc.rfb.*;
+import com.tigervnc.rfb.Exception;
+
+public class Parameters {
+
+
+  public static BoolParameter noLionFS
+  = new BoolParameter("NoLionFS",
+  "On Mac systems, setting this parameter will force the use of the old "+
+  "(pre-Lion) full-screen mode, even if the viewer is running on OS X 10.7 "+
+  "Lion or later.",
+  false);
+
+  public static BoolParameter embed
+  = new BoolParameter("Embed",
+  "If the viewer is being run as an applet, display its output to " +
+  "an embedded frame in the browser window rather than to a dedicated " +
+  "window. Embed=1 implies FullScreen=0 and Scale=100.",
+  false);
+
+  public static BoolParameter useLocalCursor
+  = new BoolParameter("UseLocalCursor",
+                      "Render the mouse cursor locally",
+                      true);
+
+  public static BoolParameter sendLocalUsername
+  = new BoolParameter("SendLocalUsername",
+                      "Send the local username for SecurityTypes "+
+                      "such as Plain rather than prompting",
+                      true);
+
+  public static StringParameter passwordFile
+  = new StringParameter("PasswordFile",
+                        "Password file for VNC authentication",
+                        "");
+
+  public static AliasParameter passwd
+  = new AliasParameter("passwd",
+                       "Alias for PasswordFile",
+                       passwordFile);
+
+  public static BoolParameter autoSelect
+  = new BoolParameter("AutoSelect",
+                      "Auto select pixel format and encoding",
+                      true);
+
+  public static BoolParameter fullColor
+  = new BoolParameter("FullColor",
+                      "Use full color - otherwise 6-bit colour is "+
+                      "used until AutoSelect decides the link is "+
+                      "fast enough",
+                      true);
+
+  public static AliasParameter fullColorAlias
+  = new AliasParameter("FullColour",
+                       "Alias for FullColor",
+                       Parameters.fullColor);
+
+  public static IntParameter lowColorLevel
+  = new IntParameter("LowColorLevel",
+                     "Color level to use on slow connections. "+
+                     "0 = Very Low (8 colors), 1 = Low (64 colors), "+
+                     "2 = Medium (256 colors)",
+                     2);
+
+  public static AliasParameter lowColorLevelAlias
+  = new AliasParameter("LowColourLevel",
+                       "Alias for LowColorLevel",
+                       lowColorLevel);
+
+  public static StringParameter preferredEncoding
+  = new StringParameter("PreferredEncoding",
+                        "Preferred encoding to use (Tight, ZRLE, "+
+                        "hextile or raw) - implies AutoSelect=0",
+                        "Tight");
+
+  public static BoolParameter viewOnly
+  = new BoolParameter("ViewOnly",
+                      "Don't send any mouse or keyboard events to "+
+                      "the server",
+                      false);
+
+  public static BoolParameter shared
+  = new BoolParameter("Shared",
+                      "Don't disconnect other viewers upon "+
+                      "connection - share the desktop instead",
+                      false);
+
+  public static BoolParameter fullScreen
+  = new BoolParameter("FullScreen",
+                      "Full Screen Mode",
+                      false);
+
+  public static BoolParameter fullScreenAllMonitors
+  = new BoolParameter("FullScreenAllMonitors",
+                      "Enable full screen over all monitors",
+                      true);
+
+  public static BoolParameter acceptClipboard
+  = new BoolParameter("AcceptClipboard",
+                      "Accept clipboard changes from the server",
+                      true);
+
+  public static BoolParameter sendClipboard
+  = new BoolParameter("SendClipboard",
+                      "Send clipboard changes to the server",
+                      true);
+
+  public static IntParameter maxCutText
+  = new IntParameter("MaxCutText",
+                     "Maximum permitted length of an outgoing clipboard update",
+                     262144);
+
+  public static StringParameter menuKey
+  = new StringParameter("MenuKey",
+                        "The key which brings up the popup menu",
+                        "F8");
+
+  public static StringParameter desktopSize
+  = new StringParameter("DesktopSize",
+                        "Reconfigure desktop size on the server on "+
+                        "connect (if possible)", "");
+
+  public static BoolParameter listenMode
+  = new BoolParameter("listen",
+                      "Listen for connections from VNC servers",
+                      false);
+
+  public static StringParameter scalingFactor
+  = new StringParameter("ScalingFactor",
+                        "Reduce or enlarge the remote desktop image. "+
+                        "The value is interpreted as a scaling factor "+
+                        "in percent. If the parameter is set to "+
+                        "\"Auto\", then automatic scaling is "+
+                        "performed. Auto-scaling tries to choose a "+
+                        "scaling factor in such a way that the whole "+
+                        "remote desktop will fit on the local screen. "+
+                        "If the parameter is set to \"FixedRatio\", "+
+                        "then automatic scaling is performed, but the "+
+                        "original aspect ratio is preserved.",
+                        "100");
+
+  public static BoolParameter alwaysShowServerDialog
+  = new BoolParameter("AlwaysShowServerDialog",
+                      "Always show the server dialog even if a server "+
+                      "has been specified in an applet parameter or on "+
+                      "the command line",
+                      false);
+
+  public static StringParameter vncServerName
+  = new StringParameter("Server",
+                        "The VNC server <host>[:<dpyNum>] or "+
+                        "<host>::<port>",
+                        "");
+
+  /*
+  public static IntParameter vncServerPort
+  = new IntParameter("Port",
+                     "The VNC server's port number, assuming it is on "+
+                     "the host from which the applet was downloaded",
+                     0);
+  */
+
+  public static BoolParameter acceptBell
+  = new BoolParameter("AcceptBell",
+                      "Produce a system beep when requested to by the server.",
+                      true);
+
+  public static StringParameter via
+  = new StringParameter("Via",
+    "Automatically create an encrypted TCP tunnel to "+
+    "the gateway machine, then connect to the VNC host "+
+    "through that tunnel. By default, this option invokes "+
+    "SSH local port forwarding using the embedded JSch "+
+    "client, however an external SSH client may be specified "+
+    "using the \"-extSSH\" parameter. Note that when using "+
+    "the -via option, the VNC host machine name should be "+
+    "specified from the point of view of the gateway machine, "+
+    "e.g. \"localhost\" denotes the gateway, "+
+    "not the machine on which the viewer was launched. "+
+    "See the System Properties section below for "+
+    "information on configuring the -Via option.", "");
+
+  public static BoolParameter tunnel
+  = new BoolParameter("Tunnel",
+    "The -Tunnel command is basically a shorthand for the "+
+    "-via command when the VNC server and SSH gateway are "+
+    "one and the same. -Tunnel creates an SSH connection "+
+    "to the server and forwards the VNC through the tunnel "+
+    "without the need to specify anything else.", false);
+
+  public static BoolParameter extSSH
+  = new BoolParameter("extSSH",
+    "By default, SSH tunneling uses the embedded JSch client "+
+    "for tunnel creation. This option causes the client to "+
+    "invoke an external SSH client application for all tunneling "+
+    "operations. By default, \"/usr/bin/ssh\" is used, however "+
+    "the path to the external application may be specified using "+
+    "the -SSHClient option.", false);
+
+  public static StringParameter extSSHClient
+  = new StringParameter("extSSHClient",
+    "Specifies the path to an external SSH client application "+
+    "that is to be used for tunneling operations when the -extSSH "+
+    "option is in effect.", "/usr/bin/ssh");
+
+  public static StringParameter extSSHArgs
+  = new StringParameter("extSSHArgs",
+    "Specifies the arguments string or command template to be used "+
+    "by the external SSH client application when the -extSSH option "+
+    "is in effect. The string will be processed according to the same "+
+    "pattern substitution rules as the VNC_TUNNEL_CMD and VNC_VIA_CMD "+
+    "system properties, and can be used to override those in a more "+
+    "command-line friendly way. If not specified, then the appropriate "+
+    "VNC_TUNNEL_CMD or VNC_VIA_CMD command template will be used.", "");
+
+  public static StringParameter sshConfig
+  = new StringParameter("SSHConfig",
+    "Specifies the path to an OpenSSH configuration file that to "+
+    "be parsed by the embedded JSch SSH client during tunneling "+
+    "operations.", FileUtils.getHomeDir()+".ssh/config");
+
+  public static StringParameter sshKey
+  = new StringParameter("SSHKey",
+    "When using the Via or Tunnel options with the embedded SSH client, "+
+    "this parameter specifies the text of the SSH private key to use when "+
+    "authenticating with the SSH server. You can use \\n within the string "+
+    "to specify a new line.", "");
+
+  public static StringParameter sshKeyFile
+  = new StringParameter("SSHKeyFile",
+    "When using the Via or Tunnel options with the embedded SSH client, "+
+    "this parameter specifies a file that contains an SSH private key "+
+    "(or keys) to use when authenticating with the SSH server. If not "+
+    "specified, ~/.ssh/id_dsa or ~/.ssh/id_rsa will be used (if they exist). "+
+    "Otherwise, the client will fallback to prompting for an SSH password.",
+    "");
+
+  public static StringParameter sshKeyPass
+  = new StringParameter("SSHKeyPass",
+    "When using the Via or Tunnel options with the embedded SSH client, "+
+    "this parameter specifies the passphrase for the SSH key.", "");
+
+  public static BoolParameter customCompressLevel
+  = new BoolParameter("CustomCompressLevel",
+                      "Use custom compression level. "+
+                      "Default if CompressLevel is specified.",
+                      false);
+
+  public static IntParameter compressLevel
+  = new IntParameter("CompressLevel",
+                     "Use specified compression level "+
+                     "0 = Low, 6 = High",
+                     1);
+
+  public static BoolParameter noJpeg
+  = new BoolParameter("NoJPEG",
+                      "Disable lossy JPEG compression in Tight encoding.",
+                      false);
+
+  public static IntParameter qualityLevel
+  = new IntParameter("QualityLevel",
+                     "JPEG quality level. "+
+                     "0 = Low, 9 = High",
+                     8);
+
+  private static final String IDENTIFIER_STRING = "TigerVNC Configuration file Version 1.0";
+
+  static VoidParameter[] parameterArray = {
+    CSecurityTLS.X509CA,
+    CSecurityTLS.X509CRL,
+    SecurityClient.secTypes,
+    autoSelect,
+    fullColor,
+    lowColorLevel,
+    preferredEncoding,
+    customCompressLevel,
+    compressLevel,
+    noJpeg,
+    qualityLevel,
+    fullScreen,
+    fullScreenAllMonitors,
+    desktopSize,
+    viewOnly,
+    shared,
+    acceptClipboard,
+    sendClipboard,
+    menuKey,
+    noLionFS,
+    useLocalCursor,
+    sendLocalUsername,
+    maxCutText,
+    scalingFactor,
+    acceptBell,
+    via,
+    tunnel,
+    extSSH,
+    extSSHClient,
+    extSSHArgs,
+    sshConfig,
+    sshKeyFile,
+  };
+
+
+  static LogWriter vlog = new LogWriter("Parameters");
+
+       public static void saveViewerParameters(String filename, String servername) {
+       
+         // Write to the registry or a predefined file if no filename was specified.
+    String filepath;
+    if (filename == null || filename.isEmpty()) {
+      saveToReg(servername);
+      return;
+      /*
+      String homeDir = FileUtils.getVncHomeDir();
+      if (homeDir == null)
+        throw new Exception("Failed to read configuration file, "+
+                            "can't obtain home directory path.");
+      filepath = homeDir.concat("default.tigervnc");
+      */
+    } else {
+      filepath = filename;
+    }
+       
+         /* Write parameters to file */
+    File f = new File(filepath);
+    if (f.exists() && !f.canWrite())
+           throw new Exception(String.format("Failed to write configuration file,"+
+                                        "can't open %s", filepath)); 
+         
+    PrintWriter pw = null;
+    try {
+      pw = new PrintWriter(f, "UTF-8");
+    } catch (java.lang.Exception e)    {
+      throw new Exception(e.getMessage());
+    }
+
+    pw.println(IDENTIFIER_STRING);
+    pw.println("");
+       
+         if (servername != null && !servername.isEmpty()) {
+           pw.println(String.format("ServerName=%s\n", servername));
+      updateConnHistory(servername);
+    }
+         
+    for (int i = 0; i < parameterArray.length; i++) {
+      if (parameterArray[i] instanceof StringParameter) {
+        //if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName()))
+          pw.println(String.format("%s=%s",parameterArray[i].getName(),
+                                   parameterArray[i].getValueStr()));
+      } else if (parameterArray[i] instanceof IntParameter) {
+        //if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName()))
+          pw.println(String.format("%s=%s",parameterArray[i].getName(),
+                                   parameterArray[i].getValueStr()));
+      } else if (parameterArray[i] instanceof BoolParameter) {
+        //if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName()))
+          pw.println(String.format("%s=%s",parameterArray[i].getName(),
+                                   parameterArray[i].getValueStr()));
+      } else {
+        vlog.error(String.format("Unknown parameter type for parameter %s",
+                   parameterArray[i].getName()));
+      }
+    }
+
+    pw.flush();
+    pw.close();
+       }
+
+  public static String loadViewerParameters(String filename) throws Exception {
+    String servername = "";
+
+    String filepath;
+    if (filename == null) {
+
+      return loadFromReg(); 
+
+      /*
+      String homeDir = FileUtils.getVncHomeDir();
+      if (homeDir == null)
+        throw new Exception("Failed to read configuration file, "+
+                            "can't obtain home directory path.");
+      filepath = homeDir.concat("default.tigervnc");
+      */
+    } else {
+      filepath = filename;
+    }
+
+    /* Read parameters from file */
+    File f = new File(filepath);
+    if (!f.exists() || !f.canRead()) {
+      if (filename == null || filename.isEmpty())
+        return null;
+      throw new Exception(String.format("Failed to read configuration file, can't open %s",
+                          filepath)); 
+    }
+
+    String line = "";
+    LineNumberReader reader;
+    try {
+      reader = new LineNumberReader(new FileReader(f));
+    } catch (FileNotFoundException e) {
+      throw new Exception(e.getMessage());
+    }
+
+    int lineNr = 0;
+    while (line != null) {
+      
+      // Read the next line
+      try {
+        line = reader.readLine();
+        lineNr = reader.getLineNumber();
+        if (line == null)
+          break;
+      } catch (IOException e) {
+        throw new Exception(String.format("Failed to read line %d in file %s: %s",
+          lineNr, filepath, e.getMessage()));
+      }
+
+      // Make sure that the first line of the file has the file identifier string
+      if(lineNr == 1) {
+        if(line.equals(IDENTIFIER_STRING))
+          continue;
+        else
+          throw new Exception(String.format(new String("Configuration file %s is in an invalid format"), filename));
+      }
+
+      // Skip empty lines and comments
+      if (line.trim().isEmpty() || line.trim().startsWith("#"))
+        continue;
+
+      // Find the parameter value
+      int idx = line.indexOf("=");
+      if (idx == -1) {
+        vlog.error(String.format("Failed to read line %d in file %s: %s",
+                   lineNr, filename, "Invalid format"));
+        continue;
+      }
+      String value = line.substring(idx+1).trim();
+      boolean invalidParameterName = true; // Will be set to false below if 
+                                           // the line contains a valid name.
+
+      if (line.substring(0,idx).trim().equalsIgnoreCase("ServerName")) {
+        if (value.length() > 256) {
+          vlog.error(String.format("Failed to read line %d in file %s: %s",
+                     lineNr, filepath, "Invalid format or too large value"));
+          continue;
+        }
+        servername = value;
+        invalidParameterName = false;
+      } else {
+        for (int i = 0; i < parameterArray.length; i++) {
+          if (parameterArray[i] instanceof StringParameter) {
+            if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName())) {
+              if (value.length() > 256) {
+                vlog.error(String.format("Failed to read line %d in file %s: %s",
+                           lineNr, filepath, "Invalid format or too large value"));
+                continue;
+              }
+              ((StringParameter)parameterArray[i]).setParam(value);
+              invalidParameterName = false;
+            }
+          } else if (parameterArray[i] instanceof IntParameter) {
+            if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName())) {
+              ((IntParameter)parameterArray[i]).setParam(value);
+              invalidParameterName = false;
+            }
+          } else if (parameterArray[i] instanceof BoolParameter) {
+            if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName())) {
+              ((BoolParameter)parameterArray[i]).setParam(value);
+              invalidParameterName = false;
+            }
+          } else {
+            vlog.error(String.format("Unknown parameter type for parameter %s",
+                       parameterArray[i].getName()));
+
+          }
+        }
+      }
+
+      if (invalidParameterName)
+        vlog.info(String.format("Unknown parameter %s on line %d in file %s",
+                  line, lineNr, filepath));
+    }
+    try {
+      reader.close();
+    } catch (IOException e) {
+      vlog.info(e.getMessage());
+    } finally {
+      try {
+        if (reader != null)
+          reader.close();
+        } catch (IOException e) { }
+    }
+
+    return servername;
+  }
+
+  public static void saveToReg(String servername) {
+    String hKey = "global";
+
+    if (servername != null && !servername.isEmpty()) {
+      UserPreferences.set(hKey, "ServerName", servername);
+      updateConnHistory(servername);
+    }
+
+    for (int i = 0; i < parameterArray.length; i++) {
+      if (parameterArray[i] instanceof StringParameter) {
+        UserPreferences.set(hKey, parameterArray[i].getName(),
+                                  parameterArray[i].getValueStr());
+      } else if (parameterArray[i] instanceof IntParameter) {
+        UserPreferences.set(hKey, parameterArray[i].getName(),
+                            ((IntParameter)parameterArray[i]).getValue());
+      } else if (parameterArray[i] instanceof BoolParameter) {
+        UserPreferences.set(hKey, parameterArray[i].getName(),
+                            ((BoolParameter)parameterArray[i]).getValue());
+      } else {
+        vlog.error(String.format("Unknown parameter type for parameter %s",
+                   parameterArray[i].getName()));
+      }
+    }
+
+    UserPreferences.save(hKey);
+  }
+
+  public static String loadFromReg() {
+  
+    String hKey = "global";
+  
+    String servername = UserPreferences.get(hKey, "ServerName");
+    if (servername == null)
+      servername = "";
+    
+    for (int i = 0; i < parameterArray.length; i++) {
+      if (parameterArray[i] instanceof StringParameter) {
+        if (UserPreferences.get(hKey, parameterArray[i].getName()) != null) {
+          String stringValue =
+            UserPreferences.get(hKey, parameterArray[i].getName());
+          ((StringParameter)parameterArray[i]).setParam(stringValue);
+        }
+      } else if (parameterArray[i] instanceof IntParameter) {
+        if (UserPreferences.get(hKey, parameterArray[i].getName()) != null) {
+          int intValue =
+            UserPreferences.getInt(hKey, parameterArray[i].getName());
+          ((IntParameter)parameterArray[i]).setParam(intValue);
+        }
+      } else if (parameterArray[i] instanceof BoolParameter) {
+        if (UserPreferences.get(hKey, parameterArray[i].getName()) != null) {
+          boolean booleanValue =
+            UserPreferences.getBool(hKey, parameterArray[i].getName());
+          ((BoolParameter)parameterArray[i]).setParam(booleanValue);
+        }
+      } else {
+        vlog.error(String.format("Unknown parameter type for parameter %s",
+                   parameterArray[i].getName()));
+      }
+    }
+  
+    return servername;
+  }
+
+  public static String loadAppletParameters(VncViewer applet) {
+    String servername = applet.getParameter("Server");
+    String serverport = applet.getParameter("Port");
+    String embedParam = applet.getParameter("Embed");
+
+    if (servername == null)
+      servername = applet.getCodeBase().getHost();
+
+    if (serverport != null)
+      servername = servername.concat("::"+serverport);
+    else
+      servername = servername.concat("::5900");
+
+    if (embedParam != null)
+      embed.setParam(embedParam);
+
+    for (int i = 0; i < parameterArray.length; i++) {
+      String value = applet.getParameter(parameterArray[i].getName());
+      if (value == null)
+        continue;
+      if (parameterArray[i] instanceof StringParameter) {
+        if (value.length() > 256) {
+          vlog.error(String.format("Failed to read applet parameter %s: %s",
+                     parameterArray[i].getName(),
+                     "Invalid format or too large value"));
+          continue;
+        }
+        ((StringParameter)parameterArray[i]).setParam(value);
+      } else if (parameterArray[i] instanceof IntParameter) {
+        ((IntParameter)parameterArray[i]).setParam(value);
+      } else if (parameterArray[i] instanceof BoolParameter) {
+        ((BoolParameter)parameterArray[i]).setParam(value);
+      } else {
+        vlog.error(String.format("Unknown parameter type for parameter %s",
+                   parameterArray[i].getName()));
+
+      }
+    }
+
+    return servername;
+  }
+
+  private static void updateConnHistory(String serverName) {
+    String hKey = "ServerDialog";
+    if (serverName != null && !serverName.isEmpty()) {
+      String valueStr = UserPreferences.get(hKey, "history");
+      String t = (valueStr == null) ? "" : valueStr;
+      StringTokenizer st = new StringTokenizer(t, ",");
+      StringBuffer sb = new StringBuffer().append(serverName);
+      while (st.hasMoreTokens()) {
+        String str = st.nextToken();
+        if (!str.equals(serverName) && !str.equals(""))
+          sb.append(',').append(str);
+      }
+      UserPreferences.set(hKey, "history", sb.toString());
+      UserPreferences.save(hKey);
+    }
+  }
+
+}