- Fix recursion when sweeping the DCE list.
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / windc.c
index 6c41145..38ac3b4 100644 (file)
@@ -1,30 +1,10 @@
 /*
- *  ReactOS W32 Subsystem
- *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            subsystems/win32/win32k/ntuser/windc.c
+ * PURPOSE:         Window DC management
+ * COPYRIGHT:       Copyright 2007 ReactOS
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/* $Id$
- *
- * COPYRIGHT:        See COPYING in the top level directory
- * PROJECT:          ReactOS kernel
- * PURPOSE:          Window classes
- * FILE:             subsys/win32k/ntuser/class.c
- * PROGRAMER:        Casper S. Hornstrup (chorns@users.sourceforge.net)
- * REVISION HISTORY:
- *       06-06-2001  CSH  Created
  */
 
 /* INCLUDES ******************************************************************/
 #define NDEBUG
 #include <debug.h>
 
+int FASTCALL CLIPPING_UpdateGCRegion(DC* Dc);
+
 /* GLOBALS *******************************************************************/
 
 /* NOTE - I think we should store this per window station (including gdi objects) */
+/* Answer: No, use the DCE pMonitor to compare with! */
 
-static PDCE FirstDce = NULL;
-static PDC defaultDCstate = NULL;
-//static INT DCECount = 0;
+static LIST_ENTRY LEDce;
+static INT DCECount = 0; // Count of DCE in system.
 
 #define DCX_CACHECOMPAREMASK (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | \
-                              DCX_CACHE | DCX_WINDOW | DCX_PARENTCLIP)
+                              DCX_NORESETATTRS | DCX_LOCKWINDOWUPDATE | \
+                              DCX_LAYEREDWIN | DCX_CACHE | DCX_WINDOW | \
+                              DCX_PARENTCLIP)
 
 /* FUNCTIONS *****************************************************************/
 
+//
+// This should be moved to dc.c or dcutil.c.
+//
 HDC FASTCALL
 DceCreateDisplayDC(VOID)
 {
-    HDC hDC;
-    UNICODE_STRING DriverName;
-    RtlInitUnicodeString(&DriverName, L"DISPLAY");
-    hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
-    return hDC;
-}
-
-VOID FASTCALL
-DceInit(VOID)
-{
-
+  HDC hDC;
+  UNICODE_STRING DriverName;
+  RtlInitUnicodeString(&DriverName, L"DISPLAY");
+  hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
+//
+// If NULL, first time through! Build the default window dc!
+//
+  if (hDC && !defaultDCstate) // Ultra HAX! Dedicated to GvG!
+  { // This is a cheesy way to do this.
+      PDC dc = DC_LockDc ( hDC );
+      defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
+      RtlZeroMemory(defaultDCstate, sizeof(DC));
+      defaultDCstate->pdcattr = &defaultDCstate->dcattr;
+      DC_vCopyState(dc, defaultDCstate, TRUE);
+      DC_UnlockDc( dc );
+      InitializeListHead(&LEDce);
+  }
+  return hDC;
 }
 
 static
 HRGN FASTCALL
 DceGetVisRgn(PWINDOW_OBJECT Window, ULONG Flags, HWND hWndChild, ULONG CFlags)
 {
-   HRGN VisRgn;
+  HRGN VisRgn;
 
-   VisRgn = VIS_ComputeVisibleRegion(Window,
+  VisRgn = VIS_ComputeVisibleRegion( Window,
                                      0 == (Flags & DCX_WINDOW),
                                      0 != (Flags & DCX_CLIPCHILDREN),
                                      0 != (Flags & DCX_CLIPSIBLINGS));
 
-   if (VisRgn == NULL)
-      VisRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
-
-   return VisRgn;
-}
-
-/*
- * NtUserGetWindowDC
- *
- * The NtUserGetWindowDC function retrieves the device context (DC) for the
- * entire window, including title bar, menus, and scroll bars. A window device
- * context permits painting anywhere in a window, because the origin of the
- * device context is the upper-left corner of the window instead of the client
- * area.
- *
- * Status
- *    @implemented
- */
-
-DWORD STDCALL
-NtUserGetWindowDC(HWND hWnd)
-{
-   return (DWORD)NtUserGetDCEx(hWnd, 0, DCX_USESTYLE | DCX_WINDOW);
-}
-
-DWORD FASTCALL
-UserGetWindowDC(PWINDOW_OBJECT Wnd)
-{
-   return (DWORD)UserGetDCEx(Wnd, 0, DCX_USESTYLE | DCX_WINDOW);
-}
+  if (VisRgn == NULL)
+      VisRgn = IntSysCreateRectRgn(0, 0, 0, 0);
 
-HDC STDCALL
-NtUserGetDC(HWND hWnd)
-{
-   return NtUserGetDCEx(hWnd, NULL, NULL == hWnd ? DCX_CACHE | DCX_WINDOW : DCX_USESTYLE);
+  return VisRgn;
 }
 
 PDCE FASTCALL
 DceAllocDCE(PWINDOW_OBJECT Window OPTIONAL, DCE_TYPE Type)
 {
-    PDCE pDce;
+  PDCE pDce;
+  PWND Wnd = NULL;
+
+  if (Window) Wnd = Window->Wnd;
 
-    pDce = ExAllocatePoolWithTag(PagedPool, sizeof(DCE), TAG_PDCE);
-    if(!pDce)
+  pDce = ExAllocatePoolWithTag(PagedPool, sizeof(DCE), TAG_PDCE);
+  if(!pDce)
         return NULL;
 
-    pDce->hDC = DceCreateDisplayDC();
-    if(!pDce->hDC)
-    {
+  pDce->hDC = DceCreateDisplayDC();
+  if (!pDce->hDC)
+  {
       ExFreePoolWithTag(pDce, TAG_PDCE);
       return NULL;
-    }
-//
-// If NULL, first time through! Build the default window dc!
-//
-    if (NULL == defaultDCstate) // Ultra HAX! Dedicated to GvG!
-      { // This is a cheesy way to do this.
-        PDC dc = DC_LockDc ( pDce->hDC );
-        defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
-        RtlZeroMemory(defaultDCstate, sizeof(DC));
-        IntGdiCopyToSaveState(dc, defaultDCstate);
-        DC_UnlockDc( dc );
-    }
-
-    pDce->hwndCurrent = (Window ? Window->hSelf : NULL);
-    pDce->hClipRgn = NULL;
-    pDce->pProcess = NULL;
-
-    KeEnterCriticalRegion();
-    pDce->next = FirstDce;
-    FirstDce = pDce;
-    KeLeaveCriticalRegion();
-
-    if (Type == DCE_WINDOW_DC) //Window DCE have ownership.
-     { // Process should already own it.
-       pDce->pProcess = PsGetCurrentProcess();
-     }
-    else
-    {
-       DPRINT("FREE DCATTR!!!! NOT DCE_WINDOW_DC!!!!! hDC-> %x\n", pDce->hDC);
-       DC_FreeDcAttr(pDce->hDC);         // Free the dcattr!
-       DC_SetOwnership(pDce->hDC, NULL); // This hDC is inaccessible!
-    }
-
-     if (Type != DCE_CACHE_DC)
-     {
-       pDce->DCXFlags = DCX_DCEBUSY;
+  }
+  DCECount++;
+  DPRINT("Alloc DCE's! %d\n",DCECount);
+  pDce->hwndCurrent = (Window ? Window->hSelf : NULL);
+  pDce->pwndOrg  = Wnd;
+  pDce->pwndClip = Wnd;
+  pDce->hrgnClip = NULL;
+  pDce->hrgnClipPublic = NULL;
+  pDce->hrgnSavedVis = NULL;
+  pDce->ppiOwner = NULL;
+
+  InsertTailList(&LEDce, &pDce->List);
+
+  DCU_SetDcUndeletable(pDce->hDC);
+
+  if (Type == DCE_WINDOW_DC || Type == DCE_CLASS_DC) //Window DCE have ownership.
+  {
+     pDce->ptiOwner = GetW32ThreadInfo();
+  }
+  else
+  {
+     DPRINT("FREE DCATTR!!!! NOT DCE_WINDOW_DC!!!!! hDC-> %x\n", pDce->hDC);
+     IntGdiSetDCOwnerEx( pDce->hDC, GDI_OBJ_HMGR_NONE, FALSE);
+     pDce->ptiOwner = NULL;
+  }
 
-        if (Window)
+  if (Type == DCE_CACHE_DC)
+  {
+     pDce->DCXFlags = DCX_CACHE | DCX_DCEEMPTY;
+  }
+  else
+  {
+     pDce->DCXFlags = DCX_DCEBUSY;
+     if (Wnd)
+     {
+        if (Type == DCE_WINDOW_DC)
         {
-           if (Window->Style & WS_CLIPCHILDREN)
-           {
-             pDce->DCXFlags |= DCX_CLIPCHILDREN;
-           }
-           if (Window->Style & WS_CLIPSIBLINGS)
-           {
-             pDce->DCXFlags |= DCX_CLIPSIBLINGS;
-           }
+          if (Wnd->style & WS_CLIPCHILDREN) pDce->DCXFlags |= DCX_CLIPCHILDREN;
+          if (Wnd->style & WS_CLIPSIBLINGS) pDce->DCXFlags |= DCX_CLIPSIBLINGS;
         }
      }
-     else
-     {
-       pDce->DCXFlags = DCX_CACHE | DCX_DCEEMPTY;
-     }
-
-    return(pDce);
+  }
+  return(pDce);
 }
 
-VOID static STDCALL
-DceSetDrawable(PWINDOW_OBJECT Window OPTIONAL, HDC hDC, ULONG Flags,
-               BOOL SetClipOrigin)
+static VOID APIENTRY
+DceSetDrawable( PWINDOW_OBJECT Window OPTIONAL,
+                HDC hDC,
+                ULONG Flags,
+                BOOL SetClipOrigin)
 {
-   DC *dc = DC_LockDc(hDC);
-   if(!dc)
+  PWND Wnd;
+  DC *dc = DC_LockDc(hDC);
+  if(!dc)
       return;
 
-   if (Window == NULL)
-   {
-      dc->w.DCOrgX = 0;
-      dc->w.DCOrgY = 0;
-   }
-   else
-   {
+  if (Window == NULL)
+  {
+      dc->ptlDCOrig.x = 0;
+      dc->ptlDCOrig.y = 0;
+  }
+  else
+  {
+      Wnd = Window->Wnd;
       if (Flags & DCX_WINDOW)
       {
-         dc->w.DCOrgX = Window->WindowRect.left;
-         dc->w.DCOrgY = Window->WindowRect.top;
+         dc->ptlDCOrig.x = Wnd->rcWindow.left;
+         dc->ptlDCOrig.y = Wnd->rcWindow.top;
       }
       else
       {
-         dc->w.DCOrgX = Window->ClientRect.left;
-         dc->w.DCOrgY = Window->ClientRect.top;
+         dc->ptlDCOrig.x = Wnd->rcClient.left;
+         dc->ptlDCOrig.y = Wnd->rcClient.top;
       }
-   }
-   DC_UnlockDc(dc);
+  }
+  DC_UnlockDc(dc);
 }
 
 
@@ -221,12 +179,12 @@ DceDeleteClipRgn(DCE* Dce)
    {
       Dce->DCXFlags &= ~DCX_KEEPCLIPRGN;
    }
-   else if (Dce->hClipRgn != NULL)
+   else if (Dce->hrgnClip != NULL)
    {
-      NtGdiDeleteObject(Dce->hClipRgn);
+      REGION_FreeRgnByHandle(Dce->hrgnClip);
    }
 
-   Dce->hClipRgn = NULL;
+   Dce->hrgnClip = NULL;
 
    /* make it dirty so that the vis rgn gets recomputed next time */
    Dce->DCXFlags |= DCX_DCEDIRTY;
@@ -241,7 +199,6 @@ DceReleaseDC(DCE* dce, BOOL EndPaint)
    }
 
    /* restore previous visible region */
-
    if ((dce->DCXFlags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) &&
          ((dce->DCXFlags & DCX_CACHE) || EndPaint))
    {
@@ -250,31 +207,50 @@ DceReleaseDC(DCE* dce, BOOL EndPaint)
 
    if (dce->DCXFlags & DCX_CACHE)
    {
-     if (!(dce->DCXFlags & DCX_NORESETATTRS))
-     {
-       /* make the DC clean so that SetDCState doesn't try to update the vis rgn */
-       IntGdiSetHookFlags(dce->hDC, DCHF_VALIDATEVISRGN);
+      if (!(dce->DCXFlags & DCX_NORESETATTRS))
+      {
+         /* make the DC clean so that SetDCState doesn't try to update the vis rgn */
+         IntGdiSetHookFlags(dce->hDC, DCHF_VALIDATEVISRGN);
 
-       PDC dc = DC_LockDc ( dce->hDC );
-       IntGdiCopyFromSaveState(dc, defaultDCstate, dce->hDC ); // Was SetDCState.
+         // Clean the DC
+         if (!IntGdiCleanDC(dce->hDC)) return 0;
 
-       dce->DCXFlags &= ~DCX_DCEBUSY;
-       if (dce->DCXFlags & DCX_DCEDIRTY)
-       {
-         /* don't keep around invalidated entries
-          * because SetDCState() disables hVisRgn updates
-          * by removing dirty bit. */
-         dce->hwndCurrent = 0;
-         dce->DCXFlags &= DCX_CACHE;
-         dce->DCXFlags |= DCX_DCEEMPTY;
-       }
-     }
-     DPRINT("Exit!!!!! DCX_CACHE!!!!!!   hDC-> %x \n", dce->hDC);
-     DC_FreeDcAttr(dce->hDC);         // Free the dcattr.
-     DC_SetOwnership(dce->hDC, NULL); // Set hDC inaccessible mode.
-     dce->pProcess = NULL;            // Reset ownership.
+         if (dce->DCXFlags & DCX_DCEDIRTY)
+         {
+           /* don't keep around invalidated entries
+            * because SetDCState() disables hVisRgn updates
+            * by removing dirty bit. */
+           dce->hwndCurrent = 0;
+           dce->DCXFlags &= DCX_CACHE;
+           dce->DCXFlags |= DCX_DCEEMPTY;
+         }
+      }
+      dce->DCXFlags &= ~DCX_DCEBUSY;
+      DPRINT("Exit!!!!! DCX_CACHE!!!!!!   hDC-> %x \n", dce->hDC);
+      if (!IntGdiSetDCOwnerEx( dce->hDC, GDI_OBJ_HMGR_NONE, FALSE))
+         return 0;
+      dce->ptiOwner = NULL; // Reset ownership.
+      dce->ppiOwner = NULL;
+
+#if 0 // Need to research and fix before this is a "growing" issue.
+      if (++DCECache > 32)
+      {
+         pLE = LEDce.Flink;
+         pDCE = CONTAINING_RECORD(pLE, DCE, List);
+         do
+         {
+            if (!(pDCE->DCXFlags & DCX_DCEBUSY))
+            {  /* Free the unused cache DCEs. */
+               pDCE = DceFreeDCE(pDCE, TRUE);
+               if (!pDCE) break;
+               continue;
+            }
+         }
+         while (pLE != &LEDce );
+      }
+#endif      
    }
-   return 1;
+   return 1; // Released!
 }
 
 static VOID FASTCALL
@@ -287,15 +263,18 @@ DceUpdateVisRgn(DCE *Dce, PWINDOW_OBJECT Window, ULONG Flags)
    if (Flags & DCX_PARENTCLIP)
    {
       PWINDOW_OBJECT Parent;
+      PWND ParentWnd;
 
-      Parent = Window->Parent;
+      Parent = Window->spwndParent;
       if(!Parent)
       {
          hRgnVisible = NULL;
          goto noparent;
       }
 
-      if (Parent->Style & WS_CLIPSIBLINGS)
+      ParentWnd = Parent->Wnd;
+
+      if (ParentWnd->style & WS_CLIPSIBLINGS)
       {
          DcxFlags = DCX_CLIPSIBLINGS |
                     (Flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW));
@@ -311,7 +290,7 @@ DceUpdateVisRgn(DCE *Dce, PWINDOW_OBJECT Window, ULONG Flags)
       DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
       if (NULL != DesktopWindow)
       {
-         hRgnVisible = UnsafeIntCreateRectRgnIndirect(&DesktopWindow->WindowRect);
+         hRgnVisible = IntSysCreateRectRgnIndirect(&DesktopWindow->Wnd->rcWindow);
       }
       else
       {
@@ -326,27 +305,26 @@ DceUpdateVisRgn(DCE *Dce, PWINDOW_OBJECT Window, ULONG Flags)
 noparent:
    if (Flags & DCX_INTERSECTRGN)
    {
-      if(Dce->hClipRgn != NULL)
+      if(Dce->hrgnClip != NULL)
       {
-         NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_AND);
+         NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hrgnClip, RGN_AND);
       }
       else
       {
          if(hRgnVisible != NULL)
          {
-            NtGdiDeleteObject(hRgnVisible);
+            REGION_FreeRgnByHandle(hRgnVisible);
          }
-         hRgnVisible = NtGdiCreateRectRgn(0, 0, 0, 0);
+         hRgnVisible = IntSysCreateRectRgn(0, 0, 0, 0);
       }
    }
-
-   if (Flags & DCX_EXCLUDERGN && Dce->hClipRgn != NULL)
+   else if (Flags & DCX_EXCLUDERGN && Dce->hrgnClip != NULL)
    {
-      NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_DIFF);
+      NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hrgnClip, RGN_DIFF);
    }
 
    Dce->DCXFlags &= ~DCX_DCEDIRTY;
