(displaying-byte-compile-warnings): Show
[bpt/emacs.git] / src / keyboard.c
index 8868577..bf5643d 100644 (file)
@@ -1,5 +1,5 @@
 /* Keyboard and mouse input; editor command loop.
-   Copyright (C) 1985,86,87,88,89,93,94,95,96 Free Software Foundation, Inc.
+   Copyright (C) 1985,86,87,88,89,93,94,95,96,97 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -32,6 +32,7 @@ Boston, MA 02111-1307, USA.  */
 #include "window.h"
 #include "commands.h"
 #include "buffer.h"
+#include "charset.h"
 #include "disptab.h"
 #include "dispextern.h"
 #include "keyboard.h"
@@ -170,6 +171,9 @@ static int inhibit_local_menu_bar_menus;
 /* Nonzero means C-g should cause immediate error-signal.  */
 int immediate_quit;
 
+/* The user's ERASE setting.  */
+Lisp_Object Vtty_erase_char;
+
 /* Character to recognize as the help char.  */
 Lisp_Object Vhelp_char;
 
@@ -268,17 +272,17 @@ static int last_non_minibuf_size;
 static Lisp_Object Vauto_save_timeout;
 
 /* Total number of times read_char has returned.  */
-int num_input_chars;
+int num_input_events;
 
 /* Total number of times read_char has returned, outside of macros.  */
-int num_nonmacro_input_chars;
+int num_nonmacro_input_events;
 
 /* Auto-save automatically when this many characters have been typed
    since the last time.  */
 
 static int auto_save_interval;
 
-/* Value of num_nonmacro_input_chars as of last auto save.  */
+/* Value of num_nonmacro_input_events as of last auto save.  */
 
 int last_auto_save;
 
@@ -313,6 +317,7 @@ Lisp_Object Qself_insert_command;
 Lisp_Object Qforward_char;
 Lisp_Object Qbackward_char;
 Lisp_Object Qundefined;
+Lisp_Object Qtimer_event_handler;
 
 /* read_key_sequence stores here the command definition of the
    key sequence that it reads.  */
@@ -339,6 +344,8 @@ Lisp_Object Vdeactivate_mark;
 Lisp_Object Vlucid_menu_bar_dirty_flag;
 Lisp_Object Qrecompute_lucid_menubar, Qactivate_menubar_hook;
 
+Lisp_Object Qecho_area_clear_hook;
+
 /* Hooks to run before and after each command.  */
 Lisp_Object Qpre_command_hook, Vpre_command_hook;
 Lisp_Object Qpost_command_hook, Vpost_command_hook;
@@ -437,7 +444,9 @@ Lisp_Object Qmake_frame_visible;
 /* Symbols to denote kinds of events.  */
 Lisp_Object Qfunction_key;
 Lisp_Object Qmouse_click;
-Lisp_Object Qtimer_event;
+#ifdef WINDOWSNT
+Lisp_Object Qmouse_wheel;
+#endif
 /* Lisp_Object Qmouse_movement; - also an event header */
 
 /* Properties of event headers.  */
@@ -474,6 +483,10 @@ EMACS_TIME timer_check ();
 
 extern char *x_get_keysym_name ();
 
+static void record_menu_key ();
+
+void swallow_events ();
+
 Lisp_Object Qpolling_period;
 
 /* List of absolute timers.  Appears in order of next scheduled event.  */
@@ -487,6 +500,8 @@ int timers_run;
 
 extern Lisp_Object Vprint_level, Vprint_length;
 
+extern nonascii_insert_offset;
+
 /* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt
    happens.  */
 EMACS_TIME *input_available_clear_time;
@@ -762,7 +777,7 @@ recursive_edit_1 ()
 
 record_auto_save ()
 {
-  last_auto_save = num_nonmacro_input_chars;
+  last_auto_save = num_nonmacro_input_events;
 }
 
 /* Make an auto save happen as soon as possible at command level.  */
@@ -1066,7 +1081,7 @@ Lisp_Object
 command_loop_1 ()
 {
   Lisp_Object cmd, tem;
-  int lose;
+  int lose, lose2;
   int nonundocount;
   Lisp_Object keybuf[30];
   int i;
@@ -1102,7 +1117,7 @@ command_loop_1 ()
     {
       if (NILP (Vunread_command_events)
          && NILP (Vexecuting_macro)
-         && !NILP (sit_for (0, post_command_idle_delay, 0, 1)))
+         && !NILP (sit_for (0, post_command_idle_delay, 0, 1, 1)))
        safe_run_hooks (Qpost_command_idle_hook);
     }
 
@@ -1138,7 +1153,8 @@ command_loop_1 ()
 
          Fsit_for (make_number (2), Qnil, Qnil);
          /* Clear the echo area.  */
-         message2 (0);
+         message2 (0, 0);
+         safe_run_hooks (Qecho_area_clear_hook);
 
          unbind_to (count, Qnil);
 
@@ -1177,7 +1193,7 @@ command_loop_1 ()
 
       /* Read next key sequence; i gets its length.  */
       i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0],
-                            Qnil, 0, 1);
+                            Qnil, 0, 1, 1);
 
       /* A filter may have run while we were reading the input.  */
       if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
@@ -1262,14 +1278,17 @@ command_loop_1 ()
                {
                   struct Lisp_Char_Table *dp
                    = window_display_table (XWINDOW (selected_window));
-                 lose = FETCH_CHAR (PT);
-                 SET_PT (PT + 1);
+                 lose = FETCH_BYTE (PT);
+                 SET_PT (forward_point (1));
                  if ((dp
                       ? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
                          ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
                           : (NILP (DISP_CHAR_VECTOR (dp, lose))
                              && (lose >= 0x20 && lose < 0x7f)))
                       : (lose >= 0x20 && lose < 0x7f))
+                     /* To extract the case of continuation on
+                         wide-column characters.  */
+                     && (WIDTH_BY_CHAR_HEAD (FETCH_BYTE (PT)) == 1)
                      && (XFASTINT (XWINDOW (selected_window)->last_modified)
                          >= MODIFF)
                      && (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
@@ -1288,8 +1307,8 @@ command_loop_1 ()
                {
                   struct Lisp_Char_Table *dp
                    = window_display_table (XWINDOW (selected_window));
-                 SET_PT (PT - 1);
-                 lose = FETCH_CHAR (PT);
+                 SET_PT (forward_point (-1));
+                 lose = FETCH_BYTE (PT);
                  if ((dp
                       ? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
                          ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
@@ -1314,7 +1333,7 @@ command_loop_1 ()
                       /* Try this optimization only on ascii keystrokes.  */
                       && INTEGERP (last_command_char))
                {
-                 unsigned char c = XINT (last_command_char);
+                 unsigned int c = XINT (last_command_char);
                  int value;
 
                  if (NILP (Vexecuting_macro)
@@ -1346,12 +1365,19 @@ command_loop_1 ()
                    nonundocount = 0;
 
                  if (!lose
-                     && (PT == ZV || FETCH_CHAR (PT) == '\n'))
+                     && (PT == ZV || FETCH_BYTE (PT) == '\n'))
                    {
                      struct Lisp_Char_Table *dp
                        = window_display_table (XWINDOW (selected_window));
                      int lose = c;
 
+                     /* Add the offset to the character, for Finsert_char.
+                        We pass internal_self_insert the unmodified character
+                        because it itself does this offsetting.  */
+                     if (lose >= 0200 && lose <= 0377
+                         && ! NILP (current_buffer->enable_multibyte_characters))
+                       lose += nonascii_insert_offset;
+
                      if (dp)
                        {
                          Lisp_Object obj;
@@ -1426,7 +1452,7 @@ command_loop_1 ()
        {
          if (NILP (Vunread_command_events)
              && NILP (Vexecuting_macro)
-             && !NILP (sit_for (0, post_command_idle_delay, 0, 1)))
+             && !NILP (sit_for (0, post_command_idle_delay, 0, 1, 1)))
            safe_run_hooks (Qpost_command_idle_hook);
        }
 
@@ -1684,17 +1710,22 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
      Lisp_Object prev_event;
      int *used_mouse_menu;
 {
-  register Lisp_Object c;
+  Lisp_Object c;
   int count;
   jmp_buf local_getcjmp;
   jmp_buf save_jump;
   int key_already_recorded = 0;
   Lisp_Object tem, save;
   Lisp_Object also_record;
+  struct gcpro gcpro1;
+
   also_record = Qnil;
 
   before_command_key_count = this_command_key_count;
   before_command_echo_length = echo_length ();
+  c = Qnil;
+
+  GCPRO1 (c);
 
  retry:
 
@@ -1752,7 +1783,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
          || executing_macro_index >= XFASTINT (Flength (Vexecuting_macro)))
        {
          XSETINT (c, -1);
-         return c;
+         RETURN_UNGCPRO (c);
        }
 
       c = Faref (Vexecuting_macro, make_number (executing_macro_index));
@@ -1775,9 +1806,15 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
       goto reread_first;
     }
 
-  if (commandflag >= 0 && !input_pending
-      && !detect_input_pending_run_timers (0))
-    redisplay ();
+  if (commandflag >= 0)
+    {
+      if (input_pending
+         || detect_input_pending_run_timers (0))
+       swallow_events (0);
+
+      if (!input_pending)
+       redisplay ();
+    }
 
   /* Message turns off echoing unless more keystrokes turn it on again. */
   if (echo_area_glyphs && *echo_area_glyphs
@@ -1841,6 +1878,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
            *tailp = Fcons (c, Qnil);
            kb->kbd_queue_has_data = 1;
            current_kboard = kb;
+           /* This is going to exit from read_char
+              so we had better get rid of this frame's stuff.  */
+           UNGCPRO;
            longjmp (wrong_kboard_jmpbuf, 1);
          }
       }
@@ -1871,9 +1911,10 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
        {
          save_getcjmp (save_jump);
          restore_getcjmp (local_getcjmp);
-         tem0 = sit_for (echo_keystrokes, 0, 1, 1);
+         tem0 = sit_for (echo_keystrokes, 0, 1, 1, 0);
          restore_getcjmp (save_jump);
-         if (EQ (tem0, Qt))
+         if (EQ (tem0, Qt)
+             && ! CONSP (Vunread_command_events))
            echo_now ();
        }
     }
@@ -1882,7 +1923,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
 
   if (commandflag != 0
       && auto_save_interval > 0
-      && num_nonmacro_input_chars - last_auto_save > max (auto_save_interval, 20)
+      && num_nonmacro_input_events - last_auto_save > max (auto_save_interval, 20)
       && !detect_input_pending_run_timers (0))
     {
       Fdo_auto_save (Qnil, Qnil);
@@ -1902,7 +1943,14 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
       /* Don't bring up a menu if we already have another event.  */
       && NILP (Vunread_command_events)
       && unread_command_char < 0)
-    c = read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu);
+    {
+      c = read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu);
+
+      /* Now that we have read an event, Emacs is not idle.  */
+      timer_stop_idle ();
+
+      RETURN_UNGCPRO (c);
+    }
 
   /* Maybe autosave and/or garbage collect due to idleness.  */
 
@@ -1924,7 +1972,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
 
       /* Auto save if enough time goes by without input.  */
       if (commandflag != 0
-         && num_nonmacro_input_chars > last_auto_save
+         && num_nonmacro_input_events > last_auto_save
          && INTEGERP (Vauto_save_timeout)
          && XINT (Vauto_save_timeout) > 0)
        {
@@ -1933,10 +1981,11 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
          save_getcjmp (save_jump);
          restore_getcjmp (local_getcjmp);
          tem0 = sit_for (delay_level * XFASTINT (Vauto_save_timeout) / 4,
-                         0, 1, 1);
+                         0, 1, 1, 0);
          restore_getcjmp (save_jump);
 
-         if (EQ (tem0, Qt))
+         if (EQ (tem0, Qt)
+             && ! CONSP (Vunread_command_events))
            {
              Fdo_auto_save (Qnil, Qnil);
 
@@ -1952,6 +2001,14 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
        }
     }
 
