summaryrefslogtreecommitdiffstats
path: root/src/lib/barrier/IClipboard.cpp
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2018-04-25 18:07:30 -0400
committerLibravatarUnit 193 <unit193@ubuntu.com>2018-04-25 18:07:30 -0400
commit9b1b081cfdb1c0fb6457278775e0823f8bc10f62 (patch)
treece8840148d8445055ba9e4f12263b2208f234c16 /src/lib/barrier/IClipboard.cpp
Import Upstream version 2.0.0+dfsgupstream/2.0.0+dfsg
Diffstat (limited to 'src/lib/barrier/IClipboard.cpp')
-rw-r--r--src/lib/barrier/IClipboard.cpp168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/lib/barrier/IClipboard.cpp b/src/lib/barrier/IClipboard.cpp
new file mode 100644
index 0000000..19b4b56
--- /dev/null
+++ b/src/lib/barrier/IClipboard.cpp
@@ -0,0 +1,168 @@
+/*
+ * barrier -- mouse and keyboard sharing utility
+ * Copyright (C) 2012-2016 Symless Ltd.
+ * Copyright (C) 2004 Chris Schoeneman
+ *
+ * This package is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * found in the file LICENSE that should have accompanied this file.
+ *
+ * This package is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "barrier/IClipboard.h"
+#include "common/stdvector.h"
+
+//
+// IClipboard
+//
+
+void
+IClipboard::unmarshall(IClipboard* clipboard, const String& data, Time time)
+{
+ assert(clipboard != NULL);
+
+ const char* index = data.data();
+
+ if (clipboard->open(time)) {
+ // clear existing data
+ clipboard->empty();
+
+ // read the number of formats
+ const UInt32 numFormats = readUInt32(index);
+ index += 4;
+
+ // read each format
+ for (UInt32 i = 0; i < numFormats; ++i) {
+ // get the format id
+ IClipboard::EFormat format =
+ static_cast<IClipboard::EFormat>(readUInt32(index));
+ index += 4;
+
+ // get the size of the format data
+ UInt32 size = readUInt32(index);
+ index += 4;
+
+ // save the data if it's a known format. if either the client
+ // or server supports more clipboard formats than the other
+ // then one of them will get a format >= kNumFormats here.
+ if (format <IClipboard::kNumFormats) {
+ clipboard->add(format, String(index, size));
+ }
+ index += size;
+ }
+
+ // done
+ clipboard->close();
+ }
+}
+
+String
+IClipboard::marshall(const IClipboard* clipboard)
+{
+ // return data format:
+ // 4 bytes => number of formats included
+ // 4 bytes => format enum
+ // 4 bytes => clipboard data size n
+ // n bytes => clipboard data
+ // back to the second 4 bytes if there is another format
+
+ assert(clipboard != NULL);
+
+ String data;
+
+ std::vector<String> formatData;
+ formatData.resize(IClipboard::kNumFormats);
+ // FIXME -- use current time
+ if (clipboard->open(0)) {
+
+ // compute size of marshalled data
+ UInt32 size = 4;
+ UInt32 numFormats = 0;
+ for (UInt32 format = 0; format != IClipboard::kNumFormats; ++format) {
+ if (clipboard->has(static_cast<IClipboard::EFormat>(format))) {
+ ++numFormats;
+ formatData[format] =
+ clipboard->get(static_cast<IClipboard::EFormat>(format));
+ size += 4 + 4 + (UInt32)formatData[format].size();
+ }
+ }
+
+ // allocate space
+ data.reserve(size);
+
+ // marshall the data
+ writeUInt32(&data, numFormats);
+ for (UInt32 format = 0; format != IClipboard::kNumFormats; ++format) {
+ if (clipboard->has(static_cast<IClipboard::EFormat>(format))) {
+ writeUInt32(&data, format);
+ writeUInt32(&data, (UInt32)formatData[format].size());
+ data += formatData[format];
+ }
+ }
+ clipboard->close();
+ }
+
+ return data;
+}
+
+bool
+IClipboard::copy(IClipboard* dst, const IClipboard* src)
+{
+ assert(dst != NULL);
+ assert(src != NULL);
+
+ return copy(dst, src, src->getTime());
+}
+
+bool
+IClipboard::copy(IClipboard* dst, const IClipboard* src, Time time)
+{
+ assert(dst != NULL);
+ assert(src != NULL);
+
+ bool success = false;
+ if (src->open(time)) {
+ if (dst->open(time)) {
+ if (dst->empty()) {
+ for (SInt32 format = 0;
+ format != IClipboard::kNumFormats; ++format) {
+ IClipboard::EFormat eFormat = (IClipboard::EFormat)format;
+ if (src->has(eFormat)) {
+ dst->add(eFormat, src->get(eFormat));
+ }
+ }
+ success = true;
+ }
+ dst->close();
+ }
+ src->close();
+ }
+
+ return success;
+}
+
+UInt32
+IClipboard::readUInt32(const char* buf)
+{
+ const unsigned char* ubuf = reinterpret_cast<const unsigned char*>(buf);
+ return (static_cast<UInt32>(ubuf[0]) << 24) |
+ (static_cast<UInt32>(ubuf[1]) << 16) |
+ (static_cast<UInt32>(ubuf[2]) << 8) |
+ static_cast<UInt32>(ubuf[3]);
+}
+
+void
+IClipboard::writeUInt32(String* buf, UInt32 v)
+{
+ *buf += static_cast<UInt8>((v >> 24) & 0xff);
+ *buf += static_cast<UInt8>((v >> 16) & 0xff);
+ *buf += static_cast<UInt8>((v >> 8) & 0xff);
+ *buf += static_cast<UInt8>( v & 0xff);
+}