Only set the pattern function pointer if the pattern surface is valid, spotted by...
[reactos.git] / reactos / subsystems / win32 / win32k / eng / bitblt.c
index a5ead86..3c65aaa 100644 (file)
@@ -1,28 +1,10 @@
 /*
- *  ReactOS W32 Subsystem
- *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/* $Id$
- *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * PURPOSE:          GDI BitBlt Functions
  * FILE:             subsys/win32k/eng/bitblt.c
  * PROGRAMER:        Jason Filby
+ *                   Timo Kreuzer
  * REVISION HISTORY:
  *        2/10/1999: Created
  */
 #define NDEBUG
 #include <debug.h>
 
-typedef BOOLEAN (STDCALL *PBLTRECTFUNC)(SURFOBJ* OutputObj,
+typedef BOOLEAN (APIENTRY *PBLTRECTFUNC)(SURFOBJ* OutputObj,
                                         SURFOBJ* InputObj,
                                         SURFOBJ* Mask,
                                         XLATEOBJ* ColorTranslation,
                                         RECTL* OutputRect,
                                         POINTL* InputPoint,
                                         POINTL* MaskOrigin,
-                                        BRUSHOBJ* Brush,
+                                        BRUSHOBJ* pbo,
                                         POINTL* BrushOrigin,
                                         ROP4 Rop4);
-typedef BOOLEAN (STDCALL *PSTRETCHRECTFUNC)(SURFOBJ* OutputObj,
-                                            SURFOBJ* InputObj,
-                                            SURFOBJ* Mask,
-                                            CLIPOBJ* ClipRegion,
-                                            XLATEOBJ* ColorTranslation,
-                                            RECTL* OutputRect,
-                                            RECTL* InputRect,
-                                            POINTL* MaskOrigin,
-                                            POINTL* BrushOrigin,
-                                            ULONG Mode);
-
-BOOL STDCALL EngIntersectRect(RECTL* prcDst, RECTL* prcSrc1, RECTL* prcSrc2)
-{
-    static const RECTL rclEmpty = { 0, 0, 0, 0 };
-
-    prcDst->left  = max(prcSrc1->left, prcSrc2->left);
-    prcDst->right = min(prcSrc1->right, prcSrc2->right);
-
-    if (prcDst->left < prcDst->right)
-    {
-        prcDst->top    = max(prcSrc1->top, prcSrc2->top);
-        prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
-
-        if (prcDst->top < prcDst->bottom)
-        {
-            return TRUE;
-        }
-    }
-
-    *prcDst = rclEmpty;
-
-    return FALSE;
-}
 
-static BOOLEAN STDCALL
-BltMask(SURFOBJ* Dest,
-        SURFOBJ* Source,
-        SURFOBJ* Mask,
-        XLATEOBJ* ColorTranslation,
-        RECTL* DestRect,
-        POINTL* SourcePoint,
-        POINTL* MaskPoint,
-        BRUSHOBJ* Brush,
-        POINTL* BrushPoint,
+static BOOLEAN APIENTRY
+BltMask(SURFOBJ* psoDest,
+        SURFOBJ* psoSource, // unused
+        SURFOBJ* psoMask,
+        XLATEOBJ* ColorTranslation,  // unused
+        RECTL* prclDest,
+        POINTL* pptlSource, // unused
+        POINTL* pptlMask,
+        BRUSHOBJ* pbo,
+        POINTL* pptlBrush,
         ROP4 Rop4)
 {
-    LONG i, j, dx, dy, c8;
-    BYTE *tMask, *lMask;
-    static BYTE maskbit[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
+    LONG x, y;
+    BYTE *pjMskLine, *pjMskCurrent;
+    BYTE fjMaskBit0, fjMaskBit;
     /* Pattern brushes */
-    PGDIBRUSHINST GdiBrush = NULL;
-    SURFOBJ *PatternObj = NULL;
-    PBITMAPOBJ PatternBitmap;
-    ULONG PatternWidth = 0, PatternHeight = 0, PatternY = 0;
-
-    if (Mask == NULL)
+    PEBRUSHOBJ pebo = NULL;
+    SURFOBJ *psoPattern = NULL;
+    PSURFACE psurfPattern;
+    ULONG PatternWidth = 0, PatternHeight = 0;
+    LONG PatternX0 = 0, PatternX = 0, PatternY = 0;
+    PFN_DIB_PutPixel fnDest_PutPixel = NULL;
+    PFN_DIB_GetPixel fnPattern_GetPixel = NULL;
+    ULONG Pattern = 0;
+    HBITMAP hbmPattern;
+
+    if (psoMask == NULL)
     {
         return FALSE;
     }
 
-    dx = DestRect->right  - DestRect->left;
-    dy = DestRect->bottom - DestRect->top;
-
-    if (Brush->iSolidColor == 0xFFFFFFFF)
+    if (pbo && pbo->iSolidColor == 0xFFFFFFFF)
     {
-        GdiBrush = CONTAINING_RECORD(
-                       Brush,
-                       GDIBRUSHINST,
-                       BrushObject);
+        pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
 
-        PatternBitmap = BITMAPOBJ_LockBitmap(GdiBrush->GdiBrushObject->hbmPattern);
-        if (PatternBitmap != NULL)
+        hbmPattern = EBRUSHOBJ_pvGetEngBrush(pebo);
+        psurfPattern = SURFACE_LockSurface(hbmPattern);
+        if (psurfPattern != NULL)
         {
-            PatternObj = &PatternBitmap->SurfObj;
-            PatternWidth = PatternObj->sizlBitmap.cx;
-            PatternHeight = PatternObj->sizlBitmap.cy;
+            psoPattern = &psurfPattern->SurfObj;
+            PatternWidth = psoPattern->sizlBitmap.cx;
+            PatternHeight = psoPattern->sizlBitmap.cy;
+            fnPattern_GetPixel = DibFunctionsForBitmapFormat[psoPattern->iBitmapFormat].DIB_GetPixel;
         }
     }
     else
-        PatternBitmap = NULL;
+        psurfPattern = NULL;
 
-    tMask = (PBYTE)Mask->pvScan0 + SourcePoint->y * Mask->lDelta + (SourcePoint->x >> 3);
-    for (j = 0; j < dy; j++)
-    {
-        lMask = tMask;
-        c8 = SourcePoint->x & 0x07;
+    pjMskLine = (PBYTE)psoMask->pvScan0 + pptlMask->y * psoMask->lDelta + (pptlMask->x >> 3);
+    fjMaskBit0 = 0x80 >> (pptlMask->x & 0x07);
 
-        if (PatternBitmap != NULL)
-            PatternY = (DestRect->top + j) % PatternHeight;
+    fnDest_PutPixel = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_PutPixel;
+    if (psurfPattern)
+    {
+        PatternY = (prclDest->top - pptlBrush->y) % PatternHeight;
+        if (PatternY < 0)
+        {
+            PatternY += PatternHeight;
+        }
+        PatternX0 = (prclDest->left - pptlBrush->x) % PatternWidth;
+        if (PatternX0 < 0)
+        {
+            PatternX0 += PatternWidth;
+        }
 
-        for (i = 0; i < dx; i++)
+        for (y = prclDest->top; y < prclDest->bottom; y++)
         {
-            if (0 != (*lMask & maskbit[c8]))
+            pjMskCurrent = pjMskLine;
+            fjMaskBit = fjMaskBit0;
+            PatternX = PatternX0;
+
+            for (x = prclDest->left; x < prclDest->right; x++)
             {
-                if (PatternBitmap == NULL)
-                {
-                    DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
-                        Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
-                }
-                else
+                if (*pjMskCurrent & fjMaskBit)
                 {
-                    DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
-                        Dest, DestRect->left + i, DestRect->top + j,
-                        DIB_GetSource(PatternObj, (DestRect->left + i) % PatternWidth, PatternY, GdiBrush->XlateObject));
+                    fnDest_PutPixel(psoDest, x, y,
+                        fnPattern_GetPixel(psoPattern, PatternX, PatternY));
                 }
+                fjMaskBit = _rotr8(fjMaskBit, 1);
+                pjMskCurrent += (fjMaskBit >> 7);
+                PatternX++;
+                PatternX %= PatternWidth;
             }
-            c8++;
-            if (8 == c8)
+            pjMskLine += psoMask->lDelta;
+            PatternY++;
+            PatternY %= PatternHeight;
+        }
+    }
+    else
+    {
+        Pattern = pbo ? pbo->iSolidColor : 0;
+        for (y = prclDest->top; y < prclDest->bottom; y++)
+        {
+            pjMskCurrent = pjMskLine;
+            fjMaskBit = fjMaskBit0;
+
+            for (x = prclDest->left; x < prclDest->right; x++)
             {
-                lMask++;
-                c8 = 0;
+                if (*pjMskCurrent & fjMaskBit)
+                {
+                     fnDest_PutPixel(psoDest, x, y, Pattern);
+                }
+                fjMaskBit = _rotr8(fjMaskBit, 1);
+                pjMskCurrent += (fjMaskBit >> 7);
             }
+            pjMskLine += psoMask->lDelta;
         }
-        tMask += Mask->lDelta;
     }
 
-    if (PatternBitmap != NULL)
-        BITMAPOBJ_UnlockBitmap(PatternBitmap);
+    if (psurfPattern)
+        SURFACE_UnlockSurface(psurfPattern);
 
     return TRUE;
 }
 
-static BOOLEAN STDCALL
+static BOOLEAN APIENTRY
 BltPatCopy(SURFOBJ* Dest,
            SURFOBJ* Source,
            SURFOBJ* Mask,
@@ -172,19 +148,19 @@ BltPatCopy(SURFOBJ* Dest,
            RECTL* DestRect,
            POINTL* SourcePoint,
            POINTL* MaskPoint,
-           BRUSHOBJ* Brush,
+           BRUSHOBJ* pbo,
            POINTL* BrushPoint,
            ROP4 Rop4)
 {
     // These functions are assigned if we're working with a DIB
     // The assigned functions depend on the bitsPerPixel of the DIB
 
-    DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_ColorFill(Dest, DestRect, Brush->iSolidColor);
+    DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_ColorFill(Dest, DestRect, pbo ? pbo->iSolidColor : 0);
 
     return TRUE;
 }
 
-static BOOLEAN STDCALL
+static BOOLEAN APIENTRY
 CallDibBitBlt(SURFOBJ* OutputObj,
               SURFOBJ* InputObj,
               SURFOBJ* Mask,
@@ -192,14 +168,15 @@ CallDibBitBlt(SURFOBJ* OutputObj,
               RECTL* OutputRect,
               POINTL* InputPoint,
               POINTL* MaskOrigin,
-              BRUSHOBJ* Brush,
+              BRUSHOBJ* pbo,
               POINTL* BrushOrigin,
               ROP4 Rop4)
 {
     BLTINFO BltInfo;
-    PGDIBRUSHINST GdiBrush = NULL;
-    BITMAPOBJ *bmPattern;
+    PEBRUSHOBJ GdiBrush = NULL;
+    SURFACE *psurfPattern;
     BOOLEAN Result;
+    HBITMAP hbmPattern;
 
     BltInfo.DestSurface = OutputObj;
     BltInfo.SourceSurface = InputObj;
@@ -211,36 +188,36 @@ CallDibBitBlt(SURFOBJ* OutputObj,
     if (ROP3_TO_ROP4(SRCCOPY) == Rop4)
         return DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
 
-    BltInfo.XlatePatternToDest = NULL;
-    BltInfo.Brush = Brush;
+    BltInfo.Brush = pbo;
     BltInfo.BrushOrigin = *BrushOrigin;
     BltInfo.Rop4 = Rop4;
 
     /* Pattern brush */
-    if (ROP4_USES_PATTERN(Rop4) && Brush->iSolidColor == 0xFFFFFFFF)
+    if (ROP4_USES_PATTERN(Rop4) && pbo && pbo->iSolidColor == 0xFFFFFFFF)
     {
-        GdiBrush = CONTAINING_RECORD(Brush, GDIBRUSHINST, BrushObject);
-        if ((bmPattern = BITMAPOBJ_LockBitmap(GdiBrush->GdiBrushObject->hbmPattern)))
+        GdiBrush = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
+        hbmPattern = EBRUSHOBJ_pvGetEngBrush(GdiBrush);
+        psurfPattern = SURFACE_LockSurface(hbmPattern);
+        if (psurfPattern)
         {
-            BltInfo.PatternSurface = &bmPattern->SurfObj;
+            BltInfo.PatternSurface = &psurfPattern->SurfObj;
         }
         else
         {
             /* FIXME - What to do here? */
         }
-        BltInfo.XlatePatternToDest = GdiBrush->XlateObject;
     }
     else
     {
-        bmPattern = NULL;
+        psurfPattern = NULL;
     }
 
     Result = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_BitBlt(&BltInfo);
 
     /* Pattern brush */
-    if (bmPattern != NULL)
+    if (psurfPattern)
     {
-        BITMAPOBJ_UnlockBitmap(bmPattern);
+        SURFACE_UnlockSurface(psurfPattern);
     }
 
     return Result;
@@ -252,7 +229,7 @@ INT __cdecl abs(INT nm);
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL APIENTRY
 NtGdiEngBitBlt(
                 IN SURFOBJ  *psoTrg,
                 IN SURFOBJ  *psoSrc,
@@ -271,7 +248,7 @@ NtGdiEngBitBlt(
     POINTL ptlMask;
     POINTL ptlBrush;
 
-    _SEH_TRY
+    _SEH2_TRY
     {
         ProbeForRead(prclTrg, sizeof(RECTL), 1);
         RtlCopyMemory(&rclTrg,prclTrg, sizeof(RECTL));
@@ -286,11 +263,11 @@ NtGdiEngBitBlt(
         RtlCopyMemory(&ptlBrush, pptlBrush, sizeof(POINTL));
 
     }
-    _SEH_HANDLE
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        _SEH_YIELD(return FALSE);
+        _SEH2_YIELD(return FALSE);
     }
-    _SEH_END;
+    _SEH2_END;
 
     return  EngBitBlt(psoTrg, psoSrc, psoMask, pco, pxlo, &rclTrg, &ptlSrc, &ptlMask, pbo, &ptlBrush, rop4);
 }
@@ -298,7 +275,7 @@ NtGdiEngBitBlt(
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL APIENTRY
 EngBitBlt(SURFOBJ *DestObj,
           SURFOBJ *SourceObj,
           SURFOBJ *Mask,
@@ -307,9 +284,9 @@ EngBitBlt(SURFOBJ *DestObj,
           RECTL *DestRect,
           POINTL *SourcePoint,
           POINTL *MaskOrigin,
-          BRUSHOBJ *Brush,
+          BRUSHOBJ *pbo,
           POINTL *BrushOrigin,
-          ROP4 Rop4)
+          ROP4 rop4)
 {
     BYTE               clippingType;
     RECTL              CombinedRect;
@@ -318,10 +295,7 @@ EngBitBlt(SURFOBJ *DestObj,
     POINTL             InputPoint;
     RECTL              InputRect;
     RECTL              OutputRect;
-    POINTL             Translate;
-    INTENG_ENTER_LEAVE EnterLeaveSource;
-    INTENG_ENTER_LEAVE EnterLeaveDest;
-    SURFOBJ*           InputObj;
+    SURFOBJ*           InputObj = 0;
     SURFOBJ*           OutputObj;
     PBLTRECTFUNC       BltRectFunc;
     BOOLEAN            Ret = TRUE;
@@ -333,9 +307,9 @@ EngBitBlt(SURFOBJ *DestObj,
     BOOL               UsesPattern;
     POINTL             AdjustedBrushOrigin;
 
-    UsesSource = ROP4_USES_SOURCE(Rop4);
-    UsesPattern = ROP4_USES_PATTERN(Rop4);
-    if (R4_NOOP == Rop4)
+    UsesSource = ROP4_USES_SOURCE(rop4);
+    UsesPattern = ROP4_USES_PATTERN(rop4);
+    if (R4_NOOP == rop4)
     {
         /* Copy destination onto itself: nop */
         return TRUE;
@@ -391,14 +365,7 @@ EngBitBlt(SURFOBJ *DestObj,
         InputRect.top = InputPoint.y;
         InputRect.bottom = InputPoint.y + (OutputRect.bottom - OutputRect.top);
 
-        if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE,
-                          &Translate, &InputObj))
-        {
-            return FALSE;
-        }
-
-        InputPoint.x += Translate.x;
-        InputPoint.y += Translate.y;
+        InputObj = SourceObj;
     }
     else
     {
@@ -439,36 +406,20 @@ EngBitBlt(SURFOBJ *DestObj,
     if (OutputRect.right <= OutputRect.left ||
             OutputRect.bottom <= OutputRect.top)
     {
-        if (UsesSource)
-        {
-            IntEngLeave(&EnterLeaveSource);
-        }
         return TRUE;
     }
 
-    if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate,
-                      &OutputObj))
-    {
-        if (UsesSource)
-        {
-            IntEngLeave(&EnterLeaveSource);
-        }
-        return FALSE;
-    }
-
-    OutputRect.left += Translate.x;
-    OutputRect.right += Translate.x;
-    OutputRect.top += Translate.y;
-    OutputRect.bottom += Translate.y;
+    OutputObj = DestObj;
 
     if (BrushOrigin)
     {
-        AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
-        AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
+        AdjustedBrushOrigin.x = BrushOrigin->x;
+        AdjustedBrushOrigin.y = BrushOrigin->y;
     }
     else
     {
-        AdjustedBrushOrigin = Translate;
+        AdjustedBrushOrigin.x = 0;
+        AdjustedBrushOrigin.y = 0;
     }
 
     /* Determine clipping type */
@@ -481,13 +432,13 @@ EngBitBlt(SURFOBJ *DestObj,
         clippingType = ClipRegion->iDComplexity;
     }
 
-    if (R4_MASK == Rop4)
+    if (R4_MASK == rop4)
     {
         BltRectFunc = BltMask;
     }
-    else if (ROP3_TO_ROP4(PATCOPY) == Rop4)
+    else if (ROP3_TO_ROP4(PATCOPY) == rop4)
     {
-        if (Brush->iSolidColor == 0xFFFFFFFF)
+        if (pbo && pbo->iSolidColor == 0xFFFFFFFF)
             BltRectFunc = CallDibBitBlt;
         else
             BltRectFunc = BltPatCopy;
@@ -502,22 +453,22 @@ EngBitBlt(SURFOBJ *DestObj,
     {
         case DC_TRIVIAL:
             Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
-                                 &OutputRect, &InputPoint, MaskOrigin, Brush,
-                                 &AdjustedBrushOrigin, Rop4);
+                                 &OutputRect, &InputPoint, MaskOrigin, pbo,
+                                 &AdjustedBrushOrigin, rop4);
             break;
         case DC_RECT:
             /* Clip the blt to the clip rectangle */
-            ClipRect.left = ClipRegion->rclBounds.left + Translate.x;
-            ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
-            ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
-            ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
-            if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+            ClipRect.left = ClipRegion->rclBounds.left;
+            ClipRect.right = ClipRegion->rclBounds.right;
+            ClipRect.top = ClipRegion->rclBounds.top;
+            ClipRect.bottom = ClipRegion->rclBounds.bottom;
+            if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
             {
                 Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
                 Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
                 Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
-                                     &CombinedRect, &Pt, MaskOrigin, Brush,
-                                     &AdjustedBrushOrigin, Rop4);
+                                     &CombinedRect, &Pt, MaskOrigin, pbo,
+                                     &AdjustedBrushOrigin, rop4);
             }
             break;
         case DC_COMPLEX:
@@ -547,18 +498,18 @@ EngBitBlt(SURFOBJ *DestObj,
 
                 for (i = 0; i < RectEnum.c; i++)
                 {
-                    ClipRect.left = RectEnum.arcl[i].left + Translate.x;
-                    ClipRect.right = RectEnum.arcl[i].right + Translate.x;
-                    ClipRect.top = RectEnum.arcl[i].top + Translate.y;
-                    ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
-                    if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+                    ClipRect.left = RectEnum.arcl[i].left;
+                    ClipRect.right = RectEnum.arcl[i].right;
+                    ClipRect.top = RectEnum.arcl[i].top;
+                    ClipRect.bottom = RectEnum.arcl[i].bottom;
+                    if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
                     {
                         Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
                         Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
                         Ret = (*BltRectFunc)(OutputObj, InputObj, Mask,
                                              ColorTranslation, &CombinedRect, &Pt,
-                                             MaskOrigin, Brush, &AdjustedBrushOrigin,
-                                             Rop4) && Ret;
+                                             MaskOrigin, pbo, &AdjustedBrushOrigin,
+                                             rop4) && Ret;
                     }
                 }
             }
@@ -566,813 +517,175 @@ EngBitBlt(SURFOBJ *DestObj,
             break;
     }
 
-
-    IntEngLeave(&EnterLeaveDest);
-    if (UsesSource)
-    {
-        IntEngLeave(&EnterLeaveSource);
-    }
-
     return Ret;
 }
 
-BOOL STDCALL
-IntEngBitBltEx(SURFOBJ *DestSurf,
-               SURFOBJ *SourceSurf,
-               SURFOBJ *MaskSurf,
-               CLIPOBJ *ClipRegion,
-               XLATEOBJ *ColorTranslation,
-               RECTL *DestRect,
-               POINTL *SourcePoint,
-               POINTL *MaskOrigin,
-               BRUSHOBJ *Brush,
-               POINTL *BrushOrigin,
-               ROP4 Rop4,
-               BOOL RemoveMouse)
+BOOL APIENTRY
+IntEngBitBltEx(
+    SURFOBJ *psoTrg,
+    SURFOBJ *psoSrc,
+    SURFOBJ *psoMask,
+    CLIPOBJ *pco,
+    XLATEOBJ *pxlo,
+    RECTL *prclTrg,
+    POINTL *pptlSrc,
+    POINTL *pptlMask,
+    BRUSHOBJ *pbo,
+    POINTL *pptlBrush,
+    ROP4 rop4,
+    BOOL bRemoveMouse)
 {
-    BOOLEAN ret;
-    RECTL InputClippedRect;
-    RECTL OutputRect;
-    POINTL InputPoint;
-    BOOLEAN UsesSource;
-    BITMAPOBJ *DestObj;
-    BITMAPOBJ *SourceObj = NULL;
+    SURFACE *psurfTrg;
+    SURFACE *psurfSrc = NULL;
+    BOOL bResult;
+    RECTL rclClipped;
+    RECTL rclSrc;
+//    INTENG_ENTER_LEAVE EnterLeaveSource;
+//    INTENG_ENTER_LEAVE EnterLeaveDest;
+    PFN_DrvBitBlt pfnBitBlt;
 
-    if (DestSurf == NULL)
-        return FALSE;
+    ASSERT(psoTrg);
+    psurfTrg = CONTAINING_RECORD(psoTrg, SURFACE, SurfObj);
 
-    ASSERT(DestSurf);
-    DestObj = CONTAINING_RECORD(DestSurf, BITMAPOBJ, SurfObj);
-    ASSERT(DestObj);
+    /* FIXME: Should we really allow to pass non-well-ordered rects? */
+    rclClipped = *prclTrg;
+    RECTL_vMakeWellOrdered(&rclClipped);
 
-    InputClippedRect = *DestRect;
-    if (InputClippedRect.right < InputClippedRect.left)
-    {
-        InputClippedRect.left = DestRect->right;
-        InputClippedRect.right = DestRect->left;
-    }
-    if (InputClippedRect.bottom < InputClippedRect.top)
+    /* Clip target rect against the bounds of the clipping region */
+    if (pco)
     {
-        InputClippedRect.top = DestRect->bottom;
-        InputClippedRect.bottom = DestRect->top;
-    }
-    UsesSource = ROP4_USES_SOURCE(Rop4);
-    if (UsesSource)
-    {
-        if (NULL == SourcePoint || NULL == SourceSurf)
-        {
-            return FALSE;
-        }
-        InputPoint = *SourcePoint;
-
-        /* Make sure we don't try to copy anything outside the valid source
-           region */
-        if (InputPoint.x < 0)
-        {
-            InputClippedRect.left -= InputPoint.x;
-            InputPoint.x = 0;
-        }
-        if (InputPoint.y < 0)
-        {
-            InputClippedRect.top -= InputPoint.y;
-            InputPoint.y = 0;
-        }
-        if (SourceSurf->sizlBitmap.cx < InputPoint.x +
-                InputClippedRect.right -
-                InputClippedRect.left)
+        if (!RECTL_bIntersectRect(&rclClipped, &rclClipped, &pco->rclBounds))
         {
-            InputClippedRect.right = InputClippedRect.left +
-                                     SourceSurf->sizlBitmap.cx - InputPoint.x;
-        }
-        if (SourceSurf->sizlBitmap.cy < InputPoint.y +
-                InputClippedRect.bottom -
-                InputClippedRect.top)
-        {
-            InputClippedRect.bottom = InputClippedRect.top +
-                                      SourceSurf->sizlBitmap.cy - InputPoint.y;
-        }
-
-        if (InputClippedRect.right < InputClippedRect.left ||
-                InputClippedRect.bottom < InputClippedRect.top)
-        {
-            /* Everything clipped away, nothing to do */
+            /* Nothing left */
             return TRUE;
         }
-    }
 
-    /* Clip against the bounds of the clipping region so we won't try to write
-     * outside the surface */
-    if (NULL != ClipRegion)
-    {
-        if (! EngIntersectRect(&OutputRect, &InputClippedRect,
-                               &ClipRegion->rclBounds))
-        {
-            return TRUE;
-        }
-        InputPoint.x += OutputRect.left - InputClippedRect.left;
-        InputPoint.y += OutputRect.top - InputClippedRect.top;
-    }
-    else
-    {
-        OutputRect = InputClippedRect;
+        /* Don't pass a clipobj with only a single rect */
+        if (pco->iDComplexity == DC_RECT)
+            pco = NULL;
     }
 
-    if (RemoveMouse)
+    if (ROP4_USES_SOURCE(rop4))
     {
-        BITMAPOBJ_LockBitmapBits(DestObj);
+        ASSERT(psoSrc);
+        psurfSrc = CONTAINING_RECORD(psoSrc, SURFACE, SurfObj);
 
-        if (UsesSource)
-        {
-            if (SourceSurf != DestSurf)
-            {
-                SourceObj = CONTAINING_RECORD(SourceSurf, BITMAPOBJ, SurfObj);
-                BITMAPOBJ_LockBitmapBits(SourceObj);
-            }
-            MouseSafetyOnDrawStart(SourceSurf, InputPoint.x, InputPoint.y,
-                                   (InputPoint.x + abs(DestRect->right - DestRect->left)),
-                                   (InputPoint.y + abs(DestRect->bottom - DestRect->top)));
-        }
-        MouseSafetyOnDrawStart(DestSurf, OutputRect.left, OutputRect.top,
-                               OutputRect.right, OutputRect.bottom);
+        /* Calculate source rect */
+        rclSrc.left = pptlSrc->x + rclClipped.left - prclTrg->left;
+        rclSrc.top = pptlSrc->y + rclClipped.top - prclTrg->top;
+        rclSrc.right = rclSrc.left + rclClipped.right - rclClipped.left;
+        rclSrc.bottom = rclSrc.top + rclClipped.bottom - rclClipped.top;
     }
-
-    /* No success yet */
-    ret = FALSE;
-
-    /* Call the driver's DrvBitBlt if available */
-    if (DestObj->flHooks & HOOK_BITBLT)
+    else
     {
-        ret = GDIDEVFUNCS(DestSurf).BitBlt(
-                  DestSurf, SourceSurf, MaskSurf, ClipRegion, ColorTranslation,
-                  &OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin,
-                  Rop4);
+        psoSrc = NULL;
+        psurfSrc = NULL;
     }
 
-    if (! ret)
+    if (bRemoveMouse)
     {
-        ret = EngBitBlt(DestSurf, SourceSurf, MaskSurf, ClipRegion, ColorTranslation,
-                        &OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin,
-                        Rop4);
-    }
+        SURFACE_LockBitmapBits(psurfTrg);
 
-    if (RemoveMouse)
-    {
-        MouseSafetyOnDrawEnd(DestSurf);
-        if (UsesSource)
+        if (psoSrc)
         {
-            MouseSafetyOnDrawEnd(SourceSurf);
-            if (SourceSurf != DestSurf)
+            if (psoSrc != psoTrg)
             {
-                BITMAPOBJ_UnlockBitmapBits(SourceObj);
+                SURFACE_LockBitmapBits(psurfSrc);
             }
+            MouseSafetyOnDrawStart(psoSrc, rclSrc.left, rclSrc.top,
+                                   rclSrc.right, rclSrc.bottom);
         }
-
-        BITMAPOBJ_UnlockBitmapBits(DestObj);
-    }
-
-    return ret;
-}
-
-static BOOLEAN STDCALL
-CallDibStretchBlt(SURFOBJ* OutputObj,
-                  SURFOBJ* InputObj,
-                  SURFOBJ* Mask,
-                  CLIPOBJ* ClipRegion,
-                  XLATEOBJ* ColorTranslation,
-                  RECTL* OutputRect,
-                  RECTL* InputRect,
-                  POINTL* MaskOrigin,
-                  POINTL* BrushOrigin,
-                  ULONG Mode)
-{
-    POINTL RealBrushOrigin;
-    if (BrushOrigin == NULL)
-    {
-        RealBrushOrigin.x = RealBrushOrigin.y = 0;
-    }
-    else
-    {
-        RealBrushOrigin = *BrushOrigin;
-    }
-    return DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_StretchBlt(
-               OutputObj, InputObj, OutputRect, InputRect, MaskOrigin, RealBrushOrigin, ClipRegion, ColorTranslation, Mode);
-}
-
-
-BOOL
-STDCALL
-NtGdiEngStretchBlt(
-    IN SURFOBJ  *DestObj,
-    IN SURFOBJ  *SourceObj,
-    IN SURFOBJ  *Mask,
-    IN CLIPOBJ  *ClipRegion,
-    IN XLATEOBJ  *ColorTranslation,
-    IN COLORADJUSTMENT  *pca,
-    IN POINTL  *BrushOrigin,
-    IN RECTL  *prclDest,
-    IN RECTL  *prclSrc,
-    IN POINTL  *MaskOrigin,
-    IN ULONG  Mode
-)
-{
-    COLORADJUSTMENT  ca;
-    POINTL  lBrushOrigin;
-    RECTL rclDest;
-    RECTL rclSrc;
-    POINTL lMaskOrigin;
-
-    _SEH_TRY
-    {
-        ProbeForRead(pca, sizeof(COLORADJUSTMENT), 1);
-        RtlCopyMemory(&ca,pca, sizeof(COLORADJUSTMENT));
-
-        ProbeForRead(BrushOrigin, sizeof(POINTL), 1);
-        RtlCopyMemory(&lBrushOrigin, BrushOrigin, sizeof(POINTL));
-
-        ProbeForRead(prclDest, sizeof(RECTL), 1);
-        RtlCopyMemory(&rclDest, prclDest, sizeof(RECTL));
-
-        ProbeForRead(prclSrc, sizeof(RECTL), 1);
-        RtlCopyMemory(&rclSrc, prclSrc, sizeof(RECTL));
-
-        ProbeForRead(MaskOrigin, sizeof(POINTL), 1);
-        RtlCopyMemory(&lMaskOrigin, MaskOrigin, sizeof(POINTL));
-
-    }
-    _SEH_HANDLE
-    {
-        _SEH_YIELD(return FALSE);
-    }
-    _SEH_END;
-
-    return EngStretchBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation, &ca, &lBrushOrigin, &rclDest, &rclSrc, &lMaskOrigin, Mode);
-}
-
-BOOL
-STDCALL
-EngStretchBlt(
-    IN SURFOBJ  *DestObj,
-    IN SURFOBJ  *SourceObj,
-    IN SURFOBJ  *Mask,
-    IN CLIPOBJ  *ClipRegion,
-    IN XLATEOBJ  *ColorTranslation,
-    IN COLORADJUSTMENT  *pca,
-    IN POINTL  *BrushOrigin,
-    IN RECTL  *prclDest,
-    IN RECTL  *prclSrc,
-    IN POINTL  *MaskOrigin,
-    IN ULONG  Mode
-)
-{
-    // www.osr.com/ddk/graphics/gdifncs_0bs7.htm
-
-    POINTL             InputPoint;
-    RECTL              InputRect;
-    RECTL              OutputRect;
-    POINTL             Translate;
-    INTENG_ENTER_LEAVE EnterLeaveSource;
-    INTENG_ENTER_LEAVE EnterLeaveDest;
-    SURFOBJ*           InputObj;
-    SURFOBJ*           OutputObj;
-    PSTRETCHRECTFUNC   BltRectFunc;
-    BOOLEAN            Ret;
-    POINTL             AdjustedBrushOrigin;
-
-    InputRect.left = prclSrc->left;
-    InputRect.right = prclSrc->right;
-    InputRect.top = prclSrc->top;
-    InputRect.bottom = prclSrc->bottom;
-
-    if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE, &Translate, &InputObj))
-    {
-        return FALSE;
-    }
-
-    InputPoint.x = InputRect.left + Translate.x;
-    InputPoint.y = InputRect.top + Translate.y;
-
-    OutputRect = *prclDest;
-
-    /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
-       nothing to do */
-    if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top)
-    {
-        IntEngLeave(&EnterLeaveSource);
-        return TRUE;
-    }
-
-    if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate, &OutputObj))
-    {
-        IntEngLeave(&EnterLeaveSource);
-        return FALSE;
-    }
-
-    OutputRect.left = prclDest->left + Translate.x;
-    OutputRect.right = prclDest->right + Translate.x;
-    OutputRect.top = prclDest->top + Translate.y;
-    OutputRect.bottom = prclDest->bottom + Translate.y;
-
-    if (NULL != BrushOrigin)
-    {
-        AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
-        AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
-    }
-    else
-    {
-        AdjustedBrushOrigin = Translate;
-    }
-
-    if (Mask != NULL)
-    {
-        //BltRectFunc = BltMask;
-        DPRINT("EngStretchBlt isn't capable of handling mask yet.\n");
-        IntEngLeave(&EnterLeaveDest);
-        IntEngLeave(&EnterLeaveSource);
-
-        return FALSE;
-    }
-    else
-    {
-        BltRectFunc = CallDibStretchBlt;
-    }
-
-
-    Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ClipRegion,
-                         ColorTranslation, &OutputRect, &InputRect, MaskOrigin,
-                         &AdjustedBrushOrigin, Mode);
-
-    IntEngLeave(&EnterLeaveDest);
-    IntEngLeave(&EnterLeaveSource);
-
-    return Ret;
-}
-
-BOOL STDCALL
-IntEngStretchBlt(SURFOBJ *DestSurf,
-                 SURFOBJ *SourceSurf,
-                 SURFOBJ *MaskSurf,
-                 CLIPOBJ *ClipRegion,
-                 XLATEOBJ *ColorTranslation,
-                 RECTL *DestRect,
-                 RECTL *SourceRect,
-                 POINTL *pMaskOrigin,
-                 BRUSHOBJ *Brush,
-                 POINTL *BrushOrigin,
-                 ULONG Mode)
-{
-    BOOLEAN ret;
-    COLORADJUSTMENT ca;
-    POINT MaskOrigin;
-    BITMAPOBJ *DestObj;
-    BITMAPOBJ *SourceObj = NULL;
-
-    ASSERT(DestSurf);
-    DestObj = CONTAINING_RECORD(DestSurf, BITMAPOBJ, SurfObj);
-    ASSERT(DestObj);
-
-    if (pMaskOrigin != NULL)
-    {
-        MaskOrigin.x = pMaskOrigin->x; MaskOrigin.y = pMaskOrigin->y;
-    }
-
-    /* No success yet */
-    ret = FALSE;
-    ASSERT(DestRect);
-    BITMAPOBJ_LockBitmapBits(DestObj);
-    MouseSafetyOnDrawStart(DestSurf, DestRect->left, DestRect->top,
-                           DestRect->right, DestRect->bottom);
-
-    if (NULL != SourceSurf)
-    {
-        SourceObj = CONTAINING_RECORD(SourceSurf, BITMAPOBJ, SurfObj);
-        ASSERT(SourceRect);
-        if (SourceSurf != DestSurf)
-        {
-            BITMAPOBJ_LockBitmapBits(SourceObj);
-        }
-        MouseSafetyOnDrawStart(SourceSurf, SourceRect->left, SourceRect->top,
-                               SourceRect->right, SourceRect->bottom);
+        MouseSafetyOnDrawStart(psoTrg, rclClipped.left, rclClipped.top,
+                               rclClipped.right, rclClipped.bottom);
     }
 
-    /* Prepare color adjustment */
-
-    /* Call the driver's DrvStretchBlt if available */
-    if (DestObj->flHooks & HOOK_STRETCHBLT)
-    {
-        /* Drv->StretchBlt (look at http://www.osr.com/ddk/graphics/ddifncs_3ew7.htm )
-        SURFOBJ *psoMask // optional, if it exists, then rop4=0xCCAA, otherwise rop4=0xCCCC */
-        // FIXME: MaskOrigin is always NULL !
-        ret = GDIDEVFUNCS(DestSurf).StretchBlt(
-                  DestSurf, SourceSurf, MaskSurf, ClipRegion, ColorTranslation,
-                  &ca, BrushOrigin, DestRect, SourceRect, NULL, Mode);
-    }
-
-    if (! ret)
-    {
-        // FIXME: see previous fixme
-        ret = EngStretchBlt(DestSurf, SourceSurf, MaskSurf, ClipRegion, ColorTranslation,
-                            &ca, BrushOrigin, DestRect, SourceRect, NULL, Mode);
-    }
-
-    if (NULL != SourceSurf)
+    /* Is the target surface device managed? */
+    if (psurfTrg->flHooks & HOOK_BITBLT)
     {
-        MouseSafetyOnDrawEnd(SourceSurf);
-        if (SourceSurf != DestSurf)
+        /* Is the source a different device managed surface? */
+        if (psoSrc && psoSrc->hdev != psoTrg->hdev && psurfSrc->flHooks & HOOK_BITBLT)
         {
-            BITMAPOBJ_UnlockBitmapBits(SourceObj);
+            DPRINT1("Need to copy to standard bitmap format!\n");
+            ASSERT(FALSE);
         }
-    }
-    MouseSafetyOnDrawEnd(DestSurf);
-    BITMAPOBJ_UnlockBitmapBits(DestObj);
-
-    return ret;
-}
-
 
-/*
- * @implemented
- */
-BOOL
-STDCALL
-NtGdiEngAlphaBlend(IN SURFOBJ *Dest,
-                   IN SURFOBJ *Source,
-                   IN CLIPOBJ *ClipRegion,
-                   IN XLATEOBJ *ColorTranslation,
-                   IN PRECTL upDestRect,
-                   IN PRECTL upSourceRect,
-                   IN BLENDOBJ *BlendObj)
-{
-    RECTL DestRect;
-    RECTL SourceRect;
-
-    _SEH_TRY
-    {
-        ProbeForRead(upDestRect, sizeof(RECTL), 1);
-        RtlCopyMemory(&DestRect,upDestRect, sizeof(RECTL));
-
-        ProbeForRead(upSourceRect, sizeof(RECTL), 1);
-        RtlCopyMemory(&SourceRect, upSourceRect, sizeof(RECTL));
-
-    }
-    _SEH_HANDLE
-    {
-        _SEH_YIELD(return FALSE);
+        pfnBitBlt = GDIDEVFUNCS(psoTrg).BitBlt;
     }
-    _SEH_END;
-
-    return EngAlphaBlend(Dest, Source, ClipRegion, ColorTranslation, &DestRect, &SourceRect, BlendObj);
-}
 
-/*
- * @implemented
- */
-BOOL
-STDCALL
-EngAlphaBlend(IN SURFOBJ *Dest,
-              IN SURFOBJ *Source,
-              IN CLIPOBJ *ClipRegion,
-              IN XLATEOBJ *ColorTranslation,
-              IN PRECTL DestRect,
-              IN PRECTL SourceRect,
-              IN BLENDOBJ *BlendObj)
-{
-    RECTL              SourceStretchedRect;
-    SIZEL              SourceStretchedSize;
-    HBITMAP            SourceStretchedBitmap = 0;
-    SURFOBJ*           SourceStretchedObj = NULL;
-    RECTL              InputRect;
-    RECTL              OutputRect;
-    RECTL              ClipRect;
-    RECTL              CombinedRect;
-    RECTL              Rect;
-    POINTL             Translate;
-    INTENG_ENTER_LEAVE EnterLeaveSource;
-    INTENG_ENTER_LEAVE EnterLeaveDest;
-    SURFOBJ*           InputObj;
-    SURFOBJ*           OutputObj;
-    LONG               Width;
-    LONG               ClippingType;
-    RECT_ENUM          RectEnum;
-    BOOL               EnumMore;
-    INT                i;
-    BOOLEAN            Ret;
-
-    DPRINT("EngAlphaBlend(Dest:0x%p, Source:0x%p, ClipRegion:0x%p, ColorTranslation:0x%p,\n", Dest, Source, ClipRegion, ColorTranslation);
-    DPRINT("              DestRect:{0x%x, 0x%x, 0x%x, 0x%x}, SourceRect:{0x%x, 0x%x, 0x%x, 0x%x},\n",
-           DestRect->left, DestRect->top, DestRect->right, DestRect->bottom,
-           SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom);
-    DPRINT("              BlendObj:{0x%x, 0x%x, 0x%x, 0x%x}\n", BlendObj->BlendFunction.BlendOp,
-           BlendObj->BlendFunction.BlendFlags, BlendObj->BlendFunction.SourceConstantAlpha,
-           BlendObj->BlendFunction.AlphaFormat);
-
-    /* Validate input */
-    if (DestRect->left >= DestRect->right || DestRect->top >= DestRect->bottom)
-    {
-        DPRINT1("Empty destination rectangle!\n");
-        return FALSE;
-    }
-    if (SourceRect->left >= SourceRect->right || SourceRect->top >= SourceRect->bottom)
-    {
-        DPRINT1("Empty source rectangle!\n");
-        return FALSE;
-    }
-    if (Dest == Source &&
-            !(DestRect->left >= SourceRect->right || SourceRect->left >= DestRect->right ||
-              DestRect->top >= SourceRect->bottom || SourceRect->top >= DestRect->bottom))
-    {
-        DPRINT1("Source and destination rectangles overlap!\n");
-        return FALSE;
-    }
-
-    if (BlendObj->BlendFunction.BlendOp != AC_SRC_OVER)
+    /* Is the source surface device managed? */
+    else if (psoSrc && psurfSrc->flHooks & HOOK_BITBLT)
     {
-        DPRINT1("BlendOp != AC_SRC_OVER (0x%x)\n", BlendObj->BlendFunction.BlendOp);
-        return FALSE;
+        pfnBitBlt = GDIDEVFUNCS(psoSrc).BitBlt;
     }
-    if (BlendObj->BlendFunction.BlendFlags != 0)
-    {
-        DPRINT1("BlendFlags != 0 (0x%x)\n", BlendObj->BlendFunction.BlendFlags);
-        return FALSE;
-    }
-    if ((BlendObj->BlendFunction.AlphaFormat & ~AC_SRC_ALPHA) != 0)
-    {
-        DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendObj->BlendFunction.AlphaFormat);
-        return FALSE;
-    }
-
-    /* Check if there is anything to draw */
-    if (ClipRegion != NULL &&
-            (ClipRegion->rclBounds.left >= ClipRegion->rclBounds.right ||
-             ClipRegion->rclBounds.top >= ClipRegion->rclBounds.bottom))
+    else
     {
-        /* Nothing to do */
-        return TRUE;
+        pfnBitBlt = EngBitBlt;
     }
 
-    /* Stretch source if needed */
-    if (DestRect->right - DestRect->left != SourceRect->right - SourceRect->left ||
-            DestRect->bottom - DestRect->top != SourceRect->bottom - SourceRect->top)
-    {
-        SourceStretchedSize.cx = DestRect->right - DestRect->left;
-        SourceStretchedSize.cy = DestRect->bottom - DestRect->top;
-        Width = DIB_GetDIBWidthBytes(SourceStretchedSize.cx, BitsPerFormat(Source->iBitmapFormat));
-        /* FIXME: Maybe it is a good idea to use EngCreateDeviceBitmap and IntEngStretchBlt
-                  if possible to get a HW accelerated stretch. */
-        SourceStretchedBitmap = EngCreateBitmap(SourceStretchedSize, Width, Source->iBitmapFormat,
-                                                BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
-        if (SourceStretchedBitmap == 0)
-        {
-            DPRINT1("EngCreateBitmap failed!\n");
-            return FALSE;
-        }
-        SourceStretchedObj = EngLockSurface((HSURF)SourceStretchedBitmap);
-        if (SourceStretchedObj == NULL)
-        {
-            DPRINT1("EngLockSurface failed!\n");
-            EngDeleteSurface((HSURF)SourceStretchedBitmap);
-            return FALSE;
-        }
+    bResult = pfnBitBlt(psoTrg,
+                        psoSrc,
+                        psoMask,
+                        pco,
+                        pxlo,
+                        &rclClipped,
+                        (POINTL*)&rclSrc,
+                        pptlMask,
+                        pbo,
+                        pptlBrush,
+                        rop4);
 
-        SourceStretchedRect.left = 0;
-        SourceStretchedRect.right = SourceStretchedSize.cx;
-        SourceStretchedRect.top = 0;
-        SourceStretchedRect.bottom = SourceStretchedSize.cy;
-        /* FIXME: IntEngStretchBlt isn't used here atm because it results in a
-                  try to acquire an already acquired mutex (lock the already locked source surface) */
-        /*if (!IntEngStretchBlt(SourceStretchedObj, Source, NULL, NULL,
-                              NULL, &SourceStretchedRect, SourceRect, NULL,
-                              NULL, NULL, COLORONCOLOR))*/
-        if (!EngStretchBlt(SourceStretchedObj, Source, NULL, NULL, NULL,
-                           NULL, NULL, &SourceStretchedRect, SourceRect,
-                           NULL, COLORONCOLOR))
-        {
-            DPRINT1("EngStretchBlt failed!\n");
-            EngFreeMem(SourceStretchedObj->pvBits);
-            EngUnlockSurface(SourceStretchedObj);
-            EngDeleteSurface((HSURF)SourceStretchedBitmap);
-            return FALSE;
-        }
-        SourceRect = &SourceStretchedRect;
-        Source = SourceStretchedObj;
-    }
+    // FIXME: cleanup temp surface!
 
-    /* Now call the DIB function */
-    InputRect.left = SourceRect->left;
-    InputRect.right = SourceRect->right;
-    InputRect.top = SourceRect->top;
-    InputRect.bottom = SourceRect->bottom;
-    if (!IntEngEnter(&EnterLeaveSource, Source, &InputRect, TRUE, &Translate, &InputObj))
-    {
-        if (SourceStretchedObj != NULL)
-        {
-            EngFreeMem(SourceStretchedObj->pvBits);
-            EngUnlockSurface(SourceStretchedObj);
-        }
-        if (SourceStretchedBitmap != 0)
-        {
-            EngDeleteSurface((HSURF)SourceStretchedBitmap);
-        }
-        return FALSE;
-    }
-    InputRect.left = SourceRect->left + Translate.x;
-    InputRect.right = SourceRect->right + Translate.x;
-    InputRect.top = SourceRect->top + Translate.y;
-    InputRect.bottom = SourceRect->bottom + Translate.y;
-
-    OutputRect.left = DestRect->left;
-    OutputRect.right = DestRect->right;
-    OutputRect.top = DestRect->top;
-    OutputRect.bottom = DestRect->bottom;
-    if (!IntEngEnter(&EnterLeaveDest, Dest, &OutputRect, FALSE, &Translate, &OutputObj))
+    if (bRemoveMouse)
     {
-        IntEngLeave(&EnterLeaveSource);
-        if (SourceStretchedObj != NULL)
+        MouseSafetyOnDrawEnd(psoTrg);
+        if (psoSrc)
         {
-            EngFreeMem(SourceStretchedObj->pvBits);
-            EngUnlockSurface(SourceStretchedObj);
-        }
-        if (SourceStretchedBitmap != 0)
-        {
-            EngDeleteSurface((HSURF)SourceStretchedBitmap);
-        }
-        return FALSE;
-    }
-    OutputRect.left = DestRect->left + Translate.x;
-    OutputRect.right = DestRect->right + Translate.x;
-    OutputRect.top = DestRect->top + Translate.y;
-    OutputRect.bottom = DestRect->bottom + Translate.y;
-
-    Ret = FALSE;
-    ClippingType = (ClipRegion == NULL) ? DC_TRIVIAL : ClipRegion->iDComplexity;
-    switch (ClippingType)
-    {
-        case DC_TRIVIAL:
-            Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
-                      OutputObj, InputObj, &OutputRect, &InputRect, ClipRegion, ColorTranslation, BlendObj);
-            break;
-
-        case DC_RECT:
-            ClipRect.left = ClipRegion->rclBounds.left + Translate.x;
-            ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
-            ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
-            ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
-            if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
-            {
-                Rect.left = InputRect.left + CombinedRect.left - OutputRect.left;
-                Rect.right = InputRect.right + CombinedRect.right - OutputRect.right;
-                Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
-                Rect.bottom = InputRect.bottom + CombinedRect.bottom - OutputRect.bottom;
-                Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
-                          OutputObj, InputObj, &CombinedRect, &Rect, ClipRegion, ColorTranslation, BlendObj);
-            }
-            break;
-
-        case DC_COMPLEX:
-            Ret = TRUE;
-            CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 0);
-            do
+            MouseSafetyOnDrawEnd(psoSrc);
+            if (psoSrc != psoTrg)
             {
-                EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum),
-                                         (PVOID) &RectEnum);
-
-                for (i = 0; i < RectEnum.c; i++)
-                {
-                    ClipRect.left = RectEnum.arcl[i].left + Translate.x;
-                    ClipRect.right = RectEnum.arcl[i].right + Translate.x;
-                    ClipRect.top = RectEnum.arcl[i].top + Translate.y;
-                    ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
-                    if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
-                    {
-                        Rect.left = InputRect.left + CombinedRect.left - OutputRect.left;
-                        Rect.right = InputRect.right + CombinedRect.right - OutputRect.right;
-                        Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
-                        Rect.bottom = InputRect.bottom + CombinedRect.bottom - OutputRect.bottom;
-                        Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
-                                  OutputObj, InputObj, &CombinedRect, &Rect, ClipRegion, ColorTranslation, BlendObj) && Ret;
-                    }
-                }
+                SURFACE_UnlockBitmapBits(psurfSrc);
             }
