*** empty log message ***
[bpt/emacs.git] / src / frame.c
index 6c8f234..0a8ac6a 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, 2000 Free Software Foundation.
 
 This file is part of GNU Emacs.
 
@@ -21,14 +21,14 @@ 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_X_WINDOWS
 #include "xterm.h"
 #endif
+#ifdef WINDOWSNT
+#include "w32term.h"
+#endif
 #include "frame.h"
 #ifdef HAVE_WINDOW_SYSTEM
 #include "fontset.h"
@@ -41,6 +41,11 @@ Boston, MA 02111-1307, USA.  */
 #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
    that initializes and staticpros the symbols declared below.  Note
    that Emacs 18 has a bug that keeps C-x C-e from being able to
@@ -85,11 +90,12 @@ Lisp_Object Qname;
 Lisp_Object Qonly;
 Lisp_Object Qunsplittable;
 Lisp_Object Qmenu_bar_lines;
-Lisp_Object Qtoolbar_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;
@@ -97,6 +103,7 @@ Lisp_Object Qtitle;
 
 Lisp_Object Vterminal_frame;
 Lisp_Object Vdefault_frame_alist;
+Lisp_Object Vmouse_position_function;
 
 static void
 syms_of_frame_1 ()
@@ -122,8 +129,8 @@ syms_of_frame_1 ()
   staticpro (&Qunsplittable);
   Qmenu_bar_lines = intern ("menu-bar-lines");
   staticpro (&Qmenu_bar_lines);
-  Qtoolbar_lines = intern ("toolbar-lines");
-  staticpro (&Qtoolbar_lines);
+  Qtool_bar_lines = intern ("tool-bar-lines");
+  staticpro (&Qtool_bar_lines);
   Qwidth = intern ("width");
   staticpro (&Qwidth);
   Qx = intern ("x");
@@ -132,6 +139,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");
@@ -165,6 +174,11 @@ set_menu_bar_lines_1 (window, n)
   XSETFASTINT (w->last_modified, 0);
   XSETFASTINT (w->top, XFASTINT (w->top) + n);
   XSETFASTINT (w->height, XFASTINT (w->height) - n);
+  
+  if (INTEGERP (w->orig_top))
+    XSETFASTINT (w->orig_top, XFASTINT (w->orig_top) + n);
+  if (INTEGERP (w->orig_height))
+    XSETFASTINT (w->orig_height, XFASTINT (w->orig_height) - n);
 
   /* Handle just the top child in a vertical split.  */
   if (!NILP (w->vchild))
@@ -217,6 +231,8 @@ set_menu_bar_lines (f, value, oldval)
 Lisp_Object Vemacs_iconified;
 Lisp_Object Vframe_list;
 
+struct x_output tty_display;
+
 extern Lisp_Object Vminibuffer_list;
 extern Lisp_Object get_minibuffer ();
 extern Lisp_Object Fhandle_switch_frame ();
@@ -227,6 +243,8 @@ DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
   "Return non-nil if OBJECT is a frame.\n\
 Value is t for a termcap frame (a character-only terminal),\n\
 `x' for an Emacs frame that is really an X window,\n\
+`w32' for an Emacs frame that is a window on MS-Windows display,\n\
+`mac' for an Emacs frame on a Macintosh display,\n\
 `pc' for a direct-write MS-DOS frame.\n\
 See also `frame-live-p'.")
   (object)
