Mercurial > hg > xemacs-beta
comparison src/event-stream.c @ 70:131b0175ea99 r20-0b30
Import from CVS: tag r20-0b30
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:02:59 +0200 |
parents | 56c54cf7c5b6 |
children | b9518feda344 |
comparison
equal
deleted
inserted
replaced
69:804d1389bcd6 | 70:131b0175ea99 |
---|---|
54 | 54 |
55 #include "sysdep.h" /* init_poll_for_quit() */ | 55 #include "sysdep.h" /* init_poll_for_quit() */ |
56 #include "syssignal.h" /* SIGCHLD, etc. */ | 56 #include "syssignal.h" /* SIGCHLD, etc. */ |
57 #include "systime.h" /* to set Vlast_input_time */ | 57 #include "systime.h" /* to set Vlast_input_time */ |
58 | 58 |
59 #ifdef MULE | |
60 #include "mule-coding.h" | |
61 #endif | |
62 | |
59 #include <errno.h> | 63 #include <errno.h> |
60 | 64 |
61 /* The number of keystrokes between auto-saves. */ | 65 /* The number of keystrokes between auto-saves. */ |
62 static int auto_save_interval; | 66 static int auto_save_interval; |
63 | 67 |
71 Lisp_Object Vpre_command_hook, Vpost_command_hook; | 75 Lisp_Object Vpre_command_hook, Vpost_command_hook; |
72 Lisp_Object Qpre_command_hook, Qpost_command_hook; | 76 Lisp_Object Qpre_command_hook, Qpost_command_hook; |
73 | 77 |
74 /* Hook run when XEmacs is about to be idle. */ | 78 /* Hook run when XEmacs is about to be idle. */ |
75 Lisp_Object Qpre_idle_hook, Vpre_idle_hook; | 79 Lisp_Object Qpre_idle_hook, Vpre_idle_hook; |
76 | |
77 /* Control gratuitous keyboard focus throwing. */ | |
78 int focus_follows_mouse; | |
79 | 80 |
80 #ifdef ILL_CONCEIVED_HOOK | 81 #ifdef ILL_CONCEIVED_HOOK |
81 /* Hook run after a command if there's no more input soon. */ | 82 /* Hook run after a command if there's no more input soon. */ |
82 Lisp_Object Qpost_command_idle_hook, Vpost_command_idle_hook; | 83 Lisp_Object Qpost_command_idle_hook, Vpost_command_idle_hook; |
83 | 84 |
160 Lisp_Object Vkeyboard_translate_table; | 161 Lisp_Object Vkeyboard_translate_table; |
161 | 162 |
162 /* If control-meta-super-shift-X is undefined, try control-meta-super-x */ | 163 /* If control-meta-super-shift-X is undefined, try control-meta-super-x */ |
163 Lisp_Object Vretry_undefined_key_binding_unshifted; | 164 Lisp_Object Vretry_undefined_key_binding_unshifted; |
164 Lisp_Object Qretry_undefined_key_binding_unshifted; | 165 Lisp_Object Qretry_undefined_key_binding_unshifted; |
166 | |
167 #ifdef HAVE_XIM | |
168 /* If composed input is undefined, use self-insert-char */ | |
169 Lisp_Object Vcomposed_character_default_binding; | |
170 #endif /* HAVE_XIM */ | |
165 | 171 |
166 /* Console that corresponds to our controlling terminal */ | 172 /* Console that corresponds to our controlling terminal */ |
167 Lisp_Object Vcontrolling_terminal; | 173 Lisp_Object Vcontrolling_terminal; |
168 | 174 |
169 /* An event (actually an event chain linked through event_next) or Qnil. | 175 /* An event (actually an event chain linked through event_next) or Qnil. |
265 cause a suspension back to the shell, which is generally | 271 cause a suspension back to the shell, which is generally |
266 undesirable. (#### This doesn't fully work.) */ | 272 undesirable. (#### This doesn't fully work.) */ |
267 | 273 |
268 int emacs_is_blocking; | 274 int emacs_is_blocking; |
269 | 275 |
270 /* Handlers which run during sit-for, sleep-for and accept-process-output | |
271 are not allowed to recursively call these routines. We record here | |
272 if we are in that situation. */ | |
273 | |
274 static Lisp_Object recursive_sit_for; | |
275 | |
276 | |
277 | 276 |
278 /**********************************************************************/ | 277 /**********************************************************************/ |
279 /* Command-builder object */ | 278 /* Command-builder object */ |
280 /**********************************************************************/ | 279 /**********************************************************************/ |
281 | 280 |
760 } | 759 } |
761 | 760 |
762 static void | 761 static void |
763 maybe_do_auto_save (void) | 762 maybe_do_auto_save (void) |
764 { | 763 { |
765 /* This function can call lisp */ | 764 /* This function can GC */ |
766 keystrokes_since_auto_save++; | 765 keystrokes_since_auto_save++; |
767 if (auto_save_interval > 0 && | 766 if (auto_save_interval > 0 && |
768 keystrokes_since_auto_save > max (auto_save_interval, 20) && | 767 keystrokes_since_auto_save > max (auto_save_interval, 20) && |
769 !detect_input_pending ()) | 768 !detect_input_pending ()) |
770 { | 769 { |
866 | 865 |
867 DEFUN ("input-pending-p", Finput_pending_p, 0, 0, 0, /* | 866 DEFUN ("input-pending-p", Finput_pending_p, 0, 0, 0, /* |
868 T if command input is currently available with no waiting. | 867 T if command input is currently available with no waiting. |
869 Actually, the value is nil only if we can be sure that no input is available. | 868 Actually, the value is nil only if we can be sure that no input is available. |
870 */ | 869 */ |
871 ()) | 870 ()) |
872 { | 871 { |
873 return ((detect_input_pending ()) ? Qt : Qnil); | 872 return ((detect_input_pending ()) ? Qt : Qnil); |
874 } | 873 } |
875 | 874 |
876 | 875 |
1199 event_stream_remove_async_timeout (timeout->interval_id); | 1198 event_stream_remove_async_timeout (timeout->interval_id); |
1200 else | 1199 else |
1201 event_stream_remove_timeout (timeout->interval_id); | 1200 event_stream_remove_timeout (timeout->interval_id); |
1202 free_managed_opaque (Vtimeout_free_list, op); | 1201 free_managed_opaque (Vtimeout_free_list, op); |
1203 } | 1202 } |
1204 } | |
1205 | |
1206 int | |
1207 event_stream_wakeup_pending_p (int id, int async_p) | |
1208 { | |
1209 struct timeout *timeout; | |
1210 Lisp_Object rest = Qnil; | |
1211 Lisp_Object timeout_list; | |
1212 int found = 0; | |
1213 | |
1214 | |
1215 if (async_p) | |
1216 timeout_list = pending_async_timeout_list; | |
1217 else | |
1218 timeout_list = pending_timeout_list; | |
1219 | |
1220 /* Find the element on the list of pending ones, if it's still there. */ | |
1221 LIST_LOOP (rest, timeout_list) | |
1222 { | |
1223 timeout = (struct timeout *) XOPAQUE_DATA (XCAR (rest)); | |
1224 if (timeout->id == id) | |
1225 { | |
1226 found = 1; | |
1227 break; | |
1228 } | |
1229 } | |
1230 | |
1231 return found; | |
1232 } | 1203 } |
1233 | 1204 |
1234 | 1205 |
1235 /**** Asynch. timeout functions (see also signal.c) ****/ | 1206 /**** Asynch. timeout functions (see also signal.c) ****/ |
1236 | 1207 |
1412 | 1383 |
1413 WARNING: if you are thinking of calling `add-async-timeout' from inside of a | 1384 WARNING: if you are thinking of calling `add-async-timeout' from inside of a |
1414 callback function as a way of resignalling a timeout, think again. There | 1385 callback function as a way of resignalling a timeout, think again. There |
1415 is a race condition. That's why the RESIGNAL argument exists. | 1386 is a race condition. That's why the RESIGNAL argument exists. |
1416 */ | 1387 */ |
1417 (secs, function, object, resignal)) | 1388 (secs, function, object, resignal)) |
1418 { | 1389 { |
1419 unsigned long msecs = lisp_number_to_milliseconds (secs, 0); | 1390 unsigned long msecs = lisp_number_to_milliseconds (secs, 0); |
1420 unsigned long msecs2 = (NILP (resignal) ? 0 : | 1391 unsigned long msecs2 = (NILP (resignal) ? 0 : |
1421 lisp_number_to_milliseconds (resignal, 0)); | 1392 lisp_number_to_milliseconds (resignal, 0)); |
1422 int id; | 1393 int id; |
1665 but that can cause us to end up in an infinite loop focussing | 1636 but that can cause us to end up in an infinite loop focussing |
1666 between two frames. It seems that since the call to `select-frame' | 1637 between two frames. It seems that since the call to `select-frame' |
1667 in emacs_handle_focus_change_final() is based on the _FOR_HOOKS | 1638 in emacs_handle_focus_change_final() is based on the _FOR_HOOKS |
1668 value, we need to do so too. */ | 1639 value, we need to do so too. */ |
1669 if (!NILP (sel_frame) && | 1640 if (!NILP (sel_frame) && |
1670 !focus_follows_mouse && | |
1671 !EQ (DEVICE_FRAME_THAT_OUGHT_TO_HAVE_FOCUS (d), sel_frame) && | 1641 !EQ (DEVICE_FRAME_THAT_OUGHT_TO_HAVE_FOCUS (d), sel_frame) && |
1672 !NILP (DEVICE_FRAME_WITH_FOCUS_FOR_HOOKS (d)) && | 1642 !NILP (DEVICE_FRAME_WITH_FOCUS_FOR_HOOKS (d)) && |
1673 !EQ (DEVICE_FRAME_WITH_FOCUS_FOR_HOOKS (d), sel_frame)) | 1643 !EQ (DEVICE_FRAME_WITH_FOCUS_FOR_HOOKS (d), sel_frame)) |
1674 { | 1644 { |
1675 /* prevent us from issuing the same request more than once */ | 1645 /* prevent us from issuing the same request more than once */ |
1966 synchronously with other events. `dispatch-event' knows what to do with | 1936 synchronously with other events. `dispatch-event' knows what to do with |
1967 these events. | 1937 these events. |
1968 */ | 1938 */ |
1969 (event, prompt)) | 1939 (event, prompt)) |
1970 { | 1940 { |
1971 /* This function can call lisp */ | 1941 /* This function can GC */ |
1972 /* #### We start out using the selected console before an event | 1942 /* #### We start out using the selected console before an event |
1973 is received, for echoing the partially completed command. | 1943 is received, for echoing the partially completed command. |
1974 This is most definitely wrong -- there needs to be a separate | 1944 This is most definitely wrong -- there needs to be a separate |
1975 echo area for each console! */ | 1945 echo area for each console! */ |
1976 struct console *con = XCONSOLE (Vselected_console); | 1946 struct console *con = XCONSOLE (Vselected_console); |
1977 struct command_builder *command_builder = | 1947 struct command_builder *command_builder = |
1978 XCOMMAND_BUILDER (con->command_builder); | 1948 XCOMMAND_BUILDER (con->command_builder); |
1979 int store_this_key = 0; | 1949 int store_this_key = 0; |
1980 struct gcpro gcpro1; | 1950 struct gcpro gcpro1; |
1981 #ifdef LWLIB_MENUBARS_LUCID | |
1982 extern int in_menu_callback; /* defined in menubar-x.c */ | |
1983 #endif /* LWLIB_MENUBARS_LUCID */ | |
1984 | |
1985 GCPRO1 (event); | 1951 GCPRO1 (event); |
1952 | |
1986 /* DO NOT do QUIT anywhere within this function or the functions it calls. | 1953 /* DO NOT do QUIT anywhere within this function or the functions it calls. |
1987 We want to read the ^G as an event. */ | 1954 We want to read the ^G as an event. */ |
1988 | |
1989 #ifdef LWLIB_MENUBARS_LUCID | |
1990 /* | |
1991 * #### Fix the menu code so this isn't necessary. | |
1992 * | |
1993 * We cannot allow the lwmenu code to be reentered, because the | |
1994 * code is not written to be reentrant and will crash. Therefore | |
1995 * paths from the menu callbacks back into the menu code have to | |
1996 * be blocked. Fnext_event is the normal path into the menu code, | |
1997 * so we signal an error here. | |
1998 */ | |
1999 if (in_menu_callback) | |
2000 error ("Attempt to call next-event inside menu callback"); | |
2001 #endif /* LWLIB_MENUBARS_LUCID */ | |
2002 | 1955 |
2003 if (NILP (event)) | 1956 if (NILP (event)) |
2004 event = Fmake_event (); | 1957 event = Fmake_event (); |
2005 else | 1958 else |
2006 CHECK_LIVE_EVENT (event); | 1959 CHECK_LIVE_EVENT (event); |
2369 | 2322 |
2370 /**********************************************************************/ | 2323 /**********************************************************************/ |
2371 /* pausing until an action occurs */ | 2324 /* pausing until an action occurs */ |
2372 /**********************************************************************/ | 2325 /**********************************************************************/ |
2373 | 2326 |
2374 /* This is used in accept-process-output, sleep-for and sit-for. | |
2375 Before running any process_events in these routines, we set | |
2376 recursive_sit_for to Qt, and use this unwind protect to reset it to | |
2377 Qnil upon exit. When recursive_sit_for is Qt, calling sit-for will | |
2378 cause it to return immediately. | |
2379 | |
2380 All of these routines install timeouts, so we clear the installed | |
2381 timeout as well. | |
2382 | |
2383 Note: It's very easy to break the desired behaviours of these | |
2384 3 routines. If you make any changes to anything in this area, run | |
2385 the regression tests at the bottom of the file. -- dmoore */ | |
2386 | |
2387 | |
2388 static Lisp_Object | |
2389 sit_for_unwind (Lisp_Object timeout_id) | |
2390 { | |
2391 if (!NILP(timeout_id)) | |
2392 Fdisable_timeout (timeout_id); | |
2393 | |
2394 recursive_sit_for = Qnil; | |
2395 return Qnil; | |
2396 } | |
2397 | |
2398 /* #### Is (accept-process-output nil 3) supposed to be like (sleep-for 3)? | 2327 /* #### Is (accept-process-output nil 3) supposed to be like (sleep-for 3)? |
2399 */ | 2328 */ |
2400 | 2329 |
2401 DEFUN ("accept-process-output", Faccept_process_output, 0, 3, 0, /* | 2330 DEFUN ("accept-process-output", Faccept_process_output, 0, 3, 0, /* |
2402 Allow any pending output from subprocesses to be read by Emacs. | 2331 Allow any pending output from subprocesses to be read by Emacs. |
2403 It is read into the process' buffers or given to their filter functions. | 2332 It is read into the process' buffers or given to their filter functions. |
2404 Non-nil arg PROCESS means do not return until some output has been received | 2333 Non-nil arg PROCESS means do not return until some output has been received |
2405 from PROCESS. Nil arg PROCESS means do not return until some output has | 2334 from PROCESS. |
2406 been received from any process. | |
2407 If the second arg is non-nil, it is the maximum number of seconds to wait: | 2335 If the second arg is non-nil, it is the maximum number of seconds to wait: |
2408 this function will return after that much time even if no input has arrived | 2336 this function will return after that much time even if no input has arrived |
2409 from PROCESS. This argument may be a float, meaning wait some fractional | 2337 from PROCESS. This argument may be a float, meaning wait some fractional |
2410 part of a second. | 2338 part of a second. |
2411 If the third arg is non-nil, it is a number of milliseconds that is added | 2339 If the third arg is non-nil, it is a number of milliseconds that is added |
2418 struct gcpro gcpro1, gcpro2; | 2346 struct gcpro gcpro1, gcpro2; |
2419 Lisp_Object event = Qnil; | 2347 Lisp_Object event = Qnil; |
2420 Lisp_Object result = Qnil; | 2348 Lisp_Object result = Qnil; |
2421 int timeout_id; | 2349 int timeout_id; |
2422 int timeout_enabled = 0; | 2350 int timeout_enabled = 0; |
2423 int done = 0; | |
2424 struct buffer *old_buffer = current_buffer; | 2351 struct buffer *old_buffer = current_buffer; |
2425 int count; | |
2426 | 2352 |
2427 /* We preserve the current buffer but nothing else. If a focus | 2353 /* We preserve the current buffer but nothing else. If a focus |
2428 change alters the selected window then the top level event loop | 2354 change alters the selected window then the top level event loop |
2429 will eventually alter current_buffer to match. In the mean time | 2355 will eventually alter current_buffer to match. In the mean time |
2430 we don't want to mess up whatever called this function. */ | 2356 we don't want to mess up whatever called this function. */ |
2432 if (!NILP (process)) | 2358 if (!NILP (process)) |
2433 CHECK_PROCESS (process); | 2359 CHECK_PROCESS (process); |
2434 | 2360 |
2435 GCPRO2 (event, process); | 2361 GCPRO2 (event, process); |
2436 | 2362 |
2437 if (!NILP (timeout_secs) || !NILP (timeout_msecs)) | 2363 if (!NILP (process) && (!NILP (timeout_secs) || !NILP (timeout_msecs))) |
2438 { | 2364 { |
2439 unsigned long msecs = 0; | 2365 unsigned long msecs = 0; |
2440 if (!NILP (timeout_secs)) | 2366 if (!NILP (timeout_secs)) |
2441 msecs = lisp_number_to_milliseconds (timeout_secs, 1); | 2367 msecs = lisp_number_to_milliseconds (timeout_secs, 1); |
2442 if (!NILP (timeout_msecs)) | 2368 if (!NILP (timeout_msecs)) |
2451 } | 2377 } |
2452 } | 2378 } |
2453 | 2379 |
2454 event = Fmake_event (); | 2380 event = Fmake_event (); |
2455 | 2381 |
2456 count = specpdl_depth (); | 2382 while (!NILP (process) |
2457 record_unwind_protect (sit_for_unwind, | |
2458 timeout_enabled ? make_int (timeout_id) : Qnil); | |
2459 recursive_sit_for = Qt; | |
2460 | |
2461 while (!done && | |
2462 ((NILP (process) && timeout_enabled) || | |
2463 (NILP (process) && event_stream_event_pending_p (0)) || | |
2464 (!NILP (process)))) | |
2465 /* Calling detect_input_pending() is the wrong thing here, because | 2383 /* Calling detect_input_pending() is the wrong thing here, because |
2466 that considers the Vunread_command_events and command_event_queue. | 2384 that considers the Vunread_command_events and command_event_queue. |
2467 We don't need to look at the command_event_queue because we are | 2385 We don't need to look at the command_event_queue because we are |
2468 only interested in process events, which don't go on that. In | 2386 only interested in process events, which don't go on that. In |
2469 fact, we can't read from it anyway, because we put stuff on it. | 2387 fact, we can't read from it anyway, because we put stuff on it. |
2474 to dispatch any process events that may be on the queue. It is | 2392 to dispatch any process events that may be on the queue. It is |
2475 not clear to me that this is important, because the top-level | 2393 not clear to me that this is important, because the top-level |
2476 loop will process it, and I don't think that there is ever a | 2394 loop will process it, and I don't think that there is ever a |
2477 time when one calls accept-process-output with a nil argument | 2395 time when one calls accept-process-output with a nil argument |
2478 and really need the processes to be handled. */ | 2396 and really need the processes to be handled. */ |
2479 { | 2397 || (!EQ (result, Qt) && event_stream_event_pending_p (0))) |
2480 /* If our timeout has arrived, we move along. */ | 2398 { |
2481 if (timeout_enabled && !event_stream_wakeup_pending_p (timeout_id, 0)) | |
2482 { | |
2483 timeout_enabled = 0; | |
2484 done = 1; /* We're done. */ | |
2485 continue; /* Don't call next_event_internal */ | |
2486 } | |
2487 | |
2488 QUIT; /* next_event_internal() does not QUIT, so check for ^G | 2399 QUIT; /* next_event_internal() does not QUIT, so check for ^G |
2489 before reading output from the process - this makes it | 2400 before reading output from the process - this makes it |
2490 less likely that the filter will actually be aborted. | 2401 less likely that the filter will actually be aborted. |
2491 */ | 2402 */ |
2492 | 2403 |
2497 next time through, QUIT will be called and will signal a quit. */ | 2408 next time through, QUIT will be called and will signal a quit. */ |
2498 switch (XEVENT_TYPE (event)) | 2409 switch (XEVENT_TYPE (event)) |
2499 { | 2410 { |
2500 case process_event: | 2411 case process_event: |
2501 { | 2412 { |
2502 if (NILP (process) || | 2413 if (EQ (XEVENT (event)->event.process.process, process)) |
2503 EQ (XEVENT (event)->event.process.process, process)) | |
2504 { | 2414 { |
2505 done = 1; | 2415 process = Qnil; |
2506 /* RMS's version always returns nil when proc is nil, | 2416 /* RMS's version always returns nil when proc is nil, |
2507 and only returns t if input ever arrived on proc. */ | 2417 and only returns t if input ever arrived on proc. */ |
2508 result = Qt; | 2418 result = Qt; |
2509 } | 2419 } |
2510 | 2420 |
2511 execute_internal_event (event); | 2421 execute_internal_event (event); |
2512 break; | 2422 break; |
2513 } | 2423 } |
2514 case timeout_event: | 2424 case timeout_event: |
2515 /* We execute the event even if it's ours, and notice that it's | 2425 { |
2516 happened above. */ | 2426 if (timeout_enabled && |
2427 XEVENT (event)->event.timeout.id_number == timeout_id) | |
2428 { | |
2429 timeout_enabled = 0; | |
2430 process = Qnil; /* we're done */ | |
2431 } | |
2432 else /* a timeout that's not the one we're waiting for */ | |
2433 goto EXECUTE_INTERNAL; | |
2434 break; | |
2435 } | |
2517 case pointer_motion_event: | 2436 case pointer_motion_event: |
2518 case magic_event: | 2437 case magic_event: |
2519 { | 2438 { |
2520 EXECUTE_INTERNAL: | 2439 EXECUTE_INTERNAL: |
2521 execute_internal_event (event); | 2440 execute_internal_event (event); |
2527 break; | 2446 break; |
2528 } | 2447 } |
2529 } | 2448 } |
2530 } | 2449 } |
2531 | 2450 |
2532 unbind_to (count, timeout_enabled ? make_int (timeout_id) : Qnil); | 2451 /* If our timeout has not been signalled yet, disable it. */ |
2452 if (timeout_enabled) | |
2453 event_stream_disable_wakeup (timeout_id, 0); | |
2533 | 2454 |
2534 Fdeallocate_event (event); | 2455 Fdeallocate_event (event); |
2535 UNGCPRO; | 2456 UNGCPRO; |
2536 current_buffer = old_buffer; | 2457 current_buffer = old_buffer; |
2537 return result; | 2458 return result; |
2538 } | 2459 } |
2539 | 2460 |
2540 DEFUN ("sleep-for", Fsleep_for, 1, 1, 0, /* | 2461 DEFUN ("sleep-for", Fsleep_for, 1, 1, 0, /* |
2541 Pause, without updating display, for ARG seconds. | 2462 Pause, without updating display, for ARG seconds. |
2542 ARG may be a float, meaning pause for some fractional part of a second. | 2463 ARG may be a float, meaning pause for some fractional part of a second. |
2543 | |
2544 It is recommended that you never call sleep-for from inside of a process | |
2545 filter function or timer event (either synchronous or asynchronous). | |
2546 */ | 2464 */ |
2547 (seconds)) | 2465 (seconds)) |
2548 { | 2466 { |
2549 /* This function can GC */ | 2467 /* This function can GC */ |
2550 unsigned long msecs = lisp_number_to_milliseconds (seconds, 1); | 2468 unsigned long msecs = lisp_number_to_milliseconds (seconds, 1); |
2551 int id; | 2469 int id; |
2552 Lisp_Object event = Qnil; | 2470 Lisp_Object event = Qnil; |
2553 int count; | |
2554 struct gcpro gcpro1; | 2471 struct gcpro gcpro1; |
2555 | 2472 |
2556 GCPRO1 (event); | 2473 GCPRO1 (event); |
2557 | 2474 |
2558 id = event_stream_generate_wakeup (msecs, 0, Qnil, Qnil, 0); | 2475 id = event_stream_generate_wakeup (msecs, 0, Qnil, Qnil, 0); |
2559 event = Fmake_event (); | 2476 event = Fmake_event (); |
2560 | |
2561 count = specpdl_depth (); | |
2562 record_unwind_protect (sit_for_unwind, make_int (id)); | |
2563 recursive_sit_for = Qt; | |
2564 | |
2565 while (1) | 2477 while (1) |
2566 { | 2478 { |
2567 /* If our timeout has arrived, we move along. */ | |
2568 if (!event_stream_wakeup_pending_p (id, 0)) | |
2569 goto DONE_LABEL; | |
2570 | |
2571 QUIT; /* next_event_internal() does not QUIT, so check for ^G | 2479 QUIT; /* next_event_internal() does not QUIT, so check for ^G |
2572 before reading output from the process - this makes it | 2480 before reading output from the process - this makes it |
2573 less likely that the filter will actually be aborted. | 2481 less likely that the filter will actually be aborted. |
2574 */ | 2482 */ |
2575 /* We're a generator of the command_event_queue, so we can't be a | 2483 /* We're a generator of the command_event_queue, so we can't be a |
2579 next_event_internal (event, 0); /* blocks */ | 2487 next_event_internal (event, 0); /* blocks */ |
2580 /* See the comment in accept-process-output about Vquit_flag */ | 2488 /* See the comment in accept-process-output about Vquit_flag */ |
2581 switch (XEVENT_TYPE (event)) | 2489 switch (XEVENT_TYPE (event)) |
2582 { | 2490 { |
2583 case timeout_event: | 2491 case timeout_event: |
2584 /* We execute the event even if it's ours, and notice that it's | 2492 { |
2585 happened above. */ | 2493 if (XEVENT (event)->event.timeout.id_number == id) |
2586 case process_event: | 2494 goto DONE_LABEL; |
2495 else | |
2496 goto EXECUTE_INTERNAL; | |
2497 } | |
2587 case pointer_motion_event: | 2498 case pointer_motion_event: |
2499 case process_event: | |
2588 case magic_event: | 2500 case magic_event: |
2589 { | 2501 { |
2590 EXECUTE_INTERNAL: | 2502 EXECUTE_INTERNAL: |
2591 execute_internal_event (event); | 2503 execute_internal_event (event); |
2592 break; | 2504 break; |
2597 break; | 2509 break; |
2598 } | 2510 } |
2599 } | 2511 } |
2600 } | 2512 } |
2601 DONE_LABEL: | 2513 DONE_LABEL: |
2602 unbind_to (count, make_int (id)); | |
2603 Fdeallocate_event (event); | 2514 Fdeallocate_event (event); |
2604 UNGCPRO; | 2515 UNGCPRO; |
2605 return Qnil; | 2516 return Qnil; |
2606 } | 2517 } |
2607 | 2518 |
2608 DEFUN ("sit-for", Fsit_for, 1, 2, 0, /* | 2519 DEFUN ("sit-for", Fsit_for, 1, 2, 0, /* |
2609 Perform redisplay, then wait ARG seconds or until user input is available. | 2520 Perform redisplay, then wait ARG seconds or until user input is available. |
2610 ARG may be a float, meaning a fractional part of a second. | 2521 ARG may be a float, meaning a fractional part of a second. |
2611 Optional second arg non-nil means don't redisplay, just wait for input. | 2522 Optional second arg non-nil means don't redisplay, just wait for input. |
2612 Redisplay is preempted as always if user input arrives, and does not | 2523 Redisplay is preempted as always if user input arrives, and does not |
2613 happen if input is available before it starts. | 2524 happen if input is available before it starts. |
2614 Value is t if waited the full time with no input arriving. | 2525 Value is t if waited the full time with no input arriving. |
2615 | |
2616 If sit-for is called from within a process filter function or timer | |
2617 event (either synchronous or asynchronous) it will return immediately. | |
2618 */ | 2526 */ |
2619 (seconds, nodisplay)) | 2527 (seconds, nodisplay)) |
2620 { | 2528 { |
2621 /* This function can GC */ | 2529 /* This function can GC */ |
2622 unsigned long msecs = lisp_number_to_milliseconds (seconds, 1); | 2530 unsigned long msecs = lisp_number_to_milliseconds (seconds, 1); |
2623 Lisp_Object event, result; | 2531 Lisp_Object event, result; |
2624 struct gcpro gcpro1; | 2532 struct gcpro gcpro1; |
2625 int id; | 2533 int id; |
2626 int count; | |
2627 | 2534 |
2628 /* The unread-command-events count as pending input */ | 2535 /* The unread-command-events count as pending input */ |
2629 if (!NILP (Vunread_command_events) || !NILP (Vunread_command_event)) | 2536 if (!NILP (Vunread_command_events) || !NILP (Vunread_command_event)) |
2630 return Qnil; | 2537 return Qnil; |
2631 | 2538 |
2644 /* If we're in a macro, or noninteractive, or early in temacs, then | 2551 /* If we're in a macro, or noninteractive, or early in temacs, then |
2645 don't wait. */ | 2552 don't wait. */ |
2646 if (noninteractive || !NILP (Vexecuting_macro)) | 2553 if (noninteractive || !NILP (Vexecuting_macro)) |
2647 return (Qnil); | 2554 return (Qnil); |
2648 | 2555 |
2649 /* Recusive call from a filter function or timeout handler. */ | |
2650 if (!NILP(recursive_sit_for)) | |
2651 { | |
2652 if (!event_stream_event_pending_p (1) && NILP (nodisplay)) | |
2653 { | |
2654 run_pre_idle_hook (); | |
2655 redisplay (); | |
2656 } | |
2657 return Qnil; | |
2658 } | |
2659 | |
2660 | |
2661 /* Otherwise, start reading events from the event_stream. | 2556 /* Otherwise, start reading events from the event_stream. |
2662 Do this loop at least once even if (sit-for 0) so that we | 2557 Do this loop at least once even if (sit-for 0) so that we |
2663 redisplay when no input pending. | 2558 redisplay when no input pending. |
2664 */ | 2559 */ |
2560 event = Fmake_event (); | |
2665 GCPRO1 (event); | 2561 GCPRO1 (event); |
2666 event = Fmake_event (); | |
2667 | 2562 |
2668 /* Generate the wakeup even if MSECS is 0, so that existing timeout/etc. | 2563 /* Generate the wakeup even if MSECS is 0, so that existing timeout/etc. |
2669 events get processed. The old (pre-19.12) code special-cased this | 2564 events get processed. The old (pre-19.12) code special-cased this |
2670 and didn't generate a wakeup, but the resulting behavior was less than | 2565 and didn't generate a wakeup, but the resulting behavior was less than |
2671 ideal; viz. the occurrence of (sit-for 0.001) scattered throughout | 2566 ideal; viz. the occurrence of (sit-for 0.001) scattered throughout |
2672 the E-Lisp universe. */ | 2567 the E-Lisp universe. */ |
2673 | 2568 |
2674 id = event_stream_generate_wakeup (msecs, 0, Qnil, Qnil, 0); | 2569 id = event_stream_generate_wakeup (msecs, 0, Qnil, Qnil, 0); |
2675 | |
2676 count = specpdl_depth (); | |
2677 record_unwind_protect (sit_for_unwind, make_int (id)); | |
2678 recursive_sit_for = Qt; | |
2679 | 2570 |
2680 while (1) | 2571 while (1) |
2681 { | 2572 { |
2682 /* If there is no user input pending, then redisplay. | 2573 /* If there is no user input pending, then redisplay. |
2683 */ | 2574 */ |
2685 { | 2576 { |
2686 run_pre_idle_hook (); | 2577 run_pre_idle_hook (); |
2687 redisplay (); | 2578 redisplay (); |
2688 } | 2579 } |
2689 | 2580 |
2690 /* If our timeout has arrived, we move along. */ | 2581 /* If we're no longer waiting for a timeout, bug out. */ |
2691 if (!event_stream_wakeup_pending_p (id, 0)) | 2582 if (! id) |
2692 { | 2583 { |
2693 result = Qt; | 2584 result = Qt; |
2694 goto DONE_LABEL; | 2585 goto DONE_LABEL; |
2695 } | 2586 } |
2696 | 2587 |
2705 next_event_internal (event, 0); /* blocks */ | 2596 next_event_internal (event, 0); /* blocks */ |
2706 /* See the comment in accept-process-output about Vquit_flag */ | 2597 /* See the comment in accept-process-output about Vquit_flag */ |
2707 | 2598 |
2708 if (command_event_p (event)) | 2599 if (command_event_p (event)) |
2709 { | 2600 { |
2710 QUIT; /* If the command was C-g check it here | |
2711 so that we abort out of the sit-for, | |
2712 not the next command. sleep-for and | |
2713 accept-process-output continue looping | |
2714 so they check QUIT again implicitly.*/ | |
2715 result = Qnil; | 2601 result = Qnil; |
2716 goto DONE_LABEL; | 2602 goto DONE_LABEL; |
2717 } | 2603 } |
2718 switch (XEVENT_TYPE (event)) | 2604 switch (XEVENT_TYPE (event)) |
2719 { | 2605 { |
2721 { | 2607 { |
2722 /* eval-events get delayed until later. */ | 2608 /* eval-events get delayed until later. */ |
2723 enqueue_command_event (Fcopy_event (event, Qnil)); | 2609 enqueue_command_event (Fcopy_event (event, Qnil)); |
2724 break; | 2610 break; |
2725 } | 2611 } |
2726 | |
2727 case timeout_event: | 2612 case timeout_event: |
2728 /* We execute the event even if it's ours, and notice that it's | 2613 { |
2729 happened above. */ | 2614 if (XEVENT (event)->event.timeout.id_number != id) |
2730 default: | 2615 /* a timeout that wasn't the one we're waiting for */ |
2616 goto EXECUTE_INTERNAL; | |
2617 id = 0; /* assert that we are no longer waiting for it. */ | |
2618 result = Qt; | |
2619 goto DONE_LABEL; | |
2620 } | |
2621 default: | |
2731 { | 2622 { |
2732 EXECUTE_INTERNAL: | 2623 EXECUTE_INTERNAL: |
2733 execute_internal_event (event); | 2624 execute_internal_event (event); |
2734 break; | 2625 break; |
2735 } | 2626 } |
2736 } | 2627 } |
2737 } | 2628 } |
2738 | 2629 |
2739 DONE_LABEL: | 2630 DONE_LABEL: |
2740 unbind_to (count, make_int (id)); | 2631 /* If our timeout has not been signalled yet, disable it. */ |
2632 if (id) | |
2633 event_stream_disable_wakeup (id, 0); | |
2741 | 2634 |
2742 /* Put back the event (if any) that made Fsit_for() exit before the | 2635 /* Put back the event (if any) that made Fsit_for() exit before the |
2743 timeout. Note that it is being added to the back of the queue, which | 2636 timeout. Note that it is being added to the back of the queue, which |
2744 would be inappropriate if there were any user events on the queue | 2637 would be inappropriate if there were any user events on the queue |
2745 already: we would be misordering them. But we know that there are | 2638 already: we would be misordering them. But we know that there are |
2872 get a SIGCHLD). */ | 2765 get a SIGCHLD). */ |
2873 || (readstatus == -1 && errno == EIO) | 2766 || (readstatus == -1 && errno == EIO) |
2874 #endif | 2767 #endif |
2875 ) | 2768 ) |
2876 { | 2769 { |
2877 /* Currently, we rely on SIGCHLD to indicate that the | 2770 /* Currently, we rely on SIGCHLD to indicate that |
2878 process has terminated. Unfortunately, on some systems | 2771 the process has terminated. Unfortunately, it |
2879 the SIGCHLD gets missed some of the time. So we put an | 2772 appears that on some systems the SIGCHLD gets |
2880 additional check in status_notify() to see whether a | 2773 missed some of the time. So, we put in am |
2881 process has terminated. We must tell status_notify() | 2774 additional check in status_notify() to see |
2882 to enable that check, and we do so now. */ | 2775 whether a process has terminated. We have to |
2776 tell status_notify() to enable that check, and | |
2777 we do so now. */ | |
2883 kick_status_notify (); | 2778 kick_status_notify (); |
2884 } | 2779 } |
2885 else | 2780 else |
2886 { | 2781 { |
2887 /* Deactivate network connection */ | 2782 /* Deactivate network connection */ |
3158 if (!NILP (Vprefix_help_command) && | 3053 if (!NILP (Vprefix_help_command) && |
3159 event_matches_key_specifier_p (XEVENT (builder->most_current_event), | 3054 event_matches_key_specifier_p (XEVENT (builder->most_current_event), |
3160 Vhelp_char)) | 3055 Vhelp_char)) |
3161 return (Vprefix_help_command); | 3056 return (Vprefix_help_command); |
3162 | 3057 |
3058 #ifdef HAVE_XIM | |
3059 /* If keysym is a non-ASCII char, bind it to self-insert-char by default. */ | |
3060 if (XEVENT_TYPE (builder->most_current_event) == key_press_event | |
3061 && !NILP (Vcomposed_character_default_binding)) | |
3062 { | |
3063 Lisp_Object keysym = XEVENT (builder->most_current_event)->event.key.keysym; | |
3064 if (CHARP (keysym) && !CHAR_ASCII_P (XCHAR (keysym))) | |
3065 return Vcomposed_character_default_binding; | |
3066 } | |
3067 #endif /* HAVE_XIM */ | |
3068 | |
3163 /* If we read extra events attempting to match a function key but end | 3069 /* If we read extra events attempting to match a function key but end |
3164 up failing, then we release those events back to the command loop | 3070 up failing, then we release those events back to the command loop |
3165 and fail on the original lookup. The released events will then be | 3071 and fail on the original lookup. The released events will then be |
3166 reprocessed in the context of the first part having failed. */ | 3072 reprocessed in the context of the first part having failed. */ |
3167 if (!NILP (builder->last_non_munged_event)) | 3073 if (!NILP (builder->last_non_munged_event)) |
3259 -- We do not reset this-command-keys when we finish reading a | 3165 -- We do not reset this-command-keys when we finish reading a |
3260 command. This is because some commands (e.g. C-u) act | 3166 command. This is because some commands (e.g. C-u) act |
3261 like command prefixes; they signal this by setting prefix-arg | 3167 like command prefixes; they signal this by setting prefix-arg |
3262 to non-nil. | 3168 to non-nil. |
3263 -- Therefore, we reset this-command-keys when we finish | 3169 -- Therefore, we reset this-command-keys when we finish |
3264 executing a command, unless prefix-arg is set. | 3170 executing a comand, unless prefix-arg is set. |
3265 -- However, if we ever do a non-local exit out of a command | 3171 -- However, if we ever do a non-local exit out of a command |
3266 loop (e.g. an error in a command), we need to reset | 3172 loop (e.g. an error in a command), we need to reset |
3267 this-command-keys. We do this by calling reset_this_command_keys() | 3173 this-command-keys. We do this by calling reset_this_command_keys() |
3268 from cmdloop.c, whenever an error causes an invocation of the | 3174 from cmdloop.c, whenever an error causes an invocation of the |
3269 default error handler, and whenever there's a throw to top-level.) | 3175 default error handler, and whenever there's a throw to top-level.) |
3293 enqueue_event (new, &Vthis_command_keys, &Vthis_command_keys_tail); | 3199 enqueue_event (new, &Vthis_command_keys, &Vthis_command_keys_tail); |
3294 } | 3200 } |
3295 | 3201 |
3296 /* The following two functions are used in call-interactively, | 3202 /* The following two functions are used in call-interactively, |
3297 for the @ and e specifications. We used to just use | 3203 for the @ and e specifications. We used to just use |
3298 `current-mouse-event' (i.e. the last mouse event in this-command-keys), | 3204 `current-mouse-event' (i.e. the last mouse event in this-comand-keys), |
3299 but FSF does it more generally so we follow their lead. */ | 3205 but FSF does it more generally so we follow their lead. */ |
3300 | 3206 |
3301 Lisp_Object | 3207 Lisp_Object |
3302 extract_this_command_keys_nth_mouse_event (int n) | 3208 extract_this_command_keys_nth_mouse_event (int n) |
3303 { | 3209 { |
4111 file = Fexpand_file_name (file, Qnil); | 4017 file = Fexpand_file_name (file, Qnil); |
4112 fd = creat ((char *) XSTRING_DATA (file), 0666); | 4018 fd = creat ((char *) XSTRING_DATA (file), 0666); |
4113 if (fd < 0) | 4019 if (fd < 0) |
4114 error ("Unable to create dribble file"); | 4020 error ("Unable to create dribble file"); |
4115 Vdribble_file = make_filedesc_output_stream (fd, 0, 0, LSTR_CLOSING); | 4021 Vdribble_file = make_filedesc_output_stream (fd, 0, 0, LSTR_CLOSING); |
4022 #ifdef MULE | |
4023 Vdribble_file = | |
4024 make_encoding_output_stream (XLSTREAM (Vdribble_file), | |
4025 Fget_coding_system (Qescape_quoted)); | |
4026 #endif | |
4116 } | 4027 } |
4117 return Qnil; | 4028 return Qnil; |
4118 } | 4029 } |
4119 | 4030 |
4120 | 4031 |
4215 something_happened = 0; | 4126 something_happened = 0; |
4216 | 4127 |
4217 last_point_position_buffer = Qnil; | 4128 last_point_position_buffer = Qnil; |
4218 staticpro (&last_point_position_buffer); | 4129 staticpro (&last_point_position_buffer); |
4219 | 4130 |
4220 recursive_sit_for = Qnil; | |
4221 | |
4222 DEFVAR_INT ("echo-keystrokes", &echo_keystrokes /* | 4131 DEFVAR_INT ("echo-keystrokes", &echo_keystrokes /* |
4223 *Nonzero means echo unfinished commands after this many seconds of pause. | 4132 *Nonzero means echo unfinished commands after this many seconds of pause. |
4224 */ ); | 4133 */ ); |
4225 echo_keystrokes = 1; | 4134 echo_keystrokes = 1; |
4226 | 4135 |
4253 `next-command-event', `sit-for', `sleep-for', `accept-process-output', | 4162 `next-command-event', `sit-for', `sleep-for', `accept-process-output', |
4254 `x-get-selection', or various Energize-specific commands. | 4163 `x-get-selection', or various Energize-specific commands. |
4255 Errors running the hook are caught and ignored. | 4164 Errors running the hook are caught and ignored. |
4256 */ ); | 4165 */ ); |
4257 Vpre_idle_hook = Qnil; | 4166 Vpre_idle_hook = Qnil; |
4258 | |
4259 DEFVAR_BOOL ("focus-follows-mouse", &focus_follows_mouse /* | |
4260 Variable to control XEmacs behavior with respect to focus changing. | |
4261 If this variable is set to t, then XEmacs will not gratuitously change | |
4262 the keyboard focus. | |
4263 */ ); | |
4264 focus_follows_mouse = 0; | |
4265 | 4167 |
4266 #ifdef ILL_CONCEIVED_HOOK | 4168 #ifdef ILL_CONCEIVED_HOOK |
4267 /* Ill-conceived because it's not run in all sorts of cases | 4169 /* Ill-conceived because it's not run in all sorts of cases |
4268 where XEmacs is blocking. That's what `pre-idle-hook' | 4170 where XEmacs is blocking. That's what `pre-idle-hook' |
4269 is designed to solve. */ | 4171 is designed to solve. */ |
4427 with the last key unshifted. (e.g. C-X C-F would be retried as C-X C-f.) | 4329 with the last key unshifted. (e.g. C-X C-F would be retried as C-X C-f.) |
4428 If lookup still fails, a normal error is signalled. In general, | 4330 If lookup still fails, a normal error is signalled. In general, |
4429 you should *bind* this, not set it. | 4331 you should *bind* this, not set it. |
4430 */ ); | 4332 */ ); |
4431 Vretry_undefined_key_binding_unshifted = Qt; | 4333 Vretry_undefined_key_binding_unshifted = Qt; |
4334 | |
4335 #ifdef HAVE_XIM | |
4336 DEFVAR_LISP ("Vcomposed_character_default_binding", | |
4337 &Vretry_undefined_key_binding_unshifted /* | |
4338 The default keybinding to use for key events from composed input. | |
4339 Window systems frequently have ways to allow the user to compose | |
4340 single characters in a language using multiple keystrokes. | |
4341 XEmacs sees these as single character keypress events. | |
4342 */ ); | |
4343 Vcomposed_character_default_binding = Qself_insert_command; | |
4344 #endif /* HAVE_XIM */ | |
4432 | 4345 |
4433 Vcontrolling_terminal = Qnil; | 4346 Vcontrolling_terminal = Qnil; |
4434 staticpro (&Vcontrolling_terminal); | 4347 staticpro (&Vcontrolling_terminal); |
4435 | 4348 |
4436 Vdribble_file = Qnil; | 4349 Vdribble_file = Qnil; |
4550 ;a should be inserted in foo. Cursor highlighting should not change in | 4463 ;a should be inserted in foo. Cursor highlighting should not change in |
4551 ;the meantime. | 4464 ;the meantime. |
4552 | 4465 |
4553 ;do it with sleep-for. move cursor into foo, then back into *scratch* | 4466 ;do it with sleep-for. move cursor into foo, then back into *scratch* |
4554 ;before typing. | 4467 ;before typing. |
4555 ;repeat also with (accept-process-output nil 20) | 4468 |
4556 | 4469 ;make sure ^G aborts both sit-for and sleep-for. |
4557 ;make sure ^G aborts sit-for, sleep-for and accept-process-output: | |
4558 | 4470 |
4559 (defun tst () | 4471 (defun tst () |
4560 (list (condition-case c | 4472 (list (condition-case c |
4561 (sleep-for 20) | 4473 (sleep-for 20) |
4562 (quit c)) | 4474 (quit c)) |
4563 (read-char))) | 4475 (read-char))) |
4564 | 4476 |
4565 (tst)^Ja^G ==> ((quit) 97) with no signal | 4477 (tst)^Ja^G ==> ((quit) 97) with no signal |
4566 (tst)^J^Ga ==> ((quit) 97) with no signal | 4478 (tst)^J^Ga ==> ((quit) 97) with no signal |
4567 (tst)^Jabc^G ==> ((quit) 97) with no signal, and "bc" inserted in buffer | 4479 (tst)^Jabc^G ==> ((quit) 97) with no signal, and "bc" inserted in buffer |
4568 | |
4569 ; with sit-for only do the 2nd test. | |
4570 ; Do all 3 tests with (accept-proccess-output nil 20) | |
4571 | 4480 |
4572 Do this: | 4481 Do this: |
4573 (setq enable-recursive-minibuffers t | 4482 (setq enable-recursive-minibuffers t |
4574 minibuffer-max-depth nil) | 4483 minibuffer-max-depth nil) |
4575 ESC ESC ESC ESC - there are now two minibuffers active | 4484 ESC ESC ESC ESC - there are now two minibuffers active |
4581 however C-g before "Quit" is displayed should leave minibuffer active. | 4490 however C-g before "Quit" is displayed should leave minibuffer active. |
4582 | 4491 |
4583 ;do it all in both v18 and v19 and make sure all results are the same. | 4492 ;do it all in both v18 and v19 and make sure all results are the same. |
4584 ;all of these cases matter a lot, but some in quite subtle ways. | 4493 ;all of these cases matter a lot, but some in quite subtle ways. |
4585 */ | 4494 */ |
4586 | |
4587 /* | |
4588 Additional test cases for accept-process-output, sleep-for, sit-for. | |
4589 Be sure you do all of the above checking for C-g and focus, too! | |
4590 | |
4591 ; Make sure that timer handlers are run during, not after sit-for: | |
4592 (defun timer-check () | |
4593 (add-timeout 2 '(lambda (ignore) (message "timer ran")) nil) | |
4594 (sit-for 5) | |
4595 (message "after sit-for")) | |
4596 | |
4597 ; The first message should appear after 2 seconds, and the final message | |
4598 ; 3 seconds after that. | |
4599 ; repeat above test with (sleep-for 5) and (accept-process-output nil 5) | |
4600 | |
4601 | |
4602 | |
4603 ; Make sure that process filters are run during, not after sit-for. | |
4604 (defun fubar () | |
4605 (message "sit-for = %s" (sit-for 30))) | |
4606 (add-hook 'post-command-hook 'fubar) | |
4607 | |
4608 ; Now type M-x shell RET | |
4609 ; wait for the shell prompt then send: ls RET | |
4610 ; the output of ls should fill immediately, and not wait 30 seconds. | |
4611 | |
4612 ; repeat above test with (sleep-for 30) and (accept-process-output nil 30) | |
4613 | |
4614 | |
4615 | |
4616 ; Make sure that recursive invocations return immediately: | |
4617 (defmacro test-diff-time (start end) | |
4618 `(+ (* (- (car ,end) (car ,start)) 65536.0) | |
4619 (- (cadr ,end) (cadr ,start)) | |
4620 (/ (- (caddr ,end) (caddr ,start)) 1000000.0))) | |
4621 | |
4622 (defun testee (ignore) | |
4623 (sit-for 10)) | |
4624 | |
4625 (defun test-them () | |
4626 (let ((start (current-time)) | |
4627 end) | |
4628 (add-timeout 2 'testee nil) | |
4629 (sit-for 5) | |
4630 (add-timeout 2 'testee nil) | |
4631 (sleep-for 5) | |
4632 (add-timeout 2 'testee nil) | |
4633 (accept-process-output nil 5) | |
4634 (setq end (current-time)) | |
4635 (test-diff-time start end))) | |
4636 | |
4637 (test-them) should sit for 15 seconds. | |
4638 Repeat with testee set to sleep-for and accept-process-output. | |
4639 These should each delay 36 seconds. | |
4640 | |
4641 */ |