reactos/win32ss/user/ntuser/msgqueue.h
Hermès Bélusca-Maïto f44e914e80 Sync with trunk r58033.
svn path=/branches/ros-csrss/; revision=58034
2012-12-28 23:37:33 +00:00

314 lines
11 KiB
C

#pragma once
#define MSQ_HUNG 5000
#define MSQ_NORMAL 0
#define MSQ_ISHOOK 1
#define MSQ_ISEVENT 2
#define MSQ_INJECTMODULE 3
#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;
LONG_PTR ExtraInfo;
DWORD dwQEvent;
PTHREADINFO pti;
} USER_MESSAGE, *PUSER_MESSAGE;
struct _USER_MESSAGE_QUEUE;
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;
struct _USER_MESSAGE_QUEUE* CallBackSenderQueue;
SENDASYNCPROC CompletionCallback;
ULONG_PTR CompletionCallbackContext;
/* entry in the dispatching list of the sender's message queue */
LIST_ENTRY DispatchingListEntry;
INT HookMessage;
BOOL HasPackedLParam;
} USER_SENT_MESSAGE, *PUSER_SENT_MESSAGE;
typedef struct _USER_MESSAGE_QUEUE
{
/* Reference counter, only access this variable with interlocked functions! */
LONG References;
PTHREADINFO ptiSysLock;
/* Owner of the message queue */
struct _ETHREAD *Thread;
/* Queue of messages sent to the queue. */
LIST_ENTRY SentMessagesListHead;
/* Queue of messages posted to the queue. */
LIST_ENTRY PostedMessagesListHead;
/* Queue for hardware messages for the queue. */
LIST_ENTRY HardwareMessagesListHead;
/* True if a WM_MOUSEMOVE is pending */
BOOLEAN MouseMoved;
/* Current WM_MOUSEMOVE message */
MSG MouseMoveMsg;
/* Last click message for translating double clicks */
MSG msgDblClk;
/* True if a WM_QUIT message is pending. */
BOOLEAN QuitPosted;
/* The quit exit code. */
ULONG QuitExitCode;
/* 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 capture window for this queue. */
PWND spwndCapture;
/* Current window with focus (ie. receives keyboard input) for this queue. */
PWND spwndFocus;
/* Current active window for this queue. */
PWND spwndActive;
PWND spwndActivePrev;
/* Current move/size window for this queue */
HWND MoveSize;
/* Current menu owner window for this queue */
HWND MenuOwner;
/* Identifes the menu state */
BYTE MenuState;
/* Caret information for this queue */
PTHRDCARETINFO CaretInfo;
/* Message Queue Flags */
DWORD QF_flags;
DWORD cThreads; // Shared message queue counter.
/* Queue state tracking */
// 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;
/* State of each key */
BYTE afKeyRecentDown[256 / 8]; // 1 bit per key
BYTE afKeyState[256 * 2 / 8]; // 2 bits per key
/* Showing cursor counter (value>=0 - cursor visible, value<0 - cursor hidden) */
INT iCursorLevel;
/* Cursor object */
PCURICON_OBJECT CursorObject;
/* Messages that are currently dispatched by other threads */
LIST_ENTRY DispatchingMessagesHead;
/* Messages that are currently dispatched by this message queue, required for cleanup */
LIST_ENTRY LocalDispatchingMessagesHead;
/* Desktop that the message queue is attached to */
struct _DESKTOP *Desktop;
} USER_MESSAGE_QUEUE, *PUSER_MESSAGE_QUEUE;
#define QF_UPDATEKEYSTATE 0x00000001
#define QF_FMENUSTATUSBREAK 0x00000004
#define QF_FMENUSTATUS 0x00000008
#define QF_FF10STATUS 0x00000010
#define QF_MOUSEMOVED 0x00000020 // See MouseMoved.
#define QF_ACTIVATIONCHANGE 0x00000040
#define QF_TABSWITCHING 0x00000080
#define QF_KEYSTATERESET 0x00000100
#define QF_INDESTROY 0x00000200
#define QF_LOCKNOREMOVE 0x00000400
#define QF_FOCUSNULLSINCEACTIVE 0x00000800
#define QF_DIALOGACTIVE 0x00004000
#define QF_EVENTDEACTIVATEREMOVED 0x00008000
#define QF_TRACKMOUSELEAVE 0x00020000
#define QF_TRACKMOUSEHOVER 0x00040000
#define QF_TRACKMOUSEFIRING 0x00080000
#define QF_CAPTURELOCKED 0x00100000
#define QF_ACTIVEWNDTRACKING 0x00200000
/* Internal messages codes */
enum internal_event_message
{
WM_ASYNC_SHOWWINDOW = 0x80000000,
WM_ASYNC_SETWINDOWPOS,
WM_ASYNC_SETACTIVEWINDOW
};
BOOL FASTCALL MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue);
VOID CALLBACK HungAppSysTimerProc(HWND,UINT,UINT_PTR,DWORD);
NTSTATUS FASTCALL co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam,
UINT uTimeout, BOOL Block, INT HookMessage, ULONG_PTR *uResult);
PUSER_MESSAGE FASTCALL MsqCreateMessage(LPMSG Msg);
VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE Message);
VOID FASTCALL MsqPostMessage(PUSER_MESSAGE_QUEUE, MSG*, BOOLEAN, DWORD, DWORD);
VOID FASTCALL MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode);
BOOLEAN APIENTRY
MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
IN BOOLEAN Remove,
IN PWND Window,
IN UINT MsgFilterLow,
IN UINT MsgFilterHigh,
IN UINT QSflags,
OUT PMSG Message);
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);
BOOL APIENTRY
co_MsqPeekMouseMove(IN PUSER_MESSAGE_QUEUE MessageQueue,
IN BOOL Remove,
IN PWND Window,
IN UINT MsgFilterLow,
IN UINT MsgFilterHigh,
OUT MSG* pMsg);
BOOLEAN FASTCALL MsqInitializeMessageQueue(PTHREADINFO, PUSER_MESSAGE_QUEUE);
PUSER_MESSAGE_QUEUE FASTCALL MsqCreateMessageQueue(PTHREADINFO);
VOID FASTCALL MsqDestroyMessageQueue(PTHREADINFO);
INIT_FUNCTION NTSTATUS NTAPI MsqInitializeImpl(VOID);
BOOLEAN FASTCALL co_MsqDispatchOneSentMessage(_In_ PUSER_MESSAGE_QUEUE MessageQueue);
NTSTATUS FASTCALL
co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWND WndFilter,
UINT MsgFilterMin, UINT MsgFilterMax);
VOID FASTCALL MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue);
VOID FASTCALL MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue);
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
LRESULT FASTCALL co_IntPostOrSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
LRESULT FASTCALL
co_IntSendMessageTimeout(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
UINT uFlags,
UINT uTimeout,
ULONG_PTR *uResult);
BOOL FASTCALL UserSendNotifyMessage( HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam );
LRESULT FASTCALL co_IntSendMessageNoWait(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam);
LRESULT FASTCALL
co_IntSendMessageWithCallBack(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
SENDASYNCPROC CompletionCallback,
ULONG_PTR CompletionCallbackContext,
ULONG_PTR *uResult);
BOOL FASTCALL
co_MsqSendMessageAsync(PTHREADINFO ptiReceiver,
HWND hwnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam,
SENDASYNCPROC CompletionCallback,
ULONG_PTR CompletionCallbackContext,
BOOL HasPackedLParam,
INT HookMessage);
LRESULT FASTCALL IntDispatchMessage(MSG* Msg);
BOOL FASTCALL IntTranslateKbdMessage(LPMSG lpMsg, UINT flags);
VOID FASTCALL MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam);
VOID FASTCALL co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook);
BOOL FASTCALL MsqIsClkLck(LPMSG Msg, BOOL Remove);
BOOL FASTCALL MsqIsDblClk(LPMSG Msg, BOOL Remove);
HWND FASTCALL MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd);
BOOL APIENTRY IntInitMessagePumpHook(VOID);
BOOL APIENTRY IntUninitMessagePumpHook(VOID);
LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam);
LPARAM FASTCALL MsqGetMessageExtraInfo(VOID);
VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PVOID pWindow); /* F*(&$ headers, will be gone in the rewrite! */
#define IntReferenceMessageQueue(MsgQueue) \
InterlockedIncrement(&(MsgQueue)->References)
#define IntDereferenceMessageQueue(MsgQueue) \
do { \
if(InterlockedDecrement(&(MsgQueue)->References) == 0) \
{ \
TRACE("Free message queue 0x%p\n", (MsgQueue)); \
if ((MsgQueue)->NewMessages != NULL) \
ObDereferenceObject((MsgQueue)->NewMessages); \
ExFreePoolWithTag((MsgQueue), USERTAG_Q); \
} \
} while(0)
#define IS_BTN_MESSAGE(message,code) \
((message) == WM_LBUTTON##code || \
(message) == WM_MBUTTON##code || \
(message) == WM_RBUTTON##code || \
(message) == WM_XBUTTON##code || \
(message) == WM_NCLBUTTON##code || \
(message) == WM_NCMBUTTON##code || \
(message) == WM_NCRBUTTON##code || \
(message) == WM_NCXBUTTON##code )
#define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
#define WM_NCMOUSELAST (WM_NCMOUSEFIRST+(WM_MOUSELAST-WM_MOUSEFIRST))
#define IS_MOUSE_MESSAGE(message) \
((message >= WM_NCMOUSEFIRST && message <= WM_NCMOUSELAST) || \
(message >= WM_MOUSEFIRST && message <= WM_MOUSELAST))
#define IS_KBD_MESSAGE(message) \
(message >= WM_KEYFIRST && message <= WM_KEYLAST)
HANDLE FASTCALL IntMsqSetWakeMask(DWORD WakeMask);
BOOL FASTCALL IntMsqClearWakeMask(VOID);
static __inline LONG
MsqCalculateMessageTime(IN PLARGE_INTEGER TickCount)
{
return (LONG)(TickCount->QuadPart * (KeQueryTimeIncrement() / 10000));
}
VOID FASTCALL IdlePing(VOID);
VOID FASTCALL IdlePong(VOID);
BOOL FASTCALL co_MsqReplyMessage(LRESULT);
VOID FASTCALL MsqWakeQueue(PUSER_MESSAGE_QUEUE,DWORD,BOOL);
VOID FASTCALL ClearMsgBitsMask(PUSER_MESSAGE_QUEUE,UINT);
int UserShowCursor(BOOL bShow);
PCURICON_OBJECT
FASTCALL
UserSetCursor(PCURICON_OBJECT NewCursor,
BOOL ForceChange);
DWORD APIENTRY IntGetQueueStatus(DWORD);
UINT lParamMemorySize(UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL FASTCALL
co_IntGetPeekMessage( PMSG pMsg,
HWND hWnd,
UINT MsgFilterMin,
UINT MsgFilterMax,
UINT RemoveMsg,
BOOL bGMSG );
/* EOF */