UT2003 regression, Windowing problem

Ann and Jason Edmeades us at the-edmeades.demon.co.uk
Mon May 9 16:43:49 CDT 2005


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






More information about the wine-devel mailing list