winex11: Add support for 16-bit/32-bit DIB sections.

This commit is contained in:
Roderick Colenbrander 2009-09-26 14:52:46 +02:00 committed by Alexandre Julliard
parent 0c70291c2c
commit 6b8753185f
3 changed files with 62 additions and 11 deletions

View File

@ -4744,19 +4744,23 @@ HBITMAP CDECL X11DRV_CreateDIBSection( X11DRV_PDEVICE *physDev, HBITMAP hbitmap,
&physBitmap->nColorMap );
}
if (!X11DRV_XRender_SetPhysBitmapDepth( physBitmap, &dib ))
{
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();
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);
}
#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");

View File

@ -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,

View File

@ -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,