]> code.delx.au - gnu-emacs/blobdiff - src/window.c
Merge from emacs-24 branch; up to 2012-05-01T10:20:43Z!rgm@gnu.org
[gnu-emacs] / src / window.c
index ae8d209df7456e1b5f33283bbfe23f79bd643f7c..3bf73134468dd03b70e2470259dcee65c85a9e9d 100644 (file)
@@ -23,6 +23,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <setjmp.h>
 
 #include "lisp.h"
+#include "character.h"
 #include "buffer.h"
 #include "keyboard.h"
 #include "keymap.h"
@@ -63,7 +64,7 @@ static int displayed_window_lines (struct window *);
 static struct window *decode_window (Lisp_Object);
 static int count_windows (struct window *);
 static int get_leaf_windows (struct window *, struct window **, int);
-static void window_scroll (Lisp_Object, int, int, int);
+static void window_scroll (Lisp_Object, EMACS_INT, int, int);
 static void window_scroll_pixel_based (Lisp_Object, int, int, int);
 static void window_scroll_line_based (Lisp_Object, int, int, int);
 static int freeze_window_start (struct window *, void *);
@@ -127,8 +128,8 @@ static int window_scroll_pixel_based_preserve_x;
 static int window_scroll_pixel_based_preserve_y;
 
 /* Same for window_scroll_line_based.  */
-static int window_scroll_preserve_hpos;
-static int window_scroll_preserve_vpos;
+static EMACS_INT window_scroll_preserve_hpos;
+static EMACS_INT window_scroll_preserve_vpos;
 \f
 static struct window *
 decode_window (register Lisp_Object window)
@@ -330,8 +331,7 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
 
   if (NILP (norecord))
     {
-      ++window_select_count;
-      XSETFASTINT (w->use_time, window_select_count);
+      w->use_time = ++window_select_count;
       record_buffer (w->buffer);
     }
 
@@ -378,7 +378,7 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
      redisplay_window has altered point after scrolling,
      because it makes the change only in the window.  */
   {
-    register EMACS_INT new_point = marker_position (w->pointm);
+    register ptrdiff_t new_point = marker_position (w->pointm);
     if (new_point < BEGV)
       SET_PT (BEGV);
     else if (new_point > ZV)
@@ -496,7 +496,7 @@ one.  The window with the lowest use time is the least recently
 selected one.  */)
   (Lisp_Object window)
 {
-  return decode_window (window)->use_time;
+  return make_number (decode_window (window)->use_time);
 }
 \f
 DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 1, 0,
@@ -665,30 +665,45 @@ DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
 WINDOW must be a live window and defaults to the selected one.  */)
   (Lisp_Object window)
 {
-  return decode_window (window)->hscroll;
+  return make_number (decode_window (window)->hscroll);
+}
+
+/* Set W's horizontal scroll amount to HSCROLL clipped to a reasonable
+   range, returning the new amount as a fixnum.  */
+static Lisp_Object
+set_window_hscroll (struct window *w, EMACS_INT hscroll)
+{
+  /* Horizontal scrolling has problems with large scroll amounts.
+     It's too slow with long lines, and even with small lines the
+     display can be messed up.  For now, though, impose only the limits
+     required by the internal representation: horizontal scrolling must
+     fit in fixnum (since it's visible to Elisp) and into ptrdiff_t
+     (since it's stored in a ptrdiff_t).  */
+  ptrdiff_t hscroll_max = min (MOST_POSITIVE_FIXNUM, PTRDIFF_MAX);
+  ptrdiff_t new_hscroll = clip_to_bounds (0, hscroll, hscroll_max);
+
+  /* Prevent redisplay shortcuts when changing the hscroll.  */
+  if (w->hscroll != new_hscroll)
+    XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
+
+  w->hscroll = new_hscroll;
+  return make_number (new_hscroll);
 }
 
 DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0,
        doc: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
 If WINDOW is nil, the selected window is used.
-Return NCOL.  NCOL should be zero or positive.
+Clip the number to a reasonable value if out of range.
+Return the new number.  NCOL should be zero or positive.
 
 Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
 window so that the location of point moves off-window.  */)
   (Lisp_Object window, Lisp_Object ncol)
 {
   struct window *w = decode_window (window);
-  int hscroll;
 
   CHECK_NUMBER (ncol);
-  hscroll = max (0, XINT (ncol));
-
-  /* Prevent redisplay shortcuts when changing the hscroll.  */
-  if (XINT (w->hscroll) != hscroll)
-    XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
-
-  w->hscroll = make_number (hscroll);
-  return ncol;
+  return set_window_hscroll (w, XINT (ncol));
 }
 
 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger,
