Improved clipboard API
Change the internal clipboard API to use a request based model in
order to be prepared for more advanced clipboard transfers.
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
index 21af0da..a3655bc 100644
--- a/common/rfb/VNCServerST.cxx
+++ b/common/rfb/VNCServerST.cxx
@@ -1,5 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009-2018 Pierre Ossman for Cendio AB
+ * Copyright 2009-2019 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -77,8 +77,8 @@
VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
: blHosts(&blacklist), desktop(desktop_), desktopStarted(false),
blockCounter(0), pb(0), ledState(ledUnknown),
- name(strDup(name_)), pointerClient(0), comparer(0),
- cursor(new Cursor(0, 0, Point(), NULL)),
+ name(strDup(name_)), pointerClient(0), clipboardClient(0),
+ comparer(0), cursor(new Cursor(0, 0, Point(), NULL)),
renderedCursorInvalid(false),
keyRemapper(&KeyRemapper::defInstance),
idleTimer(this), disconnectTimer(this), connectTimer(this),
@@ -167,9 +167,12 @@
if ((*ci)->getSock() == sock) {
clients.remove(*ci);
- // - Release the cursor if this client owns it
+ // - Remove any references to it
if (pointerClient == *ci)
pointerClient = NULL;
+ if (clipboardClient == *ci)
+ clipboardClient = NULL;
+ clipboardRequestors.remove(*ci);
// Adjust the exit timers
connectTimer.stop();
@@ -331,6 +334,45 @@
}
}
+void VNCServerST::requestClipboard()
+{
+ if (clipboardClient == NULL)
+ return;
+
+ clipboardClient->requestClipboard();
+}
+
+void VNCServerST::announceClipboard(bool available)
+{
+ std::list<VNCSConnectionST*>::iterator ci, ci_next;
+
+ if (available)
+ clipboardClient = NULL;
+
+ clipboardRequestors.clear();
+
+ for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {
+ ci_next = ci; ci_next++;
+ (*ci)->announceClipboard(available);
+ }
+}
+
+void VNCServerST::sendClipboardData(const char* data)
+{
+ std::list<VNCSConnectionST*>::iterator ci, ci_next;
+
+ if (strchr(data, '\r') != NULL)
+ throw Exception("Invalid carriage return in clipboard data");
+
+ for (ci = clipboardRequestors.begin();
+ ci != clipboardRequestors.end(); ci = ci_next) {
+ ci_next = ci; ci_next++;
+ (*ci)->sendClipboardData(data);
+ }
+
+ clipboardRequestors.clear();
+}
+
void VNCServerST::bell()
{
std::list<VNCSConnectionST*>::iterator ci, ci_next;
@@ -340,17 +382,6 @@
}
}
-void VNCServerST::serverCutText(const char* str)
-{
- if (strchr(str, '\r') != NULL)
- throw Exception("Invalid carriage return in clipboard data");
- std::list<VNCSConnectionST*>::iterator ci, ci_next;
- for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {
- ci_next = ci; ci_next++;
- (*ci)->serverCutTextOrClose(str);
- }
-}
-
void VNCServerST::setName(const char* name_)
{
name.replaceBuf(strDup(name_));
@@ -461,9 +492,32 @@
desktop->pointerEvent(pos, buttonMask);
}
-void VNCServerST::clientCutText(const char* str)
+void VNCServerST::handleClipboardRequest(VNCSConnectionST* client)
{
- desktop->clientCutText(str);
+ clipboardRequestors.push_back(client);
+ if (clipboardRequestors.size() == 1)
+ desktop->handleClipboardRequest();
+}
+
+void VNCServerST::handleClipboardAnnounce(VNCSConnectionST* client,
+ bool available)
+{
+ if (available)
+ clipboardClient = client;
+ else {
+ if (client != clipboardClient)
+ return;
+ clipboardClient = NULL;
+ }
+ desktop->handleClipboardAnnounce(available);
+}
+
+void VNCServerST::handleClipboardData(VNCSConnectionST* client,
+ const char* data)
+{
+ if (client != clipboardClient)
+ return;
+ desktop->handleClipboardData(data);
}
unsigned int VNCServerST::setDesktopSize(VNCSConnectionST* requester,