(detect_coding_iso2022): Do not exclude posibility of
[bpt/emacs.git] / src / frame.c
index 8dea582..bb0cfd4 100644 (file)
@@ -1,5 +1,5 @@
 /* Generic frame functions.
-   Copyright (C) 1993, 1994, 1995 Free Software Foundation.
+   Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation.
 
 This file is part of GNU Emacs.
 
@@ -22,6 +22,10 @@ Boston, MA 02111-1307, USA.  */
 
 #include <stdio.h>
 #include "lisp.h"
+#include "charset.h"
+#ifdef HAVE_WINDOW_SYSTEM
+#include "fontset.h"
+#endif
 #include "frame.h"
 #include "termhooks.h"
 #include "window.h"
@@ -75,10 +79,11 @@ Lisp_Object Qunsplittable;
 Lisp_Object Qmenu_bar_lines;
 Lisp_Object Qwidth;
 Lisp_Object Qx;
-Lisp_Object Qwin32;
+Lisp_Object Qw32;
 Lisp_Object Qpc;
 Lisp_Object Qvisible;
 Lisp_Object Qbuffer_predicate;
+Lisp_Object Qbuffer_list;
 Lisp_Object Qtitle;
 
 Lisp_Object Vterminal_frame;
@@ -112,14 +117,16 @@ syms_of_frame_1 ()
   staticpro (&Qwidth);
   Qx = intern ("x");
   staticpro (&Qx);
-  Qwin32 = intern ("win32");
-  staticpro (&Qwin32);
+  Qw32 = intern ("w32");
+  staticpro (&Qw32);
   Qpc = intern ("pc");
   staticpro (&Qpc);
   Qvisible = intern ("visible");
   staticpro (&Qvisible);
   Qbuffer_predicate = intern ("buffer-predicate");
   staticpro (&Qbuffer_predicate);
+  Qbuffer_list = intern ("buffer-list");
+  staticpro (&Qbuffer_list);
   Qtitle = intern ("title");
   staticpro (&Qtitle);
 
@@ -221,8 +228,8 @@ See also `frame-live-p'.")
       return Qt;
     case output_x_window:
       return Qx;
-    case output_win32:
-      return Qwin32;
+    case output_w32:
+      return Qw32;
     case output_msdos_raw:
       return Qpc;
     default:
@@ -281,7 +288,7 @@ make_frame (mini_p)
   f->focus_frame = Qnil;
   f->explicit_name = 0;
   f->can_have_scroll_bars = 0;
-  f->has_vertical_scroll_bars = 0;
+  f->vertical_scroll_bar_type = vertical_scroll_bar_none;
   f->param_alist = Qnil;
   f->scroll_bars = Qnil;
   f->condemned_scroll_bars = Qnil;
@@ -290,6 +297,7 @@ make_frame (mini_p)
   f->menu_bar_vector = Qnil;
   f->menu_bar_items_used = 0;
   f->buffer_predicate = Qnil;
+  f->buffer_list = Qnil;
 #ifdef MULTI_KBOARD
   f->kboard = initial_kboard;
 #endif
@@ -319,7 +327,7 @@ make_frame (mini_p)
      just so that there is "something there."
      Correct size will be set up later with change_frame_size.  */
 
-  f->width = 10;
+  SET_FRAME_WIDTH (f, 10);
   f->height = 10;
 
   XSETFASTINT (XWINDOW (root_window)->width, 10);
@@ -343,6 +351,8 @@ make_frame (mini_p)
     if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
       buf = Fother_buffer (buf, Qnil);
     Fset_window_buffer (root_window, buf);
+
+    f->buffer_list = Fcons (buf, Qnil);
   }
 
   if (mini_p)
@@ -360,6 +370,10 @@ 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
@@ -488,15 +502,8 @@ make_terminal_frame ()
   Vframe_list = Fcons (frame, Vframe_list);
 
   terminal_frame_count++;
-  if (terminal_frame_count == 1)
-    {
-      f->name = build_string ("Emacs");
-    }
-  else
-    {
-      sprintf (name, "Emacs-%d", terminal_frame_count);
-      f->name = build_string (name);
-    }
+  sprintf (name, "F%d", terminal_frame_count);
+  f->name = build_string (name);
 
   f->visible = 1;              /* FRAME_SET_VISIBLE wd set frame_garbaged. */
   f->async_visible = 1;                /* Don't let visible be cleared later. */
@@ -537,6 +544,7 @@ Note that changing the size of one terminal frame automatically affects all.")
   remake_frame_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;
   return frame;
@@ -1063,6 +1071,13 @@ but if the second optional argument FORCE is non-nil, you may do so.")
   if (NILP (force) && !other_visible_frames (f))
     error ("Attempt to delete the sole visible or iconified frame");
 
+#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))
+    error ("Attempt to delete the only frame");
+#endif
+
   /* Does this frame have a minibuffer, and is it the surrogate
      minibuffer for any other frame?  */
   if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
@@ -1134,6 +1149,12 @@ but if the second optional argument FORCE is non-nil, you may do so.")
   Vframe_list = Fdelq (frame, Vframe_list);
   FRAME_SET_VISIBLE (f, 0);
 
+  if (echo_area_glyphs == FRAME_MESSAGE_BUF (f))
+    {
+      echo_area_glyphs = 0;
+      previous_echo_glyphs = 0;
+    }
+
   if (f->namebuf)
     free (f->namebuf);
   if (FRAME_CURRENT_GLYPHS (f))
@@ -1150,6 +1171,13 @@ but if the second optional argument FORCE is non-nil, you may do so.")
     free (FRAME_INSERTN_COST (f));
   if (FRAME_DELETE_COST (f))
     free (FRAME_DELETE_COST (f));
+  if (FRAME_MESSAGE_BUF (f))
+    free (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
@@ -1245,6 +1273,9 @@ but if the second optional argument FORCE is non-nil, you may do so.")
        FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
     }
 
+  /* Cause frame titles to update--necessary if we now have just one frame.  */
+  update_mode_lines = 1;
+
   return Qnil;
 }
 \f
@@ -1617,13 +1648,6 @@ The redirection lasts until `redirect-frame-focus' is called to change it.")
 
   XFRAME (frame)->focus_frame = focus_frame;
 
