Convert safe_call to use variable number of arguments.
[bpt/emacs.git] / src / keyboard.c
index a771c9c..00e6f4c 100644 (file)
@@ -1,6 +1,6 @@
 /* Keyboard and mouse input; editor command loop.
 
 /* Keyboard and mouse input; editor command loop.
 
-Copyright (C) 1985-1989, 1993-1997, 1999-2011  Free Software Foundation, Inc.
+Copyright (C) 1985-1989, 1993-1997, 1999-2012  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 
 This file is part of GNU Emacs.
 
@@ -30,8 +30,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "keyboard.h"
 #include "window.h"
 #include "commands.h"
 #include "keyboard.h"
 #include "window.h"
 #include "commands.h"
-#include "buffer.h"
 #include "character.h"
 #include "character.h"
+#include "buffer.h"
 #include "disptab.h"
 #include "dispextern.h"
 #include "syntax.h"
 #include "disptab.h"
 #include "dispextern.h"
 #include "syntax.h"
@@ -73,7 +73,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "nsterm.h"
 #endif
 
 #include "nsterm.h"
 #endif
 
-/* Variables for blockinput.h: */
+/* Variables for blockinput.h:  */
 
 /* Non-zero if interrupt input is blocked right now.  */
 volatile int interrupt_input_blocked;
 
 /* Non-zero if interrupt input is blocked right now.  */
 volatile int interrupt_input_blocked;
@@ -217,9 +217,6 @@ uintmax_t num_input_events;
 
 static EMACS_INT last_auto_save;
 
 
 static EMACS_INT last_auto_save;
 
-/* This is like Vthis_command, except that commands never set it.  */
-Lisp_Object real_this_command;
-
 /* The value of point when the last command was started.  */
 static ptrdiff_t last_point_position;
 
 /* The value of point when the last command was started.  */
 static ptrdiff_t last_point_position;
 
@@ -241,6 +238,7 @@ Lisp_Object internal_last_event_frame;
 Time last_event_timestamp;
 
 static Lisp_Object Qx_set_selection, Qhandle_switch_frame;
 Time last_event_timestamp;
 
 static Lisp_Object Qx_set_selection, Qhandle_switch_frame;
+static Lisp_Object Qhandle_select_window;
 Lisp_Object QPRIMARY;
 
 static Lisp_Object Qself_insert_command;
 Lisp_Object QPRIMARY;
 
 static Lisp_Object Qself_insert_command;
@@ -252,6 +250,7 @@ static Lisp_Object Qtimer_event_handler;
 /* read_key_sequence stores here the command definition of the
    key sequence that it reads.  */
 static Lisp_Object read_key_sequence_cmd;
 /* read_key_sequence stores here the command definition of the
    key sequence that it reads.  */
 static Lisp_Object read_key_sequence_cmd;
+static Lisp_Object read_key_sequence_remapped;
 
 static Lisp_Object Qinput_method_function;
 
 
 static Lisp_Object Qinput_method_function;
 
@@ -337,7 +336,7 @@ static Lisp_Object Qconfig_changed_event;
 Lisp_Object Qevent_kind;
 static Lisp_Object Qevent_symbol_elements;
 
 Lisp_Object Qevent_kind;
 static Lisp_Object Qevent_symbol_elements;
 
-/* menu and tool bar item parts */
+/* Menu and tool bar item parts.  */
 static Lisp_Object Qmenu_enable;
 static Lisp_Object QCenable, QCvisible, QChelp, QCkeys, QCkey_sequence;
 Lisp_Object QCfilter;
 static Lisp_Object Qmenu_enable;
 static Lisp_Object QCenable, QCvisible, QChelp, QCkeys, QCkey_sequence;
 Lisp_Object QCfilter;
@@ -460,10 +459,9 @@ static void interrupt_signal (int signalnum);
 #ifdef SIGIO
 static void input_available_signal (int signo);
 #endif
 #ifdef SIGIO
 static void input_available_signal (int signo);
 #endif
-static Lisp_Object (Fcommand_execute) (Lisp_Object, Lisp_Object, Lisp_Object,
-                                      Lisp_Object);
 static void handle_interrupt (void);
 static void handle_interrupt (void);
-static void quit_throw_to_read_char (void) NO_RETURN;
+static _Noreturn void quit_throw_to_read_char (int);
+static void process_special_events (void);
 static void timer_start_idle (void);
 static void timer_stop_idle (void);
 static void timer_resume_idle (void);
 static void timer_start_idle (void);
 static void timer_stop_idle (void);
 static void timer_resume_idle (void);
@@ -482,7 +480,7 @@ echo_char (Lisp_Object c)
   if (current_kboard->immediate_echo)
     {
       int size = KEY_DESCRIPTION_SIZE + 100;
   if (current_kboard->immediate_echo)
     {
       int size = KEY_DESCRIPTION_SIZE + 100;
-      char *buffer = (char *) alloca (size);
+      char *buffer = alloca (size);
       char *ptr = buffer;
       Lisp_Object echo_string;
 
       char *ptr = buffer;
       Lisp_Object echo_string;
 
@@ -504,7 +502,7 @@ echo_char (Lisp_Object c)
            {
              int offset = ptr - buffer;
              size = max (2 * size, size + nbytes);
            {
              int offset = ptr - buffer;
              size = max (2 * size, size + nbytes);
-             buffer = (char *) alloca (size);
+             buffer = alloca (size);
              ptr = buffer + offset;
            }
 
              ptr = buffer + offset;
            }
 
@@ -522,7 +520,7 @@ echo_char (Lisp_Object c)
            {
              int offset = ptr - buffer;
              size += len;
            {
              int offset = ptr - buffer;
              size += len;
-             buffer = (char *) alloca (size);
+             buffer = alloca (size);
              ptr = buffer + offset;
            }
 
              ptr = buffer + offset;
            }
 
@@ -625,7 +623,7 @@ echo_now (void)
          if (i == this_single_command_key_start)
            before_command_echo_length = echo_length ();
 
          if (i == this_single_command_key_start)
            before_command_echo_length = echo_length ();
 
-         c = XVECTOR (this_command_keys)->contents[i];
+         c = AREF (this_command_keys, i);
          if (! (EVENT_HAS_PARAMETERS (c)
                 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
            echo_char (c);
          if (! (EVENT_HAS_PARAMETERS (c)
                 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
            echo_char (c);
@@ -652,7 +650,7 @@ echo_now (void)
   echo_kboard = current_kboard;
 
   if (waiting_for_input && !NILP (Vquit_flag))
   echo_kboard = current_kboard;
 
   if (waiting_for_input && !NILP (Vquit_flag))
-    quit_throw_to_read_char ();
+    quit_throw_to_read_char (0);
 }
 
 /* Turn off echoing, for the start of a new command.  */
 }
 
 /* Turn off echoing, for the start of a new command.  */
@@ -832,7 +830,7 @@ recursive_edit_unwind (Lisp_Object buffer)
 
 \f
 #if 0  /* These two functions are now replaced with
 
 \f
 #if 0  /* These two functions are now replaced with
-          temporarily_switch_to_single_kboard. */
+          temporarily_switch_to_single_kboard.  */
 static void
 any_kboard_state ()
 {
 static void
 any_kboard_state ()
 {
@@ -886,8 +884,7 @@ static struct kboard_stack *kboard_stack;
 void
 push_kboard (struct kboard *k)
 {
 void
 push_kboard (struct kboard *k)
 {
-  struct kboard_stack *p
-    = (struct kboard_stack *) xmalloc (sizeof (struct kboard_stack));
+  struct kboard_stack *p = xmalloc (sizeof *p);
 
   p->next = kboard_stack;
   p->kboard = current_kboard;
 
   p->next = kboard_stack;
   p->kboard = current_kboard;
@@ -929,7 +926,7 @@ pop_kboard (void)
   state later.
 
   If Emacs is already in single_kboard mode, and F's keyboard is
   state later.
 
   If Emacs is already in single_kboard mode, and F's keyboard is
-  locked, then this function will throw an errow.  */
+  locked, then this function will throw an error.  */
 
 void
 temporarily_switch_to_single_kboard (struct frame *f)
 
 void
 temporarily_switch_to_single_kboard (struct frame *f)
@@ -1035,7 +1032,7 @@ cmd_error (Lisp_Object data)
   Vquit_flag = Qnil;
 
   Vinhibit_quit = Qnil;
   Vquit_flag = Qnil;
 
   Vinhibit_quit = Qnil;
-#if 0 /* This shouldn't be necessary anymore. --lorentey */
+#if 0 /* This shouldn't be necessary anymore.  --lorentey  */
   if (command_loop_level == 0 && minibuf_level == 0)
     any_kboard_state ();
 #endif
   if (command_loop_level == 0 && minibuf_level == 0)
     any_kboard_state ();
 #endif
@@ -1057,7 +1054,7 @@ cmd_error_internal (Lisp_Object data, const char *context)
   struct frame *sf = SELECTED_FRAME ();
 
   /* The immediate context is not interesting for Quits,
   struct frame *sf = SELECTED_FRAME ();
 
   /* The immediate context is not interesting for Quits,
-     since they are asyncronous.  */
+     since they are asynchronous.  */
   if (EQ (XCAR (data), Qquit))
     Vsignaling_function = Qnil;
 
   if (EQ (XCAR (data), Qquit))
     Vsignaling_function = Qnil;
 
@@ -1128,7 +1125,7 @@ command_loop (void)
 #if 0 /* This shouldn't be necessary anymore.  --lorentey  */
         /* Reset single_kboard in case top-level set it while
            evaluating an -f option, or we are stuck there for some
 #if 0 /* This shouldn't be necessary anymore.  --lorentey  */
         /* Reset single_kboard in case top-level set it while
            evaluating an -f option, or we are stuck there for some
-           other reason. */
+           other reason.  */
         any_kboard_state ();
 #endif
        internal_catch (Qtop_level, command_loop_2, Qnil);
         any_kboard_state ();
 #endif
        internal_catch (Qtop_level, command_loop_2, Qnil);
@@ -1195,7 +1192,13 @@ This also exits all active minibuffers.  */)
   Fthrow (Qtop_level, Qnil);
 }
 
   Fthrow (Qtop_level, Qnil);
 }
 
-static Lisp_Object Fexit_recursive_edit (void) NO_RETURN;
+static _Noreturn void
+user_error (const char *msg)
+{
+  xsignal1 (Quser_error, build_string (msg));
+}
+
+_Noreturn
 DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0, "",
        doc: /* Exit from the innermost recursive edit or minibuffer.  */)
   (void)
 DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0, "",
        doc: /* Exit from the innermost recursive edit or minibuffer.  */)
   (void)
@@ -1203,10 +1206,10 @@ DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0,
   if (command_loop_level > 0 || minibuf_level > 0)
     Fthrow (Qexit, Qnil);
 
   if (command_loop_level > 0 || minibuf_level > 0)
     Fthrow (Qexit, Qnil);
 
-  error ("No recursive edit is in progress");
+  user_error ("No recursive edit is in progress");
 }
 
 }
 
-static Lisp_Object Fabort_recursive_edit (void) NO_RETURN;
+_Noreturn
 DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0, 0, "",
        doc: /* Abort the command that requested this recursive edit or minibuffer input.  */)
   (void)
 DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0, 0, "",
        doc: /* Abort the command that requested this recursive edit or minibuffer input.  */)
   (void)
@@ -1214,7 +1217,7 @@ DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0,
   if (command_loop_level > 0 || minibuf_level > 0)
     Fthrow (Qexit, Qt);
 
   if (command_loop_level > 0 || minibuf_level > 0)
     Fthrow (Qexit, Qt);
 
-  error ("No recursive edit is in progress");
+  user_error ("No recursive edit is in progress");
 }
 \f
 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
 }
 \f
 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
@@ -1315,10 +1318,12 @@ cancel_hourglass_unwind (Lisp_Object arg)
 }
 #endif
 
 }
 #endif
 
+/* The last boundary auto-added to buffer-undo-list.  */
+Lisp_Object last_undo_boundary;
+
 /* FIXME: This is wrong rather than test window-system, we should call
    a new set-selection, which will then dispatch to x-set-selection, or
    tty-set-selection, or w32-set-selection, ...  */
 /* FIXME: This is wrong rather than test window-system, we should call
    a new set-selection, which will then dispatch to x-set-selection, or
    tty-set-selection, or w32-set-selection, ...  */
-EXFUN (Fwindow_system, 1);
 
 Lisp_Object
 command_loop_1 (void)
 
 Lisp_Object
 command_loop_1 (void)
@@ -1367,9 +1372,9 @@ command_loop_1 (void)
 
   /* Do this after running Vpost_command_hook, for consistency.  */
   KVAR (current_kboard, Vlast_command) = Vthis_command;
 
   /* Do this after running Vpost_command_hook, for consistency.  */
   KVAR (current_kboard, Vlast_command) = Vthis_command;
-  KVAR (current_kboard, Vreal_last_command) = real_this_command;
+  KVAR (current_kboard, Vreal_last_command) = Vreal_this_command;
   if (!CONSP (last_command_event))
   if (!CONSP (last_command_event))
-    KVAR (current_kboard, Vlast_repeatable_command) = real_this_command;
+    KVAR (current_kboard, Vlast_repeatable_command) = Vreal_this_command;
 
   while (1)
     {
 
   while (1)
     {
@@ -1436,7 +1441,7 @@ command_loop_1 (void)
       before_command_echo_length = echo_length ();
 
       Vthis_command = Qnil;
       before_command_echo_length = echo_length ();
 
       Vthis_command = Qnil;
-      real_this_command = Qnil;
+      Vreal_this_command = Qnil;
       Vthis_original_command = Qnil;
       Vthis_command_keys_shift_translated = Qnil;
 
       Vthis_original_command = Qnil;
       Vthis_command_keys_shift_translated = Qnil;
 
@@ -1475,10 +1480,10 @@ command_loop_1 (void)
         from that position.  But also throw away beg_unchanged and
         end_unchanged information in that case, so that redisplay will
         update the whole window properly.  */
         from that position.  But also throw away beg_unchanged and
         end_unchanged information in that case, so that redisplay will
         update the whole window properly.  */
-      if (!NILP (XWINDOW (selected_window)->force_start))
+      if (XWINDOW (selected_window)->force_start)
        {
          struct buffer *b;
        {
          struct buffer *b;
-         XWINDOW (selected_window)->force_start = Qnil;
+         XWINDOW (selected_window)->force_start = 0;
          b = XBUFFER (XWINDOW (selected_window)->buffer);
          BUF_BEG_UNCHANGED (b) = BUF_END_UNCHANGED (b) = 0;
        }
          b = XBUFFER (XWINDOW (selected_window)->buffer);
          BUF_BEG_UNCHANGED (b) = BUF_END_UNCHANGED (b) = 0;
        }
@@ -1489,8 +1494,8 @@ command_loop_1 (void)
          if (!NILP (Vquit_flag))
            {
              Vexecuting_kbd_macro = Qt;
          if (!NILP (Vquit_flag))
            {
              Vexecuting_kbd_macro = Qt;
-             QUIT;             /* Make some noise. */
-                               /* Will return since macro now empty. */
+             QUIT;             /* Make some noise.  */
+                               /* Will return since macro now empty.  */
            }
        }
 
            }
        }
 
@@ -1509,22 +1514,18 @@ command_loop_1 (void)
       Vdisable_point_adjustment = Qnil;
 
       /* Process filters and timers may have messed with deactivate-mark.
       Vdisable_point_adjustment = Qnil;
 
       /* Process filters and timers may have messed with deactivate-mark.
-        reset it before we execute the command. */
+        reset it before we execute the command.  */
       Vdeactivate_mark = Qnil;
 
       Vdeactivate_mark = Qnil;
 
-      /* Remap command through active keymaps */
+      /* Remap command through active keymaps */
       Vthis_original_command = cmd;
       Vthis_original_command = cmd;
-      if (SYMBOLP (cmd))
-       {
-         Lisp_Object cmd1;
-         if (cmd1 = Fcommand_remapping (cmd, Qnil, Qnil), !NILP (cmd1))
-           cmd = cmd1;
-       }
+      if (!NILP (read_key_sequence_remapped))
+       cmd = read_key_sequence_remapped;
 
       /* Execute the command.  */
 
       Vthis_command = cmd;
 
       /* Execute the command.  */
 
       Vthis_command = cmd;
-      real_this_command = cmd;
+      Vreal_this_command = cmd;
       safe_run_hooks (Qpre_command_hook);
 
       already_adjusted = 0;
       safe_run_hooks (Qpre_command_hook);
 
       already_adjusted = 0;
@@ -1553,7 +1554,7 @@ command_loop_1 (void)
        }
       else
        {
        }
       else
        {
-         /* Here for a command that isn't executed directly */
+         /* Here for a command that isn't executed directly */
 
 #ifdef HAVE_WINDOW_SYSTEM
             ptrdiff_t scount = SPECPDL_INDEX ();
 
 #ifdef HAVE_WINDOW_SYSTEM
             ptrdiff_t scount = SPECPDL_INDEX ();
@@ -1567,7 +1568,13 @@ command_loop_1 (void)
 #endif
 
             if (NILP (KVAR (current_kboard, Vprefix_arg))) /* FIXME: Why?  --Stef  */
 #endif
 
             if (NILP (KVAR (current_kboard, Vprefix_arg))) /* FIXME: Why?  --Stef  */
-              Fundo_boundary ();
+              {
+               Lisp_Object undo = BVAR (current_buffer, undo_list);
+               Fundo_boundary ();
+               last_undo_boundary
+                 = (EQ (undo, BVAR (current_buffer, undo_list))
+                    ? Qnil : BVAR (current_buffer, undo_list));
+             }
             Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil);
 
 #ifdef HAVE_WINDOW_SYSTEM
             Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil);
 
 #ifdef HAVE_WINDOW_SYSTEM