@@ -244,6 +262,8 @@ See also `frame-live-p'.")
       return Qw32;
     case output_msdos_raw:
       return Qpc;
+    case output_mac:
+      return Qmac;
     default:
       abort ();
     }
@@ -297,7 +317,7 @@ make_frame (mini_p)
   f->auto_raise = 0;
   f->auto_lower = 0;
   f->no_split = 0;
-  f->garbaged = 0;
+  f->garbaged = 1;
   f->has_minibuffer = mini_p;
   f->focus_frame = Qnil;
   f->explicit_name = 0;
@@ -319,10 +339,10 @@ make_frame (mini_p)
   f->namebuf = 0;
   f->title = Qnil;
   f->menu_bar_window = Qnil;
-  f->toolbar_window = Qnil;
-  f->desired_toolbar_items = f->current_toolbar_items = Qnil;
-  f->desired_toolbar_string = f->current_toolbar_string = Qnil;
-  f->n_desired_toolbar_items = f->n_current_toolbar_items = 0;
+  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)
@@ -397,10 +417,6 @@ make_frame (mini_p)
      a newly-created, never-selected window.  */
   XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
 
-#ifdef HAVE_WINDOW_SYSTEM
-  f->fontset_data = alloc_fontset_data ();
-#endif
-
   return f;
 }
 \f
@@ -538,12 +554,33 @@ make_terminal_frame ()
   f->async_visible = 1;                /* Don't let visible be cleared later. */
 #ifdef MSDOS
   f->output_data.x = &the_only_x_display;
-  f->output_method = output_msdos_raw;
-#else /* not MSDOS */
-  f->output_data.nothing = 1;  /* Nonzero means frame isn't deleted.  */
-#endif
+  if (!inhibit_window_system
+      && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
+         || XFRAME (selected_frame)->output_method == output_msdos_raw))
+    f->output_method = output_msdos_raw;
+  else
+    f->output_method = output_termcap;
+#else
+#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  /* !macintosh */
+  f->output_data.x = &tty_display;
+#endif /* !macintosh */
+#endif /* MSDOS */
+
+#ifndef macintosh
   if (!noninteractive)
     init_frame_faces (f);
+#endif
   return f;
 }
 
@@ -558,25 +595,42 @@ 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
+      && sf->output_method != output_termcap)
     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);
+
+  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
@@ -585,12 +639,14 @@ do_switch_frame (frame, no_enter, track)
      Lisp_Object frame, no_enter;
      int track;
 {
+  struct frame *sf = SELECTED_FRAME ();
+  
   /* If FRAME is a switch-frame event, extract the frame we should
      switch to.  */
   if (CONSP (frame)
-      && EQ (XCONS (frame)->car, Qswitch_frame)
-      && CONSP (XCONS (frame)->cdr))
-    frame = XCONS (XCONS (frame)->cdr)->car;
+      && EQ (XCAR (frame), Qswitch_frame)
+      && CONSP (XCDR (frame)))
+    frame = XCAR (XCDR (frame));
 
   /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
      a switch-frame event to arrive after a frame is no longer live,
@@ -599,7 +655,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
@@ -616,17 +672,17 @@ do_switch_frame (frame, no_enter, track)
     {
       Lisp_Object tail;
 
-      for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
+      for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
        {
          Lisp_Object focus;
 
-         if (!FRAMEP (XCONS (tail)->car))
+         if (!FRAMEP (XCAR (tail)))
            abort ();
 
-         focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
+         focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
 
-         if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
-           Fredirect_frame_focus (XCONS (tail)->car, frame);
+         if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
+           Fredirect_frame_focus (XCAR (tail), frame);
        }
     }
 #else /* ! 0 */
@@ -640,16 +696,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);
 
@@ -708,9 +764,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,
@@ -731,7 +785,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);
@@ -763,12 +817,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,
@@ -778,12 +837,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,
@@ -795,16 +859,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;
@@ -843,11 +906,11 @@ next_frame (frame, minibuf)
   CHECK_LIVE_FRAME (frame, 0);
 
   while (1)
-    for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
+    for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
       {
        Lisp_Object f;
 
-       f = XCONS (tail)->car;
+       f = XCAR (tail);
 
        if (passed
            && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
@@ -918,11 +981,11 @@ prev_frame (frame, minibuf)
     abort ();
 
   prev = Qnil;
-  for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
+  for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
     {
       Lisp_Object f;
 
-      f = XCONS (tail)->car;
+      f = XCAR (tail);
       if (!FRAMEP (f))
        abort ();
 
@@ -993,13 +1056,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);
 }
 
@@ -1017,13 +1077,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
@@ -1037,18 +1093,18 @@ other_visible_frames (f)
 {
   /* We know the selected frame is visible,
      so if F is some other frame, it can't be the sole visible one.  */
-  if (f == selected_frame)
+  if (f == SELECTED_FRAME ())
     {
       Lisp_Object frames;
       int count = 0;
 
       for (frames = Vframe_list;
           CONSP (frames);
-          frames = XCONS (frames)->cdr)
+          frames = XCDR (frames))
        {
          Lisp_Object this;
 
-         this = XCONS (frames)->car;
+         this = XCAR (frames);
          /* Verify that the frame's window still exists
             and we can still talk to it.  And note any recent change
             in visibility.  */
@@ -1082,11 +1138,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
@@ -1104,7 +1161,7 @@ but if the second optional argument FORCE is non-nil, you may do so.")
 #if 0
   /* This is a nice idea, but x_connection_closed needs to be able
      to delete the last frame, if it is gone.  */
-  if (NILP (XCONS (Vframe_list)->cdr))
+  if (NILP (XCDR (Vframe_list)))
     error ("Attempt to delete the only frame");
 #endif
 
@@ -1116,10 +1173,10 @@ but if the second optional argument FORCE is non-nil, you may do so.")
 
       for (frames = Vframe_list;
           CONSP (frames);
-          frames = XCONS (frames)->cdr)
+          frames = XCDR (frames))
        {
          Lisp_Object this;
-         this = XCONS (frames)->car;
+         this = XCAR (frames);
 
          if (! EQ (this, frame)
              && EQ (frame,
@@ -1132,7 +1189,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;
 
@@ -1150,14 +1207,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.  */
@@ -1165,6 +1223,10 @@ but if the second optional argument FORCE is non-nil, you may do so.")
        Fselect_window (minibuf_window);
     }
 
+  /* Don't let echo_area_window to remain on a deleted frame.  */
+  if (EQ (f->minibuffer_window, echo_area_window))
+    echo_area_window = sf->minibuffer_window;
+
   /* Clear any X selections for this frame.  */
 #ifdef HAVE_X_WINDOWS
   if (FRAME_X_P (f))
@@ -1185,12 +1247,6 @@ 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)
     xfree (f->namebuf);
   if (FRAME_INSERT_COST (f))
@@ -1204,11 +1260,6 @@ but if the second optional argument FORCE is non-nil, you may do so.")
   if (FRAME_MESSAGE_BUF (f))
     xfree (FRAME_MESSAGE_BUF (f));
 
-#ifdef HAVE_WINDOW_SYSTEM
-  /* Free all fontset data.  */
-  free_fontset_data (FRAME_FONTSET_DATA (f));
-#endif
-
   /* Since some events are handled at the interrupt level, we may get
      an event for f at any time; if we zero out the frame's display
      now, then we may trip up the event-handling code.  Instead, we'll
@@ -1221,6 +1272,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
@@ -1233,9 +1292,9 @@ but if the second optional argument FORCE is non-nil, you may do so.")
 
       for (frames = Vframe_list;
           CONSP (frames);
-          frames = XCONS (frames)->cdr)
+          frames = XCDR (frames))
        {
-         f = XFRAME (XCONS (frames)->car);
+         f = XFRAME (XCAR (frames));
          if (!FRAME_MINIBUF_ONLY_P (f))
            {
              last_nonminibuf_frame = f;
@@ -1261,12 +1320,12 @@ but if the second optional argument FORCE is non-nil, you may do so.")
 
       for (frames = Vframe_list;
           CONSP (frames);
-          frames = XCONS (frames)->cdr)
+          frames = XCDR (frames))
        {
          Lisp_Object this;
          struct frame *f1;
 
-         this = XCONS (frames)->car;
+         this = XCAR (frames);
          if (!FRAMEP (this))
            abort ();
          f1 = XFRAME (this);
@@ -1317,17 +1376,20 @@ The position is given in character cells, where (0, 0) is the\n\
 upper-left corner.\n\
 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
 to read the mouse position, it returns the selected frame for FRAME\n\
-and nil for X and Y.")
+and nil for X and Y.\n\
+Runs the abnormal hook `mouse-position-function' with the normal return\n\
+value as argument.")
   ()
 {
   FRAME_PTR f;
   Lisp_Object lispy_dummy;
   enum scroll_bar_part party_dummy;
-  Lisp_Object x, y;
+  Lisp_Object x, y, retval;
   int col, row;
   unsigned long long_dummy;
+  struct gcpro gcpro1;
 
-  f = selected_frame;
+  f = SELECTED_FRAME ();
   x = y = Qnil;
 
 #ifdef HAVE_MOUSE
@@ -1347,7 +1409,11 @@ and nil for X and Y.")
     }
 #endif
   XSETFRAME (lispy_dummy, f);
