Merge from trunk
[bpt/emacs.git] / src / keyboard.c
index 5680f32..d307250 100644 (file)
@@ -201,8 +201,8 @@ Lisp_Object unread_switch_frame;
 /* Last size recorded for a current buffer which is not a minibuffer.  */
 static EMACS_INT last_non_minibuf_size;
 
-/* Total number of times read_char has returned.  */
-int num_input_events;
+/* Total number of times read_char has returned, modulo SIZE_MAX + 1.  */
+size_t num_input_events;
 
 /* Value of num_nonmacro_input_events as of last auto save.  */
 
@@ -254,7 +254,6 @@ Lisp_Object Qecho_area_clear_hook;
 /* Hooks to run before and after each command.  */
 Lisp_Object Qpre_command_hook;
 Lisp_Object Qpost_command_hook;
-Lisp_Object Qcommand_hook_internal;
 
 Lisp_Object Qdeferred_action_function;
 
@@ -351,7 +350,7 @@ Lisp_Object Qmenu_bar;
 Lisp_Object recursive_edit_unwind (Lisp_Object buffer), command_loop (void);
 Lisp_Object Fthis_command_keys (void);
 Lisp_Object Qextended_command_history;
-EMACS_TIME timer_check (int do_it_now);
+EMACS_TIME timer_check (void);
 
 static void record_menu_key (Lisp_Object c);
 static int echo_length (void);
@@ -434,15 +433,15 @@ static void restore_getcjmp (jmp_buf);
 static Lisp_Object apply_modifiers (int, Lisp_Object);
 static void clear_event (struct input_event *);
 static Lisp_Object restore_kboard_configuration (Lisp_Object);
-static SIGTYPE interrupt_signal (int signalnum);
+static void interrupt_signal (int signalnum);
 #ifdef SIGIO
-static SIGTYPE input_available_signal (int signo);
+static void input_available_signal (int signo);
 #endif
 static void handle_interrupt (void);
 static void timer_start_idle (void);
 static void timer_stop_idle (void);
 static void timer_resume_idle (void);
-static SIGTYPE handle_user_signal (int);
+static void handle_user_signal (int);
 static char *find_user_signal_name (int);
 static int store_user_signal_events (void);
 
@@ -1135,7 +1134,7 @@ command_loop_2 (Lisp_Object ignore)
 static Lisp_Object
 top_level_2 (void)
 {
-  return Feval (Vtop_level);
+  return Feval (Vtop_level, Qnil);
 }
 
 Lisp_Object
@@ -1169,6 +1168,7 @@ This also exits all active minibuffers.  */)
   Fthrow (Qtop_level, Qnil);
 }
 
+Lisp_Object Fexit_recursive_edit (void) NO_RETURN;
 DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0, "",
        doc: /* Exit from the innermost recursive edit or minibuffer.  */)
   (void)
@@ -1179,6 +1179,7 @@ DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0,
   error ("No recursive edit is in progress");
 }
 
+Lisp_Object Fabort_recursive_edit (void) NO_RETURN;
 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)
@@ -1268,7 +1269,7 @@ some_mouse_moved (void)
 /* This is the actual command reading loop,
    sans error-handling encapsulation.  */
 
-static int read_key_sequence (Lisp_Object *, int, Lisp_Object,
+static int read_key_sequence (Lisp_Object *, size_t, Lisp_Object,
                               int, int, int);
 void safe_run_hooks (Lisp_Object);
 static void adjust_point_for_property (EMACS_INT, int);
@@ -1490,10 +1491,7 @@ command_loop_1 (void)
 
       Vthis_command = cmd;
       real_this_command = cmd;
-      /* Note that the value cell will never directly contain nil
-        if the symbol is a local variable.  */
-      if (!NILP (Vpre_command_hook) && !NILP (Vrun_hooks))
-       safe_run_hooks (Qpre_command_hook);
+      safe_run_hooks (Qpre_command_hook);
 
       already_adjusted = 0;
 
@@ -1539,18 +1537,14 @@ command_loop_1 (void)
           }
       KVAR (current_kboard, Vlast_prefix_arg) = Vcurrent_prefix_arg;
 
