1 2 #include <win32k.h> 3 #include "../diblib/DibLib_interface.h" 4 DBG_DEFAULT_CHANNEL(GdiFont); 5 6 #define SURFOBJ_flags(pso) (CONTAINING_RECORD(pso, SURFACE, SurfObj)->flags) 7 8 // FIXME this needs to be updated, once we use the new structure 9 extern XCLIPOBJ gxcoTrivial; 10 /* 11 { 12 {0, {LONG_MIN, LONG_MIN, LONG_MAX, LONG_MAX}, DC_TRIVIAL, FC_RECT, TC_RECTANGLES, 0}, 13 0, 0, 0 14 }; 15 */ 16 17 static 18 void 19 CalculateCoordinates( 20 PBLTDATA pbltdata, 21 PRECTL prclClipped, 22 PRECTL prclOrg, 23 PPOINTL pptlSrc, 24 PPOINTL pptlMask, 25 PPOINTL pptlPat, 26 PSIZEL psizlPat) 27 { 28 ULONG cx, cy; 29 30 /* Calculate width and height of this rect */ 31 pbltdata->ulWidth = prclClipped->right - prclClipped->left; 32 pbltdata->ulHeight = prclClipped->bottom - prclClipped->top; 33 34 /* Calculate the x offset to the origin coordinates */ 35 if (pbltdata->siDst.iFormat == 0) 36 cx = (prclClipped->right - 1 - prclOrg->left); 37 else 38 cx = (prclClipped->left - prclOrg->left); 39 40 /* Calculate the y offset to the origin coordinates */ 41 if (pbltdata->dy < 0) 42 cy = (prclClipped->bottom - 1 - prclOrg->top); 43 else 44 cy = (prclClipped->top - prclOrg->top); 45 46 /* Calculate the target start point */ 47 pbltdata->siDst.ptOrig.x = prclOrg->left + cx; 48 pbltdata->siDst.ptOrig.y = prclOrg->top + cy; 49 50 /* Calculate start position for target */ 51 pbltdata->siDst.pjBase = pbltdata->siDst.pvScan0; 52 pbltdata->siDst.pjBase += pbltdata->siDst.ptOrig.y * pbltdata->siDst.lDelta; 53 pbltdata->siDst.pjBase += pbltdata->siDst.ptOrig.x * pbltdata->siDst.jBpp / 8; 54 55 if (pptlSrc) 56 { 57 /* Calculate start point and bitpointer for source */ 58 pbltdata->siSrc.ptOrig.x = pptlSrc->x + cx; 59 pbltdata->siSrc.ptOrig.y = pptlSrc->y + cy; 60 pbltdata->siSrc.pjBase = pbltdata->siSrc.pvScan0; 61 pbltdata->siSrc.pjBase += pbltdata->siSrc.ptOrig.y * pbltdata->siSrc.lDelta; 62 pbltdata->siSrc.pjBase += pbltdata->siSrc.ptOrig.x * pbltdata->siSrc.jBpp / 8; 63 } 64 65 if (pptlMask) 66 { 67 /* Calculate start point and bitpointer for mask */ 68 pbltdata->siMsk.ptOrig.x = pptlMask->x + cx; 69 pbltdata->siMsk.ptOrig.y = pptlMask->y + cy; 70 pbltdata->siMsk.pjBase = pbltdata->siMsk.pvScan0; 71 pbltdata->siMsk.pjBase += pbltdata->siMsk.ptOrig.y * pbltdata->siMsk.lDelta; 72 pbltdata->siMsk.pjBase += pbltdata->siMsk.ptOrig.x * pbltdata->siMsk.jBpp / 8; 73 } 74 75 if (pptlPat) 76 { 77 /* Calculate start point and bitpointer for pattern */ 78 pbltdata->siPat.ptOrig.x = (pptlPat->x + cx) % psizlPat->cx; 79 pbltdata->siPat.ptOrig.y = (pptlPat->y + cy) % psizlPat->cy; 80 pbltdata->siPat.pjBase = pbltdata->siPat.pvScan0; 81 82 /* Check for bottom-up case */ 83 if (pbltdata->dy < 0) 84 { 85 pbltdata->siPat.pjBase += (psizlPat->cy - 1) * pbltdata->siPat.lDelta; 86 pbltdata->siPat.ptOrig.y = psizlPat->cy - 1 - pbltdata->siPat.ptOrig.y; 87 } 88 89 /* Check for right-to-left case */ 90 if (pbltdata->siDst.iFormat == 0) 91 { 92 pbltdata->siPat.pjBase += (psizlPat->cx - 1) * pbltdata->siMsk.jBpp / 8; 93 pbltdata->siPat.ptOrig.x = psizlPat->cx - 1 - pbltdata->siPat.ptOrig.x; 94 } 95 } 96 } 97 98 BOOL 99 APIENTRY 100 EngBitBlt( 101 _Inout_ SURFOBJ *psoTrg, 102 _In_opt_ SURFOBJ *psoSrc, 103 _In_opt_ SURFOBJ *psoMask, 104 _In_opt_ CLIPOBJ *pco, 105 _In_opt_ XLATEOBJ *pxlo, 106 _In_ RECTL *prclTrg, 107 _When_(psoSrc, _In_) POINTL *pptlSrc, 108 _When_(psoMask, _In_) POINTL *pptlMask, 109 _In_opt_ BRUSHOBJ *pbo, 110 _When_(pbo, _In_) POINTL *pptlBrush, 111 _In_ ROP4 rop4) 112 { 113 BLTDATA bltdata; 114 ULONG i, iFunctionIndex, iDirection = CD_ANY; 115 RECTL rcTrg; 116 PFN_DIBFUNCTION pfnBitBlt; 117 BOOL bEnumMore; 118 RECT_ENUM rcenum; 119 PSIZEL psizlPat; 120 SURFOBJ *psoPattern; 121 122 //static int count = 0; 123 //if (++count >= 1230) __debugbreak(); 124 125 /* Sanity checks */ 126 ASSERT(psoTrg); 127 ASSERT(psoTrg->iBitmapFormat >= BMF_1BPP); 128 ASSERT(psoTrg->iBitmapFormat <= BMF_32BPP); 129 ASSERT(prclTrg); 130 ASSERT(prclTrg->left >= 0); 131 ASSERT(prclTrg->top >= 0); 132 ASSERT(prclTrg->right <= psoTrg->sizlBitmap.cx); 133 ASSERT(prclTrg->bottom <= psoTrg->sizlBitmap.cy); 134 135 rcTrg = *prclTrg; 136 137 bltdata.dy = 1; 138 bltdata.rop4 = rop4; 139 bltdata.apfnDoRop[0] = gapfnRop[ROP4_BKGND(rop4)]; 140 bltdata.apfnDoRop[1] = gapfnRop[ROP4_FGND(rop4)]; 141 if (!pxlo) pxlo = &gexloTrivial.xlo; 142 bltdata.pxlo = pxlo; 143 bltdata.pfnXlate = XLATEOBJ_pfnXlate(pxlo); 144 145 /* Check if the ROP uses a source */ 146 if (ROP4_USES_SOURCE(rop4)) 147 { 148 /* Sanity checks */ 149 ASSERT(psoSrc); 150 ASSERT(psoSrc->iBitmapFormat >= BMF_1BPP); 151 ASSERT(psoSrc->iBitmapFormat <= BMF_32BPP); 152 ASSERT(pptlSrc); 153 ASSERT(pptlSrc->x >= 0); 154 ASSERT(pptlSrc->y >= 0); 155 ASSERT(pptlSrc->x <= psoSrc->sizlBitmap.cx); 156 ASSERT(pptlSrc->y <= psoSrc->sizlBitmap.cy); 157 158 /* Check if source and target are equal */ 159 if (psoSrc == psoTrg) 160 { 161 /* Analyze the copying direction */ 162 if (rcTrg.top > pptlSrc->y) 163 { 164 /* Need to copy from bottom to top */ 165 iDirection = rcTrg.left < pptlSrc->x ? CD_RIGHTUP : CD_LEFTUP; 166 bltdata.dy = -1; 167 } 168 else 169 iDirection = rcTrg.left < pptlSrc->x ? CD_RIGHTDOWN : CD_LEFTDOWN; 170 171 /* Check for special right to left case */ 172 if ((rcTrg.top == pptlSrc->y) && (rcTrg.left > pptlSrc->x)) 173 { 174 /* Use 0 as target format to get special right to left versions */ 175 bltdata.siDst.iFormat = 0; 176 bltdata.siSrc.iFormat = psoSrc->iBitmapFormat; 177 //__debugbreak(); 178 } 179 else 180 { 181 /* Use 0 as source format to get special equal surface versions */ 182 bltdata.siDst.iFormat = psoTrg->iBitmapFormat; 183 bltdata.siSrc.iFormat = 0; 184 } 185 } 186 else 187 { 188 bltdata.siDst.iFormat = psoTrg->iBitmapFormat; 189 bltdata.siSrc.iFormat = psoSrc->iBitmapFormat; 190 } 191 192 /* Set the source format info */ 193 bltdata.siSrc.pvScan0 = psoSrc->pvScan0; 194 bltdata.siSrc.lDelta = psoSrc->lDelta; 195 bltdata.siSrc.cjAdvanceY = bltdata.dy * psoSrc->lDelta; 196 bltdata.siSrc.jBpp = gajBitsPerFormat[psoSrc->iBitmapFormat]; 197 } 198 else 199 { 200 bltdata.siDst.iFormat = psoTrg->iBitmapFormat; 201 } 202 203 /* Set the destination format info */ 204 bltdata.siDst.pvScan0 = psoTrg->pvScan0; 205 bltdata.siDst.lDelta = psoTrg->lDelta; 206 bltdata.siDst.cjAdvanceY = bltdata.dy * psoTrg->lDelta; 207 bltdata.siDst.jBpp = gajBitsPerFormat[psoTrg->iBitmapFormat]; 208 209 /* Check if the ROP uses a pattern / brush */ 210 if (ROP4_USES_PATTERN(rop4)) 211 { 212 /* Must have a brush */ 213 NT_ASSERT(pbo); // FIXME: test this! 214 215 /* Copy the solid color */ 216 bltdata.ulSolidColor = pbo->iSolidColor; 217 218 /* Check if this is a pattern brush */ 219 if (pbo->iSolidColor == 0xFFFFFFFF) 220 { 221 /* Get the realized pattern bitmap */ 222 psoPattern = BRUSHOBJ_psoPattern(pbo); 223 if (!psoPattern) 224 { 225 __debugbreak(); 226 return FALSE; 227 } 228 229 /* Set the pattern format info */ 230 bltdata.siPat.iFormat = psoPattern->iBitmapFormat; 231 bltdata.siPat.pvScan0 = psoPattern->pvScan0; 232 bltdata.siPat.lDelta = psoPattern->lDelta; 233 bltdata.siPat.cjAdvanceY = bltdata.dy * psoPattern->lDelta; 234 bltdata.siPat.jBpp = gajBitsPerFormat[psoPattern->iBitmapFormat]; 235 236 bltdata.ulPatWidth = psoPattern->sizlBitmap.cx; 237 bltdata.ulPatHeight = psoPattern->sizlBitmap.cy; 238 239 psizlPat = &psoPattern->sizlBitmap; 240 } 241 else 242 { 243 pptlBrush = NULL; 244 psizlPat = NULL; 245 } 246 } 247 else 248 { 249 pptlBrush = NULL; 250 psizlPat = NULL; 251 } 252 253 /* Check if the ROP uses a mask */ 254 if (ROP4_USES_MASK(rop4)) 255 { 256 //__debugbreak(); 257 258 /* Check if we don't have a mask surface */ 259 if (psoMask == NULL) 260 { 261 /* Must have a brush */ 262 NT_ASSERT(pbo); // FIXME: test this! 263 264 /* Check if the BRUSHOBJ can provide the mask */ 265 psoMask = BRUSHOBJ_psoMask(pbo); 266 if (psoMask == NULL) 267 { 268 /* We have no mask, assume the mask is all foreground */ 269 rop4 = (rop4 & 0xFF) || ((rop4 & 0xFF) << 8); 270 } 271 } 272 273 /* Set the mask format info */ 274 bltdata.siMsk.iFormat = psoMask->iBitmapFormat; 275 bltdata.siMsk.pvScan0 = psoMask->pvScan0; 276 bltdata.siMsk.lDelta = psoMask->lDelta; 277 bltdata.siMsk.cjAdvanceY = bltdata.dy * psoMask->lDelta; 278 bltdata.siMsk.jBpp = 1; 279 280 /* Calculate the masking function index */ 281 iFunctionIndex = ROP4_USES_PATTERN(rop4) ? 1 : 0; 282 iFunctionIndex |= ROP4_USES_SOURCE(rop4) ? 2 : 0; 283 iFunctionIndex |= ROP4_USES_DEST(rop4) ? 4 : 0; 284 285 /* Get the masking function */ 286 pfnBitBlt = gapfnMaskFunction[iFunctionIndex]; 287 } 288 else 289 { 290 /* Get the function index from the foreground ROP index*/ 291 iFunctionIndex = gajIndexPerRop[ROP4_FGND(rop4)]; 292 293 /* Get the dib function */ 294 pfnBitBlt = gapfnDibFunction[iFunctionIndex]; 295 } 296 297 /* If no clip object is given, use trivial one */ 298 if (!pco) pco = (CLIPOBJ*)&gxcoTrivial; 299 300 /* Check if we need to enumerate rects */ 301 if (pco->iDComplexity == DC_COMPLEX) 302 { 303 /* Start the enumeration of the clip object */ 304 CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, iDirection, 0); 305 bEnumMore = CLIPOBJ_bEnum(pco, sizeof(rcenum), (ULONG*)&rcenum); 306 } 307 else if (pco->iDComplexity == DC_RECT) 308 { 309 /* Use the clip bounds */ 310 rcenum.arcl[0] = pco->rclBounds; 311 rcenum.c = 1; 312 bEnumMore = FALSE; 313 } 314 else 315 { 316 /* Use the target rect */ 317 rcenum.arcl[0] = rcTrg; 318 rcenum.c = 1; 319 bEnumMore = FALSE; 320 } 321 322 /* Enter enumeration loop */ 323 while (TRUE) 324 { 325 /* Loop all rectangles we got */ 326 for (i = 0; i < rcenum.c; i++) 327 { 328 /* Intersect this rect with the target rect */ 329 if (!RECTL_bIntersectRect(&rcenum.arcl[i], &rcenum.arcl[i], &rcTrg)) 330 { 331 /* This rect is outside the bounds, continue */ 332 continue; 333 } 334 335 /* Calculate coordinates and pointers */ 336 CalculateCoordinates(&bltdata, 337 &rcenum.arcl[i], 338 prclTrg, 339 pptlSrc, 340 pptlMask, 341 pptlBrush, 342 psizlPat); 343 344 /* Call the dib function */ 345 pfnBitBlt(&bltdata); 346 } 347 348 /* Bail out, when there's nothing more to do */ 349 if(!bEnumMore) break; 350 351 /* Enumerate more rectangles */ 352 bEnumMore = CLIPOBJ_bEnum(pco, sizeof(rcenum), (ULONG*)&rcenum); 353 } 354 355 return TRUE; 356 } 357 358 359 static 360 VOID 361 AdjustOffsetAndSize( 362 _Out_ PPOINTL pptOffset, 363 _Out_ PSIZEL psizTrg, 364 _In_ PPOINTL pptlSrc, 365 _In_ PSIZEL psizSrc) 366 { 367 LONG x, y, cxMax, cyMax; 368 369 x = pptlSrc->x + pptOffset->x; 370 if (x < 0) pptOffset->x -= x, x = 0; 371 372 cxMax = psizSrc->cx - x; 373 if (psizTrg->cx > cxMax) psizTrg->cx = cxMax; 374 375 y = pptlSrc->y + pptOffset->y; 376 if (y < 0) pptOffset->y -= y, y = 0; 377 378 cyMax = psizSrc->cy - y; 379 if (psizTrg->cy > cyMax) psizTrg->cy = cyMax; 380 } 381 382 BOOL 383 APIENTRY 384 IntEngBitBlt( 385 _Inout_ SURFOBJ *psoTrg, 386 _In_opt_ SURFOBJ *psoSrc, 387 _In_opt_ SURFOBJ *psoMask, 388 _In_opt_ CLIPOBJ *pco, 389 _In_opt_ XLATEOBJ *pxlo, 390 _In_ RECTL *prclTrg, 391 _When_(psoSrc, _In_) POINTL *pptlSrc, 392 _When_(psoMask, _In_) POINTL *pptlMask, 393 _In_opt_ BRUSHOBJ *pbo, 394 _When_(pbo, _In_) POINTL *pptlBrush, 395 _In_ ROP4 rop4) 396 { 397 BOOL bResult; 398 RECTL rcClipped; 399 POINTL ptOffset, ptSrc, ptMask, ptBrush; 400 SIZEL sizTrg; 401 PFN_DrvBitBlt pfnBitBlt; 402 403 //__debugbreak(); 404 405 /* Sanity checks */ 406 ASSERT(IS_VALID_ROP4(rop4)); 407 ASSERT(psoTrg); 408 ASSERT(psoTrg->iBitmapFormat >= BMF_1BPP); 409 ASSERT(psoTrg->iBitmapFormat <= BMF_32BPP); 410 ASSERT(prclTrg); 411 412 /* Clip the target rect to the extents of the target surface */ 413 rcClipped.left = max(prclTrg->left, 0); 414 rcClipped.top = max(prclTrg->top, 0); 415 rcClipped.right = min(prclTrg->right, psoTrg->sizlBitmap.cx); 416 rcClipped.bottom = min(prclTrg->bottom, psoTrg->sizlBitmap.cy); 417 418 /* If no clip object is given, use trivial one */ 419 if (!pco) pco = (CLIPOBJ*)&gxcoTrivial; 420 421 /* Check if there is something to clip */ 422 if (pco->iDComplexity != DC_TRIVIAL) 423 { 424 /* Clip the target rect to the bounds of the clipping region */ 425 if (!RECTL_bIntersectRect(&rcClipped, &rcClipped, &pco->rclBounds)) 426 { 427 /* Nothing left */ 428 return TRUE; 429 } 430 } 431 432 /* Don't pass a clip object with a single rectangle */ 433 if (pco->iDComplexity == DC_RECT) pco = (CLIPOBJ*)&gxcoTrivial; 434 435 /* Calculate initial offset and size */ 436 ptOffset.x = rcClipped.left - prclTrg->left; 437 ptOffset.y = rcClipped.top - prclTrg->top; 438 sizTrg.cx = rcClipped.right - rcClipped.left; 439 sizTrg.cy = rcClipped.bottom - rcClipped.top; 440 441 /* Check if the ROP uses a source */ 442 if (ROP4_USES_SOURCE(rop4)) 443 { 444 /* Must have a source surface and point */ 445 ASSERT(psoSrc); 446 ASSERT(pptlSrc); 447 448 /* Get the source point */ 449 ptSrc = *pptlSrc; 450 451 /* Clip against the extents of the source surface */ 452 AdjustOffsetAndSize(&ptOffset, &sizTrg, &ptSrc, &psoSrc->sizlBitmap); 453 } 454 else 455 { 456 psoSrc = NULL; 457 ptSrc.x = 0; 458 ptSrc.y = 0; 459 } 460 461 /* Check if the ROP uses a mask */ 462 if (ROP4_USES_MASK(rop4)) 463 { 464 /* Must have a mask surface and point */ 465 ASSERT(psoMask); 466 ASSERT(pptlMask); 467 468 /* Get the mask point */ 469 ptMask = *pptlMask; 470 471 /* Clip against the extents of the mask surface */ 472 AdjustOffsetAndSize(&ptOffset, &sizTrg, &ptMask, &psoMask->sizlBitmap); 473 } 474 else 475 { 476 psoMask = NULL; 477 ptMask.x = 0; 478 ptMask.y = 0; 479 } 480 481 /* Check if all has been clipped away */ 482 if ((sizTrg.cx <= 0) || (sizTrg.cy <= 0)) 483 return TRUE; 484 485 /* Adjust the points */ 486 ptSrc.x += ptOffset.x; 487 ptSrc.y += ptOffset.y; 488 ptMask.x += ptOffset.x; 489 ptMask.y += ptOffset.y; 490 491 /* Check if we have a brush origin */ 492 if (pptlBrush) 493 { 494 /* calculate the new brush origin */ 495 ptBrush.x = pptlBrush->x + ptOffset.x; 496 ptBrush.y = pptlBrush->y + ptOffset.y; 497 } 498 499 /* Recalculate the target rect */ 500 rcClipped.left = prclTrg->left + ptOffset.x; 501 rcClipped.top = prclTrg->top + ptOffset.y; 502 rcClipped.right = rcClipped.left + sizTrg.cx; 503 rcClipped.bottom = rcClipped.top + sizTrg.cy; 504 505 /* Is the target surface device managed? */ 506 if (SURFOBJ_flags(psoTrg) & HOOK_BITBLT) 507 { 508 /* Is the source a different device managed surface? */ 509 if (psoSrc && (psoSrc->hdev != psoTrg->hdev) && 510 (SURFOBJ_flags(psoSrc) & HOOK_BITBLT)) 511 { 512 ERR("Need to copy to standard bitmap format!\n"); 513 ASSERT(FALSE); 514 } 515 516 pfnBitBlt = GDIDEVFUNCS(psoTrg).BitBlt; 517 } 518 /* Otherwise is the source surface device managed? */ 519 else if (psoSrc && (SURFOBJ_flags(psoSrc) & HOOK_BITBLT)) 520 { 521 pfnBitBlt = GDIDEVFUNCS(psoSrc).BitBlt; 522 } 523 else 524 { 525 pfnBitBlt = EngBitBlt; 526 } 527 528 bResult = pfnBitBlt(psoTrg, 529 psoSrc, 530 psoMask, 531 pco, 532 pxlo, 533 &rcClipped, 534 psoSrc ? &ptSrc : NULL, 535 psoMask ? &ptMask : NULL, 536 pbo, 537 pptlBrush ? &ptBrush : NULL, 538 rop4); 539 540 // FIXME: cleanup temp surface! 541 542 return bResult; 543 } 544 545 BOOL 546 APIENTRY 547 NtGdiEngBitBlt( 548 IN SURFOBJ *psoTrgUMPD, 549 IN SURFOBJ *psoSrcUMPD, 550 IN SURFOBJ *psoMaskUMPD, 551 IN CLIPOBJ *pcoUMPD, 552 IN XLATEOBJ *pxloUMPD, 553 IN RECTL *prclTrg, 554 IN POINTL *pptlSrc, 555 IN POINTL *pptlMask, 556 IN BRUSHOBJ *pboUMPD, 557 IN POINTL *pptlBrush, 558 IN ROP4 rop4) 559 { 560 RECTL rclTrg; 561 POINTL ptlSrc, ptlMask, ptlBrush; 562 HSURF hsurfTrg, hsurfSrc = NULL, hsurfMask = NULL; 563 HANDLE hBrushObj; // HUMPDOBJ 564 SURFOBJ *psoTrg, *psoSrc, *psoMask; 565 CLIPOBJ *pco; 566 XLATEOBJ *pxlo; 567 BRUSHOBJ *pbo; 568 BOOL bResult; 569 570 _SEH2_TRY 571 { 572 ProbeForRead(prclTrg, sizeof(RECTL), 1); 573 rclTrg = *prclTrg; 574 575 ProbeForRead(psoTrgUMPD, sizeof(SURFOBJ), 1); 576 hsurfTrg = psoTrgUMPD->hsurf; 577 578 if (ROP4_USES_SOURCE(rop4)) 579 { 580 ProbeForRead(pptlSrc, sizeof(POINTL), 1); 581 ptlSrc = *pptlSrc; 582 583 ProbeForRead(psoSrcUMPD, sizeof(SURFOBJ), 1); 584 hsurfSrc = psoSrcUMPD->hsurf; 585 } 586 587 if (ROP4_USES_MASK(rop4)) 588 { 589 ProbeForRead(pptlMask, sizeof(POINTL), 1); 590 ptlMask = *pptlMask; 591 592 ProbeForRead(psoMaskUMPD, sizeof(SURFOBJ), 1); 593 hsurfMask = psoMaskUMPD->hsurf; 594 } 595 596 if (ROP4_USES_PATTERN(rop4)) 597 { 598 ProbeForRead(pptlBrush, sizeof(POINTL), 1); 599 ptlBrush = *pptlBrush; 600 601 ProbeForRead(psoSrcUMPD, sizeof(SURFOBJ), 1); 602 hBrushObj = pboUMPD->pvRbrush; // FIXME 603 } 604 } 605 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 606 { 607 _SEH2_YIELD(return FALSE); 608 } 609 _SEH2_END; 610 611 // FIXME: these need to be converted/locked! 612 psoTrg = NULL; 613 psoSrc = NULL; 614 psoMask = NULL; 615 pco = NULL; 616 pxlo = NULL; 617 pbo = NULL; 618 619 bResult = EngBitBlt(psoTrg, 620 psoSrc, 621 psoMask, 622 pco, 623 pxlo, 624 &rclTrg, 625 pptlSrc ? &ptlSrc : NULL, 626 pptlMask ? &ptlMask : NULL, 627 pbo, 628 pptlBrush ? &ptlBrush : NULL, 629 rop4); 630 631 return bResult; 632 } 633 634 BOOL 635 APIENTRY 636 EngCopyBits( 637 SURFOBJ *psoTrg, 638 SURFOBJ *psoSrc, 639 CLIPOBJ *pco, 640 XLATEOBJ *pxlo, 641 RECTL *prclTrg, 642 POINTL *pptlSrc) 643 { 644 PFN_DrvCopyBits pfnCopyBits; 645 646 /* Is the target surface device managed? */ 647 if (SURFOBJ_flags(psoTrg) & HOOK_COPYBITS) 648 { 649 pfnCopyBits = GDIDEVFUNCS(psoTrg).CopyBits; 650 } 651 if (SURFOBJ_flags(psoSrc) & HOOK_COPYBITS) 652 { 653 pfnCopyBits = GDIDEVFUNCS(psoSrc).CopyBits; 654 } 655 else 656 { 657 /* Use SRCCOPY for 2 bitmaps */ 658 return EngBitBlt(psoTrg, 659 psoSrc, 660 NULL, 661 pco, 662 pxlo, 663 prclTrg, 664 pptlSrc, 665 NULL, 666 NULL, 667 NULL, 668 ROP4_SRCCOPY); 669 } 670 671 /* Forward to the driver */ 672 return pfnCopyBits(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc); 673 } 674 675 BOOL 676 APIENTRY 677 IntEngCopyBits( 678 SURFOBJ *psoTrg, 679 SURFOBJ *psoSrc, 680 CLIPOBJ *pco, 681 XLATEOBJ *pxlo, 682 RECTL *prclTrg, 683 POINTL *pptlSrc) 684 { 685 return EngCopyBits(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc); 686 } 687