Bugfix festival.
[bpt/emacs.git] / src / dispnew.c
index 7a28975..3cf15de 100644 (file)
@@ -1,5 +1,5 @@
 /* Updating of data structures for redisplay.
-   Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 98, 1999, 2000, 2001
+   Copyright (C) 1985,86,87,88,93,94,95,97,98,1999,2000,01,02,2003
        Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -29,6 +29,7 @@ Boston, MA 02111-1307, USA.  */
 #endif
 
 #include "lisp.h"
+#include "systty.h"             /* For emacs_tty in termchar.h */
 #include "termchar.h"
 #include "termopts.h"
 #include "termhooks.h"
@@ -60,9 +61,9 @@ Boston, MA 02111-1307, USA.  */
 #include "w32term.h"
 #endif /* HAVE_NTGUI */
 
-#ifdef macintosh
+#ifdef MAC_OS
 #include "macterm.h"
-#endif /* macintosh */
+#endif /* MAC_OS */
 
 /* Include systime.h after xterm.h to avoid double inclusion of time.h.  */
 
@@ -75,9 +76,6 @@ Boston, MA 02111-1307, USA.  */
 #include <unistd.h>
 #endif
 
-#define max(a, b) ((a) > (b) ? (a) : (b))
-#define min(a, b) ((a) < (b) ? (a) : (b))
-
 /* Get number of chars of output now in the buffer of a stdio stream.
    This ought to be built in in stdio, but it isn't.  Some s- files
    override this because their stdio internals differ.  */
@@ -104,7 +102,7 @@ Boston, MA 02111-1307, USA.  */
 #endif
 #endif /* not __GNU_LIBRARY__ */
 
-#if defined(HAVE_TERM_H) && defined (LINUX) && defined (HAVE_LIBNCURSES)
+#if defined(HAVE_TERM_H) && defined (GNU_LINUX) && defined (HAVE_LIBNCURSES)
 #include <term.h>              /* for tgetent */
 #endif
 \f
@@ -131,9 +129,8 @@ static int count_match P_ ((struct glyph *, struct glyph *,
 static unsigned line_draw_cost P_ ((struct glyph_matrix *, int));
 static void update_frame_line P_ ((struct frame *, int));
 static struct dim allocate_matrices_for_frame_redisplay
-     P_ ((Lisp_Object, int, int, struct dim, int, int *));
-static void allocate_matrices_for_window_redisplay P_ ((struct window *,
-                                                       struct dim));
+     P_ ((Lisp_Object, int, int, int, int *));
+static void allocate_matrices_for_window_redisplay P_ ((struct window *));
 static int realloc_glyph_pool P_ ((struct glyph_pool *, struct dim));
 static void adjust_frame_glyphs P_ ((struct frame *));
 struct glyph_matrix *new_glyph_matrix P_ ((struct glyph_pool *));
@@ -215,7 +212,7 @@ int inverse_video;
 
 /* Line speed of the terminal.  */
 
-int baud_rate;
+EMACS_INT baud_rate;
 
 /* Either nil or a symbol naming the window system under which Emacs
    is running.  */
@@ -242,7 +239,7 @@ Lisp_Object Vglyph_table;
 Lisp_Object Vstandard_display_table;
 
 /* Nonzero means reading single-character input with prompt so put
-   cursor on mini-buffer after the prompt.  positive means at end of
+   cursor on mini-buffer after the prompt.  Positive means at end of
    text in echo area; negative means at beginning of line.  */
 
 int cursor_in_echo_area;
@@ -262,14 +259,6 @@ Lisp_Object selected_frame;
 
 struct frame *last_nonminibuf_frame;
 
-/* Stdio stream being used for copy of all output.  */
-
-FILE *termscript;
-
-/* Structure for info on cursor positioning.  */
-
-struct cm Wcm;
-
 /* 1 means SIGWINCH happened when not safe.  */
 
 int delayed_size_change;
@@ -321,7 +310,7 @@ struct redisplay_interface *rif;
 
 int fonts_changed_p;
 
-/* Convert vpos and hpos from frame to window and vice versa. 
+/* Convert vpos and hpos from frame to window and vice versa.
    This may only be used for terminal frames.  */
 
 #if GLYPH_DEBUG
@@ -362,7 +351,7 @@ static void add_window_display_history P_ ((struct window *, char *, int));
 
 /* Add to the redisplay history how window W has been displayed.
    MSG is a trace containing the information how W's glyph matrix
-   has been contructed.  PAUSED_P non-zero means that the update
+   has been constructed.  PAUSED_P non-zero means that the update
    has been interrupted for pending input.  */
 
 static void
@@ -372,18 +361,18 @@ add_window_display_history (w, msg, paused_p)
      int paused_p;
 {
   char *buf;
-  
+
   if (history_idx >= REDISPLAY_HISTORY_SIZE)
     history_idx = 0;
   buf = redisplay_history[history_idx].trace;
   ++history_idx;
-  
+
   sprintf (buf, "%d: window %p (`%s')%s\n",
           history_tick++,
           w,
           ((BUFFERP (w->buffer)
             && STRINGP (XBUFFER (w->buffer)->name))
-           ? (char *) XSTRING (XBUFFER (w->buffer)->name)->data
+           ? (char *) SDATA (XBUFFER (w->buffer)->name)
            : "???"),
           paused_p ? " ***paused***" : "");
   strcat (buf, msg);
@@ -400,12 +389,12 @@ add_frame_display_history (f, paused_p)
      int paused_p;
 {
   char *buf;
-  
+
   if (history_idx >= REDISPLAY_HISTORY_SIZE)
     history_idx = 0;
   buf = redisplay_history[history_idx].trace;
   ++history_idx;
-  
+
   sprintf (buf, "%d: update frame %p%s",
           history_tick++,
           f, paused_p ? " ***paused***" : "");
@@ -414,7 +403,7 @@ add_frame_display_history (f, paused_p)
 
 DEFUN ("dump-redisplay-history", Fdump_redisplay_history,
        Sdump_redisplay_history, 0, 0, "",
-   "Dump redisplay history to stderr.")
+       doc: /* Dump redisplay history to stderr.  */)
      ()
 {
   int i;
@@ -432,8 +421,8 @@ DEFUN ("dump-redisplay-history", Fdump_redisplay_history,
 
 #else /* GLYPH_DEBUG == 0 */
 
-#define WINDOW_TO_FRAME_VPOS(W, VPOS) ((VPOS) + XFASTINT ((W)->top))
-#define WINDOW_TO_FRAME_HPOS(W, HPOS) ((HPOS) + XFASTINT ((W)->left))
+#define WINDOW_TO_FRAME_VPOS(W, VPOS) ((VPOS) + WINDOW_TOP_EDGE_LINE (W))
+#define WINDOW_TO_FRAME_HPOS(W, HPOS) ((HPOS) + WINDOW_LEFT_EDGE_COL (W))
 
 #endif /* GLYPH_DEBUG == 0 */
 
@@ -444,7 +433,8 @@ DEFUN ("dump-redisplay-history", Fdump_redisplay_history,
 
 void
 safe_bcopy (from, to, size)
-     char *from, *to;
+     const char *from;
+     char *to;
      int size;
 {
   if (size <= 0 || from == to)
@@ -459,7 +449,7 @@ safe_bcopy (from, to, size)
   /* Otherwise, we'll copy from the end.  */
   else
     {
-      register char *endf = from + size;
+      register const char *endf = from + size;
       register char *endt = to + size;
 
       /* If TO - FROM is large, then we should break the copy into
@@ -493,7 +483,7 @@ safe_bcopy (from, to, size)
          bcopy (from, to, endt - from);
        }
     }
-}     
+}
 
 
 \f
@@ -533,7 +523,7 @@ new_glyph_matrix (pool)
    is freed.  If the count gets negative, more structures were freed
    than allocated, i.e. one matrix was freed more than once or a bogus
    pointer was passed to this function.
+
    If MATRIX->pool is null, this means that the matrix manages its own
    glyph memory---this is done for matrices on X frames.  Freeing the
    matrix also frees the glyph memory in this case.  */
@@ -555,7 +545,7 @@ free_glyph_matrix (matrix)
       if (matrix->pool == NULL)
        for (i = 0; i < matrix->rows_allocated; ++i)
          xfree (matrix->rows[i].glyphs[LEFT_MARGIN_AREA]);
-      
+
       /* Free row structures and the matrix itself.  */
       xfree (matrix->rows);
       xfree (matrix);
@@ -579,7 +569,7 @@ margin_glyphs_to_reserve (w, total_glyphs, margin)
 
   if (NUMBERP (margin))
     {
-      int width = XFASTINT (w->width);
+      int width = XFASTINT (w->total_cols);
       double d = max (0, XFLOATINT (margin));
       d = min (width / 2 - 1, d);
       n = (int) ((double) total_glyphs / width * d);
@@ -626,24 +616,27 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
   int header_line_changed_p = 0;
   int header_line_p = 0;
   int left = -1, right = -1;
-  int window_x, window_y, window_width = -1, window_height;
+  int window_width = -1, window_height;
 
-  /* See if W had a top line that has disappeared now, or vice versa.  */
+  /* See if W had a header line that has disappeared now, or vice versa.
+     Get W's size.  */
   if (w)
     {
+      window_box (w, -1, 0, 0, &window_width, &window_height);
+
       header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
       header_line_changed_p = header_line_p != matrix->header_line_p;
     }
   matrix->header_line_p = header_line_p;
 
-  /* Do nothing if MATRIX' size, position, vscroll, and marginal areas
+  /* If POOL is null, MATRIX is a window matrix for window-based redisplay.
+     Do nothing if MATRIX' size, position, vscroll, and marginal areas
      haven't changed.  This optimization is important because preserving
      the matrix means preventing redisplay.  */
   if (matrix->pool == NULL)
     {
-      window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
-      left = margin_glyphs_to_reserve (w, dim.width, w->left_margin_width);
-      right = margin_glyphs_to_reserve (w, dim.width, w->right_margin_width);
+      left = margin_glyphs_to_reserve (w, dim.width, w->left_margin_cols);
+      right = margin_glyphs_to_reserve (w, dim.width, w->right_margin_cols);
       xassert (left >= 0 && right >= 0);
       marginal_areas_changed_p = (left != matrix->left_margin_glyphs
                                  || right != matrix->right_margin_glyphs);
@@ -651,14 +644,14 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
       if (!marginal_areas_changed_p
          && !fonts_changed_p
          && !header_line_changed_p
-         && matrix->window_left_x == XFASTINT (w->left)
-         && matrix->window_top_y == XFASTINT (w->top)
+         && matrix->window_left_col == WINDOW_LEFT_EDGE_COL (w)
+         && matrix->window_top_line == WINDOW_TOP_EDGE_LINE (w)
          && matrix->window_height == window_height
          && matrix->window_vscroll == w->vscroll
          && matrix->window_width == window_width)
        return;
     }
-  
+
   /* Enlarge MATRIX->rows if necessary.  New rows are cleared.  */
   if (matrix->rows_allocated < dim.height)
     {
@@ -678,26 +671,26 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
   if (matrix->pool)
     {
       xassert (matrix->pool->glyphs);
-      
+
       if (w)
        {
          left = margin_glyphs_to_reserve (w, dim.width,
-                                          w->left_margin_width);
+                                          w->left_margin_cols);
          right = margin_glyphs_to_reserve (w, dim.width,
-                                           w->right_margin_width);
+                                           w->right_margin_cols);
        }
       else
        left = right = 0;
-      
+
       for (i = 0; i < dim.height; ++i)
        {
          struct glyph_row *row = &matrix->rows[i];
-         
-         row->glyphs[LEFT_MARGIN_AREA] 
+
+         row->glyphs[LEFT_MARGIN_AREA]
            = (matrix->pool->glyphs
               + (y + i) * matrix->pool->ncolumns
               + x);
-         
+
          if (w == NULL
              || row == matrix->rows + dim.height - 1
              || (row == matrix->rows && matrix->header_line_p))
@@ -719,14 +712,15 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
                = row->glyphs[LEFT_MARGIN_AREA] + dim.width;
            }
        }
-      
+
       matrix->left_margin_glyphs = left;
       matrix->right_margin_glyphs = right;
     }
   else
     {
       /* If MATRIX->pool is null, MATRIX is responsible for managing
-        its own memory.  Allocate glyph memory from the heap.  */
+        its own memory.  It is a window matrix for window-based redisplay.
+        Allocate glyph memory from the heap.  */
       if (dim.width > matrix->matrix_w
          || new_rows
          || header_line_changed_p
@@ -734,14 +728,14 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
        {
          struct glyph_row *row = matrix->rows;
          struct glyph_row *end = row + matrix->rows_allocated;
-         
+
          while (row < end)
            {
              row->glyphs[LEFT_MARGIN_AREA]
                = (struct glyph *) xrealloc (row->glyphs[LEFT_MARGIN_AREA],
                                             (dim.width
                                              * sizeof (struct glyph)));
-             
+
              /* The mode line never has marginal areas.  */
              if (row == matrix->rows + dim.height - 1
                  || (row == matrix->rows && matrix->header_line_p))
@@ -770,7 +764,7 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
       matrix->left_margin_glyphs = left;
       matrix->right_margin_glyphs = right;
     }
-  
+
   /* Number of rows to be used by MATRIX.  */
   matrix->nrows = dim.height;
   xassert (matrix->nrows >= 0);
@@ -785,27 +779,32 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
             building desired matrices when this function runs.  */
          if (window_width < 0)
            window_width = window_box_width (w, -1);
-      
+
          /* Optimize the case that only the height has changed (C-x 2,
             upper window).  Invalidate all rows that are no longer part
             of the window.  */
          if (!marginal_areas_changed_p
-             && matrix->window_left_x == XFASTINT (w->left)
-             && matrix->window_top_y == XFASTINT (w->top)
-             && matrix->window_width == window_box_width (w, -1))
+             && !header_line_changed_p
+             && new_rows == 0
+             && dim.width == matrix->matrix_w
+             && matrix->window_left_col == WINDOW_LEFT_EDGE_COL (w)
+             && matrix->window_top_line == WINDOW_TOP_EDGE_LINE (w)
+             && matrix->window_width == window_width)
            {
-             i = 0;
-             while (matrix->rows[i].enabled_p
-                    && (MATRIX_ROW_BOTTOM_Y (matrix->rows + i)
-                        < matrix->window_height))
-               ++i;
+             /* Find the last row in the window.  */
+             for (i = 0; i < matrix->nrows && matrix->rows[i].enabled_p; ++i)
+               if (MATRIX_ROW_BOTTOM_Y (matrix->rows + i) >= window_height)
+                 {
+                   ++i;
+                   break;
+                 }
 
              /* Window end is invalid, if inside of the rows that
-                are invalidated.  */
+                are invalidated below.  */
              if (INTEGERP (w->window_end_vpos)
                  && XFASTINT (w->window_end_vpos) >= i)
                w->window_end_valid = Qnil;
-         
+
              while (i < matrix->nrows)
                matrix->rows[i++].enabled_p = 0;
            }
@@ -825,8 +824,8 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
            matrix->rows[i].enabled_p = 0;
        }
     }
-    
-  
+
+
   /* Remember last values to be able to optimize frame redraws.  */
   matrix->matrix_x = x;
   matrix->matrix_y = y;
@@ -837,8 +836,8 @@ adjust_glyph_matrix (w, matrix, x, y, dim)
      was last adjusted.  This is used to optimize redisplay above.  */
   if (w)
     {
-      matrix->window_left_x = XFASTINT (w->left);
-      matrix->window_top_y = XFASTINT (w->top);
+      matrix->window_left_col = WINDOW_LEFT_EDGE_COL (w);
+      matrix->window_top_line = WINDOW_TOP_EDGE_LINE (w);
       matrix->window_height = window_height;
       matrix->window_width = window_width;
       matrix->window_vscroll = w->vscroll;
@@ -937,7 +936,7 @@ enable_glyph_matrix_rows (matrix, start, end, enabled_p)
   xassert (start <= end);
   xassert (start >= 0 && start < matrix->nrows);
   xassert (end >= 0 && end <= matrix->nrows);
-  
+
   for (; start < end; ++start)
     matrix->rows[start].enabled_p = enabled_p != 0;
 }
@@ -963,7 +962,7 @@ clear_glyph_matrix (matrix)
       matrix->no_scrolling_p = 0;
     }
 }
-  
+
 
 /* Shift part of the glyph matrix MATRIX of window W up or down.
    Increment y-positions in glyph rows between START and END by DY,
@@ -976,26 +975,25 @@ shift_glyph_matrix (w, matrix, start, end, dy)
      int start, end, dy;
 {
   int min_y, max_y;
-  
+
   xassert (start <= end);
   xassert (start >= 0 && start < matrix->nrows);
   xassert (end >= 0 && end <= matrix->nrows);
-  
-  min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
-  max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w);
-  
+
+  min_y = WINDOW_HEADER_LINE_HEIGHT (w);
+  max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (w);
+
   for (; start < end; ++start)
     {
       struct glyph_row *row = &matrix->rows[start];
-      
+
       row->y += dy;
-      
+      row->visible_height = row->height;
+
       if (row->y < min_y)
-       row->visible_height = row->height - (min_y - row->y);
-      else if (row->y + row->height > max_y)
-       row->visible_height = row->height - (row->y + row->height - max_y);
-      else
-       row->visible_height = row->height;
+       row->visible_height -= min_y - row->y;
+      if (row->y + row->height > max_y)
+       row->visible_height -= row->y + row->height - max_y;
     }
 }
 
@@ -1036,7 +1034,7 @@ clear_desired_matrices (f)
 {
   if (f->desired_matrix)
     clear_glyph_matrix (f->desired_matrix);
-  
+
   if (WINDOWP (f->menu_bar_window))
     clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
 
@@ -1124,7 +1122,7 @@ clear_glyph_row (row)
         Redisplay outputs such glyphs, and flickering effects were
         the result.  This also depended on the contents of memory
         returned by xmalloc.  If flickering happens again, activate
-        the code below If the flickering is gone with that, chances
+        the code below If the flickering is gone with that, chances
         are that the flickering has the same reason as here.  */
   bzero (p[0], (char *) p[LAST_AREA] - (char *) p[0]);
 #endif
@@ -1141,21 +1139,20 @@ blank_row (w, row, y)
      int y;
 {
   int min_y, max_y;
-  
-  min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
-  max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w);
-  
+
+  min_y = WINDOW_HEADER_LINE_HEIGHT (w);
+  max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (w);
+
   clear_glyph_row (row);
   row->y = y;
   row->ascent = row->phys_ascent = 0;
-  row->height = row->phys_height = CANON_Y_UNIT (XFRAME (w->frame));
-  
+  row->height = row->phys_height = FRAME_LINE_HEIGHT (XFRAME (w->frame));
+  row->visible_height = row->height;
+
   if (row->y < min_y)
-    row->visible_height = row->height - (min_y - row->y);
-  else if (row->y + row->height > max_y)
-    row->visible_height = row->height - (row->y + row->height - max_y);
-  else
-    row->visible_height = row->height;
+    row->visible_height -= min_y - row->y;
+  if (row->y + row->height > max_y)
+    row->visible_height -= row->y + row->height - max_y;
 
   row->enabled_p = 1;
 }
@@ -1290,7 +1287,7 @@ copy_glyph_row_contents (to, from, delta, delta_bytes)
   /* Copy glyphs from FROM to TO.  */
   for (area = 0; area < LAST_AREA; ++area)
     if (from->used[area])
-      bcopy (from->glyphs[area], to->glyphs[area], 
+      bcopy (from->glyphs[area], to->glyphs[area],
             from->used[area] * sizeof (struct glyph));
 
   /* Increment buffer positions in TO by DELTA.  */
@@ -1383,41 +1380,32 @@ line_hash_code (row)
      struct glyph_row *row;
 {
   int hash = 0;
-  
+
   if (row->enabled_p)
     {
-      if (row->inverse_p)
-        {
-          /* Give all highlighted lines the same hash code
-            so as to encourage scrolling to leave them in place.  */
-          hash = -1;
-        }
-      else
-        {
-          struct glyph *glyph = row->glyphs[TEXT_AREA];
-         struct glyph *end = glyph + row->used[TEXT_AREA];
+      struct glyph *glyph = row->glyphs[TEXT_AREA];
+      struct glyph *end = glyph + row->used[TEXT_AREA];
 
-          while (glyph < end)
-            {
-             int c = glyph->u.ch;
-             int face_id = glyph->face_id;
-             if (must_write_spaces)
-               c -= SPACEGLYPH;
-             hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c;
-             hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + face_id;
-             ++glyph;
-           }
+      while (glyph < end)
+       {
+         int c = glyph->u.ch;
+         int face_id = glyph->face_id;
+         if (TTY_MUST_WRITE_SPACES (CURTTY ()))
+           c -= SPACEGLYPH;
+         hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c;
+         hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + face_id;
+         ++glyph;
+       }
 
-          if (hash == 0)
-           hash = 1;
-        }
+      if (hash == 0)
+       hash = 1;
     }
 
   return hash;
 }
 
 
-/* Return the cost of drawing line VPOS In MATRIX.  The cost equals
+/* Return the cost of drawing line VPOS in MATRIX.  The cost equals
    the number of characters in the line.  If must_write_spaces is
    zero, leading and trailing spaces are ignored.  */
 
@@ -1434,13 +1422,13 @@ line_draw_cost (matrix, vpos)
   int glyph_table_len = GLYPH_TABLE_LENGTH;
 
   /* Ignore trailing and leading spaces if we can.  */
-  if (!must_write_spaces)
+  if (!TTY_MUST_WRITE_SPACES (CURTTY ()))
     {
       /* Skip from the end over trailing spaces.  */
       while (end > beg && CHAR_GLYPH_SPACE_P (*(end - 1)))
        --end;
 
-      /* All blank line.  */      
+      /* All blank line.  */
       if (end == beg)
        return 0;
 
@@ -1461,17 +1449,17 @@ line_draw_cost (matrix, vpos)
       while (beg < end)
        {
          GLYPH g = GLYPH_FROM_CHAR_GLYPH (*beg);
-         
+
          if (g < 0
              || GLYPH_SIMPLE_P (glyph_table_base, glyph_table_len, g))
            len += 1;
          else
            len += GLYPH_LENGTH (glyph_table_base, g);
-         
+
          ++beg;
        }
     }
-  
+
   return len;
 }
 
@@ -1482,7 +1470,7 @@ line_draw_cost (matrix, vpos)
    visibility.  MOUSE_FACE_P non-zero means compare the mouse_face_p
    flags of A and B, too.  */
 
-static INLINE int 
+static INLINE int
 row_equal_p (w, a, b, mouse_face_p)
      struct window *w;
      struct glyph_row *a, *b;
@@ -1505,21 +1493,20 @@ row_equal_p (w, a, b, mouse_face_p)
        {
          if (a->used[area] != b->used[area])
            return 0;
-         
+
          a_glyph = a->glyphs[area];
          a_end = a_glyph + a->used[area];
          b_glyph = b->glyphs[area];
-         
+
          while (a_glyph < a_end
                 && GLYPH_EQUAL_P (a_glyph, b_glyph))
            ++a_glyph, ++b_glyph;
-         
+
          if (a_glyph != a_end)
            return 0;
        }
 
       if (a->truncated_on_left_p != b->truncated_on_left_p
-         || a->inverse_p != b->inverse_p
          || a->fill_line_p != b->fill_line_p
          || a->truncated_on_right_p != b->truncated_on_right_p
          || a->overlay_arrow_p != b->overlay_arrow_p
@@ -1561,10 +1548,10 @@ new_glyph_pool ()
   /* Allocate a new glyph_pool and clear it.  */
   result = (struct glyph_pool *) xmalloc (sizeof *result);
   bzero (result, sizeof *result);
-  
+
   /* For memory leak and double deletion checking.  */
   ++glyph_pool_count;
-  
+
   return result;
 }
 
@@ -1582,7 +1569,7 @@ free_glyph_pool (pool)
 {
   if (pool)
     {
-      /* More freed than allocated? */
+      /* More freed than allocated?  */
       --glyph_pool_count;
       xassert (glyph_pool_count >= 0);
 
@@ -1630,13 +1617,13 @@ realloc_glyph_pool (pool, matrix_dim)
       pool->nglyphs = needed;
     }
 
-  /* Remember the number of rows and columns because (a) we use then
+  /* Remember the number of rows and columns because (a) we use them
      to do sanity checks, and (b) the number of columns determines
      where rows in the frame matrix start---this must be available to
      determine pointers to rows of window sub-matrices.  */
   pool->nrows = matrix_dim.height;
   pool->ncolumns = matrix_dim.width;
-  
+
   return changed_p;
 }
 
@@ -1649,8 +1636,10 @@ realloc_glyph_pool (pool, matrix_dim)
 #if GLYPH_DEBUG
 
 
-/* Flush standard output.  This is sometimes useful to call from
-   the debugger.  */
+/* Flush standard output.  This is sometimes useful to call from the debugger.
+   XXX Maybe this should be changed to flush the current terminal instead of
+   stdout.
+*/
 
 void
 flush_stdout ()
@@ -1669,7 +1658,7 @@ check_matrix_pointer_lossage (matrix)
      struct glyph_matrix *matrix;
 {
   int i, j;
-  
+
   for (i = 0; i < matrix->nrows; ++i)
     for (j = 0; j < matrix->nrows; ++j)
       xassert (i == j
@@ -1694,7 +1683,7 @@ matrix_row (matrix, row)
 #if 0
   check_matrix_pointer_lossage (matrix);
 #endif
-  
+
   return matrix->rows + row;
 }
 
@@ -1717,7 +1706,7 @@ check_matrix_invariants (w)
   struct buffer *saved = current_buffer;
   struct buffer *buffer = XBUFFER (w->buffer);
   int c;
-  
+
   /* This can sometimes happen for a fresh window.  */
   if (matrix->nrows < 2)
     return;
@@ -1793,7 +1782,7 @@ check_matrix_invariants (w)
 
    CHANGED_LEAF_MATRIX set if the dimension or location of a matrix of
    any window in the tree will be changed or have been changed (see
-   DIM_ONLY_P).
+   DIM_ONLY_P)
 
    *WINDOW_CHANGE_FLAGS must be initialized by the caller of this
    function.
@@ -1854,11 +1843,10 @@ check_matrix_invariants (w)
 #define CHANGED_LEAF_MATRIX    (1 << 1)
 
 static struct dim
-allocate_matrices_for_frame_redisplay (window, x, y, ch_dim,
-                                      dim_only_p, window_change_flags)
+allocate_matrices_for_frame_redisplay (window, x, y, dim_only_p,
+                                      window_change_flags)
      Lisp_Object window;
      int x, y;
-     struct dim ch_dim;
      int dim_only_p;
      int *window_change_flags;
 {
@@ -1881,18 +1869,18 @@ allocate_matrices_for_frame_redisplay (window, x, y, ch_dim,
        && !NILP (XWINDOW (XWINDOW (window)->parent)->hchild));
 
   /* For WINDOW and all windows on the same level.  */
-  do 
+  do
     {
       w = XWINDOW (window);
 
       /* Get the dimension of the window sub-matrix for W, depending
-        on whether this a combination or a leaf window.  */
+        on whether this is a combination or a leaf window.  */
       if (!NILP (w->hchild))
-       dim = allocate_matrices_for_frame_redisplay (w->hchild, x, y, ch_dim,
+       dim = allocate_matrices_for_frame_redisplay (w->hchild, x, y,
                                                     dim_only_p,
                                                     window_change_flags);
       else if (!NILP (w->vchild))
-       dim = allocate_matrices_for_frame_redisplay (w->vchild, x, y, ch_dim,
+       dim = allocate_matrices_for_frame_redisplay (w->vchild, x, y,
                                                     dim_only_p,
                                                     window_change_flags);
       else
@@ -1904,11 +1892,11 @@ allocate_matrices_for_frame_redisplay (window, x, y, ch_dim,
              w->current_matrix = new_glyph_matrix (f->current_pool);
              *window_change_flags |= NEW_LEAF_MATRIX;
            }
-  
+
          /* Width and height MUST be chosen so that there are no
             holes in the frame matrix.  */
-         dim.width = XINT (w->width);
-         dim.height = XINT (w->height);
+         dim.width = required_matrix_width (w);
+         dim.height = required_matrix_height (w);
 
          /* Will matrix be re-allocated?  */
          if (x != w->desired_matrix->matrix_x
@@ -1916,10 +1904,10 @@ allocate_matrices_for_frame_redisplay (window, x, y, ch_dim,
              || dim.width != w->desired_matrix->matrix_w
              || dim.height != w->desired_matrix->matrix_h
              || (margin_glyphs_to_reserve (w, dim.width,
-                                           w->right_margin_width)
+                                           w->right_margin_cols)
                  != w->desired_matrix->left_margin_glyphs)
              || (margin_glyphs_to_reserve (w, dim.width,
-                                           w->left_margin_width)
+                                           w->left_margin_cols)
                  != w->desired_matrix->right_margin_glyphs))
            *window_change_flags |= CHANGED_LEAF_MATRIX;
 
@@ -1940,7 +1928,7 @@ allocate_matrices_for_frame_redisplay (window, x, y, ch_dim,
         below W.  */
       if (in_horz_combination_p)
        x += dim.width;
-      else 
+      else
         y += dim.height;
 
       /* Remember maximum glyph matrix dimensions.  */
@@ -1963,7 +1951,7 @@ allocate_matrices_for_frame_redisplay (window, x, y, ch_dim,
       total.width = x - x0;
       total.height = hmax;
     }
-  else 
+  else
     {
       total.width = wmax;
       total.height = y - y0;
@@ -1973,28 +1961,78 @@ allocate_matrices_for_frame_redisplay (window, x, y, ch_dim,
 }
 
 
+/* Return the required height of glyph matrices for window W.  */
+
+int
+required_matrix_height (w)
+     struct window *w;
+{
+#ifdef HAVE_WINDOW_SYSTEM
+  struct frame *f = XFRAME (w->frame);
+
+  if (FRAME_WINDOW_P (f))
+    {
+      int ch_height = FRAME_SMALLEST_FONT_HEIGHT (f);
+      int window_pixel_height = window_box_height (w) + abs (w->vscroll);
+      return (((window_pixel_height + ch_height - 1)
+              / ch_height)
+             /* One partially visible line at the top and
+                bottom of the window.  */
+             + 2
+             /* 2 for header and mode line.  */
+             + 2);
+    }
+#endif /* HAVE_WINDOW_SYSTEM */
+
+  return WINDOW_TOTAL_LINES (w);
+}
+
+
+/* Return the required width of glyph matrices for window W.  */
+
+int
+required_matrix_width (w)
+     struct window *w;
+{
+#ifdef HAVE_WINDOW_SYSTEM
+  struct frame *f = XFRAME (w->frame);
+  if (FRAME_WINDOW_P (f))
+    {
+      int ch_width = FRAME_SMALLEST_CHAR_WIDTH (f);
+      int window_pixel_width = WINDOW_TOTAL_WIDTH (w);
+
+      /* Compute number of glyphs needed in a glyph row.  */
+      return (((window_pixel_width + ch_width - 1)
+              / ch_width)
+             /* 2 partially visible columns in the text area.  */
+             + 2
+             /* One partially visible column at the right
+                edge of each marginal area.  */
+             + 1 + 1);
+    }
+#endif /* HAVE_WINDOW_SYSTEM */
+
+  return XINT (w->total_cols);
+}
+
+
 /* Allocate window matrices for window-based redisplay.  W is the
    window whose matrices must be allocated/reallocated.  CH_DIM is the
    size of the smallest character that could potentially be used on W.  */
-   
+
 static void
-allocate_matrices_for_window_redisplay (w, ch_dim)
+allocate_matrices_for_window_redisplay (w)
      struct window *w;
-     struct dim ch_dim;
 {
-  struct frame *f = XFRAME (w->frame);
-  
   while (w)
     {
       if (!NILP (w->vchild))
-       allocate_matrices_for_window_redisplay (XWINDOW (w->vchild), ch_dim);
+       allocate_matrices_for_window_redisplay (XWINDOW (w->vchild));
       else if (!NILP (w->hchild))
-       allocate_matrices_for_window_redisplay (XWINDOW (w->hchild), ch_dim);
+       allocate_matrices_for_window_redisplay (XWINDOW (w->hchild));
       else
        {
          /* W is a leaf window.  */
-         int window_pixel_width = XFLOATINT (w->width) * CANON_X_UNIT (f);
-         int window_pixel_height = window_box_height (w) + abs (w->vscroll);
          struct dim dim;
 
          /* If matrices are not yet allocated, allocate them now.  */
@@ -2004,29 +2042,12 @@ allocate_matrices_for_window_redisplay (w, ch_dim)
              w->current_matrix = new_glyph_matrix (NULL);
            }
 
-         /* Compute number of glyphs needed in a glyph row.  */
-         dim.width = (((window_pixel_width + ch_dim.width - 1)
-                       / ch_dim.width)
-                      /* 2 partially visible columns in the text area.  */
-                      + 2
-                      /* One partially visible column at the right
-                         edge of each marginal area.  */
-                      + 1 + 1);
-
-         /* Compute number of glyph rows needed.  */
-         dim.height = (((window_pixel_height + ch_dim.height - 1)
-                        / ch_dim.height)
-                       /* One partially visible line at the top and
-                          bottom of the window.  */
-                       + 2
-                       /* 2 for top and mode line.  */
-                       + 2);
-
-         /* Change matrices.  */
+         dim.width = required_matrix_width (w);
+         dim.height = required_matrix_height (w);
          adjust_glyph_matrix (w, w->desired_matrix, 0, 0, dim);
          adjust_glyph_matrix (w, w->current_matrix, 0, 0, dim);
        }
-      
+
       w = NILP (w->next) ? NULL : XWINDOW (w->next);
     }
 }
@@ -2050,7 +2071,7 @@ adjust_glyphs (f)
   else
     {
       Lisp_Object tail, lisp_frame;
-      
+
       FOR_EACH_FRAME (tail, lisp_frame)
        adjust_frame_glyphs (XFRAME (lisp_frame));
     }
@@ -2060,9 +2081,9 @@ adjust_glyphs (f)
 
 
 /* Adjust frame glyphs when Emacs is initialized.
-   
-   To be called from init_display. 
-   
+
+   To be called from init_display.
+
    We need a glyph matrix because redraw will happen soon.
    Unfortunately, window sizes on selected_frame are not yet set to
    meaningful values.  I believe we can assume that there are only two
@@ -2076,24 +2097,24 @@ adjust_frame_glyphs_initially ()
   struct frame *sf = SELECTED_FRAME ();
   struct window *root = XWINDOW (sf->root_window);
   struct window *mini = XWINDOW (root->next);
-  int frame_height = FRAME_HEIGHT (sf);
-  int frame_width = FRAME_WIDTH (sf);
+  int frame_lines = FRAME_LINES (sf);
+  int frame_cols = FRAME_COLS (sf);
   int top_margin = FRAME_TOP_MARGIN (sf);
 
   /* Do it for the root window.  */
-  XSETFASTINT (root->top, top_margin);
-  XSETFASTINT (root->width, frame_width);
-  set_window_height (sf->root_window, frame_height - 1 - top_margin, 0);
+  XSETFASTINT (root->top_line, top_margin);
+  XSETFASTINT (root->total_cols, frame_cols);
+  set_window_height (sf->root_window, frame_lines - 1 - top_margin, 0);
 
   /* Do it for the mini-buffer window.  */
-  XSETFASTINT (mini->top, frame_height - 1);
-  XSETFASTINT (mini->width, frame_width);
+  XSETFASTINT (mini->top_line, frame_lines - 1);
+  XSETFASTINT (mini->total_cols, frame_cols);
   set_window_height (root->next, 1, 0);
 
   adjust_frame_glyphs (sf);
   glyphs_initialized_initially_p = 1;
 }
-  
+
 
 /* Allocate/reallocate glyph matrices of a single frame F.  */
 
@@ -2105,7 +2126,7 @@ adjust_frame_glyphs (f)
     adjust_frame_glyphs_for_window_redisplay (f);
   else
     adjust_frame_glyphs_for_frame_redisplay (f);
-  
+
   /* Don't forget the message buffer and the buffer for
      decode_mode_spec.  */
   adjust_frame_message_buffer (f);
@@ -2123,11 +2144,11 @@ fake_current_matrices (window)
      Lisp_Object window;
 {
   struct window *w;
-      
+
   for (; !NILP (window); window = w->next)
     {
       w = XWINDOW (window);
-      
+
       if (!NILP (w->hchild))
        fake_current_matrices (w->hchild);
       else if (!NILP (w->vchild))
@@ -2139,13 +2160,13 @@ fake_current_matrices (window)
          struct glyph_matrix *m = w->current_matrix;
          struct glyph_matrix *fm = f->current_matrix;
 
-         xassert (m->matrix_h == XFASTINT (w->height));
-         xassert (m->matrix_w == XFASTINT (w->width));
-         
+         xassert (m->matrix_h == WINDOW_TOTAL_LINES (w));
+         xassert (m->matrix_w == WINDOW_TOTAL_COLS (w));
+
          for (i = 0; i < m->matrix_h; ++i)
            {
              struct glyph_row *r = m->rows + i;
-             struct glyph_row *fr = fm->rows + i + XFASTINT (w->top);
+             struct glyph_row *fr = fm->rows + i + WINDOW_TOP_EDGE_LINE (w);
 
              xassert (r->glyphs[TEXT_AREA] >= fr->glyphs[TEXT_AREA]
                       && r->glyphs[LAST_AREA] <= fr->glyphs[LAST_AREA]);
@@ -2159,7 +2180,6 @@ fake_current_matrices (window)
                                        - r->used[LEFT_MARGIN_AREA]
                                        - r->used[RIGHT_MARGIN_AREA]);
                  r->mode_line_p = 0;
-                 r->inverse_p = fr->inverse_p;
                }
            }
        }
@@ -2168,7 +2188,7 @@ fake_current_matrices (window)
 
 
 /* Save away the contents of frame F's current frame matrix.  Value is
-   a glyph matrix holding the contents of F's current frame matrix. '*/
+   a glyph matrix holding the contents of F's current frame matrix.  */
 
 static struct glyph_matrix *
 save_current_matrix (f)
@@ -2217,7 +2237,7 @@ restore_current_matrix (f, saved)
       to->used[TEXT_AREA] = from->used[TEXT_AREA];
       xfree (from->glyphs[TEXT_AREA]);
     }
-  
+
   xfree (saved->rows);
   xfree (saved);
 }
@@ -2243,7 +2263,7 @@ adjust_frame_glyphs_for_frame_redisplay (f)
   /* Determine the smallest character in any font for F.  On
      console windows, all characters have dimension (1, 1).  */
   ch_dim.width = ch_dim.height = 1;
-  
+
   top_window_y = FRAME_TOP_MARGIN (f);
 
   /* Allocate glyph pool structures if not already done.  */
@@ -2259,7 +2279,7 @@ adjust_frame_glyphs_for_frame_redisplay (f)
       f->desired_matrix = new_glyph_matrix (f->desired_pool);
       f->current_matrix = new_glyph_matrix (f->current_pool);
     }
-  
+
   /* Compute window glyph matrices.  (This takes the mini-buffer
      window into account).  The result is the size of the frame glyph
      matrix needed.  The variable window_change_flags is set to a bit
@@ -2270,7 +2290,7 @@ adjust_frame_glyphs_for_frame_redisplay (f)
   matrix_dim
     = allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
                                             0, top_window_y,
-                                            ch_dim, 1,
+                                            1,
                                             &window_change_flags);
 
   /* Add in menu bar lines, if any.  */
@@ -2280,21 +2300,21 @@ adjust_frame_glyphs_for_frame_redisplay (f)
   pool_changed_p = realloc_glyph_pool (f->desired_pool, matrix_dim);
   realloc_glyph_pool (f->current_pool, matrix_dim);
 
-  /* Set up glyph pointers within window matrices.  Do this only if 
+  /* Set up glyph pointers within window matrices.  Do this only if
      absolutely necessary since it requires a frame redraw.  */
   if (pool_changed_p || window_change_flags)
     {
       /* Do it for window matrices.  */
       allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
-                                            0, top_window_y, ch_dim, 0,
+                                            0, top_window_y, 0,
                                             &window_change_flags);
 
       /* Size of frame matrices must equal size of frame.  Note
         that we are called for X frames with window widths NOT equal
         to the frame width (from CHANGE_FRAME_SIZE_1).  */
-      xassert (matrix_dim.width == FRAME_WIDTH (f)
-              && matrix_dim.height == FRAME_HEIGHT (f));
-  
+      xassert (matrix_dim.width == FRAME_COLS (f)
+              && matrix_dim.height == FRAME_LINES (f));
+
       /* Pointers to glyph memory in glyph rows are exchanged during
         the update phase of redisplay, which means in general that a
         frame's current matrix consists of pointers into both the
@@ -2336,7 +2356,7 @@ adjust_frame_glyphs_for_window_redisplay (f)
   struct window *w;
 
   xassert (FRAME_WINDOW_P (f) && FRAME_LIVE_P (f));
-  
+
   /* Get minimum sizes.  */
 #ifdef HAVE_WINDOW_SYSTEM
   ch_dim.width = FRAME_SMALLEST_CHAR_WIDTH (f);
@@ -2344,14 +2364,13 @@ adjust_frame_glyphs_for_window_redisplay (f)
 #else
   ch_dim.width = ch_dim.height = 1;
 #endif
-    
+
   /* Allocate/reallocate window matrices.  */
-  allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)),
-                                         ch_dim);
+  allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)));
 
   /* Allocate/ reallocate matrices of the dummy window used to display
      the menu bar under X when no X toolkit support is available.  */
