]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
(mark_byte_stack): Use XMARKBIT and XMARK.
[gnu-emacs] / src / xdisp.c
index 348fdb29514c92a9b43e9564cb09e6f1c0b03a2c..484474c2ab64ad52b2b76b1734e2975b0aacb310 100644 (file)
@@ -169,9 +169,6 @@ Boston, MA 02111-1307, USA.  */
 
 #include <config.h>
 #include <stdio.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
 #include "lisp.h"
 #include "frame.h"
 #include "window.h"
@@ -219,7 +216,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 +224,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 +255,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.  */
 
@@ -584,6 +582,9 @@ 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 void clear_garbaged_frames P_ ((void));
@@ -602,7 +603,7 @@ static Lisp_Object eval_form P_ ((Lisp_Object));
 static void insert_left_trunc_glyphs P_ ((struct it *));
 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
 static void extend_face_to_end_of_line P_ ((struct it *));
-static void append_space P_ ((struct it *, int));
+static int append_space P_ ((struct it *, int));
 static void make_cursor_line_fully_visible P_ ((struct window *));
 static int try_scrolling P_ ((Lisp_Object, int, int, int, int));
 static int trailing_whitespace_p P_ ((int));
@@ -624,7 +625,7 @@ static void display_mode_lines P_ ((struct window *));
 static void display_mode_line P_ ((struct window *, enum face_id,
                                   Lisp_Object));
 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object));
-static char *decode_mode_spec P_ ((struct window *, char, int, int));
+static char *decode_mode_spec P_ ((struct window *, int, int, int));
 static void display_menu_bar P_ ((struct window *));
 static int display_count_lines P_ ((int, int, int, int, int *));
 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
@@ -678,10 +679,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 */
 
@@ -755,8 +756,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;
 }
@@ -825,8 +826,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);
 }
 
 
@@ -1156,11 +1157,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
@@ -1192,8 +1193,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.  */
@@ -1346,8 +1347,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.  */
@@ -1404,7 +1405,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;
@@ -1780,6 +1781,7 @@ handle_fontified_prop (it)
 {
   Lisp_Object prop, pos;
   enum prop_handled handled = HANDLED_NORMALLY;
+  struct gcpro gcpro1;
 
   /* Get the value of the `fontified' property at IT's current buffer
      position.  (The `fontified' property doesn't have a special
@@ -1794,6 +1796,7 @@ handle_fontified_prop (it)
     {
       Lisp_Object args[2];
 
+      GCPRO1 (pos);
       /* Run the hook functions.  */
       args[0] = Qfontification_functions;
       args[1] = pos;
@@ -1804,6 +1807,7 @@ handle_fontified_prop (it)
         fontify the text for which reason ever.  */
       if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
        handled = HANDLED_RECOMPUTE_PROPS;
+      UNGCPRO;
     }
 
   return handled;
@@ -2209,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))
@@ -2236,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
@@ -2247,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;
 }
@@ -2294,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))
@@ -2431,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;
@@ -2447,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;
@@ -2973,7 +2976,6 @@ back_to_previous_visible_line_start (it)
          && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
                                it->selective))
        visible_p = 0;
-#ifdef USE_TEXT_PROPERTIES
       else 
        {
          Lisp_Object prop;
@@ -2982,7 +2984,6 @@ back_to_previous_visible_line_start (it)
          if (TEXT_PROP_MEANS_INVISIBLE (prop))
            visible_p = 0;
        }
-#endif /* USE_TEXT_PROPERTIES  */
 
       /* Back one more newline if the current one is invisible.  */
       if (!visible_p)
@@ -3974,7 +3975,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;
@@ -4401,7 +4402,6 @@ invisible_text_between_p (it, start_charpos, end_charpos)
      struct it *it;
      int start_charpos, end_charpos;
 {
-#ifdef USE_TEXT_PROPERTIES
   Lisp_Object prop, limit;
   int invisible_found_p;
   
@@ -4414,18 +4414,13 @@ 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;
     }
 
   return invisible_found_p;
-  
-#else /* not USE_TEXT_PROPERTIES */
-  return 0;
-#endif /* not USE_TEXT_PROPERTIES */
 }
 
 
@@ -4569,6 +4564,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
@@ -4808,6 +4834,7 @@ message2_nolog (m, len, multibyte)
      char *m;
      int len;
 {
+  struct frame *sf = SELECTED_FRAME ();
   message_enable_multibyte = multibyte;
 
   if (noninteractive)
@@ -4825,19 +4852,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)));
 
@@ -4891,6 +4918,7 @@ message3_nolog (m, nbytes, multibyte)
      Lisp_Object m;
      int nbytes, multibyte;
 {
+  struct frame *sf = SELECTED_FRAME ();
   message_enable_multibyte = multibyte;
 
   if (noninteractive)
@@ -4908,8 +4936,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;
@@ -4917,12 +4945,12 @@ 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);
 
