From 887ed87355ba8d531cb1bdefe19b4451d083ed8d Mon Sep 17 00:00:00 2001
From: David Adam <david.adam.cnrs@gmail.com>
Date: Tue, 24 Aug 2010 20:35:32 +0200
Subject: SetCooperativeLevel with Full screen + exclusive + normal is authorized

---
 dlls/ddraw/ddraw.c            |    8 +-
 dlls/ddraw/tests/ddrawmodes.c |  158 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 159 insertions(+), 7 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index af5eb37..3aa05bc 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -621,13 +621,13 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND hwnd,
             This->devicewindow = NULL;
         }
     }
-    /* DDSCL_NORMAL or DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE */
+    /* DDSCL_NORMAL */
     if(cooplevel & DDSCL_NORMAL)
     {
-        /* Can't coexist with fullscreen or exclusive */
-        if(cooplevel & (DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE) )
+        /* Can't coexist with  exclusive only*/
+        if(cooplevel == (DDSCL_NORMAL | DDSCL_EXCLUSIVE) )
         {
-            TRACE("(%p) DDSCL_NORMAL is not compative with DDSCL_FULLSCREEN or DDSCL_EXCLUSIVE\n", This);
+            TRACE("(%p) DDSCL_NORMAL is not compative with DDSCL_EXCLUSIVE only \n", This);
             LeaveCriticalSection(&ddraw_cs);
             return DDERR_INVALIDPARAMS;
         }
diff --git a/dlls/ddraw/tests/ddrawmodes.c b/dlls/ddraw/tests/ddrawmodes.c
index 8235d86..cbe46b5 100644
--- a/dlls/ddraw/tests/ddrawmodes.c
+++ b/dlls/ddraw/tests/ddrawmodes.c
@@ -558,11 +558,46 @@ static void testcooperativelevels_normal(void)
     surfacedesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
 
     /* Do some tests with DDSCL_NORMAL mode */
-
+    
+    /* Fullscreen mode + normal mode + exclusive mode */
+    rc = IDirectDraw_SetCooperativeLevel(lpDD,
+        hwnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_NORMAL);
+    ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_NORMAL) returned: %x\n",rc);
+    /* Try creating a double buffered primary in fullscreen + exclusive + normal mode */
+    rc = IDirectDraw_CreateSurface(lpDD, &surfacedesc, &surface, NULL);
+    if (rc == DDERR_UNSUPPORTEDMODE)
+        skip("Unsupported mode\n");
+    else
+    {
+        ok(rc == DD_OK, "IDirectDraw_CreateSurface returned %08x\n", rc);
+        ok(surface!=NULL, "Returned NULL surface pointer \n");
+    }
+    if(surface && surface != (IDirectDrawSurface *)0xdeadbeef) IDirectDrawSurface_Release(surface);
+    
+    /* Exclusive mode + normal mode */
+    rc = IDirectDraw_SetCooperativeLevel(lpDD,
+        hwnd, DDSCL_EXCLUSIVE | DDSCL_NORMAL);
+    ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_EXCLUSIVE | DDSCL_NORMAL) returned: %x\n",rc);
+        
+    /* Fullscreen mode + normal mode */
+    rc = IDirectDraw_SetCooperativeLevel(lpDD,
+        hwnd, DDSCL_FULLSCREEN | DDSCL_NORMAL);
+    ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_FULLSCREEN | DDSCL_NORMAL) returned: %x\n",rc);  
+    /* Try creating a double buffered primary in fullscreen + normal mode */
+    rc = IDirectDraw_CreateSurface(lpDD, &surfacedesc, &surface, NULL);
+    if (rc == DDERR_UNSUPPORTEDMODE)
+        skip("Unsupported mode\n");
+    else
+    {
+        ok(rc == DDERR_NOEXCLUSIVEMODE, "IDirectDraw_CreateSurface returned %08x\n", rc);
+        ok(surface == NULL, "Returned surface pointer is %p\n", surface);
+    }
+    if(surface && surface != (IDirectDrawSurface *)0xdeadbeef) IDirectDrawSurface_Release(surface);
+    
+    /* Normal mode */
     rc = IDirectDraw_SetCooperativeLevel(lpDD,
         hwnd, DDSCL_NORMAL);
     ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_NORMAL) returned: %x\n",rc);
-
     /* Try creating a double buffered primary in normal mode */
     rc = IDirectDraw_CreateSurface(lpDD, &surfacedesc, &surface, NULL);
     if (rc == DDERR_UNSUPPORTEDMODE)
@@ -664,7 +699,7 @@ static void testcooperativelevels_exclusive(void)
     rc = IDirectDraw_SetCooperativeLevel(lpDD,
         hwnd, DDSCL_FULLSCREEN);
     ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_FULLSCREEN) returned: %x\n",rc);
-
+  
     /* Full screen mode + exclusive mode */
     rc = IDirectDraw_SetCooperativeLevel(lpDD,
         hwnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);
@@ -684,6 +719,122 @@ static void testcooperativelevels_exclusive(void)
     /* All done */
 }
 
