Module: wine Branch: master Commit: 6b8753185f30197047773af6a26eafd34d45367c URL: http://source.winehq.org/git/wine.git/?a=commit;h=6b8753185f30197047773af6a2...
Author: Roderick Colenbrander thunderbird2k@gmail.com Date: Sat Sep 26 14:52:46 2009 +0200
winex11: Add support for 16-bit/32-bit DIB sections.
---
dlls/winex11.drv/dib.c | 39 ++++++++++++++++++++++++++++----------- dlls/winex11.drv/x11drv.h | 1 + dlls/winex11.drv/xrender.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 11 deletions(-)
diff --git a/dlls/winex11.drv/dib.c b/dlls/winex11.drv/dib.c index 4b15569..1fc8812 100644 --- a/dlls/winex11.drv/dib.c +++ b/dlls/winex11.drv/dib.c @@ -4744,19 +4744,23 @@ HBITMAP CDECL X11DRV_CreateDIBSection( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, &physBitmap->nColorMap ); }
- /* create pixmap and X image */ - wine_tsx11_lock(); - if(dib.dsBm.bmBitsPixel == 1) - { - physBitmap->pixmap_depth = 1; - physBitmap->trueColor = FALSE; - } - else + if (!X11DRV_XRender_SetPhysBitmapDepth( physBitmap, &dib )) { - physBitmap->pixmap_depth = screen_depth; - physBitmap->pixmap_color_shifts = X11DRV_PALETTE_default_shifts; - physBitmap->trueColor = (visual->class == TrueColor || visual->class == DirectColor); + if (dib.dsBm.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); + } } + + /* create pixmap and X image */ + wine_tsx11_lock(); #ifdef HAVE_LIBXXSHM physBitmap->shminfo.shmid = -1;
@@ -4803,6 +4807,19 @@ HBITMAP CDECL X11DRV_CreateDIBSection( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, wine_tsx11_unlock(); if (!physBitmap->pixmap || !physBitmap->image) return 0;
+ if (physBitmap->trueColor) + { + ColorShifts *shifts = &physBitmap->pixmap_color_shifts; + + /* When XRender is around and used, we also support dibsections in other formats like 16-bit. In these + * cases we need to override the mask of XImages. The reason is that during XImage creation the masks are + * derived from a 24-bit visual (no 16-bit ones are around when X runs at 24-bit). SetImageBits and other + * functions rely on the color masks for proper color conversion, so we need to override the masks here. */ + physBitmap->image->red_mask = shifts->physicalRed.max << shifts->physicalRed.shift; + physBitmap->image->green_mask = shifts->physicalGreen.max << shifts->physicalGreen.shift; + physBitmap->image->blue_mask = shifts->physicalBlue.max << shifts->physicalBlue.shift; + } + /* install fault handler */ InitializeCriticalSection( &physBitmap->lock ); physBitmap->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": X_PHYSBITMAP.lock"); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 8f0764d..922855d 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -286,6 +286,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); 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 9280ce3..076b6d4 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -2,6 +2,7 @@ * Functions to use the XRender extension * * Copyright 2001, 2002 Huw D M Davies for CodeWeavers + * Copyright 2009 Roderick Colenbrander * * Some parts also: * Copyright 2000 Keith Packard, member of The XFree86 Project, Inc. @@ -835,6 +836,33 @@ void X11DRV_XRender_DeleteDC(X11DRV_PDEVICE *physDev) return; }
+BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, const DIBSECTION *dib) +{ + WineXRenderFormat *fmt; + ColorShifts shifts; + + /* 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) + return FALSE; + + X11DRV_PALETTE_ComputeColorShifts(&shifts, dib->dsBitfields[0], dib->dsBitfields[1], dib->dsBitfields[2]); + + /* Common formats should be in our picture format table. */ + fmt = get_xrender_format_from_color_shifts(dib->dsBm.bmBitsPixel, &shifts); + if(fmt) + { + physBitmap->pixmap_depth = fmt->pict_format->depth; + physBitmap->trueColor = TRUE; + physBitmap->pixmap_color_shifts = shifts; + return TRUE; + } + 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; +} + /*********************************************************************** * X11DRV_XRender_UpdateDrawable * @@ -2172,6 +2200,11 @@ void X11DRV_XRender_CopyBrush(X11DRV_PDEVICE *physDev, X_PHYSBITMAP *physBitmap, wine_tsx11_unlock(); }
+BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, const DIBSECTION *dib) +{ + return FALSE; +} + BOOL X11DRV_XRender_GetSrcAreaStretch(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst, Pixmap pixmap, GC gc, INT widthSrc, INT heightSrc,