int APIENTRY NtGdiExcludeClipRect(HDC hDC, int LeftRect, int TopRect, int RightRect, int BottomRect) { INT Result; RECTL Rect; PREGION prgnNew, prgnClip; PDC dc = DC_LockDc(hDC); if (!dc) { EngSetLastError(ERROR_INVALID_HANDLE); return ERROR; } Rect.left = LeftRect; Rect.top = TopRect; Rect.right = RightRect; Rect.bottom = BottomRect; IntLPtoDP(dc, (LPPOINT)&Rect, 2); prgnNew = IntSysCreateRectpRgnIndirect(&Rect); if (!prgnNew) { Result = ERROR; } else { if (!dc->rosdc.hClipRgn) { dc->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0); prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn); IntGdiCombineRgn(prgnClip, dc->prgnVis, prgnNew, RGN_DIFF); REGION_UnlockRgn(prgnClip); Result = SIMPLEREGION; } else { prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn); Result = IntGdiCombineRgn(prgnClip, prgnClip, prgnNew, RGN_DIFF); REGION_UnlockRgn(prgnClip); } REGION_Delete(prgnNew); } if (Result != ERROR) CLIPPING_UpdateGCRegion(dc); DC_UnlockDc(dc); return Result; }
int FASTCALL IntGdiExtSelectClipRgn( PDC dc, PREGION prgn, int fnMode) { if (fnMode == RGN_COPY) { if (!prgn) { if (dc->dclevel.prgnClip != NULL) { REGION_Delete(dc->dclevel.prgnClip); dc->dclevel.prgnClip = NULL; dc->fs |= DC_FLAG_DIRTY_RAO; } return SIMPLEREGION; } if (!dc->dclevel.prgnClip) dc->dclevel.prgnClip = IntSysCreateRectpRgn(0, 0, 0, 0); dc->fs |= DC_FLAG_DIRTY_RAO; return IntGdiCombineRgn(dc->dclevel.prgnClip, prgn, NULL, RGN_COPY); } ASSERT(prgn != NULL); if (!dc->dclevel.prgnClip) { RECTL rect; REGION_GetRgnBox(dc->prgnVis, &rect); dc->dclevel.prgnClip = IntSysCreateRectpRgnIndirect(&rect); } dc->fs |= DC_FLAG_DIRTY_RAO; return IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, prgn, fnMode); }
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 DceUpdateVisRgn(DCE *Dce, PWND Window, ULONG Flags) { PREGION RgnVisible = NULL; ULONG DcxFlags; PWND DesktopWindow; if (Flags & DCX_PARENTCLIP) { PWND Parent; Parent = Window->spwndParent; if (!Parent) { RgnVisible = NULL; goto noparent; } if (Parent->style & WS_CLIPSIBLINGS) { DcxFlags = DCX_CLIPSIBLINGS | (Flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW)); } else { DcxFlags = Flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW); } RgnVisible = DceGetVisRgn(Parent, DcxFlags, Window->head.h, Flags); } else if (Window == NULL) { DesktopWindow = UserGetWindowObject(IntGetDesktopWindow()); if (NULL != DesktopWindow) { RgnVisible = IntSysCreateRectpRgnIndirect(&DesktopWindow->rcWindow); } else { RgnVisible = NULL; } } else { RgnVisible = DceGetVisRgn(Window, Flags, 0, 0); } noparent: if (Flags & DCX_INTERSECTRGN) { PREGION RgnClip = NULL; if (Dce->hrgnClip != NULL) RgnClip = REGION_LockRgn(Dce->hrgnClip); if (RgnClip) { IntGdiCombineRgn(RgnVisible, RgnVisible, RgnClip, RGN_AND); REGION_UnlockRgn(RgnClip); } else { if (RgnVisible != NULL) { REGION_Delete(RgnVisible); } RgnVisible = IntSysCreateRectpRgn(0, 0, 0, 0); } } else if ((Flags & DCX_EXCLUDERGN) && Dce->hrgnClip != NULL) { PREGION RgnClip = REGION_LockRgn(Dce->hrgnClip); IntGdiCombineRgn(RgnVisible, RgnVisible, RgnClip, RGN_DIFF); REGION_UnlockRgn(RgnClip); } Dce->DCXFlags &= ~DCX_DCEDIRTY; GdiSelectVisRgn(Dce->hDC, RgnVisible); /* Tell GDI driver */ if (Window) IntEngWindowChanged(Window, WOC_RGN_CLIENT); if (RgnVisible != NULL) { REGION_Delete(RgnVisible); } }