]> code.delx.au - gnu-emacs/blobdiff - src/window.c
Have 'make' output better GEN names
[gnu-emacs] / src / window.c
index ae28b7147208f7b7a237fafe5ee8461b54173928..1d2221fd9b22c9faf99654c5854a44c76cfb2c44 100644 (file)
@@ -1,6 +1,6 @@
 /* Window creation, deletion and examination for GNU Emacs.
    Does not include redisplay.
 /* Window creation, deletion and examination for GNU Emacs.
    Does not include redisplay.
-   Copyright (C) 1985-1987, 1993-1998, 2000-2014 Free Software
+   Copyright (C) 1985-1987, 1993-1998, 2000-2015 Free Software
    Foundation, Inc.
 
 This file is part of GNU Emacs.
    Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -45,20 +45,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "msdos.h"
 #endif
 
 #include "msdos.h"
 #endif
 
-Lisp_Object Qwindowp, Qwindow_live_p;
-static Lisp_Object Qwindow_valid_p;
-static Lisp_Object Qwindow_configuration_p;
-static Lisp_Object Qrecord_window_buffer;
-static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
-static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
-static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically;
-static Lisp_Object Qwindow_sanitize_window_sizes;
-static Lisp_Object Qwindow_pixel_to_total;
-static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
-static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
-static Lisp_Object Qfloor, Qceiling;
-static Lisp_Object Qwindow_point_insertion_type;
-
 static int displayed_window_lines (struct window *);
 static int count_windows (struct window *);
 static int get_leaf_windows (struct window *, struct window **, int);
 static int displayed_window_lines (struct window *);
 static int count_windows (struct window *);
 static int get_leaf_windows (struct window *, struct window **, int);
@@ -115,15 +101,9 @@ Lisp_Object minibuf_window;
    shown as the selected window when the minibuffer is selected.  */
 Lisp_Object minibuf_selected_window;
 
    shown as the selected window when the minibuffer is selected.  */
 Lisp_Object minibuf_selected_window;
 
-/* Hook run at end of temp_output_buffer_show.  */
-static Lisp_Object Qtemp_buffer_show_hook;
-
 /* Incremented for each window created.  */
 static int sequence_number;
 
 /* Incremented for each window created.  */
 static int sequence_number;
 
-/* Hook to run when window config changes.  */
-static Lisp_Object Qwindow_configuration_change_hook;
-
 /* Used by the function window_scroll_pixel_based.  */
 static int window_scroll_pixel_based_preserve_x;
 static int window_scroll_pixel_based_preserve_y;
 /* Used by the function window_scroll_pixel_based.  */
 static int window_scroll_pixel_based_preserve_x;
 static int window_scroll_pixel_based_preserve_y;