@@ -1608,12 +1615,14 @@ command_loop_1 (void)
         If the command didn't actually create a prefix arg,
         but is merely a frame event that is transparent to prefix args,
         then the above doesn't apply.  */
         If the command didn't actually create a prefix arg,
         but is merely a frame event that is transparent to prefix args,
         then the above doesn't apply.  */
-      if (NILP (KVAR (current_kboard, Vprefix_arg)) || CONSP (last_command_event))
+      if (NILP (KVAR (current_kboard, Vprefix_arg))
+         || CONSP (last_command_event))
        {
          KVAR (current_kboard, Vlast_command) = Vthis_command;
        {
          KVAR (current_kboard, Vlast_command) = Vthis_command;
-         KVAR (current_kboard, Vreal_last_command) = real_this_command;
+         KVAR (current_kboard, Vreal_last_command) = Vreal_this_command;
          if (!CONSP (last_command_event))
          if (!CONSP (last_command_event))
-           KVAR (current_kboard, Vlast_repeatable_command) = real_this_command;
+           KVAR (current_kboard, Vlast_repeatable_command)
+             = Vreal_this_command;
          cancel_echoing ();
          this_command_key_count = 0;
          this_command_key_count_reset = 0;
          cancel_echoing ();
          this_command_key_count = 0;
          this_command_key_count_reset = 0;
@@ -1647,7 +1656,8 @@ command_loop_1 (void)
                      ? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly)
                      : (!NILP (Vselect_active_regions)
                         && !NILP (Vtransient_mark_mode)))
                      ? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly)
                      : (!NILP (Vselect_active_regions)
                         && !NILP (Vtransient_mark_mode)))
-                 && !EQ (Vthis_command, Qhandle_switch_frame))
+                 && NILP (Fmemq (Vthis_command,
+                                 Vselection_inhibit_update_commands)))
                {
                  ptrdiff_t beg =
                    XINT (Fmarker_position (BVAR (current_buffer, mark)));
                {
                  ptrdiff_t beg =
                    XINT (Fmarker_position (BVAR (current_buffer, mark)));
@@ -1747,9 +1757,11 @@ adjust_point_for_property (ptrdiff_t last_pt, int modified)
          && (beg < PT /* && end > PT   <- It's always the case.  */
              || (beg <= PT && STRINGP (val) && SCHARS (val) == 0)))
        {
          && (beg < PT /* && end > PT   <- It's always the case.  */
              || (beg <= PT && STRINGP (val) && SCHARS (val) == 0)))
        {
-         xassert (end > PT);
+         eassert (end > PT);
          SET_PT (PT < last_pt
          SET_PT (PT < last_pt
-                 ? (STRINGP (val) && SCHARS (val) == 0 ? beg - 1 : beg)
+                 ? (STRINGP (val) && SCHARS (val) == 0
+                    ? max (beg - 1, BEGV)
+                    : beg)
                  : end);
          check_composition = check_invisible = 1;
        }
                  : end);
          check_composition = check_invisible = 1;
        }
@@ -1827,7 +1839,7 @@ adjust_point_for_property (ptrdiff_t last_pt, int modified)
 #if 0 /* This assertion isn't correct, because SET_PT may end up setting
         the point to something other than its argument, due to
         point-motion hooks, intangibility, etc.  */
 #if 0 /* This assertion isn't correct, because SET_PT may end up setting
         the point to something other than its argument, due to
         point-motion hooks, intangibility, etc.  */
-         xassert (PT == beg || PT == end);
+         eassert (PT == beg || PT == end);
 #endif
 
          /* Pretend the area doesn't exist if the buffer is not
 #endif
 
          /* Pretend the area doesn't exist if the buffer is not
@@ -1877,7 +1889,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];
     = 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;
   args[1] = hook;
   args[2] = fun;
   args[3] = error_data;
@@ -1961,7 +1973,7 @@ void
 poll_for_input_1 (void)
 {
 /* Tell ns_read_socket() it is being called asynchronously so it can avoid
 poll_for_input_1 (void)
 {
 /* Tell ns_read_socket() it is being called asynchronously so it can avoid
-   doing anything dangerous. */
+   doing anything dangerous.  */
 #ifdef HAVE_NS
   ++handling_signal;
 #endif
 #ifdef HAVE_NS
   ++handling_signal;
 #endif
@@ -2001,7 +2013,7 @@ start_polling (void)
 #ifdef POLL_FOR_INPUT
   /* XXX This condition was (read_socket_hook && !interrupt_input),
      but read_socket_hook is not global anymore.  Let's pretend that
 #ifdef POLL_FOR_INPUT
   /* XXX This condition was (read_socket_hook && !interrupt_input),
      but read_socket_hook is not global anymore.  Let's pretend that
-     it's always set. */
+     it's always set.  */
   if (!interrupt_input)
     {
       /* Turn alarm handling on unconditionally.  It might have
   if (!interrupt_input)
     {
       /* Turn alarm handling on unconditionally.  It might have
@@ -2013,12 +2025,12 @@ start_polling (void)
       if (poll_timer == NULL
          || EMACS_SECS (poll_timer->interval) != polling_period)
        {
       if (poll_timer == NULL
          || EMACS_SECS (poll_timer->interval) != polling_period)
        {
-         EMACS_TIME interval;
+         time_t period = max (1, min (polling_period, TYPE_MAXIMUM (time_t)));
+         EMACS_TIME interval = make_emacs_time (period, 0);
 
          if (poll_timer)
            cancel_atimer (poll_timer);
 
 
          if (poll_timer)
            cancel_atimer (poll_timer);
 
-         EMACS_SET_SECS_USECS (interval, polling_period, 0);
          poll_timer = start_atimer (ATIMER_CONTINUOUS, interval,
                                     poll_for_input, NULL);
        }
          poll_timer = start_atimer (ATIMER_CONTINUOUS, interval,
                                     poll_for_input, NULL);
        }
@@ -2038,7 +2050,7 @@ input_polling_used (void)
 #ifdef POLL_FOR_INPUT
   /* XXX This condition was (read_socket_hook && !interrupt_input),
      but read_socket_hook is not global anymore.  Let's pretend that
 #ifdef POLL_FOR_INPUT
   /* XXX This condition was (read_socket_hook && !interrupt_input),
      but read_socket_hook is not global anymore.  Let's pretend that
-     it's always set. */
+     it's always set.  */
   return !interrupt_input;
 #else
   return 0;
   return !interrupt_input;
 #else
   return 0;
@@ -2053,7 +2065,7 @@ stop_polling (void)
 #ifdef POLL_FOR_INPUT
   /* XXX This condition was (read_socket_hook && !interrupt_input),
      but read_socket_hook is not global anymore.  Let's pretend that
 #ifdef POLL_FOR_INPUT
   /* XXX This condition was (read_socket_hook && !interrupt_input),
      but read_socket_hook is not global anymore.  Let's pretend that
-     it's always set. */
+     it's always set.  */
   if (!interrupt_input)
     ++poll_suppress_count;
 #endif
   if (!interrupt_input)
     ++poll_suppress_count;
 #endif
@@ -2086,7 +2098,7 @@ void
 bind_polling_period (int n)
 {
 #ifdef POLL_FOR_INPUT
 bind_polling_period (int n)
 {
 #ifdef POLL_FOR_INPUT
-  int new = polling_period;
+  EMACS_INT new = polling_period;
 
   if (n > new)
     new = n;
 
   if (n > new)
     new = n;
@@ -2173,14 +2185,7 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object,
   if (!NILP (help) && !STRINGP (help))
     {
       if (FUNCTIONP (help))
   if (!NILP (help) && !STRINGP (help))
     {
       if (FUNCTIONP (help))
-       {
-         Lisp_Object args[4];
-         args[0] = help;
-         args[1] = window;
-         args[2] = object;
-         args[3] = pos;
-         help = safe_call (4, args);
-       }
+       help = safe_call (4, help, window, object, pos);
       else
        help = safe_eval (help);
 
       else
        help = safe_eval (help);
 
@@ -2216,7 +2221,7 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object,
 /* Input of single characters from keyboard */
 
 static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, int *used_mouse_menu,
 /* Input of single characters from keyboard */
 
 static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, int *used_mouse_menu,
-                                        struct timeval *end_time);
+                                        EMACS_TIME *end_time);
 static void record_char (Lisp_Object c);
 
 static Lisp_Object help_form_saved_window_configs;
 static void record_char (Lisp_Object c);
 
 static Lisp_Object help_form_saved_window_configs;
@@ -2239,8 +2244,8 @@ do { if (polling_stopped_here) start_polling ();  \
        polling_stopped_here = 0; } while (0)
 
 /* read a character from the keyboard; call the redisplay if needed */
        polling_stopped_here = 0; } while (0)
 
 /* read a character from the keyboard; call the redisplay if needed */
-/* commandflag 0 means do not do auto-saving, but do do redisplay.
-   -1 means do not do redisplay, but do do autosaving.
+/* commandflag 0 means do not autosave, but do redisplay.
+   -1 means do not redisplay, but do autosave.
    1 means do both.  */
 
 /* The arguments MAPS and NMAPS are for menu prompting.
    1 means do both.  */
 
 /* The arguments MAPS and NMAPS are for menu prompting.
@@ -2268,7 +2273,7 @@ do { if (polling_stopped_here) start_polling ();  \
 Lisp_Object
 read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
           Lisp_Object prev_event,
 Lisp_Object
 read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
           Lisp_Object prev_event,
-          int *used_mouse_menu, struct timeval *end_time)
+          int *used_mouse_menu, EMACS_TIME *end_time)
 {
   volatile Lisp_Object c;
   ptrdiff_t jmpcount;
 {
   volatile Lisp_Object c;
   ptrdiff_t jmpcount;
@@ -2391,7 +2396,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
         real event came from.  Normally, a switch-frame event selects
         internal_last_event_frame after each command is read, but
         events read from a macro should never cause a new frame to be
         real event came from.  Normally, a switch-frame event selects
         internal_last_event_frame after each command is read, but
         events read from a macro should never cause a new frame to be
-        selected. */
+        selected.  */
       Vlast_event_frame = internal_last_event_frame = Qmacro;
 
       /* Exit the macro if we are at the end.
       Vlast_event_frame = internal_last_event_frame = Qmacro;
 
       /* Exit the macro if we are at the end.
@@ -2501,7 +2506,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
      Try this before the sit-for, because the sit-for
      would do the wrong thing if we are supposed to do
      menu prompting. If EVENT_HAS_PARAMETERS then we are reading
      Try this before the sit-for, because the sit-for
      would do the wrong thing if we are supposed to do
      menu prompting. If EVENT_HAS_PARAMETERS then we are reading
-     after a mouse event so don't try a minibuf menu. */
+     after a mouse event so don't try a minibuf menu.  */
   c = Qnil;
   if (nmaps > 0 && INTERACTIVE
       && !NILP (prev_event) && ! EVENT_HAS_PARAMETERS (prev_event)
   c = Qnil;
   if (nmaps > 0 && INTERACTIVE
       && !NILP (prev_event) && ! EVENT_HAS_PARAMETERS (prev_event)
@@ -2693,17 +2698,13 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
              && ! CONSP (Vunread_command_events))
            {
              Fdo_auto_save (Qnil, Qnil);
              && ! CONSP (Vunread_command_events))
            {
              Fdo_auto_save (Qnil, Qnil);
-
-             /* If we have auto-saved and there is still no input
-                available, garbage collect if there has been enough
-                consing going on to make it worthwhile.  */
-             if (!detect_input_pending_run_timers (0)
-                 && consing_since_gc > gc_cons_threshold / 2)
-               Fgarbage_collect ();
-
              redisplay ();
            }
        }
              redisplay ();
            }
        }
+
+      /* If there is still no input available, ask for GC.  */
+      if (!detect_input_pending_run_timers (0))
+       maybe_gc ();
     }
 
   /* Notify the caller if an autosave hook, or a timer, sentinel or
     }
 
   /* Notify the caller if an autosave hook, or a timer, sentinel or
@@ -2782,13 +2783,8 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
     {
       KBOARD *kb IF_LINT (= NULL);
 
     {
       KBOARD *kb IF_LINT (= NULL);
 
-      if (end_time)
-       {
-         EMACS_TIME now;
-         EMACS_GET_TIME (now);
-         if (EMACS_TIME_GE (now, *end_time))
-           goto exit;
-       }
+      if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ()))
+       goto exit;
 
       /* Actually read a character, waiting if necessary.  */
       save_getcjmp (save_jump);
 
       /* Actually read a character, waiting if necessary.  */
       save_getcjmp (save_jump);
@@ -2981,11 +2977,16 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
      own stuff with the echo area.  */
   if (!CONSP (c)
       || (!(EQ (Qhelp_echo, XCAR (c)))
      own stuff with the echo area.  */
   if (!CONSP (c)
       || (!(EQ (Qhelp_echo, XCAR (c)))
-         && !(EQ (Qswitch_frame, XCAR (c)))))
+         && !(EQ (Qswitch_frame, XCAR (c)))
+         /* Don't wipe echo area for select window events: These might
+            get delayed via `mouse-autoselect-window' (Bug#11304).  */
+         && !(EQ (Qselect_window, XCAR (c)))))
     {
       if (!NILP (echo_area_buffer[0]))
     {
       if (!NILP (echo_area_buffer[0]))
-       safe_run_hooks (Qecho_area_clear_hook);
-      clear_message (1, 0);
+       {
+         safe_run_hooks (Qecho_area_clear_hook);
+         clear_message (1, 0);
+       }
     }
 
  reread_for_input_method:
     }
 
  reread_for_input_method:
@@ -3001,7 +3002,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
       Lisp_Object keys;
       ptrdiff_t key_count;
       int key_count_reset;
       Lisp_Object keys;
       ptrdiff_t key_count;
       int key_count_reset;
-      struct gcpro inner_gcpro1;
+      struct gcpro gcpro1;
       ptrdiff_t count = SPECPDL_INDEX ();
 
       /* Save the echo status.  */
       ptrdiff_t count = SPECPDL_INDEX ();
 
       /* Save the echo status.  */
@@ -3029,7 +3030,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
        keys = Fcopy_sequence (this_command_keys);
       else
        keys = Qnil;
        keys = Fcopy_sequence (this_command_keys);
       else
        keys = Qnil;
-      GCPRO1_VAR (keys, inner_gcpro);
+      GCPRO1 (keys);
 
       /* Clear out this_command_keys.  */
       this_command_key_count = 0;
 
       /* Clear out this_command_keys.  */
       this_command_key_count = 0;
@@ -3067,7 +3068,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
       if (saved_immediate_echo)
        echo_now ();
 
       if (saved_immediate_echo)
        echo_now ();
 
-      UNGCPRO_VAR (inner_gcpro);
+      UNGCPRO;
 
       /* The input method can return no events.  */
       if (! CONSP (tem))
 
       /* The input method can return no events.  */
       if (! CONSP (tem))