+  /* If this has become non-nil here, it has been set by a timer
+     or sentinel or filter.  */
+  if (CONSP (Vunread_command_events))
+    {
+      c = XCONS (Vunread_command_events)->car;
+      Vunread_command_events = XCONS (Vunread_command_events)->cdr;
+    }
+
   /* Read something from current KBOARD's side queue, if possible.  */
 
   if (NILP (c))
@@ -1989,6 +2046,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
        if (kb->kbd_queue_has_data)
          {
            current_kboard = kb;
+           /* This is going to exit from read_char
+              so we had better get rid of this frame's stuff.  */
+           UNGCPRO;
            longjmp (wrong_kboard_jmpbuf, 1);
          }
     }
@@ -2026,6 +2086,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
          if (single_kboard)
            goto wrong_kboard;
          current_kboard = kb;
+         /* This is going to exit from read_char
+            so we had better get rid of this frame's stuff.  */
+         UNGCPRO;
          longjmp (wrong_kboard_jmpbuf, 1);
        }
 #endif
@@ -2051,10 +2114,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
 
  non_reread:
 
-  /* Now that we have read an event, Emacs is not idle--
-     unless the event was a timer event (not used now).  */
-  if (! (CONSP (c) && EQ (XCONS (c)->car, Qtimer_event)))
-    timer_stop_idle ();
+  timer_stop_idle ();
 
   start_polling ();
 
@@ -2070,12 +2130,10 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
  non_reread_1:
 
   /* Buffer switch events are only for internal wakeups
-     so don't show them to the user.  */
-  if (BUFFERP (c))
-    return c;
-
-  if (key_already_recorded)
-    return c;
+     so don't show them to the user.
+     Also, don't record a key if we already did.  */
+  if (BUFFERP (c) || key_already_recorded)
+    RETURN_UNGCPRO (c);
 
   /* Process special events within read_char
      and loop around to read another event.  */
@@ -2100,6 +2158,8 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
     }
 
   /* Wipe the echo area.  */
+  if (echo_area_glyphs)
+    safe_run_hooks (Qecho_area_clear_hook);
   echo_area_glyphs = 0;
 
   /* Handle things that only apply to characters.  */
@@ -2107,7 +2167,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
     {
       /* If kbd_buffer_get_event gave us an EOF, return that.  */
       if (XINT (c) == -1)
-       return c;
+       RETURN_UNGCPRO (c);
 
       if (STRINGP (Vkeyboard_translate_table)
          && XSTRING (Vkeyboard_translate_table)->size > (unsigned) XFASTINT (c))
@@ -2155,6 +2215,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
 
  from_macro:
  reread_first:
+
   before_command_key_count = this_command_key_count;
   before_command_echo_length = echo_length ();
 
@@ -2179,7 +2240,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
   /* Re-reading in the middle of a command */
  reread:
   last_input_char = c;
-  num_input_chars++;
+  num_input_events++;
 
   /* Process the help character specially if enabled */
   if (!NILP (Vhelp_form) && help_char_p (c))
@@ -2211,7 +2272,40 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
        }
     }
 
-  return c;
+  RETURN_UNGCPRO (c);
+}
+
+/* Record a key that came from a mouse menu.
+   Record it for echoing, for this-command-keys, and so on.  */
+
+static void
+record_menu_key (c)
+     Lisp_Object c;
+{
+  /* Wipe the echo area.  */
+  echo_area_glyphs = 0;
+
+  record_char (c);
+
+  before_command_key_count = this_command_key_count;
+  before_command_echo_length = echo_length ();
+
+  /* Don't echo mouse motion events.  */
+  if (echo_keystrokes)
+    {
+      echo_char (c);
+
+      /* Once we reread a character, echoing can happen
+        the next time we pause to read a new one.  */
+      ok_to_echo_at_next_pause = 0;
+    }
+
+  /* Record this character as part of the current key.  */
+  add_command_key (c);
+
+  /* Re-reading in the middle of a command */
+  last_input_char = c;
+  num_input_events++;
 }
 
 /* Return 1 if should recognize C as "the help character".  */
@@ -2275,7 +2369,7 @@ record_char (c)
 
   store_kbd_macro_char (c);
 
-  num_nonmacro_input_chars++;
+  num_nonmacro_input_events++;
 }
 
 Lisp_Object
@@ -2547,6 +2641,28 @@ kbd_buffer_store_event (event)
     }
 }
 \f
+/* Discard any mouse events in the event buffer by setting them to
+   no_event.  */
+void
+discard_mouse_events ()
+{
+  struct input_event *sp;
+  for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++)
+    {
+      if (sp == kbd_buffer + KBD_BUFFER_SIZE)
+       sp = kbd_buffer;
+
+      if (sp->kind == mouse_click
+#ifdef WINDOWSNT
+         || sp->kind == w32_scroll_bar_click
+#endif
+         || sp->kind == scroll_bar_click)
+       {
+         sp->kind = no_event;
+       }
+    }
+}
+\f
 /* Read one event from the event buffer, waiting if necessary.
    The value is a Lisp object representing the event.
    The value is nil for an event that should be ignored,
@@ -2614,6 +2730,15 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
 #endif /* not VMS */
     }
 
