implemented NtGdiSelectClipPath and PATH_FillPath
Modified: trunk/reactos/include/win32k/cliprgn.h
Modified: trunk/reactos/subsys/win32k/include/path.h
Modified: trunk/reactos/subsys/win32k/objects/cliprgn.c
Modified: trunk/reactos/subsys/win32k/objects/path.c

Modified: trunk/reactos/include/win32k/cliprgn.h
--- trunk/reactos/include/win32k/cliprgn.h	2005-12-09 17:57:58 UTC (rev 20011)
+++ trunk/reactos/include/win32k/cliprgn.h	2005-12-09 18:06:19 UTC (rev 20012)
@@ -6,6 +6,14 @@
 
 int
 STDCALL
+IntGdiExtSelectClipRgn (
+        PDC     dc,
+        HRGN    hrgn, 
+        int     fnMode
+        );
+
+int
+STDCALL
 NtGdiExcludeClipRect (
 	HDC	hDC,
 	int	LeftRect,

Modified: trunk/reactos/subsys/win32k/include/path.h
--- trunk/reactos/subsys/win32k/include/path.h	2005-12-09 17:57:58 UTC (rev 20011)
+++ trunk/reactos/subsys/win32k/include/path.h	2005-12-09 18:06:19 UTC (rev 20012)
@@ -18,6 +18,6 @@
 BOOL FASTCALL PATH_PolyPolyline( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylines);
 BOOL FASTCALL PATH_Rectangle (PDC dc, INT x1, INT y1, INT x2, INT y2);
 BOOL FASTCALL PATH_RoundRect (PDC dc, INT x1, INT y1, INT x2, INT y2, INT xradius, INT yradius);
-BOOL FASTCALL PATH_PathToRegion (const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn);
+BOOL FASTCALL PATH_PathToRegion (GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn);
 
 #endif /* _WIN32K_PATH_H */

Modified: trunk/reactos/subsys/win32k/objects/cliprgn.c
--- trunk/reactos/subsys/win32k/objects/cliprgn.c	2005-12-09 17:57:58 UTC (rev 20011)
+++ trunk/reactos/subsys/win32k/objects/cliprgn.c	2005-12-09 18:06:19 UTC (rev 20012)
@@ -99,21 +99,14 @@
   return retval;
 }
 
-int STDCALL NtGdiExtSelectClipRgn(HDC  hDC,
-                          HRGN  hrgn,
-                          int  fnMode)
+
+int STDCALL IntGdiExtSelectClipRgn(PDC dc, 
+                                HRGN hrgn, 
+                                int fnMode)
 {
   int retval;
-  DC *dc;
+  //  dc->w.flags &= ~DC_DIRTY;
 
-  if (!(dc = DC_LockDc(hDC)))
-  {
-  	SetLastWin32Error(ERROR_INVALID_HANDLE);
-  	return ERROR;
-  }
-
-//  dc->w.flags &= ~DC_DIRTY;
-
   if (!hrgn)
   {
     if (fnMode == RGN_COPY)
@@ -127,7 +120,6 @@
     }
     else
     {
-      DC_UnlockDc(dc);
       SetLastWin32Error(ERROR_INVALID_PARAMETER);
       return ERROR;
     }
@@ -158,8 +150,26 @@
   }
 
   retval = CLIPPING_UpdateGCRegion(dc);
+  return retval;
+}
+
+
+int STDCALL NtGdiExtSelectClipRgn(HDC  hDC,
+                          HRGN  hrgn,
+                          int  fnMode)
+{
+  int retval;
+  DC *dc;
+
+  if (!(dc = DC_LockDc(hDC)))
+  {
+  	SetLastWin32Error(ERROR_INVALID_HANDLE);
+  	return ERROR;
+  }
+
+  retval = IntGdiExtSelectClipRgn ( dc, hrgn, fnMode );
+
   DC_UnlockDc(dc);
-
   return retval;
 }
 
@@ -427,13 +437,6 @@
    return Result;
 }
 
-BOOL STDCALL NtGdiSelectClipPath(HDC  hDC,
-                         int  Mode)
-{
-  UNIMPLEMENTED;
-  return FALSE;
-}
-
 INT STDCALL
 NtGdiSelectClipRgn(HDC hDC, HRGN hRgn)
 {

Modified: trunk/reactos/subsys/win32k/objects/path.c
--- trunk/reactos/subsys/win32k/objects/path.c	2005-12-09 17:57:58 UTC (rev 20011)
+++ trunk/reactos/subsys/win32k/objects/path.c	2005-12-09 18:06:19 UTC (rev 20012)
@@ -35,7 +35,7 @@
 BOOL FASTCALL PATH_FlattenPath (GdiPath *pPath);
 VOID FASTCALL PATH_GetPathFromDC (PDC dc, GdiPath **ppPath);
 VOID FASTCALL PATH_NormalizePoint (FLOAT_POINT corners[], const FLOAT_POINT *pPoint, double *pX, double *pY);
-BOOL FASTCALL PATH_PathToRegion(const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn);
+BOOL FASTCALL PATH_PathToRegion (GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn);
 BOOL FASTCALL PATH_ReserveEntries (GdiPath *pPath, INT numEntries);
 VOID FASTCALL PATH_ScaleNormalizedPoint (FLOAT_POINT corners[], double x, double y, POINT *pPoint);
 
@@ -235,27 +235,114 @@
    return FALSE;
 }
 
