*** empty log message ***
[bpt/emacs.git] / src / frame.c
index 934c11d..a47dff8 100644 (file)
@@ -1,12 +1,12 @@
 /* Generic frame functions.
 /* Generic frame functions.
-   Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2003
-   Free Software Foundation.
+   Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003,
+                 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -16,8 +16,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #include <config.h>
 
 
 #include <config.h>
 
@@ -71,7 +71,6 @@ Lisp_Object Qx, Qw32, Qmac, Qpc;
 Lisp_Object Qvisible;
 Lisp_Object Qdisplay_type;
 Lisp_Object Qbackground_mode;
 Lisp_Object Qvisible;
 Lisp_Object Qdisplay_type;
 Lisp_Object Qbackground_mode;
-Lisp_Object Qinhibit_default_face_x_resources;
 
 Lisp_Object Qx_frame_parameter;
 Lisp_Object Qx_resource_name;
 
 Lisp_Object Qx_frame_parameter;
 Lisp_Object Qx_resource_name;
@@ -109,6 +108,7 @@ Lisp_Object Qtty_color_mode;
 
 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
 
 
 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
 
+Lisp_Object Qinhibit_face_set_after_frame_default;
 Lisp_Object Qface_set_after_frame_default;
 
 
 Lisp_Object Qface_set_after_frame_default;
 
 
@@ -118,6 +118,8 @@ Lisp_Object Vdefault_frame_scroll_bars;
 Lisp_Object Vmouse_position_function;
 Lisp_Object Vmouse_highlight;
 Lisp_Object Vdelete_frame_functions;
 Lisp_Object Vmouse_position_function;
 Lisp_Object Vmouse_highlight;
 Lisp_Object Vdelete_frame_functions;
+
+int focus_follows_mouse;
 \f
 static void
 set_menu_bar_lines_1 (window, n)
 \f
 static void
 set_menu_bar_lines_1 (window, n)
@@ -371,7 +373,8 @@ make_frame (mini_p)
   f->selected_window = root_window;
   /* Make sure this window seems more recently used than
      a newly-created, never-selected window.  */
   f->selected_window = root_window;
   /* Make sure this window seems more recently used than
      a newly-created, never-selected window.  */
-  XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
+  ++window_select_count;
+  XSETFASTINT (XWINDOW (f->selected_window)->use_time, window_select_count);
 
   f->default_face_done_p = 0;
 
 
   f->default_face_done_p = 0;
 
@@ -398,7 +401,7 @@ make_frame_without_minibuffer (mini_window, kb, display)
 #ifdef MULTI_KBOARD
   if (!NILP (mini_window)
       && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
 #ifdef MULTI_KBOARD
   if (!NILP (mini_window)
       && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
-    error ("frame and minibuffer must be on the same display");
+    error ("Frame and minibuffer must be on the same display");
 #endif
 
   /* Make a frame containing just a root window.  */
 #endif
 
   /* Make a frame containing just a root window.  */
@@ -728,20 +731,25 @@ do_switch_frame (frame, track, for_deletion)
   return frame;
 }
 
   return frame;
 }
 
-DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
+DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 1, "e",
        doc: /* Select the frame FRAME.
 Subsequent editing commands apply to its selected window.
 The selection of FRAME lasts until the next time the user does
 something to select a different frame, or until the next time this
        doc: /* Select the frame FRAME.
 Subsequent editing commands apply to its selected window.
 The selection of FRAME lasts until the next time the user does
 something to select a different frame, or until the next time this
-function is called.  */)
-  (frame, no_enter)
-    Lisp_Object frame, no_enter;
+function is called.  If you are using a window system, the previously
+selected frame may be restored as the selected frame after return to
+the command loop, because it still may have the window system's input
+focus.  On a text-only terminal, the next redisplay will display FRAME.
+
+This function returns FRAME, or nil if FRAME has been deleted.  */)
+  (frame)
+    Lisp_Object frame;
 {
   return do_switch_frame (frame, 1, 0);
 }
 
 
 {
   return do_switch_frame (frame, 1, 0);
 }
 
 
-DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
+DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e",
        doc: /* Handle a switch-frame event EVENT.
 Switch-frame events are usually bound to this function.
 A switch-frame event tells Emacs that the window manager has requested
        doc: /* Handle a switch-frame event EVENT.
 Switch-frame events are usually bound to this function.
 A switch-frame event tells Emacs that the window manager has requested
@@ -750,8 +758,8 @@ This function selects the selected window of the frame of EVENT.
 
 If EVENT is frame object, handle it as if it were a switch-frame event
 to that frame.  */)
 
 If EVENT is frame object, handle it as if it were a switch-frame event
 to that frame.  */)
-     (event, no_enter)
-     Lisp_Object event, no_enter;
+     (event)
+     Lisp_Object event;
 {
   /* Preserve prefix arg that the command loop just cleared.  */
   current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
 {
   /* Preserve prefix arg that the command loop just cleared.  */
   current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
@@ -759,15 +767,6 @@ to that frame.  */)
   return do_switch_frame (event, 0, 0);
 }
 
   return do_switch_frame (event, 0, 0);
 }
 
-DEFUN ("ignore-event", Fignore_event, Signore_event, 0, 0, "",
-       doc: /* Do nothing, but preserve any prefix argument already specified.
-This is a suitable binding for `iconify-frame' and `make-frame-visible'.  */)
-     ()
-{
-  current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
-  return Qnil;
-}
-
 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
        doc: /* Return the frame that is now selected.  */)
      ()
 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
        doc: /* Return the frame that is now selected.  */)
      ()
@@ -861,6 +860,7 @@ If omitted, FRAME defaults to the currently selected frame.  */)
 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
        Sset_frame_selected_window, 2, 2, 0,
        doc: /* Set the selected window of frame object FRAME to WINDOW.
 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
        Sset_frame_selected_window, 2, 2, 0,
        doc: /* Set the selected window of frame object FRAME to WINDOW.
+Return WINDOW.
 If FRAME is nil, the selected frame is used.
 If FRAME is the selected frame, this makes WINDOW the selected window.  */)
      (frame, window)
 If FRAME is nil, the selected frame is used.
 If FRAME is the selected frame, this makes WINDOW the selected window.  */)
      (frame, window)
@@ -903,7 +903,7 @@ DEFUN ("frame-list", Fframe_list, Sframe_list,
    If MINIBUF is 0, include all visible and iconified frames.
    Otherwise, include all frames.  */
 
    If MINIBUF is 0, include all visible and iconified frames.
    Otherwise, include all frames.  */
 
-Lisp_Object
+static Lisp_Object
 next_frame (frame, minibuf)
      Lisp_Object frame;
      Lisp_Object minibuf;
 next_frame (frame, minibuf)
      Lisp_Object frame;
      Lisp_Object minibuf;
@@ -980,7 +980,7 @@ next_frame (frame, minibuf)
    If MINIBUF is 0, include all visible and iconified frames.
    Otherwise, include all frames.  */
 
    If MINIBUF is 0, include all visible and iconified frames.
    Otherwise, include all frames.  */
 
-Lisp_Object
+static Lisp_Object
 prev_frame (frame, minibuf)
      Lisp_Object frame;
      Lisp_Object minibuf;
 prev_frame (frame, minibuf)
      Lisp_Object frame;
      Lisp_Object minibuf;
@@ -1262,6 +1262,10 @@ The functions are run with one arg, the frame to be deleted.  */)
   if (FRAME_X_P (f))
     x_clear_frame_selections (f);
 #endif
   if (FRAME_X_P (f))
     x_clear_frame_selections (f);
 #endif
+#ifdef MAC_OS
+  if (FRAME_MAC_P (f))
+    x_clear_frame_selections (f);
+#endif
 
   /* Free glyphs.
      This function must be called before the window tree of the
 
   /* Free glyphs.
      This function must be called before the window tree of the
@@ -1327,6 +1331,36 @@ The functions are run with one arg, the frame to be deleted.  */)
        }
     }
 
        }
     }
 
+  /* If there's no other frame on the same kboard, get out of
+     single-kboard state if we're in it for this kboard.  */
+  {
+    Lisp_Object frames;
+    /* 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;
+
+    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 (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
+         frame_on_same_kboard = this;
+      }
+
+    if (NILP (frame_on_same_kboard))
+      not_single_kboard_state (FRAME_KBOARD (f));
+  }
+
+
   /* If we've deleted this keyboard's default_minibuffer_frame, try to
      find another one.  Prefer minibuffer-only frames, but also notice
      frames with other windows.  */
   /* If we've deleted this keyboard's default_minibuffer_frame, try to
      find another one.  Prefer minibuffer-only frames, but also notice
      frames with other windows.  */
@@ -1397,7 +1431,8 @@ The functions are run with one arg, the frame to be deleted.  */)
 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
        doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
 The position is given in character cells, where (0, 0) is the
 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
        doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
 The position is given in character cells, where (0, 0) is the
