Module: wine Branch: master Commit: c29cf0591976f96c3adb30c3c3b6db59f4983251 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c29cf0591976f96c3adb30c3c3...
Author: Roderick Colenbrander thunderbird2k@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; }