INT FASTCALL GdiSelectVisRgn(HDC hdc, HRGN hrgn) { int retval; DC *dc; PREGION prgn; if (!hrgn) { EngSetLastError(ERROR_INVALID_PARAMETER); return ERROR; } if (!(dc = DC_LockDc(hdc))) { EngSetLastError(ERROR_INVALID_HANDLE); return ERROR; } dc->fs &= ~DC_FLAG_DIRTY_RAO; ASSERT (dc->prgnVis != NULL); prgn = RGNOBJAPI_Lock(hrgn, NULL); retval = prgn ? IntGdiCombineRgn(dc->prgnVis, prgn, NULL, RGN_COPY) : ERROR; RGNOBJAPI_Unlock(prgn); if ( retval != ERROR ) { IntGdiOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y); CLIPPING_UpdateGCRegion(dc); } DC_UnlockDc(dc); return retval; }
INT FASTCALL NEW_CLIPPING_UpdateGCRegion(PDC pDC) { CLIPOBJ * co; /* Must have VisRgn set to a valid state! */ ASSERT (pDC->prgnVis); if (pDC->prgnAPI) { REGION_Delete(pDC->prgnAPI); pDC->prgnAPI = IntSysCreateRectpRgn(0,0,0,0); } if (pDC->prgnRao) { REGION_Delete(pDC->prgnRao); pDC->prgnRao = IntSysCreateRectpRgn(0,0,0,0); } if (pDC->dclevel.prgnMeta && pDC->dclevel.prgnClip) { IntGdiCombineRgn( pDC->prgnAPI, pDC->dclevel.prgnClip, pDC->dclevel.prgnMeta, RGN_AND); } else { if (pDC->dclevel.prgnClip) { IntGdiCombineRgn( pDC->prgnAPI, pDC->dclevel.prgnClip, NULL, RGN_COPY); } else if (pDC->dclevel.prgnMeta) { IntGdiCombineRgn( pDC->prgnAPI, pDC->dclevel.prgnMeta, NULL, RGN_COPY); } } IntGdiCombineRgn( pDC->prgnRao, pDC->prgnVis, pDC->prgnAPI, RGN_AND); RtlCopyMemory(&pDC->erclClip, &((PROSRGNDATA)pDC->prgnRao)->rdh.rcBound, sizeof(RECTL)); pDC->fs &= ~DC_FLAG_DIRTY_RAO; IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y); // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build // the rects from region objects rects in pClipRgn->Buffer. // With pDC->co.pClipRgn->Buffer, // pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis; co = IntEngCreateClipRegion( ((PROSRGNDATA)pDC->prgnRao)->rdh.nCount, ((PROSRGNDATA)pDC->prgnRao)->Buffer, &pDC->erclClip); if (co) { if (pDC->rosdc.CombinedClip != NULL) IntEngDeleteClipRegion(pDC->rosdc.CombinedClip); pDC->rosdc.CombinedClip = co; } return IntGdiOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y); }
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) { IntGdiOffsetRgn(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); } } }