From 305b10aba67009b0a8feab32ce0caa9cbf8f671b Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 11 May 2012 13:47:33 +0200 Subject: [PATCH] winex11: Use an XVisualInfo structure to store color formats in Get/PutImage. --- dlls/winex11.drv/bitblt.c | 104 ++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 48 deletions(-) diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index 056e4c4108d..853f2aef942 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -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)