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.53 2004/02/01 15:45:41 gvg Exp $ */
20 #undef WIN32_LEAN_AND_MEAN
23 #include <win32k/color.h>
24 #include <win32k/gdiobj.h>
25 #include <win32k/bitmaps.h>
26 #include <win32k/brush.h>
27 #include <win32k/region.h>
28 //#include <win32k/debug.h>
29 #include "../eng/handle.h"
30 #include <include/inteng.h>
31 #include <include/eng.h>
32 #include <include/error.h>
33 #include <include/surface.h>
34 #include <include/palette.h>
37 #include <win32k/debug1.h>
39 BOOL STDCALL
NtGdiBitBlt(HDC hDCDest
,
51 PSURFOBJ SurfDest
, SurfSrc
;
52 PSURFGDI SurfGDIDest
, SurfGDISrc
;
56 PPALGDI PalDestGDI
, PalSourceGDI
;
57 PXLATEOBJ XlateObj
= NULL
;
58 HPALETTE SourcePalette
, DestPalette
;
59 ULONG SourceMode
, DestMode
;
61 BOOL UsesSource
= ((ROP
& 0xCC0000) >> 2) != (ROP
& 0x330000);
62 BOOL UsesPattern
= TRUE
;//((ROP & 0xF00000) >> 4) != (ROP & 0x0F0000);
64 DCDest
= DC_LockDc(hDCDest
);
67 DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCDest
);
68 SetLastWin32Error(ERROR_INVALID_HANDLE
);
74 if (hDCSrc
!= hDCDest
)
76 DCSrc
= DC_LockDc(hDCSrc
);
80 DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc
);
81 SetLastWin32Error(ERROR_INVALID_HANDLE
);
95 /* Offset the destination and source by the origin of their DCs. */
96 XDest
+= DCDest
->w
.DCOrgX
;
97 YDest
+= DCDest
->w
.DCOrgY
;
100 XSrc
+= DCSrc
->w
.DCOrgX
;
101 YSrc
+= DCSrc
->w
.DCOrgY
;
104 DestRect
.left
= XDest
;
105 DestRect
.top
= YDest
;
106 DestRect
.right
= XDest
+Width
;
107 DestRect
.bottom
= YDest
+Height
;
109 SourcePoint
.x
= XSrc
;
110 SourcePoint
.y
= YSrc
;
112 /* Determine surfaces to be used in the bitblt */
113 SurfDest
= (PSURFOBJ
)AccessUserObject((ULONG
)DCDest
->Surface
);
114 SurfGDIDest
= (PSURFGDI
)AccessInternalObjectFromUserObject(SurfDest
);
117 SurfSrc
= (PSURFOBJ
)AccessUserObject((ULONG
)DCSrc
->Surface
);
118 SurfGDISrc
= (PSURFGDI
)AccessInternalObjectFromUserObject(SurfSrc
);
128 BrushObj
= BRUSHOBJ_LockBrush(DCDest
->w
.hBrush
);
129 if (NULL
== BrushObj
)
131 if (UsesSource
&& hDCSrc
!= hDCDest
)
135 DC_UnlockDc(hDCDest
);
136 SetLastWin32Error(ERROR_INVALID_HANDLE
);
145 if (DCDest
->w
.hPalette
!= 0)
147 DestPalette
= DCDest
->w
.hPalette
;
151 DestPalette
= NtGdiGetStockObject(DEFAULT_PALETTE
);
154 if (UsesSource
&& DCSrc
->w
.hPalette
!= 0)
156 SourcePalette
= DCSrc
->w
.hPalette
;
160 SourcePalette
= NtGdiGetStockObject(DEFAULT_PALETTE
);
163 PalSourceGDI
= PALETTE_LockPalette(SourcePalette
);
164 if (NULL
== PalSourceGDI
)
166 if (UsesSource
&& hDCSrc
!= hDCDest
)
170 DC_UnlockDc(hDCDest
);
171 SetLastWin32Error(ERROR_INVALID_HANDLE
);
174 SourceMode
= PalSourceGDI
->Mode
;
175 PALETTE_UnlockPalette(SourcePalette
);
177 if (DestPalette
== SourcePalette
)
179 DestMode
= SourceMode
;
183 PalDestGDI
= PALETTE_LockPalette(DestPalette
);
184 if (NULL
== PalDestGDI
)
186 if (UsesSource
&& hDCSrc
!= hDCDest
)
190 DC_UnlockDc(hDCDest
);
191 SetLastWin32Error(ERROR_INVALID_HANDLE
);
194 DestMode
= PalDestGDI
->Mode
;
195 PALETTE_UnlockPalette(DestPalette
);
198 if (DCDest
->w
.bitsPerPixel
== 1)
200 XlateObj
= (PXLATEOBJ
)IntEngCreateMonoXlate(SourceMode
, DestPalette
,
201 SourcePalette
, DCSrc
->w
.backgroundColor
);
205 XlateObj
= (PXLATEOBJ
)IntEngCreateXlate(DestMode
, SourceMode
, DestPalette
, SourcePalette
);
207 if (NULL
== XlateObj
)
209 if (UsesSource
&& hDCSrc
!= hDCDest
)
213 DC_UnlockDc(hDCDest
);
214 SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES
);
218 /* Perform the bitblt operation */
219 Status
= IntEngBitBlt(SurfDest
, SurfSrc
, NULL
, DCDest
->CombinedClip
, XlateObj
,
220 &DestRect
, &SourcePoint
, NULL
, BrushObj
, NULL
, ROP
);
222 EngDeleteXlate(XlateObj
);
225 BRUSHOBJ_UnlockBrush(DCDest
->w
.hBrush
);
227 if (UsesSource
&& hDCSrc
!= hDCDest
)
231 DC_UnlockDc(hDCDest
);
236 HBITMAP STDCALL
NtGdiCreateBitmap(INT Width
,
245 Planes
= (BYTE
) Planes
;
246 BitsPerPel
= (BYTE
) BitsPerPel
;
248 /* Check parameters */
249 if (!Height
|| !Width
)
267 /* Create the BITMAPOBJ */
268 hBitmap
= BITMAPOBJ_AllocBitmap ();
271 DPRINT("NtGdiCreateBitmap: BITMAPOBJ_AllocBitmap returned 0\n");
275 bmp
= BITMAPOBJ_LockBitmap( hBitmap
);
277 DPRINT("NtGdiCreateBitmap:%dx%d, %d (%d BPP) colors returning %08x\n", Width
, Height
,
278 1 << (Planes
* BitsPerPel
), BitsPerPel
, bmp
);
280 bmp
->dimension
.cx
= 0;
281 bmp
->dimension
.cy
= 0;
282 bmp
->bitmap
.bmType
= 0;
283 bmp
->bitmap
.bmWidth
= Width
;
284 bmp
->bitmap
.bmHeight
= Height
;
285 bmp
->bitmap
.bmPlanes
= Planes
;
286 bmp
->bitmap
.bmBitsPixel
= BitsPerPel
;
287 bmp
->bitmap
.bmWidthBytes
= BITMAPOBJ_GetWidthBytes (Width
, BitsPerPel
);
288 bmp
->bitmap
.bmBits
= NULL
;
289 bmp
->DDBitmap
= NULL
;
292 // Allocate memory for bitmap bits
293 bmp
->bitmap
.bmBits
= ExAllocatePool(PagedPool
, bmp
->bitmap
.bmWidthBytes
* bmp
->bitmap
.bmHeight
);
295 BITMAPOBJ_UnlockBitmap( hBitmap
);
297 if (Bits
) /* Set bitmap bits */
299 NtGdiSetBitmapBits(hBitmap
, Height
* bmp
->bitmap
.bmWidthBytes
, Bits
);
305 BOOL FASTCALL
Bitmap_InternalDelete( PBITMAPOBJ pBmp
)
309 if (NULL
!= pBmp
->bitmap
.bmBits
)
311 if (NULL
!= pBmp
->dib
)
313 if (NULL
== pBmp
->dib
->dshSection
)
315 EngFreeUserMem(pBmp
->bitmap
.bmBits
);
319 /* This is a file-mapped section */
325 ExFreePool(pBmp
->bitmap
.bmBits
);
333 HBITMAP STDCALL
NtGdiCreateCompatibleBitmap(HDC hDC
,
343 DPRINT("NtGdiCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC
, Width
, Height
, dc
->w
.bitsPerPixel
);
349 if ((Width
>= 0x10000) || (Height
>= 0x10000))
351 DPRINT("got bad width %d or height %d, please look for reason\n", Width
, Height
);
355 /* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
356 if (!Width
|| !Height
)
358 hbmpRet
= NtGdiCreateBitmap (1, 1, 1, 1, NULL
);
362 hbmpRet
= NtGdiCreateBitmap(Width
, Height
, 1, dc
->w
.bitsPerPixel
, NULL
);
365 DPRINT ("\t\t%04x\n", hbmpRet
);
370 HBITMAP STDCALL
NtGdiCreateBitmapIndirect(CONST BITMAP
*BM
)
372 return NtGdiCreateBitmap (BM
->bmWidth
,
379 HBITMAP STDCALL
NtGdiCreateDiscardableBitmap(HDC hDC
,
383 /* FIXME: this probably should do something else */
384 return NtGdiCreateCompatibleBitmap(hDC
, Width
, Height
);
387 BOOL STDCALL
NtGdiExtFloodFill(HDC hDC
,
396 BOOL STDCALL
NtGdiFloodFill(HDC hDC
,
401 return NtGdiExtFloodFill(hDC
, XStart
, YStart
, Fill
, FLOODFILLBORDER
);
404 BOOL STDCALL
NtGdiGetBitmapDimensionEx(HBITMAP hBitmap
,
409 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
415 *Dimension
= bmp
->dimension
;
417 BITMAPOBJ_UnlockBitmap(hBitmap
);
422 COLORREF STDCALL
NtGdiGetPixel(HDC hDC
, INT XPos
, INT YPos
)
425 COLORREF Result
= (COLORREF
) 0;
427 PSURFOBJ SurfaceObject
;
429 dc
= DC_LockDc (hDC
);
432 return (COLORREF
)CLR_INVALID
;
434 if (XPos
< dc
->CombinedClip
->rclBounds
.left
||
435 XPos
> dc
->CombinedClip
->rclBounds
.right
||
436 YPos
< dc
->CombinedClip
->rclBounds
.top
||
437 YPos
> dc
->CombinedClip
->rclBounds
.top
)
440 return (COLORREF
)CLR_INVALID
;
442 SurfaceObject
= (PSURFOBJ
)AccessUserObject((ULONG
)dc
->Surface
);
443 Surface
= (PSURFGDI
)AccessInternalObjectFromUserObject(SurfaceObject
);
444 if (Surface
== NULL
|| Surface
->DIB_GetPixel
== NULL
)
447 return (COLORREF
)CLR_INVALID
;
449 Result
= Surface
->DIB_GetPixel(SurfaceObject
, XPos
, YPos
);
454 /***********************************************************************
456 * Ported from WINE by sedwards 11-4-03
458 * Someone thought it would be faster to do it here and then switch back
459 * to GDI32. I dunno. Write a test and let me know.
462 static inline BYTE
SwapROP3_SrcDst(BYTE bRop3
)
464 return (bRop3
& 0x99) | ((bRop3
& 0x22) << 1) | ((bRop3
& 0x44) >> 1);
467 #define FRGND_ROP3(ROP4) ((ROP4) & 0x00FFFFFF)
468 #define BKGND_ROP3(ROP4) (ROP3Table[(SwapROP3_SrcDst((ROP4)>>24)) & 0xFF])
469 #define DSTCOPY 0x00AA0029
470 #define DSTERASE 0x00220326 /* dest = dest & (~src) : DSna */
472 BOOL STDCALL
NtGdiMaskBlt(HDC hdcDest
, INT nXDest
, INT nYDest
,
473 INT nWidth
, INT nHeight
, HDC hdcSrc
,
474 INT nXSrc
, INT nYSrc
, HBITMAP hbmMask
,
475 INT xMask
, INT yMask
, DWORD dwRop
)
477 HBITMAP hOldMaskBitmap
, hBitmap2
, hOldBitmap2
, hBitmap3
, hOldBitmap3
;
478 HDC hDCMask
, hDC1
, hDC2
;
479 static const DWORD ROP3Table
[256] =
481 0x00000042, 0x00010289,
482 0x00020C89, 0x000300AA,
483 0x00040C88, 0x000500A9,
484 0x00060865, 0x000702C5,
485 0x00080F08, 0x00090245,
486 0x000A0329, 0x000B0B2A,
487 0x000C0324, 0x000D0B25,
488 0x000E08A5, 0x000F0001,
489 0x00100C85, 0x001100A6,
490 0x00120868, 0x001302C8,
491 0x00140869, 0x001502C9,
492 0x00165CCA, 0x00171D54,
493 0x00180D59, 0x00191CC8,
494 0x001A06C5, 0x001B0768,
495 0x001C06CA, 0x001D0766,
496 0x001E01A5, 0x001F0385,
497 0x00200F09, 0x00210248,
498 0x00220326, 0x00230B24,
499 0x00240D55, 0x00251CC5,
500 0x002606C8, 0x00271868,
501 0x00280369, 0x002916CA,
502 0x002A0CC9, 0x002B1D58,
503 0x002C0784, 0x002D060A,
504 0x002E064A, 0x002F0E2A,
505 0x0030032A, 0x00310B28,
506 0x00320688, 0x00330008,
507 0x003406C4, 0x00351864,
508 0x003601A8, 0x00370388,
509 0x0038078A, 0x00390604,
510 0x003A0644, 0x003B0E24,
511 0x003C004A, 0x003D18A4,
512 0x003E1B24, 0x003F00EA,
513 0x00400F0A, 0x00410249,
514 0x00420D5D, 0x00431CC4,
515 0x00440328, 0x00450B29,
516 0x004606C6, 0x0047076A,
517 0x00480368, 0x004916C5,
518 0x004A0789, 0x004B0605,
519 0x004C0CC8, 0x004D1954,
520 0x004E0645, 0x004F0E25,
521 0x00500325, 0x00510B26,
522 0x005206C9, 0x00530764,
523 0x005408A9, 0x00550009,
524 0x005601A9, 0x00570389,
525 0x00580785, 0x00590609,
526 0x005A0049, 0x005B18A9,
527 0x005C0649, 0x005D0E29,
528 0x005E1B29, 0x005F00E9,
529 0x00600365, 0x006116C6,
530 0x00620786, 0x00630608,
531 0x00640788, 0x00650606,
532 0x00660046, 0x006718A8,
533 0x006858A6, 0x00690145,
534 0x006A01E9, 0x006B178A,
535 0x006C01E8, 0x006D1785,
536 0x006E1E28, 0x006F0C65,
537 0x00700CC5, 0x00711D5C,
538 0x00720648, 0x00730E28,
539 0x00740646, 0x00750E26,
540 0x00761B28, 0x007700E6,
541 0x007801E5, 0x00791786,
542 0x007A1E29, 0x007B0C68,
543 0x007C1E24, 0x007D0C69,
544 0x007E0955, 0x007F03C9,
545 0x008003E9, 0x00810975,
546 0x00820C49, 0x00831E04,
547 0x00840C48, 0x00851E05,
548 0x008617A6, 0x008701C5,
549 0x008800C6, 0x00891B08,
550 0x008A0E06, 0x008B0666,
551 0x008C0E08, 0x008D0668,
552 0x008E1D7C, 0x008F0CE5,
553 0x00900C45, 0x00911E08,
554 0x009217A9, 0x009301C4,
555 0x009417AA, 0x009501C9,
556 0x00960169, 0x0097588A,
557 0x00981888, 0x00990066,
558 0x009A0709, 0x009B07A8,
559 0x009C0704, 0x009D07A6,
560 0x009E16E6, 0x009F0345,
561 0x00A000C9, 0x00A11B05,
562 0x00A20E09, 0x00A30669,
563 0x00A41885, 0x00A50065,
564 0x00A60706, 0x00A707A5,
565 0x00A803A9, 0x00A90189,
566 0x00AA0029, 0x00AB0889,
567 0x00AC0744, 0x00AD06E9,
568 0x00AE0B06, 0x00AF0229,
569 0x00B00E05, 0x00B10665,
570 0x00B21974, 0x00B30CE8,
571 0x00B4070A, 0x00B507A9,
572 0x00B616E9, 0x00B70348,
573 0x00B8074A, 0x00B906E6,
574 0x00BA0B09, 0x00BB0226,
575 0x00BC1CE4, 0x00BD0D7D,
576 0x00BE0269, 0x00BF08C9,
577 0x00C000CA, 0x00C11B04,
578 0x00C21884, 0x00C3006A,
579 0x00C40E04, 0x00C50664,
580 0x00C60708, 0x00C707AA,
581 0x00C803A8, 0x00C90184,
582 0x00CA0749, 0x00CB06E4,
583 0x00CC0020, 0x00CD0888,
584 0x00CE0B08, 0x00CF0224,
585 0x00D00E0A, 0x00D1066A,
586 0x00D20705, 0x00D307A4,
587 0x00D41D78, 0x00D50CE9,
588 0x00D616EA, 0x00D70349,
589 0x00D80745, 0x00D906E8,
590 0x00DA1CE9, 0x00DB0D75,
591 0x00DC0B04, 0x00DD0228,
592 0x00DE0268, 0x00DF08C8,
593 0x00E003A5, 0x00E10185,
594 0x00E20746, 0x00E306EA,
595 0x00E40748, 0x00E506E5,
596 0x00E61CE8, 0x00E70D79,
597 0x00E81D74, 0x00E95CE6,
598 0x00EA02E9, 0x00EB0849,
599 0x00EC02E8, 0x00ED0848,
600 0x00EE0086, 0x00EF0A08,
601 0x00F00021, 0x00F10885,
602 0x00F20B05, 0x00F3022A,
603 0x00F40B0A, 0x00F50225,
604 0x00F60265, 0x00F708C5,
605 0x00F802E5, 0x00F90845,
606 0x00FA0089, 0x00FB0A09,
607 0x00FC008A, 0x00FD0A0A,
608 0x00FE02A9, 0x00FF0062,
612 return NtGdiBitBlt(hdcDest
, nXDest
, nYDest
, nWidth
, nHeight
, hdcSrc
, nXSrc
, nYSrc
, FRGND_ROP3(dwRop
));
614 /* 1. make mask bitmap's dc */
615 hDCMask
= NtGdiCreateCompatableDC(hdcDest
);
616 hOldMaskBitmap
= (HBITMAP
)NtGdiSelectObject(hDCMask
, hbmMask
);
618 /* 2. make masked Background bitmap */
620 /* 2.1 make bitmap */
621 hDC1
= NtGdiCreateCompatableDC(hdcDest
);
622 hBitmap2
= NtGdiCreateCompatibleBitmap(hdcDest
, nWidth
, nHeight
);
623 hOldBitmap2
= (HBITMAP
)NtGdiSelectObject(hDC1
, hBitmap2
);
625 /* 2.2 draw dest bitmap and mask */
626 NtGdiBitBlt(hDC1
, 0, 0, nWidth
, nHeight
, hdcSrc
, nXSrc
, nYSrc
, SRCCOPY
);
627 NtGdiBitBlt(hDC1
, 0, 0, nWidth
, nHeight
, hdcDest
, nXDest
, nYDest
, BKGND_ROP3(dwRop
));
628 NtGdiBitBlt(hDC1
, 0, 0, nWidth
, nHeight
, hDCMask
, xMask
, yMask
, DSTERASE
);
630 /* 3. make masked Foreground bitmap */
632 /* 3.1 make bitmap */
633 hDC2
= NtGdiCreateCompatableDC(hdcDest
);
634 hBitmap3
= NtGdiCreateCompatibleBitmap(hdcDest
, nWidth
, nHeight
);
635 hOldBitmap3
= (HBITMAP
)NtGdiSelectObject(hDC2
, hBitmap3
);
637 /* 3.2 draw src bitmap and mask */
638 NtGdiBitBlt(hDC2
, 0, 0, nWidth
, nHeight
, hdcDest
, nXDest
, nYDest
, SRCCOPY
);
639 NtGdiBitBlt(hDC2
, 0, 0, nWidth
, nHeight
, hdcSrc
, nXSrc
, nYSrc
, FRGND_ROP3(dwRop
));
640 NtGdiBitBlt(hDC2
, 0, 0, nWidth
, nHeight
, hDCMask
, xMask
, yMask
, SRCAND
);
642 /* 4. combine two bitmap and copy it to hdcDest */
643 NtGdiBitBlt(hDC1
, 0, 0, nWidth
, nHeight
, hDC2
, 0, 0, SRCPAINT
);
644 NtGdiBitBlt(hdcDest
, nXDest
, nYDest
, nWidth
, nHeight
, hDC1
, 0, 0, SRCCOPY
);
646 /* 5. restore all object */
647 NtGdiSelectObject(hDCMask
, hOldMaskBitmap
);
648 NtGdiSelectObject(hDC1
, hOldBitmap2
);
649 NtGdiSelectObject(hDC2
, hOldBitmap3
);
651 /* 6. delete all temp object */
652 NtGdiDeleteObject(hBitmap2
);
653 NtGdiDeleteObject(hBitmap3
);
657 NtGdiDeleteDC(hDCMask
);
662 BOOL STDCALL
NtGdiPlgBlt(HDC hDCDest
,
676 LONG STDCALL
NtGdiSetBitmapBits(HBITMAP hBitmap
,
683 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
684 if (bmp
== NULL
|| Bits
== NULL
)
691 DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes
);
695 /* Only get entire lines */
696 height
= Bytes
/ bmp
->bitmap
.bmWidthBytes
;
697 if (height
> bmp
->bitmap
.bmHeight
)
699 height
= bmp
->bitmap
.bmHeight
;
701 Bytes
= height
* bmp
->bitmap
.bmWidthBytes
;
702 DPRINT ("(%08x, bytes:%ld, bits:%p) %dx%d %d colors fetched height: %ld\n",
707 bmp
->bitmap
.bmHeight
,
708 1 << bmp
->bitmap
.bmBitsPixel
,
712 /* FIXME: call DDI specific function here if available */
715 DPRINT ("Calling device specific BitmapBits\n");
716 if (bmp
->DDBitmap
->funcs
->pBitmapBits
)
718 ret
= bmp
->DDBitmap
->funcs
->pBitmapBits(hBitmap
, (void *) Bits
, Bytes
, DDB_SET
);
722 DPRINT ("BitmapBits == NULL??\n");
729 /* FIXME: Alloc enough for entire bitmap */
730 if (bmp
->bitmap
.bmBits
== NULL
)
732 bmp
->bitmap
.bmBits
= ExAllocatePool (PagedPool
, Bytes
);
734 if(!bmp
->bitmap
.bmBits
)
736 DPRINT ("Unable to allocate bit buffer\n");
741 memcpy(bmp
->bitmap
.bmBits
, Bits
, Bytes
);
746 BITMAPOBJ_UnlockBitmap(hBitmap
);
751 BOOL STDCALL
NtGdiSetBitmapDimensionEx(HBITMAP hBitmap
,
758 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
766 *Size
= bmp
->dimension
;
768 bmp
->dimension
.cx
= Width
;
769 bmp
->dimension
.cy
= Height
;
771 BITMAPOBJ_UnlockBitmap (hBitmap
);
776 COLORREF STDCALL
NtGdiSetPixel(HDC hDC
,
781 COLORREF cr
= NtGdiGetPixel(hDC
,X
,Y
);
782 if(cr
!= CLR_INVALID
&& NtGdiSetPixelV(hDC
,X
,Y
,Color
))
786 return ((COLORREF
) -1);
789 BOOL STDCALL
NtGdiSetPixelV(HDC hDC
,
794 HBRUSH NewBrush
= NtGdiCreateSolidBrush(Color
);
797 if (NewBrush
== NULL
)
799 OldBrush
= NtGdiSelectObject(hDC
, NewBrush
);
800 if (OldBrush
== NULL
)
802 NtGdiPatBlt(hDC
, X
, Y
, 1, 1, PATCOPY
);
803 NtGdiSelectObject(hDC
, OldBrush
);
804 NtGdiDeleteObject(NewBrush
);
808 BOOL STDCALL
NtGdiStretchBlt(HDC hDCDest
,
822 PSURFOBJ SurfDest
, SurfSrc
;
823 PSURFGDI SurfGDIDest
, SurfGDISrc
;
827 PPALGDI PalDestGDI
, PalSourceGDI
;
828 PXLATEOBJ XlateObj
= NULL
;
829 HPALETTE SourcePalette
, DestPalette
;
830 ULONG SourceMode
, DestMode
;
832 BOOL UsesSource
= ((ROP
& 0xCC0000) >> 2) != (ROP
& 0x330000);
833 BOOL UsesPattern
= ((ROP
& 0xF00000) >> 4) != (ROP
& 0x0F0000);
835 if (0 == WidthDest
|| 0 == HeightDest
|| 0 == WidthSrc
|| 0 == HeightSrc
)
837 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
840 DCDest
= DC_LockDc(hDCDest
);
843 DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCDest
);
844 SetLastWin32Error(ERROR_INVALID_HANDLE
);
850 if (hDCSrc
!= hDCDest
)
852 DCSrc
= DC_LockDc(hDCSrc
);
855 DC_UnlockDc(hDCDest
);
856 DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCSrc
);
857 SetLastWin32Error(ERROR_INVALID_HANDLE
);
871 /* Offset the destination and source by the origin of their DCs. */
872 XOriginDest
+= DCDest
->w
.DCOrgX
;
873 YOriginDest
+= DCDest
->w
.DCOrgY
;
876 XOriginSrc
+= DCSrc
->w
.DCOrgX
;
877 YOriginSrc
+= DCSrc
->w
.DCOrgY
;
880 DestRect
.left
= XOriginDest
;
881 DestRect
.top
= YOriginDest
;
882 DestRect
.right
= XOriginDest
+WidthDest
;
883 DestRect
.bottom
= YOriginDest
+HeightDest
;
885 SourceRect
.left
= XOriginSrc
;
886 SourceRect
.top
= YOriginSrc
;
887 SourceRect
.right
= XOriginSrc
+WidthSrc
;
888 SourceRect
.bottom
= YOriginSrc
+HeightSrc
;
890 /* Determine surfaces to be used in the bitblt */
891 SurfDest
= (PSURFOBJ
)AccessUserObject((ULONG
)DCDest
->Surface
);
892 SurfGDIDest
= (PSURFGDI
)AccessInternalObjectFromUserObject(SurfDest
);
895 SurfSrc
= (PSURFOBJ
)AccessUserObject((ULONG
)DCSrc
->Surface
);
896 SurfGDISrc
= (PSURFGDI
)AccessInternalObjectFromUserObject(SurfSrc
);
906 BrushObj
= BRUSHOBJ_LockBrush(DCDest
->w
.hBrush
);
907 if (NULL
== BrushObj
)
909 if (UsesSource
&& hDCSrc
!= hDCDest
)
913 DC_UnlockDc(hDCDest
);
914 SetLastWin32Error(ERROR_INVALID_HANDLE
);
923 if (DCDest
->w
.hPalette
!= 0)
925 DestPalette
= DCDest
->w
.hPalette
;
929 DestPalette
= NtGdiGetStockObject(DEFAULT_PALETTE
);
932 if (UsesSource
&& DCSrc
->w
.hPalette
!= 0)
934 SourcePalette
= DCSrc
->w
.hPalette
;
938 SourcePalette
= NtGdiGetStockObject(DEFAULT_PALETTE
);
941 PalSourceGDI
= PALETTE_LockPalette(SourcePalette
);
942 if (NULL
== PalSourceGDI
)
944 if (UsesSource
&& hDCSrc
!= hDCDest
)
948 DC_UnlockDc(hDCDest
);
949 SetLastWin32Error(ERROR_INVALID_HANDLE
);
952 SourceMode
= PalSourceGDI
->Mode
;
953 PALETTE_UnlockPalette(SourcePalette
);
955 if (DestPalette
== SourcePalette
)
957 DestMode
= SourceMode
;
961 PalDestGDI
= PALETTE_LockPalette(DestPalette
);
962 if (NULL
== PalDestGDI
)
964 if (UsesSource
&& hDCSrc
!= hDCDest
)
968 DC_UnlockDc(hDCDest
);
969 SetLastWin32Error(ERROR_INVALID_HANDLE
);
972 DestMode
= PalDestGDI
->Mode
;
973 PALETTE_UnlockPalette(DestPalette
);
976 XlateObj
= (PXLATEOBJ
)IntEngCreateXlate(DestMode
, SourceMode
, DestPalette
, SourcePalette
);
977 if (NULL
== XlateObj
)
979 if (UsesSource
&& hDCSrc
!= hDCDest
)
983 DC_UnlockDc(hDCDest
);
984 SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES
);
988 /* Perform the bitblt operation */
989 Status
= IntEngStretchBlt(SurfDest
, SurfSrc
, NULL
, DCDest
->CombinedClip
,
990 XlateObj
, &DestRect
, &SourceRect
, NULL
, NULL
, NULL
, COLORONCOLOR
);
992 EngDeleteXlate(XlateObj
);
995 BRUSHOBJ_UnlockBrush(DCDest
->w
.hBrush
);
997 if (UsesSource
&& hDCSrc
!= hDCDest
)
1001 DC_UnlockDc(hDCDest
);
1006 /* Internal Functions */
1009 BITMAPOBJ_GetWidthBytes (INT bmWidth
, INT bpp
)
1015 return 2 * ((bmWidth
+15) >> 4);
1018 bmWidth
*= 3; /* fall through */
1020 return bmWidth
+ (bmWidth
& 1);
1030 return 2 * ((bmWidth
+3) >> 2);
1039 return ((bmWidth
* bpp
+ 31) & ~31) >> 3;
1042 HBITMAP FASTCALL
BITMAPOBJ_CopyBitmap(HBITMAP hBitmap
)
1048 bmp
= BITMAPOBJ_LockBitmap(hBitmap
);
1057 BITMAPOBJ_UnlockBitmap(hBitmap
);
1058 res
= NtGdiCreateBitmapIndirect(&bm
);
1063 buf
= ExAllocatePool (NonPagedPool
, bm
.bmWidthBytes
* bm
.bmHeight
);
1064 NtGdiGetBitmapBits (hBitmap
, bm
.bmWidthBytes
* bm
.bmHeight
, buf
);
1065 NtGdiSetBitmapBits (res
, bm
.bmWidthBytes
* bm
.bmHeight
, buf
);
1072 INT STDCALL
BITMAP_GetObject(BITMAPOBJ
* bmp
, INT count
, LPVOID buffer
)
1076 if(count
< (INT
) sizeof(DIBSECTION
))
1078 if (count
> (INT
) sizeof(BITMAP
)) count
= sizeof(BITMAP
);
1082 if (count
> (INT
) sizeof(DIBSECTION
)) count
= sizeof(DIBSECTION
);
1084 memcpy(buffer
, bmp
->dib
, count
);
1089 if (count
> (INT
) sizeof(BITMAP
)) count
= sizeof(BITMAP
);
1090 memcpy(buffer
, &bmp
->bitmap
, count
);