test: visrgn.c File Reference

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

# visrgn.c File Reference

`#include "precomp.h"`

Go to the source code of this file.

## Defines

#define | CEXCLUDERECTSMAX 30
#define | CEXCLUDEPWNDSMAX 30
#define | CheckIntersectRect(prc1, prc2)
#define | EmptyRect(prc)

## Functions

BOOL | SetRectRgnIndirect (HRGN hrgn, LPCRECT lprc)
HRGN | CreateEmptyRgn (void)
HRGN | CreateEmptyRgnPublic (void)
BOOL | SetEmptyRgn (HRGN hrgn)
HRGN | SetOrCreateRectRgnIndirectPublic (HRGN *phrgn, LPCRECT lprc)
BOOL | ResizeVisExcludeMemory (VOID)
BOOL | ExcludeWindowRects (PWND pwnd, PWND pwndStop, LPRECT lprcIntersect)
BOOL | CalcWindowVisRgn (PWND pwnd, HRGN *phrgn, DWORD flags)
BOOL | CalcVisRgn (HRGN *phrgn, PWND pwndOrg, PWND pwndClip, DWORD flags)
int | CalcWindowRgn (PWND pwnd, HRGN hrgn, BOOL fClient)

## Variables

BOOL | gfVisAlloc
int | gcrcVisExclude
int | gcrcVisExcludeMax
PWND * | gapwndVisExclude
PWND * | gapwndVisDefault

## Define Documentation

#define CEXCLUDEPWNDSMAX 30

| Definition at line 21 of file visrgn.c. Referenced by CalcWindowVisRgn(), and ResizeVisExcludeMemory().

#define CEXCLUDERECTSMAX 30

| Definition at line 20 of file visrgn.c. Referenced by CalcWindowVisRgn().

#define CheckIntersectRect | ( | prc1,
|  | prc2 |  | ) |

Value:

    (   prc1->left < prc2->right              \
         && prc2->left < prc1->right              \
         && prc1->top < prc2->bottom              \
         && prc2->top < prc1->bottom)

Definition at line 188 of file visrgn.c.

Referenced by ExcludeWindowRects().

#define EmptyRect | ( | prc |  | ) |

Value:

    (   prc->left >= prc->right               \
         || prc->top >= prc->bottom)

Definition at line 194 of file visrgn.c.

Referenced by BNCalcRect(), and ExcludeWindowRects().

## Function Documentation

BOOL CalcVisRgn | ( | HRGN * | phrgn,
|  | PWND | pwndOrg,
|  | PWND | pwndClip,
|  | DWORD | flags
| ) |

Definition at line 523 of file visrgn.c.

References _IsDescendant(), BOOL, CalcWindowVisRgn(), FALSE, grpdeskRitInput, gspwndLockUpdate, tagWND::head, IsVisible(), NULL, PZERO, tagDESKTOP::rpwinstaParent, and SetOrCreateRectRgnIndirectPublic().

Referenced by _GetDCEx(), InvalidateGDIWindows(), ResetSharedDesktops(), SwpCalcVisRgn(), UserGetClientRgn(), UserSetDCVisRgn(), and UserVisrgnFromHwnd().

    00528 {
    00529     PDESKTOP    pdesk;
    00530
    00531     UserAssert(pwndOrg != NULL);
    00532
    00533     /*
    00534      * If the window's not visible or is not an active desktop,
    00535      * or if the clip window is in the process of being destroyed,
    00536      * the visrgn is empty.
    00537      */
    00538     pdesk = pwndOrg->head.rpdesk;
    00539
    00540     UserAssert(pdesk);
    00541
    00542     /*
    00543      * Make sure this happens in the IO windowstation
    00544      */
    00545 #if DBG
    00546     if (grpdeskRitInput != NULL) {
    00547         UserAssert(pdesk->rpwinstaParent == grpdeskRitInput->rpwinstaParent ||
    00548                    !IsVisible(pwndOrg));
    00549     }
    00550 #endif // DBG
    00551
    00552     if (!IsVisible(pwndOrg) || pdesk != grpdeskRitInput) {
    00553         goto EmptyRgn;
    00554     }
    00555
    00556     /*
    00557      * If LockWindowUpdate() has been called, and this window is a child
    00558      * of the lock window, always return an empty visrgn.
    00559      */
    00560     if ((gspwndLockUpdate != NULL)     &&
    00561         !(flags & DCX_LOCKWINDOWUPDATE)         &&
    00562         _IsDescendant(gspwndLockUpdate, pwndOrg)) {
    00563
    00564         goto EmptyRgn;
    00565     }
    00566
    00567     /*
    00568      * Now go compute the visrgn for pwndClip.
    00569      */
    00570     return CalcWindowVisRgn(pwndClip, phrgn, flags);
    00571
    00572 EmptyRgn:
    00573     SetOrCreateRectRgnIndirectPublic(phrgn, PZERO(RECT));
    00574     return FALSE;
    00575 }

