]> code.delx.au - gnu-emacs/blobdiff - src/frame.c
Drop async_visible and async_iconified fields of struct frame.
[gnu-emacs] / src / frame.c
index b048327abfb7d81fa1997e9800692e45103eb3b2..9c26af819bcb7e03acb0fe4a28a0d6c357710e9a 100644 (file)
@@ -1,6 +1,6 @@
 /* Generic frame functions.
 
 /* Generic frame functions.
 
-Copyright (C) 1993-1995, 1997, 1999-201 Free Software Foundation, Inc.
+Copyright (C) 1993-1995, 1997, 1999-2013 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 
 This file is part of GNU Emacs.
 
@@ -19,22 +19,21 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 
 
 #include <config.h>
 
+#define FRAME_INLINE EXTERN_INLINE
+
 #include <stdio.h>
 #include <stdio.h>
-#include <ctype.h>
 #include <errno.h>
 #include <limits.h>
 #include <errno.h>
 #include <limits.h>
-#include <setjmp.h>
+
+#include <c-ctype.h>
+
 #include "lisp.h"
 #include "character.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"
 #include "buffer.h"
 /* These help us bind and responding to switch-frame events.  */
 #include "commands.h"
@@ -54,19 +53,14 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "dosfns.h"
 #endif
 
 #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;
 #ifdef HAVE_NS
 Lisp_Object Qns_parse_geometry;
 #endif
 
 Lisp_Object Qframep, Qframe_live_p;
 Lisp_Object Qicon, Qmodeline;
-Lisp_Object Qonly;
-Lisp_Object Qx, Qw32, Qmac, Qpc, Qns;
+Lisp_Object Qonly, Qnone;
+Lisp_Object Qx, Qw32, Qpc, Qns;
 Lisp_Object Qvisible;
 Lisp_Object Qdisplay_type;
 static Lisp_Object Qbackground_mode;
 Lisp_Object Qvisible;
 Lisp_Object Qdisplay_type;
 static Lisp_Object Qbackground_mode;
@@ -125,15 +119,44 @@ static Lisp_Object Qdelete_frame_functions;
 static void x_report_frame_params (struct frame *, Lisp_Object *);
 #endif
 
 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);
 
 static void
 set_menu_bar_lines_1 (Lisp_Object window, int n)
 {
   struct window *w = XWINDOW (window);
 
-  XSETFASTINT (w->last_modified, 0);
-  XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
-  XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
+  w->last_modified = 0;
+  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 (w->vchild))
 
   /* Handle just the top child in a vertical split.  */
   if (!NILP (w->vchild))