@@ -329,7 +309,7 @@ DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
 DEFUN ("window-valid-p", Fwindow_valid_p, Swindow_valid_p, 1, 1, 0,
        doc: /* Return t if OBJECT is a valid window and nil otherwise.
 A valid window is either a window that displays a buffer or an internal
 DEFUN ("window-valid-p", Fwindow_valid_p, Swindow_valid_p, 1, 1, 0,
        doc: /* Return t if OBJECT is a valid window and nil otherwise.
 A valid window is either a window that displays a buffer or an internal
-window.  Deleted windows are not live.  */)
+window.  Windows that have been deleted are not valid.  */)
   (Lisp_Object object)
 {
   return WINDOW_VALID_P (object) ? Qt : Qnil;
   (Lisp_Object object)
 {
   return WINDOW_VALID_P (object) ? Qt : Qnil;
@@ -810,7 +790,12 @@ total width of WINDOW.  */)
 
 DEFUN ("window-new-total", Fwindow_new_total, Swindow_new_total, 0, 1, 0,
        doc: /* Return the new total size of window WINDOW.
 
 DEFUN ("window-new-total", Fwindow_new_total, Swindow_new_total, 0, 1, 0,
        doc: /* Return the new total size of window WINDOW.
-WINDOW must be a valid window and defaults to the selected one.  */)
+WINDOW must be a valid window and defaults to the selected one.
+
+The new total size of WINDOW is the value set by the last call of
+`set-window-new-total' for WINDOW.  If it is valid, it will be shortly
+installed as WINDOW's total height (see `window-total-height') or total
+width (see `window-total-width').  */)
   (Lisp_Object window)
 {
   return decode_valid_window (window)->new_total;
   (Lisp_Object window)
 {
   return decode_valid_window (window)->new_total;
@@ -819,7 +804,25 @@ WINDOW must be a valid window and defaults to the selected one.  */)
 DEFUN ("window-normal-size", Fwindow_normal_size, Swindow_normal_size, 0, 2, 0,
        doc: /* Return the normal height of window WINDOW.
 WINDOW must be a valid window and defaults to the selected one.
 DEFUN ("window-normal-size", Fwindow_normal_size, Swindow_normal_size, 0, 2, 0,
        doc: /* Return the normal height of window WINDOW.
 WINDOW must be a valid window and defaults to the selected one.
-If HORIZONTAL is non-nil, return the normal width of WINDOW.  */)
+If HORIZONTAL is non-nil, return the normal width of WINDOW.
+
+The normal height of a frame's root window or a window that is
+horizontally combined (a window that has a left or right sibling) is
+1.0.  The normal height of a window that is vertically combined (has a
+sibling above or below) is the fraction of the window's height with
+respect to its parent.  The sum of the normal heights of all windows in a
+vertical combination equals 1.0.
+
+Similarly, the normal width of a frame's root window or a window that is
+vertically combined equals 1.0.  The normal width of a window that is
+horizontally combined is the fraction of the window's width with respect
+to its parent.  The sum of the normal widths of all windows in a
+horizontal combination equals 1.0.
+
+The normal sizes of windows are used to restore the proportional sizes
+of windows after they have been shrunk to their minimum sizes; for
+example when a frame is temporarily made very small and afterwards gets
+re-enlarged to its previous size.  */)
   (Lisp_Object window, Lisp_Object horizontal)
 {
   struct window *w = decode_valid_window (window);
   (Lisp_Object window, Lisp_Object horizontal)
 {
   struct window *w = decode_valid_window (window);
@@ -829,7 +832,11 @@ If HORIZONTAL is non-nil, return the normal width of WINDOW.  */)
 
 DEFUN ("window-new-normal", Fwindow_new_normal, Swindow_new_normal, 0, 1, 0,
        doc: /* Return new normal size of window WINDOW.
 
 DEFUN ("window-new-normal", Fwindow_new_normal, Swindow_new_normal, 0, 1, 0,
        doc: /* Return new normal size of window WINDOW.
-WINDOW must be a valid window and defaults to the selected one.  */)
+WINDOW must be a valid window and defaults to the selected one.
+
+The new normal size of WINDOW is the value set by the last call of
+`set-window-new-normal' for WINDOW.  If valid, it will be shortly
+installed as WINDOW's normal size (see `window-normal-size').  */)
   (Lisp_Object window)
 {
   return decode_valid_window (window)->new_normal;
   (Lisp_Object window)
 {
   return decode_valid_window (window)->new_normal;
@@ -837,7 +844,12 @@ WINDOW must be a valid window and defaults to the selected one.  */)
 
 DEFUN ("window-new-pixel", Fwindow_new_pixel, Swindow_new_pixel, 0, 1, 0,
        doc: /* Return new pixel size of window WINDOW.
 
 DEFUN ("window-new-pixel", Fwindow_new_pixel, Swindow_new_pixel, 0, 1, 0,
        doc: /* Return new pixel size of window WINDOW.
-WINDOW must be a valid window and defaults to the selected one.  */)
+WINDOW must be a valid window and defaults to the selected one.
+
+The new pixel size of WINDOW is the value set by the last call of
+`set-window-new-pixel' for WINDOW.  If it is valid, it will be shortly
+installed as WINDOW's pixel height (see `window-pixel-height') or pixel
+width (see `window-pixel-width').  */)
   (Lisp_Object window)
 {
   return decode_valid_window (window)->new_pixel;
   (Lisp_Object window)
 {
   return decode_valid_window (window)->new_pixel;
@@ -962,7 +974,10 @@ or scroll bars.
 If PIXELWISE is nil, return the largest integer smaller than WINDOW's
 pixel width divided by the character width of WINDOW's frame.  This
 means that if a column at the right of the text area is only partially
 If PIXELWISE is nil, return the largest integer smaller than WINDOW's
 pixel width divided by the character width of WINDOW's frame.  This
 means that if a column at the right of the text area is only partially
-visible, that column is not counted.  */)
+visible, that column is not counted.
+
+Note that the returned value includes the column reserved for the
+continuation glyph.  */)
   (Lisp_Object window, Lisp_Object pixelwise)
 {
   return make_number (window_body_width (decode_live_window (window),
   (Lisp_Object window, Lisp_Object pixelwise)
 {
   return make_number (window_body_width (decode_live_window (window),
@@ -2982,6 +2997,14 @@ resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizonta
   return call5 (Qwindow_resize_root_window, window, delta, horizontal, ignore, pixelwise);
 }
 
   return call5 (Qwindow_resize_root_window, window, delta, horizontal, ignore, pixelwise);
 }
 
+/* Placeholder used by temacs -nw before window.el is loaded.  */
+DEFUN ("window--sanitize-window-sizes", Fwindow__sanitize_window_sizes,
+       Swindow__sanitize_window_sizes, 2, 2, 0,
+       doc: /* */)
+     (Lisp_Object frame, Lisp_Object horizontal)
+{
+  return Qnil;
+}
 
 Lisp_Object
 sanitize_window_sizes (Lisp_Object frame, Lisp_Object horizontal)
 
 Lisp_Object
 sanitize_window_sizes (Lisp_Object frame, Lisp_Object horizontal)
@@ -3305,7 +3328,9 @@ run_window_configuration_change_hook (struct frame *f)
     = Fdefault_value (Qwindow_configuration_change_hook);
   XSETFRAME (frame, f);
 
     = Fdefault_value (Qwindow_configuration_change_hook);
   XSETFRAME (frame, f);
 
-  if (NILP (Vrun_hooks) || !(f->official))
+  if (NILP (Vrun_hooks)
+      || !(f->can_x_set_window_size)
+      || !(f->can_run_window_configuration_change_hook))
     return;
 
   /* Use the right buffer.  Matters when running the local hooks.  */
     return;
 
   /* Use the right buffer.  Matters when running the local hooks.  */
@@ -3611,7 +3636,7 @@ temp_output_buffer_show (register Lisp_Object buf)
         record_unwind_protect (select_window_norecord, prev_window);
         Fselect_window (window, Qt);
         Fset_buffer (w->contents);
         record_unwind_protect (select_window_norecord, prev_window);
         Fselect_window (window, Qt);
         Fset_buffer (w->contents);
-        Frun_hooks (1, &Qtemp_buffer_show_hook);
+        run_hook (Qtemp_buffer_show_hook);
         unbind_to (count, Qnil);
       }
     }
         unbind_to (count, Qnil);
       }
     }
@@ -3705,6 +3730,10 @@ Return SIZE.
 Optional argument ADD non-nil means add SIZE to the new pixel size of
 WINDOW and return the sum.
 
 Optional argument ADD non-nil means add SIZE to the new pixel size of
 WINDOW and return the sum.
 
+The new pixel size of WINDOW, if valid, will be shortly installed as
+WINDOW's pixel height (see `window-pixel-height') or pixel width (see
+`window-pixel-width').
+
 Note: This function does not operate on any child windows of WINDOW.  */)
   (Lisp_Object window, Lisp_Object size, Lisp_Object add)
 {
 Note: This function does not operate on any child windows of WINDOW.  */)
   (Lisp_Object window, Lisp_Object size, Lisp_Object add)
 {
@@ -3729,6 +3758,10 @@ Return SIZE.
 Optional argument ADD non-nil means add SIZE to the new total size of
 WINDOW and return the sum.
 
 Optional argument ADD non-nil means add SIZE to the new total size of
 WINDOW and return the sum.
 
+The new total size of WINDOW, if valid, will be shortly installed as
+WINDOW's total height (see `window-total-height') or total width (see
+`window-total-width').
+
 Note: This function does not operate on any child windows of WINDOW.  */)
      (Lisp_Object window, Lisp_Object size, Lisp_Object add)
 {
 Note: This function does not operate on any child windows of WINDOW.  */)
      (Lisp_Object window, Lisp_Object size, Lisp_Object add)
 {
@@ -3748,6 +3781,9 @@ DEFUN ("set-window-new-normal", Fset_window_new_normal, Sset_window_new_normal,
 WINDOW must be a valid window and defaults to the selected one.
 Return SIZE.
 
 WINDOW must be a valid window and defaults to the selected one.
 Return SIZE.
 
+The new normal size of WINDOW, if valid, will be shortly installed as
+WINDOW's normal size (see `window-normal-size').
+
 Note: This function does not operate on any child windows of WINDOW.  */)
      (Lisp_Object window, Lisp_Object size)
 {
 Note: This function does not operate on any child windows of WINDOW.  */)
      (Lisp_Object window, Lisp_Object size)
 {
@@ -3854,7 +3890,7 @@ window_resize_check (struct window *w, bool horflag)
 }
 
 
 }
 
 
