(text-mode): Contruct paragraph-start so
[bpt/emacs.git] / src / frame.c
index 31b5b85..8298a01 100644 (file)
@@ -1,5 +1,5 @@
 /* Generic frame functions.
-   Copyright (C) 1993, 1994, 1995 Free Software Foundation.
+   Copyright (C) 1993, 1994, 1995, 1997, 1999 Free Software Foundation.
 
 This file is part of GNU Emacs.
 
@@ -22,11 +22,25 @@ Boston, MA 02111-1307, USA.  */
 
 #include <stdio.h>
 #include "lisp.h"
+#include "charset.h"
+#ifdef HAVE_X_WINDOWS
+#include "xterm.h"
+#endif
 #include "frame.h"
+#ifdef HAVE_WINDOW_SYSTEM
+#include "fontset.h"
+#endif
 #include "termhooks.h"
+#include "dispextern.h"
 #include "window.h"
 #ifdef MSDOS
 #include "msdos.h"
+#include "dosfns.h"
+#endif
+
+#ifdef macintosh
+extern struct mac_output *NewMacWindow ();
+extern void DisposeMacWindow (struct mac_output *);
 #endif
 
 /* Evaluate this expression to rebuild the section of syms_of_frame
@@ -73,12 +87,15 @@ Lisp_Object Qname;
 Lisp_Object Qonly;
 Lisp_Object Qunsplittable;
 Lisp_Object Qmenu_bar_lines;
+Lisp_Object Qtool_bar_lines;
 Lisp_Object Qwidth;
 Lisp_Object Qx;
-Lisp_Object Qwin32;
+Lisp_Object Qw32;
 Lisp_Object Qpc;
+Lisp_Object Qmac;
 Lisp_Object Qvisible;
 Lisp_Object Qbuffer_predicate;
+Lisp_Object Qbuffer_list;
 Lisp_Object Qtitle;
 
 Lisp_Object Vterminal_frame;
@@ -108,18 +125,24 @@ syms_of_frame_1 ()
   staticpro (&Qunsplittable);
   Qmenu_bar_lines = intern ("menu-bar-lines");
   staticpro (&Qmenu_bar_lines);
+  Qtool_bar_lines = intern ("tool-bar-lines");
+  staticpro (&Qtool_bar_lines);
   Qwidth = intern ("width");
   staticpro (&Qwidth);
   Qx = intern ("x");
   staticpro (&Qx);
-  Qwin32 = intern ("win32");
-  staticpro (&Qwin32);
+  Qw32 = intern ("w32");
+  staticpro (&Qw32);
   Qpc = intern ("pc");
   staticpro (&Qpc);
+  Qmac = intern ("mac");
+  staticpro (&Qmac);
   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);
 
@@ -160,7 +183,7 @@ set_menu_bar_lines_1 (window, n)
     }
 }
 
-static void
+void
 set_menu_bar_lines (f, value, oldval)
      struct frame *f;
      Lisp_Object value, oldval;
@@ -186,6 +209,7 @@ set_menu_bar_lines (f, value, oldval)
       FRAME_WINDOW_SIZES_CHANGED (f) = 1;
       FRAME_MENU_BAR_LINES (f) = nlines;
       set_menu_bar_lines_1 (f->root_window, nlines - olines);
+      adjust_glyphs (f);
     }
 }
 \f
@@ -221,10 +245,12 @@ See also `frame-live-p'.")
       return Qt;
     case output_x_window:
       return Qx;
-    case output_win32:
-      return Qwin32;
+    case output_w32:
+      return Qw32;
     case output_msdos_raw:
       return Qpc;
+    case output_mac:
+      return Qmac;
     default:
       abort ();
     }
@@ -263,10 +289,12 @@ make_frame (mini_p)
   f = (struct frame *)vec;
   XSETFRAME (frame, f);
 
-  f->cursor_x = 0;
-  f->cursor_y = 0;
-  f->current_glyphs = 0;
-  f->desired_glyphs = 0;
+  f->desired_matrix = 0;
+  f->current_matrix = 0;
+  f->desired_pool = 0;
+  f->current_pool = 0;
+  f->glyphs_initialized_p = 0;
+  f->decode_mode_spec_buffer = 0;
   f->visible = 0;
   f->async_visible = 0;
   f->output_data.nothing = 0;
@@ -286,15 +314,22 @@ make_frame (mini_p)
   f->scroll_bars = Qnil;
   f->condemned_scroll_bars = Qnil;
   f->face_alist = Qnil;
+  f->face_cache = NULL;
   f->menu_bar_items = Qnil;
   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;
+  f->menu_bar_window = Qnil;
+  f->tool_bar_window = Qnil;
+  f->desired_tool_bar_items = f->current_tool_bar_items = Qnil;
+  f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
+  f->n_desired_tool_bar_items = f->n_current_tool_bar_items = 0;
 
   root_window = make_window ();
   if (mini_p)
@@ -341,17 +376,26 @@ make_frame (mini_p)
     /* If buf is a 'hidden' buffer (i.e. one whose name starts with
        a space), try to find another one.  */
     if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
