Author: jimtabor
Date: Wed Oct 21 00:13:23 2015
New Revision: 69633
URL:
http://svn.reactos.org/svn/reactos?rev=69633&view=rev
Log:
[Win32SS]
- Implement suspended window support, see CORE-10078.
Modified:
trunk/reactos/win32ss/user/ntuser/defwnd.c
trunk/reactos/win32ss/user/ntuser/msgqueue.c
trunk/reactos/win32ss/user/ntuser/msgqueue.h
trunk/reactos/win32ss/user/ntuser/nonclient.c
trunk/reactos/win32ss/user/ntuser/painting.c
trunk/reactos/win32ss/user/ntuser/painting.h
trunk/reactos/win32ss/user/ntuser/userfuncs.h
Modified: trunk/reactos/win32ss/user/ntuser/defwnd.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/defwnd…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/defwnd.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/defwnd.c [iso-8859-1] Wed Oct 21 00:13:23 2015
@@ -1094,7 +1094,7 @@
case WM_NCCALCSIZE:
{
- return NC_HandleNCCalcSize( Wnd, wParam, (RECTL *)lParam );
+ return NC_HandleNCCalcSize( Wnd, wParam, (RECTL *)lParam, FALSE );
}
case WM_NCACTIVATE:
Modified: trunk/reactos/win32ss/user/ntuser/msgqueue.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/msgque…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/msgqueue.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/msgqueue.c [iso-8859-1] Wed Oct 21 00:13:23 2015
@@ -1058,6 +1058,13 @@
return STATUS_UNSUCCESSFUL;
}
+ if (IsThreadSuspended(ptirec))
+ {
+ ERR("Sending to Suspended Thread Msg %lx\n",Msg);
+ if (uResult) *uResult = -1;
+ return STATUS_UNSUCCESSFUL;
+ }
+
// Should we do the same for No Wait?
if ( HookMessage == MSQ_NORMAL )
{
@@ -2037,7 +2044,28 @@
LARGE_INTEGER LargeTickCount;
KeQueryTickCount(&LargeTickCount);
- return ((LargeTickCount.u.LowPart - pti->timeLast) > MSQ_HUNG);
+
+ if ((LargeTickCount.u.LowPart - pti->timeLast) > MSQ_HUNG &&
+ !(pti->pcti->fsWakeMask & QS_INPUT) &&
+ !PsGetThreadFreezeCount(pti->pEThread) &&
+ !(pti->ppi->W32PF_flags & W32PF_APPSTARTING))
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOL FASTCALL
+IsThreadSuspended(PTHREADINFO pti)
+{
+ if (pti->pEThread)
+ {
+ BOOL Ret = TRUE;
+ ObReferenceObject(pti->pEThread);
+ if (!(pti->pEThread->Tcb.SuspendCount) &&
!PsGetThreadFreezeCount(pti->pEThread)) Ret = FALSE;
+ ObDereferenceObject(pti->pEThread);
+ return Ret;
+ }
+ return FALSE;
}
VOID
Modified: trunk/reactos/win32ss/user/ntuser/msgqueue.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/msgque…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/msgqueue.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/msgqueue.h [iso-8859-1] Wed Oct 21 00:13:23 2015
@@ -251,6 +251,7 @@
VOID FASTCALL ClearMsgBitsMask(PTHREADINFO,UINT);
BOOL FASTCALL IntCallMsgFilter(LPMSG,INT);
WPARAM FASTCALL MsqGetDownKeyState(PUSER_MESSAGE_QUEUE);
+BOOL FASTCALL IsThreadSuspended(PTHREADINFO);
int UserShowCursor(BOOL bShow);
PCURICON_OBJECT
Modified: trunk/reactos/win32ss/user/ntuser/nonclient.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/noncli…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/nonclient.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/nonclient.c [iso-8859-1] Wed Oct 21 00:13:23 2015
@@ -477,7 +477,12 @@
UserDrawMovingFrame( hdc, &newRect, thickframe );
else
{ // Moving the whole window now!
- PWND pwndTemp;
+ HRGN hrgnNew;
+ HRGN hrgnOrig = GreCreateRectRgnIndirect(&pwnd->rcWindow);
+
+ if (pwnd->hrgnClip != NULL)
+ NtGdiCombineRgn(hrgnOrig, hrgnOrig, pwnd->hrgnClip, RGN_AND);
+
//// This causes the mdi child window to jump up when it is moved.
//IntMapWindowPoints( 0, pWndParent, (POINT *)&rect, 2 );
co_WinPosSetWindowPos( pwnd,
@@ -488,18 +493,29 @@
newRect.bottom - newRect.top,
( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
- // Update all the windows after the move or size, including this
window.
- for ( pwndTemp =
pwnd->head.rpdesk->pDeskInfo->spwnd->spwndChild;
- pwndTemp;
- pwndTemp = pwndTemp->spwndNext )
+ hrgnNew = GreCreateRectRgnIndirect(&pwnd->rcWindow);
+ if (pwnd->hrgnClip != NULL)
+ NtGdiCombineRgn(hrgnNew, hrgnNew, pwnd->hrgnClip, RGN_AND);
+
+ if (hrgnNew)
{
- RECTL rect;
- // Only the windows that overlap will be redrawn.
- if (RECTL_bIntersectRect( &rect, &pwnd->rcWindow,
&pwndTemp->rcWindow ))
+ if (hrgnOrig)
+ NtGdiCombineRgn(hrgnOrig, hrgnOrig, hrgnNew, RGN_DIFF);
+ }
+ else
+ {
+ if (hrgnOrig)
{
- co_UserRedrawWindow( pwndTemp, NULL, NULL, RDW_UPDATENOW |
RDW_ALLCHILDREN);
+ GreDeleteObject(hrgnOrig);
+ hrgnOrig = 0;
}
}
+
+ // Update all the windows after the move or size, including this
window.
+ UpdateThreadWindows(UserGetDesktopWindow()->spwndChild, pti,
hrgnOrig);
+
+ if (hrgnOrig) GreDeleteObject(hrgnOrig);
+ if (hrgnNew) GreDeleteObject(hrgnNew);
}
}
sizingRect = newRect;
@@ -1163,7 +1179,7 @@
{
TempRect = CurrentRect;
TempRect.bottom = TempRect.top + menu->cyMenu;
- CurrentRect.top += MENU_DrawMenuBar(hDC, &TempRect, pWnd, FALSE);
+ if (!(Flags & DC_NOSENDMSG)) CurrentRect.top += MENU_DrawMenuBar(hDC,
&TempRect, pWnd, FALSE);
}
if (ExStyle & WS_EX_CLIENTEDGE)
@@ -1214,7 +1230,7 @@
return 0; // For WM_NCPAINT message, return 0.
}
-LRESULT NC_HandleNCCalcSize( PWND Wnd, WPARAM wparam, RECTL *Rect )
+LRESULT NC_HandleNCCalcSize( PWND Wnd, WPARAM wparam, RECTL *Rect, BOOL Suspended )
{
LRESULT Result = 0;
SIZE WindowBorders;
@@ -1277,7 +1293,7 @@
CliRect.right -= OrigRect.left;
CliRect.left -= OrigRect.left;
CliRect.top -= OrigRect.top;
- Rect->top += MENU_DrawMenuBar(hDC, &CliRect, Wnd, TRUE);
+ if (!Suspended) Rect->top += MENU_DrawMenuBar(hDC, &CliRect, Wnd,
TRUE);
UserReleaseDC(Wnd, hDC, FALSE);
}
}
Modified: trunk/reactos/win32ss/user/ntuser/painting.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/painti…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/painting.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/painting.c [iso-8859-1] Wed Oct 21 00:13:23 2015
@@ -510,7 +510,7 @@
{
HWND hWnd = Wnd->head.h;
- if ((Wnd->hrgnUpdate != NULL || Wnd->state & WNDS_INTERNALPAINT))
+ if ( Wnd->hrgnUpdate != NULL || Wnd->state & WNDS_INTERNALPAINT )
{
if (Wnd->hrgnUpdate)
{
@@ -1004,6 +1004,106 @@
return TRUE;
}
+VOID FASTCALL
+PaintSuspendedWindow(PWND pwnd, HRGN hrgnOrig)
+{
+ if (pwnd->hrgnUpdate)
+ {
+ HDC hDC;
+ INT Flags = DC_NC|DC_NOSENDMSG;
+ HRGN hrgnTemp;
+ RECT Rect;
+ INT type;
+ PREGION prgn;
+
+ if (pwnd->hrgnUpdate > HRGN_WINDOW)
+ {
+ hrgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
+ type = NtGdiCombineRgn( hrgnTemp, pwnd->hrgnUpdate, 0, RGN_COPY);
+ if (type == ERROR)
+ {
+ GreDeleteObject(hrgnTemp);
+ hrgnTemp = HRGN_WINDOW;
+ }
+ }
+ else
+ {
+ hrgnTemp = GreCreateRectRgnIndirect(&pwnd->rcWindow);
+ }
+
+ if ( hrgnOrig &&
+ hrgnTemp > HRGN_WINDOW &&
+ NtGdiCombineRgn(hrgnTemp, hrgnTemp, hrgnOrig, RGN_AND) == NULLREGION)
+ {
+ GreDeleteObject(hrgnTemp);
+ return;
+ }
+
+ hDC = UserGetDCEx(pwnd, hrgnTemp,
DCX_WINDOW|DCX_INTERSECTRGN|DCX_USESTYLE|DCX_KEEPCLIPRGN);
+
+ Rect = pwnd->rcWindow;
+ RECTL_vOffsetRect(&Rect, -pwnd->rcWindow.left, -pwnd->rcWindow.top);
+
+ // Clear out client area!
+ FillRect(hDC, &Rect, IntGetSysColorBrush(COLOR_WINDOW));
+
+ NC_DoNCPaint(pwnd, hDC, Flags); // Redraw without MENUs.
+
+ UserReleaseDC(pwnd, hDC, FALSE);
+
+ prgn = REGION_LockRgn(hrgnTemp);
+ IntInvalidateWindows(pwnd, prgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
RDW_ALLCHILDREN);
+ REGION_UnlockRgn(prgn);
+
+ // Set updates for this window.
+ pwnd->state |= WNDS_SENDNCPAINT|WNDS_SENDERASEBACKGROUND|WNDS_UPDATEDIRTY;
+
+ // DCX_KEEPCLIPRGN is set. Check it anyway.
+ if (hrgnTemp > HRGN_WINDOW && GreIsHandleValid(hrgnTemp))
GreDeleteObject(hrgnTemp);
+ }
+}
+
+VOID FASTCALL
+UpdateTheadChildren(PWND pWnd, HRGN hRgn)
+{
+ PaintSuspendedWindow( pWnd, hRgn );
+
+ if (!(pWnd->style & WS_CLIPCHILDREN))
+ return;
+
+ pWnd = pWnd->spwndChild; // invalidate children if any.
+ while (pWnd)
+ {
+ UpdateTheadChildren( pWnd, hRgn );
+ pWnd = pWnd->spwndNext;
+ }
+}
+
+VOID FASTCALL
+UpdateThreadWindows(PWND pWnd, PTHREADINFO pti, HRGN hRgn)
+{
+ PWND pwndTemp;
+
+ for ( pwndTemp = pWnd;
+ pwndTemp;
+ pwndTemp = pwndTemp->spwndNext )
+ {
+ if (pwndTemp->head.pti == pti)
+ {
+ UserUpdateWindows(pwndTemp, RDW_ALLCHILDREN);
+ }
+ else
+ {
+ if (IsThreadSuspended(pwndTemp->head.pti))
+ {
+ UpdateTheadChildren(pwndTemp, hRgn);
+ }
+ else
+ UserUpdateWindows(pwndTemp, RDW_ALLCHILDREN);
+ }
+ }
+}
+
BOOL FASTCALL
IntIsWindowDirty(PWND Wnd)
{
@@ -1631,7 +1731,7 @@
{
if (hrgnTemp) GreDeleteObject(hrgnTemp);
NtGdiSetRectRgn(hRgn, 0, 0, 0, 0);
- return NULLREGION;
+ return RegionType;
}
if (Window != UserGetDesktopWindow()) // Window->fnid == FNID_DESKTOP
@@ -1684,9 +1784,23 @@
if (IntIntersectWithParents(Window, pRect))
{
- RECTL_vOffsetRect(pRect,
- -Window->rcClient.left,
- -Window->rcClient.top);
+ if (Window != UserGetDesktopWindow()) // Window->fnid == FNID_DESKTOP
+ {
+ RECTL_vOffsetRect(pRect,
+ -Window->rcClient.left,
+ -Window->rcClient.top);
+ }
+ if (Window->pcls->style & CS_OWNDC)
+ {
+ HDC hdc;
+ //DWORD layout;
+ hdc = UserGetDCEx(Window, NULL, DCX_USESTYLE);
+ //layout = NtGdiSetLayout(hdc, -1, 0);
+ //IntMapWindowPoints( 0, Window, (LPPOINT)pRect, 2 );
+ GreDPtoLP( hdc, (LPPOINT)pRect, 2 );
+ //NtGdiSetLayout(hdc, -1, layout);
+ UserReleaseDC(Window, hdc, FALSE);
+ }
}
else
{
Modified: trunk/reactos/win32ss/user/ntuser/painting.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/painti…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/painting.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/painting.h [iso-8859-1] Wed Oct 21 00:13:23 2015
@@ -35,4 +35,5 @@
BOOL FASTCALL IntIntersectWithParents(PWND, RECTL *);
BOOL FASTCALL IntIsWindowDrawable(PWND);
BOOL UserDrawCaption(PWND,HDC,RECTL*,HFONT,HICON,const PUNICODE_STRING,UINT);
+VOID FASTCALL UpdateThreadWindows(PWND,PTHREADINFO,HRGN);
Modified: trunk/reactos/win32ss/user/ntuser/userfuncs.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/userfu…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/userfuncs.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/userfuncs.h [iso-8859-1] Wed Oct 21 00:13:23 2015
@@ -131,7 +131,7 @@
LRESULT NC_DoNCPaint(PWND,HDC,INT);
void FASTCALL NC_GetSysPopupPos(PWND, RECT *);
LRESULT NC_HandleNCActivate( PWND Wnd, WPARAM wParam, LPARAM lParam );
-LRESULT NC_HandleNCCalcSize( PWND wnd, WPARAM wparam, RECTL *winRect );
+LRESULT NC_HandleNCCalcSize( PWND wnd, WPARAM wparam, RECTL *winRect, BOOL Suspended );
VOID NC_DrawFrame( HDC hDC, RECT *CurrentRect, BOOL Active, DWORD Style, DWORD ExStyle);
VOID UserDrawCaptionBar( PWND pWnd, HDC hDC, INT Flags);
void UserGetInsideRectNC(PWND Wnd, RECT *rect);