]> code.delx.au - gnu-emacs/blobdiff - src/keyboard.c
Merge from trunk.
[gnu-emacs] / src / keyboard.c
index c601649ebcae06473afc46ae60253448558fe038..622f7ca4482eb90a71753010802d0e21cccf83b6 100644 (file)
@@ -134,7 +134,7 @@ static Lisp_Object raw_keybuf;
 static int raw_keybuf_count;
 
 #define GROW_RAW_KEYBUF                                                        \
- if (raw_keybuf_count == XVECTOR (raw_keybuf)->size)                   \
+ if (raw_keybuf_count == ASIZE (raw_keybuf))                           \
    raw_keybuf = larger_vector (raw_keybuf, raw_keybuf_count * 2, Qnil)  \
 
 /* Number of elements of this_command_keys
@@ -210,8 +210,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, modulo SIZE_MAX + 1.  */
-size_t num_input_events;
+/* Total number of times read_char has returned, modulo UINTMAX_MAX + 1.  */
+uintmax_t num_input_events;
 
 /* Value of num_nonmacro_input_events as of last auto save.  */
 
@@ -238,7 +238,7 @@ Lisp_Object internal_last_event_frame;
 
 /* The timestamp of the last input event we received from the X server.
    X Windows wants this for selection ownership.  */
-unsigned long last_event_timestamp;
+Time last_event_timestamp;
 
 static Lisp_Object Qx_set_selection, Qhandle_switch_frame;
 Lisp_Object QPRIMARY;
@@ -267,6 +267,8 @@ static Lisp_Object Qpost_command_hook;
 
 static Lisp_Object Qdeferred_action_function;
 
+static Lisp_Object Qdelayed_warnings_hook;
+
 static Lisp_Object Qinput_method_exit_on_first_char;
 static Lisp_Object Qinput_method_use_echo_area;
 
@@ -433,20 +435,20 @@ static void (*keyboard_init_hook) (void);
 static int read_avail_input (int);
 static void get_input_pending (int *, int);
 static int readable_events (int);
-static Lisp_Object read_char_x_menu_prompt (int, Lisp_Object *,
+static Lisp_Object read_char_x_menu_prompt (ptrdiff_t, Lisp_Object *,
                                             Lisp_Object, int *);
-static Lisp_Object read_char_minibuf_menu_prompt (int, int,
+static Lisp_Object read_char_minibuf_menu_prompt (int, ptrdiff_t,
                                                   Lisp_Object *);
 static Lisp_Object make_lispy_event (struct input_event *);
 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
 static Lisp_Object make_lispy_movement (struct frame *, Lisp_Object,
                                         enum scroll_bar_part,
                                         Lisp_Object, Lisp_Object,
-                                        unsigned long);
+                                       Time);
 #endif
 static Lisp_Object modify_event_symbol (EMACS_INT, unsigned, Lisp_Object,
                                         Lisp_Object, const char *const *,
-                                        Lisp_Object *, unsigned);
+                                        Lisp_Object *, EMACS_INT);
 static Lisp_Object make_lispy_switch_frame (Lisp_Object);
 static int help_char_p (Lisp_Object);
 static void save_getcjmp (jmp_buf);
@@ -1298,7 +1300,7 @@ some_mouse_moved (void)
 /* This is the actual command reading loop,
    sans error-handling encapsulation.  */
 
-static int read_key_sequence (Lisp_Object *, size_t, Lisp_Object,
+static int read_key_sequence (Lisp_Object *, int, Lisp_Object,
                               int, int, int);
 void safe_run_hooks (Lisp_Object);
 static void adjust_point_for_property (EMACS_INT, int);
@@ -1356,6 +1358,10 @@ command_loop_1 (void)
       if (!NILP (echo_area_buffer[0]))
        resize_echo_area_exactly ();
 
+      /* If there are warnings waiting, process them.  */
+      if (!NILP (Vdelayed_warnings_list))
+        safe_run_hooks (Qdelayed_warnings_hook);
+
       if (!NILP (Vdeferred_action_list))
        safe_run_hooks (Qdeferred_action_function);
     }
@@ -1533,7 +1539,18 @@ command_loop_1 (void)
          message_with_string ("%s is undefined", keys, 0);
          KVAR (current_kboard, defining_kbd_macro) = Qnil;
          update_mode_lines = 1;