@@ -202,12 +225,10 @@ See also `frame-live-p'.  */)
       return Qw32;
     case output_msdos_raw:
       return Qpc;
       return Qw32;
     case output_msdos_raw:
       return Qpc;
-    case output_mac:
-      return Qmac;
     case output_ns:
       return Qns;
     default:
     case output_ns:
       return Qns;
     default:
-      abort ();
+      emacs_abort ();
     }
 }
 
     }
 }
 
@@ -269,7 +290,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.  */
 
   /* Initialize Lisp data.  Note that allocate_frame initializes all
      Lisp data to nil, so do it only for slots which should not be nil.  */
-  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.
 
   /* 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 +310,20 @@ make_frame (int mini_p)
   if (mini_p)
     {
       mini_window = make_window ();
   if (mini_p)
     {
       mini_window = make_window ();
-      XWINDOW (root_window)->next = mini_window;
-      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;
       XWINDOW (mini_window)->mini = 1;
-      XWINDOW (mini_window)->frame = frame;
-      f->minibuffer_window = mini_window;
+      wset_frame (XWINDOW (mini_window), frame);
+      fset_minibuffer_window (f, mini_window);
     }
   else
     {
       mini_window = Qnil;
     }
   else
     {
       mini_window = Qnil;
-      XWINDOW (root_window)->next = Qnil;
-      f->minibuffer_window = Qnil;
+      wset_next (XWINDOW (root_window), Qnil);
+      fset_minibuffer_window (f, Qnil);
     }
 
     }
 
-  XWINDOW (root_window)->frame = frame;
+  wset_frame (XWINDOW (root_window), frame);
 
   /* 10 is arbitrary,
      just so that there is "something there."
 
   /* 10 is arbitrary,
      just so that there is "something there."
@@ -311,25 +332,22 @@ make_frame (int mini_p)
   SET_FRAME_COLS (f, 10);
   FRAME_LINES (f) = 10;
 
   SET_FRAME_COLS (f, 10);
   FRAME_LINES (f) = 10;
 
-  XSETFASTINT (XWINDOW (root_window)->total_cols, 10);
-  XSETFASTINT (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)
     {
 
   if (mini_p)
     {
-      XSETFASTINT (XWINDOW (mini_window)->total_cols, 10);
-      XSETFASTINT (XWINDOW (mini_window)->top_line, 9);
-      XSETFASTINT (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.  */
   {
     }
 
   /* Choose a buffer for the frame's root window.  */
   {
-    Lisp_Object buf;
+    Lisp_Object buf = Fcurrent_buffer ();
 
 
-    XWINDOW (root_window)->buffer = Qt;
-    buf = Fcurrent_buffer ();
-    /* If buf is a 'hidden' buffer (i.e. one whose name starts with
-       a space), try to find another one.  */
-    if (SREF (Fbuffer_name (buf), 0) == ' ')
+    /* If current buffer is hidden, try to find another one.  */
+    if (BUFFER_HIDDEN_P (XBUFFER (buf)))
       buf = other_buffer_safely (buf);
 
     /* Use set_window_buffer, not Fset_window_buffer, and don't let
       buf = other_buffer_safely (buf);
 
     /* Use set_window_buffer, not Fset_window_buffer, and don't let
@@ -339,25 +357,21 @@ 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);
        etc.  Running Lisp functions at this point surely ends in a
        SEGV.  */
     set_window_buffer (root_window, buf, 0, 0);
-    f->buffer_list = Fcons (buf, Qnil);
+    fset_buffer_list (f, Fcons (buf, Qnil));
   }
 
   if (mini_p)
   }
 
   if (mini_p)
-    {
-      XWINDOW (mini_window)->buffer = Qt;
-      set_window_buffer (mini_window,
-                        (NILP (Vminibuffer_list)
-                         ? get_minibuffer (0)
-                         : Fcar (Vminibuffer_list)),
-                        0, 0);
-    }
-
-  f->root_window = root_window;
-  f->selected_window = root_window;
+    set_window_buffer (mini_window,
+                      (NILP (Vminibuffer_list)
+                       ? get_minibuffer (0)
+                       : Fcar (Vminibuffer_list)),
+                      0, 0);
+
+  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.  */
   /* Make sure this window seems more recently used than
      a newly-created, never-selected window.  */
-  ++window_select_count;
-  XSETFASTINT (XWINDOW (f->selected_window)->use_time, window_select_count);
+  XWINDOW (f->selected_window)->use_time = ++window_select_count;
 
   return f;
 }
 
   return f;
 }
@@ -394,23 +408,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.  */
           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;
        }
 
           UNGCPRO;
        }
 
-      mini_window = XFRAME (KVAR (kb, Vdefault_minibuffer_frame))->minibuffer_window;
+      mini_window
+       = XFRAME (KVAR (kb, Vdefault_minibuffer_frame))->minibuffer_window;
     }
 
     }
 
-  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 (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
 
   /* Make the chosen minibuffer window display the proper minibuffer,
      unless it is already showing a minibuffer.  */
   if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
-    Fset_window_buffer (mini_window,
-                       (NILP (Vminibuffer_list)
-                        ? get_minibuffer (0)
-                        : Fcar (Vminibuffer_list)), 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;
 }
 
   return f;
 }
 
@@ -437,18 +454,21 @@ make_minibuffer_frame (void)
      Avoid infinite looping on the window chain by marking next pointer
      as nil. */
 
      Avoid infinite looping on the window chain by marking next pointer
      as nil. */
 
-  mini_window = f->minibuffer_window = f->root_window;
+  mini_window = f->root_window;
+  fset_minibuffer_window (f, mini_window);
   XWINDOW (mini_window)->mini = 1;
   XWINDOW (mini_window)->mini = 1;
-  XWINDOW (mini_window)->next = Qnil;
-  XWINDOW (mini_window)->prev = Qnil;
-  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.  */
 
 
   /* 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 */
   return f;
 }
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -478,10 +498,9 @@ make_initial_frame (void)
   Vframe_list = Fcons (frame, Vframe_list);
 
   tty_frame_count = 1;
   Vframe_list = Fcons (frame, Vframe_list);
 
   tty_frame_count = 1;
-  f->name = make_pure_c_string ("F1");
+  fset_name (f, build_pure_c_string ("F1"));
 
 
-  f->visible = 1;
-  f->async_visible = 1;
+  SET_FRAME_VISIBLE (f, 1);
 
   f->output_method = terminal->type;
   f->terminal = terminal;
 
   f->output_method = terminal->type;
   f->terminal = terminal;
@@ -491,7 +510,6 @@ make_initial_frame (void)
   FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
   FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
 
   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.  */
   FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
 
   /* The default value of menu-bar-mode is t.  */
@@ -519,12 +537,10 @@ make_terminal_frame (struct terminal *terminal)
   XSETFRAME (frame, f);
   Vframe_list = Fcons (frame, Vframe_list);
 
   XSETFRAME (frame, f);
   Vframe_list = Fcons (frame, Vframe_list);
 
-  tty_frame_count++;
-  sprintf (name, "F%"pMd, tty_frame_count);
-  f->name = build_string (name);
+  fset_name (f, make_formatted_string (name, "F%"pMd, ++tty_frame_count));
+
+  SET_FRAME_VISIBLE (f, 1);
 
 
-  f->visible = 1;              /* FRAME_SET_VISIBLE wd set frame_garbaged. */
-  f->async_visible = 1;                /* Don't let visible be cleared later. */
   f->terminal = terminal;
   f->terminal->reference_count++;
 #ifdef MSDOS
   f->terminal = terminal;
   f->terminal->reference_count++;
 #ifdef MSDOS
@@ -542,14 +558,13 @@ make_terminal_frame (struct terminal *terminal)
   FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
 #endif /* not MSDOS */
 
   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;
 
   /* Set the top frame to the newly created frame. */
   if (FRAMEP (FRAME_TTY (f)->top_frame)
       && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame)))
   FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
   FRAME_MENU_BAR_LINES(f) = NILP (Vmenu_bar_mode) ? 0 : 1;
 
   /* Set the top frame to the newly created frame. */
   if (FRAMEP (FRAME_TTY (f)->top_frame)
       && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame)))
-    XFRAME (FRAME_TTY (f)->top_frame)->async_visible = 2; /* obscured */
+    SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (f)->top_frame), 2); /* obscured */
 
   FRAME_TTY (f)->top_frame = frame;
 
 
   FRAME_TTY (f)->top_frame = frame;
 
@@ -610,7 +625,7 @@ affects all frames on the same terminal device.  */)
 #ifdef MSDOS
   if (sf->output_method != output_msdos_raw
       && sf->output_method != output_termcap)
 #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! */
 #else /* not MSDOS */
 
 #ifdef WINDOWSNT                           /* This should work now! */
@@ -623,7 +638,7 @@ affects all frames on the same terminal device.  */)
     Lisp_Object terminal;
 
     terminal = Fassq (Qterminal, parms);
     Lisp_Object terminal;
 
     terminal = Fassq (Qterminal, parms);
-    if (!NILP (terminal))
+    if (CONSP (terminal))
       {
         terminal = XCDR (terminal);
         t = get_terminal (terminal, 1);
       {
         terminal = XCDR (terminal);
         t = get_terminal (terminal, 1);
@@ -648,8 +663,8 @@ affects all frames on the same terminal device.  */)
                        : NULL));
       if (!NILP (tty))
         {
                        : NULL));
       if (!NILP (tty))
         {
-          name = (char *) alloca (SBYTES (tty) + 1);
-          strncpy (name, SSDATA (tty), SBYTES (tty));
+          name = alloca (SBYTES (tty) + 1);
+          memcpy (name, SSDATA (tty), SBYTES (tty));
           name[SBYTES (tty)] = 0;
         }
 
           name[SBYTES (tty)] = 0;
         }
 
@@ -659,8 +674,8 @@ affects all frames on the same terminal device.  */)
                             : NULL));
       if (!NILP (tty_type))
         {
                             : NULL));
       if (!NILP (tty_type))
         {
-          type = (char *) alloca (SBYTES (tty_type) + 1);
-          strncpy (type, SSDATA (tty_type), SBYTES (tty_type));
+          type = alloca (SBYTES (tty_type) + 1);
+          memcpy (type, SSDATA (tty_type), SBYTES (tty_type));
           type[SBYTES (tty_type)] = 0;
         }
 
           type[SBYTES (tty_type)] = 0;
         }
 
@@ -691,7 +706,7 @@ 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.  */
 
   /* 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);
+  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.  */
   /* 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.  */
@@ -757,7 +772,7 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
          Lisp_Object focus;
 
          if (!FRAMEP (XCAR (tail)))
          Lisp_Object focus;
 
          if (!FRAMEP (XCAR (tail)))
-           abort ();
+           emacs_abort ();
 
          focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
 
 
          focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
 
@@ -790,8 +805,8 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
     {
       if (FRAMEP (FRAME_TTY (XFRAME (frame))->top_frame))
        /* Mark previously displayed frame as now obscured.  */
     {
       if (FRAMEP (FRAME_TTY (XFRAME (frame))->top_frame))
        /* Mark previously displayed frame as now obscured.  */
-       XFRAME (FRAME_TTY (XFRAME (frame))->top_frame)->async_visible = 2;
-      XFRAME (frame)->async_visible = 1;
+       SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (XFRAME (frame))->top_frame), 2);
+      SET_FRAME_VISIBLE (XFRAME (frame), 1);
       FRAME_TTY (XFRAME (frame))->top_frame = frame;
     }
 
       FRAME_TTY (XFRAME (frame))->top_frame = frame;
     }
 
@@ -845,7 +860,7 @@ to that frame.  */)
   (Lisp_Object event)
 {
   /* Preserve prefix arg that the command loop just cleared.  */
   (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);
 }
   Frun_hooks (1, &Qmouse_leave_buffer_hook);
   return do_switch_frame (event, 0, 0, Qnil);
 }
@@ -871,150 +886,98 @@ DEFUN ("frame-list", Fframe_list, Sframe_list,
   return frames;
 }
 
   return frames;
 }
 
-/* Return the next frame in the frame list after FRAME.
-   If MINIBUF is nil, exclude minibuffer-only frames.
-   If MINIBUF is a window, include only its own frame
-   and any frame now using that window as the minibuffer.
-   If MINIBUF is `visible', include all visible frames.
-   If MINIBUF is 0, include all visible and iconified frames.
-   Otherwise, include all frames.  */
+/* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the
+   same tty (for tty frames) or among frames which uses FRAME's keyboard.
+   If MINIBUF is nil, do not consider minibuffer-only candidate.
+   If MINIBUF is `visible', do not consider an invisible candidate. 
+   If MINIBUF is a window, consider only its own frame and candidate now
+   using that window as the minibuffer.
+   If MINIBUF is 0, consider candidate if it is visible or iconified.
+   Otherwise consider any candidate and return nil if CANDIDATE is not
+   acceptable.  */
+
+static Lisp_Object
+candidate_frame (Lisp_Object candidate, Lisp_Object frame, Lisp_Object minibuf)
+{
+  struct frame *c = XFRAME (candidate), *f = XFRAME (frame);
+
+  if ((!FRAME_TERMCAP_P (c) && !FRAME_TERMCAP_P (f)
+       && FRAME_KBOARD (c) == FRAME_KBOARD (f))
+      || (FRAME_TERMCAP_P (c) && FRAME_TERMCAP_P (f)
+         && FRAME_TTY (c) == FRAME_TTY (f)))
+    {
+      if (NILP (minibuf))
+       {
+         if (!FRAME_MINIBUF_ONLY_P (c))
+           return candidate;
+       }
+      else if (EQ (minibuf, Qvisible))
+       {
+         if (FRAME_VISIBLE_P (c))
+           return candidate;
+       }
+      else if (WINDOWP (minibuf))
+       {
+         if (EQ (FRAME_MINIBUF_WINDOW (c), minibuf)
+             || EQ (WINDOW_FRAME (XWINDOW (minibuf)), candidate)
+             || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
+                    FRAME_FOCUS_FRAME (c)))
+           return candidate;
+       }
+      else if (XFASTINT (minibuf) == 0)
+       {
+         if (FRAME_VISIBLE_P (c) || FRAME_ICONIFIED_P (c))
+           return candidate;
+       }
+      else
+       return candidate;
+    }
+  return Qnil;
+}
+
+/* Return the next frame in the frame list after FRAME.  */
 
 static Lisp_Object
 next_frame (Lisp_Object frame, Lisp_Object minibuf)
 {
 
 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.  */
   int passed = 0;
 
   /* There must always be at least one frame in Vframe_list.  */
-  if (! CONSP (Vframe_list))
-    abort ();
-
-  /* If this frame is dead, it won't be in Vframe_list, and we'll loop
-     forever.  Forestall that.  */
-  CHECK_LIVE_FRAME (frame);
+  eassert (CONSP (Vframe_list));
 
 
-  while (1)
-    for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
+  while (passed < 2)
+    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)))
-                || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
-                    && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame)))))
+       if (passed)
          {
          {
-           /* Decide whether this frame is eligible to be returned.  */
-
-           /* If we've looped all the way around without finding any
-              eligible frames, return the original frame.  */
-           if (EQ (f, frame))
-             return f;
-
-           /* Let minibuf decide if this frame is acceptable.  */
-           if (NILP (minibuf))
-             {
-               if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
-                 return f;
-             }
-           else if (EQ (minibuf, Qvisible))
-             {
-               FRAME_SAMPLE_VISIBILITY (XFRAME (f));
-               if (FRAME_VISIBLE_P (XFRAME (f)))
-                 return f;
-             }
-           else if (INTEGERP (minibuf) && XINT (minibuf) == 0)
-             {
-               FRAME_SAMPLE_VISIBILITY (XFRAME (f));
-               if (FRAME_VISIBLE_P (XFRAME (f))
-                   || FRAME_ICONIFIED_P (XFRAME (f)))
-                 return f;
-             }
-           else if (WINDOWP (minibuf))
-             {
-               if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
-                   || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
-                   || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
-                          FRAME_FOCUS_FRAME (XFRAME (f))))
-                 return f;
-             }
-           else
+           f = candidate_frame (f, frame, minibuf);
+           if (!NILP (f))
              return f;
          }
              return f;
          }
