[gtk+/master.fcw: 319/648] GDK-Win32 Implement is_composited() and set_composited()



commit ed3ea2b086dac51b56a742573c473c9fa4079ba2
Author: Chun-wei Fan <fanchunwei src gnome org>
Date:   Mon Dec 22 17:34:28 2014 +0800

    GDK-Win32 Implement is_composited() and set_composited()
    
    This adds implementations for ->is_composited() and set_composited() for
    the Windows GDK backend, with the following notes:
    
    -Compositing is always enabled on Windows 8/Server 2012 and later, and
     one is not allowed to disable programmatically, hence we check whether
     we are on at least Windows 8/Server 2012 first.
    -XP does not support DWM for compositing, so it is off for it.  There is
     compatibility code to make sure the code still runs on XP, but it may be
     dropped soon.  We would then only need to check whether we are on Windows
     8+/Server 2012+.
    -DWM API functions are checked for availability at run time.
    -As mentioned, only Windows Vista/7/Server 2008/Server 2008 R2 supports
     enabling and disabling compositing programmatically.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=741849

 gdk/win32/gdkmain-win32.c    |   29 +++++++++++++++++++++++++++
 gdk/win32/gdkprivate-win32.h |   45 ++++++++++++++++++++++++++++++++++++++++++
 gdk/win32/gdkscreen-win32.c  |   22 +++++++++++++++++++-
 gdk/win32/gdkwindow-win32.c  |   28 +++++++++++++++++++++++++-
 4 files changed, 122 insertions(+), 2 deletions(-)
---
diff --git a/gdk/win32/gdkmain-win32.c b/gdk/win32/gdkmain-win32.c
index 3932245..ce41782 100644
--- a/gdk/win32/gdkmain-win32.c
+++ b/gdk/win32/gdkmain-win32.c
@@ -165,6 +165,35 @@ _gdk_win32_check_os_version (glong major, glong minor)
   return VerifyVersionInfoW (&osverinfo, VER_MAJORVERSION | VER_MINORVERSION, conds);
 }
 
+/* Remove this after XP support dropped, just check whether
+ * we are on Windows 8/Server 2012 or later at that time
+ */
+GdkWin32DwmCapabilities
+_gdk_win32_get_dwm_capabilities (void)
+{
+  static GdkWin32DwmCapabilities capabilities;
+  static gsize capabilities_inited;
+
+  if (g_once_init_enter (&capabilities_inited))
+    {
+      HMODULE dwmdll = LoadLibraryW (L"dwmapi.dll");
+
+      capabilities.is_win8_or_later = _gdk_win32_check_os_version (6, 2);
+
+      capabilities.dwmIsCompositionEnabled =
+        (PFN_DwmIsCompositionEnabled) GetProcAddress (dwmdll, "DwmIsCompositionEnabled");
+      capabilities.dwmEnableComposition =
+        (PFN_DwmEnableComposition) GetProcAddress (dwmdll, "DwmEnableComposition");
+      capabilities.dwmEnableBlurBehindWindow =
+        (PFN_DwmEnableBlurBehindWindow) GetProcAddress (dwmdll, "DwmEnableBlurBehindWindow");
+
+      FreeLibrary (dwmdll);
+
+      g_once_init_leave (&capabilities_inited, 1);
+    }
+  return capabilities;
+}
+
 #ifdef G_ENABLE_DEBUG
 
 /*
diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h
index 9466a97..14e0aa8 100644
--- a/gdk/win32/gdkprivate-win32.h
+++ b/gdk/win32/gdkprivate-win32.h
@@ -511,4 +511,49 @@ void _gdk_input_wintab_init_check (GdkDeviceManager *device_manager);
 /* check OS version info */
 gboolean _gdk_win32_check_os_version (glong major, glong minor);
 
