blob: f69a29981d5445ded871e448cf0df3b167c9257a [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
Pierre Ossman61fd4862011-05-16 12:46:51 +000019#include <stdlib.h>
20
Pierre Ossmand463b572011-05-16 12:04:43 +000021#include <list>
22
23#include <FL/Fl_Tabs.H>
24#include <FL/Fl_Button.H>
25#include <FL/Fl_Return_Button.H>
26
27#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"
39#include "parameters.h"
40
41using namespace std;
42using namespace rdr;
43using namespace rfb;
44
45OptionsDialog::OptionsDialog()
46 : Fl_Window(450, 450, _("VNC Viewer: Connection Options"))
47{
48 int x, y;
49 Fl_Button *button;
50
51 Fl_Tabs *tabs = new Fl_Tabs(OUTER_MARGIN, OUTER_MARGIN,
52 w() - OUTER_MARGIN*2,
53 h() - OUTER_MARGIN*2 - INNER_MARGIN - BUTTON_HEIGHT);
54
55 {
56 int tx, ty, tw, th;
57
58 tabs->client_area(tx, ty, tw, th, TABS_HEIGHT);
59
60 createCompressionPage(tx, ty, tw, th);
61 createSecurityPage(tx, ty, tw, th);
62 createInputPage(tx, ty, tw, th);
63 createMiscPage(tx, ty, tw, th);
64 }
65
66 tabs->end();
67
68 x = w() - BUTTON_WIDTH * 2 - INNER_MARGIN - OUTER_MARGIN;
69 y = h() - BUTTON_HEIGHT - OUTER_MARGIN;
70
71 button = new Fl_Button(x, y, BUTTON_WIDTH, BUTTON_HEIGHT, _("Cancel"));
72 button->callback(this->handleCancel, this);
73
74 x += BUTTON_WIDTH + INNER_MARGIN;
75
76 button = new Fl_Return_Button(x, y, BUTTON_WIDTH, BUTTON_HEIGHT, _("OK"));
77 button->callback(this->handleOK, this);
78
79 callback(this->handleCancel, this);
80
81 set_modal();
82}
83
84
85OptionsDialog::~OptionsDialog()
86{
87}
88
89
90void OptionsDialog::showDialog(void)
91{
92 static OptionsDialog *dialog = NULL;
93
94 if (!dialog)
95 dialog = new OptionsDialog();
96
97 if (dialog->shown())
98 return;
99
100 dialog->show();
101}
102
103
104void OptionsDialog::show(void)
105{
106 loadOptions();
107
108 Fl_Window::show();
109}
110
111
112void OptionsDialog::loadOptions(void)
113{
114 /* Compression */
115 autoselectCheckbox->value(autoSelect);
116
117 int encNum = encodingNum(preferredEncoding);
118
119 switch (encNum) {
120 case encodingTight:
121 tightButton->setonly();
122 break;
123 case encodingZRLE:
124 zrleButton->setonly();
125 break;
126 case encodingHextile:
127 hextileButton->setonly();
128 break;
129 case encodingRaw:
130 rawButton->setonly();
131 break;
132 }
133
134 if (fullColour)
135 fullcolorCheckbox->setonly();
136 else {
137 switch (lowColourLevel) {
138 case 0:
139 mediumcolorCheckbox->setonly();
140 break;
141 case 1:
142 lowcolorCheckbox->setonly();
143 break;
144 case 2:
145 verylowcolorCheckbox->setonly();
146 break;
147 }
148 }
149
150 char digit[2] = "0";
151
152 compressionCheckbox->value(customCompressLevel);
153 jpegCheckbox->value(!noJpeg);
154 digit[0] = '0' + compressLevel;
155 compressionInput->value(digit);
156 digit[0] = '0' + qualityLevel;
157 jpegInput->value(digit);
158
159 handleAutoselect(autoselectCheckbox, this);
160 handleCompression(compressionCheckbox, this);
161 handleJpeg(jpegCheckbox, this);
162
163#ifdef HAVE_GNUTLS
164 /* Security */
165 Security security(SecurityClient::secTypes);
166
167 list<U8> secTypes;
168 list<U8>::iterator iter;
169
170 list<U32> secTypesExt;
171 list<U32>::iterator iterExt;
172
173 vencryptCheckbox->value(false);
174
175 encNoneCheckbox->value(false);
176 encTLSCheckbox->value(false);
177 encX509Checkbox->value(false);
178
179 authNoneCheckbox->value(false);
180 authVncCheckbox->value(false);
181 authPlainCheckbox->value(false);
182
183 secTypes = security.GetEnabledSecTypes();
184 for (iter = secTypes.begin(); iter != secTypes.end(); ++iter) {
185 switch (*iter) {
186 case secTypeVeNCrypt:
187 vencryptCheckbox->value(true);
188 break;
189 case secTypeNone:
190 encNoneCheckbox->value(true);
191 authNoneCheckbox->value(true);
192 break;
193 case secTypeVncAuth:
194 encNoneCheckbox->value(true);
195 authVncCheckbox->value(true);
196 break;
197 }
198 }
199
200 secTypesExt = security.GetEnabledExtSecTypes();
201 for (iterExt = secTypesExt.begin(); iterExt != secTypesExt.end(); ++iterExt) {
202 switch (*iterExt) {
203 case secTypePlain:
204 encNoneCheckbox->value(true);
205 authPlainCheckbox->value(true);
206 break;
207 case secTypeTLSNone:
208 encTLSCheckbox->value(true);
209 authNoneCheckbox->value(true);
210 break;
211 case secTypeTLSVnc:
212 encTLSCheckbox->value(true);
213 authVncCheckbox->value(true);
214 break;
215 case secTypeTLSPlain:
216 encTLSCheckbox->value(true);
217 authPlainCheckbox->value(true);
218 break;
219 case secTypeX509None:
220 encX509Checkbox->value(true);
221 authNoneCheckbox->value(true);
222 break;
223 case secTypeX509Vnc:
224 encX509Checkbox->value(true);
225 authVncCheckbox->value(true);
226 break;
227 case secTypeX509Plain:
228 encX509Checkbox->value(true);
229 authPlainCheckbox->value(true);
230 break;
231 }
232 }
233
234 caInput->value(CSecurityTLS::x509ca);
235 crlInput->value(CSecurityTLS::x509crl);
236
237 handleVencrypt(vencryptCheckbox, this);
238 handleX509(encX509Checkbox, this);
239#endif
240
241 /* Input */
242 viewOnlyCheckbox->value(viewOnly);
243 acceptClipboardCheckbox->value(acceptClipboard);
244 sendClipboardCheckbox->value(sendClipboard);
245 sendPrimaryCheckbox->value(sendPrimary);
246
247 /* Misc. */
248 sharedCheckbox->value(shared);
249 fullScreenCheckbox->value(fullScreen);
250 localCursorCheckbox->value(useLocalCursor);
251 dotCursorCheckbox->value(dotWhenNoCursor);
252}
253
254
255void OptionsDialog::storeOptions(void)
256{
Pierre Ossman61fd4862011-05-16 12:46:51 +0000257 /* Compression */
258 autoSelect.setParam(autoselectCheckbox->value());
259
260 if (tightButton->value())
261 preferredEncoding.setParam(encodingName(encodingTight));
262 else if (zrleButton->value())
263 preferredEncoding.setParam(encodingName(encodingZRLE));
264 else if (hextileButton->value())
265 preferredEncoding.setParam(encodingName(encodingHextile));
266 else if (rawButton->value())
267 preferredEncoding.setParam(encodingName(encodingRaw));
268
269 fullColour.setParam(fullcolorCheckbox->value());
270 if (mediumcolorCheckbox->value())
271 lowColourLevel.setParam(0);
272 else if (lowcolorCheckbox->value())
273 lowColourLevel.setParam(1);
274 else if (verylowcolorCheckbox->value())
275 lowColourLevel.setParam(2);
276
277 customCompressLevel.setParam(compressionCheckbox->value());
278 noJpeg.setParam(!jpegCheckbox->value());
279 compressLevel.setParam(atoi(compressionInput->value()));
280 qualityLevel.setParam(atoi(jpegInput->value()));
281
282#ifdef HAVE_GNUTLS
283 /* Security */
284 Security security;
285
286 /* Process security types which don't use encryption */
287 if (encNoneCheckbox->value()) {
288 if (authNoneCheckbox->value())
289 security.EnableSecType(secTypeNone);
290 if (authVncCheckbox->value())
291 security.EnableSecType(secTypeVncAuth);
292
293 if (vencryptCheckbox->value()) {
294 if (authPlainCheckbox->value())
295 security.EnableSecType(secTypePlain);
296 }
297 }
298
299 if (vencryptCheckbox->value()) {
300 /* Process security types which use TLS encryption */
301 if (encTLSCheckbox->value()) {
302 if (authNoneCheckbox->value())
303 security.EnableSecType(secTypeTLSNone);
304 if (authVncCheckbox->value())
305 security.EnableSecType(secTypeTLSVnc);
306 if (authPlainCheckbox->value())
307 security.EnableSecType(secTypeTLSPlain);
308 }
309
310 /* Process security types which use X509 encryption */
311 if (encX509Checkbox->value()) {
312 if (authNoneCheckbox->value())
313 security.EnableSecType(secTypeX509None);
314 if (authVncCheckbox->value())
315 security.EnableSecType(secTypeX509Vnc);
316 if (authPlainCheckbox->value())
317 security.EnableSecType(secTypeX509Plain);
318 }
319 }
320
321 CSecurityTLS::x509ca.setParam(caInput->value());
322 CSecurityTLS::x509crl.setParam(crlInput->value());
323#endif
324
325 /* Input */
326 viewOnly.setParam(viewOnlyCheckbox->value());
327 acceptClipboard.setParam(acceptClipboardCheckbox->value());
328 sendClipboard.setParam(sendClipboardCheckbox->value());
329 sendPrimary.setParam(sendPrimaryCheckbox->value());
330
331 /* Misc. */
332 shared.setParam(sharedCheckbox->value());
333 fullScreen.setParam(fullScreenCheckbox->value());
334 useLocalCursor.setParam(localCursorCheckbox->value());
335 dotWhenNoCursor.setParam(dotCursorCheckbox->value());
Pierre Ossmand463b572011-05-16 12:04:43 +0000336}
337
338
339void OptionsDialog::createCompressionPage(int tx, int ty, int tw, int th)
340{
341 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Compression"));
342
343 int orig_tx, orig_ty;
344 int half_width, full_width;
345 int width, height;
346
347 tx += OUTER_MARGIN;
348 ty += OUTER_MARGIN;
349
350 full_width = tw - OUTER_MARGIN * 2;
351 half_width = (full_width - INNER_MARGIN) / 2;
352
353 /* AutoSelect checkbox */
354 autoselectCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
355 CHECK_MIN_WIDTH,
356 CHECK_HEIGHT,
357 _("Auto select")));
358 autoselectCheckbox->callback(handleAutoselect, this);
359 ty += CHECK_HEIGHT + INNER_MARGIN;
360
361 /* Two columns */
362 orig_tx = tx;
363 orig_ty = ty;
364
365 /* VNC encoding box */
366 ty += GROUP_LABEL_OFFSET;
367 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 3 + RADIO_HEIGHT * 4;
368 encodingGroup = new Fl_Group(tx, ty, half_width, height,
369 _("Preferred encoding"));
370 encodingGroup->box(FL_ENGRAVED_BOX);
371 encodingGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
372
373 {
374 tx += GROUP_MARGIN;
375 ty += GROUP_MARGIN;
376
377 width = encodingGroup->w() - GROUP_MARGIN * 2;
378
379 tightButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
380 RADIO_MIN_WIDTH,
381 RADIO_HEIGHT,
382 _("Tight")));
383 tightButton->type(FL_RADIO_BUTTON);
384 ty += RADIO_HEIGHT + TIGHT_MARGIN;
385
386 zrleButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
387 RADIO_MIN_WIDTH,
388 RADIO_HEIGHT,
389 _("ZRLE")));
390 zrleButton->type(FL_RADIO_BUTTON);
391 ty += RADIO_HEIGHT + TIGHT_MARGIN;
392
393 hextileButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
394 RADIO_MIN_WIDTH,
395 RADIO_HEIGHT,
396 _("Hextile")));
397 hextileButton->type(FL_RADIO_BUTTON);
398 ty += RADIO_HEIGHT + TIGHT_MARGIN;
399
400 rawButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
401 RADIO_MIN_WIDTH,
402 RADIO_HEIGHT,
403 _("Raw")));
404 rawButton->type(FL_RADIO_BUTTON);
405 ty += RADIO_HEIGHT + TIGHT_MARGIN;
406 }
407
408 ty += GROUP_MARGIN - TIGHT_MARGIN;
409
410 encodingGroup->end();
411
412 /* Second column */
413 tx = orig_tx + half_width + INNER_MARGIN;
414 ty = orig_ty;
415
416 /* Color box */
417 ty += GROUP_LABEL_OFFSET;
418 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 3 + RADIO_HEIGHT * 4;
419 colorlevelGroup = new Fl_Group(tx, ty, half_width, height, _("Color level"));
420 colorlevelGroup->box(FL_ENGRAVED_BOX);
421 colorlevelGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
422
423 {
424 tx += GROUP_MARGIN;
425 ty += GROUP_MARGIN;
426
427 width = colorlevelGroup->w() - GROUP_MARGIN * 2;
428
429 fullcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
430 RADIO_MIN_WIDTH,
431 RADIO_HEIGHT,
432 _("Full (all available colors)")));
433 fullcolorCheckbox->type(FL_RADIO_BUTTON);
434 ty += RADIO_HEIGHT + TIGHT_MARGIN;
435
436 mediumcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
437 RADIO_MIN_WIDTH,
438 RADIO_HEIGHT,
439 _("Medium (256 colors)")));
440 mediumcolorCheckbox->type(FL_RADIO_BUTTON);
441 ty += RADIO_HEIGHT + TIGHT_MARGIN;
442
443 lowcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
444 RADIO_MIN_WIDTH,
445 RADIO_HEIGHT,
446 _("Low (64 colors)")));
447 lowcolorCheckbox->type(FL_RADIO_BUTTON);
448 ty += RADIO_HEIGHT + TIGHT_MARGIN;
449
450 verylowcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
451 RADIO_MIN_WIDTH,
452 RADIO_HEIGHT,
453 _("Very low (8 colors)")));
454 verylowcolorCheckbox->type(FL_RADIO_BUTTON);
455 ty += RADIO_HEIGHT + TIGHT_MARGIN;
456 }
457
458 ty += GROUP_MARGIN - TIGHT_MARGIN;
459
460 colorlevelGroup->end();
461
462 /* Back to normal */
463 tx = orig_tx;
464 ty += INNER_MARGIN;
465
466 /* Checkboxes */
467 compressionCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
468 CHECK_MIN_WIDTH,
469 CHECK_HEIGHT,
470 _("Custom compression level:")));
471 compressionCheckbox->callback(handleCompression, this);
472 ty += CHECK_HEIGHT + TIGHT_MARGIN;
473
474 compressionInput = new Fl_Int_Input(tx + INDENT, ty,
475 INPUT_HEIGHT, INPUT_HEIGHT,
476 _("level (1=fast, 9=best)"));
477 compressionInput->align(FL_ALIGN_RIGHT);
478 ty += INPUT_HEIGHT + INNER_MARGIN;
479
480 jpegCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
481 CHECK_MIN_WIDTH,
482 CHECK_HEIGHT,
483 _("Allow JPEG compression:")));
484 jpegCheckbox->callback(handleJpeg, this);
485 ty += CHECK_HEIGHT + TIGHT_MARGIN;
486
487 jpegInput = new Fl_Int_Input(tx + INDENT, ty,
488 INPUT_HEIGHT, INPUT_HEIGHT,
489 _("quality (1=poor, 9=best)"));
490 jpegInput->align(FL_ALIGN_RIGHT);
491 ty += INPUT_HEIGHT + INNER_MARGIN;
492
493 group->end();
494}
495
496
497void OptionsDialog::createSecurityPage(int tx, int ty, int tw, int th)
498{
499#ifdef HAVE_GNUTLS
500 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Security"));
501
502 int orig_tx;
503 int width, height;
504
505 tx += OUTER_MARGIN;
506 ty += OUTER_MARGIN;
507
508 width = tw - OUTER_MARGIN * 2;
509
510 orig_tx = tx;
511
512 /* Security */
513 vencryptCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
514 CHECK_MIN_WIDTH,
515 CHECK_HEIGHT,
516 _("Extended encryption and authentication methods (VeNCrypt)")));
517 vencryptCheckbox->callback(handleVencrypt, this);
518 ty += CHECK_HEIGHT + INNER_MARGIN;
519
520 /* Encryption */
521 ty += GROUP_LABEL_OFFSET;
522 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 4 + CHECK_HEIGHT * 3 + (INPUT_LABEL_OFFSET + INPUT_HEIGHT) * 2;
523 encryptionGroup = new Fl_Group(tx, ty, width, height, _("Encryption"));
524 encryptionGroup->box(FL_ENGRAVED_BOX);
525 encryptionGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
526
527 {
528 tx += GROUP_MARGIN;
529 ty += GROUP_MARGIN;
530
531 encNoneCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
532 CHECK_MIN_WIDTH,
533 CHECK_HEIGHT,
534 _("None")));
535 ty += CHECK_HEIGHT + TIGHT_MARGIN;
536
537 encTLSCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
538 CHECK_MIN_WIDTH,
539 CHECK_HEIGHT,
540 _("TLS with anonymous certificates")));
541 ty += CHECK_HEIGHT + TIGHT_MARGIN;
542
543 encX509Checkbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
544 CHECK_MIN_WIDTH,
545 CHECK_HEIGHT,
546 _("TLS with X509 certificates")));
547 encX509Checkbox->callback(handleX509, this);
548 ty += CHECK_HEIGHT + TIGHT_MARGIN;
549
550 ty += INPUT_LABEL_OFFSET;
551 caInput = new Fl_Input(tx + INDENT, ty,
552 width - GROUP_MARGIN*2 - INDENT, INPUT_HEIGHT,
553 _("Path to X509 CA certificate"));
554 caInput->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
555 ty += INPUT_HEIGHT + TIGHT_MARGIN;
556
557 ty += INPUT_LABEL_OFFSET;
558 crlInput = new Fl_Input(tx + INDENT, ty,
559 width - GROUP_MARGIN*2 - INDENT, INPUT_HEIGHT,
560 _("Path to X509 CRL file"));
561 crlInput->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
562 ty += INPUT_HEIGHT + TIGHT_MARGIN;
563 }
564
565 ty += GROUP_MARGIN - TIGHT_MARGIN;
566
567 encryptionGroup->end();
568
569 /* Back to normal */
570 tx = orig_tx;
571 ty += INNER_MARGIN;
572
573 /* Authentication */
574 /* Encryption */
575 ty += GROUP_LABEL_OFFSET;
576 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 2 + CHECK_HEIGHT * 3;
577 authenticationGroup = new Fl_Group(tx, ty, width, height, _("Authentication"));
578 authenticationGroup->box(FL_ENGRAVED_BOX);
579 authenticationGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
580
581 {
582 tx += GROUP_MARGIN;
583 ty += GROUP_MARGIN;
584
585 authNoneCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
586 CHECK_MIN_WIDTH,
587 CHECK_HEIGHT,
588 _("None")));
589 ty += CHECK_HEIGHT + TIGHT_MARGIN;
590
591 authVncCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
592 CHECK_MIN_WIDTH,
593 CHECK_HEIGHT,
594 _("Standard VNC (insecure without encryption)")));
595 ty += CHECK_HEIGHT + TIGHT_MARGIN;
596
597 authPlainCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
598 CHECK_MIN_WIDTH,
599 CHECK_HEIGHT,
600 _("Username and password (insecure without encryption)")));
601 ty += CHECK_HEIGHT + TIGHT_MARGIN;
602 }
603
604 ty += GROUP_MARGIN - TIGHT_MARGIN;
605
606 authenticationGroup->end();
607
608 /* Back to normal */
609 tx = orig_tx;
610 ty += INNER_MARGIN;
611
612 group->end();
613#endif
614}
615
616
617void OptionsDialog::createInputPage(int tx, int ty, int tw, int th)
618{
619 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Input"));
620
621 tx += OUTER_MARGIN;
622 ty += OUTER_MARGIN;
623
624 viewOnlyCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
625 CHECK_MIN_WIDTH,
626 CHECK_HEIGHT,
627 _("View only (ignore mouse and keyboard)")));
628 ty += CHECK_HEIGHT + TIGHT_MARGIN;
629
630 acceptClipboardCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
631 CHECK_MIN_WIDTH,
632 CHECK_HEIGHT,
633 _("Accept clipboard from server")));
634 ty += CHECK_HEIGHT + TIGHT_MARGIN;
635
636 sendClipboardCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
637 CHECK_MIN_WIDTH,
638 CHECK_HEIGHT,
639 _("Send clipboard to server")));
640 ty += CHECK_HEIGHT + TIGHT_MARGIN;
641
642 sendPrimaryCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
643 CHECK_MIN_WIDTH,
644 CHECK_HEIGHT,
645 _("Send primary selection and cut buffer as clipboard")));
646 ty += CHECK_HEIGHT + TIGHT_MARGIN;
647
648 group->end();
649}
650
651
652void OptionsDialog::createMiscPage(int tx, int ty, int tw, int th)
653{
654 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Misc."));
655
656 tx += OUTER_MARGIN;
657 ty += OUTER_MARGIN;
658
659 sharedCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
660 CHECK_MIN_WIDTH,
661 CHECK_HEIGHT,
662 _("Shared (don't disconnect other viewers)")));
663 ty += CHECK_HEIGHT + TIGHT_MARGIN;
664
665 fullScreenCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
666 CHECK_MIN_WIDTH,
667 CHECK_HEIGHT,
668 _("Full-screen mode")));
669 ty += CHECK_HEIGHT + TIGHT_MARGIN;
670
671 localCursorCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
672 CHECK_MIN_WIDTH,
673 CHECK_HEIGHT,
674 _("Render cursor locally")));
675 ty += CHECK_HEIGHT + TIGHT_MARGIN;
676
677 dotCursorCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
678 CHECK_MIN_WIDTH,
679 CHECK_HEIGHT,
680 _("Show dot when no cursor")));
681 ty += CHECK_HEIGHT + TIGHT_MARGIN;
682
683 group->end();
684}
685
686
687void OptionsDialog::handleAutoselect(Fl_Widget *widget, void *data)
688{
689 OptionsDialog *dialog = (OptionsDialog*)data;
690
691 if (dialog->autoselectCheckbox->value()) {
692 dialog->encodingGroup->deactivate();
693 dialog->colorlevelGroup->deactivate();
694 } else {
695 dialog->encodingGroup->activate();
696 dialog->colorlevelGroup->activate();
697 }
698
699 // JPEG setting is also affected by autoselection
700 dialog->handleJpeg(dialog->jpegCheckbox, dialog);
701}
702
703
704void OptionsDialog::handleCompression(Fl_Widget *widget, void *data)
705{
706 OptionsDialog *dialog = (OptionsDialog*)data;
707
708 if (dialog->compressionCheckbox->value())
709 dialog->compressionInput->activate();
710 else
711 dialog->compressionInput->deactivate();
712}
713
714
715void OptionsDialog::handleJpeg(Fl_Widget *widget, void *data)
716{
717 OptionsDialog *dialog = (OptionsDialog*)data;
718
719 if (dialog->jpegCheckbox->value() &&
720 !dialog->autoselectCheckbox->value())
721 dialog->jpegInput->activate();
722 else
723 dialog->jpegInput->deactivate();
724}
725
726
727void OptionsDialog::handleVencrypt(Fl_Widget *widget, void *data)
728{
729 OptionsDialog *dialog = (OptionsDialog*)data;
730
731 if (dialog->vencryptCheckbox->value()) {
732 dialog->encryptionGroup->activate();
733 dialog->authPlainCheckbox->activate();
734 } else {
735 dialog->encryptionGroup->deactivate();
736 dialog->authPlainCheckbox->deactivate();
737 }
738}
739
740
741void OptionsDialog::handleX509(Fl_Widget *widget, void *data)
742{
743 OptionsDialog *dialog = (OptionsDialog*)data;
744
745 if (dialog->encX509Checkbox->value()) {
746 dialog->caInput->activate();
747 dialog->crlInput->activate();
748 } else {
749 dialog->caInput->deactivate();
750 dialog->crlInput->deactivate();
751 }
752}
753
754
755void OptionsDialog::handleCancel(Fl_Widget *widget, void *data)
756{
757 OptionsDialog *dialog = (OptionsDialog*)data;
758
759 dialog->hide();
760}
761
762
763void OptionsDialog::handleOK(Fl_Widget *widget, void *data)
764{
765 OptionsDialog *dialog = (OptionsDialog*)data;
766
767 dialog->hide();
768
769 dialog->storeOptions();
770}