]> code.delx.au - gnu-emacs/blobdiff - src/frame.c
(Fwhile): If mocklisp, test for nonzeroness.
[gnu-emacs] / src / frame.c
index 4515e0d8c9120c43bd8b1dd98bf89baf065c529a..e706283a0b243d4bd7b05893b26f64fb4c6f4ef7 100644 (file)
@@ -1,5 +1,5 @@
 /* Generic frame functions.
-   Copyright (C) 1989, 1992, 1993 Free Software Foundation.
+   Copyright (C) 1993 Free Software Foundation.
 
 This file is part of GNU Emacs.
 
@@ -82,6 +82,7 @@ Lisp_Object Qmodeline;
 Lisp_Object Qname;
 Lisp_Object Qonly;
 Lisp_Object Qunsplittable;
+Lisp_Object Qmenu_bar_lines;
 Lisp_Object Qwidth;
 Lisp_Object Qx;
 
@@ -157,11 +158,12 @@ make_frame (mini_p)
   f->has_minibuffer = mini_p;
   f->focus_frame = Qnil;
   f->explicit_name = 0;
-  f->can_have_scrollbars = 0;
-  f->has_vertical_scrollbars = 0;
+  f->can_have_scroll_bars = 0;
+  f->has_vertical_scroll_bars = 0;
   f->param_alist = Qnil;
-  f->scrollbars = Qnil;
-  f->condemned_scrollbars = Qnil;
+  f->scroll_bars = Qnil;
+  f->condemned_scroll_bars = Qnil;
+  f->face_alist = Qnil;
 
   root_window = make_window ();
   if (mini_p)
@@ -323,17 +325,27 @@ make_terminal_frame ()
 }
 \f
 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
-  "Select the frame FRAME.  FRAME's selected window becomes \"the\"\n\
-selected window.  If the optional parameter NO-ENTER is non-nil, don't\n\
-focus on that frame.\n\
-\n\
-This function is interactive, and may be bound to the ``switch-frame''\n\
-event; when invoked this way, it switches to the frame named in the\n\
-event.  When called from lisp, FRAME may be a ``switch-frame'' event;\n\
-if it is, select the frame named in the event.\n\
+  "Select the frame FRAME.\n\
+Subsequent editing commands apply to its selected window.\n\
+The selection of FRAME lasts until the next time the user does\n\
+something to select a different frame, or until the next time this\n\
+function is called.")
+  (frame, no_enter)
+    Lisp_Object frame, no_enter;
+{
+  return Fhandle_switch_frame (frame, no_enter);
+}
+
+
+DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
+  "Handle a switch-frame event EVENT.\n\
+Switch-frame events is usually bound to this function.\n\
+A switch-frame event tells Emacs that the window manager has requested\n\
+that the user's events be directed to the frame mentioned in the event.\n\
+This function selects the selected window of the frame of EVENT.\n\
 \n\
-Changing the selected frame can change focus redirections.  See\n\
-`redirect-frame-focus' for details.")
+If EVENT is frame object, handle it as if it were a switch-frame event\n\
+to that frame.")
   (frame, no_enter)
      Lisp_Object frame, no_enter;
 {
@@ -379,17 +391,16 @@ Changing the selected frame can change focus redirections.  See\n\
     last_nonminibuf_frame = selected_frame;
 
   Fselect_window (XFRAME (frame)->selected_window);
-
-  /* I think this should be done with a hook.  */
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (XFRAME (frame))
-      && NILP (no_enter))
-    {
-      Ffocus_frame (frame);
-    }
-#endif
   choose_minibuf_frame ();
 
+  /* We want to make sure that the next event generates a frame-switch
+     event to the appropriate frame.  This seems kludgy to me, but
+     before you take it out, make sure that evaluating something like
+     (select-window (frame-root-window (new-frame))) doesn't end up
+     with your typing being interpreted in the new frame instead of
+     the one you're actually typing in.  */
+  internal_last_event_frame = Qnil;
+
   return frame;
 }
 
