some fixes

svn path=/trunk/; revision=7454
This commit is contained in:
Thomas Bluemel 2004-01-04 21:26:59 +00:00
parent 73990aee98
commit c82235044d
3 changed files with 350 additions and 160 deletions

View file

@ -114,5 +114,12 @@ IntGdiCreateDC(PUNICODE_STRING Driver,
PUNICODE_STRING Output, PUNICODE_STRING Output,
CONST PDEVMODEW InitData); CONST PDEVMODEW InitData);
/* Coord functions */
BOOL FASTCALL
IntGdiCombineTransform(LPXFORM XFormResult,
LPXFORM xform1,
LPXFORM xform2);
#endif /* _WIN32K_INTGDI_H */ #endif /* _WIN32K_INTGDI_H */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: coord.c,v 1.20 2003/12/21 18:38:37 navaraf Exp $ /* $Id: coord.c,v 1.21 2004/01/04 21:26:59 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -38,35 +38,63 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
BOOL FASTCALL
IntGdiCombineTransform(LPXFORM XFormResult,
LPXFORM xform1,
LPXFORM xform2)
{
/* Check for illegal parameters */
if (!XFormResult || !xform1 || !xform2)
{
return FALSE;
}
/* Create the result in a temporary XFORM, since xformResult may be
* equal to xform1 or xform2 */
XFormResult->eM11 = xform1->eM11 * xform2->eM11 + xform1->eM12 * xform2->eM21;
XFormResult->eM12 = xform1->eM11 * xform2->eM12 + xform1->eM12 * xform2->eM22;
XFormResult->eM21 = xform1->eM21 * xform2->eM11 + xform1->eM22 * xform2->eM21;
XFormResult->eM22 = xform1->eM21 * xform2->eM12 + xform1->eM22 * xform2->eM22;
XFormResult->eDx = xform1->eDx * xform2->eM11 + xform1->eDy * xform2->eM21 + xform2->eDx;
XFormResult->eDy = xform1->eDx * xform2->eM12 + xform1->eDy * xform2->eM22 + xform2->eDy;
return TRUE;
}
BOOL STDCALL NtGdiCombineTransform(LPXFORM UnsafeXFormResult, BOOL STDCALL NtGdiCombineTransform(LPXFORM UnsafeXFormResult,
CONST LPXFORM Unsafexform1, CONST LPXFORM Unsafexform1,
CONST LPXFORM Unsafexform2) CONST LPXFORM Unsafexform2)
{ {
XFORM xformTemp; XFORM xformTemp;
XFORM xform1, xform2; XFORM xform1, xform2;
NTSTATUS Status;
BOOL Ret;
/* Check for illegal parameters */
if (!UnsafeXFormResult || !Unsafexform1 || !Unsafexform2) Status = MmCopyFromCaller( &xform1, Unsafexform1, sizeof(XFORM) );
if(!NT_SUCCESS(Status))
{ {
SetLastNtError(Status);
return FALSE;
}
Status = MmCopyFromCaller( &xform2, Unsafexform2, sizeof(XFORM) );
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE; return FALSE;
} }
MmCopyFromCaller( &xform1, Unsafexform1, sizeof(XFORM) ); Ret = IntGdiCombineTransform(&xformTemp, &xform1, &xform2);
MmCopyFromCaller( &xform2, Unsafexform2, sizeof(XFORM) );
/* Create the result in a temporary XFORM, since xformResult may be
* equal to xform1 or xform2 */
xformTemp.eM11 = xform1.eM11 * xform2.eM11 + xform1.eM12 * xform2.eM21;
xformTemp.eM12 = xform1.eM11 * xform2.eM12 + xform1.eM12 * xform2.eM22;
xformTemp.eM21 = xform1.eM21 * xform2.eM11 + xform1.eM22 * xform2.eM21;
xformTemp.eM22 = xform1.eM21 * xform2.eM12 + xform1.eM22 * xform2.eM22;
xformTemp.eDx = xform1.eDx * xform2.eM11 + xform1.eDy * xform2.eM21 + xform2.eDx;
xformTemp.eDy = xform1.eDx * xform2.eM12 + xform1.eDy * xform2.eM22 + xform2.eDy;
/* Copy the result to xformResult */ /* Copy the result to xformResult */
MmCopyToCaller( UnsafeXFormResult, &xformTemp, sizeof(XFORM) ); Status = MmCopyToCaller( UnsafeXFormResult, &xformTemp, sizeof(XFORM) );
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
return TRUE; return Ret;
} }
VOID FASTCALL VOID FASTCALL
@ -107,24 +135,57 @@ NtGdiDPtoLP(HDC hDC,
int Count) int Count)
{ {
PDC dc; PDC dc;
LPPOINT Points = (LPPOINT)ExAllocatePool(PagedPool, Count * sizeof(POINT)); NTSTATUS Status;
BOOL ret = FALSE; // default to failure LPPOINT Points;
ULONG Size;
if (!Points)
return FALSE;
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if (dc) if (!dc)
{ {
ret = TRUE; SetLastWin32Error(ERROR_INVALID_HANDLE);
MmCopyFromCaller(Points, UnsafePoints, Count * sizeof(POINT)); return FALSE;
IntDPtoLP(dc, Points, Count);
MmCopyToCaller(UnsafePoints, Points, Count * sizeof(POINT));
DC_UnlockDc(hDC);
} }
ExFreePool(Points);
return ret; if (!UnsafePoints || Count <= 0)
{
DC_UnlockDc(hDC);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
Size = Count * sizeof(POINT);
Points = (LPPOINT)ExAllocatePool(PagedPool, Size);
if(!Points)
{
DC_UnlockDc(hDC);
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
Status = MmCopyFromCaller(Points, UnsafePoints, Size);
if(!NT_SUCCESS(Status))
{
DC_UnlockDc(hDC);
ExFreePool(Points);
SetLastNtError(Status);
return FALSE;
}
IntDPtoLP(dc, Points, Count);
Status = MmCopyToCaller(UnsafePoints, Points, Size);
if(!NT_SUCCESS(Status))
{
DC_UnlockDc(hDC);
ExFreePool(Points);
SetLastNtError(Status);
return FALSE;
}
DC_UnlockDc(hDC);
ExFreePool(Points);
return TRUE;
} }
int int
@ -139,15 +200,19 @@ int
STDCALL STDCALL
NtGdiGetGraphicsMode ( HDC hDC ) NtGdiGetGraphicsMode ( HDC hDC )
{ {
PDC dc = DC_LockDc ( hDC ); PDC dc;
int GraphicsMode = 0; // default to failure int GraphicsMode; // default to failure
if ( dc ) dc = DC_LockDc ( hDC );
if (!dc)
{ {
GraphicsMode = dc->w.GraphicsMode; SetLastWin32Error(ERROR_INVALID_HANDLE);
DC_UnlockDc ( hDC ); return 0;
} }
GraphicsMode = dc->w.GraphicsMode;
DC_UnlockDc ( hDC );
return GraphicsMode; return GraphicsMode;
} }
@ -157,19 +222,25 @@ NtGdiGetWorldTransform(HDC hDC,
LPXFORM XForm) LPXFORM XForm)
{ {
PDC dc; PDC dc;
NTSTATUS Status;
if (!XForm) dc = DC_LockDc ( hDC );
return FALSE;
dc = DC_LockDc (hDC);
if (!dc) if (!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
}
if (!XForm)
{
DC_UnlockDc ( hDC );
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
*XForm = dc->w.xformWorld2Wnd; Status = MmCopyToCaller(XForm, &dc->w.xformWorld2Wnd, sizeof(XFORM));
DC_UnlockDc ( hDC ); DC_UnlockDc ( hDC );
return NT_SUCCESS(Status);
return TRUE;
} }
VOID VOID
@ -213,31 +284,57 @@ BOOL STDCALL
NtGdiLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count ) NtGdiLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count )
{ {
PDC dc; PDC dc;
LPPOINT Points = (LPPOINT)ExAllocatePool ( PagedPool, Count*sizeof(POINT) ); NTSTATUS Status;
BOOL ret = FALSE; // default to failure LPPOINT Points;
ULONG Size;
ASSERT(Points); dc = DC_LockDc(hDC);
if ( !Points ) if (!dc)
return FALSE;
dc = DC_LockDc ( hDC );
if ( dc )
{ {
ret = TRUE; SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
MmCopyFromCaller( Points, UnsafePoints, Count*sizeof(POINT) );
IntLPtoDP ( dc, Points, Count );
MmCopyToCaller ( UnsafePoints, Points, Count*sizeof(POINT) );
DC_UnlockDc ( hDC );
} }
ExFreePool ( Points ); if (!UnsafePoints || Count <= 0)
{
DC_UnlockDc(hDC);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
return ret; Size = Count * sizeof(POINT);
Points = (LPPOINT)ExAllocatePool(PagedPool, Size);
if(!Points)
{
DC_UnlockDc(hDC);
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
Status = MmCopyFromCaller(Points, UnsafePoints, Size);
if(!NT_SUCCESS(Status))
{
DC_UnlockDc(hDC);
ExFreePool(Points);
SetLastNtError(Status);
return FALSE;
}
IntLPtoDP(dc, Points, Count);
Status = MmCopyToCaller(UnsafePoints, Points, Size);
if(!NT_SUCCESS(Status))
{
DC_UnlockDc(hDC);
ExFreePool(Points);
SetLastNtError(Status);
return FALSE;
}
DC_UnlockDc(hDC);
ExFreePool(Points);
return TRUE;
} }
BOOL BOOL
@ -247,23 +344,32 @@ NtGdiModifyWorldTransform(HDC hDC,
DWORD Mode) DWORD Mode)
{ {
PDC dc; PDC dc;
LPXFORM XForm = (LPXFORM) ExAllocatePool( PagedPool, sizeof( XFORM ) ); XFORM SafeXForm;
BOOL ret = FALSE; // default to failure NTSTATUS Status;
ASSERT( XForm ); dc = DC_LockDc(hDC);
if (!XForm) if (!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
}
MmCopyFromCaller( XForm, UnsafeXForm, sizeof( XFORM ) ); if (!UnsafeXForm)
{
DC_UnlockDc(hDC);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
dc = DC_LockDc (hDC); Status = MmCopyFromCaller(&SafeXForm, UnsafeXForm, sizeof(XFORM));
if ( dc ) if(!NT_SUCCESS(Status))
{ {
/* Check that graphics mode is GM_ADVANCED */ DC_UnlockDc(hDC);
if ( dc->w.GraphicsMode == GM_ADVANCED ) SetLastNtError(Status);
{ return FALSE;
ret = TRUE; // switch to a default of success }
switch (Mode)
switch(Mode)
{ {
case MWT_IDENTITY: case MWT_IDENTITY:
dc->w.xformWorld2Wnd.eM11 = 1.0f; dc->w.xformWorld2Wnd.eM11 = 1.0f;
@ -275,24 +381,22 @@ NtGdiModifyWorldTransform(HDC hDC,
break; break;
case MWT_LEFTMULTIPLY: case MWT_LEFTMULTIPLY:
NtGdiCombineTransform(&dc->w.xformWorld2Wnd, XForm, &dc->w.xformWorld2Wnd ); IntGdiCombineTransform(&dc->w.xformWorld2Wnd, &SafeXForm, &dc->w.xformWorld2Wnd );
break; break;
case MWT_RIGHTMULTIPLY: case MWT_RIGHTMULTIPLY:
NtGdiCombineTransform(&dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd, XForm); IntGdiCombineTransform(&dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd, &SafeXForm);
break; break;
default: default:
ret = FALSE; DC_UnlockDc(hDC);
break; SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
} }
if ( ret )
DC_UpdateXforms ( dc ); DC_UpdateXforms(dc);
} DC_UnlockDc(hDC);
DC_UnlockDc ( hDC ); return TRUE;
}
ExFreePool ( XForm );
return ret;
} }
BOOL BOOL
@ -305,13 +409,15 @@ NtGdiOffsetViewportOrgEx(HDC hDC,
PDC dc; PDC dc;
POINT Point; POINT Point;
NTSTATUS Status; NTSTATUS Status;
BOOL ret = FALSE; // default to failure
dc = DC_LockDc ( hDC ); dc = DC_LockDc ( hDC );
if ( dc ) if(!dc)
{ {
ret = TRUE; SetLastWin32Error(ERROR_INVALID_HANDLE);
if (NULL != UnsafePoint) return FALSE;
}
if (UnsafePoint)
{ {
Point.x = dc->vportOrgX; Point.x = dc->vportOrgX;
Point.y = dc->vportOrgY; Point.y = dc->vportOrgY;
@ -319,22 +425,19 @@ NtGdiOffsetViewportOrgEx(HDC hDC,
if ( !NT_SUCCESS(Status) ) if ( !NT_SUCCESS(Status) )
{ {
SetLastNtError(Status); SetLastNtError(Status);
ret = FALSE; DC_UnlockDc ( hDC );
return FALSE;
} }
} }
if ( ret )
{
dc->vportOrgX += XOffset; dc->vportOrgX += XOffset;
dc->vportOrgY += YOffset; dc->vportOrgY += YOffset;
DC_UpdateXforms(dc); DC_UpdateXforms(dc);
dc->w.DCOrgX += XOffset; dc->w.DCOrgX += XOffset;
dc->w.DCOrgY += YOffset; dc->w.DCOrgY += YOffset;
}
DC_UnlockDc ( hDC ); DC_UnlockDc ( hDC );
}
return TRUE; return TRUE;
} }
@ -350,13 +453,25 @@ NtGdiOffsetWindowOrgEx(HDC hDC,
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if (!dc) if (!dc)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
if (Point) if (Point)
{ {
Point->x = dc->wndOrgX; POINT SafePoint;
Point->y = dc->wndOrgY; NTSTATUS Status;
SafePoint.x = dc->wndOrgX;
SafePoint.y = dc->wndOrgY;
Status = MmCopyToCaller(Point, &SafePoint, sizeof(POINT));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
DC_UnlockDc(hDC);
return FALSE;
}
} }
dc->wndOrgX += XOffset; dc->wndOrgX += XOffset;
@ -402,6 +517,7 @@ NtGdiSetGraphicsMode(HDC hDC,
dc = DC_LockDc (hDC); dc = DC_LockDc (hDC);
if (!dc) if (!dc)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0; return 0;
} }
@ -414,6 +530,7 @@ NtGdiSetGraphicsMode(HDC hDC,
if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED)) if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED))
{ {
DC_UnlockDc( hDC ); DC_UnlockDc( hDC );
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
@ -433,7 +550,10 @@ NtGdiSetMapMode(HDC hDC,
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if (!dc) if (!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0; return 0;
}
PrevMapMode = dc->w.MapMode; PrevMapMode = dc->w.MapMode;
dc->w.MapMode = MapMode; dc->w.MapMode = MapMode;
@ -454,7 +574,10 @@ NtGdiSetViewportExtEx(HDC hDC,
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if ( !dc ) if ( !dc )
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
}
switch (dc->w.MapMode) switch (dc->w.MapMode)
{ {
@ -475,8 +598,19 @@ NtGdiSetViewportExtEx(HDC hDC,
if (Size) if (Size)
{ {
Size->cx = dc->vportExtX; SIZE SafeSize;
Size->cy = dc->vportExtY; NTSTATUS Status;
SafeSize.cx = dc->vportExtX;
SafeSize.cy = dc->vportExtY;
Status = MmCopyToCaller(Size, &SafeSize, sizeof(SIZE));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
DC_UnlockDc(hDC);
return FALSE;
}
} }
dc->vportExtX = XExtent; dc->vportExtX = XExtent;
@ -499,13 +633,25 @@ NtGdiSetViewportOrgEx(HDC hDC,
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if (!dc) if (!dc)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
if (Point) if (Point)
{ {
Point->x = dc->vportOrgX; POINT SafePoint;
Point->y = dc->vportOrgY; NTSTATUS Status;
SafePoint.x = dc->vportOrgX;
SafePoint.y = dc->vportOrgY;
Status = MmCopyToCaller(Point, &SafePoint, sizeof(POINT));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
DC_UnlockDc(hDC);
return FALSE;
}
} }
dc->vportOrgX = X; dc->vportOrgX = X;
@ -528,6 +674,7 @@ NtGdiSetWindowExtEx(HDC hDC,
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if (!dc) if (!dc)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
@ -545,8 +692,19 @@ NtGdiSetWindowExtEx(HDC hDC,
if (Size) if (Size)
{ {
Size->cx = dc->wndExtX; SIZE SafeSize;
Size->cy = dc->wndExtY; NTSTATUS Status;
SafeSize.cx = dc->wndExtX;
SafeSize.cy = dc->wndExtY;
Status = MmCopyToCaller(Size, &SafeSize, sizeof(SIZE));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
DC_UnlockDc(hDC);
return FALSE;
}
} }
dc->wndExtX = XExtent; dc->wndExtX = XExtent;
@ -569,13 +727,25 @@ NtGdiSetWindowOrgEx(HDC hDC,
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if (!dc) if (!dc)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
if (Point) if (Point)
{ {
Point->x = dc->wndOrgX; POINT SafePoint;
Point->y = dc->wndOrgY; NTSTATUS Status;
SafePoint.x = dc->wndOrgX;
SafePoint.y = dc->wndOrgY;
Status = MmCopyToCaller(Point, &SafePoint, sizeof(POINT));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
DC_UnlockDc(hDC);
return FALSE;
}
} }
dc->wndOrgX = X; dc->wndOrgX = X;
@ -592,13 +762,19 @@ NtGdiSetWorldTransform(HDC hDC,
CONST LPXFORM XForm) CONST LPXFORM XForm)
{ {
PDC dc; PDC dc;
NTSTATUS Status;
if (!XForm)
return FALSE;
dc = DC_LockDc (hDC); dc = DC_LockDc (hDC);
if ( !dc ) if ( !dc )
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
if (!XForm)
{
DC_UnlockDc( hDC );
/* Win doesn't set LastError */
return FALSE; return FALSE;
} }
@ -608,7 +784,14 @@ NtGdiSetWorldTransform(HDC hDC,
DC_UnlockDc( hDC ); DC_UnlockDc( hDC );
return FALSE; return FALSE;
} }
dc->w.xformWorld2Wnd = *XForm;
Status = MmCopyFromCaller(&dc->w.xformWorld2Wnd, XForm, sizeof(XFORM));
if(!NT_SUCCESS(Status))
{
DC_UnlockDc( hDC );
return FALSE;
}
DC_UpdateXforms (dc); DC_UpdateXforms (dc);
DC_UnlockDc( hDC ); DC_UnlockDc( hDC );
return TRUE; return TRUE;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: dc.c,v 1.114 2003/12/23 18:19:07 navaraf Exp $ /* $Id: dc.c,v 1.115 2004/01/04 21:26:59 weiden Exp $
* *
* DC.C - Device context functions * DC.C - Device context functions
* *
@ -2010,7 +2010,7 @@ DC_UpdateXforms(PDC dc)
xformWnd2Vport.eDy = (FLOAT)dc->vportOrgY - scaleY * (FLOAT)dc->wndOrgY; xformWnd2Vport.eDy = (FLOAT)dc->vportOrgY - scaleY * (FLOAT)dc->wndOrgY;
/* Combine with the world transformation */ /* Combine with the world transformation */
NtGdiCombineTransform(&dc->w.xformWorld2Vport, &dc->w.xformWorld2Wnd, &xformWnd2Vport); IntGdiCombineTransform(&dc->w.xformWorld2Vport, &dc->w.xformWorld2Wnd, &xformWnd2Vport);
/* Create inverse of world-to-viewport transformation */ /* Create inverse of world-to-viewport transformation */
dc->w.vport2WorldValid = DC_InvertXform(&dc->w.xformWorld2Vport, &dc->w.xformVport2World); dc->w.vport2WorldValid = DC_InvertXform(&dc->w.xformWorld2Vport, &dc->w.xformVport2World);