Author: jimtabor
Date: Fri Dec 3 15:34:06 2010
New Revision: 49929
URL:
http://svn.reactos.org/svn/reactos?rev=49929&view=rev
Log:
[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.
Modified:
trunk/reactos/dll/win32/user32/windows/menu.c
trunk/reactos/dll/win32/user32/windows/message.c
trunk/reactos/include/reactos/win32k/ntuser.h
trunk/reactos/subsystems/win32/win32k/include/msgqueue.h
trunk/reactos/subsystems/win32/win32k/include/win32.h
trunk/reactos/subsystems/win32/win32k/main/dllmain.c
trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c
trunk/reactos/subsystems/win32/win32k/ntuser/input.c
trunk/reactos/subsystems/win32/win32k/ntuser/message.c
trunk/reactos/subsystems/win32/win32k/ntuser/misc.c
trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c
trunk/reactos/subsystems/win32/win32k/ntuser/painting.c
trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c
trunk/reactos/subsystems/win32/win32k/ntuser/timer.c
Modified: trunk/reactos/dll/win32/user32/windows/menu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/m…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/menu.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/windows/menu.c [iso-8859-1] Fri Dec 3 15:34:06 2010
@@ -3182,7 +3182,7 @@
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 @@
}
WaitMessage();
}
+ //FIXME("MenuTrackMenu loop 1\n");
}
/* check if EndMenu() tried to cancel us, by posting this message */
@@ -3417,6 +3418,7 @@
{
PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
DispatchMessageW( &msg );
+ //FIXME("MenuTrackMenu loop 2\n");
continue;
}
@@ -3427,8 +3429,9 @@
if (fRemove && !(mt.TrackFlags & TF_SKIPREMOVE) )
PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
else mt.TrackFlags &= ~TF_SKIPREMOVE;
- }
- ERR("MenuTrackMenu 2\n");
+ //FIXME("MenuTrackMenu loop 3\n");
+ }
+ FIXME("MenuTrackMenu 2\n");
(void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, NULL);
SetCapture(NULL); /* release the capture */
Modified: trunk/reactos/dll/win32/user32/windows/message.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/m…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/message.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/windows/message.c [iso-8859-1] Fri Dec 3 15:34:06
2010
@@ -1097,7 +1097,6 @@
InSendMessage(VOID)
{
PCLIENTTHREADINFO pcti = GetWin32ClientInfo()->pClientThreadInfo;
-// FIXME("ISM %x\n",pcti);
if ( pcti )
{
if (pcti->CTI_flags & CTI_INSENDMESSAGE)
@@ -1118,7 +1117,6 @@
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 @@
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 @@
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 @@
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 @@
{
}
_SEH2_END;
-
}
else if (Wnd != NULL)
{
@@ -1654,11 +1662,16 @@
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 @@
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 @@
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 @@
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 @@
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 @@
LPHANDLE RealHandles;
HANDLE MessageQueueHandle;
DWORD Result;
+ PCLIENTINFO pci;
+ PCLIENTTHREADINFO pcti;
if (dwFlags & ~(MWMO_WAITALL | MWMO_ALERTABLE | MWMO_INPUTAVAILABLE))
{
@@ -2809,14 +2861,21 @@
return WAIT_FAILED;
}
-/*
- if (dwFlags & MWMO_INPUTAVAILABLE)
+ pci = GetWin32ClientInfo();
+ if (!pci) return WAIT_FAILED;
+
+ pcti = pci->pClientThreadInfo;
+ if (pcti && ( !nCount || !(dwFlags & MWMO_WAITALL) ))
{
- RealGetQueueStatus(dwWakeMask);
+ 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(dwWakeMask);
+
+ MessageQueueHandle = NtUserMsqSetWakeMask(MAKELONG(dwWakeMask, dwFlags));
if (MessageQueueHandle == NULL)
{
SetLastError(0); /* ? */
@@ -2840,7 +2899,7 @@
HeapFree(GetProcessHeap(), 0, RealHandles);
NtUserMsqClearWakeMask();
-
+ //FIXME("Result 0X%x\n",Result);
return Result;
}
Modified: trunk/reactos/include/reactos/win32k/ntuser.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntu…
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntuser.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/win32k/ntuser.h [iso-8859-1] Fri Dec 3 15:34:06 2010
@@ -2104,7 +2104,8 @@
THREADSTATE_PROGMANWINDOW,
THREADSTATE_TASKMANWINDOW,
THREADSTATE_GETMESSAGETIME,
- THREADSTATE_GETINPUTSTATE
+ THREADSTATE_GETINPUTSTATE,
+ THREADSTATE_UPTIMELASTREAD
};
DWORD_PTR
Modified: trunk/reactos/subsystems/win32/win32k/include/msgqueue.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/msgqueue.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/msgqueue.h [iso-8859-1] Fri Dec 3
15:34:06 2010
@@ -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 @@
{
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
__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 @@
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 */
Modified: trunk/reactos/subsystems/win32/win32k/include/win32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/win32.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/win32.h [iso-8859-1] Fri Dec 3 15:34:06
2010
@@ -161,6 +161,7 @@
struct _DESKTOP* rpdeskStartup;
PCLS pclsPrivateList;
PCLS pclsPublicList;
+ INT cThreads;
DWORD dwhmodLibLoadedMask;
HANDLE ahmodLibLoaded[CLIBS];
struct _WINSTATION_OBJECT *prpwinsta;
Modified: trunk/reactos/subsystems/win32/win32k/main/dllmain.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ma…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] Fri Dec 3 15:34:06
2010
@@ -268,6 +268,9 @@
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 @@
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 @@
e = PopEntryList(&Win32Thread->ReferencesList);
}
- IntSetThreadDesktop(NULL,
- TRUE);
-
+ IntSetThreadDesktop(NULL, TRUE);
PsSetThreadWin32Thread(Thread, NULL);
}
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c [iso-8859-1] Fri Dec 3
15:34:06 2010
@@ -1926,7 +1926,7 @@
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 @@
W32Thread->pcti = NULL;
}
- if (!W32Thread->pcti && DesktopObject)
+ if (!W32Thread->pcti && DesktopObject && NtCurrentTeb())
{
DPRINT("Allocate ClientThreadInfo\n");
W32Thread->pcti = DesktopHeapAlloc( DesktopObject,
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/input.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] Fri Dec 3 15:34:06
2010
@@ -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(a)users.sourceforge.net)
* REVISION HISTORY:
* 06-06-2001 CSH Created
@@ -205,13 +205,6 @@
IO_STATUS_BLOCK Iosb;
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 @@
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
{
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/message.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/message.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/message.c [iso-8859-1] Fri Dec 3
15:34:06 2010
@@ -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(a)users.sourceforge.net)
* REVISION HISTORY:
* 06-06-2001 CSH Created
@@ -342,12 +342,17 @@
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);
+ }
}
}
@@ -369,6 +374,25 @@
{
KeClearEvent(ppi->InputIdleEvent);
}
+}
+
+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
@@ -423,6 +447,12 @@
}
pti = PsGetCurrentThreadWin32Thread();
+
+ if ( Window->head.pti != pti)
+ {
+ SetLastWin32Error( ERROR_MESSAGE_SYNC_ONLY );
+ return 0;
+ }
if (((pMsg->message == WM_SYSTIMER) ||
(pMsg->message == WM_TIMER)) &&
@@ -503,24 +533,34 @@
}
/*
-* 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 @@
{
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 @@
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 ))
+ /* Check for hardware events. */
+ if ((ProcessMask & QS_MOUSE) &&
+ co_MsqPeekMouseMove( ThreadQueue,
+ RemoveMessages,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ Msg ))
{
return TRUE;
}
- /* Check for hardware events. */
- if(co_MsqPeekMouseMove(ThreadQueue,
- RemoveMessages,
- Window,
- MsgFilterMin,
- MsgFilterMax,
- Msg ))
+ if ((ProcessMask & QS_INPUT) &&
+ co_MsqPeekHardwareMessage( ThreadQueue,
+ RemoveMessages,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ ProcessMask,
+ Msg))
{
return TRUE;
}
- if(co_MsqPeekHardwareMessage(ThreadQueue,
- RemoveMessages,
- Window,
- MsgFilterMin,
- MsgFilterMax,
- 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 @@
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 @@
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 @@
BOOL bGMSG )
{
PWND Window;
+ PTHREADINFO pti;
BOOL Present = FALSE;
if ( hWnd == HWND_TOPMOST || hWnd == HWND_BROADCAST )
@@ -781,13 +859,19 @@
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_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 @@
}
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 @@
MsqPostQuitMessage(Window->head.pti->MessageQueue, wParam);
}
else
- {
+ {
Message.hwnd = Wnd;
Message.message = Msg;
Message.wParam = wParam;
@@ -1283,7 +1381,9 @@
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 @@
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 @@
WPARAM wParam,
LPARAM lParam )
{
- BOOL Result = TRUE;
+ BOOL Ret = TRUE;
if (FindMsgMemory(Msg) != 0)
{
@@ -1491,37 +1594,28 @@
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 );
- }
- }
- return Result;
+ ULONG_PTR lResult = 0;
+ Ret = co_IntSendMessageWithCallBack( hWnd,
+ Msg,
+ wParam,
+ lParam,
+ NULL,
+ 0,
+ &lResult);
+ }
+ return Ret;
}
@@ -1537,15 +1631,13 @@
// wine:
Changes &= (QS_ALLINPUT|QS_ALLPOSTMESSAGE|QS_SMRESULT);
- Result = MAKELONG(Queue->ChangedBits & Changes, Queue->QueueBits &
Changes);
-
- if (pti->pcti)
- {
- pti->pcti->fsChangeBits = Queue->ChangedBits;
- pti->pcti->fsChangeBits &= ~Changes;
- }
-
- Queue->ChangedBits &= ~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);
+
+ pti->pcti->fsChangeBits &= ~Changes;
return Result;
}
@@ -1684,9 +1776,9 @@
BOOL ret;
UserEnterExclusive();
-
+ DPRINT("NtUserWaitMessage Enter\n");
ret = co_IntWaitMessage(NULL, 0, 0);
-
+ DPRINT("NtUserWaitMessage Leave\n");
UserLeave();
return ret;
@@ -2338,6 +2430,13 @@
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 @@
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 @@
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;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/misc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/misc.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/misc.c [iso-8859-1] Fri Dec 3 15:34:06
2010
@@ -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(a)gse.nl)
* REVISION HISTORY:
* 2003/05/22 Created
@@ -102,6 +102,8 @@
break;
case THREADSTATE_INSENDMESSAGE:
{
+ PUSER_SENT_MESSAGE Message;
+ PLIST_ENTRY Entry;
PUSER_MESSAGE_QUEUE MessageQueue =
((PTHREADINFO)PsGetCurrentThreadWin32Thread())->MessageQueue;
DPRINT1("THREADSTATE_INSENDMESSAGE\n");
@@ -109,19 +111,37 @@
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:
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] Fri Dec 3
15:34:06 2010
@@ -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 @@
/* 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 @@
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 @@
PUSER_SENT_MESSAGE Message;
PLIST_ENTRY Entry;
LRESULT Result;
+ PTHREADINFO pti;
if (IsListEmpty(&MessageQueue->SentMessagesListHead))
{
@@ -375,11 +431,20 @@
/* remove it from the list of pending messages */
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
@@ -419,6 +484,11 @@
/* 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 @@
/* free the message */
ExFreePoolWithTag(Message, TAG_USRMSG);
+
+ pti->pcti->CTI_flags &= ~CTI_INSENDMESSAGE;
+
return(TRUE);
}
@@ -483,6 +556,7 @@
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 @@
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 @@
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 @@
/* 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 @@
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 @@
{
MessageQueue->QuitPosted = TRUE;
MessageQueue->QuitExitCode = ExitCode;
- MsqWakeQueue(MessageQueue, QS_POSTMESSAGE);
+ MsqWakeQueue(MessageQueue, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE, TRUE);
}
/***********************************************************************
@@ -1122,9 +1202,29 @@
*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
@@ -1133,6 +1233,7 @@
IN PWND Window,
IN UINT MsgFilterLow,
IN UINT MsgFilterHigh,
+ IN UINT QSflags,
OUT MSG* pMsg)
{
@@ -1141,33 +1242,45 @@
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)
+ if (IsListEmpty(CurrentEntry)) return FALSE;
+
+ CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
+ ListEntry);
+ do
{
+ if (IsListEmpty(CurrentEntry)) break;
+ if (!CurrentMessage) break;
+ CurrentEntry = CurrentMessage->ListEntry.Flink;
+
+ if ( (( MsgFilterLow == 0 && MsgFilterHigh == 0 ) &&
(CurrentMessage->QS_Flags & QSflags)) ||
+ ( MsgFilterLow <= CurrentMessage->Msg.message && MsgFilterHigh
>= CurrentMessage->Msg.message ) )
+ {
+ msg = CurrentMessage->Msg;
+
+ 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);
-
- msg = CurrentMessage->Msg;
-
- AcceptMessage = co_IntProcessHardwareMessage(&msg, &Remove, MsgFilterLow,
MsgFilterHigh);
-
- CurrentEntry = CurrentMessage->ListEntry.Flink;
-
- if (Remove)
- {
- RemoveEntryList(&CurrentMessage->ListEntry);
- MsqDestroyMessage(CurrentMessage);
- }
-
- if(AcceptMessage)
- {
- *pMsg = msg;
- return TRUE;
- }
-
}
+ while(CurrentEntry != ListHead);
return FALSE;
}
@@ -1178,6 +1291,7 @@
IN PWND Window,
IN UINT MsgFilterLow,
IN UINT MsgFilterHigh,
+ IN UINT QSflags,
OUT PMSG Message)
{
PLIST_ENTRY CurrentEntry;
@@ -1186,29 +1300,35 @@
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 ) ) )
- {
- *Message= CurrentMessage->Msg;
+ 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;
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 @@
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 @@
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 @@
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
@@ -1473,6 +1604,38 @@
}
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
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/painting.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/painting.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/painting.c [iso-8859-1] Fri Dec 3
15:34:06 2010
@@ -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(a)volny.cz)
* REVISION HISTORY:
* 06/06/2001 Created (?)
@@ -660,9 +660,7 @@
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 @@
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;
}
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c [iso-8859-1] Fri Dec 3
15:34:06 2010
@@ -333,6 +333,8 @@
_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);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/timer.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/timer.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/timer.c [iso-8859-1] Fri Dec 3 15:34:06
2010
@@ -361,7 +361,7 @@
MsqPostMessage(ThreadQueue, &Msg, FALSE, QS_TIMER);
pTmr->flags &= ~TMRF_READY;
- ThreadQueue->WakeMask = ~QS_TIMER;
+ pti->cTimersReady++;
Hit = TRUE;
break;
}