-  return Fcons (lispy_dummy, Fcons (x, y));
+  retval = Fcons (lispy_dummy, Fcons (x, y));
+  GCPRO1 (retval);
+  if (!NILP (Vmouse_position_function))
+    retval = call1 (Vmouse_position_function, retval);
+  RETURN_UNGCPRO (retval);
 }
 
 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
@@ -1364,10 +1430,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
@@ -1459,7 +1524,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);
 
@@ -1513,7 +1578,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);
 
@@ -1522,16 +1587,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.  */
@@ -1554,22 +1620,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.  */
@@ -1614,9 +1681,9 @@ DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
   Lisp_Object value;
 
   value = Qnil;
-  for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
+  for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
     {
-      frame = XCONS (tail)->car;
+      frame = XCAR (tail);
       if (!FRAMEP (frame))
        continue;
       f = XFRAME (frame);
@@ -1637,7 +1704,7 @@ doesn't support multiple overlapping frames, this function does nothing.")
      Lisp_Object frame;
 {
   if (NILP (frame))
-    XSETFRAME (frame, selected_frame);
+    frame = selected_frame;
 
   CHECK_LIVE_FRAME (frame, 0);
 
@@ -1660,7 +1727,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);
   
@@ -1797,9 +1864,13 @@ frames_bury_buffer (buffer)
 
   FOR_EACH_FRAME (tail, frame)
     {
-      XFRAME (frame)->buffer_list
-       = nconc2 (Fdelq (buffer, XFRAME (frame)->buffer_list),
-                 Fcons (buffer, Qnil));
+      struct frame *f = XFRAME (frame);
+      Lisp_Object found;
+      
+      found = Fmemq (buffer, f->buffer_list);
+      if (!NILP (found))
+       f->buffer_list = nconc2 (Fdelq (buffer, f->buffer_list),
+                                Fcons (buffer, Qnil));
     }
 }
 
