Support menus on text-mode terminals.
[bpt/emacs.git] / src / dispnew.c
index 519659a..f5d213e 100644 (file)
@@ -20,8 +20,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 
-#define DISPEXTERN_INLINE EXTERN_INLINE
-
 #include "sysstdio.h"
 #include <unistd.h>
 
@@ -49,12 +47,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include TERM_HEADER
 #endif /* HAVE_WINDOW_SYSTEM */
 
-/* Include systime.h after xterm.h to avoid double inclusion of time.h.  */
-
-#include "systime.h"
 #include <errno.h>
 
 #include <fpending.h>
+#include <timespec.h>
 
 #if defined (HAVE_TERM_H) && defined (GNU_LINUX)
 #include <term.h>              /* for tgetent */
@@ -79,7 +75,6 @@ struct dim
 static void update_frame_line (struct frame *, int);
 static int required_matrix_height (struct window *);
 static int required_matrix_width (struct window *);
-static void adjust_frame_glyphs (struct frame *);
 static void change_frame_size_1 (struct frame *, int, int, bool, bool, bool);
 static void increment_row_positions (struct glyph_row *, ptrdiff_t, ptrdiff_t);
 static void fill_up_frame_row_with_spaces (struct glyph_row *, int);
@@ -107,39 +102,16 @@ static void set_window_cursor_after_update (struct window *);
 static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
 static void adjust_frame_glyphs_for_frame_redisplay (struct frame *);
 
-/* True upon entry to redisplay means do not assume anything about
-   current contents of actual terminal frame; clear and redraw it.  */
-
-bool frame_garbaged;
-
 /* True means last display completed.  False means it was preempted.  */
 
 bool display_completed;
 
 Lisp_Object Qdisplay_table, Qredisplay_dont_pause;
 
-\f
-/* The currently selected frame.  In a single-frame version, this
-   variable always equals the_only_frame.  */
-
-Lisp_Object selected_frame;
-
-/* A frame which is not just a mini-buffer, or 0 if there are no such
-   frames.  This is usually the most recent such frame that was
-   selected.  In a single-frame version, this variable always holds
-   the address of the_only_frame.  */
-
-struct frame *last_nonminibuf_frame;
-
 /* True means SIGWINCH happened when not safe.  */
 
 static bool delayed_size_change;
 
-/* Glyph row updated in update_window_line, and area that is updated.  */
-
-struct glyph_row *updated_row;
-int updated_area;
-
 /* A glyph for a space.  */
 
 struct glyph space_glyph;
@@ -159,16 +131,6 @@ static int glyph_pool_count;
 
 static struct frame *frame_matrix_frame;
 
-/* True means that fonts have been loaded since the last glyph
-   matrix adjustments.  Redisplay must stop, and glyph matrices must
-   be adjusted when this flag becomes true during display.  The
-   reason fonts can be loaded so late is that fonts of fontsets are
-   loaded on demand.  Another reason is that a line contains many
-   characters displayed by zero width or very narrow glyphs of
-   variable-width fonts.  */
-
-bool fonts_changed_p;
-
 /* Convert vpos and hpos from frame to window and vice versa.
    This may only be used for terminal frames.  */
 
@@ -359,25 +321,19 @@ free_glyph_matrix (struct glyph_matrix *matrix)
 /* Return the number of glyphs to reserve for a marginal area of
    window W.  TOTAL_GLYPHS is the number of glyphs in a complete
    display line of window W.  MARGIN gives the width of the marginal
-   area in canonical character units.  MARGIN should be an integer
-   or a float.  */
+   area in canonical character units.  */
 
 static int
-margin_glyphs_to_reserve (struct window *w, int total_glyphs, Lisp_Object margin)
+margin_glyphs_to_reserve (struct window *w, int total_glyphs, int margin)
 {
-  int n;
-
-  if (NUMBERP (margin))
+  if (margin > 0)
     {
       int width = w->total_cols;
-      double d = max (0, XFLOATINT (margin));
+      double d = max (0, margin);
       d = min (width / 2 - 1, d);
-      n = (int) ((double) total_glyphs / width * d);
+      return (int) ((double) total_glyphs / width * d);
     }
-  else
-    n = 0;
-
-  return n;
+  return 0;
 }
 
 /* Return true if ROW's hash value is correct.
@@ -426,7 +382,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
      Get W's size.  */
   if (w)
     {
-      window_box (w, -1, 0, 0, &window_width, &window_height);
+      window_box (w, ANY_AREA, 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;
@@ -446,7 +402,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
                                  || right != matrix->right_margin_glyphs);
 
       if (!marginal_areas_changed_p
-         && !fonts_changed_p
+         && !XFRAME (w->frame)->fonts_changed
          && !header_line_changed_p
          && matrix->window_left_col == WINDOW_LEFT_EDGE_COL (w)
          && matrix->window_top_line == WINDOW_TOP_EDGE_LINE (w)
@@ -604,8 +560,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
 
              /* Window end is invalid, if inside of the rows that
                 are invalidated below.  */
-             if (INTEGERP (w->window_end_vpos)
-                 && XFASTINT (w->window_end_vpos) >= i)
+             if (w->window_end_vpos >= i)
                w->window_end_valid = 0;
 
              while (i < matrix->nrows)
@@ -808,9 +763,11 @@ clear_current_matrices (register struct frame *f)
     clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
 #endif
 
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
   /* Clear the matrix of the tool-bar window, if any.  */
   if (WINDOWP (f->tool_bar_window))
     clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
+#endif
 
   /* Clear current window matrices.  */
   eassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
@@ -831,8 +788,10 @@ clear_desired_matrices (register struct frame *f)
     clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
 #endif
 
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
   if (WINDOWP (f->tool_bar_window))
     clear_glyph_matrix (XWINDOW (f->tool_bar_window)->desired_matrix);
+#endif
 
   /* Do it for window matrices.  */
   eassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
@@ -873,41 +832,16 @@ clear_window_matrices (struct window *w, bool desired_p)
       See dispextern.h for an overall explanation of glyph rows.
  ***********************************************************************/
 
-/* Clear glyph row ROW.  Do it in a way that makes it robust against
-   changes in the glyph_row structure, i.e. addition or removal of
-   structure members.  */
-
-static struct glyph_row null_row;
+/* Clear glyph row ROW.  NOTE: this code relies on the current
+   layout of `glyphs' and `used' fields of `struct glyph_row'.  */
 
 void
 clear_glyph_row (struct glyph_row *row)
 {
-  struct glyph *p[1 + LAST_AREA];
-
-  /* Save pointers.  */
-  p[LEFT_MARGIN_AREA] = row->glyphs[LEFT_MARGIN_AREA];
-  p[TEXT_AREA] = row->glyphs[TEXT_AREA];
-  p[RIGHT_MARGIN_AREA] = row->glyphs[RIGHT_MARGIN_AREA];
-  p[LAST_AREA] = row->glyphs[LAST_AREA];
-
-  /* Clear.  */
-  *row = null_row;
-
-  /* Restore pointers.  */
-  row->glyphs[LEFT_MARGIN_AREA] = p[LEFT_MARGIN_AREA];
-  row->glyphs[TEXT_AREA] = p[TEXT_AREA];
-  row->glyphs[RIGHT_MARGIN_AREA] = p[RIGHT_MARGIN_AREA];
-  row->glyphs[LAST_AREA] = p[LAST_AREA];
-
-#if 0 /* At some point, some bit-fields of struct glyph were not set,
-        which made glyphs unequal when compared with GLYPH_EQUAL_P.
-        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
-        are that the flickering has the same reason as here.  */
-  memset (p[0], 0, (char *) p[LAST_AREA] - (char *) p[0]);
-#endif
+  enum { off = offsetof (struct glyph_row, used) };
+
+  /* Zero everything except pointers in `glyphs'.  */
+  memset (row->used, 0, sizeof *row - off);
 }
 
 
@@ -1046,29 +980,17 @@ swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b)
 }
 
 