@@ -3771,9 +3772,8 @@ clear_event (struct input_event *event)
 static Lisp_Object
 kbd_buffer_get_event (KBOARD **kbp,
                       int *used_mouse_menu,
 static Lisp_Object
 kbd_buffer_get_event (KBOARD **kbp,
                       int *used_mouse_menu,
-                      struct timeval *end_time)
+                      EMACS_TIME *end_time)
 {
 {
-  register int c;
   Lisp_Object obj;
 
 #ifdef subprocesses
   Lisp_Object obj;
 
 #ifdef subprocesses
@@ -3790,16 +3790,18 @@ kbd_buffer_get_event (KBOARD **kbp,
     }
 #endif /* subprocesses */
 
     }
 #endif /* subprocesses */
 
+#ifndef HAVE_DBUS  /* We want to read D-Bus events in batch mode.  */
   if (noninteractive
       /* In case we are running as a daemon, only do this before
         detaching from the terminal.  */
       || (IS_DAEMON && daemon_pipe[1] >= 0))
     {
   if (noninteractive
       /* In case we are running as a daemon, only do this before
         detaching from the terminal.  */
       || (IS_DAEMON && daemon_pipe[1] >= 0))
     {
-      c = getchar ();
+      int c = getchar ();
       XSETINT (obj, c);
       *kbp = current_kboard;
       return obj;
     }
       XSETINT (obj, c);
       *kbp = current_kboard;
       return obj;
     }
+#endif /* ! HAVE_DBUS  */
 
   /* Wait until there is input available.  */
   for (;;)
 
   /* Wait until there is input available.  */
   for (;;)
@@ -3820,7 +3822,7 @@ kbd_buffer_get_event (KBOARD **kbp,
       /* If the quit flag is set, then read_char will return
         quit_char, so that counts as "available input."  */
       if (!NILP (Vquit_flag))
       /* If the quit flag is set, then read_char will return
         quit_char, so that counts as "available input."  */
       if (!NILP (Vquit_flag))
-       quit_throw_to_read_char ();
+       quit_throw_to_read_char (0);
 
       /* One way or another, wait until input is available; then, if
         interrupt handlers have not read it, read it now.  */
 
       /* One way or another, wait until input is available; then, if
         interrupt handlers have not read it, read it now.  */
@@ -3837,15 +3839,15 @@ kbd_buffer_get_event (KBOARD **kbp,
 #endif
       if (end_time)
        {
 #endif
       if (end_time)
        {
-         EMACS_TIME duration;
-         EMACS_GET_TIME (duration);
-         if (EMACS_TIME_GE (duration, *end_time))
-           return Qnil;        /* finished waiting */
+         EMACS_TIME now = current_emacs_time ();
+         if (EMACS_TIME_LE (*end_time, now))
+           return Qnil;        /* Finished waiting.  */
          else
            {
          else
            {
-             EMACS_SUB_TIME (duration, *end_time, duration);
-             wait_reading_process_output (EMACS_SECS (duration),
-                                          EMACS_USECS (duration),
+             EMACS_TIME duration = sub_emacs_time (*end_time, now);
+             wait_reading_process_output (min (EMACS_SECS (duration),
+                                               WAIT_READING_MAX),
+                                          EMACS_NSECS (duration),
                                           -1, 1, Qnil, NULL, 0);
            }
        }
                                           -1, 1, Qnil, NULL, 0);
            }
        }
@@ -3967,9 +3969,11 @@ kbd_buffer_get_event (KBOARD **kbp,
 #if defined (WINDOWSNT)
       else if (event->kind == LANGUAGE_CHANGE_EVENT)
        {
 #if defined (WINDOWSNT)
       else if (event->kind == LANGUAGE_CHANGE_EVENT)
        {
-         /* Make an event (language-change (FRAME CHARSET LCID)).  */
-         obj = Fcons (event->frame_or_window, Qnil);
-         obj = Fcons (Qlanguage_change, Fcons (obj, Qnil));
+         /* Make an event (language-change (FRAME CODEPAGE LANGUAGE-ID)).  */
+         obj = Fcons (Qlanguage_change,
+                      list3 (event->frame_or_window,
+                             make_number (event->code),
+                             make_number (event->modifiers)));
          kbd_fetch_ptr = event + 1;
        }
 #endif
          kbd_fetch_ptr = event + 1;
        }
 #endif
@@ -4148,37 +4152,61 @@ kbd_buffer_get_event (KBOARD **kbp,
   return (obj);
 }
 \f
   return (obj);
 }
 \f
-/* Process any events that are not user-visible,
-   then return, without reading any user-visible events.  */
+/* Process any non-user-visible events (currently X selection events),
+   without reading any user-visible events.  */
 
 
-void
-swallow_events (int do_display)
+static void
+process_special_events (void)
 {
 {
-  int old_timers_run;
+  struct input_event *event;
 
 
-  while (kbd_fetch_ptr != kbd_store_ptr)
+  for (event = kbd_fetch_ptr; event != kbd_store_ptr; ++event)
     {
     {
-      struct input_event *event;
-
-      event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE)
-              ? kbd_fetch_ptr
-              : kbd_buffer);
-
-      last_event_timestamp = event->timestamp;
+      if (event == kbd_buffer + KBD_BUFFER_SIZE)
+       {
+         event = kbd_buffer;
+         if (event == kbd_store_ptr)
+           break;
+       }
 
 
-      /* These two kinds of events get special handling
-        and don't actually appear to the command loop.  */
+      /* If we find a stored X selection request, handle it now.  */
       if (event->kind == SELECTION_REQUEST_EVENT
          || event->kind == SELECTION_CLEAR_EVENT)
        {
 #ifdef HAVE_X11
       if (event->kind == SELECTION_REQUEST_EVENT
          || event->kind == SELECTION_CLEAR_EVENT)
        {
 #ifdef HAVE_X11
-         struct input_event copy;
 
 
-         /* Remove it from the buffer before processing it,
-            since otherwise swallow_events called recursively could see it
-            and process it again.  */
-         copy = *event;
-         kbd_fetch_ptr = event + 1;
+         /* Remove the event from the fifo buffer before processing;
+            otherwise swallow_events called recursively could see it
+            and process it again.  To do this, we move the events
+            between kbd_fetch_ptr and EVENT one slot to the right,
+            cyclically.  */
+
+         struct input_event copy = *event;
+         struct input_event *beg
+           = (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
+           ? kbd_buffer : kbd_fetch_ptr;
+
+         if (event > beg)
+           memmove (beg + 1, beg, (event - beg) * sizeof (struct input_event));
+         else if (event < beg)
+           {
+             if (event > kbd_buffer)
+               memmove (kbd_buffer + 1, kbd_buffer,
+                        (event - kbd_buffer) * sizeof (struct input_event));
+             *kbd_buffer = *(kbd_buffer + KBD_BUFFER_SIZE - 1);
+             if (beg < kbd_buffer + KBD_BUFFER_SIZE - 1)
+               memmove (beg + 1, beg,
+                        (kbd_buffer + KBD_BUFFER_SIZE - 1 - beg)
+                        * sizeof (struct input_event));
+           }
+
+         if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
+           kbd_fetch_ptr = kbd_buffer + 1;
+         else
+           kbd_fetch_ptr++;
+
+         /* X wants last_event_timestamp for selection ownership.  */
+         last_event_timestamp = copy.timestamp;
          input_pending = readable_events (0);
          x_handle_selection_event (&copy);
 #else
          input_pending = readable_events (0);
          x_handle_selection_event (&copy);
 #else
@@ -4187,9 +4215,18 @@ swallow_events (int do_display)
          abort ();
 #endif
        }
          abort ();
 #endif
        }
-      else
-       break;
     }
     }
+}
+
+/* Process any events that are not user-visible, run timer events that
+   are ripe, and return, without reading any user-visible events.  */
+
+void
+swallow_events (int do_display)
+{
+  int old_timers_run;
+
+  process_special_events ();
 
   old_timers_run = timers_run;
   get_input_pending (&input_pending, READABLE_EVENTS_DO_TIMERS_NOW);
 
   old_timers_run = timers_run;
   get_input_pending (&input_pending, READABLE_EVENTS_DO_TIMERS_NOW);
@@ -4207,11 +4244,10 @@ timer_start_idle (void)
   Lisp_Object timers;
 
   /* If we are already in the idle state, do nothing.  */
   Lisp_Object timers;
 
   /* If we are already in the idle state, do nothing.  */
-  if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
+  if (EMACS_TIME_VALID_P (timer_idleness_start_time))
     return;
 
     return;
 
-  EMACS_GET_TIME (timer_idleness_start_time);
-
+  timer_idleness_start_time = current_emacs_time ();
   timer_last_idleness_start_time = timer_idleness_start_time;
 
   /* Mark all idle-time timers as once again candidates for running.  */
   timer_last_idleness_start_time = timer_idleness_start_time;
 
   /* Mark all idle-time timers as once again candidates for running.  */
@@ -4221,9 +4257,9 @@ timer_start_idle (void)
 
       timer = XCAR (timers);
 
 
       timer = XCAR (timers);
 
-      if (!VECTORP (timer) || ASIZE (timer) != 8)
+      if (!VECTORP (timer) || ASIZE (timer) != 9)
        continue;
        continue;
-      XVECTOR (timer)->contents[0] = Qnil;
+      ASET (timer, 0, Qnil);
     }
 }
 
     }
 }
 
@@ -4232,7 +4268,7 @@ timer_start_idle (void)
 static void
 timer_stop_idle (void)
 {
 static void
 timer_stop_idle (void)
 {
-  EMACS_SET_SECS_USECS (timer_idleness_start_time, -1, -1);
+  timer_idleness_start_time = invalid_emacs_time ();
 }
 
 /* Resume idle timer from last idle start time.  */
 }
 
 /* Resume idle timer from last idle start time.  */
@@ -4240,7 +4276,7 @@ timer_stop_idle (void)
 static void
 timer_resume_idle (void)
 {
 static void
 timer_resume_idle (void)
 {
-  if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
+  if (EMACS_TIME_VALID_P (timer_idleness_start_time))
     return;
 
   timer_idleness_start_time = timer_last_idleness_start_time;
     return;
 
   timer_idleness_start_time = timer_last_idleness_start_time;
@@ -4254,6 +4290,24 @@ struct input_event last_timer_event EXTERNALLY_VISIBLE;
    ...).  Each element has the form (FUN . ARGS).  */
 Lisp_Object pending_funcalls;
 
    ...).  Each element has the form (FUN . ARGS).  */
 Lisp_Object pending_funcalls;
 
+/* If TIMER is a valid timer, return nonzero and place its value into
+   *RESULT.  Otherwise return zero.  */
+static int
+decode_timer (Lisp_Object timer, EMACS_TIME *result)
+{
+  Lisp_Object *vector;
+
+  if (! (VECTORP (timer) && ASIZE (timer) == 9))
+    return 0;
+  vector = XVECTOR (timer)->contents;
+  if (! NILP (vector[0]))
+    return 0;
+
+  return decode_time_components (vector[1], vector[2], vector[3], vector[4],
+                                result, 0);
+}
+
+
 /* Check whether a timer has fired.  To prevent larger problems we simply
    disregard elements that are not proper timers.  Do not make a circular
    timer list for the time being.
 /* Check whether a timer has fired.  To prevent larger problems we simply
    disregard elements that are not proper timers.  Do not make a circular
    timer list for the time being.
@@ -4271,17 +4325,16 @@ timer_check_2 (void)
 {
   EMACS_TIME nexttime;
   EMACS_TIME now;
 {
   EMACS_TIME nexttime;
   EMACS_TIME now;
-  EMACS_TIME idleness_now IF_LINT (= {0});
+  EMACS_TIME idleness_now;
   Lisp_Object timers, idle_timers, chosen_timer;
   struct gcpro gcpro1, gcpro2, gcpro3;
 
   Lisp_Object timers, idle_timers, chosen_timer;
   struct gcpro gcpro1, gcpro2, gcpro3;
 
-  EMACS_SET_SECS (nexttime, -1);
-  EMACS_SET_USECS (nexttime, -1);
+  nexttime = invalid_emacs_time ();
 
   /* Always consider the ordinary timers.  */
   timers = Vtimer_list;
   /* Consider the idle timers only if Emacs is idle.  */
 
   /* Always consider the ordinary timers.  */
   timers = Vtimer_list;
   /* Consider the idle timers only if Emacs is idle.  */
-  if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
+  if (EMACS_TIME_VALID_P (timer_idleness_start_time))
     idle_timers = Vtimer_idle_list;
   else
     idle_timers = Qnil;
     idle_timers = Vtimer_idle_list;
   else
     idle_timers = Qnil;
@@ -4298,9 +4351,10 @@ timer_check_2 (void)
 
   if (CONSP (timers) || CONSP (idle_timers))
     {
 
   if (CONSP (timers) || CONSP (idle_timers))
     {
-      EMACS_GET_TIME (now);
-      if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
-       EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time);
+      now = current_emacs_time ();
+      idleness_now = (EMACS_TIME_VALID_P (timer_idleness_start_time)
+                     ? sub_emacs_time (now, timer_idleness_start_time)
+                     : make_emacs_time (0, 0));
     }
 
   while (CONSP (timers) || CONSP (idle_timers))
     }
 
   while (CONSP (timers) || CONSP (idle_timers))
@@ -4309,113 +4363,79 @@ timer_check_2 (void)
       Lisp_Object timer = Qnil, idle_timer = Qnil;
       EMACS_TIME timer_time, idle_timer_time;
       EMACS_TIME difference;
       Lisp_Object timer = Qnil, idle_timer = Qnil;
       EMACS_TIME timer_time, idle_timer_time;
       EMACS_TIME difference;
-      EMACS_TIME timer_difference IF_LINT (= {0});
-      EMACS_TIME idle_timer_difference IF_LINT (= {0});
+      EMACS_TIME timer_difference = invalid_emacs_time ();
+      EMACS_TIME idle_timer_difference = invalid_emacs_time ();
+      int ripe, timer_ripe = 0, idle_timer_ripe = 0;
 
 
-      /* Skip past invalid timers and timers already handled.  */
+      /* Set TIMER and TIMER_DIFFERENCE
+        based on the next ordinary timer.
+        TIMER_DIFFERENCE is the distance in time from NOW to when
+        this timer becomes ripe (negative if it's already ripe).
+         Skip past invalid timers and timers already handled.  */
       if (CONSP (timers))
        {
          timer = XCAR (timers);
       if (CONSP (timers))
        {
          timer = XCAR (timers);
-         if (!VECTORP (timer) || ASIZE (timer) != 8)
+         if (! decode_timer (timer, &timer_time))
            {
              timers = XCDR (timers);
              continue;
            }
            {
              timers = XCDR (timers);
              continue;
            }
-         vector = XVECTOR (timer)->contents;
 
 
-         if (!INTEGERP (vector[1]) || !INTEGERP (vector[2])
-             || !INTEGERP (vector[3])
-             || ! NILP (vector[0]))
-           {
-             timers = XCDR (timers);
-             continue;
-           }
+         timer_ripe = EMACS_TIME_LE (timer_time, now);
+         timer_difference = (timer_ripe
+                             ? sub_emacs_time (now, timer_time)
+                             : sub_emacs_time (timer_time, now));
        }
        }
+
+      /* Likewise for IDLE_TIMER and IDLE_TIMER_DIFFERENCE
+        based on the next idle timer.  */
       if (CONSP (idle_timers))
        {
       if (CONSP (idle_timers))
        {
-         timer = XCAR (idle_timers);
-         if (!VECTORP (timer) || ASIZE (timer) != 8)
-           {
-             idle_timers = XCDR (idle_timers);
-             continue;
-           }
-         vector = XVECTOR (timer)->contents;
-
-         if (!INTEGERP (vector[1]) || !INTEGERP (vector[2])
-             || !INTEGERP (vector[3])
-             || ! NILP (vector[0]))
+         idle_timer = XCAR (idle_timers);
+         if (! decode_timer (idle_timer, &idle_timer_time))
            {
              idle_timers = XCDR (idle_timers);
              continue;
            }
            {
              idle_timers = XCDR (idle_timers);
              continue;
            }
-       }
-
-      /* Set TIMER, TIMER_TIME and TIMER_DIFFERENCE
-        based on the next ordinary timer.
-        TIMER_DIFFERENCE is the distance in time from NOW to when
-        this timer becomes ripe (negative if it's already ripe).  */
-      if (CONSP (timers))
-       {
-         timer = XCAR (timers);
-         vector = XVECTOR (timer)->contents;
-         EMACS_SET_SECS (timer_time,
-                         (XINT (vector[1]) << 16) | (XINT (vector[2])));
-         EMACS_SET_USECS (timer_time, XINT (vector[3]));
-         EMACS_SUB_TIME (timer_difference, timer_time, now);
-       }
 
 
-      /* Set IDLE_TIMER, IDLE_TIMER_TIME and IDLE_TIMER_DIFFERENCE
-        based on the next idle timer.  */
-      if (CONSP (idle_timers))
-       {
-         idle_timer = XCAR (idle_timers);
-         vector = XVECTOR (idle_timer)->contents;
-         EMACS_SET_SECS (idle_timer_time,
-                         (XINT (vector[1]) << 16) | (XINT (vector[2])));
-         EMACS_SET_USECS (idle_timer_time, XINT (vector[3]));
-         EMACS_SUB_TIME (idle_timer_difference, idle_timer_time, idleness_now);
+         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));
        }
 
       /* Decide which timer is the next timer,
        }
 
       /* Decide which timer is the next timer,
-        and set CHOSEN_TIMER, VECTOR and DIFFERENCE accordingly.
+        and set CHOSEN_TIMER, DIFFERENCE, and RIPE accordingly.
         Also step down the list where we found that timer.  */
 
         Also step down the list where we found that timer.  */
 
-      if (CONSP (timers) && CONSP (idle_timers))
-       {
-         EMACS_TIME temp;
-         EMACS_SUB_TIME (temp, timer_difference, idle_timer_difference);
-         if (EMACS_TIME_NEG_P (temp))
-           {
-             chosen_timer = timer;
-             timers = XCDR (timers);
-             difference = timer_difference;
-           }
-         else
-           {
-             chosen_timer = idle_timer;
-             idle_timers = XCDR (idle_timers);
-             difference = idle_timer_difference;
-           }
-       }
-      else if (CONSP (timers))
+      if (EMACS_TIME_VALID_P (timer_difference)
+         && (! EMACS_TIME_VALID_P (idle_timer_difference)
+             || idle_timer_ripe < timer_ripe
+             || (idle_timer_ripe == timer_ripe
+                 && (timer_ripe
+                     ? EMACS_TIME_LT (idle_timer_difference,
+                                      timer_difference)
+                     : EMACS_TIME_LT (timer_difference,
+                                      idle_timer_difference)))))
        {
          chosen_timer = timer;
          timers = XCDR (timers);
          difference = timer_difference;
        {
          chosen_timer = timer;
          timers = XCDR (timers);
          difference = timer_difference;
+         ripe = timer_ripe;
        }
       else
        {
          chosen_timer = idle_timer;
          idle_timers = XCDR (idle_timers);
          difference = idle_timer_difference;
        }
       else
        {
          chosen_timer = idle_timer;
          idle_timers = XCDR (idle_timers);
          difference = idle_timer_difference;
+         ripe = idle_timer_ripe;
        }
        }
-      vector = XVECTOR (chosen_timer)->contents;
 
       /* If timer is ripe, run it if it hasn't been run.  */
 
       /* If timer is ripe, run it if it hasn't been run.  */
