1*b1cdbd2cSJim Jagielski /*************************************************************************
2*b1cdbd2cSJim Jagielski
3*b1cdbd2cSJim Jagielski Copyright 2011 Yuri Dario <mc6530@mclink.it>
4*b1cdbd2cSJim Jagielski
5*b1cdbd2cSJim Jagielski Licensed under the Apache License, Version 2.0 (the "License");
6*b1cdbd2cSJim Jagielski you may not use this file except in compliance with the License.
7*b1cdbd2cSJim Jagielski You may obtain a copy of the License at
8*b1cdbd2cSJim Jagielski
9*b1cdbd2cSJim Jagielski http://www.apache.org/licenses/LICENSE-2.0
10*b1cdbd2cSJim Jagielski
11*b1cdbd2cSJim Jagielski Unless required by applicable law or agreed to in writing, software
12*b1cdbd2cSJim Jagielski distributed under the License is distributed on an "AS IS" BASIS,
13*b1cdbd2cSJim Jagielski WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*b1cdbd2cSJim Jagielski See the License for the specific language governing permissions and
15*b1cdbd2cSJim Jagielski limitations under the License.
16*b1cdbd2cSJim Jagielski
17*b1cdbd2cSJim Jagielski ************************************************************************/
18*b1cdbd2cSJim Jagielski
19*b1cdbd2cSJim Jagielski #define INCL_WIN
20*b1cdbd2cSJim Jagielski #include <svpm.h>
21*b1cdbd2cSJim Jagielski #include <string.h>
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski #ifndef _OS2CLIPBOARD_HXX_
24*b1cdbd2cSJim Jagielski #include "Os2Clipboard.hxx"
25*b1cdbd2cSJim Jagielski #endif
26*b1cdbd2cSJim Jagielski
27*b1cdbd2cSJim Jagielski // same typedefs from win32 sdk
28*b1cdbd2cSJim Jagielski typedef unsigned short WORD;
29*b1cdbd2cSJim Jagielski typedef unsigned long DWORD;
30*b1cdbd2cSJim Jagielski
31*b1cdbd2cSJim Jagielski #pragma pack(push, 1)
32*b1cdbd2cSJim Jagielski
33*b1cdbd2cSJim Jagielski typedef struct {
34*b1cdbd2cSJim Jagielski PM_BYTE rgbBlue;
35*b1cdbd2cSJim Jagielski PM_BYTE rgbGreen;
36*b1cdbd2cSJim Jagielski PM_BYTE rgbRed;
37*b1cdbd2cSJim Jagielski PM_BYTE rgbReserved;
38*b1cdbd2cSJim Jagielski } RGBQUAD, *LPRGBQUAD;
39*b1cdbd2cSJim Jagielski
40*b1cdbd2cSJim Jagielski typedef struct
41*b1cdbd2cSJim Jagielski {
42*b1cdbd2cSJim Jagielski WORD bfType;
43*b1cdbd2cSJim Jagielski DWORD bfSize;
44*b1cdbd2cSJim Jagielski WORD bfReserved1;
45*b1cdbd2cSJim Jagielski WORD bfReserved2;
46*b1cdbd2cSJim Jagielski DWORD bfOffBits;
47*b1cdbd2cSJim Jagielski } W32_BITMAPFILEHEADER, *PW32_BITMAPFILEHEADER;
48*b1cdbd2cSJim Jagielski
49*b1cdbd2cSJim Jagielski typedef struct
50*b1cdbd2cSJim Jagielski {
51*b1cdbd2cSJim Jagielski DWORD biSize;
52*b1cdbd2cSJim Jagielski LONG biWidth;
53*b1cdbd2cSJim Jagielski LONG biHeight;
54*b1cdbd2cSJim Jagielski WORD biPlanes;
55*b1cdbd2cSJim Jagielski WORD biBitCount;
56*b1cdbd2cSJim Jagielski DWORD biCompression;
57*b1cdbd2cSJim Jagielski DWORD biSizeImage;
58*b1cdbd2cSJim Jagielski LONG biXPelsPerMeter;
59*b1cdbd2cSJim Jagielski LONG biYPelsPerMeter;
60*b1cdbd2cSJim Jagielski DWORD biClrUsed;
61*b1cdbd2cSJim Jagielski DWORD biClrImportant;
62*b1cdbd2cSJim Jagielski } W32_BITMAPINFOHEADER, *PW32_BITMAPINFOHEADER;
63*b1cdbd2cSJim Jagielski
64*b1cdbd2cSJim Jagielski #pragma pack(pop)
65*b1cdbd2cSJim Jagielski
66*b1cdbd2cSJim Jagielski // store screen bitcount
67*b1cdbd2cSJim Jagielski LONG lBitCountScreen;
68*b1cdbd2cSJim Jagielski
69*b1cdbd2cSJim Jagielski /*
70*b1cdbd2cSJim Jagielski * Convert an OOo bitmap to an OS/2 bitmap handle
71*b1cdbd2cSJim Jagielski *
72*b1cdbd2cSJim Jagielski * An OOo bitmap is a BITMAPFILEHEADER structure followed by a Windows DIB
73*b1cdbd2cSJim Jagielski *
74*b1cdbd2cSJim Jagielski * OS/2 InfoHeader is a superset of Win32 InhoHeader, so we can just copy
75*b1cdbd2cSJim Jagielski * the win32 memory over the os2 memory and fix the cbFix field.
76*b1cdbd2cSJim Jagielski * colortable and bitmap data share the same format.
77*b1cdbd2cSJim Jagielski *
78*b1cdbd2cSJim Jagielski */
OOoBmpToOS2Handle(Any & aAnyB)79*b1cdbd2cSJim Jagielski HBITMAP OOoBmpToOS2Handle( Any &aAnyB)
80*b1cdbd2cSJim Jagielski {
81*b1cdbd2cSJim Jagielski // copy bitmap to clipboard
82*b1cdbd2cSJim Jagielski Sequence<sal_Int8> ByteStream;
83*b1cdbd2cSJim Jagielski aAnyB >>= ByteStream;
84*b1cdbd2cSJim Jagielski
85*b1cdbd2cSJim Jagielski // get w32 file header data
86*b1cdbd2cSJim Jagielski PW32_BITMAPFILEHEADER pbfh = (PW32_BITMAPFILEHEADER)ByteStream.getArray();
87*b1cdbd2cSJim Jagielski // get w32 info header
88*b1cdbd2cSJim Jagielski PW32_BITMAPINFOHEADER pbih = (PW32_BITMAPINFOHEADER) (pbfh+1);
89*b1cdbd2cSJim Jagielski
90*b1cdbd2cSJim Jagielski // create os2 infoheader2 (same fields of w32)
91*b1cdbd2cSJim Jagielski BITMAPINFOHEADER2 bih2;
92*b1cdbd2cSJim Jagielski memset( &bih2, 0, sizeof( bih2));
93*b1cdbd2cSJim Jagielski memcpy( &bih2, pbih, pbih->biSize);
94*b1cdbd2cSJim Jagielski bih2.cbFix = sizeof(bih2);
95*b1cdbd2cSJim Jagielski
96*b1cdbd2cSJim Jagielski // Determine size of color table
97*b1cdbd2cSJim Jagielski int iNumColors, numbits=bih2.cPlanes * bih2.cBitCount;
98*b1cdbd2cSJim Jagielski if (numbits != 24)
99*b1cdbd2cSJim Jagielski iNumColors = bih2.cclrUsed ? bih2.cclrUsed : 2<<numbits;
100*b1cdbd2cSJim Jagielski else
101*b1cdbd2cSJim Jagielski iNumColors = bih2.cclrUsed;
102*b1cdbd2cSJim Jagielski int iColorTableSize = iNumColors*sizeof(RGB2);
103*b1cdbd2cSJim Jagielski
104*b1cdbd2cSJim Jagielski // allocate bitmap info2 (header2+colortable)
105*b1cdbd2cSJim Jagielski PBITMAPINFO2 pbi2=(PBITMAPINFO2) malloc( sizeof(BITMAPINFOHEADER2)+iColorTableSize);
106*b1cdbd2cSJim Jagielski // setup header fields
107*b1cdbd2cSJim Jagielski memcpy( pbi2, &bih2, sizeof(BITMAPINFOHEADER2));
108*b1cdbd2cSJim Jagielski // copy color palette (follows pbih)
109*b1cdbd2cSJim Jagielski memcpy( &pbi2->argbColor[0], (pbih+1), iColorTableSize);
110*b1cdbd2cSJim Jagielski
111*b1cdbd2cSJim Jagielski // get bitmap data
112*b1cdbd2cSJim Jagielski PBYTE pbPelData = (PBYTE)ByteStream.getArray() + pbfh->bfOffBits;
113*b1cdbd2cSJim Jagielski HPS hps = WinGetPS(HWND_DESKTOP);
114*b1cdbd2cSJim Jagielski HBITMAP hbm = GpiCreateBitmap( hps, &bih2, CBM_INIT, pbPelData, pbi2);
115*b1cdbd2cSJim Jagielski debug_printf( "OOoBmpToOS2Handle hbm %x\n", hbm);
116*b1cdbd2cSJim Jagielski WinReleasePS(hps);
117*b1cdbd2cSJim Jagielski
118*b1cdbd2cSJim Jagielski // return handle
119*b1cdbd2cSJim Jagielski return hbm;
120*b1cdbd2cSJim Jagielski }
121*b1cdbd2cSJim Jagielski
122*b1cdbd2cSJim Jagielski /*
123*b1cdbd2cSJim Jagielski * Convert an OS/2 bitmap handle to OOo bitmap
124*b1cdbd2cSJim Jagielski *
125*b1cdbd2cSJim Jagielski * First we need to copy the bitmap to a PS, then we can get bitmap data.
126*b1cdbd2cSJim Jagielski *
127*b1cdbd2cSJim Jagielski */
OS2HandleToOOoBmp(HBITMAP hbm,Sequence<sal_Int8> * OOoDIBStream)128*b1cdbd2cSJim Jagielski int OS2HandleToOOoBmp( HBITMAP hbm, Sequence< sal_Int8 >* OOoDIBStream)
129*b1cdbd2cSJim Jagielski {
130*b1cdbd2cSJim Jagielski HAB hab = WinQueryAnchorBlock(HWND_DESKTOP);
131*b1cdbd2cSJim Jagielski HDC hdc;
132*b1cdbd2cSJim Jagielski SIZEL sizl;
133*b1cdbd2cSJim Jagielski HPS hps;
134*b1cdbd2cSJim Jagielski PM_BYTE* pbBuffer;
135*b1cdbd2cSJim Jagielski ULONG cbBuffer;
136*b1cdbd2cSJim Jagielski
137*b1cdbd2cSJim Jagielski struct {
138*b1cdbd2cSJim Jagielski BITMAPINFOHEADER2 bmp2;
139*b1cdbd2cSJim Jagielski RGB2 argb2Color[0x100];
140*b1cdbd2cSJim Jagielski } bm;
141*b1cdbd2cSJim Jagielski
142*b1cdbd2cSJim Jagielski if (!lBitCountScreen) {
143*b1cdbd2cSJim Jagielski HPS hps = WinGetPS(HWND_DESKTOP);
144*b1cdbd2cSJim Jagielski HDC hdc = GpiQueryDevice(hps);
145*b1cdbd2cSJim Jagielski DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1L, &lBitCountScreen);
146*b1cdbd2cSJim Jagielski WinReleasePS(hps);
147*b1cdbd2cSJim Jagielski }
148*b1cdbd2cSJim Jagielski
149*b1cdbd2cSJim Jagielski // STEP 1: get OS/2 bitmap data and header
150*b1cdbd2cSJim Jagielski // get bitmap header
151*b1cdbd2cSJim Jagielski memset(&(bm.bmp2), 0, sizeof(bm.bmp2));
152*b1cdbd2cSJim Jagielski bm.bmp2.cbFix = 16;
153*b1cdbd2cSJim Jagielski GpiQueryBitmapInfoHeader(hbm, &bm.bmp2);
154*b1cdbd2cSJim Jagielski
155*b1cdbd2cSJim Jagielski /* Data only actually stored in clipboard quality */
156*b1cdbd2cSJim Jagielski if ( lBitCountScreen < bm.bmp2.cBitCount )
157*b1cdbd2cSJim Jagielski bm.bmp2.cBitCount = lBitCountScreen;
158*b1cdbd2cSJim Jagielski
159*b1cdbd2cSJim Jagielski if ( bm.bmp2.cBitCount == 16 )
160*b1cdbd2cSJim Jagielski bm.bmp2.cBitCount = 24;
161*b1cdbd2cSJim Jagielski
162*b1cdbd2cSJim Jagielski if ( bm.bmp2.cPlanes != 1 ) {
163*b1cdbd2cSJim Jagielski return 0;
164*b1cdbd2cSJim Jagielski }
165*b1cdbd2cSJim Jagielski
166*b1cdbd2cSJim Jagielski if ( (hdc = DevOpenDC(hab, OD_MEMORY, "*", 0L, (PDEVOPENDATA) NULL, (HDC) NULL)) == (HDC) NULL ) {
167*b1cdbd2cSJim Jagielski return 0;
168*b1cdbd2cSJim Jagielski }
169*b1cdbd2cSJim Jagielski
170*b1cdbd2cSJim Jagielski sizl.cx = bm.bmp2.cx;
171*b1cdbd2cSJim Jagielski sizl.cy = bm.bmp2.cy;
172*b1cdbd2cSJim Jagielski if ( (hps = GpiCreatePS(hab, hdc, &sizl, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC)) == (HPS) NULL ) {
173*b1cdbd2cSJim Jagielski DevCloseDC(hdc);
174*b1cdbd2cSJim Jagielski return 0;
175*b1cdbd2cSJim Jagielski }
176*b1cdbd2cSJim Jagielski // copy bitmap to hps
177*b1cdbd2cSJim Jagielski GpiSetBitmap(hps, hbm);
178*b1cdbd2cSJim Jagielski
179*b1cdbd2cSJim Jagielski // buffer lengths
180*b1cdbd2cSJim Jagielski cbBuffer = (((bm.bmp2.cBitCount * bm.bmp2.cx) + 31) / 32) * 4 * bm.bmp2.cy * bm.bmp2.cPlanes;
181*b1cdbd2cSJim Jagielski pbBuffer = (PM_BYTE*) malloc( cbBuffer);
182*b1cdbd2cSJim Jagielski // now get bitmap data
183*b1cdbd2cSJim Jagielski GpiQueryBitmapBits(hps, 0L, (LONG) bm.bmp2.cy, pbBuffer, (BITMAPINFO2*)&bm);
184*b1cdbd2cSJim Jagielski // free OS/2 resources
185*b1cdbd2cSJim Jagielski GpiSetBitmap(hps, (HBITMAP) NULL);
186*b1cdbd2cSJim Jagielski GpiDestroyPS(hps);
187*b1cdbd2cSJim Jagielski DevCloseDC(hdc);
188*b1cdbd2cSJim Jagielski
189*b1cdbd2cSJim Jagielski // STEP 2: now convert to Win32 DIB
190*b1cdbd2cSJim Jagielski // Determine size of color table
191*b1cdbd2cSJim Jagielski int iNumColors, numbits=bm.bmp2.cPlanes * bm.bmp2.cBitCount;
192*b1cdbd2cSJim Jagielski if (numbits != 24)
193*b1cdbd2cSJim Jagielski iNumColors = bm.bmp2.cclrUsed ? bm.bmp2.cclrUsed : 2<<numbits;
194*b1cdbd2cSJim Jagielski else
195*b1cdbd2cSJim Jagielski iNumColors = bm.bmp2.cclrUsed;
196*b1cdbd2cSJim Jagielski int iColorTableSize = iNumColors*sizeof(RGBQUAD);
197*b1cdbd2cSJim Jagielski
198*b1cdbd2cSJim Jagielski // reallocate data stream object size
199*b1cdbd2cSJim Jagielski OOoDIBStream->realloc( sizeof( W32_BITMAPFILEHEADER )
200*b1cdbd2cSJim Jagielski + sizeof( W32_BITMAPINFOHEADER) + iColorTableSize + cbBuffer);
201*b1cdbd2cSJim Jagielski
202*b1cdbd2cSJim Jagielski // fill w32 file header data
203*b1cdbd2cSJim Jagielski PW32_BITMAPFILEHEADER pbfh = (PW32_BITMAPFILEHEADER) OOoDIBStream->getArray();
204*b1cdbd2cSJim Jagielski memset( pbfh, 0, sizeof( W32_BITMAPFILEHEADER));
205*b1cdbd2cSJim Jagielski pbfh->bfType = 'MB';
206*b1cdbd2cSJim Jagielski pbfh->bfSize = sizeof( W32_BITMAPFILEHEADER )
207*b1cdbd2cSJim Jagielski + sizeof( W32_BITMAPINFOHEADER) + iColorTableSize + cbBuffer;
208*b1cdbd2cSJim Jagielski pbfh->bfOffBits = sizeof( W32_BITMAPFILEHEADER) + sizeof( W32_BITMAPINFOHEADER) + iColorTableSize;
209*b1cdbd2cSJim Jagielski
210*b1cdbd2cSJim Jagielski // fill w32 info header
211*b1cdbd2cSJim Jagielski PW32_BITMAPINFOHEADER pbih = (PW32_BITMAPINFOHEADER) (pbfh+1);
212*b1cdbd2cSJim Jagielski // copy header fields (only win32 ones) and fix size
213*b1cdbd2cSJim Jagielski memcpy( pbih, &bm.bmp2, sizeof(W32_BITMAPINFOHEADER));
214*b1cdbd2cSJim Jagielski pbih->biSize = sizeof(W32_BITMAPINFOHEADER);
215*b1cdbd2cSJim Jagielski
216*b1cdbd2cSJim Jagielski // fill color palette (follows pbih)
217*b1cdbd2cSJim Jagielski memcpy( (pbih+1), &bm.argb2Color[0], iColorTableSize);
218*b1cdbd2cSJim Jagielski
219*b1cdbd2cSJim Jagielski // fill bitmap data
220*b1cdbd2cSJim Jagielski memcpy( (char*) pbfh + pbfh->bfOffBits, pbBuffer, cbBuffer);
221*b1cdbd2cSJim Jagielski
222*b1cdbd2cSJim Jagielski // done
223*b1cdbd2cSJim Jagielski free( pbBuffer);
224*b1cdbd2cSJim Jagielski return 1;
225*b1cdbd2cSJim Jagielski }
226*b1cdbd2cSJim Jagielski
227*b1cdbd2cSJim Jagielski #ifdef TESTBMP
228*b1cdbd2cSJim Jagielski
229*b1cdbd2cSJim Jagielski #include <io.h>
230*b1cdbd2cSJim Jagielski #include <fcntl.h>
231*b1cdbd2cSJim Jagielski #include <stdio.h>
232*b1cdbd2cSJim Jagielski
main(void)233*b1cdbd2cSJim Jagielski int main( void)
234*b1cdbd2cSJim Jagielski {
235*b1cdbd2cSJim Jagielski HAB hAB = WinQueryAnchorBlock( HWND_DESKTOP );
236*b1cdbd2cSJim Jagielski
237*b1cdbd2cSJim Jagielski // query clipboard data to get mimetype
238*b1cdbd2cSJim Jagielski if( WinOpenClipbrd( hAB ) )
239*b1cdbd2cSJim Jagielski {
240*b1cdbd2cSJim Jagielski ULONG handle = WinQueryClipbrdData( hAB, CF_BITMAP);
241*b1cdbd2cSJim Jagielski if (handle) {
242*b1cdbd2cSJim Jagielski Sequence< sal_Int8 > winDIBStream;
243*b1cdbd2cSJim Jagielski // convert to oustring and return it
244*b1cdbd2cSJim Jagielski if (OS2HandleToOOoBmp( handle, &winDIBStream) == 1) {
245*b1cdbd2cSJim Jagielski printf( "Conversion ok.\n");
246*b1cdbd2cSJim Jagielski int fd = open( "test.bmp", O_BINARY | O_CREAT | O_TRUNC | O_RDWR);
247*b1cdbd2cSJim Jagielski printf( "writing to fd %d\n", fd);
248*b1cdbd2cSJim Jagielski write( fd, winDIBStream.getArray(), winDIBStream.getLength());
249*b1cdbd2cSJim Jagielski close( fd);
250*b1cdbd2cSJim Jagielski } else
251*b1cdbd2cSJim Jagielski printf( "failed conversion.\n");
252*b1cdbd2cSJim Jagielski
253*b1cdbd2cSJim Jagielski }
254*b1cdbd2cSJim Jagielski WinCloseClipbrd( hAB);
255*b1cdbd2cSJim Jagielski }
256*b1cdbd2cSJim Jagielski return 0;
257*b1cdbd2cSJim Jagielski }
258*b1cdbd2cSJim Jagielski
259*b1cdbd2cSJim Jagielski #endif //TESTBMP
260*b1cdbd2cSJim Jagielski
261