See http://bugs.winehq.org/show_bug.cgi?id=3902
Hey guys, a bit of help here! I did the following changes:
-added member to X_PHYSBITMAP:
XRectangle modified_rect;
-added 2 functions:
/*********************************************************************** * X11DRV_SetBoundRect */ void X11DRV_SetBoundRect(X_PHYSBITMAP *physBitmap, INT x, INT y, INT width, INT height) { XRectangle *t; INT xMin,yMin,xMax,yMax;
if (!physBitmap) return;
t = &(physBitmap->modified_rect);
if ( t->width && t->height && /*already a valid rect inside*/ width && height ) /*not trying to invalidate rect*/ { //calculate the union of the two rectangles xMin = ((t->x < x)?t->x:x); yMin = ((t->y < y)?t->y:y); xMax = ((t->x + t->width > x + width)?(t->x + t->width):(x + width)); yMax = ((t->y + t->height > y + height)?(t->y + t->height):(y + height));
t->x = xMin; t->y = yMin; t->width = xMax - xMin; t->height = yMax - yMin;
} else { t->x = x; t->y = y; t->width = width; t->height = height; }
TRACE("(%p,%d,%d,%d,%d)\n", physBitmap->hbitmap, t->x, t->y, t->width, t->height);
}
/*********************************************************************** * X11DRV_GetBoundRect */ UINT X11DRV_GetBoundRect(X_PHYSBITMAP *physBitmap, INT *x, INT *y, INT *width, INT *height) {
DIBSECTION dib; XRectangle *t;
if (!physBitmap || GetObjectW( physBitmap->hbitmap, sizeof(dib), &dib ) != sizeof(dib)) { ERR("called for non-DIBSection!?\n"); return 1; }
t = &(physBitmap->modified_rect);
/* we should check for oversize values */ if ( (t->width > 0) && (t->height > 0) && (t->x < dib.dsBm.bmWidth) && (t->y < dib.dsBm.bmHeight) ) { *x = t->x; *y = t->y;
if (t->x + t->width > dib.dsBm.bmWidth) *width = dib.dsBm.bmWidth - t->x; else *width = t->width;
if (t->y + t->height > dib.dsBm.bmHeight) *height = dib.dsBm.bmHeight - t->y; else *height = t->height; } else { *x = 0; *y = 0; *width = dib.dsBm.bmWidth; *height = dib.dsBm.bmHeight; }
TRACE("(%p,%d,%d,%d,%d)\n", physBitmap->hbitmap, *x, *y, *width, *height);
return 0; }
-changed X11DRV_DIB_DoUpdateDIBSection like this:
static void X11DRV_DIB_DoUpdateDIBSection(X_PHYSBITMAP *physBitmap, BOOL toDIB) { INT x,y,width,height;
if ( X11DRV_GetBoundRect(physBitmap,&x,&y,&width,&height) ) return;
/*invalidate bound rect*/ X11DRV_SetBoundRect(physBitmap,0,0,0,0);
X11DRV_DIB_DoCopyDIBSection(physBitmap, toDIB, physBitmap->colorMap, physBitmap->nColorMap, physBitmap->pixmap, x, y, x, y, width, height);
}
- and finally, a GDI function calls it like this (for example bitblt):
X11DRV_SetBoundRect(physDevDst->bitmap,xDst,yDst,width,height); X11DRV_CoerceDIBSection( physDevDst, DIB_Status_GdiMod, FALSE ); if (physDevDst != physDevSrc) { X11DRV_SetBoundRect(physDevSrc->bitmap,xSrc,ySrc,width,height); X11DRV_CoerceDIBSection( physDevSrc, DIB_Status_GdiMod, FALSE ); } result = BITBLT_InternalStretchBlt( physDevDst, xDst, yDst, width, height, physDevSrc, xSrc, ySrc, width, height, rop );
END: if (physDevDst != physDevSrc) X11DRV_UnlockDIBSection( physDevSrc, FALSE ); X11DRV_UnlockDIBSection( physDevDst, TRUE );
What am i doing wrong, i mean is my logic correct ?