test: dc.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# dc.c File Reference

`#include "precomp.h"`

Go to the source code of this file.

## Defines

#define | DCX_LEAVEBITS

## Functions

__inline VOID | DecrementFreeDCECount (VOID)
__inline VOID | IncrementFreeDCECount (VOID)
void | SetMonitorRegion (PMONITOR pMonitor, HRGN hrgnDst, HRGN hrgnSrc)
VOID | ResetOrg (HRGN hrgn, PDCE pdce, BOOL fSetVisRgn)
HDC | _GetDC (PWND pwnd)
BOOL | _ReleaseDC (HDC hdc)
HDC | _GetWindowDC (PWND pwnd)
VOID | UserSetDCVisRgn (PDCE pdce)
HRGN | UserGetClientRgn (HWND hwnd, LPRECT lprc, BOOL bWindowInsteadOfClient)
BOOL | UserGetHwnd (HDC hdc, HWND *phwnd, PVOID *ppwo, BOOL bCheckStyle)
VOID | UserAssociateHwnd (HWND hwnd, PVOID pwo)
BOOL | UserReleaseDC (HDC hdc)
VOID | InvalidateDce (PDCE pdce)
VOID | DeleteHrgnClip (PDCE pdce)
HDC | _GetDCEx (PWND pwnd, HRGN hrgnClip, DWORD DCX_flags)
UINT | ReleaseCacheDC (HDC hdc, BOOL fEndPaint)
HDC | CreateCacheDC (PWND pwndOrg, DWORD DCX_flags, PMONITOR pMonitor)
PWND | WindowFromCacheDC (HDC hdc)
VOID | DelayedDestroyCacheDC (VOID)
BOOL | DestroyCacheDC (PDCE *ppdce, HDC hdc)
VOID | InvalidateGDIWindows (PWND pwnd)
BOOL | zzzInvalidateDCCache (PWND pwndInvalid, DWORD flags)
PWND | _WindowFromDC (HDC hdc)
PWND | FastWindowFromDC (HDC hdc)
BOOL | GetDCOrgOnScreen (HDC hdc, LPPOINT ppt)
BOOL | UserGetRedirectedWindowOrigin (HDC hdc, LPPOINT ppt)
PDCE | LookupDC (HDC hdc)
HDC | GetMonitorDC (PDCE pdceOrig, PMONITOR pMonitor)

## Define Documentation

#define DCX_LEAVEBITS

Value:

    (DCX_WINDOW | DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS | \
            DCX_PARENTCLIP | DCX_LOCKWINDOWUPDATE | DCX_NOCLIPCHILDREN | \
            DCX_USESTYLE | DCX_EXCLUDEUPDATE | DCX_INTERSECTUPDATE | \
            DCX_EXCLUDERGN | DCX_INTERSECTRGN)

Definition at line 2146 of file dc.c.

Referenced by GetMonitorDC().

## Function Documentation

HDC _GetDC | ( | PWND | pwnd | ) |

Definition at line 148 of file dc.c.

References _GetDCEx(), NULL, tagDESKTOP::pDeskInfo, PtiCurrent, and tagDESKTOPINFO::spwnd.

Referenced by NtUserGetDC(), UT_InvertCaret(), xxxDesktopWndProc(), xxxMNInvertItem(), and xxxRealizeDesktop().

    00150 {
    00151     /*
    00152      * Special case for NULL: For backward compatibility we want to return
    00153      * a window DC for the desktop that does not exclude its children.
    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          * The thread has no desktop.  Fail the call.
    00167          */
    00168         return NULL;
    00169     }
    00170
    00171     return _GetDCEx(pwnd, NULL, DCX_USESTYLE);
    00172 }

HDC _GetDCEx | ( | PWND | pwnd,
|  | HRGN | hrgnClip,
|  | DWORD | DCX_flags
| ) |

Definition at line 608 of file dc.c.

References _GetProp(), BOOL, CalcVisRgn(), CFCLASSDC, CFOWNDC, CFPARENTDC, CopyRgn, CreateCacheDC(), CreateEmptyRgn(), CreateEmptyRgnPublic(), tagDCE::DCX_flags, DecrementFreeDCECount(), DelayedDestroyCacheDC(), DeleteHrgnClip(), DWORD, FALSE, GetLayeredWindow(), GETPTI, ghrgnGDC, gpDispInfo, tagDCE::hdc, tagDISPLAYINFO::hDev, HRGN_FULL, HRGN_SPECIAL_LAST, tagDCE::hrgnClip, tagDCE::hrgnClipPublic, IntersectRgn, IsVisible(), NULL, tagWND::pcls, tagCLS::pdce, tagDISPLAYINFO::pdceFirst, tagDCE::pdceNext, tagDCE::pMonitor, PpiCurrent, PROP_LAYER, PtiCurrent, tagDCE::ptiOwner, tagDCE::pwndClip, tagDCE::pwndOrg, tagWND::rcWindow, ResetOrg(), SetEmptyRgn(), SpbCheckDce(), tagWND::spwndParent, SubtractRgn, TestCF, TestWF, TRUE, UpdateLayeredSprite(), WFCLIPCHILDREN, WFCLIPSIBLINGS, WFMINIMIZED, WFVISIBLE, and WFWIN31COMPAT.

