/* * synergy -- mouse and keyboard sharing utility * Copyright (C) 2012 Bolton Software 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 COPYING 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 . */ #include "synergy/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(); // clear existing data clipboard->open(time); 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(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 add(format, String(index, size)); } index += size; } // done clipboard->close(); } String IClipboard::marshall(const IClipboard* clipboard) { assert(clipboard != NULL); String data; std::vector formatData; formatData.resize(IClipboard::kNumFormats); // FIXME -- use current time 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(format))) { ++numFormats; formatData[format] = clipboard->get(static_cast(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(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(buf); return (static_cast(ubuf[0]) << 24) | (static_cast(ubuf[1]) << 16) | (static_cast(ubuf[2]) << 8) | static_cast(ubuf[3]); } void IClipboard::writeUInt32(String* buf, UInt32 v) { *buf += static_cast((v >> 24) & 0xff); *buf += static_cast((v >> 16) & 0xff); *buf += static_cast((v >> 8) & 0xff); *buf += static_cast( v & 0xff); }