source: trunk/synergy/lib/platform/CMSWindowsClipboardBitmapConverter.cpp

Last change on this file was 2749, checked in by bird, 19 years ago

synergy v1.3.1 sources (zip).

File size: 3.9 KB
Line 
1/*
2 * synergy -- mouse and keyboard sharing utility
3 * Copyright (C) 2004 Chris Schoeneman
4 *
5 * This package is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * found in the file COPYING that should have accompanied this file.
8 *
9 * This package is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include "CMSWindowsClipboardBitmapConverter.h"
16#include "CLog.h"
17
18//
19// CMSWindowsClipboardBitmapConverter
20//
21
22CMSWindowsClipboardBitmapConverter::CMSWindowsClipboardBitmapConverter()
23{
24 // do nothing
25}
26
27CMSWindowsClipboardBitmapConverter::~CMSWindowsClipboardBitmapConverter()
28{
29 // do nothing
30}
31
32IClipboard::EFormat
33CMSWindowsClipboardBitmapConverter::getFormat() const
34{
35 return IClipboard::kBitmap;
36}
37
38UINT
39CMSWindowsClipboardBitmapConverter::getWin32Format() const
40{
41 return CF_DIB;
42}
43
44HANDLE
45CMSWindowsClipboardBitmapConverter::fromIClipboard(const CString& data) const
46{
47 // copy to memory handle
48 HGLOBAL gData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, data.size());
49 if (gData != NULL) {
50 // get a pointer to the allocated memory
51 char* dst = (char*)GlobalLock(gData);
52 if (dst != NULL) {
53 memcpy(dst, data.data(), data.size());
54 GlobalUnlock(gData);
55 }
56 else {
57 GlobalFree(gData);
58 gData = NULL;
59 }
60 }
61
62 return gData;
63}
64
65CString
66CMSWindowsClipboardBitmapConverter::toIClipboard(HANDLE data) const
67{
68 // get datator
69 const char* src = (const char*)GlobalLock(data);
70 if (src == NULL) {
71 return CString();
72 }
73 UInt32 srcSize = (UInt32)GlobalSize(data);
74
75 // check image type
76 const BITMAPINFO* bitmap = reinterpret_cast<const BITMAPINFO*>(src);
77 LOG((CLOG_INFO "bitmap: %dx%d %d", bitmap->bmiHeader.biWidth, bitmap->bmiHeader.biHeight, (int)bitmap->bmiHeader.biBitCount));
78 if (bitmap->bmiHeader.biPlanes == 1 &&
79 (bitmap->bmiHeader.biBitCount == 24 ||
80 bitmap->bmiHeader.biBitCount == 32) &&
81 bitmap->bmiHeader.biCompression == BI_RGB) {
82 // already in canonical form
83 CString image(src, srcSize);
84 GlobalUnlock(data);
85 return image;
86 }
87
88 // create a destination DIB section
89 LOG((CLOG_INFO "convert image from: depth=%d comp=%d", bitmap->bmiHeader.biBitCount, bitmap->bmiHeader.biCompression));
90 void* raw;
91 BITMAPINFOHEADER info;
92 LONG w = bitmap->bmiHeader.biWidth;
93 LONG h = bitmap->bmiHeader.biHeight;
94 info.biSize = sizeof(BITMAPINFOHEADER);
95 info.biWidth = w;
96 info.biHeight = h;
97 info.biPlanes = 1;
98 info.biBitCount = 32;
99 info.biCompression = BI_RGB;
100 info.biSizeImage = 0;
101 info.biXPelsPerMeter = 1000;
102 info.biYPelsPerMeter = 1000;
103 info.biClrUsed = 0;
104 info.biClrImportant = 0;
105 HDC dc = GetDC(NULL);
106 HBITMAP dst = CreateDIBSection(dc, (BITMAPINFO*)&info,
107 DIB_RGB_COLORS, &raw, NULL, 0);
108
109 // find the start of the pixel data
110 const char* srcBits = (const char*)bitmap + bitmap->bmiHeader.biSize;
111 if (bitmap->bmiHeader.biBitCount >= 16) {
112 if (bitmap->bmiHeader.biCompression == BI_BITFIELDS &&
113 (bitmap->bmiHeader.biBitCount == 16 ||
114 bitmap->bmiHeader.biBitCount == 32)) {
115 srcBits += 3 * sizeof(DWORD);
116 }
117 }
118 else if (bitmap->bmiHeader.biClrUsed != 0) {
119 srcBits += bitmap->bmiHeader.biClrUsed * sizeof(RGBQUAD);
120 }
121 else {
122 srcBits += (1 << bitmap->bmiHeader.biBitCount) * sizeof(RGBQUAD);
123 }
124
125 // copy source image to destination image
126 HDC dstDC = CreateCompatibleDC(dc);
127 HGDIOBJ oldBitmap = SelectObject(dstDC, dst);
128 SetDIBitsToDevice(dstDC, 0, 0, w, h, 0, 0, 0, h,
129 srcBits, bitmap, DIB_RGB_COLORS);
130 SelectObject(dstDC, oldBitmap);
131 DeleteDC(dstDC);
132 GdiFlush();
133
134 // extract data
135 CString image((const char*)&info, info.biSize);
136 image.append((const char*)raw, 4 * w * h);
137
138 // clean up GDI
139 DeleteObject(dst);
140 ReleaseDC(NULL, dc);
141
142 // release handle
143 GlobalUnlock(data);
144
145 return image;
146}
Note: See TracBrowser for help on using the repository browser.