[WIN32K]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Sun, 27 Feb 2011 17:51:37 +0000 (17:51 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Sun, 27 Feb 2011 17:51:37 +0000 (17:51 +0000)
- mark surface as not selected in DC_vSelectSurface when its released from a DC
NtGdiSelectBitmap:
- Don't allow selecting a bitmap into a dc that is already selected!
- Use DC_vSelectSurface instead of manually selecting
- set the DC size based on bitmap size

svn path=/trunk/; revision=50921

reactos/subsystems/win32/win32k/eng/bitblt.c
reactos/subsystems/win32/win32k/include/dc.h
reactos/subsystems/win32/win32k/objects/dcobjs.c

index 3525a2c..029f55e 100644 (file)
@@ -541,8 +541,6 @@ IntEngBitBlt(
     BOOL bResult;
     RECTL rclClipped;
     RECTL rclSrc;
-//    INTENG_ENTER_LEAVE EnterLeaveSource;
-//    INTENG_ENTER_LEAVE EnterLeaveDest;
     PFN_DrvBitBlt pfnBitBlt;
 
     ASSERT(psoTrg);
@@ -552,9 +550,9 @@ IntEngBitBlt(
     rclClipped = *prclTrg;
     RECTL_vMakeWellOrdered(&rclClipped);
 
-    /* Clip target rect against the bounds of the clipping region */
     if (pco)
     {
+        /* Clip target rect against the bounds of the clipping region */
         if (!RECTL_bIntersectRect(&rclClipped, &rclClipped, &pco->rclBounds))
         {
             /* Nothing left */
index 2d94c24..07f412b 100644 (file)
@@ -213,7 +213,10 @@ DC_vSelectSurface(PDC pdc, PSURFACE psurfNew)
 {
     PSURFACE psurfOld = pdc->dclevel.pSurface;
     if (psurfOld)
+    {
+        psurfOld->hdc = NULL;
         SURFACE_ShareUnlockSurface(psurfOld);
+    }
     if (psurfNew)
         GDIOBJ_IncrementShareCount((POBJ)psurfNew);
     pdc->dclevel.pSurface = psurfNew;
index 25e54cb..6975b60 100644 (file)
@@ -257,9 +257,10 @@ NtGdiSelectBitmap(
     PDC pdc;
     PDC_ATTR pdcattr;
     HBITMAP hbmpOld;
-    PSURFACE psurfNew, psurfOld;
+    PSURFACE psurfNew;
     HRGN hVisRgn;
     SIZEL sizlBitmap = {1, 1};
+    HDC hdcOld;
     ASSERT_NOGDILOCKS();
 
     /* Verify parameters */
@@ -280,8 +281,17 @@ NtGdiSelectBitmap(
         return NULL;
     }
 
-    /* Save the old bitmap */
-    psurfOld = pdc->dclevel.pSurface;
+    /* Check if there was a bitmap selected before */
+    if (pdc->dclevel.pSurface)
+    {
+        /* Return its handle */
+        hbmpOld = pdc->dclevel.pSurface->BaseObject.hHmgr;
+    }
+    else
+    {
+        /* Return default bitmap */
+        hbmpOld = StockObjects[DEFAULT_BITMAP];
+    }
 
     /* Check if the default bitmap was passed */
     if (hbmp == StockObjects[DEFAULT_BITMAP])
@@ -300,16 +310,17 @@ NtGdiSelectBitmap(
             DC_UnlockDc(pdc);
             return NULL;
         }
-#if 0 // FIXME: bug bug, causes problems
+
         /* Set the bitmp's hdc */
-        if (InterlockedCompareExchangePointer((PVOID*)&psurfNew->hdc, hdc, 0))
+        hdcOld = InterlockedCompareExchangePointer((PVOID*)&psurfNew->hdc, hdc, 0);
+        if (hdcOld != NULL && hdcOld != hdc)
         {
             /* The bitmap is already selected, fail */
             SURFACE_ShareUnlockSurface(psurfNew);
             DC_UnlockDc(pdc);
             return NULL;
         }
-#endif
+
         /* Get the bitmap size */
         sizlBitmap = psurfNew->SurfObj.sizlBitmap;
 
@@ -325,25 +336,14 @@ NtGdiSelectBitmap(
         }
     }
 
-    /* Select the new bitmap */
-    pdc->dclevel.pSurface = psurfNew;
+    /* Select the new surface, release the old */
+    DC_vSelectSurface(pdc, psurfNew);
 
-    /* Check if there was a bitmap selected before */
-    if (psurfOld)
-    {
-        hbmpOld = psurfOld->BaseObject.hHmgr;
-
-        /* Reset hdc of old bitmap, this surface isn't selected anymore */
-        psurfOld->hdc = NULL;
+    /* Set the new size */
+    pdc->dclevel.sizl = sizlBitmap;
 
-        /* Release the old bitmap */
-        SURFACE_ShareUnlockSurface(psurfOld);
-    }
-    else
-    {
-        /* Return default bitmap */
-        hbmpOld = StockObjects[DEFAULT_BITMAP];
-    }
+    /* Release one reference we added */
+    SURFACE_ShareUnlockSurface(psurfNew);
 
     /* Mark the dc brushes invalid */
     pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE;