4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
12 #include <X11/Xutil.h>
16 /* #define DEBUG_GDI */
17 /* #undef DEBUG_GDI */
18 /* #define DEBUG_BITMAP */
19 /* #define DEBUG_BITMAP */
22 /* GCs used for B&W and color bitmap operations */
23 GC BITMAP_monoGC
= 0, BITMAP_colorGC
= 0;
25 extern void DC_InitDC( HDC hdc
); /* objects/dc.c */
26 extern void CLIPPING_UpdateGCRegion( DC
* dc
); /* objects/clipping.c */
28 /***********************************************************************
35 /* Create the necessary GCs */
37 if ((tmpPixmap
= XCreatePixmap( display
, rootWindow
, 1, 1, 1 )))
39 BITMAP_monoGC
= XCreateGC( display
, tmpPixmap
, 0, NULL
);
40 XSetGraphicsExposures( display
, BITMAP_monoGC
, False
);
41 XFreePixmap( display
, tmpPixmap
);
46 if ((tmpPixmap
= XCreatePixmap(display
, rootWindow
, 1,1,screenDepth
)))
48 BITMAP_colorGC
= XCreateGC( display
, tmpPixmap
, 0, NULL
);
49 XSetGraphicsExposures( display
, BITMAP_colorGC
, False
);
50 XFreePixmap( display
, tmpPixmap
);
57 /***********************************************************************
60 * Create an XImage pointing to the bitmap data.
62 static XImage
*BITMAP_BmpToImage( BITMAP
* bmp
, void * bmpData
)
64 extern void _XInitImageFuncPtrs( XImage
* );
67 image
= XCreateImage( display
, DefaultVisualOfScreen(screen
),
68 bmp
->bmBitsPixel
, ZPixmap
, 0, bmpData
,
69 bmp
->bmWidth
, bmp
->bmHeight
, 16, bmp
->bmWidthBytes
);
71 image
->byte_order
= MSBFirst
;
72 image
->bitmap_bit_order
= MSBFirst
;
73 image
->bitmap_unit
= 16;
74 _XInitImageFuncPtrs(image
);
79 /***********************************************************************
80 * CreateBitmap (GDI.48)
82 HBITMAP
CreateBitmap( short width
, short height
,
83 BYTE planes
, BYTE bpp
, LPSTR bits
)
85 BITMAP bitmap
= { 0, width
, height
, 0, planes
, bpp
, bits
};
86 dprintf_gdi(stddeb
, "CreateBitmap: %dx%d, %d colors\n",
87 width
, height
, 1 << (planes
*bpp
) );
88 return CreateBitmapIndirect( &bitmap
);
92 /***********************************************************************
93 * CreateCompatibleBitmap (GDI.51)
95 HBITMAP
CreateCompatibleBitmap( HDC hdc
, short width
, short height
)
98 dprintf_gdi(stddeb
, "CreateCompatibleBitmap: %d %dx%d\n",
100 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
101 return CreateBitmap( width
, height
, 1, dc
->w
.bitsPerPixel
, NULL
);
105 /***********************************************************************
106 * CreateBitmapIndirect (GDI.49)
108 HBITMAP
CreateBitmapIndirect( BITMAP
* bmp
)
110 BITMAPOBJ
* bmpObjPtr
;
113 /* Check parameters */
114 if (!bmp
->bmHeight
|| !bmp
->bmWidth
) return 0;
115 if (bmp
->bmPlanes
!= 1) return 0;
116 if ((bmp
->bmBitsPixel
!= 1) && (bmp
->bmBitsPixel
!= screenDepth
)) return 0;
118 if (bmp
->bmHeight
< 0)
119 bmp
->bmHeight
= -bmp
->bmHeight
;
121 if (bmp
->bmWidth
< 0)
122 bmp
->bmWidth
= -bmp
->bmWidth
;
125 /* Create the BITMAPOBJ */
126 hbitmap
= GDI_AllocObject( sizeof(BITMAPOBJ
), BITMAP_MAGIC
);
127 if (!hbitmap
) return 0;
128 bmpObjPtr
= (BITMAPOBJ
*) GDI_HEAP_ADDR( hbitmap
);
130 bmpObjPtr
->size
.cx
= 0;
131 bmpObjPtr
->size
.cy
= 0;
132 bmpObjPtr
->bitmap
= *bmp
;
133 bmpObjPtr
->bitmap
.bmBits
= NULL
;
134 bmpObjPtr
->bitmap
.bmWidthBytes
= (bmp
->bmWidth
*bmp
->bmBitsPixel
+15)/16 * 2;
136 /* Create the pixmap */
137 bmpObjPtr
->pixmap
= XCreatePixmap( display
, rootWindow
, bmp
->bmWidth
,
138 bmp
->bmHeight
, bmp
->bmBitsPixel
);
139 if (!bmpObjPtr
->pixmap
)
141 GDI_HEAP_FREE( hbitmap
);
144 else if (bmp
->bmBits
) /* Set bitmap bits */
145 SetBitmapBits( hbitmap
, bmp
->bmHeight
*bmp
->bmWidthBytes
, bmp
->bmBits
);
150 /***********************************************************************
151 * GetBitmapBits (GDI.74)
153 LONG
GetBitmapBits( HBITMAP hbitmap
, LONG count
, LPSTR buffer
)
159 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
162 dprintf_bitmap(stddeb
, "GetBitmapBits: %dx%d %d colors %p\n",
163 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
164 1 << bmp
->bitmap
.bmBitsPixel
, buffer
);
165 /* Only get entire lines */
166 height
= count
/ bmp
->bitmap
.bmWidthBytes
;
167 if (height
> bmp
->bitmap
.bmHeight
) height
= bmp
->bitmap
.bmHeight
;
168 if (!height
) return 0;
170 if (!(image
= BITMAP_BmpToImage( &bmp
->bitmap
, buffer
))) return 0;
171 XGetSubImage( display
, bmp
->pixmap
, 0, 0, bmp
->bitmap
.bmWidth
, height
,
172 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
)
188 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
191 dprintf_bitmap(stddeb
, "SetBitmapBits: %dx%d %d colors %p\n",
192 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
193 1 << bmp
->bitmap
.bmBitsPixel
, buffer
);
195 /* Only set entire lines */
196 height
= count
/ bmp
->bitmap
.bmWidthBytes
;
197 if (height
> bmp
->bitmap
.bmHeight
) height
= bmp
->bitmap
.bmHeight
;
198 if (!height
) return 0;
200 if (!(image
= BITMAP_BmpToImage( &bmp
->bitmap
, buffer
))) return 0;
201 XPutImage( display
, bmp
->pixmap
, BITMAP_GC(bmp
), image
, 0, 0,
202 0, 0, bmp
->bitmap
.bmWidth
, height
);
204 XDestroyImage( image
);
205 return height
* bmp
->bitmap
.bmWidthBytes
;
209 /***********************************************************************
212 BOOL
BMP_DeleteObject( HBITMAP hbitmap
, BITMAPOBJ
* bitmap
)
214 XFreePixmap( display
, bitmap
->pixmap
);
215 return GDI_FreeObject( hbitmap
);
219 /***********************************************************************
222 int BMP_GetObject( BITMAPOBJ
* bmp
, int count
, LPSTR buffer
)
224 if (count
> sizeof(BITMAP
)) count
= sizeof(BITMAP
);
225 memcpy( buffer
, &bmp
->bitmap
, count
);
230 /***********************************************************************
231 * BITMAP_SelectObject
233 HBITMAP
BITMAP_SelectObject( HDC hdc
, DC
* dc
, HBITMAP hbitmap
,
237 HBITMAP prevHandle
= dc
->w
.hBitmap
;
239 if (!(dc
->w
.flags
& DC_MEMORY
)) return 0;
240 hrgn
= CreateRectRgn( 0, 0, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
243 DeleteObject( dc
->w
.hVisRgn
);
244 dc
->w
.hVisRgn
= hrgn
;
245 dc
->u
.x
.drawable
= bmp
->pixmap
;
246 dc
->w
.hBitmap
= hbitmap
;
248 /* Change GC depth if needed */
250 if (dc
->w
.bitsPerPixel
!= bmp
->bitmap
.bmBitsPixel
)
252 XFreeGC( display
, dc
->u
.x
.gc
);
253 dc
->u
.x
.gc
= XCreateGC( display
, dc
->u
.x
.drawable
, 0, NULL
);
254 dc
->w
.bitsPerPixel
= bmp
->bitmap
.bmBitsPixel
;
257 else CLIPPING_UpdateGCRegion( dc
); /* Just update GC clip region */
261 /***********************************************************************
262 * CreateDiscardableBitmap (GDI.156)
264 HBITMAP
CreateDiscardableBitmap(HDC hdc
, short width
, short height
)
266 dprintf_bitmap(stddeb
,"CreateDiscardableBitmap(%04X, %d, %d); "
267 "// call CreateCompatibleBitmap() for now!\n",
269 return CreateCompatibleBitmap(hdc
, width
, height
);
272 /***********************************************************************
273 * GetBitmapDimensionEx (GDI.468)
275 BOOL
GetBitmapDimensionEx( HBITMAP hbitmap
, LPSIZE size
)
277 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
278 if (!bmp
) return FALSE
;
284 /***********************************************************************
285 * GetBitmapDimension (GDI.162)
287 DWORD
GetBitmapDimension( HBITMAP hbitmap
)
290 if (!GetBitmapDimensionEx( hbitmap
, &size
)) return 0;
291 return size
.cx
| (size
.cy
<< 16);
294 /***********************************************************************
295 * SetBitmapDimensionEx (GDI.478)
297 BOOL
SetBitmapDimensionEx( HBITMAP hbitmap
, short x
, short y
, LPSIZE prevSize
)
299 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
300 if (!bmp
) return FALSE
;
301 if (prevSize
) *prevSize
= bmp
->size
;
308 /***********************************************************************
309 * SetBitmapDimension (GDI.163)
311 DWORD
SetBitmapDimension( HBITMAP hbitmap
, short x
, short y
)
314 if (!SetBitmapDimensionEx( hbitmap
, x
, y
, &size
)) return 0;
315 return size
.cx
| (size
.cy
<< 16);