-#ifndef USE_X_TOOLKIT
+#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
   {
     /* Allocate a dummy window if not already done.  */
     if (NILP (f->menu_bar_window))
@@ -2366,14 +2385,15 @@ adjust_frame_glyphs_for_window_redisplay (f)
 
     /* Set window dimensions to frame dimensions and allocate or
        adjust glyph matrices of W.  */
-    XSETFASTINT (w->top, 0);
-    XSETFASTINT (w->left, 0);
-    XSETFASTINT (w->height, FRAME_MENU_BAR_LINES (f));
-    XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f));
-    allocate_matrices_for_window_redisplay (w, ch_dim);
+    XSETFASTINT (w->top_line, 0);
+    XSETFASTINT (w->left_col, 0);
+    XSETFASTINT (w->total_lines, FRAME_MENU_BAR_LINES (f));
+    XSETFASTINT (w->total_cols, FRAME_TOTAL_COLS (f));
+    allocate_matrices_for_window_redisplay (w);
   }
 #endif /* not USE_X_TOOLKIT */
 
+#ifndef USE_GTK
   /* Allocate/ reallocate matrices of the tool bar window.  If we
      don't have a tool bar window yet, make one.  */
   if (NILP (f->tool_bar_window))
@@ -2386,15 +2406,16 @@ adjust_frame_glyphs_for_window_redisplay (f)
   else
     w = XWINDOW (f->tool_bar_window);
 
-  XSETFASTINT (w->top, FRAME_MENU_BAR_LINES (f));
-  XSETFASTINT (w->left, 0);
-  XSETFASTINT (w->height, FRAME_TOOL_BAR_LINES (f));
-  XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f));
-  allocate_matrices_for_window_redisplay (w, ch_dim);
+  XSETFASTINT (w->top_line, FRAME_MENU_BAR_LINES (f));
+  XSETFASTINT (w->left_col, 0);
+  XSETFASTINT (w->total_lines, FRAME_TOOL_BAR_LINES (f));
+  XSETFASTINT (w->total_cols, FRAME_TOTAL_COLS (f));
+  allocate_matrices_for_window_redisplay (w);
+#endif
 }
 
 
-/* Adjust/ allocate message buffer of frame F. 
+/* Adjust/ allocate message buffer of frame F.
 
    Note that the message buffer is never freed.  Since I could not
    find a free in 19.34, I assume that freeing it would be
@@ -2452,7 +2473,7 @@ free_glyphs (f)
          event while we're in an inconsistent state.  */
       BLOCK_INPUT;
       f->glyphs_initialized_p = 0;
-      
+
       /* Release window sub-matrices.  */
       if (!NILP (f->root_window))
         free_window_matrices (XWINDOW (f->root_window));
@@ -2494,7 +2515,7 @@ free_glyphs (f)
          free_glyph_pool (f->current_pool);
          f->desired_pool = f->current_pool = NULL;
        }
-      
+
       UNBLOCK_INPUT;
     }
 }
@@ -2514,7 +2535,7 @@ free_window_matrices (w)
        free_window_matrices (XWINDOW (w->hchild));
       else if (!NILP (w->vchild))
        free_window_matrices (XWINDOW (w->vchild));
-      else 
+      else
        {
          /* This is a leaf window.  Free its memory and reset fields
             to zero in case this function is called a second time for
@@ -2589,7 +2610,7 @@ check_glyph_memory ()
    up glyph lengths of the window matrices.  A line in the frame
    matrix is enabled, if a corresponding line in a window matrix is
    enabled.
-   
+
    After building the desired frame matrix, it will be passed to
    terminal code, which will manipulate both the desired and current
    frame matrix.  Changes applied to the frame's current matrix have
@@ -2602,7 +2623,7 @@ check_glyph_memory ()
    contents needed in a frame matrix.  Thus, any modification of
    glyphs done in terminal code will be reflected in window matrices
    automatically.
-   
+
    2. Exchanges of rows in a frame matrix done by terminal code are
    intercepted by hook functions so that corresponding row operations
    on window matrices can be performed.  This is necessary because we
@@ -2627,7 +2648,7 @@ build_frame_matrix (f)
 
   /* F must have a frame matrix when this function is called.  */
   xassert (!FRAME_WINDOW_P (f));
-  
+
   /* Clear all rows in the frame matrix covered by window matrices.
      Menu bar lines are not covered by windows.  */
   for (i = FRAME_TOP_MARGIN (f); i < f->desired_matrix->nrows; ++i)
@@ -2725,7 +2746,7 @@ build_frame_matrix_from_leaf_window (frame_matrix, w)
          window_row = w->current_matrix->rows + window_y;
          current_row_p = 1;
        }
-      
+
       if (current_row_p)
        {
          /* Copy window row to frame row.  */
@@ -2736,11 +2757,11 @@ build_frame_matrix_from_leaf_window (frame_matrix, w)
       else
        {
          xassert (window_row->enabled_p);
-         
+
          /* Only when a desired row has been displayed, we want
             the corresponding frame row to be updated.  */
          frame_row->enabled_p = 1;
-         
+
           /* Maybe insert a vertical border between horizontally adjacent
             windows.  */
           if (right_border_glyph)
@@ -2752,10 +2773,10 @@ build_frame_matrix_from_leaf_window (frame_matrix, w)
          /* Window row window_y must be a slice of frame row
             frame_y.  */
          xassert (glyph_row_slice_p (window_row, frame_row));
-         
+
          /* If rows are in sync, we don't have to copy glyphs because
             frame and window share glyphs.  */
-         
+
 #if GLYPH_DEBUG
          strcpy (w->current_matrix->method, w->desired_matrix->method);
          add_window_display_history (w, w->current_matrix->method, 0);
@@ -2765,12 +2786,9 @@ build_frame_matrix_from_leaf_window (frame_matrix, w)
       /* Set number of used glyphs in the frame matrix.  Since we fill
          up with spaces, and visit leaf windows from left to right it
          can be done simply.  */
-      frame_row->used[TEXT_AREA] 
+      frame_row->used[TEXT_AREA]
        = window_matrix->matrix_x + window_matrix->matrix_w;
 
-      /* Or in other flags.  */
-      frame_row->inverse_p |= window_row->inverse_p;
-
       /* Next row.  */
       ++window_y;
       ++frame_y;
@@ -2834,7 +2852,7 @@ fill_up_frame_row_with_spaces (row, upto)
 {
   int i = row->used[TEXT_AREA];
   struct glyph *glyph = row->glyphs[TEXT_AREA];
-  
+
   while (i < upto)
     glyph[i++] = space_glyph;
 
@@ -2930,7 +2948,7 @@ mirror_make_current (w, frame_row)
              current_row->enabled_p = 1;
            }
        }
-      
+
       w = NILP (w->next) ? 0 : XWINDOW (w->next);
     }
 }
@@ -2945,7 +2963,7 @@ mirror_make_current (w, frame_row)
    row 0 <= I < NLINES which is empty.
 
    This function is called from do_scrolling and do_direct_scrolling.  */
-   
+
 void
 mirrored_line_dance (matrix, unchanged_at_top, nlines, copy_from,
                     retained_p)