@@ -4997,11 +5025,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
@@ -5059,11 +5087,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
@@ -5187,7 +5215,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
@@ -5345,8 +5372,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)));
        }
 
@@ -5397,13 +5425,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);
@@ -5415,12 +5442,40 @@ 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.  */
+
+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)
+resize_mini_window (w, exact_p)
      struct window *w;
+     int exact_p;
 {
   struct frame *f = XFRAME (w->frame);
   int window_height_changed_p = 0;
@@ -5428,7 +5483,8 @@ resize_mini_window (w)
   xassert (MINI_WINDOW_P (w));
 
   /* Nil means don't try to resize.  */
-  if (NILP (Vmax_mini_window_height))
+  if (NILP (Vmax_mini_window_height)
+      || (FRAME_X_P (f) && f->output_data.x == NULL))
     return 0;
   
   if (!FRAME_MINIBUF_ONLY_P (f))
@@ -5455,9 +5511,13 @@ resize_mini_window (w)
       max_height = min (total_height, max_height);
       
       /* Find out the height of the text in the window.  */
+      last_height = 0;
       move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
-      height = (unit - 1 + it.current_y + last_height) / unit;
-      height = max (1, height);
+      if (it.max_ascent == 0 && it.max_descent == 0)
+       height = it.current_y + last_height;
+      else
+       height = it.current_y + it.max_ascent + it.max_descent;
+      height = (height + unit - 1) / unit;
       
       /* Compute a suitable window start.  */
       if (height > max_height)
@@ -5473,17 +5533,20 @@ resize_mini_window (w)
 
       /* Let it grow only, until we display an empty message, in which
         case the window shrinks again.  */
-      if (height > XFASTINT (w->height)
-         || BEGV == ZV)
+      if (height > XFASTINT (w->height))
        {
-         Lisp_Object old_selected_window;
-             
-         freeze_window_starts (f, height > XFASTINT (w->height));
-         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;
        }
     }
 
@@ -5591,9 +5654,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);
+    }
 }
 
 
@@ -5766,8 +5832,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
@@ -5778,8 +5844,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));
 
@@ -5787,13 +5854,14 @@ echo_area_display (update_frame_p)
   if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
     return 0;
 
+#ifdef HAVE_X_WINDOWS
   /* 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 (EQ (selected_frame, Vterminal_frame) 
+      && !NILP (Vwindow_system))
     return 0;
-#endif /* HAVE_WINDOW_SYSTEM */
+#endif /* HAVE_X_WINDOWS */
 
   /* Redraw garbaged frames.  */
   if (frame_garbaged)
@@ -6070,7 +6138,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;
        }
@@ -6079,9 +6147,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
     }
 
@@ -6184,23 +6253,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;
@@ -6243,12 +6312,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);
@@ -6258,12 +6327,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;
@@ -6273,60 +6342,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];
@@ -6336,14 +6405,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.  */
@@ -6376,14 +6445,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
     }
 
@@ -6391,10 +6460,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;
@@ -6452,7 +6521,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;
@@ -6471,39 +6540,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;
@@ -6511,65 +6580,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;
@@ -6580,13 +6649,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;
@@ -6596,9 +6665,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);
@@ -6645,8 +6714,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);
@@ -6656,7 +6731,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;
@@ -6898,6 +6974,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.  */
@@ -6951,17 +7028,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
@@ -6990,7 +7067,7 @@ 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 ();
 
   if (windows_or_buffers_changed)
@@ -7056,7 +7133,7 @@ redisplay_internal (preserve_echo_area)
           && (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.  */
@@ -7315,7 +7392,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.  */
@@ -7332,8 +7409,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);
 
   
@@ -7355,19 +7432,37 @@ update:
   if (consider_all_windows_p)
     {
       Lisp_Object tail;
+      struct frame *f;
+      int hscrolled_p;
 
       pause = 0;
+      hscrolled_p = 0;
 
+      /* See if we have to hscroll.  */
       for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
-       {
-         struct frame *f;
+       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 (hscrolled_p)
+       goto retry;
+
+      for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
+       {
          if (!FRAMEP (XCAR (tail)))
            continue;
 
          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.  */
@@ -7375,9 +7470,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);
@@ -7387,13 +7479,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;
@@ -7407,10 +7500,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);
@@ -7455,7 +7548,7 @@ update:
       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));
@@ -7484,7 +7577,7 @@ 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);
@@ -7808,7 +7901,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)
@@ -7817,12 +7912,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;
@@ -7838,7 +7939,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.  */
@@ -7851,8 +7952,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))
@@ -7997,7 +8098,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;
        }