-
        if (EQ (frame, f))
          passed++;
       }
        if (EQ (frame, f))
          passed++;
       }
+  return frame;
 }
 
 }
 
-/* Return the previous frame in the frame list before FRAME.
-   If MINIBUF is nil, exclude minibuffer-only frames.
-   If MINIBUF is a window, include only its own frame
-   and any frame now using that window as the minibuffer.
-   If MINIBUF is `visible', include all visible frames.
-   If MINIBUF is 0, include all visible and iconified frames.
-   Otherwise, include all frames.  */
+/* Return the previous frame in the frame list before FRAME.  */
 
 static Lisp_Object
 prev_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.  */
 
   /* 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;
       if (EQ (frame, f) && !NILP (prev))
        return prev;
-
-      if ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
-           && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
-          || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
-              && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame))))
-       {
-         /* Decide whether this frame is eligible to be returned,
-            according to minibuf.  */
-         if (NILP (minibuf))
-           {
-             if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
-               prev = f;
-           }
-         else if (WINDOWP (minibuf))
-           {
-             if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
-                 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
-                 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
-                        FRAME_FOCUS_FRAME (XFRAME (f))))
-               prev = f;
-           }
-         else if (EQ (minibuf, Qvisible))
-           {
-             FRAME_SAMPLE_VISIBILITY (XFRAME (f));
-             if (FRAME_VISIBLE_P (XFRAME (f)))
-               prev = f;
-           }
-         else if (XFASTINT (minibuf) == 0)
-           {
-             FRAME_SAMPLE_VISIBILITY (XFRAME (f));
-             if (FRAME_VISIBLE_P (XFRAME (f))
-                 || FRAME_ICONIFIED_P (XFRAME (f)))
-               prev = f;
-           }
-         else
-           prev = f;
-       }
+      f = candidate_frame (f, frame, minibuf);
+      if (!NILP (f))
+       prev = f;
     }
 
   /* We've scanned the entire list.  */
     }
 
   /* We've scanned the entire list.  */
