[NtGDI] Fix ExtSelectClipRgn Tests
[reactos.git] / win32ss / gdi / ntgdi / dclife.c
index 3a8a359..3f25639 100644 (file)
@@ -2,7 +2,7 @@
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel
  * PURPOSE:           Functions for creation and destruction of DCs
- * FILE:              subsystem/win32/win32k/objects/dclife.c
+ * FILE:              win32ss/gdi/ntgdi/dclife.c
  * PROGRAMER:         Timo Kreuzer (timo.kreuzer@rectos.org)
  */
 
@@ -17,7 +17,7 @@
 PSURFACE psurfDefaultBitmap = NULL;
 PBRUSH pbrDefaultBrush = NULL;
 
-static const MATRIX    gmxWorldToDeviceDefault =
+const MATRIX gmxWorldToDeviceDefault =
 {
     FLOATOBJ_16, FLOATOBJ_0,
     FLOATOBJ_0, FLOATOBJ_16,
@@ -25,7 +25,7 @@ static const MATRIX   gmxWorldToDeviceDefault =
     0, 0, 0x4b
 };
 
-static const MATRIX    gmxDeviceToWorldDefault =
+const MATRIX gmxDeviceToWorldDefault =
 {
     FLOATOBJ_1_16, FLOATOBJ_0,
     FLOATOBJ_0, FLOATOBJ_1_16,
@@ -33,7 +33,7 @@ static const MATRIX   gmxDeviceToWorldDefault =
     0, 0, 0x53
 };
 
-static const MATRIX    gmxWorldToPageDefault =
+const MATRIX gmxWorldToPageDefault =
 {
     FLOATOBJ_1, FLOATOBJ_0,
     FLOATOBJ_0, FLOATOBJ_1,
@@ -50,7 +50,7 @@ static const MATRIX   gmxWorldToPageDefault =
 INIT_FUNCTION
 NTSTATUS
 NTAPI
-InitDcImpl()
+InitDcImpl(VOID)
 {
     psurfDefaultBitmap = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]);
     if (!psurfDefaultBitmap)
@@ -66,10 +66,14 @@ InitDcImpl()
 
 PDC
 NTAPI
-DC_AllocDcWithHandle()
+DC_AllocDcWithHandle(GDILOOBJTYPE eDcObjType)
 {
     PDC pdc;
 
+    NT_ASSERT((eDcObjType == GDILoObjType_LO_DC_TYPE) ||
+              (eDcObjType == GDILoObjType_LO_ALTDC_TYPE));
+
+    /* Allocate the object */
     pdc = (PDC)GDIOBJ_AllocateObject(GDIObjType_DC_TYPE,
                                      sizeof(DC),
                                      BASEFLAG_LOOKASIDE);
@@ -79,6 +83,12 @@ DC_AllocDcWithHandle()
         return NULL;
     }
 
+    /* Set the actual DC type */
+    pdc->BaseObject.hHmgr = UlongToHandle(eDcObjType);
+
+    pdc->pdcattr = &pdc->dcattr;
+
+    /* Insert the object */
     if (!GDIOBJ_hInsertObject(&pdc->BaseObject, GDI_OBJ_HMGR_POWNED))
     {
         DPRINT1("Could not insert DC into handle table.\n");
@@ -86,8 +96,6 @@ DC_AllocDcWithHandle()
         return NULL;
     }
 
-    pdc->pdcattr = &pdc->dcattr;
-
     return pdc;
 }
 
@@ -95,22 +103,25 @@ DC_AllocDcWithHandle()
 void
 DC_InitHack(PDC pdc)
 {
-    HRGN hVisRgn;
+    if (defaultDCstate == NULL)
+    {
+        defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
+        ASSERT(defaultDCstate);
+        RtlZeroMemory(defaultDCstate, sizeof(DC));
+        defaultDCstate->pdcattr = &defaultDCstate->dcattr;
+        DC_vCopyState(pdc, defaultDCstate, TRUE);
+    }
+
+    if (prgnDefault == NULL)
+    {
+        prgnDefault = IntSysCreateRectpRgn(0, 0, 0, 0);
+    }
 
     TextIntRealizeFont(pdc->pdcattr->hlfntNew,NULL);
     pdc->pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
 
     /* This should never fail */
     ASSERT(pdc->dclevel.ppal);
-
-    /* Select regions */
-    pdc->rosdc.hClipRgn = NULL;
-    pdc->rosdc.hGCClipRgn = NULL;
-
-    hVisRgn = IntSysCreateRectRgn(0, 0, 1, 1);
-    ASSERT(hVisRgn);
-    GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn);
-    GreDeleteObject(hVisRgn);
 }
 
 VOID