+BOOL STDCALL NtGdiSelectClipPath(HDC  hDC,
+                         int  Mode)
+{
+ GdiPath *pPath;
+ HRGN  hrgnPath;
+ BOOL  success = FALSE;
+ PDC dc = DC_LockDc ( hDC );
 
+ if( !dc ) return FALSE;
 
+ PATH_GetPathFromDC ( dc, &pPath );
+
+ /* Check that path is closed */
+ if( pPath->state != PATH_Closed )
+   SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+   return FALSE;
+ /* Construct a region from the path */
+ else if( PATH_PathToRegion( pPath, dc->w.polyFillMode, &hrgnPath ) )
+ {
+   success = IntGdiExtSelectClipRgn( dc, hrgnPath, Mode ) != ERROR;
+   NtGdiDeleteObject( hrgnPath );
+
+   /* Empty the path */
+   if( success )
+     PATH_EmptyPath( pPath );
+   /* FIXME: Should this function delete the path even if it failed? */
+ }
+
+ DC_UnlockDc ( dc );
+ return success;
+}
+
 /***********************************************************************
  * Exported functions
  */
 
 
 /* PATH_FillPath
- * unimplemented
  * 
+ * 
  */
 BOOL
 FASTCALL 
 PATH_FillPath( PDC dc, GdiPath *pPath )
 {
+  INT   mapMode, graphicsMode;
+  SIZE  ptViewportExt, ptWindowExt;
+  POINT ptViewportOrg, ptWindowOrg;
+  XFORM xform;
+  HRGN  hrgn;
+
   if( pPath->state != PATH_Closed )
   {
+    SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
     return FALSE;
   }
     
-  UNIMPLEMENTED;
+  if( PATH_PathToRegion( pPath, dc->w.polyFillMode, &hrgn ))
+  {
+    /* Since PaintRgn interprets the region as being in logical coordinates
+     * but the points we store for the path are already in device
+     * coordinates, we have to set the mapping mode to MM_TEXT temporarily.
+     * Using SaveDC to save information about the mapping mode / world
+     * transform would be easier but would require more overhead, especially
+     * now that SaveDC saves the current path.
+     */
+
+    /* Save the information about the old mapping mode */
+    mapMode = NtGdiGetMapMode( dc->hSelf );
+    NtGdiGetViewportExtEx( dc->hSelf, &ptViewportExt );
+    NtGdiGetViewportOrgEx( dc->hSelf, &ptViewportOrg );
+    NtGdiGetWindowExtEx( dc->hSelf, &ptWindowExt );
+    NtGdiGetWindowOrgEx( dc->hSelf, &ptWindowOrg );
+
+    /* Save world transform
+     * NB: The Windows documentation on world transforms would lead one to
+     * believe that this has to be done only in GM_ADVANCED; however, my
+     * tests show that resetting the graphics mode to GM_COMPATIBLE does
+     * not reset the world transform.
+     */
+    NtGdiGetWorldTransform( dc->hSelf, &xform );
+
+    /* Set MM_TEXT */
+    NtGdiSetMapMode( dc->hSelf, MM_TEXT );
+    NtGdiSetViewportOrgEx( dc->hSelf, 0, 0, NULL );
+    NtGdiSetWindowOrgEx( dc->hSelf, 0, 0, NULL );
+    graphicsMode = NtGdiGetGraphicsMode( dc->hSelf );
+    NtGdiSetGraphicsMode( dc->hSelf, GM_ADVANCED );
+    NtGdiModifyWorldTransform( dc->hSelf, &xform, MWT_IDENTITY );
+    NtGdiSetGraphicsMode( dc->hSelf, graphicsMode );
+
+    /* Paint the region */
+    NtGdiPaintRgn( dc->hSelf, hrgn );
+    NtGdiDeleteObject( hrgn );
+    /* Restore the old mapping mode */
+    NtGdiSetMapMode( dc->hSelf, mapMode );
+    NtGdiSetViewportExtEx( dc->hSelf, ptViewportExt.cx, ptViewportExt.cy, NULL );
+    NtGdiSetViewportOrgEx( dc->hSelf, ptViewportOrg.x, ptViewportOrg.y, NULL );
+    NtGdiSetWindowExtEx( dc->hSelf, ptWindowExt.cx, ptWindowExt.cy, NULL );
+    NtGdiSetWindowOrgEx( dc->hSelf, ptWindowOrg.x, ptWindowOrg.y, NULL );
+
+    /* Go to GM_ADVANCED temporarily to restore the world transform */
+    graphicsMode = NtGdiGetGraphicsMode( dc->hSelf );
+    NtGdiSetGraphicsMode( dc->hSelf, GM_ADVANCED );
+    NtGdiSetWorldTransform( dc->hSelf, &xform );
+    NtGdiSetGraphicsMode( dc->hSelf, graphicsMode );
+    return TRUE;
+  }
   return FALSE;
 }
 
@@ -924,15 +1011,11 @@
  * error occurs, SetLastError is called with the appropriate value and
  * FALSE is returned.
  */
-#if 0
-// FIXME - don't reenable this function until you deal with the
-// const pPath being given to PATH_FlattenPath() - which is
-// expecting a non-const*. Since this function isn't being called
-// at the moment, I'm commenting it out until the issue needs to
-// be addressed.
+
+
 BOOL
 FASTCALL
-PATH_PathToRegion ( const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn )
+PATH_PathToRegion ( GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn )
 {
   int    numStrokes, iStroke, i;
   INT  *pNumPointsInStroke;
@@ -990,7 +1073,6 @@
   *pHrgn=hrgn;
   return TRUE;
 }
-#endif
 
 /* PATH_EmptyPath
  *