winex11: Add a helper to retrieve an image from a pixmap.
This commit is contained in:
parent
305b10aba6
commit
f99af0bb8f
|
@ -1461,3 +1461,62 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
|
|||
wine_tsx11_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_pixmap_image
|
||||
*
|
||||
* Equivalent of X11DRV_GetImage that reads directly from a pixmap.
|
||||
*/
|
||||
DWORD get_pixmap_image( Pixmap pixmap, int width, int height, const XVisualInfo *vis,
|
||||
BITMAPINFO *info, struct gdi_image_bits *bits )
|
||||
{
|
||||
DWORD ret = ERROR_SUCCESS;
|
||||
XImage *image;
|
||||
struct gdi_image_bits src_bits;
|
||||
struct bitblt_coords coords;
|
||||
const XPixmapFormatValues *format = pixmap_formats[vis->depth];
|
||||
const int *mapping = NULL;
|
||||
|
||||
if (!format) return ERROR_INVALID_PARAMETER;
|
||||
|
||||
info->bmiHeader.biSize = sizeof(info->bmiHeader);
|
||||
info->bmiHeader.biWidth = width;
|
||||
info->bmiHeader.biHeight = -height;
|
||||
info->bmiHeader.biPlanes = 1;
|
||||
info->bmiHeader.biBitCount = format->bits_per_pixel;
|
||||
info->bmiHeader.biXPelsPerMeter = 0;
|
||||
info->bmiHeader.biYPelsPerMeter = 0;
|
||||
info->bmiHeader.biClrImportant = 0;
|
||||
set_color_info( vis, info );
|
||||
|
||||
if (!bits) return ERROR_SUCCESS; /* just querying the color information */
|
||||
|
||||
coords.x = 0;
|
||||
coords.y = 0;
|
||||
coords.width = width;
|
||||
coords.height = height;
|
||||
SetRect( &coords.visrect, 0, 0, width, height );
|
||||
|
||||
wine_tsx11_lock();
|
||||
image = XGetImage( gdi_display, pixmap, 0, 0, width, height, AllPlanes, ZPixmap );
|
||||
wine_tsx11_unlock();
|
||||
if (!image) return ERROR_OUTOFMEMORY;
|
||||
|
||||
info->bmiHeader.biSizeImage = height * image->bytes_per_line;
|
||||
|
||||
src_bits.ptr = image->data;
|
||||
src_bits.is_copy = TRUE;
|
||||
ret = copy_image_bits( info, is_r8g8b8(vis), image, &src_bits, bits, &coords, mapping,
|
||||
zeropad_masks[(width * image->bits_per_pixel) & 31] );
|
||||
|
||||
if (!ret && bits->ptr == image->data)
|
||||
{
|
||||
bits->free = free_ximage_bits;
|
||||
image->data = NULL;
|
||||
}
|
||||
wine_tsx11_lock();
|
||||
XDestroyImage( image );
|
||||
wine_tsx11_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -2199,68 +2199,14 @@ static void flush_pixmap( struct wine_glcontext *ctx )
|
|||
{
|
||||
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
|
||||
BITMAPINFO *info = (BITMAPINFO *)buffer;
|
||||
XImage *image;
|
||||
struct gdi_image_bits src_bits, bits;
|
||||
struct bitblt_coords coords;
|
||||
DWORD *masks;
|
||||
BOOL is_r8g8b8 = FALSE;
|
||||
const XPixmapFormatValues *format = pixmap_formats[ctx->vis->depth];
|
||||
struct gdi_image_bits bits;
|
||||
|
||||
coords.x = 0;
|
||||
coords.y = 0;
|
||||
coords.width = ctx->pixmap_size.cx;
|
||||
coords.height = ctx->pixmap_size.cy;
|
||||
SetRect( &coords.visrect, 0, 0, coords.width, coords.height );
|
||||
|
||||
info->bmiHeader.biSize = sizeof(info->bmiHeader);
|
||||
info->bmiHeader.biWidth = coords.width;
|
||||
info->bmiHeader.biHeight = -coords.height;
|
||||
info->bmiHeader.biPlanes = 1;
|
||||
info->bmiHeader.biBitCount = format->bits_per_pixel;
|
||||
info->bmiHeader.biCompression = BI_RGB;
|
||||
info->bmiHeader.biClrUsed = 0;
|
||||
switch (info->bmiHeader.biBitCount)
|
||||
{
|
||||
case 16:
|
||||
masks = (DWORD *)info->bmiColors;
|
||||
masks[0] = ctx->vis->red_mask;
|
||||
masks[1] = ctx->vis->green_mask;
|
||||
masks[2] = ctx->vis->blue_mask;
|
||||
info->bmiHeader.biCompression = BI_BITFIELDS;
|
||||
break;
|
||||
case 24:
|
||||
is_r8g8b8 = (ctx->vis->red_mask == 0xff0000 && ctx->vis->blue_mask == 0x0000ff);
|
||||
break;
|
||||
case 32:
|
||||
masks = (DWORD *)info->bmiColors;
|
||||
masks[0] = ctx->vis->red_mask;
|
||||
masks[1] = ctx->vis->green_mask;
|
||||
masks[2] = ctx->vis->blue_mask;
|
||||
if (masks[0] != 0xff0000 || masks[1] != 0x00ff00 || masks[2] != 0x0000ff)
|
||||
info->bmiHeader.biCompression = BI_BITFIELDS;
|
||||
break;
|
||||
default:
|
||||
FIXME( "depth %u not supported\n", info->bmiHeader.biBitCount );
|
||||
return;
|
||||
}
|
||||
|
||||
wine_tsx11_lock();
|
||||
image = XGetImage( gdi_display, ctx->pixmap, 0, 0, coords.width, coords.height, AllPlanes, ZPixmap );
|
||||
wine_tsx11_unlock();
|
||||
if (!image) return;
|
||||
|
||||
src_bits.ptr = image->data;
|
||||
src_bits.is_copy = TRUE;
|
||||
if (!copy_image_bits( info, is_r8g8b8, image, &src_bits, &bits, &coords, NULL, ~0u ))
|
||||
if (!get_pixmap_image( ctx->pixmap, ctx->pixmap_size.cx, ctx->pixmap_size.cy, ctx->vis, info, &bits ))
|
||||
{
|
||||
HBITMAP bitmap = GetCurrentObject( ctx->hdc, OBJ_BITMAP );
|
||||
TRACE( "drawable %lx -> hdc %p bitmap %p\n", ctx->pixmap, ctx->hdc, bitmap );
|
||||
SetDIBits( 0, bitmap, 0, coords.height, bits.ptr, info, DIB_RGB_COLORS );
|
||||
SetDIBits( 0, bitmap, 0, ctx->pixmap_size.cy, bits.ptr, info, DIB_RGB_COLORS );
|
||||
if (bits.free) bits.free( &bits );
|
||||
}
|
||||
wine_tsx11_lock();
|
||||
XDestroyImage( image );
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
|
||||
static void flush_gl_drawable( struct glx_physdev *physdev )
|
||||
|
|
|
@ -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 DWORD get_pixmap_image( Pixmap pixmap, int width, int height, const XVisualInfo *vis,
|
||||
BITMAPINFO *info, struct gdi_image_bits *bits ) DECLSPEC_HIDDEN;
|
||||
|
||||
extern RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp ) DECLSPEC_HIDDEN;
|
||||
extern BOOL add_extra_clipping_region( X11DRV_PDEVICE *dev, HRGN rgn ) DECLSPEC_HIDDEN;
|
||||
|
|
Loading…
Reference in New Issue