From 7661e8986c7bed0a6735f04d6be660cf0f6a7ed0 Mon Sep 17 00:00:00 2001 From: David Adam Date: Wed, 3 Nov 2010 07:10:54 +0100 Subject: [PATCH] ddraw: Exclusive mode is the corner case for SetCooperative, not the normal mode. --- dlls/ddraw/ddraw.c | 92 +++++++++++------------------------ dlls/ddraw/tests/ddrawmodes.c | 18 +++---- 2 files changed, 38 insertions(+), 72 deletions(-) diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index fd870711d19..20f743f784c 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -602,7 +602,7 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND hwnd, return DDERR_INVALIDPARAMS; } - if( (This->cooperative_level & DDSCL_FULLSCREEN) && window ) + if( (This->cooperative_level & DDSCL_EXCLUSIVE) && window ) { TRACE("Setting DDSCL_SETFOCUSWINDOW with an already set window, returning DDERR_HWNDALREADYSET\n"); LeaveCriticalSection(&ddraw_cs); @@ -626,76 +626,42 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND hwnd, LeaveCriticalSection(&ddraw_cs); return DD_OK; } - /* DDSCL_NORMAL or DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE */ - if(cooplevel & DDSCL_NORMAL) + + if(cooplevel & DDSCL_EXCLUSIVE) { - /* Can't coexist with fullscreen or exclusive */ - if(cooplevel & (DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE) ) + if( !(cooplevel & DDSCL_FULLSCREEN) || !hwnd ) { - TRACE("(%p) DDSCL_NORMAL is not compative with DDSCL_FULLSCREEN or DDSCL_EXCLUSIVE\n", This); + TRACE("(%p) DDSCL_EXCLUSIVE needs DDSCL_FULLSCREEN and a window\n", This); LeaveCriticalSection(&ddraw_cs); return DDERR_INVALIDPARAMS; } - - /* Switching from fullscreen? */ - if(This->cooperative_level & DDSCL_FULLSCREEN) - { - This->cooperative_level &= ~DDSCL_FULLSCREEN; - This->cooperative_level &= ~DDSCL_EXCLUSIVE; - This->cooperative_level &= ~DDSCL_ALLOWMODEX; - - IWineD3DDevice_ReleaseFocusWindow(This->wineD3DDevice); - } - - /* Don't override focus windows or private device windows */ - if( hwnd && - !(This->focuswindow) && - !(This->devicewindow) && - (hwnd != window) ) - { - This->dest_window = hwnd; - } } - else if(cooplevel & DDSCL_FULLSCREEN) + else if( !(cooplevel & DDSCL_NORMAL) ) { - /* Needs DDSCL_EXCLUSIVE */ - if(!(cooplevel & DDSCL_EXCLUSIVE) ) - { - TRACE("(%p) DDSCL_FULLSCREEN needs DDSCL_EXCLUSIVE\n", This); - LeaveCriticalSection(&ddraw_cs); - return DDERR_INVALIDPARAMS; - } - /* Need a HWND - if(hwnd == 0) - { - TRACE("(%p) DDSCL_FULLSCREEN needs a HWND\n", This); - return DDERR_INVALIDPARAMS; - } - */ - - This->cooperative_level &= ~DDSCL_NORMAL; - - /* Don't override focus windows or private device windows */ - if( hwnd && - !(This->focuswindow) && - !(This->devicewindow) && - (hwnd != window) ) - { - HRESULT hr = IWineD3DDevice_AcquireFocusWindow(This->wineD3DDevice, hwnd); - if (FAILED(hr)) - { - ERR("Failed to acquire focus window, hr %#x.\n", hr); - LeaveCriticalSection(&ddraw_cs); - return hr; - } - This->dest_window = hwnd; - } - } - else if(cooplevel & DDSCL_EXCLUSIVE) - { - TRACE("(%p) DDSCL_EXCLUSIVE needs DDSCL_FULLSCREEN\n", This); + TRACE("(%p) SetCooperativeLevel needs at least SetFocusWindow or Exclusive or Normal mode\n", This); LeaveCriticalSection(&ddraw_cs); return DDERR_INVALIDPARAMS; + } + + /* Do we switch from fullscreen to non-fullscreen ? */ + + if( !(cooplevel & DDSCL_FULLSCREEN) && (This->cooperative_level & DDSCL_FULLSCREEN) ) + IWineD3DDevice_ReleaseFocusWindow(This->wineD3DDevice); + + /* Don't override focus windows or private device windows */ + if( hwnd && !This->focuswindow && !This->devicewindow && (hwnd != window)) + { + if( cooplevel & DDSCL_FULLSCREEN ) + { + HRESULT hr = IWineD3DDevice_AcquireFocusWindow(This->wineD3DDevice, hwnd); + if (FAILED(hr)) + { + ERR("Failed to acquire focus window, hr %#x.\n", hr); + LeaveCriticalSection(&ddraw_cs); + return hr; + } + } + This->dest_window = hwnd; } if(cooplevel & DDSCL_CREATEDEVICEWINDOW) @@ -736,7 +702,7 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND hwnd, WARN("(%p) Unhandled flag DDSCL_FPUSETUP, harmless\n", This); /* Store the cooperative_level */ - This->cooperative_level |= cooplevel; + This->cooperative_level = cooplevel; TRACE("SetCooperativeLevel retuning DD_OK\n"); LeaveCriticalSection(&ddraw_cs); return DD_OK; diff --git a/dlls/ddraw/tests/ddrawmodes.c b/dlls/ddraw/tests/ddrawmodes.c index b0b84d862fe..0ced9dac886 100644 --- a/dlls/ddraw/tests/ddrawmodes.c +++ b/dlls/ddraw/tests/ddrawmodes.c @@ -565,10 +565,10 @@ static void testcooperativelevels_normal(void) skip("Failed to create the second window\n"); rc = IDirectDraw_SetCooperativeLevel(lpDD, hwnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_NORMAL); - todo_wine ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_NORMAL) returned: %x\n",rc); + ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_NORMAL) returned: %x\n",rc); if(sfw) - todo_wine ok(GetForegroundWindow()==hwnd,"Expected the main windows (%p) for foreground, received the second one (%p)\n",hwnd, hwnd2); + ok(GetForegroundWindow()==hwnd,"Expected the main windows (%p) for foreground, received the second one (%p)\n",hwnd, hwnd2); /* Try creating a double buffered primary in fullscreen + exclusive + normal mode */ rc = IDirectDraw_CreateSurface(lpDD, &surfacedesc, &surface, NULL); @@ -577,8 +577,8 @@ static void testcooperativelevels_normal(void) skip("Unsupported mode\n"); else { - todo_wine ok(rc == DD_OK, "IDirectDraw_CreateSurface returned %08x\n", rc); - todo_wine ok(surface!=NULL, "Returned NULL surface pointer\n"); + 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); @@ -592,13 +592,13 @@ static void testcooperativelevels_normal(void) if(hwnd2) sfw=SetForegroundWindow(hwnd2); rc = IDirectDraw_SetCooperativeLevel(lpDD, hwnd, DDSCL_FULLSCREEN | DDSCL_NORMAL); - todo_wine ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_FULLSCREEN | DDSCL_NORMAL) returned: %x\n",rc); + ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_FULLSCREEN | DDSCL_NORMAL) returned: %x\n",rc); if(sfw) ok(GetForegroundWindow()==hwnd2,"Expected the second windows (%p) for foreground, received the main one (%p)\n",hwnd2, hwnd); rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_FULLSCREEN | DDSCL_NORMAL); - todo_wine ok(rc==DD_OK, "Expected DD_OK, received %x\n", rc); + ok(rc==DD_OK, "Expected DD_OK, received %x\n", rc); /* Try creating a double buffered primary in fullscreen + normal mode */ rc = IDirectDraw_CreateSurface(lpDD, &surfacedesc, &surface, NULL); @@ -645,13 +645,13 @@ static void testcooperativelevels_normal(void) rc = IDirectDraw_SetCooperativeLevel(lpDD, hwnd, DDSCL_NORMAL | DDSCL_FULLSCREEN); - todo_wine ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_NORMAL | FULLSCREEN) returned: %x\n",rc); + ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_NORMAL | FULLSCREEN) returned: %x\n",rc); if(sfw) ok(GetForegroundWindow()==hwnd2,"Expected the second windows (%p) for foreground, received the main one (%p)\n",hwnd2, hwnd); rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL | DDSCL_FULLSCREEN); - todo_wine ok(rc==DD_OK, "Expected DD_OK, received %x\n", rc); + ok(rc==DD_OK, "Expected DD_OK, received %x\n", rc); /* Set the focus window */ @@ -761,7 +761,7 @@ static void testcooperativelevels_exclusive(void) /* Full screen mode + exclusive mode */ rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE); - todo_wine ok(rc==DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, received %x\n", rc); + ok(rc==DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, received %x\n", rc); sfw=FALSE; if(hwnd2)