(detect_coding_iso2022): Do not exclude posibility of
[bpt/emacs.git] / src / frame.c
index e6392da..bb0cfd4 100644 (file)
@@ -1,5 +1,5 @@
 /* Generic frame functions.
-   Copyright (C) 1993, 1994, 1995 Free Software Foundation.
+   Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation.
 
 This file is part of GNU Emacs.
 
@@ -15,12 +15,17 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 #include <config.h>
 
 #include <stdio.h>
 #include "lisp.h"
+#include "charset.h"
+#ifdef HAVE_WINDOW_SYSTEM
+#include "fontset.h"
+#endif
 #include "frame.h"
 #include "termhooks.h"
 #include "window.h"
@@ -28,19 +33,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "msdos.h"
 #endif
 
-#ifdef MULTI_FRAME
-
-#include "buffer.h"
-
-/* These help us bind and responding to switch-frame events.  */
-#include "commands.h"
-#include "keyboard.h"
-
-Lisp_Object Vemacs_iconified;
-Lisp_Object Vframe_list;
-Lisp_Object Vterminal_frame;
-Lisp_Object Vdefault_frame_alist;
-
 /* Evaluate this expression to rebuild the section of syms_of_frame
    that initializes and staticpros the symbols declared below.  Note
    that Emacs 18 has a bug that keeps C-x C-e from being able to
@@ -87,13 +79,137 @@ Lisp_Object Qunsplittable;
 Lisp_Object Qmenu_bar_lines;
 Lisp_Object Qwidth;
 Lisp_Object Qx;
+Lisp_Object Qw32;
+Lisp_Object Qpc;
 Lisp_Object Qvisible;
 Lisp_Object Qbuffer_predicate;
+Lisp_Object Qbuffer_list;
+Lisp_Object Qtitle;
+
+Lisp_Object Vterminal_frame;
+Lisp_Object Vdefault_frame_alist;
+
+static void
+syms_of_frame_1 ()
+{
+  /*&&& init symbols here &&&*/
+  Qframep = intern ("framep");
+  staticpro (&Qframep);
+  Qframe_live_p = intern ("frame-live-p");
+  staticpro (&Qframe_live_p);
+  Qheight = intern ("height");
+  staticpro (&Qheight);
+  Qicon = intern ("icon");
+  staticpro (&Qicon);
+  Qminibuffer = intern ("minibuffer");
+  staticpro (&Qminibuffer);
+  Qmodeline = intern ("modeline");
+  staticpro (&Qmodeline);
+  Qname = intern ("name");
+  staticpro (&Qname);
+  Qonly = intern ("only");
+  staticpro (&Qonly);
+  Qunsplittable = intern ("unsplittable");
+  staticpro (&Qunsplittable);
+  Qmenu_bar_lines = intern ("menu-bar-lines");
+  staticpro (&Qmenu_bar_lines);
+  Qwidth = intern ("width");
+  staticpro (&Qwidth);
+  Qx = intern ("x");
+  staticpro (&Qx);
+  Qw32 = intern ("w32");
+  staticpro (&Qw32);
+  Qpc = intern ("pc");
+  staticpro (&Qpc);
+  Qvisible = intern ("visible");
+  staticpro (&Qvisible);
+  Qbuffer_predicate = intern ("buffer-predicate");
+  staticpro (&Qbuffer_predicate);
+  Qbuffer_list = intern ("buffer-list");
+  staticpro (&Qbuffer_list);
+  Qtitle = intern ("title");
+  staticpro (&Qtitle);
+
+  DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
+    "Alist of default values for frame creation.\n\
+These may be set in your init file, like this:\n\
+  (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
+These override values given in window system configuration data,\n\
+ including X Windows' defaults database.\n\
+For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
+For values specific to the separate minibuffer frame, see\n\
+ `minibuffer-frame-alist'.\n\
+The `menu-bar-lines' element of the list controls whether new frames\n\
+ have menu bars; `menu-bar-mode' works by altering this element.");
+  Vdefault_frame_alist = Qnil;
+}
+\f
+static void
+set_menu_bar_lines_1 (window, n)
+  Lisp_Object window;
+  int n;
+{
+  struct window *w = XWINDOW (window);
+
+  XSETFASTINT (w->last_modified, 0);
+  XSETFASTINT (w->top, XFASTINT (w->top) + n);
+  XSETFASTINT (w->height, XFASTINT (w->height) - n);
+
+  /* Handle just the top child in a vertical split.  */
+  if (!NILP (w->vchild))
+    set_menu_bar_lines_1 (w->vchild, n);
+
+  /* Adjust all children in a horizontal split.  */
+  for (window = w->hchild; !NILP (window); window = w->next)
+    {
+      w = XWINDOW (window);
+      set_menu_bar_lines_1 (window, n);
+    }
+}
+
+static void
+set_menu_bar_lines (f, value, oldval)
+     struct frame *f;
+     Lisp_Object value, oldval;
+{
+  int nlines;
+  int olines = FRAME_MENU_BAR_LINES (f);
+
+  /* Right now, menu bars don't work properly in minibuf-only frames;
+     most of the commands try to apply themselves to the minibuffer
+     frame itself, and get an error because you can't switch buffers
+     in or split the minibuffer window.  */
+  if (FRAME_MINIBUF_ONLY_P (f))
+    return;
+
+  if (INTEGERP (value))
+    nlines = XINT (value);
+  else
+    nlines = 0;
+
+  if (nlines != olines)
+    {
+      windows_or_buffers_changed++;
+      FRAME_WINDOW_SIZES_CHANGED (f) = 1;
+      FRAME_MENU_BAR_LINES (f) = nlines;
+      set_menu_bar_lines_1 (f->root_window, nlines - olines);
+    }
+}
+\f
+#include "buffer.h"
+
+/* These help us bind and responding to switch-frame events.  */
+#include "commands.h"
+#include "keyboard.h"
+
+Lisp_Object Vemacs_iconified;
+Lisp_Object Vframe_list;
 
 extern Lisp_Object Vminibuffer_list;
 extern Lisp_Object get_minibuffer ();
 extern Lisp_Object Fhandle_switch_frame ();
 extern Lisp_Object Fredirect_frame_focus ();
+extern Lisp_Object x_get_focus_frame ();
 \f
 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
   "Return non-nil if OBJECT is a frame.\n\
@@ -112,7 +228,10 @@ See also `frame-live-p'.")
       return Qt;
     case output_x_window:
       return Qx;
-      /* The `pc' case is in the Fframep below.  */
+    case output_w32:
+      return Qw32;
+    case output_msdos_raw:
+      return Qpc;
     default:
       abort ();
     }
