aboutsummaryrefslogtreecommitdiffstats
path: root/common/rfb/SConnection.cxx
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2021-01-04 13:04:26 +0100
committerPierre Ossman <ossman@cendio.se>2021-01-04 13:04:26 +0100
commit1ea0f9f2109c12057c5fddc67ae3929928a3d7b1 (patch)
tree4b0a4c0155ab839774abb97db834425d724a4305 /common/rfb/SConnection.cxx
parent3a7fd223a2ea05f8781c6d3c3894ad33ef35b354 (diff)
downloadtigervnc-1ea0f9f2109c12057c5fddc67ae3929928a3d7b1.tar.gz
tigervnc-1ea0f9f2109c12057c5fddc67ae3929928a3d7b1.zip
Handle unsolicited clipboard transfers
The extended clipboard protocol has the ability for the peer to request things to be sent automatically, without a request message. Make sure we honor such settings.
Diffstat (limited to 'common/rfb/SConnection.cxx')
-rw-r--r--common/rfb/SConnection.cxx37
1 files changed, 31 insertions, 6 deletions
diff --git a/common/rfb/SConnection.cxx b/common/rfb/SConnection.cxx
index 4869199a..1b5f513e 100644
--- a/common/rfb/SConnection.cxx
+++ b/common/rfb/SConnection.cxx
@@ -54,7 +54,8 @@ SConnection::SConnection()
is(0), os(0), reader_(0), writer_(0),
ssecurity(0), state_(RFBSTATE_UNINITIALISED),
preferredEncoding(encodingRaw),
- clientClipboard(NULL), hasLocalClipboard(false)
+ clientClipboard(NULL), hasLocalClipboard(false),
+ unsolicitedClipboardAttempt(false)
{
defaultMajorVersion = 3;
defaultMinorVersion = 8;
@@ -503,14 +504,27 @@ void SConnection::requestClipboard()
void SConnection::announceClipboard(bool available)
{
hasLocalClipboard = available;
+ unsolicitedClipboardAttempt = false;
- if (client.supportsEncoding(pseudoEncodingExtendedClipboard) &&
- (client.clipboardFlags() & rfb::clipboardNotify))
- writer()->writeClipboardNotify(available ? rfb::clipboardUTF8 : 0);
- else {
- if (available)
+ if (client.supportsEncoding(pseudoEncodingExtendedClipboard)) {
+ // Attempt an unsolicited transfer?
+ if (available &&
+ (client.clipboardSize(rfb::clipboardUTF8) > 0) &&
+ (client.clipboardFlags() & rfb::clipboardProvide)) {
+ vlog.debug("Attempting unsolicited clipboard transfer...");
+ unsolicitedClipboardAttempt = true;
handleClipboardRequest();
+ return;
+ }
+
+ if (client.clipboardFlags() & rfb::clipboardNotify) {
+ writer()->writeClipboardNotify(available ? rfb::clipboardUTF8 : 0);
+ return;
+ }
}
+
+ if (available)
+ handleClipboardRequest();
}
void SConnection::sendClipboardData(const char* data)
@@ -520,6 +534,17 @@ void SConnection::sendClipboardData(const char* data)
CharArray filtered(convertCRLF(data));
size_t sizes[1] = { strlen(filtered.buf) + 1 };
const rdr::U8* data[1] = { (const rdr::U8*)filtered.buf };
+
+ if (unsolicitedClipboardAttempt) {
+ unsolicitedClipboardAttempt = false;
+ if (sizes[0] > client.clipboardSize(rfb::clipboardUTF8)) {
+ vlog.debug("Clipboard was too large for unsolicited clipboard transfer");
+ if (client.clipboardFlags() & rfb::clipboardNotify)
+ writer()->writeClipboardNotify(rfb::clipboardUTF8);
+ return;
+ }
+ }
+
writer()->writeClipboardProvide(rfb::clipboardUTF8, sizes, data);
} else {
CharArray latin1(utf8ToLatin1(data));