-/* Set w->pixel_height (w->pixel_height if HORIZONTAL is non-zero) to
+/* Set w->pixel_height (w->pixel_width if HORFLAG is non-zero) to
    w->new_pixel for window W and recursively all child windows of W.
    Also calculate and assign the new vertical (horizontal) pixel start
    positions of each of these windows.
    w->new_pixel for window W and recursively all child windows of W.
    Also calculate and assign the new vertical (horizontal) pixel start
    positions of each of these windows.
@@ -3944,7 +3980,7 @@ window_resize_apply (struct window *w, bool horflag)
 }
 
 
 }
 
 
-/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to
+/* Set w->total_lines (w->total_cols if HORFLAG is non-zero) to
    w->new_total for window W and recursively all child windows of W.
    Also calculate and assign the new vertical (horizontal) start
    positions of each of these windows.  */
    w->new_total for window W and recursively all child windows of W.
    Also calculate and assign the new vertical (horizontal) start
    positions of each of these windows.  */
@@ -4012,9 +4048,14 @@ If FRAME is omitted or nil, it defaults to the selected frame.
 Optional argument HORIZONTAL omitted or nil means apply requested
 height values.  HORIZONTAL non-nil means apply requested width values.
 
 Optional argument HORIZONTAL omitted or nil means apply requested
 height values.  HORIZONTAL non-nil means apply requested width values.
 
-This function checks whether the requested values sum up to a valid
-window layout, recursively assigns the new sizes of all child windows
-and calculates and assigns the new start positions of these windows.
+The requested size values are those set by `set-window-new-pixel' and
+`set-window-new-normal'.  This function checks whether the requested
+values sum up to a valid window layout, recursively assigns the new
+sizes of all child windows and calculates and assigns the new start
+positions of these windows.
+
+Return t if the requested values have been applied correctly, nil
+otherwise.
 
 Note: This function does not check any of `window-fixed-size-p',
 `window-min-height' or `window-min-width'.  All these checks have to
 
 Note: This function does not check any of `window-fixed-size-p',
 `window-min-height' or `window-min-width'.  All these checks have to
@@ -4085,11 +4126,7 @@ values.  */)
 
 /* Resize frame F's windows when number of lines of F is set to SIZE.
    HORFLAG 1 means resize windows when number of columns of F is set to
 
 /* Resize frame F's windows when number of lines of F is set to SIZE.
    HORFLAG 1 means resize windows when number of columns of F is set to
-   SIZE.  PIXELWISE 1 means to interpret SIZE as pixels.
-
-   This function can delete all windows but the selected one in order to
-   satisfy the request.  The result will be meaningful if and only if
-   F's windows have meaningful sizes when you call this.  */
+   SIZE.  PIXELWISE 1 means to interpret SIZE as pixels.  */
 void
 resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
 {
 void
 resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
 {
@@ -4115,7 +4152,6 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
       new_pixel_size = max (horflag
                            ? size
                            : (size
       new_pixel_size = max (horflag
                            ? size
                            : (size
-/**                           - FRAME_TOP_MARGIN_HEIGHT (f) **/
                               - ((FRAME_HAS_MINIBUF_P (f)
                                   && !FRAME_MINIBUF_ONLY_P (f))
                                  ? FRAME_LINE_HEIGHT (f) : 0)),
                               - ((FRAME_HAS_MINIBUF_P (f)
                                   && !FRAME_MINIBUF_ONLY_P (f))
                                  ? FRAME_LINE_HEIGHT (f) : 0)),
@@ -4127,7 +4163,6 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
       new_size = max (horflag
                      ? size
                      : (size
       new_size = max (horflag
                      ? size
                      : (size
-/**                     - FRAME_TOP_MARGIN (f) **/
                         - ((FRAME_HAS_MINIBUF_P (f)
                             && !FRAME_MINIBUF_ONLY_P (f))
                            ? 1 : 0)),
                         - ((FRAME_HAS_MINIBUF_P (f)
                             && !FRAME_MINIBUF_ONLY_P (f))
                            ? 1 : 0)),
@@ -4748,10 +4783,10 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
       block_input ();
       window_resize_apply (r, 0);
 
       block_input ();
       window_resize_apply (r, 0);
 
-      w->total_lines = XFASTINT (w->new_total);
-      w->top_line = r->top_line + r->total_lines;
       w->pixel_height = XFASTINT (w->new_pixel);
       w->pixel_height = XFASTINT (w->new_pixel);
+      w->total_lines = w->pixel_height / FRAME_LINE_HEIGHT (f);
       w->pixel_top = r->pixel_top + r->pixel_height;
       w->pixel_top = r->pixel_top + r->pixel_height;
+      w->top_line = r->top_line + r->total_lines;
 
       fset_redisplay (f);
       FRAME_WINDOW_SIZES_CHANGED (f) = 1;
 
       fset_redisplay (f);
       FRAME_WINDOW_SIZES_CHANGED (f) = 1;
@@ -4821,11 +4856,16 @@ window_internal_height (struct window *w)
 static void
 window_scroll (Lisp_Object window, EMACS_INT n, bool whole, int noerror)
 {
 static void
 window_scroll (Lisp_Object window, EMACS_INT n, bool whole, int noerror)
 {
+  ptrdiff_t count = SPECPDL_INDEX ();
+
   immediate_quit = 1;
   n = clip_to_bounds (INT_MIN, n, INT_MAX);
 
   wset_redisplay (XWINDOW (window));
 
   immediate_quit = 1;
   n = clip_to_bounds (INT_MIN, n, INT_MAX);
 
   wset_redisplay (XWINDOW (window));
 
+  if (whole && Vfast_but_imprecise_scrolling)
+    specbind (Qfontification_functions, Qnil);
+
   /* If we must, use the pixel-based version which is much slower than
      the line-based one but can handle varying line heights.  */
   if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame)))
   /* If we must, use the pixel-based version which is much slower than
      the line-based one but can handle varying line heights.  */
   if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame)))
@@ -4833,6 +4873,8 @@ window_scroll (Lisp_Object window, EMACS_INT n, bool whole, int noerror)
   else
     window_scroll_line_based (window, n, whole, noerror);
 
   else
     window_scroll_line_based (window, n, whole, noerror);
 
+  unbind_to (count, Qnil);
+
   /* Bug#15957.  */
   XWINDOW (window)->window_end_valid = 0;
   immediate_quit = 0;
   /* Bug#15957.  */
   XWINDOW (window)->window_end_valid = 0;
   immediate_quit = 0;
@@ -4884,8 +4926,8 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
       /* The function move_iterator_vertically may move over more than
         the specified y-distance.  If it->w is small, e.g. a
         mini-buffer window, we may end up in front of the window's
       /* The function move_iterator_vertically may move over more than
         the specified y-distance.  If it->w is small, e.g. a
         mini-buffer window, we may end up in front of the window's
-        display area.  This is the case when Start displaying at the
-        start of the line containing PT in this case.  */
+        display area.  Start displaying at the start of the line
+        containing PT in this case.  */
       if (it.current_y <= 0)
        {
          init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
       if (it.current_y <= 0)
        {
          init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
@@ -4902,9 +4944,14 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
        {
          int px;
          int dy = frame_line_height;
        {
          int px;
          int dy = frame_line_height;
+         /* In the below we divide the window box height by the
+            frame's line height to make the result predictable when
+            the window box is not an integral multiple of the line
+            height.  This is important to ensure we get back to the
+            same position when scrolling up, then down.  */
          if (whole)
          if (whole)
-           dy = max ((window_box_height (w)
-                      - next_screen_context_lines * dy),
+           dy = max ((window_box_height (w) / dy
+                      - next_screen_context_lines) * dy,
                      dy);
          dy *= n;
 
                      dy);
          dy *= n;
 
@@ -4986,9 +5033,12 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
     {
       ptrdiff_t start_pos = IT_CHARPOS (it);
       int dy = frame_line_height;
     {
       ptrdiff_t start_pos = IT_CHARPOS (it);
       int dy = frame_line_height;
-
-      dy = max ((window_box_height (w)
-                - next_screen_context_lines * dy),
+      /* In the below we divide the window box height by the frame's
+        line height to make the result predictable when the window
+        box is not an integral multiple of the line height.  This is
+        important to ensure we get back to the same position when
+        scrolling up, then down.  */
+      dy = max ((window_box_height (w) / dy - next_screen_context_lines) * dy,
                dy) * n;
 
       /* Note that move_it_vertically always moves the iterator to the
                dy) * n;
 
       /* Note that move_it_vertically always moves the iterator to the
@@ -5868,6 +5918,8 @@ and redisplay normally--don't erase and redraw the frame.  */)
   w->start_at_line_beg = (bytepos == BEGV_BYTE
                          || FETCH_BYTE (bytepos - 1) == '\n');
 
   w->start_at_line_beg = (bytepos == BEGV_BYTE
                          || FETCH_BYTE (bytepos - 1) == '\n');
 
+  wset_redisplay (w);
+
   return Qnil;
 }
 
   return Qnil;
 }
 
@@ -6076,6 +6128,7 @@ the return value is nil.  Otherwise the value is t.  */)
   Lisp_Object frame;
   struct frame *f;
   ptrdiff_t old_point = -1;
   Lisp_Object frame;
   struct frame *f;
   ptrdiff_t old_point = -1;
+  USE_SAFE_ALLOCA;
 
   CHECK_WINDOW_CONFIGURATION (configuration);
 
 
   CHECK_WINDOW_CONFIGURATION (configuration);
 
@@ -6155,8 +6208,8 @@ the return value is nil.  Otherwise the value is t.  */)
            call1 (Qrecord_window_buffer, window);
        }
 
            call1 (Qrecord_window_buffer, window);
        }
 
-      /* Consider frame unofficial, temporarily.  */
-      f->official = false;
+      /* Disallow x_set_window_size, temporarily.  */
+      f->can_x_set_window_size = false;
       /* The mouse highlighting code could get screwed up
         if it runs during this.  */
       block_input ();
       /* The mouse highlighting code could get screwed up
         if it runs during this.  */
       block_input ();
@@ -6183,8 +6236,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));
         really like to do is to free only those matrices not reused
         below.  */
       root_window = XWINDOW (FRAME_ROOT_WINDOW (f));
