NtGdiCreateDIBSection will allocate a color table for 8bpp bitmap anyway and if biClrUsed isn't set, we will later fail any color lookup.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57584
-- v2: winex11: Always fill the window surface color info. win32u: Allocate dibdrv bitmap info with the physdev object.
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57584 --- dlls/win32u/dibdrv/dc.c | 8 +++----- dlls/win32u/dibdrv/dibdrv.h | 2 ++ 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c index 2fc9000025d..c12323dfa88 100644 --- a/dlls/win32u/dibdrv/dc.c +++ b/dlls/win32u/dibdrv/dc.c @@ -327,7 +327,7 @@ void add_clipped_bounds( dibdrv_physdev *dev, const RECT *rect, HRGN clip ) */ static BOOL dibdrv_CreateDC( PHYSDEV *dev, LPCWSTR device, LPCWSTR output, const DEVMODEW *data ) { - dibdrv_physdev *pdev = calloc( 1, sizeof(*pdev) ); + dibdrv_physdev *pdev = calloc( 1, offsetof( dibdrv_physdev, info.bmiColors[256] ) );
if (!pdev) return FALSE; clear_dib_info(&pdev->dib); @@ -790,8 +790,6 @@ static void unlock_windrv_bits( struct gdi_image_bits *bits )
void dibdrv_set_window_surface( DC *dc, struct window_surface *surface ) { - char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; - BITMAPINFO *info = (BITMAPINFO *)buffer; void *bits; PHYSDEV windev; struct windrv_physdev *physdev; @@ -817,8 +815,8 @@ void dibdrv_set_window_surface( DC *dc, struct window_surface *surface ) physdev->surface = surface;
dibdrv = physdev->dibdrv; - bits = window_surface_get_color( surface, info ); - init_dib_info_from_bitmapinfo( &dibdrv->dib, info, bits ); + bits = window_surface_get_color( surface, &dibdrv->info ); + init_dib_info_from_bitmapinfo( &dibdrv->dib, &dibdrv->info, bits ); dibdrv->dib.rect = dc->attr->vis_rect; OffsetRect( &dibdrv->dib.rect, -dc->device_rect.left, -dc->device_rect.top ); dibdrv->bounds = &surface->bounds; diff --git a/dlls/win32u/dibdrv/dibdrv.h b/dlls/win32u/dibdrv/dibdrv.h index 2fcc516e925..54799d6df8c 100644 --- a/dlls/win32u/dibdrv/dibdrv.h +++ b/dlls/win32u/dibdrv/dibdrv.h @@ -110,6 +110,8 @@ typedef struct dibdrv_physdev dash_pos dash_pos; rop_mask dash_masks[2]; BOOL (* pen_lines)(struct dibdrv_physdev *pdev, int num, POINT *pts, BOOL close, HRGN region); + + BITMAPINFO info; } dibdrv_physdev;
extern BOOL dibdrv_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst,
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57584 --- dlls/winex11.drv/bitblt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index 757386595f0..267a42bd4c7 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -1902,7 +1902,7 @@ static struct window_surface *create_surface( HWND hwnd, Window window, const XV info->bmiHeader.biPlanes = 1; info->bmiHeader.biBitCount = format->bits_per_pixel; info->bmiHeader.biSizeImage = get_dib_image_size( info ); - if (format->bits_per_pixel > 8) set_color_info( vis, info, use_alpha ); + set_color_info( vis, info, use_alpha );
if (!(image = x11drv_image_create( info, vis ))) return NULL;
v2: Actually fix the issue: if the window surface has a color table, the dibdrv was copying it to a stack buffer on initialization. Then `init_dib_info_from_bitmapinfo` > `init_dib_info` keeps a reference to the color table, without copying it so we need to make sure the table lives on the dibdrv.
There shouldn't be any need to store the full BITMAPINFO, or to modify the generic dibdrv at all.
The color table is already stored in the DIB section's BITMAPOBJ, it should be possible to simply use the pointer instead of copying the full color table multiple times.