@@ -2959,7 +2977,7 @@ mirrored_line_dance (matrix, unchanged_at_top, nlines, copy_from,
 
   /* Rows to assign to.  */
   struct glyph_row *new_rows = MATRIX_ROW (matrix, unchanged_at_top);
-  
+
   int i;
 
   /* Make a copy of the original rows.  */
@@ -2981,7 +2999,7 @@ mirrored_line_dance (matrix, unchanged_at_top, nlines, copy_from,
        new_rows[i].enabled_p = 0;
     }
 
-  /* Do the same for window matrices, if MATRIX Is a frame matrix.  */
+  /* Do the same for window matrices, if MATRIX is a frame matrix.  */
   if (frame_matrix_frame)
     mirror_line_dance (XWINDOW (frame_matrix_frame->root_window),
                       unchanged_at_top, nlines, copy_from, retained_p);
@@ -2989,8 +3007,7 @@ mirrored_line_dance (matrix, unchanged_at_top, nlines, copy_from,
 
 
 /* Synchronize glyph pointers in the current matrix of window W with
-   the current frame matrix.  W must be full-width, and be on a tty
-   frame.  */
+   the current frame matrix.  */
 
 static void
 sync_window_with_frame_matrix_rows (w)
@@ -2998,27 +3015,31 @@ sync_window_with_frame_matrix_rows (w)
 {
   struct frame *f = XFRAME (w->frame);
   struct glyph_row *window_row, *window_row_end, *frame_row;
+  int left, right, x, width;
 
-  /* Preconditions: W must be a leaf window and full-width.  Its frame
-     must have a frame matrix.  */
+  /* Preconditions: W must be a leaf window on a tty frame.  */
   xassert (NILP (w->hchild) && NILP (w->vchild));
-  xassert (WINDOW_FULL_WIDTH_P (w));
   xassert (!FRAME_WINDOW_P (f));
 
-  /* If W is a full-width window, glyph pointers in W's current matrix
-     have, by definition, to be the same as glyph pointers in the
-     corresponding frame matrix.  */
+  left = margin_glyphs_to_reserve (w, 1, w->left_margin_cols);
+  right = margin_glyphs_to_reserve (w, 1, w->right_margin_cols);
+  x = w->current_matrix->matrix_x;
+  width = w->current_matrix->matrix_w;
+
   window_row = w->current_matrix->rows;
   window_row_end = window_row + w->current_matrix->nrows;
-  frame_row = f->current_matrix->rows + XFASTINT (w->top);
-  while (window_row < window_row_end)
-    {
-      int area;
-      
-      for (area = LEFT_MARGIN_AREA; area <= LAST_AREA; ++area)
-       window_row->glyphs[area] = frame_row->glyphs[area];
+  frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
 
-      ++window_row, ++frame_row;
+  for (; window_row < window_row_end; ++window_row, ++frame_row)
+    {
+      window_row->glyphs[LEFT_MARGIN_AREA]
+       = frame_row->glyphs[0] + x;
+      window_row->glyphs[TEXT_AREA]
+       = window_row->glyphs[LEFT_MARGIN_AREA] + left;
+      window_row->glyphs[LAST_AREA]
+       = window_row->glyphs[LEFT_MARGIN_AREA] + width;
+      window_row->glyphs[RIGHT_MARGIN_AREA]
+       = window_row->glyphs[LAST_AREA] - right;
     }
 }
 
@@ -3032,17 +3053,17 @@ frame_row_to_window (w, row)
      int row;
 {
   struct window *found = NULL;
-  
+
   while (w && !found)
     {
       if (!NILP (w->hchild))
        found = frame_row_to_window (XWINDOW (w->hchild), row);
       else if (!NILP (w->vchild))
        found = frame_row_to_window (XWINDOW (w->vchild), row);
-      else if (row >= XFASTINT (w->top)
-              && row < XFASTINT (w->top) + XFASTINT (w->height))
+      else if (row >= WINDOW_TOP_EDGE_LINE (w)
+              && row < WINDOW_BOTTOM_EDGE_LINE (w))
        found = w;
-      
+
       w = NILP (w->next) ? 0 : XWINDOW (w->next);
     }
 
@@ -3092,36 +3113,36 @@ mirror_line_dance (w, unchanged_at_top, nlines, copy_from, retained_p)
            {
              /* Frame relative line assigned to.  */
              int frame_to = i + unchanged_at_top;
-             
+
              /* Frame relative line assigned.  */
              int frame_from = copy_from[i] + unchanged_at_top;
-             
+
              /* Window relative line assigned to.  */
              int window_to = frame_to - m->matrix_y;
-             
+
              /* Window relative line assigned.  */
              int window_from = frame_from - m->matrix_y;
-             
+
              /* Is assigned line inside window?  */
              int from_inside_window_p
                = window_from >= 0 && window_from < m->matrix_h;
-             
+
              /* Is assigned to line inside window?  */
              int to_inside_window_p
                = window_to >= 0 && window_to < m->matrix_h;
-             
+
              if (from_inside_window_p && to_inside_window_p)
                {
                  /* Enabled setting before assignment.  */
                  int enabled_before_p;
-                 
+
                  /* Do the assignment.  The enabled_p flag is saved
                     over the assignment because the old redisplay did
                     that.  */
                  enabled_before_p = m->rows[window_to].enabled_p;
                  m->rows[window_to] = old_rows[window_from];
                  m->rows[window_to].enabled_p = enabled_before_p;
-                 
+
                  /* If frame line is empty, window line is empty, too.  */
                  if (!retained_p[copy_from[i]])
                    m->rows[window_to].enabled_p = 0;
@@ -3141,7 +3162,7 @@ mirror_line_dance (w, unchanged_at_top, nlines, copy_from, retained_p)
                  m2_from = frame_from - m2->matrix_y;
                  copy_row_except_pointers (m->rows + window_to,
                                            m2->rows + m2_from);
-                 
+
                  /* If frame line is empty, window line is empty, too.  */
                  if (!retained_p[copy_from[i]])
                    m->rows[window_to].enabled_p = 0;
@@ -3155,7 +3176,7 @@ mirror_line_dance (w, unchanged_at_top, nlines, copy_from, retained_p)
             pointers are in sync with the frame matrix.  */
          if (sync_p)
            sync_window_with_frame_matrix_rows (w);
-         
+
          /* Check that no pointers are lost.  */
          CHECK_MATRIX (m);
        }
@@ -3190,7 +3211,7 @@ check_window_matrix_pointers (w)
          check_matrix_pointers (w->desired_matrix, f->desired_matrix);
          check_matrix_pointers (w->current_matrix, f->current_matrix);
        }
-      
+
       w = NILP (w->next) ? 0 : XWINDOW (w->next);
     }
 }
@@ -3211,7 +3232,7 @@ check_matrix_pointers (window_matrix, frame_matrix)
   /* Row number corresponding to I in FRAME_MATRIX.  */
   int j = window_matrix->matrix_y;
 
-  /* For all rows check that the row in the window matrix is a 
+  /* For all rows check that the row in the window matrix is a
      slice of the row in the frame matrix.  If it isn't we didn't
      mirror an operation on the frame matrix correctly.  */
   while (i < window_matrix->nrows)
@@ -3242,17 +3263,17 @@ window_to_frame_vpos (w, vpos)
      int vpos;
 {
   struct frame *f = XFRAME (w->frame);
-  
+
   xassert (!FRAME_WINDOW_P (f));
   xassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
-  vpos += XFASTINT (w->top);
-  xassert (vpos >= 0 && vpos <= FRAME_HEIGHT (f));
+  vpos += WINDOW_TOP_EDGE_LINE (w);
+  xassert (vpos >= 0 && vpos <= FRAME_LINES (f));
   return vpos;
 }
 
 
 /* Translate horizontal position HPOS which is relative to window W to
-   a vertical position relative to W's frame.  */
+   a horizontal position relative to W's frame.  */
 
 static int
 window_to_frame_hpos (w, hpos)
@@ -3260,12 +3281,12 @@ window_to_frame_hpos (w, hpos)
      int hpos;
 {
   struct frame *f = XFRAME (w->frame);
-  
+
   xassert (!FRAME_WINDOW_P (f));
-  hpos += XFASTINT (w->left);
+  hpos += WINDOW_LEFT_EDGE_COL (w);
   return hpos;
 }
-  
+
 #endif /* GLYPH_DEBUG */
 
 
@@ -3275,13 +3296,13 @@ window_to_frame_hpos (w, hpos)
  **********************************************************************/
 
 DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
-  "Clear frame FRAME and output again what is supposed to appear on it.")
-  (frame)
+       doc: /* Clear frame FRAME and output again what is supposed to appear on it.  */)
+     (frame)
      Lisp_Object frame;
 {
   struct frame *f;
 
-  CHECK_LIVE_FRAME (frame, 0);
+  CHECK_LIVE_FRAME (frame);
   f = XFRAME (frame);
 
   /* Ignore redraw requests, if frame has no glyphs yet.
@@ -3296,7 +3317,7 @@ DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
   clear_frame ();
   clear_current_matrices (f);
   update_end (f);
-  fflush (stdout);
+  fflush (TTY_OUTPUT (FRAME_TTY (f)));
   windows_or_buffers_changed++;
   /* Mark all windows as inaccurate, so that every window will have
      its redisplay done.  */
@@ -3321,8 +3342,8 @@ redraw_frame (f)
 
 
 DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
-  "Clear and redisplay all visible frames.")
-  ()
+       doc: /* Clear and redisplay all visible frames.  */)
+     ()
 {
   Lisp_Object tail, frame;
 
@@ -3378,7 +3399,7 @@ direct_output_for_insert (g)
   struct glyph_row *glyph_row;
   struct glyph *glyphs, *glyph, *end;
   int n;
-  /* Non-null means that Redisplay of W is based on window matrices.  */
+  /* Non-null means that redisplay of W is based on window matrices.  */
   int window_redisplay_p = FRAME_WINDOW_P (f);
   /* Non-null means we are in overwrite mode.  */
   int overwrite_p = !NILP (current_buffer->overwrite_mode);
@@ -3407,8 +3428,8 @@ direct_output_for_insert (g)
         is handled specially there (see display_line).  */
       || (MINI_WINDOW_P (w) && XFASTINT (w->hscroll))
       /* Give up if overwriting in the middle of a line.  */
-      || (overwrite_p 
-         && PT != ZV 
+      || (overwrite_p
+         && PT != ZV
          && FETCH_BYTE (PT) != '\n')
       /* Give up for tabs and line ends.  */
       || g == '\t'
@@ -3436,7 +3457,7 @@ direct_output_for_insert (g)
 
   /* If we can't insert glyphs, we can use this method only
      at the end of a line.  */
-  if (!char_ins_del_ok)
+  if (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f)))
     if (PT != ZV && FETCH_BYTE (PT_BYTE) != '\n')
       return 0;
 
@@ -3452,7 +3473,7 @@ direct_output_for_insert (g)
   glyph_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
   if (glyph_row->mouse_face_p)
     return 0;
-  
+
   /* Give up if highlighting trailing whitespace and we have trailing
      whitespace in glyph_row.  We would have to remove the trailing
      whitespace face in that case.  */
@@ -3472,17 +3493,18 @@ direct_output_for_insert (g)
      if the overlay string has newlines in it.  */
   if (STRINGP (it.string))
     return 0;
-  
+
   it.hpos = w->cursor.hpos;
   it.vpos = w->cursor.vpos;
   it.current_x = w->cursor.x + it.first_visible_x;
   it.current_y = w->cursor.y;
   it.end_charpos = PT;
   it.stop_charpos = min (PT, it.stop_charpos);
+  it.stop_charpos = max (IT_CHARPOS (it), it.stop_charpos);
 
   /* More than one display element may be returned for PT - 1 if
      (i) it's a control character which is translated into `\003' or
-     `^C', or (ii) it has a display table entry, or (iii) it's a 
+     `^C', or (ii) it has a display table entry, or (iii) it's a
      combination of both.  */
   delta = delta_bytes = 0;
   while (get_next_display_element (&it))
@@ -3539,7 +3561,7 @@ direct_output_for_insert (g)
   bcopy (it.glyph_row->glyphs[TEXT_AREA], glyphs, n * sizeof *glyphs);
   glyph_row->used[TEXT_AREA] = min (glyph_row->used[TEXT_AREA] + n,
                                    end - glyph_row->glyphs[TEXT_AREA]);
-  
+
   /* Compute new line width.  */
   glyph = glyph_row->glyphs[TEXT_AREA];
   end = glyph + glyph_row->used[TEXT_AREA];
@@ -3550,18 +3572,18 @@ direct_output_for_insert (g)
       ++glyph;
     }
 
-  /* Increment buffer positions for glyphs following the newly 
+  /* Increment buffer positions for glyphs following the newly
      inserted ones.  */
   for (glyph = glyphs + n; glyph < end; ++glyph)
     if (glyph->charpos > 0 && BUFFERP (glyph->object))
       glyph->charpos += delta;
-  
+
   if (MATRIX_ROW_END_CHARPOS (glyph_row) > 0)
     {
       MATRIX_ROW_END_CHARPOS (glyph_row) += delta;
       MATRIX_ROW_END_BYTEPOS (glyph_row) += delta_bytes;
     }
-      
+
   /* Adjust positions in lines following the one we are in.  */
   increment_matrix_positions (w->current_matrix,
                              w->cursor.vpos + 1,
@@ -3583,11 +3605,12 @@ direct_output_for_insert (g)
      implemented for X frames.  The implementation uses updated_window
      and updated_row.  */
   updated_row = glyph_row;
+  updated_area = TEXT_AREA;
   update_begin (f);
   if (rif)
     {
       rif->update_window_begin_hook (w);
-      
+
       if (glyphs == end - n
          /* In front of a space added by append_space.  */
          || (glyphs == end - n - 1
@@ -3620,8 +3643,8 @@ direct_output_for_insert (g)
     {
       int x, y;
       x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos)
-          + (INTEGERP (w->left_margin_width)
-             ? XFASTINT (w->left_margin_width)
+          + (INTEGERP (w->left_margin_cols)
+             ? XFASTINT (w->left_margin_cols)
              : 0));
       y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
       cursor_to (y, x);
@@ -3631,17 +3654,10 @@ direct_output_for_insert (g)
     rif->update_window_end_hook (w, 1, 0);
   update_end (f);
   updated_row = NULL;
-  fflush (stdout);
+  fflush (TTY_OUTPUT (CURTTY ()));
 
   TRACE ((stderr, "direct output for insert\n"));
-
-  UNCHANGED_MODIFIED = MODIFF;
-  BEG_UNCHANGED = GPT - BEG;
-  XSETFASTINT (w->last_point, PT);
-  w->last_cursor = w->cursor;
-  XSETFASTINT (w->last_modified, MODIFF);
-  XSETFASTINT (w->last_overlay_modified, OVERLAY_MODIFF);
-
+  mark_window_display_accurate (it.window, 1);
   redisplay_performed_directly_p = 1;
   return 1;
 }
@@ -3667,8 +3683,8 @@ direct_output_forward_char (n)
   /* Give up if face attributes have been changed.  */
   if (face_change_count)
     return 0;
-  
-  /* Give up if current matrix is not up to date or we are 
+
+  /* Give up if current matrix is not up to date or we are
      displaying a message.  */
   if (!display_completed || cursor_in_echo_area)
     return 0;
@@ -3695,7 +3711,7 @@ direct_output_forward_char (n)
   if (XWINDOW (minibuf_window) == w
       && EQ (minibuf_window, echo_area_window))
     return 0;
-  
+
   /* Give up if we don't know where the cursor is.  */
   if (w->cursor.vpos < 0)
     return 0;
@@ -3703,18 +3719,18 @@ direct_output_forward_char (n)
   row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
 
   /* Give up if PT is outside of the last known cursor row.  */
-  if (PT <= MATRIX_ROW_START_BYTEPOS (row)
-      || PT >= MATRIX_ROW_END_BYTEPOS (row))
+  if (PT <= MATRIX_ROW_START_CHARPOS (row)
+      || PT >= MATRIX_ROW_END_CHARPOS (row))
     return 0;
 
   set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
-  
+
   w->last_cursor = w->cursor;
   XSETFASTINT (w->last_point, PT);
 
   xassert (w->cursor.hpos >= 0
           && w->cursor.hpos < w->desired_matrix->matrix_w);
-  
+
   if (FRAME_WINDOW_P (f))
     rif->cursor_to (w->cursor.vpos, w->cursor.hpos,
                    w->cursor.y, w->cursor.x);
@@ -3722,14 +3738,14 @@ direct_output_forward_char (n)
     {
       int x, y;
       x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos)
-          + (INTEGERP (w->left_margin_width)
-             ? XFASTINT (w->left_margin_width)
+          + (INTEGERP (w->left_margin_cols)
+             ? XFASTINT (w->left_margin_cols)
              : 0));
       y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
       cursor_to (y, x);
     }
-  
-  fflush (stdout);
+
+  fflush (TTY_OUTPUT (CURTTY ()));
   redisplay_performed_directly_p = 1;
   return 1;
 }
@@ -3745,7 +3761,7 @@ direct_output_forward_char (n)
    If FORCE_P is non-zero, don't let redisplay be stopped by detecting
    pending input.  If INHIBIT_HAIRY_ID_P is non-zero, don't try
    scrolling.
-   
+
    Value is non-zero if redisplay was stopped due to pending input.  */
 
 int
@@ -3778,12 +3794,13 @@ update_frame (f, force_p, inhibit_hairy_id_p)
       /* Update the tool-bar window, if present.  */
       if (WINDOWP (f->tool_bar_window))
        {
-         Lisp_Object tem;
          struct window *w = XWINDOW (f->tool_bar_window);
 
          /* Update tool-bar window.  */
          if (w->must_be_updated_p)
            {
+             Lisp_Object tem;
+
              update_window (w, 1);
              w->must_be_updated_p = 0;
 
@@ -3794,12 +3811,12 @@ update_frame (f, force_p, inhibit_hairy_id_p)
              f->desired_tool_bar_string = tem;
            }
        }
-  
+
 
       /* Update windows.  */
       paused_p = update_window_tree (root_window, force_p);
       update_end (f);
-      
+
 #if 0 /* This flush is a performance bottleneck under X,
         and it doesn't seem to be necessary anyway.  */
       rif->flush_display (f);
@@ -3813,15 +3830,15 @@ update_frame (f, force_p, inhibit_hairy_id_p)
 
       /* Build F's desired matrix from window matrices.  */
       build_frame_matrix (f);
-      
+
       /* Update the display  */
       update_begin (f);
       paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p);
       update_end (f);
 
-      if (termscript)
-       fflush (termscript);
-      fflush (stdout);
+      if (TTY_TERMSCRIPT (FRAME_TTY (f)))
+       fflush (TTY_TERMSCRIPT (FRAME_TTY (f)));
+      fflush (TTY_OUTPUT (FRAME_TTY (f)));
 
       /* Check window matrices for lost pointers.  */
 #if GLYPH_DEBUG
@@ -3832,7 +3849,7 @@ update_frame (f, force_p, inhibit_hairy_id_p)
 
   /* Reset flags indicating that a window should be updated.  */
   set_window_update_flags (root_window, 0);
-  
+
   display_completed = !paused_p;
   return paused_p;
 }
