[Win32k]
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / window.c
index 896a9f9..4445fff 100644 (file)
@@ -93,9 +93,9 @@ PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd)
    Window = UserGetWindowObject(hWnd);
    if (Window)
    {
-      ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 0);
+      ASSERT(Window->head.cLockObj >= 0);
 
-      USER_BODY_TO_HEADER(Window)->RefCount++;
+      Window->head.cLockObj++;
    }
    return Window;
 }
@@ -123,13 +123,13 @@ PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
    }
 
    Window = (PWINDOW_OBJECT)UserGetObject(gHandleTable, hWnd, otWindow);
-   if (!Window || 0 != (Window->Status & WINDOWSTATUS_DESTROYED))
+   if (!Window || 0 != (Window->state & WINDOWSTATUS_DESTROYED))
    {
       SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
       return NULL;
    }
 
-   ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 0);
+   ASSERT(Window->head.cLockObj >= 0);
    return Window;
 }
 
@@ -180,7 +180,7 @@ IntGetParent(PWINDOW_OBJECT Wnd)
    }
    else if (Wnd->Wnd->style & WS_CHILD)
    {
-      return Wnd->Parent;
+      return Wnd->spwndParent;
    }
 
    return NULL;
@@ -220,7 +220,7 @@ IntWinListChildren(PWINDOW_OBJECT Window)
 
    if (!Window) return NULL;
 
-   for (Child = Window->FirstChild; Child; Child = Child->NextSibling)
+   for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
       ++NumChildren;
 
    List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), TAG_WINLIST);
@@ -230,9 +230,9 @@ IntWinListChildren(PWINDOW_OBJECT Window)
       SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
       return NULL;
    }
-   for (Child = Window->FirstChild, Index = 0;
+   for (Child = Window->spwndChild, Index = 0;
          Child != NULL;
-         Child = Child->NextSibling, ++Index)
+         Child = Child->spwndNext, ++Index)
       List[Index] = Child->hSelf;
    List[Index] = NULL;
 
@@ -365,12 +365,12 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
 
    Wnd = Window->Wnd;
 
-   if(Window->Status & WINDOWSTATUS_DESTROYING)
+   if(Window->state & WINDOWSTATUS_DESTROYING)
    {
       DPRINT("Tried to call IntDestroyWindow() twice\n");
       return 0;
    }
-   Window->Status |= WINDOWSTATUS_DESTROYING;
+   Window->state |= WINDOWSTATUS_DESTROYING;
    Wnd->style &= ~WS_VISIBLE;
 
    IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Wnd, OBJID_WINDOW, 0);
@@ -431,20 +431,20 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
    MsqRemoveWindowMessagesFromQueue(Window);
 
    /* from now on no messages can be sent to this window anymore */
-   Window->Status |= WINDOWSTATUS_DESTROYED;
+   Window->state |= WINDOWSTATUS_DESTROYED;
    Wnd->state |= WNDS_DESTROYED;
    Wnd->fnid |= FNID_FREED;
 
    /* don't remove the WINDOWSTATUS_DESTROYING bit */
 
    /* reset shell window handles */
-   if(ThreadData->Desktop)
+   if(ThreadData->rpdesk)
    {
-      if (Window->hSelf == ThreadData->Desktop->WindowStation->ShellWindow)
-         ThreadData->Desktop->WindowStation->ShellWindow = NULL;
+      if (Window->hSelf == ThreadData->rpdesk->rpwinstaParent->ShellWindow)
+         ThreadData->rpdesk->rpwinstaParent->ShellWindow = NULL;
 
-      if (Window->hSelf == ThreadData->Desktop->WindowStation->ShellListView)
-         ThreadData->Desktop->WindowStation->ShellListView = NULL;
+      if (Window->hSelf == ThreadData->rpdesk->rpwinstaParent->ShellListView)
+         ThreadData->rpdesk->rpwinstaParent->ShellListView = NULL;
    }
 
    /* Unregister hot keys */
@@ -494,17 +494,17 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
 
    /* dereference the class */
    IntDereferenceClass(Wnd->pcls,
-                       Window->ti->pDeskInfo,
-                       Window->ti->ppi);
+                       Window->pti->pDeskInfo,
+                       Window->pti->ppi);
    Wnd->pcls = NULL;
 
-   if(Window->WindowRegion)
+   if(Window->hrgnClip)
    {
-      GreDeleteObject(Window->WindowRegion);
+      GreDeleteObject(Window->hrgnClip);
    }
 
    ASSERT(Window->Wnd != NULL);
-   UserFreeWindowInfo(Window->ti, Window);
+   UserFreeWindowInfo(Window->pti, Window);
 
    UserDereferenceObject(Window);
 
