[Win32SS]

- Fix crash and pass all wine CursorIcon test_SetCursor and test_ShowCursor.

svn path=/trunk/; revision=56707
This commit is contained in:
James Tabor 2012-06-07 12:05:17 +00:00
parent 90849a2374
commit 52c74f0cb6
8 changed files with 56 additions and 29 deletions

View file

@ -2184,7 +2184,8 @@ enum ThreadStateRoutines
THREADSTATE_GETMESSAGETIME, THREADSTATE_GETMESSAGETIME,
THREADSTATE_GETINPUTSTATE, THREADSTATE_GETINPUTSTATE,
THREADSTATE_UPTIMELASTREAD, THREADSTATE_UPTIMELASTREAD,
THREADSTATE_FOREGROUNDTHREAD THREADSTATE_FOREGROUNDTHREAD,
THREADSTATE_GETCURSOR
}; };
DWORD_PTR DWORD_PTR

View file

@ -418,13 +418,15 @@ UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach)
pai->pti1 = ptiFrom; pai->pti1 = ptiFrom;
pai->pti2 = ptiTo; pai->pti2 = ptiTo;
gpai = pai; 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->pqAttach = ptiFrom->MessageQueue;
ptiFrom->MessageQueue = ptiTo->MessageQueue; ptiFrom->MessageQueue = ptiTo->MessageQueue;
// FIXME: conditions? // FIXME: conditions?
ptiFrom->MessageQueue->spwndActive = ptiFrom->pqAttach->spwndActive; ptiFrom->MessageQueue->spwndActive = ptiFrom->pqAttach->spwndActive;
ptiFrom->MessageQueue->spwndFocus = ptiFrom->pqAttach->spwndFocus; ptiFrom->MessageQueue->spwndFocus = ptiFrom->pqAttach->spwndFocus;
ptiFrom->MessageQueue->CursorObject = ptiFrom->pqAttach->CursorObject;
} }
else /* If clear, unlink and free it. */ else /* If clear, unlink and free it. */
{ {
@ -447,13 +449,15 @@ UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach)
if (paiprev) paiprev->paiNext = pai->paiNext; if (paiprev) paiprev->paiNext = pai->paiNext;
ExFreePoolWithTag(pai, USERTAG_ATTACHINFO); 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; ptiFrom->MessageQueue = ptiFrom->pqAttach;
// FIXME: conditions? // FIXME: conditions?
ptiFrom->MessageQueue->CursorObject = NULL;
ptiFrom->MessageQueue->spwndActive = NULL; ptiFrom->MessageQueue->spwndActive = NULL;
ptiFrom->MessageQueue->spwndFocus = NULL; ptiFrom->MessageQueue->spwndFocus = NULL;
ptiFrom->pqAttach = NULL; ptiFrom->pqAttach = NULL;
ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
} }
/* Note that key state, which can be ascertained by calls to the GetKeyState /* Note that key state, which can be ascertained by calls to the GetKeyState
or GetKeyboardState function, is reset after a call to AttachThreadInput. or GetKeyboardState function, is reset after a call to AttachThreadInput.

View file

@ -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 */ /* Free the message queue */
if(ptiCurrent->MessageQueue) if(ptiCurrent->MessageQueue)
MsqDestroyMessageQueue(ptiCurrent->MessageQueue); {
MsqDestroyMessageQueue(ptiCurrent->MessageQueue);
}
/* Find the THREADINFO in the PROCESSINFO's list */ /* Find the THREADINFO in the PROCESSINFO's list */
ppti = &ppiCurrent->ptiList; ppti = &ppiCurrent->ptiList;

View file

@ -225,6 +225,10 @@ NtUserGetThreadState(
case THREADSTATE_FOREGROUNDTHREAD: case THREADSTATE_FOREGROUNDTHREAD:
ret = (gpqForeground == GetW32ThreadInfo()->MessageQueue); ret = (gpqForeground == GetW32ThreadInfo()->MessageQueue);
break; break;
case THREADSTATE_GETCURSOR:
ret = (DWORD_PTR) (GetW32ThreadInfo()->MessageQueue->CursorObject ?
UserHMGetHandle(GetW32ThreadInfo()->MessageQueue->CursorObject) : 0);
break;
} }
TRACE("Leave NtUserGetThreadState, ret=%i\n", ret); TRACE("Leave NtUserGetThreadState, ret=%i\n", ret);

View file

