You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

OptionsFrame.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  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. // Options frame.
  24. //
  25. // This deals with all the options the user can play with.
  26. // It sets the encodings array and some booleans.
  27. //
  28. import java.awt.*;
  29. import java.awt.event.*;
  30. class OptionsFrame extends Frame
  31. implements WindowListener, ActionListener, ItemListener {
  32. static String[] names = {
  33. "Encoding",
  34. "Compression level",
  35. "JPEG image quality",
  36. "Cursor shape updates",
  37. "Use CopyRect",
  38. "Continuous updates",
  39. "Restricted colors",
  40. "Mouse buttons 2 and 3",
  41. "View only",
  42. "Scale remote cursor",
  43. "Share desktop",
  44. };
  45. static String[][] values = {
  46. { "Auto", "Raw", "RRE", "CoRRE", "Hextile", "Zlib", "Tight", "ZRLE" },
  47. { "Default", "1", "2", "3", "4", "5", "6", "7", "8", "9" },
  48. { "JPEG off", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" },
  49. { "Enable", "Ignore", "Disable" },
  50. { "Yes", "No" },
  51. { "Yes", "No" },
  52. { "Yes", "No" },
  53. { "Normal", "Reversed" },
  54. { "Yes", "No" },
  55. { "No", "50%", "75%", "125%", "150%" },
  56. { "Yes", "No" },
  57. };
  58. final int
  59. encodingIndex = 0,
  60. compressLevelIndex = 1,
  61. jpegQualityIndex = 2,
  62. cursorUpdatesIndex = 3,
  63. useCopyRectIndex = 4,
  64. contUpdatesIndex = 5,
  65. eightBitColorsIndex = 6,
  66. mouseButtonIndex = 7,
  67. viewOnlyIndex = 8,
  68. scaleCursorIndex = 9,
  69. shareDesktopIndex = 10;
  70. Label[] labels = new Label[names.length];
  71. Choice[] choices = new Choice[names.length];
  72. Button closeButton;
  73. VncViewer viewer;
  74. //
  75. // The actual data which other classes look at:
  76. //
  77. int preferredEncoding;
  78. int compressLevel;
  79. int jpegQuality;
  80. boolean useCopyRect;
  81. boolean continuousUpdates;
  82. boolean requestCursorUpdates;
  83. boolean ignoreCursorUpdates;
  84. boolean eightBitColors;
  85. boolean reverseMouseButtons2And3;
  86. boolean shareDesktop;
  87. boolean viewOnly;
  88. int scaleCursor;
  89. boolean autoScale;
  90. int scalingFactor;
  91. //
  92. // Constructor. Set up the labels and choices from the names and values
  93. // arrays.
  94. //
  95. OptionsFrame(VncViewer v) {
  96. super("TightVNC Options");
  97. viewer = v;
  98. GridBagLayout gridbag = new GridBagLayout();
  99. setLayout(gridbag);
  100. GridBagConstraints gbc = new GridBagConstraints();
  101. gbc.fill = GridBagConstraints.BOTH;
  102. for (int i = 0; i < names.length; i++) {
  103. labels[i] = new Label(names[i]);
  104. gbc.gridwidth = 1;
  105. gridbag.setConstraints(labels[i],gbc);
  106. add(labels[i]);
  107. choices[i] = new Choice();
  108. gbc.gridwidth = GridBagConstraints.REMAINDER;
  109. gridbag.setConstraints(choices[i],gbc);
  110. add(choices[i]);
  111. choices[i].addItemListener(this);
  112. for (int j = 0; j < values[i].length; j++) {
  113. choices[i].addItem(values[i][j]);
  114. }
  115. }
  116. closeButton = new Button("Close");
  117. gbc.gridwidth = GridBagConstraints.REMAINDER;
  118. gridbag.setConstraints(closeButton, gbc);
  119. add(closeButton);
  120. closeButton.addActionListener(this);
  121. pack();
  122. addWindowListener(this);
  123. // Set up defaults
  124. choices[encodingIndex].select("Auto");
  125. choices[compressLevelIndex].select("Default");
  126. choices[jpegQualityIndex].select("6");
  127. choices[cursorUpdatesIndex].select("Enable");
  128. choices[useCopyRectIndex].select("Yes");
  129. choices[contUpdatesIndex].select("No");
  130. choices[eightBitColorsIndex].select("No");
  131. choices[mouseButtonIndex].select("Normal");
  132. choices[viewOnlyIndex].select("No");
  133. choices[scaleCursorIndex].select("No");
  134. choices[shareDesktopIndex].select("Yes");
  135. // But let them be overridden by parameters
  136. for (int i = 0; i < names.length; i++) {
  137. String s = viewer.readParameter(names[i], false);
  138. if (s != null) {
  139. for (int j = 0; j < values[i].length; j++) {
  140. if (s.equalsIgnoreCase(values[i][j])) {
  141. choices[i].select(j);
  142. }
  143. }
  144. }
  145. }
  146. // FIXME: Provide some sort of GUI for "Scaling Factor".
  147. autoScale = false;
  148. scalingFactor = 100;
  149. String s = viewer.readParameter("Scaling Factor", false);
  150. if (s != null) {
  151. if (s.equalsIgnoreCase("Auto")) {
  152. autoScale = true;
  153. } else {
  154. // Remove the '%' char at the end of string if present.
  155. if (s.charAt(s.length() - 1) == '%') {
  156. s = s.substring(0, s.length() - 1);
  157. }
  158. // Convert to an integer.
  159. try {
  160. scalingFactor = Integer.parseInt(s);
  161. }
  162. catch (NumberFormatException e) {
  163. scalingFactor = 100;
  164. }
  165. // Make sure scalingFactor is in the range of [1..1000].
  166. if (scalingFactor < 1) {
  167. scalingFactor = 1;
  168. } else if (scalingFactor > 1000) {
  169. scalingFactor = 1000;
  170. }
  171. }
  172. }
  173. // Make the booleans and encodings array correspond to the state of the GUI
  174. setEncodings();
  175. setColorFormat();
  176. setContinuousUpdates();
  177. setOtherOptions();
  178. }
  179. //
  180. // Disable the shareDesktop option
  181. //
  182. void disableShareDesktop() {
  183. labels[shareDesktopIndex].setEnabled(false);
  184. choices[shareDesktopIndex].setEnabled(false);
  185. }
  186. //
  187. // Disable the "Continuous updates" option. This method is called
  188. // when we figure out that the server does not support corresponding
  189. // protocol extensions.
  190. //
  191. void disableContUpdates() {
  192. labels[contUpdatesIndex].setEnabled(false);
  193. choices[contUpdatesIndex].setEnabled(false);
  194. choices[contUpdatesIndex].select("No");
  195. continuousUpdates = false;
  196. }
  197. //
  198. // setEncodings looks at the encoding, compression level, JPEG
  199. // quality level, cursor shape updates and copyRect choices and sets
  200. // corresponding variables properly. Then it calls the VncViewer's
  201. // setEncodings method to send a SetEncodings message to the RFB
  202. // server.
  203. //
  204. void setEncodings() {
  205. useCopyRect = choices[useCopyRectIndex].getSelectedItem().equals("Yes");
  206. preferredEncoding = RfbProto.EncodingRaw;
  207. boolean enableCompressLevel = false;
  208. boolean enableQualityLevel = false;
  209. if (choices[encodingIndex].getSelectedItem().equals("RRE")) {
  210. preferredEncoding = RfbProto.EncodingRRE;
  211. } else if (choices[encodingIndex].getSelectedItem().equals("CoRRE")) {
  212. preferredEncoding = RfbProto.EncodingCoRRE;
  213. } else if (choices[encodingIndex].getSelectedItem().equals("Hextile")) {
  214. preferredEncoding = RfbProto.EncodingHextile;
  215. } else if (choices[encodingIndex].getSelectedItem().equals("ZRLE")) {
  216. preferredEncoding = RfbProto.EncodingZRLE;
  217. } else if (choices[encodingIndex].getSelectedItem().equals("Zlib")) {
  218. preferredEncoding = RfbProto.EncodingZlib;
  219. enableCompressLevel = true;
  220. } else if (choices[encodingIndex].getSelectedItem().equals("Tight")) {
  221. preferredEncoding = RfbProto.EncodingTight;
  222. enableCompressLevel = true;
  223. enableQualityLevel = !eightBitColors;
  224. } else if (choices[encodingIndex].getSelectedItem().equals("Auto")) {
  225. preferredEncoding = -1;
  226. enableQualityLevel = !eightBitColors;
  227. }
  228. // Handle compression level setting.
  229. try {
  230. compressLevel =
  231. Integer.parseInt(choices[compressLevelIndex].getSelectedItem());
  232. }
  233. catch (NumberFormatException e) {
  234. compressLevel = -1;
  235. }
  236. if (compressLevel < 1 || compressLevel > 9) {
  237. compressLevel = -1;
  238. }
  239. labels[compressLevelIndex].setEnabled(enableCompressLevel);
  240. choices[compressLevelIndex].setEnabled(enableCompressLevel);
  241. // Handle JPEG quality setting.
  242. try {
  243. jpegQuality =
  244. Integer.parseInt(choices[jpegQualityIndex].getSelectedItem());
  245. }
  246. catch (NumberFormatException e) {
  247. jpegQuality = -1;
  248. }
  249. if (jpegQuality < 0 || jpegQuality > 9) {
  250. jpegQuality = -1;
  251. }
  252. labels[jpegQualityIndex].setEnabled(enableQualityLevel);
  253. choices[jpegQualityIndex].setEnabled(enableQualityLevel);
  254. // Request cursor shape updates if necessary.
  255. requestCursorUpdates =
  256. !choices[cursorUpdatesIndex].getSelectedItem().equals("Disable");
  257. if (requestCursorUpdates) {
  258. ignoreCursorUpdates =
  259. choices[cursorUpdatesIndex].getSelectedItem().equals("Ignore");
  260. }
  261. viewer.setEncodings();
  262. }
  263. //
  264. // setColorFormat sets eightBitColors variable depending on the GUI
  265. // setting, causing switches between 8-bit and 24-bit colors mode if
  266. // necessary.
  267. //
  268. void setColorFormat() {
  269. eightBitColors =
  270. choices[eightBitColorsIndex].getSelectedItem().equals("Yes");
  271. boolean enableJPEG = !eightBitColors &&
  272. (choices[encodingIndex].getSelectedItem().equals("Tight") ||
  273. choices[encodingIndex].getSelectedItem().equals("Auto"));
  274. labels[jpegQualityIndex].setEnabled(enableJPEG);
  275. choices[jpegQualityIndex].setEnabled(enableJPEG);
  276. }
  277. //
  278. // setContinuousUpdates sets continuousUpdates variable depending on
  279. // the GUI setting. VncViewer monitors the state of this variable and
  280. // send corresponding protocol messages to the server when necessary.
  281. //
  282. void setContinuousUpdates() {
  283. continuousUpdates =
  284. choices[contUpdatesIndex].getSelectedItem().equals("Yes");
  285. }
  286. //
  287. // setOtherOptions looks at the "other" choices (ones that do not
  288. // cause sending any protocol messages) and sets the boolean flags
  289. // appropriately.
  290. //
  291. void setOtherOptions() {
  292. reverseMouseButtons2And3
  293. = choices[mouseButtonIndex].getSelectedItem().equals("Reversed");
  294. viewOnly
  295. = choices[viewOnlyIndex].getSelectedItem().equals("Yes");
  296. if (viewer.vc != null)
  297. viewer.vc.enableInput(!viewOnly);
  298. shareDesktop
  299. = choices[shareDesktopIndex].getSelectedItem().equals("Yes");
  300. String scaleString = choices[scaleCursorIndex].getSelectedItem();
  301. if (scaleString.endsWith("%"))
  302. scaleString = scaleString.substring(0, scaleString.length() - 1);
  303. try {
  304. scaleCursor = Integer.parseInt(scaleString);
  305. }
  306. catch (NumberFormatException e) {
  307. scaleCursor = 0;
  308. }
  309. if (scaleCursor < 10 || scaleCursor > 500) {
  310. scaleCursor = 0;
  311. }
  312. if (requestCursorUpdates && !ignoreCursorUpdates && !viewOnly) {
  313. labels[scaleCursorIndex].setEnabled(true);
  314. choices[scaleCursorIndex].setEnabled(true);
  315. } else {
  316. labels[scaleCursorIndex].setEnabled(false);
  317. choices[scaleCursorIndex].setEnabled(false);
  318. }
  319. if (viewer.vc != null)
  320. viewer.vc.createSoftCursor(); // update cursor scaling
  321. }
  322. //
  323. // Respond to actions on Choice controls
  324. //
  325. public void itemStateChanged(ItemEvent evt) {
  326. Object source = evt.getSource();
  327. if (source == choices[encodingIndex] ||
  328. source == choices[compressLevelIndex] ||
  329. source == choices[jpegQualityIndex] ||
  330. source == choices[cursorUpdatesIndex] ||
  331. source == choices[useCopyRectIndex]) {
  332. setEncodings();
  333. if (source == choices[cursorUpdatesIndex]) {
  334. setOtherOptions(); // update scaleCursor state
  335. }
  336. } else if (source == choices[eightBitColorsIndex]) {
  337. setColorFormat();
  338. } else if (source == choices[contUpdatesIndex]) {
  339. setContinuousUpdates();
  340. } else if (source == choices[mouseButtonIndex] ||
  341. source == choices[shareDesktopIndex] ||
  342. source == choices[viewOnlyIndex] ||
  343. source == choices[scaleCursorIndex]) {
  344. setOtherOptions();
  345. }
  346. }
  347. //
  348. // Respond to button press
  349. //
  350. public void actionPerformed(ActionEvent evt) {
  351. if (evt.getSource() == closeButton)
  352. setVisible(false);
  353. }
  354. //
  355. // Respond to window events
  356. //
  357. public void windowClosing(WindowEvent evt) {
  358. setVisible(false);
  359. }
  360. public void windowActivated(WindowEvent evt) {}
  361. public void windowDeactivated(WindowEvent evt) {}
  362. public void windowOpened(WindowEvent evt) {}
  363. public void windowClosed(WindowEvent evt) {}
  364. public void windowIconified(WindowEvent evt) {}
  365. public void windowDeiconified(WindowEvent evt) {}
  366. }