This commit was generated by cvs2svn to compensate for changes in r2827,
[chise/xemacs-chise.git.1] / src / frame.c
index dbbaf63..5891e24 100644 (file)
@@ -34,12 +34,14 @@ Boston, MA 02111-1307, USA.  */
 #include "faces.h"
 #include "frame.h"
 #include "glyphs.h"
-#include "gutter.h"
 #include "menubar.h"
 #include "redisplay.h"
 #include "scrollbar.h"
 #include "window.h"
 
+#include <errno.h>
+#include "sysdep.h"
+
 Lisp_Object Vselect_frame_hook, Qselect_frame_hook;
 Lisp_Object Vdeselect_frame_hook, Qdeselect_frame_hook;
 Lisp_Object Vcreate_frame_hook, Qcreate_frame_hook;
@@ -86,6 +88,7 @@ Lisp_Object Qborder_color;
 Lisp_Object Qborder_width;
 
 Lisp_Object Qframep, Qframe_live_p;
+Lisp_Object Qframe_x_p, Qframe_tty_p;
 Lisp_Object Qdelete_frame;
 
 Lisp_Object Qframe_title_format, Vframe_title_format;
@@ -102,7 +105,7 @@ Lisp_Object Qvisible, Qiconic, Qinvisible, Qvisible_iconic, Qinvisible_iconic;
 Lisp_Object Qnomini, Qvisible_nomini, Qiconic_nomini, Qinvisible_nomini;
 Lisp_Object Qvisible_iconic_nomini, Qinvisible_iconic_nomini;
 
-Lisp_Object Qset_specifier, Qset_face_property;
+Lisp_Object Qset_specifier, Qset_glyph_image, Qset_face_property;
 Lisp_Object Qface_property_instance;
 
 Lisp_Object Qframe_property_alias;
@@ -116,22 +119,20 @@ Lisp_Object Vframe_being_created;
 Lisp_Object Qframe_being_created;
 
 static void store_minibuf_frame_prop (struct frame *f, Lisp_Object val);
-static struct display_line title_string_display_line;
-/* Used by generate_title_string. Global because they get used so much that
-   the dynamic allocation time adds up. */
-static Emchar_dynarr *title_string_emchar_dynarr;
+
+EXFUN (Fset_frame_properties, 2);
 
 \f
 static Lisp_Object
-mark_frame (Lisp_Object obj)
+mark_frame (Lisp_Object obj, void (*markobj) (Lisp_Object))
 {
   struct frame *f = XFRAME (obj);
 
-#define MARKED_SLOT(x) mark_object (f->x)
+#define MARKED_SLOT(x) ((markobj) (f->x));
 #include "frameslots.h"
 
   if (FRAME_LIVE_P (f)) /* device is nil for a dead frame */
-    MAYBE_FRAMEMETH (f, mark_frame, (f));
+    MAYBE_FRAMEMETH (f, mark_frame, (f, markobj));
 
   return Qnil;
 }
@@ -155,13 +156,13 @@ print_frame (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
 }
 
 DEFINE_LRECORD_IMPLEMENTATION ("frame", frame,
-                               mark_frame, print_frame, 0, 0, 0, 0,
+                               mark_frame, print_frame, 0, 0, 0,
                               struct frame);
 \f
 static void
 nuke_all_frame_slots (struct frame *f)
 {
-#define MARKED_SLOT(x) f->x = Qnil
+#define MARKED_SLOT(x) f->x = Qnil;
 #include "frameslots.h"
 }
 
@@ -175,7 +176,7 @@ allocate_frame_core (Lisp_Object device)
   /* This function can GC */
   Lisp_Object frame;
   Lisp_Object root_window;
-  struct frame *f = alloc_lcrecord_type (struct frame, &lrecord_frame);
+  struct frame *f = alloc_lcrecord_type (struct frame, lrecord_frame);
 
   zero_lcrecord (f);
   nuke_all_frame_slots (f);
@@ -189,28 +190,22 @@ allocate_frame_core (Lisp_Object device)
   XWINDOW (root_window)->frame = frame;
 
   /* 10 is arbitrary,
-     Just so that there is "something there."
+     just so that there is "something there."
      Correct size will be set up later with change_frame_size.  */
 
-  f->width  = 10;
+  f->width = 10;
   f->height = 10;
 
   XWINDOW (root_window)->pixel_width = 10;
   XWINDOW (root_window)->pixel_height = 9;
 
+  /* The size of the minibuffer window is now set in x_create_frame
+     in xfns.c. */
+
   f->root_window = root_window;
   f->selected_window = root_window;
   f->last_nonminibuf_window = root_window;
 
-  /* cache of subwindows visible on frame */
-  f->subwindow_instance_cache    = make_weak_list (WEAK_LIST_SIMPLE);
-
-  /* associated exposure ignore list */
-  f->subwindow_exposures = 0;
-  f->subwindow_exposures_tail = 0;
-
-  FRAME_SET_PAGENUMBER (f, 1);
-
   /* Choose a buffer for the frame's root window.  */
   XWINDOW (root_window)->buffer = Qt;
   {
@@ -221,7 +216,7 @@ allocate_frame_core (Lisp_Object device)
        a space), try to find another one.  */
     if (string_char (XSTRING (Fbuffer_name (buf)), 0) == ' ')
       buf = Fother_buffer (buf, Qnil, Qnil);