-   IntGdiSelectVisRgn(Dce->hDC, hRgnVisible);
+   GdiSelectVisRgn(Dce->hDC, hRgnVisible);
 
    if (Window != NULL)
    {
@@ -355,7 +333,7 @@ noparent:
 
    if (hRgnVisible != NULL)
    {
-      NtGdiDeleteObject(hRgnVisible);
+      REGION_FreeRgnByHandle(hRgnVisible);
    }
 }
 
@@ -364,88 +342,135 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
 {
    PWINDOW_OBJECT Parent;
    ULONG DcxFlags;
-   DCE* Dce;
-   BOOL UpdateVisRgn = TRUE;
+   DCE* Dce = NULL;
    BOOL UpdateClipOrigin = FALSE;
+   PWND Wnd = NULL;
+   HDC hDC = NULL;
+   PPROCESSINFO ppi;
+   PLIST_ENTRY pLE;
 
    if (NULL == Window)
    {
       Flags &= ~DCX_USESTYLE;
-   }
-
-   if (NULL == Window || NULL == Window->Dce)
-   {
       Flags |= DCX_CACHE;
    }
+   else
+       Wnd = Window->Wnd;
 
+   if (Flags & (DCX_WINDOW | DCX_PARENTCLIP)) Flags |= DCX_CACHE;
+
+   // When GetDC is called with hWnd nz, DCX_CACHE & _WINDOW are clear w _USESTYLE set.
    if (Flags & DCX_USESTYLE)
    {
       Flags &= ~(DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS | DCX_PARENTCLIP);
-
-      if (Window->Style & WS_CLIPSIBLINGS)
-      {
-         Flags |= DCX_CLIPSIBLINGS;
-      }
-
-      if (!(Flags & DCX_WINDOW))
+      if (!(Flags & DCX_WINDOW)) // not window rectangle
       {
-         if (Window->Class->Style & CS_PARENTDC)
+         if (Wnd->pcls->style & CS_PARENTDC)
          {
             Flags |= DCX_PARENTCLIP;
          }
 
-         if (Window->Style & WS_CLIPCHILDREN &&
-               !(Window->Style & WS_MINIMIZE))
+         if (!(Flags & DCX_CACHE) && // Not on the cheap wine list.
+             !(Wnd->pcls->style & CS_OWNDC) )
+         {
+            if (!(Wnd->pcls->style & CS_CLASSDC))
+            // The window is not POWNED or has any CLASS, so we are looking for cheap wine.
+               Flags |= DCX_CACHE;
+            else
+            {
+               if (Wnd->pcls->pdce) hDC = ((PDCE)Wnd->pcls->pdce)->hDC;
+               DPRINT("We have CLASS!!\n");
+            }
+         }
+/*         else // For Testing!
+         {
+            DPRINT1("We have POWNER!!\n");
+            if (Window->Dce) DPRINT1("We have POWNER with DCE!!\n");
+         }
+*/
+         if (Wnd->style & WS_CLIPSIBLINGS)
+         {
+            Flags |= DCX_CLIPSIBLINGS;
+         }
+
+         if (Wnd->style & WS_CLIPCHILDREN &&
+             !(Wnd->style & WS_MINIMIZE))
          {
             Flags |= DCX_CLIPCHILDREN;
          }
+         /* If minized with icon in the set, we are forced to be cheap! */
+         if (Wnd->style & WS_MINIMIZE &&
+             Wnd->pcls->hIcon)
+         {
+            Flags |= DCX_CACHE;
+         }
       }
       else
       {
+         if (Wnd->style & WS_CLIPSIBLINGS) Flags |= DCX_CLIPSIBLINGS;
          Flags |= DCX_CACHE;
       }
    }
 
+   if (Flags & DCX_WINDOW) Flags &= ~DCX_CLIPCHILDREN;
+
    if (Flags & DCX_NOCLIPCHILDREN)
    {
       Flags |= DCX_CACHE;
       Flags &= ~(DCX_PARENTCLIP | DCX_CLIPCHILDREN);
    }
 
-   if (Flags & DCX_WINDOW)
-   {
-      Flags = (Flags & ~DCX_CLIPCHILDREN) | DCX_CACHE;
-   }
-
-   Parent = (Window ? Window->Parent : NULL);
+   Parent = (Window ? Window->spwndParent : NULL);
 
-   if (NULL == Window || !(Window->Style & WS_CHILD) || NULL == Parent)
+   if (NULL == Window || !(Wnd->style & WS_CHILD) || NULL == Parent)
    {
       Flags &= ~DCX_PARENTCLIP;
+      Flags |= DCX_CLIPSIBLINGS;
    }
-   else if (Flags & DCX_PARENTCLIP)
+
+   /* it seems parent clip is ignored when clipping siblings or children */
+   if (Flags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN)) Flags &= ~DCX_PARENTCLIP;
+
+   if (Flags & DCX_PARENTCLIP)
    {
-      Flags |= DCX_CACHE;
-      if ((Window->Style & WS_VISIBLE) &&
-            (Parent->Style & WS_VISIBLE))
+      if ((Wnd->style & WS_VISIBLE) &&
+          (Parent->Wnd->style & WS_VISIBLE))
       {
          Flags &= ~DCX_CLIPCHILDREN;
-         if (Parent->Style & WS_CLIPSIBLINGS)
+         if (Parent->Wnd->style & WS_CLIPSIBLINGS)
          {
             Flags |= DCX_CLIPSIBLINGS;
          }
       }
    }
 
