blob: 5fd61546672fa8865ead82bef9793df060d083dc [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{
125 loadOptions();
126
127 Fl_Window::show();
128}
129
130
131void OptionsDialog::loadOptions(void)
132{
133 /* Compression */
134 autoselectCheckbox->value(autoSelect);
135
136 int encNum = encodingNum(preferredEncoding);
137
138 switch (encNum) {
139 case encodingTight:
140 tightButton->setonly();
141 break;
142 case encodingZRLE:
143 zrleButton->setonly();
144 break;
145 case encodingHextile:
146 hextileButton->setonly();
147 break;
148 case encodingRaw:
149 rawButton->setonly();
150 break;
151 }
152
153 if (fullColour)
154 fullcolorCheckbox->setonly();
155 else {
156 switch (lowColourLevel) {
157 case 0:
Pierre Ossmancf836f22011-07-14 14:34:09 +0000158 verylowcolorCheckbox->setonly();
Pierre Ossmand463b572011-05-16 12:04:43 +0000159 break;
160 case 1:
161 lowcolorCheckbox->setonly();
162 break;
163 case 2:
Pierre Ossmancf836f22011-07-14 14:34:09 +0000164 mediumcolorCheckbox->setonly();
Pierre Ossmand463b572011-05-16 12:04:43 +0000165 break;
166 }
167 }
168
169 char digit[2] = "0";
170
171 compressionCheckbox->value(customCompressLevel);
172 jpegCheckbox->value(!noJpeg);
173 digit[0] = '0' + compressLevel;
174 compressionInput->value(digit);
175 digit[0] = '0' + qualityLevel;
176 jpegInput->value(digit);
177
178 handleAutoselect(autoselectCheckbox, this);
179 handleCompression(compressionCheckbox, this);
180 handleJpeg(jpegCheckbox, this);
181
182#ifdef HAVE_GNUTLS
183 /* Security */
184 Security security(SecurityClient::secTypes);
185
186 list<U8> secTypes;
187 list<U8>::iterator iter;
188
189 list<U32> secTypesExt;
190 list<U32>::iterator iterExt;
191
192 vencryptCheckbox->value(false);
193
194 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) {
205 case secTypeVeNCrypt:
206 vencryptCheckbox->value(true);
207 break;
208 case secTypeNone:
209 encNoneCheckbox->value(true);
210 authNoneCheckbox->value(true);
211 break;
212 case secTypeVncAuth:
213 encNoneCheckbox->value(true);
214 authVncCheckbox->value(true);
215 break;
216 }
217 }
218
219 secTypesExt = security.GetEnabledExtSecTypes();
220 for (iterExt = secTypesExt.begin(); iterExt != secTypesExt.end(); ++iterExt) {
221 switch (*iterExt) {
222 case secTypePlain:
223 encNoneCheckbox->value(true);
224 authPlainCheckbox->value(true);
225 break;
226 case secTypeTLSNone:
227 encTLSCheckbox->value(true);
228 authNoneCheckbox->value(true);
229 break;
230 case secTypeTLSVnc:
231 encTLSCheckbox->value(true);
232 authVncCheckbox->value(true);
233 break;
234 case secTypeTLSPlain:
235 encTLSCheckbox->value(true);
236 authPlainCheckbox->value(true);
237 break;
238 case secTypeX509None:
239 encX509Checkbox->value(true);
240 authNoneCheckbox->value(true);
241 break;
242 case secTypeX509Vnc:
243 encX509Checkbox->value(true);
244 authVncCheckbox->value(true);
245 break;
246 case secTypeX509Plain:
247 encX509Checkbox->value(true);
248 authPlainCheckbox->value(true);
249 break;
250 }
251 }
252
253 caInput->value(CSecurityTLS::x509ca);
254 crlInput->value(CSecurityTLS::x509crl);
255
256 handleVencrypt(vencryptCheckbox, this);
257 handleX509(encX509Checkbox, this);
258#endif
259
260 /* Input */
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000261 const char *menuKeyBuf;
262
Pierre Ossmand463b572011-05-16 12:04:43 +0000263 viewOnlyCheckbox->value(viewOnly);
264 acceptClipboardCheckbox->value(acceptClipboard);
265 sendClipboardCheckbox->value(sendClipboard);
266 sendPrimaryCheckbox->value(sendPrimary);
Pierre Ossman407a5c32011-05-26 14:48:29 +0000267 systemKeysCheckbox->value(fullscreenSystemKeys);
Pierre Ossmand463b572011-05-16 12:04:43 +0000268
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000269 menuKeyChoice->value(0);
270
271 menuKeyBuf = menuKey;
Martin Koegler498ef462011-09-04 07:04:43 +0000272 for (int i = 0; i < getMenuKeySymbolCount(); i++)
273 if (!strcmp(getMenuKeySymbols()[i].name, menuKeyBuf))
274 menuKeyChoice->value(i + 1);
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000275
Pierre Ossmand463b572011-05-16 12:04:43 +0000276 /* Misc. */
277 sharedCheckbox->value(shared);
278 fullScreenCheckbox->value(fullScreen);
Pierre Ossmand463b572011-05-16 12:04:43 +0000279 dotCursorCheckbox->value(dotWhenNoCursor);
280}
281
282
283void OptionsDialog::storeOptions(void)
284{
Pierre Ossman61fd4862011-05-16 12:46:51 +0000285 /* Compression */
286 autoSelect.setParam(autoselectCheckbox->value());
287
288 if (tightButton->value())
289 preferredEncoding.setParam(encodingName(encodingTight));
290 else if (zrleButton->value())
291 preferredEncoding.setParam(encodingName(encodingZRLE));
292 else if (hextileButton->value())
293 preferredEncoding.setParam(encodingName(encodingHextile));
294 else if (rawButton->value())
295 preferredEncoding.setParam(encodingName(encodingRaw));
296
297 fullColour.setParam(fullcolorCheckbox->value());
Pierre Ossmancf836f22011-07-14 14:34:09 +0000298 if (verylowcolorCheckbox->value())
Pierre Ossman61fd4862011-05-16 12:46:51 +0000299 lowColourLevel.setParam(0);
300 else if (lowcolorCheckbox->value())
301 lowColourLevel.setParam(1);
Pierre Ossmancf836f22011-07-14 14:34:09 +0000302 else if (mediumcolorCheckbox->value())
Pierre Ossman61fd4862011-05-16 12:46:51 +0000303 lowColourLevel.setParam(2);
304
305 customCompressLevel.setParam(compressionCheckbox->value());
306 noJpeg.setParam(!jpegCheckbox->value());
307 compressLevel.setParam(atoi(compressionInput->value()));
308 qualityLevel.setParam(atoi(jpegInput->value()));
309
310#ifdef HAVE_GNUTLS
311 /* Security */
312 Security security;
313
314 /* Process security types which don't use encryption */
315 if (encNoneCheckbox->value()) {
316 if (authNoneCheckbox->value())
317 security.EnableSecType(secTypeNone);
318 if (authVncCheckbox->value())
319 security.EnableSecType(secTypeVncAuth);
320
321 if (vencryptCheckbox->value()) {
322 if (authPlainCheckbox->value())
323 security.EnableSecType(secTypePlain);
324 }
325 }
326
327 if (vencryptCheckbox->value()) {
328 /* Process security types which use TLS encryption */
329 if (encTLSCheckbox->value()) {
330 if (authNoneCheckbox->value())
331 security.EnableSecType(secTypeTLSNone);
332 if (authVncCheckbox->value())
333 security.EnableSecType(secTypeTLSVnc);
334 if (authPlainCheckbox->value())
335 security.EnableSecType(secTypeTLSPlain);
336 }
337
338 /* Process security types which use X509 encryption */
339 if (encX509Checkbox->value()) {
340 if (authNoneCheckbox->value())
341 security.EnableSecType(secTypeX509None);
342 if (authVncCheckbox->value())
343 security.EnableSecType(secTypeX509Vnc);
344 if (authPlainCheckbox->value())
345 security.EnableSecType(secTypeX509Plain);
346 }
347 }
348
349 CSecurityTLS::x509ca.setParam(caInput->value());
350 CSecurityTLS::x509crl.setParam(crlInput->value());
351#endif
352
353 /* Input */
354 viewOnly.setParam(viewOnlyCheckbox->value());
355 acceptClipboard.setParam(acceptClipboardCheckbox->value());
356 sendClipboard.setParam(sendClipboardCheckbox->value());
357 sendPrimary.setParam(sendPrimaryCheckbox->value());
Pierre Ossman407a5c32011-05-26 14:48:29 +0000358 fullscreenSystemKeys.setParam(systemKeysCheckbox->value());
Pierre Ossman61fd4862011-05-16 12:46:51 +0000359
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000360 if (menuKeyChoice->value() == 0)
361 menuKey.setParam("");
362 else {
Martin Koegler498ef462011-09-04 07:04:43 +0000363 menuKey.setParam(menuKeyChoice->text());
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000364 }
365
Pierre Ossman61fd4862011-05-16 12:46:51 +0000366 /* Misc. */
367 shared.setParam(sharedCheckbox->value());
368 fullScreen.setParam(fullScreenCheckbox->value());
Pierre Ossman61fd4862011-05-16 12:46:51 +0000369 dotWhenNoCursor.setParam(dotCursorCheckbox->value());
Pierre Ossman0c41e1d2011-05-17 09:36:04 +0000370
371 std::map<OptionsCallback*, void*>::const_iterator iter;
372
373 for (iter = callbacks.begin();iter != callbacks.end();++iter)
374 iter->first(iter->second);
Pierre Ossmand463b572011-05-16 12:04:43 +0000375}
376
377
378void OptionsDialog::createCompressionPage(int tx, int ty, int tw, int th)
379{
380 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Compression"));
381
382 int orig_tx, orig_ty;
383 int half_width, full_width;
384 int width, height;
385
386 tx += OUTER_MARGIN;
387 ty += OUTER_MARGIN;
388
389 full_width = tw - OUTER_MARGIN * 2;
390 half_width = (full_width - INNER_MARGIN) / 2;
391
392 /* AutoSelect checkbox */
393 autoselectCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
394 CHECK_MIN_WIDTH,
395 CHECK_HEIGHT,
396 _("Auto select")));
397 autoselectCheckbox->callback(handleAutoselect, this);
398 ty += CHECK_HEIGHT + INNER_MARGIN;
399
400 /* Two columns */
401 orig_tx = tx;
402 orig_ty = ty;
403
404 /* VNC encoding box */
405 ty += GROUP_LABEL_OFFSET;
406 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 3 + RADIO_HEIGHT * 4;
407 encodingGroup = new Fl_Group(tx, ty, half_width, height,
408 _("Preferred encoding"));
409 encodingGroup->box(FL_ENGRAVED_BOX);
410 encodingGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
411
412 {
413 tx += GROUP_MARGIN;
414 ty += GROUP_MARGIN;
415
416 width = encodingGroup->w() - GROUP_MARGIN * 2;
417
418 tightButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
419 RADIO_MIN_WIDTH,
420 RADIO_HEIGHT,
Peter Åstrand4c446002011-08-15 12:33:06 +0000421 "Tight"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000422 tightButton->type(FL_RADIO_BUTTON);
423 ty += RADIO_HEIGHT + TIGHT_MARGIN;
424
425 zrleButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
426 RADIO_MIN_WIDTH,
427 RADIO_HEIGHT,
Peter Åstrand4c446002011-08-15 12:33:06 +0000428 "ZRLE"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000429 zrleButton->type(FL_RADIO_BUTTON);
430 ty += RADIO_HEIGHT + TIGHT_MARGIN;
431
432 hextileButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
433 RADIO_MIN_WIDTH,
434 RADIO_HEIGHT,
Peter Åstrand4c446002011-08-15 12:33:06 +0000435 "Hextile"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000436 hextileButton->type(FL_RADIO_BUTTON);
437 ty += RADIO_HEIGHT + TIGHT_MARGIN;
438
439 rawButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
440 RADIO_MIN_WIDTH,
441 RADIO_HEIGHT,
Peter Åstrand4c446002011-08-15 12:33:06 +0000442 "Raw"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000443 rawButton->type(FL_RADIO_BUTTON);
444 ty += RADIO_HEIGHT + TIGHT_MARGIN;
445 }
446
447 ty += GROUP_MARGIN - TIGHT_MARGIN;
448
449 encodingGroup->end();
450
451 /* Second column */
452 tx = orig_tx + half_width + INNER_MARGIN;
453 ty = orig_ty;
454
455 /* Color box */
456 ty += GROUP_LABEL_OFFSET;
457 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 3 + RADIO_HEIGHT * 4;
458 colorlevelGroup = new Fl_Group(tx, ty, half_width, height, _("Color level"));
459 colorlevelGroup->box(FL_ENGRAVED_BOX);
460 colorlevelGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
461
462 {
463 tx += GROUP_MARGIN;
464 ty += GROUP_MARGIN;
465
466 width = colorlevelGroup->w() - GROUP_MARGIN * 2;
467
468 fullcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
469 RADIO_MIN_WIDTH,
470 RADIO_HEIGHT,
471 _("Full (all available colors)")));
472 fullcolorCheckbox->type(FL_RADIO_BUTTON);
473 ty += RADIO_HEIGHT + TIGHT_MARGIN;
474
475 mediumcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
476 RADIO_MIN_WIDTH,
477 RADIO_HEIGHT,
478 _("Medium (256 colors)")));
479 mediumcolorCheckbox->type(FL_RADIO_BUTTON);
480 ty += RADIO_HEIGHT + TIGHT_MARGIN;
481
482 lowcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
483 RADIO_MIN_WIDTH,
484 RADIO_HEIGHT,
485 _("Low (64 colors)")));
486 lowcolorCheckbox->type(FL_RADIO_BUTTON);
487 ty += RADIO_HEIGHT + TIGHT_MARGIN;
488
489 verylowcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
490 RADIO_MIN_WIDTH,
491 RADIO_HEIGHT,
492 _("Very low (8 colors)")));
493 verylowcolorCheckbox->type(FL_RADIO_BUTTON);
494 ty += RADIO_HEIGHT + TIGHT_MARGIN;
495 }
496
497 ty += GROUP_MARGIN - TIGHT_MARGIN;
498
499 colorlevelGroup->end();
500
501 /* Back to normal */
502 tx = orig_tx;
503 ty += INNER_MARGIN;
504
505 /* Checkboxes */
506 compressionCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
507 CHECK_MIN_WIDTH,
508 CHECK_HEIGHT,
509 _("Custom compression level:")));
510 compressionCheckbox->callback(handleCompression, this);
511 ty += CHECK_HEIGHT + TIGHT_MARGIN;
512
513 compressionInput = new Fl_Int_Input(tx + INDENT, ty,
514 INPUT_HEIGHT, INPUT_HEIGHT,
DRCba7bc512011-08-17 02:30:34 +0000515 _("level (1=fast, 6=best [4-6 are rarely useful])"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000516 compressionInput->align(FL_ALIGN_RIGHT);
517 ty += INPUT_HEIGHT + INNER_MARGIN;
518
519 jpegCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
520 CHECK_MIN_WIDTH,
521 CHECK_HEIGHT,
522 _("Allow JPEG compression:")));
523 jpegCheckbox->callback(handleJpeg, this);
524 ty += CHECK_HEIGHT + TIGHT_MARGIN;
525
526 jpegInput = new Fl_Int_Input(tx + INDENT, ty,
527 INPUT_HEIGHT, INPUT_HEIGHT,
DRC41036ed2011-08-23 20:36:50 +0000528 _("quality (0=poor, 9=best)"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000529 jpegInput->align(FL_ALIGN_RIGHT);
530 ty += INPUT_HEIGHT + INNER_MARGIN;
531
532 group->end();
533}
534
535
536void OptionsDialog::createSecurityPage(int tx, int ty, int tw, int th)
537{
538#ifdef HAVE_GNUTLS
539 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Security"));
540
541 int orig_tx;
542 int width, height;
543
544 tx += OUTER_MARGIN;
545 ty += OUTER_MARGIN;
546
547 width = tw - OUTER_MARGIN * 2;
548
549 orig_tx = tx;
550
551 /* Security */
552 vencryptCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
553 CHECK_MIN_WIDTH,
554 CHECK_HEIGHT,
555 _("Extended encryption and authentication methods (VeNCrypt)")));
556 vencryptCheckbox->callback(handleVencrypt, this);
557 ty += CHECK_HEIGHT + INNER_MARGIN;
558
559 /* Encryption */
560 ty += GROUP_LABEL_OFFSET;
561 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 4 + CHECK_HEIGHT * 3 + (INPUT_LABEL_OFFSET + INPUT_HEIGHT) * 2;
562 encryptionGroup = new Fl_Group(tx, ty, width, height, _("Encryption"));
563 encryptionGroup->box(FL_ENGRAVED_BOX);
564 encryptionGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
565
566 {
567 tx += GROUP_MARGIN;
568 ty += GROUP_MARGIN;
569
570 encNoneCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
571 CHECK_MIN_WIDTH,
572 CHECK_HEIGHT,
573 _("None")));
574 ty += CHECK_HEIGHT + TIGHT_MARGIN;
575
576 encTLSCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
577 CHECK_MIN_WIDTH,
578 CHECK_HEIGHT,
579 _("TLS with anonymous certificates")));
580 ty += CHECK_HEIGHT + TIGHT_MARGIN;
581
582 encX509Checkbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
583 CHECK_MIN_WIDTH,
584 CHECK_HEIGHT,
585 _("TLS with X509 certificates")));
586 encX509Checkbox->callback(handleX509, this);
587 ty += CHECK_HEIGHT + TIGHT_MARGIN;
588
589 ty += INPUT_LABEL_OFFSET;
590 caInput = new Fl_Input(tx + INDENT, ty,
591 width - GROUP_MARGIN*2 - INDENT, INPUT_HEIGHT,
592 _("Path to X509 CA certificate"));
593 caInput->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
594 ty += INPUT_HEIGHT + TIGHT_MARGIN;
595
596 ty += INPUT_LABEL_OFFSET;
597 crlInput = new Fl_Input(tx + INDENT, ty,
598 width - GROUP_MARGIN*2 - INDENT, INPUT_HEIGHT,
599 _("Path to X509 CRL file"));
600 crlInput->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
601 ty += INPUT_HEIGHT + TIGHT_MARGIN;
602 }
603
604 ty += GROUP_MARGIN - TIGHT_MARGIN;
605
606 encryptionGroup->end();
607
608 /* Back to normal */
609 tx = orig_tx;
610 ty += INNER_MARGIN;
611
612 /* Authentication */
613 /* Encryption */
614 ty += GROUP_LABEL_OFFSET;
615 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 2 + CHECK_HEIGHT * 3;
616 authenticationGroup = new Fl_Group(tx, ty, width, height, _("Authentication"));
617 authenticationGroup->box(FL_ENGRAVED_BOX);
618 authenticationGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
619
620 {
621 tx += GROUP_MARGIN;
622 ty += GROUP_MARGIN;
623
624 authNoneCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
625 CHECK_MIN_WIDTH,
626 CHECK_HEIGHT,
627 _("None")));
628 ty += CHECK_HEIGHT + TIGHT_MARGIN;
629
630 authVncCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
631 CHECK_MIN_WIDTH,
632 CHECK_HEIGHT,
633 _("Standard VNC (insecure without encryption)")));
634 ty += CHECK_HEIGHT + TIGHT_MARGIN;
635
636 authPlainCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
637 CHECK_MIN_WIDTH,
638 CHECK_HEIGHT,
639 _("Username and password (insecure without encryption)")));
640 ty += CHECK_HEIGHT + TIGHT_MARGIN;
641 }
642
643 ty += GROUP_MARGIN - TIGHT_MARGIN;
644
645 authenticationGroup->end();
646
647 /* Back to normal */
648 tx = orig_tx;
649 ty += INNER_MARGIN;
650
651 group->end();
652#endif
653}
654
655
656void OptionsDialog::createInputPage(int tx, int ty, int tw, int th)
657{
658 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Input"));
659
660 tx += OUTER_MARGIN;
661 ty += OUTER_MARGIN;
662
663 viewOnlyCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
664 CHECK_MIN_WIDTH,
665 CHECK_HEIGHT,
666 _("View only (ignore mouse and keyboard)")));
667 ty += CHECK_HEIGHT + TIGHT_MARGIN;
668
669 acceptClipboardCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
670 CHECK_MIN_WIDTH,
671 CHECK_HEIGHT,
672 _("Accept clipboard from server")));
673 ty += CHECK_HEIGHT + TIGHT_MARGIN;
674
675 sendClipboardCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
676 CHECK_MIN_WIDTH,
677 CHECK_HEIGHT,
678 _("Send clipboard to server")));
679 ty += CHECK_HEIGHT + TIGHT_MARGIN;
680
681 sendPrimaryCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
682 CHECK_MIN_WIDTH,
683 CHECK_HEIGHT,
684 _("Send primary selection and cut buffer as clipboard")));
685 ty += CHECK_HEIGHT + TIGHT_MARGIN;
686
Pierre Ossman407a5c32011-05-26 14:48:29 +0000687 systemKeysCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
688 CHECK_MIN_WIDTH,
689 CHECK_HEIGHT,
690 _("Pass system keys directly to server (full screen)")));
691 ty += CHECK_HEIGHT + TIGHT_MARGIN;
692
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000693 menuKeyChoice = new Fl_Choice(LBLLEFT(tx, ty, 150, CHOICE_HEIGHT, _("Menu key")));
694
695 menuKeyChoice->add(_("None"), 0, NULL, (void*)0, FL_MENU_DIVIDER);
Martin Koegler498ef462011-09-04 07:04:43 +0000696 for (int i = 0; i < getMenuKeySymbolCount(); i++)
697 menuKeyChoice->add(getMenuKeySymbols()[i].name, 0, NULL, 0, 0);
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000698
699 ty += CHOICE_HEIGHT + TIGHT_MARGIN;
700
Pierre Ossmand463b572011-05-16 12:04:43 +0000701 group->end();
702}
703
704
705void OptionsDialog::createMiscPage(int tx, int ty, int tw, int th)
706{
707 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Misc."));
708
709 tx += OUTER_MARGIN;
710 ty += OUTER_MARGIN;
711
712 sharedCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
713 CHECK_MIN_WIDTH,
714 CHECK_HEIGHT,
715 _("Shared (don't disconnect other viewers)")));
716 ty += CHECK_HEIGHT + TIGHT_MARGIN;
717
718 fullScreenCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
719 CHECK_MIN_WIDTH,
720 CHECK_HEIGHT,
721 _("Full-screen mode")));
722 ty += CHECK_HEIGHT + TIGHT_MARGIN;
723
Pierre Ossmand463b572011-05-16 12:04:43 +0000724 dotCursorCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
725 CHECK_MIN_WIDTH,
726 CHECK_HEIGHT,
727 _("Show dot when no cursor")));
728 ty += CHECK_HEIGHT + TIGHT_MARGIN;
729
730 group->end();
731}
732
733
734void OptionsDialog::handleAutoselect(Fl_Widget *widget, void *data)
735{
736 OptionsDialog *dialog = (OptionsDialog*)data;
737
738 if (dialog->autoselectCheckbox->value()) {
739 dialog->encodingGroup->deactivate();
740 dialog->colorlevelGroup->deactivate();
741 } else {
742 dialog->encodingGroup->activate();
743 dialog->colorlevelGroup->activate();
744 }
745
746 // JPEG setting is also affected by autoselection
747 dialog->handleJpeg(dialog->jpegCheckbox, dialog);
748}
749
750
751void OptionsDialog::handleCompression(Fl_Widget *widget, void *data)
752{
753 OptionsDialog *dialog = (OptionsDialog*)data;
754
755 if (dialog->compressionCheckbox->value())
756 dialog->compressionInput->activate();
757 else
758 dialog->compressionInput->deactivate();
759}
760
761
762void OptionsDialog::handleJpeg(Fl_Widget *widget, void *data)
763{
764 OptionsDialog *dialog = (OptionsDialog*)data;
765
766 if (dialog->jpegCheckbox->value() &&
767 !dialog->autoselectCheckbox->value())
768 dialog->jpegInput->activate();
769 else
770 dialog->jpegInput->deactivate();
771}
772
773
774void OptionsDialog::handleVencrypt(Fl_Widget *widget, void *data)
775{
776 OptionsDialog *dialog = (OptionsDialog*)data;
777
778 if (dialog->vencryptCheckbox->value()) {
779 dialog->encryptionGroup->activate();
780 dialog->authPlainCheckbox->activate();
781 } else {
782 dialog->encryptionGroup->deactivate();
783 dialog->authPlainCheckbox->deactivate();
784 }
785}
786
787
788void OptionsDialog::handleX509(Fl_Widget *widget, void *data)
789{
790 OptionsDialog *dialog = (OptionsDialog*)data;
791
792 if (dialog->encX509Checkbox->value()) {
793 dialog->caInput->activate();
794 dialog->crlInput->activate();
795 } else {
796 dialog->caInput->deactivate();
797 dialog->crlInput->deactivate();
798 }
799}
800
801
802void OptionsDialog::handleCancel(Fl_Widget *widget, void *data)
803{
804 OptionsDialog *dialog = (OptionsDialog*)data;
805
806 dialog->hide();
807}
808
809
810void OptionsDialog::handleOK(Fl_Widget *widget, void *data)
811{
812 OptionsDialog *dialog = (OptionsDialog*)data;
813
814 dialog->hide();
815
816 dialog->storeOptions();
817}