]> code.delx.au - gnu-emacs/blobdiff - src/frame.c
(Fframe_parameters): If a tty's frame's param_alist says
[gnu-emacs] / src / frame.c
index a234229cf49e8fcefa5f960def611c82790108cb..b4afa56803b4d58a0fe5e36d86ee9a2fdbd9ee90 100644 (file)
@@ -29,6 +29,10 @@ Boston, MA 02111-1307, USA.  */
 #ifdef WINDOWSNT
 #include "w32term.h"
 #endif
+#include "buffer.h"
+/* These help us bind and responding to switch-frame events.  */
+#include "commands.h"
+#include "keyboard.h"
 #include "frame.h"
 #ifdef HAVE_WINDOW_SYSTEM
 #include "fontset.h"
@@ -100,6 +104,8 @@ Lisp_Object Qvisible;
 Lisp_Object Qbuffer_predicate;
 Lisp_Object Qbuffer_list;
 Lisp_Object Qtitle;
+Lisp_Object Qdisplay_type;
+Lisp_Object Qbackground_mode;
 
 Lisp_Object Vterminal_frame;
 Lisp_Object Vdefault_frame_alist;
@@ -149,6 +155,10 @@ syms_of_frame_1 ()
   staticpro (&Qbuffer_list);
   Qtitle = intern ("title");
   staticpro (&Qtitle);
+  Qdisplay_type = intern ("display-type");
+  staticpro (&Qdisplay_type);
+  Qbackground_mode = intern ("background-mode");
+  staticpro (&Qbackground_mode);
 
   DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
     "Alist of default values for frame creation.\n\
@@ -222,12 +232,6 @@ set_menu_bar_lines (f, value, oldval)
     }
 }
 \f
-#include "buffer.h"
-
-/* These help us bind and responding to switch-frame events.  */
-#include "commands.h"
-#include "keyboard.h"
-
 Lisp_Object Vemacs_iconified;
 Lisp_Object Vframe_list;
 
@@ -557,7 +561,23 @@ make_terminal_frame ()
   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;
+    {
+      f->output_method = output_msdos_raw;
+      /* This initialization of foreground and background pixels is
+        only important for the initial frame created in temacs.  If
+        we don't do that, we get black background and foreground in
+        the dumped Emacs because the_only_x_display is a static
+        variable, hence it is born all-zeroes, and zero is the code
+        for the black color.  Other frames all inherit their pixels
+        from what's already in the_only_x_display.  */
+      if ((!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
+         && f->output_data.x->background_pixel == 0
+         && f->output_data.x->foreground_pixel == 0)
+       {
+         f->output_data.x->background_pixel = FACE_TTY_DEFAULT_BG_COLOR;
+         f->output_data.x->foreground_pixel = FACE_TTY_DEFAULT_FG_COLOR;
+       }
+    }
   else
     f->output_method = output_termcap;
 #else
@@ -934,7 +954,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))
@@ -944,11 +964,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
@@ -1004,11 +1022,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))
@@ -1956,20 +1972,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;
 
@@ -2024,11 +2061,29 @@ If FRAME is omitted, return information on the currently selected frame.")
     {
       int fg = FRAME_FOREGROUND_PIXEL (f);
       int bg = FRAME_BACKGROUND_PIXEL (f);
-
-      store_in_alist (&alist, intern ("foreground-color"),
-                     tty_color_name (f, fg));
-      store_in_alist (&alist, intern ("background-color"),
-                     tty_color_name (f, bg));
+      Lisp_Object elt;
+
+      /* If the frame's parameter alist says the colors are
+        unspecified and reversed, take the frame's background pixel
+        for foreground and vice versa.  */
+      elt = Fassq (Qforeground_color, alist);
+      if (!NILP (elt) && CONSP (elt)
+         && STRINGP (XCDR (elt))
+         && strncmp (XSTRING (XCDR (elt))->data,
+                     unspecified_bg,
+                     XSTRING (XCDR (elt))->size) == 0)
+       store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg));
+      else
+       store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
+      elt = Fassq (Qbackground_color, alist);
+      if (!NILP (elt) && CONSP (elt)
+         && STRINGP (XCDR (elt))
+         && strncmp (XSTRING (XCDR (elt))->data,
+                     unspecified_fg,
+                     XSTRING (XCDR (elt))->size) == 0)
+       store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg));
+      else
+       store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
       store_in_alist (&alist, intern ("font"),
                      build_string (FRAME_MSDOS_P (f)
                                    ? "ms-dos"
@@ -2065,6 +2120,81 @@ If FRAME is omitted, return information on the currently selected frame.")
   return alist;
 }
 
+
+DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
+   "Return FRAME's value for parameter PARAMETER.\n\
+If FRAME is nil, describe the currently selected frame.")
+  (frame, parameter)
+       Lisp_Object frame, parameter;
+{
+  struct frame *f;
+  Lisp_Object value;
+
+  if (NILP (frame))
+    frame = selected_frame;
+  else
+    CHECK_FRAME (frame, 0);
+  CHECK_SYMBOL (parameter, 1);
+  
+  f = XFRAME (frame);
+  value = Qnil;
+  
+  if (FRAME_LIVE_P (f))
+    {
+      if (EQ (parameter, Qname))
+       value = f->name;
+#ifdef HAVE_X_WINDOWS
+      else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
+       value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element);
+#endif /* HAVE_X_WINDOWS */
+      else
+       {
+         value = Fassq (parameter, f->param_alist);
+         if (CONSP (value))
+           {
+             value = XCDR (value);
+             /* Fframe_parameters puts the actual fg/bg color names,
+                even if f->param_alist says otherwise.  This is
+                important when param_alist's notion of colors is
+                "unspecified".  We need to do the same here.  */
+             if (STRINGP (value) && !FRAME_WINDOW_P (f))
+               {
+                 char *color_name;
+                 EMACS_INT csz;
+
+                 if (EQ (parameter, Qbackground_color))
+                   {
+                     color_name = XSTRING (value)->data;
+                     csz = XSTRING (value)->size;
+                     if (strncmp (color_name, unspecified_bg, csz) == 0)
+                       value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
+                     else if (strncmp (color_name, unspecified_fg, csz) == 0)
+                       value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
+                   }
+                 else if (EQ (parameter, Qforeground_color))
+                   {
+                     color_name = XSTRING (value)->data;
+                     csz = XSTRING (value)->size;
+                     if (strncmp (color_name, unspecified_fg, csz) == 0)
+                       value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
+                     else if (strncmp (color_name, unspecified_bg, csz) == 0)
+                       value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
+                   }
+               }
+           }
+         else if (EQ (parameter, Qdisplay_type)
+                  || EQ (parameter, Qbackground_mode))
+           /* Avoid consing in frequent cases.  */
+           value = Qnil;
+         else
+           value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
+       }
+    }
+  
+  return value;
+}
+
+
 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters, 
        Smodify_frame_parameters, 2, 2, 0,
   "Modify the parameters of frame FRAME according to ALIST.\n\
@@ -2072,7 +2202,11 @@ 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;
 {
@@ -2410,6 +2544,7 @@ displayed.");
   defsubr (&Sredirect_frame_focus);
   defsubr (&Sframe_focus);
   defsubr (&Sframe_parameters);
+  defsubr (&Sframe_parameter);
   defsubr (&Smodify_frame_parameters);
   defsubr (&Sframe_char_height);
   defsubr (&Sframe_char_width);