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);
}
fullScreen = viewer.fullScreen.getValue();
menuKey = Keysyms.F8;
options = new OptionsDialog(this);
+ options.initDialog();
clipboardDialog = new ClipboardDialog(this);
firstUpdate = true; pendingUpdate = false;
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);
}
}
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() {
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));
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);
}
boolean firstUpdate;
boolean pendingUpdate;
+ int scaleFactor;
+
static LogWriter vlog = new LogWriter("CConn");
}
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(); }
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);
+ }
}
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;
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;
JButton defSaveButton;
UserPrefs defaults;
+ boolean autoScale = false;
+ boolean fixedRatioScale = false;
+
public OptionsDialog(OptionsDialogCallback cb_) {
super(false);
cb = cb_;
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());
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());