@@ -798,8 +813,6 @@ of just the text area, use `window-inside-absolute-pixel-edges'.  */)
 {
   register struct window *w = decode_any_window (window);
   int add_x, add_y;
-
-  CHECK_LIVE_FRAME (w->frame);
   calc_absolute_offset (w, &add_x, &add_y);
 
   return Fcons (make_number (WINDOW_LEFT_EDGE_X (w) + add_x),
@@ -1313,8 +1326,8 @@ if it isn't already recorded.  */)
 
   if (! NILP (update)
       && ! (! NILP (w->window_end_valid)
-           && XFASTINT (w->last_modified) >= BUF_MODIFF (b)
-           && XFASTINT (w->last_overlay_modified) >= BUF_OVERLAY_MODIFF (b))
+           && w->last_modified >= BUF_MODIFF (b)
+           && w->last_overlay_modified >= BUF_OVERLAY_MODIFF (b))
       && !noninteractive)
     {
       struct text_pos startp;
@@ -1393,12 +1406,12 @@ overriding motion of point in order to display at this exact start.  */)
   CHECK_NUMBER_COERCE_MARKER (pos);
   set_marker_restricted (w->start, pos, w->buffer);
   /* this is not right, but much easier than doing what is right. */
-  w->start_at_line_beg = Qnil;
+  w->start_at_line_beg = 0;
   if (NILP (noforce))
-    w->force_start = Qt;
-  w->update_mode_line = Qt;
-  XSETFASTINT (w->last_modified, 0);
-  XSETFASTINT (w->last_overlay_modified, 0);
+    w->force_start = 1;
+  w->update_mode_line = 1;
+  w->last_modified = 0;
+  w->last_overlay_modified = 0;
   if (!EQ (window, selected_window))
     windows_or_buffers_changed++;
 
@@ -1495,7 +1508,8 @@ Return nil if window display is not up-to-date.  In that case, use
   register struct window *w;
   register struct buffer *b;
   struct glyph_row *row, *end_row;
-  int max_y, crop, i, n;
+  int max_y, crop, i;
+  EMACS_INT n;
 
   w = decode_window (window);
 
@@ -1509,8 +1523,8 @@ Return nil if window display is not up-to-date.  In that case, use
   if (NILP (w->window_end_valid)
       || current_buffer->clip_changed
       || current_buffer->prevent_redisplay_optimizations_p
-      || XFASTINT (w->last_modified) < BUF_MODIFF (b)
-      || XFASTINT (w->last_overlay_modified) < BUF_OVERLAY_MODIFF (b))
+      || w->last_modified < BUF_MODIFF (b)
+      || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b))
     return Qnil;
 
   if (NILP (line))
@@ -2033,7 +2047,7 @@ candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf
     candidate_p = 1;
   else if (NILP (all_frames))
     {
-      xassert (WINDOWP (owindow));
+      eassert (WINDOWP (owindow));
       candidate_p = EQ (w->frame, XWINDOW (owindow)->frame);
     }
   else if (EQ (all_frames, Qvisible))
@@ -2471,7 +2485,7 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
            if (EQ (w->buffer, obj))
              {
                mark_window_display_accurate (window, 0);
-               w->update_mode_line = Qt;
+               w->update_mode_line = 1;
                XBUFFER (obj)->prevent_redisplay_optimizations_p = 1;
                ++update_mode_lines;
                best_window = window;
@@ -2563,12 +2577,10 @@ window-start value is reasonable when this function is called.  */)
   struct window *w, *r, *s;
   struct frame *f;
   Lisp_Object sibling, pwindow, swindow IF_LINT (= Qnil), delta;
-  EMACS_INT startpos IF_LINT (= 0);
+  ptrdiff_t startpos IF_LINT (= 0);
   int top IF_LINT (= 0), new_top, resize_failed;
-  Mouse_HLInfo *hlinfo;
 
   w = decode_any_window (window);
-  CHECK_LIVE_FRAME (w->frame);
   XSETWINDOW (window, w);
   f = XFRAME (w->frame);
 
@@ -2582,7 +2594,6 @@ window-start value is reasonable when this function is called.  */)
     /* ROOT must be an ancestor of WINDOW.  */
     {
       r = decode_any_window (root);
-      CHECK_LIVE_FRAME (r->frame);
       pwindow = XWINDOW (window)->parent;
       while (!NILP (pwindow))
        if (EQ (pwindow, root))
@@ -2648,19 +2659,23 @@ window-start value is reasonable when this function is called.  */)
     }
 
   BLOCK_INPUT;
-  hlinfo = MOUSE_HL_INFO (f);
-  /* We are going to free the glyph matrices of WINDOW, and with that
-     we might lose any information about glyph rows that have some of
-     their glyphs highlighted in mouse face.  (These rows are marked
-     with a non-zero mouse_face_p flag.)  If WINDOW indeed has some
-     glyphs highlighted in mouse face, signal to frame's up-to-date
-     hook that mouse highlight was overwritten, so that it will
-     arrange for redisplaying the highlight.  */
-  if (EQ (hlinfo->mouse_face_window, window))
+  if (!FRAME_INITIAL_P (f))
     {
-      hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
-      hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
-      hlinfo->mouse_face_window = Qnil;
+        Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+
+      /* We are going to free the glyph matrices of WINDOW, and with
+        that we might lose any information about glyph rows that have
+        some of their glyphs highlighted in mouse face.  (These rows
+        are marked with a non-zero mouse_face_p flag.)  If WINDOW
+        indeed has some glyphs highlighted in mouse face, signal to
+        frame's up-to-date hook that mouse highlight was overwritten,
+        so that it will arrange for redisplaying the highlight.  */
+      if (EQ (hlinfo->mouse_face_window, window))
+       {
+         hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
+         hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
+         hlinfo->mouse_face_window = Qnil;
+       }
     }
   free_window_matrices (r);
 
@@ -2772,12 +2787,11 @@ window-start value is reasonable when this function is called.  */)
 
          set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
          w->window_end_valid = Qnil;
-         w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE
-                                  || FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt
-                                 : Qnil);
+         w->start_at_line_beg = (pos.bytepos == BEGV_BYTE
+                                   || FETCH_BYTE (pos.bytepos - 1) == '\n');
          /* We need to do this, so that the window-scroll-functions
             get called.  */
-         w->optional_new_start = Qt;
+         w->optional_new_start = 1;
 
          set_buffer_internal (obuf);
        }
@@ -2872,13 +2886,6 @@ adjust_window_margins (struct window *w)
   return 1;
 }
 \f
-static Lisp_Object Fset_window_margins (Lisp_Object, Lisp_Object, Lisp_Object);
-static Lisp_Object Fset_window_fringes (Lisp_Object, Lisp_Object, Lisp_Object,
-                                       Lisp_Object);
-static Lisp_Object Fset_window_scroll_bars (Lisp_Object, Lisp_Object,
-                                           Lisp_Object, Lisp_Object);
-static Lisp_Object Fset_window_vscroll (Lisp_Object, Lisp_Object, Lisp_Object);
-
 /* The following three routines are needed for running a window's
    configuration change hook.  */
 static void
@@ -2906,7 +2913,7 @@ select_frame_norecord (Lisp_Object frame)
 void
 run_window_configuration_change_hook (struct frame *f)
 {
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
   Lisp_Object frame, global_wcch
     = Fdefault_value (Qwindow_configuration_change_hook);
   XSETFRAME (frame, f);
@@ -2937,7 +2944,7 @@ run_window_configuration_change_hook (struct frame *f)
        if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook,
                                      buffer)))
          {
-           int inner_count = SPECPDL_INDEX ();
+           ptrdiff_t inner_count = SPECPDL_INDEX ();
            record_unwind_protect (select_window_norecord, Fselected_window ());
            select_window_norecord (window);
            run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook,
@@ -2972,7 +2979,7 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
 {
   struct window *w = XWINDOW (window);
   struct buffer *b = XBUFFER (buffer);
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
   int samebuf = EQ (buffer, w->buffer);
 
   w->buffer = buffer;
@@ -3001,16 +3008,16 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
         Resetting hscroll and vscroll here is problematic for things like
         image-mode and doc-view-mode since it resets the image's position
         whenever we resize the frame.  */
-      w->hscroll = w->min_hscroll = make_number (0);
+      w->hscroll = w->min_hscroll = 0;
       w->vscroll = 0;
       set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
       set_marker_restricted (w->start,
                             make_number (b->last_window_start),
                             buffer);
-      w->start_at_line_beg = Qnil;
-      w->force_start = Qnil;
-      XSETFASTINT (w->last_modified, 0);
-      XSETFASTINT (w->last_overlay_modified, 0);
+      w->start_at_line_beg = 0;
+      w->force_start = 0;
+      w->last_modified = 0;
+      w->last_overlay_modified = 0;
     }
   /* Maybe we could move this into the `if' but it's not obviously safe and
      I doubt it's worth the trouble.  */