-      /* Note that the value cell will never directly contain nil
-        if the symbol is a local variable.  */
-      if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))
-       safe_run_hooks (Qpost_command_hook);
+      safe_run_hooks (Qpost_command_hook);
 
       /* If displaying a message, resize the echo area window to fit
         that message's size exactly.  */
       if (!NILP (echo_area_buffer[0]))
        resize_echo_area_exactly ();
 
-      if (!NILP (Vdeferred_action_list))
-       safe_run_hooks (Qdeferred_action_function);
+      safe_run_hooks (Qdeferred_action_function);
 
       /* If there is a prefix argument,
         1) We don't want Vlast_command to be ``universal-argument''
@@ -1619,7 +1613,10 @@ command_loop_1 (void)
                }
 
              if (current_buffer != prev_buffer || MODIFF != prev_modiff)
-               call1 (Vrun_hooks, intern ("activate-mark-hook"));
+                {
+                  Lisp_Object hook = intern ("activate-mark-hook");
+                  Frun_hooks (1, &hook);
+                }
            }
 
          Vsaved_region_selection = Qnil;
@@ -1817,22 +1814,63 @@ adjust_point_for_property (EMACS_INT last_pt, int modified)
 static Lisp_Object
 safe_run_hooks_1 (void)
 {
-  if (NILP (Vrun_hooks))
-    return Qnil;
-  return call1 (Vrun_hooks, Vinhibit_quit);
+  eassert (CONSP (Vinhibit_quit));
+  return call0 (XCDR (Vinhibit_quit));
 }
 
-/* Subroutine for safe_run_hooks: handle an error by clearing out the hook.  */
+/* Subroutine for safe_run_hooks: handle an error by clearing out the function
+   from the hook.  */
+
+static Lisp_Object
+safe_run_hooks_error (Lisp_Object error_data)
+{
+  Lisp_Object hook
+    = 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[1] = hook;
+  args[2] = fun;
+  args[3] = error_data;
+  Fmessage (4, args);
+  if (SYMBOLP (hook))
+    {
+      Lisp_Object val;
+      int found = 0;
+      Lisp_Object newval = Qnil;
+      for (val = find_symbol_value (hook); CONSP (val); val = XCDR (val))
+       if (EQ (fun, XCAR (val)))
+         found = 1;
+       else
+         newval = Fcons (XCAR (val), newval);
+      if (found)
+       return Fset (hook, Fnreverse (newval));
+      /* Not found in the local part of the hook.  Let's look at the global
+        part.  */
+      newval = Qnil;
+      for (val = (NILP (Fdefault_boundp (hook)) ? Qnil
+                 : Fdefault_value (hook));
+          CONSP (val); val = XCDR (val))
+       if (EQ (fun, XCAR (val)))
+         found = 1;
+       else
+         newval = Fcons (XCAR (val), newval);
+      if (found)
+       return Fset_default (hook, Fnreverse (newval));
+    }
+  return Qnil;
+}
 
 static Lisp_Object
-safe_run_hooks_error (Lisp_Object data)
+safe_run_hook_funcall (size_t nargs, Lisp_Object *args)
 {
-  Lisp_Object args[3];
-  args[0] = build_string ("Error in %s: %s");
-  args[1] = Vinhibit_quit;
-  args[2] = data;
-  Fmessage (3, args);
-  return Fset (Vinhibit_quit, Qnil);
+  eassert (nargs == 1);
+  if (CONSP (Vinhibit_quit))
+    XSETCDR (Vinhibit_quit, args[0]);
+  else
+    Vinhibit_quit = Fcons (Vinhibit_quit, args[0]);
+
+  return internal_condition_case (safe_run_hooks_1, Qt, safe_run_hooks_error);
 }
 
 /* If we get an error while running the hook, cause the hook variable
@@ -1842,10 +1880,13 @@ safe_run_hooks_error (Lisp_Object data)
 void
 safe_run_hooks (Lisp_Object hook)
 {
+  /* FIXME: our `internal_condition_case' does not provide any way to pass data
+     to its body or to its handlers other than via globals such as
+     dynamically-bound variables ;-)  */
   int count = SPECPDL_INDEX ();
   specbind (Qinhibit_quit, hook);
 
