From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 40 +++++++++++++++++++-------- dlls/wineandroid.drv/window.c | 22 +++++++++------ dlls/winemac.drv/surface.c | 35 +++++++++++------------ dlls/winewayland.drv/window_surface.c | 23 ++++++++------- dlls/winex11.drv/bitblt.c | 30 +++++++++++--------- include/wine/gdi_driver.h | 3 +- 6 files changed, 90 insertions(+), 63 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 6bb090cedcf..8e6fab478d1 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -156,6 +156,8 @@ static const struct window_surface_funcs offscreen_window_surface_funcs =
void create_offscreen_window_surface( HWND hwnd, const RECT *visible_rect, struct window_surface **surface ) { + char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; + BITMAPINFO *info = (BITMAPINFO *)buffer; struct offscreen_window_surface *impl; SIZE_T size; RECT surface_rect = *visible_rect; @@ -175,20 +177,23 @@ void create_offscreen_window_surface( HWND hwnd, const RECT *visible_rect, struc } else if (*surface) window_surface_release( *surface );
+ memset( info, 0, sizeof(*info) ); + info->bmiHeader.biSize = sizeof(info->bmiHeader); + info->bmiHeader.biWidth = surface_rect.right; + info->bmiHeader.biHeight = -surface_rect.bottom; /* top-down */ + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = 32; + info->bmiHeader.biSizeImage = get_dib_image_size( info ); + info->bmiHeader.biCompression = BI_RGB; + /* create a new window surface */ *surface = NULL; - size = surface_rect.right * surface_rect.bottom * 4; + size = info->bmiHeader.biSizeImage; if (!(impl = calloc(1, offsetof( struct offscreen_window_surface, info.bmiColors[0] ) + size))) return; - window_surface_init( &impl->header, &offscreen_window_surface_funcs, hwnd, &surface_rect ); + window_surface_init( &impl->header, &offscreen_window_surface_funcs, hwnd, info, 0 );
impl->header.color_bits = (char *)&impl->info.bmiColors[0]; - impl->info.bmiHeader.biSize = sizeof( impl->info ); - impl->info.bmiHeader.biWidth = surface_rect.right; - impl->info.bmiHeader.biHeight = surface_rect.bottom; - impl->info.bmiHeader.biPlanes = 1; - impl->info.bmiHeader.biBitCount = 32; - impl->info.bmiHeader.biCompression = BI_RGB; - impl->info.bmiHeader.biSizeImage = size; + impl->info = *info;
TRACE( "created window surface %p\n", &impl->header );
@@ -197,14 +202,27 @@ void create_offscreen_window_surface( HWND hwnd, const RECT *visible_rect, struc
/* window surface common helpers */
-W32KAPI void window_surface_init( struct window_surface *surface, const struct window_surface_funcs *funcs, HWND hwnd, const RECT *rect ) +W32KAPI BOOL window_surface_init( struct window_surface *surface, const struct window_surface_funcs *funcs, + HWND hwnd, BITMAPINFO *info, HBITMAP bitmap ) { + struct bitblt_coords coords = {0}; + struct gdi_image_bits bits; + BITMAPOBJ *bmp; + surface->funcs = funcs; surface->ref = 1; surface->hwnd = hwnd; - surface->rect = *rect; + SetRect( &surface->rect, 0, 0, info->bmiHeader.biWidth, abs( info->bmiHeader.biHeight ) ); pthread_mutex_init( &surface->mutex, NULL ); reset_bounds( &surface->bounds ); + + if (!bitmap) return TRUE; + if (!(bmp = GDI_GetObjPtr( bitmap, NTGDI_OBJ_BITMAP ))) return FALSE; + get_image_from_bitmap( bmp, info, &bits, &coords ); + surface->color_bits = bits.ptr; + GDI_ReleaseObj( bitmap ); + + return TRUE; }
W32KAPI void window_surface_add_ref( struct window_surface *surface ) diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 657a5ff62cc..83e39528273 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -781,26 +781,30 @@ static struct window_surface *create_surface( HWND hwnd, const RECT *rect, { struct android_window_surface *surface; int width = rect->right - rect->left, height = rect->bottom - rect->top; + char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; + BITMAPINFO *info = (BITMAPINFO *)buffer; + + memset( info, 0, sizeof(*info) ); + set_color_info( info, src_alpha ); + info->bmiHeader.biWidth = width; + info->bmiHeader.biHeight = -height; /* top-down */ + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biSizeImage = get_dib_image_size( info );
surface = calloc( 1, FIELD_OFFSET( struct android_window_surface, info.bmiColors[3] )); if (!surface) return NULL; - window_surface_init( &surface->header, &android_surface_funcs, hwnd, rect ); - - set_color_info( &surface->info, src_alpha ); - surface->info.bmiHeader.biWidth = width; - surface->info.bmiHeader.biHeight = -height; /* top-down */ - surface->info.bmiHeader.biPlanes = 1; - surface->info.bmiHeader.biSizeImage = get_dib_image_size( &surface->info ); + if (!window_surface_init( &surface->header, &android_surface_funcs, hwnd, info, 0 )) goto failed; + memcpy( &surface->info, info, get_dib_info_size( info, DIB_RGB_COLORS ) );
surface->window = get_ioctl_window( hwnd ); surface->alpha = alpha; set_color_key( surface, color_key );
- if (!(surface->header.color_bits = malloc( surface->info.bmiHeader.biSizeImage ))) + if (!(surface->header.color_bits = malloc( info->bmiHeader.biSizeImage ))) goto failed;
TRACE( "created %p hwnd %p %s color_bits %p-%p\n", surface, hwnd, wine_dbgstr_rect(rect), - surface->header.color_bits, (char *)surface->header.color_bits + surface->info.bmiHeader.biSizeImage ); + surface->header.color_bits, (char *)surface->header.color_bits + info->bmiHeader.biSizeImage );
return &surface->header;
diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index a34df22397a..16e1629f993 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -133,37 +133,34 @@ struct window_surface *create_surface(HWND hwnd, macdrv_window window, const REC { struct macdrv_window_surface *surface; int width = rect->right - rect->left, height = rect->bottom - rect->top; - DWORD *colors; DWORD window_background; + char buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])]; + BITMAPINFO *info = (BITMAPINFO *)buffer; + + memset(info, 0, sizeof(*info)); + info->bmiHeader.biSize = sizeof(info->bmiHeader); + info->bmiHeader.biWidth = width; + info->bmiHeader.biHeight = -height; /* top-down */ + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = 32; + info->bmiHeader.biSizeImage = get_dib_image_size(info); + info->bmiHeader.biCompression = BI_RGB;
surface = calloc(1, FIELD_OFFSET(struct macdrv_window_surface, info.bmiColors[3])); if (!surface) return NULL; - window_surface_init(&surface->header, &macdrv_surface_funcs, hwnd, rect); - - surface->info.bmiHeader.biSize = sizeof(surface->info.bmiHeader); - surface->info.bmiHeader.biWidth = width; - surface->info.bmiHeader.biHeight = -height; /* top-down */ - surface->info.bmiHeader.biPlanes = 1; - surface->info.bmiHeader.biBitCount = 32; - surface->info.bmiHeader.biSizeImage = get_dib_image_size(&surface->info); - surface->info.bmiHeader.biCompression = BI_RGB; - surface->info.bmiHeader.biClrUsed = 0; - - colors = (DWORD *)((char *)&surface->info + surface->info.bmiHeader.biSize); - colors[0] = 0x00ff0000; - colors[1] = 0x0000ff00; - colors[2] = 0x000000ff; + if (!window_surface_init(&surface->header, &macdrv_surface_funcs, hwnd, info, 0)) goto failed; + memcpy(&surface->info, info, offsetof(BITMAPINFO, bmiColors[3]));
surface->window = window; if (old_surface) surface->header.bounds = old_surface->bounds; surface->use_alpha = use_alpha; - surface->header.color_bits = malloc(surface->info.bmiHeader.biSizeImage); + surface->header.color_bits = malloc(info->bmiHeader.biSizeImage); if (!surface->header.color_bits) goto failed; window_background = macdrv_window_background_color(); - memset_pattern4(surface->header.color_bits, &window_background, surface->info.bmiHeader.biSizeImage); + memset_pattern4(surface->header.color_bits, &window_background, info->bmiHeader.biSizeImage);
TRACE("created %p for %p %s color_bits %p-%p\n", surface, window, wine_dbgstr_rect(rect), - surface->header.color_bits, (char *)surface->header.color_bits + surface->info.bmiHeader.biSizeImage); + surface->header.color_bits, (char *)surface->header.color_bits + info->bmiHeader.biSizeImage);
return &surface->header;
diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index 3447e151329..636c681a25a 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -452,24 +452,27 @@ static const struct window_surface_funcs wayland_window_surface_funcs = */ struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect) { + char buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])]; + BITMAPINFO *info = (BITMAPINFO *)buffer; struct wayland_window_surface *wws; int width = rect->right - rect->left; int height = rect->bottom - rect->top;
TRACE("hwnd %p rect %s\n", hwnd, wine_dbgstr_rect(rect));
+ memset(info, 0, sizeof(*info)); + info->bmiHeader.biSize = sizeof(info->bmiHeader); + info->bmiHeader.biWidth = width; + info->bmiHeader.biHeight = -height; /* top-down */ + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = 32; + info->bmiHeader.biSizeImage = width * height * 4; + info->bmiHeader.biCompression = BI_RGB; + wws = calloc(1, sizeof(*wws)); if (!wws) return NULL; - window_surface_init(&wws->header, &wayland_window_surface_funcs, hwnd, rect); - - wws->info.bmiHeader.biSize = sizeof(wws->info.bmiHeader); - wws->info.bmiHeader.biClrUsed = 0; - wws->info.bmiHeader.biBitCount = 32; - wws->info.bmiHeader.biCompression = BI_RGB; - wws->info.bmiHeader.biWidth = width; - wws->info.bmiHeader.biHeight = -height; /* top-down */ - wws->info.bmiHeader.biPlanes = 1; - wws->info.bmiHeader.biSizeImage = width * height * 4; + if (!window_surface_init(&wws->header, &wayland_window_surface_funcs, hwnd, info, 0)) goto failed; + wws->info = *info;
if (!(wws->header.color_bits = malloc(wws->info.bmiHeader.biSizeImage))) goto failed; diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index db175938c89..74ba28cfc37 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -1961,24 +1961,28 @@ struct window_surface *create_surface( HWND hwnd, Window window, const XVisualIn COLORREF color_key, BOOL use_alpha ) { const XPixmapFormatValues *format = pixmap_formats[vis->depth]; + char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; + BITMAPINFO *info = (BITMAPINFO *)buffer; struct x11drv_window_surface *surface; int width = rect->right - rect->left, height = rect->bottom - rect->top; int colors = format->bits_per_pixel <= 8 ? 1 << format->bits_per_pixel : 3;
+ memset( info, 0, sizeof(*info) ); + info->bmiHeader.biSize = sizeof(info->bmiHeader); + info->bmiHeader.biWidth = width; + info->bmiHeader.biHeight = -height; /* top-down */ + 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 ); + surface = calloc( 1, FIELD_OFFSET( struct x11drv_window_surface, info.bmiColors[colors] )); if (!surface) return NULL; - window_surface_init( &surface->header, &x11drv_surface_funcs, hwnd, rect ); - - surface->info.bmiHeader.biSize = sizeof(surface->info.bmiHeader); - surface->info.bmiHeader.biWidth = width; - surface->info.bmiHeader.biHeight = -height; /* top-down */ - surface->info.bmiHeader.biPlanes = 1; - surface->info.bmiHeader.biBitCount = format->bits_per_pixel; - surface->info.bmiHeader.biSizeImage = get_dib_image_size( &surface->info ); - if (format->bits_per_pixel > 8) set_color_info( vis, &surface->info, use_alpha ); + if (!window_surface_init( &surface->header, &x11drv_surface_funcs, hwnd, info, 0 )) goto failed; + memcpy( &surface->info, info, get_dib_info_size( info, DIB_RGB_COLORS ) );
surface->window = window; - surface->is_argb = (use_alpha && vis->depth == 32 && surface->info.bmiHeader.biCompression == BI_RGB); + surface->is_argb = (use_alpha && vis->depth == 32 && info->bmiHeader.biCompression == BI_RGB); set_color_key( surface, color_key );
#ifdef HAVE_LIBXXSHM @@ -1989,7 +1993,7 @@ struct window_surface *create_surface( HWND hwnd, Window window, const XVisualIn surface->image = XCreateImage( gdi_display, vis->visual, vis->depth, ZPixmap, 0, NULL, width, height, 32, 0 ); if (!surface->image) goto failed; - surface->image->data = malloc( surface->info.bmiHeader.biSizeImage ); + surface->image->data = malloc( info->bmiHeader.biSizeImage ); if (!surface->image->data) goto failed; }
@@ -2003,13 +2007,13 @@ struct window_surface *create_surface( HWND hwnd, Window window, const XVisualIn if (surface->byteswap || format->bits_per_pixel == 4 || format->bits_per_pixel == 8) { /* allocate separate surface bits if byte swapping or palette mapping is required */ - if (!(surface->header.color_bits = calloc( 1, surface->info.bmiHeader.biSizeImage ))) + if (!(surface->header.color_bits = calloc( 1, info->bmiHeader.biSizeImage ))) goto failed; } else surface->header.color_bits = surface->image->data;
TRACE( "created %p for %lx %s color_bits %p-%p image %p\n", surface, window, wine_dbgstr_rect(rect), - surface->header.color_bits, (char *)surface->header.color_bits + surface->info.bmiHeader.biSizeImage, + surface->header.color_bits, (char *)surface->header.color_bits + info->bmiHeader.biSizeImage, surface->image->data );
return &surface->header; diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 07d29c9b399..556e33d1fa2 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -233,7 +233,8 @@ struct window_surface /* driver-specific fields here */ };
-W32KAPI void window_surface_init( struct window_surface *surface, const struct window_surface_funcs *funcs, HWND hwnd, const RECT *rect ); +W32KAPI BOOL window_surface_init( struct window_surface *surface, const struct window_surface_funcs *funcs, + HWND hwnd, BITMAPINFO *info, HBITMAP bitmap ); W32KAPI void window_surface_add_ref( struct window_surface *surface ); W32KAPI void window_surface_release( struct window_surface *surface ); W32KAPI void window_surface_lock( struct window_surface *surface );