diff options
Diffstat (limited to 'src/lib/barrier/IClipboard.cpp')
| -rw-r--r-- | src/lib/barrier/IClipboard.cpp | 168 |
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); +} |