@@ -1045,7 +1008,6 @@ Otherwise, include all frames.  */)
 {
   if (NILP (frame))
     frame = selected_frame;
 {
   if (NILP (frame))
     frame = selected_frame;
-
   CHECK_LIVE_FRAME (frame);
   return next_frame (frame, miniframe);
 }
   CHECK_LIVE_FRAME (frame);
   return next_frame (frame, miniframe);
 }
@@ -1076,11 +1038,10 @@ Otherwise, include all frames.  */)
 static int
 other_visible_frames (FRAME_PTR f)
 {
 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;
 
       if (f == XFRAME (this))
        continue;
 
@@ -1088,10 +1049,7 @@ other_visible_frames (FRAME_PTR f)
         and note any recent change in visibility.  */
 #ifdef HAVE_WINDOW_SYSTEM
       if (FRAME_WINDOW_P (XFRAME (this)))
         and note any recent change in visibility.  */
 #ifdef HAVE_WINDOW_SYSTEM
       if (FRAME_WINDOW_P (XFRAME (this)))
-       {
-         x_sync (XFRAME (this));
-         FRAME_SAMPLE_VISIBILITY (XFRAME (this));
-       }
+       x_sync (XFRAME (this));
 #endif
 
       if (FRAME_VISIBLE_P (XFRAME (this))
 #endif
 
       if (FRAME_VISIBLE_P (XFRAME (this))
@@ -1111,22 +1069,11 @@ other_visible_frames (FRAME_PTR f)
 Lisp_Object
 delete_frame (Lisp_Object frame, Lisp_Object force)
 {
 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;
 
   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;
 
   if (! FRAME_LIVE_P (f))
     return Qnil;
@@ -1139,19 +1086,16 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
   if (NILP (XCDR (Vframe_list)) && !EQ (force, Qnoelisp))
     error ("Attempt to delete the only frame");
 
   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?  */
   /* 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
          if (! EQ (this, frame)
              && EQ (frame,
                     WINDOW_FRAME (XWINDOW
@@ -1167,13 +1111,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.  */
 
   /* 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
     ;
   else if (EQ (force, Qnoelisp))
     pending_funcalls
@@ -1242,8 +1186,10 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
   /* Don't allow minibuf_window to remain on a deleted frame.  */
   if (EQ (f->minibuffer_window, minibuf_window))
     {
   /* Don't allow minibuf_window to remain on a deleted frame.  */
   if (EQ (f->minibuffer_window, minibuf_window))
     {
-      Fset_window_buffer (sf->minibuffer_window,
-                         XWINDOW (minibuf_window)->buffer, Qnil);
+      /* 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,
       minibuf_window = sf->minibuffer_window;
 
       /* If the dying minibuffer window was selected,
@@ -1276,16 +1222,21 @@ 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 (f->root_window);
   /* Mark all the windows that used to be on FRAME as deleted, and then
      remove the reference to them.  */
   delete_all_child_windows (f->root_window);
-  f->root_window = Qnil;
+  fset_root_window (f, Qnil);
 
   Vframe_list = Fdelq (frame, Vframe_list);
 
   Vframe_list = Fdelq (frame, Vframe_list);
-  FRAME_SET_VISIBLE (f, 0);
+  SET_FRAME_VISIBLE (f, 0);
 
   /* Allow the vector of menu bar contents to be freed in the next
      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.  */
 
   /* Allow the vector of menu bar contents to be freed in the next
      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.  */
-  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);
 
   free_font_driver_list (f);
   xfree (f->namebuf);
@@ -1294,7 +1245,6 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
   xfree (FRAME_DELETEN_COST (f));
   xfree (FRAME_INSERTN_COST (f));
   xfree (FRAME_DELETE_COST (f));
   xfree (FRAME_DELETEN_COST (f));
   xfree (FRAME_INSERTN_COST (f));
   xfree (FRAME_DELETE_COST (f));
-  xfree (FRAME_MESSAGE_BUF (f));
 
   /* 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 terminal
 
   /* 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 terminal
@@ -1309,10 +1259,10 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
   {
     struct terminal *terminal = FRAME_TERMINAL (f);
     f->output_data.nothing = 0;
   {
     struct terminal *terminal = FRAME_TERMINAL (f);
     f->output_data.nothing = 0;
-    f->terminal = 0;             /* Now the frame is dead. */
+    f->terminal = 0;             /* Now the frame is dead.  */
 
     /* If needed, delete the terminal that this frame was on.
 
     /* If needed, delete the terminal that this frame was on.
-       (This must be done after the frame is killed.) */
+       (This must be done after the frame is killed.)  */
     terminal->reference_count--;
 #ifdef USE_GTK
     /* FIXME: Deleting the terminal crashes emacs because of a GTK
     terminal->reference_count--;
 #ifdef USE_GTK
     /* FIXME: Deleting the terminal crashes emacs because of a GTK
@@ -1337,15 +1287,13 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
      another one.  */
   if (f == last_nonminibuf_frame)
     {
      another one.  */
   if (f == last_nonminibuf_frame)
     {
-      Lisp_Object frames;
+      Lisp_Object frames, this;
 
       last_nonminibuf_frame = 0;
 
 
       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;
          if (!FRAME_MINIBUF_ONLY_P (f))
            {
              last_nonminibuf_frame = f;
@@ -1358,27 +1306,13 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
      single-kboard state if we're in it for this kboard.  */
   if (kb != NULL)
     {
      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.  */
       /* 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;
+      Lisp_Object 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);
 
       if (NILP (frame_on_same_kboard))
        not_single_kboard_state (kb);
@@ -1390,27 +1324,16 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
      frames with other windows.  */
   if (kb != NULL && EQ (frame, KVAR (kb, Vdefault_minibuffer_frame)))
     {
      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.  */
 
       /* 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.  */
       /* 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.  */
 
          /* Consider only frames on the same kboard
             and only those with minibuffers.  */
@@ -1435,17 +1358,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))
             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.  */
        }
       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.  */
     }
 
   /* 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;
     update_mode_lines = 1;
 
   return Qnil;
@@ -1485,31 +1408,31 @@ and returns whatever that function returns.  */)
 {
   FRAME_PTR f;
   Lisp_Object lispy_dummy;
 {
   FRAME_PTR f;
   Lisp_Object lispy_dummy;
-  enum scroll_bar_part party_dummy;
   Lisp_Object x, y, retval;
   Lisp_Object x, y, retval;
-  int col, row;
-  Time long_dummy;
   struct gcpro gcpro1;
 
   f = SELECTED_FRAME ();
   x = y = Qnil;
 
   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)
   /* 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))
     {
   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);
     }
       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);
   XSETFRAME (lispy_dummy, f);
   retval = Fcons (lispy_dummy, Fcons (x, y));
   GCPRO1 (retval);
@@ -1531,21 +1454,22 @@ and nil for X and Y.  */)
 {
   FRAME_PTR f;
   Lisp_Object lispy_dummy;
 {
   FRAME_PTR f;
   Lisp_Object lispy_dummy;
-  enum scroll_bar_part party_dummy;
   Lisp_Object x, y;
   Lisp_Object x, y;
-  Time long_dummy;
 
   f = SELECTED_FRAME ();
   x = y = Qnil;
 
 
   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)
   /* 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));
 }
   XSETFRAME (lispy_dummy, f);
   return Fcons (lispy_dummy, Fcons (x, y));
 }
@@ -1576,7 +1500,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
     /* 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);
   if (FRAME_MSDOS_P (XFRAME (frame)))
     {
       Fselect_frame (frame, Qnil);
@@ -1617,7 +1541,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
     /* 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);
   if (FRAME_MSDOS_P (XFRAME (frame)))
     {
       Fselect_frame (frame, Qnil);
@@ -1644,25 +1568,20 @@ DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
 If omitted, FRAME defaults to the currently selected frame.  */)
   (Lisp_Object frame)
 {
 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
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
-  if (FRAME_WINDOW_P (XFRAME (frame)))
-    {
-      FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
-      x_make_frame_visible (XFRAME (frame));
-    }
+  if (FRAME_WINDOW_P (f))
+    x_make_frame_visible (f);
 #endif
 
 #endif
 
-  make_frame_visible_1 (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++;
 
 
   /* Make menu bar update for the Buffers and Frames menus.  */
   windows_or_buffers_changed++;
 
+  XSETFRAME (frame, f);
   return frame;
 }
 
   return frame;
 }
 
@@ -1679,7 +1598,7 @@ make_frame_visible_1 (Lisp_Object window)
       w = XWINDOW (window);
 
       if (!NILP (w->buffer))
       w = XWINDOW (window);
 
       if (!NILP (w->buffer))
-       BVAR (XBUFFER (w->buffer), display_time) = Fcurrent_time ();
+       bset_display_time (XBUFFER (w->buffer), Fcurrent_time ());
 
       if (!NILP (w->vchild))
        make_frame_visible_1 (w->vchild);
 
       if (!NILP (w->vchild))
        make_frame_visible_1 (w->vchild);
@@ -1703,27 +1622,26 @@ always considered visible, whether or not they are currently being
 displayed in the terminal.  */)
   (Lisp_Object frame, Lisp_Object force)
 {
 displayed in the terminal.  */)
   (Lisp_Object frame, Lisp_Object force)
 {
-  if (NILP (frame))
-    frame = selected_frame;
-
-  CHECK_LIVE_FRAME (frame);
+  struct frame *f = decode_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.  */
     error ("Attempt to make invisible the sole visible or iconified frame");
 
   /* Don't allow minibuf_window to remain on a deleted frame.  */
-  if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
+  if (EQ (f->minibuffer_window, minibuf_window))
     {
       struct frame *sf = XFRAME (selected_frame);
     {
       struct frame *sf = XFRAME (selected_frame);
-      Fset_window_buffer (sf->minibuffer_window,
-                         XWINDOW (minibuf_window)->buffer, Qnil);
+      /* 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
       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.  */
 #endif
 
   /* Make menu bar update for the Buffers and Frames menus.  */
@@ -1738,30 +1656,23 @@ DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
 If omitted, FRAME defaults to the currently selected frame.  */)
   (Lisp_Object 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 (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);
     {
       struct frame *sf = XFRAME (selected_frame);
-      Fset_window_buffer (sf->minibuffer_window,
-                         XWINDOW (minibuf_window)->buffer, Qnil);
+      /* 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
       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.  */
 #endif
 
   /* Make menu bar update for the Buffers and Frames menus.  */
@@ -1785,8 +1696,6 @@ currently being displayed on the terminal.  */)
 {
   CHECK_LIVE_FRAME (frame);
 
 {
   CHECK_LIVE_FRAME (frame);
 
-  FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
-
   if (FRAME_VISIBLE_P (XFRAME (frame)))
     return Qt;
   if (FRAME_ICONIFIED_P (XFRAME (frame)))
   if (FRAME_VISIBLE_P (XFRAME (frame)))
     return Qt;
   if (FRAME_ICONIFIED_P (XFRAME (frame)))
@@ -1799,20 +1708,12 @@ DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
        doc: /* Return a list of all frames now \"visible\" (being updated).  */)
   (void)
 {
        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;
 }
 
   return value;
 }
 
@@ -1825,13 +1726,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)
 {
 doesn't support multiple overlapping frames, this function selects FRAME.  */)
   (Lisp_Object frame)
 {
-  struct frame *f;
-  if (NILP (frame))
-    frame = selected_frame;
-
-  CHECK_LIVE_FRAME (frame);
+  struct frame *f = decode_live_frame (frame);
 
 
-  f = XFRAME (frame);
+  XSETFRAME (frame, f);
 
   if (FRAME_TERMCAP_P (f))
     /* On a text terminal select FRAME.  */
 
   if (FRAME_TERMCAP_P (f))
     /* On a text terminal select FRAME.  */
@@ -1854,14 +1751,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)
 {
 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);
 
   if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
     (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0);
@@ -1877,8 +1767,8 @@ In other words, switch-frame events caused by events in FRAME will
 request a switch to FOCUS-FRAME, and `last-event-frame' will be
 FOCUS-FRAME after reading an event typed at FRAME.
 
 request a switch to FOCUS-FRAME, and `last-event-frame' will be
 FOCUS-FRAME after reading an event typed at FRAME.
 
-If FOCUS-FRAME is omitted or nil, any existing redirection is
-canceled, and the frame again receives its own keystrokes.
+If FOCUS-FRAME is nil, any existing redirection is canceled, and the
+frame again receives its own keystrokes.
 
 Focus redirection is useful for temporarily redirecting keystrokes to
 a surrogate minibuffer frame when a frame doesn't have its own
 
 Focus redirection is useful for temporarily redirecting keystrokes to
 a surrogate minibuffer frame when a frame doesn't have its own
@@ -1897,19 +1787,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)
 {
 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.  */
   /* 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);
 
 
   if (! NILP (focus_frame))
     CHECK_LIVE_FRAME (focus_frame);
 
-  f = XFRAME (frame);
-
-  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);
 
   if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
     (*FRAME_TERMINAL (f)->frame_rehighlight_hook) (f);
@@ -1918,21 +1804,21 @@ 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.
        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)
 {
 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));
 }
 
 
 \f
 /* Return the value of frame parameter PROP in frame FRAME.  */
 
 }
 
 
 \f
 /* Return the value of frame parameter PROP in frame FRAME.  */
 
+#ifdef HAVE_WINDOW_SYSTEM
 #if !HAVE_NS
 static
 #endif
 #if !HAVE_NS
 static
 #endif
@@ -1946,22 +1832,7 @@ get_frame_param (register struct frame *frame, Lisp_Object prop)
     return tem;
   return Fcdr (tem);
 }
     return tem;
   return Fcdr (tem);
 }
-
-/* Return the buffer-predicate of the selected frame.  */
-
-Lisp_Object
-frame_buffer_predicate (Lisp_Object frame)
-{
-  return XFRAME (frame)->buffer_predicate;
-}
-
-/* Return the buffer-list of the selected frame.  */
-
-static Lisp_Object
-frame_buffer_list (Lisp_Object frame)
-{
-  return XFRAME (frame)->buffer_list;
-}
+#endif
 
 /* Discard BUFFER from the buffer-list and buried-buffer-list of each frame.  */
 
 
 /* Discard BUFFER from the buffer-list and buried-buffer-list of each frame.  */
 
@@ -1972,10 +1843,10 @@ frames_discard_buffer (Lisp_Object buffer)
 
   FOR_EACH_FRAME (tail, frame)
     {
 
   FOR_EACH_FRAME (tail, frame)
     {
-      XFRAME (frame)->buffer_list
-       = Fdelq (buffer, XFRAME (frame)->buffer_list);
-      XFRAME (frame)->buried_buffer_list
-        = Fdelq (buffer, 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,13 +1894,10 @@ 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.  */
 
       /* Check for no change needed in this very common case
         before we do any consing.  */
-      if (frame_name_fnn_p (SSDATA (f->name),
-                           SBYTES (f->name)))
+      if (frame_name_fnn_p (SSDATA (f->name), SBYTES (f->name)))
        return;
 
        return;
 
-      tty_frame_count++;
-      sprintf (namebuf, "F%"pMd, tty_frame_count);
-      name = build_string (namebuf);
+      name = make_formatted_string (namebuf, "F%"pMd, ++tty_frame_count);
     }
   else
     {
     }
   else
     {
@@ -2045,7 +1913,7 @@ set_term_frame_name (struct frame *f, Lisp_Object name)
        error ("Frame names of the form F<num> are usurped by Emacs");
     }
 
        error ("Frame names of the form F<num> are usurped by Emacs");
     }
 
-  f->name = name;
+  fset_name (f, name);
   update_mode_lines = 1;
 }
 
   update_mode_lines = 1;
 }
 
@@ -2062,7 +1930,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);
       for (; CONSP (val); val = XCDR (val))
        if (!NILP (Fbuffer_live_p (XCAR (val))))
          list = Fcons (XCAR (val), list);
-      f->buffer_list = Fnreverse (list);
+      fset_buffer_list (f, Fnreverse (list));
       return;
     }
   if (EQ (prop, Qburied_buffer_list))
       return;
     }
   if (EQ (prop, Qburied_buffer_list))
