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