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( short width
, short height
,
79 BYTE planes
, BYTE bpp
, LPSTR bits
)
81 BITMAPOBJ
* bmpObjPtr
;
84 dprintf_gdi( stddeb
, "CreateBitmap: %dx%d, %d colors\n",
85 width
, height
, 1 << (planes
*bpp
) );
87 /* Check parameters */
88 if (!height
|| !width
|| planes
!= 1) return 0;
89 if ((bpp
!= 1) && (bpp
!= screenDepth
)) return 0;
90 if (height
< 0) height
= -height
;
91 if (width
< 0) width
= -width
;
93 /* Create the BITMAPOBJ */
94 hbitmap
= GDI_AllocObject( sizeof(BITMAPOBJ
), BITMAP_MAGIC
);
95 if (!hbitmap
) return 0;
96 bmpObjPtr
= (BITMAPOBJ
*) GDI_HEAP_LIN_ADDR( hbitmap
);
98 bmpObjPtr
->size
.cx
= 0;
99 bmpObjPtr
->size
.cy
= 0;
100 bmpObjPtr
->bitmap
.bmType
= 0;
101 bmpObjPtr
->bitmap
.bmWidth
= width
;
102 bmpObjPtr
->bitmap
.bmHeight
= height
;
103 bmpObjPtr
->bitmap
.bmPlanes
= planes
;
104 bmpObjPtr
->bitmap
.bmBitsPixel
= bpp
;
105 bmpObjPtr
->bitmap
.bmWidthBytes
= (width
* bpp
+ 15) / 16 * 2;
106 bmpObjPtr
->bitmap
.bmBits
= NULL
;
108 /* Create the pixmap */
109 bmpObjPtr
->pixmap
= XCreatePixmap(display
, rootWindow
, width
, height
, bpp
);
110 if (!bmpObjPtr
->pixmap
)
112 GDI_HEAP_FREE( hbitmap
);
115 else if (bits
) /* Set bitmap bits */
116 SetBitmapBits( hbitmap
, height
* bmpObjPtr
->bitmap
.bmWidthBytes
, bits
);
121 /***********************************************************************
122 * CreateCompatibleBitmap (GDI.51)
124 HBITMAP
CreateCompatibleBitmap( HDC hdc
, short width
, short height
)
127 dprintf_gdi(stddeb
, "CreateCompatibleBitmap: "NPFMT
" %dx%d\n",
128 hdc
, width
, height
);
129 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
130 return CreateBitmap( width
, height
, 1, dc
->w
.bitsPerPixel
, NULL
);
134 /***********************************************************************
135 * CreateBitmapIndirect (GDI.49)
137 HBITMAP
CreateBitmapIndirect( BITMAP
* bmp
)
139 return CreateBitmap( bmp
->bmWidth
, bmp
->bmHeight
, bmp
->bmPlanes
,
140 bmp
->bmBitsPixel
, PTR_SEG_TO_LIN( bmp
->bmBits
) );
144 /***********************************************************************
145 * GetBitmapBits (GDI.74)
147 LONG
GetBitmapBits( HBITMAP hbitmap
, LONG count
, LPSTR buffer
)
155 fprintf(stderr
, "Negative number of bytes (%ld) passed to GetBitmapBits???\n", count
);
158 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
161 /* Only get entire lines */
162 height
= count
/ bmp
->bitmap
.bmWidthBytes
;
163 if (height
> bmp
->bitmap
.bmHeight
) height
= bmp
->bitmap
.bmHeight
;
164 dprintf_bitmap(stddeb
, "GetBitmapBits: %dx%d %d colors %p fetched height: %ld\n",
165 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
166 1 << bmp
->bitmap
.bmBitsPixel
, buffer
, height
);
167 if (!height
) return 0;
169 if (!(image
= BITMAP_BmpToImage( &bmp
->bitmap
, buffer
))) return 0;
170 CallTo32_LargeStack( (int(*)())XGetSubImage
, 11,
171 display
, bmp
->pixmap
, 0, 0, bmp
->bitmap
.bmWidth
,
172 height
, AllPlanes
, ZPixmap
, image
, 0, 0 );
174 XDestroyImage( image
);
175 return height
* bmp
->bitmap
.bmWidthBytes
;
179 /***********************************************************************
180 * SetBitmapBits (GDI.106)
182 LONG
SetBitmapBits( HBITMAP hbitmap
, LONG count
, LPSTR buffer
)
190 fprintf(stderr
, "Negative number of bytes (%ld) passed to SetBitmapBits???\n", count
);
193 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
196 dprintf_bitmap(stddeb
, "SetBitmapBits: %dx%d %d colors %p\n",
197 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
198 1 << bmp
->bitmap
.bmBitsPixel
, buffer
);
200 /* Only set entire lines */
201 height
= count
/ bmp
->bitmap
.bmWidthBytes
;
202 if (height
> bmp
->bitmap
.bmHeight
) height
= bmp
->bitmap
.bmHeight
;
203 if (!height
) return 0;
205 if (!(image
= BITMAP_BmpToImage( &bmp
->bitmap
, buffer
))) return 0;
206 CallTo32_LargeStack( XPutImage
, 10,
207 display
, bmp
->pixmap
, BITMAP_GC(bmp
), image
, 0, 0,
208 0, 0, bmp
->bitmap
.bmWidth
, height
);
210 XDestroyImage( image
);
211 return height
* bmp
->bitmap
.bmWidthBytes
;
215 /**********************************************************************
216 * LoadBitmap (USER.175)
218 HBITMAP
LoadBitmap( HANDLE instance
, SEGPTR name
)
228 char *str
= (char *)PTR_SEG_TO_LIN( name
);
229 dprintf_bitmap( stddeb
, "LoadBitmap("NPFMT
",'%s')\n", instance
, str
);
230 if (str
[0] == '#') name
= (SEGPTR
)(DWORD
)(WORD
)atoi( str
+ 1 );
233 dprintf_bitmap( stddeb
, "LoadBitmap("NPFMT
",%04x)\n",
234 instance
, LOWORD(name
) );
236 if (!instance
) /* OEM bitmap */
238 if (HIWORD((int)name
)) return 0;
239 return OBM_LoadBitmap( LOWORD((int)name
) );
242 if (!(hRsrc
= FindResource( instance
, name
, RT_BITMAP
))) return 0;
243 if (!(handle
= LoadResource( instance
, hRsrc
))) return 0;
245 info
= (BITMAPINFO
*)LockResource( handle
);
246 if ((hdc
= GetDC(0)) != 0)
248 char *bits
= (char *)info
+ DIB_BitmapInfoSize( info
, DIB_RGB_COLORS
);
249 hbitmap
= CreateDIBitmap( hdc
, &info
->bmiHeader
, CBM_INIT
,
250 bits
, info
, DIB_RGB_COLORS
);
253 FreeResource( handle
);
258 /***********************************************************************
259 * BITMAP_DeleteObject
261 BOOL
BITMAP_DeleteObject( HBITMAP hbitmap
, BITMAPOBJ
* bitmap
)
263 XFreePixmap( display
, bitmap
->pixmap
);
264 return GDI_FreeObject( hbitmap
);
268 /***********************************************************************
271 int BITMAP_GetObject( BITMAPOBJ
* bmp
, int count
, LPSTR buffer
)
273 if (count
> sizeof(BITMAP
)) count
= sizeof(BITMAP
);
274 memcpy( buffer
, &bmp
->bitmap
, count
);
279 /***********************************************************************
280 * BITMAP_SelectObject
282 HBITMAP
BITMAP_SelectObject( HDC hdc
, DC
* dc
, HBITMAP hbitmap
,
286 HBITMAP prevHandle
= dc
->w
.hBitmap
;
288 if (!(dc
->w
.flags
& DC_MEMORY
)) return 0;
289 hrgn
= CreateRectRgn( 0, 0, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
292 DeleteObject( dc
->w
.hVisRgn
);
293 dc
->w
.hVisRgn
= hrgn
;
294 dc
->u
.x
.drawable
= bmp
->pixmap
;
295 dc
->w
.hBitmap
= hbitmap
;
297 /* Change GC depth if needed */
299 if (dc
->w
.bitsPerPixel
!= bmp
->bitmap
.bmBitsPixel
)
301 XFreeGC( display
, dc
->u
.x
.gc
);
302 dc
->u
.x
.gc
= XCreateGC( display
, dc
->u
.x
.drawable
, 0, NULL
);
303 dc
->w
.bitsPerPixel
= bmp
->bitmap
.bmBitsPixel
;
306 else CLIPPING_UpdateGCRegion( dc
); /* Just update GC clip region */
310 /***********************************************************************
311 * CreateDiscardableBitmap (GDI.156)
313 HBITMAP
CreateDiscardableBitmap(HDC hdc
, short width
, short height
)
315 dprintf_bitmap(stddeb
,"CreateDiscardableBitmap("NPFMT
", %d, %d); "
316 "// call CreateCompatibleBitmap() for now!\n",
318 return CreateCompatibleBitmap(hdc
, width
, height
);
321 /***********************************************************************
322 * GetBitmapDimensionEx (GDI.468)
324 BOOL
GetBitmapDimensionEx( HBITMAP hbitmap
, LPSIZE size
)
326 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
327 if (!bmp
) return FALSE
;
333 /***********************************************************************
334 * GetBitmapDimension (GDI.162)
336 DWORD
GetBitmapDimension( HBITMAP hbitmap
)
339 if (!GetBitmapDimensionEx( hbitmap
, &size
)) return 0;
340 return size
.cx
| (size
.cy
<< 16);
343 /***********************************************************************
344 * SetBitmapDimensionEx (GDI.478)
346 BOOL
SetBitmapDimensionEx( HBITMAP hbitmap
, short x
, short y
, LPSIZE prevSize
)
348 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
349 if (!bmp
) return FALSE
;
350 if (prevSize
) *prevSize
= bmp
->size
;
357 /***********************************************************************
358 * SetBitmapDimension (GDI.163)
360 DWORD
SetBitmapDimension( HBITMAP hbitmap
, short x
, short y
)
363 if (!SetBitmapDimensionEx( hbitmap
, x
, y
, &size
)) return 0;
364 return size
.cx
| (size
.cy
<< 16);