summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--gtk/Makefile.am3
-rw-r--r--gtk/gtk-win32.rc.in1
-rw-r--r--gtk/gtkprintoperation-win32.c19
-rw-r--r--gtk/gtkprivate.h4
-rw-r--r--gtk/gtkwin32.c90
-rw-r--r--gtk/libgtk3.manifest.in21
7 files changed, 138 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index 891094db72..314dacf82b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1894,6 +1894,7 @@ gtk/Makefile
gtk/makefile.msc
gtk/gtkversion.h
gtk/gtk-win32.rc
+gtk/libgtk3.manifest
gtk/inspector/Makefile
gtk/native/Makefile
util/Makefile
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 2f74d2e862..5c31084a7a 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -90,7 +90,7 @@ gtk_win32_symbols = -export-symbols $(srcdir)/gtk.def
gtk_win32_res = gtk-win32-res.o
gtk_win32_res_ldflag = -Wl,gtk-win32-res.o
-gtk-win32-res.o : gtk-win32.rc
+gtk-win32-res.o : gtk-win32.rc libgtk3.manifest
$(WINDRES) gtk-win32.rc $@
gtk.def: libgtk-3.la
@@ -1726,6 +1726,7 @@ EXTRA_DIST += \
$(adwaita_sources) \
$(win32_theme_sources) \
$(gsettings_SCHEMAS) \
+ libgtk3.manifest.in \
gtk-win32.rc.in \
gtkwin32embed.h \
gtkwin32embedwidget.h \
diff --git a/gtk/gtk-win32.rc.in b/gtk/gtk-win32.rc.in
index 4a42d5a666..dc9464a2c1 100644
--- a/gtk/gtk-win32.rc.in
+++ b/gtk/gtk-win32.rc.in
@@ -28,3 +28,4 @@ VS_VERSION_INFO VERSIONINFO
VALUE "Translation", 0x409, 1200
END
END
+ISOLATIONAWARE_MANIFEST_RESOURCE_ID RT_MANIFEST libgtk3.manifest
diff --git a/gtk/gtkprintoperation-win32.c b/gtk/gtkprintoperation-win32.c
index e59eb9f675..3ac6bc47bf 100644
--- a/gtk/gtkprintoperation-win32.c
+++ b/gtk/gtkprintoperation-win32.c
@@ -1657,6 +1657,25 @@ gtk_print_operation_run_with_dialog (GtkPrintOperation *op,
GtkPrintOperationPrivate *priv;
IPrintDialogCallback *callback;
HPROPSHEETPAGE prop_page;
+ static volatile gsize common_controls_initialized = 0;
+
+ if (g_once_init_enter (&common_controls_initialized))
+ {
+ BOOL initialized;
+ INITCOMMONCONTROLSEX icc;
+
+ memset (&icc, 0, sizeof (icc));
+ icc.dwSize = sizeof (icc);
+ icc.dwICC = ICC_WIN95_CLASSES;
+
+ initialized = InitCommonControlsEx (&icc);
+ if (!initialized)
+ g_warning ("Failed to InitCommonControlsEx: %lu\n", GetLastError ());
+
+ _gtk_load_dll_with_libgtk3_manifest ("comdlg32.dll");
+
+ g_once_init_leave (&common_controls_initialized, initialized ? 1 : 0);
+ }
*do_print = FALSE;
diff --git a/gtk/gtkprivate.h b/gtk/gtkprivate.h
index a07f7292ba..5fe7d88eae 100644
--- a/gtk/gtkprivate.h
+++ b/gtk/gtkprivate.h
@@ -91,6 +91,10 @@ gboolean _gtk_propagate_captured_event (GtkWidget *widget,
GdkEvent *event,
GtkWidget *topmost);
+#ifdef G_OS_WIN32
+void _gtk_load_dll_with_libgtk3_manifest (const char *dllname);
+#endif
+
G_END_DECLS
#endif /* __GTK_PRIVATE_H__ */
diff --git a/gtk/gtkwin32.c b/gtk/gtkwin32.c
index e8bd7ef133..c33659e278 100644
--- a/gtk/gtkwin32.c
+++ b/gtk/gtkwin32.c
@@ -30,8 +30,15 @@
#define STRICT
#include <windows.h>
+#include <commctrl.h>
#undef STRICT
+/* In practice, resulting DLL will have manifest resource under index 2.
+ * Fall back to that value if we can't find resource index programmatically.
+ */
+#define EMPIRIC_MANIFEST_RESOURCE_INDEX 2
+
+
static HMODULE gtk_dll;
BOOL WINAPI
@@ -49,6 +56,89 @@ DllMain (HINSTANCE hinstDLL,
return TRUE;
}
+static BOOL CALLBACK
+find_first_manifest (HMODULE module_handle,
+ LPCSTR resource_type,
+ LPSTR resource_name,
+ LONG_PTR user_data)
+{
+ LPSTR *result_name = (LPSTR *) user_data;
+
+ if (resource_type == RT_MANIFEST)
+ {
+ if (IS_INTRESOURCE (resource_name))
+ *result_name = resource_name;
+ else
+ *result_name = g_strdup (resource_name);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Grabs the first manifest it finds in libgtk3 (which is expected to be the
+ * common-controls-6.0.0.0 manifest we embedded to enable visual styles),
+ * uses it to create a process-default activation context, activates that
+ * context, loads up the library passed in @dllname, then deactivates and
+ * releases the context.
+ *
+ * In practice this is used to force system DLLs (like comdlg32) to be
+ * loaded as if the application had the same manifest as libgtk3
+ * (otherwise libgtk3 manifest only affests libgtk3 itself).
+ * This way application does not need to have a manifest or to link
+ * against comctl32.
+ *
+ * Note that loaded library handle leaks, so only use this function in
+ * g_once_init_enter (leaking once is OK, Windows will clean up after us).
+ */
+void
+_gtk_load_dll_with_libgtk3_manifest (const gchar *dll_name)
+{
+ HANDLE activation_ctx_handle;
+ ACTCTXA activation_ctx_descriptor;
+ ULONG_PTR activation_cookie;
+ LPSTR resource_name;
+ BOOL activated;
+
+ resource_name = NULL;
+ EnumResourceNames (gtk_dll, RT_MANIFEST, find_first_manifest,
+ (LONG_PTR) &resource_name);
+
+ if (resource_name == NULL)
+ resource_name = MAKEINTRESOURCEA (EMPIRIC_MANIFEST_RESOURCE_INDEX);
+
+ memset (&activation_ctx_descriptor, 0, sizeof (activation_ctx_descriptor));
+ activation_ctx_descriptor.cbSize = sizeof (activation_ctx_descriptor);
+ 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.lpResourceName = resource_name;
+ activation_ctx_handle = CreateActCtx (&activation_ctx_descriptor);
+
+ if (activation_ctx_handle == INVALID_HANDLE_VALUE)
+ g_warning ("Failed to CreateActCtx for module %p, resource %p: %lu\n",
+ gtk_dll, resource_name, GetLastError ());
+ else
+ {
+ activation_cookie = 0;
+ activated = ActivateActCtx (activation_ctx_handle, &activation_cookie);
+
+ if (!activated)
+ g_warning ("Failed to ActivateActCtx: %lu\n", GetLastError ());
+
+ LoadLibraryA (dll_name);
+
+ if (activated && !DeactivateActCtx (0, activation_cookie))
+ g_warning ("Failed to DeactivateActCtx: %lu\n", GetLastError ());
+
+ ReleaseActCtx (activation_ctx_handle);
+ }
+
+ if (!IS_INTRESOURCE (resource_name))
+ g_free (resource_name);
+}
+
const gchar *
_gtk_get_libdir (void)
{
diff --git a/gtk/libgtk3.manifest.in b/gtk/libgtk3.manifest.in
new file mode 100644
index 0000000000..6e1677eb1f
--- /dev/null
+++ b/gtk/libgtk3.manifest.in
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="@EXE_MANIFEST_ARCHITECTURE@"
+ name="libgtk3"
+ type="win32"
+ />
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="@EXE_MANIFEST_ARCHITECTURE@"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+ </dependency>
+</assembly>