-upper-left corner.
+upper-left corner of the frame, X is the horizontal offset, and Y is
+the vertical offset.
 If Emacs is running on a mouseless terminal or hasn't been programmed
 to read the mouse position, it returns the selected frame for FRAME
 and nil for X and Y.
 If Emacs is running on a mouseless terminal or hasn't been programmed
 to read the mouse position, it returns the selected frame for FRAME
 and nil for X and Y.
@@ -1445,7 +1480,8 @@ DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
        Smouse_pixel_position, 0, 0, 0,
        doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
 The position is given in pixel units, where (0, 0) is the
        Smouse_pixel_position, 0, 0, 0,
        doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
 The position is given in pixel units, where (0, 0) is the
-upper-left corner.
+upper-left corner of the frame, X is the horizontal offset, and Y is
+the vertical offset.
 If Emacs is running on a mouseless terminal or hasn't been programmed
 to read the mouse position, it returns the selected frame for FRAME
 and nil for X and Y.  */)
 If Emacs is running on a mouseless terminal or hasn't been programmed
 to read the mouse position, it returns the selected frame for FRAME
 and nil for X and Y.  */)
@@ -1478,6 +1514,10 @@ Coordinates are relative to the frame, not a window,
 so the coordinates of the top left character in the frame
 may be nonzero due to left-hand scroll bars or the menu bar.
 
 so the coordinates of the top left character in the frame
 may be nonzero due to left-hand scroll bars or the menu bar.
 
+The position is given in character cells, where (0, 0) is the
+upper-left corner of the frame, X is the horizontal offset, and Y is
+the vertical offset.
+
 This function is a no-op for an X frame that is not visible.
 If you have just created a frame, you must wait for it to become visible
 before calling this function on it, like this.
 This function is a no-op for an X frame that is not visible.
 If you have just created a frame, you must wait for it to become visible
 before calling this function on it, like this.
@@ -1498,7 +1538,7 @@ before calling this function on it, like this.
 #if defined (MSDOS) && defined (HAVE_MOUSE)
   if (FRAME_MSDOS_P (XFRAME (frame)))
     {
 #if defined (MSDOS) && defined (HAVE_MOUSE)
   if (FRAME_MSDOS_P (XFRAME (frame)))
     {
-      Fselect_frame (frame, Qnil);
+      Fselect_frame (frame);
       mouse_moveto (XINT (x), XINT (y));
     }
 #endif
       mouse_moveto (XINT (x), XINT (y));
     }
 #endif
@@ -1510,6 +1550,9 @@ before calling this function on it, like this.
 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
        Sset_mouse_pixel_position, 3, 3, 0,
        doc: /* Move the mouse pointer to pixel position (X,Y) in FRAME.
 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
        Sset_mouse_pixel_position, 3, 3, 0,
        doc: /* Move the mouse pointer to pixel position (X,Y) in FRAME.
+The position is given in pixels, where (0, 0) is the upper-left corner
+of the frame, X is the horizontal offset, and Y is the vertical offset.
+
 Note, this is a no-op for an X frame that is not visible.
 If you have just created a frame, you must wait for it to become visible
 before calling this function on it, like this.
 Note, this is a no-op for an X frame that is not visible.
 If you have just created a frame, you must wait for it to become visible
 before calling this function on it, like this.
@@ -1530,7 +1573,7 @@ before calling this function on it, like this.
 #if defined (MSDOS) && defined (HAVE_MOUSE)
   if (FRAME_MSDOS_P (XFRAME (frame)))
     {
 #if defined (MSDOS) && defined (HAVE_MOUSE)
   if (FRAME_MSDOS_P (XFRAME (frame)))
     {
-      Fselect_frame (frame, Qnil);
+      Fselect_frame (frame);
       mouse_moveto (XINT (x), XINT (y));
     }
 #endif
       mouse_moveto (XINT (x), XINT (y));
     }
 #endif
@@ -1652,7 +1695,7 @@ If omitted, FRAME defaults to the currently selected 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))
 #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), Qnil);
+    Fhandle_switch_frame (next_frame (frame, Qt));
 #endif
 
   /* Don't allow minibuf_window to remain on a deleted frame.  */
 #endif
 
   /* Don't allow minibuf_window to remain on a deleted frame.  */
@@ -1681,7 +1724,11 @@ DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
        doc: /* Return t if FRAME is now \"visible\" (actually in use for display).
 A frame that is not \"visible\" is not updated and, if it works through
 a window system, it may not show at all.
        doc: /* Return t if FRAME is now \"visible\" (actually in use for display).
 A frame that is not \"visible\" is not updated and, if it works through
 a window system, it may not show at all.
-Return the symbol `icon' if frame is visible only as an icon.  */)
+Return the symbol `icon' if frame is visible only as an icon.
+
+On a text-only terminal, all frames are considered visible, whether
+they are currently being displayed or not, and this function returns t
+for all frames.  */)
      (frame)
      Lisp_Object frame;
 {
      (frame)
      Lisp_Object frame;
 {
@@ -1721,7 +1768,7 @@ DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
 
 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
        doc: /* Bring FRAME to the front, so it occludes any frames it overlaps.
 
 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
        doc: /* Bring FRAME to the front, so it occludes any frames it overlaps.
-If FRAME is invisible, make it visible.
+If FRAME is invisible or iconified, make it visible.
 If you don't specify a frame, the selected frame is used.
 If Emacs is displaying on an ordinary terminal or some other device which
 doesn't support multiple overlapping frames, this function does nothing.  */)
 If you don't specify a frame, the selected frame is used.
 If Emacs is displaying on an ordinary terminal or some other device which
 doesn't support multiple overlapping frames, this function does nothing.  */)
@@ -1777,7 +1824,7 @@ Focus redirection is useful for temporarily redirecting keystrokes to
 a surrogate minibuffer frame when a frame doesn't have its own
 minibuffer window.
 
 a surrogate minibuffer frame when a frame doesn't have its own
 minibuffer window.
 
-A frame's focus redirection can be changed by select-frame.  If frame
+A frame's focus redirection can be changed by `select-frame'.  If frame
 FOO is selected, and then a different frame BAR is selected, any
 frames redirecting their focus to FOO are shifted to redirect their
 focus to BAR.  This allows focus redirection to work properly when the
 FOO is selected, and then a different frame BAR is selected, any
 frames redirecting their focus to FOO are shifted to redirect their
 focus to BAR.  This allows focus redirection to work properly when the
@@ -1785,7 +1832,7 @@ user switches from one frame to another using `select-window'.
 
 This means that a frame whose focus is redirected to itself is treated
 differently from a frame whose focus is redirected to nil; the former
 
 This means that a frame whose focus is redirected to itself is treated
 differently from a frame whose focus is redirected to nil; the former
-is affected by select-frame, while the latter is not.
+is affected by `select-frame', while the latter is not.
 
 The redirection lasts until `redirect-frame-focus' is called to change it.  */)
      (frame, focus_frame)
 
 The redirection lasts until `redirect-frame-focus' is called to change it.  */)
      (frame, focus_frame)
@@ -1916,7 +1963,7 @@ frame_name_fnn_p (str, len)
 /* Set the name of the terminal frame.  Also used by MSDOS frames.
    Modeled after x_set_name which is used for WINDOW frames.  */
 
 /* Set the name of the terminal frame.  Also used by MSDOS frames.
    Modeled after x_set_name which is used for WINDOW frames.  */
 
-void
+static void
 set_term_frame_name (f, name)
      struct frame *f;
      Lisp_Object name;
 set_term_frame_name (f, name)
      struct frame *f;
      Lisp_Object name;
@@ -2223,15 +2270,6 @@ enabled such bindings for that variable with `make-variable-frame-local'.  */)
 {
   FRAME_PTR f;
   register Lisp_Object tail, prop, val;
 {
   FRAME_PTR f;
   register Lisp_Object tail, prop, val;
-  int count = SPECPDL_INDEX ();
-
-  /* Bind this to t to inhibit initialization of the default face from
-     X resources in face-set-after-frame-default.  If we don't inhibit
-     this, modifying the `font' frame parameter, for example, while
-     there is a `default.attributeFont' X resource, won't work,
-     because `default's font is reset to the value of the X resource
-     and that resets the `font' frame parameter.  */
-  specbind (Qinhibit_default_face_x_resources, Qt);
 
   if (EQ (frame, Qnil))
     frame = selected_frame;
 
   if (EQ (frame, Qnil))
     frame = selected_frame;
@@ -2277,10 +2315,16 @@ enabled such bindings for that variable with `make-variable-frame-local'.  */)
          prop = parms[i];
          val = values[i];
          store_frame_param (f, prop, val);
          prop = parms[i];
          val = values[i];
          store_frame_param (f, prop, val);
