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 }


Generated on Sat May 15 19:43:24 2004 for test by doxygen 1.3.7