-/* Copy glyph row structure FROM to glyph row structure TO, except
-   that glyph pointers, the `used' counts, and the hash values in the
-   structures are left unchanged.  */
+/* Copy glyph row structure FROM to glyph row structure TO, except that
+   glyph pointers, the `used' counts, and the hash values in the structures
+   are left unchanged.  NOTE: this code relies on the current layout of
+   `glyphs', `used', `hash' and `x' fields of `struct glyph_row'.  */
 
 static void
 copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from)
 {
-  struct glyph *pointers[1 + LAST_AREA];
-  short used[LAST_AREA];
-  unsigned hashval;
-
-  /* Save glyph pointers of TO.  */
-  memcpy (pointers, to->glyphs, sizeof to->glyphs);
-  memcpy (used, to->used, sizeof to->used);
-  hashval = to->hash;
-
-  /* Do a structure assignment.  */
-  *to = *from;
-
-  /* Restore original pointers of TO.  */
-  memcpy (to->glyphs, pointers, sizeof to->glyphs);
-  memcpy (to->used, used, sizeof to->used);
-  to->hash = hashval;
+  enum { off = offsetof (struct glyph_row, x) };
+
+  memcpy (&to->x, &from->x, sizeof *to - off);
 }
 
 
@@ -1813,37 +1735,17 @@ allocate_matrices_for_window_redisplay (struct window *w)
     }
 }
 
-
-/* Re-allocate/ re-compute glyph matrices on frame F.  If F is null,
-   do it for all frames; otherwise do it just for the given frame.
-   This function must be called when a new frame is created, its size
-   changes, or its window configuration changes.  */
+/* Allocate/reallocate glyph matrices of a single frame F.
+   This function must be called when a new frame is created,
+   its size changes, or its window configuration changes.  */
 
 void