@@ -157,7 +276,7 @@ make_frame (mini_p)
   f->desired_glyphs = 0;
   f->visible = 0;
   f->async_visible = 0;
-  f->display.nothing = 0;
+  f->output_data.nothing = 0;
   f->iconified = 0;
   f->async_iconified = 0;
   f->wants_modeline = 1;
@@ -169,7 +288,7 @@ make_frame (mini_p)
   f->focus_frame = Qnil;
   f->explicit_name = 0;
   f->can_have_scroll_bars = 0;
-  f->has_vertical_scroll_bars = 0;
+  f->vertical_scroll_bar_type = vertical_scroll_bar_none;
   f->param_alist = Qnil;
   f->scroll_bars = Qnil;
   f->condemned_scroll_bars = Qnil;
@@ -178,10 +297,12 @@ make_frame (mini_p)
   f->menu_bar_vector = Qnil;
   f->menu_bar_items_used = 0;
   f->buffer_predicate = Qnil;
+  f->buffer_list = Qnil;
 #ifdef MULTI_KBOARD
   f->kboard = initial_kboard;
 #endif
   f->namebuf = 0;
+  f->title = Qnil;
 
   root_window = make_window ();
   if (mini_p)
@@ -206,7 +327,7 @@ make_frame (mini_p)
      just so that there is "something there."
      Correct size will be set up later with change_frame_size.  */
 
-  f->width = 10;
+  SET_FRAME_WIDTH (f, 10);
   f->height = 10;
 
   XSETFASTINT (XWINDOW (root_window)->width, 10);
@@ -230,6 +351,8 @@ make_frame (mini_p)
     if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
       buf = Fother_buffer (buf, Qnil);
     Fset_window_buffer (root_window, buf);
+
+    f->buffer_list = Fcons (buf, Qnil);
   }
 
   if (mini_p)
@@ -247,6 +370,10 @@ make_frame (mini_p)
      a newly-created, never-selected window.  */
   XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
 
+#ifdef HAVE_WINDOW_SYSTEM
+  f->fontset_data = alloc_fontset_data ();
+#endif
+
   return f;
 }
 \f
@@ -255,40 +382,54 @@ make_frame (mini_p)
    default (the global minibuffer).  */
 
 struct frame *
-make_frame_without_minibuffer (mini_window, kb)
+make_frame_without_minibuffer (mini_window, kb, display)
      register Lisp_Object mini_window;
      KBOARD *kb;
