blob: 7543579ef5518852fd7341dd5889f5e1e0e52bba [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
Pierre Ossman5535fe62011-09-30 12:11:52 +0000349 SecurityClient::secTypes.setParam(security.ToString());
350
Pierre Ossman61fd4862011-05-16 12:46:51 +0000351 CSecurityTLS::x509ca.setParam(caInput->value());
352 CSecurityTLS::x509crl.setParam(crlInput->value());
353#endif
354
355 /* Input */
356 viewOnly.setParam(viewOnlyCheckbox->value());
357 acceptClipboard.setParam(acceptClipboardCheckbox->value());
358 sendClipboard.setParam(sendClipboardCheckbox->value());
359 sendPrimary.setParam(sendPrimaryCheckbox->value());
Pierre Ossman407a5c32011-05-26 14:48:29 +0000360 fullscreenSystemKeys.setParam(systemKeysCheckbox->value());
Pierre Ossman61fd4862011-05-16 12:46:51 +0000361
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000362 if (menuKeyChoice->value() == 0)
363 menuKey.setParam("");
364 else {
Martin Koegler498ef462011-09-04 07:04:43 +0000365 menuKey.setParam(menuKeyChoice->text());
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000366 }
367
Pierre Ossman61fd4862011-05-16 12:46:51 +0000368 /* Misc. */
369 shared.setParam(sharedCheckbox->value());
370 fullScreen.setParam(fullScreenCheckbox->value());
Pierre Ossman61fd4862011-05-16 12:46:51 +0000371 dotWhenNoCursor.setParam(dotCursorCheckbox->value());
Pierre Ossman0c41e1d2011-05-17 09:36:04 +0000372
373 std::map<OptionsCallback*, void*>::const_iterator iter;
374
375 for (iter = callbacks.begin();iter != callbacks.end();++iter)
376 iter->first(iter->second);
Pierre Ossmand463b572011-05-16 12:04:43 +0000377}
378
379
380void OptionsDialog::createCompressionPage(int tx, int ty, int tw, int th)
381{
382 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Compression"));
383
384 int orig_tx, orig_ty;
385 int half_width, full_width;
386 int width, height;
387
388 tx += OUTER_MARGIN;
389 ty += OUTER_MARGIN;
390
391 full_width = tw - OUTER_MARGIN * 2;
392 half_width = (full_width - INNER_MARGIN) / 2;
393
394 /* AutoSelect checkbox */
395 autoselectCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
396 CHECK_MIN_WIDTH,
397 CHECK_HEIGHT,
398 _("Auto select")));
399 autoselectCheckbox->callback(handleAutoselect, this);
400 ty += CHECK_HEIGHT + INNER_MARGIN;
401
402 /* Two columns */
403 orig_tx = tx;
404 orig_ty = ty;
405
406 /* VNC encoding box */
407 ty += GROUP_LABEL_OFFSET;
408 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 3 + RADIO_HEIGHT * 4;
409 encodingGroup = new Fl_Group(tx, ty, half_width, height,
410 _("Preferred encoding"));
411 encodingGroup->box(FL_ENGRAVED_BOX);
412 encodingGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
413
414 {
415 tx += GROUP_MARGIN;
416 ty += GROUP_MARGIN;
417
418 width = encodingGroup->w() - GROUP_MARGIN * 2;
419
420 tightButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
421 RADIO_MIN_WIDTH,
422 RADIO_HEIGHT,
Peter Åstrand4c446002011-08-15 12:33:06 +0000423 "Tight"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000424 tightButton->type(FL_RADIO_BUTTON);
425 ty += RADIO_HEIGHT + TIGHT_MARGIN;
426
427 zrleButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
428 RADIO_MIN_WIDTH,
429 RADIO_HEIGHT,
Peter Åstrand4c446002011-08-15 12:33:06 +0000430 "ZRLE"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000431 zrleButton->type(FL_RADIO_BUTTON);
432 ty += RADIO_HEIGHT + TIGHT_MARGIN;
433
434 hextileButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
435 RADIO_MIN_WIDTH,
436 RADIO_HEIGHT,
Peter Åstrand4c446002011-08-15 12:33:06 +0000437 "Hextile"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000438 hextileButton->type(FL_RADIO_BUTTON);
439 ty += RADIO_HEIGHT + TIGHT_MARGIN;
440
441 rawButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
442 RADIO_MIN_WIDTH,
443 RADIO_HEIGHT,
Peter Åstrand4c446002011-08-15 12:33:06 +0000444 "Raw"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000445 rawButton->type(FL_RADIO_BUTTON);
446 ty += RADIO_HEIGHT + TIGHT_MARGIN;
447 }
448
449 ty += GROUP_MARGIN - TIGHT_MARGIN;
450
451 encodingGroup->end();
452
453 /* Second column */
454 tx = orig_tx + half_width + INNER_MARGIN;
455 ty = orig_ty;
456
457 /* Color box */
458 ty += GROUP_LABEL_OFFSET;
459 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 3 + RADIO_HEIGHT * 4;
460 colorlevelGroup = new Fl_Group(tx, ty, half_width, height, _("Color level"));
461 colorlevelGroup->box(FL_ENGRAVED_BOX);
462 colorlevelGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
463
464 {
465 tx += GROUP_MARGIN;
466 ty += GROUP_MARGIN;
467
468 width = colorlevelGroup->w() - GROUP_MARGIN * 2;
469
470 fullcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
471 RADIO_MIN_WIDTH,
472 RADIO_HEIGHT,
473 _("Full (all available colors)")));
474 fullcolorCheckbox->type(FL_RADIO_BUTTON);
475 ty += RADIO_HEIGHT + TIGHT_MARGIN;
476
477 mediumcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
478 RADIO_MIN_WIDTH,
479 RADIO_HEIGHT,
480 _("Medium (256 colors)")));
481 mediumcolorCheckbox->type(FL_RADIO_BUTTON);
482 ty += RADIO_HEIGHT + TIGHT_MARGIN;
483
484 lowcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
485 RADIO_MIN_WIDTH,
486 RADIO_HEIGHT,
487 _("Low (64 colors)")));
488 lowcolorCheckbox->type(FL_RADIO_BUTTON);
489 ty += RADIO_HEIGHT + TIGHT_MARGIN;
490
491 verylowcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
492 RADIO_MIN_WIDTH,
493 RADIO_HEIGHT,
494 _("Very low (8 colors)")));
495 verylowcolorCheckbox->type(FL_RADIO_BUTTON);
496 ty += RADIO_HEIGHT + TIGHT_MARGIN;
497 }
498
499 ty += GROUP_MARGIN - TIGHT_MARGIN;
500
501 colorlevelGroup->end();
502
503 /* Back to normal */
504 tx = orig_tx;
505 ty += INNER_MARGIN;
506
507 /* Checkboxes */
508 compressionCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
509 CHECK_MIN_WIDTH,
510 CHECK_HEIGHT,
511 _("Custom compression level:")));
512 compressionCheckbox->callback(handleCompression, this);
513 ty += CHECK_HEIGHT + TIGHT_MARGIN;
514
515 compressionInput = new Fl_Int_Input(tx + INDENT, ty,
516 INPUT_HEIGHT, INPUT_HEIGHT,
DRCba7bc512011-08-17 02:30:34 +0000517 _("level (1=fast, 6=best [4-6 are rarely useful])"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000518 compressionInput->align(FL_ALIGN_RIGHT);
519 ty += INPUT_HEIGHT + INNER_MARGIN;
520
521 jpegCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
522 CHECK_MIN_WIDTH,
523 CHECK_HEIGHT,
524 _("Allow JPEG compression:")));
525 jpegCheckbox->callback(handleJpeg, this);
526 ty += CHECK_HEIGHT + TIGHT_MARGIN;
527
528 jpegInput = new Fl_Int_Input(tx + INDENT, ty,
529 INPUT_HEIGHT, INPUT_HEIGHT,
DRC41036ed2011-08-23 20:36:50 +0000530 _("quality (0=poor, 9=best)"));
Pierre Ossmand463b572011-05-16 12:04:43 +0000531 jpegInput->align(FL_ALIGN_RIGHT);
532 ty += INPUT_HEIGHT + INNER_MARGIN;
533
534 group->end();
535}
536
537
538void OptionsDialog::createSecurityPage(int tx, int ty, int tw, int th)
539{
540#ifdef HAVE_GNUTLS
541 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Security"));
542
543 int orig_tx;
544 int width, height;
545
546 tx += OUTER_MARGIN;
547 ty += OUTER_MARGIN;
548
549 width = tw - OUTER_MARGIN * 2;
550
551 orig_tx = tx;
552
553 /* Security */
554 vencryptCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
555 CHECK_MIN_WIDTH,
556 CHECK_HEIGHT,
557 _("Extended encryption and authentication methods (VeNCrypt)")));
558 vencryptCheckbox->callback(handleVencrypt, this);
559 ty += CHECK_HEIGHT + INNER_MARGIN;
560
561 /* Encryption */
562 ty += GROUP_LABEL_OFFSET;
563 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 4 + CHECK_HEIGHT * 3 + (INPUT_LABEL_OFFSET + INPUT_HEIGHT) * 2;
564 encryptionGroup = new Fl_Group(tx, ty, width, height, _("Encryption"));
565 encryptionGroup->box(FL_ENGRAVED_BOX);
566 encryptionGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
567
568 {
569 tx += GROUP_MARGIN;
570 ty += GROUP_MARGIN;
571
572 encNoneCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
573 CHECK_MIN_WIDTH,
574 CHECK_HEIGHT,
575 _("None")));
576 ty += CHECK_HEIGHT + TIGHT_MARGIN;
577
578 encTLSCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
579 CHECK_MIN_WIDTH,
580 CHECK_HEIGHT,
581 _("TLS with anonymous certificates")));
582 ty += CHECK_HEIGHT + TIGHT_MARGIN;
583
584 encX509Checkbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
585 CHECK_MIN_WIDTH,
586 CHECK_HEIGHT,
587 _("TLS with X509 certificates")));
588 encX509Checkbox->callback(handleX509, this);
589 ty += CHECK_HEIGHT + TIGHT_MARGIN;
590
591 ty += INPUT_LABEL_OFFSET;
592 caInput = new Fl_Input(tx + INDENT, ty,
593 width - GROUP_MARGIN*2 - INDENT, INPUT_HEIGHT,
594 _("Path to X509 CA certificate"));
595 caInput->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
596 ty += INPUT_HEIGHT + TIGHT_MARGIN;
597
598 ty += INPUT_LABEL_OFFSET;
599 crlInput = new Fl_Input(tx + INDENT, ty,
600 width - GROUP_MARGIN*2 - INDENT, INPUT_HEIGHT,
601 _("Path to X509 CRL file"));
602 crlInput->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
603 ty += INPUT_HEIGHT + TIGHT_MARGIN;
604 }
605
606 ty += GROUP_MARGIN - TIGHT_MARGIN;
607
608 encryptionGroup->end();
609
610 /* Back to normal */
611 tx = orig_tx;
612 ty += INNER_MARGIN;
613
614 /* Authentication */
615 /* Encryption */
616 ty += GROUP_LABEL_OFFSET;
617 height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 2 + CHECK_HEIGHT * 3;
618 authenticationGroup = new Fl_Group(tx, ty, width, height, _("Authentication"));
619 authenticationGroup->box(FL_ENGRAVED_BOX);
620 authenticationGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
621
622 {
623 tx += GROUP_MARGIN;
624 ty += GROUP_MARGIN;
625
626 authNoneCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
627 CHECK_MIN_WIDTH,
628 CHECK_HEIGHT,
629 _("None")));
630 ty += CHECK_HEIGHT + TIGHT_MARGIN;
631
632 authVncCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
633 CHECK_MIN_WIDTH,
634 CHECK_HEIGHT,
635 _("Standard VNC (insecure without encryption)")));
636 ty += CHECK_HEIGHT + TIGHT_MARGIN;
637
638 authPlainCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
639 CHECK_MIN_WIDTH,
640 CHECK_HEIGHT,
641 _("Username and password (insecure without encryption)")));
642 ty += CHECK_HEIGHT + TIGHT_MARGIN;
643 }
644
645 ty += GROUP_MARGIN - TIGHT_MARGIN;
646
647 authenticationGroup->end();
648
649 /* Back to normal */
650 tx = orig_tx;
651 ty += INNER_MARGIN;
652
653 group->end();
654#endif
655}
656
657
658void OptionsDialog::createInputPage(int tx, int ty, int tw, int th)
659{
660 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Input"));
661
662 tx += OUTER_MARGIN;
663 ty += OUTER_MARGIN;
664
665 viewOnlyCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
666 CHECK_MIN_WIDTH,
667 CHECK_HEIGHT,
668 _("View only (ignore mouse and keyboard)")));
669 ty += CHECK_HEIGHT + TIGHT_MARGIN;
670
671 acceptClipboardCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
672 CHECK_MIN_WIDTH,
673 CHECK_HEIGHT,
674 _("Accept clipboard from server")));
675 ty += CHECK_HEIGHT + TIGHT_MARGIN;
676
677 sendClipboardCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
678 CHECK_MIN_WIDTH,
679 CHECK_HEIGHT,
680 _("Send clipboard to server")));
681 ty += CHECK_HEIGHT + TIGHT_MARGIN;
682
683 sendPrimaryCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
684 CHECK_MIN_WIDTH,
685 CHECK_HEIGHT,
686 _("Send primary selection and cut buffer as clipboard")));
687 ty += CHECK_HEIGHT + TIGHT_MARGIN;
688
Pierre Ossman407a5c32011-05-26 14:48:29 +0000689 systemKeysCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
690 CHECK_MIN_WIDTH,
691 CHECK_HEIGHT,
692 _("Pass system keys directly to server (full screen)")));
693 ty += CHECK_HEIGHT + TIGHT_MARGIN;
694
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000695 menuKeyChoice = new Fl_Choice(LBLLEFT(tx, ty, 150, CHOICE_HEIGHT, _("Menu key")));
696
697 menuKeyChoice->add(_("None"), 0, NULL, (void*)0, FL_MENU_DIVIDER);
Martin Koegler498ef462011-09-04 07:04:43 +0000698 for (int i = 0; i < getMenuKeySymbolCount(); i++)
699 menuKeyChoice->add(getMenuKeySymbols()[i].name, 0, NULL, 0, 0);
Pierre Ossman4e7271e2011-05-24 12:47:12 +0000700
701 ty += CHOICE_HEIGHT + TIGHT_MARGIN;
702
Pierre Ossmand463b572011-05-16 12:04:43 +0000703 group->end();
704}
705
706
707void OptionsDialog::createMiscPage(int tx, int ty, int tw, int th)
708{
709 Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Misc."));
710
711 tx += OUTER_MARGIN;
712 ty += OUTER_MARGIN;
713
714 sharedCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
715 CHECK_MIN_WIDTH,
716 CHECK_HEIGHT,
717 _("Shared (don't disconnect other viewers)")));
718 ty += CHECK_HEIGHT + TIGHT_MARGIN;
719
720 fullScreenCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
721 CHECK_MIN_WIDTH,
722 CHECK_HEIGHT,
723 _("Full-screen mode")));
724 ty += CHECK_HEIGHT + TIGHT_MARGIN;
725
Pierre Ossmand463b572011-05-16 12:04:43 +0000726 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}