Reimplement terminal parameters in C; clean up term.c, create terminal.c.
[bpt/emacs.git] / src / frame.c
index 40be721..c314062 100644 (file)
@@ -1,6 +1,6 @@
 /* Generic frame functions.
-   Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2003, 2004, 2005
-   Free Software Foundation.
+   Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003,
+                 2004, 2005 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -16,8 +16,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #include <config.h>
 
@@ -76,7 +76,7 @@ Lisp_Object Qinhibit_default_face_x_resources;
 
 Lisp_Object Qx_frame_parameter;
 Lisp_Object Qx_resource_name;
-Lisp_Object Qdisplay_id;
+Lisp_Object Qdevice;
 Lisp_Object Qdisplay_live_p;
 
 /* Frame parameters (set or reported).  */
@@ -107,7 +107,7 @@ Lisp_Object Qtitle, Qname;
 Lisp_Object Qunsplittable;
 Lisp_Object Qmenu_bar_lines, Qtool_bar_lines;
 Lisp_Object Qleft_fringe, Qright_fringe;
-Lisp_Object Qbuffer_predicate, Qbuffer_list;
+Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list;
 Lisp_Object Qtty_color_mode;
 Lisp_Object Qtty, Qtty_type;
 Lisp_Object Qwindow_system;
@@ -303,9 +303,7 @@ make_frame (mini_p)
   f->menu_bar_items_used = 0;
   f->buffer_predicate = Qnil;
   f->buffer_list = Qnil;
-#ifdef MULTI_KBOARD
-  f->kboard = initial_kboard;
-#endif
+  f->buried_buffer_list = Qnil;
   f->namebuf = 0;
   f->title = Qnil;
   f->menu_bar_window = Qnil;
@@ -425,8 +423,8 @@ make_frame_without_minibuffer (mini_window, kb, display)
 
 #ifdef MULTI_KBOARD
   if (!NILP (mini_window)
-      && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
-    error ("frame and minibuffer must be on the same display");
+      && XFRAME (XWINDOW (mini_window)->frame)->device->kboard != kb)
+    error ("Frame and minibuffer must be on the same display");
 #endif
 
   /* Make a frame containing just a root window.  */
@@ -510,7 +508,7 @@ struct frame *
 make_initial_frame (void)
 {
   struct frame *f;
-  struct display *display;
+  struct device *device;
   Lisp_Object frame;
 
 #ifdef MULTI_KBOARD
@@ -528,7 +526,7 @@ make_initial_frame (void)
   if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
     Vframe_list = Qnil;
 
-  display = init_initial_display ();
+  device = init_initial_device ();
 
   f = make_frame (1);
   XSETFRAME (frame, f);
@@ -541,9 +539,9 @@ make_initial_frame (void)
   f->visible = 1;
   f->async_visible = 1;
 
-  f->output_method = display->type;
-  f->display = display;
-  f->display->reference_count++;
+  f->output_method = device->type;
+  f->device = device;
+  f->device->reference_count++;
   f->output_data.nothing = 0;
   
   FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
@@ -552,16 +550,12 @@ make_initial_frame (void)
   FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
   FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
 
-#ifdef MULTI_KBOARD
-  f->kboard = initial_kboard;
-#endif
-
   return f;
 }
 
 
 struct frame *
-make_terminal_frame (struct display *display)
+make_terminal_frame (struct device *device)
 {
   register struct frame *f;
   Lisp_Object frame;
@@ -612,8 +606,8 @@ make_terminal_frame (struct display *display)
 #else
   {
     f->output_method = output_termcap;
-    f->display = display;
-    f->display->reference_count++;
+    f->device = device;
+    f->device->reference_count++;
     create_tty_output (f);
     
     FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
@@ -622,10 +616,6 @@ make_terminal_frame (struct display *display)
     FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
     FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
 
-#ifdef MULTI_KBOARD
-    f->kboard = FRAME_TTY (f)->kboard;
-#endif
-
     /* Set the top frame to the newly created frame. */
     if (FRAME_TTY (f)->top_frame
         && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame)))
@@ -648,6 +638,33 @@ make_terminal_frame (struct display *display)
   return f;
 }
 
+/* Get a suitable value for frame parameter PARAMETER for a newly
+   created frame, based on (1) the user-supplied frame parameter
+   alist SUPPLIED_PARMS, (2) CURRENT_VALUE, and finally, if all else
+   fails, (3) Vdefault_frame_alist.  */
+
+static Lisp_Object
+get_future_frame_param (Lisp_Object parameter,
+                        Lisp_Object supplied_parms,
+                        char *current_value)
+{
+  Lisp_Object result;
+
+  result = Fassq (parameter, supplied_parms);
+  if (NILP (result))
+    result = Fassq (parameter, XFRAME (selected_frame)->param_alist);
+  if (NILP (result) && current_value != NULL)
+    result = build_string (current_value);
+  if (NILP (result))
+    result = Fassq (parameter, Vdefault_frame_alist);
+  if (!NILP (result) && !STRINGP (result))
+    result = XCDR (result);
+  if (NILP (result) || !STRINGP (result))
+    result = Qnil;
+
+  return result;
+}
+
 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
        1, 1, 0,
        doc: /* Create an additional terminal frame, possibly on another terminal.
@@ -669,7 +686,7 @@ affects all frames on the same terminal device.  */)
      Lisp_Object parms;
 {
   struct frame *f;
-  struct display *d = NULL;
+  struct device *d = NULL;
   Lisp_Object frame, tem;
   struct frame *sf = SELECTED_FRAME ();
 
@@ -693,63 +710,43 @@ affects all frames on the same terminal device.  */)
   {
     Lisp_Object display_device;
 
-    display_device = Fassq (Qdisplay_id, parms);
+    display_device = Fassq (Qdevice, parms);
     if (!NILP (display_device))
       {
         display_device = XCDR (display_device);
         CHECK_NUMBER (display_device);
-        d = get_display (XINT (display_device));
-        if (!d)
-          wrong_type_argument (Qdisplay_live_p, display_device);
+        d = get_device (XINT (display_device), 1);
       }
   }
   
   if (!d)
     { 
-      Lisp_Object tty, tty_type;
       char *name = 0, *type = 0;
+      Lisp_Object tty, tty_type;
 
-      tty = Fassq (Qtty, parms);
-      if (EQ (tty, Qnil))
-        tty = Fassq (Qtty, XFRAME (selected_frame)->param_alist);
-      if (EQ (tty, Qnil) && FRAME_TERMCAP_P (XFRAME (selected_frame))
-          && FRAME_TTY (XFRAME (selected_frame))->name)
-        tty = build_string (FRAME_TTY (XFRAME (selected_frame))->name);
-      if (EQ (tty, Qnil))
-        tty = Fassq (Qtty, Vdefault_frame_alist);
-      if (! EQ (tty, Qnil) && ! STRINGP (tty))
-        tty = XCDR (tty);
-      if (EQ (tty, Qnil) || !STRINGP (tty))
-        tty = Qnil;
-
-      tty_type = Fassq (Qtty_type, parms);
-      if (EQ (tty_type, Qnil))
-        tty_type = Fassq (Qtty, XFRAME (selected_frame)->param_alist);
-      if (EQ (tty_type, Qnil) && FRAME_TERMCAP_P (XFRAME (selected_frame))
-          && FRAME_TTY (XFRAME (selected_frame))->type)
-        tty_type = build_string (FRAME_TTY (XFRAME (selected_frame))->type);
-      if (EQ (tty_type, Qnil))
-        tty_type = Fassq (Qtty_type, Vdefault_frame_alist);
-      if (! EQ (tty_type, Qnil) && ! STRINGP (tty_type))
-        tty_type = XCDR (tty_type);
-      if (EQ (tty_type, Qnil) || !STRINGP (tty_type))
-        tty_type = Qnil;
-
-      if (! EQ (tty, Qnil))
+      tty = get_future_frame_param
+        (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
+                       ? FRAME_TTY (XFRAME (selected_frame))->name
+                       : NULL));
+      if (!NILP (tty))
         {
           name = (char *) alloca (SBYTES (tty) + 1);
           strncpy (name, SDATA (tty), SBYTES (tty));
           name[SBYTES (tty)] = 0;
         }
       
-      if (! EQ (tty_type, Qnil))
+      tty_type = get_future_frame_param
+        (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
+                            ? FRAME_TTY (XFRAME (selected_frame))->type
+                            : NULL));
+      if (!NILP (tty_type))
         {
           type = (char *) alloca (SBYTES (tty_type) + 1);
           strncpy (type, SDATA (tty_type), SBYTES (tty_type));
           type[SBYTES (tty_type)] = 0;
         }
 
-      d = term_init (name, type, 0); /* Errors are not fatal. */
+      d = init_tty (name, type, 0); /* Errors are not fatal. */
     }
 
   f = make_terminal_frame (d);
@@ -766,7 +763,13 @@ affects all frames on the same terminal device.  */)
   Fmodify_frame_parameters (frame, Vdefault_frame_alist);
   Fmodify_frame_parameters (frame, parms);
   Fmodify_frame_parameters (frame, Fcons (Fcons (Qwindow_system, Qnil), Qnil));
-
+  Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty_type,
+                                                 build_string (d->display_info.tty->type)),
+                                          Qnil));
+  Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty,
+                                                 build_string (d->display_info.tty->name)),
+                                          Qnil));
+  
   /* Make the frame face alist be frame-specific, so that each
      frame could change its face definitions independently.  */
   f->face_alist = Fcopy_alist (sf->face_alist);
@@ -907,7 +910,7 @@ do_switch_frame (frame, track, for_deletion)
   return frame;
 }
 
-DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
+DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 1, "e",
        doc: /* Select the frame FRAME.
 Subsequent editing commands apply to its selected window.
 The selection of FRAME lasts until the next time the user does
@@ -918,14 +921,14 @@ the command loop, because it still may have the window system's input
 focus.  On a text-only terminal, the next redisplay will display FRAME.
 
 This function returns FRAME, or nil if FRAME has been deleted.  */)
-  (frame, no_enter)
-    Lisp_Object frame, no_enter;
+  (frame)
+    Lisp_Object frame;
 {
   return do_switch_frame (frame, 1, 0);
 }
 
 
-DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
+DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e",
        doc: /* Handle a switch-frame event EVENT.
 Switch-frame events are usually bound to this function.
 A switch-frame event tells Emacs that the window manager has requested
@@ -934,8 +937,8 @@ This function selects the selected window of the frame of EVENT.
 
 If EVENT is frame object, handle it as if it were a switch-frame event
 to that frame.  */)