@@ -663,6 +663,8 @@ IntSetWindowProc(PWND pWnd,
       if (pWnd->state & WNDS_SERVERSIDEWINDOWPROC)
          pWnd->state &= ~WNDS_SERVERSIDEWINDOWPROC;
 
+      if (!NewWndProc) NewWndProc = pWnd->lpfnWndProc;
+
       if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
       {
          if (Ansi)
@@ -860,7 +862,7 @@ IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
    {
       W32Thread = PsGetCurrentThreadWin32Thread();
 
-      if(!W32Thread->Desktop)
+      if(!W32Thread->rpdesk)
          return NULL;
 
       if(Window->SystemMenu)
@@ -873,10 +875,10 @@ IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
          }
       }
 
-      if(W32Thread->Desktop->WindowStation->SystemMenuTemplate)
+      if(W32Thread->rpdesk->rpwinstaParent->SystemMenuTemplate)
       {
          /* clone system menu */
-         Menu = UserGetMenuObject(W32Thread->Desktop->WindowStation->SystemMenuTemplate);
+         Menu = UserGetMenuObject(W32Thread->rpdesk->rpwinstaParent->SystemMenuTemplate);
          if(!Menu)
             return NULL;
 
@@ -976,7 +978,7 @@ IntIsChildWindow(PWINDOW_OBJECT Parent, PWINDOW_OBJECT BaseWindow)
          break;
       }
 
-      Window = Window->Parent;
+      Window = Window->spwndParent;
    }
 
    return(FALSE);
@@ -1001,7 +1003,7 @@ IntIsWindowVisible(PWINDOW_OBJECT BaseWindow)
          return FALSE;
       }
 
-      Window = Window->Parent;
+      Window = Window->spwndParent;
    }
 
    if(Window && Wnd->style & WS_VISIBLE)
@@ -1012,6 +1014,31 @@ IntIsWindowVisible(PWINDOW_OBJECT BaseWindow)
    return FALSE;
 }
 
+VOID FASTCALL
+IntLinkWnd(
+   PWND Wnd,
+   PWND WndParent,
+   PWND WndPrevSibling) /* set to NULL if top sibling */
+{
+   Wnd->spwndParent = WndParent;
+   if ((Wnd->spwndPrev = WndPrevSibling))
+   {
+      /* link after WndPrevSibling */
+      if ((Wnd->spwndNext = WndPrevSibling->spwndNext))
+         Wnd->spwndNext->spwndPrev = Wnd;
+
+      Wnd->spwndPrev->spwndNext = Wnd;
+   }
+   else
+   {
+      /* link at top */
+      if ((Wnd->spwndNext = WndParent->spwndChild))
+         Wnd->spwndNext->spwndPrev = Wnd;
+      
+      WndParent->spwndChild = Wnd;
+   }
+
+}
 
 /* link the window into siblings and parent. children are kept in place. */
 VOID FASTCALL