+     Lisp_Object display;
 {
   register struct frame *f;
+  struct gcpro gcpro1;
 
-  /* Choose the minibuffer window to use.  */
-  if (NILP (mini_window))
-    {
-      if (!FRAMEP (kb->Vdefault_minibuffer_frame))
-       error ("default-minibuffer-frame must be set when creating minibufferless frames");
-      if (! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
-       error ("default-minibuffer-frame must be a live frame");
-      mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
-    }
-  else
-    {
-      CHECK_LIVE_WINDOW (mini_window, 0);
-    }
+  if (!NILP (mini_window))
+    CHECK_LIVE_WINDOW (mini_window, 0);
 
 #ifdef MULTI_KBOARD
-  if (XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
+  if (!NILP (mini_window)
+      && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
     error ("frame and minibuffer must be on the same display");
 #endif
 
   /* Make a frame containing just a root window.  */
   f = make_frame (0);
 
-  /* Install the chosen minibuffer window, with proper buffer.  */
+  if (NILP (mini_window))
+    {
+      /* Use default-minibuffer-frame if possible.  */
+      if (!FRAMEP (kb->Vdefault_minibuffer_frame)
+         || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
+       {
+          Lisp_Object frame_dummy;
+
+          XSETFRAME (frame_dummy, f);
+          GCPRO1 (frame_dummy);
+         /* If there's no minibuffer frame to use, create one.  */
+         kb->Vdefault_minibuffer_frame =
+           call1 (intern ("make-initial-minibuffer-frame"), display);
+          UNGCPRO;
+       }
+   
+      mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
+    }
+
   f->minibuffer_window = mini_window;
-  Fset_window_buffer (mini_window,
-                     (NILP (Vminibuffer_list)
-                      ? get_minibuffer (0)
-                      : Fcar (Vminibuffer_list)));
+
+  /* Make the chosen minibuffer window display the proper minibuffer,
+     unless it is already showing a minibuffer.  */
+  if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
+    Fset_window_buffer (mini_window,
+                       (NILP (Vminibuffer_list)
+                        ? get_minibuffer (0)
+                        : Fcar (Vminibuffer_list)));
   return f;
 }
 
@@ -361,19 +502,18 @@ make_terminal_frame ()
   Vframe_list = Fcons (frame, Vframe_list);
 
   terminal_frame_count++;
-  if (terminal_frame_count == 1)
-    {
-      f->name = build_string ("Emacs");
-    }
-  else
-    {
-      sprintf (name, "Emacs-%d", terminal_frame_count);
-      f->name = build_string (name);
-    }
+  sprintf (name, "F%d", terminal_frame_count);
+  f->name = build_string (name);
 
   f->visible = 1;              /* FRAME_SET_VISIBLE wd set frame_garbaged. */
   f->async_visible = 1;                /* Don't let visible be cleared later. */
-  f->display.nothing = 1;      /* Nonzero means frame isn't deleted.  */
+#ifdef MSDOS
+  f->output_data.x = &the_only_x_display;
+  f->output_method = output_msdos_raw;
+  init_frame_faces (f);
+#else /* not MSDOS */
+  f->output_data.nothing = 1;  /* Nonzero means frame isn't deleted.  */
+#endif
   return f;
 }
 
@@ -390,8 +530,13 @@ Note that changing the size of one terminal frame automatically affects all.")
   struct frame *f;
   Lisp_Object frame;
 
+#ifdef MSDOS
+  if (selected_frame->output_method != output_msdos_raw)
+    abort ();
+#else
   if (selected_frame->output_method != output_termcap)
     error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
+#endif
 
   f = make_terminal_frame ();
   change_frame_size (f, FRAME_HEIGHT (selected_frame),
@@ -399,11 +544,13 @@ Note that changing the size of one terminal frame automatically affects all.")
   remake_frame_glyphs (f);
   calculate_costs (f);
   XSETFRAME (frame, f);
+  Fmodify_frame_parameters (frame, Vdefault_frame_alist);
   Fmodify_frame_parameters (frame, parms);
+  f->face_alist = selected_frame->face_alist;
   return frame;
 }
 \f
-static Lisp_Object
+Lisp_Object
 do_switch_frame (frame, no_enter, track)
      Lisp_Object frame, no_enter;
      int track;
@@ -454,8 +601,8 @@ do_switch_frame (frame, no_enter, track)
     }
 #else /* ! 0 */
   /* Instead, apply it only to the frame we're pointing to.  */
-#ifdef HAVE_X_WINDOWS
-  if (track && FRAME_X_P (XFRAME (frame)))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (track && (FRAME_WINDOW_P (XFRAME (frame))))
     {
       Lisp_Object focus, xfocus;
 
@@ -470,21 +617,11 @@ do_switch_frame (frame, no_enter, track)
 #endif /* HAVE_X_WINDOWS */
 #endif /* ! 0 */
 
-  if (FRAME_TERMCAP_P (XFRAME (frame)))
-    {
-      /* Since frames on an ASCII terminal share the same display area,
-        switching means we must redisplay the whole thing.  */
-      windows_or_buffers_changed++;
-      SET_FRAME_GARBAGED (XFRAME (frame));
-      XSETFRAME (Vterminal_frame, frame);
-    }
-
   selected_frame = XFRAME (frame);
   if (! FRAME_MINIBUF_ONLY_P (selected_frame))
     last_nonminibuf_frame = selected_frame;
 
   Fselect_window (XFRAME (frame)->selected_window);
-  choose_minibuf_frame ();
 
   /* We want to make sure that the next event generates a frame-switch
      event to the appropriate frame.  This seems kludgy to me, but
@@ -519,12 +656,23 @@ This function selects the selected window of the frame of EVENT.\n\
 \n\
 If EVENT is frame object, handle it as if it were a switch-frame event\n\
 to that frame.")
-  (frame, no_enter)
-     Lisp_Object frame, no_enter;
+  (event, no_enter)
+     Lisp_Object event, no_enter;
 {
-  return do_switch_frame (frame, no_enter, 0);
+  /* Preserve prefix arg that the command loop just cleared.  */
+  current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
+  call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
+  return do_switch_frame (event, no_enter, 0);
 }
 
+DEFUN ("ignore-event", Fignore_event, Signore_event, 0, 0, "",
+  "Do nothing, but preserve any prefix argument already specified.\n\
+This is a suitable binding for iconify-frame and make-frame-visible.")
+     ()
+{
+  current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
+  return Qnil;
+}
 
 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
   "Return the frame that is now selected.")
@@ -670,7 +818,9 @@ next_frame (frame, minibuf)
        Lisp_Object f;
 
        f = XCONS (tail)->car;
-       if (passed)
+
+       if (passed
+           && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
          {
            /* Decide whether this frame is eligible to be returned.  */
 
@@ -749,38 +899,41 @@ prev_frame (frame, minibuf)
       if (EQ (frame, f) && !NILP (prev))
        return prev;
 
-      /* Decide whether this frame is eligible to be returned,
-        according to minibuf.  */
-      if (NILP (minibuf))
-       {
-         if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
-           prev = f;
-       }
-      else if (WINDOWP (minibuf))
+      if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
        {
-         if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
-             /* Check that F either is, or has forwarded its focus to,
-                MINIBUF's frame.  */
-             && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
-                 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
-                        FRAME_FOCUS_FRAME (XFRAME (f)))))
-           prev = f;
-       }
-      else if (EQ (minibuf, Qvisible))
-       {
-         FRAME_SAMPLE_VISIBILITY (XFRAME (f));
-         if (FRAME_VISIBLE_P (XFRAME (f)))
-           prev = f;
-       }
-      else if (XFASTINT (minibuf) == 0)
-       {
-         FRAME_SAMPLE_VISIBILITY (XFRAME (f));
-         if (FRAME_VISIBLE_P (XFRAME (f))
-             || FRAME_ICONIFIED_P (XFRAME (f)))
+         /* Decide whether this frame is eligible to be returned,
+            according to minibuf.  */
+         if (NILP (minibuf))
+           {
+             if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
+               prev = f;
+           }
+         else if (WINDOWP (minibuf))
+           {
+             if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
+                 /* Check that F either is, or has forwarded its focus to,
+                    MINIBUF's frame.  */
+                 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
+                     || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
+                            FRAME_FOCUS_FRAME (XFRAME (f)))))
+               prev = f;
+           }
+         else if (EQ (minibuf, Qvisible))
+           {
+             FRAME_SAMPLE_VISIBILITY (XFRAME (f));
+             if (FRAME_VISIBLE_P (XFRAME (f)))
+               prev = f;
+           }
+         else if (XFASTINT (minibuf) == 0)
+           {
+             FRAME_SAMPLE_VISIBILITY (XFRAME (f));
+             if (FRAME_VISIBLE_P (XFRAME (f))
+                 || FRAME_ICONIFIED_P (XFRAME (f)))
+               prev = f;
+           }
+         else
            prev = f;
        }
-      else
-       prev = f;
     }
 
   /* We've scanned the entire list.  */
@@ -798,13 +951,14 @@ prev_frame (frame, minibuf)
 
 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
   "Return the next frame in the frame list after FRAME.\n\
+It considers only frames on the same terminal as FRAME.\n\
 By default, skip minibuffer-only frames.\n\
 If omitted, FRAME defaults to the selected frame.\n\
 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
-If MINIBUF is a window, include only its own frame\n\
+If MINIFRAME is a window, include only its own frame\n\
 and any frame now using that window as the minibuffer.\n\
 If MINIFRAME is `visible', include all visible frames.\n\
-If MINIBUF is 0, include all visible and iconified frames.\n\
+If MINIFRAME is 0, include all visible and iconified frames.\n\
 Otherwise, include all frames.")
   (frame, miniframe)
      Lisp_Object frame, miniframe;
@@ -821,13 +975,14 @@ Otherwise, include all frames.")
 
 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
   "Return the previous frame in the frame list before FRAME.\n\
+It considers only frames on the same terminal as FRAME.\n\
 By default, skip minibuffer-only frames.\n\
 If omitted, FRAME defaults to the selected frame.\n\
 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
-If MINIBUF is a window, include only its own frame\n\
+If MINIFRAME is a window, include only its own frame\n\
 and any frame now using that window as the minibuffer.\n\
 If MINIFRAME is `visible', include all visible frames.\n\
-If MINIBUF is 0, include all visible and iconified frames.\n\
+If MINIFRAME is 0, include all visible and iconified frames.\n\
 Otherwise, include all frames.")
   (frame, miniframe)
      Lisp_Object frame, miniframe;
@@ -867,8 +1022,8 @@ other_visible_frames (f)
          /* Verify that the frame's window still exists
             and we can still talk to it.  And note any recent change
             in visibility.  */