-      buf = Fother_buffer (buf, Qnil);
-    Fset_window_buffer (root_window, buf);
+      buf = Fother_buffer (buf, Qnil, Qnil);
+
+    /* Use set_window_buffer, not Fset_window_buffer, and don't let
+       hooks be run by it.  The reason is that the whole frame/window
+       arrangement is not yet fully intialized at this point.  Windows
+       don't have the right size, glyph matrices aren't initialized
+       etc.  Running Lisp functions at this point surely ends in a
+       SEGV.  */
+    set_window_buffer (root_window, buf, 0);
+    f->buffer_list = Fcons (buf, Qnil);
   }
 
   if (mini_p)
     {
       XWINDOW (mini_window)->buffer = Qt;
-      Fset_window_buffer (mini_window,
-                         (NILP (Vminibuffer_list)
-                          ? get_minibuffer (0)
-                          : Fcar (Vminibuffer_list)));
+      set_window_buffer (mini_window,
+                        (NILP (Vminibuffer_list)
+                         ? get_minibuffer (0)
+                         : Fcar (Vminibuffer_list)),
+                        0);
     }
 
   f->root_window = root_window;
@@ -360,9 +404,14 @@ 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
+#ifdef HAVE_WINDOW_SYSTEM
 /* Make a frame using a separate minibuffer window on another frame.
    MINI_WINDOW is the minibuffer window to use.  nil means use the
    default (the global minibuffer).  */
@@ -456,6 +505,7 @@ make_minibuffer_frame ()
                       : Fcar (Vminibuffer_list)));
   return f;
 }
+#endif /* HAVE_WINDOW_SYSTEM */
 \f
 /* Construct a frame that refers to the terminal (stdin and stdout).  */
 
@@ -488,25 +538,37 @@ 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. */
 #ifdef MSDOS
   f->output_data.x = &the_only_x_display;
   f->output_method = output_msdos_raw;
+#endif /* MSDOS */
+
+#ifdef macintosh
+  f->output_data.mac = NewMacWindow(f);
+  f->output_data.mac->background_pixel = 0xffffff;
+  f->output_data.mac->foreground_pixel = 0;
+  f->output_data.mac->n_param_faces = 0;
+  f->output_data.mac->n_computed_faces = 0;
+  f->output_data.mac->size_computed_faces = 0;  
+  f->output_method = output_mac;
+  f->auto_raise = 1;
+  f->auto_lower = 1;
   init_frame_faces (f);
-#else /* not MSDOS */
+#endif /* macintosh */
+
+#ifndef MSDOS
+#ifndef macintosh
   f->output_data.nothing = 1;  /* Nonzero means frame isn't deleted.  */
 #endif
+#endif
+
+  if (!noninteractive)
+    init_frame_faces (f);
   return f;
 }
 
@@ -521,25 +583,41 @@ Note that changing the size of one terminal frame automatically affects all.")
      Lisp_Object parms;
 {
   struct frame *f;
-  Lisp_Object frame;
+  Lisp_Object frame, tem;
+  struct frame *sf = SELECTED_FRAME ();
 
 #ifdef MSDOS
-  if (selected_frame->output_method != output_msdos_raw)
+  if (sf->output_method != output_msdos_raw)
     abort ();
+#else /* not MSDOS */
+
+#ifdef macintosh
+  if (sf->output_method != output_mac)
+    error ("Not running on a Macintosh screen; cannot make a new Macintosh frame");
 #else
-  if (selected_frame->output_method != output_termcap)
+  if (sf->output_method != output_termcap)
     error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
 #endif
+#endif /* not MSDOS */
 
   f = make_terminal_frame ();
-  change_frame_size (f, FRAME_HEIGHT (selected_frame),
-                    FRAME_WIDTH (selected_frame), 0, 0);
-  remake_frame_glyphs (f);
+
+  change_frame_size (f, FRAME_HEIGHT (sf),
+                    FRAME_WIDTH (sf), 0, 0, 0);
+  adjust_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;
+
+  /* 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);
+  /* Simple Fcopy_alist isn't enough, because we need the contents of
+     the vectors which are the CDRs of associations in face_alist to
+     be copied as well.  */
+  for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
+    XCDR (XCAR (tem)) = Fcopy_sequence (XCDR (XCAR (tem)));
   return frame;
 }
 \f
