00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#include "precomp.h"
00016
#pragma hdrstop
00017
00018
00019
00020
00021
#if DBG
00022
BOOL fDisableCache;
00023
#endif
00024
00025
00026
00027
00028
00029
00030 __inline
VOID DecrementFreeDCECount(VOID)
00031 {
00032
gnDCECount--;
00033 UserAssert(
gnDCECount >= 0);
00034 }
00035
00036
00037
00038
00039
00040
00041 __inline
VOID IncrementFreeDCECount(VOID)
00042 {
00043
gnDCECount++;
00044 UserAssert(
gnDCECount >= 0);
00045 }
00046
00047
00048
00049
00050
00051
00052
00053 void SetMonitorRegion(
PMONITOR pMonitor, HRGN hrgnDst, HRGN hrgnSrc)
00054 {
00055
if (
IntersectRgn(hrgnDst, hrgnSrc, pMonitor->
hrgnMonitor) == ERROR) {
00056 GreSetRectRgn(hrgnDst, 0, 0, 0, 0);
00057
return;
00058 }
00059
00060 GreOffsetRgn(hrgnDst, -pMonitor->
rcMonitor.left, -pMonitor->
rcMonitor.top);
00061 }
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 VOID ResetOrg(
00074 HRGN hrgn,
00075
PDCE pdce,
00076 BOOL fSetVisRgn)
00077 {
00078 RECT rc;
00079
PWND pwndLayer;
00080
00081
00082
00083
00084
00085
if (
GETFNID(pdce->
pwndOrg) ==
FNID_DESKTOP) {
00086 rc.left = rc.top = 0;
00087 rc.right =
SYSMET(CXVIRTUALSCREEN);
00088 rc.bottom =
SYSMET(CYVIRTUALSCREEN);
00089 }
else if (pdce->
DCX_flags & DCX_WINDOW) {
00090 rc = pdce->
pwndOrg->
rcWindow;
00091 }
else {
00092 rc = pdce->
pwndOrg->
rcClient;
00093 }
00094
00095
if (pdce->
pMonitor !=
NULL) {
00096
OffsetRect(&rc, -pdce->
pMonitor->
rcMonitor.left,
00097 -pdce->
pMonitor->
rcMonitor.top);
00098
00099
if (hrgn !=
NULL) {
00100
SetMonitorRegion(pdce->
pMonitor, hrgn, hrgn);
00101 }
00102 }
00103
00104
if ((pwndLayer =
GetLayeredWindow(pdce->
pwndOrg)) !=
NULL) {
00105
if (pdce->
DCX_flags & DCX_LAYERED) {
00106
int x = pwndLayer->
rcWindow.left;
00107
int y = pwndLayer->
rcWindow.top;
00108
00109
00110
00111
00112
00113
00114
OffsetRect(&rc, -x, -y);
00115
if (hrgn !=
NULL) {
00116 GreOffsetRgn(hrgn, -x, -y);
00117 }
00118 }
else {
00119
00120
00121
00122
00123
00124
if (hrgn !=
NULL) {
00125 GreSetRectRgn(hrgn, 0, 0, 0, 0);
00126 }
00127 }
00128 }
else {
00129 UserAssert(!(pdce->
DCX_flags & DCX_LAYERED));
00130 }
00131
00132 GreSetDCOrg(pdce->
hdc, rc.left, rc.top, (PRECTL)&rc);
00133
00134
if (fSetVisRgn) {
00135 GreSelectVisRgn(pdce->
hdc, hrgn, SVR_DELETEOLD);
00136 }
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 HDC
_GetDC(
00149
PWND pwnd)
00150 {
00151
00152
00153
00154
00155
if (pwnd ==
NULL) {
00156
00157
PDESKTOP pdesk =
PtiCurrent()->rpdesk;
00158
00159
if (pdesk) {
00160
return _GetDCEx(pdesk->
pDeskInfo->
spwnd,
00161
NULL,
00162 DCX_WINDOW | DCX_CACHE);
00163 }
00164
00165
00166
00167
00168
return NULL;
00169 }
00170
00171
return _GetDCEx(pwnd,
NULL, DCX_USESTYLE);
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 BOOL _ReleaseDC(
00184 HDC hdc)
00185 {
00186
CheckCritIn();
00187
00188
return (
ReleaseCacheDC(hdc,
FALSE) ==
DCE_NORELEASE ?
FALSE :
TRUE);
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 HDC
_GetWindowDC(
00202
PWND pwnd)
00203 {
00204
00205
#if 0
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
if (
TestWF(pwnd,
WFMINIMIZED) && !
TestWF(pwnd,
WFWIN40COMPAT))
00217
return(
_GetDCEx(pwnd, hrgnClip, DCX_INTERNAL | DCX_CACHE | DCX_USESTYLE));
00218
#endif
00219
00220
return _GetDCEx(pwnd,
NULL, DCX_WINDOW | DCX_USESTYLE);
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 VOID UserSetDCVisRgn(
00238
PDCE pdce)
00239 {
00240 HRGN hrgn =
NULL;
00241
00242
00243
00244
00245
00246
if (!
CalcVisRgn(&hrgn, pdce->
pwndOrg, pdce->
pwndClip, pdce->
DCX_flags)) {
00247 pdce->
DCX_flags |= DCX_PWNDORGINVISIBLE;
00248 }
else {
00249 pdce->
DCX_flags &= ~DCX_PWNDORGINVISIBLE;
00250 }
00251
00252
00253
00254
00255
if (pdce->
DCX_flags & DCX_INTERSECTRGN) {
00256
00257 UserAssert(pdce->
hrgnClipPublic !=
HRGN_FULL);
00258
00259
if (pdce->
hrgnClipPublic ==
NULL) {
00260
SetEmptyRgn(hrgn);
00261 }
else {
00262
IntersectRgn(hrgn, hrgn, pdce->
hrgnClipPublic);
00263 }
00264
00265 }
else if (pdce->
DCX_flags & DCX_EXCLUDERGN) {
00266
00267 UserAssert(pdce->
hrgnClipPublic !=
NULL);
00268
00269
if (pdce->
hrgnClipPublic ==
HRGN_FULL) {
00270
SetEmptyRgn(hrgn);
00271 }
else {
00272
SubtractRgn(hrgn, hrgn, pdce->
hrgnClipPublic);
00273 }
00274 }
00275
00276
ResetOrg(hrgn, pdce,
TRUE);
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 HRGN
UserGetClientRgn(
00291 HWND hwnd,
00292 LPRECT lprc,
00293 BOOL bWindowInsteadOfClient)
00294 {
00295 HRGN hrgnClient = (HRGN)
NULL;
00296
PWND pwnd;
00297
00298
00299
00300
00301
CheckCritIn();
00302
00303
if (pwnd =
ValidateHwnd(hwnd)) {
00304
00305
if (bWindowInsteadOfClient) {
00306
00307
00308
00309
00310
00311
00312
CalcVisRgn(&hrgnClient,
00313 pwnd,
00314 pwnd,
00315 DCX_WINDOW |
00316 (
TestWF(pwnd,
WFCLIPSIBLINGS) ? DCX_CLIPSIBLINGS : 0));
00317 }
else {
00318
CalcVisRgn(&hrgnClient,
00319 pwnd,
00320 pwnd,
00321 DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS);
00322 }
00323
00324 *lprc = pwnd->
rcClient;
00325 }
00326
00327
return hrgnClient;
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 BOOL UserGetHwnd(
00345 HDC hdc,
00346 HWND *phwnd,
00347 PVOID *ppwo,
00348 BOOL bCheckStyle)
00349 {
00350
PWND pwnd;
00351
PDCE pdce;
00352
00353
00354
00355
00356
CheckCritIn();
00357
00358
00359
00360
00361
00362
00363
00364
00365
for (pdce =
gpDispInfo->
pdceFirst; pdce !=
NULL; pdce = pdce->
pdceNext) {
00366
00367
if (pdce->
hdc == hdc)
00368
break;
00369 }
00370
00371
00372
00373
00374
if ((pdce ==
NULL) || (pdce->
pwndOrg ==
NULL))
00375
return FALSE;
00376
00377 pwnd = pdce->
pwndOrg;
00378
00379
00380
00381
00382
00383
if (bCheckStyle) {
00384
00385
if ( !
TestWF(pwnd,
WFCLIPCHILDREN) ||
00386 !
TestWF(pwnd,
WFCLIPSIBLINGS) ||
00387
TestCF(pwnd,
CFPARENTDC)) {
00388
00389 RIPMSG0(RIP_WARNING,
"UserGetHwnd: Bad OpenGL window style or class");
00390
return FALSE;
00391 }
00392 }
00393
00394
00395
00396
00397 *phwnd =
HW(pwnd);
00398 *ppwo =
_GetProp(pwnd,
PROP_WNDOBJ,
TRUE);
00399
00400
return TRUE;
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 VOID UserAssociateHwnd(
00416 HWND hwnd,
00417 PVOID pwo)
00418 {
00419
PWND pwnd;
00420
00421
00422
00423
00424
CheckCritIn();
00425
00426
if (pwnd =
ValidateHwnd(hwnd)) {
00427
00428
if (pwo !=
NULL) {
00429
if (
InternalSetProp(pwnd,
PROP_WNDOBJ, pwo,
PROPF_INTERNAL |
PROPF_NOPOOL))
00430
gcountPWO++;
00431 }
else {
00432
if (
InternalRemoveProp(pwnd,
PROP_WNDOBJ,
TRUE))
00433
gcountPWO--;
00434 }
00435 }
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 BOOL UserReleaseDC(
00448 HDC hdc)
00449 {
00450
BOOL b;
00451
00452
EnterCrit();
00453 b =
_ReleaseDC(hdc);
00454
LeaveCrit();
00455
00456
return b;
00457 }
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 VOID InvalidateDce(
00471
PDCE pdce)
00472 {
00473 GreLockDisplay(
gpDispInfo->
hDev);
00474
00475
if (!(pdce->
DCX_flags & DCX_INUSE)) {
00476
00477
00478
00479
00480
00481
SpbCheckDce(pdce);
00482
00483
MarkDCEInvalid(pdce);
00484
00485 pdce->
pwndOrg =
NULL;
00486 pdce->
pwndClip =
NULL;
00487 pdce->
hrgnClip =
NULL;
00488 pdce->
hrgnClipPublic =
NULL;
00489
00490
00491
00492
00493
00494
00495 GreSelectVisRgn(pdce->
hdc,
NULL, SVR_DELETEOLD);
00496
00497 }
else {
00498
00499
PWND pwndOrg = pdce->
pwndOrg;
00500
PWND pwndClip = pdce->
pwndClip;
00501
00502
00503
00504
00505
00506
00507 pdce->
DCX_flags &= ~(DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS);
00508
00509
00510
00511
00512
if (
TestCF(pwndOrg,
CFPARENTDC) &&
00513 (
TestWF(pwndOrg,
WFWIN31COMPAT) || !
TestWF(pwndClip,
WFCLIPCHILDREN)) &&
00514 (
TestWF(pwndOrg,
WFVISIBLE) ==
TestWF(pwndClip,
WFVISIBLE))) {
00515
00516
if (
TestWF(pwndClip,
WFCLIPSIBLINGS))
00517 pdce->
DCX_flags |= DCX_CLIPSIBLINGS;
00518
00519 }
else {
00520
00521
if (
TestWF(pwndOrg,
WFCLIPCHILDREN) && !
TestWF(pwndOrg,
WFMINIMIZED))
00522 pdce->
DCX_flags |= DCX_CLIPCHILDREN;
00523
00524
if (
TestWF(pwndOrg,
WFCLIPSIBLINGS))
00525 pdce->
DCX_flags |= DCX_CLIPSIBLINGS;
00526 }
00527
00528
00529
00530
00531 pdce->
DCX_flags |= DCX_SAVEDRGNINVALID;
00532
00533
UserSetDCVisRgn(pdce);
00534 }
00535
00536 GreUnlockDisplay(
gpDispInfo->
hDev);
00537 }
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549 VOID DeleteHrgnClip(
00550
PDCE pdce)
00551 {
00552
00553
00554
00555 pdce->
DCX_flags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN);
00556
00557
00558
00559
00560
00561
if (!(pdce->
DCX_flags & DCX_NODELETERGN)) {
00562
DeleteMaybeSpecialRgn(pdce->
hrgnClip);
00563 }
else {
00564 pdce->
DCX_flags &= ~DCX_NODELETERGN;
00565 }
00566
00567
DeleteMaybeSpecialRgn(pdce->
hrgnClipPublic);
00568
00569 pdce->
hrgnClip =
NULL;
00570 pdce->
hrgnClipPublic =
NULL;
00571
00572
00573
00574
00575
00576
if (pdce->
DCX_flags & DCX_SAVEDRGNINVALID) {
00577
InvalidateDce(pdce);
00578
00579
00580
00581
00582
00583
if (pdce->
hrgnSavedVis !=
NULL) {
00584 GreDeleteObject(pdce->
hrgnSavedVis);
00585 pdce->
hrgnSavedVis =
NULL;
00586 }
00587 }
else {
00588
00589
00590
00591
00592
if (pdce->
hrgnSavedVis !=
NULL) {
00593 GreSelectVisRgn(pdce->
hdc, pdce->
hrgnSavedVis, SVR_DELETEOLD);
00594 pdce->
hrgnSavedVis =
NULL;
00595 }
00596 }
00597 }
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608 HDC
_GetDCEx(
00609
PWND pwnd,
00610 HRGN hrgnClip,
00611 DWORD DCX_flags)
00612 {
00613 HRGN hrgn;
00614 HDC hdcMatch;
00615
PWND pwndClip;
00616
PWND pwndOrg;
00617
PDCE pdce;
00618
PDCE *ppdce;
00619
PDCE *ppdceNotInUse;
00620
DWORD DCX_flagsMatch;
00621
BOOL bpwndOrgVisible;
00622
PWND pwndLayer;
00623 HBITMAP hbmLayer;
00624
BOOL fVisRgnError =
FALSE;
00625
00626
00627
00628
00629 GreLockDisplay(
gpDispInfo->
hDev);
00630
00631
if (pwnd ==
NULL)
00632 pwnd =
PtiCurrent()->rpdesk->pDeskInfo->spwnd;
00633
00634 hdcMatch =
NULL;
00635 pwndOrg = pwndClip = pwnd;
00636
00637 bpwndOrgVisible =
IsVisible(pwndOrg);
00638
00639
if (
PpiCurrent()->W32PF_Flags & W32PF_OWNDCCLEANUP) {
00640
DelayedDestroyCacheDC();
00641 }
00642
00643
00644
00645
00646
if (DCX_flags & DCX_USESTYLE) {
00647
00648 DCX_flags &= ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_PARENTCLIP);
00649
00650
if (!(DCX_flags & DCX_WINDOW)) {
00651
00652
if (
TestCF(pwndOrg,
CFPARENTDC))
00653 DCX_flags |= DCX_PARENTCLIP;
00654
00655
00656
00657
00658
00659
if (!(DCX_flags & DCX_CACHE) && !
TestCF(pwndOrg,
CFOWNDC)) {
00660
if (
TestCF(pwndOrg,
CFCLASSDC)) {
00661
00662
00663
00664
if (pwndOrg->
pcls->
pdce !=
NULL) {
00665 hdcMatch = pwndOrg->
pcls->
pdce->
hdc;
00666 }
00667 }
else {
00668 DCX_flags |= DCX_CACHE;
00669 }
00670 }
00671
00672
if (
TestWF(pwndOrg,
WFCLIPCHILDREN))
00673 DCX_flags |= DCX_CLIPCHILDREN;
00674
00675
if (
TestWF(pwndOrg,
WFCLIPSIBLINGS))
00676 DCX_flags |= DCX_CLIPSIBLINGS;
00677
00678
00679
00680
00681
if (
TestWF(pwndOrg,
WFMINIMIZED)) {
00682 DCX_flags &= ~DCX_CLIPCHILDREN;
00683
00684
if (pwndOrg->
pcls->spicn)
00685 DCX_flags |= DCX_CACHE;
00686 }
00687
00688 }
else {
00689
if (
TestWF(pwndClip,
WFCLIPSIBLINGS))
00690 DCX_flags |= DCX_CLIPSIBLINGS;
00691
00692 DCX_flags |= DCX_CACHE;
00693
00694
00695
00696
00697 }
00698 }
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
if (DCX_flags & DCX_NOCLIPCHILDREN) {
00709 DCX_flags &= ~(DCX_PARENTCLIP | DCX_CLIPCHILDREN);
00710 DCX_flags |= DCX_CACHE;
00711 }
00712
00713
00714
00715
00716
if ((pwndLayer =
GetLayeredWindow(pwndOrg)) !=
NULL &&
00717 (hbmLayer =
_GetProp(pwndLayer,
PROP_LAYER,
TRUE)) !=
NULL) {
00718
00719
00720
00721
00722 DCX_flags |= DCX_LAYERED;
00723
00724
00725
00726
00727
00728
00729
if (pwndOrg == pwndLayer) {
00730 DCX_flags &= ~DCX_PARENTCLIP;
00731 }
00732
00733
00734
00735
00736
if (hrgnClip >
HRGN_SPECIAL_LAST) {
00737 GreOffsetRgn(hrgnClip, -pwndLayer->
rcWindow.left,
00738 -pwndLayer->
rcWindow.top);
00739 }
00740 }
else {
00741 pwndLayer =
NULL;
00742 hbmLayer =
NULL;
00743 }
00744
00745
if (DCX_flags & DCX_PARENTCLIP) {
00746
00747
PWND pwndParent;
00748
00749
00750
00751
00752
00753
00754
if (pwndOrg->
spwndParent ==
NULL)
00755 pwndParent =
PtiCurrent()->rpdesk->pDeskInfo->spwnd;
00756
else
00757 pwndParent = pwndOrg->
spwndParent;
00758
00759
00760
00761
00762 DCX_flags |= DCX_CACHE;
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
if (!(DCX_flags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN)) &&
00781 (
TestWF(pwndOrg,
WFWIN31COMPAT) || !
TestWF(pwndParent,
WFCLIPCHILDREN)) &&
00782
TestWF(pwndParent,
WFVISIBLE) ==
TestWF(pwndOrg,
WFVISIBLE)) {
00783
00784 pwndClip = pwndParent;
00785
00786
#if DBG
00787
if (DCX_flags & DCX_CLIPCHILDREN)
00788 RIPMSG0(RIP_WARNING,
"WS_CLIPCHILDREN overridden by CS_PARENTDC");
00789
if (DCX_flags & DCX_CLIPSIBLINGS)
00790 RIPMSG0(RIP_WARNING,
"WS_CLIPSIBLINGS overridden by CS_PARENTDC");
00791
#endif
00792
00793
00794
00795
00796
00797 DCX_flags &= ~(DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS);
00798
if (
TestWF(pwndClip,
WFCLIPSIBLINGS))
00799 DCX_flags |= DCX_CLIPSIBLINGS;
00800 }
00801 }
00802
00803
00804
00805
00806
00807
00808
00809
if (!(DCX_flags & DCX_CACHE)) {
00810
if (pwndOrg ==
NULL ||
GETPTI(pwndOrg) !=
PtiCurrent())
00811 DCX_flags |= DCX_CACHE;
00812 }
00813
00814 DCX_flagsMatch = DCX_flags & DCX_MATCHMASK;
00815
00816
if (!(DCX_flags & DCX_CACHE)) {
00817
00818
00819
00820
00821
00822
for (ppdce = &
gpDispInfo->
pdceFirst; (pdce = *ppdce); ppdce = &pdce->
pdceNext) {
00823
00824
if (pdce->
DCX_flags & DCX_CACHE)
00825
continue;
00826
00827
00828
00829
00830
if (!(pdce->
pwndOrg == pwndOrg || pdce->
hdc == hdcMatch))
00831
continue;
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
if ((pdce->
DCX_flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN)) &&
00864 (DCX_flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN))) {
00865
00866 RIPMSG0(RIP_WARNING,
"Nested BeginPaint() calls, please fix Your app!");
00867
DeleteHrgnClip(pdce);
00868 }
00869
00870
if (pdce->
DCX_flags & DCX_LAYERED) {
00871
00872
00873
00874
00875
UpdateLayeredSprite(pdce);
00876
00877
00878
00879
00880
00881 UserVerify(GreSelectRedirectionBitmap(pdce->
hdc,
NULL));
00882 }
00883
00884
00885
00886
00887
00888
00889
if ( pdce->
pwndOrg == pwndOrg &&
00890 bpwndOrgVisible &&
00891 (pdce->
DCX_flags & DCX_LAYERED) == (DCX_flags & DCX_LAYERED) &&
00892 !(pdce->
DCX_flags & DCX_PWNDORGINVISIBLE)) {
00893
00894
goto HaveComputedEntry;
00895 }
00896
00897
goto RecomputeEntry;
00898 }
00899
00900 RIPMSG1(RIP_WARNING,
"Couldn't find DC for %p - bad code path", pwndOrg);
00901
00902 NullExit:
00903
00904 GreUnlockDisplay(
gpDispInfo->
hDev);
00905
return NULL;
00906
00907 }
else {
00908
00909
00910
00911
00912
00913 SearchAgain:
00914
00915
#if DBG
00916
if (fDisableCache)
00917
goto SearchFailed;
00918
#endif
00919
00920
00921
00922
00923
00924
for (ppdce = &
gpDispInfo->
pdceFirst; (pdce = *ppdce); ppdce = &pdce->
pdceNext) {
00925
00926
00927
00928
00929
00930
00931
00932
00933 UserAssert(!(pdce->
DCX_flags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) ||
00934 (pdce->
DCX_flags & DCX_INUSE));
00935
00936
if ((pdce->
pwndClip == pwndClip) &&
00937 pdce->
pMonitor ==
NULL &&
00938 (DCX_flagsMatch == (pdce->
DCX_flags & (DCX_MATCHMASK | DCX_INUSE | DCX_INVALID)))) {
00939
00940
00941
00942
00943
if (
TestWF(pwndClip,
WFMINIMIZED) &&
00944 (pdce->
pwndOrg != pdce->
pwndClip)) {
00945
continue;
00946 }
00947
00948
00949
00950
00951
00952
00953
00954
if (bpwndOrgVisible && pdce->
DCX_flags & DCX_PWNDORGINVISIBLE) {
00955
continue;
00956 }
00957
00958
00959
00960
00961
00962 pdce->
DCX_flags |= DCX_INUSE;
00963
00964
00965
00966
00967
00968
if (pwndOrg != pdce->
pwndOrg) {
00969
00970
00971
00972
SpbCheckDce(pdce);
00973
00974 pdce->
pwndOrg = pwndOrg;
00975
ResetOrg(
NULL, pdce,
FALSE);
00976 }
00977
00978
goto HaveComputedEntry;
00979 }
00980 }
00981
00982
#if DBG
00983
SearchFailed:
00984
#endif
00985
00986
00987
00988
00989
00990 ppdceNotInUse =
NULL;
00991
for (ppdce = &
gpDispInfo->
pdceFirst; (pdce = *ppdce); ppdce = &pdce->
pdceNext) {
00992
00993
00994
00995
00996
if (!(pdce->
DCX_flags & DCX_CACHE))
00997
continue;
00998
00999
01000
01001
01002
if (pdce->
pMonitor !=
NULL)
01003
continue;
01004
01005
if (pdce->
DCX_flags & DCX_INVALID) {
01006
break;
01007 }
else if (!(pdce->
DCX_flags & DCX_INUSE)) {
01008
01009
01010
01011
01012 ppdceNotInUse = ppdce;
01013 }
01014 }
01015
01016
01017
01018
01019
01020
if (pdce ==
NULL && ((ppdce = ppdceNotInUse) ==
NULL)) {
01021
01022
01023
01024
01025
if (!
CreateCacheDC(pwndOrg,
01026 DCX_INVALID | DCX_CACHE |
01027 (DCX_flags & DCX_LAYERED),
01028
NULL)) {
01029
goto NullExit;
01030 }
01031
01032
goto SearchAgain;
01033 }
01034
01035
01036
01037
01038 pdce = *ppdce;
01039
01040 RecomputeEntry:
01041
01042
01043
01044
01045
01046
if (!(pdce->
DCX_flags & DCX_INVALID))
01047
SpbCheckDce(pdce);
01048
01049
01050
01051
01052
01053
01054 pdce->
DCX_flags = DCX_flagsMatch | DCX_INUSE;
01055
01056
#if DBG
01057
01058
01059
01060
01061
01062 GreValidateVisrgn(pdce->
hdc,
FALSE);
01063
#endif
01064
01065
01066
01067
01068 hrgn =
NULL;
01069
if (
CalcVisRgn(&hrgn, pwndOrg, pwndClip, DCX_flagsMatch) ==
FALSE) {
01070 pdce->
DCX_flags |= DCX_PWNDORGINVISIBLE;
01071 }
01072
01073 pdce->
pwndOrg = pwndOrg;
01074 pdce->
pwndClip = pwndClip;
01075 pdce->
hrgnClip =
NULL;
01076 pdce->
hrgnClipPublic =
NULL;
01077
01078
ResetOrg(hrgn, pdce,
TRUE);
01079
01080
if (hrgn ==
NULL) {
01081 fVisRgnError =
TRUE;
01082 }
01083
01084
01085
01086
01087
01088
01089 HaveComputedEntry:
01090
01091
01092
01093
01094
01095
01096
if ((pdce->
DCX_flags & DCX_MATCHMASK) != (DCX_flags & DCX_MATCHMASK))
01097
goto RecomputeEntry;
01098
01099
01100
01101
01102 UserAssert(pdce);
01103 UserAssert(*ppdce == pdce);
01104 UserAssert(pdce->DCX_flags & DCX_INUSE);
01105 UserAssert(!(pdce->DCX_flags & DCX_INVALID));
01106 UserAssert((pdce->DCX_flags & DCX_MATCHMASK) == (DCX_flags & DCX_MATCHMASK));
01107
01108
01109
01110
01111
if (pdce !=
gpDispInfo->
pdceFirst) {
01112 *ppdce = pdce->pdceNext;
01113 pdce->pdceNext =
gpDispInfo->
pdceFirst;
01114
gpDispInfo->
pdceFirst = pdce;
01115 }
01116
01117
#if DBG
01118
01119
01120
01121
01122
01123 GreValidateVisrgn(pdce->hdc,
FALSE);
01124
#endif
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
if (DCX_flags & DCX_INTERSECTRGN) {
01142
01143
if (hrgnClip !=
HRGN_FULL) {
01144
01145
SetEmptyRgn(
ghrgnGDC);
01146
01147
01148
01149
01150
01151
01152
01153 UserAssertMsg0(!pdce->hrgnSavedVis,
01154
"Nested SaveVisRgn attempt in _GetDCEx");
01155
01156
01157
01158
01159
01160
01161 pdce->hrgnSavedVis =
CreateEmptyRgn();
01162
01163 GreSelectVisRgn(pdce->hdc,pdce->hrgnSavedVis, SVR_SWAP);
01164
01165 pdce->hrgnClip = hrgnClip;
01166
01167
if (DCX_flags & DCX_NODELETERGN)
01168 pdce->DCX_flags |= DCX_NODELETERGN;
01169
01170 pdce->DCX_flags |= DCX_INTERSECTRGN;
01171
01172
if (hrgnClip ==
NULL) {
01173
01174 pdce->hrgnClipPublic =
NULL;
01175
01176 }
else {
01177
01178
IntersectRgn(
ghrgnGDC, pdce->hrgnSavedVis, hrgnClip);
01179
01180
01181
01182
01183
01184 pdce->hrgnClipPublic =
CreateEmptyRgnPublic();
01185
CopyRgn(pdce->hrgnClipPublic, hrgnClip);
01186 }
01187
01188
01189
01190
01191
01192
01193
01194 pdce->DCX_flags &= ~DCX_SAVEDRGNINVALID;
01195
01196
01197
01198
01199
01200
01201 GreSelectVisRgn(pdce->hdc,
ghrgnGDC, SVR_SWAP);
01202 }
01203 }
else if (DCX_flags & DCX_EXCLUDERGN) {
01204
01205
if (hrgnClip !=
NULL) {
01206
01207
SetEmptyRgn(
ghrgnGDC);
01208
01209
01210
01211
01212
01213
01214
01215 UserAssertMsg0(!pdce->hrgnSavedVis,
01216
"Nested SaveVisRgn attempt in _GetDCEx");
01217
01218
01219
01220
01221
01222 pdce->hrgnSavedVis =
CreateEmptyRgn();
01223
01224 GreSelectVisRgn(pdce->hdc,pdce->hrgnSavedVis, SVR_SWAP);
01225
01226 pdce->hrgnClip = hrgnClip;
01227
01228
if (DCX_flags & DCX_NODELETERGN)
01229 pdce->DCX_flags |= DCX_NODELETERGN;
01230
01231 pdce->DCX_flags |= DCX_EXCLUDERGN;
01232
01233
if (hrgnClip ==
HRGN_FULL) {
01234
01235 pdce->hrgnClipPublic =
HRGN_FULL;
01236
01237 }
else {
01238
01239
SubtractRgn(
ghrgnGDC, pdce->hrgnSavedVis, hrgnClip);
01240
01241
01242
01243
01244
01245 pdce->hrgnClipPublic =
CreateEmptyRgnPublic();
01246
CopyRgn(pdce->hrgnClipPublic, hrgnClip);
01247 }
01248
01249
01250
01251
01252
01253
01254
01255 pdce->DCX_flags &= ~DCX_SAVEDRGNINVALID;
01256
01257
01258
01259
01260
01261
01262 GreSelectVisRgn(pdce->hdc,
ghrgnGDC, SVR_SWAP);
01263 }
01264 }
01265 }
01266
01267
if (pdce->
DCX_flags & DCX_LAYERED) {
01268 UserAssert(pwndLayer !=
NULL);
01269 UserAssert(hbmLayer !=
NULL);
01270
01271 UserVerify(GreSelectRedirectionBitmap(pdce->
hdc, hbmLayer));
01272
01273
01274
01275
01276
01277
01278 GreGetBounds(pdce->
hdc,
NULL, GGB_ENABLE_WINMGR);
01279
01280
01281
01282
01283
01284
if (fVisRgnError) {
01285 GreSelectVisRgn(pdce->
hdc,
NULL, SVR_DELETEOLD);
01286 }
01287 }
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
if (pdce->
DCX_flags & DCX_CACHE) {
01298
01299
if (!GreSetDCOwner(pdce->
hdc, OBJECT_OWNER_CURRENT)) {
01300 RIPMSG1(RIP_WARNING,
"GetDCEx: SetDCOwner Failed %lX", pdce->
hdc);
01301 }
01302
01303
01304
01305
01306
01307
DecrementFreeDCECount();
01308
01309 pdce->
ptiOwner =
PtiCurrent();
01310 }
01311
01312
#ifdef USE_MIRRORING
01313
if (
TestWF(pwnd, WEFLAYOUTRTL) && !(DCX_flags & DCX_NOMIRROR)) {
01314 GreSetLayout(pdce->
hdc, -1, LAYOUT_RTL);
01315 }
01316
#endif
01317
01318
#if DBG
01319
GreValidateVisrgn(pdce->
hdc,
TRUE);
01320
#endif
01321
01322 GreUnlockDisplay(
gpDispInfo->
hDev);
01323
01324
return pdce->
hdc;
01325 }
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337 UINT ReleaseCacheDC(
01338 HDC hdc,
01339 BOOL fEndPaint)
01340 {
01341
PDCE pdce;
01342
PDCE *ppdce;
01343
01344
for (ppdce = &
gpDispInfo->
pdceFirst; (pdce = *ppdce); ppdce = &pdce->
pdceNext) {
01345
01346
if (pdce->
hdc == hdc) {
01347
01348
01349
01350
01351
if ((pdce->
DCX_flags & (DCX_DESTROYTHIS | DCX_INVALID | DCX_INUSE)) != DCX_INUSE)
01352
return DCE_NORELEASE;
01353
01354
01355
01356
01357 GreLockDisplay(
gpDispInfo->
hDev);
01358
01359
if (pdce->
DCX_flags & DCX_LAYERED) {
01360
UpdateLayeredSprite(pdce);
01361 }
01362
01363
01364
01365
01366
if (pdce->
DCX_flags & DCX_CACHE) {
01367
01368
01369
01370
01371
01372
if (!(pdce->
DCX_flags & DCX_NORESETATTRS)) {
01373
01374
01375
01376
01377
if ( (!(GreCleanDC(hdc))) ||
01378 (!(GreSetDCOwner(hdc, OBJECT_OWNER_NONE))) ) {
01379
01380 GreUnlockDisplay(
gpDispInfo->
hDev);
01381
return DCE_NORELEASE;
01382 }
01383
01384 }
else if (!GreSetDCOwner(pdce->
hdc, OBJECT_OWNER_NONE)) {
01385
01386 GreUnlockDisplay(
gpDispInfo->
hDev);
01387
return DCE_NORELEASE;
01388 }
01389
01390 pdce->
ptiOwner =
NULL;
01391 pdce->
DCX_flags &= ~DCX_INUSE;
01392
01393
#if DBG
01394
01395
01396
01397
01398
01399
01400 GreValidateVisrgn(pdce->
hdc,
FALSE);
01401
#endif
01402
01403
01404
01405
01406
01407
if (pdce->
DCX_flags & DCX_LAYERED) {
01408 UserVerify(GreSelectRedirectionBitmap(pdce->
hdc,
NULL));
01409 }
01410
01411
01412
01413
01414
01415
01416
IncrementFreeDCECount();
01417
01418
if (
gnDCECount >
DCE_SIZE_CACHETHRESHOLD) {
01419
if (
DestroyCacheDC(ppdce, pdce->
hdc)) {
01420 GreUnlockDisplay(
gpDispInfo->
hDev);
01421
return DCE_FREED;
01422 }
01423 }
01424 }
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
if ((pdce->
DCX_flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN)) &&
01435 ((pdce->
DCX_flags & DCX_CACHE) || fEndPaint)) {
01436
DeleteHrgnClip(pdce);
01437 }
01438
01439 GreUnlockDisplay(
gpDispInfo->
hDev);
01440
return DCE_RELEASED;
01441 }
01442 }
01443
01444
01445
01446
01447 RIPERR1(ERROR_DC_NOT_FOUND, RIP_WARNING,
01448
"Invalid device context (DC) handle passed to ReleaseCacheDC (0x%08lx)", hdc);
01449
01450
return DCE_NORELEASE;
01451 }
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463 HDC
CreateCacheDC(
01464
PWND pwndOrg,
01465 DWORD DCX_flags,
01466
PMONITOR pMonitor
01467 )
01468 {
01469
PDCE pdce;
01470 HDC hdc;
01471 HANDLE hDev;
01472
01473
if ((pdce = (
PDCE)UserAllocPool(
sizeof(
DCE), TAG_DCE)) ==
NULL)
01474
return NULL;
01475
01476
if (pMonitor ==
NULL) {
01477 hDev =
gpDispInfo->
hDev;
01478 }
else {
01479 hDev = pMonitor->
hDev;
01480 }
01481
01482
if ((hdc = GreCreateDisplayDC(hDev, DCTYPE_DIRECT,
FALSE)) ==
NULL) {
01483 UserFreePool(pdce);
01484
return NULL;
01485 }
01486
01487
01488
01489
01490 pdce->
pdceNext =
gpDispInfo->
pdceFirst;
01491
gpDispInfo->
pdceFirst = pdce;
01492
01493 pdce->
hdc = hdc;
01494 pdce->
DCX_flags = DCX_flags;
01495 pdce->
pwndOrg = pwndOrg;
01496 pdce->
pwndClip = pwndOrg;
01497 pdce->
hrgnClip =
NULL;
01498 pdce->
hrgnClipPublic =
NULL;
01499 pdce->
hrgnSavedVis =
NULL;
01500 pdce->
pMonitor = pMonitor;
01501
01502
01503
01504
01505
01506 GreMarkUndeletableDC(hdc);
01507
01508
if (DCX_flags & DCX_OWNDC) {
01509
01510
01511
01512
01513
01514
01515 GreSetDCOwner(hdc, OBJECT_OWNER_CURRENT);
01516 pdce->
ptiOwner =
PtiCurrent();
01517
01518 }
else {
01519
01520
01521
01522
01523
01524
01525 GreSetDCOwner(hdc, OBJECT_OWNER_NONE);
01526 pdce->
ptiOwner =
NULL;
01527
01528
01529
01530
01531
01532
IncrementFreeDCECount();
01533 }
01534
01535
01536
01537
01538
if (!(DCX_flags & DCX_CACHE)) {
01539
01540
01541
01542
01543
if (
TestCF(pwndOrg,
CFCLASSDC))
01544 pwndOrg->
pcls->
pdce = pdce;
01545
01546
01547
01548
01549 UserAssert(!(DCX_flags & DCX_WINDOW));
01550
01551 pdce->
DCX_flags |= DCX_INUSE;
01552
01553
InvalidateDce(pdce);
01554 }
01555
01556
01557
01558
01559
if (
AnySpbs())
01560 GreGetBounds(pdce->
hdc,
NULL, DCB_ENABLE | DCB_SET | DCB_WINDOWMGR);
01561
01562
return pdce->
hdc;
01563 }
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574 PWND WindowFromCacheDC(
01575 HDC hdc)
01576 {
01577
PDCE pdce;
01578
for (pdce =
gpDispInfo->
pdceFirst; pdce; pdce = pdce->
pdceNext) {
01579
01580
if (pdce->
hdc == hdc)
01581
return (pdce->
DCX_flags & DCX_DESTROYTHIS) ?
NULL : pdce->
pwndOrg;
01582 }
01583
01584
return NULL;
01585 }
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596 VOID DelayedDestroyCacheDC(VOID)
01597 {
01598
PDCE *ppdce;
01599
PDCE pdce;
01600
01601
01602
01603
01604
01605
for (ppdce = &
gpDispInfo->
pdceFirst; *ppdce !=
NULL; ) {
01606
01607
01608
01609
01610
01611 pdce = *ppdce;
01612
01613
if (pdce->
DCX_flags & DCX_DESTROYTHIS)
01614
DestroyCacheDC(ppdce, pdce->
hdc);
01615
01616
01617
01618
01619
01620
if (pdce == *ppdce)
01621 ppdce = &pdce->
pdceNext;
01622 }
01623
01624
PpiCurrent()->W32PF_Flags &= ~W32PF_OWNDCCLEANUP;
01625 }
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638 BOOL DestroyCacheDC(
01639
PDCE *ppdce,
01640 HDC hdc)
01641 {
01642
PDCE pdce;
01643
01644
01645
01646
01647
if (ppdce ==
NULL) {
01648
for (ppdce = &
gpDispInfo->
pdceFirst; (pdce = *ppdce); ppdce = &pdce->
pdceNext) {
01649
if (pdce->
hdc == hdc)
01650
break;
01651 }
01652 }
01653
01654
if (ppdce ==
NULL)
01655
return FALSE;
01656
01657
01658
01659
01660 pdce = *ppdce;
01661 pdce->
DCX_flags |= DCX_DESTROYTHIS;
01662
01663
01664
01665
01666
01667
if (!(pdce->
DCX_flags & DCX_NODELETERGN)) {
01668
DeleteMaybeSpecialRgn(pdce->
hrgnClip);
01669 pdce->
hrgnClip =
NULL;
01670 }
01671
01672
if (pdce->
hrgnClipPublic !=
NULL) {
01673 GreDeleteObject(pdce->
hrgnClipPublic);
01674 pdce->
hrgnClipPublic =
NULL;
01675 }
01676
01677
if (pdce->
hrgnSavedVis !=
NULL) {
01678 GreDeleteObject(pdce->
hrgnSavedVis);
01679 pdce->
hrgnSavedVis =
NULL;
01680 }
01681
01682
01683
01684
01685
01686
01687
01688
if (!GreSetDCOwner(hdc, OBJECT_OWNER_PUBLIC)) {
01689
PpiCurrent()->W32PF_Flags |= W32PF_OWNDCCLEANUP;
01690
return FALSE;
01691 }
01692
01693
01694
01695
01696
01697
#if DBG
01698
pdce->
DCX_flags |= DCX_DONTRIPONDESTROY;
01699 GreMarkDeletableDC(hdc);
01700
#endif
01701
01702
if (!GreDeleteDC(hdc)) {
01703
01704
#if DBG
01705
GreMarkUndeletableDC(hdc);
01706 pdce->
DCX_flags &= ~DCX_DONTRIPONDESTROY;
01707
#endif
01708
PpiCurrent()->W32PF_Flags |= W32PF_OWNDCCLEANUP;
01709
return FALSE;
01710 }
01711
01712
01713
01714
01715
if (pdce->
DCX_flags & DCX_CACHE) {
01716
01717
if (!(pdce->
DCX_flags & DCX_INUSE)) {
01718
DecrementFreeDCECount();
01719 }
01720 }
01721
01722
#if DBG
01723
pdce->
pwndOrg =
NULL;
01724 pdce->
pwndClip =
NULL;
01725
#endif
01726
01727
01728
01729
01730 *ppdce = pdce->
pdceNext;
01731
01732 UserFreePool(pdce);
01733
01734
return TRUE;
01735 }
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746 VOID InvalidateGDIWindows(
01747
PWND pwnd)
01748 {
01749 PVOID pwo;
01750
01751
if (pwnd !=
NULL) {
01752
01753
if ((pwo =
_GetProp(pwnd,
PROP_WNDOBJ,
TRUE)) !=
NULL) {
01754
01755 HRGN hrgnClient =
NULL;
01756
01757
if (GreWindowInsteadOfClient(pwo)) {
01758
01759
01760
01761
01762
01763
01764
CalcVisRgn(&hrgnClient,
01765 pwnd,
01766 pwnd,
01767 DCX_WINDOW |
01768 (
TestWF(pwnd,
WFCLIPSIBLINGS) ? DCX_CLIPSIBLINGS : 0));
01769 }
else {
01770
CalcVisRgn(&hrgnClient,
01771 pwnd,
01772 pwnd,
01773 DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS);
01774 }
01775
01776 GreSetClientRgn(pwo, hrgnClient, &(pwnd->
rcClient));
01777 }
01778
01779 pwnd = pwnd->
spwndChild;
01780
while (pwnd !=
NULL) {
01781
InvalidateGDIWindows(pwnd);
01782 pwnd = pwnd->
spwndNext;
01783 }
01784 }
01785 }
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812 BOOL zzzInvalidateDCCache(
01813
PWND pwndInvalid,
01814 DWORD flags)
01815 {
01816
PWND pwnd;
01817
PDCE pdce;
01818
PTHREADINFO ptiCurrent =
PtiCurrent();
01819
TL tlpwndInvalid;
01820 FLONG fl;
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
ThreadLockAlwaysWithPti(ptiCurrent, pwndInvalid, &tlpwndInvalid);
01835
01836
if (!(ptiCurrent->
TIF_flags &
TIF_MOVESIZETRACKING) &&
01837 !(flags &
IDC_NOMOUSE)) {
01838
01839
#ifdef REDIRECTION
01840
if (!
IsGlobalHooked(ptiCurrent,
WHF_FROM_WH(WH_HITTEST)))
01841
#endif // REDIRECTION
01842
01843
zzzSetFMouseMoved();
01844 }
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
if (flags &
IDC_DEFAULT) {
01859
01860 flags = 0;
01861
01862
if ((pwndInvalid->
spwndParent !=
NULL) &&
01863 (pwndInvalid !=
PWNDDESKTOP(pwndInvalid))) {
01864
01865
01866
01867
01868
01869
01870
01871
01872
if (
TestWF(pwndInvalid->
spwndParent,
WFCLIPCHILDREN)) {
01873
01874 flags =
IDC_CLIENTONLY;
01875 pwndInvalid = pwndInvalid->
spwndParent;
01876
01877 }
else if (
TestWF(pwndInvalid,
WFCLIPSIBLINGS)) {
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891 flags =
IDC_CHILDRENONLY;
01892 pwndInvalid = pwndInvalid->
spwndParent;
01893 }
01894 }
01895 }
01896
01897
01898
01899
01900
01901
01902
01903
for (pdce =
gpDispInfo->
pdceFirst; pdce; pdce = pdce->
pdceNext) {
01904
01905
if (pdce->
DCX_flags & (DCX_INVALID | DCX_DESTROYTHIS))
01906
continue;
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
if (!(pdce->
DCX_flags & (DCX_CACHE | DCX_WINDOW))) {
01917
01918
if (
TestWF(pdce->
pwndOrg,
WFCLIPCHILDREN))
01919 pdce->
DCX_flags |= DCX_CLIPCHILDREN;
01920
01921
if (
TestWF(pdce->
pwndOrg,
WFMINIMIZED))
01922 pdce->
DCX_flags &= ~DCX_CLIPCHILDREN;
01923 }
01924
01925
01926
01927
01928
01929
01930
01931 UserAssert((pdce->
pwndClip == pdce->
pwndOrg) ||
01932 (pdce->
pwndClip == pdce->
pwndOrg->
spwndParent));
01933
01934
01935
01936
01937
01938
for (pwnd = pdce->
pwndOrg; pwnd; pwnd = pwnd->
spwndParent) {
01939
01940
if (pwnd == pwndInvalid) {
01941
01942
if (pwndInvalid == pdce->
pwndOrg) {
01943
01944
01945
01946
01947
if (flags &
IDC_CHILDRENONLY)
01948
break;
01949
01950
01951
01952
01953
if ((flags &
IDC_CLIENTONLY) && (pdce->
DCX_flags & DCX_WINDOW))
01954
break;
01955 }
01956
01957
InvalidateDce(pdce);
01958
break;
01959 }
01960 }
01961 }
01962
01963
01964
01965
01966 GreLockDisplay(
gpDispInfo->
hDev);
01967
01968 fl = (flags &
IDC_MOVEBLT) ? GCR_DELAYFINALUPDATE : 0;
01969
01970
if (
gcountPWO != 0) {
01971
InvalidateGDIWindows(pwndInvalid);
01972 fl |= GCR_WNDOBJEXISTS;
01973 }
01974
01975 GreClientRgnUpdated(fl);
01976
01977 GreUpdateSpriteVisRgn(
gpDispInfo->
hDev);
01978
01979 GreUnlockDisplay(
gpDispInfo->
hDev);
01980
01981
ThreadUnlock(&tlpwndInvalid);
01982
01983
return TRUE;
01984 }
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995 PWND _WindowFromDC(
01996 HDC hdc)
01997 {
01998
PDCE pdce;
01999
02000
for (pdce =
gpDispInfo->
pdceFirst; pdce; pdce = pdce->
pdceNext) {
02001
02002
if (!(pdce->
DCX_flags & DCX_INUSE) || (pdce->
DCX_flags & DCX_CREATEDC))
02003
continue;
02004
02005
if (pdce->
hdc == hdc)
02006
return pdce->
pwndOrg;
02007 }
02008
02009
return NULL;
02010 }
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022 PWND FastWindowFromDC(
02023 HDC hdc)
02024 {
02025
PDCE *ppdce;
02026
PDCE pdceT;
02027
02028
if ((
gpDispInfo->
pdceFirst->
hdc == hdc) &&
02029 (
gpDispInfo->
pdceFirst->
DCX_flags & DCX_INUSE)) {
02030
02031
return gpDispInfo->
pdceFirst->
pwndOrg;
02032 }
02033
02034
for (ppdce = &
gpDispInfo->
pdceFirst; *ppdce; ppdce = &(*ppdce)->
pdceNext) {
02035
02036
if (((*ppdce)->hdc == hdc) && ((*ppdce)->DCX_flags & DCX_INUSE)) {
02037
02038
02039
02040
02041 pdceT = *ppdce;
02042 *ppdce = pdceT->
pdceNext;
02043 pdceT->
pdceNext =
gpDispInfo->
pdceFirst;
02044
gpDispInfo->
pdceFirst = pdceT;
02045
02046
return pdceT->
pwndOrg;
02047 }
02048 }
02049
02050
return NULL;
02051 }
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066 BOOL GetDCOrgOnScreen(HDC hdc, LPPOINT ppt)
02067 {
02068
if (GreGetDCOrg(hdc, ppt)) {
02069 POINT ptScreen;
02070
02071
02072
02073
02074
if (
UserGetRedirectedWindowOrigin(hdc, &ptScreen)) {
02075 ppt->x += ptScreen.x;
02076 ppt->y += ptScreen.y;
02077
return TRUE;
02078 }
02079 }
02080
return FALSE;
02081 }
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096 BOOL UserGetRedirectedWindowOrigin(HDC hdc, LPPOINT ppt)
02097 {
02098
PWND pwnd;
02099
PDCE pdce;
02100
02101
if ((pdce =
LookupDC(hdc)) ==
NULL)
02102
return FALSE;
02103
02104
if (!(pdce->
DCX_flags & DCX_LAYERED))
02105
return FALSE;
02106
02107 pwnd =
GetLayeredWindow(pdce->
pwndOrg);
02108
02109 ppt->x = pwnd->
rcWindow.left;
02110 ppt->y = pwnd->
rcWindow.top;
02111
02112
return TRUE;
02113 }
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123 PDCE LookupDC(HDC hdc)
02124 {
02125
PDCE pdce;
02126
02127
for (pdce =
gpDispInfo->
pdceFirst; pdce !=
NULL; pdce = pdce->
pdceNext) {
02128
02129
if (pdce->
DCX_flags & (DCX_INVALID | DCX_DESTROYTHIS))
02130
continue;
02131
02132
if (pdce->
hdc == hdc && pdce->
pMonitor ==
NULL &&
02133 (pdce->
DCX_flags & DCX_INUSE)) {
02134
return pdce;
02135 }
02136 }
02137
return NULL;
02138 }
02139
02140
02141
02142
02143
02144
02145
02146 #define DCX_LEAVEBITS (DCX_WINDOW | DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS | \
02147
DCX_PARENTCLIP | DCX_LOCKWINDOWUPDATE | DCX_NOCLIPCHILDREN | \
02148
DCX_USESTYLE | DCX_EXCLUDEUPDATE | DCX_INTERSECTUPDATE | \
02149
DCX_EXCLUDERGN | DCX_INTERSECTRGN)
02150
02151 HDC
GetMonitorDC(
PDCE pdceOrig,
PMONITOR pMonitor)
02152 {
02153
PDCE pdce;
02154 POINT pt;
02155 RECT rc;
02156
02157 TryAgain:
02158
for (pdce =
gpDispInfo->
pdceFirst; pdce !=
NULL; pdce = pdce->
pdceNext) {
02159
02160
02161
02162
if (pdce->
DCX_flags & (DCX_INUSE | DCX_DESTROYTHIS))
02163
continue;
02164
02165
if (pdce->
pMonitor != pMonitor)
02166
continue;
02167
02168
if (!(pdce->
DCX_flags & DCX_INVALID))
02169
SpbCheckDce(pdce);
02170
02171
02172
02173
02174 GreSetDCOwner(pdce->
hdc, OBJECT_OWNER_CURRENT);
02175 pdce->
pwndOrg = pdceOrig->
pwndOrg;
02176 pdce->
pwndClip = pdceOrig->
pwndClip;
02177 pdce->
ptiOwner = pdceOrig->
ptiOwner;
02178 pdce->
DCX_flags = (DCX_INUSE | DCX_CACHE) |
02179 (pdceOrig->
DCX_flags &
DCX_LEAVEBITS);
02180
02181
if (pdceOrig->
hrgnClip >
HRGN_FULL) {
02182 UserAssert(pdce->
hrgnClip ==
NULL);
02183 UserAssert(pdceOrig->
DCX_flags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN));
02184
02185 pdce->
hrgnClip =
CreateEmptyRgn();
02186
SetMonitorRegion(pMonitor, pdce->
hrgnClip, pdceOrig->
hrgnClip);
02187 }
else {
02188 pdce->
hrgnClip = pdceOrig->
hrgnClip;
02189 }
02190
02191
02192
02193
02194 GreCopyVisRgn(pdceOrig->
hdc,
ghrgnGDC);
02195
SetMonitorRegion(pMonitor,
ghrgnGDC,
ghrgnGDC);
02196 GreSelectVisRgn(pdce->
hdc,
ghrgnGDC, SVR_COPYNEW);
02197
02198 GreGetDCOrgEx(pdceOrig->
hdc, &pt, &rc);
02199
OffsetRect(&rc, -pMonitor->
rcMonitor.left, -pMonitor->
rcMonitor.top);
02200 GreSetDCOrg(pdce->
hdc, rc.left, rc.top, (PRECTL)&rc);
02201
02202
02203
02204
02205
02206
DecrementFreeDCECount();
02207
02208
return pdce->
hdc;
02209 }
02210
02211
02212
02213
02214
02215
if (
CreateCacheDC(
NULL, DCX_INVALID | DCX_CACHE, pMonitor) ==
NULL)
02216
return NULL;
02217
02218
goto TryAgain;
02219 }
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
#if DBG
02231
VOID RipIfCacheDC(
02232 HDC hdc)
02233 {
02234
PDCE pdce;
02235
02236
02237
02238
02239
02240
EnterCrit();
02241
02242
for (pdce =
gpDispInfo->
pdceFirst; pdce; pdce = pdce->
pdceNext) {
02243
02244
if (pdce->
hdc == hdc && !(pdce->
DCX_flags & DCX_DONTRIPONDESTROY)) {
02245
02246 RIPMSG1(RIP_ERROR,
02247
"Deleting DC in DC cache - contact JohnC. hdc == %08lx\n",
02248 pdce->
hdc);
02249 }
02250 }
02251
02252
LeaveCrit();
02253 }
02254
#endif
02255
02256
#ifdef USE_MIRRORING
02257
02258
02259
02260
02261
02262
02263
02264
02265
void MirrorRect(
PWND pwnd, LPRECT lprc)
02266 {
02267
int left, cx;
02268
02269 cx = pwnd->
rcClient.right - pwnd->
rcClient.left;
02270 left = lprc->left;
02271 lprc->left = cx - lprc->right;
02272 lprc->right = cx - left;
02273 }
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
void OrderRects(LPRECT lpR,
int nRects)
02285 {
02286 RECT R;
02287
int i,j;
02288
02289
02290
02291
02292
for (i=0; i<nRects; i++){
02293
for (j=i+1; (j<nRects) && ((lpR+j)->top == (lpR+i)->top); j++){
02294
if (((lpR+j)->left < (lpR+i)->left)) {
02295 R = *(lpR+i);
02296 *(lpR+i) = *(lpR+j);
02297 *(lpR+j) = R;
02298 }
02299 }
02300 }
02301
02302 }
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
BOOL MirrorRegion(
PWND pwnd, HRGN hrgn, BOOL bUseClient)
02314 {
02315
int nRects, i, nDataSize, Saveleft, cx;
02316 HRGN hrgn2 =
NULL;
02317 RECT *lpR;
02318 RGNDATA *lpRgnData;
02319
BOOL bRet =
FALSE;
02320
02321
if (
TestWF(pwnd, WEFLAYOUTRTL) && hrgn >
HRGN_SPECIAL_LAST) {
02322 nDataSize = GreGetRegionData(hrgn, 0, NULL);
02323
if (nDataSize && (lpRgnData = (RGNDATA *)UserAllocPool(nDataSize, TAG_MIRROR))) {
02324
if (GreGetRegionData(hrgn, nDataSize, lpRgnData)) {
02325 nRects = lpRgnData->rdh.nCount;
02326 lpR = (RECT *)lpRgnData->Buffer;
02327
02328
if (bUseClient) {
02329 cx = pwnd->
rcClient.right - pwnd->
rcClient.left;
02330 }
else {
02331 cx = pwnd->
rcWindow.right - pwnd->
rcWindow.left;
02332 }
02333
02334 Saveleft = lpRgnData->rdh.rcBound.left;
02335 lpRgnData->rdh.rcBound.left = cx - lpRgnData->rdh.rcBound.right;
02336 lpRgnData->rdh.rcBound.right = cx - Saveleft;
02337
02338
02339
for (i=0; i<nRects; i++){
02340 Saveleft = lpR->left;
02341 lpR->left = cx - lpR->right;
02342 lpR->right = cx - Saveleft;
02343
02344 lpR++;
02345 }
02346
02347 OrderRects((RECT *)lpRgnData->Buffer, nRects);
02348 hrgn2 = GreExtCreateRegion(NULL, nDataSize, lpRgnData);
02349
if (hrgn2) {
02350 GreCombineRgn(hrgn, hrgn2, NULL, RGN_COPY);
02351 GreDeleteObject((HGDIOBJ)hrgn2);
02352 bRet =
TRUE;
02353 }
02354 }
02355
02356
02357 UserFreePool(lpRgnData);
02358 }
02359 }
02360
02361
return bRet;
02362 }
02363
02364
#endif