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 */
|
/* 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)
|
||||||
|
|
Loading…
Reference in New Issue