+  if (CONSP (Vunread_command_events))
+    {
+      Lisp_Object first;
+      first = XCONS (Vunread_command_events)->car;
+      Vunread_command_events = XCONS (Vunread_command_events)->cdr;
+      *kbp = current_kboard;
+      return first;
+    }
+
   /* At this point, we know that there is a readable event available
      somewhere.  If the event queue is empty, then there must be a
      mouse movement enabled and available.  */
@@ -2704,7 +2829,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
          XSETBUFFER (obj, current_buffer);
          kbd_fetch_ptr = event + 1;
        }
-#ifdef USE_X_TOOLKIT
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
       else if (event->kind == menu_bar_activate_event)
        {
          kbd_fetch_ptr = event + 1;
@@ -2719,6 +2844,8 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
         (They shouldn't otherwise be found in the buffer,
         but on some machines it appears they do show up
         even without MULTI_KBOARD.)  */
+      /* On Windows NT/9X, no_event is used to delete extraneous
+         mouse events during a popup-menu call.  */
       else if (event->kind == no_event)
        kbd_fetch_ptr = event + 1;
 
@@ -2881,29 +3008,6 @@ swallow_events (do_display)
          abort ();
 #endif
        }
-      /* Note that timer_event is currently never used.  */
-      else if (event->kind == timer_event)
-       {
-         Lisp_Object tem, lisp_event;
-         int was_locked = single_kboard;
-
-         tem = get_keymap_1 (Vspecial_event_map, 0, 0);
-         tem = get_keyelt (access_keymap (tem, Qtimer_event, 0, 0),
-                           1);
-         lisp_event = Fcons (Qtimer_event,
-                             Fcons (Fcdr (event->frame_or_window), Qnil));
-         kbd_fetch_ptr = event + 1;
-         if (kbd_fetch_ptr == kbd_store_ptr)
-           input_pending = 0;
-         Fcommand_execute (tem, Qnil, Fvector (1, &lisp_event), Qt);
-         timers_run++;
-         if (do_display)
-           redisplay_preserve_echo_area ();
-
-         /* Resume allowing input from any kboard, if that was true before.  */
-         if (!was_locked)
-           any_kboard_state ();
-       }
       else
        break;
     }
@@ -2974,8 +3078,6 @@ timer_check (do_it_now)
   EMACS_TIME nexttime;
   EMACS_TIME now, idleness_now;
   Lisp_Object timers, idle_timers, chosen_timer;
-  /* Nonzero if we generate some events.  */
-  int events_generated = 0;
   struct gcpro gcpro1, gcpro2, gcpro3;
 
   EMACS_SET_SECS (nexttime, -1);
@@ -3112,64 +3214,27 @@ timer_check (do_it_now)
        {
          if (NILP (vector[0]))
            {
+             Lisp_Object tem;
+             int was_locked = single_kboard;
+             int count = specpdl_ptr - specpdl;
+
              /* Mark the timer as triggered to prevent problems if the lisp
                 code fails to reschedule it right.  */
              vector[0] = Qt;
 
-             /* Run the timer or queue a timer event.  */
-             if (1)
-               {
-                 Lisp_Object tem, event;
-                 int was_locked = single_kboard;
-                 int count = specpdl_ptr - specpdl;
+             specbind (Qinhibit_quit, Qt);
 
-                 specbind (Qinhibit_quit, Qt);
+             call1 (Qtimer_event_handler, chosen_timer);
+             timers_run++;
 
-                 tem = get_keymap_1 (Vspecial_event_map, 0, 0);
-                 tem = get_keyelt (access_keymap (tem, Qtimer_event, 0, 0),
-                                   1);
-                 event = Fcons (Qtimer_event, Fcons (chosen_timer, Qnil));
-                 Fcommand_execute (tem, Qnil, Fvector (1, &event), Qt);
-                 timers_run++;
+             unbind_to (count, Qnil);
 
-                 unbind_to (count, Qnil);
+             /* Resume allowing input from any kboard, if that was true before.  */
+             if (!was_locked)
+               any_kboard_state ();
 
-                 /* Resume allowing input from any kboard, if that was true before.  */
-                 if (!was_locked)
-                   any_kboard_state ();
-
-                 /* Since we have handled the event,
-                    we don't need to tell the caller to wake up and do it.  */
-               }
-#if 0
-             else
-               {
-                 /* Generate a timer event so the caller will handle it.  */
-                 struct input_event event;
-
-                 event.kind = timer_event;
-                 event.modifiers = 0;
-                 event.x = event.y = Qnil;
-                 event.timestamp = triggertime;
-                 /* Store the timer in the frame slot.  */
-                 event.frame_or_window
-                   = Fcons (Fselected_frame (), chosen_timer);
-                 kbd_buffer_store_event (&event);
-
-                 last_timer_event = event;
-
-                 /* Tell caller to handle this event right away.  */
-                 events_generated = 1;
-                 EMACS_SET_SECS (nexttime, 0);
-                 EMACS_SET_USECS (nexttime, 0);
-
-                 /* Don't queue more than one event at once.
-                    When Emacs is ready for another, it will
-                    queue the next one.  */
-                 UNGCPRO;
-                 return nexttime;
-               }
-#endif /* 0 */
+             /* Since we have handled the event,
+                we don't need to tell the caller to wake up and do it.  */
            }
        }
       else
@@ -3177,10 +3242,6 @@ timer_check (do_it_now)
           return the amount of time to wait before it is ripe.  */
        {
          UNGCPRO;
-         /* But if we generated an event,
-            tell the caller to handle it now.  */
-         if (events_generated)
-           return nexttime;
          return difference;
        }
     }
@@ -3195,6 +3256,9 @@ timer_check (do_it_now)
 static Lisp_Object accent_key_syms;
 static Lisp_Object func_key_syms;
 static Lisp_Object mouse_syms;
