From 52c74f0cb6855170f75da63a956f46d9a7913f4c Mon Sep 17 00:00:00 2001 From: James Tabor Date: Thu, 7 Jun 2012 12:05:17 +0000 Subject: [PATCH] [Win32SS] - Fix crash and pass all wine CursorIcon test_SetCursor and test_ShowCursor. svn path=/trunk/; revision=56707 --- reactos/win32ss/include/ntuser.h | 3 +- reactos/win32ss/user/ntuser/input.c | 8 +++- reactos/win32ss/user/ntuser/main.c | 12 ++++- reactos/win32ss/user/ntuser/misc.c | 4 ++ reactos/win32ss/user/ntuser/msgqueue.c | 47 ++++++++++++------- reactos/win32ss/user/ntuser/msgqueue.h | 3 +- reactos/win32ss/user/ntuser/win32.h | 1 + .../win32ss/user/user32/windows/cursoricon.c | 7 +-- 8 files changed, 56 insertions(+), 29 deletions(-) diff --git a/reactos/win32ss/include/ntuser.h b/reactos/win32ss/include/ntuser.h index 91abf8fabb7..b0f8732b0ee 100644 --- a/reactos/win32ss/include/ntuser.h +++ b/reactos/win32ss/include/ntuser.h @@ -2184,7 +2184,8 @@ enum ThreadStateRoutines THREADSTATE_GETMESSAGETIME, THREADSTATE_GETINPUTSTATE, THREADSTATE_UPTIMELASTREAD, - THREADSTATE_FOREGROUNDTHREAD + THREADSTATE_FOREGROUNDTHREAD, + THREADSTATE_GETCURSOR }; DWORD_PTR diff --git a/reactos/win32ss/user/ntuser/input.c b/reactos/win32ss/user/ntuser/input.c index 8787b4a4a6e..2dcb5e7f73f 100644 --- a/reactos/win32ss/user/ntuser/input.c +++ b/reactos/win32ss/user/ntuser/input.c @@ -418,13 +418,15 @@ UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach) pai->pti1 = ptiFrom; pai->pti2 = ptiTo; gpai = pai; - ERR("Attach Allocated! ptiFrom 0x%p ptiTo 0x%p\n",ptiFrom,ptiTo); + TRACE("Attach Allocated! ptiFrom 0x%p ptiTo 0x%p\n",ptiFrom,ptiTo); + ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel; ptiFrom->pqAttach = ptiFrom->MessageQueue; ptiFrom->MessageQueue = ptiTo->MessageQueue; // FIXME: conditions? ptiFrom->MessageQueue->spwndActive = ptiFrom->pqAttach->spwndActive; ptiFrom->MessageQueue->spwndFocus = ptiFrom->pqAttach->spwndFocus; + ptiFrom->MessageQueue->CursorObject = ptiFrom->pqAttach->CursorObject; } else /* If clear, unlink and free it. */ { @@ -447,13 +449,15 @@ UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach) if (paiprev) paiprev->paiNext = pai->paiNext; ExFreePoolWithTag(pai, USERTAG_ATTACHINFO); - ERR("Attach Free! ptiFrom 0x%p ptiTo 0x%p\n",ptiFrom,ptiTo); + TRACE("Attach Free! ptiFrom 0x%p ptiTo 0x%p\n",ptiFrom,ptiTo); ptiFrom->MessageQueue = ptiFrom->pqAttach; // FIXME: conditions? + ptiFrom->MessageQueue->CursorObject = NULL; ptiFrom->MessageQueue->spwndActive = NULL; ptiFrom->MessageQueue->spwndFocus = NULL; ptiFrom->pqAttach = NULL; + ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel; } /* Note that key state, which can be ascertained by calls to the GetKeyState or GetKeyboardState function, is reset after a call to AttachThreadInput. diff --git a/reactos/win32ss/user/ntuser/main.c b/reactos/win32ss/user/ntuser/main.c index 8d7d7e1674a..d08d1c52260 100644 --- a/reactos/win32ss/user/ntuser/main.c +++ b/reactos/win32ss/user/ntuser/main.c @@ -462,9 +462,19 @@ UserDestroyThreadInfo(struct _ETHREAD *Thread) } } + if (ptiCurrent->pqAttach && ptiCurrent->MessageQueue) + { + PTHREADINFO ptiTo; + ptiTo = PsGetThreadWin32Thread(ptiCurrent->MessageQueue->Thread); + TRACE_CH(UserThread,"Attached Thread is getting switched!\n"); + UserAttachThreadInput( ptiCurrent, ptiTo, FALSE); + } + /* Free the message queue */ if(ptiCurrent->MessageQueue) - MsqDestroyMessageQueue(ptiCurrent->MessageQueue); + { + MsqDestroyMessageQueue(ptiCurrent->MessageQueue); + } /* Find the THREADINFO in the PROCESSINFO's list */ ppti = &ppiCurrent->ptiList; diff --git a/reactos/win32ss/user/ntuser/misc.c b/reactos/win32ss/user/ntuser/misc.c index 0ed1e37c001..37f14e891d0 100644 --- a/reactos/win32ss/user/ntuser/misc.c +++ b/reactos/win32ss/user/ntuser/misc.c @@ -225,6 +225,10 @@ NtUserGetThreadState( case THREADSTATE_FOREGROUNDTHREAD: ret = (gpqForeground == GetW32ThreadInfo()->MessageQueue); break; + case THREADSTATE_GETCURSOR: + ret = (DWORD_PTR) (GetW32ThreadInfo()->MessageQueue->CursorObject ? + UserHMGetHandle(GetW32ThreadInfo()->MessageQueue->CursorObject) : 0); + break; } TRACE("Leave NtUserGetThreadState, ret=%i\n", ret); diff --git a/reactos/win32ss/user/ntuser/msgqueue.c b/reactos/win32ss/user/ntuser/msgqueue.c index 1e4e119197e..ec02c1c6393 100644 --- a/reactos/win32ss/user/ntuser/msgqueue.c +++ b/reactos/win32ss/user/ntuser/msgqueue.c @@ -46,8 +46,7 @@ IntChildrenWindowFromPoint(PWND pWndTop, INT x, INT y) if ((pWndTop->style & WS_DISABLED)) return NULL; if (!IntPtInWindow(pWndTop, x, y)) return NULL; - if (x - pWndTop->rcClient.left < pWndTop->rcClient.right && - y - pWndTop->rcClient.top < pWndTop->rcClient.bottom ) + if (RECTL_bPointInRect(&pWndTop->rcClient, x, y)) { for (pWnd = pWndTop->spwndChild; pWnd != NULL; @@ -130,7 +129,7 @@ UserSetCursor( MessageQueue->CursorObject = NewCursor; /* If cursor is not visible we have nothing to do */ - if (MessageQueue->ShowingCursor < 0) + if (MessageQueue->iCursorLevel < 0) return OldCursor; /* Update cursor if this message queue controls it */ @@ -179,15 +178,16 @@ int UserShowCursor(BOOL bShow) MessageQueue = pti->MessageQueue; /* Update counter */ - MessageQueue->ShowingCursor += bShow ? 1 : -1; + MessageQueue->iCursorLevel += bShow ? 1 : -1; + pti->iCursorLevel += bShow ? 1 : -1; /* Check for trivial cases */ - if ((bShow && MessageQueue->ShowingCursor != 0) || - (!bShow && MessageQueue->ShowingCursor != -1)) + if ((bShow && MessageQueue->iCursorLevel != 0) || + (!bShow && MessageQueue->iCursorLevel != -1)) { /* Note: w don't update global info here because it is used only internally to check if cursor is visible */ - return MessageQueue->ShowingCursor; + return MessageQueue->iCursorLevel; } /* Check if cursor is above window owned by this MessageQueue */ @@ -208,10 +208,10 @@ int UserShowCursor(BOOL bShow) } /* Update global info */ - IntGetSysCursorInfo()->ShowingCursor = MessageQueue->ShowingCursor; + IntGetSysCursorInfo()->ShowingCursor = MessageQueue->iCursorLevel; } - return MessageQueue->ShowingCursor; + return MessageQueue->iCursorLevel; } DWORD FASTCALL @@ -382,6 +382,10 @@ MsqWakeQueue(PUSER_MESSAGE_QUEUE Queue, DWORD MessageBits, BOOL KeyEvent) { PTHREADINFO pti; + if (Queue->QF_flags & QF_INDESTROY) + { + ERR("This Message Queue is in Destroy!\n"); + } pti = Queue->Thread->Tcb.Win32Thread; pti->pcti->fsWakeBits |= MessageBits; pti->pcti->fsChangeBits |= MessageBits; @@ -482,6 +486,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook PDESKTOP pDesk; PWND pwnd, pwndDesktop; HDC hdcScreen; + PUSER_MESSAGE_QUEUE MessageQueue; PSYSTEM_CURSORINFO CurInfo; KeQueryTickCount(&LargeTickCount); @@ -541,14 +546,20 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook /* Check if we found a window */ if (Msg->hwnd != NULL && pwnd != NULL) { + MessageQueue = pwnd->head.pti->MessageQueue; + + if ( pwnd->head.pti->TIF_flags & TIF_INCLEANUP || MessageQueue->QF_flags & QF_INDESTROY) + { + ERR("Mouse is over the Window Thread is Dead!\n"); + return; + } + if (Msg->message == WM_MOUSEMOVE) { - PUSER_MESSAGE_QUEUE MessageQueue = pwnd->head.pti->MessageQueue; - - /* Check if cursor should be visible */ + /* Check if cursor should be visible */ if(hdcScreen && MessageQueue->CursorObject && - MessageQueue->ShowingCursor >= 0) + MessageQueue->iCursorLevel >= 0) { /* Check if shape has changed */ if(CurInfo->CurrentCursorObject != MessageQueue->CursorObject) @@ -569,7 +580,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook GreMovePointer(hdcScreen, -1, -1); /* Update global cursor info */ - CurInfo->ShowingCursor = MessageQueue->ShowingCursor; + CurInfo->ShowingCursor = MessageQueue->iCursorLevel; CurInfo->CurrentCursorObject = MessageQueue->CursorObject; gpqCursor = MessageQueue; @@ -579,7 +590,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook else { TRACE("Posting mouse message to hwnd=0x%x!\n", UserHMGetHandle(pwnd)); - MsqPostMessage(pwnd->head.pti->MessageQueue, Msg, TRUE, QS_MOUSEBUTTON); + MsqPostMessage(MessageQueue, Msg, TRUE, QS_MOUSEBUTTON); } } else if (hdcScreen) @@ -1532,7 +1543,7 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT /* Activate the window if needed */ - if (msg->hwnd != UserGetForegroundWindow()) + if (pwndMsg != pti->MessageQueue->spwndActive) //msg->hwnd != UserGetForegroundWindow()) { PWND pwndTop = pwndMsg; while (pwndTop) @@ -1559,7 +1570,7 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT /* fall through */ case MA_ACTIVATE: case 0: - if(!co_IntMouseActivateWindow(pwndMsg)) eatMsg = TRUE; + if (!co_IntMouseActivateWindow( pwndTop )) eatMsg = TRUE; break; default: ERR( "unknown WM_MOUSEACTIVATE code %d\n", ret ); @@ -1865,7 +1876,7 @@ MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQu MessageQueue->LastMsgRead = LargeTickCount.u.LowPart; MessageQueue->spwndFocus = NULL; MessageQueue->NewMessagesHandle = NULL; - MessageQueue->ShowingCursor = 0; + MessageQueue->iCursorLevel = 0; MessageQueue->CursorObject = NULL; RtlCopyMemory(MessageQueue->afKeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState)); diff --git a/reactos/win32ss/user/ntuser/msgqueue.h b/reactos/win32ss/user/ntuser/msgqueue.h index 6e5ba59a8c6..c8327377143 100644 --- a/reactos/win32ss/user/ntuser/msgqueue.h +++ b/reactos/win32ss/user/ntuser/msgqueue.h @@ -92,6 +92,7 @@ typedef struct _USER_MESSAGE_QUEUE PTHRDCARETINFO CaretInfo; /* Message Queue Flags */ DWORD QF_flags; + DWORD cThreads; // Shared message queue counter. /* Queue state tracking */ // Send list QS_SENDMESSAGE @@ -108,7 +109,7 @@ typedef struct _USER_MESSAGE_QUEUE BYTE afKeyState[256 * 2 / 8]; // 2 bits per key /* Showing cursor counter (value>=0 - cursor visible, value<0 - cursor hidden) */ - INT ShowingCursor; + INT iCursorLevel; /* Cursor object */ PCURICON_OBJECT CursorObject; diff --git a/reactos/win32ss/user/ntuser/win32.h b/reactos/win32ss/user/ntuser/win32.h index 3ec0f54adcb..2f23fbb9975 100644 --- a/reactos/win32ss/user/ntuser/win32.h +++ b/reactos/win32ss/user/ntuser/win32.h @@ -97,6 +97,7 @@ typedef struct _THREADINFO HANDLE hEventQueueClient; PKEVENT pEventQueueServer; LIST_ENTRY PtiLink; + INT iCursorLevel; POINT ptLast; LIST_ENTRY aphkStart[NB_HOOKS]; diff --git a/reactos/win32ss/user/user32/windows/cursoricon.c b/reactos/win32ss/user/user32/windows/cursoricon.c index eef5b24db68..45d30f822a9 100644 --- a/reactos/win32ss/user/user32/windows/cursoricon.c +++ b/reactos/win32ss/user/user32/windows/cursoricon.c @@ -1253,12 +1253,7 @@ INT WINAPI /*DECLSPEC_HOTPATCH*/ ShowCursor( BOOL bShow ) */ HCURSOR WINAPI GetCursor(void) { - CURSORINFO ci; - ci.cbSize = sizeof(CURSORINFO); - if(NtUserGetCursorInfo(&ci)) - return ci.hCursor; - else - return (HCURSOR)0; + return (HCURSOR)NtUserGetThreadState(THREADSTATE_GETCURSOR); }