int CalcWindowRgn | ( | PWND | pwnd,
|  | HRGN | hrgn,
|  | BOOL | fClient
| ) |

Definition at line 585 of file visrgn.c.

References tagWND::hrgnClip, IntersectRgn, NULL, tagWND::rcClient, tagWND::rcWindow, and SetRectRgnIndirect().

Referenced by GetNCUpdateRgn(), InternalInvalidate3(), and xxxInternalInvalidate().

    00589 {
    00590     SetRectRgnIndirect(hrgn, (fClient) ? &pwnd->rcClient : &pwnd->rcWindow);
    00591
    00592     /*
    00593      * If the window has a region, then intersect the rectangle region with
    00594      * that. If this is low on memory, it'll propagate ERROR back.
    00595      */
    00596     if (pwnd->hrgnClip != NULL) {
    00597         return IntersectRgn(hrgn, hrgn, pwnd->hrgnClip);
    00598     }
    00599
    00600     return SIMPLEREGION;
    00601 }

BOOL CalcWindowVisRgn | ( | PWND | pwnd,
|  | HRGN * | phrgn,
|  | DWORD | flags
| ) |

Definition at line 250 of file visrgn.c.

References ARRAY_SIZE, BOOL, CEXCLUDEPWNDSMAX, CEXCLUDERECTSMAX, CreateEmptyRgn(), ExcludeWindowRects(), FALSE, FLayeredOrRedirected(), FNID_DESKTOP, gapwndVisDefault, gapwndVisExclude, gcrcVisExclude, gcrcVisExcludeMax, GETFNID, gfVisAlloc, ghrgnInv2, tagWND::head, tagWND::hrgnClip, IntersectRect(), IntersectRgn, NULL, PZERO, tagWND::rcClient, tagWND::rcWindow, SetOrCreateRectRgnIndirectPublic(), SetRectEmpty, SetRectRgnIndirect(), tagWND::spwndChild, tagWND::spwndParent, SubtractRgn, TestWF, TRUE, WFCLIPSIBLINGS, and WFDESTROYED.

