diff options
author | Pierre Ossman <ossman@cendio.se> | 2018-12-10 21:16:07 +0100 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2018-12-10 21:16:07 +0100 |
commit | d8bbbeb3b37c713a72a113f7ef78741e15cc4a4d (patch) | |
tree | 7d8076302c65cf6ffbd2ccbf9d581476412be36b /vncviewer | |
parent | 139b96741004adc92032a93b8ef6e5927a618f6d (diff) | |
parent | c3826bb2fcb60efa495b54dd66296bc55ce28ecf (diff) | |
download | tigervnc-d8bbbeb3b37c713a72a113f7ef78741e15cc4a4d.tar.gz tigervnc-d8bbbeb3b37c713a72a113f7ef78741e15cc4a4d.zip |
Merge branch 'connparams' of https://github.com/CendioOssman/tigervnc
Diffstat (limited to 'vncviewer')
-rw-r--r-- | vncviewer/CConn.cxx | 265 | ||||
-rw-r--r-- | vncviewer/CConn.h | 23 | ||||
-rw-r--r-- | vncviewer/DesktopWindow.cxx | 28 | ||||
-rw-r--r-- | vncviewer/Viewport.cxx | 10 |
4 files changed, 75 insertions, 251 deletions
diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx index 69186c55..b4610e6a 100644 --- a/vncviewer/CConn.cxx +++ b/vncviewer/CConn.cxx @@ -36,8 +36,6 @@ #include <rfb/screenTypes.h> #include <rfb/fenceTypes.h> #include <rfb/Timer.h> -#include <rdr/MemInStream.h> -#include <rdr/MemOutStream.h> #include <network/TcpSocket.h> #ifndef WIN32 #include <network/UnixSocket.h> @@ -76,36 +74,21 @@ static const PixelFormat mediumColourPF(8, 8, false, true, CConn::CConn(const char* vncServerName, network::Socket* socket=NULL) : serverHost(0), serverPort(0), desktop(NULL), - updateCount(0), pixelCount(0), pendingPFChange(false), - currentEncoding(encodingTight), lastServerEncoding((unsigned int)-1), - formatChange(false), encodingChange(false), - firstUpdate(true), pendingUpdate(false), continuousUpdates(false), - forceNonincremental(true), supportsSyncFence(false) + updateCount(0), pixelCount(0), + lastServerEncoding((unsigned int)-1) { setShared(::shared); sock = socket; - int encNum = encodingNum(preferredEncoding); - if (encNum != -1) - currentEncoding = encNum; - - cp.supportsLocalCursor = true; - - cp.supportsDesktopResize = true; - cp.supportsExtendedDesktopSize = true; - cp.supportsDesktopRename = true; - - cp.supportsLEDState = true; + supportsLocalCursor = true; + supportsDesktopResize = true; + supportsLEDState = true; if (customCompressLevel) - cp.compressLevel = compressLevel; - else - cp.compressLevel = -1; + setCompressLevel(::compressLevel); if (!noJpeg) - cp.qualityLevel = qualityLevel; - else - cp.qualityLevel = -1; + setQualityLevel(::qualityLevel); if(sock == NULL) { try { @@ -158,16 +141,6 @@ CConn::~CConn() delete sock; } -void CConn::refreshFramebuffer() -{ - forceNonincremental = true; - - // Without fences, we cannot safely trigger an update request directly - // but must wait for the next update to arrive. - if (supportsSyncFence) - requestNewUpdate(); -} - const char *CConn::connectionInfo() { static char infoText[1024] = ""; @@ -181,7 +154,7 @@ const char *CConn::connectionInfo() infoText[0] = '\0'; snprintf(scratch, sizeof(scratch), - _("Desktop name: %.80s"), cp.name()); + _("Desktop name: %.80s"), server.name()); strcat(infoText, scratch); strcat(infoText, "\n"); @@ -191,13 +164,13 @@ const char *CConn::connectionInfo() strcat(infoText, "\n"); snprintf(scratch, sizeof(scratch), - _("Size: %d x %d"), cp.width, cp.height); + _("Size: %d x %d"), server.width(), server.height()); strcat(infoText, scratch); strcat(infoText, "\n"); // TRANSLATORS: Will be filled in with a string describing the // protocol pixel format in a fairly language neutral way - cp.pf().print(pfStr, 100); + server.pf().print(pfStr, 100); snprintf(scratch, sizeof(scratch), _("Pixel format: %s"), pfStr); strcat(infoText, scratch); @@ -211,7 +184,7 @@ const char *CConn::connectionInfo() strcat(infoText, "\n"); snprintf(scratch, sizeof(scratch), - _("Requested encoding: %s"), encodingName(currentEncoding)); + _("Requested encoding: %s"), encodingName(getPreferredEncoding())); strcat(infoText, scratch); strcat(infoText, "\n"); @@ -226,7 +199,7 @@ const char *CConn::connectionInfo() strcat(infoText, "\n"); snprintf(scratch, sizeof(scratch), - _("Protocol version: %d.%d"), cp.majorVersion, cp.minorVersion); + _("Protocol version: %d.%d"), server.majorVersion, server.minorVersion); strcat(infoText, scratch); strcat(infoText, "\n"); @@ -310,34 +283,27 @@ void CConn::socketEvent(FL_SOCKET fd, void *data) ////////////////////// CConnection callback methods ////////////////////// -// serverInit() is called when the serverInit message has been received. At +// initDone() is called when the serverInit message has been received. At // this point we create the desktop window and display it. We also tell the // server the pixel format and encodings to use and request the first update. -void CConn::serverInit() +void CConn::initDone() { - CConnection::serverInit(); - // If using AutoSelect with old servers, start in FullColor // mode. See comment in autoSelectFormatAndEncoding. - if (cp.beforeVersion(3, 8) && autoSelect) + if (server.beforeVersion(3, 8) && autoSelect) fullColour.setParam(true); - serverPF = cp.pf(); + serverPF = server.pf(); - desktop = new DesktopWindow(cp.width, cp.height, cp.name(), serverPF, this); + desktop = new DesktopWindow(server.width(), server.height(), + server.name(), serverPF, this); fullColourPF = desktop->getPreferredPF(); // Force a switch to the format and encoding we'd like - formatChange = encodingChange = true; - - // And kick off the update cycle - requestNewUpdate(); - - // This initial update request is a bit of a corner case, so we need - // to help out setting the correct format here. - assert(pendingPFChange); - cp.setPF(pendingPF); - pendingPFChange = false; + updatePixelFormat(); + int encNum = encodingNum(::preferredEncoding); + if (encNum != -1) + setPreferredEncoding(encNum); } // setDesktopSize() is called when the desktop size changes (including when @@ -366,8 +332,7 @@ void CConn::setExtendedDesktopSize(unsigned reason, unsigned result, void CConn::setName(const char* name) { CConnection::setName(name); - if (desktop) - desktop->setName(name); + desktop->setName(name); } // framebufferUpdateStart() is called at the beginning of an update. @@ -378,11 +343,6 @@ void CConn::framebufferUpdateStart() { CConnection::framebufferUpdateStart(); - // Note: This might not be true if sync fences are supported - pendingUpdate = false; - - requestNewUpdate(); - // Update the screen prematurely for very slow updates Fl::add_timeout(1.0, handleUpdateTimeout, this); } @@ -400,22 +360,6 @@ void CConn::framebufferUpdateEnd() Fl::remove_timeout(handleUpdateTimeout, this); desktop->updateWindow(); - if (firstUpdate) { - // We need fences to make extra update requests and continuous - // updates "safe". See fence() for the next step. - if (cp.supportsFence) - writer()->writeFence(fenceFlagRequest | fenceFlagSyncNext, 0, NULL); - - firstUpdate = false; - } - - // A format change has been scheduled and we are now past the update - // with the old format. Time to active the new one. - if (pendingPFChange) { - cp.setPF(pendingPF); - pendingPFChange = false; - } - // Compute new settings based on updated bandwidth values if (autoSelect) autoSelectFormatAndEncoding(); @@ -469,27 +413,6 @@ void CConn::fence(rdr::U32 flags, unsigned len, const char data[]) writer()->writeFence(flags, len, data); return; } - - if (len == 0) { - // Initial probe - if (flags & fenceFlagSyncNext) { - supportsSyncFence = true; - - if (cp.supportsContinuousUpdates) { - vlog.info(_("Enabling continuous updates")); - continuousUpdates = true; - writer()->writeEnableContinuousUpdates(true, 0, 0, cp.width, cp.height); - } - } - } else { - // Pixel format change - rdr::MemInStream memStream(data, len); - PixelFormat pf; - - pf.read(&memStream); - - cp.setPF(pf); - } } void CConn::setLEDState(unsigned int state) @@ -504,13 +427,7 @@ void CConn::setLEDState(unsigned int state) void CConn::resizeFramebuffer() { - if (!desktop) - return; - - if (continuousUpdates) - writer()->writeEnableContinuousUpdates(true, 0, 0, cp.width, cp.height); - - desktop->resizeFramebuffer(cp.width, cp.height); + desktop->resizeFramebuffer(server.width(), server.height()); } // autoSelectFormatAndEncoding() chooses the format and encoding appropriate @@ -533,13 +450,10 @@ void CConn::autoSelectFormatAndEncoding() int kbitsPerSecond = sock->inStream().kbitsPerSecond(); unsigned int timeWaited = sock->inStream().timeWaited(); bool newFullColour = fullColour; - int newQualityLevel = qualityLevel; + int newQualityLevel = ::qualityLevel; // Always use Tight - if (currentEncoding != encodingTight) { - currentEncoding = encodingTight; - encodingChange = true; - } + setPreferredEncoding(encodingTight); // Check that we have a decent bandwidth measurement if ((kbitsPerSecond == 0) || (timeWaited < 10000)) @@ -552,16 +466,15 @@ void CConn::autoSelectFormatAndEncoding() else newQualityLevel = 6; - if (newQualityLevel != qualityLevel) { + if (newQualityLevel != ::qualityLevel) { vlog.info(_("Throughput %d kbit/s - changing to quality %d"), kbitsPerSecond, newQualityLevel); - cp.qualityLevel = newQualityLevel; - qualityLevel.setParam(newQualityLevel); - encodingChange = true; + ::qualityLevel.setParam(newQualityLevel); + setQualityLevel(newQualityLevel); } } - if (cp.beforeVersion(3, 8)) { + if (server.beforeVersion(3, 8)) { // Xvnc from TightVNC 1.2.9 sends out FramebufferUpdates with // cursors "asynchronously". If this happens in the middle of a // pixel format change, the server will encode the cursor with @@ -582,76 +495,31 @@ void CConn::autoSelectFormatAndEncoding() vlog.info(_("Throughput %d kbit/s - full color is now disabled"), kbitsPerSecond); fullColour.setParam(newFullColour); - formatChange = true; + updatePixelFormat(); } } -// checkEncodings() sends a setEncodings message if one is needed. -void CConn::checkEncodings() -{ - if (encodingChange && writer()) { - vlog.info(_("Using %s encoding"),encodingName(currentEncoding)); - writer()->writeSetEncodings(currentEncoding, true); - encodingChange = false; - } -} - // requestNewUpdate() requests an update from the server, having set the // format and encoding appropriately. -void CConn::requestNewUpdate() +void CConn::updatePixelFormat() { - if (formatChange) { - PixelFormat pf; - - /* Catch incorrect requestNewUpdate calls */ - assert(!pendingUpdate || supportsSyncFence); - - if (fullColour) { - pf = fullColourPF; - } else { - if (lowColourLevel == 0) - pf = verylowColourPF; - else if (lowColourLevel == 1) - pf = lowColourPF; - else - pf = mediumColourPF; - } - - if (supportsSyncFence) { - // We let the fence carry the pixel format and switch once we - // get the response back. That way we will be synchronised with - // when the server switches. - rdr::MemOutStream memStream; - - pf.write(&memStream); - - writer()->writeFence(fenceFlagRequest | fenceFlagSyncNext, - memStream.length(), (const char*)memStream.data()); - } else { - // New requests are sent out at the start of processing the last - // one, so we cannot switch our internal format right now (doing so - // would mean misdecoding the current update). - pendingPFChange = true; - pendingPF = pf; - } - - char str[256]; - pf.print(str, 256); - vlog.info(_("Using pixel format %s"),str); - writer()->writeSetPixelFormat(pf); + PixelFormat pf; - formatChange = false; + if (fullColour) { + pf = fullColourPF; + } else { + if (lowColourLevel == 0) + pf = verylowColourPF; + else if (lowColourLevel == 1) + pf = lowColourPF; + else + pf = mediumColourPF; } - checkEncodings(); - - if (forceNonincremental || !continuousUpdates) { - pendingUpdate = true; - writer()->writeFramebufferUpdateRequest(Rect(0, 0, cp.width, cp.height), - !forceNonincremental); - } - - forceNonincremental = false; + char str[256]; + pf.print(str, 256); + vlog.info(_("Using pixel format %s"),str); + setPF(pf); } void CConn::handleOptions(void *data) @@ -663,50 +531,23 @@ void CConn::handleOptions(void *data) // list is cheap. Avoid overriding what the auto logic has selected // though. if (!autoSelect) { - int encNum = encodingNum(preferredEncoding); + int encNum = encodingNum(::preferredEncoding); if (encNum != -1) - self->currentEncoding = encNum; + self->setPreferredEncoding(encNum); } - self->cp.supportsLocalCursor = true; - if (customCompressLevel) - self->cp.compressLevel = compressLevel; + self->setCompressLevel(::compressLevel); else - self->cp.compressLevel = -1; + self->setCompressLevel(-1); if (!noJpeg && !autoSelect) - self->cp.qualityLevel = qualityLevel; + self->setQualityLevel(::qualityLevel); else - self->cp.qualityLevel = -1; - - self->encodingChange = true; - - // Format changes refreshes the entire screen though and are therefore - // very costly. It's probably worth the effort to see if it is necessary - // here. - PixelFormat pf; + self->setQualityLevel(-1); - if (fullColour) { - pf = self->fullColourPF; - } else { - if (lowColourLevel == 0) - pf = verylowColourPF; - else if (lowColourLevel == 1) - pf = lowColourPF; - else - pf = mediumColourPF; - } - - if (!pf.equal(self->cp.pf())) { - self->formatChange = true; - - // Without fences, we cannot safely trigger an update request directly - // but must wait for the next update to arrive. - if (self->supportsSyncFence) - self->requestNewUpdate(); - } + self->updatePixelFormat(); } void CConn::handleUpdateTimeout(void *data) diff --git a/vncviewer/CConn.h b/vncviewer/CConn.h index dd4ae893..2e3362ce 100644 --- a/vncviewer/CConn.h +++ b/vncviewer/CConn.h @@ -36,8 +36,6 @@ public: CConn(const char* vncServerName, network::Socket* sock); ~CConn(); - void refreshFramebuffer(); - const char *connectionInfo(); unsigned getUpdateCount(); @@ -51,7 +49,7 @@ public: static void socketEvent(FL_SOCKET fd, void *data); // CConnection callback methods - void serverInit(); + void initDone(); void setDesktopSize(int w, int h); void setExtendedDesktopSize(unsigned reason, unsigned result, @@ -81,8 +79,7 @@ private: void resizeFramebuffer(); void autoSelectFormatAndEncoding(); - void checkEncodings(); - void requestNewUpdate(); + void updatePixelFormat(); static void handleOptions(void *data); @@ -101,21 +98,7 @@ private: rfb::PixelFormat serverPF; rfb::PixelFormat fullColourPF; - bool pendingPFChange; - rfb::PixelFormat pendingPF; - - int currentEncoding, lastServerEncoding; - - bool formatChange; - bool encodingChange; - - bool firstUpdate; - bool pendingUpdate; - bool continuousUpdates; - - bool forceNonincremental; - - bool supportsSyncFence; + int lastServerEncoding; }; #endif diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx index 1843485a..150c39bc 100644 --- a/vncviewer/DesktopWindow.cxx +++ b/vncviewer/DesktopWindow.cxx @@ -235,7 +235,7 @@ void DesktopWindow::setName(const char *name) void DesktopWindow::updateWindow() { if (firstUpdate) { - if (cc->cp.supportsSetDesktopSize) { + if (cc->server.supportsSetDesktopSize) { // Hack: Wait until we're in the proper mode and position until // resizing things, otherwise we might send the wrong thing. if (delayedFullscreen) @@ -487,7 +487,7 @@ void DesktopWindow::resize(int x, int y, int w, int h) // d) We're not still waiting for startup fullscreen to kick in // if (not firstUpdate and not delayedFullscreen and - ::remoteResize and cc->cp.supportsSetDesktopSize) { + ::remoteResize and cc->server.supportsSetDesktopSize) { // We delay updating the remote desktop as we tend to get a flood // of resize events as the user is dragging the window. Fl::remove_timeout(handleResizeTimeout, this); @@ -1014,14 +1014,14 @@ void DesktopWindow::handleResizeTimeout(void *data) void DesktopWindow::remoteResize(int width, int height) { ScreenSet layout; - ScreenSet::iterator iter; + ScreenSet::const_iterator iter; if (!fullscreen_active() || (width > w()) || (height > h())) { // In windowed mode (or the framebuffer is so large that we need // to scroll) we just report a single virtual screen that covers // the entire framebuffer. - layout = cc->cp.screenLayout; + layout = cc->server.screenLayout(); // Not sure why we have no screens, but adding a new one should be // safe as there is nothing to conflict with... @@ -1077,8 +1077,8 @@ void DesktopWindow::remoteResize(int width, int height) sy -= viewport_rect.tl.y; // Look for perfectly matching existing screen... - for (iter = cc->cp.screenLayout.begin(); - iter != cc->cp.screenLayout.end(); ++iter) { + for (iter = cc->server.screenLayout().begin(); + iter != cc->server.screenLayout().end(); ++iter) { if ((iter->dimensions.tl.x == sx) && (iter->dimensions.tl.y == sy) && (iter->dimensions.width() == sw) && @@ -1087,7 +1087,7 @@ void DesktopWindow::remoteResize(int width, int height) } // Found it? - if (iter != cc->cp.screenLayout.end()) { + if (iter != cc->server.screenLayout().end()) { layout.add_screen(*iter); continue; } @@ -1095,13 +1095,13 @@ void DesktopWindow::remoteResize(int width, int height) // Need to add a new one, which means we need to find an unused id while (true) { id = rand(); - for (iter = cc->cp.screenLayout.begin(); - iter != cc->cp.screenLayout.end(); ++iter) { + for (iter = cc->server.screenLayout().begin(); + iter != cc->server.screenLayout().end(); ++iter) { if (iter->id == id) break; } - if (iter == cc->cp.screenLayout.end()) + if (iter == cc->server.screenLayout().end()) break; } @@ -1115,14 +1115,14 @@ void DesktopWindow::remoteResize(int width, int height) } // Do we actually change anything? - if ((width == cc->cp.width) && - (height == cc->cp.height) && - (layout == cc->cp.screenLayout)) + if ((width == cc->server.width()) && + (height == cc->server.height()) && + (layout == cc->server.screenLayout())) return; char buffer[2048]; vlog.debug("Requesting framebuffer resize from %dx%d to %dx%d", - cc->cp.width, cc->cp.height, width, height); + cc->server.width(), cc->server.height(), width, height); layout.print(buffer, sizeof(buffer)); vlog.debug("%s", buffer); diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx index 18ed69e7..425cb9f2 100644 --- a/vncviewer/Viewport.cxx +++ b/vncviewer/Viewport.cxx @@ -425,7 +425,7 @@ void Viewport::pushLEDState() unsigned int state; // Server support? - if (cc->cp.ledState() == ledUnknown) + if (cc->server.ledState() == ledUnknown) return; state = 0; @@ -458,7 +458,7 @@ void Viewport::pushLEDState() state |= ledNumLock; // No support for Scroll Lock // - state |= (cc->cp.ledState() & ledScrollLock); + state |= (cc->server.ledState() & ledScrollLock); #else unsigned int mask; @@ -484,17 +484,17 @@ void Viewport::pushLEDState() state |= ledScrollLock; #endif - if ((state & ledCapsLock) != (cc->cp.ledState() & ledCapsLock)) { + if ((state & ledCapsLock) != (cc->server.ledState() & ledCapsLock)) { vlog.debug("Inserting fake CapsLock to get in sync with server"); handleKeyPress(0x3a, XK_Caps_Lock); handleKeyRelease(0x3a); } - if ((state & ledNumLock) != (cc->cp.ledState() & ledNumLock)) { + if ((state & ledNumLock) != (cc->server.ledState() & ledNumLock)) { vlog.debug("Inserting fake NumLock to get in sync with server"); handleKeyPress(0x45, XK_Num_Lock); handleKeyRelease(0x45); } - if ((state & ledScrollLock) != (cc->cp.ledState() & ledScrollLock)) { + if ((state & ledScrollLock) != (cc->server.ledState() & ledScrollLock)) { vlog.debug("Inserting fake ScrollLock to get in sync with server"); handleKeyPress(0x46, XK_Scroll_Lock); handleKeyRelease(0x46); |