blob: f77466ecba94e952ea7def39f4ba04b5e1d1be76 [file] [log] [blame]
Pierre Ossmand463b572011-05-16 12:04:43 +00001/* 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
Peter Åstrandc359f362011-08-23 12:04:46 +000019#ifdef HAVE_CONFIG_H
20#include <config.h>
21#endif
22
Pierre Ossman61fd4862011-05-16 12:46:51 +000023#include <stdlib.h>
24
Pierre Ossmand463b572011-05-16 12:04:43 +000025#include <list>
26
Pierre Ossmand463b572011-05-16 12:04:43 +000027#include <rdr/types.h>
28#include <rfb/encodings.h>
29
30#ifdef HAVE_GNUTLS
31#include <rfb/Security.h>
32#include <rfb/SecurityClient.h>
33#include <rfb/CSecurityTLS.h>
34#endif
35
36#include "OptionsDialog.h"
37#include "fltk_layout.h"
38#include "i18n.h"
Martin Koegler498ef462011-09-04 07:04:43 +000039#include "menukey.h"
Pierre Ossmand463b572011-05-16 12:04:43 +000040#include "parameters.h"
41
DRCb65bb932011-06-24 03:17:00 +000042#include <FL/Fl_Tabs.H>
43#include <FL/Fl_Button.H>
44#include <FL/Fl_Return_Button.H>
45
Pierre Ossmand463b572011-05-16 12:04:43 +000046using namespace std;
47using namespace rdr;
48using namespace rfb;
49
Pierre Ossman0c41e1d2011-05-17 09:36:04 +000050std::map<OptionsCallback*, void*> OptionsDialog::callbacks;
51
Pierre Ossmand463b572011-05-16 12:04:43 +000052OptionsDialog::OptionsDialog()
53 : Fl_Window(450, 450, _("VNC Viewer: Connection Options"))
54{
55 int x, y;
56 Fl_Button *button;
57
58 Fl_Tabs *tabs = new Fl_Tabs(OUTER_MARGIN, OUTER_MARGIN,
59 w() - OUTER_MARGIN*2,
60 h() - OUTER_MARGIN*2 - INNER_MARGIN - BUTTON_HEIGHT);
61
62 {
63 int tx, ty, tw, th;
64
65 tabs->client_area(tx, ty, tw, th, TABS_HEIGHT);
66
67 createCompressionPage(tx, ty, tw, th);
68 createSecurityPage(tx, ty, tw, th);
69 createInputPage(tx, ty, tw, th);
70 createMiscPage(tx, ty, tw, th);
71 }
72
73 tabs->end();
74
75 x = w() - BUTTON_WIDTH * 2 - INNER_MARGIN - OUTER_MARGIN;
76 y = h() - BUTTON_HEIGHT - OUTER_MARGIN;
77
78 button = new Fl_Button(x, y, BUTTON_WIDTH, BUTTON_HEIGHT, _("Cancel"));
79 button->callback(this->handleCancel, this);
80
81 x += BUTTON_WIDTH + INNER_MARGIN;
82
83 button = new Fl_Return_Button(x, y, BUTTON_WIDTH, BUTTON_HEIGHT, _("OK"));
84 button->callback(this->handleOK, this);
85
86 callback(this->handleCancel, this);
87
88 set_modal();
89}
90
91
92OptionsDialog::~OptionsDialog()
93{
94}
95
96
97void OptionsDialog::showDialog(void)
98{
99 static OptionsDialog *dialog = NULL;
100
101 if (!dialog)
102 dialog = new OptionsDialog();
103
104 if (dialog->shown())
105 return;
106
107 dialog->show();
108}
109
110
Pierre Ossman0c41e1d2011-05-17 09:36:04 +0000111void OptionsDialog::addCallback(OptionsCallback *cb, void *data)
112{
113 callbacks[cb] = data;
114}
115
116
117void OptionsDialog::removeCallback(OptionsCallback *cb)
118{
119 callbacks.erase(cb);
120}
121
122
Pierre Ossmand463b572011-05-16 12:04:43 +0000123void OptionsDialog::show(void)
124{
Pierre Ossman33a233b2011-09-30 12:21:58 +0000125 /* show() gets called for raise events as well */
126 if (!shown())
127 loadOptions();
Pierre Ossmand463b572011-05-16 12:04:43 +0000128
129 Fl_Window::show();
130}
131
132
133void OptionsDialog::loadOptions(void)
134{
135 /* Compression */
136 autoselectCheckbox->value(autoSelect);
137
138 int encNum = encodingNum(preferredEncoding);
139
140 switch (encNum) {
141 case encodingTight:
142 tightButton->setonly();
143 break;
144 case encodingZRLE:
145 zrleButton->setonly();
146 break;
147 case encodingHextile:
148 hextileButton->setonly();
149 break;
150 case encodingRaw:
151 rawButton->setonly();
152 break;
153 }
154
155 if (fullColour)
156 fullcolorCheckbox->setonly();
157 else {
158 switch (lowColourLevel) {
159 case 0:
Pierre Ossmancf836f22011-07-14 14:34:09 +0000160 verylowcolorCheckbox->setonly();
Pierre Ossmand463b572011-05-16 12:04:43 +0000161 break;
162 case 1:
163 lowcolorCheckbox->setonly();
164 break;
165 case 2:
Pierre Ossmancf836f22011-07-14 14:34:09 +0000166 mediumcolorCheckbox->setonly();
Pierre Ossmand463b572011-05-16 12:04:43 +0000167 break;
168 }
169 }
170
171 char digit[2] = "0";
172
173 compressionCheckbox->value(customCompressLevel);
174 jpegCheckbox->value(!noJpeg);
175 digit[0] = '0' + compressLevel;
176 compressionInput->value(digit);
177 digit[0] = '0' + qualityLevel;
178 jpegInput->value(digit);
179
180 handleAutoselect(autoselectCheckbox, this);
181 handleCompression(compressionCheckbox, this);
182 handleJpeg(jpegCheckbox, this);
183
184#ifdef HAVE_GNUTLS
185 /* Security */
186 Security security(SecurityClient::secTypes);
187
188 list<U8> secTypes;
189 list<U8>::iterator iter;
190
191 list<U32> secTypesExt;
192 list<U32>::iterator iterExt;
193
Pierre Ossmand463b572011-05-16 12:04:43 +0000194 encNoneCheckbox->value(false);
195 encTLSCheckbox->value(false);
196 encX509Checkbox->value(false);
197
198 authNoneCheckbox->value(false);
199 authVncCheckbox->value(false);
200 authPlainCheckbox->value(false);
201
202 secTypes = security.GetEnabledSecTypes();
203 for (iter = secTypes.begin(); iter != secTypes.end(); ++iter) {
204 switch (*iter) {
Pierre Ossmand463b572011-05-16 12:04:43 +0000205 case secTypeNone:
206 encNoneCheckbox->value(true);
207 authNoneCheckbox->value(true);
208 break;
209 case secTypeVncAuth:
210 encNoneCheckbox->value(true);
211 authVncCheckbox->value(true);
212 break;
213 }
214 }
215
216 secTypesExt = security.GetEnabledExtSecTypes();
217 for (iterExt = secTypesExt.begin(); iterExt != secTypesExt.end(); ++iterExt) {
218 switch (*iterExt) {
219 case secTypePlain:
220 encNoneCheckbox->value(true);
221 authPlainCheckbox->value(true);
222 break;
223 case secTypeTLSNone:
224 encTLSCheckbox->value(true);
225 authNoneCheckbox->value(true);
226 break;
227 case secTypeTLSVnc:
228 encTLSCheckbox->value(true);
229 authVncCheckbox->value(true);
230 break;
231 case secTypeTLSPlain:
232 encTLSCheckbox->value(true);
233 authPlainCheckbox->value(true);
234 break;
235 case secTypeX509None:
236 encX509Checkbox->value(true);
237 authNoneCheckbox->value(true);
238 break;
239 case secTypeX509Vnc:
240 encX509Checkbox->value(true);
241 authVncCheckbox->value(true);
242 break;
243 case secTypeX509Plain:
244 encX509Checkbox->value(true);
245 authPlainCheckbox->value(true);
246 break;
247 }
248 }
249
250 caInput->value(CSecurityTLS::x509ca);
251 crlInput->value(CSecurityTLS::x509crl);
252
Pierre Ossmand463b572011-05-16 12:04:43 +0000253 handleX509(encX509Checkbox, this);
254#endif
255
256 /* Input */
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000257 const char *menuKeyBuf;
258
Pierre Ossmand463b572011-05-16 12:04:43 +0000259 viewOnlyCheckbox->value(viewOnly);
260 acceptClipboardCheckbox->value(acceptClipboard);
261 sendClipboardCheckbox->value(sendClipboard);
262 sendPrimaryCheckbox->value(sendPrimary);
Pierre Ossman407a5c32011-05-26 14:48:29 +0000263 systemKeysCheckbox->value(fullscreenSystemKeys);
Pierre Ossmand463b572011-05-16 12:04:43 +0000264
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000265 menuKeyChoice->value(0);
266
267 menuKeyBuf = menuKey;
Martin Koegler498ef462011-09-04 07:04:43 +0000268 for (int i = 0; i < getMenuKeySymbolCount(); i++)
269 if (!strcmp(getMenuKeySymbols()[i].name, menuKeyBuf))
270 menuKeyChoice->value(i + 1);
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000271
Pierre Ossmand463b572011-05-16 12:04:43 +0000272 /* Misc. */
273 sharedCheckbox->value(shared);
274 fullScreenCheckbox->value(fullScreen);
Pierre Ossmand463b572011-05-16 12:04:43 +0000275 dotCursorCheckbox->value(dotWhenNoCursor);
276}
277
278
279void OptionsDialog::storeOptions(void)
280{
Pierre Ossman61fd4862011-05-16 12:46:51 +0000281 /* Compression */
282 autoSelect.setParam(autoselectCheckbox->value());
283
284 if (tightButton->value())
285 preferredEncoding.setParam(encodingName(encodingTight));
286 else if (zrleButton->value())
287 preferredEncoding.setParam(encodingName(encodingZRLE));
288 else if (hextileButton->value())
289 preferredEncoding.setParam(encodingName(encodingHextile));
290 else if (rawButton->value())
291 preferredEncoding.setParam(encodingName(encodingRaw));
292
293 fullColour.setParam(fullcolorCheckbox->value());
Pierre Ossmancf836f22011-07-14 14:34:09 +0000294 if (verylowcolorCheckbox->value())
Pierre Ossman61fd4862011-05-16 12:46:51 +0000295 lowColourLevel.setParam(0);
296 else if (lowcolorCheckbox->value())
297 lowColourLevel.setParam(1);
Pierre Ossmancf836f22011-07-14 14:34:09 +0000298 else if (mediumcolorCheckbox->value())
Pierre Ossman61fd4862011-05-16 12:46:51 +0000299 lowColourLevel.setParam(2);
300
301 customCompressLevel.setParam(compressionCheckbox->value());
302 noJpeg.setParam(!jpegCheckbox->value());
303 compressLevel.setParam(atoi(compressionInput->value()));
304 qualityLevel.setParam(atoi(jpegInput->value()));
305
306#ifdef HAVE_GNUTLS
307 /* Security */
308 Security security;
309
310 /* Process security types which don't use encryption */
311 if (encNoneCheckbox->value()) {
312 if (authNoneCheckbox->value())
313 security.EnableSecType(secTypeNone);
314 if (authVncCheckbox->value())
315 security.EnableSecType(secTypeVncAuth);
Pierre Ossmanc1764bd2011-09-30 12:26:25 +0000316 if (authPlainCheckbox->value())
317 security.EnableSecType(secTypePlain);
Pierre Ossman61fd4862011-05-16 12:46:51 +0000318 }
319
Pierre Ossmanc1764bd2011-09-30 12:26:25 +0000320 /* Process security types which use TLS encryption */
321 if (encTLSCheckbox->value()) {
322 if (authNoneCheckbox->value())
323 security.EnableSecType(secTypeTLSNone);
324 if (authVncCheckbox->value())
325 security.EnableSecType(secTypeTLSVnc);
326 if (authPlainCheckbox->value())
327 security.EnableSecType(secTypeTLSPlain);
328 }
Pierre Ossman61fd4862011-05-16 12:46:51 +0000329
Pierre Ossmanc1764bd2011-09-30 12:26:25 +0000330 /* Process security types which use X509 encryption */
331 if (encX509Checkbox->value()) {
332 if (authNoneCheckbox->value())
333 security.EnableSecType(secTypeX509None);
334 if (authVncCheckbox->value())
335 security.EnableSecType(secTypeX509Vnc);
336 if (authPlainCheckbox->value())
337 security.EnableSecType(secTypeX509Plain);
Pierre Ossman61fd4862011-05-16 12:46:51 +0000338 }
339
Pierre Ossman5535fe62011-09-30 12:11:52 +0000340 SecurityClient::secTypes.setParam(security.ToString());
341
Pierre Ossman61fd4862011-05-16 12:46:51 +0000342 CSecurityTLS::x509ca.setParam(caInput->value());
343 CSecurityTLS::x509crl.setParam(crlInput->value());
344#endif
345
346 /* Input */
347 viewOnly.setParam(viewOnlyCheckbox->value());
348 acceptClipboard.setParam(acceptClipboardCheckbox->value());
349 sendClipboard.setParam(sendClipboardCheckbox->value());
350 sendPrimary.setParam(sendPrimaryCheckbox->value());
Pierre Ossman407a5c32011-05-26 14:48:29 +0000351 fullscreenSystemKeys.setParam(systemKeysCheckbox->value());
Pierre Ossman61fd4862011-05-16 12:46:51 +0000352
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000353 if (menuKeyChoice->value() == 0)
354 menuKey.setParam("");
355 else {
Martin Koegler498ef462011-09-04 07:04:43 +0000356 menuKey.setParam(menuKeyChoice->text());
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000357 }
358
Pierre Ossman61fd4862011-05-16 12:46:51 +0000359 /* Misc. */
360 shared.setParam(sharedCheckbox->value());
361 fullScreen.setParam(fullScreenCheckbox->value());
Pierre Ossman61fd4862011-05-16 12:46:51 +0000362 dotWhenNoCursor.setParam(dotCursorCheckbox->value());
Pierre Ossman0c41e1d2011-05-17 09:36:04 +0000363
364 std::map<OptionsCallback*, void*>::const_iterator iter;
365
366 for (iter = callbacks.begin();iter != callbacks.end();++iter)
367 iter->first(iter->second);
Pierre Ossmand463b572011-05-16 12:04:43 +0000368}
369
370
371void OptionsDialog::createCompressionPage(int tx, int ty, int tw, int th)
372{
373 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Compression"));
374
375 int orig_tx, orig_ty;
376 int half_width, full_width;
377 int width, height;
378
379 tx += OUTER_MARGIN;
380 ty += OUTER_MARGIN;
381
382 full_width = tw - OUTER_MARGIN * 2;
383 half_width = (full_width - INNER_MARGIN) / 2;
384
385 /* AutoSelect checkbox */
386 autoselectCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
387 CHECK_MIN_WIDTH,
388 CHECK_HEIGHT,
389 _("Auto select")));
390 autoselectCheckbox->callback(handleAutoselect, this);
391 ty += CHECK_HEIGHT + INNER_MARGIN;
392
393 /* Two columns */
394 orig_tx = tx;
395 orig_ty = ty;
396
397 /* VNC encoding box */
398 ty += GROUP_LABEL_OFFSET;
399 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 3 + RADIO_HEIGHT * 4;
400 encodingGroup = new Fl_Group(tx, ty, half_width, height,
401 _("Preferred encoding"));
402 encodingGroup->box(FL_ENGRAVED_BOX);
403 encodingGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
404
405 {
406 tx += GROUP_MARGIN;
407 ty += GROUP_MARGIN;
408
409 width = encodingGroup->w() - GROUP_MARGIN * 2;
410
411 tightButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
412 RADIO_MIN_WIDTH,
413 RADIO_HEIGHT,
Peter Åstrand4c446002011-08-15 12:33:06 +0000414 "Tight"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000415 tightButton->type(FL_RADIO_BUTTON);
416 ty += RADIO_HEIGHT + TIGHT_MARGIN;
417
418 zrleButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
419 RADIO_MIN_WIDTH,
420 RADIO_HEIGHT,
Peter Åstrand4c446002011-08-15 12:33:06 +0000421 "ZRLE"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000422 zrleButton->type(FL_RADIO_BUTTON);
423 ty += RADIO_HEIGHT + TIGHT_MARGIN;
424
425 hextileButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
426 RADIO_MIN_WIDTH,
427 RADIO_HEIGHT,
Peter Åstrand4c446002011-08-15 12:33:06 +0000428 "Hextile"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000429 hextileButton->type(FL_RADIO_BUTTON);
430 ty += RADIO_HEIGHT + TIGHT_MARGIN;
431
432 rawButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
433 RADIO_MIN_WIDTH,
434 RADIO_HEIGHT,
Peter Åstrand4c446002011-08-15 12:33:06 +0000435 "Raw"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000436 rawButton->type(FL_RADIO_BUTTON);
437 ty += RADIO_HEIGHT + TIGHT_MARGIN;
438 }
439
440 ty += GROUP_MARGIN - TIGHT_MARGIN;
441
442 encodingGroup->end();
443
444 /* Second column */
445 tx = orig_tx + half_width + INNER_MARGIN;
446 ty = orig_ty;
447
448 /* Color box */
449 ty += GROUP_LABEL_OFFSET;
450 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 3 + RADIO_HEIGHT * 4;
451 colorlevelGroup = new Fl_Group(tx, ty, half_width, height, _("Color level"));
452 colorlevelGroup->box(FL_ENGRAVED_BOX);
453 colorlevelGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
454
455 {
456 tx += GROUP_MARGIN;
457 ty += GROUP_MARGIN;
458
459 width = colorlevelGroup->w() - GROUP_MARGIN * 2;
460
461 fullcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
462 RADIO_MIN_WIDTH,
463 RADIO_HEIGHT,
464 _("Full (all available colors)")));
465 fullcolorCheckbox->type(FL_RADIO_BUTTON);
466 ty += RADIO_HEIGHT + TIGHT_MARGIN;
467
468 mediumcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
469 RADIO_MIN_WIDTH,
470 RADIO_HEIGHT,
471 _("Medium (256 colors)")));
472 mediumcolorCheckbox->type(FL_RADIO_BUTTON);
473 ty += RADIO_HEIGHT + TIGHT_MARGIN;
474
475 lowcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
476 RADIO_MIN_WIDTH,
477 RADIO_HEIGHT,
478 _("Low (64 colors)")));
479 lowcolorCheckbox->type(FL_RADIO_BUTTON);
480 ty += RADIO_HEIGHT + TIGHT_MARGIN;
481
482 verylowcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
483 RADIO_MIN_WIDTH,
484 RADIO_HEIGHT,
485 _("Very low (8 colors)")));
486 verylowcolorCheckbox->type(FL_RADIO_BUTTON);
487 ty += RADIO_HEIGHT + TIGHT_MARGIN;
488 }
489
490 ty += GROUP_MARGIN - TIGHT_MARGIN;
491
492 colorlevelGroup->end();
493
494 /* Back to normal */
495 tx = orig_tx;
496 ty += INNER_MARGIN;
497
498 /* Checkboxes */
499 compressionCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
500 CHECK_MIN_WIDTH,
501 CHECK_HEIGHT,
502 _("Custom compression level:")));
503 compressionCheckbox->callback(handleCompression, this);
504 ty += CHECK_HEIGHT + TIGHT_MARGIN;
505
506 compressionInput = new Fl_Int_Input(tx + INDENT, ty,
507 INPUT_HEIGHT, INPUT_HEIGHT,
DRCba7bc512011-08-17 02:30:34 +0000508 _("level (1=fast, 6=best [4-6 are rarely useful])"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000509 compressionInput->align(FL_ALIGN_RIGHT);
510 ty += INPUT_HEIGHT + INNER_MARGIN;
511
512 jpegCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
513 CHECK_MIN_WIDTH,
514 CHECK_HEIGHT,
515 _("Allow JPEG compression:")));
516 jpegCheckbox->callback(handleJpeg, this);
517 ty += CHECK_HEIGHT + TIGHT_MARGIN;
518
519 jpegInput = new Fl_Int_Input(tx + INDENT, ty,
520 INPUT_HEIGHT, INPUT_HEIGHT,
DRC41036ed2011-08-23 20:36:50 +0000521 _("quality (0=poor, 9=best)"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000522 jpegInput->align(FL_ALIGN_RIGHT);
523 ty += INPUT_HEIGHT + INNER_MARGIN;
524
525 group->end();
526}
527
528
529void OptionsDialog::createSecurityPage(int tx, int ty, int tw, int th)
530{
531#ifdef HAVE_GNUTLS
532 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Security"));
533
534 int orig_tx;
535 int width, height;
536
537 tx += OUTER_MARGIN;
538 ty += OUTER_MARGIN;
539
540 width = tw - OUTER_MARGIN * 2;
541
542 orig_tx = tx;
543
Pierre Ossmand463b572011-05-16 12:04:43 +0000544 /* Encryption */
545 ty += GROUP_LABEL_OFFSET;
546 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 4 + CHECK_HEIGHT * 3 + (INPUT_LABEL_OFFSET + INPUT_HEIGHT) * 2;
547 encryptionGroup = new Fl_Group(tx, ty, width, height, _("Encryption"));
548 encryptionGroup->box(FL_ENGRAVED_BOX);
549 encryptionGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
550
551 {
552 tx += GROUP_MARGIN;
553 ty += GROUP_MARGIN;
554
555 encNoneCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
556 CHECK_MIN_WIDTH,
557 CHECK_HEIGHT,
558 _("None")));
559 ty += CHECK_HEIGHT + TIGHT_MARGIN;
560
561 encTLSCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
562 CHECK_MIN_WIDTH,
563 CHECK_HEIGHT,
564 _("TLS with anonymous certificates")));
565 ty += CHECK_HEIGHT + TIGHT_MARGIN;
566
567 encX509Checkbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
568 CHECK_MIN_WIDTH,
569 CHECK_HEIGHT,
570 _("TLS with X509 certificates")));
571 encX509Checkbox->callback(handleX509, this);
572 ty += CHECK_HEIGHT + TIGHT_MARGIN;
573
574 ty += INPUT_LABEL_OFFSET;
575 caInput = new Fl_Input(tx + INDENT, ty,
576 width - GROUP_MARGIN*2 - INDENT, INPUT_HEIGHT,
577 _("Path to X509 CA certificate"));
578 caInput->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
579 ty += INPUT_HEIGHT + TIGHT_MARGIN;
580
581 ty += INPUT_LABEL_OFFSET;
582 crlInput = new Fl_Input(tx + INDENT, ty,
583 width - GROUP_MARGIN*2 - INDENT, INPUT_HEIGHT,
584 _("Path to X509 CRL file"));
585 crlInput->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
586 ty += INPUT_HEIGHT + TIGHT_MARGIN;
587 }
588
589 ty += GROUP_MARGIN - TIGHT_MARGIN;
590
591 encryptionGroup->end();
592
593 /* Back to normal */
594 tx = orig_tx;
595 ty += INNER_MARGIN;
596
597 /* Authentication */
Pierre Ossmand463b572011-05-16 12:04:43 +0000598 ty += GROUP_LABEL_OFFSET;
599 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 2 + CHECK_HEIGHT * 3;
600 authenticationGroup = new Fl_Group(tx, ty, width, height, _("Authentication"));
601 authenticationGroup->box(FL_ENGRAVED_BOX);
602 authenticationGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
603
604 {
605 tx += GROUP_MARGIN;
606 ty += GROUP_MARGIN;
607
608 authNoneCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
609 CHECK_MIN_WIDTH,
610 CHECK_HEIGHT,
611 _("None")));
612 ty += CHECK_HEIGHT + TIGHT_MARGIN;
613
614 authVncCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
615 CHECK_MIN_WIDTH,
616 CHECK_HEIGHT,
617 _("Standard VNC (insecure without encryption)")));
618 ty += CHECK_HEIGHT + TIGHT_MARGIN;
619
620 authPlainCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
621 CHECK_MIN_WIDTH,
622 CHECK_HEIGHT,
623 _("Username and password (insecure without encryption)")));
624 ty += CHECK_HEIGHT + TIGHT_MARGIN;
625 }
626
627 ty += GROUP_MARGIN - TIGHT_MARGIN;
628
629 authenticationGroup->end();
630
631 /* Back to normal */
632 tx = orig_tx;
633 ty += INNER_MARGIN;
634
635 group->end();
636#endif
637}
638
639
640void OptionsDialog::createInputPage(int tx, int ty, int tw, int th)
641{
642 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Input"));
643
644 tx += OUTER_MARGIN;
645 ty += OUTER_MARGIN;
646
647 viewOnlyCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
648 CHECK_MIN_WIDTH,
649 CHECK_HEIGHT,
650 _("View only (ignore mouse and keyboard)")));
651 ty += CHECK_HEIGHT + TIGHT_MARGIN;
652
653 acceptClipboardCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
654 CHECK_MIN_WIDTH,
655 CHECK_HEIGHT,
656 _("Accept clipboard from server")));
657 ty += CHECK_HEIGHT + TIGHT_MARGIN;
658
659 sendClipboardCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
660 CHECK_MIN_WIDTH,
661 CHECK_HEIGHT,
662 _("Send clipboard to server")));
663 ty += CHECK_HEIGHT + TIGHT_MARGIN;
664
665 sendPrimaryCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
666 CHECK_MIN_WIDTH,
667 CHECK_HEIGHT,
668 _("Send primary selection and cut buffer as clipboard")));
669 ty += CHECK_HEIGHT + TIGHT_MARGIN;
670
Pierre Ossman407a5c32011-05-26 14:48:29 +0000671 systemKeysCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
672 CHECK_MIN_WIDTH,
673 CHECK_HEIGHT,
674 _("Pass system keys directly to server (full screen)")));
675 ty += CHECK_HEIGHT + TIGHT_MARGIN;
676
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000677 menuKeyChoice = new Fl_Choice(LBLLEFT(tx, ty, 150, CHOICE_HEIGHT, _("Menu key")));
678
679 menuKeyChoice->add(_("None"), 0, NULL, (void*)0, FL_MENU_DIVIDER);
Martin Koegler498ef462011-09-04 07:04:43 +0000680 for (int i = 0; i < getMenuKeySymbolCount(); i++)
681 menuKeyChoice->add(getMenuKeySymbols()[i].name, 0, NULL, 0, 0);
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000682
683 ty += CHOICE_HEIGHT + TIGHT_MARGIN;
684
Pierre Ossmand463b572011-05-16 12:04:43 +0000685 group->end();
686}
687
688
689void OptionsDialog::createMiscPage(int tx, int ty, int tw, int th)
690{
691 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Misc."));
692
693 tx += OUTER_MARGIN;
694 ty += OUTER_MARGIN;
695
696 sharedCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
697 CHECK_MIN_WIDTH,
698 CHECK_HEIGHT,
699 _("Shared (don't disconnect other viewers)")));
700 ty += CHECK_HEIGHT + TIGHT_MARGIN;
701
702 fullScreenCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
703 CHECK_MIN_WIDTH,
704 CHECK_HEIGHT,
705 _("Full-screen mode")));
706 ty += CHECK_HEIGHT + TIGHT_MARGIN;
707
Pierre Ossmand463b572011-05-16 12:04:43 +0000708 dotCursorCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
709 CHECK_MIN_WIDTH,
710 CHECK_HEIGHT,
711 _("Show dot when no cursor")));
712 ty += CHECK_HEIGHT + TIGHT_MARGIN;
713
714 group->end();
715}
716
717
718void OptionsDialog::handleAutoselect(Fl_Widget *widget, void *data)
719{
720 OptionsDialog *dialog = (OptionsDialog*)data;
721
722 if (dialog->autoselectCheckbox->value()) {
723 dialog->encodingGroup->deactivate();
724 dialog->colorlevelGroup->deactivate();
725 } else {
726 dialog->encodingGroup->activate();
727 dialog->colorlevelGroup->activate();
728 }
729
730 // JPEG setting is also affected by autoselection
731 dialog->handleJpeg(dialog->jpegCheckbox, dialog);
732}
733
734
735void OptionsDialog::handleCompression(Fl_Widget *widget, void *data)
736{
737 OptionsDialog *dialog = (OptionsDialog*)data;
738
739 if (dialog->compressionCheckbox->value())
740 dialog->compressionInput->activate();
741 else
742 dialog->compressionInput->deactivate();
743}
744
745
746void OptionsDialog::handleJpeg(Fl_Widget *widget, void *data)
747{
748 OptionsDialog *dialog = (OptionsDialog*)data;
749
750 if (dialog->jpegCheckbox->value() &&
751 !dialog->autoselectCheckbox->value())
752 dialog->jpegInput->activate();
753 else
754 dialog->jpegInput->deactivate();
755}
756
757
Pierre Ossmand463b572011-05-16 12:04:43 +0000758void OptionsDialog::handleX509(Fl_Widget *widget, void *data)
759{
760 OptionsDialog *dialog = (OptionsDialog*)data;
761
762 if (dialog->encX509Checkbox->value()) {
763 dialog->caInput->activate();
764 dialog->crlInput->activate();
765 } else {
766 dialog->caInput->deactivate();
767 dialog->crlInput->deactivate();
768 }
769}
770
771
772void OptionsDialog::handleCancel(Fl_Widget *widget, void *data)
773{
774 OptionsDialog *dialog = (OptionsDialog*)data;
775
776 dialog->hide();
777}
778
779
780void OptionsDialog::handleOK(Fl_Widget *widget, void *data)
781{
782 OptionsDialog *dialog = (OptionsDialog*)data;
783
784 dialog->hide();
785
786 dialog->storeOptions();
787}