* src/keymap.c (Fcurrent_active_maps, Fdescribe_buffer_bindings):
[bpt/emacs.git] / src / keyboard.c
index fe1c3d7..d01ecb9 100644 (file)
@@ -72,7 +72,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include TERM_HEADER
 #endif /* HAVE_WINDOW_SYSTEM */
 
-/* Variables for blockinput.h: */
+/* Variables for blockinput.h:  */
 
 /* Positive if interrupt input is blocked right now.  */
 volatile int interrupt_input_blocked;
@@ -210,12 +210,6 @@ static EMACS_INT last_auto_save;
 /* The value of point when the last command was started.  */
 static ptrdiff_t last_point_position;
 
-/* The buffer that was current when the last command was started.  */
-static Lisp_Object last_point_position_buffer;
-
-/* The window that was selected when the last command was started.  */
-static Lisp_Object last_point_position_window;
-
 /* The frame in which the last input event occurred, or Qmacro if the
    last event came from a macro.  We use this to determine when to
    generate switch-frame events.  This may be cleared by functions
@@ -314,18 +308,15 @@ static Lisp_Object Qfunction_key;
 Lisp_Object Qmouse_click;
 #ifdef HAVE_NTGUI
 Lisp_Object Qlanguage_change;
-#ifdef WINDOWSNT
-Lisp_Object Qfile_w32notify;
-#endif
 #endif
 static Lisp_Object Qdrag_n_drop;
 static Lisp_Object Qsave_session;
 #ifdef HAVE_DBUS
 static Lisp_Object Qdbus_event;
 #endif
-#ifdef HAVE_INOTIFY
-static Lisp_Object Qfile_inotify;
-#endif /* HAVE_INOTIFY */
+#ifdef USE_FILE_NOTIFY
+static Lisp_Object Qfile_notify;
+#endif /* USE_FILE_NOTIFY */
 static Lisp_Object Qconfig_changed_event;
 
 /* Lisp_Object Qmouse_movement; - also an event header */
@@ -367,7 +358,7 @@ Lisp_Object Qmenu_bar;
 
 static Lisp_Object recursive_edit_unwind (Lisp_Object buffer);
 static Lisp_Object command_loop (void);
-static Lisp_Object Qextended_command_history;
+static Lisp_Object Qcommand_execute;
 EMACS_TIME timer_check (void);
 
 static void echo_now (void);
@@ -833,7 +824,7 @@ This function is called by the editor initialization to begin editing.  */)
   update_mode_lines = 1;
 
   if (command_loop_level
-      && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer))
+      && current_buffer != XBUFFER (XWINDOW (selected_window)->contents))
     buffer = Fcurrent_buffer ();
   else
     buffer = Qnil;
@@ -1185,13 +1176,13 @@ top_level_2 (void)
 static Lisp_Object
 top_level_1 (Lisp_Object ignore)
 {
-  /* On entry to the outer level, run the startup file */
+  /* On entry to the outer level, run the startup file */
   if (!NILP (Vtop_level))
     internal_condition_case (top_level_2, Qerror, cmd_error);
   else if (!NILP (Vpurify_flag))
-    message ("Bare impure Emacs (standard Lisp code not loaded)");
+    message1 ("Bare impure Emacs (standard Lisp code not loaded)");
   else
-    message ("Bare Emacs (standard Lisp code not loaded)");
+    message1 ("Bare Emacs (standard Lisp code not loaded)");
   return Qnil;
 }
 
@@ -1395,7 +1386,7 @@ command_loop_1 (void)
        Fkill_emacs (Qnil);
 
       /* Make sure the current window's buffer is selected.  */
-      set_buffer_internal (XBUFFER (XWINDOW (selected_window)->buffer));
+      set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents));
 
       /* Display any malloc warning that just came out.  Use while because
         displaying one warning can cause another.  */
@@ -1461,7 +1452,7 @@ command_loop_1 (void)
       /* A filter may have run while we were reading the input.  */
       if (! FRAME_LIVE_P (XFRAME (selected_frame)))
        Fkill_emacs (Qnil);
-      set_buffer_internal (XBUFFER (XWINDOW (selected_window)->buffer));
+      set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents));
 
       ++num_input_keys;
 
@@ -1492,7 +1483,7 @@ command_loop_1 (void)
        {
          struct buffer *b;
          XWINDOW (selected_window)->force_start = 0;
-         b = XBUFFER (XWINDOW (selected_window)->buffer);
+         b = XBUFFER (XWINDOW (selected_window)->contents);
          BUF_BEG_UNCHANGED (b) = BUF_END_UNCHANGED (b) = 0;
        }
 
@@ -1512,8 +1503,6 @@ command_loop_1 (void)
       prev_buffer = current_buffer;
       prev_modiff = MODIFF;
       last_point_position = PT;
-      last_point_position_window = selected_window;
-      XSETBUFFER (last_point_position_buffer, prev_buffer);
 
       /* By default, we adjust point to a boundary of a region that
          has such a property that should be treated intangible
@@ -1583,11 +1572,11 @@ command_loop_1 (void)
                  = (EQ (undo, BVAR (current_buffer, undo_list))
                     ? Qnil : BVAR (current_buffer, undo_list));
              }
-            Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil);
+            call1 (Qcommand_execute, Vthis_command);
 
 #ifdef HAVE_WINDOW_SYSTEM
          /* Do not check display_hourglass_p here, because
-            Fcommand_execute could change it, but we should cancel
+            `command-execute' could change it, but we should cancel
             hourglass cursor anyway.
             But don't cancel the hourglass within a macro
             just because a command in the macro finishes.  */
@@ -1893,7 +1882,7 @@ safe_run_hooks_error (Lisp_Object error_data)
     = CONSP (Vinhibit_quit) ? XCAR (Vinhibit_quit) : Vinhibit_quit;
   Lisp_Object fun = CONSP (Vinhibit_quit) ? XCDR (Vinhibit_quit) : Qnil;
   Lisp_Object args[4];
-  args[0] = build_string ("Error in %s (%s): %S");
+  args[0] = build_string ("Error in %s (%S): %S");
   args[1] = hook;
   args[2] = fun;
   args[3] = error_data;
