winex11: Implement the CreateBitmap entry point in the XRender driver.

This commit is contained in:
Alexandre Julliard 2011-09-15 19:48:46 +02:00
parent 54b37b8c41
commit 46cbdd0efc
3 changed files with 89 additions and 82 deletions

View File

@ -122,6 +122,41 @@ HBITMAP X11DRV_SelectBitmap( PHYSDEV dev, HBITMAP hbitmap )
}
/***********************************************************************
* X11DRV_create_phys_bitmap
*/
BOOL X11DRV_create_phys_bitmap( HBITMAP hbitmap, const BITMAP *bitmap, int depth,
int true_color, const ColorShifts *shifts )
{
X_PHYSBITMAP *physBitmap;
if (!(physBitmap = X11DRV_init_phys_bitmap( hbitmap ))) return FALSE;
physBitmap->pixmap_depth = depth;
physBitmap->trueColor = true_color;
if (true_color) physBitmap->pixmap_color_shifts = *shifts;
wine_tsx11_lock();
physBitmap->pixmap = XCreatePixmap( gdi_display, root_window,
bitmap->bmWidth, bitmap->bmHeight, physBitmap->pixmap_depth );
if (physBitmap->pixmap)
{
GC gc = get_bitmap_gc( depth );
XSetFunction( gdi_display, gc, GXclear );
XFillRectangle( gdi_display, physBitmap->pixmap, gc, 0, 0, bitmap->bmWidth, bitmap->bmHeight );
XSetFunction( gdi_display, gc, GXcopy );
}
wine_tsx11_unlock();
if (!physBitmap->pixmap)
{
WARN("Can't create Pixmap\n");
HeapFree( GetProcessHeap(), 0, physBitmap );
return FALSE;
}
return TRUE;
}
/****************************************************************************
* CreateBitmap (X11DRV.@)
*
@ -131,7 +166,6 @@ HBITMAP X11DRV_SelectBitmap( PHYSDEV dev, HBITMAP hbitmap )
*/
BOOL X11DRV_CreateBitmap( PHYSDEV dev, HBITMAP hbitmap )
{
X_PHYSBITMAP *physBitmap;
BITMAP bitmap;
if (!GetObjectW( hbitmap, sizeof(bitmap), &bitmap )) return FALSE;
@ -146,50 +180,22 @@ BOOL X11DRV_CreateBitmap( PHYSDEV dev, HBITMAP hbitmap )
bitmap.bmPlanes, bitmap.bmBitsPixel);
return FALSE;
}
if (hbitmap == BITMAP_stock_phys_bitmap.hbitmap)
{
ERR( "called for stock bitmap, please report\n" );
return FALSE;
}
TRACE("(%p) %dx%d %d bpp\n", hbitmap, bitmap.bmWidth, bitmap.bmHeight, bitmap.bmBitsPixel);
if (!(physBitmap = X11DRV_init_phys_bitmap( hbitmap ))) return FALSE;
if (!X11DRV_XRender_SetPhysBitmapDepth( physBitmap, bitmap.bmBitsPixel, NULL ))
if (bitmap.bmBitsPixel == 1)
{
if(bitmap.bmBitsPixel == 1)
if (hbitmap == BITMAP_stock_phys_bitmap.hbitmap)
{
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);
ERR( "called for stock bitmap, please report\n" );
return FALSE;
}
return X11DRV_create_phys_bitmap( hbitmap, &bitmap, 1, FALSE, NULL );
}
wine_tsx11_lock();
/* Create the pixmap */
physBitmap->pixmap = XCreatePixmap(gdi_display, root_window,
bitmap.bmWidth, bitmap.bmHeight, physBitmap->pixmap_depth);
if (physBitmap->pixmap)
{
GC gc = get_bitmap_gc(physBitmap->pixmap_depth);
XSetFunction( gdi_display, gc, GXclear );
XFillRectangle( gdi_display, physBitmap->pixmap, gc, 0, 0, bitmap.bmWidth, bitmap.bmHeight );
XSetFunction( gdi_display, gc, GXcopy );
}
wine_tsx11_unlock();
if (!physBitmap->pixmap)
{
WARN("Can't create Pixmap\n");
HeapFree( GetProcessHeap(), 0, physBitmap );
return FALSE;
}
return TRUE;
return X11DRV_create_phys_bitmap( hbitmap, &bitmap, screen_depth,
(visual->class == TrueColor || visual->class == DirectColor),
&X11DRV_PALETTE_default_shifts );
}

View File

@ -274,6 +274,8 @@ extern HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc) DECLSPEC_H
extern Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc ) DECLSPEC_HIDDEN;
extern X_PHYSBITMAP *X11DRV_get_phys_bitmap( HBITMAP hbitmap ) DECLSPEC_HIDDEN;
extern X_PHYSBITMAP *X11DRV_init_phys_bitmap( HBITMAP hbitmap ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_create_phys_bitmap( HBITMAP hbitmap, const BITMAP *bitmap, int depth,
int true_color, const ColorShifts *shifts ) DECLSPEC_HIDDEN;
extern Pixmap X11DRV_get_pixmap( HBITMAP hbitmap ) DECLSPEC_HIDDEN;
extern RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp ) DECLSPEC_HIDDEN;