@@ -1828,7 +1899,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;
@@ -1884,20 +1956,41 @@ store_frame_param (f, prop, val)
      struct frame *f;
      Lisp_Object prop, val;
 {
-  register Lisp_Object tem;
+  register Lisp_Object old_alist_elt;
 
+  /* The buffer-alist parameter is stored in a special place and is
+     not in the alist.  */
   if (EQ (prop, Qbuffer_list))
     {
       f->buffer_list = val;
       return;
     }
 
-  tem = Fassq (prop, f->param_alist);
-  if (EQ (tem, Qnil))
+  /* If PROP is a symbol which is supposed to have frame-local values,
+     and it is set up based on this frame, switch to the global
+     binding.  That way, we can create or alter the frame-local binding
+     without messing up the symbol's status.  */
+  if (SYMBOLP (prop))
+    {
+      Lisp_Object valcontents;
+      valcontents = XSYMBOL (prop)->value;
+      if ((BUFFER_LOCAL_VALUEP (valcontents)
+          || SOME_BUFFER_LOCAL_VALUEP (valcontents))
+         && XBUFFER_LOCAL_VALUE (valcontents)->check_frame
+         && XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f)
+       swap_in_global_binding (prop);
+    }
+
+  /* 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);
   else
-    Fsetcdr (tem, val);
+    Fsetcdr (old_alist_elt, val);
 
+  /* Update some other special parameters in their special places
+     in addition to the alist.  */
+  
   if (EQ (prop, Qbuffer_predicate))
     f->buffer_predicate = val;
 
@@ -1914,7 +2007,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");
 
@@ -1934,32 +2027,34 @@ If FRAME is omitted, return information on the currently selected frame.")
   Lisp_Object alist;
   FRAME_PTR f;
   int height, width;
+  struct gcpro gcpro1;
 
   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;
 
   alist = Fcopy_alist (f->param_alist);
-#ifdef MSDOS
-  if (FRAME_MSDOS_P (f))
+  GCPRO1 (alist);
+  
+  if (!FRAME_WINDOW_P (f))
     {
       int fg = FRAME_FOREGROUND_PIXEL (f);
       int bg = FRAME_BACKGROUND_PIXEL (f);
 
       store_in_alist (&alist, intern ("foreground-color"),
-                     build_string (msdos_stdcolor_name (fg)));
+                     tty_color_name (f, fg));
       store_in_alist (&alist, intern ("background-color"),
-                     build_string (msdos_stdcolor_name (bg)));
+                     tty_color_name (f, bg));
+      store_in_alist (&alist, intern ("font"),
+                     build_string (FRAME_MSDOS_P (f)
+                                   ? "ms-dos"
+                                   : FRAME_W32_P (f) ? "w32term" : "tty"));
     }