@@ -2230,6 +2219,160 @@ do { if (! polling_stopped_here) stop_polling ();       \
 do { if (polling_stopped_here) start_polling ();       \
        polling_stopped_here = 0; } while (0)
 
+static Lisp_Object
+read_event_from_main_queue (EMACS_TIME *end_time,
+                            sys_jmp_buf local_getcjmp,
+                            bool *used_mouse_menu)
+{
+  Lisp_Object c = Qnil;
+  sys_jmp_buf save_jump;
+  KBOARD *kb IF_LINT (= NULL);
+
+ start:
+
+  /* Read from the main queue, and if that gives us something we can't use yet,
+     we put it on the appropriate side queue and try again.  */
+
+  if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ()))
+    return c;
+
+  /* Actually read a character, waiting if necessary.  */
+  save_getcjmp (save_jump);
+  restore_getcjmp (local_getcjmp);
+  if (!end_time)
+       timer_start_idle ();
+  c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
+  restore_getcjmp (save_jump);
+
+  if (! NILP (c) && (kb != current_kboard))
+    {
+      Lisp_Object last = KVAR (kb, kbd_queue);
+      if (CONSP (last))
+        {
+          while (CONSP (XCDR (last)))
+       last = XCDR (last);
+          if (!NILP (XCDR (last)))
+       emacs_abort ();
+        }
+      if (!CONSP (last))
+        kset_kbd_queue (kb, Fcons (c, Qnil));
+      else
+        XSETCDR (last, Fcons (c, Qnil));
+      kb->kbd_queue_has_data = 1;
+      c = Qnil;
+      if (single_kboard)
+        goto start;
+      current_kboard = kb;
+      /* This is going to exit from read_char
+         so we had better get rid of this frame's stuff.  */
+      return make_number (-2);
+    }
+
+  /* Terminate Emacs in batch mode if at eof.  */
+  if (noninteractive && INTEGERP (c) && XINT (c) < 0)
+    Fkill_emacs (make_number (1));
+
+  if (INTEGERP (c))
+    {
+      /* Add in any extra modifiers, where appropriate.  */
+      if ((extra_keyboard_modifiers & CHAR_CTL)
+         || ((extra_keyboard_modifiers & 0177) < ' '
+             && (extra_keyboard_modifiers & 0177) != 0))
+       XSETINT (c, make_ctrl_char (XINT (c)));
+
+      /* Transfer any other modifier bits directly from
+        extra_keyboard_modifiers to c.  Ignore the actual character code
+        in the low 16 bits of extra_keyboard_modifiers.  */
+      XSETINT (c, XINT (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL));
+    }
+
+  /* FIXME: Decode tty keyboard input here.  */
+  return c;
+}
+
+
+
+/* Like `read_event_from_main_queue' but applies keyboard-coding-system
+   to tty input.  */
+static Lisp_Object
+read_decoded_event_from_main_queue (EMACS_TIME *end_time,
+                                    sys_jmp_buf local_getcjmp,
+                                    Lisp_Object prev_event,
+                                    bool *used_mouse_menu)
+{
+#define MAX_ENCODED_BYTES 16
+  Lisp_Object events[MAX_ENCODED_BYTES];
+  int n = 0;
+  while (true)
+    {
+      Lisp_Object nextevt
+        = read_event_from_main_queue (end_time, local_getcjmp,
+                                      used_mouse_menu);
+#ifdef WINDOWSNT
+      /* w32_console already returns decoded events.  It either reads
+        Unicode characters from the Windows keyboard input, or
+        converts characters encoded in the current codepage into
+        Unicode.  See w32inevt.c:key_event, near its end.  */
+      return nextevt;
+#else
+      struct frame *frame = XFRAME (selected_frame);
+      struct terminal *terminal = frame->terminal;
+      if (!((FRAME_TERMCAP_P (frame) || FRAME_MSDOS_P (frame))
+            /* Don't apply decoding if we're just reading a raw event
+               (e.g. reading bytes sent by the xterm to specify the position
+               of a mouse click).  */
+            && (!EQ (prev_event, Qt))
+           && (TERMINAL_KEYBOARD_CODING (terminal)->common_flags
+               & CODING_REQUIRE_DECODING_MASK)))
+       return nextevt;         /* No decoding needed.  */
+      else
+       {
+         int meta_key = terminal->display_info.tty->meta_key;
+         eassert (n < MAX_ENCODED_BYTES);
+         events[n++] = nextevt;
+         if (NATNUMP (nextevt)
+             && XINT (nextevt) < (meta_key == 1 ? 0x80 : 0x100))
+           { /* An encoded byte sequence, let's try to decode it.  */
+             struct coding_system *coding
+               = TERMINAL_KEYBOARD_CODING (terminal);
+             unsigned char *src = alloca (n);
+             int i;
+             for (i = 0; i < n; i++)
+               src[i] = XINT (events[i]);
+             if (meta_key != 2)
+               for (i = 0; i < n; i++)
+                 src[i] &= ~0x80;
+             coding->destination = alloca (n * 4);
+             coding->dst_bytes = n * 4;
+             decode_coding_c_string (coding, src, n, Qnil);
+             eassert (coding->produced_char <= n);
+             if (coding->produced_char == 0)
+               { /* The encoded sequence is incomplete.  */
+                 if (n < MAX_ENCODED_BYTES) /* Avoid buffer overflow.  */
+                   continue;                /* Read on!  */
+               }
+             else
+               {
+                 const unsigned char *p = coding->destination;
+                 eassert (coding->carryover_bytes == 0);
+                 n = 0;
+                 while (n < coding->produced_char)
+                   events[n++] = make_number (STRING_CHAR_ADVANCE (p));
+               }
+           }
+         /* Now `events' should hold decoded events.
+            Normally, n should be equal to 1, but better not rely on it.
+            We can only return one event here, so return the first we
+            had and keep the others (if any) for later.  */
+         while (n > 1)
+           Vunread_command_events
+             = Fcons (events[--n], Vunread_command_events);
+         return events[0];
+       }
+#endif
+    }
+}
+
 /* Read a character from the keyboard; call the redisplay if needed.  */
 /* commandflag 0 means do not autosave, but do redisplay.
    -1 means do not redisplay, but do autosave.
@@ -2657,9 +2800,10 @@ read_char (int commandflag, Lisp_Object map,
          && XINT (Vauto_save_timeout) > 0)
        {
          Lisp_Object tem0;
-         EMACS_INT timeout = (delay_level
-                              * min (XFASTINT (Vauto_save_timeout) / 4,
-                                     MOST_POSITIVE_FIXNUM / delay_level));
+         EMACS_INT timeout = XFASTINT (Vauto_save_timeout);
+
+         timeout = min (timeout, MOST_POSITIVE_FIXNUM / delay_level * 4);
+         timeout = delay_level * timeout / 4;
          save_getcjmp (save_jump);
          restore_getcjmp (local_getcjmp);
          tem0 = sit_for (make_number (timeout), 1, 1);
@@ -2746,68 +2890,20 @@ read_char (int commandflag, Lisp_Object map,
 
   STOP_POLLING;
 
-  /* Finally, we read from the main queue,
-     and if that gives us something we can't use yet, we put it on the
-     appropriate side queue and try again.  */
-
   if (NILP (c))
     {
-      KBOARD *kb IF_LINT (= NULL);
-
+      c = read_decoded_event_from_main_queue (end_time, local_getcjmp,
+                                              prev_event, used_mouse_menu);
       if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ()))