-      if (EMACS_TIME_NEG_P (difference)
-         || (EMACS_SECS (difference) == 0
-             && EMACS_USECS (difference) == 0))
+      if (ripe)
        {
        {
+         vector = XVECTOR (chosen_timer)->contents;
          if (NILP (vector[0]))
            {
              ptrdiff_t count = SPECPDL_INDEX ();
          if (NILP (vector[0]))
            {
              ptrdiff_t count = SPECPDL_INDEX ();
@@ -4438,8 +4458,7 @@ timer_check_2 (void)
                  return 0 to indicate that.  */
            }
 
                  return 0 to indicate that.  */
            }
 
-          EMACS_SET_SECS (nexttime, 0);
-          EMACS_SET_USECS (nexttime, 0);
+         nexttime = make_emacs_time (0, 0);
        }
       else
        /* When we encounter a timer that is still waiting,
        }
       else
        /* When we encounter a timer that is still waiting,
@@ -4462,7 +4481,7 @@ timer_check_2 (void)
    timer list for the time being.
 
    Returns the time to wait until the next timer fires.
    timer list for the time being.
 
    Returns the time to wait until the next timer fires.
-   If no timer is active, return -1.
+   If no timer is active, return an invalid value.
 
    As long as any timer is ripe, we run it.  */
 
 
    As long as any timer is ripe, we run it.  */
 
@@ -4475,34 +4494,24 @@ timer_check (void)
     {
       nexttime = timer_check_2 ();
     }
     {
       nexttime = timer_check_2 ();
     }
-  while (EMACS_SECS (nexttime) == 0 && EMACS_USECS (nexttime) == 0);
+  while (EMACS_SECS (nexttime) == 0 && EMACS_NSECS (nexttime) == 0);
 
   return nexttime;
 }
 
 DEFUN ("current-idle-time", Fcurrent_idle_time, Scurrent_idle_time, 0, 0, 0,
        doc: /* Return the current length of Emacs idleness, or nil.
 
   return nexttime;
 }
 
 DEFUN ("current-idle-time", Fcurrent_idle_time, Scurrent_idle_time, 0, 0, 0,
        doc: /* Return the current length of Emacs idleness, or nil.
-The value when Emacs is idle is a list of three integers.  The first has
-the most significant 16 bits of the seconds, while the second has the least
-significant 16 bits.  The third integer gives the microsecond count.
+The value when Emacs is idle is a list of four integers (HIGH LOW USEC PSEC)
+in the same style as (current-time).
 
 The value when Emacs is not idle is nil.
 
 
 The value when Emacs is not idle is nil.
 
-The microsecond count is zero on systems that do not provide
-resolution finer than a second.  */)
+NSEC is a multiple of the system clock resolution.  */)
   (void)
 {
   (void)
 {
-  if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
-    {
-      EMACS_TIME now, idleness_now;
-
-      EMACS_GET_TIME (now);
-      EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time);
-
-      return list3 (make_number ((EMACS_SECS (idleness_now) >> 16) & 0xffff),
-                   make_number ((EMACS_SECS (idleness_now) >> 0)  & 0xffff),
-                   make_number (EMACS_USECS (idleness_now)));
-    }
+  if (EMACS_TIME_VALID_P (timer_idleness_start_time))
+    return make_lisp_time (sub_emacs_time (current_emacs_time (),
+                                          timer_idleness_start_time));
 
   return Qnil;
 }
 
   return Qnil;
 }
@@ -4816,7 +4825,7 @@ const char *const lispy_function_keys[] =
     "ico-00",        /* VK_ICO_00         0xE4 */
     0,               /* VK_PROCESSKEY     0xE5 - used by IME */
     "ico-clear",     /* VK_ICO_CLEAR      0xE6 */
     "ico-00",        /* VK_ICO_00         0xE4 */
     0,               /* VK_PROCESSKEY     0xE5 - used by IME */
     "ico-clear",     /* VK_ICO_CLEAR      0xE6 */
-    0,               /* VK_PACKET         0xE7  - used to pass unicode chars */
+    0,               /* VK_PACKET         0xE7  - used to pass Unicode chars */
     0,               /*                   0xE8 */
     "reset",         /* VK_OEM_RESET      0xE9 */
     "jump",          /* VK_OEM_JUMP       0xEA */
     0,               /*                   0xE8 */
     "reset",         /* VK_OEM_RESET      0xE9 */
     "jump",          /* VK_OEM_JUMP       0xEA */
@@ -4983,8 +4992,8 @@ static const char *const lispy_function_keys[] =
     "break",                   /* 0xff6b */
 
     0, 0, 0, 0,
     "break",                   /* 0xff6b */
 
     0, 0, 0, 0,
-    0, 0, 0, 0, "backtab", 0, 0, 0,            /* 0xff70... */
-    0, 0, 0, 0, 0, 0, 0, "kp-numlock",         /* 0xff78... */
+    0, 0, 0, 0, "backtab", 0, 0, 0,            /* 0xff70...  */
+    0, 0, 0, 0, 0, 0, 0, "kp-numlock",         /* 0xff78...  */
     "kp-space",                        /* 0xff80 */    /* IsKeypadKey */
     0, 0, 0, 0, 0, 0, 0, 0,
     "kp-tab",                  /* 0xff89 */
     "kp-space",                        /* 0xff80 */    /* IsKeypadKey */
     0, 0, 0, 0, 0, 0, 0, 0,
     "kp-tab",                  /* 0xff89 */
@@ -5096,14 +5105,14 @@ static Lisp_Object *const scroll_bar_parts[] = {
 static Lisp_Object button_down_location;
 
 /* Information about the most recent up-going button event:  Which
 static Lisp_Object button_down_location;
 
 /* Information about the most recent up-going button event:  Which
-   button, what location, and what time. */
+   button, what location, and what time.  */
 
 static int last_mouse_button;
 static int last_mouse_x;
 static int last_mouse_y;
 static Time button_down_time;
 
 
 static int last_mouse_button;
 static int last_mouse_x;
 static int last_mouse_y;
 static Time button_down_time;
 
-/* The number of clicks in this multiple-click. */
+/* The number of clicks in this multiple-click.  */
 
 static int double_click_count;
 
 
 static int double_click_count;
 
@@ -5126,7 +5135,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
 
   if (WINDOWP (window))
     {
 
   if (WINDOWP (window))
     {
-      /* It's a click in window window at frame coordinates (x,y)  */
+      /* It's a click in window WINDOW at frame coordinates (X,Y)  */
       struct window *w = XWINDOW (window);
       Lisp_Object string_info = Qnil;
       ptrdiff_t textpos = -1;
       struct window *w = XWINDOW (window);
       Lisp_Object string_info = Qnil;
       ptrdiff_t textpos = -1;
@@ -5347,7 +5356,7 @@ make_lispy_event (struct input_event *event)
 
 #ifdef HAVE_NS
       /* NS_NONKEY_EVENTs are just like NON_ASCII_KEYSTROKE_EVENTs,
 
 #ifdef HAVE_NS
       /* NS_NONKEY_EVENTs are just like NON_ASCII_KEYSTROKE_EVENTs,
-        except that they are non-key events (last-nonmenu-event is nil). */
+        except that they are non-key events (last-nonmenu-event is nil).  */
     case NS_NONKEY_EVENT:
 #endif
 
     case NS_NONKEY_EVENT:
 #endif
 
@@ -5396,7 +5405,7 @@ make_lispy_event (struct input_event *event)
          || !lispy_function_keys[event->code - FUNCTION_KEY_OFFSET])
        {
          /* We need to use an alist rather than a vector as the cache
          || !lispy_function_keys[event->code - FUNCTION_KEY_OFFSET])
        {
          /* We need to use an alist rather than a vector as the cache
-            since we can't make a vector long enuf.  */
+            since we can't make a vector long enough.  */
          if (NILP (KVAR (current_kboard, system_key_syms)))
            KVAR (current_kboard, system_key_syms) = Fcons (Qnil, Qnil);
          return modify_event_symbol (event->code,
          if (NILP (KVAR (current_kboard, system_key_syms)))
            KVAR (current_kboard, system_key_syms) = Fcons (Qnil, Qnil);
          return modify_event_symbol (event->code,
@@ -5834,7 +5843,7 @@ make_lispy_event (struct input_event *event)
                                 Fcons (make_number (event->timestamp),
                                        Fcons (part, Qnil)))));
 
                                 Fcons (make_number (event->timestamp),
                                        Fcons (part, Qnil)))));
 
-       /* Always treat scroll bar events as clicks. */
+       /* Always treat scroll bar events as clicks.  */
        event->modifiers |= click_modifier;
        event->modifiers &= ~up_modifier;
 
        event->modifiers |= click_modifier;
        event->modifiers &= ~up_modifier;
 
@@ -6060,7 +6069,7 @@ parse_modifiers_uncached (Lisp_Object symbol, ptrdiff_t *modifier_end)
   modifiers = 0;
   name = SYMBOL_NAME (symbol);
 
   modifiers = 0;
   name = SYMBOL_NAME (symbol);
 
