aboutsummaryrefslogtreecommitdiffstats
path: root/common/rfb/CConnection.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'common/rfb/CConnection.cxx')
-rw-r--r--common/rfb/CConnection.cxx182
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);
}