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 |
|
---|
23 | CPMClipboardBitmapConverter::CPMClipboardBitmapConverter()
|
---|
24 | {
|
---|
25 | // do nothing
|
---|
26 | }
|
---|
27 |
|
---|
28 | CPMClipboardBitmapConverter::~CPMClipboardBitmapConverter()
|
---|
29 | {
|
---|
30 | // do nothing
|
---|
31 | }
|
---|
32 |
|
---|
33 | IClipboard::EFormat
|
---|
34 | CPMClipboardBitmapConverter::getFormat() const
|
---|
35 | {
|
---|
36 | return IClipboard::kBitmap;
|
---|
37 | }
|
---|
38 |
|
---|
39 | ULONG
|
---|
40 | CPMClipboardBitmapConverter::getPMFormat() const
|
---|
41 | {
|
---|
42 | return CF_BITMAP;
|
---|
43 | }
|
---|
44 |
|
---|
45 | ULONG
|
---|
46 | CPMClipboardBitmapConverter::getPMFormatInfo() const
|
---|
47 | {
|
---|
48 | return CFI_HANDLE;
|
---|
49 | }
|
---|
50 |
|
---|
51 | ULONG
|
---|
52 | CPMClipboardBitmapConverter::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 |
|
---|
61 | void
|
---|
62 | CPMClipboardBitmapConverter::freePMData(ULONG ulPMData) const
|
---|
63 | {
|
---|
64 | HBITMAP hbmp = (HBITMAP)ulPMData;
|
---|
65 | if (hbmp != NULLHANDLE) {
|
---|
66 | /** @todo implement me */
|
---|
67 | }
|
---|
68 | }
|
---|
69 |
|
---|
70 | CString
|
---|
71 | CPMClipboardBitmapConverter::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 |
|
---|