4 * Copyright 1993 Alexandre Julliard
15 #include "resource.h" /* for ConvertCore/InfoBitmap */
17 /* #define DEBUG_GDI */
18 /* #define DEBUG_BITMAP */
21 /* GCs used for B&W and color bitmap operations */
22 GC BITMAP_monoGC
= 0, BITMAP_colorGC
= 0;
24 extern void CLIPPING_UpdateGCRegion( DC
* dc
); /* objects/clipping.c */
26 /***********************************************************************
29 BOOL
BITMAP_Init(void)
33 /* Create the necessary GCs */
35 if ((tmpPixmap
= XCreatePixmap( display
, rootWindow
, 1, 1, 1 )))
37 BITMAP_monoGC
= XCreateGC( display
, tmpPixmap
, 0, NULL
);
38 XSetGraphicsExposures( display
, BITMAP_monoGC
, False
);
39 XFreePixmap( display
, tmpPixmap
);
44 if ((tmpPixmap
= XCreatePixmap(display
, rootWindow
, 1,1,screenDepth
)))
46 BITMAP_colorGC
= XCreateGC( display
, tmpPixmap
, 0, NULL
);
47 XSetGraphicsExposures( display
, BITMAP_colorGC
, False
);
48 XFreePixmap( display
, tmpPixmap
);
55 /***********************************************************************
58 * Create an XImage pointing to the bitmap data.
60 static XImage
*BITMAP_BmpToImage( BITMAP
* bmp
, void * bmpData
)
62 extern void _XInitImageFuncPtrs( XImage
* );
65 image
= XCreateImage( display
, DefaultVisualOfScreen(screen
),
66 bmp
->bmBitsPixel
, ZPixmap
, 0, bmpData
,
67 bmp
->bmWidth
, bmp
->bmHeight
, 16, bmp
->bmWidthBytes
);
69 image
->byte_order
= MSBFirst
;
70 image
->bitmap_bit_order
= MSBFirst
;
71 image
->bitmap_unit
= 16;
72 _XInitImageFuncPtrs(image
);
77 /***********************************************************************
78 * CreateBitmap (GDI.48)
80 HBITMAP
CreateBitmap( short width
, short height
,
81 BYTE planes
, BYTE bpp
, LPSTR bits
)
83 BITMAPOBJ
* bmpObjPtr
;
86 dprintf_gdi( stddeb
, "CreateBitmap: %dx%d, %d colors\n",
87 width
, height
, 1 << (planes
*bpp
) );
89 /* Check parameters */
90 if (!height
|| !width
|| planes
!= 1) return 0;
91 if ((bpp
!= 1) && (bpp
!= screenDepth
)) return 0;
92 if (height
< 0) height
= -height
;
93 if (width
< 0) width
= -width
;
95 /* Create the BITMAPOBJ */
96 hbitmap
= GDI_AllocObject( sizeof(BITMAPOBJ
), BITMAP_MAGIC
);
97 if (!hbitmap
) return 0;
98 bmpObjPtr
= (BITMAPOBJ
*) GDI_HEAP_LIN_ADDR( hbitmap
);
100 bmpObjPtr
->size
.cx
= 0;
101 bmpObjPtr
->size
.cy
= 0;
102 bmpObjPtr
->bitmap
.bmType
= 0;
103 bmpObjPtr
->bitmap
.bmWidth
= width
;
104 bmpObjPtr
->bitmap
.bmHeight
= height
;
105 bmpObjPtr
->bitmap
.bmPlanes
= planes
;
106 bmpObjPtr
->bitmap
.bmBitsPixel
= bpp
;
107 bmpObjPtr
->bitmap
.bmWidthBytes
= (width
* bpp
+ 15) / 16 * 2;
108 bmpObjPtr
->bitmap
.bmBits
= NULL
;
110 /* Create the pixmap */
111 bmpObjPtr
->pixmap
= XCreatePixmap(display
, rootWindow
, width
, height
, bpp
);
112 if (!bmpObjPtr
->pixmap
)
114 GDI_HEAP_FREE( hbitmap
);
117 else if (bits
) /* Set bitmap bits */
118 SetBitmapBits( hbitmap
, height
* bmpObjPtr
->bitmap
.bmWidthBytes
, bits
);
123 /***********************************************************************
124 * CreateCompatibleBitmap (GDI.51)
126 HBITMAP
CreateCompatibleBitmap( HDC hdc
, short width
, short height
)
129 dprintf_gdi(stddeb
, "CreateCompatibleBitmap: %d %dx%d\n",
130 hdc
, width
, height
);
131 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
132 return CreateBitmap( width
, height
, 1, dc
->w
.bitsPerPixel
, NULL
);
136 /***********************************************************************
137 * CreateBitmapIndirect (GDI.49)
139 HBITMAP
CreateBitmapIndirect( BITMAP
* bmp
)
141 return CreateBitmap( bmp
->bmWidth
, bmp
->bmHeight
, bmp
->bmPlanes
,
142 bmp
->bmBitsPixel
, PTR_SEG_TO_LIN( bmp
->bmBits
) );
146 /***********************************************************************
147 * GetBitmapBits (GDI.74)
149 LONG
GetBitmapBits( HBITMAP hbitmap
, LONG count
, LPSTR buffer
)
155 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
158 dprintf_bitmap(stddeb
, "GetBitmapBits: %dx%d %d colors %p\n",
159 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
160 1 << bmp
->bitmap
.bmBitsPixel
, buffer
);
161 /* Only get entire lines */
162 height
= count
/ bmp
->bitmap
.bmWidthBytes
;
163 if (height
> bmp
->bitmap
.bmHeight
) height
= bmp
->bitmap
.bmHeight
;
164 if (!height
) return 0;
166 if (!(image
= BITMAP_BmpToImage( &bmp
->bitmap
, buffer
))) return 0;
167 CallTo32_LargeStack( (int(*)())XGetSubImage
, 11,
168 display
, bmp
->pixmap
, 0, 0, bmp
->bitmap
.bmWidth
,
169 height
, AllPlanes
, ZPixmap
, image
, 0, 0 );
171 XDestroyImage( image
);
172 return height
* bmp
->bitmap
.bmWidthBytes
;
176 /***********************************************************************
177 * SetBitmapBits (GDI.106)
179 LONG
SetBitmapBits( HBITMAP hbitmap
, LONG count
, LPSTR buffer
)
185 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
188 dprintf_bitmap(stddeb
, "SetBitmapBits: %dx%d %d colors %p\n",
189 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
190 1 << bmp
->bitmap
.bmBitsPixel
, buffer
);
192 /* Only set entire lines */
193 height
= count
/ bmp
->bitmap
.bmWidthBytes
;
194 if (height
> bmp
->bitmap
.bmHeight
) height
= bmp
->bitmap
.bmHeight
;
195 if (!height
) return 0;
197 if (!(image
= BITMAP_BmpToImage( &bmp
->bitmap
, buffer
))) return 0;
198 CallTo32_LargeStack( XPutImage
, 10,
199 display
, bmp
->pixmap
, BITMAP_GC(bmp
), image
, 0, 0,
200 0, 0, bmp
->bitmap
.bmWidth
, height
);
202 XDestroyImage( image
);
203 return height
* bmp
->bitmap
.bmWidthBytes
;
207 /**********************************************************************
208 * LoadBitmap (USER.175)
210 HBITMAP
LoadBitmap( HANDLE instance
, SEGPTR name
)
221 char *str
= (char *)PTR_SEG_TO_LIN( name
);
222 dprintf_bitmap( stddeb
, "LoadBitmap(%04x,'%s')\n", instance
, str
);
223 if (str
[0] == '#') name
= (SEGPTR
)atoi( str
+ 1 );
226 dprintf_bitmap(stddeb
,"LoadBitmap(%04x,%04x)\n",instance
,LOWORD(name
));
228 if (!instance
) /* OEM bitmap */
230 if (HIWORD((int)name
)) return 0;
231 return OBM_LoadBitmap( LOWORD((int)name
) );
234 if (!(hRsrc
= FindResource( instance
, name
, RT_BITMAP
))) return 0;
235 if (!(handle
= LoadResource( instance
, hRsrc
))) return 0;
237 lp
= (long *)LockResource( handle
);
238 size
= CONV_LONG(*lp
);
239 if ((hdc
= GetDC(0)) != 0)
241 if (size
== sizeof(BITMAPCOREHEADER
))
242 hbitmap
= ConvertCoreBitmap( hdc
, (BITMAPCOREHEADER
*) lp
);
243 else if (size
== sizeof(BITMAPINFOHEADER
))
244 hbitmap
= ConvertInfoBitmap( hdc
, (BITMAPINFO
*) lp
);
247 FreeResource( handle
);
252 /***********************************************************************
253 * BITMAP_DeleteObject
255 BOOL
BITMAP_DeleteObject( HBITMAP hbitmap
, BITMAPOBJ
* bitmap
)
257 XFreePixmap( display
, bitmap
->pixmap
);
258 return GDI_FreeObject( hbitmap
);
262 /***********************************************************************
265 int BITMAP_GetObject( BITMAPOBJ
* bmp
, int count
, LPSTR buffer
)
267 if (count
> sizeof(BITMAP
)) count
= sizeof(BITMAP
);
268 memcpy( buffer
, &bmp
->bitmap
, count
);
273 /***********************************************************************
274 * BITMAP_SelectObject
276 HBITMAP
BITMAP_SelectObject( HDC hdc
, DC
* dc
, HBITMAP hbitmap
,
280 HBITMAP prevHandle
= dc
->w
.hBitmap
;
282 if (!(dc
->w
.flags
& DC_MEMORY
)) return 0;
283 hrgn
= CreateRectRgn( 0, 0, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
286 DeleteObject( dc
->w
.hVisRgn
);
287 dc
->w
.hVisRgn
= hrgn
;
288 dc
->u
.x
.drawable
= bmp
->pixmap
;
289 dc
->w
.hBitmap
= hbitmap
;
291 /* Change GC depth if needed */
293 if (dc
->w
.bitsPerPixel
!= bmp
->bitmap
.bmBitsPixel
)
295 XFreeGC( display
, dc
->u
.x
.gc
);
296 dc
->u
.x
.gc
= XCreateGC( display
, dc
->u
.x
.drawable
, 0, NULL
);
297 dc
->w
.bitsPerPixel
= bmp
->bitmap
.bmBitsPixel
;
300 else CLIPPING_UpdateGCRegion( dc
); /* Just update GC clip region */
304 /***********************************************************************
305 * CreateDiscardableBitmap (GDI.156)
307 HBITMAP
CreateDiscardableBitmap(HDC hdc
, short width
, short height
)
309 dprintf_bitmap(stddeb
,"CreateDiscardableBitmap(%04X, %d, %d); "
310 "// call CreateCompatibleBitmap() for now!\n",
312 return CreateCompatibleBitmap(hdc
, width
, height
);
315 /***********************************************************************
316 * GetBitmapDimensionEx (GDI.468)
318 BOOL
GetBitmapDimensionEx( HBITMAP hbitmap
, LPSIZE size
)
320 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
321 if (!bmp
) return FALSE
;
327 /***********************************************************************
328 * GetBitmapDimension (GDI.162)
330 DWORD
GetBitmapDimension( HBITMAP hbitmap
)
333 if (!GetBitmapDimensionEx( hbitmap
, &size
)) return 0;
334 return size
.cx
| (size
.cy
<< 16);
337 /***********************************************************************
338 * SetBitmapDimensionEx (GDI.478)
340 BOOL
SetBitmapDimensionEx( HBITMAP hbitmap
, short x
, short y
, LPSIZE prevSize
)
342 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
343 if (!bmp
) return FALSE
;
344 if (prevSize
) *prevSize
= bmp
->size
;
351 /***********************************************************************
352 * SetBitmapDimension (GDI.163)
354 DWORD
SetBitmapDimension( HBITMAP hbitmap
, short x
, short y
)
357 if (!SetBitmapDimensionEx( hbitmap
, x
, y
, &size
)) return 0;
358 return size
.cx
| (size
.cy
<< 16);