-adjust_glyphs (struct frame *f)
+adjust_frame_glyphs (struct frame *f)
 {
   /* Block input so that expose events and other events that access
      glyph matrices are not processed while we are changing them.  */
   block_input ();
 
-  if (f)
-    adjust_frame_glyphs (f);
-  else
-    {
-      Lisp_Object tail, lisp_frame;
-
-      FOR_EACH_FRAME (tail, lisp_frame)
-       adjust_frame_glyphs (XFRAME (lisp_frame));
-    }
-
-  unblock_input ();
-}
-
-/* Allocate/reallocate glyph matrices of a single frame F.  */
-
-static void
-adjust_frame_glyphs (struct frame *f)
-{
   if (FRAME_WINDOW_P (f))
     adjust_frame_glyphs_for_window_redisplay (f);
   else
@@ -1853,6 +1755,8 @@ adjust_frame_glyphs (struct frame *f)
   adjust_decode_mode_spec_buffer (f);
 
   f->glyphs_initialized_p = 1;
+
+  unblock_input ();
 }
 
 /* Return true if any window in the tree has nonzero window margins.  See
@@ -1867,7 +1771,7 @@ showing_window_margins_p (struct window *w)
          if (showing_window_margins_p (XWINDOW (w->contents)))
            return 1;
        }
-      else if (!NILP (w->left_margin_cols) || !NILP (w->right_margin_cols))
+      else if (w->left_margin_cols > 0 || w->right_margin_cols > 0)
        return 1;
 
       w = NILP (w->next) ? 0 : XWINDOW (w->next);
@@ -1940,9 +1844,28 @@ save_current_matrix (struct frame *f)
       struct glyph_row *from = f->current_matrix->rows + i;
       struct glyph_row *to = saved->rows + i;
       ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+
       to->glyphs[TEXT_AREA] = xmalloc (nbytes);
       memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
       to->used[TEXT_AREA] = from->used[TEXT_AREA];
+      to->enabled_p = from->enabled_p;
+      to->hash = from->hash;
+      if (from->used[LEFT_MARGIN_AREA])
+       {
+         nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph);
+         to->glyphs[LEFT_MARGIN_AREA] = (struct glyph *) xmalloc (nbytes);
+         memcpy (to->glyphs[LEFT_MARGIN_AREA],
+                 from->glyphs[LEFT_MARGIN_AREA], nbytes);
+         to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA];
+       }
+      if (from->used[RIGHT_MARGIN_AREA])
+       {
+         nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph);
+         to->glyphs[RIGHT_MARGIN_AREA] = (struct glyph *) xmalloc (nbytes);
+         memcpy (to->glyphs[RIGHT_MARGIN_AREA],
+                 from->glyphs[RIGHT_MARGIN_AREA], nbytes);
+         to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA];
+       }
     }
 
   return saved;
@@ -1962,9 +1885,30 @@ restore_current_matrix (struct frame *f, struct glyph_matrix *saved)
       struct glyph_row *from = saved->rows + i;
       struct glyph_row *to = f->current_matrix->rows + i;
       ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+
       memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
       to->used[TEXT_AREA] = from->used[TEXT_AREA];
       xfree (from->glyphs[TEXT_AREA]);
+      nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph);
+      if (nbytes)
+       {
+         memcpy (to->glyphs[LEFT_MARGIN_AREA],
+                 from->glyphs[LEFT_MARGIN_AREA], nbytes);
+         to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA];
+         xfree (from->glyphs[LEFT_MARGIN_AREA]);
+       }
+      else
+       to->used[LEFT_MARGIN_AREA] = 0;
+      nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph);
+      if (nbytes)
+       {
+         memcpy (to->glyphs[RIGHT_MARGIN_AREA],
+                 from->glyphs[RIGHT_MARGIN_AREA], nbytes);
+         to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA];
+         xfree (from->glyphs[RIGHT_MARGIN_AREA]);
+       }
+      else
+       to->used[RIGHT_MARGIN_AREA] = 0;
     }
 
   xfree (saved->rows);
@@ -2084,10 +2028,9 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
   /* Allocate/reallocate window matrices.  */
   allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)));
 
-#ifdef HAVE_X_WINDOWS
+#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
   /* Allocate/ reallocate matrices of the dummy window used to display
      the menu bar under X when no X toolkit support is available.  */
-#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
   {
     /* Allocate a dummy window if not already done.  */
     struct window *w;
@@ -2111,10 +2054,9 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
     w->total_cols = FRAME_TOTAL_COLS (f);
     allocate_matrices_for_window_redisplay (w);
   }
-#endif /* not USE_X_TOOLKIT && not USE_GTK */
-#endif /* HAVE_X_WINDOWS */
+#endif
 
-#ifndef USE_GTK
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
   {
     /* Allocate/ reallocate matrices of the tool bar window.  If we
        don't have a tool bar window yet, make one.  */
@@ -2188,6 +2130,7 @@ free_glyphs (struct frame *f)
        }
 #endif
 
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
       /* Free the tool bar window and its glyph matrices.  */
       if (!NILP (f->tool_bar_window))
        {
@@ -2197,6 +2140,7 @@ free_glyphs (struct frame *f)
          w->desired_matrix = w->current_matrix = NULL;
          fset_tool_bar_window (f, Qnil);
        }
+#endif
 
       /* Release frame glyph matrices.  Reset fields to zero in
         case we are called a second time.  */
@@ -3006,7 +2950,7 @@ redraw_frame (struct frame *f)
   /* Mark all windows as inaccurate, so that every window will have
      its redisplay done.  */
   mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
-  set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
+  set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), NULL, 1);
   f->garbaged = 0;
 }
 
@@ -3079,6 +3023,7 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
        update_window (XWINDOW (f->menu_bar_window), 1);
 #endif
 
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
       /* Update the tool-bar window, if present.  */
       if (WINDOWP (f->tool_bar_window))
        {
@@ -3099,21 +3044,11 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
              fset_desired_tool_bar_string (f, tem);
            }
        }
