https://bugs.winehq.org/show_bug.cgi?id=47036
Paul Gofman gofmanp@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Attachment #64208|0 |1 is obsolete| | Attachment #64252|0 |1 is obsolete| | Attachment #64253|0 |1 is obsolete| | Attachment #64255|0 |1 is obsolete| | Attachment #64256|0 |1 is obsolete| | Attachment #64259|0 |1 is obsolete| |
--- Comment #23 from Paul Gofman gofmanp@gmail.com --- Created attachment 65930 --> https://bugs.winehq.org/attachment.cgi?id=65930 Test showing the problem (no fix)
I've retested the issue and found what seems to be actually wrong here.
It seems that the referenced commit which triggered the regression in this game is not the real source of the problem.
The game is using ddraw7 and works in exclusive fullscreen mode. The window which was specified in SetCooperativeLevel has child windows. Clipping of those children in GL drawable was not performed before referenced commit but happens now. That might be correct behaviour for Opengl which does not have exclusive fullscreen mode the same way Directx has. But with Directx the drawing to the primary surface in exclusive mode goes directly to the hardware screen and bypasses gdi, i. e., is rendered on top of anything else on the screen. At the same time, the other windows can still receive input events. The game updates the screen by locking primary surface.
This is somewhat similar to the Bug #11999, with the difference that in Endless Online the rendering window is covered by another top level window, not its child, so the issue was visible and stays there regardless of the commit referenced here. EO works fine in windowed mode. EO is seemingly a Delphi program which creates two top level windows, TApplication and TMainForm. The latter contains clickable GUI elements. In a fullscreen mode ddraw7 SetCooperativeLevel gets TApplication window, while TMainForm is maintained on top and receives user input. Thus under Wine rendering window is hidden behind TMainForm. In windowed mode this wouldn't work on Windows either, so application passes TMainForm window to ddraw in this case.
The workaround which works for both games is to set HKCU\Software\Wine\Direct3D\DirectDrawRenderer to gdi.
I am attaching an interactive test which draws the window on top of the fullscreen exclusive window and does some ddraw rendering by filling primary surface with color. It is a bit unstable for a unit test, as I don't yet see a sure way to read the pixel from the screen as it is seen: reading it from screen DC in Wine after a single draw sometimes returns random values (some sync is seemingly missing). Also one time window creation / ddraw update looks not entirely stable both under Windows and Wine. But with repeated draws it looks stable: the primary surface fill always goes above everything on Windows and on the contrary the second window is always visible with Wine.
Unfortunately I don't yet see a sure fix for that. Both games can be fixed by taking screen DC blit path in ddraw/surface.c:ddraw_surface_update_frontbuffer(), but I suppose this would be just terrible. Ideally we would need some way to get exclusive window from display driver, but I don't yet see any straightforward way to do it. Ensuring somehow that the rendering window is on top through user32 calls is likely not an option, as the windows which are currently on top are supposed to be foreground and receive user input which will be broken if we hide them behind. Maybe it is possible to pass some window property to display driver so that child windows clipping introduced by the referenced commit won't occur for the exclusive fullscreen drawing, but this would be only the partial solution.