@@ -3144,7 +3151,7 @@ displaying that buffer.  */)
     {
       struct window *w = XWINDOW (object);
       mark_window_display_accurate (object, 0);
-      w->update_mode_line = Qt;
+      w->update_mode_line = 1;
       if (BUFFERP (w->buffer))
        XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
       ++update_mode_lines;
@@ -3195,15 +3202,15 @@ temp_output_buffer_show (register Lisp_Object buf)
        Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
       Vminibuf_scroll_window = window;
       w = XWINDOW (window);
-      XSETFASTINT (w->hscroll, 0);
-      XSETFASTINT (w->min_hscroll, 0);
+      w->hscroll = 0;
+      w->min_hscroll = 0;
       set_marker_restricted_both (w->start, buf, BEG, BEG);
       set_marker_restricted_both (w->pointm, buf, BEG, BEG);
 
       /* Run temp-buffer-show-hook, with the chosen window selected
         and its buffer current.  */
       {
-        int count = SPECPDL_INDEX ();
+        ptrdiff_t count = SPECPDL_INDEX ();
         Lisp_Object prev_window, prev_buffer;
         prev_window = selected_window;
         XSETBUFFER (prev_buffer, old);
@@ -3240,17 +3247,15 @@ make_parent_window (Lisp_Object window, int horflag)
 {
   Lisp_Object parent;
   register struct window *o, *p;
-  int i;
 
   o = XWINDOW (window);
   p = allocate_window ();
-  for (i = 0; i < VECSIZE (struct window); ++i)
-    ((struct Lisp_Vector *) p)->contents[i]
-      = ((struct Lisp_Vector *) o)->contents[i];
+  memcpy ((char *) p + sizeof (struct vectorlike_header),
+         (char *) o + sizeof (struct vectorlike_header),
+         sizeof (Lisp_Object) * VECSIZE (struct window));
   XSETWINDOW (parent, p);
 
-  ++sequence_number;
-  XSETFASTINT (p->sequence_number, sequence_number);
+  p->sequence_number = ++sequence_number;
 
   replace_window (window, parent, 1);
 
@@ -3275,9 +3280,8 @@ make_window (void)
   register struct window *w;
 
   w = allocate_window ();
-  /* Initialize all Lisp data.  */
-  w->frame = w->mini_p = Qnil;
-  w->next = w->prev = w->hchild = w->vchild = w->parent = Qnil;
+  /* Initialize Lisp data.  Note that allocate_window initializes all
+     Lisp data to nil, so do it only for slots which should not be nil.  */
   XSETFASTINT (w->left_col, 0);
   XSETFASTINT (w->top_line, 0);
   XSETFASTINT (w->total_lines, 0);
@@ -3286,46 +3290,19 @@ make_window (void)
   w->normal_cols = make_float (1.0);
   XSETFASTINT (w->new_total, 0);
   XSETFASTINT (w->new_normal, 0);
-  w->buffer = Qnil;
   w->start = Fmake_marker ();
   w->pointm = Fmake_marker ();
-  w->force_start = w->optional_new_start = Qnil;
-  XSETFASTINT (w->hscroll, 0);
-  XSETFASTINT (w->min_hscroll, 0);
-  XSETFASTINT (w->use_time, 0);
-  ++sequence_number;
-  XSETFASTINT (w->sequence_number, sequence_number);
-  w->temslot = w->last_modified = w->last_overlay_modified = Qnil;
-  XSETFASTINT (w->last_point, 0);
-  w->last_had_star = w->vertical_scroll_bar = Qnil;
-  w->left_margin_cols = w->right_margin_cols = Qnil;
-  w->left_fringe_width = w->right_fringe_width = Qnil;
-  w->fringes_outside_margins = Qnil;
-  w->scroll_bar_width = Qnil;
   w->vertical_scroll_bar_type = Qt;
-  w->last_mark_x = w->last_mark_y = Qnil;
   XSETFASTINT (w->window_end_pos, 0);
   XSETFASTINT (w->window_end_vpos, 0);
-  w->window_end_valid = w->update_mode_line = Qnil;
-  w->start_at_line_beg = w->display_table = w->dedicated = Qnil;
-  w->base_line_number = w->base_line_pos = w->region_showing = Qnil;
-  w->column_number_displayed = w->redisplay_end_trigger = Qnil;
-  w->combination_limit = w->window_parameters = Qnil;
-  w->prev_buffers = w->next_buffers = Qnil;
-  /* Initialize non-Lisp data.  */
-  w->desired_matrix = w->current_matrix = 0;
+
+  /* Initialize non-Lisp data.  Note that allocate_window zeroes out all
+     non-Lisp data, so do it only for slots which should not be zero.  */
   w->nrows_scale_factor = w->ncols_scale_factor = 1;
-  memset (&w->cursor, 0, sizeof (w->cursor));
-  memset (&w->last_cursor, 0, sizeof (w->last_cursor));
-  memset (&w->phys_cursor, 0, sizeof (w->phys_cursor));
   w->phys_cursor_type = -1;
   w->phys_cursor_width = -1;
-  w->phys_cursor_on_p = 0;
-  w->last_cursor_off_p = w->cursor_off_p = 0;
-  w->must_be_updated_p = 0;
-  w->pseudo_window_p = 0;
-  w->frozen_window_start_p = 0;
-  w->vscroll = 0;
+  w->sequence_number = ++sequence_number;
+
   /* Reset window_list.  */
   Vwindow_list = Qnil;
   /* Return window.  */
@@ -3514,8 +3491,8 @@ window_resize_apply (struct window *w, int horflag)
     }
 
   /* Clear out some redisplay caches.  */
-  XSETFASTINT (w->last_modified, 0);
-  XSETFASTINT (w->last_overlay_modified, 0);
+  w->last_modified = 0;
+  w->last_overlay_modified = 0;
 }
 
 
@@ -3903,7 +3880,6 @@ Signal an error when WINDOW is the only window on its frame.  */)
       && EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
     /* We can delete WINDOW now.  */
     {
-      Mouse_HLInfo *hlinfo;
 
       /* Block input.  */
       BLOCK_INPUT;
@@ -3911,9 +3887,13 @@ Signal an error when WINDOW is the only window on its frame.  */)
 
       /* If this window is referred to by the dpyinfo's mouse
         highlight, invalidate that slot to be safe (Bug#9904).  */
