Re: [gtk-list] Re: GraphicsExpose (was Re: About the About Box)




> On Mon, 15 Dec 1997, Owen Taylor wrote:
> > 
> > Raph Levien <raph@acm.org> writes:
> >
> > > I had another thought on this and wanted to throw it out there. Since 
> > > this is at heart a race condition caused by asynchronous GraphicsExpose 
> > > events following XCopyArea, wouldn't the problem be fixed by doing an 
> > > XSync right before the scroll? I can't imagine the performance 
> > > degradation would be that serious, and it sounds a whole lot simpler 
> > > than some of the other proposals.
> > 
> > I don't think this will help. XSync (or gdk_flush()) only affect
> > the output queue. Since the problem is GraphicsExpose events sitting
> > in the input queue, the only way to fix it is to process those events
> > before doing the XCopyArea.
> 
> Yeah, I tried the hack (it's only one line) and found it didn't help. 
> It's clear to me now why - even though the XSync causes the app to have 
> access to all pending GraphicsExpose events, it has to actively look 
> ahead in the queue to process them, something that Gtk is not doing.
> 
> It still seems to me that the XSync is required to avoid the race 
> condition, though. The manpage for XSync says that it both flushes the 
> output queue and waits until all requests have been received and 
> processed by the X server. Actually, that still sounds a little vague to 
> me - is the generation of the GraphicsExpose event part of "processing" 
> the XCopyArea request, or may it happen later?

Well, it would seem _reasonable_ that it is part of the processing but
it would probably take some serious reading of the X protocol
specification to be sure. I don't think this actually matters though,
see below.
 
> When I'm thinking about the input queue, I find it helpful to think of it 
> as having two parts. The first part is what the X server has written down 
> the socket but is not available to the app. The second part is what is 
> available to the app on a read call. Logically, the input queue is the 
> concatenation of the two. It seems to me very plausible that 
> GraphicsExpose events may be present in the first of these sections, in 
> which case the XSync would seem to be necessary.

I think XCheckIfEvent will check for events waiting on the socket in
a non-blocking fashion. The problem would be if the XCopyArea
event was still being processed by the server and it hadn't written
it to the socket yet - or it was still in network transit. 

Anyways, a _literal_ XSync isn't necessary. An XSync does something like
sending a message with a unique serial # to the server and waiting
until the server echo's it back.

But we already have something in the queue that the server will echo
back -- The XCopyArea is guaranteed generate either a sequence
of GraphicsExpose events (the last one identified by count == 0),
or a NoExpose event. If we wait until we get one or the other after
a XCopyArea, we should be OK.

Additionally, this should work OK even if the server is generating
graphics expose events asynchronously to the processesing of the
event queue.

The example I posted a reference to earlier does this by calling
XIfEvent - I may have implied that it was using XCheckIfEvent,
which would be incorrect, as you point out. (Another reason why
using the current gdk_event_get() doesn't work)

> If I'm right about this, then it seems that there's just no way to scroll 
> without at least one roundtrip to the server :(

Pretty much. One could keep a flag when waiting for an GraphicsExpose
/NoExpose event, batch up events that cause further scrolling, and then
execute them when the GraphicsExpose event is received. Not much
fun to implement though.

Regards,
                                        Owen



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]