@@ -548,12 +626,14 @@ do_switch_frame (frame, no_enter, track)
      Lisp_Object frame, no_enter;
      int track;
 {
+  struct frame *sf = SELECTED_FRAME ();
+  
   /* If FRAME is a switch-frame event, extract the frame we should
      switch to.  */
   if (CONSP (frame)
-      && EQ (XCONS (frame)->car, Qswitch_frame)
-      && CONSP (XCONS (frame)->cdr))
-    frame = XCONS (XCONS (frame)->cdr)->car;
+      && EQ (XCAR (frame), Qswitch_frame)
+      && CONSP (XCDR (frame)))
+    frame = XCAR (XCDR (frame));
 
   /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
      a switch-frame event to arrive after a frame is no longer live,
@@ -562,7 +642,7 @@ do_switch_frame (frame, no_enter, track)
   if (! FRAME_LIVE_P (XFRAME (frame)))
     return Qnil;
 
-  if (selected_frame == XFRAME (frame))
+  if (sf == XFRAME (frame))
     return frame;
 
   /* This is too greedy; it causes inappropriate focus redirection
@@ -579,17 +659,17 @@ do_switch_frame (frame, no_enter, track)
     {
       Lisp_Object tail;
 
-      for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
+      for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
        {
          Lisp_Object focus;
 
-         if (!FRAMEP (XCONS (tail)->car))
+         if (!FRAMEP (XCAR (tail)))
            abort ();
 
-         focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
+         focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
 
-         if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
-           Fredirect_frame_focus (XCONS (tail)->car, frame);
+         if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
+           Fredirect_frame_focus (XCAR (tail), frame);
        }
     }
 #else /* ! 0 */
@@ -603,16 +683,16 @@ do_switch_frame (frame, no_enter, track)
       if (FRAMEP (xfocus))
        {
          focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
-         if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
+         if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
            Fredirect_frame_focus (xfocus, frame);
        }
     }
 #endif /* HAVE_X_WINDOWS */
 #endif /* ! 0 */
 
-  selected_frame = XFRAME (frame);
-  if (! FRAME_MINIBUF_ONLY_P (selected_frame))
-    last_nonminibuf_frame = selected_frame;
+  selected_frame = frame;
+  if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
+    last_nonminibuf_frame = XFRAME (selected_frame);
 
   Fselect_window (XFRAME (frame)->selected_window);
 
@@ -671,9 +751,7 @@ DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
   "Return the frame that is now selected.")
   ()
 {
-  Lisp_Object tem;
-  XSETFRAME (tem, selected_frame);
-  return tem;
+  return selected_frame;
 }
 \f
 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
@@ -694,7 +772,7 @@ If omitted, FRAME defaults to the currently selected frame.")
   Lisp_Object w;
 
   if (NILP (frame))