-
+#endif
 
       /* Update windows.  */
       paused_p = update_window_tree (root_window, force_p);
       update_end (f);
-
-      /* This flush is a performance bottleneck under X,
-        and it doesn't seem to be necessary anyway (in general).
-         It is necessary when resizing the window with the mouse, or
-        at least the fringes are not redrawn in a timely manner.  ++kfs */
-      if (f->force_flush_display_p)
-       {
-         FRAME_RIF (f)->flush_display (f);
-         f->force_flush_display_p = 0;
-       }
     }
   else
     {
@@ -3146,12 +3081,53 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
 
  do_pause:
   /* Reset flags indicating that a window should be updated.  */
-  set_window_update_flags (root_window, 0);
+  set_window_update_flags (root_window, NULL, 0);
 
   display_completed = !paused_p;
   return paused_p;
 }
 
+/* Update a TTY frame F that has a menu dropped down over some of its
+   glyphs.  This is like the second part of update_frame, but it
+   doesn't call build_frame_matrix, because we already have the
+   desired matrix prepared, and don't want it to be overwritten by the
+   text of the normal display.  */
+void
+update_frame_with_menu (struct frame *f)
+{
+  struct window *root_window = XWINDOW (f->root_window);
+  bool paused_p;
+
+  eassert (FRAME_TERMCAP_P (f));
+
+  /* We are working on frame matrix basis.  Set the frame on whose
+     frame matrix we operate.  */
+  set_frame_matrix_frame (f);
+
+  /* Update the display  */
+  update_begin (f);
+  /* Force update_frame_1 not to stop due to pending input, and not
+     try scrolling.  */
+  paused_p = update_frame_1 (f, 1, 1);
+  update_end (f);
+
+  if (FRAME_TTY (f)->termscript)
+    fflush (FRAME_TTY (f)->termscript);
+  fflush (FRAME_TTY (f)->output);
+  /* Check window matrices for lost pointers.  */
+#if GLYPH_DEBUG
+#if 0
+      /* We cannot possibly survive the matrix pointers check, since
+        we have overwritten parts of the frame glyph matrix without
+        making any updates to the window matrices.  */
+  check_window_matrix_pointers (root_window);
+#endif
+  add_frame_display_history (f, paused_p);
+#endif
+
+  /* Reset flags indicating that a window should be updated.  */
+  set_window_update_flags (root_window, NULL, 0);
+}
 
 \f
 /************************************************************************
@@ -3237,14 +3213,12 @@ redraw_overlapped_rows (struct window *w, int yb)
 
          for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
            {
-             updated_row = row;
-             updated_area = area;
-             FRAME_RIF (f)->cursor_to (w, i, 0, row->y,
-                                        area == TEXT_AREA ? row->x : 0);
+             output_cursor_to (w, i, 0, row->y,
+                               area == TEXT_AREA ? row->x : 0);
              if (row->used[area])
-               FRAME_RIF (f)->write_glyphs (w, row->glyphs[area],
-                                             row->used[area]);
-             FRAME_RIF (f)->clear_end_of_line (w, -1);
+               FRAME_RIF (f)->write_glyphs (w, row, row->glyphs[area],
+                                             area, row->used[area]);
+             FRAME_RIF (f)->clear_end_of_line (w, row, area, -1);
            }
 
          row->overlapped_p = 0;
@@ -3497,7 +3471,7 @@ update_window (struct window *w, bool force_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.  */
+         W->output_cursor doesn't contain the cursor location.  */
       rif->update_window_end_hook (w, !paused_p, mouse_face_overwritten_p);
     }
   else
@@ -3518,22 +3492,20 @@ update_window (struct window *w, bool force_p)
    AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA.  */
 
 static void
-update_marginal_area (struct window *w, int area, int vpos)
+update_marginal_area (struct window *w, struct glyph_row *updated_row,
+                     enum glyph_row_area area, int vpos)
 {
   struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
   struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
 
-  /* Let functions in xterm.c know what area subsequent X positions
-     will be relative to.  */
-  updated_area = area;
-
   /* Set cursor to start of glyphs, write them, and clear to the end
      of the area.  I don't think that something more sophisticated is
      necessary here, since marginal areas will not be the default.  */
-  rif->cursor_to (w, vpos, 0, desired_row->y, 0);
+  output_cursor_to (w, vpos, 0, desired_row->y, 0);
   if (desired_row->used[area])
-    rif->write_glyphs (w, desired_row->glyphs[area], desired_row->used[area]);
-  rif->clear_end_of_line (w, -1);
+    rif->write_glyphs (w, updated_row, desired_row->glyphs[area],
+                      area, desired_row->used[area]);
+  rif->clear_end_of_line (w, updated_row, area, -1);
 }
 
 
@@ -3541,17 +3513,13 @@ update_marginal_area (struct window *w, int area, int vpos)
    Value is true if display has changed.  */
 
 static bool
-update_text_area (struct window *w, int vpos)
+update_text_area (struct window *w, struct glyph_row *updated_row, int vpos)
 {
   struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
   struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
   struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
   bool changed_p = 0;
 
-  /* 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
@@ -3571,14 +3539,14 @@ update_text_area (struct window *w, int vpos)
          && !(current_row->mode_line_p && vpos > 0))
       || current_row->x != desired_row->x)
     {
-      rif->cursor_to (w, vpos, 0, desired_row->y, desired_row->x);
+      output_cursor_to (w, vpos, 0, desired_row->y, desired_row->x);
 
       if (desired_row->used[TEXT_AREA])
-       rif->write_glyphs (w, desired_row->glyphs[TEXT_AREA],
-                          desired_row->used[TEXT_AREA]);
+       rif->write_glyphs (w, updated_row, desired_row->glyphs[TEXT_AREA],
+                          TEXT_AREA, desired_row->used[TEXT_AREA]);
 
       /* Clear to end of window.  */
-      rif->clear_end_of_line (w, -1);
+      rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
       changed_p = 1;
 
       /* This erases the cursor.  We do this here because
@@ -3714,8 +3682,9 @@ update_text_area (struct window *w, int vpos)
                  break;
                }
 
-             rif->cursor_to (w, vpos, start_hpos, desired_row->y, start_x);
-             rif->write_glyphs (w, start, i - start_hpos);
+             output_cursor_to (w, vpos, start_hpos, desired_row->y, start_x);
+             rif->write_glyphs (w, updated_row, start,
+                                TEXT_AREA, i - start_hpos);
              changed_p = 1;
            }
        }
@@ -3723,8 +3692,9 @@ update_text_area (struct window *w, int vpos)
       /* Write the rest.  */
       if (i < desired_row->used[TEXT_AREA])
        {
-         rif->cursor_to (w, vpos, i, desired_row->y, x);
-         rif->write_glyphs (w, desired_glyph, desired_row->used[TEXT_AREA] - i);
+         output_cursor_to (w, vpos, i, desired_row->y, x);
+         rif->write_glyphs (w, updated_row, desired_glyph,
+                            TEXT_AREA, desired_row->used[TEXT_AREA] - i);
          changed_p = 1;
        }
 
@@ -3744,9 +3714,9 @@ update_text_area (struct window *w, int vpos)
        {
          /* If old row extends to the end of the text area, clear.  */
          if (i >= desired_row->used[TEXT_AREA])
-           rif->cursor_to (w, vpos, i, desired_row->y,
-                           desired_row->pixel_width);
-         rif->clear_end_of_line (w, -1);
+           output_cursor_to (w, vpos, i, desired_row->y,
+                             desired_row->pixel_width);
+         rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
          changed_p = 1;
        }
       else if (desired_row->pixel_width < current_row->pixel_width)
@@ -3756,8 +3726,8 @@ update_text_area (struct window *w, int vpos)
          int xlim;
 
          if (i >= desired_row->used[TEXT_AREA])
-           rif->cursor_to (w, vpos, i, desired_row->y,
-                           desired_row->pixel_width);
+           output_cursor_to (w, vpos, i, desired_row->y,
+                             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
@@ -3774,7 +3744,7 @@ update_text_area (struct window *w, int vpos)
            }
          else
            xlim = current_row->pixel_width;
-         rif->clear_end_of_line (w, xlim);
+         rif->clear_end_of_line (w, updated_row, TEXT_AREA, xlim);
          changed_p = 1;
        }
     }
