1
0
mirror of https://github.com/wine-mirror/wine synced 2024-06-29 06:14:34 +00:00

win32u: Use NtGdiDdDDICreateDCFromMemory for gdi16 DIBDRV.

Instead of a custom dib_window_surface.
This commit is contained in:
Rémi Bernon 2024-03-17 00:53:39 +01:00 committed by Alexandre Julliard
parent b6223da118
commit b3bec339d7
5 changed files with 77 additions and 141 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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
*

View File

@ -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 );

View File

@ -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