Remove HAVE_MOUSE; see https://lists.gnu.org/archive/html/emacs-devel/2012-10/msg0040...
[bpt/emacs.git] / src / frame.c
index 308179e..3501fc3 100644 (file)
@@ -19,22 +19,21 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 
+#define FRAME_INLINE EXTERN_INLINE
+
 #include <stdio.h>
-#include <ctype.h>
 #include <errno.h>
 #include <limits.h>
-#include <setjmp.h>
+
+#include <c-ctype.h>
+
 #include "lisp.h"
 #include "character.h"
-#ifdef HAVE_X_WINDOWS
-#include "xterm.h"
-#endif
-#ifdef WINDOWSNT
-#include "w32term.h"
-#endif
-#ifdef HAVE_NS
-#include "nsterm.h"
-#endif
+
+#ifdef HAVE_WINDOW_SYSTEM
+#include TERM_HEADER
+#endif /* HAVE_WINDOW_SYSTEM */
+
 #include "buffer.h"
 /* These help us bind and responding to switch-frame events.  */
 #include "commands.h"
@@ -54,18 +53,13 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "dosfns.h"
 #endif
 
-
-#ifdef HAVE_WINDOW_SYSTEM
-
-#endif
-
 #ifdef HAVE_NS
 Lisp_Object Qns_parse_geometry;
 #endif
 
 Lisp_Object Qframep, Qframe_live_p;
 Lisp_Object Qicon, Qmodeline;
-Lisp_Object Qonly;
+Lisp_Object Qonly, Qnone;
 Lisp_Object Qx, Qw32, Qmac, Qpc, Qns;
 Lisp_Object Qvisible;
 Lisp_Object Qdisplay_type;
@@ -125,22 +119,51 @@ static Lisp_Object Qdelete_frame_functions;
 static void x_report_frame_params (struct frame *, Lisp_Object *);
 #endif
 
-\f
+/* These setters are used only in this file, so they can be private.  */
+static void
+fset_buffer_predicate (struct frame *f, Lisp_Object val)
+{
+  f->buffer_predicate = val;
+}
+static void
+fset_minibuffer_window (struct frame *f, Lisp_Object val)
+{
+  f->minibuffer_window = val;
+}
+
+struct frame *
+decode_live_frame (register Lisp_Object frame)
+{
+  if (NILP (frame))
+    frame = selected_frame;
+  CHECK_LIVE_FRAME (frame);
+  return XFRAME (frame);
+}
+
+struct frame *
+decode_any_frame (register Lisp_Object frame)
+{
+  if (NILP (frame))
+    frame = selected_frame;
+  CHECK_FRAME (frame);
+  return XFRAME (frame);
+}
+
 static void
 set_menu_bar_lines_1 (Lisp_Object window, int n)
 {
   struct window *w = XWINDOW (window);
 
   w->last_modified = 0;
-  XSETFASTINT (WVAR (w, top_line), XFASTINT (WVAR (w, top_line)) + n);
-  XSETFASTINT (WVAR (w, total_lines), XFASTINT (WVAR (w, total_lines)) - n);
+  wset_top_line (w, make_number (XFASTINT (w->top_line) + n));
+  wset_total_lines (w, make_number (XFASTINT (w->total_lines) - n));
 
   /* Handle just the top child in a vertical split.  */
-  if (!NILP (WVAR (w, vchild)))
-    set_menu_bar_lines_1 (WVAR (w, vchild), n);
+  if (!NILP (w->vchild))
+    set_menu_bar_lines_1 (w->vchild, n);
 
   /* Adjust all children in a horizontal split.  */
-  for (window = WVAR (w, hchild); !NILP (window); window = WVAR (w, next))
+  for (window = w->hchild; !NILP (window); window = w->next)
     {
       w = XWINDOW (window);
       set_menu_bar_lines_1 (window, n);
@@ -170,7 +193,7 @@ set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
       windows_or_buffers_changed++;
       FRAME_WINDOW_SIZES_CHANGED (f) = 1;
       FRAME_MENU_BAR_LINES (f) = nlines;
-      set_menu_bar_lines_1 (FVAR (f, root_window), nlines - olines);
+      set_menu_bar_lines_1 (f->root_window, nlines - olines);
       adjust_glyphs (f);
     }
 }