+static void testcooperativelevels_normal_other_ddraw(void)
+{
+    HRESULT hr, rc;
+    DDSURFACEDESC surfacedesc;
+    IDirectDraw7 *dd2;
+    IDirectDraw7 *dd7;
+    IDirectDrawSurface *surface = (IDirectDrawSurface *) 0xdeadbeef;
+
+    memset(&surfacedesc, 0, sizeof(surfacedesc));
+    surfacedesc.dwSize = sizeof(surfacedesc);
+    surfacedesc.ddpfPixelFormat.dwSize = sizeof(surfacedesc.ddpfPixelFormat);
+    surfacedesc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
+    surfacedesc.dwBackBufferCount = 1;
+    surfacedesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
+    
+    hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
+    if (hr==E_NOINTERFACE)
+    {
+        win_skip("DirectDraw7 is not supported\n");
+        return;
+    }
+    ok(hr==DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
+    
+    if (hr==DD_OK)
+    {  
+        /* Do some tests with DDSCL_NORMAL mode */
+    
+        /* Fullscreen mode + normal mode + exclusive mode */
+        rc = IDirectDraw_SetCooperativeLevel(lpDD,
+            hwnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_NORMAL);
+        ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_NORMAL) returned: %x\n",rc);
+        /* Try creating a double buffered primary in fullscreen + exclusive + normal mode */
+        rc = IDirectDraw_CreateSurface(lpDD, &surfacedesc, &surface, NULL);
+        if (rc == DDERR_UNSUPPORTEDMODE)
+            skip("Unsupported mode\n");
+        else
+        {
+            ok(rc == DD_OK, "IDirectDraw_CreateSurface returned %08x\n", rc);
+            ok(surface!=NULL, "Returned NULL surface pointer \n");
+        }
+        if(surface && surface != (IDirectDrawSurface *)0xdeadbeef) IDirectDrawSurface_Release(surface);
+    
+        /* Exclusive mode + normal mode */
+        rc = IDirectDraw_SetCooperativeLevel(lpDD,
+            hwnd, DDSCL_EXCLUSIVE | DDSCL_NORMAL);
+        ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_EXCLUSIVE | DDSCL_NORMAL) returned: %x\n",rc);
+        
+        /* Fullscreen mode + normal mode */
+        rc = IDirectDraw_SetCooperativeLevel(lpDD,
+            hwnd, DDSCL_FULLSCREEN | DDSCL_NORMAL);
+        ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_FULLSCREEN | DDSCL_NORMAL) returned: %x\n",rc);  
+        /* Try creating a double buffered primary in fullscreen + normal mode */
+        rc = IDirectDraw_CreateSurface(lpDD, &surfacedesc, &surface, NULL);
+        if (rc == DDERR_UNSUPPORTEDMODE)
+            skip("Unsupported mode\n");
+        else
+        {
+            ok(rc == DDERR_NOEXCLUSIVEMODE, "IDirectDraw_CreateSurface returned %08x\n", rc);
+            ok(surface == NULL, "Returned surface pointer is %p\n", surface);
+        }
+        if(surface && surface != (IDirectDrawSurface *)0xdeadbeef)  IDirectDrawSurface_Release(surface);
+    }
+    
+    IDirectDraw_Release(dd7);
+    
+    hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
+    if (hr==E_NOINTERFACE)
+    {
+        win_skip("DirectDraw2 is not supported\n");
+        return;
+    }
+    ok(hr==DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
+    
+    if (hr==DD_OK)
+    {  
+        /* Do some tests with DDSCL_NORMAL mode */
+    
+        /* Fullscreen mode + normal mode + exclusive mode */
+        rc = IDirectDraw_SetCooperativeLevel(lpDD,
+            hwnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_NORMAL);
+        ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_NORMAL) returned: %x\n",rc);
+        /* Try creating a double buffered primary in fullscreen + exclusive + normal mode */
+        rc = IDirectDraw_CreateSurface(lpDD, &surfacedesc, &surface, NULL);
+        if (rc == DDERR_UNSUPPORTEDMODE)
+            skip("Unsupported mode\n");
+        else
+        {
+            ok(rc == DD_OK, "IDirectDraw_CreateSurface returned %08x\n", rc);
+            ok(surface!=NULL, "Returned NULL surface pointer \n");
+        }
+        if(surface && surface != (IDirectDrawSurface *)0xdeadbeef) IDirectDrawSurface_Release(surface);
+    
+        /* Exclusive mode + normal mode */
+        rc = IDirectDraw_SetCooperativeLevel(lpDD,
+            hwnd, DDSCL_EXCLUSIVE | DDSCL_NORMAL);
+        ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_EXCLUSIVE | DDSCL_NORMAL) returned: %x\n",rc);
+        
+        /* Fullscreen mode + normal mode */
+        rc = IDirectDraw_SetCooperativeLevel(lpDD,
+            hwnd, DDSCL_FULLSCREEN | DDSCL_NORMAL);
+        ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_FULLSCREEN | DDSCL_NORMAL) returned: %x\n",rc);  
+        /* Try creating a double buffered primary in fullscreen + normal mode */
+        rc = IDirectDraw_CreateSurface(lpDD, &surfacedesc, &surface, NULL);
+        if (rc == DDERR_UNSUPPORTEDMODE)
+            skip("Unsupported mode\n");
+        else
+        {
+            ok(rc == DDERR_NOEXCLUSIVEMODE, "IDirectDraw_CreateSurface returned %08x\n", rc);
+            ok(surface == NULL, "Returned surface pointer is %p\n", surface);
+        }
+        if(surface && surface != (IDirectDrawSurface *)0xdeadbeef)  IDirectDrawSurface_Release(surface);
+    }
+    
+    IDirectDraw_Release(dd2);
+}
+
 static void testddraw3(void)
 {
     const GUID My_IID_IDirectDraw3 = {
@@ -766,6 +917,7 @@ START_TEST(ddrawmodes)
 
     createdirectdraw();
     testcooperativelevels_normal();
+    testcooperativelevels_normal_other_ddraw();
     releasedirectdraw();
 
     createdirectdraw();
-- 
1.7.1