@@ -2071,7 +1939,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);
       for (; CONSP (val); val = XCDR (val))
        if (!NILP (Fbuffer_live_p (XCAR (val))))
          list = Fcons (XCAR (val), list);
-      f->buried_buffer_list = Fnreverse (list);
+      fset_buried_buffer_list (f, Fnreverse (list));
       return;
     }
 
       return;
     }
 
@@ -2089,11 +1957,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;
        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;
          }
              swap_in_global_binding (sym);
            break;
          }
-       default: abort ();
+       default: emacs_abort ();
        }
     }
 
        }
     }
 
@@ -2108,7 +1976,7 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
   /* Update the frame parameter alist.  */
   old_alist_elt = Fassq (prop, f->param_alist);
   if (EQ (old_alist_elt, Qnil))
   /* Update the frame parameter alist.  */
   old_alist_elt = Fassq (prop, f->param_alist);
   if (EQ (old_alist_elt, Qnil))
-    f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
+    fset_param_alist (f, Fcons (Fcons (prop, val), f->param_alist));
   else
     Fsetcdr (old_alist_elt, val);
 
   else
     Fsetcdr (old_alist_elt, val);
 
@@ -2116,7 +1984,7 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
      in addition to the alist.  */
 
   if (EQ (prop, Qbuffer_predicate))
      in addition to the alist.  */
 
   if (EQ (prop, Qbuffer_predicate))
