[WIN32K]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Tue, 4 Jan 2011 16:53:23 +0000 (16:53 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Tue, 4 Jan 2011 16:53:23 +0000 (16:53 +0000)
- Simplify error checks, by reordering code in NtGdiScaleViewportExtEx
- Simplify exception handling, use _SEH2_YIELD
- Change function order
- Minor code improvements

svn path=/trunk/; revision=50283

reactos/subsystems/win32/win32k/objects/coord.c

index c89bc05..a615bda 100644 (file)
@@ -1,24 +1,5 @@
 /*
- *  ReactOS W32 Subsystem
- *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/*
- *
- * COPYRIGHT:        See COPYING in the top level directory
+ * COPYRIGHT:        GNU GPL, See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * PURPOSE:          Coordinate systems
  * FILE:             subsys/win32k/objects/coord.c
 /* FUNCTIONS *****************************************************************/
 
 void FASTCALL
-IntFixIsotropicMapping(PDC dc)
+IntFixIsotropicMapping(PDC pdc)
 {
     PDC_ATTR pdcattr;
     LONG fx, fy, s;
 
     /* Get a pointer to the DC_ATTR */
-    pdcattr = dc->pdcattr;
+    pdcattr = pdc->pdcattr;
 
     /* Check if all values are valid */
     if (pdcattr->szlWindowExt.cx == 0 || pdcattr->szlWindowExt.cy == 0 ||
@@ -66,6 +47,76 @@ IntFixIsotropicMapping(PDC dc)
     }
 }
 
+// FIXME: Don't use floating point in the kernel!
+void IntWindowToViewPort(PDC_ATTR pdcattr, LPXFORM xformWnd2Vport)
+{
+    FLOAT scaleX, scaleY;
+
+    scaleX = (pdcattr->szlWindowExt.cx ? (FLOAT)pdcattr->szlViewportExt.cx / (FLOAT)pdcattr->szlWindowExt.cx : 0.0f);
+    scaleY = (pdcattr->szlWindowExt.cy ? (FLOAT)pdcattr->szlViewportExt.cy / (FLOAT)pdcattr->szlWindowExt.cy : 0.0f);
+    xformWnd2Vport->eM11 = scaleX;
+    xformWnd2Vport->eM12 = 0.0;
+    xformWnd2Vport->eM21 = 0.0;
+    xformWnd2Vport->eM22 = scaleY;
+    xformWnd2Vport->eDx  = (FLOAT)pdcattr->ptlViewportOrg.x - scaleX * (FLOAT)pdcattr->ptlWindowOrg.x;
+    xformWnd2Vport->eDy  = (FLOAT)pdcattr->ptlViewportOrg.y - scaleY * (FLOAT)pdcattr->ptlWindowOrg.y;
+}
+
+// FIXME: Use XFORMOBJECT!
+VOID FASTCALL
+DC_UpdateXforms(PDC dc)
+{
+    XFORM  xformWnd2Vport;
+    PDC_ATTR pdcattr = dc->pdcattr;
+    XFORM xformWorld2Vport, xformWorld2Wnd, xformVport2World;
+
+    /* Construct a transformation to do the window-to-viewport conversion */
+    IntWindowToViewPort(pdcattr, &xformWnd2Vport);
+
+    /* Combine with the world transformation */
+    MatrixS2XForm(&xformWorld2Vport, &dc->dclevel.mxWorldToDevice);
+    MatrixS2XForm(&xformWorld2Wnd, &dc->dclevel.mxWorldToPage);
+    IntGdiCombineTransform(&xformWorld2Vport, &xformWorld2Wnd, &xformWnd2Vport);
+
+    /* Create inverse of world-to-viewport transformation */
+    MatrixS2XForm(&xformVport2World, &dc->dclevel.mxDeviceToWorld);
+    if (DC_InvertXform(&xformWorld2Vport, &xformVport2World))
+    {
+        pdcattr->flXform &= ~DEVICE_TO_WORLD_INVALID;
+    }
+    else
+    {
+        pdcattr->flXform |= DEVICE_TO_WORLD_INVALID;
+    }
+
+    /* Update transformation matrices */
+    XForm2MatrixS(&dc->dclevel.mxWorldToDevice, &xformWorld2Vport);
+    XForm2MatrixS(&dc->dclevel.mxDeviceToWorld, &xformVport2World);
+}
+
+VOID
+FASTCALL
+DC_vUpdateViewportExt(PDC pdc)
+{
+    PDC_ATTR pdcattr;
+
+    /* Get a pointer to the dc attribute */
+    pdcattr = pdc->pdcattr;
+
+    /* Check if we need to recalculate */
+    if (pdcattr->flXform & PAGE_EXTENTS_CHANGED)
+    {
+        /* Check if we need to do isotropic fixup */
+        if (pdcattr->iMapMode == MM_ISOTROPIC)
+        {
+            IntFixIsotropicMapping(pdc);
+        }
+
+        /* Update xforms, CHECKME: really done here? */
+        DC_UpdateXforms(pdc);
+    }
+}
+
 // FIXME: don't use floating point in the kernel! use XFORMOBJ function
 BOOL FASTCALL
 IntGdiCombineTransform(
@@ -74,6 +125,7 @@ IntGdiCombineTransform(
     LPXFORM xform2)
 {
     XFORM xformTemp;
+
     /* Check for illegal parameters */
     if (!XFormResult || !xform1 || !xform2)
     {
@@ -94,10 +146,12 @@ IntGdiCombineTransform(
 }
 
 // FIXME: should be XFORML and use XFORMOBJ functions
-BOOL APIENTRY NtGdiCombineTransform(
-    LPXFORM  UnsafeXFormResult,
-    LPXFORM  Unsafexform1,
-    LPXFORM  Unsafexform2)
+BOOL
+APIENTRY
+NtGdiCombineTransform(
+    LPXFORM UnsafeXFormResult,
+    LPXFORM Unsafexform1,
+    LPXFORM Unsafexform2)
 {
     BOOL Ret;
 
@@ -119,67 +173,6 @@ BOOL APIENTRY NtGdiCombineTransform(
     return Ret;
 }
 
-// FIXME: Don't use floating point in the kernel
-BOOL
-FASTCALL
-IntGdiModifyWorldTransform(
-    PDC pDc,
-    CONST LPXFORM lpXForm,
-    DWORD Mode)
-{
-    XFORM xformWorld2Wnd;
-    ASSERT(pDc);
-
-    switch (Mode)
-    {
-        case MWT_IDENTITY:
-            xformWorld2Wnd.eM11 = 1.0f;
-            xformWorld2Wnd.eM12 = 0.0f;
-            xformWorld2Wnd.eM21 = 0.0f;
-            xformWorld2Wnd.eM22 = 1.0f;
-            xformWorld2Wnd.eDx  = 0.0f;
-            xformWorld2Wnd.eDy  = 0.0f;
-            XForm2MatrixS(&pDc->dclevel.mxWorldToPage, &xformWorld2Wnd);
-            break;
-
-        case MWT_LEFTMULTIPLY:
-            MatrixS2XForm(&xformWorld2Wnd, &pDc->dclevel.mxWorldToPage);
-            IntGdiCombineTransform(&xformWorld2Wnd, lpXForm, &xformWorld2Wnd);
-            XForm2MatrixS(&pDc->dclevel.mxWorldToPage, &xformWorld2Wnd);
-            break;
-
-        case MWT_RIGHTMULTIPLY:
-            MatrixS2XForm(&xformWorld2Wnd, &pDc->dclevel.mxWorldToPage);
-            IntGdiCombineTransform(&xformWorld2Wnd, &xformWorld2Wnd, lpXForm);
-            XForm2MatrixS(&pDc->dclevel.mxWorldToPage, &xformWorld2Wnd);
-            break;
-
-        case MWT_MAX+1: // Must be MWT_SET????
-            XForm2MatrixS(&pDc->dclevel.mxWorldToPage, lpXForm); // Do it like Wine.
-            break;
-
-        default:
-            return FALSE;
-    }
-    DC_UpdateXforms(pDc);
-    return TRUE;
-}
-
-// FIXME: Don't use floating point in the kernel!
-void IntWindowToViewPort(PDC_ATTR pdcattr, LPXFORM xformWnd2Vport)
-{
-    FLOAT scaleX, scaleY;
-
-    scaleX = (pdcattr->szlWindowExt.cx ? (FLOAT)pdcattr->szlViewportExt.cx / (FLOAT)pdcattr->szlWindowExt.cx : 0.0f);
-    scaleY = (pdcattr->szlWindowExt.cy ? (FLOAT)pdcattr->szlViewportExt.cy / (FLOAT)pdcattr->szlWindowExt.cy : 0.0f);
-    xformWnd2Vport->eM11 = scaleX;
-    xformWnd2Vport->eM12 = 0.0;
-    xformWnd2Vport->eM21 = 0.0;
-    xformWnd2Vport->eM22 = scaleY;
-    xformWnd2Vport->eDx  = (FLOAT)pdcattr->ptlViewportOrg.x - scaleX * (FLOAT)pdcattr->ptlWindowOrg.x;
-    xformWnd2Vport->eDy  = (FLOAT)pdcattr->ptlViewportOrg.y - scaleY * (FLOAT)pdcattr->ptlWindowOrg.y;
-}
-
 // FIXME: Should be XFORML and use XFORMOBJ functions directly
 BOOL
 APIENTRY
@@ -188,19 +181,19 @@ NtGdiGetTransform(
     DWORD iXform,
     LPXFORM  XForm)
 {
-    PDC  dc;
+    PDC pdc;
     NTSTATUS Status = STATUS_SUCCESS;
 
-    dc = DC_LockDc(hDC);
-    if (!dc)
+    if (!XForm)
     {
-        EngSetLastError(ERROR_INVALID_HANDLE);
+        EngSetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
-    if (!XForm)
+
+    pdc = DC_LockDc(hDC);
+    if (!pdc)
     {
-        DC_UnlockDc(dc);
-        EngSetLastError(ERROR_INVALID_PARAMETER);
+        EngSetLastError(ERROR_INVALID_HANDLE);
         return FALSE;
     }
 
@@ -210,19 +203,19 @@ NtGdiGetTransform(
         switch (iXform)
         {
             case GdiWorldSpaceToPageSpace:
-                MatrixS2XForm(XForm, &dc->dclevel.mxWorldToPage);
+                MatrixS2XForm(XForm, &pdc->dclevel.mxWorldToPage);
                 break;
 
             case GdiWorldSpaceToDeviceSpace:
-                MatrixS2XForm(XForm, &dc->dclevel.mxWorldToDevice);
+                MatrixS2XForm(XForm, &pdc->dclevel.mxWorldToDevice);
                 break;
 
             case GdiPageSpaceToDeviceSpace:
-                IntWindowToViewPort(dc->pdcattr, XForm);
+                IntWindowToViewPort(pdc->pdcattr, XForm);
                 break;
 
             case GdiDeviceSpaceToWorldSpace:
-                MatrixS2XForm(XForm, &dc->dclevel.mxDeviceToWorld);
+                MatrixS2XForm(XForm, &pdc->dclevel.mxDeviceToWorld);
                 break;
 
             default:
@@ -237,18 +230,19 @@ NtGdiGetTransform(
     }
     _SEH2_END;
 
-    DC_UnlockDc(dc);
+    DC_UnlockDc(pdc);
     return NT_SUCCESS(Status);
 }
 
 
 /*!
- * Converts points from logical coordinates into device coordinates. Conversion depends on the mapping mode,
+ * Converts points from logical coordinates into device coordinates.
+ * Conversion depends on the mapping mode,
  * world transfrom, viewport origin settings for the given device context.
  * \param      hDC             device context.
  * \param      Points  an array of POINT structures (in/out).
  * \param      Count   number of elements in the array of POINT structures.
- * \return  TRUE       if success.
+ * \return  TRUE if success, FALSE otherwise.
 */
 BOOL
 APIENTRY
@@ -259,13 +253,13 @@ NtGdiTransformPoints(
     INT Count,
     INT iMode)
 {
-    PDC dc;
-    NTSTATUS Status = STATUS_SUCCESS;
+    PDC pdc;
     LPPOINT Points;
     ULONG Size;
+    BOOL ret;
 
-    dc = DC_LockDc(hDC);
-    if (!dc)
+    pdc = DC_LockDc(hDC);
+    if (!pdc)
     {
         EngSetLastError(ERROR_INVALID_HANDLE);
         return FALSE;
@@ -273,7 +267,7 @@ NtGdiTransformPoints(
 
     if (!UnsafePtsIn || !UnsafePtOut || Count <= 0)
     {
-        DC_UnlockDc(dc);
+        DC_UnlockDc(pdc);
         EngSetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
@@ -284,7 +278,7 @@ NtGdiTransformPoints(
     Points = ExAllocatePoolWithTag(PagedPool, Size, TAG_COORD);
     if (!Points)
     {
-        DC_UnlockDc(dc);
+        DC_UnlockDc(pdc);
         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return FALSE;
     }
@@ -297,35 +291,28 @@ NtGdiTransformPoints(
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        Status = _SEH2_GetExceptionCode();
+        SetLastNtError(_SEH2_GetExceptionCode());
+        ret = FALSE;
+        _SEH2_YIELD(goto leave;)
     }
     _SEH2_END;
 
-    if (!NT_SUCCESS(Status))
-    {
-        DC_UnlockDc(dc);
-        ExFreePoolWithTag(Points, TAG_COORD);
-        SetLastNtError(Status);
-        return FALSE;
-    }
-
     switch (iMode)
     {
         case GdiDpToLp:
-            IntDPtoLP(dc, Points, Count);
+            IntDPtoLP(pdc, Points, Count);
             break;
 
         case GdiLpToDp:
-            IntLPtoDP(dc, Points, Count);
+            IntLPtoDP(pdc, Points, Count);
             break;
 
         case 2: // Not supported yet. Need testing.
         default:
         {
-            DC_UnlockDc(dc);
-            ExFreePoolWithTag(Points, TAG_COORD);
             EngSetLastError(ERROR_INVALID_PARAMETER);
-            return FALSE;
+            ret = FALSE;
+            goto leave;
         }
     }
 
@@ -336,22 +323,63 @@ NtGdiTransformPoints(
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        Status = _SEH2_GetExceptionCode();
+        SetLastNtError(_SEH2_GetExceptionCode());
+        ret = FALSE;
     }
     _SEH2_END;
 
-    if (!NT_SUCCESS(Status))
-    {
-        DC_UnlockDc(dc);
-        ExFreePoolWithTag(Points, TAG_COORD);
-        SetLastNtError(Status);
-        return FALSE;
-    }
 //
 // If we are getting called that means User XForms is a mess!
 //
-    DC_UnlockDc(dc);
+leave:
+    DC_UnlockDc(pdc);
     ExFreePoolWithTag(Points, TAG_COORD);
+    return ret;
+}
+
+// FIXME: Don't use floating point in the kernel
+BOOL
+FASTCALL
+IntGdiModifyWorldTransform(
+    PDC pDc,
+    CONST LPXFORM lpXForm,
+    DWORD Mode)
+{
+    XFORM xformWorld2Wnd;
+    ASSERT(pDc);
+
+    switch (Mode)
+    {
+        case MWT_IDENTITY:
+            xformWorld2Wnd.eM11 = 1.0f;
+            xformWorld2Wnd.eM12 = 0.0f;
+            xformWorld2Wnd.eM21 = 0.0f;
+            xformWorld2Wnd.eM22 = 1.0f;
+            xformWorld2Wnd.eDx  = 0.0f;
+            xformWorld2Wnd.eDy  = 0.0f;
+            XForm2MatrixS(&pDc->dclevel.mxWorldToPage, &xformWorld2Wnd);
+            break;
+
+        case MWT_LEFTMULTIPLY:
+            MatrixS2XForm(&xformWorld2Wnd, &pDc->dclevel.mxWorldToPage);
+            IntGdiCombineTransform(&xformWorld2Wnd, lpXForm, &xformWorld2Wnd);
+            XForm2MatrixS(&pDc->dclevel.mxWorldToPage, &xformWorld2Wnd);
+            break;
+
+        case MWT_RIGHTMULTIPLY:
+            MatrixS2XForm(&xformWorld2Wnd, &pDc->dclevel.mxWorldToPage);
+            IntGdiCombineTransform(&xformWorld2Wnd, &xformWorld2Wnd, lpXForm);
+            XForm2MatrixS(&pDc->dclevel.mxWorldToPage, &xformWorld2Wnd);
+            break;
+
+        case MWT_MAX+1: // Must be MWT_SET????
+            XForm2MatrixS(&pDc->dclevel.mxWorldToPage, lpXForm); // Do it like Wine.
+            break;
+
+        default:
+            return FALSE;
+    }
+    DC_UpdateXforms(pDc);
     return TRUE;
 }
 
@@ -363,7 +391,7 @@ NtGdiModifyWorldTransform(
     DWORD Mode)
 {
     PDC dc;
-    XFORM SafeXForm;
+    XFORM SafeXForm; //FIXME: use XFORML
     BOOL Ret = TRUE;
 
     dc = DC_LockDc(hDC);
@@ -528,31 +556,6 @@ NtGdiScaleViewportExtEx(
     }
     pdcattr = pDC->pdcattr;
 
-    if (pSize)
-    {
-        NTSTATUS Status = STATUS_SUCCESS;
-
-        _SEH2_TRY
-        {
-            ProbeForWrite(pSize, sizeof(LPSIZE), 1);
-
-            pSize->cx = pdcattr->szlViewportExt.cx;
-            pSize->cy = pdcattr->szlViewportExt.cy;
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            Status = _SEH2_GetExceptionCode();
-        }
-        _SEH2_END;
-
-        if (!NT_SUCCESS(Status))
-        {
-            SetLastNtError(Status);
-            DC_UnlockDc(pDC);
-            return FALSE;
-        }
-    }
-
     if (pdcattr->iMapMode > MM_TWIPS)
     {
         if (Xdenom && Ydenom)
@@ -586,6 +589,23 @@ NtGdiScaleViewportExtEx(
     else
         Ret = TRUE;
 
+    if (pSize)
+    {
+        _SEH2_TRY
+        {
+            ProbeForWrite(pSize, sizeof(LPSIZE), 1);
+
+            pSize->cx = pdcattr->szlViewportExt.cx;
+            pSize->cy = pdcattr->szlViewportExt.cy;
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            SetLastNtError(_SEH2_GetExceptionCode());
+            Ret = FALSE;
+        }
+        _SEH2_END;
+    }
+
     DC_UnlockDc(pDC);
     return Ret;
 }
@@ -1102,37 +1122,6 @@ DC_InvertXform(const XFORM *xformSrc,
     return  TRUE;
 }
 
-VOID FASTCALL
-DC_UpdateXforms(PDC dc)
-{
-    XFORM  xformWnd2Vport;
-    PDC_ATTR pdcattr = dc->pdcattr;
-    XFORM xformWorld2Vport, xformWorld2Wnd, xformVport2World;
-
-    /* Construct a transformation to do the window-to-viewport conversion */
-    IntWindowToViewPort(pdcattr, &xformWnd2Vport);
-
-    /* Combine with the world transformation */
-    MatrixS2XForm(&xformWorld2Vport, &dc->dclevel.mxWorldToDevice);
-    MatrixS2XForm(&xformWorld2Wnd, &dc->dclevel.mxWorldToPage);
-    IntGdiCombineTransform(&xformWorld2Vport, &xformWorld2Wnd, &xformWnd2Vport);
-
-    /* Create inverse of world-to-viewport transformation */
-    MatrixS2XForm(&xformVport2World, &dc->dclevel.mxDeviceToWorld);
-    if (DC_InvertXform(&xformWorld2Vport, &xformVport2World))
-    {
-        pdcattr->flXform &= ~DEVICE_TO_WORLD_INVALID;
-    }
-    else
-    {
-        pdcattr->flXform |= DEVICE_TO_WORLD_INVALID;
-    }
-
-    /* Update transformation matrices */
-    XForm2MatrixS(&dc->dclevel.mxWorldToDevice, &xformWorld2Vport);
-    XForm2MatrixS(&dc->dclevel.mxDeviceToWorld, &xformVport2World);
-}
-
 LONG FASTCALL
 IntCalcFillOrigin(PDC pdc)
 {
@@ -1170,29 +1159,6 @@ DC_vGetAspectRatioFilter(PDC pDC, LPSIZE AspectRatio)
     }
 }
 
-VOID
-FASTCALL
-DC_vUpdateViewportExt(PDC pdc)
-{
-    PDC_ATTR pdcattr;
-
-    /* Get a pointer to the dc attribute */
-    pdcattr = pdc->pdcattr;
-
-    /* Check if we need to recalculate */
-    if (pdcattr->flXform & PAGE_EXTENTS_CHANGED)
-    {
-        /* Check if we need to do isotropic fixup */
-        if (pdcattr->iMapMode == MM_ISOTROPIC)
-        {
-            IntFixIsotropicMapping(pdc);
-        }
-
-        /* Update xforms, CHECKME: really done here? */
-        DC_UpdateXforms(pdc);
-    }
-}
-
 BOOL APIENTRY
 NtGdiGetDCPoint(
     HDC hDC,