@@ -1023,35 +1050,32 @@ IntLinkWindow(
 {
    PWINDOW_OBJECT Parent;
 
-   Wnd->Parent = WndParent;
-   Wnd->Wnd->spwndParent = WndParent ? WndParent->Wnd : NULL;
-   if ((Wnd->PrevSibling = WndPrevSibling))
+   IntLinkWnd(Wnd->Wnd, 
+              WndParent->Wnd, 
+              WndPrevSibling ? WndPrevSibling->Wnd : NULL);
+
+   Wnd->spwndParent = WndParent;
+   if ((Wnd->spwndPrev = WndPrevSibling))
    {
       /* link after WndPrevSibling */
-      if ((Wnd->NextSibling = WndPrevSibling->NextSibling))
-         Wnd->NextSibling->PrevSibling = Wnd;
-      else if ((Parent = Wnd->Parent))
-      {
-         if(Parent->LastChild == WndPrevSibling)
-            Parent->LastChild = Wnd;
-      }
-      Wnd->PrevSibling->NextSibling = Wnd;
+      if ((Wnd->spwndNext = WndPrevSibling->spwndNext))
+         Wnd->spwndNext->spwndPrev = Wnd;
+      Wnd->spwndPrev->spwndNext = Wnd;
    }
    else
    {
       /* link at top */
-      Parent = Wnd->Parent;
-      if ((Wnd->NextSibling = WndParent->FirstChild))
-         Wnd->NextSibling->PrevSibling = Wnd;
+      Parent = Wnd->spwndParent;
+      if ((Wnd->spwndNext = WndParent->spwndChild))
+         Wnd->spwndNext->spwndPrev = Wnd;
       else if (Parent)
       {
-         Parent->LastChild = Wnd;
-         Parent->FirstChild = Wnd;
+         Parent->spwndChild = Wnd;
          return;
       }
       if(Parent)
       {
-         Parent->FirstChild = Wnd;
+         Parent->spwndChild = Wnd;
       }
    }
 
@@ -1126,10 +1150,10 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
 //      return NULL;
 
    /* Window must belong to current process */
-   if (Wnd->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
+   if (Wnd->pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
       return NULL;
 
-   WndOldParent = Wnd->Parent;
+   WndOldParent = Wnd->spwndParent;
 
    if (WndOldParent) UserReferenceObject(WndOldParent); /* caller must deref */
 
@@ -1140,11 +1164,11 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
       if (0 == (Wnd->Wnd->ExStyle & WS_EX_TOPMOST))
       {
          /* Not a TOPMOST window, put after TOPMOSTs of new parent */
-         Sibling = WndNewParent->FirstChild;
+         Sibling = WndNewParent->spwndChild;
          while (NULL != Sibling && 0 != (Sibling->Wnd->ExStyle & WS_EX_TOPMOST))
          {
             InsertAfter = Sibling;
-            Sibling = Sibling->NextSibling;
+            Sibling = Sibling->spwndNext;
          }
       }
       if (NULL == InsertAfter)
@@ -1219,26 +1243,40 @@ IntSetSystemMenu(PWINDOW_OBJECT Window, PMENU_OBJECT Menu)
    return TRUE;
 }
 
+/* unlink the window from siblings and parent. children are kept in place. */
+VOID FASTCALL
+IntUnlinkWnd(PWND Wnd)
+{
+   if (Wnd->spwndNext)
+      Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
+
+   if (Wnd->spwndPrev)
+      Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
+  
+   if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd)
+      Wnd->spwndParent->spwndChild = Wnd->spwndNext;
+
+   Wnd->spwndPrev = Wnd->spwndNext = Wnd->spwndParent = NULL;
+}
+
 
 /* unlink the window from siblings and parent. children are kept in place. */
 VOID FASTCALL
 IntUnlinkWindow(PWINDOW_OBJECT Wnd)
 {
-   PWINDOW_OBJECT WndParent = Wnd->Parent;
+   PWINDOW_OBJECT WndParent = Wnd->spwndParent;
 
-   if (Wnd->NextSibling)
-      Wnd->NextSibling->PrevSibling = Wnd->PrevSibling;
-   else if (WndParent && WndParent->LastChild == Wnd)
-      WndParent->LastChild = Wnd->PrevSibling;
+   IntUnlinkWnd(Wnd->Wnd);
 
-   if (Wnd->PrevSibling)
-      Wnd->PrevSibling->NextSibling = Wnd->NextSibling;
-   else if (WndParent && WndParent->FirstChild == Wnd)
-      WndParent->FirstChild = Wnd->NextSibling;
+   if (Wnd->spwndNext)
+      Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
 
-   Wnd->PrevSibling = Wnd->NextSibling = Wnd->Parent = NULL;
-   if (Wnd->Wnd)
-       Wnd->Wnd->spwndParent = NULL;
+   if (Wnd->spwndPrev)
+      Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
+   else if (WndParent && WndParent->spwndChild == Wnd)
+      WndParent->spwndChild = Wnd->spwndNext;
+
+   Wnd->spwndPrev = Wnd->spwndNext = Wnd->spwndParent = NULL;
 }
 
 BOOL FASTCALL
@@ -1251,7 +1289,7 @@ IntAnyPopup(VOID)
       return FALSE;
    }
 
-   for(Child = Window->FirstChild; Child; Child = Child->NextSibling)
+   for(Child = Window->spwndChild; Child; Child = Child->spwndNext)
    {
       if(Child->hOwner && Child->Wnd->style & WS_VISIBLE)
       {
@@ -1269,7 +1307,7 @@ IntAnyPopup(VOID)
 BOOL FASTCALL
 IntIsWindowInDestroy(PWINDOW_OBJECT Window)
 {
-   return ((Window->Status & WINDOWSTATUS_DESTROYING) == WINDOWSTATUS_DESTROYING);
+   return ((Window->state & WINDOWSTATUS_DESTROYING) == WINDOWSTATUS_DESTROYING);
 }
 
 
@@ -1293,7 +1331,7 @@ IntGetWindowPlacement(PWINDOW_OBJECT Window, WINDOWPLACEMENT *lpwndpl)
    {
       lpwndpl->showCmd = SW_HIDE;
    }
-   else if (0 != (Window->Flags & WINDOWOBJECT_RESTOREMAX) ||
+   else if (0 != (Window->state & WINDOWOBJECT_RESTOREMAX) ||
             0 != (Wnd->style & WS_MAXIMIZE))
    {
       lpwndpl->showCmd = SW_MAXIMIZE;
@@ -1394,7 +1432,7 @@ NtUserBuildHwndList(
       }
 
       if((Parent = UserGetWindowObject(hwndParent)) &&
-         (Window = Parent->FirstChild))
+         (Window = Parent->spwndChild))
       {
          BOOL bGoDown = TRUE;
 
@@ -1422,20 +1460,20 @@ NtUserBuildHwndList(
                      break;
                   }
                }
-               if (Window->FirstChild && bChildren)
+               if (Window->spwndChild && bChildren)
                {
-                  Window = Window->FirstChild;
+                  Window = Window->spwndChild;
                   continue;
                }
                bGoDown = FALSE;
             }
-            if (Window->NextSibling)
+            if (Window->spwndNext)
             {
-               Window = Window->NextSibling;
+               Window = Window->spwndNext;
                bGoDown = TRUE;
                continue;
             }
-            Window = Window->Parent;
+            Window = Window->spwndParent;
             if (Window == Parent)
             {
                break;
@@ -1570,28 +1608,31 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
  * calculates the default position of a window
  */
 BOOL FASTCALL
-IntCalcDefPosSize(PWINDOW_OBJECT Parent, PWINDOW_OBJECT Window, RECTL *rc, BOOL IncPos)
+IntCalcDefPosSize(PWINDOW_OBJECT Parent, RECTL *rc, BOOL IncPos)
 {
    SIZE Sz;
+   PMONITOR pMonitor;
    POINT Pos = {0, 0};
+   
+   pMonitor = IntGetPrimaryMonitor();
 
    if(Parent != NULL)
    {
-      RECTL_bIntersectRect(rc, rc, &Parent->Wnd->rcClient);
+      RECTL_bIntersectRect(rc, rc, &pMonitor->rcMonitor);
 
       if(IncPos)
       {
-         Pos.x = Parent->TiledCounter * (UserGetSystemMetrics(SM_CXSIZE) + UserGetSystemMetrics(SM_CXFRAME));
-         Pos.y = Parent->TiledCounter * (UserGetSystemMetrics(SM_CYSIZE) + UserGetSystemMetrics(SM_CYFRAME));
-         if(Pos.x > ((rc->right - rc->left) / 4) ||
-               Pos.y > ((rc->bottom - rc->top) / 4))
+         Pos.x = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CXSIZE) + UserGetSystemMetrics(SM_CXFRAME));
+         Pos.y = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CYSIZE) + UserGetSystemMetrics(SM_CYFRAME));
+         if (Pos.x > ((rc->right - rc->left) / 4) ||
+             Pos.y > ((rc->bottom - rc->top) / 4))
          {
             /* reset counter and position */
             Pos.x = 0;
             Pos.y = 0;
-            Parent->TiledCounter = 0;
+            pMonitor->cWndStack = 0;
          }
-         Parent->TiledCounter++;
+         pMonitor->cWndStack++;
       }
       Pos.x += rc->left;
       Pos.y += rc->top;
@@ -1663,9 +1704,9 @@ co_IntCreateWindowEx(DWORD dwExStyle,
 
    pti = PsGetCurrentThreadWin32Thread();
 
-   if (pti->Desktop)
+   if (pti->rpdesk)
    {
-       ParentWindowHandle = pti->Desktop->DesktopWindow;
+       ParentWindowHandle = pti->rpdesk->DesktopWindow;
    }
 
 
@@ -1719,7 +1760,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
 
    /* Check the window station. */
    ti = GetW32ThreadInfo();
-   if (ti == NULL || pti->Desktop == NULL)
+   if (ti == NULL || pti->rpdesk == NULL)
    {
       DPRINT1("Thread is not attached to a desktop! Cannot create window!\n");
       RETURN( (PWND)0);
@@ -1752,26 +1793,27 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    DPRINT("ClassAtom %x\n", ClassAtom);
    Class = IntReferenceClass(Class,
                              ClassLink,
-                             pti->Desktop);
+                             pti->rpdesk);
    if (Class == NULL)
    {
        DPRINT1("Failed to reference window class!\n");
        RETURN(NULL);
    }
 
-   WinSta = pti->Desktop->WindowStation;
+   WinSta = pti->rpdesk->rpwinstaParent;
 
    //FIXME: Reference thread/desktop instead
    ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
 
    /* Create the window object. */
    Window = (PWINDOW_OBJECT) UserCreateObject( gHandleTable,
+                                               pti->rpdesk,
                                                (PHANDLE)&hWnd,
                                                otWindow,
                                                sizeof(WINDOW_OBJECT));
    if (Window)
    {
-       Window->Wnd = DesktopHeapAlloc(pti->Desktop,
+       Window->Wnd = DesktopHeapAlloc(pti->rpdesk,
                                       sizeof(WND) + Class->cbwndExtra);
        if (!Window->Wnd)
            goto AllocErr;
@@ -1782,7 +1824,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
        Wnd->fnid = 0;
 
        Wnd->head.pti = ti;
-       Wnd->head.rpdesk = pti->Desktop;
+       Wnd->head.rpdesk = pti->rpdesk;
        Wnd->hWndLastActive = hWnd;
        Wnd->state2 |= WNDS2_WIN40COMPAT;
    }
@@ -1800,17 +1842,17 @@ AllocErr:
 
    ObDereferenceObject(WinSta);
 
-   if (NULL == pti->Desktop->DesktopWindow)
+   if (NULL == pti->rpdesk->DesktopWindow)
    {
       /* If there is no desktop window yet, we must be creating it */
-      pti->Desktop->DesktopWindow = hWnd;
-      pti->Desktop->DesktopInfo->Wnd = Wnd;
+      pti->rpdesk->DesktopWindow = hWnd;
+      pti->rpdesk->pDeskInfo->spwnd = Wnd;
    }
 
    /*
     * Fill out the structure describing it.
     */
-   Window->ti = ti;
+   Window->pti = ti;
    Wnd->pcls = Class;
    Class = NULL;
 
@@ -1819,9 +1861,8 @@ AllocErr:
    Wnd->hModule = hInstance;
    Window->hSelf = hWnd;
 
-   Window->MessageQueue = pti->MessageQueue;
-   IntReferenceMessageQueue(Window->MessageQueue);
-   Window->Parent = ParentWindow;
+   IntReferenceMessageQueue(Window->pti->MessageQueue);
+   Window->spwndParent = ParentWindow;
    Wnd->spwndParent = ParentWindow ? ParentWindow->Wnd : NULL;
    if (Wnd->spwndParent != NULL && hWndParent != 0)
    {
@@ -1908,15 +1949,17 @@ AllocErr:
       }
    }
 
-   Window->OwnerThread = PsGetCurrentThread();
-   Window->FirstChild = NULL;
-   Window->LastChild = NULL;
-   Window->PrevSibling = NULL;
-   Window->NextSibling = NULL;
+   Window->spwndChild = NULL;
+   Window->spwndPrev = NULL;
+   Window->spwndNext = NULL;
+
+   Wnd->spwndNext = NULL;
+   Wnd->spwndPrev = NULL;
+   Wnd->spwndChild = NULL;
+
    Wnd->cbwndExtra = Wnd->pcls->cbwndExtra;
 
    InitializeListHead(&Wnd->PropListHead);
-   InitializeListHead(&Window->WndObjListHead);
 
    if ( NULL != WindowName->Buffer && WindowName->Length > 0 )
    {
@@ -1963,7 +2006,7 @@ AllocErr:
       if (!(dwStyle & WS_POPUP))
       {
          dwStyle |= WS_CAPTION;
-         Window->Flags |= WINDOWOBJECT_NEED_SIZE;
+         Window->state |= WINDOWOBJECT_NEED_SIZE;
          DPRINT("4: Style is now %lx\n", dwStyle);
       }
    }
@@ -2008,11 +2051,14 @@ AllocErr:
    InsertTailList (&pti->WindowListHead, &Window->ThreadListEntry);
 
    /*  Handle "CS_CLASSDC", it is tested first. */
-   if ((Wnd->pcls->style & CS_CLASSDC) && !(Wnd->pcls->pdce)) // One DCE per class to have CLASS.
-      Wnd->pcls->pdce = DceAllocDCE(Window, DCE_CLASS_DC);
-   /* Allocate a DCE for this window. */
+   if ( (Wnd->pcls->style & CS_CLASSDC) && !(Wnd->pcls->pdce) )
+   {  /* One DCE per class to have CLASS. */
+      Wnd->pcls->pdce = DceAllocDCE( Window, DCE_CLASS_DC );
+   }
    else if ( Wnd->pcls->style & CS_OWNDC)
-      Window->Dce = DceAllocDCE(Window, DCE_WINDOW_DC);
+   {  /* Allocate a DCE for this window. */
+      DceAllocDCE(Window, DCE_WINDOW_DC);
+   }
 
    Pos.x = x;
    Pos.y = y;
@@ -2063,14 +2109,14 @@ AllocErr:
       PRTL_USER_PROCESS_PARAMETERS ProcessParams;
       BOOL CalculatedDefPosSize = FALSE;
 
-      IntGetDesktopWorkArea(((PTHREADINFO)Window->OwnerThread->Tcb.Win32Thread)->Desktop, &WorkArea);
+      IntGetDesktopWorkArea(Window->pti->rpdesk, &WorkArea);
 
       rc = WorkArea;
       ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters;
 
       if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
       {
-         CalculatedDefPosSize = IntCalcDefPosSize(ParentWindow, Window, &rc, TRUE);
+         CalculatedDefPosSize = IntCalcDefPosSize(ParentWindow, &rc, TRUE);
 
          if(ProcessParams->WindowFlags & STARTF_USEPOSITION)
          {
@@ -2114,7 +2160,7 @@ AllocErr:
       {
          if(!CalculatedDefPosSize)
          {
-            IntCalcDefPosSize(ParentWindow, Window, &rc, FALSE);
+            IntCalcDefPosSize(ParentWindow, &rc, FALSE);
          }
          if(ProcessParams->WindowFlags & STARTF_USESIZE)
          {
@@ -2239,7 +2285,13 @@ AllocErr:
       {
          PWINDOW_OBJECT PrevSibling;
 
-         PrevSibling = ParentWindow->LastChild;
+         PrevSibling = ParentWindow->spwndChild;
+
+         if(PrevSibling)
+         {
+            while (PrevSibling->spwndNext)
+               PrevSibling = PrevSibling->spwndNext;
+         }
 
          /* link window as bottom sibling */
          IntLinkWindow(Window, ParentWindow, PrevSibling /*prev sibling*/);
@@ -2251,11 +2303,11 @@ AllocErr:
          if (!(dwExStyle & WS_EX_TOPMOST))
          {
             InsertAfter = NULL;
-            Sibling = ParentWindow->FirstChild;
+            Sibling = ParentWindow->spwndChild;
             while (Sibling && (Sibling->Wnd->ExStyle & WS_EX_TOPMOST))
             {
                InsertAfter = Sibling;
-               Sibling = Sibling->NextSibling;
+               Sibling = Sibling->spwndNext;
             }
          }
          else
@@ -2264,7 +2316,6 @@ AllocErr:
          }
 
          IntLinkWindow(Window, ParentWindow, InsertAfter /* prev sibling */);
-
       }
    }
 
@@ -2283,7 +2334,7 @@ AllocErr:
    IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window->Wnd, OBJID_WINDOW, 0);
 
    /* Send move and size messages. */
-   if (!(Window->Flags & WINDOWOBJECT_NEED_SIZE))
+   if (!(Window->state & WINDOWOBJECT_NEED_SIZE))
    {
       LONG lParam;
 
@@ -2417,7 +2468,8 @@ AllocErr:
 
 CLEANUP:
    if (!_ret_ && Window && Window->Wnd && ti)
-       UserFreeWindowInfo(ti, Window);
+      co_UserDestroyWindow(Window);
+//      UserFreeWindowInfo(ti, Window);
    if (Window)
    {
       UserDerefObjectCo(Window);
@@ -2574,7 +2626,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
    DPRINT("co_UserDestroyWindow \n");
 
    /* Check for owner thread */
-   if ((Window->OwnerThread != PsGetCurrentThread()))
+   if ( (Window->pti->pEThread != PsGetCurrentThread()) ||
+        Wnd->head.pti != PsGetCurrentThreadWin32Thread() )
    {
       SetLastWin32Error(ERROR_ACCESS_DENIED);
       return FALSE;
@@ -2597,14 +2650,14 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
       }
    }
 
-   if (Window->MessageQueue->ActiveWindow == Window->hSelf)
-      Window->MessageQueue->ActiveWindow = NULL;
-   if (Window->MessageQueue->FocusWindow == Window->hSelf)
-      Window->MessageQueue->FocusWindow = NULL;
-   if (Window->MessageQueue->CaptureWindow == Window->hSelf)
-      Window->MessageQueue->CaptureWindow = NULL;
+   if (Window->pti->MessageQueue->ActiveWindow == Window->hSelf)
+      Window->pti->MessageQueue->ActiveWindow = NULL;
+   if (Window->pti->MessageQueue->FocusWindow == Window->hSelf)
+      Window->pti->MessageQueue->FocusWindow = NULL;
+   if (Window->pti->MessageQueue->CaptureWindow == Window->hSelf)
+      Window->pti->MessageQueue->CaptureWindow = NULL;
 
-   IntDereferenceMessageQueue(Window->MessageQueue);
+   IntDereferenceMessageQueue(Window->pti->MessageQueue);
 
    IntEngWindowChanged(Window, WOC_DELETE);
    isChild = (0 != (Wnd->style & WS_CHILD));
@@ -3070,7 +3123,7 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
    {
       case GA_PARENT:
          {
-            WndAncestor = Wnd->Parent;
+            WndAncestor = Wnd->spwndParent;
             break;
          }
 
@@ -3081,7 +3134,7 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
 
             for(;;)
             {
-               if(!(Parent = WndAncestor->Parent))
+               if(!(Parent = WndAncestor->spwndParent))
                {
                   break;
                }
@@ -3635,29 +3688,37 @@ UserGetWindow(HWND hWnd, UINT Relationship)
    switch (Relationship)
    {
       case GW_HWNDFIRST:
-         if((Parent = Window->Parent))
+         if((Parent = Window->spwndParent))
          {
-            if (Parent->FirstChild)
-               hWndResult = Parent->FirstChild->hSelf;
+            if (Parent->spwndChild)
+               hWndResult = Parent->spwndChild->hSelf;
          }
          break;
 
       case GW_HWNDLAST:
-         if((Parent = Window->Parent))
+         if((Parent = Window->spwndParent))
          {
-            if (Parent->LastChild)
-               hWndResult = Parent->LastChild->hSelf;
+            if (Parent->spwndChild)
+            {
+               Window = Parent->spwndChild;
+               if(Window)
+               {
+                  while(Window->spwndNext)
+                     Window = Window->spwndNext;
+               }
+               hWndResult = Window->hSelf;
+            }
          }
          break;
 
       case GW_HWNDNEXT:
-         if (Window->NextSibling)
-            hWndResult = Window->NextSibling->hSelf;
+         if (Window->spwndNext)
+            hWndResult = Window->spwndNext->hSelf;
          break;
 
       case GW_HWNDPREV:
-         if (Window->PrevSibling)
-            hWndResult = Window->PrevSibling->hSelf;
+         if (Window->spwndPrev)
+            hWndResult = Window->spwndPrev->hSelf;
          break;
 
       case GW_OWNER:
@@ -3667,40 +3728,14 @@ UserGetWindow(HWND hWnd, UINT Relationship)
          }
          break;
       case GW_CHILD:
-         if (Window->FirstChild)
-            hWndResult = Window->FirstChild->hSelf;
+         if (Window->spwndChild)
+            hWndResult = Window->spwndChild->hSelf;
          break;
    }
 
    return hWndResult;
 }
 
-/*
- * NtUserGetWindow
- *
- * The NtUserGetWindow function retrieves a handle to a window that has the
- * specified relationship (Z order or owner) to the specified window.
- *
- * Status
- *    @implemented
- */
-
-HWND APIENTRY
-NtUserGetWindow(HWND hWnd, UINT Relationship)
-{
-   DECLARE_RETURN(HWND);
-
-   DPRINT("Enter NtUserGetWindow\n");
-   UserEnterShared();
-
-   RETURN(UserGetWindow(hWnd, Relationship));
-
-CLEANUP:
-   DPRINT("Leave NtUserGetWindow, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
 /*
  * NtUserGetWindowLong
  *
@@ -3732,7 +3767,7 @@ UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
     * WndProc is only available to the owner process
     */
    if (GWL_WNDPROC == Index
-         && Window->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
+         && Window->pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
    {
       SetLastWin32Error(ERROR_ACCESS_DENIED);
       return 0;
@@ -3768,7 +3803,7 @@ UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
             break;
 
          case GWL_HWNDPARENT:
-            Parent = Window->Parent;
+            Parent = Window->spwndParent;
             if(Parent)
             {
                if (Parent && Parent->hSelf == IntGetDesktopWindow())
@@ -3797,35 +3832,6 @@ UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
    return Result;
 }
 
-/*
- * NtUserGetWindowLong
- *
- * The NtUserGetWindowLong function retrieves information about the specified
- * window. The function also retrieves the 32-bit (long) value at the
- * specified offset into the extra window memory.
- *
- * Status
- *    @implemented
- */
-
-LONG APIENTRY
-NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
-{
-   DECLARE_RETURN(LONG);
-
-   DPRINT("Enter NtUserGetWindowLong(%x,%d,%d)\n", hWnd, (INT)Index, Ansi);
-   UserEnterExclusive();
-
-   RETURN(UserGetWindowLong(hWnd, Index, Ansi));
-
-CLEANUP:
-   DPRINT("Leave NtUserGetWindowLong, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
-
-
 LONG FASTCALL
 co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
 {
@@ -3854,7 +3860,7 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
    {
       if ((Index + sizeof(LONG)) > Wnd->cbwndExtra)
       {
-         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+         SetLastWin32Error(ERROR_INVALID_INDEX);
          return( 0);
       }
 
@@ -3882,7 +3888,7 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
             /*
              * Remove extended window style bit WS_EX_TOPMOST for shell windows.
              */
-            WindowStation = ((PTHREADINFO)Window->OwnerThread->Tcb.Win32Thread)->Desktop->WindowStation;
+            WindowStation = Window->pti->rpdesk->rpwinstaParent;
             if(WindowStation)
             {
                if (hWnd == WindowStation->ShellWindow || hWnd == WindowStation->ShellListView)
@@ -3923,7 +3929,7 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
             break;
 
          case GWL_HWNDPARENT:
-            Parent = Window->Parent;
+            Parent = Window->spwndParent;
             if (Parent && (Parent->hSelf == IntGetDesktopWindow()))
                OldValue = (LONG) IntSetOwner(Window->hSelf, (HWND) NewValue);
             else
@@ -3942,7 +3948,7 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
 
          default:
             DPRINT1("NtUserSetWindowLong(): Unsupported index %d\n", Index);
-            SetLastWin32Error(ERROR_INVALID_PARAMETER);
+            SetLastWin32Error(ERROR_INVALID_INDEX);
             OldValue = 0;
             break;
       }
@@ -4072,7 +4078,7 @@ NtUserGetWindowPlacement(HWND hWnd,
    {
       Safepl.showCmd = SW_HIDE;
    }
-   else if ((0 != (Window->Flags & WINDOWOBJECT_RESTOREMAX) ||
+   else if ((0 != (Window->state & WINDOWOBJECT_RESTOREMAX) ||
             0 != (Wnd->style & WS_MAXIMIZE)) &&
             0 == (Wnd->style & WS_MINIMIZE))
    {
@@ -4195,7 +4201,7 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
          break;
 
       case QUERY_WINDOW_ISHUNG:
-         Result = (DWORD)MsqIsHung(Window->MessageQueue);
+         Result = (DWORD)MsqIsHung(Window->pti->MessageQueue);
          break;
 
       case QUERY_WINDOW_REAL_ID:
@@ -4546,23 +4552,23 @@ IntGetWindowRgn(PWINDOW_OBJECT Window, HRGN hRgn)
    Wnd = Window->Wnd;
 
    /* Create a new window region using the window rectangle */
-   VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->Wnd->rcWindow);
+   VisRgn = IntSysCreateRectRgnIndirect(&Window->Wnd->rcWindow);
    NtGdiOffsetRgn(VisRgn, -Window->Wnd->rcWindow.left, -Window->Wnd->rcWindow.top);
    /* if there's a region assigned to the window, combine them both */
-   if(Window->WindowRegion && !(Wnd->style & WS_MINIMIZE))
-      NtGdiCombineRgn(VisRgn, VisRgn, Window->WindowRegion, RGN_AND);
+   if(Window->hrgnClip && !(Wnd->style & WS_MINIMIZE))
+      NtGdiCombineRgn(VisRgn, VisRgn, Window->hrgnClip, RGN_AND);
    /* Copy the region into hRgn */
    NtGdiCombineRgn(hRgn, VisRgn, NULL, RGN_COPY);
 
-   if((pRgn = REGION_LockRgn(hRgn)))
+   if((pRgn = RGNOBJAPI_Lock(hRgn, NULL)))
    {
       Ret = pRgn->rdh.iType;
-      REGION_UnlockRgn(pRgn);
+      RGNOBJAPI_Unlock(pRgn);
    }
    else
       Ret = ERROR;
 
-   GreDeleteObject(VisRgn);
+   REGION_FreeRgnByHandle(VisRgn);
 
    return Ret;
 }
@@ -4587,22 +4593,22 @@ IntGetWindowRgnBox(PWINDOW_OBJECT Window, RECTL *Rect)
    Wnd = Window->Wnd;
 
    /* Create a new window region using the window rectangle */
-   VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->Wnd->rcWindow);
+   VisRgn = IntSysCreateRectRgnIndirect(&Window->Wnd->rcWindow);
    NtGdiOffsetRgn(VisRgn, -Window->Wnd->rcWindow.left, -Window->Wnd->rcWindow.top);
    /* if there's a region assigned to the window, combine them both */
-   if(Window->WindowRegion && !(Wnd->style & WS_MINIMIZE))
-      NtGdiCombineRgn(VisRgn, VisRgn, Window->WindowRegion, RGN_AND);
+   if(Window->hrgnClip && !(Wnd->style & WS_MINIMIZE))
+      NtGdiCombineRgn(VisRgn, VisRgn, Window->hrgnClip, RGN_AND);
 
-   if((pRgn = REGION_LockRgn(VisRgn)))
+   if((pRgn = RGNOBJAPI_Lock(VisRgn, NULL)))
    {
       Ret = pRgn->rdh.iType;
       *Rect = pRgn->rdh.rcBound;
-      REGION_UnlockRgn(pRgn);
+      RGNOBJAPI_Unlock(pRgn);
    }
    else
       Ret = ERROR;
 
-   GreDeleteObject(VisRgn);
+   REGION_FreeRgnByHandle(VisRgn);
 
    return Ret;
 }
@@ -4617,6 +4623,7 @@ NtUserSetWindowRgn(
    HRGN hRgn,
    BOOL bRedraw)
 {
+   HRGN hrgnCopy;
    PWINDOW_OBJECT Window;
    DECLARE_RETURN(INT);
 
@@ -4628,15 +4635,25 @@ NtUserSetWindowRgn(
       RETURN( 0);
    }
 
-   /* FIXME - Verify if hRgn is a valid handle!!!!
-              Propably make this operation thread-safe, but maybe it's not necessary */
+   if (hRgn) // The region will be deleted in user32.
+   {
+      if (GDIOBJ_ValidateHandle(hRgn, GDI_OBJECT_TYPE_REGION))
+      {
+         hrgnCopy = IntSysCreateRectRgn(0, 0, 0, 0);
+         NtGdiCombineRgn(hrgnCopy, hRgn, 0, RGN_COPY);
+      }
+      else
+         RETURN( 0);
+   }
+   else
+      hrgnCopy = (HRGN) 1;
 
-   if(Window->WindowRegion)
+   if (Window->hrgnClip)
    {
       /* Delete no longer needed region handle */
-      GreDeleteObject(Window->WindowRegion);
+      GreDeleteObject(Window->hrgnClip);
    }
-   Window->WindowRegion = hRgn;
+   Window->hrgnClip = hrgnCopy;
 
    /* FIXME - send WM_WINDOWPOSCHANGING and WM_WINDOWPOSCHANGED messages to the window */
 
@@ -5109,7 +5126,7 @@ NtUserValidateHandleSecure(
        }
        case otMonitor:
        {
-         PMONITOR_OBJECT Monitor;
+         PMONITOR Monitor;
          if ((Monitor = UserGetMonitorObject((HMONITOR) handle))) return TRUE;
          return FALSE;
        }