winex11: Use an XVisualInfo structure to store color formats in Get/PutImage.

This commit is contained in:
Alexandre Julliard 2012-05-11 13:47:33 +02:00
parent 5d770503b9
commit 305b10aba6
1 changed files with 56 additions and 48 deletions

View File

@ -938,7 +938,7 @@ static void free_ximage_bits( struct gdi_image_bits *bits )
} }
/* store the palette or color mask data in the bitmap info structure */ /* store the palette or color mask data in the bitmap info structure */
static void set_color_info( PHYSDEV dev, const ColorShifts *color_shifts, BITMAPINFO *info ) static void set_color_info( const XVisualInfo *vis, BITMAPINFO *info )
{ {
DWORD *colors = (DWORD *)((char *)info + info->bmiHeader.biSize); DWORD *colors = (DWORD *)((char *)info + info->bmiHeader.biSize);
@ -955,7 +955,7 @@ static void set_color_info( PHYSDEV dev, const ColorShifts *color_shifts, BITMAP
UINT i, count; UINT i, count;
info->bmiHeader.biClrUsed = 1 << info->bmiHeader.biBitCount; info->bmiHeader.biClrUsed = 1 << info->bmiHeader.biBitCount;
count = X11DRV_GetSystemPaletteEntries( dev, 0, info->bmiHeader.biClrUsed, palette ); count = X11DRV_GetSystemPaletteEntries( NULL, 0, info->bmiHeader.biClrUsed, palette );
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
rgb[i].rgbRed = palette[i].peRed; rgb[i].rgbRed = palette[i].peRed;
@ -967,15 +967,15 @@ static void set_color_info( PHYSDEV dev, const ColorShifts *color_shifts, BITMAP
break; break;
} }
case 16: case 16:
colors[0] = color_shifts->logicalRed.max << color_shifts->logicalRed.shift; colors[0] = vis->red_mask;
colors[1] = color_shifts->logicalGreen.max << color_shifts->logicalGreen.shift; colors[1] = vis->green_mask;
colors[2] = color_shifts->logicalBlue.max << color_shifts->logicalBlue.shift; colors[2] = vis->blue_mask;
info->bmiHeader.biCompression = BI_BITFIELDS; info->bmiHeader.biCompression = BI_BITFIELDS;
break; break;
case 32: case 32:
colors[0] = color_shifts->logicalRed.max << color_shifts->logicalRed.shift; colors[0] = vis->red_mask;
colors[1] = color_shifts->logicalGreen.max << color_shifts->logicalGreen.shift; colors[1] = vis->green_mask;
colors[2] = color_shifts->logicalBlue.max << color_shifts->logicalBlue.shift; colors[2] = vis->blue_mask;
if (colors[0] != 0xff0000 || colors[1] != 0x00ff00 || colors[2] != 0x0000ff) if (colors[0] != 0xff0000 || colors[1] != 0x00ff00 || colors[2] != 0x0000ff)
info->bmiHeader.biCompression = BI_BITFIELDS; info->bmiHeader.biCompression = BI_BITFIELDS;
break; break;
@ -983,7 +983,7 @@ static void set_color_info( PHYSDEV dev, const ColorShifts *color_shifts, BITMAP
} }
/* check if the specified color info is suitable for PutImage */ /* check if the specified color info is suitable for PutImage */
static BOOL matching_color_info( PHYSDEV dev, const ColorShifts *color_shifts, const BITMAPINFO *info ) static BOOL matching_color_info( const XVisualInfo *vis, const BITMAPINFO *info )
{ {
DWORD *colors = (DWORD *)((char *)info + info->bmiHeader.biSize); DWORD *colors = (DWORD *)((char *)info + info->bmiHeader.biSize);
@ -1000,7 +1000,7 @@ static BOOL matching_color_info( PHYSDEV dev, const ColorShifts *color_shifts, c
UINT i, count; UINT i, count;
if (info->bmiHeader.biCompression != BI_RGB) return FALSE; if (info->bmiHeader.biCompression != BI_RGB) return FALSE;
count = X11DRV_GetSystemPaletteEntries( dev, 0, 1 << info->bmiHeader.biBitCount, palette ); count = X11DRV_GetSystemPaletteEntries( NULL, 0, 1 << info->bmiHeader.biBitCount, palette );
if (count != info->bmiHeader.biClrUsed) return FALSE; if (count != info->bmiHeader.biClrUsed) return FALSE;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
@ -1012,33 +1012,29 @@ static BOOL matching_color_info( PHYSDEV dev, const ColorShifts *color_shifts, c
} }
case 16: case 16:
if (info->bmiHeader.biCompression == BI_BITFIELDS) if (info->bmiHeader.biCompression == BI_BITFIELDS)
return (color_shifts->logicalRed.max << color_shifts->logicalRed.shift == colors[0] && return (vis->red_mask == colors[0] &&
color_shifts->logicalGreen.max << color_shifts->logicalGreen.shift == colors[1] && vis->green_mask == colors[1] &&
color_shifts->logicalBlue.max << color_shifts->logicalBlue.shift == colors[2]); vis->blue_mask == colors[2]);
if (info->bmiHeader.biCompression == BI_RGB) if (info->bmiHeader.biCompression == BI_RGB)
return (color_shifts->logicalRed.max << color_shifts->logicalRed.shift == 0x7c00 && return (vis->red_mask == 0x7c00 && vis->green_mask == 0x03e0 && vis->blue_mask == 0x001f);
color_shifts->logicalGreen.max << color_shifts->logicalGreen.shift == 0x03e0 &&
color_shifts->logicalBlue.max << color_shifts->logicalBlue.shift == 0x001f);
break; break;
case 32: case 32:
if (info->bmiHeader.biCompression == BI_BITFIELDS) if (info->bmiHeader.biCompression == BI_BITFIELDS)
return (color_shifts->logicalRed.max << color_shifts->logicalRed.shift == colors[0] && return (vis->red_mask == colors[0] &&
color_shifts->logicalGreen.max << color_shifts->logicalGreen.shift == colors[1] && vis->green_mask == colors[1] &&
color_shifts->logicalBlue.max << color_shifts->logicalBlue.shift == colors[2]); vis->blue_mask == colors[2]);
/* fall through */ /* fall through */
case 24: case 24:
if (info->bmiHeader.biCompression == BI_RGB) if (info->bmiHeader.biCompression == BI_RGB)
return (color_shifts->logicalRed.max << color_shifts->logicalRed.shift == 0xff0000 && return (vis->red_mask == 0xff0000 && vis->green_mask == 0x00ff00 && vis->blue_mask == 0x0000ff);
color_shifts->logicalGreen.max << color_shifts->logicalGreen.shift == 0x00ff00 &&
color_shifts->logicalBlue.max << color_shifts->logicalBlue.shift == 0x0000ff);
break; break;
} }
return FALSE; return FALSE;
} }
static inline BOOL is_r8g8b8( int depth, const ColorShifts *color_shifts ) static inline BOOL is_r8g8b8( const XVisualInfo *vis )
{ {
return depth == 24 && color_shifts->logicalBlue.shift == 0 && color_shifts->logicalRed.shift == 16; return vis->depth == 24 && vis->red_mask == 0xff0000 && vis->blue_mask == 0x0000ff;
} }
/* copy the image bits, fixing up alignment and byte swapping as necessary */ /* copy the image bits, fixing up alignment and byte swapping as necessary */
@ -1201,10 +1197,9 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info
X_PHYSBITMAP *bitmap; X_PHYSBITMAP *bitmap;
DWORD ret; DWORD ret;
XImage *image; XImage *image;
int depth; XVisualInfo vis;
struct gdi_image_bits dst_bits; struct gdi_image_bits dst_bits;
const XPixmapFormatValues *format; const XPixmapFormatValues *format;
const ColorShifts *color_shifts;
const BYTE *opcode = BITBLT_Opcodes[(rop >> 16) & 0xff]; const BYTE *opcode = BITBLT_Opcodes[(rop >> 16) & 0xff];
const int *mapping = NULL; const int *mapping = NULL;
@ -1212,27 +1207,34 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info
{ {
if (!(bitmap = X11DRV_get_phys_bitmap( hbitmap ))) return ERROR_INVALID_HANDLE; if (!(bitmap = X11DRV_get_phys_bitmap( hbitmap ))) return ERROR_INVALID_HANDLE;
physdev = NULL; physdev = NULL;
depth = bitmap->depth; vis.depth = bitmap->depth;
color_shifts = &bitmap->color_shifts; vis.red_mask = bitmap->color_shifts.logicalRed.max << bitmap->color_shifts.logicalRed.shift;
vis.green_mask = bitmap->color_shifts.logicalGreen.max << bitmap->color_shifts.logicalGreen.shift;
vis.blue_mask = bitmap->color_shifts.logicalBlue.max << bitmap->color_shifts.logicalBlue.shift;
} }
else else
{ {
physdev = get_x11drv_dev( dev ); physdev = get_x11drv_dev( dev );
bitmap = NULL; bitmap = NULL;
depth = physdev->depth; vis.depth = physdev->depth;
color_shifts = physdev->color_shifts; if (physdev->color_shifts)
{
vis.red_mask = physdev->color_shifts->logicalRed.max << physdev->color_shifts->logicalRed.shift;
vis.green_mask = physdev->color_shifts->logicalGreen.max << physdev->color_shifts->logicalGreen.shift;
vis.blue_mask = physdev->color_shifts->logicalBlue.max << physdev->color_shifts->logicalBlue.shift;
}
} }
format = pixmap_formats[depth]; format = pixmap_formats[vis.depth];
if (info->bmiHeader.biPlanes != 1) goto update_format; if (info->bmiHeader.biPlanes != 1) goto update_format;
if (info->bmiHeader.biBitCount != format->bits_per_pixel) goto update_format; if (info->bmiHeader.biBitCount != format->bits_per_pixel) goto update_format;
/* FIXME: could try to handle 1-bpp using XCopyPlane */ /* FIXME: could try to handle 1-bpp using XCopyPlane */
if (!matching_color_info( dev, color_shifts, info )) goto update_format; if (!matching_color_info( &vis, info )) goto update_format;
if (!bits) return ERROR_SUCCESS; /* just querying the format */ if (!bits) return ERROR_SUCCESS; /* just querying the format */
if ((src->width != dst->width) || (src->height != dst->height)) return ERROR_TRANSFORM_NOT_SUPPORTED; if ((src->width != dst->width) || (src->height != dst->height)) return ERROR_TRANSFORM_NOT_SUPPORTED;
wine_tsx11_lock(); wine_tsx11_lock();
image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0, NULL, image = XCreateImage( gdi_display, visual, vis.depth, ZPixmap, 0, NULL,
info->bmiHeader.biWidth, src->visrect.bottom - src->visrect.top, 32, 0 ); info->bmiHeader.biWidth, src->visrect.bottom - src->visrect.top, 32, 0 );
wine_tsx11_unlock(); wine_tsx11_unlock();
if (!image) return ERROR_OUTOFMEMORY; if (!image) return ERROR_OUTOFMEMORY;
@ -1243,7 +1245,7 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info
mapping = X11DRV_PALETTE_PaletteToXPixel; mapping = X11DRV_PALETTE_PaletteToXPixel;
} }
ret = copy_image_bits( info, is_r8g8b8(depth,color_shifts), image, bits, &dst_bits, src, mapping, ~0u ); ret = copy_image_bits( info, is_r8g8b8(&vis), image, bits, &dst_bits, src, mapping, ~0u );
if (!ret) if (!ret)
{ {
@ -1293,7 +1295,7 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info
gc = XCreateGC( gdi_display, physdev->drawable, 0, NULL ); gc = XCreateGC( gdi_display, physdev->drawable, 0, NULL );
XSetSubwindowMode( gdi_display, gc, IncludeInferiors ); XSetSubwindowMode( gdi_display, gc, IncludeInferiors );
XSetGraphicsExposures( gdi_display, gc, False ); XSetGraphicsExposures( gdi_display, gc, False );
src_pixmap = XCreatePixmap( gdi_display, root_window, width, height, depth ); src_pixmap = XCreatePixmap( gdi_display, root_window, width, height, vis.depth );
XPutImage( gdi_display, src_pixmap, gc, image, src->visrect.left, 0, 0, 0, width, height ); XPutImage( gdi_display, src_pixmap, gc, image, src->visrect.left, 0, 0, 0, width, height );
wine_tsx11_unlock(); wine_tsx11_unlock();
@ -1321,7 +1323,7 @@ update_format:
info->bmiHeader.biPlanes = 1; info->bmiHeader.biPlanes = 1;
info->bmiHeader.biBitCount = format->bits_per_pixel; info->bmiHeader.biBitCount = format->bits_per_pixel;
if (info->bmiHeader.biHeight > 0) info->bmiHeader.biHeight = -info->bmiHeader.biHeight; if (info->bmiHeader.biHeight > 0) info->bmiHeader.biHeight = -info->bmiHeader.biHeight;
set_color_info( dev, color_shifts, info ); set_color_info( &vis, info );
return ERROR_BAD_FORMAT; return ERROR_BAD_FORMAT;
} }
@ -1335,28 +1337,34 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
X_PHYSBITMAP *bitmap; X_PHYSBITMAP *bitmap;
DWORD ret = ERROR_SUCCESS; DWORD ret = ERROR_SUCCESS;
XImage *image; XImage *image;
XVisualInfo vis;
UINT align, x, y, width, height; UINT align, x, y, width, height;
int depth;
struct gdi_image_bits src_bits; struct gdi_image_bits src_bits;
const XPixmapFormatValues *format; const XPixmapFormatValues *format;
const ColorShifts *color_shifts;
const int *mapping = NULL; const int *mapping = NULL;
if (hbitmap) if (hbitmap)
{ {
if (!(bitmap = X11DRV_get_phys_bitmap( hbitmap ))) return ERROR_INVALID_HANDLE; if (!(bitmap = X11DRV_get_phys_bitmap( hbitmap ))) return ERROR_INVALID_HANDLE;
physdev = NULL; physdev = NULL;
depth = bitmap->depth; vis.depth = bitmap->depth;
color_shifts = &bitmap->color_shifts; vis.red_mask = bitmap->color_shifts.logicalRed.max << bitmap->color_shifts.logicalRed.shift;
vis.green_mask = bitmap->color_shifts.logicalGreen.max << bitmap->color_shifts.logicalGreen.shift;
vis.blue_mask = bitmap->color_shifts.logicalBlue.max << bitmap->color_shifts.logicalBlue.shift;
} }
else else
{ {
physdev = get_x11drv_dev( dev ); physdev = get_x11drv_dev( dev );
bitmap = NULL; bitmap = NULL;
depth = physdev->depth; vis.depth = physdev->depth;
color_shifts = physdev->color_shifts; if (physdev->color_shifts)
{
vis.red_mask = physdev->color_shifts->logicalRed.max << physdev->color_shifts->logicalRed.shift;
vis.green_mask = physdev->color_shifts->logicalGreen.max << physdev->color_shifts->logicalGreen.shift;
vis.blue_mask = physdev->color_shifts->logicalBlue.max << physdev->color_shifts->logicalBlue.shift;
}
} }
format = pixmap_formats[depth]; format = pixmap_formats[vis.depth];
/* align start and width to 32-bit boundary */ /* align start and width to 32-bit boundary */
switch (format->bits_per_pixel) switch (format->bits_per_pixel)
@ -1368,7 +1376,7 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
case 24: align = 4; break; case 24: align = 4; break;
case 32: align = 1; break; case 32: align = 1; break;
default: default:
FIXME( "depth %u bpp %u not supported yet\n", depth, format->bits_per_pixel ); FIXME( "depth %u bpp %u not supported yet\n", vis.depth, format->bits_per_pixel );
return ERROR_BAD_FORMAT; return ERROR_BAD_FORMAT;
} }
@ -1378,7 +1386,7 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
info->bmiHeader.biXPelsPerMeter = 0; info->bmiHeader.biXPelsPerMeter = 0;
info->bmiHeader.biYPelsPerMeter = 0; info->bmiHeader.biYPelsPerMeter = 0;
info->bmiHeader.biClrImportant = 0; info->bmiHeader.biClrImportant = 0;
set_color_info( dev, color_shifts, info ); set_color_info( &vis, info );
if (!bits) return ERROR_SUCCESS; /* just querying the color information */ if (!bits) return ERROR_SUCCESS; /* just querying the color information */
@ -1424,8 +1432,8 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
Pixmap pixmap; Pixmap pixmap;
wine_tsx11_lock(); wine_tsx11_lock();
pixmap = XCreatePixmap( gdi_display, root_window, width, height, depth ); pixmap = XCreatePixmap( gdi_display, root_window, width, height, vis.depth );
XCopyArea( gdi_display, physdev->drawable, pixmap, get_bitmap_gc(depth), XCopyArea( gdi_display, physdev->drawable, pixmap, get_bitmap_gc(vis.depth),
physdev->dc_rect.left + x, physdev->dc_rect.top + y, width, height, 0, 0 ); physdev->dc_rect.left + x, physdev->dc_rect.top + y, width, height, 0, 0 );
image = XGetImage( gdi_display, pixmap, 0, 0, width, height, AllPlanes, ZPixmap ); image = XGetImage( gdi_display, pixmap, 0, 0, width, height, AllPlanes, ZPixmap );
XFreePixmap( gdi_display, pixmap ); XFreePixmap( gdi_display, pixmap );
@ -1440,7 +1448,7 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
src_bits.ptr = image->data; src_bits.ptr = image->data;
src_bits.is_copy = TRUE; src_bits.is_copy = TRUE;
ret = copy_image_bits( info, is_r8g8b8(depth,color_shifts), image, &src_bits, bits, src, mapping, ret = copy_image_bits( info, is_r8g8b8(&vis), image, &src_bits, bits, src, mapping,
zeropad_masks[(width * image->bits_per_pixel) & 31] ); zeropad_masks[(width * image->bits_per_pixel) & 31] );
if (!ret && bits->ptr == image->data) if (!ret && bits->ptr == image->data)