-      leaf_windows = alloca (count_windows (root_window)
-                            * sizeof *leaf_windows);
+      int nwindows = count_windows (root_window);
+      SAFE_NALLOCA (leaf_windows, 1, nwindows);
       n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
 
       /* Kludge Alert!
       n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
 
       /* Kludge Alert!
@@ -6365,10 +6418,10 @@ the return value is nil.  Otherwise the value is t.  */)
            ++n;
        }
 
            ++n;
        }
 
-      /* Make frame official again and apply frame size changes if
+      /* Allow x_set_window_size again and apply frame size changes if
         needed.  */
         needed.  */
-      f->official = true;
-      adjust_frame_size (f, -1, -1, 1, 0);
+      f->can_x_set_window_size = true;
+      adjust_frame_size (f, -1, -1, 1, 0, Qnil);
 
       adjust_frame_glyphs (f);
       unblock_input ();
 
       adjust_frame_glyphs (f);
       unblock_input ();
@@ -6408,424 +6461,11 @@ the return value is nil.  Otherwise the value is t.  */)
   Vminibuf_scroll_window = data->minibuf_scroll_window;
   minibuf_selected_window = data->minibuf_selected_window;
 
   Vminibuf_scroll_window = data->minibuf_scroll_window;
   minibuf_selected_window = data->minibuf_selected_window;
 
+  SAFE_FREE ();
   return (FRAME_LIVE_P (f) ? Qt : Qnil);
 }
 
 
   return (FRAME_LIVE_P (f) ? Qt : Qnil);
 }
 
 