+
+         /* Changing the background color might change the background
+            mode, so that we have to load new defface specs.
+            Call frame-set-background-mode to do that.  */
+         if (EQ (prop, Qbackground_color))
+           call1 (Qframe_set_background_mode, frame);
        }
     }
 
        }
     }
 
-  return unbind_to (count, Qnil);
+  return Qnil;
 }
 \f
 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
 }
 \f
 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
@@ -2311,8 +2355,7 @@ 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.
        0, 1, 0,
        doc: /* Width in pixels of characters in the font in frame FRAME.
 If FRAME is omitted, the selected frame is used.
-The width is the same for all characters, because
-currently Emacs supports only fixed-width fonts.
+On a graphical screen, the width is the standard width of the default font.
 For a terminal screen, the value is always 1.  */)
      (frame)
      Lisp_Object frame;
 For a terminal screen, the value is always 1.  */)
      (frame)
      Lisp_Object frame;
@@ -2547,7 +2590,7 @@ extern Lisp_Object Qbox;
 extern Lisp_Object Qtop;
 
 /* Calculate fullscreen size.  Return in *TOP_POS and *LEFT_POS the
 extern Lisp_Object Qtop;
 
 /* Calculate fullscreen size.  Return in *TOP_POS and *LEFT_POS the
-   wanted positions of the WM window (not emacs window).
+   wanted positions of the WM window (not Emacs window).
    Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
    window (FRAME_X_WINDOW).
  */
    Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
    window (FRAME_X_WINDOW).
  */
@@ -2679,12 +2722,20 @@ x_set_frame_parameters (f, alist)
           || EQ (prop, Qfullscreen))
        {
          register Lisp_Object param_index, old_value;
           || EQ (prop, Qfullscreen))
        {
          register Lisp_Object param_index, old_value;
+         int count = SPECPDL_INDEX ();
 
          old_value = get_frame_param (f, prop);
          fullscreen_is_being_set |= EQ (prop, Qfullscreen);
 
          if (NILP (Fequal (val, old_value)))
            {
 
          old_value = get_frame_param (f, prop);
          fullscreen_is_being_set |= EQ (prop, Qfullscreen);
 
          if (NILP (Fequal (val, old_value)))
            {
+             /* For :font attributes, the frame_parm_handler
+                x_set_font calls `face-set-after-frame-default'.
+                Unless we bind inhibit-face-set-after-frame-default
+                here, this would reset the :font attribute that we
+                just applied to the default value for new faces.  */
+             specbind (Qinhibit_face_set_after_frame_default, Qt);
+
              store_frame_param (f, prop, val);
 
              param_index = Fget (prop, Qx_frame_parameter);
              store_frame_param (f, prop, val);
 
              param_index = Fget (prop, Qx_frame_parameter);
@@ -2693,6 +2744,8 @@ x_set_frame_parameters (f, alist)
                      < sizeof (frame_parms)/sizeof (frame_parms[0]))
                  && rif->frame_parm_handlers[XINT (param_index)])
                (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
                      < sizeof (frame_parms)/sizeof (frame_parms[0]))
                  && rif->frame_parm_handlers[XINT (param_index)])
                (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
+
+             unbind_to (count, Qnil);
            }
        }
     }
            }
        }
     }
@@ -2774,8 +2827,6 @@ x_set_frame_parameters (f, alist)
        XSETINT (icon_top, 0);
     }
 
        XSETINT (icon_top, 0);
     }
 
-#ifndef HAVE_CARBON
-  /* MAC_TODO: fullscreen */
   if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set)
     {
       /* If the frame is visible already and the fullscreen parameter is
   if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set)
     {
       /* If the frame is visible already and the fullscreen parameter is
@@ -2791,7 +2842,6 @@ x_set_frame_parameters (f, alist)
       if (new_top != f->top_pos || new_left != f->left_pos)
         x_set_offset (f, new_left, new_top, 1);
     }
       if (new_top != f->top_pos || new_left != f->left_pos)
         x_set_offset (f, new_left, new_top, 1);
     }
-#endif
 
   /* Don't set these parameters unless they've been explicitly
      specified.  The window might be mapped or resized while we're in
 
   /* Don't set these parameters unless they've been explicitly
      specified.  The window might be mapped or resized while we're in
@@ -2952,14 +3002,11 @@ x_report_frame_params (f, alistptr)
   store_in_alist (alistptr, Qdisplay,
                  XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element));
 
   store_in_alist (alistptr, Qdisplay,
                  XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element));
 
-#ifndef HAVE_CARBON
-/* A Mac Window is identified by a struct, not an integer.  */
   if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window)
     tem = Qnil;
   else
     XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc);
   store_in_alist (alistptr, Qparent_id, tem);
   if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window)
     tem = Qnil;
   else
     XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc);
   store_in_alist (alistptr, Qparent_id, tem);
