4 * Copyright 1993 Alexandre Julliard
6 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
11 #include <X11/Xutil.h>
16 /* #define DEBUG_GDI */
17 /* #define DEBUG_BITMAP */
20 /* GCs used for B&W and color bitmap operations */
21 GC BITMAP_monoGC
= 0, BITMAP_colorGC
= 0;
23 extern void CLIPPING_UpdateGCRegion( DC
* dc
); /* objects/clipping.c */
25 /***********************************************************************
28 BOOL
BITMAP_Init(void)
32 /* Create the necessary GCs */
34 if ((tmpPixmap
= XCreatePixmap( display
, rootWindow
, 1, 1, 1 )))
36 BITMAP_monoGC
= XCreateGC( display
, tmpPixmap
, 0, NULL
);
37 XSetGraphicsExposures( display
, BITMAP_monoGC
, False
);
38 XFreePixmap( display
, tmpPixmap
);
43 if ((tmpPixmap
= XCreatePixmap(display
, rootWindow
, 1,1,screenDepth
)))
45 BITMAP_colorGC
= XCreateGC( display
, tmpPixmap
, 0, NULL
);
46 XSetGraphicsExposures( display
, BITMAP_colorGC
, False
);
47 XFreePixmap( display
, tmpPixmap
);
54 /***********************************************************************
57 * Create an XImage pointing to the bitmap data.
59 static XImage
*BITMAP_BmpToImage( BITMAP
* bmp
, void * bmpData
)
61 extern void _XInitImageFuncPtrs( XImage
* );
64 image
= XCreateImage( display
, DefaultVisualOfScreen(screen
),
65 bmp
->bmBitsPixel
, ZPixmap
, 0, bmpData
,
66 bmp
->bmWidth
, bmp
->bmHeight
, 16, bmp
->bmWidthBytes
);
68 image
->byte_order
= MSBFirst
;
69 image
->bitmap_bit_order
= MSBFirst
;
70 image
->bitmap_unit
= 16;
71 _XInitImageFuncPtrs(image
);
76 /***********************************************************************
77 * CreateBitmap (GDI.48)
79 HBITMAP
CreateBitmap( short width
, short height
,
80 BYTE planes
, BYTE bpp
, LPSTR bits
)
82 BITMAP bitmap
= { 0, width
, height
, 0, planes
, bpp
, bits
};
83 dprintf_gdi(stddeb
, "CreateBitmap: %dx%d, %d colors\n",
84 width
, height
, 1 << (planes
*bpp
) );
85 return CreateBitmapIndirect( &bitmap
);
89 /***********************************************************************
90 * CreateCompatibleBitmap (GDI.51)
92 HBITMAP
CreateCompatibleBitmap( HDC hdc
, short width
, short height
)
95 dprintf_gdi(stddeb
, "CreateCompatibleBitmap: %d %dx%d\n",
97 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
98 return CreateBitmap( width
, height
, 1, dc
->w
.bitsPerPixel
, NULL
);
102 /***********************************************************************
103 * CreateBitmapIndirect (GDI.49)
105 HBITMAP
CreateBitmapIndirect( BITMAP
* bmp
)
107 BITMAPOBJ
* bmpObjPtr
;
110 /* Check parameters */
111 if (!bmp
->bmHeight
|| !bmp
->bmWidth
) return 0;
112 if (bmp
->bmPlanes
!= 1) return 0;
113 if ((bmp
->bmBitsPixel
!= 1) && (bmp
->bmBitsPixel
!= screenDepth
)) return 0;
115 if (bmp
->bmHeight
< 0)
116 bmp
->bmHeight
= -bmp
->bmHeight
;
118 if (bmp
->bmWidth
< 0)
119 bmp
->bmWidth
= -bmp
->bmWidth
;
122 /* Create the BITMAPOBJ */
123 hbitmap
= GDI_AllocObject( sizeof(BITMAPOBJ
), BITMAP_MAGIC
);
124 if (!hbitmap
) return 0;
125 bmpObjPtr
= (BITMAPOBJ
*) GDI_HEAP_ADDR( hbitmap
);
127 bmpObjPtr
->size
.cx
= 0;
128 bmpObjPtr
->size
.cy
= 0;
129 bmpObjPtr
->bitmap
= *bmp
;
130 bmpObjPtr
->bitmap
.bmBits
= NULL
;
131 bmpObjPtr
->bitmap
.bmWidthBytes
= (bmp
->bmWidth
*bmp
->bmBitsPixel
+15)/16 * 2;
133 /* Create the pixmap */
134 bmpObjPtr
->pixmap
= XCreatePixmap( display
, rootWindow
, bmp
->bmWidth
,
135 bmp
->bmHeight
, bmp
->bmBitsPixel
);
136 if (!bmpObjPtr
->pixmap
)
138 GDI_HEAP_FREE( hbitmap
);
141 else if (bmp
->bmBits
) /* Set bitmap bits */
142 SetBitmapBits( hbitmap
, bmpObjPtr
->bitmap
.bmHeight
*bmpObjPtr
->bitmap
.bmWidthBytes
, bmp
->bmBits
);
147 /***********************************************************************
148 * GetBitmapBits (GDI.74)
150 LONG
GetBitmapBits( HBITMAP hbitmap
, LONG count
, LPSTR buffer
)
156 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
159 dprintf_bitmap(stddeb
, "GetBitmapBits: %dx%d %d colors %p\n",
160 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
161 1 << bmp
->bitmap
.bmBitsPixel
, buffer
);
162 /* Only get entire lines */
163 height
= count
/ bmp
->bitmap
.bmWidthBytes
;
164 if (height
> bmp
->bitmap
.bmHeight
) height
= bmp
->bitmap
.bmHeight
;
165 if (!height
) return 0;
167 if (!(image
= BITMAP_BmpToImage( &bmp
->bitmap
, buffer
))) return 0;
168 XGetSubImage( display
, bmp
->pixmap
, 0, 0, bmp
->bitmap
.bmWidth
, height
,
169 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 XPutImage( display
, bmp
->pixmap
, BITMAP_GC(bmp
), image
, 0, 0,
199 0, 0, bmp
->bitmap
.bmWidth
, height
);
201 XDestroyImage( image
);
202 return height
* bmp
->bitmap
.bmWidthBytes
;
206 /***********************************************************************
207 * BITMAP_DeleteObject
209 BOOL
BITMAP_DeleteObject( HBITMAP hbitmap
, BITMAPOBJ
* bitmap
)
211 XFreePixmap( display
, bitmap
->pixmap
);
212 return GDI_FreeObject( hbitmap
);
216 /***********************************************************************
219 int BITMAP_GetObject( BITMAPOBJ
* bmp
, int count
, LPSTR buffer
)
221 if (count
> sizeof(BITMAP
)) count
= sizeof(BITMAP
);
222 memcpy( buffer
, &bmp
->bitmap
, count
);
227 /***********************************************************************
228 * BITMAP_SelectObject
230 HBITMAP
BITMAP_SelectObject( HDC hdc
, DC
* dc
, HBITMAP hbitmap
,
234 HBITMAP prevHandle
= dc
->w
.hBitmap
;
236 if (!(dc
->w
.flags
& DC_MEMORY
)) return 0;
237 hrgn
= CreateRectRgn( 0, 0, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
240 DeleteObject( dc
->w
.hVisRgn
);
241 dc
->w
.hVisRgn
= hrgn
;
242 dc
->u
.x
.drawable
= bmp
->pixmap
;
243 dc
->w
.hBitmap
= hbitmap
;
245 /* Change GC depth if needed */
247 if (dc
->w
.bitsPerPixel
!= bmp
->bitmap
.bmBitsPixel
)
249 XFreeGC( display
, dc
->u
.x
.gc
);
250 dc
->u
.x
.gc
= XCreateGC( display
, dc
->u
.x
.drawable
, 0, NULL
);
251 dc
->w
.bitsPerPixel
= bmp
->bitmap
.bmBitsPixel
;
254 else CLIPPING_UpdateGCRegion( dc
); /* Just update GC clip region */
258 /***********************************************************************
259 * CreateDiscardableBitmap (GDI.156)
261 HBITMAP
CreateDiscardableBitmap(HDC hdc
, short width
, short height
)
263 dprintf_bitmap(stddeb
,"CreateDiscardableBitmap(%04X, %d, %d); "
264 "// call CreateCompatibleBitmap() for now!\n",
266 return CreateCompatibleBitmap(hdc
, width
, height
);
269 /***********************************************************************
270 * GetBitmapDimensionEx (GDI.468)
272 BOOL
GetBitmapDimensionEx( HBITMAP hbitmap
, LPSIZE size
)
274 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
275 if (!bmp
) return FALSE
;
281 /***********************************************************************
282 * GetBitmapDimension (GDI.162)
284 DWORD
GetBitmapDimension( HBITMAP hbitmap
)
287 if (!GetBitmapDimensionEx( hbitmap
, &size
)) return 0;
288 return size
.cx
| (size
.cy
<< 16);
291 /***********************************************************************
292 * SetBitmapDimensionEx (GDI.478)
294 BOOL
SetBitmapDimensionEx( HBITMAP hbitmap
, short x
, short y
, LPSIZE prevSize
)
296 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
297 if (!bmp
) return FALSE
;
298 if (prevSize
) *prevSize
= bmp
->size
;
305 /***********************************************************************
306 * SetBitmapDimension (GDI.163)
308 DWORD
SetBitmapDimension( HBITMAP hbitmap
, short x
, short y
)
311 if (!SetBitmapDimensionEx( hbitmap
, x
, y
, &size
)) return 0;
312 return size
.cx
| (size
.cy
<< 16);