Author: tkreuzer
Date: Tue Jan 4 16:53:23 2011
New Revision: 50283
URL:
http://svn.reactos.org/svn/reactos?rev=50283&view=rev
Log:
[WIN32K]
- Simplify error checks, by reordering code in NtGdiScaleViewportExtEx
- Simplify exception handling, use _SEH2_YIELD
- Change function order
- Minor code improvements
Modified:
trunk/reactos/subsystems/win32/win32k/objects/coord.c
Modified: trunk/reactos/subsystems/win32/win32k/objects/coord.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/coord.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/coord.c [iso-8859-1] Tue Jan 4 16:53:23
2011
@@ -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
@@ -35,13 +16,13 @@
/* 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 ||
@@ -63,6 +44,76 @@
{
s = pdcattr->szlWindowExt.cx * pdcattr->szlViewportExt.cy > 0 ? 1 : -1;
pdcattr->szlViewportExt.cy = s * fy / pdcattr->szlWindowExt.cx;
+ }
+}
+
+// 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);
}
}
@@ -74,6 +125,7 @@
LPXFORM xform2)
{
XFORM xformTemp;
+
/* Check for illegal parameters */
if (!XFormResult || !xform1 || !xform2)
{
@@ -94,10 +146,12 @@
}
// 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;
@@ -117,6 +171,170 @@
_SEH2_END;
return Ret;
+}
+
+// FIXME: Should be XFORML and use XFORMOBJ functions directly
+BOOL
+APIENTRY
+NtGdiGetTransform(
+ HDC hDC,
+ DWORD iXform,
+ LPXFORM XForm)
+{
+ PDC pdc;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if (!XForm)
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ pdc = DC_LockDc(hDC);
+ if (!pdc)
+ {
+ EngSetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ _SEH2_TRY
+ {
+ ProbeForWrite(XForm, sizeof(XFORM), 1);
+ switch (iXform)
+ {
+ case GdiWorldSpaceToPageSpace:
+ MatrixS2XForm(XForm, &pdc->dclevel.mxWorldToPage);
+ break;
+
+ case GdiWorldSpaceToDeviceSpace:
+ MatrixS2XForm(XForm, &pdc->dclevel.mxWorldToDevice);
+ break;
+
+ case GdiPageSpaceToDeviceSpace:
+ IntWindowToViewPort(pdc->pdcattr, XForm);
+ break;
+
+ case GdiDeviceSpaceToWorldSpace:
+ MatrixS2XForm(XForm, &pdc->dclevel.mxDeviceToWorld);
+ break;
+
+ default:
+ DPRINT1("Unknown transform %lu\n", iXform);
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ DC_UnlockDc(pdc);
+ return NT_SUCCESS(Status);
+}
+
+
+/*!
+ * 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, FALSE otherwise.
+*/
+BOOL
+APIENTRY
+NtGdiTransformPoints(
+ HDC hDC,
+ PPOINT UnsafePtsIn,
+ PPOINT UnsafePtOut,
+ INT Count,
+ INT iMode)
+{
+ PDC pdc;
+ LPPOINT Points;
+ ULONG Size;
+ BOOL ret;
+
+ pdc = DC_LockDc(hDC);
+ if (!pdc)
+ {
+ EngSetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (!UnsafePtsIn || !UnsafePtOut || Count <= 0)
+ {
+ DC_UnlockDc(pdc);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ Size = Count * sizeof(POINT);
+
+ // FIXME: It would be wise to have a small stack buffer as optimization
+ Points = ExAllocatePoolWithTag(PagedPool, Size, TAG_COORD);
+ if (!Points)
+ {
+ DC_UnlockDc(pdc);
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ _SEH2_TRY
+ {
+ ProbeForWrite(UnsafePtOut, Size, 1);
+ ProbeForRead(UnsafePtsIn, Size, 1);
+ RtlCopyMemory(Points, UnsafePtsIn, Size);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ ret = FALSE;
+ _SEH2_YIELD(goto leave;)
+ }
+ _SEH2_END;
+
+ switch (iMode)
+ {
+ case GdiDpToLp:
+ IntDPtoLP(pdc, Points, Count);
+ break;
+
+ case GdiLpToDp:
+ IntLPtoDP(pdc, Points, Count);
+ break;
+
+ case 2: // Not supported yet. Need testing.
+ default:
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ ret = FALSE;
+ goto leave;
+ }
+ }
+
+ _SEH2_TRY
+ {
+ /* pointer was already probed! */
+ RtlCopyMemory(UnsafePtOut, Points, Size);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ ret = FALSE;
+ }
+ _SEH2_END;
+
+//
+// If we are getting called that means User XForms is a mess!
+//
+leave:
+ DC_UnlockDc(pdc);
+ ExFreePoolWithTag(Points, TAG_COORD);
+ return ret;
}
// FIXME: Don't use floating point in the kernel
@@ -165,196 +383,6 @@
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
-NtGdiGetTransform(
- HDC hDC,
- DWORD iXform,
- LPXFORM XForm)
-{
- PDC dc;
- NTSTATUS Status = STATUS_SUCCESS;
-
- dc = DC_LockDc(hDC);
- if (!dc)
- {
- EngSetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!XForm)
- {
- DC_UnlockDc(dc);
- EngSetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- _SEH2_TRY
- {
- ProbeForWrite(XForm, sizeof(XFORM), 1);
- switch (iXform)
- {
- case GdiWorldSpaceToPageSpace:
- MatrixS2XForm(XForm, &dc->dclevel.mxWorldToPage);
- break;
-
- case GdiWorldSpaceToDeviceSpace:
- MatrixS2XForm(XForm, &dc->dclevel.mxWorldToDevice);
- break;
-
- case GdiPageSpaceToDeviceSpace:
- IntWindowToViewPort(dc->pdcattr, XForm);
- break;
-
- case GdiDeviceSpaceToWorldSpace:
- MatrixS2XForm(XForm, &dc->dclevel.mxDeviceToWorld);
- break;
-
- default:
- DPRINT1("Unknown transform %lu\n", iXform);
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END;
-
- DC_UnlockDc(dc);
- return NT_SUCCESS(Status);
-}
-
-
-/*!
- * 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.
-*/
-BOOL
-APIENTRY
-NtGdiTransformPoints(
- HDC hDC,
- PPOINT UnsafePtsIn,
- PPOINT UnsafePtOut,
- INT Count,
- INT iMode)
-{
- PDC dc;
- NTSTATUS Status = STATUS_SUCCESS;
- LPPOINT Points;
- ULONG Size;
-
- dc = DC_LockDc(hDC);
- if (!dc)
- {
- EngSetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- if (!UnsafePtsIn || !UnsafePtOut || Count <= 0)
- {
- DC_UnlockDc(dc);
- EngSetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- Size = Count * sizeof(POINT);
-
- // FIXME: It would be wise to have a small stack buffer as optimization
- Points = ExAllocatePoolWithTag(PagedPool, Size, TAG_COORD);
- if (!Points)
- {
- DC_UnlockDc(dc);
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
-
- _SEH2_TRY
- {
- ProbeForWrite(UnsafePtOut, Size, 1);
- ProbeForRead(UnsafePtsIn, Size, 1);
- RtlCopyMemory(Points, UnsafePtsIn, Size);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _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);
- break;
-
- case GdiLpToDp:
- IntLPtoDP(dc, Points, Count);
- break;
-
- case 2: // Not supported yet. Need testing.
- default:
- {
- DC_UnlockDc(dc);
- ExFreePoolWithTag(Points, TAG_COORD);
- EngSetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- }
-
- _SEH2_TRY
- {
- /* pointer was already probed! */
- RtlCopyMemory(UnsafePtOut, Points, Size);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _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);
- ExFreePoolWithTag(Points, TAG_COORD);
- return TRUE;
-}
-
BOOL
APIENTRY
NtGdiModifyWorldTransform(
@@ -363,7 +391,7 @@
DWORD Mode)
{
PDC dc;
- XFORM SafeXForm;
+ XFORM SafeXForm; //FIXME: use XFORML
BOOL Ret = TRUE;
dc = DC_LockDc(hDC);
@@ -527,31 +555,6 @@
return FALSE;
}
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)
{
@@ -585,6 +588,23 @@
}
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 @@
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)
{
@@ -1167,29 +1156,6 @@
{
AspectRatio->cx = 0;
AspectRatio->cy = 0;
- }
-}
-
-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);
}
}