Roderick Colenbrander : winex11: Add support for 16-bit/32-bit DIB sections .
Alexandre Julliard
julliard at winehq.org
Thu Oct 1 09:48:19 CDT 2009
Module: wine
Branch: master
Commit: 6b8753185f30197047773af6a26eafd34d45367c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6b8753185f30197047773af6a26eafd34d45367c
Author: Roderick Colenbrander <thunderbird2k at 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,
More information about the wine-cvs
mailing list