]> code.delx.au - gnu-emacs/blobdiff - src/frame.c
(Fget_char_property): Update call to overlays_at.
[gnu-emacs] / src / frame.c
index bfd4b2d49195ba26bec9b05ae0138a271da2f2c1..efbf7a122596fe04264cfab46de379a798796835 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"
@@ -90,7 +90,7 @@ 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;
@@ -103,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 ()
@@ -128,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");
@@ -173,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))
@@ -225,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 ();
@@ -235,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)
@@ -307,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;
@@ -329,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)
@@ -407,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
@@ -548,9 +554,13 @@ 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;
-#endif /* MSDOS */
-
+  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;
@@ -562,16 +572,15 @@ make_terminal_frame ()
   f->auto_raise = 1;
   f->auto_lower = 1;
   init_frame_faces (f);
-#endif /* macintosh */
+#else  /* !macintosh */
+  f->output_data.x = &tty_display;
+#endif /* !macintosh */
+#endif /* MSDOS */
 
-#ifndef MSDOS
 #ifndef macintosh
-  f->output_data.nothing = 1;  /* Nonzero means frame isn't deleted.  */
-#endif
-#endif
-
   if (!noninteractive)
     init_frame_faces (f);
+#endif
   return f;
 }
 
@@ -587,25 +596,27 @@ Note that changing the size of one terminal frame automatically affects all.")
 {
   struct frame *f;
   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 (selected_frame->output_method != output_mac)
+  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, 0);
+  change_frame_size (f, FRAME_HEIGHT (sf),
+                    FRAME_WIDTH (sf), 0, 0, 0);
   adjust_glyphs (f);
   calculate_costs (f);
   XSETFRAME (frame, f);
@@ -614,7 +625,7 @@ Note that changing the size of one terminal frame automatically affects all.")
 
   /* Make the frame face alist be frame-specific, so that each
      frame could change its face definitions independently.  */
-  f->face_alist = Fcopy_alist (selected_frame->face_alist);
+  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.  */
@@ -628,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,
@@ -642,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
@@ -659,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 */
@@ -683,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);
 
@@ -751,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,
@@ -774,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);
@@ -806,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,
@@ -821,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,
@@ -838,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;
@@ -886,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)))
@@ -914,7 +934,7 @@ next_frame (frame, minibuf)
                if (FRAME_VISIBLE_P (XFRAME (f)))
                  return f;
              }
-           else if (XFASTINT (minibuf) == 0)
+           else if (INTEGERP (minibuf) && XINT (minibuf) == 0)
              {
                FRAME_SAMPLE_VISIBILITY (XFRAME (f));
                if (FRAME_VISIBLE_P (XFRAME (f))
@@ -924,11 +944,9 @@ next_frame (frame, minibuf)
            else if (WINDOWP (minibuf))
              {
                if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
-                   /* Check that F either is, or has forwarded its focus to,
-                      MINIBUF's frame.  */
-                   && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
-                       || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
-                              FRAME_FOCUS_FRAME (XFRAME (f)))))
+                   || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
+                   || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
+                          FRAME_FOCUS_FRAME (XFRAME (f))))
                  return f;
              }
            else
@@ -961,11 +979,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 ();
 
@@ -984,11 +1002,9 @@ prev_frame (frame, minibuf)
          else if (WINDOWP (minibuf))
            {
              if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
-                 /* Check that F either is, or has forwarded its focus to,
-                    MINIBUF's frame.  */
-                 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
-                     || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
-                            FRAME_FOCUS_FRAME (XFRAME (f)))))
+                 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
+                 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
+                        FRAME_FOCUS_FRAME (XFRAME (f))))
                prev = f;
            }
          else if (EQ (minibuf, Qvisible))
@@ -1036,13 +1052,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);
 }
 
@@ -1060,13 +1073,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
@@ -1080,18 +1089,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.  */
@@ -1125,11 +1134,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
@@ -1147,7 +1157,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
 
@@ -1159,10 +1169,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,
@@ -1175,7 +1185,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;
 
@@ -1193,14 +1203,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.  */
@@ -1208,6 +1219,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))
@@ -1241,11 +1256,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
@@ -1278,9 +1288,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;
@@ -1306,12 +1316,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);
@@ -1362,17 +1372,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
@@ -1392,7 +1405,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,
@@ -1409,10 +1426,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
@@ -1504,7 +1520,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);
 
@@ -1558,7 +1574,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);
 
@@ -1567,16 +1583,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.  */
@@ -1599,22 +1616,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.  */
@@ -1659,9 +1677,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);
@@ -1682,7 +1700,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);
 
@@ -1705,7 +1723,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);
   
@@ -1842,9 +1860,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));
     }
 }
 
@@ -1873,7 +1895,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;
@@ -1929,20 +1952,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;
 
@@ -1959,7 +2003,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");
 
@@ -1979,36 +2023,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);
-      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 (msdos_stdcolor_name (rv ? bg : fg)));
+                     tty_color_name (f, fg));
       store_in_alist (&alist, intern ("background-color"),
-                     build_string (msdos_stdcolor_name (rv ? fg : 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));
@@ -2021,7 +2063,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
@@ -2035,6 +2077,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;
 }
 
@@ -2045,20 +2089,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
@@ -2090,7 +2135,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);
@@ -2121,12 +2166,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))
@@ -2150,12 +2192,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))
@@ -2178,12 +2217,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))
@@ -2204,12 +2240,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))
@@ -2230,12 +2263,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
@@ -2261,12 +2291,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
@@ -2288,7 +2315,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);
@@ -2321,7 +2347,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);
@@ -2352,6 +2377,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\