Author: jimtabor Date: Fri May 10 22:28:18 2013 New Revision: 58986
URL: http://svn.reactos.org/svn/reactos?rev=58986&view=rev Log: [Win32k] - ATI fixup CORE-6551. - Giannis Adamopoulos fragment patch 18.
Modified: trunk/reactos/include/reactos/undocuser.h trunk/reactos/win32ss/user/ntuser/event.c trunk/reactos/win32ss/user/ntuser/focus.c trunk/reactos/win32ss/user/ntuser/hook.c trunk/reactos/win32ss/user/ntuser/keyboard.c trunk/reactos/win32ss/user/ntuser/main.c trunk/reactos/win32ss/user/ntuser/message.c trunk/reactos/win32ss/user/ntuser/misc.c trunk/reactos/win32ss/user/ntuser/msgqueue.c trunk/reactos/win32ss/user/ntuser/msgqueue.h trunk/reactos/win32ss/user/ntuser/painting.c trunk/reactos/win32ss/user/ntuser/simplecall.c trunk/reactos/win32ss/user/ntuser/timer.c trunk/reactos/win32ss/user/ntuser/win32.h trunk/reactos/win32ss/user/ntuser/window.c
Modified: trunk/reactos/include/reactos/undocuser.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/undocuser.h... ============================================================================== --- trunk/reactos/include/reactos/undocuser.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/undocuser.h [iso-8859-1] Fri May 10 22:28:18 2013 @@ -76,6 +76,10 @@
/* Non SDK Queue state flags. */ #define QS_SMRESULT 0x8000 /* see "Undoc. Windows" */ +// +#define QS_EVENT 0x2000 +#define QS_SYSEVENT (QS_EVENT|QS_SENDMESSAGE) +//
// // Definitions used by WM_CLIENTSHUTDOWN
Modified: trunk/reactos/win32ss/user/ntuser/event.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/event.c... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/event.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/event.c [iso-8859-1] Fri May 10 22:28:18 2013 @@ -113,7 +113,7 @@
/* FIXME: Should get timeout from * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */ - Status = co_MsqSendMessage( pEH->head.pti->MessageQueue, + Status = co_MsqSendMessage( pEH->head.pti, hwnd, event, 0,
Modified: trunk/reactos/win32ss/user/ntuser/focus.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/focus.c... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/focus.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/focus.c [iso-8859-1] Fri May 10 22:28:18 2013 @@ -296,18 +296,18 @@ VOID FASTCALL FindRemoveAsyncMsg(PWND Wnd) { - PUSER_MESSAGE_QUEUE MessageQueue; + PTHREADINFO pti; PUSER_SENT_MESSAGE Message; PLIST_ENTRY Entry;
if (!Wnd) return;
- MessageQueue = Wnd->head.pti->MessageQueue; - - if (!IsListEmpty(&MessageQueue->SentMessagesListHead)) + pti = Wnd->head.pti; + + if (!IsListEmpty(&pti->SentMessagesListHead)) { // Scan sent queue messages to see if we received async messages. - Entry = MessageQueue->SentMessagesListHead.Flink; + Entry = pti->SentMessagesListHead.Flink; Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry); do { @@ -321,7 +321,7 @@ Entry = Message->ListEntry.Flink; Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry); } - while (Entry != &MessageQueue->SentMessagesListHead); + while (Entry != &pti->SentMessagesListHead); } }
@@ -787,7 +787,7 @@ } }
- hWndPrev = MsqSetStateWindow(ThreadQueue, MSQ_STATE_CAPTURE, hWnd); + hWndPrev = MsqSetStateWindow(pti, MSQ_STATE_CAPTURE, hWnd);
if (hWndPrev) { @@ -815,8 +815,8 @@ MOUSEINPUT mi; /// These are HACKS! /* Also remove other windows if not capturing anymore */ - MsqSetStateWindow(ThreadQueue, MSQ_STATE_MENUOWNER, NULL); - MsqSetStateWindow(ThreadQueue, MSQ_STATE_MOVESIZE, NULL); + MsqSetStateWindow(pti, MSQ_STATE_MENUOWNER, NULL); + MsqSetStateWindow(pti, MSQ_STATE_MOVESIZE, NULL); /// /* Somebody may have missed some mouse movements */ mi.dx = 0;
Modified: trunk/reactos/win32ss/user/ntuser/hook.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/hook.c?... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/hook.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/hook.c [iso-8859-1] Fri May 10 22:28:18 2013 @@ -295,7 +295,7 @@
/* FIXME: Should get timeout from * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */ - Status = co_MsqSendMessage( pti->MessageQueue, + Status = co_MsqSendMessage( pti, IntToPtr(Code), // hWnd Hook->HookId, // Msg wParam,
Modified: trunk/reactos/win32ss/user/ntuser/keyboard.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/keyboar... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/keyboard.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/keyboard.c [iso-8859-1] Fri May 10 22:28:18 2013 @@ -763,6 +763,7 @@ { WORD wSimpleVk = 0, wFixedVk, wVk2; PUSER_MESSAGE_QUEUE pFocusQueue; + PTHREADINFO pti; BOOL bExt = (dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE; BOOL bIsDown = (dwFlags & KEYEVENTF_KEYUP) ? FALSE : TRUE; BOOL bPacket = (dwFlags & KEYEVENTF_UNICODE) ? TRUE : FALSE; @@ -872,6 +873,14 @@ // Focus can be null so going with Active. WM_SYSKEYXXX last wine Win test_keyboard_input. Wnd = pFocusQueue->spwndActive; } + + if ( !Wnd || Wnd->state2 & WNDS2_INDESTROY || Wnd->state & WNDS_DESTROYED ) + { + ERR("ProcessKeyEvent Active Focus window is dead!\n"); + return FALSE; + } + + pti = Wnd->head.pti;
/* Init message */ Msg.hwnd = UserHMGetHandle(Wnd); @@ -900,7 +909,7 @@
/* Post a keyboard message */ TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam); - MsqPostMessage(pFocusQueue, &Msg, TRUE, QS_KEY, 0); + MsqPostMessage(pti, &Msg, TRUE, QS_KEY, 0); }
return TRUE; @@ -913,7 +922,6 @@ PKL pKl = NULL; PKBDTABLES pKbdTbl; PUSER_MESSAGE_QUEUE pFocusQueue; - struct _ETHREAD *pFocusThread; LARGE_INTEGER LargeTickCount; DWORD dwTime; BOOL bExt = (pKbdInput->dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE; @@ -923,11 +931,9 @@ /* Find the target thread whose locale is in effect */ pFocusQueue = IntGetFocusMessageQueue();
- if (pFocusQueue) - { - pFocusThread = pFocusQueue->Thread; - if (pFocusThread && pFocusThread->Tcb.Win32Thread) - pKl = ((PTHREADINFO)pFocusThread->Tcb.Win32Thread)->KeyboardLayout; + if (pFocusQueue && pFocusQueue->ptiOwner) + { + pKl = pFocusQueue->ptiOwner->KeyboardLayout; }
if (!pKl) @@ -997,7 +1003,6 @@ PKL pKl = NULL; PKBDTABLES pKbdTbl; PUSER_MESSAGE_QUEUE pFocusQueue; - struct _ETHREAD *pFocusThread;
/* Calculate scan code with prefix */ wScanCode = pKbdInputData->MakeCode & 0x7F; @@ -1009,11 +1014,9 @@ /* Find the target thread whose locale is in effect */ pFocusQueue = IntGetFocusMessageQueue();
- if (pFocusQueue) - { - pFocusThread = pFocusQueue->Thread; - if (pFocusThread && pFocusThread->Tcb.Win32Thread) - pKl = ((PTHREADINFO)pFocusThread->Tcb.Win32Thread)->KeyboardLayout; + if (pFocusQueue && pFocusQueue->ptiOwner) + { + pKl = pFocusQueue->ptiOwner->KeyboardLayout; }
if (!pKl) @@ -1121,7 +1124,7 @@ NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR; NewMsg.wParam = HIWORD(lpMsg->lParam); NewMsg.lParam = LOWORD(lpMsg->lParam); - MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY, 0); + MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0); return TRUE; }
@@ -1150,7 +1153,7 @@ { TRACE("Msg: %x '%lc' (%04x) %08x\n", NewMsg.message, wch[i], wch[i], NewMsg.lParam); NewMsg.wParam = wch[i]; - MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY, 0); + MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0); } bResult = TRUE; }
Modified: trunk/reactos/win32ss/user/ntuser/main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/main.c?... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/main.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/main.c [iso-8859-1] Fri May 10 22:28:18 2013 @@ -254,6 +254,7 @@ int i; NTSTATUS Status = STATUS_SUCCESS; PTEB pTeb; + LARGE_INTEGER LargeTickCount;
Process = Thread->ThreadsProcess;
@@ -281,8 +282,13 @@ TRACE_CH(UserThread, "Allocated pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread);
/* Initialize the THREADINFO */ + IntReferenceThreadInfo(ptiCurrent); InitializeListHead(&ptiCurrent->WindowListHead); InitializeListHead(&ptiCurrent->W32CallbackListHead); + InitializeListHead(&ptiCurrent->PostedMessagesListHead); + InitializeListHead(&ptiCurrent->SentMessagesListHead); + InitializeListHead(&ptiCurrent->DispatchingMessagesHead); + InitializeListHead(&ptiCurrent->LocalDispatchingMessagesHead); InitializeListHead(&ptiCurrent->PtiLink); for (i = 0; i < NB_HOOKS; i++) { @@ -293,6 +299,27 @@ ptiCurrent->ptiSibling = ptiCurrent->ppi->ptiList; ptiCurrent->ppi->ptiList = ptiCurrent; ptiCurrent->ppi->cThreads++; + + ptiCurrent->hEventQueueClient = NULL; + Status = ZwCreateEvent(&ptiCurrent->hEventQueueClient, EVENT_ALL_ACCESS, + NULL, SynchronizationEvent, FALSE); + if (!NT_SUCCESS(Status)) + { + goto error; + } + Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0, + ExEventObjectType, KernelMode, + (PVOID*)&ptiCurrent->pEventQueueServer, NULL); + if (!NT_SUCCESS(Status)) + { + ZwClose(ptiCurrent->hEventQueueClient); + ptiCurrent->hEventQueueClient = NULL; + goto error; + } + + KeQueryTickCount(&LargeTickCount); + ptiCurrent->timeLast = LargeTickCount.u.LowPart; + ptiCurrent->MessageQueue = MsqCreateMessageQueue(ptiCurrent); if(ptiCurrent->MessageQueue == NULL) { @@ -400,6 +427,35 @@ ERR_CH(UserThread,"UserCreateThreadInfo failed! Freeing pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread); UserDestroyThreadInfo(Thread); return Status; +} + +/* + Called from IntDereferenceThreadInfo. + */ +VOID +FASTCALL +UserDeleteW32Thread(PTHREADINFO pti) +{ + if (!pti->RefCount) + { + ERR_CH(UserThread,"UserDeleteW32Thread pti 0x%p\n",pti); + if (pti->hEventQueueClient != NULL) + ZwClose(pti->hEventQueueClient); + pti->hEventQueueClient = NULL; + + /* Free the message queue */ + if (pti->MessageQueue) + { + MsqDestroyMessageQueue(pti); + } + + MsqCleanupThreadMsgs(pti); + + IntSetThreadDesktop(NULL, TRUE); + + PsSetThreadWin32Thread(pti->pEThread, NULL); + ExFreePoolWithTag(pti, USERTAG_THREADINFO); + } }
NTSTATUS @@ -439,7 +495,7 @@ if (ptiCurrent->pqAttach && ptiCurrent->MessageQueue) { PTHREADINFO ptiTo; - ptiTo = PsGetThreadWin32Thread(ptiCurrent->MessageQueue->Thread); + ptiTo = ptiCurrent->MessageQueue->ptiOwner; TRACE_CH(UserThread,"Attached Thread ptiFrom is getting switched!\n"); if (ptiTo) UserAttachThreadInput( ptiCurrent, ptiTo, FALSE); else @@ -487,7 +543,7 @@ HOOK_DestroyThreadHooks(Thread); EVENT_DestroyThreadEvents(Thread); DestroyTimersForThread(ptiCurrent); - KeSetEvent(ptiCurrent->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); + KeSetEvent(ptiCurrent->pEventQueueServer, IO_NO_INCREMENT, FALSE); UnregisterThreadHotKeys(Thread); /* if (IsListEmpty(&ptiCurrent->WindowListHead)) @@ -520,12 +576,6 @@ } }
- /* Free the message queue */ - if (ptiCurrent->MessageQueue) - { - MsqDestroyMessageQueue(ptiCurrent); - } - /* Find the THREADINFO in the PROCESSINFO's list */ ppti = &ppiCurrent->ptiList; while (*ppti != NULL && *ppti != ptiCurrent) @@ -547,8 +597,7 @@ TRACE_CH(UserThread,"Freeing pti 0x%p\n", ptiCurrent);
/* Free the THREADINFO */ - PsSetThreadWin32Thread(Thread, NULL); - ExFreePoolWithTag(ptiCurrent, USERTAG_THREADINFO); + IntDereferenceThreadInfo(ptiCurrent);
return STATUS_SUCCESS; }
Modified: trunk/reactos/win32ss/user/ntuser/message.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/message... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/message.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/message.c [iso-8859-1] Fri May 10 22:28:18 2013 @@ -508,7 +508,7 @@ ForegroundQueue = IntGetFocusMessageQueue();
if (ForegroundQueue) - ptiForeground = ForegroundQueue->Thread->Tcb.Win32Thread; + ptiForeground = ForegroundQueue->ptiOwner;
pti = PsGetCurrentThreadWin32Thread();
@@ -762,22 +762,15 @@ { PTHREADINFO pti; LARGE_INTEGER LargeTickCount; - PUSER_MESSAGE_QUEUE ThreadQueue; BOOL RemoveMessages; UINT ProcessMask; BOOL Hit = FALSE;
pti = PsGetCurrentThreadWin32Thread(); - ThreadQueue = pti->MessageQueue;
RemoveMessages = RemoveMsg & PM_REMOVE; ProcessMask = HIWORD(RemoveMsg); - - if (ThreadQueue->ptiSysLock && ThreadQueue->ptiSysLock != pti) - { - ERR("PeekMessage: Thread Q 0x%p is locked 0x%p to another pti 0x%p!\n", ThreadQueue, ThreadQueue->ptiSysLock, pti ); - } - + /* Hint, "If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage returns all available messages (that is, no range filtering is performed)". */ if (!ProcessMask) ProcessMask = (QS_ALLPOSTMESSAGE|QS_ALLINPUT); @@ -787,11 +780,11 @@ do { KeQueryTickCount(&LargeTickCount); - ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart; + pti->timeLast = LargeTickCount.u.LowPart; pti->pcti->tickLastMsgChecked = LargeTickCount.u.LowPart;
/* Dispatch sent messages here. */ - while ( co_MsqDispatchOneSentMessage(ThreadQueue) ) + while ( co_MsqDispatchOneSentMessage(pti) ) { /* if some PM_QS* flags were specified, only handle sent messages from now on */ if (HIWORD(RemoveMsg) && !bGMSG) Hit = TRUE; // wine does this; ProcessMask = QS_SENDMESSAGE; @@ -816,7 +809,7 @@ /* Now check for normal messages. */ if (( (ProcessMask & QS_POSTMESSAGE) || (ProcessMask & QS_HOTKEY) ) && - MsqPeekMessage( ThreadQueue, + MsqPeekMessage( pti, RemoveMessages, Window, MsgFilterMin, @@ -828,18 +821,18 @@ }
/* Now look for a quit message. */ - if (ThreadQueue->QuitPosted) + if (pti->QuitPosted) { /* According to the PSDK, WM_QUIT messages are always returned, regardless of the filter specified */ Msg->hwnd = NULL; Msg->message = WM_QUIT; - Msg->wParam = ThreadQueue->QuitExitCode; + Msg->wParam = pti->exitCode; Msg->lParam = 0; if (RemoveMessages) { - ThreadQueue->QuitPosted = FALSE; - ClearMsgBitsMask(ThreadQueue, QS_POSTMESSAGE); + pti->QuitPosted = FALSE; + ClearMsgBitsMask(pti, QS_POSTMESSAGE); pti->pcti->fsWakeBits &= ~QS_ALLPOSTMESSAGE; pti->pcti->fsChangeBits &= ~QS_ALLPOSTMESSAGE; } @@ -848,7 +841,7 @@
/* Check for hardware events. */ if ((ProcessMask & QS_MOUSE) && - co_MsqPeekMouseMove( ThreadQueue, + co_MsqPeekMouseMove( pti, RemoveMessages, Window, MsgFilterMin, @@ -859,7 +852,7 @@ }
if ((ProcessMask & QS_INPUT) && - co_MsqPeekHardwareMessage( ThreadQueue, + co_MsqPeekHardwareMessage( pti, RemoveMessages, Window, MsgFilterMin, @@ -871,7 +864,7 @@ }
/* Check for sent messages again. */ - while ( co_MsqDispatchOneSentMessage(ThreadQueue) ) + while ( co_MsqDispatchOneSentMessage(pti) ) { if (HIWORD(RemoveMsg) && !bGMSG) Hit = TRUE; } @@ -912,12 +905,10 @@ UINT MsgFilterMax ) { PTHREADINFO pti; - PUSER_MESSAGE_QUEUE ThreadQueue; NTSTATUS Status = STATUS_SUCCESS; MSG Msg;
pti = PsGetCurrentThreadWin32Thread(); - ThreadQueue = pti->MessageQueue;
do { @@ -932,7 +923,7 @@ }
/* Nothing found. Wait for new messages. */ - Status = co_MsqWaitForNewMessages( ThreadQueue, + Status = co_MsqWaitForNewMessages( pti, Window, MsgFilterMin, MsgFilterMax); @@ -1027,7 +1018,7 @@
if ( bGMSG ) { - Status = co_MsqWaitForNewMessages( pti->MessageQueue, + Status = co_MsqWaitForNewMessages( pti, Window, MsgFilterMin, MsgFilterMax); @@ -1105,7 +1096,7 @@
KeQueryTickCount(&LargeTickCount); Message.time = MsqCalculateMessageTime(&LargeTickCount); - MsqPostMessage(pThread->MessageQueue, &Message, FALSE, QS_POSTMESSAGE, 0); + MsqPostMessage(pThread, &Message, FALSE, QS_POSTMESSAGE, 0); ObDereferenceObject( peThread ); return TRUE; } @@ -1224,11 +1215,11 @@
if (WM_QUIT == Msg) { - MsqPostQuitMessage(Window->head.pti->MessageQueue, wParam); + MsqPostQuitMessage(Window->head.pti, wParam); } else { - MsqPostMessage(Window->head.pti->MessageQueue, &Message, FALSE, QS_POSTMESSAGE, 0); + MsqPostMessage(Window->head.pti, &Message, FALSE, QS_POSTMESSAGE, 0); } } return TRUE; @@ -1279,7 +1270,7 @@ Win32Thread = PsGetCurrentThreadWin32Thread();
if ( Win32Thread && - Window->head.pti->MessageQueue == Win32Thread->MessageQueue) + Window->head.pti == Win32Thread) { if (Win32Thread->TIF_flags & TIF_INCLEANUP) { @@ -1365,7 +1356,7 @@ RETURN( TRUE); }
- if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->head.pti->MessageQueue)) + if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->head.pti)) { // FIXME: Set window hung and add to a list. /* FIXME: Set a LastError? */ @@ -1381,7 +1372,7 @@
do { - Status = co_MsqSendMessage( Window->head.pti->MessageQueue, + Status = co_MsqSendMessage( Window->head.pti, hWnd, Msg, wParam, @@ -1393,7 +1384,7 @@ } while ((STATUS_TIMEOUT == Status) && (uFlags & SMTO_NOTIMEOUTIFNOTHUNG) && - !MsqIsHung(Window->head.pti->MessageQueue)); // FIXME: Set window hung and add to a list. + !MsqIsHung(Window->head.pti)); // FIXME: Set window hung and add to a list.
if (STATUS_TIMEOUT == Status) { @@ -1553,7 +1544,7 @@ }
if (Msg & 0x80000000 && - Window->head.pti->MessageQueue == Win32Thread->MessageQueue) + Window->head.pti == Win32Thread) { if (Win32Thread->TIF_flags & TIF_INCLEANUP) RETURN( FALSE);
@@ -1574,14 +1565,14 @@ lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam); }
- if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->head.pti->MessageQueue != Win32Thread->MessageQueue))) + if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->head.pti != Win32Thread))) { ERR("Failed to pack message parameters\n"); RETURN( FALSE); }
/* If it can be sent now, then send it. */ - if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue) + if (Window->head.pti == Win32Thread) { if (Win32Thread->TIF_flags & TIF_INCLEANUP) { @@ -1631,7 +1622,7 @@ } }
- if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue) + if (Window->head.pti == Win32Thread) { if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE))) { @@ -1645,12 +1636,6 @@ ERR("MsqSendMessage(): Not enough memory to allocate a message"); RETURN( FALSE); } - - IntReferenceMessageQueue(Window->head.pti->MessageQueue); - /* Take reference on this MessageQueue if its a callback. It will be released - when message is processed or removed from target hwnd MessageQueue */ - if (CompletionCallback) - IntReferenceMessageQueue(Win32Thread->MessageQueue);
Message->Msg.hwnd = hWnd; Message->Msg.message = Msg; @@ -1660,8 +1645,9 @@ Message->Result = 0; Message->lResult = 0; Message->QS_Flags = 0; - Message->SenderQueue = NULL; // mjmartin, you are right! This is null. - Message->CallBackSenderQueue = Win32Thread->MessageQueue; + Message->ptiReceiver = Window->head.pti; + Message->ptiSender = NULL; // mjmartin, you are right! This is null. + Message->ptiCallBackSender = Win32Thread; Message->DispatchingListEntry.Flink = NULL; Message->CompletionCallback = CompletionCallback; Message->CompletionCallbackContext = CompletionCallbackContext; @@ -1669,9 +1655,11 @@ Message->HasPackedLParam = (lParamBufferSize > 0); Message->QS_Flags = QS_SENDMESSAGE;
- InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry); - MsqWakeQueue(Window->head.pti->MessageQueue, QS_SENDMESSAGE, TRUE); - IntDereferenceMessageQueue(Window->head.pti->MessageQueue); + if (Msg & 0x80000000) // Higher priority event message! + InsertHeadList(&Window->head.pti->SentMessagesListHead, &Message->ListEntry); + else + InsertTailList(&Window->head.pti->SentMessagesListHead, &Message->ListEntry); + MsqWakeQueue(Window->head.pti, QS_SENDMESSAGE, TRUE);
RETURN(TRUE);
@@ -2351,7 +2339,7 @@
if ( parm.flags & BSF_IGNORECURRENTTASK ) { - if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue ) + if ( pwnd->head.pti == gptiCurrent ) continue; } co_IntSendMessageTimeout( List[i], @@ -2406,7 +2394,7 @@
if ( parm.flags & BSF_IGNORECURRENTTASK ) { - if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue ) + if ( pwnd->head.pti == gptiCurrent ) continue; } UserPostMessage(List[i], Msg, wParam, lParam); @@ -2432,7 +2420,7 @@
if ( parm.flags & BSF_IGNORECURRENTTASK ) { - if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue ) + if ( pwnd->head.pti == gptiCurrent ) continue; } UserSendNotifyMessage(List[i], Msg, wParam, lParam); @@ -2489,7 +2477,7 @@
if ( parm.flags & BSF_IGNORECURRENTTASK ) { - if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue ) + if ( pwnd->head.pti == gptiCurrent ) continue; } co_IntSendMessageTimeout( List[i], @@ -2543,7 +2531,7 @@
if ( parm.flags & BSF_IGNORECURRENTTASK ) { - if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue ) + if ( pwnd->head.pti == gptiCurrent ) continue; } UserPostMessage(List[i], Msg, wParam, lParam); @@ -2569,7 +2557,7 @@
if ( parm.flags & BSF_IGNORECURRENTTASK ) { - if ( pwnd->head.pti->MessageQueue == gptiCurrent->MessageQueue ) + if ( pwnd->head.pti == gptiCurrent ) continue; } UserSendNotifyMessage(List[i], Msg, wParam, lParam); @@ -2812,7 +2800,7 @@
Handles[0] = Process; Handles[1] = W32Process->InputIdleEvent; - Handles[2] = pti->MessageQueue->NewMessages; // pEventQueueServer; IntMsqSetWakeMask returns hEventQueueClient + Handles[2] = pti->pEventQueueServer; // IntMsqSetWakeMask returns hEventQueueClient
if (!Handles[1]) {
Modified: trunk/reactos/win32ss/user/ntuser/misc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/misc.c?... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/misc.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/misc.c [iso-8859-1] Fri May 10 22:28:18 2013 @@ -188,7 +188,7 @@ ret = ISMEX_NOSEND; if (Message) { - if (Message->SenderQueue) + if (Message->ptiSender) ret = ISMEX_SEND; else { @@ -213,7 +213,7 @@ LARGE_INTEGER LargeTickCount; pti = PsGetCurrentThreadWin32Thread(); KeQueryTickCount(&LargeTickCount); - pti->MessageQueue->LastMsgRead = LargeTickCount.u.LowPart; + pti->timeLast = LargeTickCount.u.LowPart; pti->pcti->tickLastMsgChecked = LargeTickCount.u.LowPart; } break;
Modified: trunk/reactos/win32ss/user/ntuser/msgqueue.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/msgqueu... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/msgqueue.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/msgqueue.c [iso-8859-1] Fri May 10 22:28:18 2013 @@ -347,7 +347,6 @@ IntMsqSetWakeMask(DWORD WakeMask) { PTHREADINFO Win32Thread; - PUSER_MESSAGE_QUEUE MessageQueue; HANDLE MessageEventHandle; DWORD dwFlags = HIWORD(WakeMask);
@@ -355,9 +354,8 @@ if (Win32Thread == NULL || Win32Thread->MessageQueue == NULL) return 0;
- MessageQueue = Win32Thread->MessageQueue; // Win32Thread->pEventQueueServer; IntMsqSetWakeMask returns Win32Thread->hEventQueueClient - MessageEventHandle = MessageQueue->NewMessagesHandle; + MessageEventHandle = Win32Thread->hEventQueueClient;
if (Win32Thread->pcti) { @@ -365,7 +363,7 @@ ( (dwFlags & MWMO_INPUTAVAILABLE) && (Win32Thread->pcti->fsWakeBits & LOWORD(WakeMask)) ) ) { ERR("Chg 0x%x Wake 0x%x Mask 0x%x\n",Win32Thread->pcti->fsChangeBits, Win32Thread->pcti->fsWakeBits, WakeMask); - KeSetEvent(MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); // Wake it up! + KeSetEvent(Win32Thread->pEventQueueServer, IO_NO_INCREMENT, FALSE); // Wake it up! return MessageEventHandle; } } @@ -396,55 +394,64 @@ and even if the bits are all cleared. The same as cTimers/cPaintsReady. I think this is the best solution... (jt) */ VOID FASTCALL -MsqWakeQueue(PUSER_MESSAGE_QUEUE Queue, DWORD MessageBits, BOOL KeyEvent) -{ - PTHREADINFO pti; +MsqWakeQueue(PTHREADINFO pti, DWORD MessageBits, BOOL KeyEvent) +{ + PUSER_MESSAGE_QUEUE Queue; + + Queue = pti->MessageQueue;
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;
// Start bit accounting to help clear the main set of bits. - if (MessageBits & QS_KEY) Queue->nCntsQBits[QSRosKey]++; - if (MessageBits & QS_MOUSEMOVE) Queue->nCntsQBits[QSRosMouseMove]++; - if (MessageBits & QS_MOUSEBUTTON) Queue->nCntsQBits[QSRosMouseButton]++; - if (MessageBits & QS_POSTMESSAGE) Queue->nCntsQBits[QSRosPostMessage]++; - if (MessageBits & QS_SENDMESSAGE) Queue->nCntsQBits[QSRosSendMessage]++; - if (MessageBits & QS_HOTKEY) Queue->nCntsQBits[QSRosHotKey]++; + if (MessageBits & QS_KEY) + { + pti->nCntsQBits[QSRosKey]++; + } + if (MessageBits & QS_MOUSE) + { + if (MessageBits & QS_MOUSEMOVE) pti->nCntsQBits[QSRosMouseMove]++; + if (MessageBits & QS_MOUSEBUTTON) pti->nCntsQBits[QSRosMouseButton]++; + } + if (MessageBits & QS_POSTMESSAGE) pti->nCntsQBits[QSRosPostMessage]++; + if (MessageBits & QS_SENDMESSAGE) pti->nCntsQBits[QSRosSendMessage]++; + if (MessageBits & QS_HOTKEY) pti->nCntsQBits[QSRosHotKey]++; + if (MessageBits & QS_EVENT) pti->nCntsQBits[QSRosEvent]++;
if (KeyEvent) - KeSetEvent(Queue->NewMessages, IO_NO_INCREMENT, FALSE); + KeSetEvent(pti->pEventQueueServer, IO_NO_INCREMENT, FALSE); }
VOID FASTCALL -ClearMsgBitsMask(PUSER_MESSAGE_QUEUE Queue, UINT MessageBits) -{ - PTHREADINFO pti; +ClearMsgBitsMask(PTHREADINFO pti, UINT MessageBits) +{ + PUSER_MESSAGE_QUEUE Queue; UINT ClrMask = 0;
- pti = Queue->Thread->Tcb.Win32Thread; + Queue = pti->MessageQueue;
if (MessageBits & QS_KEY) { - if (--Queue->nCntsQBits[QSRosKey] == 0) ClrMask |= QS_KEY; + if (--pti->nCntsQBits[QSRosKey] == 0) ClrMask |= QS_KEY; } if (MessageBits & QS_MOUSEMOVE) // ReactOS hard coded. { // Account for tracking mouse moves.. - if (--Queue->nCntsQBits[QSRosMouseMove] == 0) ClrMask |= QS_MOUSEMOVE; + if (--pti->nCntsQBits[QSRosMouseMove] == 0) ClrMask |= QS_MOUSEMOVE; // Handle mouse move bits here. if (Queue->MouseMoved) ClrMask |= QS_MOUSEMOVE; } if (MessageBits & QS_MOUSEBUTTON) { - if (--Queue->nCntsQBits[QSRosMouseButton] == 0) ClrMask |= QS_MOUSEBUTTON; + if (--pti->nCntsQBits[QSRosMouseButton] == 0) ClrMask |= QS_MOUSEBUTTON; } if (MessageBits & QS_POSTMESSAGE) { - if (--Queue->nCntsQBits[QSRosPostMessage] == 0) ClrMask |= QS_POSTMESSAGE; + if (--pti->nCntsQBits[QSRosPostMessage] == 0) ClrMask |= QS_POSTMESSAGE; } if (MessageBits & QS_TIMER) // ReactOS hard coded. { // Handle timer bits here. @@ -462,11 +469,11 @@ } if (MessageBits & QS_SENDMESSAGE) { - if (--Queue->nCntsQBits[QSRosSendMessage] == 0) ClrMask |= QS_SENDMESSAGE; + if (--pti->nCntsQBits[QSRosSendMessage] == 0) ClrMask |= QS_SENDMESSAGE; } if (MessageBits & QS_HOTKEY) { - if (--Queue->nCntsQBits[QSRosHotKey] == 0) ClrMask |= QS_HOTKEY; + if (--pti->nCntsQBits[QSRosHotKey] == 0) ClrMask |= QS_HOTKEY; }
pti->pcti->fsWakeBits &= ~ClrMask; @@ -474,26 +481,24 @@ }
VOID FASTCALL -MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue) -{ - PTHREADINFO pti; - pti = Queue->Thread->Tcb.Win32Thread; +MsqIncPaintCountQueue(PTHREADINFO pti) +{ pti->cPaintsReady++; - MsqWakeQueue(Queue, QS_PAINT, TRUE); + MsqWakeQueue(pti, QS_PAINT, TRUE); }
VOID FASTCALL -MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue) -{ - ClearMsgBitsMask(Queue, QS_PAINT); +MsqDecPaintCountQueue(PTHREADINFO pti) +{ + ClearMsgBitsMask(pti, QS_PAINT); }
VOID FASTCALL -MsqPostMouseMove(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg) -{ - MessageQueue->MouseMoveMsg = *Msg; - MessageQueue->MouseMoved = TRUE; - MsqWakeQueue(MessageQueue, QS_MOUSEMOVE, TRUE); +MsqPostMouseMove(PTHREADINFO pti, MSG* Msg) +{ + pti->MessageQueue->MouseMoveMsg = *Msg; + pti->MessageQueue->MouseMoved = TRUE; + MsqWakeQueue(pti, QS_MOUSEMOVE, TRUE); }
VOID FASTCALL @@ -504,6 +509,7 @@ PDESKTOP pDesk; PWND pwnd, pwndDesktop; HDC hdcScreen; + PTHREADINFO pti; PUSER_MESSAGE_QUEUE MessageQueue; PSYSTEM_CURSORINFO CurInfo;
@@ -564,9 +570,10 @@ /* 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) + pti = pwnd->head.pti; + MessageQueue = pti->MessageQueue; + + if ( pti->TIF_flags & TIF_INCLEANUP || MessageQueue->QF_flags & QF_INDESTROY) { ERR("Mouse is over the Window Thread is Dead!\n"); return; @@ -617,12 +624,12 @@ gpqCursor = MessageQueue;
/* Mouse move is a special case */ - MsqPostMouseMove(MessageQueue, Msg); + MsqPostMouseMove(pti, Msg); } else { TRACE("Posting mouse message to hwnd=0x%x!\n", UserHMGetHandle(pwnd)); - MsqPostMessage(MessageQueue, Msg, TRUE, QS_MOUSEBUTTON, 0); + MsqPostMessage(pti, Msg, TRUE, QS_MOUSEBUTTON, 0); } } else if (hdcScreen) @@ -675,7 +682,7 @@ KeQueryTickCount(&LargeTickCount); Mesg.time = MsqCalculateMessageTime(&LargeTickCount); Mesg.pt = gpsi->ptCursor; - MsqPostMessage(Window->head.pti->MessageQueue, &Mesg, FALSE, Type, 0); + MsqPostMessage(Window->head.pti, &Mesg, FALSE, Type, 0); UserDereferenceObject(Window); ObDereferenceObject (Thread);
@@ -704,41 +711,38 @@ }
BOOLEAN FASTCALL -co_MsqDispatchOneSentMessage(_In_ PUSER_MESSAGE_QUEUE MessageQueue) +co_MsqDispatchOneSentMessage(_In_ PTHREADINFO pti) { PUSER_SENT_MESSAGE SaveMsg, Message; PLIST_ENTRY Entry; - PTHREADINFO pti; BOOL Ret; LRESULT Result = 0;
- if (IsListEmpty(&MessageQueue->SentMessagesListHead)) + if (IsListEmpty(&pti->SentMessagesListHead)) { return(FALSE); }
/* remove it from the list of pending messages */ - Entry = RemoveHeadList(&MessageQueue->SentMessagesListHead); + Entry = RemoveHeadList(&pti->SentMessagesListHead); Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry); - - pti = MessageQueue->Thread->Tcb.Win32Thread;
SaveMsg = pti->pusmCurrent; pti->pusmCurrent = Message;
// Processing a message sent to it from another thread. - if ( ( Message->SenderQueue && MessageQueue != Message->SenderQueue) || - ( Message->CallBackSenderQueue && MessageQueue != Message->CallBackSenderQueue )) + if ( ( Message->ptiSender && pti != Message->ptiSender) || + ( Message->ptiCallBackSender && pti != Message->ptiCallBackSender )) { // most likely, but, to be sure. pti->pcti->CTI_flags |= CTI_INSENDMESSAGE; // Let the user know... }
/* insert it to the list of messages that are currently dispatched by this message queue */ - InsertTailList(&MessageQueue->LocalDispatchingMessagesHead, + InsertTailList(&pti->LocalDispatchingMessagesHead, &Message->ListEntry);
- ClearMsgBitsMask(MessageQueue, Message->QS_Flags); + ClearMsgBitsMask(pti, Message->QS_Flags);
if (Message->HookMessage == MSQ_ISHOOK) { // Direct Hook Call processor @@ -761,7 +765,7 @@ Message->Msg.wParam); } else if ((Message->CompletionCallback) && - (Message->CallBackSenderQueue == MessageQueue)) + (Message->ptiCallBackSender == pti)) { /* Call the callback routine */ if (Message->QS_Flags & QS_SMRESULT) { @@ -777,7 +781,7 @@ { /* The message has not been processed yet, reinsert it. */ RemoveEntryList(&Message->ListEntry); - InsertTailList(&Message->CallBackSenderQueue->SentMessagesListHead, &Message->ListEntry); + InsertTailList(&Message->ptiCallBackSender->SentMessagesListHead, &Message->ListEntry); TRACE("Callback Message not processed yet. Requeuing the message\n"); Ret = FALSE; goto Exit; @@ -798,22 +802,21 @@ /* If the message is a callback, insert it in the callback senders MessageQueue */ if (Message->CompletionCallback) { - if (Message->CallBackSenderQueue) + if (Message->ptiCallBackSender) { Message->lResult = Result; Message->QS_Flags |= QS_SMRESULT;
/* insert it in the callers message queue */ - InsertTailList(&Message->CallBackSenderQueue->SentMessagesListHead, &Message->ListEntry); - MsqWakeQueue(Message->CallBackSenderQueue, QS_SENDMESSAGE, TRUE); - IntDereferenceMessageQueue(Message->CallBackSenderQueue); + InsertTailList(&Message->ptiCallBackSender->SentMessagesListHead, &Message->ListEntry); + MsqWakeQueue(Message->ptiCallBackSender, QS_SENDMESSAGE, TRUE); } Ret = TRUE; goto Exit; }
/* remove the message from the dispatching list if needed, so lock the sender's message queue */ - if (Message->SenderQueue) + if (Message->ptiSender) { if (Message->DispatchingListEntry.Flink != NULL) { @@ -845,14 +848,6 @@ if (Message->CompletionEvent != NULL) { KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE); - } - - /* if the message has a sender */ - if (Message->SenderQueue) - { - /* dereference our and the sender's message queue */ - IntDereferenceMessageQueue(Message->SenderQueue); - IntDereferenceMessageQueue(MessageQueue); }
/* free the message */ @@ -867,22 +862,20 @@ }
VOID APIENTRY -MsqRemoveWindowMessagesFromQueue(PVOID pWindow) -{ +MsqRemoveWindowMessagesFromQueue(PWND Window) +{ + PTHREADINFO pti; PUSER_SENT_MESSAGE SentMessage; PUSER_MESSAGE PostedMessage; - PUSER_MESSAGE_QUEUE MessageQueue; PLIST_ENTRY CurrentEntry, ListHead; - PWND Window = pWindow;
ASSERT(Window);
- MessageQueue = Window->head.pti->MessageQueue; - ASSERT(MessageQueue); + pti = Window->head.pti;
/* remove the posted messages for this window */ - CurrentEntry = MessageQueue->PostedMessagesListHead.Flink; - ListHead = &MessageQueue->PostedMessagesListHead; + CurrentEntry = pti->PostedMessagesListHead.Flink; + ListHead = &pti->PostedMessagesListHead; while (CurrentEntry != ListHead) { PostedMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, @@ -890,9 +883,9 @@ if (PostedMessage->Msg.hwnd == Window->head.h) { RemoveEntryList(&PostedMessage->ListEntry); - ClearMsgBitsMask(MessageQueue, PostedMessage->QS_Flags); + ClearMsgBitsMask(pti, PostedMessage->QS_Flags); MsqDestroyMessage(PostedMessage); - CurrentEntry = MessageQueue->PostedMessagesListHead.Flink; + CurrentEntry = pti->PostedMessagesListHead.Flink; } else { @@ -900,12 +893,9 @@ } }
- /* Reference we message queue, so it won't get deleted */ - IntReferenceMessageQueue(MessageQueue); - /* remove the sent messages for this window */ - CurrentEntry = MessageQueue->SentMessagesListHead.Flink; - ListHead = &MessageQueue->SentMessagesListHead; + CurrentEntry = pti->SentMessagesListHead.Flink; + ListHead = &pti->SentMessagesListHead; while (CurrentEntry != ListHead) { SentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, @@ -915,15 +905,10 @@ TRACE("Notify the sender and remove a message from the queue that had not been dispatched\n");
RemoveEntryList(&SentMessage->ListEntry); - ClearMsgBitsMask(MessageQueue, SentMessage->QS_Flags); - - /* if it is a callback and this queue is not the sender queue, dereference queue */ - if ((SentMessage->CompletionCallback) && (SentMessage->CallBackSenderQueue != MessageQueue)) - { - IntDereferenceMessageQueue(SentMessage->CallBackSenderQueue); - } + ClearMsgBitsMask(pti, SentMessage->QS_Flags); + /* Only if the message has a sender was the queue referenced */ - if ((SentMessage->SenderQueue) + if ((SentMessage->ptiSender) && (SentMessage->DispatchingListEntry.Flink != NULL)) { RemoveEntryList(&SentMessage->DispatchingListEntry); @@ -941,27 +926,16 @@ ExFreePool((PVOID)SentMessage->Msg.lParam); }
- /* if the message has a sender */ - if (SentMessage->SenderQueue) - { - /* dereference our and the sender's message queue */ - IntDereferenceMessageQueue(MessageQueue); - IntDereferenceMessageQueue(SentMessage->SenderQueue); - } - /* free the message */ ExFreePoolWithTag(SentMessage, TAG_USRMSG);
- CurrentEntry = MessageQueue->SentMessagesListHead.Flink; + CurrentEntry = pti->SentMessagesListHead.Flink; } else { CurrentEntry = CurrentEntry->Flink; } } - - /* Remove the reference we added */ - IntDereferenceMessageQueue(MessageQueue); }
BOOL FASTCALL @@ -1000,8 +974,9 @@ Message->CompletionEvent = NULL; Message->Result = 0; Message->lResult = 0; - Message->SenderQueue = NULL; - Message->CallBackSenderQueue = ptiSender->MessageQueue; + Message->ptiReceiver = ptiReceiver; + Message->ptiSender = NULL; + Message->ptiCallBackSender = ptiSender; Message->DispatchingListEntry.Flink = NULL; Message->CompletionCallback = CompletionCallback; Message->CompletionCallbackContext = CompletionCallbackContext; @@ -1009,33 +984,29 @@ Message->HasPackedLParam = HasPackedLParam; Message->QS_Flags = QS_SENDMESSAGE;
- InsertTailList(&ptiReceiver->MessageQueue->SentMessagesListHead, &Message->ListEntry); - MsqWakeQueue(ptiReceiver->MessageQueue, QS_SENDMESSAGE, TRUE); - IntDereferenceMessageQueue(ptiReceiver->MessageQueue); + InsertTailList(&ptiReceiver->SentMessagesListHead, &Message->ListEntry); + MsqWakeQueue(ptiReceiver, QS_SENDMESSAGE, TRUE);
return TRUE; }
NTSTATUS FASTCALL -co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, +co_MsqSendMessage(PTHREADINFO ptirec, HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, UINT uTimeout, BOOL Block, INT HookMessage, ULONG_PTR *uResult) { - PTHREADINFO pti, ptirec; + PTHREADINFO pti; PUSER_SENT_MESSAGE Message; KEVENT CompletionEvent; NTSTATUS WaitStatus; - PUSER_MESSAGE_QUEUE ThreadQueue; LARGE_INTEGER Timeout; PLIST_ENTRY Entry; PWND pWnd; LRESULT Result = 0; //// Result could be trashed. ////
pti = PsGetCurrentThreadWin32Thread(); - ThreadQueue = pti->MessageQueue; - ptirec = MessageQueue->Thread->Tcb.Win32Thread; - ASSERT(ThreadQueue != MessageQueue); + ASSERT(pti != ptirec); ASSERT(ptirec->pcti); // Send must have a client side to receive it!!!!
/* Don't send from or to a dying thread */ @@ -1105,24 +1076,22 @@ Message->Result = &Result; Message->lResult = 0; Message->QS_Flags = 0; - Message->SenderQueue = ThreadQueue; - Message->CallBackSenderQueue = NULL; - IntReferenceMessageQueue(ThreadQueue); + Message->ptiReceiver = ptirec; + Message->ptiSender = pti; + Message->ptiCallBackSender = NULL; Message->CompletionCallback = NULL; Message->CompletionCallbackContext = 0; Message->HookMessage = HookMessage; Message->HasPackedLParam = FALSE;
- IntReferenceMessageQueue(MessageQueue); - /* Add it to the list of pending messages */ - InsertTailList(&ThreadQueue->DispatchingMessagesHead, &Message->DispatchingListEntry); + InsertTailList(&pti->DispatchingMessagesHead, &Message->DispatchingListEntry);
/* Queue it in the destination's message queue */ - InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry); + InsertTailList(&ptirec->SentMessagesListHead, &Message->ListEntry);
Message->QS_Flags = QS_SENDMESSAGE; - MsqWakeQueue(MessageQueue, QS_SENDMESSAGE, TRUE); + MsqWakeQueue(ptirec, QS_SENDMESSAGE, TRUE);
/* We can't access the Message anymore since it could have already been deleted! */
@@ -1140,8 +1109,8 @@ { /* Look up if the message has not yet dispatched, if so make sure it can't pass a result and it must not set the completion event anymore */ - Entry = MessageQueue->SentMessagesListHead.Flink; - while (Entry != &MessageQueue->SentMessagesListHead) + Entry = ptirec->SentMessagesListHead.Flink; + while (Entry != &ptirec->SentMessagesListHead) { if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry) == Message) @@ -1157,8 +1126,8 @@
/* Remove from the local dispatching list so the other thread knows, it can't pass a result and it must not set the completion event anymore */ - Entry = ThreadQueue->DispatchingMessagesHead.Flink; - while (Entry != &ThreadQueue->DispatchingMessagesHead) + Entry = pti->DispatchingMessagesHead.Flink; + while (Entry != &pti->DispatchingMessagesHead) { if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, DispatchingListEntry) == Message) @@ -1178,7 +1147,7 @@
TRACE("MsqSendMessage (blocked) timed out 1\n"); } - while (co_MsqDispatchOneSentMessage(ThreadQueue)) + while (co_MsqDispatchOneSentMessage(ptirec)) ; } else @@ -1186,7 +1155,7 @@ PVOID WaitObjects[2];
WaitObjects[0] = &CompletionEvent; - WaitObjects[1] = ThreadQueue->NewMessages; + WaitObjects[1] = pti->pEventQueueServer; do { UserLeaveCo(); @@ -1200,8 +1169,8 @@ { /* Look up if the message has not yet been dispatched, if so make sure it can't pass a result and it must not set the completion event anymore */ - Entry = MessageQueue->SentMessagesListHead.Flink; - while (Entry != &MessageQueue->SentMessagesListHead) + Entry = ptirec->SentMessagesListHead.Flink; + while (Entry != &ptirec->SentMessagesListHead) { if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry) == Message) @@ -1217,8 +1186,8 @@
/* Remove from the local dispatching list so the other thread knows, it can't pass a result and it must not set the completion event anymore */ - Entry = ThreadQueue->DispatchingMessagesHead.Flink; - while (Entry != &ThreadQueue->DispatchingMessagesHead) + Entry = pti->DispatchingMessagesHead.Flink; + while (Entry != &pti->DispatchingMessagesHead) { if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, DispatchingListEntry) == Message) @@ -1239,7 +1208,7 @@ TRACE("MsqSendMessage timed out 2\n"); break; } - while (co_MsqDispatchOneSentMessage(ThreadQueue)) + while (co_MsqDispatchOneSentMessage(pti)) ; } while (NT_SUCCESS(WaitStatus) && STATUS_WAIT_0 != WaitStatus); @@ -1252,27 +1221,30 @@ }
VOID FASTCALL -MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, +MsqPostMessage(PTHREADINFO pti, MSG* Msg, BOOLEAN HardwareMessage, DWORD MessageBits, DWORD dwQEvent) { PUSER_MESSAGE Message; + PUSER_MESSAGE_QUEUE MessageQueue;
if(!(Message = MsqCreateMessage(Msg))) { return; }
+ MessageQueue = pti->MessageQueue; + if (dwQEvent) { - InsertHeadList(&MessageQueue->PostedMessagesListHead, + InsertHeadList(&pti->PostedMessagesListHead, &Message->ListEntry); } else if (!HardwareMessage) { - InsertTailList(&MessageQueue->PostedMessagesListHead, + InsertTailList(&pti->PostedMessagesListHead, &Message->ListEntry); } else @@ -1284,15 +1256,15 @@ Message->dwQEvent = dwQEvent; Message->QS_Flags = MessageBits; //Message->pti = pti; Fixed in ATI changes. See CORE-6551 - MsqWakeQueue(MessageQueue, MessageBits, (MessageBits & QS_TIMER ? FALSE : TRUE)); + MsqWakeQueue(pti, MessageBits, (MessageBits & QS_TIMER ? FALSE : TRUE)); }
VOID FASTCALL -MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode) -{ - MessageQueue->QuitPosted = TRUE; - MessageQueue->QuitExitCode = ExitCode; - MsqWakeQueue(MessageQueue, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE, TRUE); +MsqPostQuitMessage(PTHREADINFO pti, ULONG ExitCode) +{ + pti->QuitPosted = TRUE; + pti->exitCode = ExitCode; + MsqWakeQueue(pti, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE, TRUE); }
/*********************************************************************** @@ -1719,7 +1691,7 @@ }
BOOL APIENTRY -co_MsqPeekMouseMove(IN PUSER_MESSAGE_QUEUE MessageQueue, +co_MsqPeekMouseMove(IN PTHREADINFO pti, IN BOOL Remove, IN PWND Window, IN UINT MsgFilterLow, @@ -1728,7 +1700,7 @@ { BOOL AcceptMessage; MSG msg; - PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); + PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue;
if(!(MessageQueue->MouseMoved)) return FALSE; @@ -1754,7 +1726,7 @@
if(Remove) { - ClearMsgBitsMask(MessageQueue, QS_MOUSEMOVE); + ClearMsgBitsMask(pti, QS_MOUSEMOVE); MessageQueue->MouseMoved = FALSE; }
@@ -1781,7 +1753,7 @@ }
BOOL APIENTRY -co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue, +co_MsqPeekHardwareMessage(IN PTHREADINFO pti, IN BOOL Remove, IN PWND Window, IN UINT MsgFilterLow, @@ -1795,7 +1767,7 @@ PLIST_ENTRY ListHead, CurrentEntry = NULL; MSG msg; BOOL Ret = FALSE; - PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); + PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue;
if (!filter_contains_hw_range( MsgFilterLow, MsgFilterHigh )) return FALSE;
@@ -1843,7 +1815,7 @@ if (Remove) { RemoveEntryList(&CurrentMessage->ListEntry); - ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags); + ClearMsgBitsMask(pti, CurrentMessage->QS_Flags); MsqDestroyMessage(CurrentMessage); }
@@ -1865,7 +1837,7 @@ }
BOOLEAN APIENTRY -MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue, +MsqPeekMessage(IN PTHREADINFO pti, IN BOOLEAN Remove, IN PWND Window, IN UINT MsgFilterLow, @@ -1877,25 +1849,12 @@ PUSER_MESSAGE CurrentMessage; PLIST_ENTRY ListHead; BOOL Ret = FALSE; - PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); - - CurrentEntry = MessageQueue->PostedMessagesListHead.Flink; - ListHead = &MessageQueue->PostedMessagesListHead; + + CurrentEntry = pti->PostedMessagesListHead.Flink; + ListHead = &pti->PostedMessagesListHead;
if (IsListEmpty(CurrentEntry)) return FALSE; - - if (!MessageQueue->ptiSysLock) - { - MessageQueue->ptiSysLock = pti; - pti->pcti->CTI_flags |= CTI_THREADSYSLOCK; - } - - if (MessageQueue->ptiSysLock != pti) - { - ERR("MsqPeekMessage: Thread Q is locked to another pti!\n"); - return FALSE; - } - + CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry); do @@ -1920,7 +1879,7 @@ if (Remove) { RemoveEntryList(&CurrentMessage->ListEntry); - ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags); + ClearMsgBitsMask(pti, CurrentMessage->QS_Flags); MsqDestroyMessage(CurrentMessage); } Ret = TRUE; @@ -1931,18 +1890,16 @@ } while (CurrentEntry != ListHead);
- MessageQueue->ptiSysLock = NULL; - pti->pcti->CTI_flags &= ~CTI_THREADSYSLOCK; return Ret; }
NTSTATUS FASTCALL -co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWND WndFilter, +co_MsqWaitForNewMessages(PTHREADINFO pti, PWND WndFilter, UINT MsgFilterMin, UINT MsgFilterMax) { NTSTATUS ret; UserLeaveCo(); - ret = KeWaitForSingleObject( MessageQueue->NewMessages, + ret = KeWaitForSingleObject( pti->pEventQueueServer, UserRequest, UserMode, FALSE, @@ -1952,12 +1909,12 @@ }
BOOL FASTCALL -MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue) +MsqIsHung(PTHREADINFO pti) { LARGE_INTEGER LargeTickCount;
KeQueryTickCount(&LargeTickCount); - return ((LargeTickCount.u.LowPart - MessageQueue->LastMsgRead) > MSQ_HUNG); + return ((LargeTickCount.u.LowPart - pti->timeLast) > MSQ_HUNG); }
VOID @@ -1972,83 +1929,46 @@ BOOLEAN FASTCALL MsqInitializeMessageQueue(PTHREADINFO pti, PUSER_MESSAGE_QUEUE MessageQueue) { - struct _ETHREAD *Thread; - LARGE_INTEGER LargeTickCount; - NTSTATUS Status; - - Thread = pti->pEThread; - MessageQueue->Thread = Thread; + MessageQueue->ptiOwner = pti; MessageQueue->CaretInfo = (PTHRDCARETINFO)(MessageQueue + 1); - InitializeListHead(&MessageQueue->PostedMessagesListHead); - InitializeListHead(&MessageQueue->SentMessagesListHead); InitializeListHead(&MessageQueue->HardwareMessagesListHead); - InitializeListHead(&MessageQueue->DispatchingMessagesHead); - InitializeListHead(&MessageQueue->LocalDispatchingMessagesHead); - MessageQueue->QuitPosted = FALSE; - MessageQueue->QuitExitCode = 0; - KeQueryTickCount(&LargeTickCount); - MessageQueue->LastMsgRead = LargeTickCount.u.LowPart; MessageQueue->spwndFocus = NULL; - MessageQueue->NewMessagesHandle = NULL; MessageQueue->iCursorLevel = 0; MessageQueue->CursorObject = NULL; RtlCopyMemory(MessageQueue->afKeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState)); - - Status = ZwCreateEvent(&MessageQueue->NewMessagesHandle, EVENT_ALL_ACCESS, - NULL, SynchronizationEvent, FALSE); - if (!NT_SUCCESS(Status)) - { - return FALSE; - } - - Status = ObReferenceObjectByHandle(MessageQueue->NewMessagesHandle, 0, - ExEventObjectType, KernelMode, - (PVOID*)&MessageQueue->NewMessages, NULL); - if (!NT_SUCCESS(Status)) - { - ZwClose(MessageQueue->NewMessagesHandle); - MessageQueue->NewMessagesHandle = NULL; - return FALSE; - } + MessageQueue->ptiMouse = pti; + MessageQueue->ptiKeyboard = pti; + MessageQueue->cThreads++;
return TRUE; }
VOID FASTCALL -MsqCleanupMessageQueue(PTHREADINFO pti) -{ - PUSER_MESSAGE_QUEUE MessageQueue; +MsqCleanupThreadMsgs(PTHREADINFO pti) +{ PLIST_ENTRY CurrentEntry; PUSER_MESSAGE CurrentMessage; PUSER_SENT_MESSAGE CurrentSentMessage; - - MessageQueue = pti->MessageQueue; - + /* cleanup posted messages */ - while (!IsListEmpty(&MessageQueue->PostedMessagesListHead)) - { - CurrentEntry = RemoveHeadList(&MessageQueue->PostedMessagesListHead); + while (!IsListEmpty(&pti->PostedMessagesListHead)) + { + CurrentEntry = RemoveHeadList(&pti->PostedMessagesListHead); CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry); MsqDestroyMessage(CurrentMessage); }
/* remove the messages that have not yet been dispatched */ - while (!IsListEmpty(&MessageQueue->SentMessagesListHead)) - { - CurrentEntry = RemoveHeadList(&MessageQueue->SentMessagesListHead); + while (!IsListEmpty(&pti->SentMessagesListHead)) + { + CurrentEntry = RemoveHeadList(&pti->SentMessagesListHead); CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry);
- /* if it is a callback and this queue is not the sender queue, dereference queue */ - if ((CurrentSentMessage->CompletionCallback) && (CurrentSentMessage->CallBackSenderQueue != MessageQueue)) - { - IntDereferenceMessageQueue(CurrentSentMessage->CallBackSenderQueue); - } - TRACE("Notify the sender and remove a message from the queue that had not been dispatched\n"); /* Only if the message has a sender was the message in the DispatchingList */ - if ((CurrentSentMessage->SenderQueue) + if ((CurrentSentMessage->ptiSender) && (CurrentSentMessage->DispatchingListEntry.Flink != NULL)) { RemoveEntryList(&CurrentSentMessage->DispatchingListEntry); @@ -2065,32 +1985,18 @@ if (CurrentSentMessage->Msg.lParam) ExFreePool((PVOID)CurrentSentMessage->Msg.lParam); } - - /* if the message has a sender */ - if (CurrentSentMessage->SenderQueue) - { - /* dereference our and the sender's message queue */ - IntDereferenceMessageQueue(MessageQueue); - IntDereferenceMessageQueue(CurrentSentMessage->SenderQueue); - } - + /* free the message */ ExFreePool(CurrentSentMessage); }
/* notify senders of dispatching messages. This needs to be cleaned up if e.g. ExitThread() was called in a SendMessage() umode callback */ - while (!IsListEmpty(&MessageQueue->LocalDispatchingMessagesHead)) - { - CurrentEntry = RemoveHeadList(&MessageQueue->LocalDispatchingMessagesHead); + while (!IsListEmpty(&pti->LocalDispatchingMessagesHead)) + { + CurrentEntry = RemoveHeadList(&pti->LocalDispatchingMessagesHead); CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry); - - /* if it is a callback and this queue is not the sender queue, dereference queue */ - if ((CurrentSentMessage->CompletionCallback) && (CurrentSentMessage->CallBackSenderQueue != MessageQueue)) - { - IntDereferenceMessageQueue(CurrentSentMessage->CallBackSenderQueue); - }
/* remove the message from the dispatching list */ if(CurrentSentMessage->DispatchingListEntry.Flink != NULL) @@ -2112,22 +2018,14 @@ ExFreePool((PVOID)CurrentSentMessage->Msg.lParam); }
- /* if the message has a sender */ - if (CurrentSentMessage->SenderQueue) - { - /* dereference our and the sender's message queue */ - IntDereferenceMessageQueue(MessageQueue); - IntDereferenceMessageQueue(CurrentSentMessage->SenderQueue); - } - /* free the message */ ExFreePool(CurrentSentMessage); }
/* tell other threads not to bother returning any info to us */ - while (! IsListEmpty(&MessageQueue->DispatchingMessagesHead)) - { - CurrentEntry = RemoveHeadList(&MessageQueue->DispatchingMessagesHead); + while (! IsListEmpty(&pti->DispatchingMessagesHead)) + { + CurrentEntry = RemoveHeadList(&pti->DispatchingMessagesHead); CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, DispatchingListEntry); CurrentSentMessage->CompletionEvent = NULL; @@ -2144,12 +2042,27 @@ pti->pcti->fsChangeBits = 0; }
- MessageQueue->nCntsQBits[QSRosKey] = 0; - MessageQueue->nCntsQBits[QSRosMouseMove] = 0; - MessageQueue->nCntsQBits[QSRosMouseButton] = 0; - MessageQueue->nCntsQBits[QSRosPostMessage] = 0; - MessageQueue->nCntsQBits[QSRosSendMessage] = 0; - MessageQueue->nCntsQBits[QSRosHotKey] = 0; + pti->nCntsQBits[QSRosKey] = 0; + pti->nCntsQBits[QSRosMouseMove] = 0; + pti->nCntsQBits[QSRosMouseButton] = 0; + pti->nCntsQBits[QSRosPostMessage] = 0; + pti->nCntsQBits[QSRosSendMessage] = 0; + pti->nCntsQBits[QSRosHotKey] = 0; + +} + +VOID FASTCALL +MsqCleanupMessageQueue(PTHREADINFO pti) +{ + PUSER_MESSAGE_QUEUE MessageQueue; + + MessageQueue = pti->MessageQueue; + MessageQueue->cThreads--; + + if (MessageQueue->cThreads) + { + if (MessageQueue->ptiSysLock == pti) MessageQueue->ptiSysLock = NULL; + }
if (MessageQueue->CursorObject) { @@ -2171,6 +2084,19 @@
UserDereferenceObject(pCursor); } + + if (gpqForeground == MessageQueue) + { + IntSetFocusMessageQueue(NULL); + } + if (gpqForegroundPrev == MessageQueue) + { + gpqForegroundPrev = NULL; + } + if (gpqCursor == MessageQueue) + { + gpqCursor = NULL; + } }
PUSER_MESSAGE_QUEUE FASTCALL @@ -2218,9 +2144,6 @@ /* clean it up */ MsqCleanupMessageQueue(pti);
- if (MessageQueue->NewMessagesHandle != NULL) - ZwClose(MessageQueue->NewMessagesHandle); - MessageQueue->NewMessagesHandle = NULL; /* decrease the reference counter, if it hits zero, the queue will be freed */ IntDereferenceMessageQueue(MessageQueue); } @@ -2276,7 +2199,7 @@ if (Message->QS_Flags & QS_SMRESULT) return FALSE;
// SendMessageXxx || Callback msg and not a notify msg - if (Message->SenderQueue || Message->CompletionCallback) + if (Message->ptiSender || Message->CompletionCallback) { Message->lResult = lResult; Message->QS_Flags |= QS_SMRESULT; @@ -2286,9 +2209,12 @@ }
HWND FASTCALL -MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd) +MsqSetStateWindow(PTHREADINFO pti, ULONG Type, HWND hWnd) { HWND Prev; + PUSER_MESSAGE_QUEUE MessageQueue; + + MessageQueue = pti->MessageQueue;
switch(Type) {
Modified: trunk/reactos/win32ss/user/ntuser/msgqueue.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/msgqueu... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/msgqueue.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/msgqueue.h [iso-8859-1] Fri May 10 22:28:18 2013 @@ -5,18 +5,6 @@ #define MSQ_ISHOOK 1 #define MSQ_ISEVENT 2 #define MSQ_INJECTMODULE 3 - -#define QSIDCOUNTS 6 - -typedef enum _QS_ROS_TYPES -{ - QSRosKey = 0, - QSRosMouseMove, - QSRosMouseButton, - QSRosPostMessage, - QSRosSendMessage, - QSRosHotKey, -}QS_ROS_TYPES,*PQS_ROS_TYPES;
typedef struct _USER_MESSAGE { @@ -38,9 +26,10 @@ PKEVENT CompletionEvent; LRESULT* Result; LRESULT lResult; - struct _USER_MESSAGE_QUEUE* SenderQueue; - struct _USER_MESSAGE_QUEUE* CallBackSenderQueue; + PTHREADINFO ptiSender; + PTHREADINFO ptiReceiver; SENDASYNCPROC CompletionCallback; + PTHREADINFO ptiCallBackSender; ULONG_PTR CompletionCallbackContext; /* entry in the dispatching list of the sender's message queue */ LIST_ENTRY DispatchingListEntry; @@ -53,13 +42,16 @@ /* Reference counter, only access this variable with interlocked functions! */ LONG References;
+ PTHREADINFO ptiOwner; // temp.. + /* Desktop that the message queue is attached to */ + struct _DESKTOP *Desktop; + PTHREADINFO ptiSysLock; /* Owner of the message queue */ - struct _ETHREAD *Thread; - /* Queue of messages sent to the queue. */ - LIST_ENTRY SentMessagesListHead; - /* Queue of messages posted to the queue. */ - LIST_ENTRY PostedMessagesListHead; +// struct _ETHREAD *Thread; + PTHREADINFO ptiMouse; + PTHREADINFO ptiKeyboard; + /* Queue for hardware messages for the queue. */ LIST_ENTRY HardwareMessagesListHead; /* True if a WM_MOUSEMOVE is pending */ @@ -68,16 +60,6 @@ MSG MouseMoveMsg; /* Last click message for translating double clicks */ MSG msgDblClk; - /* True if a WM_QUIT message is pending. */ - BOOLEAN QuitPosted; - /* The quit exit code. */ - ULONG QuitExitCode; - /* Set if there are new messages specified by WakeMask in any of the queues. */ - PKEVENT NewMessages; - /* Handle for the above event (in the context of the process owning the queue). */ - HANDLE NewMessagesHandle; - /* Last time PeekMessage() was called. */ - ULONG LastMsgRead; /* Current capture window for this queue. */ PWND spwndCapture; /* Current window with focus (ie. receives keyboard input) for this queue. */ @@ -97,13 +79,6 @@ DWORD QF_flags; DWORD cThreads; // Shared message queue counter.
- /* Queue state tracking */ - // Send list QS_SENDMESSAGE - // Post list QS_POSTMESSAGE|QS_HOTKEY|QS_PAINT|QS_TIMER|QS_KEY - // Hard list QS_MOUSE|QS_KEY only - // Accounting of queue bit sets, the rest are flags. QS_TIMER QS_PAINT counts are handled in thread information. - DWORD nCntsQBits[QSIDCOUNTS]; // QS_KEY QS_MOUSEMOVE QS_MOUSEBUTTON QS_POSTMESSAGE QS_SENDMESSAGE QS_HOTKEY - /* Extra message information */ LPARAM ExtraInfo;
@@ -116,13 +91,6 @@ /* Cursor object */ PCURICON_OBJECT CursorObject;
- /* Messages that are currently dispatched by other threads */ - LIST_ENTRY DispatchingMessagesHead; - /* Messages that are currently dispatched by this message queue, required for cleanup */ - LIST_ENTRY LocalDispatchingMessagesHead; - - /* Desktop that the message queue is attached to */ - struct _DESKTOP *Desktop; } USER_MESSAGE_QUEUE, *PUSER_MESSAGE_QUEUE;
#define QF_UPDATEKEYSTATE 0x00000001 @@ -152,17 +120,17 @@ WM_ASYNC_SETACTIVEWINDOW };
-BOOL FASTCALL MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue); +BOOL FASTCALL MsqIsHung(PTHREADINFO pti); VOID CALLBACK HungAppSysTimerProc(HWND,UINT,UINT_PTR,DWORD); -NTSTATUS FASTCALL co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, +NTSTATUS FASTCALL co_MsqSendMessage(PTHREADINFO ptirec, HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, UINT uTimeout, BOOL Block, INT HookMessage, ULONG_PTR *uResult); PUSER_MESSAGE FASTCALL MsqCreateMessage(LPMSG Msg); VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE Message); -VOID FASTCALL MsqPostMessage(PUSER_MESSAGE_QUEUE, MSG*, BOOLEAN, DWORD, DWORD); -VOID FASTCALL MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode); +VOID FASTCALL MsqPostMessage(PTHREADINFO, MSG*, BOOLEAN, DWORD, DWORD); +VOID FASTCALL MsqPostQuitMessage(PTHREADINFO pti, ULONG ExitCode); BOOLEAN APIENTRY -MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue, +MsqPeekMessage(IN PTHREADINFO pti, IN BOOLEAN Remove, IN PWND Window, IN UINT MsgFilterLow, @@ -170,7 +138,7 @@ IN UINT QSflags, OUT PMSG Message); BOOL APIENTRY -co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue, +co_MsqPeekHardwareMessage(IN PTHREADINFO pti, IN BOOL Remove, IN PWND Window, IN UINT MsgFilterLow, @@ -178,7 +146,7 @@ IN UINT QSflags, OUT MSG* pMsg); BOOL APIENTRY -co_MsqPeekMouseMove(IN PUSER_MESSAGE_QUEUE MessageQueue, +co_MsqPeekMouseMove(IN PTHREADINFO pti, IN BOOL Remove, IN PWND Window, IN UINT MsgFilterLow, @@ -186,14 +154,15 @@ OUT MSG* pMsg); BOOLEAN FASTCALL MsqInitializeMessageQueue(PTHREADINFO, PUSER_MESSAGE_QUEUE); PUSER_MESSAGE_QUEUE FASTCALL MsqCreateMessageQueue(PTHREADINFO); +VOID FASTCALL MsqCleanupThreadMsgs(PTHREADINFO); VOID FASTCALL MsqDestroyMessageQueue(PTHREADINFO); INIT_FUNCTION NTSTATUS NTAPI MsqInitializeImpl(VOID); -BOOLEAN FASTCALL co_MsqDispatchOneSentMessage(_In_ PUSER_MESSAGE_QUEUE MessageQueue); +BOOLEAN FASTCALL co_MsqDispatchOneSentMessage(PTHREADINFO pti); NTSTATUS FASTCALL -co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWND WndFilter, +co_MsqWaitForNewMessages(PTHREADINFO pti, PWND WndFilter, UINT MsgFilterMin, UINT MsgFilterMax); -VOID FASTCALL MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue); -VOID FASTCALL MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue); +VOID FASTCALL MsqIncPaintCountQueue(PTHREADINFO); +VOID FASTCALL MsqDecPaintCountQueue(PTHREADINFO); LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); LRESULT FASTCALL co_IntPostOrSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); LRESULT FASTCALL @@ -235,13 +204,13 @@ VOID FASTCALL co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook); BOOL FASTCALL MsqIsClkLck(LPMSG Msg, BOOL Remove); BOOL FASTCALL MsqIsDblClk(LPMSG Msg, BOOL Remove); -HWND FASTCALL MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd); +HWND FASTCALL MsqSetStateWindow(PTHREADINFO pti, ULONG Type, HWND hWnd); BOOL APIENTRY IntInitMessagePumpHook(VOID); BOOL APIENTRY IntUninitMessagePumpHook(VOID);
LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam); LPARAM FASTCALL MsqGetMessageExtraInfo(VOID); -VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PVOID pWindow); /* F*(&$ headers, will be gone in the rewrite! */ +VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PWND pWindow);
#define IntReferenceMessageQueue(MsgQueue) \ InterlockedIncrement(&(MsgQueue)->References) @@ -250,9 +219,7 @@ do { \ if(InterlockedDecrement(&(MsgQueue)->References) == 0) \ { \ - TRACE("Free message queue 0x%p\n", (MsgQueue)); \ - if ((MsgQueue)->NewMessages != NULL) \ - ObDereferenceObject((MsgQueue)->NewMessages); \ + ERR("Free message queue 0x%p\n", (MsgQueue)); \ ExFreePoolWithTag((MsgQueue), USERTAG_Q); \ } \ } while(0) @@ -289,8 +256,8 @@ VOID FASTCALL IdlePing(VOID); VOID FASTCALL IdlePong(VOID); BOOL FASTCALL co_MsqReplyMessage(LRESULT); -VOID FASTCALL MsqWakeQueue(PUSER_MESSAGE_QUEUE,DWORD,BOOL); -VOID FASTCALL ClearMsgBitsMask(PUSER_MESSAGE_QUEUE,UINT); +VOID FASTCALL MsqWakeQueue(PTHREADINFO,DWORD,BOOL); +VOID FASTCALL ClearMsgBitsMask(PTHREADINFO,UINT);
int UserShowCursor(BOOL bShow); PCURICON_OBJECT
Modified: trunk/reactos/win32ss/user/ntuser/painting.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/paintin... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/painting.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/painting.c [iso-8859-1] Fri May 10 22:28:18 2013 @@ -97,13 +97,12 @@ VOID FASTCALL IntSendSyncPaint(PWND Wnd, ULONG Flags) { - PTHREADINFO ptiCur; - PUSER_MESSAGE_QUEUE MessageQueue; + PTHREADINFO ptiCur, ptiWnd; PUSER_SENT_MESSAGE Message; PLIST_ENTRY Entry; BOOL bSend = TRUE;
- MessageQueue = Wnd->head.pti->MessageQueue; + ptiWnd = Wnd->head.pti; ptiCur = PsGetCurrentThreadWin32Thread(); /* Not the current thread, Wnd is in send Nonclient paint also in send erase background and it is visiable. @@ -115,10 +114,10 @@ { // For testing, if you see this, break out the Champagne and have a party! ERR("SendSyncPaint Wnd in State!\n"); - if (!IsListEmpty(&MessageQueue->SentMessagesListHead)) + if (!IsListEmpty(&ptiWnd->SentMessagesListHead)) { // Scan sent queue messages to see if we received sync paint messages. - Entry = MessageQueue->SentMessagesListHead.Flink; + Entry = ptiWnd->SentMessagesListHead.Flink; Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry); do { @@ -133,7 +132,7 @@ Entry = Message->ListEntry.Flink; Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry); } - while (Entry != &MessageQueue->SentMessagesListHead); + while (Entry != &ptiWnd->SentMessagesListHead); } if (bSend) { @@ -270,7 +269,7 @@ Window->state &= ~WNDS_UPDATEDIRTY; Window->hrgnUpdate = NULL; if (!(Window->state & WNDS_INTERNALPAINT)) - MsqDecPaintCountQueue(Window->head.pti->MessageQueue); + MsqDecPaintCountQueue(Window->head.pti); } }
@@ -557,9 +556,9 @@ if (HadPaintMessage != IntIsWindowDirty(Wnd)) { if (HadPaintMessage) - MsqDecPaintCountQueue(Wnd->head.pti->MessageQueue); + MsqDecPaintCountQueue(Wnd->head.pti); else - MsqIncPaintCountQueue(Wnd->head.pti->MessageQueue); + MsqIncPaintCountQueue(Wnd->head.pti); } TRACE("IntInvalidateWindows exit\n"); } @@ -781,7 +780,7 @@ { PaintWnd->state &= ~WNDS_INTERNALPAINT; if (!PaintWnd->hrgnUpdate) - MsqDecPaintCountQueue(Thread->MessageQueue); + MsqDecPaintCountQueue(Thread); } PaintWnd->state2 &= ~WNDS2_WMPAINTSENT; PaintWnd->state &= ~WNDS_UPDATEDIRTY; @@ -955,7 +954,7 @@
if (Window->hrgnUpdate != NULL) { - MsqDecPaintCountQueue(Window->head.pti->MessageQueue); + MsqDecPaintCountQueue(Window->head.pti); GdiGetClipBox(Ps->hdc, &Ps->rcPaint); IntGdiSetRegionOwner(Window->hrgnUpdate, GDI_OBJ_HMGR_POWNED); /* The region is part of the dc now and belongs to the process! */ @@ -964,7 +963,7 @@ else { if (Window->state & WNDS_INTERNALPAINT) - MsqDecPaintCountQueue(Window->head.pti->MessageQueue); + MsqDecPaintCountQueue(Window->head.pti);
IntGetClientRect(Window, &Ps->rcPaint); }
Modified: trunk/reactos/win32ss/user/ntuser/simplecall.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/simplec... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/simplecall.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/simplecall.c [iso-8859-1] Fri May 10 22:28:18 2013 @@ -156,7 +156,7 @@ { PTHREADINFO pti; pti = PsGetCurrentThreadWin32Thread(); - MsqPostQuitMessage(pti->MessageQueue, Param); + MsqPostQuitMessage(pti, Param); RETURN(TRUE); }
@@ -419,10 +419,9 @@
case TWOPARAM_ROUTINE_SETGUITHRDHANDLE: { - PUSER_MESSAGE_QUEUE MsgQueue = ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->MessageQueue; - - ASSERT(MsgQueue); - RETURN( (DWORD_PTR)MsqSetStateWindow(MsgQueue, (ULONG)Param1, (HWND)Param2)); + PTHREADINFO pti = (PTHREADINFO)PsGetCurrentThreadWin32Thread(); + ASSERT(pti->MessageQueue); + RETURN( (DWORD_PTR)MsqSetStateWindow(pti, (ULONG)Param1, (HWND)Param2)); }
case TWOPARAM_ROUTINE_ENABLEWINDOW:
Modified: trunk/reactos/win32ss/user/ntuser/timer.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/timer.c... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/timer.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/timer.c [iso-8859-1] Fri May 10 22:28:18 2013 @@ -409,7 +409,7 @@ Msg.wParam = (WPARAM) pTmr->nID; Msg.lParam = (LPARAM) pTmr->pfn;
- MsqPostMessage(ThreadQueue, &Msg, FALSE, QS_TIMER, 0); + MsqPostMessage(pti, &Msg, FALSE, QS_TIMER, 0); pTmr->flags &= ~TMRF_READY; pti->cTimersReady++; Hit = TRUE; @@ -484,8 +484,8 @@ // Set thread message queue for this timer. if (pTmr->pti->MessageQueue) { // Wakeup thread - ASSERT(pTmr->pti->MessageQueue->NewMessages != NULL); - KeSetEvent(pTmr->pti->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); + ASSERT(pTmr->pti->pEventQueueServer != NULL); + KeSetEvent(pTmr->pti->pEventQueueServer, IO_NO_INCREMENT, FALSE); } } }
Modified: trunk/reactos/win32ss/user/ntuser/win32.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/win32.h... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/win32.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/win32.h [iso-8859-1] Fri May 10 22:28:18 2013 @@ -32,8 +32,8 @@ #define W32PF_MANUALGUICHECK (0x02000000) #define W32PF_CREATEDWINORDC (0x04000000) #define W32PF_APIHOOKLOADED (0x08000000) -/* -#define QSIDCOUNTS 6 + +#define QSIDCOUNTS 7
typedef enum _QS_ROS_TYPES { @@ -43,8 +43,9 @@ QSRosPostMessage, QSRosSendMessage, QSRosHotKey, + QSRosEvent, }QS_ROS_TYPES,*PQS_ROS_TYPES; -*/ + extern BOOL ClientPfnInit; extern HINSTANCE hModClient; extern HANDLE hModuleWin; // This Win32k Instance. @@ -65,7 +66,7 @@ typedef struct _W32THREAD { PETHREAD pEThread; - ULONG RefCount; + LONG RefCount; PTL ptlW32; PVOID pgdiDcattr; PVOID pgdiBrushAttr; @@ -89,13 +90,18 @@ PCLIENTINFO pClientInfo; FLONG TIF_flags; PUNICODE_STRING pstrAppName; - LIST_ENTRY psmsSent; // DispatchingMessagesHead + /* Messages that are currently dispatched to other threads */ + LIST_ENTRY DispatchingMessagesHead; // psmsSent struct _USER_SENT_MESSAGE *pusmCurrent; - LIST_ENTRY psmsReceiveList; // SentMessagesListHead + /* Queue of messages sent to the queue. */ + LIST_ENTRY SentMessagesListHead; // psmsReceiveList + /* Last time PeekMessage() was called. */ LONG timeLast; ULONG_PTR idLast; + /* True if a WM_QUIT message is pending. */ BOOLEAN QuitPosted; - INT exitCode; // QuitExitCode + /* The quit exit code. */ + INT exitCode; HDESK hdesk; UINT cPaintsReady; /* Count of paints pending. */ UINT cTimersReady; /* Count of timers pending. */ @@ -109,26 +115,32 @@ LPARAM lParamHkCurrent; WPARAM wParamHkCurrent; struct tagSBTRACK* pSBTrack; - HANDLE hEventQueueClient; // NewMessagesHandle - PKEVENT pEventQueueServer; // NewMessages + /* Set if there are new messages specified by WakeMask in any of the queues. */ + HANDLE hEventQueueClient; + /* Handle for the above event (in the context of the process owning the queue). */ + PKEVENT pEventQueueServer; LIST_ENTRY PtiLink; INT iCursorLevel; POINT ptLast;
- LIST_ENTRY mlPost; // PostedMessagesListHead - + /* Queue of messages posted to the queue. */ + LIST_ENTRY PostedMessagesListHead; // mlPost + + UINT cWindows; + UINT cVisWindows; LIST_ENTRY aphkStart[NB_HOOKS]; CLIENTTHREADINFO cti; // Used only when no Desktop or pcti NULL.
/* ReactOS */
- /* Queue state tracking */ + /* Thread Queue state tracking */ // Send list QS_SENDMESSAGE // Post list QS_POSTMESSAGE|QS_HOTKEY|QS_PAINT|QS_TIMER|QS_KEY // Hard list QS_MOUSE|QS_KEY only // Accounting of queue bit sets, the rest are flags. QS_TIMER QS_PAINT counts are handled in thread information. - //DWORD nCntsQBits[QSIDCOUNTS]; // QS_KEY QS_MOUSEMOVE QS_MOUSEBUTTON QS_POSTMESSAGE QS_SENDMESSAGE QS_HOTKEY - + DWORD nCntsQBits[QSIDCOUNTS]; // QS_KEY QS_MOUSEMOVE QS_MOUSEBUTTON QS_POSTMESSAGE QS_SENDMESSAGE QS_HOTKEY + + /* Messages that are currently dispatched by this message queue, required for cleanup */ LIST_ENTRY LocalDispatchingMessagesHead; LIST_ENTRY WindowListHead; LIST_ENTRY W32CallbackListHead; @@ -141,6 +153,22 @@ } THREADINFO;
#include <poppack.h> + + +#define IntReferenceThreadInfo(pti) \ + InterlockedIncrement(&(pti)->RefCount) + +VOID FASTCALL UserDeleteW32Thread(PTHREADINFO); + +#define IntDereferenceThreadInfo(pti) \ + do { \ + if(InterlockedDecrement(&(pti)->RefCount) == 0) \ + { \ + ASSERT(pti->TIF_flags &= (TIF_INCLEANUP|TIF_DONTATTACHQUEUE) == (TIF_INCLEANUP|TIF_DONTATTACHQUEUE)); \ + UserDeleteW32Thread(pti); \ + } \ + } while(0) +
typedef struct _W32HEAP_USER_MAPPING { @@ -195,9 +223,9 @@ PTHREADINFO ptiList; PTHREADINFO ptiMainThread; struct _DESKTOP* rpdeskStartup; - PPROCESSINFO ppiNext; PCLS pclsPrivateList; PCLS pclsPublicList; + PPROCESSINFO ppiNext; INT cThreads; HDESK hdeskStartup; DWORD dwhmodLibLoadedMask;
Modified: trunk/reactos/win32ss/user/ntuser/window.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/window.... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/window.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/window.c [iso-8859-1] Fri May 10 22:28:18 2013 @@ -3779,7 +3779,7 @@ break;
case QUERY_WINDOW_ISHUNG: - Result = (DWORD)MsqIsHung(pWnd->head.pti->MessageQueue); + Result = (DWORD)MsqIsHung(pWnd->head.pti); break;
case QUERY_WINDOW_REAL_ID: