Add support for large files, 64-bit Solaris, system locale codings.
[bpt/emacs.git] / src / frame.c
index 7d46108..e5f80fd 100644 (file)
@@ -1,5 +1,5 @@
 /* Generic frame functions.
-   Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation.
+   Copyright (C) 1993, 1994, 1995, 1997, 1999 Free Software Foundation.
 
 This file is part of GNU Emacs.
 
@@ -21,23 +21,26 @@ Boston, MA 02111-1307, USA.  */
 #include <config.h>
 
 #include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
 #include "lisp.h"
 #include "charset.h"
-#ifdef HAVE_WINDOW_SYSTEM
-#include "fontset.h"
-#endif
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
 #endif
 #include "frame.h"
+#ifdef HAVE_WINDOW_SYSTEM
+#include "fontset.h"
+#endif
 #include "termhooks.h"
 #include "dispextern.h"
 #include "window.h"
 #ifdef MSDOS
 #include "msdos.h"
+#include "dosfns.h"
+#endif
+
+#ifdef macintosh
+extern struct mac_output *NewMacWindow ();
+extern void DisposeMacWindow (struct mac_output *);
 #endif
 
 /* Evaluate this expression to rebuild the section of syms_of_frame
@@ -84,10 +87,12 @@ Lisp_Object Qname;
 Lisp_Object Qonly;
 Lisp_Object Qunsplittable;
 Lisp_Object Qmenu_bar_lines;
+Lisp_Object Qtool_bar_lines;
 Lisp_Object Qwidth;
 Lisp_Object Qx;
 Lisp_Object Qw32;
 Lisp_Object Qpc;
+Lisp_Object Qmac;
 Lisp_Object Qvisible;
 Lisp_Object Qbuffer_predicate;
 Lisp_Object Qbuffer_list;
@@ -120,6 +125,8 @@ syms_of_frame_1 ()
   staticpro (&Qunsplittable);
   Qmenu_bar_lines = intern ("menu-bar-lines");
   staticpro (&Qmenu_bar_lines);
+  Qtool_bar_lines = intern ("tool-bar-lines");
+  staticpro (&Qtool_bar_lines);
   Qwidth = intern ("width");
   staticpro (&Qwidth);
   Qx = intern ("x");
@@ -128,6 +135,8 @@ syms_of_frame_1 ()
   staticpro (&Qw32);
   Qpc = intern ("pc");
   staticpro (&Qpc);
+  Qmac = intern ("mac");
+  staticpro (&Qmac);
   Qvisible = intern ("visible");
   staticpro (&Qvisible);
   Qbuffer_predicate = intern ("buffer-predicate");
@@ -200,6 +209,7 @@ set_menu_bar_lines (f, value, oldval)
       FRAME_WINDOW_SIZES_CHANGED (f) = 1;
       FRAME_MENU_BAR_LINES (f) = nlines;
       set_menu_bar_lines_1 (f->root_window, nlines - olines);
+      adjust_glyphs (f);
     }
 }
 \f
@@ -239,6 +249,8 @@ See also `frame-live-p'.")
       return Qw32;
     case output_msdos_raw:
       return Qpc;
+    case output_mac:
+      return Qmac;
     default:
       abort ();
     }
@@ -277,10 +289,12 @@ make_frame (mini_p)
   f = (struct frame *)vec;
   XSETFRAME (frame, f);
 
-  f->cursor_x = 0;
-  f->cursor_y = 0;
-  f->current_glyphs = 0;
-  f->desired_glyphs = 0;
+  f->desired_matrix = 0;
+  f->current_matrix = 0;
+  f->desired_pool = 0;
+  f->current_pool = 0;
+  f->glyphs_initialized_p = 0;
+  f->decode_mode_spec_buffer = 0;
   f->visible = 0;
   f->async_visible = 0;
   f->output_data.nothing = 0;
@@ -300,6 +314,7 @@ make_frame (mini_p)
   f->scroll_bars = Qnil;
   f->condemned_scroll_bars = Qnil;
   f->face_alist = Qnil;
+  f->face_cache = NULL;
   f->menu_bar_items = Qnil;
   f->menu_bar_vector = Qnil;
   f->menu_bar_items_used = 0;
@@ -310,6 +325,11 @@ make_frame (mini_p)
 #endif
   f->namebuf = 0;
   f->title = Qnil;
+  f->menu_bar_window = Qnil;
+  f->tool_bar_window = Qnil;
+  f->desired_tool_bar_items = f->current_tool_bar_items = Qnil;
+  f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
+  f->n_desired_tool_bar_items = f->n_current_tool_bar_items = 0;
 
   root_window = make_window ();
   if (mini_p)
@@ -356,19 +376,26 @@ make_frame (mini_p)
     /* If buf is a 'hidden' buffer (i.e. one whose name starts with
        a space), try to find another one.  */
     if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