-#if 0
-DEFUN ("set-window-configuration", Fset_window_configuration,
-       Sset_window_configuration, 1, 1, 0,
-       doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
-CONFIGURATION must be a value previously returned
-by `current-window-configuration' (which see).
-If CONFIGURATION was made from a frame that is now deleted,
-only frame-independent values can be restored.  In this case,
-the return value is nil.  Otherwise the value is t.  */)
-  (Lisp_Object configuration)
-{
-  register struct save_window_data *data;
-  struct Lisp_Vector *saved_windows;
-  Lisp_Object new_current_buffer;
-  Lisp_Object frame;
-  struct frame *f;
-  ptrdiff_t old_point = -1;
-
-  CHECK_WINDOW_CONFIGURATION (configuration);
-
-  data = (struct save_window_data *) XVECTOR (configuration);
-  saved_windows = XVECTOR (data->saved_windows);
-
-  new_current_buffer = data->current_buffer;
-  if (!BUFFER_LIVE_P (XBUFFER (new_current_buffer)))
-    new_current_buffer = Qnil;
-  else
-    {
-      if (XBUFFER (new_current_buffer) == current_buffer)
-       /* The code further down "preserves point" by saving here PT in
-          old_point and then setting it later back into PT.  When the
-          current-selected-window and the final-selected-window both show
-          the current buffer, this suffers from the problem that the
-          current PT is the window-point of the current-selected-window,
-          while the final PT is the point of the final-selected-window, so
-          this copy from one PT to the other would end up moving the
-          window-point of the final-selected-window to the window-point of
-          the current-selected-window.  So we have to be careful which
-          point of the current-buffer we copy into old_point.  */
-       if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
-           && WINDOWP (selected_window)
-           && EQ (XWINDOW (selected_window)->contents, new_current_buffer)
-           && !EQ (selected_window, data->current_window))
-         old_point = marker_position (XWINDOW (data->current_window)->pointm);
-       else
-         old_point = PT;
-      else
-       /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of
-          point in new_current_buffer as of the last time this buffer was
-          used.  This can be non-deterministic since it can be changed by
-          things like jit-lock by mere temporary selection of some random
-          window that happens to show this buffer.
-          So if possible we want this arbitrary choice of "which point" to
-          be the one from the to-be-selected-window so as to prevent this
-          window's cursor from being copied from another window.  */
-       if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
-           /* If current_window = selected_window, its point is in BUF_PT.  */
-           && !EQ (selected_window, data->current_window))
-         old_point = marker_position (XWINDOW (data->current_window)->pointm);
-       else
-         old_point = BUF_PT (XBUFFER (new_current_buffer));
-    }
-
-  frame = XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
-  f = XFRAME (frame);
-
-  /* If f is a dead frame, don't bother rebuilding its window tree.
-     However, there is other stuff we should still try to do below.  */
-  if (FRAME_LIVE_P (f))
-    {
-      Lisp_Object window;
-      Lisp_Object dead_windows = Qnil;
-      register Lisp_Object tem, par, pers;
-      register struct window *w;
-      register struct saved_window *p;
-      struct window *root_window;
-      struct window **leaf_windows;
-      int n_leaf_windows;
-      ptrdiff_t k;
-      int i, n;
-      ptrdiff_t count = SPECPDL_INDEX ();
-      /* If the frame has been resized since this window configuration was
-        made, we change the frame to the size specified in the
-        configuration, restore the configuration, and then resize it
-        back.  We keep track of the prevailing height in these variables.  */
-      int previous_frame_text_height = FRAME_TEXT_HEIGHT (f);
-      int previous_frame_text_width =  FRAME_TEXT_WIDTH  (f);
-      /* int previous_frame_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f); */
-      /* int previous_frame_tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f); */
-      /* int previous_frame_lines = FRAME_LINES (f); */
-      /* int previous_frame_cols =  FRAME_COLS  (f); */
-      int previous_frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
-      int previous_frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
-
-      /* Don't do this within the main loop below: This may call Lisp
-        code and is thus potentially unsafe while input is blocked.  */
-      for (k = 0; k < saved_windows->header.size; k++)
-       {
-         p = SAVED_WINDOW_N (saved_windows, k);
-         window = p->window;
-         w = XWINDOW (window);
-         if (BUFFERP (w->contents)
-             && !EQ (w->contents, p->buffer)
-             && BUFFER_LIVE_P (XBUFFER (p->buffer)))
-           /* If a window we restore gets another buffer, record the
-              window's old buffer.  */
-           call1 (Qrecord_window_buffer, window);
-       }
-
-      /* Consider frame unofficial, temporarily.  */
-      f->official = false;
-      /* The mouse highlighting code could get screwed up
-        if it runs during this.  */
-      block_input ();
-
-      if (data->frame_text_width != previous_frame_text_width
-         || data->frame_text_height != previous_frame_text_height)
-       /* Make frame size fit the one in data, so window sizes restored
-          from data match those of the frame.  */
-       adjust_frame_size (f, data->frame_text_width,
-                          data->frame_text_height, 5, 0);
-
-      if (data->frame_menu_bar_lines != previous_frame_menu_bar_lines)
-       {
-#ifdef HAVE_WINDOW_SYSTEM
-         if (FRAME_WINDOW_P (f))
-           x_set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines),
-                                 make_number (0));
-         else  /* TTY or MSDOS */
-#endif
-           set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines),
-                               make_number (0));
-       }
-#ifdef HAVE_WINDOW_SYSTEM
-      if (data->frame_tool_bar_lines != previous_frame_tool_bar_lines)
-       x_set_tool_bar_lines (f, make_number (data->frame_tool_bar_lines),
-                             make_number (0));
-#endif
-
-      /* "Swap out" point from the selected window's buffer
-        into the window itself.  (Normally the pointm of the selected
-        window holds garbage.)  We do this now, before
-        restoring the window contents, and prevent it from
-        being done later on when we select a new window.  */
-      if (! NILP (XWINDOW (selected_window)->contents))
-       {
-         w = XWINDOW (selected_window);
-         set_marker_both (w->pointm,
-                          w->contents,
-                          BUF_PT (XBUFFER (w->contents)),
-                          BUF_PT_BYTE (XBUFFER (w->contents)));
-       }
-
-      fset_redisplay (f);
-      FRAME_WINDOW_SIZES_CHANGED (f) = 1;
-
-      /* Problem: Freeing all matrices and later allocating them again
-        is a serious redisplay flickering problem.  What we would
-        really like to do is to free only those matrices not reused
-        below.  */
-      root_window = XWINDOW (FRAME_ROOT_WINDOW (f));
-      leaf_windows = alloca (count_windows (root_window)
-                            * sizeof *leaf_windows);
-      n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
-
-      /* Kludge Alert!
-        Mark all windows now on frame as "deleted".
-        Restoring the new configuration "undeletes" any that are in it.
-
-        Save their current buffers in their height fields, since we may
-        need it later, if a buffer saved in the configuration is now
-        dead.  */
-      delete_all_child_windows (FRAME_ROOT_WINDOW (f));
-
-      for (k = 0; k < saved_windows->header.size; k++)
-       {
-         p = SAVED_WINDOW_N (saved_windows, k);
-         window = p->window;
-         w = XWINDOW (window);
-         wset_next (w, Qnil);
-
-         if (!NILP (p->parent))
-           wset_parent
-             (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->parent))->window);
-         else
-           wset_parent (w, Qnil);
-
-         if (!NILP (p->prev))
-           {
-             wset_prev
-               (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->prev))->window);
-             wset_next (XWINDOW (w->prev), p->window);
-           }
-         else
-           {
-             wset_prev (w, Qnil);
-             if (!NILP (w->parent))
-               wset_combination (XWINDOW (w->parent),
-                                 (XINT (p->total_cols)
-                                  != XWINDOW (w->parent)->total_cols),
-                                 p->window);
-           }
-
-         /* If we squirreled away the buffer, restore it now.  */
-         if (BUFFERP (w->combination_limit))
-           wset_buffer (w, w->combination_limit);
-         w->pixel_left = XFASTINT (p->pixel_left);
-         w->pixel_top = XFASTINT (p->pixel_top);
-         w->pixel_width = XFASTINT (p->pixel_width);
-         w->pixel_height = XFASTINT (p->pixel_height);
-         w->left_col = XFASTINT (p->left_col);
-         w->top_line = XFASTINT (p->top_line);
-         w->total_cols = XFASTINT (p->total_cols);
-         w->total_lines = XFASTINT (p->total_lines);
-         wset_normal_cols (w, p->normal_cols);
-         wset_normal_lines (w, p->normal_lines);
-         w->hscroll = XFASTINT (p->hscroll);
-         w->suspend_auto_hscroll = !NILP (p->suspend_auto_hscroll);
-         w->min_hscroll = XFASTINT (p->min_hscroll);
-         w->hscroll_whole = XFASTINT (p->hscroll_whole);
-         wset_display_table (w, p->display_table);
-         w->left_margin_cols = XINT (p->left_margin_cols);
-         w->right_margin_cols = XINT (p->right_margin_cols);
-         w->left_fringe_width = XINT (p->left_fringe_width);
-         w->right_fringe_width = XINT (p->right_fringe_width);
-         w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
-         w->scroll_bar_width = XINT (p->scroll_bar_width);
-         w->scroll_bar_height = XINT (p->scroll_bar_height);
-         wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type);
-         wset_horizontal_scroll_bar_type (w, p->horizontal_scroll_bar_type);
-         wset_dedicated (w, p->dedicated);
-         wset_combination_limit (w, p->combination_limit);
-         /* Restore any window parameters that have been saved.
-            Parameters that have not been saved are left alone.  */
-         for (tem = p->window_parameters; CONSP (tem); tem = XCDR (tem))
-           {
-             pers = XCAR (tem);
-             if (CONSP (pers))
-               {
-                 if (NILP (XCDR (pers)))
-                   {
-                     par = Fassq (XCAR (pers), w->window_parameters);
-                     if (CONSP (par) && !NILP (XCDR (par)))
-                       /* Reset a parameter to nil if and only if it
-                          has a non-nil association.  Don't make new
-                          associations.  */
-                       Fsetcdr (par, Qnil);
-                   }
-                 else
-                   /* Always restore a non-nil value.  */
-                   Fset_window_parameter (window, XCAR (pers), XCDR (pers));
-               }
-           }
-
-         if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
-           /* If saved buffer is alive, install it.  */
-           {
-             wset_buffer (w, p->buffer);
-             w->start_at_line_beg = !NILP (p->start_at_line_beg);
-             set_marker_restricted (w->start, p->start, w->contents);
-             set_marker_restricted (w->pointm, p->pointm, w->contents);
-             set_marker_restricted (w->old_pointm, p->old_pointm, w->contents);
-             /* As documented in Fcurrent_window_configuration, don't
-                restore the location of point in the buffer which was
-                current when the window configuration was recorded.  */
-             if (!EQ (p->buffer, new_current_buffer)
-                 && XBUFFER (p->buffer) == current_buffer)
-               Fgoto_char (w->pointm);
-           }
-         else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents)))
-           /* Keep window's old buffer; make sure the markers are real.  */
-           {
-             /* Set window markers at start of visible range.  */
-             if (XMARKER (w->start)->buffer == 0)
-               set_marker_restricted_both (w->start, w->contents, 0, 0);
-             if (XMARKER (w->pointm)->buffer == 0)
-               set_marker_restricted_both
-                 (w->pointm, w->contents,
-                  BUF_PT (XBUFFER (w->contents)),
-                  BUF_PT_BYTE (XBUFFER (w->contents)));
-             if (XMARKER (w->old_pointm)->buffer == 0)
-               set_marker_restricted_both
-                 (w->old_pointm, w->contents,
-                  BUF_PT (XBUFFER (w->contents)),
-                  BUF_PT_BYTE (XBUFFER (w->contents)));
-             w->start_at_line_beg = 1;
-           }
-         else if (!NILP (w->start))
-           /* Leaf window has no live buffer, get one.  */
-           {
-             /* Get the buffer via other_buffer_safely in order to
-                avoid showing an unimportant buffer and, if necessary, to
-                recreate *scratch* in the course (part of Juanma's bs-show
-                scenario from March 2011).  */
-             wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
-             /* This will set the markers to beginning of visible
-                range.  */
-             set_marker_restricted_both (w->start, w->contents, 0, 0);
-             set_marker_restricted_both (w->pointm, w->contents, 0, 0);
-             set_marker_restricted_both (w->old_pointm, w->contents, 0, 0);
-             w->start_at_line_beg = 1;
-             if (!NILP (w->dedicated))
-               /* Record this window as dead.  */
-               dead_windows = Fcons (window, dead_windows);
-             /* Make sure window is no more dedicated.  */
-             wset_dedicated (w, Qnil);
-           }
-       }
-
-      fset_root_window (f, data->root_window);
-      /* Arrange *not* to restore point in the buffer that was
-        current when the window configuration was saved.  */
-      if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
-       set_marker_restricted (XWINDOW (data->current_window)->pointm,
-                              make_number (old_point),
-                              XWINDOW (data->current_window)->contents);
-
-      /* In the following call to `select-window', prevent "swapping out
-        point" in the old selected window using the buffer that has
-        been restored into it.  We already swapped out that point from
-        that window's old buffer.
-
-        Do not record the buffer here.  We do that in a separate call
-        to select_window below.  See also Bug#16207.  */
-      select_window (data->current_window, Qt, 1);
-      BVAR (XBUFFER (XWINDOW (selected_window)->contents),
-           last_selected_window)
-       = selected_window;
-
-      if (NILP (data->focus_frame)
-         || (FRAMEP (data->focus_frame)
-             && FRAME_LIVE_P (XFRAME (data->focus_frame))))
-       Fredirect_frame_focus (frame, data->focus_frame);
-
-      /* Set the frame size to the value it had before this function.  */
-      if (previous_frame_text_width != FRAME_TEXT_WIDTH (f)
-         || previous_frame_text_height != FRAME_TEXT_HEIGHT (f))
-       adjust_frame_size (f, previous_frame_text_width,
-                          previous_frame_text_height, 5, 0);
-
-      if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f))
-       {
-#ifdef HAVE_WINDOW_SYSTEM
-         if (FRAME_WINDOW_P (f))
-           x_set_menu_bar_lines (f,
-                                 make_number (previous_frame_menu_bar_lines),
-                                 make_number (0));
-         else  /* TTY or MSDOS */
-#endif
-           set_menu_bar_lines (f, make_number (previous_frame_menu_bar_lines),
-                               make_number (0));
-       }
-#ifdef HAVE_WINDOW_SYSTEM
-      if (previous_frame_tool_bar_lines != FRAME_TOOL_BAR_LINES (f))
-       x_set_tool_bar_lines (f, make_number (previous_frame_tool_bar_lines),
-                             make_number (0));
-#endif
-
-      /* Now, free glyph matrices in windows that were not reused.  */
-      for (i = n = 0; i < n_leaf_windows; ++i)
-       {
-         if (NILP (leaf_windows[i]->contents))
-           free_window_matrices (leaf_windows[i]);
-         else if (EQ (leaf_windows[i]->contents, new_current_buffer))
-           ++n;
-       }
-
-      /* Make frame official again and apply frame size changes if
-        needed.  */
-      f->official = true;
-      adjust_frame_size (f, -1, -1, 1, 0);
-
-      adjust_frame_glyphs (f);
-      unblock_input ();
-
-      /* Scan dead buffer windows.  */
-      for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
-       {
-         window = XCAR (dead_windows);
-         if (WINDOW_LIVE_P (window) && !EQ (window, FRAME_ROOT_WINDOW (f)))
-           delete_deletable_window (window);
-       }
-
-      /* Record the selected window's buffer here.  The window should
-        already be the selected one from the call above.  */
-      select_window (data->current_window, Qnil, 0);
-
-      /* Fselect_window will have made f the selected frame, so we
-        reselect the proper frame here.  Fhandle_switch_frame will change the
-        selected window too, but that doesn't make the call to
-        Fselect_window above totally superfluous; it still sets f's
-        selected window.  */
-      if (FRAME_LIVE_P (XFRAME (data->selected_frame)))
-       do_switch_frame (data->selected_frame, 0, 0, Qnil);
-
-      run_window_configuration_change_hook (f);
-    }
-
-  if (!NILP (new_current_buffer))
-    {
-      Fset_buffer (new_current_buffer);
-      /* If the new current buffer doesn't appear in the selected
-        window, go to its old point (see bug#12208).  */
-      if (!EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
-       Fgoto_char (make_number (old_point));
-    }
-
-  Vminibuf_scroll_window = data->minibuf_scroll_window;
-  minibuf_selected_window = data->minibuf_selected_window;
-
-  return (FRAME_LIVE_P (f) ? Qt : Qnil);
-}
-#endif
-
 void
 restore_window_configuration (Lisp_Object configuration)
 {
 void
 restore_window_configuration (Lisp_Object configuration)
 {
@@ -7299,7 +6939,6 @@ set_window_scroll_bars (struct window *w, Lisp_Object width,
                        Lisp_Object horizontal_type)
 {
   int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width)));
                        Lisp_Object horizontal_type)
 {
   int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width)));