Referenced by _GetDC(), _GetWindowDC(), _UserSoundSentryWorker(), DrawSwitchWndHilite(), GetTooltipDC(), MNDrawArrow(), MNDrawFullNC(), NtUserGetDCEx(), StopFade(), UserGetDesktopDC(), xxxBeginPaint(), xxxDefWindowProc(), xxxDrawAnimatedRects(), xxxDrawDragRect(), xxxDrawMenuBarUnderlines(), xxxDWP_DoNCActivate(), xxxHotTrackMenu(), xxxMenuWindowProc(), xxxMNCompute(), xxxMoveSwitchWndHilite(), xxxPaintIconsInSwitchWindow(), xxxPaintSwitchWindow(), xxxRedrawHungWindow(), xxxRedrawHungWindowFrame(), xxxScrollWindowEx(), xxxSendEraseBkgnd(), and xxxTrackCaptionButton().

    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      * Lock the device while we're playing with visrgns.
    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      * If necessary, compute DCX flags from window style.
    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              * If the DCX_CACHE flag is present, override OWNDC/CLASSDC.
    00657              * Otherwise, calculate from appropriate style bits.
    00658              */
    00659             if (!(DCX_flags & DCX_CACHE) && !TestCF(pwndOrg, CFOWNDC)) {
    00660                 if (TestCF(pwndOrg, CFCLASSDC)) {
    00661                     /*
    00662                      * Look for a non-cache entry that matches hdc...
    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              * Minimized windows never exclude their children.
    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              * Window DCs never exclude children.
    00696              */
    00697         }
    00698     }
    00699
    00700     /*
    00701      * Deal with all the Win 3.0-compatible clipping rules:
    00702      *
    00703      * DCX_NOCLIPCHILDREN overrides:
    00704      *      DCX_PARENTCLIP/CS_OWNDC/CS_CLASSDC
    00705      * DCX_PARENTCLIP overrides:
    00706      *      DCX_CLIPSIBLINGS/DCX_CLIPCHILDREN/CS_OWNDC/CS_CLASSDC
    00707      */
    00708     if (DCX_flags & DCX_NOCLIPCHILDREN) {
    00709         DCX_flags &= ~(DCX_PARENTCLIP | DCX_CLIPCHILDREN);
    00710         DCX_flags |= DCX_CACHE;
    00711     }
    00712
    00713     /*
    00714      * Deal with layered windows.
    00715      */
    00716     if ((pwndLayer = GetLayeredWindow(pwndOrg)) != NULL &&
    00717             (hbmLayer = _GetProp(pwndLayer, PROP_LAYER, TRUE)) != NULL) {
    00718
    00719         /*
    00720          * Get a layered redirection DC.
    00721          */
    00722         DCX_flags |= DCX_LAYERED;
    00723
    00724         /*
    00725          * When the window we're getting the DC for is the layered and
    00726          * redirected window, don't allow to clip to its parent, since
    00727          * clipping must not exceed the size of the backing bitmap.
    00728          */
    00729         if (pwndOrg == pwndLayer) {
    00730             DCX_flags &= ~DCX_PARENTCLIP;
    00731         }
    00732
    00733         /*
    00734          * Convert hrgnClip from screen to the redirection DC coordinates.
    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          * If this window has no parent.  This can occur if the app is
    00751          * calling GetDC in response to a CBT_CREATEWND callback.  In this
    00752          * case, the parent is not yet setup.
    00753          */
    00754         if (pwndOrg->spwndParent == NULL)
    00755             pwndParent = PtiCurrent()->rpdesk->pDeskInfo->spwnd;
    00756         else
    00757             pwndParent = pwndOrg->spwndParent;
    00758
    00759         /*
    00760          * Always get the DC from the cache.
    00761          */
    00762         DCX_flags |= DCX_CACHE;
    00763
    00764         /*
    00765          * We can't use a shared DC if the visibility of the
    00766          * child does not match the parent's, or if a
    00767          * CLIPSIBLINGS or CLIPCHILDREN DC is requested.
    00768          *
    00769          * In 3.1, we pay attention to the CLIPSIBLINGS and CLIPCHILDREN
    00770          * bits of CS_PARENTDC windows, by overriding CS_PARENTDC if
    00771          * either of these flags are requested.
    00772          *
    00773          * BACKWARD COMPATIBILITY HACK
    00774          *
    00775          * If parent is CLIPCHILDREN, get a cache DC, but don't
    00776          * use parent's DC.  Windows PowerPoint depends on this
    00777          * behavior in order to draw the little gray rect between
    00778          * its scroll bars correctly.
    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              * Make sure flags reflect hwndClip rather than hwndOrg.
    00794              * But, we must never clip the children (since that's who
    00795              * wants to do the drawing!)
    00796              */
    00797             DCX_flags &= ~(DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS);
    00798             if (TestWF(pwndClip, WFCLIPSIBLINGS))
    00799                 DCX_flags |= DCX_CLIPSIBLINGS;
    00800         }
    00801     }
    00802
    00803     /*
    00804      * Make sure we don't return an OWNDC if the calling thread didn't
    00805      * create this window - need to returned cached always in this case.
    00806      *
    00807      * Win95 does not contain this code.  Why?
    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          * Handle CS_OWNDC and CS_CLASSDC cases specially.  Based on the
    00820          * supplied match information, we need to find the appropriate DCE.
    00821          */
    00822         for (ppdce = &gpDispInfo->pdceFirst; (pdce = *ppdce); ppdce = &pdce->pdceNext) {
    00823
    00824             if (pdce->DCX_flags & DCX_CACHE)
    00825                 continue;
    00826
    00827             /*
    00828              * Look for the entry that matches hdcMatch or pwndOrg...
    00829              */
    00830             if (!(pdce->pwndOrg == pwndOrg || pdce->hdc == hdcMatch))
    00831                 continue;
    00832
    00833             /*
    00834              * NOTE: The "Multiple-BeginPaint()-of-OWNDC-Window" Conundrum
    00835              *
    00836              * There is a situation having to do with OWNDC or CLASSDC window
    00837              * DCs that can theoretically arise that is handled specially
    00838              * here and in ReleaseCacheDC().  These DCs are identified with
    00839              * the DCX_CACHE bit CLEAR.
    00840              *
    00841              * In the case where BeginPaint() (or a similar operation) is
    00842              * called more than once without an intervening EndPaint(), the
    00843              * DCX_INTERSECTRGN (or DCX_EXCLUDERGN) bit may already be set
    00844              * when we get here.
    00845              *
    00846              * Theoretically, the correct thing to do is to save the current
    00847              * hrgnClip, and set up the new one here.  In ReleaseCacheDC, the
    00848              * saved hrgnClip is restored and the visrgn recomputed.
    00849              *
    00850              * All of this is only necessary if BOTH calls involve an
    00851              * hrgnClip that causes the visrgn to be changed (i.e., the
    00852              * simple hrgnClip test clears the INTERSECTRGN or EXCLUDERGN bit
    00853              * fails), which is not at all likely.
    00854              *
    00855              * When this code encounters this multiple-BeginPaint case it
    00856              * punts by honoring the new EXCLUDE/INTERSECTRGN bits, but it
    00857              * first restores the DC to a wide-open visrgn before doing so.
    00858              * This means that the first EndPaint() will restore the visrgn
    00859              * to a wide-open DC, rather than clipped to the first
    00860              * BeginPaint()'s update rgn.  This is a good punt, because worst
    00861              * case an app does a bit more drawing than it should.
    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                  * We're giving out the same DC again. Since it may not have
    00873                  * been released, transfer any accumulated bits if needed.
    00874                  */
    00875                 UpdateLayeredSprite(pdce);
    00876
    00877                 /*
    00878                  * As this point, the DC may get converted back to a screen
    00879                  * DC, so we must select the screen surface back into the DC.
    00880                  */
    00881                 UserVerify(GreSelectRedirectionBitmap(pdce->hdc, NULL));
    00882             }
    00883
    00884             /*
    00885              * If we matched exactly, no recomputation necessary
    00886              * (we found a CS_OWNDC or a CS_CLASSDC that is already set up)
    00887              * Otherwise, we have a CS_CLASSDC that needs recomputation.
    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          * Make a quick pass through the cache, looking for an
    00911          * exact match.
    00912          */
    00913 SearchAgain:
    00914
    00915 #if DBG
    00916         if (fDisableCache)
    00917             goto SearchFailed;
    00918 #endif
    00919
    00920         /*
    00921          * CONSIDER (adams): Put this check into the loop above so we don't
    00922          * touch all these pages twice?
    00923          */
    00924         for (ppdce = &gpDispInfo->pdceFirst; (pdce = *ppdce); ppdce = &pdce->pdceNext) {
    00925
    00926             /*
    00927              * If we find an entry that is not in use and whose clip flags
    00928              * and clip window match, we can use it.
    00929              *
    00930              * NOTE: DCX_INTERSECT/EXCLUDERGN cache entries always have
    00931              * DCX_INUSE set, so we'll never erroneously match one here.
    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                  * Special case for icon - bug 9103 (win31)
    00942                  */
    00943                 if (TestWF(pwndClip, WFMINIMIZED) &&
    00944                     (pdce->pwndOrg != pdce->pwndClip)) {
    00945                     continue;
    00946                 }
    00947
    00948                 /*
    00949                  * If the pwndOrg of the DC we found is not visible and
    00950                  * the pwndOrg we're looking for is visble, then
    00951                  * the visrgn is no good, we can't reuse it so keep
    00952                  * looking.
    00953                  */
    00954                 if (bpwndOrgVisible && pdce->DCX_flags & DCX_PWNDORGINVISIBLE) {
    00955                     continue;
    00956                 }
    00957
    00958                 /*
    00959                  * Set INUSE before performing any GDI operations, just
    00960                  * in case DCHook() has a mind to recalculate the visrgn...
    00961                  */
    00962                 pdce->DCX_flags |= DCX_INUSE;
    00963
    00964                 /*
    00965                  * We found an entry with the proper visrgn.
    00966                  * If the origin doesn't match, update the CE and reset it.
    00967                  */
    00968                 if (pwndOrg != pdce->pwndOrg) {
    00969                     /*
    00970                      * Need to flush any dirty rectangle stuff now.
    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          * Couldn't find an exact match.  Find some invalid or non-inuse
    00988          * entry we can reuse.
    00989          */
    00990         ppdceNotInUse = NULL;
    00991         for (ppdce = &gpDispInfo->pdceFirst; (pdce = *ppdce); ppdce = &pdce->pdceNext) {
    00992
    00993             /*
    00994              * Skip non-cache entries
    00995              */
    00996             if (!(pdce->DCX_flags & DCX_CACHE))
    00997                 continue;
    00998
    00999             /*
    01000              * Skip monitor-specific entires
    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                  * Remember the non-inuse one, but keep looking for an invalid.
    01011                  */
    01012                 ppdceNotInUse = ppdce;
    01013             }
    01014         }
    01015
    01016         /*
    01017          * If we broke out of the loop, we found an invalid entry to reuse.
    01018          * Otherwise see if we found a non-inuse entry to reuse.
    01019          */
    01020         if (pdce == NULL && ((ppdce = ppdceNotInUse) == NULL)) {
    01021
    01022             /*
    01023              * Create another DCE if we need it.
    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          * We've chosen an entry to reuse: now fill it in and recompute it.
    01037          */
    01038         pdce = *ppdce;
    01039
    01040 RecomputeEntry:
    01041
    01042         /*
    01043          * Any non-invalid entries that we reuse might still have some bounds
    01044          * that need to be used to invalidate SPBs.  Apply them here.
    01045          */
    01046         if (!(pdce->DCX_flags & DCX_INVALID))
    01047             SpbCheckDce(pdce);
    01048
    01049         /*
    01050          * We want to compute only the matchable visrgn at first,
    01051          * so we don't set up hrgnClip, or set the EXCLUDERGN or INTERSECTRGN
    01052          * bits yet -- we'll deal with those later.
    01053          */
    01054         pdce->DCX_flags = DCX_flagsMatch | DCX_INUSE;
    01055
    01056 #if DBG
    01057         /*
    01058          * We're about to select the visrgn into the DC, even though it's
    01059          * not yet completely setup. Turn off the visrgn validation for now.
    01060          * It will be turned on before this function returns.
    01061          */
    01062         GreValidateVisrgn(pdce->hdc, FALSE);
    01063 #endif
    01064
    01065         /*
    01066          * Now recompute the visrgn (minus any hrgnClip shenanigans)
    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;      // Just in case...
    01076         pdce->hrgnClipPublic = NULL;
    01077
    01078         ResetOrg(hrgn, pdce, TRUE);
    01079
    01080         if (hrgn == NULL) {
    01081             fVisRgnError = TRUE;
    01082         }
    01083
    01084         /*
    01085          * When we arrive here, pdce (and *ppdce) point to
    01086          * a cache entry whose visrgn and origin are set up.
    01087          * All that remains to be done is to deal with EXCLUDE/INTERSECTRGN
    01088          */
    01089 HaveComputedEntry:
    01090
    01091         /*
    01092          * If the window clipping flags have changed in the window
    01093          * since the last time this dc was invalidated, then recompute
    01094          * this dc entry.
    01095          */
    01096         if ((pdce->DCX_flags & DCX_MATCHMASK) != (DCX_flags & DCX_MATCHMASK))
    01097             goto RecomputeEntry;
    01098
    01099         /*
    01100          * Let's check these assertions just in case...
    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          * Move the dce to the head of the list so it's easy to find later.
    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          * We're about to mess with the visrgn in this DC, even though it's
    01120          * not yet completely setup. Turn off the visrgn validation for now.
    01121          * It will be turned on before this function returns.
    01122          */
    01123         GreValidateVisrgn(pdce->hdc, FALSE);
    01124 #endif
    01125
    01126         /*
    01127          * Time to deal with DCX_INTERSECTRGN or DCX_EXCLUDERGN.
    01128          *
    01129          * We handle these two bits specially, because cache entries
    01130          * with these bits set cannot be reused with the bits set.  This
    01131          * is because the area described in hrgnClip would have to be
    01132          * compared along with the bit, which is a pain, especially since
    01133          * they'd never match very often anyhow.
    01134          *
    01135          * What we do instead is to save the visrgn of the window before
    01136          * applying either of these two flags, which is then restored
    01137          * at ReleaseCacheDC() time, along with the clearing of these bits.
    01138          * This effectively converts a cache entry with either of these
    01139          * bits set into a "normal" cache entry that can be matched.
    01140          */
    01141         if (DCX_flags & DCX_INTERSECTRGN) {
    01142
    01143             if (hrgnClip != HRGN_FULL) {
    01144
    01145                 SetEmptyRgn(ghrgnGDC);
    01146
    01147                 /*
    01148                  * Save the visrgn for reuse on ReleaseDC().
    01149                  * (do this BEFORE we set hrgnClip & pdce->flag bit,
    01150                  * so that if a DCHook() callback occurs it recalculates
    01151                  * without hrgnClip)
    01152                  */
    01153                 UserAssertMsg0(!pdce->hrgnSavedVis,
    01154                                "Nested SaveVisRgn attempt in _GetDCEx");
    01155
    01156                 /*
    01157                  * get the current vis region into hrgnSavedVis.  Temporarily
    01158                  * store a dummy one in the DC.
    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                      * Make a copy of the hrgnClip and make it public
    01182                      * so that we can use it in calculations in HungDraw.
    01183                      */
    01184                     pdce->hrgnClipPublic = CreateEmptyRgnPublic();
    01185                     CopyRgn(pdce->hrgnClipPublic, hrgnClip);
    01186                 }
    01187
    01188                 /*
    01189                  * Clear the SAVEDRGNINVALID bit, since we're just
    01190                  * about to set it properly now.  If the dce later
    01191                  * gets invalidated, it'll set this bit so we know
    01192                  * to recompute it when we restore the visrgn.
    01193                  */
    01194                 pdce->DCX_flags &= ~DCX_SAVEDRGNINVALID;
    01195
    01196                 /*
    01197                  * Select in the new region.  we use the SWAP_REGION mode
    01198                  * so that ghrgnGDC always has a valid rgn
    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                  * Save the visrgn for reuse on ReleaseDC().
    01211                  * (do this BEFORE we set hrgnClip & pdce->flag bit,
    01212                  * so that if a DCHook() callback occurs it recalculates
    01213                  * without hrgnClip)
    01214                  */
    01215                 UserAssertMsg0(!pdce->hrgnSavedVis,
    01216                                "Nested SaveVisRgn attempt in _GetDCEx");
    01217
    01218                 /*
    01219                  * get the current vis region into hrgnSavedVis.  Temporarily
    01220                  * store a dummy one in the DC.
    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                      * Make a copy of the hrgnClip and make it public
    01243                      * so that we can use it in calculations in HungDraw.
    01244                      */
    01245                     pdce->hrgnClipPublic = CreateEmptyRgnPublic();
    01246                     CopyRgn(pdce->hrgnClipPublic, hrgnClip);
    01247                 }
    01248
    01249                 /*
    01250                  * Clear the SAVEDRGNINVALID bit, since we're just
    01251                  * about to set it properly now.  If the dce later
    01252                  * gets invalidated, it'll set this bit so we know
    01253                  * to recompute it when we restore the visrgn.
    01254                  */
    01255                 pdce->DCX_flags &= ~DCX_SAVEDRGNINVALID;
    01256
    01257                 /*
    01258                  * Select in the new region.  we use the SWAP_REGION mode
    01259                  * so that ghrgnGDC always has a valid rgn
    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          * Enable bounds accumulation, so we know if there was any drawing
    01275          * done into that DC and the actual rect we need to update when
    01276          * this DC is released.
    01277          */
    01278         GreGetBounds(pdce->hdc, NULL, GGB_ENABLE_WINMGR);
    01279
    01280         /*
    01281          * In case the visrgn couldn't be allocated, clear it in the
    01282          * dc again, since we just selected a new surface.
    01283          */
    01284         if (fVisRgnError) {
    01285             GreSelectVisRgn(pdce->hdc, NULL, SVR_DELETEOLD);
    01286         }
    01287     }
    01288
    01289     /*
    01290      * Whew! Set ownership and return the bloody DC.
    01291      * Only set ownership for cache dcs.  Own dcs have already been owned.
    01292      * The reason why we don't want to set the ownership over again is
    01293      * because the console sets its owndcs to PUBLIC so gdisrv can use
    01294      * them without asserting.  We don't want to set the ownership back
    01295      * again.
    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          * Decrement the Free DCE Count.  This should always be >= 0,
    01305          * since we'll create a new dce if the cache is all in use.
    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 }

HDC _GetWindowDC | ( | PWND | pwnd | ) |

Definition at line 201 of file dc.c.

References _GetDCEx(), NULL, TestWF, WFMINIMIZED, and WFWIN40COMPAT.

Referenced by _UserSoundSentryWorker(), DrawCtlThumb(), InvertScrollHilite(), NtUserGetWindowDC(), xxxDrawThumb(), xxxEnableWndSBArrows(), xxxMNInvertItem(), xxxMoveThumb(), xxxRedrawTitle(), xxxSBWndProc(), xxxSnapWindow(), and zzzDrawInvertScrollArea().

    00203 {
    00204
    00205 #if 0
    00206
    00207     /*
    00208      * For WIN31 and previous apps, we want to actually return back a
    00209      * client DC.  Before WIN40, the window rect and client rect were the
    00210      * same, and there was this terrible hack to grab the window dc when
    00211      * painting because window DCs never clip anything.  Otherwise the
    00212      * children of the minimized window would be clipped out of the fake
    00213      * client area.  So apps would call GetWindowDC() to redraw their icons,
    00214      * since GetDC() would clip empty if the window had a class icon.
    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 }

BOOL _ReleaseDC | ( | HDC | hdc | ) |

Definition at line 183 of file dc.c.

References BOOL, CheckCritIn, DCE_NORELEASE, FALSE, ReleaseCacheDC(), and TRUE.

Referenced by _UserSoundSentryWorker(), CreateTooltipBitmap(), DrawCtlThumb(), DrawSwitchWndHilite(), InitTooltipAnimation(), InvertScrollHilite(), MNAnimate(), MNDrawArrow(), MNDrawFullNC(), StopFade(), TooltipAnimate(), TooltipGetSize(), UserReleaseDC(), UT_InvertCaret(), xxxDefWindowProc(), xxxDesktopWndProc(), xxxDrawAnimatedRects(), xxxDrawDragRect(), xxxDrawMenuBarUnderlines(), xxxDrawThumb(), xxxDWP_DoNCActivate(), xxxEnableWndSBArrows(), xxxHotTrackMenu(), xxxMenuWindowProc(), xxxMNCompute(), xxxMNInvertItem(), xxxMoveSwitchWndHilite(), xxxMoveThumb(), xxxPaintIconsInSwitchWindow(), xxxPaintSwitchWindow(), xxxRealizeDesktop(), xxxRedrawHungWindow(), xxxRedrawHungWindowFrame(), xxxRedrawTitle(), xxxSBWndProc(), xxxScrollWindowEx(), xxxSnapWindow(), xxxTrackCaptionButton(), and zzzDrawInvertScrollArea().

    00185 {
    00186     CheckCritIn();
    00187
    00188     return (ReleaseCacheDC(hdc, FALSE) == DCE_NORELEASE ? FALSE : TRUE);
    00189 }

PWND _WindowFromDC | ( | HDC | hdc | ) |

Definition at line 1995 of file dc.c.

References tagDCE::DCX_flags, gpDispInfo, tagDCE::hdc, NULL, tagDISPLAYINFO::pdceFirst, tagDCE::pdceNext, and tagDCE::pwndOrg.

Referenced by xxxAnimateCaption().

    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 }

HDC CreateCacheDC | ( | PWND | pwndOrg,
|  | DWORD | DCX_flags,
|  | PMONITOR | pMonitor
| ) |

Definition at line 1463 of file dc.c.

References AnySpbs, CFCLASSDC, DCE, tagDCE::DCX_flags, FALSE, gpDispInfo, tagDCE::hdc, tagDISPLAYINFO::hDev, tagMONITOR::hDev, tagDCE::hrgnClip, tagDCE::hrgnClipPublic, tagDCE::hrgnSavedVis, IncrementFreeDCECount(), InvalidateDce(), NULL, tagWND::pcls, tagCLS::pdce, tagDISPLAYINFO::pdceFirst, tagDCE::pdceNext, tagDCE::pMonitor, PtiCurrent, tagDCE::ptiOwner, tagDCE::pwndClip, tagDCE::pwndOrg, and TestCF.

Referenced by _GetDCEx(), GetMonitorDC(), InitUserScreen(), and xxxCreateWindowEx().

    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      * Link this entry into the cache entry list.
    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      * Mark it as undeleteable so no application can delete it out of our
    01504      * cache!
    01505      */
    01506     GreMarkUndeletableDC(hdc);
    01507
    01508     if (DCX_flags & DCX_OWNDC) {
    01509
    01510         /*
    01511          * Set the ownership of owndcs immediately: that way console can set
    01512          * the owernship to PUBLIC when it calls GetDC so that both the input
    01513          * thread and the service threads can use the same owndc.
    01514          */
    01515         GreSetDCOwner(hdc, OBJECT_OWNER_CURRENT);
    01516         pdce->ptiOwner = PtiCurrent();
    01517
    01518     } else {
    01519
    01520         /*
    01521          * Otherwise it is a cache dc...  set its owner to none - nothing
    01522          * is using it - equivalent of "being in the cache" but unaccessible
    01523          * to other processes.
    01524          */
    01525         GreSetDCOwner(hdc, OBJECT_OWNER_NONE);
    01526         pdce->ptiOwner = NULL;
    01527
    01528         /*
    01529          * Increment the available-cacheDC count.  Once this hits our
    01530          * threshold, then we can free-up some of the entries.
    01531          */
    01532         IncrementFreeDCECount();
    01533     }
    01534
    01535     /*
    01536      * If we're creating a permanent DC, then compute it now.
    01537      */
    01538     if (!(DCX_flags & DCX_CACHE)) {
    01539
    01540         /*
    01541          * Set up the class DC now...
    01542          */
    01543         if (TestCF(pwndOrg, CFCLASSDC))
    01544             pwndOrg->pcls->pdce = pdce;
    01545
    01546         /*
    01547          * Finish setting up DCE and force eventual visrgn calculation.
    01548          */
    01549         UserAssert(!(DCX_flags & DCX_WINDOW));
    01550
    01551         pdce->DCX_flags |= DCX_INUSE;
    01552
    01553         InvalidateDce(pdce);
    01554     }
    01555
    01556     /*
    01557      * If there are any spb's around then enable bounds accumulation.
    01558      */
    01559     if (AnySpbs())
    01560         GreGetBounds(pdce->hdc, NULL, DCB_ENABLE | DCB_SET | DCB_WINDOWMGR);
    01561
    01562     return pdce->hdc;
    01563 }

