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.

OptionsDialog.cxx 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. /* Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
  2. *
  3. * This is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This software is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  16. * USA.
  17. */
  18. #ifdef HAVE_CONFIG_H
  19. #include <config.h>
  20. #endif
  21. #include <stdlib.h>
  22. #include <list>
  23. #include <rdr/types.h>
  24. #include <rfb/encodings.h>
  25. #ifdef HAVE_GNUTLS
  26. #include <rfb/Security.h>
  27. #include <rfb/SecurityClient.h>
  28. #include <rfb/CSecurityTLS.h>
  29. #endif
  30. #include "OptionsDialog.h"
  31. #include "fltk_layout.h"
  32. #include "i18n.h"
  33. #include "menukey.h"
  34. #include "parameters.h"
  35. #include <FL/Fl_Tabs.H>
  36. #include <FL/Fl_Button.H>
  37. #include <FL/Fl_Return_Button.H>
  38. using namespace std;
  39. using namespace rdr;
  40. using namespace rfb;
  41. std::map<OptionsCallback*, void*> OptionsDialog::callbacks;
  42. OptionsDialog::OptionsDialog()
  43. : Fl_Window(450, 450, _("VNC Viewer: Connection Options"))
  44. {
  45. int x, y;
  46. Fl_Button *button;
  47. Fl_Tabs *tabs = new Fl_Tabs(OUTER_MARGIN, OUTER_MARGIN,
  48. w() - OUTER_MARGIN*2,
  49. h() - OUTER_MARGIN*2 - INNER_MARGIN - BUTTON_HEIGHT);
  50. {
  51. int tx, ty, tw, th;
  52. tabs->client_area(tx, ty, tw, th, TABS_HEIGHT);
  53. createCompressionPage(tx, ty, tw, th);
  54. createSecurityPage(tx, ty, tw, th);
  55. createInputPage(tx, ty, tw, th);
  56. createMiscPage(tx, ty, tw, th);
  57. }
  58. tabs->end();
  59. x = w() - BUTTON_WIDTH * 2 - INNER_MARGIN - OUTER_MARGIN;
  60. y = h() - BUTTON_HEIGHT - OUTER_MARGIN;
  61. button = new Fl_Button(x, y, BUTTON_WIDTH, BUTTON_HEIGHT, _("Cancel"));
  62. button->callback(this->handleCancel, this);
  63. x += BUTTON_WIDTH + INNER_MARGIN;
  64. button = new Fl_Return_Button(x, y, BUTTON_WIDTH, BUTTON_HEIGHT, _("OK"));
  65. button->callback(this->handleOK, this);
  66. callback(this->handleCancel, this);
  67. set_modal();
  68. }
  69. OptionsDialog::~OptionsDialog()
  70. {
  71. }
  72. void OptionsDialog::showDialog(void)
  73. {
  74. static OptionsDialog *dialog = NULL;
  75. if (!dialog)
  76. dialog = new OptionsDialog();
  77. if (dialog->shown())
  78. return;
  79. dialog->show();
  80. }
  81. void OptionsDialog::addCallback(OptionsCallback *cb, void *data)
  82. {
  83. callbacks[cb] = data;
  84. }
  85. void OptionsDialog::removeCallback(OptionsCallback *cb)
  86. {
  87. callbacks.erase(cb);
  88. }
  89. void OptionsDialog::show(void)
  90. {
  91. loadOptions();
  92. Fl_Window::show();
  93. }
  94. void OptionsDialog::loadOptions(void)
  95. {
  96. /* Compression */
  97. autoselectCheckbox->value(autoSelect);
  98. int encNum = encodingNum(preferredEncoding);
  99. switch (encNum) {
  100. case encodingTight:
  101. tightButton->setonly();
  102. break;
  103. case encodingZRLE:
  104. zrleButton->setonly();
  105. break;
  106. case encodingHextile:
  107. hextileButton->setonly();
  108. break;
  109. case encodingRaw:
  110. rawButton->setonly();
  111. break;
  112. }
  113. if (fullColour)
  114. fullcolorCheckbox->setonly();
  115. else {
  116. switch (lowColourLevel) {
  117. case 0:
  118. verylowcolorCheckbox->setonly();
  119. break;
  120. case 1:
  121. lowcolorCheckbox->setonly();
  122. break;
  123. case 2:
  124. mediumcolorCheckbox->setonly();
  125. break;
  126. }
  127. }
  128. char digit[2] = "0";
  129. compressionCheckbox->value(customCompressLevel);
  130. jpegCheckbox->value(!noJpeg);
  131. digit[0] = '0' + compressLevel;
  132. compressionInput->value(digit);
  133. digit[0] = '0' + qualityLevel;
  134. jpegInput->value(digit);
  135. handleAutoselect(autoselectCheckbox, this);
  136. handleCompression(compressionCheckbox, this);
  137. handleJpeg(jpegCheckbox, this);
  138. #ifdef HAVE_GNUTLS
  139. /* Security */
  140. Security security(SecurityClient::secTypes);
  141. list<U8> secTypes;
  142. list<U8>::iterator iter;
  143. list<U32> secTypesExt;
  144. list<U32>::iterator iterExt;
  145. vencryptCheckbox->value(false);
  146. encNoneCheckbox->value(false);
  147. encTLSCheckbox->value(false);
  148. encX509Checkbox->value(false);
  149. authNoneCheckbox->value(false);
  150. authVncCheckbox->value(false);
  151. authPlainCheckbox->value(false);
  152. secTypes = security.GetEnabledSecTypes();
  153. for (iter = secTypes.begin(); iter != secTypes.end(); ++iter) {
  154. switch (*iter) {
  155. case secTypeVeNCrypt:
  156. vencryptCheckbox->value(true);
  157. break;
  158. case secTypeNone:
  159. encNoneCheckbox->value(true);
  160. authNoneCheckbox->value(true);
  161. break;
  162. case secTypeVncAuth:
  163. encNoneCheckbox->value(true);
  164. authVncCheckbox->value(true);
  165. break;
  166. }
  167. }
  168. secTypesExt = security.GetEnabledExtSecTypes();
  169. for (iterExt = secTypesExt.begin(); iterExt != secTypesExt.end(); ++iterExt) {
  170. switch (*iterExt) {
  171. case secTypePlain:
  172. encNoneCheckbox->value(true);
  173. authPlainCheckbox->value(true);
  174. break;
  175. case secTypeTLSNone:
  176. encTLSCheckbox->value(true);
  177. authNoneCheckbox->value(true);
  178. break;
  179. case secTypeTLSVnc:
  180. encTLSCheckbox->value(true);
  181. authVncCheckbox->value(true);
  182. break;
  183. case secTypeTLSPlain:
  184. encTLSCheckbox->value(true);
  185. authPlainCheckbox->value(true);
  186. break;
  187. case secTypeX509None:
  188. encX509Checkbox->value(true);
  189. authNoneCheckbox->value(true);
  190. break;
  191. case secTypeX509Vnc:
  192. encX509Checkbox->value(true);
  193. authVncCheckbox->value(true);
  194. break;
  195. case secTypeX509Plain:
  196. encX509Checkbox->value(true);
  197. authPlainCheckbox->value(true);
  198. break;
  199. }
  200. }
  201. caInput->value(CSecurityTLS::x509ca);
  202. crlInput->value(CSecurityTLS::x509crl);
  203. handleVencrypt(vencryptCheckbox, this);
  204. handleX509(encX509Checkbox, this);
  205. #endif
  206. /* Input */
  207. const char *menuKeyBuf;
  208. viewOnlyCheckbox->value(viewOnly);
  209. acceptClipboardCheckbox->value(acceptClipboard);
  210. sendClipboardCheckbox->value(sendClipboard);
  211. sendPrimaryCheckbox->value(sendPrimary);
  212. systemKeysCheckbox->value(fullscreenSystemKeys);
  213. menuKeyChoice->value(0);
  214. menuKeyBuf = menuKey;
  215. for (int i = 0; i < getMenuKeySymbolCount(); i++)
  216. if (!strcmp(getMenuKeySymbols()[i].name, menuKeyBuf))
  217. menuKeyChoice->value(i + 1);
  218. /* Misc. */
  219. sharedCheckbox->value(shared);
  220. fullScreenCheckbox->value(fullScreen);
  221. dotCursorCheckbox->value(dotWhenNoCursor);
  222. }
  223. void OptionsDialog::storeOptions(void)
  224. {
  225. /* Compression */
  226. autoSelect.setParam(autoselectCheckbox->value());
  227. if (tightButton->value())
  228. preferredEncoding.setParam(encodingName(encodingTight));
  229. else if (zrleButton->value())
  230. preferredEncoding.setParam(encodingName(encodingZRLE));
  231. else if (hextileButton->value())
  232. preferredEncoding.setParam(encodingName(encodingHextile));
  233. else if (rawButton->value())
  234. preferredEncoding.setParam(encodingName(encodingRaw));
  235. fullColour.setParam(fullcolorCheckbox->value());
  236. if (verylowcolorCheckbox->value())
  237. lowColourLevel.setParam(0);
  238. else if (lowcolorCheckbox->value())
  239. lowColourLevel.setParam(1);
  240. else if (mediumcolorCheckbox->value())
  241. lowColourLevel.setParam(2);
  242. customCompressLevel.setParam(compressionCheckbox->value());
  243. noJpeg.setParam(!jpegCheckbox->value());
  244. compressLevel.setParam(atoi(compressionInput->value()));
  245. qualityLevel.setParam(atoi(jpegInput->value()));
  246. #ifdef HAVE_GNUTLS
  247. /* Security */
  248. Security security;
  249. /* Process security types which don't use encryption */
  250. if (encNoneCheckbox->value()) {
  251. if (authNoneCheckbox->value())
  252. security.EnableSecType(secTypeNone);
  253. if (authVncCheckbox->value())
  254. security.EnableSecType(secTypeVncAuth);
  255. if (vencryptCheckbox->value()) {
  256. if (authPlainCheckbox->value())
  257. security.EnableSecType(secTypePlain);
  258. }
  259. }
  260. if (vencryptCheckbox->value()) {
  261. /* Process security types which use TLS encryption */
  262. if (encTLSCheckbox->value()) {
  263. if (authNoneCheckbox->value())
  264. security.EnableSecType(secTypeTLSNone);
  265. if (authVncCheckbox->value())
  266. security.EnableSecType(secTypeTLSVnc);
  267. if (authPlainCheckbox->value())
  268. security.EnableSecType(secTypeTLSPlain);
  269. }
  270. /* Process security types which use X509 encryption */
  271. if (encX509Checkbox->value()) {
  272. if (authNoneCheckbox->value())
  273. security.EnableSecType(secTypeX509None);
  274. if (authVncCheckbox->value())
  275. security.EnableSecType(secTypeX509Vnc);
  276. if (authPlainCheckbox->value())
  277. security.EnableSecType(secTypeX509Plain);
  278. }
  279. }
  280. CSecurityTLS::x509ca.setParam(caInput->value());
  281. CSecurityTLS::x509crl.setParam(crlInput->value());
  282. #endif
  283. /* Input */
  284. viewOnly.setParam(viewOnlyCheckbox->value());
  285. acceptClipboard.setParam(acceptClipboardCheckbox->value());
  286. sendClipboard.setParam(sendClipboardCheckbox->value());
  287. sendPrimary.setParam(sendPrimaryCheckbox->value());
  288. fullscreenSystemKeys.setParam(systemKeysCheckbox->value());
  289. if (menuKeyChoice->value() == 0)
  290. menuKey.setParam("");
  291. else {
  292. menuKey.setParam(menuKeyChoice->text());
  293. }
  294. /* Misc. */
  295. shared.setParam(sharedCheckbox->value());
  296. fullScreen.setParam(fullScreenCheckbox->value());
  297. dotWhenNoCursor.setParam(dotCursorCheckbox->value());
  298. std::map<OptionsCallback*, void*>::const_iterator iter;
  299. for (iter = callbacks.begin();iter != callbacks.end();++iter)
  300. iter->first(iter->second);
  301. }
  302. void OptionsDialog::createCompressionPage(int tx, int ty, int tw, int th)
  303. {
  304. Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Compression"));
  305. int orig_tx, orig_ty;
  306. int half_width, full_width;
  307. int width, height;
  308. tx += OUTER_MARGIN;
  309. ty += OUTER_MARGIN;
  310. full_width = tw - OUTER_MARGIN * 2;
  311. half_width = (full_width - INNER_MARGIN) / 2;
  312. /* AutoSelect checkbox */
  313. autoselectCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  314. CHECK_MIN_WIDTH,
  315. CHECK_HEIGHT,
  316. _("Auto select")));
  317. autoselectCheckbox->callback(handleAutoselect, this);
  318. ty += CHECK_HEIGHT + INNER_MARGIN;
  319. /* Two columns */
  320. orig_tx = tx;
  321. orig_ty = ty;
  322. /* VNC encoding box */
  323. ty += GROUP_LABEL_OFFSET;
  324. height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 3 + RADIO_HEIGHT * 4;
  325. encodingGroup = new Fl_Group(tx, ty, half_width, height,
  326. _("Preferred encoding"));
  327. encodingGroup->box(FL_ENGRAVED_BOX);
  328. encodingGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
  329. {
  330. tx += GROUP_MARGIN;
  331. ty += GROUP_MARGIN;
  332. width = encodingGroup->w() - GROUP_MARGIN * 2;
  333. tightButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
  334. RADIO_MIN_WIDTH,
  335. RADIO_HEIGHT,
  336. "Tight"));
  337. tightButton->type(FL_RADIO_BUTTON);
  338. ty += RADIO_HEIGHT + TIGHT_MARGIN;
  339. zrleButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
  340. RADIO_MIN_WIDTH,
  341. RADIO_HEIGHT,
  342. "ZRLE"));
  343. zrleButton->type(FL_RADIO_BUTTON);
  344. ty += RADIO_HEIGHT + TIGHT_MARGIN;
  345. hextileButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
  346. RADIO_MIN_WIDTH,
  347. RADIO_HEIGHT,
  348. "Hextile"));
  349. hextileButton->type(FL_RADIO_BUTTON);
  350. ty += RADIO_HEIGHT + TIGHT_MARGIN;
  351. rawButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
  352. RADIO_MIN_WIDTH,
  353. RADIO_HEIGHT,
  354. "Raw"));
  355. rawButton->type(FL_RADIO_BUTTON);
  356. ty += RADIO_HEIGHT + TIGHT_MARGIN;
  357. }
  358. ty += GROUP_MARGIN - TIGHT_MARGIN;
  359. encodingGroup->end();
  360. /* Second column */
  361. tx = orig_tx + half_width + INNER_MARGIN;
  362. ty = orig_ty;
  363. /* Color box */
  364. ty += GROUP_LABEL_OFFSET;
  365. height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 3 + RADIO_HEIGHT * 4;
  366. colorlevelGroup = new Fl_Group(tx, ty, half_width, height, _("Color level"));
  367. colorlevelGroup->box(FL_ENGRAVED_BOX);
  368. colorlevelGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
  369. {
  370. tx += GROUP_MARGIN;
  371. ty += GROUP_MARGIN;
  372. width = colorlevelGroup->w() - GROUP_MARGIN * 2;
  373. fullcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
  374. RADIO_MIN_WIDTH,
  375. RADIO_HEIGHT,
  376. _("Full (all available colors)")));
  377. fullcolorCheckbox->type(FL_RADIO_BUTTON);
  378. ty += RADIO_HEIGHT + TIGHT_MARGIN;
  379. mediumcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
  380. RADIO_MIN_WIDTH,
  381. RADIO_HEIGHT,
  382. _("Medium (256 colors)")));
  383. mediumcolorCheckbox->type(FL_RADIO_BUTTON);
  384. ty += RADIO_HEIGHT + TIGHT_MARGIN;
  385. lowcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
  386. RADIO_MIN_WIDTH,
  387. RADIO_HEIGHT,
  388. _("Low (64 colors)")));
  389. lowcolorCheckbox->type(FL_RADIO_BUTTON);
  390. ty += RADIO_HEIGHT + TIGHT_MARGIN;
  391. verylowcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
  392. RADIO_MIN_WIDTH,
  393. RADIO_HEIGHT,
  394. _("Very low (8 colors)")));
  395. verylowcolorCheckbox->type(FL_RADIO_BUTTON);
  396. ty += RADIO_HEIGHT + TIGHT_MARGIN;
  397. }
  398. ty += GROUP_MARGIN - TIGHT_MARGIN;
  399. colorlevelGroup->end();
  400. /* Back to normal */
  401. tx = orig_tx;
  402. ty += INNER_MARGIN;
  403. /* Checkboxes */
  404. compressionCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  405. CHECK_MIN_WIDTH,
  406. CHECK_HEIGHT,
  407. _("Custom compression level:")));
  408. compressionCheckbox->callback(handleCompression, this);
  409. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  410. compressionInput = new Fl_Int_Input(tx + INDENT, ty,
  411. INPUT_HEIGHT, INPUT_HEIGHT,
  412. _("level (1=fast, 6=best [4-6 are rarely useful])"));
  413. compressionInput->align(FL_ALIGN_RIGHT);
  414. ty += INPUT_HEIGHT + INNER_MARGIN;
  415. jpegCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  416. CHECK_MIN_WIDTH,
  417. CHECK_HEIGHT,
  418. _("Allow JPEG compression:")));
  419. jpegCheckbox->callback(handleJpeg, this);
  420. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  421. jpegInput = new Fl_Int_Input(tx + INDENT, ty,
  422. INPUT_HEIGHT, INPUT_HEIGHT,
  423. _("quality (0=poor, 9=best)"));
  424. jpegInput->align(FL_ALIGN_RIGHT);
  425. ty += INPUT_HEIGHT + INNER_MARGIN;
  426. group->end();
  427. }
  428. void OptionsDialog::createSecurityPage(int tx, int ty, int tw, int th)
  429. {
  430. #ifdef HAVE_GNUTLS
  431. Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Security"));
  432. int orig_tx;
  433. int width, height;
  434. tx += OUTER_MARGIN;
  435. ty += OUTER_MARGIN;
  436. width = tw - OUTER_MARGIN * 2;
  437. orig_tx = tx;
  438. /* Security */
  439. vencryptCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  440. CHECK_MIN_WIDTH,
  441. CHECK_HEIGHT,
  442. _("Extended encryption and authentication methods (VeNCrypt)")));
  443. vencryptCheckbox->callback(handleVencrypt, this);
  444. ty += CHECK_HEIGHT + INNER_MARGIN;
  445. /* Encryption */
  446. ty += GROUP_LABEL_OFFSET;
  447. height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 4 + CHECK_HEIGHT * 3 + (INPUT_LABEL_OFFSET + INPUT_HEIGHT) * 2;
  448. encryptionGroup = new Fl_Group(tx, ty, width, height, _("Encryption"));
  449. encryptionGroup->box(FL_ENGRAVED_BOX);
  450. encryptionGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
  451. {
  452. tx += GROUP_MARGIN;
  453. ty += GROUP_MARGIN;
  454. encNoneCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  455. CHECK_MIN_WIDTH,
  456. CHECK_HEIGHT,
  457. _("None")));
  458. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  459. encTLSCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  460. CHECK_MIN_WIDTH,
  461. CHECK_HEIGHT,
  462. _("TLS with anonymous certificates")));
  463. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  464. encX509Checkbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  465. CHECK_MIN_WIDTH,
  466. CHECK_HEIGHT,
  467. _("TLS with X509 certificates")));
  468. encX509Checkbox->callback(handleX509, this);
  469. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  470. ty += INPUT_LABEL_OFFSET;
  471. caInput = new Fl_Input(tx + INDENT, ty,
  472. width - GROUP_MARGIN*2 - INDENT, INPUT_HEIGHT,
  473. _("Path to X509 CA certificate"));
  474. caInput->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
  475. ty += INPUT_HEIGHT + TIGHT_MARGIN;
  476. ty += INPUT_LABEL_OFFSET;
  477. crlInput = new Fl_Input(tx + INDENT, ty,
  478. width - GROUP_MARGIN*2 - INDENT, INPUT_HEIGHT,
  479. _("Path to X509 CRL file"));
  480. crlInput->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
  481. ty += INPUT_HEIGHT + TIGHT_MARGIN;
  482. }
  483. ty += GROUP_MARGIN - TIGHT_MARGIN;
  484. encryptionGroup->end();
  485. /* Back to normal */
  486. tx = orig_tx;
  487. ty += INNER_MARGIN;
  488. /* Authentication */
  489. /* Encryption */
  490. ty += GROUP_LABEL_OFFSET;
  491. height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 2 + CHECK_HEIGHT * 3;
  492. authenticationGroup = new Fl_Group(tx, ty, width, height, _("Authentication"));
  493. authenticationGroup->box(FL_ENGRAVED_BOX);
  494. authenticationGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
  495. {
  496. tx += GROUP_MARGIN;
  497. ty += GROUP_MARGIN;
  498. authNoneCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  499. CHECK_MIN_WIDTH,
  500. CHECK_HEIGHT,
  501. _("None")));
  502. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  503. authVncCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  504. CHECK_MIN_WIDTH,
  505. CHECK_HEIGHT,
  506. _("Standard VNC (insecure without encryption)")));
  507. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  508. authPlainCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  509. CHECK_MIN_WIDTH,
  510. CHECK_HEIGHT,
  511. _("Username and password (insecure without encryption)")));
  512. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  513. }
  514. ty += GROUP_MARGIN - TIGHT_MARGIN;
  515. authenticationGroup->end();
  516. /* Back to normal */
  517. tx = orig_tx;
  518. ty += INNER_MARGIN;
  519. group->end();
  520. #endif
  521. }
  522. void OptionsDialog::createInputPage(int tx, int ty, int tw, int th)
  523. {
  524. Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Input"));
  525. tx += OUTER_MARGIN;
  526. ty += OUTER_MARGIN;
  527. viewOnlyCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  528. CHECK_MIN_WIDTH,
  529. CHECK_HEIGHT,
  530. _("View only (ignore mouse and keyboard)")));
  531. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  532. acceptClipboardCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  533. CHECK_MIN_WIDTH,
  534. CHECK_HEIGHT,
  535. _("Accept clipboard from server")));
  536. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  537. sendClipboardCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  538. CHECK_MIN_WIDTH,
  539. CHECK_HEIGHT,
  540. _("Send clipboard to server")));
  541. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  542. sendPrimaryCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  543. CHECK_MIN_WIDTH,
  544. CHECK_HEIGHT,
  545. _("Send primary selection and cut buffer as clipboard")));
  546. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  547. systemKeysCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  548. CHECK_MIN_WIDTH,
  549. CHECK_HEIGHT,
  550. _("Pass system keys directly to server (full screen)")));
  551. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  552. menuKeyChoice = new Fl_Choice(LBLLEFT(tx, ty, 150, CHOICE_HEIGHT, _("Menu key")));
  553. menuKeyChoice->add(_("None"), 0, NULL, (void*)0, FL_MENU_DIVIDER);
  554. for (int i = 0; i < getMenuKeySymbolCount(); i++)
  555. menuKeyChoice->add(getMenuKeySymbols()[i].name, 0, NULL, 0, 0);
  556. ty += CHOICE_HEIGHT + TIGHT_MARGIN;
  557. group->end();
  558. }
  559. void OptionsDialog::createMiscPage(int tx, int ty, int tw, int th)
  560. {
  561. Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Misc."));
  562. tx += OUTER_MARGIN;
  563. ty += OUTER_MARGIN;
  564. sharedCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  565. CHECK_MIN_WIDTH,
  566. CHECK_HEIGHT,
  567. _("Shared (don't disconnect other viewers)")));
  568. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  569. fullScreenCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  570. CHECK_MIN_WIDTH,
  571. CHECK_HEIGHT,
  572. _("Full-screen mode")));
  573. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  574. dotCursorCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
  575. CHECK_MIN_WIDTH,
  576. CHECK_HEIGHT,
  577. _("Show dot when no cursor")));
  578. ty += CHECK_HEIGHT + TIGHT_MARGIN;
  579. group->end();
  580. }
  581. void OptionsDialog::handleAutoselect(Fl_Widget *widget, void *data)
  582. {
  583. OptionsDialog *dialog = (OptionsDialog*)data;
  584. if (dialog->autoselectCheckbox->value()) {
  585. dialog->encodingGroup->deactivate();
  586. dialog->colorlevelGroup->deactivate();
  587. } else {
  588. dialog->encodingGroup->activate();
  589. dialog->colorlevelGroup->activate();
  590. }
  591. // JPEG setting is also affected by autoselection
  592. dialog->handleJpeg(dialog->jpegCheckbox, dialog);
  593. }
  594. void OptionsDialog::handleCompression(Fl_Widget *widget, void *data)
  595. {
  596. OptionsDialog *dialog = (OptionsDialog*)data;
  597. if (dialog->compressionCheckbox->value())
  598. dialog->compressionInput->activate();
  599. else
  600. dialog->compressionInput->deactivate();
  601. }
  602. void OptionsDialog::handleJpeg(Fl_Widget *widget, void *data)
  603. {
  604. OptionsDialog *dialog = (OptionsDialog*)data;
  605. if (dialog->jpegCheckbox->value() &&
  606. !dialog->autoselectCheckbox->value())
  607. dialog->jpegInput->activate();
  608. else
  609. dialog->jpegInput->deactivate();
  610. }
  611. void OptionsDialog::handleVencrypt(Fl_Widget *widget, void *data)
  612. {
  613. OptionsDialog *dialog = (OptionsDialog*)data;
  614. if (dialog->vencryptCheckbox->value()) {
  615. dialog->encryptionGroup->activate();
  616. dialog->authPlainCheckbox->activate();
  617. } else {
  618. dialog->encryptionGroup->deactivate();
  619. dialog->authPlainCheckbox->deactivate();
  620. }
  621. }
  622. void OptionsDialog::handleX509(Fl_Widget *widget, void *data)
  623. {
  624. OptionsDialog *dialog = (OptionsDialog*)data;
  625. if (dialog->encX509Checkbox->value()) {
  626. dialog->caInput->activate();
  627. dialog->crlInput->activate();
  628. } else {
  629. dialog->caInput->deactivate();
  630. dialog->crlInput->deactivate();
  631. }
  632. }
  633. void OptionsDialog::handleCancel(Fl_Widget *widget, void *data)
  634. {
  635. OptionsDialog *dialog = (OptionsDialog*)data;
  636. dialog->hide();
  637. }
  638. void OptionsDialog::handleOK(Fl_Widget *widget, void *data)
  639. {
  640. OptionsDialog *dialog = (OptionsDialog*)data;
  641. dialog->hide();
  642. dialog->storeOptions();
  643. }