winex11: Add a helper to create a pixmap from an image.
This commit is contained in:
parent
f25f97d86a
commit
3e8ad9a064
|
@ -937,6 +937,16 @@ static void free_ximage_bits( struct gdi_image_bits *bits )
|
|||
wine_tsx11_unlock();
|
||||
}
|
||||
|
||||
/* only for use on sanitized BITMAPINFO structures */
|
||||
static inline int get_dib_info_size( const BITMAPINFO *info, UINT coloruse )
|
||||
{
|
||||
if (info->bmiHeader.biCompression == BI_BITFIELDS)
|
||||
return sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD);
|
||||
if (coloruse == DIB_PAL_COLORS)
|
||||
return sizeof(BITMAPINFOHEADER) + info->bmiHeader.biClrUsed * sizeof(WORD);
|
||||
return FIELD_OFFSET( BITMAPINFO, bmiColors[info->bmiHeader.biClrUsed] );
|
||||
}
|
||||
|
||||
/* store the palette or color mask data in the bitmap info structure */
|
||||
static void set_color_info( const XVisualInfo *vis, BITMAPINFO *info )
|
||||
{
|
||||
|
@ -1463,6 +1473,122 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* put_pixmap_image
|
||||
*
|
||||
* Simplified equivalent of X11DRV_PutImage that writes directly to a pixmap.
|
||||
*/
|
||||
static DWORD put_pixmap_image( Pixmap pixmap, const XVisualInfo *vis,
|
||||
BITMAPINFO *info, const struct gdi_image_bits *bits )
|
||||
{
|
||||
DWORD ret;
|
||||
XImage *image;
|
||||
struct bitblt_coords coords;
|
||||
struct gdi_image_bits dst_bits;
|
||||
const XPixmapFormatValues *format = pixmap_formats[vis->depth];
|
||||
const int *mapping = NULL;
|
||||
|
||||
if (!format) return ERROR_INVALID_PARAMETER;
|
||||
if (info->bmiHeader.biPlanes != 1) goto update_format;
|
||||
if (info->bmiHeader.biBitCount != format->bits_per_pixel) goto update_format;
|
||||
/* FIXME: could try to handle 1-bpp using XCopyPlane */
|
||||
if (!matching_color_info( vis, info )) goto update_format;
|
||||
if (!bits) return ERROR_SUCCESS; /* just querying the format */
|
||||
|
||||
coords.x = 0;
|
||||
coords.y = 0;
|
||||
coords.width = info->bmiHeader.biWidth;
|
||||
coords.height = abs( info->bmiHeader.biHeight );
|
||||
SetRect( &coords.visrect, 0, 0, coords.width, coords.height );
|
||||
|
||||
wine_tsx11_lock();
|
||||
image = XCreateImage( gdi_display, visual, vis->depth, ZPixmap, 0, NULL,
|
||||
coords.width, coords.height, 32, 0 );
|
||||
wine_tsx11_unlock();
|
||||
if (!image) return ERROR_OUTOFMEMORY;
|
||||
|
||||
if (image->bits_per_pixel == 4 || image->bits_per_pixel == 8)
|
||||
mapping = X11DRV_PALETTE_PaletteToXPixel;
|
||||
|
||||
if (!(ret = copy_image_bits( info, is_r8g8b8(vis), image, bits, &dst_bits, &coords, mapping, ~0u )))
|
||||
{
|
||||
image->data = dst_bits.ptr;
|
||||
wine_tsx11_lock();
|
||||
XPutImage( gdi_display, pixmap, get_bitmap_gc( vis->depth ),
|
||||
image, 0, 0, 0, 0, coords.width, coords.height );
|
||||
wine_tsx11_unlock();
|
||||
image->data = NULL;
|
||||
}
|
||||
|
||||
wine_tsx11_lock();
|
||||
XDestroyImage( image );
|
||||
wine_tsx11_unlock();
|
||||
if (dst_bits.free) dst_bits.free( &dst_bits );
|
||||
return ret;
|
||||
|
||||
update_format:
|
||||
info->bmiHeader.biPlanes = 1;
|
||||
info->bmiHeader.biBitCount = format->bits_per_pixel;
|
||||
if (info->bmiHeader.biHeight > 0) info->bmiHeader.biHeight = -info->bmiHeader.biHeight;
|
||||
set_color_info( vis, info );
|
||||
return ERROR_BAD_FORMAT;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* create_pixmap_from_image
|
||||
*/
|
||||
Pixmap create_pixmap_from_image( HDC hdc, const XVisualInfo *vis, const BITMAPINFO *info,
|
||||
const struct gdi_image_bits *bits, UINT coloruse )
|
||||
{
|
||||
static const RGBQUAD default_colortable[2] = { { 0x00, 0x00, 0x00 }, { 0xff, 0xff, 0xff } };
|
||||
char dst_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
|
||||
char src_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
|
||||
BITMAPINFO *dst_info = (BITMAPINFO *)dst_buffer;
|
||||
BITMAPINFO *src_info = (BITMAPINFO *)src_buffer;
|
||||
struct gdi_image_bits dst_bits;
|
||||
Pixmap pixmap;
|
||||
DWORD err;
|
||||
HBITMAP dib;
|
||||
|
||||
wine_tsx11_lock();
|
||||
pixmap = XCreatePixmap( gdi_display, root_window,
|
||||
info->bmiHeader.biWidth, abs(info->bmiHeader.biHeight), vis->depth );
|
||||
wine_tsx11_unlock();
|
||||
if (!pixmap) return 0;
|
||||
|
||||
memcpy( src_info, info, get_dib_info_size( info, coloruse ));
|
||||
memcpy( dst_info, info, get_dib_info_size( info, coloruse ));
|
||||
|
||||
if (coloruse == DIB_PAL_COLORS ||
|
||||
(err = put_pixmap_image( pixmap, vis, dst_info, bits )) == ERROR_BAD_FORMAT)
|
||||
{
|
||||
if (dst_info->bmiHeader.biBitCount == 1) /* set a default color table for 1-bpp */
|
||||
memcpy( dst_info->bmiColors, default_colortable, sizeof(default_colortable) );
|
||||
dib = CreateDIBSection( hdc, dst_info, coloruse, &dst_bits.ptr, 0, 0 );
|
||||
if (dib)
|
||||
{
|
||||
if (src_info->bmiHeader.biBitCount == 1 && !src_info->bmiHeader.biClrUsed)
|
||||
memcpy( src_info->bmiColors, default_colortable, sizeof(default_colortable) );
|
||||
SetDIBits( hdc, dib, 0, abs(info->bmiHeader.biHeight), bits->ptr, src_info, coloruse );
|
||||
dst_bits.free = NULL;
|
||||
dst_bits.is_copy = TRUE;
|
||||
err = put_pixmap_image( pixmap, vis, dst_info, &dst_bits );
|
||||
DeleteObject( dib );
|
||||
}
|
||||
else err = ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (!err) return pixmap;
|
||||
|
||||
wine_tsx11_lock();
|
||||
XFreePixmap( gdi_display, pixmap );
|
||||
wine_tsx11_unlock();
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_pixmap_image
|
||||
*
|
||||
|
|
|
@ -229,6 +229,8 @@ extern Pixmap X11DRV_get_pixmap( HBITMAP hbitmap ) DECLSPEC_HIDDEN;
|
|||
extern DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image,
|
||||
const struct gdi_image_bits *src_bits, struct gdi_image_bits *dst_bits,
|
||||
struct bitblt_coords *coords, const int *mapping, unsigned int zeropad_mask ) DECLSPEC_HIDDEN;
|
||||
extern Pixmap create_pixmap_from_image( HDC hdc, const XVisualInfo *vis, const BITMAPINFO *info,
|
||||
const struct gdi_image_bits *bits, UINT coloruse ) DECLSPEC_HIDDEN;
|
||||
extern DWORD get_pixmap_image( Pixmap pixmap, int width, int height, const XVisualInfo *vis,
|
||||
BITMAPINFO *info, struct gdi_image_bits *bits ) DECLSPEC_HIDDEN;
|
||||
|
||||
|
|
Loading…
Reference in New Issue