Added win32 clipboard support for images and HTML. Still need X11
support.
This commit is contained in:
parent
9c35a45a2c
commit
d84e5a26be
|
@ -15,6 +15,8 @@
|
|||
#include "CMSWindowsClipboard.h"
|
||||
#include "CMSWindowsClipboardTextConverter.h"
|
||||
#include "CMSWindowsClipboardUTF16Converter.h"
|
||||
#include "CMSWindowsClipboardBitmapConverter.h"
|
||||
#include "CMSWindowsClipboardHTMLConverter.h"
|
||||
#include "CLog.h"
|
||||
#include "CArchMiscWindows.h"
|
||||
|
||||
|
@ -35,6 +37,8 @@ CMSWindowsClipboard::CMSWindowsClipboard(HWND window) :
|
|||
// let it do so to avoid text encoding issues.
|
||||
m_converters.push_back(new CMSWindowsClipboardTextConverter);
|
||||
}
|
||||
m_converters.push_back(new CMSWindowsClipboardBitmapConverter);
|
||||
m_converters.push_back(new CMSWindowsClipboardHTMLConverter);
|
||||
}
|
||||
|
||||
CMSWindowsClipboard::~CMSWindowsClipboard()
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* 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 "CMSWindowsClipboardBitmapConverter.h"
|
||||
#include "CLog.h"
|
||||
|
||||
//
|
||||
// CMSWindowsClipboardBitmapConverter
|
||||
//
|
||||
|
||||
CMSWindowsClipboardBitmapConverter::CMSWindowsClipboardBitmapConverter()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
CMSWindowsClipboardBitmapConverter::~CMSWindowsClipboardBitmapConverter()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
IClipboard::EFormat
|
||||
CMSWindowsClipboardBitmapConverter::getFormat() const
|
||||
{
|
||||
return IClipboard::kBitmap;
|
||||
}
|
||||
|
||||
UINT
|
||||
CMSWindowsClipboardBitmapConverter::getWin32Format() const
|
||||
{
|
||||
return CF_DIB;
|
||||
}
|
||||
|
||||
HANDLE
|
||||
CMSWindowsClipboardBitmapConverter::fromIClipboard(const CString& data) const
|
||||
{
|
||||
// copy to memory handle
|
||||
HGLOBAL gData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, data.size());
|
||||
if (gData != NULL) {
|
||||
// get a pointer to the allocated memory
|
||||
char* dst = (char*)GlobalLock(gData);
|
||||
if (dst != NULL) {
|
||||
memcpy(dst, data.data(), data.size());
|
||||
GlobalUnlock(gData);
|
||||
}
|
||||
else {
|
||||
GlobalFree(gData);
|
||||
gData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return gData;
|
||||
}
|
||||
|
||||
CString
|
||||
CMSWindowsClipboardBitmapConverter::toIClipboard(HANDLE data) const
|
||||
{
|
||||
// get datator
|
||||
const char* src = (const char*)GlobalLock(data);
|
||||
if (src == NULL) {
|
||||
return CString();
|
||||
}
|
||||
UInt32 srcSize = (UInt32)GlobalSize(data);
|
||||
|
||||
// check image type
|
||||
const BITMAPINFO* bitmap = reinterpret_cast<const BITMAPINFO*>(src);
|
||||
LOG((CLOG_INFO "bitmap: %dx%d %d", bitmap->bmiHeader.biWidth, bitmap->bmiHeader.biHeight, (int)bitmap->bmiHeader.biBitCount));
|
||||
if (bitmap->bmiHeader.biPlanes == 1 &&
|
||||
(bitmap->bmiHeader.biBitCount == 24 ||
|
||||
bitmap->bmiHeader.biBitCount == 32) &&
|
||||
bitmap->bmiHeader.biCompression == BI_RGB) {
|
||||
// already in canonical form
|
||||
CString image(src, srcSize);
|
||||
GlobalUnlock(data);
|
||||
return image;
|
||||
}
|
||||
|
||||
// create a destination DIB section
|
||||
LOG((CLOG_INFO "convert image from: depth=%d comp=%d", bitmap->bmiHeader.biBitCount, bitmap->bmiHeader.biCompression));
|
||||
void* raw;
|
||||
BITMAPINFOHEADER info;
|
||||
LONG w = bitmap->bmiHeader.biWidth;
|
||||
LONG h = bitmap->bmiHeader.biHeight;
|
||||
info.biSize = sizeof(BITMAPINFOHEADER);
|
||||
info.biWidth = w;
|
||||
info.biHeight = h;
|
||||
info.biPlanes = 1;
|
||||
info.biBitCount = 32;
|
||||
info.biCompression = BI_RGB;
|
||||
info.biSizeImage = 0;
|
||||
info.biXPelsPerMeter = 1000;
|
||||
info.biYPelsPerMeter = 1000;
|
||||
info.biClrUsed = 0;
|
||||
info.biClrImportant = 0;
|
||||
HDC dc = GetDC(NULL);
|
||||
HBITMAP dst = CreateDIBSection(dc, (BITMAPINFO*)&info,
|
||||
DIB_RGB_COLORS, &raw, NULL, 0);
|
||||
|
||||
// find the start of the pixel data
|
||||
const char* srcBits = (const char*)bitmap + bitmap->bmiHeader.biSize;
|
||||
if (bitmap->bmiHeader.biBitCount >= 16) {
|
||||
if (bitmap->bmiHeader.biCompression == BI_BITFIELDS &&
|
||||
(bitmap->bmiHeader.biBitCount == 16 ||
|
||||
bitmap->bmiHeader.biBitCount == 32)) {
|
||||
srcBits += 3 * sizeof(DWORD);
|
||||
}
|
||||
}
|
||||
else if (bitmap->bmiHeader.biClrUsed != 0) {
|
||||
srcBits += bitmap->bmiHeader.biClrUsed * sizeof(RGBQUAD);
|
||||
}
|
||||
else {
|
||||
srcBits += (1 << bitmap->bmiHeader.biBitCount) * sizeof(RGBQUAD);
|
||||
}
|
||||
|
||||
// copy source image to destination image
|
||||
HDC dstDC = CreateCompatibleDC(dc);
|
||||
HGDIOBJ oldBitmap = SelectObject(dstDC, dst);
|
||||
SetDIBitsToDevice(dstDC, 0, 0, w, h, 0, 0, 0, h,
|
||||
srcBits, bitmap, DIB_RGB_COLORS);
|
||||
SelectObject(dstDC, oldBitmap);
|
||||
DeleteDC(dstDC);
|
||||
GdiFlush();
|
||||
|
||||
// extract data
|
||||
CString image((const char*)&info, info.biSize);
|
||||
image.append((const char*)raw, 4 * w * h);
|
||||
|
||||
// clean up GDI
|
||||
DeleteObject(dst);
|
||||
ReleaseDC(NULL, dc);
|
||||
|
||||
// release handle
|
||||
GlobalUnlock(data);
|
||||
|
||||
return image;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef CMSWINDOWSCLIPBOARDBITMAPCONVERTER_H
|
||||
#define CMSWINDOWSCLIPBOARDBITMAPCONVERTER_H
|
||||
|
||||
#include "CMSWindowsClipboard.h"
|
||||
|
||||
//! Convert to/from some text encoding
|
||||
class CMSWindowsClipboardBitmapConverter :
|
||||
public IMSWindowsClipboardConverter {
|
||||
public:
|
||||
CMSWindowsClipboardBitmapConverter();
|
||||
virtual ~CMSWindowsClipboardBitmapConverter();
|
||||
|
||||
// IMSWindowsClipboardConverter overrides
|
||||
virtual IClipboard::EFormat
|
||||
getFormat() const;
|
||||
virtual UINT getWin32Format() const;
|
||||
virtual HANDLE fromIClipboard(const CString&) const;
|
||||
virtual CString toIClipboard(HANDLE) const;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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 "CMSWindowsClipboardHTMLConverter.h"
|
||||
#include "CStringUtil.h"
|
||||
|
||||
//
|
||||
// CMSWindowsClipboardHTMLConverter
|
||||
//
|
||||
|
||||
CMSWindowsClipboardHTMLConverter::CMSWindowsClipboardHTMLConverter()
|
||||
{
|
||||
m_format = RegisterClipboardFormat("HTML Format");
|
||||
}
|
||||
|
||||
CMSWindowsClipboardHTMLConverter::~CMSWindowsClipboardHTMLConverter()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
IClipboard::EFormat
|
||||
CMSWindowsClipboardHTMLConverter::getFormat() const
|
||||
{
|
||||
return IClipboard::kHTML;
|
||||
}
|
||||
|
||||
UINT
|
||||
CMSWindowsClipboardHTMLConverter::getWin32Format() const
|
||||
{
|
||||
return m_format;
|
||||
}
|
||||
|
||||
CString
|
||||
CMSWindowsClipboardHTMLConverter::doFromIClipboard(const CString& data) const
|
||||
{
|
||||
// prepare to CF_HTML format prefix and suffix
|
||||
CString prefix("Version:0.9\nStartHTML:-1\nEndHTML:-1\n"
|
||||
"StartFragment:XXXXXXXXXX\nEndFragment:YYYYYYYYYY\n"
|
||||
"<!DOCTYPE><HTML><BODY><!--StartFragment-->");
|
||||
CString suffix("<!--EndFragment--></BODY></HTML>\n");
|
||||
UInt32 start = prefix.size();
|
||||
UInt32 end = start + data.size();
|
||||
prefix.replace(prefix.find("XXXXXXXXXX"), 10,
|
||||
CStringUtil::print("%010u", start));
|
||||
prefix.replace(prefix.find("YYYYYYYYYY"), 10,
|
||||
CStringUtil::print("%010u", end));
|
||||
|
||||
// concatenate
|
||||
prefix += data;
|
||||
prefix += suffix;
|
||||
return prefix;
|
||||
}
|
||||
|
||||
CString
|
||||
CMSWindowsClipboardHTMLConverter::doToIClipboard(const CString& data) const
|
||||
{
|
||||
// get fragment start/end args
|
||||
CString startArg = findArg(data, "StartFragment");
|
||||
CString endArg = findArg(data, "EndFragment");
|
||||
if (startArg.empty() || endArg.empty()) {
|
||||
return CString();
|
||||
}
|
||||
|
||||
// convert args to integers
|
||||
SInt32 start = (SInt32)atoi(startArg.c_str());
|
||||
SInt32 end = (SInt32)atoi(endArg.c_str());
|
||||
if (start <= 0 || end <= 0 || start >= end) {
|
||||
return CString();
|
||||
}
|
||||
|
||||
// extract the fragment
|
||||
return data.substr(start, end - start);
|
||||
}
|
||||
|
||||
CString
|
||||
CMSWindowsClipboardHTMLConverter::findArg(
|
||||
const CString& data, const CString& name) const
|
||||
{
|
||||
CString::size_type i = data.find(name);
|
||||
if (i == CString::npos) {
|
||||
return CString();
|
||||
}
|
||||
i = data.find_first_of(":\r\n", i);
|
||||
if (i == CString::npos || data[i] != ':') {
|
||||
return CString();
|
||||
}
|
||||
i = data.find_first_of("0123456789\r\n", i + 1);
|
||||
if (i == CString::npos || data[i] == '\r' || data[i] == '\n') {
|
||||
return CString();
|
||||
}
|
||||
CString::size_type j = data.find_first_not_of("0123456789", i);
|
||||
if (j == CString::npos) {
|
||||
j = data.size();
|
||||
}
|
||||
return data.substr(i, j - i);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef CMSWINDOWSCLIPBOARDHTMLCONVERTER_H
|
||||
#define CMSWINDOWSCLIPBOARDHTMLCONVERTER_H
|
||||
|
||||
#include "CMSWindowsClipboardAnyTextConverter.h"
|
||||
|
||||
//! Convert to/from HTML encoding
|
||||
class CMSWindowsClipboardHTMLConverter :
|
||||
public CMSWindowsClipboardAnyTextConverter {
|
||||
public:
|
||||
CMSWindowsClipboardHTMLConverter();
|
||||
virtual ~CMSWindowsClipboardHTMLConverter();
|
||||
|
||||
// IMSWindowsClipboardConverter overrides
|
||||
virtual IClipboard::EFormat
|
||||
getFormat() const;
|
||||
virtual UINT getWin32Format() const;
|
||||
|
||||
protected:
|
||||
// CMSWindowsClipboardAnyTextConverter overrides
|
||||
virtual CString doFromIClipboard(const CString&) const;
|
||||
virtual CString doToIClipboard(const CString&) const;
|
||||
|
||||
private:
|
||||
CString findArg(const CString& data, const CString& name) const;
|
||||
|
||||
private:
|
||||
UINT m_format;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -95,6 +95,14 @@ SOURCE=.\CMSWindowsClipboardAnyTextConverter.cpp
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CMSWindowsClipboardBitmapConverter.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CMSWindowsClipboardHTMLConverter.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CMSWindowsClipboardTextConverter.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -139,6 +147,14 @@ SOURCE=.\CMSWindowsClipboardAnyTextConverter.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CMSWindowsClipboardBitmapConverter.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CMSWindowsClipboardHTMLConverter.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CMSWindowsClipboardTextConverter.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -103,6 +103,10 @@ SOURCE=.\CClientProxy1_1.cpp
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CClientProxy1_2.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CClientProxyUnknown.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -139,6 +143,10 @@ SOURCE=.\CClientProxy1_1.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CClientProxy1_2.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CClientProxyUnknown.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -43,6 +43,8 @@ public:
|
|||
*/
|
||||
enum EFormat {
|
||||
kText, //!< Text format, UTF-8, newline is LF
|
||||
kBitmap, //!< Bitmap format, BMP 24/32bpp, BI_RGB/BI_BITFIELDS
|
||||
kHTML, //!< HTML format, HTML fragment, UTF-8, newline is LF
|
||||
kNumFormats //!< The number of clipboard formats
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue