]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
(mark_byte_stack): Use XMARKBIT and XMARK.
[gnu-emacs] / src / xdisp.c
index ab3547dc338ce8a202ef59394d5b6f2e075a7c1c..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, Qwhen;
+Lisp_Object QCeval, Qwhen, QCfile;
 Lisp_Object Qfontified;
 
 /* Functions called to fontify regions of text.  */
@@ -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.  */
 
@@ -605,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));
@@ -627,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,
@@ -1783,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
@@ -1797,6 +1796,7 @@ handle_fontified_prop (it)
     {
       Lisp_Object args[2];
 
+      GCPRO1 (pos);
       /* Run the hook functions.  */
       args[0] = Qfontification_functions;
       args[1] = pos;
@@ -1807,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;
@@ -2212,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))
@@ -2239,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
@@ -2250,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;
 }
@@ -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
@@ -5344,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)));
        }
 
@@ -5396,7 +5425,6 @@ 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;
 
@@ -5455,7 +5483,8 @@ resize_mini_window (w, exact_p)
   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))
@@ -5482,9 +5511,13 @@ resize_mini_window (w, exact_p)
       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)
@@ -5500,18 +5533,20 @@ resize_mini_window (w, exact_p)
 
       /* Let it grow only, until we display an empty message, in which
         case the window shrinks again.  */
-      if (height > XFASTINT (w->height)
-         || exact_p
-         || 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;
        }
     }
 
@@ -5619,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);
+    }
 }
 
 
@@ -5794,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
@@ -5806,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));
 
@@ -5815,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)
@@ -6107,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_tool_bar (selected_frame, 1);
+      update_tool_bar (sf, 1);
 #endif
     }
 
@@ -6933,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.  */
@@ -6986,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
@@ -7350,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.  */
@@ -7367,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);
 
   
@@ -7403,7 +7445,7 @@ update:
            f = XFRAME (XCAR (tail));
            
            if ((FRAME_WINDOW_P (f)
-                || f == selected_frame)
+                || f == sf)
                && FRAME_VISIBLE_P (f)
                && !FRAME_OBSCURED_P (f)
                && hscroll_windows (f->root_window))
@@ -7420,7 +7462,7 @@ update:
 
          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.  */
@@ -7437,14 +7479,14 @@ update:
     }
   else
     {
-      if (FRAME_VISIBLE_P (selected_frame)
-         && !FRAME_OBSCURED_P (selected_frame))
+      if (FRAME_VISIBLE_P (sf)
+         && !FRAME_OBSCURED_P (sf))
        {
          if (hscroll_windows (selected_window))
            goto retry;
          
          XWINDOW (selected_window)->must_be_updated_p = 1;
-         pause = update_frame (selected_frame, 0, 0);
+         pause = update_frame (sf, 0, 0);
        }
       else
        pause = 0;
@@ -7458,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);
@@ -7506,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));
@@ -7535,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);
@@ -8177,6 +8219,12 @@ 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).  */
@@ -8901,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
@@ -9665,8 +9713,15 @@ 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;
     }
 }
@@ -9983,8 +10038,6 @@ 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)
@@ -10437,7 +10490,8 @@ DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row,
        0, 0, "", "")
   ()
 {
-  struct glyph_matrix *m = (XWINDOW (selected_frame->tool_bar_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;
@@ -10666,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
@@ -10676,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;
@@ -10721,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;
 }
 
 
@@ -10948,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;
@@ -11268,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 */
@@ -11280,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);
     }
@@ -11289,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);
     }
@@ -11819,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;
@@ -12315,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;
@@ -12586,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");
@@ -12597,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");
@@ -12616,6 +12675,8 @@ syms_of_xdisp ()
   staticpro (&QCeval);
   Qwhen = intern ("when");
   staticpro (&Qwhen);
+  QCfile = intern (":file");
+  staticpro (&QCfile);
   Qfontified = intern ("fontified");
   staticpro (&Qfontified);
   Qfontification_functions = intern ("fontification-functions");
@@ -12625,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]);