@@ -207,7 +230,7 @@ See also `frame-live-p'.  */)
     case output_ns:
       return Qns;
     default:
-      abort ();
+      emacs_abort ();
     }
 }
 
@@ -269,7 +292,7 @@ make_frame (int mini_p)
 
   /* Initialize Lisp data.  Note that allocate_frame initializes all
      Lisp data to nil, so do it only for slots which should not be nil.  */
-  FVAR (f, tool_bar_position) = Qtop;
+  fset_tool_bar_position (f, Qtop);
 
   /* Initialize non-Lisp data.  Note that allocate_frame zeroes out all
      non-Lisp data, so do it only for slots which should not be zero.
@@ -289,20 +312,20 @@ make_frame (int mini_p)
   if (mini_p)
     {
       mini_window = make_window ();
-      WVAR (XWINDOW (root_window), next) = mini_window;
-      WVAR (XWINDOW (mini_window), prev) = root_window;
+      wset_next (XWINDOW (root_window), mini_window);
+      wset_prev (XWINDOW (mini_window), root_window);
       XWINDOW (mini_window)->mini = 1;
-      WVAR (XWINDOW (mini_window), frame) = frame;
-      FVAR (f, minibuffer_window) = mini_window;
+      wset_frame (XWINDOW (mini_window), frame);
+      fset_minibuffer_window (f, mini_window);
     }
   else
     {
       mini_window = Qnil;
-      WVAR (XWINDOW (root_window), next) = Qnil;
-      FVAR (f, minibuffer_window) = Qnil;
+      wset_next (XWINDOW (root_window), Qnil);
+      fset_minibuffer_window (f, Qnil);
     }
 
-  WVAR (XWINDOW (root_window), frame) = frame;
+  wset_frame (XWINDOW (root_window), frame);
 
   /* 10 is arbitrary,
      just so that there is "something there."
@@ -311,21 +334,21 @@ make_frame (int mini_p)
   SET_FRAME_COLS (f, 10);
   FRAME_LINES (f) = 10;
 
-  XSETFASTINT (WVAR (XWINDOW (root_window), total_cols), 10);
-  XSETFASTINT (WVAR (XWINDOW (root_window), total_lines), (mini_p ? 9 : 10));
+  wset_total_cols (XWINDOW (root_window), make_number (10));
+  wset_total_lines (XWINDOW (root_window), make_number (mini_p ? 9 : 10));
 
   if (mini_p)
     {
-      XSETFASTINT (WVAR (XWINDOW (mini_window), total_cols), 10);
-      XSETFASTINT (WVAR (XWINDOW (mini_window), top_line), 9);
-      XSETFASTINT (WVAR (XWINDOW (mini_window), total_lines), 1);
+      wset_total_cols (XWINDOW (mini_window), make_number (10));
+      wset_top_line (XWINDOW (mini_window), make_number (9));
+      wset_total_lines (XWINDOW (mini_window), make_number (1));
     }
 
   /* Choose a buffer for the frame's root window.  */
   {
     Lisp_Object buf;
 
-    WVAR (XWINDOW (root_window), buffer) = Qt;
+    wset_buffer (XWINDOW (root_window), Qt);
     buf = Fcurrent_buffer ();
     /* If buf is a 'hidden' buffer (i.e. one whose name starts with
        a space), try to find another one.  */
@@ -339,12 +362,12 @@ make_frame (int mini_p)
        etc.  Running Lisp functions at this point surely ends in a
        SEGV.  */
     set_window_buffer (root_window, buf, 0, 0);
-    FVAR (f, buffer_list) = Fcons (buf, Qnil);
+    fset_buffer_list (f, Fcons (buf, Qnil));
   }
 
   if (mini_p)
     {
-      WVAR (XWINDOW (mini_window), buffer) = Qt;
+      wset_buffer (XWINDOW (mini_window), Qt);
       set_window_buffer (mini_window,
                         (NILP (Vminibuffer_list)
                          ? get_minibuffer (0)
@@ -352,11 +375,11 @@ make_frame (int mini_p)
                         0, 0);
     }
 
-  FVAR (f, root_window) = root_window;
-  FVAR (f, selected_window) = root_window;
+  fset_root_window (f, root_window);
+  fset_selected_window (f, root_window);
   /* Make sure this window seems more recently used than
      a newly-created, never-selected window.  */
-  XWINDOW (FVAR (f, selected_window))->use_time = ++window_select_count;
+  XWINDOW (f->selected_window)->use_time = ++window_select_count;
 
   return f;
 }
@@ -376,7 +399,7 @@ make_frame_without_minibuffer (register Lisp_Object mini_window, KBOARD *kb, Lis
     CHECK_LIVE_WINDOW (mini_window);
 
   if (!NILP (mini_window)
-      && FRAME_KBOARD (XFRAME (WVAR (XWINDOW (mini_window), frame))) != kb)
+      && FRAME_KBOARD (XFRAME (XWINDOW (mini_window)->frame)) != kb)
     error ("Frame and minibuffer must be on the same terminal");
 
   /* Make a frame containing just a root window.  */
@@ -393,24 +416,26 @@ make_frame_without_minibuffer (register Lisp_Object mini_window, KBOARD *kb, Lis
           XSETFRAME (frame_dummy, f);
           GCPRO1 (frame_dummy);
          /* If there's no minibuffer frame to use, create one.  */
-         KVAR (kb, Vdefault_minibuffer_frame) =
-           call1 (intern ("make-initial-minibuffer-frame"), display);
+         kset_default_minibuffer_frame
+           (kb, call1 (intern ("make-initial-minibuffer-frame"), display));
           UNGCPRO;
        }
 
-      mini_window = FVAR (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)),
-                         minibuffer_window);
+      mini_window
+       = XFRAME (KVAR (kb, Vdefault_minibuffer_frame))->minibuffer_window;
     }
 
-  FVAR (f, minibuffer_window) = mini_window;
+  fset_minibuffer_window (f, mini_window);
 
   /* Make the chosen minibuffer window display the proper minibuffer,
      unless it is already showing a minibuffer.  */
-  if (NILP (Fmemq (WVAR (XWINDOW (mini_window), buffer), Vminibuffer_list)))
-    Fset_window_buffer (mini_window,
-                       (NILP (Vminibuffer_list)
-                        ? get_minibuffer (0)
-                        : Fcar (Vminibuffer_list)), Qnil);
+  if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
+    /* Use set_window_buffer instead of Fset_window_buffer (see
+       discussion of bug#11984, bug#12025, bug#12026).  */
+    set_window_buffer (mini_window,
+                      (NILP (Vminibuffer_list)
+                       ? get_minibuffer (0)
+                       : Fcar (Vminibuffer_list)), 0, 0);
   return f;
 }
 
@@ -437,18 +462,21 @@ make_minibuffer_frame (void)
      Avoid infinite looping on the window chain by marking next pointer
      as nil. */
 
-  mini_window = FVAR (f, minibuffer_window) = FVAR (f, root_window);
+  mini_window = f->root_window;
+  fset_minibuffer_window (f, mini_window);
   XWINDOW (mini_window)->mini = 1;
-  WVAR (XWINDOW (mini_window), next) = Qnil;
-  WVAR (XWINDOW (mini_window), prev) = Qnil;
-  WVAR (XWINDOW (mini_window), frame) = frame;
+  wset_next (XWINDOW (mini_window), Qnil);
+  wset_prev (XWINDOW (mini_window), Qnil);
+  wset_frame (XWINDOW (mini_window), frame);
 
   /* Put the proper buffer in that window.  */
 
-  Fset_window_buffer (mini_window,
-                     (NILP (Vminibuffer_list)
-                      ? get_minibuffer (0)
-                      : Fcar (Vminibuffer_list)), Qnil);
+  /* Use set_window_buffer instead of Fset_window_buffer (see
+     discussion of bug#11984, bug#12025, bug#12026).  */
+  set_window_buffer (mini_window,
+                    (NILP (Vminibuffer_list)
+                     ? get_minibuffer (0)
+                     : Fcar (Vminibuffer_list)), 0, 0);
   return f;
 }
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -478,7 +506,7 @@ make_initial_frame (void)
   Vframe_list = Fcons (frame, Vframe_list);
 
   tty_frame_count = 1;
-  FVAR (f, name) = build_pure_c_string ("F1");
+  fset_name (f, build_pure_c_string ("F1"));
 
   f->visible = 1;
   f->async_visible = 1;
@@ -491,7 +519,6 @@ make_initial_frame (void)
   FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
   FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
 
-  FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
   FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
 
   /* The default value of menu-bar-mode is t.  */
@@ -519,7 +546,7 @@ make_terminal_frame (struct terminal *terminal)
   XSETFRAME (frame, f);
   Vframe_list = Fcons (frame, Vframe_list);
 
-  FVAR (f, name) = make_formatted_string (name, "F%"pMd, ++tty_frame_count);
+  fset_name (f, make_formatted_string (name, "F%"pMd, ++tty_frame_count));
 
   f->visible = 1;              /* FRAME_SET_VISIBLE wd set frame_garbaged. */
   f->async_visible = 1;                /* Don't let visible be cleared later. */
@@ -540,7 +567,6 @@ make_terminal_frame (struct terminal *terminal)
   FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
 #endif /* not MSDOS */
 
-  FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
   FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
   FRAME_MENU_BAR_LINES(f) = NILP (Vmenu_bar_mode) ? 0 : 1;
 
@@ -570,7 +596,7 @@ get_future_frame_param (Lisp_Object parameter,
 
   result = Fassq (parameter, supplied_parms);
   if (NILP (result))
-    result = Fassq (parameter, FVAR (XFRAME (selected_frame), param_alist));
+    result = Fassq (parameter, XFRAME (selected_frame)->param_alist);
   if (NILP (result) && current_value != NULL)
     result = build_string (current_value);
   if (!NILP (result) && !STRINGP (result))
@@ -608,7 +634,7 @@ affects all frames on the same terminal device.  */)
 #ifdef MSDOS
   if (sf->output_method != output_msdos_raw
       && sf->output_method != output_termcap)
-    abort ();
+    emacs_abort ();
 #else /* not MSDOS */
 
 #ifdef WINDOWSNT                           /* This should work now! */
@@ -621,7 +647,7 @@ affects all frames on the same terminal device.  */)
     Lisp_Object terminal;
 
     terminal = Fassq (Qterminal, parms);
-    if (!NILP (terminal))
+    if (CONSP (terminal))
       {
         terminal = XCDR (terminal);
         t = get_terminal (terminal, 1);
@@ -689,11 +715,11 @@ affects all frames on the same terminal device.  */)
 
   /* Make the frame face alist be frame-specific, so that each
      frame could change its face definitions independently.  */
-  FVAR (f, face_alist) = Fcopy_alist (FVAR (sf, face_alist));
+  fset_face_alist (f, 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 = FVAR (f, face_alist); CONSP (tem); tem = XCDR (tem))
+  for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
     XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem))));
   return frame;
 }
@@ -755,7 +781,7 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
          Lisp_Object focus;
 
          if (!FRAMEP (XCAR (tail)))
-           abort ();
+           emacs_abort ();
 
          focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
 
@@ -797,7 +823,7 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
   if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
     last_nonminibuf_frame = XFRAME (selected_frame);
 
-  Fselect_window (FVAR (XFRAME (frame), selected_window), norecord);
+  Fselect_window (XFRAME (frame)->selected_window, norecord);
 
   /* We want to make sure that the next event generates a frame-switch
      event to the appropriate frame.  This seems kludgy to me, but
@@ -843,7 +869,7 @@ to that frame.  */)
   (Lisp_Object event)
 {
   /* Preserve prefix arg that the command loop just cleared.  */
-  KVAR (current_kboard, Vprefix_arg) = Vcurrent_prefix_arg;
+  kset_prefix_arg (current_kboard, Vcurrent_prefix_arg);
   Frun_hooks (1, &Qmouse_leave_buffer_hook);
   return do_switch_frame (event, 0, 0, Qnil);
 }
@@ -880,24 +906,20 @@ DEFUN ("frame-list", Fframe_list, Sframe_list,
 static Lisp_Object
 next_frame (Lisp_Object frame, Lisp_Object minibuf)
 {
-  Lisp_Object tail;
+  Lisp_Object f, tail;
   int passed = 0;
 
   /* There must always be at least one frame in Vframe_list.  */
   if (! CONSP (Vframe_list))
-    abort ();
+    emacs_abort ();
 
   /* If this frame is dead, it won't be in Vframe_list, and we'll loop
      forever.  Forestall that.  */
   CHECK_LIVE_FRAME (frame);
 
   while (1)
-    for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
+    FOR_EACH_FRAME (tail, f)
       {
-       Lisp_Object f;
-
-       f = XCAR (tail);
-
        if (passed
            && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
                  && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
@@ -958,22 +980,13 @@ next_frame (Lisp_Object frame, Lisp_Object minibuf)
 static Lisp_Object
 prev_frame (Lisp_Object frame, Lisp_Object minibuf)
 {
-  Lisp_Object tail;
-  Lisp_Object prev;
+  Lisp_Object f, tail, prev = Qnil;
 
   /* There must always be at least one frame in Vframe_list.  */
-  if (! CONSP (Vframe_list))
-    abort ();
+  eassert (CONSP (Vframe_list));
 
-  prev = Qnil;
-  for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
+  FOR_EACH_FRAME (tail, f)
     {
-      Lisp_Object f;
-
-      f = XCAR (tail);
-      if (!FRAMEP (f))
-       abort ();
-
       if (EQ (frame, f) && !NILP (prev))
        return prev;
 
@@ -1074,11 +1087,10 @@ Otherwise, include all frames.  */)
 static int
 other_visible_frames (FRAME_PTR f)
 {
-  Lisp_Object frames;
+  Lisp_Object frames, this;
 
-  for (frames = Vframe_list; CONSP (frames); frames = XCDR (frames))
+  FOR_EACH_FRAME (frames, this)
     {
-      Lisp_Object this = XCAR (frames);
       if (f == XFRAME (this))
        continue;
 
@@ -1109,22 +1121,11 @@ other_visible_frames (FRAME_PTR f)
 Lisp_Object
 delete_frame (Lisp_Object frame, Lisp_Object force)
 {
-  struct frame *f;
+  struct frame *f = decode_any_frame (frame);
   struct frame *sf = SELECTED_FRAME ();
   struct kboard *kb;
 
-  int minibuffer_selected, tooltip_frame;
-
-  if (EQ (frame, Qnil))
-    {
-      f = sf;
-      XSETFRAME (frame, f);
-    }
-  else
-    {
-      CHECK_FRAME (frame);
-      f = XFRAME (frame);
-    }
+  int minibuffer_selected, is_tooltip_frame;
 
   if (! FRAME_LIVE_P (f))
     return Qnil;
@@ -1137,19 +1138,16 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
   if (NILP (XCDR (Vframe_list)) && !EQ (force, Qnoelisp))
     error ("Attempt to delete the only frame");
 
+  XSETFRAME (frame, f);
+
   /* Does this frame have a minibuffer, and is it the surrogate
      minibuffer for any other frame?  */
-  if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
+  if (FRAME_HAS_MINIBUF_P (f))
     {
-      Lisp_Object frames;
+      Lisp_Object frames, this;
 
-      for (frames = Vframe_list;
-          CONSP (frames);
-          frames = XCDR (frames))
+      FOR_EACH_FRAME (frames, this)
        {
-         Lisp_Object this;
-         this = XCAR (frames);
-
          if (! EQ (this, frame)
              && EQ (frame,
                     WINDOW_FRAME (XWINDOW
@@ -1165,13 +1163,13 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
        }
     }
 
-  tooltip_frame = !NILP (Fframe_parameter (frame, intern ("tooltip")));
+  is_tooltip_frame = !NILP (Fframe_parameter (frame, intern ("tooltip")));
 
   /* Run `delete-frame-functions' unless FORCE is `noelisp' or
      frame is a tooltip.  FORCE is set to `noelisp' when handling
      a disconnect from the terminal, so we don't dare call Lisp
      code.  */
-  if (NILP (Vrun_hooks) || tooltip_frame)
+  if (NILP (Vrun_hooks) || is_tooltip_frame)
     ;
   else if (EQ (force, Qnoelisp))
     pending_funcalls
@@ -1238,11 +1236,13 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
     }
 
   /* Don't allow minibuf_window to remain on a deleted frame.  */
-  if (EQ (FVAR (f, minibuffer_window), minibuf_window))
+  if (EQ (f->minibuffer_window, minibuf_window))
     {
-      Fset_window_buffer (FVAR (sf, minibuffer_window),
-                         WVAR (XWINDOW (minibuf_window), buffer), Qnil);
-      minibuf_window = FVAR (sf, minibuffer_window);
+      /* Use set_window_buffer instead of Fset_window_buffer (see
+        discussion of bug#11984, bug#12025, bug#12026).  */
+      set_window_buffer (sf->minibuffer_window,
+                        XWINDOW (minibuf_window)->buffer, 0, 0);
+      minibuf_window = sf->minibuffer_window;
 
       /* If the dying minibuffer window was selected,
         select the new one.  */
@@ -1251,8 +1251,8 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
     }
 
   /* Don't let echo_area_window to remain on a deleted frame.  */
-  if (EQ (FVAR (f, minibuffer_window), echo_area_window))
-    echo_area_window = FVAR (sf, minibuffer_window);
+  if (EQ (f->minibuffer_window, echo_area_window))
+    echo_area_window = sf->minibuffer_window;
 
   /* Clear any X selections for this frame.  */
 #ifdef HAVE_X_WINDOWS
@@ -1273,8 +1273,8 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
 
   /* Mark all the windows that used to be on FRAME as deleted, and then
      remove the reference to them.  */
-  delete_all_child_windows (FVAR (f, root_window));
-  FVAR (f, root_window) = Qnil;
+  delete_all_child_windows (f->root_window);
+  fset_root_window (f, Qnil);
 
   Vframe_list = Fdelq (frame, Vframe_list);
   FRAME_SET_VISIBLE (f, 0);
@@ -1283,7 +1283,12 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
      garbage collection.  The frame object itself may not be garbage
      collected until much later, because recent_keys and other data
      structures can still refer to it.  */
-  FVAR (f, menu_bar_vector) = Qnil;
+  fset_menu_bar_vector (f, Qnil);
+
+  /* If FRAME's buffer lists contains killed
+     buffers, this helps GC to reclaim them.  */
+  fset_buffer_list (f, Qnil);
+  fset_buried_buffer_list (f, Qnil);
 
   free_font_driver_list (f);
   xfree (f->namebuf);
@@ -1335,15 +1340,13 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
      another one.  */
   if (f == last_nonminibuf_frame)
     {
-      Lisp_Object frames;
+      Lisp_Object frames, this;
 
       last_nonminibuf_frame = 0;
 
-      for (frames = Vframe_list;
-          CONSP (frames);
-          frames = XCDR (frames))
+      FOR_EACH_FRAME (frames, this)
        {
-         f = XFRAME (XCAR (frames));
+         f = XFRAME (this);
          if (!FRAME_MINIBUF_ONLY_P (f))
            {
              last_nonminibuf_frame = f;
@@ -1356,27 +1359,13 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
      single-kboard state if we're in it for this kboard.  */
   if (kb != NULL)
     {
-      Lisp_Object frames;
+      Lisp_Object frames, this;
       /* Some frame we found on the same kboard, or nil if there are none.  */
-      Lisp_Object frame_on_same_kboard;
+      Lisp_Object frame_on_same_kboard = Qnil;
 
-      frame_on_same_kboard = Qnil;
-
-      for (frames = Vframe_list;
-          CONSP (frames);
-          frames = XCDR (frames))
-       {
-         Lisp_Object this;
-         struct frame *f1;
-
-         this = XCAR (frames);
-         if (!FRAMEP (this))
-           abort ();
-         f1 = XFRAME (this);
-
-         if (kb == FRAME_KBOARD (f1))
-           frame_on_same_kboard = this;
-       }
+      FOR_EACH_FRAME (frames, this)
+       if (kb == FRAME_KBOARD (XFRAME (this)))
+         frame_on_same_kboard = this;
 
       if (NILP (frame_on_same_kboard))
        not_single_kboard_state (kb);
@@ -1388,27 +1377,16 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
      frames with other windows.  */
   if (kb != NULL && EQ (frame, KVAR (kb, Vdefault_minibuffer_frame)))
     {
-      Lisp_Object frames;
+      Lisp_Object frames, this;
 
       /* The last frame we saw with a minibuffer, minibuffer-only or not.  */
-      Lisp_Object frame_with_minibuf;
+      Lisp_Object frame_with_minibuf = Qnil;
       /* 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;
+      Lisp_Object frame_on_same_kboard = Qnil;
 
-      for (frames = Vframe_list;
-          CONSP (frames);
-          frames = XCDR (frames))
+      FOR_EACH_FRAME (frames, this)
        {
-         Lisp_Object this;
-         struct frame *f1;
-
-         this = XCAR (frames);
-         if (!FRAMEP (this))
-           abort ();
-         f1 = XFRAME (this);
+         struct frame *f1 = XFRAME (this);
 
          /* Consider only frames on the same kboard
             and only those with minibuffers.  */
@@ -1433,17 +1411,17 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
             that is prohibited at the top; you can't delete surrogate
             minibuffer frames.  */
          if (NILP (frame_with_minibuf))
-           abort ();
+           emacs_abort ();
 
-         KVAR (kb, Vdefault_minibuffer_frame) = frame_with_minibuf;
+         kset_default_minibuffer_frame (kb, frame_with_minibuf);
        }
       else
        /* No frames left on this kboard--say no minibuffer either.  */
-       KVAR (kb, Vdefault_minibuffer_frame) = Qnil;
+       kset_default_minibuffer_frame (kb, Qnil);
     }
 
   /* Cause frame titles to update--necessary if we now have just one frame.  */
-  if (!tooltip_frame)
+  if (!is_tooltip_frame)
     update_mode_lines = 1;
 
   return Qnil;
@@ -1483,31 +1461,31 @@ and returns whatever that function returns.  */)
 {
   FRAME_PTR f;
   Lisp_Object lispy_dummy;
-  enum scroll_bar_part party_dummy;
   Lisp_Object x, y, retval;
-  int col, row;
-  Time long_dummy;
   struct gcpro gcpro1;
 
   f = SELECTED_FRAME ();
   x = y = Qnil;
 
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   /* It's okay for the hook to refrain from storing anything.  */
   if (FRAME_TERMINAL (f)->mouse_position_hook)
-    (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
-                                                &lispy_dummy, &party_dummy,
-                                                &x, &y,
-                                                &long_dummy);
+    {
+      enum scroll_bar_part party_dummy;
+      Time time_dummy;
+      (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
+                                                 &lispy_dummy, &party_dummy,
+                                                 &x, &y,
+                                                 &time_dummy);
+    }
+
   if (! NILP (x))
     {
-      col = XINT (x);
-      row = XINT (y);
+      int col = XINT (x);
+      int row = XINT (y);
       pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
       XSETINT (x, col);
       XSETINT (y, row);
     }
-#endif
   XSETFRAME (lispy_dummy, f);
   retval = Fcons (lispy_dummy, Fcons (x, y));
   GCPRO1 (retval);
@@ -1529,21 +1507,22 @@ and nil for X and Y.  */)
 {
   FRAME_PTR f;
   Lisp_Object lispy_dummy;
-  enum scroll_bar_part party_dummy;
   Lisp_Object x, y;
-  Time long_dummy;
 
   f = SELECTED_FRAME ();
   x = y = Qnil;
 
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   /* It's okay for the hook to refrain from storing anything.  */
   if (FRAME_TERMINAL (f)->mouse_position_hook)
-    (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
-                                                &lispy_dummy, &party_dummy,
-                                                &x, &y,
-                                                &long_dummy);
-#endif
+    {
+      enum scroll_bar_part party_dummy;
+      Time time_dummy;
+      (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
+                                                 &lispy_dummy, &party_dummy,
+                                                 &x, &y,
+                                                 &time_dummy);
+    }
+
   XSETFRAME (lispy_dummy, f);
   return Fcons (lispy_dummy, Fcons (x, y));
 }
@@ -1574,7 +1553,7 @@ before calling this function on it, like this.
     /* Warping the mouse will cause enternotify and focus events.  */
     x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
 #else
-#if defined (MSDOS) && defined (HAVE_MOUSE)
+#if defined (MSDOS)
   if (FRAME_MSDOS_P (XFRAME (frame)))
     {
       Fselect_frame (frame, Qnil);
@@ -1615,7 +1594,7 @@ before calling this function on it, like this.
     /* Warping the mouse will cause enternotify and focus events.  */
     x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
 #else
-#if defined (MSDOS) && defined (HAVE_MOUSE)
+#if defined (MSDOS)
   if (FRAME_MSDOS_P (XFRAME (frame)))
     {
       Fselect_frame (frame, Qnil);
@@ -1642,25 +1621,23 @@ DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
 If omitted, FRAME defaults to the currently selected frame.  */)
   (Lisp_Object frame)
 {
-  if (NILP (frame))
-    frame = selected_frame;
-
-  CHECK_LIVE_FRAME (frame);
+  struct frame *f = decode_live_frame (frame);
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
-  if (FRAME_WINDOW_P (XFRAME (frame)))
+  if (FRAME_WINDOW_P (f))
     {
-      FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
-      x_make_frame_visible (XFRAME (frame));
+      FRAME_SAMPLE_VISIBILITY (f);
+      x_make_frame_visible (f);
     }
 #endif
 
-  make_frame_visible_1 (FVAR (XFRAME (frame), root_window));
+  make_frame_visible_1 (f->root_window);
 
   /* Make menu bar update for the Buffers and Frames menus.  */
   windows_or_buffers_changed++;
 
+  XSETFRAME (frame, f);
   return frame;
 }
 
@@ -1672,17 +1649,17 @@ make_frame_visible_1 (Lisp_Object window)
 {
   struct window *w;
 
-  for (;!NILP (window); window = WVAR (w, next))
+  for (;!NILP (window); window = w->next)
     {
       w = XWINDOW (window);
 
-      if (!NILP (WVAR (w, buffer)))
-       BVAR (XBUFFER (WVAR (w, buffer)), display_time) = Fcurrent_time ();
+      if (!NILP (w->buffer))
+       bset_display_time (XBUFFER (w->buffer), Fcurrent_time ());
 
-      if (!NILP (WVAR (w, vchild)))
-       make_frame_visible_1 (WVAR (w, vchild));
-      if (!NILP (WVAR (w, hchild)))
-       make_frame_visible_1 (WVAR (w, hchild));
+      if (!NILP (w->vchild))
+       make_frame_visible_1 (w->vchild);
+      if (!NILP (w->hchild))
+       make_frame_visible_1 (w->hchild);
     }
 }
 
@@ -1701,27 +1678,26 @@ always considered visible, whether or not they are currently being
 displayed in the terminal.  */)
   (Lisp_Object frame, Lisp_Object force)
 {
-  if (NILP (frame))
-    frame = selected_frame;
+  struct frame *f = decode_live_frame (frame);
 
-  CHECK_LIVE_FRAME (frame);
-
-  if (NILP (force) && !other_visible_frames (XFRAME (frame)))
+  if (NILP (force) && !other_visible_frames (f))
     error ("Attempt to make invisible the sole visible or iconified frame");
 
   /* Don't allow minibuf_window to remain on a deleted frame.  */
-  if (EQ (FVAR (XFRAME (frame), minibuffer_window), minibuf_window))
+  if (EQ (f->minibuffer_window, minibuf_window))
     {
       struct frame *sf = XFRAME (selected_frame);
-      Fset_window_buffer (FVAR (sf, minibuffer_window),
-                         WVAR (XWINDOW (minibuf_window), buffer), Qnil);
-      minibuf_window = FVAR (sf, minibuffer_window);
+      /* Use set_window_buffer instead of Fset_window_buffer (see
+        discussion of bug#11984, bug#12025, bug#12026).  */
+      set_window_buffer (sf->minibuffer_window,
+                        XWINDOW (minibuf_window)->buffer, 0, 0);
+      minibuf_window = sf->minibuffer_window;
     }
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
-  if (FRAME_WINDOW_P (XFRAME (frame)))
-    x_make_frame_invisible (XFRAME (frame));
+  if (FRAME_WINDOW_P (f))
+    x_make_frame_invisible (f);
 #endif
 
   /* Make menu bar update for the Buffers and Frames menus.  */
@@ -1736,30 +1712,23 @@ DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
 If omitted, FRAME defaults to the currently selected frame.  */)
   (Lisp_Object frame)
 {
-  if (NILP (frame))
-    frame = selected_frame;
+  struct frame *f = decode_live_frame (frame);
 
-  CHECK_LIVE_FRAME (frame);
-
-#if 0 /* This isn't logically necessary, and it can do GC.  */
-  /* Don't let the frame remain selected.  */
-  if (EQ (frame, selected_frame))
-    Fhandle_switch_frame (next_frame (frame, Qt));
-#endif
-
-  /* Don't allow minibuf_window to remain on a deleted frame.  */
-  if (EQ (FVAR (XFRAME (frame), minibuffer_window), minibuf_window))
+  /* Don't allow minibuf_window to remain on an iconified frame.  */
+  if (EQ (f->minibuffer_window, minibuf_window))
     {
       struct frame *sf = XFRAME (selected_frame);
-      Fset_window_buffer (FVAR (sf, minibuffer_window),
-                         WVAR (XWINDOW (minibuf_window), buffer), Qnil);
-      minibuf_window = FVAR (sf, minibuffer_window);
+      /* Use set_window_buffer instead of Fset_window_buffer (see
+        discussion of bug#11984, bug#12025, bug#12026).  */
+      set_window_buffer (sf->minibuffer_window,
+                        XWINDOW (minibuf_window)->buffer, 0, 0);
+      minibuf_window = sf->minibuffer_window;
     }
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
-  if (FRAME_WINDOW_P (XFRAME (frame)))
-      x_iconify_frame (XFRAME (frame));
+  if (FRAME_WINDOW_P (f))
+      x_iconify_frame (f);
 #endif
 
   /* Make menu bar update for the Buffers and Frames menus.  */
@@ -1797,20 +1766,12 @@ DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
        doc: /* Return a list of all frames now \"visible\" (being updated).  */)
   (void)
 {
-  Lisp_Object tail, frame;
-  struct frame *f;
-  Lisp_Object value;
+  Lisp_Object tail, frame, value = Qnil;
+
+  FOR_EACH_FRAME (tail, frame)
+    if (FRAME_VISIBLE_P (XFRAME (frame)))
+      value = Fcons (frame, value);
 
-  value = Qnil;
-  for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
-    {
-      frame = XCAR (tail);
-      if (!FRAMEP (frame))
-       continue;
-      f = XFRAME (frame);
-      if (FRAME_VISIBLE_P (f))
-       value = Fcons (frame, value);
-    }
   return value;
 }
 
@@ -1823,13 +1784,9 @@ If Emacs is displaying on an ordinary terminal or some other device which
 doesn't support multiple overlapping frames, this function selects FRAME.  */)
   (Lisp_Object frame)
 {
-  struct frame *f;
-  if (NILP (frame))
-    frame = selected_frame;
+  struct frame *f = decode_live_frame (frame);
 
-  CHECK_LIVE_FRAME (frame);
-
-  f = XFRAME (frame);
+  XSETFRAME (frame, f);
 
   if (FRAME_TERMCAP_P (f))
     /* On a text terminal select FRAME.  */
@@ -1852,14 +1809,7 @@ If Emacs is displaying on an ordinary terminal or some other device which
 doesn't support multiple overlapping frames, this function does nothing.  */)
   (Lisp_Object frame)
 {
-  struct frame *f;
-
-  if (NILP (frame))
-    frame = selected_frame;
-
-  CHECK_LIVE_FRAME (frame);
-
-  f = XFRAME (frame);
+  struct frame *f = decode_live_frame (frame);
 
   if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
     (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0);
@@ -1895,19 +1845,15 @@ is affected by `select-frame', while the latter is not.
 The redirection lasts until `redirect-frame-focus' is called to change it.  */)
   (Lisp_Object frame, Lisp_Object focus_frame)
 {
-  struct frame *f;
-
   /* Note that we don't check for a live frame here.  It's reasonable
      to redirect the focus of a frame you're about to delete, if you
      know what other frame should receive those keystrokes.  */
-  CHECK_FRAME (frame);
+  struct frame *f = decode_any_frame (frame);
 
   if (! NILP (focus_frame))
     CHECK_LIVE_FRAME (focus_frame);
 
-  f = XFRAME (frame);
-
-  FVAR (f, focus_frame) = focus_frame;
+  fset_focus_frame (f, focus_frame);
 
   if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
     (*FRAME_TERMINAL (f)->frame_rehighlight_hook) (f);
@@ -1916,15 +1862,14 @@ The redirection lasts until `redirect-frame-focus' is called to change it.  */)
 }
 
 
-DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
+DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 0, 1, 0,
        doc: /* Return the frame to which FRAME's keystrokes are currently being sent.
-This returns nil if FRAME's focus is not redirected.
+If FRAME is omitted or nil, the selected frame is used.
+Return nil if FRAME's focus is not redirected.
 See `redirect-frame-focus'.  */)
   (Lisp_Object frame)
 {
-  CHECK_LIVE_FRAME (frame);
-
-  return FRAME_FOCUS_FRAME (XFRAME (frame));
+  return FRAME_FOCUS_FRAME (decode_live_frame (frame));
 }
 
 
@@ -1940,29 +1885,13 @@ get_frame_param (register struct frame *frame, Lisp_Object prop)
 {
   register Lisp_Object tem;
 
-  tem = Fassq (prop, FVAR (frame, param_alist));
+  tem = Fassq (prop, frame->param_alist);
   if (EQ (tem, Qnil))
     return tem;
   return Fcdr (tem);
 }
 #endif
 
-/* Return the buffer-predicate of the selected frame.  */
-
-Lisp_Object
-frame_buffer_predicate (Lisp_Object frame)
-{
-  return FVAR (XFRAME (frame), buffer_predicate);
-}
-
-/* Return the buffer-list of the selected frame.  */
-
-static Lisp_Object
-frame_buffer_list (Lisp_Object frame)
-{
-  return FVAR (XFRAME (frame), buffer_list);
-}
-
 /* Discard BUFFER from the buffer-list and buried-buffer-list of each frame.  */
 
 void
