- Move more support for Desktop Proc into Win32k. Increase Desktop drawing by about 10%. Rearanged code and plugged in the server side callout.

svn path=/trunk/; revision=57236
This commit is contained in:
James Tabor 2012-09-04 05:37:13 +00:00
parent 81095c0413
commit 458994e118
7 changed files with 186 additions and 121 deletions

View file

@ -547,11 +547,15 @@ HWND FASTCALL IntGetCurrentThreadDesktopWindow(VOID)
/* PUBLIC FUNCTIONS ***********************************************************/
LRESULT FASTCALL
DesktopWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
BOOL FASTCALL
DesktopWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
{
PAINTSTRUCT Ps;
ULONG Value;
//ERR("DesktopWindowProc\n");
*lResult = 0;
switch (Msg)
{
case WM_NCCREATE:
@ -559,7 +563,8 @@ DesktopWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
Wnd->fnid = FNID_DESKTOP;
}
return (LRESULT)TRUE;
*lResult = (LRESULT)TRUE;
return TRUE;
case WM_CREATE:
Value = HandleToULong(PsGetCurrentProcessId());
@ -568,14 +573,31 @@ DesktopWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Value = HandleToULong(PsGetCurrentThreadId());
// Save Thread ID
co_UserSetWindowLong(UserHMGetHandle(Wnd), DT_GWL_THREADID, Value, FALSE);
case WM_CLOSE:
return 0;
case WM_CLOSE:
return TRUE;
case WM_DISPLAYCHANGE:
co_WinPosSetWindowPos(Wnd, 0, 0, 0, LOWORD(lParam), HIWORD(lParam), SWP_NOZORDER | SWP_NOACTIVATE);
break;
}
return 0;
return TRUE;
case WM_ERASEBKGND:
IntPaintDesktop((HDC)wParam);
*lResult = 1;
return TRUE;
case WM_PAINT:
{
if (IntBeginPaint(Wnd, &Ps))
{
IntEndPaint(Wnd, &Ps);
}
return TRUE;
}
case WM_SYSCOLORCHANGE:
co_UserRedrawWindow(Wnd, NULL, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN);
return TRUE;
}
return FALSE; // Not processed so go with callback.
}
HDC FASTCALL
@ -934,7 +956,6 @@ IntPaintDesktop(HDC hDC)
/* Black desktop background in Safe Mode */
DesktopBrush = StockObjects[BLACK_BRUSH];
}
/* Back ground is set to none, clear the screen */
if (doPatBlt)
{
@ -993,16 +1014,13 @@ IntPaintDesktop(HDC hDC)
GreExtTextOutW(hDC, rect.left, rect.top, 0, NULL, s_wszSafeMode, len, NULL, 0);
IntGdiSetTextAlign(hDC, TA_LEFT|TA_BASELINE);
GreExtTextOutW(hDC, rect.left, rect.bottom, 0, NULL, s_wszSafeMode, len, NULL, 0);
}
IntGdiSetBkMode(hDC, mode_old);
IntGdiSetTextAlign(hDC, align_old);
IntGdiSetTextColor(hDC, color_old);
}
}
return TRUE;
}

View file

@ -282,5 +282,5 @@ DesktopHeapAddressToUser(PVOID lpMem)
PWND FASTCALL IntGetThreadDesktopWindow(PTHREADINFO);
PWND FASTCALL co_GetDesktopWindow(PWND);
BOOL FASTCALL IntPaintDesktop(HDC);
LRESULT FASTCALL DesktopWindowProc(PWND, UINT, WPARAM, LPARAM);
BOOL FASTCALL DesktopWindowProc(PWND, UINT, WPARAM, LPARAM, LRESULT *);
/* EOF */

View file

