[NtGDI]
[reactos.git] / reactos / win32ss / gdi / ntgdi / dcutil.c
index 2fb9cb3..8ec7a8c 100644 (file)
@@ -3,40 +3,92 @@
 #define NDEBUG
 #include <debug.h>
 
+BOOL FASTCALL
+GreDPtoLP(HDC hdc, LPPOINT lpPoints, INT nCount)
+{
+   PDC dc;
+   if (!(dc = DC_LockDc(hdc)))
+   {
+      EngSetLastError(ERROR_INVALID_HANDLE);
+      return FALSE;
+   }
+   IntDPtoLP(dc, lpPoints, nCount);
+   DC_UnlockDc(dc);
+   return TRUE;
+}
+
+BOOL FASTCALL
+GreLPtoDP(HDC hdc, LPPOINT lpPoints, INT nCount)
+{
+   PDC dc;
+   if (!(dc = DC_LockDc(hdc)))
+   {
+      EngSetLastError(ERROR_INVALID_HANDLE);
+      return FALSE;
+   }
+   IntLPtoDP(dc, lpPoints, nCount);
+   DC_UnlockDc(dc);
+   return TRUE;
+}
+
 int FASTCALL
 GreGetBkMode(HDC hdc)
 {
    PDC dc;
+   LONG lBkMode;
+   if (!(dc = DC_LockDc(hdc)))
+   {
+      EngSetLastError(ERROR_INVALID_HANDLE);
+      return CLR_INVALID;
+   }
+   lBkMode = dc->pdcattr->lBkMode;
+   DC_UnlockDc(dc);
+   return lBkMode;
+}
+
+COLORREF FASTCALL
+GreGetBkColor(HDC hdc)
+{
+   PDC dc;
+   COLORREF crBk;
    if (!(dc = DC_LockDc(hdc)))
    {
       EngSetLastError(ERROR_INVALID_HANDLE);
       return CLR_INVALID;
    }
-   return dc->pdcattr->lBkMode;
+   crBk = dc->pdcattr->ulBackgroundClr;
+   DC_UnlockDc(dc);
+   return crBk;
 }
 
 int FASTCALL
 GreGetMapMode(HDC hdc)
 {
    PDC dc;
+   INT iMapMode;
    if (!(dc = DC_LockDc(hdc)))
    {
       EngSetLastError(ERROR_INVALID_HANDLE);
       return CLR_INVALID;
    }
-   return dc->pdcattr->iMapMode;
+   iMapMode = dc->pdcattr->iMapMode;
+   DC_UnlockDc(dc);
+   return iMapMode;
 }
 
 COLORREF FASTCALL
 GreGetTextColor(HDC hdc)
 {
    PDC dc;
+   ULONG ulForegroundClr;
    if (!(dc = DC_LockDc(hdc)))
    {
       EngSetLastError(ERROR_INVALID_HANDLE);
       return CLR_INVALID;
    }
-   return dc->pdcattr->ulForegroundClr;
+   ulForegroundClr = dc->pdcattr->ulForegroundClr;
+   DC_UnlockDc(dc);
+   return ulForegroundClr;
 }
 
 COLORREF FASTCALL
@@ -53,10 +105,15 @@ IntGdiSetBkColor(HDC hDC, COLORREF color)
         return CLR_INVALID;
     }
     pdcattr = dc->pdcattr;
-    oldColor = pdcattr->crBackgroundClr;
-    pdcattr->crBackgroundClr = color;
-    pdcattr->ulBackgroundClr = (ULONG)color;
-    pdcattr->ulDirty_ |= DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL; // Clear Flag if set.
+
+    oldColor = pdcattr->ulBackgroundClr;
+    pdcattr->ulBackgroundClr = color;
+
+    if (pdcattr->crBackgroundClr != color)
+    {
+        pdcattr->ulDirty_ |= (DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL); // Clear Flag if set.
+        pdcattr->crBackgroundClr = color;
+    }
     hBrush = pdcattr->hbrush;
     DC_UnlockDc(dc);
     NtGdiSelectBrush(hDC, hBrush);
@@ -122,10 +179,18 @@ IntGdiSetTextColor(HDC hDC,
     }
     pdcattr = pdc->pdcattr;
 
-    // What about ulForegroundClr, like in gdi32?
-    crOldColor = pdcattr->crForegroundClr;
-    pdcattr->crForegroundClr = color;
+    crOldColor = (COLORREF) pdcattr->ulForegroundClr;
+    pdcattr->ulForegroundClr = (ULONG)color;
+
+    if (pdcattr->crForegroundClr != color)
+    {
+        pdcattr->ulDirty_ |= (DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL);
+        pdcattr->crForegroundClr = color;
+    }
+
     DC_vUpdateTextBrush(pdc);