-      hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
-      if (EQ (hlinfo->mouse_face_window, window))
-       hlinfo->mouse_face_window = Qnil;
+      if (!FRAME_INITIAL_P (f))
+       {
+         Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+
+         if (EQ (hlinfo->mouse_face_window, window))
+           hlinfo->mouse_face_window = Qnil;
+       }
 
       windows_or_buffers_changed++;
       Vwindow_list = Qnil;
@@ -4029,8 +4009,8 @@ grow_mini_window (struct window *w, int delta)
   struct window *r;
   Lisp_Object root, value;
 
-  xassert (MINI_WINDOW_P (w));
-  xassert (delta >= 0);
+  eassert (MINI_WINDOW_P (w));
+  eassert (delta >= 0);
 
   root = FRAME_ROOT_WINDOW (f);
   r = XWINDOW (root);
@@ -4044,8 +4024,8 @@ grow_mini_window (struct window *w, int delta)
       /* Grow the mini-window.  */
       XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
       XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - XINT (value));
-      XSETFASTINT (w->last_modified, 0);
-      XSETFASTINT (w->last_overlay_modified, 0);
+      w->last_modified = 0;
+      w->last_overlay_modified = 0;
 
       adjust_glyphs (f);
       UNBLOCK_INPUT;
@@ -4062,7 +4042,7 @@ shrink_mini_window (struct window *w)
   Lisp_Object root, value;
   EMACS_INT size;
 