-  internal_condition_case (safe_run_hooks_1, Qt, safe_run_hooks_error);
+  run_hook_with_args (1, &hook, safe_run_hook_funcall);
 
   unbind_to (count, Qnil);
 }
@@ -2072,16 +2113,12 @@ make_ctrl_char (int c)
    the `display' property).  POS is the position in that string under
    the mouse.
 
-   OK_TO_OVERWRITE_KEYSTROKE_ECHO non-zero means it's okay if the help
-   echo overwrites a keystroke echo currently displayed in the echo
-   area.
-
    Note: this function may only be called with HELP nil or a string
    from X code running asynchronously.  */
 
 void
 show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object,
-               Lisp_Object pos, int ok_to_overwrite_keystroke_echo)
+               Lisp_Object pos)
 {
   if (!NILP (help) && !STRINGP (help))
     {
@@ -2692,7 +2729,7 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event
 
   if (NILP (c))
     {
-      KBOARD *kb;
+      KBOARD *kb IF_LINT (= NULL);
 
       if (end_time)
        {
@@ -2940,7 +2977,7 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event
        keys = Fcopy_sequence (this_command_keys);
       else
        keys = Qnil;
-      GCPRO1_VAR (keys, inner_gcpro1);
+      GCPRO1_VAR (keys, inner_gcpro);
 
       /* Clear out this_command_keys.  */
       this_command_key_count = 0;
@@ -2978,7 +3015,7 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event
       if (saved_immediate_echo)
        echo_now ();
 
-      UNGCPRO_VAR (inner_gcpro1);
+      UNGCPRO_VAR (inner_gcpro);
 
       /* The input method can return no events.  */
       if (! CONSP (tem))
@@ -3011,7 +3048,7 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event
       htem = Fcdr (htem);
       position = Fcar (htem);
 
-      show_help_echo (help, window, object, position, 0);
+      show_help_echo (help, window, object, position);
 
       /* We stopped being idle for this event; undo that.  */
       if (!end_time)
@@ -3058,7 +3095,7 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event
                 help_form_saved_window_configs);
       record_unwind_protect (read_char_help_form_unwind, Qnil);
 
-      tem0 = Feval (Vhelp_form);
+      tem0 = Feval (Vhelp_form, Qnil);
       if (STRINGP (tem0))
        internal_with_output_to_temp_buffer ("*Help*", print_help, tem0);
 
@@ -3313,7 +3350,7 @@ static int
 readable_events (int flags)
 {
   if (flags & READABLE_EVENTS_DO_TIMERS_NOW)
-    timer_check (1);
+    timer_check ();
 
   /* If the buffer contains only FOCUS_IN_EVENT events, and
      READABLE_EVENTS_FILTER_EVENTS is set, report it as empty.  */
@@ -4387,14 +4424,10 @@ timer_check_2 (void)
    Returns the time to wait until the next timer fires.
    If no timer is active, return -1.
 
-   As long as any timer is ripe, we run it.
-
-   DO_IT_NOW is now ignored.  It used to mean that we should
-   run the timer directly instead of queueing a timer-event.
-   Now we always run timers directly.  */
+   As long as any timer is ripe, we run it.  */
 
 EMACS_TIME
-timer_check (int do_it_now)
+timer_check (void)
 {
   EMACS_TIME nexttime;
 
@@ -5403,7 +5436,6 @@ make_lispy_event (struct input_event *event)
                && (event->modifiers & down_modifier))
              {
                Lisp_Object items, item;
-               int hpos;
                int i;
 
                /* Find the menu bar item under `column'.  */
@@ -5972,10 +6004,10 @@ make_lispy_switch_frame (Lisp_Object frame)
    This doesn't use any caches.  */
 
 static int
