(Ffunction, Fquote): Signal error if not 1 argument.
[bpt/emacs.git] / src / frame.c
index 630961d..b29e20a 100644 (file)
@@ -1,12 +1,12 @@
 /* Generic frame functions.
    Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003,
-                 2004, 2005 Free Software Foundation, Inc.
+                 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
-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,
@@ -71,7 +71,6 @@ Lisp_Object Qx, Qw32, Qmac, Qpc;
 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;
@@ -109,6 +108,7 @@ Lisp_Object Qtty_color_mode;
 
 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
 
+Lisp_Object Qinhibit_face_set_after_frame_default;
 Lisp_Object Qface_set_after_frame_default;
 
 
@@ -1429,7 +1429,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
-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.
@@ -1449,7 +1450,7 @@ and returns whatever that function returns.  */)
   f = SELECTED_FRAME ();
   x = y = Qnil;
 
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   /* It's okay for the hook to refrain from storing anything.  */
   if (mouse_position_hook)
     (*mouse_position_hook) (&f, -1,
@@ -1477,7 +1478,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
-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.  */)
@@ -1492,7 +1494,7 @@ and nil for X and Y.  */)
   f = SELECTED_FRAME ();
   x = y = Qnil;
 
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   /* It's okay for the hook to refrain from storing anything.  */
   if (mouse_position_hook)
     (*mouse_position_hook) (&f, -1,
@@ -1510,6 +1512,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.
 
+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.
@@ -1533,6 +1539,13 @@ before calling this function on it, like this.
       Fselect_frame (frame);
       mouse_moveto (XINT (x), XINT (y));
     }
+#else
+#ifdef HAVE_GPM
+    {
+      Fselect_frame (frame);
+      term_mouse_moveto (XINT (x), XINT (y));
+    }
+#endif
 #endif
 #endif
 
@@ -1542,6 +1555,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.
+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.
@@ -1565,6 +1581,13 @@ before calling this function on it, like this.
       Fselect_frame (frame);
       mouse_moveto (XINT (x), XINT (y));
     }
+#else
+#ifdef HAVE_GPM
+    {
+      Fselect_frame (frame);
+      term_mouse_moveto (XINT (x), XINT (y));
+    }
+#endif
 #endif
 #endif
 
@@ -2259,15 +2282,6 @@ enabled such bindings for that variable with `make-variable-frame-local'.  */)
 {
   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;
@@ -2322,7 +2336,7 @@ enabled such bindings for that variable with `make-variable-frame-local'.  */)
        }
     }
 
-  return unbind_to (count, Qnil);
+  return Qnil;
 }
 \f
 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
@@ -2588,7 +2602,7 @@ extern Lisp_Object Qbox;
 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).
  */
@@ -2720,12 +2734,20 @@ x_set_frame_parameters (f, alist)
           || 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)))
            {
+             /* 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);
@@ -2734,6 +2756,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);
+
+             unbind_to (count, Qnil);
            }
        }
     }
@@ -3014,6 +3038,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;
+
+  if (fullscreen_hook != NULL) 
+    fullscreen_hook (f);
 }
 
 
@@ -3030,8 +3057,7 @@ x_set_line_spacing (f, new_value, old_value)
   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);
 }
@@ -3045,16 +3071,30 @@ x_set_screen_gamma (f, 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
-    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);
 }
 
 
@@ -3095,6 +3135,11 @@ x_set_font (f, arg, oldval)
       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);
     }
@@ -3134,10 +3179,8 @@ x_set_border_width (f, arg, oldval)
   if (XINT (arg) == f->border_width)
     return;
 
-#ifndef MAC_OS
   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);
 }
@@ -3524,9 +3567,15 @@ x_get_arg (dpyinfo, alist, param, attribute, class, type)
     {
       /* If we find this parm in ALIST, clear it out
         so that it won't be "left over" at the end.  */
-#ifdef HAVE_X_WINDOWS /* macfns.c and w32fns.c have not yet
-                        been changed to cope with this.  */
+#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
@@ -3988,6 +4037,10 @@ syms_of_frame ()
   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");
@@ -4068,15 +4121,11 @@ Setting this variable does not affect existing frames, only new ones.  */);
   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,
-              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,