-       goto exit;
-
-      /* Actually read a character, waiting if necessary.  */
-      save_getcjmp (save_jump);
-      restore_getcjmp (local_getcjmp);
-      if (!end_time)
-       timer_start_idle ();
-      c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
-      restore_getcjmp (save_jump);
-
-      if (! NILP (c) && (kb != current_kboard))
-       {
-         Lisp_Object last = KVAR (kb, kbd_queue);
-         if (CONSP (last))
-           {
-             while (CONSP (XCDR (last)))
-               last = XCDR (last);
-             if (!NILP (XCDR (last)))
-               emacs_abort ();
-           }
-         if (!CONSP (last))
-           kset_kbd_queue (kb, Fcons (c, Qnil));
-         else
-           XSETCDR (last, Fcons (c, Qnil));
-         kb->kbd_queue_has_data = 1;
-         c = Qnil;
-         if (single_kboard)
-           goto wrong_kboard;
-         current_kboard = kb;
+        goto exit;
+      if (EQ (c, make_number (-2)))
+        {
          /* This is going to exit from read_char
             so we had better get rid of this frame's stuff.  */
          UNGCPRO;
-          return make_number (-2);
-       }
-    }
-
-  /* Terminate Emacs in batch mode if at eof.  */
-  if (noninteractive && INTEGERP (c) && XINT (c) < 0)
-    Fkill_emacs (make_number (1));
-
-  if (INTEGERP (c))
-    {
-      /* Add in any extra modifiers, where appropriate.  */
-      if ((extra_keyboard_modifiers & CHAR_CTL)
-         || ((extra_keyboard_modifiers & 0177) < ' '
-             && (extra_keyboard_modifiers & 0177) != 0))
-       XSETINT (c, make_ctrl_char (XINT (c)));
-
-      /* Transfer any other modifier bits directly from
-        extra_keyboard_modifiers to c.  Ignore the actual character code
-        in the low 16 bits of extra_keyboard_modifiers.  */
-      XSETINT (c, XINT (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL));
-    }
+          return c;
+        }
+  }
 
  non_reread:
 
@@ -2841,7 +2937,7 @@ read_char (int commandflag, Lisp_Object map,
     {
       struct buffer *prev_buffer = current_buffer;
       last_input_event = c;
-      Fcommand_execute (tem, Qnil, Fvector (1, &last_input_event), Qt);
+      call4 (Qcommand_execute, tem, Qnil, Fvector (1, &last_input_event), Qt);
 
       if (CONSP (c) && EQ (XCAR (c), Qselect_window) && !end_time)
        /* We stopped being idle for this event; undo that.  This
@@ -3914,18 +4010,22 @@ kbd_buffer_get_event (KBOARD **kbp,
          kbd_fetch_ptr = event + 1;
        }
 #endif
-#ifdef WINDOWSNT
+#ifdef USE_FILE_NOTIFY
       else if (event->kind == FILE_NOTIFY_EVENT)
        {
+#ifdef HAVE_W32NOTIFY
          /* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK).  */
-         obj = Fcons (Qfile_w32notify,
+         obj = Fcons (Qfile_notify,
                       list2 (list3 (make_number (event->code),
                                     XCAR (event->arg),
                                     XCDR (event->arg)),
                              event->frame_or_window));
+#else
+          obj = make_lispy_event (event);
+#endif
          kbd_fetch_ptr = event + 1;
        }
-#endif
+#endif /* USE_FILE_NOTIFY */
       else if (event->kind == SAVE_SESSION_EVENT)
         {
           obj = Fcons (Qsave_session, Fcons (event->arg, Qnil));
@@ -3982,13 +4082,6 @@ kbd_buffer_get_event (KBOARD **kbp,
          obj = make_lispy_event (event);
          kbd_fetch_ptr = event + 1;
        }
-#endif
-#ifdef HAVE_INOTIFY
-      else if (event->kind == FILE_NOTIFY_EVENT)
-        {
-          obj = make_lispy_event (event);
-          kbd_fetch_ptr = event + 1;
-        }
 #endif
       else if (event->kind == CONFIG_CHANGED_EVENT)
        {
@@ -4195,8 +4288,6 @@ swallow_events (bool do_display)
 static void
 timer_start_idle (void)
 {
-  Lisp_Object timers;
-
   /* If we are already in the idle state, do nothing.  */
   if (EMACS_TIME_VALID_P (timer_idleness_start_time))
     return;
@@ -4205,16 +4296,7 @@ timer_start_idle (void)
   timer_last_idleness_start_time = timer_idleness_start_time;
 
   /* Mark all idle-time timers as once again candidates for running.  */
-  for (timers = Vtimer_idle_list; CONSP (timers); timers = XCDR (timers))
-    {
-      Lisp_Object timer;
-
-      timer = XCAR (timers);
-
-      if (!VECTORP (timer) || ASIZE (timer) != 9)
-       continue;
-      ASET (timer, 0, Qnil);
-    }
+  call0 (intern ("internal-timer-start-idle"));
 }
 
 /* Record that Emacs is no longer idle, so stop running idle-time timers.  */
@@ -4344,10 +4426,10 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
            }
 
          idle_timer_ripe = EMACS_TIME_LE (idle_timer_time, idleness_now);
-         idle_timer_difference =
-           (idle_timer_ripe
-            ? sub_emacs_time (idleness_now, idle_timer_time)
-            : sub_emacs_time (idle_timer_time, idleness_now));
+         idle_timer_difference
+           (idle_timer_ripe
+              ? sub_emacs_time (idleness_now, idle_timer_time)
+              : sub_emacs_time (idle_timer_time, idleness_now));
        }
 
       /* Decide which timer is the next timer,
@@ -5141,7 +5223,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
          if (STRINGP (string))
            string_info = Fcons (string, make_number (charpos));
          textpos = (w == XWINDOW (selected_window)
-                    && current_buffer == XBUFFER (w->buffer))
+                    && current_buffer == XBUFFER (w->contents))
            ? PT : marker_position (w->pointm);
 
          xret = wx;
@@ -5903,12 +5985,12 @@ make_lispy_event (struct input_event *event)
       }
 #endif /* HAVE_DBUS */
 
-#ifdef HAVE_INOTIFY
+#if defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY
     case FILE_NOTIFY_EVENT:
       {
-        return Fcons (Qfile_inotify, event->arg);
+        return Fcons (Qfile_notify, event->arg);
       }
-#endif /* HAVE_INOTIFY */
+#endif /* defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY */
 
     case CONFIG_CHANGED_EVENT:
        return Fcons (Qconfig_changed_event,
@@ -6224,9 +6306,7 @@ parse_modifiers (Lisp_Object symbol)
   Lisp_Object elements;
 
   if (INTEGERP (symbol))
-    return (Fcons (make_number (KEY_TO_CHAR (symbol)),
-                  Fcons (make_number (XINT (symbol) & CHAR_MODIFIER_MASK),
-                         Qnil)));
+    return list2i (KEY_TO_CHAR (symbol), XINT (symbol) & CHAR_MODIFIER_MASK);
   else if (!SYMBOLP (symbol))
     return Qnil;
 
@@ -6553,10 +6633,7 @@ has the same base event type and all the specified modifiers.  */)
   else if (SYMBOLP (base))
     return apply_modifiers (modifiers, base);
   else
-    {
-      error ("Invalid base event");
-      return Qnil;
-    }
+    error ("Invalid base event");
 }
 
 /* Try to recognize SYMBOL as a modifier name.
@@ -6770,7 +6847,7 @@ gobble_input (void)
           hold_quit.kind = NO_EVENT;
 
           /* No need for FIONREAD or fcntl; just say don't wait.  */
-         while (0 < (nr = (*t->read_socket_hook) (t, &hold_quit)))
+         while ((nr = (*t->read_socket_hook) (t, &hold_quit)) > 0)
            nread += nr;
 
           if (nr == -1)          /* Not OK to read input now.  */
@@ -6816,48 +6893,6 @@ gobble_input (void)
   return nread;
 }
 