-  /* I think this should be done with a hook.  */
-#ifdef HAVE_WINDOW_SYSTEM
-  if (!NILP (focus_frame) && ! EQ (focus_frame, frame)
-      && (FRAME_WINDOW_P (XFRAME (focus_frame))))
-    Ffocus_frame (focus_frame);
-#endif
-
   if (frame_rehighlight_hook)
     (*frame_rehighlight_hook) (XFRAME (frame));
   
@@ -1668,6 +1692,54 @@ frame_buffer_predicate ()
   return selected_frame->buffer_predicate;
 }
 
+/* Return the buffer-list of the selected frame.  */
+
+Lisp_Object
+frame_buffer_list ()
+{
+  return selected_frame->buffer_list;
+}
+
+/* Set the buffer-list of the selected frame.  */
+
+void
+set_frame_buffer_list (list)
+     Lisp_Object list;
+{
+  selected_frame->buffer_list = list;
+}
+
+/* Discard BUFFER from the buffer-list of each frame.  */
+
+void
+frames_discard_buffer (buffer)
+     Lisp_Object buffer;
+{
+  Lisp_Object frame, tail;
+
+  FOR_EACH_FRAME (tail, frame)
+    {
+      XFRAME (frame)->buffer_list
+       = Fdelq (buffer, XFRAME (frame)->buffer_list);
+    }
+}
+
+/* Move BUFFER to the end of the buffer-list of each frame.  */
+
+void
+frames_bury_buffer (buffer)
+     Lisp_Object buffer;
+{
+  Lisp_Object frame, tail;
+
+  FOR_EACH_FRAME (tail, frame)
+    {
+      XFRAME (frame)->buffer_list
+       = nconc2 (Fdelq (buffer, XFRAME (frame)->buffer_list),
+                 Fcons (buffer, Qnil));
+    }
+}
+
 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
    If the alist already has an element for PROP, we change it.  */
 
@@ -1692,6 +1764,12 @@ store_frame_param (f, prop, val)
 {
   register Lisp_Object tem;
 
+  if (EQ (prop, Qbuffer_list))
+    {
+      f->buffer_list = val;
+      return;
+    }
+
   tem = Fassq (prop, f->param_alist);
   if (EQ (tem, Qnil))
     f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
@@ -1710,8 +1788,9 @@ 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))
-       error ("can't change the surrogate minibuffer of a frame with its own minibuffer");
+      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");
 
       /* Install the chosen minibuffer window, with proper buffer.  */
       f->minibuffer_window = val;
@@ -1769,6 +1848,7 @@ If FRAME is omitted, return information on the currently selected frame.")
                   : FRAME_MINIBUF_ONLY_P (f) ? Qonly
                   : FRAME_MINIBUF_WINDOW (f)));
   store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
+  store_in_alist (&alist, Qbuffer_list, frame_buffer_list ());
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -1790,7 +1870,9 @@ DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
   "Modify the parameters of frame FRAME according to ALIST.\n\
 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; undefined PARMs are ignored.")
+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.")
   (frame, alist)
      Lisp_Object frame, alist;
 {
@@ -1816,13 +1898,35 @@ The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
     IT_set_frame_parameters (f, alist);
   else
 #endif
-    for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
-      {
-       elt = Fcar (tail);
-       prop = Fcar (elt);
-       val = Fcdr (elt);
-       store_frame_param (f, prop, val);
-      }
+    {
+      int length = XINT (Flength (alist));
+      int i;
+      Lisp_Object *parms
+       = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
+      Lisp_Object *values
+       = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
+
+      /* Extract parm names and values into those vectors.  */
+
+      i = 0;
+      for (tail = alist; CONSP (tail); tail = Fcdr (tail))
+       {
+         Lisp_Object elt, prop, val;
+
+         elt = Fcar (tail);
+         parms[i] = Fcar (elt);
+         values[i] = Fcdr (elt);
+         i++;
+       }
+
+      /* Now process them in reverse of specified order.  */
+      for (i--; i >= 0; i--)
+       {
+         prop = parms[i];
+         val = values[i];
+         store_frame_param (f, prop, val);
+       }
+    }
 
   return Qnil;
 }