+   // Window nz, check to see if we still own this or it is just cheap wine tonight.
+   if (!(Flags & DCX_CACHE))
+   {
+      if ( Wnd->head.pti != GetW32ThreadInfo())
+         Flags |= DCX_CACHE; // Ah~ Not Powned! Forced to be cheap~
+   }
+
    DcxFlags = Flags & DCX_CACHECOMPAREMASK;
 
    if (Flags & DCX_CACHE)
-   {
+   { // Scan the cheap wine list for our match.
       DCE* DceEmpty = NULL;
       DCE* DceUnused = NULL;
       KeEnterCriticalRegion();
-      for (Dce = FirstDce; Dce != NULL; Dce = Dce->next)
+      pLE = LEDce.Flink;
+      Dce = CONTAINING_RECORD(pLE, DCE, List);
+      do
       {
+// The reason for this you may ask?
+// Well, it seems ReactOS calls GetDC with out first creating a desktop DC window!
+// Need to test for null here. Not sure if this is a bug or a feature.
+// First time use hax, need to use DceAllocDCE during window display init.
+         if (!Dce) break;
+//
+// The way I understand this, you can have more than one DC per window.
+// Only one Owned if one was requested and saved and one Cached. 
+//
          if ((Dce->DCXFlags & (DCX_CACHE | DCX_DCEBUSY)) == DCX_CACHE)
          {
             DceUnused = Dce;
@@ -456,257 +481,183 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
             else if (Dce->hwndCurrent == (Window ? Window->hSelf : NULL) &&
                      ((Dce->DCXFlags & DCX_CACHECOMPAREMASK) == DcxFlags))
             {
-#if 0 /* FIXME */
-               UpdateVisRgn = FALSE;
-#endif
-
                UpdateClipOrigin = TRUE;
                break;
             }
          }
+         pLE = Dce->List.Flink;
+         Dce = CONTAINING_RECORD(pLE, DCE, List);
       }
+      while (pLE != &LEDce);
       KeLeaveCriticalRegion();
 
-      if (Dce == NULL)
-      {
-         Dce = (DceEmpty == NULL) ? DceUnused : DceEmpty;
-      }
+      Dce = (DceEmpty == NULL) ? DceUnused : DceEmpty;
 
       if (Dce == NULL)
       {
          Dce = DceAllocDCE(NULL, DCE_CACHE_DC);
       }
+      if (!Dce) return NULL;
+
+      Dce->hwndCurrent = (Window ? Window->hSelf : NULL);
    }
-   else
+   else // If we are here, we are POWNED or having CLASS.
    {
-      Dce = Window->Dce;
-      if (NULL != Dce && Dce->hwndCurrent == (Window ? Window->hSelf : NULL))
-      {
-         UpdateVisRgn = FALSE; /* updated automatically, via DCHook() */
+      KeEnterCriticalRegion();
+      pLE = LEDce.Flink;
+      Dce = CONTAINING_RECORD(pLE, DCE, List);
+      do
+      {   // Check for Window handle than HDC match for CLASS.
+          if ((Dce->hwndCurrent == Window->hSelf) ||
+              (Dce->hDC == hDC))
+             break;
+          pLE = Dce->List.Flink;
+          Dce = CONTAINING_RECORD(pLE, DCE, List);
       }
-      else
+      while (pLE != &LEDce);
+      KeLeaveCriticalRegion();
+
+      if ( (Flags & (DCX_INTERSECTRGN|DCX_EXCLUDERGN)) &&
+           (Dce->DCXFlags & (DCX_INTERSECTRGN|DCX_EXCLUDERGN)) )          
       {
-      /* we should free dce->clip_rgn here, but Windows apparently doesn't */
-         Dce->DCXFlags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN);
-         Dce->hClipRgn = NULL;
+          DceDeleteClipRgn(Dce);
       }
-#if 1 /* FIXME */
-      UpdateVisRgn = TRUE;
-#endif
-
    }
-
+// First time use hax, need to use DceAllocDCE during window display init.
    if (NULL == Dce)
    {
       return(NULL);
    }
 
-   Dce->hwndCurrent = (Window ? Window->hSelf : NULL);
-   Dce->DCXFlags = Flags | DCX_DCEBUSY;
-
-   if (0 == (Flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN)) && NULL != ClipRegion)
+   if (!GDIOBJ_ValidateHandle(Dce->hDC, GDI_OBJECT_TYPE_DC))
    {
-      if (Flags & DCX_KEEPCLIPRGN)
-         NtGdiDeleteObject(ClipRegion);
-      ClipRegion = NULL;
+      DPRINT1("FIXME: Got DCE with invalid hDC! 0x%x\n", Dce->hDC);
+      Dce->hDC = DceCreateDisplayDC();
+      /* FIXME: Handle error */
    }
 
-#if 0
-   if (NULL != Dce->hClipRgn)
+   Dce->DCXFlags = Flags | DCX_DCEBUSY;
+
+   /*
+      Bump it up! This prevents the random errors in wine dce tests and with
+      proper bits set in DCX_CACHECOMPAREMASK.
+      Reference:
+        http://www.reactos.org/archives/public/ros-dev/2008-July/010498.html
+        http://www.reactos.org/archives/public/ros-dev/2008-July/010499.html
+    */
+   if (pLE != &LEDce)
    {
-      DceDeleteClipRgn(Dce);
-      Dce->hClipRgn = NULL;
+      RemoveEntryList(&Dce->List);
+      InsertHeadList(&LEDce, &Dce->List);
    }
-#endif
 
-   if (0 != (Flags & DCX_INTERSECTUPDATE) && NULL == ClipRegion)
+   /* Introduced in rev 6691 and modified later. */
+   if ( (Flags & DCX_INTERSECTUPDATE) && !ClipRegion )
    {
       Flags |= DCX_INTERSECTRGN | DCX_KEEPCLIPRGN;
       Dce->DCXFlags |= DCX_INTERSECTRGN | DCX_KEEPCLIPRGN;
-      ClipRegion = Window->UpdateRegion;
+      ClipRegion = Window->hrgnUpdate;
    }
 
    if (ClipRegion == (HRGN) 1)
    {
       if (!(Flags & DCX_WINDOW))
       {
-         Dce->hClipRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect);
+         Dce->hrgnClip = IntSysCreateRectRgnIndirect(&Window->Wnd->rcClient);
       }
       else
       {
-         Dce->hClipRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect);
+         Dce->hrgnClip = IntSysCreateRectRgnIndirect(&Window->Wnd->rcWindow);
       }
+      Dce->DCXFlags &= ~DCX_KEEPCLIPRGN;
    }
    else if (ClipRegion != NULL)
    {
-      Dce->hClipRgn = ClipRegion;
+      Dce->hrgnClip = ClipRegion;
    }
 
    DceSetDrawable(Window, Dce->hDC, Flags, UpdateClipOrigin);
 
