aboutsummaryrefslogtreecommitdiffstats
path: root/java/com/tigervnc
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/tigervnc')
-rw-r--r--java/com/tigervnc/vncviewer/MANIFEST.MF2
-rw-r--r--java/com/tigervnc/vncviewer/OptionsDialog.java54
-rw-r--r--java/com/tigervnc/vncviewer/Parameters.java83
-rw-r--r--java/com/tigervnc/vncviewer/README2
-rw-r--r--java/com/tigervnc/vncviewer/ServerDialog.java4
-rw-r--r--java/com/tigervnc/vncviewer/UserPreferences.java5
-rw-r--r--java/com/tigervnc/vncviewer/Viewport.java23
-rw-r--r--java/com/tigervnc/vncviewer/VncViewer.java17
8 files changed, 141 insertions, 49 deletions
diff --git a/java/com/tigervnc/vncviewer/MANIFEST.MF b/java/com/tigervnc/vncviewer/MANIFEST.MF
index 9e282655..5f67f81c 100644
--- a/java/com/tigervnc/vncviewer/MANIFEST.MF
+++ b/java/com/tigervnc/vncviewer/MANIFEST.MF
@@ -1,5 +1,5 @@
Manifest-Version: 1.0
Main-Class: com.tigervnc.vncviewer.VncViewer
-Application-Name: TigerVNC viewer
+Application-Name: TigerVNC
Permissions: all-permissions
Codebase: *
diff --git a/java/com/tigervnc/vncviewer/OptionsDialog.java b/java/com/tigervnc/vncviewer/OptionsDialog.java
index 927fdf21..9c442cbc 100644
--- a/java/com/tigervnc/vncviewer/OptionsDialog.java
+++ b/java/com/tigervnc/vncviewer/OptionsDialog.java
@@ -152,9 +152,11 @@ class OptionsDialog extends Dialog {
/* Misc. */
JCheckBox sharedCheckbox;
- JCheckBox dotWhenNoCursorCheckbox;
+ JCheckBox alwaysCursorCheckbox;
JCheckBox acceptBellCheckbox;
+ JComboBox cursorTypeChoice;
+
/* SSH */
JCheckBox tunnelCheckbox;
JCheckBox viaCheckbox;
@@ -175,7 +177,7 @@ class OptionsDialog extends Dialog {
@SuppressWarnings({"rawtypes","unchecked"})
public OptionsDialog() {
super(true);
- setTitle("VNC viewer options");
+ setTitle("TigerVNC options");
setResizable(false);
getContentPane().setLayout(
@@ -311,6 +313,7 @@ class OptionsDialog extends Dialog {
handleAutoselect();
handleCompression();
handleJpeg();
+ handleAlwaysCursor();
/* Security */
Security security = new Security(SecurityClient.secTypes);
@@ -458,7 +461,9 @@ class OptionsDialog extends Dialog {
/* Misc. */
sharedCheckbox.setSelected(shared.getValue());
- dotWhenNoCursorCheckbox.setSelected(dotWhenNoCursor.getValue());
+ alwaysCursorCheckbox.setSelected(alwaysCursor.getValue());
+ String cursorTypeStr = cursorType.getValueStr();
+ cursorTypeChoice.setSelectedItem(cursorTypeStr);
acceptBellCheckbox.setSelected(acceptBell.getValue());
/* SSH */
@@ -613,8 +618,9 @@ class OptionsDialog extends Dialog {
/* Misc. */
shared.setParam(sharedCheckbox.isSelected());
- dotWhenNoCursor.setParam(dotWhenNoCursorCheckbox.isSelected());
+ alwaysCursor.setParam(alwaysCursorCheckbox.isSelected());
acceptBell.setParam(acceptBellCheckbox.isSelected());
+ cursorType.setParam((String)cursorTypeChoice.getSelectedItem());
/* SSH */
tunnel.setParam(tunnelCheckbox.isSelected());
@@ -1173,31 +1179,54 @@ class OptionsDialog extends Dialog {
MiscPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
sharedCheckbox =
new JCheckBox("Shared (don't disconnect other viewers)");
- dotWhenNoCursorCheckbox = new JCheckBox("Show dot when no cursor");
+ alwaysCursorCheckbox = new JCheckBox("Show local cursor when not provided by server");
+ alwaysCursorCheckbox.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ handleAlwaysCursor();
+ }
+ });
+ JLabel cursorTypeLabel = new JLabel("Cursor type:");
+ String[] cursorTypes = {"Dot", "System"};
+ cursorTypeChoice = new MyJComboBox(cursorTypes);
+ cursorTypeChoice.setPrototypeDisplayValue("System.");
acceptBellCheckbox = new JCheckBox("Beep when requested by the server");
MiscPanel.add(sharedCheckbox,
new GridBagConstraints(0, 0,
- 1, 1,
+ REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
- MiscPanel.add(dotWhenNoCursorCheckbox,
+ MiscPanel.add(alwaysCursorCheckbox,
new GridBagConstraints(0, 1,
- 1, 1,
+ REMAINDER, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
- MiscPanel.add(acceptBellCheckbox,
+ MiscPanel.add(cursorTypeLabel,
new GridBagConstraints(0, 2,
1, 1,
LIGHT, LIGHT,
LINE_START, NONE,
new Insets(0, 0, 4, 0),
NONE, NONE));
- MiscPanel.add(Box.createRigidArea(new Dimension(5, 0)),
+ MiscPanel.add(cursorTypeChoice,
+ new GridBagConstraints(1, 2,
+ 1, 1,
+ LIGHT, LIGHT,
+ LINE_START, NONE,
+ new Insets(0, 5, 4, 0),
+ NONE, NONE));
+ MiscPanel.add(acceptBellCheckbox,
new GridBagConstraints(0, 3,
+ REMAINDER, 1,
+ LIGHT, LIGHT,
+ LINE_START, NONE,
+ new Insets(0, 0, 4, 0),
+ NONE, NONE));
+ MiscPanel.add(Box.createRigidArea(new Dimension(5, 0)),
+ new GridBagConstraints(0, 4,
REMAINDER, REMAINDER,
HEAVY, HEAVY,
LINE_START, BOTH,
@@ -1633,5 +1662,10 @@ class OptionsDialog extends Dialog {
}
}
+ private void handleAlwaysCursor()
+ {
+ cursorTypeChoice.setEnabled(alwaysCursorCheckbox.isSelected());
+ }
+
static LogWriter vlog = new LogWriter("OptionsDialog");
}
diff --git a/java/com/tigervnc/vncviewer/Parameters.java b/java/com/tigervnc/vncviewer/Parameters.java
index dd2f1c3e..3e14b10e 100644
--- a/java/com/tigervnc/vncviewer/Parameters.java
+++ b/java/com/tigervnc/vncviewer/Parameters.java
@@ -40,9 +40,19 @@ public class Parameters {
public static BoolParameter dotWhenNoCursor
= new BoolParameter("DotWhenNoCursor",
- "Show the dot cursor when the server sends an invisible cursor",
+ "[DEPRECATED] Show the dot cursor when the server sends an invisible cursor",
false);
+ public static BoolParameter alwaysCursor
+ = new BoolParameter("AlwaysCursor",
+ "Show the local cursor when the server sends an invisible cursor",
+ false);
+
+ public static StringParameter cursorType
+ = new StringParameter("CursorType",
+ "Specify which cursor type the local cursor should be. Should be either Dot or System",
+ "Dot");
+
public static BoolParameter sendLocalUsername
= new BoolParameter("SendLocalUsername",
"Send the local username for SecurityTypes "+
@@ -282,7 +292,8 @@ public class Parameters {
CSecurityTLS.X509CA,
CSecurityTLS.X509CRL,
SecurityClient.secTypes,
- dotWhenNoCursor,
+ alwaysCursor,
+ cursorType,
autoSelect,
fullColor,
lowColorLevel,
@@ -315,6 +326,10 @@ public class Parameters {
sshKeyFile,
};
+ static VoidParameter[] readOnlyParameterArray = {
+ dotWhenNoCursor
+ };
+
static LogWriter vlog = new LogWriter("Parameters");
@@ -447,29 +462,35 @@ public class Parameters {
invalidParameterName = false;
} else {
for (int i = 0; i < parameterArray.length; i++) {
- if (parameterArray[i] instanceof StringParameter) {
- if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName())) {
+ VoidParameter parameter;
+ if (i < parameterArray.length) {
+ parameter = parameterArray[i];
+ } else {
+ parameter = readOnlyParameterArray[i - parameterArray.length];
+ }
+ if (parameter instanceof StringParameter) {
+ if (line.substring(0,idx).trim().equalsIgnoreCase(parameter.getName())) {
if (value.length() > 256) {
vlog.error(String.format("Failed to read line %d in file %s: %s",
lineNr, filepath, "Invalid format or too large value"));
continue;
}
- ((StringParameter)parameterArray[i]).setParam(value);
+ ((StringParameter)parameter).setParam(value);
invalidParameterName = false;
}
- } else if (parameterArray[i] instanceof IntParameter) {
- if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName())) {
- ((IntParameter)parameterArray[i]).setParam(value);
+ } else if (parameter instanceof IntParameter) {
+ if (line.substring(0,idx).trim().equalsIgnoreCase(parameter.getName())) {
+ ((IntParameter)parameter).setParam(value);
invalidParameterName = false;
}
- } else if (parameterArray[i] instanceof BoolParameter) {
- if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName())) {
- ((BoolParameter)parameterArray[i]).setParam(value);
+ } else if (parameter instanceof BoolParameter) {
+ if (line.substring(0,idx).trim().equalsIgnoreCase(parameter.getName())) {
+ ((BoolParameter)parameter).setParam(value);
invalidParameterName = false;
}
} else {
vlog.error(String.format("Unknown parameter type for parameter %s",
- parameterArray[i].getName()));
+ parameter.getName()));
}
}
@@ -517,6 +538,10 @@ public class Parameters {
}
}
+ for (int i = 0; i < readOnlyParameterArray.length; i++) {
+ UserPreferences.delete(hKey, readOnlyParameterArray[i].getName());
+ }
+
UserPreferences.save(hKey);
}
@@ -528,28 +553,34 @@ public class Parameters {
if (servername == null)
servername = "";
- for (int i = 0; i < parameterArray.length; i++) {
- if (parameterArray[i] instanceof StringParameter) {
- if (UserPreferences.get(hKey, parameterArray[i].getName()) != null) {
+ for (int i = 0; i < parameterArray.length + readOnlyParameterArray.length; i++) {
+ VoidParameter parameter;
+ if (i < parameterArray.length) {
+ parameter = parameterArray[i];
+ } else {
+ parameter = readOnlyParameterArray[i - parameterArray.length];
+ }
+ if (parameter instanceof StringParameter) {
+ if (UserPreferences.get(hKey, parameter.getName()) != null) {
String stringValue =
- UserPreferences.get(hKey, parameterArray[i].getName());
- ((StringParameter)parameterArray[i]).setParam(stringValue);
+ UserPreferences.get(hKey, parameter.getName());
+ ((StringParameter)parameter).setParam(stringValue);
}
- } else if (parameterArray[i] instanceof IntParameter) {
- if (UserPreferences.get(hKey, parameterArray[i].getName()) != null) {
+ } else if (parameter instanceof IntParameter) {
+ if (UserPreferences.get(hKey, parameter.getName()) != null) {
int intValue =
- UserPreferences.getInt(hKey, parameterArray[i].getName());
- ((IntParameter)parameterArray[i]).setParam(intValue);
+ UserPreferences.getInt(hKey, parameter.getName());
+ ((IntParameter)parameter).setParam(intValue);
}
- } else if (parameterArray[i] instanceof BoolParameter) {
- if (UserPreferences.get(hKey, parameterArray[i].getName()) != null) {
+ } else if (parameter instanceof BoolParameter) {
+ if (UserPreferences.get(hKey, parameter.getName()) != null) {
boolean booleanValue =
- UserPreferences.getBool(hKey, parameterArray[i].getName());
- ((BoolParameter)parameterArray[i]).setParam(booleanValue);
+ UserPreferences.getBool(hKey, parameter.getName());
+ ((BoolParameter)parameter).setParam(booleanValue);
}
} else {
vlog.error(String.format("Unknown parameter type for parameter %s",
- parameterArray[i].getName()));
+ parameter.getName()));
}
}
diff --git a/java/com/tigervnc/vncviewer/README b/java/com/tigervnc/vncviewer/README
index 404b8eb9..4ad198fe 100644
--- a/java/com/tigervnc/vncviewer/README
+++ b/java/com/tigervnc/vncviewer/README
@@ -12,7 +12,7 @@ optimizations, major GUI improvements, and more.
Copyright (C) 2004-2005 Cendio AB
Copyright (C) 2005 Martin Koegler
Copyright (C) 2009 Pierre Ossman for Cendio AB
- Copyright (C) 2009-2024 TigerVNC Team
+ Copyright (C) 2009-2025 TigerVNC team
Copyright (C) 2011-2014 Brian P. Hinz
All rights reserved.
diff --git a/java/com/tigervnc/vncviewer/ServerDialog.java b/java/com/tigervnc/vncviewer/ServerDialog.java
index 01f91db2..9c92698e 100644
--- a/java/com/tigervnc/vncviewer/ServerDialog.java
+++ b/java/com/tigervnc/vncviewer/ServerDialog.java
@@ -47,7 +47,7 @@ class ServerDialog extends Dialog implements Runnable {
super(true);
this.vncServerName = vncServerName;
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
- setTitle("VNC viewer: Connection details");
+ setTitle("TigerVNC");
setResizable(false);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
@@ -258,7 +258,7 @@ class ServerDialog extends Dialog implements Runnable {
JOptionPane op =
new JOptionPane(msg, JOptionPane.QUESTION_MESSAGE,
JOptionPane.OK_CANCEL_OPTION, null, options, options[1]);
- JDialog dlg = op.createDialog(this, "TigerVNC Viewer");
+ JDialog dlg = op.createDialog(this, "TigerVNC");
dlg.setIconImage(VncViewer.frameIcon);
dlg.setAlwaysOnTop(true);
dlg.setVisible(true);
diff --git a/java/com/tigervnc/vncviewer/UserPreferences.java b/java/com/tigervnc/vncviewer/UserPreferences.java
index 544774db..44c62343 100644
--- a/java/com/tigervnc/vncviewer/UserPreferences.java
+++ b/java/com/tigervnc/vncviewer/UserPreferences.java
@@ -144,6 +144,11 @@ public class UserPreferences {
}
}
+ public static void delete(String nName, String key) {
+ Preferences node = root.node(nName);
+ node.remove(key);
+ }
+
static LogWriter vlog = new LogWriter("UserPreferences");
}
diff --git a/java/com/tigervnc/vncviewer/Viewport.java b/java/com/tigervnc/vncviewer/Viewport.java
index c293cb7d..3c6f623e 100644
--- a/java/com/tigervnc/vncviewer/Viewport.java
+++ b/java/com/tigervnc/vncviewer/Viewport.java
@@ -167,8 +167,15 @@ class Viewport extends JPanel implements ActionListener {
for (i = 0; i < width*height; i++)
if (data[i*4 + 3] != 0) break;
- if ((i == width*height) && dotWhenNoCursor.getValue()) {
- vlog.debug("Cursor is empty: Using dot");
+ useSystemCursor = false;
+ if ((i == width*height) && alwaysCursor.getValue()) {
+ String cursorTypeStr = cursorType.getValueStr();
+ if (cursorTypeStr.matches("^System$")) {
+ useSystemCursor = true;
+ } else {
+ vlog.debug("Cursor is empty: Using dot");
+ }
+ // Do this anyway to prevent cursor being null
cursor = new BufferedImage(5, 5, BufferedImage.TYPE_INT_ARGB_PRE);
cursor.setRGB(0, 0, 5, 5, dotcursor_xpm, 0, 5);
cursorHotspot.x = cursorHotspot.y = 3;
@@ -200,8 +207,8 @@ class Viewport extends JPanel implements ActionListener {
Graphics2D g2 = tmp.createGraphics();
g2.drawImage(cursor, 0, 0, cw, ch, 0, 0, width, height, null);
g2.dispose();
- x = (int) Math.min(Math.floor((float) x * (float) cw / (float) width), cw - 1);
- y = (int) Math.min(Math.floor((float) y * (float) ch / (float) height), ch - 1);
+ x = (int) Math.min(Math.floor((float) x * (float) cw / (float) width), Math.max(cw - 1, 0));
+ y = (int) Math.min(Math.floor((float) y * (float) ch / (float) height), Math.max(ch - 1, 0));
cursor = tmp;
}
@@ -216,7 +223,10 @@ class Viewport extends JPanel implements ActionListener {
hotspot = new java.awt.Point(x, y);
softCursor = tk.createCustomCursor(img, hotspot, name);
- setCursor(softCursor);
+ if (useSystemCursor)
+ setCursor(java.awt.Cursor.getDefaultCursor());
+ else
+ setCursor(softCursor);
}
public void resize(int x, int y, int w, int h) {
@@ -637,7 +647,7 @@ class Viewport extends JPanel implements ActionListener {
this, ID.OPTIONS, EnumSet.noneOf(MENU.class));
menu_add(contextMenu, "Connection info...", KeyEvent.VK_I,
this, ID.INFO, EnumSet.noneOf(MENU.class));
- menu_add(contextMenu, "About TigerVNC viewer...", KeyEvent.VK_T,
+ menu_add(contextMenu, "About TigerVNC...", KeyEvent.VK_T,
this, ID.ABOUT, EnumSet.of(MENU.DIVIDER));
menu_add(contextMenu, "Dismiss menu", KeyEvent.VK_M,
@@ -830,6 +840,7 @@ class Viewport extends JPanel implements ActionListener {
float scaleRatioX, scaleRatioY;
static BufferedImage cursor;
+ static boolean useSystemCursor = false;
Point cursorHotspot = new Point();
}
diff --git a/java/com/tigervnc/vncviewer/VncViewer.java b/java/com/tigervnc/vncviewer/VncViewer.java
index 4e4364cb..2a372b98 100644
--- a/java/com/tigervnc/vncviewer/VncViewer.java
+++ b/java/com/tigervnc/vncviewer/VncViewer.java
@@ -63,7 +63,7 @@ public class VncViewer implements Runnable {
public static final String aboutText =
new String("TigerVNC Java viewer v%s (%s)%n"+
"Built on %s at %s%n"+
- "Copyright (C) 1999-2024 TigerVNC Team and many others (see README.rst)%n"+
+ "Copyright (C) 1999-2025 TigerVNC team and many others (see README.rst)%n"+
"See https://www.tigervnc.org for information on TigerVNC.");
public static String version = null;
@@ -212,6 +212,8 @@ public class VncViewer implements Runnable {
// Check if the server name in reality is a configuration file
potentiallyLoadConfigurationFile(vncServerName);
+
+ migrateDeprecatedOptions();
}
public static void usage() {
@@ -359,7 +361,7 @@ public class VncViewer implements Runnable {
JOptionPane op =
new JOptionPane(msg, JOptionPane.INFORMATION_MESSAGE,
JOptionPane.DEFAULT_OPTION, VncViewer.logoIcon, options);
- JDialog dlg = op.createDialog(parent, "About TigerVNC viewer for Java");
+ JDialog dlg = op.createDialog(parent, "About TigerVNC");
dlg.setIconImage(VncViewer.frameIcon);
dlg.setAlwaysOnTop(true);
dlg.setVisible(true);
@@ -378,7 +380,7 @@ public class VncViewer implements Runnable {
void reportException(java.lang.Exception e) {
String title, msg = e.getMessage();
int msgType = JOptionPane.ERROR_MESSAGE;
- title = "TigerVNC viewer : Error";
+ title = "TigerVNC : Error";
e.printStackTrace();
JOptionPane.showMessageDialog(null, msg, title, msgType);
}
@@ -449,6 +451,15 @@ public class VncViewer implements Runnable {
}
}
+ static void migrateDeprecatedOptions() {
+ if (dotWhenNoCursor.getValue()) {
+ vlog.info("DotWhenNoCursor is deprecated, set AlwaysCursor to 1 and CursorType to 'Dot' instead");
+
+ alwaysCursor.setParam(true);
+ cursorType.setParam("Dot");
+ }
+ }
+
public static CConn cc;
public static StringParameter config
= new StringParameter("Config",