Index: win32ss/CMakeLists.txt =================================================================== --- win32ss/CMakeLists.txt (revision 66893) +++ win32ss/CMakeLists.txt (working copy) @@ -1,5 +1,5 @@ -set(USE_DIBLIB FALSE) +set(USE_DIBLIB TRUE) if(NOT MSVC) # HACK: this should be enabled globally! Index: win32ss/gdi/dib/dib_new.c =================================================================== --- win32ss/gdi/dib/dib_new.c (revision 66891) +++ win32ss/gdi/dib/dib_new.c (working copy) @@ -8,7 +8,7 @@ #include -#include "..\diblib\DibLib_interface.h" +#include "../diblib/DibLib_interface.h" /* Static data */ Index: win32ss/gdi/diblib/BitBlt.c =================================================================== --- win32ss/gdi/diblib/BitBlt.c (revision 66891) +++ win32ss/gdi/diblib/BitBlt.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME BitBlt -#define _DibDoRop(pBltData, M, D, S, P) pBltData->apfnDoRop[0](D,S,P) +#define _DibDoRop(pBltData, M, D, S, P) (pBltData->apfnDoRop[0](D,S,P) & _DEST_MASK) #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/diblib/BitBlt_DSTINVERT.c =================================================================== --- win32ss/gdi/diblib/BitBlt_DSTINVERT.c (revision 66891) +++ win32ss/gdi/diblib/BitBlt_DSTINVERT.c (working copy) @@ -6,7 +6,7 @@ #define __USES_DEST 1 #define __USES_MASK 0 -#define _DibDoRop(pBltData, M, D, S, P) ROP_DSTINVERT(D,S,P) +#define _DibDoRop(pBltData, M, D, S, P) (ROP_DSTINVERT(D,S,P) & _DEST_MASK) #define __FUNCTIONNAME BitBlt_DSTINVERT #include "DibLib_AllDstBPP.h" Index: win32ss/gdi/diblib/BitBlt_MERGECOPY.c =================================================================== --- win32ss/gdi/diblib/BitBlt_MERGECOPY.c (revision 66891) +++ win32ss/gdi/diblib/BitBlt_MERGECOPY.c (working copy) @@ -6,7 +6,7 @@ #define __USES_DEST 0 #define __USES_MASK 0 -#define _DibDoRop(pBltData, M, D, S, P) ROP_MERGECOPY(D,S,P) +#define _DibDoRop(pBltData, M, D, S, P) ROP_MERGECOPY(D,S,P) /* No ANDing needed */ #define __FUNCTIONNAME BitBlt_MERGECOPY #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/diblib/BitBlt_MERGEPAINT.c =================================================================== --- win32ss/gdi/diblib/BitBlt_MERGEPAINT.c (revision 66891) +++ win32ss/gdi/diblib/BitBlt_MERGEPAINT.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME BitBlt_MERGEPAINT -#define _DibDoRop(pBltData, M, D, S, P) ROP_MERGEPAINT(D,S,P) +#define _DibDoRop(pBltData, M, D, S, P) (ROP_MERGEPAINT(D,S,P) & _DEST_MASK) #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/diblib/BitBlt_NOTPATCOPY.c =================================================================== --- win32ss/gdi/diblib/BitBlt_NOTPATCOPY.c (revision 66891) +++ win32ss/gdi/diblib/BitBlt_NOTPATCOPY.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME BitBlt_NOTPATCOPY -#define _DibDoRop(pBltData, M, D, S, P) (~(P)) +#define _DibDoRop(pBltData, M, D, S, P) (ROP_NOTPATCOPY(0,0,P) & _DEST_MASK) #include "DibLib_AllDstBPP.h" Index: win32ss/gdi/diblib/BitBlt_NOTSRCCOPY.c =================================================================== --- win32ss/gdi/diblib/BitBlt_NOTSRCCOPY.c (revision 66891) +++ win32ss/gdi/diblib/BitBlt_NOTSRCCOPY.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME BitBlt_NOTSRCCOPY -#define _DibDoRop(pBltData, M, D, S, P) ROP_NOTSRCCOPY(D,S,P) +#define _DibDoRop(pBltData, M, D, S, P) (ROP_NOTSRCCOPY(D,S,P) & _DEST_MASK) #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/diblib/BitBlt_NOTSRCERASE.c =================================================================== --- win32ss/gdi/diblib/BitBlt_NOTSRCERASE.c (revision 66891) +++ win32ss/gdi/diblib/BitBlt_NOTSRCERASE.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME BitBlt_NOTSRCERASE -#define _DibDoRop(pBltData, M, D, S, P) ROP_NOTSRCERASE(D,S,P) +#define _DibDoRop(pBltData, M, D, S, P) (ROP_NOTSRCERASE(D,S,P) & _DEST_MASK) #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/diblib/BitBlt_PATCOPY.c =================================================================== --- win32ss/gdi/diblib/BitBlt_PATCOPY.c (revision 66891) +++ win32ss/gdi/diblib/BitBlt_PATCOPY.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME BitBlt_PATCOPY -#define _DibDoRop(pBltData, M, D, S, P) ROP_PATCOPY(D,S,P) +#define _DibDoRop(pBltData, M, D, S, P) ROP_PATCOPY(D,S,P) /* No ANDing needed */ #include "DibLib_AllDstBPP.h" Index: win32ss/gdi/diblib/BitBlt_PATINVERT.c =================================================================== --- win32ss/gdi/diblib/BitBlt_PATINVERT.c (revision 66891) +++ win32ss/gdi/diblib/BitBlt_PATINVERT.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME BitBlt_PATINVERT -#define _DibDoRop(pBltData, M, D, S, P) ROP_PATINVERT(D,S,P) +#define _DibDoRop(pBltData, M, D, S, P) ROP_PATINVERT(D,S,P) /* No ANDing needed */ #include "DibLib_AllDstBPP.h" Index: win32ss/gdi/diblib/BitBlt_PATPAINT.c =================================================================== --- win32ss/gdi/diblib/BitBlt_PATPAINT.c (revision 66891) +++ win32ss/gdi/diblib/BitBlt_PATPAINT.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME BitBlt_PATPAINT -#define _DibDoRop(pBltData, M, D, S, P) ROP_PATPAINT(D,S,P) +#define _DibDoRop(pBltData, M, D, S, P) (ROP_PATPAINT(D,S,P) & _DEST_MASK) #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/diblib/BitBlt_SRCAND.c =================================================================== --- win32ss/gdi/diblib/BitBlt_SRCAND.c (revision 66891) +++ win32ss/gdi/diblib/BitBlt_SRCAND.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME BitBlt_SRCAND -#define _DibDoRop(pBltData, M, D, S, P) ROP_SRCAND(D,S,P) +#define _DibDoRop(pBltData, M, D, S, P) ROP_SRCAND(D,S,P) /* No ANDing needed */ #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/diblib/BitBlt_SRCCOPY.c =================================================================== --- win32ss/gdi/diblib/BitBlt_SRCCOPY.c (revision 66891) +++ win32ss/gdi/diblib/BitBlt_SRCCOPY.c (working copy) @@ -1,6 +1,7 @@ #include "DibLib.h" +/* This is a fast xlateless memmove version that can be used for R2L as well */ VOID FASTCALL Dib_BitBlt_SRCCOPY_EqSurf(PBLTDATA pBltData) @@ -16,31 +17,63 @@ cLines = pBltData->ulHeight; while (cLines--) { - memcpy(pjDestBase, pjSrcBase, cjWidth); + /* Use memmove to handle copying right-to-left with overlap */ + memmove(pjDestBase, pjSrcBase, cjWidth); pjDestBase += pBltData->siDst.cjAdvanceY; pjSrcBase += pBltData->siSrc.cjAdvanceY; } } +VOID +FASTCALL +Dib_BitBlt_SRCCOPY_EqSurfR2L(PBLTDATA pBltData) +{ + ULONG cLines, cjWidth; + PBYTE pjDestBase = pBltData->siDst.pjBase; + PBYTE pjSrcBase = pBltData->siSrc.pjBase; + + /* Calculate the width in bytes */ + cjWidth = pBltData->ulWidth * pBltData->siDst.jBpp / 8; + + /* Right-to-left fixup! */ + pjDestBase -= (cjWidth - 1); + pjSrcBase -= (cjWidth - 1); + + /* Loop all lines */ + cLines = pBltData->ulHeight; + while (cLines--) + { + /* Use memmove to handle copying right-to-left with overlap */ + memmove(pjDestBase, pjSrcBase, cjWidth); + pjDestBase += pBltData->siDst.cjAdvanceY; + pjSrcBase += pBltData->siSrc.cjAdvanceY; + } +} + #define Dib_BitBlt_SRCCOPY_S8_D8_EqSurf Dib_BitBlt_SRCCOPY_EqSurf #define Dib_BitBlt_SRCCOPY_S16_D16_EqSurf Dib_BitBlt_SRCCOPY_EqSurf #define Dib_BitBlt_SRCCOPY_S24_D24_EqSurf Dib_BitBlt_SRCCOPY_EqSurf +#define Dib_BitBlt_SRCCOPY_S8_D8_EqSurfR2L Dib_BitBlt_SRCCOPY_EqSurfR2L +#define Dib_BitBlt_SRCCOPY_S16_D16_EqSurfR2L Dib_BitBlt_SRCCOPY_EqSurfR2L +#define Dib_BitBlt_SRCCOPY_S24_D24_EqSurfR2L Dib_BitBlt_SRCCOPY_EqSurfR2L +#define Dib_BitBlt_SRCCOPY_S32_D32_EqSurfR2L Dib_BitBlt_SRCCOPY_EqSurfR2L -/* special movsd optimization on x86 */ +/* special movsd optimization on x86, only for left-to-right */ #if defined(_M_IX86) || defined(_M_AMD64) VOID FASTCALL Dib_BitBlt_SRCCOPY_S32_D32_EqSurf(PBLTDATA pBltData) { - ULONG cLines, cRows = pBltData->ulWidth; + ULONG cLines, cx; PBYTE pjDestBase = pBltData->siDst.pjBase; PBYTE pjSrcBase = pBltData->siSrc.pjBase; /* Loop all lines */ + cx = pBltData->ulWidth; cLines = pBltData->ulHeight; while (cLines--) { - __movsd((PULONG)pjDestBase, (PULONG)pjSrcBase, cRows); + __movsd((PULONG)pjDestBase, (PULONG)pjSrcBase, cx); pjDestBase += pBltData->siDst.cjAdvanceY; pjSrcBase += pBltData->siSrc.cjAdvanceY; } @@ -53,6 +86,7 @@ /* This definition will be checked against in DibLib_BitBlt.h for all "redirected" functions */ #define Dib_BitBlt_SRCCOPY_EqSurf_manual 1 +#define Dib_BitBlt_SRCCOPY_EqSurfR2L_manual 1 #define __USES_SOURCE 1 #define __USES_PATTERN 0 @@ -61,7 +95,7 @@ #define __FUNCTIONNAME BitBlt_SRCCOPY -#define _DibDoRop(pBltData, M, D, S, P) ROP_SRCCOPY(D,S,P) +#define _DibDoRop(pBltData, M, D, S, P) ROP_SRCCOPY(D,S,P) /* No ANDing needed */ #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/diblib/BitBlt_SRCERASE.c =================================================================== --- win32ss/gdi/diblib/BitBlt_SRCERASE.c (revision 66891) +++ win32ss/gdi/diblib/BitBlt_SRCERASE.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME BitBlt_SRCERASE -#define _DibDoRop(pBltData, M, D, S, P) ROP_SRCERASE(D,S,P) +#define _DibDoRop(pBltData, M, D, S, P) (ROP_SRCERASE(D,S,P) & _DEST_MASK) #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/diblib/BitBlt_SRCINVERT.c =================================================================== --- win32ss/gdi/diblib/BitBlt_SRCINVERT.c (revision 66891) +++ win32ss/gdi/diblib/BitBlt_SRCINVERT.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME BitBlt_SRCINVERT -#define _DibDoRop(pBltData, M, D, S, P) ROP_SRCINVERT(D,S,P) +#define _DibDoRop(pBltData, M, D, S, P) ROP_SRCINVERT(D,S,P) /* No ANDing needed */ #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/diblib/BitBlt_SRCPAINT.c =================================================================== --- win32ss/gdi/diblib/BitBlt_SRCPAINT.c (revision 66891) +++ win32ss/gdi/diblib/BitBlt_SRCPAINT.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME BitBlt_SRCPAINT -#define _DibDoRop(pBltData, M, D, S, P) ROP_SRCPAINT(D,S,P) +#define _DibDoRop(pBltData, M, D, S, P) ROP_SRCPAINT(D,S,P) /* No ANDing needed */ #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/diblib/DibLib.h =================================================================== --- win32ss/gdi/diblib/DibLib.h (revision 66891) +++ win32ss/gdi/diblib/DibLib.h (working copy) @@ -8,6 +8,7 @@ #include #include #include +#define _ENGINE_EXPORT_ #include #ifdef _OPTIMIZE_DIBLIB @@ -37,7 +38,7 @@ #define __DIB_FUNCTION_NAME_DST2(name, dst_bpp) Dib_ ## name ## _D ## dst_bpp #define __DIB_FUNCTION_NAME_DST(name, src_bpp, dst_bpp) __DIB_FUNCTION_NAME_DST2(name, dst_bpp) #define __DIB_FUNCTION_NAME_SRCDSTEQ(name, src_bpp, dst_bpp) __PASTE(__DIB_FUNCTION_NAME_SRCDST2(name, src_bpp, dst_bpp), _EqSurf) -#define __DIB_FUNCTION_NAME_SRCDSTEQL2R(name, src_bpp, dst_bpp) __PASTE(__DIB_FUNCTION_NAME_SRCDST2(name, src_bpp, dst_bpp), _EqSurfL2R) +//#define __DIB_FUNCTION_NAME_SRCDSTEQL2R(name, src_bpp, dst_bpp) __PASTE(__DIB_FUNCTION_NAME_SRCDST2(name, src_bpp, dst_bpp), _EqSurfL2R) #define __DIB_FUNCTION_NAME_SRCDSTEQR2L(name, src_bpp, dst_bpp) __PASTE(__DIB_FUNCTION_NAME_SRCDST2(name, src_bpp, dst_bpp), _EqSurfR2L) #define _ReadPixel_1(pjSource, jShift) (((*(pjSource)) >> (jShift)) & 1) Index: win32ss/gdi/diblib/DibLib_AllDstBPP.h =================================================================== --- win32ss/gdi/diblib/DibLib_AllDstBPP.h (revision 66891) +++ win32ss/gdi/diblib/DibLib_AllDstBPP.h (working copy) @@ -8,26 +8,32 @@ #endif #define _DEST_BPP 1 +#define _DEST_MASK 1 #include "DibLib_BitBlt.h" #undef _DEST_BPP #define _DEST_BPP 4 +#define _DEST_MASK 0xf #include "DibLib_BitBlt.h" #undef _DEST_BPP #define _DEST_BPP 8 +#define _DEST_MASK 0xff #include "DibLib_BitBlt.h" #undef _DEST_BPP #define _DEST_BPP 16 +#define _DEST_MASK 0xffff #include "DibLib_BitBlt.h" #undef _DEST_BPP #define _DEST_BPP 24 +#define _DEST_MASK 0xffffff #include "DibLib_BitBlt.h" #undef _DEST_BPP #define _DEST_BPP 32 +#define _DEST_MASK 0xffffffff #include "DibLib_BitBlt.h" #undef _DEST_BPP Index: win32ss/gdi/diblib/DibLib_BitBlt.h =================================================================== --- win32ss/gdi/diblib/DibLib_BitBlt.h (revision 66891) +++ win32ss/gdi/diblib/DibLib_BitBlt.h (working copy) @@ -135,3 +135,4 @@ #undef _DibFunction #undef __FUNCTIONNAME2 +#undef _DEST_MASK Index: win32ss/gdi/diblib/MaskPaint.c =================================================================== --- win32ss/gdi/diblib/MaskPaint.c (revision 66891) +++ win32ss/gdi/diblib/MaskPaint.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME MaskPaint -#define _DibDoRop(pBltData, M, D, S, P) pBltData->apfnDoRop[M](D,0,0) +#define _DibDoRop(pBltData, M, D, S, P) (pBltData->apfnDoRop[M](D,0,0) & _DEST_MASK) #include "DibLib_AllDstBPP.h" Index: win32ss/gdi/diblib/MaskPatBlt.c =================================================================== --- win32ss/gdi/diblib/MaskPatBlt.c (revision 66891) +++ win32ss/gdi/diblib/MaskPatBlt.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME MaskPatBlt -#define _DibDoRop(pBltData, M, D, S, P) pBltData->apfnDoRop[M](0,0,P) +#define _DibDoRop(pBltData, M, D, S, P) (pBltData->apfnDoRop[M](0,0,P) & _DEST_MASK) #include "DibLib_AllDstBPP.h" Index: win32ss/gdi/diblib/MaskPatPaint.c =================================================================== --- win32ss/gdi/diblib/MaskPatPaint.c (revision 66891) +++ win32ss/gdi/diblib/MaskPatPaint.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME MaskPatPaint -#define _DibDoRop(pBltData, M, D, S, P) pBltData->apfnDoRop[M](D,0,P) +#define _DibDoRop(pBltData, M, D, S, P) (pBltData->apfnDoRop[M](D,0,P) & _DEST_MASK) #include "DibLib_AllDstBPP.h" Index: win32ss/gdi/diblib/MaskSrcBlt.c =================================================================== --- win32ss/gdi/diblib/MaskSrcBlt.c (revision 66891) +++ win32ss/gdi/diblib/MaskSrcBlt.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME MaskSrcBlt -#define _DibDoRop(pBltData, M, D, S, P) pBltData->apfnDoRop[M](D,S,0) +#define _DibDoRop(pBltData, M, D, S, P) (pBltData->apfnDoRop[M](D,S,0) & _DEST_MASK) #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/diblib/MaskSrcPaint.c =================================================================== --- win32ss/gdi/diblib/MaskSrcPaint.c (revision 66891) +++ win32ss/gdi/diblib/MaskSrcPaint.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME MaskSrcPaint -#define _DibDoRop(pBltData, M, D, S, P) pBltData->apfnDoRop[M](D,S,0) +#define _DibDoRop(pBltData, M, D, S, P) (pBltData->apfnDoRop[M](D,S,0) & _DEST_MASK) #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/diblib/MaskSrcPatBlt.c =================================================================== --- win32ss/gdi/diblib/MaskSrcPatBlt.c (revision 66891) +++ win32ss/gdi/diblib/MaskSrcPatBlt.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME MaskSrcPatBlt -#define _DibDoRop(pBltData, M, D, S, P) pBltData->apfnDoRop[M](D,S,P) +#define _DibDoRop(pBltData, M, D, S, P) (pBltData->apfnDoRop[M](D,S,P) & _DEST_MASK) #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/diblib/PatPaint.c =================================================================== --- win32ss/gdi/diblib/PatPaint.c (revision 66891) +++ win32ss/gdi/diblib/PatPaint.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME PatPaint -#define _DibDoRop(pBltData, M, D, S, P) pBltData->apfnDoRop[0](D,0,P) +#define _DibDoRop(pBltData, M, D, S, P) (pBltData->apfnDoRop[0](D,0,P) & _DEST_MASK) #include "DibLib_AllDstBPP.h" Index: win32ss/gdi/diblib/RopFunctions.h =================================================================== --- win32ss/gdi/diblib/RopFunctions.h (revision 66891) +++ win32ss/gdi/diblib/RopFunctions.h (working copy) @@ -278,5 +278,6 @@ #define ROP_PATCOPY ROP_P #define ROP_PATPAINT ROP_DPSnoo #define ROP_WHITENESS ROP_1 +#define ROP_NOTPATCOPY ROP_Pn Index: win32ss/gdi/diblib/SrcPaint.c =================================================================== --- win32ss/gdi/diblib/SrcPaint.c (revision 66891) +++ win32ss/gdi/diblib/SrcPaint.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME SrcPaint -#define _DibDoRop(pBltData, M, D, S, P) pBltData->apfnDoRop[0](D,S,0) +#define _DibDoRop(pBltData, M, D, S, P) (pBltData->apfnDoRop[0](D,S,0) & _DEST_MASK) #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/diblib/SrcPatBlt.c =================================================================== --- win32ss/gdi/diblib/SrcPatBlt.c (revision 66891) +++ win32ss/gdi/diblib/SrcPatBlt.c (working copy) @@ -8,7 +8,7 @@ #define __FUNCTIONNAME SrcPatBlt -#define _DibDoRop(pBltData, M, D, S, P) pBltData->apfnDoRop[0](0,S,P) +#define _DibDoRop(pBltData, M, D, S, P) (pBltData->apfnDoRop[0](0,S,P) & _DEST_MASK) #include "DibLib_AllSrcBPP.h" Index: win32ss/gdi/eng/bitblt_new.c =================================================================== --- win32ss/gdi/eng/bitblt_new.c (revision 66891) +++ win32ss/gdi/eng/bitblt_new.c (working copy) @@ -1,3 +1,10 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Implementation of (Int)EngBitBlt and (Int)EngCopyBits + * FILE: win32ss/gdi/eng/bitblt.c + * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org) + */ #include #include "../diblib/DibLib_interface.h" @@ -15,18 +22,198 @@ */ static -void -CalculateCoordinates( - PBLTDATA pbltdata, - PRECTL prclClipped, - PRECTL prclOrg, - PPOINTL pptlSrc, - PPOINTL pptlMask, - PPOINTL pptlPat, - PSIZEL psizlPat) +BOOL +EngSrcBufferedBitBlt ( + _Inout_ SURFOBJ *psoTrg, + _In_ SURFOBJ *psoSrc, + _In_opt_ SURFOBJ *psoMask, + _In_opt_ CLIPOBJ *pco, + _In_opt_ XLATEOBJ *pxlo, + _In_ RECTL *prclTrg, + _When_(psoSrc, _In_) POINTL *pptlSrc, + _When_(psoMask, _In_) POINTL *pptlMask, + _In_opt_ BRUSHOBJ *pbo, + _When_(pbo, _In_) POINTL *pptlBrush, + _In_ ROP4 rop4) { - ULONG cx, cy; + BOOL bResult; + PSURFACE psurfTmp; + SURFOBJ* psoTmp; + RECTL rclTmp; + ULONG iTmpBitmapFormat; + NT_ASSERT(ROP4_USES_SOURCE(rop4)); + NT_ASSERT(psoTrg != NULL); + NT_ASSERT(psoSrc != NULL); + + /* Setup the target rect for the temp surface */ + rclTmp.left = 0; + rclTmp.top = 0; + rclTmp.right = prclTrg->right - prclTrg->left; + rclTmp.bottom = prclTrg->bottom - prclTrg->top; + + /* Get the bitmap format for the temp surface */ + iTmpBitmapFormat = psoSrc->iBitmapFormat; + if (iTmpBitmapFormat == BMF_4RLE) iTmpBitmapFormat = BMF_4BPP; + else if (iTmpBitmapFormat == BMF_8RLE) iTmpBitmapFormat = BMF_8BPP; + + /* Allocate a surface */ + psurfTmp = SURFACE_AllocSurface(STYPE_BITMAP, + rclTmp.right, + rclTmp.bottom, + iTmpBitmapFormat, + 0, + 0, + 0, + NULL); + if (psurfTmp == NULL) + { + ERR("Failed to allocate a surface\n"); + return FALSE; + } + + psoTmp = &psurfTmp->SurfObj; + + /* Check if we have an RLE compressed source */ + if ((psoSrc->iBitmapFormat == BMF_4RLE) || + (psoSrc->iBitmapFormat == BMF_8RLE)) + { + SIZEL sizl; + + /* Decompress the bitmap */ + sizl.cx = rclTmp.right; + sizl.cy = rclTmp.bottom; + DecompressBitmap(sizl, + psoSrc->pvBits, + psoTmp->pvBits, + psoTmp->lDelta, + psoSrc->iBitmapFormat); + bResult = TRUE; + } + else if ((psoSrc->iBitmapFormat > BMF_8RLE)) + { + ERR("Bitmap format %d is not supported!\n", psoSrc->iBitmapFormat); + bResult = FALSE; + } + else + { + /* Copy the bits to the temp surface */ + bResult = EngCopyBits(psoTmp, psoSrc, NULL, NULL, &rclTmp, pptlSrc); + } + + if (bResult) + { + /* Do the actual operation from the temp surface */ + bResult = IntEngBitBlt(psoTrg, + psoTmp, + psoMask, + pco, + pxlo, + prclTrg, + (PPOINTL)&rclTmp, + pptlMask, + pbo, + pptlBrush, + rop4); + } + + /* Delete the temp surface */ + GDIOBJ_vDeleteObject(&psurfTmp->BaseObject); + + return bResult; +} + +static +BOOL +EngTrgBufferedBitBlt ( + _Inout_ SURFOBJ *psoTrg, + _In_opt_ SURFOBJ *psoSrc, + _In_opt_ SURFOBJ *psoMask, + _In_opt_ CLIPOBJ *pco, + _In_opt_ XLATEOBJ *pxlo, + _In_ RECTL *prclTrg, + _When_(psoSrc, _In_) POINTL *pptlSrc, + _When_(psoMask, _In_) POINTL *pptlMask, + _In_opt_ BRUSHOBJ *pbo, + _When_(pbo, _In_) POINTL *pptlBrush, + _In_ ROP4 rop4) +{ + BOOL bResult = TRUE; + PSURFACE psurfTmp; + SURFOBJ* psoTmp; + RECTL rclTmp; + + /* Setup the target rect for the temp surface */ + rclTmp.left = 0; + rclTmp.top = 0; + rclTmp.right = prclTrg->right - prclTrg->left; + rclTmp.bottom = prclTrg->bottom - prclTrg->top; + + /* Allocate a surface */ + psurfTmp = SURFACE_AllocSurface(STYPE_BITMAP, + rclTmp.right, + rclTmp.bottom, + psoTrg->iBitmapFormat, + 0, + 0, + 0, + NULL); + if (psurfTmp == NULL) + { + ERR("Failed to allocate a surface\n"); + return FALSE; + } + + psoTmp = &psurfTmp->SurfObj; + + /* Check if the ROP uses the target pixels */ + if (ROP4_USES_DEST(rop4)) + { + /* Copy the target bits to the target surface */ + bResult = EngCopyBits(psoTmp, psoSrc, NULL, NULL, &rclTmp, (PPOINTL)prclTrg); + } + + if (bResult) + { + /* Do the actual operation to the temp surface */ + bResult = IntEngBitBlt(psoTmp, + psoSrc, + psoMask, + pco, + pxlo, + &rclTmp, + pptlSrc, + pptlMask, + pbo, + pptlBrush, + rop4); + } + + if (bResult) + { + /* Copy the bits to the target surface */ + bResult = EngCopyBits(psoTrg, psoTmp, NULL, NULL, prclTrg, (PPOINTL)&rclTmp); + } + + /* Delete the temp surface */ + GDIOBJ_vDeleteObject(&psurfTmp->BaseObject); + + return bResult; +} + +FORCEINLINE +VOID +CalculateCoordinates ( + _Inout_ PBLTDATA pbltdata, + _In_ PRECTL prclClipped, + _In_ PRECTL prclOrg, + _In_opt_ PPOINTL pptlSrc, + _In_opt_ PPOINTL pptlMask, + _In_opt_ PPOINTL pptlPat, + _In_opt_ PSIZEL psizlPat) +{ + ULONG xOff, yOff; + /* Calculate width and height of this rect */ pbltdata->ulWidth = prclClipped->right - prclClipped->left; pbltdata->ulHeight = prclClipped->bottom - prclClipped->top; @@ -33,19 +220,19 @@ /* Calculate the x offset to the origin coordinates */ if (pbltdata->siDst.iFormat == 0) - cx = (prclClipped->right - 1 - prclOrg->left); + xOff = (prclClipped->right - 1 - prclOrg->left); else - cx = (prclClipped->left - prclOrg->left); + xOff = (prclClipped->left - prclOrg->left); /* Calculate the y offset to the origin coordinates */ if (pbltdata->dy < 0) - cy = (prclClipped->bottom - 1 - prclOrg->top); + yOff = (prclClipped->bottom - 1 - prclOrg->top); else - cy = (prclClipped->top - prclOrg->top); + yOff = (prclClipped->top - prclOrg->top); /* Calculate the target start point */ - pbltdata->siDst.ptOrig.x = prclOrg->left + cx; - pbltdata->siDst.ptOrig.y = prclOrg->top + cy; + pbltdata->siDst.ptOrig.x = prclOrg->left + xOff; + pbltdata->siDst.ptOrig.y = prclOrg->top + yOff; /* Calculate start position for target */ pbltdata->siDst.pjBase = pbltdata->siDst.pvScan0; @@ -55,8 +242,8 @@ if (pptlSrc) { /* Calculate start point and bitpointer for source */ - pbltdata->siSrc.ptOrig.x = pptlSrc->x + cx; - pbltdata->siSrc.ptOrig.y = pptlSrc->y + cy; + pbltdata->siSrc.ptOrig.x = pptlSrc->x + xOff; + pbltdata->siSrc.ptOrig.y = pptlSrc->y + yOff; pbltdata->siSrc.pjBase = pbltdata->siSrc.pvScan0; pbltdata->siSrc.pjBase += pbltdata->siSrc.ptOrig.y * pbltdata->siSrc.lDelta; pbltdata->siSrc.pjBase += pbltdata->siSrc.ptOrig.x * pbltdata->siSrc.jBpp / 8; @@ -65,8 +252,8 @@ if (pptlMask) { /* Calculate start point and bitpointer for mask */ - pbltdata->siMsk.ptOrig.x = pptlMask->x + cx; - pbltdata->siMsk.ptOrig.y = pptlMask->y + cy; + pbltdata->siMsk.ptOrig.x = pptlMask->x + xOff; + pbltdata->siMsk.ptOrig.y = pptlMask->y + yOff; pbltdata->siMsk.pjBase = pbltdata->siMsk.pvScan0; pbltdata->siMsk.pjBase += pbltdata->siMsk.ptOrig.y * pbltdata->siMsk.lDelta; pbltdata->siMsk.pjBase += pbltdata->siMsk.ptOrig.x * pbltdata->siMsk.jBpp / 8; @@ -75,8 +262,8 @@ if (pptlPat) { /* Calculate start point and bitpointer for pattern */ - pbltdata->siPat.ptOrig.x = (pptlPat->x + cx) % psizlPat->cx; - pbltdata->siPat.ptOrig.y = (pptlPat->y + cy) % psizlPat->cy; + pbltdata->siPat.ptOrig.x = (pptlPat->x + xOff) % psizlPat->cx; + pbltdata->siPat.ptOrig.y = (pptlPat->y + yOff) % psizlPat->cy; pbltdata->siPat.pjBase = pbltdata->siPat.pvScan0; /* Check for bottom-up case */ @@ -97,7 +284,7 @@ BOOL APIENTRY -EngBitBlt( +EngBitBlt ( _Inout_ SURFOBJ *psoTrg, _In_opt_ SURFOBJ *psoSrc, _In_opt_ SURFOBJ *psoMask, @@ -111,34 +298,60 @@ _In_ ROP4 rop4) { BLTDATA bltdata; - ULONG i, iFunctionIndex, iDirection = CD_ANY; - RECTL rcTrg; + ULONG i, iFunctionIndex, iDirection; PFN_DIBFUNCTION pfnBitBlt; BOOL bEnumMore; RECT_ENUM rcenum; PSIZEL psizlPat; SURFOBJ *psoPattern; + PFN_DrvCopyBits pfnCopyBits; -//static int count = 0; -//if (++count >= 1230) __debugbreak(); - /* Sanity checks */ - ASSERT(psoTrg); - ASSERT(psoTrg->iBitmapFormat >= BMF_1BPP); - ASSERT(psoTrg->iBitmapFormat <= BMF_32BPP); - ASSERT(prclTrg); - ASSERT(prclTrg->left >= 0); - ASSERT(prclTrg->top >= 0); - ASSERT(prclTrg->right <= psoTrg->sizlBitmap.cx); - ASSERT(prclTrg->bottom <= psoTrg->sizlBitmap.cy); + NT_ASSERT(psoTrg); + NT_ASSERT(psoTrg->iBitmapFormat >= BMF_1BPP); + NT_ASSERT(psoTrg->iBitmapFormat <= BMF_32BPP); + NT_ASSERT(prclTrg); + NT_ASSERT(prclTrg->left >= 0); + NT_ASSERT(prclTrg->top >= 0); + NT_ASSERT(prclTrg->right <= psoTrg->sizlBitmap.cx); + NT_ASSERT(prclTrg->bottom <= psoTrg->sizlBitmap.cy); + ASSERT_DEVLOCK(psoTrg); + ASSERT_DEVLOCK(psoSrc); + ASSERT_DEVLOCK(psoMask); - rcTrg = *prclTrg; + /* Check if the target is not a bitmap */ + if (psoTrg->iType != STYPE_BITMAP) + { + /* Check for special case SRCCOPY to device */ + if ((rop4 == ROP4_SRCCOPY) && + ((psoSrc->iType == STYPE_BITMAP) || (psoSrc->hdev == psoTrg->hdev))) + { + /* Use the driver's DrvCopyBits */ + pfnCopyBits = GDIDEVFUNCS(psoTrg).CopyBits; + return pfnCopyBits(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc); + } + /* We need to do a buffered bitblt */ + return EngTrgBufferedBitBlt(psoTrg, + psoSrc, + psoMask, + pco, + pxlo, + prclTrg, + pptlSrc, + pptlMask, + pbo, + pptlBrush, + rop4); + } + + if (!pxlo) pxlo = &gexloTrivial.xlo; + + /* Initialize the BLTINFO structure */ bltdata.dy = 1; bltdata.rop4 = rop4; bltdata.apfnDoRop[0] = gapfnRop[ROP4_BKGND(rop4)]; bltdata.apfnDoRop[1] = gapfnRop[ROP4_FGND(rop4)]; - if (!pxlo) pxlo = &gexloTrivial.xlo; bltdata.pxlo = pxlo; bltdata.pfnXlate = XLATEOBJ_pfnXlate(pxlo); @@ -146,35 +359,65 @@ if (ROP4_USES_SOURCE(rop4)) { /* Sanity checks */ - ASSERT(psoSrc); - ASSERT(psoSrc->iBitmapFormat >= BMF_1BPP); - ASSERT(psoSrc->iBitmapFormat <= BMF_32BPP); - ASSERT(pptlSrc); - ASSERT(pptlSrc->x >= 0); - ASSERT(pptlSrc->y >= 0); - ASSERT(pptlSrc->x <= psoSrc->sizlBitmap.cx); - ASSERT(pptlSrc->y <= psoSrc->sizlBitmap.cy); + NT_ASSERT(psoSrc); + NT_ASSERT(psoSrc->iBitmapFormat >= BMF_1BPP); + NT_ASSERT(psoSrc->iBitmapFormat <= BMF_8RLE); + NT_ASSERT(pptlSrc); + NT_ASSERT(pptlSrc->x >= 0); + NT_ASSERT(pptlSrc->y >= 0); + NT_ASSERT(pptlSrc->x <= psoSrc->sizlBitmap.cx); + NT_ASSERT(pptlSrc->y <= psoSrc->sizlBitmap.cy); - /* Check if source and target are equal */ + /* Check for special case SRCCOPY from device */ + if ((rop4 == ROP4_SRCCOPY) && + (psoSrc->iType != STYPE_BITMAP) && + ((psoTrg->iType == STYPE_BITMAP) || (psoSrc->hdev == psoTrg->hdev))) + { + /* Use the driver's DrvCopyBits */ + pfnCopyBits = GDIDEVFUNCS(psoSrc).CopyBits; + return pfnCopyBits(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc); + } + + /* Check if the source is not a normal bitmap */ + if ((psoSrc->iType != STYPE_BITMAP) || + (psoSrc->iBitmapFormat > BMF_32BPP)) + { + /* We need to do a buffered bitblt */ + return EngSrcBufferedBitBlt(psoTrg, + psoSrc, + psoMask, + pco, + pxlo, + prclTrg, + pptlSrc, + pptlMask, + pbo, + pptlBrush, + rop4); + } + + /* Check if source and target surface are equal */ if (psoSrc == psoTrg) { /* Analyze the copying direction */ - if (rcTrg.top > pptlSrc->y) + if (prclTrg->top > pptlSrc->y) { /* Need to copy from bottom to top */ - iDirection = rcTrg.left < pptlSrc->x ? CD_RIGHTUP : CD_LEFTUP; + iDirection = prclTrg->left < pptlSrc->x ? CD_RIGHTUP : CD_LEFTUP; bltdata.dy = -1; } else - iDirection = rcTrg.left < pptlSrc->x ? CD_RIGHTDOWN : CD_LEFTDOWN; + { + /* We copy from top to bottom */ + iDirection = prclTrg->left < pptlSrc->x ? CD_RIGHTDOWN : CD_LEFTDOWN; + } /* Check for special right to left case */ - if ((rcTrg.top == pptlSrc->y) && (rcTrg.left > pptlSrc->x)) + if ((prclTrg->top == pptlSrc->y) && (prclTrg->left > pptlSrc->x)) { /* Use 0 as target format to get special right to left versions */ bltdata.siDst.iFormat = 0; bltdata.siSrc.iFormat = psoSrc->iBitmapFormat; - //__debugbreak(); } else { @@ -185,11 +428,12 @@ } else { + iDirection = CD_ANY; bltdata.siDst.iFormat = psoTrg->iBitmapFormat; bltdata.siSrc.iFormat = psoSrc->iBitmapFormat; } - /* Set the source format info */ + /* Set the rest of the source format info */ bltdata.siSrc.pvScan0 = psoSrc->pvScan0; bltdata.siSrc.lDelta = psoSrc->lDelta; bltdata.siSrc.cjAdvanceY = bltdata.dy * psoSrc->lDelta; @@ -197,10 +441,11 @@ } else { + iDirection = CD_ANY; bltdata.siDst.iFormat = psoTrg->iBitmapFormat; } - /* Set the destination format info */ + /* Set the rest of the destination format info */ bltdata.siDst.pvScan0 = psoTrg->pvScan0; bltdata.siDst.lDelta = psoTrg->lDelta; bltdata.siDst.cjAdvanceY = bltdata.dy * psoTrg->lDelta; @@ -314,7 +559,7 @@ else { /* Use the target rect */ - rcenum.arcl[0] = rcTrg; + rcenum.arcl[0] = *prclTrg; rcenum.c = 1; bEnumMore = FALSE; } @@ -326,7 +571,7 @@ for (i = 0; i < rcenum.c; i++) { /* Intersect this rect with the target rect */ - if (!RECTL_bIntersectRect(&rcenum.arcl[i], &rcenum.arcl[i], &rcTrg)) + if (!RECTL_bIntersectRect(&rcenum.arcl[i], &rcenum.arcl[i], prclTrg)) { /* This rect is outside the bounds, continue */ continue; @@ -403,11 +648,11 @@ //__debugbreak(); /* Sanity checks */ - ASSERT(IS_VALID_ROP4(rop4)); - ASSERT(psoTrg); - ASSERT(psoTrg->iBitmapFormat >= BMF_1BPP); - ASSERT(psoTrg->iBitmapFormat <= BMF_32BPP); - ASSERT(prclTrg); + NT_ASSERT(IS_VALID_ROP4(rop4)); + NT_ASSERT(psoTrg); + NT_ASSERT(psoTrg->iBitmapFormat >= BMF_1BPP); + NT_ASSERT(psoTrg->iBitmapFormat <= BMF_32BPP); + NT_ASSERT(prclTrg); /* Clip the target rect to the extents of the target surface */ rcClipped.left = max(prclTrg->left, 0); @@ -416,10 +661,11 @@ rcClipped.bottom = min(prclTrg->bottom, psoTrg->sizlBitmap.cy); /* If no clip object is given, use trivial one */ - if (!pco) pco = (CLIPOBJ*)&gxcoTrivial; + if (pco == NULL) + pco = (CLIPOBJ*)&gxcoTrivial; - /* Check if there is something to clip */ - if (pco->iDComplexity != DC_TRIVIAL) + /* Check if there is anything to clip */ + else if (pco->iDComplexity != DC_TRIVIAL) { /* Clip the target rect to the bounds of the clipping region */ if (!RECTL_bIntersectRect(&rcClipped, &rcClipped, &pco->rclBounds)) @@ -427,11 +673,12 @@ /* Nothing left */ return TRUE; } + + /* Don't pass a clip object with a single rectangle */ + if (pco->iDComplexity == DC_RECT) + pco = (CLIPOBJ*)&gxcoTrivial; } - /* Don't pass a clip object with a single rectangle */ - if (pco->iDComplexity == DC_RECT) pco = (CLIPOBJ*)&gxcoTrivial; - /* Calculate initial offset and size */ ptOffset.x = rcClipped.left - prclTrg->left; ptOffset.y = rcClipped.top - prclTrg->top; @@ -442,8 +689,8 @@ if (ROP4_USES_SOURCE(rop4)) { /* Must have a source surface and point */ - ASSERT(psoSrc); - ASSERT(pptlSrc); + NT_ASSERT(psoSrc); + NT_ASSERT(pptlSrc); /* Get the source point */ ptSrc = *pptlSrc; @@ -450,6 +697,8 @@ /* Clip against the extents of the source surface */ AdjustOffsetAndSize(&ptOffset, &sizTrg, &ptSrc, &psoSrc->sizlBitmap); + + /// FIXME: do we need to draw black? } else { @@ -462,8 +711,8 @@ if (ROP4_USES_MASK(rop4)) { /* Must have a mask surface and point */ - ASSERT(psoMask); - ASSERT(pptlMask); + NT_ASSERT(psoMask); + NT_ASSERT(pptlMask); /* Get the mask point */ ptMask = *pptlMask; @@ -503,14 +752,26 @@ rcClipped.bottom = rcClipped.top + sizTrg.cy; /* Is the target surface device managed? */ - if (SURFOBJ_flags(psoTrg) & HOOK_BITBLT) + if ((psoTrg->iType != STYPE_BITMAP) || + (SURFOBJ_flags(psoTrg) & HOOK_BITBLT)) { /* Is the source a different device managed surface? */ - if (psoSrc && (psoSrc->hdev != psoTrg->hdev) && - (SURFOBJ_flags(psoSrc) & HOOK_BITBLT)) + if (psoSrc && + (psoSrc->iType != STYPE_BITMAP) && + (psoSrc->hdev != psoTrg->hdev)) { - ERR("Need to copy to standard bitmap format!\n"); - ASSERT(FALSE); + /* We need to do a buffered bitblt */ + return EngSrcBufferedBitBlt(psoTrg, + psoSrc, + psoMask, + pco, + pxlo, + prclTrg, + pptlSrc, + pptlMask, + pbo, + pptlBrush, + rop4); } pfnBitBlt = GDIDEVFUNCS(psoTrg).BitBlt; @@ -537,8 +798,6 @@ pptlBrush ? &ptBrush : NULL, rop4); - // FIXME: cleanup temp surface! - return bResult; } @@ -567,6 +826,11 @@ BRUSHOBJ *pbo; BOOL bResult; + DBG_UNREFERENCED_LOCAL_VARIABLE(hBrushObj); + DBG_UNREFERENCED_LOCAL_VARIABLE(hsurfTrg); + DBG_UNREFERENCED_LOCAL_VARIABLE(hsurfSrc); + DBG_UNREFERENCED_LOCAL_VARIABLE(hsurfMask); + _SEH2_TRY { ProbeForRead(prclTrg, sizeof(RECTL), 1); @@ -643,18 +907,53 @@ { PFN_DrvCopyBits pfnCopyBits; + /* Fail, if the target format is compressed */ + if (psoTrg->iBitmapFormat > BMF_32BPP) + { + NT_ASSERT(FALSE); + return FALSE; + } + + /* It would be a better approach to have a function that does a CopyBits / + SRCCOPY from an RLE surface to a different surface directly. Until we + have that, we simply handle this using an intermediate surface, where + we decompress the RLE bits into. */ + + /* Check if we have a compressed source format + or 2 incompatible device surfaces */ + if ((psoSrc->iBitmapFormat > BMF_32BPP) || + ((psoSrc->iType != STYPE_BITMAP) && + (psoTrg->iType != STYPE_BITMAP) && + (psoSrc->hdev != psoTrg->hdev))) + { + /* We need to create a temp bitmap */ + return EngSrcBufferedBitBlt(psoTrg, + psoSrc, + NULL, + pco, + pxlo, + prclTrg, + pptlSrc, + NULL, + NULL, + NULL, + ROP4_SRCCOPY); + } + /* Is the target surface device managed? */ - if (SURFOBJ_flags(psoTrg) & HOOK_COPYBITS) + if ((psoTrg->iType != STYPE_BITMAP) || + (SURFOBJ_flags(psoTrg) & HOOK_COPYBITS)) { pfnCopyBits = GDIDEVFUNCS(psoTrg).CopyBits; } - if (SURFOBJ_flags(psoSrc) & HOOK_COPYBITS) + else if ((psoSrc->iType != STYPE_BITMAP) || + (SURFOBJ_flags(psoSrc) & HOOK_COPYBITS)) { pfnCopyBits = GDIDEVFUNCS(psoSrc).CopyBits; } else { - /* Use SRCCOPY for 2 bitmaps */ + /* Use EngBitBlt for 2 bitmaps */ return EngBitBlt(psoTrg, psoSrc, NULL, Index: win32ss/gdi/eng/pdevobj.h =================================================================== --- win32ss/gdi/eng/pdevobj.h (revision 66891) +++ win32ss/gdi/eng/pdevobj.h (working copy) @@ -201,4 +201,11 @@ PPDEVOBJ ppdev, PDEVMODEW pdm); +FORCEINLINE +BOOL +PDEVOBJ_bLockIsOwned(PPDEVOBJ ppdev) +{ + return ExIsResourceAcquiredExclusiveLite((PERESOURCE)ppdev->hsemDevLock); +} + #endif /* !__WIN32K_PDEVOBJ_H */ Index: win32ss/gdi/eng/surface.c =================================================================== --- win32ss/gdi/eng/surface.c (revision 66891) +++ win32ss/gdi/eng/surface.c (working copy) @@ -301,6 +301,17 @@ return psurf; } +BOOL +NTAPI +SURFACE_bIsDeviceSurface( + _In_ PSURFACE psurf) +{ + PPDEVOBJ ppdev = (PPDEVOBJ)psurf->SurfObj.hdev; + + /* Check if the surface is the related PDEVOBJ's surface */ + return ((ppdev != 0) && (psurf == ppdev->pSurface)); +} + HBITMAP APIENTRY EngCreateBitmap( Index: win32ss/gdi/eng/surface.h =================================================================== --- win32ss/gdi/eng/surface.h (revision 66891) +++ win32ss/gdi/eng/surface.h (working copy) @@ -126,6 +126,18 @@ _In_opt_ ULONG cjBits, _In_opt_ PVOID pvBits); +BOOL +NTAPI +SURFACE_bIsDeviceSurface( + _In_ PSURFACE psurf); + +#define SURFOBJ_bIsDeviceSurface(pso) \ + SURFACE_bIsDeviceSurface(CONTAINING_RECORD(pso, SURFACE, SurfObj)) + +#define ASSERT_DEVLOCK(pso) \ + ASSERT(!pso || !SURFOBJ_bIsDeviceSurface(pso) || \ + PDEVOBJ_bLockIsOwned((PPDEVOBJ)pso->hdev)) + FORCEINLINE VOID SURFACE_vSetPalette(