-   //  if (UpdateVisRgn)
-   {
-      DceUpdateVisRgn(Dce, Window, Flags);
-   }
+   DceUpdateVisRgn(Dce, Window, Flags);
 
    if (Dce->DCXFlags & DCX_CACHE)
    {
       DPRINT("ENTER!!!!!! DCX_CACHE!!!!!!   hDC-> %x\n", Dce->hDC);
       // Need to set ownership so Sync dcattr will work.
-      DC_SetOwnership( Dce->hDC, PsGetCurrentProcess());
-      DC_AllocateDcAttr( Dce->hDC );         // Allocate new dcattr
-      DCU_SynchDcAttrtoUser( Dce->hDC, -1);  // Copy data from dc to dcattr
-      Dce->pProcess = PsGetCurrentProcess(); // Set the temp owning process
-   }
-   return(Dce->hDC);
-}
-
-
-
-HDC STDCALL
-NtUserGetDCEx(HWND hWnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
-{
-   PWINDOW_OBJECT Wnd=NULL;
-   DECLARE_RETURN(HDC);
-
-   DPRINT("Enter NtUserGetDCEx\n");
-   UserEnterExclusive();
-
-   if (hWnd && !(Wnd = UserGetWindowObject(hWnd)))
-   {
-      RETURN(NULL);
+      IntGdiSetDCOwnerEx( Dce->hDC, GDI_OBJ_HMGR_POWNED, FALSE);
+      Dce->ptiOwner = GetW32ThreadInfo(); // Set the temp owning
    }
 
-   RETURN( UserGetDCEx(Wnd, ClipRegion, Flags));
-
-CLEANUP:
-   DPRINT("Leave NtUserGetDCEx, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
-
-BOOL FASTCALL
-DCE_Cleanup(PDCE pDce)
-{
-   PDCE PrevInList;
-   KeEnterCriticalRegion();
-   if (pDce == FirstDce)
-   {
-      FirstDce = pDce->next;
-      PrevInList = pDce;
-   }
-   else
-   {
-      for (PrevInList = FirstDce; NULL != PrevInList; PrevInList = PrevInList->next)
-      {
-         if (pDce == PrevInList->next)
-         {
-            PrevInList->next = pDce->next;
-            break;
-         }
-      }
-      assert(NULL != PrevInList);
-   }
-   KeLeaveCriticalRegion();
-   return NULL != PrevInList;
-}
-
-HWND FASTCALL
-IntWindowFromDC(HDC hDc)
-{
-   DCE *Dce;
-   HWND Ret = NULL;
-   KeEnterCriticalRegion();
-   for (Dce = FirstDce; Dce != NULL; Dce = Dce->next)
+   if ( Wnd &&
+        Wnd->ExStyle & WS_EX_LAYOUTRTL &&
+       !(Flags & DCX_KEEPLAYOUT) )
    {
-      if(Dce->hDC == hDc)
-      {
-         Ret = Dce->hwndCurrent;
-         break;
-      }
+      NtGdiSetLayout(Dce->hDC, -1, LAYOUT_RTL);
    }
-   KeLeaveCriticalRegion();
-   return Ret;
-}
-
 
-INT FASTCALL
-UserReleaseDC(PWINDOW_OBJECT Window, HDC hDc, BOOL EndPaint)
-{
-   DCE *dce;
-   INT nRet = 0;
-
-   dce = FirstDce;
-
-   DPRINT("%p %p\n", Window, hDc);
-   KeEnterCriticalRegion();
-   while (dce && (dce->hDC != hDc))
-   {
-      dce = dce->next;
-   }
-   KeLeaveCriticalRegion();
-   if (dce && (dce->DCXFlags & DCX_DCEBUSY))
+   if (Dce->DCXFlags & DCX_PROCESSOWNED) 
    {
-      nRet = DceReleaseDC(dce, EndPaint);
+      ppi = PsGetCurrentProcessWin32Process();
+      ppi->W32PF_flags |= W32PF_OWNDCCLEANUP;
+      Dce->ptiOwner = NULL;
+      Dce->ppiOwner = ppi;
    }
 
-   return nRet;
+   return(Dce->hDC);
 }
 
-
 /***********************************************************************
  *           DceFreeDCE
  */
 PDCE FASTCALL
 DceFreeDCE(PDCE pdce, BOOLEAN Force)
-  {
-     DCE *ret;
-
-   if (NULL == pdce)
-     {
-        return NULL;
-     }
-
-   ret = pdce->next;
+{
+  DCE *ret;
+  PLIST_ENTRY pLE;
+  BOOL Hit = FALSE;
 
-  #if 0 /* FIXME */
+  if (NULL == pdce) return NULL;
 
-   SetDCHook(pdce->hDC, NULL, 0L);
-  #endif
+  pLE = pdce->List.Flink;
+  ret = CONTAINING_RECORD(pLE, DCE, List);
 
-   if(Force && !GDIOBJ_OwnedByCurrentProcess(GdiHandleTable, pdce->hDC))
+  if (Force && !GDIOBJ_OwnedByCurrentProcess(pdce->hDC))
+  {
+     DPRINT("Change ownership for DCE! -> %x\n" , pdce);
+     // Note: Windows sets W32PF_OWNDCCLEANUP and moves on.
+     if (!IsObjectDead((HGDIOBJ) pdce->hDC))
      {
-      DPRINT1("Change ownership for DCE!\n");
-      INT Index = GDI_HANDLE_GET_INDEX(pdce->hDC);
-      PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
-
-      // Must take control of handles that are not in the process of going away.
-      if ((Entry->Type & ~GDI_ENTRY_REUSE_MASK) != 0 && Entry->KernelData != NULL)
-      {
          DC_SetOwnership( pdce->hDC, PsGetCurrentProcess());
-      }
-      else
-      {
-         DPRINT1("Attempted to change ownership of an DCEhDC 0x%x currently being destroyed!!!\n",pdce->hDC);
-      }
      }
-
-   NtGdiDeleteObjectApp(pdce->hDC);
-   if (pdce->hClipRgn && ! (pdce->DCXFlags & DCX_KEEPCLIPRGN))
+     else
      {
-      NtGdiDeleteObject(pdce->hClipRgn);
+         DPRINT1("Attempted to change ownership of an DCEhDC 0x%x currently being destroyed!!!\n",pdce->hDC);
+         Hit = TRUE;
      }
+  }
 
-   DCE_Cleanup(pdce);
-   ExFreePoolWithTag(pdce, TAG_PDCE);
+  if (!Hit) IntGdiDeleteDC(pdce->hDC, TRUE);
 
-   if (FirstDce == NULL)
-   {
-     ExFreePoolWithTag(defaultDCstate, TAG_DC);
-     defaultDCstate = NULL;
-   }
-     return ret;
+  if (pdce->hrgnClip && ! (pdce->DCXFlags & DCX_KEEPCLIPRGN))
+  {
+      REGION_FreeRgnByHandle(pdce->hrgnClip);
+      pdce->hrgnClip = NULL;
+  }
+
+  RemoveEntryList(&pdce->List);
+
+  if (IsListEmpty(&pdce->List))
+  {
+      DPRINT1("List is Empty! DCE! -> %x\n" , pdce);
+      return NULL;
+  }
+
+  ExFreePoolWithTag(pdce, TAG_PDCE);
+
+  DCECount--;
+  DPRINT("Freed DCE's! %d \n", DCECount);
+
+  return ret;
 }
 
 /***********************************************************************
@@ -717,60 +668,140 @@ DceFreeDCE(PDCE pdce, BOOLEAN Force)
 void FASTCALL
 DceFreeWindowDCE(PWINDOW_OBJECT Window)
 {
-   DCE *pDCE;
+  PDCE pDCE;
+  PLIST_ENTRY pLE;
+
+  if (DCECount <= 0)
+  {
+     DPRINT1("No Entry!\n");
+     return;
+  }
+
+  pLE = LEDce.Flink;
+  pDCE = CONTAINING_RECORD(pLE, DCE, List);
+  do
+  {
+     if (!pDCE) break;
+     if (IsListEmpty(&pDCE->List)) break;
+     if ( pDCE->hwndCurrent == Window->hSelf &&
+          !(pDCE->DCXFlags & DCX_DCEEMPTY) )
+     {
+        if (!(pDCE->DCXFlags & DCX_CACHE)) /* owned or Class DCE*/
+        {
+           if (Window->Wnd->pcls->style & CS_CLASSDC) /* Test Class first */
+           {
+              if (pDCE->DCXFlags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) /* Class DCE*/
+                 DceDeleteClipRgn(pDCE);
+              // Update and reset Vis Rgn and clear the dirty bit.
+              // Should release VisRgn than reset it to default.
+              DceUpdateVisRgn(pDCE, Window, pDCE->DCXFlags);
+              pDCE->DCXFlags = DCX_DCEEMPTY|DCX_CACHE;
+              pDCE->hwndCurrent = 0;
+
+              DPRINT("POWNED DCE going Cheap!! DCX_CACHE!! hDC-> %x \n", pDCE->hDC);
+              if (!IntGdiSetDCOwnerEx( pDCE->hDC, GDI_OBJ_HMGR_NONE, FALSE))
+                  return;
+              /* Do not change owner so thread can clean up! */
+           }
+           else if (Window->Wnd->pcls->style & CS_OWNDC) /* owned DCE*/
+           {
+              pDCE = DceFreeDCE(pDCE, FALSE);
+              if (!pDCE) break;
+              continue;
+           }
+           else
+           {
+              ASSERT(FALSE);
+           }
+        }
+        else
+        {
+           if (pDCE->DCXFlags & DCX_DCEBUSY) /* shared cache DCE */
+           {
+              /* FIXME: AFAICS we are doing the right thing here so
+               * this should be a DPRINT. But this is best left as an ERR
+               * because the 'application error' is likely to come from
+               * another part of Wine (i.e. it's our fault after all).
+               * We should change this to DPRINT when ReactOS is more stable
+               * (for 1.0?).
+               */
+              DPRINT1("[%p] GetDC() without ReleaseDC()!\n", Window->hSelf);
+              DceReleaseDC(pDCE, FALSE);
+           }
+           pDCE->DCXFlags |= DCX_DCEEMPTY;
+           pDCE->hwndCurrent = 0;
+        }
+     }
+     pLE = pDCE->List.Flink;
+     pDCE = CONTAINING_RECORD(pLE, DCE, List);
+  }
+  while (pLE != &LEDce);
+}
 
-   pDCE = FirstDce;
-   KeEnterCriticalRegion();
-   while (pDCE)
+void FASTCALL
+DceFreeClassDCE(HDC hDC)
+{
+   PDCE pDCE;
+   PLIST_ENTRY pLE;
+   pLE = LEDce.Flink;
+   pDCE = CONTAINING_RECORD(pLE, DCE, List);
+
+   do
    {
-      if (pDCE->hwndCurrent == Window->hSelf)
-      {
-         if (pDCE == Window->Dce) /* owned or Class DCE*/
-         {
-            if (Window->Class->Style & CS_OWNDC) /* owned DCE*/
-            {
-               pDCE = DceFreeDCE(pDCE, FALSE);
-               Window->Dce = NULL;
-               continue;
-            }
-            else if (pDCE->DCXFlags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) /* Class DCE*/
-            {
-               DceDeleteClipRgn(pDCE);
-               pDCE->hwndCurrent = 0;
-            }
-         }
-         else
-         {
-            if (pDCE->DCXFlags & DCX_DCEBUSY) /* shared cache DCE */
-            {
-               /* FIXME: AFAICS we are doing the right thing here so
-                * this should be a DPRINT. But this is best left as an ERR
-                * because the 'application error' is likely to come from
-                * another part of Wine (i.e. it's our fault after all).
-                * We should change this to DPRINT when ReactOS is more stable
-                * (for 1.0?).
-                */
-               DPRINT1("[%p] GetDC() without ReleaseDC()!\n", Window->hSelf);
-               DceReleaseDC(pDCE, FALSE);
-            }
+       if(!pDCE) break;
+       if (pDCE->hDC == hDC)
+       {
+          pDCE = DceFreeDCE(pDCE, TRUE); // Might have gone cheap!
+          if (!pDCE) break;
+          continue;
+       }
+       pLE = pDCE->List.Flink;
+       pDCE = CONTAINING_RECORD(pLE, DCE, List);
+   }
+   while (pLE != &LEDce);
+}
 
-            pDCE->DCXFlags &= DCX_CACHE;
-            pDCE->DCXFlags |= DCX_DCEEMPTY;
-            pDCE->hwndCurrent = 0;
-         }
-      }
-      pDCE = pDCE->next;
+void FASTCALL
+DceFreeThreadDCE(PTHREADINFO pti)
+{
+   PDCE pDCE;
+   PLIST_ENTRY pLE;
+   pLE = LEDce.Flink;
+   pDCE = CONTAINING_RECORD(pLE, DCE, List);
+
+   do
+   {
+       if(!pDCE) break;
+       if (pDCE->ptiOwner == pti)
+       {
+          if (pDCE->DCXFlags & DCX_CACHE)
+          {
+             pDCE = DceFreeDCE(pDCE, TRUE);
+             if (!pDCE) break;
+             continue;
+          }
+       }
+       pLE = pDCE->List.Flink;
+       pDCE = CONTAINING_RECORD(pLE, DCE, List);
    }
-   KeLeaveCriticalRegion();
+   while (pLE != &LEDce);
 }
 
 VOID FASTCALL
-DceEmptyCache()
+DceEmptyCache(VOID)
 {
-   while (FirstDce != NULL)
+   PDCE pDCE;
+   PLIST_ENTRY pLE;
+   pLE = LEDce.Flink;
+   pDCE = CONTAINING_RECORD(pLE, DCE, List);
+
+   do
    {
-      FirstDce = DceFreeDCE(FirstDce, TRUE);
+      if(!pDCE) break;
+      pDCE = DceFreeDCE(pDCE, TRUE);
+      if(!pDCE) break;
    }
+   while (pLE != &LEDce);
 }
 
 VOID FASTCALL
@@ -781,14 +812,19 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window)
    PWINDOW_OBJECT CurrentWindow;
    INT DeltaX;
    INT DeltaY;