-            while (EnumMore);
-            break;
-
-        default:
-            UNIMPLEMENTED;
-            ASSERT(FALSE);
-            break;
-    }
-
-    IntEngLeave(&EnterLeaveDest);
-    IntEngLeave(&EnterLeaveSource);
+        }
 
-    if (SourceStretchedObj != NULL)
-    {
-        EngFreeMem(SourceStretchedObj->pvBits);
-        EngUnlockSurface(SourceStretchedObj);
-    }
-    if (SourceStretchedBitmap != 0)
-    {
-        EngDeleteSurface((HSURF)SourceStretchedBitmap);
+        SURFACE_UnlockBitmapBits(psurfTrg);
     }
 
-    return Ret;
+    return bResult;
 }
 
-BOOL STDCALL
-IntEngAlphaBlend(IN SURFOBJ *Dest,
-                 IN SURFOBJ *Source,
-                 IN CLIPOBJ *ClipRegion,
-                 IN XLATEOBJ *ColorTranslation,
-                 IN PRECTL DestRect,
-                 IN PRECTL SourceRect,
-                 IN BLENDOBJ *BlendObj)
-{
-    BOOL ret = FALSE;
-    BITMAPOBJ *DestObj;
-    BITMAPOBJ *SourceObj;
-
-    ASSERT(Dest);
-    DestObj = CONTAINING_RECORD(Dest, BITMAPOBJ, SurfObj);
-    ASSERT(DestObj);
-
-    ASSERT(Source);
-    SourceObj = CONTAINING_RECORD(Source, BITMAPOBJ, SurfObj);
-    ASSERT(SourceObj);
-
-    ASSERT(DestRect);
-    ASSERT(SourceRect);
-
-    /* Check if there is anything to draw */
-    if (ClipRegion != NULL &&
-            (ClipRegion->rclBounds.left >= ClipRegion->rclBounds.right ||
-             ClipRegion->rclBounds.top >= ClipRegion->rclBounds.bottom))
-    {
-        /* Nothing to do */
-        return TRUE;
-    }
-
-    BITMAPOBJ_LockBitmapBits(DestObj);
-    MouseSafetyOnDrawStart(Dest, DestRect->left, DestRect->top,
-                           DestRect->right, DestRect->bottom);
-
-    if (Source != Dest)
-        BITMAPOBJ_LockBitmapBits(SourceObj);
-    MouseSafetyOnDrawStart(Source, SourceRect->left, SourceRect->top,
-                           SourceRect->right, SourceRect->bottom);
-
-    /* Call the driver's DrvAlphaBlend if available */
-    if (DestObj->flHooks & HOOK_ALPHABLEND)
-    {
-        ret = GDIDEVFUNCS(Dest).AlphaBlend(
-                  Dest, Source, ClipRegion, ColorTranslation,
-                  DestRect, SourceRect, BlendObj);
-    }
-
-    if (! ret)
-    {
-        ret = EngAlphaBlend(Dest, Source, ClipRegion, ColorTranslation,
-                            DestRect, SourceRect, BlendObj);
-    }
-
-    MouseSafetyOnDrawEnd(Source);
-    if (Source != Dest)
-        BITMAPOBJ_UnlockBitmapBits(SourceObj);
-    MouseSafetyOnDrawEnd(Dest);
-    BITMAPOBJ_UnlockBitmapBits(DestObj);
-
-    return ret;
-}
 
 /**** REACTOS FONT RENDERING CODE *********************************************/
 
 /* renders the alpha mask bitmap */