@ -649,6 +649,7 @@ IntDispatchMessage(PMSG pMsg)
PTHREADINFO pti;
PWND Window = NULL;
HRGN hrgn;
BOOL DoCallBack = TRUE;
if (pMsg->hwnd)
{
@ -704,12 +705,23 @@ IntDispatchMessage(PMSG pMsg)
if ( Window->state & WNDS_SERVERSIDEWINDOWPROC )
{
TRACE("Dispatch: Server Side Window Procedure\n");
switch(Window->fnid)
{
case FNID_DESKTOP:
DoCallBack = !DesktopWindowProc( Window,
pMsg->message,
pMsg->wParam,
pMsg->lParam,
&retval);
break;
}
}
/* Since we are doing a callback on the same thread right away, there is
no need to copy the lparam to kernel mode and then back to usermode.
We just pretend it isn't a pointer */
if (DoCallBack)
retval = co_IntCallWindowProc( Window->lpfnWndProc,
!Window->Unicode,
pMsg->hwnd,
@ -1247,6 +1259,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
ULONG_PTR Hi, Lo, Result = 0;
DECLARE_RETURN(LRESULT);
USER_REFERENCE_ENTRY Ref;
BOOL DoCallBack = TRUE;
if (!(Window = UserGetWindowObject(hWnd)))
{
@ -1289,6 +1302,17 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
RETURN( FALSE);
}
/* Return after server side call, IntCallWndProcRet will not be called. */
switch(Window->fnid)
{
case FNID_DESKTOP:
DoCallBack = !DesktopWindowProc(Window, Msg, wParam, lParam,(LRESULT*)&Result);
break;
}
if (!DoCallBack)
{
if (uResult) *uResult = Result;
RETURN( TRUE);
}
}
/* See if this message type is present in the table */
MsgMemoryEntry = FindMsgMemory(Msg);
@ -1493,6 +1517,7 @@ co_IntSendMessageWithCallBack( HWND hWnd,
DECLARE_RETURN(LRESULT);
USER_REFERENCE_ENTRY Ref;
PUSER_SENT_MESSAGE Message;
BOOL DoCallBack = TRUE;
if (!(Window = UserGetWindowObject(hWnd)))
{
@ -1560,8 +1585,15 @@ co_IntSendMessageWithCallBack( HWND hWnd,
if ( Window->state & WNDS_SERVERSIDEWINDOWPROC )
{
TRACE("SMWCB: Server Side Window Procedure\n");
switch(Window->fnid)
{
case FNID_DESKTOP:
DoCallBack = !DesktopWindowProc(Window, Msg, wParam, lParamPacked, (LRESULT*)&Result);
break;
}
}
if (DoCallBack)
Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
!Window->Unicode,
hWnd,
@ -2193,7 +2225,12 @@ NtUserMessageCall( HWND hWnd,
case FNID_DESKTOP:
{
Window = UserGetWindowObject(hWnd);
if (Window) lResult = DesktopWindowProc(Window, Msg, wParam, lParam);
if (Window)
{
ERR("FNID_DESKTOP IN\n");
Ret = DesktopWindowProc(Window, Msg, wParam, lParam, &lResult);
ERR("FNID_DESKTOP OUT\n");
}
break;
}
case FNID_DEFWINDOWPROC:

View file

@ -916,6 +916,105 @@ IntFlashWindowEx(PWND pWnd, PFLASHWINFO pfwi)
return Ret;
}
HDC FASTCALL
IntBeginPaint(PWND Window, PPAINTSTRUCT Ps)
{
co_UserHideCaret(Window);
Window->state2 |= WNDS2_STARTPAINT;
Window->state &= ~WNDS_PAINTNOTPROCESSED;
if (Window->state & WNDS_SENDNCPAINT)
{
HRGN hRgn;
Window->state &= ~WNDS_UPDATEDIRTY;
hRgn = IntGetNCUpdateRgn(Window, FALSE);
Window->state &= ~WNDS_SENDNCPAINT;
co_IntSendMessage(UserHMGetHandle(Window), WM_NCPAINT, (WPARAM)hRgn, 0);
if (hRgn != HRGN_WINDOW && hRgn != NULL && GreIsHandleValid(hRgn))
{
/* NOTE: The region can already be deleted! */
GreDeleteObject(hRgn);
}
}
else
{
Window->state &= ~WNDS_UPDATEDIRTY;
}
RtlZeroMemory(Ps, sizeof(PAINTSTRUCT));
Ps->hdc = UserGetDCEx( Window,
Window->hrgnUpdate,
DCX_INTERSECTRGN | DCX_USESTYLE);
if (!Ps->hdc)
{
return NULL;
}
if (Window->hrgnUpdate != NULL)
{
MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
GdiGetClipBox(Ps->hdc, &Ps->rcPaint);
IntGdiSetRegionOwner(Window->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
/* The region is part of the dc now and belongs to the process! */
Window->hrgnUpdate = NULL;
}
else
{
if (Window->state & WNDS_INTERNALPAINT)
MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
IntGetClientRect(Window, &Ps->rcPaint);
}
Window->state &= ~WNDS_INTERNALPAINT;
if (Window->state & WNDS_SENDERASEBACKGROUND)
{
Window->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
Ps->fErase = !co_IntSendMessage(UserHMGetHandle(Window), WM_ERASEBKGND, (WPARAM)Ps->hdc, 0);
if ( Ps->fErase )
{
Window->state |= (WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
}
}
else
{
Ps->fErase = FALSE;
}
if (Window->hrgnUpdate)
{
if (!(Window->style & WS_CLIPCHILDREN))
{
PWND Child;
for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
{
if (Child->hrgnUpdate == NULL && Child->state & WNDS_SENDNCPAINT) // Helped fixing test_redrawnow.
IntInvalidateWindows(Child, Window->hrgnUpdate, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
}
}
return Ps->hdc;
}
BOOL FASTCALL
IntEndPaint(PWND Wnd, PPAINTSTRUCT Ps)
{
HDC hdc = NULL;
hdc = Ps->hdc;
UserReleaseDC(Wnd, hdc, TRUE);
Wnd->state2 &= ~(WNDS2_WMPAINTSENT|WNDS2_STARTPAINT);
co_UserShowCaret(Wnd);
return TRUE;
}
/* PUBLIC FUNCTIONS ***********************************************************/
/*
@ -931,8 +1030,9 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* UnsafePs)
PWND Window = NULL;
PAINTSTRUCT Ps;
NTSTATUS Status;
DECLARE_RETURN(HDC);
HDC hDC;
USER_REFERENCE_ENTRY Ref;
DECLARE_RETURN(HDC);
TRACE("Enter NtUserBeginPaint\n");
UserEnterExclusive();
@ -944,83 +1044,7 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* UnsafePs)
UserRefObjectCo(Window, &Ref);
co_UserHideCaret(Window);
Window->state2 |= WNDS2_STARTPAINT;
Window->state &= ~WNDS_PAINTNOTPROCESSED;
if (Window->state & WNDS_SENDNCPAINT)
{
HRGN hRgn;
Window->state &= ~WNDS_UPDATEDIRTY;
hRgn = IntGetNCUpdateRgn(Window, FALSE);
Window->state &= ~WNDS_SENDNCPAINT;
co_IntSendMessage(hWnd, WM_NCPAINT, (WPARAM)hRgn, 0);
if (hRgn != HRGN_WINDOW && hRgn != NULL && GreIsHandleValid(hRgn))
{
/* NOTE: The region can already be deleted! */
GreDeleteObject(hRgn);
}
}
else
{
Window->state &= ~WNDS_UPDATEDIRTY;
}
RtlZeroMemory(&Ps, sizeof(PAINTSTRUCT));
Ps.hdc = UserGetDCEx( Window,
Window->hrgnUpdate,
DCX_INTERSECTRGN | DCX_USESTYLE);
if (!Ps.hdc)
{
RETURN(NULL);
}
if (Window->hrgnUpdate != NULL)
{
MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
GdiGetClipBox(Ps.hdc, &Ps.rcPaint);
IntGdiSetRegionOwner(Window->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
/* The region is part of the dc now and belongs to the process! */
Window->hrgnUpdate = NULL;
}
else
{
if (Window->state & WNDS_INTERNALPAINT)
MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
IntGetClientRect(Window, &Ps.rcPaint);
}
Window->state &= ~WNDS_INTERNALPAINT;
if (Window->state & WNDS_SENDERASEBACKGROUND)
{
Window->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
Ps.fErase = !co_IntSendMessage(hWnd, WM_ERASEBKGND, (WPARAM)Ps.hdc, 0);
if ( Ps.fErase )
{
Window->state |= (WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
}
}
else
{
Ps.fErase = FALSE;
}
if (Window->hrgnUpdate)
{
if (!(Window->style & WS_CLIPCHILDREN))
{
PWND Child;
for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
{
if (Child->hrgnUpdate == NULL && Child->state & WNDS_SENDNCPAINT) // Helped fixing test_redrawnow.
IntInvalidateWindows(Child, Window->hrgnUpdate, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
}
}
hDC = IntBeginPaint(Window, &Ps);
Status = MmCopyToCaller(UnsafePs, &Ps, sizeof(PAINTSTRUCT));
if (! NT_SUCCESS(Status))
@ -1029,7 +1053,7 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* UnsafePs)
RETURN(NULL);
}
RETURN(Ps.hdc);
RETURN(hDC);
CLEANUP:
if (Window) UserDerefObjectCo(Window);
@ -1051,10 +1075,10 @@ BOOL APIENTRY
NtUserEndPaint(HWND hWnd, CONST PAINTSTRUCT* pUnsafePs)
{
NTSTATUS Status = STATUS_SUCCESS;
PWND Window;
DECLARE_RETURN(BOOL);
PWND Window = NULL;
PAINTSTRUCT Ps;
USER_REFERENCE_ENTRY Ref;
HDC hdc = NULL;
DECLARE_RETURN(BOOL);
TRACE("Enter NtUserEndPaint\n");
UserEnterExclusive();
@ -1067,7 +1091,7 @@ NtUserEndPaint(HWND hWnd, CONST PAINTSTRUCT* pUnsafePs)
_SEH2_TRY
{
ProbeForRead(pUnsafePs, sizeof(*pUnsafePs), 1);
hdc = pUnsafePs->hdc;
RtlCopyMemory(&Ps, pUnsafePs, sizeof(PAINTSTRUCT));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@ -1079,17 +1103,13 @@ NtUserEndPaint(HWND hWnd, CONST PAINTSTRUCT* pUnsafePs)
RETURN(FALSE);
}
UserReleaseDC(Window, hdc, TRUE);
Window->state2 &= ~(WNDS2_WMPAINTSENT|WNDS2_STARTPAINT);
UserRefObjectCo(Window, &Ref);
co_UserShowCaret(Window);
UserDerefObjectCo(Window);
RETURN(TRUE);
RETURN(IntEndPaint(Window, &Ps));
CLEANUP:
if (Window) UserDerefObjectCo(Window);
TRACE("Leave NtUserEndPaint, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;

View file

@ -8,3 +8,5 @@ INT FASTCALL co_UserGetUpdateRgn(PWND, HRGN, BOOL);
VOID FASTCALL co_IntPaintWindows(PWND Window, ULONG Flags, BOOL Recurse);
BOOL FASTCALL IntValidateParent(PWND Child, HRGN hValidateRgn, BOOL Recurse);
BOOL FASTCALL IntIsWindowDirty(PWND);
BOOL FASTCALL IntEndPaint(PWND,PPAINTSTRUCT);
HDC FASTCALL IntBeginPaint(PWND,PPAINTSTRUCT);

View file

@ -1493,7 +1493,7 @@ co_WinPosSetWindowPos(
INT cx,
INT cy,
UINT flags
)
)
{
WINDOWPOS WinPos;
RECTL NewWindowRect;

View file

@ -37,36 +37,24 @@ DesktopWndProcW(HWND Wnd,
WPARAM wParam,
LPARAM lParam)
{
PAINTSTRUCT PS;
TRACE("Desktop W Class Atom! hWnd 0x%x, Msg %d\n", Wnd, Msg);
switch(Msg)
{
case WM_ERASEBKGND:
case WM_NCCREATE:
case WM_CREATE:
case WM_CLOSE:
case WM_DISPLAYCHANGE:
case WM_PAINT:
case WM_SYSCOLORCHANGE:
{
LRESULT lResult;
NtUserMessageCall( Wnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DESKTOP, FALSE);
TRACE("Desktop lResult %d\n", lResult);
return lResult;
}
case WM_ERASEBKGND:
PaintDesktop((HDC)wParam);
return 1;
case WM_PAINT:
if (BeginPaint(Wnd, &PS))
{
EndPaint(Wnd, &PS);
}
return 0;
case WM_SYSCOLORCHANGE:
RedrawWindow(Wnd, NULL, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN);
break;
case WM_PALETTECHANGED:
if (Wnd == (HWND)wParam) break;
case WM_QUERYNEWPALETTE: