| // |
| // Copyright (C) 2001 HorizonLive.com, Inc. All Rights Reserved. |
| // Copyright (C) 2001 Constantin Kaplinsky. All Rights Reserved. |
| // Copyright (C) 2000 Tridia Corporation. All Rights Reserved. |
| // Copyright (C) 1999 AT&T Laboratories Cambridge. 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
| // USA. |
| // |
| |
| // |
| // Options frame. |
| // |
| // This deals with all the options the user can play with. |
| // It sets the encodings array and some booleans. |
| // |
| |
| package com.tigervnc.vncviewer; |
| |
| import java.awt.*; |
| import java.awt.event.*; |
| |
| class OptionsFrame extends Frame |
| implements WindowListener, ActionListener, ItemListener { |
| |
| static String[] names = { |
| "Encoding", |
| "Compression level", |
| "JPEG image quality", |
| "Cursor shape updates", |
| "Use CopyRect", |
| "Restricted colors", |
| "Mouse buttons 2 and 3", |
| "View only", |
| "Scaling factor", |
| "Scale remote cursor", |
| "Share desktop" |
| }; |
| |
| static String[][] values = { |
| { "Auto", "Raw", "RRE", "CoRRE", "Hextile", "Zlib", "Tight", "ZRLE" }, |
| { "Default", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, |
| { "JPEG off", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, |
| { "Enable", "Ignore", "Disable" }, |
| { "Yes", "No" }, |
| { "Yes", "No" }, |
| { "Normal", "Reversed" }, |
| { "Yes", "No" }, |
| { "Auto", "1%", "5%", "10%", "20%", "25%", "50%", "75%", "100%"}, |
| { "No", "50%", "75%", "125%", "150%" }, |
| { "Yes", "No" } |
| }; |
| |
| final int |
| encodingIndex = 0, |
| compressLevelIndex = 1, |
| jpegQualityIndex = 2, |
| cursorUpdatesIndex = 3, |
| useCopyRectIndex = 4, |
| eightBitColorsIndex = 5, |
| mouseButtonIndex = 6, |
| viewOnlyIndex = 7, |
| scalingFactorIndex = 8, |
| scaleCursorIndex = 9, |
| shareDesktopIndex = 10; |
| |
| Label[] labels = new Label[names.length]; |
| Choice[] choices = new Choice[names.length]; |
| Button closeButton; |
| VncViewer viewer; |
| |
| |
| // |
| // The actual data which other classes look at: |
| // |
| |
| int preferredEncoding; |
| int compressLevel; |
| int jpegQuality; |
| boolean useCopyRect; |
| boolean requestCursorUpdates; |
| boolean ignoreCursorUpdates; |
| |
| boolean eightBitColors; |
| |
| boolean reverseMouseButtons2And3; |
| boolean shareDesktop; |
| boolean viewOnly; |
| int scaleCursor; |
| |
| boolean autoScale; |
| int scalingFactor; |
| |
| // |
| // Constructor. Set up the labels and choices from the names and values |
| // arrays. |
| // |
| |
| OptionsFrame(VncViewer v) { |
| super("TigerVNC Options"); |
| |
| viewer = v; |
| |
| GridBagLayout gridbag = new GridBagLayout(); |
| setLayout(gridbag); |
| |
| GridBagConstraints gbc = new GridBagConstraints(); |
| gbc.fill = GridBagConstraints.BOTH; |
| |
| for (int i = 0; i < names.length; i++) { |
| labels[i] = new Label(names[i]); |
| gbc.gridwidth = 1; |
| gridbag.setConstraints(labels[i],gbc); |
| add(labels[i]); |
| |
| choices[i] = new Choice(); |
| gbc.gridwidth = GridBagConstraints.REMAINDER; |
| gridbag.setConstraints(choices[i],gbc); |
| add(choices[i]); |
| choices[i].addItemListener(this); |
| |
| for (int j = 0; j < values[i].length; j++) { |
| choices[i].addItem(values[i][j]); |
| } |
| } |
| |
| closeButton = new Button("Close"); |
| gbc.gridwidth = GridBagConstraints.REMAINDER; |
| gridbag.setConstraints(closeButton, gbc); |
| add(closeButton); |
| closeButton.addActionListener(this); |
| |
| pack(); |
| |
| addWindowListener(this); |
| |
| // Set up defaults |
| |
| choices[encodingIndex].select("Auto"); |
| choices[compressLevelIndex].select("Default"); |
| choices[jpegQualityIndex].select("6"); |
| choices[cursorUpdatesIndex].select("Enable"); |
| choices[useCopyRectIndex].select("Yes"); |
| choices[eightBitColorsIndex].select("No"); |
| choices[mouseButtonIndex].select("Normal"); |
| choices[viewOnlyIndex].select("No"); |
| choices[scaleCursorIndex].select("No"); |
| choices[shareDesktopIndex].select("Yes"); |
| |
| // But let them be overridden by parameters |
| |
| for (int i = 0; i < names.length; i++) { |
| String s = viewer.readParameter(names[i], false); |
| if (s != null) { |
| for (int j = 0; j < values[i].length; j++) { |
| if (s.equalsIgnoreCase(values[i][j])) { |
| choices[i].select(j); |
| } |
| } |
| } |
| } |
| |
| // Get scaling factor from parameters and set it |
| // to gui and class member scalingFactor |
| |
| String s = viewer.readParameter("Scaling Factor", false); |
| if (s == null) s = "100%"; |
| setScalingFactor(s); |
| if (autoScale) { |
| choices[scalingFactorIndex].select("Auto"); |
| } else { |
| choices[scalingFactorIndex].select(s); |
| } |
| |
| // Make the booleans and encodings array correspond to the state of the GUI |
| |
| setEncodings(); |
| setColorFormat(); |
| setOtherOptions(); |
| } |
| |
| // |
| // Set scaling factor class member value |
| // |
| |
| void setScalingFactor(int sf) { |
| setScalingFactor(((Integer)sf).toString()); |
| } |
| |
| void setScalingFactor(String s) { |
| autoScale = false; |
| scalingFactor = 100; |
| if (s != null) { |
| if (s.equalsIgnoreCase("Auto")) { |
| autoScale = true; |
| } else { |
| // Remove the '%' char at the end of string if present. |
| if (s.charAt(s.length() - 1) == '%') { |
| s = s.substring(0, s.length() - 1); |
| } |
| // Convert to an integer. |
| try { |
| scalingFactor = Integer.parseInt(s); |
| } |
| catch (NumberFormatException e) { |
| scalingFactor = 100; |
| } |
| // Make sure scalingFactor is in the range of [1..1000]. |
| if (scalingFactor < 1) { |
| scalingFactor = 1; |
| } else if (scalingFactor > 1000) { |
| scalingFactor = 1000; |
| } |
| } |
| } |
| } |
| |
| |
| // |
| // Disable the shareDesktop option |
| // |
| |
| void disableShareDesktop() { |
| labels[shareDesktopIndex].setEnabled(false); |
| choices[shareDesktopIndex].setEnabled(false); |
| } |
| |
| // |
| // setEncodings looks at the encoding, compression level, JPEG |
| // quality level, cursor shape updates and copyRect choices and sets |
| // corresponding variables properly. Then it calls the VncViewer's |
| // setEncodings method to send a SetEncodings message to the RFB |
| // server. |
| // |
| |
| void setEncodings() { |
| useCopyRect = choices[useCopyRectIndex].getSelectedItem().equals("Yes"); |
| |
| preferredEncoding = RfbProto.EncodingRaw; |
| boolean enableCompressLevel = false; |
| boolean enableQualityLevel = false; |
| |
| if (choices[encodingIndex].getSelectedItem().equals("RRE")) { |
| preferredEncoding = RfbProto.EncodingRRE; |
| } else if (choices[encodingIndex].getSelectedItem().equals("CoRRE")) { |
| preferredEncoding = RfbProto.EncodingCoRRE; |
| } else if (choices[encodingIndex].getSelectedItem().equals("Hextile")) { |
| preferredEncoding = RfbProto.EncodingHextile; |
| } else if (choices[encodingIndex].getSelectedItem().equals("ZRLE")) { |
| preferredEncoding = RfbProto.EncodingZRLE; |
| } else if (choices[encodingIndex].getSelectedItem().equals("Zlib")) { |
| preferredEncoding = RfbProto.EncodingZlib; |
| enableCompressLevel = true; |
| } else if (choices[encodingIndex].getSelectedItem().equals("Tight")) { |
| preferredEncoding = RfbProto.EncodingTight; |
| enableCompressLevel = true; |
| enableQualityLevel = !eightBitColors; |
| } else if (choices[encodingIndex].getSelectedItem().equals("Auto")) { |
| preferredEncoding = -1; |
| enableQualityLevel = !eightBitColors; |
| } |
| |
| // Handle compression level setting. |
| |
| try { |
| compressLevel = |
| Integer.parseInt(choices[compressLevelIndex].getSelectedItem()); |
| } |
| catch (NumberFormatException e) { |
| compressLevel = -1; |
| } |
| if (compressLevel < 1 || compressLevel > 9) { |
| compressLevel = -1; |
| } |
| labels[compressLevelIndex].setEnabled(enableCompressLevel); |
| choices[compressLevelIndex].setEnabled(enableCompressLevel); |
| |
| // Handle JPEG quality setting. |
| |
| try { |
| jpegQuality = |
| Integer.parseInt(choices[jpegQualityIndex].getSelectedItem()); |
| } |
| catch (NumberFormatException e) { |
| jpegQuality = -1; |
| } |
| if (jpegQuality < 0 || jpegQuality > 9) { |
| jpegQuality = -1; |
| } |
| labels[jpegQualityIndex].setEnabled(enableQualityLevel); |
| choices[jpegQualityIndex].setEnabled(enableQualityLevel); |
| |
| // Request cursor shape updates if necessary. |
| |
| requestCursorUpdates = |
| !choices[cursorUpdatesIndex].getSelectedItem().equals("Disable"); |
| |
| if (requestCursorUpdates) { |
| ignoreCursorUpdates = |
| choices[cursorUpdatesIndex].getSelectedItem().equals("Ignore"); |
| } |
| |
| viewer.setEncodings(); |
| } |
| |
| // |
| // setColorFormat sets eightBitColors variable depending on the GUI |
| // setting, causing switches between 8-bit and 24-bit colors mode if |
| // necessary. |
| // |
| |
| void setColorFormat() { |
| |
| eightBitColors = |
| choices[eightBitColorsIndex].getSelectedItem().equals("Yes"); |
| |
| boolean enableJPEG = !eightBitColors && |
| (choices[encodingIndex].getSelectedItem().equals("Tight") || |
| choices[encodingIndex].getSelectedItem().equals("Auto")); |
| |
| labels[jpegQualityIndex].setEnabled(enableJPEG); |
| choices[jpegQualityIndex].setEnabled(enableJPEG); |
| } |
| |
| // |
| // setOtherOptions looks at the "other" choices (ones that do not |
| // cause sending any protocol messages) and sets the boolean flags |
| // appropriately. |
| // |
| |
| void setOtherOptions() { |
| |
| reverseMouseButtons2And3 |
| = choices[mouseButtonIndex].getSelectedItem().equals("Reversed"); |
| |
| viewOnly |
| = choices[viewOnlyIndex].getSelectedItem().equals("Yes"); |
| if (viewer.vc != null) |
| viewer.vc.enableInput(!viewOnly); |
| |
| shareDesktop |
| = choices[shareDesktopIndex].getSelectedItem().equals("Yes"); |
| |
| String scaleString = choices[scaleCursorIndex].getSelectedItem(); |
| if (scaleString.endsWith("%")) |
| scaleString = scaleString.substring(0, scaleString.length() - 1); |
| try { |
| scaleCursor = Integer.parseInt(scaleString); |
| } |
| catch (NumberFormatException e) { |
| scaleCursor = 0; |
| } |
| if (scaleCursor < 10 || scaleCursor > 500) { |
| scaleCursor = 0; |
| } |
| if (requestCursorUpdates && !ignoreCursorUpdates && !viewOnly) { |
| labels[scaleCursorIndex].setEnabled(true); |
| choices[scaleCursorIndex].setEnabled(true); |
| } else { |
| labels[scaleCursorIndex].setEnabled(false); |
| choices[scaleCursorIndex].setEnabled(false); |
| } |
| if (viewer.vc != null) |
| viewer.vc.createSoftCursor(); // update cursor scaling |
| } |
| |
| |
| // |
| // Respond to actions on Choice controls |
| // |
| |
| public void itemStateChanged(ItemEvent evt) { |
| Object source = evt.getSource(); |
| |
| if (source == choices[encodingIndex] || |
| source == choices[compressLevelIndex] || |
| source == choices[jpegQualityIndex] || |
| source == choices[cursorUpdatesIndex] || |
| source == choices[useCopyRectIndex]) { |
| |
| setEncodings(); |
| |
| if (source == choices[cursorUpdatesIndex]) { |
| setOtherOptions(); // update scaleCursor state |
| } |
| |
| } else if (source == choices[eightBitColorsIndex]) { |
| |
| setColorFormat(); |
| |
| } else if (source == choices[mouseButtonIndex] || |
| source == choices[shareDesktopIndex] || |
| source == choices[viewOnlyIndex] || |
| source == choices[scaleCursorIndex]) { |
| |
| setOtherOptions(); |
| |
| } else if (source == choices[scalingFactorIndex]){ |
| // Tell VNC canvas that scaling factor has changed |
| setScalingFactor(choices[scalingFactorIndex].getSelectedItem()); |
| if (viewer.vc != null) |
| viewer.vc.setScalingFactor(scalingFactor); |
| } |
| } |
| |
| // |
| // Respond to button press |
| // |
| |
| public void actionPerformed(ActionEvent evt) { |
| if (evt.getSource() == closeButton) |
| setVisible(false); |
| } |
| |
| // |
| // Respond to window events |
| // |
| |
| public void windowClosing(WindowEvent evt) { |
| setVisible(false); |
| } |
| |
| public void windowActivated(WindowEvent evt) {} |
| public void windowDeactivated(WindowEvent evt) {} |
| public void windowOpened(WindowEvent evt) {} |
| public void windowClosed(WindowEvent evt) {} |
| public void windowIconified(WindowEvent evt) {} |
| public void windowDeiconified(WindowEvent evt) {} |
| } |