-         KVAR (current_kboard, Vprefix_arg) = Qnil;
+         /* If this is a down-mouse event, don't reset prefix-arg;
+            pass it to the command run by the up event.  */
+         if (EVENT_HAS_PARAMETERS (last_command_event))
+           {
+             Lisp_Object breakdown
+               = parse_modifiers (EVENT_HEAD (last_command_event));
+             int modifiers = XINT (XCAR (XCDR (breakdown)));
+             if (!(modifiers & down_modifier))
+               KVAR (current_kboard, Vprefix_arg) = Qnil;
+           }
+         else
+           KVAR (current_kboard, Vprefix_arg) = Qnil;
        }
       else
        {
@@ -1573,6 +1590,10 @@ command_loop_1 (void)
       if (!NILP (echo_area_buffer[0]))
        resize_echo_area_exactly ();
 
+      /* If there are warnings waiting, process them.  */
+      if (!NILP (Vdelayed_warnings_list))
+        safe_run_hooks (Qdelayed_warnings_hook);
+
       safe_run_hooks (Qdeferred_action_function);
 
       /* If there is a prefix argument,
@@ -1719,7 +1740,7 @@ adjust_point_for_property (EMACS_INT last_pt, int modified)
          && PT > BEGV && PT < ZV
          && !NILP (val = get_char_property_and_overlay
                              (make_number (PT), Qdisplay, Qnil, &overlay))
-         && display_prop_intangible_p (val)
+         && display_prop_intangible_p (val, overlay, PT, PT_BYTE)
          && (!OVERLAYP (overlay)
              ? get_property_and_range (PT, Qdisplay, &val, &beg, &end, Qnil)
              : (beg = OVERLAY_POSITION (OVERLAY_START (overlay)),
@@ -1891,7 +1912,7 @@ safe_run_hooks_error (Lisp_Object error_data)
 }
 
 static Lisp_Object
-safe_run_hook_funcall (size_t nargs, Lisp_Object *args)
+safe_run_hook_funcall (ptrdiff_t nargs, Lisp_Object *args)
 {
   eassert (nargs == 1);
   if (CONSP (Vinhibit_quit))
@@ -2246,7 +2267,8 @@ do { if (polling_stopped_here) start_polling ();  \
    Value is t if we showed a menu and the user rejected it.  */
 
 Lisp_Object
-read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event,
+read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
+          Lisp_Object prev_event,
           int *used_mouse_menu, struct timeval *end_time)
 {
   volatile Lisp_Object c;
@@ -2385,8 +2407,8 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event
 
       c = Faref (Vexecuting_kbd_macro, make_number (executing_kbd_macro_index));
       if (STRINGP (Vexecuting_kbd_macro)
-         && (XINT (c) & 0x80) && (XUINT (c) <= 0xff))
-       XSETFASTINT (c, CHAR_META | (XINT (c) & ~0x80));
+         && (XFASTINT (c) & 0x80) && (XFASTINT (c) <= 0xff))
+       XSETFASTINT (c, CHAR_META | (XFASTINT (c) & ~0x80));
 
       executing_kbd_macro_index++;
 
