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



commit 8edfc14ea30ea5c2852a245274c769536906647e
Author: Chun-wei Fan <fanchunwei src gnome org>
Date:   Tue Dec 23 16:20:25 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 it 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 FALSE on XP.  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    |   36 ++++++++++++++++++++++++++++++++++++
 gdk/win32/gdkprivate-win32.h |   42 ++++++++++++++++++++++++++++++++++++++++++
 gdk/win32/gdkscreen-win32.c  |   22 +++++++++++++++++++++-
 gdk/win32/gdkwindow-win32.c  |   28 +++++++++++++++++++++++++++-
 4 files changed, 126 insertions(+), 2 deletions(-)
---
diff --git a/gdk/win32/gdkmain-win32.c b/gdk/win32/gdkmain-win32.c
index 905c729..e97f5f4 100644
--- a/gdk/win32/gdkmain-win32.c
+++ b/gdk/win32/gdkmain-win32.c
@@ -150,6 +150,42 @@ _gdk_other_api_failed (const gchar *where,
   g_warning ("%s: %s failed", where, api);
 }
 
+/* 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 = g_win32_windows_is_at_least (6, 2, 0, G_WIN32_OS_ANY);
+      if (dwmdll == NULL)
+        {
+          capabilities.dwmIsCompositionEnabled = NULL;
+          capabilities.dwmEnableComposition = NULL;
+          capabilities.dwmEnableBlurBehindWindow = NULL;
+        }
+      else
+        {
+          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 acc3fca..f5c2add 100644
--- a/gdk/win32/gdkprivate-win32.h
+++ b/gdk/win32/gdkprivate-win32.h
@@ -508,4 +508,46 @@ void _gdk_events_init (void);
 void _gdk_input_init  (GdkDisplay *display);
 void _gdk_input_wintab_init_check (GdkDeviceManager *device_manager);
 
+/* for XP run-time compatibility, remove once XP support dropped */
+#ifndef DWM_BLURBEHIND
+typedef struct
+{
+  DWORD dwFlags;
+  BOOL fEnable;
+  HRGN hRgnBlur;
+  BOOL fTransitionOnMaximized;
+} 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
+{
+  PFN_DwmIsCompositionEnabled dwmIsCompositionEnabled;
+  PFN_DwmEnableComposition dwmEnableComposition;
+  PFN_DwmEnableBlurBehindWindow dwmEnableBlurBehindWindow;
+
+  /* Only check whether we are on Windows 8 or Server 2012 or later after dropping XP support */
+  gboolean is_win8_or_later;
+} GdkWin32DwmCapabilities;
+
+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..fed661e 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 g_win32_windows_is_at_least (6, 2, 0, G_WIN32_OS_ANY) 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;
+
+  return is_composited;
 }
 
 static void
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index 3e568a4..9599bcd 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 g_win32_windows_is_at_least (6, 2, 0, G_WIN32_OS_ANY) 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]