4 * Copyright 1993 Alexandre Julliard
10 #include <X11/Xutil.h>
19 #ifdef PRELIMINARY_WING16_SUPPORT
20 #include <sys/types.h>
25 /* GCs used for B&W and color bitmap operations */
26 GC BITMAP_monoGC
= 0, BITMAP_colorGC
= 0;
28 extern void CLIPPING_UpdateGCRegion( DC
* dc
); /* objects/clipping.c */
30 /***********************************************************************
33 BOOL32
BITMAP_Init(void)
37 /* Create the necessary GCs */
39 if ((tmpPixmap
= XCreatePixmap( display
, rootWindow
, 1, 1, 1 )))
41 BITMAP_monoGC
= XCreateGC( display
, tmpPixmap
, 0, NULL
);
42 XSetGraphicsExposures( display
, BITMAP_monoGC
, False
);
43 XFreePixmap( display
, tmpPixmap
);
48 if ((tmpPixmap
= XCreatePixmap(display
, rootWindow
, 1,1,screenDepth
)))
50 BITMAP_colorGC
= XCreateGC( display
, tmpPixmap
, 0, NULL
);
51 XSetGraphicsExposures( display
, BITMAP_colorGC
, False
);
52 XFreePixmap( display
, tmpPixmap
);
59 /***********************************************************************
62 * Create an XImage pointing to the bitmap data.
64 static XImage
*BITMAP_BmpToImage( BITMAP16
* bmp
, LPVOID bmpData
)
66 extern void _XInitImageFuncPtrs( XImage
* );
69 image
= XCreateImage( display
, DefaultVisualOfScreen(screen
),
70 bmp
->bmBitsPixel
, ZPixmap
, 0, bmpData
,
71 bmp
->bmWidth
, bmp
->bmHeight
, 16, bmp
->bmWidthBytes
);
73 image
->byte_order
= MSBFirst
;
74 image
->bitmap_bit_order
= MSBFirst
;
75 image
->bitmap_unit
= 16;
76 _XInitImageFuncPtrs(image
);
81 /***********************************************************************
82 * CreateBitmap (GDI.48) (GDI32.25)
84 HBITMAP16
CreateBitmap( INT32 width
, INT32 height
, UINT32 planes
,
85 UINT32 bpp
, LPCVOID bits
)
87 BITMAPOBJ
* bmpObjPtr
;
90 planes
= (BYTE
)planes
;
93 dprintf_gdi( stddeb
, "CreateBitmap: %dx%d, %d colors\n",
94 width
, height
, 1 << (planes
*bpp
) );
96 /* Check parameters */
97 if (!height
|| !width
|| planes
!= 1) return 0;
98 if ((bpp
!= 1) && (bpp
!= screenDepth
)) return 0;
99 if (height
< 0) height
= -height
;
100 if (width
< 0) width
= -width
;
102 /* Create the BITMAPOBJ */
103 hbitmap
= GDI_AllocObject( sizeof(BITMAPOBJ
), BITMAP_MAGIC
);
104 if (!hbitmap
) return 0;
105 bmpObjPtr
= (BITMAPOBJ
*) GDI_HEAP_LIN_ADDR( hbitmap
);
107 bmpObjPtr
->size
.cx
= 0;
108 bmpObjPtr
->size
.cy
= 0;
109 bmpObjPtr
->bitmap
.bmType
= 0;
110 bmpObjPtr
->bitmap
.bmWidth
= (INT16
)width
;
111 bmpObjPtr
->bitmap
.bmHeight
= (INT16
)height
;
112 bmpObjPtr
->bitmap
.bmPlanes
= (BYTE
)planes
;
113 bmpObjPtr
->bitmap
.bmBitsPixel
= (BYTE
)bpp
;
114 bmpObjPtr
->bitmap
.bmWidthBytes
= (INT16
)BITMAP_WIDTH_BYTES( width
, bpp
);
115 bmpObjPtr
->bitmap
.bmBits
= NULL
;
117 /* Create the pixmap */
118 bmpObjPtr
->pixmap
= XCreatePixmap(display
, rootWindow
, width
, height
, bpp
);
119 if (!bmpObjPtr
->pixmap
)
121 GDI_HEAP_FREE( hbitmap
);
124 else if (bits
) /* Set bitmap bits */
125 SetBitmapBits( hbitmap
, height
* bmpObjPtr
->bitmap
.bmWidthBytes
, bits
);
130 /***********************************************************************
131 * CreateCompatibleBitmap (GDI.51) (GDI32.30)
133 HBITMAP16
CreateCompatibleBitmap( HDC32 hdc
, INT32 width
, INT32 height
)
135 HBITMAP16 hbmpRet
= 0;
138 dprintf_gdi( stddeb
, "CreateCompatibleBitmap(%04x,%d,%d) = \n",
139 hdc
, width
, height
);
140 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
143 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
146 hbmpRet
= CreateBitmap( width
, height
, 1, dc
->w
.bitsPerPixel
, NULL
);
147 dprintf_gdi(stddeb
,"\t\t%04x\n", hbmpRet
);
152 /***********************************************************************
153 * CreateBitmapIndirect16 (GDI.49)
155 HBITMAP16
CreateBitmapIndirect16( const BITMAP16
* bmp
)
157 return CreateBitmap( bmp
->bmWidth
, bmp
->bmHeight
, bmp
->bmPlanes
,
158 bmp
->bmBitsPixel
, PTR_SEG_TO_LIN( bmp
->bmBits
) );
162 /***********************************************************************
163 * CreateBitmapIndirect32 (GDI32.26)
165 HBITMAP32
CreateBitmapIndirect32( const BITMAP32
* bmp
)
167 return CreateBitmap( bmp
->bmWidth
, bmp
->bmHeight
, bmp
->bmPlanes
,
168 bmp
->bmBitsPixel
, bmp
->bmBits
);
172 /***********************************************************************
173 * GetBitmapBits (GDI.74) (GDI32.143)
175 LONG
GetBitmapBits( HBITMAP32 hbitmap
, LONG count
, LPVOID buffer
)
183 fprintf(stderr
, "Negative number of bytes (%ld) passed to GetBitmapBits???\n", count
);
186 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
189 /* Only get entire lines */
190 height
= count
/ bmp
->bitmap
.bmWidthBytes
;
191 if (height
> bmp
->bitmap
.bmHeight
) height
= bmp
->bitmap
.bmHeight
;
192 dprintf_bitmap(stddeb
, "GetBitmapBits: %dx%d %d colors %p fetched height: %ld\n",
193 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
194 1 << bmp
->bitmap
.bmBitsPixel
, buffer
, height
);
195 if (!height
) return 0;
197 if (!(image
= BITMAP_BmpToImage( &bmp
->bitmap
, buffer
))) return 0;
198 CallTo32_LargeStack( (int(*)())XGetSubImage
, 11,
199 display
, bmp
->pixmap
, 0, 0, bmp
->bitmap
.bmWidth
,
200 height
, AllPlanes
, ZPixmap
, image
, 0, 0 );
202 XDestroyImage( image
);
203 return height
* bmp
->bitmap
.bmWidthBytes
;
207 /***********************************************************************
208 * SetBitmapBits (GDI.106) (GDI32.303)
210 LONG
SetBitmapBits( HBITMAP32 hbitmap
, LONG count
, LPCVOID buffer
)
218 fprintf(stderr
, "Negative number of bytes (%ld) passed to SetBitmapBits???\n", count
);
221 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
224 dprintf_bitmap(stddeb
, "SetBitmapBits: %dx%d %d colors %p\n",
225 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
226 1 << bmp
->bitmap
.bmBitsPixel
, buffer
);
228 /* Only set entire lines */
229 height
= count
/ bmp
->bitmap
.bmWidthBytes
;
230 if (height
> bmp
->bitmap
.bmHeight
) height
= bmp
->bitmap
.bmHeight
;
231 if (!height
) return 0;
233 if (!(image
= BITMAP_BmpToImage( &bmp
->bitmap
, (LPVOID
)buffer
))) return 0;
234 CallTo32_LargeStack( XPutImage
, 10,
235 display
, bmp
->pixmap
, BITMAP_GC(bmp
), image
, 0, 0,
236 0, 0, bmp
->bitmap
.bmWidth
, height
);
238 XDestroyImage( image
);
239 return height
* bmp
->bitmap
.bmWidthBytes
;
242 /**********************************************************************
243 * LoadImageA (USER32.364)
244 * FIXME: implementation still lacks nearly all features, see LR_*
245 * defines in windows.h
248 HANDLE32
LoadImage32A(
249 HINSTANCE32 hinst
,LPCSTR name
,UINT32 type
,INT32 desiredx
,
250 INT32 desiredy
,UINT32 loadflags
253 dprintf_resource(stddeb
,"LoadImage32A(0x%04x,%s,%d,%d,%d,0x%08x)\n",
254 hinst
,name
,type
,desiredx
,desiredy
,loadflags
257 dprintf_resource(stddeb
,"LoadImage32A(0x%04x,%p,%d,%d,%d,0x%08x)\n",
258 hinst
,name
,type
,desiredx
,desiredy
,loadflags
263 return LoadBitmap32A(hinst
,name
);
265 return LoadIcon32A(hinst
,name
);
267 return LoadCursor32A(hinst
,name
);
272 /**********************************************************************
273 * CopyImage32 (USER32.60)
275 * FIXME: implementation still lacks nearly all features, see LR_*
276 * defines in windows.h
278 HANDLE32
CopyImage32( HANDLE32 hnd
, UINT32 type
, INT32 desiredx
,
279 INT32 desiredy
, UINT32 flags
)
284 return hnd
; /* FIXME ... need to copy here */
286 return CopyIcon32(hnd
);
288 return CopyCursor32(hnd
);
294 /**********************************************************************
295 * LoadBitmap16 (USER.175)
297 HBITMAP16
LoadBitmap16( HINSTANCE16 instance
, SEGPTR name
)
299 HBITMAP32 hbitmap
= 0;
307 char *str
= (char *)PTR_SEG_TO_LIN( name
);
308 dprintf_bitmap( stddeb
, "LoadBitmap16(%04x,'%s')\n", instance
, str
);
309 if (str
[0] == '#') name
= (SEGPTR
)(DWORD
)(WORD
)atoi( str
+ 1 );
312 dprintf_bitmap( stddeb
, "LoadBitmap16(%04x,%04x)\n",
313 instance
, LOWORD(name
) );
315 if (!instance
) /* OEM bitmap */
317 if (HIWORD((int)name
)) return 0;
318 return OBM_LoadBitmap( LOWORD((int)name
) );
321 if (!(hRsrc
= FindResource16( instance
, name
, RT_BITMAP
))) return 0;
322 if (!(handle
= LoadResource16( instance
, hRsrc
))) return 0;
324 info
= (BITMAPINFO
*)LockResource16( handle
);
325 if ((hdc
= GetDC32(0)) != 0)
327 char *bits
= (char *)info
+ DIB_BitmapInfoSize( info
, DIB_RGB_COLORS
);
328 hbitmap
= CreateDIBitmap32( hdc
, &info
->bmiHeader
, CBM_INIT
,
329 bits
, info
, DIB_RGB_COLORS
);
330 ReleaseDC32( 0, hdc
);
332 FreeResource16( handle
);
336 /**********************************************************************
337 * LoadBitmap32W (USER32.357)
339 HBITMAP32
LoadBitmap32W( HINSTANCE32 instance
, LPCWSTR name
)
341 HBITMAP32 hbitmap
= 0;
347 if (!instance
) /* OEM bitmap */
349 if (HIWORD((int)name
)) return 0;
350 return OBM_LoadBitmap( LOWORD((int)name
) );
353 if (!(hRsrc
= FindResource32W( instance
, name
,
354 (LPWSTR
)RT_BITMAP
))) return 0;
355 if (!(handle
= LoadResource32( instance
, hRsrc
))) return 0;
357 info
= (BITMAPINFO
*)LockResource32( handle
);
358 if ((hdc
= GetDC32(0)) != 0)
360 char *bits
= (char *)info
+ DIB_BitmapInfoSize( info
, DIB_RGB_COLORS
);
361 hbitmap
= CreateDIBitmap32( hdc
, &info
->bmiHeader
, CBM_INIT
,
362 bits
, info
, DIB_RGB_COLORS
);
363 ReleaseDC32( 0, hdc
);
369 /**********************************************************************
370 * LoadBitmap32A (USER32.356)
372 HBITMAP32
LoadBitmap32A( HINSTANCE32 instance
, LPCSTR name
)
375 if (!HIWORD(name
)) res
= LoadBitmap32W( instance
, (LPWSTR
)name
);
378 LPWSTR uni
= HEAP_strdupAtoW( GetProcessHeap(), 0, name
);
379 res
= LoadBitmap32W( instance
, uni
);
380 HeapFree( GetProcessHeap(), 0, uni
);
386 /***********************************************************************
387 * BITMAP_DeleteObject
389 BOOL32
BITMAP_DeleteObject( HBITMAP16 hbitmap
, BITMAPOBJ
* bmp
)
391 #ifdef PRELIMINARY_WING16_SUPPORT
392 if( bmp
->bitmap
.bmBits
)
393 XShmDetach( display
, (XShmSegmentInfo
*)bmp
->bitmap
.bmBits
);
396 XFreePixmap( display
, bmp
->pixmap
);
397 #ifdef PRELIMINARY_WING16_SUPPORT
398 if( bmp
->bitmap
.bmBits
)
400 __ShmBitmapCtl
* p
= (__ShmBitmapCtl
*)bmp
->bitmap
.bmBits
;
401 WORD sel
= HIWORD(p
->bits
);
402 unsigned long l
, limit
= GetSelectorLimit(sel
);
404 for( l
= 0; l
< limit
; l
+= 0x10000, sel
+= __AHINCR
)
406 shmctl(p
->si
.shmid
, IPC_RMID
, NULL
);
407 shmdt(p
->si
.shmaddr
); /* already marked for destruction */
410 return GDI_FreeObject( hbitmap
);
414 /***********************************************************************
417 INT16
BITMAP_GetObject16( BITMAPOBJ
* bmp
, INT16 count
, LPVOID buffer
)
419 if (count
> sizeof(bmp
->bitmap
)) count
= sizeof(bmp
->bitmap
);
420 memcpy( buffer
, &bmp
->bitmap
, count
);
425 /***********************************************************************
428 INT32
BITMAP_GetObject32( BITMAPOBJ
* bmp
, INT32 count
, LPVOID buffer
)
431 bmp32
.bmType
= bmp
->bitmap
.bmType
;
432 bmp32
.bmWidth
= bmp
->bitmap
.bmWidth
;
433 bmp32
.bmHeight
= bmp
->bitmap
.bmHeight
;
434 bmp32
.bmWidthBytes
= bmp
->bitmap
.bmWidthBytes
;
435 bmp32
.bmPlanes
= bmp
->bitmap
.bmPlanes
;
436 bmp32
.bmBitsPixel
= bmp
->bitmap
.bmBitsPixel
;
438 if (count
> sizeof(bmp32
)) count
= sizeof(bmp32
);
439 memcpy( buffer
, &bmp32
, count
);
444 /***********************************************************************
445 * BITMAP_SelectObject
447 HBITMAP16
BITMAP_SelectObject( DC
* dc
, HBITMAP16 hbitmap
,
451 HBITMAP16 prevHandle
= dc
->w
.hBitmap
;
453 if (!(dc
->w
.flags
& DC_MEMORY
)) return 0;
456 SetRectRgn(dc
->w
.hVisRgn
, 0, 0, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
459 hrgn
= CreateRectRgn32(0, 0, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
461 dc
->w
.hVisRgn
= hrgn
;
464 dc
->u
.x
.drawable
= bmp
->pixmap
;
465 dc
->w
.hBitmap
= hbitmap
;
467 /* Change GC depth if needed */
469 if (dc
->w
.bitsPerPixel
!= bmp
->bitmap
.bmBitsPixel
)
471 XFreeGC( display
, dc
->u
.x
.gc
);
472 dc
->u
.x
.gc
= XCreateGC( display
, dc
->u
.x
.drawable
, 0, NULL
);
473 dc
->w
.bitsPerPixel
= bmp
->bitmap
.bmBitsPixel
;
476 else CLIPPING_UpdateGCRegion( dc
); /* Just update GC clip region */
480 /***********************************************************************
481 * CreateDiscardableBitmap (GDI.156) (GDI32.38)
483 HBITMAP16
CreateDiscardableBitmap( HDC32 hdc
, INT32 width
, INT32 height
)
485 dprintf_bitmap(stddeb
,"CreateDiscardableBitmap(%04x, %d, %d); "
486 "// call CreateCompatibleBitmap() for now!\n",
488 return CreateCompatibleBitmap(hdc
, width
, height
);
492 /***********************************************************************
493 * GetBitmapDimensionEx16 (GDI.468)
495 BOOL16
GetBitmapDimensionEx16( HBITMAP16 hbitmap
, LPSIZE16 size
)
497 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
498 if (!bmp
) return FALSE
;
504 /***********************************************************************
505 * GetBitmapDimensionEx32 (GDI32.144)
507 BOOL32
GetBitmapDimensionEx32( HBITMAP32 hbitmap
, LPSIZE32 size
)
509 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
510 if (!bmp
) return FALSE
;
511 size
->cx
= (INT32
)bmp
->size
.cx
;
512 size
->cy
= (INT32
)bmp
->size
.cy
;
517 /***********************************************************************
518 * GetBitmapDimension (GDI.162)
520 DWORD
GetBitmapDimension( HBITMAP16 hbitmap
)
523 if (!GetBitmapDimensionEx16( hbitmap
, &size
)) return 0;
524 return MAKELONG( size
.cx
, size
.cy
);
528 /***********************************************************************
529 * SetBitmapDimensionEx16 (GDI.478)
531 BOOL16
SetBitmapDimensionEx16( HBITMAP16 hbitmap
, INT16 x
, INT16 y
,
534 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
535 if (!bmp
) return FALSE
;
536 if (prevSize
) *prevSize
= bmp
->size
;
543 /***********************************************************************
544 * SetBitmapDimensionEx32 (GDI32.304)
546 BOOL32
SetBitmapDimensionEx32( HBITMAP32 hbitmap
, INT32 x
, INT32 y
,
549 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
550 if (!bmp
) return FALSE
;
551 if (prevSize
) CONV_SIZE16TO32( &bmp
->size
, prevSize
);
552 bmp
->size
.cx
= (INT16
)x
;
553 bmp
->size
.cy
= (INT16
)y
;
558 /***********************************************************************
559 * SetBitmapDimension (GDI.163)
561 DWORD
SetBitmapDimension( HBITMAP16 hbitmap
, INT16 x
, INT16 y
)
564 if (!SetBitmapDimensionEx16( hbitmap
, x
, y
, &size
)) return 0;
565 return MAKELONG( size
.cx
, size
.cy
);