@@ -2896,9 +2918,13 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event
        goto exit;
 
       if ((STRINGP (KVAR (current_kboard, Vkeyboard_translate_table))
-          && SCHARS (KVAR (current_kboard, Vkeyboard_translate_table)) > (unsigned) XFASTINT (c))
+          && UNSIGNED_CMP (XFASTINT (c), <,
+                           SCHARS (KVAR (current_kboard,
+                                         Vkeyboard_translate_table))))
          || (VECTORP (KVAR (current_kboard, Vkeyboard_translate_table))
-             && XVECTOR (KVAR (current_kboard, Vkeyboard_translate_table))->size > (unsigned) XFASTINT (c))
+             && UNSIGNED_CMP (XFASTINT (c), <,
+                              ASIZE (KVAR (current_kboard,
+                                           Vkeyboard_translate_table))))
          || (CHAR_TABLE_P (KVAR (current_kboard, Vkeyboard_translate_table))
              && CHARACTERP (c)))
        {
@@ -2945,9 +2971,7 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event
      save the echo area contents for it to refer to.  */
   if (INTEGERP (c)
       && ! NILP (Vinput_method_function)
-      && (unsigned) XINT (c) >= ' '
-      && (unsigned) XINT (c) != 127
-      && (unsigned) XINT (c) < 256)
+      && ' ' <= XINT (c) && XINT (c) < 256 && XINT (c) != 127)
     {
       previous_echo_area_message = Fcurrent_message ();
       Vinput_method_previous_message = previous_echo_area_message;
@@ -2972,9 +2996,7 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event
       /* Don't run the input method within a key sequence,
         after the first event of the key sequence.  */
       && NILP (prev_event)
-      && (unsigned) XINT (c) >= ' '
-      && (unsigned) XINT (c) != 127
-      && (unsigned) XINT (c) < 256)
+      && ' ' <= XINT (c) && XINT (c) < 256 && XINT (c) != 127)
     {
       Lisp_Object keys;
       int key_count, key_count_reset;
@@ -3311,9 +3333,9 @@ record_char (Lisp_Object c)
       if (INTEGERP (c))
        {
          if (XUINT (c) < 0x100)
-           putc (XINT (c), dribble);
+           putc (XUINT (c), dribble);
          else
-           fprintf (dribble, " 0x%x", (int) XUINT (c));
+           fprintf (dribble, " 0x%"pI"x", XUINT (c));
        }
       else
        {
@@ -3732,7 +3754,7 @@ kbd_buffer_events_waiting (int discard)
 \f
 /* Clear input event EVENT.  */
 
-static INLINE void
+static inline void
 clear_event (struct input_event *event)
 {
   event->kind = NO_EVENT;
@@ -4075,7 +4097,7 @@ kbd_buffer_get_event (KBOARD **kbp,
       Lisp_Object bar_window;
       enum scroll_bar_part part;
       Lisp_Object x, y;
-      unsigned long t;
+      Time t;
 
       *kbp = current_kboard;
       /* Note that this uses F to determine which terminal to look at.
@@ -4198,7 +4220,7 @@ timer_start_idle (void)
 
       timer = XCAR (timers);
 
-      if (!VECTORP (timer) || XVECTOR (timer)->size != 8)
+      if (!VECTORP (timer) || ASIZE (timer) != 8)
        continue;
       XVECTOR (timer)->contents[0] = Qnil;
     }
@@ -4293,7 +4315,7 @@ timer_check_2 (void)
       if (CONSP (timers))
        {
          timer = XCAR (timers);
-         if (!VECTORP (timer) || XVECTOR (timer)->size != 8)
+         if (!VECTORP (timer) || ASIZE (timer) != 8)
            {
              timers = XCDR (timers);
              continue;
@@ -4311,7 +4333,7 @@ timer_check_2 (void)
       if (CONSP (idle_timers))
        {
          timer = XCAR (idle_timers);
-         if (!VECTORP (timer) || XVECTOR (timer)->size != 8)
+         if (!VECTORP (timer) || ASIZE (timer) != 8)
            {
              idle_timers = XCDR (idle_timers);
              continue;
@@ -5078,7 +5100,7 @@ static Lisp_Object button_down_location;
 static int last_mouse_button;
 static int last_mouse_x;
 static int last_mouse_y;
-static unsigned long button_down_time;
+static Time button_down_time;
 
 /* The number of clicks in this multiple-click. */
 
@@ -5089,7 +5111,7 @@ static int double_click_count;
 
 static Lisp_Object
 make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
-                    unsigned long t)
+                    Time t)
 {
   enum window_part part;
   Lisp_Object posn = Qnil;
@@ -5381,7 +5403,7 @@ make_lispy_event (struct input_event *event)
                                      Qfunction_key,
                                      KVAR (current_kboard, Vsystem_key_alist),
                                      0, &KVAR (current_kboard, system_key_syms),
-                                     (unsigned) -1);
+                                     TYPE_MAXIMUM (EMACS_INT));
        }
 
       return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET,
@@ -5459,7 +5481,7 @@ make_lispy_event (struct input_event *event)
                /* Find the menu bar item under `column'.  */
                item = Qnil;
                items = FRAME_MENU_BAR_ITEMS (f);
-               for (i = 0; i < XVECTOR (items)->size; i += 4)
+               for (i = 0; i < ASIZE (items); i += 4)
                  {
                    Lisp_Object pos, string;
                    string = AREF (items, i + 1);
@@ -5546,9 +5568,9 @@ make_lispy_event (struct input_event *event)
                       && (eabs (XINT (event->y) - last_mouse_y) <= fuzz)
                       && button_down_time != 0
                       && (EQ (Vdouble_click_time, Qt)
-                          || (INTEGERP (Vdouble_click_time)
-                              && ((int)(event->timestamp - button_down_time)
-                                  < XINT (Vdouble_click_time)))));
+                          || (NATNUMP (Vdouble_click_time)
+                              && (event->timestamp - button_down_time
+                                  < XFASTINT (Vdouble_click_time)))));
        }
 
        last_mouse_button = button;
@@ -5652,7 +5674,7 @@ make_lispy_event (struct input_event *event)
                                      Qmouse_click, Vlispy_mouse_stem,
                                      NULL,
                                      &mouse_syms,
