aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1996-01-29 04:53:02 +0000
committerRichard M. Stallman1996-01-29 04:53:02 +0000
commitc04cbc3b12665ec8f06c12f6c0be2680523c39c1 (patch)
tree44fd83fc4c61362f07e89e3e44b1b9a05ecb8584 /src
parent038328930df6c0bf12eea61e5ab6ed57b6e94b40 (diff)
downloademacs-c04cbc3b12665ec8f06c12f6c0be2680523c39c1.tar.gz
emacs-c04cbc3b12665ec8f06c12f6c0be2680523c39c1.zip
(Qtimer_event): New symbol.
(read_char, kbd_buffer_get_event): Don't sleep past the next timer. (readable_events, kbd_buffer_get_event): Check for timer events. (make_lispy_event): Handle timer events. (timer_check): New function. (Vtimer_list): New variable. (syms_of_keyboard): Set up Qtimer_event and Vtimer_list.
Diffstat (limited to 'src')
-rw-r--r--src/keyboard.c128
1 files changed, 124 insertions, 4 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index f12da3ad580..3dd9304a577 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1,5 +1,5 @@
1/* Keyboard and mouse input; editor command loop. 1/* Keyboard and mouse input; editor command loop.
2 Copyright (C) 1985,86,87,88,89,93,94,95 Free Software Foundation, Inc. 2 Copyright (C) 1985,86,87,88,89,93,94,95,96 Free Software Foundation, Inc.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
5 5
@@ -435,6 +435,7 @@ Lisp_Object Qmake_frame_visible;
435/* Symbols to denote kinds of events. */ 435/* Symbols to denote kinds of events. */
436Lisp_Object Qfunction_key; 436Lisp_Object Qfunction_key;
437Lisp_Object Qmouse_click; 437Lisp_Object Qmouse_click;
438Lisp_Object Qtimer_event;
438/* Lisp_Object Qmouse_movement; - also an event header */ 439/* Lisp_Object Qmouse_movement; - also an event header */
439 440
440/* Properties of event headers. */ 441/* Properties of event headers. */
@@ -467,11 +468,15 @@ extern Lisp_Object Qmenu_enable;
467Lisp_Object recursive_edit_unwind (), command_loop (); 468Lisp_Object recursive_edit_unwind (), command_loop ();
468Lisp_Object Fthis_command_keys (); 469Lisp_Object Fthis_command_keys ();
469Lisp_Object Qextended_command_history; 470Lisp_Object Qextended_command_history;
471EMACS_TIME timer_check ();
470 472
471extern char *x_get_keysym_name (); 473extern char *x_get_keysym_name ();
472 474
473Lisp_Object Qpolling_period; 475Lisp_Object Qpolling_period;
474 476
477/* List of active timers. Appears in order of next scheduled event. */
478Lisp_Object Vtimer_list;
479
475extern Lisp_Object Vprint_level, Vprint_length; 480extern Lisp_Object Vprint_level, Vprint_length;
476 481
477/* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt 482/* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt
@@ -1883,11 +1888,25 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
1883 && XINT (Vauto_save_timeout) > 0) 1888 && XINT (Vauto_save_timeout) > 0)
1884 { 1889 {
1885 Lisp_Object tem0; 1890 Lisp_Object tem0;
1886 int delay = delay_level * XFASTINT (Vauto_save_timeout) / 4; 1891 EMACS_TIME timer_delay;
1892 EMACS_TIME delay, difference;
1893
1894 EMACS_SET_SECS (delay,
1895 delay_level * XFASTINT (Vauto_save_timeout) / 4);
1896 EMACS_SET_USECS (delay, 0);
1897
1898 /* Don't wait longer than until the next timer will fire. */
1899 timer_delay = timer_check (0);
1900 if (! EMACS_TIME_NEG_P (timer_delay))
1901 {
1902 EMACS_SUB_TIME (difference, timer_delay, delay);
1903 if (EMACS_TIME_NEG_P (difference))
1904 delay = timer_delay;
1905 }
1887 1906
1888 save_getcjmp (save_jump); 1907 save_getcjmp (save_jump);
1889 restore_getcjmp (local_getcjmp); 1908 restore_getcjmp (local_getcjmp);
1890 tem0 = sit_for (delay, 0, 1, 1); 1909 tem0 = sit_for (EMACS_SECS (delay), EMACS_USECS (delay), 1, 1);
1891 restore_getcjmp (save_jump); 1910 restore_getcjmp (save_jump);
1892 1911
1893 if (EQ (tem0, Qt)) 1912 if (EQ (tem0, Qt))
@@ -2322,6 +2341,7 @@ some_mouse_moved ()
2322static int 2341static int
2323readable_events () 2342readable_events ()
2324{ 2343{
2344 timer_check (0);
2325 if (kbd_fetch_ptr != kbd_store_ptr) 2345 if (kbd_fetch_ptr != kbd_store_ptr)
2326 return 1; 2346 return 1;
2327#ifdef HAVE_MOUSE 2347#ifdef HAVE_MOUSE
@@ -2501,6 +2521,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
2501{ 2521{
2502 register int c; 2522 register int c;
2503 Lisp_Object obj; 2523 Lisp_Object obj;
2524 EMACS_TIME next_timer_delay;
2504 2525
2505 if (noninteractive) 2526 if (noninteractive)
2506 { 2527 {
@@ -2520,6 +2541,17 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
2520 break; 2541 break;
2521#endif 2542#endif
2522 2543
2544 /* Check when the next timer fires. */
2545 next_timer_delay = timer_check (0);
2546 if (EMACS_SECS (next_timer_delay) == 0
2547 && EMACS_USECS (next_timer_delay) == 0)
2548 break;
2549 if (EMACS_TIME_NEG_P (next_timer_delay))
2550 {
2551 EMACS_SET_SECS (next_timer_delay, 0);
2552 EMACS_SET_USECS (next_timer_delay, 0);
2553 }
2554
2523 /* If the quit flag is set, then read_char will return 2555 /* If the quit flag is set, then read_char will return
2524 quit_char, so that counts as "available input." */ 2556 quit_char, so that counts as "available input." */
2525 if (!NILP (Vquit_flag)) 2557 if (!NILP (Vquit_flag))
@@ -2545,7 +2577,9 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
2545 Lisp_Object minus_one; 2577 Lisp_Object minus_one;
2546 2578
2547 XSETINT (minus_one, -1); 2579 XSETINT (minus_one, -1);
2548 wait_reading_process_input (0, 0, minus_one, 1); 2580 wait_reading_process_input (EMACS_SECS (next_timer_delay),
2581 EMACS_USECS (next_timer_delay),
2582 minus_one, 1);
2549 2583
2550 if (!interrupt_input && kbd_fetch_ptr == kbd_store_ptr) 2584 if (!interrupt_input && kbd_fetch_ptr == kbd_store_ptr)
2551 /* Pass 1 for EXPECT since we just waited to have input. */ 2585 /* Pass 1 for EXPECT since we just waited to have input. */
@@ -2830,6 +2864,83 @@ swallow_events ()
2830 get_input_pending (&input_pending); 2864 get_input_pending (&input_pending);
2831} 2865}
2832 2866
2867/* Check whether a timer has fired. To prevent larger problems we simply
2868 disregard elements that are not proper timers. Do not make a circular
2869 timer list for the time being.
2870
2871 Returns the number of seconds to wait until the next timer fires. If a
2872 timer is triggering now, return zero seconds.
2873 If no timer is active, return -1 seconds.
2874
2875 If a timer is triggering now, either queue a timer-event
2876 or run the timer's handler function if DO_IT_NOW is nonzero. */
2877
2878EMACS_TIME
2879timer_check (do_it_now)
2880 int do_it_now;
2881{
2882 EMACS_TIME nexttime;
2883 EMACS_TIME now;
2884 Lisp_Object timers = Vtimer_list;
2885
2886 EMACS_GET_TIME (now);
2887 EMACS_SET_SECS (nexttime, -1);
2888 EMACS_SET_USECS (nexttime, -1);
2889
2890 while (CONSP (timers))
2891 {
2892 int triggertime;
2893 Lisp_Object timer, *vector;
2894 EMACS_TIME timer_time;
2895 EMACS_TIME difference;
2896
2897 timer = XCONS (timers)->car;
2898 timers = XCONS (timers)->cdr;
2899
2900 if (!VECTORP (timer) || XVECTOR (timer)->size != 7)
2901 continue;
2902 vector = XVECTOR (timer)->contents;
2903
2904 if (!INTEGERP (vector[1]) || !INTEGERP (vector[2])
2905 || !INTEGERP (vector[3]))
2906 continue;
2907
2908 EMACS_SET_SECS (timer_time,
2909 (XINT (vector[1]) << 16) | (XINT (vector[2])));
2910 EMACS_SET_USECS (timer_time, XINT (vector[3]));
2911 EMACS_SUB_TIME (difference, timer_time, now);
2912 if (EMACS_TIME_NEG_P (difference))
2913 {
2914 if (NILP (vector[0]))
2915 {
2916 if (do_it_now)
2917 apply1 (vector[5], vector[6]);
2918 else
2919 {
2920 struct input_event event;
2921
2922 event.kind = timer_event;
2923 event.modifiers = 0;
2924 event.x = event.y = Qnil;
2925 event.timestamp = triggertime;
2926 /* Store the timer in the frame slot. */
2927 event.frame_or_window = Fcons (Fselected_frame (), timer);
2928 kbd_buffer_store_event (&event);
2929
2930 /* Mark the timer as triggered to prevent problems if the lisp
2931 code fails to reschedule it right. */
2932 vector[0] = Qt;
2933 EMACS_SET_SECS (nexttime, 0);
2934 EMACS_SET_USECS (nexttime, 0);
2935 }
2936 }
2937 }
2938 else
2939 return difference;
2940 }
2941 return nexttime;
2942}
2943
2833/* Caches for modify_event_symbol. */ 2944/* Caches for modify_event_symbol. */
2834static Lisp_Object accent_key_syms; 2945static Lisp_Object accent_key_syms;
2835static Lisp_Object func_key_syms; 2946static Lisp_Object func_key_syms;
@@ -3297,6 +3408,9 @@ make_lispy_event (event)
3297 / sizeof (lispy_function_keys[0]))); 3408 / sizeof (lispy_function_keys[0])));
3298 break; 3409 break;
3299 3410
3411 case timer_event:
3412 return Fcons (Qtimer_event, Fcdr (event->frame_or_window));
3413
3300#ifdef HAVE_MOUSE 3414#ifdef HAVE_MOUSE
3301 /* A mouse click. Figure out where it is, decide whether it's 3415 /* A mouse click. Figure out where it is, decide whether it's
3302 a press, click or drag, and build the appropriate structure. */ 3416 a press, click or drag, and build the appropriate structure. */
@@ -7299,6 +7413,8 @@ syms_of_keyboard ()
7299 staticpro (&Qfunction_key); 7413 staticpro (&Qfunction_key);
7300 Qmouse_click = intern ("mouse-click"); 7414 Qmouse_click = intern ("mouse-click");
7301 staticpro (&Qmouse_click); 7415 staticpro (&Qmouse_click);
7416 Qtimer_event = intern ("timer-event");
7417 staticpro (&Qtimer_event);
7302 7418
7303 Qmenu_enable = intern ("menu-enable"); 7419 Qmenu_enable = intern ("menu-enable");
7304 staticpro (&Qmenu_enable); 7420 staticpro (&Qmenu_enable);
@@ -7664,6 +7780,10 @@ If the value is non-nil and not a number, we wait 2 seconds.");
7664 DEFVAR_LISP ("column-number-mode", &Vcolumn_number_mode, 7780 DEFVAR_LISP ("column-number-mode", &Vcolumn_number_mode,
7665 "Non-nil enables display of the current column number in the mode line."); 7781 "Non-nil enables display of the current column number in the mode line.");
7666 Vcolumn_number_mode = Qnil; 7782 Vcolumn_number_mode = Qnil;
7783
7784 DEFVAR_LISP ("timer-list", &Vtimer_list,
7785 "List of active timers in order of increasing time");
7786 Vtimer_list = Qnil;
7667} 7787}
7668 7788
7669keys_of_keyboard () 7789keys_of_keyboard ()