(display_prop_end, invisible_text_between_p): Use
[bpt/emacs.git] / src / xdisp.c
index a2e8a4b..e5ffabb 100644 (file)
@@ -219,7 +219,7 @@ Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
 Lisp_Object Qredisplay_end_trigger_functions;
 Lisp_Object Qinhibit_point_motion_hooks;
-Lisp_Object QCeval, QCwhen;
+Lisp_Object QCeval, Qwhen, QCfile;
 Lisp_Object Qfontified;
 
 /* Functions called to fontify regions of text.  */
@@ -227,23 +227,23 @@ Lisp_Object Qfontified;
 Lisp_Object Vfontification_functions;
 Lisp_Object Qfontification_functions;
 
-/* Non-zero means draw toolbar buttons raised when the mouse moves
+/* Non-zero means draw tool bar buttons raised when the mouse moves
    over them.  */
 
-int auto_raise_toolbar_buttons_p;
+int auto_raise_tool_bar_buttons_p;
 
-/* Margin around toolbar buttons in pixels.  */
+/* Margin around tool bar buttons in pixels.  */
 
-int toolbar_button_margin;
+int tool_bar_button_margin;
 
-/* Thickness of shadow to draw around toolbar buttons.  */
+/* Thickness of shadow to draw around tool bar buttons.  */
 
-int toolbar_button_relief;
+int tool_bar_button_relief;
 
-/* Non-zero means automatically resize toolbars so that all toolbar
+/* Non-zero means automatically resize tool-bars so that all tool-bar
    items are visible, and no blank lines remain.  */
 
-int auto_resize_toolbars_p;
+int auto_resize_tool_bars_p;
 
 /* Non-nil means don't actually do any redisplay.  */
 
@@ -258,6 +258,7 @@ extern Lisp_Object Qface, Qinvisible, Qimage;
 
 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qheight, Qraise;
+Lisp_Object Qmargin;
 
 /* Non-nil means highlight trailing whitespace.  */
 
@@ -427,28 +428,6 @@ int message_enable_multibyte;
 
 int update_mode_lines;
 
-/* Smallest number of characters before the gap at any time since last
-   redisplay that finished.  Valid for current buffer when
-   try_window_id can be called.  */
-
-int beg_unchanged;
-
-/* Smallest number of characters after the gap at any time since last
-   redisplay that finished.  Valid for current buffer when
-   try_window_id can be called.  */
-
-int end_unchanged;
-
-/* MODIFF as of last redisplay that finished; if it matches MODIFF,
-   and overlay_unchanged_modified matches OVERLAY_MODIFF, that means
-   beg_unchanged and end_unchanged contain no useful information.  */
-
-int unchanged_modified;
-
-/* OVERLAY_MODIFF as of last redisplay that finished.  */
-
-int overlay_unchanged_modified;
-
 /* Nonzero if window sizes or contents have changed since last
    redisplay that finished */
 
@@ -495,7 +474,9 @@ static int display_last_displayed_message_p;
 
 int message_buf_print;
 
-/* Maximum height for resizing mini-windows.  */
+/* Maximum height for resizing mini-windows.  Either a float
+   specifying a fraction of the available height, or an integer
+   specifying a number of lines.  */
 
 static Lisp_Object Vmax_mini_window_height;
 
@@ -604,9 +585,11 @@ enum move_it_result
 \f
 /* Function prototypes.  */
 
+static struct glyph_row *row_containing_pos P_ ((struct window *, int,
+                                                struct glyph_row *,
+                                                struct glyph_row *));
 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
-static int resize_mini_window P_ ((struct window *));
 static void clear_garbaged_frames P_ ((void));
 static int current_message_1 P_ ((Lisp_Object *));
 static int truncate_message_1 P_ ((int));
@@ -699,10 +682,10 @@ static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
 
 #ifdef HAVE_WINDOW_SYSTEM
 
-static void update_toolbar P_ ((struct frame *, int));
-static void build_desired_toolbar_string P_ ((struct frame *f));
-static int redisplay_toolbar P_ ((struct frame *));
-static void display_toolbar_line P_ ((struct it *));
+static void update_tool_bar P_ ((struct frame *, int));
+static void build_desired_tool_bar_string P_ ((struct frame *f));
+static int redisplay_tool_bar P_ ((struct frame *));
+static void display_tool_bar_line P_ ((struct it *));
 
 #endif /* HAVE_WINDOW_SYSTEM */
 
@@ -742,7 +725,7 @@ window_box_width (w, area)
   
   if (!w->pseudo_window_p)
     {
-      width -= FRAME_SCROLL_BAR_WIDTH (f) + 2 * FRAME_FLAGS_AREA_COLS (f);
+      width -= FRAME_SCROLL_BAR_WIDTH (f) + FRAME_FLAGS_AREA_COLS (f);
       
       if (area == TEXT_AREA)
        {
@@ -776,8 +759,8 @@ window_box_height (w)
   if (WINDOW_WANTS_MODELINE_P (w))
     height -= CURRENT_MODE_LINE_HEIGHT (w);
 
-  if (WINDOW_WANTS_TOP_LINE_P (w))
-    height -= CURRENT_TOP_LINE_HEIGHT (w);
+  if (WINDOW_WANTS_HEADER_LINE_P (w))
+    height -= CURRENT_HEADER_LINE_HEIGHT (w);
 
   return height;
 }
@@ -799,7 +782,7 @@ window_box_left (w, area)
   if (!w->pseudo_window_p)
     {
       x += (WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f)
-           + FRAME_FLAGS_AREA_WIDTH (f));
+           + FRAME_LEFT_FLAGS_AREA_WIDTH (f));
       
       if (area == TEXT_AREA)
        x += window_box_width (w, LEFT_MARGIN_AREA);
@@ -846,8 +829,8 @@ window_box (w, area, box_x, box_y, box_width, box_height)
   *box_x = window_box_left (w, area);
   *box_y = (FRAME_INTERNAL_BORDER_WIDTH_SAFE (f)
            + XFASTINT (w->top) * CANON_Y_UNIT (f));
-  if (WINDOW_WANTS_TOP_LINE_P (w))
-    *box_y += CURRENT_TOP_LINE_HEIGHT (w);
+  if (WINDOW_WANTS_HEADER_LINE_P (w))
+    *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
 }
 
 
@@ -1177,11 +1160,11 @@ check_window_end (w)
 
    BASE_FACE_ID is the id of a base face to use.  It must be one of
    DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID or
-   TOP_LINE_FACE_ID for displaying mode lines, or TOOLBAR_FACE_ID for
-   displaying the toolbar.
+   HEADER_LINE_FACE_ID for displaying mode lines, or TOOL_BAR_FACE_ID for
+   displaying the tool-bar.
    
    If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID or
-   TOP_LINE_FACE_ID, the iterator will be initialized to use the
+   HEADER_LINE_FACE_ID, the iterator will be initialized to use the
    corresponding mode line glyph row of the desired matrix of W.  */
 
 void
@@ -1213,8 +1196,8 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
     {
       if (base_face_id == MODE_LINE_FACE_ID)
        row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
-      else if (base_face_id == TOP_LINE_FACE_ID)
-       row = MATRIX_TOP_LINE_ROW (w->desired_matrix);
+      else if (base_face_id == HEADER_LINE_FACE_ID)
+       row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
     }
   
   /* Clear IT.  */
@@ -1367,8 +1350,8 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
            it->last_visible_x -= it->continuation_pixel_width;
        }
 
-      it->top_line_p = WINDOW_WANTS_TOP_LINE_P (w);
-      it->current_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w) + w->vscroll;
+      it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
+      it->current_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w) + w->vscroll;
     }
 
   /* Leave room for a border glyph.  */