@@ -602,7 +613,7 @@ A frame may not be deleted if its minibuffer is used by other frames.")
     }
 
   if (! FRAME_LIVE_P (f))
-    return;
+    return Qnil;
 
   /* Are there any other frames besides this one?  */
   if (f == selected_frame && EQ (next_frame (frame, Qt), frame))
@@ -632,7 +643,7 @@ A frame may not be deleted if its minibuffer is used by other frames.")
 
   /* Don't let the frame remain selected.  */
   if (f == selected_frame)
-    Fselect_frame (next_frame (frame, Qt), Qnil);
+    Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
 
   /* Don't allow minibuf_window to remain on a deleted frame.  */
   if (EQ (f->minibuffer_window, minibuf_window))
@@ -732,6 +743,8 @@ A frame may not be deleted if its minibuffer is used by other frames.")
 
 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
   "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
+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.")
@@ -739,27 +752,26 @@ and nil for X and Y.")
 {
   FRAME_PTR f;
   Lisp_Object lispy_dummy;
-  enum scrollbar_part party_dummy;
+  enum scroll_bar_part party_dummy;
   Lisp_Object x, y;
   unsigned long long_dummy;
 
+  f = selected_frame;
+  x = y = Qnil;
+
+  /* It's okay for the hook to refrain from storing anything.  */
   if (mouse_position_hook)
     (*mouse_position_hook) (&f,
                            &lispy_dummy, &party_dummy,
                            &x, &y,
                            &long_dummy);
-  else
-    {
-      f = selected_frame;
-      x = y = Qnil;
-    }
 
   XSET (lispy_dummy, Lisp_Frame, f);
-  return Fcons (lispy_dummy, Fcons (make_number (x), make_number (y)));
+  return Fcons (lispy_dummy, Fcons (x, y));
 }
 
 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
-  "Move the mouse pointer to the center of cell (X,Y) in FRAME.\n\
+  "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
 WARNING:  If you use this under X, you should do `unfocus-frame' afterwards.")
   (frame, x, y)
      Lisp_Object frame, x, y;
@@ -778,64 +790,8 @@ WARNING:  If you use this under X, you should do `unfocus-frame' afterwards.")
   return Qnil;
 }
 \f
-#if 0
-/* ??? Can this be replaced with a Lisp function?
-   It is used in minibuf.c.  Can we get rid of that?
-   Yes.  All uses in minibuf.c are gone, and parallels to these
-   functions have been defined in frame.el.  */
-
-DEFUN ("frame-configuration", Fframe_configuration, Sframe_configuration,
-       0, 0, 0,
-  "Return object describing current frame configuration.\n\
-The frame configuration is the current mouse position and selected frame.\n\
-This object can be given to `restore-frame-configuration'\n\
-to restore this frame configuration.")
-  ()
-{
-  Lisp_Object c, time;
-  
-  c = Fmake_vector (make_number(4), Qnil);
-  XVECTOR (c)->contents[0] = Fselected_frame();
-  if (mouse_position_hook)
-    (*mouse_position_hook) (&XVECTOR (c)->contents[1]
-                           &XVECTOR (c)->contents[2],
-                           &XVECTOR (c)->contents[3],
-                           &time);
-  return c;
-}
-
-DEFUN ("restore-frame-configuration", Frestore_frame_configuration,
-       Srestore_frame_configuration,
-       1, 1, 0,
-  "Restores frame configuration CONFIGURATION.")
-  (config)
-  Lisp_Object config;
-{
-  Lisp_Object x_pos, y_pos, frame;
-
-  CHECK_VECTOR (config, 0);
-  if (XVECTOR (config)->size != 3)
-    {
-      error ("Wrong size vector passed to restore-frame-configuration");
-    }
-  frame = XVECTOR (config)->contents[0];
-  CHECK_LIVE_FRAME (frame, 0);
-
-  Fselect_frame (frame, Qnil);
-
-#if 0
-  /* This seems to interfere with the frame selection mechanism. jla */
-  x_pos = XVECTOR (config)->contents[2];
-  y_pos = XVECTOR (config)->contents[3];
-  set_mouse_position (frame, XINT (x_pos), XINT (y_pos));
-#endif
-
-  return frame;
-}    
-#endif
-\f
 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