-                                     XVECTOR (mouse_syms)->size);
+                                     ASIZE (mouse_syms));
          if (event->modifiers & drag_modifier)
            return Fcons (head,
                          Fcons (start_pos,
@@ -5732,9 +5754,9 @@ make_lispy_event (struct input_event *event)
                       && (eabs (XINT (event->y) - last_mouse_y) <= fuzz)
                       && button_down_time != 0
                       && (EQ (Vdouble_click_time, Qt)
-                          || (INTEGERP (Vdouble_click_time)
-                              && ((int)(event->timestamp - button_down_time)
-                                  < XINT (Vdouble_click_time)))));
+                          || (NATNUMP (Vdouble_click_time)
+                              && (event->timestamp - button_down_time
+                                  < XFASTINT (Vdouble_click_time)))));
          if (is_double)
            {
              double_click_count++;
@@ -5823,7 +5845,7 @@ make_lispy_event (struct input_event *event)
                                    Qmouse_click,
                                    Vlispy_mouse_stem,
                                    NULL, &mouse_syms,
-                                   XVECTOR (mouse_syms)->size);
+                                   ASIZE (mouse_syms));
        return Fcons (head, Fcons (position, Qnil));
       }
 
@@ -5943,7 +5965,7 @@ make_lispy_event (struct input_event *event)
                                    Qmouse_click, Vlispy_mouse_stem,
                                    NULL,
                                    &mouse_syms,
-                                   XVECTOR (mouse_syms)->size);
+                                   ASIZE (mouse_syms));
 
        if (event->modifiers & drag_modifier)
          return Fcons (head,
@@ -5977,7 +5999,7 @@ make_lispy_event (struct input_event *event)
 
 static Lisp_Object
 make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_part part,
-                    Lisp_Object x, Lisp_Object y, unsigned long t)
+                    Lisp_Object x, Lisp_Object y, Time t)
 {
   /* Is it a scroll bar movement?  */
   if (frame && ! NILP (bar_window))
@@ -6360,7 +6382,7 @@ reorder_modifiers (Lisp_Object symbol)
   Lisp_Object parsed;
 
   parsed = parse_modifiers (symbol);
-  return apply_modifiers ((int) XINT (XCAR (XCDR (parsed))),
+  return apply_modifiers (XFASTINT (XCAR (XCDR (parsed))),
                          XCAR (parsed));
 }
 
@@ -6400,7 +6422,7 @@ reorder_modifiers (Lisp_Object symbol)
 static Lisp_Object
 modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object symbol_kind,
                     Lisp_Object name_alist_or_stem, const char *const *name_table,
-                    Lisp_Object *symbol_table, unsigned int table_size)
+                    Lisp_Object *symbol_table, EMACS_INT table_size)
 {
   Lisp_Object value;
   Lisp_Object symbol_int;
@@ -6422,7 +6444,7 @@ modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object s
   else
     {
       if (! VECTORP (*symbol_table)
-         || XVECTOR (*symbol_table)->size != table_size)
+         || ASIZE (*symbol_table) != table_size)
        {
          Lisp_Object size;
 
@@ -6443,8 +6465,8 @@ modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object s
        {
          int len = SBYTES (name_alist_or_stem);
          char *buf = (char *) alloca (len + 50);
-          sprintf (buf, "%s-%ld", SDATA (name_alist_or_stem),
-                   (long) XINT (symbol_int) + 1);
+          sprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem),
+                   XINT (symbol_int) + 1);
          value = intern (buf);
        }
       else if (name_table != 0 && name_table[symbol_num])
@@ -6462,7 +6484,7 @@ modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object s
       if (NILP (value))
        {
          char buf[20];
-         sprintf (buf, "key-%ld", (long)symbol_num);
+         sprintf (buf, "key-%"pI"d", symbol_num);
          value = intern (buf);
        }
 
