From 935ca0b2f29c588426cffbfc40f33873798c71aa Mon Sep 17 00:00:00 2001 From: jerry Date: Tue, 13 May 2014 12:31:05 +0000 Subject: [PATCH] Added support for copying images (BMP) and HTML to/from the OS X clipboard - patch by Ryan Chapman --- src/lib/platform/OSXClipboard.cpp | 15 ++ .../OSXClipboardAnyBitmapConverter.cpp | 48 +++++++ .../platform/OSXClipboardAnyBitmapConverter.h | 48 +++++++ src/lib/platform/OSXClipboardBMPConverter.cpp | 134 ++++++++++++++++++ src/lib/platform/OSXClipboardBMPConverter.h | 44 ++++++ .../platform/OSXClipboardHTMLConverter.cpp | 95 +++++++++++++ src/lib/platform/OSXClipboardHTMLConverter.h | 44 ++++++ 7 files changed, 428 insertions(+) create mode 100644 src/lib/platform/OSXClipboardAnyBitmapConverter.cpp create mode 100644 src/lib/platform/OSXClipboardAnyBitmapConverter.h create mode 100644 src/lib/platform/OSXClipboardBMPConverter.cpp create mode 100644 src/lib/platform/OSXClipboardBMPConverter.h create mode 100644 src/lib/platform/OSXClipboardHTMLConverter.cpp create mode 100644 src/lib/platform/OSXClipboardHTMLConverter.h diff --git a/src/lib/platform/OSXClipboard.cpp b/src/lib/platform/OSXClipboard.cpp index b36c4fc0..025f5754 100644 --- a/src/lib/platform/OSXClipboard.cpp +++ b/src/lib/platform/OSXClipboard.cpp @@ -21,6 +21,8 @@ #include "synergy/Clipboard.h" #include "platform/OSXClipboardUTF16Converter.h" #include "platform/OSXClipboardTextConverter.h" +#include "platform/OSXClipboardBMPConverter.h" +#include "platform/OSXClipboardHTMLConverter.h" #include "base/Log.h" #include "arch/XArch.h" @@ -32,9 +34,13 @@ COSXClipboard::COSXClipboard() : m_time(0), m_pboard(NULL) { + m_converters.push_back(new COSXClipboardHTMLConverter); + m_converters.push_back(new COSXClipboardBMPConverter); m_converters.push_back(new COSXClipboardUTF16Converter); m_converters.push_back(new COSXClipboardTextConverter); + + OSStatus createErr = PasteboardCreate(kPasteboardClipboard, &m_pboard); if (createErr != noErr) { LOG((CLOG_DEBUG "failed to create clipboard reference: error %i", createErr)); @@ -94,6 +100,15 @@ COSXClipboard::add(EFormat format, const CString & data) return; LOG((CLOG_DEBUG "add %d bytes to clipboard format: %d", data.size(), format)); + if(format == IClipboard::kText) { + LOG((CLOG_DEBUG " format of data to be added to clipboard was kText")); + } + else if(format == IClipboard::kBitmap) { + LOG((CLOG_DEBUG " format of data to be added to clipboard was kBitmap")); + } + else if(format == IClipboard::kHTML) { + LOG((CLOG_DEBUG " format of data to be added to clipboard was kHTML")); + } for (ConverterList::const_iterator index = m_converters.begin(); index != m_converters.end(); ++index) { diff --git a/src/lib/platform/OSXClipboardAnyBitmapConverter.cpp b/src/lib/platform/OSXClipboardAnyBitmapConverter.cpp new file mode 100644 index 00000000..a41982ea --- /dev/null +++ b/src/lib/platform/OSXClipboardAnyBitmapConverter.cpp @@ -0,0 +1,48 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2014 Bolton Software Ltd. + * Patch by Ryan Chapman + * + * 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 "platform/OSXClipboardAnyBitmapConverter.h" +#include + +COSXClipboardAnyBitmapConverter::COSXClipboardAnyBitmapConverter() +{ + // do nothing +} + +COSXClipboardAnyBitmapConverter::~COSXClipboardAnyBitmapConverter() +{ + // do nothing +} + +IClipboard::EFormat +COSXClipboardAnyBitmapConverter::getFormat() const +{ + return IClipboard::kBitmap; +} + +CString +COSXClipboardAnyBitmapConverter::fromIClipboard(const CString& data) const +{ + return doFromIClipboard(data); +} + +CString +COSXClipboardAnyBitmapConverter::toIClipboard(const CString& data) const +{ + return doToIClipboard(data); +} diff --git a/src/lib/platform/OSXClipboardAnyBitmapConverter.h b/src/lib/platform/OSXClipboardAnyBitmapConverter.h new file mode 100644 index 00000000..eb4a51bc --- /dev/null +++ b/src/lib/platform/OSXClipboardAnyBitmapConverter.h @@ -0,0 +1,48 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2014 Bolton Software Ltd. + * Patch by Ryan Chapman + * + * 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 . + */ + +#pragma once + +#include "platform/OSXClipboard.h" + +//! Convert to/from some text encoding +class COSXClipboardAnyBitmapConverter : public IOSXClipboardConverter { +public: + COSXClipboardAnyBitmapConverter(); + virtual ~COSXClipboardAnyBitmapConverter(); + + // IOSXClipboardConverter overrides + virtual IClipboard::EFormat + getFormat() const; + virtual CFStringRef getOSXFormat() const = 0; + virtual CString fromIClipboard(const CString &) const; + virtual CString toIClipboard(const CString &) const; + +protected: + //! Convert from IClipboard format + /*! + Do UTF-8 conversion and linefeed conversion. + */ + virtual CString doFromIClipboard(const CString&) const = 0; + + //! Convert to IClipboard format + /*! + Do UTF-8 conversion and Linefeed conversion. + */ + virtual CString doToIClipboard(const CString&) const = 0; +}; diff --git a/src/lib/platform/OSXClipboardBMPConverter.cpp b/src/lib/platform/OSXClipboardBMPConverter.cpp new file mode 100644 index 00000000..4190e6a0 --- /dev/null +++ b/src/lib/platform/OSXClipboardBMPConverter.cpp @@ -0,0 +1,134 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2014 Bolton Software Ltd. + * Patch by Ryan Chapman + * + * 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 "platform/OSXClipboardBMPConverter.h" +#include "base/Log.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; +} + +COSXClipboardBMPConverter::COSXClipboardBMPConverter() +{ + // do nothing +} + +COSXClipboardBMPConverter::~COSXClipboardBMPConverter() +{ + // do nothing +} + +IClipboard::EFormat +COSXClipboardBMPConverter::getFormat() const +{ + return IClipboard::kBitmap; +} + +CFStringRef +COSXClipboardBMPConverter::getOSXFormat() const +{ + // TODO: does this only work with Windows? + return CFSTR("com.microsoft.bmp"); +} + +CString +COSXClipboardBMPConverter::fromIClipboard(const CString& bmp) const +{ + LOG((CLOG_DEBUG1 "ENTER COSXClipboardBMPConverter::doFromIClipboard()")); + // 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 +COSXClipboardBMPConverter::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); + } +} diff --git a/src/lib/platform/OSXClipboardBMPConverter.h b/src/lib/platform/OSXClipboardBMPConverter.h new file mode 100644 index 00000000..af505b79 --- /dev/null +++ b/src/lib/platform/OSXClipboardBMPConverter.h @@ -0,0 +1,44 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2014 Bolton Software Ltd. + * Patch by Ryan Chapman + * + * 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 . + */ + +#pragma once + +#include "platform/OSXClipboard.h" + +//! Convert to/from some text encoding +class COSXClipboardBMPConverter : public IOSXClipboardConverter { +public: + COSXClipboardBMPConverter(); + virtual ~COSXClipboardBMPConverter(); + + // IMSWindowsClipboardConverter overrides + virtual IClipboard::EFormat + getFormat() const; + + virtual CFStringRef + getOSXFormat() const; + + // COSXClipboardAnyBMPConverter overrides + virtual CString fromIClipboard(const CString&) const; + virtual CString toIClipboard(const CString&) const; + + // generic encoding converter + static CString convertString(const CString& data, + CFStringEncoding fromEncoding, + CFStringEncoding toEncoding); +}; diff --git a/src/lib/platform/OSXClipboardHTMLConverter.cpp b/src/lib/platform/OSXClipboardHTMLConverter.cpp new file mode 100644 index 00000000..b2e60e00 --- /dev/null +++ b/src/lib/platform/OSXClipboardHTMLConverter.cpp @@ -0,0 +1,95 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2014 Bolton Software Ltd. + * Patch by Ryan Chapman + * + * 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 "platform/OSXClipboardHTMLConverter.h" + +#include "base/Unicode.h" + +COSXClipboardHTMLConverter::COSXClipboardHTMLConverter() +{ + // do nothing +} + +COSXClipboardHTMLConverter::~COSXClipboardHTMLConverter() +{ + // do nothing +} + +IClipboard::EFormat +COSXClipboardHTMLConverter::getFormat() const +{ + return IClipboard::kHTML; +} + +CFStringRef +COSXClipboardHTMLConverter::getOSXFormat() const +{ + return CFSTR("public.html"); +} + +CString +COSXClipboardHTMLConverter::convertString( + const CString& data, + CFStringEncoding fromEncoding, + CFStringEncoding toEncoding) +{ + CFStringRef stringRef = CFStringCreateWithCString( + kCFAllocatorDefault, + data.c_str(), fromEncoding); + + if (stringRef == NULL) { + return CString(); + } + + CFIndex buffSize; + CFRange entireString = CFRangeMake(0, CFStringGetLength(stringRef)); + + CFStringGetBytes(stringRef, entireString, toEncoding, + 0, false, NULL, 0, &buffSize); + + char* buffer = new char[buffSize]; + + if (buffer == NULL) { + CFRelease(stringRef); + return CString(); + } + + CFStringGetBytes(stringRef, entireString, toEncoding, + 0, false, (UInt8*)buffer, buffSize, NULL); + + CString result(buffer, buffSize); + + delete[] buffer; + CFRelease(stringRef); + + return result; +} + +CString +COSXClipboardHTMLConverter::doFromIClipboard(const CString& data) const +{ + return convertString(data, kCFStringEncodingUTF8, + CFStringGetSystemEncoding()); +} + +CString +COSXClipboardHTMLConverter::doToIClipboard(const CString& data) const +{ + return convertString(data, CFStringGetSystemEncoding(), + kCFStringEncodingUTF8); +} diff --git a/src/lib/platform/OSXClipboardHTMLConverter.h b/src/lib/platform/OSXClipboardHTMLConverter.h new file mode 100644 index 00000000..a038ee6c --- /dev/null +++ b/src/lib/platform/OSXClipboardHTMLConverter.h @@ -0,0 +1,44 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2014 Bolton Software Ltd. + * Patch by Ryan Chapman + * + * 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 . + */ + +#pragma once + +#include "OSXClipboardAnyTextConverter.h" + +//! Convert to/from HTML encoding +class COSXClipboardHTMLConverter : public COSXClipboardAnyTextConverter { +public: + COSXClipboardHTMLConverter(); + virtual ~COSXClipboardHTMLConverter(); + + // IMSWindowsClipboardConverter overrides + virtual IClipboard::EFormat + getFormat() const; + + virtual CFStringRef getOSXFormat() const; + +protected: + // COSXClipboardAnyTextConverter overrides + virtual CString doFromIClipboard(const CString&) const; + virtual CString doToIClipboard(const CString&) const; + + // generic encoding converter + static CString convertString(const CString& data, + CFStringEncoding fromEncoding, + CFStringEncoding toEncoding); +};