set_waiting_for_input (&timeout);
}
- {
- int old_timers_run = timers_run;
- if (XINT (read_kbd) && detect_input_pending_run_timers (do_display))
- {
- nfds = 0;
- FD_ZERO (&Available);
- }
- else if (timers_run != old_timers_run)
- ;
- else
- nfds = select (MAXDESC, &Available, (SELECT_TYPE *)0, (SELECT_TYPE *)0,
- &timeout);
- }
+ if (XINT (read_kbd) && detect_input_pending ())
+ {
+ nfds = 0;
+ FD_ZERO (&Available);
+ }
+ else
+ nfds = select (MAXDESC, &Available, (SELECT_TYPE *)0, (SELECT_TYPE *)0,
+ &timeout);
xerrno = errno;
1 to return when input is available, or
-1 means caller will actually read the input, so don't throw to
the quit handler.
+ a cons cell, meaning wait until its car is non-nil
+ (and gobble terminal input into the buffer if any arrives), or
We know that read_kbd will never be a Lisp_Process, since
`subprocesses' isn't defined.
EMACS_TIME end_time, timeout;
SELECT_TYPE waitchannels;
int xerrno;
+ Lisp_Object *wait_for_cell = 0;
+
+ /* If waiting for non-nil in a cell, record where. */
+ if (CONSP (read_kbd))
+ {
+ wait_for_cell = &XCONS (read_kbd)->car;
+ XSETFASTINT (read_kbd, 0);
+ }
/* What does time_limit really mean? */
if (time_limit || microsecs)
int nfds;
int timeout_reduced_for_timers = 0;
- if (XINT (read_kbd))
- FD_SET (0, &waitchannels);
- else
- FD_ZERO (&waitchannels);
-
/* If calling from keyboard input, do not quit
since we want to return C-g as an input character.
Otherwise, do pending quit if requested. */
if (XINT (read_kbd) >= 0)
QUIT;
+ /* Exit now if the cell we're waiting for became non-nil. */
+ if (wait_for_cell && ! NILP (*wait_for_cell))
+ break;
+
/* Compute time from now till when time limit is up */
/* Exit if already run out */
if (time_limit > 0 || microsecs)
run timer events directly.
(Callers that will immediately read keyboard events
call timer_delay on their own.) */
- if (XINT (read_kbd) >= 0)
+ if (1)
{
EMACS_TIME timer_delay;
- int old_timers_run = timers_run;
+ int old_timers_run;
+
+ retry:
+ old_timers_run = timers_run;
timer_delay = timer_check (1);
if (timers_run != old_timers_run && do_display)
- redisplay_preserve_echo_area ();
+ {
+ redisplay_preserve_echo_area ();
+ /* We must retry, since a timer may have requeued itself
+ and that could alter the time delay. */
+ goto retry;
+ }
+
if (! EMACS_TIME_NEG_P (timer_delay) && time_limit != -1)
{
EMACS_TIME difference;
if (XINT (read_kbd) < 0)
set_waiting_for_input (&timeout);
+ /* Wait till there is something to do. */
+
+ if (! XINT (read_kbd) && wait_for_cell == 0)
+ FD_ZERO (&waitchannels);
+ else
+ FD_SET (0, &waitchannels);
+
/* If a frame has been newly mapped and needs updating,
reprocess its display stuff. */
if (frame_garbaged && do_display)
- redisplay_preserve_echo_area ();
+ {
+ clear_waiting_for_input ();
+ redisplay_preserve_echo_area ();
+ if (XINT (read_kbd) < 0)
+ set_waiting_for_input (&timeout);
+ }
{
int old_timers_run = timers_run;
- if (XINT (read_kbd) && detect_input_pending_run_timers (do_display))
- nfds = 0;
+ if (XINT (read_kbd) && detect_input_pending ())
+ {
+ nfds = 0;
+ FD_ZERO (&waitchannels);
+ }
else if (timers_run != old_timers_run)
;
else
/* Check for keyboard input */
- if (XINT (read_kbd) != 0
+ if ((XINT (read_kbd) != 0 || wait_for_cell)
&& detect_input_pending_run_timers (do_display))
{
swallow_events (do_display);
if (detect_input_pending_run_timers (do_display))
break;
}
+
+ /* Exit now if the cell we're waiting for became non-nil. */
+ if (wait_for_cell && ! NILP (*wait_for_cell))
+ break;
}
start_polling ();