[CMAKE]
[reactos.git] / subsystems / win32 / win32k / objects / dcstate.c
index 9e491a4..5af2052 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMER:         Timo Kreuzer (timo.kreuzer@rectos.org)
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -15,9 +15,14 @@ VOID
 FASTCALL
 DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
 {
+    DPRINT("DC_vCopyState(%p, %p)\n", pdcSrc->BaseObject.hHmgr, pdcDst->BaseObject.hHmgr);
+
     /* Copy full DC attribute */
     *pdcDst->pdcattr = *pdcSrc->pdcattr;
-    
+
+    /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
+    /* The VisRectRegion field needs to be set to a valid state */
+
     /* Mark some fields as dirty */
     pdcDst->pdcattr->ulDirty_ |= 0x0012001f; // Note: Use if, To is FALSE....
 
@@ -36,7 +41,6 @@ DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
     pdcDst->dclevel.hpal            = pdcSrc->dclevel.hpal;
 
     /* Handle references here correctly */
-    DC_vSelectSurface(pdcDst, pdcSrc->dclevel.pSurface);
     DC_vSelectFillBrush(pdcDst, pdcSrc->dclevel.pbrFill);
     DC_vSelectLineBrush(pdcDst, pdcSrc->dclevel.pbrLine);
     DC_vSelectPalette(pdcDst, pdcSrc->dclevel.ppal);
@@ -44,12 +48,6 @@ DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
     // FIXME: handle refs
     pdcDst->dclevel.plfnt           = pdcSrc->dclevel.plfnt;
 
-    /* ROS hacks */
-    if (pdcDst->dctype != DC_TYPE_MEMORY)
-    {
-        pdcDst->rosdc.bitsPerPixel = pdcSrc->rosdc.bitsPerPixel;
-    }
-
     /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
     if (To) // Copy "To" SaveDC state.
     {
@@ -77,11 +75,6 @@ IntGdiCleanDC(HDC hDC)
     // Clean the DC
     if (defaultDCstate) DC_vCopyState(defaultDCstate, dc, FALSE);
 
-    if (dc->dctype != DC_TYPE_MEMORY)
-    {
-        dc->rosdc.bitsPerPixel = defaultDCstate->rosdc.bitsPerPixel;
-    }
-
     DC_UnlockDc(dc);
 
     return TRUE;
@@ -102,53 +95,31 @@ NtGdiResetDC(
 }
 
 
-BOOL
-APIENTRY
-NtGdiRestoreDC(
-    HDC hdc,
+VOID
+NTAPI
+DC_vRestoreDC(
+    IN PDC pdc,
     INT iSaveLevel)
 {
-    PDC pdc, pdcSave;
     HDC hdcSave;
+    PDC pdcSave;
 
-    DPRINT("NtGdiRestoreDC(%lx, %d)\n", hdc, iSaveLevel);
-
-    /* Lock the original DC */
-    pdc = DC_LockDc(hdc);
-    if (!pdc)
-    {
-        SetLastWin32Error(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-
-    ASSERT(pdc->dclevel.lSaveDepth > 0);
-
-    /* Negative values are relative to the stack top */
-    if (iSaveLevel < 0)
-        iSaveLevel = pdc->dclevel.lSaveDepth + iSaveLevel;
-
-    /* Check if we have a valid instance */
-    if (iSaveLevel <= 0 || iSaveLevel >= pdc->dclevel.lSaveDepth)
-    {
-        DPRINT("Illegal save level, requested: %ld, current: %ld\n",
-               iSaveLevel, pdc->dclevel.lSaveDepth);
-        DC_UnlockDc(pdc);
-        SetLastWin32Error(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
+    ASSERT(iSaveLevel > 0);
+    DPRINT("DC_vRestoreDC(%p, %ld)\n", pdc->BaseObject.hHmgr, iSaveLevel);
 
     /* Loop the save levels */
     while (pdc->dclevel.lSaveDepth > iSaveLevel)
     {
         hdcSave = pdc->dclevel.hdcSave;
+        DPRINT("RestoreDC = %p\n", hdcSave);
 
         /* Set us as the owner */
-        if (!IntGdiSetDCOwnerEx(hdcSave, GDI_OBJ_HMGR_POWNED, FALSE ))
+        if (!GreSetObjectOwner(hdcSave, GDI_OBJ_HMGR_POWNED))
         {
             /* Could not get ownership. That's bad! */
-            DPRINT1("Could not get ownership of saved DC (%p) for dc %p!\n",
-                    hdcSave, hdc);
-            return FALSE;
+            DPRINT1("Could not get ownership of saved DC (%p) for hdc %p!\n",
+                    hdcSave, pdc->BaseObject.hHmgr);
+            return;// FALSE;
         }
 
         /* Lock the saved dc */
@@ -157,9 +128,8 @@ NtGdiRestoreDC(
         {
             /* WTF? Internal error! */
             DPRINT1("Could not lock the saved DC (%p) for dc %p!\n",
-                    hdcSave, hdc);
-            DC_UnlockDc(pdc);
-            return FALSE;
+                    hdcSave, pdc->BaseObject.hHmgr);
+            return;// FALSE;
         }
 
         /* Remove the saved dc from the queue */
@@ -174,6 +144,10 @@ NtGdiRestoreDC(
             /* Copy the state back */
             DC_vCopyState(pdcSave, pdc, FALSE);
 
+            /* Only memory DC's change their surface */
+            if (pdc->dctype == DCTYPE_MEMORY)
+                DC_vSelectSurface(pdc, pdcSave->dclevel.pSurface);
+
             // Restore Path by removing it, if the Save flag is set.
             // BeginPath will takecare of the rest.
             if (pdc->dclevel.hPath && pdc->dclevel.flPath & DCPATH_SAVE)
@@ -182,22 +156,62 @@ NtGdiRestoreDC(
                 pdc->dclevel.hPath = 0;
                 pdc->dclevel.flPath &= ~DCPATH_SAVE;
             }
-            // Attempt to plug the leak!
-            if (pdcSave->rosdc.hClipRgn)
-            {
-               DPRINT("Have hClipRgn!\n");
-               REGION_FreeRgnByHandle(pdcSave->rosdc.hClipRgn);
-            }
-            // FIXME! Handle prgnMeta!
         }
 
+        /* Prevent save dc from being restored */
+        pdcSave->dclevel.lSaveDepth = 1;
+
+        /* Unlock it */
+        DC_UnlockDc(pdcSave);
         /* Delete the saved dc */
         GreDeleteObject(hdcSave);
     }
 
+    DPRINT("Leave DC_vRestoreDC()\n");
+}
+
+
+
+BOOL
+APIENTRY
+NtGdiRestoreDC(
+    HDC hdc,
+    INT iSaveLevel)
+{
+    PDC pdc;
+
+    DPRINT("NtGdiRestoreDC(%p, %d)\n", hdc, iSaveLevel);
+
+    /* Lock the original DC */
+    pdc = DC_LockDc(hdc);
+    if (!pdc)
+    {
+        EngSetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    ASSERT(pdc->dclevel.lSaveDepth > 0);
+
+    /* Negative values are relative to the stack top */
+    if (iSaveLevel < 0)
+        iSaveLevel = pdc->dclevel.lSaveDepth + iSaveLevel;
+
+    /* Check if we have a valid instance */
+    if (iSaveLevel <= 0 || iSaveLevel >= pdc->dclevel.lSaveDepth)
+    {
+        DPRINT("Illegal save level, requested: %ld, current: %ld\n",
+               iSaveLevel, pdc->dclevel.lSaveDepth);
+        DC_UnlockDc(pdc);
+        EngSetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    /* Call the internal function */
+    DC_vRestoreDC(pdc, iSaveLevel);
+
     DC_UnlockDc(pdc);
 
-    DPRINT("Leaving NtGdiRestoreDC\n");
+    DPRINT("Leave NtGdiRestoreDC\n");
     return TRUE;
 }
 
@@ -211,19 +225,19 @@ NtGdiSaveDC(
     PDC pdc, pdcSave;
     INT lSaveDepth;
 
-    DPRINT("NtGdiSaveDC(%lx)\n", hDC);
+    DPRINT("NtGdiSaveDC(%p)\n", hDC);
 
     /* Lock the original dc */
     pdc = DC_LockDc(hDC);
     if (pdc == NULL)
     {
         DPRINT("Could not lock DC\n");
-        SetLastWin32Error(ERROR_INVALID_HANDLE);
+        EngSetLastError(ERROR_INVALID_HANDLE);
         return 0;
     }
 
     /* Allocate a new dc */
-    pdcSave = DC_AllocDC(NULL);
+    pdcSave = DC_AllocDcWithHandle();
     if (pdcSave == NULL)
     {
         DPRINT("Could not allocate a new DC\n");
@@ -232,12 +246,25 @@ NtGdiSaveDC(
     }
     hdcSave = pdcSave->BaseObject.hHmgr;
 
-    /* Copy the current state */
-    DC_vCopyState(pdc, pdcSave, TRUE);
+    InterlockedIncrement(&pdc->ppdev->cPdevRefs);
+    DC_vInitDc(pdcSave, DCTYPE_MEMORY, pdc->ppdev);
+
+    /* Handle references here correctly */
+//    pdcSrc->dclevel.pSurface = NULL;
+//    pdcSrc->dclevel.pbrFill = NULL;
+//    pdcSrc->dclevel.pbrLine = NULL;
+//    pdcSrc->dclevel.ppal = NULL;
 
     /* Make it a kernel handle
        (FIXME: windows handles this different, see wiki)*/
-    IntGdiSetDCOwnerEx(hdcSave, GDI_OBJ_HMGR_NONE, FALSE);
+    GreSetObjectOwner(hdcSave, GDI_OBJ_HMGR_PUBLIC);
+
+    /* Copy the current state */
+    DC_vCopyState(pdc, pdcSave, TRUE);
+
+    /* Only memory DC's change their surface */
+    if (pdc->dctype == DCTYPE_MEMORY)
+        DC_vSelectSurface(pdcSave, pdc->dclevel.pSurface);
 
     /* Copy path. FIXME: why this way? */
     pdcSave->dclevel.hPath = pdc->dclevel.hPath;
@@ -254,7 +281,7 @@ NtGdiSaveDC(
     DC_UnlockDc(pdcSave);
     DC_UnlockDc(pdc);
 
-    DPRINT("Leave NtGdiSaveDC: %ld\n", lSaveDepth);
+    DPRINT("Leave NtGdiSaveDC: %ld, hdcSave = %p\n", lSaveDepth, hdcSave);
     return lSaveDepth;
 }