-  xassert (MINI_WINDOW_P (w));
+  eassert (MINI_WINDOW_P (w));
 
   size = XINT (w->total_lines);
   if (size > 1)
@@ -4080,8 +4060,8 @@ shrink_mini_window (struct window *w)
          XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
          XSETFASTINT (w->total_lines, 1);
 
-         XSETFASTINT (w->last_modified, 0);
-         XSETFASTINT (w->last_overlay_modified, 0);
+         w->last_modified = 0;
+         w->last_overlay_modified = 0;
 
          adjust_glyphs (f);
          UNBLOCK_INPUT;
@@ -4191,9 +4171,10 @@ window_internal_height (struct window *w)
    respectively.  */
 
 static void
-window_scroll (Lisp_Object window, int n, int whole, int noerror)
+window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror)
 {
   immediate_quit = 1;
+  n = clip_to_bounds (INT_MIN, n, INT_MAX);
 
   /* If we must, use the pixel-based version which is much slower than
      the line-based one but can handle varying line heights.  */
@@ -4294,7 +4275,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
              /* Maybe modify window start instead of scrolling.  */
              if (rbot > 0 || w->vscroll < 0)
                {
-                 EMACS_INT spos;
+                 ptrdiff_t spos;
 
                  Fset_window_vscroll (window, make_number (0), Qt);
                  /* If there are other text lines above the current row,
@@ -4305,13 +4286,13 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
                    spos = min (XINT (Fline_end_position (Qnil)) + 1, ZV);
                  set_marker_restricted (w->start, make_number (spos),
                                         w->buffer);
-                 w->start_at_line_beg = Qt;
-                 w->update_mode_line = Qt;
-                 XSETFASTINT (w->last_modified, 0);
-                 XSETFASTINT (w->last_overlay_modified, 0);
+                 w->start_at_line_beg = 1;
+                 w->update_mode_line = 1;
+                 w->last_modified = 0;
+                 w->last_overlay_modified = 0;
                  /* Set force_start so that redisplay_window will run the
                     window-scroll-functions.  */
-                 w->force_start = Qt;
+                 w->force_start = 1;
                  return;
                }
            }
