blob: 7a2cf2edb3854cc943a3de8a699f6ec84192afdf [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 */
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000256 const char *menuKeyBuf;
257
Pierre Ossmand463b572011-05-16 12:04:43 +0000258 viewOnlyCheckbox->value(viewOnly);
259 acceptClipboardCheckbox->value(acceptClipboard);
260 sendClipboardCheckbox->value(sendClipboard);
261 sendPrimaryCheckbox->value(sendPrimary);
262
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000263 menuKeyChoice->value(0);
264
265 menuKeyBuf = menuKey;
266 if (menuKeyBuf[0] == 'F') {
267 int num = atoi(menuKeyBuf+1);
268 if ((num >= 1) && (num <= 12))
269 menuKeyChoice->value(num);
270 }
271
Pierre Ossmand463b572011-05-16 12:04:43 +0000272 /* Misc. */
273 sharedCheckbox->value(shared);
274 fullScreenCheckbox->value(fullScreen);
275 localCursorCheckbox->value(useLocalCursor);
276 dotCursorCheckbox->value(dotWhenNoCursor);
277}
278
279
280void OptionsDialog::storeOptions(void)
281{
Pierre Ossman61fd4862011-05-16 12:46:51 +0000282 /* Compression */
283 autoSelect.setParam(autoselectCheckbox->value());
284
285 if (tightButton->value())
286 preferredEncoding.setParam(encodingName(encodingTight));
287 else if (zrleButton->value())
288 preferredEncoding.setParam(encodingName(encodingZRLE));
289 else if (hextileButton->value())
290 preferredEncoding.setParam(encodingName(encodingHextile));
291 else if (rawButton->value())
292 preferredEncoding.setParam(encodingName(encodingRaw));
293
294 fullColour.setParam(fullcolorCheckbox->value());
295 if (mediumcolorCheckbox->value())
296 lowColourLevel.setParam(0);
297 else if (lowcolorCheckbox->value())
298 lowColourLevel.setParam(1);
299 else if (verylowcolorCheckbox->value())
300 lowColourLevel.setParam(2);
301
302 customCompressLevel.setParam(compressionCheckbox->value());
303 noJpeg.setParam(!jpegCheckbox->value());
304 compressLevel.setParam(atoi(compressionInput->value()));
305 qualityLevel.setParam(atoi(jpegInput->value()));
306
307#ifdef HAVE_GNUTLS
308 /* Security */
309 Security security;
310
311 /* Process security types which don't use encryption */
312 if (encNoneCheckbox->value()) {
313 if (authNoneCheckbox->value())
314 security.EnableSecType(secTypeNone);
315 if (authVncCheckbox->value())
316 security.EnableSecType(secTypeVncAuth);
317
318 if (vencryptCheckbox->value()) {
319 if (authPlainCheckbox->value())
320 security.EnableSecType(secTypePlain);
321 }
322 }
323
324 if (vencryptCheckbox->value()) {
325 /* Process security types which use TLS encryption */
326 if (encTLSCheckbox->value()) {
327 if (authNoneCheckbox->value())
328 security.EnableSecType(secTypeTLSNone);
329 if (authVncCheckbox->value())
330 security.EnableSecType(secTypeTLSVnc);
331 if (authPlainCheckbox->value())
332 security.EnableSecType(secTypeTLSPlain);
333 }
334
335 /* Process security types which use X509 encryption */
336 if (encX509Checkbox->value()) {
337 if (authNoneCheckbox->value())
338 security.EnableSecType(secTypeX509None);
339 if (authVncCheckbox->value())
340 security.EnableSecType(secTypeX509Vnc);
341 if (authPlainCheckbox->value())
342 security.EnableSecType(secTypeX509Plain);
343 }
344 }
345
346 CSecurityTLS::x509ca.setParam(caInput->value());
347 CSecurityTLS::x509crl.setParam(crlInput->value());
348#endif
349
350 /* Input */
351 viewOnly.setParam(viewOnlyCheckbox->value());
352 acceptClipboard.setParam(acceptClipboardCheckbox->value());
353 sendClipboard.setParam(sendClipboardCheckbox->value());
354 sendPrimary.setParam(sendPrimaryCheckbox->value());
355
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000356 if (menuKeyChoice->value() == 0)
357 menuKey.setParam("");
358 else {
359 char buf[16];
360 sprintf(buf, "F%d", menuKeyChoice->value());
361 menuKey.setParam(buf);
362 }
363
Pierre Ossman61fd4862011-05-16 12:46:51 +0000364 /* Misc. */
365 shared.setParam(sharedCheckbox->value());
366 fullScreen.setParam(fullScreenCheckbox->value());
367 useLocalCursor.setParam(localCursorCheckbox->value());
368 dotWhenNoCursor.setParam(dotCursorCheckbox->value());
Pierre Ossman0c41e1d2011-05-17 09:36:04 +0000369
370 std::map<OptionsCallback*, void*>::const_iterator iter;
371
372 for (iter = callbacks.begin();iter != callbacks.end();++iter)
373 iter->first(iter->second);
Pierre Ossmand463b572011-05-16 12:04:43 +0000374}
375
376
377void OptionsDialog::createCompressionPage(int tx, int ty, int tw, int th)
378{
379 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Compression"));
380
381 int orig_tx, orig_ty;
382 int half_width, full_width;
383 int width, height;
384
385 tx += OUTER_MARGIN;
386 ty += OUTER_MARGIN;
387
388 full_width = tw - OUTER_MARGIN * 2;
389 half_width = (full_width - INNER_MARGIN) / 2;
390
391 /* AutoSelect checkbox */
392 autoselectCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
393 CHECK_MIN_WIDTH,
394 CHECK_HEIGHT,
395 _("Auto select")));
396 autoselectCheckbox->callback(handleAutoselect, this);
397 ty += CHECK_HEIGHT + INNER_MARGIN;
398
399 /* Two columns */
400 orig_tx = tx;
401 orig_ty = ty;
402
403 /* VNC encoding box */
404 ty += GROUP_LABEL_OFFSET;
405 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 3 + RADIO_HEIGHT * 4;
406 encodingGroup = new Fl_Group(tx, ty, half_width, height,
407 _("Preferred encoding"));
408 encodingGroup->box(FL_ENGRAVED_BOX);
409 encodingGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
410
411 {
412 tx += GROUP_MARGIN;
413 ty += GROUP_MARGIN;
414
415 width = encodingGroup->w() - GROUP_MARGIN * 2;
416
417 tightButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
418 RADIO_MIN_WIDTH,
419 RADIO_HEIGHT,
420 _("Tight")));
421 tightButton->type(FL_RADIO_BUTTON);
422 ty += RADIO_HEIGHT + TIGHT_MARGIN;
423
424 zrleButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
425 RADIO_MIN_WIDTH,
426 RADIO_HEIGHT,
427 _("ZRLE")));
428 zrleButton->type(FL_RADIO_BUTTON);
429 ty += RADIO_HEIGHT + TIGHT_MARGIN;
430
431 hextileButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
432 RADIO_MIN_WIDTH,
433 RADIO_HEIGHT,
434 _("Hextile")));
435 hextileButton->type(FL_RADIO_BUTTON);
436 ty += RADIO_HEIGHT + TIGHT_MARGIN;
437
438 rawButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
439 RADIO_MIN_WIDTH,
440 RADIO_HEIGHT,
441 _("Raw")));
442 rawButton->type(FL_RADIO_BUTTON);
443 ty += RADIO_HEIGHT + TIGHT_MARGIN;
444 }
445
446 ty += GROUP_MARGIN - TIGHT_MARGIN;
447
448 encodingGroup->end();
449
450 /* Second column */
451 tx = orig_tx + half_width + INNER_MARGIN;
452 ty = orig_ty;
453
454 /* Color box */
455 ty += GROUP_LABEL_OFFSET;
456 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 3 + RADIO_HEIGHT * 4;
457 colorlevelGroup = new Fl_Group(tx, ty, half_width, height, _("Color level"));
458 colorlevelGroup->box(FL_ENGRAVED_BOX);
459 colorlevelGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
460
461 {
462 tx += GROUP_MARGIN;
463 ty += GROUP_MARGIN;
464
465 width = colorlevelGroup->w() - GROUP_MARGIN * 2;
466
467 fullcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
468 RADIO_MIN_WIDTH,
469 RADIO_HEIGHT,
470 _("Full (all available colors)")));
471 fullcolorCheckbox->type(FL_RADIO_BUTTON);
472 ty += RADIO_HEIGHT + TIGHT_MARGIN;
473
474 mediumcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
475 RADIO_MIN_WIDTH,
476 RADIO_HEIGHT,
477 _("Medium (256 colors)")));
478 mediumcolorCheckbox->type(FL_RADIO_BUTTON);
479 ty += RADIO_HEIGHT + TIGHT_MARGIN;
480
481 lowcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
482 RADIO_MIN_WIDTH,
483 RADIO_HEIGHT,
484 _("Low (64 colors)")));
485 lowcolorCheckbox->type(FL_RADIO_BUTTON);
486 ty += RADIO_HEIGHT + TIGHT_MARGIN;
487
488 verylowcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
489 RADIO_MIN_WIDTH,
490 RADIO_HEIGHT,
491 _("Very low (8 colors)")));
492 verylowcolorCheckbox->type(FL_RADIO_BUTTON);
493 ty += RADIO_HEIGHT + TIGHT_MARGIN;
494 }
495
496 ty += GROUP_MARGIN - TIGHT_MARGIN;
497
498 colorlevelGroup->end();
499
500 /* Back to normal */
501 tx = orig_tx;
502 ty += INNER_MARGIN;
503
504 /* Checkboxes */
505 compressionCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
506 CHECK_MIN_WIDTH,
507 CHECK_HEIGHT,
508 _("Custom compression level:")));
509 compressionCheckbox->callback(handleCompression, this);
510 ty += CHECK_HEIGHT + TIGHT_MARGIN;
511
512 compressionInput = new Fl_Int_Input(tx + INDENT, ty,
513 INPUT_HEIGHT, INPUT_HEIGHT,
514 _("level (1=fast, 9=best)"));
515 compressionInput->align(FL_ALIGN_RIGHT);
516 ty += INPUT_HEIGHT + INNER_MARGIN;
517
518 jpegCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
519 CHECK_MIN_WIDTH,
520 CHECK_HEIGHT,
521 _("Allow JPEG compression:")));
522 jpegCheckbox->callback(handleJpeg, this);
523 ty += CHECK_HEIGHT + TIGHT_MARGIN;
524
525 jpegInput = new Fl_Int_Input(tx + INDENT, ty,
526 INPUT_HEIGHT, INPUT_HEIGHT,
527 _("quality (1=poor, 9=best)"));
528 jpegInput->align(FL_ALIGN_RIGHT);
529 ty += INPUT_HEIGHT + INNER_MARGIN;
530
531 group->end();
532}
533
534
535void OptionsDialog::createSecurityPage(int tx, int ty, int tw, int th)
536{
537#ifdef HAVE_GNUTLS
538 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Security"));
539
540 int orig_tx;
541 int width, height;
542
543 tx += OUTER_MARGIN;
544 ty += OUTER_MARGIN;
545
546 width = tw - OUTER_MARGIN * 2;
547
548 orig_tx = tx;
549
550 /* Security */
551 vencryptCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
552 CHECK_MIN_WIDTH,
553 CHECK_HEIGHT,
554 _("Extended encryption and authentication methods (VeNCrypt)")));
555 vencryptCheckbox->callback(handleVencrypt, this);
556 ty += CHECK_HEIGHT + INNER_MARGIN;
557
558 /* Encryption */
559 ty += GROUP_LABEL_OFFSET;
560 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 4 + CHECK_HEIGHT * 3 + (INPUT_LABEL_OFFSET + INPUT_HEIGHT) * 2;
561 encryptionGroup = new Fl_Group(tx, ty, width, height, _("Encryption"));
562 encryptionGroup->box(FL_ENGRAVED_BOX);
563 encryptionGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
564
565 {
566 tx += GROUP_MARGIN;
567 ty += GROUP_MARGIN;
568
569 encNoneCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
570 CHECK_MIN_WIDTH,
571 CHECK_HEIGHT,
572 _("None")));
573 ty += CHECK_HEIGHT + TIGHT_MARGIN;
574
575 encTLSCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
576 CHECK_MIN_WIDTH,
577 CHECK_HEIGHT,
578 _("TLS with anonymous certificates")));
579 ty += CHECK_HEIGHT + TIGHT_MARGIN;
580
581 encX509Checkbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
582 CHECK_MIN_WIDTH,
583 CHECK_HEIGHT,
584 _("TLS with X509 certificates")));
585 encX509Checkbox->callback(handleX509, this);
586 ty += CHECK_HEIGHT + TIGHT_MARGIN;
587
588 ty += INPUT_LABEL_OFFSET;
589 caInput = new Fl_Input(tx + INDENT, ty,
590 width - GROUP_MARGIN*2 - INDENT, INPUT_HEIGHT,
591 _("Path to X509 CA certificate"));
592 caInput->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
593 ty += INPUT_HEIGHT + TIGHT_MARGIN;
594
595 ty += INPUT_LABEL_OFFSET;
596 crlInput = new Fl_Input(tx + INDENT, ty,
597 width - GROUP_MARGIN*2 - INDENT, INPUT_HEIGHT,
598 _("Path to X509 CRL file"));
599 crlInput->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
600 ty += INPUT_HEIGHT + TIGHT_MARGIN;
601 }
602
603 ty += GROUP_MARGIN - TIGHT_MARGIN;
604
605 encryptionGroup->end();
606
607 /* Back to normal */
608 tx = orig_tx;
609 ty += INNER_MARGIN;
610
611 /* Authentication */
612 /* Encryption */
613 ty += GROUP_LABEL_OFFSET;
614 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 2 + CHECK_HEIGHT * 3;
615 authenticationGroup = new Fl_Group(tx, ty, width, height, _("Authentication"));
616 authenticationGroup->box(FL_ENGRAVED_BOX);
617 authenticationGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
618
619 {
620 tx += GROUP_MARGIN;
621 ty += GROUP_MARGIN;
622
623 authNoneCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
624 CHECK_MIN_WIDTH,
625 CHECK_HEIGHT,
626 _("None")));
627 ty += CHECK_HEIGHT + TIGHT_MARGIN;
628
629 authVncCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
630 CHECK_MIN_WIDTH,
631 CHECK_HEIGHT,
632 _("Standard VNC (insecure without encryption)")));
633 ty += CHECK_HEIGHT + TIGHT_MARGIN;
634
635 authPlainCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
636 CHECK_MIN_WIDTH,
637 CHECK_HEIGHT,
638 _("Username and password (insecure without encryption)")));
639 ty += CHECK_HEIGHT + TIGHT_MARGIN;
640 }
641
642 ty += GROUP_MARGIN - TIGHT_MARGIN;
643
644 authenticationGroup->end();
645
646 /* Back to normal */
647 tx = orig_tx;
648 ty += INNER_MARGIN;
649
650 group->end();
651#endif
652}
653
654
655void OptionsDialog::createInputPage(int tx, int ty, int tw, int th)
656{
657 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Input"));
658
659 tx += OUTER_MARGIN;
660 ty += OUTER_MARGIN;
661
662 viewOnlyCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
663 CHECK_MIN_WIDTH,
664 CHECK_HEIGHT,
665 _("View only (ignore mouse and keyboard)")));
666 ty += CHECK_HEIGHT + TIGHT_MARGIN;
667
668 acceptClipboardCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
669 CHECK_MIN_WIDTH,
670 CHECK_HEIGHT,
671 _("Accept clipboard from server")));
672 ty += CHECK_HEIGHT + TIGHT_MARGIN;
673
674 sendClipboardCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
675 CHECK_MIN_WIDTH,
676 CHECK_HEIGHT,
677 _("Send clipboard to server")));
678 ty += CHECK_HEIGHT + TIGHT_MARGIN;
679
680 sendPrimaryCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
681 CHECK_MIN_WIDTH,
682 CHECK_HEIGHT,
683 _("Send primary selection and cut buffer as clipboard")));
684 ty += CHECK_HEIGHT + TIGHT_MARGIN;
685
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000686 menuKeyChoice = new Fl_Choice(LBLLEFT(tx, ty, 150, CHOICE_HEIGHT, _("Menu key")));
687
688 menuKeyChoice->add(_("None"), 0, NULL, (void*)0, FL_MENU_DIVIDER);
689 for (int i = 1;i <= 12;i++) {
690 char buf[16];
691 sprintf(buf, "F%d", i);
692 menuKeyChoice->add(buf, 0, NULL, (void*)i, 0);
693 }
694
695 ty += CHOICE_HEIGHT + TIGHT_MARGIN;
696
Pierre Ossmand463b572011-05-16 12:04:43 +0000697 group->end();
698}
699
700
701void OptionsDialog::createMiscPage(int tx, int ty, int tw, int th)
702{
703 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Misc."));
704
705 tx += OUTER_MARGIN;
706 ty += OUTER_MARGIN;
707
708 sharedCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
709 CHECK_MIN_WIDTH,
710 CHECK_HEIGHT,
711 _("Shared (don't disconnect other viewers)")));
712 ty += CHECK_HEIGHT + TIGHT_MARGIN;
713
714 fullScreenCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
715 CHECK_MIN_WIDTH,
716 CHECK_HEIGHT,
717 _("Full-screen mode")));
718 ty += CHECK_HEIGHT + TIGHT_MARGIN;
719
720 localCursorCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
721 CHECK_MIN_WIDTH,
722 CHECK_HEIGHT,
723 _("Render cursor locally")));
724 ty += CHECK_HEIGHT + TIGHT_MARGIN;
725
726 dotCursorCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
727 CHECK_MIN_WIDTH,
728 CHECK_HEIGHT,
729 _("Show dot when no cursor")));
730 ty += CHECK_HEIGHT + TIGHT_MARGIN;
731
732 group->end();
733}
734
735
736void OptionsDialog::handleAutoselect(Fl_Widget *widget, void *data)
737{
738 OptionsDialog *dialog = (OptionsDialog*)data;
739
740 if (dialog->autoselectCheckbox->value()) {
741 dialog->encodingGroup->deactivate();
742 dialog->colorlevelGroup->deactivate();
743 } else {
744 dialog->encodingGroup->activate();
745 dialog->colorlevelGroup->activate();
746 }
747
748 // JPEG setting is also affected by autoselection
749 dialog->handleJpeg(dialog->jpegCheckbox, dialog);
750}
751
752
753void OptionsDialog::handleCompression(Fl_Widget *widget, void *data)
754{
755 OptionsDialog *dialog = (OptionsDialog*)data;
756
757 if (dialog->compressionCheckbox->value())
758 dialog->compressionInput->activate();
759 else
760 dialog->compressionInput->deactivate();
761}
762
763
764void OptionsDialog::handleJpeg(Fl_Widget *widget, void *data)
765{
766 OptionsDialog *dialog = (OptionsDialog*)data;
767
768 if (dialog->jpegCheckbox->value() &&
769 !dialog->autoselectCheckbox->value())
770 dialog->jpegInput->activate();
771 else
772 dialog->jpegInput->deactivate();
773}
774
775
776void OptionsDialog::handleVencrypt(Fl_Widget *widget, void *data)
777{
778 OptionsDialog *dialog = (OptionsDialog*)data;
779
780 if (dialog->vencryptCheckbox->value()) {
781 dialog->encryptionGroup->activate();
782 dialog->authPlainCheckbox->activate();
783 } else {
784 dialog->encryptionGroup->deactivate();
785 dialog->authPlainCheckbox->deactivate();
786 }
787}
788
789
790void OptionsDialog::handleX509(Fl_Widget *widget, void *data)
791{
792 OptionsDialog *dialog = (OptionsDialog*)data;
793
794 if (dialog->encX509Checkbox->value()) {
795 dialog->caInput->activate();
796 dialog->crlInput->activate();
797 } else {
798 dialog->caInput->deactivate();
799 dialog->crlInput->deactivate();
800 }
801}
802
803
804void OptionsDialog::handleCancel(Fl_Widget *widget, void *data)
805{
806 OptionsDialog *dialog = (OptionsDialog*)data;
807
808 dialog->hide();
809}
810
811
812void OptionsDialog::handleOK(Fl_Widget *widget, void *data)
813{
814 OptionsDialog *dialog = (OptionsDialog*)data;
815
816 dialog->hide();
817
818 dialog->storeOptions();
819}