[Bug 2082] DirectDraw games only showing black screen

wine-bugs at winehq.org wine-bugs at winehq.org
Mon Dec 23 18:54:50 CST 2013


http://bugs.winehq.org/show_bug.cgi?id=2082

Ken Thomases <ken at codeweavers.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ken at codeweavers.com

--- Comment #125 from Ken Thomases <ken at codeweavers.com> ---
I've been looking into this bug as it affects Worms Armageddon.  That game has
built-in Wine-specific tweaks to work around the problem, but they don't work
with the Mac driver because the Mac driver doesn't support a virtual desktop
window.  For testing purposes, I'm using the X11 driver with WA's tweaks
disabled.

I'm going to summarize what I have found (which has also been demonstrated by
some of the test cases):

* WA creates window A.
* WA creates a dialog window D, which is owned by window A.  This has sometimes
been described as a child window but it's not.  It's a top-level window.  Being
owned by window A means that it is kept in front of window A.
* The dialog D has various controls, including buttons, etc.
* WA calls IDirectDraw::SetCooperativeLevel(window A, DDSCL_EXCLUSIVE |
DDSCL_FULLSCREEN).  The presence of DDSCL_FULLSCREEN should mean that it draws
directly to the screen, bypassing all normal (GDI) drawing of other windows. 
So, even though dialog D is in front of window A, the drawing to window A
should appear on screen.
* Wine's ddraw calls wined3d_device_setup_fullscreen_window() to set window A
up as a full-screen window.  This attempts to order window A to the front of
all windows by calling SetWindowPos(window A, HWND_TOPMOST, ...).  However,
because dialog D is owned by window A, user32 keeps D in front.

The ultimate result is that dialog D obscures window A.  I haven't investigated
why dialog D is all black as opposed to looking like a typical user32 dialog
window with controls.

I have confirmed this with a gross hack.  In
dlls/user32/dialog.c:DIALOG_CreateIndirect(), I have modified the two calls to
CreateWindowEx[AW]() to pass NULL for the owner.  This means that dialog D is
not owned by window A and window A can be moved in front of it.  The result is
that you can see the rendering.  However, clicks on the window are ignored. 
That's because window A isn't prepared to respond to the clicks.  The dialog D
is supposed to receive those clicks.

I think that Stefan was on the right path.  I think that, when ddraw/wined3d
goes to set up window A for full-screen, it should not attempt to change the
Win32 window.  I think it needs to work with the user driver to set up a
full-screen OpenGL surface that's outside of the Win32 window hierarchy.  This
surface would have to avoid interfering with mouse events.  Those should still
be delivered to whatever Win32 window is under the cursor.

It may be that targeting the desktop window is the most appropriate way for
ddraw/wined3d to communicate the need to draw to the full screen to the user
driver, although Stefan mentioned that that has its own problems.  Given that
ddraw (and d3d?) has a need to bypass the normal windowing and graphics, I
think it makes sense for it to communicate directly with the user driver.

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list