@@ -4349,7 +4330,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
   start_display (&it, w, start);
   if (whole)
     {
-      EMACS_INT start_pos = IT_CHARPOS (it);
+      ptrdiff_t start_pos = IT_CHARPOS (it);
       int dy = WINDOW_FRAME_LINE_HEIGHT (w);
       dy = max ((window_box_height (w)
                 - next_screen_context_lines * dy),
@@ -4436,8 +4417,8 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
 
   if (! vscrolled)
     {
-      EMACS_INT pos = IT_CHARPOS (it);
-      EMACS_INT bytepos;
+      ptrdiff_t pos = IT_CHARPOS (it);
+      ptrdiff_t bytepos;
 
       /* If in the middle of a multi-glyph character move forward to
         the next character.  */
@@ -4451,14 +4432,13 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
       set_marker_restricted (w->start, make_number (pos),
                             w->buffer);
       bytepos = XMARKER (w->start)->bytepos;
-      w->start_at_line_beg = ((pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n')
-                             ? Qt : Qnil);
-      w->update_mode_line = Qt;
-      XSETFASTINT (w->last_modified, 0);
-      XSETFASTINT (w->last_overlay_modified, 0);
+      w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n');
+      w->update_mode_line = 1;
+      w->last_modified = 0;
+      w->last_overlay_modified = 0;
       /* Set force_start so that redisplay_window will run the
         window-scroll-functions.  */
-      w->force_start = Qt;
+      w->force_start = 1;
     }
 
   /* The rest of this function uses current_y in a nonstandard way,
@@ -4507,7 +4487,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
     }
   else if (n < 0)
     {
-      EMACS_INT charpos, bytepos;
+      ptrdiff_t charpos, bytepos;
       int partial_p;
 
       /* Save our position, for the
@@ -4584,12 +4564,12 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
      in `grep-mode-font-lock-keywords').  So we use a marker to record
      the old point position, to prevent crashes in SET_PT_BOTH.  */
   Lisp_Object opoint_marker = Fpoint_marker ();
-  register EMACS_INT pos, pos_byte;
+  register ptrdiff_t pos, pos_byte;
   register int ht = window_internal_height (w);
   register Lisp_Object tem;
   int lose;
   Lisp_Object bolp;
-  EMACS_INT startpos;
+  ptrdiff_t startpos;
   Lisp_Object original_pos = Qnil;
 
   /* If scrolling screen-fulls, compute the number of lines to
@@ -4608,10 +4588,10 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
          struct position posit
            = *compute_motion (startpos, 0, 0, 0,
                               PT, ht, 0,
-                              -1, XINT (w->hscroll),
+                              -1, w->hscroll,
                               0, w);
          window_scroll_preserve_vpos = posit.vpos;
-         window_scroll_preserve_hpos = posit.hpos + XINT (w->hscroll);
+         window_scroll_preserve_hpos = posit.hpos + w->hscroll;
        }
 
       original_pos = Fcons (make_number (window_scroll_preserve_hpos),
@@ -4651,13 +4631,13 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
        max (0, min (scroll_margin, XINT (w->total_lines) / 4));
 
       set_marker_restricted_both (w->start, w->buffer, pos, pos_byte);
-      w->start_at_line_beg = bolp;
-      w->update_mode_line = Qt;
-      XSETFASTINT (w->last_modified, 0);
-      XSETFASTINT (w->last_overlay_modified, 0);
+      w->start_at_line_beg = !NILP (bolp);
+      w->update_mode_line = 1;
+      w->last_modified = 0;
+      w->last_overlay_modified = 0;
       /* Set force_start so that redisplay_window will run
         the window-scroll-functions.  */
-      w->force_start = Qt;
+      w->force_start = 1;
 
       if (!NILP (Vscroll_preserve_screen_position)
          && (whole || !EQ (Vscroll_preserve_screen_position, Qt)))
@@ -4738,9 +4718,9 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
 static void
 scroll_command (Lisp_Object n, int direction)
 {
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
 
-  xassert (eabs (direction) == 1);
+  eassert (eabs (direction) == 1);
 
   /* If selected window's buffer isn't current, make it current for
      the moment.  But don't screw up if window_scroll gets an error.  */
@@ -4853,7 +4833,7 @@ specifies the window to scroll.  This takes precedence over
 {
   Lisp_Object window;
   struct window *w;
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
 
   window = Fother_window_for_scrolling ();
   w = XWINDOW (window);
@@ -4872,7 +4852,7 @@ specifies the window to scroll.  This takes precedence over
   else
     {
       if (CONSP (arg))
-       arg = Fcar (arg);
+       arg = XCAR (arg);
       CHECK_NUMBER (arg);
       window_scroll (window, XINT (arg), 0, 1);
     }
@@ -4894,17 +4874,11 @@ will not scroll a window to a column less than the value returned
 by this function.  This happens in an interactive call.  */)
   (register Lisp_Object arg, Lisp_Object set_minimum)
 {
-  Lisp_Object result;
-  int hscroll;
   struct window *w = XWINDOW (selected_window);
-
-  if (NILP (arg))
-    XSETFASTINT (arg, window_body_cols (w) - 2);
-  else
-    arg = Fprefix_numeric_value (arg);
-
-  hscroll = XINT (w->hscroll) + XINT (arg);
-  result = Fset_window_hscroll (selected_window, make_number (hscroll));
+  EMACS_INT requested_arg = (NILP (arg)
+                            ? window_body_cols (w) - 2
+                            : XINT (Fprefix_numeric_value (arg)));
+  Lisp_Object result = set_window_hscroll (w, w->hscroll + requested_arg);
 
   if (!NILP (set_minimum))
     w->min_hscroll = w->hscroll;
@@ -4923,17 +4897,11 @@ will not scroll a window to a column less than the value returned
 by this function.  This happens in an interactive call.  */)
   (register Lisp_Object arg, Lisp_Object set_minimum)
 {
-  Lisp_Object result;
-  int hscroll;
   struct window *w = XWINDOW (selected_window);
-
-  if (NILP (arg))
-    XSETFASTINT (arg, window_body_cols (w) - 2);
-  else
-    arg = Fprefix_numeric_value (arg);
-
-  hscroll = XINT (w->hscroll) - XINT (arg);
-  result = Fset_window_hscroll (selected_window, make_number (hscroll));
+  EMACS_INT requested_arg = (NILP (arg)
+                            ? window_body_cols (w) - 2
+                            : XINT (Fprefix_numeric_value (arg)));
+  Lisp_Object result = set_window_hscroll (w, w->hscroll - requested_arg);
 
   if (!NILP (set_minimum))
     w->min_hscroll = w->hscroll;
@@ -5035,7 +5003,7 @@ and redisplay normally--don't erase and redraw the frame.  */)
   struct buffer *buf = XBUFFER (w->buffer);
   struct buffer *obuf = current_buffer;
   int center_p = 0;
-  EMACS_INT charpos, bytepos;
+  ptrdiff_t charpos, bytepos;
   EMACS_INT iarg IF_LINT (= 0);
   int this_scroll_margin;
 
@@ -5100,7 +5068,7 @@ and redisplay normally--don't erase and redraw the frame.  */)
        {
          struct it it;
          struct text_pos pt;
-         int nlines = min (INT_MAX, -iarg);
+         ptrdiff_t nlines = min (PTRDIFF_MAX, -iarg);
          int extra_line_spacing;
          int h = window_box_height (w);
          void *itdata = bidi_shelve_cache ();
@@ -5201,12 +5169,10 @@ and redisplay normally--don't erase and redraw the frame.  */)
   set_marker_both (w->start, w->buffer, charpos, bytepos);
   w->window_end_valid = Qnil;
 
-  w->optional_new_start = Qt;
+  w->optional_new_start = 1;
 
-  if (bytepos == BEGV_BYTE || FETCH_BYTE (bytepos - 1) == '\n')
-    w->start_at_line_beg = Qt;
-  else
-    w->start_at_line_beg = Qnil;
+  w->start_at_line_beg = (bytepos == BEGV_BYTE ||
+                         FETCH_BYTE (bytepos - 1) == '\n');
 
   set_buffer_internal (obuf);
   return Qnil;
@@ -5257,8 +5223,8 @@ zero means top of window, negative means relative to bottom of window.  */)
       int height = window_internal_height (w);
       Fvertical_motion (make_number (- (height / 2)), window);
       set_marker_both (w->start, w->buffer, PT, PT_BYTE);
-      w->start_at_line_beg = Fbolp ();
-      w->force_start = Qt;
+      w->start_at_line_beg = !NILP (Fbolp ());
+      w->force_start = 1;
     }
   else
     Fgoto_char (w->start);
@@ -5384,7 +5350,7 @@ the return value is nil.  Otherwise the value is t.  */)
   Lisp_Object frame;
   Lisp_Object auto_buffer_name;
   FRAME_PTR f;
-  EMACS_INT old_point = -1;
+  ptrdiff_t old_point = -1;
 
   CHECK_WINDOW_CONFIGURATION (configuration);
 
@@ -5501,9 +5467,8 @@ the return value is nil.  Otherwise the value is t.  */)
         really like to do is to free only those matrices not reused
         below.  */
       root_window = XWINDOW (FRAME_ROOT_WINDOW (f));
-      leaf_windows
-       = (struct window **) alloca (count_windows (root_window)
-                                    * sizeof (struct window *));
+      leaf_windows = alloca (count_windows (root_window)
+                            * sizeof *leaf_windows);
       n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
 
       /* Kludge Alert!
@@ -5562,14 +5527,14 @@ the return value is nil.  Otherwise the value is t.  */)
          w->total_lines = p->total_lines;
          w->normal_cols = p->normal_cols;
          w->normal_lines = p->normal_lines;
-         w->hscroll = p->hscroll;
-         w->min_hscroll = p->min_hscroll;
+         w->hscroll = XFASTINT (p->hscroll);
+         w->min_hscroll = XFASTINT (p->min_hscroll);
          w->display_table = p->display_table;
          w->left_margin_cols = p->left_margin_cols;
          w->right_margin_cols = p->right_margin_cols;
          w->left_fringe_width = p->left_fringe_width;
          w->right_fringe_width = p->right_fringe_width;
-         w->fringes_outside_margins = p->fringes_outside_margins;
+         w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
          w->scroll_bar_width = p->scroll_bar_width;
          w->vertical_scroll_bar_type = p->vertical_scroll_bar_type;
          w->dedicated = p->dedicated;
@@ -5596,8 +5561,8 @@ the return value is nil.  Otherwise the value is t.  */)
                }
            }
 