-  int iheight = (NILP (height) ? -1 : (CHECK_NATNUM (height), XINT (height)));
   bool changed = 0;
 
   if (iwidth == 0)
   bool changed = 0;
 
   if (iwidth == 0)
@@ -7327,29 +6966,37 @@ set_window_scroll_bars (struct window *w, Lisp_Object width,
        }
     }
 
        }
     }
 
-  if (MINI_WINDOW_P (w) || iheight == 0)
-    horizontal_type = Qnil;
+#if USE_HORIZONTAL_SCROLL_BARS
+  {
+    int iheight = (NILP (height) ? -1 : (CHECK_NATNUM (height), XINT (height)));
 
 
-  if (!(NILP (horizontal_type)
-       || EQ (horizontal_type, Qbottom)
-       || EQ (horizontal_type, Qt)))
-    error ("Invalid type of horizontal scroll bar");
+    if (MINI_WINDOW_P (w) || iheight == 0)
+      horizontal_type = Qnil;
 
 
-  if (w->scroll_bar_height != iheight
-      || !EQ (w->horizontal_scroll_bar_type, horizontal_type))
-    {
-      /* Don't change anything if new scroll bar won't fit.  */
-      if ((WINDOW_PIXEL_HEIGHT (w)
-          - WINDOW_HEADER_LINE_HEIGHT (w)
-          - WINDOW_MODE_LINE_HEIGHT (w)
-          - max (iheight, 0))
-         >= MIN_SAFE_WINDOW_PIXEL_HEIGHT (w))
-       {
-         w->scroll_bar_height = iheight;
-         wset_horizontal_scroll_bar_type (w, horizontal_type);
-         changed = 1;
-       }
-    }
+    if (!(NILP (horizontal_type)
+         || EQ (horizontal_type, Qbottom)
+         || EQ (horizontal_type, Qt)))
+      error ("Invalid type of horizontal scroll bar");
+
+    if (w->scroll_bar_height != iheight
+       || !EQ (w->horizontal_scroll_bar_type, horizontal_type))
+      {
+       /* Don't change anything if new scroll bar won't fit.  */
+       if ((WINDOW_PIXEL_HEIGHT (w)
+            - WINDOW_HEADER_LINE_HEIGHT (w)
+            - WINDOW_MODE_LINE_HEIGHT (w)
+            - max (iheight, 0))
+           >= MIN_SAFE_WINDOW_PIXEL_HEIGHT (w))
+         {
+           w->scroll_bar_height = iheight;
+           wset_horizontal_scroll_bar_type (w, horizontal_type);
+           changed = 1;
+         }
+      }
+  }
+#else
+  wset_horizontal_scroll_bar_type (w, Qnil);
+#endif
 
   return changed ? w : NULL;
 }
 
   return changed ? w : NULL;
 }
