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
CalculateCoordinates(PBLTDATA pbltdata,PRECTL prclClipped,PRECTL prclOrg,PPOINTL pptlSrc,PPOINTL pptlMask,PPOINTL pptlPat,PSIZEL psizlPat)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
EngBitBlt(_Inout_ SURFOBJ * psoTrg,_In_opt_ SURFOBJ * psoSrc,_In_opt_ SURFOBJ * psoMask,_In_opt_ CLIPOBJ * pco,_In_opt_ XLATEOBJ * pxlo,_In_ RECTL * prclTrg,_When_ (psoSrc,_In_)POINTL * pptlSrc,_When_ (psoMask,_In_)POINTL * pptlMask,_In_opt_ BRUSHOBJ * pbo,_When_ (pbo,_In_)POINTL * pptlBrush,_In_ ROP4 rop4)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
AdjustOffsetAndSize(_Out_ PPOINTL pptOffset,_Out_ PSIZEL psizTrg,_In_ PPOINTL pptlSrc,_In_ PSIZEL psizSrc)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
IntEngBitBlt(_Inout_ SURFOBJ * psoTrg,_In_opt_ SURFOBJ * psoSrc,_In_opt_ SURFOBJ * psoMask,_In_opt_ CLIPOBJ * pco,_In_opt_ XLATEOBJ * pxlo,_In_ RECTL * prclTrg,_When_ (psoSrc,_In_)POINTL * pptlSrc,_When_ (psoMask,_In_)POINTL * pptlMask,_In_opt_ BRUSHOBJ * pbo,_When_ (pbo,_In_)POINTL * pptlBrush,_In_ ROP4 rop4)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 if (!RECTL_bClipRectBySize(&rcClipped, prclTrg, &psoTrg->sizlBitmap))
414 {
415 /* Nothing left */
416 return TRUE;
417 }
418
419 /* If no clip object is given, use trivial one */
420 if (!pco) pco = (CLIPOBJ*)&gxcoTrivial;
421
422 /* Check if there is something to clip */
423 if (pco->iDComplexity != DC_TRIVIAL)
424 {
425 /* Clip the target rect to the bounds of the clipping region */
426 if (!RECTL_bIntersectRect(&rcClipped, &rcClipped, &pco->rclBounds))
427 {
428 /* Nothing left */
429 return TRUE;
430 }
431 }
432
433 /* Don't pass a clip object with a single rectangle */
434 if (pco->iDComplexity == DC_RECT) pco = (CLIPOBJ*)&gxcoTrivial;
435
436 /* Calculate initial offset and size */
437 ptOffset.x = rcClipped.left - prclTrg->left;
438 ptOffset.y = rcClipped.top - prclTrg->top;
439 sizTrg.cx = rcClipped.right - rcClipped.left;
440 sizTrg.cy = rcClipped.bottom - rcClipped.top;
441
442 /* Check if the ROP uses a source */
443 if (ROP4_USES_SOURCE(rop4))
444 {
445 /* Must have a source surface and point */
446 ASSERT(psoSrc);
447 ASSERT(pptlSrc);
448
449 /* Get the source point */
450 ptSrc = *pptlSrc;
451
452 /* Clip against the extents of the source surface */
453 AdjustOffsetAndSize(&ptOffset, &sizTrg, &ptSrc, &psoSrc->sizlBitmap);
454 }
455 else
456 {
457 psoSrc = NULL;
458 ptSrc.x = 0;
459 ptSrc.y = 0;
460 }
461
462 /* Check if the ROP uses a mask */
463 if (ROP4_USES_MASK(rop4))
464 {
465 /* Must have a mask surface and point */
466 ASSERT(psoMask);
467 ASSERT(pptlMask);
468
469 /* Get the mask point */
470 ptMask = *pptlMask;
471
472 /* Clip against the extents of the mask surface */
473 AdjustOffsetAndSize(&ptOffset, &sizTrg, &ptMask, &psoMask->sizlBitmap);
474 }
475 else
476 {
477 psoMask = NULL;
478 ptMask.x = 0;
479 ptMask.y = 0;
480 }
481
482 /* Check if all has been clipped away */
483 if ((sizTrg.cx <= 0) || (sizTrg.cy <= 0))
484 return TRUE;
485
486 /* Adjust the points */
487 ptSrc.x += ptOffset.x;
488 ptSrc.y += ptOffset.y;
489 ptMask.x += ptOffset.x;
490 ptMask.y += ptOffset.y;
491
492 /* Check if we have a brush origin */
493 if (pptlBrush)
494 {
495 /* calculate the new brush origin */
496 ptBrush.x = pptlBrush->x + ptOffset.x;
497 ptBrush.y = pptlBrush->y + ptOffset.y;
498 }
499
500 /* Recalculate the target rect */
501 rcClipped.left = prclTrg->left + ptOffset.x;
502 rcClipped.top = prclTrg->top + ptOffset.y;
503 rcClipped.right = rcClipped.left + sizTrg.cx;
504 rcClipped.bottom = rcClipped.top + sizTrg.cy;
505
506 /* Is the target surface device managed? */
507 if (SURFOBJ_flags(psoTrg) & HOOK_BITBLT)
508 {
509 /* Is the source a different device managed surface? */
510 if (psoSrc && (psoSrc->hdev != psoTrg->hdev) &&
511 (SURFOBJ_flags(psoSrc) & HOOK_BITBLT))
512 {
513 ERR("Need to copy to standard bitmap format!\n");
514 ASSERT(FALSE);
515 }
516
517 pfnBitBlt = GDIDEVFUNCS(psoTrg).BitBlt;
518 }
519 /* Otherwise is the source surface device managed? */
520 else if (psoSrc && (SURFOBJ_flags(psoSrc) & HOOK_BITBLT))
521 {
522 pfnBitBlt = GDIDEVFUNCS(psoSrc).BitBlt;
523 }
524 else
525 {
526 pfnBitBlt = EngBitBlt;
527 }
528
529 bResult = pfnBitBlt(psoTrg,
530 psoSrc,
531 psoMask,
532 pco,
533 pxlo,
534 &rcClipped,
535 psoSrc ? &ptSrc : NULL,
536 psoMask ? &ptMask : NULL,
537 pbo,
538 pptlBrush ? &ptBrush : NULL,
539 rop4);
540
541 // FIXME: cleanup temp surface!
542
543 return bResult;
544 }
545
546 BOOL
547 APIENTRY
NtGdiEngBitBlt(IN SURFOBJ * psoTrgUMPD,IN SURFOBJ * psoSrcUMPD,IN SURFOBJ * psoMaskUMPD,IN CLIPOBJ * pcoUMPD,IN XLATEOBJ * pxloUMPD,IN RECTL * prclTrg,IN POINTL * pptlSrc,IN POINTL * pptlMask,IN BRUSHOBJ * pboUMPD,IN POINTL * pptlBrush,IN ROP4 rop4)548 NtGdiEngBitBlt(
549 IN SURFOBJ *psoTrgUMPD,
550 IN SURFOBJ *psoSrcUMPD,
551 IN SURFOBJ *psoMaskUMPD,
552 IN CLIPOBJ *pcoUMPD,
553 IN XLATEOBJ *pxloUMPD,
554 IN RECTL *prclTrg,
555 IN POINTL *pptlSrc,
556 IN POINTL *pptlMask,
557 IN BRUSHOBJ *pboUMPD,
558 IN POINTL *pptlBrush,
559 IN ROP4 rop4)
560 {
561 RECTL rclTrg;
562 POINTL ptlSrc, ptlMask, ptlBrush;
563 HSURF hsurfTrg, hsurfSrc = NULL, hsurfMask = NULL;
564 HANDLE hBrushObj; // HUMPDOBJ
565 SURFOBJ *psoTrg, *psoSrc, *psoMask;
566 CLIPOBJ *pco;
567 XLATEOBJ *pxlo;
568 BRUSHOBJ *pbo;
569 BOOL bResult;
570
571 _SEH2_TRY
572 {
573 ProbeForRead(prclTrg, sizeof(RECTL), 1);
574 rclTrg = *prclTrg;
575
576 ProbeForRead(psoTrgUMPD, sizeof(SURFOBJ), 1);
577 hsurfTrg = psoTrgUMPD->hsurf;
578
579 if (ROP4_USES_SOURCE(rop4))
580 {
581 ProbeForRead(pptlSrc, sizeof(POINTL), 1);
582 ptlSrc = *pptlSrc;
583
584 ProbeForRead(psoSrcUMPD, sizeof(SURFOBJ), 1);
585 hsurfSrc = psoSrcUMPD->hsurf;
586 }
587
588 if (ROP4_USES_MASK(rop4))
589 {
590 ProbeForRead(pptlMask, sizeof(POINTL), 1);
591 ptlMask = *pptlMask;
592
593 ProbeForRead(psoMaskUMPD, sizeof(SURFOBJ), 1);
594 hsurfMask = psoMaskUMPD->hsurf;
595 }
596
597 if (ROP4_USES_PATTERN(rop4))
598 {
599 ProbeForRead(pptlBrush, sizeof(POINTL), 1);
600 ptlBrush = *pptlBrush;
601
602 ProbeForRead(psoSrcUMPD, sizeof(SURFOBJ), 1);
603 hBrushObj = pboUMPD->pvRbrush; // FIXME
604 }
605 }
606 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
607 {
608 _SEH2_YIELD(return FALSE);
609 }
610 _SEH2_END;
611
612 // FIXME: these need to be converted/locked!
613 psoTrg = NULL;
614 psoSrc = NULL;
615 psoMask = NULL;
616 pco = NULL;
617 pxlo = NULL;
618 pbo = NULL;
619
620 bResult = EngBitBlt(psoTrg,
621 psoSrc,
622 psoMask,
623 pco,
624 pxlo,
625 &rclTrg,
626 pptlSrc ? &ptlSrc : NULL,
627 pptlMask ? &ptlMask : NULL,
628 pbo,
629 pptlBrush ? &ptlBrush : NULL,
630 rop4);
631
632 return bResult;
633 }
634
635 BOOL
636 APIENTRY
EngCopyBits(SURFOBJ * psoTrg,SURFOBJ * psoSrc,CLIPOBJ * pco,XLATEOBJ * pxlo,RECTL * prclTrg,POINTL * pptlSrc)637 EngCopyBits(
638 SURFOBJ *psoTrg,
639 SURFOBJ *psoSrc,
640 CLIPOBJ *pco,
641 XLATEOBJ *pxlo,
642 RECTL *prclTrg,
643 POINTL *pptlSrc)
644 {
645 PFN_DrvCopyBits pfnCopyBits;
646
647 /* Is the target surface device managed? */
648 if (SURFOBJ_flags(psoTrg) & HOOK_COPYBITS)
649 {
650 pfnCopyBits = GDIDEVFUNCS(psoTrg).CopyBits;
651 }
652 if (SURFOBJ_flags(psoSrc) & HOOK_COPYBITS)
653 {
654 pfnCopyBits = GDIDEVFUNCS(psoSrc).CopyBits;
655 }
656 else
657 {
658 /* Use SRCCOPY for 2 bitmaps */
659 return EngBitBlt(psoTrg,
660 psoSrc,
661 NULL,
662 pco,
663 pxlo,
664 prclTrg,
665 pptlSrc,
666 NULL,
667 NULL,
668 NULL,
669 ROP4_SRCCOPY);
670 }
671
672 /* Forward to the driver */
673 return pfnCopyBits(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc);
674 }
675
676 BOOL
677 APIENTRY
IntEngCopyBits(SURFOBJ * psoTrg,SURFOBJ * psoSrc,CLIPOBJ * pco,XLATEOBJ * pxlo,RECTL * prclTrg,POINTL * pptlSrc)678 IntEngCopyBits(
679 SURFOBJ *psoTrg,
680 SURFOBJ *psoSrc,
681 CLIPOBJ *pco,
682 XLATEOBJ *pxlo,
683 RECTL *prclTrg,
684 POINTL *pptlSrc)
685 {
686 return EngCopyBits(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc);
687 }
688