+#ifdef WINDOWSNT
+static Lisp_Object mouse_wheel_syms;
+#endif
 
 /* This is a list of keysym codes for special "accent" characters.
    It parallels lispy_accent_keys.  */
@@ -3449,7 +3513,42 @@ char *lispy_function_keys[] =
     "oem_clear",     /* VK_OEM_CLEAR      0xFE */
   };
 
-#else
+#else /* not HAVE_NTGUI */
+
+#ifdef XK_kana_A
+static char *lispy_kana_keys[] =
+  {
+    /* X Keysym value */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,   /* 0x400 .. 0x40f */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,   /* 0x410 .. 0x41f */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,   /* 0x420 .. 0x42f */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,   /* 0x430 .. 0x43f */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,   /* 0x440 .. 0x44f */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,   /* 0x450 .. 0x45f */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,   /* 0x460 .. 0x46f */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,"overline",0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,   /* 0x480 .. 0x48f */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,   /* 0x490 .. 0x49f */
+    0, "kana-fullstop", "kana-openingbracket", "kana-closingbracket", 
+    "kana-comma", "kana-conjunctive", "kana-WO", "kana-a",
+    "kana-i", "kana-u", "kana-e", "kana-o",
+    "kana-ya", "kana-yu", "kana-yo", "kana-tsu",
+    "prolongedsound", "kana-A", "kana-I", "kana-U",
+    "kana-E", "kana-O", "kana-KA", "kana-KI",
+    "kana-KU", "kana-KE", "kana-KO", "kana-SA",
+    "kana-SHI", "kana-SU", "kana-SE", "kana-SO",
+    "kana-TA", "kana-CHI", "kana-TSU", "kana-TE",
+    "kana-TO", "kana-NA", "kana-NI", "kana-NU",
+    "kana-NE", "kana-NO", "kana-HA", "kana-HI",
+    "kana-FU", "kana-HE", "kana-HO", "kana-MA",
+    "kana-MI", "kana-MU", "kana-ME", "kana-MO",
+    "kana-YA", "kana-YU", "kana-YO", "kana-RA",
+    "kana-RI", "kana-RU", "kana-RE", "kana-RO",
+    "kana-WA", "kana-N", "voicedsound", "semivoicedsound",
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,   /* 0x4e0 .. 0x4ef */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,   /* 0x4f0 .. 0x4ff */
+  };
+#endif /* XK_kana_A */
 
 #define FUNCTION_KEY_OFFSET 0xff00
 
@@ -3472,7 +3571,8 @@ static char *lispy_function_keys[] =
     0, 0, 0, 0, 0, 0, 0,
     "escape",
     0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   /* 0xff20...2f */
+    0, "kanji", "muhenkan", 
+             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   /* 0xff20...2f */
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   /* 0xff30...3f */
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   /* 0xff40...4f */
 
@@ -3547,15 +3647,51 @@ static char *lispy_function_keys[] =
     0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0,     /* 0xfff0 */
     0, 0, 0, 0, 0, 0, 0, "delete"
-    };
+  };
 
-#endif /* HAVE_NTGUI */
+/* ISO 9995 Function and Modifier Keys; the first byte is 0xFE.  */
+#define ISO_FUNCTION_KEY_OFFSET 0xfe00
+
+static char *iso_lispy_function_keys[] =
+  {
+    0, 0, 0, 0, 0, 0, 0, 0,    /* 0xfe00 */
+    0, 0, 0, 0, 0, 0, 0, 0,    /* 0xfe08 */
+    0, 0, 0, 0, 0, 0, 0, 0,    /* 0xfe10 */
+    0, 0, 0, 0, 0, 0, 0, 0,    /* 0xfe18 */
+    "iso-lefttab",             /* 0xfe20 */
+    "iso-move-line-up", "iso-move-line-down", 
+    "iso-partial-line-up", "iso-partial-line-down", 
+    "iso-partial-space-left", "iso-partial-space-right", 
+    "iso-set-margin-left", "iso-set-margin-right", /* 0xffe27, 28 */
+    "iso-release-margin-left", "iso-release-margin-right",
+    "iso-release-both-margins",
+    "iso-fast-cursor-left", "iso-fast-cursor-right",
+    "iso-fast-cursor-up", "iso-fast-cursor-down",
+    "iso-continuous-underline", "iso-discontinuous-underline", /* 0xfe30, 31 */
+    "iso-emphasize", "iso-center-object", "iso-enter", /* ... 0xfe34 */
+  };
+
+#endif /* not HAVE_NTGUI */
 
 static char *lispy_mouse_names[] =
 {
   "mouse-1", "mouse-2", "mouse-3", "mouse-4", "mouse-5"
 };
 
+#ifdef WINDOWSNT
+/* mouse-wheel events are generated by the wheel on devices such as
+   the MS Intellimouse.  The wheel sits in between the left and right
+   mouse buttons, and is typically used to scroll or zoom the window
+   underneath the pointer.  mouse-wheel events specify the object on
+   which they operate, and a delta corresponding to the amount and
+   direction that the wheel is rotated.  Clicking the mouse-wheel
+   generates a mouse-2 event.  */
+static char *lispy_mouse_wheel_names[] = 
+{
+  "mouse-wheel"
+};
+#endif /* WINDOWSNT */
+
 /* Scroll bar parts.  */
 Lisp_Object Qabove_handle, Qhandle, Qbelow_handle;
 Lisp_Object Qup, Qdown;
@@ -3629,6 +3765,10 @@ make_lispy_event (event)
        c |= (event->modifiers
              & (meta_modifier | alt_modifier
                 | hyper_modifier | super_modifier));
+       /* Distinguish Shift-SPC from SPC.  */
+       if ((event->code & 0377) == 040
+           && event->modifiers & shift_modifier)
+         c |= shift_modifier;
        button_down_time = 0;
        XSETFASTINT (lispy_c, c);
        return lispy_c;