-    Fset_window_buffer (root_window, buf, Qnil);
+    Fset_window_buffer (root_window, buf);
   }
 
   return f;
@@ -244,7 +239,7 @@ setup_normal_frame (struct frame *f)
   f->has_minibuffer = 1;
 
   XWINDOW (mini_window)->buffer = Qt;
-  Fset_window_buffer (mini_window, Vminibuffer_zero, Qt);
+  Fset_window_buffer (mini_window, Vminibuffer_zero);
 }
 
 /* Make a frame using a separate minibuffer window on another frame.
@@ -265,9 +260,7 @@ setup_frame_without_minibuffer (struct frame *f, Lisp_Object mini_window)
              FRAME_CONSOLE (XFRAME (XWINDOW (mini_window)->frame))))
     error ("frame and minibuffer must be on the same console");
 
-  /* Do not create a default minibuffer frame on printer devices.  */
-  if (NILP (mini_window)
-      && DEVICE_DISPLAY_P (XDEVICE (FRAME_DEVICE (f))))
+  if (NILP (mini_window))
     {
       struct console *con = XCONSOLE (FRAME_CONSOLE (f));
       /* Use default-minibuffer-frame if possible.  */
@@ -282,13 +275,8 @@ setup_frame_without_minibuffer (struct frame *f, Lisp_Object mini_window)
     }
 
   /* Install the chosen minibuffer window, with proper buffer.  */
-  if (!NILP (mini_window))
-    {
-      store_minibuf_frame_prop (f, mini_window);
-      Fset_window_buffer (mini_window, Vminibuffer_zero, Qt);
-    }
-  else
-    f->minibuffer_window = Qnil;
+  store_minibuf_frame_prop (f, mini_window);
+  Fset_window_buffer (mini_window, Vminibuffer_zero);
 }
 
 /* Make a frame containing only a minibuffer window.  */
@@ -318,7 +306,7 @@ setup_minibuffer_frame (struct frame *f)
 
   /* Put the proper buffer in that window.  */
 
-  Fset_window_buffer (mini_window, Vminibuffer_zero, Qt);
+  Fset_window_buffer (mini_window, Vminibuffer_zero);
 }
 
 static Lisp_Object
@@ -382,7 +370,7 @@ See `set-frame-properties', `default-x-frame-plist', and
   else
     name = build_string ("emacs");
 