Referenced by CalcVisRgn().

    00254 {
    00255     RECT rcWindow;
    00256     PWND pwndParent;
    00257     PWND pwndRoot;
    00258     PWND pwndLoop;
    00259     BOOL fClipSiblings;
    00260     BOOL fRgnParent = FALSE;
    00261     BOOL fResult;
    00262     PWND apwndVisDefault[CEXCLUDEPWNDSMAX];
    00263
    00264
    00265     /*
    00266      * First get the initial window rectangle which will be used for
    00267      * the basis of exclusion calculations.
    00268      */
    00269     rcWindow = (flags & DCX_WINDOW ? pwnd->rcWindow : pwnd->rcClient);
    00270
    00271     /*
    00272      * Get the parent of this window.  We start at the parent and backtrack
    00273      * through the window-parent-list until we reach the end of the parent-
    00274      * list.  This will give us the intersect-rectangle which is used as
    00275      * the basis for checking intersection of the exclusion rects.
    00276      */
    00277     pwndRoot   = pwnd->head.rpdesk->pDeskInfo->spwnd->spwndParent;
    00278     pwndParent = pwnd->spwndParent;
    00279
    00280     /*
    00281      * The parent can be NULL in the case when pwnd == pwndRoot. In other
    00282      * cases we should figure why the hell the parent is NULL.
    00283      */
    00284     if (pwndParent == NULL) {
    00285 #if DBG
    00286         if (pwnd != pwndRoot) {
    00287             RIPMSG0(RIP_ERROR, "CalcWindowVisRgn: pwndParent is NULL");
    00288         }
    00289 #endif
    00290         goto NullRegion;
    00291     }
    00292
    00293     while (pwndParent != pwndRoot) {
    00294
    00295         /*
    00296          * Don't clip layered DCs to the desktop. The surface of the layered
    00297          * DC is the size of the window and we always want to have the image
    00298          * of the entire window in that surface.
    00299          */
    00300         if ((flags & DCX_LAYERED) && (GETFNID(pwndParent) == FNID_DESKTOP))
    00301             break;
    00302
    00303         /*
    00304          * Remember if any of the parents have a window region.
    00305          */
    00306         if (pwndParent->hrgnClip != NULL)
    00307             fRgnParent = TRUE;
    00308
    00309         /*
    00310          * Intersect the parent's client rectangle with the window rectangle.
    00311          */
    00312         if (!IntersectRect(&rcWindow, &rcWindow, &pwndParent->rcClient))
    00313             goto NullRegion;
    00314
    00315         pwndParent = pwndParent->spwndParent;
    00316     }
    00317
    00318     /*
    00319      * Initialize the VisRgn memory-buffer.  This is
    00320      * used to hold the pwnd's.
    00321      */
    00322     gapwndVisDefault  = apwndVisDefault;
    00323     gapwndVisExclude  = gapwndVisDefault;
    00324     gcrcVisExcludeMax = ARRAY_SIZE(apwndVisDefault);
    00325     gcrcVisExclude    = 0;
    00326
    00327     /*
    00328      * Build the list of exclude-rects.
    00329      */
    00330     fClipSiblings = (BOOL)(flags & DCX_CLIPSIBLINGS);
    00331     pwndParent    = pwnd->spwndParent;
    00332     pwndLoop      = pwnd;
    00333
    00334     while (pwndParent != pwndRoot) {
    00335
    00336         /*
    00337          * Don't exclude siblings of a layered window when calculating
    00338          * the virgn of a layered redirection DC.  We must always have
    00339          * a complete image of this window in the redirection bitmap.
    00340          */
    00341         if ((flags & DCX_LAYERED) && FLayeredOrRedirected(pwndLoop)) {
    00342             fClipSiblings = FALSE;
    00343         }
    00344
    00345         /*
    00346          * Exclude any siblings if necessary.
    00347          */
    00348         if (fClipSiblings && (pwndParent->spwndChild != pwndLoop)) {
    00349
    00350             if (!ExcludeWindowRects(pwndParent->spwndChild,
    00351                                     pwndLoop,
    00352                                     &rcWindow)) {
    00353
    00354                 goto NullRegion;
    00355             }
    00356         }
    00357
    00358
    00359         /*
    00360          * Set this flag for next time through the loop...
    00361          */
    00362         fClipSiblings = TestWF(pwndParent, WFCLIPSIBLINGS);
    00363
    00364         pwndLoop      = pwndParent;
    00365         pwndParent    = pwndLoop->spwndParent;
    00366     }
    00367
    00368     if ((flags & DCX_CLIPCHILDREN) && (pwnd->spwndChild != NULL)) {
    00369
    00370         if (!ExcludeWindowRects(pwnd->spwndChild, NULL, &rcWindow)) {
    00371             goto NullRegion;
    00372         }
    00373     }
    00374
    00375     /*
    00376      * If there are rectangles to exclude call GDI to create
    00377      * a region excluding them from the window rectangle.  If
    00378      * not simply call GreSetRectRgn().
    00379      */
    00380     if (gcrcVisExclude > 0) {
    00381
    00382         RECT  arcVisRects[CEXCLUDERECTSMAX];
    00383         PRECT arcExclude;
    00384         int   i;
    00385         int   ircVisExclude  = 0;
    00386         int   irgnVisExclude = 0;
    00387
    00388         /*
    00389          * If we need to exclude more rectangles than fit in
    00390          * the pre-allocated buffer, obviously we have to
    00391          * allocate one that's big enough.
    00392          */
    00393
    00394         if (gcrcVisExclude <= CEXCLUDERECTSMAX) {
    00395             arcExclude = arcVisRects;
    00396         } else {
    00397             arcExclude = (PRECT)UserAllocPoolWithQuota(
    00398                     sizeof(RECT) * gcrcVisExclude, TAG_VISRGN);
    00399
    00400             if (!arcExclude)
    00401                 goto NullRegion;
    00402         }
    00403
    00404         /*
    00405          * Now run through the list and put the
    00406          * window rectangles into the array for the call
    00407          * to CombineRgnRectList().
    00408          */
    00409         for (i = 0; i < gcrcVisExclude; i++) {
    00410
    00411             /*
    00412              * If the window has a clip-rgn associated with
    00413              * it, then re-use gpwneExcludeList[] entries for
    00414              * storing them.
    00415              */
    00416             if (gapwndVisExclude[i]->hrgnClip != NULL) {
    00417
    00418                 gapwndVisExclude[irgnVisExclude++] = gapwndVisExclude[i];
    00419                 continue;
    00420             }
    00421
    00422             /*
    00423              * This window doesn't have a clipping region; remember its
    00424              * rect for clipping purposes.
    00425              */
    00426             arcExclude[ircVisExclude++] = gapwndVisExclude[i]->rcWindow;
    00427         }
    00428
    00429         if (*phrgn == NULL)
    00430             *phrgn = CreateEmptyRgn();
    00431
    00432         if (ircVisExclude != 0) {
    00433             GreSubtractRgnRectList(*phrgn,
    00434                                    &rcWindow,
    00435                                    arcExclude,
    00436                                    ircVisExclude);
    00437         } else {
    00438             SetRectRgnIndirect(*phrgn, &rcWindow);
    00439         }
    00440
    00441         for (i = 0; i < irgnVisExclude; i++) {
    00442
    00443             SetRectRgnIndirect(ghrgnInv2, &gapwndVisExclude[i]->rcWindow);
    00444             IntersectRgn(ghrgnInv2, ghrgnInv2, gapwndVisExclude[i]->hrgnClip);
    00445
    00446             if (SubtractRgn(*phrgn, *phrgn, ghrgnInv2) == NULLREGION)
    00447                 break;
    00448         }
    00449
    00450         if (arcExclude != arcVisRects) {
    00451             UserFreePool((HLOCAL)arcExclude);
    00452         }
    00453
    00454     } else {
    00455
    00456         /*
    00457          * If the window was somehow destroyed, then we will return
    00458          * a null-region.  Emptying the rect will accomplish this.
    00459          */
    00460         if (TestWF(pwnd, WFDESTROYED)) {
    00461             SetRectEmpty(&rcWindow);
    00462         }
    00463
    00464         /*
    00465          * If there weren't any rectangles to exclude, simply call
    00466          * GreSetRectRgn() with the window rectangle.
    00467          */
    00468         SetOrCreateRectRgnIndirectPublic(phrgn, &rcWindow);
    00469     }
    00470
    00471     /*
    00472      * Clip out this window's window region
    00473      */
    00474     if (pwnd->hrgnClip != NULL) {
    00475         IntersectRgn(*phrgn, *phrgn, pwnd->hrgnClip);
    00476     }
    00477
    00478     /*
    00479      * Clip out parent's window regions, if there are any.
    00480      */
    00481     if (fRgnParent) {
    00482
    00483         PWND pwndT;
    00484
    00485         for (pwndT = pwnd->spwndParent;
    00486                 pwndT != pwndRoot;
    00487                 pwndT = pwndT->spwndParent) {
    00488
    00489             if (pwndT->hrgnClip != NULL) {
    00490
    00491                 if (IntersectRgn(*phrgn, *phrgn, pwndT->hrgnClip) == NULLREGION)
    00492                     break;
    00493             }
    00494         }
    00495     }
    00496
    00497     fResult = TRUE;
    00498     // fall-through
    00499
    00500 Cleanup:
    00501     if (gfVisAlloc) {
    00502         UserFreePool((HLOCAL)gapwndVisExclude);
    00503         gfVisAlloc = FALSE;
    00504     }
    00505
    00506     return fResult;
    00507
    00508 NullRegion:
    00509     SetOrCreateRectRgnIndirectPublic(phrgn, PZERO(RECT));
    00510     fResult = FALSE;
    00511     goto Cleanup;
    00512 }

