Browse Source

Retry connection in case of an error

tags/v1.11.90
Johannes 3 years ago
parent
commit
44b085adee

+ 6
- 6
vncviewer/CConn.cxx View File

@@ -111,8 +111,8 @@ CConn::CConn(const char* vncServerName, network::Socket* socket=NULL)
}
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(_("Failed to connect to \"%s\":\n\n%s"),
vncServerName, e.str());
abort_connection(_("Failed to connect to \"%s\":\n\n%s"),
vncServerName, e.str());
return;
}
}
@@ -259,7 +259,7 @@ void CConn::socketEvent(FL_SOCKET fd, void *data)
Timer::checkTimeouts();

// Also check if we need to stop reading and terminate
if (should_exit())
if (should_disconnect())
break;
}

@@ -270,14 +270,14 @@ void CConn::socketEvent(FL_SOCKET fd, void *data)
if (!cc->desktop) {
vlog.error(_("The connection was dropped by the server before "
"the session could be established."));
exit_vncviewer(_("The connection was dropped by the server "
abort_connection(_("The connection was dropped by the server "
"before the session could be established."));
} else {
exit_vncviewer();
disconnect();
}
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(_("An unexpected error occurred when communicating "
abort_connection(_("An unexpected error occurred when communicating "
"with the server:\n\n%s"), e.str());
}


+ 1
- 1
vncviewer/DesktopWindow.cxx View File

@@ -1393,7 +1393,7 @@ void DesktopWindow::repositionWidgets()

void DesktopWindow::handleClose(Fl_Widget *wnd, void *data)
{
exit_vncviewer();
disconnect();
}



+ 29
- 21
vncviewer/Viewport.cxx View File

@@ -103,7 +103,7 @@ static rfb::LogWriter vlog("Viewport");

// Menu constants

enum { ID_EXIT, ID_FULLSCREEN, ID_MINIMIZE, ID_RESIZE,
enum { ID_DISCONNECT, ID_FULLSCREEN, ID_MINIMIZE, ID_RESIZE,
ID_CTRL, ID_ALT, ID_MENUKEY, ID_CTRLALTDEL,
ID_REFRESH, ID_OPTIONS, ID_INFO, ID_ABOUT };

@@ -572,8 +572,9 @@ int Viewport::handle(int event)
cc->sendClipboardData(filtered);
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(_("An unexpected error occurred when communicating "
"with the server:\n\n%s"), e.str());
abort_connection(_("An unexpected error occurred when "
"communicating with the server:\n\n%s"),
e.str());
}

strFree(filtered);
@@ -669,8 +670,9 @@ void Viewport::sendPointerEvent(const rfb::Point& pos, int buttonMask)
cc->writer()->writePointerEvent(pos, buttonMask);
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(_("An unexpected error occurred when communicating "
"with the server:\n\n%s"), e.str());
abort_connection(_("An unexpected error occurred when "
"communicating with the server:\n\n%s"),
e.str());
}
} else {
if (!Fl::has_timeout(handlePointerTimeout, this))
@@ -771,8 +773,9 @@ void Viewport::handleClipboardChange(int source, void *data)
self->cc->announceClipboard(true);
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(_("An unexpected error occurred when communicating "
"with the server:\n\n%s"), e.str());
abort_connection(_("An unexpected error occurred when "
"communicating with the server:\n\n%s"),
e.str());
}
}

@@ -785,8 +788,9 @@ void Viewport::flushPendingClipboard()
cc->requestClipboard();
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(_("An unexpected error occurred when communicating "
"with the server:\n\n%s"), e.str());
abort_connection(_("An unexpected error occurred when "
"communicating with the server:\n\n%s"),
e.str());
}
}
if (pendingClientClipboard) {
@@ -795,8 +799,9 @@ void Viewport::flushPendingClipboard()
cc->announceClipboard(true);
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(_("An unexpected error occurred when communicating "
"with the server:\n\n%s"), e.str());
abort_connection(_("An unexpected error occurred when "
"communicating with the server:\n\n%s"),
e.str());
}
}

@@ -822,8 +827,9 @@ void Viewport::handlePointerTimeout(void *data)
self->lastButtonMask);
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(_("An unexpected error occurred when communicating "
"with the server:\n\n%s"), e.str());
abort_connection(_("An unexpected error occurred when "
"communicating with the server:\n\n%s"),
e.str());
}
}

@@ -892,8 +898,9 @@ void Viewport::handleKeyPress(int keyCode, rdr::U32 keySym)
cc->writer()->writeKeyEvent(keySym, keyCode, true);
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(_("An unexpected error occurred when communicating "
"with the server:\n\n%s"), e.str());
abort_connection(_("An unexpected error occurred when "
"communicating with the server:\n\n%s"),
e.str());
}
}