@@ -7228,12 +7250,29 @@ handle_user_signal (int sig)
 {
   int old_errno = errno;
   struct user_signal_info *p;
+  const char *special_event_name = NULL;
 
   SIGNAL_THREAD_CHECK (sig);
 
+  if (SYMBOLP (Vdebug_on_event))
+    special_event_name = SSDATA (SYMBOL_NAME (Vdebug_on_event));
+
   for (p = user_signals; p; p = p->next)
     if (p->sig == sig)
       {
+        if (special_event_name &&
+            strcmp (special_event_name, p->name) == 0)
+          {
+            /* Enter the debugger in many ways.  */
+            debug_on_next_call = 1;
+            debug_on_quit = 1;
+            Vquit_flag = Qt;
+            Vinhibit_quit = Qnil;
+
+            /* Eat the event.  */
+            break;
+          }
+
        p->npending++;
 #ifdef SIGIO
        if (interrupt_input)
@@ -7367,7 +7406,7 @@ menu_bar_items (Lisp_Object old)
 {
   /* The number of keymaps we're scanning right now, and the number of
      keymaps we have allocated space for.  */
-  int nmaps;
+  ptrdiff_t nmaps;
 
   /* maps[0..nmaps-1] are the prefix definitions of KEYBUF[0..t-1]
      in the current keymaps, or nil where it is not a prefix.  */
@@ -7375,7 +7414,7 @@ menu_bar_items (Lisp_Object old)
 
   Lisp_Object def, tail;
 
-  int mapno;
+  ptrdiff_t mapno;
   Lisp_Object oquit;
 
   /* In order to build the menus, we need to call the keymap
@@ -7420,7 +7459,7 @@ menu_bar_items (Lisp_Object old)
           recognized when the menu-bar (or mode-line) is updated,
           which does not normally happen after every command.  */
        Lisp_Object tem;
-       int nminor;
+       ptrdiff_t nminor;
        nminor = current_minor_maps (NULL, &tmaps);
        maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0]));
        nmaps = 0;
@@ -7443,7 +7482,7 @@ menu_bar_items (Lisp_Object old)
        if (CONSP (def))
          {
            menu_bar_one_keymap_changed_items = Qnil;
-           map_keymap (def, menu_bar_item, Qnil, NULL, 1);
+           map_keymap_canonical (def, menu_bar_item, Qnil, NULL);
          }
       }
 
@@ -7479,7 +7518,7 @@ menu_bar_items (Lisp_Object old)
   /* Add nil, nil, nil, nil at the end.  */
   {
     int i = menu_bar_items_index;
-    if (i + 4 > XVECTOR (menu_bar_items_vector)->size)
+    if (i + 4 > ASIZE (menu_bar_items_vector))
       menu_bar_items_vector =
        larger_vector (menu_bar_items_vector, 2 * i, Qnil);
     /* Add this item.  */
@@ -7551,7 +7590,7 @@ menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dumm
   if (i == menu_bar_items_index)
     {
       /* If vector is too small, get a bigger one.  */
-      if (i + 4 > XVECTOR (menu_bar_items_vector)->size)
+      if (i + 4 > ASIZE (menu_bar_items_vector))
        menu_bar_items_vector = larger_vector (menu_bar_items_vector, 2 * i, Qnil);
       /* Add this item.  */
       XVECTOR (menu_bar_items_vector)->contents[i++] = key;
@@ -7784,7 +7823,7 @@ parse_menu_item (Lisp_Object item, int inmenubar)
   /* If we got no definition, this item is just unselectable text which
      is OK in a submenu but not in the menubar.  */
   if (NILP (def))
-    return (inmenubar ? 0 : 1);
+    return (!inmenubar);
 
   /* See if this is a separate pane or a submenu.  */
   def = AREF (item_properties, ITEM_PROPERTY_DEF);
@@ -7906,7 +7945,7 @@ static int ntool_bar_items;
 /* The symbols `:image' and `:rtl'.  */
 
 static Lisp_Object QCimage;
-static Lisp_Object Qrtl;
+static Lisp_Object QCrtl;
 
 /* Function prototypes.  */
 
@@ -7924,7 +7963,7 @@ Lisp_Object
 tool_bar_items (Lisp_Object reuse, int *nitems)
 {
   Lisp_Object *maps;
-  int nmaps, i;
+  ptrdiff_t nmaps, i;
   Lisp_Object oquit;
   Lisp_Object *tmaps;
 
@@ -7964,7 +8003,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems)
         recognized when the tool-bar (or mode-line) is updated,
         which does not normally happen after every command.  */
       Lisp_Object tem;
-      int nminor;
+      ptrdiff_t nminor;
       nminor = current_minor_maps (NULL, &tmaps);
       maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0]));
       nmaps = 0;
@@ -8198,7 +8237,7 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
           /* `:label LABEL-STRING'.  */
           PROP (TOOL_BAR_ITEM_LABEL) = STRINGP (value)
             ? value
-            : make_string (bad_label, strlen (bad_label));
+            : build_string (bad_label);
           have_label = 1;
         }
       else if (EQ (ikey, QCfilter))
@@ -8219,11 +8258,11 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
        }
       else if (EQ (ikey, QCimage)
               && (CONSP (value)
-                  || (VECTORP (value) && XVECTOR (value)->size == 4)))
+                  || (VECTORP (value) && ASIZE (value) == 4)))
        /* Value is either a single image specification or a vector
           of 4 such specifications for the different button states.  */
        PROP (TOOL_BAR_ITEM_IMAGES) = value;
