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

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

Added missing freePMData method.

File size: 5.1 KB
Line 
1/*
2 * synergy -- mouse and keyboard sharing utility
3 * Copyright (C) 2004 Chris Schoeneman
4 * Copyright (C) 2006 Knut St. Osmundsen
5 *
6 * This package is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * found in the file COPYING that should have accompanied this file.
9 *
10 * This package is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include "CPMClipboardBitmapConverter.h"
17#include "CLog.h"
18
19//
20// CPMClipboardBitmapConverter
21//
22
23CPMClipboardBitmapConverter::CPMClipboardBitmapConverter()
24{
25 // do nothing
26}
27
28CPMClipboardBitmapConverter::~CPMClipboardBitmapConverter()
29{
30 // do nothing
31}
32
33IClipboard::EFormat
34CPMClipboardBitmapConverter::getFormat() const
35{
36 return IClipboard::kBitmap;
37}
38
39ULONG
40CPMClipboardBitmapConverter::getPMFormat() const
41{
42 return CF_BITMAP;
43}
44
45ULONG
46CPMClipboardBitmapConverter::getPMFormatInfo() const
47{
48 return CFI_HANDLE;
49}
50
51ULONG
52CPMClipboardBitmapConverter::fromIClipboard(const CString& data) const
53{
54 /*
55 * We're getting a windows DIB, create a PM bitmap from that.
56 */
57 /** @todo implement me */
58 return 0;
59}
60
61void
62CPMClipboardBitmapConverter::freePMData(ULONG ulPMData) const
63{
64 HBITMAP hbmp = (HBITMAP)ulPMData;
65 if (hbmp != NULLHANDLE) {
66 /** @todo implement me */
67 }
68}
69
70CString
71CPMClipboardBitmapConverter::toIClipboard(ULONG data) const
72{
73#if 1
74 /** @todo implement me */
75 return CString();
76#else
77 HBITMAP hbmp = (HBITMAP)data;
78
79 BITMAPINFOHEADER2 BmpHdr;
80
81 ULONG cbFix;
82 ULONG cx;
83 ULONG cy;
84 USHORT cPlanes;
85 USHORT cBitCount;
86 ULONG ulCompression;
87 ULONG cbImage;
88 ULONG cxResolution;
89 ULONG cyResolution;
90 ULONG cclrUsed;
91 ULONG cclrImportant;
92 USHORT usUnits;
93 USHORT usReserved;
94 USHORT usRecording;
95 USHORT usRendering;
96 ULONG cSize1;
97 ULONG cSize2;
98 ULONG ulColorEncoding;
99 ULONG ulIdentifier;
100
101 if (GpiQueryBitmapInfoHeader(hbmp, &BmpHdr)) {
102 LOG((CLOG_INFO "bitmap: %dx%d %d", bmpData.biWidth, bitmap->bmiHeader.biHeight, (int)bitmap->bmiHeader.biBitCount));
103 if ( BmpHdr.cPlanes == 1
104 && (BmpHdr.cBitsCount == 32 || BmpHdr.cBitsCount == 24 /*???*/)
105 && BmpHdr.ulCompression == ) {
106 // already in canonical form
107 char *abImage = new char[BmpHdr.cbImage];
108 /* fun stuff starts here. */
109 //if (GipQueryBitmapBits() {
110 }
111 CString image(abImage, srcSize);
112 delete abImage;
113 return image;
114 }
115
116 }
117 return CString();
118
119 // get datator
120 const char* src = (const char*)GlobalLock(data);
121 if (src == NULL) {
122 return CString();
123 }
124 UInt32 srcSize = (UInt32)GlobalSize(data);
125
126 // check image type
127 const BITMAPINFO* bitmap = reinterpret_cast<const BITMAPINFO*>(src);
128 LOG((CLOG_INFO "bitmap: %dx%d %d", bitmap->bmiHeader.biWidth, bitmap->bmiHeader.biHeight, (int)bitmap->bmiHeader.biBitCount));
129 if (bitmap->bmiHeader.biPlanes == 1 &&
130 (bitmap->bmiHeader.biBitCount == 24 ||
131 bitmap->bmiHeader.biBitCount == 32) &&
132 bitmap->bmiHeader.biCompression == BI_RGB) {
133 // already in canonical form
134 CString image(src, srcSize);
135 GlobalUnlock(data);
136 return image;
137 }
138
139 // create a destination DIB section
140 LOG((CLOG_INFO "convert image from: depth=%d comp=%d", bitmap->bmiHeader.biBitCount, bitmap->bmiHeader.biCompression));
141 void* raw;
142 BITMAPINFOHEADER info;
143 LONG w = bitmap->bmiHeader.biWidth;
144 LONG h = bitmap->bmiHeader.biHeight;
145 info.biSize = sizeof(BITMAPINFOHEADER);
146 info.biWidth = w;
147 info.biHeight = h;
148 info.biPlanes = 1;
149 info.biBitCount = 32;
150 info.biCompression = BI_RGB;
151 info.biSizeImage = 0;
152 info.biXPelsPerMeter = 1000;
153 info.biYPelsPerMeter = 1000;
154 info.biClrUsed = 0;
155 info.biClrImportant = 0;
156 HDC dc = GetDC(NULL);
157 HBITMAP dst = CreateDIBSection(dc, (BITMAPINFO*)&info,
158 DIB_RGB_COLORS, &raw, NULL, 0);
159
160 // find the start of the pixel data
161 const char* srcBits = (const char*)bitmap + bitmap->bmiHeader.biSize;
162 if (bitmap->bmiHeader.biBitCount >= 16) {
163 if (bitmap->bmiHeader.biCompression == BI_BITFIELDS &&
164 (bitmap->bmiHeader.biBitCount == 16 ||
165 bitmap->bmiHeader.biBitCount == 32)) {
166 srcBits += 3 * sizeof(ULONG);
167 }
168 }
169 else if (bitmap->bmiHeader.biClrUsed != 0) {
170 srcBits += bitmap->bmiHeader.biClrUsed * sizeof(RGBQUAD);
171 }
172 else {
173 srcBits += (1 << bitmap->bmiHeader.biBitCount) * sizeof(RGBQUAD);
174 }
175
176 // copy source image to destination image
177 HDC dstDC = CreateCompatibleDC(dc);
178 HGDIOBJ oldBitmap = SelectObject(dstDC, dst);
179 SetDIBitsToDevice(dstDC, 0, 0, w, h, 0, 0, 0, h,
180 srcBits, bitmap, DIB_RGB_COLORS);
181 SelectObject(dstDC, oldBitmap);
182 DeleteDC(dstDC);
183 GdiFlush();
184
185 // extract data
186 CString image((const char*)&info, info.biSize);
187 image.append((const char*)raw, 4 * w * h);
188
189 // clean up GDI
190 DeleteObject(dst);
191 ReleaseDC(NULL, dc);
192
193 // release handle
194 GlobalUnlock(data);
195
196 return image;
197#endif
198}
199
Note: See TracBrowser for help on using the repository browser.