Skip to content

Commit

Permalink
Merge branch 'autoclip' of https://github.com/CendioOssman/tigervnc
Browse files Browse the repository at this point in the history
  • Loading branch information
CendioOssman committed Feb 3, 2021
2 parents 7f56b54 + 49122f6 commit 35b4eed
Show file tree
Hide file tree
Showing 12 changed files with 209 additions and 31 deletions.
47 changes: 37 additions & 10 deletions common/rfb/CConnection.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -548,19 +548,21 @@ void CConnection::handleClipboardCaps(rdr::U32 flags,

void CConnection::handleClipboardRequest(rdr::U32 flags)
{
if (!(flags & rfb::clipboardUTF8))
if (!(flags & rfb::clipboardUTF8)) {
vlog.debug("Ignoring clipboard request for unsupported formats 0x%x", flags);
return;
if (!hasLocalClipboard)
}
if (!hasLocalClipboard) {
vlog.debug("Ignoring unexpected clipboard request");
return;
}
handleClipboardRequest();
}

void CConnection::handleClipboardPeek(rdr::U32 flags)
{
if (!hasLocalClipboard)
return;
if (server.clipboardFlags() & rfb::clipboardNotify)
writer()->writeClipboardNotify(rfb::clipboardUTF8);
writer()->writeClipboardNotify(hasLocalClipboard ? rfb::clipboardUTF8 : 0);
}

void CConnection::handleClipboardNotify(rdr::U32 flags)
Expand All @@ -580,8 +582,10 @@ void CConnection::handleClipboardProvide(rdr::U32 flags,
const size_t* lengths,
const rdr::U8* const* data)
{
if (!(flags & rfb::clipboardUTF8))
if (!(flags & rfb::clipboardUTF8)) {
vlog.debug("Ignoring clipboard provide with unsupported formats 0x%x", flags);
return;
}

strFree(serverClipboard);
serverClipboard = NULL;
Expand Down Expand Up @@ -631,13 +635,25 @@ void CConnection::requestClipboard()
void CConnection::announceClipboard(bool available)
{
hasLocalClipboard = available;
unsolicitedClipboardAttempt = false;

// Attempt an unsolicited transfer?
if (available &&
(server.clipboardSize(rfb::clipboardUTF8) > 0) &&
(server.clipboardFlags() & rfb::clipboardProvide)) {
vlog.debug("Attempting unsolicited clipboard transfer...");
unsolicitedClipboardAttempt = true;
handleClipboardRequest();
return;
}

if (server.clipboardFlags() & rfb::clipboardNotify)
if (server.clipboardFlags() & rfb::clipboardNotify) {
writer()->writeClipboardNotify(available ? rfb::clipboardUTF8 : 0);
else {
if (available)
handleClipboardRequest();
return;
}

if (available)
handleClipboardRequest();
}

void CConnection::sendClipboardData(const char* data)
Expand All @@ -646,6 +662,17 @@ void CConnection::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] > server.clipboardSize(rfb::clipboardUTF8)) {
vlog.debug("Clipboard was too large for unsolicited clipboard transfer");
if (server.clipboardFlags() & rfb::clipboardNotify)
writer()->writeClipboardNotify(rfb::clipboardUTF8);
return;
}
}

writer()->writeClipboardProvide(rfb::clipboardUTF8, sizes, data);
} else {
CharArray latin1(utf8ToLatin1(data));
Expand Down
1 change: 1 addition & 0 deletions common/rfb/CConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ namespace rfb {

char* serverClipboard;
bool hasLocalClipboard;
bool unsolicitedClipboardAttempt;
};
}
#endif
41 changes: 41 additions & 0 deletions common/rfb/CMsgHandler.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <rfb/Exception.h>
#include <rfb/LogWriter.h>
#include <rfb/CMsgHandler.h>
#include <rfb/clipboardTypes.h>
#include <rfb/screenTypes.h>

static rfb::LogWriter vlog("CMsgHandler");
Expand Down Expand Up @@ -101,6 +102,46 @@ void CMsgHandler::setLEDState(unsigned int state)

void CMsgHandler::handleClipboardCaps(rdr::U32 flags, const rdr::U32* lengths)
{
int i;

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 {
char bytes[1024];

iecPrefix(lengths[i], "B", bytes, sizeof(bytes));
vlog.debug(" %s (automatically send up to %s)",
type, bytes);
}
}
}

server.setClipboardCaps(flags, lengths);
}

Expand Down
12 changes: 12 additions & 0 deletions common/rfb/ClientParams.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,18 @@ void ClientParams::setLEDState(unsigned int state)
ledState_ = state;
}

rdr::U32 ClientParams::clipboardSize(unsigned int format) const
{
int i;

for (i = 0;i < 16;i++) {
if (((unsigned)1 << i) == format)
return clipSizes[i];
}

throw Exception("Invalid clipboard format 0x%x", format);
}

