From d5ce63508fe93568d9b967ced632a522b7b84479 Mon Sep 17 00:00:00 2001 From: Luca Bacci Date: Tue, 1 Mar 2022 09:25:28 +0100 Subject: [PATCH 1/3] GdkWin32: Retrieve module HINSTANCE in static builds --- gdk/win32/gdkmain-win32.c | 11 ++++++++++ gtk/gtkwin32.c | 46 ++++++++++++++++++++++++++++++--------- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/gdk/win32/gdkmain-win32.c b/gdk/win32/gdkmain-win32.c index 043341a255..f9e18f42ff 100644 --- a/gdk/win32/gdkmain-win32.c +++ b/gdk/win32/gdkmain-win32.c @@ -69,6 +69,17 @@ _gdk_win32_windowing_init (void) if (gdk_synchronize) GdiSetBatchLimit (1); +#ifndef DLL_EXPORT + if (!GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCWSTR)_gdk_win32_windowing_init, + &_gdk_dll_hinstance)) + { + g_error ("GetModuleHandleExW failed with error code %u\n", + (unsigned) GetLastError ()); + } +#endif + _gdk_app_hmodule = GetModuleHandle (NULL); _gdk_display_hdc = CreateDC ("DISPLAY", NULL, NULL, NULL); _gdk_input_locale = GetKeyboardLayout (0); diff --git a/gtk/gtkwin32.c b/gtk/gtkwin32.c index a086ad61ac..dfe068d215 100644 --- a/gtk/gtkwin32.c +++ b/gtk/gtkwin32.c @@ -38,10 +38,9 @@ */ #define EMPIRIC_MANIFEST_RESOURCE_INDEX 2 - +#ifdef DLL_EXPORT static HMODULE gtk_dll; -#ifdef DLL_EXPORT BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, @@ -56,6 +55,32 @@ DllMain (HINSTANCE hinstDLL, return TRUE; } + +static HMODULE +get_gtk_dll (void) +{ + return gtk_dll; +} +#else +static HMODULE +get_gtk_dll (void) +{ + static HMODULE gtk_dll = NULL; + + if G_UNLIKELY (gtk_dll == NULL) + { + if (!GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCWSTR) get_gtk_dll, + >k_dll)) + { + g_error ("GetModuleHandleExW failed with error code %u\n", + (unsigned) GetLastError ()); + } + } + + return gtk_dll; +} #endif static BOOL CALLBACK @@ -104,7 +129,8 @@ _gtk_load_dll_with_libgtk3_manifest (const gchar *dll_name) DWORD error_code; resource_name = NULL; - EnumResourceNames (gtk_dll, RT_MANIFEST, find_first_manifest, + EnumResourceNames (get_gtk_dll (), RT_MANIFEST, + find_first_manifest, (LONG_PTR) &resource_name); if (resource_name == NULL) @@ -115,7 +141,7 @@ _gtk_load_dll_with_libgtk3_manifest (const gchar *dll_name) activation_ctx_descriptor.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID | ACTCTX_FLAG_SET_PROCESS_DEFAULT; - activation_ctx_descriptor.hModule = gtk_dll; + activation_ctx_descriptor.hModule = get_gtk_dll (); activation_ctx_descriptor.lpResourceName = resource_name; activation_ctx_handle = CreateActCtx (&activation_ctx_descriptor); error_code = GetLastError (); @@ -123,7 +149,7 @@ _gtk_load_dll_with_libgtk3_manifest (const gchar *dll_name) if (activation_ctx_handle == INVALID_HANDLE_VALUE && error_code != ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET) g_warning ("Failed to CreateActCtx for module %p, resource %p: %lu", - gtk_dll, resource_name, GetLastError ()); + get_gtk_dll (), resource_name, GetLastError ()); else if (error_code != ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET) { activation_cookie = 0; @@ -150,7 +176,7 @@ _gtk_get_libdir (void) static char *gtk_libdir = NULL; if (gtk_libdir == NULL) { - gchar *root = g_win32_get_package_installation_directory_of_module (gtk_dll); + gchar *root = g_win32_get_package_installation_directory_of_module (get_gtk_dll ()); gchar *slash = strrchr (root, '\\'); if (slash != NULL && g_ascii_strcasecmp (slash + 1, ".libs") == 0) @@ -181,7 +207,7 @@ _gtk_get_localedir (void) while (*--p != '/') ; - root = g_win32_get_package_installation_directory_of_module (gtk_dll); + root = g_win32_get_package_installation_directory_of_module (get_gtk_dll ()); temp = g_build_filename (root, p, NULL); g_free (root); @@ -200,7 +226,7 @@ _gtk_get_datadir (void) static char *gtk_datadir = NULL; if (gtk_datadir == NULL) { - gchar *root = g_win32_get_package_installation_directory_of_module (gtk_dll); + gchar *root = g_win32_get_package_installation_directory_of_module (get_gtk_dll ()); gtk_datadir = g_build_filename (root, "share", NULL); g_free (root); } @@ -214,7 +240,7 @@ _gtk_get_sysconfdir (void) static char *gtk_sysconfdir = NULL; if (gtk_sysconfdir == NULL) { - gchar *root = g_win32_get_package_installation_directory_of_module (gtk_dll); + gchar *root = g_win32_get_package_installation_directory_of_module (get_gtk_dll ()); gtk_sysconfdir = g_build_filename (root, "etc", NULL); g_free (root); } @@ -227,7 +253,7 @@ _gtk_get_data_prefix (void) { static char *gtk_data_prefix = NULL; if (gtk_data_prefix == NULL) - gtk_data_prefix = g_win32_get_package_installation_directory_of_module (gtk_dll); + gtk_data_prefix = g_win32_get_package_installation_directory_of_module (get_gtk_dll ()); return gtk_data_prefix; } From ef4e1c473ce430f8cdec3b4fe752ce4a9b0316db Mon Sep 17 00:00:00 2001 From: Luca Bacci Date: Thu, 3 Mar 2022 12:04:51 +0100 Subject: [PATCH 2/3] Define DLL_EXPORT and _GDK_EXTERN depending on whether we are building a shared or a static library Static builds on Windows are only supported in the Meson build --- config.h.meson | 3 +++ config.h.win32.in | 13 +++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/config.h.meson b/config.h.meson index ce2aeb2946..f6716795f9 100644 --- a/config.h.meson +++ b/config.h.meson @@ -230,6 +230,9 @@ /* Define to the version of this package. */ #mesondefine PACKAGE_VERSION +/* Define when building a shared library for Windows */ +#mesondefine DLL_EXPORT + /* Use NSBundle functions to determine load paths for libraries, translations, etc. */ #mesondefine QUARTZ_RELOCATION diff --git a/config.h.win32.in b/config.h.win32.in index 9666b1b872..a68a4f20a0 100644 --- a/config.h.win32.in +++ b/config.h.win32.in @@ -314,11 +314,16 @@ /* Number of bits in a file offset, on hosts where this is settable. */ /* #undef _FILE_OFFSET_BITS */ +/* Define when building a shared library for Windows */ +#define DLL_EXPORT 1 + /* defines how to decorate public symbols while building */ -#ifdef _MSC_VER -#define _GDK_EXTERN __declspec (dllexport) extern -#else -#define _GDK_EXTERN __attribute__((visibility("default"))) __declspec (dllexport) extern +#ifdef DLL_EXPORT +# ifdef _MSC_VER +# define _GDK_EXTERN __declspec (dllexport) extern +# else +# define _GDK_EXTERN __attribute__((visibility("default"))) __declspec (dllexport) extern +# endif #endif /* Define for large files, on AIX-style hosts. */ From d53b6b858ff939d8dd72364c25aa464d28e7b288 Mon Sep 17 00:00:00 2001 From: Luca Bacci Date: Thu, 3 Mar 2022 14:07:48 +0100 Subject: [PATCH 3/3] GDK: Avoid using constructors on Win32 The constructors in GDK only have a meaning for UNIX, on Windows they are useless. --- gdk/gdk.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gdk/gdk.c b/gdk/gdk.c index f0869a6a81..83672d8f87 100644 --- a/gdk/gdk.c +++ b/gdk/gdk.c @@ -1132,7 +1132,8 @@ gdk_unichar_direction (gunichar ch) return PANGO_DIRECTION_LTR; } -#ifdef G_HAS_CONSTRUCTORS +#if defined (G_HAS_CONSTRUCTORS) && !defined (G_OS_WIN32) +#define GDK_USE_CONSTRUCTORS #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(stash_startup_id) #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(stash_autostart_id) @@ -1175,7 +1176,7 @@ gdk_get_desktop_startup_id (void) if (g_once_init_enter (&init)) { -#ifndef G_HAS_CONSTRUCTORS +#ifndef GDK_USE_CONSTRUCTORS stash_startup_id (); #endif /* Clear the environment variable so it won't be inherited by @@ -1196,7 +1197,7 @@ gdk_get_desktop_autostart_id (void) if (g_once_init_enter (&init)) { -#ifndef G_HAS_CONSTRUCTORS +#ifndef GDK_USE_CONSTRUCTORS stash_autostart_id (); #endif /* Clear the environment variable so it won't be inherited by