ReactOS 0.4.15-dev-5863-g1fe3ab7
msgqueue.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Message queues
5 * FILE: win32ss/user/ntuser/msgqueue.c
6 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 Alexandre Julliard
8 Maarten Lankhorst
9 */
10
11#include <win32k.h>
13
14/* GLOBALS *******************************************************************/
15
24
25/* FUNCTIONS *****************************************************************/
26
27CODE_SEG("INIT")
31{
32 // Setup Post Messages
35 return STATUS_NO_MEMORY;
37 NULL,
38 NULL,
39 0,
40 sizeof(USER_MESSAGE),
42 256);
43 // Setup Send Messages
46 return STATUS_NO_MEMORY;
48 NULL,
49 NULL,
50 0,
51 sizeof(USER_SENT_MESSAGE),
53 16);
54
56
57 return(STATUS_SUCCESS);
58}
59
62{
63 PWND pWnd, pwndDesktop;
64
65 /* Get the desktop window */
66 pwndDesktop = UserGetDesktopWindow();
67 if (!pwndDesktop)
68 return NULL;
69
70 /* Loop all top level windows */
71 for (pWnd = pwndDesktop->spwndChild;
72 pWnd != NULL;
73 pWnd = pWnd->spwndNext)
74 {
75 if (pWnd->state2 & WNDS2_INDESTROY || pWnd->state & WNDS_DESTROYED)
76 {
77 TRACE("The Window is in DESTROY!\n");
78 continue;
79 }
80
81 if ((pWnd->style & WS_VISIBLE) &&
83 IntPtInWindow(pWnd, x, y))
84 return pWnd;
85 }
86
87 /* Window has not been found */
88 return pwndDesktop;
89}
90
94 PCURICON_OBJECT NewCursor,
95 BOOL ForceChange)
96{
97 PCURICON_OBJECT OldCursor;
98 HDC hdcScreen;
99 PTHREADINFO pti;
100 PUSER_MESSAGE_QUEUE MessageQueue;
101 PWND pWnd;
102
104 MessageQueue = pti->MessageQueue;
105
106 OldCursor = MessageQueue->CursorObject;
107
108 /* Check if cursors are different */
109 if (OldCursor == NewCursor)
110 return OldCursor;
111
112 /* Update cursor for this message queue */
113 MessageQueue->CursorObject = NewCursor;
114
115 /* If cursor is not visible we have nothing to do */
116 if (MessageQueue->iCursorLevel < 0)
117 return OldCursor;
118
119 // Fixes the error message "Not the same cursor!".
120 if (gpqCursor == NULL)
121 {
122 gpqCursor = MessageQueue;
123 }
124
125 /* Update cursor if this message queue controls it */
126 pWnd = IntTopLevelWindowFromPoint(gpsi->ptCursor.x, gpsi->ptCursor.y);
127 if (pWnd && pWnd->head.pti->MessageQueue == MessageQueue)
128 {
129 /* Get the screen DC */
130 if (!(hdcScreen = IntGetScreenDC()))
131 {
132 return NULL;
133 }
134
135 if (NewCursor)
136 {
137 /* Call GDI to set the new screen cursor */
138 PCURICON_OBJECT CursorFrame = NewCursor;
139 if(NewCursor->CURSORF_flags & CURSORF_ACON)
140 {
141 FIXME("Should animate the cursor, using only the first frame now.\n");
142 CursorFrame = ((PACON)NewCursor)->aspcur[0];
143 }
144 GreSetPointerShape(hdcScreen,
145 CursorFrame->hbmAlpha ? NULL : NewCursor->hbmMask,
146 CursorFrame->hbmAlpha ? NewCursor->hbmAlpha : NewCursor->hbmColor,
147 CursorFrame->xHotspot,
148 CursorFrame->yHotspot,
149 gpsi->ptCursor.x,
150 gpsi->ptCursor.y,
151 CursorFrame->hbmAlpha ? SPS_ALPHA : 0);
152 }
153 else /* Note: OldCursor != NewCursor so we have to hide cursor */
154 {
155 /* Remove the cursor */
156 GreMovePointer(hdcScreen, -1, -1);
157 TRACE("Removing pointer!\n");
158 }
160 }
161
162 /* Return the old cursor */
163 return OldCursor;
164}
165
166/* Called from NtUserCallOneParam with Routine ONEPARAM_ROUTINE_SHOWCURSOR
167 * User32 macro NtUserShowCursor */
169{
170 HDC hdcScreen;
171 PTHREADINFO pti;
172 PUSER_MESSAGE_QUEUE MessageQueue;
173 PWND pWnd;
174
175 if (!(hdcScreen = IntGetScreenDC()))
176 {
177 return -1; /* No mouse */
178 }
179
181 MessageQueue = pti->MessageQueue;
182
183 /* Update counter */
184 MessageQueue->iCursorLevel += bShow ? 1 : -1;
185 pti->iCursorLevel += bShow ? 1 : -1;
186
187 /* Check for trivial cases */
188 if ((bShow && MessageQueue->iCursorLevel != 0) ||
189 (!bShow && MessageQueue->iCursorLevel != -1))
190 {
191 /* Note: w don't update global info here because it is used only
192 internally to check if cursor is visible */
193 return MessageQueue->iCursorLevel;
194 }
195
196 /* Check if cursor is above window owned by this MessageQueue */
197 pWnd = IntTopLevelWindowFromPoint(gpsi->ptCursor.x, gpsi->ptCursor.y);
198 if (pWnd && pWnd->head.pti->MessageQueue == MessageQueue)
199 {
200 if (bShow)
201 {
202 /* Show the pointer */
203 GreMovePointer(hdcScreen, gpsi->ptCursor.x, gpsi->ptCursor.y);
204 TRACE("Showing pointer!\n");
205 }
206 else
207 {
208 /* Remove the pointer */
209 GreMovePointer(hdcScreen, -1, -1);
210 TRACE("Removing pointer!\n");
211 }
212
213 /* Update global info */
215 }
216
217 return MessageQueue->iCursorLevel;
218}
219
222{
223 DWORD dwRet = 0;
224 PTHREADINFO pti;
225 PUSER_MESSAGE_QUEUE MessageQueue;
226
228 MessageQueue = pti->MessageQueue;
229
230 if (dwKey < 0x100)
231 {
232 if (IS_KEY_DOWN(MessageQueue->afKeyState, dwKey))
233 dwRet |= 0xFF80; // If down, windows returns 0xFF80.
234 if (IS_KEY_LOCKED(MessageQueue->afKeyState, dwKey))
235 dwRet |= 0x1;
236 }
237 else
238 {
240 }
241 return dwRet;
242}
243
244/* change the input key state for a given key */
245static VOID
246UpdateKeyState(PUSER_MESSAGE_QUEUE MessageQueue, WORD wVk, BOOL bIsDown)
247{
248 TRACE("UpdateKeyState wVk: %u, bIsDown: %d\n", wVk, bIsDown);
249
250 if (bIsDown)
251 {
252 /* If it's first key down event, xor lock bit */
253 if (!IS_KEY_DOWN(MessageQueue->afKeyState, wVk))
254 SET_KEY_LOCKED(MessageQueue->afKeyState, wVk, !IS_KEY_LOCKED(MessageQueue->afKeyState, wVk));
255
256 SET_KEY_DOWN(MessageQueue->afKeyState, wVk, TRUE);
257 MessageQueue->afKeyRecentDown[wVk / 8] |= (1 << (wVk % 8));
258 }
259 else
260 SET_KEY_DOWN(MessageQueue->afKeyState, wVk, FALSE);
261}
262
263/* update the input key state for a keyboard message */
264static VOID
266{
267 UCHAR key;
268 BOOL down = FALSE;
269
270 TRACE("UpdateKeyStateFromMsg message:%u\n", msg->message);
271
272 switch (msg->message)
273 {
274 case WM_LBUTTONDOWN:
275 down = TRUE;
276 /* fall through */
277 case WM_LBUTTONUP:
278 UpdateKeyState(MessageQueue, VK_LBUTTON, down);
279 break;
280 case WM_MBUTTONDOWN:
281 down = TRUE;
282 /* fall through */
283 case WM_MBUTTONUP:
284 UpdateKeyState(MessageQueue, VK_MBUTTON, down);
285 break;
286 case WM_RBUTTONDOWN:
287 down = TRUE;
288 /* fall through */
289 case WM_RBUTTONUP:
290 UpdateKeyState(MessageQueue, VK_RBUTTON, down);
291 break;
292 case WM_XBUTTONDOWN:
293 down = TRUE;
294 /* fall through */
295 case WM_XBUTTONUP:
296 if (msg->wParam == XBUTTON1)
297 UpdateKeyState(MessageQueue, VK_XBUTTON1, down);
298 else if (msg->wParam == XBUTTON2)
299 UpdateKeyState(MessageQueue, VK_XBUTTON2, down);
300 break;
301 case WM_KEYDOWN:
302 case WM_SYSKEYDOWN:
303 down = TRUE;
304 /* fall through */
305 case WM_KEYUP:
306 case WM_SYSKEYUP:
307 key = (UCHAR)msg->wParam;
308 UpdateKeyState(MessageQueue, key, down);
309 switch(key)
310 {
311 case VK_LCONTROL:
312 case VK_RCONTROL:
313 down = IS_KEY_DOWN(MessageQueue->afKeyState, VK_LCONTROL) || IS_KEY_DOWN(MessageQueue->afKeyState, VK_RCONTROL);
314 UpdateKeyState(MessageQueue, VK_CONTROL, down);
315 break;
316 case VK_LMENU:
317 case VK_RMENU:
318 down = IS_KEY_DOWN(MessageQueue->afKeyState, VK_LMENU) || IS_KEY_DOWN(MessageQueue->afKeyState, VK_RMENU);
319 UpdateKeyState(MessageQueue, VK_MENU, down);
320 break;
321 case VK_LSHIFT:
322 case VK_RSHIFT:
323 down = IS_KEY_DOWN(MessageQueue->afKeyState, VK_LSHIFT) || IS_KEY_DOWN(MessageQueue->afKeyState, VK_RSHIFT);
324 UpdateKeyState(MessageQueue, VK_SHIFT, down);
325 break;
326 }
327 break;
328 }
329}
330
331/*
332 Get down key states from the queue of prior processed input message key states.
333
334 This fixes the left button dragging on the desktop and release sticking outline issue.
335 USB Tablet pointer seems to stick the most and leaves the box outline displayed.
336 */
339{
340 WPARAM ret = 0;
341
343 {
344 if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_RBUTTON)) ret |= MK_LBUTTON;
345 if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_LBUTTON)) ret |= MK_RBUTTON;
346 }
347 else
348 {
349 if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_LBUTTON)) ret |= MK_LBUTTON;
350 if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_RBUTTON)) ret |= MK_RBUTTON;
351 }
352
353 if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_MBUTTON)) ret |= MK_MBUTTON;
354 if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_SHIFT)) ret |= MK_SHIFT;
355 if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_CONTROL)) ret |= MK_CONTROL;
356 if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_XBUTTON1)) ret |= MK_XBUTTON1;
357 if (IS_KEY_DOWN(MessageQueue->afKeyState, VK_XBUTTON2)) ret |= MK_XBUTTON2;
358 return ret;
359}
360
363{
364 PTHREADINFO Win32Thread;
365 HANDLE MessageEventHandle;
366 DWORD dwFlags = HIWORD(WakeMask);
367
368 Win32Thread = PsGetCurrentThreadWin32Thread();
369 if (Win32Thread == NULL || Win32Thread->MessageQueue == NULL)
370 return 0;
371
372// Win32Thread->pEventQueueServer; IntMsqSetWakeMask returns Win32Thread->hEventQueueClient
373 MessageEventHandle = Win32Thread->hEventQueueClient;
374
375 if (Win32Thread->pcti)
376 {
377 if ( (Win32Thread->pcti->fsChangeBits & LOWORD(WakeMask)) ||
378 ( (dwFlags & MWMO_INPUTAVAILABLE) && (Win32Thread->pcti->fsWakeBits & LOWORD(WakeMask)) ) )
379 {
380 ERR("Chg 0x%x Wake 0x%x Mask 0x%x\n",Win32Thread->pcti->fsChangeBits, Win32Thread->pcti->fsWakeBits, WakeMask);
381 KeSetEvent(Win32Thread->pEventQueueServer, IO_NO_INCREMENT, FALSE); // Wake it up!
382 return MessageEventHandle;
383 }
384 }
385
386 IdlePing();
387
388 return MessageEventHandle;
389}
390
393{
394 PTHREADINFO Win32Thread;
395
396 Win32Thread = PsGetCurrentThreadWin32Thread();
397 if (Win32Thread == NULL || Win32Thread->MessageQueue == NULL)
398 return FALSE;
399 // Very hacky, but that is what they do.
400 Win32Thread->pcti->fsWakeBits = 0;
401
402 IdlePong();
403
404 return TRUE;
405}
406
407/*
408 Due to the uncertainty of knowing what was set in our multilevel message queue,
409 and even if the bits are all cleared. The same as cTimers/cPaintsReady.
410 I think this is the best solution... (jt) */
412MsqWakeQueue(PTHREADINFO pti, DWORD MessageBits, BOOL KeyEvent)
413{
415
416 Queue = pti->MessageQueue;
417
418 if (Queue->QF_flags & QF_INDESTROY)
419 {
420 ERR("This Message Queue is in Destroy!\n");
421 }
422 pti->pcti->fsWakeBits |= MessageBits;
423 pti->pcti->fsChangeBits |= MessageBits;
424
425 // Start bit accounting to help clear the main set of bits.
426 if (MessageBits & QS_KEY)
427 {
428 pti->nCntsQBits[QSRosKey]++;
429 }
430 if (MessageBits & QS_MOUSE)
431 {
432 if (MessageBits & QS_MOUSEMOVE) pti->nCntsQBits[QSRosMouseMove]++;
433 if (MessageBits & QS_MOUSEBUTTON) pti->nCntsQBits[QSRosMouseButton]++;
434 }
435 if (MessageBits & QS_POSTMESSAGE) pti->nCntsQBits[QSRosPostMessage]++;
436 if (MessageBits & QS_SENDMESSAGE) pti->nCntsQBits[QSRosSendMessage]++;
437 if (MessageBits & QS_HOTKEY) pti->nCntsQBits[QSRosHotKey]++;
438 if (MessageBits & QS_EVENT) pti->nCntsQBits[QSRosEvent]++;
439
440 if (KeyEvent)
442}
443
446{
447 UINT ClrMask = 0;
448
449 if (MessageBits & QS_KEY)
450 {
451 if (--pti->nCntsQBits[QSRosKey] == 0) ClrMask |= QS_KEY;
452 }
453 if (MessageBits & QS_MOUSEMOVE)
454 { // Account for tracking mouse moves..
455 if (pti->nCntsQBits[QSRosMouseMove])
456 {
457 pti->nCntsQBits[QSRosMouseMove] = 0; // Throttle down count. Up to > 3:1 entries are ignored.
458 ClrMask |= QS_MOUSEMOVE;
459 }
460 }
461 if (MessageBits & QS_MOUSEBUTTON)
462 {
463 if (--pti->nCntsQBits[QSRosMouseButton] == 0) ClrMask |= QS_MOUSEBUTTON;
464 }
465 if (MessageBits & QS_POSTMESSAGE)
466 {
467 if (--pti->nCntsQBits[QSRosPostMessage] == 0) ClrMask |= QS_POSTMESSAGE;
468 }
469 if (MessageBits & QS_TIMER) // ReactOS hard coded.
470 { // Handle timer bits here.
471 if ( pti->cTimersReady )
472 {
473 if (--pti->cTimersReady == 0) ClrMask |= QS_TIMER;
474 }
475 }
476 if (MessageBits & QS_PAINT) // ReactOS hard coded.
477 { // Handle paint bits here.
478 if ( pti->cPaintsReady )
479 {
480 if (--pti->cPaintsReady == 0) ClrMask |= QS_PAINT;
481 }
482 }
483 if (MessageBits & QS_SENDMESSAGE)
484 {
485 if (--pti->nCntsQBits[QSRosSendMessage] == 0) ClrMask |= QS_SENDMESSAGE;
486 }
487 if (MessageBits & QS_HOTKEY)
488 {
489 if (--pti->nCntsQBits[QSRosHotKey] == 0) ClrMask |= QS_HOTKEY;
490 }
491 if (MessageBits & QS_EVENT)
492 {
493 if (--pti->nCntsQBits[QSRosEvent] == 0) ClrMask |= QS_EVENT;
494 }
495
496 pti->pcti->fsWakeBits &= ~ClrMask;
497 pti->pcti->fsChangeBits &= ~ClrMask;
498}
499
502{
503 pti->cPaintsReady++;
505}
506
509{
511}
512
513/*
514 Post the move or update the message still pending to be processed.
515 Do not overload the queue with mouse move messages.
516 */
519{
521 PLIST_ENTRY ListHead;
522 PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue;
523
524 ListHead = &MessageQueue->HardwareMessagesListHead;
525
526 // Do nothing if empty.
527 if (!IsListEmpty(ListHead->Flink))
528 {
529 // Look at the end of the list,
530 Message = CONTAINING_RECORD(ListHead->Blink, USER_MESSAGE, ListEntry);
531
532 // If the mouse move message is existing on the list,
533 if (Message->Msg.message == WM_MOUSEMOVE)
534 {
535 // Overwrite the message with updated data!
536 Message->Msg = *Msg;
537
539 return;
540 }
541 }
542
543 MsqPostMessage(pti, Msg, TRUE, QS_MOUSEMOVE, 0, ExtraInfo);
544}
545
546/*
547 Bring together the mouse move message.
548 Named "Coalesce" from Amine email ;^) (jt).
549 */
552{
553 MSG Msg;
554
555 // Force time stamp to update, keeping message time in sync.
556 if (gdwMouseMoveTimeStamp == 0)
557 {
559 }
560
561 // Build mouse move message.
562 Msg.hwnd = NULL;
563 Msg.message = WM_MOUSEMOVE;
564 Msg.wParam = 0;
565 Msg.lParam = MAKELONG(gpsi->ptCursor.x, gpsi->ptCursor.y);
567 Msg.pt = gpsi->ptCursor;
568
569 // Post the move.
571
572 // Zero the time stamp.
574
575 // Clear flag since the move was posted.
576 pti->MessageQueue->QF_flags &= ~QF_MOUSEMOVED;
577}
578
581{
582 MSLLHOOKSTRUCT MouseHookData;
583// PDESKTOP pDesk;
584 PWND pwnd, pwndDesktop;
585 HDC hdcScreen;
586 PTHREADINFO pti;
587 PUSER_MESSAGE_QUEUE MessageQueue;
588 PSYSTEM_CURSORINFO CurInfo;
589
590 Msg->time = EngGetTickCount32();
591
592 MouseHookData.pt.x = LOWORD(Msg->lParam);
593 MouseHookData.pt.y = HIWORD(Msg->lParam);
594 switch (Msg->message)
595 {
596 case WM_MOUSEWHEEL:
597 MouseHookData.mouseData = MAKELONG(0, GET_WHEEL_DELTA_WPARAM(Msg->wParam));
598 break;
599 case WM_XBUTTONDOWN:
600 case WM_XBUTTONUP:
601 case WM_XBUTTONDBLCLK:
602 case WM_NCXBUTTONDOWN:
603 case WM_NCXBUTTONUP:
604 case WM_NCXBUTTONDBLCLK:
605 MouseHookData.mouseData = MAKELONG(0, HIWORD(Msg->wParam));
606 break;
607 default:
608 MouseHookData.mouseData = 0;
609 break;
610 }
611
612 MouseHookData.flags = flags; // LLMHF_INJECTED
613 MouseHookData.time = Msg->time;
614 MouseHookData.dwExtraInfo = dwExtraInfo;
615
616 /* If the hook procedure returned non zero, dont send the message */
617 if (Hook)
618 {
619 if (co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION, Msg->message, (LPARAM) &MouseHookData))
620 return;
621 }
622
623 /* Get the desktop window */
624 pwndDesktop = UserGetDesktopWindow();
625 if (!pwndDesktop) return;
626// pDesk = pwndDesktop->head.rpdesk;
627
628 /* Check if the mouse is captured */
629 Msg->hwnd = IntGetCaptureWindow();
630 if (Msg->hwnd != NULL)
631 {
632 pwnd = UserGetWindowObject(Msg->hwnd);
633 }
634 else
635 {
636 pwnd = IntTopLevelWindowFromPoint(Msg->pt.x, Msg->pt.y);
637 if (pwnd) Msg->hwnd = pwnd->head.h;
638 }
639
640 hdcScreen = IntGetScreenDC();
641 CurInfo = IntGetSysCursorInfo();
642
643 /* Check if we found a window */
644 if (Msg->hwnd != NULL && pwnd != NULL)
645 {
646 pti = pwnd->head.pti;
647 MessageQueue = pti->MessageQueue;
648
649 if (MessageQueue->QF_flags & QF_INDESTROY)
650 {
651 ERR("Mouse is over a Window with a Dead Message Queue!\n");
652 return;
653 }
654
655 // Check to see if this is attached.
656 if ( pti != MessageQueue->ptiMouse &&
657 MessageQueue->cThreads > 1 )
658 {
659 // Set the send pti to the message queue mouse pti.
660 pti = MessageQueue->ptiMouse;
661 }
662
663 if (Msg->message == WM_MOUSEMOVE)
664 {
665 /* Check if cursor should be visible */
666 if(hdcScreen &&
667 MessageQueue->CursorObject &&
668 MessageQueue->iCursorLevel >= 0)
669 {
670 /* Check if shape has changed */
671 if(CurInfo->CurrentCursorObject != MessageQueue->CursorObject)
672 {
673 /* Call GDI to set the new screen cursor */
674 GreSetPointerShape(hdcScreen,
675 MessageQueue->CursorObject->hbmAlpha ?
676 NULL : MessageQueue->CursorObject->hbmMask,
677 MessageQueue->CursorObject->hbmAlpha ?
678 MessageQueue->CursorObject->hbmAlpha : MessageQueue->CursorObject->hbmColor,
679 MessageQueue->CursorObject->xHotspot,
680 MessageQueue->CursorObject->yHotspot,
681 gpsi->ptCursor.x,
682 gpsi->ptCursor.y,
683 MessageQueue->CursorObject->hbmAlpha ? SPS_ALPHA : 0);
684
685 } else
686 GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y);
687 }
688 /* Check if we have to hide cursor */
689 else if (CurInfo->ShowingCursor >= 0)
690 GreMovePointer(hdcScreen, -1, -1);
691
692 /* Update global cursor info */
693 CurInfo->ShowingCursor = MessageQueue->iCursorLevel;
694 CurInfo->CurrentCursorObject = MessageQueue->CursorObject;
695 gpqCursor = MessageQueue;
696
697 /* Mouse move is a special case */
698 MessageQueue->QF_flags |= QF_MOUSEMOVED;
699 gdwMouseMoveExtraInfo = dwExtraInfo;
702 }
703 else
704 {
705 if (!IntGetCaptureWindow())
706 {
707 // ERR("ptiLastInput is set\n");
708 // ptiLastInput = pti; // Once this is set during Reboot or Shutdown, this prevents the exit window having foreground.
709 // Find all the Move Mouse calls and fix mouse set active focus issues......
710 }
711
712 // Post mouse move before posting mouse buttons, keep it in sync.
713 if (pti->MessageQueue->QF_flags & QF_MOUSEMOVED)
714 {
716 }
717
718 TRACE("Posting mouse message to hwnd=%p!\n", UserHMGetHandle(pwnd));
719 MsqPostMessage(pti, Msg, TRUE, QS_MOUSEBUTTON, 0, dwExtraInfo);
720 }
721 }
722 else if (hdcScreen)
723 {
724 /* always show cursor on background; FIXME: set default pointer */
725 GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y);
726 CurInfo->ShowingCursor = 0;
727 }
728}
729
732{
734
735 Message = ExAllocateFromPagedLookasideList(pgMessageLookasideList);
736 if (!Message)
737 {
738 return NULL;
739 }
740
741 RtlZeroMemory(Message, sizeof(*Message));
742 RtlMoveMemory(&Message->Msg, Msg, sizeof(MSG));
743 PostMsgCount++;
744 return Message;
745}
746
749{
750 TRACE("Post Destroy %d\n",PostMsgCount);
751 if (Message->pti == NULL)
752 {
753 ERR("Double Free Message\n");
754 return;
755 }
756 RemoveEntryList(&Message->ListEntry);
757 Message->pti = NULL;
758 ExFreeToPagedLookasideList(pgMessageLookasideList, Message);
759 PostMsgCount--;
760}
761
764{
766
767 if(!(Message = ExAllocateFromPagedLookasideList(pgSendMsgLookasideList)))
768 {
769 ERR("AllocateUserMessage(): Not enough memory to allocate a message\n");
770 return NULL;
771 }
773
774 if (KEvent)
775 {
776 Message->pkCompletionEvent = &Message->CompletionEvent;
777
778 KeInitializeEvent(Message->pkCompletionEvent, NotificationEvent, FALSE);
779 }
780 SendMsgCount++;
781 TRACE("AUM pti %p msg %p\n",PsGetCurrentThreadWin32Thread(),Message);
782 return Message;
783}
784
787{
788 Message->pkCompletionEvent = NULL;
789
790 /* Remove it from the list */
791 RemoveEntryList(&Message->ListEntry);
792
793 ExFreeToPagedLookasideList(pgSendMsgLookasideList, Message);
794 SendMsgCount--;
795}
796
799{
800 PTHREADINFO pti;
801 PUSER_SENT_MESSAGE SentMessage;
802 PUSER_MESSAGE PostedMessage;
803 PLIST_ENTRY CurrentEntry, ListHead;
804
805 ASSERT(Window);
806
807 pti = Window->head.pti;
808
809 /* remove the posted messages for this window */
810 CurrentEntry = pti->PostedMessagesListHead.Flink;
811 ListHead = &pti->PostedMessagesListHead;
812 while (CurrentEntry != ListHead)
813 {
814 PostedMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
815
816 if (PostedMessage->Msg.hwnd == Window->head.h)
817 {
818 if (PostedMessage->Msg.message == WM_QUIT && pti->QuitPosted == 0)
819 {
820 pti->QuitPosted = 1;
821 pti->exitCode = PostedMessage->Msg.wParam;
822 }
823 ClearMsgBitsMask(pti, PostedMessage->QS_Flags);
824 MsqDestroyMessage(PostedMessage);
825 CurrentEntry = pti->PostedMessagesListHead.Flink;
826 }
827 else
828 {
829 CurrentEntry = CurrentEntry->Flink;
830 }
831 }
832
833 /* remove the sent messages for this window */
834 CurrentEntry = pti->SentMessagesListHead.Flink;
835 ListHead = &pti->SentMessagesListHead;
836 while (CurrentEntry != ListHead)
837 {
838 SentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry);
839
840 if(SentMessage->Msg.hwnd == Window->head.h)
841 {
842 ERR("Remove Window Messages %p From Sent Queue\n",SentMessage);
843#if 0 // Should mark these as invalid and allow the rest clean up, so far no harm by just commenting out. See CORE-9210.
844 ClearMsgBitsMask(pti, SentMessage->QS_Flags);
845
846 /* wake the sender's thread */
847 if (SentMessage->pkCompletionEvent != NULL)
848 {
850 }
851
852 if (SentMessage->HasPackedLParam)
853 {
854 if (SentMessage->Msg.lParam)
855 ExFreePool((PVOID)SentMessage->Msg.lParam);
856 }
857
858 /* free the message */
859 FreeUserMessage(SentMessage);
860
861 CurrentEntry = pti->SentMessagesListHead.Flink;
862#endif
863 CurrentEntry = CurrentEntry->Flink;
864 }
865 else
866 {
867 CurrentEntry = CurrentEntry->Flink;
868 }
869 }
870}
871
874 _In_ PTHREADINFO pti)
875{
878 BOOL Ret;
879 LRESULT Result = 0;
880
882
883 if (IsListEmpty(&pti->SentMessagesListHead))
884 {
885 return(FALSE);
886 }
887
888 /* remove it from the list of pending messages */
889 Entry = RemoveHeadList(&pti->SentMessagesListHead);
891
892 // Signal this message is being processed.
894
895 SaveMsg = pti->pusmCurrent;
896 pti->pusmCurrent = Message;
897
898 // Processing a message sent to it from another thread.
899 if ( ( Message->ptiSender && pti != Message->ptiSender) ||
900 ( Message->ptiCallBackSender && pti != Message->ptiCallBackSender ))
901 { // most likely, but, to be sure.
902 pti->pcti->CTI_flags |= CTI_INSENDMESSAGE; // Let the user know...
903 }
904
905 /* Now insert it to the global list of messages that can be removed Justin Case there's Trouble */
906 InsertTailList(&usmList, &Message->ListEntry);
907
908 ClearMsgBitsMask(pti, Message->QS_Flags);
909
910 if (Message->HookMessage == MSQ_ISHOOK)
911 { // Direct Hook Call processor
912 Result = co_CallHook( Message->Msg.message, // HookId
913 (INT)(INT_PTR)Message->Msg.hwnd, // Code
914 Message->Msg.wParam,
915 Message->Msg.lParam);
916 }
917 else if(Message->HookMessage == MSQ_INJECTMODULE)
918 {
919 Result = IntLoadHookModule(Message->Msg.message,
920 (HHOOK)Message->Msg.lParam,
921 Message->Msg.wParam);
922 }
923 else if ((Message->CompletionCallback) &&
924 (Message->ptiCallBackSender == pti))
925 { /* Call the callback routine */
926 if (Message->QS_Flags & QS_SMRESULT)
927 {
928 co_IntCallSentMessageCallback(Message->CompletionCallback,
929 Message->Msg.hwnd,
930 Message->Msg.message,
931 Message->CompletionCallbackContext,
932 Message->lResult);
933 /* Set callback to NULL to prevent reentry */
934 Message->CompletionCallback = NULL;
935 }
936 else
937 {
938 /* The message has not been processed yet, reinsert it. */
939 RemoveEntryList(&Message->ListEntry);
940 InsertTailList(&Message->ptiCallBackSender->SentMessagesListHead, &Message->ListEntry);
941 // List is occupied need to set the bit.
942 MsqWakeQueue(Message->ptiCallBackSender, QS_SENDMESSAGE, TRUE);
943 ERR("Callback Message not processed yet. Requeuing the message\n");
944 Ret = FALSE;
945 goto Exit;
946 }
947 }
948 else
949 { /* Call the window procedure. */
950 Result = co_IntSendMessage( Message->Msg.hwnd,
951 Message->Msg.message,
952 Message->Msg.wParam,
953 Message->Msg.lParam);
954 }
955
956 /* If the message is a callback, insert it in the callback senders MessageQueue */
957 if (Message->CompletionCallback)
958 {
959 if (Message->ptiCallBackSender)
960 {
961 Message->lResult = Result;
962 Message->QS_Flags |= QS_SMRESULT;
963
964 /* insert it in the callers message queue */
965 RemoveEntryList(&Message->ListEntry);
966 InsertTailList(&Message->ptiCallBackSender->SentMessagesListHead, &Message->ListEntry);
967 MsqWakeQueue(Message->ptiCallBackSender, QS_SENDMESSAGE, TRUE);
968 }
969 Ret = TRUE;
970 goto Exit;
971 }
972
973 // Retrieve the result from callback.
974 if (Message->QS_Flags & QS_SMRESULT)
975 {
976 Result = Message->lResult;
977 }
978
979 /* Let the sender know the result. */
980 Message->lResult = Result;
981
982 if (Message->HasPackedLParam)
983 {
984 if (Message->Msg.lParam)
985 ExFreePool((PVOID)Message->Msg.lParam);
986 }
987
988 // Clear busy signal.
989 Message->flags &= ~SMF_RECEIVERBUSY;
990
991 /* Notify the sender. */
992 if (Message->pkCompletionEvent != NULL)
993 {
994 KeSetEvent(Message->pkCompletionEvent, IO_NO_INCREMENT, FALSE);
995 }
996
997 /* free the message */
998 if (Message->flags & SMF_RECEIVERFREE)
999 {
1000 TRACE("Receiver Freeing Message %p\n",Message);
1002 }
1003
1004 Ret = TRUE;
1005Exit:
1006 /* do not hangup on the user if this is reentering */
1007 if (!SaveMsg) pti->pcti->CTI_flags &= ~CTI_INSENDMESSAGE;
1008 pti->pusmCurrent = SaveMsg;
1009
1010 return Ret;
1011}
1012
1015 HWND hwnd,
1016 UINT Msg,
1017 WPARAM wParam,
1018 LPARAM lParam,
1020 ULONG_PTR CompletionCallbackContext,
1021 BOOL HasPackedLParam,
1022 INT HookMessage)
1023{
1024 PTHREADINFO ptiSender;
1026
1028 {
1029 ERR("MsqSendMessageAsync(): Not enough memory to allocate a message\n");
1030 return FALSE;
1031 }
1032
1033 ptiSender = PsGetCurrentThreadWin32Thread();
1034
1035 Message->Msg.hwnd = hwnd;
1036 Message->Msg.message = Msg;
1037 Message->Msg.wParam = wParam;
1038 Message->Msg.lParam = lParam;
1039 Message->pkCompletionEvent = NULL; // No event needed.
1040 Message->ptiReceiver = ptiReceiver;
1041 Message->ptiCallBackSender = ptiSender;
1042 Message->CompletionCallback = CompletionCallback;
1043 Message->CompletionCallbackContext = CompletionCallbackContext;
1044 Message->HookMessage = HookMessage;
1045 Message->HasPackedLParam = HasPackedLParam;
1046 Message->QS_Flags = QS_SENDMESSAGE;
1047 Message->flags = SMF_RECEIVERFREE;
1048
1049 InsertTailList(&ptiReceiver->SentMessagesListHead, &Message->ListEntry);
1050 MsqWakeQueue(ptiReceiver, QS_SENDMESSAGE, TRUE);
1051
1052 return TRUE;
1053}
1054
1057 HWND Wnd,
1058 UINT Msg,
1059 WPARAM wParam,
1060 LPARAM lParam,
1061 UINT uTimeout,
1062 BOOL Block,
1063 INT HookMessage,
1064 ULONG_PTR *uResult)
1065{
1066 PTHREADINFO pti;
1067 PUSER_SENT_MESSAGE SaveMsg, Message;
1068 NTSTATUS WaitStatus;
1071 PWND pWnd;
1072 BOOLEAN SwapStateEnabled;
1073 LRESULT Result = 0;
1074
1076 ASSERT(pti != ptirec);
1077 ASSERT(ptirec->pcti); // Send must have a client side to receive it!!!!
1078
1079 /* Don't send from or to a dying thread */
1080 if (pti->TIF_flags & TIF_INCLEANUP || ptirec->TIF_flags & TIF_INCLEANUP)
1081 {
1082 // Unless we are dying and need to tell our parents.
1083 if (pti->TIF_flags & TIF_INCLEANUP && !(ptirec->TIF_flags & TIF_INCLEANUP))
1084 {
1085 // Parent notify is the big one. Fire and forget!
1086 TRACE("Send message from dying thread %u\n", Msg);
1087 co_MsqSendMessageAsync(ptirec, Wnd, Msg, wParam, lParam, NULL, 0, FALSE, HookMessage);
1088 }
1089 if (uResult) *uResult = -1;
1090 TRACE("MsqSM: Msg %u Current pti %lu or Rec pti %lu\n", Msg, pti->TIF_flags & TIF_INCLEANUP, ptirec->TIF_flags & TIF_INCLEANUP);
1091 return STATUS_UNSUCCESSFUL;
1092 }
1093
1094 if (IsThreadSuspended(ptirec))
1095 {
1096 ERR("Sending to Suspended Thread Msg %lx\n",Msg);
1097 if (uResult) *uResult = -1;
1098 return STATUS_UNSUCCESSFUL;
1099 }
1100
1101 // Should we do the same for No Wait?
1102 if ( HookMessage == MSQ_NORMAL )
1103 {
1104 pWnd = ValidateHwndNoErr(Wnd);
1105
1106 // These can not cross International Border lines!
1107 if ( pti->ppi != ptirec->ppi && pWnd )
1108 {
1109 switch(Msg)
1110 {
1111 // Handle the special case when working with password transfers across bordering processes.
1112 case EM_GETLINE:
1113 case EM_SETPASSWORDCHAR:
1114 case WM_GETTEXT:
1115 // Look for edit controls setup for passwords.
1116 if ( gpsi->atomSysClass[ICLS_EDIT] == pWnd->pcls->atomClassName && // Use atomNVClassName.
1117 pWnd->style & ES_PASSWORD )
1118 {
1119 if (uResult) *uResult = -1;
1120 ERR("Running across the border without a passport!\n");
1122 return STATUS_UNSUCCESSFUL;
1123 }
1124 break;
1125 case WM_NOTIFY:
1126 if (uResult) *uResult = -1;
1127 ERR("Running across the border without a passport!\n");
1128 return STATUS_UNSUCCESSFUL;
1129 }
1130 }
1131
1132 // These can not cross State lines!
1133 if ( Msg == WM_CREATE || Msg == WM_NCCREATE )
1134 {
1135 if (uResult) *uResult = -1;
1136 ERR("Can not tell the other State we have Create!\n");
1137 return STATUS_UNSUCCESSFUL;
1138 }
1139 }
1140
1142 {
1143 ERR("MsqSendMessage(): Not enough memory to allocate a message\n");
1144 if (uResult) *uResult = -1;
1146 }
1147
1148 Timeout.QuadPart = Int32x32To64(-10000,uTimeout); // Pass SMTO test with a TO of 0x80000000.
1149 TRACE("Timeout val %lld\n",Timeout.QuadPart);
1150
1151 Message->Msg.hwnd = Wnd;
1152 Message->Msg.message = Msg;
1153 Message->Msg.wParam = wParam;
1154 Message->Msg.lParam = lParam;
1155 Message->ptiReceiver = ptirec;
1156 Message->ptiSender = pti;
1157 Message->HookMessage = HookMessage;
1158 Message->QS_Flags = QS_SENDMESSAGE;
1159
1160 SaveMsg = pti->pusmSent;
1161 pti->pusmSent = Message;
1162
1163 /* Queue it in the destination's message queue */
1164 InsertTailList(&ptirec->SentMessagesListHead, &Message->ListEntry);
1165
1167
1168 // First time in, turn off swapping of the stack.
1169 if (pti->cEnterCount == 0)
1170 {
1171 SwapStateEnabled = KeSetKernelStackSwapEnable(FALSE);
1172 }
1173 pti->cEnterCount++;
1174
1175 if (Block)
1176 {
1177 PVOID WaitObjects[2];
1178
1179 WaitObjects[0] = Message->pkCompletionEvent; // Wait 0
1180 WaitObjects[1] = ptirec->pEThread; // Wait 1
1181
1182 UserLeaveCo();
1183
1184 WaitStatus = KeWaitForMultipleObjects( 2,
1185 WaitObjects,
1186 WaitAny,
1188 UserMode,
1189 FALSE,
1190 (uTimeout ? &Timeout : NULL),
1191 NULL );
1192
1193 UserEnterCo();
1194
1195 if (WaitStatus == STATUS_TIMEOUT)
1196 {
1197 /* Look up if the message has not yet dispatched, if so
1198 make sure it can't pass a result and it must not set the completion event anymore */
1200 while (Entry != &ptirec->SentMessagesListHead)
1201 {
1203 {
1204 Message->pkCompletionEvent = NULL;
1205 RemoveEntryList(&Message->ListEntry);
1206 ClearMsgBitsMask(ptirec, Message->QS_Flags);
1207 InsertTailList(&usmList, &Message->ListEntry);
1208 break;
1209 }
1210 Entry = Entry->Flink;
1211 }
1212
1213 ERR("MsqSendMessage (blocked) timed out 1 Status %lx\n", WaitStatus);
1214 }
1215 // Receiving thread passed on and left us hanging with issues still pending.
1216 else if (WaitStatus == STATUS_WAIT_1)
1217 {
1218 ERR("Bk Receiving Thread woken up dead!\n");
1219 Message->flags |= SMF_RECEIVERDIED;
1220 }
1221
1222 while (co_MsqDispatchOneSentMessage(pti))
1223 ;
1224 }
1225 else
1226 {
1227 PVOID WaitObjects[3];
1228
1229 WaitObjects[0] = Message->pkCompletionEvent; // Wait 0
1230 WaitObjects[1] = pti->pEventQueueServer; // Wait 1
1231 WaitObjects[2] = ptirec->pEThread; // Wait 2
1232
1233 do
1234 {
1235 UserLeaveCo();
1236
1237 WaitStatus = KeWaitForMultipleObjects( 3,
1238 WaitObjects,
1239 WaitAny,
1241 UserMode,
1242 FALSE,
1243 (uTimeout ? &Timeout : NULL),
1244 NULL);
1245
1246 UserEnterCo();
1247
1248 if (WaitStatus == STATUS_TIMEOUT)
1249 {
1250 /* Look up if the message has not yet been dispatched, if so
1251 make sure it can't pass a result and it must not set the completion event anymore */
1253 while (Entry != &ptirec->SentMessagesListHead)
1254 {
1256 {
1257 Message->pkCompletionEvent = NULL;
1258 RemoveEntryList(&Message->ListEntry);
1259 ClearMsgBitsMask(ptirec, Message->QS_Flags);
1260 InsertTailList(&usmList, &Message->ListEntry);
1261 break;
1262 }
1263 Entry = Entry->Flink;
1264 }
1265
1266 ERR("MsqSendMessage timed out 2 Status %lx\n", WaitStatus);
1267 break;
1268 }
1269 // Receiving thread passed on and left us hanging with issues still pending.
1270 else if (WaitStatus == STATUS_WAIT_2)
1271 {
1272 ERR("NB Receiving Thread woken up dead!\n");
1273 Message->flags |= SMF_RECEIVERDIED;
1274 break;
1275 }
1276
1277 if (WaitStatus == STATUS_USER_APC) break;
1278
1279 while (co_MsqDispatchOneSentMessage(pti))
1280 ;
1281 } while (WaitStatus == STATUS_WAIT_1);
1282 }
1283
1284 // Count is nil, restore swapping of the stack.
1285 if (--pti->cEnterCount == 0 )
1286 {
1287 KeSetKernelStackSwapEnable(SwapStateEnabled);
1288 }
1289
1290 // Handle User APC
1291 if (WaitStatus == STATUS_USER_APC)
1292 {
1293 // The current thread is dying!
1294 TRACE("User APC\n");
1295
1296 // The Message will be on the Trouble list until Thread cleanup.
1297 Message->flags |= SMF_SENDERDIED;
1298
1300 ERR("User APC Returned\n"); // Should not see this message.
1301 }
1302
1303 // Force this thread to wake up for the next go around.
1305
1306 Result = Message->lResult;
1307
1308 // Determine whether this message is being processed or not.
1310 {
1311 Message->flags |= SMF_RECEIVERFREE;
1312 }
1313
1314 if (!(Message->flags & SMF_RECEIVERFREE))
1315 {
1316 TRACE("Sender Freeing Message %p ptirec %p bit %d list empty %d\n",Message,ptirec,!!(ptirec->pcti->fsChangeBits & QS_SENDMESSAGE),IsListEmpty(&ptirec->SentMessagesListHead));
1317 // Make it to this point, the message was received.
1319 }
1320
1321 pti->pusmSent = SaveMsg;
1322
1323 TRACE("MSM Allocation Count %d Status %lx Result %d\n",SendMsgCount,WaitStatus,Result);
1324
1325 if (WaitStatus != STATUS_TIMEOUT)
1326 {
1327 if (uResult)
1328 {
1329 *uResult = (STATUS_WAIT_0 == WaitStatus ? Result : 0);
1330 }
1331 }
1332
1333 return WaitStatus;
1334}
1335
1338 MSG* Msg,
1339 BOOLEAN HardwareMessage,
1340 DWORD MessageBits,
1341 DWORD dwQEvent,
1342 LONG_PTR ExtraInfo)
1343{
1345 PUSER_MESSAGE_QUEUE MessageQueue;
1346
1347 if ( pti->TIF_flags & TIF_INCLEANUP || pti->MessageQueue->QF_flags & QF_INDESTROY )
1348 {
1349 ERR("Post Msg; Thread or Q is Dead!\n");
1350 return;
1351 }
1352
1353 if(!(Message = MsqCreateMessage(Msg)))
1354 {
1355 return;
1356 }
1357
1358 MessageQueue = pti->MessageQueue;
1359
1360 if (!HardwareMessage)
1361 {
1362 InsertTailList(&pti->PostedMessagesListHead, &Message->ListEntry);
1363 }
1364 else
1365 {
1366 InsertTailList(&MessageQueue->HardwareMessagesListHead, &Message->ListEntry);
1367 }
1368
1369 if (Msg->message == WM_HOTKEY) MessageBits |= QS_HOTKEY; // Justin Case, just set it.
1370 Message->dwQEvent = dwQEvent;
1371 Message->ExtraInfo = ExtraInfo;
1372 Message->QS_Flags = MessageBits;
1373 Message->pti = pti;
1374 MsqWakeQueue(pti, MessageBits, TRUE);
1375 TRACE("Post Message %d\n",PostMsgCount);
1376}
1377
1380{
1381 pti->QuitPosted = TRUE;
1382 pti->exitCode = ExitCode;
1384}
1385
1386/***********************************************************************
1387 * MsqSendParentNotify
1388 *
1389 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
1390 * the window has the WS_EX_NOPARENTNOTIFY style.
1391 */
1392static void MsqSendParentNotify( PWND pwnd, WORD event, WORD idChild, POINT pt )
1393{
1394 PWND pwndDesktop = UserGetDesktopWindow();
1395
1396 /* pt has to be in the client coordinates of the parent window */
1397 pt.x += pwndDesktop->rcClient.left - pwnd->rcClient.left;
1398 pt.y += pwndDesktop->rcClient.top - pwnd->rcClient.top;
1399
1400 for (;;)
1401 {
1402 PWND pwndParent;
1403
1404 if (!(pwnd->style & WS_CHILD)) break;
1405 if (pwnd->ExStyle & WS_EX_NOPARENTNOTIFY) break;
1406 if (!(pwndParent = IntGetParent(pwnd))) break;
1407 if (pwndParent == pwndDesktop) break;
1408 pt.x += pwnd->rcClient.left - pwndParent->rcClient.left;
1409 pt.y += pwnd->rcClient.top - pwndParent->rcClient.top;
1410
1411 pwnd = pwndParent;
1413 MAKEWPARAM( event, idChild ), MAKELPARAM( pt.x, pt.y ) );
1414 }
1415}
1416
1417VOID
1419IntTrackMouseMove(PWND pwndTrack, PDESKTOP pDesk, PMSG msg, USHORT hittest)
1420{
1421// PWND pwndTrack = IntChildrenWindowFromPoint(pwndMsg, msg->pt.x, msg->pt.y);
1422// hittest = (USHORT)GetNCHitEx(pwndTrack, msg->pt); /// @todo WTF is this???
1423
1424 if ( pDesk->spwndTrack != pwndTrack || // Change with tracking window or
1425 msg->message != WM_MOUSEMOVE || // Mouse click changes or
1426 pDesk->htEx != hittest) // Change in current hit test states.
1427 {
1428 TRACE("ITMM: Track Mouse Move!\n");
1429
1430 /* Handle only the changing window track and mouse move across a border. */
1431 if ( pDesk->spwndTrack != pwndTrack ||
1432 (pDesk->htEx == HTCLIENT) ^ (hittest == HTCLIENT) )
1433 {
1434 TRACE("ITMM: Another Wnd %d or Across Border %d\n",
1435 pDesk->spwndTrack != pwndTrack,(pDesk->htEx == HTCLIENT) ^ (hittest == HTCLIENT));
1436
1437 if ( pDesk->dwDTFlags & DF_TME_LEAVE )
1440 0, 0);
1441
1442 if ( pDesk->dwDTFlags & DF_TME_HOVER )
1444
1445 /* Clear the flags to sign a change. */
1446 pDesk->dwDTFlags &= ~(DF_TME_LEAVE|DF_TME_HOVER);
1447 }
1448 /* Set the Track window and hit test. */
1449 pDesk->spwndTrack = pwndTrack;
1450 pDesk->htEx = hittest;
1451 }
1452
1453 /* Reset, Same Track window, Hover set and Mouse Clicks or Clobbered Hover box. */
1454 if ( pDesk->spwndTrack == pwndTrack &&
1455 ( msg->message != WM_MOUSEMOVE || !RECTL_bPointInRect(&pDesk->rcMouseHover, msg->pt.x, msg->pt.y)) &&
1456 pDesk->dwDTFlags & DF_TME_HOVER )
1457 {
1458 TRACE("ITMM: Reset Hover points!\n");
1459 // Restart timer for the hover period.
1461 // Reset desktop mouse hover from the system default hover rectangle.
1463 msg->pt.x - gspv.iMouseHoverWidth / 2,
1464 msg->pt.y - gspv.iMouseHoverHeight / 2,
1465 msg->pt.x + gspv.iMouseHoverWidth / 2,
1466 msg->pt.y + gspv.iMouseHoverHeight / 2);
1467 }
1468}
1469
1470BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, BOOL* NotForUs, LONG_PTR ExtraInfo, UINT first, UINT last)
1471{
1472 MSG clk_msg;
1473 POINT pt;
1474 UINT message;
1475 USHORT hittest;
1478 BOOL eatMsg = FALSE;
1479
1480 PWND pwndMsg, pwndDesktop;
1481 PUSER_MESSAGE_QUEUE MessageQueue;
1482 PTHREADINFO pti;
1483 PSYSTEM_CURSORINFO CurInfo;
1484 PDESKTOP pDesk;
1485
1487 pwndDesktop = UserGetDesktopWindow();
1488 MessageQueue = pti->MessageQueue;
1489 CurInfo = IntGetSysCursorInfo();
1490 pwndMsg = ValidateHwndNoErr(msg->hwnd);
1491 clk_msg = MessageQueue->msgDblClk;
1492 pDesk = pwndDesktop->head.rpdesk;
1493
1494 /* find the window to dispatch this mouse message to */
1495 if (MessageQueue->spwndCapture)
1496 {
1497 hittest = HTCLIENT;
1498 pwndMsg = MessageQueue->spwndCapture;
1499 }
1500 else
1501 {
1502 /*
1503 Start with null window. See wine win.c:test_mouse_input:WM_COMMAND tests.
1504 */
1505 pwndMsg = co_WinPosWindowFromPoint( NULL, &msg->pt, &hittest, FALSE);
1506 }
1507
1508 TRACE("Got mouse message for %p, hittest: 0x%x\n", msg->hwnd, hittest);
1509
1510 // Null window or not the same "Hardware" message queue.
1511 if (pwndMsg == NULL || pwndMsg->head.pti->MessageQueue != MessageQueue)
1512 {
1513 // Crossing a boundary, so set cursor. See default message queue cursor.
1515 /* Remove and ignore the message */
1516 *RemoveMessages = TRUE;
1517 return FALSE;
1518 }
1519
1520 // Check to see if this is attached,
1521 if ( pwndMsg->head.pti != pti && // window thread is not current,
1522 MessageQueue->cThreads > 1 ) // and is attached...
1523 {
1524 // This is not for us and we should leave so the other thread can check for messages!!!
1525 *NotForUs = TRUE;
1526 *RemoveMessages = FALSE;
1527 return FALSE;
1528 }
1529
1530 if ( MessageQueue == gpqCursor ) // Cursor must use the same Queue!
1531 {
1532 IntTrackMouseMove(pwndMsg, pDesk, msg, hittest);
1533 }
1534 else
1535 {
1536 ERR("Not the same cursor!\n");
1537 }
1538
1539 msg->hwnd = UserHMGetHandle(pwndMsg);
1540
1541 pt = msg->pt;
1542 message = msg->message;
1543
1544 /* Note: windows has no concept of a non-client wheel message */
1545 if (message != WM_MOUSEWHEEL)
1546 {
1547 if (hittest != HTCLIENT)
1548 {
1550 msg->wParam = hittest; // Caution! This might break wParam check in DblClk.
1551 }
1552 else
1553 {
1554 /* coordinates don't get translated while tracking a menu */
1555 /* FIXME: should differentiate popups and top-level menus */
1556 if (!(MessageQueue->MenuOwner))
1557 {
1558 pt.x += pwndDesktop->rcClient.left - pwndMsg->rcClient.left;
1559 pt.y += pwndDesktop->rcClient.top - pwndMsg->rcClient.top;
1560 }
1561 }
1562 }
1563 msg->lParam = MAKELONG( pt.x, pt.y );
1564
1565 /* translate double clicks */
1566
1567 if ((msg->message == WM_LBUTTONDOWN) ||
1568 (msg->message == WM_RBUTTONDOWN) ||
1569 (msg->message == WM_MBUTTONDOWN) ||
1570 (msg->message == WM_XBUTTONDOWN))
1571 {
1572 BOOL update = *RemoveMessages;
1573
1574 /* translate double clicks -
1575 * note that ...MOUSEMOVEs can slip in between
1576 * ...BUTTONDOWN and ...BUTTONDBLCLK messages */
1577
1578 if ((MessageQueue->MenuOwner || MessageQueue->MoveSize) ||
1579 hittest != HTCLIENT ||
1580 (pwndMsg->pcls->style & CS_DBLCLKS))
1581 {
1582 if ((msg->message == clk_msg.message) &&
1583 (msg->hwnd == clk_msg.hwnd) &&
1584 // Only worry about XButton wParam.
1585 (msg->message != WM_XBUTTONDOWN || GET_XBUTTON_WPARAM(msg->wParam) == GET_XBUTTON_WPARAM(clk_msg.wParam)) &&
1586 ((msg->time - clk_msg.time) < (ULONG)gspv.iDblClickTime) &&
1587 (abs(msg->pt.x - clk_msg.pt.x) < UserGetSystemMetrics(SM_CXDOUBLECLK)/2) &&
1588 (abs(msg->pt.y - clk_msg.pt.y) < UserGetSystemMetrics(SM_CYDOUBLECLK)/2))
1589 {
1591 if (update)
1592 {
1593 MessageQueue->msgDblClk.message = 0; /* clear the double click conditions */
1594 update = FALSE;
1595 }
1596 }
1597 }
1598
1599 if (!((first == 0 && last == 0) || (message >= first || message <= last)))
1600 {
1601 TRACE("Message out of range!!!\n");
1602 return FALSE;
1603 }
1604
1605 /* update static double click conditions */
1606 if (update) MessageQueue->msgDblClk = *msg;
1607 }
1608 else
1609 {
1610 if (!((first == 0 && last == 0) || (message >= first || message <= last)))
1611 {
1612 TRACE("Message out of range!!!\n");
1613 return FALSE;
1614 }
1615
1616 // Update mouse move down keys.
1617 if (message == WM_MOUSEMOVE)
1618 {
1619 msg->wParam = MsqGetDownKeyState(MessageQueue);
1620 }
1621 }
1622
1624 {
1625 BOOL IsClkLck = FALSE;
1626
1627 if(msg->message == WM_LBUTTONUP)
1628 {
1629 IsClkLck = ((msg->time - CurInfo->ClickLockTime) >= gspv.dwMouseClickLockTime);
1630 if (IsClkLck && (!CurInfo->ClickLockActive))
1631 {
1632 CurInfo->ClickLockActive = TRUE;
1633 }
1634 }
1635 else if (msg->message == WM_LBUTTONDOWN)
1636 {
1637 if (CurInfo->ClickLockActive)
1638 {
1639 IsClkLck = TRUE;
1640 CurInfo->ClickLockActive = FALSE;
1641 }
1642
1643 CurInfo->ClickLockTime = msg->time;
1644 }
1645
1646 if(IsClkLck)
1647 {
1648 /* Remove and ignore the message */
1649 *RemoveMessages = TRUE;
1650 TRACE("Remove and ignore the message\n");
1651 return FALSE;
1652 }
1653 }
1654
1655 if (pti->TIF_flags & TIF_MSGPOSCHANGED)
1656 {
1657 pti->TIF_flags &= ~TIF_MSGPOSCHANGED;
1658 IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
1659 }
1660
1661 /* message is accepted now (but still get dropped) */
1662
1663 event.message = msg->message;
1664 event.time = msg->time;
1665 event.hwnd = msg->hwnd;
1666 event.paramL = msg->pt.x;
1667 event.paramH = msg->pt.y;
1669
1670 hook.pt = msg->pt;
1671 hook.hwnd = msg->hwnd;
1672 hook.wHitTestCode = hittest;
1673 hook.dwExtraInfo = ExtraInfo;
1674 if (co_HOOK_CallHooks( WH_MOUSE, *RemoveMessages ? HC_ACTION : HC_NOREMOVE,
1675 message, (LPARAM)&hook ))
1676 {
1677 hook.pt = msg->pt;
1678 hook.hwnd = msg->hwnd;
1679 hook.wHitTestCode = hittest;
1680 hook.dwExtraInfo = ExtraInfo;
1682
1683 ERR("WH_MOUSE dropped mouse message!\n");
1684
1685 /* Remove and skip message */
1686 *RemoveMessages = TRUE;
1687 return FALSE;
1688 }
1689
1690 if ((hittest == (USHORT)HTERROR) || (hittest == (USHORT)HTNOWHERE))
1691 {
1692 co_IntSendMessage( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd, MAKELONG( hittest, msg->message ));
1693
1694 /* Remove and skip message */
1695 *RemoveMessages = TRUE;
1696 return FALSE;
1697 }
1698
1699 if ((*RemoveMessages == FALSE) || MessageQueue->spwndCapture)
1700 {
1701 /* Accept the message */
1702 msg->message = message;
1703 return TRUE;
1704 }
1705
1706 if ((msg->message == WM_LBUTTONDOWN) ||
1707 (msg->message == WM_RBUTTONDOWN) ||
1708 (msg->message == WM_MBUTTONDOWN) ||
1709 (msg->message == WM_XBUTTONDOWN))
1710 {
1711 /* Send the WM_PARENTNOTIFY,
1712 * note that even for double/nonclient clicks
1713 * notification message is still WM_L/M/RBUTTONDOWN.
1714 */
1715 MsqSendParentNotify(pwndMsg, msg->message, 0, msg->pt );
1716
1717 /* Activate the window if needed */
1718
1719 if (pwndMsg != MessageQueue->spwndActive)
1720 {
1721 PWND pwndTop = pwndMsg;
1722 pwndTop = IntGetNonChildAncestor(pwndTop);
1723
1724 TRACE("Mouse pti %p pwndMsg pti %p pwndTop pti %p\n",MessageQueue->ptiMouse,pwndMsg->head.pti,pwndTop->head.pti);
1725
1726 if (pwndTop && pwndTop != pwndDesktop)
1727 {
1728 LONG ret = co_IntSendMessage( msg->hwnd,
1730 (WPARAM)UserHMGetHandle(pwndTop),
1731 MAKELONG( hittest, msg->message));
1732 switch(ret)
1733 {
1735 eatMsg = TRUE;
1736 /* fall through */
1737 case MA_NOACTIVATE:
1738 break;
1739 case MA_ACTIVATEANDEAT:
1740 eatMsg = TRUE;
1741 /* fall through */
1742 case MA_ACTIVATE:
1743 case 0:
1744 if (!co_IntMouseActivateWindow( pwndTop )) eatMsg = TRUE;
1745 break;
1746 default:
1747 ERR( "unknown WM_MOUSEACTIVATE code %d\n", ret );
1748 break;
1749 }
1750 }
1751 }
1752 }
1753
1754 /* send the WM_SETCURSOR message */
1755
1756 /* Windows sends the normal mouse message as the message parameter
1757 in the WM_SETCURSOR message even if it's non-client mouse message */
1758 co_IntSendMessage( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd, MAKELONG( hittest, msg->message ));
1759
1760 msg->message = message;
1761 return !eatMsg;
1762}
1763
1765{
1768 PWND pWnd;
1769 UINT ImmRet;
1770 BOOL Ret = TRUE;
1771 WPARAM wParam = Msg->wParam;
1773
1774 if (Msg->message == VK_PACKET)
1775 {
1776 pti->wchInjected = HIWORD(Msg->wParam);
1777 }
1778
1779 if (Msg->message == WM_KEYDOWN || Msg->message == WM_SYSKEYDOWN ||
1780 Msg->message == WM_KEYUP || Msg->message == WM_SYSKEYUP)
1781 {
1782 switch (Msg->wParam)
1783 {
1784 case VK_LSHIFT: case VK_RSHIFT:
1785 Msg->wParam = VK_SHIFT;
1786 break;
1787 case VK_LCONTROL: case VK_RCONTROL:
1788 Msg->wParam = VK_CONTROL;
1789 break;
1790 case VK_LMENU: case VK_RMENU:
1791 Msg->wParam = VK_MENU;
1792 break;
1793 }
1794 }
1795
1796 pWnd = ValidateHwndNoErr(Msg->hwnd);
1797 if (pWnd) UserRefObjectCo(pWnd, &Ref);
1798
1799 Event.message = Msg->message;
1800 Event.hwnd = Msg->hwnd;
1801 Event.time = Msg->time;
1802 Event.paramL = (Msg->wParam & 0xFF) | (HIWORD(Msg->lParam) << 8);
1803 Event.paramH = Msg->lParam & 0x7FFF;
1804 if (HIWORD(Msg->lParam) & 0x0100) Event.paramH |= 0x8000;
1806
1807 if (*RemoveMessages)
1808 {
1809 if ((Msg->message == WM_KEYDOWN) &&
1810 (Msg->hwnd != IntGetDesktopWindow()))
1811 {
1812 /* Handle F1 key by sending out WM_HELP message */
1813 if (Msg->wParam == VK_F1)
1814 {
1815 UserPostMessage( Msg->hwnd, WM_KEYF1, 0, 0 );
1816 }
1817 else if (Msg->wParam >= VK_BROWSER_BACK &&
1818 Msg->wParam <= VK_LAUNCH_APP2)
1819 {
1820 /* FIXME: Process keystate */
1821 co_IntSendMessage(Msg->hwnd, WM_APPCOMMAND, (WPARAM)Msg->hwnd, MAKELPARAM(0, (FAPPCOMMAND_KEY | (Msg->wParam - VK_BROWSER_BACK + 1))));
1822 }
1823 }
1824 else if (Msg->message == WM_KEYUP)
1825 {
1826 /* Handle VK_APPS key by posting a WM_CONTEXTMENU message */
1827 if (Msg->wParam == VK_APPS && pti->MessageQueue->MenuOwner == NULL)
1828 UserPostMessage( Msg->hwnd, WM_CONTEXTMENU, (WPARAM)Msg->hwnd, -1 );
1829 }
1830 }
1831
1833 if ( *RemoveMessages && Msg->message == WM_SYSKEYDOWN )
1834 {
1835 if ( HIWORD(Msg->lParam) & KF_ALTDOWN )
1836 {
1837 if ( Msg->wParam == VK_ESCAPE || Msg->wParam == VK_TAB ) // Alt-Tab/ESC Alt-Shift-Tab/ESC
1838 {
1839 WPARAM wParamTmp;
1840
1841 wParamTmp = UserGetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW;
1842 TRACE("Send WM_SYSCOMMAND Alt-Tab/ESC Alt-Shift-Tab/ESC\n");
1843 co_IntSendMessage( Msg->hwnd, WM_SYSCOMMAND, wParamTmp, Msg->wParam );
1844
1846 Ret = FALSE;
1848 goto Exit;
1849 }
1850 }
1851 }
1852
1853 if ( *RemoveMessages && (Msg->message == WM_SYSKEYDOWN || Msg->message == WM_KEYDOWN) )
1854 {
1855 if (gdwLanguageToggleKey < 3)
1856 {
1857 if (IS_KEY_DOWN(gafAsyncKeyState, gdwLanguageToggleKey == 1 ? VK_LMENU : VK_CONTROL)) // L Alt 1 or Ctrl 2 .
1858 {
1859 if ( wParam == VK_LSHIFT ) gLanguageToggleKeyState = INPUTLANGCHANGE_FORWARD; // Left Alt - Left Shift, Next
1861 if ( wParam == VK_RSHIFT ) gLanguageToggleKeyState = INPUTLANGCHANGE_BACKWARD; // Left Alt - Right Shift, Previous
1862 }
1863 }
1864 }
1865
1867 if ( *RemoveMessages && (Msg->message == WM_SYSKEYUP || Msg->message == WM_KEYUP) )
1868 {
1869 // When initializing win32k: Reading from the registry hotkey combination
1870 // to switch the keyboard layout and store it to global variable.
1871 // Using this combination of hotkeys in this function
1872
1873 if ( gdwLanguageToggleKey < 3 &&
1875 {
1876 if ( Msg->wParam == VK_SHIFT && !(IS_KEY_DOWN(gafAsyncKeyState, VK_SHIFT)))
1877 {
1878 WPARAM wParamILR;
1879 PKL pkl = pti->KeyboardLayout;
1880
1881 if (pWnd) UserDerefObjectCo(pWnd);
1882
1884 if (!(pWnd = pti->MessageQueue->spwndFocus))
1885 {
1886 pWnd = pti->MessageQueue->spwndActive;
1887 }
1888 if (pWnd) UserRefObjectCo(pWnd, &Ref);
1889
1890 if (pkl != NULL && gLanguageToggleKeyState)
1891 {
1892 TRACE("Posting WM_INPUTLANGCHANGEREQUEST KeyState %d\n", gLanguageToggleKeyState );
1893
1894 wParamILR = gLanguageToggleKeyState;
1895 // If system character set and font signature send flag.
1896 if ( gSystemFS & pkl->dwFontSigs )
1897 {
1898 wParamILR |= INPUTLANGCHANGE_SYSCHARSET;
1899 }
1900
1902 WM_INPUTLANGCHANGEREQUEST,
1903 wParamILR,
1904 (LPARAM)pkl->hkl );
1905
1908 Ret = FALSE;
1910 goto Exit;
1911 }
1912 }
1913 }
1914 }
1915
1917 *RemoveMessages ? HC_ACTION : HC_NOREMOVE,
1918 LOWORD(Msg->wParam),
1919 Msg->lParam))
1920 {
1921 /* skip this message */
1924 LOWORD(Msg->wParam),
1925 Msg->lParam );
1926
1927 ERR("KeyboardMessage WH_KEYBOARD Call Hook return!\n");
1928
1929 *RemoveMessages = TRUE;
1930
1931 Ret = FALSE;
1932 }
1933
1934 if ( pWnd && Ret && *RemoveMessages && Msg->message == WM_KEYDOWN && !(pti->TIF_flags & TIF_DISABLEIME))
1935 {
1936 if ( (ImmRet = IntImmProcessKey(pti->MessageQueue, pWnd, Msg->message, Msg->wParam, Msg->lParam)) )
1937 {
1938 if ( ImmRet & (IPHK_HOTKEY|IPHK_SKIPTHISKEY) )
1939 {
1940 ImmRet = 0;
1941 }
1942 if ( ImmRet & IPHK_PROCESSBYIME )
1943 {
1944 Msg->wParam = VK_PROCESSKEY;
1945 }
1946 }
1947 }
1948Exit:
1949 if (pWnd) UserDerefObjectCo(pWnd);
1950 return Ret;
1951}
1952
1953BOOL co_IntProcessHardwareMessage(MSG* Msg, BOOL* RemoveMessages, BOOL* NotForUs, LONG_PTR ExtraInfo, UINT first, UINT last)
1954{
1955 if ( IS_MOUSE_MESSAGE(Msg->message))
1956 {
1957 return co_IntProcessMouseMessage(Msg, RemoveMessages, NotForUs, ExtraInfo, first, last);
1958 }
1959 else if ( IS_KBD_MESSAGE(Msg->message))
1960 {
1961 return co_IntProcessKeyboardMessage(Msg, RemoveMessages);
1962 }
1963
1964 return TRUE;
1965}
1966
1967/* check whether a message filter contains at least one potential hardware message */
1968static INT FASTCALL
1970{
1971 /* hardware message ranges are (in numerical order):
1972 * WM_NCMOUSEFIRST .. WM_NCMOUSELAST
1973 * WM_KEYFIRST .. WM_KEYLAST
1974 * WM_MOUSEFIRST .. WM_MOUSELAST
1975 */
1976 if (!last) --last;
1977 if (last < WM_NCMOUSEFIRST) return 0;
1978 if (first > WM_NCMOUSELAST && last < WM_KEYFIRST) return 0;
1979 if (first > WM_KEYLAST && last < WM_MOUSEFIRST) return 0;
1980 if (first > WM_MOUSELAST) return 0;
1981 return 1;
1982}
1983
1984/* check whether message is in the range of mouse messages */
1986{
1987 return ( //( message >= WM_NCMOUSEFIRST && message <= WM_NCMOUSELAST ) || This seems to break tests...
1989 ( message >= WM_XBUTTONDOWN && message <= WM_XBUTTONDBLCLK ) ||
1992}
1993
1996 IN BOOL Remove,
1997 IN PWND Window,
1998 IN UINT MsgFilterLow,
1999 IN UINT MsgFilterHigh,
2000 IN UINT QSflags,
2001 OUT MSG* pMsg)
2002{
2003 BOOL AcceptMessage, NotForUs;
2004 PUSER_MESSAGE CurrentMessage;
2005 PLIST_ENTRY ListHead;
2006 MSG msg;
2007 ULONG_PTR idSave;
2008 DWORD QS_Flags;
2009 LONG_PTR ExtraInfo;
2010 BOOL Ret = FALSE;
2011 PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue;
2012
2013 if (!filter_contains_hw_range( MsgFilterLow, MsgFilterHigh )) return FALSE;
2014
2015 ListHead = MessageQueue->HardwareMessagesListHead.Flink;
2016
2017 if (IsListEmpty(ListHead)) return FALSE;
2018
2019 if (!MessageQueue->ptiSysLock)
2020 {
2021 MessageQueue->ptiSysLock = pti;
2022 pti->pcti->CTI_flags |= CTI_THREADSYSLOCK;
2023 }
2024
2025 if (MessageQueue->ptiSysLock != pti)
2026 {
2027 ERR("Thread Q is locked to ptiSysLock 0x%p pti 0x%p\n",MessageQueue->ptiSysLock,pti);
2028 return FALSE;
2029 }
2030
2031 while (ListHead != &MessageQueue->HardwareMessagesListHead)
2032 {
2033 CurrentMessage = CONTAINING_RECORD(ListHead, USER_MESSAGE, ListEntry);
2034 ListHead = ListHead->Flink;
2035
2036 if (MessageQueue->idSysPeek == (ULONG_PTR)CurrentMessage)
2037 {
2038 TRACE("Skip this message due to it is in play!\n");
2039 continue;
2040 }
2041/*
2042 MSDN:
2043 1: any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL.
2044 2: retrieves only messages on the current thread's message queue whose hwnd value is NULL.
2045 3: handle to the window whose messages are to be retrieved.
2046 */
2047 if ( ( !Window || // 1
2048 ( Window == PWND_BOTTOM && CurrentMessage->Msg.hwnd == NULL ) || // 2
2049 ( Window != PWND_BOTTOM && Window->head.h == CurrentMessage->Msg.hwnd ) || // 3
2050 ( is_mouse_message(CurrentMessage->Msg.message) ) ) && // Null window for anything mouse.
2051 ( ( ( MsgFilterLow == 0 && MsgFilterHigh == 0 ) && CurrentMessage->QS_Flags & QSflags ) ||
2052 ( MsgFilterLow <= CurrentMessage->Msg.message && MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
2053 {
2054 idSave = MessageQueue->idSysPeek;
2055 MessageQueue->idSysPeek = (ULONG_PTR)CurrentMessage;
2056
2057 msg = CurrentMessage->Msg;
2058 ExtraInfo = CurrentMessage->ExtraInfo;
2059 QS_Flags = CurrentMessage->QS_Flags;
2060
2061 NotForUs = FALSE;
2062
2063 UpdateKeyStateFromMsg(MessageQueue, &msg);
2064 AcceptMessage = co_IntProcessHardwareMessage(&msg, &Remove, &NotForUs, ExtraInfo, MsgFilterLow, MsgFilterHigh);
2065
2066 if (Remove)
2067 {
2068 if (CurrentMessage->pti != NULL && (MessageQueue->idSysPeek == (ULONG_PTR)CurrentMessage))
2069 {
2070 MsqDestroyMessage(CurrentMessage);
2071 }
2072 ClearMsgBitsMask(pti, QS_Flags);
2073 }
2074
2075 MessageQueue->idSysPeek = idSave;
2076
2077 if (NotForUs)
2078 {
2079 Ret = FALSE;
2080 break;
2081 }
2082
2083 if (AcceptMessage)
2084 {
2085 *pMsg = msg;
2086 // Fix all but one wine win:test_GetMessagePos WM_TIMER tests. See PostTimerMessages.
2087 if (!RtlEqualMemory(&pti->ptLast, &msg.pt, sizeof(POINT)))
2088 {
2089 pti->TIF_flags |= TIF_MSGPOSCHANGED;
2090 }
2091 pti->timeLast = msg.time;
2092 pti->ptLast = msg.pt;
2093 MessageQueue->ExtraInfo = ExtraInfo;
2094 Ret = TRUE;
2095 break;
2096 }
2097 }
2098 }
2099
2100 MessageQueue->ptiSysLock = NULL;
2101 pti->pcti->CTI_flags &= ~CTI_THREADSYSLOCK;
2102 return Ret;
2103}
2104
2108 IN PWND Window,
2109 IN UINT MsgFilterLow,
2110 IN UINT MsgFilterHigh,
2111 IN UINT QSflags,
2112 OUT LONG_PTR *ExtraInfo,
2113 OUT DWORD *dwQEvent,
2115{
2116 PUSER_MESSAGE CurrentMessage;
2117 PLIST_ENTRY ListHead;
2118 DWORD QS_Flags;
2119 BOOL Ret = FALSE;
2120
2121 ListHead = pti->PostedMessagesListHead.Flink;
2122
2123 if (IsListEmpty(ListHead)) return FALSE;
2124
2125 while(ListHead != &pti->PostedMessagesListHead)
2126 {
2127 CurrentMessage = CONTAINING_RECORD(ListHead, USER_MESSAGE, ListEntry);
2128 ListHead = ListHead->Flink;
2129/*
2130 MSDN:
2131 1: any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL.
2132 2: retrieves only messages on the current thread's message queue whose hwnd value is NULL.
2133 3: handle to the window whose messages are to be retrieved.
2134 */
2135 if ( ( !Window || // 1
2136 ( Window == PWND_BOTTOM && CurrentMessage->Msg.hwnd == NULL ) || // 2
2137 ( Window != PWND_BOTTOM && Window->head.h == CurrentMessage->Msg.hwnd ) ) && // 3
2138 ( ( ( MsgFilterLow == 0 && MsgFilterHigh == 0 ) && CurrentMessage->QS_Flags & QSflags ) ||
2139 ( MsgFilterLow <= CurrentMessage->Msg.message && MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
2140 {
2141 *Message = CurrentMessage->Msg;
2142 *ExtraInfo = CurrentMessage->ExtraInfo;
2143 QS_Flags = CurrentMessage->QS_Flags;
2144 if (dwQEvent) *dwQEvent = CurrentMessage->dwQEvent;
2145
2146 if (Remove)
2147 {
2148 if (CurrentMessage->pti != NULL)
2149 {
2150 MsqDestroyMessage(CurrentMessage);
2151 }
2152 ClearMsgBitsMask(pti, QS_Flags);
2153 }
2154 Ret = TRUE;
2155 break;
2156 }
2157 }
2158
2159 return Ret;
2160}
2161
2164 UINT MsgFilterMin, UINT MsgFilterMax)
2165{
2167
2168 // Post mouse moves before waiting for messages.
2169 if (pti->MessageQueue->QF_flags & QF_MOUSEMOVED)
2170 {
2172 }
2173
2174 UserLeaveCo();
2175
2176 ZwYieldExecution(); // Let someone else run!
2177
2180 UserMode,
2181 FALSE,
2182 NULL );
2183 UserEnterCo();
2184 if ( ret == STATUS_USER_APC )
2185 {
2186 TRACE("MWFNW User APC\n");
2188 }
2189 return ret;
2190}
2191
2194{
2195 DWORD dwTimeStamp = EngGetTickCount32();
2196 if (dwTimeStamp - pti->pcti->timeLastRead > TimeOut &&
2197 !(pti->pcti->fsWakeMask & QS_INPUT) &&
2198 !PsGetThreadFreezeCount(pti->pEThread) &&
2199 !(pti->ppi->W32PF_flags & W32PF_APPSTARTING))
2200 {
2201 TRACE("\nMsqIsHung(pti %p, TimeOut %lu)\n"
2202 "pEThread %p, ThreadsProcess %p, ImageFileName '%s'\n"
2203 "dwTimeStamp = %lu\n"
2204 "pti->pcti->timeLastRead = %lu\n"
2205 "pti->timeLast = %lu\n"
2206 "PsGetThreadFreezeCount(pti->pEThread) = %lu\n",
2207 pti, TimeOut,
2208 pti->pEThread,
2209 pti->pEThread ? pti->pEThread->ThreadsProcess : NULL,
2210 (pti->pEThread && pti->pEThread->ThreadsProcess)
2211 ? pti->pEThread->ThreadsProcess->ImageFileName : "(None)",
2212 dwTimeStamp,
2213 pti->pcti->timeLastRead,
2214 pti->timeLast,
2215 PsGetThreadFreezeCount(pti->pEThread));
2216
2217 return TRUE;
2218 }
2219
2220 return FALSE;
2221}
2222
2225{
2226 if (pti->pEThread)
2227 {
2228 BOOL Ret = TRUE;
2229 if (!(pti->pEThread->Tcb.SuspendCount) && !PsGetThreadFreezeCount(pti->pEThread)) Ret = FALSE;
2230 return Ret;
2231 }
2232 return FALSE;
2233}
2234
2235VOID
2238{
2240 TRACE("HungAppSysTimerProc\n");
2241 // Process list of windows that are hung and waiting.
2242}
2243
2246{
2247 InitializeListHead(&MessageQueue->HardwareMessagesListHead); // Keep here!
2248 MessageQueue->spwndFocus = NULL;
2249 MessageQueue->iCursorLevel = 0;
2250 MessageQueue->CursorObject = SYSTEMCUR(WAIT); // See test_initial_cursor.
2251 if (MessageQueue->CursorObject)
2252 {
2253 TRACE("Default cursor hcur %p\n",UserHMGetHandle(MessageQueue->CursorObject));
2254 UserReferenceObject(MessageQueue->CursorObject);
2255 }
2257 MessageQueue->ptiMouse = pti;
2258 MessageQueue->ptiKeyboard = pti;
2259 MessageQueue->cThreads++;
2260
2261 return TRUE;
2262}
2263
2266{
2267 PLIST_ENTRY CurrentEntry;
2268 PUSER_MESSAGE CurrentMessage;
2269 PUSER_SENT_MESSAGE CurrentSentMessage;
2270
2271 TRACE("MsqCleanupThreadMsgs %p\n",pti);
2272
2273 // Clear it all out.
2274 if (pti->pcti)
2275 {
2276 pti->pcti->fsWakeBits = 0;
2277 pti->pcti->fsChangeBits = 0;
2278 }
2279
2280 pti->nCntsQBits[QSRosKey] = 0;
2281 pti->nCntsQBits[QSRosMouseMove] = 0;
2282 pti->nCntsQBits[QSRosMouseButton] = 0;
2283 pti->nCntsQBits[QSRosPostMessage] = 0;
2284 pti->nCntsQBits[QSRosSendMessage] = 0;
2285 pti->nCntsQBits[QSRosHotKey] = 0;
2286 pti->nCntsQBits[QSRosEvent] = 0;
2287
2288 /* cleanup posted messages */
2289 while (!IsListEmpty(&pti->PostedMessagesListHead))
2290 {
2291 CurrentEntry = pti->PostedMessagesListHead.Flink;
2292 CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
2293 ERR("Thread Cleanup Post Messages %p\n",CurrentMessage);
2294 if (CurrentMessage->dwQEvent)
2295 {
2296 if (CurrentMessage->dwQEvent == POSTEVENT_NWE)
2297 {
2298 ExFreePoolWithTag( (PVOID)CurrentMessage->ExtraInfo, TAG_HOOK);
2299 }
2300 }
2301 MsqDestroyMessage(CurrentMessage);
2302 }
2303
2304 /* remove the messages that have not yet been dispatched */
2305 while (!IsListEmpty(&pti->SentMessagesListHead))
2306 {
2307 CurrentEntry = pti->SentMessagesListHead.Flink;
2308 CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry);
2309
2310 ERR("Thread Cleanup Sent Messages %p\n",CurrentSentMessage);
2311
2312 /* wake the sender's thread */
2313 if (CurrentSentMessage->pkCompletionEvent != NULL)
2314 {
2315 KeSetEvent(CurrentSentMessage->pkCompletionEvent, IO_NO_INCREMENT, FALSE);
2316 }
2317
2318 if (CurrentSentMessage->HasPackedLParam)
2319 {
2320 if (CurrentSentMessage->Msg.lParam)
2321 ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
2322 }
2323
2324 /* free the message */
2325 FreeUserMessage(CurrentSentMessage);
2326 }
2327
2328 // Process Trouble Message List
2329 if (!IsListEmpty(&usmList))
2330 {
2331 CurrentEntry = usmList.Flink;
2332 while (CurrentEntry != &usmList)
2333 {
2334 CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry);
2335 CurrentEntry = CurrentEntry->Flink;
2336
2337 TRACE("Found troubled messages %p on the list\n",CurrentSentMessage);
2338
2339 if ( pti == CurrentSentMessage->ptiReceiver )
2340 {
2341 if (CurrentSentMessage->HasPackedLParam)
2342 {
2343 if (CurrentSentMessage->Msg.lParam)
2344 ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
2345 }
2346
2347 /* free the message */
2348 FreeUserMessage(CurrentSentMessage);
2349 }
2350 else if ( pti == CurrentSentMessage->ptiSender ||
2351 pti == CurrentSentMessage->ptiCallBackSender )
2352 {
2353 // Determine whether this message is being processed or not.
2354 if ((CurrentSentMessage->flags & (SMF_RECEIVERBUSY|SMF_RECEIVEDMESSAGE)) != SMF_RECEIVEDMESSAGE)
2355 {
2356 CurrentSentMessage->flags |= SMF_RECEIVERFREE;
2357 }
2358
2359 if (!(CurrentSentMessage->flags & SMF_RECEIVERFREE))
2360 {
2361
2362 if (CurrentSentMessage->HasPackedLParam)
2363 {
2364 if (CurrentSentMessage->Msg.lParam)
2365 ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
2366 }
2367
2368 /* free the message */
2369 FreeUserMessage(CurrentSentMessage);
2370 }
2371 }
2372 }
2373 }
2374}
2375
2378{
2379 PUSER_MESSAGE_QUEUE MessageQueue;
2380 PLIST_ENTRY CurrentEntry;
2381 PUSER_MESSAGE CurrentMessage;
2382
2383 MessageQueue = pti->MessageQueue;
2384 MessageQueue->cThreads--;
2385
2386 if (MessageQueue->cThreads)
2387 {
2388 if (MessageQueue->ptiSysLock == pti) MessageQueue->ptiSysLock = NULL;
2389 }
2390
2391 if (MessageQueue->cThreads == 0)
2392 {
2393 /* cleanup posted messages */
2394 while (!IsListEmpty(&MessageQueue->HardwareMessagesListHead))
2395 {
2396 CurrentEntry = MessageQueue->HardwareMessagesListHead.Flink;
2397 CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
2398 ERR("MQ Cleanup Post Messages %p\n",CurrentMessage);
2399 MsqDestroyMessage(CurrentMessage);
2400 }
2401 }
2402
2403 if (MessageQueue->CursorObject)
2404 {
2405 PCURICON_OBJECT pCursor = MessageQueue->CursorObject;
2406
2407 /* Change to another cursor if we going to dereference current one
2408 Note: we can't use UserSetCursor because it uses current thread
2409 message queue instead of queue given for cleanup */
2410 if (IntGetSysCursorInfo()->CurrentCursorObject == pCursor)
2411 {
2412 HDC hdcScreen;
2413
2414 /* Get the screen DC */
2415 hdcScreen = IntGetScreenDC();
2416 if (hdcScreen)
2417 GreMovePointer(hdcScreen, -1, -1);
2419 }
2420
2421 TRACE("DereferenceObject pCursor\n");
2422 UserDereferenceObject(pCursor);
2423 }
2424
2425 if (gpqForeground == MessageQueue)
2426 {
2428 }
2429 if (gpqForegroundPrev == MessageQueue)
2430 {
2432 }
2433 if (gpqCursor == MessageQueue)
2434 {
2435 gpqCursor = NULL;
2436 }
2437}
2438
2441{
2442 PUSER_MESSAGE_QUEUE MessageQueue;
2443
2444 MessageQueue = ExAllocatePoolWithTag(NonPagedPool,
2445 sizeof(*MessageQueue),
2446 USERTAG_Q);
2447
2448 if (!MessageQueue)
2449 {
2450 return NULL;
2451 }
2452
2453 RtlZeroMemory(MessageQueue, sizeof(*MessageQueue));
2454 /* hold at least one reference until it'll be destroyed */
2455 IntReferenceMessageQueue(MessageQueue);
2456 /* initialize the queue */
2457 if (!MsqInitializeMessageQueue(pti, MessageQueue))
2458 {
2459 IntDereferenceMessageQueue(MessageQueue);
2460 return NULL;
2461 }
2462
2463 return MessageQueue;
2464}
2465
2468{
2469 PDESKTOP desk;
2470 PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue;
2471
2472 NT_ASSERT(MessageQueue != NULL);
2473 MessageQueue->QF_flags |= QF_INDESTROY;
2474
2475 /* remove the message queue from any desktops */
2476 if ((desk = InterlockedExchangePointer((PVOID*)&MessageQueue->Desktop, 0)))
2477 {
2479 IntDereferenceMessageQueue(MessageQueue);
2480 }
2481
2482 /* clean it up */
2484
2485 /* decrease the reference counter, if it hits zero, the queue will be freed */
2487 IntDereferenceMessageQueue(MessageQueue);
2488}
2489
2492{
2493 LPARAM Ret;
2494 PTHREADINFO pti;
2495 PUSER_MESSAGE_QUEUE MessageQueue;
2496
2498 MessageQueue = pti->MessageQueue;
2499 if(!MessageQueue)
2500 {
2501 return 0;
2502 }
2503
2504 Ret = MessageQueue->ExtraInfo;
2505 MessageQueue->ExtraInfo = lParam;
2506
2507 return Ret;
2508}
2509
2512{
2513 PTHREADINFO pti;
2514 PUSER_MESSAGE_QUEUE MessageQueue;
2515
2517 MessageQueue = pti->MessageQueue;
2518 if(!MessageQueue)
2519 {
2520 return 0;
2521 }
2522
2523 return MessageQueue->ExtraInfo;
2524}
2525
2526// ReplyMessage is called by the thread receiving the window message.
2529{
2531 PTHREADINFO pti;
2532
2534 Message = pti->pusmCurrent;
2535
2536 if (!Message) return FALSE;
2537
2538 if (Message->QS_Flags & QS_SMRESULT) return FALSE;
2539
2540 // SendMessageXxx || Callback msg and not a notify msg
2541 if (Message->ptiSender || Message->CompletionCallback)
2542 {
2543 Message->lResult = lResult;
2544 Message->QS_Flags |= QS_SMRESULT;
2545 // See co_MsqDispatchOneSentMessage, change bits already accounted for and cleared and this msg is going away..
2546 }
2547 return TRUE;
2548}
2549
2552{
2553 HWND Prev;
2554 PUSER_MESSAGE_QUEUE MessageQueue;
2555
2556 MessageQueue = pti->MessageQueue;
2557
2558 switch(Type)
2559 {
2560 case MSQ_STATE_CAPTURE:
2561 Prev = MessageQueue->spwndCapture ? UserHMGetHandle(MessageQueue->spwndCapture) : 0;
2562 MessageQueue->spwndCapture = ValidateHwndNoErr(hWnd);
2563 return Prev;
2564 case MSQ_STATE_ACTIVE:
2565 Prev = MessageQueue->spwndActive ? UserHMGetHandle(MessageQueue->spwndActive) : 0;
2566 MessageQueue->spwndActive = ValidateHwndNoErr(hWnd);
2567 return Prev;
2568 case MSQ_STATE_FOCUS:
2569 Prev = MessageQueue->spwndFocus ? UserHMGetHandle(MessageQueue->spwndFocus) : 0;
2570 MessageQueue->spwndFocus = ValidateHwndNoErr(hWnd);
2571 return Prev;
2573 Prev = MessageQueue->MenuOwner;
2574 MessageQueue->MenuOwner = hWnd;
2575 return Prev;
2576 case MSQ_STATE_MOVESIZE:
2577 Prev = MessageQueue->MoveSize;
2578 MessageQueue->MoveSize = hWnd;
2579 return Prev;
2580 case MSQ_STATE_CARET:
2581 Prev = MessageQueue->CaretInfo.hWnd;
2582 MessageQueue->CaretInfo.hWnd = hWnd;
2583 return Prev;
2584 }
2585
2586 return NULL;
2587}
2588
2589SHORT
2592{
2593 DWORD Ret;
2594
2596
2597 Ret = UserGetKeyState(key);
2598
2599 UserLeave();
2600
2601 return (SHORT)Ret;
2602}
2603
2604
2605DWORD
2608{
2609 DWORD i, ret = TRUE;
2610 PTHREADINFO pti;
2611 PUSER_MESSAGE_QUEUE MessageQueue;
2612
2614
2616 MessageQueue = pti->MessageQueue;
2617
2618 _SEH2_TRY
2619 {
2620 /* Probe and copy key state to an array */
2621 ProbeForWrite(lpKeyState, 256 * sizeof(BYTE), 1);
2622 for (i = 0; i < 256; ++i)
2623 {
2624 lpKeyState[i] = 0;
2625 if (IS_KEY_DOWN(MessageQueue->afKeyState, i))
2626 lpKeyState[i] |= KS_DOWN_BIT;
2627 if (IS_KEY_LOCKED(MessageQueue->afKeyState, i))
2628 lpKeyState[i] |= KS_LOCK_BIT;
2629 }
2630 }
2632 {
2634 ret = FALSE;
2635 }
2636 _SEH2_END;
2637
2638 UserLeave();
2639
2640 return ret;
2641}
2642
2643BOOL
2646{
2647 UINT i;
2648 BOOL bRet = TRUE;
2649 PTHREADINFO pti;
2650 PUSER_MESSAGE_QUEUE MessageQueue;
2651
2653
2655 MessageQueue = pti->MessageQueue;
2656
2657 _SEH2_TRY
2658 {
2659 ProbeForRead(pKeyState, 256 * sizeof(BYTE), 1);
2660 for (i = 0; i < 256; ++i)
2661 {
2662 SET_KEY_DOWN(MessageQueue->afKeyState, i, pKeyState[i] & KS_DOWN_BIT);
2663 SET_KEY_LOCKED(MessageQueue->afKeyState, i, pKeyState[i] & KS_LOCK_BIT);
2664 }
2665 }
2667 {
2669 bRet = FALSE;
2670 }
2671 _SEH2_END;
2672
2673 UserLeave();
2674
2675 return bRet;
2676}
2677
2678/* EOF */
const TCHAR * CompletionCallback(unsigned __int64 &rnIndex, const BOOL *pblnForward, const TCHAR *pszContext, const TCHAR *pszBegin)
Definition: Completion.cpp:439
unsigned char BOOLEAN
Type
Definition: Type.h:7
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
LONG NTSTATUS
Definition: precomp.h:26
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:103
WPARAM wParam
Definition: combotst.c:138
struct @1609 Msg[]
LPARAM lParam
Definition: combotst.c:139
@ hook
Definition: msg.h:42
#define SYSTEMCUR(func)
Definition: cursoricon.h:129
struct tagACON * PACON
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define APIENTRY
Definition: api.h:79
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CALLBACK
Definition: compat.h:35
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
PSERVERINFO gpsi
Definition: imm.c:18
#define ValidateHwndNoErr(hwnd)
Definition: precomp.h:84
static const WCHAR Message[]
Definition: register.c:74
#define pt(x, y)
Definition: drawing.c:79
#define ULONG_PTR
Definition: config.h:101
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define EngGetTickCount32()
Definition: eng.h:43
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define abs(i)
Definition: fconv.c:206
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
BOOL FASTCALL co_IntMouseActivateWindow(PWND Wnd)
Definition: focus.c:1250
HWND FASTCALL IntGetCaptureWindow(VOID)
Definition: focus.c:34
PUSER_MESSAGE_QUEUE gpqForeground
Definition: focus.c:13
PUSER_MESSAGE_QUEUE gpqForegroundPrev
Definition: focus.c:14
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
struct _cl_event * event
Definition: glext.h:7739
GLbitfield flags
Definition: glext.h:7161
const GLint * first
Definition: glext.h:5794
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
POINT last
Definition: font.c:46
#define down(mutex)
Definition: glue.h:29
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ICLS_EDIT
Definition: ntuser.h:908
#define TIF_INCLEANUP
Definition: ntuser.h:262
#define WNDS_DESTROYED
Definition: ntuser.h:631
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
#define PWND_BOTTOM
Definition: ntuser.h:764
#define MSQ_STATE_CARET
Definition: ntuser.h:3704
#define MSQ_STATE_MOVESIZE
Definition: ntuser.h:3703
#define TIF_DISABLEIME
Definition: ntuser.h:287
#define MSQ_STATE_CAPTURE
Definition: ntuser.h:3699
#define MSQ_STATE_FOCUS
Definition: ntuser.h:3701
#define MSQ_STATE_ACTIVE
Definition: ntuser.h:3700
#define MSQ_STATE_MENUOWNER
Definition: ntuser.h:3702
#define CTI_THREADSYSLOCK
Definition: ntuser.h:161
#define CTI_INSENDMESSAGE
Definition: ntuser.h:162
#define WNDS2_INDESTROY
Definition: ntuser.h:643
#define TIF_MSGPOSCHANGED
Definition: ntuser.h:282
#define CURSORF_ACON
Definition: ntuser.h:1197
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
#define RtlEqualMemory(a, b, c)
Definition: kdvm.h:18
VOID NTAPI ExInitializePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:270
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
static HDC
Definition: imagelist.c:92
#define WAIT
Definition: listbox.c:36
#define WM_KEYF1
Definition: msg.c:47
#define _In_
Definition: ms_sal.h:308
VOID FASTCALL ClearMsgBitsMask(PTHREADINFO pti, UINT MessageBits)
Definition: msgqueue.c:445
VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PWND Window)
Definition: msgqueue.c:798
INT PostMsgCount
Definition: msgqueue.c:18
VOID FASTCALL MsqPostQuitMessage(PTHREADINFO pti, ULONG ExitCode)
Definition: msgqueue.c:1379
VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE Message)
Definition: msgqueue.c:748
BOOL APIENTRY NtUserSetKeyboardState(LPBYTE pKeyState)
Definition: msgqueue.c:2645
BOOLEAN FASTCALL co_MsqDispatchOneSentMessage(_In_ PTHREADINFO pti)
Definition: msgqueue.c:873
VOID FASTCALL MsqDecPaintCountQueue(PTHREADINFO pti)
Definition: msgqueue.c:508
VOID FASTCALL MsqIncPaintCountQueue(PTHREADINFO pti)
Definition: msgqueue.c:501
BOOLEAN FASTCALL MsqInitializeMessageQueue(PTHREADINFO pti, PUSER_MESSAGE_QUEUE MessageQueue)
Definition: msgqueue.c:2245
static BOOL is_mouse_message(UINT message)
Definition: msgqueue.c:1985
VOID FASTCALL MsqPostMouseMove(PTHREADINFO pti, MSG *Msg, LONG_PTR ExtraInfo)
Definition: msgqueue.c:518
HWND FASTCALL MsqSetStateWindow(PTHREADINFO pti, ULONG Type, HWND hWnd)
Definition: msgqueue.c:2551
BOOL APIENTRY co_MsqPeekHardwareMessage(IN PTHREADINFO pti, IN BOOL Remove, IN PWND Window, IN UINT MsgFilterLow, IN UINT MsgFilterHigh, IN UINT QSflags, OUT MSG *pMsg)
Definition: msgqueue.c:1995
int UserShowCursor(BOOL bShow)
Definition: msgqueue.c:168
DWORD FASTCALL UserGetKeyState(DWORD dwKey)
Definition: msgqueue.c:221
VOID FASTCALL IntCoalesceMouseMove(PTHREADINFO pti)
Definition: msgqueue.c:551
BOOL co_IntProcessKeyboardMessage(MSG *Msg, BOOL *RemoveMessages)
Definition: msgqueue.c:1764
VOID FASTCALL co_MsqInsertMouseMessage(MSG *Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook)
Definition: msgqueue.c:580
static PPAGED_LOOKASIDE_LIST pgSendMsgLookasideList
Definition: msgqueue.c:17
PCURICON_OBJECT FASTCALL UserSetCursor(PCURICON_OBJECT NewCursor, BOOL ForceChange)
Definition: msgqueue.c:93
static VOID UpdateKeyStateFromMsg(PUSER_MESSAGE_QUEUE MessageQueue, MSG *msg)
Definition: msgqueue.c:265
static PPAGED_LOOKASIDE_LIST pgMessageLookasideList
Definition: msgqueue.c:16
WPARAM FASTCALL MsqGetDownKeyState(PUSER_MESSAGE_QUEUE MessageQueue)
Definition: msgqueue.c:338
BOOL co_IntProcessMouseMessage(MSG *msg, BOOL *RemoveMessages, BOOL *NotForUs, LONG_PTR ExtraInfo, UINT first, UINT last)
Definition: msgqueue.c:1470
INT SendMsgCount
Definition: msgqueue.c:19
DWORD APIENTRY NtUserGetKeyboardState(LPBYTE lpKeyState)
Definition: msgqueue.c:2607
VOID FASTCALL MsqDestroyMessageQueue(_In_ PTHREADINFO pti)
Definition: msgqueue.c:2467
NTSTATUS FASTCALL co_MsqSendMessage(PTHREADINFO ptirec, HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, UINT uTimeout, BOOL Block, INT HookMessage, ULONG_PTR *uResult)
Definition: msgqueue.c:1056
VOID FASTCALL MsqCleanupMessageQueue(PTHREADINFO pti)
Definition: msgqueue.c:2377
static void MsqSendParentNotify(PWND pwnd, WORD event, WORD idChild, POINT pt)
Definition: msgqueue.c:1392
static VOID UpdateKeyState(PUSER_MESSAGE_QUEUE MessageQueue, WORD wVk, BOOL bIsDown)
Definition: msgqueue.c:246
BOOL FASTCALL IntMsqClearWakeMask(VOID)
Definition: msgqueue.c:392
VOID FASTCALL MsqPostMessage(PTHREADINFO pti, MSG *Msg, BOOLEAN HardwareMessage, DWORD MessageBits, DWORD dwQEvent, LONG_PTR ExtraInfo)
Definition: msgqueue.c:1337
SHORT APIENTRY NtUserGetKeyState(INT key)
Definition: msgqueue.c:2591
VOID CALLBACK HungAppSysTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Definition: msgqueue.c:2237
BOOL FASTCALL IsThreadSuspended(PTHREADINFO pti)
Definition: msgqueue.c:2224
static INT FASTCALL filter_contains_hw_range(UINT first, UINT last)
Definition: msgqueue.c:1969
PWND FASTCALL IntTopLevelWindowFromPoint(INT x, INT y)
Definition: msgqueue.c:61
ULONG_PTR gdwMouseMoveExtraInfo
Definition: msgqueue.c:21
VOID FASTCALL MsqCleanupThreadMsgs(PTHREADINFO pti)
Definition: msgqueue.c:2265
NTSTATUS NTAPI MsqInitializeImpl(VOID)
Definition: msgqueue.c:30
VOID FASTCALL FreeUserMessage(PUSER_SENT_MESSAGE Message)
Definition: msgqueue.c:786
PUSER_MESSAGE_QUEUE gpqCursor
Definition: msgqueue.c:20
LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam)
Definition: msgqueue.c:2491
BOOL FASTCALL co_MsqSendMessageAsync(PTHREADINFO ptiReceiver, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, SENDASYNCPROC CompletionCallback, ULONG_PTR CompletionCallbackContext, BOOL HasPackedLParam, INT HookMessage)
Definition: msgqueue.c:1014
BOOL FASTCALL MsqIsHung(PTHREADINFO pti, DWORD TimeOut)
Definition: msgqueue.c:2193
BOOL co_IntProcessHardwareMessage(MSG *Msg, BOOL *RemoveMessages, BOOL *NotForUs, LONG_PTR ExtraInfo, UINT first, UINT last)
Definition: msgqueue.c:1953
BOOL FASTCALL co_MsqReplyMessage(LRESULT lResult)
Definition: msgqueue.c:2528
PUSER_MESSAGE_QUEUE FASTCALL MsqCreateMessageQueue(PTHREADINFO pti)
Definition: msgqueue.c:2440
HANDLE FASTCALL IntMsqSetWakeMask(DWORD WakeMask)
Definition: msgqueue.c:362
NTSTATUS FASTCALL co_MsqWaitForNewMessages(PTHREADINFO pti, PWND WndFilter, UINT MsgFilterMin, UINT MsgFilterMax)
Definition: msgqueue.c:2163
BOOLEAN APIENTRY MsqPeekMessage(IN PTHREADINFO pti, IN BOOLEAN Remove, IN PWND Window, IN UINT MsgFilterLow, IN UINT MsgFilterHigh, IN UINT QSflags, OUT LONG_PTR *ExtraInfo, OUT DWORD *dwQEvent, OUT PMSG Message)
Definition: msgqueue.c:2106
LIST_ENTRY usmList
Definition: msgqueue.c:23
VOID FASTCALL IntTrackMouseMove(PWND pwndTrack, PDESKTOP pDesk, PMSG msg, USHORT hittest)
Definition: msgqueue.c:1419
LPARAM FASTCALL MsqGetMessageExtraInfo(VOID)
Definition: msgqueue.c:2511
VOID FASTCALL MsqWakeQueue(PTHREADINFO pti, DWORD MessageBits, BOOL KeyEvent)
Definition: msgqueue.c:412
PUSER_SENT_MESSAGE FASTCALL AllocateUserMessage(BOOL KEvent)
Definition: msgqueue.c:763
DWORD gdwMouseMoveTimeStamp
Definition: msgqueue.c:22
PUSER_MESSAGE FASTCALL MsqCreateMessage(LPMSG Msg)
Definition: msgqueue.c:731
#define IS_KBD_MESSAGE(message)
Definition: msgqueue.h:246
#define MSQ_ISHOOK
Definition: msgqueue.h:5
#define SMF_SENDERDIED
Definition: msgqueue.h:39
#define POSTEVENT_NWE
Definition: msgqueue.h:125
#define MSQ_NORMAL
Definition: msgqueue.h:4
#define SMF_RECEIVEDMESSAGE
Definition: msgqueue.h:41
#define MSQ_INJECTMODULE
Definition: msgqueue.h:6
#define SMF_RECEIVERDIED
Definition: msgqueue.h:38
#define SMF_RECEIVERBUSY
Definition: msgqueue.h:42
#define IntReferenceMessageQueue(MsgQueue)
Definition: msgqueue.h:217
#define QF_INDESTROY
Definition: msgqueue.h:103
#define WM_NCMOUSEFIRST
Definition: msgqueue.h:239
#define IntDereferenceMessageQueue(MsgQueue)
Definition: msgqueue.h:220
#define WM_NCMOUSELAST
Definition: msgqueue.h:240
#define SMF_RECEIVERFREE
Definition: msgqueue.h:40
#define QF_MOUSEMOVED
Definition: msgqueue.h:99
#define IS_MOUSE_MESSAGE(message)
Definition: msgqueue.h:242
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
#define UserMode
Definition: asm.h:35
NTSYSAPI NTSTATUS NTAPI ZwYieldExecution(VOID)
#define FASTCALL
Definition: nt_native.h:50
#define Int32x32To64(a, b)
@ NotificationEvent
@ WaitAny
NTSTATUS NTAPI KeWaitForMultipleObjects(IN ULONG Count, IN PVOID Object[], IN WAIT_TYPE WaitType, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL, OUT PKWAIT_BLOCK WaitBlockArray OPTIONAL)
Definition: wait.c:586
ULONG NTAPI PsGetThreadFreezeCount(IN PETHREAD Thread)
Definition: thread.c:685
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
#define STATUS_WAIT_0
Definition: ntstatus.h:237
#define STATUS_WAIT_1
Definition: ntstatus.h:71
#define STATUS_USER_APC
Definition: ntstatus.h:78
#define STATUS_WAIT_2
Definition: ntstatus.h:72
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
LRESULT APIENTRY co_CallHook(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:322
LRESULT APIENTRY co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:1103
BOOL IntLoadHookModule(int iHookID, HHOOK hHook, BOOL Unload)
Definition: hook.c:31
PWND APIENTRY co_WinPosWindowFromPoint(IN PWND ScopeWin, IN POINT *WinPoint, IN OUT USHORT *HitTest, IN BOOL Ignore)
Definition: winpos.c:2934
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:254
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:238
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:245
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:40
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:27
#define LOWORD(l)
Definition: pedump.c:82
#define ES_PASSWORD
Definition: pedump.c:670
#define WS_CHILD
Definition: pedump.c:617
#define WS_EX_NOPARENTNOTIFY
Definition: pedump.c:646
#define WS_VISIBLE
Definition: pedump.c:620
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
#define WS_EX_TRANSPARENT
Definition: pedump.c:649
unsigned short USHORT
Definition: pedump.c:61
static ULONG Timeout
Definition: ping.c:61
#define WM_MOUSELEAVE
Definition: commctrl.h:4975
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define WM_CONTEXTMENU
Definition: richedit.h:64
#define WM_NOTIFY
Definition: richedit.h:61
#define STATUS_SUCCESS
Definition: shellext.h:65
static void Exit(void)
Definition: sock.c:1330
#define TRACE(s)
Definition: solgame.cpp:4
DWORD dwTime
Definition: solitaire.cpp:26
base of all file and directory entries
Definition: entries.h:83
Definition: window.c:28
RTL_ATOM atomClassName
Definition: ntuser.h:563
UINT style
Definition: ntuser.h:575
HBITMAP hbmColor
Definition: cursoricon.h:20
HBITMAP hbmMask
Definition: cursoricon.h:19
ULONG CURSORF_flags
Definition: cursoricon.h:16
HBITMAP hbmAlpha
Definition: cursoricon.h:21
DWORD dwMouseHoverTime
Definition: desktop.h:34
struct _USER_MESSAGE_QUEUE * ActiveMessageQueue
Definition: desktop.h:38
PWND spwndTrack
Definition: desktop.h:31
DWORD htEx
Definition: desktop.h:32
RECT rcMouseHover
Definition: desktop.h:33
DWORD dwDTFlags
Definition: desktop.h:12
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
INT iMouseHoverWidth
Definition: sysparams.h:85
BOOL bMouseBtnSwap
Definition: sysparams.h:82
INT iDblClickTime
Definition: sysparams.h:90
DWORD dwMouseClickLockTime
Definition: sysparams.h:79
BOOL bMouseClickLock
Definition: sysparams.h:77
INT iMouseHoverHeight
Definition: sysparams.h:86
PCURICON_OBJECT CurrentCursorObject
Definition: cursoricon.h:74
struct _DESKTOP * rpdesk
Definition: ntuser.h:194
struct _USER_SENT_MESSAGE * pusmCurrent
Definition: win32.h:98
PPROCESSINFO ppi
Definition: win32.h:88
INT cEnterCount
Definition: win32.h:135
INT exitCode
Definition: win32.h:107
LIST_ENTRY PostedMessagesListHead
Definition: win32.h:137
DWORD nCntsQBits[QSIDCOUNTS]
Definition: win32.h:153
struct _USER_SENT_MESSAGE * pusmSent
Definition: win32.h:97
PKEVENT pEventQueueServer
Definition: win32.h:125
BOOLEAN QuitPosted
Definition: win32.h:105
INT iCursorLevel
Definition: win32.h:127
struct tagKL * KeyboardLayout
Definition: win32.h:90
LONG timeLast
Definition: win32.h:102
struct _CLIENTTHREADINFO * pcti
Definition: win32.h:91
UINT cTimersReady
Definition: win32.h:110
HANDLE hEventQueueClient
Definition: win32.h:123
FLONG TIF_flags
Definition: win32.h:95
LIST_ENTRY SentMessagesListHead
Definition: win32.h:100
WCHAR wchInjected
Definition: win32.h:139
UINT cPaintsReady
Definition: win32.h:109
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:89
BYTE afKeyState[256 *2/8]
Definition: msgqueue.h:84
ULONG_PTR idSysPeek
Definition: msgqueue.h:54
PTHREADINFO ptiSysLock
Definition: msgqueue.h:52
PTHREADINFO ptiMouse
Definition: msgqueue.h:55
LIST_ENTRY HardwareMessagesListHead
Definition: msgqueue.h:59
THRDCARETINFO CaretInfo
Definition: msgqueue.h:92
struct _DESKTOP * Desktop
Definition: msgqueue.h:50
PCURICON_OBJECT CursorObject
Definition: msgqueue.h:89
PTHREADINFO ptiKeyboard
Definition: msgqueue.h:56
BYTE afKeyRecentDown[256/8]
Definition: msgqueue.h:83
PTHREADINFO pti
Definition: msgqueue.h:15
DWORD QS_Flags
Definition: msgqueue.h:12
LONG_PTR ExtraInfo
Definition: msgqueue.h:13
DWORD dwQEvent
Definition: msgqueue.h:14
Definition: object.h:4
BOOL HasPackedLParam
Definition: msgqueue.h:34
PTHREADINFO ptiReceiver
Definition: msgqueue.h:29
PTHREADINFO ptiCallBackSender
Definition: msgqueue.h:31
PKEVENT pkCompletionEvent
Definition: msgqueue.h:25
PTHREADINFO ptiSender
Definition: msgqueue.h:28
Definition: ntuser.h:689
DWORD ExStyle
Definition: ntuser.h:699
PCLS pcls
Definition: ntuser.h:715
THRDESKHEAD head
Definition: ntuser.h:690
DWORD style
Definition: ntuser.h:701
DWORD state2
Definition: ntuser.h:697
struct _WND * spwndChild
Definition: ntuser.h:709
RECT rcClient
Definition: ntuser.h:712
DWORD state
Definition: ntuser.h:696
struct _WND * spwndNext
Definition: ntuser.h:706
Definition: copy.c:22
Definition: tftpd.h:60
Definition: input.h:27
DWORD dwFontSigs
Definition: input.h:34
HKL hkl
Definition: input.h:32
ULONG_PTR dwExtraInfo
Definition: winuser.h:3811
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
ATOM atomSysClass[ICLS_NOTUSED+1]
Definition: ntuser.h:1055
#define _PRAGMA_WARNING_SUPPRESS(x)
Definition: suppress.h:28
#define __WARNING_USING_UNINIT_VAR
Definition: suppress.h:31
BOOLEAN NTAPI KeSetKernelStackSwapEnable(IN BOOLEAN Enable)
Definition: thrdobj.c:997
#define WM_MOUSEWHEEL
Definition: treelist.c:96
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int32_t INT_PTR
Definition: typedefs.h:64
unsigned char * LPBYTE
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
#define OUT
Definition: typedefs.h:40
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IPHK_SKIPTHISKEY
Definition: undocuser.h:142
#define IPHK_HOTKEY
Definition: undocuser.h:139
#define IPHK_PROCESSBYIME
Definition: undocuser.h:140
#define QS_SMRESULT
Definition: undocuser.h:95
#define QS_EVENT
Definition: undocuser.h:97
#define UserEnterCo
Definition: ntuser.h:8
#define UserLeaveCo
Definition: ntuser.h:9
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:134
int ret
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2225
#define W32PF_APPSTARTING
Definition: win32.h:10
@ QSRosMouseMove
Definition: win32.h:42
@ QSRosKey
Definition: win32.h:41
@ QSRosEvent
Definition: win32.h:47
@ QSRosHotKey
Definition: win32.h:46
@ QSRosSendMessage
Definition: win32.h:45
@ QSRosPostMessage
Definition: win32.h:44
@ QSRosMouseButton
Definition: win32.h:43
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:37
ULONG NTAPI GreSetPointerShape(_In_ HDC hdc, _In_opt_ HBITMAP hbmMask, _In_opt_ HBITMAP hbmColor, _In_ LONG xHot, _In_ LONG yHot, _In_ LONG x, _In_ LONG y, _In_ FLONG fl)
Definition: mouse.c:703
VOID NTAPI GreMovePointer(_In_ HDC hdc, _In_ LONG x, _In_ LONG y)
Definition: mouse.c:799
FORCEINLINE VOID RECTL_vSetRect(_Out_ RECTL *prcl, _In_ LONG left, _In_ LONG top, _In_ LONG right, _In_ LONG bottom)
Definition: rect.h:5
FORCEINLINE BOOL RECTL_bPointInRect(_In_ const RECTL *prcl, _In_ INT x, _In_ INT y)
Definition: rect.h:52
VOID APIENTRY co_IntCallSentMessageCallback(SENDASYNCPROC CompletionCallback, HWND hWnd, UINT Msg, ULONG_PTR CompletionCallbackContext, LRESULT Result)
Definition: callback.c:238
VOID FASTCALL co_IntDeliverUserAPC(VOID)
Definition: callback.c:1157
PCURICON_OBJECT IntSystemSetCursor(PCURICON_OBJECT pcurNew)
Definition: cursoricon.c:230
PSYSTEM_CURSORINFO IntGetSysCursorInfo(VOID)
Definition: cursoricon.c:187
PWND FASTCALL UserGetDesktopWindow(VOID)
Definition: desktop.c:1386
VOID FASTCALL IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue)
Definition: desktop.c:1319
HWND FASTCALL IntGetDesktopWindow(VOID)
Definition: desktop.c:1374
#define DF_TME_LEAVE
Definition: desktop.h:48
#define DF_TME_HOVER
Definition: desktop.h:47
HDC FASTCALL IntGetScreenDC(VOID)
Definition: winsta.c:371
VOID FASTCALL IntNotifyWinEvent(DWORD Event, PWND pWnd, LONG idObject, LONG idChild, DWORD flags)
Definition: event.c:179
UINT FASTCALL IntImmProcessKey(PUSER_MESSAGE_QUEUE MessageQueue, PWND pWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: ime.c:585
VOID FASTCALL DoTheScreenSaver(VOID)
Definition: input.c:48
#define SET_KEY_DOWN(ks, vk, down)
Definition: input.h:101
#define KS_DOWN_BIT
Definition: input.h:54
DWORD gSystemFS
Definition: kbdlayout.c:24
BYTE gafAsyncKeyState[256 *2/8]
Definition: keyboard.c:13
DWORD gdwLanguageToggleKey
Definition: keyboard.c:19
#define IS_KEY_DOWN(ks, vk)
Definition: input.h:99
int gLanguageToggleKeyState
Definition: keyboard.c:18
#define KS_LOCK_BIT
Definition: input.h:55
#define IS_KEY_LOCKED(ks, vk)
Definition: input.h:100
#define SET_KEY_LOCKED(ks, vk, down)
Definition: input.h:104
VOID FASTCALL IdlePing(VOID)
Definition: message.c:527
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1346
VOID FASTCALL IdlePong(VOID)
Definition: message.c:557
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1446
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:208
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:644
VOID FASTCALL UserReferenceObject(PVOID obj)
Definition: object.c:731
SPIVALUES gspv
Definition: sysparams.c:17
#define TAG_USRMSG
Definition: tags.h:8
#define USERTAG_Q
Definition: tags.h:269
#define TAG_HOOK
Definition: tags.h:5
VOID CALLBACK SystemTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Definition: timer.c:280
BOOL FASTCALL IntKillTimer(PWND Window, UINT_PTR IDEvent, BOOL SystemTimer)
Definition: timer.c:573
UINT_PTR FASTCALL IntSetTimer(PWND Window, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, INT Type)
Definition: timer.c:177
#define TMRF_SYSTEM
Definition: timer.h:20
#define ID_EVENT_SYSTIMER_MOUSEHOVER
Definition: timer.h:27
PWND FASTCALL IntGetParent(PWND Wnd)
Definition: window.c:216
PWND FASTCALL IntGetNonChildAncestor(PWND pWnd)
Definition: window.c:363
#define OBJID_CLIENT
Definition: winable.h:19
#define CHILDID_SELF
Definition: winable.h:14
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define SPS_ALPHA
Definition: winddi.h:4039
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:28
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
FORCEINLINE BOOL IntPtInWindow(PWND pwnd, INT x, INT y)
Definition: winpos.h:30
#define HC_NOREMOVE
Definition: winuser.h:51
#define MK_RBUTTON
Definition: winuser.h:2358
#define WH_KEYBOARD
Definition: winuser.h:32
#define MAKEWPARAM(l, h)
Definition: winuser.h:3999
#define QS_KEY
Definition: winuser.h:868
#define MK_SHIFT
Definition: winuser.h:2359
void(CALLBACK * SENDASYNCPROC)(HWND, UINT, ULONG_PTR, LRESULT)
Definition: winuser.h:2906
#define WM_SYSCOMMAND
Definition: winuser.h:1731
#define QS_MOUSEMOVE
Definition: winuser.h:869
#define QS_SENDMESSAGE
Definition: winuser.h:874
#define VK_TAB
Definition: winuser.h:2189
#define WM_MOUSEFIRST
Definition: winuser.h:1764
#define SM_CXDOUBLECLK
Definition: winuser.h:993
#define WM_QUIT
Definition: winuser.h:1613
#define VK_APPS
Definition: winuser.h:2227
#define MAKELPARAM(l, h)
Definition: winuser.h:3998
#define WM_KEYUP
Definition: winuser.h:1706
#define WM_MOUSELAST
Definition: winuser.h:1791
#define QS_TIMER
Definition: winuser.h:872
#define WM_CREATE
Definition: winuser.h:1598
#define EM_SETPASSWORDCHAR
Definition: winuser.h:2004
#define SC_PREVWINDOW
Definition: winuser.h:2581
#define HTERROR
Definition: winuser.h:2462
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1768
#define KF_ALTDOWN
Definition: winuser.h:2439
#define MA_ACTIVATE
Definition: winuser.h:2491
#define VK_RBUTTON
Definition: winuser.h:2181
#define WM_APPCOMMAND
Definition: winuser.h:1872
#define WM_KEYFIRST
Definition: winuser.h:1704
#define VK_CONTROL
Definition: winuser.h:2193
#define HC_ACTION
Definition: winuser.h:48
#define WM_RBUTTONUP
Definition: winuser.h:1770
#define VK_RSHIFT
Definition: winuser.h:2273
#define WM_RBUTTONDBLCLK
Definition: winuser.h:1771
#define VK_PROCESSKEY
Definition: winuser.h:2317
#define SM_CYDOUBLECLK
Definition: winuser.h:994
#define QS_ALLPOSTMESSAGE
Definition: winuser.h:876
#define WM_MOUSEMOVE
Definition: winuser.h:1765
#define VK_MBUTTON
Definition: winuser.h:2183
#define WM_GETTEXT
Definition: winuser.h:1608
#define MA_NOACTIVATE
Definition: winuser.h:2493
#define CS_DBLCLKS
Definition: winuser.h:646
#define VK_LSHIFT
Definition: winuser.h:2272
#define WM_LBUTTONDOWN
Definition: winuser.h:1766
#define WH_CBT
Definition: winuser.h:35
#define VK_LCONTROL
Definition: winuser.h:2274
#define VK_F1
Definition: winuser.h:2245
#define WM_NCCREATE
Definition: winuser.h:1673
#define VK_RCONTROL
Definition: winuser.h:2275
#define MWMO_INPUTAVAILABLE
Definition: winuser.h:904
#define WM_RBUTTONDOWN
Definition: winuser.h:1769
#define QS_HOTKEY
Definition: winuser.h:875
#define SC_NEXTWINDOW
Definition: winuser.h:2580
#define WM_NCMOUSEMOVE
Definition: winuser.h:1681
#define WH_MOUSE_LL
Definition: winuser.h:44
#define MK_MBUTTON
Definition: winuser.h:2361
#define QS_MOUSEBUTTON
Definition: winuser.h:870
#define EM_GETLINE
Definition: winuser.h:1981
#define WH_MOUSE
Definition: winuser.h:37
#define MK_CONTROL
Definition: winuser.h:2360
#define VK_RMENU
Definition: winuser.h:2277
#define HCBT_CLICKSKIPPED
Definition: winuser.h:61
#define QS_INPUT
Definition: winuser.h:893
#define HTCLIENT
Definition: winuser.h:2465
#define WM_MBUTTONDBLCLK
Definition: winuser.h:1774
#define QS_MOUSE
Definition: winuser.h:886
#define WM_SYSKEYUP
Definition: winuser.h:1710
#define HTNOWHERE
Definition: winuser.h:2464
#define WM_MOUSEACTIVATE
Definition: winuser.h:1627
#define WS_EX_LAYERED
Definition: winuser.h:389
#define WM_LBUTTONUP
Definition: winuser.h:1767
#define QS_POSTMESSAGE
Definition: winuser.h:871
#define MA_NOACTIVATEANDEAT
Definition: winuser.h:2494
#define WM_SETCURSOR
Definition: winuser.h:1626
#define WM_HOTKEY
Definition: winuser.h:1869
#define MK_LBUTTON
Definition: winuser.h:2357
#define QS_PAINT
Definition: winuser.h:873
#define VK_SHIFT
Definition: winuser.h:2192
#define WM_KEYDOWN
Definition: winuser.h:1705
#define WM_PARENTNOTIFY
Definition: winuser.h:1793
#define WM_NCMOUSELEAVE
Definition: winuser.h:1832
#define WM_MBUTTONUP
Definition: winuser.h:1773
#define WM_KEYLAST
Definition: winuser.h:1718
#define VK_ESCAPE
Definition: winuser.h:2204
#define WM_SYSKEYDOWN
Definition: winuser.h:1709
#define WH_JOURNALRECORD
Definition: winuser.h:30
#define HCBT_KEYSKIPPED
Definition: winuser.h:62
#define WM_MBUTTONDOWN
Definition: winuser.h:1772
#define MA_ACTIVATEANDEAT
Definition: winuser.h:2492
#define VK_LMENU
Definition: winuser.h:2276
#define VK_MENU
Definition: winuser.h:2194
#define VK_LBUTTON
Definition: winuser.h:2180
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
struct LOOKASIDE_ALIGN _PAGED_LOOKASIDE_LIST PAGED_LOOKASIDE_LIST
struct LOOKASIDE_ALIGN _PAGED_LOOKASIDE_LIST * PPAGED_LOOKASIDE_LIST
#define IO_NO_INCREMENT
Definition: iotypes.h:598
@ UserRequest
Definition: ketypes.h:409
_In_ BOOLEAN Remove
Definition: psfuncs.h:110
#define NT_ASSERT
Definition: rtlfuncs.h:3310
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned char BYTE
Definition: xxhash.c:193