-      buf = Fother_buffer (buf, Qnil);
-    Fset_window_buffer (root_window, buf);
-
+      buf = Fother_buffer (buf, Qnil, Qnil);
+
+    /* Use set_window_buffer, not Fset_window_buffer, and don't let
+       hooks be run by it.  The reason is that the whole frame/window
+       arrangement is not yet fully intialized at this point.  Windows
+       don't have the right size, glyph matrices aren't initialized
+       etc.  Running Lisp functions at this point surely ends in a
+       SEGV.  */
+    set_window_buffer (root_window, buf, 0);
     f->buffer_list = Fcons (buf, Qnil);
   }
 
   if (mini_p)
     {
       XWINDOW (mini_window)->buffer = Qt;
-      Fset_window_buffer (mini_window,
-                         (NILP (Vminibuffer_list)
-                          ? get_minibuffer (0)
-                          : Fcar (Vminibuffer_list)));
+      set_window_buffer (mini_window,
+                        (NILP (Vminibuffer_list)
+                         ? get_minibuffer (0)
+                         : Fcar (Vminibuffer_list)),
+                        0);
     }
 
   f->root_window = root_window;
@@ -519,10 +546,29 @@ make_terminal_frame ()
 #ifdef MSDOS
   f->output_data.x = &the_only_x_display;
   f->output_method = output_msdos_raw;
+#endif /* MSDOS */
+
+#ifdef macintosh
+  f->output_data.mac = NewMacWindow(f);
+  f->output_data.mac->background_pixel = 0xffffff;
+  f->output_data.mac->foreground_pixel = 0;
+  f->output_data.mac->n_param_faces = 0;
+  f->output_data.mac->n_computed_faces = 0;
+  f->output_data.mac->size_computed_faces = 0;  
+  f->output_method = output_mac;
+  f->auto_raise = 1;
+  f->auto_lower = 1;
   init_frame_faces (f);
-#else /* not MSDOS */
+#endif /* macintosh */
+
+#ifndef MSDOS
+#ifndef macintosh
   f->output_data.nothing = 1;  /* Nonzero means frame isn't deleted.  */
 #endif
+#endif
+
+  if (!noninteractive)
+    init_frame_faces (f);
   return f;
 }
 
@@ -537,25 +583,41 @@ Note that changing the size of one terminal frame automatically affects all.")
      Lisp_Object parms;
 {
   struct frame *f;
-  Lisp_Object frame;
+  Lisp_Object frame, tem;
+  struct frame *sf = SELECTED_FRAME ();
 
 #ifdef MSDOS
-  if (selected_frame->output_method != output_msdos_raw)
+  if (sf->output_method != output_msdos_raw)
     abort ();
+#else /* not MSDOS */
+
+#ifdef macintosh
+  if (sf->output_method != output_mac)
+    error ("Not running on a Macintosh screen; cannot make a new Macintosh frame");
 #else
-  if (selected_frame->output_method != output_termcap)
+  if (sf->output_method != output_termcap)
     error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
 #endif
+#endif /* not MSDOS */
 
   f = make_terminal_frame ();
-  change_frame_size (f, FRAME_HEIGHT (selected_frame),
-                    FRAME_WIDTH (selected_frame), 0, 0);
-  remake_frame_glyphs (f);
+
+  change_frame_size (f, FRAME_HEIGHT (sf),
+                    FRAME_WIDTH (sf), 0, 0, 0);
+  adjust_glyphs (f);
   calculate_costs (f);
   XSETFRAME (frame, f);
   Fmodify_frame_parameters (frame, Vdefault_frame_alist);
   Fmodify_frame_parameters (frame, parms);
-  f->face_alist = selected_frame->face_alist;
+
+  /* Make the frame face alist be frame-specific, so that each
+     frame could change its face definitions independently.  */
+  f->face_alist = Fcopy_alist (sf->face_alist);
+  /* Simple Fcopy_alist isn't enough, because we need the contents of
+     the vectors which are the CDRs of associations in face_alist to
+     be copied as well.  */
+  for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
+    XCDR (XCAR (tem)) = Fcopy_sequence (XCDR (XCAR (tem)));
   return frame;
 }
 \f
