4 * Copyright 1993 Alexandre Julliard
15 /* #define DEBUG_GDI */
16 /* #define DEBUG_BITMAP */
19 /* GCs used for B&W and color bitmap operations */
20 GC BITMAP_monoGC
= 0, BITMAP_colorGC
= 0;
22 extern void CLIPPING_UpdateGCRegion( DC
* dc
); /* objects/clipping.c */
24 /***********************************************************************
27 BOOL
BITMAP_Init(void)
31 /* Create the necessary GCs */
33 if ((tmpPixmap
= XCreatePixmap( display
, rootWindow
, 1, 1, 1 )))
35 BITMAP_monoGC
= XCreateGC( display
, tmpPixmap
, 0, NULL
);
36 XSetGraphicsExposures( display
, BITMAP_monoGC
, False
);
37 XFreePixmap( display
, tmpPixmap
);
42 if ((tmpPixmap
= XCreatePixmap(display
, rootWindow
, 1,1,screenDepth
)))
44 BITMAP_colorGC
= XCreateGC( display
, tmpPixmap
, 0, NULL
);
45 XSetGraphicsExposures( display
, BITMAP_colorGC
, False
);
46 XFreePixmap( display
, tmpPixmap
);
53 /***********************************************************************
56 * Create an XImage pointing to the bitmap data.
58 static XImage
*BITMAP_BmpToImage( BITMAP
* bmp
, void * bmpData
)
60 extern void _XInitImageFuncPtrs( XImage
* );
63 image
= XCreateImage( display
, DefaultVisualOfScreen(screen
),
64 bmp
->bmBitsPixel
, ZPixmap
, 0, bmpData
,
65 bmp
->bmWidth
, bmp
->bmHeight
, 16, bmp
->bmWidthBytes
);
67 image
->byte_order
= MSBFirst
;
68 image
->bitmap_bit_order
= MSBFirst
;
69 image
->bitmap_unit
= 16;
70 _XInitImageFuncPtrs(image
);
75 /***********************************************************************
76 * CreateBitmap (GDI.48)
78 HBITMAP
CreateBitmap( INT width
, INT height
, UINT planes
, UINT bpp
, LPVOID bits
)
80 BITMAPOBJ
* bmpObjPtr
;
83 dprintf_gdi( stddeb
, "CreateBitmap: %dx%d, %d colors\n",
84 width
, height
, 1 << (planes
*bpp
) );
86 /* Check parameters */
87 if (!height
|| !width
|| planes
!= 1) return 0;
88 if ((bpp
!= 1) && (bpp
!= screenDepth
)) return 0;
89 if (height
< 0) height
= -height
;
90 if (width
< 0) width
= -width
;
92 /* Create the BITMAPOBJ */
93 hbitmap
= GDI_AllocObject( sizeof(BITMAPOBJ
), BITMAP_MAGIC
);
94 if (!hbitmap
) return 0;
95 bmpObjPtr
= (BITMAPOBJ
*) GDI_HEAP_LIN_ADDR( hbitmap
);
97 bmpObjPtr
->size
.cx
= 0;
98 bmpObjPtr
->size
.cy
= 0;
99 bmpObjPtr
->bitmap
.bmType
= 0;
100 bmpObjPtr
->bitmap
.bmWidth
= width
;
101 bmpObjPtr
->bitmap
.bmHeight
= height
;
102 bmpObjPtr
->bitmap
.bmPlanes
= planes
;
103 bmpObjPtr
->bitmap
.bmBitsPixel
= bpp
;
104 bmpObjPtr
->bitmap
.bmWidthBytes
= (width
* bpp
+ 15) / 16 * 2;
105 bmpObjPtr
->bitmap
.bmBits
= NULL
;
107 /* Create the pixmap */
108 bmpObjPtr
->pixmap
= XCreatePixmap(display
, rootWindow
, width
, height
, bpp
);
109 if (!bmpObjPtr
->pixmap
)
111 GDI_HEAP_FREE( hbitmap
);
114 else if (bits
) /* Set bitmap bits */
115 SetBitmapBits( hbitmap
, height
* bmpObjPtr
->bitmap
.bmWidthBytes
, bits
);
120 /***********************************************************************
121 * CreateCompatibleBitmap (GDI.51)
123 HBITMAP
CreateCompatibleBitmap( HDC hdc
, INT width
, INT height
)
126 dprintf_gdi(stddeb
, "CreateCompatibleBitmap: %04x %dx%d\n",
127 hdc
, width
, height
);
128 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
129 return CreateBitmap( width
, height
, 1, dc
->w
.bitsPerPixel
, NULL
);
133 /***********************************************************************
134 * CreateBitmapIndirect (GDI.49)
136 HBITMAP
CreateBitmapIndirect( const BITMAP
* bmp
)
138 return CreateBitmap( bmp
->bmWidth
, bmp
->bmHeight
, bmp
->bmPlanes
,
139 bmp
->bmBitsPixel
, PTR_SEG_TO_LIN( bmp
->bmBits
) );
143 /***********************************************************************
144 * GetBitmapBits (GDI.74)
146 LONG
GetBitmapBits( HBITMAP hbitmap
, LONG count
, LPSTR buffer
)
154 fprintf(stderr
, "Negative number of bytes (%ld) passed to GetBitmapBits???\n", count
);
157 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
160 /* Only get entire lines */
161 height
= count
/ bmp
->bitmap
.bmWidthBytes
;
162 if (height
> bmp
->bitmap
.bmHeight
) height
= bmp
->bitmap
.bmHeight
;
163 dprintf_bitmap(stddeb
, "GetBitmapBits: %dx%d %d colors %p fetched height: %ld\n",
164 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
165 1 << bmp
->bitmap
.bmBitsPixel
, buffer
, height
);
166 if (!height
) return 0;
168 if (!(image
= BITMAP_BmpToImage( &bmp
->bitmap
, buffer
))) return 0;
169 CallTo32_LargeStack( (int(*)())XGetSubImage
, 11,
170 display
, bmp
->pixmap
, 0, 0, bmp
->bitmap
.bmWidth
,
171 height
, AllPlanes
, ZPixmap
, image
, 0, 0 );
173 XDestroyImage( image
);
174 return height
* bmp
->bitmap
.bmWidthBytes
;
178 /***********************************************************************
179 * SetBitmapBits (GDI.106)
181 LONG
SetBitmapBits( HBITMAP hbitmap
, LONG count
, LPSTR buffer
)
189 fprintf(stderr
, "Negative number of bytes (%ld) passed to SetBitmapBits???\n", count
);
192 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
195 dprintf_bitmap(stddeb
, "SetBitmapBits: %dx%d %d colors %p\n",
196 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
197 1 << bmp
->bitmap
.bmBitsPixel
, buffer
);
199 /* Only set entire lines */
200 height
= count
/ bmp
->bitmap
.bmWidthBytes
;
201 if (height
> bmp
->bitmap
.bmHeight
) height
= bmp
->bitmap
.bmHeight
;
202 if (!height
) return 0;
204 if (!(image
= BITMAP_BmpToImage( &bmp
->bitmap
, buffer
))) return 0;
205 CallTo32_LargeStack( XPutImage
, 10,
206 display
, bmp
->pixmap
, BITMAP_GC(bmp
), image
, 0, 0,
207 0, 0, bmp
->bitmap
.bmWidth
, height
);
209 XDestroyImage( image
);
210 return height
* bmp
->bitmap
.bmWidthBytes
;
214 /**********************************************************************
215 * LoadBitmap (USER.175)
217 HBITMAP
LoadBitmap( HANDLE instance
, SEGPTR name
)
227 char *str
= (char *)PTR_SEG_TO_LIN( name
);
228 dprintf_bitmap( stddeb
, "LoadBitmap(%04x,'%s')\n", instance
, str
);
229 if (str
[0] == '#') name
= (SEGPTR
)(DWORD
)(WORD
)atoi( str
+ 1 );
232 dprintf_bitmap( stddeb
, "LoadBitmap(%04x,%04x)\n",
233 instance
, LOWORD(name
) );
235 if (!instance
) /* OEM bitmap */
237 if (HIWORD((int)name
)) return 0;
238 return OBM_LoadBitmap( LOWORD((int)name
) );
241 if (!(hRsrc
= FindResource( instance
, name
, RT_BITMAP
))) return 0;
242 if (!(handle
= LoadResource( instance
, hRsrc
))) return 0;
244 info
= (BITMAPINFO
*)LockResource( handle
);
245 if ((hdc
= GetDC(0)) != 0)
247 char *bits
= (char *)info
+ DIB_BitmapInfoSize( info
, DIB_RGB_COLORS
);
248 hbitmap
= CreateDIBitmap( hdc
, &info
->bmiHeader
, CBM_INIT
,
249 bits
, info
, DIB_RGB_COLORS
);
252 FreeResource( handle
);
257 /***********************************************************************
258 * BITMAP_DeleteObject
260 BOOL
BITMAP_DeleteObject( HBITMAP hbitmap
, BITMAPOBJ
* bitmap
)
262 XFreePixmap( display
, bitmap
->pixmap
);
263 return GDI_FreeObject( hbitmap
);
267 /***********************************************************************
270 int BITMAP_GetObject( BITMAPOBJ
* bmp
, int count
, LPSTR buffer
)
272 if (count
> sizeof(BITMAP
)) count
= sizeof(BITMAP
);
273 memcpy( buffer
, &bmp
->bitmap
, count
);
278 /***********************************************************************
279 * BITMAP_SelectObject
281 HBITMAP
BITMAP_SelectObject( HDC hdc
, DC
* dc
, HBITMAP hbitmap
,
285 HBITMAP prevHandle
= dc
->w
.hBitmap
;
287 if (!(dc
->w
.flags
& DC_MEMORY
)) return 0;
288 hrgn
= CreateRectRgn( 0, 0, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
291 DeleteObject( dc
->w
.hVisRgn
);
292 dc
->w
.hVisRgn
= hrgn
;
293 dc
->u
.x
.drawable
= bmp
->pixmap
;
294 dc
->w
.hBitmap
= hbitmap
;
296 /* Change GC depth if needed */
298 if (dc
->w
.bitsPerPixel
!= bmp
->bitmap
.bmBitsPixel
)
300 XFreeGC( display
, dc
->u
.x
.gc
);
301 dc
->u
.x
.gc
= XCreateGC( display
, dc
->u
.x
.drawable
, 0, NULL
);
302 dc
->w
.bitsPerPixel
= bmp
->bitmap
.bmBitsPixel
;
305 else CLIPPING_UpdateGCRegion( dc
); /* Just update GC clip region */
309 /***********************************************************************
310 * CreateDiscardableBitmap (GDI.156)
312 HBITMAP
CreateDiscardableBitmap(HDC hdc
, INT width
, INT height
)
314 dprintf_bitmap(stddeb
,"CreateDiscardableBitmap(%04x, %d, %d); "
315 "// call CreateCompatibleBitmap() for now!\n",
317 return CreateCompatibleBitmap(hdc
, width
, height
);
320 /***********************************************************************
321 * GetBitmapDimensionEx (GDI.468)
323 BOOL
GetBitmapDimensionEx( HBITMAP hbitmap
, LPSIZE size
)
325 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
326 if (!bmp
) return FALSE
;
332 /***********************************************************************
333 * GetBitmapDimension (GDI.162)
335 DWORD
GetBitmapDimension( HBITMAP hbitmap
)
338 if (!GetBitmapDimensionEx( hbitmap
, &size
)) return 0;
339 return size
.cx
| (size
.cy
<< 16);
342 /***********************************************************************
343 * SetBitmapDimensionEx (GDI.478)
345 BOOL
SetBitmapDimensionEx( HBITMAP hbitmap
, short x
, short y
, LPSIZE prevSize
)
347 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
348 if (!bmp
) return FALSE
;
349 if (prevSize
) *prevSize
= bmp
->size
;
356 /***********************************************************************
357 * SetBitmapDimension (GDI.163)
359 DWORD
SetBitmapDimension( HBITMAP hbitmap
, short x
, short y
)
362 if (!SetBitmapDimensionEx( hbitmap
, x
, y
, &size
)) return 0;
363 return size
.cx
| (size
.cy
<< 16);