Hi all,
I'm trying to track down a regression which causes UT2003 (and UT2004 / Unreal2 apparently) to fail, and am getting stuck at the windowing level so would appreciate any thoughts as to possible causes. (And no, I haven't tried to work out what regressed it... Why spoil my fun!)
Basically we enter RedrawWindow and continually loop because the window in question never gets repainted 'properly'. The window has just been created, and very little has happened on the window other than being activated.
A +tid,+win,+msg,+x11drv,+spy (with various extra debug code in) shows:
Initial pass into RedrawWindow is via UpdateWindow which forces a redrawnow
0009:fixme:win:UpdateWindow In updateWindow 0009:trace:win:RedrawWindow 0x1002e whole window flags: RDW_ALLCHILDREN RDW_UPDATENOW 0009:fixme:win:RedrawWindow redraw hrgn
Because of flags, we insist we redraw the screen now...
0009:fixme:win:RedrawWindow @@@> Redrawwindow calling updatenow? 256 0009:fixme:win:RedrawWindow @@@> Calling....
(We never leave the update_now routine)
0009:fixme:win:update_now Before wait
We wait for outstanding painting related events. The window has just been created, so its just a clear of the whole screen from
0009:trace:x11drv:X11DRV_Expose win 0x1002e (3000006) 0,0 648x507 0009:trace:x11drv:X11DRV_Expose @@@> 0x1002e B4 Offset into rect (0,0)-(648,507) 0009:trace:x11drv:X11DRV_Expose @@@> 0x1002e Offset into rect (-4,-23)-(644,484) 0009:trace:win:RedrawWindow 0x1002e rect (-4,-23)-(644,484) flags: RDW_INVALIDATE RDW_ERASE RDW_ALLCHILDREN RDW_FRAME 0009:fixme:win:RedrawWindow redraw rects 0009:fixme:win:RedrawWindow @@@> Redrawwindow calling updatenow? 0
So the outstanding event was an invalidate of the whole area
0009:fixme:win:update_now After wait
0009:fixme:win:update_now @@> Calling erase 0009:fixme:win:update_now @@> Called erase
The infinite for loop
0009:fixme:win:update_now @@> FOR loop prev=(nil) child=0x40027bec
The window needs redrawing
0009:fixme:win:update_now Paint required! 0009:trace:msg:WINPROC_CallProc32WTo32A func 0x11017650 (hwnd=0x1002e,msg=WM_PAINT,wp=00000000,lp=00000000)
***> Nothing happens here as a result of the paint?
0009:fixme:win:update_now @@> FOR loop prev=0x1002e child=0x1002e
So the invalid region is still set, so its assumed the updates have failed so we schedule a complete erase
0009:fixme:win:update_now @@@> 0x1002e not repainted properly, erasing 0009:trace:win:update_now 0x1002e not repainted properly, erasing
0009:fixme:win:update_now 0x1002e region 0x150c box (4,23)-(644,503) In send_erase 0009:trace:msg:WINPROC_CallProc32WTo32A func 0x11017650 (hwnd=0x1002e,msg=WM_ERASEBKGND,wp=000014ac,lp=00000000) 0009:trace:win:RedrawWindow 0x1002e rect (0,0)-(640,480) flags: RDW_INVALIDATE RDW_ERASE RDW_NOCHILDREN 0009:fixme:win:RedrawWindow redraw rects 0009:fixme:win:RedrawWindow @@@> Redrawwindow calling updatenow? 0 0009:fixme:win:send_erase Out send_erase
So we loop again...
0009:fixme:win:update_now @@> FOR loop prev=(nil) child=0x1002e 0009:fixme:win:update_now Paint required! 0009:trace:msg:WINPROC_CallProc32WTo32A func 0x11017650 (hwnd=0x1002e,msg= WM_PAINT,wp=00000000,lp=00000000)
***> Nothing happens here as a result of the paint? Etc etc
0009:fixme:win:update_now @@> FOR loop prev=0x1002e child=0x1002e 0009:fixme:win:update_now @@@> 0x1002e not repainted properly, erasing 0009:trace:win:update_now 0x1002e not repainted properly, erasing
etc etc
So should there have been an action as a result of the WM_PAINT, and is it valid for it not to occur (ie is wine overdoing the assumption on redrawing)
Is updatenow correct for an UpdateWindow call (MSDN states a WM_PAINT should be sent, but doesn't say it will check it gets done).
Note there are 2 suspicious patches in painting.c both by AJ - (1.19 and 1.20) - The first tries to handle broken WM_PAINT handlers by avoiding the loop, and the 2nd (1.20) just forces the loop to occur! Adding a 'break' in the case where child==prev and a send ncpaint / send erase has occurred avoids the problem, but what is the correct fix
Jason
On Mon, 09 May 2005 22:43:49 +0100, Ann and Jason Edmeades wrote:
So should there have been an action as a result of the WM_PAINT, and is it valid for it not to occur (ie is wine overdoing the assumption on redrawing)
Notes has the same problem. Last time I talked to The Director about it he said doing nothing in WM_PAINT was invalid and indeed, doing that on Windows goes into an infinite loop. Most puzzling. There seems to be a magic combination of things you can do that make it not go into this loop ... not sure.
On Mon, 09 May 2005 22:43:49 +0100, Ann and Jason Edmeades wrote:
So should there have been an action as a result of the WM_PAINT, and is it valid for it not to occur (ie is wine overdoing the assumption on redrawing)
Notes has the same problem. Last time I talked to The Director about it he said doing nothing in WM_PAINT was invalid and indeed, doing that on Windows goes into an infinite loop. Most puzzling. There seems to be a magic combination of things you can do that make it not go into this loop ... not sure.
Looks like I have 2 more apps: Empire Earth and MS Office 2003. Empire Earth locks during startup(before reaching it's usual problems), and MS Office 2003 blocks when showing the file open/save dialog.
Adding a break in the child==prev path of update_now fixes them too.
Stefan