-#endif
 }
 
 
 }
 
 
@@ -2971,7 +3018,6 @@ x_set_fullscreen (f, new_value, old_value)
      struct frame *f;
      Lisp_Object new_value, old_value;
 {
      struct frame *f;
      Lisp_Object new_value, old_value;
 {
-#ifndef HAVE_CARBON
   if (NILP (new_value))
     f->want_fullscreen = FULLSCREEN_NONE;
   else if (EQ (new_value, Qfullboth))
   if (NILP (new_value))
     f->want_fullscreen = FULLSCREEN_NONE;
   else if (EQ (new_value, Qfullboth))
@@ -2980,7 +3026,9 @@ x_set_fullscreen (f, new_value, old_value)
     f->want_fullscreen = FULLSCREEN_WIDTH;
   else if (EQ (new_value, Qfullheight))
     f->want_fullscreen = FULLSCREEN_HEIGHT;
     f->want_fullscreen = FULLSCREEN_WIDTH;
   else if (EQ (new_value, Qfullheight))
     f->want_fullscreen = FULLSCREEN_HEIGHT;
-#endif
+
+  if (fullscreen_hook != NULL) 
+    fullscreen_hook (f);
 }
 
 
 }
 
 
@@ -2997,8 +3045,7 @@ x_set_line_spacing (f, new_value, old_value)
   else if (NATNUMP (new_value))
     f->extra_line_spacing = XFASTINT (new_value);
   else
   else if (NATNUMP (new_value))
     f->extra_line_spacing = XFASTINT (new_value);
   else
-    Fsignal (Qerror, Fcons (build_string ("Invalid line-spacing"),
-                           Fcons (new_value, Qnil)));
+    signal_error ("Invalid line-spacing", new_value);
   if (FRAME_VISIBLE_P (f))
     redraw_frame (f);
 }
   if (FRAME_VISIBLE_P (f))
     redraw_frame (f);
 }
@@ -3012,16 +3059,30 @@ x_set_screen_gamma (f, new_value, old_value)
      struct frame *f;
      Lisp_Object new_value, old_value;
 {
      struct frame *f;
      Lisp_Object new_value, old_value;
 {
+  Lisp_Object bgcolor;
+
   if (NILP (new_value))
     f->gamma = 0;
   else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0)
     /* The value 0.4545 is the normal viewing gamma.  */
     f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value));
   else
   if (NILP (new_value))
     f->gamma = 0;
   else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0)
     /* The value 0.4545 is the normal viewing gamma.  */
     f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value));
   else
-    Fsignal (Qerror, Fcons (build_string ("Invalid screen-gamma"),
-                           Fcons (new_value, Qnil)));
+    signal_error ("Invalid screen-gamma", new_value);
 
 
-  clear_face_cache (0);
+  /* Apply the new gamma value to the frame background.  */
+  bgcolor = Fassq (Qbackground_color, f->param_alist);
+  if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor)))
+    {
+      Lisp_Object index = Fget (Qbackground_color, Qx_frame_parameter);
+      if (NATNUMP (index)
+         && (XFASTINT (index)
+             < sizeof (frame_parms)/sizeof (frame_parms[0]))
+         && rif->frame_parm_handlers[XFASTINT (index)])
+       (*(rif->frame_parm_handlers[XFASTINT (index)]))
+         (f, bgcolor, Qnil);
+    }
+
+  Fclear_face_cache (Qnil);
 }
 
 
 }
 
 