-#ifdef HAVE_X_WINDOWS
-         if (FRAME_X_P (XFRAME (this)))
+#ifdef HAVE_WINDOW_SYSTEM
+         if (FRAME_WINDOW_P (XFRAME (this)))
            {
              x_sync (XFRAME (this));
              FRAME_SAMPLE_VISIBILITY (XFRAME (this));
@@ -879,7 +1034,7 @@ other_visible_frames (f)
              || FRAME_ICONIFIED_P (XFRAME (this))
              /* Allow deleting the terminal frame when at least
                 one X frame exists!  */
-             || (FRAME_X_P (XFRAME (this)) && !FRAME_X_P (f)))
+             || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
            count++;
        }
       return count > 1;
@@ -897,6 +1052,7 @@ but if the second optional argument FORCE is non-nil, you may do so.")
      Lisp_Object frame, force;
 {
   struct frame *f;
+  int minibuffer_selected;
 
   if (EQ (frame, Qnil))
     {
@@ -915,6 +1071,13 @@ but if the second optional argument FORCE is non-nil, you may do so.")
   if (NILP (force) && !other_visible_frames (f))
     error ("Attempt to delete the sole visible or iconified frame");
 
+#if 0
+  /* This is a nice idea, but x_connection_closed needs to be able
+     to delete the last frame, if it is gone.  */
+  if (NILP (XCONS (Vframe_list)->cdr))
+    error ("Attempt to delete the only frame");
+#endif
+
   /* Does this frame have a minibuffer, and is it the surrogate
      minibuffer for any other frame?  */
   if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
@@ -936,9 +1099,28 @@ but if the second optional argument FORCE is non-nil, you may do so.")
        }
     }
 
+  minibuffer_selected = EQ (minibuf_window, selected_window);
+
   /* Don't let the frame remain selected.  */
   if (f == selected_frame)
-    Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
+    {
+      Lisp_Object tail, frame1;
+
+      /* Look for another visible frame on the same terminal.  */
+      frame1 = next_frame (frame, Qvisible);
+
+      /* If there is none, find *some* other frame.  */
+      if (NILP (frame1) || EQ (frame1, frame))
+       {
+         FOR_EACH_FRAME (tail, frame1)
+           {
+             if (! EQ (frame, frame1))
+               break;
+           }
+       }
+
+      do_switch_frame (frame1, Qnil, 0);
+    }
 
   /* Don't allow minibuf_window to remain on a deleted frame.  */
   if (EQ (f->minibuffer_window, minibuf_window))
@@ -946,6 +1128,11 @@ but if the second optional argument FORCE is non-nil, you may do so.")
       Fset_window_buffer (selected_frame->minibuffer_window,
                          XWINDOW (minibuf_window)->buffer);
       minibuf_window = selected_frame->minibuffer_window;
+
+      /* If the dying minibuffer window was selected,
+        select the new one.  */
+      if (minibuffer_selected)
+       Fselect_window (minibuf_window);
     }
 
   /* Clear any X selections for this frame.  */
@@ -962,6 +1149,12 @@ but if the second optional argument FORCE is non-nil, you may do so.")
   Vframe_list = Fdelq (frame, Vframe_list);
   FRAME_SET_VISIBLE (f, 0);
 
+  if (echo_area_glyphs == FRAME_MESSAGE_BUF (f))
+    {
+      echo_area_glyphs = 0;
+      previous_echo_glyphs = 0;
+    }
+
   if (f->namebuf)
     free (f->namebuf);
   if (FRAME_CURRENT_GLYPHS (f))
@@ -978,6 +1171,13 @@ but if the second optional argument FORCE is non-nil, you may do so.")
     free (FRAME_INSERTN_COST (f));
   if (FRAME_DELETE_COST (f))
     free (FRAME_DELETE_COST (f));
+  if (FRAME_MESSAGE_BUF (f))
+    free (FRAME_MESSAGE_BUF (f));
+
+#ifdef HAVE_WINDOW_SYSTEM
+  /* Free all fontset data.  */
+  free_fontset_data (FRAME_FONTSET_DATA (f));
+#endif
 
   /* Since some events are handled at the interrupt level, we may get
      an event for f at any time; if we zero out the frame's display
@@ -986,12 +1186,12 @@ but if the second optional argument FORCE is non-nil, you may do so.")
      called the window-system-dependent frame destruction routine.  */
 
   /* I think this should be done with a hook.  */
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (f))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
     x_destroy_window (f);
 #endif
 
-  f->display.nothing = 0;
+  f->output_data.nothing = 0;
 
   /* If we've deleted the last_nonminibuf_frame, then try to find
      another one.  */
@@ -1023,8 +1223,12 @@ but if the second optional argument FORCE is non-nil, you may do so.")
 
       /* The last frame we saw with a minibuffer, minibuffer-only or not.  */
       Lisp_Object frame_with_minibuf;
+      /* 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_with_minibuf = Qnil;
+
       for (frames = Vframe_list;
           CONSP (frames);
           frames = XCONS (frames)->cdr)
@@ -1046,20 +1250,32 @@ but if the second optional argument FORCE is non-nil, you may do so.")
              if (FRAME_MINIBUF_ONLY_P (f1))
                break;
            }
+
+         if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
+           frame_on_same_kboard = this;
        }
 
-      /* We know that there must be some frame with a minibuffer out
-        there.  If this were not true, all of the frames present
-        would have to be minibufferless, which implies that at some
-        point their minibuffer frames must have been deleted, but
-        that is prohibited at the top; you can't delete surrogate
-        minibuffer frames.  */
-      if (NILP (frame_with_minibuf))
-       abort ();
+      if (!NILP (frame_on_same_kboard))
+       {
+         /* We know that there must be some frame with a minibuffer out
+            there.  If this were not true, all of the frames present
+            would have to be minibufferless, which implies that at some
+            point their minibuffer frames must have been deleted, but
+            that is prohibited at the top; you can't delete surrogate
+            minibuffer frames.  */
+         if (NILP (frame_with_minibuf))
+           abort ();
 
-      FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
+         FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
+       }
+      else
+       /* No frames left on this kboard--say no minibuffer either.  */
+       FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
     }
 
+  /* Cause frame titles to update--necessary if we now have just one frame.  */
+  update_mode_lines = 1;
+
   return Qnil;
 }
 \f
@@ -1095,7 +1311,7 @@ and nil for X and Y.")
     {
       col = XINT (x);
       row = XINT (y);
-      pixel_to_glyph_coords (f, col, row, &col, &row, 0, 1);
+      pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
       XSETINT (x, col);
       XSETINT (y, row);
     }
@@ -1138,8 +1354,10 @@ and nil for X and Y.")
 
 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
   "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