@@ -8050,7 +8151,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;
            }
@@ -8118,10 +8219,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);
@@ -8206,7 +8313,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.  */
@@ -8842,13 +8949,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
@@ -8865,7 +8972,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);
 
@@ -8881,12 +8988,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)
@@ -8923,10 +9030,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
     }
 
@@ -9086,8 +9193,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
@@ -9194,7 +9301,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)
            {
@@ -9337,7 +9444,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)
        {
@@ -9353,7 +9460,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)
        {
@@ -9606,13 +9713,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.
@@ -9879,44 +10038,23 @@ 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;
-           }
-
-         /* If PT is at ZV, this is not in a line displaying text.
-            Check that case.  */
-         if (w->cursor.vpos < 0
-             && PT - delta == MATRIX_ROW_START_CHARPOS (row)
-             && row->ends_at_zv_p)
+         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);
        }
@@ -10151,13 +10289,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);
@@ -10348,11 +10486,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;
@@ -10509,7 +10648,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
@@ -10548,9 +10687,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);
@@ -10581,7 +10720,7 @@ compute_line_metrics (it)
 /* Append one space to the glyph row of iterator IT if doing a
    window-based redisplay.  DEFAULT_FACE_P non-zero means let the
    space have the default face, otherwise let it have the same face as
-   IT->face_id.
+   IT->face_id.  Value is non-zero if a space was added.
 
    This function is called to make sure that there is always one glyph
    at the end of a glyph row that the cursor can be set on under
@@ -10591,7 +10730,7 @@ compute_line_metrics (it)
    At the same time this space let's a nicely handle clearing to the
    end of the line if the row ends in italic text.  */
 
-static void
+static int
 append_space (it, default_face_p)
      struct it *it;
      int default_face_p;
@@ -10636,8 +10775,11 @@ append_space (it, default_face_p)
          it->what = saved_what;
          it->face_id = saved_face_id;
          it->charset = saved_charset;
+         return 1;
        }
     }
+
+  return 0;
 }
 
 
@@ -10863,13 +11005,11 @@ display_line (it)
       if (!get_next_display_element (it))
        {
          /* Maybe add a space at the end of this line that is used to
-            display the cursor there under X.  */
-         append_space (it, 1);
-
-         /* The position -1 below indicates a blank line not
-            corresponding to any text, as opposed to an empty line
-            corresponding to a line end.  */
-         if (row->used[TEXT_AREA] <= 1)
+            display the cursor there under X.  Set the charpos of the
+            first glyph of blank lines not corresponding to any text
+            to -1.  */
+         if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
+             || row->used[TEXT_AREA] == 0)
            {
              row->glyphs[TEXT_AREA]->charpos = -1;
              row->displays_text_p = 0;
@@ -11183,7 +11323,7 @@ display_menu_bar (w)
 
 #ifdef USE_X_TOOLKIT
   xassert (!FRAME_WINDOW_P (f));
-  init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MODE_LINE_FACE_ID);
+  init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
   it.first_visible_x = 0;
   it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
 #else /* not USE_X_TOOLKIT */
@@ -11195,7 +11335,7 @@ display_menu_bar (w)
       xassert (WINDOWP (f->menu_bar_window));
       menu_w = XWINDOW (f->menu_bar_window);
       init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
-                    MODE_LINE_FACE_ID);
+                    MENU_FACE_ID);
       it.first_visible_x = 0;
       it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
     }
@@ -11204,7 +11344,7 @@ display_menu_bar (w)
       /* This is a TTY frame, i.e. character hpos/vpos are used as
         pixel x/y.  */
       init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
-                    MODE_LINE_FACE_ID);
+                    MENU_FACE_ID);
       it.first_visible_x = 0;
       it.last_visible_x = FRAME_WIDTH (f);
     }
@@ -11267,15 +11407,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
@@ -11732,7 +11874,7 @@ static char lots_of_dashes[] = "------------------------------------------------
 static char *
 decode_mode_spec (w, c, field_width, precision)
      struct window *w;
-     register char c;
+     register int c;
      int field_width, precision;
 {
   Lisp_Object obj;
@@ -12228,6 +12370,8 @@ display_string (string, lisp_string, face_string, face_string_pos,
                start, it, field_width, precision, max_x, multibyte)
      unsigned char *string;
      Lisp_Object lisp_string;
+     Lisp_Object face_string;
+     int face_string_pos;
      int start;
      struct it *it;
      int field_width, precision, max_x;
@@ -12477,7 +12621,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
 
@@ -12499,9 +12643,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");
@@ -12510,9 +12653,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");
@@ -12527,8 +12673,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");
@@ -12538,10 +12686,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]);
@@ -12669,24 +12817,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\