View File

@ -1185,6 +1185,31 @@ static INT xrenderdrv_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID
*/
static BOOL xrenderdrv_CreateBitmap( PHYSDEV dev, HBITMAP hbitmap )
{
XRenderPictFormat *pict_format = NULL;
ColorShifts shifts;
BITMAP bitmap;
if (!GetObjectW( hbitmap, sizeof(bitmap), &bitmap )) return FALSE;
if (bitmap.bmPlanes == 1 && bitmap.bmBitsPixel == screen_bpp)
{
switch (bitmap.bmBitsPixel)
{
case 16: pict_format = pict_formats[WXR_FORMAT_R5G6B5]; break;
case 24: pict_format = pict_formats[WXR_FORMAT_R8G8B8]; break;
case 32: pict_format = pict_formats[WXR_FORMAT_A8R8G8B8]; break;
}
}
if (pict_format)
{
X11DRV_PALETTE_ComputeColorShifts( &shifts,
pict_format->direct.redMask << pict_format->direct.red,
pict_format->direct.greenMask << pict_format->direct.green,
pict_format->direct.blueMask << pict_format->direct.blue );
return X11DRV_create_phys_bitmap( hbitmap, &bitmap, pict_format->depth, TRUE, &shifts );
}
dev = GET_NEXT_PHYSDEV( dev, pCreateBitmap );
return dev->funcs->pCreateBitmap( dev, hbitmap );
}
@ -1253,8 +1278,12 @@ static void xrenderdrv_SetDeviceClipping( PHYSDEV dev, HRGN vis_rgn, HRGN clip_r
BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, int bits_pixel, const DIBSECTION *dib)
{
XRenderPictFormat *pict_format = NULL;
XRenderPictFormat *pict_format;
ColorShifts shifts;
const DWORD *bitfields;
static const DWORD bitfields_32[3] = {0xff0000, 0x00ff00, 0x0000ff};
static const DWORD bitfields_16[3] = {0x7c00, 0x03e0, 0x001f};
/* 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
@ -1262,52 +1291,22 @@ BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, int bits_pixel,
if (!X11DRV_XRender_Installed || bits_pixel <= 8)
return FALSE;
if (dib)
{
const DWORD *bitfields;
static const DWORD bitfields_32[3] = {0xff0000, 0x00ff00, 0x0000ff};
static const DWORD bitfields_16[3] = {0x7c00, 0x03e0, 0x001f};
if(dib->dsBmih.biCompression == BI_BITFIELDS)
bitfields = dib->dsBitfields;
else if(bits_pixel == 24 || bits_pixel == 32)
bitfields = bitfields_32;
else
bitfields = bitfields_16;
X11DRV_PALETTE_ComputeColorShifts(&shifts, bitfields[0], bitfields[1], bitfields[2]);
pict_format = pict_formats[get_xrender_format_from_color_shifts(dib->dsBm.bmBitsPixel, &shifts)];
/* Common formats should be in our picture format table. */
if (!pict_format)
{
TRACE("Unhandled dibsection format bpp=%d, redMask=%x, greenMask=%x, blueMask=%x\n",
dib->dsBm.bmBitsPixel, bitfields[0], bitfields[1], bitfields[2]);
return FALSE;
}
}
if(dib->dsBmih.biCompression == BI_BITFIELDS)
bitfields = dib->dsBitfields;
else if(bits_pixel == 24 || bits_pixel == 32)
bitfields = bitfields_32;
else
bitfields = bitfields_16;
X11DRV_PALETTE_ComputeColorShifts(&shifts, bitfields[0], bitfields[1], bitfields[2]);
pict_format = pict_formats[get_xrender_format_from_color_shifts(dib->dsBm.bmBitsPixel, &shifts)];
/* Common formats should be in our picture format table. */
if (!pict_format)
{
int red_mask, green_mask, blue_mask;
/* We are dealing with a DDB */
switch (bits_pixel)
{
case 16: pict_format = pict_formats[WXR_FORMAT_R5G6B5]; break;
case 24: pict_format = pict_formats[WXR_FORMAT_R8G8B8]; break;
case 32: pict_format = pict_formats[WXR_FORMAT_A8R8G8B8]; break;
}
if (!pict_format)
{
TRACE("Unhandled DDB bits_pixel=%d\n", bits_pixel);
return FALSE;
}
red_mask = pict_format->direct.redMask << pict_format->direct.red;
green_mask = pict_format->direct.greenMask << pict_format->direct.green;
blue_mask = pict_format->direct.blueMask << 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, bitfields[0], bitfields[1], bitfields[2]);
return FALSE;
}
physBitmap->pixmap_depth = pict_format->depth;