-  for (i = 0; 2 <= SBYTES (name) - i; )
+  for (i = 0; i < SBYTES (name) - 1; )
     {
       ptrdiff_t this_mod_end = 0;
       int this_mod = 0;
     {
       ptrdiff_t this_mod_end = 0;
       int this_mod = 0;
@@ -6102,7 +6111,7 @@ parse_modifiers_uncached (Lisp_Object symbol, ptrdiff_t *modifier_end)
 
 #define MULTI_LETTER_MOD(BIT, NAME, LEN)                       \
          if (i + LEN + 1 <= SBYTES (name)                      \
 
 #define MULTI_LETTER_MOD(BIT, NAME, LEN)                       \
          if (i + LEN + 1 <= SBYTES (name)                      \
-             && ! strncmp (SSDATA (name) + i, NAME, LEN))      \
+             && ! memcmp (SDATA (name) + i, NAME, LEN))        \
            {                                                   \
              this_mod_end = i + LEN;                           \
              this_mod = BIT;                                   \
            {                                                   \
              this_mod_end = i + LEN;                           \
              this_mod = BIT;                                   \
@@ -6140,13 +6149,13 @@ parse_modifiers_uncached (Lisp_Object symbol, ptrdiff_t *modifier_end)
   if (! (modifiers & (down_modifier | drag_modifier
                      | double_modifier | triple_modifier))
       && i + 7 == SBYTES (name)
   if (! (modifiers & (down_modifier | drag_modifier
                      | double_modifier | triple_modifier))
       && i + 7 == SBYTES (name)
-      && strncmp (SSDATA (name) + i, "mouse-", 6) == 0
+      && memcmp (SDATA (name) + i, "mouse-", 6) == 0
       && ('0' <= SREF (name, i + 6) && SREF (name, i + 6) <= '9'))
     modifiers |= click_modifier;
 
   if (! (modifiers & (double_modifier | triple_modifier))
       && i + 6 < SBYTES (name)
       && ('0' <= SREF (name, i + 6) && SREF (name, i + 6) <= '9'))
     modifiers |= click_modifier;
 
   if (! (modifiers & (double_modifier | triple_modifier))
       && i + 6 < SBYTES (name)
-      && strncmp (SSDATA (name) + i, "wheel-", 6) == 0)
+      && memcmp (SDATA (name) + i, "wheel-", 6) == 0)
     modifiers |= click_modifier;
 
   if (modifier_end)
     modifiers |= click_modifier;
 
   if (modifier_end)
@@ -6164,8 +6173,7 @@ apply_modifiers_uncached (int modifiers, char *base, int base_len, int base_len_
   /* Since BASE could contain nulls, we can't use intern here; we have
      to use Fintern, which expects a genuine Lisp_String, and keeps a
      reference to it.  */
   /* Since BASE could contain nulls, we can't use intern here; we have
      to use Fintern, which expects a genuine Lisp_String, and keeps a
      reference to it.  */
-  char *new_mods
-    = (char *) alloca (sizeof ("A-C-H-M-S-s-down-drag-double-triple-"));
+  char new_mods[sizeof "A-C-H-M-S-s-down-drag-double-triple-"];
   int mod_len;
 
   {
   int mod_len;
 
   {
@@ -6226,7 +6234,7 @@ lispy_modifier_list (int modifiers)
   modifier_list = Qnil;
   for (i = 0; (1<<i) <= modifiers && i < NUM_MOD_NAMES; i++)
     if (modifiers & (1<<i))
   modifier_list = Qnil;
   for (i = 0; (1<<i) <= modifiers && i < NUM_MOD_NAMES; i++)
     if (modifiers & (1<<i))
-      modifier_list = Fcons (XVECTOR (modifier_symbols)->contents[i],
+      modifier_list = Fcons (AREF (modifier_symbols, i),
                             modifier_list);
 
   return modifier_list;
                             modifier_list);
 
   return modifier_list;
@@ -6457,7 +6465,7 @@ modify_event_symbol (ptrdiff_t symbol_num, int modifiers, Lisp_Object symbol_kin
          *symbol_table = Fmake_vector (size, Qnil);
        }
 
          *symbol_table = Fmake_vector (size, Qnil);
        }
 
-      value = XVECTOR (*symbol_table)->contents[symbol_num];
+      value = AREF (*symbol_table, symbol_num);
     }
 
   /* Have we already used this symbol before?  */
     }
 
   /* Have we already used this symbol before?  */
@@ -6500,7 +6508,7 @@ modify_event_symbol (ptrdiff_t symbol_num, int modifiers, Lisp_Object symbol_kin
       if (CONSP (*symbol_table))
         *symbol_table = Fcons (Fcons (symbol_int, value), *symbol_table);
       else
       if (CONSP (*symbol_table))
         *symbol_table = Fcons (Fcons (symbol_int, value), *symbol_table);
       else
-       XVECTOR (*symbol_table)->contents[symbol_num] = value;
+       ASET (*symbol_table, symbol_num, value);
 
       /* Fill in the cache entries for this symbol; this also
         builds the Qevent_symbol_elements property, which the user
 
       /* Fill in the cache entries for this symbol; this also
         builds the Qevent_symbol_elements property, which the user
@@ -6599,7 +6607,7 @@ parse_solitary_modifier (Lisp_Object symbol)
 
 #define MULTI_LETTER_MOD(BIT, NAME, LEN)               \
       if (LEN == SBYTES (name)                         \
 
 #define MULTI_LETTER_MOD(BIT, NAME, LEN)               \
       if (LEN == SBYTES (name)                         \
-         && ! strncmp (SSDATA (name), NAME, LEN))      \
+         && ! memcmp (SDATA (name), NAME, LEN))        \
        return BIT;
 
     case 'A':
        return BIT;
 
     case 'A':
@@ -6701,7 +6709,7 @@ lucid_event_type_list_p (Lisp_Object object)
    If READABLE_EVENTS_FILTER_EVENTS is set in FLAGS, ignore internal
    events (FOCUS_IN_EVENT).
    If READABLE_EVENTS_IGNORE_SQUEEZABLES is set in FLAGS, ignore mouse
    If READABLE_EVENTS_FILTER_EVENTS is set in FLAGS, ignore internal
    events (FOCUS_IN_EVENT).
    If READABLE_EVENTS_IGNORE_SQUEEZABLES is set in FLAGS, ignore mouse
-   movements and toolkit scroll bar thumb drags. */
+   movements and toolkit scroll bar thumb drags.  */
 
 static void
 get_input_pending (int *addr, int flags)
 
 static void
 get_input_pending (int *addr, int flags)
@@ -6735,7 +6743,7 @@ gobble_input (int expected)
 #ifdef POLL_FOR_INPUT
   /* XXX This condition was (read_socket_hook && !interrupt_input),
      but read_socket_hook is not global anymore.  Let's pretend that
 #ifdef POLL_FOR_INPUT
   /* XXX This condition was (read_socket_hook && !interrupt_input),
      but read_socket_hook is not global anymore.  Let's pretend that
-     it's always set. */
+     it's always set.  */
   if (!interrupt_input && poll_suppress_count == 0)
     {
       SIGMASKTYPE mask;
   if (!interrupt_input && poll_suppress_count == 0)
     {
       SIGMASKTYPE mask;
@@ -6810,7 +6818,7 @@ read_avail_input (int expected)
   if (store_user_signal_events ())
     expected = 0;
 
   if (store_user_signal_events ())
     expected = 0;
 
-  /* Loop through the available terminals, and call their input hooks. */
+  /* Loop through the available terminals, and call their input hooks.  */
   t = terminal_list;
   while (t)
     {
   t = terminal_list;
   while (t)
     {
@@ -6831,15 +6839,15 @@ read_avail_input (int expected)
               expected = 0;
             }
 
               expected = 0;
             }
 
-          if (nr == -1)          /* Not OK to read input now. */
+          if (nr == -1)          /* Not OK to read input now.  */
             {
               err = 1;
             }
             {
               err = 1;
             }
-          else if (nr == -2)          /* Non-transient error. */
+          else if (nr == -2)          /* Non-transient error.  */
             {
             {
-              /* The terminal device terminated; it should be closed. */
+              /* The terminal device terminated; it should be closed.  */
 
 
-              /* Kill Emacs if this was our last terminal. */
+              /* Kill Emacs if this was our last terminal.  */
               if (!terminal_list->next_terminal)
                 /* Formerly simply reported no input, but that
                    sometimes led to a failure of Emacs to terminate.
               if (!terminal_list->next_terminal)
                 /* Formerly simply reported no input, but that
                    sometimes led to a failure of Emacs to terminate.
@@ -6851,7 +6859,7 @@ read_avail_input (int expected)
                    alone in its group.  */
                 kill (getpid (), SIGHUP);
 
                    alone in its group.  */
                 kill (getpid (), SIGHUP);
 
-              /* XXX Is calling delete_terminal safe here?  It calls delete_frame. */
+              /* XXX Is calling delete_terminal safe here?  It calls delete_frame.  */
              {
                Lisp_Object tmp;
                XSETTERMINAL (tmp, t);
              {
                Lisp_Object tmp;
                XSETTERMINAL (tmp, t);
@@ -6941,7 +6949,7 @@ tty_read_avail_input (struct terminal *terminal,
     return 0;
 #endif /* subprocesses */
 
     return 0;
 #endif /* subprocesses */
 
-  if (!terminal->name)         /* Don't read from a dead terminal. */
+  if (!terminal->name)         /* Don't read from a dead terminal.  */
     return 0;
 
   if (terminal->type != output_termcap
     return 0;
 
   if (terminal->type != output_termcap
@@ -6949,15 +6957,15 @@ tty_read_avail_input (struct terminal *terminal,
     abort ();
 
   /* XXX I think the following code should be moved to separate hook
     abort ();
 
   /* XXX I think the following code should be moved to separate hook
-     functions in system-dependent files. */
+     functions in system-dependent files.  */
 #ifdef WINDOWSNT
   return 0;
 #else /* not WINDOWSNT */
 #ifdef WINDOWSNT
   return 0;
 #else /* not WINDOWSNT */
-  if (! tty->term_initted)      /* In case we get called during bootstrap. */
+  if (! tty->term_initted)      /* In case we get called during bootstrap.  */
     return 0;
 
   if (! tty->input)
     return 0;
 
   if (! tty->input)
-    return 0;                   /* The terminal is suspended. */
+    return 0;                   /* The terminal is suspended.  */
 
 #ifdef MSDOS
   n_to_read = dos_keysns ();
 
 #ifdef MSDOS
   n_to_read = dos_keysns ();
@@ -6983,7 +6991,7 @@ tty_read_avail_input (struct terminal *terminal,
                 Gpm_GetEvent closes gpm_fd and clears it to -1, which is why
                we save it in `fd' so close_gpm can remove it from the
                select masks.
                 Gpm_GetEvent closes gpm_fd and clears it to -1, which is why
                we save it in `fd' so close_gpm can remove it from the
                select masks.
-         gpm==-1 if a protocol error or EWOULDBLOCK; the latter is normal. */
+         gpm==-1 if a protocol error or EWOULDBLOCK; the latter is normal.  */
       while (gpm = Gpm_GetEvent (&event), gpm == 1) {
          nread += handle_one_term_event (tty, &event, &gpm_hold_quit);
       }
       while (gpm = Gpm_GetEvent (&event), gpm == 1) {
          nread += handle_one_term_event (tty, &event, &gpm_hold_quit);
       }
@@ -7003,7 +7011,7 @@ tty_read_avail_input (struct terminal *terminal,
   if (ioctl (fileno (tty->input), FIONREAD, &n_to_read) < 0)
     {
       if (! noninteractive)
   if (ioctl (fileno (tty->input), FIONREAD, &n_to_read) < 0)
     {
       if (! noninteractive)
-        return -2;          /* Close this terminal. */
+        return -2;          /* Close this terminal.  */
       else
         n_to_read = 0;
     }
       else
         n_to_read = 0;
     }
@@ -7036,16 +7044,16 @@ tty_read_avail_input (struct terminal *terminal,
          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.
          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. */
+         Jeffrey Honig <jch@bsdi.com> says this is generally safe.  */
       if (nread == -1 && errno == EIO)
       if (nread == -1 && errno == EIO)
-        return -2;          /* Close this terminal. */
+        return -2;          /* Close this terminal.  */
 #if defined (AIX) && defined (_BSD)
       /* The kernel sometimes fails to deliver SIGHUP for ptys.
          This looks incorrect, but it isn't, because _BSD causes
          O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
          and that causes a value other than 0 when there is no input.  */
       if (nread == 0)
 #if defined (AIX) && defined (_BSD)
       /* The kernel sometimes fails to deliver SIGHUP for ptys.
          This looks incorrect, but it isn't, because _BSD causes
          O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
          and that causes a value other than 0 when there is no input.  */
       if (nread == 0)
-        return -2;          /* Close this terminal. */
+        return -2;          /* Close this terminal.  */
 #endif
     }
   while (
 #endif
     }
   while (
@@ -7123,7 +7131,7 @@ tty_read_avail_input (struct terminal *terminal,
       buf.code = cbuf[i];
       /* Set the frame corresponding to the active tty.  Note that the
          value of selected_frame is not reliable here, redisplay tends
       buf.code = cbuf[i];
       /* Set the frame corresponding to the active tty.  Note that the
          value of selected_frame is not reliable here, redisplay tends
-         to temporarily change it. */
+         to temporarily change it.  */
       buf.frame_or_window = tty->top_frame;
       buf.arg = Qnil;
 
       buf.frame_or_window = tty->top_frame;
       buf.arg = Qnil;
 
@@ -7138,6 +7146,7 @@ tty_read_avail_input (struct terminal *terminal,
   return nread;
 }
 \f
   return nread;
 }
 \f
+#if defined SYNC_INPUT || defined SIGIO
 static void
 handle_async_input (void)
 {
 static void
 handle_async_input (void)
 {
@@ -7146,7 +7155,7 @@ handle_async_input (void)
   pending_signals = pending_atimers;
 #endif
 /* Tell ns_read_socket() it is being called asynchronously so it can avoid
   pending_signals = pending_atimers;
 #endif
 /* Tell ns_read_socket() it is being called asynchronously so it can avoid
-   doing anything dangerous. */
+   doing anything dangerous.  */
 #ifdef HAVE_NS
   ++handling_signal;
 #endif
 #ifdef HAVE_NS
   ++handling_signal;
 #endif
@@ -7164,7 +7173,9 @@ handle_async_input (void)
   --handling_signal;
 #endif
 }
   --handling_signal;
 #endif
 }
+#endif /* SYNC_INPUT || SIGIO */
 
 
+#ifdef SYNC_INPUT
 void
 process_pending_signals (void)
 {
 void
 process_pending_signals (void)
 {
@@ -7172,6 +7183,7 @@ process_pending_signals (void)
     handle_async_input ();
   do_pending_atimers ();
 }
     handle_async_input ();
   do_pending_atimers ();
 }
+#endif
 
 #ifdef SIGIO   /* for entire page */
 /* Note SIGIO has been undef'd if FIONREAD is missing.  */
 
 #ifdef SIGIO   /* for entire page */
 /* Note SIGIO has been undef'd if FIONREAD is missing.  */
@@ -7189,7 +7201,7 @@ input_available_signal (int signo)
 #endif
 
   if (input_available_clear_time)
 #endif
 
   if (input_available_clear_time)
-    EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
+    *input_available_clear_time = make_emacs_time (0, 0);
 
 #ifndef SYNC_INPUT
   handle_async_input ();
 
 #ifndef SYNC_INPUT
   handle_async_input ();
@@ -7204,7 +7216,7 @@ input_available_signal (int signo)
    This function exists so that the UNBLOCK_INPUT macro in
    blockinput.h can have some way to take care of input we put off
    dealing with, without assuming that every file which uses
    This function exists so that the UNBLOCK_INPUT macro in
    blockinput.h can have some way to take care of input we put off
    dealing with, without assuming that every file which uses
-   UNBLOCK_INPUT also has #included the files necessary to get SIGIO. */
+   UNBLOCK_INPUT also has #included the files necessary to get SIGIO.  */
 void
 reinvoke_input_signal (void)
 {
 void
 reinvoke_input_signal (void)
 {
@@ -7231,7 +7243,7 @@ struct user_signal_info
   struct user_signal_info *next;
 };
 
   struct user_signal_info *next;
 };
 
-/* List of user signals. */
+/* List of user signals.  */
 static struct user_signal_info *user_signals = NULL;
 
 void
 static struct user_signal_info *user_signals = NULL;
 
 void
@@ -7244,7 +7256,7 @@ add_user_signal (int sig, const char *name)
       /* Already added.  */
       return;
 
       /* Already added.  */
       return;
 
-  p = xmalloc (sizeof (struct user_signal_info));
+  p = xmalloc (sizeof *p);
   p->sig = sig;
   p->name = xstrdup (name);
   p->npending = 0;
   p->sig = sig;
   p->name = xstrdup (name);
   p->npending = 0;
@@ -7269,8 +7281,8 @@ handle_user_signal (int sig)
   for (p = user_signals; p; p = p->next)
     if (p->sig == sig)
       {
   for (p = user_signals; p; p = p->next)
     if (p->sig == sig)
       {
-        if (special_event_name &&
-            strcmp (special_event_name, p->name) == 0)
+        if (special_event_name
+           && strcmp (special_event_name, p->name) == 0)
           {
             /* Enter the debugger in many ways.  */
             debug_on_next_call = 1;
           {
             /* Enter the debugger in many ways.  */
             debug_on_next_call = 1;
@@ -7292,7 +7304,7 @@ handle_user_signal (int sig)
            /* Tell wait_reading_process_output that it needs to wake
               up and look around.  */
            if (input_available_clear_time)
            /* Tell wait_reading_process_output that it needs to wake
               up and look around.  */
            if (input_available_clear_time)
-             EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
+             *input_available_clear_time = make_emacs_time (0, 0);
          }
        break;
       }
          }
        break;
       }
@@ -7383,7 +7395,7 @@ menu_separator_name_p (const char *label)
   if (!label)
     return 0;
   else if (strlen (label) > 3
   if (!label)
     return 0;
   else if (strlen (label) > 3
-          && strncmp (label, "--", 2) == 0
+          && memcmp (label, "--", 2) == 0
           && label[2] != '-')
     {
       int i;
           && label[2] != '-')
     {
       int i;
@@ -7470,7 +7482,7 @@ menu_bar_items (Lisp_Object old)
        Lisp_Object tem;
        ptrdiff_t nminor;
        nminor = current_minor_maps (NULL, &tmaps);
        Lisp_Object tem;
        ptrdiff_t nminor;
        nminor = current_minor_maps (NULL, &tmaps);
-       maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0]));
+       maps = alloca ((nminor + 3) * sizeof *maps);
        nmaps = 0;
        if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem))
          maps[nmaps++] = tem;
        nmaps = 0;
        if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem))
          maps[nmaps++] = tem;
@@ -7503,23 +7515,23 @@ menu_bar_items (Lisp_Object old)
       int end = menu_bar_items_index;
 
       for (i = 0; i < end; i += 4)
       int end = menu_bar_items_index;
 
       for (i = 0; i < end; i += 4)
-       if (EQ (XCAR (tail), XVECTOR (menu_bar_items_vector)->contents[i]))
+       if (EQ (XCAR (tail), AREF (menu_bar_items_vector, i)))
          {
            Lisp_Object tem0, tem1, tem2, tem3;
            /* Move the item at index I to the end,
               shifting all the others forward.  */
          {
            Lisp_Object tem0, tem1, tem2, tem3;
            /* Move the item at index I to the end,
               shifting all the others forward.  */
-           tem0 = XVECTOR (menu_bar_items_vector)->contents[i + 0];
-           tem1 = XVECTOR (menu_bar_items_vector)->contents[i + 1];
-           tem2 = XVECTOR (menu_bar_items_vector)->contents[i + 2];
-           tem3 = XVECTOR (menu_bar_items_vector)->contents[i + 3];
+           tem0 = AREF (menu_bar_items_vector, i + 0);
+           tem1 = AREF (menu_bar_items_vector, i + 1);
+           tem2 = AREF (menu_bar_items_vector, i + 2);
+           tem3 = AREF (menu_bar_items_vector, i + 3);
            if (end > i + 4)
            if (end > i + 4)
-             memmove (&XVECTOR (menu_bar_items_vector)->contents[i],
-                      &XVECTOR (menu_bar_items_vector)->contents[i + 4],
+             memmove (&AREF (menu_bar_items_vector, i),
+                      &AREF (menu_bar_items_vector, i + 4),
                       (end - i - 4) * sizeof (Lisp_Object));
                       (end - i - 4) * sizeof (Lisp_Object));
-           XVECTOR (menu_bar_items_vector)->contents[end - 4] = tem0;
-           XVECTOR (menu_bar_items_vector)->contents[end - 3] = tem1;
-           XVECTOR (menu_bar_items_vector)->contents[end - 2] = tem2;
-           XVECTOR (menu_bar_items_vector)->contents[end - 1] = tem3;
+           ASET (menu_bar_items_vector, end - 4, tem0);
+           ASET (menu_bar_items_vector, end - 3, tem1);
+           ASET (menu_bar_items_vector, end - 2, tem2);
+           ASET (menu_bar_items_vector, end - 1, tem3);
            break;
          }
     }
            break;
          }
     }
@@ -7531,10 +7543,10 @@ menu_bar_items (Lisp_Object old)
       menu_bar_items_vector =
        larger_vector (menu_bar_items_vector, 4, -1);
     /* Add this item.  */
       menu_bar_items_vector =
        larger_vector (menu_bar_items_vector, 4, -1);
     /* Add this item.  */
-    XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil;
-    XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil;
-    XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil;
-    XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil;
+    ASET (menu_bar_items_vector, i, Qnil); i++;
+    ASET (menu_bar_items_vector, i, Qnil); i++;
+    ASET (menu_bar_items_vector, i, Qnil); i++;
+    ASET (menu_bar_items_vector, i, Qnil); i++;
     menu_bar_items_index = i;
   }
 
     menu_bar_items_index = i;
   }
 
@@ -7560,11 +7572,11 @@ menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dumm
         discard any previously made menu bar item.  */
 
       for (i = 0; i < menu_bar_items_index; i += 4)
         discard any previously made menu bar item.  */
 
       for (i = 0; i < menu_bar_items_index; i += 4)
-       if (EQ (key, XVECTOR (menu_bar_items_vector)->contents[i]))
+       if (EQ (key, AREF (menu_bar_items_vector, i)))
          {
            if (menu_bar_items_index > i + 4)
          {
            if (menu_bar_items_index > i + 4)
-             memmove (&XVECTOR (menu_bar_items_vector)->contents[i],
-                      &XVECTOR (menu_bar_items_vector)->contents[i + 4],
+             memmove (&AREF (menu_bar_items_vector, i),
+                      &AREF (menu_bar_items_vector, i + 4),
                       (menu_bar_items_index - i - 4) * sizeof (Lisp_Object));
            menu_bar_items_index -= 4;
          }
                       (menu_bar_items_index - i - 4) * sizeof (Lisp_Object));
            menu_bar_items_index -= 4;
          }
@@ -7588,11 +7600,11 @@ menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dumm
   if (!i)
     return;
 
   if (!i)
     return;
 
-  item = XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF];
+  item = AREF (item_properties, ITEM_PROPERTY_DEF);
 
   /* Find any existing item for this KEY.  */
   for (i = 0; i < menu_bar_items_index; i += 4)
 
   /* Find any existing item for this KEY.  */
   for (i = 0; i < menu_bar_items_index; i += 4)
-    if (EQ (key, XVECTOR (menu_bar_items_vector)->contents[i]))
+    if (EQ (key, AREF (menu_bar_items_vector, i)))
       break;
 
   /* If we did not find this KEY, add it at the end.  */
       break;
 
   /* If we did not find this KEY, add it at the end.  */
@@ -7602,22 +7614,22 @@ menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dumm
       if (i + 4 > ASIZE (menu_bar_items_vector))
        menu_bar_items_vector = larger_vector (menu_bar_items_vector, 4, -1);
       /* Add this item.  */
       if (i + 4 > ASIZE (menu_bar_items_vector))
        menu_bar_items_vector = larger_vector (menu_bar_items_vector, 4, -1);
       /* Add this item.  */
-      XVECTOR (menu_bar_items_vector)->contents[i++] = key;
-      XVECTOR (menu_bar_items_vector)->contents[i++]
-       = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];
-      XVECTOR (menu_bar_items_vector)->contents[i++] = Fcons (item, Qnil);
-      XVECTOR (menu_bar_items_vector)->contents[i++] = make_number (0);
+      ASET (menu_bar_items_vector, i, key); i++;
+      ASET (menu_bar_items_vector, i,
+           AREF (item_properties, ITEM_PROPERTY_NAME)); i++;
+      ASET (menu_bar_items_vector, i, Fcons (item, Qnil)); i++;
+      ASET (menu_bar_items_vector, i, make_number (0)); i++;
       menu_bar_items_index = i;
     }
   /* We did find an item for this KEY.  Add ITEM to its list of maps.  */
   else
     {
       Lisp_Object old;
       menu_bar_items_index = i;
     }
   /* We did find an item for this KEY.  Add ITEM to its list of maps.  */
   else
     {
       Lisp_Object old;
-      old = XVECTOR (menu_bar_items_vector)->contents[i + 2];
+      old = AREF (menu_bar_items_vector, i + 2);
       /* If the new and the old items are not both keymaps,
         the lookup will only find `item'.  */
       item = Fcons (item, KEYMAPP (item) && KEYMAPP (XCAR (old)) ? old : Qnil);
       /* If the new and the old items are not both keymaps,
         the lookup will only find `item'.  */
       item = Fcons (item, KEYMAPP (item) && KEYMAPP (XCAR (old)) ? old : Qnil);
-      XVECTOR (menu_bar_items_vector)->contents[i + 2] = item;
+      ASET (menu_bar_items_vector, i + 2, item);
     }
 }
 \f
     }
 }
 \f
@@ -7768,7 +7780,7 @@ parse_menu_item (Lisp_Object item, int inmenubar)
                {
                  tem = XCAR (item);
                  if (SYMBOLP (tem) || STRINGP (tem) || VECTORP (tem))
                {
                  tem = XCAR (item);
                  if (SYMBOLP (tem) || STRINGP (tem) || VECTORP (tem))
-                   /* Be GC protected. Set keyhint to item instead of tem. */
+                   /* Be GC protected. Set keyhint to item instead of tem.  */
                    keyhint = item;
                }
              else if (EQ (tem, QCkeys))
                    keyhint = item;
                }
              else if (EQ (tem, QCkeys))
@@ -7851,7 +7863,7 @@ parse_menu_item (Lisp_Object item, int inmenubar)
   if (inmenubar > 0)
     return 1;
 
   if (inmenubar > 0)
     return 1;
 
-  { /* This is a command.  See if there is an equivalent key binding. */
+  { /* This is a command.  See if there is an equivalent key binding.  */
     Lisp_Object keyeq = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
 
     /* The previous code preferred :key-sequence to :keys, so we
     Lisp_Object keyeq = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
 
     /* The previous code preferred :key-sequence to :keys, so we
@@ -7997,7 +8009,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems)
   if (!NILP (Voverriding_local_map_menu_flag))
     {
       /* Yes, use them (if non-nil) as well as the global map.  */
   if (!NILP (Voverriding_local_map_menu_flag))
     {
       /* Yes, use them (if non-nil) as well as the global map.  */
-      maps = (Lisp_Object *) alloca (3 * sizeof (maps[0]));
+      maps = alloca (3 * sizeof *maps);
       nmaps = 0;
       if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
        maps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
       nmaps = 0;
       if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
        maps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
@@ -8014,7 +8026,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems)
       Lisp_Object tem;
       ptrdiff_t nminor;
       nminor = current_minor_maps (NULL, &tmaps);
       Lisp_Object tem;
       ptrdiff_t nminor;
       nminor = current_minor_maps (NULL, &tmaps);
-      maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0]));
+      maps = alloca ((nminor + 3) * sizeof *maps);
       nmaps = 0;
       if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem))
        maps[nmaps++] = tem;
       nmaps = 0;
       if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem))
        maps[nmaps++] = tem;