+    DC_vUpdateLineBrush(pdc);
+    DC_vUpdateFillBrush(pdc);
 
     DC_UnlockDc(pdc);
 
@@ -153,6 +218,7 @@ IntSetDCBrushColor(HDC hdc, COLORREF crColor)
          dc->pdcattr->crBrushClr = crColor;
       }
    }
+   DC_UnlockDc(dc);
    return OldColor;
 }
 
@@ -175,7 +241,7 @@ IntSetDCPenColor(HDC hdc, COLORREF crColor)
       dc->pdcattr->ulDirty_ |= DIRTY_LINE;
       dc->pdcattr->crPenClr = crColor;
    }
-
+   DC_UnlockDc(dc);
    return OldColor;
 }
 
@@ -198,10 +264,26 @@ GreSetStretchBltMode(HDC hDC, int iStretchMode)
        if ((iStretchMode <= 0) || (iStretchMode > MAXSTRETCHBLTMODE)) iStretchMode = WHITEONBLACK;
 
        pdcattr->jStretchBltMode = iStretchMode;
+       DC_UnlockDc(pdc);
     }
     return oSMode;
 }
 
+int FASTCALL
+GreGetGraphicsMode(HDC hdc)
+{
+   PDC dc;
+   int GraphicsMode;
+   if (!(dc = DC_LockDc(hdc)))
+   {
+      EngSetLastError(ERROR_INVALID_HANDLE);
+      return CLR_INVALID;
+   }
+   GraphicsMode = dc->pdcattr->iGraphicsMode;
+   DC_UnlockDc(dc);
+   return GraphicsMode;
+}
+
 VOID
 FASTCALL
 DCU_SetDcUndeletable(HDC  hDC)
@@ -235,7 +317,7 @@ FASTCALL
 IntSetDefaultRegion(PDC pdc)
 {
     PSURFACE pSurface;
-    PROSRGNDATA prgn;
+    PREGION prgn;
     RECTL rclWnd, rclClip;
 
     IntGdiReleaseRaoRgn(pdc);
@@ -328,7 +410,7 @@ IntGdiSetHookFlags(HDC hDC, WORD Flags)
     }
     else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags)
     {
-        dc->fs &= ~DC_FLAG_DIRTY_RAO;
+        //dc->fs &= ~DC_FLAG_DIRTY_RAO;
     }
 
     DC_UnlockDc(dc);
