2 * X11DRV bitmap objects
4 * Copyright 1993 Alexandre Julliard
9 #ifndef X_DISPLAY_MISSING
26 #include "wine/winuser16.h"
28 /* GCs used for B&W and color bitmap operations */
29 GC BITMAP_monoGC
= 0, BITMAP_colorGC
= 0;
32 /***********************************************************************
35 BOOL
X11DRV_BITMAP_Init(void)
39 /* Create the necessary GCs */
41 if ((tmpPixmap
= TSXCreatePixmap(display
,
42 X11DRV_GetXRootWindow(),
46 BITMAP_monoGC
= TSXCreateGC( display
, tmpPixmap
, 0, NULL
);
47 TSXSetGraphicsExposures( display
, BITMAP_monoGC
, False
);
48 TSXFreePixmap( display
, tmpPixmap
);
51 if (MONITOR_GetDepth(&MONITOR_PrimaryMonitor
) != 1)
53 if ((tmpPixmap
= TSXCreatePixmap(display
,
54 X11DRV_GetXRootWindow(),
56 MONITOR_GetDepth(&MONITOR_PrimaryMonitor
))))
58 BITMAP_colorGC
= TSXCreateGC( display
, tmpPixmap
, 0, NULL
);
59 TSXSetGraphicsExposures( display
, BITMAP_colorGC
, False
);
60 TSXFreePixmap( display
, tmpPixmap
);
66 /***********************************************************************
67 * X11DRV_BITMAP_SelectObject
69 HBITMAP
X11DRV_BITMAP_SelectObject( DC
* dc
, HBITMAP hbitmap
,
73 HBITMAP prevHandle
= dc
->w
.hBitmap
;
74 X11DRV_PHYSBITMAP
*pbitmap
;
75 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
78 if (!(dc
->w
.flags
& DC_MEMORY
)) return 0;
81 if(!X11DRV_CreateBitmap(hbitmap
))
84 if(bmp
->DDBitmap
->funcs
!= dc
->funcs
) {
85 WARN(x11drv
, "Trying to select non-X11 DDB into an X11 dc\n");
89 pbitmap
= bmp
->DDBitmap
->physBitmap
;
91 dc
->w
.totalExtent
.left
= 0;
92 dc
->w
.totalExtent
.top
= 0;
93 dc
->w
.totalExtent
.right
= bmp
->bitmap
.bmWidth
;
94 dc
->w
.totalExtent
.bottom
= bmp
->bitmap
.bmHeight
;
97 SetRectRgn( dc
->w
.hVisRgn
, 0, 0,
98 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
101 hrgn
= CreateRectRgn(0, 0, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
103 dc
->w
.hVisRgn
= hrgn
;
106 physDev
->drawable
= pbitmap
->pixmap
;
107 dc
->w
.hBitmap
= hbitmap
;
109 /* Change GC depth if needed */
111 if (dc
->w
.bitsPerPixel
!= bmp
->bitmap
.bmBitsPixel
)
113 TSXFreeGC( display
, physDev
->gc
);
114 physDev
->gc
= TSXCreateGC( display
, physDev
->drawable
, 0, NULL
);
115 TSXSetGraphicsExposures( display
, physDev
->gc
, False
);
116 dc
->w
.bitsPerPixel
= bmp
->bitmap
.bmBitsPixel
;
119 else CLIPPING_UpdateGCRegion( dc
); /* Just update GC clip region */
124 /***********************************************************************
127 * Wrapper to call XPutImage with CALL_LARGE_STACK.
130 struct XPutImage_descr
138 static int XPutImage_wrapper( const struct XPutImage_descr
*descr
)
140 return XPutImage( display
,
141 ((X11DRV_PHYSBITMAP
*)descr
->bmp
->DDBitmap
->physBitmap
)->pixmap
,
142 BITMAP_GC(descr
->bmp
),
143 descr
->image
, 0, 0, 0, 0, descr
->width
, descr
->height
);
147 /***************************************************************************
151 * Allocate DDBitmap and physBitmap
154 X11DRV_PHYSBITMAP
*X11DRV_AllocBitmap( BITMAPOBJ
*bmp
)
156 X11DRV_PHYSBITMAP
*pbitmap
;
158 if(!(bmp
->DDBitmap
= HeapAlloc(GetProcessHeap(), 0, sizeof(DDBITMAP
)))) {
159 WARN(x11drv
, "Can't alloc DDBITMAP\n");
163 if(!(pbitmap
= HeapAlloc(GetProcessHeap(), 0,sizeof(X11DRV_PHYSBITMAP
)))) {
164 WARN(x11drv
, "Can't alloc X11DRV_PHYSBITMAP\n");
165 HeapFree(GetProcessHeap(), 0, bmp
->DDBitmap
);
169 bmp
->DDBitmap
->physBitmap
= pbitmap
;
170 bmp
->DDBitmap
->funcs
= DRIVER_FindDriver( "DISPLAY" );
175 /****************************************************************************
177 * X11DRV_CreateBitmap
179 * Create a device dependent X11 bitmap
181 * Returns TRUE on success else FALSE
185 BOOL
X11DRV_CreateBitmap( HBITMAP hbitmap
)
187 X11DRV_PHYSBITMAP
*pbitmap
;
188 BITMAPOBJ
*bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
191 WARN(x11drv
, "Bad bitmap handle %08x\n", hbitmap
);
195 /* Check parameters */
196 if (bmp
->bitmap
.bmPlanes
!= 1) return 0;
197 if ((bmp
->bitmap
.bmBitsPixel
!= 1) &&
198 (bmp
->bitmap
.bmBitsPixel
!= MONITOR_GetDepth(&MONITOR_PrimaryMonitor
))) {
199 ERR(x11drv
, "Trying to make bitmap with planes=%d, bpp=%d\n",
200 bmp
->bitmap
.bmPlanes
, bmp
->bitmap
.bmBitsPixel
);
201 GDI_HEAP_UNLOCK( hbitmap
);
205 TRACE(x11drv
, "(%08x) %dx%d %d bpp\n", hbitmap
, bmp
->bitmap
.bmWidth
,
206 bmp
->bitmap
.bmHeight
, bmp
->bitmap
.bmBitsPixel
);
208 pbitmap
= X11DRV_AllocBitmap( bmp
);
209 if(!pbitmap
) return FALSE
;
211 /* Create the pixmap */
212 pbitmap
->pixmap
= TSXCreatePixmap(display
, X11DRV_GetXRootWindow(), bmp
->bitmap
.bmWidth
,
213 bmp
->bitmap
.bmHeight
, bmp
->bitmap
.bmBitsPixel
);
214 if (!pbitmap
->pixmap
) {
215 WARN(x11drv
, "Can't create Pixmap\n");
216 HeapFree(GetProcessHeap(), 0, bmp
->DDBitmap
->physBitmap
);
217 HeapFree(GetProcessHeap(), 0, bmp
->DDBitmap
);
218 GDI_HEAP_UNLOCK( hbitmap
);
222 if (bmp
->bitmap
.bmBits
) /* Set bitmap bits */
223 X11DRV_BitmapBits( hbitmap
, bmp
->bitmap
.bmBits
,
224 bmp
->bitmap
.bmHeight
* bmp
->bitmap
.bmWidthBytes
,
227 GDI_HEAP_UNLOCK( hbitmap
);
232 /***********************************************************************
233 * X11DRV_BITMAP_GetXImage
235 * Get an X image for a bitmap. For use with CALL_LARGE_STACK.
237 XImage
*X11DRV_BITMAP_GetXImage( const BITMAPOBJ
*bmp
)
239 return XGetImage( display
,
240 ((X11DRV_PHYSBITMAP
*)bmp
->DDBitmap
->physBitmap
)->pixmap
,
241 0, 0, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
242 AllPlanes
, ZPixmap
);
246 /***********************************************************************
247 * X11DRV_GetBitmapBits
250 * Success: Number of bytes copied
253 static LONG
X11DRV_GetBitmapBits(BITMAPOBJ
*bmp
, void *buffer
, LONG count
)
255 LONG old_height
, height
;
257 LPBYTE tbuf
, startline
;
260 TRACE(x11drv
, "(bmp=%p, buffer=%p, count=0x%lx)\n", bmp
, buffer
, count
);
262 EnterCriticalSection( &X11DRV_CritSection
);
264 /* Hack: change the bitmap height temporarily to avoid */
265 /* getting unnecessary bitmap rows. */
267 old_height
= bmp
->bitmap
.bmHeight
;
268 height
= bmp
->bitmap
.bmHeight
= count
/ bmp
->bitmap
.bmWidthBytes
;
270 image
= (XImage
*)CALL_LARGE_STACK( X11DRV_BITMAP_GetXImage
, bmp
);
272 bmp
->bitmap
.bmHeight
= old_height
;
274 /* copy XImage to 16 bit padded image buffer with real bitsperpixel */
277 switch (bmp
->bitmap
.bmBitsPixel
)
280 for (h
=0;h
<height
;h
++)
284 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
288 *tbuf
|= XGetPixel(image
,w
,h
)<<(7-(w
&7));
289 if ((w
&7) == 7) ++tbuf
;
291 startline
+= bmp
->bitmap
.bmWidthBytes
;
295 for (h
=0;h
<height
;h
++)
298 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
300 if (!(w
& 1)) *tbuf
= XGetPixel( image
, w
, h
) << 4;
301 else *tbuf
++ |= XGetPixel( image
, w
, h
) & 0x0f;
303 startline
+= bmp
->bitmap
.bmWidthBytes
;
307 for (h
=0;h
<height
;h
++)
310 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
311 *tbuf
++ = XGetPixel(image
,w
,h
);
312 startline
+= bmp
->bitmap
.bmWidthBytes
;
317 for (h
=0;h
<height
;h
++)
320 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
322 long pixel
= XGetPixel(image
,w
,h
);
324 *tbuf
++ = pixel
& 0xff;
325 *tbuf
++ = (pixel
>>8) & 0xff;
327 startline
+= bmp
->bitmap
.bmWidthBytes
;
331 for (h
=0;h
<height
;h
++)
334 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
336 long pixel
= XGetPixel(image
,w
,h
);
338 *tbuf
++ = pixel
& 0xff;
339 *tbuf
++ = (pixel
>> 8) & 0xff;
340 *tbuf
++ = (pixel
>>16) & 0xff;
342 startline
+= bmp
->bitmap
.bmWidthBytes
;
347 for (h
=0;h
<height
;h
++)
350 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
352 long pixel
= XGetPixel(image
,w
,h
);
354 *tbuf
++ = pixel
& 0xff;
355 *tbuf
++ = (pixel
>> 8) & 0xff;
356 *tbuf
++ = (pixel
>>16) & 0xff;
357 *tbuf
++ = (pixel
>>24) & 0xff;
359 startline
+= bmp
->bitmap
.bmWidthBytes
;
363 FIXME(x11drv
, "Unhandled bits:%d\n", bmp
->bitmap
.bmBitsPixel
);
365 XDestroyImage( image
);
366 LeaveCriticalSection( &X11DRV_CritSection
);
373 /******************************************************************************
374 * X11DRV_SetBitmapBits
377 * Success: Number of bytes used in setting the bitmap bits
380 static LONG
X11DRV_SetBitmapBits(BITMAPOBJ
*bmp
, void *bits
, LONG count
)
382 struct XPutImage_descr descr
;
385 LPBYTE sbuf
, startline
;
388 TRACE(x11drv
, "(bmp=%p, bits=%p, count=0x%lx)\n", bmp
, bits
, count
);
390 height
= count
/ bmp
->bitmap
.bmWidthBytes
;
392 EnterCriticalSection( &X11DRV_CritSection
);
393 image
= XCreateImage( display
, DefaultVisualOfScreen(X11DRV_GetXScreen()),
394 bmp
->bitmap
.bmBitsPixel
, ZPixmap
, 0, NULL
,
395 bmp
->bitmap
.bmWidth
, height
, 32, 0 );
396 image
->data
= (LPBYTE
)xmalloc(image
->bytes_per_line
* height
);
398 /* copy 16 bit padded image buffer with real bitsperpixel to XImage */
402 switch (bmp
->bitmap
.bmBitsPixel
)
405 for (h
=0;h
<height
;h
++)
408 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
410 XPutPixel(image
,w
,h
,(sbuf
[0]>>(7-(w
&7))) & 1);
414 startline
+= bmp
->bitmap
.bmWidthBytes
;
418 for (h
=0;h
<height
;h
++)
421 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
423 if (!(w
& 1)) XPutPixel( image
, w
, h
, *sbuf
>> 4 );
424 else XPutPixel( image
, w
, h
, *sbuf
++ & 0xf );
426 startline
+= bmp
->bitmap
.bmWidthBytes
;
430 for (h
=0;h
<height
;h
++)
433 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
434 XPutPixel(image
,w
,h
,*sbuf
++);
435 startline
+= bmp
->bitmap
.bmWidthBytes
;
440 for (h
=0;h
<height
;h
++)
443 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
445 XPutPixel(image
,w
,h
,sbuf
[1]*256+sbuf
[0]);
448 startline
+= bmp
->bitmap
.bmWidthBytes
;
452 for (h
=0;h
<height
;h
++)
455 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
457 XPutPixel(image
,w
,h
,(sbuf
[2]<<16)+(sbuf
[1]<<8)+sbuf
[0]);
460 startline
+= bmp
->bitmap
.bmWidthBytes
;
464 for (h
=0;h
<height
;h
++)
467 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
469 XPutPixel(image
,w
,h
,(sbuf
[3]<<24)+(sbuf
[2]<<16)+(sbuf
[1]<<8)+sbuf
[0]);
472 startline
+= bmp
->bitmap
.bmWidthBytes
;
476 FIXME(x11drv
, "Unhandled bits:%d\n", bmp
->bitmap
.bmBitsPixel
);
482 descr
.width
= bmp
->bitmap
.bmWidth
;
483 descr
.height
= height
;
485 CALL_LARGE_STACK( XPutImage_wrapper
, &descr
);
486 XDestroyImage( image
); /* frees image->data too */
487 LeaveCriticalSection( &X11DRV_CritSection
);
492 /***********************************************************************
495 LONG
X11DRV_BitmapBits(HBITMAP hbitmap
, void *bits
, LONG count
, WORD flags
)
497 BITMAPOBJ
*bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
500 WARN(x11drv
, "Bad bitmap handle %08x\n", hbitmap
);
505 ret
= X11DRV_GetBitmapBits(bmp
, bits
, count
);
506 else if(flags
== DDB_SET
)
507 ret
= X11DRV_SetBitmapBits(bmp
, bits
, count
);
509 ERR(x11drv
, "Unknown flags value %d\n", flags
);
513 GDI_HEAP_UNLOCK( hbitmap
);
517 /***********************************************************************
518 * X11DRV_BITMAP_DeleteObject
520 BOOL
X11DRV_BITMAP_DeleteObject( HBITMAP hbitmap
, BITMAPOBJ
* bmp
)
522 X11DRV_PHYSBITMAP
*pbitmap
= bmp
->DDBitmap
->physBitmap
;
524 TSXFreePixmap( display
, pbitmap
->pixmap
);
526 HeapFree( GetProcessHeap(), 0, bmp
->DDBitmap
->physBitmap
);
527 HeapFree( GetProcessHeap(), 0, bmp
->DDBitmap
);
528 bmp
->DDBitmap
= NULL
;
533 /***********************************************************************
534 * X11DRV_BITMAP_Pixmap
536 * This function exists solely for x11 driver of the window system.
538 BOOL
X11DRV_BITMAP_Pixmap(HBITMAP hbitmap
)
540 BITMAPOBJ
*bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
541 return ((X11DRV_PHYSBITMAP
*)(bmp
->DDBitmap
->physBitmap
))->pixmap
;
544 #endif /* !defined(X_DISPLAY_MISSING) */