-parse_modifiers_uncached (Lisp_Object symbol, int *modifier_end)
+parse_modifiers_uncached (Lisp_Object symbol, EMACS_INT *modifier_end)
 {
   Lisp_Object name;
-  int i;
+  EMACS_INT i;
   int modifiers;
 
   CHECK_SYMBOL (symbol);
@@ -5985,7 +6017,7 @@ parse_modifiers_uncached (Lisp_Object symbol, int *modifier_end)
 
   for (i = 0; i+2 <= SBYTES (name); )
     {
-      int this_mod_end = 0;
+      EMACS_INT this_mod_end = 0;
       int this_mod = 0;
 
       /* See if the name continues with a modifier word.
@@ -6182,7 +6214,7 @@ parse_modifiers (Lisp_Object symbol)
     return elements;
   else
     {
-      int end;
+      EMACS_INT end;
       int modifiers = parse_modifiers_uncached (symbol, &end);
       Lisp_Object unmodified;
       Lisp_Object mask;
@@ -7095,7 +7127,7 @@ process_pending_signals (void)
 #ifdef SIGIO   /* for entire page */
 /* Note SIGIO has been undef'd if FIONREAD is missing.  */
 
-static SIGTYPE
+static void
 input_available_signal (int signo)
 {
   /* Must preserve main program's value of errno.  */
@@ -7173,7 +7205,7 @@ add_user_signal (int sig, const char *name)
   signal (sig, handle_user_signal);
 }
 
-static SIGTYPE
+static void
 handle_user_signal (int sig)
 {
   int old_errno = errno;
@@ -7539,6 +7571,12 @@ menu_item_eval_property_1 (Lisp_Object arg)
   return Qnil;
 }
 
+static Lisp_Object
+eval_dyn (Lisp_Object form)
+{
+  return Feval (form, Qnil);
+}
+
 /* Evaluate an expression and return the result (or nil if something
    went wrong).  Used to evaluate dynamic parts of menu items.  */
 Lisp_Object
@@ -7547,7 +7585,7 @@ menu_item_eval_property (Lisp_Object sexpr)
   int count = SPECPDL_INDEX ();
   Lisp_Object val;
   specbind (Qinhibit_redisplay, Qt);
-  val = internal_condition_case_1 (Feval, sexpr, Qerror,
+  val = internal_condition_case_1 (eval_dyn, sexpr, Qerror,
                                   menu_item_eval_property_1);
   return unbind_to (count, val);
 }
@@ -8761,7 +8799,7 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt,
    The return value is non-zero if the remapping actually took place.  */
 
 static int
-keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey,
+keyremap_step (Lisp_Object *keybuf, size_t bufsize, volatile keyremap *fkey,
               int input, int doit, int *diff, Lisp_Object prompt)
 {
   Lisp_Object next, key;
@@ -8854,7 +8892,7 @@ keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey,
    from the selected window's buffer.  */
 
 static int
-read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
+read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
                   int dont_downcase_last, int can_return_switch_frame,
                   int fix_current_buffer)
 {
@@ -8961,7 +8999,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
 
   struct gcpro outer_gcpro1;
 
-  GCPRO1_VAR (fake_prefixed_keys, outer_gcpro1);
+  GCPRO1_VAR (fake_prefixed_keys, outer_gcpro);
   raw_keybuf_count = 0;
 
   last_nonmenu_event = Qnil;
@@ -9256,7 +9294,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
          if (EQ (key, Qt))
            {
              unbind_to (count, Qnil);
-             UNGCPRO_VAR (outer_gcpro1);
+             UNGCPRO_VAR (outer_gcpro);
              return -1;
            }
 
@@ -9372,80 +9410,84 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
                    last_real_key_start = t - 1;
                }
 
-             /* Key sequences beginning with mouse clicks are
-                read using the keymaps in the buffer clicked on,
-                not the current buffer.  If we're at the
-                beginning of a key sequence, switch buffers.  */
-             if (last_real_key_start == 0
-                 && WINDOWP (window)
-                 && BUFFERP (XWINDOW (window)->buffer)
-                 && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
+             if (last_real_key_start == 0)
                {
-                 XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = key;
-                 keybuf[t] = key;
-                 mock_input = t + 1;
-
-                 /* Arrange to go back to the original buffer once we're
-                    done reading the key sequence.  Note that we can't
-                    use save_excursion_{save,restore} here, because they
-                    save point as well as the current buffer; we don't
-                    want to save point, because redisplay may change it,
-                    to accommodate a Fset_window_start or something.  We
-                    don't want to do this at the top of the function,
-                    because we may get input from a subprocess which
-                    wants to change the selected window and stuff (say,
-                    emacsclient).  */
-                 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
-
-                 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
-                   Fkill_emacs (Qnil);
-                 set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
-                 orig_local_map = get_local_map (PT, current_buffer,
-                                                 Qlocal_map);
-                 orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
-                 goto replay_sequence;
-               }
+                 /* Key sequences beginning with mouse clicks are
+                    read using the keymaps in the buffer clicked on,
+                    not the current buffer.  If we're at the
+                    beginning of a key sequence, switch buffers.  */
+                 if (WINDOWP (window)
+                     && BUFFERP (XWINDOW (window)->buffer)
+                     && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
+                   {
+                     XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = key;
+                     keybuf[t] = key;
+                     mock_input = t + 1;
+
+                     /* Arrange to go back to the original buffer once we're
+                        done reading the key sequence.  Note that we can't
+                        use save_excursion_{save,restore} here, because they
+                        save point as well as the current buffer; we don't
+                        want to save point, because redisplay may change it,
+                        to accommodate a Fset_window_start or something.  We
+                        don't want to do this at the top of the function,
+                        because we may get input from a subprocess which
+                        wants to change the selected window and stuff (say,
+                        emacsclient).  */
+                     record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+
+                     if (! FRAME_LIVE_P (XFRAME (selected_frame)))
+                       Fkill_emacs (Qnil);
+                     set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
+                     orig_local_map = get_local_map (PT, current_buffer,
+                                                     Qlocal_map);
+                     orig_keymap = get_local_map (PT, current_buffer,
+                                                  Qkeymap);
+                     goto replay_sequence;
+                   }
 
-             /* For a mouse click, get the local text-property keymap
-                of the place clicked on, rather than point.  */
-             if (last_real_key_start == 0
-                 && CONSP (XCDR (key))
-                 && ! localized_local_map)
-               {
-                 Lisp_Object map_here, start, pos;
+                 /* For a mouse click, get the local text-property keymap
+                    of the place clicked on, rather than point.  */
+                 if (CONSP (XCDR (key))
+                     && ! localized_local_map)
+                   {
+                     Lisp_Object map_here, start, pos;
 
-                 localized_local_map = 1;
-                 start = EVENT_START (key);
+                     localized_local_map = 1;
+                     start = EVENT_START (key);
 
-                 if (CONSP (start) && POSN_INBUFFER_P (start))
-                   {
-                     pos = POSN_BUFFER_POSN (start);
-                     if (INTEGERP (pos)
-                         && XINT (pos) >= BEGV
-                         && XINT (pos) <= ZV)
+                     if (CONSP (start) && POSN_INBUFFER_P (start))
                        {
-                         map_here = get_local_map (XINT (pos),
-                                                   current_buffer, Qlocal_map);
-                         if (!EQ (map_here, orig_local_map))
+                         pos = POSN_BUFFER_POSN (start);
+                         if (INTEGERP (pos)
+                             && XINT (pos) >= BEGV
+                             && XINT (pos) <= ZV)
                            {
-                             orig_local_map = map_here;
-                             ++localized_local_map;
-                           }
+                             map_here = get_local_map (XINT (pos),
+                                                       current_buffer,
+                                                       Qlocal_map);
+                             if (!EQ (map_here, orig_local_map))
+                               {
+                                 orig_local_map = map_here;
+                                 ++localized_local_map;
+                               }
 
-                         map_here = get_local_map (XINT (pos),
-                                                    current_buffer, Qkeymap);
-                         if (!EQ (map_here, orig_keymap))
-                           {
-                             orig_keymap = map_here;
-                             ++localized_local_map;
-                           }
+                             map_here = get_local_map (XINT (pos),
+                                                       current_buffer,
+                                                       Qkeymap);
+                             if (!EQ (map_here, orig_keymap))
+                               {
+                                 orig_keymap = map_here;
+                                 ++localized_local_map;
+                               }
 
-                         if (localized_local_map > 1)
-                           {
-                             keybuf[t] = key;
-                             mock_input = t + 1;
+                             if (localized_local_map > 1)
+                               {
+                                 keybuf[t] = key;
+                                 mock_input = t + 1;
 
-                             goto replay_sequence;
+                                 goto replay_sequence;
+                               }
                            }
                        }
                    }
@@ -9834,7 +9876,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
          && /* indec.start >= t && fkey.start >= t && */ keytran.start >= t
          && INTEGERP (key)
          && ((CHARACTERP (make_number (XINT (key) & ~CHAR_MODIFIER_MASK))
-              && UPPERCASEP (XINT (key) & ~CHAR_MODIFIER_MASK))
+              && uppercasep (XINT (key) & ~CHAR_MODIFIER_MASK))
              || (XINT (key) & shift_modifier)))
        {
          Lisp_Object new_key;
@@ -9845,7 +9887,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
          if (XINT (key) & shift_modifier)
            XSETINT (new_key, XINT (key) & ~shift_modifier);
          else
-           XSETINT (new_key, (DOWNCASE (XINT (key) & ~CHAR_MODIFIER_MASK)
+           XSETINT (new_key, (downcase (XINT (key) & ~CHAR_MODIFIER_MASK)
                               | (XINT (key) & CHAR_MODIFIER_MASK)));
 
          /* We have to do this unconditionally, regardless of whether
@@ -9873,13 +9915,13 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
              || (INTEGERP (key)
                  && (KEY_TO_CHAR (key)
                      < XCHAR_TABLE (BVAR (current_buffer, downcase_table))->size)
-                 && UPPERCASEP (KEY_TO_CHAR (key))))
+                 && uppercasep (KEY_TO_CHAR (key))))
            {
              Lisp_Object new_key
                = (modifiers & shift_modifier
                   ? apply_modifiers (modifiers & ~shift_modifier,
                                      XCAR (breakdown))
-                  : make_number (DOWNCASE (KEY_TO_CHAR (key)) | modifiers));
+                  : make_number (downcase (KEY_TO_CHAR (key)) | modifiers));
 
              original_uppercase = key;
              original_uppercase_position = t - 1;
@@ -9939,7 +9981,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
       add_command_key (keybuf[t]);
     }
 
-  UNGCPRO_VAR (outer_gcpro1);
+  UNGCPRO_VAR (outer_gcpro);
   return t;
 }
 
@@ -10127,11 +10169,11 @@ a special event, so ignore the prefix argument and don't clear it.  */)
   if (SYMBOLP (cmd))
     {
       tem = Fget (cmd, Qdisabled);
-      if (!NILP (tem) && !NILP (Vrun_hooks))
+      if (!NILP (tem))
        {
          tem = Fsymbol_value (Qdisabled_command_function);
          if (!NILP (tem))
-           return call1 (Vrun_hooks, Qdisabled_command_function);
+           return Frun_hooks (1, &Qdisabled_command_function);
        }
     }
 
@@ -10304,9 +10346,9 @@ give to the command you invoke, if it asks for an argument.  */)
          sprintf (newmessage, "You can run the command `%s' with %s",
                   SDATA (SYMBOL_NAME (function)),
                   SDATA (binding));
-         message2_nolog (newmessage,
-                         strlen (newmessage),
-                         STRING_MULTIBYTE (binding));
+         message2 (newmessage,
+                   strlen (newmessage),
+                   STRING_MULTIBYTE (binding));
          if (NUMBERP (Vsuggest_key_bindings))
            waited = sit_for (Vsuggest_key_bindings, 0, 2);
          else
@@ -10615,6 +10657,7 @@ On such systems, Emacs starts a subshell instead of suspending.  */)
   int old_height, old_width;
   int width, height;
   struct gcpro gcpro1;
+  Lisp_Object hook;
 
   if (tty_list && tty_list->next)
     error ("There are other tty frames open; close them before suspending Emacs");
@@ -10623,8 +10666,8 @@ On such systems, Emacs starts a subshell instead of suspending.  */)
     CHECK_STRING (stuffstring);
 
   /* Run the functions in suspend-hook.  */
-  if (!NILP (Vrun_hooks))
-    call1 (Vrun_hooks, intern ("suspend-hook"));
+  hook = intern ("suspend-hook");
+  Frun_hooks (1, &hook);
 
   GCPRO1 (stuffstring);
   get_tty_size (fileno (CURTTY ()->input), &old_width, &old_height);
@@ -10648,8 +10691,8 @@ On such systems, Emacs starts a subshell instead of suspending.  */)
     change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0);
 
   /* Run suspend-resume-hook.  */
-  if (!NILP (Vrun_hooks))
-    call1 (Vrun_hooks, intern ("suspend-resume-hook"));
+  hook = intern ("suspend-resume-hook");
+  Frun_hooks (1, &hook);
 
   UNGCPRO;
   return Qnil;
@@ -10724,7 +10767,7 @@ clear_waiting_for_input (void)
    SIGINT was generated by C-g, so we call handle_interrupt.
    Otherwise, the handler kills Emacs.  */
 
-static SIGTYPE
+static void
 interrupt_signal (int signalnum)       /* If we don't have an argument, some */
                                        /* compilers complain in signal calls. */
 {
@@ -11450,9 +11493,6 @@ syms_of_keyboard (void)
   Qdeferred_action_function = intern_c_string ("deferred-action-function");
   staticpro (&Qdeferred_action_function);
 
-  Qcommand_hook_internal = intern_c_string ("command-hook-internal");
-  staticpro (&Qcommand_hook_internal);
-
   Qfunction_key = intern_c_string ("function-key");
   staticpro (&Qfunction_key);
   Qmouse_click = intern_c_string ("mouse-click");
@@ -11572,12 +11612,12 @@ syms_of_keyboard (void)
   last_point_position_window = Qnil;
 
   {
-    const struct event_head *p;
+    int i;
+    int len = sizeof (head_table) / sizeof (head_table[0]);
 
-    for (p = head_table;
-        p < head_table + (sizeof (head_table) / sizeof (head_table[0]));
-        p++)
+    for (i = 0; i < len; i++)
       {
+       const struct event_head *p = &head_table[i];
        *p->var = intern_c_string (p->name);
        staticpro (p->var);
        Fput (*p->var, Qevent_kind, *p->kind);
@@ -11920,22 +11960,18 @@ Buffer modification stores t in this variable.  */);
   Qdeactivate_mark = intern_c_string ("deactivate-mark");
   staticpro (&Qdeactivate_mark);
 
-  DEFVAR_LISP ("command-hook-internal", Vcommand_hook_internal,
-              doc: /* Temporary storage of `pre-command-hook' or `post-command-hook'.  */);
-  Vcommand_hook_internal = Qnil;
-
   DEFVAR_LISP ("pre-command-hook", Vpre_command_hook,
               doc: /* Normal hook run before each command is executed.
 If an unhandled error happens in running this hook,
-the hook value is set to nil, since otherwise the error
-might happen repeatedly and make Emacs nonfunctional.  */);
+the function in which the error occurred is unconditionally removed, since
+otherwise the error might happen repeatedly and make Emacs nonfunctional.  */);
   Vpre_command_hook = Qnil;
 
   DEFVAR_LISP ("post-command-hook", Vpost_command_hook,
               doc: /* Normal hook run after each command is executed.
 If an unhandled error happens in running this hook,
-the hook value is set to nil, since otherwise the error
-might happen repeatedly and make Emacs nonfunctional.  */);
+the function in which the error occurred is unconditionally removed, since
+otherwise the error might happen repeatedly and make Emacs nonfunctional.  */);
   Vpost_command_hook = Qnil;
 
 #if 0