__inline VOID DecrementFreeDCECount | ( | VOID |  | ) |

Definition at line 30 of file dc.c.

References gnDCECount, and VOID().

Referenced by _GetDCEx(), DestroyCacheDC(), and GetMonitorDC().

    00031 {
    00032     gnDCECount--;
    00033     UserAssert(gnDCECount >= 0);
    00034 }

VOID DelayedDestroyCacheDC | ( | VOID |  | ) |

Definition at line 1596 of file dc.c.

References tagDCE::DCX_flags, DestroyCacheDC(), gpDispInfo, tagDCE::hdc, NULL, tagDISPLAYINFO::pdceFirst, tagDCE::pdceNext, PpiCurrent, and VOID().

Referenced by _GetDCEx(), CleanupGDI(), and DestroyProcessInfo().

    01597 {
    01598     PDCE *ppdce;
    01599     PDCE pdce;
    01600
    01601
    01602     /*
    01603      * Zip through the cache looking for a DCX_DESTROYTHIS hdc.
    01604      */
    01605     for (ppdce = &gpDispInfo->pdceFirst; *ppdce != NULL; ) {
    01606
    01607         /*
    01608          * If we found a DCE on this thread that we tried to destroy
    01609          * earlier, try and destroy it again.
    01610          */
    01611         pdce = *ppdce;
    01612
    01613         if (pdce->DCX_flags & DCX_DESTROYTHIS)
    01614             DestroyCacheDC(ppdce, pdce->hdc);
    01615
    01616         /*
    01617          * Step to the next DC.  If the DC was deleted, there
    01618          * is no need to calculate address of the next entry.
    01619          */
    01620         if (pdce == *ppdce)
    01621             ppdce = &pdce->pdceNext;
    01622     }
    01623
    01624     PpiCurrent()->W32PF_Flags &= ~W32PF_OWNDCCLEANUP;
    01625 }

