00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
#include "precomp.h"
00012
#pragma hdrstop
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #define CHRLINCR 10
00025
00026 VOID SetHungFlag(
00027
PWND pwnd,
00028 WORD wFlag)
00029 {
00030
00031
00032
00033
00034
if (!
TestWF(pwnd,
WFANYHUNGREDRAW) && pwnd->
spwndParent ==
PWNDDESKTOP(pwnd)) {
00035
00036
00037
00038
VWPLAdd(&
gpvwplHungRedraw, pwnd,
CHRLINCR);
00039 }
00040
00041
SetWF(pwnd, wFlag);
00042 }
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 VOID ClearHungFlag(
00058
PWND pwnd,
00059 WORD wFlag)
00060 {
00061
BOOL fInRedrawList =
TestWF(pwnd,
WFANYHUNGREDRAW);
00062
00063
ClrWF(pwnd, wFlag);
00064
if (!
TestWF(pwnd,
WFANYHUNGREDRAW) && fInRedrawList) {
00065
00066
00067
00068
VWPLRemove(&
gpvwplHungRedraw, pwnd);
00069 }
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 BOOL FHungApp(
00081
PTHREADINFO pti,
00082 DWORD dwTimeFromLastRead)
00083 {
00084
00085
00086
00087
00088
00089
00090
if (((
NtGetTickCount() -
GET_TIME_LAST_READ(pti)) > dwTimeFromLastRead) &&
00091 !((pti->
pcti->
fsWakeMask & QS_INPUT) && (pti->pEThread->Tcb.FreezeCount == 0)) &&
00092 !(pti->
ppi->W32PF_Flags & W32PF_APPSTARTING)) {
00093
return TRUE;
00094 }
00095
00096
return FALSE;
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 VOID xxxRedrawHungWindowFrame(
00108
PWND pwnd,
00109 BOOL fActive)
00110 {
00111 HDC hdc;
00112
UINT wFlags = DC_NC | DC_NOSENDMSG;
00113
00114
CheckLock(pwnd);
00115
00116
if (fActive)
00117 wFlags |= DC_ACTIVE;
00118
00119 hdc =
_GetDCEx(pwnd,
NULL, DCX_USESTYLE | DCX_WINDOW);
00120
xxxDrawCaptionBar(pwnd, hdc, wFlags);
00121
_ReleaseDC(hdc);
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 VOID xxxRedrawHungWindow(
00136
PWND pwnd,
00137 HRGN hrgnFullDrag)
00138 {
00139 HDC hdc;
00140 HBRUSH hbr;
00141 HRGN hrgnUpdate;
00142 RECT rc;
00143
TL tlpwnd;
00144
UINT flags;
00145 W32PID sid;
00146
DWORD dwColor;
00147
PWND pwndDesk;
00148
TL tlpwndDesk;
00149
00150
CheckCritIn();
00151
CheckLock(pwnd);
00152
00153
if (pwnd->
hrgnUpdate ==
NULL) {
00154
return;
00155 }
00156
00157
#ifdef HUNGAPP_GHOSTING
00158
00159
00160
00161
00162
if (!
TestWF(pwnd,
WFVISIBLE)) {
00163
return;
00164 }
00165
00166
00167
00168
00169
00170
if ((hrgnFullDrag ==
NULL) || (hrgnFullDrag !=
NULL &&
00171
FHungApp(
GETPTI(pwnd),
CMSHUNGAPPTIMEOUT))) {
00172 SignalGhost(pwnd);
00173 }
00174
00175
#endif // HUNGAPP_GHOSTING
00176
00177
00178
00179
00180
if (pwnd->
hrgnUpdate >
HRGN_FULL) {
00181 hrgnUpdate =
CreateEmptyRgn();
00182
if (hrgnUpdate ==
NULL) {
00183 hrgnUpdate =
HRGN_FULL;
00184
00185 }
else if (
CopyRgn(hrgnUpdate, pwnd->
hrgnUpdate) == ERROR) {
00186 GreDeleteObject(hrgnUpdate);
00187 hrgnUpdate =
HRGN_FULL;
00188 }
00189
00190 }
else {
00191
00192
00193
00194
00195
00196
CopyRect(&rc, &pwnd->
rcWindow);
00197 hrgnUpdate = GreCreateRectRgnIndirect(&rc);
00198
if (hrgnUpdate ==
NULL) {
00199 hrgnUpdate =
HRGN_FULL;
00200 }
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
if (hrgnFullDrag && hrgnUpdate !=
HRGN_FULL &&
00213
IntersectRgn(hrgnUpdate, hrgnUpdate, hrgnFullDrag) == NULLREGION) {
00214 GreDeleteObject(hrgnUpdate);
00215
return;
00216 }
00217
00218
ThreadLock(pwnd, &tlpwnd);
00219
00220 hdc =
_GetDCEx(pwnd, hrgnUpdate, DCX_USESTYLE | DCX_WINDOW |
00221 DCX_INTERSECTRGN | DCX_NODELETERGN | DCX_LOCKWINDOWUPDATE);
00222
xxxDrawWindowFrame(pwnd, hdc,
TRUE,
TestwndFrameOn(pwnd));
00223
_ReleaseDC(hdc);
00224
00225
CopyRect(&rc, &pwnd->
rcWindow);
00226
xxxCalcClientRect(pwnd, &rc,
TRUE);
00227
SetRectRgnIndirect(
ghrgnInv2, &rc);
00228
00229
if (hrgnUpdate >
HRGN_FULL) {
00230
switch (
IntersectRgn(hrgnUpdate, hrgnUpdate,
ghrgnInv2)) {
00231
00232
case ERROR:
00233 GreDeleteObject(hrgnUpdate);
00234 hrgnUpdate =
HRGN_FULL;
00235
break;
00236
00237
case NULLREGION:
00238
00239
00240
00241
00242
00243 GreDeleteObject(hrgnUpdate);
00244 hrgnUpdate =
NULL;
00245
break;
00246 }
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
if (hrgnUpdate !=
NULL && !
TestWF(pwnd,
WFCLIPCHILDREN)) {
00256 RECT rcT;
00257
PWND pwndT;
00258
00259
if (hrgnUpdate ==
HRGN_FULL) {
00260 rc = pwnd->
rcWindow;
00261 }
else {
00262 GreGetRgnBox(hrgnUpdate, &rc);
00263 }
00264
00265
for (pwndT = pwnd->
spwndChild; pwndT !=
NULL;
00266 pwndT = pwndT->
spwndNext) {
00267
00268
if (
TestWF(pwndT,
WFVISIBLE) &&
00269 (
TestWF(pwndT,
WFSTARTPAINT) || pwndT->
hrgnUpdate ==
NULL) &&
00270
IntersectRect(&rcT, &rc, &pwndT->
rcWindow)) {
00271
00272
00273
00274
00275
00276
00277
BEGINATOMICCHECK();
00278
xxxInternalInvalidate(pwndT, hrgnUpdate, RDW_INVALIDATE |
00279 RDW_FRAME | RDW_ERASE | RDW_ALLCHILDREN);
00280
ENDATOMICCHECK();
00281 }
00282 }
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 flags = DCX_INTERSECTRGN | DCX_WINDOW | DCX_CACHE;
00296
if (
TestWF(pwnd,
WFCLIPSIBLINGS))
00297 flags |= DCX_CLIPSIBLINGS;
00298
if (
TestWF(pwnd,
WFCLIPCHILDREN))
00299 flags |= DCX_CLIPCHILDREN;
00300
00301 hdc =
_GetDCEx(pwnd, hrgnUpdate, flags);
00302
00303
if (pwnd == pwnd->
head.rpdesk->pDeskInfo->spwndBkGnd) {
00304 pwndDesk =
PWNDDESKTOP(pwnd);
00305
ThreadLock(pwndDesk, &tlpwndDesk);
00306
xxxInternalPaintDesktop(
PWNDDESKTOP(pwnd), hdc,
TRUE);
00307
ThreadUnlock(&tlpwndDesk);
00308
00309 }
else {
00310
00311 rc = pwnd->
rcWindow;
00312
00313
OffsetRect(&rc, -pwnd->
rcWindow.left, -pwnd->
rcWindow.top);
00314
00315
00316
00317
00318
00319
if ((hbr = pwnd->
pcls->hbrBackground) !=
NULL) {
00320
if (hbr <= (HBRUSH)COLOR_ENDCOLORS + 1)
00321 hbr =
SYSHBRUSH((ULONG_PTR)hbr - 1);
00322 }
else {
00323
00324
00325
00326
00327
if (
TestWF(pwnd,
WFDIALOGWINDOW) &&
TestWF(pwnd,
WFWIN40COMPAT))
00328 hbr =
SYSHBR(3DFACE);
00329
else
00330 hbr =
SYSHBR(
WINDOW);
00331 }
00332
00333
00334
00335
00336 sid = (W32PID)GreGetObjectOwner((HOBJ)hbr, BRUSH_TYPE);
00337
if (sid == (W32PID)(ULONG_PTR)
GetCurrentProcessId() || sid == OBJECT_OWNER_PUBLIC) {
00338
00339
FillRect(hdc, &rc, hbr);
00340
00341 }
else {
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
if (
gatomConsoleClass == pwnd->
pcls->
atomClassName) {
00355
00356 dwColor =
_GetWindowLong(pwnd, GWL_CONSOLE_BKCOLOR);
00357
00358 }
else {
00359
00360
if ((dwColor = GreGetBrushColor(hbr)) == -1)
00361 dwColor = GreGetBrushColor(
SYSHBR(
WINDOW));
00362 }
00363
00364 GreSetSolidBrush(
ghbrHungApp, dwColor);
00365
00366
FillRect(hdc, &rc,
ghbrHungApp);
00367 }
00368 }
00369
_ReleaseDC(hdc);
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
SetWF(pwnd,
WFSENDNCPAINT);
00387
SetWF(pwnd,
WFSENDERASEBKGND);
00388
00389
00390
00391
00392
00393
00394
00395
SetWF(pwnd,
WFUPDATEDIRTY);
00396
00397
#ifdef WIN95DOESTHIS
00398
00399
00400
00401
if (hrgnFullDrag !=
NULL) {
00402
PWND pwndT;
00403
TL tlpwndT;
00404
00405 pwndT = pwnd->
spwndChild;
00406
ThreadLockNever(&tlpwndT);
00407
while (pwndT) {
00408
00409
if (
TestWF(pwndT,
WFREDRAWIFHUNG) &&
00410
FHungApp(
GETPTI(pwndT),
CMSHUNGAPPTIMEOUT)) {
00411
00412
ClearHungFlag(pwndT,
WFREDRAWIFHUNG);
00413
ThreadLockExchangeAlways(pwndT, &tlpwndT);
00414
xxxRedrawHungWindow(pwndT,
NULL);
00415 }
00416
00417
if (
TestWF(pwndT,
WFDESTROYED)) {
00418
break;
00419 }
00420
00421 pwndT = pwndT->
spwndNext;
00422 }
00423
00424
ThreadUnlock(&tlpwndT);
00425 }
00426
#endif
00427
00428
ThreadUnlock(&tlpwnd);
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 VOID xxxHungAppDemon(
00447
PWND pwnd,
00448 UINT message,
00449 UINT_PTR nID,
00450 LPARAM lParam)
00451 {
00452
TL tlpwnd;
00453
#if DBG
00454
PWND pwndT;
00455
#endif
00456
DWORD nPwndHungRedraw;
00457
PWND pwndHungRedraw;
00458
00459
00460
00461 UNREFERENCED_PARAMETER(message);
00462 UNREFERENCED_PARAMETER(nID);
00463
00464 UNREFERENCED_PARAMETER(lParam);
00465 UNREFERENCED_PARAMETER(pwnd);
00466
CheckLock(pwnd);
00467
00468
00469
00470
00471
IdleTimerProc();
00472
00473
00474
00475
00476
if (
NtGetTickCount() >=
gtimeStartCursorHide) {
00477
00478
00479
00480
zzzCalcStartCursorHide(
NULL, 0);
00481 }
00482
00483
00484
00485
00486
00487
if (
grpdeskRitInput ==
NULL ||
grpdeskRitInput->
pDeskInfo->
spwnd ==
NULL)
00488
return;
00489
00490
00491
00492
00493
00494 nPwndHungRedraw = 0;
00495 pwndHungRedraw =
NULL;
00496
while (pwndHungRedraw =
VWPLNext(
gpvwplHungRedraw, pwndHungRedraw, &nPwndHungRedraw)) {
00497
00498
00499
00500
00501
if (
FHungApp(
GETPTI(pwndHungRedraw),
CMSHUNGAPPTIMEOUT)) {
00502
ThreadLock(pwndHungRedraw, &tlpwnd);
00503
if (
TestWF(pwndHungRedraw,
WFREDRAWFRAMEIFHUNG)) {
00504
00505
00506
00507
00508
00509
xxxRedrawHungWindowFrame(pwndHungRedraw,
TestwndFrameOn(pwndHungRedraw));
00510 }
00511
00512
if (
TestWF(pwndHungRedraw,
WFREDRAWIFHUNG)) {
00513
ClearHungFlag(pwndHungRedraw,
WFREDRAWIFHUNG);
00514
xxxRedrawHungWindow(pwndHungRedraw,
NULL);
00515 }
00516
#if DBG
00517
pwndT =
00518
#endif
00519
00520
ThreadUnlock(&tlpwnd);
00521 }
00522 }
00523
00524
return;
00525 }