@@ -3051,6 +3112,7 @@ x_set_font (f, arg, oldval)
     error ("The characters of the given font have varying widths");
   else if (STRINGP (result))
     {
     error ("The characters of the given font have varying widths");
   else if (STRINGP (result))
     {
+      set_default_ascii_font (result);
       if (STRINGP (fontset_name))
        {
          /* Fontset names are built from ASCII font names, so the
       if (STRINGP (fontset_name))
        {
          /* Fontset names are built from ASCII font names, so the
@@ -3061,6 +3123,11 @@ x_set_font (f, arg, oldval)
       else if (!NILP (Fequal (result, oldval)))
         return;
 
       else if (!NILP (Fequal (result, oldval)))
         return;
 
+      /* Recalculate toolbar height.  */
+      f->n_tool_bar_rows = 0;
+      /* Ensure we redraw it.  */
+      clear_current_matrices (f);
+
       store_frame_param (f, Qfont, result);
       recompute_basic_faces (f);
     }
       store_frame_param (f, Qfont, result);
       recompute_basic_faces (f);
     }
@@ -3100,10 +3167,8 @@ x_set_border_width (f, arg, oldval)
   if (XINT (arg) == f->border_width)
     return;
 
   if (XINT (arg) == f->border_width)
     return;
 
-#ifndef HAVE_CARBON
   if (FRAME_X_WINDOW (f) != 0)
   if (FRAME_X_WINDOW (f) != 0)
-    error ("Cannot change the border width of a window");
-#endif /* MAC_TODO */
+    error ("Cannot change the border width of a frame");
 
   f->border_width = XINT (arg);
 }
 
   f->border_width = XINT (arg);
 }
@@ -3339,7 +3404,7 @@ extern char *x_get_string_resource P_ ((XrmDatabase, char *, char *));
 extern Display_Info *check_x_display_info P_ ((Lisp_Object));
 
 
 extern Display_Info *check_x_display_info P_ ((Lisp_Object));
 
 
-/* Get specified attribute from resource database RDB.  
+/* Get specified attribute from resource database RDB.
    See Fx_get_resource below for other parameters.  */
 
 static Lisp_Object
    See Fx_get_resource below for other parameters.  */
 
 static Lisp_Object
@@ -3476,7 +3541,7 @@ x_get_resource_string (attribute, class)
 
 Lisp_Object
 x_get_arg (dpyinfo, alist, param, attribute, class, type)
 
 Lisp_Object
 x_get_arg (dpyinfo, alist, param, attribute, class, type)
-     Display_Info *dpyinfo; 
+     Display_Info *dpyinfo;
      Lisp_Object alist, param;
      char *attribute;
      char *class;
      Lisp_Object alist, param;
      char *attribute;
      char *class;
@@ -3485,8 +3550,27 @@ x_get_arg (dpyinfo, alist, param, attribute, class, type)
   register Lisp_Object tem;
 
   tem = Fassq (param, alist);
   register Lisp_Object tem;
 
   tem = Fassq (param, alist);
-  if (EQ (tem, Qnil))
+
+  if (!NILP (tem))
+    {
+      /* If we find this parm in ALIST, clear it out
+        so that it won't be "left over" at the end.  */
+#ifndef WINDOWSNT /* w32fns.c has not yet been changed to cope with this.  */
+      Lisp_Object tail;
+      XSETCAR (tem, Qnil);
+      /* In case the parameter appears more than once in the alist,
+        clear it out.  */
+      for (tail = alist; CONSP (tail); tail = XCDR (tail))
+       if (CONSP (XCAR (tail))
+           && EQ (XCAR (XCAR (tail)), param))
+         XSETCAR (XCAR (tail), Qnil);
+#endif
+    }
+  else
     tem = Fassq (param, Vdefault_frame_alist);
     tem = Fassq (param, Vdefault_frame_alist);
+
+  /* If it wasn't specified in ALIST or the Lisp-level defaults,
+     look in the X resources.  */
   if (EQ (tem, Qnil))
     {
       if (attribute)
   if (EQ (tem, Qnil))
     {
       if (attribute)
@@ -3570,7 +3654,7 @@ x_frame_get_and_record_arg (f, alist, param, attribute, class, type)
 
   value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param,
                     attribute, class, type);
 
   value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param,
                     attribute, class, type);
-  if (! NILP (value))
+  if (! NILP (value) && ! EQ (value, Qunbound))
     store_frame_param (f, param, value);
 
   return value;
     store_frame_param (f, param, value);
 
   return value;
@@ -3941,6 +4025,10 @@ syms_of_frame ()
   Qface_set_after_frame_default = intern ("face-set-after-frame-default");
   staticpro (&Qface_set_after_frame_default);
 
   Qface_set_after_frame_default = intern ("face-set-after-frame-default");
   staticpro (&Qface_set_after_frame_default);
 
