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