ddraw: Fix filtering of enumerated display modes

Ričardas Barkauskas rbarkauskas at codeweavers.com
Sun May 8 09:54:54 CDT 2011


---
 dlls/ddraw/ddraw.c            |   26 +++----
 dlls/ddraw/tests/ddrawmodes.c |  165 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 170 insertions(+), 21 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 9b87b95..a4e09b0 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -2070,7 +2070,8 @@ static HRESULT CALLBACK EnumDisplayModesCallbackThunk(DDSURFACEDESC2 *surface_de
  * the DDSD parameter.
  *
  * Params:
- *  Flags: can be DDEDM_REFRESHRATES and DDEDM_STANDARDVGAMODES
+ *  Flags: can be DDEDM_REFRESHRATES and DDEDM_STANDARDVGAMODES. For old ddraw
+ *         versions (3 and older?) this is reserved and must be 0.
  *  DDSD: Surface description to filter the modes
  *  Context: Pointer passed back to the callback function
  *  cb: Application-provided callback function
@@ -2085,11 +2086,11 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags,
 {
     IDirectDrawImpl *This = impl_from_IDirectDraw7(iface);
     unsigned int modenum, fmt;
-    enum wined3d_format_id pixelformat = WINED3DFMT_UNKNOWN;
     WINED3DDISPLAYMODE mode;
     DDSURFACEDESC2 callback_sd;
     WINED3DDISPLAYMODE *enum_modes = NULL;
     unsigned enum_mode_count = 0, enum_mode_array_size = 0;
+    DDPIXELFORMAT pixelformat;
 
     static const enum wined3d_format_id checkFormatList[] =
     {
@@ -2109,12 +2110,6 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags,
         return DDERR_INVALIDPARAMS;
     }
 
-    if(DDSD)
-    {
-        if ((DDSD->dwFlags & DDSD_PIXELFORMAT) && (DDSD->u4.ddpfPixelFormat.dwFlags & DDPF_RGB) )
-            pixelformat = PixelFormat_DD2WineD3D(&DDSD->u4.ddpfPixelFormat);
-    }
-
     if(!(Flags & DDEDM_REFRESHRATES))
     {
         enum_mode_array_size = 16;
@@ -2127,21 +2122,21 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags,
         }
     }
 
+    pixelformat.dwSize = sizeof(pixelformat);
     for(fmt = 0; fmt < (sizeof(checkFormatList) / sizeof(checkFormatList[0])); fmt++)
     {
-        if(pixelformat != WINED3DFMT_UNKNOWN && checkFormatList[fmt] != pixelformat)
-        {
-            continue;
-        }
-
         modenum = 0;
         while (wined3d_enum_adapter_modes(This->wineD3D, WINED3DADAPTER_DEFAULT,
                 checkFormatList[fmt], modenum++, &mode) == WINED3D_OK)
         {
+            PixelFormat_WineD3DtoDD(&pixelformat, mode.Format);
             if(DDSD)
             {
                 if(DDSD->dwFlags & DDSD_WIDTH && mode.Width != DDSD->dwWidth) continue;
                 if(DDSD->dwFlags & DDSD_HEIGHT && mode.Height != DDSD->dwHeight) continue;
+                if(DDSD->dwFlags & DDSD_REFRESHRATE && mode.RefreshRate != DDSD->u2.dwRefreshRate) continue;
+                if (DDSD->dwFlags & DDSD_PIXELFORMAT &&
+                        pixelformat.u1.dwRGBBitCount != DDSD->u4.ddpfPixelFormat.u1.dwRGBBitCount) continue;
             }
 
             if(!(Flags & DDEDM_REFRESHRATES))
@@ -2170,17 +2165,16 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags,
             callback_sd.dwSize = sizeof(callback_sd);
             callback_sd.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
 
-            callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH;
+            callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_REFRESHRATE;
             if(Flags & DDEDM_REFRESHRATES)
             {
-                callback_sd.dwFlags |= DDSD_REFRESHRATE;
                 callback_sd.u2.dwRefreshRate = mode.RefreshRate;
             }
 
             callback_sd.dwWidth = mode.Width;
             callback_sd.dwHeight = mode.Height;
 
-            PixelFormat_WineD3DtoDD(&callback_sd.u4.ddpfPixelFormat, mode.Format);
+            callback_sd.u4.ddpfPixelFormat=pixelformat;
 
             /* Calc pitch and DWORD align like MSDN says */
             callback_sd.u1.lPitch = (callback_sd.u4.ddpfPixelFormat.u1.dwRGBBitCount / 8) * mode.Width;
diff --git a/dlls/ddraw/tests/ddrawmodes.c b/dlls/ddraw/tests/ddrawmodes.c
index a103d65..ae090a2 100644
--- a/dlls/ddraw/tests/ddrawmodes.c
+++ b/dlls/ddraw/tests/ddrawmodes.c
@@ -39,6 +39,9 @@ static int modes_size;
 static LPDDSURFACEDESC modes;
 static RECT rect_before_create;
 static RECT rect_after_delete;
+static int modes16bpp_cnt;
+static int refresh_rate;
+static int refresh_rate_cnt;
 
 static HRESULT (WINAPI *pDirectDrawEnumerateA)(LPDDENUMCALLBACKA,LPVOID);
 static HRESULT (WINAPI *pDirectDrawEnumerateW)(LPDDENUMCALLBACKW,LPVOID);
@@ -344,8 +347,8 @@ static void flushdisplaymodes(void)
 
 static HRESULT WINAPI enummodescallback(LPDDSURFACEDESC lpddsd, LPVOID lpContext)
 {
-    trace("Width = %i, Height = %i, Refresh Rate = %i, Pitch = %i, flags =%02X\n",
-        lpddsd->dwWidth, lpddsd->dwHeight,
+    trace("Width = %i, Height = %i, bpp = %i, Refresh Rate = %i, Pitch = %i, flags =%02X\n",
+        lpddsd->dwWidth, lpddsd->dwHeight, U1(lpddsd->ddpfPixelFormat).dwRGBBitCount,
           U2(*lpddsd).dwRefreshRate, U1(*lpddsd).lPitch, lpddsd->dwFlags);
 
     /* Check that the pitch is valid if applicable */
@@ -365,6 +368,56 @@ static HRESULT WINAPI enummodescallback(LPDDSURFACEDESC lpddsd, LPVOID lpContext
      */
 
     adddisplaymode(lpddsd);
+    if(U1(lpddsd->ddpfPixelFormat).dwRGBBitCount == 16)
+        modes16bpp_cnt++;
+
+    return DDENUMRET_OK;
+}
+
+static HRESULT WINAPI enummodescallback_16bit(LPDDSURFACEDESC lpddsd, LPVOID lpContext)
+{
+    trace("Width = %i, Height = %i, bpp = %i, Refresh Rate = %i, Pitch = %i, flags =%02X\n",
+        lpddsd->dwWidth, lpddsd->dwHeight, U1(lpddsd->ddpfPixelFormat).dwRGBBitCount,
+          U2(*lpddsd).dwRefreshRate, U1(*lpddsd).lPitch, lpddsd->dwFlags);
+
+    ok(lpddsd->dwFlags == (DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_REFRESHRATE),
+            "Wrong surface description flags %02X\n", lpddsd->dwFlags);
+    ok(lpddsd->ddpfPixelFormat.dwFlags == DDPF_RGB, "Wrong pixel format flag %02X\n",
+            lpddsd->ddpfPixelFormat.dwFlags);
+    ok(U1(lpddsd->ddpfPixelFormat).dwRGBBitCount == 16, "Expected 16 bpp got %i\n",
+            U1(lpddsd->ddpfPixelFormat).dwRGBBitCount);
+
+    /* Check that the pitch is valid if applicable */
+    if(lpddsd->dwFlags & DDSD_PITCH)
+    {
+        ok(U1(*lpddsd).lPitch != 0, "EnumDisplayModes callback with bad pitch\n");
+    }
+
+    if(!refresh_rate)
+    {
+        if(U2(*lpddsd).dwRefreshRate )
+        {
+            refresh_rate = U2(*lpddsd).dwRefreshRate;
+            refresh_rate_cnt++;
+        }
+    }
+    else
+    {
+        if(refresh_rate == U2(*lpddsd).dwRefreshRate)
+            refresh_rate_cnt++;
+    }
+
+    modes16bpp_cnt++;
+
+    return DDENUMRET_OK;
+}
+
+static HRESULT WINAPI enummodescallback_count(LPDDSURFACEDESC lpddsd, LPVOID lpContext)
+{
+    ok(lpddsd->dwFlags == (DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_REFRESHRATE),
+            "Wrong surface description flags %02X\n", lpddsd->dwFlags);
+
+    modes16bpp_cnt++;
 
     return DDENUMRET_OK;
 }
@@ -373,15 +426,117 @@ static void enumdisplaymodes(void)
 {
     DDSURFACEDESC ddsd;
     HRESULT rc;
+    int count, refresh_count;
 
     ZeroMemory(&ddsd, sizeof(DDSURFACEDESC));
     ddsd.dwSize = sizeof(DDSURFACEDESC);
     ddsd.dwFlags = DDSD_CAPS;
     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
 
-    rc = IDirectDraw_EnumDisplayModes(lpDD,
-        DDEDM_STANDARDVGAMODES, &ddsd, 0, enummodescallback);
-    ok(rc==DD_OK || rc==E_INVALIDARG,"EnumDisplayModes returned: %x\n",rc);
+    /* Flags parameter is reserved in very old ddraw versions (3 and older?) and must be 0 */
+    rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback);
+    ok(rc==DD_OK, "EnumDisplayModes returned: %x\n",rc);
+
+    count = modes16bpp_cnt;
+
+    modes16bpp_cnt = 0;
+    ddsd.dwFlags = DDSD_PIXELFORMAT;
+    ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
+    U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 16;
+    U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x7C00;
+    U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x03E0;
+    U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x001F;
+
+    rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
+    ok(rc==DD_OK, "EnumDisplayModes returned: %x\n",rc);
+    ok(modes16bpp_cnt == count, "Expected %d modes got %d\n", count, modes16bpp_cnt);
+
+    modes16bpp_cnt = 0;
+    U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x0000;
+    U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000;
+    U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000;
+
+    rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
+    ok(rc==DD_OK, "EnumDisplayModes returned: %x\n",rc);
+    ok(modes16bpp_cnt == count, "Expected %d modes got %d\n", count, modes16bpp_cnt);
+
+    modes16bpp_cnt = 0;
+    U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xF0F0;
+    U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0F00;
+    U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000F;
+
+    rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
+    ok(rc==DD_OK, "EnumDisplayModes returned: %x\n",rc);
+    ok(modes16bpp_cnt == count, "Expected %d modes got %d\n", count, modes16bpp_cnt);
+
+
+    modes16bpp_cnt = 0;
+    ddsd.ddpfPixelFormat.dwFlags = DDPF_YUV;
+
+    rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
+    ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
+    ok(modes16bpp_cnt == count, "Expected %d modes got %d\n", count, modes16bpp_cnt);
+
+    modes16bpp_cnt = 0;
+    ddsd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
+
+    rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
+    ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
+    ok(modes16bpp_cnt == count, "Expected %d modes got %d\n", count, modes16bpp_cnt);
+
+    modes16bpp_cnt = 0;
+    ddsd.dwFlags = DDSD_PIXELFORMAT;
+    ddsd.ddpfPixelFormat.dwFlags = 0;
+
+    rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
+    ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
+    ok(modes16bpp_cnt == count, "Expected %d modes got %d\n", count, modes16bpp_cnt);
+
+    modes16bpp_cnt = 0;
+    ddsd.dwFlags = 0;
+
+    rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_count);
+    ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
+    ok(modes16bpp_cnt == modes_cnt, "Expected %d modes got %d\n", modes_cnt, modes16bpp_cnt);
+
+    modes16bpp_cnt = 0;
+    ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_PITCH;
+    ddsd.lPitch = 123;
+
+    rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
+    ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
+    ok(modes16bpp_cnt == count, "Expected %d modes got %d\n", count, modes16bpp_cnt);
+
+    modes16bpp_cnt = 0;
+    ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_REFRESHRATE;
+    ddsd.dwRefreshRate = 1;
+
+    rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
+    ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
+    ok(modes16bpp_cnt == 0, "Expected 0 modes got %d\n", modes16bpp_cnt);
+
+    modes16bpp_cnt = 0;
+    ddsd.dwFlags = DDSD_PIXELFORMAT;
+
+    rc = IDirectDraw_EnumDisplayModes(lpDD, DDEDM_REFRESHRATES, &ddsd, 0, enummodescallback_16bit);
+    if(rc == DDERR_INVALIDPARAMS)
+    {
+        skip("Ddraw version too old. Skipping.\n");
+        return;
+    }
+    ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
+    refresh_count = refresh_rate_cnt;
+
+    if(refresh_rate)
+    {
+        modes16bpp_cnt = 0;
+        ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_REFRESHRATE;
+        ddsd.dwRefreshRate = refresh_rate;
+
+        rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
+        ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
+        ok(modes16bpp_cnt == refresh_count, "Expected %d modes got %d\n", refresh_count, modes16bpp_cnt);
+    }
 }
 
 static void setdisplaymode(int i)
-- 
1.7.5.1

------=_20110512085508_73188--





More information about the wine-patches mailing list