-         XSETFASTINT (w->last_modified, 0);
-         XSETFASTINT (w->last_overlay_modified, 0);
+         w->last_modified = 0;
+         w->last_overlay_modified = 0;
 
          /* Reinstall the saved buffer and pointers into it.  */
          if (NILP (p->buffer))
@@ -5607,7 +5572,7 @@ the return value is nil.  Otherwise the value is t.  */)
            /* If saved buffer is alive, install it.  */
            {
              w->buffer = p->buffer;
-             w->start_at_line_beg = p->start_at_line_beg;
+             w->start_at_line_beg = !NILP (p->start_at_line_beg);
              set_marker_restricted (w->start, p->start, w->buffer);
              set_marker_restricted (w->pointm, p->pointm, w->buffer);
              Fset_marker (BVAR (XBUFFER (w->buffer), mark),
@@ -5632,7 +5597,7 @@ the return value is nil.  Otherwise the value is t.  */)
                set_marker_restricted_both (w->pointm, w->buffer,
                                            BUF_PT (XBUFFER (w->buffer)),
                                            BUF_PT_BYTE (XBUFFER (w->buffer)));
-             w->start_at_line_beg = Qt;
+             w->start_at_line_beg = 1;
            }
          else if (STRINGP (auto_buffer_name =
                            Fwindow_parameter (window, Qauto_buffer_name))
@@ -5641,7 +5606,7 @@ the return value is nil.  Otherwise the value is t.  */)
            {
              set_marker_restricted (w->start, make_number (0), w->buffer);
              set_marker_restricted (w->pointm, make_number (0), w->buffer);
-             w->start_at_line_beg = Qt;
+             w->start_at_line_beg = 1;
            }
          else
            /* Window has no live buffer, get one.  */
