Merge from trunk.
[bpt/emacs.git] / src / xdisp.c
index c6939a5..d051e88 100644 (file)
@@ -748,7 +748,7 @@ static Lisp_Object Qinhibit_free_realized_faces;
 Lisp_Object help_echo_string;
 Lisp_Object help_echo_window;
 Lisp_Object help_echo_object;
-EMACS_INT help_echo_pos;
+ptrdiff_t help_echo_pos;
 
 /* Temporary variable for XTread_socket.  */
 
@@ -795,33 +795,33 @@ static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
 
 static void handle_line_prefix (struct it *);
 
-static void pint2str (char *, int, EMACS_INT);
-static void pint2hrstr (char *, int, EMACS_INT);
+static void pint2str (char *, int, ptrdiff_t);
+static void pint2hrstr (char *, int, ptrdiff_t);
 static struct text_pos run_window_scroll_functions (Lisp_Object,
                                                     struct text_pos);
 static void reconsider_clip_changes (struct window *, struct buffer *);
 static int text_outside_line_unchanged_p (struct window *,
-                                         EMACS_INT, EMACS_INT);
+                                         ptrdiff_t, ptrdiff_t);
 static void store_mode_line_noprop_char (char);
 static int store_mode_line_noprop (const char *, int, int);
 static void handle_stop (struct it *);
-static void handle_stop_backwards (struct it *, EMACS_INT);
+static void handle_stop_backwards (struct it *, ptrdiff_t);
 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
 static void ensure_echo_area_buffers (void);
 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
 static int with_echo_area_buffer (struct window *, int,
-                                  int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
-                                  EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+                                  int (*) (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t),
+                                  ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
 static void clear_garbaged_frames (void);
-static int current_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static int current_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
 static void pop_message (void);
-static int truncate_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
-static void set_message (const char *, Lisp_Object, EMACS_INT, int);
-static int set_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static int truncate_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
+static void set_message (const char *, Lisp_Object, ptrdiff_t, int);
+static int set_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
 static int display_echo_area (struct window *);
-static int display_echo_area_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
-static int resize_mini_window_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static int display_echo_area_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
+static int resize_mini_window_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
 static Lisp_Object unwind_redisplay (Lisp_Object);
 static int string_char_and_length (const unsigned char *, int *);
 static struct text_pos display_prop_end (struct it *, Lisp_Object,
@@ -834,10 +834,10 @@ static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
 static void extend_face_to_end_of_line (struct it *);
 static int append_space_for_newline (struct it *, int);
 static int cursor_row_fully_visible_p (struct window *, int, int);
-static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
+static int try_scrolling (Lisp_Object, int, ptrdiff_t, ptrdiff_t, int, int);
 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
-static int trailing_whitespace_p (EMACS_INT);
-static intmax_t message_log_check_duplicate (EMACS_INT, EMACS_INT);
+static int trailing_whitespace_p (ptrdiff_t);
+static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
 static void push_it (struct it *, struct text_pos *);
 static void pop_it (struct it *);
 static void sync_frame_with_window_matrix_rows (struct window *);
@@ -850,7 +850,7 @@ static Lisp_Object redisplay_window_error (Lisp_Object);
 static Lisp_Object redisplay_window_0 (Lisp_Object);
 static Lisp_Object redisplay_window_1 (Lisp_Object);
 static int set_cursor_from_row (struct window *, struct glyph_row *,
-                               struct glyph_matrix *, EMACS_INT, EMACS_INT,
+                               struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
                                int, int);
 static int update_menu_bar (struct frame *, int, int);
 static int try_window_reusing_current_matrix (struct window *);
@@ -862,14 +862,14 @@ static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_O
 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
 static void display_menu_bar (struct window *);
-static EMACS_INT display_count_lines (EMACS_INT, EMACS_INT, EMACS_INT,
-                                     EMACS_INT *);
+static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
+                                     ptrdiff_t *);
 static int display_string (const char *, Lisp_Object, Lisp_Object,
-                           EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
+                           ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
 static void compute_line_metrics (struct it *);
 static void run_redisplay_end_trigger_hook (struct it *);
-static int get_overlay_strings (struct it *, EMACS_INT);
-static int get_overlay_strings_1 (struct it *, EMACS_INT, int);
+static int get_overlay_strings (struct it *, ptrdiff_t);
+static int get_overlay_strings_1 (struct it *, ptrdiff_t, int);
 static void next_overlay_string (struct it *);
 static void reseat (struct it *, struct text_pos, int);
 static void reseat_1 (struct it *, struct text_pos, int);
@@ -884,14 +884,14 @@ static int next_element_from_buffer (struct it *);
 static int next_element_from_composition (struct it *);
 static int next_element_from_image (struct it *);
 static int next_element_from_stretch (struct it *);
-static void load_overlay_strings (struct it *, EMACS_INT);
+static void load_overlay_strings (struct it *, ptrdiff_t);
 static int init_from_display_pos (struct it *, struct window *,
                                   struct display_pos *);
 static void reseat_to_string (struct it *, const char *,
-                              Lisp_Object, EMACS_INT, EMACS_INT, int, int);
+                              Lisp_Object, ptrdiff_t, ptrdiff_t, int, int);
 static int get_next_display_element (struct it *);
 static enum move_it_result
-       move_it_in_display_line_to (struct it *, EMACS_INT, int,
+       move_it_in_display_line_to (struct it *, ptrdiff_t, int,
                                   enum move_operation_enum);
 void move_it_vertically_backward (struct it *, int);
 static void init_to_row_start (struct it *, struct window *,
@@ -901,20 +901,20 @@ static int init_to_row_end (struct it *, struct window *,
 static void back_to_previous_line_start (struct it *);
 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
 static struct text_pos string_pos_nchars_ahead (struct text_pos,
-                                                Lisp_Object, EMACS_INT);
-static struct text_pos string_pos (EMACS_INT, Lisp_Object);
-static struct text_pos c_string_pos (EMACS_INT, const char *, int);
-static EMACS_INT number_of_chars (const char *, int);
+                                                Lisp_Object, ptrdiff_t);
+static struct text_pos string_pos (ptrdiff_t, Lisp_Object);
+static struct text_pos c_string_pos (ptrdiff_t, const char *, int);
+static ptrdiff_t number_of_chars (const char *, int);
 static void compute_stop_pos (struct it *);
 static void compute_string_pos (struct text_pos *, struct text_pos,
                                 Lisp_Object);
 static int face_before_or_after_it_pos (struct it *, int);
-static EMACS_INT next_overlay_change (EMACS_INT);
+static ptrdiff_t next_overlay_change (ptrdiff_t);
 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
-                               Lisp_Object, struct text_pos *, EMACS_INT, int);
+                               Lisp_Object, struct text_pos *, ptrdiff_t, int);
 static int handle_single_display_spec (struct it *, Lisp_Object,
                                        Lisp_Object, Lisp_Object,
-                                       struct text_pos *, EMACS_INT, int, int);
+                                       struct text_pos *, ptrdiff_t, int, int);
 static int underlying_face_id (struct it *);
 static int in_ellipses_for_invisible_text_p (struct display_pos *,
                                              struct window *);
@@ -1246,7 +1246,7 @@ string_from_display_spec (Lisp_Object spec)
    Set *ROWH and *VPOS to row's visible height and VPOS (row number).  */
 
 int
-pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
+pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
               int *rtop, int *rbot, int *rowh, int *vpos)
 {
   struct it it;
@@ -1550,7 +1550,7 @@ string_char_and_length (const unsigned char *str, int *len)
    in STRING, return the position NCHARS ahead (NCHARS >= 0).  */
 
 static struct text_pos
-string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, EMACS_INT nchars)
+string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
 {
   xassert (STRINGP (string) && nchars >= 0);
 
@@ -1578,7 +1578,7 @@ string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, EMACS_INT ncha
    for character position CHARPOS in STRING.  */
 
 static inline struct text_pos
-string_pos (EMACS_INT charpos, Lisp_Object string)
+string_pos (ptrdiff_t charpos, Lisp_Object string)
 {
   struct text_pos pos;
   xassert (STRINGP (string));
@@ -1593,7 +1593,7 @@ string_pos (EMACS_INT charpos, Lisp_Object string)
    means recognize multibyte characters.  */
 
 static struct text_pos
-c_string_pos (EMACS_INT charpos, const char *s, int multibyte_p)
+c_string_pos (ptrdiff_t charpos, const char *s, int multibyte_p)
 {
   struct text_pos pos;
 
@@ -1623,14 +1623,14 @@ c_string_pos (EMACS_INT charpos, const char *s, int multibyte_p)
 /* Value is the number of characters in C string S.  MULTIBYTE_P
    non-zero means recognize multibyte characters.  */
 
-static EMACS_INT
+static ptrdiff_t
 number_of_chars (const char *s, int multibyte_p)
 {
-  EMACS_INT nchars;
+  ptrdiff_t nchars;
 
   if (multibyte_p)
     {
-      EMACS_INT rest = strlen (s);
+      ptrdiff_t rest = strlen (s);
       int len;
       const unsigned char *p = (const unsigned char *) s;
 
@@ -2346,7 +2346,7 @@ safe_call (ptrdiff_t nargs, Lisp_Object *args)
     val = Qnil;
   else
     {
-      int count = SPECPDL_INDEX ();
+      ptrdiff_t count = SPECPDL_INDEX ();
       struct gcpro gcpro1;
 
       GCPRO1 (args[0]);
@@ -2496,7 +2496,7 @@ check_window_end (struct window *w)
 
 void
 init_iterator (struct it *it, struct window *w,
-              EMACS_INT charpos, EMACS_INT bytepos,
+              ptrdiff_t charpos, ptrdiff_t bytepos,
               struct glyph_row *row, enum face_id base_face_id)
 {
   int highlight_region_p;
@@ -2587,7 +2587,9 @@ init_iterator (struct it *it, struct window *w,
      is invisible.  >0 means lines indented more than this value are
      invisible.  */
   it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
-                  ? XINT (BVAR (current_buffer, selective_display))
+                  ? clip_to_bounds (-1, XINT (BVAR (current_buffer,
+                                                    selective_display)),
+                                    PTRDIFF_MAX)
                   : (!NILP (BVAR (current_buffer, selective_display))
                      ? -1 : 0));
   it->selective_display_ellipsis_p
@@ -2620,7 +2622,7 @@ init_iterator (struct it *it, struct window *w,
              && WINDOWP (minibuf_selected_window)
              && w == XWINDOW (minibuf_selected_window))))
     {
-      EMACS_INT markpos = marker_position (BVAR (current_buffer, mark));
+      ptrdiff_t markpos = marker_position (BVAR (current_buffer, mark));
       it->region_beg_charpos = min (PT, markpos);
       it->region_end_charpos = max (PT, markpos);
     }
@@ -2634,7 +2636,8 @@ init_iterator (struct it *it, struct window *w,
     it->redisplay_end_trigger_charpos
       = marker_position (w->redisplay_end_trigger);
   else if (INTEGERP (w->redisplay_end_trigger))
-    it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
+    it->redisplay_end_trigger_charpos =
+      clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger), PTRDIFF_MAX);
 
   it->tab_width = SANE_TAB_WIDTH (current_buffer);
 
@@ -2894,7 +2897,7 @@ in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
 {
   Lisp_Object prop, window;
   int ellipses_p = 0;
-  EMACS_INT charpos = CHARPOS (pos->pos);
+  ptrdiff_t charpos = CHARPOS (pos->pos);
 
   /* If POS specifies a position in a display vector, this might
      be for an ellipsis displayed for invisible text.  We won't
@@ -2926,7 +2929,7 @@ in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
 static int
 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
 {
-  EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
+  ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
   int i, overlay_strings_with_newlines = 0;
 
   /* If POS specifies a position in a display vector, this might
@@ -2986,7 +2989,7 @@ init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
         pos->overlay_string_index is in IT->overlay_strings.  */
       if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
        {
-         int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
+         ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
          it->current.overlay_string_index = 0;
          while (n--)
            {
@@ -3173,7 +3176,7 @@ compute_stop_pos (struct it *it)
 {
   register INTERVAL iv, next_iv;
   Lisp_Object object, limit, position;
-  EMACS_INT charpos, bytepos;
+  ptrdiff_t charpos, bytepos;
 
   if (STRINGP (it->string))
     {
@@ -3187,7 +3190,7 @@ compute_stop_pos (struct it *it)
     }
   else
     {
-      EMACS_INT pos;
+      ptrdiff_t pos;
 
       /* If end_charpos is out of range for some reason, such as a
         misbehaving display function, rationalize it (Bug#5984).  */
@@ -3269,7 +3272,7 @@ compute_stop_pos (struct it *it)
 
   if (it->cmp_it.id < 0)
     {
-      EMACS_INT stoppos = it->end_charpos;
+      ptrdiff_t stoppos = it->end_charpos;
 
       if (it->bidi_p && it->bidi_it.scan_dir < 0)
        stoppos = -1;
@@ -3288,11 +3291,11 @@ compute_stop_pos (struct it *it)
    follows.  This is like `next-overlay-change' but doesn't use
    xmalloc.  */
 
-static EMACS_INT
-next_overlay_change (EMACS_INT pos)
+static ptrdiff_t
+next_overlay_change (ptrdiff_t pos)
 {
   ptrdiff_t i, noverlays;
-  EMACS_INT endpos;
+  ptrdiff_t endpos;
   Lisp_Object *overlays;
 
   /* Get all overlays at the given position.  */
@@ -3303,7 +3306,7 @@ next_overlay_change (EMACS_INT pos)
   for (i = 0; i < noverlays; ++i)
     {
       Lisp_Object oend;
-      EMACS_INT oendpos;
+      ptrdiff_t oendpos;
 
       oend = OVERLAY_END (overlays[i]);
       oendpos = OVERLAY_POSITION (oend);
@@ -3330,7 +3333,7 @@ next_overlay_change (EMACS_INT pos)
    strings, non-zero otherwise.  It is set to 2 if the display string
    uses any kind of `(space ...)' spec that will produce a stretch of
    white space in the text area.  */
-EMACS_INT
+ptrdiff_t
 compute_display_string_pos (struct text_pos *position,
                            struct bidi_string_data *string,
                            int frame_window_p, int *disp_prop)
@@ -3340,10 +3343,10 @@ compute_display_string_pos (struct text_pos *position,
     (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
   Lisp_Object pos, spec, limpos;
   int string_p = (string && (STRINGP (string->lstring) || string->s));
-  EMACS_INT eob = string_p ? string->schars : ZV;
-  EMACS_INT begb = string_p ? 0 : BEGV;
-  EMACS_INT bufpos, charpos = CHARPOS (*position);
-  EMACS_INT lim =
+  ptrdiff_t eob = string_p ? string->schars : ZV;
+  ptrdiff_t begb = string_p ? 0 : BEGV;
+  ptrdiff_t bufpos, charpos = CHARPOS (*position);
+  ptrdiff_t lim =
     (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
   struct text_pos tpos;
   int rv = 0;
@@ -3414,14 +3417,14 @@ compute_display_string_pos (struct text_pos *position,
    return -1.  A display string is either an overlay with `display'
    property whose value is a string or a `display' text property whose
    value is a string.  */
-EMACS_INT
-compute_display_string_end (EMACS_INT charpos, struct bidi_string_data *string)
+ptrdiff_t
+compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
 {
   /* OBJECT = nil means current buffer.  */
   Lisp_Object object =
     (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
   Lisp_Object pos = make_number (charpos);
-  EMACS_INT eob =
+  ptrdiff_t eob =
     (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
 
   if (charpos >= eob || (string->s && !STRINGP (object)))
@@ -3484,7 +3487,7 @@ handle_fontified_prop (struct it *it)
             no amount of fontifying will be able to change it.  */
          NILP (prop) && IT_CHARPOS (*it) < Z))
     {
-      int count = SPECPDL_INDEX ();
+      ptrdiff_t count = SPECPDL_INDEX ();
       Lisp_Object val;
       struct buffer *obuf = current_buffer;
       int begv = BEGV, zv = ZV;
@@ -3581,7 +3584,7 @@ static enum prop_handled
 handle_face_prop (struct it *it)
 {
   int new_face_id;
-  EMACS_INT next_stop;
+  ptrdiff_t next_stop;
 
   if (!STRINGP (it->string))
     {
@@ -3622,7 +3625,7 @@ handle_face_prop (struct it *it)
   else
     {
       int base_face_id;
-      EMACS_INT bufpos;
+      ptrdiff_t bufpos;
       int i;
       Lisp_Object from_overlay
        = (it->current.overlay_string_index >= 0
@@ -3742,7 +3745,7 @@ static int
 face_before_or_after_it_pos (struct it *it, int before_p)
 {
   int face_id, limit;
-  EMACS_INT next_check_charpos;
+  ptrdiff_t next_check_charpos;
   struct it it_copy;
   void *it_copy_data = NULL;
 
@@ -3750,7 +3753,7 @@ face_before_or_after_it_pos (struct it *it, int before_p)
 
   if (STRINGP (it->string))
     {
-      EMACS_INT bufpos, charpos;
+      ptrdiff_t bufpos, charpos;
       int base_face_id;
 
       /* No face change past the end of the string (for the case
@@ -3963,7 +3966,7 @@ handle_invisible_prop (struct it *it)
       if (!NILP (prop)
          && IT_STRING_CHARPOS (*it) < it->end_charpos)
        {
-         EMACS_INT endpos;
+         ptrdiff_t endpos;
 
          handled = HANDLED_RECOMPUTE_PROPS;
 
@@ -3982,7 +3985,7 @@ handle_invisible_prop (struct it *it)
              && (endpos = XFASTINT (end_charpos)) < XFASTINT (limit))
            {
              struct text_pos old;
-             EMACS_INT oldpos;
+             ptrdiff_t oldpos;
 
              old = it->current.string_pos;
              oldpos = CHARPOS (old);
@@ -4034,7 +4037,7 @@ handle_invisible_prop (struct it *it)
   else
     {
       int invis_p;
-      EMACS_INT newpos, next_stop, start_charpos, tem;
+      ptrdiff_t newpos, next_stop, start_charpos, tem;
       Lisp_Object pos, prop, overlay;
 
       /* First of all, is there invisible text at this position?  */
@@ -4097,7 +4100,7 @@ handle_invisible_prop (struct it *it)
          /* The position newpos is now either ZV or on visible text.  */
          if (it->bidi_p)
            {
-             EMACS_INT bpos = CHAR_TO_BYTE (newpos);
+             ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
              int on_newline =
                bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
              int after_newline =
@@ -4273,7 +4276,7 @@ handle_display_prop (struct it *it)
 {
   Lisp_Object propval, object, overlay;
   struct text_pos *position;
-  EMACS_INT bufpos;
+  ptrdiff_t bufpos;
   /* Nonzero if some property replaces the display of the text itself.  */
   int display_replaced_p = 0;
 
@@ -4338,7 +4341,7 @@ handle_display_prop (struct it *it)
 static int
 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
                     Lisp_Object overlay, struct text_pos *position,
-                    EMACS_INT bufpos, int frame_window_p)
+                    ptrdiff_t bufpos, int frame_window_p)
 {
   int replacing_p = 0;
   int rv;
@@ -4374,7 +4377,7 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
     }
   else if (VECTORP (spec))
     {
-      int i;
+      ptrdiff_t i;
       for (i = 0; i < ASIZE (spec); ++i)
        if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
                                              overlay, position, bufpos,
@@ -4445,7 +4448,7 @@ display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
 static int
 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
                            Lisp_Object overlay, struct text_pos *position,
-                           EMACS_INT bufpos, int display_replaced_p,
+                           ptrdiff_t bufpos, int display_replaced_p,
                            int frame_window_p)
 {
   Lisp_Object form;
@@ -4467,7 +4470,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
 
   if (!NILP (form) && !EQ (form, Qt))
     {
-      int count = SPECPDL_INDEX ();
+      ptrdiff_t count = SPECPDL_INDEX ();
       struct gcpro gcpro1;
 
       /* Bind `object' to the object having the `display' property, a
@@ -4509,7 +4512,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
                  && (EQ (XCAR (it->font_height), Qplus)
                      || EQ (XCAR (it->font_height), Qminus))
                  && CONSP (XCDR (it->font_height))
-                 && INTEGERP (XCAR (XCDR (it->font_height))))
+                 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
                {
                  /* `(+ N)' or `(- N)' where N is an integer.  */
                  int steps = XINT (XCAR (XCDR (it->font_height)));
@@ -4541,7 +4544,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
                {
                  /* Evaluate IT->font_height with `height' bound to the
                     current specified height to get the new height.  */
-                 int count = SPECPDL_INDEX ();
+                 ptrdiff_t count = SPECPDL_INDEX ();
 
                  specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
                  value = safe_eval (it->font_height);
@@ -4870,7 +4873,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
 
 int
 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
-                          EMACS_INT charpos, EMACS_INT bytepos)
+                          ptrdiff_t charpos, ptrdiff_t bytepos)
 {
   int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
   struct text_pos position;
@@ -4951,7 +4954,7 @@ display_prop_string_p (Lisp_Object prop, Lisp_Object string)
   else if (VECTORP (prop))
     {
       /* A vector of sub-properties.  */
-      int i;
+      ptrdiff_t i;
       for (i = 0; i < ASIZE (prop); ++i)
        if (single_display_spec_string_p (AREF (prop, i), string))
          return 1;
@@ -4972,9 +4975,9 @@ display_prop_string_p (Lisp_Object prop, Lisp_Object string)
    This function may only use code that doesn't eval because it is
    called asynchronously from note_mouse_highlight.  */
 
-static EMACS_INT
+static ptrdiff_t
 string_buffer_position_lim (Lisp_Object string,
-                           EMACS_INT from, EMACS_INT to, int back_p)
+                           ptrdiff_t from, ptrdiff_t to, int back_p)
 {
   Lisp_Object limit, prop, pos;
   int found = 0;
@@ -5020,11 +5023,11 @@ string_buffer_position_lim (Lisp_Object string,
    This function may only use code that doesn't eval because it is
    called asynchronously from note_mouse_highlight.  */
 
-static EMACS_INT
-string_buffer_position (Lisp_Object string, EMACS_INT around_charpos)
+static ptrdiff_t
+string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
 {
   const int MAX_DISTANCE = 1000;
-  EMACS_INT found = string_buffer_position_lim (string, around_charpos,
+  ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
                                                around_charpos + MAX_DISTANCE,
                                                0);
 
@@ -5047,7 +5050,7 @@ static enum prop_handled
 handle_composition_prop (struct it *it)
 {
   Lisp_Object prop, string;
-  EMACS_INT pos, pos_byte, start, end;
+  ptrdiff_t pos, pos_byte, start, end;
 
   if (STRINGP (it->string))
     {
@@ -5113,7 +5116,7 @@ struct overlay_entry
 {
   Lisp_Object overlay;
   Lisp_Object string;
-  int priority;
+  EMACS_INT priority;
   int after_string_p;
 };
 
@@ -5245,12 +5248,17 @@ compare_overlay_entries (const void *e1, const void *e2)
       else
        result = entry1->after_string_p ? -1 : 1;
     }
-  else if (entry1->after_string_p)
-    /* After-strings sorted in order of decreasing priority.  */
-    result = entry2->priority - entry1->priority;
+  else if (entry1->priority != entry2->priority)
+    {
+      if (entry1->after_string_p)
+       /* After-strings sorted in order of decreasing priority.  */
+       result = entry2->priority < entry1->priority ? -1 : 1;
+      else
+       /* Before-strings sorted in order of increasing priority.  */
+       result = entry1->priority < entry2->priority ? -1 : 1;
+    }
   else
-    /* Before-strings sorted in order of increasing priority.  */
-    result = entry1->priority - entry2->priority;
+    result = 0;
 
   return result;
 }
@@ -5281,15 +5289,17 @@ compare_overlay_entries (const void *e1, const void *e2)
    compare_overlay_entries.  */
 
 static void
-load_overlay_strings (struct it *it, EMACS_INT charpos)
+load_overlay_strings (struct it *it, ptrdiff_t charpos)
 {
   Lisp_Object overlay, window, str, invisible;
   struct Lisp_Overlay *ov;
-  EMACS_INT start, end;
-  int size = 20;
-  int n = 0, i, j, invis_p;
+  ptrdiff_t start, end;
+  ptrdiff_t size = 20;
+  ptrdiff_t n = 0, i, j;
+  int invis_p;
   struct overlay_entry *entries
     = (struct overlay_entry *) alloca (size * sizeof *entries);
+  USE_SAFE_ALLOCA;
 
   if (charpos <= 0)
     charpos = IT_CHARPOS (*it);
@@ -5305,13 +5315,10 @@ load_overlay_strings (struct it *it, EMACS_INT charpos)
                                                                        \
       if (n == size)                                                   \
        {                                                               \
-         int new_size = 2 * size;                                      \
          struct overlay_entry *old = entries;                          \
-         entries =                                                     \
-            (struct overlay_entry *) alloca (new_size                  \
-                                            * sizeof *entries);        \
+         SAFE_NALLOCA (entries, 2, size);                              \
          memcpy (entries, old, size * sizeof *entries);                \
-         size = new_size;                                              \
+         size *= 2;                                                    \
        }                                                               \
                                                                        \
       entries[n].string = (STRING);                                    \
@@ -5424,6 +5431,7 @@ load_overlay_strings (struct it *it, EMACS_INT charpos)
     }
 
   CHECK_IT (it);
+  SAFE_FREE ();
 }
 
 
@@ -5432,7 +5440,7 @@ load_overlay_strings (struct it *it, EMACS_INT charpos)
    least one overlay string was found.  */
 
 static int
-get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p)
+get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
 {
   /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
      process.  This fills IT->overlay_strings with strings, and sets
@@ -5496,7 +5504,7 @@ get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p)
       /* Set up the bidi iterator for this overlay string.  */
       if (it->bidi_p)
        {
-         EMACS_INT pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
+         ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
 
          it->bidi_it.string.lstring = it->string;
          it->bidi_it.string.s = NULL;
@@ -5514,7 +5522,7 @@ get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p)
 }
 
 static int
-get_overlay_strings (struct it *it, EMACS_INT charpos)
+get_overlay_strings (struct it *it, ptrdiff_t charpos)
 {
   it->string = Qnil;
   it->method = GET_FROM_BUFFER;
@@ -5595,8 +5603,8 @@ static void
 iterate_out_of_display_property (struct it *it)
 {
   int buffer_p = BUFFERP (it->object);
-  EMACS_INT eob = (buffer_p ? ZV : it->end_charpos);
-  EMACS_INT bob = (buffer_p ? BEGV : 0);
+  ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
+  ptrdiff_t bob = (buffer_p ? BEGV : 0);
 
   xassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
 
@@ -5758,7 +5766,7 @@ static int
 forward_to_next_line_start (struct it *it, int *skipped_p,
                            struct bidi_it *bidi_it_prev)
 {
-  EMACS_INT old_selective;
+  ptrdiff_t old_selective;
   int newline_found_p, n;
   const int MAX_NEWLINE_DISTANCE = 500;
 
@@ -5800,8 +5808,8 @@ forward_to_next_line_start (struct it *it, int *skipped_p,
      short-cut.  */
   if (!newline_found_p)
     {
-      EMACS_INT start = IT_CHARPOS (*it);
-      EMACS_INT limit = find_next_newline_no_quit (start, 1);
+      ptrdiff_t start = IT_CHARPOS (*it);
+      ptrdiff_t limit = find_next_newline_no_quit (start, 1);
       Lisp_Object pos;
 
       xassert (!STRINGP (it->string));
@@ -5899,8 +5907,8 @@ back_to_previous_visible_line_start (struct it *it)
       {
        struct it it2;
        void *it2data = NULL;
-       EMACS_INT pos;
-       EMACS_INT beg, end;
+       ptrdiff_t pos;
+       ptrdiff_t beg, end;
        Lisp_Object val, overlay;
 
        SAVE_IT (it2, *it, it2data);
@@ -6053,7 +6061,7 @@ reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
 static void
 reseat (struct it *it, struct text_pos pos, int force_p)
 {
-  EMACS_INT original_pos = IT_CHARPOS (*it);
+  ptrdiff_t original_pos = IT_CHARPOS (*it);
 
   reseat_1 (it, pos, 0);
 
@@ -6163,7 +6171,7 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
 
 static void
 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
-                 EMACS_INT charpos, EMACS_INT precision, int field_width,
+                 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
                  int multibyte)
 {
   /* No region in strings.  */
@@ -6281,7 +6289,7 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string,
     }
   if (s == NULL && it->multibyte_p)
     {
-      EMACS_INT endpos = SCHARS (it->string);
+      ptrdiff_t endpos = SCHARS (it->string);
       if (endpos > it->end_charpos)
        endpos = it->end_charpos;
       composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
@@ -6389,11 +6397,11 @@ lookup_glyphless_char_display (int c, struct it *it)
    end of buffer (or C string) is reached.  */
 
 static struct frame *last_escape_glyph_frame = NULL;
-static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
+static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
 static int last_escape_glyph_merged_face_id = 0;
 
 struct frame *last_glyphless_glyph_frame = NULL;
-unsigned last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
+int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
 int last_glyphless_glyph_merged_face_id = 0;
 
 static int
@@ -6525,7 +6533,7 @@ get_next_display_element (struct it *it)
              Lisp_Object gc;
              int ctl_len;
              int face_id;
-             EMACS_INT lface_id = 0;
+             int lface_id = 0;
              int escape_glyph;
 
              /* Handle control characters with ^.  */
@@ -6537,8 +6545,7 @@ get_next_display_element (struct it *it)
                  g = '^';           /* default glyph for Control */
                  /* Set IT->ctl_chars[0] to the glyph for `^'.  */
                  if (it->dp
-                     && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
-                     && GLYPH_CODE_CHAR_VALID_P (gc))
+                     && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
                    {
                      g = GLYPH_CODE_CHAR (gc);
                      lface_id = GLYPH_CODE_FACE (gc);
@@ -6587,8 +6594,7 @@ get_next_display_element (struct it *it)
              escape_glyph = '\\';
 
              if (it->dp
-                 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
-                 && GLYPH_CODE_CHAR_VALID_P (gc))
+                 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
                {
                  escape_glyph = GLYPH_CODE_CHAR (gc);
                  lface_id = GLYPH_CODE_FACE (gc);
@@ -6687,7 +6693,7 @@ get_next_display_element (struct it *it)
        }
       else
        {
-         EMACS_INT pos = (it->s ? -1
+         ptrdiff_t pos = (it->s ? -1
                     : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
                     : IT_CHARPOS (*it));
          int c;
@@ -6739,7 +6745,7 @@ get_next_display_element (struct it *it)
                       && (it->current.overlay_string_index
                           == it->n_overlay_strings - 1))
                {
-                 EMACS_INT ignore;
+                 ptrdiff_t ignore;
                  int next_face_id;
                  struct text_pos pos = it->current.pos;
                  INC_TEXT_POS (pos, it->multibyte_p);
@@ -6841,7 +6847,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
                {
                  /* No more grapheme clusters in this composition.
                     Find the next stop position.  */
-                 EMACS_INT stop = it->end_charpos;
+                 ptrdiff_t stop = it->end_charpos;
                  if (it->bidi_it.scan_dir < 0)
                    /* Now we are scanning backward and don't know
                       where to stop.  */
@@ -6869,7 +6875,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
                {
                  /* No more grapheme clusters in this composition.
                     Find the next stop position.  */
-                 EMACS_INT stop = it->end_charpos;
+                 ptrdiff_t stop = it->end_charpos;
                  if (it->bidi_it.scan_dir < 0)
                    /* Now we are scanning backward and don't know
                       where to stop.  */
@@ -6902,7 +6908,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
                {
                  /* As the scan direction was changed, we must
                     re-compute the stop position for composition.  */
-                 EMACS_INT stop = it->end_charpos;
+                 ptrdiff_t stop = it->end_charpos;
                  if (it->bidi_it.scan_dir < 0)
                    stop = -1;
                  composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
@@ -7012,7 +7018,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
                it->cmp_it.from = it->cmp_it.to;
              else
                {
-                 EMACS_INT stop = it->end_charpos;
+                 ptrdiff_t stop = it->end_charpos;
                  if (it->bidi_it.scan_dir < 0)
                    stop = -1;
                  composition_compute_stop_pos (&it->cmp_it,
@@ -7031,7 +7037,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
                it->cmp_it.to = it->cmp_it.from;
              else
                {
-                 EMACS_INT stop = it->end_charpos;
+                 ptrdiff_t stop = it->end_charpos;
                  if (it->bidi_it.scan_dir < 0)
                    stop = -1;
                  composition_compute_stop_pos (&it->cmp_it,
@@ -7063,7 +7069,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
              IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
              if (prev_scan_dir != it->bidi_it.scan_dir)
                {
-                 EMACS_INT stop = it->end_charpos;
+                 ptrdiff_t stop = it->end_charpos;
 
                  if (it->bidi_it.scan_dir < 0)
                    stop = -1;
@@ -7149,7 +7155,7 @@ next_element_from_display_vector (struct it *it)
      That seemed totally bogus - so I changed it...  */
   gc = it->dpvec[it->current.dpvec_index];
 
-  if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
+  if (GLYPH_CODE_P (gc))
     {
       it->c = GLYPH_CODE_CHAR (gc);
       it->len = CHAR_BYTES (it->c);
@@ -7161,7 +7167,7 @@ next_element_from_display_vector (struct it *it)
        it->face_id = it->dpvec_face_id;
       else
        {
-         EMACS_INT lface_id = GLYPH_CODE_FACE (gc);
+         int lface_id = GLYPH_CODE_FACE (gc);
          if (lface_id > 0)
            it->face_id = merge_faces (it->f, Qt, lface_id,
                                       it->saved_face_id);
@@ -7184,8 +7190,8 @@ static void
 get_visually_first_element (struct it *it)
 {
   int string_p = STRINGP (it->string) || it->s;
-  EMACS_INT eob = (string_p ? it->bidi_it.string.schars : ZV);
-  EMACS_INT bob = (string_p ? 0 : BEGV);
+  ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
+  ptrdiff_t bob = (string_p ? 0 : BEGV);
 
   if (STRINGP (it->string))
     {
@@ -7217,7 +7223,7 @@ get_visually_first_element (struct it *it)
     }
   else
     {
-      EMACS_INT orig_bytepos = it->bidi_it.bytepos;
+      ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
 
       /* We need to prime the bidi iterator starting at the line's or
         string's beginning, before we will be able to produce the
@@ -7255,7 +7261,7 @@ get_visually_first_element (struct it *it)
 
   if (STRINGP (it->string) || !it->s)
     {
-      EMACS_INT stop, charpos, bytepos;
+      ptrdiff_t stop, charpos, bytepos;
 
       if (STRINGP (it->string))
        {
@@ -7556,10 +7562,10 @@ compute_stop_pos_backwards (struct it *it)
   struct text_pos pos;
   struct display_pos save_current = it->current;
   struct text_pos save_position = it->position;
-  EMACS_INT charpos = IT_CHARPOS (*it);
-  EMACS_INT where_we_are = charpos;
-  EMACS_INT save_stop_pos = it->stop_charpos;
-  EMACS_INT save_end_pos = it->end_charpos;
+  ptrdiff_t charpos = IT_CHARPOS (*it);
+  ptrdiff_t where_we_are = charpos;
+  ptrdiff_t save_stop_pos = it->stop_charpos;
+  ptrdiff_t save_end_pos = it->end_charpos;
 
   xassert (NILP (it->string) && !it->s);
   xassert (it->bidi_p);
@@ -7597,14 +7603,14 @@ compute_stop_pos_backwards (struct it *it)
    position.  */
 
 static void
-handle_stop_backwards (struct it *it, EMACS_INT charpos)
+handle_stop_backwards (struct it *it, ptrdiff_t charpos)
 {
   int bufp = !STRINGP (it->string);
-  EMACS_INT where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
+  ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
   struct display_pos save_current = it->current;
   struct text_pos save_position = it->position;
   struct text_pos pos1;
-  EMACS_INT next_stop;
+  ptrdiff_t next_stop;
 
   /* Scan in strict logical order.  */
   xassert (it->bidi_p);
@@ -7748,7 +7754,7 @@ next_element_from_buffer (struct it *it)
       /* No face changes, overlays etc. in sight, so just return a
         character from current_buffer.  */
       unsigned char *p;
-      EMACS_INT stop;
+      ptrdiff_t stop;
 
       /* Maybe run the redisplay end trigger hook.  Performance note:
         This doesn't seem to cost measurable time.  */
@@ -7937,7 +7943,7 @@ next_element_from_composition (struct it *it)
 
 static enum move_it_result
 move_it_in_display_line_to (struct it *it,
-                           EMACS_INT to_charpos, int to_x,
+                           ptrdiff_t to_charpos, int to_x,
                            enum move_operation_enum op)
 {
   enum move_it_result result = MOVE_UNDEFINED;
@@ -7947,7 +7953,7 @@ move_it_in_display_line_to (struct it *it,
   void *ppos_data = NULL;
   int may_wrap = 0;
   enum it_method prev_method = it->method;
-  EMACS_INT prev_pos = IT_CHARPOS (*it);
+  ptrdiff_t prev_pos = IT_CHARPOS (*it);
   int saw_smaller_pos = prev_pos < to_charpos;
 
   /* Don't produce glyphs in produce_glyphs.  */
@@ -8441,7 +8447,7 @@ move_it_in_display_line_to (struct it *it,
 /* For external use.  */
 void
 move_it_in_display_line (struct it *it,
-                        EMACS_INT to_charpos, int to_x,
+                        ptrdiff_t to_charpos, int to_x,
                         enum move_operation_enum op)
 {
   if (it->line_wrap == WORD_WRAP
@@ -8484,7 +8490,7 @@ move_it_in_display_line (struct it *it,
    displayed to the right of TO_CHARPOS on the screen.  */
 
 void
-move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos, int op)
+move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
 {
   enum move_it_result skip, skip2 = MOVE_X_REACHED;
   int line_height, line_start_x = 0, reached = 0;
@@ -8751,7 +8757,7 @@ move_it_vertically_backward (struct it *it, int dy)
   int nlines, h;
   struct it it2, it3;
   void *it2data = NULL, *it3data = NULL;
-  EMACS_INT start_pos;
+  ptrdiff_t start_pos;
 
  move_further_back:
   xassert (dy >= 0);
@@ -8833,7 +8839,7 @@ move_it_vertically_backward (struct it *it, int dy)
          && IT_CHARPOS (*it) > BEGV
          && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
        {
-         EMACS_INT nl_pos =
+         ptrdiff_t nl_pos =
            find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
 
          move_it_to (it, nl_pos, -1, -1, -1, MOVE_TO_POS);
@@ -8943,7 +8949,7 @@ move_it_past_eol (struct it *it)
    truncate-lines nil.  */
 
 void
-move_it_by_lines (struct it *it, int dvpos)
+move_it_by_lines (struct it *it, ptrdiff_t dvpos)
 {
 
   /* The commented-out optimization uses vmotion on terminals.  This
@@ -8992,7 +8998,7 @@ move_it_by_lines (struct it *it, int dvpos)
     {
       struct it it2;
       void *it2data = NULL;
-      EMACS_INT start_charpos, i;
+      ptrdiff_t start_charpos, i;
 
       /* Start at the beginning of the screen line containing IT's
         position.  This may actually move vertically backwards,
@@ -9078,7 +9084,7 @@ add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
   Lisp_Object args[3];
   Lisp_Object msg, fmt;
   char *buffer;
-  EMACS_INT len;
+  ptrdiff_t len;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   USE_SAFE_ALLOCA;
 
@@ -9127,7 +9133,7 @@ message_log_maybe_newline (void)
    so the buffer M must NOT point to a Lisp string.  */
 
 void
-message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
+message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte)
 {
   const unsigned char *msg = (const unsigned char *) m;
 
@@ -9139,8 +9145,8 @@ message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
       struct buffer *oldbuf;
       Lisp_Object oldpoint, oldbegv, oldzv;
       int old_windows_or_buffers_changed = windows_or_buffers_changed;
-      EMACS_INT point_at_end = 0;
-      EMACS_INT zv_at_end = 0;
+      ptrdiff_t point_at_end = 0;
+      ptrdiff_t zv_at_end = 0;
       Lisp_Object old_deactivate_mark, tem;
       struct gcpro gcpro1;
 
@@ -9173,7 +9179,7 @@ message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
       if (multibyte
          && NILP (BVAR (current_buffer, enable_multibyte_characters)))
        {
-         EMACS_INT i;
+         ptrdiff_t i;
          int c, char_bytes;
          char work[1];
 
@@ -9191,7 +9197,7 @@ message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
       else if (! multibyte
               && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
        {
-         EMACS_INT i;
+         ptrdiff_t i;
          int c, char_bytes;
          unsigned char str[MAX_MULTIBYTE_LENGTH];
          /* Convert a single-byte string to multibyte
@@ -9209,7 +9215,7 @@ message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
 
       if (nlflag)
        {
-         EMACS_INT this_bol, this_bol_byte, prev_bol, prev_bol_byte;
+         ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
          printmax_t dups;
          insert_1 ("\n", 1, 1, 0, 0);
 
@@ -9302,10 +9308,10 @@ message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
    value N > 1 if we should also append " [N times]".  */
 
 static intmax_t
-message_log_check_duplicate (EMACS_INT prev_bol_byte, EMACS_INT this_bol_byte)
+message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
 {
-  EMACS_INT i;
-  EMACS_INT len = Z_BYTE - 1 - this_bol_byte;
+  ptrdiff_t i;
+  ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
   int seen_dots = 0;
   unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
   unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
@@ -9339,7 +9345,7 @@ message_log_check_duplicate (EMACS_INT prev_bol_byte, EMACS_INT this_bol_byte)
    This may GC, so the buffer M must NOT point to a Lisp string.  */
 
 void
-message2 (const char *m, EMACS_INT nbytes, int multibyte)
+message2 (const char *m, ptrdiff_t nbytes, int multibyte)
 {
   /* First flush out any partial line written with print.  */
   message_log_maybe_newline ();
@@ -9352,7 +9358,7 @@ message2 (const char *m, EMACS_INT nbytes, int multibyte)
 /* The non-logging counterpart of message2.  */
 
 void
-message2_nolog (const char *m, EMACS_INT nbytes, int multibyte)
+message2_nolog (const char *m, ptrdiff_t nbytes, int multibyte)
 {
   struct frame *sf = SELECTED_FRAME ();
   message_enable_multibyte = multibyte;
@@ -9414,7 +9420,7 @@ message2_nolog (const char *m, EMACS_INT nbytes, int multibyte)
    This function cancels echoing.  */
 
 void
-message3 (Lisp_Object m, EMACS_INT nbytes, int multibyte)
+message3 (Lisp_Object m, ptrdiff_t nbytes, int multibyte)
 {
   struct gcpro gcpro1;
 
@@ -9446,7 +9452,7 @@ message3 (Lisp_Object m, EMACS_INT nbytes, int multibyte)
    and make this cancel echoing.  */
 
 void
-message3_nolog (Lisp_Object m, EMACS_INT nbytes, int multibyte)
+message3_nolog (Lisp_Object m, ptrdiff_t nbytes, int multibyte)
 {
   struct frame *sf = SELECTED_FRAME ();
   message_enable_multibyte = multibyte;
@@ -9743,12 +9749,12 @@ ensure_echo_area_buffers (void)
 
 static int
 with_echo_area_buffer (struct window *w, int which,
-                      int (*fn) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
-                      EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
+                      int (*fn) (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t),
+                      ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
 {
   Lisp_Object buffer;
   int this_one, the_other, clear_buffer_p, rc;
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
 
   /* If buffers aren't live, make new ones.  */
   ensure_echo_area_buffers ();
@@ -9924,7 +9930,7 @@ setup_echo_area_for_printing (int multibyte_p)
 
       if (Z > BEG)
        {
-         int count = SPECPDL_INDEX ();
+         ptrdiff_t count = SPECPDL_INDEX ();
          specbind (Qinhibit_read_only, Qt);
          /* Note that undo recording is always disabled.  */
          del_range (BEG, Z);
@@ -9977,14 +9983,14 @@ setup_echo_area_for_printing (int multibyte_p)
 static int
 display_echo_area (struct window *w)
 {
-  int i, no_message_p, window_height_changed_p, count;
+  int i, no_message_p, window_height_changed_p;
 
   /* Temporarily disable garbage collections while displaying the echo
      area.  This is done because a GC can print a message itself.
      That message would modify the echo area buffer's contents while a
      redisplay of the buffer is going on, and seriously confuse
      redisplay.  */
-  count = inhibit_garbage_collection ();
+  ptrdiff_t count = inhibit_garbage_collection ();
 
   /* If there is no message, we must call display_echo_area_1
      nevertheless because it resizes the window.  But we will have to
@@ -10013,7 +10019,7 @@ display_echo_area (struct window *w)
    Value is non-zero if height of W was changed.  */
 
 static int
-display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
+display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
 {
   intptr_t i1 = a1;
   struct window *w = (struct window *) i1;
@@ -10077,7 +10083,7 @@ resize_echo_area_exactly (void)
    resize_mini_window returns.  */
 
 static int
-resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
+resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly, ptrdiff_t a3, ptrdiff_t a4)
 {
   intptr_t i1 = a1;
   return resize_mini_window ((struct window *) i1, !NILP (exactly));
@@ -10127,7 +10133,8 @@ resize_mini_window (struct window *w, int exact_p)
       struct it it;
       struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
       int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
-      int height, max_height;
+      int height;
+      EMACS_INT max_height;
       int unit = FRAME_LINE_HEIGHT (f);
       struct text_pos start;
       struct buffer *old_current_buffer = NULL;
@@ -10256,7 +10263,7 @@ current_message (void)
 
 
 static int
-current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
+current_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
 {
   intptr_t i1 = a1;
   Lisp_Object *msg = (Lisp_Object *) i1;
@@ -10335,7 +10342,7 @@ check_message_stack (void)
    time we display it---but don't redisplay it now.  */
 
 void
-truncate_echo_area (EMACS_INT nchars)
+truncate_echo_area (ptrdiff_t nchars)
 {
   if (nchars == 0)
     echo_area_buffer[0] = Qnil;
@@ -10357,7 +10364,7 @@ truncate_echo_area (EMACS_INT nchars)
    message to at most NCHARS characters.  */
 
 static int
-truncate_message_1 (EMACS_INT nchars, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
+truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
 {
   if (BEG + nchars < Z)
     del_range (BEG + nchars, Z);
@@ -10383,7 +10390,7 @@ truncate_message_1 (EMACS_INT nchars, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4
 
 static void
 set_message (const char *s, Lisp_Object string,
-            EMACS_INT nbytes, int multibyte_p)
+            ptrdiff_t nbytes, int multibyte_p)
 {
   message_enable_multibyte
     = ((s && multibyte_p)
@@ -10402,7 +10409,7 @@ set_message (const char *s, Lisp_Object string,
    current.  */
 
 static int
-set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
+set_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t nbytes, ptrdiff_t multibyte_p)
 {
   intptr_t i1 = a1;
   const char *s = (const char *) i1;
@@ -10423,7 +10430,7 @@ set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multiby
 
   if (STRINGP (string))
     {
-      EMACS_INT nchars;
+      ptrdiff_t nchars;
 
       if (nbytes == 0)
        nbytes = SBYTES (string);
@@ -10442,7 +10449,7 @@ set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multiby
       if (multibyte_p && NILP (BVAR (current_buffer, enable_multibyte_characters)))
        {
          /* Convert from multi-byte to single-byte.  */
-         EMACS_INT i;
+         ptrdiff_t i;
          int c, n;
          char work[1];
 
@@ -10460,7 +10467,7 @@ set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multiby
               && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
        {
          /* Convert from single-byte to multi-byte.  */
-         EMACS_INT i;
+         ptrdiff_t i;
          int c, n;
          unsigned char str[MAX_MULTIBYTE_LENGTH];
 
@@ -10605,7 +10612,7 @@ echo_area_display (int update_frame_p)
              /* Must update other windows.  Likewise as in other
                 cases, don't let this update be interrupted by
                 pending input.  */
-             int count = SPECPDL_INDEX ();
+             ptrdiff_t count = SPECPDL_INDEX ();
              specbind (Qredisplay_dont_pause, Qt);
              windows_or_buffers_changed = 1;
              redisplay_internal ();
@@ -10782,7 +10789,7 @@ store_mode_line_noprop (const char *string, int field_width, int precision)
 {
   const unsigned char *str = (const unsigned char *) string;
   int n = 0;
-  EMACS_INT dummy, nbytes;
+  ptrdiff_t dummy, nbytes;
 
   /* Copy at most PRECISION chars from STR.  */
   nbytes = strlen (string);
@@ -10827,7 +10834,7 @@ x_consider_frame_title (Lisp_Object frame)
       char *title;
       ptrdiff_t len;
       struct it it;
-      int count = SPECPDL_INDEX ();
+      ptrdiff_t count = SPECPDL_INDEX ();
 
       for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
        {
@@ -10930,7 +10937,7 @@ prepare_menu_bars (void)
   if (all_windows)
     {
       Lisp_Object tail, frame;
-      int count = SPECPDL_INDEX ();
+      ptrdiff_t count = SPECPDL_INDEX ();
       /* 1 means that update_menu_bar has run its hooks
         so any further calls to update_menu_bar shouldn't do so again.  */
       int menu_bar_hooks_run = 0;
@@ -11047,7 +11054,7 @@ update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
              != !NILP (w->region_showing)))
        {
          struct buffer *prev = current_buffer;
-         int count = SPECPDL_INDEX ();
+         ptrdiff_t count = SPECPDL_INDEX ();
 
          specbind (Qinhibit_menubar_update, Qt);
 
@@ -11245,7 +11252,7 @@ update_tool_bar (struct frame *f, int save_match_data)
              != !NILP (w->region_showing)))
        {
          struct buffer *prev = current_buffer;
-         int count = SPECPDL_INDEX ();
+         ptrdiff_t count = SPECPDL_INDEX ();
          Lisp_Object frame, new_tool_bar;
           int new_n_tool_bar;
          struct gcpro gcpro1;
@@ -11383,20 +11390,20 @@ build_desired_tool_bar_string (struct frame *f)
                : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
       hmargin = vmargin = relief;
 
-      if (INTEGERP (Vtool_bar_button_margin)
-         && XINT (Vtool_bar_button_margin) > 0)
+      if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
+                          INT_MAX - max (hmargin, vmargin)))
        {
          hmargin += XFASTINT (Vtool_bar_button_margin);
          vmargin += XFASTINT (Vtool_bar_button_margin);
        }
       else if (CONSP (Vtool_bar_button_margin))
        {
-         if (INTEGERP (XCAR (Vtool_bar_button_margin))
-             && XINT (XCAR (Vtool_bar_button_margin)) > 0)
+         if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
+                              INT_MAX - hmargin))
            hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
 
-         if (INTEGERP (XCDR (Vtool_bar_button_margin))
-             && XINT (XCDR (Vtool_bar_button_margin)) > 0)
+         if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
+                              INT_MAX - vmargin))
            vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
        }
 
@@ -11742,7 +11749,7 @@ redisplay_tool_bar (struct frame *f)
     {
       int border, rows, height, extra;
 
-      if (INTEGERP (Vtool_bar_border))
+      if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
        border = XINT (Vtool_bar_border);
       else if (EQ (Vtool_bar_border, Qinternal_border_width))
        border = FRAME_INTERNAL_BORDER_WIDTH (f);
@@ -11930,7 +11937,7 @@ get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
 
 void
 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
-                      unsigned int modifiers)
+                      int modifiers)
 {
   Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
   struct window *w = XWINDOW (f->tool_bar_window);
@@ -12109,7 +12116,7 @@ hscroll_window_tree (Lisp_Object window)
          hscroll_step_abs = 0;
        }
     }
-  else if (INTEGERP (Vhscroll_step))
+  else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
     {
       hscroll_step_abs = XINT (Vhscroll_step);
       if (hscroll_step_abs < 0)
@@ -12173,9 +12180,9 @@ hscroll_window_tree (Lisp_Object window)
                              && (w->cursor.x >= text_area_width - h_margin))))))
            {
              struct it it;
-             int hscroll;
+             ptrdiff_t hscroll;
              struct buffer *saved_current_buffer;
-             EMACS_INT pt;
+             ptrdiff_t pt;
              int wanted_x;
 
              /* Find point in a display of infinite width.  */
@@ -12290,12 +12297,12 @@ static int debug_dvpos, debug_dy;
 
 /* Delta in characters and bytes for try_window_id.  */
 
-static EMACS_INT debug_delta, debug_delta_bytes;
+static ptrdiff_t debug_delta, debug_delta_bytes;
 
 /* Values of window_end_pos and window_end_vpos at the end of
    try_window_id.  */
 
-static EMACS_INT debug_end_vpos;
+static ptrdiff_t debug_end_vpos;
 
 /* Append a string to W->desired_matrix->method.  FMT is a printf
    format string.  If trace_redisplay_p is non-zero also printf the
@@ -12345,7 +12352,7 @@ debug_method_add (struct window *w, char const *fmt, ...)
 
 static inline int
 text_outside_line_unchanged_p (struct window *w,
-                              EMACS_INT start, EMACS_INT end)
+                              ptrdiff_t start, ptrdiff_t end)
 {
   int unchanged_p = 1;
 
@@ -12568,10 +12575,10 @@ overlay_arrow_at_row (struct it *it, struct glyph_row *row)
    position.  BUF and PT are the current point buffer and position.  */
 
 static int
-check_point_in_composition (struct buffer *prev_buf, EMACS_INT prev_pt,
-                           struct buffer *buf, EMACS_INT pt)
+check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
+                           struct buffer *buf, ptrdiff_t pt)
 {
-  EMACS_INT start, end;
+  ptrdiff_t start, end;
   Lisp_Object prop;
   Lisp_Object buffer;
 
@@ -12622,7 +12629,7 @@ reconsider_clip_changes (struct window *w, struct buffer *b)
   if (!b->clip_changed
       && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
     {
-      EMACS_INT pt;
+      ptrdiff_t pt;
 
       if (w == XWINDOW (selected_window))
        pt = PT;
@@ -12691,7 +12698,7 @@ redisplay_internal (void)
   int must_finish = 0;
   struct text_pos tlbufpos, tlendpos;
   int number_of_visible_frames;
-  int count, count1;
+  ptrdiff_t count, count1;
   struct frame *sf;
   int polling_stopped_here = 0;
   Lisp_Object old_frame = selected_frame;
@@ -13034,7 +13041,7 @@ redisplay_internal (void)
                {
                  struct glyph_row *row
                    = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
-                 EMACS_INT delta, delta_bytes;
+                 ptrdiff_t delta, delta_bytes;
 
                  /* We used to distinguish between two cases here,
                     conditioned by Z - CHARPOS (tlendpos) == ZV, for
@@ -13657,18 +13664,18 @@ redisplay_window_1 (Lisp_Object window)
 static int
 set_cursor_from_row (struct window *w, struct glyph_row *row,
                     struct glyph_matrix *matrix,
-                    EMACS_INT delta, EMACS_INT delta_bytes,
+                    ptrdiff_t delta, ptrdiff_t delta_bytes,
                     int dy, int dvpos)
 {
   struct glyph *glyph = row->glyphs[TEXT_AREA];
   struct glyph *end = glyph + row->used[TEXT_AREA];
   struct glyph *cursor = NULL;
   /* The last known character position in row.  */
-  EMACS_INT last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
+  ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
   int x = row->x;
-  EMACS_INT pt_old = PT - delta;
-  EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
-  EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
+  ptrdiff_t pt_old = PT - delta;
+  ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
+  ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
   struct glyph *glyph_before = glyph - 1, *glyph_after = end;
   /* A glyph beyond the edge of TEXT_AREA which we should never
      touch.  */
@@ -13681,11 +13688,11 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
   int string_seen = 0;
   /* Largest and smallest buffer positions seen so far during scan of
      glyph row.  */
-  EMACS_INT bpos_max = pos_before;
-  EMACS_INT bpos_min = pos_after;
+  ptrdiff_t bpos_max = pos_before;
+  ptrdiff_t bpos_min = pos_after;
   /* Last buffer position covered by an overlay string with an integer
      `cursor' property.  */
-  EMACS_INT bpos_covered = 0;
+  ptrdiff_t bpos_covered = 0;
   /* Non-zero means the display string on which to display the cursor
      comes from a text property, not from an overlay.  */
   int string_from_text_prop = 0;
@@ -13771,7 +13778,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
       {
        if (BUFFERP (glyph->object))
          {
-           EMACS_INT dpos = glyph->charpos - pt_old;
+           ptrdiff_t dpos = glyph->charpos - pt_old;
 
            if (glyph->charpos > bpos_max)
              bpos_max = glyph->charpos;
@@ -13808,7 +13815,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
        else if (STRINGP (glyph->object))
          {
            Lisp_Object chprop;
-           EMACS_INT glyph_pos = glyph->charpos;
+           ptrdiff_t glyph_pos = glyph->charpos;
 
            chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
                                         glyph->object);
@@ -13824,7 +13831,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
                   text is completely covered by display properties,
                   so that no glyph with valid buffer positions is
                   ever seen in the row.  */
-               EMACS_INT prop_pos =
+               ptrdiff_t prop_pos =
                  string_buffer_position_lim (glyph->object, pos_before,
                                              pos_after, 0);
 
@@ -13862,7 +13869,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
       {
        if (BUFFERP (glyph->object))
          {
-           EMACS_INT dpos = glyph->charpos - pt_old;
+           ptrdiff_t dpos = glyph->charpos - pt_old;
 
            if (glyph->charpos > bpos_max)
              bpos_max = glyph->charpos;
@@ -13892,13 +13899,13 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
        else if (STRINGP (glyph->object))
          {
            Lisp_Object chprop;
-           EMACS_INT glyph_pos = glyph->charpos;
+           ptrdiff_t glyph_pos = glyph->charpos;
 
            chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
                                         glyph->object);
            if (!NILP (chprop))
              {
-               EMACS_INT prop_pos =
+               ptrdiff_t prop_pos =
                  string_buffer_position_lim (glyph->object, pos_before,
                                              pos_after, 0);
 
@@ -13946,7 +13953,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
 
       if (row->ends_in_ellipsis_p && pos_after == last_pos)
        {
-         EMACS_INT ellipsis_pos;
+         ptrdiff_t ellipsis_pos;
 
          /* Scan back over the ellipsis glyphs.  */
          if (!row->reversed_p)
@@ -13986,7 +13993,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
             positioned between POS_BEFORE and POS_AFTER in the
             buffer.  */
          struct glyph *start, *stop;
-         EMACS_INT pos = pos_before;
+         ptrdiff_t pos = pos_before;
 
          x = -1;
 
@@ -14029,10 +14036,10 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
              if (STRINGP (glyph->object))
                {
                  Lisp_Object str;
-                 EMACS_INT tem;
+                 ptrdiff_t tem;
                  /* If the display property covers the newline, we
                     need to search for it one position farther.  */
-                 EMACS_INT lim = pos_after
+                 ptrdiff_t lim = pos_after
                    + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
 
                  string_from_text_prop = 0;
@@ -14061,7 +14068,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
                             be a character in the string with the
                             `cursor' property, which means display
                             cursor on that character's glyph.  */
-                         EMACS_INT strpos = glyph->charpos;
+                         ptrdiff_t strpos = glyph->charpos;
 
                          if (tem)
                            {
@@ -14074,7 +14081,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
                               glyph += incr)
                            {
                              Lisp_Object cprop;
-                             EMACS_INT gpos = glyph->charpos;
+                             ptrdiff_t gpos = glyph->charpos;
 
                              cprop = Fget_char_property (make_number (gpos),
                                                          Qcursor,
@@ -14365,7 +14372,7 @@ enum
 
 static int
 try_scrolling (Lisp_Object window, int just_this_one_p,
-              EMACS_INT arg_scroll_conservatively, EMACS_INT scroll_step,
+              ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
               int temp_scroll_step, int last_line_misfit)
 {
   struct window *w = XWINDOW (window);
@@ -14999,7 +15006,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
                        MATRIX_ROW (w->current_matrix, w->cursor.vpos);
                      struct glyph *g =
                        candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
-                     EMACS_INT endpos = MATRIX_ROW_END_CHARPOS (candidate);
+                     ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
 
                      exact_match_p =
                        (BUFFERP (g->object) && g->charpos == PT)
@@ -15059,7 +15066,7 @@ static
 void
 set_vertical_scroll_bar (struct window *w)
 {
-  EMACS_INT start, end, whole;
+  ptrdiff_t start, end, whole;
 
   /* Calculate the start and end positions for the current window.
      At some point, it would be nice to choose between scrollbars
@@ -15119,11 +15126,11 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
      It indicates that the buffer contents and narrowing are unchanged.  */
   int buffer_unchanged_p = 0;
   int temp_scroll_step = 0;
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
   int rc;
   int centering_position = -1;
   int last_line_misfit = 0;
-  EMACS_INT beg_unchanged, end_unchanged;
+  ptrdiff_t beg_unchanged, end_unchanged;
 
   SET_TEXT_POS (lpoint, PT, PT_BYTE);
   opoint = lpoint;
@@ -15264,8 +15271,8 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
      window, set up appropriate value.  */
   if (!EQ (window, selected_window))
     {
-      EMACS_INT new_pt = XMARKER (w->pointm)->charpos;
-      EMACS_INT new_pt_byte = marker_byte_position (w->pointm);
+      ptrdiff_t new_pt = XMARKER (w->pointm)->charpos;
+      ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
       if (new_pt < BEGV)
        {
          new_pt = BEGV;
@@ -15637,7 +15644,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
        scroll_margin > 0
        ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
        : 0;
-      EMACS_INT margin_pos = CHARPOS (startp);
+      ptrdiff_t margin_pos = CHARPOS (startp);
       Lisp_Object aggressive;
       int scrolling_up;
 
@@ -16536,7 +16543,7 @@ try_window_reusing_current_matrix (struct window *w)
 
 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
-                                                          EMACS_INT *, EMACS_INT *);
+                                                          ptrdiff_t *, ptrdiff_t *);
 static struct glyph_row *
 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
                                struct glyph_row *);
@@ -16584,7 +16591,7 @@ find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
 static struct glyph_row *
 find_last_unchanged_at_beg_row (struct window *w)
 {
-  EMACS_INT first_changed_pos = BEG + BEG_UNCHANGED;
+  ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
   struct glyph_row *row;
   struct glyph_row *row_found = NULL;
   int yb = window_text_bottom_y (w);
@@ -16632,7 +16639,7 @@ find_last_unchanged_at_beg_row (struct window *w)
 
 static struct glyph_row *
 find_first_unchanged_at_end_row (struct window *w,
-                                EMACS_INT *delta, EMACS_INT *delta_bytes)
+                                ptrdiff_t *delta, ptrdiff_t *delta_bytes)
 {
   struct glyph_row *row;
   struct glyph_row *row_found = NULL;
@@ -16660,11 +16667,11 @@ find_first_unchanged_at_end_row (struct window *w,
         corresponds to window_end_pos.  This allows us to translate
         buffer positions in the current matrix to current buffer
         positions for characters not in changed text.  */
-      EMACS_INT Z_old =
+      ptrdiff_t Z_old =
        MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
-      EMACS_INT Z_BYTE_old =
+      ptrdiff_t Z_BYTE_old =
        MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
-      EMACS_INT last_unchanged_pos, last_unchanged_pos_old;
+      ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
       struct glyph_row *first_text_row
        = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
 
@@ -16751,12 +16758,12 @@ sync_frame_with_window_matrix_rows (struct window *w)
    containing CHARPOS or null.  */
 
 struct glyph_row *
-row_containing_pos (struct window *w, EMACS_INT charpos,
+row_containing_pos (struct window *w, ptrdiff_t charpos,
                    struct glyph_row *start, struct glyph_row *end, int dy)
 {
   struct glyph_row *row = start;
   struct glyph_row *best_row = NULL;
-  EMACS_INT mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
+  ptrdiff_t mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
   int last_y;
 
   /* If we happen to start on a header-line, skip that.  */
@@ -16870,14 +16877,14 @@ try_window_id (struct window *w)
   struct glyph_row *bottom_row;
   int bottom_vpos;
   struct it it;
-  EMACS_INT delta = 0, delta_bytes = 0, stop_pos;
+  ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
   int dvpos, dy;
   struct text_pos start_pos;
   struct run run;
   int first_unchanged_at_end_vpos = 0;
   struct glyph_row *last_text_row, *last_text_row_at_end;
   struct text_pos start;
-  EMACS_INT first_changed_charpos, last_changed_charpos;
+  ptrdiff_t first_changed_charpos, last_changed_charpos;
 
 #if GLYPH_DEBUG
   if (inhibit_try_window_id)
@@ -17004,7 +17011,7 @@ try_window_id (struct window *w)
          || (last_changed_charpos < CHARPOS (start) - 1
              && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
     {
-      EMACS_INT Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
+      ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
       struct glyph_row *r0;
 
       /* Compute how many chars/bytes have been added to or removed
@@ -17748,7 +17755,7 @@ dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
               row->visible_height,
               row->ascent,
               row->phys_ascent);
-      fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
+      fprintf (stderr, "%9"pD"d %5"pD"d\t%5d\n", row->start.overlay_string_index,
               row->end.overlay_string_index,
               row->continuation_lines_width);
       fprintf (stderr, "%9"pI"d %5"pI"d\n",
@@ -17822,7 +17829,7 @@ glyphs in short form, otherwise show glyphs in long form.  */)
           w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
   fprintf (stderr, "=============================================\n");
   dump_glyph_matrix (w->current_matrix,
-                    NILP (glyphs) ? 0 : XINT (glyphs));
+                    TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
   return Qnil;
 }
 
@@ -17845,7 +17852,7 @@ GLYPH > 1 or omitted means dump glyphs in long form.  */)
   (Lisp_Object row, Lisp_Object glyphs)
 {
   struct glyph_matrix *matrix;
-  int vpos;
+  EMACS_INT vpos;
 
   CHECK_NUMBER (row);
   matrix = XWINDOW (selected_window)->current_matrix;
@@ -17853,7 +17860,7 @@ GLYPH > 1 or omitted means dump glyphs in long form.  */)
   if (vpos >= 0 && vpos < matrix->nrows)
     dump_glyph_row (MATRIX_ROW (matrix, vpos),
                    vpos,
-                   INTEGERP (glyphs) ? XINT (glyphs) : 2);
+                   TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
   return Qnil;
 }
 
@@ -17867,13 +17874,13 @@ GLYPH > 1 or omitted means dump glyphs in long form.  */)
 {
   struct frame *sf = SELECTED_FRAME ();
   struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
-  int vpos;
+  EMACS_INT vpos;
 
   CHECK_NUMBER (row);
   vpos = XINT (row);
   if (vpos >= 0 && vpos < m->nrows)
     dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
-                   INTEGERP (glyphs) ? XINT (glyphs) : 2);
+                   TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
   return Qnil;
 }
 
@@ -18398,9 +18405,9 @@ extend_face_to_end_of_line (struct it *it)
    trailing whitespace.  */
 
 static int
-trailing_whitespace_p (EMACS_INT charpos)
+trailing_whitespace_p (ptrdiff_t charpos)
 {
-  EMACS_INT bytepos = CHAR_TO_BYTE (charpos);
+  ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
   int c = 0;
 
   while (bytepos < ZV_BYTE
@@ -18542,7 +18549,7 @@ cursor_row_p (struct glyph_row *row)
 
                        for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
                          {
-                           EMACS_INT gpos = glyph->charpos;
+                           ptrdiff_t gpos = glyph->charpos;
 
                            if (!NILP (Fget_char_property (make_number (gpos),
                                                           Qcursor, s)))
@@ -18739,8 +18746,8 @@ unproduce_glyphs (struct it *it, int n)
    and ROW->maxpos.  */
 static void
 find_row_edges (struct it *it, struct glyph_row *row,
-               EMACS_INT min_pos, EMACS_INT min_bpos,
-               EMACS_INT max_pos, EMACS_INT max_bpos)
+               ptrdiff_t min_pos, ptrdiff_t min_bpos,
+               ptrdiff_t max_pos, ptrdiff_t max_bpos)
 {
   /* FIXME: Revisit this when glyph ``spilling'' in continuation
      lines' rows is implemented for bidi-reordered rows.  */
@@ -18907,11 +18914,11 @@ display_line (struct it *it)
   int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
   int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
   int wrap_row_extra_line_spacing IF_LINT (= 0);
-  EMACS_INT wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
-  EMACS_INT wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
+  ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
+  ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
   int cvpos;
-  EMACS_INT min_pos = ZV + 1, max_pos = 0;
-  EMACS_INT min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
+  ptrdiff_t min_pos = ZV + 1, max_pos = 0;
+  ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
 
   /* We always start displaying at hpos zero even if hscrolled.  */
   xassert (it->hpos == 0 && it->current_x == 0);
@@ -18984,10 +18991,10 @@ display_line (struct it *it)
     {                                                          \
       int composition_p = !STRINGP ((IT)->string)              \
        && ((IT)->what == IT_COMPOSITION);                      \
-      EMACS_INT current_pos =                                  \
+      ptrdiff_t current_pos =                                  \
        composition_p ? (IT)->cmp_it.charpos                    \
                      : IT_CHARPOS (*(IT));                     \
-      EMACS_INT current_bpos =                                 \
+      ptrdiff_t current_bpos =                                 \
        composition_p ? CHAR_TO_BYTE (current_pos)              \
                      : IT_BYTEPOS (*(IT));                     \
       if (current_pos < min_pos)                               \
@@ -19635,8 +19642,8 @@ See also `bidi-paragraph-direction'.  */)
         use current_matrix if it is up to date, but this seems fast
         enough as it is.  */
       struct bidi_it itb;
-      EMACS_INT pos = BUF_PT (buf);
-      EMACS_INT bytepos = BUF_PT_BYTE (buf);
+      ptrdiff_t pos = BUF_PT (buf);
+      ptrdiff_t bytepos = BUF_PT_BYTE (buf);
       int c;
       void *itb_data = bidi_shelve_cache ();
 
@@ -19924,7 +19931,7 @@ display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
 {
   struct it it;
   struct face *face;
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
 
   init_iterator (&it, w, -1, -1, NULL, face_id);
   /* Don't extend on a previously drawn mode-line.
@@ -20060,7 +20067,7 @@ display_mode_element (struct it *it, int depth, int field_width, int precision,
       {
        /* A string: output it and check for %-constructs within it.  */
        unsigned char c;
-       EMACS_INT offset = 0;
+       ptrdiff_t offset = 0;
 
        if (SCHARS (elt) > 0
            && (!NILP (props) || risky))
@@ -20157,7 +20164,7 @@ display_mode_element (struct it *it, int depth, int field_width, int precision,
               && (mode_line_target != MODE_LINE_DISPLAY
                   || it->current_x < it->last_visible_x))
          {
-           EMACS_INT last_offset = offset;
+           ptrdiff_t last_offset = offset;
 
            /* Advance to end of string or next format specifier.  */
            while ((c = SREF (elt, offset++)) != '\0' && c != '%')
@@ -20165,7 +20172,7 @@ display_mode_element (struct it *it, int depth, int field_width, int precision,
 
            if (offset - 1 != last_offset)
              {
-               EMACS_INT nchars, nbytes;
+               ptrdiff_t nchars, nbytes;
 
                /* Output to end of string or up to '%'.  Field width
                   is length of string.  Don't output more than
@@ -20184,9 +20191,9 @@ display_mode_element (struct it *it, int depth, int field_width, int precision,
                    break;
                  case MODE_LINE_STRING:
                    {
-                     EMACS_INT bytepos = last_offset;
-                     EMACS_INT charpos = string_byte_to_char (elt, bytepos);
-                     EMACS_INT endpos = (precision <= 0
+                     ptrdiff_t bytepos = last_offset;
+                     ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
+                     ptrdiff_t endpos = (precision <= 0
                                          ? string_byte_to_char (elt, offset)
                                          : charpos + nchars);
 
@@ -20198,8 +20205,8 @@ display_mode_element (struct it *it, int depth, int field_width, int precision,
                    break;
                  case MODE_LINE_DISPLAY:
                    {
-                     EMACS_INT bytepos = last_offset;
-                     EMACS_INT charpos = string_byte_to_char (elt, bytepos);
+                     ptrdiff_t bytepos = last_offset;
+                     ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
 
                      if (precision <= 0)
                        nchars = string_byte_to_char (elt, offset) - charpos;
@@ -20212,7 +20219,7 @@ display_mode_element (struct it *it, int depth, int field_width, int precision,
              }
            else /* c == '%' */
              {
-               EMACS_INT percent_position = offset;
+               ptrdiff_t percent_position = offset;
 
                /* Get the specified minimum width.  Zero means
                   don't pad.  */
@@ -20234,7 +20241,7 @@ display_mode_element (struct it *it, int depth, int field_width, int precision,
                else if (c != 0)
                  {
                    int multibyte;
-                   EMACS_INT bytepos, charpos;
+                   ptrdiff_t bytepos, charpos;
                    const char *spec;
                    Lisp_Object string;
 
@@ -20507,7 +20514,7 @@ static int
 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
                        int field_width, int precision, Lisp_Object props)
 {
-  EMACS_INT len;
+  ptrdiff_t len;
   int n = 0;
 
   if (string != NULL)
@@ -20608,7 +20615,7 @@ are the selected window and the WINDOW's buffer).  */)
   struct buffer *old_buffer = NULL;
   int face_id;
   int no_props = INTEGERP (face);
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
   Lisp_Object str;
   int string_start = 0;
 
@@ -20694,7 +20701,7 @@ are the selected window and the WINDOW's buffer).  */)
    the positive integer D to BUF using a minimal field width WIDTH.  */
 
 static void
-pint2str (register char *buf, register int width, register EMACS_INT d)
+pint2str (register char *buf, register int width, register ptrdiff_t d)
 {
   register char *p = buf;
 
@@ -20738,11 +20745,11 @@ static const char power_letter[] =
   };
 
 static void
-pint2hrstr (char *buf, int width, EMACS_INT d)
+pint2hrstr (char *buf, int width, ptrdiff_t d)
 {
   /* We aim to represent the nonnegative integer D as
      QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
-  EMACS_INT quotient = d;
+  ptrdiff_t quotient = d;
   int remainder = 0;
   /* -1 means: do not use TENTHS. */
   int tenths = -1;
@@ -21022,7 +21029,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
        return "";
       else
        {
-         EMACS_INT col = current_column ();
+         ptrdiff_t col = current_column ();
          w->column_number_displayed = make_number (col);
          pint2str (decode_mode_spec_buf, field_width, col);
          return decode_mode_spec_buf;
@@ -21054,23 +21061,23 @@ decode_mode_spec (struct window *w, register int c, int field_width,
 
     case 'i':
       {
-       EMACS_INT size = ZV - BEGV;
+       ptrdiff_t size = ZV - BEGV;
        pint2str (decode_mode_spec_buf, field_width, size);
        return decode_mode_spec_buf;
       }
 
     case 'I':
       {
-       EMACS_INT size = ZV - BEGV;
+       ptrdiff_t size = ZV - BEGV;
        pint2hrstr (decode_mode_spec_buf, field_width, size);
        return decode_mode_spec_buf;
       }
 
     case 'l':
       {
-       EMACS_INT startpos, startpos_byte, line, linepos, linepos_byte;
-       EMACS_INT topline, nlines, height;
-       EMACS_INT junk;
+       ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
+       ptrdiff_t topline, nlines, height;
+       ptrdiff_t junk;
 
        /* %c and %l are ignored in `frame-title-format'.  */
        if (mode_line_target == MODE_LINE_TITLE)
@@ -21131,10 +21138,10 @@ decode_mode_spec (struct window *w, register int c, int field_width,
        else if (nlines < height + 25 || nlines > height * 3 + 50
                 || linepos == BUF_BEGV (b))
          {
-           EMACS_INT limit = BUF_BEGV (b);
-           EMACS_INT limit_byte = BUF_BEGV_BYTE (b);
-           EMACS_INT position;
-           EMACS_INT distance =
+           ptrdiff_t limit = BUF_BEGV (b);
+           ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
+           ptrdiff_t position;
+           ptrdiff_t distance =
              (height * 2 + 30) * line_number_display_limit_width;
 
            if (startpos - distance > limit)
@@ -21196,8 +21203,8 @@ decode_mode_spec (struct window *w, register int c, int field_width,
 
     case 'p':
       {
-       EMACS_INT pos = marker_position (w->start);
-       EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
+       ptrdiff_t pos = marker_position (w->start);
+       ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
 
        if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
          {
@@ -21219,7 +21226,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
               so get us a 2-digit number that is close.  */
            if (total == 100)
              total = 99;
-           sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
+           sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
            return decode_mode_spec_buf;
          }
       }
@@ -21227,9 +21234,9 @@ decode_mode_spec (struct window *w, register int c, int field_width,
       /* Display percentage of size above the bottom of the screen.  */
     case 'P':
       {
-       EMACS_INT toppos = marker_position (w->start);
-       EMACS_INT botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
-       EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
+       ptrdiff_t toppos = marker_position (w->start);
+       ptrdiff_t botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
+       ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
 
        if (botpos >= BUF_ZV (b))
          {
@@ -21250,9 +21257,9 @@ decode_mode_spec (struct window *w, register int c, int field_width,
            if (total == 100)
              total = 99;
            if (toppos <= BUF_BEGV (b))
-             sprintf (decode_mode_spec_buf, "Top%2"pI"d%%", total);
+             sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
            else
-             sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
+             sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
            return decode_mode_spec_buf;
          }
       }
@@ -21269,7 +21276,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
 
     case '@':
       {
-       int count = inhibit_garbage_collection ();
+       ptrdiff_t count = inhibit_garbage_collection ();
        Lisp_Object val = call1 (intern ("file-remote-p"),
                                 BVAR (current_buffer, directory));
        unbind_to (count, Qnil);
@@ -21338,17 +21345,17 @@ decode_mode_spec (struct window *w, register int c, int field_width,
 
    Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT.  */
 
-static EMACS_INT
-display_count_lines (EMACS_INT start_byte,
-                    EMACS_INT limit_byte, EMACS_INT count,
-                    EMACS_INT *byte_pos_ptr)
+static ptrdiff_t
+display_count_lines (ptrdiff_t start_byte,
+                    ptrdiff_t limit_byte, ptrdiff_t count,
+                    ptrdiff_t *byte_pos_ptr)
 {
   register unsigned char *cursor;
   unsigned char *base;
 
-  register EMACS_INT ceiling;
+  register ptrdiff_t ceiling;
   register unsigned char *ceiling_addr;
-  EMACS_INT orig_count = count;
+  ptrdiff_t orig_count = count;
 
   /* If we are not in selective display mode,
      check only for newlines.  */
@@ -21482,13 +21489,13 @@ display_count_lines (EMACS_INT start_byte,
 
 static int
 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
-               EMACS_INT face_string_pos, EMACS_INT start, struct it *it,
+               ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
                int field_width, int precision, int max_x, int multibyte)
 {
   int hpos_at_start = it->hpos;
   int saved_face_id = it->face_id;
   struct glyph_row *row = it->glyph_row;
-  EMACS_INT it_charpos;
+  ptrdiff_t it_charpos;
 
   /* Initialize the iterator IT for iteration over STRING beginning
      with index START.  */
@@ -21503,7 +21510,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
      FACE_STRING, if that's given.  */
   if (STRINGP (face_string))
     {
-      EMACS_INT endptr;
+      ptrdiff_t endptr;
       struct face *face;
 
       it->face_id
@@ -22990,7 +22997,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
 
 static int
 draw_glyphs (struct window *w, int x, struct glyph_row *row,
-            enum glyph_row_area area, EMACS_INT start, EMACS_INT end,
+            enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
             enum draw_glyphs_face hl, int overlaps)
 {
   struct glyph_string *head, *tail;
@@ -24454,7 +24461,7 @@ x_produce_glyphs (struct it *it)
          XChar2b char2b;
          struct font_metrics *pcm;
          int font_not_found_p;
-         EMACS_INT pos;
+         ptrdiff_t pos;
 
          for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
            if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
@@ -24862,7 +24869,7 @@ x_insert_glyphs (struct glyph *start, int len)
   struct glyph_row *row;
   struct glyph *glyph;
   int frame_x, frame_y;
-  EMACS_INT hpos;
+  ptrdiff_t hpos;
 
   xassert (updated_window && updated_row);
   BLOCK_INPUT;
@@ -25009,8 +25016,7 @@ get_specified_cursor_type (Lisp_Object arg, int *width)
 
   if (CONSP (arg)
       && EQ (XCAR (arg), Qbar)
-      && INTEGERP (XCDR (arg))
-      && XINT (XCDR (arg)) >= 0)
+      && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
     {
       *width = XINT (XCDR (arg));
       return BAR_CURSOR;
@@ -25024,8 +25030,7 @@ get_specified_cursor_type (Lisp_Object arg, int *width)
 
   if (CONSP (arg)
       && EQ (XCAR (arg), Qhbar)
-      && INTEGERP (XCDR (arg))
-      && XINT (XCDR (arg)) >= 0)
+      && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
     {
       *width = XINT (XCDR (arg));
       return HBAR_CURSOR;
@@ -25922,7 +25927,7 @@ cursor_in_mouse_face_p (struct window *w)
    buffer positions change non-linearly with glyph rows.  */
 static void
 rows_from_pos_range (struct window *w,
-                    EMACS_INT start_charpos, EMACS_INT end_charpos,
+                    ptrdiff_t start_charpos, ptrdiff_t end_charpos,
                     Lisp_Object disp_string,
                     struct glyph_row **start, struct glyph_row **end)
 {
@@ -25998,7 +26003,7 @@ rows_from_pos_range (struct window *w,
   for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
     {
       struct glyph_row *next = row + 1;
-      EMACS_INT next_start = MATRIX_ROW_START_CHARPOS (next);
+      ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
 
       if (!next->enabled_p
          || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
@@ -26079,9 +26084,9 @@ rows_from_pos_range (struct window *w,
 static void
 mouse_face_from_buffer_pos (Lisp_Object window,
                            Mouse_HLInfo *hlinfo,
-                           EMACS_INT mouse_charpos,
-                           EMACS_INT start_charpos,
-                           EMACS_INT end_charpos,
+                           ptrdiff_t mouse_charpos,
+                           ptrdiff_t start_charpos,
+                           ptrdiff_t end_charpos,
                            Lisp_Object before_string,
                            Lisp_Object after_string,
                            Lisp_Object disp_string)
@@ -26090,7 +26095,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
   struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
   struct glyph_row *r1, *r2;
   struct glyph *glyph, *end;
-  EMACS_INT ignore, pos;
+  ptrdiff_t ignore, pos;
   int x;
 
   xassert (NILP (disp_string) || STRINGP (disp_string));
@@ -26423,7 +26428,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
    Value is non-zero if a glyph was found.  */
 
 static int
-fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
+fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
                      int *hpos, int *vpos, int *x, int *y, int right_p)
 {
   int yb = window_text_bottom_y (w);
@@ -26493,7 +26498,7 @@ fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
 static void
 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
                            Lisp_Object object,
-                           EMACS_INT startpos, EMACS_INT endpos)
+                           ptrdiff_t startpos, ptrdiff_t endpos)
 {
   int yb = window_text_bottom_y (w);
   struct glyph_row *r;
@@ -26663,8 +26668,8 @@ on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
        {
          struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
          Lisp_Object *poly = v->contents;
-         int n = v->header.size;
-         int i;
+         ptrdiff_t n = v->header.size;
+         ptrdiff_t i;
          int inside = 0;
          Lisp_Object lx, ly;
          int x0, y0;
@@ -26742,7 +26747,9 @@ Returns the alist element for the first matching AREA in MAP.  */)
   CHECK_NUMBER (x);
   CHECK_NUMBER (y);
 
-  return find_hot_spot (map, XINT (x), XINT (y));
+  return find_hot_spot (map,
+                       clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
+                       clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
 }
 
 
@@ -26801,7 +26808,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
   Cursor cursor = No_Cursor;
   Lisp_Object pointer = Qnil;
   int dx, dy, width, height;
-  EMACS_INT charpos;
+  ptrdiff_t charpos;
   Lisp_Object string, object = Qnil;
   Lisp_Object pos, help;
 
@@ -26941,7 +26948,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
          int gpos;
          int gseq_length;
          int total_pixel_width;
-         EMACS_INT begpos, endpos, ignore;
+         ptrdiff_t begpos, endpos, ignore;
 
          int vpos, hpos;
 
@@ -27171,14 +27178,14 @@ note_mouse_highlight (struct frame *f, int x, int y)
       && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
     {
       int hpos, vpos, dx, dy, area = LAST_AREA;
-      EMACS_INT pos;
+      ptrdiff_t pos;
       struct glyph *glyph;
       Lisp_Object object;
       Lisp_Object mouse_face = Qnil, position;
       Lisp_Object *overlay_vec = NULL;
       ptrdiff_t i, noverlays;
       struct buffer *obuf;
-      EMACS_INT obegv, ozv;
+      ptrdiff_t obegv, ozv;
       int same_region;
 
       /* Find the glyph under X/Y.  */
@@ -27336,7 +27343,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
              /* The mouse-highlighting comes from a display string
                 with a mouse-face.  */
              Lisp_Object s, e;
-             EMACS_INT ignore;
+             ptrdiff_t ignore;
 
              s = Fprevious_single_property_change
                (make_number (pos + 1), Qmouse_face, object, Qnil);
@@ -27368,7 +27375,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
                  /* If we are on a display string with no mouse-face,
                     check if the text under it has one.  */
                  struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
-                 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
+                 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
                  pos = string_buffer_position (object, start);
                  if (pos > 0)
                    {
@@ -27467,7 +27474,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
        else
          {
            Lisp_Object obj = glyph->object;
-           EMACS_INT charpos = glyph->charpos;
+           ptrdiff_t charpos = glyph->charpos;
 
            /* Try text properties.  */
            if (STRINGP (obj)
@@ -27482,8 +27489,8 @@ note_mouse_highlight (struct frame *f, int x, int y)
                       see if the buffer text ``under'' it does.  */
                    struct glyph_row *r
                      = MATRIX_ROW (w->current_matrix, vpos);
-                   EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
-                   EMACS_INT p = string_buffer_position (obj, start);
+                   ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
+                   ptrdiff_t p = string_buffer_position (obj, start);
                    if (p > 0)
                      {
                        help = Fget_char_property (make_number (p),
@@ -27523,7 +27530,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
          if (NILP (pointer))
            {
              Lisp_Object obj = glyph->object;
-             EMACS_INT charpos = glyph->charpos;
+             ptrdiff_t charpos = glyph->charpos;
 
              /* Try text properties.  */
              if (STRINGP (obj)
@@ -27538,8 +27545,8 @@ note_mouse_highlight (struct frame *f, int x, int y)
                         see if the buffer text ``under'' it does.  */
                      struct glyph_row *r
                        = MATRIX_ROW (w->current_matrix, vpos);
-                     EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
-                     EMACS_INT p = string_buffer_position (obj, start);
+                     ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
+                     ptrdiff_t p = string_buffer_position (obj, start);
                      if (p > 0)
                        pointer = Fget_char_property (make_number (p),
                                                      Qpointer, w->buffer);
@@ -28836,23 +28843,16 @@ start_hourglass (void)
 {
 #if defined (HAVE_WINDOW_SYSTEM)
   EMACS_TIME delay;
-  int secs, usecs = 0;
+  int secs = DEFAULT_HOURGLASS_DELAY, usecs = 0;
 
   cancel_hourglass ();
 
-  if (INTEGERP (Vhourglass_delay)
-      && XINT (Vhourglass_delay) > 0)
-    secs = XFASTINT (Vhourglass_delay);
-  else if (FLOATP (Vhourglass_delay)
-          && XFLOAT_DATA (Vhourglass_delay) > 0)
+  if (NUMBERP (Vhourglass_delay))
     {
-      Lisp_Object tem;
-      tem = Ftruncate (Vhourglass_delay, Qnil);
-      secs = XFASTINT (tem);
-      usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
+      double duration = extract_float (Vhourglass_delay);
+      if (0 < duration)
+       duration_to_sec_usec (duration, &secs, &usecs);
     }
-  else
-    secs = DEFAULT_HOURGLASS_DELAY;
 
   EMACS_SET_SECS_USECS (delay, secs, usecs);
   hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,