VOID DeleteHrgnClip | ( | PDCE | pdce | ) |

Definition at line 549 of file dc.c.

References tagDCE::DCX_flags, DeleteMaybeSpecialRgn(), tagDCE::hdc, tagDCE::hrgnClip, tagDCE::hrgnClipPublic, tagDCE::hrgnSavedVis, InvalidateDce(), NULL, and VOID().

Referenced by _GetDCEx(), ReleaseCacheDC(), and xxxFreeWindow().

    00551 {
    00552     /*
    00553      * Clear these flags first in case we get a DCHook() callback...
    00554      */
    00555     pdce->DCX_flags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN);
    00556
    00557     /*
    00558      * Blow away pdce->hrgnClip and clear the associated flags.
    00559      * Do not delete hrgnClip if DCX_NODELETERGN is set!
    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      * If the saved visrgn was invalidated by an InvalidateDce()
    00574      * while we had it checked out, then invalidate the entry now.
    00575      */
    00576     if (pdce->DCX_flags & DCX_SAVEDRGNINVALID) {
    00577         InvalidateDce(pdce);
    00578
    00579         /*
    00580          * We've just gone through InvalidateDce, so the visrgn in the
    00581          * DC has been properly reset. Simply nuke the old saved visrgn.
    00582          */
    00583         if (pdce->hrgnSavedVis != NULL) {
    00584             GreDeleteObject(pdce->hrgnSavedVis);
    00585             pdce->hrgnSavedVis = NULL;
    00586         }
    00587     } else {
    00588         /*
    00589          * The saved visrgn is still valid, select it back into the
    00590          * DC so the entry may be re-used without recomputing.
    00591          */
    00592         if (pdce->hrgnSavedVis != NULL) {
    00593             GreSelectVisRgn(pdce->hdc, pdce->hrgnSavedVis, SVR_DELETEOLD);
    00594             pdce->hrgnSavedVis = NULL;
    00595         }
    00596     }
    00597 }

