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