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 */
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);
@ -955,7 +955,7 @@ static void set_color_info( PHYSDEV dev, const ColorShifts *color_shifts, BITMAP
UINT i, count;
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++)
{
rgb[i].rgbRed = palette[i].peRed;
@ -967,15 +967,15 @@ static void set_color_info( PHYSDEV dev, const ColorShifts *color_shifts, BITMAP
break;
}
case 16:
colors[0] = color_shifts->logicalRed.max << color_shifts->logicalRed.shift;
colors[1] = color_shifts->logicalGreen.max << color_shifts->logicalGreen.shift;
colors[2] = color_shifts->logicalBlue.max << color_shifts->logicalBlue.shift;
colors[0] = vis->red_mask;
colors[1] = vis->green_mask;
colors[2] = vis->blue_mask;
info->bmiHeader.biCompression = BI_BITFIELDS;
break;
case 32:
colors[0] = color_shifts->logicalRed.max << color_shifts->logicalRed.shift;
colors[1] = color_shifts->logicalGreen.max << color_shifts->logicalGreen.shift;
colors[2] = color_shifts->logicalBlue.max << color_shifts->logicalBlue.shift;
colors[0] = vis->red_mask;
colors[1] = vis->green_mask;
colors[2] = vis->blue_mask;
if (colors[0] != 0xff0000 || colors[1] != 0x00ff00 || colors[2] != 0x0000ff)
info->bmiHeader.biCompression = BI_BITFIELDS;
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 */
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);
@ -1000,7 +1000,7 @@ static BOOL matching_color_info( PHYSDEV dev, const ColorShifts *color_shifts, c
UINT i, count;
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;
for (i = 0; i < count; i++)
{
@ -1012,33 +1012,29 @@ static BOOL matching_color_info( PHYSDEV dev, const ColorShifts *color_shifts, c
}
case 16:
if (info->bmiHeader.biCompression == BI_BITFIELDS)
return (color_shifts->logicalRed.max << color_shifts->logicalRed.shift == colors[0] &&
color_shifts->logicalGreen.max << color_shifts->logicalGreen.shift == colors[1] &&
color_shifts->logicalBlue.max << color_shifts->logicalBlue.shift == colors[2]);
return (vis->red_mask == colors[0] &&
vis->green_mask == colors[1] &&
vis->blue_mask == colors[2]);
if (info->bmiHeader.biCompression == BI_RGB)
return (color_shifts->logicalRed.max << color_shifts->logicalRed.shift == 0x7c00 &&
color_shifts->logicalGreen.max << color_shifts->logicalGreen.shift == 0x03e0 &&
color_shifts->logicalBlue.max << color_shifts->logicalBlue.shift == 0x001f);
return (vis->red_mask == 0x7c00 && vis->green_mask == 0x03e0 && vis->blue_mask == 0x001f);
break;
case 32:
if (info->bmiHeader.biCompression == BI_BITFIELDS)
return (color_shifts->logicalRed.max << color_shifts->logicalRed.shift == colors[0] &&
color_shifts->logicalGreen.max << color_shifts->logicalGreen.shift == colors[1] &&
color_shifts->logicalBlue.max << color_shifts->logicalBlue.shift == colors[2]);
return (vis->red_mask == colors[0] &&
vis->green_mask == colors[1] &&
vis->blue_mask == colors[2]);
/* fall through */
case 24:
if (info->bmiHeader.biCompression == BI_RGB)
return (color_shifts->logicalRed.max << color_shifts->logicalRed.shift == 0xff0000 &&
color_shifts->logicalGreen.max << color_shifts->logicalGreen.shift == 0x00ff00 &&
color_shifts->logicalBlue.max << color_shifts->logicalBlue.shift == 0x0000ff);
return (vis->red_mask == 0xff0000 && vis->green_mask == 0x00ff00 && vis->blue_mask == 0x0000ff);
break;
}
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 */
@ -1201,10 +1197,9 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info
X_PHYSBITMAP *bitmap;
DWORD ret;
XImage *image;
int depth;
XVisualInfo vis;
struct gdi_image_bits dst_bits;
const XPixmapFormatValues *format;
const ColorShifts *color_shifts;
const BYTE *opcode = BITBLT_Opcodes[(rop >> 16) & 0xff];
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;
physdev = NULL;
depth = bitmap->depth;
color_shifts = &bitmap->color_shifts;
vis.depth = bitmap->depth;
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
{
physdev = get_x11drv_dev( dev );
bitmap = NULL;
depth = physdev->depth;
color_shifts = physdev->color_shifts;
vis.depth = physdev->depth;
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.biBitCount != format->bits_per_pixel) goto update_format;
/* 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 ((src->width != dst->width) || (src->height != dst->height)) return ERROR_TRANSFORM_NOT_SUPPORTED;
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 );
wine_tsx11_unlock();
if (!image) return ERROR_OUTOFMEMORY;
@ -1243,7 +1245,7 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info
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)
{
@ -1293,7 +1295,7 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info
gc = XCreateGC( gdi_display, physdev->drawable, 0, NULL );
XSetSubwindowMode( gdi_display, gc, IncludeInferiors );
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 );
wine_tsx11_unlock();
@ -1321,7 +1323,7 @@ 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( dev, color_shifts, info );
set_color_info( &vis, info );
return ERROR_BAD_FORMAT;
}
@ -1335,28 +1337,34 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
X_PHYSBITMAP *bitmap;
DWORD ret = ERROR_SUCCESS;
XImage *image;
XVisualInfo vis;
UINT align, x, y, width, height;
int depth;
struct gdi_image_bits src_bits;
const XPixmapFormatValues *format;
const ColorShifts *color_shifts;
const int *mapping = NULL;
if (hbitmap)
{
if (!(bitmap = X11DRV_get_phys_bitmap( hbitmap ))) return ERROR_INVALID_HANDLE;
physdev = NULL;
depth = bitmap->depth;
color_shifts = &bitmap->color_shifts;
vis.depth = bitmap->depth;
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
{
physdev = get_x11drv_dev( dev );
bitmap = NULL;
depth = physdev->depth;
color_shifts = physdev->color_shifts;
vis.depth = physdev->depth;
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 */
switch (format->bits_per_pixel)
@ -1368,7 +1376,7 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
case 24: align = 4; break;
case 32: align = 1; break;
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;
}
@ -1378,7 +1386,7 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
info->bmiHeader.biXPelsPerMeter = 0;
info->bmiHeader.biYPelsPerMeter = 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 */
@ -1424,8 +1432,8 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
Pixmap pixmap;
wine_tsx11_lock();
pixmap = XCreatePixmap( gdi_display, root_window, width, height, depth );
XCopyArea( gdi_display, physdev->drawable, pixmap, get_bitmap_gc(depth),
pixmap = XCreatePixmap( gdi_display, root_window, width, height, vis.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 );
image = XGetImage( gdi_display, pixmap, 0, 0, width, height, AllPlanes, ZPixmap );
XFreePixmap( gdi_display, pixmap );
@ -1440,7 +1448,7 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
src_bits.ptr = image->data;
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] );
if (!ret && bits->ptr == image->data)