BOOL DestroyCacheDC | ( | PDCE * | ppdce,
|  | HDC | hdc
| ) |

Definition at line 1638 of file dc.c.

References BOOL, tagDCE::DCX_flags, DecrementFreeDCECount(), DeleteMaybeSpecialRgn(), FALSE, gpDispInfo, tagDCE::hdc, tagDCE::hrgnClip, tagDCE::hrgnClipPublic, tagDCE::hrgnSavedVis, NULL, tagDISPLAYINFO::pdceFirst, tagDCE::pdceNext, PpiCurrent, tagDCE::pwndClip, tagDCE::pwndOrg, and TRUE.

Referenced by DelayedDestroyCacheDC(), DestroyCacheDCEntries(), DestroyClass(), DestroyMonitorDCs(), ReleaseCacheDC(), xxxFreeWindow(), and xxxUserProcessCallout().

    01641 {
    01642     PDCE pdce;
    01643
    01644     /*
    01645      * Zip through the cache looking for hdc.
    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      * Set this here so we know this DCE is supposed to be deleted.
    01659      */
    01660     pdce = *ppdce;
    01661     pdce->DCX_flags |= DCX_DESTROYTHIS;
    01662
    01663     /*
    01664      * Free up the dce object and contents.
    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      * If GreSetDCOwner() or GreDeleteDC() fail, the
    01684      * DC is in-use by another thread.  Set
    01685      * W32PF_OWNDCCLEANUP so we know to scan for and
    01686      * delete this DCE later.
    01687      */
    01688     if (!GreSetDCOwner(hdc, OBJECT_OWNER_PUBLIC)) {
    01689         PpiCurrent()->W32PF_Flags |= W32PF_OWNDCCLEANUP;
    01690         return FALSE;
    01691     }
    01692
    01693     /*
    01694      * Set the don't rip flag so our routine RipIfCacheDC() doesn't
    01695      * rip (called back from gdi).
    01696      */
    01697 #if DBG
    01698     pdce->DCX_flags |= DCX_DONTRIPONDESTROY;
    01699     GreMarkDeletableDC(hdc);    // So GRE doesn't RIP.
    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      * Decrement this dc-entry from the free-list count.
    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      * Unlink the DCE from the list.
    01729      */
    01730     *ppdce = pdce->pdceNext;
    01731
    01732     UserFreePool(pdce);
    01733
    01734     return TRUE;
    01735 }

PWND FastWindowFromDC | ( | HDC | hdc | ) |

Definition at line 2022 of file dc.c.