@@ -1972,10 +1901,10 @@ frames_discard_buffer (Lisp_Object buffer)
 
   FOR_EACH_FRAME (tail, frame)
     {
-      FVAR (XFRAME (frame), buffer_list)
-       = Fdelq (buffer, FVAR (XFRAME (frame), buffer_list));
-      FVAR (XFRAME (frame), buried_buffer_list)
-        = Fdelq (buffer, FVAR (XFRAME (frame), buried_buffer_list));
+      fset_buffer_list
+       (XFRAME (frame), Fdelq (buffer, XFRAME (frame)->buffer_list));
+      fset_buried_buffer_list
+       (XFRAME (frame), Fdelq (buffer, XFRAME (frame)->buried_buffer_list));
     }
 }
 
@@ -2023,8 +1952,7 @@ set_term_frame_name (struct frame *f, Lisp_Object name)
 
       /* Check for no change needed in this very common case
         before we do any consing.  */
-      if (frame_name_fnn_p (SSDATA (FVAR (f, name)),
-                           SBYTES (FVAR (f, name))))
+      if (frame_name_fnn_p (SSDATA (f->name), SBYTES (f->name)))
        return;
 
       name = make_formatted_string (namebuf, "F%"pMd, ++tty_frame_count);
@@ -2034,7 +1962,7 @@ set_term_frame_name (struct frame *f, Lisp_Object name)
       CHECK_STRING (name);
 
       /* Don't change the name if it's already NAME.  */
