source: trunk/packages/invirt-vnc-client/OptionsFrame.java @ 2923

Last change on this file since 2923 was 1334, checked in by broder, 16 years ago

sipb-xen-vnc-client -> invirt-vnc-client

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.