-WARNING:  If you use this under X windows,\n\
-you should call `unfocus-frame' afterwards.")
+Note, this is a no-op for an X frame that is not visible.\n\
+If you have just created a frame, you must wait for it to become visible\n\
+before calling this function on it, like this.\n\
+  (while (not (frame-visible-p frame)) (sleep-for .5))")
   (frame, x, y)
      Lisp_Object frame, x, y;
 {
@@ -1148,10 +1366,18 @@ you should call `unfocus-frame' afterwards.")
   CHECK_NUMBER (y, 1);
 
   /* I think this should be done with a hook.  */
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (XFRAME (frame)))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (XFRAME (frame)))
     /* Warping the mouse will cause  enternotify and focus events. */
     x_set_mouse_position (XFRAME (frame), x, y);
+#else
+#if defined (MSDOS) && defined (HAVE_MOUSE)
+  if (FRAME_MSDOS_P (XFRAME (frame)))
+    {
+      Fselect_frame (frame, Qnil);
+      mouse_moveto (XINT (x), XINT (y));
+    }
+#endif
 #endif
 
   return Qnil;
@@ -1160,8 +1386,10 @@ you should call `unfocus-frame' afterwards.")
 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
        Sset_mouse_pixel_position, 3, 3, 0,
   "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
-WARNING:  If you use this under X windows,\n\
-you should call `unfocus-frame' afterwards.")
+Note, this is a no-op for an X frame that is not visible.\n\
+If you have just created a frame, you must wait for it to become visible\n\
+before calling this function on it, like this.\n\
+  (while (not (frame-visible-p frame)) (sleep-for .5))")
   (frame, x, y)
      Lisp_Object frame, x, y;
 {
@@ -1170,10 +1398,18 @@ you should call `unfocus-frame' afterwards.")
   CHECK_NUMBER (y, 1);
 
   /* I think this should be done with a hook.  */
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (XFRAME (frame)))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (XFRAME (frame)))
     /* Warping the mouse will cause  enternotify and focus events. */
     x_set_mouse_pixel_position (XFRAME (frame), x, y);
+#else
+#if defined (MSDOS) && defined (HAVE_MOUSE)
+  if (FRAME_MSDOS_P (XFRAME (frame)))
+    {
+      Fselect_frame (frame, Qnil);
+      mouse_moveto (XINT (x), XINT (y));
+    }
+#endif
 #endif
 
   return Qnil;
@@ -1192,8 +1428,8 @@ If omitted, FRAME defaults to the currently selected frame.")
   CHECK_LIVE_FRAME (frame, 0);
 
   /* I think this should be done with a hook.  */
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (XFRAME (frame)))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (XFRAME (frame)))
     {
       FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
       x_make_frame_visible (XFRAME (frame));
@@ -1226,7 +1462,7 @@ but if the second optional argument FORCE is non-nil, you may do so.")
 #if 0 /* This isn't logically necessary, and it can do GC.  */
   /* Don't let the frame remain selected.  */
   if (XFRAME (frame) == selected_frame)
-    Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
+    do_switch_frame (next_frame (frame, Qt), Qnil, 0)
 #endif
 
   /* Don't allow minibuf_window to remain on a deleted frame.  */
@@ -1238,8 +1474,8 @@ but if the second optional argument FORCE is non-nil, you may do so.")
     }
 
   /* I think this should be done with a hook.  */
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (XFRAME (frame)))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (XFRAME (frame)))
     x_make_frame_invisible (XFRAME (frame));
 #endif
 
@@ -1276,8 +1512,8 @@ If omitted, FRAME defaults to the currently selected frame.")
     }
 
   /* I think this should be done with a hook.  */
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (XFRAME (frame)))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (XFRAME (frame)))
       x_iconify_frame (XFRAME (frame));
 #endif
 
@@ -1412,13 +1648,6 @@ The redirection lasts until `redirect-frame-focus' is called to change it.")
 
   XFRAME (frame)->focus_frame = focus_frame;
 
-  /* I think this should be done with a hook.  */
-#ifdef HAVE_X_WINDOWS
-  if (!NILP (focus_frame) && ! EQ (focus_frame, frame)
-      && FRAME_X_P (XFRAME (focus_frame)))
-    Ffocus_frame (focus_frame);
-#endif
-
   if (frame_rehighlight_hook)
     (*frame_rehighlight_hook) (XFRAME (frame));
   
@@ -1463,6 +1692,54 @@ frame_buffer_predicate ()
   return selected_frame->buffer_predicate;
 }
 
+/* Return the buffer-list of the selected frame.  */
+
+Lisp_Object
+frame_buffer_list ()
+{
+  return selected_frame->buffer_list;
+}
+
+/* Set the buffer-list of the selected frame.  */
+
+void
+set_frame_buffer_list (list)
+     Lisp_Object list;
+{
+  selected_frame->buffer_list = list;
+}
+
+/* Discard BUFFER from the buffer-list of each frame.  */
+
+void
+frames_discard_buffer (buffer)
+     Lisp_Object buffer;
+{
+  Lisp_Object frame, tail;
+
+  FOR_EACH_FRAME (tail, frame)
+    {
+      XFRAME (frame)->buffer_list
+       = Fdelq (buffer, XFRAME (frame)->buffer_list);
+    }
+}
+
+/* Move BUFFER to the end of the buffer-list of each frame.  */
+
+void
+frames_bury_buffer (buffer)
+     Lisp_Object buffer;
+{
+  Lisp_Object frame, tail;
+
+  FOR_EACH_FRAME (tail, frame)
+    {
+      XFRAME (frame)->buffer_list
+       = nconc2 (Fdelq (buffer, XFRAME (frame)->buffer_list),
+                 Fcons (buffer, Qnil));
+    }
+}
+
 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
    If the alist already has an element for PROP, we change it.  */
 
@@ -1487,6 +1764,12 @@ store_frame_param (f, prop, val)
 {
   register Lisp_Object tem;
 
+  if (EQ (prop, Qbuffer_list))
+    {
+      f->buffer_list = val;
+      return;
+    }
+
   tem = Fassq (prop, f->param_alist);
   if (EQ (tem, Qnil))
     f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
@@ -1496,13 +1779,18 @@ store_frame_param (f, prop, val)
   if (EQ (prop, Qbuffer_predicate))
     f->buffer_predicate = val;
 
+  if (! FRAME_WINDOW_P (f))
+    if (EQ (prop, Qmenu_bar_lines))
+      set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
+
   if (EQ (prop, Qminibuffer) && WINDOWP (val))
     {
       if (! MINI_WINDOW_P (XWINDOW (val)))
        error ("Surrogate minibuffer windows must be minibuffer windows.");
 
-      if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
-       error ("can't change the surrogate minibuffer of a frame with its own minibuffer");
+      if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f)
+         && !EQ (val, f->minibuffer_window))
+       error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
 
       /* Install the chosen minibuffer window, with proper buffer.  */
       f->minibuffer_window = val;
@@ -1519,6 +1807,7 @@ If FRAME is omitted, return information on the currently selected frame.")
 {
   Lisp_Object alist;
   FRAME_PTR f;
+  int height, width;
 
   if (EQ (frame, Qnil))
     f = selected_frame;
@@ -1532,19 +1821,38 @@ If FRAME is omitted, return information on the currently selected frame.")
     return Qnil;
 
   alist = Fcopy_alist (f->param_alist);
+#ifdef MSDOS
+  if (FRAME_MSDOS_P (f))
+    {
+      static char *colornames[16] = 
+       {
+         "black", "blue", "green", "cyan", "red", "magenta", "brown",
+         "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
+         "lightred", "lightmagenta", "yellow", "white"
+       };
+      store_in_alist (&alist, intern ("foreground-color"),
+                     build_string (colornames[FRAME_FOREGROUND_PIXEL (f)]));
+      store_in_alist (&alist, intern ("background-color"),
+                     build_string (colornames[FRAME_BACKGROUND_PIXEL (f)]));
+    }
+  store_in_alist (&alist, intern ("font"), build_string ("default"));
+#endif
   store_in_alist (&alist, Qname, f->name);
-  store_in_alist (&alist, Qheight, make_number (FRAME_HEIGHT (f)));
-  store_in_alist (&alist, Qwidth, make_number (FRAME_WIDTH (f)));
+  height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
+  store_in_alist (&alist, Qheight, make_number (height));
+  width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
+  store_in_alist (&alist, Qwidth, make_number (width));
   store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
   store_in_alist (&alist, Qminibuffer,
                  (! FRAME_HAS_MINIBUF_P (f) ? Qnil
                   : FRAME_MINIBUF_ONLY_P (f) ? Qonly
                   : 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 ());
 
   /* I think this should be done with a hook.  */
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (f))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
     x_report_frame_params (f, &alist);
   else
 #endif
@@ -1562,7 +1870,9 @@ DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
   "Modify the parameters of frame FRAME according to ALIST.\n\
 ALIST is an alist of parameters to change and their new values.\n\
 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
-The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
+The meaningful PARMs depend on the kind of frame.\n\
+Undefined PARMs are ignored, but stored in the frame's parameter list\n\
+so that `frame-parameters' will return them.")
   (frame, alist)
      Lisp_Object frame, alist;
 {
@@ -1578,20 +1888,47 @@ The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
     }
 
   /* I think this should be done with a hook.  */
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (f))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
     x_set_frame_parameters (f, alist);
   else
 #endif
-    for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
-      {
-       elt = Fcar (tail);
-       prop = Fcar (elt);
-       val = Fcdr (elt);
-       store_frame_param (f, prop, val);
-      }
+#ifdef MSDOS
+  if (FRAME_MSDOS_P (f))
+    IT_set_frame_parameters (f, alist);
+  else
+#endif
+    {
+      int length = XINT (Flength (alist));
+      int i;
+      Lisp_Object *parms
+       = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
+      Lisp_Object *values
+       = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
 
-  return Qnil;
+      /* Extract parm names and values into those vectors.  */
+
+      i = 0;
+      for (tail = alist; CONSP (tail); tail = Fcdr (tail))
+       {
+         Lisp_Object elt, prop, val;
+
+         elt = Fcar (tail);
+         parms[i] = Fcar (elt);
+         values[i] = Fcdr (elt);
+         i++;
+       }
+
+      /* Now process them in reverse of specified order.  */
+      for (i--; i >= 0; i--)
+       {
+         prop = parms[i];
+         val = values[i];
+         store_frame_param (f, prop, val);
+       }
+    }
+
+  return Qnil;
 }
 \f
 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
@@ -1612,8 +1949,8 @@ For a terminal frame, the value is always 1.")
       f = XFRAME (frame);
     }
 
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (f))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
     return make_number (x_char_height (f));
   else
 #endif
@@ -1641,8 +1978,8 @@ For a terminal screen, the value is always 1.")
       f = XFRAME (frame);
     }
 
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (f))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
     return make_number (x_char_width (f));
   else
 #endif
@@ -1667,8 +2004,8 @@ If FRAME is omitted, the selected frame is used.")
       f = XFRAME (frame);
     }
 
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (f))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
     return make_number (x_pixel_height (f));
   else
 #endif
@@ -1693,8 +2030,8 @@ If FRAME is omitted, the selected frame is used.")
       f = XFRAME (frame);
     }
 
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (f))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
     return make_number (x_pixel_width (f));
   else
 #endif
@@ -1705,12 +2042,12 @@ DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
   "Specify that the frame FRAME has LINES lines.\n\
 Optional third arg non-nil means that redisplay should use LINES lines\n\
 but that the idea of the actual height of the frame should not be changed.")
-  (frame, rows, pretend)
-     Lisp_Object frame, rows, pretend;
+  (frame, lines, pretend)
+     Lisp_Object frame, lines, pretend;
 {
   register struct frame *f;
 
-  CHECK_NUMBER (rows, 0);
+  CHECK_NUMBER (lines, 0);
   if (NILP (frame))
     f = selected_frame;
   else
@@ -1720,15 +2057,15 @@ but that the idea of the actual height of the frame should not be changed.")
     }
 
   /* I think this should be done with a hook.  */
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (f))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
     {
-      if (XINT (rows) != f->height)
-       x_set_window_size (f, 1, f->width, XINT (rows));
+      if (XINT (lines) != f->height)
+       x_set_window_size (f, 1, f->width, XINT (lines));
     }
   else
 #endif
-    change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0);
+    change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0);
   return Qnil;
 }
 
@@ -1750,8 +2087,8 @@ but that the idea of the actual width of the frame should not be changed.")
     }
 
   /* I think this should be done with a hook.  */
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (f))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
     {
       if (XINT (cols) != f->width)
        x_set_window_size (f, 1, XINT (cols), f->height);
@@ -1776,10 +2113,11 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
   f = XFRAME (frame);
 
   /* I think this should be done with a hook.  */
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (f))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
     {
-      if (XINT (rows) != f->height || XINT (cols) != f->width)
+      if (XINT (rows) != f->height || XINT (cols) != f->width
+         || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
        x_set_window_size (f, 1, XINT (cols), XINT (rows));
     }
   else
@@ -1807,8 +2145,8 @@ the rightmost or bottommost possible position (that stays within the screen).")
   f = XFRAME (frame);
 
   /* I think this should be done with a hook.  */
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (f))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
     x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
 #endif
 
@@ -1816,57 +2154,9 @@ the rightmost or bottommost possible position (that stays within the screen).")
 }
 
 \f
