2 * X11DRV bitmap objects
4 * Copyright 1993 Alexandre Julliard
20 /* GCs used for B&W and color bitmap operations */
21 GC BITMAP_monoGC
= 0, BITMAP_colorGC
= 0;
24 /***********************************************************************
27 BOOL32
X11DRV_BITMAP_Init(void)
31 /* Create the necessary GCs */
33 if ((tmpPixmap
= TSXCreatePixmap( display
, rootWindow
, 1, 1, 1 )))
35 BITMAP_monoGC
= TSXCreateGC( display
, tmpPixmap
, 0, NULL
);
36 TSXSetGraphicsExposures( display
, BITMAP_monoGC
, False
);
37 TSXFreePixmap( display
, tmpPixmap
);
42 if ((tmpPixmap
= TSXCreatePixmap(display
, rootWindow
, 1,1,screenDepth
)))
44 BITMAP_colorGC
= TSXCreateGC( display
, tmpPixmap
, 0, NULL
);
45 TSXSetGraphicsExposures( display
, BITMAP_colorGC
, False
);
46 TSXFreePixmap( display
, tmpPixmap
);
52 /***********************************************************************
53 * X11DRV_BITMAP_SelectObject
55 HBITMAP32
X11DRV_BITMAP_SelectObject( DC
* dc
, HBITMAP32 hbitmap
,
59 HBITMAP32 prevHandle
= dc
->w
.hBitmap
;
60 X11DRV_PHYSBITMAP
*pbitmap
;
61 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
64 if (!(dc
->w
.flags
& DC_MEMORY
)) return 0;
67 if(!X11DRV_CreateBitmap(hbitmap
))
70 if(bmp
->DDBitmap
->funcs
!= dc
->funcs
) {
71 WARN(x11drv
, "Trying to select non-X11 DDB into an X11 dc\n");
75 pbitmap
= bmp
->DDBitmap
->physBitmap
;
77 dc
->w
.totalExtent
.left
= 0;
78 dc
->w
.totalExtent
.top
= 0;
79 dc
->w
.totalExtent
.right
= bmp
->bitmap
.bmWidth
;
80 dc
->w
.totalExtent
.bottom
= bmp
->bitmap
.bmHeight
;
83 SetRectRgn32( dc
->w
.hVisRgn
, 0, 0,
84 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
87 hrgn
= CreateRectRgn32(0, 0, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
92 physDev
->drawable
= pbitmap
->pixmap
;
93 dc
->w
.hBitmap
= hbitmap
;
95 /* Change GC depth if needed */
97 if (dc
->w
.bitsPerPixel
!= bmp
->bitmap
.bmBitsPixel
)
99 TSXFreeGC( display
, physDev
->gc
);
100 physDev
->gc
= TSXCreateGC( display
, physDev
->drawable
, 0, NULL
);
101 dc
->w
.bitsPerPixel
= bmp
->bitmap
.bmBitsPixel
;
104 else CLIPPING_UpdateGCRegion( dc
); /* Just update GC clip region */
109 /***********************************************************************
112 * Wrapper to call XPutImage with CALL_LARGE_STACK.
115 struct XPutImage_descr
123 static int XPutImage_wrapper( const struct XPutImage_descr
*descr
)
125 return XPutImage( display
,
126 ((X11DRV_PHYSBITMAP
*)descr
->bmp
->DDBitmap
->physBitmap
)->pixmap
,
127 BITMAP_GC(descr
->bmp
),
128 descr
->image
, 0, 0, 0, 0, descr
->width
, descr
->height
);
132 /***************************************************************************
136 * Allocate DDBitmap and physBitmap
139 X11DRV_PHYSBITMAP
*X11DRV_AllocBitmap( BITMAPOBJ
*bmp
)
141 X11DRV_PHYSBITMAP
*pbitmap
;
143 if(!(bmp
->DDBitmap
= HeapAlloc(GetProcessHeap(), 0, sizeof(DDBITMAP
)))) {
144 WARN(x11drv
, "Can't alloc DDBITMAP\n");
148 if(!(pbitmap
= HeapAlloc(GetProcessHeap(), 0,sizeof(X11DRV_PHYSBITMAP
)))) {
149 WARN(x11drv
, "Can't alloc X11DRV_PHYSBITMAP\n");
150 HeapFree(GetProcessHeap(), 0, bmp
->DDBitmap
);
154 bmp
->DDBitmap
->physBitmap
= pbitmap
;
155 bmp
->DDBitmap
->funcs
= DRIVER_FindDriver( "DISPLAY" );
160 /****************************************************************************
162 * X11DRV_CreateBitmap
164 * Create a device dependent X11 bitmap
166 * Returns TRUE on success else FALSE
170 BOOL32
X11DRV_CreateBitmap( HBITMAP32 hbitmap
)
172 X11DRV_PHYSBITMAP
*pbitmap
;
173 BITMAPOBJ
*bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
176 WARN(x11drv
, "Bad bitmap handle %08x\n", hbitmap
);
180 /* Check parameters */
181 if (bmp
->bitmap
.bmPlanes
!= 1) return 0;
182 if ((bmp
->bitmap
.bmBitsPixel
!= 1) &&
183 (bmp
->bitmap
.bmBitsPixel
!= screenDepth
)) {
184 ERR(x11drv
, "Trying to make bitmap with planes=%d, bpp=%d\n",
185 bmp
->bitmap
.bmPlanes
, bmp
->bitmap
.bmBitsPixel
);
186 GDI_HEAP_UNLOCK( hbitmap
);
190 TRACE(x11drv
, "(%08x) %dx%d %d bpp\n", hbitmap
, bmp
->bitmap
.bmWidth
,
191 bmp
->bitmap
.bmHeight
, bmp
->bitmap
.bmBitsPixel
);
193 pbitmap
= X11DRV_AllocBitmap( bmp
);
194 if(!pbitmap
) return FALSE
;
196 /* Create the pixmap */
197 pbitmap
->pixmap
= TSXCreatePixmap(display
, rootWindow
, bmp
->bitmap
.bmWidth
,
198 bmp
->bitmap
.bmHeight
, bmp
->bitmap
.bmBitsPixel
);
199 if (!pbitmap
->pixmap
) {
200 WARN(x11drv
, "Can't create Pixmap\n");
201 HeapFree(GetProcessHeap(), 0, bmp
->DDBitmap
->physBitmap
);
202 HeapFree(GetProcessHeap(), 0, bmp
->DDBitmap
);
203 GDI_HEAP_UNLOCK( hbitmap
);
207 if (bmp
->bitmap
.bmBits
) /* Set bitmap bits */
208 X11DRV_BitmapBits( hbitmap
, bmp
->bitmap
.bmBits
,
209 bmp
->bitmap
.bmHeight
* bmp
->bitmap
.bmWidthBytes
,
212 GDI_HEAP_UNLOCK( hbitmap
);
217 /***********************************************************************
218 * X11DRV_BITMAP_GetXImage
220 * Get an X image for a bitmap. For use with CALL_LARGE_STACK.
222 XImage
*X11DRV_BITMAP_GetXImage( const BITMAPOBJ
*bmp
)
224 return XGetImage( display
,
225 ((X11DRV_PHYSBITMAP
*)bmp
->DDBitmap
->physBitmap
)->pixmap
,
226 0, 0, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
227 AllPlanes
, ZPixmap
);
231 /***********************************************************************
232 * X11DRV_GetBitmapBits
235 * Success: Number of bytes copied
238 static LONG
X11DRV_GetBitmapBits(BITMAPOBJ
*bmp
, void *buffer
, LONG count
)
240 LONG old_height
, height
;
245 TRACE(x11drv
, "(bmp=%p, buffer=%p, count=0x%lx)\n", bmp
, buffer
, count
);
247 pad
= BITMAP_GetPadding(bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmBitsPixel
);
252 EnterCriticalSection( &X11DRV_CritSection
);
254 /* Hack: change the bitmap height temporarily to avoid */
255 /* getting unnecessary bitmap rows. */
257 old_height
= bmp
->bitmap
.bmHeight
;
258 height
= bmp
->bitmap
.bmHeight
= count
/ bmp
->bitmap
.bmWidthBytes
;
260 image
= (XImage
*)CALL_LARGE_STACK( X11DRV_BITMAP_GetXImage
, bmp
);
262 bmp
->bitmap
.bmHeight
= old_height
;
264 /* copy XImage to 16 bit padded image buffer with real bitsperpixel */
267 switch (bmp
->bitmap
.bmBitsPixel
)
270 for (h
=0;h
<height
;h
++)
273 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
277 *tbuf
|= XGetPixel(image
,w
,h
)<<(7-(w
&7));
278 if ((w
&7) == 7) ++tbuf
;
284 for (h
=0;h
<height
;h
++)
286 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
288 if (!(w
& 1)) *tbuf
= XGetPixel( image
, w
, h
) << 4;
289 else *tbuf
++ |= XGetPixel( image
, w
, h
) & 0x0f;
295 for (h
=0;h
<height
;h
++)
297 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
298 *tbuf
++ = XGetPixel(image
,w
,h
);
304 for (h
=0;h
<height
;h
++)
306 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
308 long pixel
= XGetPixel(image
,w
,h
);
310 *tbuf
++ = pixel
& 0xff;
311 *tbuf
++ = (pixel
>>8) & 0xff;
316 for (h
=0;h
<height
;h
++)
318 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
320 long pixel
= XGetPixel(image
,w
,h
);
322 *tbuf
++ = pixel
& 0xff;
323 *tbuf
++ = (pixel
>> 8) & 0xff;
324 *tbuf
++ = (pixel
>>16) & 0xff;
331 for (h
=0;h
<height
;h
++)
333 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
335 long pixel
= XGetPixel(image
,w
,h
);
337 *tbuf
++ = pixel
& 0xff;
338 *tbuf
++ = (pixel
>> 8) & 0xff;
339 *tbuf
++ = (pixel
>>16) & 0xff;
340 *tbuf
++ = (pixel
>>24) & 0xff;
346 FIXME(x11drv
, "Unhandled bits:%d\n", bmp
->bitmap
.bmBitsPixel
);
348 XDestroyImage( image
);
349 LeaveCriticalSection( &X11DRV_CritSection
);
356 /******************************************************************************
357 * X11DRV_SetBitmapBits
360 * Success: Number of bytes used in setting the bitmap bits
363 static LONG
X11DRV_SetBitmapBits(BITMAPOBJ
*bmp
, void *bits
, LONG count
)
365 struct XPutImage_descr descr
;
371 TRACE(x11drv
, "(bmp=%p, bits=%p, count=0x%lx)\n", bmp
, bits
, count
);
373 pad
= BITMAP_GetPadding(bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmBitsPixel
);
380 height
= count
/ bmp
->bitmap
.bmWidthBytes
;
382 EnterCriticalSection( &X11DRV_CritSection
);
383 image
= XCreateImage( display
, DefaultVisualOfScreen(screen
),
384 bmp
->bitmap
.bmBitsPixel
, ZPixmap
, 0, NULL
,
385 bmp
->bitmap
.bmWidth
, height
, 32, 0 );
386 image
->data
= (LPBYTE
)xmalloc(image
->bytes_per_line
* height
);
388 /* copy 16 bit padded image buffer with real bitsperpixel to XImage */
390 switch (bmp
->bitmap
.bmBitsPixel
)
393 for (h
=0;h
<height
;h
++)
395 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
397 XPutPixel(image
,w
,h
,(sbuf
[0]>>(7-(w
&7))) & 1);
405 for (h
=0;h
<height
;h
++)
407 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
409 if (!(w
& 1)) XPutPixel( image
, w
, h
, *sbuf
>> 4 );
410 else XPutPixel( image
, w
, h
, *sbuf
++ & 0xf );
416 for (h
=0;h
<height
;h
++)
418 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
419 XPutPixel(image
,w
,h
,*sbuf
++);
425 for (h
=0;h
<height
;h
++)
427 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
429 XPutPixel(image
,w
,h
,sbuf
[1]*256+sbuf
[0]);
435 for (h
=0;h
<height
;h
++)
437 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
439 XPutPixel(image
,w
,h
,(sbuf
[2]<<16)+(sbuf
[1]<<8)+sbuf
[0]);
446 for (h
=0;h
<height
;h
++)
448 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
450 XPutPixel(image
,w
,h
,(sbuf
[3]<<24)+(sbuf
[2]<<16)+(sbuf
[1]<<8)+sbuf
[0]);
457 FIXME(x11drv
, "Unhandled bits:%d\n", bmp
->bitmap
.bmBitsPixel
);
463 descr
.width
= bmp
->bitmap
.bmWidth
;
464 descr
.height
= height
;
466 CALL_LARGE_STACK( XPutImage_wrapper
, &descr
);
467 XDestroyImage( image
); /* frees image->data too */
468 LeaveCriticalSection( &X11DRV_CritSection
);
473 /***********************************************************************
476 LONG
X11DRV_BitmapBits(HBITMAP32 hbitmap
, void *bits
, LONG count
, WORD flags
)
478 BITMAPOBJ
*bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
481 WARN(x11drv
, "Bad bitmap handle %08x\n", hbitmap
);
486 ret
= X11DRV_GetBitmapBits(bmp
, bits
, count
);
487 else if(flags
== DDB_SET
)
488 ret
= X11DRV_SetBitmapBits(bmp
, bits
, count
);
490 ERR(x11drv
, "Unknown flags value %d\n", flags
);
494 GDI_HEAP_UNLOCK( hbitmap
);
498 /***********************************************************************
499 * X11DRV_BITMAP_DeleteObject
501 BOOL32
X11DRV_BITMAP_DeleteObject( HBITMAP32 hbitmap
, BITMAPOBJ
* bmp
)
503 X11DRV_PHYSBITMAP
*pbitmap
= bmp
->DDBitmap
->physBitmap
;
505 TSXFreePixmap( display
, pbitmap
->pixmap
);
507 HeapFree( GetProcessHeap(), 0, bmp
->DDBitmap
->physBitmap
);
508 HeapFree( GetProcessHeap(), 0, bmp
->DDBitmap
);
509 bmp
->DDBitmap
= NULL
;