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