-     (event, no_enter)
-     Lisp_Object event, no_enter;
+     (event)
+     Lisp_Object event;
 {
   /* Preserve prefix arg that the command loop just cleared.  */
   current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
@@ -1066,14 +1069,14 @@ The display device is represented by its integer identifier.  */)
   (frame)
      Lisp_Object frame;
 {
-  struct display *d;
+  struct device *d;
 
   if (NILP (frame))
     frame = selected_frame;
 
   CHECK_LIVE_FRAME (frame);
 
-  d = get_display (frame);
+  d = get_device (frame, 0);
 
   if (!d)
     return Qnil;
@@ -1104,7 +1107,7 @@ DEFUN ("frame-list", Fframe_list, Sframe_list,
    If MINIBUF is 0, include all visible and iconified frames.
    Otherwise, include all frames.  */
 
-Lisp_Object
+static Lisp_Object
 next_frame (frame, minibuf)
      Lisp_Object frame;
      Lisp_Object minibuf;
@@ -1184,7 +1187,7 @@ next_frame (frame, minibuf)
    If MINIBUF is 0, include all visible and iconified frames.
    Otherwise, include all frames.  */
 
-Lisp_Object
+static Lisp_Object
 prev_frame (frame, minibuf)
      Lisp_Object frame;
      Lisp_Object minibuf;
@@ -1360,6 +1363,8 @@ The functions are run with one arg, the frame to be deleted.  */)
 {
   struct frame *f;
   struct frame *sf = SELECTED_FRAME ();
+  struct kboard *kb;
+
   int minibuffer_selected;
 
   if (EQ (frame, Qnil))
@@ -1473,6 +1478,10 @@ The functions are run with one arg, the frame to be deleted.  */)
   if (FRAME_X_P (f))
     x_clear_frame_selections (f);
 #endif
+#ifdef MAC_OS
+  if (FRAME_MAC_P (f))
+    x_clear_frame_selections (f);
+#endif
 
   /* Free glyphs.
      This function must be called before the window tree of the
@@ -1509,25 +1518,27 @@ The functions are run with one arg, the frame to be deleted.  */)
      promise that the display of the frame must be valid until we have
      called the window-system-dependent frame destruction routine.  */
 
-  if (FRAME_DISPLAY (f)->delete_frame_hook)
-    (*FRAME_DISPLAY (f)->delete_frame_hook) (f);
-  
-  {
-    struct display *display = FRAME_DISPLAY (f);
+  if (FRAME_DEVICE (f)->delete_frame_hook)
+    (*FRAME_DEVICE (f)->delete_frame_hook) (f);
 
+  {
+    struct device *device = FRAME_DEVICE (f);
     f->output_data.nothing = 0; 
-    f->display = 0;             /* Now the frame is dead. */
+    f->device = 0;             /* Now the frame is dead. */
 
     /* If needed, delete the device that this frame was on.
-       (This must be done after the frame is killed.) */  
-    display->reference_count--;
-    if (display->reference_count == 0)
-    {
-      if (display->delete_display_hook)
-        (*display->delete_display_hook) (display);
-      else
-        delete_display (display);
-    }
+       (This must be done after the frame is killed.) */
+    device->reference_count--;
+    if (device->reference_count == 0)
+      {
+        kb = NULL;
+        if (device->delete_device_hook)
+          (*device->delete_device_hook) (device);
+        else
+          delete_device (device);
+      }
+    else
+      kb = device->kboard;
   }
 
   /* If we've deleted the last_nonminibuf_frame, then try to find
@@ -1553,38 +1564,39 @@ The functions are run with one arg, the frame to be deleted.  */)
 
   /* If there's no other frame on the same kboard, get out of
      single-kboard state if we're in it for this kboard.  */
-  {
-    Lisp_Object frames;
-    /* Some frame we found on the same kboard, or nil if there are none.  */
-    Lisp_Object frame_on_same_kboard;
+  if (kb != NULL)
+    {
+      Lisp_Object frames;
+      /* Some frame we found on the same kboard, or nil if there are none.  */
+      Lisp_Object frame_on_same_kboard;
 
-    frame_on_same_kboard = Qnil;
+      frame_on_same_kboard = Qnil;
 
-    for (frames = Vframe_list;
-        CONSP (frames);
-        frames = XCDR (frames))
-      {
-       Lisp_Object this;
-       struct frame *f1;
+      for (frames = Vframe_list;
+          CONSP (frames);
+          frames = XCDR (frames))
+       {
+         Lisp_Object this;
+         struct frame *f1;
 
-       this = XCAR (frames);
-       if (!FRAMEP (this))
-         abort ();
-       f1 = XFRAME (this);
+         this = XCAR (frames);
+         if (!FRAMEP (this))
+           abort ();
+         f1 = XFRAME (this);
 
-       if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
-         frame_on_same_kboard = this;
-      }
+         if (kb == FRAME_KBOARD (f1))
+           frame_on_same_kboard = this;
+       }
 
-    if (NILP (frame_on_same_kboard))
-      not_single_kboard_state (FRAME_KBOARD (f));
-  }
+      if (NILP (frame_on_same_kboard))
+       not_single_kboard_state (kb);
+    }
 
 
   /* If we've deleted this keyboard's default_minibuffer_frame, try to
      find another one.  Prefer minibuffer-only frames, but also notice
      frames with other windows.  */