@@ -5655,7 +5620,7 @@ the return value is nil.  Otherwise the value is t.  */)
                 range.  */
              set_marker_restricted (w->start, make_number (0), w->buffer);
              set_marker_restricted (w->pointm, make_number (0), w->buffer);
-             w->start_at_line_beg = Qt;
+             w->start_at_line_beg = 1;
              if (!NILP (w->dedicated))
                /* Record this window as dead.  */
                dead_windows = Fcons (window, dead_windows);
@@ -5707,7 +5672,7 @@ the return value is nil.  Otherwise the value is t.  */)
          if (NILP (leaf_windows[i]->buffer))
            {
              /* Assert it's not reused as a combination.  */
-             xassert (NILP (leaf_windows[i]->hchild)
+             eassert (NILP (leaf_windows[i]->hchild)
                       && NILP (leaf_windows[i]->vchild));
              free_window_matrices (leaf_windows[i]);
            }
@@ -5836,7 +5801,7 @@ get_phys_cursor_glyph (struct window *w)
   if (!row->enabled_p)
     return NULL;
 
-  if (XINT (w->hscroll))
+  if (w->hscroll)
     {
       /* When the window is hscrolled, cursor hpos can legitimately be
         out of bounds, but we draw the cursor at the corresponding
@@ -5878,14 +5843,14 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
       p->total_lines = w->total_lines;
       p->normal_cols = w->normal_cols;
       p->normal_lines = w->normal_lines;
-      p->hscroll = w->hscroll;
-      p->min_hscroll = w->min_hscroll;
+      XSETFASTINT (p->hscroll, w->hscroll);
+      XSETFASTINT (p->min_hscroll, w->min_hscroll);
       p->display_table = w->display_table;
       p->left_margin_cols = w->left_margin_cols;
       p->right_margin_cols = w->right_margin_cols;
       p->left_fringe_width = w->left_fringe_width;
       p->right_fringe_width = w->right_fringe_width;
-      p->fringes_outside_margins = w->fringes_outside_margins;
+      p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil;
       p->scroll_bar_width = w->scroll_bar_width;
       p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
       p->dedicated = w->dedicated;
@@ -5944,17 +5909,16 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
             is the selected window, then get the value of point from
             the buffer; pointm is garbage in the selected window.  */
          if (EQ (window, selected_window))
-           {
-             p->pointm = Fmake_marker ();
-             set_marker_both (p->pointm, w->buffer,
-                              BUF_PT (XBUFFER (w->buffer)),
-                              BUF_PT_BYTE (XBUFFER (w->buffer)));
-           }
+           p->pointm = build_marker (XBUFFER (w->buffer),
+                                     BUF_PT (XBUFFER (w->buffer)),
+                                     BUF_PT_BYTE (XBUFFER (w->buffer)));
          else
            p->pointm = Fcopy_marker (w->pointm, Qnil);
+         XMARKER (p->pointm)->insertion_type
+           = !NILP (Vwindow_point_insertion_type);
 
          p->start = Fcopy_marker (w->start, Qnil);
-         p->start_at_line_beg = w->start_at_line_beg;
+         p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil;
 
          tem = BVAR (XBUFFER (w->buffer), mark);
          p->mark = Fcopy_marker (tem, Qnil);
@@ -6029,8 +5993,8 @@ saved by this function.  */)
   tem = Fmake_vector (make_number (n_windows), Qnil);
   data->saved_windows = tem;
   for (i = 0; i < n_windows; i++)
-    XVECTOR (tem)->contents[i]
-      = Fmake_vector (make_number (VECSIZE (struct saved_window)), Qnil);
+    ASET (tem, i,
+         Fmake_vector (make_number (VECSIZE (struct saved_window)), Qnil));
   save_window_save (FRAME_ROOT_WINDOW (f), XVECTOR (tem), 0);
   XSETWINDOW_CONFIGURATION (tem, data);
   return (tem);
@@ -6120,6 +6084,7 @@ display marginal areas and the text area.  */)
   (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width, Lisp_Object outside_margins)
 {
   struct window *w = decode_window (window);
+  int outside = !NILP (outside_margins);
 
   if (!NILP (left_width))
     CHECK_NATNUM (left_width);
@@ -6130,11 +6095,11 @@ display marginal areas and the text area.  */)
   if (FRAME_WINDOW_P (WINDOW_XFRAME (w))
       && (!EQ (w->left_fringe_width, left_width)
          || !EQ (w->right_fringe_width, right_width)
-         || !EQ (w->fringes_outside_margins, outside_margins)))
+         || w->fringes_outside_margins != outside))
     {
       w->left_fringe_width = left_width;
       w->right_fringe_width = right_width;
-      w->fringes_outside_margins = outside_margins;
+      w->fringes_outside_margins = outside;
 
       adjust_window_margins (w);
 
@@ -6187,7 +6152,7 @@ Fourth parameter HORIZONTAL-TYPE is currently unused.  */)
 
   if (!NILP (width))
     {
-      CHECK_NATNUM (width);
+      CHECK_RANGED_INTEGER (width, 0, INT_MAX);
 
       if (XINT (width) == 0)
        vertical_type = Qnil;