4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
11 /* A GDI bitmap object contains a handle to a packed BITMAP,
12 * which is stored on the global heap.
13 * A packed BITMAP is a BITMAP structure followed by the bitmap bits.
16 /* Handle of the bitmap selected by default in a memory DC */
17 HBITMAP BITMAP_hbitmapMemDC
;
19 /* List of supported depths */
20 static int depthCount
;
21 static int * depthList
;
23 /* List of GC used for bitmap to pixmap operations (one for each depth) */
27 /***********************************************************************
35 depthList
= XListDepths( XT_display
, DefaultScreen(XT_display
),
37 if (!depthList
|| !depthCount
) return FALSE
;
38 if (!(bitmapGC
= (GC
*) malloc( depthCount
* sizeof(GC
) ))) return FALSE
;
40 /* Create the necessary GCs */
42 for (i
= 0; i
< depthCount
; i
++)
44 tmpPixmap
= XCreatePixmap( XT_display
, DefaultRootWindow(XT_display
),
48 bitmapGC
[i
] = XCreateGC( XT_display
, tmpPixmap
, 0, NULL
);
49 XSetGraphicsExposures( XT_display
, bitmapGC
[i
], False
);
50 XFreePixmap( XT_display
, tmpPixmap
);
55 BITMAP_hbitmapMemDC
= CreateBitmap( 1, 1, 1, 1, NULL
);
56 return (BITMAP_hbitmapMemDC
!= 0);
60 /***********************************************************************
61 * BITMAP_FindGCForDepth
63 * Return a GC appropriate for operations with the given depth.
65 GC
BITMAP_FindGCForDepth( int depth
)
68 for (i
= 0; i
< depthCount
; i
++)
69 if (depthList
[i
] == depth
) return bitmapGC
[i
];
74 /***********************************************************************
77 * Create an XImage pointing to the bitmap data.
79 XImage
* BITMAP_BmpToImage( BITMAP
* bmp
, void * bmpData
)
83 image
= XCreateImage( XT_display
, DefaultVisualOfScreen(XT_screen
),
84 bmp
->bmBitsPixel
, ZPixmap
, 0, bmpData
,
85 bmp
->bmWidth
, bmp
->bmHeight
, 16, bmp
->bmWidthBytes
);
87 image
->byte_order
= MSBFirst
;
88 image
->bitmap_bit_order
= MSBFirst
;
89 image
->bitmap_unit
= 16;
90 _XInitImageFuncPtrs(image
);
95 /***********************************************************************
98 * Copy the content of the bitmap to the pixmap. Both must have the same depth.
100 BOOL
BITMAP_CopyToPixmap( BITMAP
* bmp
, Pixmap pixmap
,
101 int x
, int y
, int width
, int height
)
106 gc
= BITMAP_FindGCForDepth( bmp
->bmBitsPixel
);
107 if (!gc
) return FALSE
;
109 image
= BITMAP_BmpToImage( bmp
, ((char *)bmp
) + sizeof(BITMAP
) );
110 if (!image
) return FALSE
;
113 printf( "BITMAP_CopyToPixmap: %dx%d %d colors -> %d,%d %dx%d\n",
114 bmp
->bmWidth
, bmp
->bmHeight
, 1 << bmp
->bmBitsPixel
, x
, y
, width
, height
);
116 XPutImage(XT_display
, pixmap
, gc
, image
, 0, 0, x
, y
, width
, height
);
118 XDestroyImage( image
);
123 /***********************************************************************
124 * BITMAP_CopyFromPixmap
126 * Copy the content of the pixmap to the bitmap. Both must have
127 * the same dimensions and depth.
129 BOOL
BITMAP_CopyFromPixmap( BITMAP
* bmp
, Pixmap pixmap
)
131 XImage
*image
= BITMAP_BmpToImage( bmp
, ((char *)bmp
) + sizeof(BITMAP
) );
132 if (!image
) return FALSE
;
135 printf( "BITMAP_CopyFromPixmap: %dx%d %d colors\n",
136 bmp
->bmWidth
, bmp
->bmHeight
, 1 << bmp
->bmBitsPixel
);
138 XGetSubImage( XT_display
, pixmap
, 0, 0, bmp
->bmWidth
, bmp
->bmHeight
,
139 AllPlanes
, ZPixmap
, image
, 0, 0 );
141 XDestroyImage( image
);
146 /***********************************************************************
147 * CreateBitmap (GDI.48)
149 HBITMAP
CreateBitmap( short width
, short height
,
150 BYTE planes
, BYTE bpp
, LPSTR bits
)
152 BITMAP bitmap
= { 0, width
, height
, 0, planes
, bpp
, bits
};
154 printf( "CreateBitmap: %dx%d, %d colors\n",
155 width
, height
, 1 << (planes
*bpp
) );
157 if (!width
|| !height
) return 0;
158 if ((planes
!= 1) && (bpp
!= 1)) return 0;
159 bitmap
.bmWidthBytes
= (width
* bpp
+ 15) / 16 * 2;
160 return CreateBitmapIndirect( &bitmap
);
164 /***********************************************************************
165 * CreateCompatibleBitmap (GDI.51)
167 HBITMAP
CreateCompatibleBitmap( HDC hdc
, short width
, short height
)
172 printf( "CreateCompatibleBitmap: %d %dx%d\n", hdc
, width
, height
);
174 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
176 hbitmap
= CreateBitmap( width
, height
, dc
->w
.planes
, dc
->w
.bitsPerPixel
, NULL
);
181 /***********************************************************************
182 * CreateBitmapIndirect (GDI.49)
184 HBITMAP
CreateBitmapIndirect( BITMAP
* bmp
)
186 BITMAPOBJ
* bmpObjPtr
;
189 int size
= bmp
->bmPlanes
* bmp
->bmHeight
* bmp
->bmWidthBytes
;
191 /* Create the BITMAPOBJ */
193 hbitmap
= GDI_AllocObject( sizeof(BITMAPOBJ
), BITMAP_MAGIC
);
194 if (!hbitmap
) return 0;
195 bmpObjPtr
= (BITMAPOBJ
*) GDI_HEAP_ADDR( hbitmap
);
197 /* Create the bitmap in global heap */
199 bmpObjPtr
->hBitmap
= GlobalAlloc( GMEM_MOVEABLE
, sizeof(BITMAP
) + size
);
200 if (!bmpObjPtr
->hBitmap
)
202 GDI_FreeObject( hbitmap
);
205 bmpPtr
= (char *) GlobalLock( bmpObjPtr
->hBitmap
);
206 memcpy( bmpPtr
, bmp
, sizeof(BITMAP
) );
207 ((BITMAP
*)bmpPtr
)->bmBits
= NULL
;
208 if (bmp
->bmBits
) memcpy( bmpPtr
+ sizeof(BITMAP
), bmp
->bmBits
, size
);
209 GlobalUnlock( bmpObjPtr
->hBitmap
);
211 bmpObjPtr
->bSelected
= FALSE
;
213 bmpObjPtr
->size
.cx
= 0;
214 bmpObjPtr
->size
.cy
= 0;
219 /***********************************************************************
220 * BITMAP_GetSetBitmapBits
222 LONG
BITMAP_GetSetBitmapBits( HBITMAP hbitmap
, LONG count
,
223 LPSTR buffer
, int set
)
225 BITMAPOBJ
* bmpObjPtr
;
230 if (!count
) return 0;
231 bmpObjPtr
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
232 if (!bmpObjPtr
) return 0;
233 if (!(bmp
= (BITMAP
*) GlobalLock( bmpObjPtr
->hBitmap
))) return 0;
235 if (bmpObjPtr
->bSelected
)
236 dc
= (DC
*) GDI_GetObjPtr( bmpObjPtr
->hdc
, DC_MAGIC
);
238 maxSize
= bmp
->bmPlanes
* bmp
->bmHeight
* bmp
->bmWidthBytes
;
239 if (count
> maxSize
) count
= maxSize
;
243 memcpy( bmp
+1, buffer
, count
);
244 if (dc
) BITMAP_CopyToPixmap( bmp
, dc
->u
.x
.drawable
,
245 0, 0, bmp
->bmWidth
, bmp
->bmHeight
);
249 if (dc
) BITMAP_CopyFromPixmap( bmp
, dc
->u
.x
.drawable
);
250 memcpy( buffer
, bmp
+1, count
);
252 GlobalUnlock( bmpObjPtr
->hBitmap
);
257 /***********************************************************************
258 * GetBitmapBits (GDI.74)
260 LONG
GetBitmapBits( HBITMAP hbitmap
, LONG count
, LPSTR buffer
)
262 return BITMAP_GetSetBitmapBits( hbitmap
, count
, buffer
, 0 );
266 /***********************************************************************
267 * SetBitmapBits (GDI.106)
269 LONG
SetBitmapBits( HBITMAP hbitmap
, LONG count
, LPSTR buffer
)
271 return BITMAP_GetSetBitmapBits( hbitmap
, count
, buffer
, 1 );
275 /***********************************************************************
278 BOOL
BMP_DeleteObject( HBITMAP hbitmap
, BITMAPOBJ
* bitmap
)
280 /* Free bitmap on global heap */
281 GlobalFree( bitmap
->hBitmap
);
282 return GDI_FreeObject( hbitmap
);
286 /***********************************************************************
289 int BMP_GetObject( BITMAPOBJ
* bitmap
, int count
, LPSTR buffer
)
291 char * bmpPtr
= (char *) GlobalLock( bitmap
->hBitmap
);
292 if (count
> sizeof(BITMAP
)) count
= sizeof(BITMAP
);
293 memcpy( buffer
, bmpPtr
, count
);
294 GlobalUnlock( bitmap
->hBitmap
);
299 /***********************************************************************
300 * BITMAP_UnselectBitmap
302 * Unselect the bitmap from the DC. Used by SelectObject and DeleteDC.
304 BOOL
BITMAP_UnselectBitmap( DC
* dc
)
309 if (!dc
->w
.hBitmap
) return TRUE
;
310 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( dc
->w
.hBitmap
, BITMAP_MAGIC
);
311 if (!bmp
) return FALSE
;
313 if (!(bmpPtr
= (BITMAP
*) GlobalLock( bmp
->hBitmap
))) return FALSE
;
315 BITMAP_CopyFromPixmap( bmpPtr
, dc
->u
.x
.drawable
);
316 XFreePixmap( XT_display
, dc
->u
.x
.drawable
);
317 bmp
->bSelected
= FALSE
;
319 GlobalUnlock( bmp
->hBitmap
);
324 /***********************************************************************
325 * BITMAP_SelectObject
327 HBITMAP
BITMAP_SelectObject( HDC hdc
, DC
* dc
, HBITMAP hbitmap
,
331 HBITMAP prevHandle
= dc
->w
.hBitmap
;
333 if (!(dc
->w
.flags
& DC_MEMORY
)) return 0;
334 if (bitmap
->bSelected
&& hbitmap
!= BITMAP_hbitmapMemDC
) return 0;
335 if (!(bmp
= (BITMAP
*) GlobalLock( bitmap
->hBitmap
))) return 0;
337 /* Make sure the bitmap has the right format */
339 if ((bmp
->bmPlanes
!= 1) || !BITMAP_FindGCForDepth( bmp
->bmBitsPixel
))
341 GlobalUnlock( bitmap
->hBitmap
);
345 /* Unselect the previous bitmap */
347 if (!BITMAP_UnselectBitmap( dc
))
349 GlobalUnlock( bitmap
->hBitmap
);
353 /* Create the pixmap */
355 dc
->u
.x
.drawable
= XCreatePixmap( XT_display
,
356 DefaultRootWindow( XT_display
),
357 bmp
->bmWidth
, bmp
->bmHeight
,
359 dc
->w
.DCSizeX
= bmp
->bmWidth
;
360 dc
->w
.DCSizeY
= bmp
->bmHeight
;
361 BITMAP_CopyToPixmap( bmp
, dc
->u
.x
.drawable
,
362 0, 0, bmp
->bmWidth
, bmp
->bmHeight
);
364 /* Change GC depth if needed */
366 if (dc
->w
.bitsPerPixel
!= bmp
->bmBitsPixel
)
368 XFreeGC( XT_display
, dc
->u
.x
.gc
);
369 dc
->u
.x
.gc
= XCreateGC( XT_display
, dc
->u
.x
.drawable
, 0, NULL
);
370 dc
->w
.bitsPerPixel
= bmp
->bmBitsPixel
;
371 DC_SetDeviceInfo( hdc
, dc
);
374 GlobalUnlock( bitmap
->hBitmap
);
375 dc
->w
.hBitmap
= hbitmap
;
376 bitmap
->bSelected
= TRUE
;
382 /***********************************************************************
383 * GetBitmapDimensionEx (GDI.468)
385 BOOL
GetBitmapDimensionEx( HBITMAP hbitmap
, LPSIZE size
)
387 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
388 if (!bmp
) return FALSE
;
394 /***********************************************************************
395 * GetBitmapDimension (GDI.162)
397 DWORD
GetBitmapDimension( HBITMAP hbitmap
)
400 if (!GetBitmapDimensionEx( hbitmap
, &size
)) return 0;
401 return size
.cx
| (size
.cy
<< 16);
404 /***********************************************************************
405 * SetBitmapDimensionEx (GDI.478)
407 BOOL
SetBitmapDimensionEx( HBITMAP hbitmap
, short x
, short y
, LPSIZE prevSize
)
409 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
410 if (!bmp
) return FALSE
;
411 if (prevSize
) *prevSize
= bmp
->size
;
418 /***********************************************************************
419 * SetBitmapDimension (GDI.163)
421 DWORD
SetBitmapDimension( HBITMAP hbitmap
, short x
, short y
)
424 if (!SetBitmapDimensionEx( hbitmap
, x
, y
, &size
)) return 0;
425 return size
.cx
| (size
.cy
<< 16);