@@ -3852,7 +3869,7 @@ update_window_tree (w, force_p)
      int force_p;
 {
   int paused_p = 0;
-  
+
   while (w && !paused_p)
     {
       if (!NILP (w->hchild))
@@ -3904,7 +3921,7 @@ redraw_overlapped_rows (w, yb)
      int yb;
 {
   int i;
-  
+
   /* If rows overlapping others have been changed, the rows being
      overlapped have to be redrawn.  This won't draw lines that have
      already been drawn in update_window_line because overlapped_p in
@@ -3918,11 +3935,11 @@ redraw_overlapped_rows (w, yb)
        break;
       else if (row->mode_line_p)
        continue;
-      
+
       if (row->overlapped_p)
        {
          enum glyph_row_area area;
-         
+
          for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
            {
              updated_row = row;
@@ -3932,7 +3949,7 @@ redraw_overlapped_rows (w, yb)
                rif->write_glyphs (row->glyphs[area], row->used[area]);
              rif->clear_end_of_line (-1);
            }
-         
+
          row->overlapped_p = 0;
        }
 
@@ -3952,7 +3969,7 @@ redraw_overlapping_rows (w, yb)
 {
   int i, bottom_y;
   struct glyph_row *row;
-  
+
   for (i = 0; i < w->current_matrix->nrows; ++i)
     {
       row = w->current_matrix->rows + i;
@@ -3961,21 +3978,21 @@ redraw_overlapping_rows (w, yb)
        break;
       else if (row->mode_line_p)
        continue;
-      
+
       bottom_y = MATRIX_ROW_BOTTOM_Y (row);
 
       if (row->overlapping_p && i > 0 && bottom_y < yb)
        {
          if (row->used[LEFT_MARGIN_AREA])
            rif->fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
-  
+
          if (row->used[TEXT_AREA])
            rif->fix_overlapping_area (w, row, TEXT_AREA);
-  
+
          if (row->used[RIGHT_MARGIN_AREA])
            rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
 
-         /* Record in neighbor rows that ROW overwrites part of their
+         /* Record in neighbour rows that ROW overwrites part of their
             display.  */
          if (row->phys_ascent > row->ascent && i > 0)
            MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1;
@@ -4031,7 +4048,6 @@ update_window (w, force_p)
   extern Lisp_Object do_mouse_tracking;
 #if GLYPH_DEBUG
   struct frame *f = XFRAME (WINDOW_FRAME (w));
-  extern struct frame *updating_frame;
 #endif
 
   /* Check that W's frame doesn't have glyph matrices.  */
@@ -4050,18 +4066,24 @@ update_window (w, force_p)
     {
       struct glyph_row *row, *end;
       struct glyph_row *mode_line_row;
-      struct glyph_row *header_line_row = NULL;
+      struct glyph_row *header_line_row;
       int yb, changed_p = 0, mouse_face_overwritten_p = 0, n_updated;
 
       rif->update_window_begin_hook (w);
       yb = window_text_bottom_y (w);
 
-      /* If window has a top line, update it before everything else.
-        Adjust y-positions of other rows by the top line height.  */
+      /* If window has a header line, update it before everything else.
+        Adjust y-positions of other rows by the header line height.  */
       row = desired_matrix->rows;
       end = row + desired_matrix->nrows - 1;
+
       if (row->mode_line_p)
-       header_line_row = row++;
+       {
+         header_line_row = row;
+         ++row;
+       }
+      else
+       header_line_row = NULL;
 
       /* Update the mode line, if necessary.  */
       mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
@@ -4079,7 +4101,7 @@ update_window (w, force_p)
         be also completely empty matrices.  */
       while (row < end && !row->enabled_p)
        ++row;
-      
+
       /* Try reusing part of the display by copying.  */
       if (row < end && !desired_matrix->no_scrolling_p)
        {
@@ -4091,11 +4113,12 @@ update_window (w, force_p)
              goto set_cursor;
            }
          else if (rc > 0)
+           /* We've scrolled the display.  */
            force_p = 1;
          changed_p = 1;
        }
 
-      /* Update the top mode line after scrolling because a new top
+      /* Update the header line after scrolling because a new header
         line would otherwise overwrite lines at the top of the window
         that can be scrolled.  */
       if (header_line_row && header_line_row->enabled_p)
@@ -4111,8 +4134,8 @@ update_window (w, force_p)
          {
            int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
            int i;
-           
-           /* We'll Have to play a little bit with when to
+
+           /* We'll have to play a little bit with when to
               detect_input_pending.  If it's done too often,
               scrolling large windows with repeated scroll-up
               commands will too quickly pause redisplay.  */
@@ -4138,10 +4161,10 @@ update_window (w, force_p)
 
       /* Was display preempted?  */
       paused_p = row < end;
-      
+
     set_cursor:
-      
-      /* Fix the appearance of overlapping(overlapped rows.  */
+
+      /* Fix the appearance of overlapping/overlapped rows.  */
       if (!paused_p && !w->pseudo_window_p)
        {
          if (changed_p && rif->fix_overlapping_area)
@@ -4149,7 +4172,7 @@ update_window (w, force_p)
              redraw_overlapped_rows (w, yb);
              redraw_overlapping_rows (w, yb);
            }
-      
+
          /* Make cursor visible at cursor position of W.  */
          set_window_cursor_after_update (w);
 
@@ -4164,8 +4187,11 @@ update_window (w, force_p)
       strcpy (w->current_matrix->method, w->desired_matrix->method);
 #endif
 
-      /* End of update of window W.  */
-      rif->update_window_end_hook (w, 1, mouse_face_overwritten_p);
+      /* End the update of window W.  Don't set the cursor if we
+         paused updating the display because in this case,
+         set_window_cursor_after_update hasn't been called, and
+         output_cursor doesn't contain the cursor location.  */
+      rif->update_window_end_hook (w, !paused_p, mouse_face_overwritten_p);
     }
   else
     paused_p = 1;
@@ -4174,7 +4200,7 @@ update_window (w, force_p)
   /* check_current_matrix_flags (w); */
   add_window_display_history (w, w->current_matrix->method, paused_p);
 #endif
-  
+
   clear_glyph_matrix (desired_matrix);
 
   return paused_p;
@@ -4220,7 +4246,7 @@ update_text_area (w, vpos)
   /* Let functions in xterm.c know what area subsequent X positions
      will be relative to.  */
   updated_area = TEXT_AREA;
-  
+
   /* If rows are at different X or Y, or rows have different height,
      or the current row is marked invalid, write the entire line.  */
   if (!current_row->enabled_p
@@ -4234,14 +4260,24 @@ update_text_area (w, vpos)
       || current_row->x != desired_row->x)
     {
       rif->cursor_to (vpos, 0, desired_row->y, desired_row->x);
-      
+
       if (desired_row->used[TEXT_AREA])
        rif->write_glyphs (desired_row->glyphs[TEXT_AREA],
                           desired_row->used[TEXT_AREA]);
-      
+
       /* Clear to end of window.  */
       rif->clear_end_of_line (-1);
       changed_p = 1;
+
+      /* This erases the cursor.  We do this here because
+         notice_overwritten_cursor cannot easily check this, which
+         might indicate that the whole functionality of
+         notice_overwritten_cursor would better be implemented here.
+         On the other hand, we need notice_overwritten_cursor as long
+         as mouse highlighting is done asynchronously outside of
+         redisplay.  */
+      if (vpos == w->phys_cursor.vpos)
+       w->phys_cursor_on_p = 0;
     }
   else
     {
@@ -4256,7 +4292,7 @@ update_text_area (w, vpos)
         extension actually takes place.  */
       if (MATRIX_ROW_EXTENDS_FACE_P (desired_row))
        --desired_stop_pos;
-      
+
       stop = min (current_row->used[TEXT_AREA], desired_stop_pos);
       i = 0;
       x = desired_row->x;
@@ -4266,7 +4302,7 @@ update_text_area (w, vpos)
       while (i < stop)
        {
          int can_skip_p = 1;
-         
+
          /* Skip over glyphs that both rows have in common.  These
             don't have to be written.  We can't skip if the last
             current glyph overlaps the glyph to its right.  For
@@ -4279,12 +4315,12 @@ update_text_area (w, vpos)
            {
              struct glyph *glyph = &current_row->glyphs[TEXT_AREA][i - 1];
              int left, right;
-             
+
              rif->get_glyph_overhangs (glyph, XFRAME (w->frame),
                                        &left, &right);
              can_skip_p = right == 0;
            }
-         
+
          if (can_skip_p)
            {
              while (i < stop
@@ -4301,7 +4337,7 @@ update_text_area (w, vpos)
                 first `p' in the current row.  If we would start
                 writing glyphs there, we wouldn't erase the lbearing
                 of the `p'.  The rest of the lbearing problem is then
-                taken care of by x_draw_glyphs.  */
+                taken care of by draw_glyphs.  */
              if (overlapping_glyphs_p
                  && i > 0
                  && i < current_row->used[TEXT_AREA]
@@ -4309,7 +4345,7 @@ update_text_area (w, vpos)
                      != desired_row->used[TEXT_AREA]))
                {
                  int left, right;
-             
+
                  rif->get_glyph_overhangs (current_glyph, XFRAME (w->frame),
                                            &left, &right);
                  while (left > 0 && i > 0)
@@ -4320,7 +4356,7 @@ update_text_area (w, vpos)
                    }
                }
            }
-         
+
          /* Try to avoid writing the entire rest of the desired row
             by looking for a resync point.  This mainly prevents
             mode line flickering in the case the mode line is in
@@ -4357,7 +4393,7 @@ update_text_area (w, vpos)
              changed_p = 1;
            }
        }
-      
+
       /* Write the rest.  */
       if (i < desired_row->used[TEXT_AREA])
        {
@@ -4365,7 +4401,7 @@ update_text_area (w, vpos)
          rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i);
          changed_p = 1;
        }
-      
+
       /* Maybe clear to end of line.  */
       if (MATRIX_ROW_EXTENDS_FACE_P (desired_row))
        {
@@ -4380,7 +4416,7 @@ update_text_area (w, vpos)
          /* If old row extends to the end of the text area, clear.  */
          if (i >= desired_row->used[TEXT_AREA])
            rif->cursor_to (vpos, i, desired_row->y,
-                           desired_row->x + desired_row->pixel_width);
+                           desired_row->pixel_width);
          rif->clear_end_of_line (-1);
          changed_p = 1;
        }
@@ -4389,10 +4425,10 @@ update_text_area (w, vpos)
          /* Otherwise clear to the end of the old row.  Everything
             after that position should be clear already.  */
          int x;
-         
+
          if (i >= desired_row->used[TEXT_AREA])
            rif->cursor_to (vpos, i, desired_row->y,
-                           desired_row->x + desired_row->pixel_width);
+                           desired_row->pixel_width);
 
          /* If cursor is displayed at the end of the line, make sure
             it's cleared.  Nowadays we don't have a phys_cursor_glyph
@@ -4406,7 +4442,7 @@ update_text_area (w, vpos)
              x = -1;
            }
          else
-           x = current_row->x + current_row->pixel_width;
+           x = current_row->pixel_width;
          rif->clear_end_of_line (x);
          changed_p = 1;
        }
@@ -4432,8 +4468,8 @@ update_window_line (w, vpos, mouse_face_overwritten_p)
      know what line height values are in effect.  */
   updated_row = desired_row;
 
-  /* A row can be completely invisible in case a desired matrix was 
-     built with a vscroll and then make_cursor_line_fully_visible shifts 
+  /* A row can be completely invisible in case a desired matrix was
+     built with a vscroll and then make_cursor_line_fully_visible shifts
      the matrix.  Make sure to make such rows current anyway, since
      we need the correct y-position, for example, in the current matrix.  */
   if (desired_row->mode_line_p
@@ -4443,12 +4479,12 @@ update_window_line (w, vpos, mouse_face_overwritten_p)
 
       /* Update display of the left margin area, if there is one.  */
       if (!desired_row->full_width_p
-         && !NILP (w->left_margin_width))
+         && !NILP (w->left_margin_cols))
        {
          changed_p = 1;
          update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
        }
-      
+
       /* Update the display of the text area.  */
       if (update_text_area (w, vpos))
        {
@@ -4456,15 +4492,15 @@ update_window_line (w, vpos, mouse_face_overwritten_p)
          if (current_row->mouse_face_p)
            *mouse_face_overwritten_p = 1;
        }
-      
+
       /* Update display of the right margin area, if there is one.  */
       if (!desired_row->full_width_p
-         && !NILP (w->right_margin_width))
+         && !NILP (w->right_margin_cols))
        {
          changed_p = 1;
          update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
        }
-      
+
       /* Draw truncation marks etc.  */
       if (!current_row->enabled_p
          || desired_row->y != current_row->y
@@ -4480,7 +4516,7 @@ update_window_line (w, vpos, mouse_face_overwritten_p)
              != MATRIX_ROW_CONTINUATION_LINE_P (current_row)))
        rif->after_update_window_line_hook (desired_row);
     }
-  
+
   /* Update current_row from desired_row.  */
   make_current (w->desired_matrix, w->current_matrix, vpos);
   updated_row = NULL;
@@ -4500,7 +4536,7 @@ set_window_cursor_after_update (w)
 
   /* Not intended for frame matrix updates.  */
   xassert (FRAME_WINDOW_P (f));
-  
+
   if (cursor_in_echo_area
       && !NILP (echo_area_buffer[0])
       /* If we are showing a message instead of the mini-buffer,
@@ -4525,26 +4561,25 @@ set_window_cursor_after_update (w)
          int yb = window_text_bottom_y (w);
 
          last_row = NULL;
-         for (row = MATRIX_ROW (w->current_matrix, 0);
-              row->enabled_p;
-              ++row)
+         row = w->current_matrix->rows;
+         while (row->enabled_p
+                && (last_row == NULL
+                    || MATRIX_ROW_BOTTOM_Y (row) <= yb))
            {
              if (row->used[TEXT_AREA]
                  && row->glyphs[TEXT_AREA][0].charpos >= 0)
                last_row = row;
-
-             if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
-               break;
+             ++row;
            }
-         
+
          if (last_row)
            {
-             struct glyph *start = row->glyphs[TEXT_AREA];
-             struct glyph *last = start + row->used[TEXT_AREA] - 1;
+             struct glyph *start = last_row->glyphs[TEXT_AREA];
+             struct glyph *last = start + last_row->used[TEXT_AREA] - 1;
 
              while (last > start && last->charpos < 0)
                --last;
-             
+
              for (glyph = start; glyph < last; ++glyph)
                {
                  cx += glyph->pixel_width;
@@ -4592,7 +4627,7 @@ set_window_update_flags (w, on_p)
 
       w = NILP (w->next) ? 0 : XWINDOW (w->next);
     }
-}    
+}
 
 
 \f
@@ -4606,16 +4641,16 @@ struct row_entry
 {
   /* Number of occurrences of this row in desired and current matrix.  */
   int old_uses, new_uses;
-    
+
   /* Vpos of row in new matrix.  */
   int new_line_number;
 
   /* Bucket index of this row_entry in the hash table row_table.  */
   int bucket;
-    
+
   /* The row described by this entry.  */
   struct glyph_row *row;
-    
+
   /* Hash collision chain.  */
   struct row_entry *next;
 };
@@ -4653,10 +4688,6 @@ static int runs_size;
 
 static struct run **runs;
 
-static struct row_entry *add_row_entry P_ ((struct window *,
-                                           struct glyph_row *));
-
-
 /* Add glyph row ROW to the scrolling hash table during the scrolling
    of window W.  */
 
