*** empty log message ***
[bpt/emacs.git] / src / dispnew.c
index fce73f1..06dcebc 100644 (file)
@@ -1,11 +1,11 @@
 /* Updating of data structures for redisplay.
-   Copyright (C) 1985, 1986, 1987, 1988, 1990 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1988, 1993 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 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -24,50 +24,22 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <stdio.h>
 #include <ctype.h>
 
-#ifdef NEED_TIME_H
-#include <time.h>
-#else /* not NEED_TIME_H */
-#ifdef HAVE_TIMEVAL
-#include <sys/time.h>
-#endif /* HAVE_TIMEVAL */
-#endif /* not NEED_TIME_H */
-
-#ifdef HAVE_TERMIO
-#include <termio.h>
-#ifdef TCOUTQ
-#undef TIOCOUTQ
-#define TIOCOUTQ TCOUTQ
-#endif /* TCOUTQ defined */
-#include <fcntl.h>
-#else
-#ifndef VMS
-#include <sys/ioctl.h>
-#endif /* not VMS */
-#endif /* not HAVE_TERMIO */
-
-/* Allow m- file to inhibit use of FIONREAD.  */
-#ifdef BROKEN_FIONREAD
-#undef FIONREAD
-#endif
-
-/* Interupt input is not used if there is no FIONREAD.  */
-#ifndef FIONREAD
-#undef SIGIO
-#endif
-
-#undef NULL
-
+#include "lisp.h"
 #include "termchar.h"
 #include "termopts.h"
+#include "termhooks.h"
 #include "cm.h"
-#include "lisp.h"
 #include "dispextern.h"
 #include "buffer.h"
-#include "screen.h"
+#include "frame.h"
 #include "window.h"
 #include "commands.h"
 #include "disptab.h"
 #include "indent.h"
+#include "intervals.h"
+
+#include "systty.h"
+#include "systime.h"
 
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
@@ -83,10 +55,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
 #endif
 
-/* Nonzero means do not assume anything about current
-   contents of actual terminal screen */
+/* Nonzero upon entry to redisplay means do not assume anything about
+   current contents of actual terminal frame; clear and redraw it.  */
 
-int screen_garbaged;
+int frame_garbaged;
 
 /* Nonzero means last display completed.  Zero means it was preempted. */
 
@@ -97,7 +69,7 @@ int display_completed;
 
 int visible_bell;
 
-/* Invert the color of the whole screen, at a low level.  */
+/* Invert the color of the whole frame, at a low level.  */
 
 int inverse_video;
 
@@ -126,39 +98,37 @@ Lisp_Object Vglyph_table;
 Lisp_Object Vstandard_display_table;
 
 /* Nonzero means reading single-character input with prompt
-   so put cursor on minibuffer after the prompt.  */
-
+   so put cursor on minibuffer after the prompt.
+   positive means at end of text in echo area;
+   negative means at beginning of line.  */
 int cursor_in_echo_area;
 \f
-/* The currently selected screen.
-   In a single-screen version, this variable always remains 0.  */
-
-SCREEN_PTR selected_screen;
+/* The currently selected frame.
+   In a single-frame version, this variable always remains 0.  */
 
-/* In a single-screen version, the information that would otherwise
-   exist inside a `struct screen' lives in the following variables instead.  */
+FRAME_PTR selected_frame;
 
-#ifndef MULTI_SCREEN
+/* A frame which is not just a minibuffer, or 0 if there are no such
+   frames.  This is usually the most recent such frame that was
+   selected.  In a single-frame version, this variable always remains 0.  */
+FRAME_PTR last_nonminibuf_frame;
 
-/* Desired terminal cursor position (to show position of point),
-   origin zero */
+/* In a single-frame version, the information that would otherwise
+   exist inside frame objects lives in the following structure instead.
 
-int cursX, cursY;
+   NOTE: the_only_frame is not checked for garbage collection; don't
+   store collectible objects in any of its fields!
 
-/* Description of current screen contents */
+   You're not/The only frame in town/...  */
 
-struct screen_glyphs *current_glyphs;
-
-/* Description of desired screen contents */
-
-struct screen_glyphs *desired_glyphs;
-
-#endif /* not MULTI_SCREEN */
+#ifndef MULTI_FRAME
+struct frame the_only_frame;
+#endif
 
 /* This is a vector, made larger whenever it isn't large enough,
-   which is used inside `update_screen' to hold the old contents
-   of the SCREEN_PHYS_LINES of the screen being updated.  */
-struct screen_glyphs **ophys_lines;
+   which is used inside `update_frame' to hold the old contents
+   of the FRAME_PHYS_LINES of the frame being updated.  */
+struct frame_glyphs **ophys_lines;
 /* Length of vector currently allocated.  */
 int ophys_lines_length;
 
@@ -168,93 +138,103 @@ struct cm Wcm;           /* Structure for info on cursor positioning */
 
 extern short ospeed;   /* Output speed (from sg_ospeed) */
 
-int in_display;                /* 1 if in redisplay: can't handle SIGWINCH now.  */
-
 int delayed_size_change;  /* 1 means SIGWINCH happened when not safe.  */
-int delayed_screen_height;  /* Remembered new screen height.  */
-int delayed_screen_width;   /* Remembered new screen width.  */
 \f
-#ifdef MULTI_SCREEN
+#ifdef MULTI_FRAME
 
-DEFUN ("redraw-screen", Fredraw_screen, Sredraw_screen, 1, 1, 0,
-  "Clear screen SCREEN and output again what is supposed to appear on it.")
-  (screen)
-     Lisp_Object screen;
+DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
+  "Clear frame FRAME and output again what is supposed to appear on it.")
+  (frame)
+     Lisp_Object frame;
 {
-  SCREEN_PTR s;
+  FRAME_PTR f;
 
-  CHECK_SCREEN (screen, 0);
-  s = XSCREEN (screen);
-  update_begin (s);
+  CHECK_LIVE_FRAME (frame, 0);
+  f = XFRAME (frame);
+  update_begin (f);
   /*  set_terminal_modes (); */
-  clear_screen ();
-  update_end (s);
+  clear_frame ();
+  clear_frame_records (f);
+  update_end (f);
   fflush (stdout);
-  clear_screen_records (s);
   windows_or_buffers_changed++;
   /* Mark all windows as INaccurate,
      so that every window will have its redisplay done.  */
-  mark_window_display_accurate (SCREEN_ROOT_WINDOW (s), 0);
-  s->garbaged = 0;
+  mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
+  f->garbaged = 0;
   return Qnil;
 }
 
-DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
-  "Redraw all screens marked as having their images garbled.")
-  ()
+redraw_frame (f)
+     FRAME_PTR f;
 {
-  Lisp_Object screen, tail;
-
-  for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
-    {
-      screen = XCONS (tail)->car;
-      if (XSCREEN (screen)->garbaged && XSCREEN (screen)->visible)
-       Fredraw_screen (screen);
-    }
-  return Qnil;
+  Lisp_Object frame;
+  XSET (frame, Lisp_Frame, f);
+  Fredraw_frame (frame);
 }
 
-redraw_screen (s)
-     SCREEN_PTR s;
-{
-  Lisp_Object screen;
-  XSET (screen, Lisp_Screen, s);
-  Fredraw_screen (screen);
-}
-
-#else /* not MULTI_SCREEN */
+#else
 
-DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, 0,
-  "Clear screen and output again what is supposed to appear on it.")
-  ()
+DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, "",
+  "Clear frame FRAME and output again what is supposed to appear on it.")
+  (frame)
+     Lisp_Object frame;
 {
   update_begin (0);
   set_terminal_modes ();
-  clear_screen ();
+  clear_frame ();
   update_end (0);
   fflush (stdout);
-  clear_screen_records (0);
+  clear_frame_records (0);
   windows_or_buffers_changed++;
   /* Mark all windows as INaccurate,
      so that every window will have its redisplay done.  */
-  mark_window_display_accurate (XWINDOW (minibuf_window)->prev, 0);
+  mark_window_display_accurate (FRAME_ROOT_WINDOW (0), 0);
+  return Qnil;
+}
+
+#endif
+
+DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
+  "Clear and redisplay all visible frames.")
+  ()
+{
+  Lisp_Object tail, frame;
+
+  FOR_EACH_FRAME (tail, frame)
+    if (FRAME_VISIBLE_P (XFRAME (frame)))
+      Fredraw_frame (frame);
+
   return Qnil;
 }
 
-#endif /* not MULTI_SCREEN */
+/* This is used when frame_garbaged is set.
+   Redraw the individual frames marked as garbaged.  */
+
+void
+redraw_garbaged_frames ()
+{
+  Lisp_Object tail, frame;
+
+  FOR_EACH_FRAME (tail, frame)
+    if (FRAME_VISIBLE_P (XFRAME (frame))
+       && FRAME_GARBAGED_P (XFRAME (frame)))
+      Fredraw_frame (frame);
+}
+
 \f
-static struct screen_glyphs *
-make_screen_glyphs (screen, empty)
-     register SCREEN_PTR screen;
+static struct frame_glyphs *
+make_frame_glyphs (frame, empty)
+     register FRAME_PTR frame;
      int empty;
 {
   register int i;
-  register width = SCREEN_WIDTH (screen);
-  register height = SCREEN_HEIGHT (screen);
-  register struct screen_glyphs *new =
-    (struct screen_glyphs *) xmalloc (sizeof (struct screen_glyphs));
+  register width = FRAME_WIDTH (frame);
+  register height = FRAME_HEIGHT (frame);
+  register struct frame_glyphs *new =
+    (struct frame_glyphs *) xmalloc (sizeof (struct frame_glyphs));
 
-  SET_GLYPHS_SCREEN (new, screen);
+  SET_GLYPHS_FRAME (new, frame);
   new->height = height;
   new->width = width;
   new->used = (int *) xmalloc (height * sizeof (int));
@@ -265,22 +245,20 @@ make_screen_glyphs (screen, empty)
   new->bufp = (int *) xmalloc (height * sizeof (int));
 
 #ifdef HAVE_X_WINDOWS
-  if (SCREEN_IS_X (screen))
+  if (FRAME_X_P (frame))
     {
-      new->nruns = (int *) xmalloc (height * sizeof (int));
-      new->face_list
-       = (struct run **) xmalloc (height * sizeof (struct run *));
       new->top_left_x = (short *) xmalloc (height * sizeof (short));
       new->top_left_y = (short *) xmalloc (height * sizeof (short));
       new->pix_width = (short *) xmalloc (height * sizeof (short));
       new->pix_height = (short *) xmalloc (height * sizeof (short));
+      new->max_ascent = (short *) xmalloc (height * sizeof (short));
     }
 #endif
 
   if (empty)
     {
       /* Make the buffer used by decode_mode_spec.  This buffer is also
-         used as temporary storage when updating the screen.  See scroll.c. */
+         used as temporary storage when updating the frame.  See scroll.c. */
       unsigned int total_glyphs = (width + 2) * sizeof (GLYPH);
 
       new->total_contents = (GLYPH *) xmalloc (total_glyphs);
@@ -300,64 +278,74 @@ make_screen_glyphs (screen, empty)
 }
 
 static void
-free_screen_glyphs (screen, glyphs)
-     SCREEN_PTR screen;
-     struct screen_glyphs *glyphs;
+free_frame_glyphs (frame, glyphs)
+     FRAME_PTR frame;
+     struct frame_glyphs *glyphs;
 {
   if (glyphs->total_contents)
-    free (glyphs->total_contents);
+    xfree (glyphs->total_contents);
 
-  free (glyphs->used);
-  free (glyphs->glyphs);
-  free (glyphs->highlight);
-  free (glyphs->enable);
-  free (glyphs->bufp);
+  xfree (glyphs->used);
+  xfree (glyphs->glyphs);
+  xfree (glyphs->highlight);
+  xfree (glyphs->enable);
+  xfree (glyphs->bufp);
 
 #ifdef HAVE_X_WINDOWS
-  if (SCREEN_IS_X (screen))
+  if (FRAME_X_P (frame))
     {
-      free (glyphs->nruns);
-      free (glyphs->face_list);
-      free (glyphs->top_left_x);
-      free (glyphs->top_left_y);
-      free (glyphs->pix_width);
-      free (glyphs->pix_height);
+      xfree (glyphs->top_left_x);
+      xfree (glyphs->top_left_y);
+      xfree (glyphs->pix_width);
+      xfree (glyphs->pix_height);
+      xfree (glyphs->max_ascent);
     }
 #endif
 
-  free (glyphs);
+  xfree (glyphs);
 }
 
 static void
-remake_screen_glyphs (screen)
-     SCREEN_PTR screen;
+remake_frame_glyphs (frame)
+     FRAME_PTR frame;
 {
-  if (SCREEN_CURRENT_GLYPHS (screen))
-    free_screen_glyphs (screen, SCREEN_CURRENT_GLYPHS (screen));
-  if (SCREEN_DESIRED_GLYPHS (screen))
-    free_screen_glyphs (screen, SCREEN_DESIRED_GLYPHS (screen));
-  if (SCREEN_TEMP_GLYPHS (screen))
-    free_screen_glyphs (screen, SCREEN_TEMP_GLYPHS (screen));
-
-  if (SCREEN_MESSAGE_BUF (screen))
-    SCREEN_MESSAGE_BUF (screen)
-      = (char *) xrealloc (SCREEN_MESSAGE_BUF (screen),
-                          SCREEN_WIDTH (screen) + 1);
+  if (FRAME_CURRENT_GLYPHS (frame))
+    free_frame_glyphs (frame, FRAME_CURRENT_GLYPHS (frame));
+  if (FRAME_DESIRED_GLYPHS (frame))
+    free_frame_glyphs (frame, FRAME_DESIRED_GLYPHS (frame));
+  if (FRAME_TEMP_GLYPHS (frame))
+    free_frame_glyphs (frame, FRAME_TEMP_GLYPHS (frame));
+
+  if (FRAME_MESSAGE_BUF (frame))
+    {
+      /* Reallocate the frame's message buffer; remember that
+        echo_area_glyphs may be pointing here.  */
+      char *old_message_buf = FRAME_MESSAGE_BUF (frame);
+
+      FRAME_MESSAGE_BUF (frame)
+       = (char *) xrealloc (FRAME_MESSAGE_BUF (frame),
+                            FRAME_WIDTH (frame) + 1);
+
+      if (echo_area_glyphs == old_message_buf)
+       echo_area_glyphs = FRAME_MESSAGE_BUF (frame);
+      if (previous_echo_glyphs == old_message_buf)
+       previous_echo_glyphs = FRAME_MESSAGE_BUF (frame);
+    }
   else
-    SCREEN_MESSAGE_BUF (screen)
-      = (char *) xmalloc (SCREEN_WIDTH (screen) + 1);
+    FRAME_MESSAGE_BUF (frame)
+      = (char *) xmalloc (FRAME_WIDTH (frame) + 1);
 
-  SCREEN_CURRENT_GLYPHS (screen) = make_screen_glyphs (screen, 0);
-  SCREEN_DESIRED_GLYPHS (screen) = make_screen_glyphs (screen, 0);
-  SCREEN_TEMP_GLYPHS (screen) = make_screen_glyphs (screen, 1);
-  SET_SCREEN_GARBAGED (screen);
+  FRAME_CURRENT_GLYPHS (frame) = make_frame_glyphs (frame, 0);
+  FRAME_DESIRED_GLYPHS (frame) = make_frame_glyphs (frame, 0);
+  FRAME_TEMP_GLYPHS (frame) = make_frame_glyphs (frame, 1);
+  SET_FRAME_GARBAGED (frame);
 }
 \f
-/* Return the hash code of contents of line VPOS in screen-matrix M.  */
+/* Return the hash code of contents of line VPOS in frame-matrix M.  */
 
 static int
 line_hash_code (m, vpos)
-     register struct screen_glyphs *m;
+     register struct frame_glyphs *m;
      int vpos;
 {
   register GLYPH *body, *end;
@@ -366,7 +354,7 @@ line_hash_code (m, vpos)
   if (!m->enable[vpos])
     return 0;
 
-  /* Give all lighlighted lines the same hash code
+  /* Give all highlighted lines the same hash code
      so as to encourage scrolling to leave them in place.  */
   if (m->highlight[vpos])
     return -1;
@@ -403,7 +391,7 @@ line_hash_code (m, vpos)
 
 static unsigned int
 line_draw_cost (m, vpos)
-     struct screen_glyphs *m;
+     struct frame_glyphs *m;
      int vpos;
 {
   register GLYPH *beg = m->glyphs[vpos];
@@ -446,37 +434,37 @@ line_draw_cost (m, vpos)
 /* The functions on this page are the interface from xdisp.c to redisplay.
 
    The only other interface into redisplay is through setting
-   SCREEN_CURSOR_X (screen) and SCREEN_CURSOR_Y (screen)
-   and SET_SCREEN_GARBAGED (screen).  */
+   FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
+   and SET_FRAME_GARBAGED (frame).  */
 
 /* cancel_line eliminates any request to display a line at position `vpos' */
 
