]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
Syntactic cleanup.
[gnu-emacs] / src / xdisp.c
index 640f7006dd14dfe2fa27325a2f15b503410da156..d22c9a53bc3cc01f8d6e51cc0832856f9b5c0398 100644 (file)
@@ -1,13 +1,13 @@
 /* Display generation from window structure and buffer text.
    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
                  1997, 1998, 1999, 2000, 2001, 2002, 2003,
-                 2004, 2005, 2006 Free Software Foundation, Inc.
+                 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -256,9 +256,9 @@ Lisp_Object list_of_error;
 Lisp_Object Vfontification_functions;
 Lisp_Object Qfontification_functions;
 
-/* Non-zero means automatically select any window when the mouse
+/* Non-nil means automatically select any window when the mouse
    cursor moves into it.  */
-int mouse_autoselect_window;
+Lisp_Object Vmouse_autoselect_window;
 
 /* Non-zero means draw tool bar buttons raised when the mouse moves
    over them.  */
@@ -283,10 +283,12 @@ Lisp_Object Vtool_bar_button_margin;
 
 EMACS_INT tool_bar_button_relief;
 
-/* Non-zero means automatically resize tool-bars so that all tool-bar
-   items are visible, and no blank lines remain.  */
+/* Non-nil means automatically resize tool-bars so that all tool-bar
+   items are visible, and no blank lines remain.
 
-int auto_resize_tool_bars_p;
+   If value is `grow-only', only make tool-bar bigger.  */
+
+Lisp_Object Vauto_resize_tool_bars;
 
 /* Non-zero means draw block and hollow cursor as wide as the glyph
    under it.  For example, if a block cursor is over a tab, it will be
@@ -615,6 +617,11 @@ int message_buf_print;
 Lisp_Object Qinhibit_menubar_update;
 int inhibit_menubar_update;
 
+/* When evaluating expressions from menu bar items (enable conditions,
+   for instance), this is the frame they are being processed for.  */
+
+Lisp_Object Vmenu_updating_frame;
+
 /* Maximum height for resizing mini-windows.  Either a float
    specifying a fraction of the available height, or an integer
    specifying a number of lines.  */
@@ -710,6 +717,10 @@ Lisp_Object Vresize_mini_windows;
 
 struct buffer *displayed_buffer;
 
+/* Space between overline and text. */
+
+EMACS_INT overline_margin;
+
 /* Value returned from text property handlers (see below).  */
 
 enum prop_handled
@@ -1266,15 +1277,15 @@ line_bottom_y (it)
 
 
 /* Return 1 if position CHARPOS is visible in window W.
+   CHARPOS < 0 means return info about WINDOW_END position.
    If visible, set *X and *Y to pixel coordinates of top left corner.
    Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
-   EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
-   and header-lines heights.  */
+   Set *ROWH and *VPOS to row's visible height and VPOS (row number).  */
 
 int
-pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
+pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
      struct window *w;
-     int charpos, *x, *y, *rtop, *rbot, exact_mode_line_heights_p;
+     int charpos, *x, *y, *rtop, *rbot, *rowh, *vpos;
 {
   struct it it;
   struct text_pos top;
@@ -1292,26 +1303,23 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
 
   SET_TEXT_POS_FROM_MARKER (top, w->start);
 
-  /* Compute exact mode line heights, if requested.  */
-  if (exact_mode_line_heights_p)
-    {
-      if (WINDOW_WANTS_MODELINE_P (w))
-       current_mode_line_height
-         = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
-                              current_buffer->mode_line_format);
+  /* Compute exact mode line heights.  */
+  if (WINDOW_WANTS_MODELINE_P (w))
+    current_mode_line_height
+      = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
+                          current_buffer->mode_line_format);
 
-      if (WINDOW_WANTS_HEADER_LINE_P (w))
-       current_header_line_height
-         = display_mode_line (w, HEADER_LINE_FACE_ID,
+  if (WINDOW_WANTS_HEADER_LINE_P (w))
+    current_header_line_height
+      = display_mode_line (w, HEADER_LINE_FACE_ID,
                               current_buffer->header_line_format);
-    }
 
   start_display (&it, w, top);
-  move_it_to (&it, charpos, -1, it.last_visible_y, -1,
-             MOVE_TO_POS | MOVE_TO_Y);
+  move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
+             (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
 
   /* Note that we may overshoot because of invisible text.  */
-  if (IT_CHARPOS (it) >= charpos)
+  if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
     {
       int top_x = it.current_x;
       int top_y = it.current_y;
@@ -1328,6 +1336,9 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
          *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
          *rtop = max (0, window_top_y - top_y);
          *rbot = max (0, bottom_y - it.last_visible_y);
+         *rowh = max (0, (min (bottom_y, it.last_visible_y)
+                          - max (top_y, window_top_y)));
+         *vpos = it.vpos;
        }
     }
   else
@@ -1337,7 +1348,8 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
       it2 = it;
       if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
        move_it_by_lines (&it, 1, 0);
-      if (charpos < IT_CHARPOS (it))
+      if (charpos < IT_CHARPOS (it)
+         || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
        {
          visible_p = 1;
          move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
@@ -1346,6 +1358,11 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
          *rtop = max (0, -it2.current_y);
          *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
                           - it.last_visible_y));
+         *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
+                               it.last_visible_y)
+                          - max (it2.current_y,
+                                 WINDOW_HEADER_LINE_HEIGHT (w))));
+         *vpos = it2.vpos;
        }
     }
 
@@ -1357,6 +1374,15 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
   if (visible_p && XFASTINT (w->hscroll) > 0)
     *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
 
+#if 0
+  /* Debugging code.  */
+  if (visible_p)
+    fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
+            charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
+  else
+    fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
+#endif
+
   return visible_p;
 }
 
@@ -2067,8 +2093,9 @@ remember_mouse_glyph (f, gx, gy, rect)
   /* Try to determine frame pixel position and size of the glyph under
      frame pixel coordinates X/Y on frame F.  */
 
-  window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0);
-  if (NILP (window))
+  if (!f->glyphs_initialized_p
+      || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0),
+         NILP (window)))
     {
       width = FRAME_SMALLEST_CHAR_WIDTH (f);
       height = FRAME_SMALLEST_FONT_HEIGHT (f);
@@ -3223,7 +3250,9 @@ handle_fontified_prop (it)
       && !NILP (Vrun_hooks)
       && (pos = make_number (IT_CHARPOS (*it)),
          prop = Fget_char_property (pos, Qfontified, Qnil),
-         NILP (prop)))
+         /* Ignore the special cased nil value always present at EOB since
+            no amount of fontifying will be able to change it.  */
+         NILP (prop) && IT_CHARPOS (*it) < Z))
     {
       int count = SPECPDL_INDEX ();
       Lisp_Object val;
@@ -6240,7 +6269,7 @@ next_element_from_buffer (it)
        it->c = *p, it->len = 1;
 
       /* Record what we have and where it came from.  */
-      it->what = IT_CHARACTER;;
+      it->what = IT_CHARACTER;
       it->object = it->w->buffer;
       it->position = it->current.pos;
 
@@ -6801,7 +6830,12 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
          break;
 
        case MOVE_LINE_CONTINUED:
-         it->continuation_lines_width += it->current_x;
+         /* For continued lines ending in a tab, some of the glyphs
+            associated with the tab are displayed on the current
+            line.  Since it->current_x does not include these glyphs,
+            we use it->last_visible_x instead.  */
+         it->continuation_lines_width +=
+           (it->c == '\t') ? it->last_visible_x : it->current_x;
          break;
 
        default:
@@ -7053,18 +7087,22 @@ move_it_by_lines (it, dvpos, need_y_p)
 {
   struct position pos;
 
-  if (!FRAME_WINDOW_P (it->f))
+  /* The commented-out optimization uses vmotion on terminals.  This
+     gives bad results, because elements like it->what, on which
+     callers such as pos_visible_p rely, aren't updated. */
+  /*  if (!FRAME_WINDOW_P (it->f))
     {
       struct text_pos textpos;
 
-      /* We can use vmotion on frames without proportional fonts.  */
       pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
       SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
       reseat (it, textpos, 1);
       it->vpos += pos.vpos;
       it->current_y += pos.vpos;
     }
-  else if (dvpos == 0)
+    else */
+
+  if (dvpos == 0)
     {
       /* DVPOS == 0 means move to the start of the screen line.  */
       move_it_vertically_backward (it, 0);
@@ -9126,7 +9164,7 @@ update_menu_bar (f, save_match_data, hooks_run)
      happen when, for instance, an activate-menubar-hook causes a
      redisplay.  */
   if (inhibit_menubar_update)
-    return;
+    return hooks_run;
 
   window = FRAME_SELECTED_WINDOW (f);
   w = XWINDOW (window);
@@ -9197,6 +9235,7 @@ update_menu_bar (f, save_match_data, hooks_run)
              hooks_run = 1;
            }
 
+         XSETFRAME (Vmenu_updating_frame, f);
          FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
 
          /* Redisplay the menu bar in case we changed it.  */
@@ -9330,7 +9369,7 @@ update_tool_bar (f, save_match_data)
      struct frame *f;
      int save_match_data;
 {
-#ifdef USE_GTK
+#if defined (USE_GTK) || USE_MAC_TOOLBAR
   int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
 #else
   int do_update = WINDOWP (f->tool_bar_window)
@@ -9661,9 +9700,16 @@ display_tool_bar_line (it, height)
  out:;
 
   row->displays_text_p = row->used[TEXT_AREA] != 0;
-  /* Use default face for the border below the tool bar.  */
-  if (!row->displays_text_p)
+
+  /* Use default face for the border below the tool bar.
+
+     FIXME: When auto-resize-tool-bars is grow-only, there is
+     no additional border below the possibly empty tool-bar lines.
+     So to make the extra empty lines look "normal", we have to
+     use the tool-bar face for the border too.  */
+  if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
     it->face_id = DEFAULT_FACE_ID;
+
   extend_face_to_end_of_line (it);
   last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
   last->right_box_line_p = 1;
@@ -9685,6 +9731,7 @@ display_tool_bar_line (it, height)
   if (!row->displays_text_p)
     {
       row->height = row->phys_height = it->last_visible_y - row->y;
+      row->visible_height = row->height;
       row->ascent = row->phys_ascent = 0;
       row->extra_line_spacing = 0;
     }
@@ -9787,9 +9834,8 @@ redisplay_tool_bar (f)
   struct window *w;
   struct it it;
   struct glyph_row *row;
-  int change_height_p = 0;
 
-#ifdef USE_GTK
+#if defined (USE_GTK) || USE_MAC_TOOLBAR
   if (FRAME_EXTERNAL_TOOL_BAR (f))
     update_frame_tool_bar (f);
   return 0;
@@ -9882,10 +9928,10 @@ redisplay_tool_bar (f)
   w->desired_matrix->no_scrolling_p = 1;
   w->must_be_updated_p = 1;
 
-  if (auto_resize_tool_bars_p)
+  if (!NILP (Vauto_resize_tool_bars))
     {
-      int nlines, nrows;
       int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
+      int change_height_p = 0;
 
       /* If we couldn't display everything, change the tool-bar's
         height if there is room for more.  */
@@ -9911,29 +9957,40 @@ redisplay_tool_bar (f)
 
       /* Resize windows as needed by changing the `tool-bar-lines'
         frame parameter.  */
-      if (change_height_p
-         && (nlines = tool_bar_lines_needed (f, &nrows),
-             nlines != WINDOW_TOTAL_LINES (w)))
+      if (change_height_p)
        {
          extern Lisp_Object Qtool_bar_lines;
          Lisp_Object frame;
          int old_height = WINDOW_TOTAL_LINES (w);
+         int nrows;
+         int nlines = tool_bar_lines_needed (f, &nrows);
 
-         XSETFRAME (frame, f);
-         Fmodify_frame_parameters (frame,
-                                   Fcons (Fcons (Qtool_bar_lines,
-                                                 make_number (nlines)),
-                                          Qnil));
-         if (WINDOW_TOTAL_LINES (w) != old_height)
+         change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
+                             && !f->minimize_tool_bar_window_p)
+                            ? (nlines > old_height)
+                            : (nlines != old_height));
+         f->minimize_tool_bar_window_p = 0;
+
+         if (change_height_p)
            {
-             clear_glyph_matrix (w->desired_matrix);
-             f->n_tool_bar_rows = nrows;
-             fonts_changed_p = 1;
+             XSETFRAME (frame, f);
+             Fmodify_frame_parameters (frame,
+                                       Fcons (Fcons (Qtool_bar_lines,
+                                                     make_number (nlines)),
+                                              Qnil));
+             if (WINDOW_TOTAL_LINES (w) != old_height)
+               {
+                 clear_glyph_matrix (w->desired_matrix);
+                 f->n_tool_bar_rows = nrows;
+                 fonts_changed_p = 1;
+                 return 1;
+               }
            }
        }
     }
 
-  return change_height_p;
+  f->minimize_tool_bar_window_p = 0;
+  return 0;
 }
 
 
@@ -10778,13 +10835,13 @@ redisplay_internal (preserve_echo_area)
      int preserve_echo_area;
 {
   struct window *w = XWINDOW (selected_window);
-  struct frame *f = XFRAME (w->frame);
+  struct frame *f;
   int pause;
   int must_finish = 0;
   struct text_pos tlbufpos, tlendpos;
   int number_of_visible_frames;
-  int count;
-  struct frame *sf = SELECTED_FRAME ();
+  int count, count1;
+  struct frame *sf;
   int polling_stopped_here = 0;
 
   /* Non-zero means redisplay has to consider all windows on all
@@ -10797,8 +10854,16 @@ redisplay_internal (preserve_echo_area)
      initialized, or redisplay is explicitly turned off by setting
      Vinhibit_redisplay.  */
   if (noninteractive
-      || !NILP (Vinhibit_redisplay)
-      || !f->glyphs_initialized_p)
+      || !NILP (Vinhibit_redisplay))
+    return;
+
+  /* Don't examine these until after testing Vinhibit_redisplay.
+     When Emacs is shutting down, perhaps because its connection to
+     X has dropped, we should not look at them at all.  */
+  f = XFRAME (w->frame);
+  sf = SELECTED_FRAME ();
+
+  if (!f->glyphs_initialized_p)
     return;
 
   /* The flag redisplay_performed_directly_p is set by
@@ -10811,7 +10876,7 @@ redisplay_internal (preserve_echo_area)
        return;
     }
 
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
   if (popup_activated ())
     return;
 #endif
@@ -10913,6 +10978,10 @@ redisplay_internal (preserve_echo_area)
        update_mode_lines++;
     }
 
+  /* Avoid invocation of point motion hooks by `current_column' below.  */
+  count1 = SPECPDL_INDEX ();
+  specbind (Qinhibit_point_motion_hooks, Qt);
+
   /* If %c is in the mode line, update it if needed.  */
   if (!NILP (w->column_number_displayed)
       /* This alternative quickly identifies a common case
@@ -10924,6 +10993,8 @@ redisplay_internal (preserve_echo_area)
           != (int) current_column ()))  /* iftc */
     w->update_mode_line = Qt;
 
+  unbind_to (count1, Qnil);
+
   FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
 
   /* The variable buffer_shared is set in redisplay_window and
@@ -12019,7 +12090,8 @@ cursor_row_fully_visible_p (w, force_p, current_matrix_p)
   window_height = window_box_height (w);
   if (row->height >= window_height)
     {
-      if (!force_p || MINI_WINDOW_P (w) || w->vscroll)
+      if (!force_p || MINI_WINDOW_P (w)
+         || w->vscroll || w->cursor.vpos == 0)
        return 1;
     }
   return 0;
@@ -12715,6 +12787,7 @@ redisplay_window (window, just_this_one_p)
   int rc;
   int centering_position = -1;
   int last_line_misfit = 0;
+  int beg_unchanged, end_unchanged;
 
   SET_TEXT_POS (lpoint, PT, PT_BYTE);
   opoint = lpoint;
@@ -12779,6 +12852,9 @@ redisplay_window (window, just_this_one_p)
   set_buffer_internal_1 (XBUFFER (w->buffer));
   SET_TEXT_POS (opoint, PT, PT_BYTE);
 
+  beg_unchanged = BEG_UNCHANGED;
+  end_unchanged = END_UNCHANGED;
+
   current_matrix_up_to_date_p
     = (!NILP (w->window_end_valid)
        && !current_buffer->clip_changed
@@ -12902,6 +12978,8 @@ redisplay_window (window, just_this_one_p)
        w->force_start = Qt;
     }
 
+ force_start:
+
   /* Handle case where place to start displaying has been specified,
      unless the specified location is outside the accessible range.  */
   if (!NILP (w->force_start)
@@ -13072,32 +13150,25 @@ redisplay_window (window, just_this_one_p)
 
       /* If first window line is a continuation line, and window start
         is inside the modified region, but the first change is before
-        current window start, we must select a new window start.*/
-      if (NILP (w->start_at_line_beg)
-         && CHARPOS (startp) > BEGV)
-       {
-         /* Make sure beg_unchanged and end_unchanged are up to date.
-            Do it only if buffer has really changed.  This may or may
-            not have been done by try_window_id (see which) already. */
-         if (MODIFF > SAVE_MODIFF
-             /* This seems to happen sometimes after saving a buffer.  */
-             || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
-           {
-             if (GPT - BEG < BEG_UNCHANGED)
-               BEG_UNCHANGED = GPT - BEG;
-             if (Z - GPT < END_UNCHANGED)
-               END_UNCHANGED = Z - GPT;
-           }
+        current window start, we must select a new window start.
 
-         if (CHARPOS (startp) > BEG + BEG_UNCHANGED
-             && CHARPOS (startp) <= Z - END_UNCHANGED)
-           {
-             /* There doesn't seems to be a simple way to find a new
-                window start that is near the old window start, so
-                we just recenter.  */
-             goto recenter;
-           }
-       }
+        However, if this is the result of a down-mouse event (e.g. by
+        extending the mouse-drag-overlay), we don't want to select a
+        new window start, since that would change the position under
+        the mouse, resulting in an unwanted mouse-movement rather
+        than a simple mouse-click.  */
+      if (NILP (w->start_at_line_beg)
+         && NILP (do_mouse_tracking)
+         && CHARPOS (startp) > BEGV
+         && CHARPOS (startp) > BEG + beg_unchanged
+         && CHARPOS (startp) <= Z - end_unchanged)
+       {
+         w->force_start = Qt;
+         if (XMARKER (w->start)->buffer == current_buffer)
+           compute_window_start_on_continuation_line (w);
+         SET_TEXT_POS_FROM_MARKER (startp, w->start);
+         goto force_start;
+       }
 
 #if GLYPH_DEBUG
       debug_method_add (w, "same window start");
@@ -13400,17 +13471,20 @@ redisplay_window (window, just_this_one_p)
         display_menu_bar (w);
 
 #ifdef HAVE_WINDOW_SYSTEM
-#ifdef USE_GTK
+#if defined (USE_GTK) || USE_MAC_TOOLBAR
       redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
 #else
       redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
         && (FRAME_TOOL_BAR_LINES (f) > 0
-            || auto_resize_tool_bars_p);
+            || !NILP (Vauto_resize_tool_bars));
 
 #endif
 
-      if (redisplay_tool_bar_p)
-        redisplay_tool_bar (f);
+      if (redisplay_tool_bar_p && redisplay_tool_bar (f))
+       {
+         extern int ignore_mouse_drag_p;
+         ignore_mouse_drag_p = 1;
+       }
 #endif
     }
 
@@ -13450,7 +13524,10 @@ redisplay_window (window, just_this_one_p)
   /* Restore current_buffer and value of point in it.  */
   TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
   set_buffer_internal_1 (old);
-  TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
+  /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
+     shorter.  This can be caused by log truncation in *Messages*. */
+  if (CHARPOS (lpoint) <= ZV)
+    TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
 
   unbind_to (count, Qnil);
 }
@@ -13473,6 +13550,7 @@ try_window (window, pos, check_margins)
   struct window *w = XWINDOW (window);
   struct it it;
   struct glyph_row *last_text_row = NULL;
+  struct frame *f = XFRAME (w->frame);
 
   /* Make POS the new window start.  */
   set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
@@ -13503,7 +13581,8 @@ try_window (window, pos, check_margins)
       this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
       this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
 
-      if ((w->cursor.y < this_scroll_margin
+      if ((w->cursor.y >= 0    /* not vscrolled */
+          && w->cursor.y < this_scroll_margin
           && CHARPOS (pos) > BEGV
           && IT_CHARPOS (it) < ZV)
          /* rms: considering make_cursor_line_fully_visible_p here
@@ -13723,7 +13802,7 @@ try_window_reusing_current_matrix (w)
                         nrows_scrolled);
 
          /* Disable lines that must be updated.  */
-         for (i = 0; i < it.vpos; ++i)
+         for (i = 0; i < nrows_scrolled; ++i)
            (start_row + i)->enabled_p = 0;
 
          /* Re-compute Y positions.  */
@@ -14824,7 +14903,7 @@ try_window_id (w)
     sync_frame_with_window_matrix_rows (w);
 
   /* Adjust buffer positions in reused rows.  */
-  if (delta)
+  if (delta || delta_bytes)
     increment_matrix_positions (current_matrix,
                                first_unchanged_at_end_vpos + dvpos,
                                bottom_vpos, delta, delta_bytes);
@@ -15779,13 +15858,37 @@ cursor_row_p (w, row)
 
   if (PT == MATRIX_ROW_END_CHARPOS (row))
     {
-      /* If the row ends with a newline from a string, we don't want
-        the cursor there, but we still want it at the start of the
-        string if the string starts in this row.
-        If the row is continued it doesn't end in a newline.  */
+      /* Suppose the row ends on a string.
+        Unless the row is continued, that means it ends on a newline
+        in the string.  If it's anything other than a display string
+        (e.g. a before-string from an overlay), we don't want the
+        cursor there.  (This heuristic seems to give the optimal
+        behavior for the various types of multi-line strings.)  */
       if (CHARPOS (row->end.string_pos) >= 0)
-       cursor_row_p = (row->continued_p
-                       || PT >= MATRIX_ROW_START_CHARPOS (row));
+       {
+         if (row->continued_p)
+           cursor_row_p = 1;
+         else
+           {
+             /* Check for `display' property.  */
+             struct glyph *beg = row->glyphs[TEXT_AREA];
+             struct glyph *end = beg + row->used[TEXT_AREA] - 1;
+             struct glyph *glyph;
+
+             cursor_row_p = 0;
+             for (glyph = end; glyph >= beg; --glyph)
+               if (STRINGP (glyph->object))
+                 {
+                   Lisp_Object prop
+                     = Fget_char_property (make_number (PT),
+                                           Qdisplay, Qnil);
+                   cursor_row_p =
+                     (!NILP (prop)
+                      && display_prop_string_p (prop, glyph->object));
+                   break;
+                 }
+           }
+       }
       else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
        {
          /* If the row ends in middle of a real character,
@@ -16554,6 +16657,9 @@ display_mode_line (w, face_id, format)
   int count = SPECPDL_INDEX ();
 
   init_iterator (&it, w, -1, -1, NULL, face_id);
+  /* Don't extend on a previously drawn mode-line.
+     This may happen if called from pos_visible_p.  */
+  it.glyph_row->enabled_p = 0;
   prepare_desired_row (it.glyph_row);
 
   it.glyph_row->mode_line_p = 1;
@@ -17212,9 +17318,9 @@ for details) to use.
 
 Optional second arg FACE specifies the face property to put
 on all characters for which no face is specified.
-t means whatever face the window's mode line currently uses
+The value t means whatever face the window's mode line currently uses
 \(either `mode-line' or `mode-line-inactive', depending).
-nil means the default is no face property.
+A value of nil means the default is no face property.
 If FACE is an integer, the value string has no text properties.
 
 Optional third and fourth args WINDOW and BUFFER specify the window
@@ -17243,7 +17349,7 @@ are the selected window and the window's buffer).  */)
   CHECK_BUFFER (buffer);
 
   if (NILP (format))
-    return build_string ("");
+    return empty_unibyte_string;
 
   if (no_props)
     face = Qnil;
@@ -17301,7 +17407,7 @@ are the selected window and the window's buffer).  */)
     {
       mode_line_string_list = Fnreverse (mode_line_string_list);
       str = Fmapconcat (intern ("identity"), mode_line_string_list,
-                       make_string ("", 0));
+                       empty_unibyte_string);
     }
 
   unbind_to (count, Qnil);
@@ -17343,7 +17449,7 @@ pint2str (buf, width, d)
 
 /* Write a null-terminated, right justified decimal and "human
    readable" representation of the nonnegative integer D to BUF using
-   a minimal field width WIDTH.         D should be smaller than 999.5e24. */
+   a minimal field width WIDTH.  D should be smaller than 999.5e24. */
 
 static const char power_letter[] =
   {
@@ -17643,12 +17749,20 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
       break;
 
     case 'c':
-      {
-       int col = (int) current_column (); /* iftc */
-       w->column_number_displayed = make_number (col);
-       pint2str (decode_mode_spec_buf, field_width, col);
-       return decode_mode_spec_buf;
-      }
+      /* %c and %l are ignored in `frame-title-format'.
+         (In redisplay_internal, the frame title is drawn _before_ the
+         windows are updated, so the stuff which depends on actual
+         window contents (such as %l) may fail to render properly, or
+         even crash emacs.)  */
+      if (mode_line_target == MODE_LINE_TITLE)
+       return "";
+      else
+       {
+         int col = (int) current_column (); /* iftc */
+         w->column_number_displayed = make_number (col);
+         pint2str (decode_mode_spec_buf, field_width, col);
+         return decode_mode_spec_buf;
+       }
 
     case 'e':
 #ifndef SYSTEM_MALLOC
@@ -17690,11 +17804,16 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
 
     case 'l':
       {
-       int startpos = XMARKER (w->start)->charpos;
-       int startpos_byte = marker_byte_position (w->start);
-       int line, linepos, linepos_byte, topline;
-       int nlines, junk;
-       int height = WINDOW_TOTAL_LINES (w);
+       int startpos, startpos_byte, line, linepos, linepos_byte;
+       int topline, nlines, junk, height;
+
+       /* %c and %l are ignored in `frame-title-format'.  */
+       if (mode_line_target == MODE_LINE_TITLE)
+         return "";
+
+       startpos = XMARKER (w->start)->charpos;
+       startpos_byte = marker_byte_position (w->start);
+       height = WINDOW_TOTAL_LINES (w);
 
        /* If we decided that this buffer isn't suitable for line numbers,
           don't forget that too fast.  */
@@ -17882,6 +18001,16 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
 #endif
       break;
 
+    case '@':
+      {
+       Lisp_Object val;
+       val = call1 (intern ("file-remote-p"), current_buffer->directory);
+       if (NILP (val))
+         return "-";
+       else
+         return "@";
+      }
+
     case 't':                  /* indicate TEXT or BINARY */
 #ifdef MODE_LINE_BINARY_TEXT
       return MODE_LINE_BINARY_TEXT (b);
@@ -18306,6 +18435,27 @@ invisible_p (propval, list)
   return 0;
 }
 
+DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
+       doc: /* Non-nil if the property makes the text invisible.
+POS-OR-PROP can be a marker or number, in which case it is taken to be
+a position in the current buffer and the value of the `invisible' property
+is checked; or it can be some other value, which is then presumed to be the
+value of the `invisible' property of the text of interest.
+The non-nil value returned can be t for truly invisible text or something
+else if the text is replaced by an ellipsis.  */)
+     (pos_or_prop)
+     Lisp_Object pos_or_prop;
+{
+  Lisp_Object prop
+    = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
+       ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
+       : pos_or_prop);
+  int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
+  return (invis == 0 ? Qnil
+         : invis == 1 ? Qt
+         : make_number (invis));
+}
+
 /* Calculate a width or height in pixels from a specification using
    the following elements:
 
@@ -19753,7 +19903,7 @@ produce_image_glyph (it)
 {
   struct image *img;
   struct face *face;
-  int glyph_ascent;
+  int glyph_ascent, crop;
   struct glyph_slice slice;
 
   xassert (it->what == IT_IMAGE);
@@ -19861,6 +20011,15 @@ produce_image_glyph (it)
 
   take_vertical_position_into_account (it);
 
+  /* Automatically crop wide image glyphs at right edge so we can
+     draw the cursor on same display row.  */
+  if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
+      && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
+    {
+      it->pixel_width -= crop;
+      slice.width -= crop;
+    }
+
   if (it->glyph_row)
     {
       struct glyph *glyph;
@@ -20357,7 +20516,7 @@ x_produce_glyphs (it)
          /* If face has an overline, add the height of the overline
             (1 pixel) and a 1 pixel margin to the character height.  */
          if (face->overline_p)
-           it->ascent += 2;
+           it->ascent += overline_margin;
 
          if (it->constrain_row_ascent_descent_p)
            {
@@ -20559,7 +20718,7 @@ x_produce_glyphs (it)
          /* If face has an overline, add the height of the overline
             (1 pixel) and a 1 pixel margin to the character height.  */
          if (face->overline_p)
-           it->ascent += 2;
+           it->ascent += overline_margin;
 
          take_vertical_position_into_account (it);
 
@@ -20834,7 +20993,7 @@ x_produce_glyphs (it)
       /* If face has an overline, add the height of the overline
         (1 pixel) and a 1 pixel margin to the character height.  */
       if (face->overline_p)
-       it->ascent += 2;
+       it->ascent += overline_margin;
 
       take_vertical_position_into_account (it);
 
@@ -21209,10 +21368,35 @@ get_window_cursor_type (w, glyph, width, active_cursor)
   /* Use normal cursor if not blinked off.  */
   if (!w->cursor_off_p)
     {
-      if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
-       if (cursor_type == FILLED_BOX_CURSOR)
-         cursor_type = HOLLOW_BOX_CURSOR;
+#ifdef HAVE_WINDOW_SYSTEM
+      if (glyph != NULL && glyph->type == IMAGE_GLYPH)
+       {
+         if (cursor_type == FILLED_BOX_CURSOR)
+           {
+             /* Using a block cursor on large images can be very annoying.
+                So use a hollow cursor for "large" images.
+                If image is not transparent (no mask), also use hollow cursor.  */
+             struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
+             if (img != NULL && IMAGEP (img->spec))
+               {
+                 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
+                    where N = size of default frame font size.
+                    This should cover most of the "tiny" icons people may use.  */
+                 if (!img->mask
+                     || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
+                     || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
+                   cursor_type = HOLLOW_BOX_CURSOR;
+               }
+           }
+         else if (cursor_type != NO_CURSOR)
+           {
+             /* Display current only supports BOX and HOLLOW cursors for images.
+                So for now, unconditionally use a HOLLOW cursor when cursor is
+                not a solid box cursor.  */
+             cursor_type = HOLLOW_BOX_CURSOR;
+           }
       }
+#endif
       return cursor_type;
     }
 
@@ -21763,7 +21947,7 @@ show_mouse_face (dpyinfo, draw)
     }
 
   /* Change the mouse cursor.  */
-  if (draw == DRAW_NORMAL_TEXT)
+  if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
     rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
   else if (draw == DRAW_MOUSE_FACE)
     rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
@@ -22313,7 +22497,7 @@ note_mode_line_or_margin_highlight (window, x, y, area)
 
   Lisp_Object mouse_face;
   int original_x_pixel = x;
-  struct glyph * glyph = NULL;
+  struct glyph * glyph = NULL, * row_start_glyph = NULL;
   struct glyph_row *row;
 
   if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
@@ -22331,7 +22515,7 @@ note_mode_line_or_margin_highlight (window, x, y, area)
       /* Find glyph */
       if (row->mode_line_p && row->enabled_p)
        {
-         glyph = row->glyphs[TEXT_AREA];
+         glyph = row_start_glyph = row->glyphs[TEXT_AREA];
          end = glyph + row->used[TEXT_AREA];
 
          for (x0 = original_x_pixel;
@@ -22455,12 +22639,17 @@ note_mode_line_or_margin_highlight (window, x, y, area)
             is converted to a flatten by emacs lisp interpreter.
             The internal string is an element of the structures.
             The displayed string is the flatten string. */
-         for (tmp_glyph = glyph - 1, gpos = 0;
-              tmp_glyph->charpos >= XINT (b);
-              tmp_glyph--, gpos++)
+         gpos = 0;
+         if (glyph > row_start_glyph)
            {
-             if (!EQ (tmp_glyph->object, glyph->object))
-               break;
+             tmp_glyph = glyph - 1;
+             while (tmp_glyph >= row_start_glyph
+                    && tmp_glyph->charpos >= XINT (b)
+                    && EQ (tmp_glyph->object, glyph->object))
+               {
+                 tmp_glyph--;
+                 gpos++;
+               }
            }
 
          /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
@@ -22548,7 +22737,7 @@ note_mouse_highlight (f, x, y)
   struct buffer *b;
 
   /* When a menu is active, don't highlight because this looks odd.  */
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
   if (popup_activated ())
     return;
 #endif
@@ -23638,6 +23827,7 @@ syms_of_xdisp ()
   defsubr (&Slookup_image_map);
 #endif
   defsubr (&Sformat_mode_line);
+  defsubr (&Sinvisible_p);
 
   staticpro (&Qmenu_bar_update_hook);
   Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
@@ -23884,7 +24074,7 @@ Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI).  */);
   truncate_partial_width_windows = 1;
 
   DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
-    doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
+    doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
 Any other value means to use the appropriate face, `mode-line',
 `header-line', or `menu' respectively.  */);
   mode_line_inverse_video = 1;
@@ -23915,9 +24105,10 @@ This variable is not guaranteed to be accurate except while processing
   DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
     doc: /* Template for displaying the title bar of visible frames.
 \(Assuming the window manager supports this feature.)
-This variable has the same structure as `mode-line-format' (which see),
-and is used only on frames for which no explicit name has been set
-\(see `modify-frame-parameters').  */);
+
+This variable has the same structure as `mode-line-format', except that
+the %c and %l constructs are ignored.  It is used only on frames for
+which no explicit name has been set \(see `modify-frame-parameters').  */);
 
   DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
     doc: /* Template for displaying the title bar of an iconified frame.
@@ -23929,7 +24120,7 @@ and is used only on frames for which no explicit name has been set
     = Vframe_title_format
     = Fcons (intern ("multiple-frames"),
             Fcons (build_string ("%b"),
-                   Fcons (Fcons (empty_string,
+                   Fcons (Fcons (empty_unibyte_string,
                                  Fcons (intern ("invocation-name"),
                                         Fcons (build_string ("@"),
                                                Fcons (intern ("system-name"),
@@ -23940,7 +24131,7 @@ and is used only on frames for which no explicit name has been set
     doc: /* Maximum number of lines to keep in the message log buffer.
 If nil, disable message logging.  If t, log messages but don't truncate
 the buffer when it becomes large.  */);
-  Vmessage_log_max = make_number (50);
+  Vmessage_log_max = make_number (100);
 
   DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
     doc: /* Functions called before redisplay, if window sizes have changed.
@@ -23963,16 +24154,30 @@ Each function is called with two arguments, the window and the end trigger value
 See `set-window-redisplay-end-trigger'.  */);
   Vredisplay_end_trigger_functions = Qnil;
 
-  DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
-    doc: /* *Non-nil means autoselect window with mouse pointer.  */);
-  mouse_autoselect_window = 0;
-
-  DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
+  DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window,
+     doc: /* *Non-nil means autoselect window with mouse pointer.
+If nil, do not autoselect windows.
+A positive number means delay autoselection by that many seconds: a
+window is autoselected only after the mouse has remained in that
+window for the duration of the delay.
+A negative number has a similar effect, but causes windows to be
+autoselected only after the mouse has stopped moving.  \(Because of
+the way Emacs compares mouse events, you will occasionally wait twice
+that time before the window gets selected.\)
+Any other value means to autoselect window instantaneously when the
+mouse pointer enters it.
+
+Autoselection selects the minibuffer only if it is active, and never
+unselects the minibuffer if it is active.  */);
+  Vmouse_autoselect_window = Qnil;
+
+  DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,
     doc: /* *Non-nil means automatically resize tool-bars.
-This increases a tool-bar's height if not all tool-bar items are visible.
-It decreases a tool-bar's height when it would display blank lines
-otherwise.  */);
-  auto_resize_tool_bars_p = 1;
+This dynamically changes the tool-bar's height to the minimum height
+that is needed to make all tool-bar items visible.
+If value is `grow-only', the tool-bar's height is only increased
+automatically; to decrease the tool-bar height, use \\[recenter].  */);
+  Vauto_resize_tool_bars = Qt;
 
   DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
     doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them.  */);
@@ -24085,6 +24290,11 @@ This is used to update submenus such as Buffers,
 whose contents depend on various data.  */);
   Vmenu_bar_update_hook = Qnil;
 
+  DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
+              doc: /* Frame for which we are updating a menu.
+The enable predicate for a menu binding should check this variable.  */);
+  Vmenu_updating_frame = Qnil;
+
   DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
     doc: /* Non-nil means don't update menu bars.  Internal use only.  */);
   inhibit_menubar_update = 0;
@@ -24110,6 +24320,12 @@ whose contents depend on various data.  */);
               doc: /* Inhibit try_cursor_movement display optimization.  */);
   inhibit_try_cursor_movement = 0;
 #endif /* GLYPH_DEBUG */
+
+  DEFVAR_INT ("overline-margin", &overline_margin,
+              doc: /* *Space between overline and text, in pixels.
+The default value is 2: the height of the overline (1 pixel) plus 1 pixel
+margin to the caracter height.  */);
+  overline_margin = 2;
 }