00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
#include "precomp.h"
00014
#pragma hdrstop
00015
00016
00017
#ifdef MARKPATH
00018
BOOL gfMarkPath;
00019
#endif
00020
00021
#if DEBUGTAGS
00022
00023
int gnSysPeekSearch;
00024
00025
void CheckPtiSysPeek(
int where,
PQ pq, ULONG_PTR newIdSysPeek)
00026 {
00027
PTHREADINFO ptiCurrent =
PtiCurrent();
00028
DWORD dwRip;
00029
00030 dwRip = (newIdSysPeek > 1) ? RIP_THERESMORE : 0;
00031 TAGMSG5(DBGTAG_SysPeek | dwRip,
00032
"%d pti %#p sets id %#p to pq %#p ; old id %#p",
00033 where, ptiCurrent, newIdSysPeek, pq, pq->
idSysPeek);
00034
00035
if (newIdSysPeek > 1) {
00036
PQMSG pqmsg = (
PQMSG)newIdSysPeek;
00037 TAGMSG5(DBGTAG_SysPeek | RIP_NONAME,
00038
"-> msg %lx hwnd %#p w %#p l %#p pti %#p",
00039 pqmsg->
msg.message, pqmsg->
msg.hwnd, pqmsg->
msg.wParam,
00040 pqmsg->
msg.lParam, pqmsg->
pti);
00041 }
00042 }
00043
00044
void CheckSysLock(
int where,
PQ pq,
PTHREADINFO ptiSysLock)
00045 {
00046
PTHREADINFO ptiCurrent =
PtiCurrent();
00047 TAGMSG5(DBGTAG_SysPeek,
00048
"%d pti %#p sets ptiSL %#p to pq %#p ; old ptiSL %#p\n",
00049 where, ptiCurrent, ptiSysLock, pq, pq->
ptiSysLock);
00050 }
00051
#endif //DEBUGTAGS
00052
00053
#if DBG
00054
BOOL gfLogPlayback;
00055
00056 LPCSTR aszMouse[] = {
00057
"WM_MOUSEMOVE",
00058
"WM_LBUTTONDOWN",
00059
"WM_LBUTTONUP",
00060
"WM_LBUTTONDBLCLK",
00061
"WM_RBUTTONDOWN",
00062
"WM_RBUTTONUP",
00063
"WM_RBUTTONDBLCLK",
00064
"WM_MBUTTONDOWN",
00065
"WM_MBUTTONUP",
00066
"WM_MBUTTONDBLCLK"
00067
"WM_MOUSEWHEEL",
00068
"WM_XBUTTONDOWN",
00069
"WM_XBUTTONUP",
00070
"WM_XBUTTONDBLCLK",
00071 };
00072 LPCSTR aszKey[] = {
00073
"WM_KEYDOWN",
00074
"WM_KEYUP",
00075
"WM_CHAR",
00076
"WM_DEADCHAR",
00077
"WM_SYSKEYDOWN",
00078
"WM_SYSKEYUP",
00079
"WM_SYSCHAR",
00080
"WM_SYSDEADCHAR"
00081 };
00082
#endif // DBG
00083
00084 #define CANCEL_ACTIVESTATE 0
00085 #define CANCEL_FOCUSSTATE 1
00086 #define CANCEL_CAPTURESTATE 2
00087
00088 #define KEYSTATESIZE (CBKEYSTATE + CBKEYSTATERECENTDOWN)
00089
00090
00091
00092
00093
00094 #define PQMSG_PLAYBACK ((PQMSG)1)
00095
00096
BOOL xxxScanSysQueue(
PTHREADINFO ptiCurrent, LPMSG lpMsg,
PWND pwndFilter,
00097 UINT msgMinFilter, UINT msgMaxFilter, DWORD flags, DWORD fsReason);
00098
BOOL xxxReadPostMessage(
PTHREADINFO pti, LPMSG lpMsg,
PWND pwndFilter,
00099 UINT msgMin, UINT msgMax, BOOL fRemoveMsg);
00100
void CleanEventMessage(
PQMSG pqmsg);
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 BOOL xxxWaitMessage(VOID)
00113 {
00114
return xxxSleepThread(QS_ALLINPUT | QS_EVENT, 0,
TRUE);
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 void CheckProcessForeground(
00156
PTHREADINFO pti)
00157 {
00158
PTHREADINFO ptiT;
00159
00160
00161
00162
00163
00164 pti->
pClientInfo->
cSpins = 0;
00165 pti->
TIF_flags &= ~
TIF_SPINNING;
00166 pti->
pClientInfo->
dwTIFlags = pti->
TIF_flags;
00167
00168
if (pti->
ppi->W32PF_Flags & W32PF_FORCEBACKGROUNDPRIORITY) {
00169
00170
00171
00172
00173
for (ptiT = pti->
ppi->
ptiList; ptiT !=
NULL; ptiT = ptiT->
ptiSibling) {
00174
if (ptiT->
TIF_flags &
TIF_SPINNING)
00175
return;
00176 }
00177
00178 pti->
ppi->W32PF_Flags &= ~W32PF_FORCEBACKGROUNDPRIORITY;
00179
if (pti->
ppi ==
gppiWantForegroundPriority) {
00180
SetForegroundPriority(pti,
TRUE);
00181 }
00182 }
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 BOOL xxxInternalGetMessage(
00214 LPMSG lpMsg,
00215 HWND hwndFilter,
00216 UINT msgMin,
00217 UINT msgMax,
00218 UINT flags,
00219 BOOL fGetMessage)
00220 {
00221
UINT fsWakeBits;
00222
UINT fsWakeMask;
00223
UINT fsRemoveBits;
00224
PTHREADINFO ptiCurrent;
00225 PW32PROCESS W32Process;
00226
PWND pwndFilter;
00227
BOOL fLockPwndFilter;
00228
TL tlpwndFilter;
00229
BOOL fRemove;
00230
BOOL fExit;
00231
PQ pq;
00232
#ifdef MARKPATH
00233
DWORD pathTaken = 0;
00234
00235
#define PATHTAKEN(x) pathTaken |= x
00236
#define DUMPPATHTAKEN() if (gfMarkPath) DbgPrint("xxxInternalGetMessage path:%08x\n", pathTaken)
00237
#else
00238
#define PATHTAKEN(x)
00239
#define DUMPPATHTAKEN()
00240
#endif
00241
00242
CheckCritIn();
00243 UserAssert(
IsWinEventNotifyDeferredOK());
00244
00245 ptiCurrent =
PtiCurrent();
00246
00247
00248
00249
00250
00251
00252
00253
if ((hwndFilter == (HWND)-1) || (hwndFilter == (HWND)0x0000FFFF)) {
00254 hwndFilter = (HWND)1;
00255 }
00256
00257
if ((hwndFilter !=
NULL) && (hwndFilter != (HWND)1)) {
00258
if ((pwndFilter =
ValidateHwnd(hwndFilter)) ==
NULL) {
00259 lpMsg->hwnd =
NULL;
00260 lpMsg->message = WM_NULL;
00261
PATHTAKEN(1);
00262
DUMPPATHTAKEN();
00263
if (fGetMessage)
00264
return -1;
00265
else
00266
return 0;
00267 }
00268
00269
ThreadLockAlwaysWithPti(ptiCurrent, pwndFilter, &tlpwndFilter);
00270 fLockPwndFilter =
TRUE;
00271
00272 }
else {
00273 pwndFilter = (
PWND)hwndFilter;
00274 fLockPwndFilter =
FALSE;
00275 }
00276
00277
00278
00279
00280
00281
00282 ptiCurrent->
pClientInfo->
cSpins++;
00283
00284
00285
00286
00287 W32Process = W32GetCurrentProcess();
00288
if (W32Process->W32PF_Flags & W32PF_STARTGLASS) {
00289
00290
00291
00292
00293
00294 W32Process->W32PF_Flags &= ~W32PF_STARTGLASS;
00295
00296
00297
00298
zzzCalcStartCursorHide(
NULL, 0);
00299 }
00300
00301
00302
00303
00304
00305
if (ptiCurrent->
ppi->
cSysExpunge !=
gcSysExpunge) {
00306 ptiCurrent->
ppi->
cSysExpunge =
gcSysExpunge;
00307
if (ptiCurrent->
ppi->
dwhmodLibLoadedMask &
gdwSysExpungeMask)
00308
xxxDoSysExpunge(ptiCurrent);
00309 }
00310
00311
00312
00313
00314 fRemove = flags & PM_REMOVE;
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 pq = ptiCurrent->
pq;
00330
if ( (ptiCurrent->
psmsCurrent !=
NULL)
00331 || (pq->
ptiSysLock == ptiCurrent && pq->
idSysLock == ptiCurrent->
idLast)
00332 ) {
00333
CheckSysLock(1, pq,
NULL);
00334 pq->
ptiSysLock =
NULL;
00335
PATHTAKEN(2);
00336 }
else if (pq->
ptiSysLock
00337 && (pq->
ptiSysLock->
cVisWindows == 0)
00338 && (
PhkFirstGlobalValid(ptiCurrent, WH_JOURNALPLAYBACK) !=
NULL)) {
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
CheckSysLock(2, pq,
NULL);
00352 pq->
ptiSysLock =
NULL;
00353
PATHTAKEN(3);
00354 }
00355
if (pq->
ptiSysLock != ptiCurrent) {
00356 ptiCurrent->
pcti->
CTIF_flags &= ~
CTIF_SYSQUEUELOCKED;
00357 }
00358
00359
00360
00361
00362
00363
if (msgMax == 0)
00364 msgMax--;
00365
00366
00367
00368
00369
00370 fsWakeMask =
CalcWakeMask(msgMin, msgMax, HIWORD(flags));
00371 ptiCurrent->
fsChangeBitsRemoved = 0;
00372
00373
00374
00375
00376
00377
if (!(flags & PM_NOYIELD) && ptiCurrent->
TIF_flags &
TIF_DELAYEDEVENT) {
00378 ptiCurrent->
pcti->
fsWakeBits |= QS_EVENT;
00379 ptiCurrent->
pcti->
fsChangeBits |= QS_EVENT;
00380 ptiCurrent->
TIF_flags &= ~
TIF_DELAYEDEVENT;
00381 ptiCurrent->
pClientInfo->
dwTIFlags = ptiCurrent->
TIF_flags;
00382 }
00383
00384
while (
TRUE) {
00385
00386
00387
00388
00389 ptiCurrent->
pcti->
fsWakeBits |= ptiCurrent->
pcti->
fsWakeBitsJournal;
00390
00391
00392
00393
00394
00395
00396
if (ptiCurrent->
rpdesk ==
gpdeskRecalcQueueAttach) {
00397
gpdeskRecalcQueueAttach =
NULL;
00398
00399
if (ptiCurrent->
rpdesk !=
NULL && !
FJOURNALRECORD() && !
FJOURNALPLAYBACK()) {
00400
00401
00402
00403
00404
zzzReattachThreads(
FALSE);
00405
PATHTAKEN(4);
00406 }
00407 }
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 fsRemoveBits = fsWakeMask & ~QS_SENDMESSAGE;
00432 ptiCurrent->
fsChangeBitsRemoved |= ptiCurrent->
pcti->
fsChangeBits & fsRemoveBits;
00433
00434
00435
00436
00437
00438
00439 ptiCurrent->
pcti->
fsChangeBits &= ~fsRemoveBits;
00440
00441
00442
00443
00444
00445
if (ptiCurrent->
pcti->
fsWakeBits & fsWakeMask & QS_SENDMESSAGE) {
00446
xxxReceiveMessages(ptiCurrent);
00447 }
else if (ptiCurrent->
pcti->
fsWakeBits & QS_SENDMESSAGE) {
00448 RIPMSG2(RIP_WARNING,
"xxxInternalGetMessage:(1st test) sendmsgs pending. Bits:%#lx Mask:%#lx",
00449 ptiCurrent->
pcti->
fsWakeBits, fsWakeMask);
00450
goto NoMessages;
00451 }
00452
00453
00454
00455
00456
if ((ptiCurrent->
pcti->
fsWakeBits & fsWakeMask) == 0) {
00457
PATHTAKEN(8);
00458
goto NoMessages;
00459 }
00460 fsWakeBits = ptiCurrent->
pcti->
fsWakeBits;
00461
00462
00463
00464
00465
00466
00467
00468
00469
if (ptiCurrent->
pq->
ptiSysLock == ptiCurrent &&
00470 (ptiCurrent->
pq->
QF_flags &
QF_LOCKNOREMOVE)) {
00471
00472
00473
00474
if (fsWakeBits & fsWakeMask & (QS_INPUT | QS_EVENT)) {
00475
00476
00477
00478
00479 UserAssert(
gbExitInProgress ==
FALSE);
00480
00481
if (
xxxScanSysQueue(ptiCurrent, lpMsg, pwndFilter,
00482 msgMin, msgMax, flags,
00483 fsWakeBits & fsWakeMask & (QS_INPUT | QS_EVENT))) {
00484
00485
PATHTAKEN(0x10);
00486
break;
00487 }
00488 }
else if (fsWakeBits & QS_EVENT) {
00489 RIPMSG2(RIP_WARNING,
00490
"xxxInternalGetMessage:(1st test)events pending. Bits:%#lx Mask:%#lx",
00491 fsWakeBits, fsWakeMask);
00492
goto NoMessages;
00493 }
00494 }
00495
00496
00497
00498
00499
if (fsWakeBits & fsWakeMask & QS_POSTMESSAGE) {
00500
if (
xxxReadPostMessage(ptiCurrent, lpMsg, pwndFilter,
00501 msgMin, msgMax, fRemove)) {
00502
PATHTAKEN(0x20);
00503
break;
00504 }
00505 }
00506
00507
00508
00509
00510
00511
if (fsWakeBits & fsWakeMask & (QS_INPUT | QS_EVENT)) {
00512
00513
00514
00515
00516 UserAssert(
gbExitInProgress ==
FALSE);
00517
00518
if (
xxxScanSysQueue(ptiCurrent, lpMsg, pwndFilter,
00519 msgMin, msgMax, flags,
00520 fsWakeBits & fsWakeMask & (QS_INPUT | QS_EVENT))) {
00521
PATHTAKEN(0x40);
00522
break;
00523 }
00524 }
else if (fsWakeBits & QS_EVENT) {
00525 RIPMSG2(RIP_WARNING,
"xxxInternalGetMessage:(2nd test)events pending. Bits:%#lx Mask:%#lx",
00526 fsWakeBits, fsWakeMask);
00527
goto NoMessages;
00528 }
00529
00530
00531
00532
00533
00534
if (ptiCurrent->
pcti->
fsWakeBits & fsWakeMask & QS_SENDMESSAGE) {
00535
xxxReceiveMessages(ptiCurrent);
00536 }
else if (ptiCurrent->
pcti->
fsWakeBits & QS_SENDMESSAGE) {
00537 RIPMSG2(RIP_WARNING,
"xxxInternalGetMessage:(2nd test)sendmsgs pending. Bits:%#lx Mask:%#lx",
00538 ptiCurrent->
pcti->
fsWakeBits, fsWakeMask);
00539
goto NoMessages;
00540 }
00541
00542
00543
00544
00545
if ((ptiCurrent->
pcti->
fsWakeBits & fsWakeMask) == 0) {
00546
PATHTAKEN(0x80);
00547
goto NoMessages;
00548 }
00549 fsWakeBits = ptiCurrent->
pcti->
fsWakeBits;
00550
00551
00552
00553
00554
if (fsWakeBits & fsWakeMask & QS_PAINT) {
00555
if (
DoPaint(pwndFilter, lpMsg)) {
00556
PATHTAKEN(0x100);
00557
break;
00558 }
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
if (!(flags & PM_NOYIELD)) {
00571
00572
00573
00574
00575
zzzWakeInputIdle(ptiCurrent);
00576
00577
00578
00579
00580
xxxUserYield(ptiCurrent);
00581
00582
00583
00584
00585
if (ptiCurrent->
pcti->
fsWakeBits & fsWakeMask & QS_SENDMESSAGE) {
00586
xxxReceiveMessages(ptiCurrent);
00587 }
else if (ptiCurrent->
pcti->
fsWakeBits & QS_SENDMESSAGE) {
00588 RIPMSG2(RIP_WARNING,
"xxxInternalGetMessage:(3rd test) sendmsgs pending. Bits:%#lx Mask:%#lx",
00589 ptiCurrent->
pcti->
fsWakeBits, fsWakeMask);
00590
goto NoMessages;
00591 }
00592
00593
if ((ptiCurrent->
pcti->
fsWakeBits & fsWakeMask) == 0) {
00594
00595
PATHTAKEN(0x200);
00596
goto NoMessages;
00597 }
00598 fsWakeBits = ptiCurrent->
pcti->
fsWakeBits;
00599 }
00600
00601
00602
00603
00604
if (fsWakeBits & fsWakeMask & QS_TIMER) {
00605
if (
DoTimer(pwndFilter)) {
00606
00607
00608
00609
00610
PATHTAKEN(0x400);
00611
continue;
00612 }
00613 }
00614
00615 NoMessages:
00616
00617
00618
00619
00620
if (!fGetMessage) {
00621
00622
00623
00624
00625
if (!(flags & PM_NOYIELD)) {
00626
00627
00628
00629
00630
zzzWakeInputIdle(ptiCurrent);
00631
00632
00633
00634
00635
xxxUserYield(ptiCurrent);
00636 }
00637
PATHTAKEN(0x800);
00638
goto FalseExit;
00639 }
00640
00641
00642
00643
00644
00645
00646
if (!
xxxSleepThread(fsWakeMask, 0,
TRUE))
00647
goto FalseExit;
00648 }
00649
00650
00651
00652
00653
00654
if (
IsHooked(ptiCurrent,
WHF_GETMESSAGE))
00655
xxxCallHook(HC_ACTION, flags, (LPARAM)lpMsg, WH_GETMESSAGE);
00656
00657
00658
00659
00660
if (!fGetMessage) {
00661
PATHTAKEN(0x1000);
00662
goto TrueExit;
00663 }
00664
00665
00666
00667
00668
00669
if (lpMsg->message == WM_QUIT) {
00670
PATHTAKEN(0x2000);
00671
goto FalseExit;
00672 }
00673
00674
00675
00676
00677
00678 TrueExit:
00679
00680
00681
00682
SET_TIME_LAST_READ(ptiCurrent);
00683 fExit =
TRUE;
00684
PATHTAKEN(0x4000);
00685
goto Exit;
00686
00687 FalseExit:
00688 fExit =
FALSE;
00689
00690 Exit:
00691
if (fLockPwndFilter)
00692
ThreadUnlock(&tlpwndFilter);
00693
00694
00695
00696
00697
00698
00699
if (ptiCurrent->
pClientInfo->
cSpins >=
CSPINBACKGROUND) {
00700
00701 ptiCurrent->
pClientInfo->
cSpins = 0;
00702
00703
if (!(ptiCurrent->
TIF_flags &
TIF_SPINNING)) {
00704
00705 ptiCurrent->
TIF_flags |=
TIF_SPINNING;
00706 ptiCurrent->
pClientInfo->
dwTIFlags = ptiCurrent->
TIF_flags;
00707
00708
if (!(ptiCurrent->
ppi->W32PF_Flags & W32PF_FORCEBACKGROUNDPRIORITY)) {
00709
00710 ptiCurrent->
ppi->W32PF_Flags |= W32PF_FORCEBACKGROUNDPRIORITY;
00711
00712
if (ptiCurrent->
ppi ==
gppiWantForegroundPriority) {
00713
SetForegroundPriority(ptiCurrent,
FALSE);
00714 }
00715 }
00716 }
00717
00718
00719
00720
00721
00722
00723
00724
00725
if (ptiCurrent->
TIF_flags &
TIF_16BIT) {
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
xxxSleepTask(
FALSE,
HEVENT_REMOVEME);
00736
00737
LeaveCrit();
00738 ZwYieldExecution();
00739
CheckForClientDeath();
00740
EnterCrit();
00741
00742
xxxDirectedYield(DY_OLDYIELD);
00743 }
00744 }
00745
00746
PATHTAKEN(0x8000);
00747
DUMPPATHTAKEN();
00748
return fExit;
00749 }
00750
#undef PATHTAKEN
00751
#undef DUMPPATHTAKEN
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762 LRESULT
xxxDispatchMessage(
00763 LPMSG pmsg)
00764 {
00765 LRESULT lRet;
00766
PWND pwnd;
00767
WNDPROC_PWND lpfnWndProc;
00768
TL tlpwnd;
00769
00770 pwnd =
NULL;
00771
if (pmsg->hwnd !=
NULL) {
00772
if ((pwnd =
ValidateHwnd(pmsg->hwnd)) ==
NULL)
00773
return 0;
00774 }
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
if (
TESTSYNCONLYMESSAGE(pmsg->message, pmsg->wParam)) {
00786
00787
00788
00789
if (!(
PtiCurrent()->TIF_flags &
TIF_16BIT)) {
00790 RIPERR1(ERROR_MESSAGE_SYNC_ONLY, RIP_WARNING,
"xxxDispatchMessage: Sync only message 0x%lX",
00791 pmsg->message);
00792
return 0;
00793 }
00794
00795
00796
00797
00798
00799
00800
00801 pmsg->message |=
MSGFLAG_WOW_RESERVED;
00802 }
00803
00804
ThreadLock(pwnd, &tlpwnd);
00805
00806
00807
00808
00809
00810
if ((pmsg->message == WM_TIMER) || (pmsg->message ==
WM_SYSTIMER)) {
00811
if (pmsg->lParam != 0) {
00812
00813
00814
00815
00816
if (pmsg->message ==
WM_SYSTIMER) {
00817
00818
00819
00820
00821
00822
00823
PTIMER ptmr;
00824 lRet = 0;
00825
for (ptmr =
gptmrFirst; ptmr !=
NULL; ptmr = ptmr->
ptmrNext) {
00826
if ((pmsg->lParam == (LPARAM)ptmr->
pfn) && (ptmr->
flags & TMRF_SYSTEM)) {
00827 ptmr->
pfn(pwnd,
WM_SYSTIMER, (
UINT)pmsg->wParam,
00828
NtGetTickCount());
00829
break;
00830 }
00831 }
00832
goto Exit;
00833 }
else {
00834
00835
00836
00837
PTHREADINFO ptiCurrent =
PtiCurrent();
00838
00839
if (ptiCurrent->
TIF_flags &
TIF_SYSTEMTHREAD) {
00840 lRet = 0;
00841
goto Exit;
00842 }
00843
00844 lRet =
CallClientProcA(pwnd, WM_TIMER,
00845 pmsg->wParam,
NtGetTickCount(), pmsg->lParam);
00846
00847
goto Exit;
00848 }
00849 }
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
if (pwnd ==
NULL) {
00859 lRet = 0;
00860
goto Exit;
00861 }
00862
00863
00864
00865
00866
00867
if (pmsg->message == WM_PAINT)
00868
SetWF(pwnd,
WFPAINTNOTPROCESSED);
00869
00870
00871
00872
00873
00874
00875
if (
TestWF(pwnd,
WFSERVERSIDEPROC)) {
00876 ULONG_PTR fnMessageType;
00877
00878 fnMessageType = pmsg->message >= WM_USER ? (ULONG_PTR)SfnDWORD :
00879 (ULONG_PTR)
gapfnScSendMessage[
MessageTable[pmsg->message].
iFunction];
00880
00881
00882
00883
00884
if (fnMessageType == (ULONG_PTR)SfnINWPARAMCHAR &&
TestWF(pwnd,
WFANSIPROC)) {
00885 UserAssert(
PtiCurrent() ==
GETPTI(pwnd));
00886
RtlMBMessageWParamCharToWCS(pmsg->message, &pmsg->wParam);
00887 }
00888
00889 lRet = pwnd->
lpfnWndProc(pwnd, pmsg->message, pmsg->wParam,
00890 pmsg->lParam);
00891
goto Exit;
00892 }
00893
00894
00895
00896
00897
00898 lpfnWndProc = pwnd->
lpfnWndProc;
00899
00900 {
00901
00902
00903
00904
00905
if (
TestWF(pwnd,
WFANSIPROC)) {
00906 UserAssert(
PtiCurrent() ==
GETPTI(pwnd));
00907
RtlWCSMessageWParamCharToMB(pmsg->message, &pmsg->wParam);
00908 lRet =
CallClientProcA(pwnd, pmsg->message,
00909 pmsg->wParam, pmsg->lParam, (ULONG_PTR)lpfnWndProc);
00910 }
else {
00911 lRet =
CallClientProcW(pwnd, pmsg->message,
00912 pmsg->wParam, pmsg->lParam, (ULONG_PTR)lpfnWndProc);
00913 }
00914 }
00915
00916
00917
00918
00919
00920
if (pmsg->message == WM_PAINT &&
RevalidateHwnd(pmsg->hwnd) &&
00921
TestWF(pwnd,
WFPAINTNOTPROCESSED)) {
00922
00923
00924
ClrWF(pwnd,
WFWMPAINTSENT);
00925
xxxSimpleDoSyncPaint(pwnd);
00926 }
00927
00928 Exit:
00929
ThreadUnlock(&tlpwnd);
00930
return lRet;
00931 }
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943 void AdjustForCoalescing(
00944
PMLIST pml,
00945 HWND hwnd,
00946 UINT message)
00947 {
00948
00949
00950
00951
if (!
CheckMsgFilter(message, WM_COALESCE_FIRST, WM_COALESCE_LAST) &&
00952 (message != WM_TIMECHANGE))
00953
return;
00954
00955
if (pml->
pqmsgWriteLast ==
NULL)
00956
return;
00957
00958
if (pml->
pqmsgWriteLast->
msg.message != message)
00959
return;
00960
00961
if (pml->
pqmsgWriteLast->
msg.hwnd != hwnd)
00962
return;
00963
00964
00965
00966
00967
00968
DelQEntry(pml, pml->
pqmsgWriteLast);
00969 }
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981 BOOL _PostMessage(
00982
PWND pwnd,
00983 UINT message,
00984 WPARAM wParam,
00985 LPARAM lParam)
00986 {
00987
PQMSG pqmsg;
00988
BOOL fPwndUnlock;
00989
BOOL fRet;
00990
DWORD dwPostCode;
00991
TL tlpwnd;
00992
PTHREADINFO pti;
00993
00994
00995
00996
00997
00998
00999
01000
01001
if (
TESTSYNCONLYMESSAGE(message, wParam)) {
01002 RIPERR1(ERROR_MESSAGE_SYNC_ONLY,
01003 RIP_WARNING,
01004
"Invalid parameter \"message\" (%ld) to _PostMessage",
01005 message);
01006
01007
return FALSE;
01008 }
01009
01010
01011
01012
01013
if (pwnd ==
PWND_BROADCAST) {
01014
xxxBroadcastMessage(
NULL, message, wParam, lParam,
BMSG_POSTMSG,
NULL);
01015
return TRUE;
01016 }
01017
01018 pti =
PtiCurrent();
01019
01020
01021
01022
01023
if (pwnd ==
NULL) {
01024
return _PostThreadMessage(pti, message, wParam, lParam);
01025 }
01026
01027 fPwndUnlock =
FALSE;
01028
if (message >= WM_DDE_FIRST && message <= WM_DDE_LAST) {
01029
ThreadLockAlwaysWithPti(pti, pwnd, &tlpwnd);
01030 dwPostCode =
xxxDDETrackPostHook(&message, pwnd, wParam, &lParam,
FALSE);
01031
01032
if (dwPostCode !=
DO_POST) {
01033
ThreadUnlock(&tlpwnd);
01034
return (
BOOL)dwPostCode;
01035 }
01036
01037 fPwndUnlock =
TRUE;
01038 }
01039
01040 pti =
GETPTI(pwnd);
01041
01042
01043
01044
01045
01046
AdjustForCoalescing(&pti->
mlPost,
HWq(pwnd), message);
01047
01048
01049
01050
01051
if (message >= WM_KEYFIRST && message <= WM_KEYLAST) {
01052
PostUpdateKeyStateEvent(pti->
pq);
01053 }
01054
01055
01056
01057
01058 fRet =
FALSE;
01059
if ((pqmsg =
AllocQEntry(&pti->
mlPost)) !=
NULL) {
01060
01061
01062
01063
StoreQMessage(pqmsg, pwnd, message, wParam, lParam, 0, 0, 0);
01064
SetWakeBit(pti, QS_POSTMESSAGE | QS_ALLPOSTMESSAGE);
01065
01066
01067
01068
01069
01070
if (message == WM_HOTKEY)
01071
SetWakeBit(pti, QS_HOTKEY);
01072
01073 fRet =
TRUE;
01074 }
else {
01075 RIPMSG1(RIP_WARNING,
"_PostMessage: Failed to alloc Q entry: target pti=0x%p",
01076 pti);
01077 }
01078
01079
01080
01081
01082
01083
01084
if (pti == pti->
pq->
ptiSysLock)
01085 pti->
pq->
idSysLock = (ULONG_PTR)pqmsg;
01086
01087
if (fPwndUnlock)
01088
ThreadUnlock(&tlpwnd);
01089
01090
return fRet;
01091 }
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102 BOOL IPostQuitMessage(
PTHREADINFO pti,
int nExitCode)
01103 {
01104 pti->
cQuit = 1;
01105 pti->
exitCode = nExitCode;
01106
SetWakeBit(pti, QS_POSTMESSAGE | QS_ALLPOSTMESSAGE);
01107
return TRUE;
01108 }
01109 BOOL _PostQuitMessage(
int nExitCode)
01110 {
01111
return IPostQuitMessage(
PtiCurrent(), nExitCode);
01112 }
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123 BOOL _PostThreadMessage(
01124
PTHREADINFO pti,
01125 UINT message,
01126 WPARAM wParam,
01127 LPARAM lParam)
01128 {
01129
PQMSG pqmsg;
01130
01131
if ((pti ==
NULL) ||
01132 !(pti->
TIF_flags &
TIF_GUITHREADINITIALIZED) ||
01133 (pti->
TIF_flags &
TIF_INCLEANUP)) {
01134
01135 RIPERR0(ERROR_INVALID_THREAD_ID, RIP_VERBOSE,
"");
01136
return FALSE;
01137 }
01138
01139
01140
01141
01142
01143
01144
01145
01146
if (
TESTSYNCONLYMESSAGE(message, wParam)) {
01147 RIPERR1(ERROR_MESSAGE_SYNC_ONLY,
01148 RIP_WARNING,
01149
"Invalid parameter \"message\" (%ld) to _PostThreadMessage",
01150 message);
01151
01152
return FALSE;
01153 }
01154
01155
01156
01157
01158
01159
AdjustForCoalescing(&pti->
mlPost,
NULL, message);
01160
01161
01162
01163
01164
if ((pqmsg =
AllocQEntry(&pti->
mlPost)) ==
NULL) {
01165 RIPMSG1(RIP_WARNING,
"_PostThreadMessage: Failed to alloc Q entry: Target pti=0x%p",
01166 pti);
01167
return FALSE;
01168 }
01169
01170
01171
01172
01173
StoreQMessage(pqmsg,
NULL, message, wParam, lParam, 0, 0, 0);
01174
SetWakeBit(pti, QS_POSTMESSAGE | QS_ALLPOSTMESSAGE);
01175
01176
01177
01178
01179
01180
if (message == WM_HOTKEY)
01181
SetWakeBit(pti, QS_HOTKEY);
01182
01183
01184
01185
01186
01187
01188
if (pti == pti->
pq->
ptiSysLock)
01189 pti->
pq->
idSysLock = (ULONG_PTR)pqmsg;
01190
01191
return TRUE;
01192 }
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205 DWORD _GetMessagePos(VOID)
01206 {
01207
PTHREADINFO pti;
01208
01209 pti =
PtiCurrent();
01210
01211
return MAKELONG((
SHORT)pti->
ptLast.x, (
SHORT)pti->
ptLast.y);
01212 }
01213
01214
01215
01216
#ifdef SYSMODALWINDOWS
01217
01218
01219
01220
01221
01222
01223
01224
PWND APIENTRY _SetSysModalWindow(
01225
PWND pwnd)
01226 {
01227 pwnd;
01228
return NULL;
01229 }
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
PWND APIENTRY _GetSysModalWindow(VOID)
01240 {
01241
return NULL;
01242 }
01243
#endif //LATER
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254 VOID PostMove(
01255
PQ pq)
01256 {
01257
#ifdef REDIRECTION
01258
POINT pt;
01259
#endif // REDIRECTION
01260
01261
CheckCritIn();
01262
01263
01264
01265
01266
01267
01268
if (
gdwMouseMoveTimeStamp == 0) {
01269
gdwMouseMoveTimeStamp =
NtGetTickCount();
01270 }
01271
01272
#ifdef REDIRECTION
01273
01274 PopMouseMove(pq, &pt);
01275
01276
PostInputMessage(pq,
NULL, WM_MOUSEMOVE, 0,
01277 MAKELONG((
SHORT)pt.x, (
SHORT)pt.y),
01278
gdwMouseMoveTimeStamp,
gdwMouseMoveExtraInfo);
01279
#else
01280
PostInputMessage(pq,
NULL, WM_MOUSEMOVE, 0,
01281 MAKELONG((
SHORT)
gpsi->ptCursor.x, (
SHORT)
gpsi->ptCursor.y),
01282
gdwMouseMoveTimeStamp,
gdwMouseMoveExtraInfo);
01283
#endif // REDIRECTION
01284
01285
gdwMouseMoveTimeStamp = 0;
01286
01287 pq->
QF_flags &= ~
QF_MOUSEMOVED;
01288 }
01289
01290
#ifdef REDIRECTION
01291
01292
typedef struct tagQMOUSEMOVE {
01293
PQ pq;
01294 POINT pt;
01295 } QMOUSEMOVE;
01296
01297
#define MAX_QMOUSEMOVE 16
01298
01299 QMOUSEMOVE gqMouseMove[MAX_QMOUSEMOVE];
01300
01301
int gnLastMouseMove;
01302
01303
VOID PushMouseMove(
01304
PQ pq,
01305 POINT pt)
01306 {
01307
int ind;
01308
01309
CheckCritIn();
01310
01311 UserAssert(gnLastMouseMove < MAX_QMOUSEMOVE - 1);
01312
01313
for (ind = 0; ind < gnLastMouseMove; ind++) {
01314
if (pq == gqMouseMove[ind].pq) {
01315
01316 gqMouseMove[ind].pt = pt;
01317
return;
01318 }
01319 }
01320
01321 gqMouseMove[gnLastMouseMove].pq = pq;
01322 gqMouseMove[gnLastMouseMove].pt = pt;
01323
01324 gnLastMouseMove++;
01325 }
01326
01327
VOID PopMouseMove(
01328
PQ pq,
01329 POINT* ppt)
01330 {
01331
int ind;
01332
01333
CheckCritIn();
01334
01335
for (ind = 0; ind < gnLastMouseMove; ind++) {
01336
if (pq == gqMouseMove[ind].pq) {
01337 *ppt = gqMouseMove[ind].pt;
01338
01339 RtlMoveMemory(&gqMouseMove[ind],
01340 &gqMouseMove[ind + 1],
01341 (gnLastMouseMove - ind - 1) *
sizeof(QMOUSEMOVE));
01342
01343 gnLastMouseMove--;
01344
01345
return;
01346 }
01347 }
01348 UserAssert(0);
01349 }
01350
#endif // REDIRECTION
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363 VOID zzzSetFMouseMoved()
01364 {
01365
PWND pwnd;
01366
PWND pwndOldCursor;
01367
PQ pq;
01368
01369
#ifdef REDIRECTION
01370
PWND pwndStart;
01371 POINT ptMouse =
gpsi->ptCursor;
01372
#endif // REDIRECTION
01373
01374
01375
01376
01377
01378
if ((pwnd =
gspwndScreenCapture) ==
NULL) {
01379
01380
#ifdef REDIRECTION
01381
01382
01383
01384 pwndStart = xxxCallSpeedHitTestHook(&ptMouse);
01385
#endif // REDIRECTION
01386
01387
if ((pwnd =
gspwndMouseOwner) ==
NULL) {
01388
if ((pwnd =
gspwndInternalCapture) ==
NULL) {
01389
01390 UserAssert(
grpdeskRitInput !=
NULL);
01391
01392
#ifdef REDIRECTION
01393
if (pwndStart ==
NULL) {
01394 pwndStart =
grpdeskRitInput->
pDeskInfo->
spwnd;
01395 }
01396 pwnd =
SpeedHitTest(pwndStart, ptMouse);
01397
#else
01398
pwnd =
SpeedHitTest(
grpdeskRitInput->
pDeskInfo->
spwnd,
gpsi->ptCursor);
01399
#endif // REDIRECTION
01400
01401 }
01402 }
01403 }
01404
01405
if (pwnd ==
NULL)
01406
return;
01407
01408
01409
01410
01411
01412 pwndOldCursor =
Lock(&
gspwndCursor, pwnd);
01413
01414
01415
01416
01417
01418 pq =
GETPTI(pwnd)->pq;
01419
01420
01421
01422
01423
DeferWinEventNotify();
01424
01425
if (pq !=
gpqCursor) {
01426
01427
01428
01429
01430
01431
if (
gpqCursor !=
NULL) {
01432
01433
if (
gpqCursor->
spwndCapture !=
NULL) {
01434
gpqCursor->
QF_flags |=
QF_MOUSEMOVED;
01435
SetWakeBit(
GETPTI(
gpqCursor->
spwndCapture), QS_MOUSEMOVE);
01436
01437
#ifdef REDIRECTION
01438
PushMouseMove(
gpqCursor, ptMouse);
01439
#endif // REDIRECTION
01440
01441 }
01442
01443
if ((pwndOldCursor !=
NULL) && (
PtoHq(pwndOldCursor) !=
PtoHq(pwnd))) {
01444
PDESKTOP pdesk =
GETPDESK(pwndOldCursor);
01445
if (pdesk->
dwDTFlags &
DF_MOUSEMOVETRK) {
01446
PTHREADINFO pti =
GETPTI(pdesk->
spwndTrack);
01447
PostEventMessage(pti, pti->
pq,
QEVENT_CANCELMOUSEMOVETRK,
01448 pdesk->
spwndTrack, pdesk->
dwDTFlags, pdesk->
htEx,
01449
DF_MOUSEMOVETRK);
01450 pdesk->
dwDTFlags &= ~
DF_MOUSEMOVETRK;
01451 }
01452 }
01453 }
01454
01455
01456
01457
01458
01459
01460
gpqCursor = pq;
01461
01462
01463
01464
01465
01466
zzzUpdateCursorImage();
01467
01468 }
01469
01470
01471
01472
01473
01474 pq->
QF_flags |=
QF_MOUSEMOVED;
01475
01476
#ifdef REDIRECTION
01477
PushMouseMove(pq, ptMouse);
01478
#endif // REDIRECTION
01479
01480
01481
01482
01483
01484
01485 pq->
ptiMouse =
GETPTI(pwnd);
01486
01487
01488
01489
01490
WakeSomeone(pq, WM_MOUSEMOVE,
NULL);
01491
01492
01493
01494
01495
01496
gdwMouseMoveExtraInfo = 0;
01497
01498
zzzEndDeferWinEventNotify();
01499 }
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515 void CancelForegroundActivate()
01516 {
01517
PPROCESSINFO ppiT;
01518
01519
if (
TEST_PUDF(
PUDF_ALLOWFOREGROUNDACTIVATE)) {
01520
01521
for (ppiT =
gppiStarting; ppiT !=
NULL; ppiT = ppiT->
ppiNext) {
01522
01523
01524
01525
01526
01527
01528
if (!ppiT->Process->DebugPort) {
01529 ppiT->W32PF_Flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE;
01530 TAGMSG1(DBGTAG_FOREGROUND,
"CancelForegroundActivate clear W32PF %#p", ppiT);
01531 }
01532 }
01533
01534
CLEAR_PUDF(
PUDF_ALLOWFOREGROUNDACTIVATE);
01535 TAGMSG0(DBGTAG_FOREGROUND,
"CancelForegroundActivate clear PUDF");
01536 }
01537 }
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549 void RestoreForegroundActivate()
01550 {
01551
PPROCESSINFO ppiT;
01552
01553
for (ppiT =
gppiStarting; ppiT !=
NULL; ppiT = ppiT->
ppiNext) {
01554
if (ppiT->W32PF_Flags & W32PF_APPSTARTING) {
01555 ppiT->W32PF_Flags |= W32PF_ALLOWFOREGROUNDACTIVATE;
01556 TAGMSG1(DBGTAG_FOREGROUND,
"RestoreForegroundActivate set W32PF %#p", ppiT);
01557
SET_PUDF(
PUDF_ALLOWFOREGROUNDACTIVATE);
01558 TAGMSG0(DBGTAG_FOREGROUND,
"RestoreForegroundActivate set PUDF");
01559 }
01560 }
01561 }
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575 void PostInputMessage(
01576
PQ pq,
01577
PWND pwnd,
01578 UINT message,
01579 WPARAM wParam,
01580 LPARAM lParam,
01581 DWORD time,
01582 ULONG_PTR dwExtraInfo)
01583 {
01584
PQMSG pqmsgInput, pqmsgPrev;
01585
short sWheelDelta;
01586
01587
01588
01589
01590
01591 pqmsgPrev = pq->
mlInput.
pqmsgWriteLast;
01592
01593
01594
01595
01596
if (pq->
QF_flags &
QF_UPDATEKEYSTATE) {
01597
PostUpdateKeyStateEvent(pq);
01598 }
01599
01600
01601
01602
01603
01604
01605
01606
if (pqmsgPrev !=
NULL &&
01607 pqmsgPrev->
msg.message == message &&
01608 (message == WM_MOUSEMOVE || message == WM_MOUSEWHEEL)) {
01609
01610
if (message == WM_MOUSEWHEEL) {
01611 sWheelDelta = (
short)HIWORD(wParam) + (
short)HIWORD(pqmsgPrev->
msg.wParam);
01612
01613
#if 0
01614
01615
01616
01617
01618
01619
01620
01621
01622
if (sWheelDelta == 0) {
01623
if ((
PQMSG)pq->
idSysPeek == pqmsgPrev) {
01624 RIPMSG0(RIP_VERBOSE,
01625
"Coalescing of mouse wheel messages causing "
01626
"idSysPeek to be reset to 0");
01627
01628 pq->
idSysPeek = 0;
01629 }
01630
01631
DelQEntry(&pq->
mlInput, pqmsgPrev);
01632
return;
01633 }
01634
#endif
01635
01636 wParam = MAKEWPARAM(LOWORD(wParam), sWheelDelta);
01637 }
01638
01639
StoreQMessage(pqmsgPrev, pwnd, message, wParam, lParam, time, 0, dwExtraInfo);
01640
WakeSomeone(pq, message, pqmsgPrev);
01641
01642
return;
01643 }
01644
01645
01646
01647
01648 pqmsgInput =
AllocQEntry(&pq->
mlInput);
01649
if (pqmsgInput !=
NULL) {
01650
StoreQMessage(pqmsgInput, pwnd, message, wParam, lParam, time, 0, dwExtraInfo);
01651
WakeSomeone(pq, message, pqmsgInput);
01652 }
01653 }
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664 void WakeSomeone(
01665
PQ pq,
01666 UINT message,
01667
PQMSG pqmsg)
01668 {
01669
BOOL fSetLastWoken =
FALSE;
01670
PTHREADINFO ptiT;
01671
01672
01673
01674
01675 ptiT =
NULL;
01676
switch (message) {
01677
01678
case WM_SYSKEYDOWN:
01679
case WM_KEYDOWN:
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
if (pqmsg !=
NULL) {
01690
switch (pqmsg->
msg.wParam) {
01691
case VK_SHIFT:
01692
case VK_CONTROL:
01693
case VK_MENU:
01694
if (
TestKeyStateDown(pq, pqmsg->
msg.wParam)) {
01695
break;
01696 }
01697
01698
01699
default:
01700 fSetLastWoken =
TRUE;
01701
break;
01702 }
01703 }
else {
01704 fSetLastWoken =
TRUE;
01705 }
01706
01707
01708
case WM_SYSCHAR:
01709
case WM_CHAR:
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
CancelForegroundActivate();
01729
01730
01731
01732
case WM_KEYUP:
01733
case WM_SYSKEYUP:
01734
case WM_MOUSEWHEEL:
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745 ptiT = pq->
ptiKeyboard;
01746
if (pq->
spwndActive !=
NULL)
01747 ptiT =
GETPTI(pq->
spwndActive);
01748
01749
SetWakeBit(ptiT, message == WM_MOUSEWHEEL ? QS_MOUSEBUTTON : QS_KEY);
01750
break;
01751
01752
case WM_MOUSEMOVE:
01753
01754
01755
01756
01757
01758
01759
if (pq->
spwndCapture !=
NULL)
01760 ptiT =
GETPTI(pq->
spwndCapture);
01761
else
01762 ptiT = pq->
ptiMouse;
01763
SetWakeBit(ptiT, QS_MOUSEMOVE);
01764
break;
01765
01766
01767
case WM_LBUTTONDOWN:
01768
case WM_LBUTTONDBLCLK:
01769
case WM_RBUTTONDOWN:
01770
case WM_RBUTTONDBLCLK:
01771
case WM_MBUTTONDOWN:
01772
case WM_MBUTTONDBLCLK:
01773
case WM_XBUTTONDOWN:
01774
case WM_XBUTTONDBLCLK:
01775 fSetLastWoken =
TRUE;
01776
01777
01778
01779
default:
01780
01781
01782
01783
01784
CancelForegroundActivate();
01785
01786
01787
01788
case WM_LBUTTONUP:
01789
case WM_RBUTTONUP:
01790
case WM_MBUTTONUP:
01791
case WM_XBUTTONUP:
01792
01793
01794
01795
01796
01797
01798
if (pq->
spwndCapture !=
NULL &&
01799 message >= WM_MOUSEFIRST && message <= WM_MOUSELAST)
01800 ptiT =
GETPTI(pq->
spwndCapture);
01801
else
01802 ptiT = pq->
ptiMouse;
01803
SetWakeBit(ptiT, QS_MOUSEBUTTON);
01804
break;
01805 }
01806
01807
01808
01809
01810
01811
01812
01813
if (ptiT !=
NULL) {
01814
if (pqmsg !=
NULL) {
01815
01816
StoreQMessagePti(pqmsg, ptiT);
01817
01818 UserAssert(!(ptiT->
TIF_flags &
TIF_INCLEANUP));
01819 }
01820
01821
01822
01823
01824
if (fSetLastWoken) {
01825
glinp.
ptiLastWoken = ptiT;
01826 }
01827 }
01828
01829 }
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874 void PostUpdateKeyStateEvent(
01875
PQ pq)
01876 {
01877
BYTE *pb;
01878
PQMSG pqmsg;
01879
01880
if (!(pq->
QF_flags &
QF_UPDATEKEYSTATE))
01881
return;
01882
01883
01884
01885
01886
if (pq->
ptiKeyboard ==
gptiRit) {
01887
return;
01888 }
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
if (pq->
mlInput.
cMsgs == 0) {
01900
ProcessUpdateKeyStateEvent(pq,
gafAsyncKeyState, pq->
afKeyRecentDown);
01901
goto SyncQueue;
01902 }
01903
#if DBG
01904
else if ((!pq->
ptiKeyboard || !(pq->
ptiKeyboard->
pcti->
fsWakeBits & QS_KEY)) &&
01905 (!pq->
ptiMouse || !(pq->
ptiMouse->
pcti->
fsWakeBits & QS_MOUSEBUTTON))) {
01906
01907
01908
01909
01910
PQMSG pqmsgT;
01911
for (pqmsgT = pq->
mlInput.
pqmsgRead; pqmsgT; pqmsgT = pqmsgT->
pqmsgNext) {
01912
if (pqmsgT->
msg.message >= WM_KEYFIRST && pqmsgT->
msg.message <= WM_KEYLAST) {
01913 TAGMSG1(DBGTAG_InputWithoutQS,
01914
"PostUpdateKeyStateEvent() pushing in front of a keystroke: Q %#p", pq);
01915 }
else if (pqmsgT->
msg.message >= WM_LBUTTONDOWN && pqmsgT->
msg.message <= WM_XBUTTONDBLCLK) {
01916 TAGMSG1(DBGTAG_InputWithoutQS,
01917
"PostUpdateKeyStateEvent() pushing in front of a mousebutton: Q %#p", pq);
01918 }
01919 }
01920 }
01921
#endif
01922
01923 UserAssert(pq->
mlInput.
pqmsgWriteLast !=
NULL);
01924
01925
01926
01927
01928
01929 pqmsg = pq->
mlInput.
pqmsgWriteLast;
01930
if (pqmsg->
dwQEvent ==
QEVENT_UPDATEKEYSTATE) {
01931
int i;
01932
DWORD *pdw;
01933
01934 pb = (
PBYTE)(pqmsg->
msg.wParam);
01935 pdw = (
DWORD *) (pb +
CBKEYSTATE);
01936
01937
01938
01939
01940 RtlCopyMemory(pb,
gafAsyncKeyState,
CBKEYSTATE);
01941
01942
01943
01944
01945
#if (CBKEYSTATERECENTDOWN % 4) != 0
01946
#error "CBKEYSTATERECENTDOWN assumed to be an integral number of DWORDs"
01947
#endif
01948
for (i = 0; i <
CBKEYSTATERECENTDOWN /
sizeof(*pdw); i++) {
01949 *pdw++ |= ((
DWORD *)(pq->
afKeyRecentDown))[i];
01950 }
01951
01952
01953
01954
01955
01956
SetWakeBit(pq->
ptiKeyboard, QS_EVENTSET);
01957
goto SyncQueue;
01958 }
01959
01960
01961
01962
01963
01964
if ((pb = UserAllocPool(
KEYSTATESIZE, TAG_KBDSTATE)) ==
NULL) {
01965
return;
01966 }
01967
01968 RtlCopyMemory(pb,
gafAsyncKeyState,
CBKEYSTATE);
01969 RtlCopyMemory(pb +
CBKEYSTATE, pq->
afKeyRecentDown,
CBKEYSTATERECENTDOWN);
01970
01971
if (!
PostEventMessage(pq->
ptiKeyboard, pq,
QEVENT_UPDATEKEYSTATE,
01972
NULL, 0 , (WPARAM)pb, 0)) {
01973 UserFreePool(pb);
01974
return;
01975 }
01976
01977
01978
01979
01980
01981 SyncQueue:
01982 RtlZeroMemory(pq->
afKeyRecentDown,
CBKEYSTATERECENTDOWN);
01983 pq->
QF_flags &= ~
QF_UPDATEKEYSTATE;
01984 }
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996 void ProcessUpdateKeyStateEvent(
01997
PQ pq,
01998 CONST PBYTE pbKeyState,
01999 CONST PBYTE pbRecentDown)
02000 {
02001
int i, j;
02002
BYTE *pbChange;
02003
int vk;
02004
02005 pbChange = pbRecentDown;
02006
for (i = 0; i <
CBKEYSTATERECENTDOWN; i++, pbChange++) {
02007
02008
02009
02010
02011
if (*pbChange == 0)
02012
continue;
02013
02014
02015
02016
02017
for (j = 0; j < 8; j++) {
02018
02019
02020
02021
02022
02023 vk = (i << 3) + j;
02024
if (!
TestKeyRecentDownBit(pbRecentDown, vk))
02025
continue;
02026
02027
02028
02029
02030
02031
02032
if (
TestKeyDownBit(pbKeyState, vk)) {
02033
SetKeyStateDown(pq, vk);
02034 }
else {
02035
ClearKeyStateDown(pq, vk);
02036 }
02037
02038
if (
TestKeyToggleBit(pbKeyState, vk)) {
02039
SetKeyStateToggle(pq, vk);
02040 }
else {
02041
ClearKeyStateToggle(pq, vk);
02042 }
02043 }
02044 }
02045
02046
02047
02048
02049
gpsi->dwKeyCache++;
02050
02051
02052
02053
02054
if (pbKeyState !=
gafAsyncKeyState) {
02055 UserFreePool(pbKeyState);
02056 }
02057 }
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068 BOOL PostEventMessage(
02069
PTHREADINFO pti,
02070
PQ pq,
02071 DWORD dwQEvent,
02072
PWND pwnd,
02073 UINT message,
02074 WPARAM wParam,
02075 LPARAM lParam)
02076 {
02077
PQMSG pqmsgEvent;
02078
02079
CheckCritIn();
02080
02081
02082
02083
02084
02085
02086
if (pti && (pti->
TIF_flags &
TIF_INCLEANUP))
02087
return FALSE;
02088
02089
if ((pqmsgEvent =
AllocQEntry(&pq->
mlInput)) ==
NULL)
02090
return FALSE;
02091
02092
StoreQMessage(pqmsgEvent, pwnd, message, wParam, lParam, 0, dwQEvent, 0);
02093
02094
StoreQMessagePti(pqmsgEvent, pti);
02095
02096
02097
02098
02099
if (pti ==
NULL) {
02100 UserAssert(pti);
02101
SetWakeBit(pq->
ptiMouse, QS_EVENTSET);
02102
SetWakeBit(pq->
ptiKeyboard, QS_EVENTSET);
02103 }
else {
02104
SetWakeBit(pti, QS_EVENTSET);
02105 }
02106
02107
return TRUE;
02108 }
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148 BOOL CheckOnTop(
PTHREADINFO pti,
PWND pwndTop, UINT message)
02149 {
02150
if (pwndTop != pti->
pq->
spwndActive)
02151
return FALSE;
02152
02153
switch (message) {
02154
case WM_LBUTTONDOWN:
02155
case WM_RBUTTONDOWN:
02156
case WM_MBUTTONDOWN:
02157
case WM_XBUTTONDOWN:
02158
if (
TestWF(pwndTop,
WEFTOPMOST)
02159 || (
_GetWindow(pwndTop, GW_HWNDPREV) !=
CalcForegroundInsertAfter(pwndTop))) {
02160
02161
return xxxSetWindowPos(pwndTop,
PWND_TOP, 0, 0, 0, 0,
02162 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
02163 }
02164
break;
02165 }
02166
02167
return FALSE;
02168 }
02169
02170
02171 #define MA_PASSTHRU 0
02172 #define MA_SKIP 1
02173 #define MA_REHITTEST 2
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187 void zzzActiveCursorTracking (
PWND pwnd)
02188 {
02189
BOOL fVisible;
02190 POINT pt;
02191
02192
02193
02194
02195
02196
if (!(
glinp.
dwFlags &
LINP_KEYBOARD)) {
02197
return;
02198 }
02199
02200
02201
02202
if (
PtInRect((LPRECT)&pwnd->
rcWindow,
gptCursorAsync)) {
02203
return;
02204 }
02205
02206
02207
02208
02209
if ((
gspwndCursor !=
NULL) && (
GetActiveTrackPwnd(
gspwndCursor,
NULL) ==
NULL)) {
02210
return;
02211 }
02212
02213
02214
02215 pt.x = pwnd->
rcWindow.left + ((pwnd->
rcWindow.right - pwnd->
rcWindow.left) / 2);
02216 pt.y = pwnd->
rcWindow.top + ((pwnd->
rcWindow.bottom - pwnd->
rcWindow.top) / 2);
02217
BoundCursor(&pt);
02218
if (!
PtInRect((LPRECT)&pwnd->
rcWindow, pt)) {
02219
return;
02220 }
02221
02222
02223
02224
02225
02226
02227
02228
02229 fVisible =
TestWF(pwnd,
WFVISIBLE);
02230
if (!fVisible) {
02231
SetVisible(pwnd,
SV_SET);
02232 }
02233
02234
02235
02236
02237
zzzInternalSetCursorPos(pt.x, pt.y);
02238
02239
02240
02241
if (!fVisible) {
02242
SetVisible(pwnd,
SV_UNSET);
02243 }
02244 }
02245
02246
02247
02248
02249
02250
02251 PWND GetActiveTrackPwnd(
PWND pwnd,
Q **ppq)
02252 {
02253
PWND pwndActivate;
02254
Q *pq;
02255
02256
CheckCritIn();
02257 pwndActivate = pwnd;
02258
02259
02260
02261
02262
while (
TestwndChild(pwndActivate)) {
02263 pwndActivate = pwndActivate->
spwndParent;
02264 }
02265
02266
02267
02268
02269
if (
TestWF(pwndActivate,
WFDISABLED)) {
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281 pwndActivate =
DWP_GetEnabledPopup(pwndActivate);
02282 }
02283
02284
02285
02286
02287
if ((pwndActivate ==
NULL) || !
TestWF(pwndActivate,
WFVISIBLE)) {
02288
return NULL;
02289 }
02290
02291
02292
02293
02294
02295
02296 pq =
GETPTI(pwndActivate)->pq;
02297
if ((pq ==
gpqForeground)
02298 && ((pwndActivate == pq->
spwndActive)
02299 ||
IsModelessMenuNotificationWindow(pwndActivate))) {
02300
02301
return NULL;
02302 }
02303
02304
02305
02306
02307
if (pwndActivate == pwndActivate->
head.rpdesk->pDeskInfo->spwndShell) {
02308
return NULL;
02309 }
02310
02311
02312
02313
02314
if (ppq !=
NULL) {
02315 *ppq = pq;
02316 }
02317
02318
return pwndActivate;
02319 }
02320
02321
02322
02323
02324
02325
02326
02327 int xxxActiveWindowTracking(
02328
PWND pwnd,
02329 UINT uMsg,
02330
int iHitTest)
02331 {
02332
02333
BOOL fSuccess;
02334
int iRet;
02335
PWND pwndActivate;
02336
Q *pq;
02337
TL tlpwndActivate;
02338
02339
CheckLock(pwnd);
02340 UserAssert(
TestUP(ACTIVEWINDOWTRACKING));
02341
02342
02343
02344
02345 pq =
GETPTI(pwnd)->pq;
02346
if (!(pq->
QF_flags &
QF_ACTIVEWNDTRACKING)) {
02347
return MA_PASSTHRU;
02348 }
02349 pq->
QF_flags &= ~
QF_ACTIVEWNDTRACKING;
02350
02351
02352
02353
02354
if (
IsForegroundLocked()) {
02355
return MA_PASSTHRU;
02356 }
02357
02358
02359
02360
02361 pwndActivate =
GetActiveTrackPwnd(pwnd, &pq);
02362
if (pwndActivate ==
NULL) {
02363
return MA_PASSTHRU;
02364 }
02365
02366
02367
02368
02369
if (pwnd != pwndActivate) {
02370
ThreadLockAlways(pwndActivate, &tlpwndActivate);
02371 }
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383 iRet = (
int)
xxxSendMessage(pwndActivate, WM_MOUSEACTIVATE,
02384 (WPARAM)(
HWq(pwndActivate)), MAKELONG((
SHORT)iHitTest, uMsg));
02385
02386
02387
switch (iRet) {
02388
case MA_ACTIVATE:
02389
case MA_ACTIVATEANDEAT:
02390
if (pq ==
gpqForeground) {
02391 fSuccess =
xxxActivateThisWindow(pwndActivate, 0,
02392 (
TestUP(ACTIVEWNDTRKZORDER) ? 0 :
ATW_NOZORDER));
02393 }
else {
02394 fSuccess =
xxxSetForegroundWindow2(pwndActivate,
NULL,
02395
SFW_SWITCH | (
TestUP(ACTIVEWNDTRKZORDER) ? 0 :
SFW_NOZORDER));
02396 }
02397
02398
02399
02400
02401
if (!fSuccess) {
02402 iRet =
MA_SKIP;
02403 }
else if (iRet == MA_ACTIVATEANDEAT) {
02404 iRet =
MA_SKIP;
02405 }
02406
break;
02407
02408
case MA_NOACTIVATEANDEAT:
02409 iRet =
MA_SKIP;
02410
break;
02411
02412
02413
case MA_NOACTIVATE:
02414
default:
02415 iRet =
MA_PASSTHRU;
02416
break;
02417 }
02418
02419
if (pwnd != pwndActivate) {
02420
ThreadUnlock(&tlpwndActivate);
02421 }
02422
02423
return iRet;
02424
02425 }
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444 int xxxMouseActivate(
02445
PTHREADINFO pti,
02446
PWND pwnd,
02447 UINT message,
02448 WPARAM wParam,
02449 LPPOINT lppt,
02450
int ht)
02451 {
02452
UINT x, y;
02453
PWND pwndTop;
02454
int result;
02455
TL tlpwndTop;
02456
BOOL fSend;
02457
02458
CheckLock(pwnd);
02459
02460 UserAssert(
_GETPDESK(pwnd) !=
NULL);
02461
02462
02463
02464
02465
02466
02467
02468
02469
if (pti->
pq->
spwndCapture !=
NULL) {
02470
return MA_PASSTHRU;
02471 }
02472
02473 result =
MA_PASSTHRU;
02474
02475 pwndTop = pwnd;
02476
ThreadLockWithPti(pti, pwndTop, &tlpwndTop);
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489 fSend = (!
TestWF(pwnd,
WFWIN40COMPAT) || !
TestWF(pwnd,
WEFNOPARENTNOTIFY));
02490
02491
02492
02493
02494
switch (message) {
02495
case WM_LBUTTONDOWN:
02496
case WM_RBUTTONDOWN:
02497
case WM_MBUTTONDOWN:
02498
case WM_XBUTTONDOWN:
02499
while (
TestwndChild(pwndTop)) {
02500 pwndTop = pwndTop->
spwndParent;
02501
02502
if (fSend) {
02503
ThreadUnlock(&tlpwndTop);
02504
ThreadLockWithPti(pti, pwndTop, &tlpwndTop);
02505 x = (
UINT)(lppt->x - pwndTop->
rcClient.left);
02506 y = (
UINT)(lppt->y - pwndTop->
rcClient.top);
02507
02508
02509 UserAssert(message == WM_XBUTTONDOWN || HIWORD(wParam) == 0);
02510 UserAssert(LOWORD(wParam) == 0);
02511
xxxSendMessage(pwndTop, WM_PARENTNOTIFY, (WPARAM)(message | wParam), MAKELPARAM(x, y));
02512 }
02513 }
02514
02515
if (!fSend) {
02516
ThreadUnlock(&tlpwndTop);
02517
ThreadLockAlwaysWithPti(pti, pwndTop, &tlpwndTop);
02518 }
02519
02520
02521
02522
02523
break;
02524 }
02525
02526
02527
02528
02529
if (
TestUP(ACTIVEWINDOWTRACKING) && (message == WM_MOUSEMOVE)) {
02530 result =
xxxActiveWindowTracking(pwnd, WM_MOUSEMOVE, ht);
02531 }
02532
02533
02534
02535
02536
02537
02538
02539
else if ((pti->
pq->
spwndActive != pwnd || pti->
pq->
QF_flags &
QF_EVENTDEACTIVATEREMOVED) &&
02540 (pwndTop !=
PWNDDESKTOP(pwndTop))) {
02541
switch (message) {
02542
case WM_LBUTTONDOWN:
02543
case WM_RBUTTONDOWN:
02544
case WM_MBUTTONDOWN:
02545
case WM_XBUTTONDOWN:
02546
02547
02548
02549
02550 result = (
int)
xxxSendMessage(pwnd, WM_MOUSEACTIVATE,
02551 (WPARAM)(
HW(pwndTop)), MAKELONG((
SHORT)ht, message));
02552
02553
switch (result) {
02554
02555
case 0:
02556
case MA_ACTIVATE:
02557
case MA_ACTIVATEANDEAT:
02558
02559
02560
02561
02562
if ((pwndTop != pti->
pq->
spwndActive ||
02563 pti->
pq->
QF_flags &
QF_EVENTDEACTIVATEREMOVED) &&
02564 !
xxxActivateWindow(pwndTop,
02565 (
UINT)((pti->
pq->
codeCapture ==
NO_CAP_CLIENT) ?
02566
AW_TRY2 :
AW_TRY))) {
02567 result =
MA_SKIP;
02568 }
else if (
TestWF(pwndTop,
WFDISABLED)) {
02569
#ifdef NEVER
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582 result =
MA_REHITTEST;
02583
#endif
02584
02585
02586
02587
02588
02589
02590 result =
MA_SKIP;
02591 }
else if (result == MA_ACTIVATEANDEAT) {
02592 result =
MA_SKIP;
02593 }
else {
02594 result =
MA_PASSTHRU;
02595
goto ItsActiveJustCheckOnTop;
02596 }
02597
break;
02598
02599
case MA_NOACTIVATEANDEAT:
02600 result =
MA_SKIP;
02601
break;
02602 }
02603 }
02604 }
else {
02605 ItsActiveJustCheckOnTop:
02606
02607
02608
02609
02610
if (
TestUP(ACTIVEWINDOWTRACKING)) {
02611
if (
CheckOnTop(pti, pwndTop, message)) {
02612
02613
02614
02615
02616
02617
02618
02619
02620
if ((ht == HTCLIENT)
02621 && (
GETPTI(pwndTop)->TIF_flags &
TIF_CSRSSTHREAD)
02622 && !(
TestWF(pwndTop,
WEFTOPMOST))) {
02623
02624 RIPMSG2(RIP_WARNING,
"xxxMouseActivate: Skipping msg %#lx for pwnd %#p",
02625 message, pwndTop);
02626 result =
MA_SKIP;
02627 }
02628 }
02629 }
02630 }
02631
02632
02633
02634
02635
if (pti->
pq->
spwndCapture ==
NULL) {
02636
xxxSendMessage(pwnd, WM_SETCURSOR, (WPARAM)
HW(pwnd),
02637 MAKELONG((
SHORT)ht, message));
02638 }
02639
02640
ThreadUnlock(&tlpwndTop);
02641
return result;
02642 }
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653 void ResetMouseHover(
PDESKTOP pdesk, POINT pt)
02654 {
02655
02656
02657
02658
InternalSetTimer(pdesk->
spwndTrack,
IDSYS_MOUSEHOVER,
02659 pdesk->
dwMouseHoverTime,
02660
xxxSystemTimerProc, TMRF_SYSTEM);
02661
02662
SetRect(&pdesk->
rcMouseHover,
02663 pt.x -
gcxMouseHover / 2,
02664 pt.y -
gcyMouseHover / 2,
02665 pt.x +
gcxMouseHover / 2,
02666 pt.y +
gcyMouseHover / 2);
02667
02668 }
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679 BOOL QueryTrackMouseEvent(
02680 LPTRACKMOUSEEVENT lpTME)
02681 {
02682
PTHREADINFO ptiCurrent =
PtiCurrent();
02683
PDESKTOP pdesk = ptiCurrent->
rpdesk;
02684
02685
02686
02687
02688 RtlZeroMemory(lpTME,
sizeof(*lpTME));
02689 lpTME->cbSize =
sizeof(*lpTME);
02690
02691
02692
02693
02694
if (!(pdesk->
dwDTFlags &
DF_TRACKMOUSEEVENT)
02695 || (ptiCurrent->
pq !=
GETPTI(pdesk->
spwndTrack)->pq)) {
02696
return TRUE;
02697 }
02698
02699
02700
02701
if (pdesk->
htEx != HTCLIENT) {
02702 lpTME->dwFlags |= TME_NONCLIENT;
02703 }
02704
if (pdesk->
dwDTFlags &
DF_TRACKMOUSELEAVE) {
02705 lpTME->dwFlags |= TME_LEAVE;
02706 }
02707
if (pdesk->
dwDTFlags &
DF_TRACKMOUSEHOVER) {
02708 lpTME->dwFlags |= TME_HOVER;
02709 lpTME->dwHoverTime = pdesk->
dwMouseHoverTime;
02710 }
02711
02712 lpTME->hwndTrack =
HWq(pdesk->
spwndTrack);
02713
02714
return TRUE;
02715 }
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725 BOOL TrackMouseEvent(
02726 LPTRACKMOUSEEVENT lpTME)
02727 {
02728
PDESKTOP pdesk =
PtiCurrent()->rpdesk;
02729
PWND pwnd;
02730
02731
02732
02733
02734 pwnd =
ValidateHwnd(lpTME->hwndTrack);
02735
if (pwnd ==
NULL) {
02736
return FALSE;
02737 }
02738
02739
02740
02741
if ((pwnd != pdesk->
spwndTrack)
02742 || (!!(lpTME->dwFlags & TME_NONCLIENT) ^ (pdesk->
htEx != HTCLIENT))) {
02743
02744
if ((lpTME->dwFlags & TME_LEAVE) && !(lpTME->dwFlags & TME_CANCEL)) {
02745
_PostMessage(pwnd,
02746 ((lpTME->dwFlags & TME_NONCLIENT) ? WM_NCMOUSELEAVE : WM_MOUSELEAVE),
02747 0, 0);
02748 }
02749
return TRUE;
02750 }
02751
02752
02753
02754
02755
if (lpTME->dwFlags & TME_CANCEL) {
02756
if (lpTME->dwFlags & TME_LEAVE) {
02757 pdesk->
dwDTFlags &= ~
DF_TRACKMOUSELEAVE;
02758 }
02759
if (lpTME->dwFlags & TME_HOVER) {
02760
if (pdesk->
dwDTFlags &
DF_TRACKMOUSEHOVER) {
02761
_KillSystemTimer(pwnd,
IDSYS_MOUSEHOVER);
02762 pdesk->
dwDTFlags &= ~
DF_TRACKMOUSEHOVER;
02763 }
02764 }
02765
return TRUE;
02766 }
02767
02768
02769
02770
02771
if (lpTME->dwFlags & TME_LEAVE) {
02772 pdesk->
dwDTFlags |=
DF_TRACKMOUSELEAVE;
02773 }
02774
02775
02776
02777
if (lpTME->dwFlags & TME_HOVER) {
02778 pdesk->
dwDTFlags |=
DF_TRACKMOUSEHOVER;
02779
02780 pdesk->
dwMouseHoverTime = lpTME->dwHoverTime;
02781
if ((pdesk->
dwMouseHoverTime == 0) || (pdesk->
dwMouseHoverTime == HOVER_DEFAULT)) {
02782 pdesk->
dwMouseHoverTime =
gdtMouseHover;
02783 }
02784
02785
ResetMouseHover(pdesk,
GETPTI(pwnd)->ptLast);
02786 }
02787
02788
return TRUE;
02789 }
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802 PQMSG xxxGetNextSysMsg(
02803
PTHREADINFO pti,
02804
PQMSG pqmsgPrev,
02805
PQMSG pqmsg)
02806 {
02807
DWORD dt;
02808
PMLIST pml;
02809
PQMSG pqmsgT;
02810
02811
02812
02813
02814
if ((
PhkFirstGlobalValid(pti, WH_JOURNALPLAYBACK) !=
NULL)
02815 && (pti->
rpdesk ==
grpdeskRitInput)) {
02816
02817
02818
02819
02820
02821
if (pqmsgPrev != 0)
02822
return NULL;
02823
02824
02825
02826
02827
02828
dt =
xxxCallJournalPlaybackHook(pqmsg);
02829
if (
dt == 0xFFFFFFFF)
02830
return NULL;
02831
02832
02833
02834
02835
02836
if (
dt == 0) {
02837
WakeSomeone(pti->
pq, pqmsg->
msg.message,
NULL);
02838
return PQMSG_PLAYBACK;
02839 }
else {
02840
02841
02842
02843
02844 pti->
pcti->
fsWakeBits &= ~QS_INPUT;
02845 pti->
pcti->
fsChangeBits &= ~QS_INPUT;
02846
02847
02848
02849
02850
02851
SetJournalTimer(
dt, pqmsg->
msg.message);
02852
02853
return NULL;
02854 }
02855 }
02856
02857
02858
02859
02860
02861
02862
02863
02864
if (pti->
pq->
QF_flags &
QF_MOUSEMOVED) {
02865
PostMove(pti->
pq);
02866 }
02867
02868
02869
02870
02871 pml = &pti->
pq->
mlInput;
02872
if (pml->
cMsgs == 0)
02873
return NULL;
02874
02875
02876
02877
02878
02879
if (pqmsgPrev ==
NULL || pti->
pq->
idSysPeek <= (ULONG_PTR)
PQMSG_PLAYBACK) {
02880 pqmsgT = pml->
pqmsgRead;
02881 }
else {
02882
02883
02884
02885
02886
02887 pqmsgT = ((
PQMSG)(pti->
pq->
idSysPeek))->
pqmsgNext;
02888 }
02889
02890
02891
02892
02893
02894
02895
if (pqmsgT !=
NULL)
02896 *pqmsg = *pqmsgT;
02897
return pqmsgT;
02898 }
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908 void UpdateKeyState(
02909
PQ pq,
02910 UINT vk,
02911 BOOL fDown)
02912 {
02913
if (vk != 0) {
02914
02915
02916
02917
02918
if (fDown && !
TestKeyStateDown(pq, vk)) {
02919
if (
TestKeyStateToggle(pq, vk)) {
02920
ClearKeyStateToggle(pq, vk);
02921 }
else {
02922
SetKeyStateToggle(pq, vk);
02923 }
02924 }
02925
02926
02927
02928
02929
if (fDown) {
02930
SetKeyStateDown(pq, vk);
02931 }
else {
02932
ClearKeyStateDown(pq, vk);
02933 }
02934
02935
02936
02937
02938
if (vk <
CVKKEYCACHE) {
02939
gpsi->dwKeyCache++;
02940 }
02941 }
02942 }
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953 BOOL EqualMsg(
PQMSG pqmsg1,
PQMSG pqmsg2)
02954 {
02955
if (pqmsg1->
msg.hwnd != pqmsg2->
msg.hwnd ||
02956 pqmsg1->
msg.message != pqmsg2->
msg.message)
02957
return FALSE;
02958
02959
02960
02961
02962
if (pqmsg1->
msg.message == WM_MOUSEMOVE)
02963
return TRUE;
02964
02965
if (pqmsg1->
pti != pqmsg2->
pti ||
02966 pqmsg1->
msg.time != pqmsg2->
msg.time)
02967
return FALSE;
02968
02969
return TRUE;
02970 }
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982 void xxxSkipSysMsg(
02983
PTHREADINFO pti,
02984
PQMSG pqmsg)
02985 {
02986
PQMSG pqmsgT;
02987
BOOL fDown;
02988
BYTE vk;
02989
PHOOK phook;
02990
02991
02992
02993
02994
02995
02996
if (pti->
pq->
idSysPeek == 0)
02997
return;
02998
02999 phook =
PhkFirstGlobalValid(pti, WH_JOURNALPLAYBACK);
03000
if (phook !=
NULL) {
03001
03002
03003
03004
03005 phook->
flags |=
HF_NEEDHC_SKIP;
03006 }
else {
03007 phook =
PhkFirstGlobalValid(pti, WH_JOURNALRECORD);
03008
if (phook !=
NULL) {
03009
03010
03011
03012
03013
xxxCallJournalRecordHook(pqmsg);
03014 }
03015
03016
03017
03018
03019
03020
03021
if ((pqmsgT = (
PQMSG)pti->
pq->
idSysPeek) ==
NULL)
03022
return;
03023
03024
03025
03026
03027
03028
03029
if (pqmsgT !=
PQMSG_PLAYBACK) {
03030
03031
03032
03033
03034
03035
03036
03037
03038
if (!
EqualMsg(pqmsgT, pqmsg)) {
03039
03040
PQMSG pqmsgS;
03041
03042
#if DEBUGTAGS
03043
if (IsDbgTagEnabled(DBGTAG_SysPeek)) {
03044 gnSysPeekSearch++;
03045 }
03046
#endif
03047
03048 TAGMSG0(DBGTAG_SysPeek | RIP_THERESMORE,
"Different message than idSysPeek\n");
03049 TAGMSG2(DBGTAG_SysPeek | RIP_NONAME | RIP_THERESMORE,
"pqmsg = %#p idSysPeek = %#p", pqmsg, pqmsgT);
03050 TAGMSG2(DBGTAG_SysPeek | RIP_NONAME | RIP_THERESMORE,
"pti = %#p pti = %#p", pqmsg->
pti, pqmsgT->
pti);
03051 TAGMSG2(DBGTAG_SysPeek | RIP_NONAME | RIP_THERESMORE,
"msg = %08lx msg = %08lx", pqmsg->
msg.message, pqmsgT->
msg.message);
03052 TAGMSG2(DBGTAG_SysPeek | RIP_NONAME | RIP_THERESMORE,
"hwnd = %#p hwnd = %#p", pqmsg->
msg.hwnd, pqmsgT->
msg.hwnd);
03053 TAGMSG2(DBGTAG_SysPeek | RIP_NONAME | RIP_THERESMORE,
"wParam = %#p wParam = %#p", pqmsg->
msg.wParam, pqmsgT->
msg.wParam);
03054 TAGMSG2(DBGTAG_SysPeek | RIP_NONAME | RIP_THERESMORE,
"lParam = %#p lParam = %#p", pqmsg->
msg.lParam, pqmsgT->
msg.lParam);
03055 TAGMSG2(DBGTAG_SysPeek | RIP_NONAME | RIP_THERESMORE,
"time = %08lx time = %08lx", pqmsg->
msg.time, pqmsgT->
msg.time);
03056 TAGMSG2(DBGTAG_SysPeek | RIP_NONAME | RIP_THERESMORE,
"Extra = %08lx Extra = %08lx", pqmsg->
ExtraInfo, pqmsgT->
ExtraInfo);
03057 TAGMSG1(DBGTAG_SysPeek | RIP_NONAME,
"\npqmsgT = %#p", pqmsgT);
03058
03059
03060
03061
03062 pqmsgS = pti->
pq->
mlInput.
pqmsgRead;
03063
03064
while (pqmsgS !=
NULL) {
03065
if (
EqualMsg(pqmsgS, pqmsg)) {
03066 TAGMSG2(DBGTAG_SysPeek | RIP_THERESMORE,
03067
"Deleting pqmsg %#p, pti %#p",
03068 pqmsgS, pqmsgS->
pti);
03069
03070 TAGMSG4(DBGTAG_SysPeek | RIP_NONAME,
03071
"m %04lx, w %#p, l %#p, t %lx",
03072 pqmsgS->
msg.message, pqmsgS->
msg.hwnd,
03073 pqmsgS->
msg.lParam, pqmsgS->
msg.time);
03074
03075 pqmsgT = pqmsgS;
03076
break;
03077 }
03078 pqmsgS = pqmsgS->
pqmsgNext;
03079 }
03080
if (pqmsgS ==
NULL) {
03081 TAGMSG0(DBGTAG_SysPeek,
"Didn't find a matching message. No message removed.");
03082
return;
03083 }
03084 }
03085
03086
if (pqmsgT == (
PQMSG)pti->
pq->
idSysPeek) {
03087
03088
03089
03090
03091
CheckPtiSysPeek(1, pti->
pq, 0);
03092 pti->
pq->
idSysPeek = 0;
03093 }
03094
DelQEntry(&pti->
pq->
mlInput, pqmsgT);
03095 }
03096 }
03097
03098 fDown =
TRUE;
03099 vk = 0;
03100
03101
switch (pqmsg->
msg.message) {
03102
case WM_MOUSEMOVE:
03103
case WM_QUEUESYNC:
03104
default:
03105
03106
03107
03108
break;
03109
03110
case WM_KEYUP:
03111
case WM_SYSKEYUP:
03112 fDown =
FALSE;
03113
03114
03115
03116
03117
case WM_KEYDOWN:
03118
case WM_SYSKEYDOWN:
03119 vk =
LOBYTE(LOWORD(pqmsg->
msg.wParam));
03120
break;
03121
03122
case WM_LBUTTONUP:
03123 fDown =
FALSE;
03124
03125
03126
03127
03128
case WM_LBUTTONDOWN:
03129 vk = VK_LBUTTON;
03130
break;
03131
03132
case WM_RBUTTONUP:
03133 fDown =
FALSE;
03134
03135
03136
03137
03138
case WM_RBUTTONDOWN:
03139 vk = VK_RBUTTON;
03140
break;
03141
03142
case WM_MBUTTONUP:
03143 fDown =
FALSE;
03144
03145
03146
03147
03148
case WM_MBUTTONDOWN:
03149 vk = VK_MBUTTON;
03150
break;
03151
03152
case WM_XBUTTONUP:
03153 fDown =
FALSE;
03154
03155
03156
03157
03158
case WM_XBUTTONDOWN:
03159 UserAssert(GET_XBUTTON_WPARAM(pqmsg->
msg.wParam) == XBUTTON1 ||
03160 GET_XBUTTON_WPARAM(pqmsg->
msg.wParam) == XBUTTON2);
03161
03162
switch (GET_XBUTTON_WPARAM(pqmsg->
msg.wParam)) {
03163
case XBUTTON1:
03164 vk = VK_XBUTTON1;
03165
break;
03166
03167
case XBUTTON2:
03168 vk = VK_XBUTTON2;
03169
break;
03170 }
03171
03172
break;
03173 }
03174
03175
03176
03177
03178
if ((vk == VK_SHIFT) || (vk == VK_MENU) || (vk == VK_CONTROL)) {
03179
BYTE vkHanded, vkOtherHand;
03180
03181
03182
03183
03184 vkHanded = (vk - VK_SHIFT) * 2 + VK_LSHIFT +
03185 ((pqmsg->
msg.lParam & EXTENDED_BIT) ? 1 : 0);
03186 vkOtherHand = vkHanded ^ 1;
03187
03188
if (vk == VK_SHIFT) {
03189
03190
03191
03192
03193 pqmsg->
msg.lParam &= ~EXTENDED_BIT;
03194 }
03195
03196
03197
03198
03199
UpdateKeyState(pti->
pq, vkHanded, fDown);
03200
03201
03202
03203
03204
if (fDown || !
TestKeyStateDown(pti->
pq, vkOtherHand)) {
03205
UpdateKeyState(pti->
pq, vk, fDown);
03206 }
03207 }
else {
03208
UpdateKeyState(pti->
pq, vk, fDown);
03209 }
03210 }
03211
03212
03213
03214
#if DBG
03215
03216
03217
03218
03219
03220
03221
03222
03223
void LogPlayback(
03224
PWND pwnd,
03225 PMSG lpmsg)
03226 {
03227
static PWND pwndM =
NULL, pwndK =
NULL;
03228 LPCSTR lpszMsg;
03229
CHAR achBuf[20];
03230
03231
if ((lpmsg->message >= WM_MOUSEFIRST) && (lpmsg->message <= WM_MOUSELAST)) {
03232 lpszMsg = aszMouse[lpmsg->message - WM_MOUSEFIRST];
03233
if (pwnd != pwndM) {
03234
DbgPrint(
"*** Mouse input to window \"%ws\" of class \"%s\"\n",
03235 pwnd->
strName.
Length ? pwnd->
strName.
Buffer : L
"",
03236 pwnd->
pcls->lpszAnsiClassName);
03237 pwndM = pwnd;
03238 }
03239 }
else if ((lpmsg->message >= WM_KEYFIRST) && (lpmsg->message <= WM_KEYLAST)) {
03240 lpszMsg = aszKey[lpmsg->message - WM_KEYFIRST];
03241
if (pwnd != pwndK) {
03242
DbgPrint(
"*** Kbd input to window \"%ws\" of class \"%s\"\n",
03243 pwnd->
strName.
Length ? pwnd->
strName.
Buffer : L
"",
03244 pwnd->
pcls->lpszAnsiClassName);
03245 pwndK = pwnd;
03246 }
03247 }
else if (lpmsg->message == WM_QUEUESYNC) {
03248 lpszMsg =
"WM_QUEUESYNC";
03249 }
else {
03250
sprintf(achBuf,
"0x%4x", lpmsg->message);
03251 lpszMsg = achBuf;
03252 }
03253
DbgPrint(
"msg = %s, wP = %x, lP = %x\n", lpszMsg,
03254 lpmsg->wParam, lpmsg->lParam);
03255 }
03256
#endif // DBG
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267 UINT GetMouseKeyFlags(
03268
PQ pq)
03269 {
03270
UINT wParam = 0;
03271
03272
if (
TestKeyStateDown(pq, VK_LBUTTON))
03273 wParam |= MK_LBUTTON;
03274
if (
TestKeyStateDown(pq, VK_RBUTTON))
03275 wParam |= MK_RBUTTON;
03276
if (
TestKeyStateDown(pq, VK_MBUTTON))
03277 wParam |= MK_MBUTTON;
03278
if (
TestKeyStateDown(pq, VK_XBUTTON1))
03279 wParam |= MK_XBUTTON1;
03280
if (
TestKeyStateDown(pq, VK_XBUTTON2))
03281 wParam |= MK_XBUTTON2;
03282
if (
TestKeyStateDown(pq, VK_SHIFT))
03283 wParam |= MK_SHIFT;
03284
if (
TestKeyStateDown(pq, VK_CONTROL))
03285 wParam |= MK_CONTROL;
03286
03287
return wParam;
03288 }
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305 BOOL xxxScanSysQueue(
03306
PTHREADINFO ptiCurrent,
03307 LPMSG lpMsg,
03308
PWND pwndFilter,
03309 UINT msgMinFilter,
03310 UINT msgMaxFilter,
03311 DWORD flags,
03312 DWORD fsReason)
03313 {
03314
QMSG qmsg;
03315 HWND hwnd;
03316
PWND pwnd;
03317
UINT message;
03318 WPARAM wParam;
03319 LPARAM lParam;
03320
PTHREADINFO ptiKeyWake, ptiMouseWake, ptiEventWake;
03321 POINT pt, ptScreen;
03322
UINT codeMouseDown;
03323
BOOL fMouseHookCalled;
03324
BOOL fKbdHookCalled;
03325
BOOL fOtherApp;
03326
int part;
03327 MOUSEHOOKSTRUCTEX mhs;
03328
PWND pwndT;
03329
BOOL fPrevDown;
03330
BOOL fDown;
03331
BOOL fAlt;
03332
TL tlpwnd;
03333
TL tlpwndT;
03334
BOOL fRemove = (flags & PM_REMOVE);
03335
#ifdef FE_IME
03336
DWORD dwImmRet = 0;
03337
#endif
03338
#ifdef MARKPATH
03339
DWORD pathTaken = 0;
03340
DWORD pathTaken2 = 0;
03341
DWORD pathTaken3 = 0;
03342
03343
#define PATHTAKEN(x) pathTaken |= x
03344
#define PATHTAKEN2(x) pathTaken2 |= x
03345
#define PATHTAKEN3(x) pathTaken3 |= x
03346
#define DUMPPATHTAKEN() if (gfMarkPath) DbgPrint("xxxScanSysQueue path:%08x %08x %08x\n", pathTaken, pathTaken2, pathTaken3)
03347
#define DUMPSUBPATHTAKEN(p, x) if (gfMarkPath && p & x) { DbgPrint(" %08x %08x %08x\n", pathTaken, pathTaken2, pathTaken3); pathTaken = pathTaken2 = pathTaken3 = 0; }
03348
#else
03349
#define PATHTAKEN(x)
03350
#define PATHTAKEN2(x)
03351
#define PATHTAKEN3(x)
03352
#define DUMPPATHTAKEN()
03353
#define DUMPSUBPATHTAKEN(p, x)
03354
#endif
03355
03356 UserAssert(
IsWinEventNotifyDeferredOK());
03357 UserAssert((fsReason & ~(QS_EVENT | QS_INPUT)) == 0 &&
03358 (fsReason & (QS_EVENT | QS_INPUT)) != 0);
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
if (fsReason == QS_EVENT) {
03370
if (ptiCurrent->
pq->
idSysPeek != 0) {
03371
PATHTAKEN(1);
03372
DUMPPATHTAKEN();
03373
return FALSE;
03374 }
03375 }
03376
03377 fDown =
FALSE;
03378 fMouseHookCalled =
FALSE;
03379 fKbdHookCalled =
FALSE;
03380
03381
03382
03383
03384
if (ptiCurrent->
pq->
ptiSysLock ==
NULL) {
03385
CheckSysLock(3, ptiCurrent->
pq, ptiCurrent);
03386 ptiCurrent->
pq->
ptiSysLock = ptiCurrent;
03387 ptiCurrent->
pcti->
CTIF_flags |=
CTIF_SYSQUEUELOCKED;
03388 }
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399
if (fsReason & QS_INPUT) {
03400
if (fRemove) {
03401
PATHTAKEN(2);
03402 ptiCurrent->
pq->
QF_flags &= ~
QF_LOCKNOREMOVE;
03403 }
else {
03404
PATHTAKEN(4);
03405 ptiCurrent->
pq->
QF_flags |=
QF_LOCKNOREMOVE;
03406 }
03407 }
03408
03409
03410
03411
03412
if (ptiCurrent->
pq->
ptiSysLock != ptiCurrent) {
03413
PATHTAKEN(8);
03414
DUMPPATHTAKEN();
03415
return FALSE;
03416 }
03417
03418 ptiEventWake = ptiKeyWake = ptiMouseWake =
NULL;
03419
03420
03421
03422
03423
03424 pwnd =
NULL;
03425
ThreadLockWithPti(ptiCurrent, pwnd, &tlpwnd);
03426
03427 RestartScan:
03428
CheckPtiSysPeek(2, ptiCurrent->
pq, 0);
03429 ptiCurrent->
pq->
idSysPeek = 0;
03430
03431 ContinueScan:
03432
while (
TRUE) {
03433 ULONG_PTR idSysPeek;
03434
03435
DUMPSUBPATHTAKEN(pathTaken, 0xf0);
03436
03437
03438
03439
03440
03441 idSysPeek = (ULONG_PTR)
xxxGetNextSysMsg(ptiCurrent,
03442 (
PQMSG)ptiCurrent->
pq->
idSysPeek, &qmsg);
03443
CheckPtiSysPeek(3, ptiCurrent->
pq, idSysPeek);
03444 ptiCurrent->
pq->
idSysPeek = idSysPeek;
03445
03446
if (ptiCurrent->
pq->
idSysPeek == 0) {
03447
03448
03449
03450
03451
if (fsReason == QS_EVENT)
03452
ClearWakeBit(ptiCurrent, QS_EVENT,
FALSE);
03453
PATHTAKEN(0x10);
03454
goto NoMessages;
03455 }
03456
03457
03458
03459
03460
03461
03462
ThreadUnlock(&tlpwnd);
03463 pwnd =
RevalidateHwnd(qmsg.
msg.hwnd);
03464
ThreadLockWithPti(ptiCurrent, pwnd, &tlpwnd);
03465
03466
03467
03468
03469
03470
03471
if (qmsg.
dwQEvent != 0) {
03472
PTHREADINFO pti;
03473
03474
PATHTAKEN(0x20);
03475
03476
03477
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488
switch (qmsg.
dwQEvent) {
03489
case QEVENT_UPDATEKEYSTATE:
03490
03491
03492
03493
03494
if (ptiCurrent->
pq->
idSysPeek !=
03495 (ULONG_PTR)ptiCurrent->
pq->
mlInput.
pqmsgRead) {
03496
PATHTAKEN(0x40);
03497
continue;
03498 }
03499
break;
03500 }
03501
03502
03503
03504
03505
03506
03507
if (qmsg.
pti !=
NULL && (pti = qmsg.
pti) != ptiCurrent) {
03508
03509
03510
03511
03512
03513 UserAssert(pti->pq == ptiCurrent->
pq);
03514
if (pti->pq != ptiCurrent->
pq) {
03515
CleanEventMessage((
PQMSG)ptiCurrent->
pq->
idSysPeek);
03516
DelQEntry(&ptiCurrent->
pq->
mlInput,
03517 (
PQMSG)ptiCurrent->
pq->
idSysPeek);
03518
PATHTAKEN(0x80);
03519
goto RestartScan;
03520 }
03521
03522
03523
03524
03525
03526
if (ptiEventWake ==
NULL)
03527 ptiEventWake = pti;
03528
03529
03530
03531
03532
03533
03534
CheckPtiSysPeek(4, ptiCurrent->
pq, 0);
03535 ptiCurrent->
pq->
idSysPeek = 0;
03536
PATHTAKEN(0x100);
03537
goto NoMessages;
03538 }
03539
03540
03541
03542
03543
03544
03545
if ((flags & PM_NOYIELD) && (ptiCurrent->
TIF_flags &
TIF_16BIT)) {
03546
PATHTAKEN(0x200);
03547
switch (qmsg.
dwQEvent) {
03548
03549
03550
03551
03552
03553
case QEVENT_UPDATEKEYSTATE:
03554
case QEVENT_ASYNCSENDMSG:
03555
break;
03556
03557
03558
03559
03560
default:
03561 ptiCurrent->
TIF_flags |=
TIF_DELAYEDEVENT;
03562 ptiCurrent->
pClientInfo->
dwTIFlags = ptiCurrent->
TIF_flags;
03563
PATHTAKEN(0x400);
03564
goto ContinueScan;
03565 }
03566 }
03567
03568
03569
03570
03571
03572
DelQEntry(&ptiCurrent->
pq->
mlInput,
03573 (
PQMSG)ptiCurrent->
pq->
idSysPeek);
03574
03575
03576
03577
03578
03579
CheckPtiSysPeek(5, ptiCurrent->
pq, 0);
03580 ptiCurrent->
pq->
idSysPeek = 0;
03581
xxxProcessEventMessage(ptiCurrent, &qmsg);
03582
03583
03584
03585
03586
03587
PATHTAKEN(0x800);
03588
goto RestartScan;
03589 }
03590
03591
03592
03593
03594
03595
if (fsReason == QS_EVENT) {
03596
PATHTAKEN(0x1000);
03597
continue;
03598 }
03599
03600
switch (message = qmsg.
msg.message) {
03601
case WM_QUEUESYNC:
03602
PATHTAKEN(0x2000);
03603
03604
03605
03606
03607 wParam = 0;
03608 lParam = qmsg.
msg.lParam;
03609
03610
03611
03612
03613
03614
if (pwnd !=
NULL &&
GETPTI(pwnd) != ptiCurrent) {
03615
03616
03617
03618
03619
03620
03621
03622
03623
if (
GETPTI(pwnd)->pq != ptiCurrent->
pq) {
03624
PATHTAKEN(0x4000);
03625
goto SkipMessage;
03626 }
03627
03628
if (ptiMouseWake ==
NULL)
03629 ptiMouseWake =
GETPTI(pwnd);
03630
PATHTAKEN(0x8000);
03631
goto NoMessages;
03632 }
03633
03634
if (!
CheckMsgFilter(message, msgMinFilter, msgMaxFilter)) {
03635
PATHTAKEN(0x10000);
03636
goto NoMessages;
03637 }
03638
03639
03640
03641
03642
if (fRemove) {
03643
xxxSkipSysMsg(ptiCurrent, &qmsg);
03644 }
03645
03646
03647
03648
03649
03650
03651
03652
03653
PATHTAKEN(0x20000);
03654
goto ReturnMessage;
03655
break;
03656
03657
03658
03659
03660
03661
03662
default:
03663 ReprocessMsg:
03664
DUMPSUBPATHTAKEN(pathTaken, 0x40000);
03665
PATHTAKEN(0x40000);
03666
03667
03668
03669
03670
03671
03672
03673 pt.x = (
int)(
short)LOWORD(qmsg.
msg.lParam);
03674 pt.y = (
int)(
short)HIWORD(qmsg.
msg.lParam);
03675
03676
03677
03678
03679 part = HTCLIENT;
03680
03681
03682
03683
03684
03685
if (
gspwndScreenCapture !=
NULL) {
03686
03687
03688
03689 pwnd =
gspwndScreenCapture;
03690 lParam = MAKELONG((WORD)qmsg.
msg.pt.x,
03691 (WORD)qmsg.
msg.pt.y);
03692
PATHTAKEN(0x80000);
03693 }
else if ((pwnd = ptiCurrent->
pq->
spwndCapture) ==
NULL) {
03694
03695
PATHTAKEN(0x100000);
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706 pwndT =
gptiRit->
rpdesk->
pDeskInfo->
spwnd;
03707
03708
ThreadLockWithPti(ptiCurrent, pwndT, &tlpwndT);
03709
03710 hwnd =
xxxWindowHitTest(pwndT, pt, &part,
WHT_IGNOREDISABLED);
03711
ThreadUnlock(&tlpwndT);
03712
03713
if ((pwnd =
RevalidateHwnd(hwnd)) ==
NULL) {
03714 pwnd = ptiCurrent->
rpdesk->
pDeskInfo->
spwnd;
03715
PATHTAKEN(0x200000);
03716 }
03717
03718
if (part == HTCLIENT) {
03719
03720
03721
03722
03723
03724 ptiCurrent->
pq->
codeCapture =
NO_CAP_CLIENT;
03725
PATHTAKEN(0x400000);
03726 }
else {
03727
03728
03729
03730
03731
03732 ptiCurrent->
pq->
codeCapture =
NO_CAP_SYS;
03733
PATHTAKEN(0x800000);
03734 }
03735 }
03736
03737
03738
03739
03740
ThreadLockExchange(pwnd, &tlpwnd);
03741
03742
if (fOtherApp = (
GETPTI(pwnd) != ptiCurrent)) {
03743
03744
PATHTAKEN(0x1000000);
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754
if (
GETPTI(pwnd)->pq != ptiCurrent->
pq) {
03755
zzzSetCursor(
SYSCUR(ARROW));
03756
PATHTAKEN(0x2000000);
03757
goto SkipMessage;
03758 }
03759
03760
03761
03762
03763
03764
if (ptiMouseWake ==
NULL) {
03765 ptiMouseWake =
GETPTI(pwnd);
03766
PATHTAKEN(0x4000000);
03767 }
03768 }
03769
03770
03771
03772
03773 ptScreen = pt;
03774
switch (ptiCurrent->
pq->
codeCapture) {
03775
case CLIENT_CAPTURE:
03776
case NO_CAP_CLIENT:
03777
#ifdef USE_MIRRORING
03778
03779
if (
TestWF(pwnd, WEFLAYOUTRTL)) {
03780 pt.x = pwnd->
rcClient.right - pt.x;
03781 }
else
03782
#endif
03783
{
03784 pt.x -= pwnd->
rcClient.left;
03785 }
03786 pt.y -= pwnd->
rcClient.top;
03787
PATHTAKEN2(2);
03788
break;
03789
03790
case WINDOW_CAPTURE:
03791
#ifdef USE_MIRRORING
03792
03793
if (
TestWF(pwnd, WEFLAYOUTRTL)) {
03794 pt.x = pwnd->
rcWindow.right - pt.x;
03795 }
else
03796
#endif
03797
{
03798 pt.x -= pwnd->
rcWindow.left;
03799 }
03800 pt.y -= pwnd->
rcWindow.top;
03801
PATHTAKEN2(4);
03802
break;
03803 }
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
if (!fOtherApp && (ptiCurrent->
pq ==
gpqCursor)) {
03819
BOOL fNewpwndTrack = (ptiCurrent->
rpdesk->
spwndTrack != pwnd);
03820
int htEx =
FindNCHitEx(pwnd, part, pt);
03821
if ((message != WM_MOUSEMOVE)
03822 || fNewpwndTrack
03823 || (ptiCurrent->
rpdesk->
htEx != htEx)) {
03824
03825
xxxTrackMouseMove(pwnd, htEx, message);
03826 ValidateThreadLocks(
NULL, ptiCurrent->
ptl, (ULONG_PTR)&tlpwnd,
TRUE);
03827 }
03828
03829
03830
03831
03832
03833
if (!fNewpwndTrack && (ptiCurrent->
rpdesk->
dwDTFlags &
DF_TRACKMOUSEHOVER)) {
03834
if ((message != WM_MOUSEMOVE)
03835 || !
PtInRect(&ptiCurrent->
rpdesk->
rcMouseHover, ptScreen)) {
03836
03837
ResetMouseHover(ptiCurrent->
rpdesk, ptScreen);
03838 }
03839 }
else {
03840
03841
03842
03843 UserAssert(!(ptiCurrent->
rpdesk->
dwDTFlags &
DF_TRACKMOUSEHOVER));
03844 }
03845
03846 }
03847
03848
03849
03850
03851
03852
if (!
CheckPwndFilter(pwnd, pwndFilter)) {
03853
PATHTAKEN(0x8000000);
03854
continue;
03855 }
03856
03857
03858
03859
03860 codeMouseDown = 0;
03861
switch (message) {
03862
case WM_LBUTTONDOWN:
03863
case WM_RBUTTONDOWN:
03864
case WM_MBUTTONDOWN:
03865
case WM_XBUTTONDOWN:
03866
if (
TestCF(pwnd,
CFDBLCLKS) ||
03867 ptiCurrent->
pq->
codeCapture ==
NO_CAP_SYS ||
03868
IsMenuStarted(ptiCurrent)) {
03869 codeMouseDown++;
03870
PATHTAKEN(0x10000000);
03871
if (qmsg.
msg.time <= ptiCurrent->
pq->
timeDblClk &&
03872 (!
gbClientDoubleClickSupport) &&
03873
HW(pwnd) == ptiCurrent->
pq->
hwndDblClk &&
03874 message == ptiCurrent->
pq->
msgDblClk &&
03875 (message != WM_XBUTTONDOWN ||
03876 GET_XBUTTON_WPARAM(qmsg.
msg.wParam) == ptiCurrent->
pq->
xbtnDblClk)) {
03877 RECT rcDblClk = {
03878 ptiCurrent->
pq->
ptDblClk.x -
SYSMET(CXDOUBLECLK) / 2,
03879 ptiCurrent->
pq->
ptDblClk.y -
SYSMET(CYDOUBLECLK) / 2,
03880 ptiCurrent->
pq->
ptDblClk.x +
SYSMET(CXDOUBLECLK) / 2,
03881 ptiCurrent->
pq->
ptDblClk.y +
SYSMET(CYDOUBLECLK) / 2
03882 };
03883
if (
PtInRect(&rcDblClk, qmsg.
msg.pt)) {
03884 message += (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
03885 codeMouseDown++;
03886
PATHTAKEN(0x20000000);
03887 }
03888 }
03889 }
03890
03891
03892
03893
case WM_LBUTTONUP:
03894
case WM_RBUTTONUP:
03895
case WM_MBUTTONUP:
03896
case WM_XBUTTONUP:
03897
03898
03899
03900
03901
03902
PATHTAKEN(0x40000000);
03903
if (ptiCurrent->
pq->
QF_flags &
QF_FMENUSTATUS) {
03904 ptiCurrent->
pq->
QF_flags |=
QF_FMENUSTATUSBREAK;
03905
PATHTAKEN(0x80000000);
03906 }
03907 }
03908
03909
03910
03911
03912
if (ptiCurrent->
pq->
codeCapture ==
NO_CAP_SYS) {
03913 message += (
UINT)(WM_NCMOUSEMOVE - WM_MOUSEMOVE);
03914 wParam = (
UINT)part;
03915
PATHTAKEN2(1);
03916 }
03917
03918
03919
03920
03921
03922
if (!
CheckMsgFilter(message, msgMinFilter, msgMaxFilter)) {
03923
PATHTAKEN2(8);
03924
continue;
03925 }
03926
03927
03928
03929
03930
03931
03932
03933
03934
if (fOtherApp) {
03935
PATHTAKEN2(0x10);
03936
goto NoMessages;
03937 }
03938
03939
03940
03941
03942
03943
03944
03945
03946
03947
03948
if (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST &&
03949 ptiCurrent->
TIF_flags &
TIF_MOVESIZETRACKING) {
03950
PATHTAKEN2(0x20);
03951
continue;
03952 }
03953
03954
if (
FWINABLE() && (ptiCurrent->
TIF_flags &
TIF_MSGPOSCHANGED)) {
03955 ptiCurrent->
TIF_flags &= ~
TIF_MSGPOSCHANGED;
03956
xxxWindowEvent(EVENT_OBJECT_LOCATIONCHANGE,
NULL,
03957 OBJID_CURSOR, INDEXID_CONTAINER,
TRUE);
03958 ValidateThreadLocks(
NULL, ptiCurrent->
ptl, (ULONG_PTR)&tlpwnd,
TRUE);
03959 }
03960
03961
03962
03963
03964
03965
03966
03967
03968
03969
if (
IsHooked(ptiCurrent,
WHF_MOUSE)) {
03970 fMouseHookCalled =
TRUE;
03971 mhs.pt = qmsg.
msg.pt;
03972 mhs.hwnd =
HW(pwnd);
03973 mhs.wHitTestCode = (
UINT)part;
03974 mhs.dwExtraInfo = qmsg.
ExtraInfo;
03975 UserAssert(LOWORD(qmsg.
msg.wParam) == 0);
03976 mhs.mouseData = (
DWORD)qmsg.
msg.wParam;
03977
03978
if (
xxxCallMouseHook(message, &mhs, fRemove)) {
03979
03980
03981
03982
PATHTAKEN2(0x40);
03983
goto SkipMessage;
03984 }
03985
PATHTAKEN2(0x80);
03986 ValidateThreadLocks(
NULL, ptiCurrent->
ptl, (ULONG_PTR)&tlpwnd,
TRUE);
03987 }
03988
03989
03990
03991
03992
03993
03994
switch (part) {
03995
case HTERROR:
03996
case HTNOWHERE:
03997
03998
03999
04000
xxxSendMessage(pwnd, WM_SETCURSOR, (WPARAM)
HW(pwnd),
04001 MAKELONG(part, qmsg.
msg.message));
04002
04003
04004
04005
04006
PATHTAKEN2(0x100);
04007
goto SkipMessage;
04008
break;
04009 }
04010
04011
if (fRemove) {
04012
PATHTAKEN2(0x200);
04013
04014
04015
04016
04017
04018
04019
04020
switch (codeMouseDown) {
04021
case 1:
04022
04023
04024
04025 ptiCurrent->
pq->
msgDblClk = qmsg.
msg.message;
04026
04027
04028
04029
04030
04031
04032
04033 UserAssert(qmsg.
msg.message == WM_XBUTTONDOWN || GET_XBUTTON_WPARAM(qmsg.
msg.wParam) == 0);
04034 ptiCurrent->
pq->
xbtnDblClk = GET_XBUTTON_WPARAM(qmsg.
msg.wParam);
04035
04036 ptiCurrent->
pq->
timeDblClk = qmsg.
msg.time +
gdtDblClk;
04037 ptiCurrent->
pq->
hwndDblClk =
HW(pwnd);
04038 ptiCurrent->
pq->
ptDblClk = qmsg.
msg.pt;
04039
PATHTAKEN2(0x400);
04040
break;
04041
04042
case 2:
04043
04044
04045
04046 ptiCurrent->
pq->
timeDblClk = 0
L;
04047
PATHTAKEN2(0x800);
04048
break;
04049
04050
default:
04051
PATHTAKEN2(0x1000);
04052
break;
04053 }
04054
04055
04056
04057
04058
04059
switch (
xxxMouseActivate(ptiCurrent, pwnd,
04060 qmsg.
msg.message, qmsg.
msg.wParam, &qmsg.
msg.pt, part)) {
04061 SkipMessage:
04062
case MA_SKIP:
04063
DUMPSUBPATHTAKEN(pathTaken2, 0x2000);
04064
PATHTAKEN2(0x2000);
04065
xxxSkipSysMsg(ptiCurrent, &qmsg);
04066
04067
04068
04069
04070
if (fMouseHookCalled) {
04071
if (
IsHooked(ptiCurrent,
WHF_CBT)) {
04072
xxxCallHook(HCBT_CLICKSKIPPED, message,
04073 (LPARAM)&mhs, WH_CBT);
04074
PATHTAKEN2(0x4000);
04075 }
04076 fMouseHookCalled =
FALSE;
04077 }
04078
04079
04080
04081
04082
if (fKbdHookCalled) {
04083
if (
IsHooked(ptiCurrent,
WHF_CBT)) {
04084
xxxCallHook(HCBT_KEYSKIPPED, wParam, lParam,
04085 WH_CBT);
04086
PATHTAKEN2(0x8000);
04087 }
04088 fKbdHookCalled =
FALSE;
04089 }
04090
04091
04092
04093
04094
04095
04096
04097
if (!fRemove) {
04098
PATHTAKEN2(0x10000);
04099
goto ContinueScan;
04100 }
else {
04101
PATHTAKEN2(0x20000);
04102
goto RestartScan;
04103 }
04104
break;
04105
04106
case MA_REHITTEST:
04107
04108
04109
04110
PATHTAKEN2(0x40000);
04111
goto ReprocessMsg;
04112 }
04113 }
04114
04115
04116
04117
04118
04119
PATHTAKEN2(0x80000);
04120
if (fRemove) {
04121
xxxSkipSysMsg(ptiCurrent, &qmsg);
04122 }
04123
04124
if (fRemove && fMouseHookCalled &&
IsHooked(ptiCurrent,
WHF_CBT)) {
04125
xxxCallHook(HCBT_CLICKSKIPPED, message,
04126 (LPARAM)&mhs, WH_CBT);
04127 }
04128 fMouseHookCalled =
FALSE;
04129
04130 lParam = MAKELONG((
short)pt.x, (
short)pt.y);
04131
04132
04133
04134
04135
if (message >= WM_MOUSEFIRST) {
04136
04137
04138
04139
04140 wParam =
GetMouseKeyFlags(ptiCurrent->
pq);
04141
PATHTAKEN2(0x100000);
04142 }
04143
04144
if ( (WM_NCXBUTTONFIRST <= message && message <= WM_NCXBUTTONLAST) ||
04145 (WM_XBUTTONFIRST <= message && message <= WM_XBUTTONLAST)) {
04146
04147
04148
04149
04150
04151 UserAssert(LOWORD(qmsg.
msg.wParam) == 0);
04152 UserAssert(HIWORD(wParam) == 0);
04153 wParam |= qmsg.
msg.wParam;
04154 }
04155
04156
PATHTAKEN2(0x200000);
04157
04158
04159
04160
04161
04162
04163
04164
if ((part == HTMENU)
04165 && fRemove
04166 && (ptiCurrent->
pMenuState !=
NULL)
04167 && ptiCurrent->
pMenuState->
fModelessMenu
04168 && (ptiCurrent->
pMenuState->
pGlobalPopupMenu !=
NULL)
04169 && (ptiCurrent->
pMenuState->
pGlobalPopupMenu->
fIsMenuBar)) {
04170
04171
if (
xxxCallHandleMenuMessages(ptiCurrent->
pMenuState, pwnd, message, wParam, lParam)) {
04172
goto RestartScan;
04173 }
04174 }
04175
04176
goto ReturnMessage;
04177
break;
04178
04179
case WM_KEYDOWN:
04180
case WM_SYSKEYDOWN:
04181 fDown =
TRUE;
04182
04183
04184
04185
04186
04187
04188
04189
04190
if (ptiCurrent->
TIF_flags &
TIF_SPINNING)
04191
CheckProcessForeground(ptiCurrent);
04192
04193
04194
04195
04196
04197 wParam = qmsg.
msg.wParam & 0xFF;
04198
04199
04200
04201
04202
04203
04204
if (wParam != VK_MENU)
04205 ptiCurrent->
pq->
QF_flags &= ~(
QF_FMENUSTATUS|
QF_FMENUSTATUSBREAK);
04206
04207
04208
04209
04210
04211
04212
04213
if (
gLangToggle[0].
bVkey && (
gLangToggleKeyState <
KLT_NONE)) {
04214
DWORD i;
04215
BYTE scancode =
LOBYTE(HIWORD(qmsg.
msg.lParam));
04216
BYTE vkey =
LOBYTE(qmsg.
msg.wParam);
04217
04218
for (i = 0; i <
LANGTOGGLEKEYS_SIZE; i++) {
04219
if (
gLangToggle[i].
bScan) {
04220
if (
gLangToggle[i].
bScan == scancode) {
04221
gLangToggleKeyState |=
gLangToggle[i].
iBitPosition;
04222
break;
04223 }
04224 }
else {
04225
if (
gLangToggle[i].
bVkey == vkey) {
04226
gLangToggleKeyState |=
gLangToggle[i].
iBitPosition;
04227
break;
04228 }
04229 }
04230 }
04231
04232
if (i ==
LANGTOGGLEKEYS_SIZE) {
04233
gLangToggleKeyState =
KLT_NONE;
04234 }
04235 }
04236
04237
04238
04239
04240 fAlt =
TestKeyStateDown(ptiCurrent->
pq, VK_MENU);
04241
if (wParam == VK_SNAPSHOT &&
04242 ((fAlt && !(ptiCurrent->
fsReserveKeys & CONSOLE_ALTPRTSC)) ||
04243 (!fAlt && !(ptiCurrent->
fsReserveKeys & CONSOLE_PRTSC)))) {
04244
04245
04246
04247
04248
PATHTAKEN2(0x400000);
04249
xxxSkipSysMsg(ptiCurrent, &qmsg);
04250
04251
04252
04253
04254
04255 pwndT = ptiCurrent->
pq->
spwndActive;
04256
04257
04258
04259
04260
04261
04262
if (!fAlt && ((qmsg.
msg.lParam & 0x00FF0000) != 0x00010000)) {
04263 pwndT = ptiCurrent->
rpdesk->
pDeskInfo->
spwnd;
04264 }
04265
04266
if (pwndT !=
NULL) {
04267
ThreadLockAlwaysWithPti(ptiCurrent, pwndT, &tlpwndT);
04268
xxxSnapWindow(pwndT);
04269
ThreadUnlock(&tlpwndT);
04270 }
04271
04272
PATHTAKEN2(0x800000);
04273
goto RestartScan;
04274 }
04275
04276
04277
04278
04279
if (
gcHotKey != 0 && (!
gfEnableHexNumpad || (
gfInNumpadHexInput &
NUMPAD_HEXMODE_HL) == 0)) {
04280
UINT key;
04281 key = (
UINT)wParam;
04282
04283
if (
TestKeyStateDown(ptiCurrent->
pq, VK_MENU))
04284 key |= 0x0400;
04285
04286
if (
TestKeyStateDown(ptiCurrent->
pq, VK_CONTROL))
04287 key |= 0x0200;
04288
04289
if (
TestKeyStateDown(ptiCurrent->
pq, VK_SHIFT))
04290 key |= 0x0100;
04291
04292 pwndT =
HotKeyToWindow(key);
04293
04294
if (pwndT !=
NULL) {
04295
04296
04297
04298 UserAssert((key & 0xff) != VK_PACKET);
04299
04300
_PostMessage(ptiCurrent->
pq->
spwndActive, WM_SYSCOMMAND,
04301 (WPARAM)SC_HOTKEY, (LPARAM)
HWq(pwndT));
04302
04303
04304
04305
04306
xxxSkipSysMsg(ptiCurrent, &qmsg);
04307
PATHTAKEN2(0x1000000);
04308
goto RestartScan;
04309 }
04310
04311
PATHTAKEN2(0x2000000);
04312 }
04313
04314
#if DBG
04315
else if (
gfInNumpadHexInput &
NUMPAD_HEXMODE_HL) {
04316 RIPMSG0(RIP_VERBOSE,
"xxxScanSysQueue: gfInNumpadHexInput is true, so we skipped hotkey.");
04317 }
04318
#endif
04319
04320
if (wParam == VK_PACKET) {
04321
04322
04323
04324 ptiCurrent->
wchInjected = HIWORD(qmsg.
msg.wParam);
04325 qmsg.
msg.wParam = wParam;
04326 UserAssert(qmsg.
msg.wParam == VK_PACKET);
04327 }
04328
04329
04330
04331
04332
04333
case WM_SYSKEYUP:
04334
case WM_KEYUP:
04335 wParam = qmsg.
msg.wParam & 0xFF;
04336
if (wParam == VK_PACKET) {
04337 qmsg.
msg.wParam = wParam;
04338 }
04339
04340
04341
04342
04343
04344
04345
if (
gbGraveKeyToggle &&
04346
04347
04348
04349
04350 !(
GetAppImeCompatFlags(
NULL) & IMECOMPAT_HYDRACLIENT) &&
04351
LOBYTE(HIWORD(qmsg.
msg.lParam)) == SCANCODE_THAI_LAYOUT_TOGGLE &&
04352 fRemove &&
04353 !
TestKeyStateDown(ptiCurrent->
pq, VK_SHIFT) &&
04354 !
TestKeyStateDown(ptiCurrent->
pq, VK_MENU) &&
04355 !
TestKeyStateDown(ptiCurrent->
pq, VK_CONTROL) &&
04356 !
TestKeyStateDown(ptiCurrent->
pq, VK_LWIN) &&
04357 !
TestKeyStateDown(ptiCurrent->
pq, VK_RWIN)){
04358
04359
if ((pwnd = ptiCurrent->
pq->
spwndFocus) ==
NULL){
04360 pwnd = ptiCurrent->
pq->
spwndActive;
04361 }
04362
04363
04364
04365
04366
if (!fDown && pwnd){
04367
PTHREADINFO ptiToggle =
GETPTI(pwnd);
04368
PKL pkl = ptiToggle->
spklActive;
04369
04370
if (pkl && (pkl =
HKLtoPKL(ptiToggle, (HKL)HKL_NEXT))) {
04371
_PostMessage(
04372 pwnd,
04373 WM_INPUTLANGCHANGEREQUEST,
04374 (WPARAM)(((pkl->dwFontSigs &
gSystemFS) ? INPUTLANGCHANGE_SYSCHARSET : 0) | INPUTLANGCHANGE_FORWARD),
04375 (LPARAM)pkl->hkl
04376 );
04377 }
04378 }
04379
04380
04381
04382
xxxSkipSysMsg(ptiCurrent, &qmsg);
04383
goto RestartScan;
04384 }
04385
04386
04387
04388
04389
04390
04391
04392
04393
04394
04395
if (!fDown && fRemove &&
gLangToggle[0].
bVkey) {
04396
BOOL bDropToggle =
FALSE;
04397
DWORD dwDirection = 0;
04398
PKL pkl;
04399
PTHREADINFO ptiToggle;
04400
04401
BOOL bArabicSwitchPresent =
FALSE;
04402 LCID lcid;
04403
04404 ZwQueryDefaultLocale(
FALSE, &lcid);
04405
04406 pwnd = ptiCurrent->
pq->
spwndFocus;
04407
if (pwnd ==
NULL) {
04408 pwnd = ptiCurrent->
pq->
spwndActive;
04409
if (!pwnd) {
04410
goto NoLayoutSwitch;
04411 }
04412 }
04413
04414 ptiToggle =
GETPTI(pwnd);
04415 pkl = ptiToggle->
spklActive;
04416 UserAssert(ptiToggle->
spklActive !=
NULL);
04417
04418
04419
04420
04421
if (
gLangToggleKeyState <
KLT_NONE && PRIMARYLANGID(lcid) == LANG_ARABIC){
04422
PKL pkl_next =
HKLtoPKL (ptiToggle, (HKL)HKL_NEXT);
04423
04424
04425
04426
04427
04428
if (pkl && pkl_next &&
04429 pkl->
hkl != pkl_next->
hkl && pkl_next ==
HKLtoPKL(ptiToggle, (HKL)HKL_PREV) &&
04430 (PRIMARYLANGID(HandleToUlong(pkl->
hkl)) == LANG_ARABIC || PRIMARYLANGID(HandleToUlong(pkl_next->
hkl)) == LANG_ARABIC)){
04431 bArabicSwitchPresent =
TRUE;
04432 }
04433 }
04434
04435
04436
04437
04438
04439
switch (
gLangToggleKeyState) {
04440
case KLT_ALTLEFTSHIFT:
04441 bDropToggle =
TRUE;
04442 dwDirection = INPUTLANGCHANGE_FORWARD;
04443
if (!bArabicSwitchPresent || PRIMARYLANGID(HandleToUlong(pkl->
hkl)) == LANG_ARABIC){
04444 pkl =
HKLtoPKL(ptiToggle, (HKL)HKL_NEXT);
04445 }
04446
break;
04447
04448
case KLT_ALTRIGHTSHIFT:
04449 bDropToggle =
TRUE;
04450 dwDirection = INPUTLANGCHANGE_BACKWARD;
04451
if (!bArabicSwitchPresent || PRIMARYLANGID(HandleToUlong(pkl->
hkl)) != LANG_ARABIC){
04452 pkl =
HKLtoPKL(ptiToggle, (HKL)HKL_PREV);
04453 }
04454
break;
04455
04456
case KLT_ALTBOTHSHIFTS:
04457 pkl =
gspklBaseLayout;
04458
break;
04459
04460
default:
04461
goto NoLayoutSwitch;
04462
break;
04463 }
04464
04465
if (pkl ==
NULL) {
04466 pkl =
GETPTI(pwnd)->spklActive;
04467 }
04468
04469
04470
04471
04472
04473
04474 UserAssert(
gspklBaseLayout !=
NULL);
04475 UserAssert(pkl);
04476
if (pkl) {
04477
04478
04479
04480
04481
04482
04483
04484
04485
04486
_PostMessage(pwnd, WM_INPUTLANGCHANGEREQUEST,
04487 (
DWORD)(((pkl->
dwFontSigs &
gSystemFS) ? INPUTLANGCHANGE_SYSCHARSET : 0) | dwDirection),
04488 (LPARAM)pkl->
hkl);
04489 }
04490
04491 NoLayoutSwitch:
04492
04493
if (bDropToggle) {
04494
04495
04496
04497
04498
04499
04500
DWORD i;
04501
BYTE scancode =
LOBYTE(HIWORD(qmsg.
msg.lParam));
04502
BYTE vkey =
LOBYTE(qmsg.
msg.wParam);
04503
04504
for (i = 0; i <
LANGTOGGLEKEYS_SIZE; i++) {
04505
if (
gLangToggle[i].
bScan) {
04506
if (
gLangToggle[i].
bScan == scancode) {
04507
gLangToggleKeyState &= ~(
gLangToggle[i].
iBitPosition);
04508 }
04509 }
else {
04510
if (
gLangToggle[i].
bVkey == vkey) {
04511
gLangToggleKeyState &= ~(
gLangToggle[i].
iBitPosition);
04512 }
04513 }
04514 }
04515 }
else {
04516
gLangToggleKeyState = 0;
04517 }
04518 }
04519
04520
04521
04522
04523
if (wParam == VK_F10)
04524 message |= (WM_SYSKEYDOWN - WM_KEYDOWN);
04525
04526
if (
TestKeyStateDown(ptiCurrent->
pq, VK_CONTROL) &&
04527 wParam == VK_ESCAPE) {
04528 message |= (WM_SYSKEYDOWN - WM_KEYDOWN);
04529 }
04530
04531
04532
04533
04534
04535
04536
04537
04538
04539
if (!(ptiCurrent->
TIF_flags &
TIF_CSRSSTHREAD))
04540 qmsg.
msg.lParam &= ~FAKE_KEYSTROKE;
04541
PATHTAKEN2(0x4000000);
04542
04543
04544
04545
04546
04547
04548
04549
04550
04551
04552
04553
04554
04555
04556
04557
case WM_CHAR:
04558 wParam = qmsg.
msg.wParam & 0xFF;
04559
04560
04561
04562
04563
04564 pwnd = ptiCurrent->
pq->
spwndFocus;
04565
if (ptiCurrent->
pq->
spwndFocus ==
NULL) {
04566
if ((pwnd = ptiCurrent->
pq->
spwndActive) !=
NULL) {
04567
if (
CheckMsgFilter(message, WM_KEYDOWN, WM_DEADCHAR)) {
04568 message += (WM_SYSKEYDOWN - WM_KEYDOWN);
04569
PATHTAKEN2(0x8000000);
04570 }
04571 }
else {
04572
PATHTAKEN2(0x10000000);
04573
goto SkipMessage;
04574 }
04575 }
04576
04577
04578
04579
04580
04581
if (pwnd ==
NULL) {
04582
PATHTAKEN2(0x20000000);
04583
goto SkipMessage;
04584 }
04585
04586
ThreadUnlock(&tlpwnd);
04587
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd);
04588
04589
04590
04591
04592
if (fOtherApp = (
GETPTI(pwnd) != ptiCurrent)) {
04593
PWND pwndModalLoop;
04594
04595
04596
04597
04598
04599
04600
04601
04602
04603
04604
if (
GETPTI(pwnd)->pq != ptiCurrent->
pq) {
04605
PATHTAKEN2(0x40000000);
04606
goto SkipMessage;
04607 }
04608
04609
04610
04611
04612
04613
if (
IsInsideMenuLoop(ptiCurrent)) {
04614 pwndModalLoop = ptiCurrent->
pMenuState->
pGlobalPopupMenu->
spwndNotify;
04615 }
else if (ptiCurrent->
pmsd !=
NULL) {
04616 pwndModalLoop = ptiCurrent->
pmsd->
spwnd;
04617 RIPMSG0(RIP_WARNING,
"xxxScanSysQueue: returning key to movesize loop");
04618 }
else {
04619 pwndModalLoop =
NULL;
04620 }
04621
04622
04623
04624
04625
if (pwndModalLoop !=
NULL) {
04626 pwnd = pwndModalLoop;
04627 fOtherApp = (
GETPTI(pwnd) != ptiCurrent);
04628
ThreadUnlock(&tlpwnd);
04629
ThreadLockWithPti(ptiCurrent, pwnd, &tlpwnd);
04630
PATHTAKEN2(0x80000000);
04631 }
04632
04633
04634
04635
04636
if (ptiKeyWake ==
NULL) {
04637
PATHTAKEN3(1);
04638 ptiKeyWake =
GETPTI(pwnd);
04639 }
04640 }
04641
04642
04643
04644
04645
if (!
CheckMsgFilter(message, msgMinFilter, msgMaxFilter) ||
04646 !
CheckPwndFilter(pwnd, pwndFilter)) {
04647
PATHTAKEN3(2);
04648
continue;
04649 }
04650
04651
04652
04653
04654
04655
04656
if (fOtherApp) {
04657
PATHTAKEN3(4);
04658
goto NoMessages;
04659 }
04660
04661
04662
04663
04664
04665
if (fRemove && !
IsInsideMenuLoop(ptiCurrent)) {
04666
04667
04668
04669
if ((wParam == VK_APPS) && (message == WM_KEYUP)) {
04670
_PostMessage(pwnd, WM_CONTEXTMENU, (WPARAM)
PtoH(pwnd),
KEYBOARD_MENU);
04671 }
04672
04673
04674
04675
04676
04677
if ((wParam == VK_F1) && (message == WM_KEYDOWN)) {
04678
_PostMessage(pwnd, WM_KEYF1, 0, 0);
04679 }
04680 }
04681
04682
04683
04684
04685
04686
04687
04688
if (wParam == VK_SHIFT) {
04689
BYTE vkHanded, vkOtherHand;
04690
04691
if (qmsg.
msg.lParam & EXTENDED_BIT) {
04692 vkHanded = VK_RSHIFT;
04693 }
else {
04694 vkHanded = VK_LSHIFT;
04695 }
04696 vkOtherHand = vkHanded ^ 1;
04697
04698
if (!fDown &&
TestKeyStateDown(ptiCurrent->
pq, vkOtherHand)) {
04699
04700
04701
04702
04703
04704
04705
04706
04707
if ((ptiCurrent->
TIF_flags &
TIF_CSRSSTHREAD) == 0) {
04708
04709
04710
04711
04712
04713 qmsg.
msg.wParam = vkHanded;
04714
xxxSkipSysMsg(ptiCurrent, &qmsg);
04715
PATHTAKEN3(8);
04716
goto RestartScan;
04717 }
04718
PATHTAKEN3(0x10);
04719 }
04720 }
04721
04722
04723
04724
04725
04726
04727 fPrevDown =
FALSE;
04728
if (
TestKeyStateDown(ptiCurrent->
pq, wParam))
04729 fPrevDown =
TRUE;
04730
04731
04732
04733
04734
04735
PATHTAKEN3(0x20);
04736
if (fRemove) {
04737
xxxSkipSysMsg(ptiCurrent, &qmsg);
04738 }
04739
04740
04741
04742
04743
04744
04745
04746
04747 lParam = qmsg.
msg.lParam;
04748 wParam = qmsg.
msg.wParam;
04749
04750
04751
04752
04753
if (fPrevDown)
04754 lParam |= 0x40000000;
04755
04756
04757
04758
04759
switch (message) {
04760
case WM_KEYUP:
04761
case WM_SYSKEYUP:
04762 lParam |= 0x80000000;
04763
break;
04764 }
04765
04766
04767
04768
04769
if (
TestKeyStateDown(ptiCurrent->
pq, VK_MENU)) {
04770 lParam |= 0x20000000;
04771 }
04772
04773
04774
04775
04776
if (
IsMenuStarted(ptiCurrent)) {
04777 lParam |= 0x10000000;
04778 }
04779
04780
04781
04782
04783
if (ptiCurrent->
pq->
QF_flags &
QF_DIALOGACTIVE) {
04784 lParam |= 0x08000000;
04785 }
04786
04787
04788
04789
04790
04791
04792
04793
04794
04795
04796
04797
04798
04799
04800
04801
04802
04803
04804
04805
04806
04807
04808 UserAssert(ptiCurrent !=
NULL);
04809
if (
gpImeHotKeyListHeader !=
NULL &&
04810 fRemove &&
04811 !
IsMenuStarted(ptiCurrent) &&
04812 !(ptiCurrent->
TIF_flags &
TIF_DISABLEIME) &&
04813 pwnd !=
NULL) {
04814
04815 WPARAM wParamTemp = wParam;
04816
04817
if (wParam == VK_PACKET) {
04818 wParamTemp = MAKEWPARAM(wParam, ptiCurrent->
wchInjected);
04819 }
04820
04821
04822
04823
04824 dwImmRet =
xxxImmProcessKey( ptiCurrent->
pq,
04825 pwnd,
04826 message,
04827 wParamTemp,
04828 lParam);
04829
if ( dwImmRet & (
IPHK_HOTKEY | IPHK_SKIPTHISKEY) ) {
04830 dwImmRet = 0;
04831
goto SkipMessage;
04832 }
04833 }
04834
04835
04836
04837
04838
04839
04840
if (
IsHooked(ptiCurrent,
WHF_KEYBOARD)) {
04841 fKbdHookCalled =
TRUE;
04842
if (
xxxCallHook(fRemove ? HC_ACTION : HC_NOREMOVE,
04843 wParam, lParam, WH_KEYBOARD)) {
04844
PATHTAKEN3(0x40);
04845
goto SkipMessage;
04846 }
04847 }
04848
04849
if (fKbdHookCalled && fRemove &&
IsHooked(ptiCurrent,
WHF_CBT)) {
04850
xxxCallHook(HCBT_KEYSKIPPED, wParam, lParam, WH_CBT);
04851
PATHTAKEN3(0x80);
04852 }
04853
04854 fKbdHookCalled =
FALSE;
04855
PATHTAKEN3(0x100);
04856
goto ReturnMessage;
04857
04858
case WM_MOUSEWHEEL:
04859
04860
04861
04862
04863
04864
04865
04866
if (ptiCurrent->
TIF_flags &
TIF_SPINNING)
04867
CheckProcessForeground(ptiCurrent);
04868
04869
04870
04871
04872
04873 pwnd = ptiCurrent->
pq->
spwndFocus;
04874
if (pwnd ==
NULL ||
IsInsideMenuLoop(ptiCurrent)) {
04875
PATHTAKEN2(0x20000000);
04876
goto SkipMessage;
04877 }
04878
04879
ThreadUnlock(&tlpwnd);
04880
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd);
04881
04882
04883
04884
04885
if (fOtherApp = (
GETPTI(pwnd) != ptiCurrent)) {
04886
04887
04888
04889
04890
04891
04892
04893
04894
04895
04896
if (
GETPTI(pwnd)->pq != ptiCurrent->
pq) {
04897
PATHTAKEN2(0x40000000);
04898
goto SkipMessage;
04899 }
04900
04901
04902
04903
04904
if (ptiKeyWake ==
NULL) {
04905
PATHTAKEN3(1);
04906 ptiKeyWake =
GETPTI(pwnd);
04907 }
04908 }
04909
04910
04911
04912
04913
04914
04915
04916
if ( !
CheckMsgFilter(WM_MOUSEWHEEL, msgMinFilter, msgMaxFilter) ||
04917 !
CheckPwndFilter(pwnd, pwndFilter)) {
04918
PATHTAKEN3(2);
04919
continue;
04920 }
04921
04922
04923
04924
04925
04926
04927
if (fOtherApp) {
04928
PATHTAKEN3(4);
04929
goto NoMessages;
04930 }
04931
04932
04933
04934
04935
04936
PATHTAKEN3(0x20);
04937
if (fRemove) {
04938
xxxSkipSysMsg(ptiCurrent, &qmsg);
04939 }
04940
04941 wParam =
GetMouseKeyFlags(ptiCurrent->
pq);
04942 UserAssert(LOWORD(qmsg.
msg.wParam) == 0);
04943 UserAssert(HIWORD(wParam) == 0);
04944 wParam |= qmsg.
msg.wParam;
04945 lParam = qmsg.
msg.lParam;
04946
04947
04948
04949
04950
04951
04952
if (
IsHooked(ptiCurrent,
WHF_MOUSE)) {
04953 fMouseHookCalled =
TRUE;
04954 mhs.pt = qmsg.
msg.pt;
04955 mhs.hwnd =
HW(pwnd);
04956 mhs.wHitTestCode = HTNOWHERE;
04957 mhs.dwExtraInfo = qmsg.
ExtraInfo;
04958 mhs.mouseData = (
DWORD)qmsg.
msg.wParam;
04959
if (
xxxCallMouseHook(message, &mhs, fRemove)) {
04960
04961
04962
04963
PATHTAKEN3(0x40);
04964
goto SkipMessage;
04965 }
04966 }
04967
04968
if (fMouseHookCalled && fRemove &&
IsHooked(ptiCurrent,
WHF_CBT)) {
04969
04970
04971
04972
xxxCallHook(HCBT_CLICKSKIPPED, message, (LPARAM)&mhs, WH_CBT);
04973
PATHTAKEN3(0x80);
04974 }
04975
04976 fMouseHookCalled =
FALSE;
04977
PATHTAKEN3(0x100);
04978
goto ReturnMessage;
04979 }
04980 }
04981
04982 ReturnMessage:
04983
if (!RtlEqualMemory(&ptiCurrent->
ptLast, &qmsg.
msg.pt,
sizeof(POINT))) {
04984 ptiCurrent->
TIF_flags |=
TIF_MSGPOSCHANGED;
04985 }
04986 ptiCurrent->
ptLast = qmsg.
msg.pt;
04987 ptiCurrent->
timeLast = qmsg.
msg.time;
04988 ptiCurrent->
pq->
ExtraInfo = qmsg.
ExtraInfo;
04989
04990
04991
04992
04993
04994 ptiCurrent->
idLast = ptiCurrent->
pq->
idSysLock = 1;
04995
04996
04997
04998
04999
05000
TransferWakeBit(ptiCurrent, message);
05001
05002
05003
05004
05005
ClearWakeBit(ptiCurrent, QS_MOUSE | QS_KEY | QS_EVENT | QS_TRANSFER,
TRUE);
05006
05007
05008
05009
05010 lpMsg->hwnd =
HW(pwnd);
05011 lpMsg->message = message;
05012
05013
05014
05015
05016
05017
05018 lpMsg->wParam = (dwImmRet &
IPHK_PROCESSBYIME) ? VK_PROCESSKEY : wParam;
05019
05020 lpMsg->lParam = lParam;
05021 lpMsg->time = qmsg.
msg.time;
05022 lpMsg->pt = qmsg.
msg.pt;
05023
05024
#if DBG
05025
if (gfLogPlayback && ptiCurrent->
pq->
idSysPeek == (LONG_PTR)
PQMSG_PLAYBACK)
05026 LogPlayback(pwnd, lpMsg);
05027
#endif // DBG
05028
05029
ThreadUnlock(&tlpwnd);
05030
05031
PATHTAKEN3(0x200);
05032
DUMPPATHTAKEN();
05033
return TRUE;
05034
05035 NoMessages:
05036
05037
05038
05039
05040
05041
05042
05043
05044 ptiCurrent->
pq->
idSysLock = 0;
05045
CheckSysLock(4, ptiCurrent->
pq,
NULL);
05046 ptiCurrent->
pq->
ptiSysLock =
NULL;
05047 ptiCurrent->
pcti->
CTIF_flags &= ~
CTIF_SYSQUEUELOCKED;
05048
05049
05050
05051
05052
05053
05054
if (ptiKeyWake !=
NULL || ptiMouseWake !=
NULL || ptiEventWake !=
NULL) {
05055
PATHTAKEN3(0x400);
05056
if (ptiKeyWake !=
NULL) {
05057
SetWakeBit(ptiKeyWake, QS_KEY | QS_TRANSFER);
05058
ClearWakeBit(ptiCurrent, QS_KEY | QS_TRANSFER,
FALSE);
05059
PATHTAKEN3(0x800);
05060 }
05061
05062
if (ptiMouseWake !=
NULL) {
05063
SetWakeBit(ptiMouseWake, QS_MOUSE | QS_TRANSFER);
05064
ClearWakeBit(ptiCurrent, QS_MOUSE | QS_TRANSFER,
FALSE);
05065
PATHTAKEN3(0x1000);
05066 }
05067
05068
if (ptiEventWake !=
NULL) {
05069
SetWakeBit(ptiEventWake, QS_EVENTSET);
05070
ClearWakeBit(ptiCurrent, QS_EVENT,
FALSE);
05071
PATHTAKEN3(0x2000);
05072 }
else if (
FJOURNALPLAYBACK()) {
05073
05074
05075
05076
05077
05078
05079
05080
05081
05082 ptiCurrent->
pcti->
fsWakeBitsJournal |= (ptiCurrent->
pcti->
fsWakeBits &
05083 (QS_MOUSE | QS_KEY | QS_TRANSFER));
05084
ClearWakeBit(ptiCurrent, QS_MOUSE | QS_KEY | QS_TRANSFER,
FALSE);
05085 ptiCurrent->
pcti->
fsChangeBits &= ~(QS_MOUSE | QS_KEY | QS_TRANSFER);
05086 }
05087 }
else {
05088
05089
05090
05091 ptiCurrent->
pcti->
fsWakeBitsJournal = 0;
05092
ClearWakeBit(ptiCurrent, QS_MOUSE | QS_KEY | QS_EVENT |
05093 QS_TRANSFER,
TRUE);
05094
PATHTAKEN3(0x4000);
05095 }
05096
05097
ThreadUnlock(&tlpwnd);
05098
05099
PATHTAKEN3(0x8000);
05100
DUMPPATHTAKEN();
05101
return FALSE;
05102 }
05103
#undef PATHTAKEN
05104
#undef PATHTAKEN2
05105
#undef PATHTAKEN3
05106
#undef DUMPPATHTAKEN
05107
#undef DUMPSUBPATHTAKEN
05108
05109
05110
05111
05112
05113
05114
05115
05116
05117
05118
05119
05120 VOID IdleTimerProc(VOID)
05121 {
05122
05123
CheckCritIn();
05124
05125
if ( (
TestAsyncKeyStateDown(VK_LBUTTON)) ||
05126 (
TestAsyncKeyStateDown(VK_RBUTTON)) ||
05127 (
TestAsyncKeyStateDown(VK_MBUTTON)) ||
05128 (
TestAsyncKeyStateDown(VK_XBUTTON1)) ||
05129 (
TestAsyncKeyStateDown(VK_XBUTTON2))) {
05130
05131
return;
05132 }
05133
05134
05135
if (
giScreenSaveTimeOutMs > 0) {
05136
05137
if (
IsTimeFromLastInput((
DWORD)(
giScreenSaveTimeOutMs))) {
05138
05139
if (
gppiScreenSaver !=
NULL) {
05140
05141
if (!(
gppiScreenSaver->W32PF_Flags & W32PF_IDLESCREENSAVER)) {
05142
05143
05144
05145
gppiScreenSaver->W32PF_Flags |= W32PF_IDLESCREENSAVER;
05146
SetForegroundPriorityProcess(
gppiScreenSaver,
gppiScreenSaver->
ptiMainThread,
TRUE);
05147 }
05148 }
else {
05149
05150
05151
05152
05153
05154
05155
05156
if ((
gpqForeground !=
NULL) &&
05157 (
gpqForeground->
spwndActive !=
NULL) &&
05158 !
FHungApp(
GETPTI(
gpqForeground->
spwndActive),
CMSHUNGAPPTIMEOUT)) {
05159
05160
05161
05162
05163
05164
05165
StartScreenSaver(
TRUE);
05166
_PostMessage(
gpqForeground->
spwndActive, WM_SYSCOMMAND, SC_SCREENSAVE, 0
L);
05167 }
else {
05168
StartScreenSaver(
FALSE);
05169 }
05170 }
05171 }
05172 }
05173
05174
if ((
giLowPowerTimeOutMs > 0) && ((
glinp.
dwFlags &
LINP_LOWPOWER) == 0)) {
05175
if (
IsTimeFromLastInput((
DWORD)(
giLowPowerTimeOutMs))) {
05176
if ((
gpqForeground !=
NULL) && (
gpqForeground->
spwndActive !=
NULL)) {
05177
_PostMessage(
gpqForeground->
spwndActive, WM_SYSCOMMAND, SC_MONITORPOWER,
LOWPOWER_PHASE);
05178 }
05179 }
05180 }
05181
05182
if ((
giPowerOffTimeOutMs > 0) && ((
glinp.
dwFlags &
LINP_POWEROFF) == 0)) {
05183
if (
IsTimeFromLastInput((
DWORD)(
giPowerOffTimeOutMs))) {
05184
if ((
gpqForeground !=
NULL) && (
gpqForeground->
spwndActive !=
NULL)) {
05185
_PostMessage(
gpqForeground->
spwndActive, WM_SYSCOMMAND, SC_MONITORPOWER,
POWEROFF_PHASE);
05186 }
05187 }
05188 }
05189
05190 }
05191
05192
05193
05194
05195
05196
05197
05198
05199
05200 void zzzWakeInputIdle(
05201
PTHREADINFO pti)
05202 {
05203 PW32PROCESS W32Process = W32GetCurrentProcess();
05204
05205
05206
05207
05208 pti->
TIF_flags &= ~
TIF_FIRSTIDLE;
05209
05210
05211
05212
05213
05214
05215
if (pti->
TIF_flags &
TIF_SHAREDWOW) {
05216 UserAssert(pti->
TIF_flags &
TIF_16BIT);
05217
if (pti->
ptdb->
pwti) {
05218
SET_PSEUDO_EVENT(&pti->
ptdb->
pwti->
pIdleEvent);
05219 }
05220 }
else {
05221
05222
05223
05224
05225
if (pti->
ppi->
ptiMainThread ==
NULL)
05226 pti->
ppi->
ptiMainThread = pti;
05227
05228
05229
05230
05231
if (pti->
ppi->
ptiMainThread == pti) {
05232
SET_PSEUDO_EVENT(&W32Process->InputIdleEvent);
05233 }
05234 }
05235
05236
05237
05238
05239
if (W32Process->W32PF_Flags & W32PF_STARTGLASS) {
05240
05241
05242
05243
05244 W32Process->W32PF_Flags &= ~W32PF_STARTGLASS;
05245
zzzCalcStartCursorHide(
NULL, 0);
05246 }
05247 }
05248
05249 void SleepInputIdle(
05250
PTHREADINFO pti)
05251 {
05252 PW32PROCESS W32Process;
05253
05254
05255
05256
05257
05258
if (pti->
TIF_flags &
TIF_SHAREDWOW) {
05259 UserAssert(pti->
TIF_flags &
TIF_16BIT);
05260
if (pti->
ptdb->
pwti) {
05261
RESET_PSEUDO_EVENT(&pti->
ptdb->
pwti->
pIdleEvent);
05262 }
05263 }
else {
05264
05265
05266
05267
05268
if (pti->
ppi->
ptiMainThread ==
NULL)
05269 pti->
ppi->
ptiMainThread = pti;
05270
05271
05272
05273
05274
if (pti->
ppi->
ptiMainThread == pti) {
05275 W32Process = W32GetCurrentProcess();
05276
RESET_PSEUDO_EVENT(&W32Process->InputIdleEvent);
05277 }
05278 }
05279 }
05280
05281
05282
05283
05284
05285
05286
05287
05288
05289
05290
05291
05292
05293
05294
05295
05296
05297
05298
05299
05300
05301
05302
05303
05304
05305 void zzzAddAttachment(
05306
PTHREADINFO pti,
05307
PQ pqAttach,
05308 LPBOOL pfChanged)
05309 {
05310
if (pti->
pqAttach != pqAttach) {
05311
05312
05313
05314
05315
05316
05317
05318
05319
05320
05321
05322
05323
05324
05325
PQ pqDestroy = pti->
pqAttach;
05326 pti->
pqAttach = pqAttach;
05327
if (pqDestroy !=
NULL)
05328
zzzDestroyQueue(pqDestroy, pti);
05329 pqAttach->
cThreads++;
05330 *pfChanged =
TRUE;
05331 }
05332 }
05333
05334 void zzzRecalc2(
05335
PQ pqAttach)
05336 {
05337
PATTACHINFO pai;
05338
PTHREADINFO pti;
05339
BOOL fChanged;
05340 PLIST_ENTRY pHead, pEntry;
05341
05342
05343
05344
05345
05346
DeferWinEventNotify();
05347
BEGINATOMICCHECK();
05348
05349
05350
05351
05352
05353
do {
05354 fChanged =
FALSE;
05355
05356
05357
05358
05359
05360 pHead = &
PtiCurrent()->rpdesk->PtiList;
05361
for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink) {
05362 pti = CONTAINING_RECORD(pEntry,
THREADINFO, PtiLink);
05363
05364
if (pti->
pqAttach == pqAttach) {
05365
05366
05367
05368
05369
for (pai =
gpai; pai !=
NULL; pai = pai->
paiNext) {
05370
05371
05372
05373
if (pai->
pti1 == pti || pai->
pti2 == pti) {
05374
zzzAddAttachment((pai->
pti1 == pti) ? pai->
pti2 : pai->
pti1,
05375 pqAttach, &fChanged);
05376 }
05377 }
05378
05379
05380
05381
05382
05383
if (pti->
TIF_flags &
TIF_16BIT) {
05384
PTHREADINFO ptiAttach;
05385 PLIST_ENTRY pHeadAttach, pEntryAttach;
05386
05387 pHeadAttach = &pti->
rpdesk->
PtiList;
05388
for (pEntryAttach = pHeadAttach->Flink;
05389 pEntryAttach != pHeadAttach;
05390 pEntryAttach = pEntryAttach->Flink) {
05391 ptiAttach = CONTAINING_RECORD(pEntryAttach,
THREADINFO, PtiLink);
05392
05393
if (ptiAttach->
TIF_flags &
TIF_16BIT &&
05394 ptiAttach->
ppi == pti->
ppi) {
05395
zzzAddAttachment(ptiAttach, pqAttach, &fChanged);
05396 }
05397 }
05398 }
05399 }
05400 }
05401 }
while (fChanged);
05402
ENDATOMICCHECK();
05403
zzzEndDeferWinEventNotify();
05404 }
05405
05406
05407 void zzzRecalcThreadAttachment()
05408 {
05409
PTHREADINFO pti;
05410 PLIST_ENTRY pHead, pEntry;
05411
05412
05413
05414
05415 UserAssert(
IsWinEventNotifyDeferred());
05416
05417
05418
05419
05420
05421 pHead = &
PtiCurrent()->rpdesk->PtiList;
05422
for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink) {
05423 pti = CONTAINING_RECORD(pEntry,
THREADINFO, PtiLink);
05424
05425
05426
05427
05428
05429 UserAssert(pti->
pq !=
NULL);
05430
05431
if (pti->
pqAttach ==
NULL) {
05432
05433
05434
05435
05436
05437
if (pti->
pq->
cThreads > 1) {
05438 pti->
pqAttach =
AllocQueue(
NULL,
NULL);
05439
05440
if (pti->
pqAttach ==
NULL) {
05441 RIPMSG0(RIP_WARNING,
"zzzRecalcThreadAttachment: AllocQueue failed");
05442
break;
05443 }
05444
05445 pti->
pqAttach->
cThreads++;
05446 }
else {
05447 pti->
pqAttach = pti->
pq;
05448 }
05449
05450
05451
05452
05453
05454
zzzRecalc2(pti->
pqAttach);
05455 }
05456 }
05457 }
05458
05459
05460
05461
05462
05463
05464
05465
05466
05467
05468
05469
05470 void RedistributeInput(
05471
PQMSG pqmsgS,
05472
PQ pqRedist)
05473 {
05474
PTHREADINFO ptiSave;
05475
PTHREADINFO ptiT;
05476
PQMSG *ppqmsgD;
05477
PQMSG pqmsgT;
05478
PMLIST pmlInput;
05479
05480
05481
05482
05483
05484
05485
05486
05487
05488
05489
05490
05491
05492
05493
05494 ptiT =
NULL;
05495 ppqmsgD =
NULL;
05496 pmlInput =
NULL;
05497
05498
while (pqmsgS !=
NULL) {
05499
05500
05501
05502
05503 ptiSave = ptiT;
05504 ptiT = pqmsgS->
pti;
05505
05506
05507
05508
05509
05510
05511
if (pqmsgS->
dwQEvent ==
QEVENT_UPDATEKEYSTATE) {
05512 ptiT =
NULL;
05513 }
05514
05515
if (ptiT ==
NULL) {
05516
05517
05518
05519
05520 UserAssert(!pqmsgS->
pqmsgPrev);
05521
if (pqmsgS->
pqmsgNext !=
NULL) {
05522 pqmsgS->
pqmsgNext->
pqmsgPrev =
NULL;
05523 }
05524
05525 pqmsgT = pqmsgS;
05526 pqmsgS = pqmsgS->
pqmsgNext;
05527
05528
05529
05530
05531
CleanEventMessage(pqmsgT);
05532
FreeQEntry(pqmsgT);
05533
05534 ptiT = ptiSave;
05535
continue;
05536 }
05537
05538
05539
05540
05541
05542
05543
if (ppqmsgD ==
NULL || ptiSave != ptiT) {
05544
05545
05546
05547
05548
05549
05550
05551
if (ptiT->pq->mlInput.pqmsgWriteLast !=
NULL &&
05552 pqmsgS->
msg.time >= ptiT->pq->mlInput.pqmsgWriteLast->msg.time) {
05553 ppqmsgD = &ptiT->pq->mlInput.pqmsgWriteLast->
pqmsgNext;
05554 }
else {
05555 ppqmsgD = &ptiT->pq->mlInput.pqmsgRead;
05556 }
05557
05558 pmlInput = &ptiT->pq->mlInput;
05559 }
05560
05561
05562
05563
05564
05565
05566
while (*ppqmsgD !=
NULL && ((*ppqmsgD)->msg.time <= pqmsgS->
msg.time)) {
05567 ppqmsgD = &((*ppqmsgD)->pqmsgNext);
05568 }
05569
05570
05571
05572
05573
05574
05575 pqmsgT = pqmsgS;
05576 pqmsgS = pqmsgS->
pqmsgNext;
05577 pqmsgT->
pqmsgNext = *ppqmsgD;
05578
05579
if (*ppqmsgD !=
NULL) {
05580 pqmsgT->
pqmsgPrev = (*ppqmsgD)->
pqmsgPrev;
05581 (*ppqmsgD)->
pqmsgPrev = pqmsgT;
05582 }
else {
05583 pqmsgT->
pqmsgPrev = pmlInput->
pqmsgWriteLast;
05584 pmlInput->
pqmsgWriteLast = pqmsgT;
05585 }
05586 *ppqmsgD = pqmsgT;
05587 ppqmsgD = &pqmsgT->
pqmsgNext;
05588 pmlInput->
cMsgs++;
05589
05590
05591
05592
05593
05594
05595
05596
if (pqmsgT->dwQEvent != 0 && !(ptiT->pcti->fsWakeBits & QS_EVENT)) {
05597
SetWakeBit(ptiT, QS_EVENTSET);
05598 }
05599
05600
05601
05602
05603
05604
if (pqmsgT == (
PQMSG)(pqRedist->
idSysPeek) && (pqRedist != ptiT->pq)) {
05605
05606
if (ptiT->pq->idSysPeek == 0) {
05607
CheckPtiSysPeek(6, ptiT->pq, pqRedist->
idSysPeek);
05608 ptiT->pq->idSysPeek = pqRedist->
idSysPeek;
05609 }
05610
05611
#if DEBUGTAGS
05612
else {
05613 TAGMSG2(DBGTAG_SysPeek,
05614
"idSysPeek %#p already set in pq %#p",
05615 ptiT->pq->idSysPeek, ptiT->pq);
05616
05617 }
05618
#endif
05619
05620
05621
05622
05623
CheckPtiSysPeek(7, pqRedist, 0);
05624 pqRedist->
idSysPeek = 0;
05625
05626
05627
05628
05629
05630
05631
if (ptiT->pq->ptiSysLock ==
NULL &&
05632 pqRedist->
ptiSysLock !=
NULL &&
05633 pqRedist->
ptiSysLock->
pq == ptiT->pq) {
05634
05635
CheckSysLock(4, ptiT->pq, pqRedist->
ptiSysLock);
05636 ptiT->pq->ptiSysLock = pqRedist->
ptiSysLock;
05637
05638
CheckSysLock(5, pqRedist,
NULL);
05639 pqRedist->
ptiSysLock =
NULL;
05640 }
05641
#if DEBUGTAGS
05642
else {
05643 TAGMSG2(DBGTAG_SysPeek,
05644
"ptiSysLock %#p already set in pq %#p\n",
05645 ptiT->pq->ptiSysLock, ptiT->pq);
05646 }
05647
#endif
05648
}
05649
05650
05651
05652
05653
05654
05655
05656
if (pqmsgS !=
NULL) {
05657 pqmsgS->pqmsgPrev =
NULL;
05658 }
05659 }
05660 }
05661
05662
05663
05664
05665
05666
05667
05668
05669
05670
05671 VOID CancelInputState(
05672
PTHREADINFO pti,
05673 DWORD cmd)
05674 {
05675
PTHREADINFO ptiCurrent =
PtiCurrent();
05676
PWND pwndT;
05677
TL tlpwndT;
05678
TL tlpwndChild;
05679
AAS aas;
05680
05681
05682
05683
05684
05685
05686
05687
05688
05689
switch (cmd) {
05690
case CANCEL_ACTIVESTATE:
05691
05692
05693
05694 pwndT = pti->
pq->
spwndActive;
05695
ThreadLockWithPti(ptiCurrent, pwndT, &tlpwndT);
05696
05697
QueueNotifyMessage(pwndT, WM_NCACTIVATE,
FALSE, 0);
05698
QueueNotifyMessage(pwndT, WM_ACTIVATE,
05699 MAKELONG(WA_INACTIVE,
TestWF(pwndT,
WFMINIMIZED)),
05700 0);
05701
05702
if (pwndT == pti->
pq->
spwndActive)
05703
Unlock(&pti->
pq->
spwndActive);
05704
05705 aas.
ptiNotify =
GETPTI(pwndT);
05706 aas.
tidActDeact =
TIDq(
GETPTI(pwndT));
05707 aas.
fActivating =
FALSE;
05708 aas.
fQueueNotify =
TRUE;
05709
05710
05711
05712
05713
05714
ThreadLockWithPti(ptiCurrent,
GETPTI(pwndT)->rpdesk->pDeskInfo->spwnd->spwndChild, &tlpwndChild);
05715
xxxInternalEnumWindow(
GETPTI(pwndT)->rpdesk->pDeskInfo->spwnd->spwndChild,
05716 (
WNDENUMPROC_PWND)
xxxActivateApp, (LPARAM)&aas,
BWL_ENUMLIST);
05717
ThreadUnlock(&tlpwndChild);
05718
05719
ThreadUnlock(&tlpwndT);
05720
break;
05721
05722
case CANCEL_FOCUSSTATE:
05723
05724
05725
05726 pwndT = pti->
pq->
spwndFocus;
05727
ThreadLockWithPti(ptiCurrent, pwndT, &tlpwndT);
05728
05729
QueueNotifyMessage(pwndT, WM_KILLFOCUS, 0, 0);
05730
#ifdef FE_IME
05731
if (
IS_IME_ENABLED()) {
05732
05733
05734
05735
05736
xxxFocusSetInputContext(pwndT,
FALSE,
TRUE);
05737 }
05738
#endif
05739
if (pwndT == pti->
pq->
spwndFocus)
05740
Unlock(&pti->
pq->
spwndFocus);
05741
05742
ThreadUnlock(&tlpwndT);
05743
break;
05744
05745
case CANCEL_CAPTURESTATE:
05746
05747
05748
05749
05750
05751
05752
05753 UserAssert((pti->
pMenuState ==
NULL)
05754 || pti->
pMenuState->
fModelessMenu
05755 || pti->
pMenuState->
fInDoDragDrop);
05756
05757 pti->
pq->
QF_flags &= ~
QF_CAPTURELOCKED;
05758 pwndT = pti->
pq->
spwndCapture;
05759
ThreadLockWithPti(ptiCurrent, pwndT, &tlpwndT);
05760
05761
QueueNotifyMessage(pwndT, WM_CANCELMODE, 0, 0);
05762
if (pwndT == pti->
pq->
spwndCapture)
05763
UnlockCaptureWindow(pti->
pq);
05764
05765
ThreadUnlock(&tlpwndT);
05766
break;
05767 }
05768
05769
return;
05770 }
05771
05772
05773
05774
05775
05776
05777
05778
05779
05780
#if DBG
05781
#define VALIDATEQSPWND(spwnd) \
05782
if (pq-> ## spwnd != NULL) { \
05783
ptiwnd = GETPTI(pq-> ## spwnd); \
05784
fDestroyedOK = (TestWF(pq-> ## spwnd, WFDESTROYED) && (ptiwnd == gptiRit)); \
05785
UserAssert((pti->rpdesk == ptiwnd->rpdesk) || fDestroyedOK); \
05786
UserAssert((pti == ptiwnd) \
05787
|| (fAttached && (pq == ptiwnd->pq)) \
05788
|| fDestroyedOK); \
05789
}
05790
05791
05792
void DBGValidateQueueStates (
PDESKTOP pdesk)
05793 {
05794
BOOL fAttached, fDestroyedOK;
05795
PQ pq;
05796 PLIST_ENTRY pHead, pEntry;
05797
PTHREADINFO pti, ptiwnd;
05798
DWORD dwInForeground = 0;
05799
05800 UserAssert((gpqForeground == NULL)
05801 || ((
gpqForeground->
ptiMouse->
rpdesk == grpdeskRitInput)
05802 && (
gpqForeground->
cThreads != 0)));
05803
05804
if (pdesk ==
NULL) {
05805 RIPMSG0(RIP_WARNING,
"DBGValidateQueueStates: Null pdesk parameter");
05806
return;
05807 }
05808 pHead = &pdesk->
PtiList;
05809
for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink) {
05810
05811 pti = CONTAINING_RECORD(pEntry,
THREADINFO, PtiLink);
05812 pq = pti->
pq;
05813
if (pq ==
NULL) {
05814 RIPMSG2(RIP_WARNING,
"DBGValidateQueueStates: Null pq. pti:%#p. pdesk:%#p", pti, pdesk);
05815
continue;
05816 }
05817
05818
05819
05820
05821
if (!(pq->
QF_flags &
QF_INDESTROY)) {
05822 UserAssert(pq->
cThreads != 0);
05823 }
05824 fAttached = (pq->
cThreads > 1);
05825
if (pti->
pq ==
gpqForeground) {
05826 dwInForeground++;
05827 }
05828
05829
05830
05831 UserAssert((pti == pq->
ptiMouse)
05832 || (fAttached && (pq == pq->
ptiMouse->
pq)));
05833 UserAssert(pti->
rpdesk == pq->
ptiMouse->
rpdesk);
05834 UserAssert((pti == pq->
ptiKeyboard)
05835 || (fAttached && (pq == pq->
ptiKeyboard->
pq)));
05836 UserAssert(pti->
rpdesk == pq->
ptiKeyboard->
rpdesk);
05837
if (pq->
ptiSysLock !=
NULL) {
05838 UserAssert((pti == pq->
ptiSysLock)
05839 || (fAttached && (pq == pq->
ptiSysLock->
pq)));
05840 }
05841
05842
05843
05844 VALIDATEQSPWND(spwndActive);
05845 VALIDATEQSPWND(spwndFocus);
05846 VALIDATEQSPWND(spwndCapture);
05847 VALIDATEQSPWND(spwndActivePrev);
05848 }
05849
05850 UserAssert((gpqForeground == NULL)
05851 || (dwInForeground == 0)
05852 || (
gpqForeground->
cThreads == dwInForeground));
05853 }
05854
05855
05856
05857
05858
05859
05860
05861
05862
void DBGValidateQueue(
PQ pq)
05863 {
05864
if (pq !=
NULL) {
05865
Q q = *pq;
05866 UserAssert(q.
spwndActive ==
HtoP(
PtoH(q.
spwndActive)));
05867 UserAssert(q.
spwndFocus ==
HtoP(
PtoH(q.
spwndFocus)));
05868 UserAssert(q.
spwndCapture ==
HtoP(
PtoH(q.
spwndCapture)));
05869 UserAssert(q.
spwndActivePrev ==
HtoP(
PtoH(q.
spwndActivePrev)));
05870 UserAssert(q.
spcurCurrent ==
HtoP(
PtoH(q.
spcurCurrent)));
05871 }
05872 }
05873
#endif
05874
05875
05876
05877
05878
05879
05880
05881
05882
05883
05884
05885
05886 #define CTS_DONOTHING 0
05887 #define CTS_CANCELOLD 1
05888 #define CTS_TRANSFER 2
05889
05890 DWORD CheckTransferState(
05891
PTHREADINFO pti,
05892
PQ pqAttach,
05893 LONG offset,
05894 BOOL fJoiningForeground)
05895 {
05896
PWND pwndOld, pwndNew, pwndForegroundState;
05897
05898
05899
05900
05901
05902
05903 pwndOld = *(
PWND *)(((
BYTE *)pti->
pq) + offset);
05904 pwndNew = *(
PWND *)(((
BYTE *)pqAttach) + offset);
05905
05906
05907
05908
05909
05910
if (pwndOld ==
NULL ||
GETPTI(pwndOld) != pti)
05911
return CTS_DONOTHING;
05912
05913
05914
05915
05916
if (pwndNew !=
NULL)
05917
return CTS_CANCELOLD;
05918
05919
05920
05921
05922
if (
gpqForeground ==
NULL || !fJoiningForeground)
05923
return CTS_TRANSFER;
05924
05925
05926
05927
05928
05929 pwndForegroundState = *(
PWND *)(((
BYTE *)
gpqForeground) + offset);
05930
if (pwndForegroundState ==
NULL || pwndOld == pwndForegroundState)
05931
return CTS_TRANSFER;
05932
05933
05934
05935
05936
05937
return CTS_CANCELOLD;
05938 }
05939
05940 void zzzAttachToQueue(
05941
PTHREADINFO pti,
05942
PQ pqAttach,
05943
PQ pqJournal,
05944 BOOL fJoiningForeground)
05945 {
05946
PQMSG pqmsgT;
05947
PQ pqDestroy;
05948
05949
05950
05951
05952
switch (
CheckTransferState(pti, pqAttach,
05953 FIELD_OFFSET(
Q, spwndActive), fJoiningForeground)) {
05954
case CTS_CANCELOLD:
05955
CancelInputState(pti,
CANCEL_ACTIVESTATE);
05956
break;
05957
05958
case CTS_TRANSFER:
05959
Lock(&pqAttach->
spwndActive, pti->
pq->
spwndActive);
05960
Unlock(&pti->
pq->
spwndActive);
05961
05962
05963
05964
05965
05966
if (pti->
pq->
caret.
spwnd !=
NULL) {
05967
05968
if (
GETPTI(pti->
pq->
caret.
spwnd) == pti) {
05969
05970
05971
05972
05973
if (pqAttach->
caret.
spwnd ==
NULL) {
05974 pqAttach->
caret = pti->
pq->
caret;
05975 pti->
pq->
caret.
spwnd =
NULL;
05976 }
05977 }
05978 }
05979
break;
05980 }
05981
05982
05983
05984
05985
switch (
CheckTransferState(pti, pqAttach,
05986 FIELD_OFFSET(
Q, spwndFocus), fJoiningForeground)) {
05987
case CTS_CANCELOLD:
05988
CancelInputState(pti,
CANCEL_FOCUSSTATE);
05989
break;
05990
05991
case CTS_TRANSFER:
05992
Lock(&pqAttach->
spwndFocus, pti->
pq->
spwndFocus);
05993
Unlock(&pti->
pq->
spwndFocus);
05994
break;
05995 }
05996
05997
05998
05999
06000
switch (
CheckTransferState(pti, pqAttach,
06001 FIELD_OFFSET(
Q, spwndCapture), fJoiningForeground)) {
06002
case CTS_CANCELOLD:
06003
CancelInputState(pti,
CANCEL_CAPTURESTATE);
06004
break;
06005
06006
case CTS_TRANSFER:
06007
LockCaptureWindow(pqAttach, pti->
pq->
spwndCapture);
06008
UnlockCaptureWindow(pti->
pq);
06009 pqAttach->
codeCapture = pti->
pq->
codeCapture;
06010 pqAttach->
QF_flags ^= ((pqAttach->
QF_flags ^ pti->
pq->
QF_flags) &
QF_CAPTURELOCKED);
06011
break;
06012
06013
#if DBG
06014
case CTS_DONOTHING:
06015
06016
06017
06018
06019 UserAssert((pti->
pMenuState ==
NULL)
06020 ||
ExitMenuLoop(pti->
pMenuState, pti->
pMenuState->
pGlobalPopupMenu)
06021 || pti->
pMenuState->
fModelessMenu
06022 || pti->
pMenuState->
fInDoDragDrop);
06023
06024
break;
06025
#endif
06026
}
06027
06028
06029
06030
06031
06032
06033
06034
06035
06036
06037
switch (
CheckTransferState(pti, pqAttach,
06038 FIELD_OFFSET(
Q, spwndActivePrev), fJoiningForeground)) {
06039
case CTS_TRANSFER:
06040
Lock(&pqAttach->
spwndActivePrev, pti->
pq->
spwndActivePrev);
06041
Unlock(&pti->
pq->
spwndActivePrev);
06042
break;
06043
06044
case CTS_CANCELOLD:
06045
06046
06047
06048
06049
06050
if (pqAttach->
spwndActive &&
06051 (pqAttach->
spwndActivePrev && pti->
pq->
spwndActivePrev) &&
06052 (pqAttach->
spwndActive->
spwndNext == pti->
pq->
spwndActivePrev)) {
06053
06054
Lock(&pqAttach->
spwndActivePrev, pti->
pq->
spwndActivePrev);
06055
Unlock(&pti->
pq->
spwndActivePrev);
06056 }
06057
break;
06058 }
06059
06060
if (pti == pti->
pq->
ptiSysLock) {
06061
06062
06063
06064
06065
06066 pqAttach->
QF_flags ^= ((pqAttach->
QF_flags ^ pti->
pq->
QF_flags)
06067 & ~(
QF_CAPTURELOCKED));
06068
06069
06070
06071
06072
06073
06074
06075
06076
06077
06078
if (!
IsInsideMenuLoop(pti)) {
06079 pqAttach->
QF_flags &= ~
QF_ACTIVATIONCHANGE;
06080 }
06081
06082
06083
06084
06085
06086 pti->
pq->
ptiSysLock =
NULL;
06087 }
06088
06089
if (
gspwndCursor !=
NULL && pti ==
GETPTI(
gspwndCursor)) {
06090
LockQCursor(pqAttach, pti->pq->
spcurCurrent);
06091 }
06092
06093
06094
06095
06096
06097
06098
06099
06100
06101
06102
06103
06104
06105 pqAttach->
iCursorLevel += pti->iCursorLevel;
06106
06107
06108
06109
06110 pqAttach->
ptiMouse = pti;
06111 pqAttach->
ptiKeyboard = pti;
06112
06113 pqDestroy = pti->pq;
06114
06115
06116
06117
06118
06119
06120 pti->pq = pqAttach;
06121
06122
06123
06124
06125
06126
if (pqDestroy != pqJournal) {
06127
06128
06129
06130
06131
06132 pqmsgT = pqDestroy->
mlInput.
pqmsgRead;
06133 pqDestroy->
mlInput.
pqmsgRead =
NULL;
06134 pqDestroy->
mlInput.
pqmsgWriteLast =
NULL;
06135 pqDestroy->
mlInput.
cMsgs = 0;
06136
06137
06138
06139
06140
06141
06142
06143
RedistributeInput(pqmsgT, pqDestroy);
06144
06145
06146
06147
06148
06149
06150
zzzDestroyQueue(pqDestroy, pti);
06151
06152 }
else {
06153 UserAssert(pqDestroy->
cThreads);
06154 pqDestroy->
cThreads--;
06155 }
06156 }
06157
06158 BOOL zzzReattachThreads(
06159 BOOL fJournalAttach)
06160 {
06161
PTHREADINFO ptiCurrent =
PtiCurrent();
06162
PTHREADINFO pti;
06163
PQ pqForegroundPrevNew;
06164
PQ pqForegroundNew;
06165
PQ pqAttach;
06166
PQ pqJournal;
06167 PLIST_ENTRY pHead, pEntry;
06168
BOOL bHadAnActiveForegroundWindow;
06169
06170
06171
06172
06173
06174
06175
06176
06177
06178
06179
#if DBG
06180
DBGValidateQueueStates(ptiCurrent->
rpdesk);
06181
#endif
06182
06183
06184
06185
06186
06187
DeferWinEventNotify();
06188
BEGINATOMICCHECK();
06189
06190
06191
06192
06193
06194
if (!fJournalAttach) {
06195
06196
06197
06198
06199
06200
06201
06202
zzzRecalcThreadAttachment();
06203
06204
06205
06206
06207 pqJournal =
gpqForeground;
06208
if (pqJournal ==
NULL)
06209 pqJournal = ptiCurrent->
pq;
06210
06211
06212
06213
06214
if (pqJournal->
cThreads == 1) {
06215 pqJournal =
NULL;
06216 }
else {
06217
06218
06219
06220
06221
06222 (pqJournal->
cLockCount)++;
06223 }
06224 }
else {
06225 pqJournal =
NULL;
06226 }
06227
06228
06229
06230
06231 pqForegroundNew =
NULL;
06232
06233
06234
06235
06236
06237
if (
gpqForeground !=
NULL &&
gpqForeground->
spwndActive !=
NULL) {
06238 bHadAnActiveForegroundWindow =
TRUE;
06239 pqForegroundNew =
GETPTI(
gpqForeground->
spwndActive)->pqAttach;
06240 }
else {
06241 bHadAnActiveForegroundWindow =
FALSE;
06242 }
06243
06244 pqForegroundPrevNew =
NULL;
06245
if (
gpqForegroundPrev !=
NULL &&
gpqForegroundPrev->
spwndActivePrev !=
NULL) {
06246 pqForegroundPrevNew =
GETPTI(
gpqForegroundPrev->
spwndActivePrev)->pqAttach;
06247 }
06248
06249
06250 pHead = &ptiCurrent->
rpdesk->
PtiList;
06251
for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink) {
06252 pti = CONTAINING_RECORD(pEntry,
THREADINFO, PtiLink);
06253
06254
if (pti->
pqAttach == pti->
pq) {
06255 pti->
pqAttach =
NULL;
06256 }
else if(pti->
pqAttach !=
NULL) {
06257
06258
06259
06260
06261
06262 pqAttach = pti->
pqAttach;
06263 pti->
pqAttach =
NULL;
06264
06265
zzzAttachToQueue(pti, pqAttach, pqJournal, pqForegroundNew == pqAttach);
06266 }
06267
06268 }
06269
06270
06271
06272
06273
06274
if (pqJournal !=
NULL) {
06275
PQMSG pqmsgRedist;
06276
06277 UserAssert(pqJournal->
cLockCount);
06278 (pqJournal->
cLockCount)--;
06279 pqmsgRedist = pqJournal->
mlInput.
pqmsgRead;
06280
06281 pqJournal->
mlInput.
pqmsgRead =
NULL;
06282 pqJournal->
mlInput.
pqmsgWriteLast =
NULL;
06283 pqJournal->
mlInput.
cMsgs = 0;
06284
RedistributeInput(pqmsgRedist, pqJournal);
06285
06286
06287
06288
06289
if (pqJournal->
cThreads == 0) {
06290 pqJournal->
cThreads = 1;
06291
zzzDestroyQueue(pqJournal, pti);
06292 }
else {
06293
06294
06295
06296
06297
06298
06299
06300
if ((pqJournal->
ptiMouse !=
NULL)
06301 && (pqJournal != pqJournal->
ptiMouse->
pq)) {
06302 pqJournal->
cThreads++;
06303
zzzDestroyQueue(pqJournal, pqJournal->
ptiMouse);
06304 }
06305
if ((pqJournal->
ptiKeyboard !=
NULL)
06306 && (pqJournal != pqJournal->
ptiKeyboard->
pq)) {
06307 pqJournal->
cThreads++;
06308
zzzDestroyQueue(pqJournal, pqJournal->
ptiKeyboard);
06309 }
06310 }
06311 }
06312
06313
#if DBG
06314
DBGValidateQueueStates(ptiCurrent->
rpdesk);
06315
#endif
06316
06317
06318
06319
06320
06321
if (
PtiCurrent()->rpdesk !=
grpdeskRitInput) {
06322
EXITATOMICCHECK();
06323
zzzEndDeferWinEventNotify();
06324
return TRUE;
06325 }
06326
06327
06328
06329
06330
06331
#if DBG
06332
DBGValidateQueue(pqForegroundNew);
06333
#endif
06334
gpqForeground = pqForegroundNew;
06335
06336
06337 UserAssert(!
gpqForeground || (
gpqForeground->
ptiKeyboard &&
gpqForeground->
ptiKeyboard->
rpdesk));
06338
gpqForegroundPrev = pqForegroundPrevNew;
06339
06340
ENDATOMICCHECK();
06341
zzzEndDeferWinEventNotify();
06342
06343
if ((
gpqForeground ==
NULL) && (bHadAnActiveForegroundWindow)) {
06344
PWND pwndNewForeground;
06345
PTHREADINFO pti =
PtiCurrent();
06346
06347 pwndNewForeground =
_GetNextQueueWindow(pti->
rpdesk->
pDeskInfo->
spwnd->
spwndChild, 0,
FALSE);
06348
06349
06350
06351
06352
06353
06354
06355
if (pwndNewForeground !=
NULL) {
06356
PostEventMessage(
GETPTI(pwndNewForeground),
06357
GETPTI(pwndNewForeground)->pq,
QEVENT_ACTIVATE,
NULL, 0,
06358 0, (LPARAM)
HWq(pwndNewForeground));
06359 }
06360 }
06361
zzzSetFMouseMoved();
06362 UserAssert((
gpqForeground ==
NULL) || (
gpqForeground->
ptiMouse->
rpdesk ==
grpdeskRitInput));
06363
06364
return TRUE;
06365 }
06366
06367 BOOL zzzAttachThreadInput(
06368
PTHREADINFO ptiAttach,
06369
PTHREADINFO ptiAttachTo,
06370 BOOL fAttach)
06371 {
06372
CheckCritIn();
06373
06374
06375
06376
06377
if (ptiAttach == ptiAttachTo)
06378
return FALSE;
06379
06380
#if defined(FE_IME)
06381
06382
06383
06384
06385
06386
06387
if (
IS_IME_ENABLED()) {
06388
PTHREADINFO ptiConsoleIME;
06389
PTHREADINFO ptiConsoleInput;
06390
06391
if ( ((ptiConsoleIME =
PtiFromThreadId(ptiAttach->
rpdesk->
dwConsoleIMEThreadId)) !=
NULL) &&
06392 ((ptiConsoleInput =
PtiFromThreadId(ptiAttach->
rpdesk->
dwConsoleThreadId)) !=
NULL) &&
06393 (ptiAttach == ptiConsoleIME) &&
06394 (ptiAttachTo == ptiConsoleInput) &&
06395 (ptiConsoleIME->
TIF_flags &
TIF_DONTATTACHQUEUE)
06396 )
06397 {
06398
goto SkipCheck;
06399 }
06400 }
06401
#endif
06402
06403
06404
06405
06406
if (ptiAttachTo->
TIF_flags &
TIF_DONTATTACHQUEUE)
06407
return FALSE;
06408
if (ptiAttach->
TIF_flags &
TIF_DONTATTACHQUEUE)
06409
return FALSE;
06410
06411
#if defined(FE_IME)
06412
SkipCheck:
06413
#endif
06414
06415
06416
06417
if (ptiAttachTo->
rpdesk != ptiAttach->
rpdesk)
06418
return FALSE;
06419
06420
06421
06422
06423
06424
if (fAttach) {
06425
PATTACHINFO pai;
06426
06427
06428
06429
06430
if ((pai = (
PATTACHINFO)UserAllocPool(
sizeof(
ATTACHINFO), TAG_ATTACHINFO)) ==
NULL)
06431
return FALSE;
06432
06433 pai->
pti1 = ptiAttach;
06434 pai->
pti2 = ptiAttachTo;;
06435 pai->
paiNext =
gpai;
06436
gpai = pai;
06437 }
else {
06438
PATTACHINFO *ppai;
06439
BOOL fFound =
FALSE;
06440
06441
06442
06443
06444
06445
for (ppai = &
gpai; (*ppai) !=
NULL; ppai = &(*ppai)->
paiNext) {
06446
if (((*ppai)->pti2 == ptiAttachTo) && ((*ppai)->pti1 == ptiAttach)) {
06447
PATTACHINFO paiKill = *ppai;
06448 fFound =
TRUE;
06449 *ppai = (*ppai)->
paiNext;
06450 UserFreePool((HLOCAL)paiKill);
06451
break;
06452 }
06453 }
06454
06455
06456
06457
06458
if (!fFound) {
06459
return FALSE;
06460 }
06461 }
06462
06463
06464
06465
06466
06467
06468
06469
06470
06471
06472
if (!
FJOURNALRECORD() && !
FJOURNALPLAYBACK())
06473
return zzzReattachThreads(
FALSE);
06474
06475
return TRUE;
06476 }
06477
06478
06479
06480
06481
06482
06483
06484
06485 LONG_PTR
_SetMessageExtraInfo(LONG_PTR lData)
06486 {
06487 LONG_PTR lRet;
06488
PTHREADINFO pti =
PtiCurrent();
06489
06490 lRet = pti->
pq->
ExtraInfo;
06491 pti->
pq->
ExtraInfo = lData;
06492
return lRet;
06493 }