-  if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
+  if (kb != NULL && EQ (frame, kb->Vdefault_minibuffer_frame))
     {
       Lisp_Object frames;
 
@@ -1610,7 +1622,7 @@ The functions are run with one arg, the frame to be deleted.  */)
 
          /* Consider only frames on the same kboard
             and only those with minibuffers.  */
-         if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
+         if (kb == FRAME_KBOARD (f1)
              && FRAME_HAS_MINIBUF_P (f1))
            {
              frame_with_minibuf = this;
@@ -1618,7 +1630,7 @@ The functions are run with one arg, the frame to be deleted.  */)
                break;
            }
 
-         if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
+         if (kb == FRAME_KBOARD (f1))
            frame_on_same_kboard = this;
        }
 
@@ -1633,11 +1645,11 @@ The functions are run with one arg, the frame to be deleted.  */)
          if (NILP (frame_with_minibuf))
            abort ();
 
-         FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
+         kb->Vdefault_minibuffer_frame = frame_with_minibuf;
        }
       else
        /* No frames left on this kboard--say no minibuffer either.  */
-       FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
+       kb->Vdefault_minibuffer_frame = Qnil;
     }
 
   /* Cause frame titles to update--necessary if we now have just one frame.  */
@@ -1673,8 +1685,8 @@ and returns whatever that function returns.  */)
 
 #ifdef HAVE_MOUSE
   /* It's okay for the hook to refrain from storing anything.  */
-  if (FRAME_DISPLAY (f)->mouse_position_hook)
-    (*FRAME_DISPLAY (f)->mouse_position_hook) (&f, -1,
+  if (FRAME_DEVICE (f)->mouse_position_hook)
+    (*FRAME_DEVICE (f)->mouse_position_hook) (&f, -1,
                                               &lispy_dummy, &party_dummy,
                                               &x, &y,
                                               &long_dummy);
@@ -1716,8 +1728,8 @@ and nil for X and Y.  */)
 
 #ifdef HAVE_MOUSE
   /* It's okay for the hook to refrain from storing anything.  */
-  if (FRAME_DISPLAY (f)->mouse_position_hook)
-    (*FRAME_DISPLAY (f)->mouse_position_hook) (&f, -1,
+  if (FRAME_DEVICE (f)->mouse_position_hook)
+    (*FRAME_DEVICE (f)->mouse_position_hook) (&f, -1,
                                               &lispy_dummy, &party_dummy,
                                               &x, &y,
                                               &long_dummy);
@@ -1752,7 +1764,7 @@ before calling this function on it, like this.
 #if defined (MSDOS) && defined (HAVE_MOUSE)
   if (FRAME_MSDOS_P (XFRAME (frame)))
     {
-      Fselect_frame (frame, Qnil);
+      Fselect_frame (frame);
       mouse_moveto (XINT (x), XINT (y));
     }
 #endif
@@ -1784,7 +1796,7 @@ before calling this function on it, like this.
 #if defined (MSDOS) && defined (HAVE_MOUSE)
   if (FRAME_MSDOS_P (XFRAME (frame)))
     {
-      Fselect_frame (frame, Qnil);
+      Fselect_frame (frame);
       mouse_moveto (XINT (x), XINT (y));
     }
 #endif
@@ -1906,7 +1918,7 @@ If omitted, FRAME defaults to the currently selected frame.  */)
 #if 0 /* This isn't logically necessary, and it can do GC.  */
   /* Don't let the frame remain selected.  */
   if (EQ (frame, selected_frame))
-    Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
+    Fhandle_switch_frame (next_frame (frame, Qt));
 #endif
 
   /* Don't allow minibuf_window to remain on a deleted frame.  */
