From b3bec339d7851b14abf6f6ca341731d560c7f44b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Sun, 17 Mar 2024 00:53:39 +0100 Subject: [PATCH] win32u: Use NtGdiDdDDICreateDCFromMemory for gdi16 DIBDRV. Instead of a custom dib_window_surface. --- dlls/gdi.exe16/gdi.c | 80 +++++++++++++++++++++- dlls/win32u/dc.c | 6 -- dlls/win32u/dce.c | 128 ----------------------------------- dlls/win32u/win32u_private.h | 1 - include/ntgdi.h | 3 - 5 files changed, 77 insertions(+), 141 deletions(-) diff --git a/dlls/gdi.exe16/gdi.c b/dlls/gdi.exe16/gdi.c index 3f363ef2401..c634f0739c7 100644 --- a/dlls/gdi.exe16/gdi.c +++ b/dlls/gdi.exe16/gdi.c @@ -43,6 +43,15 @@ struct saved_visrgn static struct list saved_regions = LIST_INIT( saved_regions ); +struct saved_bitmap +{ + struct list entry; + HDC hdc; + HBITMAP hbitmap; +}; + +static struct list saved_bitmaps = LIST_INIT( saved_bitmaps ); + static HPALETTE16 hPrimaryPalette; /* @@ -1175,8 +1184,62 @@ HDC16 WINAPI CreateDC16( LPCSTR driver, LPCSTR device, LPCSTR output, { if (!lstrcmpiA( driver, "dib" ) || !lstrcmpiA( driver, "dirdib" )) { - DRIVER_INFO_2W driver_info = { .cVersion = NTGDI_WIN16_DIB }; - return HDC_16( NtGdiOpenDCW( NULL, NULL, NULL, 0, TRUE, 0, &driver_info, (void *)initData )); + PALETTEENTRY palette[256]; + BITMAPINFO *info = (BITMAPINFO *)initData; + D3DKMT_CREATEDCFROMMEMORY desc = + { + .Width = info->bmiHeader.biWidth, + .Height = info->bmiHeader.biHeight, + .Pitch = info->bmiHeader.biWidth * info->bmiHeader.biBitCount / 8, + }; + struct saved_bitmap *bitmap; + int color; + + if (info->bmiHeader.biBitCount <= 8) + { + if (info->bmiHeader.biClrUsed) + { + for (color = 0; color < info->bmiHeader.biClrUsed; color++) + { + palette[color].peBlue = info->bmiColors[color].rgbBlue; + palette[color].peGreen = info->bmiColors[color].rgbGreen; + palette[color].peRed = info->bmiColors[color].rgbRed; + } + } + else + { + for (color = 0; color < (1 << info->bmiHeader.biBitCount); color++) + { + palette[color].peBlue = color; + palette[color].peGreen = color; + palette[color].peRed = color; + } + } + desc.pColorTable = palette; + desc.Format = D3DDDIFMT_P8; + desc.pMemory = &info->bmiColors[color]; + } + else if (info->bmiHeader.biCompression == BI_BITFIELDS) + { + desc.Format = D3DDDIFMT_R5G6B5; + desc.pMemory = &info->bmiColors[3]; + } + else + { + desc.Format = info->bmiHeader.biBitCount == 24 ? D3DDDIFMT_R8G8B8 : D3DDDIFMT_X8R8G8B8; + desc.pMemory = &info->bmiColors[0]; + } + + if (NtGdiDdDDICreateDCFromMemory( &desc )) return 0; + + if ((bitmap = HeapAlloc( GetProcessHeap(), 0, sizeof(*bitmap) ))) + { + bitmap->hdc = desc.hDc; + bitmap->hbitmap = desc.hBitmap; + list_add_tail( &saved_bitmaps, &bitmap->entry ); + } + + return HDC_16( desc.hDc ); } return HDC_16( CreateDCA( driver, device, output, initData ) ); } @@ -1329,8 +1392,10 @@ BOOL16 WINAPI DeleteDC16( HDC16 hdc ) { if (DeleteDC( HDC_32(hdc) )) { - struct saved_visrgn *saved, *next; + struct saved_visrgn *saved; + struct saved_bitmap *bitmap; struct gdi_thunk* thunk; + void *next; if ((thunk = GDI_FindThunk(hdc))) GDI_DeleteThunk(thunk); @@ -1341,6 +1406,15 @@ BOOL16 WINAPI DeleteDC16( HDC16 hdc ) DeleteObject( saved->hrgn ); HeapFree( GetProcessHeap(), 0, saved ); } + + LIST_FOR_EACH_ENTRY_SAFE( bitmap, next, &saved_bitmaps, struct saved_bitmap, entry ) + { + if (bitmap->hdc != HDC_32(hdc)) continue; + list_remove( &bitmap->entry ); + DeleteObject( bitmap->hbitmap ); + HeapFree( GetProcessHeap(), 0, bitmap ); + } + return TRUE; } return FALSE; diff --git a/dlls/win32u/dc.c b/dlls/win32u/dc.c index 16920e08d33..24a3bca5544 100644 --- a/dlls/win32u/dc.c +++ b/dlls/win32u/dc.c @@ -765,12 +765,6 @@ HDC WINAPI NtGdiOpenDCW( UNICODE_STRING *device, const DEVMODEW *devmode, UNICOD DC_InitDC( dc ); release_dc_ptr( dc ); - if (driver_info && driver_info->cVersion == NTGDI_WIN16_DIB && - !create_dib_surface( hdc, pdev )) - { - NtGdiDeleteObjectApp( hdc ); - return 0; - } return hdc; } diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 39bbc77f29f..5c4f691b460 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -245,134 +245,6 @@ void create_offscreen_window_surface( const RECT *visible_rect, struct window_su *surface = &impl->header; } -/* window surface used to implement the DIB.DRV driver */ - -struct dib_window_surface -{ - struct window_surface header; - RECT bounds; - void *bits; - UINT info_size; - BITMAPINFO info; /* variable size, must be last */ -}; - -static struct dib_window_surface *get_dib_surface( struct window_surface *surface ) -{ - return (struct dib_window_surface *)surface; -} - -/*********************************************************************** - * dib_surface_lock - */ -static void dib_surface_lock( struct window_surface *window_surface ) -{ - /* nothing to do */ -} - -/*********************************************************************** - * dib_surface_unlock - */ -static void dib_surface_unlock( struct window_surface *window_surface ) -{ - /* nothing to do */ -} - -/*********************************************************************** - * dib_surface_get_bitmap_info - */ -static void *dib_surface_get_bitmap_info( struct window_surface *window_surface, BITMAPINFO *info ) -{ - struct dib_window_surface *surface = get_dib_surface( window_surface ); - - memcpy( info, &surface->info, surface->info_size ); - return surface->bits; -} - -/*********************************************************************** - * dib_surface_get_bounds - */ -static RECT *dib_surface_get_bounds( struct window_surface *window_surface ) -{ - struct dib_window_surface *surface = get_dib_surface( window_surface ); - - return &surface->bounds; -} - -/*********************************************************************** - * dib_surface_set_region - */ -static void dib_surface_set_region( struct window_surface *window_surface, HRGN region ) -{ - /* nothing to do */ -} - -/*********************************************************************** - * dib_surface_flush - */ -static void dib_surface_flush( struct window_surface *window_surface ) -{ - /* nothing to do */ -} - -/*********************************************************************** - * dib_surface_destroy - */ -static void dib_surface_destroy( struct window_surface *window_surface ) -{ - struct dib_window_surface *surface = get_dib_surface( window_surface ); - - TRACE( "freeing %p\n", surface ); - free( surface ); -} - -static const struct window_surface_funcs dib_surface_funcs = -{ - dib_surface_lock, - dib_surface_unlock, - dib_surface_get_bitmap_info, - dib_surface_get_bounds, - dib_surface_set_region, - dib_surface_flush, - dib_surface_destroy -}; - -BOOL create_dib_surface( HDC hdc, const BITMAPINFO *info ) -{ - struct dib_window_surface *surface; - int color = 0; - HRGN region; - RECT rect; - - if (info->bmiHeader.biBitCount <= 8) - color = info->bmiHeader.biClrUsed ? info->bmiHeader.biClrUsed : (1 << info->bmiHeader.biBitCount); - else if (info->bmiHeader.biCompression == BI_BITFIELDS) - color = 3; - - surface = calloc( 1, offsetof( struct dib_window_surface, info.bmiColors[color] )); - if (!surface) return FALSE; - - rect.left = 0; - rect.top = 0; - rect.right = info->bmiHeader.biWidth; - rect.bottom = abs(info->bmiHeader.biHeight); - - surface->header.funcs = &dib_surface_funcs; - surface->header.rect = rect; - surface->header.ref = 1; - surface->info_size = offsetof( BITMAPINFO, bmiColors[color] ); - surface->bits = (char *)info + surface->info_size; - memcpy( &surface->info, info, surface->info_size ); - - TRACE( "created %p %ux%u for info %p bits %p\n", - surface, (int)rect.right, (int)rect.bottom, info, surface->bits ); - - region = NtGdiCreateRectRgn( rect.left, rect.top, rect.right, rect.bottom ); - set_visible_region( hdc, region, &rect, &rect, &surface->header ); - TRACE( "using hdc %p surface %p\n", hdc, surface ); - window_surface_release( &surface->header ); - return TRUE; -} - /******************************************************************* * register_window_surface * diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 7672cf3b356..222db6fb5f7 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -45,7 +45,6 @@ extern ULONG_PTR set_icon_param( HICON handle, ULONG_PTR param ); /* dce.c */ extern struct window_surface dummy_surface; -extern BOOL create_dib_surface( HDC hdc, const BITMAPINFO *info ); extern void create_offscreen_window_surface( const RECT *visible_rect, struct window_surface **surface ); extern void erase_now( HWND hwnd, UINT rdw_flags ); diff --git a/include/ntgdi.h b/include/ntgdi.h index 50973535c7a..a33638deee4 100644 --- a/include/ntgdi.h +++ b/include/ntgdi.h @@ -219,9 +219,6 @@ struct font_enum_entry /* flag for NtGdiGetRandomRgn to respect LAYOUT_RTL */ #define NTGDI_RGN_MIRROR_RTL 0x80000000 -/* magic driver version that we use for win16 DCs with DIB surfaces */ -#define NTGDI_WIN16_DIB 0xfafa000 - #endif /* __WINESRC__ */ struct font_realization_info