@@ -3663,17 +3803,33 @@ make_lispy_event (event)
                                      (unsigned)-1);
        }
 
-      return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET,
-                                 event->modifiers,
-                                 Qfunction_key, Qnil,
-                                 lispy_function_keys, &func_key_syms,
-                                 (sizeof (lispy_function_keys)
-                                  / sizeof (lispy_function_keys[0])));
-      break;
-
-      /* Note that timer_event is currently never used.  */
-    case timer_event:
-      return Fcons (Qtimer_event, Fcons (Fcdr (event->frame_or_window), Qnil));
+#ifdef XK_kana_A
+      if (event->code >= 0x400 && event->code < 0x500)
+       return modify_event_symbol (event->code - 0x400,
+                                   event->modifiers & ~shift_modifier,
+                                   Qfunction_key, Qnil,
+                                   lispy_kana_keys, &func_key_syms,
+                                   (sizeof (lispy_kana_keys)
+                                    / sizeof (lispy_kana_keys[0])));
+#endif /* XK_kana_A */
+
+#ifdef ISO_FUNCTION_KEY_OFFSET
+      if (event->code < FUNCTION_KEY_OFFSET
+         && event->code >= ISO_FUNCTION_KEY_OFFSET)
+       return modify_event_symbol (event->code - ISO_FUNCTION_KEY_OFFSET,
+                                   event->modifiers,
+                                   Qfunction_key, Qnil,
+                                   iso_lispy_function_keys, &func_key_syms,
+                                   (sizeof (iso_lispy_function_keys)
+                                    / sizeof (iso_lispy_function_keys[0])));
+      else
+#endif
+       return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET,
+                                   event->modifiers,
+                                   Qfunction_key, Qnil,
+                                   lispy_function_keys, &func_key_syms,
+                                   (sizeof (lispy_function_keys)
+                                    / sizeof (lispy_function_keys[0])));
 
 #ifdef HAVE_MOUSE
       /* A mouse click.  Figure out where it is, decide whether it's
@@ -3966,8 +4122,68 @@ make_lispy_event (event)
                               Qnil));
        }
       }
-#endif
+    case mouse_wheel:
+      {
+       int part;
+       FRAME_PTR f = XFRAME (event->frame_or_window);
+       Lisp_Object window;
+       Lisp_Object posn;
+       Lisp_Object head, position;
+       int row, column;
+
+       /* Ignore mouse events that were made on frame that
+          have been deleted.  */
+       if (! FRAME_LIVE_P (f))
+         return Qnil;
+       pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
+                              &column, &row, NULL, 1);
+       window = window_from_coordinates (f, column, row, &part);
+
+       if (!WINDOWP (window))
+         {
+           window = event->frame_or_window;
+           posn = Qnil;
+         }
+       else
+         {
+           int pixcolumn, pixrow;
+           column -= XINT (XWINDOW (window)->left);
+           row -= XINT (XWINDOW (window)->top);
+           glyph_to_pixel_coords (f, column, row, &pixcolumn, &pixrow);
+           XSETINT (event->x, pixcolumn);
+           XSETINT (event->y, pixrow);
+
+           if (part == 1)
+             posn = Qmode_line;
+           else if (part == 2)
+             posn = Qvertical_line;
+           else
+             XSETINT (posn,
+                      buffer_posn_from_coords (XWINDOW (window),
+                                               column, row));
+         }
 
+       {
+         Lisp_Object head, position;
+
+         position
+           = Fcons (window,
+                    Fcons (posn,
+                           Fcons (Fcons (event->x, event->y),
+                                  Fcons (make_number (event->timestamp),
+                                         Qnil))));
+
+         head = modify_event_symbol (0, event->modifiers,
+                                     Qmouse_wheel, Qnil,
+                                     lispy_mouse_wheel_names,
+                                     &mouse_wheel_syms, 1);
+         return Fcons (head,
+                       Fcons (position,
+                              Fcons (make_number (event->code),
+                                     Qnil)));
+       }
+      }
+#endif /* WINDOWSNT */
 #endif /* HAVE_MOUSE */
 
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
@@ -4845,6 +5061,13 @@ read_avail_input (expected)
 #else
          nread = read (input_fd, cbuf, n_to_read);
 #endif
+         /* POSIX infers that processes which are not in the session leader's
+            process group won't get SIGHUP's at logout time.  BSDI adheres to
+            this part standard and returns -1 from read(0) with errno==EIO
+            when the control tty is taken away.
+            Jeffrey Honig <jch@bsdi.com> says this is generally safe.  */
+         if (nread == -1 && errno == EIO)
+           kill (0, SIGHUP);
 #if defined (AIX) && (! defined (aix386) && defined (_BSD))
          /* The kernel sometimes fails to deliver SIGHUP for ptys.
             This looks incorrect, but it isn't, because _BSD causes
@@ -5086,7 +5309,7 @@ menu_bar_items (old)
   for (mapno = nmaps - 1; mapno >= 0; mapno--)
     {
       if (! NILP (maps[mapno]))
-       def = get_keyelt (access_keymap (maps[mapno], Qmenu_bar, 1, 0));
+       def = get_keyelt (access_keymap (maps[mapno], Qmenu_bar, 1, 0), 0);
       else
        def = Qnil;
 
@@ -5374,6 +5597,8 @@ read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu)
        {
          Lisp_Object tem;
 
+         record_menu_key (XCONS (value)->car);
+
          /* If we got multiple events, unread all but
             the first.
             There is no way to prevent those unread events
@@ -5384,10 +5609,13 @@ read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu)
             they won't confuse things.  */
          for (tem = XCONS (value)->cdr; !NILP (tem);
               tem = XCONS (tem)->cdr)