-    f->buffer_predicate = val;
+    fset_buffer_predicate (f, val);
 
   if (! FRAME_WINDOW_P (f))
     {
 
   if (! FRAME_WINDOW_P (f))
     {
@@ -2136,7 +2004,7 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
        error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
 
       /* Install the chosen minibuffer window, with proper buffer.  */
        error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
 
       /* Install the chosen minibuffer window, with proper buffer.  */
-      f->minibuffer_window = val;
+      fset_minibuffer_window (f, val);
     }
 }
 
     }
 }
 
@@ -2144,20 +2012,14 @@ 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.
        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;
   (Lisp_Object frame)
 {
   Lisp_Object alist;
-  FRAME_PTR f;
+  struct frame *f = decode_any_frame (frame);
   int height, width;
   struct gcpro gcpro1;
 
   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;
 
   if (!FRAME_LIVE_P (f))
     return Qnil;
 
@@ -2218,8 +2080,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));
                   : 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, 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
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -2244,17 +2106,12 @@ 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)
 {
 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);
 
   CHECK_SYMBOL (parameter);
 
-  f = XFRAME (frame);
-  value = Qnil;
+  XSETFRAME (frame, f);
 
   if (FRAME_LIVE_P (f))
     {
 
   if (FRAME_LIVE_P (f))
     {
@@ -2334,14 +2191,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)
 {
 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;
 
   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))
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
@@ -2396,20 +2248,15 @@ 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.
 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)
 {
 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
 #ifdef HAVE_WINDOW_SYSTEM
+  struct frame *f = decode_any_frame (frame);
+
   if (FRAME_WINDOW_P (f))
   if (FRAME_WINDOW_P (f))
-    return make_number (x_char_height (f));
+    return make_number (FRAME_LINE_HEIGHT (f));
   else
 #endif
     return make_number (1);
   else
 #endif
     return make_number (1);
@@ -2419,21 +2266,16 @@ 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.
 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)
 {
 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
 #ifdef HAVE_WINDOW_SYSTEM
+  struct frame *f = decode_any_frame (frame);
+
   if (FRAME_WINDOW_P (f))
   if (FRAME_WINDOW_P (f))
-    return make_number (x_char_width (f));
+    return make_number (FRAME_COLUMN_WIDTH (f));
   else
 #endif
     return make_number (1);
   else
 #endif
     return make_number (1);
@@ -2442,30 +2284,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.
 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.
 
 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)
 {
 
 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))
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
@@ -2479,15 +2313,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.
        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)
 {
   (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))
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
@@ -2501,18 +2330,13 @@ 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
        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)
 {
   (Lisp_Object frame)
 {
-  struct frame *f;
-
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_FRAME (frame);
-  f = XFRAME (frame);
-
 #ifdef FRAME_TOOLBAR_WIDTH
 #ifdef FRAME_TOOLBAR_WIDTH
+  struct frame *f = decode_any_frame (frame);
+
   if (FRAME_WINDOW_P (f))
     return make_number (FRAME_TOOLBAR_WIDTH (f));
 #endif
   if (FRAME_WINDOW_P (f))
     return make_number (FRAME_TOOLBAR_WIDTH (f));
 #endif
@@ -2525,13 +2349,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)
 {
 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);
 
   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
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -2553,12 +2373,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)
 {
 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);
   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
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -2680,7 +2497,7 @@ static const struct frame_parm_table frame_parms[] =
   {"tool-bar-position",                &Qtool_bar_position},
 };
 
   {"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).
 
 /* Calculate fullscreen size.  Return in *TOP_POS and *LEFT_POS the
    wanted positions of the WM window (not Emacs window).
@@ -2724,7 +2541,7 @@ x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int
   *height = newheight;
 }
 
   *height = newheight;
 }
 
-#endif /* WINDOWSNT */
+#endif /* HAVE_NTGUI */
 
 #ifdef HAVE_WINDOW_SYSTEM
 
 
 #ifdef HAVE_WINDOW_SYSTEM
 
@@ -2760,11 +2577,11 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
   struct gcpro gcpro1, gcpro2;
 
   i = 0;
   struct gcpro gcpro1, gcpro2;
 
   i = 0;
-  for (tail = alist; CONSP (tail); tail = Fcdr (tail))
+  for (tail = alist; CONSP (tail); tail = XCDR (tail))
     i++;
 
     i++;
 
-  parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
-  values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
+  parms = alloca (i * sizeof *parms);
+  values = alloca (i * sizeof *values);
 
   /* Extract parm names and values into those vectors.  */
 
 
   /* Extract parm names and values into those vectors.  */
 
@@ -2874,7 +2691,7 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
     }
 
   /* Don't die if just one of these was set.  */
     }
 
   /* Don't die if just one of these was set.  */
