1 /* $Id: msgqueue.c,v 1.5 2002/07/17 21:04:57 dwelch Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Message queues
6 * FILE: subsys/win32k/ntuser/msgqueue.c
7 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 * 06-06-2001 CSH Created
12 /* INCLUDES ******************************************************************/
14 #include <ddk/ntddk.h>
15 #include <win32k/win32k.h>
16 #include <include/msgqueue.h>
17 #include <include/callback.h>
22 /* GLOBALS *******************************************************************/
24 static PUSER_MESSAGE_QUEUE CurrentFocusMessageQueue
;
26 /* FUNCTIONS *****************************************************************/
29 MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue
)
31 ExAcquireFastMutex(&Queue
->Lock
);
33 Queue
->PaintPosted
= TRUE
;
34 ExReleaseFastMutex(&Queue
->Lock
);
38 MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue
)
40 ExAcquireFastMutex(&Queue
->Lock
);
42 if (Queue
->PaintCount
== 0)
44 Queue
->PaintPosted
= FALSE
;
46 ExReleaseFastMutex(&Queue
->Lock
);
51 MsqInitializeImpl(VOID
)
53 CurrentFocusMessageQueue
= NULL
;
54 return(STATUS_SUCCESS
);
58 MsqPostKeyboardMessage(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
61 PUSER_MESSAGE Message
;
63 Msg
.hwnd
= CurrentFocusMessageQueue
->FocusWindow
;
67 /* FIXME: Initialize time and point. */
69 Message
= MsqCreateMessage(&Msg
);
70 MsqPostMessage(CurrentFocusMessageQueue
, Message
, TRUE
);
74 MsqInitializeMessage(PUSER_MESSAGE Message
,
77 RtlMoveMemory(&Message
->Msg
, Msg
, sizeof(MSG
));
81 MsqCreateMessage(LPMSG Msg
)
83 PUSER_MESSAGE Message
;
85 Message
= (PUSER_MESSAGE
)ExAllocatePool(PagedPool
, sizeof(USER_MESSAGE
));
91 MsqInitializeMessage(Message
, Msg
);
97 MsqDestroyMessage(PUSER_MESSAGE Message
)
103 MsqDispatchSentNotifyMessages(PUSER_MESSAGE_QUEUE MessageQueue
)
105 PLIST_ENTRY ListEntry
;
106 PUSER_SENT_MESSAGE_NOTIFY Message
;
108 while (!IsListEmpty(&MessageQueue
->SentMessagesListHead
))
110 ExAcquireFastMutex(&MessageQueue
->Lock
);
111 ListEntry
= RemoveHeadList(&MessageQueue
->SentMessagesListHead
);
112 Message
= CONTAINING_RECORD(ListEntry
, USER_SENT_MESSAGE_NOTIFY
,
114 ExReleaseFastMutex(&MessageQueue
->Lock
);
116 W32kCallSentMessageCallback(Message
->CompletionCallback
,
119 Message
->CompletionCallbackContext
,
125 MsqPeekSentMessages(PUSER_MESSAGE_QUEUE MessageQueue
)
127 return(!IsListEmpty(&MessageQueue
->SentMessagesListHead
));
131 MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue
)
133 PUSER_SENT_MESSAGE Message
;
136 PUSER_SENT_MESSAGE_NOTIFY NotifyMessage
;
138 ExAcquireFastMutex(&MessageQueue
->Lock
);
139 if (IsListEmpty(&MessageQueue
->SentMessagesListHead
))
141 ExReleaseFastMutex(&MessageQueue
->Lock
);
144 Entry
= RemoveHeadList(&MessageQueue
->SentMessagesListHead
);
145 Message
= CONTAINING_RECORD(Entry
, USER_SENT_MESSAGE
, ListEntry
);
146 ExReleaseFastMutex(&MessageQueue
->Lock
);
148 /* Call the window procedure. */
149 Result
= W32kCallWindowProc(NULL
,
151 Message
->Msg
.message
,
153 Message
->Msg
.lParam
);
155 /* Let the sender know the result. */
156 if (Message
->Result
!= NULL
)
158 *Message
->Result
= Result
;
161 /* Notify the sender. */
162 if (Message
->CompletionEvent
!= NULL
)
164 KeSetEvent(Message
->CompletionEvent
, IO_NO_INCREMENT
, FALSE
);
167 /* Notify the sender if they specified a callback. */
168 if (Message
->CompletionCallback
!= NULL
)
170 NotifyMessage
= ExAllocatePool(NonPagedPool
,
171 sizeof(USER_SENT_MESSAGE_NOTIFY
));
172 NotifyMessage
->CompletionCallback
=
173 Message
->CompletionCallback
;
174 NotifyMessage
->CompletionCallbackContext
=
175 Message
->CompletionCallbackContext
;
176 NotifyMessage
->Result
= Result
;
177 NotifyMessage
->hWnd
= Message
->Msg
.hwnd
;
178 NotifyMessage
->Msg
= Message
->Msg
.message
;
179 MsqSendNotifyMessage(Message
->CompletionQueue
, NotifyMessage
);
187 MsqSendNotifyMessage(PUSER_MESSAGE_QUEUE MessageQueue
,
188 PUSER_SENT_MESSAGE_NOTIFY NotifyMessage
)
190 ExAcquireFastMutex(&MessageQueue
->Lock
);
191 InsertTailList(&MessageQueue
->NotifyMessagesListHead
,
192 &NotifyMessage
->ListEntry
);
193 ExReleaseFastMutex(&MessageQueue
->Lock
);
197 MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue
,
198 PUSER_SENT_MESSAGE Message
)
200 ExAcquireFastMutex(&MessageQueue
->Lock
);
201 InsertTailList(&MessageQueue
->SentMessagesListHead
, &Message
->ListEntry
);
202 ExReleaseFastMutex(&MessageQueue
->Lock
);
206 MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue
,
207 PUSER_MESSAGE Message
,
210 ExAcquireFastMutex(&MessageQueue
->Lock
);
213 InsertTailList(&MessageQueue
->HardwareMessagesListHead
,
214 &Message
->ListEntry
);
218 InsertTailList(&MessageQueue
->PostedMessagesListHead
,
219 &Message
->ListEntry
);
221 KeSetEvent(&MessageQueue
->NewMessages
, IO_NO_INCREMENT
, FALSE
);
222 ExReleaseFastMutex(&MessageQueue
->Lock
);
226 MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue
,
230 IN UINT MsgFilterLow
,
231 IN UINT MsgFilterHigh
,
232 OUT PUSER_MESSAGE
* Message
)
234 PLIST_ENTRY CurrentEntry
;
235 PUSER_MESSAGE CurrentMessage
;
236 PLIST_ENTRY ListHead
;
238 ExAcquireFastMutex(&MessageQueue
->Lock
);
241 CurrentEntry
= MessageQueue
->HardwareMessagesListHead
.Flink
;
242 ListHead
= &MessageQueue
->HardwareMessagesListHead
;
246 CurrentEntry
= MessageQueue
->PostedMessagesListHead
.Flink
;
247 ListHead
= &MessageQueue
->PostedMessagesListHead
;
249 while (CurrentEntry
!= ListHead
)
251 CurrentMessage
= CONTAINING_RECORD(CurrentEntry
, USER_MESSAGE
,
253 if ((Wnd
== 0 || Wnd
== CurrentMessage
->Msg
.hwnd
) &&
254 ((MsgFilterLow
== 0 && MsgFilterHigh
== 0) ||
255 (MsgFilterLow
<= CurrentMessage
->Msg
.message
&&
256 MsgFilterHigh
>= CurrentMessage
->Msg
.message
)))
260 RemoveEntryList(&CurrentMessage
->ListEntry
);
262 ExReleaseFastMutex(&MessageQueue
->Lock
);
263 *Message
= CurrentMessage
;
266 CurrentEntry
= CurrentEntry
->Flink
;
268 ExReleaseFastMutex(&MessageQueue
->Lock
);
273 MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue
)
275 return(KeWaitForSingleObject(&MessageQueue
->NewMessages
,
283 MsqInitializeMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue
)
285 InitializeListHead(&MessageQueue
->PostedMessagesListHead
);
286 InitializeListHead(&MessageQueue
->HardwareMessagesListHead
);
287 InitializeListHead(&MessageQueue
->SentMessagesListHead
);
288 ExInitializeFastMutex(&MessageQueue
->Lock
);
289 MessageQueue
->QuitPosted
= FALSE
;
290 MessageQueue
->QuitExitCode
= 0;
291 KeInitializeEvent(&MessageQueue
->NewMessages
, NotificationEvent
, FALSE
);
292 MessageQueue
->QueueStatus
= 0;
293 MessageQueue
->FocusWindow
= NULL
;
297 MsqFreeMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue
)
299 PLIST_ENTRY CurrentEntry
;
300 PUSER_MESSAGE CurrentMessage
;
302 CurrentEntry
= MessageQueue
->PostedMessagesListHead
.Flink
;
303 while (CurrentEntry
!= &MessageQueue
->PostedMessagesListHead
)
305 CurrentMessage
= CONTAINING_RECORD(CurrentEntry
, USER_MESSAGE
,
307 CurrentEntry
= CurrentEntry
->Flink
;
308 ExFreePool(CurrentMessage
);
311 CurrentEntry
= MessageQueue
->HardwareMessagesListHead
.Flink
;
312 while (CurrentEntry
!= &MessageQueue
->HardwareMessagesListHead
)
314 CurrentMessage
= CONTAINING_RECORD(CurrentEntry
, USER_MESSAGE
,
316 CurrentEntry
= CurrentEntry
->Flink
;
317 ExFreePool(CurrentMessage
);
322 MsqCreateMessageQueue(VOID
)
324 PUSER_MESSAGE_QUEUE MessageQueue
;
326 MessageQueue
= (PUSER_MESSAGE_QUEUE
)ExAllocatePool(PagedPool
,
327 sizeof(USER_MESSAGE_QUEUE
));
333 MsqInitializeMessageQueue(MessageQueue
);
339 MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue
)
341 MsqFreeMessageQueue(MessageQueue
);
342 ExFreePool(MessageQueue
);