@@ -3793,10 +3763,6 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
   struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
   bool changed_p = 0;
 
-  /* Set the row being updated.  This is important to let xterm.c
-     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
      the matrix.  Make sure to make such rows current anyway, since
@@ -3807,11 +3773,10 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
       eassert (desired_row->enabled_p);
 
       /* Update display of the left margin area, if there is one.  */
-      if (!desired_row->full_width_p
-         && !NILP (w->left_margin_cols))
+      if (!desired_row->full_width_p && w->left_margin_cols > 0)
        {
          changed_p = 1;
-         update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
+         update_marginal_area (w, desired_row, LEFT_MARGIN_AREA, vpos);
          /* Setting this flag will ensure the vertical border, if
             any, between this window and the one on its left will be
             redrawn.  This is necessary because updating the left
@@ -3820,7 +3785,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
        }
 
       /* Update the display of the text area.  */
-      if (update_text_area (w, vpos))
+      if (update_text_area (w, desired_row, vpos))
        {
          changed_p = 1;
          if (current_row->mouse_face_p)
@@ -3828,11 +3793,10 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
        }
 
       /* Update display of the right margin area, if there is one.  */
-      if (!desired_row->full_width_p
-         && !NILP (w->right_margin_cols))
+      if (!desired_row->full_width_p && w->right_margin_cols > 0)
        {
          changed_p = 1;
-         update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
+         update_marginal_area (w, desired_row, RIGHT_MARGIN_AREA, vpos);
        }
 
       /* Draw truncation marks etc.  */
@@ -3851,7 +3815,6 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
 
   /* Update current_row from desired_row.  */
   make_current (w->desired_matrix, w->current_matrix, vpos);
-  updated_row = NULL;
   return changed_p;
 }
 
@@ -3863,7 +3826,6 @@ static void
 set_window_cursor_after_update (struct window *w)
 {
   struct frame *f = XFRAME (w->frame);
-  struct redisplay_interface *rif = FRAME_RIF (f);
   int cx, cy, vpos, hpos;
 
   /* Not intended for frame matrix updates.  */
@@ -3935,21 +3897,22 @@ set_window_cursor_after_update (struct window *w)
      Horizontal position is -1 when cursor is on the left fringe.   */
   hpos = clip_to_bounds (-1, hpos, w->current_matrix->matrix_w - 1);
   vpos = clip_to_bounds (0, vpos, w->current_matrix->nrows - 1);
-  rif->cursor_to (w, vpos, hpos, cy, cx);
+  output_cursor_to (w, vpos, hpos, cy, cx);
 }
 
 
-/* Set WINDOW->must_be_updated_p to ON_P for all windows in the window
-   tree rooted at W.  */
+/* If B is NULL, set WINDOW->must_be_updated_p to ON_P for all windows in
+   the window tree rooted at W.  Otherwise set WINDOW->must_be_updated_p
+   to ON_P only for windows that displays B.  */
 
 void
-set_window_update_flags (struct window *w, bool on_p)
+set_window_update_flags (struct window *w, struct buffer *b, bool on_p)
 {
   while (w)
     {
       if (WINDOWP (w->contents))
-       set_window_update_flags (XWINDOW (w->contents), on_p);
-      else
+       set_window_update_flags (XWINDOW (w->contents), b, on_p);
+      else if (!(b && b != XBUFFER (w->contents)))
        w->must_be_updated_p = on_p;
 
       w = NILP (w->next) ? 0 : XWINDOW (w->next);
@@ -4515,7 +4478,7 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p)
        }
     }
 
