aboutsummaryrefslogtreecommitdiffstats
path: root/vncviewer/CConn.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vncviewer/CConn.cxx')
-rw-r--r--vncviewer/CConn.cxx81
1 files changed, 60 insertions, 21 deletions
diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx
index ba4876f2..da99c8f1 100644
--- a/vncviewer/CConn.cxx
+++ b/vncviewer/CConn.cxx
@@ -30,6 +30,7 @@
#include <core/LogWriter.h>
#include <core/Timer.h>
#include <core/string.h>
+#include <core/time.h>
#include <rdr/FdInStream.h>
#include <rdr/FdOutStream.h>
@@ -76,12 +77,12 @@ static const rfb::PixelFormat mediumColourPF(8, 8, false, true,
// Time new bandwidth estimates are weighted against (in ms)
static const unsigned bpsEstimateWindow = 1000;
-CConn::CConn(const char* vncServerName, network::Socket* socket=nullptr)
- : serverPort(0), desktop(nullptr), updateCount(0), pixelCount(0),
+CConn::CConn()
+ : serverPort(0), sock(nullptr), desktop(nullptr),
+ updateCount(0), pixelCount(0),
lastServerEncoding((unsigned int)-1), bpsEstimate(20000000)
{
setShared(::shared);
- sock = socket;
supportsLocalCursor = true;
supportsCursorPosition = true;
@@ -94,6 +95,61 @@ CConn::CConn(const char* vncServerName, network::Socket* socket=nullptr)
if (!noJpeg)
setQualityLevel(::qualityLevel);
+ OptionsDialog::addCallback(handleOptions, this);
+}
+
+CConn::~CConn()
+{
+ close();
+
+ OptionsDialog::removeCallback(handleOptions);
+ Fl::remove_timeout(handleUpdateTimeout, this);
+
+ if (desktop)
+ delete desktop;
+
+ if (sock) {
+ struct timeval now;
+
+ sock->shutdown();
+
+ // Do a graceful close by waiting for the peer (up to 250 ms)
+ // FIXME: should do this asynchronously
+ gettimeofday(&now, nullptr);
+ while (core::msSince(&now) < 250) {
+ bool done;
+
+ done = false;
+ while (true) {
+ try {
+ sock->inStream().skip(sock->inStream().avail());
+ if (!sock->inStream().hasData(1))
+ break;
+ } catch (std::exception&) {
+ done = true;
+ break;
+ }
+ }
+
+ if (done)
+ break;
+
+ #ifdef WIN32
+ Sleep(10);
+ #else
+ usleep(10000);
+ #endif
+ }
+
+ Fl::remove_fd(sock->getFd());
+
+ delete sock;
+ }
+}
+
+void CConn::connect(const char* vncServerName, network::Socket* socket)
+{
+ sock = socket;
if(sock == nullptr) {
try {
#ifndef WIN32
@@ -124,23 +180,6 @@ CConn::CConn(const char* vncServerName, network::Socket* socket=nullptr)
setStreams(&sock->inStream(), &sock->outStream());
initialiseProtocol();
-
- OptionsDialog::addCallback(handleOptions, this);
-}
-
-CConn::~CConn()
-{
- close();
-
- OptionsDialog::removeCallback(handleOptions);
- Fl::remove_timeout(handleUpdateTimeout, this);
-
- if (desktop)
- delete desktop;
-
- if (sock)
- Fl::remove_fd(sock->getFd());
- delete sock;
}
std::string CConn::connectionInfo()
@@ -322,7 +361,7 @@ void CConn::setExtendedDesktopSize(unsigned reason, unsigned result,
void CConn::setName(const char* name)
{
CConnection::setName(name);
- desktop->setName();
+ desktop->updateCaption();
}
// framebufferUpdateStart() is called at the beginning of an update.