HRGN CreateEmptyRgn | ( | void |  | ) |

Definition at line 57 of file visrgn.c.

References PZERO.

Referenced by _GetDCEx(), BltValidInit(), CalcWindowVisRgn(), CenterWallpaper(), CreateEmptyRgnPublic(), GetMonitorDC(), InternalScrollDC(), NtUserGetDC(), PreventInterMonitorBlts(), ResetSharedDesktops(), UserValidateCopyRgn(), xxxBeginPaint(), xxxCreateDisconnectDesktop(), xxxMenuBarDraw(), xxxMNInvertItem(), and xxxRedrawHungWindow().

    00058 {
    00059     return GreCreateRectRgnIndirect(PZERO(RECT));
    00060 }

HRGN CreateEmptyRgnPublic | ( | void |  | ) |

Definition at line 74 of file visrgn.c.

References CreateEmptyRgn().

Referenced by _GetDCEx(), GetNCUpdateRgn(), InitUserScreen(), and InternalInvalidate3().

    00075 {
    00076     HRGN hrgn;
    00077
    00078     if (hrgn = CreateEmptyRgn()) {
    00079         UserVerify(GreSetRegionOwner(hrgn, OBJECT_OWNER_PUBLIC));
    00080     }
    00081
    00082     return hrgn;
    00083 }

