2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: bitmaps.c,v 1.38 2003/08/31 07:56:24 gvg Exp $ */
20 #undef WIN32_LEAN_AND_MEAN
23 #include <win32k/gdiobj.h>
24 #include <win32k/bitmaps.h>
25 //#include <win32k/debug.h>
26 #include "../eng/handle.h"
27 #include <include/inteng.h>
28 #include <include/eng.h>
29 #include <include/surface.h>
30 #include <include/palette.h>
33 #include <win32k/debug1.h>
35 //FIXME: where should CLR_INVALID be defined?
36 #define CLR_INVALID 0xffffffff
38 BOOL STDCALL
NtGdiBitBlt(HDC hDCDest
,
48 GDIMULTILOCK Lock
[2] = {{hDCDest
, 0, GDI_OBJECT_TYPE_DC
}, {hDCSrc
, 0, GDI_OBJECT_TYPE_DC
}};
51 PSURFOBJ SurfDest
, SurfSrc
;
52 PSURFGDI SurfGDIDest
, SurfGDISrc
;
55 //PBITMAPOBJ DestBitmapObj;
56 //PBITMAPOBJ SrcBitmapObj;
57 BOOL Status
, SurfDestAlloc
, SurfSrcAlloc
;
58 PPALGDI PalDestGDI
, PalSourceGDI
;
59 PXLATEOBJ XlateObj
= NULL
;
60 HPALETTE SourcePalette
, DestPalette
;
61 ULONG SourceMode
, DestMode
;
63 if ( !GDIOBJ_LockMultipleObj(Lock
, sizeof(Lock
)/sizeof(Lock
[0])) )
65 DPRINT1("GDIOBJ_LockMultipleObj() failed\n" );
66 return STATUS_INVALID_PARAMETER
;
69 DCDest
= Lock
[0].pObj
;
72 if ( !DCDest
|| !DCSrc
)
73 return STATUS_INVALID_PARAMETER
;
75 /* Offset the destination and source by the origin of their DCs. */
76 XDest
+= DCDest
->w
.DCOrgX
;
77 YDest
+= DCDest
->w
.DCOrgY
;
78 XSrc
+= DCSrc
->w
.DCOrgX
;
79 YSrc
+= DCSrc
->w
.DCOrgY
;
81 DestRect
.left
= XDest
;
83 DestRect
.right
= XDest
+Width
;
84 DestRect
.bottom
= YDest
+Height
;
89 SurfDestAlloc
= FALSE
;
92 // Determine surfaces to be used in the bitblt
93 SurfDest
= (PSURFOBJ
)AccessUserObject((ULONG
)DCDest
->Surface
);
94 SurfSrc
= (PSURFOBJ
)AccessUserObject((ULONG
)DCSrc
->Surface
);
96 SurfGDIDest
= (PSURFGDI
)AccessInternalObjectFromUserObject(SurfDest
);
97 SurfGDISrc
= (PSURFGDI
)AccessInternalObjectFromUserObject(SurfSrc
);
99 if (DCDest
->w
.hPalette
!= 0)
101 DestPalette
= DCDest
->w
.hPalette
;
105 DestPalette
= NtGdiGetStockObject(DEFAULT_PALETTE
);
108 if(DCSrc
->w
.hPalette
!= 0)
110 SourcePalette
= DCSrc
->w
.hPalette
;
114 SourcePalette
= NtGdiGetStockObject(DEFAULT_PALETTE
);
117 PalSourceGDI
= PALETTE_LockPalette(SourcePalette
);
118 SourceMode
= PalSourceGDI
->Mode
;
119 PALETTE_UnlockPalette(SourcePalette
);
120 if (DestPalette
== SourcePalette
)
122 DestMode
= SourceMode
;
126 PalDestGDI
= PALETTE_LockPalette(DestPalette
);
127 DestMode
= PalDestGDI
->Mode
;
128 PALETTE_UnlockPalette(DestPalette
);
131 XlateObj
= (PXLATEOBJ
)IntEngCreateXlate(DestMode
, SourceMode
, DestPalette
, SourcePalette
);
133 // Perform the bitblt operation
135 Status
= IntEngBitBlt(SurfDest
, SurfSrc
, NULL
, DCDest
->CombinedClip
, XlateObj
, &DestRect
, &SourcePoint
, NULL
, NULL
, NULL
, ROP
);
137 EngDeleteXlate(XlateObj
);
138 if (SurfDestAlloc
) ExFreePool(SurfDest
);
139 if (SurfSrcAlloc
) ExFreePool(SurfSrc
);
141 GDIOBJ_UnlockMultipleObj(Lock
, sizeof(Lock
) / sizeof(Lock
[0]));
146 HBITMAP STDCALL
NtGdiCreateBitmap(INT Width
,
155 Planes
= (BYTE
) Planes
;
156 BitsPerPel
= (BYTE
) BitsPerPel
;
158 /* Check parameters */
159 if (!Height
|| !Width
)
177 /* Create the BITMAPOBJ */
178 hBitmap
= BITMAPOBJ_AllocBitmap ();
181 DPRINT("NtGdiCreateBitmap: BITMAPOBJ_AllocBitmap returned 0\n");
185 bmp
= BITMAPOBJ_LockBitmap( hBitmap
);
187 DPRINT("NtGdiCreateBitmap:%dx%d, %d (%d BPP) colors returning %08x\n", Width
, Height
,
188 1 << (Planes
* BitsPerPel
), BitsPerPel
, bmp
);
190 bmp
->size
.cx
= Width
;
191 bmp
->size
.cy
= Height
;
192 bmp
->bitmap
.bmType
= 0;
193 bmp
->bitmap
.bmWidth
= Width
;
194 bmp
->bitmap
.bmHeight
= Height
;
195 bmp
->bitmap
.bmPlanes
= Planes
;
196 bmp
->bitmap
.bmBitsPixel
= BitsPerPel
;
197 bmp
->bitmap
.bmWidthBytes
= BITMAPOBJ_GetWidthBytes (Width
, BitsPerPel
);
198 bmp
->bitmap
.bmBits
= NULL
;
199 bmp
->DDBitmap
= NULL
;
202 // Allocate memory for bitmap bits
203 bmp
->bitmap
.bmBits
= ExAllocatePool(PagedPool
, bmp
->bitmap
.bmWidthBytes
* bmp
->bitmap
.bmHeight
);
205 BITMAPOBJ_UnlockBitmap( hBitmap
);
207 if (Bits
) /* Set bitmap bits */
209 NtGdiSetBitmapBits(hBitmap
, Height
* bmp
->bitmap
.bmWidthBytes
, Bits
);
215 BOOL FASTCALL
Bitmap_InternalDelete( PBITMAPOBJ pBmp
)
219 if (NULL
!= pBmp
->bitmap
.bmBits
)
221 if (NULL
!= pBmp
->dib
)
223 if (NULL
== pBmp
->dib
->dshSection
)
225 EngFreeUserMem(pBmp
->bitmap
.bmBits
);
229 /* This is a file-mapped section */
235 ExFreePool(pBmp
->bitmap
.bmBits
);
243 HBITMAP STDCALL
NtGdiCreateCompatibleBitmap(HDC hDC
,
253 DPRINT("NtGdiCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC
, Width
, Height
, dc
->w
.bitsPerPixel
);
259 if ((Width
>= 0x10000) || (Height
>= 0x10000))
261 DPRINT("got bad width %d or height %d, please look for reason\n", Width
, Height
);
265 /* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
266 if (!Width
|| !Height
)
268 hbmpRet
= NtGdiCreateBitmap (1, 1, 1, 1, NULL
);
272 hbmpRet
= NtGdiCreateBitmap(Width
, Height
, 1, dc
->w
.bitsPerPixel
, NULL
);
275 DPRINT ("\t\t%04x\n", hbmpRet
);
280 HBITMAP STDCALL
NtGdiCreateBitmapIndirect(CONST BITMAP
*BM
)
282 return NtGdiCreateBitmap (BM
->bmWidth
,
289 HBITMAP STDCALL
NtGdiCreateDiscardableBitmap(HDC hDC
,
293 /* FIXME: this probably should do something else */
294 return NtGdiCreateCompatibleBitmap(hDC
, Width
, Height
);
297 BOOL STDCALL
NtGdiExtFloodFill(HDC hDC
,
306 BOOL STDCALL
NtGdiFloodFill(HDC hDC
,
314 BOOL STDCALL
NtGdiGetBitmapDimensionEx(HBITMAP hBitmap
,
319 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
325 *Dimension
= bmp
->size
;
327 BITMAPOBJ_UnlockBitmap(hBitmap
);
332 COLORREF STDCALL
NtGdiGetPixel(HDC hDC
,
337 COLORREF cr
= (COLORREF
) 0;
339 dc
= DC_LockDc (hDC
);
342 return (COLORREF
) CLR_INVALID
;
344 //FIXME: get actual pixel RGB value
349 BOOL STDCALL
NtGdiMaskBlt(HDC hDCDest
,
365 BOOL STDCALL
NtGdiPlgBlt(HDC hDCDest
,
379 LONG STDCALL
NtGdiSetBitmapBits(HBITMAP hBitmap
,
386 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
387 if (bmp
== NULL
|| Bits
== NULL
)
394 DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes
);
398 /* Only get entire lines */
399 height
= Bytes
/ bmp
->bitmap
.bmWidthBytes
;
400 if (height
> bmp
->bitmap
.bmHeight
)
402 height
= bmp
->bitmap
.bmHeight
;
404 Bytes
= height
* bmp
->bitmap
.bmWidthBytes
;
405 DPRINT ("(%08x, bytes:%ld, bits:%p) %dx%d %d colors fetched height: %ld\n",
410 bmp
->bitmap
.bmHeight
,
411 1 << bmp
->bitmap
.bmBitsPixel
,
415 /* FIXME: call DDI specific function here if available */
418 DPRINT ("Calling device specific BitmapBits\n");
419 if (bmp
->DDBitmap
->funcs
->pBitmapBits
)
421 ret
= bmp
->DDBitmap
->funcs
->pBitmapBits(hBitmap
, (void *) Bits
, Bytes
, DDB_SET
);
425 DPRINT ("BitmapBits == NULL??\n");
432 /* FIXME: Alloc enough for entire bitmap */
433 if (bmp
->bitmap
.bmBits
== NULL
)
435 bmp
->bitmap
.bmBits
= ExAllocatePool (PagedPool
, Bytes
);
437 if(!bmp
->bitmap
.bmBits
)
439 DPRINT ("Unable to allocate bit buffer\n");
444 memcpy(bmp
->bitmap
.bmBits
, Bits
, Bytes
);
449 BITMAPOBJ_UnlockBitmap(hBitmap
);
454 BOOL STDCALL
NtGdiSetBitmapDimensionEx(HBITMAP hBitmap
,
461 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
471 bmp
->size
.cx
= Width
;
472 bmp
->size
.cy
= Height
;
474 BITMAPOBJ_UnlockBitmap (hBitmap
);
479 COLORREF STDCALL
NtGdiSetPixel(HDC hDC
,
484 if(NtGdiSetPixelV(hDC
,X
,Y
,Color
))
486 COLORREF cr
= NtGdiGetPixel(hDC
,X
,Y
);
487 if(CLR_INVALID
!= cr
) return(cr
);
489 return ((COLORREF
) -1);
492 BOOL STDCALL
NtGdiSetPixelV(HDC hDC
,
498 PBITMAPOBJ bmp
= NULL
;
501 dc
= DC_LockDc (hDC
);
506 bmp
= BITMAPOBJ_LockBitmap (dc
->w
.hBitmap
);
513 //FIXME: set the actual pixel value
514 BITMAPOBJ_UnlockBitmap (dc
->w
.hBitmap
);
519 BOOL STDCALL
NtGdiStretchBlt(HDC hDCDest
,
534 /* Internal Functions */
537 BITMAPOBJ_GetWidthBytes (INT bmWidth
, INT bpp
)
543 return 2 * ((bmWidth
+15) >> 4);
546 bmWidth
*= 3; /* fall through */
548 return bmWidth
+ (bmWidth
& 1);
558 return 2 * ((bmWidth
+3) >> 2);
567 return ((bmWidth
* bpp
+ 31) & ~31) >> 3;
570 HBITMAP FASTCALL
BITMAPOBJ_CopyBitmap(HBITMAP hBitmap
)
576 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
585 BITMAPOBJ_UnlockBitmap(hBitmap
);
586 res
= NtGdiCreateBitmapIndirect(&bm
);
591 buf
= ExAllocatePool (NonPagedPool
, bm
.bmWidthBytes
* bm
.bmHeight
);
592 NtGdiGetBitmapBits (hBitmap
, bm
.bmWidthBytes
* bm
.bmHeight
, buf
);
593 NtGdiSetBitmapBits (res
, bm
.bmWidthBytes
* bm
.bmHeight
, buf
);
600 INT STDCALL
BITMAP_GetObject(BITMAPOBJ
* bmp
, INT count
, LPVOID buffer
)
604 if(count
< (INT
) sizeof(DIBSECTION
))
606 if (count
> (INT
) sizeof(BITMAP
)) count
= sizeof(BITMAP
);
610 if (count
> (INT
) sizeof(DIBSECTION
)) count
= sizeof(DIBSECTION
);
612 memcpy(buffer
, bmp
->dib
, count
);
617 if (count
> (INT
) sizeof(BITMAP
)) count
= sizeof(BITMAP
);
618 memcpy(buffer
, &bmp
->bitmap
, count
);