-static BOOLEAN STDCALL
-AlphaBltMask(SURFOBJ* Dest,
-             SURFOBJ* Source,
-             SURFOBJ* Mask,
+static BOOLEAN APIENTRY
+AlphaBltMask(SURFOBJ* psoDest,
+             SURFOBJ* psoSource, // unused
+             SURFOBJ* psoMask,
              XLATEOBJ* ColorTranslation,
              XLATEOBJ* SrcColorTranslation,
-             RECTL* DestRect,
-             POINTL* SourcePoint,
-             POINTL* MaskPoint,
-             BRUSHOBJ* Brush,
-             POINTL* BrushPoint)
+             RECTL* prclDest,
+             POINTL* pptlSource, // unused
+             POINTL* pptlMask,
+             BRUSHOBJ* pbo,
+             POINTL* pptlBrush)
 {
     LONG i, j, dx, dy;
     int r, g, b;
     ULONG Background, BrushColor, NewColor;
     BYTE *tMask, *lMask;
 
-    dx = DestRect->right  - DestRect->left;
-    dy = DestRect->bottom - DestRect->top;
+    dx = prclDest->right  - prclDest->left;
+    dy = prclDest->bottom - prclDest->top;
 
-    if (Mask != NULL)
+    if (psoMask != NULL)
     {
-        BrushColor = XLATEOBJ_iXlate(SrcColorTranslation, Brush->iSolidColor);
+        BrushColor = XLATEOBJ_iXlate(SrcColorTranslation, pbo ? pbo->iSolidColor : 0);
         r = (int)GetRValue(BrushColor);
         g = (int)GetGValue(BrushColor);
         b = (int)GetBValue(BrushColor);
 
-        tMask = (PBYTE)Mask->pvScan0 + (SourcePoint->y * Mask->lDelta) + SourcePoint->x;
+        tMask = (PBYTE)psoMask->pvScan0 + (pptlMask->y * psoMask->lDelta) + pptlMask->x;
         for (j = 0; j < dy; j++)
         {
             lMask = tMask;
@@ -1382,12 +695,12 @@ AlphaBltMask(SURFOBJ* Dest,
                 {
                     if (*lMask == 0xff)
                     {
-                        DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
-                            Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
+                        DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_PutPixel(
+                            psoDest, prclDest->left + i, prclDest->top + j, pbo ? pbo->iSolidColor : 0);
                     }
                     else
                     {
-                        Background = DIB_GetSource(Dest, DestRect->left + i, DestRect->top + j,
+                        Background = DIB_GetSource(psoDest, prclDest->left + i, prclDest->top + j,
                                                    SrcColorTranslation);
 
                         NewColor =
@@ -1396,13 +709,13 @@ AlphaBltMask(SURFOBJ* Dest,
                                 (*lMask * (b - GetBValue(Background)) >> 8) + GetBValue(Background));
 
                         Background = XLATEOBJ_iXlate(ColorTranslation, NewColor);
-                        DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
-                            Dest, DestRect->left + i, DestRect->top + j, Background);
+                        DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_PutPixel(
+                            psoDest, prclDest->left + i, prclDest->top + j, Background);
                     }
                 }
                 lMask++;
             }
-            tMask += Mask->lDelta;
+            tMask += psoMask->lDelta;
         }
         return TRUE;
     }
@@ -1412,16 +725,16 @@ AlphaBltMask(SURFOBJ* Dest,
     }
 }
 
