summaryrefslogtreecommitdiffstats
path: root/vncviewer
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2011-05-16 12:04:43 +0000
committerPierre Ossman <ossman@cendio.se>2011-05-16 12:04:43 +0000
commitd463b57681c875f096e32250919e5a23f58a439a (patch)
treea2d94e3b5f45c75f3d52222edc65b9b7a3cc15ab /vncviewer
parent2b006fd93177653cdb4ae87220265f52a34a0d65 (diff)
downloadtigervnc-d463b57681c875f096e32250919e5a23f58a439a.tar.gz
tigervnc-d463b57681c875f096e32250919e5a23f58a439a.zip
Initial options dialog (read-only) loosly based on the Unix vncviewer.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4416 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'vncviewer')
-rw-r--r--vncviewer/CMakeLists.txt1
-rw-r--r--vncviewer/OptionsDialog.cxx689
-rw-r--r--vncviewer/OptionsDialog.h106
-rw-r--r--vncviewer/ServerDialog.cxx14
-rw-r--r--vncviewer/ServerDialog.h1
-rw-r--r--vncviewer/Viewport.cxx7
-rw-r--r--vncviewer/fltk_layout.h86
7 files changed, 901 insertions, 3 deletions
diff --git a/vncviewer/CMakeLists.txt b/vncviewer/CMakeLists.txt
index 36561f8d..ecf7b692 100644
--- a/vncviewer/CMakeLists.txt
+++ b/vncviewer/CMakeLists.txt
@@ -7,6 +7,7 @@ set(VNCVIEWER_SOURCES
DesktopWindow.cxx
UserDialog.cxx
ServerDialog.cxx
+ OptionsDialog.cxx
Viewport.cxx
parameters.cxx
keysym2ucs.c
diff --git a/vncviewer/OptionsDialog.cxx b/vncviewer/OptionsDialog.cxx
new file mode 100644
index 00000000..4c9e0880
--- /dev/null
+++ b/vncviewer/OptionsDialog.cxx
@@ -0,0 +1,689 @@
+/* Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+#include <list>
+
+#include <FL/Fl_Tabs.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Return_Button.H>
+
+#include <rdr/types.h>
+#include <rfb/encodings.h>
+
+#ifdef HAVE_GNUTLS
+#include <rfb/Security.h>
+#include <rfb/SecurityClient.h>
+#include <rfb/CSecurityTLS.h>
+#endif
+
+#include "OptionsDialog.h"
+#include "fltk_layout.h"
+#include "i18n.h"
+#include "parameters.h"
+
+using namespace std;
+using namespace rdr;
+using namespace rfb;
+
+OptionsDialog::OptionsDialog()
+ : Fl_Window(450, 450, _("VNC Viewer: Connection Options"))
+{
+ int x, y;
+ Fl_Button *button;
+
+ Fl_Tabs *tabs = new Fl_Tabs(OUTER_MARGIN, OUTER_MARGIN,
+ w() - OUTER_MARGIN*2,
+ h() - OUTER_MARGIN*2 - INNER_MARGIN - BUTTON_HEIGHT);
+
+ {
+ int tx, ty, tw, th;
+
+ tabs->client_area(tx, ty, tw, th, TABS_HEIGHT);
+
+ createCompressionPage(tx, ty, tw, th);
+ createSecurityPage(tx, ty, tw, th);
+ createInputPage(tx, ty, tw, th);
+ createMiscPage(tx, ty, tw, th);
+ }
+
+ tabs->end();
+
+ x = w() - BUTTON_WIDTH * 2 - INNER_MARGIN - OUTER_MARGIN;
+ y = h() - BUTTON_HEIGHT - OUTER_MARGIN;
+
+ button = new Fl_Button(x, y, BUTTON_WIDTH, BUTTON_HEIGHT, _("Cancel"));
+ button->callback(this->handleCancel, this);
+
+ x += BUTTON_WIDTH + INNER_MARGIN;
+
+ button = new Fl_Return_Button(x, y, BUTTON_WIDTH, BUTTON_HEIGHT, _("OK"));
+ button->callback(this->handleOK, this);
+
+ callback(this->handleCancel, this);
+
+ set_modal();
+}
+
+
+OptionsDialog::~OptionsDialog()
+{
+}
+
+
+void OptionsDialog::showDialog(void)
+{
+ static OptionsDialog *dialog = NULL;
+
+ if (!dialog)
+ dialog = new OptionsDialog();
+
+ if (dialog->shown())
+ return;
+
+ dialog->show();
+}
+
+
+void OptionsDialog::show(void)
+{
+ loadOptions();
+
+ Fl_Window::show();
+}
+
+
+void OptionsDialog::loadOptions(void)
+{
+ /* Compression */
+ autoselectCheckbox->value(autoSelect);
+
+ int encNum = encodingNum(preferredEncoding);
+
+ switch (encNum) {
+ case encodingTight:
+ tightButton->setonly();
+ break;
+ case encodingZRLE:
+ zrleButton->setonly();
+ break;
+ case encodingHextile:
+ hextileButton->setonly();
+ break;
+ case encodingRaw:
+ rawButton->setonly();
+ break;
+ }
+
+ if (fullColour)
+ fullcolorCheckbox->setonly();
+ else {
+ switch (lowColourLevel) {
+ case 0:
+ mediumcolorCheckbox->setonly();
+ break;
+ case 1:
+ lowcolorCheckbox->setonly();
+ break;
+ case 2:
+ verylowcolorCheckbox->setonly();
+ break;
+ }
+ }
+
+ char digit[2] = "0";
+
+ compressionCheckbox->value(customCompressLevel);
+ jpegCheckbox->value(!noJpeg);
+ digit[0] = '0' + compressLevel;
+ compressionInput->value(digit);
+ digit[0] = '0' + qualityLevel;
+ jpegInput->value(digit);
+
+ handleAutoselect(autoselectCheckbox, this);
+ handleCompression(compressionCheckbox, this);
+ handleJpeg(jpegCheckbox, this);
+
+#ifdef HAVE_GNUTLS
+ /* Security */
+ Security security(SecurityClient::secTypes);
+
+ list<U8> secTypes;
+ list<U8>::iterator iter;
+
+ list<U32> secTypesExt;
+ list<U32>::iterator iterExt;
+
+ vencryptCheckbox->value(false);
+
+ encNoneCheckbox->value(false);
+ encTLSCheckbox->value(false);
+ encX509Checkbox->value(false);
+
+ authNoneCheckbox->value(false);
+ authVncCheckbox->value(false);
+ authPlainCheckbox->value(false);
+
+ secTypes = security.GetEnabledSecTypes();
+ for (iter = secTypes.begin(); iter != secTypes.end(); ++iter) {
+ switch (*iter) {
+ case secTypeVeNCrypt:
+ vencryptCheckbox->value(true);
+ break;
+ case secTypeNone:
+ encNoneCheckbox->value(true);
+ authNoneCheckbox->value(true);
+ break;
+ case secTypeVncAuth:
+ encNoneCheckbox->value(true);
+ authVncCheckbox->value(true);
+ break;
+ }
+ }
+
+ secTypesExt = security.GetEnabledExtSecTypes();
+ for (iterExt = secTypesExt.begin(); iterExt != secTypesExt.end(); ++iterExt) {
+ switch (*iterExt) {
+ case secTypePlain:
+ encNoneCheckbox->value(true);
+ authPlainCheckbox->value(true);
+ break;
+ case secTypeTLSNone:
+ encTLSCheckbox->value(true);
+ authNoneCheckbox->value(true);
+ break;
+ case secTypeTLSVnc:
+ encTLSCheckbox->value(true);
+ authVncCheckbox->value(true);
+ break;
+ case secTypeTLSPlain:
+ encTLSCheckbox->value(true);
+ authPlainCheckbox->value(true);
+ break;
+ case secTypeX509None:
+ encX509Checkbox->value(true);
+ authNoneCheckbox->value(true);
+ break;
+ case secTypeX509Vnc:
+ encX509Checkbox->value(true);
+ authVncCheckbox->value(true);
+ break;
+ case secTypeX509Plain:
+ encX509Checkbox->value(true);
+ authPlainCheckbox->value(true);
+ break;
+ }
+ }
+
+ caInput->value(CSecurityTLS::x509ca);
+ crlInput->value(CSecurityTLS::x509crl);
+
+ handleVencrypt(vencryptCheckbox, this);
+ handleX509(encX509Checkbox, this);
+#endif
+
+ /* Input */
+ viewOnlyCheckbox->value(viewOnly);
+ acceptClipboardCheckbox->value(acceptClipboard);
+ sendClipboardCheckbox->value(sendClipboard);
+ sendPrimaryCheckbox->value(sendPrimary);
+
+ /* Misc. */
+ sharedCheckbox->value(shared);
+ fullScreenCheckbox->value(fullScreen);
+ localCursorCheckbox->value(useLocalCursor);
+ dotCursorCheckbox->value(dotWhenNoCursor);
+}
+
+
+void OptionsDialog::storeOptions(void)
+{
+}
+
+
+void OptionsDialog::createCompressionPage(int tx, int ty, int tw, int th)
+{
+ Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Compression"));
+
+ int orig_tx, orig_ty;
+ int half_width, full_width;
+ int width, height;
+
+ tx += OUTER_MARGIN;
+ ty += OUTER_MARGIN;
+
+ full_width = tw - OUTER_MARGIN * 2;
+ half_width = (full_width - INNER_MARGIN) / 2;
+
+ /* AutoSelect checkbox */
+ autoselectCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("Auto select")));
+ autoselectCheckbox->callback(handleAutoselect, this);
+ ty += CHECK_HEIGHT + INNER_MARGIN;
+
+ /* Two columns */
+ orig_tx = tx;
+ orig_ty = ty;
+
+ /* VNC encoding box */
+ ty += GROUP_LABEL_OFFSET;
+ height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 3 + RADIO_HEIGHT * 4;
+ encodingGroup = new Fl_Group(tx, ty, half_width, height,
+ _("Preferred encoding"));
+ encodingGroup->box(FL_ENGRAVED_BOX);
+ encodingGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
+
+ {
+ tx += GROUP_MARGIN;
+ ty += GROUP_MARGIN;
+
+ width = encodingGroup->w() - GROUP_MARGIN * 2;
+
+ tightButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
+ RADIO_MIN_WIDTH,
+ RADIO_HEIGHT,
+ _("Tight")));
+ tightButton->type(FL_RADIO_BUTTON);
+ ty += RADIO_HEIGHT + TIGHT_MARGIN;
+
+ zrleButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
+ RADIO_MIN_WIDTH,
+ RADIO_HEIGHT,
+ _("ZRLE")));
+ zrleButton->type(FL_RADIO_BUTTON);
+ ty += RADIO_HEIGHT + TIGHT_MARGIN;
+
+ hextileButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
+ RADIO_MIN_WIDTH,
+ RADIO_HEIGHT,
+ _("Hextile")));
+ hextileButton->type(FL_RADIO_BUTTON);
+ ty += RADIO_HEIGHT + TIGHT_MARGIN;
+
+ rawButton = new Fl_Round_Button(LBLRIGHT(tx, ty,
+ RADIO_MIN_WIDTH,
+ RADIO_HEIGHT,
+ _("Raw")));
+ rawButton->type(FL_RADIO_BUTTON);
+ ty += RADIO_HEIGHT + TIGHT_MARGIN;
+ }
+
+ ty += GROUP_MARGIN - TIGHT_MARGIN;
+
+ encodingGroup->end();
+
+ /* Second column */
+ tx = orig_tx + half_width + INNER_MARGIN;
+ ty = orig_ty;
+
+ /* Color box */
+ ty += GROUP_LABEL_OFFSET;
+ height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 3 + RADIO_HEIGHT * 4;
+ colorlevelGroup = new Fl_Group(tx, ty, half_width, height, _("Color level"));
+ colorlevelGroup->box(FL_ENGRAVED_BOX);
+ colorlevelGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
+
+ {
+ tx += GROUP_MARGIN;
+ ty += GROUP_MARGIN;
+
+ width = colorlevelGroup->w() - GROUP_MARGIN * 2;
+
+ fullcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
+ RADIO_MIN_WIDTH,
+ RADIO_HEIGHT,
+ _("Full (all available colors)")));
+ fullcolorCheckbox->type(FL_RADIO_BUTTON);
+ ty += RADIO_HEIGHT + TIGHT_MARGIN;
+
+ mediumcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
+ RADIO_MIN_WIDTH,
+ RADIO_HEIGHT,
+ _("Medium (256 colors)")));
+ mediumcolorCheckbox->type(FL_RADIO_BUTTON);
+ ty += RADIO_HEIGHT + TIGHT_MARGIN;
+
+ lowcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
+ RADIO_MIN_WIDTH,
+ RADIO_HEIGHT,
+ _("Low (64 colors)")));
+ lowcolorCheckbox->type(FL_RADIO_BUTTON);
+ ty += RADIO_HEIGHT + TIGHT_MARGIN;
+
+ verylowcolorCheckbox = new Fl_Round_Button(LBLRIGHT(tx, ty,
+ RADIO_MIN_WIDTH,
+ RADIO_HEIGHT,
+ _("Very low (8 colors)")));
+ verylowcolorCheckbox->type(FL_RADIO_BUTTON);
+ ty += RADIO_HEIGHT + TIGHT_MARGIN;
+ }
+
+ ty += GROUP_MARGIN - TIGHT_MARGIN;
+
+ colorlevelGroup->end();
+
+ /* Back to normal */
+ tx = orig_tx;
+ ty += INNER_MARGIN;
+
+ /* Checkboxes */
+ compressionCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("Custom compression level:")));
+ compressionCheckbox->callback(handleCompression, this);
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ compressionInput = new Fl_Int_Input(tx + INDENT, ty,
+ INPUT_HEIGHT, INPUT_HEIGHT,
+ _("level (1=fast, 9=best)"));
+ compressionInput->align(FL_ALIGN_RIGHT);
+ ty += INPUT_HEIGHT + INNER_MARGIN;
+
+ jpegCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("Allow JPEG compression:")));
+ jpegCheckbox->callback(handleJpeg, this);
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ jpegInput = new Fl_Int_Input(tx + INDENT, ty,
+ INPUT_HEIGHT, INPUT_HEIGHT,
+ _("quality (1=poor, 9=best)"));
+ jpegInput->align(FL_ALIGN_RIGHT);
+ ty += INPUT_HEIGHT + INNER_MARGIN;
+
+ group->end();
+}
+
+
+void OptionsDialog::createSecurityPage(int tx, int ty, int tw, int th)
+{
+#ifdef HAVE_GNUTLS
+ Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Security"));
+
+ int orig_tx;
+ int width, height;
+
+ tx += OUTER_MARGIN;
+ ty += OUTER_MARGIN;
+
+ width = tw - OUTER_MARGIN * 2;
+
+ orig_tx = tx;
+
+ /* Security */
+ vencryptCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("Extended encryption and authentication methods (VeNCrypt)")));
+ vencryptCheckbox->callback(handleVencrypt, this);
+ ty += CHECK_HEIGHT + INNER_MARGIN;
+
+ /* Encryption */
+ ty += GROUP_LABEL_OFFSET;
+ height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 4 + CHECK_HEIGHT * 3 + (INPUT_LABEL_OFFSET + INPUT_HEIGHT) * 2;
+ encryptionGroup = new Fl_Group(tx, ty, width, height, _("Encryption"));
+ encryptionGroup->box(FL_ENGRAVED_BOX);
+ encryptionGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
+
+ {
+ tx += GROUP_MARGIN;
+ ty += GROUP_MARGIN;
+
+ encNoneCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("None")));
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ encTLSCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("TLS with anonymous certificates")));
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ encX509Checkbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("TLS with X509 certificates")));
+ encX509Checkbox->callback(handleX509, this);
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ ty += INPUT_LABEL_OFFSET;
+ caInput = new Fl_Input(tx + INDENT, ty,
+ width - GROUP_MARGIN*2 - INDENT, INPUT_HEIGHT,
+ _("Path to X509 CA certificate"));
+ caInput->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
+ ty += INPUT_HEIGHT + TIGHT_MARGIN;
+
+ ty += INPUT_LABEL_OFFSET;
+ crlInput = new Fl_Input(tx + INDENT, ty,
+ width - GROUP_MARGIN*2 - INDENT, INPUT_HEIGHT,
+ _("Path to X509 CRL file"));
+ crlInput->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
+ ty += INPUT_HEIGHT + TIGHT_MARGIN;
+ }
+
+ ty += GROUP_MARGIN - TIGHT_MARGIN;
+
+ encryptionGroup->end();
+
+ /* Back to normal */
+ tx = orig_tx;
+ ty += INNER_MARGIN;
+
+ /* Authentication */
+ /* Encryption */
+ ty += GROUP_LABEL_OFFSET;
+ height = GROUP_MARGIN * 2 + TIGHT_MARGIN * 2 + CHECK_HEIGHT * 3;
+ authenticationGroup = new Fl_Group(tx, ty, width, height, _("Authentication"));
+ authenticationGroup->box(FL_ENGRAVED_BOX);
+ authenticationGroup->align(FL_ALIGN_LEFT | FL_ALIGN_TOP);
+
+ {
+ tx += GROUP_MARGIN;
+ ty += GROUP_MARGIN;
+
+ authNoneCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("None")));
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ authVncCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("Standard VNC (insecure without encryption)")));
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ authPlainCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("Username and password (insecure without encryption)")));
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+ }
+
+ ty += GROUP_MARGIN - TIGHT_MARGIN;
+
+ authenticationGroup->end();
+
+ /* Back to normal */
+ tx = orig_tx;
+ ty += INNER_MARGIN;
+
+ group->end();
+#endif
+}
+
+
+void OptionsDialog::createInputPage(int tx, int ty, int tw, int th)
+{
+ Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Input"));
+
+ tx += OUTER_MARGIN;
+ ty += OUTER_MARGIN;
+
+ viewOnlyCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("View only (ignore mouse and keyboard)")));
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ acceptClipboardCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("Accept clipboard from server")));
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ sendClipboardCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("Send clipboard to server")));
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ sendPrimaryCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("Send primary selection and cut buffer as clipboard")));
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ group->end();
+}
+
+
+void OptionsDialog::createMiscPage(int tx, int ty, int tw, int th)
+{
+ Fl_Group *group = new Fl_Group(tx, ty, tw, th, _("Misc."));
+
+ tx += OUTER_MARGIN;
+ ty += OUTER_MARGIN;
+
+ sharedCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("Shared (don't disconnect other viewers)")));
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ fullScreenCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("Full-screen mode")));
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ localCursorCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("Render cursor locally")));
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ dotCursorCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+ CHECK_MIN_WIDTH,
+ CHECK_HEIGHT,
+ _("Show dot when no cursor")));
+ ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
+ group->end();
+}
+
+
+void OptionsDialog::handleAutoselect(Fl_Widget *widget, void *data)
+{
+ OptionsDialog *dialog = (OptionsDialog*)data;
+
+ if (dialog->autoselectCheckbox->value()) {
+ dialog->encodingGroup->deactivate();
+ dialog->colorlevelGroup->deactivate();
+ } else {
+ dialog->encodingGroup->activate();
+ dialog->colorlevelGroup->activate();
+ }
+
+ // JPEG setting is also affected by autoselection
+ dialog->handleJpeg(dialog->jpegCheckbox, dialog);
+}
+
+
+void OptionsDialog::handleCompression(Fl_Widget *widget, void *data)
+{
+ OptionsDialog *dialog = (OptionsDialog*)data;
+
+ if (dialog->compressionCheckbox->value())
+ dialog->compressionInput->activate();
+ else
+ dialog->compressionInput->deactivate();
+}
+
+
+void OptionsDialog::handleJpeg(Fl_Widget *widget, void *data)
+{
+ OptionsDialog *dialog = (OptionsDialog*)data;
+
+ if (dialog->jpegCheckbox->value() &&
+ !dialog->autoselectCheckbox->value())
+ dialog->jpegInput->activate();
+ else
+ dialog->jpegInput->deactivate();
+}
+
+
+void OptionsDialog::handleVencrypt(Fl_Widget *widget, void *data)
+{
+ OptionsDialog *dialog = (OptionsDialog*)data;
+
+ if (dialog->vencryptCheckbox->value()) {
+ dialog->encryptionGroup->activate();
+ dialog->authPlainCheckbox->activate();
+ } else {
+ dialog->encryptionGroup->deactivate();
+ dialog->authPlainCheckbox->deactivate();
+ }
+}
+
+
+void OptionsDialog::handleX509(Fl_Widget *widget, void *data)
+{
+ OptionsDialog *dialog = (OptionsDialog*)data;
+
+ if (dialog->encX509Checkbox->value()) {
+ dialog->caInput->activate();
+ dialog->crlInput->activate();
+ } else {
+ dialog->caInput->deactivate();
+ dialog->crlInput->deactivate();
+ }
+}
+
+
+void OptionsDialog::handleCancel(Fl_Widget *widget, void *data)
+{
+ OptionsDialog *dialog = (OptionsDialog*)data;
+
+ dialog->hide();
+}
+
+
+void OptionsDialog::handleOK(Fl_Widget *widget, void *data)
+{
+ OptionsDialog *dialog = (OptionsDialog*)data;
+
+ dialog->hide();
+
+ dialog->storeOptions();
+}
diff --git a/vncviewer/OptionsDialog.h b/vncviewer/OptionsDialog.h
new file mode 100644
index 00000000..cb18bcd5
--- /dev/null
+++ b/vncviewer/OptionsDialog.h
@@ -0,0 +1,106 @@
+/* Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+#ifndef __OPTIONSDIALOG_H__
+#define __OPTIONSDIALOG_H__
+
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Check_Button.H>
+#include <FL/Fl_Round_Button.H>
+#include <FL/Fl_Int_Input.H>
+
+class OptionsDialog : public Fl_Window {
+protected:
+ OptionsDialog();
+ ~OptionsDialog();
+
+public:
+ static void showDialog(void);
+
+ void show(void);
+
+protected:
+ void loadOptions(void);
+ void storeOptions(void);
+
+ void createCompressionPage(int tx, int ty, int tw, int th);
+ void createSecurityPage(int tx, int ty, int tw, int th);
+ void createInputPage(int tx, int ty, int tw, int th);
+ void createMiscPage(int tx, int ty, int tw, int th);
+
+ static void handleAutoselect(Fl_Widget *widget, void *data);
+ static void handleCompression(Fl_Widget *widget, void *data);
+ static void handleJpeg(Fl_Widget *widget, void *data);
+
+ static void handleVencrypt(Fl_Widget *widget, void *data);
+ static void handleX509(Fl_Widget *widget, void *data);
+
+ static void handleCancel(Fl_Widget *widget, void *data);
+ static void handleOK(Fl_Widget *widget, void *data);
+
+protected:
+ /* Compression */
+ Fl_Check_Button *autoselectCheckbox;
+
+ Fl_Group *encodingGroup;
+ Fl_Round_Button *tightButton;
+ Fl_Round_Button *zrleButton;
+ Fl_Round_Button *hextileButton;
+ Fl_Round_Button *rawButton;
+
+ Fl_Group *colorlevelGroup;
+ Fl_Round_Button *fullcolorCheckbox;
+ Fl_Round_Button *mediumcolorCheckbox;
+ Fl_Round_Button *lowcolorCheckbox;
+ Fl_Round_Button *verylowcolorCheckbox;
+
+ Fl_Check_Button *compressionCheckbox;
+ Fl_Check_Button *jpegCheckbox;
+ Fl_Int_Input *compressionInput;
+ Fl_Int_Input *jpegInput;
+
+ /* Security */
+ Fl_Check_Button *vencryptCheckbox;
+
+ Fl_Group *encryptionGroup;
+ Fl_Check_Button *encNoneCheckbox;
+ Fl_Check_Button *encTLSCheckbox;
+ Fl_Check_Button *encX509Checkbox;
+ Fl_Input *caInput;
+ Fl_Input *crlInput;
+
+ Fl_Group *authenticationGroup;
+ Fl_Check_Button *authNoneCheckbox;
+ Fl_Check_Button *authVncCheckbox;
+ Fl_Check_Button *authPlainCheckbox;
+
+ /* Input */
+ Fl_Check_Button *viewOnlyCheckbox;
+ Fl_Check_Button *acceptClipboardCheckbox;
+ Fl_Check_Button *sendClipboardCheckbox;
+ Fl_Check_Button *sendPrimaryCheckbox;
+
+ /* Misc. */
+ Fl_Check_Button *sharedCheckbox;
+ Fl_Check_Button *fullScreenCheckbox;
+ Fl_Check_Button *localCursorCheckbox;
+ Fl_Check_Button *dotCursorCheckbox;
+};
+
+#endif
diff --git a/vncviewer/ServerDialog.cxx b/vncviewer/ServerDialog.cxx
index fab1448c..e65cbadb 100644
--- a/vncviewer/ServerDialog.cxx
+++ b/vncviewer/ServerDialog.cxx
@@ -23,6 +23,8 @@
#include <FL/fl_draw.H>
#include "ServerDialog.h"
+#include "OptionsDialog.h"
+#include "fltk_layout.h"
#include "i18n.h"
extern void about_vncviewer();
@@ -33,8 +35,7 @@ ServerDialog::ServerDialog()
int width;
Fl_Button *button;
- fl_font(FL_HELVETICA, FL_NORMAL_SIZE);
- width = fl_width(_("VNC server:"));
+ width = gui_str_len(_("VNC server:"));
serverName = new Fl_Input(20 + width, 20, w() - 20*2 - width, 25, _("VNC server:"));
width = (w() - 20) / 4;
@@ -42,6 +43,9 @@ ServerDialog::ServerDialog()
button = new Fl_Button(20 + width*0, 20+25+20, width - 20, 27, _("About..."));
button->callback(this->handleAbout, this);
+ button = new Fl_Button(20 + width*1, 20+25+20, width - 20, 27, _("Options..."));
+ button->callback(this->handleOptions, this);
+
button = new Fl_Button(20 + width*2, 20+25+20, width - 20, 27, _("Cancel"));
button->callback(this->handleCancel, this);
@@ -83,6 +87,12 @@ void ServerDialog::handleAbout(Fl_Widget *widget, void *data)
}
+void ServerDialog::handleOptions(Fl_Widget *widget, void *data)
+{
+ OptionsDialog::showDialog();
+}
+
+
void ServerDialog::handleCancel(Fl_Widget *widget, void *data)
{
ServerDialog *dialog = (ServerDialog*)data;
diff --git a/vncviewer/ServerDialog.h b/vncviewer/ServerDialog.h
index 0d5f6d8c..052eb62f 100644
--- a/vncviewer/ServerDialog.h
+++ b/vncviewer/ServerDialog.h
@@ -32,6 +32,7 @@ public:
protected:
static void handleAbout(Fl_Widget *widget, void *data);
+ static void handleOptions(Fl_Widget *widget, void *data);
static void handleCancel(Fl_Widget *widget, void *data);
static void handleOK(Fl_Widget *widget, void *data);
diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx
index 6a6e983f..74f9340f 100644
--- a/vncviewer/Viewport.cxx
+++ b/vncviewer/Viewport.cxx
@@ -35,6 +35,7 @@
#include "Viewport.h"
#include "CConn.h"
+#include "OptionsDialog.h"
#include "i18n.h"
#include "parameters.h"
#include "keysym2ucs.h"
@@ -53,7 +54,7 @@ static rfb::LogWriter vlog("Viewport");
// Menu constants
enum { ID_EXIT, ID_CTRL, ID_ALT, ID_MENUKEY, ID_CTRLALTDEL,
- ID_REFRESH, ID_ABOUT, ID_DISMISS };
+ ID_REFRESH, ID_OPTIONS, ID_ABOUT, ID_DISMISS };
Viewport::Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_)
: Fl_Widget(0, 0, w, h), cc(cc_), frameBuffer(NULL), pixelTrans(NULL),
@@ -450,6 +451,7 @@ void Viewport::initContextMenu()
contextMenu->add(_("Refresh screen"), 0, NULL, (void*)ID_REFRESH, FL_MENU_DIVIDER);
+ contextMenu->add(_("Options..."), 0, NULL, (void*)ID_OPTIONS, 0);
contextMenu->add(_("About TigerVNC viewer..."), 0, NULL, (void*)ID_ABOUT, FL_MENU_DIVIDER);
contextMenu->add(_("Dismiss menu"), 0, NULL, (void*)ID_DISMISS, 0);
@@ -498,6 +500,9 @@ void Viewport::popupContextMenu()
case ID_REFRESH:
cc->refreshFramebuffer();
break;
+ case ID_OPTIONS:
+ OptionsDialog::showDialog();
+ break;
case ID_ABOUT:
about_vncviewer();
break;
diff --git a/vncviewer/fltk_layout.h b/vncviewer/fltk_layout.h
new file mode 100644
index 00000000..5119188c
--- /dev/null
+++ b/vncviewer/fltk_layout.h
@@ -0,0 +1,86 @@
+/* Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+#ifndef __FLTK_LAYOUT_H__
+#define __FLTK_LAYOUT_H__
+
+#include <FL/fl_draw.H>
+
+/* Calculates the width of a string as printed by FLTK (pixels) */
+static inline int gui_str_len(const char *str)
+{
+ float len;
+
+ fl_font(FL_HELVETICA, FL_NORMAL_SIZE);
+
+ len = fl_width(str);
+
+ return (int)(len + 0.5f);
+}
+
+/**** MARGINS ****/
+
+#define OUTER_MARGIN 10
+#define INNER_MARGIN 10
+
+/* Tighter grouping of related fields */
+#define TIGHT_MARGIN 5
+
+/**** ADJUSTMENTS ****/
+#define INDENT 20
+
+/**** FLTK WIDGETS ****/
+
+/* Fl_Tabs */
+#define TABS_HEIGHT 30
+
+/* Fl_Input */
+#define INPUT_LABEL_OFFSET FL_NORMAL_SIZE
+#define INPUT_HEIGHT 25
+
+/* Fl_Button */
+#define BUTTON_WIDTH 115
+#define BUTTON_HEIGHT 27
+
+/* Fl_Round_Button */
+#define RADIO_MIN_WIDTH (FL_NORMAL_SIZE + 5)
+#define RADIO_HEIGHT (FL_NORMAL_SIZE + 7)
+
+/* Fl_Check_Button */
+#define CHECK_MIN_WIDTH RADIO_MIN_WIDTH
+#define CHECK_HEIGHT RADIO_HEIGHT
+
+/* Fl_Group */
+#define GROUP_LABEL_OFFSET FL_NORMAL_SIZE
+#define GROUP_MARGIN 12
+
+/**** HELPERS FOR DYNAMIC TEXT ****/
+
+/* Extra space to add after any text line */
+#define TEXT_PADDING 2
+
+/* Use this when the text extends to the right (e.g. checkboxes) */
+#define LBLRIGHT(x, y, w, h, str) \
+ (x), (y), (w) + gui_str_len(str) + TEXT_PADDING, (h), (str)
+
+/* Use this when the space for the label is taken from the left (e.g. input) */
+#define LBLLEFT(x, y, w, h, str) \
+ (x) + (gui_str_len(str) + TEXT_PADDING), (y), \
+ (w) - (gui_str_len(str) + TEXT_PADDING), (h), (str)
+
+#endif