Jacek Caban : gdi32: Get stock objects directly from GDI_SHARED_MEMORY in GetStockObject.

Alexandre Julliard julliard at winehq.org
Fri Sep 3 16:25:29 CDT 2021


Module: wine
Branch: master
Commit: 951d8ace18c5677d7bc577a08c69a1c1af8bf2d1
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=951d8ace18c5677d7bc577a08c69a1c1af8bf2d1

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Sep  3 13:59:50 2021 +0100

gdi32: Get stock objects directly from GDI_SHARED_MEMORY in GetStockObject.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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.@)
  */




More information about the wine-cvs mailing list