Roderick Colenbrander : winex11: Add support for 32-bit DDBs.

Alexandre Julliard julliard at winehq.org
Tue Apr 13 11:24:41 CDT 2010


Module: wine
Branch: master
Commit: c29cf0591976f96c3adb30c3c3b6db59f4983251
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c29cf0591976f96c3adb30c3c3b6db59f4983251

Author: Roderick Colenbrander <thunderbird2k at gmail.com>
Date:   Tue Apr  6 19:07:25 2010 +0200

winex11: Add support for 32-bit DDBs.

---

 dlls/gdi32/tests/bitmap.c  |   49 ++++++++++++++++++++++++++++++++++
 dlls/winex11.drv/bitmap.c  |   26 ++++++++++-------
 dlls/winex11.drv/dib.c     |    2 +-
 dlls/winex11.drv/x11drv.h  |    2 +-
 dlls/winex11.drv/xrender.c |   63 ++++++++++++++++++++++++++++++++++----------
 5 files changed, 115 insertions(+), 27 deletions(-)

diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index df658ff..882d548 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -2852,6 +2852,54 @@ static void test_clipping(void)
     DeleteDC( hdcSrc );
 }
 
+static void test_32bit_bitmap_blt(void)
+{
+    BITMAPINFO biDst;
+    HBITMAP bmpSrc, bmpDst;
+    HBITMAP oldSrc, oldDst;
+    HDC hdcSrc, hdcDst, hdcScreen;
+    UINT32 *dstBuffer;
+    DWORD colorSrc = 0x11223344;
+
+    memset(&biDst, 0, sizeof(BITMAPINFO));
+    biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    biDst.bmiHeader.biWidth = 2;
+    biDst.bmiHeader.biHeight = -2;
+    biDst.bmiHeader.biPlanes = 1;
+    biDst.bmiHeader.biBitCount = 32;
+    biDst.bmiHeader.biCompression = BI_RGB;
+
+    hdcScreen = CreateCompatibleDC(0);
+    if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
+    {
+        DeleteDC(hdcScreen);
+        trace("Skipping 32-bit DDB test\n");
+        return;
+    }
+
+    hdcSrc = CreateCompatibleDC(hdcScreen);
+    bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
+    oldSrc = SelectObject(hdcSrc, bmpSrc);
+
+    hdcDst = CreateCompatibleDC(hdcScreen);
+    bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
+    oldDst = SelectObject(hdcDst, bmpDst);
+
+    StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
+    ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
+
+    /* Tidy up */
+    SelectObject(hdcDst, oldDst);
+    DeleteObject(bmpDst);
+    DeleteDC(hdcDst);
+
+    SelectObject(hdcSrc, oldSrc);
+    DeleteObject(bmpSrc);
+    DeleteDC(hdcSrc);
+
+    DeleteDC(hdcScreen);
+}
+
 START_TEST(bitmap)
 {
     HMODULE hdll;
@@ -2878,6 +2926,7 @@ START_TEST(bitmap)
     test_StretchBlt();
     test_StretchDIBits();
     test_GdiAlphaBlend();
+    test_32bit_bitmap_blt();
     test_bitmapinfoheadersize();
     test_get16dibits();
     test_clipping();
diff --git a/dlls/winex11.drv/bitmap.c b/dlls/winex11.drv/bitmap.c
index 5992b31..4683fd9 100644
--- a/dlls/winex11.drv/bitmap.c
+++ b/dlls/winex11.drv/bitmap.c
@@ -158,19 +158,23 @@ BOOL CDECL X11DRV_CreateBitmap( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, LPVOID
 
     if (!(physBitmap = X11DRV_init_phys_bitmap( hbitmap ))) return FALSE;
 
-      /* Create the pixmap */
-    wine_tsx11_lock();
-    if(bitmap.bmBitsPixel == 1)
-    {
-        physBitmap->pixmap_depth = 1;
-        physBitmap->trueColor = FALSE;
-    }
-    else
+    if (!X11DRV_XRender_SetPhysBitmapDepth( physBitmap, bitmap.bmBitsPixel, NULL ))
     {
-        physBitmap->pixmap_depth = screen_depth;
-        physBitmap->pixmap_color_shifts = X11DRV_PALETTE_default_shifts;
-        physBitmap->trueColor = (visual->class == TrueColor || visual->class == DirectColor);
+        if(bitmap.bmBitsPixel == 1)
+        {
+            physBitmap->pixmap_depth = 1;
+            physBitmap->trueColor = FALSE;
+        }
+        else
+        {
+            physBitmap->pixmap_depth = screen_depth;
+            physBitmap->pixmap_color_shifts = X11DRV_PALETTE_default_shifts;
+            physBitmap->trueColor = (visual->class == TrueColor || visual->class == DirectColor);
+        }
     }
+
+    wine_tsx11_lock();
+    /* Create the pixmap */
     physBitmap->pixmap = XCreatePixmap(gdi_display, root_window,
                                        bitmap.bmWidth, bitmap.bmHeight, physBitmap->pixmap_depth);
     wine_tsx11_unlock();
diff --git a/dlls/winex11.drv/dib.c b/dlls/winex11.drv/dib.c
index ed65af3..4cdec0e 100644
--- a/dlls/winex11.drv/dib.c
+++ b/dlls/winex11.drv/dib.c
@@ -4750,7 +4750,7 @@ HBITMAP CDECL X11DRV_CreateDIBSection( X11DRV_PDEVICE *physDev, HBITMAP hbitmap,
                                                          &physBitmap->nColorMap );
     }
 
-    if (!X11DRV_XRender_SetPhysBitmapDepth( physBitmap, &dib ))
+    if (!X11DRV_XRender_SetPhysBitmapDepth( physBitmap, dib.dsBm.bmBitsPixel, &dib ))
     {
         if (dib.dsBm.bmBitsPixel == 1)
         {
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 13d67e6..b4ccff3 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -290,7 +290,7 @@ extern void X11DRV_XRender_CopyBrush(X11DRV_PDEVICE *physDev, X_PHYSBITMAP *phys
 extern BOOL X11DRV_XRender_ExtTextOut(X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
 				      const RECT *lprect, LPCWSTR wstr,
 				      UINT count, const INT *lpDx);
-extern BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, const DIBSECTION *dib);
+extern BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, int bits_pixel, const DIBSECTION *dib);
 BOOL X11DRV_XRender_GetSrcAreaStretch(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
                                       Pixmap pixmap, GC gc,
                                       INT widthSrc, INT heightSrc,
diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c
index 27e495b..ea6d0a7 100644
--- a/dlls/winex11.drv/xrender.c
+++ b/dlls/winex11.drv/xrender.c
@@ -931,7 +931,7 @@ void X11DRV_XRender_DeleteDC(X11DRV_PDEVICE *physDev)
     return;
 }
 
-BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, const DIBSECTION *dib)
+BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, int bits_pixel, const DIBSECTION *dib)
 {
     const WineXRenderFormat *fmt;
     ColorShifts shifts;
@@ -939,23 +939,58 @@ BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, const DIBSECTIO
     /* When XRender is not around we can only use the screen_depth and when needed we perform depth conversion
      * in software. Further we also return the screen depth for paletted formats or TrueColor formats with a low
      * number of bits because XRender can't handle paletted formats and 8-bit TrueColor does not exist for XRender. */
-    if(!X11DRV_XRender_Installed || dib->dsBm.bmBitsPixel <= 8)
+    if (!X11DRV_XRender_Installed || bits_pixel <= 8)
         return FALSE;
 
-    X11DRV_PALETTE_ComputeColorShifts(&shifts, dib->dsBitfields[0], dib->dsBitfields[1], dib->dsBitfields[2]);
+    if (dib)
+    {
+        X11DRV_PALETTE_ComputeColorShifts(&shifts, dib->dsBitfields[0], dib->dsBitfields[1], dib->dsBitfields[2]);
+        fmt = get_xrender_format_from_color_shifts(dib->dsBm.bmBitsPixel, &shifts);
 
-    /* Common formats should be in our picture format table. */
-    fmt = get_xrender_format_from_color_shifts(dib->dsBm.bmBitsPixel, &shifts);
-    if(fmt)
+        /* Common formats should be in our picture format table. */
+        if (!fmt)
+        {
+            TRACE("Unhandled dibsection format bpp=%d, redMask=%x, greenMask=%x, blueMask=%x\n",
+                dib->dsBm.bmBitsPixel, dib->dsBitfields[0], dib->dsBitfields[1], dib->dsBitfields[2]);
+            return FALSE;
+        }
+    }
+    else
     {
-        physBitmap->pixmap_depth = fmt->pict_format->depth;
-        physBitmap->trueColor = TRUE;
-        physBitmap->pixmap_color_shifts = shifts;
-        return TRUE;
+        int red_mask, green_mask, blue_mask;
+
+        /* We are dealing with a DDB */
+        switch (bits_pixel)
+        {
+            case 16:
+                fmt = get_xrender_format(WXR_FORMAT_R5G6B5);
+                break;
+            case 24:
+                fmt = get_xrender_format(WXR_FORMAT_R8G8B8);
+                break;
+            case 32:
+                fmt = get_xrender_format(WXR_FORMAT_A8R8G8B8);
+                break;
+            default:
+                fmt = NULL;
+        }
+
+        if (!fmt)
+        {
+            TRACE("Unhandled DDB bits_pixel=%d\n", bits_pixel);
+            return FALSE;
+        }
+
+        red_mask = fmt->pict_format->direct.redMask << fmt->pict_format->direct.red;
+        green_mask = fmt->pict_format->direct.greenMask << fmt->pict_format->direct.green;
+        blue_mask = fmt->pict_format->direct.blueMask << fmt->pict_format->direct.blue;
+        X11DRV_PALETTE_ComputeColorShifts(&shifts, red_mask, green_mask, blue_mask);
     }
-    TRACE("Unhandled dibsection format bpp=%d, redMask=%x, greenMask=%x, blueMask=%x\n",
-          dib->dsBm.bmBitsPixel, dib->dsBitfields[0], dib->dsBitfields[1], dib->dsBitfields[2]);
-    return FALSE;
+
+    physBitmap->pixmap_depth = fmt->pict_format->depth;
+    physBitmap->trueColor = TRUE;
+    physBitmap->pixmap_color_shifts = shifts;
+    return TRUE;
 }
 
 /***********************************************************************
@@ -2278,7 +2313,7 @@ void X11DRV_XRender_CopyBrush(X11DRV_PDEVICE *physDev, X_PHYSBITMAP *physBitmap,
     wine_tsx11_unlock();
 }
 
-BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, const DIBSECTION *dib)
+BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, int bits_pixel, const DIBSECTION *dib)
 {
     return FALSE;
 }




More information about the wine-cvs mailing list