-static void
-decode_keyboard_code (struct tty_display_info *tty,
-                     struct coding_system *coding,
-                     unsigned char *buf, int nbytes)
-{
-  unsigned char *src = buf;
-  const unsigned char *p;
-  int i;
-
-  if (nbytes == 0)
-    return;
-  if (tty->meta_key != 2)
-    for (i = 0; i < nbytes; i++)
-      buf[i] &= ~0x80;
-  if (coding->carryover_bytes > 0)
-    {
-      src = alloca (coding->carryover_bytes + nbytes);
-      memcpy (src, coding->carryover, coding->carryover_bytes);
-      memcpy (src + coding->carryover_bytes, buf, nbytes);
-      nbytes += coding->carryover_bytes;
-    }
-  coding->destination = alloca (nbytes * 4);
-  coding->dst_bytes = nbytes * 4;
-  decode_coding_c_string (coding, src, nbytes, Qnil);
-  if (coding->produced_char == 0)
-    return;
-  for (i = 0, p = coding->destination; i < coding->produced_char; i++)
-    {
-      struct input_event event_buf;
-
-      EVENT_INIT (event_buf);
-      event_buf.code = STRING_CHAR_ADVANCE (p);
-      event_buf.kind =
-       (ASCII_CHAR_P (event_buf.code)
-        ? ASCII_KEYSTROKE_EVENT : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
-      /* See the comment in tty_read_avail_input.  */
-      event_buf.frame_or_window = tty->top_frame;
-      event_buf.arg = Qnil;
-      kbd_buffer_store_event (&event_buf);
-    }
-}
-
 /* This is the tty way of reading available input.
 
    Note that each terminal device has its own `struct terminal' object,
@@ -6892,6 +6927,8 @@ tty_read_avail_input (struct terminal *terminal,
   /* XXX I think the following code should be moved to separate hook
      functions in system-dependent files.  */
 #ifdef WINDOWSNT
+  /* FIXME: AFAIK, tty_read_avail_input is not used under w32 since the non-GUI
+     code sets read_socket_hook to w32_console_read_socket instead!  */
   return 0;
 #else /* not WINDOWSNT */
   if (! tty->term_initted)      /* In case we get called during bootstrap.  */
@@ -7015,36 +7052,6 @@ tty_read_avail_input (struct terminal *terminal,
 #endif /* not MSDOS */
 #endif /* not WINDOWSNT */
 
-  if (TERMINAL_KEYBOARD_CODING (terminal)->common_flags
-      & CODING_REQUIRE_DECODING_MASK)
-    {
-      struct coding_system *coding = TERMINAL_KEYBOARD_CODING (terminal);
-      int from;
-
-      /* Decode the key sequence except for those with meta
-        modifiers.  */
-      for (i = from = 0; ; i++)
-       if (i == nread || (tty->meta_key == 1 && (cbuf[i] & 0x80)))
-         {
-           struct input_event buf;
-
-           decode_keyboard_code (tty, coding, cbuf + from, i - from);
-           if (i == nread)
-             break;
-
-           EVENT_INIT (buf);
-           buf.kind = ASCII_KEYSTROKE_EVENT;
-           buf.modifiers = meta_modifier;
-           buf.code = cbuf[i] & ~0x80;
-           /* See the comment below.  */
-           buf.frame_or_window = tty->top_frame;
-           buf.arg = Qnil;
-           kbd_buffer_store_event (&buf);
-           from = i + 1;
-         }
-      return nread;
-    }
-
   for (i = 0; i < nread; i++)
     {
       struct input_event buf;
@@ -7385,7 +7392,8 @@ menu_bar_items (Lisp_Object old)
     Lisp_Object *tmaps;
 
     /* Should overriding-terminal-local-map and overriding-local-map apply?  */
-    if (!NILP (Voverriding_local_map_menu_flag))
+    if (!NILP (Voverriding_local_map_menu_flag)
+       && !NILP (Voverriding_local_map))
       {
        /* Yes, use them (if non-nil) as well as the global map.  */
        maps = alloca (3 * sizeof (maps[0]));
@@ -7405,8 +7413,11 @@ menu_bar_items (Lisp_Object old)
        Lisp_Object tem;
        ptrdiff_t nminor;
        nminor = current_minor_maps (NULL, &tmaps);
-       maps = alloca ((nminor + 3) * sizeof *maps);
+       maps = alloca ((nminor + 4) * sizeof *maps);
        nmaps = 0;
+       tem = KVAR (current_kboard, Voverriding_terminal_local_map);
+       if (!NILP (tem) && !NILP (Voverriding_local_map_menu_flag))
+         maps[nmaps++] = tem;
        if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem))
          maps[nmaps++] = tem;
        memcpy (maps + nmaps, tmaps, nminor * sizeof (maps[0]));
@@ -7931,7 +7942,8 @@ tool_bar_items (Lisp_Object reuse, int *nitems)
      to process.  */
 
   /* Should overriding-terminal-local-map and overriding-local-map apply?  */
-  if (!NILP (Voverriding_local_map_menu_flag))
+  if (!NILP (Voverriding_local_map_menu_flag)
+      && !NILP (Voverriding_local_map))
     {
       /* Yes, use them (if non-nil) as well as the global map.  */
       maps = alloca (3 * sizeof *maps);
@@ -7951,8 +7963,11 @@ tool_bar_items (Lisp_Object reuse, int *nitems)
       Lisp_Object tem;
       ptrdiff_t nminor;
       nminor = current_minor_maps (NULL, &tmaps);
-      maps = alloca ((nminor + 3) * sizeof *maps);
+      maps = alloca ((nminor + 4) * sizeof *maps);
       nmaps = 0;
+      tem = KVAR (current_kboard, Voverriding_terminal_local_map);
+      if (!NILP (tem) && !NILP (Voverriding_local_map_menu_flag))
+       maps[nmaps++] = tem;
       if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem))
        maps[nmaps++] = tem;
       memcpy (maps + nmaps, tmaps, nminor * sizeof (maps[0]));
@@ -8316,9 +8331,8 @@ append_tool_bar_item (void)
        - (ASIZE (tool_bar_items_vector) - TOOL_BAR_ITEM_NSLOTS));
 
   /* Enlarge tool_bar_items_vector if necessary.  */