@@ -8134,13 +8146,13 @@ static int
 parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
 {
   /* Access slot with index IDX of vector tool_bar_item_properties.  */
 parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
 {
   /* Access slot with index IDX of vector tool_bar_item_properties.  */
-#define PROP(IDX) XVECTOR (tool_bar_item_properties)->contents[IDX]
+#define PROP(IDX) AREF (tool_bar_item_properties, (IDX))
 
   Lisp_Object filter = Qnil;
   Lisp_Object caption;
   int i, have_label = 0;
 
 
   Lisp_Object filter = Qnil;
   Lisp_Object caption;
   int i, have_label = 0;
 
-  /* Defininition looks like `(menu-item CAPTION BINDING PROPS...)'.
+  /* Definition looks like `(menu-item CAPTION BINDING PROPS...)'.
      Rule out items that aren't lists, don't start with
      `menu-item' or whose rest following `tool-bar-item' is not a
      list.  */
      Rule out items that aren't lists, don't start with
      `menu-item' or whose rest following `tool-bar-item' is not a
      list.  */
@@ -8286,7 +8298,7 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
       const char *capt = STRINGP (tcapt) ? SSDATA (tcapt) : "";
       ptrdiff_t max_lbl =
        2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2));
       const char *capt = STRINGP (tcapt) ? SSDATA (tcapt) : "";
       ptrdiff_t max_lbl =
        2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2));
-      char *buf = (char *) xmalloc (max_lbl + 1);
+      char *buf = xmalloc (max_lbl + 1);
       Lisp_Object new_lbl;
       ptrdiff_t caption_len = strlen (capt);
 
       Lisp_Object new_lbl;
       ptrdiff_t caption_len = strlen (capt);
 
@@ -8317,7 +8329,7 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
       if (SCHARS (new_lbl) <= tool_bar_max_label_size)
         PROP (TOOL_BAR_ITEM_LABEL) = new_lbl;
       else
       if (SCHARS (new_lbl) <= tool_bar_max_label_size)
         PROP (TOOL_BAR_ITEM_LABEL) = new_lbl;
       else
-        PROP (TOOL_BAR_ITEM_LABEL) = make_string ("", 0);
+        PROP (TOOL_BAR_ITEM_LABEL) = empty_unibyte_string;
       xfree (buf);
     }
 
       xfree (buf);
     }
 
@@ -8408,7 +8420,7 @@ append_tool_bar_item (void)
    These are done in different ways, depending on how the input will be read.
    Menus using X are done after auto-saving in read-char, getting the input
    event from Fx_popup_menu; menus using the minibuf use read_char recursively
    These are done in different ways, depending on how the input will be read.
    Menus using X are done after auto-saving in read-char, getting the input
    event from Fx_popup_menu; menus using the minibuf use read_char recursively
-   and do auto-saving in the inner call of read_char. */
+   and do auto-saving in the inner call of read_char.  */
 
 static Lisp_Object
 read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps,
 
 static Lisp_Object
 read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps,
@@ -8439,8 +8451,7 @@ read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps,
       && !EQ (XCAR (prev_event), Qtool_bar))
     {
       /* Display the menu and get the selection.  */
       && !EQ (XCAR (prev_event), Qtool_bar))
     {
       /* Display the menu and get the selection.  */
-      Lisp_Object *realmaps
-       = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object));
+      Lisp_Object *realmaps = alloca (nmaps * sizeof *realmaps);
       Lisp_Object value;
       ptrdiff_t nmaps1 = 0;
 
       Lisp_Object value;
       ptrdiff_t nmaps1 = 0;
 
@@ -8534,7 +8545,7 @@ read_char_minibuf_menu_prompt (int commandflag,
   if (width + 4 > read_char_minibuf_menu_width)
     {
       read_char_minibuf_menu_text
   if (width + 4 > read_char_minibuf_menu_width)
     {
       read_char_minibuf_menu_text
-       = (char *) xrealloc (read_char_minibuf_menu_text, width + 4);
+       = xrealloc (read_char_minibuf_menu_text, width + 4);
       read_char_minibuf_menu_width = width + 4;
     }
   menu = read_char_minibuf_menu_text;
       read_char_minibuf_menu_width = width + 4;
     }
   menu = read_char_minibuf_menu_text;
@@ -8579,7 +8590,7 @@ read_char_minibuf_menu_prompt (int commandflag,
 
          /* Look at the next element of the map.  */
          if (idx >= 0)
 
          /* Look at the next element of the map.  */
          if (idx >= 0)
-           elt = XVECTOR (vector)->contents[idx];
+           elt = AREF (vector, idx);
          else
            elt = Fcar_safe (rest);
 
          else
            elt = Fcar_safe (rest);
 
@@ -8614,7 +8625,7 @@ read_char_minibuf_menu_prompt (int commandflag,
                  Lisp_Object upcased_event, downcased_event;
                  Lisp_Object desc = Qnil;
                  Lisp_Object s
                  Lisp_Object upcased_event, downcased_event;
                  Lisp_Object desc = Qnil;
                  Lisp_Object s
-                   = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];
+                   = AREF (item_properties, ITEM_PROPERTY_NAME);
 
                  upcased_event = Fupcase (event);
                  downcased_event = Fdowncase (event);
 
                  upcased_event = Fupcase (event);
                  downcased_event = Fdowncase (event);
@@ -8628,16 +8639,16 @@ read_char_minibuf_menu_prompt (int commandflag,
                  tem
                    = XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ];
                  if (!NILP (tem))
                  tem
                    = XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ];
                  if (!NILP (tem))
-                   /* Insert equivalent keybinding. */
+                   /* Insert equivalent keybinding.  */
                    s = concat2 (s, tem);
 #endif
                  tem
                    s = concat2 (s, tem);
 #endif
                  tem
-                   = XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE];
+                   = AREF (item_properties, ITEM_PROPERTY_TYPE);
                  if (EQ (tem, QCradio) || EQ (tem, QCtoggle))
                    {
                  if (EQ (tem, QCradio) || EQ (tem, QCtoggle))
                    {
-                     /* Insert button prefix. */
+                     /* Insert button prefix.  */
                      Lisp_Object selected
                      Lisp_Object selected
-                       = XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED];
+                       = AREF (item_properties, ITEM_PROPERTY_SELECTED);
                      if (EQ (tem, QCradio))
                        tem = build_string (NILP (selected) ? "(*) " : "( ) ");
                      else
                      if (EQ (tem, QCradio))
                        tem = build_string (NILP (selected) ? "(*) " : "( ) ");
                      else
@@ -8790,7 +8801,7 @@ typedef struct keyremap
   /* Positions [START, END) in the key sequence buffer
      are the key that we have scanned so far.
      Those events are the ones that we will replace
   /* Positions [START, END) in the key sequence buffer
      are the key that we have scanned so far.
      Those events are the ones that we will replace
-     if PAREHT maps them into a key sequence.  */
+     if PARENT maps them into a key sequence.  */
   int start, end;
 } keyremap;
 
   int start, end;
 } keyremap;
 
@@ -8809,18 +8820,12 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt,
 
   next = access_keymap (map, key, 1, 0, 1);
 
 
   next = access_keymap (map, key, 1, 0, 1);
 
-  /* Handle symbol with autoload definition.  */
-  if (SYMBOLP (next) && !NILP (Ffboundp (next))
-      && CONSP (XSYMBOL (next)->function)
-      && EQ (XCAR (XSYMBOL (next)->function), Qautoload))
-    do_autoload (XSYMBOL (next)->function, next);
-
   /* Handle a symbol whose function definition is a keymap
      or an array.  */
   if (SYMBOLP (next) && !NILP (Ffboundp (next))
       && (ARRAYP (XSYMBOL (next)->function)
          || KEYMAPP (XSYMBOL (next)->function)))
   /* Handle a symbol whose function definition is a keymap
      or an array.  */
   if (SYMBOLP (next) && !NILP (Ffboundp (next))
       && (ARRAYP (XSYMBOL (next)->function)
          || KEYMAPP (XSYMBOL (next)->function)))
-    next = XSYMBOL (next)->function;
+    next = Fautoload_do_load (XSYMBOL (next)->function, next, Qnil);
 
   /* If the keymap gives a function, not an
      array, then call the function with one arg and use
 
   /* If the keymap gives a function, not an
      array, then call the function with one arg and use
@@ -8869,7 +8874,7 @@ keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey,
 
   /* If keybuf[fkey->start..fkey->end] is bound in the
      map and we're in a position to do the key remapping, replace it with
 
   /* If keybuf[fkey->start..fkey->end] is bound in the
      map and we're in a position to do the key remapping, replace it with
-     the binding and restart with fkey->start at the end. */
+     the binding and restart with fkey->start at the end.  */
   if ((VECTORP (next) || STRINGP (next)) && doit)
     {
       int len = XFASTINT (Flength (next));
   if ((VECTORP (next) || STRINGP (next)) && doit)
     {
       int len = XFASTINT (Flength (next));
@@ -8910,6 +8915,14 @@ keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey,
   return 0;
 }
 
   return 0;
 }
 
+static int
+test_undefined (Lisp_Object binding)
+{
+  return (EQ (binding, Qundefined)
+         || (!NILP (binding) && SYMBOLP (binding)
+             && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined)));
+}
+
 /* Read a sequence of keys that ends with a non prefix character,
    storing it in KEYBUF, a buffer of size BUFSIZE.
    Prompt with PROMPT.
 /* Read a sequence of keys that ends with a non prefix character,
    storing it in KEYBUF, a buffer of size BUFSIZE.
    Prompt with PROMPT.
@@ -9025,7 +9038,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
 
   /* Non-zero if we are trying to map a key by changing an upper-case
      letter to lower case, or a shifted function key to an unshifted
 
   /* Non-zero if we are trying to map a key by changing an upper-case
      letter to lower case, or a shifted function key to an unshifted
-     one. */
+     one.  */
   int shift_translated = 0;
 
   /* If we receive a `switch-frame' or `select-window' event in the middle of
   int shift_translated = 0;
 
   /* If we receive a `switch-frame' or `select-window' event in the middle of
@@ -9033,7 +9046,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
      While we're reading, we keep the event here.  */
   Lisp_Object delayed_switch_frame;
 
      While we're reading, we keep the event here.  */
   Lisp_Object delayed_switch_frame;
 
-  /* See the comment below... */
+  /* See the comment below...  */
 #if defined (GOBBLE_FIRST_EVENT)
   Lisp_Object first_event;
 #endif
 #if defined (GOBBLE_FIRST_EVENT)
   Lisp_Object first_event;
 #endif
@@ -9053,9 +9066,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
   int junk;
 #endif
 
   int junk;
 #endif
 
-  struct gcpro outer_gcpro1;
+  struct gcpro gcpro1;
 
 
-  GCPRO1_VAR (fake_prefixed_keys, outer_gcpro);
+  GCPRO1 (fake_prefixed_keys);
   raw_keybuf_count = 0;
 
   last_nonmenu_event = Qnil;
   raw_keybuf_count = 0;
 
   last_nonmenu_event = Qnil;
@@ -9133,8 +9146,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
     {
       if (2 > nmaps_allocated)
        {
     {
       if (2 > nmaps_allocated)
        {
-         submaps = (Lisp_Object *) alloca (2 * sizeof (submaps[0]));
-         defs    = (Lisp_Object *) alloca (2 * sizeof (defs[0]));
+         submaps = alloca (2 * sizeof *submaps);
+         defs    = alloca (2 * sizeof *defs);
          nmaps_allocated = 2;
        }
       submaps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
          nmaps_allocated = 2;
        }
       submaps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
@@ -9143,8 +9156,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
     {
       if (2 > nmaps_allocated)
        {
     {
       if (2 > nmaps_allocated)
        {
-         submaps = (Lisp_Object *) alloca (2 * sizeof (submaps[0]));
-         defs    = (Lisp_Object *) alloca (2 * sizeof (defs[0]));
+         submaps = alloca (2 * sizeof *submaps);
+         defs    = alloca (2 * sizeof *defs);
          nmaps_allocated = 2;
        }
       submaps[nmaps++] = Voverriding_local_map;
          nmaps_allocated = 2;
        }
       submaps[nmaps++] = Voverriding_local_map;
@@ -9160,8 +9173,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
 
       if (total > nmaps_allocated)
        {
 
       if (total > nmaps_allocated)
        {
-         submaps = (Lisp_Object *) alloca (total * sizeof (submaps[0]));
-         defs    = (Lisp_Object *) alloca (total * sizeof (defs[0]));
+         submaps = alloca (total * sizeof *submaps);
+         defs    = alloca (total * sizeof *defs);
          nmaps_allocated = total;
        }
 
          nmaps_allocated = total;
        }
 
@@ -9308,7 +9321,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
                if (!found)
                  {
                    /* Don't touch interrupted_kboard when it's been
                if (!found)
                  {
                    /* Don't touch interrupted_kboard when it's been
-                      deleted. */
+                      deleted.  */
                    delayed_switch_frame = Qnil;
                    goto replay_entire_sequence;
                  }
                    delayed_switch_frame = Qnil;
                    goto replay_entire_sequence;
                  }
@@ -9351,7 +9364,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
          if (EQ (key, Qt))
            {
              unbind_to (count, Qnil);
          if (EQ (key, Qt))
            {
              unbind_to (count, Qnil);
-             UNGCPRO_VAR (outer_gcpro);
+             UNGCPRO;
              return -1;
            }
 
              return -1;
            }
 
@@ -9399,7 +9412,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
              && current_buffer != starting_buffer)
            {
              GROW_RAW_KEYBUF;
              && current_buffer != starting_buffer)
            {
              GROW_RAW_KEYBUF;
-             XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = key;
+             ASET (raw_keybuf, raw_keybuf_count, key);
+             raw_keybuf_count++;
              keybuf[t++] = key;
              mock_input = t;
              Vquit_flag = Qnil;
              keybuf[t++] = key;
              mock_input = t;
              Vquit_flag = Qnil;
@@ -9416,7 +9430,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
            {
              /* If we're at the beginning of a key sequence, and the caller
                 says it's okay, go ahead and return this event.  If we're
            {
              /* If we're at the beginning of a key sequence, and the caller
                 says it's okay, go ahead and return this event.  If we're
-                in the midst of a key sequence, delay it until the end. */
+                in the midst of a key sequence, delay it until the end.  */
              if (t > 0 || !can_return_switch_frame)
                {
                  delayed_switch_frame = key;
              if (t > 0 || !can_return_switch_frame)
                {
                  delayed_switch_frame = key;
@@ -9477,7 +9491,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
                      && BUFFERP (XWINDOW (window)->buffer)
                      && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
                    {
                      && BUFFERP (XWINDOW (window)->buffer)
                      && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
                    {
-                     XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = key;
+                     ASET (raw_keybuf, raw_keybuf_count, key);
+                     raw_keybuf_count++;
                      keybuf[t] = key;
                      mock_input = t + 1;
 
                      keybuf[t] = key;
                      mock_input = t + 1;
 
@@ -9713,7 +9728,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
                   Down-clicks are eliminated.
                   Double-downs reduce to downs, then are eliminated.
                   Triple-downs reduce to double-downs, then to downs,
                   Down-clicks are eliminated.
                   Double-downs reduce to downs, then are eliminated.
                   Triple-downs reduce to double-downs, then to downs,
-                    then are eliminated. */
+                    then are eliminated.  */
              if (modifiers & (down_modifier | drag_modifier
                               | double_modifier | triple_modifier))
                {
              if (modifiers & (down_modifier | drag_modifier
                               | double_modifier | triple_modifier))
                {
@@ -9860,7 +9875,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
            }
        }
 
            }
        }
 
-      if (first_binding < nmaps && NILP (submaps[first_binding])
+      if (first_binding < nmaps
+         && NILP (submaps[first_binding])
+         && !test_undefined (defs[first_binding])
          && indec.start >= t)
        /* There is a binding and it's not a prefix.
           (and it doesn't have any input-decode-map translation pending).
          && indec.start >= t)
        /* There is a binding and it's not a prefix.
           (and it doesn't have any input-decode-map translation pending).
@@ -9887,7 +9904,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
                                  /* If there's a binding (i.e.
                                     first_binding >= nmaps) we don't want
                                     to apply this function-key-mapping.  */
                                  /* If there's a binding (i.e.
                                     first_binding >= nmaps) we don't want
                                     to apply this function-key-mapping.  */
-                                 fkey.end + 1 == t && first_binding >= nmaps,
+                                 fkey.end + 1 == t
+                                 && (first_binding >= nmaps
+                                     || test_undefined (defs[first_binding])),
                                  &diff, prompt);
            UNGCPRO;
            if (done)
                                  &diff, prompt);
            UNGCPRO;
            if (done)
@@ -10004,6 +10023,13 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
     read_key_sequence_cmd = (first_binding < nmaps
                             ? defs[first_binding]
                             : Qnil);
     read_key_sequence_cmd = (first_binding < nmaps
                             ? defs[first_binding]
                             : Qnil);
+  read_key_sequence_remapped
+    /* Remap command through active keymaps.
+       Do the remapping here, before the unbind_to so it uses the keymaps
+       of the appropriate buffer.  */
+    = SYMBOLP (read_key_sequence_cmd)
+    ? Fcommand_remapping (read_key_sequence_cmd, Qnil, Qnil)
+    : Qnil;
 
   unread_switch_frame = delayed_switch_frame;
   unbind_to (count, Qnil);
 
   unread_switch_frame = delayed_switch_frame;
   unbind_to (count, Qnil);
@@ -10038,7 +10064,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
       add_command_key (keybuf[t]);
     }
 
       add_command_key (keybuf[t]);
     }
 
-  UNGCPRO_VAR (outer_gcpro);
+  UNGCPRO;
   return t;
 }
 
   return t;
 }
 
@@ -10126,7 +10152,7 @@ will read just one key sequence.  */)
                         ! NILP (can_return_switch_frame), 0);
 
 #if 0  /* The following is fine for code reading a key sequence and
                         ! NILP (can_return_switch_frame), 0);
 
 #if 0  /* The following is fine for code reading a key sequence and