-    w = selected_frame->root_window;
+    w = SELECTED_FRAME ()->root_window;
   else
     {
       CHECK_LIVE_FRAME (frame, 0);
@@ -726,12 +804,17 @@ If omitted, FRAME defaults to the currently selected frame.")
   (frame)
      Lisp_Object frame;
 {
+  Lisp_Object window;
+  
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
+    window = SELECTED_FRAME ()->root_window;
   else
-    CHECK_LIVE_FRAME (frame, 0);
-
-  return XFRAME (frame)->root_window;
+    {
+      CHECK_LIVE_FRAME (frame, 0);
+      window = XFRAME (frame)->root_window;
+    }
+  
+  return window;
 }
 
 DEFUN ("frame-selected-window", Fframe_selected_window,
@@ -741,12 +824,17 @@ If omitted, FRAME defaults to the currently selected frame.")
   (frame)
      Lisp_Object frame;
 {
+  Lisp_Object window;
+  
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
+    window = SELECTED_FRAME ()->selected_window;
   else
-    CHECK_LIVE_FRAME (frame, 0);
+    {
+      CHECK_LIVE_FRAME (frame, 0);
+      window = XFRAME (frame)->selected_window;
+    }
 
-  return XFRAME (frame)->selected_window;
+  return window;
 }
 
 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
@@ -758,16 +846,15 @@ If FRAME is the selected frame, this makes WINDOW the selected window.")
      Lisp_Object frame, window;
 {
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
-  else
-    CHECK_LIVE_FRAME (frame, 0);
-
+    frame = selected_frame;
+  
+  CHECK_LIVE_FRAME (frame, 0);
   CHECK_LIVE_WINDOW (window, 1);
 
   if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
     error ("In `set-frame-selected-window', WINDOW is not on FRAME");
 
-  if (XFRAME (frame) == selected_frame)
+  if (EQ (frame, selected_frame))
     return Fselect_window (window);
 
   return XFRAME (frame)->selected_window = window;
@@ -806,11 +893,11 @@ next_frame (frame, minibuf)
   CHECK_LIVE_FRAME (frame, 0);
 
   while (1)
-    for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
+    for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
       {
        Lisp_Object f;
 
-       f = XCONS (tail)->car;
+       f = XCAR (tail);
 
        if (passed
            && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
@@ -881,11 +968,11 @@ prev_frame (frame, minibuf)
     abort ();
 
   prev = Qnil;
-  for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
+  for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
     {
       Lisp_Object f;
 
-      f = XCONS (tail)->car;
+      f = XCAR (tail);
       if (!FRAMEP (f))
        abort ();
 
@@ -956,13 +1043,10 @@ Otherwise, include all frames.")
   (frame, miniframe)
      Lisp_Object frame, miniframe;
 {
-  Lisp_Object tail;
-
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
-  else
-    CHECK_LIVE_FRAME (frame, 0);
-
+    frame = selected_frame;
+  
+  CHECK_LIVE_FRAME (frame, 0);
   return next_frame (frame, miniframe);
 }
 
@@ -980,13 +1064,9 @@ Otherwise, include all frames.")
   (frame, miniframe)
      Lisp_Object frame, miniframe;
 {
-  Lisp_Object tail;
-
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
-  else
-    CHECK_LIVE_FRAME (frame, 0);
-
+    frame = selected_frame;
+  CHECK_LIVE_FRAME (frame, 0);
   return prev_frame (frame, miniframe);
 }
 \f
@@ -1000,18 +1080,18 @@ other_visible_frames (f)
 {
   /* We know the selected frame is visible,
      so if F is some other frame, it can't be the sole visible one.  */
-  if (f == selected_frame)
+  if (f == SELECTED_FRAME ())
     {
       Lisp_Object frames;
       int count = 0;
 
       for (frames = Vframe_list;
           CONSP (frames);
-          frames = XCONS (frames)->cdr)
+          frames = XCDR (frames))
        {
          Lisp_Object this;
 
-         this = XCONS (frames)->car;
+         this = XCAR (frames);
          /* Verify that the frame's window still exists
             and we can still talk to it.  And note any recent change
             in visibility.  */
@@ -1045,11 +1125,12 @@ but if the second optional argument FORCE is non-nil, you may do so.")
      Lisp_Object frame, force;
 {
   struct frame *f;
+  struct frame *sf = SELECTED_FRAME ();
   int minibuffer_selected;
 
   if (EQ (frame, Qnil))
     {
-      f = selected_frame;
+      f = sf;
       XSETFRAME (frame, f);
     }
   else
@@ -1064,6 +1145,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 (XCDR (Vframe_list)))
+    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)))
@@ -1072,10 +1160,10 @@ but if the second optional argument FORCE is non-nil, you may do so.")
 
       for (frames = Vframe_list;
           CONSP (frames);
-          frames = XCONS (frames)->cdr)
+          frames = XCDR (frames))
        {
          Lisp_Object this;
-         this = XCONS (frames)->car;
+         this = XCAR (frames);
 
          if (! EQ (this, frame)
              && EQ (frame,
@@ -1088,7 +1176,7 @@ 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)
+  if (f == sf)
     {
       Lisp_Object tail, frame1;
 
@@ -1106,14 +1194,15 @@ but if the second optional argument FORCE is non-nil, you may do so.")
        }
 
       do_switch_frame (frame1, Qnil, 0);
+      sf = SELECTED_FRAME ();
     }
 
   /* Don't allow minibuf_window to remain on a deleted frame.  */
   if (EQ (f->minibuffer_window, minibuf_window))
     {
-      Fset_window_buffer (selected_frame->minibuffer_window,
+      Fset_window_buffer (sf->minibuffer_window,
                          XWINDOW (minibuf_window)->buffer);
-      minibuf_window = selected_frame->minibuffer_window;
+      minibuf_window = sf->minibuffer_window;
 
       /* If the dying minibuffer window was selected,
         select the new one.  */
@@ -1127,6 +1216,12 @@ but if the second optional argument FORCE is non-nil, you may do so.")
     x_clear_frame_selections (f);
 #endif
 
+  /* Free glyphs. 
+     This function must be called before the window tree of the 
+     frame is deleted because windows contain dynamically allocated
+     memory. */
+  free_glyphs (f);
+
   /* Mark all the windows that used to be on FRAME as deleted, and then
      remove the reference to them.  */
   delete_all_subwindows (XWINDOW (f->root_window));
@@ -1136,21 +1231,22 @@ but if the second optional argument FORCE is non-nil, you may do so.")
   FRAME_SET_VISIBLE (f, 0);
 
   if (f->namebuf)
-    free (f->namebuf);
-  if (FRAME_CURRENT_GLYPHS (f))
-    free_frame_glyphs (f, FRAME_CURRENT_GLYPHS (f));
-  if (FRAME_DESIRED_GLYPHS (f))
-    free_frame_glyphs (f, FRAME_DESIRED_GLYPHS (f));
-  if (FRAME_TEMP_GLYPHS (f))
-    free_frame_glyphs (f, FRAME_TEMP_GLYPHS (f));
+    xfree (f->namebuf);
   if (FRAME_INSERT_COST (f))
-    free (FRAME_INSERT_COST (f));
+    xfree (FRAME_INSERT_COST (f));
   if (FRAME_DELETEN_COST (f))
-    free (FRAME_DELETEN_COST (f));
+    xfree (FRAME_DELETEN_COST (f));
   if (FRAME_INSERTN_COST (f))
-    free (FRAME_INSERTN_COST (f));
+    xfree (FRAME_INSERTN_COST (f));
   if (FRAME_DELETE_COST (f))
-    free (FRAME_DELETE_COST (f));
+    xfree (FRAME_DELETE_COST (f));
+  if (FRAME_MESSAGE_BUF (f))
+    xfree (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
@@ -1164,6 +1260,14 @@ but if the second optional argument FORCE is non-nil, you may do so.")
     x_destroy_window (f);
 #endif
 
+/* Done by x_destroy_window above already */
+#if 0
+#ifdef macintosh
+  if (FRAME_MAC_P (f))
+    DisposeMacWindow (f->output_data.mac);
+#endif
+#endif
+
   f->output_data.nothing = 0;
 
   /* If we've deleted the last_nonminibuf_frame, then try to find
@@ -1176,9 +1280,9 @@ but if the second optional argument FORCE is non-nil, you may do so.")
 
       for (frames = Vframe_list;
           CONSP (frames);
-          frames = XCONS (frames)->cdr)
+          frames = XCDR (frames))
        {
-         f = XFRAME (XCONS (frames)->car);
+         f = XFRAME (XCAR (frames));
          if (!FRAME_MINIBUF_ONLY_P (f))
            {
              last_nonminibuf_frame = f;
@@ -1204,12 +1308,12 @@ but if the second optional argument FORCE is non-nil, you may do so.")
 
       for (frames = Vframe_list;
           CONSP (frames);
-          frames = XCONS (frames)->cdr)
+          frames = XCDR (frames))
        {
          Lisp_Object this;
          struct frame *f1;
 
-         this = XCONS (frames)->car;
+         this = XCAR (frames);
          if (!FRAMEP (this))
            abort ();
          f1 = XFRAME (this);
@@ -1270,13 +1374,13 @@ and nil for X and Y.")
   int col, row;
   unsigned long long_dummy;
 
-  f = selected_frame;
+  f = SELECTED_FRAME ();
   x = y = Qnil;
 
 #ifdef HAVE_MOUSE
   /* It's okay for the hook to refrain from storing anything.  */
   if (mouse_position_hook)
-    (*mouse_position_hook) (&f, 0,
+    (*mouse_position_hook) (&f, -1,
                            &lispy_dummy, &party_dummy,
                            &x, &y,
                            &long_dummy);
@@ -1307,16 +1411,15 @@ and nil for X and Y.")
   Lisp_Object lispy_dummy;
   enum scroll_bar_part party_dummy;
   Lisp_Object x, y;
-  int col, row;
   unsigned long long_dummy;
 
-  f = selected_frame;
+  f = SELECTED_FRAME ();
   x = y = Qnil;
 
 #ifdef HAVE_MOUSE
   /* It's okay for the hook to refrain from storing anything.  */
   if (mouse_position_hook)
-    (*mouse_position_hook) (&f, 0,
+    (*mouse_position_hook) (&f, -1,
                            &lispy_dummy, &party_dummy,
                            &x, &y,
                            &long_dummy);
@@ -1327,7 +1430,11 @@ 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\
-Note, this is a no-op for an X frame that is not visible.\n\
+Coordinates are relative to the frame, not a window,\n\
+so the coordinates of the top left character in the frame\n\
+may be nonzero due to left-hand scroll bars or the menu bar.\n\
+\n\
+This function 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))")
@@ -1342,7 +1449,7 @@ before calling this function on it, like this.\n\
 #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);
+    x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
 #else
 #if defined (MSDOS) && defined (HAVE_MOUSE)
   if (FRAME_MSDOS_P (XFRAME (frame)))
@@ -1374,7 +1481,7 @@ before calling this function on it, like this.\n\
 #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);
+    x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
 #else
 #if defined (MSDOS) && defined (HAVE_MOUSE)
   if (FRAME_MSDOS_P (XFRAME (frame)))
@@ -1388,6 +1495,8 @@ before calling this function on it, like this.\n\
   return Qnil;
 }
 \f
+static void make_frame_visible_1 P_ ((Lisp_Object));
+
 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
        0, 1, "",
   "Make the frame FRAME visible (assuming it is an X-window).\n\
@@ -1396,7 +1505,7 @@ If omitted, FRAME defaults to the currently selected frame.")
      Lisp_Object frame;
 {
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
+    frame = selected_frame;
 
   CHECK_LIVE_FRAME (frame, 0);
 
@@ -1409,12 +1518,37 @@ If omitted, FRAME defaults to the currently selected frame.")
     }
 #endif
 
+  make_frame_visible_1 (XFRAME (frame)->root_window);
+
   /* Make menu bar update for the Buffers and Frams menus.  */
   windows_or_buffers_changed++;
 
   return frame;
 }
 
+/* Update the display_time slot of the buffers shown in WINDOW
+   and all its descendents.  */
+
+static void
+make_frame_visible_1 (window)
+     Lisp_Object window;
+{
+  struct window *w;
+
+  for (;!NILP (window); window = w->next)
+    {
+      w = XWINDOW (window);
+
+      if (!NILP (w->buffer))
+       XBUFFER (w->buffer)->display_time = Fcurrent_time ();
+
+      if (!NILP (w->vchild))
+       make_frame_visible_1 (w->vchild);
+      if (!NILP (w->hchild))
+       make_frame_visible_1 (w->hchild);
+    }
+}
+
 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
        0, 2, "",
   "Make the frame FRAME invisible (assuming it is an X-window).\n\
@@ -1425,7 +1559,7 @@ but if the second optional argument FORCE is non-nil, you may do so.")
      Lisp_Object frame, force;
 {
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
+    frame = selected_frame;
 
   CHECK_LIVE_FRAME (frame, 0);
 
@@ -1434,16 +1568,17 @@ 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)
+  if (EQ (frame, selected_frame))
     do_switch_frame (next_frame (frame, Qt), Qnil, 0)
 #endif
 
   /* Don't allow minibuf_window to remain on a deleted frame.  */
   if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
     {
-      Fset_window_buffer (selected_frame->minibuffer_window,
+      struct frame *sf = XFRAME (selected_frame);
+      Fset_window_buffer (sf->minibuffer_window,
                          XWINDOW (minibuf_window)->buffer);
-      minibuf_window = selected_frame->minibuffer_window;
+      minibuf_window = sf->minibuffer_window;
     }
 
   /* I think this should be done with a hook.  */
@@ -1466,22 +1601,23 @@ If omitted, FRAME defaults to the currently selected frame.")
      Lisp_Object frame;
 {
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
+    frame = selected_frame;
   
   CHECK_LIVE_FRAME (frame, 0);
 
 #if 0 /* This isn't logically necessary, and it can do GC.  */
   /* Don't let the frame remain selected.  */
-  if (XFRAME (frame) == selected_frame)
+  if (EQ (frame, selected_frame))
     Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
 #endif
 
   /* Don't allow minibuf_window to remain on a deleted frame.  */
   if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
     {
-      Fset_window_buffer (selected_frame->minibuffer_window,
+      struct frame *sf = XFRAME (selected_frame);
+      Fset_window_buffer (sf->minibuffer_window,
                          XWINDOW (minibuf_window)->buffer);
-      minibuf_window = selected_frame->minibuffer_window;
+      minibuf_window = sf->minibuffer_window;
     }
 
   /* I think this should be done with a hook.  */
@@ -1526,9 +1662,9 @@ DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
   Lisp_Object value;
 
   value = Qnil;
-  for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
+  for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
     {
-      frame = XCONS (tail)->car;
+      frame = XCAR (tail);
       if (!FRAMEP (frame))
        continue;
       f = XFRAME (frame);
@@ -1549,7 +1685,7 @@ doesn't support multiple overlapping frames, this function does nothing.")
      Lisp_Object frame;
 {
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
+    frame = selected_frame;
 
   CHECK_LIVE_FRAME (frame, 0);
 
@@ -1572,7 +1708,7 @@ doesn't support multiple overlapping frames, this function does nothing.")
      Lisp_Object frame;
 {
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
+    frame = selected_frame;
 
   CHECK_LIVE_FRAME (frame, 0);
   
@@ -1660,9 +1796,59 @@ get_frame_param (frame, prop)
 /* Return the buffer-predicate of the selected frame.  */
 
 Lisp_Object
-frame_buffer_predicate ()
+frame_buffer_predicate (frame)
+     Lisp_Object frame;
+{
+  return XFRAME (frame)->buffer_predicate;
+}
+
+/* Return the buffer-list of the selected frame.  */
+
+Lisp_Object
+frame_buffer_list (frame)
+     Lisp_Object frame;
+{
+  return XFRAME (frame)->buffer_list;
+}
+
+/* Set the buffer-list of the selected frame.  */
+
+void
+set_frame_buffer_list (frame, list)
+     Lisp_Object frame, list;
+{
+  XFRAME (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;
 {
-  return selected_frame->buffer_predicate;
+  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.
@@ -1682,6 +1868,66 @@ store_in_alist (alistptr, prop, val)
     Fsetcdr (tem, val);
 }
 
+static int
+frame_name_fnn_p (str, len)
+     char *str;
+     int len;
+{
+  if (len > 1 && str[0] == 'F')
+    {
+      char *end_ptr;
+
+      strtol (str + 1, &end_ptr, 10);
+
+      if (end_ptr == str + len)
+       return 1;
+    }
+  return 0;
+}
+
+/* Set the name of the terminal frame.  Also used by MSDOS frames.
+   Modeled after x_set_name which is used for WINDOW frames.  */
+
+void
+set_term_frame_name (f, name)
+     struct frame *f;
+     Lisp_Object name;
+{
+  f->explicit_name = ! NILP (name);
+
+  /* If NAME is nil, set the name to F<num>.  */
+  if (NILP (name))
+    {
+      char namebuf[20];
+
+      /* Check for no change needed in this very common case
+        before we do any consing.  */
+      if (frame_name_fnn_p (XSTRING (f->name)->data,
+                           STRING_BYTES (XSTRING (f->name))))
+       return;
+
+      terminal_frame_count++;
+      sprintf (namebuf, "F%d", terminal_frame_count);
+      name = build_string (namebuf);
+    }
+  else
+    {
+      CHECK_STRING (name, 0);
+
+      /* Don't change the name if it's already NAME.  */
+      if (! NILP (Fstring_equal (name, f->name)))
+       return;
+
+      /* Don't allow the user to set the frame name to F<num>, so it
+        doesn't clash with the names we generate for terminal frames.  */
+      if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name))))
+       error ("Frame names of the form F<num> are usurped by Emacs");
+    }
+
+  f->name = name;
+  update_mode_lines = 1;
+}
+
 void
 store_frame_param (f, prop, val)
      struct frame *f;
@@ -1689,6 +1935,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);
@@ -1699,15 +1951,19 @@ store_frame_param (f, prop, val)
     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, Qmenu_bar_lines))
+       set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
+      else if (EQ (prop, Qname))
+       set_term_frame_name (f, val);
+    }
 
   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)
+      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");
 
@@ -1729,12 +1985,10 @@ If FRAME is omitted, return information on the currently selected frame.")
   int height, width;
 
   if (EQ (frame, Qnil))
-    f = selected_frame;
-  else
-    {
-      CHECK_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+
+  CHECK_FRAME (frame, 0);
+  f = XFRAME (frame);
 
   if (!FRAME_LIVE_P (f))
     return Qnil;
@@ -1743,18 +1997,19 @@ If FRAME is omitted, return information on the currently selected frame.")
 #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"
-       };
+      int fg = FRAME_FOREGROUND_PIXEL (f);
+      int bg = FRAME_BACKGROUND_PIXEL (f);
+      Lisp_Object qreverse = intern ("reverse");
+      int rv =
+       !NILP (Fassq (qreverse, alist))
+       || !NILP (Fassq (qreverse, Vdefault_frame_alist));
+
       store_in_alist (&alist, intern ("foreground-color"),
-                     build_string (colornames[FRAME_FOREGROUND_PIXEL (f)]));
+                     build_string (msdos_stdcolor_name (rv ? bg : fg)));
       store_in_alist (&alist, intern ("background-color"),
-                     build_string (colornames[FRAME_BACKGROUND_PIXEL (f)]));
+                     build_string (msdos_stdcolor_name (rv ? fg : bg)));
     }