References tagDCE::DCX_flags, gpDispInfo, tagDCE::hdc, NULL, tagDISPLAYINFO::pdceFirst, tagDCE::pdceNext, and tagDCE::pwndOrg.

Referenced by _ScrollDC().

    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              * Unlink/link to make it first.
    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 }

BOOL GetDCOrgOnScreen | ( | HDC | hdc,
|  | LPPOINT | ppt
| ) |

Definition at line 2066 of file dc.c.

References BOOL, FALSE, TRUE, and UserGetRedirectedWindowOrigin().

Referenced by InternalScrollDC(), and xxxScrollWindowEx().

    02067 {
    02068     if (GreGetDCOrg(hdc, ppt)) {
    02069         POINT ptScreen;
    02070
    02071         /*
    02072          * Get the origin of the redirected window in screen coordinates.
    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 }

HDC GetMonitorDC | ( | PDCE | pdceOrig,
|  | PMONITOR | pMonitor
| ) |

Definition at line 2151 of file dc.c.

References CreateCacheDC(), CreateEmptyRgn(), tagDCE::DCX_flags, DCX_LEAVEBITS, DecrementFreeDCECount(), ghrgnGDC, gpDispInfo, tagDCE::hdc, HRGN_FULL, tagDCE::hrgnClip, NULL, OffsetRect(), tagDISPLAYINFO::pdceFirst, tagDCE::pdceNext, tagDCE::pMonitor, tagDCE::ptiOwner, tagDCE::pwndClip, tagDCE::pwndOrg, tagMONITOR::rcMonitor, SetMonitorRegion(), and SpbCheckDce().

Referenced by xxxEnumDisplayMonitors().

    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          * Find an available DC for this monitor.
    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          * Copy DC properties and style bits.
    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          * Setup the visrgn clipped to this monitor.
    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          * Decrement the Free DCE Count.  This should always be >= 0,
    02204          * since we'll create a new dce if the cache is all in use.
    02205          */
    02206         DecrementFreeDCECount();
    02207
    02208         return pdce->hdc;
    02209     }
    02210
    02211     /*
    02212      * If this call succeeds a new DC will be available in the cache,
    02213      * so the loop will find it and properly set it up.
    02214      */
    02215     if (CreateCacheDC(NULL, DCX_INVALID | DCX_CACHE, pMonitor) == NULL)
    02216         return NULL;
    02217
    02218     goto TryAgain;
    02219 }

__inline VOID IncrementFreeDCECount | ( | VOID |  | ) |

Definition at line 41 of file dc.c.

References gnDCECount, and VOID().

Referenced by CreateCacheDC(), and ReleaseCacheDC().

    00042 {
    00043     gnDCECount++;
    00044     UserAssert(gnDCECount >= 0);
    00045 }

VOID InvalidateDce | ( | PDCE | pdce | ) |

Definition at line 470 of file dc.c.

References CFPARENTDC, tagDCE::DCX_flags, gpDispInfo, tagDCE::hdc, tagDISPLAYINFO::hDev, tagDCE::hrgnClip, tagDCE::hrgnClipPublic, MarkDCEInvalid(), NULL, tagDCE::pwndClip, tagDCE::pwndOrg, SpbCheckDce(), TestCF, TestWF, UserSetDCVisRgn(), VOID(), WFCLIPCHILDREN, WFCLIPSIBLINGS, WFMINIMIZED, WFVISIBLE, and WFWIN31COMPAT.

Referenced by ConvertRedirectionDCs(), CreateCacheDC(), DeleteHrgnClip(), and zzzInvalidateDCCache().

    00472 {
    00473     GreLockDisplay(gpDispInfo->hDev);
    00474
    00475     if (!(pdce->DCX_flags & DCX_INUSE)) {
    00476
    00477         /*
    00478          * Accumulate any bounds for this CE
    00479          * since we're about to mark it invalid.
    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          * Remove the vis rgn since it is still owned - if we did not,
    00492          * gdi would not be able to clean up properly if the app that
    00493          * owns this vis rgn exist while the vis rgn is still selected.
    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          * In case the window's clipping style bits changed,
    00504          * reset the DCE flags from the window style bits.
    00505          * Note that minimized windows never exclude their children.
    00506          */
    00507         pdce->DCX_flags &= ~(DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS);
    00508
    00509         /*
    00510          * Chicago stuff...
    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          * Mark that any saved visrgn needs to be recomputed.
    00530          */
    00531         pdce->DCX_flags |= DCX_SAVEDRGNINVALID;
    00532
    00533         UserSetDCVisRgn(pdce);
    00534     }
    00535
    00536     GreUnlockDisplay(gpDispInfo->hDev);
    00537 }

VOID InvalidateGDIWindows | ( | PWND | pwnd | ) |

Definition at line 1746 of file dc.c.

References _GetProp(), CalcVisRgn(), NULL, PROP_WNDOBJ, tagWND::rcClient, tagWND::spwndChild, tagWND::spwndNext, TestWF, TRUE, VOID(), and WFCLIPSIBLINGS.

Referenced by zzzInvalidateDCCache().

    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                  * Never clip children for WO_RGN_WINDOW so that NetMeeting
    01761                  * gets the unioned window area:
    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 }

PDCE LookupDC | ( | HDC | hdc | ) |

Definition at line 2123 of file dc.c.

References tagDCE::DCX_flags, gpDispInfo, tagDCE::hdc, NULL, tagDISPLAYINFO::pdceFirst, tagDCE::pdceNext, and tagDCE::pMonitor.

Referenced by UserGetRedirectedWindowOrigin(), and xxxEnumDisplayMonitors().

    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 }

UINT ReleaseCacheDC | ( | HDC | hdc,
|  | BOOL | fEndPaint
| ) |

Definition at line 1337 of file dc.c.

References DCE_FREED, DCE_NORELEASE, DCE_RELEASED, DCE_SIZE_CACHETHRESHOLD, tagDCE::DCX_flags, DeleteHrgnClip(), DestroyCacheDC(), FALSE, gnDCECount, gpDispInfo, tagDCE::hdc, tagDISPLAYINFO::hDev, IncrementFreeDCECount(), NULL, tagDISPLAYINFO::pdceFirst, tagDCE::pdceNext, tagDCE::ptiOwner, UINT, and UpdateLayeredSprite().

