diff src/xdisp.c @ 91041:bdb3fe0ba9fa

Merge from emacs--devo--0 Patches applied: * emacs--devo--0 (patch 866-879) - Merge multi-tty branch - Update from CVS - Merge from emacs--rel--22 Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-257
author Miles Bader <miles@gnu.org>
date Thu, 11 Oct 2007 16:22:07 +0000
parents cb5edf67e2f2 5039706521c9
children 3807f7a342ae
line wrap: on
line diff
--- a/src/xdisp.c	Thu Oct 11 16:14:00 2007 +0000
+++ b/src/xdisp.c	Thu Oct 11 16:22:07 2007 +0000
@@ -587,21 +587,12 @@
 
 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];
 
@@ -822,10 +813,6 @@
 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;
@@ -2525,7 +2512,7 @@
   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))
@@ -2542,9 +2529,9 @@
 
   /* 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);
@@ -3639,7 +3626,8 @@
     }
   else
     {
-      int invis_p, newpos, next_stop, start_charpos;
+      int invis_p;
+      EMACS_INT newpos, next_stop, start_charpos;
       Lisp_Object pos, prop, overlay;
 
       /* First of all, is there invisible text at this position?  */
@@ -3969,7 +3957,7 @@
       && 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));
@@ -4035,7 +4023,7 @@
       && 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));
@@ -4051,7 +4039,7 @@
     {
       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))
@@ -4077,7 +4065,7 @@
       && 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
@@ -4118,7 +4106,7 @@
       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;
@@ -4167,7 +4155,7 @@
 	  it->left_user_fringe_face_id = face_id;
 	}
       else
-	{
+        {
 	  it->right_user_fringe_bitmap = fringe_bitmap;
 	  it->right_user_fringe_face_id = face_id;
 	}
@@ -4212,9 +4200,9 @@
 
   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)
     {
@@ -4284,7 +4272,7 @@
 }
 
 
-/* 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
@@ -7695,8 +7683,8 @@
       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);
     }
 }
 
@@ -7799,8 +7787,8 @@
       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);
     }
 }
 
@@ -8038,6 +8026,10 @@
    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
@@ -8062,6 +8054,17 @@
     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.  */
@@ -8699,7 +8702,7 @@
     = ((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;
@@ -8729,7 +8732,6 @@
 
   /* Insert new message at BEG.  */
   TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
-  Ferase_buffer ();
 
   if (STRINGP (string))
     {
@@ -8826,11 +8828,11 @@
     {
       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)
@@ -8844,7 +8846,7 @@
 	      f->resized_p = 0;
 	    }
 	}
-
+      
       frame_garbaged = 0;
       if (changed_count)
 	++windows_or_buffers_changed;
@@ -8877,11 +8879,10 @@
 /* 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
@@ -8932,7 +8933,7 @@
 		 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);
@@ -8947,8 +8948,10 @@
   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
@@ -9502,8 +9505,8 @@
     {
       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;
     }
 }
@@ -10955,6 +10958,8 @@
   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))
@@ -11011,6 +11016,7 @@
   int count, count1;
   struct frame *sf;
   int polling_stopped_here = 0;
+  Lisp_Object old_frame = selected_frame;
 
   /* Non-zero means redisplay has to consider all windows on all
      frames.  Zero means, only selected_window is considered.  */
@@ -11072,6 +11078,14 @@
   }
 
  retry:
+  if (!EQ (old_frame, selected_frame)
+      && FRAME_LIVE_P (XFRAME (old_frame)))
+    /* When running redisplay, we play a bit fast-and-loose and allow e.g.
+       selected_frame and selected_window to be temporarily out-of-sync so
+       when we come back here via `goto retry', we need to resync because we
+       may need to run Elisp code (via prepare_menu_bars).  */
+    select_frame_for_redisplay (old_frame);
+
   pause = 0;
   reconsider_clip_changes (w, current_buffer);
   last_escape_glyph_frame = NULL;
@@ -11092,17 +11106,16 @@
   if (face_change_count)
     ++windows_or_buffers_changed;
 
-  if (! FRAME_WINDOW_P (sf)
-      && previous_terminal_frame != sf)
-    {
-      /* Since frames on an ASCII terminal share the same display
-	 area, displaying a different frame means redisplay the whole
-	 thing.  */
+  if (FRAME_TERMCAP_P (sf)
+      && FRAME_TTY (sf)->previous_frame != sf)
+    {
+      /* 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);
-    }
-  previous_terminal_frame = sf;
+      FRAME_TTY (sf)->previous_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
@@ -11124,6 +11137,7 @@
       }
   }
 
+  
   /* Notice any pending interrupt request to change frame size.  */
   do_pending_window_change (1);
 
@@ -11485,7 +11499,7 @@
 	{
 	  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
@@ -11494,16 +11508,16 @@
 
 	      /* 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
@@ -11550,12 +11564,12 @@
 	  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);
+                }
 	    }
 	}
     }
@@ -11640,8 +11654,8 @@
 	  /* 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;
@@ -11751,8 +11765,9 @@
   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);
 }
 
 
@@ -11760,7 +11775,8 @@
    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)
@@ -11771,7 +11787,8 @@
   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;
 }
@@ -12909,7 +12926,9 @@
     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);
 }
 
 
@@ -13628,20 +13647,22 @@
         display_menu_bar (w);
 
 #ifdef HAVE_WINDOW_SYSTEM
+      if (FRAME_WINDOW_P (f))
+        {
 #if defined (USE_GTK) || USE_MAC_TOOLBAR
-      redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
+          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
-            || !NILP (Vauto_resize_tool_bars));
-
-#endif
-
-      if (redisplay_tool_bar_p && redisplay_tool_bar (f))
-	{
-	  extern int ignore_mouse_drag_p;
-	  ignore_mouse_drag_p = 1;
-	}
+          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))
+	    {
+	      extern int ignore_mouse_drag_p;
+	      ignore_mouse_drag_p = 1;
+	    }
+        }
 #endif
     }
 
@@ -13675,7 +13696,8 @@
 
       /* 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.  */
@@ -13944,10 +13966,10 @@
 	  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);
 	    }
 
@@ -14116,10 +14138,10 @@
       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);
 	}
 
@@ -14569,7 +14591,7 @@
 
   /* 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);
 
@@ -14978,10 +15000,10 @@
 
       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
 	{
@@ -14999,36 +15021,36 @@
 	    {
 	      /* 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);
-	    }
-
-	  set_terminal_window (0);
+	      if (!FRAME_SCROLL_REGION_OK (f))
+		ins_del_lines (f, end + dvpos, -dvpos);
+	    }
+
+	  set_terminal_window (f, 0);
 	}
 
       update_end (f);
@@ -16602,7 +16624,7 @@
 
   /* 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)
@@ -16833,10 +16855,10 @@
   /* 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);
 
@@ -17551,9 +17573,9 @@
 	= (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)
     {
@@ -18704,6 +18726,8 @@
   if (NILP (prop))
     return OK_PIXELS (0);
 
+  xassert (FRAME_LIVE_P (it->f));
+
   if (SYMBOLP (prop))
     {
       if (SCHARS (SYMBOL_NAME (prop)) == 2)
@@ -18820,7 +18844,8 @@
       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);
@@ -19070,7 +19095,7 @@
       else
 	STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
        /* Maybe encode the character in *CHAR2B.  */
-      rif->encode_char (c, char2b, font_info, charset, NULL);
+      FRAME_RIF (f)->encode_char (c, char2b, font_info, charset, NULL);
     }
 
   /* Make sure X resources of the face are allocated.  */
@@ -19151,8 +19176,8 @@
 	  if (CHARSET_ID (charset) != charset_ascii)
 	    {
 	      glyph->font_type
-		= rif->encode_char (glyph->u.ch, char2b, font_info, charset,
-				    two_byte_p);
+		= FRAME_RIF (f)->encode_char (glyph->u.ch, char2b, font_info,
+					      charset, two_byte_p);
 	    }
 	}
     }
@@ -19407,7 +19432,8 @@
 }
 
 static XCharStruct *
-get_per_char_metric (font, font_info, char2b, font_type)
+get_per_char_metric (f, font, font_info, char2b, font_type)
+     struct frame *f;
      XFontStruct *font;
      struct font_info *font_info;
      XChar2b *char2b;
@@ -19433,7 +19459,7 @@
       return &pcm_value;
     }
 #endif	/* USE_FONT_BACKEND */
-  return rif->per_char_metric (font, char2b, font_type);
+  return FRAME_RIF (f)->per_char_metric (font, char2b, font_type);
 }
 
 /* EXPORT for RIF:
@@ -19461,7 +19487,7 @@
       font = face->font;
       font_info = FONT_INFO_FROM_FACE (f, face);
       if (font  /* ++KFS: Should this be font_info ?  */
-	  && (pcm = get_per_char_metric (font, font_info, &char2b, glyph->font_type)))
+	  && (pcm = get_per_char_metric (f, font, font_info, &char2b, glyph->font_type)))
 	{
 	  if (pcm->rbearing > pcm->width)
 	    *right = pcm->rbearing - pcm->width;
@@ -19589,6 +19615,70 @@
 }
 
 
+/* Get face and two-byte form of character C in face FACE_ID on frame
+   F.  The encoding of C is returned in *CHAR2B.  MULTIBYTE_P non-zero
+   means we want to display multibyte text.  DISPLAY_P non-zero means
+   make sure that X resources for the face returned are allocated.
+   Value is a pointer to a realized face that is ready for display if
+   DISPLAY_P is non-zero.  */
+
+static INLINE struct face *
+get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
+     struct frame *f;
+     int c, face_id;
+     XChar2b *char2b;
+     int multibyte_p, display_p;
+{
+  struct face *face = FACE_FROM_ID (f, face_id);
+
+  if (!multibyte_p)
+    {
+      /* Unibyte case.  We don't have to encode, but we have to make
+	 sure to use a face suitable for unibyte.  */
+      STORE_XCHAR2B (char2b, 0, c);
+      face_id = FACE_FOR_CHAR (f, face, c);
+      face = FACE_FROM_ID (f, face_id);
+    }
+  else if (c < 128)
+    {
+      /* Case of ASCII in a face known to fit ASCII.  */
+      STORE_XCHAR2B (char2b, 0, c);
+    }
+  else
+    {
+      int c1, c2, charset;
+
+      /* Split characters into bytes.  If c2 is -1 afterwards, C is
+	 really a one-byte character so that byte1 is zero.  */
+      SPLIT_CHAR (c, charset, c1, c2);
+      if (c2 > 0)
+	STORE_XCHAR2B (char2b, c1, c2);
+      else
+	STORE_XCHAR2B (char2b, 0, c1);
+
+      /* Maybe encode the character in *CHAR2B.  */
+      if (face->font != NULL)
+	{
+	  struct font_info *font_info
+	    = FONT_INFO_FROM_ID (f, face->font_info_id);
+	  if (font_info)
+	    FRAME_RIF (f)->encode_char (c, char2b, font_info, 0);
+	}
+    }
+
+  /* Make sure X resources of the face are allocated.  */
+#ifdef HAVE_X_WINDOWS
+  if (display_p)
+#endif
+    {
+      xassert (face != NULL);
+      PREPARE_FACE_FOR_DISPLAY (f, face);
+    }
+
+  return face;
+}
+
+
 /* Set background width of glyph string S.  START is the index of the
    first glyph following S.  LAST_X is the right-most x-position + 1
    in the drawing area.  */