-         then proceeding with a lenghty computation, but it's not good
+         then proceeding with a lengthy computation, but it's not good
          for code reading keys in a loop, like an input method.  */
 #ifdef HAVE_WINDOW_SYSTEM
   if (display_hourglass_p)
          for code reading keys in a loop, like an input method.  */
 #ifdef HAVE_WINDOW_SYSTEM
   if (display_hourglass_p)
@@ -10164,7 +10190,7 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector,
 
   memset (keybuf, 0, sizeof keybuf);
   GCPRO1 (keybuf[0]);
 
   memset (keybuf, 0, sizeof keybuf);
   GCPRO1 (keybuf[0]);
-  gcpro1.nvars = (sizeof keybuf/sizeof (keybuf[0]));
+  gcpro1.nvars = (sizeof keybuf / sizeof (keybuf[0]));
 
   if (NILP (continue_echo))
     {
 
   if (NILP (continue_echo))
     {
@@ -10178,7 +10204,7 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector,
     cancel_hourglass ();
 #endif
 
     cancel_hourglass ();
 #endif
 
-  i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])),
+  i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])),
                         prompt, ! NILP (dont_downcase_last),
                         ! NILP (can_return_switch_frame), 0);
 
                         prompt, ! NILP (dont_downcase_last),
                         ! NILP (can_return_switch_frame), 0);
 
@@ -10243,7 +10269,7 @@ a special event, so ignore the prefix argument and don't clear it.  */)
          struct gcpro gcpro1, gcpro2;
 
          GCPRO2 (cmd, prefixarg);
          struct gcpro gcpro1, gcpro2;
 
          GCPRO2 (cmd, prefixarg);
-         do_autoload (final, cmd);
+         Fautoload_do_load (final, cmd, Qnil);
          UNGCPRO;
        }
       else
          UNGCPRO;
        }
       else
@@ -10285,146 +10311,6 @@ a special event, so ignore the prefix argument and don't clear it.  */)
 
 
 \f
 
 
 \f
-DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_command,
-       1, 1, "P",
-       doc: /* Read function name, then read its arguments and call it.
-
-To pass a numeric argument to the command you are invoking with, specify
-the numeric argument to this command.
-
-Noninteractively, the argument PREFIXARG is the prefix argument to
-give to the command you invoke, if it asks for an argument.  */)
-  (Lisp_Object prefixarg)
-{
-  Lisp_Object function;
-  ptrdiff_t saved_last_point_position;
-  Lisp_Object saved_keys, saved_last_point_position_buffer;
-  Lisp_Object bindings, value;
-  struct gcpro gcpro1, gcpro2, gcpro3;
-#ifdef HAVE_WINDOW_SYSTEM
-  /* The call to Fcompleting_read will start and cancel the hourglass,
-     but if the hourglass was already scheduled, this means that no
-     hourglass will be shown for the actual M-x command itself.
-     So we restart it if it is already scheduled.  Note that checking
-     hourglass_shown_p is not enough,  normally the hourglass is not shown,
-     just scheduled to be shown.  */
-  int hstarted = hourglass_started ();
-#endif
-
-  saved_keys = Fvector (this_command_key_count,
-                       XVECTOR (this_command_keys)->contents);
-  saved_last_point_position_buffer = last_point_position_buffer;
-  saved_last_point_position = last_point_position;
-  GCPRO3 (saved_keys, prefixarg, saved_last_point_position_buffer);
-
-  function = call0 (intern ("read-extended-command"));
-
-#ifdef HAVE_WINDOW_SYSTEM
-  if (hstarted) start_hourglass ();
-#endif
-
-  if (STRINGP (function) && SCHARS (function) == 0)
-    error ("No command name given");
-
-  /* Set this_command_keys to the concatenation of saved_keys and
-     function, followed by a RET.  */
-  {
-    Lisp_Object *keys;
-    int i;
-
-    this_command_key_count = 0;
-    this_command_key_count_reset = 0;
-    this_single_command_key_start = 0;
-
-    keys = XVECTOR (saved_keys)->contents;
-    for (i = 0; i < ASIZE (saved_keys); i++)
-      add_command_key (keys[i]);
-
-    for (i = 0; i < SCHARS (function); i++)
-      add_command_key (Faref (function, make_number (i)));
-
-    add_command_key (make_number ('\015'));
-  }
-
-  last_point_position = saved_last_point_position;
-  last_point_position_buffer = saved_last_point_position_buffer;
-
-  UNGCPRO;
-
-  function = Fintern (function, Qnil);
-  KVAR (current_kboard, Vprefix_arg) = prefixarg;
-  Vthis_command = function;
-  real_this_command = function;
-
-  /* If enabled, show which key runs this command.  */
-  if (!NILP (Vsuggest_key_bindings)
-      && NILP (Vexecuting_kbd_macro)
-      && SYMBOLP (function))
-    bindings = Fwhere_is_internal (function, Voverriding_local_map,
-                                  Qt, Qnil, Qnil);
-  else
-    bindings = Qnil;
-
-  value = Qnil;
-  GCPRO3 (bindings, value, function);
-  value = Fcommand_execute (function, Qt, Qnil, Qnil);
-
-  /* If the command has a key binding, print it now.  */
-  if (!NILP (bindings)
-      && ! (VECTORP (bindings) && EQ (Faref (bindings, make_number (0)),
-                                     Qmouse_movement)))
-    {
-      /* But first wait, and skip the message if there is input.  */
-      Lisp_Object waited;
-
-      /* If this command displayed something in the echo area;
-        wait a few seconds, then display our suggestion message.  */
-      if (NILP (echo_area_buffer[0]))
-       waited = sit_for (make_number (0), 0, 2);
-      else if (NUMBERP (Vsuggest_key_bindings))
-       waited = sit_for (Vsuggest_key_bindings, 0, 2);
-      else
-       waited = sit_for (make_number (2), 0, 2);
-
-      if (!NILP (waited) && ! CONSP (Vunread_command_events))
-       {
-         Lisp_Object binding;
-         char *newmessage;
-         int message_p = push_message ();
-         ptrdiff_t count = SPECPDL_INDEX ();
-         ptrdiff_t newmessage_len, newmessage_alloc;
-         USE_SAFE_ALLOCA;
-
-         record_unwind_protect (pop_message_unwind, Qnil);
-         binding = Fkey_description (bindings, Qnil);
-         newmessage_alloc =
-           (sizeof "You can run the command `' with "
-            + SBYTES (SYMBOL_NAME (function)) + SBYTES (binding));
-         SAFE_ALLOCA (newmessage, char *, newmessage_alloc);
-         newmessage_len =
-           esprintf (newmessage, "You can run the command `%s' with %s",
-                     SDATA (SYMBOL_NAME (function)),
-                     SDATA (binding));
-         message2 (newmessage,
-                   newmessage_len,
-                   STRING_MULTIBYTE (binding));
-         if (NUMBERP (Vsuggest_key_bindings))
-           waited = sit_for (Vsuggest_key_bindings, 0, 2);
-         else
-           waited = sit_for (make_number (2), 0, 2);
-
-         if (!NILP (waited) && message_p)
-           restore_message ();
-
-         SAFE_FREE ();
-         unbind_to (count, Qnil);
-       }
-    }
-
-  RETURN_UNGCPRO (value);
-}
-
-\f
 /* Return nonzero if input events are pending.  */
 
 int
 /* Return nonzero if input events are pending.  */
 
 int
@@ -10511,6 +10397,9 @@ if there is a doubt, the value is t.  */)
       || !NILP (Vunread_input_method_events))
     return (Qt);
 
       || !NILP (Vunread_input_method_events))
     return (Qt);
 
+  /* Process non-user-visible events (Bug#10195).  */
+  process_special_events ();
+
   get_input_pending (&input_pending,
                     READABLE_EVENTS_DO_TIMERS_NOW
                     | READABLE_EVENTS_FILTER_EVENTS);
   get_input_pending (&input_pending,
                     READABLE_EVENTS_DO_TIMERS_NOW
                     | READABLE_EVENTS_FILTER_EVENTS);
@@ -10634,7 +10523,7 @@ KEEP-RECORD is non-nil.  */)
   if (NILP (keep_record))
     {
       for (i = 0; i < ASIZE (recent_keys); ++i)
   if (NILP (keep_record))
     {
       for (i = 0; i < ASIZE (recent_keys); ++i)
-       XVECTOR (recent_keys)->contents[i] = Qnil;
+       ASET (recent_keys, i, Qnil);
       total_keys = 0;
       recent_keys_index = 0;
     }
       total_keys = 0;
       recent_keys_index = 0;
     }
@@ -10803,7 +10692,7 @@ stuff_buffered_input (Lisp_Object stuffstring)
 }
 \f
 void
 }
 \f
 void
-set_waiting_for_input (struct timeval *time_to_clear)
+set_waiting_for_input (EMACS_TIME *time_to_clear)
 {
   input_available_clear_time = time_to_clear;
 
 {
   input_available_clear_time = time_to_clear;
 
@@ -10811,9 +10700,9 @@ set_waiting_for_input (struct timeval *time_to_clear)
   waiting_for_input = 1;
 
   /* If handle_interrupt was called before and buffered a C-g,
   waiting_for_input = 1;
 
   /* If handle_interrupt was called before and buffered a C-g,
-     make it run again now, to avoid timing error. */
+     make it run again now, to avoid timing error.  */
   if (!NILP (Vquit_flag))
   if (!NILP (Vquit_flag))
-    quit_throw_to_read_char ();
+    quit_throw_to_read_char (0);
 }
 
 void
 }
 
 void
@@ -10828,11 +10717,11 @@ clear_waiting_for_input (void)
 
    If we have a frame on the controlling tty, we assume that the
    SIGINT was generated by C-g, so we call handle_interrupt.
 
    If we have a frame on the controlling tty, we assume that the
    SIGINT was generated by C-g, so we call handle_interrupt.
-   Otherwise, the handler kills Emacs.  */
+   Otherwise, tell QUIT to kill Emacs.  */
 
 static void
 interrupt_signal (int signalnum)       /* If we don't have an argument, some */
 
 static void
 interrupt_signal (int signalnum)       /* If we don't have an argument, some */
-                                       /* compilers complain in signal calls. */
+                                       /* compilers complain in signal calls.  */
 {
   /* Must preserve main program's value of errno.  */
   int old_errno = errno;
 {
   /* Must preserve main program's value of errno.  */
   int old_errno = errno;
@@ -10840,13 +10729,15 @@ interrupt_signal (int signalnum)      /* If we don't have an argument, some */
 
   SIGNAL_THREAD_CHECK (signalnum);
 
 
   SIGNAL_THREAD_CHECK (signalnum);
 
-  /* See if we have an active terminal on our controlling tty. */
+  /* See if we have an active terminal on our controlling tty.  */
   terminal = get_named_tty ("/dev/tty");
   if (!terminal)
     {
       /* If there are no frames there, let's pretend that we are a
   terminal = get_named_tty ("/dev/tty");
   if (!terminal)
     {
       /* If there are no frames there, let's pretend that we are a
-         well-behaving UN*X program and quit. */
-      Fkill_emacs (Qnil);
+         well-behaving UN*X program and quit.  We must not call Lisp
+         in a signal handler, so tell QUIT to exit when it is
+         safe.  */
+      Vquit_flag = Qkill_emacs;
     }
   else
     {
     }
   else
     {
@@ -10864,6 +10755,11 @@ interrupt_signal (int signalnum)       /* If we don't have an argument, some */
   errno = old_errno;
 }
 
   errno = old_errno;
 }
 
+/* If Emacs is stuck because `inhibit-quit' is true, then keep track
+   of the number of times C-g has been requested.  If C-g is pressed
+   enough times, then quit anyway.  See bug#6585.  */
+static int force_quit_count;
+
 /* This routine is called at interrupt level in response to C-g.
 
    It is called from the SIGINT handler or kbd_buffer_store_event.
 /* This routine is called at interrupt level in response to C-g.
 
    It is called from the SIGINT handler or kbd_buffer_store_event.
@@ -10873,7 +10769,7 @@ interrupt_signal (int signalnum)        /* If we don't have an argument, some */
 
    Otherwise it sets the Lisp variable quit-flag not-nil.  This causes
    eval to throw, when it gets a chance.  If quit-flag is already
 
    Otherwise it sets the Lisp variable quit-flag not-nil.  This causes
    eval to throw, when it gets a chance.  If quit-flag is already
-   non-nil, it stops the job right away. */
+   non-nil, it stops the job right away.  */
 
 static void
 handle_interrupt (void)
 
 static void
 handle_interrupt (void)
@@ -10882,7 +10778,7 @@ handle_interrupt (void)
 
   cancel_echoing ();
 
 
   cancel_echoing ();
 
-  /* XXX This code needs to be revised for multi-tty support. */
+  /* XXX This code needs to be revised for multi-tty support.  */
   if (!NILP (Vquit_flag) && get_named_tty ("/dev/tty"))
     {
       /* If SIGINT isn't blocked, don't let us be interrupted by
   if (!NILP (Vquit_flag) && get_named_tty ("/dev/tty"))
     {
       /* If SIGINT isn't blocked, don't let us be interrupted by
@@ -10982,8 +10878,16 @@ handle_interrupt (void)
          UNGCPRO;
        }
       else
          UNGCPRO;
        }
       else
-       /* Else request quit when it's safe */
-       Vquit_flag = Qt;
+        { /* Else request quit when it's safe.  */
+          if (NILP (Vquit_flag))
+           force_quit_count = 0;
+         if (++force_quit_count == 3)
+            {
+              immediate_quit = 1;
+              Vinhibit_quit = Qnil;
+            }
+          Vquit_flag = Qt;
+        }
     }
 
 /* TODO: The longjmp in this call throws the NS event loop integration off,
     }
 
 /* TODO: The longjmp in this call throws the NS event loop integration off,
@@ -10992,18 +10896,23 @@ handle_interrupt (void)
          wait_reading_process_output() under HAVE_NS because of the call
          to ns_select there (needed because otherwise events aren't picked up
          outside of polling since we don't get SIGIO like X and we don't have a
          wait_reading_process_output() under HAVE_NS because of the call
          to ns_select there (needed because otherwise events aren't picked up
          outside of polling since we don't get SIGIO like X and we don't have a
-         separate event loop thread like W32. */
+         separate event loop thread like W32.  */
 #ifndef HAVE_NS
   if (waiting_for_input && !echoing)
 #ifndef HAVE_NS
   if (waiting_for_input && !echoing)
-      quit_throw_to_read_char ();
+      quit_throw_to_read_char (1);
 #endif
 }
 
 /* Handle a C-g by making read_char return C-g.  */
 
 static void
 #endif
 }
 
 /* Handle a C-g by making read_char return C-g.  */
 
 static void
