diff options
Diffstat (limited to 'common/rfb/CConnection.cxx')
-rw-r--r-- | common/rfb/CConnection.cxx | 182 |
1 files changed, 138 insertions, 44 deletions
diff --git a/common/rfb/CConnection.cxx b/common/rfb/CConnection.cxx index 5e7530c8..bbeef385 100644 --- a/common/rfb/CConnection.cxx +++ b/common/rfb/CConnection.cxx @@ -27,31 +27,34 @@ #include <algorithm> +#include <core/LogWriter.h> +#include <core/string.h> + #include <rfb/Exception.h> #include <rfb/clipboardTypes.h> #include <rfb/fenceTypes.h> +#include <rfb/screenTypes.h> #include <rfb/CMsgReader.h> #include <rfb/CMsgWriter.h> #include <rfb/CSecurity.h> +#include <rfb/Cursor.h> #include <rfb/Decoder.h> #include <rfb/KeysymStr.h> +#include <rfb/PixelBuffer.h> #include <rfb/Security.h> #include <rfb/SecurityClient.h> #include <rfb/CConnection.h> -#include <rfb/util.h> #define XK_MISCELLANY #define XK_XKB_KEYS #include <rfb/keysymdef.h> -#include <rfb/LogWriter.h> - #include <rdr/InStream.h> #include <rdr/OutStream.h> using namespace rfb; -static LogWriter vlog("CConnection"); +static core::LogWriter vlog("CConnection"); CConnection::CConnection() : csecurity(nullptr), @@ -98,7 +101,7 @@ void CConnection::setFramebuffer(ModifiablePixelBuffer* fb) } if ((framebuffer != nullptr) && (fb != nullptr)) { - Rect rect; + core::Rect rect; const uint8_t* data; int stride; @@ -107,9 +110,8 @@ void CConnection::setFramebuffer(ModifiablePixelBuffer* fb) // Copy still valid area - rect.setXYWH(0, 0, - __rfbmin(fb->width(), framebuffer->width()), - __rfbmin(fb->height(), framebuffer->height())); + rect = fb->getRect(); + rect = rect.intersect(framebuffer->getRect()); data = framebuffer->getBuffer(framebuffer->getRect(), &stride); fb->imageRect(rect, data, stride); @@ -189,10 +191,9 @@ bool CConnection::processVersionMsg() vlog.error("Server gave unsupported RFB protocol version %d.%d", server.majorVersion, server.minorVersion); state_ = RFBSTATE_INVALID; - throw protocol_error(format("Server gave unsupported RFB protocol " - "version %d.%d", - server.majorVersion, - server.minorVersion)); + throw protocol_error( + core::format("Server gave unsupported RFB protocol version %d.%d", + server.majorVersion, server.minorVersion)); } else if (server.beforeVersion(3,7)) { server.setVersion(3,3); } else if (server.afterVersion(3,8)) { @@ -379,7 +380,6 @@ void CConnection::securityCompleted() reader_ = new CMsgReader(this, is); writer_ = new CMsgWriter(&server, os); vlog.debug("Authentication success!"); - authSuccess(); writer_->writeClientInit(shared); } @@ -410,7 +410,7 @@ void CConnection::setDesktopSize(int w, int h) { decoder.flush(); - CMsgHandler::setDesktopSize(w,h); + server.setDimensions(w, h); if (continuousUpdates) writer()->writeEnableContinuousUpdates(true, 0, 0, @@ -430,7 +430,15 @@ void CConnection::setExtendedDesktopSize(unsigned reason, { decoder.flush(); - CMsgHandler::setExtendedDesktopSize(reason, result, w, h, layout); + server.supportsSetDesktopSize = true; + + if ((reason != reasonClient) || (result == resultSuccess)) + server.setDimensions(w, h, layout); + + if ((reason == reasonClient) && (result != resultSuccess)) { + vlog.error("SetDesktopSize failed: %d", result); + return; + } if (continuousUpdates) writer()->writeEnableContinuousUpdates(true, 0, 0, @@ -443,9 +451,41 @@ void CConnection::setExtendedDesktopSize(unsigned reason, assert(framebuffer->height() == server.height()); } +void CConnection::setCursor(int width, int height, + const core::Point& hotspot, + const uint8_t* data) +{ + Cursor cursor(width, height, hotspot, data); + server.setCursor(cursor); +} + +void CConnection::setCursorPos(const core::Point& /*pos*/) +{ +} + +void CConnection::setName(const char* name) +{ + server.setName(name); +} + +void CConnection::fence(uint32_t flags, unsigned len, const uint8_t data[]) +{ + server.supportsFence = true; + + if (flags & fenceFlagRequest) { + // FIXME: We handle everything synchronously, and we assume anything + // using us also does so, which means we automatically handle + // these flags + flags = flags & (fenceFlagBlockBefore | fenceFlagBlockAfter); + + writer()->writeFence(flags, len, data); + return; + } +} + void CConnection::endOfContinuousUpdates() { - CMsgHandler::endOfContinuousUpdates(); + server.supportsContinuousUpdates = true; // We've gotten the marker for a format change, so make the pending // one active @@ -459,11 +499,23 @@ void CConnection::endOfContinuousUpdates() } } +void CConnection::supportsQEMUKeyEvent() +{ + server.supportsQEMUKeyEvent = true; +} + +void CConnection::supportsExtendedMouseButtons() +{ + server.supportsExtendedMouseButtons = true; +} + void CConnection::serverInit(int width, int height, const PixelFormat& pf, const char* name) { - CMsgHandler::serverInit(width, height, pf, name); + server.setDimensions(width, height); + server.setPF(pf); + server.setName(name); state_ = RFBSTATE_NORMAL; vlog.debug("Initialisation done"); @@ -486,7 +538,7 @@ void CConnection::serverInit(int width, int height, } } -bool CConnection::readAndDecodeRect(const Rect& r, int encoding, +bool CConnection::readAndDecodeRect(const core::Rect& r, int encoding, ModifiablePixelBuffer* pb) { if (!decoder.decodeRect(r, encoding, pb)) @@ -497,8 +549,6 @@ bool CConnection::readAndDecodeRect(const Rect& r, int encoding, void CConnection::framebufferUpdateStart() { - CMsgHandler::framebufferUpdateStart(); - assert(framebuffer != nullptr); // Note: This might not be true if continuous updates are supported @@ -511,8 +561,6 @@ void CConnection::framebufferUpdateEnd() { decoder.flush(); - CMsgHandler::framebufferUpdateEnd(); - // 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 && !continuousUpdates) { @@ -533,11 +581,18 @@ void CConnection::framebufferUpdateEnd() } } -bool CConnection::dataRect(const Rect& r, int encoding) +bool CConnection::dataRect(const core::Rect& r, int encoding) { return decoder.decodeRect(r, encoding, framebuffer); } +void CConnection::setColourMapEntries(int /*firstColour*/, + int /*nColours*/, + uint16_t* /*rgbs*/) +{ + vlog.error("Invalid SetColourMapEntries from server!"); +} + void CConnection::serverCutText(const char* str) { hasLocalClipboard = false; @@ -548,12 +603,53 @@ void CConnection::serverCutText(const char* str) handleClipboardAnnounce(true); } +void CConnection::setLEDState(unsigned int state) +{ + server.setLEDState(state); +} + void CConnection::handleClipboardCaps(uint32_t flags, const uint32_t* lengths) { + int i; uint32_t sizes[] = { 0 }; - CMsgHandler::handleClipboardCaps(flags, lengths); + vlog.debug("Got server clipboard capabilities:"); + for (i = 0;i < 16;i++) { + if (flags & (1 << i)) { + const char *type; + + switch (1 << i) { + case clipboardUTF8: + type = "Plain text"; + break; + case clipboardRTF: + type = "Rich text"; + break; + case clipboardHTML: + type = "HTML"; + break; + case clipboardDIB: + type = "Images"; + break; + case clipboardFiles: + type = "Files"; + break; + default: + vlog.debug(" Unknown format 0x%x", 1 << i); + continue; + } + + if (lengths[i] == 0) + vlog.debug(" %s (only notify)", type); + else { + vlog.debug(" %s (automatically send up to %s)", + type, core::iecPrefix(lengths[i], "B").c_str()); + } + } + } + + server.setClipboardCaps(flags, lengths); writer()->writeClipboardCaps(rfb::clipboardUTF8 | rfb::clipboardRequest | @@ -604,21 +700,17 @@ void CConnection::handleClipboardProvide(uint32_t flags, } // FIXME: This conversion magic should be in CMsgReader - if (!isValidUTF8((const char*)data[0], lengths[0])) { + if (!core::isValidUTF8((const char*)data[0], lengths[0])) { vlog.error("Invalid UTF-8 sequence in clipboard - ignoring"); return; } - serverClipboard = convertLF((const char*)data[0], lengths[0]); + serverClipboard = core::convertLF((const char*)data[0], lengths[0]); hasRemoteClipboard = true; // FIXME: Should probably verify that this data was actually requested handleClipboardData(serverClipboard.c_str()); } -void CConnection::authSuccess() -{ -} - void CConnection::initDone() { } @@ -679,7 +771,7 @@ void CConnection::sendClipboardData(const char* data) { if (server.clipboardFlags() & rfb::clipboardProvide) { // FIXME: This conversion magic should be in CMsgWriter - std::string filtered(convertCRLF(data)); + std::string filtered(core::convertCRLF(data)); size_t sizes[1] = { filtered.size() + 1 }; const uint8_t* datas[1] = { (const uint8_t*)filtered.c_str() }; @@ -815,6 +907,11 @@ void CConnection::setCompressLevel(int level) encodingChange = true; } +int CConnection::getCompressLevel() +{ + return compressLevel; +} + void CConnection::setQualityLevel(int level) { if (qualityLevel == level) @@ -824,6 +921,11 @@ void CConnection::setQualityLevel(int level) encodingChange = true; } +int CConnection::getQualityLevel() +{ + return qualityLevel; +} + void CConnection::setPF(const PixelFormat& pf) { if (server.pf() == pf && !formatChange) @@ -833,17 +935,9 @@ void CConnection::setPF(const PixelFormat& pf) formatChange = true; } -void CConnection::fence(uint32_t flags, unsigned len, const uint8_t data[]) +bool CConnection::isSecure() const { - CMsgHandler::fence(flags, len, data); - - if (!(flags & fenceFlagRequest)) - return; - - // We cannot guarantee any synchronisation at this level - flags = 0; - - writer()->writeFence(flags, len, data); + return csecurity ? csecurity->isSecure() : false; } // requestNewUpdate() requests an update from the server, having set the @@ -884,9 +978,9 @@ void CConnection::requestNewUpdate() if (forceNonincremental || !continuousUpdates) { pendingUpdate = true; - writer()->writeFramebufferUpdateRequest(Rect(0, 0, - server.width(), - server.height()), + writer()->writeFramebufferUpdateRequest({0, 0, + server.width(), + server.height()}, !forceNonincremental); } |