@@ -1425,7 +1408,7 @@ start_display (it, w, pos)
 {
   int start_at_line_beg_p;
   struct glyph_row *row;
-  int first_vpos = WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0;
+  int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
   int first_y;
 
   row = w->desired_matrix->rows + first_vpos;
@@ -2230,8 +2213,11 @@ handle_display_prop (it)
     return HANDLED_NORMALLY;
 
   space_or_image_found_p = 0;
-  if (CONSP (prop) && CONSP (XCAR (prop)))
+  if (CONSP (prop)
+      && CONSP (XCAR (prop))
+      && !EQ (Qmargin, XCAR (XCAR (prop))))
     {
+      /* A list of sub-properties.  */
       while (CONSP (prop))
        {
          if (handle_single_display_prop (it, XCAR (prop), object, position))
@@ -2257,7 +2243,7 @@ handle_display_prop (it)
 }
 
 
-/* Value is the position of the end of the `display' property stating
+/* Value is the position of the end of the `display' property starting
    at START_POS in OBJECT.  */
 
 static struct text_pos
@@ -2268,27 +2254,14 @@ display_prop_end (it, object, start_pos)
 {
   Lisp_Object end;
   struct text_pos end_pos;
-  
-  /* Characters having this form of property are not displayed, so
-     we have to find the end of the property.  */
-  end = Fnext_single_property_change (make_number (start_pos.charpos),
-                                     Qdisplay, object, Qnil);
-  if (NILP (end))
-    {
-      /* A nil value of `end' means there are no changes of the
-        property to the end of the buffer or string.  */
-      if (it->current.overlay_string_index >= 0)
-       end_pos.charpos = XSTRING (it->string)->size;
-      else
-       end_pos.charpos = it->end_charpos;
-    }
-  else
-    end_pos.charpos = XFASTINT (end);
 
-  if (STRINGP (it->string))
+  end = next_single_char_property_change (make_number (CHARPOS (start_pos)),
+                                         Qdisplay, object, Qnil);
+  CHARPOS (end_pos) = XFASTINT (end);
+  if (STRINGP (object))
     compute_string_pos (&end_pos, start_pos, it->string);
   else
-    end_pos.bytepos = CHAR_TO_BYTE (end_pos.charpos);
+    BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
 
   return end_pos;
 }
@@ -2315,19 +2288,16 @@ handle_single_display_prop (it, prop, object, position)
 
   Lisp_Object form;
 
-  /* If PROP is a list of the form `(:when FORM VALUE)', FORM is
-     evaluated.  If the result is nil, VALUE is ignored.  */
+  /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
+     evaluated.  If the result is nil, VALUE is ignored. */
   form = Qt;
-  if (CONSP (prop) && EQ (XCAR (prop), QCwhen))
+  if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
     {
       prop = XCDR (prop);
       if (!CONSP (prop))
        return 0;
       form = XCAR (prop);
       prop = XCDR (prop);
-      if (!CONSP (prop))
-       return 0;
-      prop = XCAR (prop);
     }
 
   if (!NILP (form) && !EQ (form, Qt))
@@ -2452,8 +2422,8 @@ handle_single_display_prop (it, prop, object, position)
     }
   else if (!it->string_from_display_prop_p)
     {
-      /* `(left-margin VALUE)' or `(right-margin VALUE)
-        or `(nil VALUE)' or VALUE.  */
+      /* `((margin left-margin) VALUE)' or `((margin right-margin)
+        VALUE) or `((margin nil) VALUE)' or VALUE. */
       Lisp_Object location, value;
       struct text_pos start_pos;
       int valid_p;
@@ -2468,14 +2438,26 @@ handle_single_display_prop (it, prop, object, position)
         text properties change there.  */
       it->stop_charpos = position->charpos;
 
-      if (CONSP (prop)
-         && !EQ (XCAR (prop), Qspace)
-         && !EQ (XCAR (prop), Qimage))
+      location = Qunbound;
+      if (CONSP (prop) && CONSP (XCAR (prop)))
        {
-         location = XCAR (prop);
+         Lisp_Object tem;
+         
          value = XCDR (prop);
+         if (CONSP (value))
+           value = XCAR (value);
+
+         tem = XCAR (prop);
+         if (EQ (XCAR (tem), Qmargin)
+             && (tem = XCDR (tem),
+                 tem = CONSP (tem) ? XCAR (tem) : Qnil,
+                 (NILP (tem)
+                  || EQ (tem, Qleft_margin)
+                  || EQ (tem, Qright_margin))))
+           location = tem;
        }
-      else
+
+      if (EQ (location, Qunbound))
        {
          location = Qnil;
          value = prop;
@@ -2727,9 +2709,9 @@ load_overlay_strings (it)
   /* Process overlay before the overlay center.  */
   for (ov = current_buffer->overlays_before;
        CONSP (ov);
-       ov = XCONS (ov)->cdr)
+       ov = XCDR (ov))
     {
-      overlay = XCONS (ov)->car;
+      overlay = XCAR (ov);
       xassert (OVERLAYP (overlay));
       start = OVERLAY_POSITION (OVERLAY_START (overlay));
       end = OVERLAY_POSITION (OVERLAY_END (overlay));
@@ -2763,9 +2745,9 @@ load_overlay_strings (it)
   /* Process overlays after the overlay center.  */
   for (ov = current_buffer->overlays_after;
        CONSP (ov);
-       ov = XCONS (ov)->cdr)
+       ov = XCDR (ov))
     {
-      overlay = XCONS (ov)->car;
+      overlay = XCAR (ov);
       xassert (OVERLAYP (overlay));
       start = OVERLAY_POSITION (OVERLAY_START (overlay));
       end = OVERLAY_POSITION (OVERLAY_END (overlay));
@@ -3316,12 +3298,16 @@ get_next_display_element (it)
             Control characters coming from a display table entry are
             currently not translated because we use IT->dpvec to hold
             the translation.  This could easily be changed but I
-            don't believe that it is worth doing.  */
+            don't believe that it is worth doing.
+
+            Non-printable multibyte characters are also translated
+            octal form.  */
          else if ((it->c < ' '
                    && (it->area != TEXT_AREA
                        || (it->c != '\n' && it->c != '\t')))
                   || (it->c >= 127
-                      && it->len == 1))
+                      && it->len == 1)
+                  || !CHAR_PRINTABLE_P (it->c))
            {
              /* IT->c is a control character which must be displayed
                 either as '\003' or as `^C' where the '\\' and '^'
@@ -3354,29 +3340,37 @@ get_next_display_element (it)
                }
              else
                {
+                 unsigned char work[4], *str;
+                 int len = CHAR_STRING (it->c, work, str);
+                 int i;
+                 GLYPH escape_glyph;
+
                  /* Set IT->ctl_chars[0] to the glyph for `\\'.  */
                  if (it->dp
                      && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
                      && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
-                   g = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
+                   escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
                  else
-                   g = FAST_MAKE_GLYPH ('\\', 0);
-                 XSETINT (it->ctl_chars[0], g);
+                   escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
 
-                 /* Insert three more glyphs into IT->ctl_chars for
-                    the octal display of the character.  */
-                 g = FAST_MAKE_GLYPH (((it->c >> 6) & 7) + '0', 0); 
-                 XSETINT (it->ctl_chars[1], g);
-                 g = FAST_MAKE_GLYPH (((it->c >> 3) & 7) + '0', 0); 
-                 XSETINT (it->ctl_chars[2], g);
-                 g = FAST_MAKE_GLYPH ((it->c & 7) + '0', 0); 
-                 XSETINT (it->ctl_chars[3], g);
+                 for (i = 0; i < len; i++)
+                   {
+                     XSETINT (it->ctl_chars[i * 4], escape_glyph);
+                     /* Insert three more glyphs into IT->ctl_chars for
+                        the octal display of the character.  */
+                     g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0); 
+                     XSETINT (it->ctl_chars[i * 4 + 1], g);
+                     g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0); 
+                     XSETINT (it->ctl_chars[i * 4 + 2], g);
+                     g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0); 
+                     XSETINT (it->ctl_chars[i * 4 + 3], g);
+                   }
 
                  /* Set up IT->dpvec and return the first character
                      from it.  */
                  it->dpvec_char_len = it->len;
                  it->dpvec = it->ctl_chars;
-                 it->dpend = it->dpvec + 4;
+                 it->dpend = it->dpvec + len * 4;
                  it->current.dpvec_index = 0;
                  it->method = next_element_from_display_vector;
                  get_next_display_element (it);
@@ -3983,7 +3977,7 @@ run_redisplay_end_trigger_hook (it)
      - when we stopped at a line end, i.e. a newline or a CR and selective
      display is on.  */
 
-enum move_it_result
+static enum move_it_result
 move_it_in_display_line_to (it, to_charpos, to_x, op)
      struct it *it;
      int to_charpos, to_x, op;
@@ -4423,10 +4417,9 @@ invisible_text_between_p (it, start_charpos, end_charpos)
     invisible_found_p = 1;
   else
     {
-      limit = Fnext_single_property_change (make_number (start_charpos),
-                                           Qinvisible,
-                                           Fcurrent_buffer (),
-                                           make_number (end_charpos));
+      limit = next_single_char_property_change (make_number (start_charpos),
+                                               Qinvisible, Qnil,
+                                               make_number (end_charpos));
       invisible_found_p = XFASTINT (limit) < end_charpos;
     }
 
@@ -4578,6 +4571,37 @@ move_it_by_lines (it, dvpos, need_y_p)
  ***********************************************************************/
 
 
+/* Add a message with format string FORMAT and arguments ARG1 and ARG2
+   to *Messages*.  */
+
+void
+add_to_log (format, arg1, arg2)
+     char *format;
+     Lisp_Object arg1, arg2;
+{
+  Lisp_Object args[3];
+  Lisp_Object msg, fmt;
+  char *buffer;
+  int len;
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
+
+  fmt = msg = Qnil;
+  GCPRO4 (fmt, msg, arg1, arg2);
+  
+  args[0] = fmt = build_string (format);
+  args[1] = arg1;
+  args[2] = arg2;
+  msg = Fformat (make_number (3), args);
+
+  len = STRING_BYTES (XSTRING (msg)) + 1;
+  buffer = (char *) alloca (len);
+  strcpy (buffer, XSTRING (msg)->data);
+  
+  message_dolog (buffer, len, 1, 0);
+  UNGCPRO;
+}
+
+
 /* Output a newline in the *Messages* buffer if "needs" one.  */
 
 void