@@ -564,6 +626,8 @@ do_switch_frame (frame, no_enter, track)
      Lisp_Object frame, no_enter;
      int track;
 {
+  struct frame *sf = SELECTED_FRAME ();
+  
   /* If FRAME is a switch-frame event, extract the frame we should
      switch to.  */
   if (CONSP (frame)
@@ -578,7 +642,7 @@ do_switch_frame (frame, no_enter, track)
   if (! FRAME_LIVE_P (XFRAME (frame)))
     return Qnil;
 
-  if (selected_frame == XFRAME (frame))
+  if (sf == XFRAME (frame))
     return frame;
 
   /* This is too greedy; it causes inappropriate focus redirection
@@ -604,7 +668,7 @@ do_switch_frame (frame, no_enter, track)
 
          focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
 
-         if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
+         if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
            Fredirect_frame_focus (XCONS (tail)->car, frame);
        }
     }
@@ -619,16 +683,16 @@ do_switch_frame (frame, no_enter, track)
       if (FRAMEP (xfocus))
        {
          focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
-         if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
+         if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
            Fredirect_frame_focus (xfocus, frame);
        }
     }
 #endif /* HAVE_X_WINDOWS */
 #endif /* ! 0 */
 
-  selected_frame = XFRAME (frame);
-  if (! FRAME_MINIBUF_ONLY_P (selected_frame))
-    last_nonminibuf_frame = selected_frame;
+  selected_frame = frame;
+  if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
+    last_nonminibuf_frame = XFRAME (selected_frame);
 
   Fselect_window (XFRAME (frame)->selected_window);
 
@@ -687,9 +751,7 @@ DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
   "Return the frame that is now selected.")
   ()
 {
-  Lisp_Object tem;
-  XSETFRAME (tem, selected_frame);
-  return tem;
+  return selected_frame;
 }
 \f
 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
@@ -710,7 +772,7 @@ If omitted, FRAME defaults to the currently selected frame.")
   Lisp_Object w;
 
   if (NILP (frame))
-    w = selected_frame->root_window;
+    w = SELECTED_FRAME ()->root_window;
   else
     {
       CHECK_LIVE_FRAME (frame, 0);
@@ -742,12 +804,17 @@ If omitted, FRAME defaults to the currently selected frame.")
   (frame)
      Lisp_Object frame;
 {
+  Lisp_Object window;
+  
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
+    window = SELECTED_FRAME ()->root_window;
   else
-    CHECK_LIVE_FRAME (frame, 0);
-
-  return XFRAME (frame)->root_window;
+    {
+      CHECK_LIVE_FRAME (frame, 0);
+      window = XFRAME (frame)->root_window;
+    }
+  
+  return window;
 }
 
 DEFUN ("frame-selected-window", Fframe_selected_window,
@@ -757,12 +824,17 @@ If omitted, FRAME defaults to the currently selected frame.")
   (frame)
      Lisp_Object frame;
 {
+  Lisp_Object window;
+  
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
+    window = SELECTED_FRAME ()->selected_window;
   else
-    CHECK_LIVE_FRAME (frame, 0);
+    {
+      CHECK_LIVE_FRAME (frame, 0);
+      window = XFRAME (frame)->selected_window;
+    }
 
-  return XFRAME (frame)->selected_window;
+  return window;
 }
 
 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
@@ -774,16 +846,15 @@ If FRAME is the selected frame, this makes WINDOW the selected window.")
      Lisp_Object frame, window;
 {
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
-  else
-    CHECK_LIVE_FRAME (frame, 0);
-
+    frame = selected_frame;
+  
+  CHECK_LIVE_FRAME (frame, 0);
   CHECK_LIVE_WINDOW (window, 1);
 
   if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
     error ("In `set-frame-selected-window', WINDOW is not on FRAME");
 
-  if (XFRAME (frame) == selected_frame)
+  if (EQ (frame, selected_frame))
     return Fselect_window (window);
 
   return XFRAME (frame)->selected_window = window;
@@ -972,13 +1043,10 @@ Otherwise, include all frames.")
   (frame, miniframe)
      Lisp_Object frame, miniframe;
 {
-  Lisp_Object tail;
-
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
-  else
-    CHECK_LIVE_FRAME (frame, 0);
-
+    frame = selected_frame;
+  
+  CHECK_LIVE_FRAME (frame, 0);
   return next_frame (frame, miniframe);
 }
 
@@ -996,13 +1064,9 @@ Otherwise, include all frames.")
   (frame, miniframe)
      Lisp_Object frame, miniframe;
 {
-  Lisp_Object tail;
-
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
-  else
-    CHECK_LIVE_FRAME (frame, 0);
-
+    frame = selected_frame;
+  CHECK_LIVE_FRAME (frame, 0);
   return prev_frame (frame, miniframe);
 }
 \f
@@ -1016,7 +1080,7 @@ other_visible_frames (f)
 {
   /* We know the selected frame is visible,
      so if F is some other frame, it can't be the sole visible one.  */
-  if (f == selected_frame)
+  if (f == SELECTED_FRAME ())
     {
       Lisp_Object frames;
       int count = 0;
@@ -1061,11 +1125,12 @@ but if the second optional argument FORCE is non-nil, you may do so.")
      Lisp_Object frame, force;
 {
   struct frame *f;
+  struct frame *sf = SELECTED_FRAME ();
   int minibuffer_selected;
 
   if (EQ (frame, Qnil))
     {
-      f = selected_frame;
+      f = sf;
       XSETFRAME (frame, f);
     }
   else
@@ -1111,7 +1176,7 @@ but if the second optional argument FORCE is non-nil, you may do so.")
   minibuffer_selected = EQ (minibuf_window, selected_window);
 
   /* Don't let the frame remain selected.  */
-  if (f == selected_frame)
+  if (f == sf)
     {
       Lisp_Object tail, frame1;
 
@@ -1129,14 +1194,15 @@ but if the second optional argument FORCE is non-nil, you may do so.")
        }
 
       do_switch_frame (frame1, Qnil, 0);
+      sf = SELECTED_FRAME ();
     }
 
   /* Don't allow minibuf_window to remain on a deleted frame.  */
   if (EQ (f->minibuffer_window, minibuf_window))
     {
-      Fset_window_buffer (selected_frame->minibuffer_window,
+      Fset_window_buffer (sf->minibuffer_window,
                          XWINDOW (minibuf_window)->buffer);
-      minibuf_window = selected_frame->minibuffer_window;
+      minibuf_window = sf->minibuffer_window;
 
       /* If the dying minibuffer window was selected,
         select the new one.  */
@@ -1150,6 +1216,12 @@ but if the second optional argument FORCE is non-nil, you may do so.")
     x_clear_frame_selections (f);
 #endif
 
+  /* Free glyphs. 
+     This function must be called before the window tree of the 
+     frame is deleted because windows contain dynamically allocated
+     memory. */
+  free_glyphs (f);
+
   /* Mark all the windows that used to be on FRAME as deleted, and then
      remove the reference to them.  */
   delete_all_subwindows (XWINDOW (f->root_window));
@@ -1158,30 +1230,18 @@ but if the second optional argument FORCE is non-nil, you may do so.")
   Vframe_list = Fdelq (frame, Vframe_list);
   FRAME_SET_VISIBLE (f, 0);
 
-  if (echo_area_glyphs == FRAME_MESSAGE_BUF (f))
-    {
-      echo_area_glyphs = 0;
-      previous_echo_glyphs = 0;
-    }
-
   if (f->namebuf)
-    free (f->namebuf);
-  if (FRAME_CURRENT_GLYPHS (f))
-    free_frame_glyphs (f, FRAME_CURRENT_GLYPHS (f));
-  if (FRAME_DESIRED_GLYPHS (f))
-    free_frame_glyphs (f, FRAME_DESIRED_GLYPHS (f));
-  if (FRAME_TEMP_GLYPHS (f))
-    free_frame_glyphs (f, FRAME_TEMP_GLYPHS (f));
+    xfree (f->namebuf);
   if (FRAME_INSERT_COST (f))
-    free (FRAME_INSERT_COST (f));
+    xfree (FRAME_INSERT_COST (f));
   if (FRAME_DELETEN_COST (f))
-    free (FRAME_DELETEN_COST (f));
+    xfree (FRAME_DELETEN_COST (f));
   if (FRAME_INSERTN_COST (f))
-    free (FRAME_INSERTN_COST (f));
+    xfree (FRAME_INSERTN_COST (f));
   if (FRAME_DELETE_COST (f))
-    free (FRAME_DELETE_COST (f));
+    xfree (FRAME_DELETE_COST (f));
   if (FRAME_MESSAGE_BUF (f))
-    free (FRAME_MESSAGE_BUF (f));
+    xfree (FRAME_MESSAGE_BUF (f));
 
 #ifdef HAVE_WINDOW_SYSTEM
   /* Free all fontset data.  */
@@ -1200,6 +1260,14 @@ but if the second optional argument FORCE is non-nil, you may do so.")
     x_destroy_window (f);
 #endif
 
+/* Done by x_destroy_window above already */
+#if 0
+#ifdef macintosh
+  if (FRAME_MAC_P (f))
+    DisposeMacWindow (f->output_data.mac);
+#endif
+#endif
+
   f->output_data.nothing = 0;
 
   /* If we've deleted the last_nonminibuf_frame, then try to find
@@ -1306,7 +1374,7 @@ and nil for X and Y.")
   int col, row;
   unsigned long long_dummy;
 
-  f = selected_frame;
+  f = SELECTED_FRAME ();
   x = y = Qnil;
 
 #ifdef HAVE_MOUSE
@@ -1343,10 +1411,9 @@ and nil for X and Y.")
   Lisp_Object lispy_dummy;
   enum scroll_bar_part party_dummy;
   Lisp_Object x, y;
-  int col, row;
   unsigned long long_dummy;
 
-  f = selected_frame;
+  f = SELECTED_FRAME ();
   x = y = Qnil;
 
 #ifdef HAVE_MOUSE
@@ -1363,7 +1430,11 @@ and nil for X and Y.")
 
 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
   "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
-Note, this is a no-op for an X frame that is not visible.\n\
+Coordinates are relative to the frame, not a window,\n\
+so the coordinates of the top left character in the frame\n\
+may be nonzero due to left-hand scroll bars or the menu bar.\n\
+\n\
+This function is a no-op for an X frame that is not visible.\n\
 If you have just created a frame, you must wait for it to become visible\n\
 before calling this function on it, like this.\n\
   (while (not (frame-visible-p frame)) (sleep-for .5))")
@@ -1424,6 +1495,8 @@ before calling this function on it, like this.\n\
   return Qnil;
 }
 \f
+static void make_frame_visible_1 P_ ((Lisp_Object));
+
 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
        0, 1, "",
   "Make the frame FRAME visible (assuming it is an X-window).\n\
@@ -1432,7 +1505,7 @@ If omitted, FRAME defaults to the currently selected frame.")
      Lisp_Object frame;
 {
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
+    frame = selected_frame;
 
   CHECK_LIVE_FRAME (frame, 0);
 
@@ -1445,12 +1518,37 @@ If omitted, FRAME defaults to the currently selected frame.")
     }
 #endif
 
+  make_frame_visible_1 (XFRAME (frame)->root_window);
+
   /* Make menu bar update for the Buffers and Frams menus.  */
   windows_or_buffers_changed++;
 
   return frame;
 }
 
+/* Update the display_time slot of the buffers shown in WINDOW
+   and all its descendents.  */
+
+static void
+make_frame_visible_1 (window)
+     Lisp_Object window;
+{
+  struct window *w;
+
+  for (;!NILP (window); window = w->next)
+    {
+      w = XWINDOW (window);
+
+      if (!NILP (w->buffer))
+       XBUFFER (w->buffer)->display_time = Fcurrent_time ();
+
+      if (!NILP (w->vchild))
+       make_frame_visible_1 (w->vchild);
+      if (!NILP (w->hchild))
+       make_frame_visible_1 (w->hchild);
+    }
+}
+
 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
        0, 2, "",
   "Make the frame FRAME invisible (assuming it is an X-window).\n\
@@ -1461,7 +1559,7 @@ but if the second optional argument FORCE is non-nil, you may do so.")
      Lisp_Object frame, force;
 {
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
+    frame = selected_frame;
 
   CHECK_LIVE_FRAME (frame, 0);
 
@@ -1470,16 +1568,17 @@ but if the second optional argument FORCE is non-nil, you may do so.")
 
 #if 0 /* This isn't logically necessary, and it can do GC.  */
   /* Don't let the frame remain selected.  */
-  if (XFRAME (frame) == selected_frame)
+  if (EQ (frame, selected_frame))
     do_switch_frame (next_frame (frame, Qt), Qnil, 0)
 #endif
 
   /* Don't allow minibuf_window to remain on a deleted frame.  */
   if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
     {
-      Fset_window_buffer (selected_frame->minibuffer_window,
+      struct frame *sf = XFRAME (selected_frame);
+      Fset_window_buffer (sf->minibuffer_window,
                          XWINDOW (minibuf_window)->buffer);
-      minibuf_window = selected_frame->minibuffer_window;
+      minibuf_window = sf->minibuffer_window;
     }
 
   /* I think this should be done with a hook.  */
@@ -1502,22 +1601,23 @@ If omitted, FRAME defaults to the currently selected frame.")
      Lisp_Object frame;
 {
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
+    frame = selected_frame;
   
   CHECK_LIVE_FRAME (frame, 0);
 
 #if 0 /* This isn't logically necessary, and it can do GC.  */
   /* Don't let the frame remain selected.  */
-  if (XFRAME (frame) == selected_frame)
+  if (EQ (frame, selected_frame))
     Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
 #endif
 
   /* Don't allow minibuf_window to remain on a deleted frame.  */
   if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
     {
-      Fset_window_buffer (selected_frame->minibuffer_window,
+      struct frame *sf = XFRAME (selected_frame);
+      Fset_window_buffer (sf->minibuffer_window,
                          XWINDOW (minibuf_window)->buffer);
-      minibuf_window = selected_frame->minibuffer_window;
+      minibuf_window = sf->minibuffer_window;
     }
 
   /* I think this should be done with a hook.  */
@@ -1585,7 +1685,7 @@ doesn't support multiple overlapping frames, this function does nothing.")
      Lisp_Object frame;
 {
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
+    frame = selected_frame;
 
   CHECK_LIVE_FRAME (frame, 0);
 
@@ -1608,7 +1708,7 @@ doesn't support multiple overlapping frames, this function does nothing.")
      Lisp_Object frame;
 {
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
+    frame = selected_frame;
 
   CHECK_LIVE_FRAME (frame, 0);
   
@@ -1696,26 +1796,28 @@ get_frame_param (frame, prop)
 /* Return the buffer-predicate of the selected frame.  */
 
 Lisp_Object
-frame_buffer_predicate ()
+frame_buffer_predicate (frame)
+     Lisp_Object frame;
 {
-  return selected_frame->buffer_predicate;
+  return XFRAME (frame)->buffer_predicate;
 }
 
 /* Return the buffer-list of the selected frame.  */
 
 Lisp_Object
-frame_buffer_list ()
+frame_buffer_list (frame)
+     Lisp_Object frame;
 {
-  return selected_frame->buffer_list;
+  return XFRAME (frame)->buffer_list;
 }
 
 /* Set the buffer-list of the selected frame.  */
 
 void
-set_frame_buffer_list (list)
-     Lisp_Object list;
+set_frame_buffer_list (frame, list)
+     Lisp_Object frame, list;
 {
-  selected_frame->buffer_list = list;
+  XFRAME (frame)->buffer_list = list;
 }
 
 /* Discard BUFFER from the buffer-list of each frame.  */
@@ -1774,7 +1876,8 @@ frame_name_fnn_p (str, len)
   if (len > 1 && str[0] == 'F')
     {
       char *end_ptr;
-      long num = strtol (str + 1, &end_ptr, 10);
+
+      strtol (str + 1, &end_ptr, 10);
 
       if (end_ptr == str + len)
        return 1;
@@ -1860,7 +1963,7 @@ store_frame_param (f, prop, val)
       if (! MINI_WINDOW_P (XWINDOW (val)))
        error ("Surrogate minibuffer windows must be minibuffer windows.");
 
-      if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f)
+      if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
          && !EQ (val, f->minibuffer_window))
        error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
 
@@ -1882,12 +1985,10 @@ If FRAME is omitted, return information on the currently selected frame.")
   int height, width;
 
   if (EQ (frame, Qnil))
-    f = selected_frame;
-  else
-    {
-      CHECK_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+
+  CHECK_FRAME (frame, 0);
+  f = XFRAME (frame);
 
   if (!FRAME_LIVE_P (f))
     return Qnil;
@@ -1896,18 +1997,19 @@ If FRAME is omitted, return information on the currently selected frame.")
 #ifdef MSDOS
   if (FRAME_MSDOS_P (f))
     {
-      static char *colornames[16] = 
-       {
-         "black", "blue", "green", "cyan", "red", "magenta", "brown",
-         "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
-         "lightred", "lightmagenta", "yellow", "white"
-       };
+      int fg = FRAME_FOREGROUND_PIXEL (f);
+      int bg = FRAME_BACKGROUND_PIXEL (f);
+      Lisp_Object qreverse = intern ("reverse");
+      int rv =
+       !NILP (Fassq (qreverse, alist))
+       || !NILP (Fassq (qreverse, Vdefault_frame_alist));
+
       store_in_alist (&alist, intern ("foreground-color"),
-                     build_string (colornames[FRAME_FOREGROUND_PIXEL (f)]));
+                     build_string (msdos_stdcolor_name (rv ? bg : fg)));
       store_in_alist (&alist, intern ("background-color"),
-                     build_string (colornames[FRAME_BACKGROUND_PIXEL (f)]));
+                     build_string (msdos_stdcolor_name (rv ? fg : bg)));
     }
-  store_in_alist (&alist, intern ("font"), build_string ("default"));
+  store_in_alist (&alist, intern ("font"), build_string ("ms-dos"));
 #endif
   store_in_alist (&alist, Qname, f->name);
   height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
@@ -1920,7 +2022,8 @@ If FRAME is omitted, return information on the currently selected frame.")
                   : FRAME_MINIBUF_ONLY_P (f) ? Qonly
                   : FRAME_MINIBUF_WINDOW (f)));
   store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
-  store_in_alist (&alist, Qbuffer_list, frame_buffer_list ());
+  store_in_alist (&alist, Qbuffer_list,
+                 frame_buffer_list (selected_frame));
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -1949,15 +2052,12 @@ so that `frame-parameters' will return them.")
      Lisp_Object frame, alist;
 {
   FRAME_PTR f;
-  register Lisp_Object tail, elt, prop, val;
+  register Lisp_Object tail, prop, val;
 
   if (EQ (frame, Qnil))
-    f = selected_frame;
-  else
-    {
-      CHECK_LIVE_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+  CHECK_LIVE_FRAME (frame, 0);
+  f = XFRAME (frame);
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -1970,6 +2070,12 @@ so that `frame-parameters' will return them.")
     IT_set_frame_parameters (f, alist);
   else
 #endif
+#ifdef macintosh
+  if (FRAME_MAC_P (f))
+    mac_set_frame_parameters (f, alist);
+  else
+#endif
+
     {
       int length = XINT (Flength (alist));
       int i;
@@ -1983,7 +2089,7 @@ so that `frame-parameters' will return them.")
       i = 0;
       for (tail = alist; CONSP (tail); tail = Fcdr (tail))
        {
-         Lisp_Object elt, prop, val;
+         Lisp_Object elt;
 
          elt = Fcar (tail);
          parms[i] = Fcar (elt);
@@ -2014,12 +2120,9 @@ For a terminal frame, the value is always 1.")
   struct frame *f;
 
   if (NILP (frame))
-    f = selected_frame;
-  else
-    {
-      CHECK_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+  CHECK_FRAME (frame, 0);
+  f = XFRAME (frame);
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
@@ -2043,12 +2146,9 @@ For a terminal screen, the value is always 1.")
   struct frame *f;
 
   if (NILP (frame))
-    f = selected_frame;
-  else
-    {
-      CHECK_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+  CHECK_FRAME (frame, 0);
+  f = XFRAME (frame);
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
@@ -2071,12 +2171,9 @@ If FRAME is omitted, the selected frame is used.")
   struct frame *f;
 
   if (NILP (frame))
-    f = selected_frame;
-  else
-    {
-      CHECK_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+  CHECK_FRAME (frame, 0);
+  f = XFRAME (frame);
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
@@ -2097,12 +2194,9 @@ If FRAME is omitted, the selected frame is used.")
   struct frame *f;
 
   if (NILP (frame))
-    f = selected_frame;
-  else
-    {
-      CHECK_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+  CHECK_FRAME (frame, 0);
+  f = XFRAME (frame);
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
@@ -2123,12 +2217,9 @@ but that the idea of the actual height of the frame should not be changed.")
 
   CHECK_NUMBER (lines, 0);
   if (NILP (frame))
-    f = selected_frame;
-  else
-    {
-      CHECK_LIVE_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+  CHECK_LIVE_FRAME (frame, 0);
+  f = XFRAME (frame);
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -2136,10 +2227,11 @@ but that the idea of the actual height of the frame should not be changed.")
     {
       if (XINT (lines) != f->height)
        x_set_window_size (f, 1, f->width, XINT (lines));
+      do_pending_window_change (0);
     }
   else
 #endif
-    change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0);
+    change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
   return Qnil;
 }
 
@@ -2153,12 +2245,9 @@ but that the idea of the actual width of the frame should not be changed.")
   register struct frame *f;
   CHECK_NUMBER (cols, 0);
   if (NILP (frame))
-    f = selected_frame;
-  else
-    {
-      CHECK_LIVE_FRAME (frame, 0);
-      f = XFRAME (frame);
-    }
+    frame = selected_frame;
+  CHECK_LIVE_FRAME (frame, 0);
+  f = XFRAME (frame);
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -2166,10 +2255,11 @@ but that the idea of the actual width of the frame should not be changed.")
     {
       if (XINT (cols) != f->width)
        x_set_window_size (f, 1, XINT (cols), f->height);
+      do_pending_window_change (0);
     }
   else
 #endif
-    change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
+    change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
   return Qnil;
 }
 
@@ -2179,7 +2269,6 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
      Lisp_Object frame, cols, rows;
 {
   register struct frame *f;
-  int mask;
 
   CHECK_LIVE_FRAME (frame, 0);
   CHECK_NUMBER (cols, 2);
@@ -2193,10 +2282,11 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
       if (XINT (rows) != f->height || XINT (cols) != f->width
          || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
        x_set_window_size (f, 1, XINT (cols), XINT (rows));
+      do_pending_window_change (0);
     }
   else
 #endif
-    change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
+    change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
 
   return Qnil;
 }
@@ -2211,7 +2301,6 @@ the rightmost or bottommost possible position (that stays within the screen).")
      Lisp_Object frame, xoffset, yoffset;
 {
   register struct frame *f;
-  int mask;
 
   CHECK_LIVE_FRAME (frame, 0);
   CHECK_NUMBER (xoffset, 1);