-      else if (EQ (ikey, Qrtl))
+      else if (EQ (ikey, QCrtl))
         /* ':rtl STRING' */
        PROP (TOOL_BAR_ITEM_RTL_IMAGE) = value;
     }
@@ -8236,10 +8275,11 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
       Lisp_Object tcapt = PROP (TOOL_BAR_ITEM_CAPTION);
       const char *label = SYMBOLP (tkey) ? SSDATA (SYMBOL_NAME (tkey)) : "";
       const char *capt = STRINGP (tcapt) ? SSDATA (tcapt) : "";
-      EMACS_INT max_lbl = 2 * tool_bar_max_label_size;
+      ptrdiff_t max_lbl =
+       2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2));
       char *buf = (char *) xmalloc (max_lbl + 1);
       Lisp_Object new_lbl;
-      size_t caption_len = strlen (capt);
+      ptrdiff_t caption_len = strlen (capt);
 
       if (caption_len <= max_lbl && capt[0] != '\0')
         {
@@ -8252,7 +8292,7 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
 
       if (strlen (label) <= max_lbl && label[0] != '\0')
         {
-          int j;
+          ptrdiff_t j;
           if (label != buf)
            strcpy (buf, label);
 
@@ -8264,7 +8304,7 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
       else
        label = "";
 
-      new_lbl = Fupcase_initials (make_string (label, strlen (label)));
+      new_lbl = Fupcase_initials (build_string (label));
       if (SCHARS (new_lbl) <= tool_bar_max_label_size)
         PROP (TOOL_BAR_ITEM_LABEL) = new_lbl;
       else
@@ -8323,10 +8363,10 @@ append_tool_bar_item (void)
 
   /* Enlarge tool_bar_items_vector if necessary.  */
   if (ntool_bar_items + TOOL_BAR_ITEM_NSLOTS
-      >= XVECTOR (tool_bar_items_vector)->size)
+      >= ASIZE (tool_bar_items_vector))
     tool_bar_items_vector
       = larger_vector (tool_bar_items_vector,
-                      2 * XVECTOR (tool_bar_items_vector)->size, Qnil);
+                      2 * ASIZE (tool_bar_items_vector), Qnil);
 
   /* Append entries from tool_bar_item_properties to the end of
      tool_bar_items_vector.  */
@@ -8361,10 +8401,10 @@ append_tool_bar_item (void)
    and do auto-saving in the inner call of read_char. */
 
 static Lisp_Object
-read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event,
-                        int *used_mouse_menu)
+read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps,
+                        Lisp_Object prev_event, int *used_mouse_menu)
 {
-  int mapno;
+  ptrdiff_t mapno;
 
   if (used_mouse_menu)
     *used_mouse_menu = 0;
@@ -8392,7 +8432,7 @@ read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event,
       Lisp_Object *realmaps
        = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object));
       Lisp_Object value;
-      int nmaps1 = 0;
+      ptrdiff_t nmaps1 = 0;
 
       /* Use the maps that are not nil.  */
       for (mapno = 0; mapno < nmaps; mapno++)
@@ -8443,17 +8483,18 @@ read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event,
    We make this bigger when necessary, and never free it.  */
 static char *read_char_minibuf_menu_text;
 /* Size of that buffer.  */
-static int read_char_minibuf_menu_width;
+static ptrdiff_t read_char_minibuf_menu_width;
 
 static Lisp_Object