-      if (! NILP (Fstring_equal (name, FVAR (f, name))))
+      if (! NILP (Fstring_equal (name, f->name)))
        return;
 
       /* Don't allow the user to set the frame name to F<num>, so it
@@ -2043,7 +1971,7 @@ set_term_frame_name (struct frame *f, Lisp_Object name)
        error ("Frame names of the form F<num> are usurped by Emacs");
     }
 
-  FVAR (f, name) = name;
+  fset_name (f, name);
   update_mode_lines = 1;
 }
 
@@ -2060,7 +1988,7 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
       for (; CONSP (val); val = XCDR (val))
        if (!NILP (Fbuffer_live_p (XCAR (val))))
          list = Fcons (XCAR (val), list);
-      FVAR (f, buffer_list) = Fnreverse (list);
+      fset_buffer_list (f, Fnreverse (list));
       return;
     }
   if (EQ (prop, Qburied_buffer_list))
@@ -2069,7 +1997,7 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
       for (; CONSP (val); val = XCDR (val))
        if (!NILP (Fbuffer_live_p (XCAR (val))))
          list = Fcons (XCAR (val), list);
-      FVAR (f, buried_buffer_list) = Fnreverse (list);
+      fset_buried_buffer_list (f, Fnreverse (list));
       return;
     }
 
@@ -2087,11 +2015,11 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
        case SYMBOL_PLAINVAL: case SYMBOL_FORWARDED: break;
        case SYMBOL_LOCALIZED:
          { struct Lisp_Buffer_Local_Value *blv = sym->val.blv;
-           if (blv->frame_local && BLV_FOUND (blv) && XFRAME (blv->where) == f)
+           if (blv->frame_local && blv_found (blv) && XFRAME (blv->where) == f)
              swap_in_global_binding (sym);
            break;
          }
-       default: abort ();
+       default: emacs_abort ();
        }
     }
 
@@ -2104,9 +2032,9 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
     FRAME_TTY (f)->previous_frame = NULL;
 
   /* Update the frame parameter alist.  */
