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