00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #define _TIMERS 1 // uses a LARGE_INTEGER
00014
#include "precomp.h"
00015
#pragma hdrstop
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #define TIMERID_MAX 0x7FFF
00028 #define TIMERID_MIN 0x100
00029
00030 #define ELAPSED_MAX 0x7FFFFFFF
00031
00032 #define SYSRIT_TIMER (TMRF_SYSTEM | TMRF_RIT)
00033
00034 WORD
cTimerId =
TIMERID_MAX;
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 UINT_PTR
_SetTimer(
00046
PWND pwnd,
00047 UINT_PTR nIDEvent,
00048 UINT dwElapse,
00049 TIMERPROC_PWND pTimerFunc)
00050 {
00051
00052
00053
00054
if (pwnd && (
PpiCurrent() !=
GETPTI(pwnd)->ppi)) {
00055
00056 RIPERR1(ERROR_ACCESS_DENIED,
00057 RIP_WARNING,
00058
"Calling SetTimer with window of another process %lX",
00059 pwnd);
00060
00061
return 0;
00062 }
00063
00064
return InternalSetTimer(pwnd, nIDEvent, dwElapse, pTimerFunc, 0);
00065 }
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 UINT_PTR
_SetSystemTimer(
00079
PWND pwnd,
00080 UINT_PTR nIDEvent,
00081 DWORD dwElapse,
00082 TIMERPROC_PWND pTimerFunc)
00083 {
00084
00085
00086
00087
if (pwnd &&
PpiCurrent() !=
GETPTI(pwnd)->ppi) {
00088
00089 RIPERR1(ERROR_ACCESS_DENIED,
00090 RIP_WARNING,
00091
"Calling SetSystemTimer with window of another process %lX",
00092 pwnd);
00093
00094
return 0;
00095 }
00096
00097
return InternalSetTimer(pwnd, nIDEvent, dwElapse, pTimerFunc, TMRF_SYSTEM);
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 VOID FreeTimer(
00113
PTIMER ptmr) {
00114
00115
CheckCritIn();
00116
00117
00118
00119
00120
00121
if (!
HMMarkObjectDestroy((PVOID)ptmr))
00122
return;
00123
00124
00125
00126
00127
00128
if (ptmr->flags & TMRF_READY)
00129
DecTimerCount(ptmr->pti);
00130
00131
00132
00133
00134
Unlock(&ptmr->spwnd);
00135
00136
00137
00138
00139
if (ptmr->ptmrPrev) {
00140 ptmr->ptmrPrev->ptmrNext = ptmr->ptmrNext;
00141 }
else {
00142
gptmrFirst = ptmr->
ptmrNext;
00143 }
00144
00145
if (ptmr->ptmrNext) {
00146 ptmr->
ptmrNext->
ptmrPrev = ptmr->
ptmrPrev;
00147 }
00148
00149
00150
00151
00152
HMFreeObject((PVOID)ptmr);
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 PTIMER FindTimer(
00168
PWND pwnd,
00169 UINT_PTR nID,
00170 UINT flags,
00171 BOOL fKill)
00172 {
00173
PTIMER ptmr;
00174
00175 ptmr =
gptmrFirst;
00176
00177
while (ptmr !=
NULL) {
00178
00179
00180
00181
00182
if ((ptmr->
spwnd == pwnd) &&
00183 (ptmr->
nID == nID) &&
00184 (ptmr->
flags &
SYSRIT_TIMER) == (flags &
SYSRIT_TIMER)) {
00185
00186
00187
00188
00189
00190
if (fKill) {
00191
FreeTimer(ptmr);
00192
return (
PTIMER)
TRUE;
00193 }
00194
00195
00196
00197
00198
break;
00199 }
00200
00201
00202
00203
00204 ptmr = ptmr->
ptmrNext;
00205 }
00206
00207
return ptmr;
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 UINT_PTR
InternalSetTimer(
00226
PWND pwnd,
00227 UINT_PTR nIDEvent,
00228 UINT dwElapse,
00229 TIMERPROC_PWND pTimerFunc,
00230 UINT flags)
00231 {
00232 LARGE_INTEGER liT = {1, 0};
00233
PTIMER ptmr;
00234
PTHREADINFO ptiCurrent;
00235
00236
CheckCritIn();
00237
00238
00239
00240
00241
00242 UserAssert(
gptiRit !=
NULL);
00243
00244
00245
00246
00247
00248
00249
if ((dwElapse == 0) || (dwElapse >
ELAPSED_MAX))
00250 dwElapse = 1;
00251
00252
00253
00254
00255
00256
if ((ptmr =
FindTimer(pwnd, nIDEvent, flags,
FALSE)) ==
NULL) {
00257
00258
00259
00260
00261 ptmr = (
PTIMER)
HMAllocObject(
NULL,
NULL,
TYPE_TIMER,
sizeof(
TIMER));
00262
if (ptmr ==
NULL) {
00263
return 0;
00264 }
00265
00266 ptmr->
spwnd =
NULL;
00267
00268
if (pwnd ==
NULL) {
00269
00270 WORD timerIdInitial =
cTimerId;
00271
00272
00273
00274
00275
do {
00276
00277
if (--
cTimerId <=
TIMERID_MIN)
00278
cTimerId =
TIMERID_MAX;
00279
00280
if (
cTimerId == timerIdInitial) {
00281
00282
00283
00284
00285
HMFreeObject(ptmr);
00286
return 0;
00287 }
00288
00289 }
while (
FindTimer(
NULL,
cTimerId, flags,
FALSE) !=
NULL);
00290
00291 ptmr->
nID = (
UINT)
cTimerId;
00292
00293 }
else {
00294 ptmr->
nID = nIDEvent;
00295 }
00296
00297
00298
00299
00300
00301 ptmr->
ptmrNext =
gptmrFirst;
00302 ptmr->
ptmrPrev =
NULL;
00303
if (
gptmrFirst)
00304
gptmrFirst->
ptmrPrev = ptmr;
00305
gptmrFirst = ptmr;
00306
00307 }
else {
00308
00309
00310
00311
00312
00313
if (ptmr->
flags & TMRF_READY)
00314
DecTimerCount(ptmr->
pti);
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 ptiCurrent = (
PTHREADINFO)(W32GetCurrentThread());
00334
00335
00336
00337
00338
if (pwnd ==
NULL) {
00339
00340
if (flags & TMRF_RIT) {
00341 ptmr->
pti =
gptiRit;
00342 }
else {
00343 ptmr->
pti = ptiCurrent;
00344 UserAssert(ptiCurrent);
00345 }
00346
00347 }
else {
00348
00349
00350
00351
00352
00353
00354
00355
if ((ptiCurrent->
TIF_flags &
TIF_16BIT) && !(flags & TMRF_PTIWINDOW)) {
00356 ptmr->
pti = ptiCurrent;
00357 UserAssert(ptiCurrent);
00358 }
else {
00359 ptmr->
pti =
GETPTI(pwnd);
00360 }
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
Lock(&(ptmr->
spwnd), pwnd);
00375
00376 ptmr->
cmsCountdown = ptmr->
cmsRate = dwElapse;
00377 ptmr->
flags = flags | TMRF_INIT;
00378 ptmr->
pfn = pTimerFunc;
00379 ptmr->
ptiOptCreator = (flags & TMRF_RIT ? ptiCurrent :
NULL);
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
if (ptiCurrent ==
gptiRit) {
00390
00391
00392
00393
gbMasterTimerSet =
TRUE;
00394 }
00395
00396 UserAssert(
gptmrMaster);
00397
KeSetTimer(
gptmrMaster, liT,
NULL);
00398
00399
00400
00401
00402
return (ptmr->
nID == 0 ? 1 : ptmr->
nID);
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 BOOL _KillTimer(
00415
PWND pwnd,
00416 UINT_PTR nIDEvent)
00417 {
00418
return KillTimer2(pwnd, nIDEvent,
FALSE);
00419 }
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 BOOL _KillSystemTimer(
00432
PWND pwnd,
00433 UINT_PTR nIDEvent)
00434 {
00435
return KillTimer2(pwnd, nIDEvent,
TRUE);
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 BOOL KillTimer2(
00448
PWND pwnd,
00449 UINT_PTR nIDEvent,
00450 BOOL fSystemTimer)
00451 {
00452
00453
00454
00455
00456
return (
FindTimer(pwnd,
00457 nIDEvent,
00458 (fSystemTimer ? TMRF_SYSTEM : 0),
00459
TRUE) !=
NULL);
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 VOID DestroyThreadsTimers(
00473
PTHREADINFO pti)
00474 {
00475
PTIMER ptmr;
00476
00477 ptmr =
gptmrFirst;
00478
00479
while (ptmr !=
NULL) {
00480
00481
00482
00483
00484
if (ptmr->
pti == pti || ptmr->
ptiOptCreator == pti) {
00485
PTIMER ptmrNext = ptmr->
ptmrNext;
00486
FreeTimer(ptmr);
00487 ptmr = ptmrNext;
00488 }
else {
00489 ptmr = ptmr->
ptmrNext;
00490 }
00491 }
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 VOID DestroyWindowsTimers(
00505
PWND pwnd)
00506 {
00507
PTIMER ptmr;
00508
00509 ptmr =
gptmrFirst;
00510
00511
while (ptmr !=
NULL) {
00512
00513
00514
00515
00516
if (ptmr->
spwnd == pwnd) {
00517
PTIMER ptmrNext = ptmr->
ptmrNext;
00518
FreeTimer(ptmr);
00519 ptmr = ptmrNext;
00520 }
else {
00521 ptmr = ptmr->
ptmrNext;
00522 }
00523 }
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 BOOL DoTimer(
00539
PWND pwndFilter)
00540 {
00541
PTHREADINFO pti;
00542
PTIMER ptmr;
00543
PTIMER ptmrNext;
00544
PQMSG pqmsg;
00545
00546
CheckCritIn();
00547
00548 pti =
PtiCurrent();
00549
00550
00551
00552
00553 ptmr =
gptmrFirst;
00554
00555
while (ptmr !=
NULL) {
00556
00557
00558
00559
00560
if ((ptmr->
flags & TMRF_READY) &&
00561 (ptmr->
pti == pti) &&
00562
CheckPwndFilter(ptmr->
spwnd, pwndFilter)) {
00563
00564
00565
00566
00567
00568
if ((pqmsg =
AllocQEntry(&pti->
mlPost)) !=
NULL) {
00569
00570
00571
00572
00573
00574
StoreQMessage(pqmsg,
00575 ptmr->
spwnd,
00576 (
UINT)((ptmr->
flags & TMRF_SYSTEM) ?
00577
WM_SYSTIMER : WM_TIMER),
00578 (WPARAM)ptmr->
nID,
00579 (LPARAM)ptmr->
pfn,
00580 0, 0, 0);
00581
#ifdef REDIRECTION
00582
StoreQMessagePti(pqmsg, pti);
00583
#endif // REDIRECTION
00584
SetWakeBit(pti, QS_POSTMESSAGE | QS_ALLPOSTMESSAGE);
00585 }
00586
00587
00588
00589
00590 ptmr->
flags &= ~TMRF_READY;
00591
DecTimerCount(ptmr->
pti);
00592
00593
00594
00595
00596
00597
00598 ptmrNext = ptmr->
ptmrNext;
00599
if (ptmrNext !=
NULL) {
00600
00601
00602
00603
00604
if (ptmr->
ptmrPrev) {
00605 ptmr->
ptmrPrev->
ptmrNext = ptmr->
ptmrNext;
00606 }
else
00607
gptmrFirst = ptmr->
ptmrNext;
00608
00609 ptmrNext->
ptmrPrev = ptmr->
ptmrPrev;
00610
00611
00612
00613
00614
while (ptmrNext->
ptmrNext !=
NULL)
00615 ptmrNext = ptmrNext->
ptmrNext;
00616
00617
00618
00619
00620 ptmrNext->
ptmrNext = ptmr;
00621 ptmr->
ptmrPrev = ptmrNext;
00622 ptmr->
ptmrNext =
NULL;
00623 }
00624
00625
return TRUE;
00626 }
00627
00628 ptmr = ptmr->
ptmrNext;
00629 }
00630
00631
return FALSE;
00632 }
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 VOID DecTimerCount(
00645
PTHREADINFO pti)
00646 {
00647
CheckCritIn();
00648
00649
if (--pti->
cTimersReady == 0)
00650 pti->
pcti->
fsWakeBits &= ~QS_TIMER;
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661 VOID JournalTimer(
00662
PWND pwnd,
00663 UINT message,
00664 UINT_PTR nID,
00665 LPARAM lParam)
00666 {
00667
PTHREADINFO pti;
00668
00669 DBG_UNREFERENCED_PARAMETER(pwnd);
00670 DBG_UNREFERENCED_PARAMETER(message);
00671 DBG_UNREFERENCED_PARAMETER(nID);
00672
00673
00674
00675
00676
if (pti = ((
PTIMER)lParam)->ptiOptCreator)
00677
WakeSomeone(pti->
pq, pti->
pq->
msgJournal,
NULL);
00678
00679
return;
00680 }
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693 void SetJournalTimer(
00694 DWORD dt,
00695 UINT msgJournal)
00696 {
00697
static UINT_PTR idJournal = 0;
00698
00699
PtiCurrent()->pq->msgJournal = msgJournal;
00700
00701
00702
00703
00704
00705
00706 idJournal =
InternalSetTimer(
NULL,
00707 idJournal,
00708
dt,
00709
JournalTimer,
00710 TMRF_RIT | TMRF_ONESHOT);
00711 }
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722 UINT_PTR
StartTimers(VOID)
00723 {
00724
00725
00726
00727 GreStartTimers();
00728
00729
00730
00731
00732
00733
return InternalSetTimer(
NULL, 0, 1000,
xxxHungAppDemon, TMRF_RIT);
00734 }
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746 VOID TimersProc(
00747 VOID)
00748 {
00749
INT dmsSinceLast;
00750 LARGE_INTEGER liT;
00751
PTIMER ptmr;
00752
DWORD cmsCur;
00753
00754
00755
00756
00757
00758
00759
EnterCrit();
00760
00761 cmsCur =
NtGetTickCount();
00762 dmsSinceLast =
ComputePastTickDelta(cmsCur,
gcmsLastTimer);
00763
gcmsLastTimer = cmsCur;
00764
00765
00766
00767
00768
00769
00770
00771
gdmsNextTimer = 0x7FFFFFFF;
00772 ptmr =
gptmrFirst;
00773
gbMasterTimerSet =
FALSE;
00774
while (ptmr !=
NULL) {
00775
00776
00777
00778
00779
00780
00781
00782
if (ptmr->
flags & TMRF_WAITING) {
00783 ptmr = ptmr->
ptmrNext;
00784
continue;
00785 }
00786
00787
00788
00789
00790
00791
00792
if (ptmr->
flags & TMRF_INIT) {
00793 ptmr->
flags &= ~TMRF_INIT;
00794
00795 }
else {
00796
00797
00798
00799
00800 ptmr->
cmsCountdown -= dmsSinceLast;
00801
if (ptmr->
cmsCountdown <= 0) {
00802 ptmr->
cmsCountdown = ptmr->
cmsRate;
00803
00804
00805
00806
00807
00808
00809
if (!(ptmr->
flags & TMRF_READY)) {
00810
00811
00812
00813
00814
if (ptmr->
flags & TMRF_ONESHOT)
00815 ptmr->
flags |= TMRF_WAITING;
00816
00817
00818
00819
00820
00821
00822
00823
00824
if (ptmr->
flags & TMRF_RIT) {
00825
TL tlTimer;
00826
00827
ThreadLock(ptmr, &tlTimer);
00828
00829
00830
00831 (ptmr->
pfn)(
NULL,
00832
WM_SYSTIMER,
00833 ptmr->
nID,
00834 (LPARAM)ptmr);
00835
00836
if (
HMIsMarkDestroy(ptmr)) {
00837 ptmr = ptmr->
ptmrNext;
00838
ThreadUnlock(&tlTimer);
00839
continue;
00840 }
00841
ThreadUnlock(&tlTimer);
00842
00843 }
else {
00844 ptmr->
flags |= TMRF_READY;
00845 ptmr->
pti->
cTimersReady++;
00846
SetWakeBit(ptmr->
pti, QS_TIMER);
00847 }
00848 }
00849 }
00850 }
00851
00852
00853
00854
00855
if (ptmr->
cmsCountdown <
gdmsNextTimer)
00856
gdmsNextTimer = ptmr->
cmsCountdown;
00857
00858
00859
00860
00861 ptmr = ptmr->
ptmrNext;
00862 }
00863
00864
if (!
gbMasterTimerSet) {
00865
00866
00867
00868
00869
00870 liT.QuadPart = Int32x32To64(-10000,
gdmsNextTimer);
00871
KeSetTimer(
gptmrMaster, liT,
NULL);
00872 }
00873
00874
LeaveCrit();
00875 }
00876
00877
00878
00879
00880
00881
00882 VOID xxxSystemTimerProc(
PWND pwnd, UINT msg, UINT_PTR
id, LPARAM lParam)
00883 {
00884
CheckLock(pwnd);
00885 UNREFERENCED_PARAMETER(
msg);
00886 UNREFERENCED_PARAMETER(
id);
00887 UNREFERENCED_PARAMETER(lParam);
00888
00889
switch (
id) {
00890
case IDSYS_LAYER: {
00891
PDCE pdce;
00892
00893
for (pdce =
gpDispInfo->
pdceFirst; pdce !=
NULL; pdce = pdce->
pdceNext) {
00894
00895
if (pdce->
DCX_flags & (DCX_INVALID | DCX_DESTROYTHIS))
00896
continue;
00897
00898
if ((pdce->
DCX_flags & DCX_LAYERED) && (pdce->
DCX_flags & DCX_INUSE)) {
00899
UpdateLayeredSprite(pdce);
00900 }
00901 }
00902 }
00903
return;
00904
00905
case IDSYS_FADE:
00906
AnimateFade();
00907
return;
00908
00909
case IDSYS_FLASHWND:
00910
xxxFlashWindow(pwnd, FLASHW_TIMERCALL, 0);
00911
return;
00912
00913
case IDSYS_WNDTRACKING: {
00914
00915
00916
00917
00918
00919
00920
PTHREADINFO pti =
GETPTI(pwnd);
00921 UserAssert(
TestUP(ACTIVEWINDOWTRACKING));
00922
00923
if ((pti->
rpdesk->
spwndTrack !=
NULL)
00924 && (pwnd ==
GetActiveTrackPwnd(pti->
rpdesk->
spwndTrack,
NULL))) {
00925
00926 pti->
pq->
QF_flags |= (
QF_ACTIVEWNDTRACKING |
QF_MOUSEMOVED);
00927
00928
#ifdef REDIRECTION
00929
00930
00931
00932 PushMouseMove(pti->
pq,
gpsi->ptCursor);
00933
#endif // REDIRECTION
00934
00935
SetWakeBit(pti, QS_MOUSEMOVE);
00936 }
00937 }
00938
break;
00939
00940
case IDSYS_MOUSEHOVER: {
00941
PTHREADINFO pti =
GETPTI(pwnd);
00942
PDESKTOP pdesk = pti->
rpdesk;
00943
00944
00945
00946
00947
00948
if ((pdesk->
dwDTFlags &
DF_TRACKMOUSEHOVER)
00949 && (
HWq(pwnd) ==
HWq(pdesk->
spwndTrack)
00950 &&
PtInRect(&pdesk->
rcMouseHover,
gpsi->ptCursor))) {
00951
00952
UINT message;
00953 WPARAM wParam;
00954 POINT pt =
gpsi->ptCursor;
00955
00956
if (pdesk->
htEx == HTCLIENT) {
00957 message = WM_MOUSEHOVER;
00958 wParam = (WPARAM)
GetMouseKeyFlags(pti->
pq);
00959
#ifdef USE_MIRRORING
00960
if (
TestWF(pwnd, WEFLAYOUTRTL)) {
00961 pt.x = pwnd->
rcClient.right - pt.x - 1;
00962 }
else
00963
#endif
00964
{
00965 pt.x -= pwnd->
rcClient.left;
00966 }
00967 pt.y -= pwnd->
rcClient.top;
00968 }
else {
00969 message = WM_NCMOUSEHOVER;
00970
00971
00972
00973 wParam = (WPARAM)LOWORD(pdesk->
htEx);
00974
if ((wParam >=
HTEXMENUFIRST) && (wParam <=
HTEXMENULAST)) {
00975 wParam = (WPARAM)HTMENU;
00976 }
else if ((wParam >=
HTEXSCROLLFIRST) && (wParam <=
HTEXSCROLLLAST)) {
00977 wParam = (WPARAM)(HIWORD(pdesk->
htEx) ? HTVSCROLL : HTHSCROLL);
00978 }
00979 }
00980
00981
_PostMessage(pwnd, message, wParam, MAKELPARAM(pt.x, pt.y));
00982
00983 pdesk->
dwDTFlags &= ~
DF_TRACKMOUSEHOVER;
00984
break;
00985 }
00986 }
00987
return;
00988
00989
00990
default:
00991 RIPMSG1(RIP_ERROR,
"xxxSystemTimerProc: unexpected id:%#lx",
id);
00992
break;
00993 }
00994
00995
00996
00997
00998
_KillSystemTimer(pwnd,
id);
00999
return;
01000 }
01001