-  store_in_alist (&alist, intern ("font"), build_string ("default"));
+  store_in_alist (&alist, intern ("font"), build_string ("ms-dos"));
 #endif
   store_in_alist (&alist, Qname, f->name);
   height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
@@ -1767,6 +2022,8 @@ If FRAME is omitted, return information on the currently selected frame.")
                   : 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 (selected_frame));
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -1795,15 +2052,12 @@ so that `frame-parameters' will return them.")
      Lisp_Object frame, alist;
 {
   FRAME_PTR f;
-  register Lisp_Object tail, elt, prop, val;
+  register Lisp_Object tail, prop, val;
 
   if (EQ (frame, Qnil))
-    f = selected_frame;
-  else
-    {
-      CHECK_LIVE_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+  CHECK_LIVE_FRAME (frame, 0);
+  f = XFRAME (frame);
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -1816,6 +2070,12 @@ so that `frame-parameters' will return them.")
     IT_set_frame_parameters (f, alist);
   else
 #endif
+#ifdef macintosh
+  if (FRAME_MAC_P (f))
+    mac_set_frame_parameters (f, alist);
+  else
+#endif
+
     {
       int length = XINT (Flength (alist));
       int i;
@@ -1829,7 +2089,7 @@ so that `frame-parameters' will return them.")
       i = 0;
       for (tail = alist; CONSP (tail); tail = Fcdr (tail))
        {
-         Lisp_Object elt, prop, val;
+         Lisp_Object elt;
 
          elt = Fcar (tail);
          parms[i] = Fcar (elt);
@@ -1860,12 +2120,9 @@ For a terminal frame, the value is always 1.")
   struct frame *f;
 
   if (NILP (frame))
-    f = selected_frame;
-  else
-    {
-      CHECK_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+  CHECK_FRAME (frame, 0);
+  f = XFRAME (frame);
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
@@ -1889,12 +2146,9 @@ For a terminal screen, the value is always 1.")
   struct frame *f;
 
   if (NILP (frame))
-    f = selected_frame;
-  else
-    {
-      CHECK_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+  CHECK_FRAME (frame, 0);
+  f = XFRAME (frame);
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
@@ -1907,6 +2161,8 @@ For a terminal screen, the value is always 1.")
 DEFUN ("frame-pixel-height", Fframe_pixel_height, 
        Sframe_pixel_height, 0, 1, 0,
   "Return a FRAME's height in pixels.\n\
+This counts only the height available for text lines,\n\
+not menu bars on window-system Emacs frames.\n\
 For a terminal frame, the result really gives the height in characters.\n\
 If FRAME is omitted, the selected frame is used.")
   (frame)
@@ -1915,12 +2171,9 @@ If FRAME is omitted, the selected frame is used.")
   struct frame *f;
 
   if (NILP (frame))
-    f = selected_frame;
-  else
-    {
-      CHECK_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+  CHECK_FRAME (frame, 0);
+  f = XFRAME (frame);
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
@@ -1941,12 +2194,9 @@ If FRAME is omitted, the selected frame is used.")
   struct frame *f;
 
   if (NILP (frame))
-    f = selected_frame;
-  else
-    {
-      CHECK_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+  CHECK_FRAME (frame, 0);
+  f = XFRAME (frame);
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
@@ -1967,12 +2217,9 @@ but that the idea of the actual height of the frame should not be changed.")
 
   CHECK_NUMBER (lines, 0);
   if (NILP (frame))
-    f = selected_frame;
-  else
-    {
-      CHECK_LIVE_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+  CHECK_LIVE_FRAME (frame, 0);
+  f = XFRAME (frame);
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -1980,10 +2227,11 @@ but that the idea of the actual height of the frame should not be changed.")
     {
       if (XINT (lines) != f->height)
        x_set_window_size (f, 1, f->width, XINT (lines));
+      do_pending_window_change (0);
     }
   else
 #endif
-    change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0);
+    change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
   return Qnil;
 }
 
@@ -1997,12 +2245,9 @@ but that the idea of the actual width of the frame should not be changed.")
   register struct frame *f;
   CHECK_NUMBER (cols, 0);
   if (NILP (frame))
-    f = selected_frame;
-  else
-    {
-      CHECK_LIVE_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+  CHECK_LIVE_FRAME (frame, 0);
+  f = XFRAME (frame);
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -2010,10 +2255,11 @@ but that the idea of the actual width of the frame should not be changed.")
     {
       if (XINT (cols) != f->width)
        x_set_window_size (f, 1, XINT (cols), f->height);
+      do_pending_window_change (0);
     }
   else
 #endif
-    change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
+    change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
   return Qnil;
 }
 
@@ -2023,7 +2269,6 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
      Lisp_Object frame, cols, rows;
 {
   register struct frame *f;
-  int mask;
 
   CHECK_LIVE_FRAME (frame, 0);
   CHECK_NUMBER (cols, 2);
@@ -2037,10 +2282,11 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
       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));
+      do_pending_window_change (0);
     }
   else
 #endif
-    change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
+    change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
 
   return Qnil;
 }
@@ -2055,7 +2301,6 @@ the rightmost or bottommost possible position (that stays within the screen).")
      Lisp_Object frame, xoffset, yoffset;
 {
   register struct frame *f;
-  int mask;
 
   CHECK_LIVE_FRAME (frame, 0);
   CHECK_NUMBER (xoffset, 1);
@@ -2072,6 +2317,7 @@ the rightmost or bottommost possible position (that stays within the screen).")
 }
 
 \f
+void
 syms_of_frame ()
 {
   syms_of_frame_1 ();
@@ -2144,6 +2390,7 @@ displayed.");
   defsubr (&Sset_frame_position);
 }
 
+void
 keys_of_frame ()
 {
   initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");