[comp.windows.x] How should slow client handle Events?

mbr@aoa.UUCP (Mark Rosenthal) (03/06/90)

I have a client written solely in Xlib routines.  The user can instruct the
program either to display another drawing or to exit, by means of key presses
or button presses.  The user can also resize the window with a window manager,
in which case the bit gravity of the window (set to ForgetGravity) clears the
window, and the program redraws the drawing in the new size.

Unfortunately, it takes a fair bit of time for the client to compute and for
the server to draw this window.  During this time, users type keys, press
buttons, or resize the window, and they don't get what they expect.  A key
press which tells the program to go to the next picture is not seen by the
client until it finishes drawing the current picture.  A resize causes the
window to be cleared, but the client keeps on drawing the rest of its picture
in a size appropriate to the old size window, into the newly cleared and
resized window.  It then gets back to the main event loop, sees expose events,
and redraws a correctly sized picture on top of this partial picture.

Part of the solution is fairly easy.  I can just clear the window on the first
Expose event following a ConfigureNotify, and the user will never end up with
two pictures on top of one another.

However, the user will still have to wait for the code to finish drawing a
picture he doesn't want to see, before the code recognizes that he has typed
a key.  In the non-event driven paradigm for C code under Unix, problems like
this are handled by having the tty driver convert a few special keystrokes into
signals.  No analogous mechanism appears to be available in X11.

I am willing to have the image-drawing code occasionally examine the event
queue, and return to the main loop if it finds an appropriate event, but I
can't find an Xlib call which does what I need.  I want to peek into the queue
to decide whether I should stop drawing and return, but if there is no event
which I interpret as meaning stop drawing, I want to continue drawing.
Unfortunately, XPeekEvent() and XPeekIfEvent() cause the code to block until
an event is available.  This would prevent the code from ever finishing the
drawing.  All the XCheck...Event() functions pull the event off the queue.
This means that the code would not know where in the queue the event was
found.  When somebody presses "n", I want to be able to go immediately to
the next drawing.  This means that I must flush all expose events which
occurred before the key was pressed, but process expose events which occurred
after the key was pressed.  Once the event has been pulled off of the queue,
I believe I've lost any indication of the event's position in the queue.  If so,
None of the XCheck...Event() functions would be useful.

The best idea I've come up with is to call XCheckIfEvent(), write my predicate
function so that it always returns False and store information in a global
variable about whether the drawing routine should continue drawing.  That would
allow the client to prevent the event from being pulled from the queue, and
still not block.  Unfortunately, it would require the entire event queue to
be searched every time.  This seems like it could slow down the drawing
routine substantially.

Does anybody have any better solution?
-- 
	Mark of the Valley of Roses
	...!bbn.com!aoa!mbr