-  lint_assume (0 <= FRAME_LINES (f));
+  assume (0 <= FRAME_LINES (f));
   pause_p = 0 < i && i < FRAME_LINES (f) - 1;
 
   /* Now just clean up termcap drivers and set cursor, etc.  */
@@ -4606,10 +4569,7 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p)
              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_cols))
-               x += XFASTINT (w->left_margin_cols);
-
-             /* x = max (min (x, FRAME_TOTAL_COLS (f) - 1), 0); */
+             x += max (0, w->left_margin_cols);
              cursor_to (f, y, x);
            }
        }
@@ -5097,9 +5057,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
      wrong thing with `face-remapping-alist' (bug#2044).  */
   Fset_buffer (w->contents);
   itdata = bidi_shelve_cache ();
-  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)));
+  CLIP_TEXT_POS_FROM_MARKER (startp, w->start);
   start_display (&it, w, startp);
   /* start_display takes into account the header-line row, but IT's
      vpos still counts from the glyph row that includes the window's
@@ -5560,8 +5518,10 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth,
       if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
        FrameCols (FRAME_TTY (f)) = newwidth;
 
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
       if (WINDOWP (f->tool_bar_window))
        XWINDOW (f->tool_bar_window)->total_cols = newwidth;
+#endif
     }
 
   FRAME_LINES (f) = newheight;
@@ -5579,7 +5539,7 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth,
       w->cursor.vpos = w->cursor.y = 0;
   }
 
-  adjust_glyphs (f);
+  adjust_frame_glyphs (f);
   calculate_costs (f);
   SET_FRAME_GARBAGED (f);
   f->resized_p = 1;
@@ -5736,9 +5696,9 @@ additional wait period, in milliseconds; this is for backwards compatibility.
 
   if (duration > 0)
     {
-      EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (duration);
-      wait_reading_process_output (min (EMACS_SECS (t), WAIT_READING_MAX),
-                                  EMACS_NSECS (t), 0, 0, Qnil, NULL, 0);
+      struct timespec t = dtotimespec (duration);
+      wait_reading_process_output (min (t.tv_sec, WAIT_READING_MAX),
+                                  t.tv_nsec, 0, 0, Qnil, NULL, 0);
     }
 
   return Qnil;
@@ -5785,9 +5745,9 @@ sit_for (Lisp_Object timeout, bool reading, int display_option)
        return Qt;
       else
        {
-         EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (seconds);
-         sec = min (EMACS_SECS (t), WAIT_READING_MAX);
-         nsec = EMACS_NSECS (t);
+         struct timespec t = dtotimespec (seconds);
+         sec = min (t.tv_sec, WAIT_READING_MAX);
+         nsec = t.tv_nsec;
        }
     }
   else if (EQ (timeout, Qt))
@@ -6205,19 +6165,6 @@ WINDOW nil or omitted means report on the selected window.  */)
 {
   return decode_any_window (window)->cursor_off_p ? Qnil : Qt;
 }
-
-DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
-       Slast_nonminibuf_frame, 0, 0, 0,
-       doc: /* Value is last nonminibuffer frame. */)
-  (void)
-{
-  Lisp_Object frame = Qnil;
-
-  if (last_nonminibuf_frame)
-    XSETFRAME (frame, last_nonminibuf_frame);
-
-  return frame;
-}
 \f
 /***********************************************************************
                            Initialization
@@ -6236,7 +6183,6 @@ syms_of_display (void)
   defsubr (&Ssend_string_to_terminal);
   defsubr (&Sinternal_show_cursor);
   defsubr (&Sinternal_show_cursor_p);
-  defsubr (&Slast_nonminibuf_frame);
 
 #ifdef GLYPH_DEBUG
   defsubr (&Sdump_redisplay_history);