-  if (! TYPE_RANGED_INTEGERP (int, left))
+  if (EQ (left, Qunbound))
     {
       left_no_change = 1;
       if (f->left_pos < 0)
     {
       left_no_change = 1;
       if (f->left_pos < 0)
@@ -2882,7 +2699,7 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
       else
        XSETINT (left, f->left_pos);
     }
       else
        XSETINT (left, f->left_pos);
     }
-  if (! TYPE_RANGED_INTEGERP (int, top))
+  if (EQ (top, Qunbound))
     {
       top_no_change = 1;
       if (f->top_pos < 0)
     {
       top_no_change = 1;
       if (f->top_pos < 0)
@@ -3011,9 +2828,9 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
 void
 x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
 {
 void
 x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
 {
-  char buf[16];
   Lisp_Object tem;
   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.  */
 
   /* Represent negative positions (off the top or left screen edge)
      in a way that Fmodify_frame_parameters will understand correctly.  */
@@ -3050,24 +2867,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.  */
      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);
-  sprintf (buf, "%lu", w);
+  w = (uintptr_t) FRAME_X_WINDOW (f);
   store_in_alist (alistptr, Qwindow_id,
   store_in_alist (alistptr, Qwindow_id,
-                 build_string (buf));
+                 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
 #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);
-      sprintf (buf, "%lu", w);
-    }
+    w = (uintptr_t) FRAME_OUTER_WINDOW (f);
   store_in_alist (alistptr, Qouter_window_id,
   store_in_alist (alistptr, Qouter_window_id,
-                 build_string (buf));
+                 make_formatted_string (buf, "%"pMu, w));
 #endif
   store_in_alist (alistptr, Qicon_name, f->icon_name);
 #endif
   store_in_alist (alistptr, Qicon_name, f->icon_name);
-  FRAME_SAMPLE_VISIBILITY (f);
   store_in_alist (alistptr, Qvisibility,
                  (FRAME_VISIBLE_P (f) ? Qt
                   : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
   store_in_alist (alistptr, Qvisibility,
                  (FRAME_VISIBLE_P (f) ? Qt
                   : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
@@ -3159,8 +2971,11 @@ x_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
 void
 x_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
 void
 x_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
-  Lisp_Object font_object, font_param = Qnil;
+  Lisp_Object font_object;
   int fontset = -1;
   int fontset = -1;
+#ifdef HAVE_X_WINDOWS
+  Lisp_Object font_param = arg;
+#endif
 
   /* Set the frame parameter back to the old value because we may
      fail to use ARG as the new parameter value.  */
 
   /* Set the frame parameter back to the old value because we may
      fail to use ARG as the new parameter value.  */
@@ -3171,20 +2986,17 @@ x_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
      never fail.  */
   if (STRINGP (arg))
     {
      never fail.  */
   if (STRINGP (arg))
     {
-      font_param = arg;
       fontset = fs_query_fontset (arg, 0);
       if (fontset < 0)
        {
       fontset = fs_query_fontset (arg, 0);
       if (fontset < 0)
        {
-         font_object = font_open_by_name (f, SSDATA (arg));
+         font_object = font_open_by_name (f, arg);
          if (NILP (font_object))
            error ("Font `%s' is not defined", SSDATA (arg));
          arg = AREF (font_object, FONT_NAME_INDEX);
        }
       else if (fontset > 0)
        {
          if (NILP (font_object))
            error ("Font `%s' is not defined", SSDATA (arg));
          arg = AREF (font_object, FONT_NAME_INDEX);
        }
       else if (fontset > 0)
        {
-         Lisp_Object ascii_font = fontset_ascii (fontset);
-
-         font_object = font_open_by_name (f, SSDATA (ascii_font));
+         font_object = font_open_by_name (f, fontset_ascii (fontset));
          if (NILP (font_object))
            error ("Font `%s' is not defined", SDATA (arg));
          arg = AREF (font_object, FONT_NAME_INDEX);
          if (NILP (font_object))
            error ("Font `%s' is not defined", SDATA (arg));
          arg = AREF (font_object, FONT_NAME_INDEX);
@@ -3202,12 +3014,16 @@ x_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
        error ("Unknown fontset: %s", SDATA (XCAR (arg)));
       font_object = XCDR (arg);
       arg = AREF (font_object, FONT_NAME_INDEX);
        error ("Unknown fontset: %s", SDATA (XCAR (arg)));
       font_object = XCDR (arg);
       arg = AREF (font_object, FONT_NAME_INDEX);
+#ifdef HAVE_X_WINDOWS
       font_param = Ffont_get (font_object, QCname);
       font_param = Ffont_get (font_object, QCname);
+#endif
     }
   else if (FONT_OBJECT_P (arg))
     {
       font_object = arg;
     }
   else if (FONT_OBJECT_P (arg))
     {
       font_object = arg;
+#ifdef HAVE_X_WINDOWS
       font_param = Ffont_get (font_object, QCname);
       font_param = Ffont_get (font_object, QCname);
+#endif
       /* This is to store the XLFD font name in the frame parameter for
         backward compatibility.  We should store the font-object
         itself in the future.  */
       /* This is to store the XLFD font name in the frame parameter for
         backward compatibility.  We should store the font-object
         itself in the future.  */
@@ -3220,6 +3036,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);
 
          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;
        }
          if (! font_match_p (spec, font_object))
            fontset = -1;
        }
@@ -3266,7 +3085,7 @@ x_set_font_backend (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
       new_value = Qnil;
       while (*p0)
        {
       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);
          if (p0 < p1)
            new_value = Fcons (Fintern (make_string (p0, p1 - p0), Qnil),
                               new_value);
@@ -3274,7 +3093,7 @@ x_set_font_backend (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
            {
              int c;
 
            {
              int c;
 
-             while ((c = *++p1) && isspace (c));
+             while ((c = *++p1) && c_isspace (c));
            }
          p0 = p1;
        }
            }
          p0 = p1;
        }
@@ -3516,9 +3335,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)
     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);
   x_set_frame_alpha (f);
-  UNBLOCK_INPUT;
+  unblock_input ();
 #endif
 
   return;
 #endif
 
   return;
@@ -3625,17 +3444,17 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li
 
   /* Allocate space for the components, the dots which separate them,
      and the final '\0'.  Make them big enough for the worst case.  */
 
   /* Allocate space for the components, the dots which separate them,
      and the final '\0'.  Make them big enough for the worst case.  */
-  name_key = (char *) alloca (SBYTES (Vx_resource_name)
-                             + (STRINGP (component)
-                                ? SBYTES (component) : 0)
-                             + SBYTES (attribute)
-                             + 3);
-
-  class_key = (char *) alloca (SBYTES (Vx_resource_class)
-                              + SBYTES (class)
-                              + (STRINGP (subclass)
-                                 ? SBYTES (subclass) : 0)
-                              + 3);
+  name_key = alloca (SBYTES (Vx_resource_name)
+                    + (STRINGP (component)
+                       ? SBYTES (component) : 0)
+                    + SBYTES (attribute)
+                    + 3);
+
+  class_key = alloca (SBYTES (Vx_resource_class)
+                     + SBYTES (class)
+                     + (STRINGP (subclass)
+                        ? SBYTES (subclass) : 0)
+                     + 3);
 
   /* Start with emacs.FRAMENAME for the name (the specific one)
      and with `Emacs' for the class key (the general one).  */
 
   /* Start with emacs.FRAMENAME for the name (the specific one)
      and with `Emacs' for the class key (the general one).  */
@@ -3701,8 +3520,6 @@ display_x_get_resource (Display_Info *dpyinfo, Lisp_Object attribute, Lisp_Objec
 char *
 x_get_resource_string (const char *attribute, const char *class)
 {
 char *
 x_get_resource_string (const char *attribute, const char *class)
 {
-  char *name_key;
-  char *class_key;
   char *result;
   struct frame *sf = SELECTED_FRAME ();
   ptrdiff_t invocation_namelen = SBYTES (Vinvocation_name);
   char *result;
   struct frame *sf = SELECTED_FRAME ();
   ptrdiff_t invocation_namelen = SBYTES (Vinvocation_name);
@@ -3710,9 +3527,8 @@ x_get_resource_string (const char *attribute, const char *class)
 
   /* Allocate space for the components, the dots which separate them,
      and the final '\0'.  */
 
   /* Allocate space for the components, the dots which separate them,
      and the final '\0'.  */
-  SAFE_ALLOCA (name_key, char *, invocation_namelen + strlen (attribute) + 2);
-  class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
-                              + strlen (class) + 2);
+  char *name_key = SAFE_ALLOCA (invocation_namelen + strlen (attribute) + 2);
+  char *class_key = alloca ((sizeof (EMACS_CLASS) - 1) + strlen (class) + 2);
 
   esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute);
   sprintf (class_key, "%s.%s", EMACS_CLASS, class);
 
   esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute);
   sprintf (class_key, "%s.%s", EMACS_CLASS, class);
@@ -3825,7 +3641,7 @@ x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param,
              }
 
            default:
              }
 
            default:
-             abort ();
+             emacs_abort ();
            }
        }
       else
            }
        }
       else