@@ -4667,11 +4698,11 @@ add_row_entry (w, row)
 {
   struct row_entry *entry;
   int i = row->hash % row_table_size;
-  
+
   entry = row_table[i];
   while (entry && !row_equal_p (w, entry->row, row, 1))
     entry = entry->next;
-  
+
   if (entry == NULL)
     {
       entry = row_entry_pool + row_entry_idx++;
@@ -4688,7 +4719,7 @@ add_row_entry (w, row)
 
 
 /* Try to reuse part of the current display of W by scrolling lines.
-   HEADER_LINE_P non-zero means W has a top mode line.
+   HEADER_LINE_P non-zero means W has a header line.
 
    The algorithm is taken from Communications of the ACM, Apr78 "A
    Technique for Isolating Differences Between Files."  It should take
@@ -4748,7 +4779,7 @@ scrolling_window (w, header_line_p)
   /* Give up if some rows in the desired matrix are not enabled.  */
   if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
     return -1;
-  
+
   first_old = first_new = i;
 
   /* Set last_new to the index + 1 of the last enabled row in the
@@ -4800,14 +4831,14 @@ scrolling_window (w, header_line_p)
     return 0;
 
   /* Reallocate vectors, tables etc. if necessary.  */
-  
+
   if (current_matrix->nrows > old_lines_size)
     {
       old_lines_size = current_matrix->nrows;
       nbytes = old_lines_size * sizeof *old_lines;
       old_lines = (struct row_entry **) xrealloc (old_lines, nbytes);
     }
-  
+
   if (desired_matrix->nrows > new_lines_size)
     {
       new_lines_size = desired_matrix->nrows;
@@ -4845,7 +4876,7 @@ scrolling_window (w, header_line_p)
 
   /* Add rows from the current and desired matrix to the hash table
      row_hash_table to be able to find equal ones quickly.  */
-  
+
   for (i = first_old; i < last_old; ++i)
     {
       if (MATRIX_ROW (current_matrix, i)->enabled_p)
@@ -4894,8 +4925,8 @@ scrolling_window (w, header_line_p)
               && old_lines[j] == new_lines[k])
          {
            int h = MATRIX_ROW (current_matrix, j)->height;
-           --run->current_vpos; 
-           --run->desired_vpos; 
+           --run->current_vpos;
+           --run->desired_vpos;
            ++run->nrows;
            run->height += h;
            run->desired_y -= h;
@@ -4911,7 +4942,7 @@ scrolling_window (w, header_line_p)
               && old_lines[j] == new_lines[k])
          {
            int h = MATRIX_ROW (current_matrix, j)->height;
-           ++run->nrows; 
+           ++run->nrows;
            run->height += h;
            ++j, ++k;
          }
@@ -4961,7 +4992,7 @@ scrolling_window (w, header_line_p)
            for (j = i + 1; j < nruns; ++j)
              {
                struct run *p = runs[j];
-               
+
                if ((p->current_y >= r->desired_y
                     && p->current_y < r->desired_y + r->height)
                    || (p->current_y + p->height >= r->desired_y
@@ -5039,7 +5070,7 @@ update_frame_1 (f, force_p, inhibit_id_p)
     }
 
   /* If we cannot insert/delete lines, it's no use trying it.  */
-  if (!line_ins_del_ok)
+  if (!TTY_LINE_INS_DEL_OK (FRAME_TTY (f)))
     inhibit_id_p = 1;
 
   /* See if any of the desired lines are enabled; don't compute for
@@ -5067,18 +5098,18 @@ update_frame_1 (f, force_p, inhibit_id_p)
                 Also flush out if likely to have more than 1k buffered
                 otherwise.   I'm told that some telnet connections get
                 really screwed by more than 1k output at once.  */
-             int outq = PENDING_OUTPUT_COUNT (stdout);
+             int outq = PENDING_OUTPUT_COUNT (TTY_OUTPUT (FRAME_TTY (f)));
              if (outq > 900
                  || (outq > 20 && ((i - 1) % preempt_count == 0)))
                {
-                 fflush (stdout);
+                 fflush (TTY_OUTPUT (FRAME_TTY (f)));
                  if (preempt_count == 1)
                    {
 #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);
+                          the outq count.  */
+                       outq = PENDING_OUTPUT_COUNT (TTY_OUTPUT (FRAME_TTY (f)));
 #endif
                      outq *= 10;
                      if (baud_rate <= outq && baud_rate > 0)
@@ -5093,8 +5124,8 @@ update_frame_1 (f, force_p, inhibit_id_p)
          update_frame_line (f, i);
        }
     }
-  
-  pause = (i < FRAME_HEIGHT (f) - 1) ? i : 0;
+
+  pause = (i < FRAME_LINES (f) - 1) ? i : 0;
 
   /* Now just clean up termcap drivers and set cursor, etc.  */
   if (!pause)
@@ -5111,7 +5142,7 @@ update_frame_1 (f, force_p, inhibit_id_p)
          && FRAME_HAS_MINIBUF_P (f)
          && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
        {
-         int top = XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top);
+         int top = WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f)));
          int row, col;
 
          if (cursor_in_echo_area < 0)
@@ -5127,12 +5158,12 @@ update_frame_1 (f, force_p, inhibit_id_p)
                 cursor at the end of the prompt.  If the mini-buffer
                 is several lines high, find the last line that has
                 any text on it.  */
-             row = FRAME_HEIGHT (f);
-             do 
+             row = FRAME_LINES (f);
+             do
                {
                  --row;
                  col = 0;
-                 
+
                  if (MATRIX_ROW_ENABLED_P (current_matrix, row))
                    {
                      /* Frame rows are filled up with spaces that
@@ -5145,7 +5176,7 @@ update_frame_1 (f, force_p, inhibit_id_p)
                      while (last > start
                             && (last - 1)->charpos < 0)
                        --last;
-                     
+
                      col = last - start;
                    }
                }
@@ -5155,9 +5186,9 @@ update_frame_1 (f, force_p, inhibit_id_p)
              if (col >= FRAME_CURSOR_X_LIMIT (f))
                {
                  /* If we have another row, advance cursor into it.  */
-                 if (row < FRAME_HEIGHT (f) - 1)
+                 if (row < FRAME_LINES (f) - 1)
                    {
-                     col = FRAME_LEFT_SCROLL_BAR_WIDTH (f);
+                     col = FRAME_LEFT_SCROLL_BAR_COLS (f);
                      row++;
                    }
                  /* Otherwise move it back in range.  */
@@ -5179,15 +5210,15 @@ update_frame_1 (f, force_p, inhibit_id_p)
                 with the cursor in the lower half of it.  The window
                 is split, and a message causes a redisplay before
                 a new cursor position has been computed.  */
-             && w->cursor.vpos < XFASTINT (w->height))
+             && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
            {
              int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
              int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
 
-             if (INTEGERP (w->left_margin_width))
-               x += XFASTINT (w->left_margin_width);
-             
-             /* x = max (min (x, FRAME_WINDOW_WIDTH (f) - 1), 0); */
+             if (INTEGERP (w->left_margin_cols))
+               x += XFASTINT (w->left_margin_cols);
+
+             /* x = max (min (x, FRAME_TOTAL_COLS (f) - 1), 0); */
              cursor_to (y, x);
            }
        }
@@ -5209,12 +5240,12 @@ scrolling (frame)
   int unchanged_at_top, unchanged_at_bottom;
   int window_size;
   int changed_lines;
-  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));
-  int *old_draw_cost = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
+  int *old_hash = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
+  int *new_hash = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
+  int *draw_cost = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
+  int *old_draw_cost = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
   register int i;
-  int free_at_end_vpos = FRAME_HEIGHT (frame);
+  int free_at_end_vpos = FRAME_LINES (frame);
   struct glyph_matrix *current_matrix = frame->current_matrix;
   struct glyph_matrix *desired_matrix = frame->desired_matrix;
 
@@ -5226,8 +5257,8 @@ scrolling (frame)
      number of unchanged lines at the end.  */
   changed_lines = 0;
   unchanged_at_top = 0;
-  unchanged_at_bottom = FRAME_HEIGHT (frame);
-  for (i = 0; i < FRAME_HEIGHT (frame); i++)
+  unchanged_at_bottom = FRAME_LINES (frame);
+  for (i = 0; i < FRAME_LINES (frame); i++)
     {
       /* Give up on this scrolling if some old lines are not enabled.  */
       if (!MATRIX_ROW_ENABLED_P (current_matrix, i))
@@ -5249,7 +5280,7 @@ scrolling (frame)
       if (old_hash[i] != new_hash[i])
        {
          changed_lines++;
-         unchanged_at_bottom = FRAME_HEIGHT (frame) - i - 1;
+         unchanged_at_bottom = FRAME_LINES (frame) - i - 1;
        }
       else if (i == unchanged_at_top)
        unchanged_at_top++;
@@ -5257,24 +5288,26 @@ scrolling (frame)
     }
 
   /* If changed lines are few, don't allow preemption, don't scroll.  */
-  if ((!scroll_region_ok && changed_lines < baud_rate / 2400)
-      || unchanged_at_bottom == FRAME_HEIGHT (frame))
+  if ((!TTY_SCROLL_REGION_OK (FRAME_TTY (frame))
+       && changed_lines < baud_rate / 2400)
+      || unchanged_at_bottom == FRAME_LINES (frame))
     return 1;
 
-  window_size = (FRAME_HEIGHT (frame) - unchanged_at_top
+  window_size = (FRAME_LINES (frame) - unchanged_at_top
                 - unchanged_at_bottom);
 
-  if (scroll_region_ok)
+  if (TTY_SCROLL_REGION_OK (FRAME_TTY (frame)))
     free_at_end_vpos -= unchanged_at_bottom;
-  else if (memory_below_frame)
+  else if (TTY_MEMORY_BELOW_FRAME (FRAME_TTY (frame)))
     free_at_end_vpos = -1;
 
   /* If large window, fast terminal and few lines in common between
      current frame and desired frame, don't bother with i/d calc.  */
-  if (!scroll_region_ok && window_size >= 18 && baud_rate > 2400
+  if (!TTY_SCROLL_REGION_OK (FRAME_TTY (frame))
+      && window_size >= 18 && baud_rate > 2400
       && (window_size >=
          10 * scrolling_max_lines_saved (unchanged_at_top,
-                                         FRAME_HEIGHT (frame) - unchanged_at_bottom,
+                                         FRAME_LINES (frame) - unchanged_at_bottom,
                                          old_hash, new_hash, draw_cost)))
     return 0;
 
@@ -5301,7 +5334,7 @@ count_blanks (r, len)
      int len;
 {
   int i;
-  
+
   for (i = 0; i < len; ++i)
     if (!CHAR_GLYPH_SPACE_P (r[i]))
       break;
@@ -5320,12 +5353,12 @@ count_match (str1, end1, str2, end2)
 {
   struct glyph *p1 = str1;
   struct glyph *p2 = str2;
-  
+
   while (p1 < end1
         && p2 < end2
         && GLYPH_CHAR_AND_FACE_EQUAL_P (p1, p2))
     ++p1, ++p2;
-  
+
   return p1 - str1;
 }
 
@@ -5333,7 +5366,7 @@ count_match (str1, end1, str2, end2)
 /* Char insertion/deletion cost vector, from term.c */
 
 extern int *char_ins_del_vector;
-#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WINDOW_WIDTH((f))])
+#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_TOTAL_COLS((f))])
 
 
 /* Perform a frame-based update on line VPOS in frame FRAME.  */
@@ -5351,23 +5384,13 @@ update_frame_line (f, vpos)
   struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos);
   struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, vpos);
   int must_write_whole_line_p;
-  int write_spaces_p = must_write_spaces;
+  int write_spaces_p = TTY_MUST_WRITE_SPACES (FRAME_TTY (f));
   int colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background
                          != FACE_TTY_DEFAULT_BG_COLOR);
 
   if (colored_spaces_p)
     write_spaces_p = 1;
 
-  if (desired_row->inverse_p
-      != (current_row->enabled_p && current_row->inverse_p))
-    {
-      int n = current_row->enabled_p ? current_row->used[TEXT_AREA] : 0;
-      change_line_highlight (desired_row->inverse_p, vpos, vpos, n);
-      current_row->enabled_p = 0;
-    }
-  else
-    reassert_line_highlight (desired_row->inverse_p, vpos);
-
   /* Current row not enabled means it has unknown contents.  We must
      write the whole desired line in that case.  */
   must_write_whole_line_p = !current_row->enabled_p;
@@ -5380,27 +5403,15 @@ update_frame_line (f, vpos)
     {
       obody = MATRIX_ROW_GLYPH_START (current_matrix, vpos);
       olen = current_row->used[TEXT_AREA];
-      
-      if (!current_row->inverse_p)
-       {
-         /* Ignore trailing spaces, if we can.  */
-         if (!write_spaces_p)
-           while (olen > 0 && CHAR_GLYPH_SPACE_P (obody[olen-1]))
-             olen--;
-       }
-      else
-       {
-         /* For an inverse-video line, make sure it's filled with
-            spaces all the way to the frame edge so that the reverse
-            video extends all the way across.  */
-         while (olen < FRAME_WIDTH (f) - 1)
-           obody[olen++] = space_glyph;
-       }
+
+      /* Ignore trailing spaces, if we can.  */
+      if (!write_spaces_p)
+       while (olen > 0 && CHAR_GLYPH_SPACE_P (obody[olen-1]))
+         olen--;
     }
 
   current_row->enabled_p = 1;
   current_row->used[TEXT_AREA] = desired_row->used[TEXT_AREA];
-  current_row->inverse_p = desired_row->inverse_p;
 
   /* If desired line is empty, just clear the line.  */
   if (!desired_row->enabled_p)
@@ -5427,43 +5438,32 @@ update_frame_line (f, vpos)
           cursor_to (vpos, 0);
          write_glyphs (nbody, nlen);
        }
-      
+
       /* Don't call clear_end_of_line if we already wrote the whole
         line.  The cursor will not be at the right margin in that
         case but in the line below.  */
-      if (nlen < FRAME_WINDOW_WIDTH (f))
+      if (nlen < FRAME_TOTAL_COLS (f))
        {
          cursor_to (vpos, nlen);
-          clear_end_of_line (FRAME_WINDOW_WIDTH (f));
+          clear_end_of_line (FRAME_TOTAL_COLS (f));
        }
       else
        /* Make sure we are in the right row, otherwise cursor movement
           with cmgoto might use `ch' in the wrong row.  */
        cursor_to (vpos, 0);
-      
+
       make_current (desired_matrix, current_matrix, vpos);
       return;
     }
 
   /* Pretend trailing spaces are not there at all,
      unless for one reason or another we must write all spaces.  */
-  if (!desired_row->inverse_p)
-    {
-      if (!write_spaces_p)
-       while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
-         nlen--;
-    }
-  else
-    {
-      /* For an inverse-video line, give it extra trailing spaces all
-        the way to the frame edge so that the reverse video extends
-        all the way across.  */
-      while (nlen < FRAME_WIDTH (f) - 1)
-       nbody[nlen++] = space_glyph;
-    }
+  if (!write_spaces_p)
+    while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
+      nlen--;
 
   /* If there's no i/d char, quickly do the best we can without it.  */
-  if (!char_ins_del_ok)
+  if (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f)))
     {
       int i, j;
 
@@ -5480,8 +5480,8 @@ update_frame_line (f, vpos)
                         || !GLYPH_EQUAL_P (nbody + j, obody + j)
                         || CHAR_GLYPH_PADDING_P (nbody[j])))
                ++j;
-                    
-             /* Output this run of non-matching chars.  */ 
+
+             /* Output this run of non-matching chars.  */
              cursor_to (vpos, i);
              write_glyphs (nbody + i, j - i);
              i = j - 1;
