Oops. Forgot the patches. Here they are.
And the very second I sent the last E-Mail the DIB engine work got
accepted as a SoC project (by someone else)... I've no idea what this
means to me. Someone clarify please. :)
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c
index 00bf375..5debebd 100644
--- a/dlls/winex11.drv/bitblt.c
+++ b/dlls/winex11.drv/bitblt.c
@@ -1515,7 +1515,7 @@ BOOL X11DRV_PatBlt( X11DRV_PDEVICE *physDev, INT left, INT top, INT width, INT h
{
BOOL result;
- X11DRV_LockDIBSection( physDev, DIB_Status_GdiMod, FALSE );
+ X11DRV_LockDIBSection( physDev, DIB_Status_GdiMod, TRUE );
result = BITBLT_InternalStretchBlt( physDev, left, top, width, height, NULL, 0, 0, 0, 0, rop );
X11DRV_UnlockDIBSection( physDev, TRUE );
return result;
@@ -1643,7 +1643,7 @@ BOOL X11DRV_BitBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst,
INT xSrc, INT ySrc, DWORD rop )
{
BOOL result = FALSE;
- INT sSrc, sDst;
+ INT sSrc = DIB_Status_None, sDst = DIB_Status_None;
RECT visRectDst, visRectSrc;
if (((rop >> 16) & 0x55) == ((rop >> 17) & 0x55)) {
@@ -1653,11 +1653,12 @@ BOOL X11DRV_BitBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst,
* which may avoid a copy in some situations */
}
- sDst = X11DRV_LockDIBSection( physDevDst, DIB_Status_None, FALSE );
- if (physDevDst != physDevSrc)
- sSrc = X11DRV_LockDIBSection( physDevSrc, DIB_Status_None, FALSE );
+ if (physDevDst && physDevDst->bitmap)
+ sDst = X11DRV_DIB_Lock( physDevDst->bitmap, DIB_Status_None, FALSE );
+ if (physDevSrc && physDevSrc->bitmap && physDevDst != physDevSrc)
+ sSrc = X11DRV_DIB_Lock( physDevSrc->bitmap, DIB_Status_None, FALSE );
else
- sSrc = sDst;
+ sSrc = sDst;
if ((sSrc == DIB_Status_AppMod) && (rop == SRCCOPY) &&
(physDevSrc->depth == physDevDst->depth))
@@ -1723,9 +1724,10 @@ BOOL X11DRV_BitBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst,
physDevSrc, xSrc, ySrc, width, height, rop );
END:
- if (physDevDst != physDevSrc)
- X11DRV_UnlockDIBSection( physDevSrc, FALSE );
- X11DRV_UnlockDIBSection( physDevDst, TRUE );
+ if (physDevSrc && physDevSrc->bitmap && physDevDst != physDevSrc)
+ X11DRV_DIB_Unlock( physDevSrc->bitmap, FALSE );
+ if (physDevDst && physDevDst->bitmap)
+ X11DRV_DIB_Unlock( physDevDst->bitmap, TRUE );
return result;
}
@@ -1741,9 +1743,9 @@ BOOL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst,
{
BOOL result;
- X11DRV_LockDIBSection( physDevDst, DIB_Status_GdiMod, FALSE );
+ X11DRV_LockDIBSection( physDevDst, DIB_Status_GdiMod, TRUE );
if (physDevDst != physDevSrc)
- X11DRV_LockDIBSection( physDevSrc, DIB_Status_GdiMod, FALSE );
+ X11DRV_LockDIBSection( physDevSrc, DIB_Status_GdiMod, TRUE );
result = BITBLT_InternalStretchBlt( physDevDst, xDst, yDst, widthDst, heightDst,
physDevSrc, xSrc, ySrc, widthSrc, heightSrc, rop );
diff --git a/dlls/winex11.drv/dib.c b/dlls/winex11.drv/dib.c
index c921034..bd923c2 100644
--- a/dlls/winex11.drv/dib.c
+++ b/dlls/winex11.drv/dib.c
@@ -98,8 +98,6 @@ enum Rle_EscapeCodes
static INT X11DRV_DIB_Coerce(X_PHYSBITMAP *,INT,BOOL);
-static INT X11DRV_DIB_Lock(X_PHYSBITMAP *,INT,BOOL);
-static void X11DRV_DIB_Unlock(X_PHYSBITMAP *,BOOL);
/*
Some of the following helper functions are duplicated in
@@ -3787,7 +3785,7 @@ INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWO
if (!cx || !cy) return lines;
/* Update the pixmap from the DIB section */
- X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
+ X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, TRUE);
X11DRV_SetupGCForText( physDev ); /* To have the correct colors */
wine_tsx11_lock();
@@ -4413,7 +4411,7 @@ static INT X11DRV_DIB_Coerce(X_PHYSBITMAP *physBitmap, INT req, BOOL lossy)
/***********************************************************************
* X11DRV_DIB_Lock
*/
-static INT X11DRV_DIB_Lock(X_PHYSBITMAP *physBitmap, INT req, BOOL lossy)
+INT X11DRV_DIB_Lock(X_PHYSBITMAP *physBitmap, INT req, BOOL lossy)
{
INT ret = DIB_Status_None;
@@ -4429,7 +4427,7 @@ static INT X11DRV_DIB_Lock(X_PHYSBITMAP *physBitmap, INT req, BOOL lossy)
/***********************************************************************
* X11DRV_DIB_Unlock
*/
-static void X11DRV_DIB_Unlock(X_PHYSBITMAP *physBitmap, BOOL commit)
+void X11DRV_DIB_Unlock(X_PHYSBITMAP *physBitmap, BOOL commit)
{
if (!physBitmap->image) return; /* not a DIB section */
switch (physBitmap->status)
@@ -4496,10 +4494,17 @@ INT X11DRV_CoerceDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
/***********************************************************************
* X11DRV_LockDIBSection
*/
-INT X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
+HBITMAP X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL force)
{
- if (!physDev || !physDev->bitmap) return DIB_Status_None;
- return X11DRV_DIB_Lock(physDev->bitmap, req, lossy);
+ if (!physDev || !physDev->bitmap) return NULL;
+
+ if (force)
+ X11DRV_DIB_Lock(physDev->bitmap, req, FALSE);
+ else
+ if (X11DRV_DIB_Lock(physDev->bitmap, DIB_Status_None, FALSE) != req)
+ return NULL;
+
+ return physDev->bitmap->hbitmap;
}
/***********************************************************************
diff --git a/dlls/winex11.drv/graphics.c b/dlls/winex11.drv/graphics.c
index 638356b..fcbda87 100644
--- a/dlls/winex11.drv/graphics.c
+++ b/dlls/winex11.drv/graphics.c
@@ -333,7 +333,7 @@ X11DRV_LineTo( X11DRV_PDEVICE *physDev, INT x, INT y )
if (X11DRV_SetupGCForPen( physDev )) {
/* Update the pixmap from the DIB section */
- X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
+ X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, TRUE);
GetCurrentPositionEx( physDev->hdc, &pt[0] );
pt[1].x = x;
@@ -429,7 +429,7 @@ X11DRV_DrawArc( X11DRV_PDEVICE *physDev, INT left, INT top, INT right,
if (idiff_angle <= 0) idiff_angle += 360 * 64;
/* Update the pixmap from the DIB section */
- X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
+ X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, TRUE);
/* Fill arc with brush if Chord() or Pie() */
@@ -589,7 +589,7 @@ X11DRV_Ellipse( X11DRV_PDEVICE *physDev, INT left, INT top, INT right, INT botto
physDev->pen.width = width;
/* Update the pixmap from the DIB section */
- X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
+ X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, TRUE);
if (X11DRV_SetupGCForBrush( physDev ))
{
@@ -658,7 +658,7 @@ X11DRV_Rectangle(X11DRV_PDEVICE *physDev, INT left, INT top, INT right, INT bott
physDev->pen.linejoin = PS_JOIN_MITER;
/* Update the pixmap from the DIB section */
- X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
+ X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, TRUE);
if ((rc.right > rc.left + width) && (rc.bottom > rc.top + width))
{
@@ -745,7 +745,7 @@ X11DRV_RoundRect( X11DRV_PDEVICE *physDev, INT left, INT top, INT right,
physDev->pen.endcap = PS_ENDCAP_SQUARE;
/* Update the pixmap from the DIB section */
- X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
+ X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, TRUE);
wine_tsx11_lock();
if (X11DRV_SetupGCForBrush( physDev ))
@@ -914,7 +914,7 @@ X11DRV_SetPixel( X11DRV_PDEVICE *physDev, INT x, INT y, COLORREF color )
pixel = X11DRV_PALETTE_ToPhysical( physDev, color );
/* Update the pixmap from the DIB section */
- X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
+ X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, TRUE);
/* inefficient but simple... */
wine_tsx11_lock();
@@ -948,7 +948,7 @@ X11DRV_GetPixel( X11DRV_PDEVICE *physDev, INT x, INT y )
LPtoDP( physDev->hdc, &pt, 1 );
/* Update the pixmap from the DIB section */
- X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
+ X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, TRUE);
wine_tsx11_lock();
if (memdc)
@@ -998,7 +998,7 @@ X11DRV_PaintRgn( X11DRV_PDEVICE *physDev, HRGN hrgn )
rect[i].y += physDev->dc_rect.top;
}
- X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
+ X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, TRUE);
wine_tsx11_lock();
XFillRectangles( gdi_display, physDev->drawable, physDev->gc, rect, data->rdh.nCount );
wine_tsx11_unlock();
@@ -1032,7 +1032,7 @@ X11DRV_Polyline( X11DRV_PDEVICE *physDev, const POINT* pt, INT count )
if (X11DRV_SetupGCForPen ( physDev ))
{
- X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
+ X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, TRUE);
wine_tsx11_lock();
XDrawLines( gdi_display, physDev->drawable, physDev->gc,
points, count, CoordModeOrigin );
@@ -1070,7 +1070,7 @@ X11DRV_Polygon( X11DRV_PDEVICE *physDev, const POINT* pt, INT count )
points[count] = points[0];
/* Update the pixmap from the DIB section */
- X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
+ X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, TRUE);
if (X11DRV_SetupGCForBrush( physDev ))
{
@@ -1121,7 +1121,7 @@ X11DRV_PolyPolygon( X11DRV_PDEVICE *physDev, const POINT* pt, const INT* counts,
XPoint *points;
/* Update the pixmap from the DIB section */
- X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
+ X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, TRUE);
for (i = 0; i < polygons; i++) if (counts[i] > max) max = counts[i];
if (!(points = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * (max+1) )))
@@ -1167,7 +1167,7 @@ X11DRV_PolyPolyline( X11DRV_PDEVICE *physDev, const POINT* pt, const DWORD* coun
XPoint *points;
/* Update the pixmap from the DIB section */
- X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
+ X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, TRUE);
for (i = 0; i < polylines; i++) if (counts[i] > max) max = counts[i];
if (!(points = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * max )))
@@ -1306,7 +1306,7 @@ X11DRV_ExtFloodFill( X11DRV_PDEVICE *physDev, INT x, INT y, COLORREF color,
if (X11DRV_SetupGCForBrush( physDev ))
{
/* Update the pixmap from the DIB section */
- X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
+ X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, TRUE);
/* ROP mode is always GXcopy for flood-fill */
wine_tsx11_lock();
diff --git a/dlls/winex11.drv/text.c b/dlls/winex11.drv/text.c
index 57e5cd8..c51aa25 100644
--- a/dlls/winex11.drv/text.c
+++ b/dlls/winex11.drv/text.c
@@ -76,7 +76,7 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
if (flags & ETO_OPAQUE)
{
- X11DRV_LockDIBSection( physDev, DIB_Status_GdiMod, FALSE );
+ X11DRV_LockDIBSection( physDev, DIB_Status_GdiMod, TRUE );
dibUpdateFlag = TRUE;
wine_tsx11_lock();
XSetForeground( gdi_display, physDev->gc, physDev->backgroundPixel );
@@ -106,7 +106,7 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
if (!dibUpdateFlag)
{
- X11DRV_LockDIBSection( physDev, DIB_Status_GdiMod, FALSE );
+ X11DRV_LockDIBSection( physDev, DIB_Status_GdiMod, TRUE );
dibUpdateFlag = TRUE;
}
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 8de2e25..6ab20c4 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -418,8 +418,10 @@ extern const dib_conversions dib_normal, dib_src_byteswap, dib_dst_byteswap;
extern INT X11DRV_DIB_MaskToShift(DWORD mask);
extern INT X11DRV_CoerceDIBSection(X11DRV_PDEVICE *physDev,INT,BOOL);
-extern INT X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev,INT,BOOL);
+extern HBITMAP X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev,BOOL,BOOL);
extern void X11DRV_UnlockDIBSection(X11DRV_PDEVICE *physDev,BOOL);
+extern INT X11DRV_DIB_Lock(X_PHYSBITMAP *,INT,BOOL);
+extern void X11DRV_DIB_Unlock(X_PHYSBITMAP *,BOOL);
extern void X11DRV_DIB_DeleteDIBSection(X_PHYSBITMAP *physBitmap, DIBSECTION *dib);
extern void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c
index e03540e..3c0b5b7 100644
--- a/dlls/winex11.drv/xrender.c
+++ b/dlls/winex11.drv/xrender.c
@@ -1100,7 +1100,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
XChangeGC( gdi_display, physDev->gc, GCFunction | GCBackground | GCFillStyle, &xgcval );
wine_tsx11_unlock();
- X11DRV_LockDIBSection( physDev, DIB_Status_GdiMod, FALSE );
+ X11DRV_LockDIBSection( physDev, DIB_Status_GdiMod, TRUE );
if(physDev->depth == 1) {
if((physDev->textPixel & 0xffffff) == 0) {
diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c
index 9d472ef..ad93932 100644
--- a/dlls/gdi32/driver.c
+++ b/dlls/gdi32/driver.c
@@ -125,6 +125,7 @@ static struct graphics_driver *create_driver( HMODULE module )
GET_FUNC(IntersectClipRect);
GET_FUNC(InvertRgn);
GET_FUNC(LineTo);
+ GET_FUNC(LockDIBSection);
GET_FUNC(MoveTo);
GET_FUNC(ModifyWorldTransform);
GET_FUNC(OffsetClipRgn);
@@ -193,6 +194,7 @@ static struct graphics_driver *create_driver( HMODULE module )
GET_FUNC(StrokePath);
GET_FUNC(SwapBuffers);
GET_FUNC(UnrealizePalette);
+ GET_FUNC(UnlockDIBSection);
GET_FUNC(WidenPath);
/* OpenGL32 */
diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c
index 4f418e1..57856d5 100644
--- a/dlls/gdi32/enhmfdrv/init.c
+++ b/dlls/gdi32/enhmfdrv/init.c
@@ -84,6 +84,7 @@ static const DC_FUNCTIONS EMFDRV_Funcs =
EMFDRV_IntersectClipRect, /* pIntersectClipRect */
EMFDRV_InvertRgn, /* pInvertRgn */
EMFDRV_LineTo, /* pLineTo */
+ NULL, /* pLockDIBSection */
EMFDRV_ModifyWorldTransform, /* pModifyWorldTransform */
EMFDRV_MoveTo, /* pMoveTo */
EMFDRV_OffsetClipRgn, /* pOffsetClipRgn */
@@ -151,6 +152,7 @@ static const DC_FUNCTIONS EMFDRV_Funcs =
EMFDRV_StrokeAndFillPath, /* pStrokeAndFillPath */
EMFDRV_StrokePath, /* pStrokePath */
NULL, /* pSwapBuffers */
+ NULL, /* pUnlockDIBSection */
NULL, /* pUnrealizePalette */
EMFDRV_WidenPath /* pWidenPath */
};
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index e43ac30..6d06e02 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -97,6 +97,9 @@ typedef struct tagGDIOBJHDR
typedef struct { int opaque; } *PHYSDEV; /* PHYSDEV is an opaque pointer */
+/* For pLockDIBSection() */
+enum { DIB_Status_None, DIB_Status_InSync, DIB_Status_GdiMod, DIB_Status_AppMod };
+
typedef struct tagDC_FUNCS
{
INT (*pAbortDoc)(PHYSDEV);
@@ -150,6 +153,7 @@ typedef struct tagDC_FUNCS
INT (*pIntersectClipRect)(PHYSDEV,INT,INT,INT,INT);
BOOL (*pInvertRgn)(PHYSDEV,HRGN);
BOOL (*pLineTo)(PHYSDEV,INT,INT);
+ HBITMAP (*pLockDIBSection)(PHYSDEV,BOOL,BOOL);
BOOL (*pModifyWorldTransform)(PHYSDEV,const XFORM*,INT);
BOOL (*pMoveTo)(PHYSDEV,INT,INT);
INT (*pOffsetClipRgn)(PHYSDEV,INT,INT);
@@ -219,6 +223,7 @@ typedef struct tagDC_FUNCS
BOOL (*pStrokeAndFillPath)(PHYSDEV);
BOOL (*pStrokePath)(PHYSDEV);
BOOL (*pSwapBuffers)(PHYSDEV);
+ VOID (*pUnlockDIBSection)(PHYSDEV,BOOL);
BOOL (*pUnrealizePalette)(HPALETTE);
BOOL (*pWidenPath)(PHYSDEV);
diff --git a/dlls/gdi32/mfdrv/init.c b/dlls/gdi32/mfdrv/init.c
index e939ce1..88e102d 100644
--- a/dlls/gdi32/mfdrv/init.c
+++ b/dlls/gdi32/mfdrv/init.c
@@ -84,6 +84,7 @@ static const DC_FUNCTIONS MFDRV_Funcs =
MFDRV_IntersectClipRect, /* pIntersectClipRect */
MFDRV_InvertRgn, /* pInvertRgn */
MFDRV_LineTo, /* pLineTo */
+ NULL, /* pLockDIBSection */
NULL, /* pModifyWorldTransform */
MFDRV_MoveTo, /* pMoveTo */
MFDRV_OffsetClipRgn, /* pOffsetClipRgn */
@@ -151,6 +152,7 @@ static const DC_FUNCTIONS MFDRV_Funcs =
MFDRV_StrokeAndFillPath, /* pStrokeAndFillPath */
MFDRV_StrokePath, /* pStrokePath */
NULL, /* pSwapBuffers */
+ NULL, /* pUnlockDIBSection */
NULL, /* pUnrealizePalette */
MFDRV_WidenPath /* pWidenPath */
};
diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec
index 6a6c173..abb9279 100644
--- a/dlls/winex11.drv/winex11.drv.spec
+++ b/dlls/winex11.drv/winex11.drv.spec
@@ -29,6 +29,7 @@
@ cdecl GetTextExtentExPoint(ptr ptr long long ptr ptr ptr) X11DRV_GetTextExtentExPoint
@ cdecl GetTextMetrics(ptr ptr) X11DRV_GetTextMetrics
@ cdecl LineTo(ptr long long) X11DRV_LineTo
+@ cdecl LockDIBSection(ptr long long) X11DRV_LockDIBSection
@ cdecl PaintRgn(ptr long) X11DRV_PaintRgn
@ cdecl PatBlt(ptr long long long long long) X11DRV_PatBlt
@ cdecl Pie(ptr long long long long long long long long) X11DRV_Pie
@@ -59,6 +60,7 @@
@ cdecl SetTextColor(ptr long) X11DRV_SetTextColor
@ cdecl StretchBlt(ptr long long long long ptr long long long long long) X11DRV_StretchBlt
@ cdecl SwapBuffers(ptr) X11DRV_SwapBuffers
+@ cdecl UnlockDIBSection(ptr long) X11DRV_UnlockDIBSection
@ cdecl UnrealizePalette(long) X11DRV_UnrealizePalette
# USER driver
diff --git a/dlls/gdi32/Makefile.in b/dlls/gdi32/Makefile.in
index e3b2d67..279df01 100644
--- a/dlls/gdi32/Makefile.in
+++ b/dlls/gdi32/Makefile.in
@@ -22,6 +22,7 @@ C_SRCS = \
clipping.c \
dc.c \
dib.c \
+ dibdrv.c \
driver.c \
enhmetafile.c \
enhmfdrv/bitblt.c \
diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c
index d16e70f..d59906b 100644
--- a/dlls/gdi32/bitmap.c
+++ b/dlls/gdi32/bitmap.c
@@ -586,6 +586,18 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
if (handle)
{
+ BITMAPOBJ *old = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
+ if (old)
+ {
+ /* When switching from non-DIB to DIB or vice versa adjust
+ * DC function pointers. */
+ if (!old->dib && bitmap->dib)
+ DIBDRV_Install( dc, bitmap );
+ else if (old->dib && !bitmap->dib)
+ DIBDRV_Remove( dc, old );
+ }
+ GDI_ReleaseObj( old );
+
dc->hBitmap = handle;
dc->flags &= ~DC_DIRTY;
SetRectRgn( dc->hVisRgn, 0, 0, bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight);
diff --git a/dlls/gdi32/dibdrv.c b/dlls/gdi32/dibdrv.c
new file mode 100644
index 0000000..e4a216e
--- /dev/null
+++ b/dlls/gdi32/dibdrv.c
@@ -0,0 +1,190 @@
+/*
+ * DIB driver
+ *
+ * Copyright 2007 Felix Nawothnig
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+
+#include "gdi_private.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+static const DC_FUNCTIONS DIBDRV_Funcs =
+{
+ NULL, /* pAbortDoc */
+ NULL, /* pAbortPath */
+ NULL, /* pAlphaBlend */
+ NULL, /* pAngleArc */
+ NULL, /* pArc */
+ NULL, /* pArcTo */
+ NULL, /* pBeginPath */
+ NULL, /* pBitBlt */
+ NULL, /* pChoosePixelFormat */
+ NULL, /* pChord */
+ NULL, /* pCloseFigure */
+ NULL, /* pCreateBitmap */
+ NULL, /* pCreateDC */
+ NULL, /* pCreateDIBSection */
+ NULL, /* pDeleteBitmap */
+ NULL, /* pDeleteDC */
+ NULL, /* pDeleteObject */
+ NULL, /* pDescribePixelFormat */
+ NULL, /* pDeviceCapabilities */
+ NULL, /* pEllipse */
+ NULL, /* pEndDoc */
+ NULL, /* pEndPage */
+ NULL, /* pEndPath */
+ NULL, /* pEnumDeviceFonts */
+ NULL, /* pExcludeClipRect */
+ NULL, /* pExtDeviceMode */
+ NULL, /* pExtEscape */
+ NULL, /* pExtFloodFill */
+ NULL, /* pExtSelectClipRgn */
+ NULL, /* pExtTextOut */
+ NULL, /* pFillPath */
+ NULL, /* pFillRgn */
+ NULL, /* pFlattenPath */
+ NULL, /* pFrameRgn */
+ NULL, /* pGdiComment */
+ NULL, /* pGetBitmapBits */
+ NULL, /* pGetCharWidth */
+ NULL, /* pGetDCOrgEx */
+ NULL, /* pGetDIBColorTable */
+ NULL, /* pGetDIBits */
+ NULL, /* pGetDeviceCaps */
+ NULL, /* pGetDeviceGammaRamp */
+ NULL, /* pGetNearestColor */
+ NULL, /* pGetPixel */
+ NULL, /* pGetPixelFormat */
+ NULL, /* pGetSystemPaletteEntries */
+ NULL, /* pGetTextExtentExPoint */
+ NULL, /* pGetTextMetrics */
+ NULL, /* pIntersectClipRect */
+ NULL, /* pInvertRgn */
+ NULL, /* pLineTo */
+ NULL, /* pLockDIBSection */
+ NULL, /* pModifyWorldTransform */
+ NULL, /* pMoveTo */
+ NULL, /* pOffsetClipRgn */
+ NULL, /* pOffsetViewportOrg */
+ NULL, /* pOffsetWindowOrg */
+ NULL, /* pPaintRgn */
+ NULL, /* pPatBlt */
+ NULL, /* pPie */
+ NULL, /* pPolyBezier */
+ NULL, /* pPolyBezierTo */
+ NULL, /* pPolyDraw */
+ NULL, /* pPolyPolygon */
+ NULL, /* pPolyPolyline */
+ NULL, /* pPolygon */
+ NULL, /* pPolyline */
+ NULL, /* pPolylineTo */
+ NULL, /* pRealizeDefaultPalette */
+ NULL, /* pRealizePalette */
+ NULL, /* pRectangle */
+ NULL, /* pResetDC */
+ NULL, /* pRestoreDC */
+ NULL, /* pRoundRect */
+ NULL, /* pSaveDC */
+ NULL, /* pScaleViewportExt */
+ NULL, /* pScaleWindowExt */
+ NULL, /* pSelectBitmap */
+ NULL, /* pSelectBrush */
+ NULL, /* pSelectClipPath */
+ NULL, /* pSelectFont */
+ NULL, /* pSelectPalette */
+ NULL, /* pSelectPen */
+ NULL, /* pSetArcDirection */
+ NULL, /* pSetBitmapBits */
+ NULL, /* pSetBkColor */
+ NULL, /* pSetBkMode */
+ NULL, /* pSetDCBrushColor*/
+ NULL, /* pSetDCOrg */
+ NULL, /* pSetDCPenColor*/
+ NULL, /* pSetDIBColorTable */
+ NULL, /* pSetDIBits */
+ NULL, /* pSetDIBitsToDevice */
+ NULL, /* pSetDeviceClipping */
+ NULL, /* pSetDeviceGammaRamp */
+ NULL, /* pSetMapMode */
+ NULL, /* pSetMapperFlags */
+ NULL, /* pSetPixel */
+ NULL, /* pSetPixelFormat */
+ NULL, /* pSetPolyFillMode */
+ NULL, /* pSetROP2 */
+ NULL, /* pSetRelAbs */
+ NULL, /* pSetStretchBltMode */
+ NULL, /* pSetTextAlign */
+ NULL, /* pSetTextCharacterExtra */
+ NULL, /* pSetTextColor */
+ NULL, /* pSetTextJustification */
+ NULL, /* pSetViewportExt */
+ NULL, /* pSetViewportOrg */
+ NULL, /* pSetWindowExt */
+ NULL, /* pSetWindowOrg */
+ NULL, /* pSetWorldTransform */
+ NULL, /* pStartDoc */
+ NULL, /* pStartPage */
+ NULL, /* pStretchBlt */
+ NULL, /* pStretchDIBits */
+ NULL, /* pStrokeAndFillPath */
+ NULL, /* pStrokePath */
+ NULL, /* pSwapBuffers */
+ NULL, /* pUnlockDIBSection */
+ NULL, /* pUnrealizePalette */
+ NULL /* pWidenPath */
+};
+
+/***********************************************************************
+ * DIBDRV_Install
+ *
+ * Note: We do not use DRIVER_load_driver because we want to forward
+ * unimplemented functions to the DC driver.
+ */
+void DIBDRV_Install(DC *dc, BITMAPOBJ *bmp)
+{
+ int i;
+
+ TRACE("(%p,%p)\n", dc, bmp);
+
+ bmp->orig_funcs = dc->funcs;
+ dc->funcs = &bmp->local_funcs;
+
+ memcpy(&bmp->local_funcs, bmp->orig_funcs, sizeof(DC_FUNCTIONS));
+
+ /* Overload implemented functions */
+ for(i = 0; i < sizeof(DC_FUNCTIONS) / sizeof(void *); i++)
+ if(((void **)&DIBDRV_Funcs)[i])
+ ((void **)dc->funcs)[i] = ((void **)&DIBDRV_Funcs)[i];
+}
+
+/***********************************************************************
+ * DIBDRV_Remove
+ */
+void DIBDRV_Remove(DC *dc, BITMAPOBJ *bmp)
+{
+ TRACE("(%p,%p)\n", dc, bmp);
+
+ dc->funcs = bmp->orig_funcs;
+}
+
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 6d06e02..cb8f7f4 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -367,6 +367,8 @@ typedef struct tagBITMAPOBJ
const DC_FUNCTIONS *funcs; /* DC function table */
/* For device-independent bitmaps: */
DIBSECTION *dib;
+ const DC_FUNCTIONS *orig_funcs;
+ DC_FUNCTIONS local_funcs;
SEGPTR segptr_bits; /* segptr to DIB bits */
RGBQUAD *color_table; /* DIB color table if <= 8bpp */
UINT nb_colors; /* number of colors in table */
@@ -408,6 +410,10 @@ extern int DIB_GetDIBWidthBytes( int width, int depth );
extern int DIB_GetDIBImageBytes( int width, int height, int depth );
extern int DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse );
+/* dibdrv.c */
+extern void DIBDRV_Install( DC *dc, BITMAPOBJ *bmp );
+extern void DIBDRV_Remove( DC *dc, BITMAPOBJ *bmp );
+
/* driver.c */
extern const DC_FUNCTIONS *DRIVER_load_driver( LPCWSTR name );
extern const DC_FUNCTIONS *DRIVER_get_driver( const DC_FUNCTIONS *funcs );