-quit_throw_to_read_char (void)
+quit_throw_to_read_char (int from_signal)
 {
 {
+  /* When not called from a signal handler it is safe to call
+     Lisp.  */
+  if (!from_signal && EQ (Vquit_flag, Qkill_emacs))
+    Fkill_emacs (Qnil);
+
   sigfree ();
   /* Prevent another signal from doing this before we finish.  */
   clear_waiting_for_input ();
   sigfree ();
   /* Prevent another signal from doing this before we finish.  */
   clear_waiting_for_input ();
@@ -11406,7 +11315,7 @@ init_keyboard (void)
   quit_char = Ctl ('g');
   Vunread_command_events = Qnil;
   unread_command_char = -1;
   quit_char = Ctl ('g');
   Vunread_command_events = Qnil;
   unread_command_char = -1;
-  EMACS_SET_SECS_USECS (timer_idleness_start_time, -1, -1);
+  timer_idleness_start_time = invalid_emacs_time ();
   total_keys = 0;
   recent_keys_index = 0;
   kbd_fetch_ptr = kbd_buffer;
   total_keys = 0;
   recent_keys_index = 0;
   kbd_fetch_ptr = kbd_buffer;
@@ -11441,7 +11350,7 @@ init_keyboard (void)
          session may have multiple display types, so we always handle
          SIGINT.  There is special code in interrupt_signal to exit
          Emacs on SIGINT when there are no termcap frames on the
          session may have multiple display types, so we always handle
          SIGINT.  There is special code in interrupt_signal to exit
          Emacs on SIGINT when there are no termcap frames on the
-         controlling terminal. */
+         controlling terminal.  */
       signal (SIGINT, interrupt_signal);
 #ifndef DOS_NT
       /* For systems with SysV TERMIO, C-g is set up for both SIGINT and
       signal (SIGINT, interrupt_signal);
 #ifndef DOS_NT
       /* For systems with SysV TERMIO, C-g is set up for both SIGINT and
@@ -11503,7 +11412,7 @@ syms_of_keyboard (void)
   pending_funcalls = Qnil;
   staticpro (&pending_funcalls);
 
   pending_funcalls = Qnil;
   staticpro (&pending_funcalls);
 
-  Vlispy_mouse_stem = make_pure_c_string ("mouse");
+  Vlispy_mouse_stem = build_pure_c_string ("mouse");
   staticpro (&Vlispy_mouse_stem);
 
   /* Tool-bars.  */
   staticpro (&Vlispy_mouse_stem);
 
   /* Tool-bars.  */
@@ -11519,9 +11428,6 @@ syms_of_keyboard (void)
   staticpro (&tool_bar_items_vector);
   tool_bar_items_vector = Qnil;
 
   staticpro (&tool_bar_items_vector);
   tool_bar_items_vector = Qnil;
 
-  staticpro (&real_this_command);
-  real_this_command = Qnil;
-
   DEFSYM (Qtimer_event_handler, "timer-event-handler");
   DEFSYM (Qdisabled_command_function, "disabled-command-function");
   DEFSYM (Qself_insert_command, "self-insert-command");
   DEFSYM (Qtimer_event_handler, "timer-event-handler");
   DEFSYM (Qdisabled_command_function, "disabled-command-function");
   DEFSYM (Qself_insert_command, "self-insert-command");
@@ -11592,6 +11498,7 @@ syms_of_keyboard (void)
   DEFSYM (Qx_set_selection, "x-set-selection");
   DEFSYM (QPRIMARY, "PRIMARY");
   DEFSYM (Qhandle_switch_frame, "handle-switch-frame");
   DEFSYM (Qx_set_selection, "x-set-selection");
   DEFSYM (QPRIMARY, "PRIMARY");
   DEFSYM (Qhandle_switch_frame, "handle-switch-frame");
+  DEFSYM (Qhandle_select_window, "handle-select-window");
 
   DEFSYM (Qinput_method_function, "input-method-function");
   DEFSYM (Qinput_method_exit_on_first_char, "input-method-exit-on-first-char");
 
   DEFSYM (Qinput_method_function, "input-method-function");
   DEFSYM (Qinput_method_exit_on_first_char, "input-method-exit-on-first-char");
@@ -11635,7 +11542,7 @@ syms_of_keyboard (void)
     modifier_symbols = Fmake_vector (make_number (len), Qnil);
     for (i = 0; i < len; i++)
       if (modifier_names[i])
     modifier_symbols = Fmake_vector (make_number (len), Qnil);
     for (i = 0; i < len; i++)
       if (modifier_names[i])
-       XVECTOR (modifier_symbols)->contents[i] = intern_c_string (modifier_names[i]);
+       ASET (modifier_symbols, i, intern_c_string (modifier_names[i]));
     staticpro (&modifier_symbols);
   }
 
     staticpro (&modifier_symbols);
   }
 
@@ -11668,6 +11575,8 @@ syms_of_keyboard (void)
 
   read_key_sequence_cmd = Qnil;
   staticpro (&read_key_sequence_cmd);
 
   read_key_sequence_cmd = Qnil;
   staticpro (&read_key_sequence_cmd);
+  read_key_sequence_remapped = Qnil;
+  staticpro (&read_key_sequence_remapped);
 
   menu_bar_one_keymap_changed_items = Qnil;
   staticpro (&menu_bar_one_keymap_changed_items);
 
   menu_bar_one_keymap_changed_items = Qnil;
   staticpro (&menu_bar_one_keymap_changed_items);
@@ -11709,7 +11618,6 @@ syms_of_keyboard (void)
   defsubr (&Sset_quit_char);
   defsubr (&Sset_input_mode);
   defsubr (&Scurrent_input_mode);
   defsubr (&Sset_quit_char);
   defsubr (&Sset_input_mode);
   defsubr (&Scurrent_input_mode);
-  defsubr (&Sexecute_extended_command);
   defsubr (&Sposn_at_point);
   defsubr (&Sposn_at_x_y);
 
   defsubr (&Sposn_at_point);
   defsubr (&Sposn_at_x_y);
 
@@ -11773,12 +11681,14 @@ was a kill command.
 See Info node `(elisp)Multiple Terminals'.  */);
 
   DEFVAR_KBOARD ("real-last-command", Vreal_last_command,
 See Info node `(elisp)Multiple Terminals'.  */);
 
   DEFVAR_KBOARD ("real-last-command", Vreal_last_command,
-                doc: /* Same as `last-command', but never altered by Lisp code.  */);
+                doc: /* Same as `last-command', but never altered by Lisp code.
+Taken from the previous value of `real-this-command'.  */);
 
   DEFVAR_KBOARD ("last-repeatable-command", Vlast_repeatable_command,
                 doc: /* Last command that may be repeated.
 The last command executed that was not bound to an input event.
 
   DEFVAR_KBOARD ("last-repeatable-command", Vlast_repeatable_command,
                 doc: /* Last command that may be repeated.
 The last command executed that was not bound to an input event.
-This is the command `repeat' will try to repeat.  */);
+This is the command `repeat' will try to repeat.
+Taken from a previous value of `real-this-command'.  */);
 
   DEFVAR_LISP ("this-command", Vthis_command,
               doc: /* The command now being executed.
 
   DEFVAR_LISP ("this-command", Vthis_command,
               doc: /* The command now being executed.
@@ -11786,6 +11696,10 @@ The command can set this variable; whatever is put here
 will be in `last-command' during the following command.  */);
   Vthis_command = Qnil;
 
 will be in `last-command' during the following command.  */);
   Vthis_command = Qnil;
 
+  DEFVAR_LISP ("real-this-command", Vreal_this_command,
+              doc: /* This is like `this-command', except that commands should never modify it.  */);
+  Vreal_this_command = Qnil;
+
   DEFVAR_LISP ("this-command-keys-shift-translated",
               Vthis_command_keys_shift_translated,
               doc: /* Non-nil if the key sequence activating this command was shift-translated.
   DEFVAR_LISP ("this-command-keys-shift-translated",
               Vthis_command_keys_shift_translated,
               doc: /* Non-nil if the key sequence activating this command was shift-translated.
@@ -11802,38 +11716,39 @@ result of looking up the original command in the active keymaps.  */);
   Vthis_original_command = Qnil;
 
   DEFVAR_INT ("auto-save-interval", auto_save_interval,
   Vthis_original_command = Qnil;
 
   DEFVAR_INT ("auto-save-interval", auto_save_interval,
-             doc: /* *Number of input events between auto-saves.
+             doc: /* Number of input events between auto-saves.
 Zero means disable autosaving due to number of characters typed.  */);
   auto_save_interval = 300;
 
   DEFVAR_LISP ("auto-save-timeout", Vauto_save_timeout,
 Zero means disable autosaving due to number of characters typed.  */);
   auto_save_interval = 300;
 
   DEFVAR_LISP ("auto-save-timeout", Vauto_save_timeout,
-              doc: /* *Number of seconds idle time before auto-save.
+              doc: /* Number of seconds idle time before auto-save.
 Zero or nil means disable auto-saving due to idleness.
 After auto-saving due to this many seconds of idle time,
 Emacs also does a garbage collection if that seems to be warranted.  */);
   XSETFASTINT (Vauto_save_timeout, 30);
 
   DEFVAR_LISP ("echo-keystrokes", Vecho_keystrokes,
 Zero or nil means disable auto-saving due to idleness.
 After auto-saving due to this many seconds of idle time,
 Emacs also does a garbage collection if that seems to be warranted.  */);
   XSETFASTINT (Vauto_save_timeout, 30);
 
   DEFVAR_LISP ("echo-keystrokes", Vecho_keystrokes,
-              doc: /* *Nonzero means echo unfinished commands after this many seconds of pause.
-The value may be integer or floating point.  */);
+              doc: /* Nonzero means echo unfinished commands after this many seconds of pause.
+The value may be integer or floating point.
+If the value is zero, don't echo at all.  */);
   Vecho_keystrokes = make_number (1);
 
   DEFVAR_INT ("polling-period", polling_period,
   Vecho_keystrokes = make_number (1);
 
   DEFVAR_INT ("polling-period", polling_period,
-             doc: /* *Interval between polling for input during Lisp execution.
+             doc: /* Interval between polling for input during Lisp execution.
 The reason for polling is to make C-g work to stop a running program.
 Polling is needed only when using X windows and SIGIO does not work.
 Polling is automatically disabled in all other cases.  */);
   polling_period = 2;
 
   DEFVAR_LISP ("double-click-time", Vdouble_click_time,
 The reason for polling is to make C-g work to stop a running program.
 Polling is needed only when using X windows and SIGIO does not work.
 Polling is automatically disabled in all other cases.  */);
   polling_period = 2;
 
   DEFVAR_LISP ("double-click-time", Vdouble_click_time,
-              doc: /* *Maximum time between mouse clicks to make a double-click.
+              doc: /* Maximum time between mouse clicks to make a double-click.
 Measured in milliseconds.  The value nil means disable double-click
 recognition; t means double-clicks have no time limit and are detected
 by position only.  */);
   Vdouble_click_time = make_number (500);
 
   DEFVAR_INT ("double-click-fuzz", double_click_fuzz,
 Measured in milliseconds.  The value nil means disable double-click
 recognition; t means double-clicks have no time limit and are detected
 by position only.  */);
   Vdouble_click_time = make_number (500);
 
   DEFVAR_INT ("double-click-fuzz", double_click_fuzz,
-             doc: /* *Maximum mouse movement between clicks to make a double-click.
+             doc: /* Maximum mouse movement between clicks to make a double-click.
 On window-system frames, value is the number of pixels the mouse may have
 moved horizontally or vertically between two clicks to make a double-click.
 On non window-system frames, value is interpreted in units of 1/8 characters
 On window-system frames, value is the number of pixels the mouse may have
 moved horizontally or vertically between two clicks to make a double-click.
 On non window-system frames, value is interpreted in units of 1/8 characters
@@ -11844,7 +11759,7 @@ to count as a drag.  */);
   double_click_fuzz = 3;
 
   DEFVAR_BOOL ("inhibit-local-menu-bar-menus", inhibit_local_menu_bar_menus,
   double_click_fuzz = 3;
 
   DEFVAR_BOOL ("inhibit-local-menu-bar-menus", inhibit_local_menu_bar_menus,
-              doc: /* *Non-nil means inhibit local map menu bar menus.  */);
+              doc: /* Non-nil means inhibit local map menu bar menus.  */);
   inhibit_local_menu_bar_menus = 0;
 
   DEFVAR_INT ("num-input-keys", num_input_keys,
   inhibit_local_menu_bar_menus = 0;
 
   DEFVAR_INT ("num-input-keys", num_input_keys,
@@ -12019,7 +11934,7 @@ and the minor mode maps regardless of `overriding-local-map'.  */);
   Vspecial_event_map = Fcons (intern_c_string ("keymap"), Qnil);
 
   DEFVAR_LISP ("track-mouse", do_mouse_tracking,
   Vspecial_event_map = Fcons (intern_c_string ("keymap"), Qnil);
 
   DEFVAR_LISP ("track-mouse", do_mouse_tracking,
-              doc: /* *Non-nil means generate motion events for mouse motion.  */);
+              doc: /* Non-nil means generate motion events for mouse motion.  */);
 
   DEFVAR_KBOARD ("system-key-alist", Vsystem_key_alist,
                 doc: /* Alist of system-specific X windows key symbols.
 
   DEFVAR_KBOARD ("system-key-alist", Vsystem_key_alist,
                 doc: /* Alist of system-specific X windows key symbols.
@@ -12083,7 +11998,7 @@ This variable is keyboard-local.  */);
 Function key definitions that apply to all terminal devices should go
 here.  If a mapping is defined in both the current
 `local-function-key-map' binding and this variable, then the local
 Function key definitions that apply to all terminal devices should go
 here.  If a mapping is defined in both the current
 `local-function-key-map' binding and this variable, then the local
-definition will take precendence.  */);
+definition will take precedence.  */);
   Vfunction_key_map = Fmake_sparse_keymap (Qnil);
 
   DEFVAR_LISP ("key-translation-map", Vkey_translation_map,
   Vfunction_key_map = Fmake_sparse_keymap (Qnil);
 
   DEFVAR_LISP ("key-translation-map", Vkey_translation_map,
@@ -12105,19 +12020,13 @@ whenever `deferred-action-list' is non-nil.  */);
   Vdeferred_action_function = Qnil;
 
   DEFVAR_LISP ("delayed-warnings-list", Vdelayed_warnings_list,
   Vdeferred_action_function = Qnil;
 
   DEFVAR_LISP ("delayed-warnings-list", Vdelayed_warnings_list,
-               doc: /* List of warnings to be displayed as soon as possible.
+               doc: /* List of warnings to be displayed after this command.
 Each element must be a list (TYPE MESSAGE [LEVEL [BUFFER-NAME]]),
 as per the args of `display-warning' (which see).
 If this variable is non-nil, `delayed-warnings-hook' will be run
 immediately after running `post-command-hook'.  */);
   Vdelayed_warnings_list = Qnil;
 
 Each element must be a list (TYPE MESSAGE [LEVEL [BUFFER-NAME]]),
 as per the args of `display-warning' (which see).
 If this variable is non-nil, `delayed-warnings-hook' will be run
 immediately after running `post-command-hook'.  */);
   Vdelayed_warnings_list = Qnil;
 
-  DEFVAR_LISP ("suggest-key-bindings", Vsuggest_key_bindings,
-              doc: /* *Non-nil means show the equivalent key-binding when M-x command has one.
-The value can be a length of time to show the message for.
-If the value is non-nil and not a number, we wait 2 seconds.  */);
-  Vsuggest_key_bindings = Qt;
-
   DEFVAR_LISP ("timer-list", Vtimer_list,
               doc: /* List of active absolute time timers in order of increasing time.  */);
   Vtimer_list = Qnil;
   DEFVAR_LISP ("timer-list", Vtimer_list,
               doc: /* List of active absolute time timers in order of increasing time.  */);
   Vtimer_list = Qnil;
@@ -12173,7 +12082,7 @@ just after executing the command.  */);
 
   DEFVAR_LISP ("global-disable-point-adjustment",
               Vglobal_disable_point_adjustment,
 
   DEFVAR_LISP ("global-disable-point-adjustment",
               Vglobal_disable_point_adjustment,
-              doc: /* *If non-nil, always suppress point adjustment.
+              doc: /* If non-nil, always suppress point adjustment.
 
 The default value is nil, in which case, point adjustment are
 suppressed only after special commands that set
 
 The default value is nil, in which case, point adjustment are
 suppressed only after special commands that set
@@ -12181,7 +12090,7 @@ suppressed only after special commands that set
   Vglobal_disable_point_adjustment = Qnil;
 
   DEFVAR_LISP ("minibuffer-message-timeout", Vminibuffer_message_timeout,
   Vglobal_disable_point_adjustment = Qnil;
 
   DEFVAR_LISP ("minibuffer-message-timeout", Vminibuffer_message_timeout,
-              doc: /* *How long to display an echo-area message when the minibuffer is active.
+              doc: /* How long to display an echo-area message when the minibuffer is active.
 If the value is not a number, such messages don't time out.  */);
   Vminibuffer_message_timeout = make_number (2);
 
 If the value is not a number, such messages don't time out.  */);
   Vminibuffer_message_timeout = make_number (2);
 
@@ -12225,10 +12134,20 @@ text in the region before modifying the buffer.  The next
 `deactivate-mark' call uses this to set the window selection.  */);
   Vsaved_region_selection = Qnil;
 
 `deactivate-mark' call uses this to set the window selection.  */);
   Vsaved_region_selection = Qnil;
 
+  DEFVAR_LISP ("selection-inhibit-update-commands",
+              Vselection_inhibit_update_commands,
+              doc: /* List of commands which should not update the selection.
+Normally, if `select-active-regions' is non-nil and the mark remains
+active after a command (i.e. the mark was not deactivated), the Emacs
+command loop sets the selection to the text in the region.  However,
+if the command is in this list, the selection is not updated.  */);
+  Vselection_inhibit_update_commands
+    = list2 (Qhandle_switch_frame, Qhandle_select_window);
+
   DEFVAR_LISP ("debug-on-event",
                Vdebug_on_event,
                doc: /* Enter debugger on this event.  When Emacs
   DEFVAR_LISP ("debug-on-event",
                Vdebug_on_event,
                doc: /* Enter debugger on this event.  When Emacs
-receives the special event specifed by this variable, it will try to
+receives the special event specified by this variable, it will try to
 break into the debugger as soon as possible instead of processing the
 event normally through `special-event-map'.
 
 break into the debugger as soon as possible instead of processing the
 event normally through `special-event-map'.
 
@@ -12236,8 +12155,8 @@ Currently, the only supported values for this
 variable are `sigusr1' and `sigusr2'.  */);
   Vdebug_on_event = intern_c_string ("sigusr2");
 
 variable are `sigusr1' and `sigusr2'.  */);
   Vdebug_on_event = intern_c_string ("sigusr2");
 
-  /* Create the initial keyboard. */
-  initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+  /* Create the initial keyboard.  */
+  initial_kboard = xmalloc (sizeof *initial_kboard);
   init_kboard (initial_kboard);
   /* Vwindow_system is left at t for now.  */
   initial_kboard->next_kboard = all_kboards;
   init_kboard (initial_kboard);
   /* Vwindow_system is left at t for now.  */
   initial_kboard->next_kboard = all_kboards;
@@ -12300,10 +12219,14 @@ keys_of_keyboard (void)
 
   initial_define_lispy_key (Vspecial_event_map, "config-changed-event",
                            "ignore");
 
   initial_define_lispy_key (Vspecial_event_map, "config-changed-event",
                            "ignore");
+#if defined (WINDOWSNT)
+  initial_define_lispy_key (Vspecial_event_map, "language-change",
+                           "ignore");
+#endif
 }
 
 /* Mark the pointers in the kboard objects.
 }
 
 /* Mark the pointers in the kboard objects.
-   Called by the Fgarbage_collector.  */
+   Called by Fgarbage_collect.  */
 void
 mark_kboards (void)
 {
 void
 mark_kboards (void)
 {