From c0cf16f0ef5dc84d17c62a6a6fdd60853d7b48e9 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
Date: Mon, 2 Mar 2015 23:18:10 -0700
Subject: winex11: Display a helpful warning when Dynamic TwinView is enabled.

---
 configure.ac              | 22 +++++++++++++++++++++-
 dlls/winex11.drv/xrandr.c | 22 ++++++++++++++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index f242181..27e0fdc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -86,6 +86,8 @@ AC_ARG_WITH(xinput,    AS_HELP_STRING([--without-xinput],[do not use the Xinput
 AC_ARG_WITH(xinput2,   AS_HELP_STRING([--without-xinput2],[do not use the Xinput 2 extension]),
             [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_XInput2_h=no; fi])
 AC_ARG_WITH(xml,       AS_HELP_STRING([--without-xml],[do not use XML]))
+AC_ARG_WITH(xnvctrl,   AS_HELP_STRING([--without-xnvctrl],[do not use the NV-CONTROL extension]),
+            [if test "x$withval" = "xno"; then ac_cv_header_NVCtrl_NVCtrlLib_h=no; fi])
 AC_ARG_WITH(xrandr,    AS_HELP_STRING([--without-xrandr],[do not use Xrandr (resolution changes)]),
             [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xrandr_h=no; fi])
 AC_ARG_WITH(xrender,   AS_HELP_STRING([--without-xrender],[do not use the Xrender extension]),
@@ -1108,7 +1110,8 @@ then
                       X11/extensions/Xrandr.h \
                       X11/extensions/Xrender.h \
                       X11/extensions/xf86vmode.h \
-                      X11/extensions/xf86vmproto.h],,,
+                      X11/extensions/xf86vmproto.h \
+                      NVCtrl/NVCtrlLib.h],,,
 [#ifdef HAVE_X11_XLIB_H
 # include <X11/Xlib.h>
 #endif
@@ -1225,6 +1228,23 @@ then
 #include <X11/Xlib.h>
 #endif])
 
+        dnl *** Check for NV-CONTROL extension
+        if test "$ac_cv_header_NVCtrl_NVCtrlLib_h" = "yes"
+        then
+            AC_MSG_CHECKING([for -lXNVCtrl])
+            ac_save_LIBS="$LIBS"
+            LIBS="-lXNVCtrl $X_LIBS $X_EXTRA_LIBS $LIBS"
+            AC_LINK_IFELSE([AC_LANG_CALL([], [XNVCTRLIsNvScreen])],
+                           [AC_MSG_RESULT([yes])
+                            X_EXTRA_LIBS="$X_EXTRA_LIBS -lXNVCtrl"
+                            AC_DEFINE_UNQUOTED(HAVE_NVCTRL,1,[Define to 1 if libXNVCtrl is available])],
+                           [AC_MSG_RESULT([no])
+                            ac_cv_header_NVCtrl_NVCtrlLib_h=no])
+            LIBS="$ac_save_LIBS"
+        fi
+        WINE_NOTICE_WITH(xnvctrl,[test "x$ac_cv_header_NVCtrl_NVCtrlLib_h" != xyes],
+                         [XNVCtrl ${notice_platform}development files not found, the NV-CONTROL extension won't be supported.])
+
     dnl *** End of X11/Xlib.h check
 
     dnl Check for the presence of OpenGL
diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c
index 58e66d6..e7fbf91 100644
--- a/dlls/winex11.drv/xrandr.c
+++ b/dlls/winex11.drv/xrandr.c
@@ -32,6 +32,9 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
 
 #include <X11/Xlib.h>
 #include <X11/extensions/Xrandr.h>
+#ifdef HAVE_NVCTRL_NVCTRLLIB_H
+# include <NVCtrl/NVCtrlLib.h>
+#endif
 #include "x11drv.h"
 
 #include "wine/library.h"
@@ -192,6 +195,22 @@ static LONG xrandr10_set_current_mode( int mode )
     return DISP_CHANGE_FAILED;
 }
 
+static void xrandr10_nvidia_rate(void)
+{
+#ifdef HAVE_NVCTRL
+    int major, minor, twinview;
+
+    if (!XNVCTRLIsNvScreen( gdi_display, DefaultScreen(gdi_display) )) return;
+    if (!XNVCTRLQueryVersion( gdi_display, &major, &minor )) return;
+    if (!XNVCTRLQueryAttribute( gdi_display, DefaultScreen(gdi_display), 0,
+                                NV_CTRL_DYNAMIC_TWINVIEW, &twinview )) return;
+    if (!twinview) return;
+
+    ERR_(winediag)("NVIDIA Dynamic TwinView detected, XRandR will report inaccurate refresh rates. "
+                   "Please consider disabling the \"DynamicTwinView\" option in your X config.\n");
+#endif
+}
+
 static void xrandr10_init_modes(void)
 {
     XRRScreenSize *sizes;
@@ -201,6 +220,9 @@ static void xrandr10_init_modes(void)
     sizes = pXRRSizes( gdi_display, DefaultScreen(gdi_display), &sizes_count );
     if (sizes_count <= 0) return;
 
+    /* Output a warning about nVidia Dynamic TwinView (if applicable) */
+    xrandr10_nvidia_rate();
+
     TRACE("XRandR: found %d sizes.\n", sizes_count);
     for (i = 0; i < sizes_count; ++i)
     {
-- 
2.3.0