-       0, 1, 0,
+       0, 1, "",
   "Make the frame FRAME visible (assuming it is an X-window).\n\
 Also raises the frame so that nothing obscures it.\n\
 If omitted, FRAME defaults to the currently selected frame.")
@@ -868,6 +824,18 @@ If omitted, FRAME defaults to the currently selected frame.")
 
   CHECK_LIVE_FRAME (frame, 0);
 
+  /* Don't let the frame remain selected.  */
+  if (XFRAME (frame) == selected_frame)
+    Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
+
+  /* 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,
+                         XWINDOW (minibuf_window)->buffer);
+      minibuf_window = selected_frame->minibuffer_window;
+    }
+
   /* I think this should be done with a hook.  */
 #ifdef HAVE_X_WINDOWS
   if (FRAME_X_P (XFRAME (frame)))
@@ -889,6 +857,18 @@ If omitted, FRAME defaults to the currently selected frame.")
   
   CHECK_LIVE_FRAME (frame, 0);
 
+  /* Don't let the frame remain selected.  */
+  if (XFRAME (frame) == selected_frame)
+    Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
+
+  /* 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,
+                         XWINDOW (minibuf_window)->buffer);
+      minibuf_window = selected_frame->minibuffer_window;
+    }
+
   /* I think this should be done with a hook.  */
 #ifdef HAVE_X_WINDOWS
   if (FRAME_X_P (XFRAME (frame)))
@@ -939,7 +919,7 @@ DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
 }
 
 
-DEFUN ("frame-to-front", Fframe_to_front, Sframe_to_front, 1, 1, 0,
+DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 1, 1, 0,
   "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
 If FRAME is invisible, make it visible.\n\
 If Emacs is displaying on an ordinary terminal or some other device which\n\
@@ -955,7 +935,8 @@ doesn't support multiple overlapping frames, this function does nothing.")
   return Qnil;
 }
 