@@ -5509,7 +5509,7 @@ update_frame_line (f, vpos)
     {
       /* If current line is blank, skip over initial spaces, if
         possible, and write the rest.  */
-      if (write_spaces_p || desired_row->inverse_p)
+      if (write_spaces_p)
        nsp = 0;
       else
        nsp = count_blanks (nbody, nlen);
@@ -5527,9 +5527,7 @@ update_frame_line (f, vpos)
 
   /* Compute number of leading blanks in old and new contents.  */
   osp = count_blanks (obody, olen);
-  nsp = (desired_row->inverse_p || colored_spaces_p
-        ? 0
-        : count_blanks (nbody, nlen));
+  nsp = (colored_spaces_p ? 0 : count_blanks (nbody, nlen));
 
   /* Compute number of matching chars starting with first non-blank.  */
   begmatch = count_match (obody + osp, obody + olen,
@@ -5568,7 +5566,8 @@ update_frame_line (f, vpos)
 
   tem = (nlen - nsp) - (olen - osp);
   if (endmatch && tem
-      && (!char_ins_del_ok || endmatch <= char_ins_del_cost (f)[tem]))
+      && (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f))
+          || endmatch <= char_ins_del_cost (f)[tem]))
     endmatch = 0;
 
   /* nsp - osp is the distance to insert or delete.
@@ -5577,7 +5576,7 @@ update_frame_line (f, vpos)
      Is it worth it?  */
 
   if (nsp != osp
-      && (!char_ins_del_ok
+      && (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f))
          || begmatch + endmatch <= char_ins_del_cost (f)[nsp - osp]))
     {
       begmatch = 0;
@@ -5618,7 +5617,7 @@ update_frame_line (f, vpos)
             no need to do clear-to-eol at the end of this function
             (and it would not be safe, since cursor is not going to
             be "at the margin" after the text is done).  */
-         if (nlen == FRAME_WINDOW_WIDTH (f))
+         if (nlen == FRAME_TOTAL_COLS (f))
            olen = 0;
 
          /* Function write_glyphs is prepared to do nothing
@@ -5643,17 +5642,17 @@ update_frame_line (f, vpos)
          int del;
 
          cursor_to (vpos, nsp + begmatch);
-         
+
          /* Calculate columns we can actually overwrite.  */
          while (CHAR_GLYPH_PADDING_P (nbody[nsp + begmatch + out]))
            out--;
          write_glyphs (nbody + nsp + begmatch, out);
-         
+
          /* If we left columns to be overwritten, we must delete them.  */
          del = olen - tem - out;
          if (del > 0)
            delete_glyphs (del);
-         
+
          /* At last, we insert columns not yet written out.  */
          insert_glyphs (nbody + nsp + begmatch + out, nlen - olen + del);
          olen = nlen;
@@ -5685,79 +5684,216 @@ update_frame_line (f, vpos)
                   X/Y Position -> Buffer Position
  ***********************************************************************/
 
-/* Return the character position of the character at window relative
-   pixel position (*X, *Y).  *X and *Y are adjusted to character
-   boundaries.  */
+/* Determine what's under window-relative pixel position (*X, *Y).
+   Return in *OBJECT the object (string or buffer) that's there.
+   Return in *POS the position in that object. Adjust *X and *Y
+   to character positions.  */
 
-int
-buffer_posn_from_coords (w, x, y)
+void
+buffer_posn_from_coords (w, x, y, dx, dy, object, pos)
      struct window *w;
      int *x, *y;
+     int *dx, *dy;
+     Lisp_Object *object;
+     struct display_pos *pos;
 {
   struct it it;
   struct buffer *old_current_buffer = current_buffer;
   struct text_pos startp;
-  int left_area_width;
+  int x0, x1;
 
   current_buffer = XBUFFER (w->buffer);
   SET_TEXT_POS_FROM_MARKER (startp, w->start);
   CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
   BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
   start_display (&it, w, startp);
-  
-  left_area_width = WINDOW_DISPLAY_LEFT_AREA_PIXEL_WIDTH (w);
-  move_it_to (&it, -1, *x + it.first_visible_x - left_area_width, *y, -1,
+
+  x0 = *x - WINDOW_LEFT_MARGIN_WIDTH (w);
+  move_it_to (&it, -1, x0 + it.first_visible_x, *y, -1,
              MOVE_TO_X | MOVE_TO_Y);
-  
-  *x = it.current_x - it.first_visible_x + left_area_width;
-  *y = it.current_y;
+
   current_buffer = old_current_buffer;
-  return IT_CHARPOS (it);
+
+  *dx = x0 + it.first_visible_x - it.current_x;
+  *dy = *y - it.current_y;
+
+  *object =  w->buffer;
+
+#ifdef HAVE_WINDOW_SYSTEM
+  if (it.what == IT_IMAGE)
+    {
+      struct image *img;
+      if ((img = IMAGE_FROM_ID (it.f, it.image_id)) != NULL
+         && !NILP (img->spec))
+       {
+         struct glyph_row *row = MATRIX_ROW (w->current_matrix, it.vpos);
+         struct glyph *glyph;
+
+         if (it.hpos < row->used[TEXT_AREA]
+             && (glyph = row->glyphs[TEXT_AREA] + it.hpos,
+                 glyph->type == IMAGE_GLYPH))
+           {
+             *dy -= row->ascent - glyph->ascent;
+             *object = img->spec;
+           }
+       }
+    }
+  else
+#endif
+    if (STRINGP (it.string))
+      *object = it.string;
+
+  *pos = it.current;
+
+  /* Add extra (default width) columns if clicked after EOL. */
+  x1 = max(0, it.current_x + it.pixel_width - it.first_visible_x);
+  if (x0 > x1)
+    it.hpos += (x0 - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
+
+  *x = it.hpos;
+  *y = it.vpos;
 }
 
 
 /* Value is the string under window-relative coordinates X/Y in the
-   mode or top line of window W, or nil if none.  MODE_LINE_P non-zero
+   mode or header line of window W, or nil if none.  MODE_LINE_P non-zero
    means look at the mode line.  *CHARPOS is set to the position in
    the string returned.  */
 
 Lisp_Object
-mode_line_string (w, x, y, mode_line_p, charpos)
+mode_line_string (w, x, y, dx, dy, part, charpos)
      struct window *w;
-     int x, y, mode_line_p;
+     int *x, *y;
+     int *dx, *dy;
+     enum window_part part;
      int *charpos;
 {
   struct glyph_row *row;
   struct glyph *glyph, *end;
-  struct frame *f = XFRAME (w->frame);
-  int x0;
+  int x0, y0;
   Lisp_Object string = Qnil;
 
-  if (mode_line_p)
+  if (part == ON_MODE_LINE)
     row = MATRIX_MODE_LINE_ROW (w->current_matrix);
   else
     row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
+  y0 = *y - row->y;
+  *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix);
 
   if (row->mode_line_p && row->enabled_p)
     {
-      /* The mode lines are displayed over scroll bars and bitmap
-        areas, and X is window-relative.  Correct X by the scroll bar
-        and bitmap area width.  */
-      if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
-       x += FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
-      x += FRAME_LEFT_FLAGS_AREA_WIDTH (f);
-
       /* Find the glyph under X.  If we find one with a string object,
          it's the one we were looking for.  */
       glyph = row->glyphs[TEXT_AREA];
       end = glyph + row->used[TEXT_AREA];
-      for (x0 = 0; glyph < end; x0 += glyph->pixel_width, ++glyph)
-       if (x >= x0 && x < x0 + glyph->pixel_width)
-         {
-           string = glyph->object;
-           *charpos = glyph->charpos;
-           break;
-         }
+      for (x0 = *x; glyph < end && x0 > glyph->pixel_width; ++glyph)
+       x0 -= glyph->pixel_width;
+      *x = glyph - row->glyphs[TEXT_AREA];
+      if (glyph < end)
+       {
+         string = glyph->object;
+         *charpos = glyph->charpos;
+       }
+      else
+       /* Add extra (default width) columns if clicked after EOL. */
+       *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
+    }
+  else
+    {
+      *x = 0;
+      x0 = 0;
+    }
+
+  if (dx)
+    {
+      *dx = x0;
+      *dy = y0;
+    }
+
+  return string;
+}
+
+
+/* Value is the string under window-relative coordinates X/Y in either
+   marginal area, or nil if none.  *CHARPOS is set to the position in
+   the string returned.  */
+
+Lisp_Object
+marginal_area_string (w, x, y, dx, dy, part, charpos)
+     struct window *w;
+     int *x, *y;
+     int *dx, *dy;
+     enum window_part part;
+     int *charpos;
+{
+  struct glyph_row *row = w->current_matrix->rows;
+  struct glyph *glyph, *end;
+  int x0, y0, i, wy = *y;
+  int area;
+  Lisp_Object string = Qnil;
+
+  if (part == ON_LEFT_MARGIN)
+    area = LEFT_MARGIN_AREA;
+  else if (part == ON_RIGHT_MARGIN)
+    area = RIGHT_MARGIN_AREA;
+  else
+    abort ();
+
+  for (i = 0; row->enabled_p && i < w->current_matrix->nrows; ++i, ++row)
+    if (wy >= row->y && wy < MATRIX_ROW_BOTTOM_Y (row))
+      break;
+  y0 = *y - row->y;
+  *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix);
+
+  if (row->enabled_p)
+    {
+      /* Find the glyph under X.  If we find one with a string object,
+        it's the one we were looking for.  */
+      if (area == RIGHT_MARGIN_AREA)
+       x0 = ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+              ? WINDOW_LEFT_FRINGE_WIDTH (w) 
+              : WINDOW_TOTAL_FRINGE_WIDTH (w))
+             + window_box_width (w, LEFT_MARGIN_AREA)
+             + window_box_width (w, TEXT_AREA));
+      else
+       x0 = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+             ? WINDOW_LEFT_FRINGE_WIDTH (w) 
+             : 0);
+
+      glyph = row->glyphs[area];
+      end = glyph + row->used[area];
+      for (x0 = *x - x0; glyph < end && x0 > glyph->pixel_width; ++glyph)
+       x0 -= glyph->pixel_width;
+      *x = glyph - row->glyphs[area];
+      if (glyph < end)
+       {
+         string = glyph->object;
+         *charpos = glyph->charpos;
+#ifdef HAVE_WINDOW_SYSTEM
+         if (glyph->type == IMAGE_GLYPH)
+           {
+             struct image *img;
+             img = IMAGE_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
+             if (img != NULL)
+               string = img->spec;
+             y0 -= row->ascent - glyph->ascent;
+           }
+#endif
+       }
+      else
+       /* Add extra (default width) columns if clicked after EOL. */
+       *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
+    }
+  else
+    {
+      x0 = 0;
+      *x = 0;
+    }
+
+  if (dx)
+    {
+      *dx = x0;
+      *dy = y0;
     }
 
   return string;
@@ -5780,28 +5916,35 @@ window_change_signal (signalnum) /* If we don't have an argument, */
 #endif
   int old_errno = errno;
 
-  get_frame_size (&width, &height);
-
-  /* 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 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, frame;
-
-    FOR_EACH_FRAME (tail, frame)
-      {
-       if (FRAME_TERMCAP_P (XFRAME (frame)))
-         {
-           change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
-           break;
-         }
-      }
+  struct tty_output *tty;
+  
+  /* The frame size change obviously applies to a single
+     termcap-controlled terminal, but we can't decide which.
+     Therefore, we resize the frames corresponding to each tty.
+  */
+  for (tty = tty_list; tty; tty = tty->next) {
+
+    if (! tty->term_initted)
+      continue;
+    
+    get_tty_size (tty, &width, &height);
+    
+    {
+      Lisp_Object tail, frame;
+      
+      FOR_EACH_FRAME (tail, frame)
+        {
+          if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty)
+            {
+              /* Record the new sizes, but don't reallocate the data structures
+                 now.  Let that be done later outside of the signal handler.  */
+              change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
+              break;
+            }
+        }
+    }
   }
-
+  
   signal (SIGWINCH, window_change_signal);
   errno = old_errno;
 }
@@ -5819,7 +5962,7 @@ do_pending_window_change (safe)
   /* If window_change_signal should have run before, run it now.  */
   if (redisplaying_p && !safe)
     return;
-  
+
   while (delayed_size_change)
     {
       Lisp_Object tail, frame;
@@ -5830,18 +5973,16 @@ do_pending_window_change (safe)
        {
          struct frame *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, safe);
+         if (f->new_text_lines != 0 || f->new_text_cols != 0)
+           change_frame_size (f, f->new_text_lines, f->new_text_cols,
+                              0, 0, safe);
        }
     }
 }
 
 
 /* Change the frame height and/or width.  Values may be given as zero to
-   indicate no change is to take place. 
+   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
@@ -5858,10 +5999,11 @@ change_frame_size (f, newheight, newwidth, pretend, delay, safe)
 {
   Lisp_Object tail, frame;
 
-  if (! FRAME_WINDOW_P (f))
+  if (FRAME_MSDOS_P (f))
     {
-      /* When using termcap, or on MS-DOS, all frames use
-        the same screen, so a change in size affects all frames.  */
+      /* On MS-DOS, all frames use the same screen, so a change in
+         size affects all frames.  Termcap now supports multiple
+         ttys. */
       FOR_EACH_FRAME (tail, frame)
        if (! FRAME_WINDOW_P (XFRAME (frame)))
          change_frame_size_1 (XFRAME (frame), newheight, newwidth,
@@ -5876,38 +6018,38 @@ change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
      register struct frame *f;
      int newheight, newwidth, pretend, delay, safe;
 {
-  int new_frame_window_width;
-  int count = specpdl_ptr - specpdl;
+  int new_frame_total_cols;
+  int count = SPECPDL_INDEX ();
 
   /* If we can't deal with the change now, queue it for later.  */
   if (delay || (redisplaying_p && !safe))
     {
-      FRAME_NEW_HEIGHT (f) = newheight;
-      FRAME_NEW_WIDTH (f) = newwidth;
+      f->new_text_lines = newheight;
+      f->new_text_cols = newwidth;
       delayed_size_change = 1;
       return;
     }
 
   /* This size-change overrides any pending one for this frame.  */
-  FRAME_NEW_HEIGHT (f) = 0;
-  FRAME_NEW_WIDTH  (f) = 0;
+  f->new_text_lines = 0;
+  f->new_text_cols = 0;
 
   /* If an argument is zero, set it to the current value.  */
   if (newheight == 0)
-    newheight = FRAME_HEIGHT (f);
+    newheight = FRAME_LINES (f);
   if (newwidth == 0)
-    newwidth  = FRAME_WIDTH  (f);
+    newwidth  = FRAME_COLS  (f);
 
   /* Compute width of windows in F.
      This is the width of the frame without vertical scroll bars.  */
-  new_frame_window_width = FRAME_WINDOW_WIDTH_ARG (f, newwidth);
+  new_frame_total_cols = FRAME_TOTAL_COLS_ARG (f, newwidth);
 
   /* Round up to the smallest acceptable size.  */
   check_frame_size (f, &newheight, &newwidth);
 
   /* If we're not changing the frame size, quit now.  */
-  if (newheight == FRAME_HEIGHT (f)
-      && new_frame_window_width == FRAME_WINDOW_WIDTH (f))
+  if (newheight == FRAME_LINES (f)
+      && new_frame_total_cols == FRAME_TOTAL_COLS (f))
     return;
 
   BLOCK_INPUT;
@@ -5919,19 +6061,19 @@ change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
   dos_set_window_size (&newheight, &newwidth);
 #endif
 
-  if (newheight != FRAME_HEIGHT (f))
+  if (newheight != FRAME_LINES (f))
     {
       if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
        {
          /* Frame has both root and mini-buffer.  */
-         XSETFASTINT (XWINDOW (FRAME_ROOT_WINDOW (f))->top,
+         XSETFASTINT (XWINDOW (FRAME_ROOT_WINDOW (f))->top_line,
                       FRAME_TOP_MARGIN (f));
          set_window_height (FRAME_ROOT_WINDOW (f),
                             (newheight
                              - 1
                              - FRAME_TOP_MARGIN (f)),
                              0);
-         XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top,
+         XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top_line,
                       newheight - 1);
          set_window_height (FRAME_MINIBUF_WINDOW (f), 1, 0);
        }
@@ -5941,29 +6083,29 @@ change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
                           newheight - FRAME_TOP_MARGIN (f), 0);
 
       if (FRAME_TERMCAP_P (f) && !pretend)
-       FrameRows = newheight;
+       FrameRows (FRAME_TTY (f)) = newheight;
     }
 
-  if (new_frame_window_width  != FRAME_WINDOW_WIDTH (f))
+  if (new_frame_total_cols != FRAME_TOTAL_COLS (f))
     {
-      set_window_width (FRAME_ROOT_WINDOW (f), new_frame_window_width, 0);
+      set_window_width (FRAME_ROOT_WINDOW (f), new_frame_total_cols, 0);
       if (FRAME_HAS_MINIBUF_P (f))
-       set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_window_width, 0);
+       set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_total_cols, 0);
 
       if (FRAME_TERMCAP_P (f) && !pretend)
-       FrameCols = newwidth;
+       FrameCols (FRAME_TTY (f)) = newwidth;
 
       if (WINDOWP (f->tool_bar_window))
-       XSETFASTINT (XWINDOW (f->tool_bar_window)->width, newwidth);
+       XSETFASTINT (XWINDOW (f->tool_bar_window)->total_cols, newwidth);
     }
 
-  FRAME_HEIGHT (f) = newheight;
-  SET_FRAME_WIDTH (f, newwidth);
+  FRAME_LINES (f) = newheight;
+  SET_FRAME_COLS (f, newwidth);
 
   {
     struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
     int text_area_x, text_area_y, text_area_width, text_area_height;
-    
+
     window_box (w, TEXT_AREA, &text_area_x, &text_area_y, &text_area_width,
                &text_area_height);
     if (w->cursor.x >= text_area_x + text_area_width)
@@ -5973,8 +6115,9 @@ change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
   }
 
   adjust_glyphs (f);
-  SET_FRAME_GARBAGED (f);
   calculate_costs (f);
+  SET_FRAME_GARBAGED (f);
+  f->resized_p = 1;
 
   UNBLOCK_INPUT;
 
@@ -5982,7 +6125,7 @@ change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
 
   /* This isn't quite a no-op: it runs window-configuration-change-hook.  */
   Fset_window_buffer (FRAME_SELECTED_WINDOW (f),
-                     XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer);
+                     XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer, Qt);
 
   unbind_to (count, Qnil);
 }
@@ -5994,20 +6137,21 @@ change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
  ***********************************************************************/
 
 DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
