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.35 2003/08/20 20:45:28 ea 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>
32 #include <win32k/debug1.h>
34 //FIXME: where should CLR_INVALID be defined?
35 #define CLR_INVALID 0xffffffff
37 BOOL STDCALL
NtGdiBitBlt(HDC hDCDest
,
47 GDIMULTILOCK Lock
[2] = {{hDCDest
, 0, GDI_OBJECT_TYPE_DC
}, {hDCSrc
, 0, GDI_OBJECT_TYPE_DC
}};
50 PSURFOBJ SurfDest
, SurfSrc
;
51 PSURFGDI SurfGDIDest
, SurfGDISrc
;
54 //PBITMAPOBJ DestBitmapObj;
55 //PBITMAPOBJ SrcBitmapObj;
56 BOOL Status
, SurfDestAlloc
, SurfSrcAlloc
, XlateAlloc
;
58 PPALGDI PalDestGDI
, PalSourceGDI
;
59 PXLATEOBJ XlateObj
= NULL
;
60 HPALETTE SourcePalette
, DestPalette
;
62 if ( !GDIOBJ_LockMultipleObj(Lock
, sizeof(Lock
)/sizeof(Lock
[0])) )
64 DPRINT1("GDIOBJ_LockMultipleObj() failed\n" );
65 return STATUS_INVALID_PARAMETER
;
68 DCDest
= Lock
[0].pObj
;
71 if ( !DCDest
|| !DCSrc
)
72 return STATUS_INVALID_PARAMETER
;
74 /* Offset the destination and source by the origin of their DCs. */
75 XDest
+= DCDest
->w
.DCOrgX
;
76 YDest
+= DCDest
->w
.DCOrgY
;
77 XSrc
+= DCSrc
->w
.DCOrgX
;
78 YSrc
+= DCSrc
->w
.DCOrgY
;
80 DestRect
.left
= XDest
;
82 DestRect
.right
= XDest
+Width
;
83 DestRect
.bottom
= YDest
+Height
;
88 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 // Retrieve the logical palette of the destination DC
100 DCLogPal
= (PPALOBJ
)AccessUserObject((ULONG
)DCDest
->w
.hPalette
);
103 if(DCLogPal
->logicalToSystem
)
104 XlateObj
= DCLogPal
->logicalToSystem
;
106 // If the source and destination formats differ, create an XlateObj [what if we already have one??]
107 if((BitsPerFormat(SurfDest
->iBitmapFormat
) != BitsPerFormat(SurfSrc
->iBitmapFormat
)) && (XlateObj
== NULL
))
109 if(DCDest
->w
.hPalette
!= 0)
110 DestPalette
= DCDest
->w
.hPalette
;
112 DestPalette
= NtGdiGetStockObject(DEFAULT_PALETTE
);
114 if(DCSrc
->w
.hPalette
!= 0)
115 SourcePalette
= DCSrc
->w
.hPalette
;
117 SourcePalette
= NtGdiGetStockObject(DEFAULT_PALETTE
);
119 PalDestGDI
= (PPALGDI
)AccessInternalObject((ULONG
)DestPalette
);
120 PalSourceGDI
= (PPALGDI
)AccessInternalObject((ULONG
)SourcePalette
);
122 XlateObj
= (PXLATEOBJ
)IntEngCreateXlate(PalDestGDI
->Mode
, PalSourceGDI
->Mode
, DestPalette
, SourcePalette
);
126 // Perform the bitblt operation
128 Status
= IntEngBitBlt(SurfDest
, SurfSrc
, NULL
, DCDest
->CombinedClip
, XlateObj
, &DestRect
, &SourcePoint
, NULL
, NULL
, NULL
, ROP
);
130 if (XlateAlloc
) EngDeleteXlate(XlateObj
);
131 if (SurfDestAlloc
) ExFreePool(SurfDest
);
132 if (SurfSrcAlloc
) ExFreePool(SurfSrc
);
134 GDIOBJ_UnlockMultipleObj(Lock
, sizeof(Lock
)/sizeof(Lock
[0]));
139 HBITMAP STDCALL
NtGdiCreateBitmap(INT Width
,
148 Planes
= (BYTE
) Planes
;
149 BitsPerPel
= (BYTE
) BitsPerPel
;
151 /* Check parameters */
152 if (!Height
|| !Width
)
170 /* Create the BITMAPOBJ */
171 hBitmap
= BITMAPOBJ_AllocBitmap ();
174 DPRINT("NtGdiCreateBitmap: BITMAPOBJ_AllocBitmap returned 0\n");
178 bmp
= BITMAPOBJ_LockBitmap( hBitmap
);
180 DPRINT("NtGdiCreateBitmap:%dx%d, %d (%d BPP) colors returning %08x\n", Width
, Height
,
181 1 << (Planes
* BitsPerPel
), BitsPerPel
, bmp
);
183 bmp
->size
.cx
= Width
;
184 bmp
->size
.cy
= Height
;
185 bmp
->bitmap
.bmType
= 0;
186 bmp
->bitmap
.bmWidth
= Width
;
187 bmp
->bitmap
.bmHeight
= Height
;
188 bmp
->bitmap
.bmPlanes
= Planes
;
189 bmp
->bitmap
.bmBitsPixel
= BitsPerPel
;
190 bmp
->bitmap
.bmWidthBytes
= BITMAPOBJ_GetWidthBytes (Width
, BitsPerPel
);
191 bmp
->bitmap
.bmBits
= NULL
;
192 bmp
->DDBitmap
= NULL
;
195 // Allocate memory for bitmap bits
196 bmp
->bitmap
.bmBits
= ExAllocatePool(PagedPool
, bmp
->bitmap
.bmWidthBytes
* bmp
->bitmap
.bmHeight
);
198 if (Bits
) /* Set bitmap bits */
200 NtGdiSetBitmapBits(hBitmap
, Height
* bmp
->bitmap
.bmWidthBytes
, Bits
);
203 BITMAPOBJ_UnlockBitmap( hBitmap
);
208 BOOL FASTCALL
Bitmap_InternalDelete( PBITMAPOBJ pBmp
)
212 if (NULL
!= pBmp
->bitmap
.bmBits
)
214 if (NULL
!= pBmp
->dib
)
216 if (NULL
== pBmp
->dib
->dshSection
)
218 EngFreeUserMem(pBmp
->bitmap
.bmBits
);
222 /* This is a file-mapped section */
228 ExFreePool(pBmp
->bitmap
.bmBits
);
236 HBITMAP STDCALL
NtGdiCreateCompatibleBitmap(HDC hDC
,
246 DPRINT("NtGdiCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC
, Width
, Height
, dc
->w
.bitsPerPixel
);
252 if ((Width
>= 0x10000) || (Height
>= 0x10000))
254 DPRINT("got bad width %d or height %d, please look for reason\n", Width
, Height
);
258 /* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
259 if (!Width
|| !Height
)
261 hbmpRet
= NtGdiCreateBitmap (1, 1, 1, 1, NULL
);
265 hbmpRet
= NtGdiCreateBitmap(Width
, Height
, 1, dc
->w
.bitsPerPixel
, NULL
);
268 DPRINT ("\t\t%04x\n", hbmpRet
);
273 HBITMAP STDCALL
NtGdiCreateBitmapIndirect(CONST BITMAP
*BM
)
275 return NtGdiCreateBitmap (BM
->bmWidth
,
282 HBITMAP STDCALL
NtGdiCreateDiscardableBitmap(HDC hDC
,
286 /* FIXME: this probably should do something else */
287 return NtGdiCreateCompatibleBitmap(hDC
, Width
, Height
);
290 BOOL STDCALL
NtGdiExtFloodFill(HDC hDC
,
299 BOOL STDCALL
NtGdiFloodFill(HDC hDC
,
307 BOOL STDCALL
NtGdiGetBitmapDimensionEx(HBITMAP hBitmap
,
312 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
318 *Dimension
= bmp
->size
;
320 BITMAPOBJ_UnlockBitmap(hBitmap
);
325 COLORREF STDCALL
NtGdiGetPixel(HDC hDC
,
330 COLORREF cr
= (COLORREF
) 0;
332 dc
= DC_LockDc (hDC
);
335 return (COLORREF
) CLR_INVALID
;
337 //FIXME: get actual pixel RGB value
342 BOOL STDCALL
NtGdiMaskBlt(HDC hDCDest
,
358 BOOL STDCALL
NtGdiPlgBlt(HDC hDCDest
,
372 LONG STDCALL
NtGdiSetBitmapBits(HBITMAP hBitmap
,
379 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
380 if (bmp
== NULL
|| Bits
== NULL
)
387 DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes
);
391 /* Only get entire lines */
392 height
= Bytes
/ bmp
->bitmap
.bmWidthBytes
;
393 if (height
> bmp
->bitmap
.bmHeight
)
395 height
= bmp
->bitmap
.bmHeight
;
397 Bytes
= height
* bmp
->bitmap
.bmWidthBytes
;
398 DPRINT ("(%08x, bytes:%ld, bits:%p) %dx%d %d colors fetched height: %ld\n",
403 bmp
->bitmap
.bmHeight
,
404 1 << bmp
->bitmap
.bmBitsPixel
,
408 /* FIXME: call DDI specific function here if available */
411 DPRINT ("Calling device specific BitmapBits\n");
412 if (bmp
->DDBitmap
->funcs
->pBitmapBits
)
414 ret
= bmp
->DDBitmap
->funcs
->pBitmapBits(hBitmap
, (void *) Bits
, Bytes
, DDB_SET
);
418 DPRINT ("BitmapBits == NULL??\n");
425 /* FIXME: Alloc enough for entire bitmap */
426 if (bmp
->bitmap
.bmBits
== NULL
)
428 bmp
->bitmap
.bmBits
= ExAllocatePool (PagedPool
, Bytes
);
430 if(!bmp
->bitmap
.bmBits
)
432 DPRINT ("Unable to allocate bit buffer\n");
437 memcpy(bmp
->bitmap
.bmBits
, Bits
, Bytes
);
445 BOOL STDCALL
NtGdiSetBitmapDimensionEx(HBITMAP hBitmap
,
452 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
462 bmp
->size
.cx
= Width
;
463 bmp
->size
.cy
= Height
;
465 BITMAPOBJ_UnlockBitmap (hBitmap
);
470 COLORREF STDCALL
NtGdiSetPixel(HDC hDC
,
475 if(NtGdiSetPixelV(hDC
,X
,Y
,Color
))
477 COLORREF cr
= NtGdiGetPixel(hDC
,X
,Y
);
478 if(CLR_INVALID
!= cr
) return(cr
);
480 return ((COLORREF
) -1);
483 BOOL STDCALL
NtGdiSetPixelV(HDC hDC
,
489 PBITMAPOBJ bmp
= NULL
;
492 dc
= DC_LockDc (hDC
);
497 bmp
= BITMAPOBJ_LockBitmap (dc
->w
.hBitmap
);
504 //FIXME: set the actual pixel value
505 BITMAPOBJ_UnlockBitmap (bmp
);
510 BOOL STDCALL
NtGdiStretchBlt(HDC hDCDest
,
525 /* Internal Functions */
528 BITMAPOBJ_GetWidthBytes (INT bmWidth
, INT bpp
)
534 return 2 * ((bmWidth
+15) >> 4);
537 bmWidth
*= 3; /* fall through */
539 return bmWidth
+ (bmWidth
& 1);
549 return 2 * ((bmWidth
+3) >> 2);
558 return ((bmWidth
* bpp
+ 31) & ~31) >> 3;
561 HBITMAP FASTCALL
BITMAPOBJ_CopyBitmap(HBITMAP hBitmap
)
567 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
576 res
= NtGdiCreateBitmapIndirect(&bm
);
581 buf
= ExAllocatePool (NonPagedPool
, bm
.bmWidthBytes
* bm
.bmHeight
);
582 NtGdiGetBitmapBits (hBitmap
, bm
.bmWidthBytes
* bm
.bmHeight
, buf
);
583 NtGdiSetBitmapBits (res
, bm
.bmWidthBytes
* bm
.bmHeight
, buf
);
590 INT STDCALL
BITMAP_GetObject(BITMAPOBJ
* bmp
, INT count
, LPVOID buffer
)
594 if(count
< (INT
) sizeof(DIBSECTION
))
596 if (count
> (INT
) sizeof(BITMAP
)) count
= sizeof(BITMAP
);
600 if (count
> (INT
) sizeof(DIBSECTION
)) count
= sizeof(DIBSECTION
);
602 memcpy(buffer
, bmp
->dib
, count
);
607 if (count
> (INT
) sizeof(BITMAP
)) count
= sizeof(BITMAP
);
608 memcpy(buffer
, &bmp
->bitmap
, count
);