-  if (0 < incr)
-    tool_bar_items_vector
-      = larger_vector (tool_bar_items_vector, incr, -1);
+  if (incr > 0)
+    tool_bar_items_vector = larger_vector (tool_bar_items_vector, incr, -1);
 
   /* Append entries from tool_bar_item_properties to the end of
      tool_bar_items_vector.  */
@@ -8700,7 +8714,7 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt,
         barf--don't ignore it.
         (To ignore it safely, we would need to gcpro a bunch of
         other variables.)  */
-      if (! (VECTORP (next) || STRINGP (next)))
+      if (! (NILP (next) || VECTORP (next) || STRINGP (next)))
        error ("Function %s returns invalid key sequence",
               SSDATA (SYMBOL_NAME (tem)));
     }
@@ -9062,8 +9076,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
            KBOARD *interrupted_kboard = current_kboard;
            struct frame *interrupted_frame = SELECTED_FRAME ();
            key = read_char (NILP (prompt),
-                            current_binding, last_nonmenu_event,
-                            &used_mouse_menu, NULL);
+                            current_binding, last_nonmenu_event,
+                             &used_mouse_menu, NULL);
            if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */
                /* When switching to a new tty (with a new keyboard),
                   read_char returns the new buffer, rather than -2
@@ -9157,9 +9171,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
                {
                  if (! FRAME_LIVE_P (XFRAME (selected_frame)))
                    Fkill_emacs (Qnil);
-                 if (XBUFFER (XWINDOW (selected_window)->buffer)
+                 if (XBUFFER (XWINDOW (selected_window)->contents)
                      != current_buffer)
-                   Fset_buffer (XWINDOW (selected_window)->buffer);
+                   Fset_buffer (XWINDOW (selected_window)->contents);
                }
 
              goto replay_sequence;
@@ -9207,9 +9221,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
                 special-event-map, ...) might have switched the current buffer
                 or the selected window from under us in the mean time.  */
              if (fix_current_buffer
-                 && (XBUFFER (XWINDOW (selected_window)->buffer)
+                 && (XBUFFER (XWINDOW (selected_window)->contents)
                      != current_buffer))
-               Fset_buffer (XWINDOW (selected_window)->buffer);
+               Fset_buffer (XWINDOW (selected_window)->contents);
              current_binding = active_maps (first_event);
            }
 
