Msg.lParam |= KF_MENUMODE << 16;
}
+ // Post mouse move before posting key buttons, to keep it syned.
+ if (pFocusQueue->QF_flags & QF_MOUSEMOVED)
+ {
+ IntCoalesceMouseMove(pti);
+ }
+
/* Post a keyboard message */
TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam);
if (!Wnd) {ERR("Window is NULL\n");}
- MsqPostMessage(pti, &Msg, TRUE, QS_KEY, 0);
+ MsqPostMessage(pti, &Msg, TRUE, QS_KEY, 0, dwExtraInfo);
}
return TRUE;
NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
NewMsg.wParam = HIWORD(lpMsg->lParam);
NewMsg.lParam = LOWORD(lpMsg->lParam);
- MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0);
+ MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0, 0);
return TRUE;
}
{
TRACE("Msg: %x '%lc' (%04x) %08x\n", NewMsg.message, wch[i], wch[i], NewMsg.lParam);
NewMsg.wParam = wch[i];
- MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0);
+ MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0, 0);
}
bResult = TRUE;
}
pti->timeLast = LargeTickCount.u.LowPart;
pti->pcti->tickLastMsgChecked = LargeTickCount.u.LowPart;
+ // Post mouse moves while looping through peek messages.
+ if (pti->MessageQueue->QF_flags & QF_MOUSEMOVED)
+ {
+ IntCoalesceMouseMove(pti);
+ }
+
/* Dispatch sent messages here. */
while ( co_MsqDispatchOneSentMessage(pti) )
{
KeQueryTickCount(&LargeTickCount);
Message.time = MsqCalculateMessageTime(&LargeTickCount);
- MsqPostMessage(pti, &Message, FALSE, QS_POSTMESSAGE, 0);
+ MsqPostMessage(pti, &Message, FALSE, QS_POSTMESSAGE, 0, 0);
return TRUE;
}
}
else
{
- MsqPostMessage(pti, &Message, FALSE, QS_POSTMESSAGE, 0);
+ MsqPostMessage(pti, &Message, FALSE, QS_POSTMESSAGE, 0, 0);
}
}
return TRUE;
CLEANUP:
if (Window) UserDerefObjectCo(Window);
+ // Current Thread and it's a Copy Data message, then free kernel memory.
if ( !ptiSendTo && Msg == WM_COPYDATA )
{
ExFreePool((PVOID) lParam);
END_CLEANUP;
}
-
+#if 0
/*
This HACK function posts a message if the destination's message queue belongs to
another thread, otherwise it sends the message. It does not support broadcast
return (LRESULT)Result;
}
+#endif
static LRESULT FASTCALL
co_IntDoSendMessage( HWND hWnd,
static PPAGED_LOOKASIDE_LIST pgMessageLookasideList;
PUSER_MESSAGE_QUEUE gpqCursor;
+ULONG_PTR gdwMouseMoveExtraInfo = 0;
+DWORD gdwMouseMoveTimeStamp = 0;
+
/* FUNCTIONS *****************************************************************/
}
}
+/*
+ Get down key states from the queue of prior processed input message key states.
+
+ This fixes the left button dragging on the desktop and release sticking outline issue.
+ USB Tablet pointer seems to stick the most and leaves the box outline displayed.
+ */
+WPARAM FASTCALL
+MsqGetDownKeyState(PUSER_MESSAGE_QUEUE MessageQueue)
+{
+ WPARAM ret = 0;
+
+ if (gspv.bMouseBtnSwap)
+ {
+ if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_RBUTTON)) ret |= MK_LBUTTON;
+ if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_LBUTTON)) ret |= MK_RBUTTON;
+ }
+ else
+ {
+ if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_LBUTTON)) ret |= MK_LBUTTON;
+ if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_RBUTTON)) ret |= MK_RBUTTON;
+ }
+
+ if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_MBUTTON)) ret |= MK_MBUTTON;
+ if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_SHIFT)) ret |= MK_SHIFT;
+ if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_CONTROL)) ret |= MK_CONTROL;
+ if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_XBUTTON1)) ret |= MK_XBUTTON1;
+ if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_XBUTTON2)) ret |= MK_XBUTTON2;
+ return ret;
+}
+
HANDLE FASTCALL
IntMsqSetWakeMask(DWORD WakeMask)
{
VOID FASTCALL
ClearMsgBitsMask(PTHREADINFO pti, UINT MessageBits)
{
- PUSER_MESSAGE_QUEUE Queue;
UINT ClrMask = 0;
- Queue = pti->MessageQueue;
-
if (MessageBits & QS_KEY)
{
if (--pti->nCntsQBits[QSRosKey] == 0) ClrMask |= QS_KEY;
}
- if (MessageBits & QS_MOUSEMOVE) // ReactOS hard coded.
+ if (MessageBits & QS_MOUSEMOVE)
{ // Account for tracking mouse moves..
if (pti->nCntsQBits[QSRosMouseMove])
{
pti->nCntsQBits[QSRosMouseMove] = 0; // Throttle down count. Up to > 3:1 entries are ignored.
- }
- // Handle mouse move bits here.
- if (Queue->MouseMoved)
- {
ClrMask |= QS_MOUSEMOVE;
- Queue->MouseMoved = FALSE;
}
}
if (MessageBits & QS_MOUSEBUTTON)
}
/*
- Post Mouse Move.
+ Post the move or update the message still pending to be processed.
+ Do not overload the queue with mouse move messages.
*/
VOID FASTCALL
-MsqPostMouseMove(PTHREADINFO pti, MSG* Msg)
+MsqPostMouseMove(PTHREADINFO pti, MSG* Msg, LONG_PTR ExtraInfo)
{
PUSER_MESSAGE Message;
PLIST_ENTRY ListHead;
ListHead = &MessageQueue->HardwareMessagesListHead;
- MessageQueue->MouseMoved = TRUE;
-
+ // Do nothing if empty.
if (!IsListEmpty(ListHead->Flink))
- { // Look at the end of the list,
+ {
+ // Look at the end of the list,
Message = CONTAINING_RECORD(ListHead->Blink, USER_MESSAGE, ListEntry);
- // If the mouse move message is existing,
+
+ // If the mouse move message is existing on the list,
if (Message->Msg.message == WM_MOUSEMOVE)
{
- TRACE("Post Old MM Message in Q\n");
- Message->Msg = *Msg; // Overwrite the message with updated data!
+ // Overwrite the message with updated data!
+ Message->Msg = *Msg;
+
MsqWakeQueue(pti, QS_MOUSEMOVE, TRUE);
return;
}
}
- TRACE("Post New MM Message to Q\n");
- MsqPostMessage(pti, Msg, TRUE, QS_MOUSEMOVE, 0);
+
+ MsqPostMessage(pti, Msg, TRUE, QS_MOUSEMOVE, 0, ExtraInfo);
+}
+
+/*
+ Bring together the mouse move message.
+ Named "Coalesce" from Amine email ;^) (jt).
+ */
+VOID FASTCALL
+IntCoalesceMouseMove(PTHREADINFO pti)
+{
+ MSG Msg;
+ LARGE_INTEGER LargeTickCount;
+
+ // Force time stamp to update, keeping message time in sync.
+ if (gdwMouseMoveTimeStamp == 0)
+ {
+ KeQueryTickCount(&LargeTickCount);
+ gdwMouseMoveTimeStamp = MsqCalculateMessageTime(&LargeTickCount);
+ }
+
+ // Build mouse move message.
+ Msg.hwnd = NULL;
+ Msg.message = WM_MOUSEMOVE;
+ Msg.wParam = 0;
+ Msg.lParam = MAKELONG(gpsi->ptCursor.x, gpsi->ptCursor.y);
+ Msg.time = gdwMouseMoveTimeStamp;
+ Msg.pt = gpsi->ptCursor;
+
+ // Post the move.
+ MsqPostMouseMove(pti, &Msg, gdwMouseMoveExtraInfo);
+
+ // Zero the time stamp.
+ gdwMouseMoveTimeStamp = 0;
+
+ // Clear flag since the move was posted.
+ pti->MessageQueue->QF_flags &= ~QF_MOUSEMOVED;
}
VOID FASTCALL
gpqCursor = MessageQueue;
/* Mouse move is a special case */
- MsqPostMouseMove(pti, Msg);
+ MessageQueue->QF_flags |= QF_MOUSEMOVED;
+ gdwMouseMoveExtraInfo = dwExtraInfo;
+ gdwMouseMoveTimeStamp = Msg->time;
+ MsqWakeQueue(pti, QS_MOUSEMOVE, TRUE);
}
else
{
// ptiLastInput = pti; // Once this is set during Reboot or Shutdown, this prevents the exit window having foreground.
// Find all the Move Mouse calls and fix mouse set active focus issues......
}
+
+ // Post mouse move before posting mouse buttons, keep it in sync.
+ if (pti->MessageQueue->QF_flags & QF_MOUSEMOVED)
+ {
+ IntCoalesceMouseMove(pti);
+ }
+
TRACE("Posting mouse message to hwnd=%p!\n", UserHMGetHandle(pwnd));
- MsqPostMessage(pti, Msg, TRUE, QS_MOUSEBUTTON, 0);
+ MsqPostMessage(pti, Msg, TRUE, QS_MOUSEBUTTON, 0, dwExtraInfo);
}
}
else if (hdcScreen)
MSG* Msg,
BOOLEAN HardwareMessage,
DWORD MessageBits,
- DWORD dwQEvent)
+ DWORD dwQEvent,
+ LONG_PTR ExtraInfo)
{
PUSER_MESSAGE Message;
PUSER_MESSAGE_QUEUE MessageQueue;
if (Msg->message == WM_HOTKEY) MessageBits |= QS_HOTKEY; // Justin Case, just set it.
Message->dwQEvent = dwQEvent;
+ Message->ExtraInfo = ExtraInfo;
Message->QS_Flags = MessageBits;
Message->pti = pti;
MsqWakeQueue(pti, MessageBits, TRUE);
}
else
{
- pwndMsg = co_WinPosWindowFromPoint(NULL, &msg->pt, &hittest, FALSE);//TRUE);
+ pwndMsg = co_WinPosWindowFromPoint(pwndMsg, &msg->pt, &hittest, FALSE);
}
TRACE("Got mouse message for %p, hittest: 0x%x\n", msg->hwnd, hittest);
- if (pwndMsg == NULL || pwndMsg->head.pti != pti)
+ // Null window or not the same "Hardware" message queue.
+ if (pwndMsg == NULL || pwndMsg->head.pti->MessageQueue != pti->MessageQueue)
{
/* Remove and ignore the message */
*RemoveMessages = TRUE;
TRACE("Message out of range!!!\n");
RETURN(FALSE);
}
+
+ // Update mouse move down keys.
+ if (message == WM_MOUSEMOVE)
+ {
+ msg->wParam = MsqGetDownKeyState(MessageQueue);
+ }
}
if(gspv.bMouseClickLock)
*/
if ( ( !Window || // 1
( Window == PWND_BOTTOM && CurrentMessage->Msg.hwnd == NULL ) || // 2
- ( Window != PWND_BOTTOM && Window->head.h == CurrentMessage->Msg.hwnd ) ) && // 3
+ ( Window != PWND_BOTTOM && Window->head.h == CurrentMessage->Msg.hwnd ) || // 3
+ ( CurrentMessage->Msg.message == WM_MOUSEMOVE ) ) && // Null window for mouse moves.
( ( ( MsgFilterLow == 0 && MsgFilterHigh == 0 ) && CurrentMessage->QS_Flags & QSflags ) ||
( MsgFilterLow <= CurrentMessage->Msg.message && MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
{
/* Queue for hardware messages for the queue. */
LIST_ENTRY HardwareMessagesListHead;
- /* True if a WM_MOUSEMOVE is pending */
- BOOLEAN MouseMoved;
- /* Current WM_MOUSEMOVE message */
+ /* Last click message for translating double clicks */
MSG msgDblClk;
/* Current capture window for this queue. */
PWND spwndCapture;
#define QF_FMENUSTATUSBREAK 0x00000004
#define QF_FMENUSTATUS 0x00000008
#define QF_FF10STATUS 0x00000010
-#define QF_MOUSEMOVED 0x00000020 // See MouseMoved.
+#define QF_MOUSEMOVED 0x00000020
#define QF_ACTIVATIONCHANGE 0x00000040
#define QF_TABSWITCHING 0x00000080
#define QF_KEYSTATERESET 0x00000100
UINT uTimeout, BOOL Block, INT HookMessage, ULONG_PTR *uResult);
PUSER_MESSAGE FASTCALL MsqCreateMessage(LPMSG Msg);
VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE Message);
-VOID FASTCALL MsqPostMessage(PTHREADINFO, MSG*, BOOLEAN, DWORD, DWORD);
+VOID FASTCALL MsqPostMessage(PTHREADINFO, MSG*, BOOLEAN, DWORD, DWORD, LONG_PTR);
VOID FASTCALL MsqPostQuitMessage(PTHREADINFO pti, ULONG ExitCode);
BOOLEAN APIENTRY
MsqPeekMessage(IN PTHREADINFO pti,
BOOL HasPackedLParam,
INT HookMessage);
+VOID FASTCALL IntCoalesceMouseMove(PTHREADINFO);
LRESULT FASTCALL IntDispatchMessage(MSG* Msg);
BOOL FASTCALL IntTranslateKbdMessage(LPMSG lpMsg, UINT flags);
VOID FASTCALL co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook);
VOID FASTCALL MsqWakeQueue(PTHREADINFO,DWORD,BOOL);
VOID FASTCALL ClearMsgBitsMask(PTHREADINFO,UINT);
BOOL FASTCALL IntCallMsgFilter(LPMSG,INT);
+WPARAM FASTCALL MsqGetDownKeyState(PUSER_MESSAGE_QUEUE);
int UserShowCursor(BOOL bShow);
PCURICON_OBJECT