source: trunk/vnc/vnc_javasrc/OptionsFrame.java @ 233

Last change on this file since 233 was 66, checked in by quentin, 17 years ago

Initial checkin of modified Java VNC viewer for use as remote console

File size: 11.4 KB
Line 
1//
2//  Copyright (C) 2001 HorizonLive.com, Inc.  All Rights Reserved.
3//  Copyright (C) 2001 Constantin Kaplinsky.  All Rights Reserved.
4//  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved.
5//  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
6//
7//  This is free software; you can redistribute it and/or modify
8//  it under the terms of the GNU General Public License as published by
9//  the Free Software Foundation; either version 2 of the License, or
10//  (at your option) any later version.
11//
12//  This software is distributed in the hope that it will be useful,
13//  but WITHOUT ANY WARRANTY; without even the implied warranty of
14//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15//  GNU General Public License for more details.
16//
17//  You should have received a copy of the GNU General Public License
18//  along with this software; if not, write to the Free Software
19//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
20//  USA.
21//
22
23//
24// Options frame.
25//
26// This deals with all the options the user can play with.
27// It sets the encodings array and some booleans.
28//
29
30import java.awt.*;
31import java.awt.event.*;
32
33class OptionsFrame extends Frame
34  implements WindowListener, ActionListener, ItemListener {
35
36  static String[] names = {
37    "Encoding",
38    "Compression level",
39    "JPEG image quality",
40    "Cursor shape updates",
41    "Use CopyRect",
42    "Restricted colors",
43    "Mouse buttons 2 and 3",
44    "View only",
45    "Scale remote cursor",
46    "Share desktop",
47  };
48
49  static String[][] values = {
50    { "Auto", "Raw", "RRE", "CoRRE", "Hextile", "Zlib", "Tight", "ZRLE" },
51    { "Default", "1", "2", "3", "4", "5", "6", "7", "8", "9" },
52    { "JPEG off", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" },
53    { "Enable", "Ignore", "Disable" },
54    { "Yes", "No" },
55    { "Yes", "No" },
56    { "Normal", "Reversed" },
57    { "Yes", "No" },
58    { "No", "50%", "75%", "125%", "150%" },
59    { "Yes", "No" },
60  };
61
62  final int
63    encodingIndex        = 0,
64    compressLevelIndex   = 1,
65    jpegQualityIndex     = 2,
66    cursorUpdatesIndex   = 3,
67    useCopyRectIndex     = 4,
68    eightBitColorsIndex  = 5,
69    mouseButtonIndex     = 6,
70    viewOnlyIndex        = 7,
71    scaleCursorIndex     = 8,
72    shareDesktopIndex    = 9;
73
74  Label[] labels = new Label[names.length];
75  Choice[] choices = new Choice[names.length];
76  Button closeButton;
77  VncViewer viewer;
78
79
80  //
81  // The actual data which other classes look at:
82  //
83
84  int preferredEncoding;
85  int compressLevel;
86  int jpegQuality;
87  boolean useCopyRect;
88  boolean requestCursorUpdates;
89  boolean ignoreCursorUpdates;
90
91  boolean eightBitColors;
92
93  boolean reverseMouseButtons2And3;
94  boolean shareDesktop;
95  boolean viewOnly;
96  int scaleCursor;
97
98  boolean autoScale;
99  int scalingFactor;
100
101  //
102  // Constructor.  Set up the labels and choices from the names and values
103  // arrays.
104  //
105
106  OptionsFrame(VncViewer v) {
107    super("TightVNC Options");
108
109    viewer = v;
110
111    GridBagLayout gridbag = new GridBagLayout();
112    setLayout(gridbag);
113
114    GridBagConstraints gbc = new GridBagConstraints();
115    gbc.fill = GridBagConstraints.BOTH;
116
117    for (int i = 0; i < names.length; i++) {
118      labels[i] = new Label(names[i]);
119      gbc.gridwidth = 1;
120      gridbag.setConstraints(labels[i],gbc);
121      add(labels[i]);
122
123      choices[i] = new Choice();
124      gbc.gridwidth = GridBagConstraints.REMAINDER;
125      gridbag.setConstraints(choices[i],gbc);
126      add(choices[i]);
127      choices[i].addItemListener(this);
128
129      for (int j = 0; j < values[i].length; j++) {
130        choices[i].addItem(values[i][j]);
131      }
132    }
133
134    closeButton = new Button("Close");
135    gbc.gridwidth = GridBagConstraints.REMAINDER;
136    gridbag.setConstraints(closeButton, gbc);
137    add(closeButton);
138    closeButton.addActionListener(this);
139
140    pack();
141
142    addWindowListener(this);
143
144    // Set up defaults
145
146    choices[encodingIndex].select("Auto");
147    choices[compressLevelIndex].select("Default");
148    choices[jpegQualityIndex].select("6");
149    choices[cursorUpdatesIndex].select("Enable");
150    choices[useCopyRectIndex].select("Yes");
151    choices[eightBitColorsIndex].select("No");
152    choices[mouseButtonIndex].select("Normal");
153    choices[viewOnlyIndex].select("No");
154    choices[scaleCursorIndex].select("No");
155    choices[shareDesktopIndex].select("Yes");
156
157    // But let them be overridden by parameters
158
159    for (int i = 0; i < names.length; i++) {
160      String s = viewer.readParameter(names[i], false);
161      if (s != null) {
162        for (int j = 0; j < values[i].length; j++) {
163          if (s.equalsIgnoreCase(values[i][j])) {
164            choices[i].select(j);
165          }
166        }
167      }
168    }
169
170    // FIXME: Provide some sort of GUI for "Scaling Factor".
171
172    autoScale = false;
173    scalingFactor = 100;
174    String s = viewer.readParameter("Scaling Factor", false);
175    if (s != null) {
176      if (s.equalsIgnoreCase("Auto")) {
177        autoScale = true;
178      } else {
179        // Remove the '%' char at the end of string if present.
180        if (s.charAt(s.length() - 1) == '%') {
181          s = s.substring(0, s.length() - 1);
182        }
183        // Convert to an integer.
184        try {
185          scalingFactor = Integer.parseInt(s);
186        }
187        catch (NumberFormatException e) {
188          scalingFactor = 100;
189        }
190        // Make sure scalingFactor is in the range of [1..1000].
191        if (scalingFactor < 1) {
192          scalingFactor = 1;
193        } else if (scalingFactor > 1000) {
194          scalingFactor = 1000;
195        }
196      }
197    }
198
199    // Make the booleans and encodings array correspond to the state of the GUI
200
201    setEncodings();
202    setColorFormat();
203    setOtherOptions();
204  }
205
206
207  //
208  // Disable the shareDesktop option
209  //
210
211  void disableShareDesktop() {
212    labels[shareDesktopIndex].setEnabled(false);
213    choices[shareDesktopIndex].setEnabled(false);
214  }
215
216
217  //
218  // setEncodings looks at the encoding, compression level, JPEG
219  // quality level, cursor shape updates and copyRect choices and sets
220  // corresponding variables properly. Then it calls the VncViewer's
221  // setEncodings method to send a SetEncodings message to the RFB
222  // server.
223  //
224
225  void setEncodings() {
226    useCopyRect = choices[useCopyRectIndex].getSelectedItem().equals("Yes");
227
228    preferredEncoding = RfbProto.EncodingRaw;
229    boolean enableCompressLevel = false;
230    boolean enableQualityLevel = false;
231
232    if (choices[encodingIndex].getSelectedItem().equals("RRE")) {
233      preferredEncoding = RfbProto.EncodingRRE;
234    } else if (choices[encodingIndex].getSelectedItem().equals("CoRRE")) {
235      preferredEncoding = RfbProto.EncodingCoRRE;
236    } else if (choices[encodingIndex].getSelectedItem().equals("Hextile")) {
237      preferredEncoding = RfbProto.EncodingHextile;
238    } else if (choices[encodingIndex].getSelectedItem().equals("ZRLE")) {
239      preferredEncoding = RfbProto.EncodingZRLE;
240    } else if (choices[encodingIndex].getSelectedItem().equals("Zlib")) {
241      preferredEncoding = RfbProto.EncodingZlib;
242      enableCompressLevel = true;
243    } else if (choices[encodingIndex].getSelectedItem().equals("Tight")) {
244      preferredEncoding = RfbProto.EncodingTight;
245      enableCompressLevel = true;
246      enableQualityLevel = !eightBitColors;
247    } else if (choices[encodingIndex].getSelectedItem().equals("Auto")) {
248      preferredEncoding = -1;
249      enableQualityLevel = !eightBitColors;
250    }
251
252    // Handle compression level setting.
253
254    try {
255      compressLevel =
256        Integer.parseInt(choices[compressLevelIndex].getSelectedItem());
257    }
258    catch (NumberFormatException e) {
259      compressLevel = -1;
260    }
261    if (compressLevel < 1 || compressLevel > 9) {
262      compressLevel = -1;
263    }
264    labels[compressLevelIndex].setEnabled(enableCompressLevel);
265    choices[compressLevelIndex].setEnabled(enableCompressLevel);
266
267    // Handle JPEG quality setting.
268
269    try {
270      jpegQuality =
271        Integer.parseInt(choices[jpegQualityIndex].getSelectedItem());
272    }
273    catch (NumberFormatException e) {
274      jpegQuality = -1;
275    }
276    if (jpegQuality < 0 || jpegQuality > 9) {
277      jpegQuality = -1;
278    }
279    labels[jpegQualityIndex].setEnabled(enableQualityLevel);
280    choices[jpegQualityIndex].setEnabled(enableQualityLevel);
281
282    // Request cursor shape updates if necessary.
283
284    requestCursorUpdates =
285      !choices[cursorUpdatesIndex].getSelectedItem().equals("Disable");
286
287    if (requestCursorUpdates) {
288      ignoreCursorUpdates =
289        choices[cursorUpdatesIndex].getSelectedItem().equals("Ignore");
290    }
291
292    viewer.setEncodings();
293  }
294
295  //
296  // setColorFormat sets eightBitColors variable depending on the GUI
297  // setting, causing switches between 8-bit and 24-bit colors mode if
298  // necessary.
299  //
300
301  void setColorFormat() {
302
303    eightBitColors =
304      choices[eightBitColorsIndex].getSelectedItem().equals("Yes");
305
306    boolean enableJPEG = !eightBitColors &&
307      (choices[encodingIndex].getSelectedItem().equals("Tight") ||
308       choices[encodingIndex].getSelectedItem().equals("Auto"));
309
310    labels[jpegQualityIndex].setEnabled(enableJPEG);
311    choices[jpegQualityIndex].setEnabled(enableJPEG);
312  }
313
314  //
315  // setOtherOptions looks at the "other" choices (ones which don't set the
316  // encoding or the color format) and sets the boolean flags appropriately.
317  //
318
319  void setOtherOptions() {
320
321    reverseMouseButtons2And3
322      = choices[mouseButtonIndex].getSelectedItem().equals("Reversed");
323
324    viewOnly
325      = choices[viewOnlyIndex].getSelectedItem().equals("Yes");
326    if (viewer.vc != null)
327      viewer.vc.enableInput(!viewOnly);
328
329    shareDesktop
330      = choices[shareDesktopIndex].getSelectedItem().equals("Yes");
331
332    String scaleString = choices[scaleCursorIndex].getSelectedItem();
333    if (scaleString.endsWith("%"))
334      scaleString = scaleString.substring(0, scaleString.length() - 1);
335    try {
336      scaleCursor = Integer.parseInt(scaleString);
337    }
338    catch (NumberFormatException e) {
339      scaleCursor = 0;
340    }
341    if (scaleCursor < 10 || scaleCursor > 500) {
342      scaleCursor = 0;
343    }
344    if (requestCursorUpdates && !ignoreCursorUpdates && !viewOnly) {
345      labels[scaleCursorIndex].setEnabled(true);
346      choices[scaleCursorIndex].setEnabled(true);
347    } else {
348      labels[scaleCursorIndex].setEnabled(false);
349      choices[scaleCursorIndex].setEnabled(false);
350    }
351    if (viewer.vc != null)
352      viewer.vc.createSoftCursor(); // update cursor scaling
353  }
354
355
356  //
357  // Respond to actions on Choice controls
358  //
359
360  public void itemStateChanged(ItemEvent evt) {
361    Object source = evt.getSource();
362
363    if (source == choices[encodingIndex] ||
364        source == choices[compressLevelIndex] ||
365        source == choices[jpegQualityIndex] ||
366        source == choices[cursorUpdatesIndex] ||
367        source == choices[useCopyRectIndex]) {
368
369      setEncodings();
370
371      if (source == choices[cursorUpdatesIndex]) {
372        setOtherOptions();      // update scaleCursor state
373      }
374
375    } else if (source == choices[eightBitColorsIndex]) {
376
377      setColorFormat();
378
379    } else if (source == choices[mouseButtonIndex] ||
380               source == choices[shareDesktopIndex] ||
381               source == choices[viewOnlyIndex] ||
382               source == choices[scaleCursorIndex]) {
383
384      setOtherOptions();
385    }
386  }
387
388  //
389  // Respond to button press
390  //
391
392  public void actionPerformed(ActionEvent evt) {
393    if (evt.getSource() == closeButton)
394      setVisible(false);
395  }
396
397  //
398  // Respond to window events
399  //
400
401  public void windowClosing(WindowEvent evt) {
402    setVisible(false);
403  }
404
405  public void windowActivated(WindowEvent evt) {}
406  public void windowDeactivated(WindowEvent evt) {}
407  public void windowOpened(WindowEvent evt) {}
408  public void windowClosed(WindowEvent evt) {}
409  public void windowIconified(WindowEvent evt) {}
410  public void windowDeiconified(WindowEvent evt) {}
411}
Note: See TracBrowser for help on using the repository browser.