@ -46,8 +46,7 @@ IntChildrenWindowFromPoint(PWND pWndTop, INT x, INT y)
if ((pWndTop->style & WS_DISABLED)) return NULL; if ((pWndTop->style & WS_DISABLED)) return NULL;
if (!IntPtInWindow(pWndTop, x, y)) return NULL; if (!IntPtInWindow(pWndTop, x, y)) return NULL;
if (x - pWndTop->rcClient.left < pWndTop->rcClient.right && if (RECTL_bPointInRect(&pWndTop->rcClient, x, y))
y - pWndTop->rcClient.top < pWndTop->rcClient.bottom )
{ {
for (pWnd = pWndTop->spwndChild; for (pWnd = pWndTop->spwndChild;
pWnd != NULL; pWnd != NULL;
@ -130,7 +129,7 @@ UserSetCursor(
MessageQueue->CursorObject = NewCursor; MessageQueue->CursorObject = NewCursor;
/* If cursor is not visible we have nothing to do */ /* If cursor is not visible we have nothing to do */
if (MessageQueue->ShowingCursor < 0) if (MessageQueue->iCursorLevel < 0)
return OldCursor; return OldCursor;
/* Update cursor if this message queue controls it */ /* Update cursor if this message queue controls it */
@ -179,15 +178,16 @@ int UserShowCursor(BOOL bShow)
MessageQueue = pti->MessageQueue; MessageQueue = pti->MessageQueue;
/* Update counter */ /* Update counter */
MessageQueue->ShowingCursor += bShow ? 1 : -1; MessageQueue->iCursorLevel += bShow ? 1 : -1;
pti->iCursorLevel += bShow ? 1 : -1;
/* Check for trivial cases */ /* Check for trivial cases */
if ((bShow && MessageQueue->ShowingCursor != 0) || if ((bShow && MessageQueue->iCursorLevel != 0) ||
(!bShow && MessageQueue->ShowingCursor != -1)) (!bShow && MessageQueue->iCursorLevel != -1))
{ {
/* Note: w don't update global info here because it is used only /* Note: w don't update global info here because it is used only
internally to check if cursor is visible */ internally to check if cursor is visible */
return MessageQueue->ShowingCursor; return MessageQueue->iCursorLevel;
} }
/* Check if cursor is above window owned by this MessageQueue */ /* Check if cursor is above window owned by this MessageQueue */
@ -208,10 +208,10 @@ int UserShowCursor(BOOL bShow)
} }
/* Update global info */ /* Update global info */
IntGetSysCursorInfo()->ShowingCursor = MessageQueue->ShowingCursor; IntGetSysCursorInfo()->ShowingCursor = MessageQueue->iCursorLevel;
} }
return MessageQueue->ShowingCursor; return MessageQueue->iCursorLevel;
} }
DWORD FASTCALL DWORD FASTCALL
@ -382,6 +382,10 @@ MsqWakeQueue(PUSER_MESSAGE_QUEUE Queue, DWORD MessageBits, BOOL KeyEvent)
{ {
PTHREADINFO pti; PTHREADINFO pti;
if (Queue->QF_flags & QF_INDESTROY)
{
ERR("This Message Queue is in Destroy!\n");
}
pti = Queue->Thread->Tcb.Win32Thread; pti = Queue->Thread->Tcb.Win32Thread;
pti->pcti->fsWakeBits |= MessageBits; pti->pcti->fsWakeBits |= MessageBits;
pti->pcti->fsChangeBits |= MessageBits; pti->pcti->fsChangeBits |= MessageBits;
@ -482,6 +486,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
PDESKTOP pDesk; PDESKTOP pDesk;
PWND pwnd, pwndDesktop; PWND pwnd, pwndDesktop;
HDC hdcScreen; HDC hdcScreen;
PUSER_MESSAGE_QUEUE MessageQueue;
PSYSTEM_CURSORINFO CurInfo; PSYSTEM_CURSORINFO CurInfo;
KeQueryTickCount(&LargeTickCount); KeQueryTickCount(&LargeTickCount);
@ -541,14 +546,20 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
/* Check if we found a window */ /* Check if we found a window */
if (Msg->hwnd != NULL && pwnd != NULL) 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) 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 && if(hdcScreen &&
MessageQueue->CursorObject && MessageQueue->CursorObject &&
MessageQueue->ShowingCursor >= 0) MessageQueue->iCursorLevel >= 0)
{ {
/* Check if shape has changed */ /* Check if shape has changed */
if(CurInfo->CurrentCursorObject != MessageQueue->CursorObject) if(CurInfo->CurrentCursorObject != MessageQueue->CursorObject)
@ -569,7 +580,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
GreMovePointer(hdcScreen, -1, -1); GreMovePointer(hdcScreen, -1, -1);
/* Update global cursor info */ /* Update global cursor info */
CurInfo->ShowingCursor = MessageQueue->ShowingCursor; CurInfo->ShowingCursor = MessageQueue->iCursorLevel;
CurInfo->CurrentCursorObject = MessageQueue->CursorObject; CurInfo->CurrentCursorObject = MessageQueue->CursorObject;
gpqCursor = MessageQueue; gpqCursor = MessageQueue;
@ -579,7 +590,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
else else
{ {
TRACE("Posting mouse message to hwnd=0x%x!\n", UserHMGetHandle(pwnd)); 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) else if (hdcScreen)
@ -1532,7 +1543,7 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT
/* Activate the window if needed */ /* Activate the window if needed */
if (msg->hwnd != UserGetForegroundWindow()) if (pwndMsg != pti->MessageQueue->spwndActive) //msg->hwnd != UserGetForegroundWindow())
{ {
PWND pwndTop = pwndMsg; PWND pwndTop = pwndMsg;
while (pwndTop) while (pwndTop)
@ -1559,7 +1570,7 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT
/* fall through */ /* fall through */
case MA_ACTIVATE: case MA_ACTIVATE:
case 0: case 0:
if(!co_IntMouseActivateWindow(pwndMsg)) eatMsg = TRUE; if (!co_IntMouseActivateWindow( pwndTop )) eatMsg = TRUE;
break; break;
default: default:
ERR( "unknown WM_MOUSEACTIVATE code %d\n", ret ); 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->LastMsgRead = LargeTickCount.u.LowPart;
MessageQueue->spwndFocus = NULL; MessageQueue->spwndFocus = NULL;
MessageQueue->NewMessagesHandle = NULL; MessageQueue->NewMessagesHandle = NULL;
MessageQueue->ShowingCursor = 0; MessageQueue->iCursorLevel = 0;
MessageQueue->CursorObject = NULL; MessageQueue->CursorObject = NULL;
RtlCopyMemory(MessageQueue->afKeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState)); RtlCopyMemory(MessageQueue->afKeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState));

View file

@ -92,6 +92,7 @@ typedef struct _USER_MESSAGE_QUEUE
PTHRDCARETINFO CaretInfo; PTHRDCARETINFO CaretInfo;
/* Message Queue Flags */ /* Message Queue Flags */
DWORD QF_flags; DWORD QF_flags;
DWORD cThreads; // Shared message queue counter.
/* Queue state tracking */ /* Queue state tracking */
// Send list QS_SENDMESSAGE // Send list QS_SENDMESSAGE
@ -108,7 +109,7 @@ typedef struct _USER_MESSAGE_QUEUE
BYTE afKeyState[256 * 2 / 8]; // 2 bits per key BYTE afKeyState[256 * 2 / 8]; // 2 bits per key
/* Showing cursor counter (value>=0 - cursor visible, value<0 - cursor hidden) */ /* Showing cursor counter (value>=0 - cursor visible, value<0 - cursor hidden) */
INT ShowingCursor; INT iCursorLevel;
/* Cursor object */ /* Cursor object */
PCURICON_OBJECT CursorObject; PCURICON_OBJECT CursorObject;

View file

@ -97,6 +97,7 @@ typedef struct _THREADINFO
HANDLE hEventQueueClient; HANDLE hEventQueueClient;
PKEVENT pEventQueueServer; PKEVENT pEventQueueServer;
LIST_ENTRY PtiLink; LIST_ENTRY PtiLink;
INT iCursorLevel;
POINT ptLast; POINT ptLast;
LIST_ENTRY aphkStart[NB_HOOKS]; LIST_ENTRY aphkStart[NB_HOOKS];

View file

@ -1253,12 +1253,7 @@ INT WINAPI /*DECLSPEC_HOTPATCH*/ ShowCursor( BOOL bShow )
*/ */
HCURSOR WINAPI GetCursor(void) HCURSOR WINAPI GetCursor(void)
{ {
CURSORINFO ci; return (HCURSOR)NtUserGetThreadState(THREADSTATE_GETCURSOR);
ci.cbSize = sizeof(CURSORINFO);
if(NtUserGetCursorInfo(&ci))
return ci.hCursor;
else
return (HCURSOR)0;
} }