@@ -7359,16 +7006,17 @@ DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
        doc: /* Set width and type of scroll bars of window WINDOW.
 WINDOW must be a live window and defaults to the selected one.
 
        doc: /* Set width and type of scroll bars of window WINDOW.
 WINDOW must be a live window and defaults to the selected one.
 
-Second parameter WIDTH specifies the pixel width for the scroll bar.
+Second parameter WIDTH specifies the pixel width for the vertical scroll
+bar.  If WIDTH is nil, use the scroll-bar width of WINDOW's frame.
 Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
 Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
-bar: left, right, or nil.  If WIDTH is nil, use the frame's scroll-bar
-width.  If VERTICAL-TYPE is t, use the frame's scroll-bar type.
+bar: left, right, or nil.  If VERTICAL-TYPE is t, this means use the
+frame's scroll-bar type.
 
 
-Fourth parameter HEIGHT specifies the pixel height for the scroll bar.
-Fifth parameter HORIZONTAL-TYPE specifies the type of the vertical
-scroll bar: nil, bottom, or t.  If HEIGHT is nil, use the frame's
-scroll-bar height.  If HORIZONTAL-TYPE is t, use the frame's scroll-bar
-type.
+Fourth parameter HEIGHT specifies the pixel height for the horizontal
+scroll bar.  If HEIGHT is nil, use the scroll-bar height of WINDOW's
+frame.  Fifth parameter HORIZONTAL-TYPE specifies the type of the
+horizontal scroll bar: nil, bottom, or t.  If HORIZONTAL-TYPE is t, this
+means to use the frame's horizontal scroll-bar type.
 
 Return t if scroll bars were actually changed and nil otherwise.  */)
   (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type,
 
 Return t if scroll bars were actually changed and nil otherwise.  */)
   (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type,
@@ -7386,17 +7034,22 @@ DEFUN ("window-scroll-bars", Fwindow_scroll_bars, Swindow_scroll_bars,
        doc: /* Get width and type of scroll bars of window WINDOW.
 WINDOW must be a live window and defaults to the selected one.
 
        doc: /* Get width and type of scroll bars of window WINDOW.
 WINDOW must be a live window and defaults to the selected one.
 
-Value is a list of the form (WIDTH COLS VERTICAL-TYPE HEIGHT LINES
-HORIZONTAL-TYPE).  If WIDTH or HEIGHT is nil or TYPE is t, the window is
-using the frame's corresponding value.  */)
+Value is a list of the form (WIDTH COLUMNS VERTICAL-TYPE HEIGHT LINES
+HORIZONTAL-TYPE).  If WIDTH or HEIGHT is nil or VERTICAL-TYPE or
+HORIZONTAL-TYPE is t, the window is using the frame's corresponding
+value.  */)
   (Lisp_Object window)
 {
   struct window *w = decode_live_window (window);
 
   (Lisp_Object window)
 {
   struct window *w = decode_live_window (window);
 
-  return Fcons (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (w)),
+  return Fcons (((w->scroll_bar_width >= 0)
+                ? make_number (w->scroll_bar_width)
+                : Qnil),
                list5 (make_number (WINDOW_SCROLL_BAR_COLS (w)),
                       w->vertical_scroll_bar_type,
                list5 (make_number (WINDOW_SCROLL_BAR_COLS (w)),
                       w->vertical_scroll_bar_type,
-                      make_number (WINDOW_SCROLL_BAR_AREA_HEIGHT (w)),
+                      ((w->scroll_bar_height >= 0)
+                       ? make_number (w->scroll_bar_height)
+                       : Qnil),
                       make_number (WINDOW_SCROLL_BAR_LINES (w)),
                       w->horizontal_scroll_bar_type));
 }
                       make_number (WINDOW_SCROLL_BAR_LINES (w)),
                       w->horizontal_scroll_bar_type));
 }
