summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Hinz <bphinz@users.sourceforge.net>2011-09-30 02:47:06 +0000
committerBrian Hinz <bphinz@users.sourceforge.net>2011-09-30 02:47:06 +0000
commit476a8f5e1c0c27b70c838b4bcb12ccef4dcd345c (patch)
tree7d5159ee5fbdaa483293562000aea80471492af5
parentd69bcc4739155fd95427b1875bc7463164c2c2d7 (diff)
downloadtigervnc-476a8f5e1c0c27b70c838b4bcb12ccef4dcd345c.tar.gz
tigervnc-476a8f5e1c0c27b70c838b4bcb12ccef4dcd345c.zip
initial support for client side scaling. Options dialog offers "Auto" and "FixedRatio" but these haven't been implemented yet
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4678 3789f03b-4d11-0410-bbf8-ca57d06f2519
-rw-r--r--java/src/com/tigervnc/vncviewer/CConn.java98
-rw-r--r--java/src/com/tigervnc/vncviewer/DesktopWindow.java40
-rw-r--r--java/src/com/tigervnc/vncviewer/OptionsDialog.java30
-rw-r--r--java/src/com/tigervnc/vncviewer/VncViewer.java12
4 files changed, 145 insertions, 35 deletions
diff --git a/java/src/com/tigervnc/vncviewer/CConn.java b/java/src/com/tigervnc/vncviewer/CConn.java
index be6a8d81..4abcf13b 100644
--- a/java/src/com/tigervnc/vncviewer/CConn.java
+++ b/java/src/com/tigervnc/vncviewer/CConn.java
@@ -94,9 +94,12 @@ class ViewportFrame extends JFrame
addChild(child);
}
- public void setGeometry(int x, int y, int w, int h) {
- pack();
- if (cc.fullScreen) setSize(w, h);
+ public void setGeometry(int x, int y, int w, int h, boolean pack) {
+ if (pack) {
+ pack();
+ } else {
+ setSize(w, h);
+ }
setLocation(x, y);
setBackground(Color.BLACK);
}
@@ -127,6 +130,7 @@ public class CConn extends CConnection
fullScreen = viewer.fullScreen.getValue();
menuKey = Keysyms.F8;
options = new OptionsDialog(this);
+ options.initDialog();
clipboardDialog = new ClipboardDialog(this);
firstUpdate = true; pendingUpdate = false;
@@ -465,27 +469,39 @@ public class CConn extends CConnection
private void reconfigureViewport()
{
- //viewport->setMaxSize(cp.width, cp.height);
+ //viewport.setMaxSize(cp.width, cp.height);
+ boolean pack = true;
+ int w = cp.width;
+ int h = cp.height;
+ Dimension dpySize = viewport.getToolkit().getScreenSize();
+ desktop.setScaledSize();
+ if (!options.autoScale && !options.fixedRatioScale) {
+ w = (int)java.lang.Math.floor(cp.width*scaleFactor/100);
+ h = (int)java.lang.Math.floor(cp.height*scaleFactor/100);
+ }
if (fullScreen) {
- Dimension dpySize = viewport.getToolkit().getScreenSize();
viewport.setExtendedState(JFrame.MAXIMIZED_BOTH);
- viewport.setGeometry(0, 0, dpySize.width, dpySize.height);
+ viewport.setGeometry(0, 0, dpySize.width, dpySize.height, false);
} else {
- int w = cp.width;
- int h = cp.height;
- Dimension dpySize = viewport.getToolkit().getScreenSize();
int wmDecorationWidth = 0;
int wmDecorationHeight = 24;
- if (w + wmDecorationWidth >= dpySize.width)
+ if (w + wmDecorationWidth >= dpySize.width) {
w = dpySize.width - wmDecorationWidth;
- if (h + wmDecorationHeight >= dpySize.height)
+ pack = false;
+ }
+ if (h + wmDecorationHeight >= dpySize.height) {
h = dpySize.height - wmDecorationHeight;
+ pack = false;
+ }
+
+ if (!pack)
+ viewport.setPreferredSize(new Dimension(w,h));
int x = (dpySize.width - w - wmDecorationWidth) / 2;
int y = (dpySize.height - h - wmDecorationHeight)/2;
viewport.setExtendedState(JFrame.NORMAL);
- viewport.setGeometry(x, y, w, h);
+ viewport.setGeometry(x, y, w, h, pack);
}
}
@@ -799,6 +815,25 @@ public class CConn extends CConnection
options.useLocalCursor.setSelected(viewer.useLocalCursor.getValue());
options.fastCopyRect.setSelected(viewer.fastCopyRect.getValue());
options.acceptBell.setSelected(viewer.acceptBell.getValue());
+ options.autoScale = false;
+ options.fixedRatioScale = false;
+ String scaleString = viewer.scalingFactor.getValue();
+ if (scaleString.equals("Auto")) {
+ options.autoScale = true;
+ } else if( scaleString.equals("FixedRatio")) {
+ options.fixedRatioScale = true;
+ } else {
+ digit = Integer.parseInt(scaleString);
+ if (digit >= 1 && digit <= 1000) {
+ options.scalingFactor.setSelectedItem(digit+"%");
+ } else {
+ options.scalingFactor.setSelectedItem(Integer.parseInt(viewer.scalingFactor.getDefaultStr())+"%");
+ }
+ scaleFactor =
+ Integer.parseInt(scaleString.substring(0, scaleString.length()));
+ if (desktop != null)
+ desktop.setScaledSize();
+ }
}
public void getOptions() {
@@ -855,6 +890,24 @@ public class CConn extends CConnection
viewer.sendClipboard.setParam(options.sendClipboard.isSelected());
viewer.fastCopyRect.setParam(options.fastCopyRect.isSelected());
viewer.acceptBell.setParam(options.acceptBell.isSelected());
+ if (options.autoScale) {
+ viewer.scalingFactor.setParam("Auto");
+ } else if(options.fixedRatioScale) {
+ viewer.scalingFactor.setParam("FixedRatio");
+ } else {
+ String scaleString =
+ options.scalingFactor.getSelectedItem().toString();
+ viewer.scalingFactor.setParam(scaleString.substring(0, scaleString.length()-1));
+ int oldScaleFactor = scaleFactor;
+ scaleFactor =
+ Integer.parseInt(scaleString.substring(0, scaleString.length()-1));
+ if (oldScaleFactor != scaleFactor && desktop != null) {
+ //desktop.setScaledSize();
+ reconfigureViewport();
+ viewport.update(viewport.g);
+ }
+ }
+
clipboardDialog.setSendingEnabled(viewer.sendClipboard.getValue());
menuKey = (int)(options.menuKey.getSelectedIndex()+0xFFBE);
F8Menu.f8.setLabel("Send F"+(menuKey-Keysyms.F1+1));
@@ -1096,14 +1149,17 @@ public class CConn extends CConnection
writeModifiers(ev.getModifiers() & ~KeyEvent.ALT_MASK & ~KeyEvent.META_MASK);
- x = ev.getX();
- y = ev.getY();
- if (x < 0) x = 0;
- if (x > cp.width-1) x = cp.width-1;
- if (y < 0) y = 0;
- if (y > cp.height-1) y = cp.height-1;
-
- writer().writePointerEvent(new Point(x, y), buttonMask);
+ if (cp.width != desktop.scaledWidth ||
+ cp.height != desktop.scaledHeight) {
+ int sx = (desktop.scaleWidthRatio == -1)
+ ? ev.getX() : (int)java.lang.Math.floor(ev.getX()/desktop.scaleWidthRatio);
+ int sy = (desktop.scaleHeightRatio == -1)
+ ? ev.getY() : (int)java.lang.Math.floor(ev.getY()/desktop.scaleWidthRatio);
+ ev.translatePoint(sx - ev.getX(), sy - ev.getY());
+ writer().writePointerEvent(new Point(ev.getX(),ev.getY()), buttonMask);
+ } else {
+ writer().writePointerEvent(new Point(ev.getX(),ev.getY()), buttonMask);
+ }
if (buttonMask == 0) writeModifiers(0);
}
@@ -1216,5 +1272,7 @@ public class CConn extends CConnection
boolean firstUpdate;
boolean pendingUpdate;
+ int scaleFactor;
+
static LogWriter vlog = new LogWriter("CConn");
}
diff --git a/java/src/com/tigervnc/vncviewer/DesktopWindow.java b/java/src/com/tigervnc/vncviewer/DesktopWindow.java
index 5e2764bc..ea57669e 100644
--- a/java/src/com/tigervnc/vncviewer/DesktopWindow.java
+++ b/java/src/com/tigervnc/vncviewer/DesktopWindow.java
@@ -86,7 +86,7 @@ class DesktopWindow extends JPanel implements
public void initGraphics() {
cc.viewport.g = cc.viewport.getGraphics();
graphics = getComponentGraphics(cc.viewport.g);
- prepareImage(im.image, -1, -1, this);
+ prepareImage(im.image, scaledWidth, scaledHeight, this);
}
final public PixelFormat getPF() { return im.getPF(); }
@@ -289,21 +289,46 @@ class DesktopWindow extends JPanel implements
cursorAvailable = false;
}
- synchronized public Dimension getPreferredSize() {
- return new Dimension(im.width(), im.height());
+ //
+ // Callback methods to determine geometry of our Component.
+ //
+
+ public Dimension getPreferredSize() {
+ return new Dimension(scaledWidth, scaledHeight);
+ }
+
+ public Dimension getMinimumSize() {
+ return new Dimension(scaledWidth, scaledHeight);
}
- synchronized public Dimension getMinimumSize() {
- return new Dimension(im.width(), im.height());
+ public Dimension getMaximumSize() {
+ return new Dimension(scaledWidth, scaledHeight);
}
public void update(Graphics g) {
//repaint();
}
+ public void setScaledSize() {
+ int w = (int)java.lang.Math.floor(cc.cp.width*cc.scaleFactor/100);
+ int h = (int)java.lang.Math.floor(cc.cp.height*cc.scaleFactor/100);
+ scaledWidth = w;
+ scaledHeight = h;
+ scaleWidthRatio = ((float)w/(float)cc.cp.width);
+ scaleHeightRatio = ((float)h/(float)cc.cp.height);
+ }
+
synchronized public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
- g2.drawImage(im.image, 0, 0, this);
+ g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+ RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+ g2.setRenderingHint(RenderingHints.KEY_RENDERING,
+ RenderingHints.VALUE_RENDER_QUALITY);
+ if (cc.cp.width == scaledWidth && cc.cp.height == scaledHeight) {
+ g2.drawImage(im.image, 0, 0, null);
+ } else {
+ g2.drawImage(im.image, 0, 0, scaledWidth, scaledHeight, null);
+ }
}
@@ -474,6 +499,9 @@ class DesktopWindow extends JPanel implements
java.awt.Cursor softCursor;
static Toolkit tk = Toolkit.getDefaultToolkit();
+ public int scaledWidth = 0, scaledHeight = 0;
+ float scaleWidthRatio, scaleHeightRatio;
+
// the following are only ever accessed by the RFB thread:
boolean invalidRect;
int invalidLeft, invalidRight, invalidTop, invalidBottom;
diff --git a/java/src/com/tigervnc/vncviewer/OptionsDialog.java b/java/src/com/tigervnc/vncviewer/OptionsDialog.java
index f64ed682..0aa148f2 100644
--- a/java/src/com/tigervnc/vncviewer/OptionsDialog.java
+++ b/java/src/com/tigervnc/vncviewer/OptionsDialog.java
@@ -42,7 +42,7 @@ class OptionsDialog extends Dialog implements
OptionsDialogCallback cb;
JPanel FormatPanel, InputsPanel, MiscPanel, DefaultsPanel, SecPanel;
JCheckBox autoSelect, customCompressLevel, noJpeg;
- JComboBox menuKey, compressLevel, qualityLevel ;
+ JComboBox menuKey, compressLevel, qualityLevel, scalingFactor;
ButtonGroup encodingGroup, colourGroup;
JRadioButton zrle, hextile, tight, raw;
JRadioButton fullColour, mediumColour, lowColour, veryLowColour;
@@ -55,6 +55,9 @@ class OptionsDialog extends Dialog implements
JButton defSaveButton;
UserPrefs defaults;
+ boolean autoScale = false;
+ boolean fixedRatioScale = false;
+
public OptionsDialog(OptionsDialogCallback cb_) {
super(false);
cb = cb_;
@@ -142,9 +145,8 @@ class OptionsDialog extends Dialog implements
addGBComponent(viewOnly,InputsPanel, 0, 0, 2, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
addGBComponent(acceptClipboard,InputsPanel, 0, 1, 2, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
addGBComponent(sendClipboard,InputsPanel, 0, 2, 2, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
- addGBComponent(menuKeyLabel,InputsPanel, 0, 3, 1, GridBagConstraints.REMAINDER, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(8,10,0,4));
- addGBComponent(menuKey,InputsPanel, 1, 3, 1, GridBagConstraints.REMAINDER, 0, 0, 2, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(4,4,0,125));
- //((javax.swing.plaf.basic.BasicComboBoxRenderer)menuKey.getRenderer()).setBorder(new EmptyBorder(0,3,0,3));
+ addGBComponent(menuKeyLabel,InputsPanel, 0, 3, 1, GridBagConstraints.REMAINDER, 0, 0, 1, 1, GridBagConstraints.NONE, GridBagConstraints.FIRST_LINE_START, new Insets(8,8,0,4));
+ addGBComponent(menuKey,InputsPanel, 1, 3, 1, GridBagConstraints.REMAINDER, 0, 0, 25, 1, GridBagConstraints.NONE, GridBagConstraints.FIRST_LINE_START, new Insets(4,4,0,4));
// Misc tab
MiscPanel=new JPanel(new GridBagLayout());
@@ -159,11 +161,21 @@ class OptionsDialog extends Dialog implements
fastCopyRect.addItemListener(this);
acceptBell = new JCheckBox("Beep when requested by the server");
acceptBell.addItemListener(this);
- addGBComponent(fullScreen,MiscPanel, 0, 0, 1, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
- addGBComponent(shared,MiscPanel, 0, 1, 1, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
- addGBComponent(useLocalCursor,MiscPanel, 0, 2, 1, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
- addGBComponent(fastCopyRect,MiscPanel, 0, 3, 1, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
- addGBComponent(acceptBell,MiscPanel, 0, 4, 1, GridBagConstraints.REMAINDER, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(4,4,0,4));
+ JLabel scalingFactorLabel = new JLabel("Scaling Factor");
+ Object[] scalingFactors = {
+ //"50%", "75%", "95%", "100%", "105%",
+ "Auto", "Fixed Aspect Ratio", "50%", "75%", "95%", "100%", "105%",
+ "125%", "150%", "175%", "200%", "250%", "300%", "350%", "400%" };
+ scalingFactor = new JComboBox(scalingFactors);
+ scalingFactor.setEditable(true);
+ scalingFactor.addItemListener(this);
+ addGBComponent(fullScreen,MiscPanel, 0, 0, 2, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
+ addGBComponent(shared,MiscPanel, 0, 1, 2, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
+ addGBComponent(useLocalCursor,MiscPanel, 0, 2, 2, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
+ addGBComponent(fastCopyRect,MiscPanel, 0, 3, 2, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(4,4,0,4));
+ addGBComponent(acceptBell,MiscPanel, 0, 4, 2, 1, 0, 0, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, new Insets(4,4,0,4));
+ addGBComponent(scalingFactorLabel,MiscPanel, 0, 5, 1, GridBagConstraints.REMAINDER, 0, 0, 1, 1, GridBagConstraints.NONE, GridBagConstraints.FIRST_LINE_START, new Insets(8,8,0,4));
+ addGBComponent(scalingFactor,MiscPanel, 1, 5, 1, GridBagConstraints.REMAINDER, 0, 0, 25, 1, GridBagConstraints.NONE, GridBagConstraints.FIRST_LINE_START, new Insets(4,4,0,4));
// load/save tab
DefaultsPanel=new JPanel(new GridBagLayout());
diff --git a/java/src/com/tigervnc/vncviewer/VncViewer.java b/java/src/com/tigervnc/vncviewer/VncViewer.java
index c2b39bfe..d548f423 100644
--- a/java/src/com/tigervnc/vncviewer/VncViewer.java
+++ b/java/src/com/tigervnc/vncviewer/VncViewer.java
@@ -233,6 +233,18 @@ public class VncViewer extends java.applet.Applet implements Runnable
= new StringParameter("DesktopSize",
"Reconfigure desktop size on the server on "+
"connect (if possible)", "");
+ 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 "+