void ClientParams::setClipboardCaps(rdr::U32 flags, const rdr::U32* lengths)
{
int i, num;
Expand Down
1 change: 1 addition & 0 deletions common/rfb/ClientParams.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ namespace rfb {
void setLEDState(unsigned int state);

rdr::U32 clipboardFlags() const { return clipFlags; }
rdr::U32 clipboardSize(unsigned int format) const;
void setClipboardCaps(rdr::U32 flags, const rdr::U32* lengths);

// Wrappers to check for functionality rather than specific
Expand Down
62 changes: 48 additions & 14 deletions common/rfb/SConnection.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ SConnection::SConnection()
is(0), os(0), reader_(0), writer_(0), ssecurity(0),
authFailureTimer(this, &SConnection::handleAuthFailureTimeout),
state_(RFBSTATE_UNINITIALISED), preferredEncoding(encodingRaw),
clientClipboard(NULL), hasLocalClipboard(false)
clientClipboard(NULL), hasLocalClipboard(false),
unsolicitedClipboardAttempt(false)
{
defaultMajorVersion = 3;
defaultMinorVersion = 8;
Expand Down Expand Up @@ -370,6 +371,8 @@ void SConnection::setEncodings(int nEncodings, const rdr::S32* encodings)

void SConnection::clientCutText(const char* str)
{
hasLocalClipboard = false;

strFree(clientClipboard);
clientClipboard = NULL;

Expand All @@ -380,44 +383,51 @@ void SConnection::clientCutText(const char* str)

void SConnection::handleClipboardRequest(rdr::U32 flags)
{
if (!(flags & rfb::clipboardUTF8))
if (!(flags & rfb::clipboardUTF8)) {
vlog.debug("Ignoring clipboard request for unsupported formats 0x%x", flags);
return;
if (!hasLocalClipboard)
}
if (!hasLocalClipboard) {
vlog.debug("Ignoring unexpected clipboard request");
return;
}
handleClipboardRequest();
}

void SConnection::handleClipboardPeek(rdr::U32 flags)
{
if (!hasLocalClipboard)
return;
if (client.clipboardFlags() & rfb::clipboardNotify)
writer()->writeClipboardNotify(rfb::clipboardUTF8);
writer()->writeClipboardNotify(hasLocalClipboard ? rfb::clipboardUTF8 : 0);
}

void SConnection::handleClipboardNotify(rdr::U32 flags)
{
strFree(clientClipboard);
clientClipboard = NULL;

if (flags & rfb::clipboardUTF8)
if (flags & rfb::clipboardUTF8) {
hasLocalClipboard = false;
handleClipboardAnnounce(true);
else
} else {
handleClipboardAnnounce(false);
}
}

void SConnection::handleClipboardProvide(rdr::U32 flags,
const size_t* lengths,
const rdr::U8* const* data)
{
if (!(flags & rfb::clipboardUTF8))
if (!(flags & rfb::clipboardUTF8)) {
vlog.debug("Ignoring clipboard provide with unsupported formats 0x%x", flags);
return;
}

strFree(clientClipboard);
clientClipboard = NULL;

clientClipboard = convertLF((const char*)data[0], lengths[0]);

// FIXME: Should probably verify that this data was actually requested
handleClipboardData(clientClipboard);
}

Expand Down Expand Up @@ -547,14 +557,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)
Expand All @@ -564,6 +587,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));
Expand Down
1 change: 1 addition & 0 deletions common/rfb/SConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ namespace rfb {

char* clientClipboard;
bool hasLocalClipboard;
bool unsolicitedClipboardAttempt;
};
}
#endif
44 changes: 44 additions & 0 deletions common/rfb/SMsgHandler.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@
* USA.
*/
#include <rfb/Exception.h>
#include <rfb/LogWriter.h>
#include <rfb/SMsgHandler.h>
#include <rfb/ScreenSet.h>
#include <rfb/clipboardTypes.h>
#include <rfb/encodings.h>

using namespace rfb;

static LogWriter vlog("SMsgHandler");

SMsgHandler::SMsgHandler()
{
}
Expand Down Expand Up @@ -66,6 +70,46 @@ void SMsgHandler::setEncodings(int nEncodings, const rdr::S32* encodings)

void SMsgHandler::handleClipboardCaps(rdr::U32 flags, const rdr::U32* lengths)
{
int i;

vlog.debug("Got client 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 {
char bytes[1024];

iecPrefix(lengths[i], "B", bytes, sizeof(bytes));
vlog.debug(" %s (automatically send up to %s)",
type, bytes);
}
}
}

client.setClipboardCaps(flags, lengths);
}

Expand Down
12 changes: 12 additions & 0 deletions common/rfb/ServerParams.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ void ServerParams::setLEDState(unsigned int state)
ledState_ = state;
}

rdr::U32 ServerParams::clipboardSize(unsigned int format) const
{
int i;

for (i = 0;i < 16;i++) {
if (((unsigned)1 << i) == format)
return clipSizes[i];
}

throw Exception("Invalid clipboard format 0x%x", format);
}

void ServerParams::setClipboardCaps(rdr::U32 flags, const rdr::U32* lengths)
{
int i, num;
Expand Down
Loading

0 comments on commit 35b4eed

Please sign in to comment.