DWORD APIENTRY NtGdiSetBoundsRect( IN HDC hdc, IN LPRECT prc, IN DWORD flags) { DWORD ret; PDC pdc; RECTL rcl; /* Verify arguments */ if ((flags & DCB_ENABLE) && (flags & DCB_DISABLE)) return 0; /* Lock the DC */ if (!(pdc = DC_LockDc(hdc))) return 0; /* Get the return value */ ret = pdc->fs & DC_ACCUM_APP ? DCB_ENABLE : DCB_DISABLE; ret |= RECTL_bIsEmptyRect(&pdc->erclBoundsApp) ? DCB_RESET : DCB_SET; if (flags & DCB_RESET) { RECTL_vSetEmptyRect(&pdc->erclBoundsApp); } if (flags & DCB_ACCUMULATE && prc != NULL) { /* Capture the rect */ _SEH2_TRY { ProbeForRead(prc, sizeof(RECT), 1); rcl = *prc; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { DC_UnlockDc(pdc); _SEH2_YIELD(return 0;) } _SEH2_END; RECTL_vMakeWellOrdered(&rcl); RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, &rcl); }
DWORD APIENTRY NtGdiGetBoundsRect( IN HDC hdc, OUT LPRECT prc, IN DWORD flags) { DWORD ret; PDC pdc; /* Lock the DC */ if (!(pdc = DC_LockDc(hdc))) return 0; /* Get the return value */ ret = pdc->fs & DC_ACCUM_APP ? DCB_ENABLE : DCB_DISABLE; ret |= RECTL_bIsEmptyRect(&pdc->erclBoundsApp) ? DCB_RESET : DCB_SET; /* Copy the rect to the caller */ _SEH2_TRY { ProbeForWrite(prc, sizeof(RECT), 1); *prc = pdc->erclBoundsApp; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ret = 0; } _SEH2_END; if (flags & DCB_RESET) { RECTL_vSetEmptyRect(&pdc->erclBoundsApp); } DC_UnlockDc(pdc); return ret; }
DWORD APIENTRY NtGdiSetBoundsRect( IN HDC hdc, IN LPRECT prc, IN DWORD flags) { DWORD ret; PDC pdc; RECTL rcl; /* Verify arguments */ if ((flags & DCB_ENABLE) && (flags & DCB_DISABLE)) return 0; /* Lock the DC */ if (!(pdc = DC_LockDc(hdc))) return 0; /* Get the return value */ ret = DCB_RESET; /* we don't have device-specific bounds */ ret = (pdc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR) ? DCB_ENABLE : DCB_DISABLE) | (RECTL_bIsEmptyRect(&pdc->erclBoundsApp) ? ret & DCB_SET : DCB_SET ); ret |= (flags & DCB_WINDOWMGR); if (flags & DCB_RESET) { if (!(flags & DCB_WINDOWMGR)) { pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX; pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN; } else { pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX; pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN; } } if (flags & DCB_ACCUMULATE && prc != NULL) { /* Capture the rect */ _SEH2_TRY { ProbeForRead(prc, sizeof(RECT), 1); rcl = *prc; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { DC_UnlockDc(pdc); _SEH2_YIELD(return 0;) } _SEH2_END; RECTL_vMakeWellOrdered(&rcl); if (!(flags & DCB_WINDOWMGR)) { IntLPtoDP( pdc, (POINT *)&rcl, 2 ); RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, &rcl); } else RECTL_bUnionRect(&pdc->erclBounds, &pdc->erclBounds, &rcl); }
DWORD APIENTRY NtGdiGetBoundsRect( IN HDC hdc, OUT LPRECT prc, IN DWORD flags) { DWORD ret; PDC pdc; RECT rc; /* Lock the DC */ if (!(pdc = DC_LockDc(hdc))) return 0; if (!(flags & DCB_WINDOWMGR)) { rc = pdc->erclBoundsApp; if (RECTL_bIsEmptyRect(&rc)) { rc.left = rc.top = rc.right = rc.bottom = 0; ret = DCB_RESET; } else { RECTL rcRgn; if (pdc->fs & DC_FLAG_DIRTY_RAO) CLIPPING_UpdateGCRegion(pdc); if(!REGION_GetRgnBox(pdc->prgnRao, &rcRgn)) { REGION_GetRgnBox(pdc->prgnVis, &rcRgn); } rc.left = max( rc.left, 0 ); rc.top = max( rc.top, 0 ); rc.right = min( rc.right, rcRgn.right - rcRgn.left ); rc.bottom = min( rc.bottom, rcRgn.bottom - rcRgn.top ); DPRINT("Rao dc %p r %d b %d\n",pdc,rcRgn.right - rcRgn.left, rcRgn.bottom - rcRgn.top); DPRINT("rc l %d t %d\n",rc.left,rc.top); DPRINT(" r %d b %d\n",rc.right,rc.bottom); ret = DCB_SET; } IntDPtoLP( pdc, &rc, 2 ); DPRINT("rc1 l %d t %d\n",rc.left,rc.top); DPRINT(" r %d b %d\n",rc.right,rc.bottom); } else { rc = pdc->erclBounds; ret = DCB_SET; } /* Copy the rect to the caller */ _SEH2_TRY { ProbeForWrite(prc, sizeof(RECT), 1); *prc = rc; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ret = 0; } _SEH2_END; if (flags & DCB_RESET) { if (!(flags & DCB_WINDOWMGR)) { pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX; pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN; } else { pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX; pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN; } } DC_UnlockDc(pdc); return ret; }
/* * @implemented */ BOOL APIENTRY EngCopyBits( _In_ SURFOBJ *psoDest, _In_ SURFOBJ *psoSource, _In_opt_ CLIPOBJ *Clip, _In_opt_ XLATEOBJ *ColorTranslation, _In_ RECTL *DestRect, _In_ POINTL *SourcePoint) { BOOL ret; BYTE clippingType; RECT_ENUM RectEnum; BOOL EnumMore; BLTINFO BltInfo; SURFACE *psurfDest; SURFACE *psurfSource; RECTL rclDest = *DestRect; POINTL ptlSrc = *SourcePoint; ASSERT(psoDest != NULL && psoSource != NULL && DestRect != NULL && SourcePoint != NULL); psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj); psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj); /* Clip dest rect against source surface size / source point */ if (psoSource->sizlBitmap.cx - ptlSrc.x < rclDest.right - rclDest.left) rclDest.right = rclDest.left + psoSource->sizlBitmap.cx - ptlSrc.x; if (psoSource->sizlBitmap.cy - ptlSrc.y < rclDest.bottom - rclDest.top) rclDest.bottom = rclDest.top + psoSource->sizlBitmap.cy - ptlSrc.y; /* Clip dest rect against target surface size */ if (rclDest.right > psoDest->sizlBitmap.cx) rclDest.right = psoDest->sizlBitmap.cx; if (rclDest.bottom > psoDest->sizlBitmap.cy) rclDest.bottom = psoDest->sizlBitmap.cy; if (RECTL_bIsEmptyRect(&rclDest)) return TRUE; DestRect = &rclDest; // FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead, // mark the copy block function to be DrvCopyBits instead of the // GDI's copy bit function so as to remove clipping from the // driver's responsibility // If one of the surfaces isn't managed by the GDI if ((psoDest->iType!=STYPE_BITMAP) || (psoSource->iType!=STYPE_BITMAP)) { // Destination surface is device managed if (psoDest->iType!=STYPE_BITMAP) { /* FIXME: Eng* functions shouldn't call Drv* functions. ? */ if (psurfDest->flags & HOOK_COPYBITS) { ret = GDIDEVFUNCS(psoDest).CopyBits( psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint); goto cleanup; } } // Source surface is device managed if (psoSource->iType!=STYPE_BITMAP) { /* FIXME: Eng* functions shouldn't call Drv* functions. ? */ if (psurfSource->flags & HOOK_COPYBITS) { ret = GDIDEVFUNCS(psoSource).CopyBits( psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint); goto cleanup; } } // If CopyBits wasn't hooked, BitBlt must be ret = IntEngBitBlt(psoDest, psoSource, NULL, Clip, ColorTranslation, DestRect, SourcePoint, NULL, NULL, NULL, ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY)); goto cleanup; } // Determine clipping type if (!Clip) { clippingType = DC_TRIVIAL; } else { clippingType = Clip->iDComplexity; } BltInfo.DestSurface = psoDest; BltInfo.SourceSurface = psoSource; BltInfo.PatternSurface = NULL; BltInfo.XlateSourceToDest = ColorTranslation; BltInfo.Rop4 = ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY); switch (clippingType) { case DC_TRIVIAL: BltInfo.DestRect = *DestRect; BltInfo.SourcePoint = *SourcePoint; ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo); break; case DC_RECT: // Clip the blt to the clip rectangle RECTL_bIntersectRect(&BltInfo.DestRect, DestRect, &Clip->rclBounds); BltInfo.SourcePoint.x = SourcePoint->x + BltInfo.DestRect.left - DestRect->left; BltInfo.SourcePoint.y = SourcePoint->y + BltInfo.DestRect.top - DestRect->top; ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo); break; case DC_COMPLEX: CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, 0); do { EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum); if (RectEnum.c > 0) { RECTL* prclEnd = &RectEnum.arcl[RectEnum.c]; RECTL* prcl = &RectEnum.arcl[0]; do { RECTL_bIntersectRect(&BltInfo.DestRect, prcl, DestRect); BltInfo.SourcePoint.x = SourcePoint->x + BltInfo.DestRect.left - DestRect->left; BltInfo.SourcePoint.y = SourcePoint->y + BltInfo.DestRect.top - DestRect->top; if (!DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo)) { ret = FALSE; goto cleanup; } prcl++; } while (prcl < prclEnd); } } while (EnumMore); ret = TRUE; break; default: ASSERT(FALSE); ret = FALSE; break; } cleanup: return ret; }
void IntDrawScrollBar(PWND Wnd, HDC DC, INT Bar) { //PSBWND pSBWnd; //INT ThumbSize; PTHREADINFO pti; SCROLLBARINFO Info; BOOL Vertical; pti = PsGetCurrentThreadWin32Thread(); /* * Get scroll bar info. */ switch (Bar) { case SB_HORZ: Vertical = FALSE; break; case SB_VERT: Vertical = TRUE; break; case SB_CTL: Vertical = (Wnd->style & SBS_VERT) != 0; break; default: return; } if (!co_IntGetScrollBarInfo(Wnd, IntScrollGetObjectId(Bar), &Info)) { return; } if (RECTL_bIsEmptyRect(&Info.rcScrollBar)) { return; } //ThumbSize = pSBWnd->pSBCalc->pxThumbBottom - pSBWnd->pSBCalc->pxThumbTop; /* * Draw the arrows. */ if (Info.dxyLineButton) { IntDrawScrollArrows(DC, &Info, Vertical); } /* * Draw the interior. */ IntDrawScrollInterior(Wnd, DC, Bar, Vertical, &Info); /* * If scroll bar has focus, reposition the caret. */ if ( Wnd == pti->MessageQueue->spwndFocus && Bar == SB_CTL ) { if (Vertical) { co_IntSetCaretPos(Info.rcScrollBar.top + 1, Info.dxyLineButton + 1); } else { co_IntSetCaretPos(Info.dxyLineButton + 1, Info.rcScrollBar.top + 1); } } }