+  Qinhibit_face_set_after_frame_default
+    = intern ("inhibit-face-set-after-frame-default");
+  staticpro (&Qinhibit_face_set_after_frame_default);
+
   Qfullwidth = intern ("fullwidth");
   staticpro (&Qfullwidth);
   Qfullheight = intern ("fullheight");
   Qfullwidth = intern ("fullwidth");
   staticpro (&Qfullwidth);
   Qfullheight = intern ("fullheight");
@@ -3997,7 +4085,7 @@ is a reasonable practice.  See also the variable `x-resource-name'.  */);
   DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
               doc: /* Alist of default values for frame creation.
 These may be set in your init file, like this:
   DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
               doc: /* Alist of default values for frame creation.
 These may be set in your init file, like this:
-  (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))
+  (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1)))
 These override values given in window system configuration data,
  including X Windows' defaults database.
 For values specific to the first Emacs frame, see `initial-frame-alist'.
 These override values given in window system configuration data,
  including X Windows' defaults database.
 For values specific to the first Emacs frame, see `initial-frame-alist'.
@@ -4011,7 +4099,7 @@ Setting this variable does not affect existing frames, only new ones.  */);
   DEFVAR_LISP ("default-frame-scroll-bars", &Vdefault_frame_scroll_bars,
               doc: /* Default position of scroll bars on this window-system.  */);
 #ifdef HAVE_WINDOW_SYSTEM
   DEFVAR_LISP ("default-frame-scroll-bars", &Vdefault_frame_scroll_bars,
               doc: /* Default position of scroll bars on this window-system.  */);
 #ifdef HAVE_WINDOW_SYSTEM
-#if defined(HAVE_NTGUI) || defined(HAVE_CARBON)
+#if defined(HAVE_NTGUI) || defined(MAC_OS)
   /* MS-Windows has scroll bars on the right by default.  */
   Vdefault_frame_scroll_bars = Qright;
 #else
   /* MS-Windows has scroll bars on the right by default.  */
   Vdefault_frame_scroll_bars = Qright;
 #else
@@ -4021,15 +4109,11 @@ Setting this variable does not affect existing frames, only new ones.  */);
   Vdefault_frame_scroll_bars = Qnil;
 #endif
 
   Vdefault_frame_scroll_bars = Qnil;
 #endif
 
-  Qinhibit_default_face_x_resources
-    = intern ("inhibit-default-face-x-resources");
-  staticpro (&Qinhibit_default_face_x_resources);
-
   DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
               doc: /* The initial frame-object, which represents Emacs's stdout.  */);
 
   DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
   DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
               doc: /* The initial frame-object, which represents Emacs's stdout.  */);
 
   DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
-              doc: /* Non-nil if all of emacs is iconified and frame updates are not needed.  */);
+              doc: /* Non-nil if all of Emacs is iconified and frame updates are not needed.  */);
   Vemacs_iconified = Qnil;
 
   DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function,
   Vemacs_iconified = Qnil;
 
   DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function,
@@ -4069,6 +4153,21 @@ displayed.
 
 This variable is local to the current terminal and cannot be buffer-local.  */);
 
 
 This variable is local to the current terminal and cannot be buffer-local.  */);
 
+  DEFVAR_BOOL ("focus-follows-mouse", &focus_follows_mouse,
+              doc: /* Non-nil if window system changes focus when you move the mouse.
+You should set this variable to tell Emacs how your window manager
+handles focus, since there is no way in general for Emacs to find out
+automatically.  */);
+#ifdef HAVE_WINDOW_SYSTEM
+#if defined(HAVE_NTGUI) || defined(MAC_OS)
+  focus_follows_mouse = 0;
+#else
+  focus_follows_mouse = 1;
+#endif
+#else
+  focus_follows_mouse = 0;
+#endif
+        
   staticpro (&Vframe_list);
 
   defsubr (&Sactive_minibuffer_window);
   staticpro (&Vframe_list);
 
   defsubr (&Sactive_minibuffer_window);
@@ -4076,7 +4175,6 @@ This variable is local to the current terminal and cannot be buffer-local.  */);
   defsubr (&Sframe_live_p);
   defsubr (&Smake_terminal_frame);
   defsubr (&Shandle_switch_frame);
   defsubr (&Sframe_live_p);
   defsubr (&Smake_terminal_frame);
   defsubr (&Shandle_switch_frame);
-  defsubr (&Signore_event);
   defsubr (&Sselect_frame);
   defsubr (&Sselected_frame);
   defsubr (&Swindow_frame);
   defsubr (&Sselect_frame);
   defsubr (&Sselected_frame);
   defsubr (&Swindow_frame);