From 599864f0a90e7bf64902dbd7ff135f253d270802 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 5 Nov 2015 14:33:48 +0100
Subject: winex11.drv: Allow to select default display frequency in registry
 key.

When an application doesn't request a specific display frequency, Wine
currently just picks the first one. Most of the time this is fine, but
there is no way to switch to a different frequency. This patch adds a
registry key (of type STRING) to select the default display frequency:

HKCU\Software\Wine\X11 Driver\DefaultDisplayFrequency
---
 dlls/winex11.drv/settings.c    | 58 ++++++++++++++++++++++------------
 dlls/winex11.drv/x11drv.h      |  1 +
 dlls/winex11.drv/x11drv_main.c |  4 +++
 3 files changed, 43 insertions(+), 20 deletions(-)

diff --git a/dlls/winex11.drv/settings.c b/dlls/winex11.drv/settings.c
index 24644db62..4fac4beb6 100644
--- a/dlls/winex11.drv/settings.c
+++ b/dlls/winex11.drv/settings.c
@@ -319,8 +319,9 @@ LONG CDECL X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode,
                                            HWND hwnd, DWORD flags, LPVOID lpvoid )
 {
     char bpp_buffer[16], freq_buffer[18];
-    DWORD i;
+    DWORD i, mode;
 
+    mode = ENUM_CURRENT_SETTINGS;
     for (i = 0; i < dd_mode_count; i++)
     {
         if (devmode->dmFields & DM_BITSPERPEL)
@@ -338,32 +339,49 @@ LONG CDECL X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode,
             if (devmode->dmPelsHeight != dd_modes[i].height)
                 continue;
         }
-        if ((devmode->dmFields & DM_DISPLAYFREQUENCY) && (dd_modes[i].refresh_rate != 0) &&
+        if ((devmode->dmFields & DM_DISPLAYFREQUENCY) &&
             devmode->dmDisplayFrequency != 0)
         {
-            if (devmode->dmDisplayFrequency != dd_modes[i].refresh_rate)
+            if (dd_modes[i].refresh_rate != 0 &&
+                devmode->dmDisplayFrequency != dd_modes[i].refresh_rate)
                 continue;
         }
-        /* we have a valid mode */
-        TRACE("Requested display settings match mode %d (%s)\n", i, handler_name);
-
-        if (flags & CDS_UPDATEREGISTRY)
-            write_registry_settings(devmode);
+        else if (default_display_frequency != 0)
+        {
+            if (dd_modes[i].refresh_rate != 0 &&
+                default_display_frequency == dd_modes[i].refresh_rate)
+            {
+                TRACE("Found display mode %d with default frequency (%s)\n", i, handler_name);
+                mode = i;
+                break;
+            }
+        }
 
-        if (!(flags & (CDS_TEST | CDS_NORESET)))
-            return pSetCurrentMode(i);
+        if (mode == ENUM_CURRENT_SETTINGS)
+            mode = i;
+    }
 
-        return DISP_CHANGE_SUCCESSFUL;
+    if (mode == ENUM_CURRENT_SETTINGS)
+    {
+        /* no valid modes found, only print the fields we were trying to matching against */
+        bpp_buffer[0] = freq_buffer[0] = 0;
+        if (devmode->dmFields & DM_BITSPERPEL)
+            sprintf(bpp_buffer, "bpp=%u ",  devmode->dmBitsPerPel);
+        if ((devmode->dmFields & DM_DISPLAYFREQUENCY) && (devmode->dmDisplayFrequency != 0))
+            sprintf(freq_buffer, "freq=%u ", devmode->dmDisplayFrequency);
+        ERR("No matching mode found: width=%d height=%d %s%s(%s)\n",
+            devmode->dmPelsWidth, devmode->dmPelsHeight, bpp_buffer, freq_buffer, handler_name);
+        return DISP_CHANGE_BADMODE;
     }
 
-    /* no valid modes found, only print the fields we were trying to matching against */
-    bpp_buffer[0] = freq_buffer[0] = 0;
-    if (devmode->dmFields & DM_BITSPERPEL)
-        sprintf(bpp_buffer, "bpp=%u ",  devmode->dmBitsPerPel);
-    if ((devmode->dmFields & DM_DISPLAYFREQUENCY) && (devmode->dmDisplayFrequency != 0))
-        sprintf(freq_buffer, "freq=%u ", devmode->dmDisplayFrequency);
-    ERR("No matching mode found: width=%d height=%d %s%s(%s)\n",
-        devmode->dmPelsWidth, devmode->dmPelsHeight, bpp_buffer, freq_buffer, handler_name);
+    /* we have a valid mode */
+    TRACE("Requested display settings match mode %d (%s)\n", mode, handler_name);
+
+    if (flags & CDS_UPDATEREGISTRY)
+        write_registry_settings(devmode);
+
+    if (!(flags & (CDS_TEST | CDS_NORESET)))
+        return pSetCurrentMode(mode);
 
-    return DISP_CHANGE_BADMODE;
+    return DISP_CHANGE_SUCCESSFUL;
 }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 98cab8947..9f76596e4 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -404,6 +404,7 @@ extern BOOL private_color_map DECLSPEC_HIDDEN;
 extern int primary_monitor DECLSPEC_HIDDEN;
 extern int copy_default_colors DECLSPEC_HIDDEN;
 extern int alloc_system_colors DECLSPEC_HIDDEN;
+extern int default_display_frequency DECLSPEC_HIDDEN;
 extern int xrender_error_base DECLSPEC_HIDDEN;
 extern HMODULE x11drv_module DECLSPEC_HIDDEN;
 extern char *process_name DECLSPEC_HIDDEN;
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 4f611f5fa..981bcc6fb 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -86,6 +86,7 @@ BOOL client_side_with_render = TRUE;
 BOOL shape_layered_windows = TRUE;
 int copy_default_colors = 128;
 int alloc_system_colors = 256;
+int default_display_frequency = 0;
 DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
 int xrender_error_base = 0;
 HMODULE x11drv_module = 0;
@@ -436,6 +437,9 @@ static void setup_options(void)
     if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
         alloc_system_colors = atoi(buffer);
 
+    if (!get_config_key( hkey, appkey, "DefaultDisplayFrequency", buffer, sizeof(buffer) ))
+        default_display_frequency = atoi(buffer);
+
     get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
 
     if (appkey) RegCloseKey( appkey );
-- 
2.25.0