[Win32k]
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / winpos.c
index 3099bee..0d6b268 100644 (file)
@@ -1120,7 +1120,7 @@ co_WinPosSetWindowPos(
       Window->style |= WS_VISIBLE;
    }
 
-   if (Window->hrgnUpdate != NULL && Window->hrgnUpdate != (HRGN)1)
+   if (Window->hrgnUpdate != NULL && Window->hrgnUpdate != HRGN_WINDOW)
    {
       NtGdiOffsetRgn(Window->hrgnUpdate,
                      NewWindowRect.left - OldWindowRect.left,
@@ -1673,6 +1673,204 @@ co_WinPosWindowFromPoint(PWND ScopeWin, POINT *WinPoint, USHORT* HitTest)
    return Window;
 }
 
+HDWP
+FASTCALL
+IntDeferWindowPos( HDWP hdwp,
+                   HWND hwnd,
+                   HWND hwndAfter,
+                   INT x,
+                   INT y,
+                   INT cx,
+                   INT cy,
+                   UINT flags )
+{
+    PSMWP pDWP;
+    int i;
+    HDWP retvalue = hdwp;
+
+    DPRINT("hdwp %p, hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
+          hdwp, hwnd, hwndAfter, x, y, cx, cy, flags);
+
+    if (flags & ~(SWP_NOSIZE | SWP_NOMOVE |
+                  SWP_NOZORDER | SWP_NOREDRAW |
+                  SWP_NOACTIVATE | SWP_NOCOPYBITS |
+                  SWP_NOOWNERZORDER|SWP_SHOWWINDOW |
+                  SWP_HIDEWINDOW | SWP_FRAMECHANGED))
+    {
+       EngSetLastError(ERROR_INVALID_PARAMETER);
+       return NULL;    
+    }
+
+    if (!(pDWP = (PSMWP)UserGetObject(gHandleTable, hdwp, otSMWP)))
+    {
+       EngSetLastError(ERROR_INVALID_DWP_HANDLE);
+       return NULL;
+    }
+
+    for (i = 0; i < pDWP->ccvr; i++)
+    {
+        if (pDWP->acvr[i].pos.hwnd == hwnd)
+        {
+              /* Merge with the other changes */
+            if (!(flags & SWP_NOZORDER))
+            {
+                pDWP->acvr[i].pos.hwndInsertAfter = hwndAfter;
+            }
+            if (!(flags & SWP_NOMOVE))
+            {
+                pDWP->acvr[i].pos.x = x;
+                pDWP->acvr[i].pos.y = y;
+            }
+            if (!(flags & SWP_NOSIZE))
+            {
+                pDWP->acvr[i].pos.cx = cx;
+                pDWP->acvr[i].pos.cy = cy;
+            }
+            pDWP->acvr[i].pos.flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
+                                               SWP_NOZORDER | SWP_NOREDRAW |
+                                               SWP_NOACTIVATE | SWP_NOCOPYBITS|
+                                               SWP_NOOWNERZORDER);
+            pDWP->acvr[i].pos.flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
+                                              SWP_FRAMECHANGED);
+            goto END;
+        }
+    }
+    if (pDWP->ccvr >= pDWP->ccvrAlloc)
+    {
+        PCVR newpos = ExAllocatePoolWithTag(PagedPool, pDWP->ccvrAlloc * 2 * sizeof(CVR), USERTAG_SWP);
+        if (!newpos)
+        {
+            retvalue = NULL;
+            goto END;
+        }
+        RtlZeroMemory(newpos, pDWP->ccvrAlloc * 2 * sizeof(CVR));
+        RtlCopyMemory(newpos, pDWP->acvr, pDWP->ccvrAlloc * sizeof(CVR));
+        ExFreePoolWithTag(pDWP->acvr, USERTAG_SWP);
+        pDWP->ccvrAlloc *= 2;
+        pDWP->acvr = newpos;
+    }
+    pDWP->acvr[pDWP->ccvr].pos.hwnd = hwnd;
+    pDWP->acvr[pDWP->ccvr].pos.hwndInsertAfter = hwndAfter;
+    pDWP->acvr[pDWP->ccvr].pos.x = x;
+    pDWP->acvr[pDWP->ccvr].pos.y = y;
+    pDWP->acvr[pDWP->ccvr].pos.cx = cx;
+    pDWP->acvr[pDWP->ccvr].pos.cy = cy;
+    pDWP->acvr[pDWP->ccvr].pos.flags = flags;
+    pDWP->acvr[pDWP->ccvr].hrgnClip = NULL; 
+    pDWP->acvr[pDWP->ccvr].hrgnInterMonitor = NULL;
+    pDWP->ccvr++;
+END:
+    return retvalue;
+}
+
+BOOL FASTCALL IntEndDeferWindowPosEx( HDWP hdwp )
+{
+    PSMWP pDWP;
+    PCVR winpos;
+    BOOL res = TRUE;
+    int i;
+
+    DPRINT("%p\n", hdwp);
+
+    if (!(pDWP = (PSMWP)UserGetObject(gHandleTable, hdwp, otSMWP)))
+    {
+       EngSetLastError(ERROR_INVALID_DWP_HANDLE);
+       return FALSE;
+    }
+
+    for (i = 0, winpos = pDWP->acvr; res && i < pDWP->ccvr; i++, winpos++)
+    {
+        DPRINT("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
+               winpos->pos.hwnd, winpos->pos.hwndInsertAfter, winpos->pos.x, winpos->pos.y,
+               winpos->pos.cx, winpos->pos.cy, winpos->pos.flags);
+
+        res = co_WinPosSetWindowPos( UserGetWindowObject(winpos->pos.hwnd),
+                                     winpos->pos.hwndInsertAfter,
+                                     winpos->pos.x,
+                                     winpos->pos.y,
+                                     winpos->pos.cx,
+                                     winpos->pos.cy,
+                                     winpos->pos.flags);
+    }
+    ExFreePoolWithTag(pDWP->acvr, USERTAG_SWP);
+    UserDeleteObject(hdwp, otSMWP);
+    return res;
+}
+
+/*
+ * @implemented
+ */
+BOOL APIENTRY
+NtUserEndDeferWindowPosEx(HDWP WinPosInfo,
+                          DWORD Unknown1)
+{
+   BOOL Ret;
+   DPRINT("Enter NtUserEndDeferWindowPosEx\n");
+   UserEnterExclusive();
+   Ret = IntEndDeferWindowPosEx(WinPosInfo);
+   DPRINT("Leave NtUserEndDeferWindowPosEx, ret=%i\n", Ret);
+   UserLeave();
+   return Ret;
+}
+
+/*
+ * @implemented
+ */
+HDWP APIENTRY
+NtUserDeferWindowPos(HDWP WinPosInfo,
+                     HWND Wnd,
+                     HWND WndInsertAfter,
+                     int x,
+                     int y,
+                     int cx,
+                     int cy,
+                     UINT Flags)
+{
+   PWND pWnd, pWndIA;
+   HDWP Ret = NULL;
+   UINT Tmp = ~(SWP_ASYNCWINDOWPOS|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_NOREPOSITION|
+                SWP_NOCOPYBITS|SWP_HIDEWINDOW|SWP_SHOWWINDOW|SWP_FRAMECHANGED|
+                SWP_NOACTIVATE|SWP_NOREDRAW|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE);
+
+   DPRINT("Enter NtUsereferWindowPos\n");
+   UserEnterExclusive();
+
+   if ( Flags & Tmp )
+   {
+      EngSetLastError(ERROR_INVALID_FLAGS);
+      goto Exit;
+   }
+
+   pWnd = UserGetWindowObject(Wnd);
+   if ( !pWnd ||
+         pWnd == IntGetDesktopWindow() ||
+         pWnd == IntGetMessageWindow() )
+   {
+      goto Exit;
+   }
+
+   if ( WndInsertAfter &&
+        WndInsertAfter != HWND_BOTTOM &&
+        WndInsertAfter != HWND_TOPMOST && 
+        WndInsertAfter != HWND_NOTOPMOST )
+   {
+      pWndIA = UserGetWindowObject(WndInsertAfter);
+      if ( !pWndIA ||
+            pWndIA == IntGetDesktopWindow() ||
+            pWndIA == IntGetMessageWindow() )
+      {
+         goto Exit;
+      }
+   }
+
+   Ret = IntDeferWindowPos(WinPosInfo, Wnd, WndInsertAfter, x, y, cx, cy, Flags);
+
+Exit:
+   DPRINT("Leave NtUserDeferWindowPos, ret=%i\n", Ret);
+   UserLeave();
+   return Ret;   
+}
+
 BOOL
 APIENTRY
 NtUserGetMinMaxInfo(