Added win32 clipboard support for images and HTML. Still need X11

support.
This commit is contained in:
crs 2004-05-02 08:04:48 +00:00
parent 9c35a45a2c
commit d84e5a26be
8 changed files with 362 additions and 0 deletions

View File

@ -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()

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View 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

View 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
};