Referenced by _ReleaseDC(), xxxEndPaint(), xxxEnumDisplayMonitors(), xxxFreeWindow(), and xxxSendEraseBkgnd().

    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              * Check for redundant releases or release of an invalid entry
    01350              */
    01351             if ((pdce->DCX_flags & (DCX_DESTROYTHIS | DCX_INVALID | DCX_INUSE)) != DCX_INUSE)
    01352                 return DCE_NORELEASE;
    01353
    01354             /*
    01355              * Lock the display since we may be playing with visrgns.
    01356              */
    01357             GreLockDisplay(gpDispInfo->hDev);
    01358
    01359             if (pdce->DCX_flags & DCX_LAYERED) {
    01360                 UpdateLayeredSprite(pdce);
    01361             }
    01362
    01363             /*
    01364              * If this is a permanent DC, then don't reset its state.
    01365              */
    01366             if (pdce->DCX_flags & DCX_CACHE) {
    01367                 /*
    01368                  * Restore the DC state and mark the entry as not in use.
    01369                  * Set owner back to server as well, since it's going back
    01370                  * into the cache.
    01371                  */
    01372                 if (!(pdce->DCX_flags & DCX_NORESETATTRS)) {
    01373                     /*
    01374                      * If bSetupDC() failed, the DC is busy (ie. in-use
    01375                      * by another thread), so don't release it.
    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                  * Turn off checked only surface validation for now, since
    01396                  * we may select a different surface (screen) in this DC that
    01397                  * may not correspond to the visrgn currently in the DC. When
    01398                  * the DC is given out again, it will be revalidated.
    01399                  */
    01400                 GreValidateVisrgn(pdce->hdc, FALSE);
    01401 #endif
    01402
    01403                 /*
    01404                  * The DC is no longer in use, so unselect the redirection
    01405                  * bitmap from it.
    01406                  */
    01407                 if (pdce->DCX_flags & DCX_LAYERED) {
    01408                     UserVerify(GreSelectRedirectionBitmap(pdce->hdc, NULL));
    01409                 }
    01410
    01411                 /*
    01412                  * Increment the Free DCE count.  This holds the count
    01413                  * of available DCEs.  Check the threshold, and destroy
    01414                  * the dce if it's above the mark.
    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              * If we have an EXCLUDERGN or INTERSECTRGN cache entry,
    01428              * convert it back to a "normal" cache entry by restoring
    01429              * the visrgn and blowing away hrgnClip.
    01430              *
    01431              * Note that for non-DCX_CACHE DCs, we only do this if
    01432              * we're being called from EndPaint().
    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      * Yell if DC couldn't be found...
    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 }

VOID ResetOrg | ( | HRGN | hrgn,
|  | PDCE | pdce,
|  | BOOL | fSetVisRgn
| ) |

Definition at line 73 of file dc.c.

References tagDCE::DCX_flags, FNID_DESKTOP, GETFNID, GetLayeredWindow(), tagDCE::hdc, NULL, OffsetRect(), tagDCE::pMonitor, tagDCE::pwndOrg, tagWND::rcClient, tagMONITOR::rcMonitor, tagWND::rcWindow, SetMonitorRegion(), SYSMET, and VOID().

Referenced by _GetDCEx(), and UserSetDCVisRgn().

    00077 {
    00078     RECT  rc;
    00079     PWND  pwndLayer;
    00080
    00081     /*
    00082      * For compatibility purposes, make sure that the DC's for the
    00083      * desktop windows originate at the primary monitor, i.e. (0,0).
    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              * For layered redirection DCs, the surface origin is the
    00111              * window origin, so offset both the rectangle and the
    00112              * region appropriately.
    00113              */
    00114             OffsetRect(&rc, -x, -y);
    00115             if (hrgn != NULL) {
    00116                 GreOffsetRgn(hrgn, -x, -y);
    00117             }
    00118         } else {
    00119             /*
    00120              * Layered windows can only draw to the screen via the redirection
    00121              * DCs or UpdateLayeredWindow, so select an empty visrgn into this
    00122              * screen DC.
    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 }

void SetMonitorRegion | ( | PMONITOR | pMonitor,
|  | HRGN | hrgnDst,
|  | HRGN | hrgnSrc
| ) |

Definition at line 53 of file dc.c.

References tagMONITOR::hrgnMonitor, IntersectRgn, and tagMONITOR::rcMonitor.

Referenced by GetMonitorDC(), and ResetOrg().

    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 }

VOID UserAssociateHwnd | ( | HWND | hwnd,
|  | PVOID | pwo
| ) |

Definition at line 415 of file dc.c.

References CheckCritIn, gcountPWO, InternalRemoveProp(), InternalSetProp(), NULL, PROP_WNDOBJ, PROPF_INTERNAL, PROPF_NOPOOL, TRUE, ValidateHwnd, and VOID().

    00418 {
    00419     PWND pwnd;
    00420
    00421     /*
    00422      * Must be in critical section.
    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 }

HRGN UserGetClientRgn | ( | HWND | hwnd,
|  | LPRECT | lprc,
|  | BOOL | bWindowInsteadOfClient
| ) |

Definition at line 290 of file dc.c.

References CalcVisRgn(), CheckCritIn, NULL, tagWND::rcClient, TestWF, ValidateHwnd, and WFCLIPSIBLINGS.

    00294 {
    00295     HRGN hrgnClient = (HRGN)NULL;
    00296     PWND pwnd;
    00297
    00298     /*
    00299      * Must be in critical section.
    00300      */
    00301     CheckCritIn();
    00302
    00303     if (pwnd = ValidateHwnd(hwnd)) {
    00304
    00305         if (bWindowInsteadOfClient) {
    00306
    00307             /*
    00308              * Never clip children for WO_RGN_WINDOW so that NetMeeting
    00309              * gets the unioned window area:
    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 }

BOOL UserGetHwnd | ( | HDC | hdc,
|  | HWND * | phwnd,
|  | PVOID * | ppwo,
|  | BOOL | bCheckStyle
| ) |

Definition at line 344 of file dc.c.

References _GetProp(), BOOL, CFPARENTDC, CheckCritIn, FALSE, gpDispInfo, tagDCE::hdc, HW, NULL, tagDISPLAYINFO::pdceFirst, tagDCE::pdceNext, PROP_WNDOBJ, tagDCE::pwndOrg, TestCF, TestWF, TRUE, WFCLIPCHILDREN, and WFCLIPSIBLINGS.

    00349 {
    00350     PWND pwnd;
    00351     PDCE pdce;
    00352
    00353     /*
    00354      * Must be in critical section.
    00355      */
    00356     CheckCritIn();
    00357
    00358     /*
    00359      * Find pdce and pwnd for this DC.
    00360      *
    00361      * Note: the SAMEHANDLE macro strips out the user defined bits in the
    00362      * handle before doing the comparison.  This is important because when
    00363      * GRE calls this function, it may have lost track of the OWNDC bit.
    00364      */
    00365     for (pdce = gpDispInfo->pdceFirst; pdce != NULL; pdce = pdce->pdceNext) {
    00366
    00367         if (pdce->hdc == hdc) // this should be undone once SAMEHANDLE is fixed for kmode
    00368             break;
    00369     }
    00370
    00371     /*
    00372      * Return FALSE If it is not in the pdce list.
    00373      */
    00374     if ((pdce == NULL) || (pdce->pwndOrg == NULL))
    00375         return FALSE;
    00376
    00377     pwnd = pdce->pwndOrg;
    00378
    00379     /*
    00380      * The window style must be clipchildren and clipsiblings.
    00381      * the window's class must not be parentdc
    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      * Return the hwnd with the correct styles for a device format window.
    00396      */
    00397     *phwnd = HW(pwnd);
    00398     *ppwo  = _GetProp(pwnd, PROP_WNDOBJ, TRUE);
    00399
    00400     return TRUE;
    00401 }

BOOL UserGetRedirectedWindowOrigin | ( | HDC | hdc,
|  | LPPOINT | ppt
| ) |

Definition at line 2096 of file dc.c.

References BOOL, tagDCE::DCX_flags, FALSE, GetLayeredWindow(), LookupDC(), NULL, tagDCE::pwndOrg, tagWND::rcWindow, and TRUE.

Referenced by GetDCOrgOnScreen().

    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 }

BOOL UserReleaseDC | ( | HDC | hdc | ) |

Definition at line 447 of file dc.c.

References _ReleaseDC(), BOOL, EnterCrit, and LeaveCrit.

    00449 {
    00450     BOOL b;
    00451
    00452     EnterCrit();
    00453     b = _ReleaseDC(hdc);
    00454     LeaveCrit();
    00455
    00456     return b;
    00457 }

VOID UserSetDCVisRgn | ( | PDCE | pdce | ) |

Definition at line 237 of file dc.c.

References CalcVisRgn(), tagDCE::DCX_flags, HRGN_FULL, tagDCE::hrgnClipPublic, IntersectRgn, NULL, tagDCE::pwndClip, tagDCE::pwndOrg, ResetOrg(), SetEmptyRgn(), SubtractRgn, TRUE, and VOID().

Referenced by InvalidateDce().

    00239 {
    00240     HRGN hrgn = NULL;
    00241
    00242     /*
    00243      * If the visrgn calculated is empt, set the flag DCX_PWNDORGINVISIBLE,
    00244      * otherwise clear it (it could've been set earlier on).
    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      * Deal with INTERSECTRGN and EXCLUDERGN.
    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 }

PWND WindowFromCacheDC | ( | HDC | hdc | ) |

Definition at line 1574 of file dc.c.

References tagDCE::DCX_flags, gpDispInfo, tagDCE::hdc, NULL, tagDISPLAYINFO::pdceFirst, tagDCE::pdceNext, and tagDCE::pwndOrg.

Referenced by _SelectPalette(), and xxxRealizePalette().

    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 }

BOOL zzzInvalidateDCCache | ( | PWND | pwndInvalid,
|  | DWORD | flags
| ) |

Definition at line 1812 of file dc.c.

References BOOL, tagDCE::DCX_flags, gcountPWO, gpDispInfo, tagDISPLAYINFO::hDev, IDC_CHILDRENONLY, IDC_CLIENTONLY, IDC_DEFAULT, IDC_MOVEBLT, IDC_NOMOUSE, InvalidateDce(), InvalidateGDIWindows(), IsGlobalHooked, NULL, tagDISPLAYINFO::pdceFirst, tagDCE::pdceNext, PtiCurrent, tagDCE::pwndClip, PWNDDESKTOP, tagDCE::pwndOrg, tagWND::spwndParent, TestWF, ThreadLockAlwaysWithPti, ThreadUnlock, tagTHREADINFO::TIF_flags, TIF_MOVESIZETRACKING, TRUE, WFCLIPCHILDREN, WFCLIPSIBLINGS, WFMINIMIZED, WHF_FROM_WH, and zzzSetFMouseMoved().

Referenced by LockWindowUpdate2(), ResetSharedDesktops(), UnsetLayeredWindow(), xxxDWP_SetRedraw(), xxxMinimizeHungWindow(), xxxScrollWindowEx(), xxxSetLayeredWindow(), xxxSetParent(), xxxSetWindowStyle(), and zzzBltValidBits().

    01815 {
    01816     PWND        pwnd;
    01817     PDCE        pdce;
    01818     PTHREADINFO ptiCurrent = PtiCurrent();
    01819     TL          tlpwndInvalid;
    01820     FLONG       fl;
    01821
    01822     /*
    01823      * Invalidation implies screen real estate is changing so we must
    01824      * jiggle the mouse, because a different window may be underneath
    01825      * the mouse, which needs to get a mouse move in order to change the
    01826      * mouse pointer.
    01827      *
    01828      * The check for the tracking is added for full-drag-windows.  In doing
    01829      * full-drag, zzzBltValidBits() is called from setting the window-pos.
    01830      * This resulted in an extra-mousemove being queued from this routine.
    01831      * So, when we're tracking, don't queue a mousemove.  This pointer is
    01832      * null when tracking is off, so it won't effect the normal case.
    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      * The visrgn of pwnd is changing.  First see if a change to this
    01848      * visrgn will also affect other window's visrgns:
    01849      *
    01850      * 1) if parent is clipchildren, we need to invalidate parent
    01851      * 2) if clipsiblings, we need to invalidate our sibling's visrgns.
    01852      *
    01853      * We don't optimize the case where we're NOT clipsiblings, and our
    01854      * parent is clipchildren: very rare case.
    01855      * We also don't optimize the fact that a clipsiblings window visrgn
    01856      * change only affects the visrgns of windows BELOW it.
    01857      */
    01858     if (flags & IDC_DEFAULT) {
    01859
    01860         flags = 0;
    01861
    01862         if ((pwndInvalid->spwndParent != NULL) &&
    01863             (pwndInvalid != PWNDDESKTOP(pwndInvalid))) {
    01864
    01865             /*
    01866              * If the parent is a clip-children window, then
    01867              * a change to our visrgn will affect his visrgn, and
    01868              * possibly those of our siblings.  So, invalidate starting
    01869              * from our parent.  Note that we don't need to invalidate
    01870              * any window DCs associated with our parent.
    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                  * If we are clip-siblings, chances are that our siblings are
    01881                  * too.  A change to our visrgn might affect our siblings,
    01882                  * so invalidate all of our siblings.
    01883                  *
    01884                  * NOTE! This code assumes that if pwndInvalid is NOT
    01885                  * CLIPSIBLINGs, that either it does not overlap other
    01886                  * CLIPSIBLINGs windows, or that none of the siblings are
    01887                  * CLIPSIBLINGs.  This is a reasonable assumption, because
    01888                  * mixing CLIPSIBLINGs and non CLIPSIBLINGs windows that
    01889                  * overlap is generally unpredictable anyhow.
    01890                  */
    01891                 flags = IDC_CHILDRENONLY;
    01892                 pwndInvalid = pwndInvalid->spwndParent;
    01893             }
    01894         }
    01895     }
    01896
    01897     /*
    01898      * Go through the list of DCE's, looking for any that need to be
    01899      * invalidated or recalculated.  Basically, any DCE that contains
    01900      * a window handle that is equal to pwndInvalid or a child of pwndInvalid
    01901      * needs to be invalidated.
    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          * HACK ALERT
    01910          *
    01911          * A minimized client DC must never exclude its children, even if
    01912          * its WS_CLIPCHILDREN bit is set.  For CS_OWNDC windows we must
    01913          * update the flags of the DCE to reflect the change in window state
    01914          * when the visrgn is eventually recomputed.
    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          * This code assumes that if pdce->pwndClip != pdce->pwndOrg,
    01927          * that pdce->pwndClip == pdce->pwndOrg->spwndParent.  To ensure
    01928          * that both windows are visited, we start the walk upwards from
    01929          * the lower of the two, or pwndOrg.
    01930          */
    01931         UserAssert((pdce->pwndClip == pdce->pwndOrg) ||
    01932                    (pdce->pwndClip == pdce->pwndOrg->spwndParent));
    01933
    01934         /*
    01935          * Walk upwards from pdce->pwndOrg, to see if we encounter
    01936          * pwndInvalid.
    01937          */
    01938         for (pwnd = pdce->pwndOrg; pwnd; pwnd = pwnd->spwndParent) {
    01939
    01940             if (pwnd == pwndInvalid) {
    01941
    01942                 if (pwndInvalid == pdce->pwndOrg) {
    01943
    01944                     /*
    01945                      * Ignore DCEs for pwndInvalid if IDC_CHILDRENONLY.
    01946                      */
    01947                     if (flags & IDC_CHILDRENONLY)
    01948                         break;
    01949
    01950                     /*
    01951                      * Ignore window DCEs for pwndInvalid if IDC_CLIENTONLY
    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      * Update WNDOBJs in gdi if they exist.
    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 }