-  old_alist_elt = Fassq (prop, FVAR (f, param_alist));
+  old_alist_elt = Fassq (prop, f->param_alist);
   if (EQ (old_alist_elt, Qnil))
-    FVAR (f, param_alist) = Fcons (Fcons (prop, val), FVAR (f, param_alist));
+    fset_param_alist (f, Fcons (Fcons (prop, val), f->param_alist));
   else
     Fsetcdr (old_alist_elt, val);
 
@@ -2114,7 +2042,7 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
      in addition to the alist.  */
 
   if (EQ (prop, Qbuffer_predicate))
-    FVAR (f, buffer_predicate) = val;
+    fset_buffer_predicate (f, val);
 
   if (! FRAME_WINDOW_P (f))
     {
@@ -2130,11 +2058,11 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
        error ("Surrogate minibuffer windows must be minibuffer windows");
 
       if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
-         && !EQ (val, FVAR (f, minibuffer_window)))
+         && !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.  */
-      FVAR (f, minibuffer_window) = val;
+      fset_minibuffer_window (f, val);
     }
 }
 
@@ -2142,24 +2070,18 @@ DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
        doc: /* Return the parameters-alist of frame FRAME.
 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
 The meaningful PARMs depend on the kind of frame.
-If FRAME is omitted, return information on the currently selected frame.  */)
+If FRAME is omitted or nil, return information on the currently selected frame.  */)
   (Lisp_Object frame)
 {
   Lisp_Object alist;
-  FRAME_PTR f;
+  struct frame *f = decode_any_frame (frame);
   int height, width;
   struct gcpro gcpro1;
 
-  if (NILP (frame))
-    frame = selected_frame;
-
-  CHECK_FRAME (frame);
-  f = XFRAME (frame);
-
   if (!FRAME_LIVE_P (f))
     return Qnil;
 
-  alist = Fcopy_alist (FVAR (f, param_alist));
+  alist = Fcopy_alist (f->param_alist);
   GCPRO1 (alist);
 
   if (!FRAME_WINDOW_P (f))
@@ -2205,7 +2127,7 @@ If FRAME is omitted, return information on the currently selected frame.  */)
                                    : FRAME_W32_P (f) ? "w32term"
                                    :"tty"));
     }
-  store_in_alist (&alist, Qname, FVAR (f, name));
+  store_in_alist (&alist, Qname, f->name);
   height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
   store_in_alist (&alist, Qheight, make_number (height));
   width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
@@ -2216,9 +2138,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 (frame));
-  store_in_alist (&alist, Qburied_buffer_list,
-                 FVAR (XFRAME (frame), buried_buffer_list));
+  store_in_alist (&alist, Qbuffer_list, f->buffer_list);
+  store_in_alist (&alist, Qburied_buffer_list, f->buried_buffer_list);
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -2243,23 +2164,18 @@ DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
 If FRAME is nil, describe the currently selected frame.  */)
   (Lisp_Object frame, Lisp_Object parameter)
 {
-  struct frame *f;
-  Lisp_Object value;
+  struct frame *f = decode_any_frame (frame);
+  Lisp_Object value = Qnil;
 
-  if (NILP (frame))
-    frame = selected_frame;
-  else
-    CHECK_FRAME (frame);
   CHECK_SYMBOL (parameter);
 
-  f = XFRAME (frame);
-  value = Qnil;
+  XSETFRAME (frame, f);
 
   if (FRAME_LIVE_P (f))
     {
       /* Avoid consing in frequent cases.  */
       if (EQ (parameter, Qname))
-       value = FVAR (f, name);
+       value = f->name;
 #ifdef HAVE_X_WINDOWS
       else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
        value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element);
@@ -2267,7 +2183,7 @@ If FRAME is nil, describe the currently selected frame.  */)
       else if (EQ (parameter, Qbackground_color)
               || EQ (parameter, Qforeground_color))
        {
-         value = Fassq (parameter, FVAR (f, param_alist));
+         value = Fassq (parameter, f->param_alist);
          if (CONSP (value))
            {
              value = XCDR (value);
@@ -2305,7 +2221,7 @@ If FRAME is nil, describe the currently selected frame.  */)
        }
       else if (EQ (parameter, Qdisplay_type)
               || EQ (parameter, Qbackground_mode))
-       value = Fcdr (Fassq (parameter, FVAR (f, param_alist)));
+       value = Fcdr (Fassq (parameter, f->param_alist));
       else
        /* FIXME: Avoid this code path at all (as well as code duplication)
           by sharing more code with Fframe_parameters.  */