@@ -7686,7 +7339,7 @@ the buffer; `temp-buffer-show-hook' is not run unless this function runs it.  */
               doc: /* Non-nil means to use `mode-line-inactive' face in non-selected windows.
 If the minibuffer is active, the `minibuffer-scroll-window' mode line
 is displayed in the `mode-line' face.  */);
               doc: /* Non-nil means to use `mode-line-inactive' face in non-selected windows.
 If the minibuffer is active, the `minibuffer-scroll-window' mode line
 is displayed in the `mode-line' face.  */);
-  mode_line_in_non_selected_windows = 1;
+  mode_line_in_non_selected_windows = true;
 
   DEFVAR_LISP ("other-window-scroll-buffer", Vother_window_scroll_buffer,
               doc: /* If this is a live buffer, \\[scroll-other-window] should scroll its window.  */);
 
   DEFVAR_LISP ("other-window-scroll-buffer", Vother_window_scroll_buffer,
               doc: /* If this is a live buffer, \\[scroll-other-window] should scroll its window.  */);
@@ -7694,7 +7347,7 @@ is displayed in the `mode-line' face.  */);
 
   DEFVAR_BOOL ("auto-window-vscroll", auto_window_vscroll_p,
               doc: /* Non-nil means to automatically adjust `window-vscroll' to view tall lines.  */);
 
   DEFVAR_BOOL ("auto-window-vscroll", auto_window_vscroll_p,
               doc: /* Non-nil means to automatically adjust `window-vscroll' to view tall lines.  */);
-  auto_window_vscroll_p = 1;
+  auto_window_vscroll_p = true;
 
   DEFVAR_INT ("next-screen-context-lines", next_screen_context_lines,
              doc: /* Number of lines of continuity when scrolling by screenfuls.  */);
 
   DEFVAR_INT ("next-screen-context-lines", next_screen_context_lines,
              doc: /* Number of lines of continuity when scrolling by screenfuls.  */);
@@ -7817,7 +7470,18 @@ all functions that symmetrically resize a parent window.
 Note that when a frame's pixel size is not a multiple of the
 frame's character size, at least one window may get resized
 pixelwise even if this option is nil.  */);
 Note that when a frame's pixel size is not a multiple of the
 frame's character size, at least one window may get resized
 pixelwise even if this option is nil.  */);
-  window_resize_pixelwise = 0;
+  window_resize_pixelwise = false;
+
+  DEFVAR_BOOL ("fast-but-imprecise-scrolling",
+               Vfast_but_imprecise_scrolling,
+               doc: /* When non-nil, accelerate scrolling operations.
+This comes into play when scrolling rapidly over previously
+unfontified buffer regions.  Only those portions of the buffer which
+are actually going to be displayed get fontified.
+
+Note that this optimization can cause the portion of the buffer
+displayed after a scrolling operation to be somewhat inaccurate.  */);
+  Vfast_but_imprecise_scrolling = false;
 
   defsubr (&Sselected_window);
   defsubr (&Sminibuffer_window);
 
   defsubr (&Sselected_window);
   defsubr (&Sminibuffer_window);
@@ -7890,6 +7554,7 @@ pixelwise even if this option is nil.  */);
   defsubr (&Sset_window_display_table);
   defsubr (&Snext_window);
   defsubr (&Sprevious_window);
   defsubr (&Sset_window_display_table);
   defsubr (&Snext_window);
   defsubr (&Sprevious_window);
+  defsubr (&Swindow__sanitize_window_sizes);
   defsubr (&Sget_buffer_window);
   defsubr (&Sdelete_other_windows_internal);
   defsubr (&Sdelete_window_internal);
   defsubr (&Sget_buffer_window);
   defsubr (&Sdelete_other_windows_internal);
   defsubr (&Sdelete_window_internal);