Author: jimtabor
Date: Fri Mar 18 22:41:22 2011
New Revision: 51089
URL:
http://svn.reactos.org/svn/reactos?rev=51089&view=rev
Log:
[Win32k]
- Implement the set of DeferWindowPos functions. Regedit (one of many application) uses it
and allocated three when it should be four. This was a good test to verify the batch list
growing routine. Instead of drawing per DeferWindowPos call, now a real list is created
and run down as a batch.
- ReactOS should handle this the correct way and a good test case is located here:
http://bugs.winehq.org/show_bug.cgi?id=23187
- The code is from wine and modified for the use in ReactOS.
Modified:
trunk/reactos/dll/win32/user32/windows/window.c
trunk/reactos/include/reactos/win32k/ntuser.h
trunk/reactos/subsystems/win32/win32k/include/winpos.h
trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c
trunk/reactos/subsystems/win32/win32k/ntuser/object.c
trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c
trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c
Modified: trunk/reactos/dll/win32/user32/windows/window.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/w…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/window.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/windows/window.c [iso-8859-1] Fri Mar 18 22:41:22 2011
@@ -65,17 +65,7 @@
HDWP WINAPI
BeginDeferWindowPos(int nNumWindows)
{
- if (nNumWindows < 0)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-#if 0
- UNIMPLEMENTED;
- return (HDWP)0;
-#else
- return (HDWP)1;
-#endif
+ return (HDWP)NtUserCallOneParam((DWORD_PTR)nNumWindows,
ONEPARAM_ROUTINE_BEGINDEFERWNDPOS);
}
@@ -567,12 +557,7 @@
int cy,
UINT uFlags)
{
-#if 0
return NtUserDeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter, x, y, cx, cy,
uFlags);
-#else
- SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
- return hWinPosInfo;
-#endif
}
@@ -582,12 +567,7 @@
BOOL WINAPI
EndDeferWindowPos(HDWP hWinPosInfo)
{
-#if 0
- UNIMPLEMENTED;
- return FALSE;
-#else
- return TRUE;
-#endif
+ return NtUserEndDeferWindowPosEx(hWinPosInfo, 0);
}
Modified: trunk/reactos/include/reactos/win32k/ntuser.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntu…
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntuser.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/win32k/ntuser.h [iso-8859-1] Fri Mar 18 22:41:22 2011
@@ -1631,10 +1631,10 @@
UINT wSBflags,
UINT wArrows);
-DWORD
+BOOL
NTAPI
NtUserEndDeferWindowPosEx(
- DWORD Unknown0,
+ HDWP WinPosInfo,
DWORD Unknown1);
BOOL NTAPI
Modified: trunk/reactos/subsystems/win32/win32k/include/winpos.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/winpos.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/winpos.h [iso-8859-1] Fri Mar 18
22:41:22 2011
@@ -1,4 +1,31 @@
#pragma once
+
+typedef struct _CVR // Tag Ussw
+{
+ WINDOWPOS pos;
+ LONG xClientNew;
+ LONG yClientNew;
+ LONG cxClientNew;
+ LONG cyClientNew;
+ RECT rcBlt;
+ LONG dxBlt;
+ LONG dyBlt;
+ UINT fsRE;
+ HRGN hrgnVisOld;
+ PTHREADINFO pti;
+ HRGN hrgnClip;
+ HRGN hrgnInterMonitor;
+} CVR, *PCVR;
+
+typedef struct _SMWP
+{
+ HEAD head;
+ UINT bShellNotify:1;
+ UINT bHandle:1;
+ INT ccvr;
+ INT ccvrAlloc;
+ PCVR acvr;
+} SMWP, *PSMWP;
#define IntPtInWindow(WndObject,x,y) \
((x) >= (WndObject)->rcWindow.left && \
@@ -36,3 +63,5 @@
VOID FASTCALL WinPosInitInternalPos(PWND WindowObject,
POINT *pt, RECTL *RestoreRect);
+BOOL FASTCALL IntEndDeferWindowPosEx(HDWP);
+HDWP FASTCALL IntDeferWindowPos(HDWP,HWND,HWND,INT,INT,INT,INT,UINT);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c [iso-8859-1] Fri Mar 18
22:41:22 2011
@@ -1169,18 +1169,6 @@
}
/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserEndDeferWindowPosEx(DWORD Unknown0,
- DWORD Unknown1)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-/*
* FillWindow: Called from User; Dialog, Edit and ListBox procs during a WM_ERASEBKGND.
*/
/*
@@ -1205,7 +1193,7 @@
{
UNIMPLEMENTED
- return 0;
+ return 1;
}
/*
@@ -1306,25 +1294,6 @@
}
/*
- * @unimplemented
- */
-HDWP APIENTRY
-NtUserDeferWindowPos(HDWP WinPosInfo,
- HWND Wnd,
- HWND WndInsertAfter,
- int x,
- int y,
- int cx,
- int cy,
- UINT Flags)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
-/*
* NtUserResolveDesktopForWOW
*
* Status
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/object.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/object.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/object.c [iso-8859-1] Fri Mar 18 22:41:22
2011
@@ -177,6 +177,7 @@
case otHook:
case otCallProc:
case otAccel:
+ case otSMWP:
pi = GetW32ProcessInfo();
break;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c [iso-8859-1] Fri Mar 18
22:41:22 2011
@@ -157,6 +157,38 @@
MsqPostQuitMessage(pti->MessageQueue, Param);
RETURN(TRUE);
}
+
+ case ONEPARAM_ROUTINE_BEGINDEFERWNDPOS:
+ {
+ PSMWP psmwp;
+ HDWP hDwp = NULL;
+ if (Param < 0)
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ RETURN(0);
+ }
+ /* Windows allows zero count, in which case it allocates context for 8 moves
*/
+ if (Param == 0) Param = 8;
+
+ psmwp = (PSMWP) UserCreateObject( gHandleTable,
+ NULL,
+ (PHANDLE)&hDwp,
+ otSMWP,
+ sizeof(SMWP));
+ if (!psmwp) RETURN(0);
+ psmwp->acvr = ExAllocatePoolWithTag(PagedPool, Param * sizeof(CVR),
USERTAG_SWP);
+ if (!psmwp->acvr)
+ {
+ UserDeleteObject(hDwp, otSMWP);
+ RETURN(0);
+ }
+ RtlZeroMemory(psmwp->acvr, Param * sizeof(CVR));
+ psmwp->bHandle = TRUE;
+ psmwp->ccvr = 0; // actualCount
+ psmwp->ccvrAlloc = Param; // suggestedCount
+ RETURN((DWORD_PTR)hDwp);
+ }
+
case ONEPARAM_ROUTINE_SHOWCURSOR:
RETURN( (DWORD_PTR)UserShowCursor((BOOL)Param) );
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c [iso-8859-1] Fri Mar 18 22:41:22
2011
@@ -1673,6 +1673,204 @@
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(