[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_GETINPUTSTATE,
THREADSTATE_UPTIMELASTREAD,
THREADSTATE_FOREGROUNDTHREAD
THREADSTATE_FOREGROUNDTHREAD,
THREADSTATE_GETCURSOR
};
DWORD_PTR

View file

@ -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.

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

View file

@ -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);

View file

@ -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));

View file

@ -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;

View file

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

View file

@ -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);
}