+   PLIST_ENTRY pLE;
 
    if (NULL == Window)
    {
       return;
    }
-   pDCE = FirstDce;
-   while (pDCE)
+   pLE = LEDce.Flink;
+   pDCE = CONTAINING_RECORD(pLE, DCE, List);
+   if(!pDCE) return; // Another null test!
+   do
    {
+      if(!pDCE) break;
+      if(pLE == &LEDce) break;
       if (0 == (pDCE->DCXFlags & DCX_DCEEMPTY))
       {
          if (Window->hSelf == pDCE->hwndCurrent)
@@ -800,46 +836,43 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window)
             CurrentWindow = UserGetWindowObject(pDCE->hwndCurrent);
             if (NULL == CurrentWindow)
             {
-               pDCE = pDCE->next;
+               pLE = pDCE->List.Flink;
+               pDCE = CONTAINING_RECORD(pLE, DCE, List);
                continue;
             }
          }
 
-         dc = DC_LockDc(pDCE->hDC);
-         if (dc == NULL)
+         if (!GDIOBJ_ValidateHandle(pDCE->hDC, GDI_OBJECT_TYPE_DC) ||
+             (dc = DC_LockDc(pDCE->hDC)) == NULL)
          {
-//            if (Window->hSelf != pDCE->hwndCurrent)
-//            {
-//               UserDerefObject(CurrentWindow);
-//            }
-            pDCE = pDCE->next;
+            pLE = pDCE->List.Flink;
+            pDCE = CONTAINING_RECORD(pLE, DCE, List);
             continue;
          }
          if (Window == CurrentWindow || IntIsChildWindow(Window, CurrentWindow))
          {
             if (pDCE->DCXFlags & DCX_WINDOW)
             {
-               DeltaX = CurrentWindow->WindowRect.left - dc->w.DCOrgX;
-               DeltaY = CurrentWindow->WindowRect.top - dc->w.DCOrgY;
-               dc->w.DCOrgX = CurrentWindow->WindowRect.left;
-               dc->w.DCOrgY = CurrentWindow->WindowRect.top;
+               DeltaX = CurrentWindow->Wnd->rcWindow.left - dc->ptlDCOrig.x;
+               DeltaY = CurrentWindow->Wnd->rcWindow.top - dc->ptlDCOrig.y;
+               dc->ptlDCOrig.x = CurrentWindow->Wnd->rcWindow.left;
+               dc->ptlDCOrig.y = CurrentWindow->Wnd->rcWindow.top;
             }
             else
             {
-               DeltaX = CurrentWindow->ClientRect.left - dc->w.DCOrgX;
-               DeltaY = CurrentWindow->ClientRect.top - dc->w.DCOrgY;
-               dc->w.DCOrgX = CurrentWindow->ClientRect.left;
-               dc->w.DCOrgY = CurrentWindow->ClientRect.top;
+               DeltaX = CurrentWindow->Wnd->rcClient.left - dc->ptlDCOrig.x;
+               DeltaY = CurrentWindow->Wnd->rcClient.top - dc->ptlDCOrig.y;
+               dc->ptlDCOrig.x = CurrentWindow->Wnd->rcClient.left;
+               dc->ptlDCOrig.y = CurrentWindow->Wnd->rcClient.top;
             }
-            if (NULL != dc->w.hClipRgn)
+            if (NULL != dc->rosdc.hClipRgn)
             {
-               int FASTCALL CLIPPING_UpdateGCRegion(DC* Dc);
-               NtGdiOffsetRgn(dc->w.hClipRgn, DeltaX, DeltaY);
+               NtGdiOffsetRgn(dc->rosdc.hClipRgn, DeltaX, DeltaY);
                CLIPPING_UpdateGCRegion(dc);
             }
-            if (NULL != pDCE->hClipRgn)
+            if (NULL != pDCE->hrgnClip)
             {
-               NtGdiOffsetRgn(pDCE->hClipRgn, DeltaX, DeltaY);
+               NtGdiOffsetRgn(pDCE->hrgnClip, DeltaX, DeltaY);
             }
          }
          DC_UnlockDc(dc);