-choose_minibuf_frame ()
-{
-  /* For lowest-level minibuf, put it on currently selected frame
-     if frame has a minibuffer.  */
-
-  if (minibuf_level == 0
-      && selected_frame != 0
-      && !EQ (minibuf_window, selected_frame->minibuffer_window))
-    {
-      /* I don't think that any frames may validly have a null minibuffer
-        window anymore.  */
-      if (NILP (selected_frame->minibuffer_window))
-       abort ();
-
-      Fset_window_buffer (selected_frame->minibuffer_window,
-                         XWINDOW (minibuf_window)->buffer);
-      minibuf_window = selected_frame->minibuffer_window;
-    }
-}
-\f
 syms_of_frame ()
 {
-  /*&&& init symbols here &&&*/
-  Qframep = intern ("framep");
-  staticpro (&Qframep);
-  Qframe_live_p = intern ("frame-live-p");
-  staticpro (&Qframe_live_p);
-  Qheight = intern ("height");
-  staticpro (&Qheight);
-  Qicon = intern ("icon");
-  staticpro (&Qicon);
-  Qminibuffer = intern ("minibuffer");
-  staticpro (&Qminibuffer);
-  Qmodeline = intern ("modeline");
-  staticpro (&Qmodeline);
-  Qname = intern ("name");
-  staticpro (&Qname);
-  Qonly = intern ("only");
-  staticpro (&Qonly);
-  Qunsplittable = intern ("unsplittable");
-  staticpro (&Qunsplittable);
-  Qmenu_bar_lines = intern ("menu-bar-lines");
-  staticpro (&Qmenu_bar_lines);
-  Qwidth = intern ("width");
-  staticpro (&Qwidth);
-  Qx = intern ("x");
-  staticpro (&Qx);
-  Qvisible = intern ("visible");
-  staticpro (&Qvisible);
-  Qbuffer_predicate = intern ("buffer-predicate");
-  staticpro (&Qbuffer_predicate);
+  syms_of_frame_1 ();
 
   staticpro (&Vframe_list);
 
@@ -1890,24 +2180,12 @@ this variable doesn't necessarily say anything meaningful about the\n\
 current set of frames, or where the minibuffer is currently being\n\
 displayed.");
 
-  DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
-    "Alist of default values for frame creation.\n\
-These may be set in your init file, like this:\n\
-  (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
-These override values given in window system configuration data,\n\
- including X Windows' defaults database.\n\
-For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
-For values specific to the separate minibuffer frame, see\n\
- `minibuffer-frame-alist'.\n\
-The `menu-bar-lines' element of the list controls whether new frames\n\
- have menu bars; `menu-bar-mode' works by altering this element.");
-  Vdefault_frame_alist = Qnil;
-
   defsubr (&Sactive_minibuffer_window);
   defsubr (&Sframep);
   defsubr (&Sframe_live_p);
   defsubr (&Smake_terminal_frame);
   defsubr (&Shandle_switch_frame);
+  defsubr (&Signore_event);
   defsubr (&Sselect_frame);
   defsubr (&Sselected_frame);
   defsubr (&Swindow_frame);
@@ -1952,406 +2230,6 @@ keys_of_frame ()
 {
   initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
   initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
-  initial_define_lispy_key (global_map, "iconify-frame", "ignore");
-  initial_define_lispy_key (global_map, "make-frame-visible", "ignore");
-}
-\f
-#else /* not MULTI_FRAME */
-
-/* If we're not using multi-frame stuff, we still need to provide some
-   support functions.  */
-
-Lisp_Object Qheight;
-Lisp_Object Qminibuffer;
-Lisp_Object Qmodeline;
-Lisp_Object Qname;
-Lisp_Object Qunsplittable;
-Lisp_Object Qmenu_bar_lines;
-Lisp_Object Qwidth;
-
-Lisp_Object Vterminal_frame;
-
-/* Unless this function is defined, providing set-frame-height and
-   set-frame-width doesn't help compatibility any, since they both
-   want this as their first argument.  */
-DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  ()
-{
-  /* For your possible information, this code is unfolded into the
-     second WINDOW_FRAME in frame.h.  */     
-  Lisp_Object tem;
-  XSETFASTINT (tem, 0);
-  return tem;
-}
-
-DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (window)
-     Lisp_Object window;
-{
-  /* For your possible information, this code is unfolded into the
-     second WINDOW_FRAME in frame.h.  */     
-  Lisp_Object tem;
-  XSETFASTINT (tem, 0);
-  return tem;
-}
-
-DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
-  0)
-  (frame)
-     Lisp_Object frame;
-{
-  Lisp_Object w;
-
-  w = FRAME_ROOT_WINDOW (selected_frame);
-
-  while (NILP (XWINDOW (w)->buffer))
-    {
-      if (! NILP (XWINDOW (w)->hchild))
-       w = XWINDOW (w)->hchild;
-      else if (! NILP (XWINDOW (w)->vchild))
-       w = XWINDOW (w)->vchild;
-      else
-       abort ();
-    }
-  return w;
-}
-
-DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (object)
-     Lisp_Object object;
-{
-#ifdef MSDOS
-  if (FRAME_X_P (object))
-    return intern ("pc");
-#endif
-  return Qnil;
-}
-
-DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (frame, rows, pretend)
-     Lisp_Object frame, rows, pretend;
-{
-  CHECK_NUMBER (rows, 0);
-
-  change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
-  return Qnil;
+  initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
+  initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");
 }
