diff --git a/dlls/gdi.exe16/gdi.c b/dlls/gdi.exe16/gdi.c index b4bcd1c2228..3f363ef2401 100644 --- a/dlls/gdi.exe16/gdi.c +++ b/dlls/gdi.exe16/gdi.c @@ -23,11 +23,10 @@ #include "windef.h" #include "winbase.h" -#include "wingdi.h" +#include "ntgdi.h" #include "wownt32.h" #include "wine/wingdi16.h" #include "wine/list.h" -#include "wine/gdi_driver.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(gdi); @@ -430,129 +429,6 @@ static void free_segptr_bits( HBITMAP16 bmp ) } } -/* 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 CDECL dib_surface_lock( struct window_surface *window_surface ) -{ - /* nothing to do */ -} - -/*********************************************************************** - * dib_surface_unlock - */ -static void CDECL dib_surface_unlock( struct window_surface *window_surface ) -{ - /* nothing to do */ -} - -/*********************************************************************** - * dib_surface_get_bitmap_info - */ -static void *CDECL 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 *CDECL 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 CDECL dib_surface_set_region( struct window_surface *window_surface, HRGN region ) -{ - /* nothing to do */ -} - -/*********************************************************************** - * dib_surface_flush - */ -static void CDECL dib_surface_flush( struct window_surface *window_surface ) -{ - /* nothing to do */ -} - -/*********************************************************************** - * dib_surface_destroy - */ -static void CDECL dib_surface_destroy( struct window_surface *window_surface ) -{ - struct dib_window_surface *surface = get_dib_surface( window_surface ); - - TRACE( "freeing %p\n", surface ); - HeapFree( GetProcessHeap(), 0, 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 -}; - -/*********************************************************************** - * create_surface - */ -static struct window_surface *create_surface( const BITMAPINFO *info ) -{ - struct dib_window_surface *surface; - int color = 0; - - 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 = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, - offsetof( struct dib_window_surface, info.bmiColors[color] )); - if (!surface) return NULL; - - surface->header.funcs = &dib_surface_funcs; - surface->header.rect.left = 0; - surface->header.rect.top = 0; - surface->header.rect.right = info->bmiHeader.biWidth; - surface->header.rect.bottom = abs(info->bmiHeader.biHeight); - 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 %lux%lu for info %p bits %p\n", - surface, surface->header.rect.right, surface->header.rect.bottom, info, surface->bits ); - return &surface->header; -} - /*********************************************************************** * SetBkColor (GDI.1) @@ -1299,19 +1175,8 @@ HDC16 WINAPI CreateDC16( LPCSTR driver, LPCSTR device, LPCSTR output, { if (!lstrcmpiA( driver, "dib" ) || !lstrcmpiA( driver, "dirdib" )) { - struct window_surface *surface; - HDC hdc; - - if (!(surface = create_surface( (const BITMAPINFO *)initData ))) return 0; - - if ((hdc = CreateDCA( "DISPLAY", NULL, NULL, NULL ))) - { - __wine_set_visible_region( hdc, CreateRectRgnIndirect( &surface->rect ), - &surface->rect, &surface->rect, surface ); - TRACE( "returning hdc %p surface %p\n", hdc, surface ); - } - window_surface_release( surface ); - return HDC_16( hdc ); + DRIVER_INFO_2W driver_info = { .cVersion = NTGDI_WIN16_DIB }; + return HDC_16( NtGdiOpenDCW( NULL, NULL, NULL, 0, TRUE, 0, &driver_info, (void *)initData )); } return HDC_16( CreateDCA( driver, device, output, initData ) ); } diff --git a/dlls/win32u/clipping.c b/dlls/win32u/clipping.c index 704d5142855..cf13e7d46c7 100644 --- a/dlls/win32u/clipping.c +++ b/dlls/win32u/clipping.c @@ -201,10 +201,10 @@ INT WINAPI NtGdiExtSelectClipRgn( HDC hdc, HRGN rgn, INT mode ) } /*********************************************************************** - * __wine_set_visible_region (win32u.@) + * set_visible_region */ -void CDECL __wine_set_visible_region( HDC hdc, HRGN hrgn, const RECT *vis_rect, const RECT *device_rect, - struct window_surface *surface ) +void set_visible_region( HDC hdc, HRGN hrgn, const RECT *vis_rect, const RECT *device_rect, + struct window_surface *surface ) { DC * dc; diff --git a/dlls/win32u/dc.c b/dlls/win32u/dc.c index 8d2c887ce79..6336c8afb2e 100644 --- a/dlls/win32u/dc.c +++ b/dlls/win32u/dc.c @@ -755,6 +755,13 @@ 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 4c6035b0b12..ee5359e616c 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -245,6 +245,134 @@ 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 CDECL dib_surface_lock( struct window_surface *window_surface ) +{ + /* nothing to do */ +} + +/*********************************************************************** + * dib_surface_unlock + */ +static void CDECL dib_surface_unlock( struct window_surface *window_surface ) +{ + /* nothing to do */ +} + +/*********************************************************************** + * dib_surface_get_bitmap_info + */ +static void *CDECL 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 *CDECL 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 CDECL dib_surface_set_region( struct window_surface *window_surface, HRGN region ) +{ + /* nothing to do */ +} + +/*********************************************************************** + * dib_surface_flush + */ +static void CDECL dib_surface_flush( struct window_surface *window_surface ) +{ + /* nothing to do */ +} + +/*********************************************************************** + * dib_surface_destroy + */ +static void CDECL 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, rect.right, 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 * @@ -400,7 +528,7 @@ static void update_visible_region( struct dce *dce ) } if (!surface) SetRectEmpty( &top_rect ); - __wine_set_visible_region( dce->hdc, vis_rgn, &win_rect, &top_rect, surface ); + set_visible_region( dce->hdc, vis_rgn, &win_rect, &top_rect, surface ); if (surface) window_surface_release( surface ); } @@ -411,7 +539,7 @@ static void release_dce( struct dce *dce ) { if (!dce->hwnd) return; /* already released */ - __wine_set_visible_region( dce->hdc, 0, &dummy_surface.rect, &dummy_surface.rect, &dummy_surface ); + set_visible_region( dce->hdc, 0, &dummy_surface.rect, &dummy_surface.rect, &dummy_surface ); user_driver->pReleaseDC( dce->hwnd, dce->hdc ); if (dce->clip_rgn) NtGdiDeleteObjectApp( dce->clip_rgn ); diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index 09262845866..d05de2f959f 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -1229,7 +1229,6 @@ static struct unix_funcs unix_funcs = __wine_get_vulkan_driver, __wine_get_wgl_driver, __wine_set_display_driver, - __wine_set_visible_region, }; NTSTATUS gdi_init(void) diff --git a/dlls/win32u/ntgdi_private.h b/dlls/win32u/ntgdi_private.h index 75cddc00fb3..9328a02e1bc 100644 --- a/dlls/win32u/ntgdi_private.h +++ b/dlls/win32u/ntgdi_private.h @@ -159,6 +159,8 @@ extern void free_brush_pattern( struct brush_pattern *pattern ) DECLSPEC_HIDDEN; /* clipping.c */ extern BOOL clip_device_rect( DC *dc, RECT *dst, const RECT *src ) DECLSPEC_HIDDEN; extern BOOL clip_visrect( DC *dc, RECT *dst, const RECT *src ) DECLSPEC_HIDDEN; +extern void set_visible_region( HDC hdc, HRGN hrgn, const RECT *vis_rect, + const RECT *device_rect, struct window_surface *surface ); extern void update_dc_clipping( DC * dc ) DECLSPEC_HIDDEN; /* Return the total DC region (if any) */ diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 1e1060b4c36..a179a720773 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1320,9 +1320,6 @@ ################################################################ # Wine internal extensions -# user32 -@ cdecl __wine_set_visible_region(long long ptr ptr ptr) - # Graphics drivers @ cdecl __wine_set_display_driver(ptr long) diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index dcadf24040b..8f954fb40f8 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -290,8 +290,6 @@ struct unix_funcs const struct vulkan_funcs * (CDECL *get_vulkan_driver)( UINT version ); struct opengl_funcs * (CDECL *get_wgl_driver)( HDC hdc, UINT version ); void (CDECL *set_display_driver)( struct user_driver_funcs *funcs, UINT version ); - void (CDECL *set_visible_region)( HDC hdc, HRGN hrgn, const RECT *vis_rect, const RECT *device_rect, - struct window_surface *surface ); }; /* clipboard.c */ @@ -305,6 +303,7 @@ extern ULONG_PTR set_icon_param( HICON handle, ULONG_PTR param ) DECLSPEC_HIDDEN /* dce.c */ extern struct window_surface dummy_surface DECLSPEC_HIDDEN; +extern BOOL create_dib_surface( HDC hdc, const BITMAPINFO *info ) DECLSPEC_HIDDEN; extern void create_offscreen_window_surface( const RECT *visible_rect, struct window_surface **surface ) DECLSPEC_HIDDEN; extern void erase_now( HWND hwnd, UINT rdw_flags ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c index 05e200e7403..1f7c7f6ab51 100644 --- a/dlls/win32u/wrappers.c +++ b/dlls/win32u/wrappers.c @@ -1166,13 +1166,6 @@ BOOL CDECL __wine_get_icm_profile( HDC hdc, BOOL allow_default, DWORD *size, WCH return unix_funcs->get_icm_profile( hdc, allow_default, size, filename ); } -void CDECL __wine_set_visible_region( HDC hdc, HRGN hrgn, const RECT *vis_rect, const RECT *device_rect, - struct window_surface *surface ) -{ - if (!unix_funcs) return; - unix_funcs->set_visible_region( hdc, hrgn, vis_rect, device_rect, surface ); -} - BOOL CDECL __wine_get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void *bits, UINT *usage ) { if (!unix_funcs) return FALSE; diff --git a/include/ntgdi.h b/include/ntgdi.h index d8103e3f995..3bc1d4206e4 100644 --- a/include/ntgdi.h +++ b/include/ntgdi.h @@ -183,6 +183,9 @@ 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 diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index b3c77a1d2c1..ecbc8ea9de1 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -327,8 +327,6 @@ struct user_driver_funcs }; extern void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version ); -extern void CDECL __wine_set_visible_region( HDC hdc, HRGN hrgn, const RECT *vis_rect, - const RECT *device_rect, struct window_surface *surface ); extern void CDECL __wine_set_display_driver( struct user_driver_funcs *funcs, UINT version ); extern struct opengl_funcs * CDECL __wine_get_wgl_driver( HDC hdc, UINT version ); extern const struct vulkan_funcs * CDECL __wine_get_vulkan_driver( UINT version );