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