-  1, 1, "FOpen termscript file: ",
-  "Start writing all terminal output to FILE as well as the terminal.\n\
-FILE = nil means just close any termscript file currently open.")
-  (file)
+       1, 1, "FOpen termscript file: ",
+       doc: /* Start writing all terminal output to FILE as well as the terminal.
+FILE = nil means just close any termscript file currently open.  */)
+     (file)
      Lisp_Object file;
 {
-  if (termscript != 0) fclose (termscript);
-  termscript = 0;
+  if (TTY_TERMSCRIPT (CURTTY ()) != 0)
+    fclose (TTY_TERMSCRIPT (CURTTY ()));
+  TTY_TERMSCRIPT (CURTTY ()) = 0;
 
   if (! NILP (file))
     {
       file = Fexpand_file_name (file, Qnil);
-      termscript = fopen (XSTRING (file)->data, "w");
-      if (termscript == 0)
+      TTY_TERMSCRIPT (CURTTY ()) = fopen (SDATA (file), "w");
+      if (TTY_TERMSCRIPT (CURTTY ()) == 0)
        report_file_error ("Opening termscript", Fcons (file, Qnil));
     }
   return Qnil;
@@ -6015,31 +6159,32 @@ FILE = nil means just close any termscript file currently open.")
 
 
 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
-  Ssend_string_to_terminal, 1, 1, 0,
-  "Send STRING to the terminal without alteration.\n\
-Control characters in STRING will have terminal-dependent effects.")
-  (string)
+       Ssend_string_to_terminal, 1, 1, 0,
+       doc: /* Send STRING to the terminal without alteration.
+Control characters in STRING will have terminal-dependent effects.  */)
+     (string)
      Lisp_Object string;
 {
   /* ??? Perhaps we should do something special for multibyte strings here.  */
-  CHECK_STRING (string, 0);
-  fwrite (XSTRING (string)->data, 1, STRING_BYTES (XSTRING (string)), stdout);
-  fflush (stdout);
-  if (termscript)
+  CHECK_STRING (string);
+  if (TTY_TERMSCRIPT (CURTTY ()))
     {
-      fwrite (XSTRING (string)->data, 1, STRING_BYTES (XSTRING (string)),
-             termscript);
-      fflush (termscript);
+      fwrite (SDATA (string), 1, SBYTES (string),
+             TTY_TERMSCRIPT (CURTTY ()));
+      fflush (TTY_TERMSCRIPT (CURTTY ()));
     }
+  fwrite (SDATA (string), 1, SBYTES (string),
+          TTY_OUTPUT (CURTTY ()));
+  fflush (TTY_OUTPUT (CURTTY ()));
   return Qnil;
 }
 
 
 DEFUN ("ding", Fding, Sding, 0, 1, 0,
-  "Beep, or flash the screen.\n\
-Also, unless an argument is given,\n\
-terminate any keyboard macro currently executing.")
-  (arg)
+       doc: /* Beep, or flash the screen.
+Also, unless an argument is given,
+terminate any keyboard macro currently executing.  */)
+     (arg)
   Lisp_Object arg;
 {
   if (!NILP (arg))
@@ -6048,7 +6193,7 @@ terminate any keyboard macro currently executing.")
        putchar (07);
       else
        ring_bell ();
-      fflush (stdout);
+      fflush (TTY_OUTPUT (CURTTY ()));
     }
   else
     bitch_at_user ();
@@ -6065,7 +6210,7 @@ bitch_at_user ()
     error ("Keyboard macro terminated by a command ringing the bell");
   else
     ring_bell ();
-  fflush (stdout);
+  fflush (TTY_OUTPUT (CURTTY ()));
 }
 
 
@@ -6075,13 +6220,13 @@ bitch_at_user ()
  ***********************************************************************/
 
 DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
-  "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)
+       doc: /* Pause, without updating display, for SECONDS seconds.
+SECONDS may be a floating-point value, meaning that you can wait for a
+fraction of a second.  Optional second arg MILLISECONDS specifies an
+additional wait period, in milliseconds; this may be useful if your
+Emacs was built without floating point support.
+\(Not all operating systems support waiting for a fraction of a second.)  */)
+     (seconds, milliseconds)
      Lisp_Object seconds, milliseconds;
 {
   int sec, usec;
@@ -6089,7 +6234,7 @@ Emacs was built without floating point support.\n\
   if (NILP (milliseconds))
     XSETINT (milliseconds, 0);
   else
-    CHECK_NUMBER (milliseconds, 1);
+    CHECK_NUMBER (milliseconds);
   usec = XINT (milliseconds) * 1000;
 
   {
@@ -6106,7 +6251,7 @@ Emacs was built without floating point support.\n\
   /* Assure that 0 <= usec < 1000000.  */
   if (usec < 0)
     {
-      /* We can't rely on the rounding being correct if user is negative.  */
+      /* We can't rely on the rounding being correct if usec is negative.  */
       if (-1000000 < usec)
        sec--, usec += 1000000;
       else
@@ -6135,14 +6280,14 @@ Emacs was built without floating point support.\n\
 #ifdef VMS
   sys_sleep (sec);
 #else /* not VMS */
-/* The reason this is done this way 
+/* The reason this is done this way
     (rather than defined (H_S) && defined (H_T))
-   is because the VMS preprocessor doesn't grok `defined' */
+   is because the VMS preprocessor doesn't grok `defined' */
 #ifdef HAVE_SELECT
   EMACS_GET_TIME (end_time);
   EMACS_SET_SECS_USECS (timeout, sec, usec);
   EMACS_ADD_TIME (end_time, end_time, timeout);
+
   while (1)
     {
       EMACS_GET_TIME (timeout);
@@ -6155,7 +6300,7 @@ Emacs was built without floating point support.\n\
   sleep (sec);
 #endif /* HAVE_SELECT */
 #endif /* not VMS */
-  
+
   immediate_quit = 0;
 #endif /* no subprocesses */
 
@@ -6177,7 +6322,7 @@ sit_for (sec, usec, reading, display, initial_display)
 
   swallow_events (display);
 
-  if (detect_input_pending_run_timers (display))
+  if (detect_input_pending_run_timers (display) || !NILP (Vexecuting_macro))
     return Qnil;
 
   if (initial_display)
@@ -6198,25 +6343,39 @@ sit_for (sec, usec, reading, display, initial_display)
 
 
 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 NODISP 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)
+       doc: /* Perform redisplay, then wait for SECONDS seconds or until input is available.
+SECONDS may be a floating-point value, meaning that you can wait for a
+fraction of a second.
+\(Not all operating systems support waiting for a fraction of a second.)
+Optional arg NODISP non-nil means don't redisplay, just wait for input.
+Redisplay is preempted as always if input arrives, and does not happen
+if input is available before it starts.
+Value is t if waited the full time with no input arriving.
+
+An obsolete but still supported form is
+\(sit-for SECONDS &optional MILLISECONDS NODISP)
+Where the optional arg MILLISECONDS specifies an additional wait period,
+in milliseconds; this was useful when Emacs was built without
+floating point support.
+usage: (sit-for SECONDS &optional NODISP OLD-NODISP) */)
+
+/* The `old-nodisp' stuff is there so that the arglist has the correct
+   length.  Otherwise, `defdvice' will redefine it with fewer args.  */
+     (seconds, milliseconds, nodisp)
      Lisp_Object seconds, milliseconds, nodisp;
 {
   int sec, usec;
 
+  if (NILP (nodisp) && !NUMBERP (milliseconds))
+    { /* New style.  */
+      nodisp = milliseconds;
+      milliseconds = Qnil;
+    }
+
   if (NILP (milliseconds))
     XSETINT (milliseconds, 0);
   else
-    CHECK_NUMBER (milliseconds, 1);
+    CHECK_NUMBER (milliseconds);
   usec = XINT (milliseconds) * 1000;
 
   {
@@ -6248,15 +6407,15 @@ static Lisp_Object frame_and_buffer_state;
 
 
 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p,
-  Sframe_or_buffer_changed_p, 0, 0, 0,
-  "Return non-nil if the frame and buffer state appears to have changed.\n\
-The state variable is an internal vector containing all frames and buffers,\n\
-aside from buffers whose names start with space,\n\
-along with the buffers' read-only and modified flags, which allows a fast\n\
-check to see whether the menu bars might need to be recomputed.\n\
-If this function returns non-nil, it updates the internal vector to reflect\n\
-the current state.\n")
-  ()
+       Sframe_or_buffer_changed_p, 0, 0, 0,
+       doc: /* Return non-nil if the frame and buffer state appears to have changed.
+The state variable is an internal vector containing all frames and buffers,
+aside from buffers whose names start with space,
+along with the buffers' read-only and modified flags, which allows a fast
+check to see whether the menu bars might need to be recomputed.
+If this function returns non-nil, it updates the internal vector to reflect
+the current state.  */)
+     ()
 {
   Lisp_Object tail, frame, buf;
   Lisp_Object *vecp;
@@ -6278,7 +6437,7 @@ the current state.\n")
     {
       buf = XCDR (XCAR (tail));
       /* Ignore buffers that aren't included in buffer lists.  */
-      if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
+      if (SREF (XBUFFER (buf)->name, 0) == ' ')
        continue;
       if (!EQ (*vecp++, buf))
        goto changed;
@@ -6312,7 +6471,7 @@ the current state.\n")
     {
       buf = XCDR (XCAR (tail));
       /* Ignore buffers that aren't included in buffer lists.  */
-      if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
+      if (SREF (XBUFFER (buf)->name, 0) == ' ')
        continue;
       *vecp++ = buf;
       *vecp++ = XBUFFER (buf)->read_only;
@@ -6336,8 +6495,6 @@ the current state.\n")
                            Initialization
 ***********************************************************************/
 
-char *terminal_type;
-
 /* Initialization done when Emacs fork is started, before doing stty.
    Determine terminal type and set terminal_driver.  Then invoke its
    decoding routine to set up variables in the terminal package.  */
@@ -6345,6 +6502,8 @@ char *terminal_type;
 void
 init_display ()
 {
+  char *terminal_type;
+
 #ifdef HAVE_X_WINDOWS
   extern int display_arg;
 #endif
@@ -6354,7 +6513,6 @@ init_display ()
   SET_CHAR_GLYPH_FROM_GLYPH (space_glyph, ' ');
   space_glyph.charpos = -1;
 
-  meta_key = 0;
   inverse_video = 0;
   cursor_in_echo_area = 0;
   terminal_type = (char *) 0;
@@ -6384,7 +6542,7 @@ init_display ()
       display_arg = (display != 0 && *display != 0);
     }
 
-  if (!inhibit_window_system && display_arg 
+  if (!inhibit_window_system && display_arg
 #ifndef CANNOT_DUMP
      && initialized
 #endif
@@ -6396,7 +6554,7 @@ init_display ()
 #else
       Vwindow_system_version = make_number (10);
 #endif
-#if defined (LINUX) && defined (HAVE_LIBNCURSES)
+#if defined (GNU_LINUX) && defined (HAVE_LIBNCURSES)
       /* In some versions of ncurses,
         tputs crashes if we have not called tgetent.
         So call tgetent.  */
@@ -6408,7 +6566,7 @@ init_display ()
 #endif /* HAVE_X_WINDOWS */
 
 #ifdef HAVE_NTGUI
-  if (!inhibit_window_system) 
+  if (!inhibit_window_system)
     {
       Vwindow_system = intern ("w32");
       Vwindow_system_version = make_number (1);
@@ -6417,15 +6575,15 @@ init_display ()
     }
 #endif /* HAVE_NTGUI */
 
-#ifdef macintosh
-  if (!inhibit_window_system) 
+#ifdef MAC_OS
+  if (!inhibit_window_system)
     {
       Vwindow_system = intern ("mac");
       Vwindow_system_version = make_number (1);
       adjust_frame_glyphs_initially ();
       return;
     }
-#endif /* macintosh */
+#endif /* MAC_OS */
 
   /* If no window system has been specified, try to use the terminal.  */
   if (! isatty (0))
@@ -6434,7 +6592,7 @@ init_display ()
       exit (1);
     }
 
-  /* Look at the TERM variable */
+  /* Look at the TERM variable */
   terminal_type = (char *) getenv ("TERM");
   if (!terminal_type)
     {
@@ -6463,15 +6621,20 @@ For types not defined in VMS, use  define emacs_term \"TYPE\".\n\
        *p = tolower (*p);
 
     terminal_type = new;
-  }    
+  }
 #endif /* VMS */
 
-  term_init (terminal_type);
+  {
+    struct tty_output *tty;
+    
+    tty = term_init (selected_frame, 0, terminal_type);
+    change_frame_size (XFRAME (selected_frame), FrameRows (tty), FrameCols (tty), 0, 0, 0);
+  }
   
   {
     struct frame *sf = SELECTED_FRAME ();
-    int width = FRAME_WINDOW_WIDTH (sf);
-    int height = FRAME_HEIGHT (sf);
+    int width = FRAME_TOTAL_COLS (sf);
+    int height = FRAME_LINES (sf);
 
     unsigned int total_glyphs = height * (width + 2) * sizeof (struct glyph);
 
@@ -6521,11 +6684,11 @@ For types not defined in VMS, use  define emacs_term \"TYPE\".\n\
 
 DEFUN ("internal-show-cursor", Finternal_show_cursor,
        Sinternal_show_cursor, 2, 2, 0,
-  "Set the cursor-visibility flag of WINDOW to SHOW.\n\
-WINDOW nil means use the selected window.  SHOW non-nil means\n\
-show a cursor in WINDOW in the next redisplay.  SHOW nil means\n\
-don't show a cursor.")
-  (window, show)
+       doc: /* Set the cursor-visibility flag of WINDOW to SHOW.
+WINDOW nil means use the selected window.  SHOW non-nil means
+show a cursor in WINDOW in the next redisplay.  SHOW nil means
+don't show a cursor.  */)
+     (window, show)
      Lisp_Object window, show;
 {
   /* Don't change cursor state while redisplaying.  This could confuse
@@ -6535,8 +6698,8 @@ don't show a cursor.")
       if (NILP (window))
        window = selected_window;
       else
-       CHECK_WINDOW (window, 2);
-      
+       CHECK_WINDOW (window);
+
       XWINDOW (window)->cursor_off_p = NILP (show);
     }
 
@@ -6546,20 +6709,20 @@ don't show a cursor.")
 
 DEFUN ("internal-show-cursor-p", Finternal_show_cursor_p,
        Sinternal_show_cursor_p, 0, 1, 0,
-  "Value is non-nil if next redisplay will display a cursor in WINDOW.\n\
-WINDOW nil or omitted means report on the selected window.")
-  (window)
+       doc: /* Value is non-nil if next redisplay will display a cursor in WINDOW.
+WINDOW nil or omitted means report on the selected window.  */)
+     (window)
      Lisp_Object window;
 {
   struct window *w;
-  
+
   if (NILP (window))
     window = selected_window;
   else
-    CHECK_WINDOW (window, 2);
-  
+    CHECK_WINDOW (window);
+
   w = XWINDOW (window);
-  return w->cursor_off_p ? Qnil : Qt;    
+  return w->cursor_off_p ? Qnil : Qt;
 }
 
 \f
@@ -6594,51 +6757,55 @@ syms_of_display ()
   staticpro (&Qredisplay_dont_pause);
 
   DEFVAR_INT ("baud-rate", &baud_rate,
-    "*The output baud rate of the terminal.\n\
-On most systems, changing this value will affect the amount of padding\n\
-and the other strategic decisions made during redisplay.");
-  
+             doc: /* *The output baud rate of the terminal.
+On most systems, changing this value will affect the amount of padding
+and the other strategic decisions made during redisplay.  */);
+
   DEFVAR_BOOL ("inverse-video", &inverse_video,
-    "*Non-nil means invert the entire frame display.\n\
-This means everything is in inverse video which otherwise would not be.");
-  
+              doc: /* *Non-nil means invert the entire frame display.
+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 frame to represent a bell.");
-  
+              doc: /* *Non-nil means try to flash the frame to represent a bell.
+
+See also `ring-bell-function'.  */);
+
   DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter,
-    "*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 frame display when you reenter Emacs.\n\
-It is up to you to set this variable if your terminal can do that.");
-  
+              doc: /* *Non-nil means no need to redraw entire frame after suspending.
+A non-nil value is useful if the terminal can automatically preserve
+Emacs's frame display when you reenter Emacs.
+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\
-\(such as `x'), or nil if emacs is running on an ordinary terminal.");
-  
+              doc: /* Name of window system that Emacs is displaying through.
+The value is a symbol--for instance, `x' for X windows.
+The value is nil if Emacs is using a text-only terminal.  */);
+
   DEFVAR_LISP ("window-system-version", &Vwindow_system_version,
-    "The version number of the window system in use.\n\
-For X windows, this is 10 or 11.");
-  
+              doc: /* The version number of the window system in use.
+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.");
-  
+              doc: /* 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 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\
- string: output this glyph using that string (not impl. in X windows).\n\
- nil: this glyph mod 256 is char code to output,\n\
-    and this glyph / 256 is face code for X windows (see `face-id').");
+              doc: /* Table defining how to output a glyph code to the frame.
+If not nil, this is a vector indexed by glyph code to define the glyph.
+Each element can be:
+ integer: a glyph code which this glyph is an alias for.
+ string: output this glyph using that string (not impl. in X windows).
+ nil: this glyph mod 524288 is the code of a character to output,
+    and this glyph / 524288 is the face number (see `face-id') to use
+    while outputting it.  */);
   Vglyph_table = Qnil;
 
   DEFVAR_LISP ("standard-display-table", &Vstandard_display_table,
-    "Display table to use for buffers that specify none.\n\
-See `buffer-display-table' for more information.");
+              doc: /* Display table to use for buffers that specify none.
+See `buffer-display-table' for more information.  */);
   Vstandard_display_table = Qnil;
 
   DEFVAR_BOOL ("redisplay-dont-pause", &redisplay_dont_pause,
-    "*Non-nil means update isn't paused when input is detected.");
+              doc: /* *Non-nil means update isn't paused when input is detected.  */);
   redisplay_dont_pause = 0;
 
   /* Initialize `window-system', unless init_display already decided it.  */
@@ -6650,3 +6817,6 @@ See `buffer-display-table' for more information.");
       Vwindow_system_version = Qnil;
     }
 }
+
+/* arch-tag: 8d812b1f-04a2-4195-a9c4-381f8457a413
+   (do not change this comment) */