@@ -9258,8 +9272,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
                     not the current buffer.  If we're at the
                     beginning of a key sequence, switch buffers.  */
                  if (WINDOWP (window)
-                     && BUFFERP (XWINDOW (window)->buffer)
-                     && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
+                     && BUFFERP (XWINDOW (window)->contents)
+                     && XBUFFER (XWINDOW (window)->contents) != current_buffer)
                    {
                      ASET (raw_keybuf, raw_keybuf_count, key);
                      raw_keybuf_count++;
@@ -9280,7 +9294,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
 
                      if (! FRAME_LIVE_P (XFRAME (selected_frame)))
                        Fkill_emacs (Qnil);
-                     set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
+                     set_buffer_internal (XBUFFER (XWINDOW (window)->contents));
                      goto replay_sequence;
                    }
                }
@@ -9875,95 +9889,6 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector,
   return unbind_to (count, Fvector (i, keybuf));
 }
 \f
-DEFUN ("command-execute", Fcommand_execute, Scommand_execute, 1, 4, 0,
-       doc: /* Execute CMD as an editor command.
-CMD must be a symbol that satisfies the `commandp' predicate.
-Optional second arg RECORD-FLAG non-nil
-means unconditionally put this command in the variable `command-history'.
-Otherwise, that is done only if an arg is read using the minibuffer.
-The argument KEYS specifies the value to use instead of (this-command-keys)
-when reading the arguments; if it is nil, (this-command-keys) is used.
-The argument SPECIAL, if non-nil, means that this command is executing
-a special event, so ignore the prefix argument and don't clear it.  */)
-  (Lisp_Object cmd, Lisp_Object record_flag, Lisp_Object keys, Lisp_Object special)
-{
-  register Lisp_Object final;
-  register Lisp_Object tem;
-  Lisp_Object prefixarg;
-
-  debug_on_next_call = 0;
-
-  if (NILP (special))
-    {
-      prefixarg = KVAR (current_kboard, Vprefix_arg);
-      Vcurrent_prefix_arg = prefixarg;
-      kset_prefix_arg (current_kboard, Qnil);
-    }
-  else
-    prefixarg = Qnil;
-
-  if (SYMBOLP (cmd))
-    {
-      tem = Fget (cmd, Qdisabled);
-      if (!NILP (tem))
-       {
-         tem = Fsymbol_value (Qdisabled_command_function);
-         if (!NILP (tem))
-           return Frun_hooks (1, &Qdisabled_command_function);
-       }
-    }
-
-  while (1)
-    {
-      final = Findirect_function (cmd, Qnil);
-
-      if (CONSP (final) && (tem = Fcar (final), EQ (tem, Qautoload)))
-       {
-         struct gcpro gcpro1, gcpro2;
-
-         GCPRO2 (cmd, prefixarg);
-         Fautoload_do_load (final, cmd, Qnil);
-         UNGCPRO;
-       }
-      else
-       break;
-    }
-
-  if (STRINGP (final) || VECTORP (final))
-    {
-      /* If requested, place the macro in the command history.  For
-        other sorts of commands, call-interactively takes care of
-        this.  */
-      if (!NILP (record_flag))
-       {
-         Vcommand_history
-           = Fcons (Fcons (Qexecute_kbd_macro,
-                           Fcons (final, Fcons (prefixarg, Qnil))),
-                    Vcommand_history);
-
-         /* Don't keep command history around forever.  */
-         if (NUMBERP (Vhistory_length) && XINT (Vhistory_length) > 0)
-           {
-             tem = Fnthcdr (Vhistory_length, Vcommand_history);
-             if (CONSP (tem))
-               XSETCDR (tem, Qnil);
-           }
-       }
-
-      return Fexecute_kbd_macro (final, prefixarg, Qnil);
-    }
-
-  if (CONSP (final) || SUBRP (final) || COMPILEDP (final))
-    /* Don't call Fcall_interactively directly because we want to make
-       sure the backtrace has an entry for `call-interactively'.
-       For the same reason, pass `cmd' rather than `final'.  */
-      return call3 (Qcall_interactively, cmd, record_flag, keys);
-
-  return Qnil;
-}
-
-
-\f
 /* Return true if input events are pending.  */
 
 bool