@@ -4817,6 +4841,7 @@ message2_nolog (m, len, multibyte)
      char *m;
      int len;
 {
+  struct frame *sf = SELECTED_FRAME ();
   message_enable_multibyte = multibyte;
 
   if (noninteractive)
@@ -4834,19 +4859,19 @@ message2_nolog (m, len, multibyte)
      initialized yet.  Error messages get reported properly by
      cmd_error, so this must be just an informative message; toss it.  */
   else if (INTERACTIVE 
-          && selected_frame->glyphs_initialized_p
-          && FRAME_MESSAGE_BUF (selected_frame))
+          && sf->glyphs_initialized_p
+          && FRAME_MESSAGE_BUF (sf))
     {
       Lisp_Object mini_window;
       struct frame *f;
 
       /* Get the frame containing the mini-buffer
         that the selected frame is using.  */
-      mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
+      mini_window = FRAME_MINIBUF_WINDOW (sf);
       f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
 
       FRAME_SAMPLE_VISIBILITY (f);
-      if (FRAME_VISIBLE_P (selected_frame)
+      if (FRAME_VISIBLE_P (sf)
          && ! FRAME_VISIBLE_P (f))
        Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
 
@@ -4900,6 +4925,7 @@ message3_nolog (m, nbytes, multibyte)
      Lisp_Object m;
      int nbytes, multibyte;
 {
+  struct frame *sf = SELECTED_FRAME ();
   message_enable_multibyte = multibyte;
 
   if (noninteractive)
@@ -4917,8 +4943,8 @@ message3_nolog (m, nbytes, multibyte)
      initialized yet.  Error messages get reported properly by
      cmd_error, so this must be just an informative message; toss it.  */
   else if (INTERACTIVE 
-          && selected_frame->glyphs_initialized_p
-          && FRAME_MESSAGE_BUF (selected_frame))
+          && sf->glyphs_initialized_p
+          && FRAME_MESSAGE_BUF (sf))
     {
       Lisp_Object mini_window;
       Lisp_Object frame;
@@ -4926,19 +4952,20 @@ message3_nolog (m, nbytes, multibyte)
 
       /* Get the frame containing the mini-buffer
         that the selected frame is using.  */
-      mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
+      mini_window = FRAME_MINIBUF_WINDOW (sf);
       frame = XWINDOW (mini_window)->frame;
       f = XFRAME (frame);
 
       FRAME_SAMPLE_VISIBILITY (f);
-      if (FRAME_VISIBLE_P (selected_frame)
+      if (FRAME_VISIBLE_P (sf)
          && !FRAME_VISIBLE_P (f))
        Fmake_frame_visible (frame);
 
       if (STRINGP (m) && XSTRING (m)->size)
        {
          set_message (NULL, m, nbytes, multibyte);
-         Fraise_frame (frame);
+         if (minibuffer_auto_raise)
+           Fraise_frame (frame);
        }
       else
        clear_message (1, 1);
@@ -5005,11 +5032,11 @@ message_with_string (m, string, log)
         It may be larger than the selected frame, so we need
         to use its buffer, not the selected frame's buffer.  */
       Lisp_Object mini_window;
-      FRAME_PTR f;
+      struct frame *f, *sf = SELECTED_FRAME ();
 
       /* Get the frame containing the minibuffer
         that the selected frame is using.  */
-      mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
+      mini_window = FRAME_MINIBUF_WINDOW (sf);
       f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
 
       /* A null message buffer means that the frame hasn't really been
@@ -5067,11 +5094,11 @@ message (m, a1, a2, a3)
         on.  It may be larger than the selected frame, so we need to
         use its buffer, not the selected frame's buffer.  */
       Lisp_Object mini_window;
-      struct frame *f;
+      struct frame *f, *sf = SELECTED_FRAME ();
 
       /* Get the frame containing the mini-buffer
         that the selected frame is using.  */
-      mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
+      mini_window = FRAME_MINIBUF_WINDOW (sf);
       f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
 
       /* A null message buffer means that the frame hasn't really been
@@ -5195,7 +5222,6 @@ with_echo_area_buffer (w, which, fn, a1, a2, a3, a4, a5)
       if (!NILP (echo_area_buffer[this_one])
          && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
        echo_area_buffer[this_one] = Qnil;
-      
     }
 
   /* Choose a suitable buffer from echo_buffer[] is we don't
@@ -5221,7 +5247,7 @@ with_echo_area_buffer (w, which, fn, a1, a2, a3, a4, a5)
      Fset_window_buffer.  We must also change w->pointm, though,
      because otherwise an assertions in unshow_buffer fails, and Emacs
      aborts.  */
-  set_buffer_internal (XBUFFER (buffer));
+  set_buffer_internal_1 (XBUFFER (buffer));
   if (w)
     {
       w->buffer = buffer;
@@ -5263,13 +5289,11 @@ with_echo_area_buffer_unwind_data (w)
   Vwith_echo_area_save_vector = Qnil;
   
   if (NILP (vector))
-    vector = Fmake_vector (make_number (9), Qnil);
+    vector = Fmake_vector (make_number (7), Qnil);
   
   XSETBUFFER (XVECTOR (vector)->contents[i], current_buffer); ++i;
   XVECTOR (vector)->contents[i++] = Vdeactivate_mark;
   XVECTOR (vector)->contents[i++] = make_number (windows_or_buffers_changed);
-  XVECTOR (vector)->contents[i++] = make_number (beg_unchanged);
-  XVECTOR (vector)->contents[i++] = make_number (end_unchanged);
   
   if (w)
     {
@@ -5301,11 +5325,9 @@ unwind_with_echo_area_buffer (vector)
 {
   int i = 0;
   
-  set_buffer_internal (XBUFFER (XVECTOR (vector)->contents[i])); ++i;
+  set_buffer_internal_1 (XBUFFER (XVECTOR (vector)->contents[i])); ++i;
   Vdeactivate_mark = XVECTOR (vector)->contents[i]; ++i;
   windows_or_buffers_changed = XFASTINT (XVECTOR (vector)->contents[i]); ++i;
-  beg_unchanged = XFASTINT (XVECTOR (vector)->contents[i]); ++i;
-  end_unchanged = XFASTINT (XVECTOR (vector)->contents[i]); ++i;
 
   if (WINDOWP (XVECTOR (vector)->contents[i]))
     {
@@ -5357,8 +5379,9 @@ setup_echo_area_for_printing (multibyte_p)
       /* Raise the frame containing the echo area.  */
       if (minibuffer_auto_raise)
        {
+         struct frame *sf = SELECTED_FRAME ();
          Lisp_Object mini_window;
-         mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
+         mini_window = FRAME_MINIBUF_WINDOW (sf);
          Fraise_frame  (WINDOW_FRAME (XWINDOW (mini_window)));
        }
 
@@ -5409,13 +5432,12 @@ display_echo_area_1 (w)
      struct window *w;
 {
   Lisp_Object window;
-  struct frame *f = XFRAME (w->frame);
   struct text_pos start;
   int window_height_changed_p = 0;
 
   /* Do this before displaying, so that we have a large enough glyph
      matrix for the display.  */
-  window_height_changed_p = resize_mini_window (w);
+  window_height_changed_p = resize_mini_window (w, 0);
 
   /* Display.  */
   clear_glyph_matrix (w->desired_matrix);
@@ -5427,17 +5449,49 @@ display_echo_area_1 (w)
 }
 
 
-/* Resize mini-window W to fit the size of its contents.  Value is
-   non-zero if the window height has been changed.  */
+/* Resize the echo area window to exactly the size needed for the
+   currently displayed message, if there is one.  */
 
-static int
-resize_mini_window (w)
+void
+resize_echo_area_axactly ()
+{
+  if (BUFFERP (echo_area_buffer[0])
+      && WINDOWP (echo_area_window))
+    {
+      struct window *w = XWINDOW (echo_area_window);
+      int resized_p;
+      
+      resized_p = with_echo_area_buffer (w, 0,
+                                        (int (*) ()) resize_mini_window,
+                                        w, 1);
+      if (resized_p)
+       {
+         ++windows_or_buffers_changed;
+         ++update_mode_lines;
+         redisplay_internal (0);
+       }
+    }
+}
+
+
+/* Resize mini-window W to fit the size of its contents.  EXACT:P
+   means size the window exactly to the size needed.  Otherwise, it's
+   only enlarged until W's buffer is empty.  Value is non-zero if
+   the window height has been changed. */
+
+int
+resize_mini_window (w, exact_p)
      struct window *w;
+     int exact_p;
 {
   struct frame *f = XFRAME (w->frame);
   int window_height_changed_p = 0;
 
   xassert (MINI_WINDOW_P (w));
+
+  /* Nil means don't try to resize.  */
+  if (NILP (Vmax_mini_window_height))
+    return 0;
   
   if (!FRAME_MINIBUF_ONLY_P (f))
     {
@@ -5447,7 +5501,7 @@ resize_mini_window (w)
       int height, max_height;
       int unit = CANON_Y_UNIT (f);
       struct text_pos start;
-      
+
       init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
 
       /* Compute the max. number of lines specified by the user.  */
@@ -5455,6 +5509,8 @@ resize_mini_window (w)
        max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
       else if (INTEGERP (Vmax_mini_window_height))
        max_height = XINT (Vmax_mini_window_height);
+      else
+       max_height = total_height / 4;
       
       /* Correct that max. height if it's bogus. */
       max_height = max (1, max_height);
@@ -5476,17 +5532,23 @@ resize_mini_window (w)
       else
        SET_TEXT_POS (start, BEGV, BEGV_BYTE);
       SET_MARKER_FROM_TEXT_POS (w->start, start);
-      
-      /* Change window's height, if necessary.  */
-      if (height != XFASTINT (w->height))
+
+      /* Let it grow only, until we display an empty message, in which
+        case the window shrinks again.  */
+      if (height > XFASTINT (w->height))
        {
-         Lisp_Object old_selected_window;
-         
-         old_selected_window = selected_window;
-         XSETWINDOW (selected_window, w);
-         change_window_height (height - XFASTINT (w->height), 0);
-         selected_window = old_selected_window;
-         window_height_changed_p = 1;
+         int old_height = XFASTINT (w->height);
+         freeze_window_starts (f, 1);
+         grow_mini_window (w, height - XFASTINT (w->height));
+         window_height_changed_p = XFASTINT (w->height) != old_height;
+       }
+      else if (height < XFASTINT (w->height)
+              && (exact_p || BEGV == ZV))
+       {
+         int old_height = XFASTINT (w->height);
+         freeze_window_starts (f, 0);
+         shrink_mini_window (w);
+         window_height_changed_p = XFASTINT (w->height) != old_height;
        }
     }
 
@@ -5594,9 +5656,12 @@ truncate_echo_area (nchars)
      cmd_error, so this must be just an informative message; toss it.  */
   else if (!noninteractive
           && INTERACTIVE
-          && FRAME_MESSAGE_BUF (selected_frame)
           && !NILP (echo_area_buffer[0]))
-    with_echo_area_buffer (0, 0, (int (*) ()) truncate_message_1, nchars);
+    {
+      struct frame *sf = SELECTED_FRAME ();
+      if (FRAME_MESSAGE_BUF (sf))
+       with_echo_area_buffer (0, 0, (int (*) ()) truncate_message_1, nchars);
+    }
 }
 
 
@@ -5769,8 +5834,8 @@ clear_garbaged_frames ()
 }
 
 
-/* Redisplay the echo area of selected_frame.  If UPDATE_FRAME_P is
-   non-zero update selected_frame.  Value is non-zero if the
+/* Redisplay the echo area of the selected frame.  If UPDATE_FRAME_P
+   is non-zero update selected_frame.  Value is non-zero if the
    mini-windows height has been changed.  */
 
 static int
@@ -5781,8 +5846,9 @@ echo_area_display (update_frame_p)
   struct window *w;
   struct frame *f;
   int window_height_changed_p = 0;
+  struct frame *sf = SELECTED_FRAME ();
 
-  mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
+  mini_window = FRAME_MINIBUF_WINDOW (sf);
   w = XWINDOW (mini_window);
   f = XFRAME (WINDOW_FRAME (w));
 
@@ -5790,13 +5856,18 @@ echo_area_display (update_frame_p)
   if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
     return 0;
 
+#if 0 /* inhibit_window_system is not a valid way of testing
+        whether a window system is in use.
+        This code prevents all echo area display
+        when you run plain `emacs' on a tty.  */
   /* When Emacs starts, selected_frame may be a visible terminal
      frame, even if we run under a window system.  If we let this
      through, a message would be displayed on the terminal.  */
 #ifdef HAVE_WINDOW_SYSTEM
-  if (!inhibit_window_system && !FRAME_WINDOW_P (selected_frame))
+  if (!inhibit_window_system && !FRAME_WINDOW_P (sf))
     return 0;
 #endif /* HAVE_WINDOW_SYSTEM */
+#endif
 
   /* Redraw garbaged frames.  */
   if (frame_garbaged)
@@ -5807,12 +5878,20 @@ echo_area_display (update_frame_p)
       echo_area_window = mini_window;
       window_height_changed_p = display_echo_area (w);
       w->must_be_updated_p = 1;
-      
+
       if (update_frame_p)
        {
-         /* Calling update_single_window is faster when we can use
-            window-based redisplay.  */
-         if (FRAME_WINDOW_P (f))
+         /* Not called from redisplay_internal.  If we changed
+            window configuration, we must redisplay thoroughly.
+            Otherwise, we can do with updating what we displayed
+            above.  */
+         if (window_height_changed_p)
+           {
+             ++windows_or_buffers_changed;
+             ++update_mode_lines;
+             redisplay_internal (0);
+           }
+         else if (FRAME_WINDOW_P (f))
            {
              update_single_window (w, 1);
              rif->flush_display (f);
@@ -5823,7 +5902,8 @@ echo_area_display (update_frame_p)
     }
   else if (!EQ (mini_window, selected_window))
     windows_or_buffers_changed++;
-  
+
+  /* Last displayed message is now the current message.  */
   echo_area_buffer[1] = echo_area_buffer[0];
       
   /* Prevent redisplay optimization in redisplay_internal by resetting
@@ -5933,9 +6013,9 @@ x_consider_frame_title (frame)
       int len;
       struct it it;
 
-      for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
+      for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
        {
-         struct frame *tf = XFRAME (XCONS (tail)->car);
+         struct frame *tf = XFRAME (XCAR (tail));
 
          if (tf != f 
              && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
@@ -6064,7 +6144,7 @@ prepare_menu_bars ()
          GCPRO1 (tail);
          update_menu_bar (f, 0);
 #ifdef HAVE_WINDOW_SYSTEM
-         update_toolbar (f, 0);
+         update_tool_bar (f, 0);
 #endif
          UNGCPRO;
        }
@@ -6073,9 +6153,10 @@ prepare_menu_bars ()
     }
   else
     {
-      update_menu_bar (selected_frame, 1);
+      struct frame *sf = SELECTED_FRAME ();
+      update_menu_bar (sf, 1);
 #ifdef HAVE_WINDOW_SYSTEM
-      update_toolbar (selected_frame, 1);
+      update_tool_bar (sf, 1);
 #endif
     }
 
@@ -6178,23 +6259,23 @@ update_menu_bar (f, save_match_data)
 
 \f
 /***********************************************************************
-                              Toolbars
+                              Tool-bars
  ***********************************************************************/
 
 #ifdef HAVE_WINDOW_SYSTEM
 
-/* Update the toolbar item list for frame F.  This has to be done
+/* Update the tool-bar item list for frame F.  This has to be done
    before we start to fill in any display lines.  Called from
    prepare_menu_bars.  If SAVE_MATCH_DATA is non-zero, we must save
    and restore it here.  */
 
 static void
-update_toolbar (f, save_match_data)
+update_tool_bar (f, save_match_data)
      struct frame *f;
      int save_match_data;
 {
-  if (WINDOWP (f->toolbar_window)
-      && XFASTINT (XWINDOW (f->toolbar_window)->height) > 0)
+  if (WINDOWP (f->tool_bar_window)
+      && XFASTINT (XWINDOW (f->tool_bar_window)->height) > 0)
     {
       Lisp_Object window;
       struct window *w;
@@ -6237,12 +6318,12 @@ update_toolbar (f, save_match_data)
              specbind (Qoverriding_local_map, Qnil);
            }
 
-         /* Build desired toolbar items from keymaps.  */
-         f->desired_toolbar_items
-           = toolbar_items (f->desired_toolbar_items,
-                            &f->n_desired_toolbar_items);
+         /* Build desired tool-bar items from keymaps.  */
+         f->desired_tool_bar_items
+           = tool_bar_items (f->desired_tool_bar_items,
+                             &f->n_desired_tool_bar_items);
          
-         /* Redisplay the toolbar in case we changed it.  */
+         /* Redisplay the tool-bar in case we changed it.  */
          w->update_mode_line = Qt;
 
          unbind_to (count, Qnil);
@@ -6252,12 +6333,12 @@ update_toolbar (f, save_match_data)
 }
 
 
-/* Set F->desired_toolbar_string to a Lisp string representing frame
-   F's desired toolbar contents.  F->desired_toolbar_items must have
+/* Set F->desired_tool_bar_string to a Lisp string representing frame
+   F's desired tool-bar contents.  F->desired_tool_bar_items must have
    been set up previously by calling prepare_menu_bars.  */
 
 static void
-build_desired_toolbar_string (f)
+build_desired_tool_bar_string (f)
      struct frame *f;
 {
   int i, size, size_needed, string_idx;
@@ -6267,60 +6348,60 @@ build_desired_toolbar_string (f)
   image = plist = props = Qnil;
   GCPRO3 (image, plist, props);
 
-  /* Prepare F->desired_toolbar_string.  If we can reuse it, do so.
+  /* Prepare F->desired_tool_bar_string.  If we can reuse it, do so.
      Otherwise, make a new string.  */
   
   /* The size of the string we might be able to reuse.  */
-  size = (STRINGP (f->desired_toolbar_string)
-         ? XSTRING (f->desired_toolbar_string)->size
+  size = (STRINGP (f->desired_tool_bar_string)
+         ? XSTRING (f->desired_tool_bar_string)->size
          : 0);
 
   /* Each image in the string we build is preceded by a space,
      and there is a space at the end.  */
-  size_needed = f->n_desired_toolbar_items + 1;
+  size_needed = f->n_desired_tool_bar_items + 1;
 
-  /* Reuse f->desired_toolbar_string, if possible.  */
+  /* Reuse f->desired_tool_bar_string, if possible.  */
   if (size < size_needed)
-    f->desired_toolbar_string = Fmake_string (make_number (size_needed), ' ');
+    f->desired_tool_bar_string = Fmake_string (make_number (size_needed), ' ');
   else
     {
       props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
       Fremove_text_properties (make_number (0), make_number (size),
-                              props, f->desired_toolbar_string);
+                              props, f->desired_tool_bar_string);
     }
 
   /* Put a `display' property on the string for the images to display,
-     put a `menu_item' property on toolbar items with a value that
-     is the index of the item in F's toolbar item vector.  */
+     put a `menu_item' property on tool-bar items with a value that
+     is the index of the item in F's tool-bar item vector.  */
   for (i = 0, string_idx = 0;
-       i < f->n_desired_toolbar_items;
+       i < f->n_desired_tool_bar_items;
        ++i, string_idx += 1)
     {
 #define PROP(IDX)                                      \
-      (XVECTOR (f->desired_toolbar_items)              \
-       ->contents[i * TOOLBAR_ITEM_NSLOTS + (IDX)])
+      (XVECTOR (f->desired_tool_bar_items)             \
+       ->contents[i * TOOL_BAR_ITEM_NSLOTS + (IDX)])
 
-      int enabled_p = !NILP (PROP (TOOLBAR_ITEM_ENABLED_P));
-      int selected_p = !NILP (PROP (TOOLBAR_ITEM_SELECTED_P));
+      int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
+      int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
       int margin, relief;
       extern Lisp_Object QCrelief, QCmargin, QCalgorithm, Qimage;
       extern Lisp_Object Qlaplace;
 
       /* If image is a vector, choose the image according to the
         button state.  */
-      image = PROP (TOOLBAR_ITEM_IMAGES);
+      image = PROP (TOOL_BAR_ITEM_IMAGES);
       if (VECTORP (image))
        {
-         enum toolbar_item_image idx;
+         enum tool_bar_item_image idx;
          
          if (enabled_p)
            idx = (selected_p
-                  ? TOOLBAR_IMAGE_ENABLED_SELECTED
-                  : TOOLBAR_IMAGE_ENABLED_DESELECTED);
+                  ? TOOL_BAR_IMAGE_ENABLED_SELECTED
+                  : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
          else
            idx = (selected_p
-                  ? TOOLBAR_IMAGE_DISABLED_SELECTED
-                  : TOOLBAR_IMAGE_DISABLED_DESELECTED);
+                  ? TOOL_BAR_IMAGE_DISABLED_SELECTED
+                  : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
          
          xassert (XVECTOR (image)->size >= idx);
          image = XVECTOR (image)->contents[idx];
@@ -6330,14 +6411,14 @@ build_desired_toolbar_string (f)
       if (!valid_image_p (image))
        continue;
 
-      /* Display the toolbar button pressed, or depressed.  */
+      /* Display the tool-bar button pressed, or depressed.  */
       plist = Fcopy_sequence (XCDR (image));
 
       /* Compute margin and relief to draw.  */
-      relief = toolbar_button_relief > 0 ? toolbar_button_relief : 3;
-      margin = relief + max (0, toolbar_button_margin);
+      relief = tool_bar_button_relief > 0 ? tool_bar_button_relief : 3;
+      margin = relief + max (0, tool_bar_button_margin);
       
-      if (auto_raise_toolbar_buttons_p)
+      if (auto_raise_tool_bar_buttons_p)
        {
          /* Add a `:relief' property to the image spec if the item is
             selected.  */
@@ -6370,14 +6451,14 @@ build_desired_toolbar_string (f)
       
       /* Put a `display' text property on the string for the image to
         display.  Put a `menu-item' property on the string that gives
-        the start of this item's properties in the toolbar items
+        the start of this item's properties in the tool-bar items
         vector.  */
       image = Fcons (Qimage, plist);
       props = list4 (Qdisplay, image,
-                    Qmenu_item, make_number (i * TOOLBAR_ITEM_NSLOTS)),
+                    Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS)),
       Fadd_text_properties (make_number (string_idx),
                            make_number (string_idx + 1),
-                           props, f->desired_toolbar_string);
+                           props, f->desired_tool_bar_string);
 #undef PROP
     }
 
@@ -6385,10 +6466,10 @@ build_desired_toolbar_string (f)
 }
 
 
-/* Display one line of the toolbar of frame IT->f.  */
+/* Display one line of the tool-bar of frame IT->f.  */
 
 static void
-display_toolbar_line (it)
+display_tool_bar_line (it)
      struct it *it;
 {
   struct glyph_row *row = it->glyph_row;
@@ -6446,7 +6527,7 @@ display_toolbar_line (it)
   last->right_box_line_p = 1;
   compute_line_metrics (it);
   
-  /* If line is empty, make it occupy the rest of the toolbar.  */
+  /* If line is empty, make it occupy the rest of the tool-bar.  */
   if (!row->displays_text_p)
     {
       row->height = row->phys_height = it->last_visible_y - row->y;
@@ -6465,39 +6546,39 @@ display_toolbar_line (it)
 }
 
 
-/* Value is the number of screen lines needed to make all toolbar
+/* Value is the number of screen lines needed to make all tool-bar
    items of frame F visible.  */
 
 static int
-toolbar_lines_needed (f)
+tool_bar_lines_needed (f)
      struct frame *f;
 {
-  struct window *w = XWINDOW (f->toolbar_window);
+  struct window *w = XWINDOW (f->tool_bar_window);
   struct it it;
   
-  /* Initialize an iterator for iteration over F->desired_toolbar_string
-     in the toolbar window of frame F.  */
-  init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOLBAR_FACE_ID);
+  /* Initialize an iterator for iteration over
+     F->desired_tool_bar_string in the tool-bar window of frame F.  */
+  init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
   it.first_visible_x = 0;
   it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
-  reseat_to_string (&it, NULL, f->desired_toolbar_string, 0, 0, 0, -1);
+  reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
 
   while (!ITERATOR_AT_END_P (&it))
     {
       it.glyph_row = w->desired_matrix->rows;
       clear_glyph_row (it.glyph_row);
-      display_toolbar_line (&it);
+      display_tool_bar_line (&it);
     }
 
   return (it.current_y + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
 }
 
 
-/* Display the toolbar of frame F.  Value is non-zero if toolbar's
+/* Display the tool-bar of frame F.  Value is non-zero if tool-bar's
    height should be changed.  */
 
 static int
-redisplay_toolbar (f)
+redisplay_tool_bar (f)
      struct frame *f;
 {
   struct window *w;
@@ -6505,65 +6586,65 @@ redisplay_toolbar (f)
   struct glyph_row *row;
   int change_height_p = 0;
   
-  /* If frame hasn't a toolbar window or if it is zero-height, don't
-     do anything.  This means you must start with toolbar-lines
+  /* If frame hasn't a tool-bar window or if it is zero-height, don't
+     do anything.  This means you must start with tool-bar-lines
      non-zero to get the auto-sizing effect.  Or in other words, you
-     can turn off toolbars by specifying toolbar-lines zero.  */
-  if (!WINDOWP (f->toolbar_window)
-      || (w = XWINDOW (f->toolbar_window),
+     can turn off tool-bars by specifying tool-bar-lines zero.  */
+  if (!WINDOWP (f->tool_bar_window)
+      || (w = XWINDOW (f->tool_bar_window),
          XFASTINT (w->height) == 0))
     return 0;
 
-  /* Set up an iterator for the toolbar window.  */
-  init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOLBAR_FACE_ID);
+  /* Set up an iterator for the tool-bar window.  */
+  init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
   it.first_visible_x = 0;
   it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
   row = it.glyph_row;
 
-  /* Build a string that represents the contents of the toolbar.  */
-  build_desired_toolbar_string (f);
-  reseat_to_string (&it, NULL, f->desired_toolbar_string, 0, 0, 0, -1);
+  /* Build a string that represents the contents of the tool-bar.  */
+  build_desired_tool_bar_string (f);
+  reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
 
-  /* Display as many lines as needed to display all toolbar items.  */
+  /* Display as many lines as needed to display all tool-bar items.  */
   while (it.current_y < it.last_visible_y)
-    display_toolbar_line (&it);
+    display_tool_bar_line (&it);
 
-  /* It doesn't make much sense to try scrolling in the toolbar
+  /* It doesn't make much sense to try scrolling in the tool-bar
      window, so don't do it.  */
   w->desired_matrix->no_scrolling_p = 1;
   w->must_be_updated_p = 1;
 
-  if (auto_resize_toolbars_p)
+  if (auto_resize_tool_bars_p)
     {
       int nlines;
       
       /* If there are blank lines at the end, except for a partially
         visible blank line at the end that is smaller than
-        CANON_Y_UNIT, change the toolbar's height.  */
+        CANON_Y_UNIT, change the tool-bar's height.  */
       row = it.glyph_row - 1;
       if (!row->displays_text_p
          && row->height >= CANON_Y_UNIT (f))
        change_height_p = 1;
 
-      /* If row displays toolbar items, but is partially visible,
-        change the toolbar's height.  */
+      /* If row displays tool-bar items, but is partially visible,
+        change the tool-bar's height.  */
       if (row->displays_text_p
          && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
        change_height_p = 1;
 
-      /* Resize windows as needed by changing the `toolbar-lines'
+      /* Resize windows as needed by changing the `tool-bar-lines'
         frame parameter.  */
       if (change_height_p
-         && (nlines = toolbar_lines_needed (f),
+         && (nlines = tool_bar_lines_needed (f),
              nlines != XFASTINT (w->height)))
        {
-         extern Lisp_Object Qtoolbar_lines;
+         extern Lisp_Object Qtool_bar_lines;
          Lisp_Object frame;
          
          XSETFRAME (frame, f);
          clear_glyph_matrix (w->desired_matrix);
          Fmodify_frame_parameters (frame,
-                                   Fcons (Fcons (Qtoolbar_lines,
+                                   Fcons (Fcons (Qtool_bar_lines,
                                                  make_number (nlines)),
                                           Qnil));
          fonts_changed_p = 1;
@@ -6574,13 +6655,13 @@ redisplay_toolbar (f)
 }
 
 
-/* Get information about the toolbar item which is displayed in GLYPH
-   on frame F.  Return in *PROP_IDX the index where toolbar item
-   properties start in F->current_toolbar_items.  Value is zero if
-   GLYPH doesn't display a toolbar item.  */
+/* Get information about the tool-bar item which is displayed in GLYPH
+   on frame F.  Return in *PROP_IDX the index where tool-bar item
+   properties start in F->current_tool_bar_items.  Value is zero if
+   GLYPH doesn't display a tool-bar item.  */
 
 int
-toolbar_item_info (f, glyph, prop_idx)
+tool_bar_item_info (f, glyph, prop_idx)
      struct frame *f;
      struct glyph *glyph;
      int *prop_idx;
@@ -6590,9 +6671,9 @@ toolbar_item_info (f, glyph, prop_idx)
   
   /* Get the text property `menu-item' at pos. The value of that
      property is the start index of this item's properties in
-     F->current_toolbar_items.  */
+     F->current_tool_bar_items.  */
   prop = Fget_text_property (make_number (glyph->charpos),
-                            Qmenu_item, f->current_toolbar_string);
+                            Qmenu_item, f->current_tool_bar_string);
   if (INTEGERP (prop))
     {
       *prop_idx = XINT (prop);
@@ -6639,8 +6720,14 @@ hscroll_window_tree (window)
        {
          int hscroll_margin, text_area_x, text_area_y;
          int text_area_width, text_area_height;
-         struct glyph_row *cursor_row = MATRIX_ROW (w->current_matrix,
-                                                    w->cursor.vpos);
+         struct glyph_row *current_cursor_row
+           = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
+         struct glyph_row *desired_cursor_row
+           = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
+         struct glyph_row *cursor_row
+           = (desired_cursor_row->enabled_p
+              ? desired_cursor_row
+              : current_cursor_row);
 
          window_box (w, TEXT_AREA, &text_area_x, &text_area_y,
                      &text_area_width, &text_area_height);
@@ -6650,7 +6737,8 @@ hscroll_window_tree (window)
          
          if ((XFASTINT (w->hscroll)
               && w->cursor.x < hscroll_margin)
-             || (cursor_row->truncated_on_right_p
+             || (cursor_row->enabled_p
+                 && cursor_row->truncated_on_right_p
                  && (w->cursor.x > text_area_width - hscroll_margin)))
            {
              struct it it;
@@ -6729,11 +6817,6 @@ hscroll_windows (window)
 
 #if GLYPH_DEBUG
 
-/* Values of beg_unchanged and end_unchanged as of last call to
-   try_window_id.  */
-
-int debug_beg_unchanged, debug_end_unchanged;
-
 /* First and last unchanged row for try_window_id.  */
 
 int debug_first_unchanged_at_end_vpos;
@@ -6830,8 +6913,8 @@ text_outside_line_unchanged_p (w, start, end)
 
       /* Changes start in front of the line, or end after it?  */
       if (unchanged_p
-         && (beg_unchanged < start - 1
-             || end_unchanged < end))
+         && (BEG_UNCHANGED < start - 1
+             || END_UNCHANGED < end))
        unchanged_p = 0;
       
       /* If selective display, can't optimize if changes start at the
@@ -6839,7 +6922,7 @@ text_outside_line_unchanged_p (w, start, end)
       if (unchanged_p
          && INTEGERP (current_buffer->selective_display)
          && XINT (current_buffer->selective_display) > 0
-         && (beg_unchanged < start || GPT <= start))
+         && (BEG_UNCHANGED < start || GPT <= start))
        unchanged_p = 0;
     }
 
@@ -6861,6 +6944,25 @@ redisplay ()
 }
 
 
+/* Reconsider the setting of B->clip_changed which is displayed
+   in window W.  */
+
+static INLINE void
+reconsider_clip_changes (w, b)
+     struct window *w;
+     struct buffer *b;
+{
+  if (b->prevent_redisplay_optimizations_p)
+    b->clip_changed = 1;
+  else if (b->clip_changed
+          && !NILP (w->window_end_valid)
+          && w->current_matrix->buffer == b
+          && w->current_matrix->zv == BUF_ZV (b)
+          && w->current_matrix->begv == BUF_BEGV (b))
+    b->clip_changed = 0;
+}
+
+
 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
    response to any user action; therefore, we should preserve the echo
    area.  (Actually, our caller does that job.)  Perhaps in the future
@@ -6878,6 +6980,7 @@ redisplay_internal (preserve_echo_area)
   struct text_pos tlbufpos, tlendpos;
   int number_of_visible_frames;
   int count;
+  struct frame *sf = SELECTED_FRAME ();
 
   /* Non-zero means redisplay has to consider all windows on all
      frames.  Zero means, only selected_window is considered.  */
@@ -6920,6 +7023,8 @@ redisplay_internal (preserve_echo_area)
   
  retry:
 
+  reconsider_clip_changes (w, current_buffer);
+
   /* If new fonts have been loaded that make a glyph matrix adjustment
      necessary, do it.  */
   if (fonts_changed_p)
@@ -6929,17 +7034,17 @@ redisplay_internal (preserve_echo_area)
       fonts_changed_p = 0;
     }
 
-  if (! FRAME_WINDOW_P (selected_frame)
-      && previous_terminal_frame != selected_frame)
+  if (! FRAME_WINDOW_P (sf)
+      && previous_terminal_frame != sf)
     {
       /* Since frames on an ASCII terminal share the same display
         area, displaying a different frame means redisplay the whole
         thing.  */
       windows_or_buffers_changed++;
-      SET_FRAME_GARBAGED (selected_frame);
-      XSETFRAME (Vterminal_frame, selected_frame);
+      SET_FRAME_GARBAGED (sf);
+      XSETFRAME (Vterminal_frame, sf);
     }
-  previous_terminal_frame = selected_frame;
+  previous_terminal_frame = sf;
 
   /* Set the visible flags for all frames.  Do this before checking
      for resized or garbaged frames; they want to know if their frames
@@ -6968,11 +7073,9 @@ redisplay_internal (preserve_echo_area)
   if (frame_garbaged)
     clear_garbaged_frames ();
 
-  /* Build menubar and toolbar items.  */
+  /* Build menubar and tool-bar items.  */
   prepare_menu_bars ();
 
- retry_1:
-
   if (windows_or_buffers_changed)
     update_mode_lines++;
 
@@ -7024,13 +7127,19 @@ redisplay_internal (preserve_echo_area)
          consider_all_windows_p = 1;
          ++update_mode_lines;
          ++windows_or_buffers_changed;
+         
+         /* If window configuration was changed, frames may have been
+            marked garbaged.  Clear them or we will experience
+            surprises wrt scrolling.  */
+         if (frame_garbaged)
+           clear_garbaged_frames ();
        }
     }
   else if (w == XWINDOW (minibuf_window)
           && (current_buffer->clip_changed
               || XFASTINT (w->last_modified) < MODIFF
               || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
-          && resize_mini_window (w))
+          && resize_mini_window (w, 0))
     {
       /* Resized active mini-window to fit the size of what it is
          showing if its contents might have changed.  */
@@ -7038,6 +7147,12 @@ redisplay_internal (preserve_echo_area)
       consider_all_windows_p = 1;
       ++windows_or_buffers_changed;
       ++update_mode_lines;
+      
+      /* If window configuration was changed, frames may have been
+        marked garbaged.  Clear them or we will experience
+        surprises wrt scrolling.  */
+      if (frame_garbaged)
+       clear_garbaged_frames ();
     }
   
 
@@ -7283,7 +7398,7 @@ redisplay_internal (preserve_echo_area)
       FOR_EACH_FRAME (tail, frame)
        {
          struct frame *f = XFRAME (frame);
-         if (FRAME_WINDOW_P (f) || f == selected_frame)
+         if (FRAME_WINDOW_P (f) || f == sf)
            {
              /* Mark all the scroll bars to be removed; we'll redeem
                 the ones we want when we redisplay their windows.  */
@@ -7300,8 +7415,8 @@ redisplay_internal (preserve_echo_area)
            }
        }
     }
-  else if (FRAME_VISIBLE_P (selected_frame)
-          && !FRAME_OBSCURED_P (selected_frame))
+  else if (FRAME_VISIBLE_P (sf)
+          && !FRAME_OBSCURED_P (sf))
     redisplay_window (selected_window, 1);
 
   
@@ -7323,19 +7438,37 @@ update:
   if (consider_all_windows_p)
     {
       Lisp_Object tail;
+      struct frame *f;
+      int hscrolled_p;
 
       pause = 0;
+      hscrolled_p = 0;
 
-      for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
-       {
-         struct frame *f;
+      /* See if we have to hscroll.  */
+      for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
+       if (FRAMEP (XCAR (tail)))
+         {
+           f = XFRAME (XCAR (tail));
+           
+           if ((FRAME_WINDOW_P (f)
+                || f == sf)
+               && FRAME_VISIBLE_P (f)
+               && !FRAME_OBSCURED_P (f)
+               && hscroll_windows (f->root_window))
+             hscrolled_p = 1;
+         }
 
-         if (!FRAMEP (XCONS (tail)->car))
+      if (hscrolled_p)
+       goto retry;
+
+      for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
+       {
+         if (!FRAMEP (XCAR (tail)))
            continue;
 
-         f = XFRAME (XCONS (tail)->car);
+         f = XFRAME (XCAR (tail));
 
-         if ((FRAME_WINDOW_P (f) || f == selected_frame)
+         if ((FRAME_WINDOW_P (f) || f == sf)
              && FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
            {
              /* Mark all windows as to be updated.  */
@@ -7343,9 +7476,6 @@ update:
              pause |= update_frame (f, 0, 0);
              if (!pause)
                {
-                 if (hscroll_windows (f->root_window))
-                   goto retry;
-
                  mark_window_display_accurate (f->root_window, 1);
                  if (frame_up_to_date_hook != 0)
                    (*frame_up_to_date_hook) (f);
@@ -7355,13 +7485,14 @@ update:
     }
   else
     {
-      if (FRAME_VISIBLE_P (selected_frame)
-         && !FRAME_OBSCURED_P (selected_frame))
+      if (FRAME_VISIBLE_P (sf)
+         && !FRAME_OBSCURED_P (sf))
        {
-         XWINDOW (selected_window)->must_be_updated_p = 1;
-         pause = update_frame (selected_frame, 0, 0);
-         if (!pause && hscroll_windows (selected_window))
+         if (hscroll_windows (selected_window))
            goto retry;
+         
+         XWINDOW (selected_window)->must_be_updated_p = 1;
+         pause = update_frame (sf, 0, 0);
        }
       else
        pause = 0;
@@ -7375,10 +7506,10 @@ update:
        Lisp_Object mini_window;
        struct frame *mini_frame;
 
-       mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
+       mini_window = FRAME_MINIBUF_WINDOW (sf);
        mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
        
-       if (mini_frame != selected_frame && FRAME_WINDOW_P (mini_frame))
+       if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
          {
            XWINDOW (mini_window)->must_be_updated_p = 1;
            pause |= update_frame (mini_frame, 0, 0);
@@ -7417,13 +7548,13 @@ update:
     {
       register struct buffer *b = XBUFFER (w->buffer);
 
-      unchanged_modified = BUF_MODIFF (b);
-      overlay_unchanged_modified = BUF_OVERLAY_MODIFF (b);
-      beg_unchanged = BUF_GPT (b) - BUF_BEG (b);
-      end_unchanged = BUF_Z (b) - BUF_GPT (b);
+      BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
+      BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
+      BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
+      BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
 
       if (consider_all_windows_p)
-       mark_window_display_accurate (FRAME_ROOT_WINDOW (selected_frame), 1);
+       mark_window_display_accurate (FRAME_ROOT_WINDOW (sf), 1);
       else
        {
          XSETFASTINT (w->last_point, BUF_PT (b));
@@ -7431,6 +7562,7 @@ update:
          w->last_cursor_off_p = w->cursor_off_p;
 
          b->clip_changed = 0;
+         b->prevent_redisplay_optimizations_p = 0;
          w->update_mode_line = Qnil;
          XSETFASTINT (w->last_modified, BUF_MODIFF (b));
          XSETFASTINT (w->last_overlay_modified, BUF_OVERLAY_MODIFF (b));
@@ -7451,7 +7583,11 @@ update:
          last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
          last_arrow_string = Voverlay_arrow_string;
          if (frame_up_to_date_hook != 0)
-           (*frame_up_to_date_hook) (selected_frame);
+           (*frame_up_to_date_hook) (sf);
+
+         w->current_matrix->buffer = b;
+         w->current_matrix->begv = BUF_BEGV (b);
+         w->current_matrix->zv = BUF_ZV (b);
        }
       
       update_mode_lines = 0;
@@ -7589,6 +7725,10 @@ mark_window_display_accurate (window, accurate_p)
          if (accurate_p)
            {
              b->clip_changed = 0;
+             b->prevent_redisplay_optimizations_p = 0;
+             w->current_matrix->buffer = b;
+             w->current_matrix->begv = BUF_BEGV (b);
+             w->current_matrix->zv = BUF_ZV (b);
              w->last_cursor = w->cursor;
              w->last_cursor_off_p = w->cursor_off_p;
              if (w == XWINDOW (selected_window))
@@ -7767,7 +7907,9 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
 
 
 /* Run window scroll functions, if any, for WINDOW with new window
-   start STARTP.  Sets the window start of WINDOW to that position.  */
+   start STARTP.  Sets the window start of WINDOW to that position.
+
+   We assume that the window's buffer is really current.  */
 
 static INLINE struct text_pos
 run_window_scroll_functions (window, startp)
@@ -7776,12 +7918,18 @@ run_window_scroll_functions (window, startp)
 {
   struct window *w = XWINDOW (window);
   SET_MARKER_FROM_TEXT_POS (w->start, startp);
-  
+
+  if (current_buffer != XBUFFER (w->buffer))
+    abort ();
+
   if (!NILP (Vwindow_scroll_functions))
     {
       run_hook_with_args_2 (Qwindow_scroll_functions, window, 
                            make_number (CHARPOS (startp)));
       SET_TEXT_POS_FROM_MARKER (startp, w->start);
+      /* In case the hook functions switch buffers.  */
+      if (current_buffer != XBUFFER (w->buffer))
+       set_buffer_internal_1 (XBUFFER (w->buffer));
     }
 
   return startp;
@@ -7797,7 +7945,7 @@ make_cursor_line_fully_visible (w)
 {
   struct glyph_matrix *matrix;
   struct glyph_row *row;
-  int top_line_height;
+  int header_line_height;
   
   /* It's not always possible to find the cursor, e.g, when a window
      is full of overlay strings.  Don't do anything in that case.  */
@@ -7810,8 +7958,8 @@ make_cursor_line_fully_visible (w)
   /* If row->y == top y of window display area, the window isn't tall
      enough to display a single line.  There is nothing we can do
      about it.  */
-  top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
-  if (row->y == top_line_height)
+  header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
+  if (row->y == header_line_height)
     return;
 
   if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
@@ -7956,7 +8104,7 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
        {
          aggressive = current_buffer->scroll_down_aggressively;
          height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
-                   - WINDOW_DISPLAY_TOP_LINE_HEIGHT (w));
+                   - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
          if (NUMBERP (aggressive))
            amount_to_scroll = XFLOATINT (aggressive) * height;
        }
@@ -8009,7 +8157,7 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
            {
              aggressive = current_buffer->scroll_up_aggressively;
              height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
-                       - WINDOW_DISPLAY_TOP_LINE_HEIGHT (w));
+                       - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
              if (NUMBERP (aggressive))
                amount_to_scroll = XFLOATINT (aggressive) * height;
            }
@@ -8039,7 +8187,7 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
       /* Maybe forget recorded base line for line number display.  */
       if (!just_this_one_p 
          || current_buffer->clip_changed
-         || beg_unchanged < CHARPOS (startp))
+         || BEG_UNCHANGED < CHARPOS (startp))
        w->base_line_number = Qnil;
       
       /* If cursor ends up on a partially visible line, shift display
@@ -8077,10 +8225,16 @@ compute_window_start_on_continuation_line (w)
     {
       struct it it;
       struct glyph_row *row;
+
+      /* Handle the case that the window start is out of range.  */
+      if (CHARPOS (start_pos) < BEGV)
+       SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
+      else if (CHARPOS (start_pos) > ZV)
+       SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
       
       /* Find the start of the continued line.  This should be fast
         because scan_buffer is fast (newline cache).  */
-      row = w->desired_matrix->rows + (WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0);
+      row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
       init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
                     row, DEFAULT_FACE_ID);
       reseat_at_previous_visible_line_start (&it);
@@ -8150,7 +8304,9 @@ redisplay_window (window, just_this_one_p)
 #endif
 
   specbind (Qinhibit_point_motion_hooks, Qt);
-  
+
+  reconsider_clip_changes (w, buffer);
+    
   /* Has the mode line to be updated?  */ 
   update_mode_line = (!NILP (w->update_mode_line)
                      || update_mode_lines
@@ -8163,7 +8319,7 @@ redisplay_window (window, just_this_one_p)
        {
          if (update_mode_line)
            /* We may have to update a tty frame's menu bar or a
-              toolbar.  Example `M-x C-h C-h C-g'.  */
+              tool-bar.  Example `M-x C-h C-h C-g'.  */
            goto finish_menu_bars;
          else
            /* We've already displayed the echo area glyphs in this window.  */
@@ -8311,7 +8467,8 @@ redisplay_window (window, just_this_one_p)
 
   /* Handle case where place to start displaying has been specified,
      unless the specified location is outside the accessible range.  */
-  if (!NILP (w->force_start))
+  if (!NILP (w->force_start)
+      || w->frozen_window_start_p)
     {
       w->force_start = Qnil;
       w->vscroll = 0;
@@ -8360,7 +8517,7 @@ redisplay_window (window, just_this_one_p)
          goto restore_buffers;
        }
 
-      if (w->cursor.vpos < 0)
+      if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
        {
          /* If point does not appear, or on a line that is not fully
             visible, move point so it does appear.  The desired
@@ -8573,12 +8730,12 @@ redisplay_window (window, just_this_one_p)
     }
   
   /* Try scrolling with try_window_id.  */
-  else if (!windows_or_buffers_changed
+  else if (/* Windows and buffers haven't changed.  */
+          !windows_or_buffers_changed
           /* Window must be either use window-based redisplay or
              be full width.  */
           && (FRAME_WINDOW_P (f)
-              || ((line_ins_del_ok && WINDOW_FULL_WIDTH_P (w))
-                  && just_this_one_p))
+              || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)))
           && !MINI_WINDOW_P (w)
           /* Point is not known NOT to appear in window.  */
           && PT >= CHARPOS (startp)
@@ -8647,7 +8804,7 @@ redisplay_window (window, just_this_one_p)
        {
          if (!just_this_one_p 
              || current_buffer->clip_changed
-             || beg_unchanged < CHARPOS (startp))
+             || BEG_UNCHANGED < CHARPOS (startp))
            /* Forget any recorded base line for line number display.  */
            w->base_line_number = Qnil;
          
@@ -8798,13 +8955,13 @@ redisplay_window (window, just_this_one_p)
   
   make_cursor_line_fully_visible (w);
 
+ done:
+
   SET_TEXT_POS_FROM_MARKER (startp, w->start);
   w->start_at_line_beg = ((CHARPOS (startp) == BEGV
                           || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
                          ? Qt : Qnil);
 
- done:
-
   /* Display the mode line, if we must.  */
   if ((update_mode_line
        /* If window not full width, must redo its mode line
@@ -8821,7 +8978,7 @@ redisplay_window (window, just_this_one_p)
           && XFASTINT (w->column_number_displayed) != current_column ()))
        /* This means that the window has a mode line.  */
        && (WINDOW_WANTS_MODELINE_P (w)
-          || WINDOW_WANTS_TOP_LINE_P (w)))
+          || WINDOW_WANTS_HEADER_LINE_P (w)))
     {
       display_mode_lines (w);
 
@@ -8837,12 +8994,12 @@ redisplay_window (window, just_this_one_p)
       
       /* If top line height has changed, arrange for a thorough
         immediate redisplay using the correct mode line height.  */
-      if (WINDOW_WANTS_TOP_LINE_P (w)
-         && CURRENT_TOP_LINE_HEIGHT (w) != DESIRED_TOP_LINE_HEIGHT (w))
+      if (WINDOW_WANTS_HEADER_LINE_P (w)
+         && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
        {
          fonts_changed_p = 1;
-         MATRIX_TOP_LINE_ROW (w->current_matrix)->height
-           = DESIRED_TOP_LINE_HEIGHT (w);
+         MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
+           = DESIRED_HEADER_LINE_HEIGHT (w);
        }
 
       if (fonts_changed_p)
@@ -8879,10 +9036,10 @@ redisplay_window (window, just_this_one_p)
         display_menu_bar (w);
 
 #ifdef HAVE_WINDOW_SYSTEM
-      if (WINDOWP (f->toolbar_window)
-         && (FRAME_TOOLBAR_LINES (f) > 0
-             || auto_resize_toolbars_p))
-       redisplay_toolbar (f);
+      if (WINDOWP (f->tool_bar_window)
+         && (FRAME_TOOL_BAR_LINES (f) > 0
+             || auto_resize_tool_bars_p))
+       redisplay_tool_bar (f);
 #endif
     }
 
@@ -9042,8 +9199,8 @@ try_window_reusing_current_matrix (w)
     return 0;
 
   /* If top-line visibility has changed, give up.  */
-  if (WINDOW_WANTS_TOP_LINE_P (w)
-      != MATRIX_TOP_LINE_ROW (w->current_matrix)->mode_line_p)
+  if (WINDOW_WANTS_HEADER_LINE_P (w)
+      != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
     return 0;
 
   /* Give up if old or new display is scrolled vertically.  We could
@@ -9150,7 +9307,7 @@ try_window_reusing_current_matrix (w)
          
          /* Re-compute Y positions.  */
          row = MATRIX_FIRST_TEXT_ROW (w->current_matrix) + nrows_scrolled;
-         min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
+         min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
          max_y = it.last_visible_y;
          while (row < bottom_row)
            {
@@ -9293,7 +9450,7 @@ try_window_reusing_current_matrix (w)
 
       /* Scroll the display.  */
       run.current_y = first_reusable_row->y;
-      run.desired_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
+      run.desired_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
       run.height = it.last_visible_y - run.current_y;
       if (run.height)
        {
@@ -9309,7 +9466,7 @@ try_window_reusing_current_matrix (w)
       bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
       row = first_reusable_row;
       dy = first_reusable_row->y;
-      min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
+      min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
       max_y = it.last_visible_y;
       while (row < first_row_to_display)
        {
@@ -9428,7 +9585,7 @@ static struct glyph_row *
 get_last_unchanged_at_beg_row (w)
      struct window *w;
 {
-  int first_changed_pos = BEG + beg_unchanged;
+  int first_changed_pos = BEG + BEG_UNCHANGED;
   struct glyph_row *row;
   struct glyph_row *row_found = NULL;
   int yb = window_text_bottom_y (w);
@@ -9465,14 +9622,10 @@ get_last_unchanged_at_beg_row (w)
 /* Find the first glyph row in the current matrix of W that is not
    affected by changes at the end of current_buffer since the last
    time the window was redisplayed.  Return in *DELTA the number of
-   bytes by which buffer positions in unchanged text at the end of
-   current_buffer must be adjusted.  Value is null if no such row
-   exists, i.e. all rows are affected by changes.
-
-   The global variable end_unchanged is assumed to contain the number
-   of unchanged bytes at the end of current_buffer.  The buffer
-   position of the last changed byte in current_buffer is then Z -
-   end_unchanged.  */
+   chars by which buffer positions in unchanged text at the end of
+   current_buffer must be adjusted.  Return in *DELTA_BYTES the
+   corresponding number of bytes.  Value is null if no such row
+   exists, i.e. all rows are affected by changes.  */
    
 static struct glyph_row *
 get_first_unchanged_at_end_row (w, delta, delta_bytes)
@@ -9488,7 +9641,7 @@ get_first_unchanged_at_end_row (w, delta, delta_bytes)
      end is in the range of changed text.  If so, there is no
      unchanged row at the end of W's current matrix.  */
   xassert (!NILP (w->window_end_valid));
-  if (XFASTINT (w->window_end_pos) >= end_unchanged)
+  if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
     return NULL;
 
   /* Set row to the last row in W's current matrix displaying text.  */
@@ -9517,7 +9670,7 @@ get_first_unchanged_at_end_row (w, delta, delta_bytes)
         subtracting end_unchanged we get the index of the last
         unchanged character, and we have to add BEG to get its buffer
         position.  */
-      last_unchanged_pos = Z - end_unchanged + BEG;
+      last_unchanged_pos = Z - END_UNCHANGED + BEG;
       last_unchanged_pos_old = last_unchanged_pos - *delta;
       
       /* Search backward from ROW for a row displaying a line that
@@ -9566,13 +9719,65 @@ sync_frame_with_window_matrix_rows (w)
   while (window_row < window_row_end)
     {
       int area;
+      
       for (area = LEFT_MARGIN_AREA; area <= LAST_AREA; ++area)
        frame_row->glyphs[area] = window_row->glyphs[area];
+
+      /* Disable frame rows whose corresponding window rows have
+        been disabled in try_window_id.  */
+      if (!window_row->enabled_p)
+       frame_row->enabled_p = 0;
+      
       ++window_row, ++frame_row;
     }
 }
 
 
+/* Find the glyph row in window W containing CHARPOS.  Consider all
+   rows between START and END (not inclusive).  END null means search
+   all rows to the end of the display area of W.  Value is the row
+   containing CHARPOS or null.  */
+
+static struct glyph_row *
+row_containing_pos (w, charpos, start, end)
+     struct window *w;
+     int charpos;
+     struct glyph_row *start, *end;
+{
+  struct glyph_row *row = start;
+  int last_y;
+
+  /* If we happen to start on a header-line, skip that.  */
+  if (row->mode_line_p)
+    ++row;
+  
+  if ((end && row >= end) || !row->enabled_p)
+    return NULL;
+  
+  last_y = window_text_bottom_y (w);
+      
+  while ((end == NULL || row < end)
+        && (MATRIX_ROW_END_CHARPOS (row) < charpos
+            /* The end position of a row equals the start
+               position of the next row.  If CHARPOS is there, we
+               would rather display it in the next line, except
+               when this line ends in ZV.  */
+            || (MATRIX_ROW_END_CHARPOS (row) == charpos
+                && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
+                    || !row->ends_at_zv_p)))
+        && MATRIX_ROW_BOTTOM_Y (row) < last_y)
+    ++row;
+      
+  /* Give up if CHARPOS not found.  */
+  if ((end && row >= end)
+      || charpos < MATRIX_ROW_START_CHARPOS (row)
+      || charpos > MATRIX_ROW_END_CHARPOS (row))
+    row = NULL;
+
+  return row;
+}
+
+
 /* Try to redisplay window W by reusing its existing display.  W's
    current matrix must be up to date when this function is called,
    i.e. window_end_valid must not be nil.
@@ -9644,10 +9849,10 @@ try_window_id (w)
      set end_unchanged to 0 in that case.  */
   if (MODIFF > SAVE_MODIFF)
     {
-      if (GPT - BEG < beg_unchanged)
-       beg_unchanged = GPT - BEG;
-      if (Z - GPT < end_unchanged)
-       end_unchanged = Z - GPT;
+      if (GPT - BEG < BEG_UNCHANGED)
+       BEG_UNCHANGED = GPT - BEG;
+      if (Z - GPT < END_UNCHANGED)
+       END_UNCHANGED = Z - GPT;
     }
   
   /* If window starts after a line end, and the last change is in
@@ -9655,7 +9860,7 @@ try_window_id (w)
      This case happens with stealth-fontification.  */
   row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
   if (CHARPOS (start) > BEGV
-      && Z - end_unchanged < CHARPOS (start) - 1
+      && Z - END_UNCHANGED < CHARPOS (start) - 1
       && FETCH_BYTE (BYTEPOS (start) - 1) == '\n'
       && PT < MATRIX_ROW_END_CHARPOS (row))
     {
@@ -9670,7 +9875,7 @@ try_window_id (w)
 
   /* Return quickly if changes are all below what is displayed in the
      window, and if PT is in the window.  */
-  if (beg_unchanged > MATRIX_ROW_END_CHARPOS (row)
+  if (BEG_UNCHANGED > MATRIX_ROW_END_CHARPOS (row)
       && PT < MATRIX_ROW_END_CHARPOS (row))
     {
       /* We have to update window end positions because the buffer's
@@ -9690,10 +9895,6 @@ try_window_id (w)
   if (!TEXT_POS_EQUAL_P (start, row->start.pos))
     return 0;
 
-  /* Remember beg_unchanged and end_unchanged for debugging purposes.  */
-  IF_DEBUG (debug_beg_unchanged = beg_unchanged;
-           debug_end_unchanged = end_unchanged);
-
   /* Compute the position at which we have to start displaying new
      lines.  Some of the lines at the top of the window might be
      reusable because they are not displaying changed text.  Find the
@@ -9724,9 +9925,6 @@ try_window_id (w)
       start_pos = it.current.pos;
     }
 
-  bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
-  bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
-  
   /* Find the first row that is not affected by changes at the end of
      the buffer.  Value will be null if there is no unchanged row, in
      which case we must redisplay to the end of the window.  delta
@@ -9769,7 +9967,7 @@ try_window_id (w)
                      + delta);
          first_unchanged_at_end_vpos
            = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
-         xassert (stop_pos >= Z - end_unchanged);
+         xassert (stop_pos >= Z - END_UNCHANGED);
        }
     }
   else if (last_unchanged_at_beg_row == NULL)
@@ -9815,7 +10013,10 @@ try_window_id (w)
   /* Compute differences in buffer positions, y-positions etc.  for
      lines reused at the bottom of the window.  Compute what we can
      scroll.  */
-  if (first_unchanged_at_end_row)
+  if (first_unchanged_at_end_row
+      /* No lines reused because we displayed everything up to the
+         bottom of the window.  */
+      && it.current_y < it.last_visible_y)
     {
       dvpos = (it.vpos
               - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
@@ -9826,10 +10027,13 @@ try_window_id (w)
       run.height = it.last_visible_y - max (run.current_y, run.desired_y);
     }
   else
-    delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
+    {
+      delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
+      first_unchanged_at_end_row = NULL;
+    }
   IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
 
-  
+
   /* Find the cursor if not already found.  We have to decide whether
      PT will appear on this window (it sometimes doesn't, but this is
      not a very frequent case.)  This decision has to be made before
@@ -9840,37 +10044,25 @@ try_window_id (w)
      mentioned, this is not a frequent case.  */
   if (w->cursor.vpos < 0)
     {
-      int last_y = min (it.last_visible_y, it.last_visible_y + dy);
-
       /* Cursor in unchanged rows at the top?  */
       if (PT < CHARPOS (start_pos)
          && last_unchanged_at_beg_row)
        {
-         row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
-         while (row <= last_unchanged_at_beg_row
-                && MATRIX_ROW_END_CHARPOS (row) <= PT)
-           ++row;
-         xassert (row <= last_unchanged_at_beg_row);
+         row = row_containing_pos (w, PT,
+                                   MATRIX_FIRST_TEXT_ROW (w->current_matrix),
+                                   last_unchanged_at_beg_row + 1);
+         xassert (row && row <= last_unchanged_at_beg_row);
          set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
        }
 
       /* Start from first_unchanged_at_end_row looking for PT.  */
       else if (first_unchanged_at_end_row)
        {
-         row = first_unchanged_at_end_row;
-         while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
-           {
-             if (PT - delta >= MATRIX_ROW_START_CHARPOS (row)
-                 && PT - delta < MATRIX_ROW_END_CHARPOS (row))
-               {
-                 set_cursor_from_row (w, row, w->current_matrix, delta,
-                                      delta_bytes, dy, dvpos);
-                 break;
-               }
-             else if (MATRIX_ROW_BOTTOM_Y (row) >= last_y)
-               break;
-             ++row;
-           }
+         row = row_containing_pos (w, PT - delta,
+                                   first_unchanged_at_end_row, NULL);
+         if (row)
+           set_cursor_from_row (w, row, w->current_matrix, delta,
+                                delta_bytes, dy, dvpos);
        }
 
       /* Give up if cursor was not found.  */
@@ -9965,7 +10157,11 @@ try_window_id (w)
       update_end (f);
     }
 
-  /* Shift reused rows of the current matrix to the right position.  */
+  /* Shift reused rows of the current matrix to the right position.
+     BOTTOM_ROW is the last + 1 row in the current matrix reserved for
+     text.  */
+  bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
+  bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
   if (dvpos < 0)
     {
       rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
@@ -10099,13 +10295,13 @@ try_window_id (w)
       /* Displayed to end of window, but no line containing text was
         displayed.  Lines were deleted at the end of the window.  */
       int vpos;
-      int top_line_p = WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0;
+      int header_line_p = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
 
       for (vpos = XFASTINT (w->window_end_vpos); vpos > 0; --vpos)
-       if ((w->desired_matrix->rows[vpos + top_line_p].enabled_p
-            && w->desired_matrix->rows[vpos + top_line_p].displays_text_p)
-           || (!w->desired_matrix->rows[vpos + top_line_p].enabled_p
-               && w->current_matrix->rows[vpos + top_line_p].displays_text_p))
+       if ((w->desired_matrix->rows[vpos + header_line_p].enabled_p
+            && w->desired_matrix->rows[vpos + header_line_p].displays_text_p)
+           || (!w->desired_matrix->rows[vpos + header_line_p].enabled_p
+               && w->current_matrix->rows[vpos + header_line_p].displays_text_p))
          break;
 
       w->window_end_vpos = make_number (vpos);
@@ -10296,11 +10492,12 @@ DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 1, "",
 }
 
 
-DEFUN ("dump-toolbar-row", Fdump_toolbar_row, Sdump_toolbar_row,
+DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row,
        0, 0, "", "")
   ()
 {
-  struct glyph_matrix *m = (XWINDOW (selected_frame->toolbar_window)
+  struct frame *sf = SELECTED_FRAME ();
+  struct glyph_matrix *m = (XWINDOW (sf->tool_bar_window)
                            ->current_matrix);
   dump_glyph_row (m, 0, 1);
   return Qnil;
@@ -10457,7 +10654,7 @@ compute_line_metrics (it)
 
   if (FRAME_WINDOW_P (it->f))
     {
-      int i, top_line_height;
+      int i, header_line_height;
 
       /* The line may consist of one space only, that was added to
         place the cursor on it.  If so, the row's height hasn't been
@@ -10496,9 +10693,9 @@ compute_line_metrics (it)
       /* Compute how much of the line is visible.  */
       row->visible_height = row->height;
       
-      top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (it->w);
-      if (row->y < top_line_height)
-       row->visible_height -= top_line_height - row->y;
+      header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (it->w);
+      if (row->y < header_line_height)
+       row->visible_height -= header_line_height - row->y;
       else
        {
          int max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (it->w);
@@ -11215,15 +11412,17 @@ display_mode_lines (w)
   w->column_number_displayed = Qnil;
 
   if (WINDOW_WANTS_MODELINE_P (w))
-    display_mode_line (w, MODE_LINE_FACE_ID, current_buffer->mode_line_format);
+    display_mode_line (w, MODE_LINE_FACE_ID,
+                      current_buffer->mode_line_format);
   
-  if (WINDOW_WANTS_TOP_LINE_P (w))
-    display_mode_line (w, TOP_LINE_FACE_ID, current_buffer->top_line_format);
+  if (WINDOW_WANTS_HEADER_LINE_P (w))
+    display_mode_line (w, HEADER_LINE_FACE_ID,
+                      current_buffer->header_line_format);
 }
 
 
 /* Display mode or top line of window W.  FACE_ID specifies which line
-   to display; it is either MODE_LINE_FACE_ID or TOP_LINE_FACE_ID.
+   to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
    FORMAT is the mode line format to display.  */
 
 static void
@@ -11441,7 +11640,7 @@ display_mode_element (it, depth, field_width, precision, elt)
           to at least that many characters.
           If first element is a symbol, process the cadr or caddr recursively
           according to whether the symbol's value is non-nil or nil.  */
-       car = XCONS (elt)->car;
+       car = XCAR (elt);
        if (EQ (car, QCeval) && CONSP (XCDR (elt)))
          {
            /* An element of the form (:eval FORM) means evaluate FORM
@@ -11458,7 +11657,7 @@ display_mode_element (it, depth, field_width, precision, elt)
        else if (SYMBOLP (car))
          {
            tem = Fboundp (car);
-           elt = XCONS (elt)->cdr;
+           elt = XCDR (elt);
            if (!CONSP (elt))
              goto invalid;
            /* elt is now the cdr, and we know it is a cons cell.
@@ -11467,23 +11666,26 @@ display_mode_element (it, depth, field_width, precision, elt)
              {
                tem = Fsymbol_value (car);
                if (!NILP (tem))
-                 { elt = XCONS (elt)->car; goto tail_recurse; }
+                 {
+                   elt = XCAR (elt);
+                   goto tail_recurse;
+                 }
              }
            /* Symbol's value is nil (or symbol is unbound)
               Get the cddr of the original list
               and if possible find the caddr and use that.  */
-           elt = XCONS (elt)->cdr;
+           elt = XCDR (elt);
            if (NILP (elt))
              break;
            else if (!CONSP (elt))
              goto invalid;
-           elt = XCONS (elt)->car;
+           elt = XCAR (elt);
            goto tail_recurse;
          }
        else if (INTEGERP (car))
          {
            register int lim = XINT (car);
-           elt = XCONS (elt)->cdr;
+           elt = XCDR (elt);
            if (lim < 0)
              {
                /* Negative int means reduce maximum width.  */
@@ -11515,8 +11717,8 @@ display_mode_element (it, depth, field_width, precision, elt)
                   && (precision <= 0 || n < precision))
              {
                n += display_mode_element (it, depth, field_width - n,
-                                          precision - n, XCONS (elt)->car);
-               elt = XCONS (elt)->cdr;
+                                          precision - n, XCAR (elt));
+               elt = XCDR (elt);
              }
          }
       }
@@ -12334,28 +12536,28 @@ invisible_p (propval, list)
      Lisp_Object list;
 {
   register Lisp_Object tail, proptail;
-  for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
+  for (tail = list; CONSP (tail); tail = XCDR (tail))
     {
       register Lisp_Object tem;
-      tem = XCONS (tail)->car;
+      tem = XCAR (tail);
       if (EQ (propval, tem))
        return 1;
-      if (CONSP (tem) && EQ (propval, XCONS (tem)->car))
+      if (CONSP (tem) && EQ (propval, XCAR (tem)))
        return 1;
     }
   if (CONSP (propval))
     for (proptail = propval; CONSP (proptail);
-        proptail = XCONS (proptail)->cdr)
+        proptail = XCDR (proptail))
       {
        Lisp_Object propelt;
-       propelt = XCONS (proptail)->car;
-       for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
+       propelt = XCAR (proptail);
+       for (tail = list; CONSP (tail); tail = XCDR (tail))
          {
            register Lisp_Object tem;
-           tem = XCONS (tail)->car;
+           tem = XCAR (tail);
            if (EQ (propelt, tem))
              return 1;
-           if (CONSP (tem) && EQ (propelt, XCONS (tem)->car))
+           if (CONSP (tem) && EQ (propelt, XCAR (tem)))
              return 1;
          }
       }
@@ -12375,27 +12577,29 @@ invisible_ellipsis_p (propval, list)
      Lisp_Object list;
 {
   register Lisp_Object tail, proptail;
-  for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
+  
+  for (tail = list; CONSP (tail); tail = XCDR (tail))
     {
       register Lisp_Object tem;
-      tem = XCONS (tail)->car;
-      if (CONSP (tem) && EQ (propval, XCONS (tem)->car))
-       return ! NILP (XCONS (tem)->cdr);
+      tem = XCAR (tail);
+      if (CONSP (tem) && EQ (propval, XCAR (tem)))
+       return ! NILP (XCDR (tem));
     }
+  
   if (CONSP (propval))
-    for (proptail = propval; CONSP (proptail);
-        proptail = XCONS (proptail)->cdr)
+    for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
       {
        Lisp_Object propelt;
-       propelt = XCONS (proptail)->car;
-       for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
+       propelt = XCAR (proptail);
+       for (tail = list; CONSP (tail); tail = XCDR (tail))
          {
            register Lisp_Object tem;
-           tem = XCONS (tail)->car;
-           if (CONSP (tem) && EQ (propelt, XCONS (tem)->car))
-             return ! NILP (XCONS (tem)->cdr);
+           tem = XCAR (tail);
+           if (CONSP (tem) && EQ (propelt, XCAR (tem)))
+             return ! NILP (XCDR (tem));
          }
       }
+  
   return 0;
 }
 
@@ -12420,7 +12624,7 @@ syms_of_xdisp ()
 #if GLYPH_DEBUG
   defsubr (&Sdump_glyph_matrix);
   defsubr (&Sdump_glyph_row);
-  defsubr (&Sdump_toolbar_row);
+  defsubr (&Sdump_tool_bar_row);
   defsubr (&Strace_redisplay_toggle);
 #endif
 
@@ -12442,9 +12646,8 @@ syms_of_xdisp ()
   staticpro (&Qinhibit_point_motion_hooks);
   Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
 
-  staticpro (&Qdisplay);
   Qdisplay = intern ("display");
-  staticpro (&Qleft_margin);
+  staticpro (&Qdisplay);
   Qspace_width = intern ("space-width");
   staticpro (&Qspace_width);
   Qheight = intern ("height");
@@ -12453,9 +12656,12 @@ syms_of_xdisp ()
   staticpro (&Qraise);
   Qspace = intern ("space");
   staticpro (&Qspace);
+  Qmargin = intern ("margin");
+  staticpro (&Qmargin);
   Qleft_margin = intern ("left-margin");
-  staticpro (&Qright_margin);
+  staticpro (&Qleft_margin);
   Qright_margin = intern ("right-margin");
+  staticpro (&Qright_margin);
   Qalign_to = intern ("align-to");
   staticpro (&Qalign_to);
   QCalign_to = intern (":align-to");
@@ -12470,8 +12676,10 @@ syms_of_xdisp ()
   staticpro (&QCrelative_height);
   QCeval = intern (":eval");
   staticpro (&QCeval);
-  QCwhen = intern (":when");
-  staticpro (&QCwhen);
+  Qwhen = intern ("when");
+  staticpro (&Qwhen);
+  QCfile = intern (":file");
+  staticpro (&QCfile);
   Qfontified = intern ("fontified");
   staticpro (&Qfontified);
   Qfontification_functions = intern ("fontification-functions");
@@ -12481,10 +12689,10 @@ syms_of_xdisp ()
   Qimage = intern ("image");
   staticpro (&Qimage);
 
-  staticpro (&last_arrow_position);
-  staticpro (&last_arrow_string);
   last_arrow_position = Qnil;
   last_arrow_string = Qnil;
+  staticpro (&last_arrow_position);
+  staticpro (&last_arrow_string);
   
   echo_buffer[0] = echo_buffer[1] = Qnil;
   staticpro (&echo_buffer[0]);
@@ -12612,24 +12820,24 @@ and its new display-start position.  Note that the value of `window-end'\n\
 is not valid when these functions are called.");
   Vwindow_scroll_functions = Qnil;
   
-  DEFVAR_BOOL ("auto-resize-toolbars", &auto_resize_toolbars_p,
-    "*Non-nil means automatically resize toolbars.\n\
-This increases a toolbar's height if not all toolbar items are visible.\n\
-It decreases a toolbar's height when it would display blank lines\n\
+  DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
+    "*Non-nil means automatically resize tool-bars.\n\
+This increases a tool-bar's height if not all tool-bar items are visible.\n\
+It decreases a tool-bar's height when it would display blank lines\n\
 otherwise.");
-  auto_resize_toolbars_p = 1;
+  auto_resize_tool_bars_p = 1;
   
-  DEFVAR_BOOL ("auto-raise-toolbar-buttons", &auto_raise_toolbar_buttons_p,
-    "*Non-nil means raise toolbar buttons when the mouse moves over them.");
-  auto_raise_toolbar_buttons_p = 1;
+  DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
+    "*Non-nil means raise tool-bar buttons when the mouse moves over them.");
+  auto_raise_tool_bar_buttons_p = 1;
 
-  DEFVAR_INT ("toolbar-button-margin", &toolbar_button_margin,
-    "*Margin around toolbar buttons in pixels.");
-  toolbar_button_margin = 1;
+  DEFVAR_INT ("tool-bar-button-margin", &tool_bar_button_margin,
+    "*Margin around tool-bar buttons in pixels.");
+  tool_bar_button_margin = 1;
 
-  DEFVAR_INT ("toolbar-button-relief", &toolbar_button_relief,
-    "Relief thickness of toolbar buttons.");
-  toolbar_button_relief = 3;
+  DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
+    "Relief thickness of tool-bar buttons.");
+  tool_bar_button_relief = 3;
 
   DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
     "List of functions to call to fontify regions of text.\n\
@@ -12652,7 +12860,8 @@ displayed according to the current fontset.");
   DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
     "*Maximum height for resizing mini-windows.\n\
 If a float, it specifies a fraction of the mini-window frame's height.\n\
-If an integer, it specifies a number of lines.");
+If an integer, it specifies a number of lines.\n\
+If nil, don't resize.");
   Vmax_mini_window_height = make_float (0.25);
 }