4 * Copyright 1993 Alexandre Julliard
11 #include <X11/Xutil.h>
20 #ifdef PRELIMINARY_WING16_SUPPORT
21 #include <sys/types.h>
26 /* GCs used for B&W and color bitmap operations */
27 GC BITMAP_monoGC
= 0, BITMAP_colorGC
= 0;
29 extern void CLIPPING_UpdateGCRegion( DC
* dc
); /* objects/clipping.c */
32 /***********************************************************************
33 * CreateBitmap16 (GDI.48)
35 HBITMAP16
CreateBitmap16( INT16 width
, INT16 height
, UINT16 planes
,
36 UINT16 bpp
, LPCVOID bits
)
38 return CreateBitmap32( width
, height
, planes
, bpp
, bits
);
42 /***********************************************************************
43 * CreateBitmap32 (GDI32.25)
45 HBITMAP32
CreateBitmap32( INT32 width
, INT32 height
, UINT32 planes
,
46 UINT32 bpp
, LPCVOID bits
)
48 BITMAPOBJ
* bmpObjPtr
;
51 planes
= (BYTE
)planes
;
54 dprintf_gdi( stddeb
, "CreateBitmap: %dx%d, %d colors\n",
55 width
, height
, 1 << (planes
*bpp
) );
57 /* Check parameters */
58 if (!height
|| !width
|| planes
!= 1) return 0;
59 if ((bpp
!= 1) && (bpp
!= screenDepth
)) return 0;
60 if (height
< 0) height
= -height
;
61 if (width
< 0) width
= -width
;
63 /* Create the BITMAPOBJ */
64 hbitmap
= GDI_AllocObject( sizeof(BITMAPOBJ
), BITMAP_MAGIC
);
65 if (!hbitmap
) return 0;
66 bmpObjPtr
= (BITMAPOBJ
*) GDI_HEAP_LIN_ADDR( hbitmap
);
68 bmpObjPtr
->size
.cx
= 0;
69 bmpObjPtr
->size
.cy
= 0;
70 bmpObjPtr
->bitmap
.bmType
= 0;
71 bmpObjPtr
->bitmap
.bmWidth
= (INT16
)width
;
72 bmpObjPtr
->bitmap
.bmHeight
= (INT16
)height
;
73 bmpObjPtr
->bitmap
.bmPlanes
= (BYTE
)planes
;
74 bmpObjPtr
->bitmap
.bmBitsPixel
= (BYTE
)bpp
;
75 bmpObjPtr
->bitmap
.bmWidthBytes
= (INT16
)BITMAP_WIDTH_BYTES( width
, bpp
);
76 bmpObjPtr
->bitmap
.bmBits
= NULL
;
78 /* Create the pixmap */
79 bmpObjPtr
->pixmap
= XCreatePixmap(display
, rootWindow
, width
, height
, bpp
);
80 if (!bmpObjPtr
->pixmap
)
82 GDI_HEAP_FREE( hbitmap
);
85 else if (bits
) /* Set bitmap bits */
86 SetBitmapBits32( hbitmap
, height
* bmpObjPtr
->bitmap
.bmWidthBytes
,
92 /***********************************************************************
93 * CreateCompatibleBitmap16 (GDI.51)
95 HBITMAP16
CreateCompatibleBitmap16( HDC16 hdc
, INT16 width
, INT16 height
)
97 return CreateCompatibleBitmap32( hdc
, width
, height
);
101 /***********************************************************************
102 * CreateCompatibleBitmap32 (GDI32.30)
104 HBITMAP32
CreateCompatibleBitmap32( HDC32 hdc
, INT32 width
, INT32 height
)
106 HBITMAP32 hbmpRet
= 0;
109 dprintf_gdi( stddeb
, "CreateCompatibleBitmap(%04x,%d,%d) = \n",
110 hdc
, width
, height
);
111 if (!(dc
= DC_GetDCPtr( hdc
))) return 0;
112 hbmpRet
= CreateBitmap32( width
, height
, 1, dc
->w
.bitsPerPixel
, NULL
);
113 dprintf_gdi(stddeb
,"\t\t%04x\n", hbmpRet
);
118 /***********************************************************************
119 * CreateBitmapIndirect16 (GDI.49)
121 HBITMAP16
CreateBitmapIndirect16( const BITMAP16
* bmp
)
123 return CreateBitmap16( bmp
->bmWidth
, bmp
->bmHeight
, bmp
->bmPlanes
,
124 bmp
->bmBitsPixel
, PTR_SEG_TO_LIN( bmp
->bmBits
) );
128 /***********************************************************************
129 * CreateBitmapIndirect32 (GDI32.26)
131 HBITMAP32
CreateBitmapIndirect32( const BITMAP32
* bmp
)
133 return CreateBitmap32( bmp
->bmWidth
, bmp
->bmHeight
, bmp
->bmPlanes
,
134 bmp
->bmBitsPixel
, bmp
->bmBits
);
138 /***********************************************************************
139 * GetBitmapBits16 (GDI.74)
141 LONG
GetBitmapBits16( HBITMAP16 hbitmap
, LONG count
, LPVOID buffer
)
143 return GetBitmapBits32( hbitmap
, count
, buffer
);
147 /***********************************************************************
148 * GetBitmapBits32 (GDI32.143)
150 LONG
GetBitmapBits32( HBITMAP32 hbitmap
, LONG count
, LPVOID buffer
)
153 LONG height
,widthbytes
;
155 LPBYTE tmpbuffer
,tbuf
;
160 fprintf(stderr
, "Negative number of bytes (%ld) passed to GetBitmapBits???\n", count
);
163 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
166 /* Only get entire lines */
167 height
= count
/ bmp
->bitmap
.bmWidthBytes
;
168 if (height
> bmp
->bitmap
.bmHeight
) height
= bmp
->bitmap
.bmHeight
;
169 dprintf_bitmap(stddeb
, "GetBitmapBits: %dx%d %d colors %p fetched height: %ld\n",
170 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
171 1 << bmp
->bitmap
.bmBitsPixel
, buffer
, height
);
172 if (!height
) return 0;
174 switch (bmp
->bitmap
.bmBitsPixel
) {
176 if (!(bmp
->bitmap
.bmWidth
& 15))
179 pad
= ((16 - (bmp
->bitmap
.bmWidth
& 15)) + 7) / 8;
182 if (!(bmp
->bitmap
.bmWidth
& 3))
185 pad
= ((4 - (bmp
->bitmap
.bmWidth
& 3)) + 1) / 2;
188 pad
= (2 - (bmp
->bitmap
.bmWidth
& 1)) & 1;
192 pad
= 0; /* we have 16bit alignment already */
195 pad
= (bmp
->bitmap
.bmWidth
*3) & 1;
198 fprintf(stderr
,"GetBitMapBits32: unknown depth %d, please report.\n",
199 bmp
->bitmap
.bmBitsPixel
204 widthbytes
= DIB_GetImageWidthBytesX11(bmp
->bitmap
.bmWidth
,bmp
->bitmap
.bmBitsPixel
);
205 tmpbuffer
= (LPBYTE
)xmalloc(widthbytes
*height
);
206 image
= XCreateImage( display
, DefaultVisualOfScreen(screen
),
207 bmp
->bitmap
.bmBitsPixel
, ZPixmap
, 0, tmpbuffer
,
208 bmp
->bitmap
.bmWidth
,height
,32,widthbytes
211 CallTo32_LargeStack( (int(*)())XGetSubImage
, 11,
212 display
, bmp
->pixmap
, 0, 0, bmp
->bitmap
.bmWidth
,
213 height
, AllPlanes
, ZPixmap
, image
, 0, 0 );
215 /* copy XImage to 16 bit padded image buffer with real bitsperpixel */
218 switch (bmp
->bitmap
.bmBitsPixel
)
221 for (h
=0;h
<height
;h
++)
224 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
226 *tbuf
|= XGetPixel(image
,w
,h
)<<(7-(w
&7));
227 if ((w
&7) == 7) *(++tbuf
) = 0;
233 for (h
=0;h
<height
;h
++)
235 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
237 if (!(w
& 1)) *tbuf
= XGetPixel( image
, w
, h
) << 4;
238 else *tbuf
++ |= XGetPixel( image
, w
, h
) & 0x0f;
244 for (h
=0;h
<height
;h
++)
246 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
247 *tbuf
++ = XGetPixel(image
,w
,h
);
253 for (h
=0;h
<height
;h
++)
255 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
257 long pixel
= XGetPixel(image
,w
,h
);
259 *tbuf
++ = pixel
& 0xff;
260 *tbuf
++ = (pixel
>>8) & 0xff;
265 for (h
=0;h
<height
;h
++)
267 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
269 long pixel
= XGetPixel(image
,w
,h
);
271 *tbuf
++ = pixel
& 0xff;
272 *tbuf
++ = (pixel
>> 8) & 0xff;
273 *tbuf
++ = (pixel
>>16) & 0xff;
278 XDestroyImage( image
); /* frees tbuffer too */
279 return height
* bmp
->bitmap
.bmWidthBytes
;
283 /***********************************************************************
284 * SetBitmapBits16 (GDI.106)
286 LONG
SetBitmapBits16( HBITMAP16 hbitmap
, LONG count
, LPCVOID buffer
)
288 return SetBitmapBits32( hbitmap
, count
, buffer
);
292 /***********************************************************************
293 * SetBitmapBits32 (GDI32.303)
295 LONG
SetBitmapBits32( HBITMAP32 hbitmap
, LONG count
, LPCVOID buffer
)
300 LPBYTE sbuf
,tmpbuffer
;
301 int w
,h
,pad
,widthbytes
;
305 fprintf(stderr
, "Negative number of bytes (%ld) passed to SetBitmapBits???\n", count
);
308 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
311 dprintf_bitmap(stddeb
, "SetBitmapBits: %dx%d %d colors %p\n",
312 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
313 1 << bmp
->bitmap
.bmBitsPixel
, buffer
);
315 /* Only set entire lines */
316 height
= count
/ bmp
->bitmap
.bmWidthBytes
;
317 if (height
> bmp
->bitmap
.bmHeight
) height
= bmp
->bitmap
.bmHeight
;
318 if (!height
) return 0;
320 switch (bmp
->bitmap
.bmBitsPixel
) {
322 if (!(bmp
->bitmap
.bmWidth
& 15))
325 pad
= ((16 - (bmp
->bitmap
.bmWidth
& 15)) + 7) / 8;
328 if (!(bmp
->bitmap
.bmWidth
& 3))
331 pad
= ((4 - (bmp
->bitmap
.bmWidth
& 3)) + 1) / 2;
334 pad
= (2 - (bmp
->bitmap
.bmWidth
& 1)) & 1;
338 pad
= 0; /* we have 16bit alignment already */
341 pad
= (bmp
->bitmap
.bmWidth
*3) & 1;
344 fprintf(stderr
,"SetBitMapBits32: unknown depth %d, please report.\n",
345 bmp
->bitmap
.bmBitsPixel
349 sbuf
= (LPBYTE
)buffer
;
351 widthbytes
= DIB_GetImageWidthBytesX11(bmp
->bitmap
.bmWidth
,bmp
->bitmap
.bmBitsPixel
);
352 tmpbuffer
= (LPBYTE
)xmalloc(widthbytes
*height
);
353 image
= XCreateImage( display
, DefaultVisualOfScreen(screen
),
354 bmp
->bitmap
.bmBitsPixel
, ZPixmap
, 0, tmpbuffer
,
355 bmp
->bitmap
.bmWidth
,height
,32,widthbytes
358 /* copy 16 bit padded image buffer with real bitsperpixel to XImage */
359 sbuf
= (LPBYTE
)buffer
;
360 switch (bmp
->bitmap
.bmBitsPixel
)
363 for (h
=0;h
<height
;h
++)
365 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
367 XPutPixel(image
,w
,h
,(sbuf
[0]>>(7-(w
&7))) & 1);
375 for (h
=0;h
<height
;h
++)
377 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
379 if (!(w
& 1)) XPutPixel( image
, w
, h
, *sbuf
>> 4 );
380 else XPutPixel( image
, w
, h
, *sbuf
++ & 0xf );
386 for (h
=0;h
<height
;h
++)
388 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
389 XPutPixel(image
,w
,h
,*sbuf
++);
395 for (h
=0;h
<height
;h
++)
397 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
399 XPutPixel(image
,w
,h
,sbuf
[1]*256+sbuf
[0]);
405 for (h
=0;h
<height
;h
++)
407 for (w
=0;w
<bmp
->bitmap
.bmWidth
;w
++)
409 XPutPixel(image
,w
,h
,(sbuf
[2]<<16)+(sbuf
[1]<<8)+sbuf
[0]);
417 CallTo32_LargeStack( XPutImage
, 10,
418 display
, bmp
->pixmap
, BITMAP_GC(bmp
), image
, 0, 0,
419 0, 0, bmp
->bitmap
.bmWidth
, height
);
420 XDestroyImage( image
); /* frees tmpbuffer too */
421 return height
* bmp
->bitmap
.bmWidthBytes
;
424 /**********************************************************************
425 * LoadImageA (USER32.364)
426 * FIXME: implementation still lacks nearly all features, see LR_*
427 * defines in windows.h
430 HANDLE32
LoadImage32A(
431 HINSTANCE32 hinst
,LPCSTR name
,UINT32 type
,INT32 desiredx
,
432 INT32 desiredy
,UINT32 loadflags
435 dprintf_resource(stddeb
,"LoadImage32A(0x%04x,%s,%d,%d,%d,0x%08x)\n",
436 hinst
,name
,type
,desiredx
,desiredy
,loadflags
439 dprintf_resource(stddeb
,"LoadImage32A(0x%04x,%p,%d,%d,%d,0x%08x)\n",
440 hinst
,name
,type
,desiredx
,desiredy
,loadflags
445 return LoadBitmap32A(hinst
,name
);
447 return LoadIcon32A(hinst
,name
);
449 return LoadCursor32A(hinst
,name
);
454 /**********************************************************************
455 * CopyImage32 (USER32.60)
457 * FIXME: implementation still lacks nearly all features, see LR_*
458 * defines in windows.h
460 HANDLE32
CopyImage32( HANDLE32 hnd
, UINT32 type
, INT32 desiredx
,
461 INT32 desiredy
, UINT32 flags
)
466 return hnd
; /* FIXME ... need to copy here */
468 return CopyIcon32(hnd
);
470 return CopyCursor32(hnd
);
476 /**********************************************************************
477 * LoadBitmap16 (USER.175)
479 HBITMAP16
LoadBitmap16( HINSTANCE16 instance
, SEGPTR name
)
481 HBITMAP32 hbitmap
= 0;
489 char *str
= (char *)PTR_SEG_TO_LIN( name
);
490 dprintf_bitmap( stddeb
, "LoadBitmap16(%04x,'%s')\n", instance
, str
);
491 if (str
[0] == '#') name
= (SEGPTR
)(DWORD
)(WORD
)atoi( str
+ 1 );
494 dprintf_bitmap( stddeb
, "LoadBitmap16(%04x,%04x)\n",
495 instance
, LOWORD(name
) );
497 if (!instance
) /* OEM bitmap */
499 if (HIWORD((int)name
)) return 0;
500 return OBM_LoadBitmap( LOWORD((int)name
) );
503 if (!(hRsrc
= FindResource16( instance
, name
, RT_BITMAP
))) return 0;
504 if (!(handle
= LoadResource16( instance
, hRsrc
))) return 0;
506 info
= (BITMAPINFO
*)LockResource16( handle
);
507 if ((hdc
= GetDC32(0)) != 0)
509 char *bits
= (char *)info
+ DIB_BitmapInfoSize( info
, DIB_RGB_COLORS
);
510 hbitmap
= CreateDIBitmap32( hdc
, &info
->bmiHeader
, CBM_INIT
,
511 bits
, info
, DIB_RGB_COLORS
);
512 ReleaseDC32( 0, hdc
);
514 FreeResource16( handle
);
518 /**********************************************************************
519 * LoadBitmap32W (USER32.357)
521 HBITMAP32
LoadBitmap32W( HINSTANCE32 instance
, LPCWSTR name
)
523 HBITMAP32 hbitmap
= 0;
529 if (!instance
) /* OEM bitmap */
531 if (HIWORD((int)name
)) return 0;
532 return OBM_LoadBitmap( LOWORD((int)name
) );
535 if (!(hRsrc
= FindResource32W( instance
, name
,
536 (LPWSTR
)RT_BITMAP
))) return 0;
537 if (!(handle
= LoadResource32( instance
, hRsrc
))) return 0;
539 info
= (BITMAPINFO
*)LockResource32( handle
);
540 if ((hdc
= GetDC32(0)) != 0)
542 char *bits
= (char *)info
+ DIB_BitmapInfoSize( info
, DIB_RGB_COLORS
);
543 hbitmap
= CreateDIBitmap32( hdc
, &info
->bmiHeader
, CBM_INIT
,
544 bits
, info
, DIB_RGB_COLORS
);
545 ReleaseDC32( 0, hdc
);
551 /**********************************************************************
552 * LoadBitmap32A (USER32.356)
554 HBITMAP32
LoadBitmap32A( HINSTANCE32 instance
, LPCSTR name
)
557 if (!HIWORD(name
)) res
= LoadBitmap32W( instance
, (LPWSTR
)name
);
560 LPWSTR uni
= HEAP_strdupAtoW( GetProcessHeap(), 0, name
);
561 res
= LoadBitmap32W( instance
, uni
);
562 HeapFree( GetProcessHeap(), 0, uni
);
568 /***********************************************************************
569 * BITMAP_DeleteObject
571 BOOL32
BITMAP_DeleteObject( HBITMAP16 hbitmap
, BITMAPOBJ
* bmp
)
573 #ifdef PRELIMINARY_WING16_SUPPORT
574 if( bmp
->bitmap
.bmBits
)
575 XShmDetach( display
, (XShmSegmentInfo
*)bmp
->bitmap
.bmBits
);
578 XFreePixmap( display
, bmp
->pixmap
);
579 #ifdef PRELIMINARY_WING16_SUPPORT
580 if( bmp
->bitmap
.bmBits
)
582 __ShmBitmapCtl
* p
= (__ShmBitmapCtl
*)bmp
->bitmap
.bmBits
;
583 WORD sel
= HIWORD(p
->bits
);
584 unsigned long l
, limit
= GetSelectorLimit(sel
);
586 for( l
= 0; l
< limit
; l
+= 0x10000, sel
+= __AHINCR
)
588 shmctl(p
->si
.shmid
, IPC_RMID
, NULL
);
589 shmdt(p
->si
.shmaddr
); /* already marked for destruction */
592 return GDI_FreeObject( hbitmap
);
596 /***********************************************************************
599 INT16
BITMAP_GetObject16( BITMAPOBJ
* bmp
, INT16 count
, LPVOID buffer
)
601 if (count
> sizeof(bmp
->bitmap
)) count
= sizeof(bmp
->bitmap
);
602 memcpy( buffer
, &bmp
->bitmap
, count
);
607 /***********************************************************************
610 INT32
BITMAP_GetObject32( BITMAPOBJ
* bmp
, INT32 count
, LPVOID buffer
)
613 bmp32
.bmType
= bmp
->bitmap
.bmType
;
614 bmp32
.bmWidth
= bmp
->bitmap
.bmWidth
;
615 bmp32
.bmHeight
= bmp
->bitmap
.bmHeight
;
616 bmp32
.bmWidthBytes
= bmp
->bitmap
.bmWidthBytes
;
617 bmp32
.bmPlanes
= bmp
->bitmap
.bmPlanes
;
618 bmp32
.bmBitsPixel
= bmp
->bitmap
.bmBitsPixel
;
620 if (count
> sizeof(bmp32
)) count
= sizeof(bmp32
);
621 memcpy( buffer
, &bmp32
, count
);
627 /***********************************************************************
628 * CreateDiscardableBitmap16 (GDI.156)
630 HBITMAP16
CreateDiscardableBitmap16( HDC16 hdc
, INT16 width
, INT16 height
)
632 return CreateCompatibleBitmap16( hdc
, width
, height
);
636 /***********************************************************************
637 * CreateDiscardableBitmap32 (GDI32.38)
639 HBITMAP32
CreateDiscardableBitmap32( HDC32 hdc
, INT32 width
, INT32 height
)
641 return CreateCompatibleBitmap32( hdc
, width
, height
);
645 /***********************************************************************
646 * GetBitmapDimensionEx16 (GDI.468)
648 BOOL16
GetBitmapDimensionEx16( HBITMAP16 hbitmap
, LPSIZE16 size
)
650 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
651 if (!bmp
) return FALSE
;
657 /***********************************************************************
658 * GetBitmapDimensionEx32 (GDI32.144)
660 BOOL32
GetBitmapDimensionEx32( HBITMAP32 hbitmap
, LPSIZE32 size
)
662 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
663 if (!bmp
) return FALSE
;
664 size
->cx
= (INT32
)bmp
->size
.cx
;
665 size
->cy
= (INT32
)bmp
->size
.cy
;
670 /***********************************************************************
671 * GetBitmapDimension (GDI.162)
673 DWORD
GetBitmapDimension( HBITMAP16 hbitmap
)
676 if (!GetBitmapDimensionEx16( hbitmap
, &size
)) return 0;
677 return MAKELONG( size
.cx
, size
.cy
);
681 /***********************************************************************
682 * SetBitmapDimensionEx16 (GDI.478)
684 BOOL16
SetBitmapDimensionEx16( HBITMAP16 hbitmap
, INT16 x
, INT16 y
,
687 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
688 if (!bmp
) return FALSE
;
689 if (prevSize
) *prevSize
= bmp
->size
;
696 /***********************************************************************
697 * SetBitmapDimensionEx32 (GDI32.304)
699 BOOL32
SetBitmapDimensionEx32( HBITMAP32 hbitmap
, INT32 x
, INT32 y
,
702 BITMAPOBJ
* bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
);
703 if (!bmp
) return FALSE
;
704 if (prevSize
) CONV_SIZE16TO32( &bmp
->size
, prevSize
);
705 bmp
->size
.cx
= (INT16
)x
;
706 bmp
->size
.cy
= (INT16
)y
;
711 /***********************************************************************
712 * SetBitmapDimension (GDI.163)
714 DWORD
SetBitmapDimension( HBITMAP16 hbitmap
, INT16 x
, INT16 y
)
717 if (!SetBitmapDimensionEx16( hbitmap
, x
, y
, &size
)) return 0;
718 return MAKELONG( size
.cx
, size
.cy
);