Mercurial > hg > xemacs-beta
diff src/event-stream.c @ 86:364816949b59 r20-0b93
Import from CVS: tag r20-0b93
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:09:02 +0200 |
parents | 6a378aca36af |
children | 0d2f883870bc |
line wrap: on
line diff
--- a/src/event-stream.c Mon Aug 13 09:08:31 2007 +0200 +++ b/src/event-stream.c Mon Aug 13 09:09:02 2007 +0200 @@ -260,6 +260,8 @@ Chained through event_next() command_event_queue_tail is a pointer to the last-added element. */ +static Lisp_Object process_event_queue; +static Lisp_Object process_event_queue_tail; static Lisp_Object command_event_queue; static Lisp_Object command_event_queue_tail; @@ -1450,6 +1452,19 @@ /* enqueuing and dequeuing events */ /**********************************************************************/ +/* Add an event to the back of the process_event_queue */ +void +enqueue_process_event (Lisp_Object event) +{ + enqueue_event (event, &process_event_queue, &process_event_queue_tail); +} + +Lisp_Object +dequeue_process_event (void) +{ + return dequeue_event (&process_event_queue, &process_event_queue_tail); +} + /* Add an event to the back of the command-event queue: it will be the next event read after all pending events. This only works on keyboard, mouse-click, misc-user, and eval events. @@ -1839,7 +1854,8 @@ Charcount num_input_chars; static void -next_event_internal (Lisp_Object target_event, int allow_queued) +next_event_internal (Lisp_Object target_event, int allow_queued, + int allow_deferred) { struct gcpro gcpro1; /* QUIT; This is incorrect - the caller must do this because some @@ -1865,6 +1881,21 @@ } #endif } + else if (allow_deferred && !NILP (process_event_queue)) + { + Lisp_Object event = dequeue_process_event (); + Fcopy_event (event, target_event); + Fdeallocate_event (event); +#ifdef DEBUG_EMACS + if (debug_emacs_events) + { + write_c_string ("(process event queue) ", + Qexternal_debugging_output); + print_internal (target_event, Qexternal_debugging_output, 1); + write_c_string ("\n", Qexternal_debugging_output); + } +#endif + } else { struct Lisp_Event *e = XEVENT (target_event); @@ -2101,7 +2132,7 @@ { run_pre_idle_hook (); redisplay (); - next_event_internal (event, 1); + next_event_internal (event, 1, 1); Vquit_flag = Qnil; /* Read C-g as an event. */ store_this_key = 1; } @@ -2302,7 +2333,7 @@ /* This will take stuff off the command_event_queue, or read it from the event_stream, but it will not block. */ - next_event_internal (event, 1); + next_event_internal (event, 1, 1); Vquit_flag = Qnil; /* Treat C-g as a user event (ignore it). It is vitally important that we reset Vquit_flag here. Otherwise, if we're @@ -2363,7 +2394,8 @@ Allow any pending output from subprocesses to be read by Emacs. It is read into the process' buffers or given to their filter functions. Non-nil arg PROCESS means do not return until some output has been received - from PROCESS. + from PROCESS. Nil arg PROCESS means do not return until some output has + been received from any process. If the second arg is non-nil, it is the maximum number of seconds to wait: this function will return after that much time even if no input has arrived from PROCESS. This argument may be a float, meaning wait some fractional @@ -2380,6 +2412,7 @@ Lisp_Object result = Qnil; int timeout_id; int timeout_enabled = 0; + int done = 0; struct buffer *old_buffer = current_buffer; /* We preserve the current buffer but nothing else. If a focus @@ -2392,7 +2425,7 @@ GCPRO2 (event, process); - if (!NILP (process) && (!NILP (timeout_secs) || !NILP (timeout_msecs))) + if (!NILP (timeout_secs) || !NILP (timeout_msecs)) { unsigned long msecs = 0; if (!NILP (timeout_secs)) @@ -2411,7 +2444,10 @@ event = Fmake_event (); - while (!NILP (process) + while (!done && + ((NILP (process) && timeout_enabled) || + (NILP (process) && event_stream_event_pending_p (0)) || + (!NILP (process)))) /* Calling detect_input_pending() is the wrong thing here, because that considers the Vunread_command_events and command_event_queue. We don't need to look at the command_event_queue because we are @@ -2426,13 +2462,13 @@ loop will process it, and I don't think that there is ever a time when one calls accept-process-output with a nil argument and really need the processes to be handled. */ - || (!EQ (result, Qt) && event_stream_event_pending_p (0))) { /* If our timeout has arrived, we move along. */ if (timeout_enabled && !event_stream_wakeup_pending_p (timeout_id, 0)) { timeout_enabled = 0; - process = Qnil; /* We're done. */ + done = 1; /* We're done. */ + continue; /* Don't call next_event_internal */ } QUIT; /* next_event_internal() does not QUIT, so check for ^G @@ -2440,7 +2476,7 @@ less likely that the filter will actually be aborted. */ - next_event_internal (event, 0); + next_event_internal (event, 0, 1); /* If C-g was pressed while we were waiting, Vquit_flag got set and next_event_internal() also returns C-g. When we enqueue the C-g below, it will get discarded. The @@ -2449,9 +2485,10 @@ { case process_event: { - if (EQ (XEVENT (event)->event.process.process, process)) + if (NILP (process) || + EQ (XEVENT (event)->event.process.process, process)) { - process = Qnil; + done = 1; /* RMS's version always returns nil when proc is nil, and only returns t if input ever arrived on proc. */ result = Qt; @@ -2518,15 +2555,22 @@ consumer as well. We don't care about command and eval-events anyway. */ - next_event_internal (event, 0); /* blocks */ + next_event_internal (event, 0, 0); /* blocks */ /* See the comment in accept-process-output about Vquit_flag */ switch (XEVENT_TYPE (event)) { + case process_event: + { + /* Avoid calling filter functions recursively by squirreling + away process events */ + enqueue_process_event (Fcopy_event (event, Qnil)); + goto DONE_LABEL; + } + case timeout_event: /* We execute the event even if it's ours, and notice that it's happened above. */ case pointer_motion_event: - case process_event: case magic_event: { EXECUTE_INTERNAL: @@ -2623,7 +2667,7 @@ consumer as well. In fact, we know there's nothing on the command_event_queue that we didn't just put there. */ - next_event_internal (event, 0); /* blocks */ + next_event_internal (event, 0, 0); /* blocks */ /* See the comment in accept-process-output about Vquit_flag */ if (command_event_p (event)) @@ -2639,6 +2683,14 @@ enqueue_command_event (Fcopy_event (event, Qnil)); break; } + + case process_event: + { + /* Avoid recursive calls to process filters */ + enqueue_process_event (Fcopy_event (event, Qnil)); + break; + } + case timeout_event: /* We execute the event even if it's ours, and notice that it's happened above. */ @@ -2693,7 +2745,7 @@ command_event_queue; there are only user and eval-events there, and we'd just have to put them back anyway. */ - next_event_internal (event, 0); + next_event_internal (event, 0, 1); /* See the comment in accept-process-output about Vquit_flag */ if (command_event_p (event) || (XEVENT_TYPE (event) == eval_event) @@ -4129,6 +4181,10 @@ staticpro (&command_event_queue); command_event_queue_tail = Qnil; + process_event_queue = Qnil; + staticpro (&process_event_queue); + process_event_queue_tail = Qnil; + Vlast_selected_frame = Qnil; staticpro (&Vlast_selected_frame);