-
-DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (frame, cols, pretend)
-     Lisp_Object frame, cols, pretend;
-{
-  CHECK_NUMBER (cols, 0);
-
-  change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
-  return Qnil;
-}
-
-DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (frame, cols, rows)
-     Lisp_Object frame, cols, rows;
-{
-  CHECK_NUMBER (cols, 2);
-  CHECK_NUMBER (rows, 1);
-
-  change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
-
-  return Qnil;
-}
-\f
-DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 1, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (frame)
-    Lisp_Object frame;
-{
-  return make_number (FRAME_HEIGHT (selected_frame));
-}
-
-DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 1, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (frame)
-    Lisp_Object frame;
-{
-  return make_number (FRAME_WIDTH (selected_frame));
-}
-
-DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
-  0, 1, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (frame)
-     Lisp_Object frame;
-{
-  return make_number (1);
-}
-
-
-DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
-  0, 1, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (frame)
-     Lisp_Object frame;
-{
-  return make_number (1);
-}
-
-DEFUN ("frame-pixel-height", Fframe_pixel_height, 
-       Sframe_pixel_height, 0, 1, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (frame)
-     Lisp_Object frame;
-{
-  return make_number (FRAME_HEIGHT (f));
-}
-
-DEFUN ("frame-pixel-width", Fframe_pixel_width, 
-       Sframe_pixel_width, 0, 1, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (frame)
-     Lisp_Object frame;
-{
-  return make_number (FRAME_WIDTH (f));
-}
-
-/* These are for backward compatibility with Emacs 18.  */
-
-DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (lines, pretend)
-     Lisp_Object lines, pretend;
-{
-  CHECK_NUMBER (lines, 0);
-
-  change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
-  return Qnil;
-}
-
-DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (cols, pretend)
-     Lisp_Object cols, pretend;
-{
-  CHECK_NUMBER (cols, 0);
-
-  change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
-  return Qnil;
-}
-
-DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  ()
-{
-#ifdef HAVE_MOUSE
-  if (mouse_position_hook)
-    {
-      FRAME_PTR f;
-      Lisp_Object lispy_dummy;
-      enum scroll_bar_part party_dummy;
-      Lisp_Object x, y;
-      unsigned long long_dummy;
-
-      (*mouse_position_hook) (&f, 0,
-                             &lispy_dummy, &party_dummy,
-                             &x, &y,
-                             &long_dummy);      
-      return Fcons (Fselected_frame (), Fcons (x, y));
-    }
-#endif
-  return Fcons (Qnil, Fcons (Qnil, Qnil));
-}
-\f
-void
-store_in_alist (alistptr, prop, val)
-     Lisp_Object *alistptr, val;
-     Lisp_Object prop;
-{
-  register Lisp_Object tem;
-
-  tem = Fassq (prop, *alistptr);
-  if (EQ (tem, Qnil))
-    *alistptr = Fcons (Fcons (prop, val), *alistptr);
-  else
-    Fsetcdr (tem, val);
-}
-
-DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (frame)
-     Lisp_Object frame;
-{
-  Lisp_Object alist;
-  FRAME_PTR f;
-
-  if (EQ (frame, Qnil))
-    f = selected_frame;
-  else
-    {
-      CHECK_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
-
-  if (!FRAME_LIVE_P (f))
-    return Qnil;
-
-  alist = Qnil;
-#ifdef MSDOS
-  if (FRAME_X_P (f))
-    {
-      static char *colornames[16] = 
-       {
-         "black", "blue", "green", "cyan", "red", "magenta", "brown",
-         "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
-         "lightred", "lightmagenta", "yellow", "white"
-       };
-      store_in_alist (&alist, intern ("foreground-color"),
-                     build_string (colornames[FRAME_FOREGROUND_PIXEL (f)]));
-      store_in_alist (&alist, intern ("background-color"),
-                     build_string (colornames[FRAME_BACKGROUND_PIXEL (f)]));
-    }
-#endif
-  store_in_alist (&alist, intern ("font"), build_string ("default"));
-  store_in_alist (&alist, Qname, build_string ("emacs"));
-  store_in_alist (&alist, Qheight, make_number (FRAME_HEIGHT (f)));
-  store_in_alist (&alist, Qwidth, make_number (FRAME_WIDTH (f)));
-  store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
-  store_in_alist (&alist, Qminibuffer, FRAME_MINIBUF_WINDOW (f));
-  store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
-  store_in_alist (&alist, Qmenu_bar_lines, (FRAME_MENU_BAR_LINES (f)));
-
-  return alist;
-}
-
-DEFUN ("modify-frame-parameters", Fmodify_frame_parameters, 
-       Smodify_frame_parameters, 2, 2, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (frame, alist)
-     Lisp_Object frame, alist;
-{
-#ifdef MSDOS
-  if (FRAME_X_P (frame))
-    IT_set_frame_parameters (XFRAME (frame), alist);
-#endif
-  return Qnil;
-}
-
-DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  (frame)
-     Lisp_Object frame;
-{
-  return Qt;
-}
-
-DEFUN ("frame-list", Fframe_list, Sframe_list, 0, 0, 0,
-  /* Don't confuse make-docfile by having two doc strings for this function.
-     make-docfile does not pay attention to #if, for good reason!  */
-  0)
-  ()
-{
-  return Fcons (Fselected_frame (), Qnil);
-}
-
-syms_of_frame ()
-{
-  Qheight = intern ("height");
-  staticpro (&Qheight);
-  Qminibuffer = intern ("minibuffer");
-  staticpro (&Qminibuffer);
-  Qmodeline = intern ("modeline");
-  staticpro (&Qmodeline);
-  Qname = intern ("name");
-  staticpro (&Qname);
-  Qunsplittable = intern ("unsplittable");
-  staticpro (&Qunsplittable);
-  Qmenu_bar_lines = intern ("menu-bar-lines");
-  staticpro (&Qmenu_bar_lines);
-  Qwidth = intern ("width");
-  staticpro (&Qwidth);
-
-  DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
-  /* Don't confuse make-docfile by having two doc strings for this variable.
-     make-docfile does not pay attention to #if, for good reason!  */
-              0);
-  XSETFASTINT (Vterminal_frame, 0);
-
-  defsubr (&Sselected_frame);
-  defsubr (&Swindow_frame);
-  defsubr (&Sframe_first_window);
-  defsubr (&Sframep);
-  defsubr (&Sframe_char_height);
-  defsubr (&Sframe_char_width);
-  defsubr (&Sframe_pixel_height);
-  defsubr (&Sframe_pixel_width);
-  defsubr (&Sset_frame_height);
-  defsubr (&Sset_frame_width);
-  defsubr (&Sset_frame_size);
-  defsubr (&Sset_screen_height);
-  defsubr (&Sset_screen_width);
-  defsubr (&Sframe_height);
-  Ffset (intern ("screen-height"), intern ("frame-height"));
-  defsubr (&Sframe_width);
-  Ffset (intern ("screen-width"), intern ("frame-width"));
-  defsubr (&Smouse_position);
-  defsubr (&Sframe_parameters);
-  defsubr (&Smodify_frame_parameters);
-  defsubr (&Sframe_live_p);
-  defsubr (&Sframe_list);
-
-#ifdef MSDOS
-  /* A comment in dispnew.c says the_only_frame is not protected.  */
-  the_only_frame.face_alist = Qnil;
-  staticpro (&the_only_frame.face_alist);
-  the_only_frame.menu_bar_items = Qnil;
-  staticpro (&the_only_frame.menu_bar_items);
-  the_only_frame.menu_bar_vector = Qnil;
-  staticpro (&the_only_frame.menu_bar_vector);
-  the_only_frame.menu_bar_items = menu_bar_items (Qnil);
-#endif
-}
-
-keys_of_frame ()
-{
-}
-
-#endif /* not MULTI_FRAME */