param.setImmutable();
}
+ public void setHasBeenSet() {
+ param.setHasBeenSet();
+ }
+
+ public boolean hasBeenSet() {
+ return param.hasBeenSet();
+ }
+
protected VoidParameter param;
}
int secType = Security.secTypeInvalid;
List<Integer> secTypes = new ArrayList<Integer>();
- secTypes = Security.GetEnabledSecTypes();
+ secTypes = security.GetEnabledSecTypes();
if (cp.isVersion(3,3)) {
// Ownership of the IdentityVerifier is retained by the CConnection instance.
//public IdentityVerifier getIdentityVerifier() { return 0; }
+ public void framebufferUpdateStart()
+ {
+ super.framebufferUpdateStart();
+ }
+
+ public void framebufferUpdateEnd()
+ {
+ super.framebufferUpdateEnd();
+ }
+
// authSuccess() is called when authentication has succeeded.
public void authSuccess() {}
public class CSecurityTLS extends CSecurity {
- public static StringParameter x509ca
- = new StringParameter("x509ca",
+ public static StringParameter X509CA
+ = new StringParameter("X509CA",
"X509 CA certificate", "", Configuration.ConfigurationObject.ConfViewer);
- public static StringParameter x509crl
- = new StringParameter("x509crl",
+ public static StringParameter X509CRL
+ = new StringParameter("X509CRL",
"X509 CRL file", "", Configuration.ConfigurationObject.ConfViewer);
private void initGlobal()
manager = null;
setDefaults();
- cafile = x509ca.getData();
- crlfile = x509crl.getData();
+ cafile = X509CA.getData();
+ crlfile = X509CRL.getData();
}
public static String getDefaultCA() {
public static void setDefaults()
{
if (new File(getDefaultCA()).exists())
- x509ca.setDefaultStr(getDefaultCA());
+ X509CA.setDefaultStr(getDefaultCA());
if (new File(getDefaultCRL()).exists())
- x509crl.setDefaultStr(getDefaultCRL());
+ X509CRL.setDefaultStr(getDefaultCRL());
}
// FIXME:
Iterator<Integer> j;
List<Integer> secTypes = new ArrayList<Integer>();
- secTypes = Security.GetEnabledExtSecTypes();
+ secTypes = security.GetEnabledExtSecTypes();
/* Honor server's security type order */
for (i = 0; i < nAvailableTypes; i++) {
import java.io.FileInputStream;
import java.io.PrintWriter;
+import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
+import com.tigervnc.vncviewer.VncViewer;
+
public class Configuration {
static LogWriter vlog = new LogWriter("Configuration");
+ private static final String IDENTIFIER_STRING = "TigerVNC Configuration file Version 1.0";
+
public enum ConfigurationObject { ConfGlobal, ConfServer, ConfViewer };
// -=- The Global/server/viewer Configuration objects
list(79, 10);
}
- public void readAppletParams(java.applet.Applet applet) {
- VoidParameter current = head;
- while (current != null) {
- String str = applet.getParameter(current.getName());
- if (str != null)
- current.setParam(str);
- current = current._next;
- }
- }
-
- public static void load(String filename) {
- if (filename == null)
- return;
-
- /* Read parameters from file */
- Properties props = new Properties();
- try {
- props.load(new FileInputStream(filename));
- } catch(java.security.AccessControlException e) {
- vlog.error("Cannot access system properties:"+e.getMessage());
- return;
- } catch (java.lang.Exception e) {
- vlog.error("Error opening config file:"+e.getMessage());
- return;
- }
-
- for (Iterator<String> i = props.stringPropertyNames().iterator(); i.hasNext();) {
- String name = (String)i.next();
- if (name.startsWith("[")) {
- // skip the section delimiters
- continue;
- } else if (name.equals("host")) {
- setParam("Server", props.getProperty(name));
- } else if (name.equals("disableclipboard")) {
- setParam("RecvClipboard", props.getProperty(name));
- setParam("SendClipboard", props.getProperty(name));
- } else if (name.equals("localcursor")) {
- setParam("UseLocalCursor", props.getProperty(name));
- } else {
- if (!setParam(name, props.getProperty(name)))
- vlog.debug("Cannot set parameter: "+name);
- }
- }
- }
-
- public static void save(String filename) {
- PrintWriter pw = null;
- try {
- pw = new PrintWriter(filename, "UTF-8");
- } catch (java.lang.Exception e) {
- vlog.error("Error opening config file:"+e.getMessage());
- return;
- }
-
- pw.println("# TigerVNC viewer configuration");
- DateFormat dateFormat = new SimpleDateFormat("E MMM d k:m:s z yyyy");
- Date date = new Date();
- pw.println("# "+dateFormat.format(date));
- VoidParameter current = Configuration.global().head;
- while (current != null) {
- String name = current.getName();
- String value = current.getValueStr();
- if (!name.equals("Server") && !name.equals("Port") &&
- value != null && value != current.getDefaultStr())
- pw.println(name+"="+current.getValueStr());
- current = current._next;
- }
- pw.flush();
- pw.close();
- }
-
// Name for this Configuration
private String name;
public static final int secResultFailed = 1;
public static final int secResultTooMany = 2; // deprecated
+ public Security() { }
+
public Security(StringParameter secTypes)
{
String secTypesStr;
secTypesStr = null;
}
- public static List<Integer> enabledSecTypes = new ArrayList<Integer>();
+ private List<Integer> enabledSecTypes = new ArrayList<Integer>();
- public static final List<Integer> GetEnabledSecTypes()
+ public final List<Integer> GetEnabledSecTypes()
{
List<Integer> result = new ArrayList<Integer>();
return (result);
}
- public static final List<Integer> GetEnabledExtSecTypes()
+ public final List<Integer> GetEnabledExtSecTypes()
{
List<Integer> result = new ArrayList<Integer>();
return (result);
}
- public static final void EnableSecType(int secType)
+ public final void EnableSecType(int secType)
{
for (Iterator<Integer> i = enabledSecTypes.iterator(); i.hasNext(); )
return false;
}
- public static void DisableSecType(int secType) { enabledSecTypes.remove((Object)secType); }
+ public String ToString()
+ {
+ Iterator<Integer> i;
+ String out = new String("");
+ boolean firstpass = true;
+ String name;
+
+ for (i = enabledSecTypes.iterator(); i.hasNext(); ) {
+ name = secTypeName((Integer)i.next());
+ if (name.startsWith("[")) /* Unknown security type */
+ continue;
+
+ if (!firstpass)
+ out = out.concat(",");
+ else
+ firstpass = false;
+ out = out.concat(name);
+ }
+
+ return out;
+ }
+
+ public void DisableSecType(int secType) { enabledSecTypes.remove((Object)secType); }
public static int secTypeNum(String name) {
if (name.equalsIgnoreCase("None")) return secTypeNone;
return (result);
}
- public final void SetSecTypes(List<Integer> secTypes) { enabledSecTypes = secTypes; }
+ public final void SetSecTypes(List<Integer> secTypes) {
+ enabledSecTypes = secTypes;
+ }
static LogWriter vlog = new LogWriter("Security");
}
//UserPasswdGetter upg = null;
String msg = null;
- static StringParameter secTypes
+ public static StringParameter secTypes
= new StringParameter("SecurityTypes",
- "Specify which security scheme to use (None, VncAuth)",
- "Ident,TLSIdent,X509Ident,X509Plain,TLSPlain,X509Vnc,TLSVnc,X509None,TLSNone,VncAuth,None", Configuration.ConfigurationObject.ConfViewer);
+ "Specify which security scheme to use (None, VncAuth, Plain, Ident, TLSNone, TLSVnc, TLSPlain, TLSIdent, X509None, X509Vnc, X509Plain, X509Ident)",
+ "X509Ident,X509Plain,TLSIdent,TLSPlain,X509Vnc,TLSVnc,X509None,TLSNone,Ident,VncAuth,None", Configuration.ConfigurationObject.ConfViewer);
}
public class BIPixelBuffer extends PlatformPixelBuffer implements ImageObserver
{
- public BIPixelBuffer(int w, int h, CConn cc_, DesktopWindow desktop_) {
- super(w, h, cc_, desktop_);
+ public BIPixelBuffer(PixelFormat pf, int w, int h, DesktopWindow desktop_) {
+ super(pf, w, h, desktop_);
clip = new Rectangle();
}
package com.tigervnc.vncviewer;
import java.awt.*;
+import java.awt.datatransfer.StringSelection;
import java.awt.event.*;
+import java.awt.Toolkit;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.*;
+import java.util.prefs.*;
import com.tigervnc.rdr.*;
import com.tigervnc.rfb.*;
import com.tigervnc.network.Socket;
import com.tigervnc.network.TcpSocket;
+import static com.tigervnc.vncviewer.Parameters.*;
+
public class CConn extends CConnection implements
- UserPasswdGetter, UserMsgBox, OptionsDialogCallback,
+ UserPasswdGetter, UserMsgBox,
FdInStreamBlockCallback, ActionListener {
- public final PixelFormat getPreferredPF() { return fullColourPF; }
- static final PixelFormat verylowColourPF =
+ public final PixelFormat getPreferredPF() { return fullColorPF; }
+ static final PixelFormat verylowColorPF =
new PixelFormat(8, 3, false, true, 1, 1, 1, 2, 1, 0);
- static final PixelFormat lowColourPF =
+ static final PixelFormat lowColorPF =
new PixelFormat(8, 6, false, true, 3, 3, 3, 4, 2, 0);
- static final PixelFormat mediumColourPF =
+ static final PixelFormat mediumColorPF =
new PixelFormat(8, 8, false, false, 7, 7, 3, 0, 3, 6);
static final int KEY_LOC_SHIFT_R = 0;
static final int KEY_LOC_SHIFT_L = 16;
////////////////////////////////////////////////////////////////////
// The following methods are all called from the RFB thread
- public CConn(VncViewer viewer_, Socket sock_,
- String vncServerName)
+ public CConn(String vncServerName, Socket socket)
{
- sock = sock_; viewer = viewer_;
pendingPFChange = false;
currentEncoding = Encodings.encodingTight; lastServerEncoding = -1;
- fullColour = viewer.fullColour.getValue();
- lowColourLevel = viewer.lowColourLevel.getValue();
- autoSelect = viewer.autoSelect.getValue();
formatChange = false; encodingChange = false;
- fullScreen = viewer.fullScreen.getValue();
- menuKeyCode = MenuKey.getMenuKeyCode();
- options = new OptionsDialog(this);
- options.initDialog();
- clipboardDialog = new ClipboardDialog(this);
firstUpdate = true; pendingUpdate = false; continuousUpdates = false;
forceNonincremental = true; supportsSyncFence = false;
+
+ setShared(shared.getValue());
+ sock = socket;
downKeySym = new HashMap<Integer, Integer>();
- setShared(viewer.shared.getValue());
upg = this;
msg = this;
- String encStr = viewer.preferredEncoding.getValue();
- int encNum = Encodings.encodingNum(encStr);
- if (encNum != -1) {
+ int encNum = Encodings.encodingNum(preferredEncoding.getValue());
+ if (encNum != -1)
currentEncoding = encNum;
- }
+
+ cp.supportsLocalCursor = useLocalCursor.getValue();
+
cp.supportsDesktopResize = true;
cp.supportsExtendedDesktopSize = true;
- cp.supportsSetDesktopSize = false;
- cp.supportsClientRedirect = 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.getPeerEndpoint();
- vlog.info("Accepted connection from " + name);
- } else {
- if (vncServerName != null &&
- !viewer.alwaysShowServerDialog.getValue()) {
- setServerName(Hostname.getHost(vncServerName));
- setServerPort(Hostname.getPort(vncServerName));
- } else {
- ServerDialog dlg = new ServerDialog(options, vncServerName, this);
- boolean ret = dlg.showDialog();
- if (!ret) {
- close();
- return;
- }
- setServerName(viewer.vncServerName.getValueStr());
- setServerPort(viewer.vncServerPort.getValue());
- }
+ cp.supportsSetDesktopSize = false;
+ cp.supportsClientRedirect = true;
+ if (customCompressLevel.getValue())
+ cp.compressLevel = compressLevel.getValue();
+ else
+ cp.compressLevel = -1;
+
+ if (noJpeg.getValue())
+ cp.qualityLevel = qualityLevel.getValue();
+ else
+ cp.qualityLevel = -1;
+
+ if (sock == null) {
+ setServerName(Hostname.getHost(vncServerName));
+ setServerPort(Hostname.getPort(vncServerName));
try {
- if (viewer.tunnel.getValue() || (viewer.via.getValue() != null)) {
+ if (tunnel.getValue() || !via.getValue().isEmpty()) {
int localPort = TcpSocket.findFreeTcpPort();
if (localPort == 0)
throw new Exception("Could not obtain free TCP port");
throw new Exception(e.getMessage());
}
vlog.info("connected to host "+getServerName()+" port "+getServerPort());
+ } else {
+ String name = sock.getPeerEndpoint();
+ if (listenMode.getValue())
+ vlog.info("Accepted connection from " + name);
+ else
+ vlog.info("connected to host "+Hostname.getHost(name)+" port "+Hostname.getPort(name));
}
sock.inStream().setBlockCallback(this);
+
setStreams(sock.inStream(), sock.outStream());
+
initialiseProtocol();
+
+ OptionsDialog.addCallback("handleOptions", this);
}
public void refreshFramebuffer()
public final boolean getUserPasswd(StringBuffer user, StringBuffer passwd) {
String title = ("VNC Authentication ["
+csecurity.description() + "]");
- String passwordFileStr = viewer.passwordFile.getValue();
+ String passwordFileStr = passwordFile.getValue();
PasswdDialog dlg;
if (user == null && !passwordFileStr.equals("")) {
if (user == null) {
dlg = new PasswdDialog(title, (user == null), (passwd == null));
} else {
- if ((passwd == null) && viewer.sendLocalUsername.getValue()) {
+ if ((passwd == null) && sendLocalUsername.getValue()) {
user.append((String)System.getProperties().get("user.name"));
return true;
}
- dlg = new PasswdDialog(title, viewer.sendLocalUsername.getValue(),
+ dlg = new PasswdDialog(title, sendLocalUsername.getValue(),
(passwd == null));
}
- if (!dlg.showDialog()) return false;
+ dlg.showDialog();
if (user != null) {
- if (viewer.sendLocalUsername.getValue()) {
+ if (sendLocalUsername.getValue()) {
user.append((String)System.getProperties().get("user.name"));
} else {
user.append(dlg.userEntry.getText());
// If using AutoSelect with old servers, start in FullColor
// mode. See comment in autoSelectFormatAndEncoding.
- if (cp.beforeVersion(3, 8) && autoSelect)
- fullColour = true;
+ if (cp.beforeVersion(3, 8) && autoSelect.getValue())
+ fullColor.setParam(true);
serverPF = cp.pf();
- desktop = new DesktopWindow(cp.width, cp.height, serverPF, this);
- fullColourPF = desktop.getPreferredPF();
+ desktop = new DesktopWindow(cp.width, cp.height, cp.name(), serverPF, this);
+ fullColorPF = desktop.getPreferredPF();
// Force a switch to the format and encoding we'd like
formatChange = true; encodingChange = true;
cp.setPF(pendingPF);
pendingPFChange = false;
- if (viewer.embed.getValue()) {
- setupEmbeddedFrame();
- } else {
- recreateViewport();
- }
- }
-
- void setupEmbeddedFrame() {
- UIManager.getDefaults().put("ScrollPane.ancestorInputMap",
- new UIDefaults.LazyInputMap(new Object[]{}));
- JScrollPane sp = new JScrollPane();
- sp.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
- sp.getViewport().setBackground(Color.BLACK);
- InputMap im = sp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
- int ctrlAltShiftMask = Event.SHIFT_MASK | Event.CTRL_MASK | Event.ALT_MASK;
- if (im != null) {
- im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, ctrlAltShiftMask),
- "unitScrollUp");
- im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, ctrlAltShiftMask),
- "unitScrollDown");
- im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, ctrlAltShiftMask),
- "unitScrollLeft");
- im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, ctrlAltShiftMask),
- "unitScrollRight");
- im.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, ctrlAltShiftMask),
- "scrollUp");
- im.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, ctrlAltShiftMask),
- "scrollDown");
- im.put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, ctrlAltShiftMask),
- "scrollLeft");
- im.put(KeyStroke.getKeyStroke(KeyEvent.VK_END, ctrlAltShiftMask),
- "scrollRight");
- }
- sp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
- sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
- desktop.setViewport(sp.getViewport());
- viewer.getContentPane().removeAll();
- viewer.add(sp);
- viewer.addFocusListener(new FocusAdapter() {
- public void focusGained(FocusEvent e) {
- if (desktop.isAncestorOf(viewer))
- desktop.requestFocus();
- }
- public void focusLost(FocusEvent e) {
- releaseDownKeys();
- }
- });
- viewer.validate();
- desktop.requestFocus();
+ recreateViewport();
}
// setDesktopSize() is called when the desktop size changes (including when
String x509subject) {
try {
sock.close();
- setServerPort(port);
sock = new TcpSocket(host, port);
vlog.info("Redirected to "+host+":"+port);
- VncViewer.newViewer(viewer, sock, true);
+ setServerName(host);
+ setServerPort(port);
+ sock.inStream().setBlockCallback(this);
+ setStreams(sock.inStream(), sock.outStream());
+ initialiseProtocol();
} catch (java.lang.Exception e) {
throw new Exception(e.getMessage());
}
// setName() is called when the desktop name changes
public void setName(String name) {
super.setName(name);
-
- if (viewport != null) {
+ if (viewport != null)
viewport.setTitle(name+" - TigerVNC");
- }
}
// framebufferUpdateStart() is called at the beginning of an update.
// one.
public void framebufferUpdateStart()
{
+ super.framebufferUpdateStart();
+
// Note: This might not be true if sync fences are supported
pendingUpdate = false;
// appropriately, and then request another incremental update.
public void framebufferUpdateEnd()
{
+ super.framebufferUpdateEnd();
desktop.updateWindow();
writer().writeFence(fenceTypes.fenceFlagRequest | fenceTypes.fenceFlagSyncNext, 0, null);
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]);
+ !desktopSize.getValue().isEmpty() &&
+ desktopSize.getValue().split("x").length == 2) {
+ width = Integer.parseInt(desktopSize.getValue().split("x")[0]);
+ height = Integer.parseInt(desktopSize.getValue().split("x")[1]);
ScreenSet layout;
layout = cp.screenLayout;
}
// Compute new settings based on updated bandwidth values
- if (autoSelect)
+ if (autoSelect.getValue())
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 setColourMapEntries(int firstColor, int nColors, int[] rgbs) {
+ desktop.setColourMapEntries(firstColor, nColors, rgbs);
}
public void bell() {
- if (viewer.acceptBell.getValue())
+ if (acceptBell.getValue())
desktop.getToolkit().beep();
}
public void serverCutText(String str, int len) {
- if (viewer.acceptClipboard.getValue())
- clipboardDialog.serverCutText(str, len);
+ StringSelection buffer;
+
+ if (!acceptClipboard.getValue())
+ return;
+
+ ClipboardDialog.serverCutText(str);
}
// We start timing on beginRect and stop timing on endRect, to
return;
desktop.resize();
- if (viewer.embed.getValue()) {
- setupEmbeddedFrame();
- } else {
+ if (!firstUpdate)
recreateViewport();
- }
}
- public void setEmbeddedFeatures(boolean s) {
- menu.restore.setEnabled(s);
- menu.minimize.setEnabled(s);
- menu.maximize.setEnabled(s);
- menu.fullScreen.setEnabled(s);
- menu.newConn.setEnabled(s);
- options.fullScreen.setEnabled(s);
- options.fullScreenAllMonitors.setEnabled(s);
- options.scalingFactor.setEnabled(s);
- }
-
// 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.
public void recreateViewport() {
- if (viewer.embed.getValue())
- return;
- if (viewport != null) viewport.dispose();
- viewport = new Viewport(cp.name(), this);
- viewport.setUndecorated(fullScreen);
- desktop.setViewport(viewport.getViewport());
- reconfigureViewport();
- if ((cp.width > 0) && (cp.height > 0))
- viewport.setVisible(true);
- desktop.requestFocusInWindow();
+ if (embed.getValue()) {
+ desktop.setViewport(VncViewer.getViewport());
+ Container viewer =
+ SwingUtilities.getAncestorOfClass(JApplet.class, desktop);
+ viewer.addFocusListener(new FocusAdapter() {
+ public void focusGained(FocusEvent e) {
+ Container c =
+ SwingUtilities.getAncestorOfClass(JApplet.class, desktop);
+ if (c != null && desktop.isAncestorOf(c))
+ desktop.requestFocus();
+ }
+ public void focusLost(FocusEvent e) {
+ releaseDownKeys();
+ }
+ });
+ viewer.validate();
+ desktop.requestFocus();
+ } else {
+ if (viewport != null)
+ viewport.dispose();
+ viewport = new Viewport(cp.name(), this);
+ viewport.setUndecorated(fullScreen.getValue());
+ desktop.setViewport(viewport.getViewport());
+ reconfigureViewport();
+ if ((cp.width > 0) && (cp.height > 0))
+ viewport.setVisible(true);
+ desktop.requestFocusInWindow();
+ }
}
private void reconfigureViewport() {
Dimension dpySize = viewport.getScreenSize();
int w = desktop.scaledWidth;
int h = desktop.scaledHeight;
- if (fullScreen) {
- if (!viewer.fullScreenAllMonitors.getValue())
+ if (fullScreen.getValue()) {
+ if (!fullScreenAllMonitors.getValue())
viewport.setExtendedState(JFrame.MAXIMIZED_BOTH);
viewport.setBounds(viewport.getScreenBounds());
- if (!viewer.fullScreenAllMonitors.getValue())
+ if (!fullScreenAllMonitors.getValue())
Viewport.setFullScreenWindow(viewport);
} else {
int wmDecorationWidth = viewport.getInsets().left + viewport.getInsets().right;
private void autoSelectFormatAndEncoding() {
long kbitsPerSecond = sock.inStream().kbitsPerSecond();
long timeWaited = sock.inStream().timeWaited();
- boolean newFullColour = fullColour;
+ boolean newFullColor = fullColor.getValue();
int newQualityLevel = cp.qualityLevel;
// Always use Tight
vlog.info("Throughput "+kbitsPerSecond+
" kbit/s - changing to quality "+newQualityLevel);
cp.qualityLevel = newQualityLevel;
- viewer.qualityLevel.setParam(Integer.toString(newQualityLevel));
+ qualityLevel.setParam(newQualityLevel);
encodingChange = true;
}
}
}
// Select best color level
- newFullColour = (kbitsPerSecond > 256);
- if (newFullColour != fullColour) {
+ newFullColor = (kbitsPerSecond > 256);
+ if (newFullColor != fullColor.getValue()) {
vlog.info("Throughput "+kbitsPerSecond+
" kbit/s - full color is now "+
- (newFullColour ? "enabled" : "disabled"));
- fullColour = newFullColour;
+ (newFullColor ? "enabled" : "disabled"));
+ fullColor.setParam(newFullColor);
formatChange = true;
forceNonincremental = true;
}
/* Catch incorrect requestNewUpdate calls */
assert(!pendingUpdate || supportsSyncFence);
- if (fullColour) {
- pf = fullColourPF;
+ if (fullColor.getValue()) {
+ pf = fullColorPF;
} else {
- if (lowColourLevel == 0) {
- pf = verylowColourPF;
- } else if (lowColourLevel == 1) {
- pf = lowColourPF;
+ if (lowColorLevel.getValue() == 0) {
+ pf = verylowColorPF;
+ } else if (lowColorLevel.getValue() == 1) {
+ pf = lowColorPF;
} else {
- pf = mediumColourPF;
+ pf = mediumColorPF;
}
}
// close() shuts down the socket, thus waking up the RFB thread.
public void close() {
if (closeListener != null) {
- viewer.embed.setParam(true);
- if (VncViewer.nViewers == 1) {
- JFrame f = (JFrame)JOptionPane.getFrameForComponent(viewer);
- if (f != null)
- f.dispatchEvent(new WindowEvent(f, WindowEvent.WINDOW_CLOSING));
- }
+ embed.setParam(true);
+ JFrame f =
+ (JFrame)SwingUtilities.getAncestorOfClass(JFrame.class, desktop);
+ if (f != null)
+ f.dispatchEvent(new WindowEvent(f, WindowEvent.WINDOW_CLOSING));
}
deleteWindow();
shuttingDown = true;
}
}
- // 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() {
- String pkgDate = "";
- String pkgTime = "";
- try {
- Manifest manifest = new Manifest(VncViewer.timestamp);
- Attributes attributes = manifest.getMainAttributes();
- pkgDate = attributes.getValue("Package-Date");
- pkgTime = attributes.getValue("Package-Time");
- } catch (java.lang.Exception e) { }
-
- Window fullScreenWindow = Viewport.getFullScreenWindow();
- if (fullScreenWindow != null)
- Viewport.setFullScreenWindow(null);
- String msg =
- String.format(VncViewer.aboutText, VncViewer.version, VncViewer.build,
- VncViewer.buildDate, VncViewer.buildTime);
- JOptionPane op =
- new JOptionPane(msg, JOptionPane.INFORMATION_MESSAGE,
- JOptionPane.DEFAULT_OPTION, VncViewer.logoIcon);
- JDialog dlg = op.createDialog(desktop, "About TigerVNC Viewer for Java");
- dlg.setIconImage(VncViewer.frameIcon);
- dlg.setAlwaysOnTop(true);
- dlg.setVisible(true);
- if (fullScreenWindow != null)
- Viewport.setFullScreenWindow(fullScreenWindow);
- }
-
void showInfo() {
Window fullScreenWindow = Viewport.getFullScreenWindow();
if (fullScreenWindow != null)
cp.majorVersion, cp.minorVersion,
Security.secTypeName(csecurity.getType()),
csecurity.description());
- JOptionPane op = new JOptionPane(msg, JOptionPane.PLAIN_MESSAGE,
- JOptionPane.DEFAULT_OPTION);
+ Object[] options = {"Close \u21B5"};
+ JOptionPane op =
+ new JOptionPane(msg, JOptionPane.PLAIN_MESSAGE,
+ JOptionPane.DEFAULT_OPTION, null, options);
JDialog dlg = op.createDialog(desktop, "VNC connection info");
dlg.setIconImage(VncViewer.frameIcon);
dlg.setAlwaysOnTop(true);
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();
- if (digit >= 0 && digit <= 9) {
- options.compressLevel.setSelectedItem(digit);
- } else {
- options.compressLevel.setSelectedItem(Integer.parseInt(viewer.compressLevel.getDefaultStr()));
- }
- options.noJpeg.setSelected(!viewer.noJpeg.getValue());
- digit = 0 + viewer.qualityLevel.getValue();
- if (digit >= 0 && digit <= 9) {
- options.qualityLevel.setSelectedItem(digit);
- } else {
- options.qualityLevel.setSelectedItem(Integer.parseInt(viewer.qualityLevel.getDefaultStr()));
- }
-
- options.viewOnly.setSelected(viewer.viewOnly.getValue());
- options.acceptClipboard.setSelected(viewer.acceptClipboard.getValue());
- options.sendClipboard.setSelected(viewer.sendClipboard.getValue());
- options.menuKey.setSelectedItem(KeyEvent.getKeyText(MenuKey.getMenuKeyCode()));
- options.sendLocalUsername.setSelected(viewer.sendLocalUsername.getValue());
-
- 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.x509ca.setEnabled(false);
- options.caButton.setEnabled(false);
- options.x509crl.setEnabled(false);
- options.crlButton.setEnabled(false);
- options.secIdent.setEnabled(false);
- options.secNone.setEnabled(false);
- options.secVnc.setEnabled(false);
- options.secPlain.setEnabled(false);
- options.sendLocalUsername.setEnabled(false);
- options.cfLoadButton.setEnabled(false);
- options.cfSaveAsButton.setEnabled(true);
- options.sshTunnel.setEnabled(false);
- options.sshUseGateway.setEnabled(false);
- options.sshUser.setEnabled(false);
- options.sshHost.setEnabled(false);
- options.sshPort.setEnabled(false);
- options.sshUseExt.setEnabled(false);
- options.sshClient.setEnabled(false);
- options.sshClientBrowser.setEnabled(false);
- options.sshArgsDefault.setEnabled(false);
- options.sshArgsCustom.setEnabled(false);
- options.sshArguments.setEnabled(false);
- options.sshConfig.setEnabled(false);
- options.sshConfigBrowser.setEnabled(false);
- options.sshKeyFile.setEnabled(false);
- options.sshKeyFileBrowser.setEnabled(false);
- } else {
- options.shared.setSelected(viewer.shared.getValue());
- options.sendLocalUsername.setSelected(viewer.sendLocalUsername.getValue());
- options.cfSaveAsButton.setEnabled(false);
- if (viewer.tunnel.getValue() || viewer.via.getValue() != null)
- options.sshTunnel.setSelected(true);
- if (viewer.via.getValue() != null)
- options.sshUseGateway.setSelected(true);
- options.sshUser.setText(Tunnel.getSshUser(this));
- options.sshHost.setText(Tunnel.getSshHost(this));
- options.sshPort.setText(Integer.toString(Tunnel.getSshPort(this)));
- options.sshUseExt.setSelected(viewer.extSSH.getValue());
- File client = new File(viewer.extSSHClient.getValue());
- if (client.exists() && client.canRead())
- options.sshClient.setText(client.getAbsolutePath());
- if (viewer.extSSHArgs.getValue() == null) {
- options.sshArgsDefault.setSelected(true);
- options.sshArguments.setText("");
- } else {
- options.sshArgsCustom.setSelected(true);
- options.sshArguments.setText(viewer.extSSHArgs.getValue());
- }
- File config = new File(viewer.sshConfig.getValue());
- if (config.exists() && config.canRead())
- options.sshConfig.setText(config.getAbsolutePath());
- options.sshKeyFile.setText(Tunnel.getSshKeyFile(this));
-
- /* Process non-VeNCrypt sectypes */
- java.util.List<Integer> secTypes = new ArrayList<Integer>();
- secTypes = Security.GetEnabledSecTypes();
- for (Iterator<Integer> i = secTypes.iterator(); i.hasNext();) {
- switch ((Integer)i.next()) {
- case Security.secTypeVeNCrypt:
- options.secVeNCrypt.setSelected(UserPreferences.getBool("viewer", "secVeNCrypt", true));
- break;
- case Security.secTypeNone:
- options.encNone.setSelected(true);
- options.secNone.setSelected(UserPreferences.getBool("viewer", "secTypeNone", true));
- break;
- case Security.secTypeVncAuth:
- options.encNone.setSelected(true);
- options.secVnc.setSelected(UserPreferences.getBool("viewer", "secTypeVncAuth", true));
- break;
- }
- }
-
- /* Process VeNCrypt subtypes */
- if (options.secVeNCrypt.isSelected()) {
- java.util.List<Integer> secTypesExt = new ArrayList<Integer>();
- secTypesExt = Security.GetEnabledExtSecTypes();
- for (Iterator<Integer> iext = secTypesExt.iterator(); iext.hasNext();) {
- switch ((Integer)iext.next()) {
- case Security.secTypePlain:
- options.encNone.setSelected(UserPreferences.getBool("viewer", "encNone", true));
- options.secPlain.setSelected(UserPreferences.getBool("viewer", "secPlain", true));
- break;
- case Security.secTypeIdent:
- options.encNone.setSelected(UserPreferences.getBool("viewer", "encNone", true));
- options.secIdent.setSelected(UserPreferences.getBool("viewer", "secIdent", true));
- break;
- case Security.secTypeTLSNone:
- options.encTLS.setSelected(UserPreferences.getBool("viewer", "encTLS", true));
- options.secNone.setSelected(UserPreferences.getBool("viewer", "secNone", true));
- break;
- case Security.secTypeTLSVnc:
- options.encTLS.setSelected(UserPreferences.getBool("viewer", "encTLS", true));
- options.secVnc.setSelected(UserPreferences.getBool("viewer", "secVnc", true));
- break;
- case Security.secTypeTLSPlain:
- options.encTLS.setSelected(UserPreferences.getBool("viewer", "encTLS", true));
- options.secPlain.setSelected(UserPreferences.getBool("viewer", "secPlain", true));
- break;
- case Security.secTypeTLSIdent:
- options.encTLS.setSelected(UserPreferences.getBool("viewer", "encTLS", true));
- options.secIdent.setSelected(UserPreferences.getBool("viewer", "secIdent", true));
- break;
- case Security.secTypeX509None:
- options.encX509.setSelected(UserPreferences.getBool("viewer", "encX509", true));
- options.secNone.setSelected(UserPreferences.getBool("viewer", "secNone", true));
- break;
- case Security.secTypeX509Vnc:
- options.encX509.setSelected(UserPreferences.getBool("viewer", "encX509", true));
- options.secVnc.setSelected(UserPreferences.getBool("viewer", "secVnc", true));
- break;
- case Security.secTypeX509Plain:
- options.encX509.setSelected(UserPreferences.getBool("viewer", "encX509", true));
- options.secPlain.setSelected(UserPreferences.getBool("viewer", "secPlain", true));
- break;
- case Security.secTypeX509Ident:
- options.encX509.setSelected(UserPreferences.getBool("viewer", "encX509", true));
- options.secIdent.setSelected(UserPreferences.getBool("viewer", "secIdent", true));
- break;
- }
- }
- }
- File caFile = new File(viewer.x509ca.getValue());
- if (caFile.exists() && caFile.canRead())
- options.x509ca.setText(caFile.getAbsolutePath());
- File crlFile = new File(viewer.x509crl.getValue());
- if (crlFile.exists() && crlFile.canRead())
- options.x509crl.setText(crlFile.getAbsolutePath());
- options.encNone.setEnabled(options.secVeNCrypt.isSelected());
- options.encTLS.setEnabled(options.secVeNCrypt.isSelected());
- options.encX509.setEnabled(options.secVeNCrypt.isSelected());
- options.x509ca.setEnabled(options.secVeNCrypt.isSelected() &&
- options.encX509.isSelected());
- options.caButton.setEnabled(options.secVeNCrypt.isSelected() &&
- options.encX509.isSelected());
- options.x509crl.setEnabled(options.secVeNCrypt.isSelected() &&
- options.encX509.isSelected());
- options.crlButton.setEnabled(options.secVeNCrypt.isSelected() &&
- options.encX509.isSelected());
- options.secIdent.setEnabled(options.secVeNCrypt.isSelected());
- options.secPlain.setEnabled(options.secVeNCrypt.isSelected());
- options.sendLocalUsername.setEnabled(options.secPlain.isSelected()||
- options.secIdent.isSelected());
- options.sshTunnel.setEnabled(true);
- options.sshUseGateway.setEnabled(options.sshTunnel.isSelected());
- options.sshUser.setEnabled(options.sshTunnel.isSelected() &&
- options.sshUseGateway.isEnabled() &&
- options.sshUseGateway.isSelected());
- options.sshHost.setEnabled(options.sshTunnel.isSelected() &&
- options.sshUseGateway.isEnabled() &&
- options.sshUseGateway.isSelected());
- options.sshPort.setEnabled(options.sshTunnel.isSelected() &&
- options.sshUseGateway.isEnabled() &&
- options.sshUseGateway.isSelected());
- options.sshUseExt.setEnabled(options.sshTunnel.isSelected());
- options.sshClient.setEnabled(options.sshTunnel.isSelected() &&
- options.sshUseExt.isEnabled() &&
- options.sshUseExt.isSelected());
- options.sshClientBrowser.setEnabled(options.sshTunnel.isSelected() &&
- options.sshUseExt.isEnabled() &&
- options.sshUseExt.isSelected());
- options.sshArgsDefault.setEnabled(options.sshTunnel.isSelected() &&
- options.sshUseExt.isEnabled() &&
- options.sshUseExt.isSelected());
- options.sshArgsCustom.setEnabled(options.sshTunnel.isSelected() &&
- options.sshUseExt.isEnabled() &&
- options.sshUseExt.isSelected());
- options.sshArguments.setEnabled(options.sshTunnel.isSelected() &&
- options.sshUseExt.isEnabled() &&
- options.sshUseExt.isSelected() &&
- options.sshArgsCustom.isSelected());
- options.sshConfig.setEnabled(options.sshTunnel.isSelected() &&
- options.sshUseExt.isEnabled() &&
- !options.sshUseExt.isSelected());
- options.sshConfigBrowser.setEnabled(options.sshTunnel.isSelected() &&
- options.sshUseExt.isEnabled() &&
- !options.sshUseExt.isSelected());
- options.sshKeyFile.setEnabled(options.sshTunnel.isSelected() &&
- options.sshUseExt.isEnabled() &&
- !options.sshUseExt.isSelected());
- options.sshKeyFileBrowser.setEnabled(options.sshTunnel.isSelected() &&
- options.sshUseExt.isEnabled() &&
- !options.sshUseExt.isSelected());
- }
-
- options.fullScreen.setSelected(fullScreen);
- options.fullScreenAllMonitors.setSelected(viewer.fullScreenAllMonitors.getValue());
- options.useLocalCursor.setSelected(viewer.useLocalCursor.getValue());
- options.acceptBell.setSelected(viewer.acceptBell.getValue());
- String scaleString = viewer.scalingFactor.getValue();
- if (scaleString.equalsIgnoreCase("Auto")) {
- options.scalingFactor.setSelectedItem("Auto");
- } else if(scaleString.equalsIgnoreCase("FixedRatio")) {
- options.scalingFactor.setSelectedItem("Fixed Aspect Ratio");
- } else {
- digit = Integer.parseInt(scaleString);
- if (digit >= 1 && digit <= 1000) {
- options.scalingFactor.setSelectedItem(digit+"%");
- } else {
- digit = Integer.parseInt(viewer.scalingFactor.getDefaultStr());
- options.scalingFactor.setSelectedItem(digit+"%");
- }
- int scaleFactor =
- Integer.parseInt(scaleString.substring(0, scaleString.length()));
- }
- if (viewer.desktopSize.getValue() != null &&
- viewer.desktopSize.getValue().split("x").length == 2) {
- options.desktopSize.setSelected(true);
- String desktopWidth = viewer.desktopSize.getValue().split("x")[0];
- options.desktopWidth.setText(desktopWidth);
- String desktopHeight = viewer.desktopSize.getValue().split("x")[1];
- options.desktopHeight.setText(desktopHeight);
- }
+ public synchronized int currentEncoding() {
+ return currentEncoding;
}
- public void getOptions() {
- autoSelect = options.autoSelect.isSelected();
- if (fullColour != options.fullColour.isSelected()) {
- formatChange = true;
- forceNonincremental = 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;
- forceNonincremental = 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;
- }
+ public void handleOptions()
+ {
- viewer.customCompressLevel.setParam(options.customCompressLevel.isSelected());
- if (cp.customCompressLevel != viewer.customCompressLevel.getValue()) {
- cp.customCompressLevel = viewer.customCompressLevel.getValue();
- encodingChange = true;
- }
- if (Integer.parseInt(options.compressLevel.getSelectedItem().toString()) >= 0 &&
- Integer.parseInt(options.compressLevel.getSelectedItem().toString()) <= 9) {
- viewer.compressLevel.setParam(options.compressLevel.getSelectedItem().toString());
- } else {
- viewer.compressLevel.setParam(viewer.compressLevel.getDefaultStr());
- }
- 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;
- }
- if (!options.x509ca.getText().equals(""))
- CSecurityTLS.x509ca.setParam(options.x509ca.getText());
- if (!options.x509crl.getText().equals(""))
- CSecurityTLS.x509crl.setParam(options.x509crl.getText());
- viewer.sendLocalUsername.setParam(options.sendLocalUsername.isSelected());
-
- viewer.viewOnly.setParam(options.viewOnly.isSelected());
- viewer.acceptClipboard.setParam(options.acceptClipboard.isSelected());
- viewer.sendClipboard.setParam(options.sendClipboard.isSelected());
- viewer.acceptBell.setParam(options.acceptBell.isSelected());
- String scaleString =
- options.scalingFactor.getSelectedItem().toString();
- String oldScaleFactor = viewer.scalingFactor.getValue();
- if (scaleString.equalsIgnoreCase("Fixed Aspect Ratio")) {
- scaleString = new String("FixedRatio");
- } else if (scaleString.equalsIgnoreCase("Auto")) {
- scaleString = new String("Auto");
- } else {
- scaleString=scaleString.substring(0, scaleString.length()-1);
- }
- if (!oldScaleFactor.equals(scaleString)) {
- viewer.scalingFactor.setParam(scaleString);
- if ((options.fullScreen.isSelected() == fullScreen) &&
- (desktop != null))
- recreateViewport();
+ if (viewport != null && viewport.isVisible()) {
+ viewport.toFront();
+ viewport.requestFocus();
}
- clipboardDialog.setSendingEnabled(viewer.sendClipboard.getValue());
- viewer.menuKey.setParam(MenuKey.getMenuKeySymbols()[options.menuKey.getSelectedIndex()].name);
- F8Menu.f8.setText("Send "+KeyEvent.getKeyText(MenuKey.getMenuKeyCode()));
+ // Checking all the details of the current set of encodings is just
+ // a pain. Assume something has changed, as resending the encoding
+ // list is cheap. Avoid overriding what the auto logic has selected
+ // though.
+ if (!autoSelect.getValue()) {
+ int encNum = Encodings.encodingNum(preferredEncoding.getValue());
- setShared(options.shared.isSelected());
- viewer.useLocalCursor.setParam(options.useLocalCursor.isSelected());
- if (cp.supportsLocalCursor != viewer.useLocalCursor.getValue()) {
- cp.supportsLocalCursor = viewer.useLocalCursor.getValue();
- encodingChange = true;
- if (desktop != null)
- desktop.resetLocalCursor();
+ if (encNum != -1)
+ this.currentEncoding = encNum;
}
- viewer.extSSH.setParam(options.sshUseExt.isSelected());
- checkEncodings();
+ this.cp.supportsLocalCursor = useLocalCursor.getValue();
- 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);
- }
+ if (customCompressLevel.getValue())
+ this.cp.compressLevel = compressLevel.getValue();
+ else
+ this.cp.compressLevel = -1;
- /* 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);
- }
+ if (!noJpeg.getValue() && !autoSelect.getValue())
+ this.cp.qualityLevel = qualityLevel.getValue();
+ else
+ this.cp.qualityLevel = -1;
- /* 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);
- }
+ this.encodingChange = true;
- /* 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);
- }
+ // Format changes refreshes the entire screen though and are therefore
+ // very costly. It's probably worth the effort to see if it is necessary
+ // here.
+ PixelFormat pf;
- /* 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);
- }
+ if (fullColor.getValue()) {
+ pf = fullColorPF;
+ } else {
+ if (lowColorLevel.getValue() == 0)
+ pf = verylowColorPF;
+ else if (lowColorLevel.getValue() == 1)
+ pf = lowColorPF;
+ else
+ pf = mediumColorPF;
+ }
- /* 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);
- }
+ if (!pf.equal(this.cp.pf())) {
+ this.formatChange = true;
- /* 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);
- }
- if (options.sshTunnel.isSelected()) {
- if (options.sshUseGateway.isSelected()) {
- String user = options.sshUser.getText();
- String host = options.sshHost.getText();
- String port = options.sshPort.getText();
- viewer.via.setParam(user+"@"+host+":"+port);
- } else {
- viewer.tunnel.setParam(true);
- }
- }
- viewer.extSSH.setParam(options.sshUseExt.isSelected());
- viewer.extSSHClient.setParam(options.sshClient.getText());
- if (options.sshArgsCustom.isSelected())
- viewer.extSSHArgs.setParam(options.sshArguments.getText());
- viewer.sshConfig.setParam(options.sshConfig.getText());
- viewer.sshKeyFile.setParam(options.sshKeyFile.getText());
- }
- String desktopSize = (options.desktopSize.isSelected()) ?
- options.desktopWidth.getText() + "x" + options.desktopHeight.getText() : "";
- viewer.desktopSize.setParam(desktopSize);
- if (options.fullScreen.isSelected() ^ fullScreen) {
- viewer.fullScreenAllMonitors.setParam(options.fullScreenAllMonitors.isSelected());
- toggleFullScreen();
- } else {
- if (viewer.fullScreenAllMonitors.getValue() !=
- options.fullScreenAllMonitors.isSelected()) {
- viewer.fullScreenAllMonitors.setParam(options.fullScreenAllMonitors.isSelected());
- if (desktop != null)
- recreateViewport();
- } else {
- viewer.fullScreenAllMonitors.setParam(options.fullScreenAllMonitors.isSelected());
- }
+ // Without fences, we cannot safely trigger an update request directly
+ // but must wait for the next update to arrive.
+ if (this.supportsSyncFence)
+ this.requestNewUpdate();
}
+
}
public void toggleFullScreen() {
- if (viewer.embed.getValue())
+ if (embed.getValue())
return;
- fullScreen = !fullScreen;
- menu.fullScreen.setSelected(fullScreen);
+ fullScreen.setParam(!fullScreen.getValue());
if (viewport != null) {
if (!viewport.lionFSSupported()) {
recreateViewport();
}
public void writeKeyEvent(KeyEvent ev) {
- if (viewer.viewOnly.getValue() || shuttingDown)
+ if (viewOnly.getValue() || shuttingDown)
return;
boolean down = (ev.getID() == KeyEvent.KEY_PRESSED);
// the following never change so need no synchronization:
-
- // 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:
// reading and writing int and boolean is atomic in java, so no
// synchronization of the following flags is needed:
- 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;
+ private String serverHost;
+ private int serverPort;
private Socket sock;
protected DesktopWindow desktop;
- // FIXME: should be private
- public PixelFormat serverPF;
- private PixelFormat fullColourPF;
+ private PixelFormat serverPF;
+ private PixelFormat fullColorPF;
private boolean pendingPFChange;
private PixelFormat pendingPF;
private boolean supportsSyncFence;
- public int menuKeyCode;
Viewport viewport;
- private boolean fullColour;
- private boolean autoSelect;
- boolean fullScreen;
private HashMap<Integer, Integer> downKeySym;
public ActionListener closeListener = null;
import java.nio.*;
import javax.swing.*;
import javax.swing.border.*;
+import javax.swing.event.*;
import javax.swing.text.*;
import com.tigervnc.rfb.LogWriter;
+import static com.tigervnc.vncviewer.Parameters.*;
+
class ClipboardDialog extends Dialog {
- private class VncTransferHandler extends TransferHandler {
- // Custom TransferHandler designed to limit the size of outbound
- // clipboard transfers to VncViewer.maxCutText.getValue() bytes.
- private LogWriter vlog = new LogWriter("VncTransferHandler");
-
- public void exportToClipboard(JComponent c, Clipboard clip, int a)
- throws IllegalStateException {
- if (!(c instanceof JTextComponent)) return;
- StringSelection selection =
- new StringSelection(((JTextComponent)c).getText());
- clip.setContents(selection, null);
- }
+ protected static class MyJTextArea extends JTextArea {
- public boolean importData(JComponent c, Transferable t) {
- if (canImport(c, t.getTransferDataFlavors())) {
+ private class VncTransferHandler extends TransferHandler {
+ // Custom TransferHandler designed to limit the size of outbound
+ // clipboard transfers to VncViewer.maxCutText.getValue() bytes.
+ private LogWriter vlog = new LogWriter("VncTransferHandler");
+
+ public void exportToClipboard(JComponent c, Clipboard clip, int a)
+ throws IllegalStateException {
+ if (!(c instanceof JTextComponent)) return;
+ String text = ((JTextComponent)c).getText();
try {
- DataFlavor VncFlavor = null;
- for (DataFlavor f : t.getTransferDataFlavors())
- if (f.isFlavorTextType() && f.isRepresentationClassInputStream())
- VncFlavor = f;
- if (VncFlavor == null) return false;
- Reader reader = (Reader)VncFlavor.getReaderForText(t);
- CharBuffer cbuf =
- CharBuffer.allocate(VncViewer.maxCutText.getValue());
- cbuf.limit(reader.read(cbuf.array(), 0, cbuf.length()));
- reader.close();
- if (c instanceof JTextComponent)
- ((JTextComponent)c).setText(cbuf.toString());
- return true;
- } catch (OutOfMemoryError oome) {
- vlog.error("ERROR: Too much data on local clipboard!");
- } catch (UnsupportedFlavorException ufe) {
- // Skip import
- vlog.info(ufe.toString());
- } catch (IOException ioe) {
- // Skip import
- vlog.info(ioe.toString());
+ if (text.equals((String)clip.getData(DataFlavor.stringFlavor))) return;
+ } catch (IOException e) {
+ // worst case we set the clipboard contents unnecessarily
+ vlog.info(e.toString());
+ } catch (UnsupportedFlavorException e) {
+ // worst case we set the clipboard contents unnecessarily
+ vlog.info(e.toString());
}
- }
- return false;
- }
+ StringSelection selection = new StringSelection(text);
+ clip.setContents(selection, null);
+ }
+
+ public boolean importData(JComponent c, Transferable t) {
+ if (canImport(c, t.getTransferDataFlavors())) {
+ try {
+ DataFlavor VncFlavor = null;
+ for (DataFlavor f : t.getTransferDataFlavors()) {
+ if (f.isMimeTypeEqual("text/plain") &&
+ f.isRepresentationClassInputStream()) {
+ VncFlavor = f;
+ break;
+ }
+ }
+ if (VncFlavor == null) return false;
+ CharBuffer cbuf =
+ CharBuffer.allocate(maxCutText.getValue());
+ Reader reader = (Reader)VncFlavor.getReaderForText(t);
+ int n = reader.read(cbuf.array(), 0, cbuf.length());
+ reader.close();
+ // reader returns -1 (EOF) for empty clipboard
+ cbuf.limit(n < 0 ? 0 : n);
+ if (c instanceof JTextComponent)
+ if (!cbuf.toString().equals(((JTextComponent)c).getText()))
+ ((JTextComponent)c).setText(cbuf.toString());
+ return true;
+ } catch (OutOfMemoryError e) {
+ vlog.error("ERROR: Too much data on local clipboard!");
+ } catch (UnsupportedFlavorException e) {
+ // Skip import
+ vlog.info(e.toString());
+ } catch (IOException e) {
+ // Skip import
+ vlog.info(e.toString());
+ }
+ }
+ return false;
+ }
+
+ public boolean canImport(JComponent c, DataFlavor[] flavors) {
+ for (DataFlavor f : flavors)
+ if (f.isMimeTypeEqual("text/plain") &&
+ f.isRepresentationClassReader()) {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ private class MyTextListener implements DocumentListener {
+ public MyTextListener() { }
+
+ public void changedUpdate(DocumentEvent e) { }
+
+ public void insertUpdate(DocumentEvent e) {
+ if (!listen) return;
+ String text = textArea.getText();
+ if (sendClipboard.getValue())
+ VncViewer.cc.writeClientCutText(text, text.length());
+ }
+
+ public void removeUpdate(DocumentEvent e) { }
+ }
- public boolean canImport(JComponent c, DataFlavor[] flavors) {
- for (DataFlavor f : flavors)
- if (f.isFlavorTextType() && f.isRepresentationClassReader())
- return true;
- return false;
+ public MyJTextArea() {
+ super();
+ setTransferHandler(new VncTransferHandler());
+ getDocument().addDocumentListener(new MyTextListener());
+ // If the textArea can receive the focus, then text within the textArea
+ // can be selected. On platforms that don't support separate selection
+ // and clipboard buffers, this triggers a replacement of the textAra's
+ // contents with the selected text.
+ setFocusable(false);
+ setLineWrap(false);
+ setWrapStyleWord(true);
}
}
- public ClipboardDialog(CConn cc_) {
+ public ClipboardDialog() {
super(false);
setTitle("VNC Clipboard Viewer");
setPreferredSize(new Dimension(640, 480));
- addWindowFocusListener(new WindowAdapter() {
+ addWindowFocusListener(new WindowFocusListener() {
// Necessary to ensure that updates from the system clipboard
- // still occur when the ClipboardDialog has the focus.
- public void WindowGainedFocus(WindowEvent e) {
+ // are propagated to the textArea when the dialog is visible.
+ public void windowGainedFocus(WindowEvent e) {
clientCutText();
}
+ public void windowLostFocus(WindowEvent e) { }
});
- cc = cc_;
- textArea = new JTextArea();
- textArea.setTransferHandler(new VncTransferHandler());
- // If the textArea can receive the focus, then text within the textArea
- // can be selected. On platforms that don't support separate selection
- // and clipboard buffers, this triggers a replacement of the textAra's
- // contents with the selected text.
- textArea.setFocusable(false);
- textArea.setLineWrap(false);
- textArea.setWrapStyleWord(true);
JScrollPane sp = new JScrollPane(textArea);
getContentPane().add(sp, BorderLayout.CENTER);
// button panel placed below the scrollpane
pack();
}
- public void serverCutText(String str, int len) {
+ public static void showDialog(Container c) {
+ if (dialog == null)
+ dialog = new ClipboardDialog();
+ dialog.show(c);
+ }
+
+ public void show(Container c) {
+ super.showDialog(c);
+ }
+
+ public void endDialog() {
+ super.endDialog();
+ dialog.dispose();
+ }
+
+ public static void serverCutText(String str) {
+ if (textArea.getText().equals(str))
+ return;
+ // Update the text area with incoming serverCutText. We need to diable
+ // the DocumentListener temporarily to prevent an clientCutText msg from
+ // being sent back to the server when the textArea is updated.
+ listen = false;
textArea.setText(str);
textArea.copy();
+ listen = true;
}
- public void clientCutText() {
- int hc = textArea.getText().hashCode();
+ public static void clientCutText() {
+ // Update the textArea with the current contents of the system clipboard.
+ // The TransferHandler ensures that the textArea's contents are only
+ // changed when they differ from the clipboard's. If the textArea is
+ // updated, the DocumentListener will trigger an RFB clientCutText msg.
textArea.paste();
textArea.setCaretPosition(0);
- String text = textArea.getText();
- if (cc.viewer.sendClipboard.getValue())
- if (hc != text.hashCode())
- cc.writeClientCutText(text, text.length());
}
public void setSendingEnabled(boolean b) {
public void actionPerformed(ActionEvent e) {
Object s = e.getSource();
if (s instanceof JButton && (JButton)s == clearButton) {
- serverCutText(new String(""), 0);
+ serverCutText(new String(""));
} else if (s instanceof JButton && (JButton)s == sendButton) {
String text = textArea.getText();
- cc.writeClientCutText(text, text.length());
+ VncViewer.cc.writeClientCutText(text, text.length());
endDialog();
} else if (s instanceof JButton && (JButton)s == cancelButton) {
endDialog();
}
}
- CConn cc;
- JTextArea textArea;
- JButton clearButton, sendButton, cancelButton;
+ private JButton clearButton, sendButton, cancelButton;
+ private static boolean listen = true;
+ static ClipboardDialog dialog;
+ static MyJTextArea textArea = new MyJTextArea();
+ static Toolkit tk = Toolkit.getDefaultToolkit();
static LogWriter vlog = new LogWriter("ClipboardDialog");
}
import com.tigervnc.rfb.Cursor;
import com.tigervnc.rfb.Point;
+import static com.tigervnc.vncviewer.Parameters.*;
+
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,
+ public DesktopWindow(int width, int height, String name, PixelFormat serverPF,
CConn cc_) {
cc = cc_;
setSize(width, height);
setScaledSize();
setOpaque(false);
+ if (cc.viewport != null)
+ cc.viewport.setName(name);
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
} else {
vlog.debug("GraphicsDevice does not support HW acceleration.");
}
- im = new BIPixelBuffer(width, height, cc, this);
+ im = new BIPixelBuffer(serverPF, width, height, this);
cursor = new Cursor();
cursorBacking = new ManagedPixelBuffer();
addKeyListener(this);
addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent e) {
- cc.clipboardDialog.clientCutText();
+ ClipboardDialog.clientCutText();
}
public void focusLost(FocusEvent e) {
cc.releaseDownKeys();
});
setFocusTraversalKeysEnabled(false);
setFocusable(true);
+ OptionsDialog.addCallback("handleOptions", this);
}
public int width() {
// 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(cc.viewer.useLocalCursor) {
- if (!cc.viewer.useLocalCursor.getValue())
- return;
- }
+ if (!useLocalCursor.getValue())
+ return;
hideLocalCursor();
}
public void setScaledSize() {
- String scaleString = cc.viewer.scalingFactor.getValue();
+ String scaleString = scalingFactor.getValue();
if (!scaleString.equalsIgnoreCase("Auto") &&
!scaleString.equalsIgnoreCase("FixedRatio")) {
int scalingFactor = Integer.parseInt(scaleString);
// Mouse-Motion callback function
private void mouseMotionCB(MouseEvent e) {
- if (!cc.viewer.viewOnly.getValue() &&
+ if (!viewOnly.getValue() &&
e.getX() >= 0 && e.getX() <= scaledWidth &&
e.getY() >= 0 && e.getY() <= scaledHeight)
cc.writePointerEvent(e);
// Mouse callback function
private void mouseCB(MouseEvent e) {
- if (!cc.viewer.viewOnly.getValue()) {
+ if (!viewOnly.getValue()) {
if ((e.getID() == MouseEvent.MOUSE_RELEASED) ||
(e.getX() >= 0 && e.getX() <= scaledWidth &&
e.getY() >= 0 && e.getY() <= scaledHeight))
public void mousePressed(MouseEvent e) { mouseCB(e); }
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {
- if (cc.viewer.embed.getValue())
+ if (embed.getValue())
requestFocus();
}
public void mouseExited(MouseEvent e) {}
// MouseWheel callback function
private void mouseWheelCB(MouseWheelEvent e) {
- if (!cc.viewer.viewOnly.getValue())
+ if (!viewOnly.getValue())
cc.writeWheelEvent(e);
}
lastY : (int)Math.floor(lastY * scaleHeightRatio);
java.awt.Point ev = new java.awt.Point(lastX, lastY);
ev.translate(sx - lastX, sy - lastY);
- cc.showMenu((int)ev.getX(), (int)ev.getY());
+ F8Menu menu = new F8Menu(cc);
+ menu.show(this, (int)ev.getX(), (int)ev.getY());
return;
}
int ctrlAltShiftMask = Event.SHIFT_MASK | Event.CTRL_MASK | Event.ALT_MASK;
if ((e.getModifiers() & ctrlAltShiftMask) == ctrlAltShiftMask) {
switch (e.getKeyCode()) {
case KeyEvent.VK_A:
- cc.showAbout();
+ VncViewer.showAbout(this);
return;
case KeyEvent.VK_F:
cc.toggleFullScreen();
cc.showInfo();
return;
case KeyEvent.VK_O:
- cc.options.showDialog(cc.viewport);
+ OptionsDialog.showDialog(cc.viewport);
return;
case KeyEvent.VK_W:
- VncViewer.newViewer(cc.viewer);
+ VncViewer.newViewer();
return;
case KeyEvent.VK_LEFT:
case KeyEvent.VK_RIGHT:
setColourMapEntriesTimerThread = null;
}
+ public void handleOptions()
+ {
+ if (fullScreen.getValue() && Viewport.getFullScreenWindow() == null)
+ cc.toggleFullScreen();
+ else if (!fullScreen.getValue() && Viewport.getFullScreenWindow() != null)
+ cc.toggleFullScreen();
+ }
+
// access to cc by different threads is specified in CConn
CConn cc;
import java.awt.*;
import java.awt.Dialog.*;
import java.awt.event.*;
+import java.io.File;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.text.*;
}
}
- public boolean showDialog(Component c) {
+ public void showDialog(Component c) {
initDialog();
if (c != null) {
setLocationRelativeTo(c);
if (getModalityType() == ModalityType.APPLICATION_MODAL)
setAlwaysOnTop(true);
setVisible(true);
- return ret;
}
- public boolean showDialog() {
- return showDialog(null);
+ public void showDialog() {
+ showDialog(null);
}
public void endDialog() {
return width + gap;
}
+ public static File showChooser(String title, File defFile, Container c) {
+ JFileChooser fc = new JFileChooser(defFile);
+ fc.setDialogTitle(title);
+ fc.setApproveButtonText("OK \u21B5");
+ fc.setFileHidingEnabled(false);
+ if (fc.showOpenDialog(c) == JFileChooser.APPROVE_OPTION)
+ return fc.getSelectedFile();
+ else
+ return null;
+ }
+
+ protected File showChooser(String title, File defFile) {
+ return showChooser(title, defFile, this);
+ }
+
protected class GroupedJRadioButton extends JRadioButton {
public GroupedJRadioButton(String l, ButtonGroup g, JComponent c) {
super(l);
JTextField jtf = (JTextField)editor.getEditorComponent();
jtf.setDocument(doc);
}
+
}
private Window fullScreenWindow;
- protected boolean ret = true;
}
import java.awt.*;
import java.awt.Cursor;
import java.awt.event.*;
+import java.io.File;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JFileChooser;
-import javax.swing.JPopupMenu;
import javax.swing.JMenuItem;
-import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPopupMenu;
import com.tigervnc.rfb.*;
+import static com.tigervnc.vncviewer.Parameters.*;
+
public class F8Menu extends JPopupMenu implements ActionListener {
- public F8Menu(CConn cc_) {
+ public F8Menu(CConn cc) {
super("VNC Menu");
setLightWeightPopupEnabled(false);
- cc = cc_;
+ String os = System.getProperty("os.name");
+ if (os.startsWith("Windows"))
+ com.sun.java.swing.plaf.windows.WindowsLookAndFeel.setMnemonicHidden(false);
+ this.cc = cc;
restore = addMenuItem("Restore",KeyEvent.VK_R);
- restore.setEnabled(!cc.viewer.embed.getValue());
+ restore.setEnabled(!embed.getValue());
move = addMenuItem("Move");
move.setEnabled(false);
size = addMenuItem("Size");
size.setEnabled(false);
minimize = addMenuItem("Minimize", KeyEvent.VK_N);
- minimize.setEnabled(!cc.viewer.embed.getValue());
+ minimize.setEnabled(!embed.getValue());
maximize = addMenuItem("Maximize", KeyEvent.VK_X);
- maximize.setEnabled(!cc.viewer.embed.getValue());
+ maximize.setEnabled(!embed.getValue());
addSeparator();
exit = addMenuItem("Close Viewer", KeyEvent.VK_C);
addSeparator();
- fullScreen = new JCheckBoxMenuItem("Full Screen");
- fullScreen.setMnemonic(KeyEvent.VK_F);
- fullScreen.setSelected(cc.fullScreen);
- fullScreen.addActionListener(this);
- fullScreen.setEnabled(!cc.viewer.embed.getValue());
- add(fullScreen);
+ fullScreenCheckbox = new JCheckBoxMenuItem("Full Screen");
+ fullScreenCheckbox.setMnemonic(KeyEvent.VK_F);
+ fullScreenCheckbox.setSelected(fullScreen.getValue());
+ fullScreenCheckbox.addActionListener(this);
+ fullScreenCheckbox.setEnabled(!embed.getValue());
+ add(fullScreenCheckbox);
addSeparator();
clipboard = addMenuItem("Clipboard...");
addSeparator();
- f8 = addMenuItem("Send "+KeyEvent.getKeyText(MenuKey.getMenuKeyCode()), MenuKey.getMenuKeyCode());
+ int keyCode = MenuKey.getMenuKeyCode();
+ String keyText = KeyEvent.getKeyText(keyCode);
+ f8 = addMenuItem("Send "+keyText, keyCode);
ctrlAltDel = addMenuItem("Send Ctrl-Alt-Del");
addSeparator();
refresh = addMenuItem("Refresh Screen", KeyEvent.VK_H);
addSeparator();
newConn = addMenuItem("New connection...", KeyEvent.VK_W);
- newConn.setEnabled(!cc.viewer.embed.getValue());
+ newConn.setEnabled(!embed.getValue());
options = addMenuItem("Options...", KeyEvent.VK_O);
save = addMenuItem("Save connection info as...", KeyEvent.VK_S);
info = addMenuItem("Connection info...", KeyEvent.VK_I);
public void actionPerformed(ActionEvent ev) {
if (actionMatch(ev, exit)) {
cc.close();
- } else if (actionMatch(ev, fullScreen)) {
+ } else if (actionMatch(ev, fullScreenCheckbox)) {
cc.toggleFullScreen();
} else if (actionMatch(ev, restore)) {
- if (cc.fullScreen) cc.toggleFullScreen();
+ if (fullScreen.getValue()) cc.toggleFullScreen();
cc.viewport.setExtendedState(JFrame.NORMAL);
} else if (actionMatch(ev, minimize)) {
- if (cc.fullScreen) cc.toggleFullScreen();
+ if (fullScreen.getValue()) cc.toggleFullScreen();
cc.viewport.setExtendedState(JFrame.ICONIFIED);
} else if (actionMatch(ev, maximize)) {
- if (cc.fullScreen) cc.toggleFullScreen();
+ if (fullScreen.getValue()) cc.toggleFullScreen();
cc.viewport.setExtendedState(JFrame.MAXIMIZED_BOTH);
} else if (actionMatch(ev, clipboard)) {
- cc.clipboardDialog.showDialog(cc.viewport);
+ //ClipboardDialog dlg = new ClipboardDialog(cc);
+ ClipboardDialog.showDialog(cc.viewport);
} else if (actionMatch(ev, f8)) {
cc.writeKeyEvent(MenuKey.getMenuKeySym(), true);
cc.writeKeyEvent(MenuKey.getMenuKeySym(), false);
} else if (actionMatch(ev, refresh)) {
cc.refresh();
} else if (actionMatch(ev, newConn)) {
- VncViewer.newViewer(cc.viewer);
+ VncViewer.newViewer();
} else if (actionMatch(ev, options)) {
- cc.options.showDialog(cc.viewport);
+ OptionsDialog.showDialog(cc.viewport);
} else if (actionMatch(ev, save)) {
- JFileChooser fc = new JFileChooser();
- fc.setDialogTitle("Save current configuration as:");
- fc.setApproveButtonText("OK");
- fc.setFileHidingEnabled(false);
- Window fullScreenWindow = Viewport.getFullScreenWindow();
- if (fullScreenWindow != null)
- Viewport.setFullScreenWindow(null);
- int ret = fc.showOpenDialog(cc.viewport);
- if (fullScreenWindow != null)
- Viewport.setFullScreenWindow(fullScreenWindow);
- if (ret == JFileChooser.APPROVE_OPTION) {
- String filename = fc.getSelectedFile().toString();
- if (filename != null)
- Configuration.save(filename);
- }
+ String title = "Save the TigerVNC configuration to file";
+ File dflt = new File(FileUtils.getVncHomeDir().concat("default.tigervnc"));
+ if (!dflt.exists() || !dflt.isFile())
+ dflt = new File(FileUtils.getVncHomeDir());
+ File f = Dialog.showChooser(title, dflt, this);
+ while (f != null && f.exists() && f.isFile()) {
+ String msg = f.getAbsolutePath();
+ msg = msg.concat(" already exists. Do you want to overwrite?");
+ Object[] options = {"Overwrite", "No \u21B5"};
+ JOptionPane op =
+ new JOptionPane(msg, JOptionPane.QUESTION_MESSAGE,
+ JOptionPane.OK_CANCEL_OPTION, null, options, options[1]);
+ JDialog dlg = op.createDialog(this, "TigerVNC Viewer");
+ dlg.setIconImage(VncViewer.frameIcon);
+ dlg.setAlwaysOnTop(true);
+ dlg.setVisible(true);
+ if (op.getValue() == options[0])
+ break;
+ else
+ f = Dialog.showChooser(title, f, this);
+ }
+ if (f != null && (!f.exists() || f.canWrite()))
+ saveViewerParameters(f.getAbsolutePath(), vncServerName.getValue());
} else if (actionMatch(ev, info)) {
cc.showInfo();
} else if (actionMatch(ev, about)) {
- cc.showAbout();
+ VncViewer.showAbout(cc.desktop);
} else if (actionMatch(ev, dismiss)) {
firePopupMenuCanceled();
}
JMenuItem exit, clipboard, ctrlAltDel, refresh;
JMenuItem newConn, options, save, info, about, dismiss;
static JMenuItem f8;
- JCheckBoxMenuItem fullScreen;
+ JCheckBoxMenuItem fullScreenCheckbox;
static LogWriter vlog = new LogWriter("F8Menu");
}
import java.awt.*;
import java.awt.event.*;
import java.io.File;
+import java.lang.reflect.*;
import java.text.Format;
import java.text.NumberFormat;
import javax.swing.*;
import javax.swing.UIManager.*;
import javax.swing.text.*;
import java.util.*;
+import java.util.List;
import java.util.Map.Entry;
+import java.util.prefs.*;
import com.tigervnc.rfb.*;
import static java.awt.GridBagConstraints.REMAINDER;
import static java.awt.GridBagConstraints.VERTICAL;
+import static com.tigervnc.vncviewer.Parameters.*;
+
class OptionsDialog extends Dialog {
private class IntegerDocument extends PlainDocument {
}
}
- // Constants
- static LogWriter vlog = new LogWriter("OptionsDialog");
+ private static Map<String, Object> callbacks = new HashMap<String, Object>();
+ /* Compression */
+ JCheckBox autoselectCheckbox;
+
+ ButtonGroup encodingGroup;
+ JRadioButton tightButton;
+ JRadioButton zrleButton;
+ JRadioButton hextileButton;
+ JRadioButton rawButton;
+
+ ButtonGroup colorlevelGroup;
+ JRadioButton fullcolorButton;
+ JRadioButton mediumcolorButton;
+ JRadioButton lowcolorButton;
+ JRadioButton verylowcolorButton;
+
+ JCheckBox compressionCheckbox;
+ JCheckBox jpegCheckbox;
+ JComboBox compressionInput;
+ JComboBox jpegInput;
+
+ /* Security */
+ JCheckBox encNoneCheckbox;
+ JCheckBox encTLSCheckbox;
+ JCheckBox encX509Checkbox;
+ JTextField caInput;
+ JTextField crlInput;
+ JButton caChooser;
+ JButton crlChooser;
+
+ JCheckBox authNoneCheckbox;
+ JCheckBox authVncCheckbox;
+ JCheckBox authPlainCheckbox;
+ JCheckBox authIdentCheckbox;
+ JCheckBox sendLocalUsernameCheckbox;
- CConn cc;
- @SuppressWarnings({"rawtypes"})
- JComboBox menuKey, compressLevel, qualityLevel, scalingFactor;
- ButtonGroup encodingGroup, colourGroup, sshArgsGroup;
- JRadioButton zrle, hextile, tight, raw, fullColour, mediumColour,
- lowColour, veryLowColour, sshArgsDefault, sshArgsCustom;
- JCheckBox autoSelect, customCompressLevel, noJpeg, viewOnly,
- acceptClipboard, sendClipboard, acceptBell, desktopSize,
- fullScreen, fullScreenAllMonitors, shared, useLocalCursor,
- secVeNCrypt, encNone, encTLS, encX509, secNone, secVnc,
- secPlain, secIdent, sendLocalUsername, sshTunnel, sshUseExt,
- sshUseGateway;
- JButton okButton, cancelButton, caButton, crlButton, cfLoadButton,
- cfSaveAsButton, defSaveButton, defReloadButton, defClearButton,
- sshConfigBrowser, sshKeyFileBrowser, sshClientBrowser;
- JTextField desktopWidth, desktopHeight, x509ca, x509crl, sshUser, sshHost,
- sshPort, sshClient, sshArguments, sshConfig, sshKeyFile;
- JTabbedPane tabPane;
+ /* Input */
+ JCheckBox viewOnlyCheckbox;
+ JCheckBox acceptClipboardCheckbox;
+ JCheckBox sendClipboardCheckbox;
+ JComboBox menuKeyChoice;
+
+ /* Screen */
+ JCheckBox desktopSizeCheckbox;
+ JTextField desktopWidthInput;
+ JTextField desktopHeightInput;
+ JCheckBox fullScreenCheckbox;
+ JCheckBox fullScreenAllMonitorsCheckbox;
+ JComboBox scalingFactorInput;
+
+ /* Misc. */
+ JCheckBox sharedCheckbox;
+ JCheckBox localCursorCheckbox;
+ JCheckBox acceptBellCheckbox;
+
+ /* SSH */
+ JCheckBox tunnelCheckbox;
+ JCheckBox viaCheckbox;
+ JTextField viaUserInput;
+ JTextField viaHostInput;
+ JTextField viaPortInput;
+ JCheckBox extSSHCheckbox;
+ JTextField sshClientInput;
+ JButton sshClientChooser;
+ JRadioButton sshArgsDefaultButton;
+ JRadioButton sshArgsCustomButton;
+ JTextField sshArgsInput;
+ JTextField sshConfigInput;
+ JTextField sshKeyFileInput;
+ JButton sshConfigChooser;
+ JButton sshKeyFileChooser;
@SuppressWarnings({"rawtypes","unchecked"})
- public OptionsDialog(CConn cc_) {
+ public OptionsDialog() {
super(true);
- cc = cc_;
setTitle("VNC Viewer Options");
setResizable(false);
getContentPane().setLayout(
new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
- tabPane = new JTabbedPane();
+ JTabbedPane tabPane = new JTabbedPane();
tabPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
encodingGroup = new ButtonGroup();
- colourGroup = new ButtonGroup();
- sshArgsGroup = new ButtonGroup();
- int indent = 0;
+ colorlevelGroup = new ButtonGroup();
+
+ // tabPane
+ tabPane.addTab("Compression", createCompressionPanel());
+ tabPane.addTab("Security", createSecurityPanel());
+ tabPane.addTab("Input", createInputPanel());
+ tabPane.addTab("Screen", createScreenPanel());
+ tabPane.addTab("Misc", createMiscPanel());
+ tabPane.addTab("SSH", createSshPanel());
+ tabPane.setBorder(BorderFactory.createEmptyBorder());
+ // Resize the tabPane if necessary to prevent scrolling
+ Insets tpi =
+ (Insets)UIManager.get("TabbedPane:TabbedPaneTabArea.contentMargins");
+ int minWidth = tpi.left + tpi.right;
+ for (int i = 0; i < tabPane.getTabCount(); i++)
+ minWidth += tabPane.getBoundsAt(i).width;
+ int minHeight = tabPane.getPreferredSize().height;
+ if (tabPane.getPreferredSize().width < minWidth)
+ tabPane.setPreferredSize(new Dimension(minWidth, minHeight));
+
+ // button pane
+ JButton okButton = new JButton("OK \u21B5");
+ okButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ storeOptions();
+ endDialog();
+ }
+ });
+ JButton cancelButton = new JButton("Cancel");
+ cancelButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ endDialog();
+ }
+ });
+
+ JPanel buttonPane = new JPanel(new GridLayout(1, 5, 10, 10));
+ buttonPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 5));
+ buttonPane.add(Box.createRigidArea(new Dimension()));
+ buttonPane.add(Box.createRigidArea(new Dimension()));
+ buttonPane.add(Box.createRigidArea(new Dimension()));
+ buttonPane.add(cancelButton);
+ buttonPane.add(okButton);
+
+ this.add(tabPane);
+ this.add(buttonPane);
+ addListeners(this);
+ pack();
+ }
+
+ public static void showDialog(Container c) {
+ OptionsDialog dialog = new OptionsDialog();
+ dialog.show(c);
+ }
+
+ public void show(Container c) {
+ loadOptions();
+ super.showDialog(c);
+ }
+
+ public static void addCallback(String cb, Object obj)
+ {
+ callbacks.put(cb, obj);
+ }
+
+ public static void removeCallback(String cb)
+ {
+ callbacks.remove(cb);
+ }
+
+ public void endDialog() {
+ super.endDialog();
+ // Making a new dialog is so cheap that it's not worth keeping
+ this.dispose();
+ }
+
+ public void setEmbeddedFeatures(boolean s) {
+ fullScreenCheckbox.setEnabled(s);
+ fullScreenAllMonitorsCheckbox.setEnabled(s);
+ scalingFactorInput.setEnabled(s);
+ }
+
+ private void loadOptions()
+ {
+ /* Compression */
+ autoselectCheckbox.setSelected(autoSelect.getValue());
+
+ int encNum = Encodings.encodingNum(preferredEncoding.getValueStr());
+
+ switch (encNum) {
+ case Encodings.encodingTight:
+ tightButton.setSelected(true);
+ break;
+ case Encodings.encodingZRLE:
+ zrleButton.setSelected(true);
+ break;
+ case Encodings.encodingHextile:
+ hextileButton.setSelected(true);
+ break;
+ case Encodings.encodingRaw:
+ rawButton.setSelected(true);
+ break;
+ }
+
+ if (fullColor.getValue())
+ fullcolorButton.setSelected(true);
+ else {
+ switch (lowColorLevel.getValue()) {
+ case 0:
+ verylowcolorButton.setSelected(true);
+ break;
+ case 1:
+ lowcolorButton.setSelected(true);
+ break;
+ case 2:
+ mediumcolorButton.setSelected(true);
+ break;
+ }
+ }
+
+ int digit = 0;
+
+ compressionCheckbox.setSelected(customCompressLevel.getValue());
+ jpegCheckbox.setSelected(!noJpeg.getValue());
+ digit = 0 + compressLevel.getValue();
+ compressionInput.setSelectedItem(digit);
+ digit = 0 + qualityLevel.getValue();
+ jpegInput.setSelectedItem(digit);
+
+ handleAutoselect();
+ handleCompression();
+ handleJpeg();
+
+ /* Security */
+ Security security = new Security(SecurityClient.secTypes);
+
+ List<Integer> secTypes;
+ Iterator<Integer> iter;
+
+ List<Integer> secTypesExt;
+ Iterator<Integer> iterExt;
+
+ encNoneCheckbox.setSelected(false);
+ encTLSCheckbox.setSelected(false);
+ encX509Checkbox.setSelected(false);
+
+ authNoneCheckbox.setSelected(false);
+ authVncCheckbox.setSelected(false);
+ authPlainCheckbox.setSelected(false);
+ authIdentCheckbox.setSelected(false);
+ sendLocalUsernameCheckbox.setSelected(sendLocalUsername.getValue());
+
+ secTypes = security.GetEnabledSecTypes();
+ for (iter = secTypes.iterator(); iter.hasNext(); ) {
+ switch ((Integer)iter.next()) {
+ case Security.secTypeNone:
+ encNoneCheckbox.setSelected(true);
+ authNoneCheckbox.setSelected(true);
+ break;
+ case Security.secTypeVncAuth:
+ encNoneCheckbox.setSelected(true);
+ authVncCheckbox.setSelected(true);
+ break;
+ }
+ }
+
+ secTypesExt = security.GetEnabledExtSecTypes();
+ for (iterExt = secTypesExt.iterator(); iterExt.hasNext(); ) {
+ switch ((Integer)iterExt.next()) {
+ case Security.secTypePlain:
+ encNoneCheckbox.setSelected(true);
+ authPlainCheckbox.setSelected(true);
+ break;
+ case Security.secTypeIdent:
+ encNoneCheckbox.setSelected(true);
+ authIdentCheckbox.setSelected(true);
+ break;
+ case Security.secTypeTLSNone:
+ encTLSCheckbox.setSelected(true);
+ authNoneCheckbox.setSelected(true);
+ break;
+ case Security.secTypeTLSVnc:
+ encTLSCheckbox.setSelected(true);
+ authVncCheckbox.setSelected(true);
+ break;
+ case Security.secTypeTLSPlain:
+ encTLSCheckbox.setSelected(true);
+ authPlainCheckbox.setSelected(true);
+ break;
+ case Security.secTypeTLSIdent:
+ encTLSCheckbox.setSelected(true);
+ authIdentCheckbox.setSelected(true);
+ break;
+ case Security.secTypeX509None:
+ encX509Checkbox.setSelected(true);
+ authNoneCheckbox.setSelected(true);
+ break;
+ case Security.secTypeX509Vnc:
+ encX509Checkbox.setSelected(true);
+ authVncCheckbox.setSelected(true);
+ break;
+ case Security.secTypeX509Plain:
+ encX509Checkbox.setSelected(true);
+ authPlainCheckbox.setSelected(true);
+ break;
+ case Security.secTypeX509Ident:
+ encX509Checkbox.setSelected(true);
+ authIdentCheckbox.setSelected(true);
+ break;
+ }
+ }
+
+ File caFile = new File(CSecurityTLS.X509CA.getValueStr());
+ if (caFile.exists() && caFile.canRead())
+ caInput.setText(caFile.getAbsolutePath());
+ File crlFile = new File(CSecurityTLS.X509CRL.getValueStr());
+ if (crlFile.exists() && crlFile.canRead())
+ crlInput.setText(crlFile.getAbsolutePath());
+
+ handleX509();
+ handleSendLocalUsername();
+
+ /* Input */
+ viewOnlyCheckbox.setSelected(viewOnly.getValue());
+ acceptClipboardCheckbox.setSelected(acceptClipboard.getValue());
+ sendClipboardCheckbox.setSelected(sendClipboard.getValue());
+
+ menuKeyChoice.setSelectedIndex(0);
+
+ String menuKeyStr = menuKey.getValueStr();
+ for (int i = 0; i < menuKeyChoice.getItemCount(); i++)
+ if (menuKeyStr.equals(menuKeyChoice.getItemAt(i)))
+ menuKeyChoice.setSelectedIndex(i);
+
+ /* Screen */
+ String width, height;
+
+ if (desktopSize.getValueStr().isEmpty() ||
+ desktopSize.getValueStr().split("x").length != 2) {
+ desktopSizeCheckbox.setSelected(false);
+ desktopWidthInput.setText("1024");
+ desktopHeightInput.setText("768");
+ } else {
+ desktopSizeCheckbox.setSelected(true);
+ width = desktopSize.getValueStr().split("x")[0];
+ desktopWidthInput.setText(width);
+ height = desktopSize.getValueStr().split("x")[1];
+ desktopHeightInput.setText(height);
+ }
+ fullScreenCheckbox.setSelected(fullScreen.getValue());
+ fullScreenAllMonitorsCheckbox.setSelected(fullScreenAllMonitors.getValue());
+
+ scalingFactorInput.setSelectedItem("100%");
+ String scaleStr = scalingFactor.getValueStr();
+ if (scaleStr.matches("^[0-9]+$"))
+ scaleStr = scaleStr.concat("%");
+ for (int i = 0; i < scalingFactorInput.getItemCount(); i++)
+ if (scaleStr.equals(scalingFactorInput.getItemAt(i)))
+ scalingFactorInput.setSelectedIndex(i);
+
+ handleDesktopSize();
+
+ /* Misc. */
+ sharedCheckbox.setSelected(shared.getValue());
+ localCursorCheckbox.setSelected(useLocalCursor.getValue());
+ acceptBellCheckbox.setSelected(acceptBell.getValue());
+
+ /* SSH */
+ File f;
+ tunnelCheckbox.setSelected(tunnel.getValue() || !via.getValueStr().isEmpty());
+ viaCheckbox.setSelected(!via.getValueStr().isEmpty());
+ if (viaCheckbox.isSelected()) {
+ viaUserInput.setText(Tunnel.getSshUser());
+ viaHostInput.setText(Tunnel.getSshHost());
+ viaPortInput.setText(Integer.toString(Tunnel.getSshPort()));
+ }
+ extSSHCheckbox.setSelected(extSSH.getValue());
+ f = new File(extSSHClient.getValueStr());
+ if (f.exists() && f.isFile() && f.canExecute())
+ sshClientInput.setText(f.getAbsolutePath());
+ if (extSSHArgs.getValueStr().isEmpty()) {
+ sshArgsDefaultButton.setSelected(true);
+ } else {
+ sshArgsCustomButton.setSelected(true);
+ sshArgsInput.setText(extSSHArgs.getValueStr());
+ }
+ f = new File(sshKeyFile.getValueStr());
+ if (f.exists() && f.isFile() && f.canRead())
+ sshKeyFileInput.setText(f.getAbsolutePath());
+ f = new File(sshConfig.getValueStr());
+ if (f.exists() && f.isFile() && f.canRead())
+ sshConfigInput.setText(f.getAbsolutePath());
+
+ handleTunnel();
+ handleVia();
+ handleExtSSH();
+ handleEmbed();
+ handleRfbState();
+ }
+
+ private void storeOptions() {
+ /* Compression */
+ autoSelect.setParam(autoselectCheckbox.isSelected());
+
+ if (tightButton.isSelected())
+ preferredEncoding.setParam(Encodings.encodingName(Encodings.encodingTight));
+ else if (zrleButton.isSelected())
+ preferredEncoding.setParam(Encodings.encodingName(Encodings.encodingZRLE));
+ else if (hextileButton.isSelected())
+ preferredEncoding.setParam(Encodings.encodingName(Encodings.encodingHextile));
+ else if (rawButton.isSelected())
+ preferredEncoding.setParam(Encodings.encodingName(Encodings.encodingRaw));
+
+ fullColor.setParam(fullcolorButton.isSelected());
+ if (verylowcolorButton.isSelected())
+ lowColorLevel.setParam(0);
+ else if (lowcolorButton.isSelected())
+ lowColorLevel.setParam(1);
+ else if (mediumcolorButton.isSelected())
+ lowColorLevel.setParam(2);
+
+ customCompressLevel.setParam(compressionCheckbox.isSelected());
+ noJpeg.setParam(!jpegCheckbox.isSelected());
+ compressLevel.setParam((Integer)compressionInput.getSelectedItem());
+ qualityLevel.setParam((Integer)jpegInput.getSelectedItem());
+
+ /* Security */
+ Security security = new Security();
+
+ /* Process security types which don't use encryption */
+ if (encNoneCheckbox.isSelected()) {
+ if (authNoneCheckbox.isSelected())
+ security.EnableSecType(Security.secTypeNone);
+ if (authVncCheckbox.isSelected())
+ security.EnableSecType(Security.secTypeVncAuth);
+ if (authPlainCheckbox.isSelected())
+ security.EnableSecType(Security.secTypePlain);
+ if (authIdentCheckbox.isSelected())
+ security.EnableSecType(Security.secTypeIdent);
+ }
+
+ /* Process security types which use TLS encryption */
+ if (encTLSCheckbox.isSelected()) {
+ if (authNoneCheckbox.isSelected())
+ security.EnableSecType(Security.secTypeTLSNone);
+ if (authVncCheckbox.isSelected())
+ security.EnableSecType(Security.secTypeTLSVnc);
+ if (authPlainCheckbox.isSelected())
+ security.EnableSecType(Security.secTypeTLSPlain);
+ if (authIdentCheckbox.isSelected())
+ security.EnableSecType(Security.secTypeTLSIdent);
+ }
+
+ /* Process security types which use X509 encryption */
+ if (encX509Checkbox.isSelected()) {
+ if (authNoneCheckbox.isSelected())
+ security.EnableSecType(Security.secTypeX509None);
+ if (authVncCheckbox.isSelected())
+ security.EnableSecType(Security.secTypeX509Vnc);
+ if (authPlainCheckbox.isSelected())
+ security.EnableSecType(Security.secTypeX509Plain);
+ if (authIdentCheckbox.isSelected())
+ security.EnableSecType(Security.secTypeX509Ident);
+ }
+
+ if (authIdentCheckbox.isSelected() ||
+ authPlainCheckbox.isSelected()) {
+ sendLocalUsername.setParam(sendLocalUsernameCheckbox.isSelected());
+ }
+
+ SecurityClient.secTypes.setParam(security.ToString());
+
+ File caFile = new File(caInput.getText());
+ if (caFile.exists() && caFile.canRead())
+ CSecurityTLS.X509CA.setParam(caFile.getAbsolutePath());
+ File crlFile = new File(crlInput.getText());
+ if (crlFile.exists() && crlFile.canRead())
+ CSecurityTLS.X509CRL.setParam(crlFile.getAbsolutePath());
+
+ /* Input */
+ viewOnly.setParam(viewOnlyCheckbox.isSelected());
+ acceptClipboard.setParam(acceptClipboardCheckbox.isSelected());
+ sendClipboard.setParam(sendClipboardCheckbox.isSelected());
+
+ String menuKeyStr =
+ MenuKey.getMenuKeySymbols()[menuKeyChoice.getSelectedIndex()].name;
+ menuKey.setParam(menuKeyStr);
- // Compression tab
+ /* Screen */
+ if (desktopSizeCheckbox.isSelected() &&
+ !desktopWidthInput.getText().isEmpty() &&
+ !desktopHeightInput.getText().isEmpty()) {
+ String width = desktopWidthInput.getText();
+ String height = desktopHeightInput.getText();
+ desktopSize.setParam(width.concat("x").concat(height));
+ } else {
+ desktopSize.setParam("");
+ }
+ fullScreen.setParam(fullScreenCheckbox.isSelected());
+ fullScreenAllMonitors.setParam(fullScreenAllMonitorsCheckbox.isSelected());
+
+ String scaleStr =
+ ((String)scalingFactorInput.getSelectedItem()).replace("%", "");
+ if (scaleStr.equals("Fixed Aspect Ratio"))
+ scaleStr = "FixedRatio";
+ scalingFactor.setParam(scaleStr);
+
+ /* Misc. */
+ shared.setParam(sharedCheckbox.isSelected());
+ useLocalCursor.setParam(localCursorCheckbox.isSelected());
+ acceptBell.setParam(acceptBellCheckbox.isSelected());
+
+ /* SSH */
+ tunnel.setParam(tunnelCheckbox.isSelected());
+ if (viaCheckbox.isSelected() &&
+ !viaUserInput.getText().isEmpty() &&
+ !viaHostInput.getText().isEmpty() &&
+ !viaPortInput.getText().isEmpty()) {
+ String sshUser = viaUserInput.getText();
+ String sshHost = viaHostInput.getText();
+ String sshPort = viaPortInput.getText();
+ String viaStr = sshUser.concat("@").concat(sshHost).concat(":").concat(sshPort);
+ via.setParam(viaStr);
+ }
+ extSSH.setParam(extSSHCheckbox.isSelected());
+ if (!sshClientInput.getText().isEmpty())
+ extSSHClient.setParam(sshClientInput.getText());
+ if (sshArgsDefaultButton.isSelected())
+ if (!sshArgsInput.getText().isEmpty())
+ extSSHArgs.setParam(sshArgsInput.getText());
+ if (!sshConfigInput.getText().isEmpty())
+ sshConfig.setParam(sshConfigInput.getText());
+ if (!sshKeyFileInput.getText().isEmpty())
+ sshKeyFile.setParam(sshKeyFileInput.getText());
+
+ try {
+ for (Map.Entry<String, Object> iter : callbacks.entrySet()) {
+ Object obj = iter.getValue();
+ Method cb = obj.getClass().getMethod(iter.getKey(), new Class[]{});
+ cb.invoke(obj);
+ }
+ } catch (NoSuchMethodException e) {
+ vlog.error("NoSuchMethodException: "+e.getMessage());
+ } catch (IllegalAccessException e) {
+ vlog.error("IllegalAccessException: "+e.getMessage());
+ } catch (InvocationTargetException e) {
+ vlog.error("InvocationTargetException: "+e.getMessage());
+ }
+ }
+
+ private JPanel createCompressionPanel() {
JPanel FormatPanel = new JPanel();
FormatPanel.setLayout(new BoxLayout(FormatPanel,
BoxLayout.PAGE_AXIS));
autoSelectPane.setLayout(new BoxLayout(autoSelectPane,
BoxLayout.LINE_AXIS));
autoSelectPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
- autoSelect = new JCheckBox("Auto Select");
- autoSelectPane.add(autoSelect);
+ autoselectCheckbox = new JCheckBox("Auto Select");
+ autoselectCheckbox.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ handleAutoselect();
+ }
+ });
+ autoSelectPane.add(autoselectCheckbox);
autoSelectPane.add(Box.createHorizontalGlue());
JPanel encodingPanel = new JPanel(new GridLayout(4, 1));
- encodingPanel.
- setBorder(BorderFactory.createTitledBorder("Preferred encoding"));
- tight = new GroupedJRadioButton("Tight",
- encodingGroup, encodingPanel);
- zrle = new GroupedJRadioButton("ZRLE",
- encodingGroup, encodingPanel);
- hextile = new GroupedJRadioButton("Hextile",
- encodingGroup, encodingPanel);
- raw = new GroupedJRadioButton("Raw", encodingGroup, encodingPanel);
-
- JPanel colourPanel = new JPanel(new GridLayout(4, 1));
- colourPanel.setBorder(BorderFactory.createTitledBorder("Color level"));
- fullColour = new GroupedJRadioButton("Full (all available colors)",
- colourGroup, colourPanel);
- mediumColour = new GroupedJRadioButton("Medium (256 colors)",
- colourGroup, colourPanel);
- lowColour = new GroupedJRadioButton("Low (64 colours)",
- colourGroup, colourPanel);
- veryLowColour = new GroupedJRadioButton("Very low(8 colors)",
- colourGroup, colourPanel);
+ encodingPanel.setBorder(BorderFactory.createTitledBorder("Preferred encoding"));
+ tightButton = new GroupedJRadioButton("Tight", encodingGroup, encodingPanel);
+ zrleButton = new GroupedJRadioButton("ZRLE", encodingGroup, encodingPanel);
+ hextileButton = new GroupedJRadioButton("Hextile", encodingGroup, encodingPanel);
+ rawButton = new GroupedJRadioButton("Raw", encodingGroup, encodingPanel);
+
+ JPanel colorPanel = new JPanel(new GridLayout(4, 1));
+ colorPanel.setBorder(BorderFactory.createTitledBorder("Color level"));
+ fullcolorButton = new GroupedJRadioButton("Full (all available colors)",
+ colorlevelGroup, colorPanel);
+ mediumcolorButton = new GroupedJRadioButton("Medium (256 colors)",
+ colorlevelGroup, colorPanel);
+ lowcolorButton = new GroupedJRadioButton("Low (64 colors)",
+ colorlevelGroup, colorPanel);
+ verylowcolorButton = new GroupedJRadioButton("Very low (8 colors)",
+ colorlevelGroup, colorPanel);
JPanel encodingPane = new JPanel(new GridLayout(1, 2, 5, 0));
encodingPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
encodingPane.add(encodingPanel);
- encodingPane.add(colourPanel);
+ encodingPane.add(colorPanel);
JPanel tightPanel = new JPanel(new GridBagLayout());
- customCompressLevel = new JCheckBox("Custom Compression Level");
+ compressionCheckbox = new JCheckBox("Custom Compression Level");
+ compressionCheckbox.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ handleCompression();
+ }
+ });
Object[] compressionLevels = { 1, 2, 3, 4, 5, 6 };
- compressLevel = new MyJComboBox(compressionLevels);
- ((MyJComboBox)compressLevel).setDocument(new IntegerDocument(1));
- compressLevel.setPrototypeDisplayValue("0.");
- compressLevel.setEditable(true);
+ compressionInput = new MyJComboBox(compressionLevels);
+ ((MyJComboBox)compressionInput).setDocument(new IntegerDocument(1));
+ compressionInput.setPrototypeDisplayValue("0.");
+ compressionInput.setEditable(true);
JLabel compressionLabel =
new JLabel("Level (1=fast, 6=best [4-6 are rarely useful])");
- noJpeg = new JCheckBox("Allow JPEG Compression");
+ jpegCheckbox = new JCheckBox("Allow JPEG Compression");
+ jpegCheckbox.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ handleJpeg();
+ }
+ });
Object[] qualityLevels = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
- qualityLevel = new MyJComboBox(qualityLevels);
- qualityLevel.setPrototypeDisplayValue("0.");
+ jpegInput = new MyJComboBox(qualityLevels);
+ jpegInput.setPrototypeDisplayValue("0.");
JLabel qualityLabel = new JLabel("Quality (0=poor, 9=best)");
- tightPanel.add(customCompressLevel,
+ tightPanel.add(compressionCheckbox,
new GridBagConstraints(0, 0,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 0, 0),
NONE, NONE));
- indent = getButtonLabelInset(customCompressLevel);
- tightPanel.add(compressLevel,
+ int indent = getButtonLabelInset(compressionCheckbox);
+ tightPanel.add(compressionInput,
new GridBagConstraints(0, 1,
1, 1,
LIGHT, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 0, 0),
NONE, NONE));
- tightPanel.add(noJpeg,
+ tightPanel.add(jpegCheckbox,
new GridBagConstraints(0, 2,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(5, 0, 0, 0),
NONE, NONE));
- indent = getButtonLabelInset(noJpeg);
- tightPanel.add(qualityLevel,
+ indent = getButtonLabelInset(jpegCheckbox);
+ tightPanel.add(jpegInput,
new GridBagConstraints(0, 3,
1, 1,
LIGHT, LIGHT,
FormatPanel.add(autoSelectPane);
FormatPanel.add(encodingPane);
FormatPanel.add(tightPanel);
+ return FormatPanel;
+ }
- // security tab
+ private JPanel createSecurityPanel() {
JPanel SecPanel = new JPanel();
SecPanel.setLayout(new BoxLayout(SecPanel,
BoxLayout.PAGE_AXIS));
vencryptPane.setLayout(new BoxLayout(vencryptPane,
BoxLayout.LINE_AXIS));
vencryptPane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
- secVeNCrypt = new JCheckBox("Extended encryption and "+
- "authentication methods (VeNCrypt)");
- vencryptPane.add(secVeNCrypt);
- vencryptPane.add(Box.createHorizontalGlue());
JPanel encrPanel = new JPanel(new GridBagLayout());
encrPanel.setBorder(BorderFactory.createTitledBorder("Encryption"));
- encNone = new JCheckBox("None");
- encTLS = new JCheckBox("Anonymous TLS");
- encX509 = new JCheckBox("TLS with X.509 certificates");
+ encNoneCheckbox = new JCheckBox("None");
+ encTLSCheckbox = new JCheckBox("Anonymous TLS");
+ encX509Checkbox = new JCheckBox("TLS with X.509 certificates");
+ encX509Checkbox.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ handleX509();
+ }
+ });
JLabel caLabel = new JLabel("X.509 CA Certificate");
- x509ca = new JTextField();
- x509ca.setName(Configuration.getParam("x509ca").getName());
- caButton = new JButton("Browse");
+ caInput = new JTextField();
+ caChooser = new JButton("Browse");
+ caChooser.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ JComponent c = ((JButton)e.getSource()).getRootPane();
+ File dflt = new File(CSecurityTLS.X509CA.getValueStr());
+ File f = showChooser("Path to X509 CA certificate", dflt, c);
+ if (f != null && f.exists() && f.canRead())
+ caInput.setText(f.getAbsolutePath());
+ }
+ });
JLabel crlLabel = new JLabel("X.509 CRL file");
- x509crl = new JTextField();
- x509crl.setName(Configuration.getParam("x509crl").getName());
- crlButton = new JButton("Browse");
- encrPanel.add(encNone,
+ crlInput = new JTextField();
+ crlChooser = new JButton("Browse");
+ crlChooser.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ JComponent c = ((JButton)e.getSource()).getRootPane();
+ File dflt = new File(CSecurityTLS.X509CRL.getValueStr());
+ File f = showChooser("Path to X509 CRL file", dflt, c);
+ if (f != null && f.exists() && f.canRead())
+ crlInput.setText(f.getAbsolutePath());
+ }
+ });
+ encrPanel.add(encNoneCheckbox,
new GridBagConstraints(0, 0,
REMAINDER, 1,
HEAVY, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
- encrPanel.add(encTLS,
+ encrPanel.add(encTLSCheckbox,
new GridBagConstraints(0, 1,
REMAINDER, 1,
HEAVY, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
- encrPanel.add(encX509,
+ encrPanel.add(encX509Checkbox,
new GridBagConstraints(0, 2,
3, 1,
HEAVY, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 0, 0),
NONE, NONE));
- indent = getButtonLabelInset(encX509);
+ int indent = getButtonLabelInset(encX509Checkbox);
encrPanel.add(caLabel,
new GridBagConstraints(0, 3,
1, 1,
LINE_END, NONE,
new Insets(0, indent, 5, 0),
0, 0));
- encrPanel.add(x509ca,
+ encrPanel.add(caInput,
new GridBagConstraints(1, 3,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 5, 0),
0, 0));
- encrPanel.add(caButton,
+ encrPanel.add(caChooser,
new GridBagConstraints(2, 3,
1, 1,
LIGHT, LIGHT,
LINE_END, NONE,
new Insets(0, indent, 0, 0),
0, 0));
- encrPanel.add(x509crl,
+ encrPanel.add(crlInput,
new GridBagConstraints(1, 4,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 0, 0),
0, 0));
- encrPanel.add(crlButton,
+ encrPanel.add(crlChooser,
new GridBagConstraints(2, 4,
1, 1,
LIGHT, LIGHT,
JPanel authPanel = new JPanel(new GridBagLayout());
authPanel.setBorder(BorderFactory.createTitledBorder("Authentication"));
- secNone = new JCheckBox("None");
- secVnc = new JCheckBox("Standard VNC");
- secPlain = new JCheckBox("Plaintext");
- secIdent = new JCheckBox("Ident");
- sendLocalUsername = new JCheckBox("Send Local Username");
- authPanel.add(secNone,
+ authNoneCheckbox = new JCheckBox("None");
+ authVncCheckbox = new JCheckBox("Standard VNC");
+ authPlainCheckbox = new JCheckBox("Plaintext");
+ authPlainCheckbox.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ handleSendLocalUsername();
+ }
+ });
+ authIdentCheckbox = new JCheckBox("Ident");
+ authIdentCheckbox.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ handleSendLocalUsername();
+ }
+ });
+ sendLocalUsernameCheckbox = new JCheckBox("Send Local Username");
+ authPanel.add(authNoneCheckbox,
new GridBagConstraints(0, 0,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
- authPanel.add(secVnc,
+ authPanel.add(authVncCheckbox,
new GridBagConstraints(0, 1,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
- authPanel.add(secPlain,
+ authPanel.add(authPlainCheckbox,
new GridBagConstraints(0, 2,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 2, 0),
NONE, NONE));
- authPanel.add(secIdent,
+ authPanel.add(authIdentCheckbox,
new GridBagConstraints(0, 3,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(2, 0, 0, 0),
NONE, NONE));
- authPanel.add(sendLocalUsername,
+ authPanel.add(sendLocalUsernameCheckbox,
new GridBagConstraints(1, 2,
1, 2,
HEAVY, LIGHT,
LINE_START, BOTH,
new Insets(0, 0, 0, 0),
NONE, NONE));
+ return SecPanel;
+ }
- // Input tab
+ private JPanel createInputPanel() {
JPanel inputPanel = new JPanel(new GridBagLayout());
inputPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
- viewOnly = new JCheckBox("View Only (ignore mouse & keyboard)");
- acceptClipboard = new JCheckBox("Accept clipboard from server");
- sendClipboard = new JCheckBox("Send clipboard to server");
- JLabel menuKeyLabel = new JLabel("Menu Key");
+ viewOnlyCheckbox = new JCheckBox("View only (ignore mouse and keyboard)");
+ acceptClipboardCheckbox = new JCheckBox("Accept clipboard from server");
+ sendClipboardCheckbox = new JCheckBox("Send clipboard to server");
+ JLabel menuKeyLabel = new JLabel("Menu key");
String[] menuKeys = new String[MenuKey.getMenuKeySymbolCount()];
+ //String[] menuKeys = new String[MenuKey.getMenuKeySymbolCount()+1];
+ //menuKeys[0] = "None";
for (int i = 0; i < MenuKey.getMenuKeySymbolCount(); i++)
menuKeys[i] = MenuKey.getKeyText(MenuKey.getMenuKeySymbols()[i]);
- menuKey = new JComboBox(menuKeys);
+ //menuKeys[i+1] = MenuKey.getKeyText(MenuKey.getMenuKeySymbols()[i]);
+ menuKeyChoice = new JComboBox(menuKeys);
- inputPanel.add(viewOnly,
+ inputPanel.add(viewOnlyCheckbox,
new GridBagConstraints(0, 0,
REMAINDER, 1,
HEAVY, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
- inputPanel.add(acceptClipboard,
+ inputPanel.add(acceptClipboardCheckbox,
new GridBagConstraints(0, 1,
REMAINDER, 1,
HEAVY, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
- inputPanel.add(sendClipboard,
+ inputPanel.add(sendClipboardCheckbox,
new GridBagConstraints(0, 2,
REMAINDER, 1,
HEAVY, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 0, 0),
NONE, NONE));
- inputPanel.add(menuKey,
+ inputPanel.add(menuKeyChoice,
new GridBagConstraints(1, 3,
1, 1,
HEAVY, LIGHT,
LINE_START, BOTH,
new Insets(0, 0, 0, 0),
NONE, NONE));
+ return inputPanel;
+ }
- // Screen tab
+ private JPanel createScreenPanel() {
JPanel ScreenPanel = new JPanel(new GridBagLayout());
ScreenPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
- desktopSize = new JCheckBox("Resize remote session on connect");
- desktopSize.setEnabled(!cc.viewer.embed.getValue() &&
- (cc.viewer.desktopSize.getValue() != null));
- desktopWidth = new IntegerTextField(5);
- desktopWidth.setEnabled(desktopSize.isSelected());
- desktopHeight = new IntegerTextField(5);
- desktopHeight.setEnabled(desktopSize.isSelected());
+ desktopSizeCheckbox = new JCheckBox("Resize remote session on connect");
+ desktopSizeCheckbox.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ handleDesktopSize();
+ }
+ });
+ desktopWidthInput = new IntegerTextField(5);
+ desktopHeightInput = new IntegerTextField(5);
JPanel desktopSizePanel =
new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0));
- desktopSizePanel.add(desktopWidth);
+ desktopSizePanel.add(desktopWidthInput);
desktopSizePanel.add(new JLabel(" x "));
- desktopSizePanel.add(desktopHeight);
- fullScreen = new JCheckBox("Full-screen mode");
- fullScreen.setEnabled(!cc.viewer.embed.getValue());
- fullScreenAllMonitors =
+ desktopSizePanel.add(desktopHeightInput);
+ fullScreenCheckbox = new JCheckBox("Full-screen mode");
+ fullScreenAllMonitorsCheckbox =
new JCheckBox("Enable full-screen mode over all monitors");
- fullScreenAllMonitors.setEnabled(!cc.viewer.embed.getValue());
JLabel scalingFactorLabel = new JLabel("Scaling Factor");
Object[] scalingFactors = {
"Auto", "Fixed Aspect Ratio", "50%", "75%", "95%", "100%", "105%",
"125%", "150%", "175%", "200%", "250%", "300%", "350%", "400%" };
- scalingFactor = new MyJComboBox(scalingFactors);
- scalingFactor.setEditable(true);
- scalingFactor.setEnabled(!cc.viewer.embed.getValue());
- ScreenPanel.add(desktopSize,
+ scalingFactorInput = new MyJComboBox(scalingFactors);
+ scalingFactorInput.setEditable(true);
+ ScreenPanel.add(desktopSizeCheckbox,
new GridBagConstraints(0, 0,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 0, 0),
NONE, NONE));
- indent = getButtonLabelInset(desktopSize);
+ int indent = getButtonLabelInset(desktopSizeCheckbox);
ScreenPanel.add(desktopSizePanel,
new GridBagConstraints(0, 1,
REMAINDER, 1,
LINE_START, NONE,
new Insets(0, indent, 0, 0),
NONE, NONE));
- ScreenPanel.add(fullScreen,
+ ScreenPanel.add(fullScreenCheckbox,
new GridBagConstraints(0, 2,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
- indent = getButtonLabelInset(fullScreen);
- ScreenPanel.add(fullScreenAllMonitors,
+ indent = getButtonLabelInset(fullScreenCheckbox);
+ ScreenPanel.add(fullScreenAllMonitorsCheckbox,
new GridBagConstraints(0, 3,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
- ScreenPanel.add(scalingFactor,
+ ScreenPanel.add(scalingFactorInput,
new GridBagConstraints(1, 4,
1, 1,
HEAVY, LIGHT,
LINE_START, BOTH,
new Insets(0, 0, 0, 0),
NONE, NONE));
+ return ScreenPanel;
+ }
- // Misc tab
+ private JPanel createMiscPanel() {
JPanel MiscPanel = new JPanel(new GridBagLayout());
MiscPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
- shared =
- new JCheckBox("Shared connection (do not disconnect other viewers)");
- useLocalCursor = new JCheckBox("Render cursor locally");
- acceptBell = new JCheckBox("Beep when requested by the server");
- MiscPanel.add(shared,
+ sharedCheckbox =
+ new JCheckBox("Shared (don't disconnect other viewers)");
+ localCursorCheckbox = new JCheckBox("Render cursor locally");
+ acceptBellCheckbox = new JCheckBox("Beep when requested by the server");
+ MiscPanel.add(sharedCheckbox,
new GridBagConstraints(0, 0,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
- MiscPanel.add(useLocalCursor,
+ MiscPanel.add(localCursorCheckbox,
new GridBagConstraints(0, 1,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
- MiscPanel.add(acceptBell,
+ MiscPanel.add(acceptBellCheckbox,
new GridBagConstraints(0, 2,
1, 1,
LIGHT, LIGHT,
LINE_START, BOTH,
new Insets(0, 0, 0, 0),
NONE, NONE));
+ return MiscPanel;
+ }
- // SSH tab
+ private JPanel createSshPanel() {
JPanel sshPanel = new JPanel(new GridBagLayout());
sshPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
- sshTunnel = new JCheckBox("Tunnel VNC over SSH");
+ ButtonGroup sshArgsGroup = new ButtonGroup();
+ tunnelCheckbox = new JCheckBox("Tunnel VNC over SSH");
+ tunnelCheckbox.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ handleTunnel();
+ }
+ });
JPanel tunnelPanel = new JPanel(new GridBagLayout());
- sshUseGateway = new JCheckBox("Use SSH gateway");
+ viaCheckbox = new JCheckBox("Use SSH gateway");
+ viaCheckbox.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ handleVia();
+ }
+ });
JLabel sshUserLabel = new JLabel("Username");
- sshUser = new JTextField();
+ viaUserInput = new JTextField();
JLabel sshUserAtLabel = new JLabel("@");
JLabel sshHostLabel = new JLabel("Hostname (or IP address)");
- sshHost = new JTextField("");
+ viaHostInput = new JTextField("");
JLabel sshPortLabel = new JLabel("Port");
- sshPort = new IntegerTextField(5);
+ viaPortInput = new IntegerTextField(5);
- sshUseExt = new JCheckBox("Use external SSH client");
- sshClient = new JTextField();
- sshClient.setName(Configuration.getParam("extSSHClient").getName());
- sshClientBrowser = new JButton("Browse");
+ extSSHCheckbox = new JCheckBox("Use external SSH client");
+ extSSHCheckbox.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ handleExtSSH();
+ }
+ });
+ sshClientInput = new JTextField();
+ sshClientChooser = new JButton("Browse");
+ sshClientChooser.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ JComponent c = ((JButton)e.getSource()).getRootPane();
+ File dflt = new File(extSSHClient.getValueStr());
+ File f = showChooser("Path to external SSH client", dflt, c);
+ if (f != null && f.exists() && f.isFile() && f.canExecute())
+ sshClientInput.setText(f.getAbsolutePath());
+ }
+ });
JLabel sshConfigLabel = new JLabel("SSH config file");
- sshConfig = new JTextField();
- sshConfig.setName(Configuration.getParam("sshConfig").getName());
- sshConfigBrowser = new JButton("Browse");
+ sshConfigInput = new JTextField();
+ sshConfigChooser = new JButton("Browse");
+ sshConfigChooser.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ JComponent c = ((JButton)e.getSource()).getRootPane();
+ File dflt = new File(sshConfig.getValueStr());
+ File f = showChooser("Path to OpenSSH client config file", dflt, c);
+ if (f != null && f.exists() && f.isFile() && f.canRead())
+ sshConfigInput.setText(f.getAbsolutePath());
+ }
+ });
JLabel sshKeyFileLabel = new JLabel("SSH identity file");
- sshKeyFile = new JTextField();
- sshKeyFile.setName(Configuration.getParam("sshKeyFile").getName());
- sshKeyFileBrowser = new JButton("Browse");
+ sshKeyFileInput = new JTextField();
+ sshKeyFileChooser = new JButton("Browse");
+ sshKeyFileChooser.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ JComponent c = ((JButton)e.getSource()).getRootPane();
+ File f = showChooser("Path to SSH key file", null, c);
+ if (f != null && f.exists() && f.isFile() && f.canRead())
+ sshKeyFileInput.setText(f.getAbsolutePath());
+ }
+ });
JPanel sshArgsPanel = new JPanel(new GridBagLayout());
JLabel sshArgsLabel = new JLabel("Arguments:");
- sshArgsDefault =
- new GroupedJRadioButton("Default", sshArgsGroup, sshArgsPanel);
- sshArgsCustom =
- new GroupedJRadioButton("Custom", sshArgsGroup, sshArgsPanel);
- sshArguments = new JTextField();
+ sshArgsDefaultButton = new GroupedJRadioButton("Default", sshArgsGroup, sshArgsPanel);
+ sshArgsDefaultButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ sshArgsInput.setEnabled(sshArgsCustomButton.isSelected());
+ }
+ });
+ sshArgsCustomButton = new GroupedJRadioButton("Custom", sshArgsGroup, sshArgsPanel);
+ sshArgsCustomButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ sshArgsInput.setEnabled(sshArgsCustomButton.isSelected());
+ }
+ });
+ sshArgsInput = new JTextField();
JPanel gatewayPanel = new JPanel(new GridBagLayout());
- gatewayPanel.add(sshUseGateway,
+ gatewayPanel.add(viaCheckbox,
new GridBagConstraints(0, 0,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
- indent = getButtonLabelInset(sshUseGateway);
+ int indent = getButtonLabelInset(viaCheckbox);
gatewayPanel.add(sshUserLabel,
new GridBagConstraints(0, 1,
1, 1,
LINE_START, HORIZONTAL,
new Insets(0, 5, 4, 0),
NONE, NONE));
- gatewayPanel.add(sshUser,
+ gatewayPanel.add(viaUserInput,
new GridBagConstraints(0, 2,
1, 1,
LIGHT, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 2, 0, 2),
NONE, NONE));
- gatewayPanel.add(sshHost,
+ gatewayPanel.add(viaHostInput,
new GridBagConstraints(2, 2,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 0, 0, 0),
NONE, NONE));
- gatewayPanel.add(sshPort,
+ gatewayPanel.add(viaPortInput,
new GridBagConstraints(3, 2,
1, 1,
LIGHT, LIGHT,
NONE, NONE));
JPanel clientPanel = new JPanel(new GridBagLayout());
- clientPanel.add(sshUseExt,
+ clientPanel.add(extSSHCheckbox,
new GridBagConstraints(0, 0,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 0, 0),
NONE, NONE));
- clientPanel.add(sshClient,
+ clientPanel.add(sshClientInput,
new GridBagConstraints(1, 0,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 0, 0),
NONE, NONE));
- clientPanel.add(sshClientBrowser,
+ clientPanel.add(sshClientChooser,
new GridBagConstraints(2, 0,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 0, 0),
NONE, NONE));
- sshArgsPanel.add(sshArgsDefault,
+ sshArgsPanel.add(sshArgsDefaultButton,
new GridBagConstraints(1, 1,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 5, 0, 0),
NONE, NONE));
- sshArgsPanel.add(sshArgsCustom,
+ sshArgsPanel.add(sshArgsCustomButton,
new GridBagConstraints(2, 1,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 5, 0, 0),
NONE, NONE));
- sshArgsPanel.add(sshArguments,
+ sshArgsPanel.add(sshArgsInput,
new GridBagConstraints(3, 1,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 0, 0),
NONE, NONE));
- indent = getButtonLabelInset(sshUseExt);
+ indent = getButtonLabelInset(extSSHCheckbox);
clientPanel.add(sshArgsPanel,
new GridBagConstraints(0, 1,
REMAINDER, 1,
NONE, NONE));
JPanel opensshPanel = new JPanel(new GridBagLayout());
- opensshPanel.setBorder(BorderFactory.createTitledBorder("Embedded SSH client configuration"));
+ TitledBorder border =
+ BorderFactory.createTitledBorder("Embedded SSH client configuration");
+ opensshPanel.setBorder(border);
opensshPanel.add(sshConfigLabel,
new GridBagConstraints(0, 0,
1, 1,
LINE_START, NONE,
new Insets(0, 0, 5, 0),
NONE, NONE));
- opensshPanel.add(sshConfig,
+ opensshPanel.add(sshConfigInput,
new GridBagConstraints(1, 0,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 5, 0),
NONE, NONE));
- opensshPanel.add(sshConfigBrowser,
+ opensshPanel.add(sshConfigChooser,
new GridBagConstraints(2, 0,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 0, 0),
NONE, NONE));
- opensshPanel.add(sshKeyFile,
+ opensshPanel.add(sshKeyFileInput,
new GridBagConstraints(1, 1,
1, 1,
HEAVY, LIGHT,
LINE_START, HORIZONTAL,
new Insets(0, 5, 0, 0),
NONE, NONE));
- opensshPanel.add(sshKeyFileBrowser,
+ opensshPanel.add(sshKeyFileChooser,
new GridBagConstraints(2, 1,
1, 1,
LIGHT, LIGHT,
new Insets(0, 0, 0, 0),
NONE, NONE));
- sshPanel.add(sshTunnel,
+ sshPanel.add(tunnelCheckbox,
new GridBagConstraints(0, 0,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
- indent = getButtonLabelInset(sshTunnel);
+ indent = getButtonLabelInset(tunnelCheckbox);
sshPanel.add(tunnelPanel,
new GridBagConstraints(0, 2,
REMAINDER, 1,
LINE_START, BOTH,
new Insets(0, 0, 0, 0),
NONE, NONE));
+ return sshPanel;
+ }
- // load/save tab
- JPanel loadSavePanel = new JPanel(new GridBagLayout());
- loadSavePanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
- JPanel configPanel = new JPanel(new GridBagLayout());
- configPanel.
- setBorder(BorderFactory.createTitledBorder("Configuration File"));
- cfLoadButton = new JButton("Load");
- cfSaveAsButton = new JButton("Save As...");
- configPanel.add(cfLoadButton,
- new GridBagConstraints(0, 0,
- 1, 1,
- HEAVY, LIGHT,
- CENTER, HORIZONTAL,
- new Insets(0, 0, 5, 0),
- NONE, NONE));
- configPanel.add(cfSaveAsButton,
- new GridBagConstraints(0, 1,
- 1, 1,
- HEAVY, HEAVY,
- CENTER, HORIZONTAL,
- new Insets(0, 0, 0, 0),
- NONE, NONE));
+ private void handleAutoselect()
+ {
+ ButtonGroup[] groups = { encodingGroup, colorlevelGroup };
+ for (ButtonGroup grp : groups) {
+ Enumeration<AbstractButton> elems = grp.getElements();
+ while (elems.hasMoreElements())
+ elems.nextElement().setEnabled(!autoselectCheckbox.isSelected());
+ }
- JPanel defaultsPanel = new JPanel(new GridBagLayout());
- defaultsPanel.setBorder(BorderFactory.createTitledBorder("Defaults"));
- defClearButton = new JButton("Clear");
- defReloadButton = new JButton("Reload");
- defSaveButton = new JButton("Save");
- defaultsPanel.add(defClearButton,
- new GridBagConstraints(0, 0,
- 1, 1,
- HEAVY, LIGHT,
- CENTER, HORIZONTAL,
- new Insets(0, 0, 5, 0),
- NONE, NONE));
- defaultsPanel.add(defReloadButton,
- new GridBagConstraints(0, 1,
- 1, 1,
- HEAVY, LIGHT,
- CENTER, HORIZONTAL,
- new Insets(0, 0, 5, 0),
- NONE, NONE));
- defaultsPanel.add(defSaveButton,
- new GridBagConstraints(0, 2,
- 1, 1,
- HEAVY, HEAVY,
- CENTER, HORIZONTAL,
- new Insets(0, 0, 0, 0),
- NONE, NONE));
-
- loadSavePanel.add(configPanel,
- new GridBagConstraints(0, 0,
- 1, 1,
- HEAVY, LIGHT,
- PAGE_START, HORIZONTAL,
- new Insets(0, 0, 0, 0),
- NONE, NONE));
- loadSavePanel.add(Box.createRigidArea(new Dimension(5, 0)),
- new GridBagConstraints(1, 1,
- 1, 1,
- LIGHT, LIGHT,
- LINE_START, NONE,
- new Insets(0, 0, 0, 0),
- NONE, NONE));
- loadSavePanel.add(defaultsPanel,
- new GridBagConstraints(2, 0,
- 1, 1,
- HEAVY, LIGHT,
- PAGE_START, HORIZONTAL,
- new Insets(0, 0, 0, 0),
- NONE, NONE));
- loadSavePanel.add(Box.createRigidArea(new Dimension(5, 0)),
- new GridBagConstraints(0, 1,
- REMAINDER, REMAINDER,
- HEAVY, HEAVY,
- LINE_START, BOTH,
- new Insets(0, 0, 0, 0),
- NONE, NONE));
+ // JPEG setting is also affected by autoselection
+ jpegCheckbox.setEnabled(!autoselectCheckbox.isSelected());
+ handleJpeg();
+ }
- // tabPane
- tabPane.addTab("Compression", FormatPanel);
- tabPane.addTab("Security", SecPanel);
- tabPane.addTab("Input", inputPanel);
- tabPane.addTab("Screen", ScreenPanel);
- tabPane.addTab("Misc", MiscPanel);
- tabPane.addTab("SSH", sshPanel);
- tabPane.addTab("Load / Save", loadSavePanel);
- tabPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
- // Resize the tabPane if necessary to prevent scrolling
- Insets tpi =
- (Insets)UIManager.get("TabbedPane:TabbedPaneTabArea.contentMargins");
- int minWidth = tpi.left + tpi.right;
- for (int i = 0; i < tabPane.getTabCount(); i++)
- minWidth += tabPane.getBoundsAt(i).width;
- int minHeight = tabPane.getPreferredSize().height;
- if (tabPane.getPreferredSize().width < minWidth)
- tabPane.setPreferredSize(new Dimension(minWidth, minHeight));
+ private void handleCompression()
+ {
+ compressionInput.setEnabled(compressionCheckbox.isSelected());
+ }
- // button pane
- okButton = new JButton("OK");
- cancelButton = new JButton("Cancel");
+ private void handleJpeg()
+ {
+ if (jpegCheckbox.isSelected() &&
+ !autoselectCheckbox.isSelected())
+ jpegInput.setEnabled(true);
+ else
+ jpegInput.setEnabled(false);
+ }
- JPanel buttonPane = new JPanel(new GridLayout(1, 5, 10, 10));
- buttonPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 5));
- buttonPane.add(Box.createRigidArea(new Dimension()));
- buttonPane.add(Box.createRigidArea(new Dimension()));
- buttonPane.add(Box.createRigidArea(new Dimension()));
- buttonPane.add(okButton);
- buttonPane.add(cancelButton);
+ private void handleX509()
+ {
+ caInput.setEnabled(encX509Checkbox.isSelected());
+ caChooser.setEnabled(encX509Checkbox.isSelected());
+ crlInput.setEnabled(encX509Checkbox.isSelected());
+ crlChooser.setEnabled(encX509Checkbox.isSelected());
+ }
- this.add(tabPane);
- this.add(buttonPane);
- addListeners(this);
- pack();
+ private void handleSendLocalUsername()
+ {
+ boolean value = authIdentCheckbox.isSelected() ||
+ authPlainCheckbox.isSelected();
+ sendLocalUsernameCheckbox.setEnabled(value);
}
- public void initDialog() {
- if (cc != null) cc.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()));
- sshArguments.setEnabled(sshTunnel.isSelected() &&
- (sshUseExt.isSelected() && sshArgsCustom.isSelected()));
+ private void handleDesktopSize()
+ {
+ desktopWidthInput.setEnabled(desktopSizeCheckbox.isSelected());
+ desktopHeightInput.setEnabled(desktopSizeCheckbox.isSelected());
}
- private void updatePreferences() {
- if (autoSelect.isSelected()) {
- UserPreferences.set("global", "AutoSelect", true);
- } else {
- UserPreferences.set("global", "AutoSelect", false);
- if (zrle.isSelected()) {
- UserPreferences.set("global", "PreferredEncoding", "ZRLE");
- } else if (hextile.isSelected()) {
- UserPreferences.set("global", "PreferredEncoding", "hextile");
- } else if (tight.isSelected()) {
- UserPreferences.set("global", "PreferredEncoding", "Tight");
- } else if (raw.isSelected()) {
- UserPreferences.set("global", "PreferredEncoding", "raw");
- }
- }
- if (fullColour.isSelected()) {
- UserPreferences.set("global", "FullColour", true);
- } else {
- UserPreferences.set("global", "FullColour", false);
- if (mediumColour.isSelected()) {
- UserPreferences.set("global", "LowColorLevel", 2);
- } else if (lowColour.isSelected()) {
- UserPreferences.set("global", "LowColorLevel", 1);
- } else if (veryLowColour.isSelected()) {
- UserPreferences.set("global", "LowColorLevel", 0);
- }
- }
- UserPreferences.set("global", "NoJPEG", !noJpeg.isSelected());
- UserPreferences.set("global",
- "QualityLevel", (Integer)qualityLevel.getSelectedItem());
- UserPreferences.set("global",
- "CustomCompressLevel", customCompressLevel.isSelected());
- UserPreferences.set("global",
- "CompressLevel", (Integer)compressLevel.getSelectedItem());
- UserPreferences.set("global", "ViewOnly", viewOnly.isSelected());
- UserPreferences.set("global",
- "AcceptClipboard", acceptClipboard.isSelected());
- UserPreferences.set("global", "SendClipboard", sendClipboard.isSelected());
- String menuKeyStr =
- MenuKey.getMenuKeySymbols()[menuKey.getSelectedIndex()].name;
- UserPreferences.set("global", "MenuKey", menuKeyStr);
- String desktopSizeString =
- desktopSize.isSelected() ?
- desktopWidth.getText() + "x" + desktopHeight.getText() : "";
- UserPreferences.set("global", "DesktopSize", desktopSizeString);
- UserPreferences.set("global", "FullScreen", fullScreen.isSelected());
- UserPreferences.set("global",
- "FullScreenAllMonitors", fullScreenAllMonitors.isSelected());
- UserPreferences.set("global", "Shared", shared.isSelected());
- UserPreferences.set("global",
- "UseLocalCursor", useLocalCursor.isSelected());
- UserPreferences.set("global", "AcceptBell", acceptBell.isSelected());
- String scaleString = scalingFactor.getSelectedItem().toString();
- if (scaleString.equalsIgnoreCase("Auto")) {
- UserPreferences.set("global", "ScalingFactor", "Auto");
- } else if(scaleString.equalsIgnoreCase("Fixed Aspect Ratio")) {
- UserPreferences.set("global", "ScalingFactor", "FixedRatio");
+ private void handleTunnel()
+ {
+ viaCheckbox.setEnabled(tunnelCheckbox.isSelected());
+ extSSHCheckbox.setEnabled(tunnelCheckbox.isSelected());
+ if (tunnelCheckbox.isSelected()) {
+ JComponent[] components = { viaUserInput, viaHostInput, viaPortInput };
+ for (JComponent c : components)
+ c.setEnabled(viaCheckbox.isSelected());
+ sshClientInput.setEnabled(extSSHCheckbox.isSelected());
+ sshClientChooser.setEnabled(extSSHCheckbox.isSelected());
+ sshArgsDefaultButton.setEnabled(extSSHCheckbox.isSelected());
+ sshArgsCustomButton.setEnabled(extSSHCheckbox.isSelected());
+ sshArgsInput.setEnabled(extSSHCheckbox.isSelected());
+ sshConfigInput.setEnabled(!extSSHCheckbox.isSelected());
+ sshConfigChooser.setEnabled(!extSSHCheckbox.isSelected());
+ sshKeyFileInput.setEnabled(!extSSHCheckbox.isSelected());
+ sshKeyFileChooser.setEnabled(!extSSHCheckbox.isSelected());
} else {
- scaleString=scaleString.substring(0, scaleString.length()-1);
- UserPreferences.set("global", "ScalingFactor", scaleString);
- }
- UserPreferences.set("viewer", "secVeNCrypt", secVeNCrypt.isSelected());
- UserPreferences.set("viewer", "encNone", encNone.isSelected());
- UserPreferences.set("viewer", "encTLS", encTLS.isSelected());
- UserPreferences.set("viewer", "encX509", encX509.isSelected());
- UserPreferences.set("viewer", "secNone", secNone.isSelected());
- UserPreferences.set("viewer", "secVnc", secVnc.isSelected());
- UserPreferences.set("viewer", "secPlain", secPlain.isSelected());
- UserPreferences.set("viewer", "secIdent", secIdent.isSelected());
- UserPreferences.set("global",
- "SendLocalUsername", sendLocalUsername.isSelected());
- if (!CSecurityTLS.x509ca.getValueStr().equals(""))
- UserPreferences.set("viewer", "x509ca",
- CSecurityTLS.x509ca.getValueStr());
- if (!CSecurityTLS.x509crl.getValueStr().equals(""))
- UserPreferences.set("viewer", "x509crl",
- CSecurityTLS.x509crl.getValueStr());
- UserPreferences.set("global", "Tunnel", sshTunnel.isSelected());
- if (sshUseGateway.isSelected()) {
- String via = sshUser.getText()+"@"+sshHost.getText()+":"+sshPort.getText();
- UserPreferences.set("global", "Via", via);
+ JComponent[] components = {
+ viaUserInput, viaHostInput, viaPortInput, sshClientInput,
+ sshClientChooser, sshArgsDefaultButton, sshArgsCustomButton,
+ sshArgsInput, sshConfigInput, sshConfigChooser, sshKeyFileInput,
+ sshKeyFileChooser, };
+ for (JComponent c : components)
+ c.setEnabled(false);
}
- if (sshUseExt.isSelected()) {
- UserPreferences.set("global", "extSSH", sshUseExt.isSelected());
- UserPreferences.set("global", "extSSHClient", sshClient.getText());
- if (!sshArguments.getText().isEmpty())
- UserPreferences.set("global", "extSSHArgs", sshArguments.getText());
- }
- UserPreferences.set("global", "SSHConfig", sshConfig.getText());
- UserPreferences.set("global", "SSHKeyFile", sshKeyFile.getText());
}
- private void restorePreferences() {
- autoSelect.setSelected(UserPreferences.getBool("global", "AutoSelect"));
- if (!autoSelect.isSelected()) {
- if (UserPreferences.getBool("global", "FullColour")) {
- fullColour.setSelected(true);
- } else {
- switch (UserPreferences.getInt("global", "LowColorLevel")) {
- case 2:
- mediumColour.setSelected(true);
- break;
- case 1:
- lowColour.setSelected(true);
- break;
- case 0:
- veryLowColour.setSelected(true);
- break;
- }
- }
- String encoding = UserPreferences.get("global", "PreferredEncoding");
- if (encoding != null) {
- switch (Encodings.encodingNum(encoding)) {
- case Encodings.encodingZRLE:
- zrle.setSelected(true);
- break;
- case Encodings.encodingHextile:
- hextile.setSelected(true);
- break;
- case Encodings.encodingRaw:
- raw.setSelected(true);
- break;
- default:
- tight.setSelected(true);
- }
- }
+ private void handleVia()
+ {
+ if (tunnelCheckbox.isSelected()) {
+ viaUserInput.setEnabled(viaCheckbox.isSelected());
+ viaHostInput.setEnabled(viaCheckbox.isSelected());
+ viaPortInput.setEnabled(viaCheckbox.isSelected());
}
- noJpeg.setSelected(!UserPreferences.getBool("global", "NoJPEG"));
- qualityLevel.setSelectedItem(UserPreferences.getInt("global",
- "QualityLevel"));
- customCompressLevel.setSelected(UserPreferences.getBool("global",
- "CustomCompressLevel"));
- compressLevel.setSelectedItem(UserPreferences.getInt("global",
- "CompressLevel"));
- viewOnly.setSelected(UserPreferences.getBool("global", "ViewOnly"));
- acceptClipboard.setSelected(UserPreferences.getBool("global",
- "AcceptClipboard"));
- sendClipboard.setSelected(UserPreferences.getBool("global",
- "SendClipboard"));
- menuKey.setSelectedItem(UserPreferences.get("global", "MenuKey"));
- desktopSize.setSelected(!UserPreferences.get("global", "DesktopSize").isEmpty());
- if (desktopSize.isSelected()) {
- String desktopSizeString = UserPreferences.get("global", "DesktopSize");
- desktopWidth.setText(desktopSizeString.split("x")[0]);
- desktopHeight.setText(desktopSizeString.split("x")[1]);
- }
- fullScreen.setSelected(UserPreferences.getBool("global", "FullScreen"));
- fullScreenAllMonitors.setSelected(UserPreferences.getBool("global",
- "FullScreenAllMonitors"));
- if (shared.isEnabled())
- shared.setSelected(UserPreferences.getBool("global", "Shared"));
- useLocalCursor.setSelected(UserPreferences.getBool("global",
- "UseLocalCursor"));
- acceptBell.setSelected(UserPreferences.getBool("global", "AcceptBell"));
- String scaleString = UserPreferences.get("global", "ScalingFactor");
- if (scaleString != null) {
- if (scaleString.equalsIgnoreCase("Auto")) {
- scalingFactor.setSelectedItem("Auto");
- } else if (scaleString.equalsIgnoreCase("FixedRatio")) {
- scalingFactor.setSelectedItem("Fixed Aspect Ratio");
- } else {
- scalingFactor.setSelectedItem(scaleString+"%");
- }
- }
- if (secVeNCrypt.isEnabled()) {
- secVeNCrypt.setSelected(UserPreferences.getBool("viewer",
- "secVeNCrypt", true));
- if (secVeNCrypt.isSelected()) {
- encNone.setSelected(UserPreferences.getBool("viewer", "encNone", true));
- encTLS.setSelected(UserPreferences.getBool("viewer", "encTLS", true));
- encX509.setSelected(UserPreferences.getBool("viewer", "encX509", true));
- secPlain.setSelected(UserPreferences.getBool("viewer", "secPlain", true));
- secIdent.setSelected(UserPreferences.getBool("viewer", "secIdent", true));
- sendLocalUsername.setSelected(UserPreferences.getBool("global",
- "SendLocalUsername"));
- }
- }
- if (secNone.isEnabled())
- secNone.setSelected(UserPreferences.getBool("viewer", "secNone", true));
- if (secVnc.isEnabled())
- secVnc.setSelected(UserPreferences.getBool("viewer", "secVnc", true));
- sshTunnel.setSelected(UserPreferences.getBool("global", "Tunnel"));
- sshUseGateway.setSelected(UserPreferences.get("global", "Via") != null);
- if (sshUseGateway.isSelected())
- cc.viewer.via.setParam(UserPreferences.get("global", "Via"));
- sshUser.setText(Tunnel.getSshUser(cc));
- sshHost.setText(Tunnel.getSshHost(cc));
- sshPort.setText(Integer.toString(Tunnel.getSshPort(cc)));
- sshUseExt.setSelected(UserPreferences.getBool("global", "extSSH"));
- File f = new File(UserPreferences.get("global", "extSSHClient"));
- if (f.exists() && f.canExecute())
- sshClient.setText(f.getAbsolutePath());
- sshArguments.setText(UserPreferences.get("global", "extSSHArgs"));
- if (sshArguments.getText().isEmpty())
- sshArgsDefault.setSelected(true);
- else
- sshArgsCustom.setSelected(true);
- f = new File(UserPreferences.get("global", "SSHConfig"));
- if (f.exists() && f.canRead())
- sshConfig.setText(f.getAbsolutePath());
- if (UserPreferences.get("global", "SSHKeyFile") != null) {
- f = new File(UserPreferences.get("global", "SSHKeyFile"));
- if (f.exists() && f.canRead())
- sshKeyFile.setText(f.getAbsolutePath());
- } else {
- sshKeyFile.setText(Tunnel.getSshKeyFile(cc));
- }
- sshUseGateway.setEnabled(sshTunnel.isSelected());
- sshUser.setEnabled(sshTunnel.isSelected() &&
- sshUseGateway.isEnabled() &&
- sshUseGateway.isSelected());
- sshHost.setEnabled(sshTunnel.isSelected() &&
- sshUseGateway.isEnabled() &&
- sshUseGateway.isSelected());
- sshPort.setEnabled(sshTunnel.isSelected() &&
- sshUseGateway.isEnabled() &&
- sshUseGateway.isSelected());
- sshUseExt.setEnabled(sshTunnel.isSelected());
- sshClient.setEnabled(sshTunnel.isSelected() &&
- sshUseExt.isEnabled());
- sshClientBrowser.setEnabled(sshTunnel.isSelected() &&
- sshUseExt.isEnabled() &&
- sshUseExt.isSelected());
- sshArgsDefault.setEnabled(sshTunnel.isSelected() &&
- sshUseExt.isEnabled() &&
- sshUseExt.isSelected());
- sshArgsCustom.setEnabled(sshTunnel.isSelected() &&
- sshUseExt.isEnabled() &&
- sshUseExt.isSelected());
- sshArguments.setEnabled(sshTunnel.isSelected() &&
- sshUseExt.isEnabled() &&
- sshUseExt.isSelected() &&
- sshArgsCustom.isSelected());
- sshConfig.setEnabled(sshTunnel.isSelected() &&
- sshUseExt.isEnabled() &&
- !sshUseExt.isSelected());
- sshConfigBrowser.setEnabled(sshTunnel.isSelected() &&
- sshUseExt.isEnabled() &&
- !sshUseExt.isSelected());
- sshKeyFile.setEnabled(sshTunnel.isSelected() &&
- sshUseExt.isEnabled() &&
- !sshUseExt.isSelected());
- sshKeyFileBrowser.setEnabled(sshTunnel.isSelected() &&
- sshUseExt.isEnabled() &&
- !sshUseExt.isSelected());
}
- public void endDialog() {
- super.endDialog();
- if (cc.viewport != null && cc.viewport.isVisible()) {
- cc.viewport.toFront();
- cc.viewport.requestFocus();
+ private void handleExtSSH()
+ {
+ if (tunnelCheckbox.isSelected()) {
+ sshClientInput.setEnabled(extSSHCheckbox.isSelected());
+ sshClientChooser.setEnabled(extSSHCheckbox.isSelected());
+ sshArgsDefaultButton.setEnabled(extSSHCheckbox.isSelected());
+ sshArgsCustomButton.setEnabled(extSSHCheckbox.isSelected());
+ sshConfigInput.setEnabled(!extSSHCheckbox.isSelected());
+ sshConfigChooser.setEnabled(!extSSHCheckbox.isSelected());
+ sshKeyFileInput.setEnabled(!extSSHCheckbox.isSelected());
+ sshKeyFileChooser.setEnabled(!extSSHCheckbox.isSelected());
+ if (sshArgsCustomButton.isSelected())
+ sshArgsInput.setEnabled(extSSHCheckbox.isSelected());
+ else
+ sshArgsInput.setEnabled(false);
}
}
- public void actionPerformed(ActionEvent e) {
- Object s = e.getSource();
- if (s instanceof JButton) {
- JButton button = (JButton)s;
- if (button == okButton) {
- JTextField[] fields =
- { x509ca, x509crl, sshClient, sshConfig, sshKeyFile };
- for (JTextField field : fields) {
- if (field.getText() != null && !field.getText().equals("")) {
- File f = new File(field.getText());
- if (!f.exists() || !f.canRead()) {
- String msg = new String("The file "+f.getAbsolutePath()+
- " specified for option "+field.getName()+
- " does not exist or cannot be read. Please"+
- " correct before proceeding.");
- JOptionPane.showMessageDialog(this, msg, "WARNING",
- JOptionPane.WARNING_MESSAGE);
- return;
- }
- }
- }
- if (cc != null) cc.getOptions();
- endDialog();
- } else if (button == cancelButton) {
- endDialog();
- } else if (button == cfLoadButton) {
- JFileChooser fc = new JFileChooser();
- fc.setDialogTitle("Path to configuration file");
- fc.setApproveButtonText("OK");
- fc.setFileHidingEnabled(false);
- int ret = fc.showOpenDialog(this);
- if (ret == JFileChooser.APPROVE_OPTION) {
- String filename = fc.getSelectedFile().toString();
- if (filename != null)
- Configuration.load(filename);
- cc.setOptions();
- }
- } else if (button == cfSaveAsButton) {
- JFileChooser fc = new JFileChooser();
- fc.setDialogTitle("Save current configuration as:");
- fc.setApproveButtonText("OK");
- fc.setFileHidingEnabled(false);
- int ret = fc.showOpenDialog(this);
- if (ret == JFileChooser.APPROVE_OPTION) {
- String filename = fc.getSelectedFile().toString();
- if (filename != null)
- Configuration.save(filename);
- }
- } else if (button == defSaveButton) {
- updatePreferences();
- UserPreferences.save();
- } else if (button == defReloadButton) {
- restorePreferences();
- } else if (button == defClearButton) {
- UserPreferences.clear();
- cc.setOptions();
- } else if (button == caButton) {
- JFileChooser fc =
- new JFileChooser(new File(CSecurityTLS.getDefaultCA()));
- fc.setDialogTitle("Path to X509 CA certificate");
- fc.setApproveButtonText("OK");
- fc.setFileHidingEnabled(false);
- int ret = fc.showOpenDialog(this);
- if (ret == JFileChooser.APPROVE_OPTION)
- x509ca.setText(fc.getSelectedFile().toString());
- } else if (button == crlButton) {
- JFileChooser fc =
- new JFileChooser(new File(CSecurityTLS.getDefaultCRL()));
- fc.setDialogTitle("Path to X509 CRL file");
- fc.setApproveButtonText("OK");
- fc.setFileHidingEnabled(false);
- int ret = fc.showOpenDialog(this);
- if (ret == JFileChooser.APPROVE_OPTION)
- x509crl.setText(fc.getSelectedFile().toString());
- } else if (button == sshClientBrowser) {
- JFileChooser fc = new JFileChooser();
- fc.setDialogTitle("Path to external SSH client");
- fc.setApproveButtonText("OK");
- fc.setFileHidingEnabled(false);
- int ret = fc.showOpenDialog(this);
- if (ret == JFileChooser.APPROVE_OPTION)
- sshClient.setText(fc.getSelectedFile().toString());
- } else if (button == sshConfigBrowser) {
- JFileChooser fc = new JFileChooser();
- fc.setDialogTitle("Path to OpenSSH client config file");
- fc.setApproveButtonText("OK");
- fc.setFileHidingEnabled(false);
- int ret = fc.showOpenDialog(this);
- if (ret == JFileChooser.APPROVE_OPTION)
- sshConfig.setText(fc.getSelectedFile().toString());
- } else if (button == sshKeyFileBrowser) {
- JFileChooser fc = new JFileChooser();
- fc.setDialogTitle("Path to SSH key file");
- fc.setApproveButtonText("OK");
- fc.setFileHidingEnabled(false);
- int ret = fc.showOpenDialog(this);
- if (ret == JFileChooser.APPROVE_OPTION)
- sshKeyFile.setText(fc.getSelectedFile().toString());
- }
- } else if (s instanceof JRadioButton) {
- JRadioButton button = (JRadioButton)s;
- if (button == sshArgsCustom || button == sshArgsDefault) {
- sshArguments.setEnabled(sshArgsCustom.isSelected());
- }
+ private void handleEmbed()
+ {
+ if (embed.getValue()) {
+ desktopSizeCheckbox.setEnabled(false);
+ desktopWidthInput.setEnabled(false);
+ desktopHeightInput.setEnabled(false);
+ fullScreenCheckbox.setEnabled(false);
+ fullScreenAllMonitorsCheckbox.setEnabled(false);
+ scalingFactorInput.setEnabled(false);
}
}
- public void itemStateChanged(ItemEvent e) {
- Object s = e.getSource();
- if (s instanceof JCheckBox) {
- JCheckBox item = (JCheckBox)s;
- boolean enable = item.isSelected();
- if (item == autoSelect) {
- ButtonGroup[] groups = { encodingGroup, colourGroup };
- for (ButtonGroup grp : groups) {
- Enumeration<AbstractButton> elems = grp.getElements();
- while (elems.hasMoreElements())
- elems.nextElement().setEnabled(!enable);
- }
- } else if (item == customCompressLevel) {
- compressLevel.setEnabled(enable);
- } else if (item == desktopSize) {
- desktopWidth.setEnabled(enable);
- desktopHeight.setEnabled(enable);
- } else if (item == noJpeg) {
- qualityLevel.setEnabled(enable);
- } else if (item == encX509) {
- x509ca.setEnabled(enable);
- caButton.setEnabled(enable);
- x509crl.setEnabled(enable);
- crlButton.setEnabled(enable);
- } else if (item == secVeNCrypt) {
- encNone.setEnabled(enable);
- encTLS.setEnabled(enable);
- encX509.setEnabled(enable);
- x509ca.setEnabled(enable && encX509.isSelected());
- caButton.setEnabled(enable && encX509.isSelected());
- x509crl.setEnabled(enable && encX509.isSelected());
- crlButton.setEnabled(enable && encX509.isSelected());
- secIdent.setEnabled(enable);
- secPlain.setEnabled(enable);
- sendLocalUsername.setEnabled(enable);
- } else if (item == encNone) {
- secNone.setSelected(enable &&
- UserPreferences.getBool("viewer", "secNone", true));
- secVnc.setSelected(enable &&
- UserPreferences.getBool("viewer", "secVnc", true));
- } else if (item == secIdent || item == secPlain) {
- sendLocalUsername.setEnabled(secIdent.isSelected() ||
- secPlain.isSelected());
- } else if (item == sshTunnel) {
- sshUseGateway.setEnabled(enable);
- sshUser.setEnabled(enable &&
- sshUseGateway.isEnabled() &&
- sshUseGateway.isSelected());
- sshHost.setEnabled(enable &&
- sshUseGateway.isEnabled() &&
- sshUseGateway.isSelected());
- sshPort.setEnabled(enable &&
- sshUseGateway.isEnabled() &&
- sshUseGateway.isSelected());
- sshUseExt.setEnabled(enable);
- sshClient.setEnabled(enable &&
- sshUseExt.isEnabled() &&
- sshUseExt.isSelected());
- sshClientBrowser.setEnabled(enable &&
- sshUseExt.isEnabled() &&
- sshUseExt.isSelected());
- sshArgsDefault.setEnabled(enable &&
- sshUseExt.isEnabled() &&
- sshUseExt.isSelected());
- sshArgsCustom.setEnabled(enable &&
- sshUseExt.isEnabled() &&
- sshUseExt.isSelected());
- sshArguments.setEnabled(enable &&
- sshUseExt.isEnabled() &&
- sshUseExt.isSelected() &&
- sshArgsCustom.isSelected());
- sshConfig.setEnabled(enable &&
- sshUseExt.isEnabled() &&
- !sshUseExt.isSelected());
- sshConfigBrowser.setEnabled(enable &&
- sshUseExt.isEnabled() &&
- !sshUseExt.isSelected());
- sshKeyFile.setEnabled(enable &&
- sshUseExt.isEnabled() &&
- !sshUseExt.isSelected());
- sshKeyFileBrowser.setEnabled(enable &&
- sshUseExt.isEnabled() &&
- !sshUseExt.isSelected());
- } else if (item == sshUseExt) {
- sshClient.setEnabled(enable);
- sshClientBrowser.setEnabled(enable);
- sshArgsDefault.setEnabled(enable);
- sshArgsCustom.setEnabled(enable);
- sshArguments.setEnabled(enable && sshArgsCustom.isSelected());
- sshConfig.setEnabled(!enable);
- sshConfigBrowser.setEnabled(!enable);
- sshKeyFile.setEnabled(!enable);
- sshKeyFileBrowser.setEnabled(!enable);
- } else if (item == sshUseGateway) {
- sshUser.setEnabled(enable);
- sshHost.setEnabled(enable);
- sshPort.setEnabled(enable);
- }
+ private void handleRfbState()
+ {
+ CConn cc = VncViewer.cc;
+ if (cc != null && cc.state() == CConnection.RFBSTATE_NORMAL) {
+ JComponent[] components = {
+ encNoneCheckbox, encTLSCheckbox, encX509Checkbox, authNoneCheckbox,
+ authVncCheckbox, authVncCheckbox, authIdentCheckbox, authPlainCheckbox,
+ sendLocalUsernameCheckbox, caInput, caChooser, crlInput, crlChooser,
+ sharedCheckbox, tunnelCheckbox, viaCheckbox, viaUserInput, viaHostInput,
+ viaPortInput, extSSHCheckbox, sshClientInput, sshClientChooser,
+ sshArgsDefaultButton, sshArgsCustomButton, sshArgsInput, sshConfigInput,
+ sshKeyFileInput, sshConfigChooser, sshKeyFileChooser,
+ };
+ for (JComponent c : components)
+ c.setEnabled(false);
}
}
+
+ static LogWriter vlog = new LogWriter("OptionsDialog");
}
+++ /dev/null
-/* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
-
-package com.tigervnc.vncviewer;
-
-public interface OptionsDialogCallback {
- public void setOptions();
- public void getOptions();
-}
String instruction,
String[] prompt,
boolean[] echo) {
- vlog.info("OK");
Container panel = new JPanel(new GridBagLayout());
((JPanel)panel).setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
abstract public class PlatformPixelBuffer extends PixelBuffer
{
- public PlatformPixelBuffer(int w, int h, CConn cc_, DesktopWindow desktop_) {
- cc = cc_;
+ public PlatformPixelBuffer(PixelFormat pf, int w, int h, DesktopWindow desktop_) {
desktop = desktop_;
PixelFormat nativePF = getNativePF();
- if (nativePF.depth > cc.serverPF.depth) {
- setPF(cc.serverPF);
+ if (nativePF.depth > pf.depth) {
+ setPF(pf);
} else {
setPF(nativePF);
}
byte[] greens;
byte[] blues;
- CConn cc;
DesktopWindow desktop;
static LogWriter vlog = new LogWriter("PlatformPixelBuffer");
}
import java.awt.*;
import java.awt.event.*;
+import java.io.File;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.WindowConstants.*;
import static java.awt.GridBagConstraints.HORIZONTAL;
import static java.awt.GridBagConstraints.LINE_START;
+import static java.awt.GridBagConstraints.LINE_END;
import static java.awt.GridBagConstraints.NONE;
import static java.awt.GridBagConstraints.REMAINDER;
-class ServerDialog extends Dialog {
+import static com.tigervnc.vncviewer.Parameters.*;
- @SuppressWarnings({"unchecked","rawtypes"})
- public ServerDialog(OptionsDialog options_,
- String defaultServerName, CConn cc_) {
+class ServerDialog extends Dialog implements Runnable {
+ @SuppressWarnings({"unchecked","rawtypes"})
+ public ServerDialog() {
super(true);
- cc = cc_;
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
setTitle("VNC Viewer: Connection Details");
setResizable(false);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
- if (VncViewer.nViewers == 1) {
- cc.viewer.exit(1);
- } else {
- ret = false;
- endDialog();
- }
+ endDialog();
+ System.exit(1);
}
});
- options = options_;
-
- JLabel serverLabel = new JLabel("VNC Server:", JLabel.RIGHT);
+ JLabel serverLabel = new JLabel("VNC server:", JLabel.RIGHT);
String valueStr = new String("");
if (UserPreferences.get("ServerDialog", "history") != null)
valueStr = UserPreferences.get("ServerDialog", "history");
server = new MyJComboBox(valueStr.split(","));
+ server.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ JComboBox s = (JComboBox)e.getSource();
+ if (e.getActionCommand().equals("comboBoxEdited")) {
+ s.insertItemAt(editor.getItem(), 0);
+ s.setSelectedIndex(0);
+ }
+ }
+ });
if (valueStr.equals(""))
server.setPrototypeDisplayValue("255.255.255.255:5900");
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
server.insertItemAt(editor.getItem(), 0);
server.setSelectedIndex(0);
- commit();
+ handleConnect();
}
}
});
JLabel icon = new JLabel(VncViewer.logoIcon);
optionsButton = new JButton("Options...");
+ optionsButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ handleOptions();
+ }
+ });
+ JButton loadButton = new JButton("Load...");
+ loadButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ handleLoad();
+ }
+ });
+ JButton saveAsButton = new JButton("Save As...");
+ saveAsButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ handleSaveAs();
+ }
+ });
aboutButton = new JButton("About...");
- okButton = new JButton("OK");
+ aboutButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ handleAbout();
+ }
+ });
cancelButton = new JButton("Cancel");
+ cancelButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ handleCancel();
+ }
+ });
+ connectButton = new JButton("Connect \u21B5");
+ connectButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ handleConnect();
+ }
+ });
contentPane.add(icon,
new GridBagConstraints(0, 0,
LINE_START, HORIZONTAL,
new Insets(5, 0, 5, 5),
NONE, NONE));
- JPanel buttonPane = new JPanel();
- buttonPane.setLayout(new GridLayout(1, 4, 5, 5));
- buttonPane.add(aboutButton);
- buttonPane.add(optionsButton);
- buttonPane.add(okButton);
- buttonPane.add(cancelButton);
- contentPane.add(buttonPane,
+ JPanel buttonPane1 = new JPanel();
+ Box box = Box.createHorizontalBox();
+ JSeparator separator1 = new JSeparator();
+ JSeparator separator2 = new JSeparator();
+ GroupLayout layout = new GroupLayout(buttonPane1);
+ buttonPane1.setLayout(layout);
+ layout.setAutoCreateGaps(false);
+ layout.setAutoCreateContainerGaps(false);
+ layout.setHorizontalGroup(
+ layout.createSequentialGroup()
+ .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addGap(10)
+ .addComponent(optionsButton))
+ .addComponent(separator1)
+ .addGroup(layout.createSequentialGroup()
+ .addGap(10)
+ .addComponent(aboutButton)))
+ .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
+ .addGroup(layout.createSequentialGroup()
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(loadButton)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(saveAsButton)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(box)
+ .addGap(10))
+ .addComponent(separator2)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(cancelButton)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(connectButton)
+ .addGap(10)))
+ );
+ layout.setVerticalGroup(
+ layout.createSequentialGroup()
+ .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
+ .addComponent(optionsButton)
+ .addComponent(loadButton)
+ .addComponent(saveAsButton)
+ .addComponent(box))
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
+ .addComponent(separator1)
+ .addComponent(separator2))
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
+ .addComponent(aboutButton)
+ .addComponent(cancelButton)
+ .addComponent(connectButton))
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ );
+ layout.linkSize(SwingConstants.HORIZONTAL,
+ optionsButton, loadButton, saveAsButton,
+ aboutButton, cancelButton, box);
+ contentPane.add(buttonPane1,
new GridBagConstraints(0, 1,
REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, HORIZONTAL,
- new Insets(5, 5, 5, 5),
+ new Insets(5, 0, 10, 0),
NONE, NONE));
- addListeners(this);
pack();
}
- @SuppressWarnings({"unchecked","rawtypes"})
- public void actionPerformed(ActionEvent e) {
- Object s = e.getSource();
- if (s instanceof JButton && (JButton)s == okButton) {
- commit();
- } else if (s instanceof JButton && (JButton)s == cancelButton) {
- if (VncViewer.nViewers == 1)
- cc.viewer.exit(1);
- ret = false;
- endDialog();
- } else if (s instanceof JButton && (JButton)s == optionsButton) {
- options.showDialog(this);
- } 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);
- }
+ public void run() {
+ this.showDialog();
+ }
+
+ private void handleOptions() {
+ OptionsDialog.showDialog(this);
+ }
+
+ private void handleLoad() {
+ String title = "Select a TigerVNC configuration file";
+ File dflt = new File(FileUtils.getVncHomeDir().concat("default.tigervnc"));
+ File f = showChooser(title, dflt);
+ if (f != null && f.exists() && f.canRead())
+ loadViewerParameters(f.getAbsolutePath());
+ }
+
+ private void handleSaveAs() {
+ String title = "Save the TigerVNC configuration to file";
+ File dflt = new File(FileUtils.getVncHomeDir().concat("default.tigervnc"));
+ if (!dflt.exists() || !dflt.isFile())
+ dflt = new File(FileUtils.getVncHomeDir());
+ File f = showChooser(title, dflt);
+ while (f != null && f.exists() && f.isFile()) {
+ String msg = f.getAbsolutePath();
+ msg = msg.concat(" already exists. Do you want to overwrite?");
+ Object[] options = {"Overwrite", "No \u21B5"};
+ JOptionPane op =
+ new JOptionPane(msg, JOptionPane.QUESTION_MESSAGE,
+ JOptionPane.OK_CANCEL_OPTION, null, options, options[1]);
+ JDialog dlg = op.createDialog(this, "TigerVNC Viewer");
+ dlg.setIconImage(VncViewer.frameIcon);
+ dlg.setAlwaysOnTop(true);
+ dlg.setVisible(true);
+ if (op.getValue() == options[0])
+ break;
+ else
+ f = showChooser(title, f);
}
+ if (f != null && (!f.exists() || f.canWrite()))
+ saveViewerParameters(f.getAbsolutePath(), (String)server.getSelectedItem());
+ }
+
+ private void handleAbout() {
+ VncViewer.showAbout(this);
}
- private void commit() {
+ private void handleCancel() {
+ vncServerName.setParam("");
+ endDialog();
+ }
+
+ private void handleConnect() {
String serverName = (String)server.getSelectedItem();
- if (serverName == null || serverName.equals("")) {
- vlog.error("Invalid servername specified");
- if (VncViewer.nViewers == 1)
- cc.viewer.exit(1);
- ret = false;
- endDialog();
- }
- // set params
- Configuration.setParam("Server", Hostname.getHost(serverName));
- Configuration.setParam("Port",
- Integer.toString(Hostname.getPort(serverName)));
- // Update the history list
- String valueStr = UserPreferences.get("ServerDialog", "history");
- String t = (valueStr == null) ? "" : valueStr;
- StringTokenizer st = new StringTokenizer(t, ",");
- StringBuffer sb =
- new StringBuffer().append((String)server.getSelectedItem());
- while (st.hasMoreTokens()) {
- String str = st.nextToken();
- if (!str.equals((String)server.getSelectedItem()) && !str.equals("")) {
- sb.append(',');
- sb.append(str);
- }
- }
- UserPreferences.set("ServerDialog", "history", sb.toString());
- UserPreferences.save("ServerDialog");
+ vncServerName.setParam(serverName);
+ saveViewerParameters(null, serverName);
endDialog();
}
- CConn cc;
@SuppressWarnings("rawtypes")
MyJComboBox server;
ComboBoxEditor editor;
- JButton aboutButton, optionsButton, okButton, cancelButton;
+ JButton aboutButton, optionsButton, connectButton, cancelButton;
OptionsDialog options;
static LogWriter vlog = new LogWriter("ServerDialog");
/*
- * Copyright (C) 2012-2016 All Rights Reserved.
+ * Copyright (C) 2012-2016 Brian P. Hinz. All Rights Reserved.
* Copyright (C) 2000 Const Kaplinsky. All Rights Reserved.
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
*
import com.jcraft.jsch.OpenSSHConfig;
import com.jcraft.jsch.Session;
+import static com.tigervnc.vncviewer.Parameters.*;
+
public class Tunnel {
private final static String DEFAULT_TUNNEL_TEMPLATE
String remoteHost;
remotePort = cc.getServerPort();
- if (cc.viewer.tunnel.getValue()) {
+ if (tunnel.getValue()) {
gatewayHost = cc.getServerName();
remoteHost = "localhost";
} else {
- gatewayHost = getSshHost(cc);
+ gatewayHost = getSshHost();
remoteHost = cc.getServerName();
}
- String pattern = cc.viewer.extSSHArgs.getValue();
- if (pattern == null) {
- if (cc.viewer.tunnel.getValue())
+ String pattern = extSSHArgs.getValue();
+ if (pattern == null || pattern.isEmpty()) {
+ if (tunnel.getValue())
pattern = System.getProperty("VNC_TUNNEL_CMD");
else
pattern = System.getProperty("VNC_VIA_CMD");
}
- if (cc.viewer.extSSH.getValue() ||
+ if (extSSH.getValue() ||
(pattern != null && pattern.length() > 0)) {
- createTunnelExt(gatewayHost, remoteHost, remotePort, localPort, pattern, cc);
+ createTunnelExt(gatewayHost, remoteHost, remotePort, localPort, pattern);
} else {
- createTunnelJSch(gatewayHost, remoteHost, remotePort, localPort, cc);
+ createTunnelJSch(gatewayHost, remoteHost, remotePort, localPort);
}
}
}
}
- public static String getSshHost(CConn cc) {
- String sshHost = cc.viewer.via.getValue();
- if (sshHost == null)
- return cc.getServerName();
+ public static String getSshHost() {
+ String sshHost = via.getValue();
+ if (sshHost.isEmpty())
+ return vncServerName.getValue();
int end = sshHost.indexOf(":");
if (end < 0)
end = sshHost.length();
return sshHost;
}
- public static String getSshUser(CConn cc) {
+ public static String getSshUser() {
String sshUser = (String)System.getProperties().get("user.name");
- String via = cc.viewer.via.getValue();
- if (via != null && via.indexOf("@") > 0)
- sshUser = via.substring(0, via.indexOf("@"));
+ String viaStr = via.getValue();
+ if (!viaStr.isEmpty() && viaStr.indexOf("@") > 0)
+ sshUser = viaStr.substring(0, viaStr.indexOf("@"));
return sshUser;
}
- public static int getSshPort(CConn cc) {
+ public static int getSshPort() {
String sshPort = "22";
- String via = cc.viewer.via.getValue();
- if (via != null && via.indexOf(":") > 0)
- sshPort = via.substring(via.indexOf(":")+1, via.length());
+ String viaStr = via.getValue();
+ if (!viaStr.isEmpty() && viaStr.indexOf(":") > 0)
+ sshPort = viaStr.substring(viaStr.indexOf(":")+1, viaStr.length());
return Integer.parseInt(sshPort);
}
- public static String getSshKeyFile(CConn cc) {
- if (cc.viewer.sshKeyFile.getValue() != null)
- return cc.viewer.sshKeyFile.getValue();
+ public static String getSshKeyFile() {
+ if (!sshKeyFile.getValue().isEmpty())
+ return sshKeyFile.getValue();
String[] ids = { "id_dsa", "id_rsa" };
for (String id : ids) {
File f = new File(FileUtils.getHomeDir()+".ssh/"+id);
if (f.exists() && f.canRead())
return(f.getAbsolutePath());
}
- return null;
+ return "";
+ }
+
+ public static String getSshKey() {
+ if (!sshKey.getValue().isEmpty())
+ return sshKeyFile.getValue().replaceAll("\\\\n", "\n");
+ return "";
}
private static void createTunnelJSch(String gatewayHost, String remoteHost,
- int remotePort, int localPort,
- CConn cc) throws Exception {
+ int remotePort, int localPort) throws Exception {
JSch.setLogger(new MyJSchLogger());
JSch jsch=new JSch();
if (knownHosts.exists() && knownHosts.canRead())
jsch.setKnownHosts(knownHosts.getAbsolutePath());
ArrayList<File> privateKeys = new ArrayList<File>();
- String sshKeyFile = cc.options.sshKeyFile.getText();
- String sshKey = cc.viewer.sshKey.getValue();
- if (sshKey != null) {
- String sshKeyPass = cc.viewer.sshKeyPass.getValue();
+ if (!getSshKey().isEmpty()) {
byte[] keyPass = null, key;
- if (sshKeyPass != null)
- keyPass = sshKeyPass.getBytes();
- sshKey = sshKey.replaceAll("\\\\n", "\n");
- key = sshKey.getBytes();
- jsch.addIdentity("TigerVNC", key, null, keyPass);
- } else if (!sshKeyFile.equals("")) {
- File f = new File(sshKeyFile);
+ if (!sshKeyPass.getValue().isEmpty())
+ keyPass = sshKeyPass.getValue().getBytes();
+ jsch.addIdentity("TigerVNC", getSshKey().getBytes(), null, keyPass);
+ } else if (!getSshKeyFile().isEmpty()) {
+ File f = new File(getSshKeyFile());
if (!f.exists() || !f.canRead())
- throw new Exception("Cannot access SSH key file "+ sshKeyFile);
+ throw new Exception("Cannot access SSH key file "+getSshKeyFile());
privateKeys.add(f);
}
for (Iterator<File> i = privateKeys.iterator(); i.hasNext();) {
File privateKey = (File)i.next();
if (privateKey.exists() && privateKey.canRead())
- if (cc.viewer.sshKeyPass.getValue() != null)
+ if (!sshKeyPass.getValue().isEmpty())
jsch.addIdentity(privateKey.getAbsolutePath(),
- cc.viewer.sshKeyPass.getValue());
+ sshKeyPass.getValue());
else
jsch.addIdentity(privateKey.getAbsolutePath());
}
- String user = getSshUser(cc);
+ String user = getSshUser();
String label = new String("SSH Authentication");
PasswdDialog dlg =
new PasswdDialog(label, (user == null ? false : true), false);
dlg.userEntry.setText(user != null ? user : "");
- File ssh_config = new File(cc.viewer.sshConfig.getValue());
+ File ssh_config = new File(sshConfig.getValue());
if (ssh_config.exists() && ssh_config.canRead()) {
ConfigRepository repo =
OpenSSHConfig.parse(ssh_config.getAbsolutePath());
jsch.setConfigRepository(repo);
}
- Session session=jsch.getSession(user, gatewayHost, getSshPort(cc));
+ Session session=jsch.getSession(user, gatewayHost, getSshPort());
session.setUserInfo(dlg);
// OpenSSHConfig doesn't recognize StrictHostKeyChecking
if (session.getConfig("StrictHostKeyChecking") == null)
}
}
- private static class MyExtProcess implements Runnable {
-
- private String cmd = null;
- private Process pid = null;
-
- private static class MyProcessLogger extends Thread {
- private final BufferedReader err;
-
- public MyProcessLogger(Process p) {
- InputStreamReader reader =
- new InputStreamReader(p.getErrorStream());
- err = new BufferedReader(reader);
- }
-
- @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 MyExtProcess(String command) {
- cmd = command;
- }
-
- public void run() {
- try {
- Runtime runtime = Runtime.getRuntime();
- pid = runtime.exec(cmd);
- runtime.addShutdownHook(new MyShutdownHook(pid));
- new MyProcessLogger(pid).start();
- pid.waitFor();
- } catch(InterruptedException e) {
- vlog.info(e.getMessage());
- } catch(java.io.IOException e) {
- vlog.info(e.getMessage());
- }
- }
- }
-
private static void createTunnelExt(String gatewayHost, String remoteHost,
int remotePort, int localPort,
- String pattern, CConn cc) throws Exception {
+ String pattern) throws Exception {
if (pattern == null || pattern.length() < 1) {
- if (cc.viewer.tunnel.getValue())
+ if (tunnel.getValue())
pattern = DEFAULT_TUNNEL_TEMPLATE;
else
pattern = DEFAULT_VIA_TEMPLATE;
}
String cmd = fillCmdPattern(pattern, gatewayHost, remoteHost,
- remotePort, localPort, cc);
+ remotePort, localPort);
try {
- Thread t = new Thread(new MyExtProcess(cmd));
+ Thread t = new Thread(new ExtProcess(cmd, vlog, true));
t.start();
// wait for the ssh process to start
Thread.sleep(1000);
private static String fillCmdPattern(String pattern, String gatewayHost,
String remoteHost, int remotePort,
- int localPort, CConn cc) {
+ int localPort) {
boolean H_found = false, G_found = false, R_found = false, L_found = false;
boolean P_found = false;
- String cmd = cc.options.sshClient.getText() + " ";
+ String cmd = extSSHClient.getValue() + " ";
pattern.replaceAll("^\\s+", "");
- String user = getSshUser(cc);
- int sshPort = getSshPort(cc);
+ String user = getSshUser();
+ int sshPort = getSshPort();
gatewayHost = user + "@" + gatewayHost;
for (int i = 0; i < pattern.length(); i++) {
if (pattern.charAt(i) == '%') {
switch (pattern.charAt(++i)) {
case 'H':
- cmd += (cc.viewer.tunnel.getValue() ? gatewayHost : remoteHost);
+ cmd += (tunnel.getValue() ? gatewayHost : remoteHost);
H_found = true;
continue;
case 'G':
if (!H_found || !R_found || !L_found)
throw new Exception("%H, %R or %L absent in tunneling command template.");
- if (!cc.viewer.tunnel.getValue() && !G_found)
+ if (!tunnel.getValue() && !G_found)
throw new Exception("%G pattern absent in tunneling command template.");
vlog.info("SSH command line: "+cmd);
import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
+import static com.tigervnc.vncviewer.Parameters.*;
+
public class Viewport extends JFrame
{
public Viewport(String name, CConn cc_) {
sp.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
getContentPane().add(sp);
if (VncViewer.os.startsWith("mac os x")) {
- if (!VncViewer.noLionFS.getValue())
+ if (!noLionFS.getValue())
enableLionFS();
}
addWindowFocusListener(new WindowAdapter() {
});
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
- if (VncViewer.nViewers == 1) {
- if (cc.closeListener != null) {
- cc.close();
- } else {
- cc.viewer.exit(1);
- }
- } else {
- cc.close();
- }
+ cc.close();
}
});
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
- String scaleString = cc.viewer.scalingFactor.getValue();
+ String scaleString = scalingFactor.getValue();
if (scaleString.equalsIgnoreCase("Auto") ||
scaleString.equalsIgnoreCase("FixedRatio")) {
if ((sp.getSize().width != cc.desktop.scaledWidth) ||
sp.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_NEVER);
sp.validate();
if (getExtendedState() != JFrame.MAXIMIZED_BOTH &&
- !cc.fullScreen) {
+ !fullScreen.getValue()) {
sp.setSize(new Dimension(cc.desktop.scaledWidth,
cc.desktop.scaledHeight));
int w = cc.desktop.scaledWidth + getInsets().left +
});
}
+ public void setName(String name) {
+ setTitle(name + "- TigerVNC");
+ }
+
boolean lionFSSupported() { return canDoLionFS; }
void enableLionFS() {
public void setGeometry(int x, int y, int w, int h) {
pack();
- if (!cc.fullScreen)
+ if (!fullScreen.getValue())
setLocation(x, y);
}
GraphicsEnvironment.getLocalGraphicsEnvironment();
Rectangle r = new Rectangle();
setMaximizedBounds(null);
- if (cc.viewer.fullScreenAllMonitors.getValue()) {
+ if (fullScreenAllMonitors.getValue()) {
for (GraphicsDevice gd : ge.getScreenDevices())
for (GraphicsConfiguration gc : gd.getConfigurations())
r = r.union(gc.getBounds());
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2011-2013 D. R. Commander. All Rights Reserved.
- * Copyright (C) 2011-2015 Brian P. Hinz
+ * Copyright (C) 2011-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
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
+import java.io.BufferedReader;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.IOException;
import java.io.File;
import java.lang.Character;
import java.lang.reflect.*;
+import java.net.URL;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.*;
import javax.swing.*;
import javax.swing.plaf.FontUIResource;
+import javax.swing.SwingUtilities;
import javax.swing.UIManager.*;
import com.tigervnc.rdr.*;
import com.tigervnc.rfb.*;
import com.tigervnc.network.*;
+import static com.tigervnc.vncviewer.Parameters.*;
+
public class VncViewer extends javax.swing.JApplet
implements Runnable, ActionListener {
viewer.start();
}
+ public VncViewer() {
+ //this(new String[0]);
+ embed.setParam(true);
+ }
public VncViewer(String[] argv) {
- embed.setParam(false);
-
- // load user preferences
- UserPreferences.load("global");
SecurityClient.setDefaults();
Configuration.enableViewerParams();
+ /* Load the default parameter settings */
+ String defaultServerName;
+ try {
+ defaultServerName = loadViewerParameters(null);
+ } catch (com.tigervnc.rfb.Exception e) {
+ defaultServerName = "";
+ vlog.info(e.getMessage());
+ }
+
// Override defaults with command-line options
for (int i = 0; i < argv.length; i++) {
if (argv[i].length() == 0)
continue;
if (argv[i].equalsIgnoreCase("-config")) {
- if (++i >= argv.length) usage();
- Configuration.load(argv[i]);
+ if (++i >= argv.length)
+ usage();
+ defaultServerName = loadViewerParameters(argv[i]);
continue;
}
usage();
}
- if (vncServerName.getValue() != null)
+ if (!vncServerName.getValue().isEmpty())
usage();
vncServerName.setParam(argv[i]);
}
- if (!autoSelect.hasBeenSet()) {
- // Default to AutoSelect=0 if -PreferredEncoding or -FullColor is used
- autoSelect.setParam(!preferredEncoding.hasBeenSet() &&
- !fullColour.hasBeenSet() &&
- !fullColourAlias.hasBeenSet());
- }
- if (!fullColour.hasBeenSet() && !fullColourAlias.hasBeenSet()) {
- // Default to FullColor=0 if AutoSelect=0 && LowColorLevel is set
- if (!autoSelect.getValue() && (lowColourLevel.hasBeenSet() ||
- lowColourLevelAlias.hasBeenSet())) {
- fullColour.setParam(false);
- }
- }
- if (!customCompressLevel.hasBeenSet()) {
- // Default to CustomCompressLevel=1 if CompressLevel is used.
- customCompressLevel.setParam(compressLevel.hasBeenSet());
- }
}
public static void usage() {
System.exit(1);
}
- public VncViewer() {
- UserPreferences.load("global");
- embed.setParam(true);
- }
-
- public static void newViewer(VncViewer oldViewer, Socket sock, boolean close) {
- VncViewer viewer = new VncViewer();
- viewer.embed.setParam(oldViewer.embed.getValue());
- viewer.sock = sock;
- viewer.start();
- if (close)
- oldViewer.exit(0);
- }
-
- public static void newViewer(VncViewer oldViewer, Socket sock) {
- newViewer(oldViewer, sock, false);
- }
-
- public static void newViewer(VncViewer oldViewer) {
- newViewer(oldViewer, null);
+ public static void newViewer() {
+ String cmd = "java -jar ";
+ try {
+ URL url =
+ VncViewer.class.getProtectionDomain().getCodeSource().getLocation();
+ File f = new File(url.toURI());
+ if (!f.exists() || !f.canRead()) {
+ String msg = new String("The jar file "+f.getAbsolutePath()+
+ " does not exist or cannot be read.");
+ JOptionPane.showMessageDialog(null, msg, "ERROR",
+ JOptionPane.ERROR_MESSAGE);
+ return;
+ }
+ cmd = cmd.concat(f.getAbsolutePath());
+ Thread t = new Thread(new ExtProcess(cmd, vlog));
+ t.start();
+ } catch (java.net.URISyntaxException e) {
+ vlog.info(e.getMessage());
+ } catch (java.lang.Exception e) {
+ vlog.info(e.getMessage());
+ }
}
public boolean isAppletDragStart(MouseEvent e) {
}
public void appletDragFinished() {
- cc.setEmbeddedFeatures(true);
JFrame f = (JFrame)JOptionPane.getFrameForComponent(this);
if (f != null)
f.dispose();
}
public void appletRestored() {
- cc.setEmbeddedFeatures(false);
cc.setCloseListener(null);
}
}
}
+ public static void showAbout(Container parent) {
+ String pkgDate = "";
+ String pkgTime = "";
+ try {
+ Manifest manifest = new Manifest(VncViewer.timestamp);
+ Attributes attributes = manifest.getMainAttributes();
+ pkgDate = attributes.getValue("Package-Date");
+ pkgTime = attributes.getValue("Package-Time");
+ } catch (java.lang.Exception e) { }
+
+ Window fullScreenWindow = Viewport.getFullScreenWindow();
+ if (fullScreenWindow != null)
+ Viewport.setFullScreenWindow(null);
+ String msg =
+ String.format(VncViewer.aboutText, VncViewer.version, VncViewer.build,
+ VncViewer.buildDate, VncViewer.buildTime);
+ Object[] options = {"Close \u21B5"};
+ JOptionPane op =
+ new JOptionPane(msg, JOptionPane.INFORMATION_MESSAGE,
+ JOptionPane.DEFAULT_OPTION, VncViewer.logoIcon, options);
+ JDialog dlg = op.createDialog(parent, "About TigerVNC Viewer for Java");
+ dlg.setIconImage(VncViewer.frameIcon);
+ dlg.setAlwaysOnTop(true);
+ dlg.setVisible(true);
+ if (fullScreenWindow != null)
+ Viewport.setFullScreenWindow(fullScreenWindow);
+ }
+
public void start() {
vlog.debug("start called");
getTimestamp();
- if (embed.getValue() && nViewers == 0) {
+ if (embed.getValue()) {
+ setupEmbeddedFrame();
alwaysShowServerDialog.setParam(false);
- Configuration.global().readAppletParams(this);
+ String servername = loadAppletParameters(this);
+ vncServerName.setParam(servername);
fullScreen.setParam(false);
scalingFactor.setParam("100");
- String host = getCodeBase().getHost();
- if (vncServerName.getValue() == null && vncServerPort.getValue() != 0) {
- int port = vncServerPort.getValue();
- vncServerName.setParam(host + ((port >= 5900 && port <= 5999)
- ? (":"+(port-5900))
- : ("::"+port)));
- }
}
- nViewers++;
thread = new Thread(this);
thread.start();
}
public void exit(int n) {
- nViewers--;
- if (nViewers > 0)
- return;
if (embed.getValue())
destroy();
else
System.exit(n);
}
+ private void setupEmbeddedFrame() {
+ UIManager.getDefaults().put("ScrollPane.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{}));
+ sp = new JScrollPane();
+ sp.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
+ sp.getViewport().setBackground(Color.BLACK);
+ InputMap im = sp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
+ int ctrlAltShiftMask = Event.SHIFT_MASK | Event.CTRL_MASK | Event.ALT_MASK;
+ if (im != null) {
+ im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, ctrlAltShiftMask),
+ "unitScrollUp");
+ im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, ctrlAltShiftMask),
+ "unitScrollDown");
+ im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, ctrlAltShiftMask),
+ "unitScrollLeft");
+ im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, ctrlAltShiftMask),
+ "unitScrollRight");
+ im.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, ctrlAltShiftMask),
+ "scrollUp");
+ im.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, ctrlAltShiftMask),
+ "scrollDown");
+ im.put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, ctrlAltShiftMask),
+ "scrollLeft");
+ im.put(KeyStroke.getKeyStroke(KeyEvent.VK_END, ctrlAltShiftMask),
+ "scrollRight");
+ }
+ sp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
+ add(sp);
+ }
+
+ public static JViewport getViewport() {
+ return sp.getViewport();
+ }
+
// If "Reconnect" button is pressed
public void actionPerformed(ActionEvent e) {
getContentPane().removeAll();
}
}
- CConn cc;
public void run() {
cc = null;
if (listenMode.getValue()) {
int port = 5500;
- if (vncServerName.getValue() != null &&
+ if (!vncServerName.getValue().isEmpty() &&
Character.isDigit(vncServerName.getValue().charAt(0)))
port = Integer.parseInt(vncServerName.getValue());
vlog.info("Listening on port "+port);
- while (true) {
- Socket new_sock = listener.accept();
- if (new_sock != null)
- newViewer(this, new_sock, true);
+ while (sock == null)
+ sock = listener.accept();
+ } else {
+ if (alwaysShowServerDialog.getValue() || sock == null) {
+ if (vncServerName.getValue().isEmpty()) {
+ try {
+ SwingUtilities.invokeAndWait(new ServerDialog());
+ } catch (InvocationTargetException e) {
+ reportException(e);
+ } catch (InterruptedException e) {
+ reportException(e);
+ }
+ if (vncServerName.getValue().isEmpty())
+ exit(0);
+ }
}
}
try {
- cc = new CConn(this, sock, vncServerName.getValue());
+ cc = new CConn(vncServerName.getValue(), sock);
while (!cc.shuttingDown)
cc.processMsg();
exit(0);
}
}
- 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);
-
- 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);
-
- BoolParameter useLocalCursor
- = new BoolParameter("UseLocalCursor",
- "Render the mouse cursor locally",
- true);
- BoolParameter sendLocalUsername
- = new BoolParameter("SendLocalUsername",
- "Send the local username for SecurityTypes "+
- "such as Plain rather than prompting",
- true);
- StringParameter passwordFile
- = new StringParameter("PasswordFile",
- "Password file for VNC authentication",
- "");
- AliasParameter passwd
- = new AliasParameter("passwd",
- "Alias for PasswordFile",
- passwordFile);
- BoolParameter autoSelect
- = new BoolParameter("AutoSelect",
- "Auto select pixel format and encoding",
- true);
- BoolParameter fullColour
- = new BoolParameter("FullColour",
- "Use full colour - otherwise 6-bit colour is "+
- "used until AutoSelect decides the link is "+
- "fast enough",
- true);
- AliasParameter fullColourAlias
- = new AliasParameter("FullColor",
- "Alias for FullColour",
- fullColour);
- IntParameter lowColourLevel
- = new IntParameter("LowColorLevel",
- "Color level to use on slow connections. "+
- "0 = Very Low (8 colors), 1 = Low (64 colors), "+
- "2 = Medium (256 colors)",
- 2);
- AliasParameter lowColourLevelAlias
- = new AliasParameter("LowColourLevel",
- "Alias for LowColorLevel",
- lowColourLevel);
- StringParameter preferredEncoding
- = new StringParameter("PreferredEncoding",
- "Preferred encoding to use (Tight, ZRLE, "+
- "hextile or raw) - implies AutoSelect=0",
- "Tight");
- BoolParameter viewOnly
- = new BoolParameter("ViewOnly",
- "Don't send any mouse or keyboard events to "+
- "the server",
- false);
- BoolParameter shared
- = new BoolParameter("Shared",
- "Don't disconnect other viewers upon "+
- "connection - share the desktop instead",
- false);
- BoolParameter fullScreen
- = new BoolParameter("FullScreen",
- "Full Screen Mode",
- false);
- BoolParameter fullScreenAllMonitors
- = new BoolParameter("FullScreenAllMonitors",
- "Enable full screen over all monitors",
- true);
- BoolParameter acceptClipboard
- = new BoolParameter("AcceptClipboard",
- "Accept clipboard changes from the server",
- true);
- BoolParameter sendClipboard
- = new BoolParameter("SendClipboard",
- "Send clipboard changes to the server",
- true);
- static IntParameter maxCutText
- = new IntParameter("MaxCutText",
- "Maximum permitted length of an outgoing clipboard update",
- 262144);
- StringParameter menuKey
- = new StringParameter("MenuKey",
- "The key which brings up the popup menu",
- "F8");
- StringParameter desktopSize
- = new StringParameter("DesktopSize",
- "Reconfigure desktop size on the server on "+
- "connect (if possible)", "");
- BoolParameter listenMode
- = new BoolParameter("listen",
- "Listen for connections from VNC servers",
- false);
- 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");
- 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);
- StringParameter vncServerName
- = new StringParameter("Server",
- "The VNC server <host>[:<dpyNum>] or "+
- "<host>::<port>",
- null);
- IntParameter vncServerPort
- = new IntParameter("Port",
- "The VNC server's port number, assuming it is on "+
- "the host from which the applet was downloaded",
- 0);
- BoolParameter acceptBell
- = new BoolParameter("AcceptBell",
- "Produce a system beep when requested to by the server.",
- true);
- 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.", null);
- 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);
- 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);
- 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");
- 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.", null);
- 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");
- 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.", null);
- 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.",
- null);
- 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.", null);
- BoolParameter customCompressLevel
- = new BoolParameter("CustomCompressLevel",
- "Use custom compression level. "+
- "Default if CompressLevel is specified.",
- false);
- IntParameter compressLevel
- = new IntParameter("CompressLevel",
- "Use specified compression level "+
- "0 = Low, 6 = High",
- 1);
- BoolParameter noJpeg
- = new BoolParameter("NoJPEG",
- "Disable lossy JPEG compression in Tight encoding.",
- false);
- IntParameter qualityLevel
- = new IntParameter("QualityLevel",
- "JPEG quality level. "+
- "0 = Low, 9 = High",
- 8);
- StringParameter x509ca
- = new StringParameter("X509CA",
- "Path to CA certificate to use when authenticating remote servers "+
- "using any of the X509 security schemes (X509None, X509Vnc, etc.). "+
- "Must be in PEM format.",
- FileUtils.getHomeDir()+".vnc/x509_ca.pem");
- StringParameter x509crl
- = new StringParameter("X509CRL",
- "Path to certificate revocation list to use in conjunction with "+
- "-X509CA. Must also be in PEM format.",
- FileUtils.getHomeDir()+".vnc/x509_crl.pem");
- StringParameter config
- = new StringParameter("config",
+ public static CConn cc;
+ private static JScrollPane sp;
+ public static StringParameter config
+ = new StringParameter("Config",
"Specifies a configuration file to load.", null);
Thread thread;
Socket sock;
- static int nViewers;
static LogWriter vlog = new LogWriter("VncViewer");
}