@@ -3883,6 +3699,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
 
 \f
 /* NS used to define x-parse-geometry in ns-win.el, but that confused
@@ -3903,15 +3808,16 @@ or a list (- N) meaning -N pixels relative to bottom/right corner.
 On Nextstep, this just calls `ns-parse-geometry'.  */)
   (Lisp_Object string)
 {
 On Nextstep, this just calls `ns-parse-geometry'.  */)
   (Lisp_Object string)
 {
-#ifdef HAVE_NS
-  call1 (Qns_parse_geometry, string);
-#else
   int geometry, x, y;
   unsigned int width, height;
   Lisp_Object result;
 
   CHECK_STRING (string);
 
   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;
   geometry = XParseGeometry (SSDATA (string),
                             &x, &y, &width, &height);
   result = Qnil;
@@ -3947,7 +3853,6 @@ On Nextstep, this just calls `ns-parse-geometry'.  */)
     result = Fcons (Fcons (Qheight, make_number (height)), result);
 
   return result;
     result = Fcons (Fcons (Qheight, make_number (height)), result);
 
   return result;
-#endif /* HAVE_NS */
 }
 
 
 }
 
 
@@ -4186,12 +4091,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)
 {
 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
 }
 
 \f
@@ -4210,6 +4110,7 @@ syms_of_frame (void)
   DEFSYM (Qminibuffer, "minibuffer");
   DEFSYM (Qmodeline, "modeline");
   DEFSYM (Qonly, "only");
   DEFSYM (Qminibuffer, "minibuffer");
   DEFSYM (Qmodeline, "modeline");
   DEFSYM (Qonly, "only");
+  DEFSYM (Qnone, "none");
   DEFSYM (Qwidth, "width");
   DEFSYM (Qgeometry, "geometry");
   DEFSYM (Qicon_left, "icon-left");
   DEFSYM (Qwidth, "width");
   DEFSYM (Qgeometry, "geometry");
   DEFSYM (Qicon_left, "icon-left");
@@ -4227,7 +4128,6 @@ syms_of_frame (void)
   DEFSYM (Qx, "x");
   DEFSYM (Qw32, "w32");
   DEFSYM (Qpc, "pc");
   DEFSYM (Qx, "x");
   DEFSYM (Qw32, "w32");
   DEFSYM (Qpc, "pc");
-  DEFSYM (Qmac, "mac");
   DEFSYM (Qns, "ns");
   DEFSYM (Qvisible, "visible");
   DEFSYM (Qbuffer_predicate, "buffer-predicate");
   DEFSYM (Qns, "ns");
   DEFSYM (Qvisible, "visible");
   DEFSYM (Qbuffer_predicate, "buffer-predicate");
@@ -4358,7 +4258,7 @@ The pointer becomes visible again when the mouse is moved.  */);
   Vmake_pointer_invisible = Qt;
 
   DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions,
   Vmake_pointer_invisible = Qt;
 
   DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions,
-              doc: /* Functions to be run before deleting a frame.
+              doc: /* Functions run before deleting a frame.
 The functions are run with one arg, the frame to be deleted.
 See `delete-frame'.
 
 The functions are run with one arg, the frame to be deleted.
 See `delete-frame'.