diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index c252ffbf99a..b31528ecf86 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -2679,12 +2679,12 @@ NtUserValidateRect( HWND hWnd, CONST RECT *lpRect); -DWORD -NTAPI +BOOL +APIENTRY NtUserValidateTimerCallback( - DWORD dwUnknown1, - DWORD dwUnknown2, - DWORD dwUnknown3); + HWND hWnd, + WPARAM wParam, + LPARAM lParam); DWORD NTAPI diff --git a/reactos/subsystems/win32/win32k/include/painting.h b/reactos/subsystems/win32/win32k/include/painting.h index 1c80319c41c..3b6b76d82ea 100644 --- a/reactos/subsystems/win32/win32k/include/painting.h +++ b/reactos/subsystems/win32/win32k/include/painting.h @@ -13,5 +13,6 @@ BOOL FASTCALL IntGetPaintMessage(HWND hWnd, UINT MsgFilterMin, UINT MsgFilterMax, PTHREADINFO Thread, MSG *Message, BOOL Remove); INT FASTCALL UserRealizePalette(HDC); +INT FASTCALL co_UserGetUpdateRgn(PWINDOW_OBJECT, HRGN, BOOL); #endif /* _WIN32K_PAINTING_H */ diff --git a/reactos/subsystems/win32/win32k/include/timer.h b/reactos/subsystems/win32/win32k/include/timer.h index d44e38e1e3a..b3ddbff9527 100644 --- a/reactos/subsystems/win32/win32k/include/timer.h +++ b/reactos/subsystems/win32/win32k/include/timer.h @@ -13,8 +13,20 @@ typedef struct _TIMER TIMERPROC pfn; // lpTimerFunc } TIMER, *PTIMER; +// +// Timer structure flags. +// +#define TMRF_READY 0x0001 +#define TMRF_SYSTEM 0x0002 +#define TMRF_RIT 0x0004 +#define TMRF_INIT 0x0008 +#define TMRF_ONESHOT 0x0010 +#define TMRF_WAITING 0x0020 + NTSTATUS FASTCALL InitTimerImpl(VOID); BOOL FASTCALL IntKillTimer(HWND Wnd, UINT_PTR IDEvent, BOOL SystemTimer); UINT_PTR FASTCALL IntSetTimer(HWND Wnd, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, BOOL SystemTimer); +PTIMER FASTCALL FindSystemTimer(PMSG); +BOOL FASTCALL ValidateTimerCallback(PW32THREADINFO,PWINDOW_OBJECT,WPARAM,LPARAM); #endif /* _WIN32K_TIMER_H */ diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index ae2cf1960dc..76486456d64 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -341,6 +341,62 @@ IntCallWndProcRet } } +LRESULT +FASTCALL +IntDispatchMessage(PMSG pMsg) +{ + LRESULT retval; + PWINDOW_OBJECT Window = NULL; + + if (pMsg->hwnd) + { + Window = UserGetWindowObject(pMsg->hwnd); + if (!Window || !Window->Wnd) return 0; + } + + if (((pMsg->message == WM_SYSTIMER) || + (pMsg->message == WM_TIMER)) && + (pMsg->lParam) ) + { + if (pMsg->message == WM_TIMER) + { + if (ValidateTimerCallback(GetW32ThreadInfo(),Window,pMsg->wParam,pMsg->lParam)) + { + return co_IntCallWindowProc((WNDPROC)pMsg->lParam, + TRUE, + pMsg->hwnd, + WM_TIMER, + pMsg->wParam, + (LPARAM)EngGetTickCount(), + sizeof(LPARAM)); + } + return 0; + } + else + { + PTIMER pTimer = FindSystemTimer(pMsg); + if (pTimer && pTimer->pfn) + { + pTimer->pfn(pMsg->hwnd, WM_SYSTIMER, (UINT)pMsg->wParam, (DWORD)EngGetTickCount()); + } + return 0; + } + } + // Need a window! + if (!Window) return 0; + + retval = co_IntPostOrSendMessage(pMsg->hwnd, pMsg->message, pMsg->wParam, pMsg->lParam); + + if (pMsg->message == WM_PAINT) + { + /* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */ + HRGN hrgn = NtGdiCreateRectRgn( 0, 0, 0, 0 ); + co_UserGetUpdateRgn( Window, hrgn, TRUE ); + NtGdiDeleteObject( hrgn ); + } + return retval; +} + BOOL APIENTRY @@ -407,8 +463,27 @@ CLEANUP: LRESULT APIENTRY NtUserDispatchMessage(PMSG UnsafeMsgInfo) { - UNIMPLEMENTED; - return 0; + LRESULT Res = 0; + BOOL Hit = FALSE; + MSG SafeMsg; + + UserEnterExclusive(); + _SEH2_TRY + { + ProbeForRead(UnsafeMsgInfo, sizeof(MSG), 1); + RtlCopyMemory(&SafeMsg, UnsafeMsgInfo, sizeof(MSG)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + SetLastNtError(_SEH2_GetExceptionCode()); + Hit = TRUE; + } + _SEH2_END; + + if (!Hit) Res = IntDispatchMessage(&SafeMsg); + + UserLeave(); + return Res; } diff --git a/reactos/subsystems/win32/win32k/ntuser/ntstubs.c b/reactos/subsystems/win32/win32k/ntuser/ntstubs.c index e7f70a79580..286b7399a6d 100644 --- a/reactos/subsystems/win32/win32k/ntuser/ntstubs.c +++ b/reactos/subsystems/win32/win32k/ntuser/ntstubs.c @@ -1098,15 +1098,30 @@ NtUserValidateRect( return 0; } -DWORD +BOOL APIENTRY NtUserValidateTimerCallback( - DWORD dwUnknown1, - DWORD dwUnknown2, - DWORD dwUnknown3) + HWND hWnd, + WPARAM wParam, + LPARAM lParam) { - UNIMPLEMENTED; - return 0; + BOOL Ret = FALSE; + PWINDOW_OBJECT Window = NULL; + + UserEnterShared(); + + if (hWnd) + { + Window = UserGetWindowObject(hWnd); + if (!Window || !Window->Wnd) + goto Exit; + } + + Ret = ValidateTimerCallback(GetW32ThreadInfo(), Window, wParam, lParam); + +Exit: + UserLeave(); + return Ret; } DWORD diff --git a/reactos/subsystems/win32/win32k/ntuser/timer.c b/reactos/subsystems/win32/win32k/ntuser/timer.c index f03bea603b0..c6afb6dce76 100644 --- a/reactos/subsystems/win32/win32k/ntuser/timer.c +++ b/reactos/subsystems/win32/win32k/ntuser/timer.c @@ -55,6 +55,54 @@ static ULONG HintIndex = 0; /* FUNCTIONS *****************************************************************/ +PTIMER +FASTCALL +FindSystemTimer(PMSG pMsg) +{ + PTIMER pTmr = FirstpTmr; + KeEnterCriticalRegion(); + do + { + if (!pTmr) break; + + if ( pMsg->lParam == (LPARAM)pTmr->pfn && + (pTmr->flags & TMRF_SYSTEM) ) + break; + + pTmr = (PTIMER)pTmr->ptmrList.Flink; + } while (pTmr != FirstpTmr); + KeLeaveCriticalRegion(); + + return pTmr; +} + +BOOL +FASTCALL +ValidateTimerCallback(PW32THREADINFO pti, + PWINDOW_OBJECT Window, + WPARAM wParam, + LPARAM lParam) +{ + PTIMER pTmr = FirstpTmr; + + if (!pTmr) return FALSE; + + KeEnterCriticalRegion(); + do + { + if ( (lParam == (LPARAM)pTmr->pfn) && + (pTmr->flags & (TMRF_SYSTEM|TMRF_RIT)) && + (pTmr->pti->pi == pti->pi) ) + break; + + pTmr = (PTIMER)pTmr->ptmrList.Flink; + } while (pTmr != FirstpTmr); + KeLeaveCriticalRegion(); + + if (!pTmr) return FALSE; + + return TRUE; +} UINT_PTR FASTCALL IntSetTimer(HWND Wnd, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, BOOL SystemTimer) @@ -229,7 +277,6 @@ InitTimerImpl(VOID) return STATUS_SUCCESS; } - UINT_PTR APIENTRY NtUserSetTimer diff --git a/reactos/subsystems/win32/win32k/objects/pen.c b/reactos/subsystems/win32/win32k/objects/pen.c index b75711ad875..d9ded060855 100644 --- a/reactos/subsystems/win32/win32k/objects/pen.c +++ b/reactos/subsystems/win32/win32k/objects/pen.c @@ -85,7 +85,7 @@ IntGdiExtCreatePen( // If nWidth is zero, the pen is a single pixel wide, regardless of the current transformation. if ((bOldStylePen) && (!dwWidth) && (dwPenStyle & PS_STYLE_MASK) != PS_SOLID) - dwWidth = 1; + dwWidth = 1; PenObject->ptPenWidth.x = dwWidth; PenObject->ptPenWidth.y = 0;