mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 17:01:53 +00:00
[Win32k|User32]
- Fixed SendNotifyMessage, thanks to Michael Martin callback changes. Fixed DispatchMessage when dealing with thread errors. Fixed all but one of the Get/PeekMessage wine tests. Fixed attaching threads to process information. Plus other fixes. - Implemented support for QS bits, ReplyMessage (not fully correct), and others. - Tested everything here, please post regressions so I can add more applications to the test list. This patch is synced with 49720 and 49772. After that there are graphic issues. - Credits goes to wine for helping with diagnosing issues in the ReactOS message system. svn path=/trunk/; revision=49929
This commit is contained in:
parent
3972c628bb
commit
7d1736a1a2
14 changed files with 657 additions and 279 deletions
|
@ -3182,7 +3182,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
|
|||
SetCapture(mt.OwnerWnd);
|
||||
(void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, mt.OwnerWnd);
|
||||
|
||||
ERR("MenuTrackMenu 1\n");
|
||||
FIXME("MenuTrackMenu 1\n");
|
||||
while (! fEndMenu)
|
||||
{
|
||||
PVOID menu = ValidateHandle(mt.CurrentMenu, VALIDATE_TYPE_MENU);
|
||||
|
@ -3210,6 +3210,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
|
|||
}
|
||||
WaitMessage();
|
||||
}
|
||||
//FIXME("MenuTrackMenu loop 1\n");
|
||||
}
|
||||
|
||||
/* check if EndMenu() tried to cancel us, by posting this message */
|
||||
|
@ -3417,6 +3418,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
|
|||
{
|
||||
PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
|
||||
DispatchMessageW( &msg );
|
||||
//FIXME("MenuTrackMenu loop 2\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -3427,8 +3429,9 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
|
|||
if (fRemove && !(mt.TrackFlags & TF_SKIPREMOVE) )
|
||||
PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
|
||||
else mt.TrackFlags &= ~TF_SKIPREMOVE;
|
||||
//FIXME("MenuTrackMenu loop 3\n");
|
||||
}
|
||||
ERR("MenuTrackMenu 2\n");
|
||||
FIXME("MenuTrackMenu 2\n");
|
||||
|
||||
(void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, NULL);
|
||||
SetCapture(NULL); /* release the capture */
|
||||
|
|
|
@ -1097,7 +1097,6 @@ WINAPI
|
|||
InSendMessage(VOID)
|
||||
{
|
||||
PCLIENTTHREADINFO pcti = GetWin32ClientInfo()->pClientThreadInfo;
|
||||
// FIXME("ISM %x\n",pcti);
|
||||
if ( pcti )
|
||||
{
|
||||
if (pcti->CTI_flags & CTI_INSENDMESSAGE)
|
||||
|
@ -1118,7 +1117,6 @@ InSendMessageEx(
|
|||
LPVOID lpReserved)
|
||||
{
|
||||
PCLIENTTHREADINFO pcti = GetWin32ClientInfo()->pClientThreadInfo;
|
||||
// FIXME("ISMEX %x\n",pcti);
|
||||
if (pcti && !(pcti->CTI_flags & CTI_INSENDMESSAGE))
|
||||
return ISMEX_NOSEND;
|
||||
else
|
||||
|
@ -1442,6 +1440,12 @@ IntCallMessageProc(IN PWND Wnd, IN HWND hWnd, IN UINT Msg, IN WPARAM wParam, IN
|
|||
|
||||
Class = DesktopPtrToUser(Wnd->pcls);
|
||||
WndProc = NULL;
|
||||
|
||||
if ( Wnd->head.pti != GetW32ThreadInfo())
|
||||
{ // Must be inside the same thread!
|
||||
SetLastError( ERROR_MESSAGE_SYNC_ONLY );
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
This is the message exchange for user32. If there's a need to monitor messages,
|
||||
do it here!
|
||||
|
@ -1586,11 +1590,16 @@ DispatchMessageA(CONST MSG *lpmsg)
|
|||
MSG UnicodeMsg;
|
||||
PWND Wnd;
|
||||
|
||||
if ( lpmsg->message & ~WM_MAXIMUM )
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lpmsg->hwnd != NULL)
|
||||
{
|
||||
Wnd = ValidateHwnd(lpmsg->hwnd);
|
||||
if (!Wnd || Wnd->head.pti != GetW32ThreadInfo())
|
||||
return 0;
|
||||
if (!Wnd) return 0;
|
||||
}
|
||||
else
|
||||
Wnd = NULL;
|
||||
|
@ -1602,7 +1611,7 @@ DispatchMessageA(CONST MSG *lpmsg)
|
|||
if ( lpmsg->message == WM_SYSTIMER )
|
||||
return NtUserDispatchMessage( (PMSG)lpmsg );
|
||||
|
||||
_SEH2_TRY // wine does this.
|
||||
_SEH2_TRY // wine does this. Hint: Prevents call to another thread....
|
||||
{
|
||||
Ret = WndProc(lpmsg->hwnd,
|
||||
lpmsg->message,
|
||||
|
@ -1613,7 +1622,6 @@ DispatchMessageA(CONST MSG *lpmsg)
|
|||
{
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
}
|
||||
else if (Wnd != NULL)
|
||||
{
|
||||
|
@ -1654,11 +1662,16 @@ DispatchMessageW(CONST MSG *lpmsg)
|
|||
LRESULT Ret = 0;
|
||||
PWND Wnd;
|
||||
|
||||
if ( lpmsg->message & ~WM_MAXIMUM )
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lpmsg->hwnd != NULL)
|
||||
{
|
||||
Wnd = ValidateHwnd(lpmsg->hwnd);
|
||||
if (!Wnd || Wnd->head.pti != GetW32ThreadInfo())
|
||||
return 0;
|
||||
if (!Wnd) return 0;
|
||||
}
|
||||
else
|
||||
Wnd = NULL;
|
||||
|
@ -1795,6 +1808,42 @@ GetMessageW(LPMSG lpMsg,
|
|||
return Res;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
PeekMessageWorker(PNTUSERGETMESSAGEINFO pInfo,
|
||||
HWND hWnd,
|
||||
UINT wMsgFilterMin,
|
||||
UINT wMsgFilterMax,
|
||||
UINT wRemoveMsg)
|
||||
{
|
||||
PCLIENTINFO pci;
|
||||
PCLIENTTHREADINFO pcti;
|
||||
pci = GetWin32ClientInfo();
|
||||
pcti = pci->pClientThreadInfo;
|
||||
|
||||
if (!hWnd && pci && pcti)
|
||||
{
|
||||
pci->cSpins++;
|
||||
|
||||
if ((pci->cSpins >= 100) && (pci->dwTIFlags & TIF_SPINNING))
|
||||
{ // Yield after 100 spin cycles and ready to swap vinyl.
|
||||
if (!(pci->dwTIFlags & TIF_WAITFORINPUTIDLE))
|
||||
{ // Not waiting for idle event.
|
||||
if (!pcti->fsChangeBits && !pcti->fsWakeBits)
|
||||
{ // No messages are available.
|
||||
if ((GetTickCount() - pcti->tickLastMsgChecked) > 1000)
|
||||
{ // Up the msg read count if over 1 sec.
|
||||
NtUserGetThreadState(THREADSTATE_UPTIMELASTREAD);
|
||||
}
|
||||
pci->cSpins = 0;
|
||||
ZwYieldExecution();
|
||||
FIXME("seeSpins!\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NtUserPeekMessage(pInfo, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
|
@ -1812,7 +1861,7 @@ PeekMessageA(LPMSG lpMsg,
|
|||
PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
|
||||
|
||||
MsgConversionCleanup(lpMsg, TRUE, FALSE, NULL);
|
||||
Res = NtUserPeekMessage(&Info, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
|
||||
Res = PeekMessageWorker(&Info, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
|
||||
if (-1 == (int) Res || !Res)
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -1865,7 +1914,7 @@ PeekMessageW(
|
|||
PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
|
||||
|
||||
MsgConversionCleanup(lpMsg, FALSE, FALSE, NULL);
|
||||
Res = NtUserPeekMessage(&Info, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
|
||||
Res = PeekMessageWorker(&Info, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
|
||||
if (-1 == (int) Res || !Res)
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -2567,7 +2616,8 @@ DWORD
|
|||
WINAPI
|
||||
RealGetQueueStatus(UINT flags)
|
||||
{
|
||||
if (flags & ~(QS_SMRESULT|QS_ALLPOSTMESSAGE|QS_ALLINPUT))
|
||||
#define QS_TEMPALLINPUT 255 // ATM, do not support QS_RAWINPUT
|
||||
if (flags & ~(QS_SMRESULT|QS_ALLPOSTMESSAGE|QS_TEMPALLINPUT))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_FLAGS );
|
||||
return 0;
|
||||
|
@ -2802,6 +2852,8 @@ RealMsgWaitForMultipleObjectsEx(
|
|||
LPHANDLE RealHandles;
|
||||
HANDLE MessageQueueHandle;
|
||||
DWORD Result;
|
||||
PCLIENTINFO pci;
|
||||
PCLIENTTHREADINFO pcti;
|
||||
|
||||
if (dwFlags & ~(MWMO_WAITALL | MWMO_ALERTABLE | MWMO_INPUTAVAILABLE))
|
||||
{
|
||||
|
@ -2809,14 +2861,21 @@ RealMsgWaitForMultipleObjectsEx(
|
|||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
/*
|
||||
if (dwFlags & MWMO_INPUTAVAILABLE)
|
||||
{
|
||||
RealGetQueueStatus(dwWakeMask);
|
||||
}
|
||||
*/
|
||||
pci = GetWin32ClientInfo();
|
||||
if (!pci) return WAIT_FAILED;
|
||||
|
||||
MessageQueueHandle = NtUserMsqSetWakeMask(dwWakeMask);
|
||||
pcti = pci->pClientThreadInfo;
|
||||
if (pcti && ( !nCount || !(dwFlags & MWMO_WAITALL) ))
|
||||
{
|
||||
if ( (pcti->fsChangeBits & LOWORD(dwWakeMask)) ||
|
||||
( (dwFlags & MWMO_INPUTAVAILABLE) && (pcti->fsWakeBits & LOWORD(dwWakeMask)) ) )
|
||||
{
|
||||
//FIXME("Chg 0x%x Wake 0x%x Mask 0x%x nCnt %d\n",pcti->fsChangeBits, pcti->fsWakeBits, dwWakeMask, nCount);
|
||||
return nCount;
|
||||
}
|
||||
}
|
||||
|
||||
MessageQueueHandle = NtUserMsqSetWakeMask(MAKELONG(dwWakeMask, dwFlags));
|
||||
if (MessageQueueHandle == NULL)
|
||||
{
|
||||
SetLastError(0); /* ? */
|
||||
|
@ -2840,7 +2899,7 @@ RealMsgWaitForMultipleObjectsEx(
|
|||
|
||||
HeapFree(GetProcessHeap(), 0, RealHandles);
|
||||
NtUserMsqClearWakeMask();
|
||||
|
||||
//FIXME("Result 0X%x\n",Result);
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
|
|
@ -2104,7 +2104,8 @@ enum ThreadStateRoutines
|
|||
THREADSTATE_PROGMANWINDOW,
|
||||
THREADSTATE_TASKMANWINDOW,
|
||||
THREADSTATE_GETMESSAGETIME,
|
||||
THREADSTATE_GETINPUTSTATE
|
||||
THREADSTATE_GETINPUTSTATE,
|
||||
THREADSTATE_UPTIMELASTREAD
|
||||
};
|
||||
|
||||
DWORD_PTR
|
||||
|
|
|
@ -8,10 +8,23 @@
|
|||
#define MSQ_ISEVENT 2
|
||||
#define MSQ_SENTNOWAIT 0x80000000
|
||||
|
||||
#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
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
MSG Msg;
|
||||
DWORD QS_Flags;
|
||||
} USER_MESSAGE, *PUSER_MESSAGE;
|
||||
|
||||
struct _USER_MESSAGE_QUEUE;
|
||||
|
@ -20,8 +33,10 @@ typedef struct _USER_SENT_MESSAGE
|
|||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
MSG Msg;
|
||||
DWORD QS_Flags; // Original QS bits used to create this message.
|
||||
PKEVENT CompletionEvent;
|
||||
LRESULT* Result;
|
||||
LRESULT lResult;
|
||||
struct _USER_MESSAGE_QUEUE* SenderQueue;
|
||||
SENDASYNCPROC CompletionCallback;
|
||||
ULONG_PTR CompletionCallbackContext;
|
||||
|
@ -31,16 +46,6 @@ typedef struct _USER_SENT_MESSAGE
|
|||
BOOL HasPackedLParam;
|
||||
} USER_SENT_MESSAGE, *PUSER_SENT_MESSAGE;
|
||||
|
||||
typedef struct _USER_SENT_MESSAGE_NOTIFY
|
||||
{
|
||||
SENDASYNCPROC CompletionCallback;
|
||||
ULONG_PTR CompletionCallbackContext;
|
||||
LRESULT Result;
|
||||
HWND hWnd;
|
||||
UINT Msg;
|
||||
LIST_ENTRY ListEntry;
|
||||
} USER_SENT_MESSAGE_NOTIFY, *PUSER_SENT_MESSAGE_NOTIFY;
|
||||
|
||||
typedef struct _USER_MESSAGE_QUEUE
|
||||
{
|
||||
/* Reference counter, only access this variable with interlocked functions! */
|
||||
|
@ -52,8 +57,6 @@ typedef struct _USER_MESSAGE_QUEUE
|
|||
LIST_ENTRY SentMessagesListHead;
|
||||
/* Queue of messages posted to the queue. */
|
||||
LIST_ENTRY PostedMessagesListHead;
|
||||
/* Queue of sent-message notifies for the queue. */
|
||||
LIST_ENTRY NotifyMessagesListHead;
|
||||
/* Queue for hardware messages for the queue. */
|
||||
LIST_ENTRY HardwareMessagesListHead;
|
||||
/* Lock for the hardware message list. */
|
||||
|
@ -76,8 +79,6 @@ typedef struct _USER_MESSAGE_QUEUE
|
|||
ULONG LastMsgRead;
|
||||
/* Current window with focus (ie. receives keyboard input) for this queue. */
|
||||
HWND FocusWindow;
|
||||
/* Count of paints pending. */
|
||||
ULONG PaintCount;
|
||||
/* Current active window for this queue. */
|
||||
HWND ActiveWindow;
|
||||
/* Current capture window for this queue. */
|
||||
|
@ -92,9 +93,11 @@ typedef struct _USER_MESSAGE_QUEUE
|
|||
PTHRDCARETINFO CaretInfo;
|
||||
|
||||
/* queue state tracking */
|
||||
WORD WakeMask;
|
||||
WORD QueueBits;
|
||||
WORD ChangedBits;
|
||||
// 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;
|
||||
|
@ -130,6 +133,7 @@ MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
|
|||
IN PWND Window,
|
||||
IN UINT MsgFilterLow,
|
||||
IN UINT MsgFilterHigh,
|
||||
IN UINT QSflags,
|
||||
OUT PMSG Message);
|
||||
BOOL APIENTRY
|
||||
co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
|
||||
|
@ -137,6 +141,7 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
|
|||
IN PWND Window,
|
||||
IN UINT MsgFilterLow,
|
||||
IN UINT MsgFilterHigh,
|
||||
IN UINT QSflags,
|
||||
OUT MSG* pMsg);
|
||||
BOOL APIENTRY
|
||||
co_MsqPeekMouseMove(IN PUSER_MESSAGE_QUEUE MessageQueue,
|
||||
|
@ -220,7 +225,6 @@ MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd);
|
|||
|
||||
__inline BOOL MsqIsSignaled( PUSER_MESSAGE_QUEUE queue );
|
||||
__inline VOID MsqSetQueueBits( PUSER_MESSAGE_QUEUE queue, WORD bits );
|
||||
__inline VOID MsqClearQueueBits( PUSER_MESSAGE_QUEUE queue, WORD bits );
|
||||
BOOL APIENTRY IntInitMessagePumpHook();
|
||||
BOOL APIENTRY IntUninitMessagePumpHook();
|
||||
#define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF))
|
||||
|
@ -285,5 +289,9 @@ MsqCalculateMessageTime(IN PLARGE_INTEGER TickCount)
|
|||
|
||||
VOID FASTCALL IdlePing(VOID);
|
||||
VOID FASTCALL IdlePong(VOID);
|
||||
BOOL FASTCALL co_MsqReplyMessage(LRESULT);
|
||||
UINT FASTCALL GetWakeMask(UINT, UINT);
|
||||
VOID FASTCALL MsqWakeQueue(PUSER_MESSAGE_QUEUE,DWORD,BOOL);
|
||||
VOID FASTCALL ClearMsgBitsMask(PUSER_MESSAGE_QUEUE,UINT);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -161,6 +161,7 @@ typedef struct _PROCESSINFO
|
|||
struct _DESKTOP* rpdeskStartup;
|
||||
PCLS pclsPrivateList;
|
||||
PCLS pclsPublicList;
|
||||
INT cThreads;
|
||||
DWORD dwhmodLibLoadedMask;
|
||||
HANDLE ahmodLibLoaded[CLIBS];
|
||||
struct _WINSTATION_OBJECT *prpwinsta;
|
||||
|
|
|
@ -268,6 +268,9 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
|
|||
Win32Thread->TIF_flags &= ~TIF_INCLEANUP;
|
||||
co_IntDestroyCaret(Win32Thread);
|
||||
Win32Thread->ppi = PsGetCurrentProcessWin32Process();
|
||||
Win32Thread->ptiSibling = Win32Thread->ppi->ptiList;
|
||||
Win32Thread->ppi->ptiList = Win32Thread;
|
||||
Win32Thread->ppi->cThreads++;
|
||||
if (Win32Thread->rpdesk && !Win32Thread->pDeskInfo)
|
||||
{
|
||||
Win32Thread->pDeskInfo = Win32Thread->rpdesk->pDeskInfo;
|
||||
|
@ -298,16 +301,39 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
|
|||
else
|
||||
{
|
||||
DPRINT1("No TEB for this Thread!\n");
|
||||
// System thread running! Now SendMessage should be okay.
|
||||
Win32Thread->pcti = &Win32Thread->cti;
|
||||
}
|
||||
Win32Thread->pEThread = Thread;
|
||||
}
|
||||
else
|
||||
{
|
||||
PTHREADINFO pti;
|
||||
PSINGLE_LIST_ENTRY e;
|
||||
|
||||
DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
|
||||
|
||||
Win32Thread->TIF_flags |= TIF_INCLEANUP;
|
||||
pti = Win32Thread->ppi->ptiList;
|
||||
if (pti == Win32Thread)
|
||||
{
|
||||
Win32Thread->ppi->ptiList = Win32Thread->ptiSibling;
|
||||
Win32Thread->ppi->cThreads--;
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
if (pti->ptiSibling == Win32Thread)
|
||||
{
|
||||
pti->ptiSibling = Win32Thread->ptiSibling;
|
||||
Win32Thread->ppi->cThreads--;
|
||||
break;
|
||||
}
|
||||
pti = pti->ptiSibling;
|
||||
}
|
||||
while (pti);
|
||||
}
|
||||
DceFreeThreadDCE(Win32Thread);
|
||||
HOOK_DestroyThreadHooks(Thread);
|
||||
EVENT_DestroyThreadEvents(Thread);
|
||||
|
@ -332,9 +358,7 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
|
|||
e = PopEntryList(&Win32Thread->ReferencesList);
|
||||
}
|
||||
|
||||
IntSetThreadDesktop(NULL,
|
||||
TRUE);
|
||||
|
||||
IntSetThreadDesktop(NULL, TRUE);
|
||||
|
||||
PsSetThreadWin32Thread(Thread, NULL);
|
||||
}
|
||||
|
|
|
@ -1926,7 +1926,7 @@ IntSetThreadDesktop(IN PDESKTOP DesktopObject,
|
|||
|
||||
RtlZeroMemory(&ctiSave, sizeof(CLIENTTHREADINFO));
|
||||
|
||||
if (W32Thread->pcti && OldDesktop)
|
||||
if (W32Thread->pcti && OldDesktop && NtCurrentTeb())
|
||||
{
|
||||
RtlCopyMemory(&ctiSave, W32Thread->pcti, sizeof(CLIENTTHREADINFO));
|
||||
DPRINT("Free ClientThreadInfo\n");
|
||||
|
@ -1934,7 +1934,7 @@ IntSetThreadDesktop(IN PDESKTOP DesktopObject,
|
|||
W32Thread->pcti = NULL;
|
||||
}
|
||||
|
||||
if (!W32Thread->pcti && DesktopObject)
|
||||
if (!W32Thread->pcti && DesktopObject && NtCurrentTeb())
|
||||
{
|
||||
DPRINT("Allocate ClientThreadInfo\n");
|
||||
W32Thread->pcti = DesktopHeapAlloc( DesktopObject,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* PURPOSE: Window classes
|
||||
* FILE: subsys/win32k/ntuser/class.c
|
||||
* FILE: subsystems/win32/win32k/ntuser/input.c
|
||||
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISION HISTORY:
|
||||
* 06-06-2001 CSH Created
|
||||
|
@ -206,13 +206,6 @@ MouseThreadMain(PVOID StartContext)
|
|||
NTSTATUS Status;
|
||||
MOUSE_ATTRIBUTES MouseAttr;
|
||||
|
||||
Status = Win32kInitWin32Thread(PsGetCurrentThread());
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Win32K: Failed making keyboard thread a win32 thread.\n");
|
||||
return; //(Status);
|
||||
}
|
||||
|
||||
KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
|
||||
LOW_REALTIME_PRIORITY + 3);
|
||||
|
||||
|
@ -1399,8 +1392,9 @@ IntKeyboardInput(KEYBDINPUT *ki)
|
|||
FocusMessageQueue->Desktop->pDeskInfo->LastInputWasKbd = TRUE;
|
||||
|
||||
Msg.pt = gpsi->ptCursor;
|
||||
|
||||
MsqPostMessage(FocusMessageQueue, &Msg, FALSE, QS_KEY);
|
||||
// Post to hardware queue, based on the first part of wine "some GetMessage tests"
|
||||
// in test_PeekMessage()
|
||||
MsqPostMessage(FocusMessageQueue, &Msg, TRUE, QS_KEY);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* PURPOSE: Messages
|
||||
* FILE: subsys/win32k/ntuser/message.c
|
||||
* FILE: subsystems/win32/win32k/ntuser/message.c
|
||||
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISION HISTORY:
|
||||
* 06-06-2001 CSH Created
|
||||
|
@ -342,12 +342,17 @@ IdlePing(VOID)
|
|||
|
||||
pti = PsGetCurrentThreadWin32Thread();
|
||||
|
||||
if ( pti && pti->pDeskInfo && pti == ptiForeground )
|
||||
if ( pti )
|
||||
{
|
||||
if ( pti->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) ||
|
||||
pti->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) )
|
||||
pti->pClientInfo->cSpins = 0; // Reset spins.
|
||||
|
||||
if ( pti->pDeskInfo && pti == ptiForeground )
|
||||
{
|
||||
co_HOOK_CallHooks(WH_FOREGROUNDIDLE,HC_ACTION,0,0);
|
||||
if ( pti->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) ||
|
||||
pti->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) )
|
||||
{
|
||||
co_HOOK_CallHooks(WH_FOREGROUNDIDLE,HC_ACTION,0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -371,6 +376,25 @@ IdlePong(VOID)
|
|||
}
|
||||
}
|
||||
|
||||
UINT FASTCALL
|
||||
GetWakeMask(UINT first, UINT last )
|
||||
{
|
||||
UINT mask = QS_POSTMESSAGE | QS_SENDMESSAGE; /* Always selected */
|
||||
|
||||
if (first || last)
|
||||
{
|
||||
if ((first <= WM_KEYLAST) && (last >= WM_KEYFIRST)) mask |= QS_KEY;
|
||||
if ( ((first <= WM_MOUSELAST) && (last >= WM_MOUSEFIRST)) ||
|
||||
((first <= WM_NCMOUSELAST) && (last >= WM_NCMOUSEFIRST)) ) mask |= QS_MOUSE;
|
||||
if ((first <= WM_TIMER) && (last >= WM_TIMER)) mask |= QS_TIMER;
|
||||
if ((first <= WM_SYSTIMER) && (last >= WM_SYSTIMER)) mask |= QS_TIMER;
|
||||
if ((first <= WM_PAINT) && (last >= WM_PAINT)) mask |= QS_PAINT;
|
||||
}
|
||||
else mask = QS_ALLINPUT;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static VOID FASTCALL
|
||||
IntCallWndProc( PWND Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
@ -424,6 +448,12 @@ IntDispatchMessage(PMSG pMsg)
|
|||
|
||||
pti = PsGetCurrentThreadWin32Thread();
|
||||
|
||||
if ( Window->head.pti != pti)
|
||||
{
|
||||
SetLastWin32Error( ERROR_MESSAGE_SYNC_ONLY );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((pMsg->message == WM_SYSTIMER) ||
|
||||
(pMsg->message == WM_TIMER)) &&
|
||||
(pMsg->lParam) )
|
||||
|
@ -503,24 +533,34 @@ IntDispatchMessage(PMSG pMsg)
|
|||
}
|
||||
|
||||
/*
|
||||
* Internal version of PeekMessage() doing all the work
|
||||
*/
|
||||
* Internal version of PeekMessage() doing all the work
|
||||
*/
|
||||
BOOL FASTCALL
|
||||
co_IntPeekMessage( PMSG Msg,
|
||||
PWND Window,
|
||||
UINT MsgFilterMin,
|
||||
UINT MsgFilterMax,
|
||||
UINT RemoveMsg )
|
||||
UINT RemoveMsg,
|
||||
BOOL bGMSG )
|
||||
{
|
||||
PTHREADINFO pti;
|
||||
PCLIENTINFO pci;
|
||||
LARGE_INTEGER LargeTickCount;
|
||||
PUSER_MESSAGE_QUEUE ThreadQueue;
|
||||
BOOL RemoveMessages;
|
||||
UINT ProcessMask;
|
||||
BOOL Hit = FALSE;
|
||||
|
||||
pti = PsGetCurrentThreadWin32Thread();
|
||||
ThreadQueue = pti->MessageQueue;
|
||||
pci = pti->pClientInfo;
|
||||
|
||||
RemoveMessages = RemoveMsg & PM_REMOVE;
|
||||
ProcessMask = HIWORD(RemoveMsg);
|
||||
|
||||
/* 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);
|
||||
|
||||
IdlePong();
|
||||
|
||||
|
@ -528,16 +568,49 @@ co_IntPeekMessage( PMSG Msg,
|
|||
{
|
||||
KeQueryTickCount(&LargeTickCount);
|
||||
ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
|
||||
pti->pcti->tickLastMsgChecked = LargeTickCount.u.LowPart;
|
||||
|
||||
/* Dispatch sent messages here. */
|
||||
while (co_MsqDispatchOneSentMessage(ThreadQueue)) ;
|
||||
while ( co_MsqDispatchOneSentMessage(ThreadQueue) )
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
if (Hit) return FALSE;
|
||||
|
||||
/* Clear changed bits so we can wait on them if we don't find a message */
|
||||
if (ProcessMask & QS_POSTMESSAGE)
|
||||
{
|
||||
pti->pcti->fsChangeBits &= ~(QS_POSTMESSAGE | QS_HOTKEY | QS_TIMER);
|
||||
if (MsgFilterMin == 0 && MsgFilterMax == 0) // wine hack does this; ~0U)
|
||||
{
|
||||
pti->pcti->fsChangeBits &= ~QS_ALLPOSTMESSAGE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ProcessMask & QS_INPUT)
|
||||
{
|
||||
pti->pcti->fsChangeBits &= ~QS_INPUT;
|
||||
}
|
||||
|
||||
/* Now check for normal messages. */
|
||||
if ((ProcessMask & QS_POSTMESSAGE) &&
|
||||
MsqPeekMessage( ThreadQueue,
|
||||
RemoveMessages,
|
||||
Window,
|
||||
MsgFilterMin,
|
||||
MsgFilterMax,
|
||||
ProcessMask,
|
||||
Msg ))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Now look for a quit message. */
|
||||
|
||||
if (ThreadQueue->QuitPosted)
|
||||
{
|
||||
/* According to the PSDK, WM_QUIT messages are always returned, regardless
|
||||
of the filter specified */
|
||||
of the filter specified */
|
||||
Msg->hwnd = NULL;
|
||||
Msg->message = WM_QUIT;
|
||||
Msg->wParam = ThreadQueue->QuitExitCode;
|
||||
|
@ -545,49 +618,48 @@ co_IntPeekMessage( PMSG Msg,
|
|||
if (RemoveMessages)
|
||||
{
|
||||
ThreadQueue->QuitPosted = FALSE;
|
||||
ClearMsgBitsMask(ThreadQueue, QS_POSTMESSAGE);
|
||||
pti->pcti->fsWakeBits &= ~QS_ALLPOSTMESSAGE;
|
||||
pti->pcti->fsChangeBits &= ~QS_ALLPOSTMESSAGE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Now check for normal messages. */
|
||||
if (MsqPeekMessage( ThreadQueue,
|
||||
RemoveMessages,
|
||||
Window,
|
||||
MsgFilterMin,
|
||||
MsgFilterMax,
|
||||
Msg ))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Check for hardware events. */
|
||||
if(co_MsqPeekMouseMove(ThreadQueue,
|
||||
RemoveMessages,
|
||||
Window,
|
||||
MsgFilterMin,
|
||||
MsgFilterMax,
|
||||
Msg ))
|
||||
if ((ProcessMask & QS_MOUSE) &&
|
||||
co_MsqPeekMouseMove( ThreadQueue,
|
||||
RemoveMessages,
|
||||
Window,
|
||||
MsgFilterMin,
|
||||
MsgFilterMax,
|
||||
Msg ))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if(co_MsqPeekHardwareMessage(ThreadQueue,
|
||||
RemoveMessages,
|
||||
Window,
|
||||
MsgFilterMin,
|
||||
MsgFilterMax,
|
||||
Msg))
|
||||
if ((ProcessMask & QS_INPUT) &&
|
||||
co_MsqPeekHardwareMessage( ThreadQueue,
|
||||
RemoveMessages,
|
||||
Window,
|
||||
MsgFilterMin,
|
||||
MsgFilterMax,
|
||||
ProcessMask,
|
||||
Msg))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Check for sent messages again. */
|
||||
while (co_MsqDispatchOneSentMessage(ThreadQueue))
|
||||
;
|
||||
while ( co_MsqDispatchOneSentMessage(ThreadQueue) )
|
||||
{
|
||||
if (HIWORD(RemoveMsg) && !bGMSG) Hit = TRUE;
|
||||
}
|
||||
if (Hit) return FALSE;
|
||||
|
||||
/* Check for paint messages. */
|
||||
if( IntGetPaintMessage( Window,
|
||||
if ((ProcessMask & QS_PAINT) &&
|
||||
pti->cPaintsReady &&
|
||||
IntGetPaintMessage( Window,
|
||||
MsgFilterMin,
|
||||
MsgFilterMax,
|
||||
pti,
|
||||
|
@ -597,7 +669,11 @@ co_IntPeekMessage( PMSG Msg,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if (PostTimerMessages(Window))
|
||||
/* This is correct, check for the current threads timers waiting to be
|
||||
posted to this threads message queue. If any we loop again.
|
||||
*/
|
||||
if ((ProcessMask & QS_TIMER) &&
|
||||
PostTimerMessages(Window))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -718,11 +794,12 @@ co_IntWaitMessage( PWND Window,
|
|||
|
||||
do
|
||||
{
|
||||
if ( co_IntPeekMessage( &Msg,
|
||||
Window,
|
||||
MsgFilterMin,
|
||||
MsgFilterMax,
|
||||
PM_NOREMOVE))
|
||||
if ( co_IntPeekMessage( &Msg, // Dont reenter!
|
||||
Window,
|
||||
MsgFilterMin,
|
||||
MsgFilterMax,
|
||||
MAKELONG( PM_NOREMOVE, GetWakeMask( MsgFilterMin, MsgFilterMax)),
|
||||
TRUE ) ) // act like GetMessage.
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -754,6 +831,7 @@ co_IntGetPeekMessage( PMSG pMsg,
|
|||
BOOL bGMSG )
|
||||
{
|
||||
PWND Window;
|
||||
PTHREADINFO pti;
|
||||
BOOL Present = FALSE;
|
||||
|
||||
if ( hWnd == HWND_TOPMOST || hWnd == HWND_BROADCAST )
|
||||
|
@ -781,13 +859,19 @@ co_IntGetPeekMessage( PMSG pMsg,
|
|||
MsgFilterMax = 0;
|
||||
}
|
||||
|
||||
if (bGMSG)
|
||||
{
|
||||
RemoveMsg |= ((GetWakeMask( MsgFilterMin, MsgFilterMax ))<< 16);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
Present = co_IntPeekMessage( pMsg,
|
||||
Window,
|
||||
MsgFilterMin,
|
||||
MsgFilterMax,
|
||||
RemoveMsg );
|
||||
RemoveMsg,
|
||||
bGMSG );
|
||||
if (Present)
|
||||
{
|
||||
// The WH_GETMESSAGE hook enables an application to monitor messages about to
|
||||
|
@ -796,13 +880,19 @@ co_IntGetPeekMessage( PMSG pMsg,
|
|||
co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)pMsg);
|
||||
|
||||
if ( bGMSG )
|
||||
return (WM_QUIT != pMsg->message);
|
||||
{
|
||||
Present = (WM_QUIT != pMsg->message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( bGMSG )
|
||||
{
|
||||
if ( !co_IntWaitMessage(Window, MsgFilterMin, MsgFilterMax) )
|
||||
return -1;
|
||||
{
|
||||
Present = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -821,6 +911,14 @@ co_IntGetPeekMessage( PMSG pMsg,
|
|||
}
|
||||
while( bGMSG && !Present );
|
||||
|
||||
pti = PsGetCurrentThreadWin32Thread();
|
||||
// Been spinning, time to swap vinyl...
|
||||
if (pti->pClientInfo->cSpins >= 100)
|
||||
{
|
||||
// Clear the spin cycle to fix the mix.
|
||||
pti->pClientInfo->cSpins = 0;
|
||||
//if (!(pti->TIF_flags & TIF_SPINNING)) FIXME need to swap vinyl..
|
||||
}
|
||||
return Present;
|
||||
}
|
||||
|
||||
|
@ -947,7 +1045,7 @@ UserPostMessage( HWND Wnd,
|
|||
MsqPostQuitMessage(Window->head.pti->MessageQueue, wParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
Message.hwnd = Wnd;
|
||||
Message.message = Msg;
|
||||
Message.wParam = wParam;
|
||||
|
@ -1283,7 +1381,9 @@ co_IntSendMessageWithCallBack( HWND hWnd,
|
|||
Message->Msg.lParam = lParamPacked;
|
||||
Message->CompletionEvent = NULL;
|
||||
Message->Result = 0;
|
||||
Message->SenderQueue = NULL; //Win32Thread->MessageQueue;
|
||||
Message->lResult = 0;
|
||||
Message->QS_Flags = 0;
|
||||
Message->SenderQueue = NULL; // mjmartin, you are right! This is null. Win32Thread->MessageQueue;
|
||||
|
||||
IntReferenceMessageQueue(Window->head.pti->MessageQueue);
|
||||
Message->CompletionCallback = CompletionCallback;
|
||||
|
@ -1291,6 +1391,9 @@ co_IntSendMessageWithCallBack( HWND hWnd,
|
|||
Message->HookMessage = MSQ_NORMAL | MSQ_SENTNOWAIT;
|
||||
Message->HasPackedLParam = (lParamBufferSize > 0);
|
||||
|
||||
Message->QS_Flags = QS_SENDMESSAGE;
|
||||
MsqWakeQueue(Window->head.pti->MessageQueue, QS_SENDMESSAGE, FALSE);
|
||||
|
||||
InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
|
||||
IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
|
||||
|
||||
|
@ -1468,7 +1571,7 @@ UserSendNotifyMessage( HWND hWnd,
|
|||
WPARAM wParam,
|
||||
LPARAM lParam )
|
||||
{
|
||||
BOOL Result = TRUE;
|
||||
BOOL Ret = TRUE;
|
||||
|
||||
if (FindMsgMemory(Msg) != 0)
|
||||
{
|
||||
|
@ -1491,37 +1594,28 @@ UserSendNotifyMessage( HWND hWnd,
|
|||
UserSendNotifyMessage(DesktopWindow->head.h, Msg, wParam, lParam);
|
||||
for (i = 0; List[i]; i++)
|
||||
{
|
||||
UserSendNotifyMessage(List[i], Msg, wParam, lParam);
|
||||
Ret = UserSendNotifyMessage(List[i], Msg, wParam, lParam);
|
||||
if (!Ret)
|
||||
{
|
||||
DPRINT1("SendNotifyMessage: Failed in Broadcast!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
ExFreePool(List);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ULONG_PTR PResult;
|
||||
PTHREADINFO pti;
|
||||
PWND Window;
|
||||
|
||||
if ( !(Window = UserGetWindowObject(hWnd)) ) return FALSE;
|
||||
|
||||
pti = PsGetCurrentThreadWin32Thread();
|
||||
|
||||
if (Window->head.pti->MessageQueue != pti->MessageQueue)
|
||||
{ // Send message w/o waiting for it.
|
||||
Result = UserPostMessage(hWnd, Msg, wParam, lParam);
|
||||
}
|
||||
else
|
||||
{ // Handle message and callback.
|
||||
Result = co_IntSendMessageTimeoutSingle( hWnd,
|
||||
Msg,
|
||||
wParam,
|
||||
lParam,
|
||||
SMTO_NORMAL,
|
||||
0,
|
||||
&PResult );
|
||||
}
|
||||
ULONG_PTR lResult = 0;
|
||||
Ret = co_IntSendMessageWithCallBack( hWnd,
|
||||
Msg,
|
||||
wParam,
|
||||
lParam,
|
||||
NULL,
|
||||
0,
|
||||
&lResult);
|
||||
}
|
||||
return Result;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1537,15 +1631,13 @@ IntGetQueueStatus(DWORD Changes)
|
|||
// wine:
|
||||
Changes &= (QS_ALLINPUT|QS_ALLPOSTMESSAGE|QS_SMRESULT);
|
||||
|
||||
Result = MAKELONG(Queue->ChangedBits & Changes, Queue->QueueBits & Changes);
|
||||
/* High word, types of messages currently in the queue.
|
||||
Low word, types of messages that have been added to the queue and that
|
||||
are still in the queue
|
||||
*/
|
||||
Result = MAKELONG(pti->pcti->fsChangeBits & Changes, pti->pcti->fsWakeBits & Changes);
|
||||
|
||||
if (pti->pcti)
|
||||
{
|
||||
pti->pcti->fsChangeBits = Queue->ChangedBits;
|
||||
pti->pcti->fsChangeBits &= ~Changes;
|
||||
}
|
||||
|
||||
Queue->ChangedBits &= ~Changes;
|
||||
pti->pcti->fsChangeBits &= ~Changes;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
@ -1684,9 +1776,9 @@ NtUserWaitMessage(VOID)
|
|||
BOOL ret;
|
||||
|
||||
UserEnterExclusive();
|
||||
|
||||
DPRINT("NtUserWaitMessage Enter\n");
|
||||
ret = co_IntWaitMessage(NULL, 0, 0);
|
||||
|
||||
DPRINT("NtUserWaitMessage Leave\n");
|
||||
UserLeave();
|
||||
|
||||
return ret;
|
||||
|
@ -2338,6 +2430,13 @@ NtUserWaitForInputIdle( IN HANDLE hProcess,
|
|||
if (dwMilliseconds != INFINITE)
|
||||
Timeout.QuadPart = (LONGLONG) dwMilliseconds * (LONGLONG) -10000;
|
||||
|
||||
W32Process->W32PF_flags |= W32PF_WAITFORINPUTIDLE;
|
||||
for (pti = W32Process->ptiList; pti; pti = pti->ptiSibling)
|
||||
{
|
||||
pti->TIF_flags |= TIF_WAITFORINPUTIDLE;
|
||||
pti->pClientInfo->dwTIFlags = pti->TIF_flags;
|
||||
}
|
||||
|
||||
DPRINT("WFII: ppi 0x%x\n",W32Process);
|
||||
DPRINT("WFII: waiting for %p\n", Handles[1] );
|
||||
do
|
||||
|
@ -2368,7 +2467,7 @@ NtUserWaitForInputIdle( IN HANDLE hProcess,
|
|||
case STATUS_WAIT_2:
|
||||
{
|
||||
MSG Msg;
|
||||
co_IntPeekMessage( &Msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE );
|
||||
co_IntGetPeekMessage( &Msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE, FALSE);
|
||||
DPRINT1("WFII: WAIT 2\n");
|
||||
}
|
||||
break;
|
||||
|
@ -2387,6 +2486,12 @@ NtUserWaitForInputIdle( IN HANDLE hProcess,
|
|||
while (TRUE);
|
||||
|
||||
WaitExit:
|
||||
for (pti = W32Process->ptiList; pti; pti = pti->ptiSibling)
|
||||
{
|
||||
pti->TIF_flags &= ~TIF_WAITFORINPUTIDLE;
|
||||
pti->pClientInfo->dwTIFlags = pti->TIF_flags;
|
||||
}
|
||||
W32Process->W32PF_flags &= ~W32PF_WAITFORINPUTIDLE;
|
||||
ObDereferenceObject(Process);
|
||||
UserLeave();
|
||||
return Status;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* PURPOSE: Misc User funcs
|
||||
* FILE: subsystem/win32/win32k/ntuser/misc.c
|
||||
* FILE: subsystems/win32/win32k/ntuser/misc.c
|
||||
* PROGRAMER: Ge van Geldorp (ge@gse.nl)
|
||||
* REVISION HISTORY:
|
||||
* 2003/05/22 Created
|
||||
|
@ -102,6 +102,8 @@ NtUserGetThreadState(
|
|||
break;
|
||||
case THREADSTATE_INSENDMESSAGE:
|
||||
{
|
||||
PUSER_SENT_MESSAGE Message;
|
||||
PLIST_ENTRY Entry;
|
||||
PUSER_MESSAGE_QUEUE MessageQueue =
|
||||
((PTHREADINFO)PsGetCurrentThreadWin32Thread())->MessageQueue;
|
||||
DPRINT1("THREADSTATE_INSENDMESSAGE\n");
|
||||
|
@ -109,21 +111,39 @@ NtUserGetThreadState(
|
|||
ret = ISMEX_NOSEND;
|
||||
if (!IsListEmpty(&MessageQueue->SentMessagesListHead))
|
||||
{
|
||||
ret = ISMEX_SEND;
|
||||
Entry = MessageQueue->SentMessagesListHead.Flink;
|
||||
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
|
||||
|
||||
if (Message->SenderQueue)
|
||||
ret = ISMEX_SEND;
|
||||
else
|
||||
{
|
||||
if (Message->CompletionCallback)
|
||||
ret = ISMEX_CALLBACK;
|
||||
else
|
||||
ret = ISMEX_NOTIFY;
|
||||
}
|
||||
/* if ReplyMessage */
|
||||
if (Message->QS_Flags & QS_SMRESULT) ret |= ISMEX_REPLIED;
|
||||
}
|
||||
else if (!IsListEmpty(&MessageQueue->NotifyMessagesListHead))
|
||||
{
|
||||
/* FIXME Need to set message flag when in callback mode with notify */
|
||||
ret = ISMEX_NOTIFY;
|
||||
}
|
||||
/* FIXME Need to set message flag if replied to or ReplyMessage */
|
||||
|
||||
break;
|
||||
}
|
||||
case THREADSTATE_GETMESSAGETIME:
|
||||
/* FIXME Needs more work! */
|
||||
case THREADSTATE_GETMESSAGETIME:
|
||||
ret = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->timeLast;
|
||||
break;
|
||||
|
||||
case THREADSTATE_UPTIMELASTREAD:
|
||||
{
|
||||
PTHREADINFO pti;
|
||||
LARGE_INTEGER LargeTickCount;
|
||||
pti = PsGetCurrentThreadWin32Thread();
|
||||
KeQueryTickCount(&LargeTickCount);
|
||||
pti->MessageQueue->LastMsgRead = LargeTickCount.u.LowPart;
|
||||
pti->pcti->tickLastMsgChecked = LargeTickCount.u.LowPart;
|
||||
}
|
||||
break;
|
||||
|
||||
case THREADSTATE_GETINPUTSTATE:
|
||||
ret = LOWORD(IntGetQueueStatus(QS_POSTMESSAGE|QS_TIMER|QS_PAINT|QS_SENDMESSAGE|QS_INPUT)) & (QS_KEY | QS_MOUSEBUTTON);
|
||||
break;
|
||||
|
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
* ReactOS W32 Subsystem
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -41,74 +23,6 @@ static PAGED_LOOKASIDE_LIST MessageLookasideList;
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
HANDLE FASTCALL
|
||||
IntMsqSetWakeMask(DWORD WakeMask)
|
||||
{
|
||||
PTHREADINFO Win32Thread;
|
||||
PUSER_MESSAGE_QUEUE MessageQueue;
|
||||
HANDLE MessageEventHandle;
|
||||
|
||||
Win32Thread = PsGetCurrentThreadWin32Thread();
|
||||
if (Win32Thread == NULL || Win32Thread->MessageQueue == NULL)
|
||||
return 0;
|
||||
|
||||
MessageQueue = Win32Thread->MessageQueue;
|
||||
MessageQueue->WakeMask = WakeMask;
|
||||
MessageEventHandle = MessageQueue->NewMessagesHandle;
|
||||
|
||||
if (Win32Thread->pcti)
|
||||
Win32Thread->pcti->fsWakeMask = WakeMask;
|
||||
|
||||
IdlePing();
|
||||
|
||||
return MessageEventHandle;
|
||||
}
|
||||
|
||||
BOOL FASTCALL
|
||||
IntMsqClearWakeMask(VOID)
|
||||
{
|
||||
PTHREADINFO Win32Thread;
|
||||
PUSER_MESSAGE_QUEUE MessageQueue;
|
||||
|
||||
Win32Thread = PsGetCurrentThreadWin32Thread();
|
||||
if (Win32Thread == NULL || Win32Thread->MessageQueue == NULL)
|
||||
return FALSE;
|
||||
|
||||
MessageQueue = Win32Thread->MessageQueue;
|
||||
// HACK!!!!!!! Newbies that wrote this should hold your head down in shame! (jt)
|
||||
MessageQueue->WakeMask = ~0;
|
||||
|
||||
if (Win32Thread->pcti)
|
||||
Win32Thread->pcti->fsWakeMask = 0;
|
||||
|
||||
IdlePong();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
MsqWakeQueue(PUSER_MESSAGE_QUEUE Queue, DWORD MessageBits)
|
||||
{
|
||||
Queue->QueueBits |= MessageBits;
|
||||
Queue->ChangedBits |= MessageBits;
|
||||
if (Queue->WakeMask & MessageBits)
|
||||
KeSetEvent(Queue->NewMessages, IO_NO_INCREMENT, FALSE);
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue)
|
||||
{
|
||||
Queue->PaintCount++;
|
||||
MsqWakeQueue(Queue, QS_PAINT);
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue)
|
||||
{
|
||||
Queue->PaintCount--;
|
||||
}
|
||||
|
||||
|
||||
INIT_FUNCTION
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
|
@ -125,12 +39,153 @@ MsqInitializeImpl(VOID)
|
|||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
HANDLE FASTCALL
|
||||
IntMsqSetWakeMask(DWORD WakeMask)
|
||||
{
|
||||
PTHREADINFO Win32Thread;
|
||||
PUSER_MESSAGE_QUEUE MessageQueue;
|
||||
HANDLE MessageEventHandle;
|
||||
DWORD dwFlags = HIWORD(WakeMask);
|
||||
|
||||
Win32Thread = PsGetCurrentThreadWin32Thread();
|
||||
if (Win32Thread == NULL || Win32Thread->MessageQueue == NULL)
|
||||
return 0;
|
||||
|
||||
MessageQueue = Win32Thread->MessageQueue;
|
||||
// Win32Thread->pEventQueueServer; IntMsqSetWakeMask returns Win32Thread->hEventQueueClient
|
||||
MessageEventHandle = MessageQueue->NewMessagesHandle;
|
||||
|
||||
if (Win32Thread->pcti)
|
||||
{
|
||||
if ( (Win32Thread->pcti->fsChangeBits & LOWORD(WakeMask)) ||
|
||||
( (dwFlags & MWMO_INPUTAVAILABLE) && (Win32Thread->pcti->fsWakeBits & LOWORD(WakeMask)) ) )
|
||||
{
|
||||
DPRINT1("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!
|
||||
return MessageEventHandle;
|
||||
}
|
||||
}
|
||||
|
||||
IdlePing();
|
||||
|
||||
return MessageEventHandle;
|
||||
}
|
||||
|
||||
BOOL FASTCALL
|
||||
IntMsqClearWakeMask(VOID)
|
||||
{
|
||||
PTHREADINFO Win32Thread;
|
||||
|
||||
Win32Thread = PsGetCurrentThreadWin32Thread();
|
||||
if (Win32Thread == NULL || Win32Thread->MessageQueue == NULL)
|
||||
return FALSE;
|
||||
// Very hacky, but that is what they do.
|
||||
Win32Thread->pcti->fsWakeBits = 0;
|
||||
|
||||
IdlePong();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
Due to the uncertainty of knowing what was set in our multilevel message queue,
|
||||
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;
|
||||
|
||||
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 (KeyEvent)
|
||||
KeSetEvent(Queue->NewMessages, IO_NO_INCREMENT, FALSE);
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
ClearMsgBitsMask(PUSER_MESSAGE_QUEUE Queue, UINT MessageBits)
|
||||
{
|
||||
PTHREADINFO pti;
|
||||
UINT ClrMask = 0;
|
||||
|
||||
pti = Queue->Thread->Tcb.Win32Thread;
|
||||
|
||||
if (MessageBits & QS_KEY)
|
||||
{
|
||||
if (--Queue->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;
|
||||
// Handle mouse move bits here.
|
||||
if (Queue->MouseMoved) ClrMask |= QS_MOUSEMOVE;
|
||||
}
|
||||
if (MessageBits & QS_MOUSEBUTTON)
|
||||
{
|
||||
if (--Queue->nCntsQBits[QSRosMouseButton] == 0) ClrMask |= QS_MOUSEBUTTON;
|
||||
}
|
||||
if (MessageBits & QS_POSTMESSAGE)
|
||||
{
|
||||
if (--Queue->nCntsQBits[QSRosPostMessage] == 0) ClrMask |= QS_POSTMESSAGE;
|
||||
}
|
||||
if (MessageBits & QS_TIMER) // ReactOS hard coded.
|
||||
{ // Handle timer bits here.
|
||||
if ( pti->cTimersReady )
|
||||
{
|
||||
if (--pti->cTimersReady == 0) ClrMask |= QS_TIMER;
|
||||
}
|
||||
}
|
||||
if (MessageBits & QS_PAINT) // ReactOS hard coded.
|
||||
{ // Handle paint bits here.
|
||||
if ( pti->cPaintsReady )
|
||||
{
|
||||
if (--pti->cPaintsReady == 0) ClrMask |= QS_PAINT;
|
||||
}
|
||||
}
|
||||
if (MessageBits & QS_SENDMESSAGE)
|
||||
{
|
||||
if (--Queue->nCntsQBits[QSRosSendMessage] == 0) ClrMask |= QS_SENDMESSAGE;
|
||||
}
|
||||
if (MessageBits & QS_HOTKEY)
|
||||
{
|
||||
if (--Queue->nCntsQBits[QSRosHotKey] == 0) ClrMask |= QS_HOTKEY;
|
||||
}
|
||||
|
||||
pti->pcti->fsWakeBits &= ~ClrMask;
|
||||
pti->pcti->fsChangeBits &= ~ClrMask;
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue)
|
||||
{
|
||||
PTHREADINFO pti;
|
||||
pti = Queue->Thread->Tcb.Win32Thread;
|
||||
pti->cPaintsReady++;
|
||||
MsqWakeQueue(Queue, QS_PAINT, TRUE);
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue)
|
||||
{
|
||||
ClearMsgBitsMask(Queue, QS_PAINT);
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
MsqPostMouseMove(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg)
|
||||
{
|
||||
MessageQueue->MouseMoveMsg = *Msg;
|
||||
MessageQueue->MouseMoved = TRUE;
|
||||
MsqWakeQueue(MessageQueue, QS_MOUSEMOVE);
|
||||
MsqWakeQueue(MessageQueue, QS_MOUSEMOVE, TRUE);
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
|
@ -366,6 +421,7 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
|
|||
PUSER_SENT_MESSAGE Message;
|
||||
PLIST_ENTRY Entry;
|
||||
LRESULT Result;
|
||||
PTHREADINFO pti;
|
||||
|
||||
if (IsListEmpty(&MessageQueue->SentMessagesListHead))
|
||||
{
|
||||
|
@ -376,11 +432,20 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
|
|||
Entry = RemoveHeadList(&MessageQueue->SentMessagesListHead);
|
||||
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
|
||||
|
||||
pti = MessageQueue->Thread->Tcb.Win32Thread;
|
||||
// Processing a message sent to it from another thread.
|
||||
if ( MessageQueue != Message->SenderQueue ) // 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,
|
||||
&Message->ListEntry);
|
||||
|
||||
ClearMsgBitsMask(MessageQueue, Message->QS_Flags);
|
||||
|
||||
if (Message->HookMessage == MSQ_ISHOOK)
|
||||
{ // Direct Hook Call processor
|
||||
Result = co_CallHook( Message->Msg.message, // HookId
|
||||
|
@ -419,6 +484,11 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
|
|||
/* still keep the sender's message queue locked, so the sender can't exit the
|
||||
MsqSendMessage() function (if timed out) */
|
||||
|
||||
if (Message->QS_Flags & QS_SMRESULT)
|
||||
{
|
||||
Result = Message->lResult;
|
||||
}
|
||||
|
||||
/* Let the sender know the result. */
|
||||
if (Message->Result != NULL)
|
||||
{
|
||||
|
@ -456,6 +526,9 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
|
|||
|
||||
/* free the message */
|
||||
ExFreePoolWithTag(Message, TAG_USRMSG);
|
||||
|
||||
pti->pcti->CTI_flags &= ~CTI_INSENDMESSAGE;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
@ -483,6 +556,7 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
|
|||
if (PostedMessage->Msg.hwnd == Window->head.h)
|
||||
{
|
||||
RemoveEntryList(&PostedMessage->ListEntry);
|
||||
ClearMsgBitsMask(MessageQueue, PostedMessage->QS_Flags);
|
||||
MsqDestroyMessage(PostedMessage);
|
||||
CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
|
||||
}
|
||||
|
@ -504,6 +578,7 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
|
|||
DPRINT("Notify the sender and remove a message from the queue that had not been dispatched\n");
|
||||
|
||||
RemoveEntryList(&SentMessage->ListEntry);
|
||||
ClearMsgBitsMask(MessageQueue, SentMessage->QS_Flags);
|
||||
|
||||
/* remove the message from the dispatching list if neede */
|
||||
if ((!(SentMessage->HookMessage & MSQ_SENTNOWAIT))
|
||||
|
@ -581,6 +656,8 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
|||
Message->Msg.lParam = lParam;
|
||||
Message->CompletionEvent = &CompletionEvent;
|
||||
Message->Result = &Result;
|
||||
Message->lResult = 0;
|
||||
Message->QS_Flags = 0;
|
||||
Message->SenderQueue = ThreadQueue;
|
||||
IntReferenceMessageQueue(ThreadQueue);
|
||||
Message->CompletionCallback = NULL;
|
||||
|
@ -596,7 +673,8 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
|||
/* queue it in the destination's message queue */
|
||||
InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry);
|
||||
|
||||
MsqWakeQueue(MessageQueue, QS_SENDMESSAGE);
|
||||
Message->QS_Flags = QS_SENDMESSAGE;
|
||||
MsqWakeQueue(MessageQueue, QS_SENDMESSAGE, TRUE);
|
||||
|
||||
/* we can't access the Message anymore since it could have already been deleted! */
|
||||
|
||||
|
@ -746,7 +824,9 @@ MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN HardwareMessa
|
|||
InsertTailList(&MessageQueue->HardwareMessagesListHead,
|
||||
&Message->ListEntry);
|
||||
}
|
||||
MsqWakeQueue(MessageQueue, MessageBits);
|
||||
|
||||
Message->QS_Flags = MessageBits;
|
||||
MsqWakeQueue(MessageQueue, MessageBits, (MessageBits & QS_TIMER ? FALSE : TRUE));
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
|
@ -754,7 +834,7 @@ MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode)
|
|||
{
|
||||
MessageQueue->QuitPosted = TRUE;
|
||||
MessageQueue->QuitExitCode = ExitCode;
|
||||
MsqWakeQueue(MessageQueue, QS_POSTMESSAGE);
|
||||
MsqWakeQueue(MessageQueue, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE, TRUE);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1122,17 +1202,38 @@ co_MsqPeekMouseMove(IN PUSER_MESSAGE_QUEUE MessageQueue,
|
|||
*pMsg = msg;
|
||||
|
||||
if(Remove)
|
||||
{
|
||||
ClearMsgBitsMask(MessageQueue, QS_MOUSEMOVE);
|
||||
MessageQueue->MouseMoved = FALSE;
|
||||
}
|
||||
|
||||
return AcceptMessage;
|
||||
}
|
||||
|
||||
/* check whether a message filter contains at least one potential hardware message */
|
||||
static INT FASTCALL
|
||||
filter_contains_hw_range( UINT first, UINT last )
|
||||
{
|
||||
/* hardware message ranges are (in numerical order):
|
||||
* WM_NCMOUSEFIRST .. WM_NCMOUSELAST
|
||||
* WM_KEYFIRST .. WM_KEYLAST
|
||||
* WM_MOUSEFIRST .. WM_MOUSELAST
|
||||
*/
|
||||
if (!last) --last;
|
||||
if (last < WM_NCMOUSEFIRST) return 0;
|
||||
if (first > WM_NCMOUSELAST && last < WM_KEYFIRST) return 0;
|
||||
if (first > WM_KEYLAST && last < WM_MOUSEFIRST) return 0;
|
||||
if (first > WM_MOUSELAST) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL APIENTRY
|
||||
co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
|
||||
IN BOOL Remove,
|
||||
IN PWND Window,
|
||||
IN UINT MsgFilterLow,
|
||||
IN UINT MsgFilterHigh,
|
||||
IN UINT QSflags,
|
||||
OUT MSG* pMsg)
|
||||
{
|
||||
|
||||
|
@ -1141,33 +1242,45 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
|
|||
PLIST_ENTRY ListHead, CurrentEntry = NULL;
|
||||
MSG msg;
|
||||
|
||||
if (!filter_contains_hw_range( MsgFilterLow, MsgFilterHigh )) return FALSE;
|
||||
|
||||
ListHead = &MessageQueue->HardwareMessagesListHead;
|
||||
CurrentEntry = ListHead->Flink;
|
||||
|
||||
while(CurrentEntry != ListHead)
|
||||
{
|
||||
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
|
||||
if (IsListEmpty(CurrentEntry)) return FALSE;
|
||||
|
||||
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
|
||||
ListEntry);
|
||||
|
||||
msg = CurrentMessage->Msg;
|
||||
|
||||
AcceptMessage = co_IntProcessHardwareMessage(&msg, &Remove, MsgFilterLow, MsgFilterHigh);
|
||||
|
||||
do
|
||||
{
|
||||
if (IsListEmpty(CurrentEntry)) break;
|
||||
if (!CurrentMessage) break;
|
||||
CurrentEntry = CurrentMessage->ListEntry.Flink;
|
||||
|
||||
if (Remove)
|
||||
if ( (( MsgFilterLow == 0 && MsgFilterHigh == 0 ) && (CurrentMessage->QS_Flags & QSflags)) ||
|
||||
( MsgFilterLow <= CurrentMessage->Msg.message && MsgFilterHigh >= CurrentMessage->Msg.message ) )
|
||||
{
|
||||
RemoveEntryList(&CurrentMessage->ListEntry);
|
||||
MsqDestroyMessage(CurrentMessage);
|
||||
}
|
||||
msg = CurrentMessage->Msg;
|
||||
|
||||
if(AcceptMessage)
|
||||
{
|
||||
*pMsg = msg;
|
||||
return TRUE;
|
||||
}
|
||||
AcceptMessage = co_IntProcessHardwareMessage(&msg, &Remove, MsgFilterLow, MsgFilterHigh);
|
||||
|
||||
if (Remove)
|
||||
{
|
||||
RemoveEntryList(&CurrentMessage->ListEntry);
|
||||
ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags);
|
||||
MsqDestroyMessage(CurrentMessage);
|
||||
}
|
||||
|
||||
if (AcceptMessage)
|
||||
{
|
||||
*pMsg = msg;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
|
||||
ListEntry);
|
||||
}
|
||||
while(CurrentEntry != ListHead);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1178,6 +1291,7 @@ MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
|
|||
IN PWND Window,
|
||||
IN UINT MsgFilterLow,
|
||||
IN UINT MsgFilterHigh,
|
||||
IN UINT QSflags,
|
||||
OUT PMSG Message)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
|
@ -1186,29 +1300,35 @@ MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
|
|||
|
||||
CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
|
||||
ListHead = &MessageQueue->PostedMessagesListHead;
|
||||
while (CurrentEntry != ListHead)
|
||||
{
|
||||
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
|
||||
|
||||
if (IsListEmpty(CurrentEntry)) return FALSE;
|
||||
|
||||
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
|
||||
ListEntry);
|
||||
if ( ( !Window ||
|
||||
PtrToInt(Window) == 1 ||
|
||||
Window->head.h == CurrentMessage->Msg.hwnd ) &&
|
||||
( (MsgFilterLow == 0 && MsgFilterHigh == 0) ||
|
||||
( MsgFilterLow <= CurrentMessage->Msg.message &&
|
||||
MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
|
||||
do
|
||||
{
|
||||
if (IsListEmpty(CurrentEntry)) break;
|
||||
if (!CurrentMessage) break;
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
|
||||
if ( ( !Window || Window == HWND_BOTTOM || Window->head.h == CurrentMessage->Msg.hwnd ) &&
|
||||
( ( ( MsgFilterLow == 0 && MsgFilterHigh == 0 ) && CurrentMessage->QS_Flags & QSflags ) ||
|
||||
( MsgFilterLow <= CurrentMessage->Msg.message && MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
|
||||
{
|
||||
*Message= CurrentMessage->Msg;
|
||||
*Message = CurrentMessage->Msg;
|
||||
|
||||
if (Remove)
|
||||
{
|
||||
RemoveEntryList(&CurrentMessage->ListEntry);
|
||||
ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags);
|
||||
MsqDestroyMessage(CurrentMessage);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
|
||||
ListEntry);
|
||||
}
|
||||
while (CurrentEntry != ListHead);
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
@ -1257,9 +1377,6 @@ MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQu
|
|||
KeQueryTickCount(&LargeTickCount);
|
||||
MessageQueue->LastMsgRead = LargeTickCount.u.LowPart;
|
||||
MessageQueue->FocusWindow = NULL;
|
||||
MessageQueue->PaintCount = 0;
|
||||
// HACK!!!!!!! Newbies that wrote this should hold your head down in shame! (jt)
|
||||
MessageQueue->WakeMask = ~0;
|
||||
MessageQueue->NewMessagesHandle = NULL;
|
||||
|
||||
Status = ZwCreateEvent(&MessageQueue->NewMessagesHandle, EVENT_ALL_ACCESS,
|
||||
|
@ -1288,6 +1405,10 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
|
|||
PLIST_ENTRY CurrentEntry;
|
||||
PUSER_MESSAGE CurrentMessage;
|
||||
PUSER_SENT_MESSAGE CurrentSentMessage;
|
||||
PTHREADINFO pti;
|
||||
|
||||
pti = MessageQueue->Thread->Tcb.Win32Thread;
|
||||
|
||||
|
||||
/* cleanup posted messages */
|
||||
while (!IsListEmpty(&MessageQueue->PostedMessagesListHead))
|
||||
|
@ -1391,6 +1512,16 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
|
|||
locked later */
|
||||
}
|
||||
|
||||
// Clear it all out.
|
||||
pti->pcti->fsWakeBits = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
PUSER_MESSAGE_QUEUE FASTCALL
|
||||
|
@ -1475,6 +1606,38 @@ MsqGetMessageExtraInfo(VOID)
|
|||
return MessageQueue->ExtraInfo;
|
||||
}
|
||||
|
||||
BOOL FASTCALL
|
||||
co_MsqReplyMessage( LRESULT lResult )
|
||||
{
|
||||
PUSER_SENT_MESSAGE Message;
|
||||
PLIST_ENTRY Entry;
|
||||
PTHREADINFO pti;
|
||||
PUSER_MESSAGE_QUEUE MessageQueue;
|
||||
|
||||
pti = PsGetCurrentThreadWin32Thread();
|
||||
MessageQueue = pti->MessageQueue;
|
||||
|
||||
if(!MessageQueue) return FALSE;
|
||||
|
||||
if (IsListEmpty(&MessageQueue->SentMessagesListHead))
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
// Do we loop through all msgs or just set the first one?
|
||||
Entry = MessageQueue->SentMessagesListHead.Flink;
|
||||
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
|
||||
|
||||
if (Message->QS_Flags & QS_SMRESULT) return FALSE;
|
||||
|
||||
if (Message->SenderQueue || Message->CompletionCallback)
|
||||
{
|
||||
Message->lResult = lResult;
|
||||
Message->QS_Flags |= QS_SMRESULT;
|
||||
MsqWakeQueue(MessageQueue, 0, TRUE); // Wake it up!? Bits?
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HWND FASTCALL
|
||||
MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd)
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* PURPOSE: Window painting function
|
||||
* FILE: subsys/win32k/ntuser/painting.c
|
||||
* FILE: subsystems/win32/win32k/ntuser/painting.c
|
||||
* PROGRAMER: Filip Navara (xnavara@volny.cz)
|
||||
* REVISION HISTORY:
|
||||
* 06/06/2001 Created (?)
|
||||
|
@ -660,9 +660,7 @@ IntGetPaintMessage(
|
|||
MSG *Message,
|
||||
BOOL Remove)
|
||||
{
|
||||
PUSER_MESSAGE_QUEUE MessageQueue = (PUSER_MESSAGE_QUEUE)Thread->MessageQueue;
|
||||
|
||||
if (!MessageQueue->PaintCount)
|
||||
if (!Thread->cPaintsReady)
|
||||
return FALSE;
|
||||
|
||||
if ((MsgFilterMin != 0 || MsgFilterMax != 0) &&
|
||||
|
@ -673,9 +671,9 @@ IntGetPaintMessage(
|
|||
|
||||
if (Message->hwnd == NULL)
|
||||
{
|
||||
DPRINT1("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found!\n");
|
||||
DPRINT1("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found! Counts %d\n",Thread->cPaintsReady);
|
||||
/* Hack to stop spamming the debuglog ! */
|
||||
MessageQueue->PaintCount = 0;
|
||||
Thread->cPaintsReady = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -333,6 +333,8 @@ NtUserCallOneParam(
|
|||
_SEH2_END;
|
||||
RETURN(Ret);
|
||||
}
|
||||
case ONEPARAM_ROUTINE_REPLYMESSAGE:
|
||||
RETURN (co_MsqReplyMessage((LRESULT) Param));
|
||||
}
|
||||
DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
|
||||
Routine, Param);
|
||||
|
|
|
@ -361,7 +361,7 @@ PostTimerMessages(PWND Window)
|
|||
|
||||
MsqPostMessage(ThreadQueue, &Msg, FALSE, QS_TIMER);
|
||||
pTmr->flags &= ~TMRF_READY;
|
||||
ThreadQueue->WakeMask = ~QS_TIMER;
|
||||
pti->cTimersReady++;
|
||||
Hit = TRUE;
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue