Author: jimtabor
Date: Fri Feb 13 13:39:57 2015
New Revision: 66244
URL:
http://svn.reactos.org/svn/reactos?rev=66244&view=rev
Log:
[NtUser]
- Use a real timer for caret. This should cleanup message testing from those random system
timer messages. See CORE-7447.
Modified:
trunk/reactos/win32ss/user/ntuser/caret.c
Modified: trunk/reactos/win32ss/user/ntuser/caret.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/caret.…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/caret.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/caret.c [iso-8859-1] Fri Feb 13 13:39:57 2015
@@ -16,6 +16,111 @@
/* FUNCTIONS *****************************************************************/
+VOID FASTCALL
+co_IntDrawCaret(PWND pWnd, PTHRDCARETINFO CaretInfo)
+{
+ HDC hdc, hdcMem;
+ HBITMAP hbmOld;
+ BOOL bDone = FALSE;
+
+ hdc = UserGetDCEx(pWnd, 0, DCX_USESTYLE | DCX_WINDOW);
+ if (!hdc)
+ {
+ ERR("GetDC failed\n");
+ return;
+ }
+
+ if (pWnd->hrgnUpdate)
+ {
+ NtGdiSaveDC(hdc);
+ }
+
+ if(CaretInfo->Bitmap && NtGdiGetBitmapDimension(CaretInfo->Bitmap,
&CaretInfo->Size))
+ {
+ hdcMem = NtGdiCreateCompatibleDC(hdc);
+ if (hdcMem)
+ {
+ hbmOld = NtGdiSelectBitmap(hdcMem, CaretInfo->Bitmap);
+ bDone = NtGdiBitBlt(hdc,
+ CaretInfo->Pos.x,
+ CaretInfo->Pos.y,
+ CaretInfo->Size.cx,
+ CaretInfo->Size.cy,
+ hdcMem,
+ 0,
+ 0,
+ SRCINVERT,
+ 0,
+ 0);
+ NtGdiSelectBitmap(hdcMem, hbmOld);
+ GreDeleteObject(hdcMem);
+ }
+ }
+
+ if (!bDone)
+ {
+ NtGdiPatBlt(hdc,
+ CaretInfo->Pos.x,
+ CaretInfo->Pos.y,
+ CaretInfo->Size.cx,
+ CaretInfo->Size.cy,
+ DSTINVERT);
+ }
+
+ if (pWnd->hrgnUpdate)
+ {
+ NtGdiRestoreDC(hdc, -1);
+ }
+
+ UserReleaseDC(pWnd, hdc, FALSE);
+}
+
+VOID
+CALLBACK
+CaretSystemTimerProc(HWND hwnd,
+ UINT uMsg,
+ UINT_PTR idEvent,
+ DWORD dwTime)
+{
+ PTHREADINFO pti;
+ PUSER_MESSAGE_QUEUE ThreadQueue;
+ PWND pWnd;
+
+ pti = PsGetCurrentThreadWin32Thread();
+ ThreadQueue = pti->MessageQueue;
+
+ if (ThreadQueue->CaretInfo->hWnd != hwnd)
+ {
+ ERR("Not the same caret window!\n");
+ return;
+ }
+
+ if (hwnd)
+ {
+ pWnd = UserGetWindowObject(hwnd);
+ if (!pWnd)
+ {
+ ERR("Caret System Timer Proc has invalid window handle! %p Id: %u\n",
hwnd, idEvent);
+ return;
+ }
+ }
+ else
+ {
+ TRACE( "Windowless Caret Timer Running!\n" );
+ return;
+ }
+
+ switch (idEvent)
+ {
+ case IDCARETTIMER:
+ {
+ ThreadQueue->CaretInfo->Showing = (ThreadQueue->CaretInfo->Showing ?
0 : 1);
+ co_IntDrawCaret(pWnd, ThreadQueue->CaretInfo);
+ }
+ }
+ return;
+}
+
static
BOOL FASTCALL
co_IntHideCaret(PTHRDCARETINFO CaretInfo)
@@ -24,8 +129,8 @@
if(CaretInfo->hWnd && CaretInfo->Visible &&
CaretInfo->Showing)
{
pWnd = UserGetWindowObject(CaretInfo->hWnd);
- co_IntSendMessage(CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
CaretInfo->Showing = 0;
+
IntNotifyWinEvent(EVENT_OBJECT_HIDE, pWnd, OBJID_CARET, CHILDID_SELF, 0);
return TRUE;
}
@@ -92,8 +197,8 @@
ThreadQueue->CaretInfo->Showing = 0;
ThreadQueue->CaretInfo->Pos.x = X;
ThreadQueue->CaretInfo->Pos.y = Y;
- co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER,
0);
- IntSetTimer(pWnd, IDCARETTIMER, gpsi->dtCaretBlink, NULL, TMRF_SYSTEM);
+
+ IntSetTimer(pWnd, IDCARETTIMER, gpsi->dtCaretBlink, CaretSystemTimerProc,
TMRF_SYSTEM);
IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_CARET, CHILDID_SELF,
0);
}
return TRUE;
@@ -102,6 +207,78 @@
return FALSE;
}
+BOOL FASTCALL co_UserHideCaret(PWND Window OPTIONAL)
+{
+ PTHREADINFO pti;
+ PUSER_MESSAGE_QUEUE ThreadQueue;
+
+ if (Window) ASSERT_REFS_CO(Window);
+
+ if(Window && Window->head.pti->pEThread != PsGetCurrentThread())
+ {
+ EngSetLastError(ERROR_ACCESS_DENIED);
+ return FALSE;
+ }
+
+ pti = PsGetCurrentThreadWin32Thread();
+ ThreadQueue = pti->MessageQueue;
+
+ if(Window && ThreadQueue->CaretInfo->hWnd != Window->head.h)
+ {
+ EngSetLastError(ERROR_ACCESS_DENIED);
+ return FALSE;
+ }
+
+ if(ThreadQueue->CaretInfo->Visible)
+ {
+ PWND pwnd = UserGetWindowObject(ThreadQueue->CaretInfo->hWnd);
+ IntKillTimer(pwnd, IDCARETTIMER, TRUE);
+
+ co_IntHideCaret(ThreadQueue->CaretInfo);
+ ThreadQueue->CaretInfo->Visible = 0;
+ ThreadQueue->CaretInfo->Showing = 0;
+ }
+
+ return TRUE;
+}
+
+BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL)
+{
+ PTHREADINFO pti;
+ PUSER_MESSAGE_QUEUE ThreadQueue;
+ PWND pWnd = NULL;
+
+ if (Window) ASSERT_REFS_CO(Window);
+
+ if(Window && Window->head.pti->pEThread != PsGetCurrentThread())
+ {
+ EngSetLastError(ERROR_ACCESS_DENIED);
+ return FALSE;
+ }
+
+ pti = PsGetCurrentThreadWin32Thread();
+ ThreadQueue = pti->MessageQueue;
+
+ if(Window && ThreadQueue->CaretInfo->hWnd != Window->head.h)
+ {
+ EngSetLastError(ERROR_ACCESS_DENIED);
+ return FALSE;
+ }
+
+ if (!ThreadQueue->CaretInfo->Visible)
+ {
+ ThreadQueue->CaretInfo->Visible = 1;
+ pWnd = ValidateHwndNoErr(ThreadQueue->CaretInfo->hWnd);
+ if (!ThreadQueue->CaretInfo->Showing && pWnd)
+ {
+ IntNotifyWinEvent(EVENT_OBJECT_SHOW, pWnd, OBJID_CARET, OBJID_CARET, 0);
+ }
+ IntSetTimer(pWnd, IDCARETTIMER, gpsi->dtCaretBlink, CaretSystemTimerProc,
TMRF_SYSTEM);
+ }
+ return TRUE;
+}
+
+/* This can go away now! */
BOOL FASTCALL
IntSwitchCaretShowing(PVOID Info)
{
@@ -120,102 +297,6 @@
return FALSE;
}
-
-#if 0 // Unused
-static
-VOID FASTCALL
-co_IntDrawCaret(HWND hWnd)
-{
- PTHREADINFO pti;
- PUSER_MESSAGE_QUEUE ThreadQueue;
-
- pti = PsGetCurrentThreadWin32Thread();
- ThreadQueue = pti->MessageQueue;
-
- if(ThreadQueue->CaretInfo->hWnd && ThreadQueue->CaretInfo->Visible
&&
- ThreadQueue->CaretInfo->Showing)
- {
- co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER,
0);
- ThreadQueue->CaretInfo->Showing = 1;
- }
-}
-#endif
-
-
-
-BOOL FASTCALL co_UserHideCaret(PWND Window OPTIONAL)
-{
- PTHREADINFO pti;
- PUSER_MESSAGE_QUEUE ThreadQueue;
-
- if (Window) ASSERT_REFS_CO(Window);
-
- if(Window && Window->head.pti->pEThread != PsGetCurrentThread())
- {
- EngSetLastError(ERROR_ACCESS_DENIED);
- return FALSE;
- }
-
- pti = PsGetCurrentThreadWin32Thread();
- ThreadQueue = pti->MessageQueue;
-
- if(Window && ThreadQueue->CaretInfo->hWnd != Window->head.h)
- {
- EngSetLastError(ERROR_ACCESS_DENIED);
- return FALSE;
- }
-
- if(ThreadQueue->CaretInfo->Visible)
- {
- PWND pwnd = UserGetWindowObject(ThreadQueue->CaretInfo->hWnd);
- IntKillTimer(pwnd, IDCARETTIMER, TRUE);
-
- co_IntHideCaret(ThreadQueue->CaretInfo);
- ThreadQueue->CaretInfo->Visible = 0;
- ThreadQueue->CaretInfo->Showing = 0;
- }
-
- return TRUE;
-}
-
-
-BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL)
-{
- PTHREADINFO pti;
- PUSER_MESSAGE_QUEUE ThreadQueue;
- PWND pWnd = NULL;
-
- if (Window) ASSERT_REFS_CO(Window);
-
- if(Window && Window->head.pti->pEThread != PsGetCurrentThread())
- {
- EngSetLastError(ERROR_ACCESS_DENIED);
- return FALSE;
- }
-
- pti = PsGetCurrentThreadWin32Thread();
- ThreadQueue = pti->MessageQueue;
-
- if(Window && ThreadQueue->CaretInfo->hWnd != Window->head.h)
- {
- EngSetLastError(ERROR_ACCESS_DENIED);
- return FALSE;
- }
-
- if (!ThreadQueue->CaretInfo->Visible)
- {
- ThreadQueue->CaretInfo->Visible = 1;
- pWnd = ValidateHwndNoErr(ThreadQueue->CaretInfo->hWnd);
- if (!ThreadQueue->CaretInfo->Showing && pWnd)
- {
- co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER,
0);
- IntNotifyWinEvent(EVENT_OBJECT_SHOW, pWnd, OBJID_CARET, OBJID_CARET, 0);
- }
- IntSetTimer(pWnd, IDCARETTIMER, gpsi->dtCaretBlink, NULL, TMRF_SYSTEM);
- }
- return TRUE;
-}
-
/* SYSCALLS *****************************************************************/
@@ -277,7 +358,11 @@
}
ThreadQueue->CaretInfo->Visible = 0;
ThreadQueue->CaretInfo->Showing = 0;
+
+ IntSetTimer( Window, IDCARETTIMER, gpsi->dtCaretBlink, CaretSystemTimerProc,
TMRF_SYSTEM );
+
IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_CARET, CHILDID_SELF, 0);
+
RETURN(TRUE);
CLEANUP: