[WIN32K]
[reactos.git] / reactos / subsystems / win32 / win32k / include / msgqueue.h
1 #pragma once
2
3 #define MSQ_HUNG 5000
4 #define MSQ_NORMAL 0
5 #define MSQ_ISHOOK 1
6 #define MSQ_ISEVENT 2
7 #define MSQ_INJECTMODULE 3
8
9 #define QSIDCOUNTS 6
10
11 typedef enum _QS_ROS_TYPES
12 {
13 QSRosKey = 0,
14 QSRosMouseMove,
15 QSRosMouseButton,
16 QSRosPostMessage,
17 QSRosSendMessage,
18 QSRosHotKey,
19 }QS_ROS_TYPES,*PQS_ROS_TYPES;
20
21 typedef struct _USER_MESSAGE
22 {
23 LIST_ENTRY ListEntry;
24 MSG Msg;
25 DWORD QS_Flags;
26 } USER_MESSAGE, *PUSER_MESSAGE;
27
28 struct _USER_MESSAGE_QUEUE;
29
30 typedef struct _USER_SENT_MESSAGE
31 {
32 LIST_ENTRY ListEntry;
33 MSG Msg;
34 DWORD QS_Flags; // Original QS bits used to create this message.
35 PKEVENT CompletionEvent;
36 LRESULT* Result;
37 LRESULT lResult;
38 struct _USER_MESSAGE_QUEUE* SenderQueue;
39 struct _USER_MESSAGE_QUEUE* CallBackSenderQueue;
40 SENDASYNCPROC CompletionCallback;
41 ULONG_PTR CompletionCallbackContext;
42 /* entry in the dispatching list of the sender's message queue */
43 LIST_ENTRY DispatchingListEntry;
44 INT HookMessage;
45 BOOL HasPackedLParam;
46 } USER_SENT_MESSAGE, *PUSER_SENT_MESSAGE;
47
48 typedef struct _USER_MESSAGE_QUEUE
49 {
50 /* Reference counter, only access this variable with interlocked functions! */
51 LONG References;
52
53 /* Owner of the message queue */
54 struct _ETHREAD *Thread;
55 /* Queue of messages sent to the queue. */
56 LIST_ENTRY SentMessagesListHead;
57 /* Queue of messages posted to the queue. */
58 LIST_ENTRY PostedMessagesListHead;
59 /* Queue for hardware messages for the queue. */
60 LIST_ENTRY HardwareMessagesListHead;
61 /* True if a WM_MOUSEMOVE is pending */
62 BOOLEAN MouseMoved;
63 /* Current WM_MOUSEMOVE message */
64 MSG MouseMoveMsg;
65 /* Last click message for translating double clicks */
66 MSG msgDblClk;
67 /* True if a WM_QUIT message is pending. */
68 BOOLEAN QuitPosted;
69 /* The quit exit code. */
70 ULONG QuitExitCode;
71 /* Set if there are new messages specified by WakeMask in any of the queues. */
72 PKEVENT NewMessages;
73 /* Handle for the above event (in the context of the process owning the queue). */
74 HANDLE NewMessagesHandle;
75 /* Last time PeekMessage() was called. */
76 ULONG LastMsgRead;
77 /* Current capture window for this queue. */
78 HWND CaptureWindow;
79 PWND spwndCapture;
80 /* Current window with focus (ie. receives keyboard input) for this queue. */
81 HWND FocusWindow;
82 PWND spwndFocus;
83 /* Current active window for this queue. */
84 HWND ActiveWindow;
85 PWND spwndActive;
86 PWND spwndActivePrev;
87 /* Current move/size window for this queue */
88 HWND MoveSize;
89 /* Current menu owner window for this queue */
90 HWND MenuOwner;
91 /* Identifes the menu state */
92 BYTE MenuState;
93 /* Caret information for this queue */
94 PTHRDCARETINFO CaretInfo;
95 /* Message Queue Flags */
96 DWORD QF_flags;
97
98 /* Queue state tracking */
99 // Send list QS_SENDMESSAGE
100 // Post list QS_POSTMESSAGE|QS_HOTKEY|QS_PAINT|QS_TIMER|QS_KEY
101 // Hard list QS_MOUSE|QS_KEY only
102 // Accounting of queue bit sets, the rest are flags. QS_TIMER QS_PAINT counts are handled in thread information.
103 DWORD nCntsQBits[QSIDCOUNTS]; // QS_KEY QS_MOUSEMOVE QS_MOUSEBUTTON QS_POSTMESSAGE QS_SENDMESSAGE QS_HOTKEY
104
105 /* Extra message information */
106 LPARAM ExtraInfo;
107
108 /* State of each key */
109 BYTE afKeyRecentDown[256 / 8]; // 1 bit per key
110 BYTE afKeyState[256 * 2 / 8]; // 2 bits per key
111
112 /* Showing cursor counter (value>=0 - cursor visible, value<0 - cursor hidden) */
113 INT ShowingCursor;
114 /* Cursor object */
115 PCURICON_OBJECT CursorObject;
116
117 /* Messages that are currently dispatched by other threads */
118 LIST_ENTRY DispatchingMessagesHead;
119 /* Messages that are currently dispatched by this message queue, required for cleanup */
120 LIST_ENTRY LocalDispatchingMessagesHead;
121
122 /* Desktop that the message queue is attached to */
123 struct _DESKTOP *Desktop;
124 } USER_MESSAGE_QUEUE, *PUSER_MESSAGE_QUEUE;
125
126 #define QF_UPDATEKEYSTATE 0x00000001
127 #define QF_FMENUSTATUSBREAK 0x00000004
128 #define QF_FMENUSTATUS 0x00000008
129 #define QF_FF10STATUS 0x00000010
130 #define QF_MOUSEMOVED 0x00000020 // See MouseMoved.
131 #define QF_ACTIVATIONCHANGE 0x00000040
132 #define QF_TABSWITCHING 0x00000080
133 #define QF_KEYSTATERESET 0x00000100
134 #define QF_INDESTROY 0x00000200
135 #define QF_LOCKNOREMOVE 0x00000400
136 #define QF_FOCUSNULLSINCEACTIVE 0x00000800
137 #define QF_DIALOGACTIVE 0x00004000
138 #define QF_EVENTDEACTIVATEREMOVED 0x00008000
139 #define QF_TRACKMOUSELEAVE 0x00020000
140 #define QF_TRACKMOUSEHOVER 0x00040000
141 #define QF_TRACKMOUSEFIRING 0x00080000
142 #define QF_CAPTURELOCKED 0x00100000
143 #define QF_ACTIVEWNDTRACKING 0x00200000
144
145 /* Internal messages codes */
146 enum internal_event_message
147 {
148 WM_ASYNC_SHOWWINDOW = 0x80000000,
149 WM_ASYNC_SETWINDOWPOS
150 };
151
152 BOOL FASTCALL MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue);
153 VOID CALLBACK HungAppSysTimerProc(HWND,UINT,UINT_PTR,DWORD);
154 NTSTATUS FASTCALL co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
155 HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam,
156 UINT uTimeout, BOOL Block, INT HookMessage, ULONG_PTR *uResult);
157 PUSER_MESSAGE FASTCALL MsqCreateMessage(LPMSG Msg);
158 VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE Message);
159 VOID FASTCALL MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN HardwareMessage, DWORD MessageBits);
160 VOID FASTCALL MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode);
161 BOOLEAN APIENTRY
162 MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
163 IN BOOLEAN Remove,
164 IN PWND Window,
165 IN UINT MsgFilterLow,
166 IN UINT MsgFilterHigh,
167 IN UINT QSflags,
168 OUT PMSG Message);
169 BOOL APIENTRY
170 co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
171 IN BOOL Remove,
172 IN PWND Window,
173 IN UINT MsgFilterLow,
174 IN UINT MsgFilterHigh,
175 IN UINT QSflags,
176 OUT MSG* pMsg);
177 BOOL APIENTRY
178 co_MsqPeekMouseMove(IN PUSER_MESSAGE_QUEUE MessageQueue,
179 IN BOOL Remove,
180 IN PWND Window,
181 IN UINT MsgFilterLow,
182 IN UINT MsgFilterHigh,
183 OUT MSG* pMsg);
184 BOOLEAN FASTCALL MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQueue);
185 PUSER_MESSAGE_QUEUE FASTCALL MsqCreateMessageQueue(struct _ETHREAD *Thread);
186 VOID FASTCALL MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue);
187 INIT_FUNCTION NTSTATUS NTAPI MsqInitializeImpl(VOID);
188 BOOLEAN FASTCALL co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue);
189 NTSTATUS FASTCALL
190 co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWND WndFilter,
191 UINT MsgFilterMin, UINT MsgFilterMax);
192 VOID FASTCALL MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue);
193 VOID FASTCALL MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue);
194 LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
195 LRESULT FASTCALL co_IntPostOrSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
196 LRESULT FASTCALL
197 co_IntSendMessageTimeout(HWND hWnd,
198 UINT Msg,
199 WPARAM wParam,
200 LPARAM lParam,
201 UINT uFlags,
202 UINT uTimeout,
203 ULONG_PTR *uResult);
204
205 BOOL FASTCALL UserSendNotifyMessage( HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam );
206 LRESULT FASTCALL co_IntSendMessageNoWait(HWND hWnd,
207 UINT Msg,
208 WPARAM wParam,
209 LPARAM lParam);
210 LRESULT FASTCALL
211 co_IntSendMessageWithCallBack(HWND hWnd,
212 UINT Msg,
213 WPARAM wParam,
214 LPARAM lParam,
215 SENDASYNCPROC CompletionCallback,
216 ULONG_PTR CompletionCallbackContext,
217 ULONG_PTR *uResult);
218 BOOL FASTCALL
219 co_MsqSendMessageAsync(PTHREADINFO ptiReceiver,
220 HWND hwnd,
221 UINT Msg,
222 WPARAM wParam,
223 LPARAM lParam,
224 SENDASYNCPROC CompletionCallback,
225 ULONG_PTR CompletionCallbackContext,
226 BOOL HasPackedLParam,
227 INT HookMessage);
228
229 LRESULT FASTCALL IntDispatchMessage(MSG* Msg);
230 BOOL FASTCALL IntTranslateKbdMessage(LPMSG lpMsg, UINT flags);
231 VOID FASTCALL MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam);
232 VOID FASTCALL co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook);
233 BOOL FASTCALL MsqIsClkLck(LPMSG Msg, BOOL Remove);
234 BOOL FASTCALL MsqIsDblClk(LPMSG Msg, BOOL Remove);
235 HWND FASTCALL MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd);
236 BOOL APIENTRY IntInitMessagePumpHook(VOID);
237 BOOL APIENTRY IntUninitMessagePumpHook(VOID);
238
239 LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam);
240 LPARAM FASTCALL MsqGetMessageExtraInfo(VOID);
241 VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PVOID pWindow); /* F*(&$ headers, will be gone in the rewrite! */
242
243 #define IntReferenceMessageQueue(MsgQueue) \
244 InterlockedIncrement(&(MsgQueue)->References)
245
246 #define IntDereferenceMessageQueue(MsgQueue) \
247 do { \
248 if(InterlockedDecrement(&(MsgQueue)->References) == 0) \
249 { \
250 TRACE("Free message queue 0x%x\n", (MsgQueue)); \
251 if ((MsgQueue)->NewMessages != NULL) \
252 ObDereferenceObject((MsgQueue)->NewMessages); \
253 ExFreePoolWithTag((MsgQueue), USERTAG_Q); \
254 } \
255 } while(0)
256
257 #define IS_BTN_MESSAGE(message,code) \
258 ((message) == WM_LBUTTON##code || \
259 (message) == WM_MBUTTON##code || \
260 (message) == WM_RBUTTON##code || \
261 (message) == WM_XBUTTON##code || \
262 (message) == WM_NCLBUTTON##code || \
263 (message) == WM_NCMBUTTON##code || \
264 (message) == WM_NCRBUTTON##code || \
265 (message) == WM_NCXBUTTON##code )
266
267 #define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
268 #define WM_NCMOUSELAST (WM_NCMOUSEFIRST+(WM_MOUSELAST-WM_MOUSEFIRST))
269
270 #define IS_MOUSE_MESSAGE(message) \
271 ((message >= WM_NCMOUSEFIRST && message <= WM_NCMOUSELAST) || \
272 (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST))
273
274 #define IS_KBD_MESSAGE(message) \
275 (message >= WM_KEYFIRST && message <= WM_KEYLAST)
276
277 HANDLE FASTCALL IntMsqSetWakeMask(DWORD WakeMask);
278 BOOL FASTCALL IntMsqClearWakeMask(VOID);
279
280 static __inline LONG
281 MsqCalculateMessageTime(IN PLARGE_INTEGER TickCount)
282 {
283 return (LONG)(TickCount->QuadPart * (KeQueryTimeIncrement() / 10000));
284 }
285
286 VOID FASTCALL IdlePing(VOID);
287 VOID FASTCALL IdlePong(VOID);
288 BOOL FASTCALL co_MsqReplyMessage(LRESULT);
289 VOID FASTCALL MsqWakeQueue(PUSER_MESSAGE_QUEUE,DWORD,BOOL);
290 VOID FASTCALL ClearMsgBitsMask(PUSER_MESSAGE_QUEUE,UINT);
291
292 int UserShowCursor(BOOL bShow);
293 PCURICON_OBJECT
294 FASTCALL
295 UserSetCursor(PCURICON_OBJECT NewCursor,
296 BOOL ForceChange);
297
298 DWORD APIENTRY IntGetQueueStatus(DWORD);
299 /* EOF */