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 );


Reply via email to