-read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
+read_char_minibuf_menu_prompt (int commandflag,
+                              ptrdiff_t nmaps, Lisp_Object *maps)
 {
-  int mapno;
+  ptrdiff_t mapno;
   register Lisp_Object name;
-  int nlength;
+  ptrdiff_t nlength;
   /* FIXME: Use the minibuffer's frame width.  */
-  int width = FRAME_COLS (SELECTED_FRAME ()) - 4;
-  int idx = -1;
+  ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4;
+  ptrdiff_t idx = -1;
   int nobindings = 1;
   Lisp_Object rest, vector;
   char *menu;
@@ -8478,16 +8519,13 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
 
   /* Make sure we have a big enough buffer for the menu text.  */
   width = max (width, SBYTES (name));
-  if (read_char_minibuf_menu_text == 0)
+  if (STRING_BYTES_BOUND - 4 < width)
+    memory_full (SIZE_MAX);
+  if (width + 4 > read_char_minibuf_menu_width)
     {
-      read_char_minibuf_menu_width = width + 4;
-      read_char_minibuf_menu_text = (char *) xmalloc (width + 4);
-    }
-  else if (width + 4 > read_char_minibuf_menu_width)
-    {
-      read_char_minibuf_menu_width = width + 4;
       read_char_minibuf_menu_text
        = (char *) xrealloc (read_char_minibuf_menu_text, width + 4);
+      read_char_minibuf_menu_width = width + 4;
     }
   menu = read_char_minibuf_menu_text;
 
@@ -8506,7 +8544,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
   while (1)
     {
       int notfirst = 0;
-      int i = nlength;
+      ptrdiff_t i = nlength;
       Lisp_Object obj;
       Lisp_Object orig_defn_macro;
 
@@ -8605,7 +8643,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
                      < width
                      || !notfirst)
                    {
-                     int thiswidth;
+                     ptrdiff_t thiswidth;
 
                      /* Punctuate between strings.  */
                      if (notfirst)
@@ -8621,9 +8659,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
                      if (! char_matches)
                        {
                          /* Add as much of string as fits.  */
-                         thiswidth = SCHARS (desc);
-                         if (thiswidth + i > width)
-                           thiswidth = width - i;
+                         thiswidth = min (SCHARS (desc), width - i);
                          memcpy (menu + i, SDATA (desc), thiswidth);
                          i += thiswidth;
                          strcpy (menu + i, " = ");
@@ -8631,9 +8667,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
                        }
 
                      /* Add as much of string as fits.  */
-                     thiswidth = SCHARS (s);
-                     if (thiswidth + i > width)
-                       thiswidth = width - i;
+                     thiswidth = min (SCHARS (s), width - i);
                      memcpy (menu + i, SDATA (s), thiswidth);
                      i += thiswidth;
                      menu[i] = 0;
@@ -8648,7 +8682,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
                }
 
              /* Move past this element.  */
-             if (idx >= 0 && idx + 1 >= XVECTOR (vector)->size)
+             if (idx >= 0 && idx + 1 >= ASIZE (vector))
                /* Handle reaching end of dense table.  */
                idx = -1;
              if (idx >= 0)
@@ -8708,10 +8742,10 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
    NEXT may be the same array as CURRENT.  */
 
 static int
-follow_key (Lisp_Object key, int nmaps, Lisp_Object *current, Lisp_Object *defs,
-           Lisp_Object *next)
+follow_key (Lisp_Object key, ptrdiff_t nmaps, Lisp_Object *current,
+           Lisp_Object *defs, Lisp_Object *next)
 {
-  int i, first_binding;
+  ptrdiff_t i, first_binding;
 
   first_binding = nmaps;
   for (i = nmaps - 1; i >= 0; i--)
@@ -8811,7 +8845,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, size_t bufsize, volatile keyremap *fkey,
+keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey,
               int input, int doit, int *diff, Lisp_Object prompt)
 {
   Lisp_Object next, key;
@@ -8833,7 +8867,7 @@ keyremap_step (Lisp_Object *keybuf, size_t bufsize, volatile keyremap *fkey,
 
       *diff = len - (fkey->end - fkey->start);
 
-      if (input + *diff >= bufsize)
+      if (bufsize - input <= *diff)
        error ("Key sequence too long");
 
       /* Shift the keys that follow fkey->end.  */
@@ -8904,7 +8938,7 @@ keyremap_step (Lisp_Object *keybuf, size_t bufsize, volatile keyremap *fkey,
    from the selected window's buffer.  */
 
 static int
-read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
+read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
                   int dont_downcase_last, int can_return_switch_frame,
                   int fix_current_buffer)
 {
@@ -8921,8 +8955,8 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
 
   /* The number of keymaps we're scanning right now, and the number of
      keymaps we have allocated space for.  */
-  int nmaps;
-  int nmaps_allocated = 0;
+  ptrdiff_t nmaps;
+  ptrdiff_t nmaps_allocated = 0;
 
   /* defs[0..nmaps-1] are the definitions of KEYBUF[0..t-1] in
      the current keymaps.  */
@@ -8946,7 +8980,7 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
   /* The index in submaps[] of the first keymap that has a binding for
      this key sequence.  In other words, the lowest i such that
      submaps[i] is non-nil.  */
-  int first_binding;
+  ptrdiff_t first_binding;
   /* Index of the first key that has no binding.
      It is useless to try fkey.start larger than that.  */
   int first_unbound;
@@ -9107,8 +9141,8 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
     }
   else
     {
-      int nminor;
-      int total;
+      ptrdiff_t nminor;
+      ptrdiff_t total;
       Lisp_Object *maps;
 
       nminor = current_minor_maps (0, &maps);
@@ -9174,7 +9208,8 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
         echo_local_start and keys_local_start allow us to throw away
         just one key.  */
       int echo_local_start IF_LINT (= 0);
-      int keys_local_start, local_first_binding;
+      int keys_local_start;
+      ptrdiff_t local_first_binding;
 
       eassert (indec.end == t || (indec.end > t && indec.end <= mock_input));
       eassert (indec.start <= indec.end);
@@ -9511,7 +9546,7 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
                  && (NILP (fake_prefixed_keys)
                      || NILP (Fmemq (key, fake_prefixed_keys))))
                {
-                 if (t + 1 >= bufsize)
+                 if (bufsize - t <= 1)
                    error ("Key sequence too long");
 
                  keybuf[t]     = posn;
@@ -9592,7 +9627,7 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
                 insert the dummy prefix event `menu-bar'.  */
              if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar))
                {
-                 if (t + 1 >= bufsize)
+                 if (bufsize - t <= 1)
                    error ("Key sequence too long");
                  keybuf[t] = posn;
                  keybuf[t+1] = key;
@@ -9926,7 +9961,7 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
              /* Treat uppercase keys as shifted.  */
              || (INTEGERP (key)
                  && (KEY_TO_CHAR (key)
-                     < XCHAR_TABLE (BVAR (current_buffer, downcase_table))->size)
+                     < XCHAR_TABLE (BVAR (current_buffer, downcase_table))->header.size)
                  && uppercasep (KEY_TO_CHAR (key))))
            {
              Lisp_Object new_key
@@ -10292,7 +10327,7 @@ give to the command you invoke, if it asks for an argument.  */)
     this_single_command_key_start = 0;
 
     keys = XVECTOR (saved_keys)->contents;
-    for (i = 0; i < XVECTOR (saved_keys)->size; i++)
+    for (i = 0; i < ASIZE (saved_keys); i++)
       add_command_key (keys[i]);
 
     for (i = 0; i < SCHARS (function); i++)
@@ -10585,7 +10620,7 @@ KEEP-RECORD is non-nil.  */)
 
   if (NILP (keep_record))
     {
-      for (i = 0; i < XVECTOR (recent_keys)->size; ++i)
+      for (i = 0; i < ASIZE (recent_keys); ++i)
        XVECTOR (recent_keys)->contents[i] = Qnil;
       total_keys = 0;
       recent_keys_index = 0;
@@ -10605,7 +10640,8 @@ DEFUN ("recursion-depth", Frecursion_depth, Srecursion_depth, 0, 0, 0,
 DEFUN ("open-dribble-file", Fopen_dribble_file, Sopen_dribble_file, 1, 1,
        "FOpen dribble file: ",
        doc: /* Start writing all keyboard characters to a dribble file called FILE.
-If FILE is nil, close any open dribble file.  */)
+If FILE is nil, close any open dribble file.
+The file will be closed when Emacs exits.  */)
   (Lisp_Object file)
 {
   if (dribble)
@@ -11458,7 +11494,7 @@ syms_of_keyboard (void)
   /* Tool-bars.  */
   DEFSYM (QCimage, ":image");
   DEFSYM (Qhelp_echo, "help-echo");
-  DEFSYM (Qrtl, ":rtl");
+  DEFSYM (QCrtl, ":rtl");
 
   staticpro (&item_properties);
   item_properties = Qnil;
@@ -11481,6 +11517,7 @@ syms_of_keyboard (void)
   DEFSYM (Qpre_command_hook, "pre-command-hook");
   DEFSYM (Qpost_command_hook, "post-command-hook");
   DEFSYM (Qdeferred_action_function, "deferred-action-function");
+  DEFSYM (Qdelayed_warnings_hook, "delayed-warnings-hook");
   DEFSYM (Qfunction_key, "function-key");
   DEFSYM (Qmouse_click, "mouse-click");
   DEFSYM (Qdrag_n_drop, "drag-n-drop");
@@ -12052,6 +12089,14 @@ This function is called with no arguments after each command
 whenever `deferred-action-list' is non-nil.  */);
   Vdeferred_action_function = Qnil;
 
+  DEFVAR_LISP ("delayed-warnings-list", Vdelayed_warnings_list,
+               doc: /* List of warnings to be displayed as soon as possible.
+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.
@@ -12165,6 +12210,17 @@ text in the region before modifying the buffer.  The next
 `deactivate-mark' call uses this to set the window selection.  */);
   Vsaved_region_selection = Qnil;
 
+  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
+break into the debugger as soon as possible instead of processing the
+event normally through `special-event-map'.
+
+Currently, the only supported values for this
+variable are `sigusr1' and `sigusr2'.  */);
+  Vdebug_on_event = intern_c_string ("sigusr2");
+
   /* Create the initial keyboard. */
   initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
   init_kboard (initial_kboard);