-           if (SYMBOLP (XCONS (tem)->car)
-               || INTEGERP (XCONS (tem)->car))
-             XCONS (tem)->car
-               = Fcons (XCONS (tem)->car, Qnil);
+           {
+             record_menu_key (XCONS (tem)->car);
+             if (SYMBOLP (XCONS (tem)->car)
+                 || INTEGERP (XCONS (tem)->car))
+               XCONS (tem)->car
+                 = Fcons (XCONS (tem)->car, Qnil);
+           }
 
          /* If we got more than one event, put all but the first
             onto this list to be read later.
@@ -5668,7 +5896,7 @@ follow_key (key, nmaps, current, defs, next)
          {
            Lisp_Object def;
            def = get_keyelt (access_keymap (current[i],
-                                            meta_prefix_char, 1, 0));
+                                            meta_prefix_char, 1, 0), 0);
 
            /* Note that since we pass the resulting bindings through
               get_keymap_1, non-prefix bindings for meta-prefix-char
@@ -5693,7 +5921,7 @@ follow_key (key, nmaps, current, defs, next)
          else
            map = current[i];
 
-         defs[i] = get_keyelt (access_keymap (map, key, 1, 0));
+         defs[i] = get_keyelt (access_keymap (map, key, 1, 0), 0);
          if (! NILP (defs[i]))
            first_binding = i;
        }
@@ -5741,16 +5969,20 @@ follow_key (key, nmaps, current, defs, next)
 
    If the user switches frames in the midst of a key sequence, we put
    off the switch-frame event until later; the next call to
-   read_char will return it.  */
+   read_char will return it.
+
+   If FIX_CURRENT_BUFFER is nonzero, we restore current_buffer
+   from the selected window's buffer.  */
 
 static int
 read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
-                  can_return_switch_frame)
+                  can_return_switch_frame, fix_current_buffer)
      Lisp_Object *keybuf;
      int bufsize;
      Lisp_Object prompt;
      int dont_downcase_last;
      int can_return_switch_frame;
+     int fix_current_buffer;
 {
   int count = specpdl_ptr - specpdl;
 
@@ -5842,12 +6074,12 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
   /* Save the status of key translation before each step,
      so that we can restore this after downcasing.  */
   Lisp_Object prev_fkey_map;
-  Lisp_Object prev_fkey_start;
-  Lisp_Object prev_fkey_end;
+  int prev_fkey_start;
+  int prev_fkey_end;
 
   Lisp_Object prev_keytran_map;
-  Lisp_Object prev_keytran_start;
-  Lisp_Object prev_keytran_end;
+  int prev_keytran_start;
+  int prev_keytran_end;
 
   int junk;
 
@@ -6090,6 +6322,14 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
          if (BUFFERP (key))
            {
              mock_input = t;
+             /* Reset the current buffer from the selected window
+                in case something changed the former and not the latter.
+                This is to be more consistent with the behavior
+                of the command_loop_1.  */
+             if (fix_current_buffer)
+               if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
+                 Fset_buffer (XWINDOW (selected_window)->buffer);
+
              orig_local_map = get_local_map (PT, current_buffer);
              goto replay_sequence;
            }
@@ -6433,7 +6673,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                  fkey_next
                    = get_keymap_1
                      (get_keyelt
-                      (access_keymap (fkey_map, meta_prefix_char, 1, 0)),
+                      (access_keymap (fkey_map, meta_prefix_char, 1, 0), 0),
                       0, 1);
                  XSETFASTINT (key, XFASTINT (key) & ~meta_modifier);
                }
@@ -6441,7 +6681,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                fkey_next = fkey_map;
 
              fkey_next
-               = get_keyelt (access_keymap (fkey_next, key, 1, 0));
+               = get_keyelt (access_keymap (fkey_next, key, 1, 0), 0);
 
 #if 0 /* I didn't turn this on, because it might cause trouble
         for the mapping of return into C-m and tab into C-i.  */
@@ -6541,7 +6781,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                keytran_next
                  = get_keymap_1
                    (get_keyelt
-                    (access_keymap (keytran_map, meta_prefix_char, 1, 0)),
+                    (access_keymap (keytran_map, meta_prefix_char, 1, 0), 0),
                     0, 1);
                XSETFASTINT (key, XFASTINT (key) & ~meta_modifier);
              }
@@ -6549,7 +6789,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
              keytran_next = keytran_map;
 
            keytran_next
-             = get_keyelt (access_keymap (keytran_next, key, 1, 0));
+             = get_keyelt (access_keymap (keytran_next, key, 1, 0), 0);
 
            /* If the key translation map gives a function, not an
               array, then call the function with no args and use
@@ -6810,7 +7050,7 @@ DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 4, 0,
 
   i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])),
                         prompt, ! NILP (dont_downcase_last),
-                        ! NILP (can_return_switch_frame));
+                        ! NILP (can_return_switch_frame), 0);
 
   if (i == -1)
     {
@@ -6959,7 +7199,8 @@ DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_
      history list. */
   function = Fcompleting_read (build_string (buf),
                               Vobarray, Qcommandp,
-                              Qt, Qnil, Qextended_command_history);
+                              Qt, Qnil, Qextended_command_history, Qnil,
+                              Qnil);
 
   if (STRINGP (function) && XSTRING (function)->size == 0)
     error ("No command name given");