@@ -1997,8 +2009,8 @@ doesn't support multiple overlapping frames, this function does nothing.  */)
   /* Do like the documentation says. */
   Fmake_frame_visible (frame);
 
-  if (FRAME_DISPLAY (f)->frame_raise_lower_hook)
-    (*FRAME_DISPLAY (f)->frame_raise_lower_hook) (f, 1);
+  if (FRAME_DEVICE (f)->frame_raise_lower_hook)
+    (*FRAME_DEVICE (f)->frame_raise_lower_hook) (f, 1);
 
   return Qnil;
 }
@@ -2021,8 +2033,8 @@ doesn't support multiple overlapping frames, this function does nothing.  */)
 
   f = XFRAME (frame);
   
-  if (FRAME_DISPLAY (f)->frame_raise_lower_hook)
-    (*FRAME_DISPLAY (f)->frame_raise_lower_hook) (f, 0);
+  if (FRAME_DEVICE (f)->frame_raise_lower_hook)
+    (*FRAME_DEVICE (f)->frame_raise_lower_hook) (f, 0);
 
   return Qnil;
 }
@@ -2042,7 +2054,7 @@ Focus redirection is useful for temporarily redirecting keystrokes to
 a surrogate minibuffer frame when a frame doesn't have its own
 minibuffer window.
 
-A frame's focus redirection can be changed by select-frame.  If frame
+A frame's focus redirection can be changed by `select-frame'.  If frame
 FOO is selected, and then a different frame BAR is selected, any
 frames redirecting their focus to FOO are shifted to redirect their
 focus to BAR.  This allows focus redirection to work properly when the
@@ -2050,7 +2062,7 @@ user switches from one frame to another using `select-window'.
 
 This means that a frame whose focus is redirected to itself is treated
 differently from a frame whose focus is redirected to nil; the former
-is affected by select-frame, while the latter is not.
+is affected by `select-frame', while the latter is not.
 
 The redirection lasts until `redirect-frame-focus' is called to change it.  */)
      (frame, focus_frame)
@@ -2070,8 +2082,8 @@ The redirection lasts until `redirect-frame-focus' is called to change it.  */)
   
   f->focus_frame = focus_frame;
 
-  if (FRAME_DISPLAY (f)->frame_rehighlight_hook)
-    (*FRAME_DISPLAY (f)->frame_rehighlight_hook) (f);
+  if (FRAME_DEVICE (f)->frame_rehighlight_hook)
+    (*FRAME_DEVICE (f)->frame_rehighlight_hook) (f);
 
   return Qnil;
 }
@@ -2133,7 +2145,7 @@ set_frame_buffer_list (frame, list)
   XFRAME (frame)->buffer_list = list;
 }
 
-/* Discard BUFFER from the buffer-list of each frame.  */
+/* Discard BUFFER from the buffer-list and buried-buffer-list of each frame.  */
 
 void
 frames_discard_buffer (buffer)
@@ -2145,6 +2157,8 @@ frames_discard_buffer (buffer)
     {
       XFRAME (frame)->buffer_list
        = Fdelq (buffer, XFRAME (frame)->buffer_list);
+      XFRAME (frame)->buried_buffer_list
+        = Fdelq (buffer, XFRAME (frame)->buried_buffer_list);
     }
 }
 
@@ -2185,7 +2199,7 @@ frame_name_fnn_p (str, len)
 /* Set the name of the terminal frame.  Also used by MSDOS frames.
    Modeled after x_set_name which is used for WINDOW frames.  */
 
-void
+static void
 set_term_frame_name (f, name)
      struct frame *f;
      Lisp_Object name;