BOOL ExcludeWindowRects | ( | PWND | pwnd,
|  | PWND | pwndStop,
|  | LPRECT | lprcIntersect
| ) |

Definition at line 198 of file visrgn.c.

References BOOL, CheckIntersectRect, EmptyRect, FALSE, FLayeredOrRedirected(), gapwndVisExclude, gcrcVisExclude, gcrcVisExcludeMax, NULL, tagWND::rcWindow, ResizeVisExcludeMemory(), tagWND::spwndNext, tagWND::spwndParent, TestWF, TRUE, WEFTRANSPARENT, and WFVISIBLE.

Referenced by CalcWindowVisRgn().

    00202 {
    00203     PRECT prc;
    00204
    00205 #if DBG
    00206     if (pwnd != NULL && pwndStop != NULL &&
    00207             pwnd->spwndParent != pwndStop->spwndParent) {
    00208         RIPMSG0(RIP_ERROR, "ExcludeWindowRects: bad windows passed in");
    00209     }
    00210 #endif
    00211
    00212     while ((pwnd != NULL) && (pwnd != pwndStop)) {
    00213         UserAssert(pwnd);
    00214         prc = &pwnd->rcWindow;
    00215         if (       TestWF(pwnd, WFVISIBLE)
    00216                 && !FLayeredOrRedirected(pwnd)
    00217                 && (TestWF(pwnd, WEFTRANSPARENT) == 0)
    00218                 && CheckIntersectRect(lprcIntersect, prc)
    00219                 && !EmptyRect(prc)) {
    00220
    00221             UserAssert(gcrcVisExclude <= gcrcVisExcludeMax);
    00222             if (gcrcVisExclude == gcrcVisExcludeMax) {
    00223                 if (!ResizeVisExcludeMemory()) {
    00224                     return FALSE;
    00225                 }
    00226             }
    00227
    00228             gapwndVisExclude[gcrcVisExclude++] = pwnd;
    00229         }
    00230
    00231         pwnd = pwnd->spwndNext;
    00232     }
    00233
    00234     return TRUE;
    00235 }

BOOL ResizeVisExcludeMemory | ( | VOID |  | ) |

Definition at line 140 of file visrgn.c.

References BOOL, CEXCLUDEPWNDSMAX, FALSE, gapwndVisExclude, gcrcVisExclude, gcrcVisExcludeMax, gfVisAlloc, PWND, and TRUE.

