1 /*************************************************************************
3 * $RCSfile: OS2Bitmap.cxx,v $
7 * last change: $Author: obo $ $Date: 2008-07-22 17:53:52 $
9 * This code is property of Serenity Systems Intl
10 * All rights reserverd.
12 ************************************************************************/
17 #ifndef _OS2CLIPBOARD_HXX_
18 #include "Os2Clipboard.hxx"
21 // same typedefs from win32 sdk
22 typedef unsigned short WORD
;
23 typedef unsigned long DWORD
;
32 } RGBQUAD
, *LPRGBQUAD
;
41 } W32_BITMAPFILEHEADER
, *PW32_BITMAPFILEHEADER
;
56 } W32_BITMAPINFOHEADER
, *PW32_BITMAPINFOHEADER
;
60 // store screen bitcount
64 * Convert an OOo bitmap to an OS/2 bitmap handle
66 * An OOo bitmap is a BITMAPFILEHEADER structure followed by a Windows DIB
68 * OS/2 InfoHeader is a superset of Win32 InhoHeader, so we can just copy
69 * the win32 memory over the os2 memory and fix the cbFix field.
70 * colortable and bitmap data share the same format.
73 HBITMAP
OOoBmpToOS2Handle( Any
&aAnyB
)
75 // copy bitmap to clipboard
76 Sequence
<sal_Int8
> ByteStream
;
79 // get w32 file header data
80 PW32_BITMAPFILEHEADER pbfh
= (PW32_BITMAPFILEHEADER
)ByteStream
.getArray();
81 // get w32 info header
82 PW32_BITMAPINFOHEADER pbih
= (PW32_BITMAPINFOHEADER
) (pbfh
+1);
84 // create os2 infoheader2 (same fields of w32)
85 BITMAPINFOHEADER2 bih2
;
86 memset( &bih2
, 0, sizeof( bih2
));
87 memcpy( &bih2
, pbih
, pbih
->biSize
);
88 bih2
.cbFix
= sizeof(bih2
);
90 // Determine size of color table
91 int iNumColors
, numbits
=bih2
.cPlanes
* bih2
.cBitCount
;
93 iNumColors
= bih2
.cclrUsed
? bih2
.cclrUsed
: 2<<numbits
;
95 iNumColors
= bih2
.cclrUsed
;
96 int iColorTableSize
= iNumColors
*sizeof(RGB2
);
98 // allocate bitmap info2 (header2+colortable)
99 PBITMAPINFO2 pbi2
=(PBITMAPINFO2
) malloc( sizeof(BITMAPINFOHEADER2
)+iColorTableSize
);
100 // setup header fields
101 memcpy( pbi2
, &bih2
, sizeof(BITMAPINFOHEADER2
));
102 // copy color palette (follows pbih)
103 memcpy( &pbi2
->argbColor
[0], (pbih
+1), iColorTableSize
);
106 PBYTE pbPelData
= (PBYTE
)ByteStream
.getArray() + pbfh
->bfOffBits
;
107 HPS hps
= WinGetPS(HWND_DESKTOP
);
108 HBITMAP hbm
= GpiCreateBitmap( hps
, &bih2
, CBM_INIT
, pbPelData
, pbi2
);
109 debug_printf( "OOoBmpToOS2Handle hbm %x\n", hbm
);
117 * Convert an OS/2 bitmap handle to OOo bitmap
119 * First we need to copy the bitmap to a PS, then we can get bitmap data.
122 int OS2HandleToOOoBmp( HBITMAP hbm
, Sequence
< sal_Int8
>* OOoDIBStream
)
124 HAB hab
= WinQueryAnchorBlock(HWND_DESKTOP
);
132 BITMAPINFOHEADER2 bmp2
;
133 RGB2 argb2Color
[0x100];
136 if (!lBitCountScreen
) {
137 HPS hps
= WinGetPS(HWND_DESKTOP
);
138 HDC hdc
= GpiQueryDevice(hps
);
139 DevQueryCaps(hdc
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCountScreen
);
143 // STEP 1: get OS/2 bitmap data and header
145 memset(&(bm
.bmp2
), 0, sizeof(bm
.bmp2
));
147 GpiQueryBitmapInfoHeader(hbm
, &bm
.bmp2
);
149 /* Data only actually stored in clipboard quality */
150 if ( lBitCountScreen
< bm
.bmp2
.cBitCount
)
151 bm
.bmp2
.cBitCount
= lBitCountScreen
;
153 if ( bm
.bmp2
.cBitCount
== 16 )
154 bm
.bmp2
.cBitCount
= 24;
156 if ( bm
.bmp2
.cPlanes
!= 1 ) {
160 if ( (hdc
= DevOpenDC(hab
, OD_MEMORY
, "*", 0L, (PDEVOPENDATA
) NULL
, (HDC
) NULL
)) == (HDC
) NULL
) {
164 sizl
.cx
= bm
.bmp2
.cx
;
165 sizl
.cy
= bm
.bmp2
.cy
;
166 if ( (hps
= GpiCreatePS(hab
, hdc
, &sizl
, PU_PELS
| GPIF_DEFAULT
| GPIT_MICRO
| GPIA_ASSOC
)) == (HPS
) NULL
) {
170 // copy bitmap to hps
171 GpiSetBitmap(hps
, hbm
);
174 cbBuffer
= (((bm
.bmp2
.cBitCount
* bm
.bmp2
.cx
) + 31) / 32) * 4 * bm
.bmp2
.cy
* bm
.bmp2
.cPlanes
;
175 pbBuffer
= (PM_BYTE
*) malloc( cbBuffer
);
176 // now get bitmap data
177 GpiQueryBitmapBits(hps
, 0L, (LONG
) bm
.bmp2
.cy
, pbBuffer
, (BITMAPINFO2
*)&bm
);
178 // free OS/2 resources
179 GpiSetBitmap(hps
, (HBITMAP
) NULL
);
183 // STEP 2: now convert to Win32 DIB
184 // Determine size of color table
185 int iNumColors
, numbits
=bm
.bmp2
.cPlanes
* bm
.bmp2
.cBitCount
;
187 iNumColors
= bm
.bmp2
.cclrUsed
? bm
.bmp2
.cclrUsed
: 2<<numbits
;
189 iNumColors
= bm
.bmp2
.cclrUsed
;
190 int iColorTableSize
= iNumColors
*sizeof(RGBQUAD
);
192 // reallocate data stream object size
193 OOoDIBStream
->realloc( sizeof( W32_BITMAPFILEHEADER
)
194 + sizeof( W32_BITMAPINFOHEADER
) + iColorTableSize
+ cbBuffer
);
196 // fill w32 file header data
197 PW32_BITMAPFILEHEADER pbfh
= (PW32_BITMAPFILEHEADER
) OOoDIBStream
->getArray();
198 memset( pbfh
, 0, sizeof( W32_BITMAPFILEHEADER
));
200 pbfh
->bfSize
= sizeof( W32_BITMAPFILEHEADER
)
201 + sizeof( W32_BITMAPINFOHEADER
) + iColorTableSize
+ cbBuffer
;
202 pbfh
->bfOffBits
= sizeof( W32_BITMAPFILEHEADER
) + sizeof( W32_BITMAPINFOHEADER
) + iColorTableSize
;
204 // fill w32 info header
205 PW32_BITMAPINFOHEADER pbih
= (PW32_BITMAPINFOHEADER
) (pbfh
+1);
206 // copy header fields (only win32 ones) and fix size
207 memcpy( pbih
, &bm
.bmp2
, sizeof(W32_BITMAPINFOHEADER
));
208 pbih
->biSize
= sizeof(W32_BITMAPINFOHEADER
);
210 // fill color palette (follows pbih)
211 memcpy( (pbih
+1), &bm
.argb2Color
[0], iColorTableSize
);
214 memcpy( (char*) pbfh
+ pbfh
->bfOffBits
, pbBuffer
, cbBuffer
);
229 HAB hAB
= WinQueryAnchorBlock( HWND_DESKTOP
);
231 // query clipboard data to get mimetype
232 if( WinOpenClipbrd( hAB
) )
234 ULONG handle
= WinQueryClipbrdData( hAB
, CF_BITMAP
);
236 Sequence
< sal_Int8
> winDIBStream
;
237 // convert to oustring and return it
238 if (OS2HandleToOOoBmp( handle
, &winDIBStream
) == 1) {
239 printf( "Conversion ok.\n");
240 int fd
= open( "test.bmp", O_BINARY
| O_CREAT
| O_TRUNC
| O_RDWR
);
241 printf( "writing to fd %d\n", fd
);
242 write( fd
, winDIBStream
.getArray(), winDIBStream
.getLength());
245 printf( "failed conversion.\n");
248 WinCloseClipbrd( hAB
);