@@ -2333,14 +2249,9 @@ Note that this functionality is obsolete as of Emacs 22.2, and its
 use is not recommended.  Explicitly check for a frame-parameter instead.  */)
   (Lisp_Object frame, Lisp_Object alist)
 {
-  FRAME_PTR f;
+  struct frame *f = decode_live_frame (frame);
   register Lisp_Object tail, prop, val;
 
-  if (EQ (frame, Qnil))
-    frame = selected_frame;
-  CHECK_LIVE_FRAME (frame);
-  f = XFRAME (frame);
-
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
@@ -2395,18 +2306,13 @@ use is not recommended.  Explicitly check for a frame-parameter instead.  */)
 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
        0, 1, 0,
        doc: /* Height in pixels of a line in the font in frame FRAME.
-If FRAME is omitted, the selected frame is used.
+If FRAME is omitted or nil, the selected frame is used.
 For a terminal frame, the value is always 1.  */)
   (Lisp_Object frame)
 {
-  struct frame *f;
-
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_FRAME (frame);
-  f = XFRAME (frame);
-
 #ifdef HAVE_WINDOW_SYSTEM
+  struct frame *f = decode_any_frame (frame);
+
   if (FRAME_WINDOW_P (f))
     return make_number (x_char_height (f));
   else
@@ -2418,19 +2324,14 @@ For a terminal frame, the value is always 1.  */)
 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
        0, 1, 0,
        doc: /* Width in pixels of characters in the font in frame FRAME.
-If FRAME is omitted, the selected frame is used.
+If FRAME is omitted or nil, the selected frame is used.
 On a graphical screen, the width is the standard width of the default font.
 For a terminal screen, the value is always 1.  */)
   (Lisp_Object frame)
 {
-  struct frame *f;
-
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_FRAME (frame);
-  f = XFRAME (frame);
-
 #ifdef HAVE_WINDOW_SYSTEM
+  struct frame *f = decode_any_frame (frame);
+
   if (FRAME_WINDOW_P (f))
     return make_number (x_char_width (f));
   else
@@ -2441,30 +2342,22 @@ For a terminal screen, the value is always 1.  */)
 DEFUN ("frame-pixel-height", Fframe_pixel_height,
        Sframe_pixel_height, 0, 1, 0,
        doc: /* Return a FRAME's height in pixels.
-If FRAME is omitted, the selected frame is used.  The exact value
+If FRAME is omitted or nil, the selected frame is used.  The exact value
 of the result depends on the window-system and toolkit in use:
 
 In the Gtk+ version of Emacs, it includes only any window (including
 the minibuffer or echo area), mode line, and header line.  It does not
 include the tool bar or menu bar.
 
-With the Motif or Lucid toolkits, it also includes the tool bar (but
-not the menu bar).
-
-In a graphical version with no toolkit, it includes both the tool bar
-and menu bar.
+With other graphical versions, it also includes the tool bar and the
+menu bar.
 
 For a text terminal, it includes the menu bar.  In this case, the
 result is really in characters rather than pixels (i.e., is identical
 to `frame-height'). */)
   (Lisp_Object frame)
 {
-  struct frame *f;
-
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_FRAME (frame);
-  f = XFRAME (frame);
+  struct frame *f = decode_any_frame (frame);
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
@@ -2478,15 +2371,10 @@ DEFUN ("frame-pixel-width", Fframe_pixel_width,
        Sframe_pixel_width, 0, 1, 0,
        doc: /* Return FRAME's width in pixels.
 For a terminal frame, the result really gives the width in characters.
-If FRAME is omitted, the selected frame is used.  */)
+If FRAME is omitted or nil, the selected frame is used.  */)
   (Lisp_Object frame)
 {
-  struct frame *f;
-
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_FRAME (frame);
-  f = XFRAME (frame);
+  struct frame *f = decode_any_frame (frame);
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
@@ -2500,17 +2388,15 @@ DEFUN ("tool-bar-pixel-width", Ftool_bar_pixel_width,
        Stool_bar_pixel_width, 0, 1, 0,
        doc: /* Return width in pixels of FRAME's tool bar.
 The result is greater than zero only when the tool bar is on the left
-or right side of FRAME.  If FRAME is omitted, the selected frame is
-used.  */)
+or right side of FRAME.  If FRAME is omitted or nil, the selected frame
+is used.  */)
   (Lisp_Object frame)
 {
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_FRAME (frame);
-
 #ifdef FRAME_TOOLBAR_WIDTH
-  if (FRAME_WINDOW_P (XFRAME (frame)))
-    return make_number (FRAME_TOOLBAR_WIDTH (XFRAME (frame)));
+  struct frame *f = decode_any_frame (frame);
+
+  if (FRAME_WINDOW_P (f))
+    return make_number (FRAME_TOOLBAR_WIDTH (f));
 #endif
   return make_number (0);
 }
@@ -2521,13 +2407,9 @@ Optional third arg non-nil means that redisplay should use LINES lines
 but that the idea of the actual height of the frame should not be changed.  */)
   (Lisp_Object frame, Lisp_Object lines, Lisp_Object pretend)
 {
-  register struct frame *f;
+  register struct frame *f = decode_live_frame (frame);
 
   CHECK_TYPE_RANGED_INTEGER (int, lines);
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_LIVE_FRAME (frame);
-  f = XFRAME (frame);
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -2549,12 +2431,9 @@ Optional third arg non-nil means that redisplay should use COLS columns
 but that the idea of the actual width of the frame should not be changed.  */)
   (Lisp_Object frame, Lisp_Object cols, Lisp_Object pretend)
 {
-  register struct frame *f;
+  register struct frame *f = decode_live_frame (frame);
+
   CHECK_TYPE_RANGED_INTEGER (int, cols);
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_LIVE_FRAME (frame);
-  f = XFRAME (frame);
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -2676,7 +2555,7 @@ static const struct frame_parm_table frame_parms[] =
   {"tool-bar-position",                &Qtool_bar_position},
 };
 
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
 
 /* Calculate fullscreen size.  Return in *TOP_POS and *LEFT_POS the
    wanted positions of the WM window (not Emacs window).
@@ -2720,7 +2599,7 @@ x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int
   *height = newheight;
 }
 
-#endif /* WINDOWSNT */
+#endif /* HAVE_NTGUI */
 
 #ifdef HAVE_WINDOW_SYSTEM
 
@@ -2891,14 +2770,14 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
   if (! TYPE_RANGED_INTEGERP (int, icon_left))
     {
       icon_left_no_change = 1;
-      icon_left = Fcdr (Fassq (Qicon_left, FVAR (f, param_alist)));
+      icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
       if (NILP (icon_left))
        XSETINT (icon_left, 0);
     }
   if (! TYPE_RANGED_INTEGERP (int, icon_top))
     {
       icon_top_no_change = 1;
-      icon_top = Fcdr (Fassq (Qicon_top, FVAR (f, param_alist)));
+      icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
       if (NILP (icon_top))
        XSETINT (icon_top, 0);
     }
@@ -3007,9 +2886,9 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
 void
 x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
 {
-  char buf[16];
   Lisp_Object tem;
-  unsigned long w;
+  uprintmax_t w;
+  char buf[INT_BUFSIZE_BOUND (w)];
 
   /* Represent negative positions (off the top or left screen edge)
      in a way that Fmodify_frame_parameters will understand correctly.  */
@@ -3046,19 +2925,19 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
      MS-Windows it returns a value whose type is HANDLE, which is
      actually a pointer.  Explicit casting avoids compiler
      warnings.  */
-  w = (unsigned long) FRAME_X_WINDOW (f);
+  w = (uintptr_t) FRAME_X_WINDOW (f);
   store_in_alist (alistptr, Qwindow_id,
-                 make_formatted_string (buf, "%lu", w));
+                 make_formatted_string (buf, "%"pMu, w));
 #ifdef HAVE_X_WINDOWS
 #ifdef USE_X_TOOLKIT
   /* Tooltip frame may not have this widget.  */
   if (FRAME_X_OUTPUT (f)->widget)
 #endif
-    w = (unsigned long) FRAME_OUTER_WINDOW (f);
+    w = (uintptr_t) FRAME_OUTER_WINDOW (f);
   store_in_alist (alistptr, Qouter_window_id,
-                 make_formatted_string (buf, "%lu", w));
+                 make_formatted_string (buf, "%"pMu, w));
 #endif
