From 0d1fa6006006e91406c385e6bcc336042ff8fca0 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Fri, 24 Aug 2007 04:49:38 +0000 Subject: [PATCH] Pluged in NtGdiPolyPolyDraw. Does not work yet, still testing it. svn path=/trunk/; revision=28503 --- reactos/dll/win32/gdi32/objects/painting.c | 36 ++-- .../win32/win32k/objects/fillshap.c | 183 +++++++++++++++++- 2 files changed, 203 insertions(+), 16 deletions(-) diff --git a/reactos/dll/win32/gdi32/objects/painting.c b/reactos/dll/win32/gdi32/objects/painting.c index 4dc644f01e3..a21b95365cd 100644 --- a/reactos/dll/win32/gdi32/objects/painting.c +++ b/reactos/dll/win32/gdi32/objects/painting.c @@ -376,11 +376,13 @@ PaintRgn( HDC hDC, HRGN hRgn ) return NtGdiFillRgn( hDC, hRgn, hBrush); } +#endif BOOL STDCALL PolyBezier(HDC hDC ,const POINT* Point, DWORD cPoints) { +#if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) { @@ -405,7 +407,8 @@ PolyBezier(HDC hDC ,const POINT* Point, DWORD cPoints) return FALSE; } } - return NtGdiPolyPolyDraw( hDC , Point, &cPoints, 1, GdiPolyBezier ); +#endif + return NtGdiPolyPolyDraw( hDC ,(PPOINT) Point, &cPoints, 1, GdiPolyBezier ); } @@ -413,6 +416,7 @@ BOOL STDCALL PolyBezierTo(HDC hDC, const POINT* Point ,DWORD cPoints) { +#if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) { @@ -433,7 +437,8 @@ PolyBezierTo(HDC hDC, const POINT* Point ,DWORD cPoints) return FALSE; } } - return NtGdiPolyPolyDraw( hDC , Point, &cPoints, 1, GdiPolyBezierTo ); +#endif + return NtGdiPolyPolyDraw( hDC , (PPOINT) Point, &cPoints, 1, GdiPolyBezierTo ); } @@ -441,6 +446,7 @@ BOOL STDCALL PolyDraw(HDC hDC, const POINT* Point, const BYTE *lpbTypes, int cCount ) { +#if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) { @@ -461,7 +467,8 @@ PolyDraw(HDC hDC, const POINT* Point, const BYTE *lpbTypes, int cCount ) return FALSE; } } - return NtGdiPolyDraw( hDC , Point, lpbTypes, cCount ); +#endif + return NtGdiPolyDraw( hDC , (PPOINT) Point, (PBYTE)lpbTypes, cCount ); } @@ -469,6 +476,7 @@ BOOL STDCALL Polygon(HDC hDC, const POINT *Point, int Count) { +#if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) { @@ -489,7 +497,8 @@ Polygon(HDC hDC, const POINT *Point, int Count) return FALSE; } } - return NtGdiPolyPolyDraw( hDC , Point, &Count, 1, GdiPolygon ); +#endif + return NtGdiPolyPolyDraw( hDC , (PPOINT) Point, (PULONG)&Count, 1, GdiPolyPolygon ); } @@ -497,6 +506,7 @@ BOOL STDCALL Polyline(HDC hDC, const POINT *Point, int Count) { +#if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) { @@ -517,7 +527,8 @@ Polyline(HDC hDC, const POINT *Point, int Count) return FALSE; } } - return NtGdiPolyPolyDraw( hDC , Point, &Count, 1, GdiPolyPolyLine ); +#endif + return NtGdiPolyPolyDraw( hDC , (PPOINT) Point, (PULONG)&Count, 1, GdiPolyPolyLine ); } @@ -525,6 +536,7 @@ BOOL STDCALL PolylineTo(HDC hDC, const POINT* Point, DWORD Count) { +#if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) { @@ -545,8 +557,8 @@ PolylineTo(HDC hDC, const POINT* Point, DWORD Count) return FALSE; } } - return NtGdiPolyPolyDraw( hDC , Point, &Count, 1, GdiPolyLineTo ); - +#endif + return NtGdiPolyPolyDraw( hDC , (PPOINT) Point, &Count, 1, GdiPolyLineTo ); } @@ -554,6 +566,7 @@ BOOL STDCALL PolyPolygon(HDC hDC, const POINT* Point, const INT* Count, int Polys) { +#if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) { @@ -574,8 +587,8 @@ PolyPolygon(HDC hDC, const POINT* Point, const INT* Count, int Polys) return FALSE; } } - return NtGdiPolyPolyDraw( hDC , Point, Count, Polys, GdiPolygon ); - +#endif + return NtGdiPolyPolyDraw( hDC , (PPOINT)Point, (PULONG)Count, Polys, GdiPolyPolygon ); } @@ -583,6 +596,7 @@ BOOL STDCALL PolyPolyline(HDC hDC, const POINT* Point, const DWORD* Counts, DWORD Polys) { +#if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) { @@ -603,9 +617,9 @@ PolyPolyline(HDC hDC, const POINT* Point, const DWORD* Counts, DWORD Polys) return FALSE; } } - return NtGdiPolyPolyDraw( hDC , Point, Count, Polys, GdiPolyPolyLine ); -} #endif + return NtGdiPolyPolyDraw( hDC , (PPOINT)Point, (PULONG)Counts, Polys, GdiPolyPolyLine ); +} BOOL diff --git a/reactos/subsystems/win32/win32k/objects/fillshap.c b/reactos/subsystems/win32/win32k/objects/fillshap.c index 72089c61db0..ff135a94b50 100644 --- a/reactos/subsystems/win32/win32k/objects/fillshap.c +++ b/reactos/subsystems/win32/win32k/objects/fillshap.c @@ -985,13 +985,186 @@ NtGdiPolyPolygon(HDC hDC, ULONG_PTR STDCALL -NtGdiPolyPolyDraw( IN HDC hdc, - IN PPOINT ppt, - IN PULONG pcpt, - IN ULONG ccpt, +NtGdiPolyPolyDraw( IN HDC hDC, + IN PPOINT Points, + IN PULONG PolyCounts, + IN ULONG Count, IN INT iFunc ) { - return (ULONG_PTR) 0; + DC *dc; + LPPOINT Safept; + LPINT SafePolyPoints; + NTSTATUS Status = STATUS_SUCCESS; + BOOL Ret = TRUE; + INT nPoints, nEmpty, nInvalid, i; + + if (iFunc == GdiPolyPolyRgn) + { // Rename me to FASTCALL GdiCreatePolyPolygonRgn + return (ULONG_PTR) NtGdiCreatePolyPolygonRgn((CONST PPOINT) Points, + (CONST PINT) PolyCounts, + Count, + (INT) hDC); + } + dc = DC_LockDc(hDC); + if(!dc) + { + SetLastWin32Error(ERROR_INVALID_HANDLE); + return FALSE; + } + if (dc->IsIC) + { + DC_UnlockDc(dc); + /* Yes, Windows really returns TRUE in this case */ + return TRUE; + } + + if(Count > 0) + { + _SEH_TRY + { + ProbeForRead(Points, + Count * sizeof(POINT), + 1); + ProbeForRead(PolyCounts, + Count * sizeof(INT), + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + DC_UnlockDc(dc); + SetLastNtError(Status); + return FALSE; + } + + SafePolyPoints = ExAllocatePoolWithTag(PagedPool, Count * sizeof(INT), TAG_SHAPE); + if(!SafePolyPoints) + { + DC_UnlockDc(dc); + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + _SEH_TRY + { + /* pointers already probed! */ + RtlCopyMemory(SafePolyPoints, + PolyCounts, + Count * sizeof(INT)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + DC_UnlockDc(dc); + ExFreePool(SafePolyPoints); + SetLastNtError(Status); + return FALSE; + } + /* validate poligons */ + nPoints = 0; + nEmpty = 0; + nInvalid = 0; + for (i = 0; i < Count; i++) + { + if (SafePolyPoints[i] == 0) + { + nEmpty++; + } + if (SafePolyPoints[i] == 1) + { + nInvalid++; + } + nPoints += SafePolyPoints[i]; + } + + if (nEmpty == Count) + { + /* if all polygon counts are zero, return without setting a last error code. */ + ExFreePool(SafePolyPoints); + return FALSE; + } + if (nInvalid != 0) + { + /* if at least one poly count is 1, fail */ + ExFreePool(SafePolyPoints); + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + + Safept = ExAllocatePoolWithTag(PagedPool, nPoints * sizeof(POINT), TAG_SHAPE); + if(!Safept) + { + DC_UnlockDc(dc); + ExFreePool(SafePolyPoints); + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + _SEH_TRY + { + /* pointers already probed! */ + RtlCopyMemory(Safept, + Points, + Count * sizeof(POINT)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + DC_UnlockDc(dc); + ExFreePool(SafePolyPoints); + ExFreePool(Safept); + SetLastNtError(Status); + return FALSE; + } + } + else + { + DC_UnlockDc(dc); + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + + switch(iFunc) + { + case GdiPolyPolygon: + Ret = IntGdiPolyPolygon(dc, Safept, SafePolyPoints, Count); + break; + case GdiPolyPolyLine: + Ret = IntGdiPolyPolyline(dc, Safept, (LPDWORD) SafePolyPoints, Count); + break; + case GdiPolyBezier: + Ret = IntGdiPolyBezier(dc, Safept, *PolyCounts); + break; + case GdiPolyLineTo: + Ret = IntGdiPolylineTo(dc, Safept, *PolyCounts); + break; + case GdiPolyBezierTo: + Ret = IntGdiPolyBezierTo(dc, Safept, *PolyCounts); + break; + default: + SetLastWin32Error(ERROR_INVALID_PARAMETER); + Ret = FALSE; + } + ExFreePool(SafePolyPoints); + ExFreePool(Safept); + DC_UnlockDc(dc); + + return (ULONG_PTR) Ret; }