From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/gdi32/gdiobj.c | 131 ++++++++++++++++++------------------------- dlls/gdi32/objects.c | 52 +++++++++++++++++ 2 files changed, 107 insertions(+), 76 deletions(-)
diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c index ffb42ab88e2..50c337cd6c4 100644 --- a/dlls/gdi32/gdiobj.c +++ b/dlls/gdi32/gdiobj.c @@ -82,13 +82,6 @@ static const LOGBRUSH DkGrayBrush = { BS_SOLID, RGB(64,64,64), 0 };
static const LOGBRUSH DCBrush = { BS_SOLID, RGB(255,255,255), 0 };
-/* reserve one extra entry for the stock default bitmap */ -/* this is what Windows does too */ -#define NB_STOCK_OBJECTS (STOCK_LAST+2) - -static HGDIOBJ stock_objects[NB_STOCK_OBJECTS]; -static HGDIOBJ scaled_stock_objects[NB_STOCK_OBJECTS]; - static CRITICAL_SECTION gdi_section; static CRITICAL_SECTION_DEBUG critsect_debug = { @@ -617,14 +610,62 @@ static void set_gdi_shared(void) NtCurrentTeb()->Peb->GdiSharedHandleTable = &gdi_shared; }
-static HGDIOBJ make_stock_object( HGDIOBJ obj ) +static void init_stock_objects(void) { - GDI_HANDLE_ENTRY *entry; + const struct DefaultFontInfo *deffonts; + unsigned int i; + HGDIOBJ obj; + + /* Create stock objects in order matching stock object macros, + * so that they use predictable handle slots. Our GetStockObject + * depends on it. */ + create_brush( &WhiteBrush ); + create_brush( &LtGrayBrush ); + create_brush( &GrayBrush ); + create_brush( &DkGrayBrush ); + create_brush( &BlackBrush ); + create_brush( &NullBrush ); + + create_pen( PS_SOLID, 0, RGB(255,255,255) ); + create_pen( PS_SOLID, 0, RGB(0,0,0) ); + create_pen( PS_NULL, 0, RGB(0,0,0) ); + + /* slot 9 is not used for non-scaled stock objects */ + create_scaled_font( &OEMFixedFont ); + + /* language-independent stock fonts */ + create_font( &OEMFixedFont ); + create_font( &AnsiFixedFont ); + create_font( &AnsiVarFont ); + + /* language-dependent stock fonts */ + deffonts = get_default_fonts(get_default_charset()); + create_font( &deffonts->SystemFont ); + create_font( &deffonts->DeviceDefaultFont ); + + PALETTE_Init(); + + create_font( &deffonts->SystemFixedFont ); + create_font( &deffonts->DefaultGuiFont );
- if (!(entry = handle_entry( obj ))) return 0; - entry_obj( entry )->system = TRUE; - entry->StockFlag = 1; - return entry_to_handle( entry ); + create_brush( &DCBrush ); + NtGdiCreatePen( PS_SOLID, 0, RGB(0,0,0), NULL ); + + obj = NtGdiCreateBitmap( 1, 1, 1, 1, NULL ); + + assert( (HandleToULong( obj ) & 0xffff) == FIRST_GDI_HANDLE + DEFAULT_BITMAP ); + + create_scaled_font( &deffonts->SystemFont ); + create_scaled_font( &deffonts->SystemFixedFont ); + create_scaled_font( &deffonts->DefaultGuiFont ); + + /* clear the NOSYSTEM bit on all stock objects*/ + for (i = 0; i < STOCK_LAST + 5; i++) + { + GDI_HANDLE_ENTRY *entry = &gdi_shared.Handles[FIRST_GDI_HANDLE + i]; + entry_obj( entry )->system = TRUE; + entry->StockFlag = 1; + } }
/*********************************************************************** @@ -634,57 +675,13 @@ static HGDIOBJ make_stock_object( HGDIOBJ obj ) */ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) { - const struct DefaultFontInfo* deffonts; - int i; - if (reason != DLL_PROCESS_ATTACH) return TRUE;
gdi32_module = inst; DisableThreadLibraryCalls( inst ); set_gdi_shared(); font_init(); - - /* create stock objects */ - stock_objects[WHITE_BRUSH] = create_brush( &WhiteBrush ); - stock_objects[LTGRAY_BRUSH] = create_brush( &LtGrayBrush ); - stock_objects[GRAY_BRUSH] = create_brush( &GrayBrush ); - stock_objects[DKGRAY_BRUSH] = create_brush( &DkGrayBrush ); - stock_objects[BLACK_BRUSH] = create_brush( &BlackBrush ); - stock_objects[NULL_BRUSH] = create_brush( &NullBrush ); - - stock_objects[WHITE_PEN] = create_pen( PS_SOLID, 0, RGB(255,255,255) ); - stock_objects[BLACK_PEN] = create_pen( PS_SOLID, 0, RGB(0,0,0) ); - stock_objects[NULL_PEN] = create_pen( PS_NULL, 0, RGB(0,0,0) ); - - stock_objects[DEFAULT_PALETTE] = PALETTE_Init(); - stock_objects[DEFAULT_BITMAP] = NtGdiCreateBitmap( 1, 1, 1, 1, NULL ); - - /* language-independent stock fonts */ - stock_objects[OEM_FIXED_FONT] = create_font( &OEMFixedFont ); - stock_objects[ANSI_FIXED_FONT] = create_font( &AnsiFixedFont ); - stock_objects[ANSI_VAR_FONT] = create_font( &AnsiVarFont ); - - /* language-dependent stock fonts */ - deffonts = get_default_fonts(get_default_charset()); - stock_objects[SYSTEM_FONT] = create_font( &deffonts->SystemFont ); - stock_objects[DEVICE_DEFAULT_FONT] = create_font( &deffonts->DeviceDefaultFont ); - stock_objects[SYSTEM_FIXED_FONT] = create_font( &deffonts->SystemFixedFont ); - stock_objects[DEFAULT_GUI_FONT] = create_font( &deffonts->DefaultGuiFont ); - - scaled_stock_objects[OEM_FIXED_FONT] = create_scaled_font( &OEMFixedFont ); - scaled_stock_objects[SYSTEM_FONT] = create_scaled_font( &deffonts->SystemFont ); - scaled_stock_objects[SYSTEM_FIXED_FONT] = create_scaled_font( &deffonts->SystemFixedFont ); - scaled_stock_objects[DEFAULT_GUI_FONT] = create_scaled_font( &deffonts->DefaultGuiFont ); - - stock_objects[DC_BRUSH] = create_brush( &DCBrush ); - stock_objects[DC_PEN] = create_pen( PS_SOLID, 0, RGB(0,0,0) ); - - /* clear the NOSYSTEM bit on all stock objects*/ - for (i = 0; i < NB_STOCK_OBJECTS; i++) - { - stock_objects[i] = make_stock_object( stock_objects[i] ); - scaled_stock_objects[i] = make_stock_object( scaled_stock_objects[i] ); - } + init_stock_objects(); return TRUE; }
@@ -960,24 +957,6 @@ BOOL WINAPI NtGdiDeleteClientObj( HGDIOBJ handle ) return TRUE; }
-/*********************************************************************** - * GetStockObject (GDI32.@) - */ -HGDIOBJ WINAPI GetStockObject( INT obj ) -{ - if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0; - switch (obj) - { - case OEM_FIXED_FONT: - case SYSTEM_FONT: - case SYSTEM_FIXED_FONT: - case DEFAULT_GUI_FONT: - if (get_system_dpi() != 96) return scaled_stock_objects[obj]; - break; - } - return stock_objects[obj]; -} -
/*********************************************************************** * NtGdiExtGetObjectW (win32u.@) diff --git a/dlls/gdi32/objects.c b/dlls/gdi32/objects.c index b656c2a3f1e..5b1145c52a2 100644 --- a/dlls/gdi32/objects.c +++ b/dlls/gdi32/objects.c @@ -39,6 +39,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdi);
DEFINE_DEVPROPKEY(DEVPROPKEY_GPU_LUID, 0x60b193cb, 0x5276, 0x4d0f, 0x96, 0xfc, 0xf1, 0x73, 0xab, 0xad, 0x3e, 0xc6, 2);
+#define FIRST_GDI_HANDLE 32 + struct hdc_list { HDC hdc; @@ -95,6 +97,12 @@ static inline GDI_HANDLE_ENTRY *handle_entry( HGDIOBJ handle ) return NULL; }
+static HGDIOBJ entry_to_handle( GDI_HANDLE_ENTRY *entry ) +{ + unsigned int idx = entry - get_gdi_shared()->Handles; + return LongToHandle( idx | (entry->Unique << NTGDI_HANDLE_TYPE_SHIFT) ); +} + static DWORD get_object_type( HGDIOBJ obj ) { GDI_HANDLE_ENTRY *entry = handle_entry( obj ); @@ -379,6 +387,50 @@ HGDIOBJ WINAPI GetCurrentObject( HDC hdc, UINT type ) return NtGdiGetDCObject( hdc, obj_type ); }
+/****************************************************************************** + * get_system_dpi + * + * Get the system DPI, based on the DPI awareness mode. + */ +static DWORD get_system_dpi(void) +{ + static UINT (WINAPI *pGetDpiForSystem)(void); + + if (!pGetDpiForSystem) + { + HMODULE user = GetModuleHandleW( L"user32.dll" ); + if (user) pGetDpiForSystem = (void *)GetProcAddress( user, "GetDpiForSystem" ); + } + return pGetDpiForSystem ? pGetDpiForSystem() : 96; +} + +/*********************************************************************** + * GetStockObject (GDI32.@) + */ +HGDIOBJ WINAPI GetStockObject( INT obj ) +{ + if (obj < 0 || obj > STOCK_LAST + 1 || obj == 9) return 0; + + /* Wine stores stock objects in predictable order, see init_stock_objects */ + switch (obj) + { + case OEM_FIXED_FONT: + if (get_system_dpi() != 96) obj = 9; + break; + case SYSTEM_FONT: + if (get_system_dpi() != 96) obj = STOCK_LAST + 2; + break; + case SYSTEM_FIXED_FONT: + if (get_system_dpi() != 96) obj = STOCK_LAST + 3; + break; + case DEFAULT_GUI_FONT: + if (get_system_dpi() != 96) obj = STOCK_LAST + 4; + break; + } + + return entry_to_handle( handle_entry( ULongToHandle( obj + FIRST_GDI_HANDLE ))); +} + /*********************************************************************** * GetObjectA (GDI32.@) */