Pluged in NtGdiPolyPolyDraw. Does not work yet, still testing it.
authorJames Tabor <james.tabor@reactos.org>
Fri, 24 Aug 2007 04:49:38 +0000 (04:49 +0000)
committerJames Tabor <james.tabor@reactos.org>
Fri, 24 Aug 2007 04:49:38 +0000 (04:49 +0000)
svn path=/trunk/; revision=28503

reactos/dll/win32/gdi32/objects/painting.c
reactos/subsystems/win32/win32k/objects/fillshap.c

index 4dc644f..a21b953 100644 (file)
@@ -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
index 72089c6..ff135a9 100644 (file)
@@ -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;
 }