DIB Engine: implement AlphaBlend
[wine/hacks.git] / dlls / winedib.drv / bitblt.c
blobc0227a0384633e0859e2412848dcb23475baa1f6
1 /*
2 * DIBDRV bit-blit operations
4 * Copyright 2009 Massimo Del Fedele
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
24 #include "dibdrv.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
28 static inline void intSwap(int *a, int *b)
30 int tmp;
31 tmp = *a;
32 *a = *b;
33 *b = tmp;
36 /* clips a source and destination areas to their respective clip rectangles
37 returning both source and dest modified; result is TRUE if clipping
38 leads to a non null rectangle, FALSE otherwise */
39 static BOOL BitBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *sz, RECT*srcClip, RECT*dstClip)
41 int xs1, ys1, xs2, ys2;
42 int xsc1, ysc1, xsc2, ysc2;
43 int xd1, yd1, xd2, yd2;
44 int xdc1, ydc1, xdc2, ydc2;
45 int w, h, dx, dy;
47 /* extract sizes */
48 w = sz->cx; h = sz->cy;
50 /* if sizes null or negative, just return false */
51 if(w <= 0 || h <= 0)
52 return FALSE;
54 /* extract dest area data */
55 xd1 = pd->x;
56 yd1 = pd->y;
57 xd2 = xd1 + w;
58 yd2 = yd1 + h;
60 /* extract source data */
61 xs1 = ps->x;
62 ys1 = ps->y;
63 xs2 = xs1 + w;
64 ys2 = ys1 + h;
66 /* if source clip area is not null, do first clipping on it */
67 if(srcClip)
69 /* extract source clipping area */
70 xsc1 = srcClip->left;
71 ysc1 = srcClip->top;
72 xsc2 = srcClip->right;
73 ysc2 = srcClip->bottom;
75 /* order clip area rectangle points */
76 if(xsc1 > xsc2) intSwap(&xsc1, &xsc2);
77 if(ysc1 > ysc2) intSwap(&ysc1, &ysc2);
79 /* clip on source clipping start point */
80 if(xs1 < xsc1) { dx = xsc1 - xs1; w -= dx; xd1 += dx; xs1 = xsc1; }
81 if(ys1 < ysc1) { dy = ysc1 - ys1; h -= dy; yd1 += dy; ys1 = ysc1; }
83 /* clip on source clipping end point */
84 if(xs2 > xsc2) { dx = xs2 - xsc2; w -= dx; xd2 -= dx; xs2 = xsc2; }
85 if(ys2 > ysc2) { dy = ys2 - ysc2; h -= dy; yd2 -= dy; ys2 = ysc2; }
87 /* if already zero area, return false */
88 if(w <= 0 || h <= 0)
89 return FALSE;
91 /* now do clipping on destination area */
93 if(dstClip)
95 /* extract destination clipping area */
96 xdc1 = dstClip->left;
97 ydc1 = dstClip->top;
98 xdc2 = dstClip->right;
99 ydc2 = dstClip->bottom;
101 /* order clip area rectangle points */
102 if(xdc1 > xdc2) intSwap(&xdc1, &xdc2);
103 if(ydc1 > ydc2) intSwap(&ydc1, &ydc2);
105 /* clip on dest clipping start point */
106 if(xd1 < xdc1) { dx = xdc1 - xd1; w -= dx; xs1 += dx; xd1 = xdc1; }
107 if(yd1 < ydc1) { dy = ydc1 - yd1; h -= dy; ys1 += dy; yd1 = ydc1; }
109 /* clip on dest clipping end point */
110 if(xd2 > xdc2) { dx = xd2 - xdc2; w -= dx; xs2 -= dx; xd2 = xdc2; }
111 if(yd2 > ydc2) { dy = yd2 - ydc2; h -= dy; ys2 -= dy; yd2 = ydc2; }
113 /* if already zero area, return false */
114 if(w <= 0 || h <= 0)
115 return FALSE;
118 /* sets clipped/translated points and sizes and returns TRUE */
119 ps->x = xs1; ps->y = ys1;
120 pd->x = xd1; pd->y = yd1;
121 sz->cx = w; sz->cy = h;
123 return TRUE;
128 /* clips a source and destination areas to their respective clip rectangles
129 returning both source and dest modified; result is TRUE if clipping
130 leads to a non null rectangle, FALSE otherwise */
131 static BOOL StretchBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *szSrc, SIZE *szDst, RECT*srcClip, RECT*dstClip)
133 ONCE(FIXME("TO DO\n"));
135 return TRUE;
139 /***********************************************************************
140 * DIBDRV_AlphaBlend
142 BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT widthDst, INT heightDst,
143 DIBDRVPHYSDEV *physDevSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc,
144 BLENDFUNCTION blendfn)
146 BOOL res;
148 MAYBE(TRACE("physDevDst:%p(%s%s), xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, physDevSrc:%p(%s%s), xSrc:%d, ySrc:%d, widthSrc:%d, heightSrc:%d\n",
149 physDevDst, physDevDst->hasDIB ? "DIB-" : "DDB", physDevDst->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevDst->physBitmap) : "",
150 xDst, yDst, widthDst, heightDst,
151 physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevSrc->physBitmap) : "",
152 xSrc, ySrc, widthSrc, heightSrc));
155 /* if sizes are null or negative, returns false */
156 if(widthSrc <= 0 || heightSrc <= 0 || widthDst <= 0 || heightDst <= 0)
158 res = FALSE;
159 goto fin;
162 /* source sould be a 32 bit DIB */
163 if(!physDevSrc)
165 FIXME("Null source bitmap -- shouldn't happen\n");
166 res = FALSE;
167 goto fin;
169 else if(!physDevSrc->hasDIB)
171 FIXME("DDB source bitmap -- shouldn't happen\n");
172 res = FALSE;
173 goto fin;
176 if(physDevDst->hasDIB)
178 /* DIB section selected in dest DC, use DIB Engine */
179 MAYBE(TRACE("Blending DIB->DIB\n"));
180 res = physDevDst->physBitmap.funcs->AlphaBlend(physDevDst, xDst, yDst, widthDst, heightDst,
181 physDevSrc, xSrc, ySrc, widthSrc, heightSrc, blendfn);
183 else
185 /* DDB selected on dest DC -- must double-convert */
186 HBITMAP tmpDIB, stock;
187 HDC tmpDC;
188 MAYBE(TRACE("Blending DIB->DDB\n"));
190 /* converts dest DDB onto a temporary DIB -- just the needed part */
191 tmpDIB = _DIBDRV_ConvertDevDDBtoDIB(physDevDst->hdc, physDevSrc->hdc, xDst, yDst, widthDst, heightDst);
192 if(!tmpDIB)
194 ERR("Couldn't convert dest DDB to DIB\n");
195 res = FALSE;
196 goto fin;
199 /* selects the temporary DIB into a temporary DC */
200 tmpDC = CreateCompatibleDC(physDevDst->hdc);
201 if(!tmpDC)
203 ERR("Couldn't create temporary DC\n");
204 DeleteObject(tmpDIB);
205 res = FALSE;
206 goto fin;
208 stock = SelectObject(tmpDC, tmpDIB);
209 if(!stock)
211 ERR("Couldn't select temporary DIB into temporary DC\n");
212 DeleteDC(tmpDC);
213 DeleteObject(tmpDIB);
214 res = FALSE;
215 goto fin;
218 /* blends source DIB onto temp DIB and re-blits onto dest DC */
219 res = GdiAlphaBlend(tmpDC, 0, 0, widthDst, heightDst, physDevSrc->hdc, xSrc, ySrc, widthSrc, heightSrc, blendfn);
220 if(!res)
221 MAYBE(TRACE("AlphaBlend failed\n"));
222 else
223 res = BitBlt(physDevDst->hdc, xDst, yDst, widthDst, heightDst, tmpDC, 0, 0, SRCCOPY);
225 /* frees resources */
226 SelectObject(tmpDC, stock);
227 DeleteDC(tmpDC);
228 DeleteObject(tmpDIB);
230 fin:
231 return res;
234 /***********************************************************************
235 * DIBDRV_BitBlt
237 BOOL DIBDRV_BitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
238 INT width, INT height, DIBDRVPHYSDEV *physDevSrc,
239 INT xSrc, INT ySrc, DWORD rop )
241 BOOL res;
243 /* clip blit area */
244 POINT pd = {xDst, yDst};
245 POINT ps = {xSrc, ySrc};
246 SIZE sz = {width, height};
248 MAYBE(TRACE("physDevDst:%p(%s%s), xDst:%d, yDst:%d, width:%d, height:%d, physDevSrc:%p(%s%s), xSrc:%d, ySrc:%d, rop:%08x\n",
249 physDevDst, physDevDst->hasDIB ? "DIB-" : "DDB", physDevDst->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevDst->physBitmap) : "",
250 xDst, yDst, width, height,
251 physDevSrc, physDevSrc ? (physDevSrc->hasDIB ? "DIB-" : "DDB"): "---", physDevSrc && physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevSrc->physBitmap) : "",
252 xSrc, ySrc, rop));
254 if(physDevDst->hasDIB)
256 /* DIB section selected in dest DC, use DIB Engine */
258 /* clip blit area */
259 RECT dstClip = {0, 0, physDevDst->physBitmap.width, physDevDst->physBitmap.height};
261 if(!physDevSrc || physDevSrc->hasDIB)
263 /* clip blit area */
264 if(physDevSrc)
266 RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height};
267 res = BitBlt_ClipAreas(&ps, &pd, &sz, &srcClip, &dstClip);
269 else
270 res = BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip);
271 if(!res)
272 goto noBlt2;
273 xDst = pd.x; yDst = pd.y; width = sz.cx; height = sz.cy; xSrc = ps.x; ySrc = ps.y;
275 /* source is null or has a DIB, no need to convert anyting */
276 res = physDevDst->physBitmap.funcs->BitBlt(physDevDst, xDst, yDst, width, height, physDevSrc, xSrc, ySrc, rop);
278 else
280 /* source is a DDB, must convert it to DIB */
282 /* don't clip on source */
283 res = BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip);
284 if(!res)
285 goto noBlt2;
286 xDst = pd.x; yDst = pd.y; width = sz.cx; height = sz.cy; xSrc = ps.x; ySrc = ps.y;
288 /* we must differentiate from 2 cases :
289 1) source DC is a memory DC
290 2) source DC is a device DC */
291 if(GetObjectType(physDevSrc->hdc) == OBJ_MEMDC)
293 /* memory DC */
294 HBITMAP dib, ddb;
296 ddb = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP));
297 if(!ddb)
299 ERR("Couldn't select out DDB from source HDC\n");
300 res = 0;
301 goto noBlt1;
303 dib = _DIBDRV_ConvertDDBtoDIB(physDevSrc->hdc, ddb, ySrc, height);
304 if(!dib)
306 ERR("Failed converting source DDB to DIB\n");
307 SelectObject(physDevSrc->hdc, ddb);
308 res = 0;
309 goto noBlt1;
311 SelectObject(physDevSrc->hdc, dib);
312 res = physDevDst->physBitmap.funcs->BitBlt(physDevDst, xDst, yDst, width, height,
313 physDevSrc, xSrc, 0, rop);
314 SelectObject(physDevSrc->hdc, ddb);
315 DeleteObject(dib);
316 noBlt1:
319 else
321 /* device DC */
322 HBITMAP dib, stock;
323 HDC memHdc;
325 dib = _DIBDRV_ConvertDevDDBtoDIB(physDevSrc->hdc, physDevDst->hdc, xSrc, ySrc, width, height);
326 if(!dib)
328 ERR("Failed converting source DDB tp DIB for device DC\n");
329 res = 0;
330 goto noBlt2;
332 memHdc = CreateCompatibleDC(physDevDst->hdc);
333 if(!memHdc)
335 ERR("Failed creating temporary memory DC\n");
336 DeleteObject(dib);
337 res = 0;
338 goto noBlt2;
340 stock = SelectObject(memHdc, dib);
341 if(!stock)
343 ERR("Failed selecting converted DIB into temporary memory DC\n");
344 DeleteObject(dib);
345 DeleteDC(memHdc);
346 res = 0;
347 goto noBlt2;
349 res = BitBlt(physDevDst->hdc, xDst, yDst, width, height, memHdc, 0, 0, rop);
351 SelectObject(memHdc, stock);
352 DeleteObject(dib);
353 DeleteDC(memHdc);
354 noBlt2:
359 else /* dest is a DDB */
361 /* DDB selected on dest DC, use X11 Driver */
362 if(!physDevSrc || !physDevSrc->hasDIB)
364 /* source is null or has also a DDB, no need to convert anything */
365 res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height,
366 physDevSrc ? physDevSrc->X11PhysDev : 0, xSrc, ySrc, rop);
368 else
370 /* DIB on source, DDB on dest -- must convert source DIB to DDB and use X11 driver for blit */
371 HBITMAP dib, ddb;
373 /* clip blit area */
374 if(physDevSrc)
376 RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height};
377 res = BitBlt_ClipAreas(&ps, &pd, &sz, &srcClip, 0);
379 else
380 res = TRUE;
381 if(!res)
382 goto noBlt3;
383 xDst = pd.x; yDst = pd.y; width = sz.cx; height = sz.cy; xSrc = ps.x; ySrc = ps.y;
385 dib = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP));
386 if(!dib)
388 ERR("Couldn't select out DIB from source HDC\n");
389 res = 0;
390 goto noBlt3;
392 ddb = _DIBDRV_ConvertDIBtoDDB(physDevSrc->hdc, dib, ySrc, height);
393 if(!ddb)
395 ERR("Failed converting source DIB to DDB\n");
396 SelectObject(physDevSrc->hdc, dib);
397 res = 0;
398 goto noBlt3;
400 SelectObject(physDevSrc->hdc, ddb);
401 res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height,
402 physDevSrc ? physDevSrc->X11PhysDev : 0, xSrc, 0, rop);
403 SelectObject(physDevSrc->hdc, dib);
404 DeleteObject(ddb);
405 noBlt3:
409 return res;
412 /***********************************************************************
413 * DIBDRV_StretchBlt
415 BOOL DIBDRV_StretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
416 INT widthDst, INT heightDst,
417 DIBDRVPHYSDEV *physDevSrc, INT xSrc, INT ySrc,
418 INT widthSrc, INT heightSrc, DWORD rop )
420 BOOL res;
422 /* clip blit area */
423 POINT pd = {xDst, yDst};
424 POINT ps = {xSrc, ySrc};
425 SIZE szDst = {widthDst, heightDst};
426 SIZE szSrc = {widthSrc, heightSrc};
428 /* if source and dest sizes match, just call BitBlt(), it's faster */
429 if(!physDevSrc || (widthDst == widthSrc && heightDst == heightSrc))
430 return DIBDRV_BitBlt(physDevDst, xDst, yDst, widthDst, heightDst, physDevSrc, xSrc, ySrc, rop);
432 MAYBE(TRACE("physDevDst:%p(%s%s), xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, physDevSrc:%p(%s%s), xSrc:%d, ySrc:%d, widthSrc:%d, heightSrc:%d, rop:%08x\n",
433 physDevDst, physDevDst->hasDIB ? "DIB-" : "DDB", physDevDst->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevDst->physBitmap) : "",
434 xDst, yDst, widthDst, heightDst,
435 physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevSrc->physBitmap) : "",
436 xSrc, ySrc, widthSrc, heightSrc, rop));
438 if(physDevDst->hasDIB)
440 /* DIB section selected in dest DC, use DIB Engine */
442 /* clip blit area */
443 RECT dstClip = {0, 0, physDevDst->physBitmap.width, physDevDst->physBitmap.height};
445 if(!physDevSrc || physDevSrc->hasDIB)
447 /* clip blit area */
448 if(physDevSrc)
450 RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height};
451 res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, &srcClip, &dstClip);
453 else
454 res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, 0, &dstClip);
455 if(!res)
456 goto noBlt2;
457 xDst = pd.x; yDst = pd.y; widthDst = szDst.cx; heightDst = szDst.cy;
458 xSrc = ps.x; ySrc = ps.y; widthSrc = szSrc.cx; heightSrc = szSrc.cy;
460 /* source is null or has a DIB, no need to convert anyting */
461 res = physDevDst->physBitmap.funcs->StretchBlt(physDevDst, xDst, yDst, widthDst, heightDst, physDevSrc, xSrc, ySrc, widthSrc, heightSrc, rop);
463 else
465 /* source is a DDB, must convert it to DIB */
467 /* don't clip on source */
468 res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, 0, &dstClip);
469 if(!res)
470 goto noBlt2;
471 xDst = pd.x; yDst = pd.y; widthDst = szDst.cx; heightDst = szDst.cy;
472 xSrc = ps.x; ySrc = ps.y; widthSrc = szSrc.cx; heightSrc = szSrc.cy;
474 /* we must differentiate from 2 cases :
475 1) source DC is a memory DC
476 2) source DC is a device DC */
477 if(GetObjectType(physDevSrc->hdc) == OBJ_MEMDC)
479 /* memory DC */
480 HBITMAP dib, ddb;
482 ddb = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP));
483 if(!ddb)
485 ERR("Couldn't select out DDB from source HDC\n");
486 res = 0;
487 goto noBlt1;
489 dib = _DIBDRV_ConvertDDBtoDIB(physDevSrc->hdc, ddb, ySrc, heightSrc);
490 if(!dib)
492 ERR("Failed converting source DDB to DIB\n");
493 SelectObject(physDevSrc->hdc, ddb);
494 res = 0;
495 goto noBlt1;
497 SelectObject(physDevSrc->hdc, dib);
498 res = physDevDst->physBitmap.funcs->StretchBlt(physDevDst, xDst, yDst, widthDst, heightDst,
499 physDevSrc, xSrc, 0, widthSrc, heightSrc, rop);
500 SelectObject(physDevSrc->hdc, ddb);
501 DeleteObject(dib);
502 noBlt1:
505 else
507 /* device DC */
508 HBITMAP dib, stock;
509 HDC memHdc;
511 dib = _DIBDRV_ConvertDevDDBtoDIB(physDevSrc->hdc, physDevDst->hdc, xSrc, ySrc, widthSrc, heightSrc);
512 if(!dib)
514 ERR("Failed converting source DDB tp DIB for device DC\n");
515 res = 0;
516 goto noBlt2;
518 memHdc = CreateCompatibleDC(physDevDst->hdc);
519 if(!memHdc)
521 ERR("Failed creating temporary memory DC\n");
522 DeleteObject(dib);
523 res = 0;
524 goto noBlt2;
526 stock = SelectObject(memHdc, dib);
527 if(!stock)
529 ERR("Failed selecting converted DIB into temporary memory DC\n");
530 DeleteObject(dib);
531 DeleteDC(memHdc);
532 res = 0;
533 goto noBlt2;
535 res = StretchBlt(physDevDst->hdc, xDst, yDst, widthDst, heightDst, memHdc, 0, 0, widthSrc, widthDst, rop);
537 SelectObject(memHdc, stock);
538 DeleteObject(dib);
539 DeleteDC(memHdc);
540 noBlt2:
545 else /* dest is a DDB */
547 /* DDB selected on dest DC, use X11 Driver */
548 if(!physDevSrc || !physDevSrc->hasDIB)
550 /* source is null or has also a DDB, no need to convert anything */
551 res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst,
552 physDevSrc ? physDevSrc->X11PhysDev : 0, xSrc, ySrc, widthSrc, heightSrc, rop);
554 else
556 /* DIB on source, DDB on dest -- must convert source DIB to DDB and use X11 driver for blit */
557 HBITMAP dib, ddb;
559 /* clip blit area */
560 if(physDevSrc)
562 RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height};
563 res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, &srcClip, 0);
565 else
566 res = TRUE;
567 if(!res)
568 goto noBlt3;
569 xDst = pd.x; yDst = pd.y; widthDst = szDst.cx; heightDst = szDst.cy;
570 xSrc = ps.x; ySrc = ps.y; widthSrc = szSrc.cx; heightSrc = szSrc.cy;
572 dib = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP));
573 if(!dib)
575 ERR("Couldn't select out DIB from source HDC\n");
576 res = 0;
577 goto noBlt3;
579 ddb = _DIBDRV_ConvertDIBtoDDB(physDevSrc->hdc, dib, ySrc, heightSrc);
580 if(!ddb)
582 ERR("Failed converting source DIB to DDB\n");
583 SelectObject(physDevSrc->hdc, dib);
584 res = 0;
585 goto noBlt3;
587 if(!SelectObject(physDevSrc->hdc, ddb))
589 ERR("Failed to select converted DDB into source HDC\n");
590 SelectObject(physDevSrc->hdc, dib);
591 DeleteObject(ddb);
592 res = 0;
593 goto noBlt3;
595 res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst,
596 physDevSrc ? physDevSrc->X11PhysDev : 0, xSrc, 0, widthSrc, heightSrc, rop);
597 SelectObject(physDevSrc->hdc, dib);
598 DeleteObject(ddb);
599 noBlt3:
603 return res;
606 /***********************************************************************
607 * DIBDRV_PatBlt
609 BOOL DIBDRV_PatBlt( DIBDRVPHYSDEV *physDev, INT left, INT top, INT width, INT height, DWORD rop )
611 BOOL res;
613 MAYBE(TRACE("physDev:%p, left:%d, top:%d, width:%d, height:%d, rop:%06x\n", physDev, left, top, width, height, rop));
615 if(physDev->hasDIB)
617 /* DIB section selected in, use DIB Engine */
618 ONCE(FIXME("TEMPORARY - use BitBlt by now\n"));
619 res = DIBDRV_BitBlt(physDev, left, top, width, height, NULL, 0, 0, rop);
621 else
623 /* DDB selected in, use X11 driver */
624 res = _DIBDRV_GetDisplayDriver()->pPatBlt(physDev->X11PhysDev, left, top, width, height, rop);
626 return res;