aboutsummaryrefslogtreecommitdiffstats
path: root/common/rfb/SConnection.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'common/rfb/SConnection.cxx')
-rw-r--r--common/rfb/SConnection.cxx83
1 files changed, 78 insertions, 5 deletions
diff --git a/common/rfb/SConnection.cxx b/common/rfb/SConnection.cxx
index 46f0a850..4869199a 100644
--- a/common/rfb/SConnection.cxx
+++ b/common/rfb/SConnection.cxx
@@ -20,6 +20,7 @@
#include <string.h>
#include <rfb/Exception.h>
#include <rfb/Security.h>
+#include <rfb/clipboardTypes.h>
#include <rfb/msgTypes.h>
#include <rfb/fenceTypes.h>
#include <rfb/SMsgReader.h>
@@ -53,7 +54,7 @@ SConnection::SConnection()
is(0), os(0), reader_(0), writer_(0),
ssecurity(0), state_(RFBSTATE_UNINITIALISED),
preferredEncoding(encodingRaw),
- clientClipboard(NULL)
+ clientClipboard(NULL), hasLocalClipboard(false)
{
defaultMajorVersion = 3;
defaultMinorVersion = 8;
@@ -299,6 +300,16 @@ void SConnection::setEncodings(int nEncodings, const rdr::S32* encodings)
}
SMsgHandler::setEncodings(nEncodings, encodings);
+
+ if (client.supportsEncoding(pseudoEncodingExtendedClipboard)) {
+ rdr::U32 sizes[] = { 0 };
+ writer()->writeClipboardCaps(rfb::clipboardUTF8 |
+ rfb::clipboardRequest |
+ rfb::clipboardPeek |
+ rfb::clipboardNotify |
+ rfb::clipboardProvide,
+ sizes);
+ }
}
void SConnection::clientCutText(const char* str)
@@ -311,6 +322,49 @@ void SConnection::clientCutText(const char* str)
handleClipboardAnnounce(true);
}
+void SConnection::handleClipboardRequest(rdr::U32 flags)
+{
+ if (!(flags & rfb::clipboardUTF8))
+ return;
+ if (!hasLocalClipboard)
+ return;
+ handleClipboardRequest();
+}
+
+void SConnection::handleClipboardPeek(rdr::U32 flags)
+{
+ if (!hasLocalClipboard)
+ return;
+ if (client.clipboardFlags() & rfb::clipboardNotify)
+ writer()->writeClipboardNotify(rfb::clipboardUTF8);
+}
+
+void SConnection::handleClipboardNotify(rdr::U32 flags)
+{
+ strFree(clientClipboard);
+ clientClipboard = NULL;
+
+ if (flags & rfb::clipboardUTF8)
+ handleClipboardAnnounce(true);
+ else
+ handleClipboardAnnounce(false);
+}
+
+void SConnection::handleClipboardProvide(rdr::U32 flags,
+ const size_t* lengths,
+ const rdr::U8* const* data)
+{
+ if (!(flags & rfb::clipboardUTF8))
+ return;
+
+ strFree(clientClipboard);
+ clientClipboard = NULL;
+
+ clientClipboard = convertLF((const char*)data[0], lengths[0]);
+
+ handleClipboardData(clientClipboard);
+}
+
void SConnection::supportsQEMUKeyEvent()
{
writer()->writeQEMUKeyEvent();
@@ -440,19 +494,38 @@ void SConnection::requestClipboard()
handleClipboardData(clientClipboard);
return;
}
+
+ if (client.supportsEncoding(pseudoEncodingExtendedClipboard) &&
+ (client.clipboardFlags() & rfb::clipboardRequest))
+ writer()->writeClipboardRequest(rfb::clipboardUTF8);
}
void SConnection::announceClipboard(bool available)
{
- if (available)
- handleClipboardRequest();
+ hasLocalClipboard = available;
+
+ if (client.supportsEncoding(pseudoEncodingExtendedClipboard) &&
+ (client.clipboardFlags() & rfb::clipboardNotify))
+ writer()->writeClipboardNotify(available ? rfb::clipboardUTF8 : 0);
+ else {
+ if (available)
+ handleClipboardRequest();
+ }
}
void SConnection::sendClipboardData(const char* data)
{
- CharArray latin1(utf8ToLatin1(data));
+ if (client.supportsEncoding(pseudoEncodingExtendedClipboard) &&
+ (client.clipboardFlags() & rfb::clipboardProvide)) {
+ CharArray filtered(convertCRLF(data));
+ size_t sizes[1] = { strlen(filtered.buf) + 1 };
+ const rdr::U8* data[1] = { (const rdr::U8*)filtered.buf };
+ writer()->writeClipboardProvide(rfb::clipboardUTF8, sizes, data);
+ } else {
+ CharArray latin1(utf8ToLatin1(data));
- writer()->writeServerCutText(latin1.buf);
+ writer()->writeServerCutText(latin1.buf);
+ }
}
void SConnection::writeFakeColourMap(void)