@@ -927,8 +934,9 @@ void Viewport::handleKeyRelease(int keyCode)
cc->writer()->writeKeyEvent(iter->second, keyCode, false);
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(_("An unexpected error occurred when communicating "
"with the server:\n\n%s"), e.str());
abort_connection(_("An unexpected error occurred when "
"communicating with the server:\n\n%s"),
e.str());
}

downKeySym.erase(iter);
@@ -1239,8 +1247,8 @@ void Viewport::initContextMenu()
{
contextMenu->clear();

fltk_menu_add(contextMenu, p_("ContextMenu|", "E&xit viewer"),
0, NULL, (void*)ID_EXIT, FL_MENU_DIVIDER);
fltk_menu_add(contextMenu, p_("ContextMenu|", "Dis&connect"),
0, NULL, (void*)ID_DISCONNECT, FL_MENU_DIVIDER);

fltk_menu_add(contextMenu, p_("ContextMenu|", "&Full screen"),
0, NULL, (void*)ID_FULLSCREEN,
@@ -1314,8 +1322,8 @@ void Viewport::popupContextMenu()
return;

switch (m->argument()) {
case ID_EXIT:
exit_vncviewer();
case ID_DISCONNECT:
disconnect();
break;
case ID_FULLSCREEN:
if (window()->fullscreen_active())

+ 4
- 0
vncviewer/parameters.cxx View File

@@ -69,6 +69,10 @@ BoolParameter alertOnFatalError("AlertOnFatalError",
"Give a dialog on connection problems rather "
"than exiting immediately", true);

BoolParameter reconnectOnError("ReconnectOnError",
"Give a dialog on connection problems rather "
"than exiting immediately and ask for a reconnect.", true);

StringParameter passwordFile("PasswordFile",
"Password file for VNC authentication", "");
AliasParameter passwd("passwd", "Alias for PasswordFile", &passwordFile);

+ 1
- 0
vncviewer/parameters.h View File

@@ -74,6 +74,7 @@ extern rfb::StringParameter menuKey;

extern rfb::BoolParameter fullscreenSystemKeys;
extern rfb::BoolParameter alertOnFatalError;
extern rfb::BoolParameter reconnectOnError;

#ifndef WIN32
extern rfb::StringParameter via;

+ 3
- 3
vncviewer/touch.cxx View File

@@ -181,7 +181,7 @@ static int handleTouchEvent(void *event, void *data)
handlers[msg->hwnd] = new Win32TouchHandler(msg->hwnd);
} catch (rfb::Exception& e) {
vlog.error(_("Failed to create touch handler: %s"), e.str());
exit_vncviewer(_("Failed to create touch handler: %s"), e.str());
abort_vncviewer(_("Failed to create touch handler: %s"), e.str());
}
// Add a special hook-in for handling events sent directly to WndProc
if (!SetWindowSubclass(msg->hwnd, &win32WindowProc, 1, 0)) {
@@ -248,14 +248,14 @@ void enable_touch()
fl_open_display();

if (!XQueryExtension(fl_display, "XInputExtension", &xi_major, &ev, &err)) {
exit_vncviewer(_("X Input extension not available."));
abort_vncviewer(_("X Input extension not available."));
return; // Not reached
}

major_ver = 2;
minor_ver = 2;
if (XIQueryVersion(fl_display, &major_ver, &minor_ver) != Success) {
exit_vncviewer(_("X Input 2 (or newer) is not available."));
abort_vncviewer(_("X Input 2 (or newer) is not available."));
return; // Not reached
}


+ 86
- 27
vncviewer/vncviewer.cxx View File

@@ -22,6 +22,7 @@
#include <config.h>
#endif

#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
@@ -87,7 +88,8 @@ static const char *argv0 = NULL;

static bool inMainloop = false;
static bool exitMainloop = false;
static const char *exitError = NULL;
static char *exitError = NULL;
static bool fatalError = false;

static const char *about_text()
{
@@ -107,17 +109,19 @@ static const char *about_text()
return buffer;
}

void exit_vncviewer(const char *error, ...)

void abort_vncviewer(const char *error, ...)
{
fatalError = true;

// Prioritise the first error we get as that is probably the most
// relevant one.
if ((error != NULL) && (exitError == NULL)) {
if (exitError == NULL) {
va_list ap;

va_start(ap, error);
exitError = (char*)malloc(1024);
if (exitError)
(void) vsnprintf((char*)exitError, 1024, error, ap);
vsnprintf(exitError, 1024, error, ap);
va_end(ap);
}

@@ -131,7 +135,30 @@ void exit_vncviewer(const char *error, ...)
}
}

bool should_exit()
void abort_connection(const char *error, ...)
{
assert(inMainloop);

// Prioritise the first error we get as that is probably the most
// relevant one.
if (exitError == NULL) {
va_list ap;

va_start(ap, error);
exitError = (char*)malloc(1024);
vsnprintf(exitError, 1024, error, ap);
va_end(ap);
}

exitMainloop = true;
}

void disconnect()
{
exitMainloop = true;
}

bool should_disconnect()
{
return exitMainloop;
}
@@ -142,17 +169,57 @@ void about_vncviewer()
fl_message("%s", about_text());
}

void run_mainloop()
static void mainloop(const char* vncserver, network::Socket* sock)
{
int next_timer;
while (true) {
CConn *cc;

next_timer = Timer::checkTimeouts();
if (next_timer == 0)
next_timer = INT_MAX;
exitMainloop = false;

if (Fl::wait((double)next_timer / 1000.0) < 0.0) {
vlog.error(_("Internal FLTK error. Exiting."));
exit(-1);
cc = new CConn(vncServerName, sock);

while (!exitMainloop) {
int next_timer;

next_timer = Timer::checkTimeouts();
if (next_timer == 0)
next_timer = INT_MAX;

if (Fl::wait((double)next_timer / 1000.0) < 0.0) {
vlog.error(_("Internal FLTK error. Exiting."));
exit(-1);
}
}

delete cc;

if (fatalError) {
assert(exitError != NULL);
if (alertOnFatalError)
fl_alert("%s", exitError);
break;
}

if (exitError == NULL)
break;

if(reconnectOnError && (sock == NULL)) {
int ret;
ret = fl_choice(_("%s\n\n"
"Attempt to reconnect?"),
fl_yes, fl_no, 0, exitError);
free(exitError);
exitError = NULL;
if (ret == 0)
continue;
else
break;
}

if (alertOnFatalError)
fl_alert("%s", exitError);

break;
}
}

@@ -429,8 +496,8 @@ potentiallyLoadConfigurationFile(char *vncServerName)
vncServerName[VNCSERVERNAMELEN-1] = '\0';
} catch (rfb::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(_("Error reading configuration file \"%s\":\n\n%s"),
vncServerName, e.str());
abort_vncviewer(_("Error reading configuration file \"%s\":\n\n%s"),
vncServerName, e.str());
}
}
}
@@ -640,7 +707,7 @@ int main(int argc, char** argv)
// TRANSLATORS: "Parameters" are command line arguments, or settings
// from a file or the Windows registry.
vlog.error(_("Parameters -listen and -via are incompatible"));
exit_vncviewer(_("Parameters -listen and -via are incompatible"));
abort_vncviewer(_("Parameters -listen and -via are incompatible"));
return 1; /* Not reached */
}
#endif
@@ -687,7 +754,7 @@ int main(int argc, char** argv)
}
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(_("Failure waiting for incoming VNC connection:\n\n%s"), e.str());
abort_vncviewer(_("Failure waiting for incoming VNC connection:\n\n%s"), e.str());
return 1; /* Not reached */
}