-DEFUN ("frame-to-back", Fframe_to_back, Sframe_to_back, 1, 1, 0,
+/* Should we have a corresponding function called Flower_Power?  */
+DEFUN ("lower-frame", Flower_frame, Slower_frame, 1, 1, 0,
   "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
 If Emacs is displaying on an ordinary terminal or some other device which\n\
 doesn't support multiple overlapping frames, this function does nothing.")
@@ -999,13 +980,23 @@ The redirection lasts until `redirect-frame-focus' is called to change it.")
   (frame, focus_frame)
     Lisp_Object frame, focus_frame;
 {
-  CHECK_LIVE_FRAME (frame, 0);
+  /* Note that we don't check for a live frame here.  It's reasonable
+     to redirect the focus of a frame you're about to delete, if you
+     know what other frame should receive those keystrokes.  */
+  CHECK_FRAME (frame, 0);
 
   if (! NILP (focus_frame))
     CHECK_LIVE_FRAME (focus_frame, 1);
 
   XFRAME (frame)->focus_frame = focus_frame;
 
+  /* I think this should be done with a hook.  */
+#ifdef HAVE_X_WINDOWS
+  if (!NILP (focus_frame) && ! EQ (focus_frame, frame)
+      && FRAME_X_P (XFRAME (focus_frame)))
+    Ffocus_frame (focus_frame);
+#endif
+
   if (frame_rehighlight_hook)
     (*frame_rehighlight_hook) ();
   
@@ -1074,7 +1065,7 @@ store_frame_param (f, prop, 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.");
+       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;
@@ -1113,6 +1104,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, (f->no_split ? Qt : Qnil));
+  store_in_alist (&alist, Qmenu_bar_lines, (FRAME_MENU_BAR_LINES (f)));
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_X_WINDOWS
@@ -1162,47 +1154,113 @@ The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
   return Qnil;
 }
 \f
-
-#if 0
-/* This function isn't useful enough by itself to include; we need to
-   add functions to allow the user to find the size of a font before
-   this is actually useful.  */
-
-DEFUN ("frame-pixel-size", Fframe_pixel_size, 
-       Sframe_pixel_size, 1, 1, 0,
-  "Return a cons (width . height) of FRAME's size in pixels.")
+DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
+  0, 1, 0,
+  "Height in pixels of a line in the font in frame FRAME.\n\
+If FRAME is omitted, the selected frame is used.\n\
+For a terminal frame, the value is always 1.")
   (frame)
      Lisp_Object frame;
 {
-  register struct frame *f;
-  int width, height;
+  struct frame *f;
 
-  CHECK_LIVE_FRAME (frame, 0);
-  f = XFRAME (frame);
-  
-  return Fcons (make_number (x_pixel_width (f)),
-               make_number (x_pixel_height (f)));
-}
+  if (NILP (frame))
+    f = selected_frame;
+  else
+    {
+      CHECK_FRAME (frame, 0);
+      f = XFRAME (frame);
+    }
+
+#ifdef HAVE_X_WINDOWS
+  if (FRAME_X_P (f))
+    return make_number (x_char_height (f));
+  else
 #endif
+    return make_number (1);
+}
 
-#if 0
-/* These functions have no C callers, and can be written nicely in lisp.  */
 
-DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 0, 0,
-  "Return number of lines available for display on selected frame.")
-  ()
+DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
+  0, 1, 0,
+  "Width in pixels of characters in the font in frame FRAME.\n\
+If FRAME is omitted, the selected frame is used.\n\
+The width is the same for all characters, because\n\
+currently Emacs supports only fixed-width fonts.\n\
+For a terminal screen, the value is always 1.")
+  (frame)
+     Lisp_Object frame;
 {
-  return make_number (FRAME_HEIGHT (selected_frame));
+  struct frame *f;
+
+  if (NILP (frame))
+    f = selected_frame;
+  else
+    {
+      CHECK_FRAME (frame, 0);
+      f = XFRAME (frame);
+    }
+
+#ifdef HAVE_X_WINDOWS
+  if (FRAME_X_P (f))
+    return make_number (x_char_width (f));
+  else
+#endif
+    return make_number (1);
 }
 
-DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 0, 0,
-  "Return number of columns available for display on selected frame.")
-  ()
+DEFUN ("frame-pixel-height", Fframe_pixel_height, 
+       Sframe_pixel_height, 0, 1, 0,
+  "Return a FRAME's height in pixels.\n\
+For a terminal frame, the result really gives the height in characters.\n\
+If FRAME is omitted, the selected frame is used.")
+  (frame)
+     Lisp_Object frame;
 {
-  return make_number (FRAME_WIDTH (selected_frame));
-}
+  struct frame *f;
+
+  if (NILP (frame))
+    f = selected_frame;
+  else
+    {
+      CHECK_FRAME (frame, 0);
+      f = XFRAME (frame);
+    }
+
+#ifdef HAVE_X_WINDOWS
+  if (FRAME_X_P (f))
+    return make_number (x_pixel_height (f));
+  else
 #endif
+    return make_number (FRAME_HEIGHT (f));
+}
 
+DEFUN ("frame-pixel-width", Fframe_pixel_width, 
+       Sframe_pixel_width, 0, 1, 0,
+  "Return FRAME's width in pixels.\n\
+For a terminal frame, the result really gives the width in characters.\n\
+If FRAME is omitted, the selected frame is used.")
+  (frame)
+     Lisp_Object frame;
+{
+  struct frame *f;
+
+  if (NILP (frame))
+    f = selected_frame;
+  else
+    {
+      CHECK_FRAME (frame, 0);
+      f = XFRAME (frame);
+    }
+
+#ifdef HAVE_X_WINDOWS
+  if (FRAME_X_P (f))
+    return make_number (x_pixel_width (f));
+  else
+#endif
+    return make_number (FRAME_WIDTH (f));
+}
+\f
 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
   "Specify that the frame FRAME has LINES lines.\n\
 Optional third arg non-nil means that redisplay should use LINES lines\n\
@@ -1317,46 +1375,6 @@ off the screen.")
   return Qt;
 }
 
-\f
-#ifndef HAVE_X11
-DEFUN ("rubber-band-rectangle", Frubber_band_rectangle, Srubber_band_rectangle,
-       3, 3, "",
-  "Ask user to specify a window position and size on FRAME with the mouse.\n\
-Arguments are FRAME, NAME and GEO.  NAME is a name to be displayed as\n\
-the purpose of this rectangle.  GEO is an X-windows size spec that can\n\
-specify defaults for some sizes/positions.  If GEO specifies everything,\n\
-the mouse is not used.\n\
-Returns a list of five values: (FRAME LEFT TOP WIDTH HEIGHT).")
-  (frame, name, geo)
-     Lisp_Object frame;
-     Lisp_Object name;
-     Lisp_Object geo;
-{
-  int vals[4];
-  Lisp_Object nums[4];
-  int i;
-
-  CHECK_FRAME (frame, 0);
-  CHECK_STRING (name, 1);
-  CHECK_STRING (geo, 2);
-
-  switch (XFRAME (frame)->output_method)
-    {
-    case output_x_window:
-      x_rubber_band (XFRAME (frame), &vals[0], &vals[1], &vals[2], &vals[3],
-                    XSTRING (geo)->data, XSTRING (name)->data);
-      break;
-
-    default:
-      return Qnil;
-    }
-
-  for (i = 0; i < 4; i++)
-    XFASTINT (nums[i]) = vals[i];
-  return Fcons (frame, Flist (4, nums));
-  return Qnil;
-}
-#endif /* not HAVE_X11 */
 \f
 choose_minibuf_frame ()
 {
@@ -1403,6 +1421,8 @@ syms_of_frame ()
   staticpro (&Qwidth);
   Qx = intern ("x");
   staticpro (&Qx);
+  Qmenu_bar_lines = intern ("menu-bar-lines");
+  staticpro (&Qmenu_bar_lines);
 
   staticpro (&Vframe_list);
 
@@ -1440,6 +1460,7 @@ For values specific to the separate minibuffer frame, see\n\
 
   defsubr (&Sframep);
   defsubr (&Sframe_live_p);
+  defsubr (&Shandle_switch_frame);
   defsubr (&Sselect_frame);
   defsubr (&Sselected_frame);
   defsubr (&Swindow_frame);
@@ -1459,31 +1480,27 @@ For values specific to the separate minibuffer frame, see\n\
   defsubr (&Siconify_frame);
   defsubr (&Sframe_visible_p);
   defsubr (&Svisible_frame_list);
-  defsubr (&Sframe_to_front);
-  defsubr (&Sframe_to_back);
+  defsubr (&Sraise_frame);
+  defsubr (&Slower_frame);
   defsubr (&Sredirect_frame_focus);
   defsubr (&Sframe_focus);
   defsubr (&Sframe_parameters);
   defsubr (&Smodify_frame_parameters);
-#if 0
-  defsubr (&Sframe_pixel_size);
-  defsubr (&Sframe_height);
-  defsubr (&Sframe_width);
-#endif
+  defsubr (&Sframe_char_height);
+  defsubr (&Sframe_char_width);
+  defsubr (&Sframe_pixel_height);
+  defsubr (&Sframe_pixel_width);
   defsubr (&Sset_frame_height);
   defsubr (&Sset_frame_width);
   defsubr (&Sset_frame_size);
   defsubr (&Sset_frame_position);
-#ifndef HAVE_X11
-  defsubr (&Srubber_band_rectangle);
-#endif /* HAVE_X11 */
 }
 
 keys_of_frame ()
 {
-  initial_define_lispy_key (global_map, "switch-frame", "select-frame");
+  initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
 }
-
+\f
 #else /* not MULTI_FRAME */
 
 /* If we're not using multi-frame stuff, we still need to provide some
@@ -1500,6 +1517,16 @@ DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
   XFASTINT (tem) = 0;
   return tem;
 }
+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\
+Also see `live-frame-p'.")
+  (object)
+     Lisp_Object object;
+{
+  return Qnil;
+}
 
 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
   "Specify that the frame FRAME has LINES lines.\n\
@@ -1540,20 +1567,71 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
   return Qnil;
 }
 
-DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 0, 0,
-  "Return number of lines available for display on selected frame.")
-  ()
+DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 1, 0,
+  "Return number of lines available for display on FRAME.\n\
+If FRAME is omitted, describe the currently selected frame.")
+  (frame)
+    Lisp_Object frame;
 {
   return make_number (FRAME_HEIGHT (selected_frame));
 }
 
-DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 0, 0,
-  "Return number of columns available for display on selected frame.")
-  ()
+DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 1, 0,
+  "Return number of columns available for display on FRAME.\n\
+If FRAME is omitted, describe the currently selected frame.")
+  (frame)
+    Lisp_Object frame;
 {
   return make_number (FRAME_WIDTH (selected_frame));
 }
 
+DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
+  0, 1, 0,
+  "Height in pixels of a line in the font in frame FRAME.\n\
+If FRAME is omitted, the selected frame is used.\n\
+For a terminal frame, the value is always 1.")
+  (frame)
+     Lisp_Object frame;
+{
+  return make_number (1);
+}
+
+
+DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
+  0, 1, 0,
+  "Width in pixels of characters in the font in frame FRAME.\n\
+If FRAME is omitted, the selected frame is used.\n\
+The width is the same for all characters, because\n\
+currently Emacs supports only fixed-width fonts.\n\
+For a terminal screen, the value is always 1.")
+  (frame)
+     Lisp_Object frame;
+{
+  return make_number (1);
+}
+
+DEFUN ("frame-pixel-height", Fframe_pixel_height, 
+       Sframe_pixel_height, 0, 1, 0,
+  "Return FRAME's height in pixels.\n\
+For a terminal frame, the result really gives the height in characters.\n\
+If FRAME is omitted, the selected frame is used.")
+  (frame)
+     Lisp_Object frame;
+{
+  return make_number (FRAME_HEIGHT (f));
+}
+
+DEFUN ("frame-pixel-width", Fframe_pixel_width, 
+       Sframe_pixel_width, 0, 1, 0,
+  "Return FRAME's width in pixels.\n\
+For a terminal frame, the result really gives the width in characters.\n\
+If FRAME is omitted, the selected frame is used.")
+  (frame)
+     Lisp_Object frame;
+{
+  return make_number (FRAME_WIDTH (f));
+}
+
 /* These are for backward compatibility with Emacs 18.  */
 
 DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
@@ -1584,6 +1662,12 @@ but that the idea of the actual width of the screen should not be changed.")
 
 syms_of_frame ()
 {
+  defsubr (&Sselected_frame);
+  defsubr (&Sframep);
+  defsubr (&Sframe_char_height);
+  defsubr (&Sframe_char_width);
+  defsubr (&Sframe_pixel_height);
+  defsubr (&Sframe_pixel_width);
   defsubr (&Sset_frame_height);
   defsubr (&Sset_frame_width);
   defsubr (&Sset_frame_size);