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