@@ -10643,7 +10568,7 @@ See also `current-input-mode'.  */)
   if (tty->flow_control != !NILP (flow))
     {
 #ifndef DOS_NT
-      /* this causes startup screen to be restored and messes with the mouse */
+      /* This causes startup screen to be restored and messes with the mouse.  */
       reset_sys_modes (tty);
 #endif
 
@@ -11083,17 +11008,13 @@ syms_of_keyboard (void)
   DEFSYM (Qlanguage_change, "language-change");
 #endif
 
-#ifdef WINDOWSNT
-  DEFSYM (Qfile_w32notify, "file-w32notify");
-#endif
-
 #ifdef HAVE_DBUS
   DEFSYM (Qdbus_event, "dbus-event");
 #endif
 
-#ifdef HAVE_INOTIFY
-  DEFSYM (Qfile_inotify, "file-inotify");
-#endif /* HAVE_INOTIFY */
+#ifdef USE_FILE_NOTIFY
+  DEFSYM (Qfile_notify, "file-notify");
+#endif /* USE_FILE_NOTIFY */
 
   DEFSYM (QCenable, ":enable");
   DEFSYM (QCvisible, ":visible");
@@ -11148,9 +11069,6 @@ syms_of_keyboard (void)
   Fset (Qinput_method_exit_on_first_char, Qnil);
   Fset (Qinput_method_use_echo_area, Qnil);
 
-  last_point_position_buffer = Qnil;
-  last_point_position_window = Qnil;
-
   {
     int i;
     int len = sizeof (head_table) / sizeof (head_table[0]);
@@ -11194,8 +11112,7 @@ syms_of_keyboard (void)
   raw_keybuf = Fmake_vector (make_number (30), Qnil);
   staticpro (&raw_keybuf);
 
-  DEFSYM (Qextended_command_history, "extended-command-history");
-  Fset (Qextended_command_history, Qnil);
+  DEFSYM (Qcommand_execute, "command-execute");
 
   accent_key_syms = Qnil;
   staticpro (&accent_key_syms);
@@ -11234,7 +11151,6 @@ syms_of_keyboard (void)
   defsubr (&Srecursive_edit);
   defsubr (&Strack_mouse);
   defsubr (&Sinput_pending_p);
-  defsubr (&Scommand_execute);
   defsubr (&Srecent_keys);
   defsubr (&Sthis_command_keys);
   defsubr (&Sthis_command_keys_vector);
@@ -11535,10 +11451,7 @@ tool-bar separators natively.  Otherwise it is unused (e.g. on GTK).  */);
 
   DEFVAR_KBOARD ("overriding-terminal-local-map",
                 Voverriding_terminal_local_map,
-                doc: /* Per-terminal keymap that overrides all other local keymaps.
-If this variable is non-nil, it is used as a keymap instead of the
-buffer's local map, and the minor mode keymaps and text property keymaps.
-It also replaces `overriding-local-map'.
+                doc: /* Per-terminal keymap that takes precedence over all other keymaps.
 
 This variable is intended to let commands such as `universal-argument'
 set up a different keymap for reading the next command.
@@ -11548,7 +11461,7 @@ terminal device.
 See Info node `(elisp)Multiple Terminals'.  */);
 
   DEFVAR_LISP ("overriding-local-map", Voverriding_local_map,
-              doc: /* Keymap that overrides all other local keymaps.
+              doc: /* Keymap that overrides almost all other local keymaps.
 If this variable is non-nil, it is used as a keymap--replacing the
 buffer's local map, the minor mode keymaps, and char property keymaps.  */);
   Voverriding_local_map = Qnil;
@@ -11844,20 +11757,18 @@ keys_of_keyboard (void)
                            "dbus-handle-event");
 #endif
 
-#ifdef HAVE_INOTIFY
-  /* Define a special event which is raised for inotify callback
+#ifdef USE_FILE_NOTIFY
+  /* Define a special event which is raised for notification callback
      functions.  */
-  initial_define_lispy_key (Vspecial_event_map, "file-inotify",
-                            "inotify-handle-event");
-#endif /* HAVE_INOTIFY */
+  initial_define_lispy_key (Vspecial_event_map, "file-notify",
+                            "file-notify-handle-event");
+#endif /* USE_FILE_NOTIFY */
 
   initial_define_lispy_key (Vspecial_event_map, "config-changed-event",
                            "ignore");
 #if defined (WINDOWSNT)
   initial_define_lispy_key (Vspecial_event_map, "language-change",
                            "ignore");
-  initial_define_lispy_key (Vspecial_event_map, "file-w32notify",
-                           "w32notify-handle-event");
 #endif
 }