Help with a patch needed
Oliver Stieber
oliver_stieber at yahoo.co.uk
Wed Sep 7 19:05:30 CDT 2005
--- Stefan Dösinger <stefandoesinger at gmx.at> wrote:
> Hi,
> I've sent the following patch to wine-patches approximatly 2 weeks ago, and it
> wasn't applied nor any suggestions for improvement where given. As suggested
> by some people in another thread, I send it to wine-devel to ask for help.
>
> This patch adds handling for the DDSCL_SETFOCUSWINDOW flag in
> DirectDraw7::SetCooperativeLevel. It also adds some tests which test the
> reactions of Windows to these flag.
>
> I've stumbled across the DDSCL_SETFOCUSWINDOW flag while debugging Empire
> Earth. This game cancels with msvcrt_abort if SetCooperativeLevel returns an
> error.
>
> Any comments / Suggestions from the DirectX people?
>
Seems ok to me, the logging could do with a but of tarting up.
It's usually really handy if the instance is logged with each FIXME / TRACE
e.g.
instead of
FIXME("Poorly handled flag DDSCL_SETFOCUSWINDOW\n");
use
FIXME("(%p) : Poorly handled flag DDSCL_SETFOCUSWINDOW\n", This);
It's also usefull to log whenever a function returns an error.
e.g.
if (!(cooplevel & (DDSCL_EXCLUSIVE|DDSCL_NORMAL|DDSCL_SETFOCUSWINDOW))) {
TRACE("(%p) : Call to SetCooperativeLevel failed: cooplevel !=
DDSCL_EXCLUSIVE|DDSCL_NORMAL|DDSCL_SETFOCUSWINDOW, returning DDERR_INVALIDPARAMS);
return DDERR_INVALIDPARAMS;
}
that way if returning an error is causing something else to fail it's fairly easy to pick up.
Oliver.
> Thanks,
> Stefan Dösinger
> > ? dlls/ddraw/tests/cooplevels.c
> Index: dlls/ddraw/ddraw_main.c
> ===================================================================
> RCS file: /home/wine/wine/dlls/ddraw/ddraw_main.c,v
> retrieving revision 1.8
> diff -u -p -r1.8 ddraw_main.c
> --- dlls/ddraw/ddraw_main.c 26 Jul 2005 20:10:51 -0000 1.8
> +++ dlls/ddraw/ddraw_main.c 25 Aug 2005 13:53:20 -0000
> @@ -1116,13 +1116,54 @@ Main_DirectDraw_SetCooperativeLevel(LPDI
> * created." Otherwise the window can be changed???
> *
> * This appears to be wrong - comment it out for now.
> + * This seems to be true at least for DDSCL_SETFOCUSWINDOW
> + * It looks like Windows doesn't store the HWND in all cases,
> + * probably if DDSCL_NORMAL is specified, but that's not sure
> if (This->window)
> return DDERR_HWNDALREADYSET;
> */
>
> - if (!(cooplevel & (DDSCL_EXCLUSIVE|DDSCL_NORMAL)))
> - return DDERR_INVALIDPARAMS;
> + /* DDSCL_EXCLUSIVE or DDSCL_NORMAL or DDSCL_SETFOCUSWINDOW must be given */
> + if (!(cooplevel & (DDSCL_EXCLUSIVE|DDSCL_NORMAL|DDSCL_SETFOCUSWINDOW)))
> + return DDERR_INVALIDPARAMS;
>
> + /* Device window and focus Window. They only really matter in a
> + * Multi-Monitor application, but some games specify them and we
> + * have to react correctly. */
> + if(cooplevel & DDSCL_SETFOCUSWINDOW)
> + {
> + /* This flag is a biest: It is only valid when DDSCL_NORMAL has been set
> + * or no hwnd is set and no other flags are allowed, except DDSCL_NOWINDOWCHANGES
> + */
> + if(This->window)
> + if(!(This->cooperative_level & DDSCL_NORMAL)) return DDERR_HWNDALREADYSET;
> + if((cooplevel != DDSCL_SETFOCUSWINDOW))
> + if(cooplevel != (DDSCL_SETFOCUSWINDOW | DDSCL_NOWINDOWCHANGES) ) return
> DDERR_INVALIDPARAMS;
> +
> + /* Don't know what exactly to do, but it's perfectly valid
> + * to pass DDSCL_SETFOCUSWINDOW only */
> + FIXME("Poorly handled flag DDSCL_SETFOCUSWINDOW\n");
> +
> + /* Store the flag in the cooperative level. I don't think that all other
> + * flags should be overwritten, so just add it
> + * (In the most cases this will be DDSCL_SETFOCUSWINDOW | DDSCL_NORMAL) */
> + cooplevel |= DDSCL_SETFOCUSWINDOW;
> +
> + return DD_OK;
> + }
> +
> + /* DDSCL_EXCLUSE mode requires DDSCL_FULLSCREEN and vice versa */
> + if((cooplevel & DDSCL_EXCLUSIVE) && !(cooplevel & DDSCL_FULLSCREEN))
> + return DDERR_INVALIDPARAMS;
> + /* The other case is checked above */
> +
> + /* Unhandled flags. Give a warning */
> + if(cooplevel & DDSCL_SETDEVICEWINDOW)
> + FIXME("Unhandled flag DDSCL_SETDEVICEWINDOW.\n");
> + if(cooplevel & DDSCL_CREATEDEVICEWINDOW)
> + FIXME("Unhandled flag DDSCL_CREATEDEVICEWINDOW.\n");
> +
> + /* Perhaps the hwnd is only set in DDSCL_EXLUSIVE and DDSCL_FULLSCREEN mode. Not sure */
> This->window = hwnd;
> This->cooperative_level = cooplevel;
>
> Index: dlls/ddraw/tests/Makefile.in
> ===================================================================
> RCS file: /home/wine/wine/dlls/ddraw/tests/Makefile.in,v
> retrieving revision 1.5
> diff -u -p -r1.5 Makefile.in
> --- dlls/ddraw/tests/Makefile.in 7 Jun 2005 21:34:59 -0000 1.5
> +++ dlls/ddraw/tests/Makefile.in 25 Aug 2005 13:53:20 -0000
> @@ -9,7 +9,8 @@ EXTRALIBS = -ldxguid
> CTESTS = \
> d3d.c \
> ddrawmodes.c \
> - dsurface.c
> + dsurface.c \
> + cooplevels.c
>
> @MAKE_TEST_RULES@
>
> --- /dev/null 2005-08-25 09:49:19.469757400 +0000
> +++ dlls/ddraw/tests/cooplevels.c 2005-08-25 15:26:27.000000000 +0000
> @@ -0,0 +1,187 @@
> +/*
> + * Unit tests for ddraw cooperative levels
> + *
> + * Copyright (C) 2005 Stefan Dösinger
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + */
> +
> +#include <assert.h>
> +#include "wine/test.h"
> +#include "ddraw.h"
> +
> +static LPDIRECTDRAW lpDD = NULL;
> +static WNDCLASS wc;
> +static HWND hwnd;
> +
> +static void createwindow(void)
> +{
> + wc.style = CS_HREDRAW | CS_VREDRAW;
> + wc.lpfnWndProc = DefWindowProcA;
> + wc.cbClsExtra = 0;
> + wc.cbWndExtra = 0;
> + wc.hInstance = GetModuleHandleA(0);
> + wc.hIcon = LoadIconA(wc.hInstance, IDI_APPLICATION);
> + wc.hCursor = LoadCursorA(NULL, IDC_ARROW);
> + wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
> + wc.lpszMenuName = NULL;
> + wc.lpszClassName = "TestWindowClass";
> + if(!RegisterClassA(&wc))
> + assert(0);
> +
> + hwnd = CreateWindowExA(0, "TestWindowClass", "TestWindowClass",
> + WS_POPUP, 0, 0,
> + GetSystemMetrics(SM_CXSCREEN),
> + GetSystemMetrics(SM_CYSCREEN),
> + NULL, NULL, GetModuleHandleA(0), NULL);
> + assert(hwnd != NULL);
> +
> + ShowWindow(hwnd, SW_HIDE);
> + UpdateWindow(hwnd);
> + SetFocus(hwnd);
> +
> +}
> +
> +static void createdirectdraw(void)
> +{
> + HRESULT rc;
> +
> + rc = DirectDrawCreate(NULL, &lpDD, NULL);
> + ok(rc==DD_OK,"DirectDrawCreate returned: %lx\n",rc);
> +}
> +
> +
> +static void releasedirectdraw(void)
> +{
> + if( lpDD != NULL )
> + {
> + IDirectDraw_Release(lpDD);
> + lpDD = NULL;
> + }
> +}
> +
> +static void testcooperativelevels_normal(void)
> +{
> + HRESULT rc;
> +
> + /* Do some tests with DDSCL_NORMAL mode */
> +
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_NORMAL);
> + ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_NORMAL) returned: %lx\n",rc);
> +
> + /* Set the focus window */
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_SETFOCUSWINDOW);
> + ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_SETFOCUSWINDOW) returned: %lx\n",rc);
> +
> + /* Set the focus window a secound time*/
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_SETFOCUSWINDOW);
> + ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_SETFOCUSWINDOW) the secound time returned:
> %lx\n",rc);
> +
> + /* Test DDSCL_SETFOCUSWINDOW with the other flags. They should all fail, except of
> DDSCL_NOWINDOWCHANGES */
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_NORMAL | DDSCL_SETFOCUSWINDOW);
> + ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_NORMAL | DDSCL_SETFOCUSWINDOW)
> returned: %lx\n",rc);
> +
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_SETFOCUSWINDOW);
> + ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN |
> DDSCL_SETFOCUSWINDOW) returned: %lx\n",rc);
> +
> + /* This one succeeds */
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_NOWINDOWCHANGES | DDSCL_SETFOCUSWINDOW);
> + ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_NOWINDOWCHANGES | DDSCL_SETFOCUSWINDOW) returned:
> %lx\n",rc);
> +
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_MULTITHREADED | DDSCL_SETFOCUSWINDOW);
> + ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_MULTITHREADED | DDSCL_SETFOCUSWINDOW)
> returned: %lx\n",rc);
> +
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_FPUSETUP | DDSCL_SETFOCUSWINDOW);
> + ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_FPUSETUP | DDSCL_SETFOCUSWINDOW)
> returned: %lx\n",rc);
> +
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_FPUPRESERVE | DDSCL_SETFOCUSWINDOW);
> + ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_FPUPRESERVE | DDSCL_SETFOCUSWINDOW)
> returned: %lx\n",rc);
> +
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_ALLOWREBOOT | DDSCL_SETFOCUSWINDOW);
> + ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_ALLOWREBOOT | DDSCL_SETFOCUSWINDOW)
> returned: %lx\n",rc);
> +
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_ALLOWMODEX | DDSCL_SETFOCUSWINDOW);
> + ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_ALLOWMODEX | DDSCL_SETFOCUSWINDOW)
> returned: %lx\n",rc);
> +
> + /* Set the device window without any other flags. Should give an error */
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_SETDEVICEWINDOW);
> + ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_SETDEVICEWINDOW) returned:
> %lx\n",rc);
> +
> + /* Set device window with DDSCL_NORMAL */
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_NORMAL | DDSCL_SETDEVICEWINDOW);
> + ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_NORMAL | DDSCL_SETDEVICEWINDOW) returned:
> %lx\n",rc);
> +
> + /* Also set the focus window. Should give an error */
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_SETDEVICEWINDOW |
> DDSCL_SETFOCUSWINDOW);
> + ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_NORMAL | DDSCL_SETDEVICEWINDOW |
> DDSCL_SETFOCUSWINDOW) returned: %lx\n",rc);
> +
> + /* All done */
> +}
> +
> +static void testcooperativelevels_exclusive(void)
> +{
> + HRESULT rc;
> +
> + /* Do some tests with DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN mode */
> +
> + /* Try to set exclusive mode only */
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_EXCLUSIVE);
> + ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_EXCLUSIVE) returned: %lx\n",rc);
> +
> + /* Full screen mode only */
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_FULLSCREEN);
> + ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_FULLSCREEN) returned: %lx\n",rc);
> +
> + /* Full screen mode + exclusive mode */
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);
> + ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN) returned: %lx\n",rc);
> +
> + /* Set the focus window. Should fail */
> + rc = IDirectDraw_SetCooperativeLevel(lpDD,
> + hwnd, DDSCL_SETFOCUSWINDOW);
> + ok(rc==DDERR_HWNDALREADYSET,"SetCooperativeLevel(DDSCL_SETFOCUSWINDOW) returned:
> %lx\n",rc);
> +
> +
> + /* All done */
> +}
> +START_TEST(cooplevels)
> +{
> + createwindow();
> +
> + createdirectdraw();
> + testcooperativelevels_normal();
> + releasedirectdraw();
> +
> + createdirectdraw();
> + testcooperativelevels_exclusive();
> + releasedirectdraw();
> +}
> >
>
___________________________________________________________
Yahoo! Messenger - NEW crystal clear PC to PC calling worldwide with voicemail http://uk.messenger.yahoo.com
More information about the wine-devel
mailing list