blob: 0b2de53e1bc20882697c6d9798f4d91cf23e9cb3 [file] [log] [blame]
Pierre Ossman5156d5e2011-03-09 09:42:34 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
2 * Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
DRCb65bb932011-06-24 03:17:00 +00003 * Copyright (C) 2011 D. R. Commander. All Rights Reserved.
Pierre Ossman5156d5e2011-03-09 09:42:34 +00004 *
5 * This is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This software is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this software; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18 * USA.
19 */
20
Peter Åstrandc359f362011-08-23 12:04:46 +000021#ifdef HAVE_CONFIG_H
22#include <config.h>
23#endif
24
Pierre Ossman5156d5e2011-03-09 09:42:34 +000025#include <string.h>
26#include <stdio.h>
Pierre Ossman2a7a8d62013-02-15 08:33:39 +000027#include <ctype.h>
Pierre Ossman5156d5e2011-03-09 09:42:34 +000028#include <stdlib.h>
29#include <errno.h>
30#include <signal.h>
31#include <locale.h>
Pierre Ossman5bf17ad2015-02-17 13:23:00 +010032#include <fcntl.h>
Pierre Ossman5156d5e2011-03-09 09:42:34 +000033#include <sys/stat.h>
34
35#ifdef WIN32
Peter Åstrand (astrand)11167e12015-02-05 11:10:32 +010036#include <os/winerrno.h>
Pierre Ossman5156d5e2011-03-09 09:42:34 +000037#include <direct.h>
38#define mkdir(path, mode) _mkdir(path)
39#endif
40
Pierre Ossman6b9622d2014-07-21 16:42:12 +020041#if !defined(WIN32) && !defined(__APPLE__)
42#include <X11/Xlib.h>
43#include <X11/XKBlib.h>
44#endif
45
Pierre Ossman5156d5e2011-03-09 09:42:34 +000046#include <rfb/Logger_stdio.h>
47#include <rfb/SecurityClient.h>
48#include <rfb/Security.h>
49#ifdef HAVE_GNUTLS
50#include <rfb/CSecurityTLS.h>
51#endif
52#include <rfb/LogWriter.h>
53#include <rfb/Timer.h>
Peter Åstrand8a2b0812012-08-08 11:49:01 +000054#include <rfb/Exception.h>
Pierre Ossman5156d5e2011-03-09 09:42:34 +000055#include <network/TcpSocket.h>
DRC4426f002011-10-12 20:02:55 +000056#include <os/os.h>
Pierre Ossman5156d5e2011-03-09 09:42:34 +000057
58#include <FL/Fl.H>
59#include <FL/Fl_Widget.H>
Pierre Ossman8eb35082012-03-27 12:50:54 +000060#include <FL/Fl_PNG_Image.H>
Pierre Ossman5156d5e2011-03-09 09:42:34 +000061#include <FL/fl_ask.H>
Pierre Ossmanb8858222011-04-29 11:51:38 +000062#include <FL/x.H>
Pierre Ossman5156d5e2011-03-09 09:42:34 +000063
64#include "i18n.h"
65#include "parameters.h"
66#include "CConn.h"
Pierre Ossman561ff0c2011-05-13 14:04:59 +000067#include "ServerDialog.h"
Pierre Ossman5156d5e2011-03-09 09:42:34 +000068#include "UserDialog.h"
Adam Tkac8ac4b302013-01-23 13:55:46 +000069#include "vncviewer.h"
Pierre Ossman5156d5e2011-03-09 09:42:34 +000070
DRCb65bb932011-06-24 03:17:00 +000071#ifdef WIN32
Pierre Ossman8eb35082012-03-27 12:50:54 +000072#include "resource.h"
DRCb65bb932011-06-24 03:17:00 +000073#include "win32.h"
74#endif
75
Pierre Ossman5156d5e2011-03-09 09:42:34 +000076rfb::LogWriter vlog("main");
77
78using namespace network;
79using namespace rfb;
80using namespace std;
81
Pierre Ossmandc96cb42014-09-22 12:19:26 +020082static char aboutText[1024];
83
Adam Tkac8ac4b302013-01-23 13:55:46 +000084char vncServerName[VNCSERVERNAMELEN] = { '\0' };
85
Pierre Ossman5156d5e2011-03-09 09:42:34 +000086static bool exitMainloop = false;
Pierre Ossmane2ef5c12011-07-12 16:56:34 +000087static const char *exitError = NULL;
Pierre Ossman5156d5e2011-03-09 09:42:34 +000088
Pierre Ossmane2ef5c12011-07-12 16:56:34 +000089void exit_vncviewer(const char *error)
Pierre Ossman5156d5e2011-03-09 09:42:34 +000090{
Pierre Ossmane2ef5c12011-07-12 16:56:34 +000091 // Prioritise the first error we get as that is probably the most
92 // relevant one.
93 if ((error != NULL) && (exitError == NULL))
94 exitError = strdup(error);
95
Pierre Ossman5156d5e2011-03-09 09:42:34 +000096 exitMainloop = true;
97}
98
Pierre Ossmanb8858222011-04-29 11:51:38 +000099void about_vncviewer()
100{
101 fl_message_title(_("About TigerVNC Viewer"));
Pierre Ossmandc96cb42014-09-22 12:19:26 +0200102 fl_message("%s", aboutText);
Pierre Ossmanb8858222011-04-29 11:51:38 +0000103}
104
105static void about_callback(Fl_Widget *widget, void *data)
106{
107 about_vncviewer();
108}
109
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000110static void CleanupSignalHandler(int sig)
111{
112 // CleanupSignalHandler allows C++ object cleanup to happen because it calls
113 // exit() rather than the default which is to abort.
Pierre Ossmanc76bd2b2014-12-03 14:01:31 +0100114 vlog.info(_("Termination signal %d has been received. TigerVNC Viewer will now exit."), sig);
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000115 exit(1);
116}
117
118static void init_fltk()
119{
120 // Basic text size (10pt @ 96 dpi => 13px)
121 FL_NORMAL_SIZE = 13;
122
123#ifndef __APPLE__
124 // Select a FLTK scheme and background color that looks somewhat
125 // close to modern Linux and Windows.
126 Fl::scheme("gtk+");
127 Fl::background(220, 220, 220);
128#else
129 // On Mac OS X there is another scheme that fits better though.
130 Fl::scheme("plastic");
131#endif
132
Henrik Andersson3b837032011-09-19 13:46:55 +0000133 // Proper Gnome Shell integration requires that we set a sensible
134 // WM_CLASS for the window.
135 Fl_Window::default_xclass("vncviewer");
136
Pierre Ossman8eb35082012-03-27 12:50:54 +0000137 // Set the default icon for all windows.
138#ifdef HAVE_FLTK_ICONS
139#ifdef WIN32
140 HICON lg, sm;
141
142 lg = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON),
143 IMAGE_ICON, GetSystemMetrics(SM_CXICON),
144 GetSystemMetrics(SM_CYICON),
145 LR_DEFAULTCOLOR | LR_SHARED);
146 sm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON),
147 IMAGE_ICON, GetSystemMetrics(SM_CXSMICON),
148 GetSystemMetrics(SM_CYSMICON),
149 LR_DEFAULTCOLOR | LR_SHARED);
150
151 Fl_Window::default_icons(lg, sm);
152#elif ! defined(__APPLE__)
153 const int icon_sizes[] = {48, 32, 24, 16};
154
155 Fl_PNG_Image *icons[4];
156 int count;
157
158 count = 0;
159
160 // FIXME: Follow icon theme specification
161 for (size_t i = 0;i < sizeof(icon_sizes)/sizeof(icon_sizes[0]);i++) {
162 char icon_path[PATH_MAX];
163 bool exists;
164
Pierre Ossman6a007bd2012-09-11 10:56:21 +0000165 sprintf(icon_path, "%s/icons/hicolor/%dx%d/apps/tigervnc.png",
Pierre Ossman8eb35082012-03-27 12:50:54 +0000166 DATA_DIR, icon_sizes[i], icon_sizes[i]);
167
168#ifndef WIN32
169 struct stat st;
170 if (stat(icon_path, &st) != 0)
171#else
172 struct _stat st;
173 if (_stat(icon_path, &st) != 0)
174 return(false);
175#endif
176 exists = false;
177 else
178 exists = true;
179
180 if (exists) {
181 icons[count] = new Fl_PNG_Image(icon_path);
182 if (icons[count]->w() == 0 ||
183 icons[count]->h() == 0 ||
184 icons[count]->d() != 4) {
185 delete icons[count];
186 continue;
187 }
188
189 count++;
190 }
191 }
192
193 Fl_Window::default_icons((const Fl_RGB_Image**)icons, count);
194
195 for (int i = 0;i < count;i++)
196 delete icons[i];
197#endif
198#endif // FLTK_HAVE_ICONS
199
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000200 // This makes the "icon" in dialogs rounded, which fits better
201 // with the above schemes.
202 fl_message_icon()->box(FL_UP_BOX);
203
204 // Turn off the annoying behaviour where popups track the mouse.
205 fl_message_hotspot(false);
206
207 // Avoid empty titles for popups
208 fl_message_title_default(_("TigerVNC Viewer"));
209
210#ifdef WIN32
211 // Most "normal" Windows apps use this font for UI elements.
212 Fl::set_font(FL_HELVETICA, "Tahoma");
213#endif
214
215 // FLTK exposes these so that we can translate them.
216 fl_no = _("No");
217 fl_yes = _("Yes");
218 fl_ok = _("OK");
219 fl_cancel = _("Cancel");
220 fl_close = _("Close");
Pierre Ossmanb8858222011-04-29 11:51:38 +0000221
222#ifdef __APPLE__
Peter Åstrandb7c55242011-08-29 13:14:51 +0000223 /* Needs trailing space */
224 static char fltk_about[16];
225 snprintf(fltk_about, sizeof(fltk_about), "%s ", _("About"));
226 Fl_Mac_App_Menu::about = fltk_about;
227 static char fltk_hide[16];
228 snprintf(fltk_hide, sizeof(fltk_hide), "%s ", _("Hide"));
229 Fl_Mac_App_Menu::hide = fltk_hide;
230 static char fltk_quit[16];
231 snprintf(fltk_quit, sizeof(fltk_quit), "%s ", _("Quit"));
232 Fl_Mac_App_Menu::quit = fltk_quit;
233
Pierre Ossman41ba6032011-06-16 11:09:31 +0000234 Fl_Mac_App_Menu::print = ""; // Don't want the print item
235 Fl_Mac_App_Menu::services = _("Services");
Pierre Ossman41ba6032011-06-16 11:09:31 +0000236 Fl_Mac_App_Menu::hide_others = _("Hide Others");
237 Fl_Mac_App_Menu::show = _("Show All");
Pierre Ossman41ba6032011-06-16 11:09:31 +0000238
Pierre Ossmanb8858222011-04-29 11:51:38 +0000239 fl_mac_set_about(about_callback, NULL);
240#endif
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000241}
242
243static void mkvnchomedir()
244{
245 // Create .vnc in the user's home directory if it doesn't already exist
246 char* homeDir = NULL;
247
248 if (getvnchomedir(&homeDir) == -1) {
249 vlog.error(_("Could not create VNC home directory: can't obtain home "
250 "directory path."));
251 } else {
252 int result = mkdir(homeDir, 0755);
253 if (result == -1 && errno != EEXIST)
254 vlog.error(_("Could not create VNC home directory: %s."), strerror(errno));
255 delete [] homeDir;
256 }
257}
258
259static void usage(const char *programName)
260{
Pierre Ossman5bf17ad2015-02-17 13:23:00 +0100261#ifdef WIN32
262 // If we don't have a console then we need to create one for output
263 if (GetConsoleWindow() == NULL) {
264 HANDLE handle;
265 int fd;
266
267 AllocConsole();
268
269 handle = GetStdHandle(STD_ERROR_HANDLE);
270 fd = _open_osfhandle((intptr_t)handle, O_TEXT);
271 *stderr = *fdopen(fd, "w");
272 }
273#endif
274
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000275 fprintf(stderr,
276 "\nusage: %s [parameters] [host:displayNum] [parameters]\n"
277 " %s [parameters] -listen [port] [parameters]\n",
278 programName, programName);
279 fprintf(stderr,"\n"
280 "Parameters can be turned on with -<param> or off with -<param>=0\n"
281 "Parameters which take a value can be specified as "
282 "-<param> <value>\n"
283 "Other valid forms are <param>=<value> -<param>=<value> "
284 "--<param>=<value>\n"
285 "Parameter names are case-insensitive. The parameters are:\n\n");
286 Configuration::listParams(79, 14);
Pierre Ossman5bf17ad2015-02-17 13:23:00 +0100287
288#ifdef WIN32
289 // Just wait for the user to kill the console window
290 Sleep(INFINITE);
291#endif
292
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000293 exit(1);
294}
295
Adam Tkac8ac4b302013-01-23 13:55:46 +0000296#ifndef WIN32
297static int
298interpretViaParam(char *remoteHost, int *remotePort, int localPort)
299{
300 const int SERVER_PORT_OFFSET = 5900;
301 char *pos = strchr(vncServerName, ':');
302 if (pos == NULL)
303 *remotePort = SERVER_PORT_OFFSET;
304 else {
305 int portOffset = SERVER_PORT_OFFSET;
306 size_t len;
307 *pos++ = '\0';
308 len = strlen(pos);
309 if (*pos == ':') {
310 /* Two colons is an absolute port number, not an offset. */
311 pos++;
312 len--;
313 portOffset = 0;
314 }
315 if (!len || strspn (pos, "-0123456789") != len )
316 return 1;
317 *remotePort = atoi(pos) + portOffset;
318 }
319
320 if (*vncServerName != '\0')
321 strncpy(remoteHost, vncServerName, VNCSERVERNAMELEN);
322 else
323 strncpy(remoteHost, "localhost", VNCSERVERNAMELEN);
324
325 remoteHost[VNCSERVERNAMELEN - 1] = '\0';
326
327 snprintf(vncServerName, VNCSERVERNAMELEN, "localhost::%d", localPort);
328 vncServerName[VNCSERVERNAMELEN - 1] = '\0';
Adam Tkac8ac4b302013-01-23 13:55:46 +0000329
330 return 0;
331}
332
333static void
334createTunnel(const char *gatewayHost, const char *remoteHost,
335 int remotePort, int localPort)
336{
Pierre Ossmanf8d525b2014-07-09 17:02:27 +0200337 const char *cmd = getenv("VNC_VIA_CMD");
338 char *cmd2, *percent;
Adam Tkac8ac4b302013-01-23 13:55:46 +0000339 char lport[10], rport[10];
340 sprintf(lport, "%d", localPort);
341 sprintf(rport, "%d", remotePort);
342 setenv("G", gatewayHost, 1);
343 setenv("H", remoteHost, 1);
344 setenv("R", rport, 1);
345 setenv("L", lport, 1);
Adam Tkac8ac4b302013-01-23 13:55:46 +0000346 if (!cmd)
347 cmd = "/usr/bin/ssh -f -L \"$L\":\"$H\":\"$R\" \"$G\" sleep 20";
348 /* Compatibility with TigerVNC's method. */
Pierre Ossmanf8d525b2014-07-09 17:02:27 +0200349 cmd2 = strdup(cmd);
350 while ((percent = strchr(cmd2, '%')) != NULL)
Adam Tkac8ac4b302013-01-23 13:55:46 +0000351 *percent = '$';
Pierre Ossmanf8d525b2014-07-09 17:02:27 +0200352 system(cmd2);
353 free(cmd2);
Adam Tkac8ac4b302013-01-23 13:55:46 +0000354}
355
356static int mktunnel()
357{
358 const char *gatewayHost;
359 char remoteHost[VNCSERVERNAMELEN];
360 int localPort = findFreeTcpPort();
361 int remotePort;
362
363 gatewayHost = strDup(via.getValueStr());
364 if (interpretViaParam(remoteHost, &remotePort, localPort) != 0)
365 return 1;
366 createTunnel(gatewayHost, remoteHost, remotePort, localPort);
367
368 return 0;
369}
370#endif /* !WIN32 */
371
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000372int main(int argc, char** argv)
373{
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000374 UserDialog dlg;
375
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000376 setlocale(LC_ALL, "");
Pierre Ossman0878eca2012-03-27 13:03:22 +0000377 bindtextdomain(PACKAGE_NAME, LOCALE_DIR);
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000378 textdomain(PACKAGE_NAME);
379
Pierre Ossmandc96cb42014-09-22 12:19:26 +0200380 // Generate the about string now that we get the proper translation
Pierre Ossman63471c92015-03-03 16:49:50 +0100381 snprintf(aboutText, sizeof(aboutText),
382 _("TigerVNC Viewer %d-bit v%s\n"
383 "Built on: %s\n"
384 "Copyright (C) 1999-%d TigerVNC Team and many others (see README.txt)\n"
385 "See http://www.tigervnc.org for information on TigerVNC."),
Pierre Ossman5945d732014-09-22 13:13:15 +0200386 (int)sizeof(size_t)*8, PACKAGE_VERSION,
Pierre Ossmanc1341682015-02-20 17:12:57 +0100387 BUILD_TIMESTAMP, 2015);
Pierre Ossmandc96cb42014-09-22 12:19:26 +0200388
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000389 rfb::SecurityClient::setDefaults();
390
391 // Write about text to console, still using normal locale codeset
Pierre Ossmandc96cb42014-09-22 12:19:26 +0200392 fprintf(stderr,"\n%s\n", aboutText);
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000393
394 // Set gettext codeset to what our GUI toolkit uses. Since we are
395 // passing strings from strerror/gai_strerror to the GUI, these must
396 // be in GUI codeset as well.
397 bind_textdomain_codeset(PACKAGE_NAME, "UTF-8");
398 bind_textdomain_codeset("libc", "UTF-8");
399
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000400 rfb::initStdIOLoggers();
Pierre Ossmanc8719ad2012-04-26 14:27:52 +0000401#ifdef WIN32
402 rfb::initFileLogger("C:\\temp\\vncviewer.log");
403#else
404 rfb::initFileLogger("/tmp/vncviewer.log");
405#endif
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000406 rfb::LogWriter::setLogParams("*:stderr:30");
407
408#ifdef SIGHUP
409 signal(SIGHUP, CleanupSignalHandler);
410#endif
411 signal(SIGINT, CleanupSignalHandler);
412 signal(SIGTERM, CleanupSignalHandler);
413
414 init_fltk();
415
Pierre Ossman6b9622d2014-07-21 16:42:12 +0200416#if !defined(WIN32) && !defined(__APPLE__)
417 fl_open_display();
418 XkbSetDetectableAutoRepeat(fl_display, True, NULL);
419#endif
420
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000421 Configuration::enableViewerParams();
422
Peter Åstrand8a2b0812012-08-08 11:49:01 +0000423 /* Load the default parameter settings */
424 const char* defaultServerName;
425 try {
426 defaultServerName = loadViewerParameters(NULL);
427 } catch (rfb::Exception& e) {
428 fl_alert("%s", e.str());
429 }
430
DRC5aa06502011-06-23 22:04:46 +0000431 int i = 1;
432 if (!Fl::args(argc, argv, i) || i < argc)
433 for (; i < argc; i++) {
434 if (Configuration::setParam(argv[i]))
435 continue;
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000436
DRC5aa06502011-06-23 22:04:46 +0000437 if (argv[i][0] == '-') {
438 if (i+1 < argc) {
439 if (Configuration::setParam(&argv[i][1], argv[i+1])) {
440 i++;
441 continue;
442 }
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000443 }
DRC5aa06502011-06-23 22:04:46 +0000444 usage(argv[0]);
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000445 }
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000446
Adam Tkac8ac4b302013-01-23 13:55:46 +0000447 strncpy(vncServerName, argv[i], VNCSERVERNAMELEN);
448 vncServerName[VNCSERVERNAMELEN - 1] = '\0';
DRC5aa06502011-06-23 22:04:46 +0000449 }
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000450
451 if (!::autoSelect.hasBeenSet()) {
452 // Default to AutoSelect=0 if -PreferredEncoding or -FullColor is used
Peter Åstrand8a2b0812012-08-08 11:49:01 +0000453 if (::preferredEncoding.hasBeenSet() || ::fullColour.hasBeenSet() ||
454 ::fullColourAlias.hasBeenSet()) {
455 ::autoSelect.setParam(false);
456 }
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000457 }
458 if (!::fullColour.hasBeenSet() && !::fullColourAlias.hasBeenSet()) {
459 // Default to FullColor=0 if AutoSelect=0 && LowColorLevel is set
460 if (!::autoSelect && (::lowColourLevel.hasBeenSet() ||
461 ::lowColourLevelAlias.hasBeenSet())) {
462 ::fullColour.setParam(false);
463 }
464 }
465 if (!::customCompressLevel.hasBeenSet()) {
466 // Default to CustomCompressLevel=1 if CompressLevel is used.
Peter Åstrand8a2b0812012-08-08 11:49:01 +0000467 if(::compressLevel.hasBeenSet()) {
468 ::customCompressLevel.setParam(true);
469 }
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000470 }
471
472 mkvnchomedir();
473
474 CSecurity::upg = &dlg;
475#ifdef HAVE_GNUTLS
476 CSecurityTLS::msg = &dlg;
477#endif
478
Pierre Ossman2a7a8d62013-02-15 08:33:39 +0000479 Socket *sock = NULL;
480
DRC3e7ed812013-02-26 10:34:22 +0000481#ifndef WIN32
Adam Tkac571089b2013-02-19 14:30:32 +0000482 /* Specifying -via and -listen together is nonsense */
483 if (listenMode && strlen(via.getValueStr()) > 0) {
Pierre Ossman744e55c2014-12-03 14:00:54 +0100484 // TRANSLATORS: "Parameters" are command line arguments, or settings
485 // from a file or the Windows registry.
Pierre Ossman8ca4c1d2014-09-22 12:54:26 +0200486 vlog.error(_("Parameters -listen and -via are incompatible"));
487 fl_alert(_("Parameters -listen and -via are incompatible"));
Adam Tkac571089b2013-02-19 14:30:32 +0000488 exit_vncviewer();
489 return 1;
490 }
DRC3e7ed812013-02-26 10:34:22 +0000491#endif
Adam Tkac571089b2013-02-19 14:30:32 +0000492
493 if (listenMode) {
Pierre Ossman2a7a8d62013-02-15 08:33:39 +0000494 try {
495 int port = 5500;
496 if (isdigit(vncServerName[0]))
497 port = atoi(vncServerName);
498
499 TcpListener listener(NULL, port);
500
Pierre Ossman8ca4c1d2014-09-22 12:54:26 +0200501 vlog.info(_("Listening on port %d\n"), port);
Pierre Ossman2a7a8d62013-02-15 08:33:39 +0000502 sock = listener.accept();
503 } catch (rdr::Exception& e) {
504 vlog.error("%s", e.str());
505 fl_alert("%s", e.str());
506 exit_vncviewer();
507 return 1;
508 }
509
510 } else {
511 if (vncServerName[0] == '\0') {
512 ServerDialog::run(defaultServerName, vncServerName);
513 if (vncServerName[0] == '\0')
514 return 1;
515 }
Pierre Ossman561ff0c2011-05-13 14:04:59 +0000516
Adam Tkac8ac4b302013-01-23 13:55:46 +0000517#ifndef WIN32
Pierre Ossman2a7a8d62013-02-15 08:33:39 +0000518 if (strlen (via.getValueStr()) > 0 && mktunnel() != 0)
519 usage(argv[0]);
Adam Tkac8ac4b302013-01-23 13:55:46 +0000520#endif
Pierre Ossman2a7a8d62013-02-15 08:33:39 +0000521 }
Adam Tkac8ac4b302013-01-23 13:55:46 +0000522
Pierre Ossman2a7a8d62013-02-15 08:33:39 +0000523 CConn *cc = new CConn(vncServerName, sock);
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000524
525 while (!exitMainloop) {
526 int next_timer;
527
528 next_timer = Timer::checkTimeouts();
529 if (next_timer == 0)
530 next_timer = INT_MAX;
531
532 if (Fl::wait((double)next_timer / 1000.0) < 0.0) {
533 vlog.error(_("Internal FLTK error. Exiting."));
534 break;
535 }
536 }
537
Pierre Ossmane2ef5c12011-07-12 16:56:34 +0000538 delete cc;
539
540 if (exitError != NULL)
Pierre Ossmanf52740e2012-04-25 15:43:56 +0000541 fl_alert("%s", exitError);
Pierre Ossmane2ef5c12011-07-12 16:56:34 +0000542
Pierre Ossman5156d5e2011-03-09 09:42:34 +0000543 return 0;
544}