-  store_in_alist (alistptr, Qicon_name, FVAR (f, icon_name));
+  store_in_alist (alistptr, Qicon_name, f->icon_name);
   FRAME_SAMPLE_VISIBILITY (f);
   store_in_alist (alistptr, Qvisibility,
                  (FRAME_VISIBLE_P (f) ? Qt
@@ -3072,7 +2951,7 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
     XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc);
   store_in_alist (alistptr, Qexplicit_name, (f->explicit_name ? Qt : Qnil));
   store_in_alist (alistptr, Qparent_id, tem);
-  store_in_alist (alistptr, Qtool_bar_position, FVAR (f, tool_bar_position));
+  store_in_alist (alistptr, Qtool_bar_position, f->tool_bar_position);
 }
 
 
@@ -3132,7 +3011,7 @@ x_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
     signal_error ("Invalid screen-gamma", new_value);
 
   /* Apply the new gamma value to the frame background.  */
-  bgcolor = Fassq (Qbackground_color, FVAR (f, param_alist));
+  bgcolor = Fassq (Qbackground_color, f->param_alist);
   if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor)))
     {
       Lisp_Object parm_index = Fget (Qbackground_color, Qx_frame_parameter);
@@ -3216,6 +3095,9 @@ x_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
          Lisp_Object ascii_font = fontset_ascii (fontset);
          Lisp_Object spec = font_spec_from_name (ascii_font);
 
+         if (NILP (spec))
+           signal_error ("Invalid font name", ascii_font);
+
          if (! font_match_p (spec, font_object))
            fontset = -1;
        }
@@ -3262,7 +3144,7 @@ x_set_font_backend (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
       new_value = Qnil;
       while (*p0)
        {
-         while (*p1 && ! isspace (*p1) && *p1 != ',') p1++;
+         while (*p1 && ! c_isspace (*p1) && *p1 != ',') p1++;
          if (p0 < p1)
            new_value = Fcons (Fintern (make_string (p0, p1 - p0), Qnil),
                               new_value);
@@ -3270,7 +3152,7 @@ x_set_font_backend (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
            {
              int c;
 
-             while ((c = *++p1) && isspace (c));
+             while ((c = *++p1) && c_isspace (c));
            }
          p0 = p1;
        }
@@ -3461,7 +3343,7 @@ x_icon_type (FRAME_PTR f)
 {
   Lisp_Object tem;
 
-  tem = assq_no_quit (Qicon_type, FVAR (f, param_alist));
+  tem = assq_no_quit (Qicon_type, f->param_alist);
   if (CONSP (tem))
     return XCDR (tem);
   else
@@ -3512,9 +3394,9 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
     f->alpha[i] = newval[i];
 
 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA)
-  BLOCK_INPUT;
+  block_input ();
   x_set_frame_alpha (f);
-  UNBLOCK_INPUT;
+  unblock_input ();
 #endif
 
   return;
@@ -3818,7 +3700,7 @@ x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param,
              }
 
            default:
-             abort ();
+             emacs_abort ();
            }
        }
       else
@@ -3876,6 +3758,95 @@ x_default_parameter (struct frame *f, Lisp_Object alist, Lisp_Object prop,
 }
 
 
+#if !defined (HAVE_X_WINDOWS) && defined (NoValue)
+
+/*
+ *    XParseGeometry parses strings of the form
+ *   "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
+ *   width, height, xoffset, and yoffset are unsigned integers.
+ *   Example:  "=80x24+300-49"
+ *   The equal sign is optional.
+ *   It returns a bitmask that indicates which of the four values
+ *   were actually found in the string.  For each value found,
+ *   the corresponding argument is updated;  for each value
+ *   not found, the corresponding argument is left unchanged.
+ */
+
+static int
+XParseGeometry (char *string,
+               int *x, int *y,
+               unsigned int *width, unsigned int *height)
+{
+  int mask = NoValue;
+  char *strind;
+  unsigned long int tempWidth, tempHeight;
+  long int tempX, tempY;
+  char *nextCharacter;
+
+  if (string == NULL || *string == '\0')
+    return mask;
+  if (*string == '=')
+    string++;  /* ignore possible '=' at beg of geometry spec */
+
+  strind = string;
+  if (*strind != '+' && *strind != '-' && *strind != 'x')
+    {
+      tempWidth = strtoul (strind, &nextCharacter, 10);
+      if (strind == nextCharacter)
+       return 0;
+      strind = nextCharacter;
+      mask |= WidthValue;
+    }
+
+  if (*strind == 'x' || *strind == 'X')
+    {
+      strind++;
+      tempHeight = strtoul (strind, &nextCharacter, 10);
+      if (strind == nextCharacter)
+       return 0;
+      strind = nextCharacter;
+      mask |= HeightValue;
+    }
+
+  if (*strind == '+' || *strind == '-')
+    {
+      if (*strind == '-')
+       mask |= XNegative;
+      tempX = strtol (strind, &nextCharacter, 10);
+      if (strind == nextCharacter)
+       return 0;
+      strind = nextCharacter;
+      mask |= XValue;
+      if (*strind == '+' || *strind == '-')
+       {
+         if (*strind == '-')
+           mask |= YNegative;
+         tempY = strtol (strind, &nextCharacter, 10);
+         if (strind == nextCharacter)
+           return 0;
+         strind = nextCharacter;
+         mask |= YValue;
+       }
+    }
+
+  /* If strind isn't at the end of the string then it's an invalid
+     geometry specification. */
+
+  if (*strind != '\0')
+    return 0;
+
+  if (mask & XValue)
+    *x = clip_to_bounds (INT_MIN, tempX, INT_MAX);
+  if (mask & YValue)
+    *y = clip_to_bounds (INT_MIN, tempY, INT_MAX);
+  if (mask & WidthValue)
+    *width = min (tempWidth, UINT_MAX);
+  if (mask & HeightValue)
+    *height = min (tempHeight, UINT_MAX);
+  return mask;
+}
+
+#endif /* !defined (HAVE_X_WINDOWS) && defined (NoValue) */
 
 \f
 /* NS used to define x-parse-geometry in ns-win.el, but that confused
@@ -3896,15 +3867,16 @@ or a list (- N) meaning -N pixels relative to bottom/right corner.
 On Nextstep, this just calls `ns-parse-geometry'.  */)
   (Lisp_Object string)
 {
-#ifdef HAVE_NS
-  return call1 (Qns_parse_geometry, string);
-#else
   int geometry, x, y;
   unsigned int width, height;
   Lisp_Object result;
 
   CHECK_STRING (string);
 
+#ifdef HAVE_NS
+  if (strchr (SSDATA (string), ' ') != NULL)
+    return call1 (Qns_parse_geometry, string);
+#endif
   geometry = XParseGeometry (SSDATA (string),
                             &x, &y, &width, &height);
   result = Qnil;
@@ -3940,7 +3912,6 @@ On Nextstep, this just calls `ns-parse-geometry'.  */)
     result = Fcons (Fcons (Qheight, make_number (height)), result);
 
   return result;
-#endif /* HAVE_NS */
 }
 
 
@@ -4179,12 +4150,7 @@ Otherwise it returns nil.  FRAME omitted or nil means the
 selected frame.  This is useful when `make-pointer-invisible' is set.  */)
   (Lisp_Object frame)
 {
-  if (NILP (frame))
-    frame = selected_frame;
-
-  CHECK_FRAME (frame);
-
-  return (XFRAME (frame)->pointer_invisible ? Qnil : Qt);
+  return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
 }
 
 \f
@@ -4203,6 +4169,7 @@ syms_of_frame (void)
   DEFSYM (Qminibuffer, "minibuffer");
   DEFSYM (Qmodeline, "modeline");
   DEFSYM (Qonly, "only");
+  DEFSYM (Qnone, "none");
   DEFSYM (Qwidth, "width");
   DEFSYM (Qgeometry, "geometry");
   DEFSYM (Qicon_left, "icon-left");
@@ -4220,7 +4187,6 @@ syms_of_frame (void)
   DEFSYM (Qx, "x");
   DEFSYM (Qw32, "w32");
   DEFSYM (Qpc, "pc");
-  DEFSYM (Qmac, "mac");
   DEFSYM (Qns, "ns");
   DEFSYM (Qvisible, "visible");
   DEFSYM (Qbuffer_predicate, "buffer-predicate");