-cancel_line (vpos, screen)
+cancel_line (vpos, frame)
      int vpos;
-     register SCREEN_PTR screen;
+     register FRAME_PTR frame;
 {
-  SCREEN_DESIRED_GLYPHS (screen)->enable[vpos] = 0;
+  FRAME_DESIRED_GLYPHS (frame)->enable[vpos] = 0;
 }
 
-clear_screen_records (screen)
-     register SCREEN_PTR screen;
+clear_frame_records (frame)
+     register FRAME_PTR frame;
 {
-  bzero (SCREEN_CURRENT_GLYPHS (screen)->enable, SCREEN_HEIGHT (screen));
+  bzero (FRAME_CURRENT_GLYPHS (frame)->enable, FRAME_HEIGHT (frame));
 }
 
 /* Prepare to display on line VPOS starting at HPOS within it.  */
 
 void
-get_display_line (screen, vpos, hpos)
-     register SCREEN_PTR screen;
+get_display_line (frame, vpos, hpos)
+     register FRAME_PTR frame;
      int vpos;
      register int hpos;
 {
-  register struct screen_glyphs *glyphs;
-  register struct screen_glyphs *desired_glyphs = SCREEN_DESIRED_GLYPHS (screen);
+  register struct frame_glyphs *glyphs;
+  register struct frame_glyphs *desired_glyphs = FRAME_DESIRED_GLYPHS (frame);
   register GLYPH *p;
 
-  if (vpos < 0 || (! SCREEN_VISIBLE_P (screen)))
+  if (vpos < 0)
     abort ();
 
   if ((desired_glyphs->enable[vpos]) && desired_glyphs->used[vpos] > hpos)
@@ -507,25 +495,27 @@ safe_bcopy (from, to, size)
      char *from, *to;
      int size;
 {
-  register char *endf;
-  register char *endt;
-
-  if (size == 0)
+  if (size <= 0 || from == to)
     return;
 
-  /* If destination is higher in memory, and overlaps source zone,
-     copy from the end.  */
-  if (from < to && from + size > to)
+  /* If the source and destination don't overlap, then bcopy can
+     handle it.  If they do overlap, but the destination is lower in
+     memory than the source, we'll assume bcopy can handle that.  */
+  if (to < from || from + size <= to)
+    bcopy (from, to, size);
+
+  /* Otherwise, we'll copy from the end.  */
+  else
     {
-      endf = from + size;
-      endt = to + size;
+      register char *endf = from + size;
+      register char *endt = to + size;
 
       /* If TO - FROM is large, then we should break the copy into
         nonoverlapping chunks of TO - FROM bytes each.  However, if
         TO - FROM is small, then the bcopy function call overhead
         makes this not worth it.  The crossover point could be about
-        anywhere.  Since I don't think the obvious copy loop is ever
-        too bad, I'm trying to err in its favor.  */
+        anywhere.  Since I don't think the obvious copy loop is too
+        bad, I'm trying to err in its favor.  */
       if (to - from < 64)
        {
          do
@@ -534,57 +524,26 @@ safe_bcopy (from, to, size)
        }
       else
        {
-         /* Since the overlap is always less than SIZE, we can always
-            safely do this loop once.  */
-         while (endt > to)
+         for (;;)
            {
              endt -= (to - from);
              endf -= (to - from);
 
+             if (endt < to)
+               break;
+
              bcopy (endf, endt, to - from);
            }
-         
-         /* If TO - FROM wasn't a multiple of SIZE, there will be a
+
+         /* If SIZE wasn't a multiple of TO - FROM, there will be a
             little left over.  The amount left over is
             (endt + (to - from)) - to, which is endt - from.  */
          bcopy (from, to, endt - from);
        }
     }
-  else
-    bcopy (from, to, size);
 }     
 
-#if 0
-void
-safe_bcopy (from, to, size)
-     char *from, *to;
-     int size;
-{
-  register char *endf;
-  register char *endt;
-
-  if (size == 0)
-    return;
-
-  /* If destination is higher in memory, and overlaps source zone,
-     copy from the end. */
-  if (from < to && from + size > to)
-    {
-      endf = from + size;
-      endt = to + size;
-
-      do
-       *--endt = *--endf;
-      while (endf != from);
-
-      return;
-    }
-
-  bcopy (from, to, size);
-}
-#endif
-
-/* Rotate a vector of SIZE bytes, by DISTANCE bytes.
+/* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
    DISTANCE may be negative.  */
 
 static void
@@ -608,13 +567,13 @@ rotate_vector (vector, size, distance)
    Returns nonzero if done, zero if terminal cannot scroll them.  */
 
 int
-scroll_screen_lines (screen, from, end, amount)
-     register SCREEN_PTR screen;
+scroll_frame_lines (frame, from, end, amount)
+     register FRAME_PTR frame;
      int from, end, amount;
 {
   register int i;
-  register struct screen_glyphs *current_screen
-    = SCREEN_CURRENT_GLYPHS (screen);
+  register struct frame_glyphs *current_frame
+    = FRAME_CURRENT_GLYPHS (frame);
 
   if (!line_ins_del_ok)
     return 0;
@@ -624,193 +583,187 @@ scroll_screen_lines (screen, from, end, amount)
 
   if (amount > 0)
     {
-      update_begin (screen);
+      update_begin (frame);
       set_terminal_window (end + amount);
       if (!scroll_region_ok)
        ins_del_lines (end, -amount);
       ins_del_lines (from, amount);
       set_terminal_window (0);
 
-      rotate_vector (current_screen->glyphs + from,
+      rotate_vector (current_frame->glyphs + from,
                     sizeof (GLYPH *) * (end + amount - from),
                     amount * sizeof (GLYPH *));
 
-      safe_bcopy (current_screen->used + from,
-                 current_screen->used + from + amount,
-                 (end - from) * sizeof current_screen->used[0]);
+      safe_bcopy (current_frame->used + from,
+                 current_frame->used + from + amount,
+                 (end - from) * sizeof current_frame->used[0]);
 
-      safe_bcopy (current_screen->highlight + from,
-                 current_screen->highlight + from + amount,
-                 (end - from) * sizeof current_screen->highlight[0]);
+      safe_bcopy (current_frame->highlight + from,
+                 current_frame->highlight + from + amount,
+                 (end - from) * sizeof current_frame->highlight[0]);
 
-      safe_bcopy (current_screen->enable + from,
-                 current_screen->enable + from + amount,
-                 (end - from) * sizeof current_screen->enable[0]);
+      safe_bcopy (current_frame->enable + from,
+                 current_frame->enable + from + amount,
+                 (end - from) * sizeof current_frame->enable[0]);
 
       /* Mark the lines made empty by scrolling as enabled, empty and
         normal video.  */
-      bzero (current_screen->used + from,
-            amount * sizeof current_screen->used[0]);
-      bzero (current_screen->highlight + from,
-            amount * sizeof current_screen->highlight[0]);
+      bzero (current_frame->used + from,
+            amount * sizeof current_frame->used[0]);
+      bzero (current_frame->highlight + from,
+            amount * sizeof current_frame->highlight[0]);
       for (i = from; i < from + amount; i++)
        {
-         current_screen->glyphs[i][0] = '\0';
-         current_screen->enable[i] = 1;
+         current_frame->glyphs[i][0] = '\0';
+         current_frame->enable[i] = 1;
        }
 
-      safe_bcopy (current_screen->bufp + from,
-                 current_screen->bufp + from + amount,
-                 (end - from) * sizeof current_screen->bufp[0]);
+      safe_bcopy (current_frame->bufp + from,
+                 current_frame->bufp + from + amount,
+                 (end - from) * sizeof current_frame->bufp[0]);
 
 #ifdef HAVE_X_WINDOWS
-      if (SCREEN_IS_X (screen))
+      if (FRAME_X_P (frame))
        {
-         safe_bcopy (current_screen->nruns + from,
-                     current_screen->nruns + from + amount,
-                     (end - from) * sizeof current_screen->nruns[0]);
-
-         safe_bcopy (current_screen->face_list + from,
-                     current_screen->face_list + from + amount,
-                     (end - from) * sizeof current_screen->face_list[0]);
+         safe_bcopy (current_frame->top_left_x + from,
+                     current_frame->top_left_x + from + amount,
+                     (end - from) * sizeof current_frame->top_left_x[0]);
 
-         safe_bcopy (current_screen->top_left_x + from,
-                     current_screen->top_left_x + from + amount,
-                     (end - from) * sizeof current_screen->top_left_x[0]);
+         safe_bcopy (current_frame->top_left_y + from,
+                     current_frame->top_left_y + from + amount,
+                     (end - from) * sizeof current_frame->top_left_y[0]);
 
-         safe_bcopy (current_screen->top_left_y + from,
-                     current_screen->top_left_y + from + amount,
-                     (end - from) * sizeof current_screen->top_left_y[0]);
+         safe_bcopy (current_frame->pix_width + from,
+                     current_frame->pix_width + from + amount,
+                     (end - from) * sizeof current_frame->pix_width[0]);
 
-         safe_bcopy (current_screen->pix_width + from,
-                     current_screen->pix_width + from + amount,
-                     (end - from) * sizeof current_screen->pix_width[0]);
+         safe_bcopy (current_frame->pix_height + from,
+                     current_frame->pix_height + from + amount,
+                     (end - from) * sizeof current_frame->pix_height[0]);
 
-         safe_bcopy (current_screen->pix_height + from,
-                     current_screen->pix_height + from + amount,
-                     (end - from) * sizeof current_screen->pix_height[0]);
+         safe_bcopy (current_frame->max_ascent + from,
+                     current_frame->max_ascent + from + amount,
+                     (end - from) * sizeof current_frame->max_ascent[0]);
        }
 #endif                         /* HAVE_X_WINDOWS */
 
-      update_end (screen);
+      update_end (frame);
     }
   if (amount < 0)
     {
-      update_begin (screen);
+      update_begin (frame);
       set_terminal_window (end);
       ins_del_lines (from + amount, amount);
       if (!scroll_region_ok)
        ins_del_lines (end + amount, -amount);
       set_terminal_window (0);
 
-      rotate_vector (current_screen->glyphs + from + amount,
+      rotate_vector (current_frame->glyphs + from + amount,
                     sizeof (GLYPH *) * (end - from - amount),
                     amount * sizeof (GLYPH *));
 
-      safe_bcopy (current_screen->used + from,
-                 current_screen->used + from + amount,
-                 (end - from) * sizeof current_screen->used[0]);
+      safe_bcopy (current_frame->used + from,
+                 current_frame->used + from + amount,
+                 (end - from) * sizeof current_frame->used[0]);
 
-      safe_bcopy (current_screen->highlight + from,
-                 current_screen->highlight + from + amount,
-                 (end - from) * sizeof current_screen->highlight[0]);
+      safe_bcopy (current_frame->highlight + from,
+                 current_frame->highlight + from + amount,
+                 (end - from) * sizeof current_frame->highlight[0]);
 
-      safe_bcopy (current_screen->enable + from,
-                 current_screen->enable + from + amount,
-                 (end - from) * sizeof current_screen->enable[0]);
+      safe_bcopy (current_frame->enable + from,
+                 current_frame->enable + from + amount,
+                 (end - from) * sizeof current_frame->enable[0]);
 
       /* Mark the lines made empty by scrolling as enabled, empty and
         normal video.  */
-      bzero (current_screen->used + end + amount,
-            - amount * sizeof current_screen->used[0]);
-      bzero (current_screen->highlight + end + amount,
-            - amount * sizeof current_screen->highlight[0]);
+      bzero (current_frame->used + end + amount,
+            - amount * sizeof current_frame->used[0]);
+      bzero (current_frame->highlight + end + amount,
+            - amount * sizeof current_frame->highlight[0]);
       for (i = end + amount; i < end; i++)
        {
-         current_screen->glyphs[i][0] = '\0';
-         current_screen->enable[i] = 1;
+         current_frame->glyphs[i][0] = '\0';
+         current_frame->enable[i] = 1;
        }
 
-      safe_bcopy (current_screen->bufp + from,
-                 current_screen->bufp + from + amount,
-                 (end - from) * sizeof current_screen->bufp[0]);
+      safe_bcopy (current_frame->bufp + from,
+                 current_frame->bufp + from + amount,
+                 (end - from) * sizeof current_frame->bufp[0]);
 
 #ifdef HAVE_X_WINDOWS
-      if (SCREEN_IS_X (screen))
+      if (FRAME_X_P (frame))
        {
-         safe_bcopy (current_screen->nruns + from,
-                     current_screen->nruns + from + amount,
-                     (end - from) * sizeof current_screen->nruns[0]);
-
-         safe_bcopy (current_screen->face_list + from,
-                     current_screen->face_list + from + amount,
-                     (end - from) * sizeof current_screen->face_list[0]);
+         safe_bcopy (current_frame->top_left_x + from,
+                     current_frame->top_left_x + from + amount,
+                     (end - from) * sizeof current_frame->top_left_x[0]);
 
-         safe_bcopy (current_screen->top_left_x + from,
-                     current_screen->top_left_x + from + amount,
-                     (end - from) * sizeof current_screen->top_left_x[0]);
+         safe_bcopy (current_frame->top_left_y + from,
+                     current_frame->top_left_y + from + amount,
+                     (end - from) * sizeof current_frame->top_left_y[0]);
 
-         safe_bcopy (current_screen->top_left_y + from,
-                     current_screen->top_left_y + from + amount,
-                     (end - from) * sizeof current_screen->top_left_y[0]);
+         safe_bcopy (current_frame->pix_width + from,
+                     current_frame->pix_width + from + amount,
+                     (end - from) * sizeof current_frame->pix_width[0]);
 
-         safe_bcopy (current_screen->pix_width + from,
-                     current_screen->pix_width + from + amount,
-                     (end - from) * sizeof current_screen->pix_width[0]);
+         safe_bcopy (current_frame->pix_height + from,
+                     current_frame->pix_height + from + amount,
+                     (end - from) * sizeof current_frame->pix_height[0]);
 
-         safe_bcopy (current_screen->pix_height + from,
-                     current_screen->pix_height + from + amount,
-                     (end - from) * sizeof current_screen->pix_height[0]);
+         safe_bcopy (current_frame->max_ascent + from,
+                     current_frame->max_ascent + from + amount,
+                     (end - from) * sizeof current_frame->max_ascent[0]);
        }
 #endif                         /* HAVE_X_WINDOWS */
 
-      update_end (screen);
+      update_end (frame);
     }
   return 1;
 }
 \f
-/* After updating a window W that isn't the full screen wide,
+/* After updating a window W that isn't the full frame wide,
    copy all the columns that W does not occupy
-   into the SCREEN_DESIRED_GLYPHS (screen) from the SCREEN_PHYS_GLYPHS (screen)
-   so that update_screen will not change those columns.  */
+   into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
+   so that update_frame will not change those columns.  */
 
 preserve_other_columns (w)
      struct window *w;
 {
   register int vpos;
-  register struct screen_glyphs *current_screen, *desired_screen;
-  register SCREEN_PTR screen = XSCREEN (w->screen);
+  register struct frame_glyphs *current_frame, *desired_frame;
+  register FRAME_PTR frame = XFRAME (w->frame);
   int start = XFASTINT (w->left);
   int end = XFASTINT (w->left) + XFASTINT (w->width);
   int bot = XFASTINT (w->top) + XFASTINT (w->height);
 
-  current_screen = SCREEN_CURRENT_GLYPHS (screen);
-  desired_screen = SCREEN_DESIRED_GLYPHS (screen);
+  current_frame = FRAME_CURRENT_GLYPHS (frame);
+  desired_frame = FRAME_DESIRED_GLYPHS (frame);
 
   for (vpos = XFASTINT (w->top); vpos < bot; vpos++)
     {
-      if (current_screen->enable[vpos] && desired_screen->enable[vpos])
+      if (current_frame->enable[vpos] && desired_frame->enable[vpos])
        {
          if (start > 0)
            {
              int len;
 
-             bcopy (current_screen->glyphs[vpos],
-                    desired_screen->glyphs[vpos], start);
-             len = min (start, current_screen->used[vpos]);
-             if (desired_screen->used[vpos] < len)
-               desired_screen->used[vpos] = len;
+             bcopy (current_frame->glyphs[vpos],
+                    desired_frame->glyphs[vpos],
+                    start * sizeof (current_frame->glyphs[vpos]));
+             len = min (start, current_frame->used[vpos]);
+             if (desired_frame->used[vpos] < len)
+               desired_frame->used[vpos] = len;
            }
-         if (current_screen->used[vpos] > end
-             && desired_screen->used[vpos] < current_screen->used[vpos])
+         if (current_frame->used[vpos] > end
+             && desired_frame->used[vpos] < current_frame->used[vpos])
            {
-             while (desired_screen->used[vpos] < end)
-               desired_screen->glyphs[vpos][desired_screen->used[vpos]++]
+             while (desired_frame->used[vpos] < end)
+               desired_frame->glyphs[vpos][desired_frame->used[vpos]++]
                  = SPACEGLYPH;
-             bcopy (current_screen->glyphs[vpos] + end,
-                    desired_screen->glyphs[vpos] + end,
-                    current_screen->used[vpos] - end);
-             desired_screen->used[vpos] = current_screen->used[vpos];
+             bcopy (current_frame->glyphs[vpos] + end,
+                    desired_frame->glyphs[vpos] + end,
+                    ((current_frame->used[vpos] - end)
+                     * sizeof (current_frame->glyphs[vpos])));
+             desired_frame->used[vpos] = current_frame->used[vpos];
            }
        }
     }
@@ -818,10 +771,10 @@ preserve_other_columns (w)
 \f
 #if 0
 
-/* If window w does not need to be updated and isn't the full screen wide,
+/* If window w does not need to be updated and isn't the full frame wide,
  copy all the columns that w does occupy
- into the SCREEN_DESIRED_LINES (screen) from the SCREEN_PHYS_LINES (screen)
- so that update_screen will not change those columns.
+ into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
+ so that update_frame will not change those columns.
 
  Have not been able to figure out how to use this correctly.  */
 
@@ -829,16 +782,16 @@ preserve_my_columns (w)
      struct window *w;
 {
   register int vpos, fin;
-  register struct screen_glyphs *l1, *l2;
-  register SCREEN_PTR screen = XSCREEN (w->screen);
+  register struct frame_glyphs *l1, *l2;
+  register FRAME_PTR frame = XFRAME (w->frame);
   int start = XFASTINT (w->left);
   int end = XFASTINT (w->left) + XFASTINT (w->width);
   int bot = XFASTINT (w->top) + XFASTINT (w->height);
 
   for (vpos = XFASTINT (w->top); vpos < bot; vpos++)
     {
-      if ((l1 = SCREEN_DESIRED_GLYPHS (screen)->glyphs[vpos + 1])
-         && (l2 = SCREEN_PHYS_GLYPHS (screen)->glyphs[vpos + 1]))
+      if ((l1 = FRAME_DESIRED_GLYPHS (frame)->glyphs[vpos + 1])
+         && (l2 = FRAME_PHYS_GLYPHS (frame)->glyphs[vpos + 1]))
        {
          if (l2->length > start && l1->length < l2->length)
            {
@@ -863,8 +816,8 @@ cancel_my_columns (w)
      struct window *w;
 {
   register int vpos;
-  register SCREEN_PTR screen = XSCREEN (w->screen);
-  register struct screen_glyphs *desired_glyphs = screen->desired_glyphs;
+  register struct frame_glyphs *desired_glyphs =
+    FRAME_DESIRED_GLYPHS (XFRAME (w->frame));
   register int start = XFASTINT (w->left);
   register int bot = XFASTINT (w->top) + XFASTINT (w->height);
 
@@ -874,21 +827,21 @@ cancel_my_columns (w)
       desired_glyphs->used[vpos] = start;
 }
 \f
-/* These functions try to perform directly and immediately on the screen
+/* These functions try to perform directly and immediately on the frame
    the necessary output for one change in the buffer.
    They may return 0 meaning nothing was done if anything is difficult,
    or 1 meaning the output was performed properly.
-   They assume that the screen was up to date before the buffer
-   change being displayed.  THey make various other assumptions too;
+   They assume that the frame was up to date before the buffer
+   change being displayed.  They make various other assumptions too;
    see command_loop_1 where these are called.  */
 
 int
 direct_output_for_insert (g)
      int g;
 {
-  register SCREEN_PTR screen = selected_screen;
-  register struct screen_glyphs *current_screen
-    = SCREEN_CURRENT_GLYPHS (screen);
+  register FRAME_PTR frame = selected_frame;
+  register struct frame_glyphs *current_frame
+    = FRAME_CURRENT_GLYPHS (frame);
 
 #ifndef COMPILER_REGISTER_BUG
   register
@@ -897,33 +850,54 @@ direct_output_for_insert (g)
 #ifndef COMPILER_REGISTER_BUG
   register
 #endif /* COMPILER_REGISTER_BUG */
-    int hpos = SCREEN_CURSOR_X (screen);
+    int hpos = FRAME_CURSOR_X (frame);
 #ifndef COMPILER_REGISTER_BUG
   register
 #endif /* COMPILER_REGISTER_BUG */
-    int vpos = SCREEN_CURSOR_Y (screen);
-
-  /* Give up if about to continue line */
-  if (hpos - XFASTINT (w->left) + 1 + 1 >= XFASTINT (w->width)
+    int vpos = FRAME_CURSOR_Y (frame);
 
+  /* Give up if about to continue line.  */
+  if (hpos >= XFASTINT (w->left) + window_internal_width (w) - 1
+    
   /* Avoid losing if cursor is in invisible text off left margin */
       || (XINT (w->hscroll) && hpos == XFASTINT (w->left))
     
   /* Give up if cursor outside window (in minibuf, probably) */
-      || SCREEN_CURSOR_Y (screen) < XFASTINT (w->top)
-      || SCREEN_CURSOR_Y (screen) >= XFASTINT (w->top) + XFASTINT (w->height)
+      || cursor_in_echo_area
+      || FRAME_CURSOR_Y (frame) < XFASTINT (w->top)
+      || FRAME_CURSOR_Y (frame) >= XFASTINT (w->top) + XFASTINT (w->height)
 
-  /* Give up if cursor not really at SCREEN_CURSOR_X, SCREEN_CURSOR_Y */
+  /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
       || !display_completed
 
   /* Give up if buffer appears in two places.  */
       || buffer_shared > 1
 
+#ifdef USE_TEXT_PROPERTIES
+  /* Intervals have already been adjusted, point is after the
+     character that was just inserted. */
+  /* Give up if character has is invisible. */
+  /* Give up if character has a face property.
+     At the moment we only lose at end of line or end of buffer
+     and only with faces that have some background */
+  /* Instead of wasting time, give up if character has any text properties */
+      || ! NILP (Ftext_properties_at (XFASTINT (point - 1), Qnil))
+#endif
+
   /* Give up if w is minibuffer and a message is being displayed there */
       || (MINI_WINDOW_P (w) && echo_area_glyphs))
     return 0;
 
-  current_screen->glyphs[vpos][hpos] = g;
+  {
+#ifdef HAVE_X_WINDOWS
+    int dummy;
+    int face = compute_char_face (frame, w, point - 1, -1, -1, &dummy);
+#else
+    int face = 0;
+#endif
+                                 
+    current_frame->glyphs[vpos][hpos] = MAKE_GLYPH (g, face);
+  }
   unchanged_modified = MODIFF;
   beg_unchanged = GPT - BEG;
   XFASTINT (w->last_point) = point;
@@ -931,13 +905,13 @@ direct_output_for_insert (g)
   XFASTINT (w->last_modified) = MODIFF;
 
   reassert_line_highlight (0, vpos);
-  write_glyphs (&current_screen->glyphs[vpos][hpos], 1);
+  write_glyphs (&current_frame->glyphs[vpos][hpos], 1);
   fflush (stdout);
-  ++SCREEN_CURSOR_X (screen);
-  if (hpos == current_screen->used[vpos])
+  ++FRAME_CURSOR_X (frame);
+  if (hpos == current_frame->used[vpos])
     {
-      current_screen->used[vpos] = hpos + 1;
-      current_screen->glyphs[vpos][hpos + 1] = 0;
+      current_frame->used[vpos] = hpos + 1;
+      current_frame->glyphs[vpos][hpos + 1] = 0;
     }
 
   return 1;
@@ -947,35 +921,65 @@ int
 direct_output_forward_char (n)
      int n;
 {
-  register SCREEN_PTR screen = selected_screen;
+  register FRAME_PTR frame = selected_frame;
   register struct window *w = XWINDOW (selected_window);
-
-  /* Avoid losing if cursor is in invisible text off left margin */
-  if (XINT (w->hscroll) && SCREEN_CURSOR_X (screen) == XFASTINT (w->left))
+  int position;
+  
+  /* Avoid losing if cursor is in invisible text off left margin
+     or about to go off either side of window.  */
+  if ((FRAME_CURSOR_X (frame) == XFASTINT (w->left)
+       && (XINT (w->hscroll) || n < 0))
+      || (n > 0
+         && (FRAME_CURSOR_X (frame) + 1 >= window_internal_width (w) - 1))
+      || cursor_in_echo_area)
+    return 0;
+  
+  /* Can't use direct output if highlighting a region.  */
+  if (!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active))
     return 0;
 
-  SCREEN_CURSOR_X (screen) += n;
-  XFASTINT (w->last_point_x) = SCREEN_CURSOR_X (screen);
+#ifdef USE_TEXT_PROPERTIES
+  /* Don't use direct output next to an invisible character
+     since we might need to do something special.  */
+
+  XFASTINT (position) = point;
+  if (XFASTINT (position) < ZV
+      && ! NILP (Fget_text_property (position,
+                                    Qinvisible,
+                                    Fcurrent_buffer ())))
+    return;
+
+  XFASTINT (position) = point - 1;
+  if (XFASTINT (position) >= BEGV
+      && ! NILP (Fget_text_property (position,
+                                    Qinvisible,
+                                    Fcurrent_buffer ())))
+    return;
+#endif
+
+  FRAME_CURSOR_X (frame) += n;
+  XFASTINT (w->last_point_x) = FRAME_CURSOR_X (frame);
   XFASTINT (w->last_point) = point;
-  cursor_to (SCREEN_CURSOR_Y (screen), SCREEN_CURSOR_X (screen));
+  cursor_to (FRAME_CURSOR_Y (frame), FRAME_CURSOR_X (frame));
   fflush (stdout);
+
   return 1;
 }
 \f
 static void update_line ();
 
-/* Update screen S based on the data in SCREEN_DESIRED_GLYPHS.
+/* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
    Value is nonzero if redisplay stopped due to pending input.
    FORCE nonzero means do not stop for pending input.  */
 
 int
-update_screen (s, force, inhibit_hairy_id)
-     SCREEN_PTR s;
+update_frame (f, force, inhibit_hairy_id)
+     FRAME_PTR f;
      int force;
      int inhibit_hairy_id;
 {
-  register struct screen_glyphs *current_screen = SCREEN_CURRENT_GLYPHS (s);
-  register struct screen_glyphs *desired_screen = SCREEN_DESIRED_GLYPHS (s);
+  register struct frame_glyphs *current_frame = FRAME_CURRENT_GLYPHS (f);
+  register struct frame_glyphs *desired_frame = FRAME_DESIRED_GLYPHS (f);
   register int i;
   int pause;
   int preempt_count = baud_rate / 2400 + 1;
@@ -984,7 +988,10 @@ update_screen (s, force, inhibit_hairy_id)
   register int downto, leftmost;
 #endif
 
-  if (SCREEN_HEIGHT (s) == 0) abort (); /* Some bug zeros some core */
+  if (preempt_count <= 0)
+    preempt_count = 1;
+
+  if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */
 
   detect_input_pending ();
   if (input_pending && !force)
@@ -993,47 +1000,48 @@ update_screen (s, force, inhibit_hairy_id)
       goto do_pause;
     }
 
-  update_begin (s);
+  update_begin (f);
 
   if (!line_ins_del_ok)
     inhibit_hairy_id = 1;
 
-  /* Don't compute for i/d line if just want cursor motion. */
-  for (i = 0; i < SCREEN_HEIGHT (s); i++)
-    if (desired_screen->enable[i])
+  /* See if any of the desired lines are enabled; don't compute for
+     i/d line if just want cursor motion. */
+  for (i = 0; i < FRAME_HEIGHT (f); i++)
+    if (desired_frame->enable[i])
       break;
 
   /* Try doing i/d line, if not yet inhibited.  */
-  if (!inhibit_hairy_id && i < SCREEN_HEIGHT (s))
-    force |= scrolling (s);
+  if (!inhibit_hairy_id && i < FRAME_HEIGHT (f))
+    force |= scrolling (f);
 
   /* Update the individual lines as needed.  Do bottom line first.  */
 
-  if (desired_screen->enable[SCREEN_HEIGHT (s) - 1])
-    update_line (s, SCREEN_HEIGHT (s) - 1);
+  if (desired_frame->enable[FRAME_HEIGHT (f) - 1])
+    update_line (f, FRAME_HEIGHT (f) - 1);
 
 #ifdef HAVE_X_WINDOWS
-  if (SCREEN_IS_X (s))
+  if (FRAME_X_P (f))
     {
-      leftmost = downto = s->display.x->internal_border_width;
-      if (desired_screen->enable[0])
+      leftmost = downto = f->display.x->internal_border_width;
+      if (desired_frame->enable[0])
        {
-         current_screen->top_left_x[SCREEN_HEIGHT (s) - 1] = leftmost;
-         current_screen->top_left_y[SCREEN_HEIGHT (s) - 1]
-           = PIXEL_HEIGHT (s) - s->display.x->internal_border_width
-             - LINE_HEIGHT(s, SCREEN_HEIGHT (s) - 1);
-         current_screen->top_left_x[0] = leftmost;
-         current_screen->top_left_y[0] = downto;
+         current_frame->top_left_x[FRAME_HEIGHT (f) - 1] = leftmost;
+         current_frame->top_left_y[FRAME_HEIGHT (f) - 1]
+           = PIXEL_HEIGHT (f) - f->display.x->internal_border_width
+             - current_frame->pix_height[FRAME_HEIGHT (f) - 1];
+         current_frame->top_left_x[0] = leftmost;
+         current_frame->top_left_y[0] = downto;
        }
     }
 #endif /* HAVE_X_WINDOWS */
 
   /* Now update the rest of the lines. */
-  for (i = 0; i < SCREEN_HEIGHT (s) - 1 && (force || !input_pending); i++)
+  for (i = 0; i < FRAME_HEIGHT (f) - 1 && (force || !input_pending); i++)
     {
-      if (desired_screen->enable[i])
+      if (desired_frame->enable[i])
        {
-         if (SCREEN_IS_TERMCAP (s))
+         if (FRAME_TERMCAP_P (f))
            {
              /* Flush out every so many lines.
                 Also flush out if likely to have more than 1k buffered
@@ -1046,54 +1054,83 @@ update_screen (s, force, inhibit_hairy_id)
                  fflush (stdout);
                  if (preempt_count == 1)
                    {
-#ifdef TIOCOUTQ
-                     if (ioctl (0, TIOCOUTQ, &outq) < 0)
+#ifdef EMACS_OUTQSIZE
+                     if (EMACS_OUTQSIZE (0, &outq) < 0)
                        /* Probably not a tty.  Ignore the error and reset
                         * the outq count. */
                        outq = PENDING_OUTPUT_COUNT (stdout);
 #endif
                      outq *= 10;
-                     sleep (outq / baud_rate);
+                     if (baud_rate > 0)
+                       sleep (outq / baud_rate);
                    }
                }
              if ((i - 1) % preempt_count == 0)
                detect_input_pending ();
            }
 
-         update_line (s, i);
+         update_line (f, i);
 #ifdef HAVE_X_WINDOWS
-         if (SCREEN_IS_X (s))
+         if (FRAME_X_P (f))
            {
-             current_screen->top_left_y[i] = downto;
-             current_screen->top_left_x[i] = leftmost;
+             current_frame->top_left_y[i] = downto;
+             current_frame->top_left_x[i] = leftmost;
            }
 #endif /* HAVE_X_WINDOWS */
        }
 
-      if (SCREEN_IS_X (s))
-       downto += LINE_HEIGHT(s, i);
+#ifdef HAVE_X_WINDOWS
+      if (FRAME_X_P (f))
+       downto += current_frame->pix_height[i];
+#endif
     }
-  pause = (i < SCREEN_HEIGHT (s) - 1) ? i : 0;
+  pause = (i < FRAME_HEIGHT (f) - 1) ? i : 0;
 
   /* Now just clean up termcap drivers and set cursor, etc.  */
   if (!pause)
     {
+      if (cursor_in_echo_area
+         && FRAME_HAS_MINIBUF_P (f))
+       {
+         int top = XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top);
+         int row, col;
 
-      if (s == selected_screen && cursor_in_echo_area < 0)
-       cursor_to (SCREEN_HEIGHT (s) - 1, 0);
-      else if (s == selected_screen && cursor_in_echo_area
-              && !desired_screen->used[SCREEN_HEIGHT (s) - 1])
-       cursor_to (SCREEN_HEIGHT (s), 0);
-      else if (cursor_in_echo_area)
-       cursor_to (SCREEN_HEIGHT (s) - 1,
-                  min (SCREEN_WIDTH (s) - 1,
-                       desired_screen->used[SCREEN_HEIGHT (s) - 1]));
+         if (cursor_in_echo_area < 0)
+           {
+             row = top;
+             col = 0;
+           }
+         else
+           {
+             /* If the minibuffer is several lines high, find the last
+                line that has any text on it.  */
+             row = FRAME_HEIGHT (f);
+             do 
+               {
+                 row--;
+                 if (current_frame->enable[row])
+                   col = current_frame->used[row];
+                 else
+                   col = 0;
+               }
+             while (row > top && col == 0);
+
+             if (col >= FRAME_WIDTH (f))
+               {
+                 col = 0;
+                 if (row < FRAME_HEIGHT (f) - 1)
+                   row++;
+               }
+           }
+
+         cursor_to (row, col);
+       }
       else
-       cursor_to (SCREEN_CURSOR_Y (s), max (min (SCREEN_CURSOR_X (s),
-                                                 SCREEN_WIDTH (s) - 1), 0));
+       cursor_to (FRAME_CURSOR_Y (f), max (min (FRAME_CURSOR_X (f),
+                                                 FRAME_WIDTH (f) - 1), 0));
     }
 
-  update_end (s);
+  update_end (f);
 
   if (termscript)
     fflush (termscript);
@@ -1102,10 +1139,10 @@ update_screen (s, force, inhibit_hairy_id)
   /* Here if output is preempted because input is detected.  */
  do_pause:
 
-  if (SCREEN_HEIGHT (s) == 0) abort (); /* Some bug zeros some core */
+  if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */
   display_completed = !pause;
 
-  bzero (desired_screen->enable, SCREEN_HEIGHT (s));
+  bzero (desired_frame->enable, FRAME_HEIGHT (f));
   return pause;
 }
 
@@ -1115,11 +1152,11 @@ update_screen (s, force, inhibit_hairy_id)
 void
 quit_error_check ()
 {
-  if (SCREEN_DESIRED_GLYPHS (selected_screen) == 0)
+  if (FRAME_DESIRED_GLYPHS (selected_frame) == 0)
     return;
-  if (SCREEN_DESIRED_GLYPHS (selected_screen)->enable[0])
+  if (FRAME_DESIRED_GLYPHS (selected_frame)->enable[0])
     abort ();
-  if (SCREEN_DESIRED_GLYPHS (selected_screen)->enable[SCREEN_HEIGHT (selected_screen) - 1])
+  if (FRAME_DESIRED_GLYPHS (selected_frame)->enable[FRAME_HEIGHT (selected_frame) - 1])
     abort ();
 }
 \f
@@ -1127,19 +1164,19 @@ quit_error_check ()
 
 extern void scrolling_1 ();
 
-scrolling (screen)
-     SCREEN_PTR screen;
+scrolling (frame)
+     FRAME_PTR frame;
 {
   int unchanged_at_top, unchanged_at_bottom;
   int window_size;
   int changed_lines;
-  int *old_hash = (int *) alloca (SCREEN_HEIGHT (screen) * sizeof (int));
-  int *new_hash = (int *) alloca (SCREEN_HEIGHT (screen) * sizeof (int));
-  int *draw_cost = (int *) alloca (SCREEN_HEIGHT (screen) * sizeof (int));
+  int *old_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
+  int *new_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
+  int *draw_cost = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
   register int i;
-  int free_at_end_vpos = SCREEN_HEIGHT (screen);
-  register struct screen_glyphs *current_screen = SCREEN_CURRENT_GLYPHS (screen);
-  register struct screen_glyphs *desired_screen = SCREEN_DESIRED_GLYPHS (screen);
+  int free_at_end_vpos = FRAME_HEIGHT (frame);
+  register struct frame_glyphs *current_frame = FRAME_CURRENT_GLYPHS (frame);
+  register struct frame_glyphs *desired_frame = FRAME_DESIRED_GLYPHS (frame);
 
   /* Compute hash codes of all the lines.
      Also calculate number of changed lines,
@@ -1148,51 +1185,51 @@ scrolling (screen)
 
   changed_lines = 0;
   unchanged_at_top = 0;
-  unchanged_at_bottom = SCREEN_HEIGHT (screen);
-  for (i = 0; i < SCREEN_HEIGHT (screen); i++)
+  unchanged_at_bottom = FRAME_HEIGHT (frame);
+  for (i = 0; i < FRAME_HEIGHT (frame); i++)
     {
       /* Give up on this scrolling if some old lines are not enabled.  */
-      if (!current_screen->enable[i])
+      if (!current_frame->enable[i])
        return 0;
-      old_hash[i] = line_hash_code (current_screen, i);
-      if (! desired_screen->enable[i])
+      old_hash[i] = line_hash_code (current_frame, i);
+      if (! desired_frame->enable[i])
        new_hash[i] = old_hash[i];
       else
-       new_hash[i] = line_hash_code (desired_screen, i);
+       new_hash[i] = line_hash_code (desired_frame, i);
 
       if (old_hash[i] != new_hash[i])
        {
          changed_lines++;
-         unchanged_at_bottom = SCREEN_HEIGHT (screen) - i - 1;
+         unchanged_at_bottom = FRAME_HEIGHT (frame) - i - 1;
        }
       else if (i == unchanged_at_top)
        unchanged_at_top++;
-      draw_cost[i] = line_draw_cost (desired_screen, i);
+      draw_cost[i] = line_draw_cost (desired_frame, i);
     }
 
   /* If changed lines are few, don't allow preemption, don't scroll.  */
   if (changed_lines < baud_rate / 2400
-      || unchanged_at_bottom == SCREEN_HEIGHT (screen))
+      || unchanged_at_bottom == FRAME_HEIGHT (frame))
     return 1;
 
-  window_size = (SCREEN_HEIGHT (screen) - unchanged_at_top
+  window_size = (FRAME_HEIGHT (frame) - unchanged_at_top
                 - unchanged_at_bottom);
 
   if (scroll_region_ok)
     free_at_end_vpos -= unchanged_at_bottom;
-  else if (memory_below_screen)
+  else if (memory_below_frame)
     free_at_end_vpos = -1;
 
   /* If large window, fast terminal and few lines in common between
-     current screen and desired screen, don't bother with i/d calc. */
+     current frame and desired frame, don't bother with i/d calc. */
   if (window_size >= 18 && baud_rate > 2400
       && (window_size >=
          10 * scrolling_max_lines_saved (unchanged_at_top,
-                                         SCREEN_HEIGHT (screen) - unchanged_at_bottom,
+                                         FRAME_HEIGHT (frame) - unchanged_at_bottom,
                                          old_hash, new_hash, draw_cost)))
     return 0;
 
-  scrolling_1 (screen, window_size, unchanged_at_top, unchanged_at_bottom,
+  scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom,
               draw_cost + unchanged_at_top - 1,
               old_hash + unchanged_at_top - 1,
               new_hash + unchanged_at_top - 1,
@@ -1211,64 +1248,39 @@ buffer_posn_from_coords (window, col, line)
   int window_left = XFASTINT (window->left);
 
   /* The actual width of the window is window->width less one for the
-     \ which ends wrapped lines, and less one if it's not the
-     rightmost window.  */
-  int window_width = (XFASTINT (window->width) - 1
-                     - (XFASTINT (window->width) + window_left
-                        != SCREEN_WIDTH (XSCREEN (window->screen))));
+     DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
+     window.  */
+  int window_width = window_internal_width (window) - 1;
 
-  /* The screen's list of buffer positions of line starts.  */
-  int *bufp = SCREEN_CURRENT_GLYPHS (XSCREEN (window->screen))->bufp;
+  int startp = marker_position (window->start);
 
   /* Since compute_motion will only operate on the current buffer,
      we need to save the old one and restore it when we're done.  */
   struct buffer *old_current_buffer = current_buffer;
-  int posn;
+  struct position *posn;
 
   current_buffer = XBUFFER (window->buffer);
 
-  { 
-    /* compute_motion will find the buffer position corresponding to a
-       screen position, given a buffer position to start at and its
-       screen position, by scanning from the start to the goal.  In
-       order to make this faster, we need to choose a starting buffer
-       position with a known screen position as close to the goal as
-       possible.
-
-       The bufp array in the screen_glyphs structure gives the buffer
-       position of the first character on each screen line.  This
-       would be a perfect starting location, except that there's no
-       way to know if this character really starts flush with the
-       beginning of the line or if it is being continued from the
-       previous line; characters like ?\M-x display as \370 and can
-       wrap off the end of one line onto the next.
-
-       So what we do is start on the target line, and scan upwards
-       until we find a screen line that starts right after a newline
-       in the buffer, or at the top of the window; both of these
-       assure us that the character at bufp starts flush with the
-       beginning of the line.  */
-    int i;
-
-    /* Only works for the leftmost window on a line.  bufp is useless
-       for the others.  */
-    if (window_left == 0)
-      {
-       for (i = line; i > XFASTINT (window->top); i--)
-         if (FETCH_CHAR (bufp[i]-1) == '\n')
-           break;
-      }
-
-    posn
-      = compute_motion (bufp[i], i, window_left,
-                       ZV, col, line,
-                       window_width, XINT (window->hscroll), 0)
-       ->bufpos;
-  }
+  /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
+     (window->frame))->bufp to avoid scanning from the very top of
+     the window, but it isn't maintained correctly, and I'm not even
+     sure I will keep it.  */
+  posn = compute_motion (startp, 0,
+                        (window == XWINDOW (minibuf_window) && startp == 1
+                         ? minibuf_prompt_width : 0),
+                        ZV, line, col,
+                        window_width, XINT (window->hscroll), 0);
 
   current_buffer = old_current_buffer;
 
-  return posn;
+  /* compute_motion considers frame points past the end of a line
+     to be *after* the newline, i.e. at the start of the next line.
+     This is reasonable, but not really what we want.  So if the
+     result is on a line below LINE, back it up one character.  */
+  if (posn->vpos > line)
+    return posn->bufpos - 1;
+  else
+    return posn->bufpos;
 }
 \f
 static int
@@ -1276,8 +1288,8 @@ count_blanks (r)
      register GLYPH *r;
 {
   register GLYPH *p = r;
-  while (*r++ == SPACEGLYPH);
-  return r - p - 1;
+  while (*p++ == SPACEGLYPH);
+  return p - r - 1;
 }
 
 static int
@@ -1293,42 +1305,42 @@ count_match (str1, str2)
 /* Char insertion/deletion cost vector, from term.c */
 extern int *char_ins_del_vector;
 
-#define char_ins_del_cost(s) (&char_ins_del_vector[SCREEN_HEIGHT((s))])
+#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH((f))])
 
 static void
-update_line (screen, vpos)
-     register SCREEN_PTR screen;
+update_line (frame, vpos)
+     register FRAME_PTR frame;
      int vpos;
 {
   register GLYPH *obody, *nbody, *op1, *op2, *np1, *temp;
   int tem;
   int osp, nsp, begmatch, endmatch, olen, nlen;
   int save;
-  register struct screen_glyphs *current_screen
-    = SCREEN_CURRENT_GLYPHS (screen);
-  register struct screen_glyphs *desired_screen
-    = SCREEN_DESIRED_GLYPHS (screen);
+  register struct frame_glyphs *current_frame
+    = FRAME_CURRENT_GLYPHS (frame);
+  register struct frame_glyphs *desired_frame
+    = FRAME_DESIRED_GLYPHS (frame);
 
-  if (desired_screen->highlight[vpos]
-      != (current_screen->enable[vpos] && current_screen->highlight[vpos]))
+  if (desired_frame->highlight[vpos]
+      != (current_frame->enable[vpos] && current_frame->highlight[vpos]))
     {
-      change_line_highlight (desired_screen->highlight[vpos], vpos,
-                            (current_screen->enable[vpos] ?
-                             current_screen->used[vpos] : 0));
-      current_screen->enable[vpos] = 0;
+      change_line_highlight (desired_frame->highlight[vpos], vpos,
+                            (current_frame->enable[vpos] ?
+                             current_frame->used[vpos] : 0));
+      current_frame->enable[vpos] = 0;
     }
   else
-    reassert_line_highlight (desired_screen->highlight[vpos], vpos);
+    reassert_line_highlight (desired_frame->highlight[vpos], vpos);
 
-  if (! current_screen->enable[vpos])
+  if (! current_frame->enable[vpos])
     {
       olen = 0;
     }
   else
     {
-      obody = current_screen->glyphs[vpos];
-      olen = current_screen->used[vpos];
-      if (! current_screen->highlight[vpos])
+      obody = current_frame->glyphs[vpos];
+      olen = current_frame->used[vpos];
+      if (! current_frame->highlight[vpos])
        {
          if (!must_write_spaces)
            while (obody[olen - 1] == SPACEGLYPH && olen > 0)
@@ -1337,43 +1349,43 @@ update_line (screen, vpos)
       else
        {
          /* For an inverse-video line, remember we gave it
-            spaces all the way to the screen edge
+            spaces all the way to the frame edge
             so that the reverse video extends all the way across.  */
 
-         while (olen < SCREEN_WIDTH (screen) - 1)
+         while (olen < FRAME_WIDTH (frame) - 1)
            obody[olen++] = SPACEGLYPH;
        }
     }
 
   /* One way or another, this will enable the line being updated.  */
-  current_screen->enable[vpos] = 1;
-  current_screen->used[vpos] = desired_screen->used[vpos];
-  current_screen->highlight[vpos] = desired_screen->highlight[vpos];
-  current_screen->bufp[vpos] = desired_screen->bufp[vpos];
+  current_frame->enable[vpos] = 1;
+  current_frame->used[vpos] = desired_frame->used[vpos];
+  current_frame->highlight[vpos] = desired_frame->highlight[vpos];
+  current_frame->bufp[vpos] = desired_frame->bufp[vpos];
 
 #ifdef HAVE_X_WINDOWS
-  if (SCREEN_IS_X (screen))
+  if (FRAME_X_P (frame))
     {
-      current_screen->pix_width[vpos]
-       = current_screen->used[vpos]
-         * FONT_WIDTH (screen->display.x->font);
-      current_screen->pix_height[vpos]
-       = FONT_HEIGHT (screen->display.x->font);
+      current_frame->pix_width[vpos]
+       = current_frame->used[vpos]
+         * FONT_WIDTH (frame->display.x->font);
+      current_frame->pix_height[vpos]
+       = FONT_HEIGHT (frame->display.x->font);
     }
 #endif /* HAVE_X_WINDOWS */
 
-  if (!desired_screen->enable[vpos])
+  if (!desired_frame->enable[vpos])
     {
       nlen = 0;
       goto just_erase;
     }
 
-  nbody = desired_screen->glyphs[vpos];
-  nlen = desired_screen->used[vpos];
+  nbody = desired_frame->glyphs[vpos];
+  nlen = desired_frame->used[vpos];
 
   /* Pretend trailing spaces are not there at all,
      unless for one reason or another we must write all spaces.  */
-  if (! desired_screen->highlight[vpos])
+  if (! desired_frame->highlight[vpos])
     {
       if (!must_write_spaces)
        /* We know that the previous character byte contains 0.  */
@@ -1383,10 +1395,10 @@ update_line (screen, vpos)
   else
     {
       /* For an inverse-video line, give it extra trailing spaces
-        all the way to the screen edge
+        all the way to the frame edge
         so that the reverse video extends all the way across.  */
 
-      while (nlen < SCREEN_WIDTH (screen) - 1)
+      while (nlen < FRAME_WIDTH (frame) - 1)
        nbody[nlen++] = SPACEGLYPH;
     }
 
@@ -1395,6 +1407,25 @@ update_line (screen, vpos)
     {
       int i,j;
 
+#if 0
+      if (FRAME_X_P (frame))
+       {
+         /* Under X, erase everything we are going to rewrite,
+            and rewrite everything from the first char that's changed.
+            This is part of supporting fonts like Courier
+            whose chars can overlap outside the char width.  */
+         for (i = 0; i < nlen; i++)
+           if (i >= olen || nbody[i] != obody[i])
+             break;
+
+         cursor_to (vpos, i);
+         if (i != olen)
+           clear_end_of_line (olen);
+         write_glyphs (nbody + i, nlen - i);
+       }
+      else
+       {}
+#endif /* 0 */
       for (i = 0; i < nlen; i++)
        {
          if (i >= olen || nbody[i] != obody[i])    /* A non-matching char. */
@@ -1419,17 +1450,17 @@ update_line (screen, vpos)
          clear_end_of_line (olen);
        }
 
-      /* Exchange contents between current_screen and new_screen.  */
-      temp = desired_screen->glyphs[vpos];
-      desired_screen->glyphs[vpos] = current_screen->glyphs[vpos];
-      current_screen->glyphs[vpos] = temp;
+      /* Exchange contents between current_frame and new_frame.  */
+      temp = desired_frame->glyphs[vpos];
+      desired_frame->glyphs[vpos] = current_frame->glyphs[vpos];
+      current_frame->glyphs[vpos] = temp;
 
       return;
     }
 
   if (!olen)
     {
-      nsp = (must_write_spaces || desired_screen->highlight[vpos])
+      nsp = (must_write_spaces || desired_frame->highlight[vpos])
              ? 0 : count_blanks (nbody);
       if (nlen > nsp)
        {
@@ -1437,10 +1468,10 @@ update_line (screen, vpos)
          write_glyphs (nbody + nsp, nlen - nsp);
        }
 
-      /* Exchange contents between current_screen and new_screen.  */
-      temp = desired_screen->glyphs[vpos];
-      desired_screen->glyphs[vpos] = current_screen->glyphs[vpos];
-      current_screen->glyphs[vpos] = temp;
+      /* Exchange contents between current_frame and new_frame.  */
+      temp = desired_frame->glyphs[vpos];
+      desired_frame->glyphs[vpos] = current_frame->glyphs[vpos];
+      current_frame->glyphs[vpos] = temp;
 
       return;
     }
@@ -1451,7 +1482,7 @@ update_line (screen, vpos)
 
   /* Compute number of leading blanks in old and new contents.  */
   osp = count_blanks (obody);
-  if (!desired_screen->highlight[vpos])
+  if (!desired_frame->highlight[vpos])
     nsp = count_blanks (nbody);
   else
     nsp = 0;
@@ -1498,7 +1529,7 @@ update_line (screen, vpos)
 
   tem = (nlen - nsp) - (olen - osp);
   if (endmatch && tem
-      && (!char_ins_del_ok || endmatch <= char_ins_del_cost (screen)[tem]))
+      && (!char_ins_del_ok || endmatch <= char_ins_del_cost (frame)[tem]))
     endmatch = 0;
 
   /* nsp - osp is the distance to insert or delete.
@@ -1508,7 +1539,7 @@ update_line (screen, vpos)
 
   if (nsp != osp
       && (!char_ins_del_ok
-         || begmatch + endmatch <= char_ins_del_cost (screen)[nsp - osp]))
+         || begmatch + endmatch <= char_ins_del_cost (frame)[nsp - osp]))
     {
       begmatch = 0;
       endmatch = 0;
@@ -1549,7 +1580,7 @@ update_line (screen, vpos)
             there is no need to do clear-to-eol at the end.
             (and it would not be safe, since cursor is not
             going to be "at the margin" after the text is done) */
-         if (nlen == SCREEN_WIDTH (screen))
+         if (nlen == FRAME_WIDTH (frame))
            olen = 0;
          write_glyphs (nbody + nsp + begmatch, nlen - tem);
 
@@ -1563,7 +1594,7 @@ update_line (screen, vpos)
             it will lose one way or another (depending on AutoWrap)
             to clear to end of line after outputting all the text.
             So pause with one character to go and clear the line then.  */
-         if (nlen == SCREEN_WIDTH (screen) && fast_clear_end_of_line && olen > nlen)
+         if (nlen == FRAME_WIDTH (frame) && fast_clear_end_of_line && olen > nlen)
            {
              /* endmatch must be zero, and tem must equal nsp + begmatch */
              write_glyphs (nbody + tem, nlen - tem - 1);
@@ -1598,10 +1629,10 @@ update_line (screen, vpos)
       clear_end_of_line (olen);
     }
 
-  /* Exchange contents between current_screen and new_screen.  */
-  temp = desired_screen->glyphs[vpos];
-  desired_screen->glyphs[vpos] = current_screen->glyphs[vpos];
-  current_screen->glyphs[vpos] = temp;
+  /* Exchange contents between current_frame and new_frame.  */
+  temp = desired_frame->glyphs[vpos];
+  desired_frame->glyphs[vpos] = current_frame->glyphs[vpos];
+  current_frame->glyphs[vpos] = temp;
 }
 \f
 DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
@@ -1614,7 +1645,7 @@ FILE = nil means just close any termscript file currently open.")
   if (termscript != 0) fclose (termscript);
   termscript = 0;
 
-  if (! NULL (file))
+  if (! NILP (file))
     {
       file = Fexpand_file_name (file, Qnil);
       termscript = fopen (XSTRING (file)->data, "w");
@@ -1626,33 +1657,30 @@ FILE = nil means just close any termscript file currently open.")
 \f
 
 #ifdef SIGWINCH
+SIGTYPE
 window_change_signal ()
 {
   int width, height;
   extern int errno;
   int old_errno = errno;
 
-  get_screen_size (&width, &height);
+  get_frame_size (&width, &height);
 
-  /* The screen size change obviously applies to a termcap-controlled
-     screen.  Find such a screen in the list, and assume it's the only
+  /* The frame size change obviously applies to a termcap-controlled
+     frame.  Find such a frame in the list, and assume it's the only
      one (since the redisplay code always writes to stdout, not a
-     FILE * specified in the screen structure).  Record the new size,
+     FILE * specified in the frame structure).  Record the new size,
      but don't reallocate the data structures now.  Let that be done
      later outside of the signal handler.  */
 
   {
-    Lisp_Object tail;
+    Lisp_Object tail, frame;
 
-    for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
+    FOR_EACH_FRAME (tail, frame)
       {
-       SCREEN_PTR s = XSCREEN (XCONS (tail)->car);
-       
-       if (s->output_method == output_termcap)
+       if (FRAME_TERMCAP_P (XFRAME (frame)))
          {
-           ++in_display;
-           change_screen_size (s, height, width, 0);
-           --in_display;
+           change_frame_size (XFRAME (frame), height, width, 0, 1);
            break;
          }
       }
@@ -1664,113 +1692,121 @@ window_change_signal ()
 #endif /* SIGWINCH */
 
 
-/* Do any change in screen size that was requested by a signal.  */
+/* Do any change in frame size that was requested by a signal.  */
 
 do_pending_window_change ()
 {
   /* If window_change_signal should have run before, run it now.  */
   while (delayed_size_change)
     {
-      Lisp_Object tail;
+      Lisp_Object tail, frame;
 
       delayed_size_change = 0;
 
-      for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
+      FOR_EACH_FRAME (tail, frame)
        {
-         SCREEN_PTR s = XSCREEN (XCONS (tail)->car);
-         int height = SCREEN_NEW_HEIGHT (s);
-         int width = SCREEN_NEW_WIDTH (s);
-           
-         SCREEN_NEW_HEIGHT (s) = 0;
-         SCREEN_NEW_WIDTH (s) = 0;
-
-         if (height != 0)
-           change_screen_size (s, height, width, 0);
+         FRAME_PTR f = XFRAME (frame);
+
+         int height = FRAME_NEW_HEIGHT (f);
+         int width = FRAME_NEW_WIDTH (f);
+
+         if (height != 0 || width != 0)
+           change_frame_size (f, height, width, 0, 0);
        }
     }
 }
 
 
-/* Change the screen height and/or width.  Values may be given as zero to
-   indicate no change is to take place. */
+/* Change the frame height and/or width.  Values may be given as zero to
+   indicate no change is to take place. 
+
+   If DELAY is non-zero, then assume we're being called from a signal
+   handler, and queue the change for later - perhaps the next
+   redisplay.  Since this tries to resize windows, we can't call it
+   from a signal handler.  */
 
-change_screen_size (screen, newlength, newwidth, pretend)
-     register SCREEN_PTR screen;
-     register int newlength, newwidth, pretend;
+change_frame_size (frame, newheight, newwidth, pretend, delay)
+     register FRAME_PTR frame;
+     int newheight, newwidth, pretend;
 {
   /* If we can't deal with the change now, queue it for later.  */
-  if (in_display)
+  if (delay)
     {
-      SCREEN_NEW_HEIGHT (screen) = newlength;
-      SCREEN_NEW_WIDTH (screen) = newwidth;
+      FRAME_NEW_HEIGHT (frame) = newheight;
+      FRAME_NEW_WIDTH (frame) = newwidth;
       delayed_size_change = 1;
       return;
     }
 
-  /* This size-change overrides any pending one for this screen.  */
-  SCREEN_NEW_HEIGHT (screen) = 0;
-  SCREEN_NEW_WIDTH (screen) = 0;
+  /* This size-change overrides any pending one for this frame.  */
+  FRAME_NEW_HEIGHT (frame) = 0;
+  FRAME_NEW_WIDTH  (frame) = 0;
+
+  /* If an argument is zero, set it to the current value.  */
+  newheight || (newheight = FRAME_HEIGHT (frame));
+  newwidth  || (newwidth  = FRAME_WIDTH  (frame));
 
-  if ((newlength == 0 || newlength == SCREEN_HEIGHT (screen))
-      && (newwidth == 0 || newwidth == SCREEN_WIDTH (screen)))
+  /* Round up to the smallest acceptable size.  */
+  check_frame_size (frame, &newheight, &newwidth);
+
+  /* If we're not changing the frame size, quit now.  */
+  if (newheight == FRAME_HEIGHT (frame)
+      && newwidth == FRAME_WIDTH (frame))
     return;
 
-  if (newlength && newlength != SCREEN_HEIGHT (screen))
+  if (newheight != FRAME_HEIGHT (frame))
     {
-      if (XSCREEN (WINDOW_SCREEN (XWINDOW (SCREEN_MINIBUF_WINDOW (screen))))
-         == screen
-         && ! EQ (SCREEN_MINIBUF_WINDOW (screen),
-                  SCREEN_ROOT_WINDOW (screen)))
+      if (FRAME_HAS_MINIBUF_P (frame)
+         && ! FRAME_MINIBUF_ONLY_P (frame))
        {
-         /* Screen has both root and minibuffer.  */
-         set_window_height (SCREEN_ROOT_WINDOW (screen),
-                            newlength - 1, 0);
-         XFASTINT (XWINDOW (SCREEN_MINIBUF_WINDOW (screen))->top)
-           = newlength - 1;
-         set_window_height (SCREEN_MINIBUF_WINDOW (screen), 1, 0);
+         /* Frame has both root and minibuffer.  */
+         set_window_height (FRAME_ROOT_WINDOW (frame),
+                            newheight - 1 - FRAME_MENU_BAR_LINES (frame), 0);
+         XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame))->top)
+           = newheight - 1;
+         set_window_height (FRAME_MINIBUF_WINDOW (frame), 1, 0);
        }
       else
-       /* Screen has just one top-level window.  */
-       set_window_height (SCREEN_ROOT_WINDOW (screen), newlength, 0);
-       
-      if (SCREEN_IS_TERMCAP (screen) == output_termcap && !pretend)
-       ScreenRows = newlength;
+       /* Frame has just one top-level window.  */
+       set_window_height (FRAME_ROOT_WINDOW (frame),
+                          newheight - FRAME_MENU_BAR_LINES (frame), 0);
+
+      if (FRAME_TERMCAP_P (frame) && !pretend)
+       FrameRows = newheight;
 
 #if 0
-      if (screen->output_method == output_termcap)
+      if (frame->output_method == output_termcap)
        {
-         screen_height = newlength;
+         frame_height = newheight;
          if (!pretend)
-           ScreenRows = newlength;
+           FrameRows = newheight;
        }
 #endif
     }
 
-  if (newwidth && newwidth != SCREEN_WIDTH (screen))
+  if (newwidth != FRAME_WIDTH (frame))
     {
-      set_window_width (SCREEN_ROOT_WINDOW (screen), newwidth, 0);
-      if (XSCREEN (WINDOW_SCREEN (XWINDOW (SCREEN_MINIBUF_WINDOW (screen))))
-         == screen)
-       set_window_width (SCREEN_MINIBUF_WINDOW (screen), newwidth, 0);
-      SCREEN_WIDTH (screen) = newwidth;
-
-      if (SCREEN_IS_TERMCAP (screen) && !pretend)
-       ScreenCols = newwidth;
+      set_window_width (FRAME_ROOT_WINDOW (frame), newwidth, 0);
+      if (FRAME_HAS_MINIBUF_P (frame))
+       set_window_width (FRAME_MINIBUF_WINDOW (frame), newwidth, 0);
+
+      if (FRAME_TERMCAP_P (frame) && !pretend)
+       FrameCols = newwidth;
 #if 0
-      if (screen->output_method == output_termcap)
+      if (frame->output_method == output_termcap)
        {
-         screen_width = newwidth;
+         frame_width = newwidth;
          if (!pretend)
-           ScreenCols = newwidth;
+           FrameCols = newwidth;
        }
 #endif
     }
 
-  if (newlength)
-    SCREEN_HEIGHT (screen) = newlength;
-
-  remake_screen_glyphs (screen);
-  calculate_costs (screen);
+  FRAME_HEIGHT (frame) = newheight;
+  FRAME_WIDTH (frame)  = newwidth;
+       
+  remake_frame_glyphs (frame);
+  calculate_costs (frame);
 }
 \f
 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
@@ -1798,9 +1834,12 @@ terminate any keyboard macro currently executing.")
   (arg)
   Lisp_Object arg;
 {
-  if (!NULL (arg))
+  if (!NILP (arg))
     {
-      ring_bell ();
+      if (noninteractive)
+       putchar (07);
+      else
+       ring_bell ();
       fflush (stdout);
     }
   else
@@ -1821,38 +1860,65 @@ bitch_at_user ()
 }
 
 DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
-  "Pause, without updating display, for ARG seconds.\n\
-Optional second arg non-nil means ARG is measured in milliseconds.\n\
-\(Not all operating systems support milliseconds.)")
-  (n, millisec)
-     Lisp_Object n, millisec;
+  "Pause, without updating display, for SECONDS seconds.\n\
+SECONDS may be a floating-point value, meaning that you can wait for a\n\
+fraction of a second.  Optional second arg MILLISECONDS specifies an\n\
+additional wait period, in milliseconds; this may be useful if your\n\
+Emacs was built without floating point support.\n\
+\(Not all operating systems support waiting for a fraction of a second.)")
+  (seconds, milliseconds)
+     Lisp_Object seconds, milliseconds;
 {
-#ifndef subprocesses
-#ifdef HAVE_TIMEVAL
-  struct timeval timeout, end_time, garbage1;
-#endif /* HAVE_TIMEVAL */
-#endif /* no subprocesses */
-  int usec = 0;
-  int sec;
+  int sec, usec;
 
-  CHECK_NUMBER (n, 0);
-  sec = XINT (n);
-  if (sec <= 0)
-    return Qnil;
+  if (NILP (milliseconds))
+    XSET (milliseconds, Lisp_Int, 0);
+  else
+    CHECK_NUMBER (milliseconds, 1);
+  usec = XINT (milliseconds) * 1000;
 
-  if (!NULL (millisec))
-    {
-#ifndef HAVE_TIMEVAL
-      error ("millisecond sit-for not supported on %s", SYSTEM_TYPE);
+#ifdef LISP_FLOAT_TYPE
+  {
+    double duration = extract_float (seconds);
+    sec = (int) duration;
+    usec += (duration - sec) * 1000000;
+  }
 #else
-      usec = sec % 1000 * 1000;
-      sec /= 1000;
+  CHECK_NUMBER (seconds, 0);
+  sec = XINT (seconds);
 #endif
+
+#ifndef EMACS_HAS_USECS
+  if (sec == 0 && usec != 0)
+    error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE);
+#endif
+
+  /* Assure that 0 <= usec < 1000000.  */
+  if (usec < 0)
+    {
+      /* We can't rely on the rounding being correct if user is negative.  */
+      if (-1000000 < usec)
+       sec--, usec += 1000000;
+      else
+       sec -= -usec / 1000000, usec = 1000000 - (-usec % 1000000);
     }
+  else
+    sec += usec / 1000000, usec %= 1000000;
+
+  if (sec <= 0)
+    return Qnil;
+
+  {
+    Lisp_Object zero;
+
+    XFASTINT (zero) = 0;
+    wait_reading_process_input (sec, usec, zero, 0);
+  }
 
-#ifdef subprocesses
-  wait_reading_process_input (sec, usec, 0, 0);
-#else /* No subprocesses */
+  /* We should always have wait_reading_process_input; we have a dummy
+     implementation for systems which don't support subprocesses.  */
+#if 0
+  /* No wait_reading_process_input */
   immediate_quit = 1;
   QUIT;
 
@@ -1863,29 +1929,18 @@ Optional second arg non-nil means ARG is measured in milliseconds.\n\
     (rather than defined (H_S) && defined (H_T))
    is because the VMS preprocessor doesn't grok `defined' */
 #ifdef HAVE_SELECT
-#ifdef HAVE_TIMEVAL
-  gettimeofday (&end_time, &garbage1);
-  end_time.tv_sec += sec;
-  end_time.tv_usec += usec;
-  if (end_time.tv_usec >= 1000000)
-    end_time.tv_sec++, end_time.tv_usec -= 1000000;
-
+  EMACS_GET_TIME (end_time);
+  EMACS_SET_SECS_USECS (timeout, sec, usec);
+  EMACS_ADD_TIME (end_time, end_time, timeout);
   while (1)
     {
-      gettimeofday (&timeout, &garbage1);
-      timeout.tv_sec = end_time.tv_sec - timeout.tv_sec;
-      timeout.tv_usec = end_time.tv_usec - timeout.tv_usec;
-      if (timeout.tv_usec < 0)
-       timeout.tv_usec += 1000000, timeout.tv_sec--;
-      if (timeout.tv_sec < 0)
-       break;
-      if (!select (1, 0, 0, 0, &timeout))
+      EMACS_GET_TIME (timeout);
+      EMACS_SUB_TIME (timeout, end_time, timeout);
+      if (EMACS_TIME_NEG_P (timeout)
+         || !select (1, 0, 0, 0, &timeout))
        break;
     }
-#else /* not HAVE_TIMEVAL */
-  /* Is it safe to quit out of `sleep'?  I'm afraid to trust it.  */
-  sleep (sec);
-#endif /* HAVE_TIMEVAL */
 #else /* not HAVE_SELECT */
   sleep (sec);
 #endif /* HAVE_SELECT */
@@ -1897,61 +1952,46 @@ Optional second arg non-nil means ARG is measured in milliseconds.\n\
   return Qnil;
 }
 
-DEFUN ("sit-for", Fsit_for, Ssit_for, 1, 3, 0,
-  "Perform redisplay, then wait for ARG seconds or until input is available.\n\
-Optional second arg non-nil means ARG counts in milliseconds.\n\
-Optional third arg non-nil means don't redisplay, just wait for input.\n\
-Redisplay is preempted as always if input arrives, and does not happen\n\
-if input is available before it starts.\n\
-Value is t if waited the full time with no input arriving.")
-  (n, millisec, nodisp)
-     Lisp_Object n, millisec, nodisp;
-{
-#ifndef subprocesses
-#ifdef HAVE_TIMEVAL
-  struct timeval timeout;
-#else
-  int timeout_sec;
-#endif
-  int waitchannels;
-#endif /* no subprocesses */
-  int usec = 0;
-  int sec;
+/* This is just like wait_reading_process_input, except that
+   it does the redisplay.
+
+   It's also just like Fsit_for, except that it can be used for
+   waiting for input as well.  */
 
-  CHECK_NUMBER (n, 0);
+Lisp_Object
+sit_for (sec, usec, reading, display)
+     int sec, usec, reading, display;
+{
+  Lisp_Object read_kbd;
 
   if (detect_input_pending ())
     return Qnil;
-  
-  if (EQ (nodisp, Qnil))
+
+  if (display)
     redisplay_preserve_echo_area ();
 
-  sec = XINT (n);
-  if (sec <= 0)
+  if (sec == 0 && usec == 0)
     return Qt;
 
-  if (!NULL (millisec))
-    {
-#ifndef HAVE_TIMEVAL
-      error ("millisecond sleep-for not supported on %s", SYSTEM_TYPE);
-#else
-      usec = sec % 1000 * 1000;
-      sec /= 1000;
+#ifdef SIGIO
+  gobble_input (0);
 #endif
-    }
 
-#ifdef subprocesses
-#ifdef SIGIO
-  gobble_input ();
-#endif                         /* SIGIO */
-  wait_reading_process_input (sec, usec, 1, 1);
-#else                          /* no subprocesses */
+  XSET (read_kbd, Lisp_Int, reading ? -1 : 1);
+  wait_reading_process_input (sec, usec, read_kbd, display);
+
+
+  /* wait_reading_process_input should always be available now; it is
+     simulated in a simple way on systems that don't support
+     subprocesses.  */
+#if 0
+  /* No wait_reading_process_input available.  */
   immediate_quit = 1;
   QUIT;
 
   waitchannels = 1;
 #ifdef VMS
-  input_wait_timeout (XINT (n));
+  input_wait_timeout (XINT (arg));
 #else                          /* not VMS */
 #ifndef HAVE_TIMEVAL
   timeout_sec = sec;
@@ -1964,25 +2004,50 @@ Value is t if waited the full time with no input arriving.")
 #endif /* not VMS */
 
   immediate_quit = 0;
-#endif /* no subprocesses */
+#endif 
 
   return detect_input_pending () ? Qnil : Qt;
 }
 
-DEFUN ("sleep-for-millisecs", Fsleep_for_millisecs, Ssleep_for_millisecs,
-  1, 1, 0,
-  "Pause, without updating display, for ARG milliseconds.")
-  (n)
-     Lisp_Object n;
+DEFUN ("sit-for", Fsit_for, Ssit_for, 1, 3, 0,
+  "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
+SECONDS may be a floating-point value, meaning that you can wait for a\n\
+fraction of a second.  Optional second arg MILLISECONDS specifies an\n\
+additional wait period, in milliseconds; this may be useful if your\n\
+Emacs was built without floating point support.\n\
+\(Not all operating systems support waiting for a fraction of a second.)\n\
+Optional third arg non-nil means don't redisplay, just wait for input.\n\
+Redisplay is preempted as always if input arrives, and does not happen\n\
+if input is available before it starts.\n\
+Value is t if waited the full time with no input arriving.")
+  (seconds, milliseconds, nodisp)
+     Lisp_Object seconds, milliseconds, nodisp;
 {
-#ifndef HAVE_TIMEVAL
-  error ("sleep-for-millisecs not supported on %s", SYSTEM_TYPE);
+  int sec, usec;
+
+  if (NILP (milliseconds))
+    XSET (milliseconds, Lisp_Int, 0);
+  else
+    CHECK_NUMBER (milliseconds, 1);
+  usec = XINT (milliseconds) * 1000;
+
+#ifdef LISP_FLOAT_TYPE
+  {
+    double duration = extract_float (seconds);
+    sec = (int) duration;
+    usec += (duration - sec) * 1000000;
+  }
 #else
-  CHECK_NUMBER (n, 0);
-  wait_reading_process_input (XINT (n) / 1000, XINT (n) % 1000 * 1000,
-                             0, 0);
-  return Qnil;
-#endif /* HAVE_TIMEVAL */
+  CHECK_NUMBER (seconds, 0);
+  sec = XINT (seconds);
+#endif
+
+#ifndef EMACS_HAS_USECS
+  if (usec != 0 && sec == 0)
+    error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE);
+#endif
+
+  return sit_for (sec, usec, 0, NILP (nodisp));
 }
 \f
 char *terminal_type;
@@ -2003,20 +2068,29 @@ init_display ()
   cursor_in_echo_area = 0;
   terminal_type = (char *) 0;
 
-  /* If the DISPLAY environment variable is set, try to use X, and
-     die with an error message if that doesn't work.  */
+  /* Now is the time to initialize this; it's used by init_sys_modes
+     during startup.  */
+  Vwindow_system = Qnil;
 
-  /* Check if we're using a window system here before trying to
-     initialize the terminal.  If we check the terminal first,
+  /* If the user wants to use a window system, we shouldn't bother
+     initializing the terminal.  This is especially important when the
+     terminal is so dumb that emacs gives up before and doesn't bother
+     using the window system.
 
-     If someone has indicated that they want
-     to use a window system, we shouldn't bother initializing the
-     terminal.  This is especially important when the terminal is so
-     dumb that emacs gives up before  and doesn't bother using the window
-     system.  */
+     If the DISPLAY environment variable is set, try to use X, and die
+     with an error message if that doesn't work.  */
 
 #ifdef HAVE_X_WINDOWS
-  if (!inhibit_window_system && (display_arg || egetenv ("DISPLAY")))
+  if (! display_arg)
+    {
+#ifdef VMS
+      display_arg = (getenv ("DECW$DISPLAY") != 0);
+#else
+      display_arg = (getenv ("DISPLAY") != 0);
+#endif
+    }
+
+  if (!inhibit_window_system && display_arg)
     {
       Vwindow_system = intern ("x");
 #ifdef HAVE_X11
@@ -2069,12 +2143,12 @@ For types not defined in VMS, use  define emacs_term \"TYPE\".\n\
 
   term_init (terminal_type);
 
-  remake_screen_glyphs (selected_screen);
-  calculate_costs (selected_screen);
+  remake_frame_glyphs (selected_frame);
+  calculate_costs (selected_frame);
 
   /* X and Y coordinates of the cursor between updates. */
-  SCREEN_CURSOR_X (selected_screen) = 0;
-  SCREEN_CURSOR_Y (selected_screen) = 0;
+  FRAME_CURSOR_X (selected_frame) = 0;
+  FRAME_CURSOR_Y (selected_frame) = 0;
 
 #ifdef SIGWINCH
 #ifndef CANNOT_DUMP
@@ -2086,8 +2160,8 @@ For types not defined in VMS, use  define emacs_term \"TYPE\".\n\
 \f
 syms_of_display ()
 {
-#ifdef MULTI_SCREEN
-  defsubr (&Sredraw_screen);
+#ifdef MULTI_FRAME
+  defsubr (&Sredraw_frame);
 #endif
   defsubr (&Sredraw_display);
   defsubr (&Sopen_termscript);
@@ -2101,14 +2175,14 @@ syms_of_display ()
 On most systems, changing this value will affect the amount of padding\n\
 and the other strategic decisions made during redisplay.");
   DEFVAR_BOOL ("inverse-video", &inverse_video,
-    "*Non-nil means invert the entire screen display.\n\
+    "*Non-nil means invert the entire frame display.\n\
 This means everything is in inverse video which otherwise would not be.");
   DEFVAR_BOOL ("visible-bell", &visible_bell,
-    "*Non-nil means try to flash the screen to represent a bell.");
+    "*Non-nil means try to flash the frame to represent a bell.");
   DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter,
-    "*Non-nil means no need to redraw entire screen after suspending.\n\
+    "*Non-nil means no need to redraw entire frame after suspending.\n\
 A non-nil value is useful if the terminal can automatically preserve\n\
-Emacs's screen display when you reenter Emacs.\n\
+Emacs's frame display when you reenter Emacs.\n\
 It is up to you to set this variable if your terminal can do that.");
   DEFVAR_LISP ("window-system", &Vwindow_system,
     "A symbol naming the window-system under which Emacs is running\n\
@@ -2119,7 +2193,7 @@ For X windows, this is 10 or 11.");
   DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area,
     "Non-nil means put cursor in minibuffer, at end of any message there.");
   DEFVAR_LISP ("glyph-table", &Vglyph_table,
-    "Table defining how to output a glyph code to the screen.\n\
+    "Table defining how to output a glyph code to the frame.\n\
 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
 Each element can be:\n\
  integer: a glyph code which this glyph is an alias for.\n\