/* * synergy -- mouse and keyboard sharing utility * 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. */ #include "CXWindowsClipboardBMPConverter.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; } // // CXWindowsClipboardBMPConverter // CXWindowsClipboardBMPConverter::CXWindowsClipboardBMPConverter( Display* display) : m_atom(XInternAtom(display, "image/bmp", False)) { // do nothing } CXWindowsClipboardBMPConverter::~CXWindowsClipboardBMPConverter() { // do nothing } IClipboard::EFormat CXWindowsClipboardBMPConverter::getFormat() const { return IClipboard::kBitmap; } Atom CXWindowsClipboardBMPConverter::getAtom() const { return m_atom; } int CXWindowsClipboardBMPConverter::getDataSize() const { return 8; } CString CXWindowsClipboardBMPConverter::fromIClipboard(const CString& 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 CString(reinterpret_cast(header), 14) + bmp; } CString CXWindowsClipboardBMPConverter::toIClipboard(const CString& bmp) const { // make sure data is big enough for a BMP file if (bmp.size() <= 14 + 40) { return CString(); } // check BMP file header const UInt8* rawBMPHeader = reinterpret_cast(bmp.data()); if (rawBMPHeader[0] != 'B' || rawBMPHeader[1] != 'M') { return CString(); } // 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); } }