Gunnar Evermann wrote:
I need some advice from people who understand X.
I am trying to debug a problem with the C-g detection in xemacs. The
main part of this is in x_check_for_quit_char() which does the
following:
------------------------------------------------------------
XtAppPending (Xt_app_con);
XEventsQueued (display, QueuedAfterReading);
queued = XCheckIfEvent (display, &event,
quit_char_predicate,
(char *) &critical_quit);
------------------------------------------------------------
To be able to interrupt system calls (like a hung connect()) with C-g
the above is called _once_ from a SIGALARM signal handler.
The problem is that XCheckIfEvent() doesn't seem to find all events.
For example if I run all this from a debugger then what I see is that
XCheckIfEvent() checks two events, but if I then immediately call
XCheckIfEvent() again there is suddenly another event in the queue. If
I call it once more then there are four (in my example finally
including the C-g).
I assume the idea of the XtAppPending() and XEventsQueued() calls was
to avoid exactly this situation by making sure that all events are
available in the queue. Obviously this doesn't work.
Can anybody shed some light on this? Is there any way to make sure we
really check all events?
i just read the docs, and the above behavior is exactly as documented. the bug
is in our code, which apparently has never worked right.
the solution:
-- drain_X_queue[] has a bug in it. it should read:
while (XEventsQueued (display, QueuedAfterReading))
XtAppProcessEvent (Xt_app_con, XtIMXEvent);
NOT:
while (XtAppPending (Xt_app_con) & XtIMXEvent)
XtAppProcessEvent (Xt_app_con, XtIMXEvent);
this also alleviates the problem mentioned in
/* XtAppPending() can be super-slow, esp. over a network connection. ... */
-- change x_check_for_quit_char:
x_check_for_quit_char (Display *display)
{
drain_X_queue();
scan_dispatch_queue_for_a_C_g_event_setting_Vquit_flag_if_appropriate();
}
where the latter function does as named, and can be closely modelled on
emacs_mswindows_quit_p(). (WARNING, its handling of critical-quit i.e. C-S-g is
broken. make sure your version works.)
ben
Gunnar
P.S.: In case this is relevant: before all this we called
fcntl (filedesc, F_SETFL, fcntl (filedesc, F_GETFL, 0) & ~FASYNC);
--
ben
I'm sometimes slow in getting around to reading my mail, so if you
want to reach me faster, call 520-661-6661.
See
http://www.666.com/ben/chronic-pain/ for the hell I've been
through.