-  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));
   store_in_alist (&alist, Qheight, make_number (height));
@@ -1972,7 +2067,7 @@ If FRAME is omitted, return information on the currently selected frame.")
                   : 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 (Fselected_frame ()));
+                 frame_buffer_list (selected_frame));
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -1986,6 +2081,8 @@ If FRAME is omitted, return information on the currently selected frame.")
       XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
       store_in_alist (&alist, Qmenu_bar_lines, lines);
     }
+
+  UNGCPRO;
   return alist;
 }
 
@@ -1996,20 +2093,21 @@ ALIST is an alist of parameters to change and their new values.\n\
 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
 The meaningful PARMs depend on the kind of frame.\n\
 Undefined PARMs are ignored, but stored in the frame's parameter list\n\
-so that `frame-parameters' will return them.")
+so that `frame-parameters' will return them.\n\
+\n\
+The value of frame parameter FOO can also be accessed\n\
+as a frame-local binding for the variable FOO, if you have\n\
+enabled such bindings for that variable with `make-variable-frame-local'.")
   (frame, alist)
      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
@@ -2022,6 +2120,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;
@@ -2035,7 +2139,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);
@@ -2066,12 +2170,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))
@@ -2095,12 +2196,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))
@@ -2123,12 +2221,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))
@@ -2149,12 +2244,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))
@@ -2175,12 +2267,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
@@ -2188,11 +2277,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 ();
+      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;
 }
 
@@ -2206,12 +2295,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
@@ -2219,11 +2305,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 ();
+      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;
 }
 
@@ -2233,7 +2319,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);
@@ -2247,11 +2332,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 ();
+      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;
 }
@@ -2266,7 +2351,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);
@@ -2297,6 +2381,12 @@ syms_of_frame ()
     "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,
+    "If non-nil, function applied to the normal result of `mouse-position'.\n\
+This abnormal hook exists for the benefit of packages like XTerm-mouse\n\
+which need to do mouse handling at the Lisp level.");
+  Vmouse_position_function = Qnil;
+
   DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
     "Minibufferless frames use this frame's minibuffer.\n\
 \n\