@@ -2232,13 +2246,18 @@ store_frame_param (f, prop, val)
 {
   register Lisp_Object old_alist_elt;
 
-  /* The buffer-alist parameter is stored in a special place and is
-     not in the alist.  */
+  /* The buffer-list parameters are stored in a special place and not
+     in the alist.  */
   if (EQ (prop, Qbuffer_list))
     {
       f->buffer_list = val;
       return;
     }
+  if (EQ (prop, Qburied_buffer_list))
+    {
+      f->buried_buffer_list = val;
+      return;
+    }
 
   /* If PROP is a symbol which is supposed to have frame-local values,
      and it is set up based on this frame, switch to the global
@@ -2378,6 +2397,7 @@ If FRAME is omitted, return information on the currently selected frame.  */)
                   : FRAME_MINIBUF_WINDOW (f)));
   store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
   store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame));
+  store_in_alist (&alist, Qburied_buffer_list, XFRAME (frame)->buried_buffer_list);
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -2546,6 +2566,12 @@ enabled such bindings for that variable with `make-variable-frame-local'.  */)
          prop = parms[i];
          val = values[i];
          store_frame_param (f, prop, val);
+
+         /* Changing the background color might change the background
+            mode, so that we have to load new defface specs.
+            Call frame-set-background-mode to do that.  */
+         if (EQ (prop, Qbackground_color))
+           call1 (Qframe_set_background_mode, frame);
        }
     }
 
@@ -2580,8 +2606,7 @@ DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
        0, 1, 0,
        doc: /* Width in pixels of characters in the font in frame FRAME.
 If FRAME is omitted, the selected frame is used.
-The width is the same for all characters, because
-currently Emacs supports only fixed-width fonts.
+On a graphical screen, the width is the standard width of the default font.
 For a terminal screen, the value is always 1.  */)
      (frame)
      Lisp_Object frame;
@@ -3601,7 +3626,7 @@ extern char *x_get_string_resource P_ ((XrmDatabase, char *, char *));
 extern Display_Info *check_x_display_info P_ ((Lisp_Object));
 
 
-/* Get specified attribute from resource database RDB.  
+/* Get specified attribute from resource database RDB.
    See Fx_get_resource below for other parameters.  */
 
 static Lisp_Object
@@ -3738,7 +3763,7 @@ x_get_resource_string (attribute, class)
 
 Lisp_Object
 x_get_arg (dpyinfo, alist, param, attribute, class, type)
-     Display_Info *dpyinfo; 
+     Display_Info *dpyinfo;
      Lisp_Object alist, param;
      char *attribute;
      char *class;
@@ -4193,6 +4218,8 @@ syms_of_frame ()
   staticpro (&Qbuffer_predicate);
   Qbuffer_list = intern ("buffer-list");
   staticpro (&Qbuffer_list);
+  Qburied_buffer_list = intern ("buried-buffer-list");
+  staticpro (&Qburied_buffer_list);
   Qdisplay_type = intern ("display-type");
   staticpro (&Qdisplay_type);
   Qbackground_mode = intern ("background-mode");
@@ -4221,8 +4248,8 @@ syms_of_frame ()
   Qx_frame_parameter = intern ("x-frame-parameter");
   staticpro (&Qx_frame_parameter);
 
-  Qdisplay_id = intern ("display-id");
-  staticpro (&Qdisplay_id);
+  Qdevice = intern ("device");
+  staticpro (&Qdevice);
   Qdisplay_live_p = intern ("display-live-p");
   staticpro (&Qdisplay_live_p);
   
@@ -4324,7 +4351,14 @@ when the mouse is over clickable text.  */);
   DEFVAR_LISP ("delete-frame-functions", &Vdelete_frame_functions,
               doc: /* Functions to be run before deleting a frame.
 The functions are run with one arg, the frame to be deleted.
-See `delete-frame'.  */);
+See `delete-frame'.
+
+Note that functions in this list may be called twice on the same
+frame.  In the second invocation, the frame is already deleted, and
+the function should do nothing.  (You can use `frame-live-p' to check
+for this.)  This wrinkle happens when an earlier function in
+`delete-frame-functions' (indirectly) calls delete-frame
+recursively.  */);
   Vdelete_frame_functions = Qnil;
 
   DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,