@@ -170,9 +181,7 @@ DC_vInitDc(
         pdc->erclBoundsApp.right = 0x00007ffc; // FIXME
         pdc->erclBoundsApp.bottom = 0x00000333; // FIXME
         pdc->erclClip = pdc->erclBounds;
-//        pdc->co
-
-        pdc->fs |= DC_SYNCHRONIZEACCESS | DC_ACCUM_APP | DC_PERMANANT | DC_DISPLAY;
+        pdc->co = gxcoTrivial;
     }
     else
     {
@@ -185,7 +194,7 @@ DC_vInitDc(
         pdc->erclBounds.bottom = 0;
         pdc->erclBoundsApp = pdc->erclBounds;
         pdc->erclClip = pdc->erclWindow;
-        //pdc->co = NULL
+        pdc->co = gxcoTrivial;
     }
 
       //pdc->dcattr.VisRectRegion:
@@ -237,10 +246,18 @@ DC_vInitDc(
     /* Setup regions */
     pdc->prgnAPI = NULL;
        pdc->prgnRao = NULL;
+       pdc->dclevel.prgnClip = NULL;
+       pdc->dclevel.prgnMeta = NULL;
     /* Allocate a Vis region */
     pdc->prgnVis = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
        ASSERT(pdc->prgnVis);
 
+    /* Setup Vis Region Attribute information */
+    UpdateVisRgn(pdc);
+
+       /* Initialize Clip object */
+       IntEngInitClipObj(&pdc->co);
+
     /* Setup palette */
     pdc->dclevel.hpal = StockObjects[DEFAULT_PALETTE];
     pdc->dclevel.ppal = PALETTE_ShareLockPalette(pdc->dclevel.hpal);
@@ -324,7 +341,7 @@ DC_vInitDc(
     /* Other stuff */
     pdc->hdcNext = NULL;
     pdc->hdcPrev = NULL;
-    pdc->ipfdDevMax = 0x0000ffff;
+    pdc->ipfdDevMax = 0;
     pdc->ulCopyCount = -1;
     pdc->ptlDoBanding.x = 0;
     pdc->ptlDoBanding.y = 0;
@@ -333,15 +350,6 @@ DC_vInitDc(
        pdc->dcattr.iGraphicsMode = GM_COMPATIBLE;
        pdc->dcattr.iCS_CP = 0;
     pdc->pSurfInfo = NULL;
-
-    if (defaultDCstate == NULL)
-    {
-        defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
-        ASSERT(defaultDCstate);
-        RtlZeroMemory(defaultDCstate, sizeof(DC));
-        defaultDCstate->pdcattr = &defaultDCstate->dcattr;
-        DC_vCopyState(pdc, defaultDCstate, TRUE);
-    }
 }
 
 VOID
@@ -369,44 +377,44 @@ DC_vCleanup(PVOID ObjectBody)
     EBRUSHOBJ_vCleanup(&pdc->eboBackground);
 
     /* Release font */
-    LFONT_ShareUnlockFont(pdc->dclevel.plfnt);
+    if (pdc->dclevel.plfnt)
+        LFONT_ShareUnlockFont(pdc->dclevel.plfnt);
 
     /*  Free regions */
-    if (pdc->rosdc.hClipRgn && GreIsHandleValid(pdc->rosdc.hClipRgn))
-        GreDeleteObject(pdc->rosdc.hClipRgn);
+    if (pdc->dclevel.prgnClip)
+        REGION_Delete(pdc->dclevel.prgnClip);
+    if (pdc->dclevel.prgnMeta)
+        REGION_Delete(pdc->dclevel.prgnMeta);
     if (pdc->prgnVis)
-    {
         REGION_Delete(pdc->prgnVis);
-    }
-    if (pdc->rosdc.hGCClipRgn && GreIsHandleValid(pdc->rosdc.hGCClipRgn))
-    {
-        GreDeleteObject(pdc->rosdc.hGCClipRgn);
-    }
-    if (NULL != pdc->rosdc.CombinedClip)
-        IntEngDeleteClipRegion(pdc->rosdc.CombinedClip);
+    if (pdc->prgnRao)
+        REGION_Delete(pdc->prgnRao);
+    if (pdc->prgnAPI)
+        REGION_Delete(pdc->prgnAPI);
 
-    PATH_Delete(pdc->dclevel.hPath);
+    /* Free CLIPOBJ resources */
+    IntEngFreeClipResources(&pdc->co);
 
-    if(pdc->dclevel.pSurface)
+    if (pdc->dclevel.hPath)
+    {
+       DPRINT("DC_vCleanup Path\n");
+       PATH_Delete(pdc->dclevel.hPath);
+       pdc->dclevel.hPath = 0;
+       pdc->dclevel.flPath = 0;
+    }
+    if (pdc->dclevel.pSurface)
         SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface);
 
-    PDEVOBJ_vRelease(pdc->ppdev) ;
+    if (pdc->ppdev)
+        PDEVOBJ_vRelease(pdc->ppdev);
 }
 
 VOID
 NTAPI
 DC_vSetOwner(PDC pdc, ULONG ulOwner)
 {
-
-    if (pdc->rosdc.hClipRgn)
-    {
-        IntGdiSetRegionOwner(pdc->rosdc.hClipRgn, ulOwner);
-    }
-
-    if (pdc->rosdc.hGCClipRgn)
-    {
-        IntGdiSetRegionOwner(pdc->rosdc.hGCClipRgn, ulOwner);
-    }
+    /* Delete saved DCs */
+    DC_vRestoreDC(pdc, 1);
 
     if (pdc->dclevel.hPath)
     {
@@ -466,8 +474,8 @@ static
 void
 DC_vUpdateDC(PDC pdc)
 {
-    HRGN hVisRgn ;
-    PPDEVOBJ ppdev = pdc->ppdev ;
+    // PREGION VisRgn ;
+    PPDEVOBJ ppdev = pdc->ppdev;
 
     pdc->dhpdev = ppdev->dhpdev;
 
@@ -475,10 +483,12 @@ DC_vUpdateDC(PDC pdc)
     pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev);
 
     PDEVOBJ_sizl(pdc->ppdev, &pdc->dclevel.sizl);
-    hVisRgn = NtGdiCreateRectRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
-    ASSERT(hVisRgn);
-    GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn);
-    GreDeleteObject(hVisRgn);
+#if 0
+    VisRgn = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
+    ASSERT(VisRgn);
+    GdiSelectVisRgn(pdc->BaseObject.hHmgr, VisRgn);
+    REGION_Delete(VisRgn);
+#endif
 
     pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps;
     pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2;
@@ -492,76 +502,110 @@ DC_vUpdateDC(PDC pdc)
  * from where we take pixels. */
 VOID
 FASTCALL
-DC_vPrepareDCsForBlit(PDC pdc1,
-                      RECT rc1,
-                      PDC pdc2,
-                      RECT rc2)
+DC_vPrepareDCsForBlit(
+    PDC pdcDest,
+    const RECT* rcDest,
+    PDC pdcSrc,
+    const RECT* rcSrc)
 {
     PDC pdcFirst, pdcSecond;
-    PRECT prcFirst, prcSecond;
+    const RECT *prcFirst, *prcSecond;
 
     /* Update brushes */
-    if (pdc1->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
-        DC_vUpdateFillBrush(pdc1);
-    if (pdc1->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
-        DC_vUpdateLineBrush(pdc1);
-    if(pdc1->pdcattr->ulDirty_ & DIRTY_TEXT)
-        DC_vUpdateTextBrush(pdc1);
+    if (pdcDest->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+        DC_vUpdateFillBrush(pdcDest);
+    if (pdcDest->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+        DC_vUpdateLineBrush(pdcDest);
+    if(pdcDest->pdcattr->ulDirty_ & DIRTY_TEXT)
+        DC_vUpdateTextBrush(pdcDest);
 
     /* Lock them in good order */
-    if(pdc2)
+    if (pdcSrc)
     {
-        if((ULONG_PTR)pdc1->ppdev->hsemDevLock >= (ULONG_PTR)pdc2->ppdev->hsemDevLock)
+        if((ULONG_PTR)pdcDest->ppdev->hsemDevLock >=
+           (ULONG_PTR)pdcSrc->ppdev->hsemDevLock)
         {
-            pdcFirst = pdc1;
-            prcFirst = &rc1;
-            pdcSecond = pdc2;
-            prcSecond = &rc2;
+            pdcFirst = pdcDest;
+            prcFirst = rcDest;
+            pdcSecond = pdcSrc;
+            prcSecond = rcSrc;
         }
         else
         {
-            pdcFirst = pdc2;
-            prcFirst = &rc2;
-            pdcSecond = pdc1;
-            prcSecond = &rc1;
+            pdcFirst = pdcSrc;
+            prcFirst = rcSrc;
+            pdcSecond = pdcDest;
+            prcSecond = rcDest;
         }
     }
     else
     {
-        pdcFirst = pdc;
-        prcFirst = &rc1;
+        pdcFirst = pdcDest;
+        prcFirst = rcDest;
         pdcSecond = NULL;
         prcSecond = NULL;
     }
 
-    if(pdcFirst && pdcFirst->dctype == DCTYPE_DIRECT)
+    if (pdcDest->fs & DC_FLAG_DIRTY_RAO)
+        CLIPPING_UpdateGCRegion(pdcDest);
+
+    /* Lock and update first DC */
+    if (pdcFirst->dctype == DCTYPE_DIRECT)
     {
         EngAcquireSemaphore(pdcFirst->ppdev->hsemDevLock);
-        MouseSafetyOnDrawStart(pdcFirst->ppdev,
-                                    prcFirst->left,
-                                    prcFirst->top,
-                                    prcFirst->right,
-                                    prcFirst->bottom) ;
+
         /* Update surface if needed */
-        if(pdcFirst->ppdev->pSurface != pdcFirst->dclevel.pSurface)
+        if (pdcFirst->ppdev->pSurface != pdcFirst->dclevel.pSurface)
         {
             DC_vUpdateDC(pdcFirst);
         }
     }
-    if(pdcSecond && pdcSecond->dctype == DCTYPE_DIRECT)
+
+    if (pdcFirst->dctype == DCTYPE_DIRECT)
+    {
+        if (!prcFirst)
+            prcFirst = &pdcFirst->erclClip;
+
+        MouseSafetyOnDrawStart(pdcFirst->ppdev,
+                               prcFirst->left,
+                               prcFirst->top,
+                               prcFirst->right,
+                               prcFirst->bottom) ;
+    }
+
+#if DBG
+    pdcFirst->fs |= DC_PREPARED;
+#endif
+
+    if (!pdcSecond)
+        return;
+
+    /* Lock and update second DC */
+    if (pdcSecond->dctype == DCTYPE_DIRECT)
     {
         EngAcquireSemaphore(pdcSecond->ppdev->hsemDevLock);
-        MouseSafetyOnDrawStart(pdcSecond->ppdev,
-                                    prcSecond->left,
-                                    prcSecond->top,
-                                    prcSecond->right,
-                                    prcSecond->bottom) ;
+
         /* Update surface if needed */
-        if(pdcSecond->ppdev->pSurface != pdcSecond->dclevel.pSurface)
+        if (pdcSecond->ppdev->pSurface != pdcSecond->dclevel.pSurface)
         {
             DC_vUpdateDC(pdcSecond);
         }
     }
+
+    if (pdcSecond->dctype == DCTYPE_DIRECT)
+    {
+        if (!prcSecond)
+            prcSecond = &pdcSecond->erclClip;
+        MouseSafetyOnDrawStart(pdcSecond->ppdev,
+                               prcSecond->left,
+                               prcSecond->top,
+                               prcSecond->right,
+                               prcSecond->bottom) ;
+    }
+
+#if DBG
+    pdcSecond->fs |= DC_PREPARED;
+#endif
 }
 
 /* Finishes a blit for one or two DCs */
@@ -569,19 +613,25 @@ VOID
 FASTCALL
 DC_vFinishBlit(PDC pdc1, PDC pdc2)
 {
-    if(pdc1->dctype == DCTYPE_DIRECT)
+    if (pdc1->dctype == DCTYPE_DIRECT)
     {
         MouseSafetyOnDrawEnd(pdc1->ppdev);
         EngReleaseSemaphore(pdc1->ppdev->hsemDevLock);
     }
+#if DBG
+    pdc1->fs &= ~DC_PREPARED;
+#endif
 
-    if(pdc2)
+    if (pdc2)
     {
-        if(pdc2->dctype == DCTYPE_DIRECT)
+        if (pdc2->dctype == DCTYPE_DIRECT)
         {
             MouseSafetyOnDrawEnd(pdc2->ppdev);
             EngReleaseSemaphore(pdc2->ppdev->hsemDevLock);
         }
+#if DBG
+        pdc2->fs &= ~DC_PREPARED;
+#endif
     }
 }
 
@@ -595,7 +645,7 @@ GreOpenDCW(
     BOOL bDisplay,
     HANDLE hspool,
     VOID *pDriverInfo2,
-    VOID *pUMdhpdev)
+    PVOID *pUMdhpdev)
 {
     PPDEVOBJ ppdev;
     PDC pdc;
@@ -614,7 +664,7 @@ GreOpenDCW(
 
     DPRINT("GreOpenDCW - ppdev = %p\n", ppdev);
 
-    pdc = DC_AllocDcWithHandle();
+    pdc = DC_AllocDcWithHandle(GDILoObjType_LO_DC_TYPE);
     if (!pdc)
     {
         DPRINT1("Could not Allocate a DC\n");
@@ -625,6 +675,7 @@ GreOpenDCW(
 
     /* Lock ppdev and initialize the new DC */
     DC_vInitDc(pdc, iType, ppdev);
+    if (pUMdhpdev) *pUMdhpdev = ppdev->dhpdev;
     /* FIXME: HACK! */
     DC_InitHack(pdc);
 
@@ -637,23 +688,26 @@ GreOpenDCW(
     return hdc;
 }
 
+__kernel_entry
 HDC
 APIENTRY
 NtGdiOpenDCW(
-    PUNICODE_STRING pustrDevice,
-    DEVMODEW *pdmInit,
-    PUNICODE_STRING pustrLogAddr,
-    ULONG iType,
-    BOOL bDisplay,
-    HANDLE hspool,
-    VOID *pDriverInfo2,
-    VOID *pUMdhpdev)
+    _In_opt_ PUNICODE_STRING pustrDevice,
+    _In_ DEVMODEW *pdmInit,
+    _In_ PUNICODE_STRING pustrLogAddr,
+    _In_ ULONG iType,
+    _In_ BOOL bDisplay,
+    _In_opt_ HANDLE hspool,
+    /*_In_opt_ DRIVER_INFO2W *pdDriverInfo2, Need this soon!!!! */
+    _At_((PUMDHPDEV*)pUMdhpdev, _Out_) PVOID pUMdhpdev)
 {
     UNICODE_STRING ustrDevice;
     WCHAR awcDevice[CCHDEVICENAME];
-    DEVMODEW dmInit;
     PVOID dhpdev;
     HDC hdc;
+    WORD dmSize, dmDriverExtra;
+    DWORD Size;
+    DEVMODEW * _SEH2_VOLATILE pdmAllocated = NULL;
 
     /* Only if a devicename is given, we need any data */
     if (pustrDevice)
@@ -670,11 +724,22 @@ NtGdiOpenDCW(
             /* Copy the string */
             RtlCopyUnicodeString(&ustrDevice, pustrDevice);
 
+            /* Allocate and store pdmAllocated if pdmInit is not NULL */
             if (pdmInit)
             {
-                /* FIXME: could be larger */
                 ProbeForRead(pdmInit, sizeof(DEVMODEW), 1);
-                RtlCopyMemory(&dmInit, pdmInit, sizeof(DEVMODEW));
+
+                dmSize = pdmInit->dmSize;
+                dmDriverExtra = pdmInit->dmDriverExtra;
+                Size = dmSize + dmDriverExtra;
+                ProbeForRead(pdmInit, Size, 1);
+
+                pdmAllocated = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,
+                                                     Size,
+                                                     TAG_DC);
+                RtlCopyMemory(pdmAllocated, pdmInit, Size);
+                pdmAllocated->dmSize = dmSize;
+                pdmAllocated->dmDriverExtra = dmDriverExtra;
             }
 
             if (pUMdhpdev)
@@ -684,6 +749,10 @@ NtGdiOpenDCW(
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
+            if (pdmAllocated)
+            {
+                ExFreePoolWithTag(pdmAllocated, TAG_DC);
+            }
             SetLastNtError(_SEH2_GetExceptionCode());
             _SEH2_YIELD(return NULL);
         }
@@ -693,6 +762,7 @@ NtGdiOpenDCW(
     {
         pdmInit = NULL;
         pUMdhpdev = NULL;
+        // return UserGetDesktopDC(iType, FALSE, TRUE);
     }
 
     /* FIXME: HACK! */
@@ -707,7 +777,7 @@ NtGdiOpenDCW(
 
     /* Call the internal function */
     hdc = GreOpenDCW(pustrDevice ? &ustrDevice : NULL,
-                     pdmInit ? &dmInit : NULL,
+                     pdmAllocated,
                      NULL, // FIXME: pwszLogAddress
                      iType,
                      bDisplay,
@@ -718,7 +788,7 @@ NtGdiOpenDCW(
     /* If we got a HDC and a UM dhpdev is requested,... */
     if (hdc && pUMdhpdev)
     {
-        /* Copy dhpdev to caller (FIXME: use dhpdev?) */
+        /* Copy dhpdev to caller */
         _SEH2_TRY
         {
             /* Pointer was already probed */
@@ -732,14 +802,21 @@ NtGdiOpenDCW(
         _SEH2_END
     }
 
+    /* Free the allocated */
+    if (pdmAllocated)
+    {
+        ExFreePoolWithTag(pdmAllocated, TAG_DC);
+    }
+
     return hdc;
 }
 
 
 HDC
 APIENTRY
-NtGdiCreateCompatibleDC(HDC hdc)
+GreCreateCompatibleDC(HDC hdc, BOOL bAltDc)
 {
+    GDILOOBJTYPE eDcObjType;
     HDC hdcNew;
     PPDEVOBJ ppdev;
     PDC pdc, pdcNew;
@@ -777,7 +854,8 @@ NtGdiCreateCompatibleDC(HDC hdc)
     }
 
     /* Allocate a new DC */
-    pdcNew = DC_AllocDcWithHandle();
+    eDcObjType = bAltDc ? GDILoObjType_LO_ALTDC_TYPE : GDILoObjType_LO_DC_TYPE;
+    pdcNew = DC_AllocDcWithHandle(eDcObjType);
     if (!pdcNew)
     {
         DPRINT1("Could not allocate a new DC\n");
@@ -787,7 +865,7 @@ NtGdiCreateCompatibleDC(HDC hdc)
     hdcNew = pdcNew->BaseObject.hHmgr;
 
     /* Lock ppdev and initialize the new DC */
-    DC_vInitDc(pdcNew, DCTYPE_MEMORY, ppdev);
+    DC_vInitDc(pdcNew, bAltDc ? DCTYPE_INFO : DCTYPE_MEMORY, ppdev);
     /* FIXME: HACK! */
     DC_InitHack(pdcNew);
 
@@ -801,6 +879,14 @@ NtGdiCreateCompatibleDC(HDC hdc)
     return hdcNew;
 }
 
+HDC
+APIENTRY
+NtGdiCreateCompatibleDC(HDC hdc)
+{
+    /* Call the internal function to create a normal memory DC */
+    return GreCreateCompatibleDC(hdc, FALSE);
+}
+
 BOOL
 FASTCALL
 IntGdiDeleteDC(HDC hDC, BOOL Force)
@@ -847,11 +933,13 @@ IntGdiDeleteDC(HDC hDC, BOOL Force)
         if (!GreDeleteObject(hDC))
         {
             DPRINT1("DC_FreeDC failed\n");
+            return FALSE;
         }
     }
     else
     {
         DPRINT1("Attempted to Delete 0x%p currently being destroyed!!!\n", hDC);
+        return FALSE;
     }
 
     return TRUE;