reactos/lib/gdi32/misc
diff -u -r1.61 -r1.62
--- stubs.c 15 May 2004 08:52:25 -0000 1.61
+++ stubs.c 18 May 2004 13:57:41 -0000 1.62
@@ -1,4 +1,4 @@
-/* $Id: stubs.c,v 1.61 2004/05/15 08:52:25 navaraf Exp $
+/* $Id: stubs.c,v 1.62 2004/05/18 13:57:41 weiden Exp $
*
* reactos/lib/gdi32/misc/stubs.c
*
@@ -1091,22 +1091,6 @@
return FALSE;
}
-
-/*
- * @unimplemented
- */
-HRGN
-STDCALL
-CreatePolygonRgn(
- CONST POINT *a0,
- int a1,
- int a2
- )
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
-
/*
* @unimplemented
*/
reactos/lib/gdi32/objects
diff -u -r1.14 -r1.15
--- region.c 25 Apr 2004 14:46:54 -0000 1.14
+++ region.c 18 May 2004 13:57:41 -0000 1.15
@@ -85,8 +85,27 @@
int fnPolyFillMode
)
{
- return NtGdiCreatePolyPolygonRgn ( (CONST PPOINT)lppt,
- (CONST PINT)lpPolyCounts, nCount, fnPolyFillMode );
+ return NtGdiCreatePolyPolygonRgn((CONST PPOINT)lppt,
+ (CONST PINT)lpPolyCounts,
+ nCount,
+ fnPolyFillMode);
+}
+
+
+/*
+ * @implemented
+ */
+HRGN
+STDCALL
+CreatePolygonRgn(
+ CONST POINT *lppt,
+ int cPoints,
+ int fnPolyFillMode
+ )
+{
+ return NtGdiCreatePolygonRgn((CONST PPOINT)lppt,
+ cPoints,
+ fnPolyFillMode);
}
@@ -312,3 +331,4 @@
{
return NtGdiFrameRgn(hdc, hrgn, hbr, nWidth, nHeight);
}
+
reactos/subsys/win32k/objects
diff -u -r1.53 -r1.54
--- region.c 16 May 2004 09:51:27 -0000 1.53
+++ region.c 18 May 2004 13:57:41 -0000 1.54
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: region.c,v 1.53 2004/05/16 09:51:27 weiden Exp $ */
+/* $Id: region.c,v 1.54 2004/05/18 13:57:41 weiden Exp $ */
#include <w32k.h>
#include <win32k/float.h>
@@ -1692,23 +1692,168 @@
SafeRect.right - SafeRect.left, SafeRect.bottom - SafeRect.top);
}
+HRGN FASTCALL
+IntCreatePolyPolgonRgn(PPOINT pt,
+ PINT PolyCounts,
+ INT Count,
+ INT PolyFillMode)
+{
+ return (HRGN)0;
+}
+
HRGN
STDCALL
NtGdiCreatePolygonRgn(CONST PPOINT pt,
- INT Count,
- INT PolyFillMode)
+ INT Count,
+ INT PolyFillMode)
{
- UNIMPLEMENTED;
+ POINT *SafePoints;
+ NTSTATUS Status;
+ HRGN hRgn;
+
+
+ if (pt == NULL || Count == 0 ||
+ (PolyFillMode != WINDING && PolyFillMode != ALTERNATE))
+ {
+ /* Windows doesn't set a last error here */
+ return (HRGN)0;
+ }
+
+ if (Count == 1)
+ {
+ /* can't create a region with only one point! */
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return (HRGN)0;
+ }
+
+ if (Count == 2)
+ {
+ /* Windows creates an empty region! */
+ ROSRGNDATA *rgn;
+
+ if(!(hRgn = RGNDATA_AllocRgn(1)))
+ {
+ return (HRGN)0;
+ }
+ if(!(rgn = RGNDATA_LockRgn(hRgn)))
+ {
+ NtGdiDeleteObject(hRgn);
+ return (HRGN)0;
+ }
+
+ EMPTY_REGION(rgn);
+
+ RGNDATA_UnlockRgn(hRgn);
+ return hRgn;
+ }
+
+ if (!(SafePoints = ExAllocatePool(PagedPool, Count * sizeof(POINT))))
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return (HRGN)0;
+ }
+
+ Status = MmCopyFromCaller(SafePoints, pt, Count * sizeof(POINT));
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(SafePoints);
+ SetLastNtError(Status);
+ return (HRGN)0;
+ }
+
+ hRgn = IntCreatePolyPolgonRgn(SafePoints, &Count, 1, PolyFillMode);
+
+ ExFreePool(SafePoints);
+ return hRgn;
}
HRGN
STDCALL
NtGdiCreatePolyPolygonRgn(CONST PPOINT pt,
- CONST PINT PolyCounts,
- INT Count,
- INT PolyFillMode)
-{
- UNIMPLEMENTED;
+ CONST PINT PolyCounts,
+ INT Count,
+ INT PolyFillMode)
+{
+ POINT *Safept;
+ INT *SafePolyCounts;
+ INT nPoints, nEmpty, nInvalid, i;
+ HRGN hRgn;
+ NTSTATUS Status;
+
+ if (pt == NULL || PolyCounts == NULL || Count == 0 ||
+ (PolyFillMode != WINDING && PolyFillMode != ALTERNATE))
+ {
+ /* Windows doesn't set a last error here */
+ return (HRGN)0;
+ }
+
+ if (!(SafePolyCounts = ExAllocatePool(PagedPool, Count * sizeof(INT))))
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return (HRGN)0;
+ }
+
+ Status = MmCopyFromCaller(SafePolyCounts, PolyCounts, Count * sizeof(INT));
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(SafePolyCounts);
+ SetLastNtError(Status);
+ return (HRGN)0;
+ }
+
+ /* validate poligons */
+ nPoints = 0;
+ nEmpty = 0;
+ nInvalid = 0;
+ for (i = 0; i < Count; i++)
+ {
+ if (SafePolyCounts[i] == 0)
+ {
+ nEmpty++;
+ }
+ if (SafePolyCounts[i] == 1)
+ {
+ nInvalid++;
+ }
+ nPoints += SafePolyCounts[i];
+ }
+
+ if (nEmpty == Count)
+ {
+ /* if all polygon counts are zero, return without setting a last error code. */
+ ExFreePool(SafePolyCounts);
+ return (HRGN)0;
+ }
+ if (nInvalid != 0)
+ {
+ /* if at least one poly count is 1, fail */
+ ExFreePool(SafePolyCounts);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return (HRGN)0;
+ }
+
+ /* copy points */
+ if (!(Safept = ExAllocatePool(PagedPool, nPoints * sizeof(POINT))))
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return (HRGN)0;
+ }
+
+ Status = MmCopyFromCaller(Safept, pt, nPoints * sizeof(POINT));
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(Safept);
+ ExFreePool(SafePolyCounts);
+ SetLastNtError(Status);
+ return (HRGN)0;
+ }
+
+ /* now we're ready to calculate the region safely */
+ hRgn = IntCreatePolyPolgonRgn(Safept, SafePolyCounts, Count, PolyFillMode);
+
+ ExFreePool(Safept);
+ ExFreePool(SafePolyCounts);
+ return hRgn;
}
HRGN STDCALL