@@ -848,183 +881,143 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window)
 
          if (Window->hSelf != pDCE->hwndCurrent)
          {
-            //              IntEngWindowChanged(CurrentWindow, WOC_RGN_CLIENT);
+//            IntEngWindowChanged(CurrentWindow, WOC_RGN_CLIENT);
 //            UserDerefObject(CurrentWindow);
          }
       }
-      pDCE = pDCE->next;
+      pLE = pDCE->List.Flink;
+      pDCE = CONTAINING_RECORD(pLE, DCE, List);
    }
+   while (pLE != &LEDce);
 }
 
-
-#define COPY_DEVMODE_VALUE_TO_CALLER(dst, src, member) \
-    Status = MmCopyToCaller(&(dst)->member, &(src)->member, sizeof ((src)->member)); \
-    if (!NT_SUCCESS(Status)) \
-    { \
-      SetLastNtError(Status); \
-      ExFreePool(src); \
-      return FALSE; \
-    }
-
-BOOL
-STDCALL
-NtUserEnumDisplaySettings(
-   PUNICODE_STRING lpszDeviceName,
-   DWORD iModeNum,
-   LPDEVMODEW lpDevMode, /* FIXME is this correct? */
-   DWORD dwFlags )
+HWND FASTCALL
+IntWindowFromDC(HDC hDc)
 {
-   NTSTATUS Status;
-   LPDEVMODEW pSafeDevMode;
-   PUNICODE_STRING pSafeDeviceName = NULL;
-   UNICODE_STRING SafeDeviceName;
-   USHORT Size = 0, ExtraSize = 0;
-
-   /* Copy the devmode */
-   Status = MmCopyFromCaller(&Size, &lpDevMode->dmSize, sizeof (Size));
-   if (!NT_SUCCESS(Status))
-   {
-      SetLastNtError(Status);
-      return FALSE;
-   }
-   Status = MmCopyFromCaller(&ExtraSize, &lpDevMode->dmDriverExtra, sizeof (ExtraSize));
-   if (!NT_SUCCESS(Status))
-   {
-      SetLastNtError(Status);
-      return FALSE;
-   }
-   pSafeDevMode = ExAllocatePool(PagedPool, Size + ExtraSize);
-   if (pSafeDevMode == NULL)
-   {
-      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-      return FALSE;
-   }
-   pSafeDevMode->dmSize = Size;
-   pSafeDevMode->dmDriverExtra = ExtraSize;
+  DCE *Dce;
+  PLIST_ENTRY pLE;
+  HWND Ret = NULL;
 
-   /* Copy the device name */
-   if (lpszDeviceName != NULL)
-   {
-      Status = IntSafeCopyUnicodeString(&SafeDeviceName, lpszDeviceName);
-      if (!NT_SUCCESS(Status))
+  pLE = LEDce.Flink;
+  Dce = CONTAINING_RECORD(pLE, DCE, List);
+  do
+  {
+      if(Dce->hDC == hDc)
       {
-         ExFreePool(pSafeDevMode);
-         SetLastNtError(Status);
-         return FALSE;
+         Ret = Dce->hwndCurrent;
+         break;
       }
-      pSafeDeviceName = &SafeDeviceName;
-   }
+      pLE = Dce->List.Flink;
+      Dce = CONTAINING_RECORD(pLE, DCE, List);
+  }
+  while (pLE != &LEDce);
+  return Ret;
+}
 
-   /* Call internal function */
-   if (!IntEnumDisplaySettings(pSafeDeviceName, iModeNum, pSafeDevMode, dwFlags))
-   {
-      if (pSafeDeviceName != NULL)
-         RtlFreeUnicodeString(pSafeDeviceName);
-      ExFreePool(pSafeDevMode);
-      return FALSE;
-   }
-   if (pSafeDeviceName != NULL)
-      RtlFreeUnicodeString(pSafeDeviceName);
-
-   /* Copy some information back */
-   COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmPelsWidth);
-   COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmPelsHeight);
-   COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmBitsPerPel);
-   COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmDisplayFrequency);
-   COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmDisplayFlags);
-
-   /* output private/extra driver data */
-   if (ExtraSize > 0)
-   {
-      Status = MmCopyToCaller((PCHAR)lpDevMode + Size, (PCHAR)pSafeDevMode + Size, ExtraSize);
-      if (!NT_SUCCESS(Status))
-      {
-         SetLastNtError(Status);
-         ExFreePool(pSafeDevMode);
-         return FALSE;
-      }
-   }
+INT FASTCALL
+UserReleaseDC(PWINDOW_OBJECT Window, HDC hDc, BOOL EndPaint)
+{
+  PDCE dce;
+  PLIST_ENTRY pLE;
+  INT nRet = 0;
+  BOOL Hit = FALSE;
+
+  DPRINT("%p %p\n", Window, hDc);
+  pLE = LEDce.Flink;
+  dce = CONTAINING_RECORD(pLE, DCE, List);
+  do
+  {
+     if(!dce) break;
+     if (dce->hDC == hDc)
+     {
+        Hit = TRUE;
+        break;
+     }
+     pLE = dce->List.Flink;
+     dce = CONTAINING_RECORD(pLE, DCE, List);
+  }
+  while (pLE != &LEDce );
 
-   ExFreePool(pSafeDevMode);
-   return TRUE;
-}
+  if ( Hit && (dce->DCXFlags & DCX_DCEBUSY))
+  {
+     nRet = DceReleaseDC(dce, EndPaint);
+  }
 