@@ -7015,7 +7256,8 @@ DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_
       /* But first wait, and skip the message if there is input.  */
       if (!NILP (Fsit_for ((NUMBERP (Vsuggest_key_bindings)
                            ? Vsuggest_key_bindings : make_number (2)),
-                          Qnil, Qnil)))
+                          Qnil, Qnil))
+         && ! CONSP (Vunread_command_events))
        {
          Lisp_Object binding;
          char *newmessage;
@@ -7410,11 +7652,17 @@ interrupt_signal (signalnum)    /* If we don't have an argument, */
 
   cancel_echoing ();
 
-  if (!NILP (Vquit_flag) && FRAME_TERMCAP_P (selected_frame))
+  if (!NILP (Vquit_flag)
+      && (FRAME_TERMCAP_P (selected_frame) || FRAME_MSDOS_P (selected_frame)))
     {
+      /* If SIGINT isn't blocked, don't let us be interrupted by
+        another SIGINT, it might be harmful due to non-reentrancy
+        in I/O functions.  */
+      sigblock (sigmask (SIGINT));
+
       fflush (stdout);
       reset_sys_modes ();
-      sigfree ();
+
 #ifdef SIGTSTP                 /* Support possible in later USG versions */
 /*
  * On systems which can suspend the current process and return to the original
@@ -7493,6 +7741,7 @@ interrupt_signal (signalnum)      /* If we don't have an argument, */
 #endif /* not MSDOS */
       fflush (stdout);
       init_sys_modes ();
+      sigfree ();
     }
   else
     {
@@ -7568,7 +7817,7 @@ See also `current-input-mode'.")
   stop_polling ();
 #endif
 
-#ifndef MSDOS
+#ifndef DOS_NT
   /* this causes startup screen to be restored and messes with the mouse */
   reset_sys_modes ();
 #endif
@@ -7607,7 +7856,7 @@ See also `current-input-mode'.")
     /* Don't let this value be out of range.  */
     quit_char = XINT (quit) & (meta_key ? 0377 : 0177);
 
-#ifndef MSDOS
+#ifndef DOS_NT
   init_sys_modes ();
 #endif
 
@@ -7794,6 +8043,9 @@ struct event_head head_table[] = {
 
 syms_of_keyboard ()
 {
+  Qtimer_event_handler = intern ("timer-event-handler");
+  staticpro (&Qtimer_event_handler);
+
   Qdisabled_command_hook = intern ("disabled-command-hook");
   staticpro (&Qdisabled_command_hook);
 
@@ -7831,8 +8083,10 @@ syms_of_keyboard ()
   staticpro (&Qfunction_key);
   Qmouse_click = intern ("mouse-click");
   staticpro (&Qmouse_click);
-  Qtimer_event = intern ("timer-event");
-  staticpro (&Qtimer_event);
+#ifdef WINDOWSNT
+  Qmouse_wheel = intern ("mouse-wheel");
+  staticpro (&Qmouse_wheel);
+#endif
 
   Qmenu_enable = intern ("menu-enable");
   staticpro (&Qmenu_enable);
@@ -7925,6 +8179,11 @@ syms_of_keyboard ()
   mouse_syms = Qnil;
   staticpro (&mouse_syms);
 
+#ifdef WINDOWSNT
+  mouse_wheel_syms = Qnil;
+  staticpro (&mouse_wheel_syms);
+#endif
+
   unread_switch_frame = Qnil;
   staticpro (&unread_switch_frame);
 
@@ -8040,16 +8299,25 @@ by position only.");
   inhibit_local_menu_bar_menus = 0;
 
   DEFVAR_INT ("num-input-keys", &num_input_keys,
-    "Number of complete key sequences read from the keyboard so far.\n\
+    "Number of complete key sequences read as input so far.\n\
 This includes key sequences read from keyboard macros.\n\
 The number is effectively the number of interactive command invocations.");
   num_input_keys = 0;
 
+  DEFVAR_INT ("num-nonmacro-input-events", &num_nonmacro_input_events,
+    "Number of input events read from the keyboard so far.\n\
+This does not include events generated by keyboard macros.");
+  num_nonmacro_input_events = 0;
+
   DEFVAR_LISP ("last-event-frame", &Vlast_event_frame,
     "The frame in which the most recently read event occurred.\n\
 If the last event came from a keyboard macro, this is set to `macro'.");
   Vlast_event_frame = Qnil;
 
+  /* This variable is set up in sysdep.c.  */
+  DEFVAR_LISP ("tty-erase-char", &Vtty_erase_char,
+    "The ERASE character as set by the user with stty.");
+
   DEFVAR_LISP ("help-char", &Vhelp_char,
     "Character to recognize as meaning Help.\n\
 When it is read, do `(eval help-form)', and display result if it's a string.\n\
@@ -8152,6 +8420,13 @@ This feature is obsolete; use idle timers instead.  See `etc/NEWS'.");
 This is measured in microseconds.");
   post_command_idle_delay = 100000;
 
+#if 0
+  DEFVAR_LISP ("echo-area-clear-hook", ...,
+    "Normal hook run when clearing the echo area.");
+#endif
+  Qecho_area_clear_hook = intern ("echo-area-clear-hook");
+  XSYMBOL (Qecho_area_clear_hook)->value = Qnil;
+
   DEFVAR_LISP ("lucid-menu-bar-dirty-flag", &Vlucid_menu_bar_dirty_flag,
     "t means menu bar, specified Lucid style, needs to be recomputed.");
   Vlucid_menu_bar_dirty_flag = Qnil;
@@ -8163,9 +8438,11 @@ The elements of the list are event types that may have menu bar bindings.");
 
   DEFVAR_KBOARD ("overriding-terminal-local-map",
                 Voverriding_terminal_local_map,
-    "Keymap that overrides all other local keymaps.\n\
+    "Per-terminal keymap that overrides all other local keymaps.\n\
 If this variable is non-nil, it is used as a keymap instead of the\n\
-buffer's local map, and the minor mode keymaps and text property keymaps.");
+buffer's local map, and the minor mode keymaps and text property keymaps.\n\
+This variable is intended to let commands such as `universal-argumemnt'\n\
+set up a different keymap for reading the next command.");
 
   DEFVAR_LISP ("overriding-local-map", &Voverriding_local_map,
     "Keymap that overrides all other local keymaps.\n\