/*
* synergy -- 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 .
*/
#include "platform/XWindowsClipboardBMPConverter.h"
// BMP file header structure
struct CBMPHeader {
public:
UInt16 type;
UInt32 size;
UInt16 reserved1;
UInt16 reserved2;
UInt32 offset;
};
// BMP is little-endian
static inline UInt32 fromLEU32(const UInt8 *data) {
return static_cast(data[0]) | (static_cast(data[1]) << 8) |
(static_cast(data[2]) << 16) |
(static_cast(data[3]) << 24);
}
static void toLE(UInt8 *&dst, char src) {
dst[0] = static_cast(src);
dst += 1;
}
static void toLE(UInt8 *&dst, UInt16 src) {
dst[0] = static_cast(src & 0xffu);
dst[1] = static_cast((src >> 8) & 0xffu);
dst += 2;
}
static void toLE(UInt8 *&dst, UInt32 src) {
dst[0] = static_cast(src & 0xffu);
dst[1] = static_cast((src >> 8) & 0xffu);
dst[2] = static_cast((src >> 16) & 0xffu);
dst[3] = static_cast((src >> 24) & 0xffu);
dst += 4;
}
//
// XWindowsClipboardBMPConverter
//
XWindowsClipboardBMPConverter::XWindowsClipboardBMPConverter(Display *display)
: m_atom(XInternAtom(display, "image/bmp", False)) {
// do nothing
}
XWindowsClipboardBMPConverter::~XWindowsClipboardBMPConverter() {
// do nothing
}
IClipboard::EFormat XWindowsClipboardBMPConverter::getFormat() const {
return IClipboard::kBitmap;
}
Atom XWindowsClipboardBMPConverter::getAtom() const { return m_atom; }
int XWindowsClipboardBMPConverter::getDataSize() const { return 8; }
String XWindowsClipboardBMPConverter::fromIClipboard(const String &bmp) const {
// create BMP image
UInt8 header[14];
UInt8 *dst = header;
toLE(dst, 'B');
toLE(dst, 'M');
toLE(dst, static_cast(14 + bmp.size()));
toLE(dst, static_cast(0));
toLE(dst, static_cast(0));
toLE(dst, static_cast(14 + 40));
return String(reinterpret_cast(header), 14) + bmp;
}
String XWindowsClipboardBMPConverter::toIClipboard(const String &bmp) const {
// make sure data is big enough for a BMP file
if (bmp.size() <= 14 + 40) {
return String();
}
// check BMP file header
const UInt8 *rawBMPHeader = reinterpret_cast(bmp.data());
if (rawBMPHeader[0] != 'B' || rawBMPHeader[1] != 'M') {
return String();
}
// get offset to image data
UInt32 offset = fromLEU32(rawBMPHeader + 10);
// construct BMP
if (offset == 14 + 40) {
return bmp.substr(14);
} else {
return bmp.substr(14, 40) + bmp.substr(offset, bmp.size() - offset);
}
}