Referenced by ExcludeWindowRects().

    00141 {
    00142     int     crcNew;
    00143     PWND    apwndNew;
    00144
    00145     /*
    00146      * Note (adams): a previous version of the code called UserReallocPool
    00147      * if memory had already been allocated. Unfortunately, UserReallocPool
    00148      * just has to allocate more memory and copy the contents, since Rtl
    00149      * doesn't have a realloc function. If Rtl later gains a Realloc function,
    00150      * this code should be changed to the previous version.
    00151      */
    00152
    00153     crcNew = gcrcVisExcludeMax + CEXCLUDEPWNDSMAX;
    00154     apwndNew = (PWND)UserAllocPool(
    00155             crcNew * sizeof(PWND), TAG_VISRGN);
    00156
    00157     if (!apwndNew)
    00158         return FALSE;
    00159
    00160     UserAssert(gcrcVisExcludeMax == gcrcVisExclude);
    00161     RtlCopyMemory(apwndNew, gapwndVisExclude, gcrcVisExcludeMax * sizeof(PWND));
    00162     if (gfVisAlloc) {
    00163         UserFreePool(gapwndVisExclude);
    00164     } else {
    00165         gfVisAlloc = TRUE;
    00166     }
    00167
    00168     gcrcVisExcludeMax = crcNew;
    00169     gapwndVisExclude = (PWND *)apwndNew;
    00170     return TRUE;
    00171 }

BOOL SetEmptyRgn | ( | HRGN | hrgn | ) |

Definition at line 97 of file visrgn.c.

References PZERO, and SetRectRgnIndirect().

Referenced by _GetDCEx(), InternalScrollDC(), UserSetDCVisRgn(), xxxGetUpdateRgn(), xxxInternalInvalidate(), and xxxScrollWindowEx().

    00098 {
    00099     return SetRectRgnIndirect(hrgn, PZERO(RECT));
    00100 }

HRGN SetOrCreateRectRgnIndirectPublic | ( | HRGN * | phrgn,
|  | LPCRECT | lprc
| ) |

Definition at line 115 of file visrgn.c.

References SetRectRgnIndirect().

Referenced by CalcVisRgn(), CalcWindowVisRgn(), SpbCheckRect2(), and UpdateUserScreen().

    00116 {
    00117     if (*phrgn) {
    00118         UserVerify(SetRectRgnIndirect(*phrgn, lprc));
    00119     } else if (*phrgn = GreCreateRectRgnIndirect((LPRECT) lprc)) {
    00120         UserVerify(GreSetRegionOwner(*phrgn, OBJECT_OWNER_PUBLIC));
    00121     }
    00122
    00123     return *phrgn;
    00124 }

BOOL SetRectRgnIndirect | ( | HRGN | hrgn,
|  | LPCRECT | lprc
| ) |

Definition at line 40 of file visrgn.c.

Referenced by CalcWindowRgn(), CalcWindowVisRgn(), CreateSpb(), InternalInvalidate2(), InternalScrollDC(), LockWindowUpdate2(), RestoreSpb(), SetEmptyRgn(), SetOrCreateRectRgnIndirectPublic(), SmartRectInRegion(), SpbCheckRect2(), ValidateParents(), xxxGetUpdateRgn(), xxxRedrawHungWindow(), xxxRedrawWindow(), and zzzBltValidBits().

    00041 {
    00042     return GreSetRectRgn(hrgn, lprc->left, lprc->top, lprc->right, lprc->bottom);
    00043 }

## Variable Documentation

PWND* gapwndVisDefault

| Definition at line 28 of file visrgn.c. Referenced by CalcWindowVisRgn().

PWND* gapwndVisExclude

| Definition at line 27 of file visrgn.c. Referenced by CalcWindowVisRgn(), ExcludeWindowRects(), and ResizeVisExcludeMemory().

int gcrcVisExclude

| Definition at line 25 of file visrgn.c. Referenced by CalcWindowVisRgn(), ExcludeWindowRects(), and ResizeVisExcludeMemory().

int gcrcVisExcludeMax

| Definition at line 26 of file visrgn.c. Referenced by CalcWindowVisRgn(), ExcludeWindowRects(), and ResizeVisExcludeMemory().

BOOL gfVisAlloc

| Definition at line 24 of file visrgn.c. Referenced by CalcWindowVisRgn(), and ResizeVisExcludeMemory().