[WIN32K]
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / painting.c
index 00465bb..f2e3850 100644 (file)
@@ -2,7 +2,7 @@
  *  COPYRIGHT:        See COPYING in the top level directory
  *  PROJECT:          ReactOS kernel
  *  PURPOSE:          Window painting function
- *  FILE:             subsys/win32k/ntuser/painting.c
+ *  FILE:             subsystems/win32/win32k/ntuser/painting.c
  *  PROGRAMER:        Filip Navara (xnavara@volny.cz)
  *  REVISION HISTORY:
  *       06/06/2001   Created (?)
@@ -11,7 +11,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
  */
 
 BOOL FASTCALL
-IntIntersectWithParents(PWINDOW_OBJECT Child, RECTL *WindowRect)
+IntIntersectWithParents(PWND Child, RECTL *WindowRect)
 {
-   PWINDOW_OBJECT ParentWindow;
    PWND ParentWnd;
 
-   ParentWindow = Child->spwndParent;
-   while (ParentWindow != NULL)
+   ParentWnd = Child->spwndParent;
+   while (ParentWnd != NULL)
    {
-      ParentWnd = ParentWindow->Wnd;
       if (!(ParentWnd->style & WS_VISIBLE) ||
           (ParentWnd->style & WS_MINIMIZE))
       {
@@ -58,34 +56,33 @@ IntIntersectWithParents(PWINDOW_OBJECT Child, RECTL *WindowRect)
 
       /* FIXME: Layered windows. */
 
-      ParentWindow = ParentWindow->spwndParent;
+      ParentWnd = ParentWnd->spwndParent;
    }
 
    return TRUE;
 }
 
 BOOL FASTCALL
-IntValidateParent(PWINDOW_OBJECT Child, HRGN hValidateRgn, BOOL Recurse)
+IntValidateParent(PWND Child, HRGN hValidateRgn, BOOL Recurse)
 {
-   PWINDOW_OBJECT ParentWindow = Child->spwndParent;
-   PWND ParentWnd;
+   PWND ParentWnd = Child->spwndParent;
 
-   while (ParentWindow)
+   while (ParentWnd)
    {
-      ParentWnd = ParentWindow->Wnd;
       if (ParentWnd->style & WS_CLIPCHILDREN)
          break;
 
-      if (ParentWindow->UpdateRegion != 0)
+      if (ParentWnd->hrgnUpdate != 0)
       {
          if (Recurse)
             return FALSE;
 
-         IntInvalidateWindows(ParentWindow, hValidateRgn,
-                              RDW_VALIDATE | RDW_NOCHILDREN);
+         IntInvalidateWindows( ParentWnd,
+                               hValidateRgn,
+                               RDW_VALIDATE | RDW_NOCHILDREN);
       }
 
-      ParentWindow = ParentWindow->spwndParent;
+      ParentWnd = ParentWnd->spwndParent;
    }
 
    return TRUE;
@@ -98,24 +95,21 @@ IntValidateParent(PWINDOW_OBJECT Child, HRGN hValidateRgn, BOOL Recurse)
  */
 
 HRGN FASTCALL
-IntCalcWindowRgn(PWINDOW_OBJECT Window, BOOL Client)
+IntCalcWindowRgn(PWND Wnd, BOOL Client)
 {
-   PWND Wnd;
    HRGN hRgnWindow;
-   UINT RgnType;
 
-   Wnd = Window->Wnd;
    if (Client)
-      hRgnWindow = UnsafeIntCreateRectRgnIndirect(&Wnd->rcClient);
+      hRgnWindow = IntSysCreateRectRgnIndirect(&Wnd->rcClient);
    else
-      hRgnWindow = UnsafeIntCreateRectRgnIndirect(&Wnd->rcWindow);
+      hRgnWindow = IntSysCreateRectRgnIndirect(&Wnd->rcWindow);
 
-   if (Window->WindowRegion != NULL && !(Wnd->style & WS_MINIMIZE))
+   if (Wnd->hrgnClip != NULL && !(Wnd->style & WS_MINIMIZE))
    {
       NtGdiOffsetRgn(hRgnWindow,
          -Wnd->rcWindow.left,
          -Wnd->rcWindow.top);
-      RgnType = NtGdiCombineRgn(hRgnWindow, hRgnWindow, Window->WindowRegion, RGN_AND);
+      NtGdiCombineRgn(hRgnWindow, hRgnWindow, Wnd->hrgnClip, RGN_AND);
       NtGdiOffsetRgn(hRgnWindow,
          Wnd->rcWindow.left,
          Wnd->rcWindow.top);
@@ -140,14 +134,14 @@ IntCalcWindowRgn(PWINDOW_OBJECT Window, BOOL Client)
  */
 
 HRGN FASTCALL
-IntGetNCUpdateRgn(PWINDOW_OBJECT Window, BOOL Validate)
+IntGetNCUpdateRgn(PWND Window, BOOL Validate)
 {
    HRGN hRgnNonClient;
    HRGN hRgnWindow;
    UINT RgnType;
 
-   if (Window->UpdateRegion != NULL &&
-       Window->UpdateRegion != (HRGN)1)
+   if (Window->hrgnUpdate != NULL &&
+       Window->hrgnUpdate != HRGN_WINDOW)
    {
       hRgnNonClient = IntCalcWindowRgn(Window, FALSE);
 
@@ -157,28 +151,28 @@ IntGetNCUpdateRgn(PWINDOW_OBJECT Window, BOOL Validate)
        */
       if (hRgnNonClient == NULL)
       {
-         return (HRGN)1;
+         return HRGN_WINDOW;
       }
 
       hRgnWindow = IntCalcWindowRgn(Window, TRUE);
       if (hRgnWindow == NULL)
       {
-         GreDeleteObject(hRgnNonClient);
-         return (HRGN)1;
+         REGION_FreeRgnByHandle(hRgnNonClient);
+         return HRGN_WINDOW;
       }
 
       RgnType = NtGdiCombineRgn(hRgnNonClient, hRgnNonClient,
                                 hRgnWindow, RGN_DIFF);
       if (RgnType == ERROR)
       {
-         GreDeleteObject(hRgnWindow);
-         GreDeleteObject(hRgnNonClient);
-         return (HRGN)1;
+         REGION_FreeRgnByHandle(hRgnWindow);
+         REGION_FreeRgnByHandle(hRgnNonClient);
+         return HRGN_WINDOW;
       }
       else if (RgnType == NULLREGION)
       {
-         GreDeleteObject(hRgnWindow);
-         GreDeleteObject(hRgnNonClient);
+         REGION_FreeRgnByHandle(hRgnWindow);
+         REGION_FreeRgnByHandle(hRgnNonClient);
          return NULL;
       }
 
@@ -189,24 +183,24 @@ IntGetNCUpdateRgn(PWINDOW_OBJECT Window, BOOL Validate)
 
       if (Validate)
       {
-         if (NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion,
+         if (NtGdiCombineRgn(Window->hrgnUpdate, Window->hrgnUpdate,
                              hRgnWindow, RGN_AND) == NULLREGION)
          {
-            GDIOBJ_SetOwnership(Window->UpdateRegion, PsGetCurrentProcess());
-            GreDeleteObject(Window->UpdateRegion);
-            Window->UpdateRegion = NULL;
-            if (!(Window->state & WINDOWOBJECT_NEED_INTERNALPAINT))
-               MsqDecPaintCountQueue(Window->MessageQueue);
+            IntGdiSetRegionOwner(Window->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
+            REGION_FreeRgnByHandle(Window->hrgnUpdate);
+            Window->hrgnUpdate = NULL;
+            if (!(Window->state & WNDS_INTERNALPAINT))
+               MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
          }
       }
 
-      GreDeleteObject(hRgnWindow);
+      REGION_FreeRgnByHandle(hRgnWindow);
 
       return hRgnNonClient;
    }
    else
    {
-      return Window->UpdateRegion;
+      return Window->hrgnUpdate;
    }
 }
 
@@ -217,58 +211,58 @@ IntGetNCUpdateRgn(PWINDOW_OBJECT Window, BOOL Validate)
  */
 
 VOID FASTCALL
-co_IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags, BOOL Recurse)
+co_IntPaintWindows(PWND Wnd, ULONG Flags, BOOL Recurse)
 {
    HDC hDC;
-   HWND hWnd = Window->hSelf;
+   HWND hWnd = Wnd->head.h;
    HRGN TempRegion;
-   PWND Wnd;
-
-   Wnd = Window->Wnd;
 
    if (Flags & (RDW_ERASENOW | RDW_UPDATENOW))
    {
-      if (Window->UpdateRegion)
+      if (Wnd->hrgnUpdate)
       {
-         if (!IntValidateParent(Window, Window->UpdateRegion, Recurse))
+         if (!IntValidateParent(Wnd, Wnd->hrgnUpdate, Recurse))
             return;
       }
 
       if (Flags & RDW_UPDATENOW)
       {
-         if (Window->UpdateRegion != NULL ||
-             Window->state & WINDOWOBJECT_NEED_INTERNALPAINT)
+         if (Wnd->hrgnUpdate != NULL ||
+             Wnd->state & WNDS_INTERNALPAINT)
          {
             co_IntSendMessage(hWnd, WM_PAINT, 0, 0);
          }
       }
       else
       {
-         if (Window->state & WINDOWOBJECT_NEED_NCPAINT)
+         if (Wnd->state & WNDS_SENDNCPAINT)
          {
-            TempRegion = IntGetNCUpdateRgn(Window, TRUE);
-            Window->state &= ~WINDOWOBJECT_NEED_NCPAINT;
-            MsqDecPaintCountQueue(Window->MessageQueue);
+            TempRegion = IntGetNCUpdateRgn(Wnd, TRUE);
+            Wnd->state &= ~WNDS_SENDNCPAINT;
+            MsqDecPaintCountQueue(Wnd->head.pti->MessageQueue);
             co_IntSendMessage(hWnd, WM_NCPAINT, (WPARAM)TempRegion, 0);
-            if ((HANDLE) 1 != TempRegion && NULL != TempRegion)
+
+            if ( (HANDLE) 1 != TempRegion &&
+                 NULL != TempRegion)
             {
                /* NOTE: The region can already be deleted! */
                GDIOBJ_FreeObjByHandle(TempRegion, GDI_OBJECT_TYPE_REGION | GDI_OBJECT_TYPE_SILENT);
             }
          }
 
-         if (Window->state & WINDOWOBJECT_NEED_ERASEBKGND)
+         if (Wnd->state & WNDS_ERASEBACKGROUND)
          {
-            if (Window->UpdateRegion)
+            if (Wnd->hrgnUpdate)
             {
-               hDC = UserGetDCEx(Window, Window->UpdateRegion,
-                                 DCX_CACHE | DCX_USESTYLE |
-                                 DCX_INTERSECTRGN | DCX_KEEPCLIPRGN);
+               hDC = UserGetDCEx( Wnd,
+                                  Wnd->hrgnUpdate,
+                                  DCX_CACHE|DCX_USESTYLE|DCX_INTERSECTRGN|DCX_KEEPCLIPRGN);
+
                if (co_IntSendMessage(hWnd, WM_ERASEBKGND, (WPARAM)hDC, 0))
                {
-                  Window->state &= ~WINDOWOBJECT_NEED_ERASEBKGND;
+                  Wnd->state &= ~WNDS_ERASEBACKGROUND;
                }
-               UserReleaseDC(Window, hDC, FALSE);
+               UserReleaseDC(Wnd, hDC, FALSE);
             }
          }
       }
@@ -285,24 +279,24 @@ co_IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags, BOOL Recurse)
    /*
     * Paint child windows.
     */
-   if (!(Flags & RDW_NOCHILDREN) && !(Wnd->style & WS_MINIMIZE) &&
-       ((Flags & RDW_ALLCHILDREN) || !(Wnd->style & WS_CLIPCHILDREN)))
+   if (!(Flags & RDW_NOCHILDREN) &&
+       !(Wnd->style & WS_MINIMIZE) &&
+        ((Flags & RDW_ALLCHILDREN) || !(Wnd->style & WS_CLIPCHILDREN)) )
    {
       HWND *List, *phWnd;
 
-      if ((List = IntWinListChildren(Window)))
+      if ((List = IntWinListChildren(Wnd)))
       {
          /* FIXME: Handle WS_EX_TRANSPARENT */
          for (phWnd = List; *phWnd; ++phWnd)
          {
-            Window = UserGetWindowObject(*phWnd);
-            Wnd = Window->Wnd;
-            if (Window && (Wnd->style & WS_VISIBLE))
+            Wnd = UserGetWindowObject(*phWnd);
+            if (Wnd && (Wnd->style & WS_VISIBLE))
             {
                USER_REFERENCE_ENTRY Ref;
-               UserRefObjectCo(Window, &Ref);
-               co_IntPaintWindows(Window, Flags, TRUE);
-               UserDerefObjectCo(Window);
+               UserRefObjectCo(Wnd, &Ref);
+               co_IntPaintWindows(Wnd, Flags, TRUE);
+               UserDerefObjectCo(Wnd);
             }
          }
          ExFreePool(List);
@@ -313,19 +307,17 @@ co_IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags, BOOL Recurse)
 /*
  * IntInvalidateWindows
  *
- * Internal function used by IntRedrawWindow.
+ * Internal function used by IntRedrawWindow, UserRedrawDesktop,
+ * co_WinPosSetWindowPos, IntValidateParent, co_UserRedrawWindow.
  */
-
 VOID FASTCALL
-IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
+IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags)
 {
    INT RgnType;
-   PWND Wnd;
    BOOL HadPaintMessage, HadNCPaintMessage;
    BOOL HasPaintMessage, HasNCPaintMessage;
 
-   Wnd = Window->Wnd;
-
+   DPRINT("IntInvalidateWindows start\n");
    /*
     * If the nonclient is not to be redrawn, clip the region to the client
     * rect
@@ -334,41 +326,41 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
    {
       HRGN hRgnClient;
 
-      hRgnClient = UnsafeIntCreateRectRgnIndirect(&Window->Wnd->rcClient);
+      hRgnClient = IntSysCreateRectRgnIndirect(&Wnd->rcClient);
       RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnClient, RGN_AND);
-      GreDeleteObject(hRgnClient);
+      REGION_FreeRgnByHandle(hRgnClient);
    }
 
    /*
     * Clip the given region with window rectangle (or region)
     */
 
-   if (!Window->WindowRegion || (Wnd->style & WS_MINIMIZE))
+   if (!Wnd->hrgnClip || (Wnd->style & WS_MINIMIZE))
    {
       HRGN hRgnWindow;
 
-      hRgnWindow = UnsafeIntCreateRectRgnIndirect(&Window->Wnd->rcWindow);
+      hRgnWindow = IntSysCreateRectRgnIndirect(&Wnd->rcWindow);
       RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnWindow, RGN_AND);
-      GreDeleteObject(hRgnWindow);
+      REGION_FreeRgnByHandle(hRgnWindow);
    }
    else
    {
-      NtGdiOffsetRgn(hRgn,
-         -Wnd->rcWindow.left,
-         -Wnd->rcWindow.top);
-      RgnType = NtGdiCombineRgn(hRgn, hRgn, Window->WindowRegion, RGN_AND);
-      NtGdiOffsetRgn(hRgn,
-         Wnd->rcWindow.left,
-         Wnd->rcWindow.top);
+      NtGdiOffsetRgn( hRgn,
+                     -Wnd->rcWindow.left,
+                     -Wnd->rcWindow.top);
+      RgnType = NtGdiCombineRgn(hRgn, hRgn, Wnd->hrgnClip, RGN_AND);
+      NtGdiOffsetRgn( hRgn,
+                      Wnd->rcWindow.left,
+                      Wnd->rcWindow.top);
    }
 
    /*
     * Save current state of pending updates
     */
 
-   HadPaintMessage = Window->UpdateRegion != NULL ||
-                     Window->state & WINDOWOBJECT_NEED_INTERNALPAINT;
-   HadNCPaintMessage = Window->state & WINDOWOBJECT_NEED_NCPAINT;
+   HadPaintMessage = Wnd->hrgnUpdate != NULL ||
+                     Wnd->state & WNDS_INTERNALPAINT;
+   HadNCPaintMessage = Wnd->state & WNDS_SENDNCPAINT;
 
    /*
     * Update the region and flags
@@ -376,57 +368,57 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
 
    if (Flags & RDW_INVALIDATE && RgnType != NULLREGION)
    {
-      if (Window->UpdateRegion == NULL)
+      if (Wnd->hrgnUpdate == NULL)
       {
-         Window->UpdateRegion = NtGdiCreateRectRgn(0, 0, 0, 0);
-         GDIOBJ_SetOwnership(Window->UpdateRegion, NULL);
+         Wnd->hrgnUpdate = IntSysCreateRectRgn(0, 0, 0, 0);
+         IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_PUBLIC);
       }
 
-      if (NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion,
+      if (NtGdiCombineRgn(Wnd->hrgnUpdate, Wnd->hrgnUpdate,
                           hRgn, RGN_OR) == NULLREGION)
       {
-         GDIOBJ_SetOwnership(Window->UpdateRegion, PsGetCurrentProcess());
-         GreDeleteObject(Window->UpdateRegion);
-         Window->UpdateRegion = NULL;
+         IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
+         REGION_FreeRgnByHandle(Wnd->hrgnUpdate);
+         Wnd->hrgnUpdate = NULL;
       }
 
       if (Flags & RDW_FRAME)
-         Window->state |= WINDOWOBJECT_NEED_NCPAINT;
+         Wnd->state |= WNDS_SENDNCPAINT;
       if (Flags & RDW_ERASE)
-         Window->state |= WINDOWOBJECT_NEED_ERASEBKGND;
+         Wnd->state |= WNDS_ERASEBACKGROUND;
 
       Flags |= RDW_FRAME;
    }
 
    if (Flags & RDW_VALIDATE && RgnType != NULLREGION)
    {
-      if (Window->UpdateRegion != NULL)
+      if (Wnd->hrgnUpdate != NULL)
       {
-         if (NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion,
+         if (NtGdiCombineRgn(Wnd->hrgnUpdate, Wnd->hrgnUpdate,
                              hRgn, RGN_DIFF) == NULLREGION)
          {
-            GDIOBJ_SetOwnership(Window->UpdateRegion, PsGetCurrentProcess());
-            GreDeleteObject(Window->UpdateRegion);
-            Window->UpdateRegion = NULL;
+            IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
+            REGION_FreeRgnByHandle(Wnd->hrgnUpdate);
+            Wnd->hrgnUpdate = NULL;
          }
       }
 
-      if (Window->UpdateRegion == NULL)
-         Window->state &= ~WINDOWOBJECT_NEED_ERASEBKGND;
+      if (Wnd->hrgnUpdate == NULL)
+         Wnd->state &= ~WNDS_ERASEBACKGROUND;
       if (Flags & RDW_NOFRAME)
-         Window->state &= ~WINDOWOBJECT_NEED_NCPAINT;
+         Wnd->state &= ~WNDS_SENDNCPAINT;
       if (Flags & RDW_NOERASE)
-         Window->state &= ~WINDOWOBJECT_NEED_ERASEBKGND;
+         Wnd->state &= ~WNDS_ERASEBACKGROUND;
    }
 
    if (Flags & RDW_INTERNALPAINT)
    {
-      Window->state |= WINDOWOBJECT_NEED_INTERNALPAINT;
+      Wnd->state |= WNDS_INTERNALPAINT;
    }
 
    if (Flags & RDW_NOINTERNALPAINT)
    {
-      Window->state &= ~WINDOWOBJECT_NEED_INTERNALPAINT;
+      Wnd->state &= ~WNDS_INTERNALPAINT;
    }
 
    /*
@@ -436,19 +428,19 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
    if (!(Flags & RDW_NOCHILDREN) && !(Wnd->style & WS_MINIMIZE) &&
          ((Flags & RDW_ALLCHILDREN) || !(Wnd->style & WS_CLIPCHILDREN)))
    {
-      PWINDOW_OBJECT Child;
+      PWND Child;
 
-      for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
+      for (Child = Wnd->spwndChild; Child; Child = Child->spwndNext)
       {
-         if (Child->Wnd->style & WS_VISIBLE)
+         if (Child->style & WS_VISIBLE)
          {
             /*
-             * Recursive call to update children UpdateRegion
+             * Recursive call to update children hrgnUpdate
              */
-            HRGN hRgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
+            HRGN hRgnTemp = IntSysCreateRectRgn(0, 0, 0, 0);
             NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY);
             IntInvalidateWindows(Child, hRgnTemp, Flags);
-            GreDeleteObject(hRgnTemp);
+            REGION_FreeRgnByHandle(hRgnTemp);
          }
 
       }
@@ -458,26 +450,26 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
     * Fake post paint messages to window message queue if needed
     */
 
-   HasPaintMessage = Window->UpdateRegion != NULL ||
-                     Window->state & WINDOWOBJECT_NEED_INTERNALPAINT;
-   HasNCPaintMessage = Window->state & WINDOWOBJECT_NEED_NCPAINT;
+   HasPaintMessage = Wnd->hrgnUpdate != NULL ||
+                     Wnd->state & WNDS_INTERNALPAINT;
+   HasNCPaintMessage = Wnd->state & WNDS_SENDNCPAINT;
 
    if (HasPaintMessage != HadPaintMessage)
    {
       if (HadPaintMessage)
-         MsqDecPaintCountQueue(Window->MessageQueue);
+         MsqDecPaintCountQueue(Wnd->head.pti->MessageQueue);
       else
-         MsqIncPaintCountQueue(Window->MessageQueue);
+         MsqIncPaintCountQueue(Wnd->head.pti->MessageQueue);
    }
 
    if (HasNCPaintMessage != HadNCPaintMessage)
    {
       if (HadNCPaintMessage)
-         MsqDecPaintCountQueue(Window->MessageQueue);
+         MsqDecPaintCountQueue(Wnd->head.pti->MessageQueue);
       else
-         MsqIncPaintCountQueue(Window->MessageQueue);
+         MsqIncPaintCountQueue(Wnd->head.pti->MessageQueue);
    }
-
+   DPRINT("IntInvalidateWindows exit\n");
 }
 
 /*
@@ -489,16 +481,17 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
  */
 
 BOOL FASTCALL
-IntIsWindowDrawable(PWINDOW_OBJECT Window)
+IntIsWindowDrawable(PWND Wnd)
 {
-   PWINDOW_OBJECT WndObject;
-   PWND Wnd;
+   PWND WndObject;
 
-   for (WndObject = Window; WndObject != NULL; WndObject = WndObject->spwndParent)
+   for (WndObject = Wnd; WndObject != NULL; WndObject = WndObject->spwndParent)
    {
-      Wnd = WndObject->Wnd;
-      if (!(Wnd->style & WS_VISIBLE) ||
-            ((Wnd->style & WS_MINIMIZE) && (WndObject != Window)))
+      if ( WndObject->state2 & WNDS2_INDESTROY ||
+           WndObject->state & WNDS_DESTROYED ||
+           !WndObject ||
+           !(WndObject->style & WS_VISIBLE) ||
+            ((WndObject->style & WS_MINIMIZE) && (WndObject != Wnd)))
       {
          return FALSE;
       }
@@ -510,26 +503,28 @@ IntIsWindowDrawable(PWINDOW_OBJECT Window)
 /*
  * IntRedrawWindow
  *
- * Internal version of NtUserRedrawWindow that takes WINDOW_OBJECT as
+ * Internal version of NtUserRedrawWindow that takes WND as
  * first parameter.
  */
 
 BOOL FASTCALL
-co_UserRedrawWindow(PWINDOW_OBJECT Window, const RECTL* UpdateRect, HRGN UpdateRgn,
-                    ULONG Flags)
+co_UserRedrawWindow(
+   PWND Window,
+   const RECTL* UpdateRect,
+   HRGN UpdateRgn,
+   ULONG Flags)
 {
    HRGN hRgn = NULL;
+   DPRINT("co_UserRedrawWindow start\n");
 
    /*
     * Step 1.
     * Validation of passed parameters.
     */
 
-   if (!IntIsWindowDrawable(Window) ||
-         (Flags & (RDW_VALIDATE | RDW_INVALIDATE)) ==
-         (RDW_VALIDATE | RDW_INVALIDATE))
+   if (!IntIsWindowDrawable(Window))
    {
-      return FALSE;
+      return TRUE; // Just do nothing!!!
    }
 
    /*
@@ -538,37 +533,37 @@ co_UserRedrawWindow(PWINDOW_OBJECT Window, const RECTL* UpdateRect, HRGN UpdateR
     * a region hRgn specified in screen coordinates.
     */
 
-   if (Flags & (RDW_INVALIDATE | RDW_VALIDATE))
+   if (Flags & (RDW_INVALIDATE | RDW_VALIDATE)) // Both are OKAY!
    {
       if (UpdateRgn != NULL)
       {
-         hRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
+         hRgn = IntSysCreateRectRgn(0, 0, 0, 0);
          if (NtGdiCombineRgn(hRgn, UpdateRgn, NULL, RGN_COPY) == NULLREGION)
          {
-            GreDeleteObject(hRgn);
+            REGION_FreeRgnByHandle(hRgn);
             hRgn = NULL;
          }
          else
-            NtGdiOffsetRgn(hRgn, Window->Wnd->rcClient.left, Window->Wnd->rcClient.top);
+            NtGdiOffsetRgn(hRgn, Window->rcClient.left, Window->rcClient.top);
       }
       else if (UpdateRect != NULL)
       {
          if (!RECTL_bIsEmptyRect(UpdateRect))
          {
-            hRgn = UnsafeIntCreateRectRgnIndirect((RECTL *)UpdateRect);
-            NtGdiOffsetRgn(hRgn, Window->Wnd->rcClient.left, Window->Wnd->rcClient.top);
+            hRgn = IntSysCreateRectRgnIndirect((RECTL *)UpdateRect);
+            NtGdiOffsetRgn(hRgn, Window->rcClient.left, Window->rcClient.top);
          }
       }
       else if ((Flags & (RDW_INVALIDATE | RDW_FRAME)) == (RDW_INVALIDATE | RDW_FRAME) ||
                (Flags & (RDW_VALIDATE | RDW_NOFRAME)) == (RDW_VALIDATE | RDW_NOFRAME))
       {
-         if (!RECTL_bIsEmptyRect(&Window->Wnd->rcWindow))
-            hRgn = UnsafeIntCreateRectRgnIndirect(&Window->Wnd->rcWindow);
+         if (!RECTL_bIsEmptyRect(&Window->rcWindow))
+            hRgn = IntSysCreateRectRgnIndirect(&Window->rcWindow);
       }
       else
       {
-         if (!RECTL_bIsEmptyRect(&Window->Wnd->rcClient))
-            hRgn = UnsafeIntCreateRectRgnIndirect(&Window->Wnd->rcClient);
+         if (!RECTL_bIsEmptyRect(&Window->rcClient))
+            hRgn = IntSysCreateRectRgnIndirect(&Window->rcClient);
       }
    }
 
@@ -600,52 +595,49 @@ co_UserRedrawWindow(PWINDOW_OBJECT Window, const RECTL* UpdateRect, HRGN UpdateR
 
    if (hRgn != NULL)
    {
-      GreDeleteObject(hRgn);
+      REGION_FreeRgnByHandle(hRgn);
    }
+   DPRINT("co_UserRedrawWindow exit\n");
 
    return TRUE;
 }
 
 BOOL FASTCALL
-IntIsWindowDirty(PWINDOW_OBJECT Window)
+IntIsWindowDirty(PWND Wnd)
 {
-   PWND Wnd = Window->Wnd;
    return (Wnd->style & WS_VISIBLE) &&
-          ((Window->UpdateRegion != NULL) ||
-           (Window->state & WINDOWOBJECT_NEED_INTERNALPAINT) ||
-           (Window->state & WINDOWOBJECT_NEED_NCPAINT));
+          ((Wnd->hrgnUpdate != NULL) ||
+           (Wnd->state & WNDS_INTERNALPAINT) ||
+           (Wnd->state & WNDS_SENDNCPAINT));
 }
 
 HWND FASTCALL
-IntFindWindowToRepaint(PWINDOW_OBJECT Window, PTHREADINFO Thread)
+IntFindWindowToRepaint(PWND Window, PTHREADINFO Thread)
 {
    HWND hChild;
-   PWINDOW_OBJECT TempWindow;
-   PWND Wnd, TempWnd;
+   PWND TempWindow;
 
    for (; Window != NULL; Window = Window->spwndNext)
    {
-      Wnd = Window->Wnd;
       if (IntWndBelongsToThread(Window, Thread) &&
           IntIsWindowDirty(Window))
       {
          /* Make sure all non-transparent siblings are already drawn. */
-         if (Wnd->ExStyle & WS_EX_TRANSPARENT)
+         if (Window->ExStyle & WS_EX_TRANSPARENT)
          {
             for (TempWindow = Window->spwndNext; TempWindow != NULL;
                  TempWindow = TempWindow->spwndNext)
             {
-               TempWnd = TempWindow->Wnd;
-               if (!(TempWnd->ExStyle & WS_EX_TRANSPARENT) &&
+               if (!(TempWindow->ExStyle & WS_EX_TRANSPARENT) &&
                    IntWndBelongsToThread(TempWindow, Thread) &&
                    IntIsWindowDirty(TempWindow))
                {
-                  return TempWindow->hSelf;
+                  return TempWindow->head.h;
                }
             }
          }
 
-         return Window->hSelf;
+         return Window->head.h;
       }
 
       if (Window->spwndChild)
@@ -660,12 +652,15 @@ IntFindWindowToRepaint(PWINDOW_OBJECT Window, PTHREADINFO Thread)
 }
 
 BOOL FASTCALL
-IntGetPaintMessage(PWINDOW_OBJECT Window, UINT MsgFilterMin, UINT MsgFilterMax,
-                   PTHREADINFO Thread, MSG *Message, BOOL Remove)
+IntGetPaintMessage(
+   PWND Window,
+   UINT MsgFilterMin,
+   UINT MsgFilterMax,
+   PTHREADINFO Thread,
+   MSG *Message,
+   BOOL Remove)
 {
-   PUSER_MESSAGE_QUEUE MessageQueue = (PUSER_MESSAGE_QUEUE)Thread->MessageQueue;
-
-   if (!MessageQueue->PaintCount)
+   if (!Thread->cPaintsReady)
       return FALSE;
 
    if ((MsgFilterMin != 0 || MsgFilterMax != 0) &&
@@ -676,13 +671,13 @@ IntGetPaintMessage(PWINDOW_OBJECT Window, UINT MsgFilterMin, UINT MsgFilterMax,
 
    if (Message->hwnd == NULL)
    {
-      DPRINT1("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found!\n");
+      DPRINT1("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found! Counts %d\n",Thread->cPaintsReady);
       /* Hack to stop spamming the debuglog ! */
-      MessageQueue->PaintCount = 0;
+      Thread->cPaintsReady = 0;
       return FALSE;
    }
 
-   if (Window != NULL && Message->hwnd != Window->hSelf)
+   if (Window != NULL && Message->hwnd != Window->head.h)
       return FALSE;
 
    Message->message = WM_PAINT;
@@ -693,17 +688,22 @@ IntGetPaintMessage(PWINDOW_OBJECT Window, UINT MsgFilterMin, UINT MsgFilterMax,
 
 static
 HWND FASTCALL
-co_IntFixCaret(PWINDOW_OBJECT Window, RECTL *lprc, UINT flags)
+co_IntFixCaret(PWND Window, RECTL *lprc, UINT flags)
 {
    PDESKTOP Desktop;
    PTHRDCARETINFO CaretInfo;
+   PTHREADINFO pti;
+   PUSER_MESSAGE_QUEUE ActiveMessageQueue;
    HWND hWndCaret;
-   PWINDOW_OBJECT WndCaret;
+   PWND WndCaret;
 
    ASSERT_REFS_CO(Window);
 
-   Desktop = ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->Desktop;
-   CaretInfo = ((PUSER_MESSAGE_QUEUE)Desktop->ActiveMessageQueue)->CaretInfo;
+   pti = PsGetCurrentThreadWin32Thread();
+   Desktop = pti->rpdesk;
+   ActiveMessageQueue = Desktop->ActiveMessageQueue;
+   if (!ActiveMessageQueue) return 0;
+   CaretInfo = ActiveMessageQueue->CaretInfo;
    hWndCaret = CaretInfo->hWnd;
 
    WndCaret = UserGetWindowObject(hWndCaret);
@@ -712,15 +712,13 @@ co_IntFixCaret(PWINDOW_OBJECT Window, RECTL *lprc, UINT flags)
    if (WndCaret == Window ||
          ((flags & SW_SCROLLCHILDREN) && IntIsChildWindow(Window, WndCaret)))
    {
-      POINT pt, FromOffset, ToOffset, Offset;
+      POINT pt, FromOffset, ToOffset;
       RECTL rcCaret;
 
       pt.x = CaretInfo->Pos.x;
       pt.y = CaretInfo->Pos.y;
       IntGetClientOrigin(WndCaret, &FromOffset);
       IntGetClientOrigin(Window, &ToOffset);
-      Offset.x = FromOffset.x - ToOffset.x;
-      Offset.y = FromOffset.y - ToOffset.y;
       rcCaret.left = pt.x;
       rcCaret.top = pt.y;
       rcCaret.right = pt.x + CaretInfo->Size.cx;
@@ -737,6 +735,58 @@ co_IntFixCaret(PWINDOW_OBJECT Window, RECTL *lprc, UINT flags)
    return 0;
 }
 
+BOOL
+FASTCALL
+IntPrintWindow(
+    PWND pwnd,
+    HDC hdcBlt,
+    UINT nFlags)
+{
+    HDC hdcSrc;
+    INT cx, cy, xSrc, ySrc;
+
+    if ( nFlags & PW_CLIENTONLY)
+    {
+       cx = pwnd->rcClient.right - pwnd->rcClient.left;
+       cy = pwnd->rcClient.bottom - pwnd->rcClient.top;
+       xSrc = pwnd->rcClient.left - pwnd->rcWindow.left;
+       ySrc = pwnd->rcClient.top - pwnd->rcWindow.top;
+    }
+    else
+    {
+       cx = pwnd->rcWindow.right - pwnd->rcWindow.left;
+       cy = pwnd->rcWindow.bottom - pwnd->rcWindow.top;
+       xSrc = 0;
+       ySrc = 0;
+    }
+
+    // TODO: Setup Redirection for Print.
+    return FALSE;
+
+    /* Update the window just incase. */
+    co_IntPaintWindows( pwnd, RDW_ERASENOW|RDW_UPDATENOW, FALSE);
+
+    hdcSrc = UserGetDCEx( pwnd, NULL, DCX_CACHE|DCX_WINDOW);
+    /* Print window to printer context. */
+    NtGdiBitBlt( hdcBlt,
+                 0,
+                 0,
+                 cx,
+                 cy,
+                 hdcSrc,
+                 xSrc,
+                 ySrc,
+                 SRCCOPY,
+                 0,
+                 0);
+
+    UserReleaseDC( pwnd, hdcSrc, FALSE);
+
+    // TODO: Release Redirection from Print.
+
+    return TRUE;
+}
+
 /* PUBLIC FUNCTIONS ***********************************************************/
 
 /*
@@ -749,12 +799,11 @@ co_IntFixCaret(PWINDOW_OBJECT Window, RECTL *lprc, UINT flags)
 HDC APIENTRY
 NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* UnsafePs)
 {
-   PWINDOW_OBJECT Window = NULL;
+   PWND Window = NULL;
    PAINTSTRUCT Ps;
    NTSTATUS Status;
    DECLARE_RETURN(HDC);
    USER_REFERENCE_ENTRY Ref;
-   PWND Wnd;
 
    DPRINT("Enter NtUserBeginPaint\n");
    UserEnterExclusive();
@@ -766,17 +815,15 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* UnsafePs)
 
    UserRefObjectCo(Window, &Ref);
 
-   Wnd = Window->Wnd;
-
    co_UserHideCaret(Window);
 
-   if (Window->state & WINDOWOBJECT_NEED_NCPAINT)
+   if (Window->state & WNDS_SENDNCPAINT)
    {
       HRGN hRgn;
 
       hRgn = IntGetNCUpdateRgn(Window, FALSE);
-      Window->state &= ~WINDOWOBJECT_NEED_NCPAINT;
-      MsqDecPaintCountQueue(Window->MessageQueue);
+      Window->state &= ~WNDS_SENDNCPAINT;
+      MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
       co_IntSendMessage(hWnd, WM_NCPAINT, (WPARAM)hRgn, 0);
       if (hRgn != (HANDLE)1 && hRgn != NULL)
       {
@@ -787,47 +834,49 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* UnsafePs)
 
    RtlZeroMemory(&Ps, sizeof(PAINTSTRUCT));
 
-   Ps.hdc = UserGetDCEx(Window, Window->UpdateRegion, DCX_INTERSECTRGN | DCX_USESTYLE);
+   Ps.hdc = UserGetDCEx( Window,
+                         Window->hrgnUpdate,
+                         DCX_INTERSECTRGN | DCX_USESTYLE);
    if (!Ps.hdc)
    {
       RETURN(NULL);
    }
 
-   if (Window->UpdateRegion != NULL)
+   if (Window->hrgnUpdate != NULL)
    {
-      MsqDecPaintCountQueue(Window->MessageQueue);
+      MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
       GdiGetClipBox(Ps.hdc, &Ps.rcPaint);
-      GDIOBJ_SetOwnership(Window->UpdateRegion, PsGetCurrentProcess());
+      IntGdiSetRegionOwner(Window->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
       /* The region is part of the dc now and belongs to the process! */
-      Window->UpdateRegion = NULL;
+      Window->hrgnUpdate = NULL;
    }
    else
    {
-      if (Window->state & WINDOWOBJECT_NEED_INTERNALPAINT)
-         MsqDecPaintCountQueue(Window->MessageQueue);
+      if (Window->state & WNDS_INTERNALPAINT)
+         MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
 
       IntGetClientRect(Window, &Ps.rcPaint);
    }
 
-   Window->state &= ~WINDOWOBJECT_NEED_INTERNALPAINT;
+   Window->state &= ~WNDS_INTERNALPAINT;
 
-   if (Window->state & WINDOWOBJECT_NEED_ERASEBKGND)
+   if (Window->state & WNDS_ERASEBACKGROUND)
    {
-      Window->state &= ~WINDOWOBJECT_NEED_ERASEBKGND;
+      Window->state &= ~WNDS_ERASEBACKGROUND;
       Ps.fErase = !co_IntSendMessage(hWnd, WM_ERASEBKGND, (WPARAM)Ps.hdc, 0);
    }
    else
    {
       Ps.fErase = FALSE;
    }
-   if (Window->UpdateRegion)
+   if (Window->hrgnUpdate)
    {
-      if (!(Wnd->style & WS_CLIPCHILDREN))
+      if (!(Window->style & WS_CLIPCHILDREN))
       {
-         PWINDOW_OBJECT Child;
+         PWND Child;
          for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
          {
-            IntInvalidateWindows(Child, Window->UpdateRegion, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
+            IntInvalidateWindows(Child, Window->hrgnUpdate, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
          }
       }
    }
@@ -861,7 +910,7 @@ BOOL APIENTRY
 NtUserEndPaint(HWND hWnd, CONST PAINTSTRUCT* pUnsafePs)
 {
    NTSTATUS Status = STATUS_SUCCESS;
-   PWINDOW_OBJECT Window;
+   PWND Window;
    DECLARE_RETURN(BOOL);
    USER_REFERENCE_ENTRY Ref;
    HDC hdc = NULL;
@@ -905,24 +954,24 @@ CLEANUP:
 
 
 INT FASTCALL
-co_UserGetUpdateRgn(PWINDOW_OBJECT Window, HRGN hRgn, BOOL bErase)
+co_UserGetUpdateRgn(PWND Window, HRGN hRgn, BOOL bErase)
 {
    int RegionType;
    RECTL Rect;
 
    ASSERT_REFS_CO(Window);
 
-   if (Window->UpdateRegion == NULL)
+   if (Window->hrgnUpdate == NULL)
    {
       RegionType = (NtGdiSetRectRgn(hRgn, 0, 0, 0, 0) ? NULLREGION : ERROR);
    }
    else
    {
-      Rect = Window->Wnd->rcClient;
+      Rect = Window->rcClient;
       IntIntersectWithParents(Window, &Rect);
       NtGdiSetRectRgn(hRgn, Rect.left, Rect.top, Rect.right, Rect.bottom);
-      RegionType = NtGdiCombineRgn(hRgn, hRgn, Window->UpdateRegion, RGN_AND);
-      NtGdiOffsetRgn(hRgn, -Window->Wnd->rcClient.left, -Window->Wnd->rcClient.top);
+      RegionType = NtGdiCombineRgn(hRgn, hRgn, Window->hrgnUpdate, RGN_AND);
+      NtGdiOffsetRgn(hRgn, -Window->rcClient.left, -Window->rcClient.top);
    }
 
    if (bErase && RegionType != NULLREGION && RegionType != ERROR)
@@ -944,7 +993,7 @@ INT APIENTRY
 NtUserGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
 {
    DECLARE_RETURN(INT);
-   PWINDOW_OBJECT Window;
+   PWND Window;
    INT ret;
    USER_REFERENCE_ENTRY Ref;
 
@@ -978,7 +1027,7 @@ CLEANUP:
 BOOL APIENTRY
 NtUserGetUpdateRect(HWND hWnd, LPRECT UnsafeRect, BOOL bErase)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
    RECTL Rect;
    INT RegionType;
    PROSRGNDATA RgnData;
@@ -993,33 +1042,33 @@ NtUserGetUpdateRect(HWND hWnd, LPRECT UnsafeRect, BOOL bErase)
       RETURN(FALSE);
    }
 
-   if (Window->UpdateRegion == NULL)
+   if (Window->hrgnUpdate == NULL)
    {
       Rect.left = Rect.top = Rect.right = Rect.bottom = 0;
    }
    else
    {
       /* Get the update region bounding box. */
-      if (Window->UpdateRegion == (HRGN)1)
+      if (Window->hrgnUpdate == HRGN_WINDOW)
       {
-         Rect = Window->Wnd->rcClient;
+         Rect = Window->rcClient;
       }
       else
       {
-         RgnData = RGNOBJAPI_Lock(Window->UpdateRegion, NULL);
+         RgnData = RGNOBJAPI_Lock(Window->hrgnUpdate, NULL);
          ASSERT(RgnData != NULL);
          RegionType = REGION_GetRgnBox(RgnData, &Rect);
          RGNOBJAPI_Unlock(RgnData);
 
          if (RegionType != ERROR && RegionType != NULLREGION)
-            RECTL_bIntersectRect(&Rect, &Rect, &Window->Wnd->rcClient);
+            RECTL_bIntersectRect(&Rect, &Rect, &Window->rcClient);
       }
 
       if (IntIntersectWithParents(Window, &Rect))
       {
          RECTL_vOffsetRect(&Rect,
-                          -Window->Wnd->rcClient.left,
-                          -Window->Wnd->rcClient.top);
+                          -Window->rcClient.left,
+                          -Window->rcClient.top);
       } else
       {
          Rect.left = Rect.top = Rect.right = Rect.bottom = 0;
@@ -1039,7 +1088,7 @@ NtUserGetUpdateRect(HWND hWnd, LPRECT UnsafeRect, BOOL bErase)
       Status = MmCopyToCaller(UnsafeRect, &Rect, sizeof(RECTL));
       if (!NT_SUCCESS(Status))
       {
-         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+         EngSetLastError(ERROR_INVALID_PARAMETER);
          RETURN(FALSE);
       }
    }
@@ -1060,14 +1109,18 @@ CLEANUP:
  */
 
 BOOL APIENTRY
-NtUserRedrawWindow(HWND hWnd, CONST RECT *lprcUpdate, HRGN hrgnUpdate,
-                   UINT flags)
+NtUserRedrawWindow(
+   HWND hWnd,
+   CONST RECT *lprcUpdate,
+   HRGN hrgnUpdate,
+   UINT flags)
 {
    RECTL SafeUpdateRect;
-   NTSTATUS Status;
-   PWINDOW_OBJECT Wnd;
-   DECLARE_RETURN(BOOL);
+   PWND Wnd;
+   BOOL Ret;
    USER_REFERENCE_ENTRY Ref;
+   NTSTATUS Status = STATUS_SUCCESS;
+   DECLARE_RETURN(BOOL);
 
    DPRINT("Enter NtUserRedrawWindow\n");
    UserEnterExclusive();
@@ -1077,33 +1130,44 @@ NtUserRedrawWindow(HWND hWnd, CONST RECT *lprcUpdate, HRGN hrgnUpdate,
       RETURN( FALSE);
    }
 
-   if (lprcUpdate != NULL)
+   if (lprcUpdate)
    {
-      Status = MmCopyFromCaller(&SafeUpdateRect, lprcUpdate,
-                                sizeof(RECTL));
-
+      _SEH2_TRY
+      {
+          ProbeForRead(lprcUpdate, sizeof(RECTL), 1);
+          RtlCopyMemory(&SafeUpdateRect, lprcUpdate, sizeof(RECTL));
+      }
+      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+      {
+         Status = _SEH2_GetExceptionCode();
+      }
+      _SEH2_END
       if (!NT_SUCCESS(Status))
       {
-         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+         EngSetLastError(RtlNtStatusToDosError(Status));
          RETURN( FALSE);
       }
    }
 
+   if ( flags & ~(RDW_ERASE|RDW_FRAME|RDW_INTERNALPAINT|RDW_INVALIDATE|
+                  RDW_NOERASE|RDW_NOFRAME|RDW_NOINTERNALPAINT|RDW_VALIDATE|
+                  RDW_ERASENOW|RDW_UPDATENOW|RDW_ALLCHILDREN|RDW_NOCHILDREN) )
+   {
+      /* RedrawWindow fails only in case that flags are invalid */
+      EngSetLastError(ERROR_INVALID_FLAGS);
+      RETURN( FALSE);
+   }
+
    UserRefObjectCo(Wnd, &Ref);
 
-   Status = co_UserRedrawWindow(Wnd, NULL == lprcUpdate ? NULL : &SafeUpdateRect,
-                                hrgnUpdate, flags);
+   Ret = co_UserRedrawWindow( Wnd,
+                              lprcUpdate ? &SafeUpdateRect : NULL,
+                              hrgnUpdate,
+                              flags);
 
    UserDerefObjectCo(Wnd);
 
-   if (!NT_SUCCESS(Status))
-   {
-      /* IntRedrawWindow fails only in case that flags are invalid */
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      RETURN( FALSE);
-   }
-
-   RETURN( TRUE);
+   RETURN( Ret);
 
 CLEANUP:
    DPRINT("Leave NtUserRedrawWindow, ret=%i\n",_ret_);
@@ -1111,12 +1175,16 @@ CLEANUP:
    END_CLEANUP;
 }
 
-
-
 static
 INT FASTCALL
-UserScrollDC(HDC hDC, INT dx, INT dy, const RECTL *prcScroll,
-             const RECTL *prcClip, HRGN hrgnUpdate, RECTL *prcUpdate)
+UserScrollDC(
+   HDC hDC,
+   INT dx,
+   INT dy,
+   const RECTL *prcScroll,
+   const RECTL *prcClip,
+   HRGN hrgnUpdate,
+   RECTL *prcUpdate)
 {
    PDC pDC;
    RECTL rcScroll, rcClip, rcSrc, rcDst;
@@ -1143,9 +1211,17 @@ UserScrollDC(HDC hDC, INT dx, INT dy, const RECTL *prcScroll,
    RECTL_vOffsetRect(&rcDst, dx, dy);
    RECTL_bIntersectRect(&rcDst, &rcDst, &rcClip);
 
-   if (!NtGdiBitBlt(hDC, rcDst.left, rcDst.top,
-                    rcDst.right - rcDst.left, rcDst.bottom - rcDst.top,
-                    hDC, rcDst.left - dx, rcDst.top - dy, SRCCOPY, 0, 0))
+   if (!NtGdiBitBlt( hDC,
+                     rcDst.left,
+                     rcDst.top,
+                     rcDst.right - rcDst.left,
+                     rcDst.bottom - rcDst.top,
+                     hDC,
+                     rcDst.left - dx,
+                     rcDst.top - dy,
+                     SRCCOPY,
+                     0,
+                     0))
    {
       return ERROR;
    }
@@ -1161,8 +1237,7 @@ UserScrollDC(HDC hDC, INT dx, INT dy, const RECTL *prcScroll,
       {
          return FALSE;
       }
-      hrgnVisible = pDC->rosdc.hVisRgn;  // pDC->w.hGCClipRgn?
-      DC_UnlockDc(pDC);
+      hrgnVisible = ((PROSRGNDATA)pDC->prgnVis)->BaseObject.hHmgr;  // pDC->prgnRao?
 
       /* Begin with the shifted and then clipped scroll rect */
       rcDst = rcScroll;
@@ -1178,11 +1253,11 @@ UserScrollDC(HDC hDC, INT dx, INT dy, const RECTL *prcScroll,
       }
       else
       {
-         hrgnOwn = UnsafeIntCreateRectRgnIndirect(&rcDst);
+         hrgnOwn = IntSysCreateRectRgnIndirect(&rcDst);
       }
 
       /* Add the source rect */
-      hrgnTmp = UnsafeIntCreateRectRgnIndirect(&rcSrc);
+      hrgnTmp = IntSysCreateRectRgnIndirect(&rcSrc);
       NtGdiCombineRgn(hrgnOwn, hrgnOwn, hrgnTmp, RGN_OR);
 
       /* Substract the part of the dest that was visible in source */
@@ -1190,7 +1265,10 @@ UserScrollDC(HDC hDC, INT dx, INT dy, const RECTL *prcScroll,
       NtGdiOffsetRgn(hrgnTmp, dx, dy);
       Result = NtGdiCombineRgn(hrgnOwn, hrgnOwn, hrgnTmp, RGN_DIFF);
 
-      GreDeleteObject(hrgnTmp);
+         /* DO NOT Unlock DC while messing with prgnVis! */
+         DC_UnlockDc(pDC);
+
+      REGION_FreeRgnByHandle(hrgnTmp);
 
       if (prcUpdate)
       {
@@ -1199,7 +1277,7 @@ UserScrollDC(HDC hDC, INT dx, INT dy, const RECTL *prcScroll,
 
       if (!hrgnUpdate)
       {
-         GreDeleteObject(hrgnOwn);
+         REGION_FreeRgnByHandle(hrgnOwn);
       }
    }
    else
@@ -1208,19 +1286,21 @@ UserScrollDC(HDC hDC, INT dx, INT dy, const RECTL *prcScroll,
    return Result;
 }
 
-
-
-
 /*
  * NtUserScrollDC
  *
  * Status
  *    @implemented
  */
-
 BOOL APIENTRY
-NtUserScrollDC(HDC hDC, INT dx, INT dy, const RECT *prcUnsafeScroll,
-               const RECT *prcUnsafeClip, HRGN hrgnUpdate, LPRECT prcUnsafeUpdate)
+NtUserScrollDC(
+   HDC hDC,
+   INT dx,
+   INT dy,
+   const RECT *prcUnsafeScroll,
+   const RECT *prcUnsafeClip,
+   HRGN hrgnUpdate,
+   LPRECT prcUnsafeUpdate)
 {
    DECLARE_RETURN(DWORD);
    RECTL rcScroll, rcClip, rcUpdate;
@@ -1258,10 +1338,13 @@ NtUserScrollDC(HDC hDC, INT dx, INT dy, const RECT *prcUnsafeScroll,
       RETURN(FALSE);
    }
 
-   Result = UserScrollDC(hDC, dx, dy,
-                         prcUnsafeScroll? &rcScroll : 0,
-                         prcUnsafeClip? &rcClip : 0, hrgnUpdate,
-                         prcUnsafeUpdate? &rcUpdate : NULL);
+   Result = UserScrollDC( hDC,
+                          dx,
+                          dy,
+                          prcUnsafeScroll? &rcScroll : 0,
+                          prcUnsafeClip? &rcClip : 0,
+                          hrgnUpdate,
+                          prcUnsafeUpdate? &rcUpdate : NULL);
    if(Result == ERROR)
    {
          /* FIXME: Only if hRgnUpdate is invalid we should SetLastError(ERROR_INVALID_HANDLE) */
@@ -1303,12 +1386,19 @@ CLEANUP:
  */
 
 DWORD APIENTRY
-NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *prcUnsafeScroll,
-                     const RECT *prcUnsafeClip, HRGN hrgnUpdate, LPRECT prcUnsafeUpdate, UINT flags)
+NtUserScrollWindowEx(
+   HWND hWnd,
+   INT dx,
+   INT dy,
+   const RECT *prcUnsafeScroll,
+   const RECT *prcUnsafeClip,
+   HRGN hrgnUpdate,
+   LPRECT prcUnsafeUpdate,
+   UINT flags)
 {
    RECTL rcScroll, rcClip, rcCaret, rcUpdate;
    INT Result;
-   PWINDOW_OBJECT Window = NULL, CaretWnd;
+   PWND Window = NULL, CaretWnd;
    HDC hDC;
    HRGN hrgnOwn = NULL, hrgnTemp;
    HWND hwndCaret;
@@ -1366,7 +1456,7 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *prcUnsafeScroll,
    if (hrgnUpdate)
       hrgnOwn = hrgnUpdate;
    else
-      hrgnOwn = NtGdiCreateRectRgn(0, 0, 0, 0);
+      hrgnOwn = IntSysCreateRectRgn(0, 0, 0, 0);
 
    hDC = UserGetDCEx(Window, 0, DCX_CACHE | DCX_USESTYLE);
    if (!hDC)
@@ -1378,7 +1468,14 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *prcUnsafeScroll,
    rcCaret = rcScroll;
    hwndCaret = co_IntFixCaret(Window, &rcCaret, flags);
 
-   Result = UserScrollDC(hDC, dx, dy, &rcScroll, &rcClip, hrgnOwn, prcUnsafeUpdate? &rcUpdate : NULL);
+   Result = UserScrollDC( hDC,
+                          dx,
+                          dy,
+                         &rcScroll,
+                         &rcClip,
+                          hrgnOwn,
+                          prcUnsafeUpdate? &rcUpdate : NULL);
+
    UserReleaseDC(Window, hDC, FALSE);
 
    /*
@@ -1386,20 +1483,20 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *prcUnsafeScroll,
     * the scroll.
     */
 
-   hrgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
+   hrgnTemp = IntSysCreateRectRgn(0, 0, 0, 0);
    if (co_UserGetUpdateRgn(Window, hrgnTemp, FALSE) != NULLREGION)
    {
-      HRGN hrgnClip = UnsafeIntCreateRectRgnIndirect(&rcClip);
+      HRGN hrgnClip = IntSysCreateRectRgnIndirect(&rcClip);
       NtGdiOffsetRgn(hrgnTemp, dx, dy);
       NtGdiCombineRgn(hrgnTemp, hrgnTemp, hrgnClip, RGN_AND);
       co_UserRedrawWindow(Window, NULL, hrgnTemp, RDW_INVALIDATE | RDW_ERASE);
-      GreDeleteObject(hrgnClip);
+      REGION_FreeRgnByHandle(hrgnClip);
    }
-   GreDeleteObject(hrgnTemp);
+   REGION_FreeRgnByHandle(hrgnTemp);
 
    if (flags & SW_SCROLLCHILDREN)
    {
-      PWINDOW_OBJECT Child;
+      PWND Child;
       RECTL rcChild;
       POINT ClientOrigin;
       USER_REFERENCE_ENTRY WndRef;
@@ -1408,7 +1505,7 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *prcUnsafeScroll,
       IntGetClientOrigin(Window, &ClientOrigin);
       for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
       {
-         rcChild = Child->Wnd->rcWindow;
+         rcChild = Child->rcWindow;
          rcChild.left -= ClientOrigin.x;
          rcChild.top -= ClientOrigin.y;
          rcChild.right -= ClientOrigin.x;
@@ -1468,7 +1565,7 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *prcUnsafeScroll,
 CLEANUP:
    if (hrgnOwn && !hrgnUpdate)
    {
-      GreDeleteObject(hrgnOwn);
+      REGION_FreeRgnByHandle(hrgnOwn);
    }
 
    if (Window)
@@ -1482,7 +1579,7 @@ CLEANUP:
 
 BOOL
 UserDrawSysMenuButton(
-   PWINDOW_OBJECT pWnd,
+   PWND pWnd,
    HDC hDc,
    RECTL *lpRc,
    BOOL Down)
@@ -1494,12 +1591,12 @@ UserDrawSysMenuButton(
 
    /* Get the icon to draw. We don't care about WM_GETICON here. */
 
-   hIcon = pWnd->Wnd->pcls->hIconSm;
+   hIcon = pWnd->pcls->hIconSm;
 
    if(!hIcon)
    {
       DPRINT("Wnd class has no small icon.\n");
-      hIcon = pWnd->Wnd->pcls->hIcon;
+      hIcon = pWnd->pcls->hIcon;
    }
 
    if(!hIcon)
@@ -1522,7 +1619,8 @@ UserDrawSysMenuButton(
 }
 
 BOOL
-UserDrawCaptionText(HDC hDc,
+UserDrawCaptionText(
+   HDC hDc,
    const PUNICODE_STRING Text,
    const RECTL *lpRc,
    UINT uFlags)
@@ -1587,7 +1685,7 @@ UserDrawCaptionText(HDC hDc,
 }
 
 BOOL UserDrawCaption(
-   PWINDOW_OBJECT pWnd,
+   PWND pWnd,
    HDC hDc,
    RECTL *lpRc,
    HFONT hFont,
@@ -1604,13 +1702,9 @@ BOOL UserDrawCaption(
    RECTL r = *lpRc;
    LONG ButtonWidth, IconWidth;
    BOOL HasIcon;
-   PWND Wnd = NULL;
 
    //ASSERT(pWnd != NULL);
 
-   if (pWnd)
-       Wnd = pWnd->Wnd;
-
    RECTL_vMakeWellOrdered(lpRc);
    hMemBmp = NtGdiCreateCompatibleBitmap(hDc,
       lpRc->right - lpRc->left,
@@ -1640,14 +1734,14 @@ BOOL UserDrawCaption(
    VCenter = (lpRc->bottom - lpRc->top) / 2;
    Padding = VCenter - (Height / 2);
 
-   if ((!hIcon) && (Wnd != NULL))
+   if ((!hIcon) && (pWnd != NULL))
    {
-     HasIcon = (uFlags & DC_ICON) && (Wnd->style & WS_SYSMENU)
-        && !(uFlags & DC_SMALLCAP) && !(Wnd->ExStyle & WS_EX_DLGMODALFRAME)
-        && !(Wnd->ExStyle & WS_EX_TOOLWINDOW);
+     HasIcon = (uFlags & DC_ICON) && (pWnd->style & WS_SYSMENU)
+        && !(uFlags & DC_SMALLCAP) && !(pWnd->ExStyle & WS_EX_DLGMODALFRAME)
+        && !(pWnd->ExStyle & WS_EX_TOOLWINDOW);
    }
    else
-     HasIcon = (BOOL) hIcon;
+     HasIcon = (hIcon != 0);
 
    IconWidth = UserGetSystemMetrics(SM_CXSIZE) + Padding;
 
@@ -1717,16 +1811,15 @@ BOOL UserDrawCaption(
          static GRADIENT_RECT gcap = {0, 1};
          TRIVERTEX vert[2];
          COLORREF Colors[2];
-         PDC pMemDc;
 
-                if (Wnd != NULL)
+                if (pWnd != NULL)
                 {
-                        if(Wnd->style & WS_SYSMENU)
+                        if(pWnd->style & WS_SYSMENU)
                         {
                                r.right -= 3 + ButtonWidth;
                                if(!(uFlags & DC_SMALLCAP))
                                {
-                                  if(Wnd->style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
+                                  if(pWnd->style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
                                          r.right -= 2 + 2 * ButtonWidth;
                                   else r.right -= 2;
                                   r.right -= 2;
@@ -1770,20 +1863,12 @@ BOOL UserDrawCaption(
          vert[1].Blue = (WORD)(Colors[1]>>8) & 0xFF00;
          vert[1].Alpha = 0;
 
-         pMemDc = DC_LockDc(hMemDc);
-         if(!pMemDc)
-         {
-            DPRINT1("%s: Can't lock dc!\n", __FUNCTION__);
-            goto cleanup;
-         }
-
-         if(!IntGdiGradientFill(pMemDc, vert, 2, &gcap,
+         if(!GreGradientFill(hMemDc, vert, 2, &gcap,
             1, GRADIENT_FILL_RECT_H))
          {
             DPRINT1("%s: IntGdiGradientFill() failed!\n", __FUNCTION__);
          }
 
-         DC_UnlockDc(pMemDc);
       } //if(uFlags & DC_GRADIENT)
    }
 
@@ -1814,12 +1899,12 @@ BOOL UserDrawCaption(
             ButtonWidth = UserGetSystemMetrics(SM_CXSMSIZE) - 2;
          else ButtonWidth = UserGetSystemMetrics(SM_CXSIZE) - 2;
 
-         if ((Wnd != NULL) && (Wnd->style & WS_SYSMENU))
+         if ((pWnd != NULL) && (pWnd->style & WS_SYSMENU))
          {
             r.right -= 3 + ButtonWidth;
             if(! (uFlags & DC_SMALLCAP))
             {
-               if(Wnd->style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
+               if(pWnd->style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
                   r.right -= 2 + 2 * ButtonWidth;
                else r.right -= 2;
                r.right -= 2;
@@ -1831,7 +1916,13 @@ BOOL UserDrawCaption(
       if (str)
          UserDrawCaptionText(hMemDc, str, &r, uFlags);
       else if (pWnd != NULL)
-         UserDrawCaptionText(hMemDc, &pWnd->Wnd->strName, &r, uFlags);
+      {
+         UNICODE_STRING ustr;
+         ustr.Buffer = pWnd->strName.Buffer;
+         ustr.Length = pWnd->strName.Length;
+         ustr.MaximumLength = pWnd->strName.MaximumLength;
+         UserDrawCaptionText(hMemDc, &ustr, &r, uFlags);
+      }
    }
 
    if(!NtGdiBitBlt(hDc, lpRc->left, lpRc->top,
@@ -1866,7 +1957,7 @@ UserRealizePalette(HDC hdc)
       hWnd = IntWindowFromDC(hdc);
       if (hWnd) // Send broadcast if dc is associated with a window.
       {  // FYI: Thread locked in CallOneParam.
-         co_IntSendMessage((HWND)HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)hWnd, 0);
+         UserSendNotifyMessage((HWND)HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)hWnd, 0);
       }
   }
   return Ret;
@@ -1883,7 +1974,7 @@ NtUserDrawCaptionTemp(
    const PUNICODE_STRING str,
    UINT uFlags)
 {
-   PWINDOW_OBJECT pWnd = NULL;
+   PWND pWnd = NULL;
    UNICODE_STRING SafeStr = {0};
    NTSTATUS Status = STATUS_SUCCESS;
    RECTL SafeRect;
@@ -1967,4 +2058,49 @@ NtUserInvalidateRgn(
     return NtUserRedrawWindow(hWnd, NULL, hRgn, RDW_INVALIDATE | (bErase? RDW_ERASE : 0));
 }
 
+BOOL
+APIENTRY
+NtUserPrintWindow(
+    HWND hwnd,
+    HDC  hdcBlt,
+    UINT nFlags)
+{
+    PWND Window;
+    BOOL Ret = FALSE;
+
+    UserEnterExclusive();
+
+    if (hwnd)
+    {
+       Window = UserGetWindowObject(hwnd);
+       // TODO: Add Desktop and MessageBox check via FNID's.
+       if ( Window )
+       {
+          /* Validate flags and check it as a mask for 0 or 1. */
+          if ( (nFlags & PW_CLIENTONLY) == nFlags)
+             Ret = IntPrintWindow( Window, hdcBlt, nFlags);
+          else
+             EngSetLastError(ERROR_INVALID_PARAMETER);
+       }
+    }
+
+    UserLeave();
+    return Ret;
+}
+
+/* ValidateRect gets redirected to NtUserValidateRect:
+   http://blog.csdn.net/ntdll/archive/2005/10/19/509299.aspx */
+BOOL
+APIENTRY
+NtUserValidateRect(
+    HWND hWnd,
+    const RECT *lpRect)
+{
+    if (hWnd)
+    {
+       return NtUserRedrawWindow(hWnd, lpRect, NULL, RDW_VALIDATE );
+    }
+    return NtUserRedrawWindow(hWnd, lpRect, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ERASENOW|RDW_ALLCHILDREN);
+}
+
 /* EOF */