+/* for XP run-time compatibility, remove once XP support dropped */
+#ifndef DWM_BLURBEHIND
+struct _DWM_BLURBEHIND
+{
+  DWORD dwFlags;
+  BOOL fEnable;
+  HRGN hRgnBlur;
+  BOOL fTransitionOnMaximized;
+};
+
+typedef struct _DWM_BLURBEHIND DWM_BLURBEHIND;
+#endif
+
+#ifndef DWM_EC_DISABLECOMPOSITION
+#define DWM_EC_DISABLECOMPOSITION 0
+#endif
+#ifndef DWM_EC_ENABLECOMPOSITION
+#define DWM_EC_ENABLECOMPOSITION 1
+#endif
+
+#ifndef DWM_BB_ENABLE
+#define DWM_BB_ENABLE 0x00000001
+#endif
+
+#ifndef DWM_BB_BLURREGION
+#define DWM_BB_BLURREGION 0x00000002
+#endif
+
+typedef HRESULT (WINAPI *PFN_DwmIsCompositionEnabled) (BOOL *);
+typedef HRESULT (WINAPI *PFN_DwmEnableComposition) (UINT);
+typedef HRESULT (WINAPI *PFN_DwmEnableBlurBehindWindow) (HWND, const DWM_BLURBEHIND *);
+
+typedef struct _GdkWin32DwmCapabilities GdkWin32DwmCapabilities;
+struct _GdkWin32DwmCapabilities
+{
+  PFN_DwmIsCompositionEnabled dwmIsCompositionEnabled;
+  PFN_DwmEnableComposition dwmEnableComposition;
+  PFN_DwmEnableBlurBehindWindow dwmEnableBlurBehindWindow;
+
+  /* only use this when XP support dropped, no more GetProcAddress()'ing */
+  gboolean is_win8_or_later;
+};
+
+GdkWin32DwmCapabilities _gdk_win32_get_dwm_capabilities (void);
+
 #endif /* __GDK_PRIVATE_WIN32_H__ */
diff --git a/gdk/win32/gdkscreen-win32.c b/gdk/win32/gdkscreen-win32.c
index 8c6fb03..a96c79f 100644
--- a/gdk/win32/gdkscreen-win32.c
+++ b/gdk/win32/gdkscreen-win32.c
@@ -195,9 +195,29 @@ gdk_win32_screen_get_window_stack (GdkScreen *screen)
 static gboolean
 gdk_win32_screen_is_composited (GdkScreen *screen)
 {
+  /* XXX: Call DwmIsCompositionEnabled() directly when we drop Windows XP Support */
+  GdkWin32DwmCapabilities capabilities;
+
+  gboolean is_composited;
+
   g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
 
-  return FALSE;
+  capabilities = _gdk_win32_get_dwm_capabilities ();
+
+  /* Windows 8/Server 2012 and later are always composited.
+     Use _gdk_win32_check_os_version (6, 2) when XP support dropped */
+  if (capabilities.is_win8_or_later)
+    return TRUE;
+
+  /* not Windows 8+/Server 2012+, check further
+     DwmIsCompositionEnabled() is only on Vista and later */
+  if (capabilities.dwmIsCompositionEnabled == NULL)
+    return FALSE;
+
+  if (capabilities.dwmIsCompositionEnabled (&is_composited) != S_OK)
+    return FALSE;
+  else
+    return is_composited;
 }
 
 static void
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index 3e568a4..02054f5 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -3363,6 +3363,32 @@ gdk_win32_ref_cairo_surface (GdkWindow *window)
 }
 
 static void
+gdk_win32_window_set_composited (GdkWindow *window,
+                                 gboolean composited)
+{
+  /* XXX: Call DwmEnableComposition() directly when we drop Windows XP Support */
+  GdkWin32DwmCapabilities capabilities = _gdk_win32_get_dwm_capabilities ();
+
+  guint action;
+
+  /* we can't set whether the Window is composited or not on Windows 8+/Server 2012+,
+     as it is always composited.
+     Use _gdk_win32_check_os_version (6, 2) when XP support dropped */
+  if (capabilities.is_win8_or_later)
+    return;
+
+  /* There isn't DWM on XP either, so can't set this as well */
+  if (capabilities.dwmEnableComposition == NULL)
+    return;
+  if (composited)
+    action = DWM_EC_ENABLECOMPOSITION;
+  else
+    action = DWM_EC_DISABLECOMPOSITION;
+
+  capabilities.dwmEnableComposition (action);
+}
+
+static void
 gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -3437,7 +3463,7 @@ gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
   impl_class->begin_resize_drag = gdk_win32_window_begin_resize_drag;
   impl_class->begin_move_drag = gdk_win32_window_begin_move_drag;
   impl_class->set_opacity = gdk_win32_window_set_opacity;
-  //impl_class->set_composited = gdk_win32_window_set_composited;
+  impl_class->set_composited = gdk_win32_window_set_composited;
   impl_class->destroy_notify = gdk_win32_window_destroy_notify;
   impl_class->get_drag_protocol = _gdk_win32_window_get_drag_protocol;
   impl_class->register_dnd = _gdk_win32_window_register_dnd;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]