VOID FASTCALL co_VIS_WindowLayoutChanged( PWND Wnd, PREGION NewlyExposed) { PWND Parent; USER_REFERENCE_ENTRY Ref; ASSERT_REFS_CO(Wnd); Parent = Wnd->spwndParent; if(Parent) { PREGION TempRgn = IntSysCreateRectpRgn(0, 0, 0, 0); if (!TempRgn) return; IntGdiCombineRgn(TempRgn, NewlyExposed, NULL, RGN_COPY); REGION_bOffsetRgn(TempRgn, Wnd->rcWindow.left - Parent->rcClient.left, Wnd->rcWindow.top - Parent->rcClient.top); UserRefObjectCo(Parent, &Ref); co_UserRedrawWindow(Parent, NULL, TempRgn, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN); UserDerefObjectCo(Parent); REGION_Delete(TempRgn); } }
VOID FASTCALL GdiSelectVisRgn( HDC hdc, PREGION prgn) { DC *dc; if (!(dc = DC_LockDc(hdc))) { EngSetLastError(ERROR_INVALID_HANDLE); return; } dc->fs |= DC_FLAG_DIRTY_RAO; ASSERT(dc->prgnVis != NULL); ASSERT(prgn != NULL); IntGdiCombineRgn(dc->prgnVis, prgn, NULL, RGN_COPY); REGION_bOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y); DC_UnlockDc(dc); }
PREGION FASTCALL VIS_ComputeVisibleRegion( PWND Wnd, BOOLEAN ClientArea, BOOLEAN ClipChildren, BOOLEAN ClipSiblings) { PREGION VisRgn, ClipRgn; PWND PreviousWindow, CurrentWindow, CurrentSibling; if (!Wnd || !(Wnd->style & WS_VISIBLE)) { return NULL; } VisRgn = NULL; if (ClientArea) { VisRgn = IntSysCreateRectpRgnIndirect(&Wnd->rcClient); } else { VisRgn = IntSysCreateRectpRgnIndirect(&Wnd->rcWindow); } /* * Walk through all parent windows and for each clip the visble region * to the parent's client area and exclude all siblings that are over * our window. */ PreviousWindow = Wnd; CurrentWindow = Wnd->spwndParent; while (CurrentWindow) { if (!VerifyWnd(CurrentWindow)) { ERR("ATM the Current Window or Parent is dead! %p\n",CurrentWindow); if (VisRgn) REGION_Delete(VisRgn); return NULL; } if (!(CurrentWindow->style & WS_VISIBLE)) { if (VisRgn) REGION_Delete(VisRgn); return NULL; } ClipRgn = IntSysCreateRectpRgnIndirect(&CurrentWindow->rcClient); IntGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_AND); REGION_Delete(ClipRgn); if ((PreviousWindow->style & WS_CLIPSIBLINGS) || (PreviousWindow == Wnd && ClipSiblings)) { CurrentSibling = CurrentWindow->spwndChild; while ( CurrentSibling != NULL && CurrentSibling != PreviousWindow ) { if ((CurrentSibling->style & WS_VISIBLE) && !(CurrentSibling->ExStyle & WS_EX_TRANSPARENT)) { ClipRgn = IntSysCreateRectpRgnIndirect(&CurrentSibling->rcWindow); /* Combine it with the window region if available */ if (CurrentSibling->hrgnClip && !(CurrentSibling->style & WS_MINIMIZE)) { PREGION SiblingClipRgn = REGION_LockRgn(CurrentSibling->hrgnClip); if (SiblingClipRgn) { REGION_bOffsetRgn(ClipRgn, -CurrentSibling->rcWindow.left, -CurrentSibling->rcWindow.top); IntGdiCombineRgn(ClipRgn, ClipRgn, SiblingClipRgn, RGN_AND); REGION_bOffsetRgn(ClipRgn, CurrentSibling->rcWindow.left, CurrentSibling->rcWindow.top); REGION_UnlockRgn(SiblingClipRgn); } } IntGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF); REGION_Delete(ClipRgn); } CurrentSibling = CurrentSibling->spwndNext; } } PreviousWindow = CurrentWindow; CurrentWindow = CurrentWindow->spwndParent; } if (ClipChildren) { CurrentWindow = Wnd->spwndChild; while (CurrentWindow) { if ((CurrentWindow->style & WS_VISIBLE) && !(CurrentWindow->ExStyle & WS_EX_TRANSPARENT)) { ClipRgn = IntSysCreateRectpRgnIndirect(&CurrentWindow->rcWindow); /* Combine it with the window region if available */ if (CurrentWindow->hrgnClip && !(CurrentWindow->style & WS_MINIMIZE)) { PREGION CurrentRgnClip = REGION_LockRgn(CurrentWindow->hrgnClip); if (CurrentRgnClip) { REGION_bOffsetRgn(ClipRgn, -CurrentWindow->rcWindow.left, -CurrentWindow->rcWindow.top); IntGdiCombineRgn(ClipRgn, ClipRgn, CurrentRgnClip, RGN_AND); REGION_bOffsetRgn(ClipRgn, CurrentWindow->rcWindow.left, CurrentWindow->rcWindow.top); REGION_UnlockRgn(CurrentRgnClip); } } IntGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF); REGION_Delete(ClipRgn); } CurrentWindow = CurrentWindow->spwndNext; } } if (Wnd->hrgnClip && !(Wnd->style & WS_MINIMIZE)) { PREGION WndRgnClip = REGION_LockRgn(Wnd->hrgnClip); if (WndRgnClip) { REGION_bOffsetRgn(VisRgn, -Wnd->rcWindow.left, -Wnd->rcWindow.top); IntGdiCombineRgn(VisRgn, VisRgn, WndRgnClip, RGN_AND); REGION_bOffsetRgn(VisRgn, Wnd->rcWindow.left, Wnd->rcWindow.top); REGION_UnlockRgn(WndRgnClip); } } return VisRgn; }
VOID FASTCALL DceResetActiveDCEs(PWND Window) { DCE *pDCE; PDC dc; PWND CurrentWindow; INT DeltaX; INT DeltaY; PLIST_ENTRY ListEntry; if (NULL == Window) { return; } ListEntry = LEDce.Flink; while (ListEntry != &LEDce) { pDCE = CONTAINING_RECORD(ListEntry, DCE, List); ListEntry = ListEntry->Flink; if (0 == (pDCE->DCXFlags & (DCX_DCEEMPTY|DCX_INDESTROY))) { if (Window->head.h == pDCE->hwndCurrent) { CurrentWindow = Window; } else { if (!pDCE->hwndCurrent) CurrentWindow = NULL; else CurrentWindow = UserGetWindowObject(pDCE->hwndCurrent); if (NULL == CurrentWindow) { continue; } } if (!GreIsHandleValid(pDCE->hDC) || (dc = DC_LockDc(pDCE->hDC)) == NULL) { continue; } if (Window == CurrentWindow || IntIsChildWindow(Window, CurrentWindow)) { if (pDCE->DCXFlags & DCX_WINDOW) { DeltaX = CurrentWindow->rcWindow.left - dc->ptlDCOrig.x; DeltaY = CurrentWindow->rcWindow.top - dc->ptlDCOrig.y; dc->ptlDCOrig.x = CurrentWindow->rcWindow.left; dc->ptlDCOrig.y = CurrentWindow->rcWindow.top; } else { DeltaX = CurrentWindow->rcClient.left - dc->ptlDCOrig.x; DeltaY = CurrentWindow->rcClient.top - dc->ptlDCOrig.y; dc->ptlDCOrig.x = CurrentWindow->rcClient.left; dc->ptlDCOrig.y = CurrentWindow->rcClient.top; } if (NULL != dc->dclevel.prgnClip) { REGION_bOffsetRgn(dc->dclevel.prgnClip, DeltaX, DeltaY); dc->fs |= DC_FLAG_DIRTY_RAO; } if (NULL != pDCE->hrgnClip) { NtGdiOffsetRgn(pDCE->hrgnClip, DeltaX, DeltaY); } } DC_UnlockDc(dc); DceUpdateVisRgn(pDCE, CurrentWindow, pDCE->DCXFlags); IntGdiSetHookFlags(pDCE->hDC, DCHF_VALIDATEVISRGN); } } }