-BOOL STDCALL
-EngMaskBitBlt(SURFOBJ *DestObj,
-              SURFOBJ *Mask,
+static
+BOOL APIENTRY
+EngMaskBitBlt(SURFOBJ *psoDest,
+              SURFOBJ *psoMask,
               CLIPOBJ *ClipRegion,
               XLATEOBJ *DestColorTranslation,
               XLATEOBJ *SourceColorTranslation,
               RECTL *DestRect,
-              POINTL *SourcePoint,
-              POINTL *MaskOrigin,
-              BRUSHOBJ *Brush,
+              POINTL *pptlMask,
+              BRUSHOBJ *pbo,
               POINTL *BrushOrigin)
 {
     BYTE               clippingType;
@@ -1434,8 +747,8 @@ EngMaskBitBlt(SURFOBJ *DestObj,
     POINTL             Translate;
     INTENG_ENTER_LEAVE EnterLeaveSource;
     INTENG_ENTER_LEAVE EnterLeaveDest;
-    SURFOBJ*           InputObj;
-    SURFOBJ*           OutputObj;
+    SURFOBJ*           psoInput;
+    SURFOBJ*           psoOutput;
     BOOLEAN            Ret = TRUE;
     RECTL              ClipRect;
     unsigned           i;
@@ -1443,14 +756,14 @@ EngMaskBitBlt(SURFOBJ *DestObj,
     ULONG              Direction;
     POINTL             AdjustedBrushOrigin;
 
-    ASSERT ( Mask );
+    ASSERT(psoMask);
 
-    if (NULL != SourcePoint)
+    if (pptlMask)
     {
-        InputRect.left = SourcePoint->x;
-        InputRect.right = SourcePoint->x + (DestRect->right - DestRect->left);
-        InputRect.top = SourcePoint->y;
-        InputRect.bottom = SourcePoint->y + (DestRect->bottom - DestRect->top);
+        InputRect.left = pptlMask->x;
+        InputRect.right = pptlMask->x + (DestRect->right - DestRect->left);
+        InputRect.top = pptlMask->y;
+        InputRect.bottom = pptlMask->y + (DestRect->bottom - DestRect->top);
     }
     else
     {
@@ -1460,29 +773,12 @@ EngMaskBitBlt(SURFOBJ *DestObj,
         InputRect.bottom = DestRect->bottom - DestRect->top;
     }
 
-    if (! IntEngEnter(&EnterLeaveSource, DestObj, &InputRect, TRUE, &Translate, &InputObj))
-    {
-        return FALSE;
-    }
-
-    if (NULL != SourcePoint)
-    {
-        InputPoint.x = SourcePoint->x + Translate.x;
-        InputPoint.y = SourcePoint->y + Translate.y;
-    }
-    else
-    {
-        InputPoint.x = 0;
-        InputPoint.y = 0;
-    }
-
     OutputRect = *DestRect;
     if (NULL != ClipRegion)
     {
         if (OutputRect.left < ClipRegion->rclBounds.left)
         {
             InputRect.left += ClipRegion->rclBounds.left - OutputRect.left;
-            InputPoint.x += ClipRegion->rclBounds.left - OutputRect.left;
             OutputRect.left = ClipRegion->rclBounds.left;
         }
         if (ClipRegion->rclBounds.right < OutputRect.right)
@@ -1493,7 +789,6 @@ EngMaskBitBlt(SURFOBJ *DestObj,
         if (OutputRect.top < ClipRegion->rclBounds.top)
         {
             InputRect.top += ClipRegion->rclBounds.top - OutputRect.top;
-            InputPoint.y += ClipRegion->rclBounds.top - OutputRect.top;
             OutputRect.top = ClipRegion->rclBounds.top;
         }
         if (ClipRegion->rclBounds.bottom < OutputRect.bottom)
@@ -1503,6 +798,14 @@ EngMaskBitBlt(SURFOBJ *DestObj,
         }
     }
 
+    if (! IntEngEnter(&EnterLeaveSource, psoMask, &InputRect, TRUE, &Translate, &psoInput))
+    {
+        return FALSE;
+    }
+
+    InputPoint.x = InputRect.left + Translate.x;
+    InputPoint.y = InputRect.top + Translate.y;
+
     /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
        nothing to do */
     if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top)
@@ -1511,7 +814,7 @@ EngMaskBitBlt(SURFOBJ *DestObj,
         return TRUE;
     }
 
-    if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate, &OutputObj))
+    if (! IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE, &Translate, &psoOutput))
     {
         IntEngLeave(&EnterLeaveSource);
         return FALSE;
@@ -1541,12 +844,12 @@ EngMaskBitBlt(SURFOBJ *DestObj,
     switch (clippingType)
     {
         case DC_TRIVIAL:
-            if (Mask->iBitmapFormat == BMF_8BPP)
-                Ret = AlphaBltMask(OutputObj, InputObj, Mask, DestColorTranslation, SourceColorTranslation,
-                                   &OutputRect, &InputPoint, MaskOrigin, Brush, &AdjustedBrushOrigin);
+            if (psoMask->iBitmapFormat == BMF_8BPP)
+                Ret = AlphaBltMask(psoOutput, NULL , psoInput, DestColorTranslation, SourceColorTranslation,
+                                   &OutputRect, &InputPoint, pptlMask, pbo, &AdjustedBrushOrigin);
             else
-                Ret = BltMask(OutputObj, InputObj, Mask, DestColorTranslation,
-                              &OutputRect, &InputPoint, MaskOrigin, Brush, &AdjustedBrushOrigin,
+                Ret = BltMask(psoOutput, NULL, psoInput, DestColorTranslation,
+                              &OutputRect, &InputPoint, pptlMask, pbo, &AdjustedBrushOrigin,
                               R4_MASK);
             break;
         case DC_RECT:
@@ -1555,25 +858,25 @@ EngMaskBitBlt(SURFOBJ *DestObj,
             ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
             ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
             ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
-            if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+            if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
             {
                 Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
                 Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
-                if (Mask->iBitmapFormat == BMF_8BPP)
+                if (psoMask->iBitmapFormat == BMF_8BPP)
                 {
-                    Ret = AlphaBltMask(OutputObj, InputObj, Mask, DestColorTranslation, SourceColorTranslation,
-                                       &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin);
+                    Ret = AlphaBltMask(psoOutput, psoInput, psoMask, DestColorTranslation, SourceColorTranslation,
+                                       &CombinedRect, &Pt, pptlMask, pbo, &AdjustedBrushOrigin);
                 }
                 else
                 {
-                    Ret = BltMask(OutputObj, InputObj, Mask, DestColorTranslation,
-                                  &CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin, R4_MASK);
+                    Ret = BltMask(psoOutput, psoInput, psoMask, DestColorTranslation,
+                                  &CombinedRect, &Pt, pptlMask, pbo, &AdjustedBrushOrigin, R4_MASK);
                 }
             }
             break;
         case DC_COMPLEX:
             Ret = TRUE;
-            if (OutputObj == InputObj)
+            if (psoOutput == psoInput)
             {
                 if (OutputRect.top < InputPoint.y)
                 {
@@ -1599,23 +902,23 @@ EngMaskBitBlt(SURFOBJ *DestObj,
                     ClipRect.right = RectEnum.arcl[i].right + Translate.x;
                     ClipRect.top = RectEnum.arcl[i].top + Translate.y;
                     ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
-                    if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+                    if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
                     {
                         Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
                         Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
-                        if (Mask->iBitmapFormat == BMF_8BPP)
+                        if (psoMask->iBitmapFormat == BMF_8BPP)
                         {
-                            Ret = AlphaBltMask(OutputObj, InputObj, Mask,
+                            Ret = AlphaBltMask(psoOutput, psoInput, psoMask,
                                                DestColorTranslation,
                                                SourceColorTranslation,
-                                               &CombinedRect, &Pt, MaskOrigin, Brush,
+                                               &CombinedRect, &Pt, pptlMask, pbo,
                                                &AdjustedBrushOrigin) && Ret;
                         }
                         else
                         {
-                            Ret = BltMask(OutputObj, InputObj, Mask,
+                            Ret = BltMask(psoOutput, psoInput, psoMask,
                                           DestColorTranslation, &CombinedRect, &Pt,
-                                          MaskOrigin, Brush, &AdjustedBrushOrigin,
+                                          pptlMask, pbo, &AdjustedBrushOrigin,
                                           R4_MASK) && Ret;
                         }
                     }
@@ -1632,35 +935,34 @@ EngMaskBitBlt(SURFOBJ *DestObj,
     return Ret;
 }
 
-BOOL STDCALL
-IntEngMaskBlt(SURFOBJ *DestSurf,
-              SURFOBJ *Mask,
+BOOL APIENTRY
+IntEngMaskBlt(SURFOBJ *psoDest,
+              SURFOBJ *psoMask,
               CLIPOBJ *ClipRegion,
               XLATEOBJ *DestColorTranslation,
               XLATEOBJ *SourceColorTranslation,
               RECTL *DestRect,
-              POINTL *SourcePoint,
-              POINTL *MaskOrigin,
-              BRUSHOBJ *Brush,
+              POINTL *pptlMask,
+              BRUSHOBJ *pbo,
               POINTL *BrushOrigin)
 {
     BOOLEAN ret;
     RECTL OutputRect;
     POINTL InputPoint;
-    BITMAPOBJ *DestObj;
+    SURFACE *psurfDest;
 
-    ASSERT(Mask);
+    ASSERT(psoMask);
 
-    if (NULL != SourcePoint)
+    if (pptlMask)
     {
-        InputPoint = *SourcePoint;
+        InputPoint = *pptlMask;
     }
 
     /* Clip against the bounds of the clipping region so we won't try to write
      * outside the surface */
     if (NULL != ClipRegion)
     {
-        if (! EngIntersectRect(&OutputRect, DestRect, &ClipRegion->rclBounds))
+        if (!RECTL_bIntersectRect(&OutputRect, DestRect, &ClipRegion->rclBounds))
         {
             return TRUE;
         }
@@ -1674,31 +976,32 @@ IntEngMaskBlt(SURFOBJ *DestSurf,
 
     /* No success yet */
     ret = FALSE;
-    ASSERT(DestSurf);
-    DestObj = CONTAINING_RECORD(DestSurf, BITMAPOBJ, SurfObj);
+    ASSERT(psoDest);
+    psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
 
-    BITMAPOBJ_LockBitmapBits(DestObj);
-    MouseSafetyOnDrawStart(DestSurf, OutputRect.left, OutputRect.top,
+    SURFACE_LockBitmapBits(psurfDest);
+    MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top,
                            OutputRect.right, OutputRect.bottom);
 
     /* Dummy BitBlt to let driver know that it should flush its changes.
        This should really be done using a call to DrvSynchronizeSurface,
        but the VMware driver doesn't hook that call. */
-    IntEngBitBltEx(DestSurf, NULL, Mask, ClipRegion, DestColorTranslation,
-                   DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin,
+    IntEngBitBltEx(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
+                   DestRect, pptlMask, pptlMask, pbo, BrushOrigin,
                    R4_NOOP, FALSE);
 
-    ret = EngMaskBitBlt(DestSurf, Mask, ClipRegion, DestColorTranslation, SourceColorTranslation,
-                        &OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin);
+    ret = EngMaskBitBlt(psoDest, psoMask, ClipRegion, DestColorTranslation, SourceColorTranslation,
+                        &OutputRect, &InputPoint, pbo, BrushOrigin);
 
     /* Dummy BitBlt to let driver know that something has changed. */
-    IntEngBitBltEx(DestSurf, NULL, Mask, ClipRegion, DestColorTranslation,
-                   DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin,
+    IntEngBitBltEx(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
+                   DestRect, pptlMask, pptlMask, pbo, BrushOrigin,
                    R4_NOOP, FALSE);
 
-    MouseSafetyOnDrawEnd(DestSurf);
-    BITMAPOBJ_UnlockBitmapBits(DestObj);
+    MouseSafetyOnDrawEnd(psoDest);
+    SURFACE_UnlockBitmapBits(psurfDest);
 
     return ret;
 }
+
 /* EOF */