@@ -19635,8 +19725,8 @@
     {
       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;
@@ -19646,8 +19736,8 @@
     {
       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;
@@ -19923,9 +20013,9 @@
       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
@@ -20004,7 +20094,7 @@
 
   /* 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
@@ -20693,20 +20783,20 @@
 
 	  it->nglyphs = 1;
 
-	  pcm = get_per_char_metric (font, font_info, &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 = get_per_char_metric (it->f, font, font_info, &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)
 	    {
@@ -20924,8 +21014,8 @@
 	     multiplying the width of font by the width of the
 	     character.  */
 
-	  pcm = get_per_char_metric (font, font_info, &char2b,
-				      FONT_TYPE_FOR_MULTIBYTE (font, it->c));
+	    pcm = get_per_char_metric (it->f, font, font_info, &char2b,
+				       FONT_TYPE_FOR_MULTIBYTE (font, it->c));
 
 	  if (font_not_found_p || !pcm)
 	    {
@@ -21073,7 +21163,7 @@
 	    {
 	      get_char_face_and_encoding (it->f, c, it->face_id,
 					  &char2b, it->multibyte_p, 0);
-	      pcm = get_per_char_metric (font, font_info, &char2b,
+	      pcm = get_per_char_metric (it->f, font, font_info, &char2b,
 					 FONT_TYPE_FOR_MULTIBYTE (font, c));
 	    }
 
@@ -21140,7 +21230,7 @@
 		    this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
 		  get_char_face_and_encoding (it->f, ch, face_id,
 					      &char2b, it->multibyte_p, 0);
-		  pcm = get_per_char_metric (font, font_info, &char2b,
+		  pcm = get_per_char_metric (it->f, font, font_info, &char2b,
 					     FONT_TYPE_FOR_MULTIBYTE (font,
 								      ch));
 		}
@@ -21417,8 +21507,8 @@
   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];
@@ -21500,8 +21590,8 @@
   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;
     }
 }
@@ -21644,7 +21734,7 @@
       non_selected = 1;
     }
 
-  /* Nonselected window or nonselected frame.  */
+  /* Detect a nonselected window or nonselected frame.  */
   else if (w != XWINDOW (f->selected_window)
 #ifdef HAVE_WINDOW_SYSTEM
 	   || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
@@ -21663,13 +21753,6 @@
   if (NILP (b->cursor_type))
     return NO_CURSOR;
 
-  /* Use cursor-in-non-selected-windows for non-selected window or frame.  */
-  if (non_selected)
-    {
-      alt_cursor = b->cursor_in_non_selected_windows;
-      return get_specified_cursor_type (alt_cursor, width);
-    }
-
   /* Get the normal cursor type for this window.  */
   if (EQ (b->cursor_type, Qt))
     {
@@ -21679,6 +21762,21 @@
   else
     cursor_type = get_specified_cursor_type (b->cursor_type, width);
 
+  /* Use cursor-in-non-selected-windows instead
+     for non-selected window or frame.  */
+  if (non_selected)
+    {
+      alt_cursor = b->cursor_in_non_selected_windows;
+      if (!EQ (Qt, alt_cursor))
+	return get_specified_cursor_type (alt_cursor, width);
+      /* t means modify the normal cursor type.  */
+      if (cursor_type == FILLED_BOX_CURSOR)
+	cursor_type = HOLLOW_BOX_CURSOR;
+      else if (cursor_type == BAR_CURSOR && *width > 1)
+	--*width;
+      return cursor_type;
+    }
+
   /* Use normal cursor if not blinked off.  */
   if (!w->cursor_off_p)
     {
@@ -22014,7 +22112,7 @@
       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.  */
@@ -22111,9 +22209,9 @@
       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);
 }
 
 
@@ -22262,11 +22360,11 @@
 
   /* Change the mouse cursor.  */
   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);
+    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);
-  else
-    rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
+    FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
+  else
+    FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
 }
 
 /* EXPORT:
@@ -22705,7 +22803,6 @@
 	  return inside;
 	}
     }
-  /* If we don't understand the format, pretend we're not in the hot-spot.  */
   return 0;
 }
 
@@ -22785,7 +22882,7 @@
     }
 
   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
@@ -23756,8 +23853,8 @@
 	 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;
 }
 
 
@@ -23769,6 +23866,8 @@
 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 */
@@ -23789,9 +23888,9 @@
       y1 -= 1;
 
       if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
-	x1 -= 1;
-
-      rif->draw_vertical_window_border (w, x1, y0, y1);
+        x1 -= 1;
+
+      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))
@@ -23802,9 +23901,9 @@
       y1 -= 1;
 
       if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
-	x0 -= 1;
-
-      rif->draw_vertical_window_border (w, x0, y0, y1);
+        x0 -= 1;
+
+      FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
     }
 }
 
@@ -24500,7 +24599,10 @@
 mouse pointer enters it.
 
 Autoselection selects the minibuffer only if it is active, and never
-unselects the minibuffer if it is active.  */);
+unselects the minibuffer if it is active.
+
+When customizing this variable make sure that the actual value of
+`focus-follows-mouse' matches the behavior of your window manager.  */);
   Vmouse_autoselect_window = Qnil;
 
   DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,