@@ -708,17 +775,9 @@ int main(int argc, char** argv)
#endif
}

CConn *cc = new CConn(vncServerName, sock);

inMainloop = true;
while (!exitMainloop)
run_mainloop();
mainloop(vncServerName, sock);
inMainloop = false;

delete cc;

if (exitError != NULL && alertOnFatalError)
fl_alert("%s", exitError);

return 0;
}

+ 5
- 3
vncviewer/vncviewer.h View File

@@ -27,9 +27,11 @@
# define __printf_attr(a, b)
#endif // __GNUC__

void exit_vncviewer(const char *error = NULL, ...) __printf_attr(1, 2);
bool should_exit();
void abort_vncviewer(const char *error, ...) __printf_attr(1, 2);
void abort_connection(const char *error, ...) __printf_attr(1, 2);
void disconnect();
bool should_disconnect();

void about_vncviewer();
void run_mainloop();

#endif

+ 6
- 0
vncviewer/vncviewer.man View File

@@ -328,6 +328,12 @@ respectively.
.TP
.B \-AlertOnFatalError
Display a dialog with any fatal error before exiting. Default is on.
.
.TP
.B \-ReconnectOnError
Display a dialog with any error and offer the possibility to retry
establishing the connection. In case this is off no dialog to
re-connect will be offered. Default is on.

.SH FILES
.TP

Loading…
Cancel
Save