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