-#undef COPY_DEVMODE_VALUE_TO_CALLER
+  return nRet;
+}
 
+HDC FASTCALL
+UserGetWindowDC(PWINDOW_OBJECT Wnd)
+{
+  return UserGetDCEx(Wnd, 0, DCX_USESTYLE | DCX_WINDOW);
+}
 
-LONG
-STDCALL
-NtUserChangeDisplaySettings(
-   PUNICODE_STRING lpszDeviceName,
-   LPDEVMODEW lpDevMode,
-   HWND hwnd,
-   DWORD dwflags,
-   LPVOID lParam)
+HWND FASTCALL
+UserGethWnd( HDC hdc, PWNDOBJ *pwndo)
 {
-   NTSTATUS Status;
-   DEVMODEW DevMode;
-   PUNICODE_STRING pSafeDeviceName = NULL;
-   UNICODE_STRING SafeDeviceName;
-   LONG Ret;
+  PWNDGDI pWndgdi;
+  PWINDOW_OBJECT Wnd;
+  HWND hWnd;
 
-   /* Check arguments */
-#ifdef CDS_VIDEOPARAMETERS
+  hWnd = IntWindowFromDC(hdc);
 
-   if (dwflags != CDS_VIDEOPARAMETERS && lParam != NULL)
-#else
+  if (hWnd && !(Wnd = UserGetWindowObject(hWnd)))
+  {
+     pWndgdi = (WNDGDI *)IntGetProp(Wnd, AtomWndObj);
 
-   if (lParam != NULL)
-#endif
+     if ( pWndgdi && pWndgdi->Hwnd == hWnd )
+     {
+        if (pwndo) *pwndo = (PWNDOBJ)pWndgdi;
+     }
+  }
+  return hWnd;
+}
 
-   {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      return DISP_CHANGE_BADPARAM;
-   }
-   if (hwnd != NULL)
-   {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      return DISP_CHANGE_BADPARAM;
-   }
+HDC APIENTRY
+NtUserGetDCEx(HWND hWnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
+{
+  PWINDOW_OBJECT Wnd=NULL;
+  DECLARE_RETURN(HDC);
 
-   /* Copy devmode */
-   Status = MmCopyFromCaller(&DevMode.dmSize, &lpDevMode->dmSize, sizeof (DevMode.dmSize));
-   if (!NT_SUCCESS(Status))
-   {
-      SetLastNtError(Status);
-      return DISP_CHANGE_BADPARAM;
-   }
-   DevMode.dmSize = min(sizeof (DevMode), DevMode.dmSize);
-   Status = MmCopyFromCaller(&DevMode, lpDevMode, DevMode.dmSize);
-   if (!NT_SUCCESS(Status))
-   {
-      SetLastNtError(Status);
-      return DISP_CHANGE_BADPARAM;
-   }
-   if (DevMode.dmDriverExtra > 0)
-   {
-      DbgPrint("(%s:%i) WIN32K: %s lpDevMode->dmDriverExtra is IGNORED!\n", __FILE__, __LINE__, __FUNCTION__);
-      DevMode.dmDriverExtra = 0;
-   }
+  DPRINT("Enter NtUserGetDCEx\n");
+  UserEnterExclusive();
 
-   /* Copy the device name */
-   if (lpszDeviceName != NULL)
-   {
-      Status = IntSafeCopyUnicodeString(&SafeDeviceName, lpszDeviceName);
-      if (!NT_SUCCESS(Status))
-      {
-         SetLastNtError(Status);
-         return DISP_CHANGE_BADPARAM;
-      }
-      pSafeDeviceName = &SafeDeviceName;
-   }
+  if (hWnd && !(Wnd = UserGetWindowObject(hWnd)))
+  {
+      RETURN(NULL);
+  }
+  RETURN( UserGetDCEx(Wnd, ClipRegion, Flags));
 
-   /* Call internal function */
-   Ret = IntChangeDisplaySettings(pSafeDeviceName, &DevMode, dwflags, lParam);
+CLEANUP:
+  DPRINT("Leave NtUserGetDCEx, ret=%i\n",_ret_);
+  UserLeave();
+  END_CLEANUP;
+}
+
+/*
+ * NtUserGetWindowDC
+ *
+ * The NtUserGetWindowDC function retrieves the device context (DC) for the
+ * entire window, including title bar, menus, and scroll bars. A window device
+ * context permits painting anywhere in a window, because the origin of the
+ * device context is the upper-left corner of the window instead of the client
+ * area.
+ *
+ * Status
+ *    @implemented
+ */
+HDC APIENTRY
+NtUserGetWindowDC(HWND hWnd)
+{
+  return NtUserGetDCEx(hWnd, 0, DCX_USESTYLE | DCX_WINDOW);
+}
 
-   if (pSafeDeviceName != NULL)
-      RtlFreeUnicodeString(pSafeDeviceName);
+HDC APIENTRY
+NtUserGetDC(HWND hWnd)
+{
+ DPRINT("NtUGetDC -> %x:%x\n", hWnd, !hWnd ? DCX_CACHE | DCX_WINDOW : DCX_USESTYLE );
 
-   return Ret;
+  return NtUserGetDCEx(hWnd, NULL, NULL == hWnd ? DCX_CACHE | DCX_WINDOW : DCX_USESTYLE);
 }
 
 /*!
@@ -1038,50 +1031,18 @@ NtUserChangeDisplaySettings(
  *
  * \todo       implement ForceBackground == TRUE
 */
-HPALETTE STDCALL NtUserSelectPalette(HDC  hDC,
-                            HPALETTE  hpal,
-                            BOOL  ForceBackground)
+HPALETTE
+APIENTRY
+NtUserSelectPalette(HDC  hDC,
+              HPALETTE  hpal,
+       BOOL  ForceBackground)
 {
-  PDC dc;
-  HPALETTE oldPal = NULL;
-  PPALGDI PalGDI;
-
-  // FIXME: mark the palette as a [fore\back]ground pal
-  dc = DC_LockDc(hDC);
-  if (NULL != dc)
-    {
-      /* Check if this is a valid palette handle */
-      PalGDI = PALETTE_LockPalette(hpal);
-      if (NULL != PalGDI)
-       {
-          /* Is this a valid palette for this depth? */
-          if ((dc->w.bitsPerPixel <= 8 && PAL_INDEXED == PalGDI->Mode)
-              || (8 < dc->w.bitsPerPixel && PAL_INDEXED != PalGDI->Mode))
-            {
-              PALETTE_UnlockPalette(PalGDI);
-              oldPal = dc->w.hPalette;
-              dc->w.hPalette = hpal;
-            }
-          else if (8 < dc->w.bitsPerPixel && PAL_INDEXED == PalGDI->Mode)
-            {
-              PALETTE_UnlockPalette(PalGDI);
-              oldPal = dc->PalIndexed;
-              dc->PalIndexed = hpal;
-            }
-          else
-            {
-              PALETTE_UnlockPalette(PalGDI);
-              oldPal = NULL;
-            }
-       }
-      else
-       {
-         oldPal = NULL;
-       }
-      DC_UnlockDc(dc);
-    }
-
-  return oldPal;
+    HPALETTE oldPal;
+    UserEnterExclusive();
+    // Implement window checks
+    oldPal = GdiSelectPalette( hDC, hpal, ForceBackground);
+    UserLeave();
+    return oldPal;
 }