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
PWNDgapwndVisExclude
PWNDgapwndVisDefault


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().


Generated on Sat May 15 19:46:08 2004 for test by doxygen 1.3.7