c15103973195e075cb8e68570c09db5ce9c21b17
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.34 2003/08/20 07:45:02 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>
32 #include <win32k/debug1.h>
34 BOOL STDCALL
NtGdiBitBlt(HDC hDCDest
,
44 GDIMULTILOCK Lock
[2] = {{hDCDest
, 0, GDI_OBJECT_TYPE_DC
}, {hDCSrc
, 0, GDI_OBJECT_TYPE_DC
}};
47 PSURFOBJ SurfDest
, SurfSrc
;
48 PSURFGDI SurfGDIDest
, SurfGDISrc
;
51 //PBITMAPOBJ DestBitmapObj;
52 //PBITMAPOBJ SrcBitmapObj;
53 BOOL Status
, SurfDestAlloc
, SurfSrcAlloc
, XlateAlloc
;
55 PPALGDI PalDestGDI
, PalSourceGDI
;
56 PXLATEOBJ XlateObj
= NULL
;
57 HPALETTE SourcePalette
, DestPalette
;
59 if ( !GDIOBJ_LockMultipleObj(Lock
, sizeof(Lock
)/sizeof(Lock
[0])) )
61 DPRINT1("GDIOBJ_LockMultipleObj() failed\n" );
62 return STATUS_INVALID_PARAMETER
;
65 DCDest
= Lock
[0].pObj
;
68 if ( !DCDest
|| !DCSrc
)
69 return STATUS_INVALID_PARAMETER
;
71 /* Offset the destination and source by the origin of their DCs. */
72 XDest
+= DCDest
->w
.DCOrgX
;
73 YDest
+= DCDest
->w
.DCOrgY
;
74 XSrc
+= DCSrc
->w
.DCOrgX
;
75 YSrc
+= DCSrc
->w
.DCOrgY
;
77 DestRect
.left
= XDest
;
79 DestRect
.right
= XDest
+Width
;
80 DestRect
.bottom
= YDest
+Height
;
85 SurfDestAlloc
= FALSE
;
89 // Determine surfaces to be used in the bitblt
90 SurfDest
= (PSURFOBJ
)AccessUserObject((ULONG
)DCDest
->Surface
);
91 SurfSrc
= (PSURFOBJ
)AccessUserObject((ULONG
)DCSrc
->Surface
);
93 SurfGDIDest
= (PSURFGDI
)AccessInternalObjectFromUserObject(SurfDest
);
94 SurfGDISrc
= (PSURFGDI
)AccessInternalObjectFromUserObject(SurfSrc
);
96 // Retrieve the logical palette of the destination DC
97 DCLogPal
= (PPALOBJ
)AccessUserObject((ULONG
)DCDest
->w
.hPalette
);
100 if(DCLogPal
->logicalToSystem
)
101 XlateObj
= DCLogPal
->logicalToSystem
;
103 // If the source and destination formats differ, create an XlateObj [what if we already have one??]
104 if((BitsPerFormat(SurfDest
->iBitmapFormat
) != BitsPerFormat(SurfSrc
->iBitmapFormat
)) && (XlateObj
== NULL
))
106 if(DCDest
->w
.hPalette
!= 0)
107 DestPalette
= DCDest
->w
.hPalette
;
109 DestPalette
= NtGdiGetStockObject(DEFAULT_PALETTE
);
111 if(DCSrc
->w
.hPalette
!= 0)
112 SourcePalette
= DCSrc
->w
.hPalette
;
114 SourcePalette
= NtGdiGetStockObject(DEFAULT_PALETTE
);
116 PalDestGDI
= (PPALGDI
)AccessInternalObject((ULONG
)DestPalette
);
117 PalSourceGDI
= (PPALGDI
)AccessInternalObject((ULONG
)SourcePalette
);
119 XlateObj
= (PXLATEOBJ
)IntEngCreateXlate(PalDestGDI
->Mode
, PalSourceGDI
->Mode
, DestPalette
, SourcePalette
);
123 // Perform the bitblt operation
125 Status
= IntEngBitBlt(SurfDest
, SurfSrc
, NULL
, DCDest
->CombinedClip
, XlateObj
, &DestRect
, &SourcePoint
, NULL
, NULL
, NULL
, ROP
);
127 if (XlateAlloc
) EngDeleteXlate(XlateObj
);
128 if (SurfDestAlloc
) ExFreePool(SurfDest
);
129 if (SurfSrcAlloc
) ExFreePool(SurfSrc
);
131 GDIOBJ_UnlockMultipleObj(Lock
, sizeof(Lock
)/sizeof(Lock
[0]));
136 HBITMAP STDCALL
NtGdiCreateBitmap(INT Width
,
145 Planes
= (BYTE
) Planes
;
146 BitsPerPel
= (BYTE
) BitsPerPel
;
148 /* Check parameters */
149 if (!Height
|| !Width
)
167 /* Create the BITMAPOBJ */
168 hBitmap
= BITMAPOBJ_AllocBitmap ();
171 DPRINT("NtGdiCreateBitmap: BITMAPOBJ_AllocBitmap returned 0\n");
175 bmp
= BITMAPOBJ_LockBitmap( hBitmap
);
177 DPRINT("NtGdiCreateBitmap:%dx%d, %d (%d BPP) colors returning %08x\n", Width
, Height
,
178 1 << (Planes
* BitsPerPel
), BitsPerPel
, bmp
);
180 bmp
->size
.cx
= Width
;
181 bmp
->size
.cy
= Height
;
182 bmp
->bitmap
.bmType
= 0;
183 bmp
->bitmap
.bmWidth
= Width
;
184 bmp
->bitmap
.bmHeight
= Height
;
185 bmp
->bitmap
.bmPlanes
= Planes
;
186 bmp
->bitmap
.bmBitsPixel
= BitsPerPel
;
187 bmp
->bitmap
.bmWidthBytes
= BITMAPOBJ_GetWidthBytes (Width
, BitsPerPel
);
188 bmp
->bitmap
.bmBits
= NULL
;
189 bmp
->DDBitmap
= NULL
;
192 // Allocate memory for bitmap bits
193 bmp
->bitmap
.bmBits
= ExAllocatePool(PagedPool
, bmp
->bitmap
.bmWidthBytes
* bmp
->bitmap
.bmHeight
);
195 if (Bits
) /* Set bitmap bits */
197 NtGdiSetBitmapBits(hBitmap
, Height
* bmp
->bitmap
.bmWidthBytes
, Bits
);
200 BITMAPOBJ_UnlockBitmap( hBitmap
);
205 BOOL FASTCALL
Bitmap_InternalDelete( PBITMAPOBJ pBmp
)
209 if (NULL
!= pBmp
->bitmap
.bmBits
)
211 if (NULL
!= pBmp
->dib
)
213 if (NULL
== pBmp
->dib
->dshSection
)
215 EngFreeUserMem(pBmp
->bitmap
.bmBits
);
219 /* This is a file-mapped section */
225 ExFreePool(pBmp
->bitmap
.bmBits
);
233 HBITMAP STDCALL
NtGdiCreateCompatibleBitmap(HDC hDC
,
243 DPRINT("NtGdiCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC
, Width
, Height
, dc
->w
.bitsPerPixel
);
249 if ((Width
>= 0x10000) || (Height
>= 0x10000))
251 DPRINT("got bad width %d or height %d, please look for reason\n", Width
, Height
);
255 /* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
256 if (!Width
|| !Height
)
258 hbmpRet
= NtGdiCreateBitmap (1, 1, 1, 1, NULL
);
262 hbmpRet
= NtGdiCreateBitmap(Width
, Height
, 1, dc
->w
.bitsPerPixel
, NULL
);
265 DPRINT ("\t\t%04x\n", hbmpRet
);
270 HBITMAP STDCALL
NtGdiCreateBitmapIndirect(CONST BITMAP
*BM
)
272 return NtGdiCreateBitmap (BM
->bmWidth
,
279 HBITMAP STDCALL
NtGdiCreateDiscardableBitmap(HDC hDC
,
283 /* FIXME: this probably should do something else */
284 return NtGdiCreateCompatibleBitmap(hDC
, Width
, Height
);
287 BOOL STDCALL
NtGdiExtFloodFill(HDC hDC
,
296 BOOL STDCALL
NtGdiFloodFill(HDC hDC
,
304 BOOL STDCALL
NtGdiGetBitmapDimensionEx(HBITMAP hBitmap
,
309 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
315 *Dimension
= bmp
->size
;
317 BITMAPOBJ_UnlockBitmap(hBitmap
);
322 COLORREF STDCALL
NtGdiGetPixel(HDC hDC
,
329 BOOL STDCALL
NtGdiMaskBlt(HDC hDCDest
,
345 BOOL STDCALL
NtGdiPlgBlt(HDC hDCDest
,
359 LONG STDCALL
NtGdiSetBitmapBits(HBITMAP hBitmap
,
366 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
367 if (bmp
== NULL
|| Bits
== NULL
)
374 DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes
);
378 /* Only get entire lines */
379 height
= Bytes
/ bmp
->bitmap
.bmWidthBytes
;
380 if (height
> bmp
->bitmap
.bmHeight
)
382 height
= bmp
->bitmap
.bmHeight
;
384 Bytes
= height
* bmp
->bitmap
.bmWidthBytes
;
385 DPRINT ("(%08x, bytes:%ld, bits:%p) %dx%d %d colors fetched height: %ld\n",
390 bmp
->bitmap
.bmHeight
,
391 1 << bmp
->bitmap
.bmBitsPixel
,
395 /* FIXME: call DDI specific function here if available */
398 DPRINT ("Calling device specific BitmapBits\n");
399 if (bmp
->DDBitmap
->funcs
->pBitmapBits
)
401 ret
= bmp
->DDBitmap
->funcs
->pBitmapBits(hBitmap
, (void *) Bits
, Bytes
, DDB_SET
);
405 DPRINT ("BitmapBits == NULL??\n");
412 /* FIXME: Alloc enough for entire bitmap */
413 if (bmp
->bitmap
.bmBits
== NULL
)
415 bmp
->bitmap
.bmBits
= ExAllocatePool (PagedPool
, Bytes
);
417 if(!bmp
->bitmap
.bmBits
)
419 DPRINT ("Unable to allocate bit buffer\n");
424 memcpy(bmp
->bitmap
.bmBits
, Bits
, Bytes
);
432 BOOL STDCALL
NtGdiSetBitmapDimensionEx(HBITMAP hBitmap
,
439 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
449 bmp
->size
.cx
= Width
;
450 bmp
->size
.cy
= Height
;
455 COLORREF STDCALL
NtGdiSetPixel(HDC hDC
,
463 BOOL STDCALL
NtGdiSetPixelV(HDC hDC
,
471 BOOL STDCALL
NtGdiStretchBlt(HDC hDCDest
,
486 /* Internal Functions */
489 BITMAPOBJ_GetWidthBytes (INT bmWidth
, INT bpp
)
495 return 2 * ((bmWidth
+15) >> 4);
498 bmWidth
*= 3; /* fall through */
500 return bmWidth
+ (bmWidth
& 1);
510 return 2 * ((bmWidth
+3) >> 2);
519 return ((bmWidth
* bpp
+ 31) & ~31) >> 3;
522 HBITMAP FASTCALL
BITMAPOBJ_CopyBitmap(HBITMAP hBitmap
)
528 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
537 res
= NtGdiCreateBitmapIndirect(&bm
);
542 buf
= ExAllocatePool (NonPagedPool
, bm
.bmWidthBytes
* bm
.bmHeight
);
543 NtGdiGetBitmapBits (hBitmap
, bm
.bmWidthBytes
* bm
.bmHeight
, buf
);
544 NtGdiSetBitmapBits (res
, bm
.bmWidthBytes
* bm
.bmHeight
, buf
);
551 INT STDCALL
BITMAP_GetObject(BITMAPOBJ
* bmp
, INT count
, LPVOID buffer
)
555 if(count
< (INT
) sizeof(DIBSECTION
))
557 if (count
> (INT
) sizeof(BITMAP
)) count
= sizeof(BITMAP
);
561 if (count
> (INT
) sizeof(DIBSECTION
)) count
= sizeof(DIBSECTION
);
563 memcpy(buffer
, bmp
->dib
, count
);
568 if (count
> (INT
) sizeof(BITMAP
)) count
= sizeof(BITMAP
);
569 memcpy(buffer
, &bmp
->bitmap
, count
);