From adc5944468a2f034cfba4ec348a55390b18f78d7 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Sat, 25 Dec 2004 22:59:10 +0000 Subject: [PATCH] - Partial implementation of RealMsgWaitForMultipleObjectsEx and message queue wake mask. - Fix setting of menu item type and strings. svn path=/trunk/; revision=12336 --- reactos/include/win32k/ntuser.h | 20 ++-- reactos/lib/user32/include/user32.h | 6 ++ reactos/lib/user32/misc/stubs.c | 19 +--- reactos/lib/user32/windows/message.c | 78 +++++++++++++- reactos/subsys/win32k/include/msgqueue.h | 25 +++-- reactos/subsys/win32k/ntuser/caret.c | 4 +- reactos/subsys/win32k/ntuser/keyboard.c | 8 +- reactos/subsys/win32k/ntuser/menu.c | 27 +++-- reactos/subsys/win32k/ntuser/message.c | 14 ++- reactos/subsys/win32k/ntuser/misc.c | 8 +- reactos/subsys/win32k/ntuser/msgqueue.c | 129 ++++++++++++++++++----- reactos/subsys/win32k/ntuser/timer.c | 5 +- 12 files changed, 253 insertions(+), 90 deletions(-) diff --git a/reactos/include/win32k/ntuser.h b/reactos/include/win32k/ntuser.h index 23b7f5326cd..13983b00a4f 100644 --- a/reactos/include/win32k/ntuser.h +++ b/reactos/include/win32k/ntuser.h @@ -156,14 +156,15 @@ NtUserCallNextHookEx( WPARAM wParam, LPARAM lParam); -#define NOPARAM_ROUTINE_REGISTER_PRIMITIVE 0xffff0001 /* Private ROS */ -#define NOPARAM_ROUTINE_DESTROY_CARET 0xffff0002 -#define NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP 0xffff0003 -#define NOPARAM_ROUTINE_INIT_MESSAGE_PUMP 0xffff0004 -#define NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO 0xffff0005 -#define NOPARAM_ROUTINE_ANYPOPUP 0xffff0006 -#define NOPARAM_ROUTINE_CSRSS_INITIALIZED 0xffff0007 -#define NOPARAM_ROUTINE_GDI_QUERY_TABLE 0xffff0008 +#define NOPARAM_ROUTINE_MSQCLEARWAKEMASK 0x3 +#define NOPARAM_ROUTINE_REGISTER_PRIMITIVE 0xffff0001 /* Private ROS */ +#define NOPARAM_ROUTINE_DESTROY_CARET 0xffff0002 +#define NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP 0xffff0003 +#define NOPARAM_ROUTINE_INIT_MESSAGE_PUMP 0xffff0004 +#define NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO 0xffff0005 +#define NOPARAM_ROUTINE_ANYPOPUP 0xffff0006 +#define NOPARAM_ROUTINE_CSRSS_INITIALIZED 0xffff0007 +#define NOPARAM_ROUTINE_GDI_QUERY_TABLE 0xffff0008 DWORD STDCALL NtUserCallNoParam( @@ -178,11 +179,12 @@ NtUserCallNoParam( #define ONEPARAM_ROUTINE_GETCARETINFO 0x07 #define ONEPARAM_ROUTINE_SWITCHCARETSHOWING 0x08 #define ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS 0x09 -#define ONEPARAM_ROUTINE_GETWINDOWINSTANCE 0x10 #define ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO 0x0a #define ONEPARAM_ROUTINE_GETCURSORPOSITION 0x0b #define ONEPARAM_ROUTINE_ISWINDOWINDESTROY 0x0c #define ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING 0x0d +#define ONEPARAM_ROUTINE_GETWINDOWINSTANCE 0x10 +#define ONEPARAM_ROUTINE_MSQSETWAKEMASK 0x27 DWORD STDCALL NtUserCallOneParam( diff --git a/reactos/lib/user32/include/user32.h b/reactos/lib/user32/include/user32.h index a9aba8750a0..178cfdfa02a 100644 --- a/reactos/lib/user32/include/user32.h +++ b/reactos/lib/user32/include/user32.h @@ -35,6 +35,12 @@ VOID CreateFrameBrushes(VOID); VOID DeleteFrameBrushes(VOID); void DrawCaret(HWND hWnd, PTHRDCARETINFO CaretInfo); +#define NtUserMsqSetWakeMask(dwWaitMask) \ + (HANDLE)NtUserCallOneParam(dwWaitMask, ONEPARAM_ROUTINE_MSQSETWAKEMASK) + +#define NtUserMsqClearWakeMask() \ + NtUserCallNoParam(NOPARAM_ROUTINE_MSQCLEARWAKEMASK) + LONG WINAPI RegCloseKey(HKEY); LONG WINAPI RegOpenKeyExW(HKEY,LPCWSTR,DWORD,REGSAM,PHKEY); LONG WINAPI RegQueryValueExW(HKEY,LPCWSTR,LPDWORD,LPDWORD,LPBYTE,LPDWORD); diff --git a/reactos/lib/user32/misc/stubs.c b/reactos/lib/user32/misc/stubs.c index b2938ee3d5e..1c27055178b 100644 --- a/reactos/lib/user32/misc/stubs.c +++ b/reactos/lib/user32/misc/stubs.c @@ -1,4 +1,4 @@ -/* $Id: stubs.c,v 1.70 2004/12/16 03:57:35 rcampbell Exp $ +/* $Id: stubs.c,v 1.71 2004/12/25 22:59:10 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -126,23 +126,6 @@ MsgWaitForMultipleObjects( } -/* - * @unimplemented - */ -DWORD -STDCALL -RealMsgWaitForMultipleObjectsEx( - DWORD nCount, - LPHANDLE pHandles, - DWORD dwMilliseconds, - DWORD dwWakeMask, - DWORD dwFlags) -{ - UNIMPLEMENTED; - return 0; -} - - /* * @unimplemented */ diff --git a/reactos/lib/user32/windows/message.c b/reactos/lib/user32/windows/message.c index 3b77990bb89..e45fd7c679e 100644 --- a/reactos/lib/user32/windows/message.c +++ b/reactos/lib/user32/windows/message.c @@ -1,4 +1,4 @@ -/* $Id: message.c,v 1.46 2004/12/25 20:30:49 navaraf Exp $ +/* $Id: message.c,v 1.47 2004/12/25 22:59:10 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -1919,6 +1919,8 @@ BOOL WINAPI IsInsideMessagePumpHook() if(!gfMessagePumpHook) return FALSE; + /* This code checks for WOW16. */ +#if 0 /* Since our TEB doesnt match that of real windows, testing this value is useless until we know what it does PUCHAR NtTeb = (PUCHAR)NtCurrentTeb(); @@ -1927,6 +1929,7 @@ BOOL WINAPI IsInsideMessagePumpHook() if(**(PLONG*)&NtTeb[0x708] <= 0) return FALSE;*/ +#endif return TRUE; } @@ -1999,6 +2002,79 @@ DWORD WINAPI GetQueueStatus(UINT flags) return IsInsideMessagePumpHook() ? gmph.RealGetQueueStatus(flags) : RealGetQueueStatus(flags); } +/** + * @name RealMsgWaitForMultipleObjectsEx + * + * Wait either for either message arrival or for one of the passed events + * to be signalled. + * + * @param nCount + * Number of handles in the pHandles array. + * @param pHandles + * Handles of events to wait for. + * @param dwMilliseconds + * Timeout interval. + * @param dwWakeMask + * Mask specifying on which message events we should wakeup. + * @param dwFlags + * Wait type (see MWMO_* constants). + * + * @implemented + */ + +DWORD STDCALL +RealMsgWaitForMultipleObjectsEx( + DWORD nCount, + const HANDLE *pHandles, + DWORD dwMilliseconds, + DWORD dwWakeMask, + DWORD dwFlags) +{ + LPHANDLE RealHandles; + HANDLE MessageQueueHandle; + DWORD Result; + + if (dwFlags & ~(MWMO_WAITALL | MWMO_ALERTABLE | MWMO_INPUTAVAILABLE)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return WAIT_FAILED; + } + +/* + if (dwFlags & MWMO_INPUTAVAILABLE) + { + RealGetQueueStatus(dwWakeMask); + } + */ + + MessageQueueHandle = NtUserMsqSetWakeMask(dwWakeMask); + if (MessageQueueHandle == NULL) + { + SetLastError(0); /* ? */ + return WAIT_FAILED; + } + + RealHandles = HeapAlloc(GetProcessHeap(), 0, (nCount + 1) * sizeof(HANDLE)); + if (RealHandles == NULL) + { + NtUserMsqClearWakeMask(); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return WAIT_FAILED; + } + + RtlCopyMemory(RealHandles, pHandles, nCount); + RealHandles[nCount] = MessageQueueHandle; + + Result = WaitForMultipleObjectsEx(nCount + 1, RealHandles, + dwFlags & MWMO_WAITALL, + dwMilliseconds, dwFlags & MWMO_ALERTABLE); + + HeapFree(GetProcessHeap(), 0, RealHandles); + NtUserMsqClearWakeMask(); + + return Result; +} + DWORD WINAPI MsgWaitForMultipleObjectsEx(DWORD nCount, CONST HANDLE *lpHandles, DWORD dwMilliseconds, DWORD dwWakeMask, DWORD dwFlags) { return IsInsideMessagePumpHook() ? gmph.RealMsgWaitForMultipleObjectsEx(nCount, lpHandles, dwMilliseconds, dwWakeMask, dwFlags) : RealMsgWaitForMultipleObjectsEx(nCount, lpHandles,dwMilliseconds, dwWakeMask, dwFlags); diff --git a/reactos/subsys/win32k/include/msgqueue.h b/reactos/subsys/win32k/include/msgqueue.h index b9aa1f59aec..e1bbfd345a2 100644 --- a/reactos/subsys/win32k/include/msgqueue.h +++ b/reactos/subsys/win32k/include/msgqueue.h @@ -65,8 +65,10 @@ typedef struct _USER_MESSAGE_QUEUE BOOLEAN QuitPosted; /* The quit exit code. */ ULONG QuitExitCode; - /* Set if there are new messages in any of the queues. */ - KEVENT NewMessages; + /* Set if there are new messages specified by WakeMask in any of the queues. */ + PKEVENT NewMessages; + /* Handle for the above event (in the context of the process owning the queue). */ + HANDLE NewMessagesHandle; /* Last time PeekMessage() was called. */ ULONG LastMsgRead; /* Current window with focus (ie. receives keyboard input) for this queue. */ @@ -92,10 +94,9 @@ typedef struct _USER_MESSAGE_QUEUE PHOOKTABLE Hooks; /* queue state tracking */ - WORD WakeBits; WORD WakeMask; + WORD QueueBits; WORD ChangedBits; - WORD ChangedMask; /* extra message information */ LPARAM ExtraInfo; @@ -121,7 +122,7 @@ VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE Message); VOID FASTCALL MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, - MSG* Msg, BOOLEAN FreeLParam); + MSG* Msg, BOOLEAN FreeLParam, DWORD MessageBits); VOID FASTCALL MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode); BOOLEAN STDCALL @@ -132,7 +133,7 @@ MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue, IN UINT MsgFilterLow, IN UINT MsgFilterHigh, OUT PUSER_MESSAGE* Message); -VOID FASTCALL +BOOLEAN FASTCALL MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQueue); VOID FASTCALL MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue); @@ -225,14 +226,12 @@ VOID STDCALL MsqRemoveWindowMessagesFromQueue(PVOID pWindow); /* F*(&$ headers, if(InterlockedDecrement(&(MsgQueue)->References) == 0) \ { \ DPRINT("Free message queue 0x%x\n", (MsgQueue)); \ + if ((MsgQueue)->NewMessagesHandle != NULL) \ + ZwClose((MsgQueue)->NewMessagesHandle); \ ExFreePool((MsgQueue)); \ } \ } while(0) -/* check the queue status */ -#define MsqIsSignaled(MsgQueue) \ - (((MsgQueue)->WakeBits & (MsgQueue)->WakeMask) || ((MsgQueue)->ChangedBits & (MsgQueue)->ChangedMask)) - #define IS_BTN_MESSAGE(message,code) \ ((message) == WM_LBUTTON##code || \ (message) == WM_MBUTTON##code || \ @@ -243,6 +242,12 @@ VOID STDCALL MsqRemoveWindowMessagesFromQueue(PVOID pWindow); /* F*(&$ headers, (message) == WM_NCRBUTTON##code || \ (message) == WM_NCXBUTTON##code ) +HANDLE FASTCALL +IntMsqSetWakeMask(DWORD WakeMask); + +BOOL FASTCALL +IntMsqClearWakeMask(VOID); + #endif /* _WIN32K_MSGQUEUE_H */ /* EOF */ diff --git a/reactos/subsys/win32k/ntuser/caret.c b/reactos/subsys/win32k/ntuser/caret.c index 2d9b51f854a..6f5b4037635 100644 --- a/reactos/subsys/win32k/ntuser/caret.c +++ b/reactos/subsys/win32k/ntuser/caret.c @@ -1,4 +1,4 @@ -/* $Id: caret.c,v 1.15 2004/11/20 16:46:06 weiden Exp $ +/* $Id: caret.c,v 1.16 2004/12/25 22:59:10 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -315,7 +315,7 @@ NtUserHideCaret( } ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue; - + if(ThreadQueue->CaretInfo->hWnd != hWnd) { IntReleaseWindowObject(WindowObject); diff --git a/reactos/subsys/win32k/ntuser/keyboard.c b/reactos/subsys/win32k/ntuser/keyboard.c index f01733ce150..98e3f07eb64 100644 --- a/reactos/subsys/win32k/ntuser/keyboard.c +++ b/reactos/subsys/win32k/ntuser/keyboard.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: keyboard.c,v 1.33 2004/11/15 16:36:28 ekohl Exp $ +/* $Id: keyboard.c,v 1.34 2004/12/25 22:59:10 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -660,14 +660,14 @@ IntTranslateKbdMessage(LPMSG lpMsg, NewMsg.wParam = dead_char; NewMsg.lParam = lpMsg->lParam; dead_char = 0; - MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE); + MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE, QS_KEY); } NewMsg.hwnd = lpMsg->hwnd; NewMsg.wParam = wp[0]; NewMsg.lParam = lpMsg->lParam; DPRINT( "CHAR='%c' %04x %08x\n", wp[0], wp[0], lpMsg->lParam ); - MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE); + MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE, QS_KEY); Result = TRUE; } else if (UState == -1) @@ -678,7 +678,7 @@ IntTranslateKbdMessage(LPMSG lpMsg, NewMsg.wParam = wp[0]; NewMsg.lParam = lpMsg->lParam; dead_char = wp[0]; - MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE); + MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE, QS_KEY); Result = TRUE; } diff --git a/reactos/subsys/win32k/ntuser/menu.c b/reactos/subsys/win32k/ntuser/menu.c index 44a52bd88b7..4615cbb0288 100644 --- a/reactos/subsys/win32k/ntuser/menu.c +++ b/reactos/subsys/win32k/ntuser/menu.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: menu.c,v 1.57 2004/12/13 15:38:19 navaraf Exp $ +/* $Id: menu.c,v 1.58 2004/12/25 22:59:10 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -717,6 +717,16 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINF } if(lpmii->fMask & (MIIM_FTYPE | MIIM_TYPE)) { + /* + * Delete the menu item type when changing type from + * MF_STRING. + */ + if (MenuItem->fType != lpmii->fType && + MENU_ITEM_TYPE(MenuItem->fType) == MF_STRING) + { + FreeMenuText(MenuItem); + RtlInitUnicodeString(&MenuItem->Text, NULL); + } MenuItem->fType = lpmii->fType; } if(lpmii->fMask & MIIM_ID) @@ -747,9 +757,11 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINF } } } - if((lpmii->fMask & (MIIM_TYPE | MIIM_STRING)) && - (MENU_ITEM_TYPE(lpmii->fType) == MF_STRING)) + if ((lpmii->fMask & (MIIM_TYPE | MIIM_STRING)) && + (MENU_ITEM_TYPE(lpmii->fType) == MF_STRING)) { + FreeMenuText(MenuItem); + if(lpmii->dwTypeData && lpmii->cch) { UNICODE_STRING Source; @@ -758,7 +770,6 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINF Source.MaximumLength = lpmii->cch * sizeof(WCHAR); Source.Buffer = lpmii->dwTypeData; - FreeMenuText(MenuItem); MenuItem->Text.Buffer = (PWSTR)ExAllocatePoolWithTag( PagedPool, Source.Length + sizeof(WCHAR), TAG_STRING); if(MenuItem->Text.Buffer != NULL) @@ -770,9 +781,7 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINF } else { - MenuItem->Text.Length = 0; - MenuItem->Text.MaximumLength = 0; - MenuItem->Text.Buffer = NULL; + RtlInitUnicodeString(&MenuItem->Text, NULL); } } else @@ -781,10 +790,6 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINF RtlInitUnicodeString(&MenuItem->Text, NULL); } } - else - { - RtlInitUnicodeString(&MenuItem->Text, NULL); - } if (sizeof(ROSMENUITEMINFO) == lpmii->cbSize) { diff --git a/reactos/subsys/win32k/ntuser/message.c b/reactos/subsys/win32k/ntuser/message.c index 49ae78eb52d..851b9c35d6f 100644 --- a/reactos/subsys/win32k/ntuser/message.c +++ b/reactos/subsys/win32k/ntuser/message.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: message.c,v 1.77 2004/12/25 20:30:50 navaraf Exp $ +/* $Id: message.c,v 1.78 2004/12/25 22:59:10 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -525,7 +525,9 @@ IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *Hit Msg->hwnd = Wnd->Self; if(!(Wnd->Status & WINDOWSTATUS_DESTROYING)) { - MsqPostMessage(Wnd->MessageQueue, Msg, FALSE); + MsqPostMessage(Wnd->MessageQueue, Msg, FALSE, + Msg->message == WM_MOUSEMOVE ? QS_MOUSEMOVE : + QS_MOUSEBUTTON); } /* eat the message */ @@ -1146,7 +1148,8 @@ NtUserPostMessage(HWND Wnd, KeQueryTickCount(&LargeTickCount); KernelModeMsg.time = LargeTickCount.u.LowPart; MsqPostMessage(Window->MessageQueue, &KernelModeMsg, - NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam); + NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam, + QS_POSTMESSAGE); IntReleaseWindowObject(Window); } @@ -1188,7 +1191,8 @@ NtUserPostThreadMessage(DWORD idThread, return FALSE; } MsqPostMessage(pThread->MessageQueue, &KernelModeMsg, - NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam); + NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam, + QS_POSTMESSAGE); ObDereferenceObject( peThread ); return TRUE; } else { @@ -1614,7 +1618,7 @@ NtUserGetQueueStatus(BOOL ClearChanges) IntLockMessageQueue(Queue); - Result = MAKELONG(Queue->ChangedBits, Queue->WakeBits); + Result = MAKELONG(Queue->QueueBits, Queue->ChangedBits); if (ClearChanges) { Queue->ChangedBits = 0; diff --git a/reactos/subsys/win32k/ntuser/misc.c b/reactos/subsys/win32k/ntuser/misc.c index c5d32b9bb20..63b109b5488 100644 --- a/reactos/subsys/win32k/ntuser/misc.c +++ b/reactos/subsys/win32k/ntuser/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.94 2004/12/24 17:45:58 weiden Exp $ +/* $Id: misc.c,v 1.95 2004/12/25 22:59:10 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -135,6 +135,9 @@ NtUserCallNoParam(DWORD Routine) Result = (DWORD)GDI_MapHandleTable(NtCurrentProcess()); break; + case NOPARAM_ROUTINE_MSQCLEARWAKEMASK: + return (DWORD)IntMsqClearWakeMask(); + default: DPRINT1("Calling invalid routine number 0x%x in NtUserCallNoParam\n", Routine); SetLastWin32Error(ERROR_INVALID_PARAMETER); @@ -333,6 +336,9 @@ NtUserCallOneParam( return FALSE; } + + case ONEPARAM_ROUTINE_MSQSETWAKEMASK: + return (DWORD)IntMsqSetWakeMask(Param); } DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n", Routine, Param); diff --git a/reactos/subsys/win32k/ntuser/msgqueue.c b/reactos/subsys/win32k/ntuser/msgqueue.c index 2efccbffe3a..20c1b59b9a7 100644 --- a/reactos/subsys/win32k/ntuser/msgqueue.c +++ b/reactos/subsys/win32k/ntuser/msgqueue.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: msgqueue.c,v 1.110 2004/12/11 19:39:18 weiden Exp $ +/* $Id: msgqueue.c,v 1.111 2004/12/25 22:59:10 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -65,19 +65,42 @@ static PAGED_LOOKASIDE_LIST MessageLookasideList; /* FUNCTIONS *****************************************************************/ -/* set some queue bits */ -inline VOID MsqSetQueueBits( PUSER_MESSAGE_QUEUE Queue, WORD Bits ) +HANDLE FASTCALL +IntMsqSetWakeMask(DWORD WakeMask) { - Queue->WakeBits |= Bits; - Queue->ChangedBits |= Bits; - if (MsqIsSignaled( Queue )) KeSetEvent(&Queue->NewMessages, IO_NO_INCREMENT, FALSE); + PW32THREAD Win32Thread; + PUSER_MESSAGE_QUEUE MessageQueue; + HANDLE MessageEventHandle; + + Win32Thread = PsGetWin32Thread(); + if (Win32Thread == NULL || Win32Thread->MessageQueue == NULL) + return 0; + + MessageQueue = Win32Thread->MessageQueue; + IntLockMessageQueue(MessageQueue); + MessageQueue->WakeMask = WakeMask; + MessageEventHandle = MessageQueue->NewMessagesHandle; + IntUnLockMessageQueue(MessageQueue); + + return MessageEventHandle; } -/* clear some queue bits */ -inline VOID MsqClearQueueBits( PUSER_MESSAGE_QUEUE Queue, WORD Bits ) +BOOL FASTCALL +IntMsqClearWakeMask(VOID) { - Queue->WakeBits &= ~Bits; - Queue->ChangedBits &= ~Bits; + PW32THREAD Win32Thread; + PUSER_MESSAGE_QUEUE MessageQueue; + + Win32Thread = PsGetWin32Thread(); + if (Win32Thread == NULL || Win32Thread->MessageQueue == NULL) + return FALSE; + + MessageQueue = Win32Thread->MessageQueue; + IntLockMessageQueue(MessageQueue); + MessageQueue->WakeMask = ~0; + IntUnLockMessageQueue(MessageQueue); + + return TRUE; } VOID FASTCALL @@ -86,7 +109,10 @@ MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue) IntLockMessageQueue(Queue); Queue->PaintCount++; Queue->PaintPosted = TRUE; - KeSetEvent(&Queue->NewMessages, IO_NO_INCREMENT, FALSE); + Queue->QueueBits |= QS_PAINT; + Queue->ChangedBits |= QS_PAINT; + if (Queue->WakeMask & QS_PAINT) + KeSetEvent(Queue->NewMessages, IO_NO_INCREMENT, FALSE); IntUnLockMessageQueue(Queue); } @@ -305,10 +331,21 @@ MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, UINT Filte } /* save the pointer to the WM_MOUSEMOVE message in the new queue */ Window->MessageQueue->MouseMoveMsg = Message; + + Window->MessageQueue->QueueBits |= QS_MOUSEMOVE; + Window->MessageQueue->ChangedBits |= QS_MOUSEMOVE; + if (Window->MessageQueue->WakeMask & QS_MOUSEMOVE) + KeSetEvent(Window->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); + } + else + { + Window->MessageQueue->QueueBits |= QS_MOUSEBUTTON; + Window->MessageQueue->ChangedBits |= QS_MOUSEBUTTON; + if (Window->MessageQueue->WakeMask & QS_MOUSEBUTTON) + KeSetEvent(Window->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); } IntUnLockHardwareMessageQueue(Window->MessageQueue); - KeSetEvent(&Window->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); *Freed = FALSE; IntReleaseWindowObject(Window); return(FALSE); @@ -416,7 +453,7 @@ MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, return FALSE; } - WaitObjects[1] = &MessageQueue->NewMessages; + WaitObjects[1] = MessageQueue->NewMessages; WaitObjects[0] = &HardwareMessageQueueLock; do { @@ -585,7 +622,7 @@ MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) FocusMessageQueue = IntGetFocusMessageQueue(); if( !IntGetScreenDC() ) { if( W32kGetPrimitiveMessageQueue() ) { - MsqPostMessage(W32kGetPrimitiveMessageQueue(), &Msg, FALSE); + MsqPostMessage(W32kGetPrimitiveMessageQueue(), &Msg, FALSE, QS_KEY); } } else { if (FocusMessageQueue == NULL) @@ -598,7 +635,7 @@ MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { Msg.hwnd = FocusMessageQueue->FocusWindow; DPRINT("Msg.hwnd = %x\n", Msg.hwnd); - MsqPostMessage(FocusMessageQueue, &Msg, FALSE); + MsqPostMessage(FocusMessageQueue, &Msg, FALSE, QS_KEY); } else { @@ -647,14 +684,14 @@ MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam) // Mesg.pt.y = PsGetWin32Process()->WindowStation->SystemCursor.y; // KeQueryTickCount(&LargeTickCount); // Mesg.time = LargeTickCount.u.LowPart; - MsqPostMessage(Window->MessageQueue, &Mesg, FALSE); + MsqPostMessage(Window->MessageQueue, &Mesg, FALSE, QS_HOTKEY); ObmDereferenceObject(Window); ObDereferenceObject (Thread); // IntLockMessageQueue(pThread->MessageQueue); // InsertHeadList(&pThread->MessageQueue->PostedMessagesListHead, // &Message->ListEntry); -// KeSetEvent(&pThread->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); +// KeSetEvent(pThread->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); // IntUnLockMessageQueue(pThread->MessageQueue); } @@ -894,7 +931,10 @@ MsqSendNotifyMessage(PUSER_MESSAGE_QUEUE MessageQueue, IntLockMessageQueue(MessageQueue); InsertTailList(&MessageQueue->NotifyMessagesListHead, &NotifyMessage->ListEntry); - KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); + MessageQueue->QueueBits |= QS_SENDMESSAGE; + MessageQueue->ChangedBits |= QS_SENDMESSAGE; + if (MessageQueue->WakeMask & QS_SENDMESSAGE) + KeSetEvent(MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); IntUnLockMessageQueue(MessageQueue); } @@ -949,7 +989,10 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry); IntUnLockMessageQueue(MessageQueue); - KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); + MessageQueue->QueueBits |= QS_SENDMESSAGE; + MessageQueue->ChangedBits |= QS_SENDMESSAGE; + if (MessageQueue->WakeMask & QS_SENDMESSAGE) + KeSetEvent(MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); /* we can't access the Message anymore since it could have already been deleted! */ @@ -1010,7 +1053,7 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, PVOID WaitObjects[2]; WaitObjects[0] = &CompletionEvent; - WaitObjects[1] = &ThreadQueue->NewMessages; + WaitObjects[1] = ThreadQueue->NewMessages; do { WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest, @@ -1073,7 +1116,8 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, } VOID FASTCALL -MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN FreeLParam) +MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN FreeLParam, + DWORD MessageBits) { PUSER_MESSAGE Message; @@ -1084,7 +1128,10 @@ MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN FreeLParam) IntLockMessageQueue(MessageQueue); InsertTailList(&MessageQueue->PostedMessagesListHead, &Message->ListEntry); - KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); + MessageQueue->QueueBits |= MessageBits; + MessageQueue->ChangedBits |= MessageBits; + if (MessageQueue->WakeMask & MessageBits) + KeSetEvent(MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); IntUnLockMessageQueue(MessageQueue); } @@ -1094,7 +1141,10 @@ MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode) IntLockMessageQueue(MessageQueue); MessageQueue->QuitPosted = TRUE; MessageQueue->QuitExitCode = ExitCode; - KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); + MessageQueue->QueueBits |= QS_POSTMESSAGE; + MessageQueue->ChangedBits |= QS_POSTMESSAGE; + if (MessageQueue->WakeMask & QS_POSTMESSAGE) + KeSetEvent(MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); IntUnLockMessageQueue(MessageQueue); } @@ -1147,7 +1197,7 @@ MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue, NTSTATUS FASTCALL MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue) { - PVOID WaitObjects[2] = {&MessageQueue->NewMessages, &HardwareMessageEvent}; + PVOID WaitObjects[2] = {MessageQueue->NewMessages, &HardwareMessageEvent}; return(KeWaitForMultipleObjects(2, WaitObjects, WaitAny, @@ -1167,10 +1217,11 @@ MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue) return ((LargeTickCount.u.LowPart - MessageQueue->LastMsgRead) > MSQ_HUNG); } -VOID FASTCALL +BOOLEAN FASTCALL MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQueue) { LARGE_INTEGER LargeTickCount; + NTSTATUS Status; MessageQueue->Thread = Thread; MessageQueue->CaretInfo = (PTHRDCARETINFO)(MessageQueue + 1); @@ -1183,12 +1234,32 @@ MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQu ExInitializeFastMutex(&MessageQueue->Lock); MessageQueue->QuitPosted = FALSE; MessageQueue->QuitExitCode = 0; - KeInitializeEvent(&MessageQueue->NewMessages, SynchronizationEvent, FALSE); KeQueryTickCount(&LargeTickCount); MessageQueue->LastMsgRead = LargeTickCount.u.LowPart; MessageQueue->FocusWindow = NULL; MessageQueue->PaintPosted = FALSE; MessageQueue->PaintCount = 0; + MessageQueue->WakeMask = ~0; + MessageQueue->NewMessagesHandle = NULL; + + Status = ZwCreateEvent(&MessageQueue->NewMessagesHandle, EVENT_ALL_ACCESS, + NULL, SynchronizationEvent, FALSE); + if (!NT_SUCCESS(Status)) + { + return FALSE; + } + + Status = ObReferenceObjectByHandle(MessageQueue->NewMessagesHandle, 0, + ExEventObjectType, KernelMode, + (PVOID*)&MessageQueue->NewMessages, NULL); + if (!NT_SUCCESS(Status)) + { + ZwClose(MessageQueue->NewMessagesHandle); + MessageQueue->NewMessagesHandle = NULL; + return FALSE; + } + + return TRUE; } VOID FASTCALL @@ -1298,7 +1369,11 @@ MsqCreateMessageQueue(struct _ETHREAD *Thread) /* hold at least one reference until it'll be destroyed */ IntReferenceMessageQueue(MessageQueue); /* initialize the queue */ - MsqInitializeMessageQueue(Thread, MessageQueue); + if (!MsqInitializeMessageQueue(Thread, MessageQueue)) + { + IntDereferenceMessageQueue(MessageQueue); + return NULL; + } return MessageQueue; } diff --git a/reactos/subsys/win32k/ntuser/timer.c b/reactos/subsys/win32k/ntuser/timer.c index 05011780d3c..8d4a19030fc 100644 --- a/reactos/subsys/win32k/ntuser/timer.c +++ b/reactos/subsys/win32k/ntuser/timer.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: timer.c,v 1.36 2004/09/28 15:02:30 weiden Exp $ +/* $Id: timer.c,v 1.37 2004/12/25 22:59:10 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -405,7 +405,8 @@ TimerThreadMain(PVOID StartContext) continue; } - MsqPostMessage(Thread->Tcb.Win32Thread->MessageQueue, &MsgTimer->Msg, FALSE); + MsqPostMessage(Thread->Tcb.Win32Thread->MessageQueue, &MsgTimer->Msg, + FALSE, QS_TIMER); ThreadsToDereference[ThreadsToDereferencePos] = Thread; ++ThreadsToDereferencePos;