[WIN32K]
[reactos.git] / subsystems / win32 / win32k / objects / bitblt.c
index a02d652..7df98ec 100644 (file)
@@ -42,6 +42,8 @@ NtGdiAlphaBlend(
 {
     PDC DCDest;
     PDC DCSrc;
+    HDC ahDC[2];
+    PGDIOBJ apObj[2];
     SURFACE *BitmapDest, *BitmapSrc;
     RECTL DestRect, SourceRect;
     BOOL bResult;
@@ -55,45 +57,30 @@ NtGdiAlphaBlend(
         return FALSE;
     }
 
-    DCDest = DC_LockDc(hDCDest);
-    if (NULL == DCDest)
+    DPRINT("Locking DCs\n");
+    ahDC[0] = hDCDest;
+    ahDC[1] = hDCSrc ;
+    GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
+    DCDest = apObj[0];
+    DCSrc = apObj[1];
+
+    if ((NULL == DCDest) || (NULL == DCSrc))
     {
-        DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCDest);
+        DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hDCDest, hDCSrc);
         SetLastWin32Error(ERROR_INVALID_HANDLE);
+        if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+        if(DCDest) GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
         return FALSE;
     }
 
-    if (DCDest->dctype == DC_TYPE_INFO)
+    if (DCDest->dctype == DC_TYPE_INFO || DCDest->dctype == DCTYPE_INFO)
     {
-        DC_UnlockDc(DCDest);
+        GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+        GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
         /* Yes, Windows really returns TRUE in this case */
         return TRUE;
     }
 
-    if (hDCSrc != hDCDest)
-    {
-        DCSrc = DC_LockDc(hDCSrc);
-        if (NULL == DCSrc)
-        {
-            DC_UnlockDc(DCDest);
-            DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCSrc);
-            SetLastWin32Error(ERROR_INVALID_HANDLE);
-            return FALSE;
-        }
-
-        if (DCSrc->dctype == DC_TYPE_INFO)
-        {
-            DC_UnlockDc(DCSrc);
-            DC_UnlockDc(DCDest);
-            /* Yes, Windows really returns TRUE in this case */
-            return TRUE;
-        }
-    }
-    else
-    {
-        DCSrc = DCDest;
-    }
-
     DestRect.left   = XOriginDest;
     DestRect.top    = YOriginDest;
     DestRect.right  = XOriginDest + WidthDest;
@@ -121,35 +108,35 @@ NtGdiAlphaBlend(
         !SourceRect.right ||
         !SourceRect.bottom)
     {
-        if (hDCSrc != hDCDest)
-            DC_UnlockDc(DCSrc);
-        DC_UnlockDc(DCDest);
+        GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+        GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
         return TRUE;
     }
 
+    /* Prepare DCs for blit */
+    DPRINT("Preparing DCs for blit\n");
+    DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
+
     /* Determine surfaces to be used in the bitblt */
     BitmapDest = DCDest->dclevel.pSurface;
     if (!BitmapDest)
     {
-        if (hDCSrc != hDCDest)
-            DC_UnlockDc(DCSrc);
-        DC_UnlockDc(DCDest);
-        return FALSE;
+        bResult = FALSE ;
+        goto leave ;
     }
 
     BitmapSrc = DCSrc->dclevel.pSurface;
     if (!BitmapSrc)
     {
-        if (hDCSrc != hDCDest)
-            DC_UnlockDc(DCSrc);
-        DC_UnlockDc(DCDest);
-        return FALSE;
+        bResult = FALSE;
+        goto leave;
     }
 
     /* Create the XLATEOBJ. */
     EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
 
     /* Perform the alpha blend operation */
+    DPRINT("Performing the alpha Blend\n");
     bResult = IntEngAlphaBlend(&BitmapDest->SurfObj,
                                &BitmapSrc->SurfObj,
                                DCDest->rosdc.CombinedClip,
@@ -159,9 +146,11 @@ NtGdiAlphaBlend(
                                &BlendObj);
 
     EXLATEOBJ_vCleanup(&exlo);
-    DC_UnlockDc(DCDest);
-    if (hDCSrc != hDCDest)
-        DC_UnlockDc(DCSrc);
+leave :
+    DPRINT("Finishing blit\n");
+    DC_vFinishBlit(DCDest, DCSrc);
+    GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+    GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
 
     return bResult;
 }
@@ -318,6 +307,8 @@ NtGdiTransparentBlt(
     COLORREF TransColor)
 {
     PDC DCDest, DCSrc;
+    HDC ahDC[2];
+    PGDIOBJ apObj[2];
     RECTL rcDest, rcSrc;
     SURFACE *BitmapDest, *BitmapSrc = NULL;
     HPALETTE SourcePalette = 0, DestPalette = 0;
@@ -327,42 +318,54 @@ NtGdiTransparentBlt(
     BOOL Ret = FALSE;
     EXLATEOBJ exlo;
 
-    if(!(DCDest = DC_LockDc(hdcDst)))
+    DPRINT("Locking DCs\n");
+    ahDC[0] = hdcDst;
+    ahDC[1] = hdcSrc ;
+    GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
+    DCDest = apObj[0];
+    DCSrc = apObj[1];
+
+    if ((NULL == DCDest) || (NULL == DCSrc))
     {
-        DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiTransparentBlt\n", hdcDst);
+        DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hdcDst, hdcSrc);
         SetLastWin32Error(ERROR_INVALID_HANDLE);
+        if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+        if(DCDest) GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
         return FALSE;
     }
-    if (DCDest->dctype == DC_TYPE_INFO)
+
+    if (DCDest->dctype == DC_TYPE_INFO || DCDest->dctype == DCTYPE_INFO)
     {
-        DC_UnlockDc(DCDest);
+        GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+        GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
         /* Yes, Windows really returns TRUE in this case */
         return TRUE;
     }
 
-    if((hdcDst != hdcSrc) && !(DCSrc = DC_LockDc(hdcSrc)))
-    {
-        DC_UnlockDc(DCDest);
-        DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiTransparentBlt\n", hdcSrc);
-        SetLastWin32Error(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
+    rcDest.left   = xDst;
+    rcDest.top    = yDst;
+    rcDest.right  = rcDest.left + cxDst;
+    rcDest.bottom = rcDest.top + cyDst;
+    IntLPtoDP(DCDest, (LPPOINT)&rcDest, 2);
 
-    if(hdcDst == hdcSrc)
-    {
-        DCSrc = DCDest;
-    }
+    rcDest.left   += DCDest->ptlDCOrig.x;
+    rcDest.top    += DCDest->ptlDCOrig.y;
+    rcDest.right  += DCDest->ptlDCOrig.x;
+    rcDest.bottom += DCDest->ptlDCOrig.y;
 
-    if (DCSrc->dctype == DC_TYPE_INFO)
-    {
-        DC_UnlockDc(DCSrc);
-        if(hdcDst != hdcSrc)
-        {
-            DC_UnlockDc(DCDest);
-        }
-        /* Yes, Windows really returns TRUE in this case */
-        return TRUE;
-    }
+    rcSrc.left   = xSrc;
+    rcSrc.top    = ySrc;
+    rcSrc.right  = rcSrc.left + cxSrc;
+    rcSrc.bottom = rcSrc.top + cySrc;
+    IntLPtoDP(DCSrc, (LPPOINT)&rcSrc, 2);
+
+    rcSrc.left   += DCSrc->ptlDCOrig.x;
+    rcSrc.top    += DCSrc->ptlDCOrig.y;
+    rcSrc.right  += DCSrc->ptlDCOrig.x;
+    rcSrc.bottom += DCSrc->ptlDCOrig.y;
+
+    /* Prepare for blit */
+    DC_vPrepareDCsForBlit(DCDest, rcDest, DCSrc, rcSrc);
 
     BitmapDest = DCDest->dclevel.pSurface;
     if (!BitmapDest)
@@ -413,39 +416,17 @@ NtGdiTransparentBlt(
 
     EXLATEOBJ_vInitialize(&exlo, PalSourceGDI, PalDestGDI, 0, 0, 0);
 
-    rcDest.left   = xDst;
-    rcDest.top    = yDst;
-    rcDest.right  = rcDest.left + cxDst;
-    rcDest.bottom = rcDest.top + cyDst;
-    IntLPtoDP(DCDest, (LPPOINT)&rcDest, 2);
-
-    rcDest.left   += DCDest->ptlDCOrig.x;
-    rcDest.top    += DCDest->ptlDCOrig.y;
-    rcDest.right  += DCDest->ptlDCOrig.x;
-    rcDest.bottom += DCDest->ptlDCOrig.y;
-
-    rcSrc.left   = xSrc;
-    rcSrc.top    = ySrc;
-    rcSrc.right  = rcSrc.left + cxSrc;
-    rcSrc.bottom = rcSrc.top + cySrc;
-    IntLPtoDP(DCSrc, (LPPOINT)&rcSrc, 2);
-
-    rcSrc.left   += DCSrc->ptlDCOrig.x;
-    rcSrc.top    += DCSrc->ptlDCOrig.y;
-    rcSrc.right  += DCSrc->ptlDCOrig.x;
-    rcSrc.bottom += DCSrc->ptlDCOrig.y;
-
     Ret = IntEngTransparentBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj,
         DCDest->rosdc.CombinedClip, &exlo.xlo, &rcDest, &rcSrc,
         TransparentColor, 0);
 
-done:
-    DC_UnlockDc(DCSrc);
-    if(hdcDst != hdcSrc)
-    {
-        DC_UnlockDc(DCDest);
-    }
     EXLATEOBJ_vCleanup(&exlo);
+
+done:
+    DC_vFinishBlit(DCDest, DCSrc);
+    GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
+    GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+
     return Ret;
 }
 
@@ -833,8 +814,8 @@ GreStretchBltMask(
                 (BitmapMask->SurfObj.sizlBitmap.cx < WidthSrc ||
                  BitmapMask->SurfObj.sizlBitmap.cy < HeightSrc))
             {
-                DPRINT1("%dx%d mask is smaller than %dx%d bitmap\n", 
-                        BitmapMask->SurfObj.sizlBitmap.cx, BitmapMask->SurfObj.sizlBitmap.cy, 
+                DPRINT1("%dx%d mask is smaller than %dx%d bitmap\n",
+                        BitmapMask->SurfObj.sizlBitmap.cx, BitmapMask->SurfObj.sizlBitmap.cy,
                         WidthSrc, HeightSrc);
                 goto failed;
             }