winex11: Use an XVisualInfo structure to store color formats in Get/PutImage.
This commit is contained in:
parent
5d770503b9
commit
305b10aba6
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue