]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
Merge from emacs--devo--0
[gnu-emacs] / src / xdisp.c
index 909ec688affd7e60c459b615416bd48a92dda14f..674e07a2ed75c89f1f51cf59f8d183dc51b1cd89 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,
@@ -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
@@ -578,21 +580,12 @@ Lisp_Object Vmessage_log_max;
 
 static Lisp_Object Vmessages_buffer_name;
 
-/* Index 0 is the buffer that holds the current (desired) echo area message,
-   or nil if none is desired right now.
-
-   Index 1 is the buffer that holds the previously displayed echo area message,
-   or nil to indicate no message.  This is normally what's on the screen now.
-
-   These two can point to the same buffer.  That happens when the last
-   message output by the user (or made by echoing) has been displayed.  */
+/* Current, index 0, and last displayed echo area message.  Either
+   buffers from echo_buffers, or nil to indicate no message.  */
 
 Lisp_Object echo_area_buffer[2];
 
-/* Permanent pointers to the two buffers that are used for echo area
-   purposes.  Once the two buffers are made, and their pointers are
-   placed here, these two slots remain unchanged unless those buffers
-   need to be created afresh.  */
+/* The buffers referenced from echo_area_buffer.  */
 
 static Lisp_Object echo_buffer[2];
 
@@ -811,10 +804,6 @@ static int clear_face_cache_count;
 static int clear_image_cache_count;
 #endif
 
-/* Record the previous terminal frame we displayed.  */
-
-static struct frame *previous_terminal_frame;
-
 /* Non-zero while redisplay_internal is in progress.  */
 
 int redisplaying_p;
@@ -2506,7 +2495,7 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
   XSETWINDOW (it->window, w);
   it->w = w;
   it->f = XFRAME (w->frame);
-
+  
   /* Extra space between lines (on window systems only).  */
   if (base_face_id == DEFAULT_FACE_ID
       && FRAME_WINDOW_P (it->f))
@@ -2523,9 +2512,9 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
 
   /* If realized faces have been removed, e.g. because of face
      attribute changes of named faces, recompute them.  When running
-     in batch mode, the face cache of Vterminal_frame is null.  If
+     in batch mode, the face cache of the initial frame is null.  If
      we happen to get called, make a dummy face cache.  */
-  if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
+  if (FRAME_FACE_CACHE (it->f) == NULL)
     init_frame_faces (it->f);
   if (FRAME_FACE_CACHE (it->f)->used == 0)
     recompute_basic_faces (it->f);
@@ -3950,7 +3939,7 @@ handle_single_display_spec (it, spec, object, position,
       && EQ (XCAR (spec), Qheight)
       && CONSP (XCDR (spec)))
     {
-      if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+      if (!FRAME_WINDOW_P (it->f))
        return 0;
 
       it->font_height = XCAR (XCDR (spec));
@@ -4016,7 +4005,7 @@ handle_single_display_spec (it, spec, object, position,
       && EQ (XCAR (spec), Qspace_width)
       && CONSP (XCDR (spec)))
     {
-      if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+      if (!FRAME_WINDOW_P (it->f))
        return 0;
 
       value = XCAR (XCDR (spec));
@@ -4032,7 +4021,7 @@ handle_single_display_spec (it, spec, object, position,
     {
       Lisp_Object tem;
 
-      if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+      if (!FRAME_WINDOW_P (it->f))
        return 0;
 
       if (tem = XCDR (spec), CONSP (tem))
@@ -4058,7 +4047,7 @@ handle_single_display_spec (it, spec, object, position,
       && EQ (XCAR (spec), Qraise)
       && CONSP (XCDR (spec)))
     {
-      if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+      if (!FRAME_WINDOW_P (it->f))
        return 0;
 
 #ifdef HAVE_WINDOW_SYSTEM
@@ -4099,7 +4088,7 @@ handle_single_display_spec (it, spec, object, position,
       int face_id = DEFAULT_FACE_ID;
       int fringe_bitmap;
 
-      if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+      if (!FRAME_WINDOW_P (it->f))
        /* If we return here, POSITION has been advanced
           across the text with this property.  */
        return 0;
@@ -4148,7 +4137,7 @@ handle_single_display_spec (it, spec, object, position,
          it->left_user_fringe_face_id = face_id;
        }
       else
-       {
+        {
          it->right_user_fringe_bitmap = fringe_bitmap;
          it->right_user_fringe_face_id = face_id;
        }
@@ -4193,9 +4182,9 @@ handle_single_display_spec (it, spec, object, position,
 
   valid_p = (STRINGP (value)
 #ifdef HAVE_WINDOW_SYSTEM
-            || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
+             || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
 #endif /* not HAVE_WINDOW_SYSTEM */
-            || (CONSP (value) && EQ (XCAR (value), Qspace)));
+             || (CONSP (value) && EQ (XCAR (value), Qspace)));
 
   if (valid_p && !display_replaced_before_p)
     {
@@ -4265,7 +4254,7 @@ handle_single_display_spec (it, spec, object, position,
 }
 
 
-/* Check if SPEC is a display specification value whose text should be
+/* Check if SPEC is a display sub-property value whose text should be
    treated as intangible.  */
 
 static int
@@ -6267,7 +6256,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;
 
@@ -6828,7 +6817,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:
@@ -7517,8 +7511,8 @@ message2_nolog (m, nbytes, multibyte)
       do_pending_window_change (0);
       echo_area_display (1);
       do_pending_window_change (0);
-      if (frame_up_to_date_hook != 0 && ! gc_in_progress)
-       (*frame_up_to_date_hook) (f);
+      if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
+       (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
     }
 }
 
@@ -7621,8 +7615,8 @@ message3_nolog (m, nbytes, multibyte)
       do_pending_window_change (0);
       echo_area_display (1);
       do_pending_window_change (0);
-      if (frame_up_to_date_hook != 0 && ! gc_in_progress)
-       (*frame_up_to_date_hook) (f);
+      if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
+       (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
     }
 }
 
@@ -7860,6 +7854,10 @@ ensure_echo_area_buffers ()
    WHICH > 0 means use echo_area_buffer[1].  If that is nil, choose a
    suitable buffer from echo_buffer[] and clear it.
 
+   If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
+   that the current message becomes the last displayed one, make
+   choose a suitable buffer for echo_area_buffer[0], and clear it.
+
    Value is what FN returns.  */
 
 static int
@@ -7884,6 +7882,17 @@ with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
     this_one = 0, the_other = 1;
   else if (which > 0)
     this_one = 1, the_other = 0;
+  else
+    {
+      this_one = 0, the_other = 1;
+      clear_buffer_p = 1;
+
+      /* We need a fresh one in case the current echo buffer equals
+        the one containing the last displayed echo area message.  */
+      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
      have one.  */
@@ -8521,7 +8530,7 @@ set_message (s, string, nbytes, multibyte_p)
     = ((s && multibyte_p)
        || (STRINGP (string) && STRING_MULTIBYTE (string)));
 
-  with_echo_area_buffer (0, 0, set_message_1,
+  with_echo_area_buffer (0, -1, set_message_1,
                         (EMACS_INT) s, string, nbytes, multibyte_p);
   message_buf_print = 0;
   help_echo_showing_p = 0;
@@ -8551,7 +8560,6 @@ set_message_1 (a1, a2, nbytes, multibyte_p)
 
   /* Insert new message at BEG.  */
   TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
-  Ferase_buffer ();
 
   if (STRINGP (string))
     {
@@ -8647,11 +8655,11 @@ clear_garbaged_frames ()
     {
       Lisp_Object tail, frame;
       int changed_count = 0;
-
+      
       FOR_EACH_FRAME (tail, frame)
        {
          struct frame *f = XFRAME (frame);
-
+         
          if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
            {
              if (f->resized_p)
@@ -8665,7 +8673,7 @@ clear_garbaged_frames ()
              f->resized_p = 0;
            }
        }
-
+      
       frame_garbaged = 0;
       if (changed_count)
        ++windows_or_buffers_changed;
@@ -8698,11 +8706,10 @@ echo_area_display (update_frame_p)
 /* The terminal frame is used as the first Emacs frame on the Mac OS.  */
 #ifndef MAC_OS8
 #ifdef HAVE_WINDOW_SYSTEM
-  /* 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.  */
-  if (EQ (selected_frame, Vterminal_frame)
-      && !NILP (Vwindow_system))
+  /* When Emacs starts, selected_frame may be the initial terminal
+     frame.  If we let this through, a message would be displayed on
+     the terminal.  */
+  if (FRAME_INITIAL_P (XFRAME (selected_frame)))
     return 0;
 #endif /* HAVE_WINDOW_SYSTEM */
 #endif
@@ -8753,7 +8760,7 @@ echo_area_display (update_frame_p)
                 Can do with a display update of the echo area,
                 unless we displayed some mode lines.  */
              update_single_window (w, 1);
-             rif->flush_display (f);
+             FRAME_RIF (f)->flush_display (f);
            }
          else
            update_frame (f, 1, 1);
@@ -8768,8 +8775,10 @@ echo_area_display (update_frame_p)
   else if (!EQ (mini_window, selected_window))
     windows_or_buffers_changed++;
 
-  /* The current message is now also the last one displayed.  */
+  /* Last displayed message is now the current message.  */
   echo_area_buffer[1] = echo_area_buffer[0];
+  /* Inform read_char that we're not echoing.  */
+  echo_message_buffer = Qnil;
 
   /* Prevent redisplay optimization in redisplay_internal by resetting
      this_line_start_pos.  This is done because the mini-buffer now
@@ -9323,8 +9332,8 @@ x_cursor_to (vpos, hpos, y, x)
     {
       BLOCK_INPUT;
       display_and_set_cursor (w, 1, hpos, vpos, x, y);
-      if (rif->flush_display_optional)
-       rif->flush_display_optional (SELECTED_FRAME ());
+      if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
+       FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
       UNBLOCK_INPUT;
     }
 }
@@ -9358,7 +9367,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)
@@ -9689,9 +9698,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;
@@ -9713,6 +9729,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;
     }
@@ -9815,9 +9832,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;
@@ -9910,10 +9926,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.  */
@@ -9939,29 +9955,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;
 }
 
 
@@ -10758,6 +10785,8 @@ select_frame_for_redisplay (frame)
   Lisp_Object tail, sym, val;
   Lisp_Object old = selected_frame;
 
+  xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
+
   selected_frame = frame;
 
   for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
@@ -10811,7 +10840,7 @@ redisplay_internal (preserve_echo_area)
   int must_finish = 0;
   struct text_pos tlbufpos, tlendpos;
   int number_of_visible_frames;
-  int count;
+  int count, count1;
   struct frame *sf;
   int polling_stopped_here = 0;
 
@@ -10847,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
@@ -10895,17 +10924,16 @@ redisplay_internal (preserve_echo_area)
   if (face_change_count)
     ++windows_or_buffers_changed;
 
-  if (! FRAME_WINDOW_P (sf)
-      && previous_terminal_frame != sf)
+  if (FRAME_TERMCAP_P (sf)
+      && FRAME_TTY (sf)->previous_frame != sf)
     {
-      /* Since frames on an ASCII terminal share the same display
-        area, displaying a different frame means redisplay the whole
-        thing.  */
+      /* Since frames on a single ASCII terminal share the same
+        display area, displaying a different frame means redisplay
+        the whole thing.  */
       windows_or_buffers_changed++;
       SET_FRAME_GARBAGED (sf);
-      XSETFRAME (Vterminal_frame, sf);
+      FRAME_TTY (sf)->previous_frame = sf;
     }
-  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
@@ -10927,6 +10955,7 @@ redisplay_internal (preserve_echo_area)
       }
   }
 
+  
   /* Notice any pending interrupt request to change frame size.  */
   do_pending_window_change (1);
 
@@ -10949,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
@@ -10960,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
@@ -11282,7 +11317,7 @@ redisplay_internal (preserve_echo_area)
        {
          struct frame *f = XFRAME (frame);
 
-         if (FRAME_WINDOW_P (f) || f == sf)
+         if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
            {
              if (! EQ (frame, selected_frame))
                /* Select the frame, for the sake of frame-local
@@ -11291,16 +11326,16 @@ redisplay_internal (preserve_echo_area)
 
              /* Mark all the scroll bars to be removed; we'll redeem
                 the ones we want when we redisplay their windows.  */
-             if (condemn_scroll_bars_hook)
-               condemn_scroll_bars_hook (f);
+             if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
+               FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
 
              if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
                redisplay_windows (FRAME_ROOT_WINDOW (f));
 
              /* Any scroll bars which redisplay_windows should have
                 nuked should now go away.  */
-             if (judge_scroll_bars_hook)
-               judge_scroll_bars_hook (f);
+             if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
+               FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
 
              /* If fonts changed, display again.  */
              /* ??? rms: I suspect it is a mistake to jump all the way
@@ -11347,12 +11382,12 @@ redisplay_internal (preserve_echo_area)
          FOR_EACH_FRAME (tail, frame)
            {
              struct frame *f = XFRAME (frame);
-             if (f->updated_p)
-               {
-                 mark_window_display_accurate (f->root_window, 1);
-                 if (frame_up_to_date_hook)
-                   frame_up_to_date_hook (f);
-               }
+              if (f->updated_p)
+                {
+                  mark_window_display_accurate (f->root_window, 1);
+                  if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
+                    FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
+                }
            }
        }
     }
@@ -11437,8 +11472,8 @@ redisplay_internal (preserve_echo_area)
          /* Say overlay arrows are up to date.  */
          update_overlay_arrows (1);
 
-         if (frame_up_to_date_hook != 0)
-           frame_up_to_date_hook (sf);
+         if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
+           FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
        }
 
       update_mode_lines = 0;
@@ -11548,8 +11583,9 @@ redisplay_preserve_echo_area (from_where)
   else
     redisplay_internal (1);
 
-  if (rif != NULL && rif->flush_display_optional)
-    rif->flush_display_optional (NULL);
+  if (FRAME_RIF (SELECTED_FRAME ()) != NULL
+      && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
+    FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
 }
 
 
@@ -11557,7 +11593,8 @@ redisplay_preserve_echo_area (from_where)
    redisplay_internal.  Reset redisplaying_p to the value it had
    before redisplay_internal was called, and clear
    prevent_freeing_realized_faces_p.  It also selects the previously
-   selected frame.  */
+   selected frame, unless it has been deleted (by an X connection
+   failure during redisplay, for example).  */
 
 static Lisp_Object
 unwind_redisplay (val)
@@ -11568,7 +11605,8 @@ unwind_redisplay (val)
   old_redisplaying_p = XCAR (val);
   redisplaying_p = XFASTINT (old_redisplaying_p);
   old_frame = XCDR (val);
-  if (! EQ (old_frame, selected_frame))
+  if (! EQ (old_frame, selected_frame)
+      && FRAME_LIVE_P (XFRAME (old_frame)))
     select_frame_for_redisplay (old_frame);
   return Qnil;
 }
@@ -12717,7 +12755,9 @@ set_vertical_scroll_bar (w)
     start = end = whole = 0;
 
   /* Indicate what this scroll bar ought to be displaying now.  */
-  set_vertical_scroll_bar_hook (w, end - start, whole, start);
+  if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
+    (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
+      (w, end - start, whole, start);
 }
 
 
@@ -12752,6 +12792,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;
@@ -12816,6 +12857,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
@@ -12939,6 +12983,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)
@@ -13109,32 +13155,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");
@@ -13437,17 +13476,22 @@ redisplay_window (window, just_this_one_p)
         display_menu_bar (w);
 
 #ifdef HAVE_WINDOW_SYSTEM
-#ifdef USE_GTK
-      redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
+      if (FRAME_WINDOW_P (f))
+        {
+#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);
-
+          redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
+            && (FRAME_TOOL_BAR_LINES (f) > 0
+                || !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
     }
 
@@ -13481,7 +13525,8 @@ redisplay_window (window, just_this_one_p)
 
       /* Note that we actually used the scroll bar attached to this
         window, so it shouldn't be deleted at the end of redisplay.  */
-      redeem_scroll_bar_hook (w);
+      if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
+        (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
     }
 
   /* Restore current_buffer and value of point in it.  */
@@ -13510,6 +13555,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));
@@ -13746,10 +13792,10 @@ try_window_reusing_current_matrix (w)
          if (run.height > 0 && run.current_y != run.desired_y)
            {
              update_begin (f);
-             rif->update_window_begin_hook (w);
-             rif->clear_window_mouse_face (w);
-             rif->scroll_run_hook (w, &run);
-             rif->update_window_end_hook (w, 0, 0);
+             FRAME_RIF (f)->update_window_begin_hook (w);
+             FRAME_RIF (f)->clear_window_mouse_face (w);
+             FRAME_RIF (f)->scroll_run_hook (w, &run);
+             FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
              update_end (f);
            }
 
@@ -13761,7 +13807,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.  */
@@ -13918,10 +13964,10 @@ try_window_reusing_current_matrix (w)
       if (run.height)
        {
          update_begin (f);
-         rif->update_window_begin_hook (w);
-         rif->clear_window_mouse_face (w);
-         rif->scroll_run_hook (w, &run);
-         rif->update_window_end_hook (w, 0, 0);
+         FRAME_RIF (f)->update_window_begin_hook (w);
+         FRAME_RIF (f)->clear_window_mouse_face (w);
+         FRAME_RIF (f)->scroll_run_hook (w, &run);
+         FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
          update_end (f);
        }
 
@@ -14371,7 +14417,7 @@ try_window_id (w)
 
   /* Window must either use window-based redisplay or be full width.  */
   if (!FRAME_WINDOW_P (f)
-      && (!line_ins_del_ok
+      && (!FRAME_LINE_INS_DEL_OK (f)
          || !WINDOW_FULL_WIDTH_P (w)))
     GIVE_UP (4);
 
@@ -14780,10 +14826,10 @@ try_window_id (w)
 
       if (FRAME_WINDOW_P (f))
        {
-         rif->update_window_begin_hook (w);
-         rif->clear_window_mouse_face (w);
-         rif->scroll_run_hook (w, &run);
-         rif->update_window_end_hook (w, 0, 0);
+         FRAME_RIF (f)->update_window_begin_hook (w);
+         FRAME_RIF (f)->clear_window_mouse_face (w);
+         FRAME_RIF (f)->scroll_run_hook (w, &run);
+         FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
        }
       else
        {
@@ -14801,36 +14847,36 @@ try_window_id (w)
            {
              /* Scroll last_unchanged_at_beg_row to the end of the
                 window down dvpos lines.  */
-             set_terminal_window (end);
+             set_terminal_window (f, end);
 
              /* On dumb terminals delete dvpos lines at the end
                 before inserting dvpos empty lines.  */
-             if (!scroll_region_ok)
-               ins_del_lines (end - dvpos, -dvpos);
+             if (!FRAME_SCROLL_REGION_OK (f))
+               ins_del_lines (f, end - dvpos, -dvpos);
 
              /* Insert dvpos empty lines in front of
                  last_unchanged_at_beg_row.  */
-             ins_del_lines (from, dvpos);
+             ins_del_lines (f, from, dvpos);
            }
          else if (dvpos < 0)
            {
              /* Scroll up last_unchanged_at_beg_vpos to the end of
                 the window to last_unchanged_at_beg_vpos - |dvpos|.  */
-             set_terminal_window (end);
+             set_terminal_window (f, end);
 
              /* Delete dvpos lines in front of
                 last_unchanged_at_beg_vpos.  ins_del_lines will set
                 the cursor to the given vpos and emit |dvpos| delete
                 line sequences.  */
-             ins_del_lines (from + dvpos, dvpos);
+             ins_del_lines (f, from + dvpos, dvpos);
 
              /* On a dumb terminal insert dvpos empty lines at the
                  end.  */
-             if (!scroll_region_ok)
-               ins_del_lines (end + dvpos, -dvpos);
+             if (!FRAME_SCROLL_REGION_OK (f))
+               ins_del_lines (f, end + dvpos, -dvpos);
            }
 
-         set_terminal_window (0);
+         set_terminal_window (f, 0);
        }
 
       update_end (f);
@@ -14862,7 +14908,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);
@@ -15817,13 +15863,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,
@@ -16380,7 +16450,7 @@ display_menu_bar (w)
 
   /* Don't do all this for graphical frames.  */
 #ifdef HAVE_NTGUI
-  if (!NILP (Vwindow_system))
+  if (FRAME_W32_P (f))
     return;
 #endif
 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
@@ -16611,10 +16681,10 @@ display_mode_line (w, face_id, format)
   /* Temporarily make frame's keyboard the current kboard so that
      kboard-local variables in the mode_line_format will get the right
      values.  */
-  push_frame_kboard (it.f);
+  push_kboard (FRAME_KBOARD (it.f));
   record_unwind_save_match_data ();
   display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
-  pop_frame_kboard ();
+  pop_kboard ();
 
   unbind_to (count, Qnil);
 
@@ -17253,9 +17323,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
@@ -17284,7 +17354,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;
@@ -17329,9 +17399,9 @@ are the selected window and the window's buffer).  */)
        = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
     }
 
-  push_frame_kboard (it.f);
+  push_kboard (FRAME_KBOARD (it.f));
   display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
-  pop_frame_kboard ();
+  pop_kboard ();
 
   if (no_props)
     {
@@ -17342,7 +17412,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);
@@ -17936,6 +18006,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);
@@ -17955,8 +18035,8 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
          {
            /* No need to mention EOL here--the terminal never needs
               to do EOL conversion.  */
-           p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
-           p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
+           p = decode_mode_spec_coding (FRAME_KEYBOARD_CODING (f)->symbol, p, 0);
+           p = decode_mode_spec_coding (FRAME_TERMINAL_CODING (f)->symbol, p, 0);
          }
        p = decode_mode_spec_coding (b->buffer_file_coding_system,
                                     p, eol_flag);
@@ -18448,6 +18528,8 @@ calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
   if (NILP (prop))
     return OK_PIXELS (0);
 
+  xassert (FRAME_LIVE_P (it->f));
+
   if (SYMBOLP (prop))
     {
       if (SCHARS (SYMBOL_NAME (prop)) == 2)
@@ -18564,7 +18646,8 @@ calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
       if (SYMBOLP (car))
        {
 #ifdef HAVE_WINDOW_SYSTEM
-         if (valid_image_p (prop))
+         if (FRAME_WINDOW_P (it->f)
+             && valid_image_p (prop))
            {
              int id = lookup_image (it->f, prop);
              struct image *img = IMAGE_FROM_ID (it->f, id);
@@ -18805,7 +18888,7 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
            = FONT_INFO_FROM_ID (f, face->font_info_id);
          if (font_info)
            glyph->font_type
-             = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
+             = FRAME_RIF (f)->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
        }
     }
 
@@ -19038,7 +19121,7 @@ x_get_glyph_overhangs (glyph, f, left, right)
       font = face->font;
       font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
       if (font  /* ++KFS: Should this be font_info ?  */
-         && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
+         && (pcm = FRAME_RIF (f)->per_char_metric (font, &char2b, glyph->font_type)))
        {
          if (pcm->rbearing > pcm->width)
            *right = pcm->rbearing - pcm->width;
@@ -19206,7 +19289,7 @@ get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
          struct font_info *font_info
            = FONT_INFO_FROM_ID (f, face->font_info_id);
          if (font_info)
-           rif->encode_char (c, char2b, font_info, 0);
+           FRAME_RIF (f)->encode_char (c, char2b, font_info, 0);
        }
     }
 
@@ -19269,8 +19352,8 @@ compute_overhangs_and_x (s, x, backward_p)
     {
       while (s)
        {
-         if (rif->compute_glyph_string_overhangs)
-           rif->compute_glyph_string_overhangs (s);
+         if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
+           FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
          x -= s->width;
          s->x = x;
          s = s->prev;
@@ -19280,8 +19363,8 @@ compute_overhangs_and_x (s, x, backward_p)
     {
       while (s)
        {
-         if (rif->compute_glyph_string_overhangs)
-           rif->compute_glyph_string_overhangs (s);
+         if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
+           FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
          s->x = x;
          x += s->width;
          s = s->next;
@@ -19569,9 +19652,9 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps)
       struct glyph_string *h, *t;
 
       /* Compute overhangs for all glyph strings.  */
-      if (rif->compute_glyph_string_overhangs)
+      if (FRAME_RIF (f)->compute_glyph_string_overhangs)
        for (s = head; s; s = s->next)
-         rif->compute_glyph_string_overhangs (s);
+         FRAME_RIF (f)->compute_glyph_string_overhangs (s);
 
       /* Prepend glyph strings for glyphs in front of the first glyph
         string that are overwritten because of the first glyph
@@ -19649,7 +19732,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps)
 
   /* Draw all strings.  */
   for (s = head; s; s = s->next)
-    rif->draw_glyph_string (s);
+    FRAME_RIF (f)->draw_glyph_string (s);
 
   if (area == TEXT_AREA
       && !row->full_width_p
@@ -20344,20 +20427,20 @@ x_produce_glyphs (it)
 
          it->nglyphs = 1;
 
-         pcm = rif->per_char_metric (font, &char2b,
-                                     FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
-
-         if (it->override_ascent >= 0)
-           {
-             it->ascent = it->override_ascent;
-             it->descent = it->override_descent;
-             boff = it->override_boff;
-           }
-         else
-           {
-             it->ascent = FONT_BASE (font) + boff;
-             it->descent = FONT_DESCENT (font) - boff;
-           }
+          pcm = FRAME_RIF (it->f)->per_char_metric
+            (font, &char2b, FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
+
+         if (it->override_ascent >= 0)
+           {
+             it->ascent = it->override_ascent;
+             it->descent = it->override_descent;
+             boff = it->override_boff;
+           }
+         else
+           {
+             it->ascent = FONT_BASE (font) + boff;
+             it->descent = FONT_DESCENT (font) - boff;
+           }
 
          if (pcm)
            {
@@ -20575,8 +20658,8 @@ x_produce_glyphs (it)
             from the charset width; this is what old redisplay code
             did.  */
 
-         pcm = rif->per_char_metric (font, &char2b,
-                                     FONT_TYPE_FOR_MULTIBYTE (font, it->c));
+         pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
+                                                    FONT_TYPE_FOR_MULTIBYTE (font, it->c));
 
          if (font_not_found_p || !pcm)
            {
@@ -20707,8 +20790,8 @@ x_produce_glyphs (it)
 
          /* Initialize the bounding box.  */
          if (font_info
-             && (pcm = rif->per_char_metric (font, &char2b,
-                                             FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
+             && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
+                                                            FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
            {
              width = pcm->width;
              ascent = pcm->ascent;
@@ -20766,8 +20849,8 @@ x_produce_glyphs (it)
                }
 
              if (font_info
-                 && (pcm = rif->per_char_metric (font, &char2b,
-                                                 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
+                 && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
+                                                                FONT_TYPE_FOR_MULTIBYTE (font, ch))))
                {
                  width = pcm->width;
                  ascent = pcm->ascent;
@@ -21007,8 +21090,8 @@ x_insert_glyphs (start, len)
   frame_x = window_box_left (w, updated_area) + output_cursor.x;
   frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
 
-  rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
-                               line_height, shift_by_width);
+  FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
+                                          line_height, shift_by_width);
 
   /* Write the glyphs.  */
   hpos = start - row->glyphs[updated_area];
@@ -21090,8 +21173,8 @@ x_clear_end_of_line (to_x)
   if (to_x > from_x && to_y > from_y)
     {
       BLOCK_INPUT;
-      rif->clear_frame_area (f, from_x, from_y,
-                            to_x - from_x, to_y - from_y);
+      FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
+                                       to_x - from_x, to_y - from_y);
       UNBLOCK_INPUT;
     }
 }
@@ -21604,7 +21687,7 @@ erase_phys_cursor (w)
       x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
 
       if (width > 0)
-      rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
+       FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
     }
 
   /* Erase the cursor by redrawing the character underneath it.  */
@@ -21701,9 +21784,9 @@ display_and_set_cursor (w, on, hpos, vpos, x, y)
       w->phys_cursor.vpos = vpos;
     }
 
-  rif->draw_window_cursor (w, glyph_row, x, y,
-                          new_cursor_type, new_cursor_width,
-                          on, active_cursor);
+  FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
+                                     new_cursor_type, new_cursor_width,
+                                     on, active_cursor);
 }
 
 
@@ -21851,12 +21934,12 @@ show_mouse_face (dpyinfo, draw)
     }
 
   /* Change the mouse cursor.  */
-  if (draw == DRAW_NORMAL_TEXT)
-    rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
+  if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
+    FRAME_RIF (f)->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);
+    FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
   else
-    rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
+    FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
 }
 
 /* EXPORT:
@@ -22295,7 +22378,6 @@ on_hot_spot_p (hot_spot, x, y)
          return inside;
        }
     }
-  /* If we don't understand the format, pretend we're not in the hot-spot.  */
   return 0;
 }
 
@@ -22375,7 +22457,7 @@ define_frame_cursor1 (f, cursor, pointer)
     }
 
   if (cursor != No_Cursor)
-    rif->define_frame_cursor (f, cursor);
+    FRAME_RIF (f)->define_frame_cursor (f, cursor);
 }
 
 /* Take proper action when mouse has moved to the mode or header line
@@ -22401,7 +22483,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)
@@ -22419,7 +22501,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;
@@ -22543,12 +22625,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
@@ -22636,7 +22723,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)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
   if (popup_activated ())
     return;
 #endif
@@ -23338,8 +23425,8 @@ phys_cursor_in_rect_p (w, r)
         I assume the effect is the same -- and this is portable.  */
       return x_intersect_rectangles (&cr, r, &result);
     }
-  else
-    return 0;
+  /* If we don't understand the format, pretend we're not in the hot-spot.  */
+  return 0;
 }
 
 
@@ -23351,6 +23438,8 @@ void
 x_draw_vertical_border (w)
      struct window *w;
 {
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  
   /* We could do better, if we knew what type of scroll-bar the adjacent
      windows (on either side) have...  But we don't :-(
      However, I think this works ok.  ++KFS 2003-04-25 */
@@ -23371,9 +23460,9 @@ x_draw_vertical_border (w)
       y1 -= 1;
 
       if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
-       x1 -= 1;
+        x1 -= 1;
 
-      rif->draw_vertical_window_border (w, x1, y0, y1);
+      FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
     }
   else if (!WINDOW_LEFTMOST_P (w)
           && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
@@ -23384,9 +23473,9 @@ x_draw_vertical_border (w)
       y1 -= 1;
 
       if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
-       x0 -= 1;
+        x0 -= 1;
 
-      rif->draw_vertical_window_border (w, x0, y0, y1);
+      FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
     }
 }
 
@@ -23972,7 +24061,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;
@@ -24018,7 +24107,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"),
@@ -24029,7 +24118,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.
@@ -24069,12 +24158,13 @@ Autoselection selects the minibuffer only if it is active, and never
 unselects the minibuffer if it is active.  */);
   Vmouse_autoselect_window = Qnil;
 
-  DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
+  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.  */);