[PATCH] Implement correct behavior for the DDEDM_REFRESHRATES flag, as the old implementation was not implemented as specified on MSDN. This fixes some older apps which dont like getting flooded with enumerated copies of modes, even though they did not set the DDEDM_REFRESHRATES flag. ATTEMPT #2.

Peter Dons Tychsen (none) donpedro at dhcppc4.
Tue Feb 12 19:02:12 CST 2008


---
 dlls/ddraw/ddraw.c |   61 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index e87043a..b1f4f96 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -1215,6 +1215,8 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
     unsigned int modenum, fmt;
     WINED3DFORMAT pixelformat = WINED3DFMT_UNKNOWN;
     WINED3DDISPLAYMODE mode;
+    WINED3DDISPLAYMODE *prevmodes=NULL;
+    int prevmodecount = 0, prevmodealloc = 0; 
     DDSURFACEDESC2 callback_sd;
 
     WINED3DFORMAT checkFormatList[] =
@@ -1272,17 +1274,60 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
                 if(DDSD->dwFlags & DDSD_WIDTH && mode.Width != DDSD->dwWidth) continue;
                 if(DDSD->dwFlags & DDSD_HEIGHT && mode.Height != DDSD->dwHeight) continue;
             }
-
+            
+            /* Check if this mode is already is enumerated. If it is, then dont enumerate it again,
+               unless the DDEDM_REFRESHRATES flags is set. MSDN specifies this for all ddraw versions.
+               The maximum number of enumerated modes is not specified, so make room for a 100 at a time,
+               and then expand if necessary. */
+            if(!(Flags & DDEDM_REFRESHRATES))
+            {
+                int i;
+                for(i=0; i<prevmodecount; i++)
+                {
+                    if((prevmodes[i].Width == mode.Width) && (prevmodes[i].Height == mode.Height) && (prevmodes[i].Format == mode.Format))
+                    {
+                        break;
+                    }
+                }
+                if(i!=prevmodecount)
+                {
+                    /* Skip this mode, we already have it */
+                    continue;
+                }
+                if(!prevmodes)
+                {
+                    /* Create buffer */
+                    prevmodes = HeapAlloc(GetProcessHeap(), 0, sizeof(WINED3DDISPLAYMODE) * 100);
+                    prevmodealloc = 100;
+                    if(!prevmodes)
+                    {
+                        LeaveCriticalSection(&ddraw_cs);
+                        return DDERR_OUTOFMEMORY;
+                    }
+                }
+                if(prevmodecount == prevmodealloc)
+                {
+                    /* Increase buffer */
+                    WINED3DDISPLAYMODE *newmodes;
+                    prevmodealloc += 100;
+                    newmodes = HeapReAlloc(GetProcessHeap(), 0, prevmodes, prevmodealloc); 
+                    if(!newmodes)
+                    {
+                        LeaveCriticalSection(&ddraw_cs);
+                        HeapFree(GetProcessHeap(), 0, prevmodes);
+                        return DDERR_OUTOFMEMORY;
+                    }
+                    prevmodes = newmodes;
+                }
+                prevmodes[prevmodecount++] = mode;
+            }
+            
             memset(&callback_sd, 0, sizeof(callback_sd));
             callback_sd.dwSize = sizeof(callback_sd);
             callback_sd.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
 
-            callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH;
-            if(Flags & DDEDM_REFRESHRATES)
-            {
-                callback_sd.dwFlags |= DDSD_REFRESHRATE;
-                callback_sd.u2.dwRefreshRate = mode.RefreshRate;
-            }
+            callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_REFRESHRATE;
+            callback_sd.u2.dwRefreshRate = mode.RefreshRate;
 
             callback_sd.dwWidth = mode.Width;
             callback_sd.dwHeight = mode.Height;
@@ -1299,6 +1344,7 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
             if(cb(&callback_sd, Context) == DDENUMRET_CANCEL)
             {
                 TRACE("Application asked to terminate the enumeration\n");
+                HeapFree(GetProcessHeap(), 0, prevmodes);
                 LeaveCriticalSection(&ddraw_cs);
                 return DD_OK;
             }
@@ -1306,6 +1352,7 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
     }
 
     TRACE("End of enumeration\n");
+    HeapFree(GetProcessHeap(), 0, prevmodes);
     LeaveCriticalSection(&ddraw_cs);
     return DD_OK;
 }
-- 
1.5.3.8


--=-NdsLXfaKcwXheyB8iXRU--




More information about the wine-patches mailing list