static PPAGED_LOOKASIDE_LIST pgMessageLookasideList;
static PPAGED_LOOKASIDE_LIST pgSendMsgLookasideList;
+INT PostMsgCount = 0;
INT SendMsgCount = 0;
PUSER_MESSAGE_QUEUE gpqCursor;
ULONG_PTR gdwMouseMoveExtraInfo = 0;
RtlZeroMemory(Message, sizeof(*Message));
RtlMoveMemory(&Message->Msg, Msg, sizeof(MSG));
-
+ PostMsgCount++;
return Message;
}
VOID FASTCALL
MsqDestroyMessage(PUSER_MESSAGE Message)
{
+ TRACE("Post Destroy %d\n",PostMsgCount)
if (Message->pti == NULL)
{
ERR("Double Free Message\n");
return;
}
+ RemoveEntryList(&Message->ListEntry);
Message->pti = NULL;
ExFreeToPagedLookasideList(pgMessageLookasideList, Message);
+ PostMsgCount--;
}
PUSER_SENT_MESSAGE FASTCALL
if (KEvent)
{
- Message->pkCompletionEvent = &Message->CompletionEvent;;
+ Message->pkCompletionEvent = &Message->CompletionEvent;
KeInitializeEvent(Message->pkCompletionEvent, NotificationEvent, FALSE);
}
SendMsgCount++;
- //ERR("AUM pti %p msg %p\n",PsGetCurrentThreadWin32Thread(),Message);
+ TRACE("AUM pti %p msg %p\n",PsGetCurrentThreadWin32Thread(),Message);
return Message;
}
pti->QuitPosted = 1;
pti->exitCode = PostedMessage->Msg.wParam;
}
- RemoveEntryList(&PostedMessage->ListEntry);
ClearMsgBitsMask(pti, PostedMessage->QS_Flags);
MsqDestroyMessage(PostedMessage);
CurrentEntry = pti->PostedMessagesListHead.Flink;
Message->QS_Flags = MessageBits;
Message->pti = pti;
MsqWakeQueue(pti, MessageBits, TRUE);
+ TRACE("Post Message %d\n",PostMsgCount);
}
VOID FASTCALL
}
}
-BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, BOOL* NotForUs, UINT first, UINT last)
+BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, BOOL* NotForUs, LONG_PTR ExtraInfo, UINT first, UINT last)
{
MSG clk_msg;
POINT pt;
if (pwndMsg == NULL || pwndMsg->head.pti->MessageQueue != MessageQueue)
{
// Crossing a boundary, so set cursor. See default message queue cursor.
- UserSetCursor(SYSTEMCUR(ARROW), FALSE);
+ IntSystemSetCursor(SYSTEMCUR(ARROW));
/* Remove and ignore the message */
*RemoveMessages = TRUE;
return FALSE;
}
}
+ if (pti->TIF_flags & TIF_MSGPOSCHANGED)
+ {
+ pti->TIF_flags &= ~TIF_MSGPOSCHANGED;
+ IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
+ }
+
/* message is accepted now (but still get dropped) */
event.message = msg->message;
hook.pt = msg->pt;
hook.hwnd = msg->hwnd;
hook.wHitTestCode = hittest;
- hook.dwExtraInfo = 0 /* extra_info */ ;
+ hook.dwExtraInfo = ExtraInfo;
if (co_HOOK_CallHooks( WH_MOUSE, *RemoveMessages ? HC_ACTION : HC_NOREMOVE,
message, (LPARAM)&hook ))
{
hook.pt = msg->pt;
hook.hwnd = msg->hwnd;
hook.wHitTestCode = hittest;
- hook.dwExtraInfo = 0 /* extra_info */ ;
+ hook.dwExtraInfo = ExtraInfo;
co_HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook );
ERR("WH_MOUSE dropped mouse message!\n");
PWND pWnd;
UINT ImmRet;
BOOL Ret = TRUE;
+ WPARAM wParam = Msg->wParam;
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
if (Msg->message == VK_PACKET)
}
}
+ //// Key Down!
+ if ( *RemoveMessages && Msg->message == WM_SYSKEYDOWN )
+ {
+ if ( HIWORD(Msg->lParam) & KF_ALTDOWN )
+ {
+ if ( Msg->wParam == VK_ESCAPE || Msg->wParam == VK_TAB ) // Alt-Tab/ESC Alt-Shift-Tab/ESC
+ {
+ WPARAM wParamTmp;
+
+ wParamTmp = UserGetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW;
+ TRACE("Send WM_SYSCOMMAND Alt-Tab/ESC Alt-Shift-Tab/ESC\n");
+ co_IntSendMessage( Msg->hwnd, WM_SYSCOMMAND, wParamTmp, Msg->wParam );
+
+ //// Keep looping.
+ Ret = FALSE;
+ //// Skip the rest.
+ goto Exit;
+ }
+ }
+ }
+
+ if ( *RemoveMessages && (Msg->message == WM_SYSKEYDOWN || Msg->message == WM_KEYDOWN) )
+ {
+ if (gdwLanguageToggleKey < 3)
+ {
+ if (IS_KEY_DOWN(gafAsyncKeyState, gdwLanguageToggleKey == 1 ? VK_LMENU : VK_CONTROL)) // L Alt 1 or Ctrl 2 .
+ {
+ if ( wParam == VK_LSHIFT ) gLanguageToggleKeyState = INPUTLANGCHANGE_FORWARD; // Left Alt - Left Shift, Next
+ //// FIXME : It seems to always be VK_LSHIFT.
+ if ( wParam == VK_RSHIFT ) gLanguageToggleKeyState = INPUTLANGCHANGE_BACKWARD; // Left Alt - Right Shift, Previous
+ }
+ }
+ }
+
+ //// Key Up! Alt Key Ctrl Key
+ if ( *RemoveMessages && (Msg->message == WM_SYSKEYUP || Msg->message == WM_KEYUP) )
+ {
+ // When initializing win32k: Reading from the registry hotkey combination
+ // to switch the keyboard layout and store it to global variable.
+ // Using this combination of hotkeys in this function
+
+ if ( gdwLanguageToggleKey < 3 &&
+ IS_KEY_DOWN(gafAsyncKeyState, gdwLanguageToggleKey == 1 ? VK_LMENU : VK_CONTROL) )
+ {
+ if ( Msg->wParam == VK_SHIFT && !(IS_KEY_DOWN(gafAsyncKeyState, VK_SHIFT)))
+ {
+ WPARAM wParamILR;
+ PKL pkl = pti->KeyboardLayout;
+
+ if (pWnd) UserDerefObjectCo(pWnd);
+
+ //// Seems to override message window.
+ if (!(pWnd = pti->MessageQueue->spwndFocus))
+ {
+ pWnd = pti->MessageQueue->spwndActive;
+ }
+ if (pWnd) UserRefObjectCo(pWnd, &Ref);
+
+ if (pkl != NULL && gLanguageToggleKeyState)
+ {
+ TRACE("Posting WM_INPUTLANGCHANGEREQUEST KeyState %d\n", gLanguageToggleKeyState );
+
+ wParamILR = gLanguageToggleKeyState;
+ // If system character set and font signature send flag.
+ if ( gSystemFS & pkl->dwFontSigs )
+ {
+ wParamILR |= INPUTLANGCHANGE_SYSCHARSET;
+ }
+
+ UserPostMessage( UserHMGetHandle(pWnd),
+ WM_INPUTLANGCHANGEREQUEST,
+ wParamILR,
+ (LPARAM)pkl->hkl );
+
+ gLanguageToggleKeyState = 0;
+ //// Keep looping.
+ Ret = FALSE;
+ //// Skip the rest.
+ goto Exit;
+ }
+ }
+ }
+ }
+
if (co_HOOK_CallHooks( WH_KEYBOARD,
*RemoveMessages ? HC_ACTION : HC_NOREMOVE,
LOWORD(Msg->wParam),
}
}
}
-
+Exit:
if (pWnd) UserDerefObjectCo(pWnd);
return Ret;
}
-BOOL co_IntProcessHardwareMessage(MSG* Msg, BOOL* RemoveMessages, BOOL* NotForUs, UINT first, UINT last)
+BOOL co_IntProcessHardwareMessage(MSG* Msg, BOOL* RemoveMessages, BOOL* NotForUs, LONG_PTR ExtraInfo, UINT first, UINT last)
{
if ( IS_MOUSE_MESSAGE(Msg->message))
{
- return co_IntProcessMouseMessage(Msg, RemoveMessages, NotForUs, first, last);
+ return co_IntProcessMouseMessage(Msg, RemoveMessages, NotForUs, ExtraInfo, first, last);
}
else if ( IS_KBD_MESSAGE(Msg->message))
{
return 1;
}
+/* check whether message is in the range of mouse messages */
+static inline BOOL is_mouse_message( UINT message )
+{
+ return ( //( message >= WM_NCMOUSEFIRST && message <= WM_NCMOUSELAST ) || This seems to break tests...
+ ( message >= WM_MOUSEFIRST && message <= WM_MOUSELAST ) ||
+ ( message >= WM_XBUTTONDOWN && message <= WM_XBUTTONDBLCLK ) ||
+ ( message >= WM_MBUTTONDOWN && message <= WM_MBUTTONDBLCLK ) ||
+ ( message >= WM_LBUTTONDOWN && message <= WM_RBUTTONDBLCLK ) );
+}
+
BOOL APIENTRY
co_MsqPeekHardwareMessage(IN PTHREADINFO pti,
IN BOOL Remove,
MSG msg;
ULONG_PTR idSave;
DWORD QS_Flags;
+ LONG_PTR ExtraInfo;
BOOL Ret = FALSE;
PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue;
if ( ( !Window || // 1
( Window == PWND_BOTTOM && CurrentMessage->Msg.hwnd == NULL ) || // 2
( Window != PWND_BOTTOM && Window->head.h == CurrentMessage->Msg.hwnd ) || // 3
- ( CurrentMessage->Msg.message == WM_MOUSEMOVE ) ) && // Null window for mouse moves.
+ ( is_mouse_message(CurrentMessage->Msg.message) ) ) && // Null window for anything mouse.
( ( ( MsgFilterLow == 0 && MsgFilterHigh == 0 ) && CurrentMessage->QS_Flags & QSflags ) ||
( MsgFilterLow <= CurrentMessage->Msg.message && MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
{
MessageQueue->idSysPeek = (ULONG_PTR)CurrentMessage;
msg = CurrentMessage->Msg;
+ ExtraInfo = CurrentMessage->ExtraInfo;
QS_Flags = CurrentMessage->QS_Flags;
NotForUs = FALSE;
UpdateKeyStateFromMsg(MessageQueue, &msg);
- AcceptMessage = co_IntProcessHardwareMessage(&msg, &Remove, &NotForUs, MsgFilterLow, MsgFilterHigh);
+ AcceptMessage = co_IntProcessHardwareMessage(&msg, &Remove, &NotForUs, ExtraInfo, MsgFilterLow, MsgFilterHigh);
if (Remove)
{
- if (CurrentMessage->pti != NULL)
+ if (CurrentMessage->pti != NULL && (MessageQueue->idSysPeek == (ULONG_PTR)CurrentMessage))
{
- RemoveEntryList(&CurrentMessage->ListEntry);
MsqDestroyMessage(CurrentMessage);
}
ClearMsgBitsMask(pti, QS_Flags);
if (AcceptMessage)
{
*pMsg = msg;
+ // Fix all but one wine win:test_GetMessagePos WM_TIMER tests. See PostTimerMessages.
+ if (!RtlEqualMemory(&pti->ptLast, &msg.pt, sizeof(POINT)))
+ {
+ pti->TIF_flags |= TIF_MSGPOSCHANGED;
+ }
+ pti->ptLast = msg.pt;
+ pti->timeLast = msg.time;
+ MessageQueue->ExtraInfo = ExtraInfo;
Ret = TRUE;
break;
}
IN UINT MsgFilterHigh,
IN UINT QSflags,
OUT LONG_PTR *ExtraInfo,
+ OUT DWORD *dwQEvent,
OUT PMSG Message)
{
PUSER_MESSAGE CurrentMessage;
*Message = CurrentMessage->Msg;
*ExtraInfo = CurrentMessage->ExtraInfo;
QS_Flags = CurrentMessage->QS_Flags;
+ if (dwQEvent) *dwQEvent = CurrentMessage->dwQEvent;
if (Remove)
{
if (CurrentMessage->pti != NULL)
{
- RemoveEntryList(&CurrentMessage->ListEntry);
MsqDestroyMessage(CurrentMessage);
}
ClearMsgBitsMask(pti, QS_Flags);
if (pti->pEThread)
{
BOOL Ret = TRUE;
- ObReferenceObject(pti->pEThread);
if (!(pti->pEThread->Tcb.SuspendCount) && !PsGetThreadFreezeCount(pti->pEThread)) Ret = FALSE;
- ObDereferenceObject(pti->pEThread);
return Ret;
}
return FALSE;
/* cleanup posted messages */
while (!IsListEmpty(&pti->PostedMessagesListHead))
{
- CurrentEntry = RemoveHeadList(&pti->PostedMessagesListHead);
+ CurrentEntry = pti->PostedMessagesListHead.Flink;
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
+ ERR("Thread Cleanup Post Messages %p\n",CurrentMessage);
if (CurrentMessage->dwQEvent)
{
if (CurrentMessage->dwQEvent == POSTEVENT_NWE)
else if ( pti == CurrentSentMessage->ptiSender ||
pti == CurrentSentMessage->ptiCallBackSender )
{
+ // Determine whether this message is being processed or not.
+ if ((CurrentSentMessage->flags & (SMF_RECEIVERBUSY|SMF_RECEIVEDMESSAGE)) != SMF_RECEIVEDMESSAGE)
+ {
+ CurrentSentMessage->flags |= SMF_RECEIVERFREE;
+ }
+
if (!(CurrentSentMessage->flags & SMF_RECEIVERFREE))
{
MsqCleanupMessageQueue(PTHREADINFO pti)
{
PUSER_MESSAGE_QUEUE MessageQueue;
+ PLIST_ENTRY CurrentEntry;
+ PUSER_MESSAGE CurrentMessage;
MessageQueue = pti->MessageQueue;
MessageQueue->cThreads--;
if (MessageQueue->ptiSysLock == pti) MessageQueue->ptiSysLock = NULL;
}
+ if (MessageQueue->cThreads == 0) //// Fix a crash related to CORE-10471 testing.
+ {
+ /* cleanup posted messages */
+ while (!IsListEmpty(&MessageQueue->HardwareMessagesListHead))
+ {
+ CurrentEntry = MessageQueue->HardwareMessagesListHead.Flink;
+ CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
+ ERR("MQ Cleanup Post Messages %p\n",CurrentMessage);
+ MsqDestroyMessage(CurrentMessage);
+ }
+ } ////
+
if (MessageQueue->CursorObject)
{
PCURICON_OBJECT pCursor = MessageQueue->CursorObject;