-  if (!NILP (Fstring_match (make_string ((const Bufbyte *) "\\.", 2), name,
+  if (!NILP (Fstring_match (make_string ((CONST Bufbyte *) "\\.", 2), name,
                            Qnil, Qnil)))
     signal_simple_error (". not allowed in frame names", name);
 
@@ -419,7 +407,7 @@ See `set-frame-properties', `default-x-frame-plist', and
 
   update_frame_window_mirror (f);
 
-  if (initialized && !DEVICE_STREAM_P (d))
+  if (initialized)
     {
       if (!NILP (f->minibuffer_window))
         reset_face_cachels (XWINDOW (f->minibuffer_window));
@@ -466,9 +454,9 @@ See `set-frame-properties', `default-x-frame-plist', and
         things. */
       init_frame_toolbars (f);
 #endif
+
       reset_face_cachels (XWINDOW (FRAME_SELECTED_WINDOW (f)));
       reset_glyph_cachels (XWINDOW (FRAME_SELECTED_WINDOW (f)));
-
       change_frame_size (f, f->height, f->width, 0);
     }
 
@@ -501,18 +489,6 @@ See `set-frame-properties', `default-x-frame-plist', and
   MAYBE_FRAMEMETH (f, after_init_frame, (f, first_frame_on_device,
                                         first_frame_on_console));
 
-  if (!DEVICE_STREAM_P (d))
-    {
-      /* Now initialise the gutters. This won't change the frame size,
-         but is needed as input to the layout that change_frame_size
-         will eventually do. Unfortunately gutter sizing code relies
-         on the frame in question being visible so we can't do this
-         earlier. */
-      init_frame_gutters (f);
-
-      change_frame_size (f, f->height, f->width, 0);
-    }
-
   if (first_frame_on_device)
     {
       if (first_frame_on_console)
@@ -604,7 +580,7 @@ unhold_frame_size_changes (void)
 void
 invalidate_vertical_divider_cache_in_frame (struct frame *f)
 {
-  /* Invalidate cached value of needs_vertical_divider_p in
+  /* Invalidate cached value of needs_vertical_divider_p in 
      every and all windows */
   map_windows (f, invalidate_vertical_divider_cache_in_window, 0);
 }
@@ -913,13 +889,10 @@ set_frame_selected_window (struct frame *f, Lisp_Object window)
   f->selected_window = window;
   if (!MINI_WINDOW_P (XWINDOW (window)) || FRAME_MINIBUF_ONLY_P (f))
     {
-      if (!EQ (f->last_nonminibuf_window, window))
-       {
 #ifdef HAVE_TOOLBARS
-         MARK_TOOLBAR_CHANGED;
-#endif
-         MARK_GUTTER_CHANGED;
-       }
+      if (!EQ (f->last_nonminibuf_window, window))
+       MARK_TOOLBAR_CHANGED;
+#endif      
       f->last_nonminibuf_window = window;
     }
 }
@@ -1033,10 +1006,13 @@ frame_matches_frametype (Lisp_Object frame, Lisp_Object type)
 }
 
 int
-device_matches_console_spec (Lisp_Object device, Lisp_Object console)
+device_matches_console_spec (Lisp_Object frame, Lisp_Object device,
+                            Lisp_Object console)
 {
   if (EQ (console, Qwindow_system))
     return DEVICE_WIN_P (XDEVICE (device));
+  if (NILP (console))
+    console = (DEVICE_CONSOLE (XDEVICE (FRAME_DEVICE (XFRAME (frame)))));
   if (DEVICEP (console))
     return EQ (device, console);
   if (CONSOLEP (console))
@@ -1050,60 +1026,78 @@ device_matches_console_spec (Lisp_Object device, Lisp_Object console)
    FRAMETYPE and CONSOLE control which frames and devices
    are considered; see `next-frame'. */
 
-Lisp_Object
-next_frame (Lisp_Object frame, Lisp_Object frametype, Lisp_Object console)
+static Lisp_Object
+next_frame_internal (Lisp_Object frame, Lisp_Object frametype,
+                    Lisp_Object console, int called_from_delete_device)
 {
-  Lisp_Object first = Qnil;
-  Lisp_Object devcons, concons;
   int passed = 0;
+  int started_over = 0;
 
+  /* If this frame is dead, it won't be in frame_list, and we'll loop
+     forever.  Forestall that.  */
   CHECK_LIVE_FRAME (frame);
 
-  DEVICE_LOOP_NO_BREAK (devcons, concons)
+  while (1)
     {
-      Lisp_Object device = XCAR (devcons);
-      Lisp_Object frmcons;
+      Lisp_Object devcons, concons;
 
-      if (!device_matches_console_spec (device, console))
+      DEVICE_LOOP_NO_BREAK (devcons, concons)
        {
-         if (EQ (device, FRAME_DEVICE (XFRAME (frame))))
-           passed = 1;
-         continue;
-       }
+         Lisp_Object device = XCAR (devcons);
+         Lisp_Object frmcons;
 
-      DEVICE_FRAME_LOOP (frmcons, XDEVICE (device))
-       {
-         Lisp_Object f = XCAR (frmcons);
+         if (!device_matches_console_spec (frame, device, console))
+           continue;
 
-         if (passed)
+         DEVICE_FRAME_LOOP (frmcons, XDEVICE (device))
            {
-             if (frame_matches_frametype (f, frametype))
-               return f;
-           }
-         else
-           {
-             if (EQ (frame, f))
+             Lisp_Object f = XCAR (frmcons);
+             if (passed)
                {
-                 passed = 1;
-               }
-             else
-               {
-                 if (NILP (first) && frame_matches_frametype (f, frametype))
-                   first = f;
+                 /* #### Doing this here is bad and is now
+                     unnecessary.  The real bug was that f->iconified
+                     was never, ever updated unless a user explicitly
+                     called frame-iconified-p.  That has now been
+                     fixed.  With this change removed all of the other
+                     changes made to support this routine having the
+                     called_from_delete_device arg could be removed.
+                     But it is too close to release to do that now. */
+#if 0
+                 /* Make sure the visibility and iconified flags are
+                     up-to-date unless we're being deleted. */
+                 if (!called_from_delete_device)
+                   {
+                     Fframe_iconified_p (f);
+                     Fframe_visible_p (f);
+                   }
+#endif
+
+                 /* Decide whether this frame is eligible to be returned.  */
+
+                 /* If we've looped all the way around without finding any
+                    eligible frames, return the original frame.  */
+                 if (EQ (f, frame))
+                   return f;
+
+                 if (frame_matches_frametype (f, frametype))
+                   return f;
                }
+
+             if (EQ (frame, f))
+               passed++;
            }
        }
+      /* We hit the end of the list, and need to start over again. */
+      if (started_over)
+       return Qnil;
+      started_over++;
     }
+}
 
-  if (NILP (first))
-    /* We went through the whole frame list without finding a single
-       acceptable frame.  Return the original frame.  */
-    return frame;
-  else
-    /* There were no acceptable frames in the list after FRAME; otherwise,
-       we would have returned directly from the loop.  Since FIRST is the last
-       acceptable frame in the list, return it.  */
-    return first;
+Lisp_Object
+next_frame (Lisp_Object frame, Lisp_Object frametype, Lisp_Object console)
+{
+  return next_frame_internal (frame, frametype, console, 0);
 }
 
 /* Return the previous frame in the frame list before FRAME.
@@ -1111,52 +1105,50 @@ next_frame (Lisp_Object frame, Lisp_Object frametype, Lisp_Object console)
    are considered; see `next-frame'. */
 
 Lisp_Object
-previous_frame (Lisp_Object frame, Lisp_Object frametype, Lisp_Object console)
+prev_frame (Lisp_Object frame, Lisp_Object frametype, Lisp_Object console)
 {
   Lisp_Object devcons, concons;
-  Lisp_Object last = Qnil;
+  Lisp_Object prev;
 
+  /* If this frame is dead, it won't be in frame_list, and we'll loop
+     forever.  Forestall that.  */
   CHECK_LIVE_FRAME (frame);
 
+  prev = Qnil;
   DEVICE_LOOP_NO_BREAK (devcons, concons)
     {
       Lisp_Object device = XCAR (devcons);
       Lisp_Object frmcons;
 
-      if (!device_matches_console_spec (device, console))
-       {
-         if (EQ (device, FRAME_DEVICE (XFRAME (frame)))
-             && !NILP (last))
-           return last;
-         continue;
-       }
+      if (!device_matches_console_spec (frame, device, console))
+       continue;
 
       DEVICE_FRAME_LOOP (frmcons, XDEVICE (device))
        {
          Lisp_Object f = XCAR (frmcons);
 
-         if (EQ (frame, f))
-           {
-             if (!NILP (last))
-               return last;
-           }
-         else
-           {
-             if (frame_matches_frametype (f, frametype))
-               last = f;
-           }
+         if (EQ (frame, f) && !NILP (prev))
+           return prev;
+
+         /* Decide whether this frame is eligible to be returned,
+            according to frametype.  */
+
+         if (frame_matches_frametype (f, frametype))
+           prev = f;
+
        }
     }
 
-  if (NILP (last))
+  /* We've scanned the entire list.  */
+  if (NILP (prev))
     /* We went through the whole frame list without finding a single
        acceptable frame.  Return the original frame.  */
     return frame;
   else
     /* There were no acceptable frames in the list before FRAME; otherwise,
-       we would have returned directly from the loop.  Since LAST is the last
+       we would have returned directly from the loop.  Since PREV is the last
        acceptable frame in the list, return it.  */
-    return last;
+    return prev;
 }
 
 DEFUN ("next-frame", Fnext_frame, 0, 3, 0, /*
@@ -1221,7 +1213,7 @@ arguments.
 {
   XSETFRAME (frame, decode_frame (frame));
 
-  return previous_frame (frame, frametype, console);
+  return prev_frame (frame, frametype, console);
 }
 
 /* Return any frame for which PREDICATE is non-zero, or return Qnil
@@ -1253,15 +1245,23 @@ find_some_frame (int (*predicate) (Lisp_Object, void *),
    (Exception: if F is a stream frame, it's OK to delete if
    any other frames exist.) */
 
-int
-other_visible_frames (struct frame *f)
+static int
+other_visible_frames_internal (struct frame *f, int called_from_delete_device)
 {
   Lisp_Object frame;
 
   XSETFRAME (frame, f);
   if (FRAME_STREAM_P (f))
-    return !EQ (frame, next_frame (frame, Qt, Qt));
-  return !EQ (frame, next_frame (frame, Qvisible_iconic_nomini, Qt));
+    return !EQ (frame, next_frame_internal (frame, Qt, Qt,
+                                           called_from_delete_device));
+  return !EQ (frame, next_frame_internal (frame, Qvisible_iconic_nomini, Qt,
+                                         called_from_delete_device));
+}
+
+int
+other_visible_frames (struct frame *f)
+{
+  return other_visible_frames_internal (f, 0);
 }
 
 /* Delete frame F.
@@ -1303,9 +1303,7 @@ delete_frame_internal (struct frame *f, int force,
   console = DEVICE_CONSOLE (d);
   con = XCONSOLE (console);
 
-  if (!called_from_delete_device &&
-      !(MAYBE_INT_DEVMETH (d, device_implementation_flags, ())
-       & XDEVIMPF_FRAMELESS_OK))
+  if (!called_from_delete_device)
     {
       /* If we're deleting the only non-minibuffer frame on the
         device, delete the device. */
@@ -1324,7 +1322,7 @@ delete_frame_internal (struct frame *f, int force,
      losing any way of communicating with the still running XEmacs process.
      So we put it back.  */
   if (!force && !allow_deletion_of_last_visible_frame &&
-      !other_visible_frames (f))
+      !other_visible_frames_internal (f, called_from_delete_device))
     error ("Attempt to delete the sole visible or iconified frame");
 
   /* Does this frame have a minibuffer, and is it the surrogate
@@ -1450,17 +1448,22 @@ delete_frame_internal (struct frame *f, int force,
 
       next = DEVMETH_OR_GIVEN (d, get_frame_parent, (f), Qnil);
       if (NILP (next) || EQ (next, frame) || ! FRAME_LIVE_P (XFRAME (next)))
-       next = next_frame (frame, Qvisible, device);
+       next = next_frame_internal (frame, Qvisible, device,
+                                   called_from_delete_device);
       if (NILP (next) || EQ (next, frame))
-       next = next_frame (frame, Qvisible, console);
+       next = next_frame_internal (frame, Qvisible, console,
+                                   called_from_delete_device);
       if (NILP (next) || EQ (next, frame))
-       next = next_frame (frame, Qvisible, Qt);
+       next = next_frame_internal (frame, Qvisible, Qt,
+                                   called_from_delete_device);
       if (NILP (next) || EQ (next, frame))
-       next = next_frame (frame, Qt, device);
+       next = next_frame_internal (frame, Qt, device,
+                                   called_from_delete_device);
       if (NILP (next) || EQ (next, frame))
-       next = next_frame (frame, Qt, console);
+       next = next_frame_internal (frame, Qt, console,
+                                   called_from_delete_device);
       if (NILP (next) || EQ (next, frame))
-       next = next_frame (frame, Qt, Qt);
+       next = next_frame_internal (frame, Qt, Qt, called_from_delete_device);
 
       /* if we haven't found another frame at this point
         then there aren't any. */
@@ -1482,9 +1485,11 @@ delete_frame_internal (struct frame *f, int force,
           */
          if (!EQ (device, FRAME_DEVICE(XFRAME(next))))
            {
-               Lisp_Object next_f = next_frame (frame, Qt, device);
+               Lisp_Object next_f =
+                   next_frame_internal (frame, Qt, device,
+                                        called_from_delete_device);
                if (NILP (next_f) || EQ (next_f, frame))
-                 set_device_selected_frame (d, Qnil);
+                 ;
                else
                  set_device_selected_frame (d, next_f);
            }
@@ -1499,7 +1504,7 @@ delete_frame_internal (struct frame *f, int force,
     {
       struct frame *sel_frame = selected_frame ();
       Fset_window_buffer (sel_frame->minibuffer_window,
-                         XWINDOW (minibuf_window)->buffer, Qt);
+                         XWINDOW (minibuf_window)->buffer);
       minibuf_window = sel_frame->minibuffer_window;
 
       /* If the dying minibuffer window was selected,
@@ -1519,13 +1524,6 @@ delete_frame_internal (struct frame *f, int force,
 #ifdef HAVE_TOOLBARS
   free_frame_toolbars (f);
 #endif
-  free_frame_gutters (f);
-  /* Unfortunately deleting the frame will also delete the parent of
-     all of the subwindow instances current on the frame. I think this
-     can lead to bad things when trying to finalize the
-     instances. Thus we loop over all instance caches calling the
-     finalize method for each instance. */
-  free_frame_subwindow_instances (f);
 
   /* This must be done before the window and window_mirror structures
      are freed.  The scrollbar information is attached to them. */
@@ -1536,9 +1534,6 @@ delete_frame_internal (struct frame *f, int force,
   delete_all_subwindows (XWINDOW (f->root_window));
   f->root_window = Qnil;
 
-  /* clear out the cached glyph information */
-  f->subwindow_instance_cache = Qnil;
-
   /* Remove the frame now from the list.  This way, any events generated
      on this frame by the maneuvers below will disperse themselves. */
 
@@ -1711,14 +1706,13 @@ mouse_pixel_position_1 (struct device *d, Lisp_Object *frame,
 
 DEFUN ("mouse-pixel-position", Fmouse_pixel_position, 0, 1, 0, /*
 Return a list (WINDOW X . Y) giving the current mouse window and position.
-The position is given in pixel units, where (0, 0) is the upper-left corner
-of the window.
+The position is given in pixel units, where (0, 0) is the upper-left corner.
 
 When the cursor is not over a window, the return value is a list (nil nil).
 
 DEVICE specifies the device on which to read the mouse position, and
 defaults to the selected device.  If the device is a mouseless terminal
-or XEmacs hasn't been programmed to read its mouse position, it returns
+or Emacs hasn't been programmed to read its mouse position, it returns
 the device's selected window for WINDOW and nil for X and Y.
 */
        (device))
@@ -1835,7 +1829,7 @@ Note also: Warping the mouse is contrary to the ICCCM, so be very sure
   struct window *w;
   int pix_x, pix_y;
 
-  CHECK_LIVE_WINDOW (window);
+  CHECK_WINDOW (window);
   CHECK_INT (x);
   CHECK_INT (y);
 
@@ -1859,7 +1853,7 @@ before calling this function on it, like this.
 {
   struct window *w;
 
-  CHECK_LIVE_WINDOW (window);
+  CHECK_WINDOW (window);
   CHECK_INT (x);
   CHECK_INT (y);
 
@@ -1908,7 +1902,7 @@ you may do so.
   if (EQ (f->minibuffer_window, minibuf_window))
     {
       Fset_window_buffer (sel_frame->minibuffer_window,
-                         XWINDOW (minibuf_window)->buffer, Qt);
+                         XWINDOW (minibuf_window)->buffer);
       minibuf_window = sel_frame->minibuffer_window;
     }
 
@@ -1934,7 +1928,7 @@ If omitted, FRAME defaults to the currently selected frame.
   if (EQ (f->minibuffer_window, minibuf_window))
     {
       Fset_window_buffer (sel_frame->minibuffer_window,
-                         XWINDOW (minibuf_window)->buffer, Qt);
+                         XWINDOW (minibuf_window)->buffer);
       minibuf_window = sel_frame->minibuffer_window;
     }
 
@@ -2064,61 +2058,8 @@ doesn't support multiple overlapping frames, this function does nothing.
   return Qnil;
 }
 
-\f
-DEFUN ("disable-frame", Fdisable_frame, 1, 1, 0, /*
-Disable frame FRAME, so that it cannot have the focus or receive user input.
-This is normally used during modal dialog boxes.
-WARNING: Be very careful not to wedge XEmacs!
-Use an `unwind-protect' that re-enables the frame to avoid this.
-*/
-       (frame))
-{
-  struct frame *f = decode_frame (frame);
-
-  f->disabled = 1;
-  MAYBE_FRAMEMETH (f, disable_frame, (f));
-  return Qnil;
-}
-
-DEFUN ("enable-frame", Fenable_frame, 1, 1, 0, /*
-Enable frame FRAME, so that it can have the focus and receive user input.
-Frames are normally enabled, unless explicitly disabled using `disable-frame'.
-*/
-       (frame))
-{
-  struct frame *f = decode_frame (frame);
-  f->disabled = 0;
-  MAYBE_FRAMEMETH (f, enable_frame, (f));
-  return Qnil;
-}
-
 /* Ben thinks there is no need for `redirect-frame-focus' or `frame-focus',
    crockish FSFmacs functions.  See summary on focus in event-stream.c. */
-\f
-DEFUN ("print-job-page-number", Fprint_job_page_number, 1, 1, 0, /*
-Return current page number for the print job FRAME.
-*/
-       (frame))
-{
-  CHECK_PRINTER_FRAME (frame);
-  return make_int (FRAME_PAGENUMBER (XFRAME (frame)));
-}
-
-DEFUN ("print-job-eject-page", Fprint_job_eject_page, 1, 1, 0, /*
-Eject page in the print job FRAME.
-*/
-       (frame))
-{
-  struct frame *f;
-
-  CHECK_PRINTER_FRAME (frame);
-  f = XFRAME (frame);
-  FRAMEMETH (f, eject_page, (f));
-  FRAME_SET_PAGENUMBER (f, 1 + FRAME_PAGENUMBER (f));
-  f->clear = 1;
-
-  return Qnil;
-}
 
 \f
 /***************************************************************************/
@@ -2174,7 +2115,7 @@ dissect_as_face_setting (Lisp_Object sym, Lisp_Object *face_out,
                         Lisp_Object *face_prop_out)
 {
   Lisp_Object list = Vbuilt_in_face_specifiers;
-  Lisp_String *s;
+  struct Lisp_String *s;
 
   if (!SYMBOLP (sym))
     return 0;
@@ -2184,7 +2125,7 @@ dissect_as_face_setting (Lisp_Object sym, Lisp_Object *face_out,
   while (!NILP (list))
     {
       Lisp_Object prop = Fcar (list);
-      Lisp_String *prop_name;
+      struct Lisp_String *prop_name;
 
       if (!SYMBOLP (prop))
        continue;
@@ -2262,9 +2203,8 @@ The following symbols etc. have predefined meanings:
 
  minibuffer    Gives the minibuffer behavior for this frame.  Either
                t (frame has its own minibuffer), `only' (frame is
-               a minibuffer-only frame), `none' (frame has no minibuffer)
-               or a window (frame uses that window, which is on another
-               frame, as the minibuffer).
+               a minibuffer-only frame), or a window (frame uses that
+               window, which is on another frame, as the minibuffer).
 
  unsplittable  If non-nil, frame cannot be split by `display-buffer'.
 
@@ -2278,13 +2218,7 @@ The following symbols etc. have predefined meanings:
  left-toolbar-visible-p, right-toolbar-visible-p, toolbar-buttons-captioned-p,
  top-toolbar-border-width, bottom-toolbar-border-width,
  left-toolbar-border-width, right-toolbar-border-width,
- modeline-shadow-thickness, has-modeline-p,
- default-gutter, top-gutter, bottom-gutter, left-gutter, right-gutter,
- default-gutter-height, default-gutter-width, top-gutter-height,
- bottom-gutter-height, left-gutter-width, right-gutter-width,
- default-gutter-visible-p, top-gutter-visible-p, bottom-gutter-visible-p,
- left-gutter-visible-p, right-gutter-visible-p, top-gutter-border-width,
- bottom-gutter-border-width, left-gutter-border-width, right-gutter-border-width,
+ modeline-shadow-thickness, has-modeline-p
                [Giving the name of any built-in specifier variable is
                equivalent to calling `set-specifier' on the specifier,
                with a locale of FRAME.  Giving the name to `frame-property'
@@ -2717,8 +2651,8 @@ frame_conversion_internal (struct frame *f, int pixel_to_char,
 
   window = FRAME_SELECTED_WINDOW (f);
 
-  egw = max (glyph_width (Vcontinuation_glyph, window),
-            glyph_width (Vtruncation_glyph, window));
+  egw = max (glyph_width (Vcontinuation_glyph, Vdefault_face, 0, window),
+            glyph_width (Vtruncation_glyph, Vdefault_face, 0, window));
   egw = max (egw, cpw);
   bdr = 2 * f->internal_border_width;
   obw = FRAME_SCROLLBAR_WIDTH (f) + FRAME_THEORETICAL_LEFT_TOOLBAR_WIDTH (f) +
@@ -2861,7 +2795,7 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth)
 
   /* when frame_conversion_internal() calculated the number of rows/cols
      in the frame, the theoretical toolbar sizes were subtracted out.
-     The calculations below adjust for real toolbar height/width in
+     The caluclations below adjust for real toolbar height/width in
      frame, which may be different from frame spec, taking the above
      fact into account */
   new_pixheight +=
@@ -2869,7 +2803,7 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth)
     + 2 * FRAME_THEORETICAL_TOP_TOOLBAR_BORDER_WIDTH (f)
     - FRAME_REAL_TOP_TOOLBAR_HEIGHT (f)
     - 2 * FRAME_REAL_TOP_TOOLBAR_BORDER_WIDTH (f);
-
+  
   new_pixheight +=
     + FRAME_THEORETICAL_BOTTOM_TOOLBAR_HEIGHT (f)
     + 2 * FRAME_THEORETICAL_BOTTOM_TOOLBAR_BORDER_WIDTH (f)
@@ -2881,21 +2815,21 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth)
     + 2 * FRAME_THEORETICAL_LEFT_TOOLBAR_BORDER_WIDTH (f)
     - FRAME_REAL_LEFT_TOOLBAR_WIDTH (f)
     - 2 * FRAME_REAL_LEFT_TOOLBAR_BORDER_WIDTH (f);
-
+  
   new_pixwidth +=
     + FRAME_THEORETICAL_RIGHT_TOOLBAR_WIDTH (f)
     + 2 * FRAME_THEORETICAL_RIGHT_TOOLBAR_BORDER_WIDTH (f)
     - FRAME_REAL_RIGHT_TOOLBAR_WIDTH (f)
     - 2 * FRAME_REAL_RIGHT_TOOLBAR_BORDER_WIDTH (f);
-
+  
   /* Adjust the width for the end glyph which may be a different width
      than the default character width. */
   {
     int adjustment, trunc_width, cont_width;
 
-    trunc_width = glyph_width (Vtruncation_glyph,
+    trunc_width = glyph_width (Vtruncation_glyph, Vdefault_face, 0,
                               FRAME_SELECTED_WINDOW (f));
-    cont_width = glyph_width (Vcontinuation_glyph,
+    cont_width = glyph_width (Vcontinuation_glyph, Vdefault_face, 0,
                              FRAME_SELECTED_WINDOW (f));
     adjustment = max (trunc_width, cont_width);
     adjustment = max (adjustment, font_width);
@@ -2909,14 +2843,7 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth)
 
   if (new_pixheight)
     {
-      /* Adjust for gutters here so that we always get set
-         properly. */
-      new_pixheight -=
-       (FRAME_TOP_GUTTER_BOUNDS (f)
-        + FRAME_BOTTOM_GUTTER_BOUNDS (f));
-
-      XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top
-       = FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f);
+      XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top = FRAME_TOP_BORDER_END (f);
 
       if (FRAME_HAS_MINIBUF_P (f)
          && ! FRAME_MINIBUF_ONLY_P (f))
@@ -2942,10 +2869,7 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth)
                                new_pixheight - minibuf_height, 0);
 
          XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_top =
-           FRAME_TOP_BORDER_END (f) +
-           FRAME_TOP_GUTTER_BOUNDS (f) +
-           FRAME_BOTTOM_GUTTER_BOUNDS (f) +
-           new_pixheight - minibuf_height;
+           new_pixheight - minibuf_height + FRAME_TOP_BORDER_END (f);
 
          set_window_pixheight (FRAME_MINIBUF_WINDOW (f), minibuf_height, 0);
        }
@@ -2960,20 +2884,13 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth)
 
   if (new_pixwidth)
     {
-      /* Adjust for gutters here so that we always get set
-         properly. */
-      new_pixwidth -=
-       (FRAME_LEFT_GUTTER_BOUNDS (f)
-        + FRAME_RIGHT_GUTTER_BOUNDS (f));
-
-      XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left =
-       FRAME_LEFT_BORDER_END (f) + FRAME_LEFT_GUTTER_BOUNDS (f);
+      XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left = FRAME_LEFT_BORDER_END (f);
       set_window_pixwidth (FRAME_ROOT_WINDOW (f), new_pixwidth, 0);
 
       if (FRAME_HAS_MINIBUF_P (f))
        {
          XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_left =
-           FRAME_LEFT_BORDER_END (f) + FRAME_LEFT_GUTTER_BOUNDS (f);
+           FRAME_LEFT_BORDER_END (f);
          set_window_pixwidth (FRAME_MINIBUF_WINDOW (f), new_pixwidth, 0);
        }
 
@@ -2990,9 +2907,8 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth)
       FRAME_CHARWIDTH (f) = FRAME_WIDTH (f);
       FRAME_CHARHEIGHT (f) = FRAME_HEIGHT (f);
     }
-
+      
   MARK_FRAME_TOOLBARS_CHANGED (f);
-  MARK_FRAME_GUTTERS_CHANGED (f);
   MARK_FRAME_CHANGED (f);
   f->echo_area_garbaged = 1;
 }
@@ -3028,37 +2944,6 @@ change_frame_size (struct frame *f, int newheight, int newwidth, int delay)
 }
 
 \f
-/* The caller is responsible for freeing the returned string. */
-static Bufbyte *
-generate_title_string (struct window *w, Lisp_Object format_str,
-                      face_index findex, int type)
-{
-  struct display_line *dl;
-  struct display_block *db;
-  int elt = 0;
-
-  dl = &title_string_display_line;
-  db = get_display_block_from_line (dl, TEXT);
-  Dynarr_reset (db->runes);
-
-  generate_formatted_string_db (format_str, Qnil, w, dl, db, findex, 0,
-                                -1, type);
-
-  Dynarr_reset (title_string_emchar_dynarr);
-  while (elt < Dynarr_length (db->runes))
-    {
-      if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR)
-       Dynarr_add (title_string_emchar_dynarr,
-                   Dynarr_atp (db->runes, elt)->object.chr.ch);
-      elt++;
-    }
-
-  return
-    convert_emchar_string_into_malloced_string
-    (Dynarr_atp (title_string_emchar_dynarr, 0),
-     Dynarr_length (title_string_emchar_dynarr), 0);
-}
-
 void
 update_frame_title (struct frame *f)
 {
@@ -3082,8 +2967,8 @@ update_frame_title (struct frame *f)
 
   if (HAS_FRAMEMETH_P (f, set_title_from_bufbyte))
     {
-      title = generate_title_string (w, title_format,
-                                    DEFAULT_INDEX, CURRENT_DISP);
+      title = generate_formatted_string (w, title_format, Qnil,
+                                         DEFAULT_INDEX, CURRENT_DISP);
       FRAMEMETH (f, set_title_from_bufbyte, (f, title));
     }
 
@@ -3094,8 +2979,8 @@ update_frame_title (struct frame *f)
          if (title)
            xfree (title);
 
-         title = generate_title_string (w, icon_format,
-                                        DEFAULT_INDEX, CURRENT_DISP);
+         title = generate_formatted_string (w, icon_format, Qnil,
+                                             DEFAULT_INDEX, CURRENT_DISP);
        }
       FRAMEMETH (f, set_icon_name_from_bufbyte, (f, title));
     }
@@ -3154,29 +3039,9 @@ icon_glyph_changed (Lisp_Object glyph, Lisp_Object property,
 }
 
 \f
-/***************************************************************************/
-/*                                                                        */
-/*                              initialization                             */
-/*                                                                        */
-/***************************************************************************/
-
-void
-init_frame (void)
-{
-#ifndef PDUMP
-  if (!initialized)
-#endif
-    {
-      title_string_emchar_dynarr = Dynarr_new (Emchar);
-      xzero (title_string_display_line);
-    }
-}
-
 void
 syms_of_frame (void)
 {
-  INIT_LRECORD_IMPLEMENTATION (frame);
-
   defsymbol (&Qdelete_frame_hook, "delete-frame-hook");
   defsymbol (&Qselect_frame_hook, "select-frame-hook");
   defsymbol (&Qdeselect_frame_hook, "deselect-frame-hook");
@@ -3189,6 +3054,8 @@ syms_of_frame (void)
 
   defsymbol (&Qframep, "framep");
   defsymbol (&Qframe_live_p, "frame-live-p");
+  defsymbol (&Qframe_x_p, "frame-x-p");
+  defsymbol (&Qframe_tty_p, "frame-tty-p");
   defsymbol (&Qdelete_frame, "delete-frame");
   defsymbol (&Qsynchronize_minibuffers, "synchronize-minibuffers");
   defsymbol (&Qbuffer_predicate, "buffer-predicate");
@@ -3237,6 +3104,7 @@ syms_of_frame (void)
   defsymbol (&Qborder_width, "border-width");
   /* Qwidth, Qheight, Qleft, Qtop in general.c */
   defsymbol (&Qset_specifier, "set-specifier");
+  defsymbol (&Qset_glyph_image, "set-glyph-image");
   defsymbol (&Qset_face_property, "set-face-property");
   defsymbol (&Qface_property_instance, "face-property-instance");
   defsymbol (&Qframe_property_alias, "frame-property-alias");
@@ -3274,8 +3142,6 @@ syms_of_frame (void)
   DEFSUBR (Fvisible_frame_list);
   DEFSUBR (Fraise_frame);
   DEFSUBR (Flower_frame);
-  DEFSUBR (Fdisable_frame);
-  DEFSUBR (Fenable_frame);
   DEFSUBR (Fframe_property);
   DEFSUBR (Fframe_properties);
   DEFSUBR (Fset_frame_properties);
@@ -3288,8 +3154,6 @@ syms_of_frame (void)
   DEFSUBR (Fset_frame_size);
   DEFSUBR (Fset_frame_position);
   DEFSUBR (Fset_frame_pointer);
-  DEFSUBR (Fprint_job_page_number);
-  DEFSUBR (Fprint_job_eject_page);
 }
 
 void
@@ -3403,34 +3267,27 @@ visible frames.
   Vsynchronize_minibuffers = Qnil;
 
   DEFVAR_LISP ("frame-title-format", &Vframe_title_format /*
-Controls the title of the window-system window of the selected frame.
+Controls the title of the X window corresponding to the selected frame.
 This is the same format as `modeline-format' with the exception that
 %- is ignored.
 */ );
-/* #### I would change this unilaterally but for the wrath of the Kyles
-of the world. */
-#ifdef WIN32_NATIVE
-  Vframe_title_format = build_string ("%b - XEmacs");
-#else
-  Vframe_title_format = build_string ("%S: %b");
-#endif
+  Vframe_title_format = Fpurecopy (build_string ("%S: %b"));
 
   DEFVAR_LISP ("frame-icon-title-format", &Vframe_icon_title_format /*
 Controls the title of the icon corresponding to the selected frame.
 See also the variable `frame-title-format'.
 */ );
-  Vframe_icon_title_format = build_string ("%b");
+  Vframe_icon_title_format = Fpurecopy (build_string ("%b"));
 
   DEFVAR_LISP ("default-frame-name", &Vdefault_frame_name /*
 The default name to assign to newly-created frames.
-This can be overridden by arguments to `make-frame'.  This must be a string.
-This is used primarily for picking up X resources, and is *not* the title
-of the frame. (See `frame-title-format'.)
+This can be overridden by arguments to `make-frame'.
+This must be a string.
 */ );
 #ifndef INFODOCK
-  Vdefault_frame_name = build_string ("emacs");
+  Vdefault_frame_name = Fpurecopy (build_string ("emacs"));
 #else
-  Vdefault_frame_name = build_string ("InfoDock");
+  Vdefault_frame_name = Fpurecopy (build_string ("InfoDock"));
 #endif
 
   DEFVAR_LISP ("default-frame-plist", &Vdefault_frame_plist /*