@@ -390,6 +472,7 @@ NtGdiGetDCDword(
             break;
 
         case GdiGetEMFRestorDc:
+            SafeResult = pdc->dclevel.lSaveDepth;
             break;
 
         case GdiGetFontLanguageInfo:
@@ -569,6 +652,20 @@ NtGdiGetAndSetDCDword(
     return Ret;
 }
 
+VOID
+FASTCALL
+IntUpdateBoundsRect(PDC pdc, PRECTL pRect)
+{
+   if (pdc->fs & DC_ACCUM_APP)
+   {
+      RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, pRect);
+   }
+   if (pdc->fs & DC_ACCUM_WMGR)
+   {
+      RECTL_bUnionRect(&pdc->erclBounds, &pdc->erclBounds, pRect);
+   }
+}
+
 DWORD
 APIENTRY
 NtGdiGetBoundsRect(
@@ -578,19 +675,49 @@ NtGdiGetBoundsRect(
 {
     DWORD ret;
     PDC pdc;
+    RECT rc;
 
     /* Lock the DC */
     if (!(pdc = DC_LockDc(hdc))) return 0;
 
-    /* Get the return value */
-    ret = pdc->fs & DC_ACCUM_APP ? DCB_ENABLE : DCB_DISABLE;
-    ret |= RECTL_bIsEmptyRect(&pdc->erclBoundsApp) ? DCB_RESET : DCB_SET;
+    if (!(flags & DCB_WINDOWMGR))
+    {
+       rc = pdc->erclBoundsApp;
+
+       if (RECTL_bIsEmptyRect(&rc))
+       {
+          rc.left = rc.top = rc.right = rc.bottom = 0;
+          ret = DCB_RESET;
+       }
+       else
+       {
+          RECTL rcRgn;
+          if (pdc->fs & DC_FLAG_DIRTY_RAO) CLIPPING_UpdateGCRegion(pdc);
+          if(!REGION_GetRgnBox(pdc->prgnRao, &rcRgn))
+          {
+             REGION_GetRgnBox(pdc->prgnVis, &rcRgn);
+          }
+          rc.left   = max( rc.left, 0 );
+          rc.top    = max( rc.top, 0 );
+          rc.right  = min( rc.right,  rcRgn.right - rcRgn.left );
+          rc.bottom = min( rc.bottom, rcRgn.bottom - rcRgn.top );
+          DPRINT("Rao dc %p r %d b %d\n",pdc,rcRgn.right - rcRgn.left, rcRgn.bottom - rcRgn.top);
+          DPRINT("rc  l %d t %d\n",rc.left,rc.top);
+          DPRINT("    r %d b %d\n",rc.right,rc.bottom);
+          ret = DCB_SET;
+       }
+       IntDPtoLP( pdc, &rc, 2 );
+       DPRINT("rc1 l %d t %d\n",rc.left,rc.top);
+       DPRINT("    r %d b %d\n",rc.right,rc.bottom);
+    }
+    else
+       rc = pdc->erclBounds;
 
     /* Copy the rect to the caller */
     _SEH2_TRY
     {
         ProbeForWrite(prc, sizeof(RECT), 1);
-        *prc = pdc->erclBoundsApp;
+        *prc = rc;
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -600,14 +727,22 @@ NtGdiGetBoundsRect(
 
     if (flags & DCB_RESET)
     {
-        RECTL_vSetEmptyRect(&pdc->erclBoundsApp);
+        if (!(flags & DCB_WINDOWMGR))
+        {
+           pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX;
+           pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN;
+        }
+        else
+        {
+           pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX;
+           pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN;
+        }
     }
 
     DC_UnlockDc(pdc);
     return ret;
 }
 
-
 DWORD
 APIENTRY
 NtGdiSetBoundsRect(
@@ -626,15 +761,26 @@ NtGdiSetBoundsRect(
     if (!(pdc = DC_LockDc(hdc))) return 0;
 
     /* Get the return value */
-    ret = pdc->fs & DC_ACCUM_APP ? DCB_ENABLE : DCB_DISABLE;
-    ret |= RECTL_bIsEmptyRect(&pdc->erclBoundsApp) ? DCB_RESET : DCB_SET;
+    ret = DCB_RESET; /* we don't have device-specific bounds */
+    ret = (pdc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR) ? DCB_ENABLE : DCB_DISABLE) |
+          (RECTL_bIsEmptyRect(&pdc->erclBoundsApp) ? ret & DCB_SET : DCB_SET );
+    ret |= (flags & DCB_WINDOWMGR);
 
     if (flags & DCB_RESET)
     {
-        RECTL_vSetEmptyRect(&pdc->erclBoundsApp);
+        if (!(flags & DCB_WINDOWMGR))
+        {
+           pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX;
+           pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN;
+        }
+        else
+        {
+           pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX;
+           pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN;
+        }
     }
 
-    if (flags & DCB_ACCUMULATE)
+    if (flags & DCB_ACCUMULATE && prc != NULL)
     {
         /* Capture the rect */
         _SEH2_TRY
@@ -650,11 +796,30 @@ NtGdiSetBoundsRect(
         _SEH2_END;
 
         RECTL_vMakeWellOrdered(&rcl);
-        RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, &rcl);
+
+        if (!(flags & DCB_WINDOWMGR))
+        {           
+           IntLPtoDP( pdc, (POINT *)&rcl, 2 );
+           RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, &rcl);
+        }
+        else
+           RECTL_bUnionRect(&pdc->erclBounds, &pdc->erclBounds, &rcl);
     }
 
-    if (flags & DCB_ENABLE) pdc->fs |= DC_ACCUM_APP;
-    if (flags & DCB_DISABLE) pdc->fs &= ~DC_ACCUM_APP;
+    if (flags & DCB_ENABLE)
+    {
+       if (!(flags & DCB_WINDOWMGR))
+          pdc->fs |= DC_ACCUM_APP;
+       else
+          pdc->fs |= DC_ACCUM_WMGR;
+    }
+    if (flags & DCB_DISABLE)
+    {
+       if (!(flags & DCB_WINDOWMGR))
+          pdc->fs &= ~DC_ACCUM_APP;
+       else
+          pdc->fs &= ~DC_ACCUM_WMGR;
+    }
     DC_UnlockDc(pdc);
     return ret;
 }