]> code.delx.au - gnu-emacs/blobdiff - src/dispnew.c
(Fbyte_code): Harmonize arguments with documentation.
[gnu-emacs] / src / dispnew.c
index dac5c164356d324d7bfc7b2e8c945a777f49b095..e9978749e2a47966702b591e32a94010656db85e 100644 (file)
@@ -1,5 +1,5 @@
 /* Updating of data structures for redisplay.
-   Copyright (C) 1985, 1986, 1987, 1988, 1993 Free Software Foundation, Inc.
+   Copyright (C) 1985, 86, 87, 88, 93, 94, 95 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -21,6 +21,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <signal.h>
 
 #include <config.h>
+
 #include <stdio.h>
 #include <ctype.h>
 
@@ -28,8 +29,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "termchar.h"
 #include "termopts.h"
 #include "termhooks.h"
-#include "cm.h"
+/* cm.h must come after dispextern.h on Windows.  */
 #include "dispextern.h"
+#include "cm.h"
 #include "buffer.h"
 #include "frame.h"
 #include "window.h"
@@ -39,21 +41,44 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "intervals.h"
 
 #include "systty.h"
-#include "systime.h"
+#include "syssignal.h"
 
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
 #endif /* HAVE_X_WINDOWS */
 
+#ifdef HAVE_NTGUI
+#include "w32term.h"
+#endif /* HAVE_NTGUI */
+
+/* Include systime.h after xterm.h to avoid double inclusion of time.h. */
+#include "systime.h"
+
+#include <errno.h>
+
 #define max(a, b) ((a) > (b) ? (a) : (b))
 #define min(a, b) ((a) < (b) ? (a) : (b))
 
-#ifndef PENDING_OUTPUT_COUNT
 /* 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.  */
+#ifdef __GNU_LIBRARY__
+/* The s- file might have overridden the definition with one that works for
+   the system's C library.  But we are using the GNU C library, so this is
+   the right definition for every system.  */
+#ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT
+#define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT
+#else
+#undef PENDING_OUTPUT_COUNT
+#define        PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
+#endif
+#else /* not __GNU_LIBRARY__ */
+#ifndef PENDING_OUTPUT_COUNT
 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
 #endif
+#endif
+
+static void change_frame_size_1 ();
 
 /* Nonzero upon entry to redisplay means do not assume anything about
    current contents of actual terminal frame; clear and redraw it.  */
@@ -102,15 +127,19 @@ Lisp_Object Vstandard_display_table;
    positive means at end of text in echo area;
    negative means at beginning of line.  */
 int cursor_in_echo_area;
+
+Lisp_Object Qdisplay_table;
 \f
 /* The currently selected frame.
-   In a single-frame version, this variable always remains 0.  */
+   In a single-frame version, this variable always holds the address of
+   the_only_frame.  */
 
 FRAME_PTR selected_frame;
 
 /* A frame which is not just a minibuffer, or 0 if there are no such
    frames.  This is usually the most recent such frame that was
-   selected.  In a single-frame version, this variable always remains 0.  */
+   selected.  In a single-frame version, this variable always holds
+   the address of the_only_frame.  */
 FRAME_PTR last_nonminibuf_frame;
 
 /* In a single-frame version, the information that would otherwise
@@ -169,14 +198,16 @@ redraw_frame (f)
      FRAME_PTR f;
 {
   Lisp_Object frame;
-  XSET (frame, Lisp_Frame, f);
+  XSETFRAME (frame, f);
   Fredraw_frame (frame);
 }
 
 #else
 
-DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, "",
-  "Clear frame FRAME and output again what is supposed to appear on it.")
+DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
+  /* Don't confuse make-docfile by having two doc strings for this function.
+     make-docfile does not pay attention to #if, for good reason!  */
+  0)
   (frame)
      Lisp_Object frame;
 {
@@ -231,21 +262,22 @@ make_frame_glyphs (frame, empty)
   register int i;
   register width = FRAME_WIDTH (frame);
   register height = FRAME_HEIGHT (frame);
-  register struct frame_glyphs *new =
-    (struct frame_glyphs *) xmalloc (sizeof (struct frame_glyphs));
+  register struct frame_glyphs *new
+    (struct frame_glyphs *) xmalloc (sizeof (struct frame_glyphs));
 
   SET_GLYPHS_FRAME (new, frame);
   new->height = height;
   new->width = width;
   new->used = (int *) xmalloc (height * sizeof (int));
   new->glyphs = (GLYPH **) xmalloc (height * sizeof (GLYPH *));
+  new->charstarts = (int **) xmalloc (height * sizeof (int *));
   new->highlight = (char *) xmalloc (height * sizeof (char));
   new->enable = (char *) xmalloc (height * sizeof (char));
   bzero (new->enable, height * sizeof (char));
   new->bufp = (int *) xmalloc (height * sizeof (int));
 
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (frame))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (frame))
     {
       new->top_left_x = (short *) xmalloc (height * sizeof (short));
       new->top_left_y = (short *) xmalloc (height * sizeof (short));
@@ -253,16 +285,20 @@ make_frame_glyphs (frame, empty)
       new->pix_height = (short *) xmalloc (height * sizeof (short));
       new->max_ascent = (short *) xmalloc (height * sizeof (short));
     }
-#endif
+#endif /* HAVE_WINDOW_SYSTEM */
 
   if (empty)
     {
       /* Make the buffer used by decode_mode_spec.  This buffer is also
          used as temporary storage when updating the frame.  See scroll.c. */
       unsigned int total_glyphs = (width + 2) * sizeof (GLYPH);
+      unsigned int total_charstarts = (width + 2) * sizeof (int);
 
       new->total_contents = (GLYPH *) xmalloc (total_glyphs);
       bzero (new->total_contents, total_glyphs);
+
+      new->total_charstarts = (int *) xmalloc (total_charstarts);
+      bzero (new->total_charstarts, total_glyphs);
     }
   else
     {
@@ -272,27 +308,50 @@ make_frame_glyphs (frame, empty)
       bzero (new->total_contents, total_glyphs);
       for (i = 0; i < height; i++)
        new->glyphs[i] = new->total_contents + i * (width + 2) + 1;
+
+      if (!FRAME_TERMCAP_P (frame))
+       {
+         unsigned int total_charstarts = height * (width + 2) * sizeof (int);
+
+         new->total_charstarts = (int *) xmalloc (total_charstarts);
+         bzero (new->total_charstarts, total_charstarts);
+         for (i = 0; i < height; i++)
+           new->charstarts[i] = new->total_charstarts + i * (width + 2) + 1;
+       }
+      else
+       {
+         /* Without a window system, we don't really need charstarts.
+            So use a small amount of space to make enough data structure
+            to prevent crashes in display_text_line.  */
+         new->total_charstarts = (int *) xmalloc ((width + 2) * sizeof (int));
+         for (i = 0; i < height; i++)
+           new->charstarts[i] = new->total_charstarts;
+       }
     }
 
   return new;
 }
 
-static void
+void
 free_frame_glyphs (frame, glyphs)
      FRAME_PTR frame;
      struct frame_glyphs *glyphs;
 {
   if (glyphs->total_contents)
     xfree (glyphs->total_contents);
+  if (glyphs->total_charstarts)
+    xfree (glyphs->total_charstarts);
 
   xfree (glyphs->used);
   xfree (glyphs->glyphs);
   xfree (glyphs->highlight);
   xfree (glyphs->enable);
   xfree (glyphs->bufp);
+  if (glyphs->charstarts)
+    xfree (glyphs->charstarts);
 
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (frame))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (frame))
     {
       xfree (glyphs->top_left_x);
       xfree (glyphs->top_left_y);
@@ -300,12 +359,12 @@ free_frame_glyphs (frame, glyphs)
       xfree (glyphs->pix_height);
       xfree (glyphs->max_ascent);
     }
-#endif
+#endif /* HAVE_WINDOW_SYSTEM */
 
   xfree (glyphs);
 }
 
-static void
+void
 remake_frame_glyphs (frame)
      FRAME_PTR frame;
 {
@@ -338,7 +397,8 @@ remake_frame_glyphs (frame)
   FRAME_CURRENT_GLYPHS (frame) = make_frame_glyphs (frame, 0);
   FRAME_DESIRED_GLYPHS (frame) = make_frame_glyphs (frame, 0);
   FRAME_TEMP_GLYPHS (frame) = make_frame_glyphs (frame, 1);
-  SET_FRAME_GARBAGED (frame);
+  if (! FRAME_TERMCAP_P (frame) || frame == selected_frame)
+    SET_FRAME_GARBAGED (frame);
 }
 \f
 /* Return the hash code of contents of line VPOS in frame-matrix M.  */
@@ -452,6 +512,20 @@ clear_frame_records (frame)
   bzero (FRAME_CURRENT_GLYPHS (frame)->enable, FRAME_HEIGHT (frame));
 }
 
+/* Clear out all display lines for a coming redisplay.  */
+
+void
+init_desired_glyphs (frame)
+     register FRAME_PTR frame;
+{
+  register struct frame_glyphs *desired_glyphs = FRAME_DESIRED_GLYPHS (frame);
+  int vpos;
+  int height = FRAME_HEIGHT (frame);
+
+  for (vpos = 0; vpos < height; vpos++)
+    desired_glyphs->enable[vpos] = 0;
+}
+
 /* Prepare to display on line VPOS starting at HPOS within it.  */
 
 void
@@ -467,9 +541,6 @@ get_display_line (frame, vpos, hpos)
   if (vpos < 0)
     abort ();
 
-  if ((desired_glyphs->enable[vpos]) && desired_glyphs->used[vpos] > hpos)
-    abort ();
-
   if (! desired_glyphs->enable[vpos])
     {
       desired_glyphs->used[vpos] = 0;
@@ -567,13 +638,15 @@ rotate_vector (vector, size, distance)
    Returns nonzero if done, zero if terminal cannot scroll them.  */
 
 int
-scroll_frame_lines (frame, from, end, amount)
+scroll_frame_lines (frame, from, end, amount, newpos)
      register FRAME_PTR frame;
-     int from, end, amount;
+     int from, end, amount, newpos;
 {
   register int i;
   register struct frame_glyphs *current_frame
     = FRAME_CURRENT_GLYPHS (frame);
+  int pos_adjust;
+  int width = FRAME_WIDTH (frame);
 
   if (!line_ins_del_ok)
     return 0;
@@ -594,6 +667,10 @@ scroll_frame_lines (frame, from, end, amount)
                     sizeof (GLYPH *) * (end + amount - from),
                     amount * sizeof (GLYPH *));
 
+      rotate_vector (current_frame->charstarts + from,
+                    sizeof (int *) * (end + amount - from),
+                    amount * sizeof (int *));
+
       safe_bcopy (current_frame->used + from,
                  current_frame->used + from + amount,
                  (end - from) * sizeof current_frame->used[0]);
@@ -606,6 +683,29 @@ scroll_frame_lines (frame, from, end, amount)
                  current_frame->enable + from + amount,
                  (end - from) * sizeof current_frame->enable[0]);
 
+      /* Adjust the lines by an amount
+        that puts the first of them at NEWPOS.  */
+      pos_adjust = newpos - current_frame->charstarts[from + amount][0];
+
+      /* Offset each char position in the charstarts lines we moved
+        by pos_adjust.  */
+      for (i = from + amount; i < end + amount; i++)
+       {
+         int *line = current_frame->charstarts[i];
+         int col;
+         for (col = 0; col < width; col++)
+           if (line[col] > 0)
+             line[col] += pos_adjust;
+       }
+      for (i = from; i < from + amount; i++)
+       {
+         int *line = current_frame->charstarts[i];
+         int col;
+         line[0] = -1;
+         for (col = 0; col < width; col++)
+           line[col] = 0;
+       }
+
       /* Mark the lines made empty by scrolling as enabled, empty and
         normal video.  */
       bzero (current_frame->used + from,
@@ -615,6 +715,7 @@ scroll_frame_lines (frame, from, end, amount)
       for (i = from; i < from + amount; i++)
        {
          current_frame->glyphs[i][0] = '\0';
+         current_frame->charstarts[i][0] = -1;
          current_frame->enable[i] = 1;
        }
 
@@ -622,8 +723,8 @@ scroll_frame_lines (frame, from, end, amount)
                  current_frame->bufp + from + amount,
                  (end - from) * sizeof current_frame->bufp[0]);
 
-#ifdef HAVE_X_WINDOWS
-      if (FRAME_X_P (frame))
+#ifdef HAVE_WINDOW_SYSTEM
+      if (FRAME_WINDOW_P (frame))
        {
          safe_bcopy (current_frame->top_left_x + from,
                      current_frame->top_left_x + from + amount,
@@ -645,7 +746,7 @@ scroll_frame_lines (frame, from, end, amount)
                      current_frame->max_ascent + from + amount,
                      (end - from) * sizeof current_frame->max_ascent[0]);
        }
-#endif                         /* HAVE_X_WINDOWS */
+#endif /* HAVE_WINDOW_SYSTEM */
 
       update_end (frame);
     }
@@ -662,6 +763,10 @@ scroll_frame_lines (frame, from, end, amount)
                     sizeof (GLYPH *) * (end - from - amount),
                     amount * sizeof (GLYPH *));
 
+      rotate_vector (current_frame->charstarts + from + amount,
+                    sizeof (int *) * (end - from - amount),
+                    amount * sizeof (int *));
+
       safe_bcopy (current_frame->used + from,
                  current_frame->used + from + amount,
                  (end - from) * sizeof current_frame->used[0]);
@@ -674,6 +779,29 @@ scroll_frame_lines (frame, from, end, amount)
                  current_frame->enable + from + amount,
                  (end - from) * sizeof current_frame->enable[0]);
 
+      /* Adjust the lines by an amount
+        that puts the first of them at NEWPOS.  */
+      pos_adjust = newpos - current_frame->charstarts[from + amount][0];
+
+      /* Offset each char position in the charstarts lines we moved
+        by pos_adjust.  */
+      for (i = from + amount; i < end + amount; i++)
+       {
+         int *line = current_frame->charstarts[i];
+         int col;
+         for (col = 0; col < width; col++)
+           if (line[col] > 0)
+             line[col] += pos_adjust;
+       }
+      for (i = end + amount; i < end; i++)
+       {
+         int *line = current_frame->charstarts[i];
+         int col;
+         line[0] = -1;
+         for (col = 0; col < width; col++)
+           line[col] = 0;
+       }
+
       /* Mark the lines made empty by scrolling as enabled, empty and
         normal video.  */
       bzero (current_frame->used + end + amount,
@@ -683,6 +811,7 @@ scroll_frame_lines (frame, from, end, amount)
       for (i = end + amount; i < end; i++)
        {
          current_frame->glyphs[i][0] = '\0';
+         current_frame->charstarts[i][0] = 0;
          current_frame->enable[i] = 1;
        }
 
@@ -690,8 +819,8 @@ scroll_frame_lines (frame, from, end, amount)
                  current_frame->bufp + from + amount,
                  (end - from) * sizeof current_frame->bufp[0]);
 
-#ifdef HAVE_X_WINDOWS
-      if (FRAME_X_P (frame))
+#ifdef HAVE_WINDOW_SYSTEM
+      if (FRAME_WINDOW_P (frame))
        {
          safe_bcopy (current_frame->top_left_x + from,
                      current_frame->top_left_x + from + amount,
@@ -713,7 +842,7 @@ scroll_frame_lines (frame, from, end, amount)
                      current_frame->max_ascent + from + amount,
                      (end - from) * sizeof current_frame->max_ascent[0]);
        }
-#endif                         /* HAVE_X_WINDOWS */
+#endif /* HAVE_WINDOW_SYSTEM */
 
       update_end (frame);
     }
@@ -748,7 +877,10 @@ preserve_other_columns (w)
 
              bcopy (current_frame->glyphs[vpos],
                     desired_frame->glyphs[vpos],
-                    start * sizeof (current_frame->glyphs[vpos]));
+                    start * sizeof (current_frame->glyphs[vpos][0]));
+             bcopy (current_frame->charstarts[vpos],
+                    desired_frame->charstarts[vpos],
+                    start * sizeof (current_frame->charstarts[vpos][0]));
              len = min (start, current_frame->used[vpos]);
              if (desired_frame->used[vpos] < len)
                desired_frame->used[vpos] = len;
@@ -757,12 +889,19 @@ preserve_other_columns (w)
              && desired_frame->used[vpos] < current_frame->used[vpos])
            {
              while (desired_frame->used[vpos] < end)
-               desired_frame->glyphs[vpos][desired_frame->used[vpos]++]
-                 = SPACEGLYPH;
+               {
+                 int used = desired_frame->used[vpos]++;
+                 desired_frame->glyphs[vpos][used] = SPACEGLYPH;
+                 desired_frame->glyphs[vpos][used] = 0;
+               }
              bcopy (current_frame->glyphs[vpos] + end,
                     desired_frame->glyphs[vpos] + end,
                     ((current_frame->used[vpos] - end)
-                     * sizeof (current_frame->glyphs[vpos])));
+                     * sizeof (current_frame->glyphs[vpos][0])));
+             bcopy (current_frame->charstarts[vpos] + end,
+                    desired_frame->charstarts[vpos] + end,
+                    ((current_frame->used[vpos] - end)
+                     * sizeof (current_frame->charstarts[vpos][0])));
              desired_frame->used[vpos] = current_frame->used[vpos];
            }
        }
@@ -808,6 +947,89 @@ preserve_my_columns (w)
 
 #endif
 \f
+/* Adjust by ADJUST the charstart values in window W
+   after vpos VPOS, which counts relative to the frame
+   (not relative to W itself).  */
+
+void
+adjust_window_charstarts (w, vpos, adjust)
+     struct window *w;
+     int vpos;
+     int adjust;
+{
+  int left = XFASTINT (w->left);
+  int top = XFASTINT (w->top);
+  int right = left + window_internal_width (w);
+  int bottom = top + window_internal_height (w);
+  int i;
+
+  for (i = vpos + 1; i < bottom; i++)
+    {
+      int *charstart
+       = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w)))->charstarts[i];
+      int j;
+      for (j = left; j < right; j++)
+       if (charstart[j] > 0)
+         charstart[j] += adjust;
+    }
+}
+
+/* Check the charstarts values in the area of window W
+   for internal consistency.  We cannot check that they are "right";
+   we can only look for something nonsensical.  */
+
+verify_charstarts (w)
+     struct window *w;
+{
+  FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
+  int i;
+  int top = XFASTINT (w->top);
+  int bottom = top + window_internal_height (w);
+  int left = XFASTINT (w->left);
+  int right = left + window_internal_width (w);
+  int next_line;
+  int truncate = (XINT (w->hscroll)
+                 || (truncate_partial_width_windows
+                     && (XFASTINT (w->width) < FRAME_WIDTH (f)))
+                 || !NILP (XBUFFER (w->buffer)->truncate_lines));
+
+  for (i = top; i < bottom; i++)
+    {
+      int j;
+      int last;
+      int *charstart = FRAME_CURRENT_GLYPHS (f)->charstarts[i];
+
+      if (i != top)
+       {
+         if (truncate)
+           {
+             /* If we are truncating lines, allow a jump
+                in charstarts from one line to the next.  */
+             if (charstart[left] < next_line)
+               abort ();
+           }
+         else
+           {
+             if (charstart[left] != next_line)
+               abort ();
+           }
+       }
+
+      for (j = left; j < right; j++)
+       if (charstart[j] > 0)
+         last = charstart[j];
+      /* Record where the next line should start.  */
+      next_line = last;
+      if (BUF_ZV (XBUFFER (w->buffer)) != last)
+       {
+         /* If there's a newline between the two lines, count that.  */
+         int endchar = *BUF_CHAR_ADDRESS (XBUFFER (w->buffer), last);
+         if (endchar == '\n')
+           next_line++;
+       }
+    }
+}
+\f
 /* On discovering that the redisplay for a window was no good,
    cancel the columns of that window, so that when the window is
    displayed over again get_display_line will not complain.  */
@@ -816,8 +1038,8 @@ cancel_my_columns (w)
      struct window *w;
 {
   register int vpos;
-  register struct frame_glyphs *desired_glyphs =
-    FRAME_DESIRED_GLYPHS (XFRAME (w->frame));
+  register struct frame_glyphs *desired_glyphs
+    FRAME_DESIRED_GLYPHS (XFRAME (w->frame));
   register int start = XFASTINT (w->left);
   register int bot = XFASTINT (w->top) + XFASTINT (w->height);
 
@@ -876,12 +1098,12 @@ direct_output_for_insert (g)
 #ifdef USE_TEXT_PROPERTIES
   /* Intervals have already been adjusted, point is after the
      character that was just inserted. */
-  /* Give up if character has is invisible. */
+  /* Give up if character is invisible. */
   /* Give up if character has a face property.
      At the moment we only lose at end of line or end of buffer
      and only with faces that have some background */
   /* Instead of wasting time, give up if character has any text properties */
-      || ! NILP (Ftext_properties_at (XFASTINT (point - 1), Qnil))
+      || ! NILP (Ftext_properties_at (make_number (point - 1), Qnil))
 #endif
 
   /* Give up if w is minibuffer and a message is being displayed there */
@@ -889,20 +1111,24 @@ direct_output_for_insert (g)
     return 0;
 
   {
-#ifdef HAVE_X_WINDOWS
-    int dummy;
-    int face = compute_char_face (frame, w, point - 1, -1, -1, &dummy, point);
-#else
     int face = 0;
+#ifdef HAVE_FACES
+    int dummy;
+
+    if (FRAME_WINDOW_P (frame))
+      face = compute_char_face (frame, w, point - 1, -1, -1, &dummy, point, 0);
 #endif
-                                 
-    current_frame->glyphs[vpos][hpos] = MAKE_GLYPH (g, face);
+    current_frame->glyphs[vpos][hpos] = MAKE_GLYPH (frame, g, face);
+    current_frame->charstarts[vpos][hpos] = point - 1;
+    /* Record the entry for after the newly inserted character.  */
+    current_frame->charstarts[vpos][hpos + 1] = point;
+    adjust_window_charstarts (w, vpos, 1);
   }
   unchanged_modified = MODIFF;
   beg_unchanged = GPT - BEG;
-  XFASTINT (w->last_point) = point;
-  XFASTINT (w->last_point_x) = hpos;
-  XFASTINT (w->last_modified) = MODIFF;
+  XSETFASTINT (w->last_point, point);
+  XSETFASTINT (w->last_point_x, hpos);
+  XSETFASTINT (w->last_modified, MODIFF);
 
   reassert_line_highlight (0, vpos);
   write_glyphs (&current_frame->glyphs[vpos][hpos], 1);
@@ -923,8 +1149,13 @@ direct_output_forward_char (n)
 {
   register FRAME_PTR frame = selected_frame;
   register struct window *w = XWINDOW (selected_window);
-  int position;
-  
+  Lisp_Object position;
+  int hpos = FRAME_CURSOR_X (frame);
+
+  /* Give up if in truncated text at end of line.  */
+  if (hpos >= XFASTINT (w->left) + window_internal_width (w) - 1)
+    return 0;
+
   /* Avoid losing if cursor is in invisible text off left margin
      or about to go off either side of window.  */
   if ((FRAME_CURSOR_X (frame) == XFASTINT (w->left)
@@ -933,33 +1164,38 @@ direct_output_forward_char (n)
          && (FRAME_CURSOR_X (frame) + 1 >= window_internal_width (w) - 1))
       || cursor_in_echo_area)
     return 0;
-  
+
   /* Can't use direct output if highlighting a region.  */
   if (!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active))
     return 0;
 
+  /* Can't use direct output at an overlay boundary; it might have
+     before-string or after-string properties.  */
+  if (overlay_touches_p (PT) || overlay_touches_p (PT - n))
+    return 0;
+
 #ifdef USE_TEXT_PROPERTIES
   /* Don't use direct output next to an invisible character
      since we might need to do something special.  */
 
-  XFASTINT (position) = point;
+  XSETFASTINT (position, point);
   if (XFASTINT (position) < ZV
-      && ! NILP (Fget_text_property (position,
+      && ! NILP (Fget_char_property (position,
                                     Qinvisible,
-                                    Fcurrent_buffer ())))
-    return;
+                                    selected_window)))
+    return 0;
 
-  XFASTINT (position) = point - 1;
+  XSETFASTINT (position, point - 1);
   if (XFASTINT (position) >= BEGV
-      && ! NILP (Fget_text_property (position,
+      && ! NILP (Fget_char_property (position,
                                     Qinvisible,
-                                    Fcurrent_buffer ())))
-    return;
+                                    selected_window)))
+    return 0;
 #endif
 
   FRAME_CURSOR_X (frame) += n;
-  XFASTINT (w->last_point_x) = FRAME_CURSOR_X (frame);
-  XFASTINT (w->last_point) = point;
+  XSETFASTINT (w->last_point_x, FRAME_CURSOR_X (frame));
+  XSETFASTINT (w->last_point, point);
   cursor_to (FRAME_CURSOR_Y (frame), FRAME_CURSOR_X (frame));
   fflush (stdout);
 
@@ -978,16 +1214,19 @@ update_frame (f, force, inhibit_hairy_id)
      int force;
      int inhibit_hairy_id;
 {
-  register struct frame_glyphs *current_frame = FRAME_CURRENT_GLYPHS (f);
-  register struct frame_glyphs *desired_frame = FRAME_DESIRED_GLYPHS (f);
+  register struct frame_glyphs *current_frame;
+  register struct frame_glyphs *desired_frame = 0;
   register int i;
   int pause;
   int preempt_count = baud_rate / 2400 + 1;
   extern input_pending;
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   register int downto, leftmost;
 #endif
 
+  if (baud_rate != FRAME_COST_BAUD_RATE (f))
+    calculate_costs (f);
+
   if (preempt_count <= 0)
     preempt_count = 1;
 
@@ -1005,6 +1244,10 @@ update_frame (f, force, inhibit_hairy_id)
   if (!line_ins_del_ok)
     inhibit_hairy_id = 1;
 
+  /* These are separate to avoid a possible bug in the AIX C compiler.  */
+  current_frame = FRAME_CURRENT_GLYPHS (f);
+  desired_frame = FRAME_DESIRED_GLYPHS (f);
+
   /* See if any of the desired lines are enabled; don't compute for
      i/d line if just want cursor motion. */
   for (i = 0; i < FRAME_HEIGHT (f); i++)
@@ -1020,21 +1263,21 @@ update_frame (f, force, inhibit_hairy_id)
   if (desired_frame->enable[FRAME_HEIGHT (f) - 1])
     update_line (f, FRAME_HEIGHT (f) - 1);
 
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (f))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (f))
     {
-      leftmost = downto = f->display.x->internal_border_width;
+      leftmost = downto = FRAME_INTERNAL_BORDER_WIDTH (f);
       if (desired_frame->enable[0])
        {
          current_frame->top_left_x[FRAME_HEIGHT (f) - 1] = leftmost;
          current_frame->top_left_y[FRAME_HEIGHT (f) - 1]
-           = PIXEL_HEIGHT (f) - f->display.x->internal_border_width
+           = PIXEL_HEIGHT (f) - FRAME_INTERNAL_BORDER_WIDTH (f)
              - current_frame->pix_height[FRAME_HEIGHT (f) - 1];
          current_frame->top_left_x[0] = leftmost;
          current_frame->top_left_y[0] = downto;
        }
     }
-#endif /* HAVE_X_WINDOWS */
+#endif /* HAVE_WINDOW_SYSTEM */
 
   /* Now update the rest of the lines. */
   for (i = 0; i < FRAME_HEIGHT (f) - 1 && (force || !input_pending); i++)
@@ -1061,7 +1304,7 @@ update_frame (f, force, inhibit_hairy_id)
                        outq = PENDING_OUTPUT_COUNT (stdout);
 #endif
                      outq *= 10;
-                     if (baud_rate > 0)
+                     if (baud_rate <= outq && baud_rate > 0)
                        sleep (outq / baud_rate);
                    }
                }
@@ -1070,27 +1313,36 @@ update_frame (f, force, inhibit_hairy_id)
            }
 
          update_line (f, i);
-#ifdef HAVE_X_WINDOWS
-         if (FRAME_X_P (f))
+#ifdef HAVE_WINDOW_SYSTEM
+         if (FRAME_WINDOW_P (f))
            {
              current_frame->top_left_y[i] = downto;
              current_frame->top_left_x[i] = leftmost;
            }
-#endif /* HAVE_X_WINDOWS */
+#endif /* HAVE_WINDOW_SYSTEM */
        }
 
-#ifdef HAVE_X_WINDOWS
-      if (FRAME_X_P (f))
+#ifdef HAVE_WINDOW_SYSTEM
+      if (FRAME_WINDOW_P (f))
        downto += current_frame->pix_height[i];
-#endif
+#endif /* HAVE_WINDOW_SYSTEM */
     }
   pause = (i < FRAME_HEIGHT (f) - 1) ? i : 0;
 
   /* Now just clean up termcap drivers and set cursor, etc.  */
   if (!pause)
     {
-      if (cursor_in_echo_area
-         && FRAME_HAS_MINIBUF_P (f))
+      if ((cursor_in_echo_area
+          /* If we are showing a message instead of the minibuffer,
+             show the cursor for the message instead of for the
+             (now hidden) minibuffer contents.  */
+          || (EQ (minibuf_window, selected_window)
+              && EQ (minibuf_window, echo_area_window)
+              && echo_area_glyphs != 0))
+         /* These cases apply only to the frame that contains
+            the active minibuffer window.  */
+         && FRAME_HAS_MINIBUF_P (f)
+         && EQ (FRAME_MINIBUF_WINDOW (f), minibuf_window))
        {
          int top = XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top);
          int row, col;
@@ -1142,7 +1394,7 @@ update_frame (f, force, inhibit_hairy_id)
   if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */
   display_completed = !pause;
 
-  bzero (desired_frame->enable, FRAME_HEIGHT (f));
+  bzero (FRAME_DESIRED_GLYPHS (f)->enable, FRAME_HEIGHT (f));
   return pause;
 }
 
@@ -1152,12 +1404,14 @@ update_frame (f, force, inhibit_hairy_id)
 void
 quit_error_check ()
 {
+#if 0
   if (FRAME_DESIRED_GLYPHS (selected_frame) == 0)
     return;
   if (FRAME_DESIRED_GLYPHS (selected_frame)->enable[0])
     abort ();
   if (FRAME_DESIRED_GLYPHS (selected_frame)->enable[FRAME_HEIGHT (selected_frame) - 1])
     abort ();
+#endif
 }
 \f
 /* Decide what insert/delete line to do, and do it */
@@ -1173,6 +1427,7 @@ scrolling (frame)
   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));
   register int i;
   int free_at_end_vpos = FRAME_HEIGHT (frame);
   register struct frame_glyphs *current_frame = FRAME_CURRENT_GLYPHS (frame);
@@ -1205,10 +1460,11 @@ scrolling (frame)
       else if (i == unchanged_at_top)
        unchanged_at_top++;
       draw_cost[i] = line_draw_cost (desired_frame, i);
+      old_draw_cost[i] = line_draw_cost (current_frame, i);
     }
 
   /* If changed lines are few, don't allow preemption, don't scroll.  */
-  if (changed_lines < baud_rate / 2400
+  if (!scroll_region_ok && changed_lines < baud_rate / 2400
       || unchanged_at_bottom == FRAME_HEIGHT (frame))
     return 1;
 
@@ -1222,7 +1478,7 @@ scrolling (frame)
 
   /* If large window, fast terminal and few lines in common between
      current frame and desired frame, don't bother with i/d calc. */
-  if (window_size >= 18 && baud_rate > 2400
+  if (!scroll_region_ok && window_size >= 18 && baud_rate > 2400
       && (window_size >=
          10 * scrolling_max_lines_saved (unchanged_at_top,
                                          FRAME_HEIGHT (frame) - unchanged_at_bottom,
@@ -1231,6 +1487,7 @@ scrolling (frame)
 
   scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom,
               draw_cost + unchanged_at_top - 1,
+              old_draw_cost + unchanged_at_top - 1,
               old_hash + unchanged_at_top - 1,
               new_hash + unchanged_at_top - 1,
               free_at_end_vpos - unchanged_at_top);
@@ -1245,6 +1502,7 @@ buffer_posn_from_coords (window, col, line)
      struct window *window;
      int col, line;
 {
+  int hscroll = XINT (window->hscroll);
   int window_left = XFASTINT (window->left);
 
   /* The actual width of the window is window->width less one for the
@@ -1261,15 +1519,22 @@ buffer_posn_from_coords (window, col, line)
 
   current_buffer = XBUFFER (window->buffer);
 
+  /* We can't get a correct result in this case,
+     but at least prevent compute_motion from crashing.  */
+  if (startp < BEGV)
+    startp = BEGV;
+
   /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
      (window->frame))->bufp to avoid scanning from the very top of
      the window, but it isn't maintained correctly, and I'm not even
      sure I will keep it.  */
   posn = compute_motion (startp, 0,
-                        (window == XWINDOW (minibuf_window) && startp == 1
-                         ? minibuf_prompt_width : 0),
+                        ((window == XWINDOW (minibuf_window) && startp == BEG
+                          ? minibuf_prompt_width : 0)
+                         + (hscroll ? 1 - hscroll : 0)),
+                        0,
                         ZV, line, col,
-                        window_width, XINT (window->hscroll), 0);
+                        window_width, hscroll, 0, window);
 
   current_buffer = old_current_buffer;
 
@@ -1313,6 +1578,7 @@ update_line (frame, vpos)
      int vpos;
 {
   register GLYPH *obody, *nbody, *op1, *op2, *np1, *temp;
+  int *temp1;
   int tem;
   int osp, nsp, begmatch, endmatch, olen, nlen;
   int save;
@@ -1343,7 +1609,7 @@ update_line (frame, vpos)
       if (! current_frame->highlight[vpos])
        {
          if (!must_write_spaces)
-           while (obody[olen - 1] == SPACEGLYPH && olen > 0)
+           while (olen > 0 && obody[olen - 1] == SPACEGLYPH)
              olen--;
        }
       else
@@ -1363,16 +1629,16 @@ update_line (frame, vpos)
   current_frame->highlight[vpos] = desired_frame->highlight[vpos];
   current_frame->bufp[vpos] = desired_frame->bufp[vpos];
 
-#ifdef HAVE_X_WINDOWS
-  if (FRAME_X_P (frame))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (FRAME_WINDOW_P (frame))
     {
       current_frame->pix_width[vpos]
        = current_frame->used[vpos]
-         * FONT_WIDTH (frame->display.x->font);
+         * FONT_WIDTH (FRAME_FONT (frame));
       current_frame->pix_height[vpos]
-       = FONT_HEIGHT (frame->display.x->font);
+       = FRAME_LINE_HEIGHT (frame);
     }
-#endif /* HAVE_X_WINDOWS */
+#endif /* HAVE_WINDOW_SYSTEM */
 
   if (!desired_frame->enable[vpos])
     {
@@ -1455,6 +1721,11 @@ update_line (frame, vpos)
       desired_frame->glyphs[vpos] = current_frame->glyphs[vpos];
       current_frame->glyphs[vpos] = temp;
 
+      /* Exchange charstarts between current_frame and new_frame.  */
+      temp1 = desired_frame->charstarts[vpos];
+      desired_frame->charstarts[vpos] = current_frame->charstarts[vpos];
+      current_frame->charstarts[vpos] = temp1;
+
       return;
     }
 
@@ -1473,6 +1744,11 @@ update_line (frame, vpos)
       desired_frame->glyphs[vpos] = current_frame->glyphs[vpos];
       current_frame->glyphs[vpos] = temp;
 
+      /* Exchange charstarts between current_frame and new_frame.  */
+      temp1 = desired_frame->charstarts[vpos];
+      desired_frame->charstarts[vpos] = current_frame->charstarts[vpos];
+      current_frame->charstarts[vpos] = temp1;
+
       return;
     }
 
@@ -1633,6 +1909,100 @@ update_line (frame, vpos)
   temp = desired_frame->glyphs[vpos];
   desired_frame->glyphs[vpos] = current_frame->glyphs[vpos];
   current_frame->glyphs[vpos] = temp;
+
+  /* Exchange charstarts between current_frame and new_frame.  */
+  temp1 = desired_frame->charstarts[vpos];
+  desired_frame->charstarts[vpos] = current_frame->charstarts[vpos];
+  current_frame->charstarts[vpos] = temp1;
+}
+\f
+/* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
+   session's frames, frame names, buffers, buffer-read-only flags, and
+   buffer-modified-flags, and a trailing sentinel (so we don't need to
+   add length checks).  */
+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")
+  ()
+{
+  Lisp_Object tail, frame, buf;
+  Lisp_Object *vecp;
+  int n;
+
+  vecp = XVECTOR (frame_and_buffer_state)->contents;
+  FOR_EACH_FRAME (tail, frame)
+    {
+      if (!EQ (*vecp++, frame))
+       goto changed;
+      if (!EQ (*vecp++, XFRAME (frame)->name))
+       goto changed;
+    }
+  /* Check that the buffer info matches.
+     No need to test for the end of the vector
+     because the last element of the vector is lambda
+     and that will always cause a mismatch.  */
+  for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr)
+    {
+      buf = XCONS (XCONS (tail)->car)->cdr;
+      /* Ignore buffers that aren't included in buffer lists.  */
+      if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
+       continue;
+      if (!EQ (*vecp++, buf))
+       goto changed;
+      if (!EQ (*vecp++, XBUFFER (buf)->read_only))
+       goto changed;
+      if (!EQ (*vecp++, Fbuffer_modified_p (buf)))
+       goto changed;
+    }
+  /* Detect deletion of a buffer at the end of the list.  */
+  if (*vecp == Qlambda)
+    return Qnil;
+ changed:
+  /* Start with 1 so there is room for at least one lambda at the end.  */
+  n = 1;
+  FOR_EACH_FRAME (tail, frame)
+    n += 2;
+  for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr)
+    n += 3;
+  /* Reallocate the vector if it's grown, or if it's shrunk a lot.  */
+  if (n > XVECTOR (frame_and_buffer_state)->size
+      || n + 20 < XVECTOR (frame_and_buffer_state)->size / 2)
+    /* Add 20 extra so we grow it less often.  */
+    frame_and_buffer_state = Fmake_vector (make_number (n + 20), Qlambda);
+  vecp = XVECTOR (frame_and_buffer_state)->contents;
+  FOR_EACH_FRAME (tail, frame)
+    {
+      *vecp++ = frame;
+      *vecp++ = XFRAME (frame)->name;
+    }
+  for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr)
+    {
+      buf = XCONS (XCONS (tail)->car)->cdr;
+      /* Ignore buffers that aren't included in buffer lists.  */
+      if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
+       continue;
+      *vecp++ = buf;
+      *vecp++ = XBUFFER (buf)->read_only;
+      *vecp++ = Fbuffer_modified_p (buf);
+    }
+  /* Fill up the vector with lambdas (always at least one).  */
+  *vecp++ = Qlambda;
+  while  (vecp - XVECTOR (frame_and_buffer_state)->contents
+         < XVECTOR (frame_and_buffer_state)->size)
+    *vecp++ = Qlambda;
+  /* Make sure we didn't overflow the vector.  */
+  if (vecp - XVECTOR (frame_and_buffer_state)->contents
+      > XVECTOR (frame_and_buffer_state)->size)
+    abort ();
+  return Qt;
 }
 \f
 DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
@@ -1658,7 +2028,8 @@ FILE = nil means just close any termscript file currently open.")
 
 #ifdef SIGWINCH
 SIGTYPE
-window_change_signal ()
+window_change_signal (signalnum) /* If we don't have an argument, */
+     int signalnum;            /* some compilers complain in signal calls. */
 {
   int width, height;
   extern int errno;
@@ -1725,9 +2096,28 @@ do_pending_window_change ()
    redisplay.  Since this tries to resize windows, we can't call it
    from a signal handler.  */
 
-change_frame_size (frame, newheight, newwidth, pretend, delay)
-     register FRAME_PTR frame;
+change_frame_size (f, newheight, newwidth, pretend, delay)
+     register FRAME_PTR f;
      int newheight, newwidth, pretend;
+{
+  Lisp_Object tail, frame;
+  if (FRAME_TERMCAP_P (f))
+    {
+      /* When using termcap, all frames use the same screen,
+        so a change in size affects all termcap frames.  */
+      FOR_EACH_FRAME (tail, frame)
+       if (FRAME_TERMCAP_P (XFRAME (frame)))
+         change_frame_size_1 (XFRAME (frame), newheight, newwidth,
+                              pretend, delay);
+    }
+  else
+    change_frame_size_1 (f, newheight, newwidth, pretend, delay);
+}
+
+static void
+change_frame_size_1 (frame, newheight, newwidth, pretend, delay)
+     register FRAME_PTR frame;
+     int newheight, newwidth, pretend, delay;
 {
   /* If we can't deal with the change now, queue it for later.  */
   if (delay)
@@ -1762,8 +2152,8 @@ change_frame_size (frame, newheight, newwidth, pretend, delay)
          /* Frame has both root and minibuffer.  */
          set_window_height (FRAME_ROOT_WINDOW (frame),
                             newheight - 1 - FRAME_MENU_BAR_LINES (frame), 0);
-         XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame))->top)
-           = newheight - 1;
+         XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame))->top,
+                      newheight - 1);
          set_window_height (FRAME_MINIBUF_WINDOW (frame), 1, 0);
        }
       else
@@ -1804,7 +2194,12 @@ change_frame_size (frame, newheight, newwidth, pretend, delay)
 
   FRAME_HEIGHT (frame) = newheight;
   FRAME_WIDTH (frame)  = newwidth;
-       
+
+  if (FRAME_CURSOR_X (frame) >= FRAME_WIDTH (frame))
+    FRAME_CURSOR_X (frame) = FRAME_WIDTH (frame) - 1;
+  if (FRAME_CURSOR_Y (frame) >= FRAME_HEIGHT (frame))
+    FRAME_CURSOR_Y (frame) = FRAME_HEIGHT (frame) - 1;
+
   remake_frame_glyphs (frame);
   calculate_costs (frame);
 }
@@ -1872,7 +2267,7 @@ Emacs was built without floating point support.\n\
   int sec, usec;
 
   if (NILP (milliseconds))
-    XSET (milliseconds, Lisp_Int, 0);
+    XSETINT (milliseconds, 0);
   else
     CHECK_NUMBER (milliseconds, 1);
   usec = XINT (milliseconds) * 1000;
@@ -1911,7 +2306,7 @@ Emacs was built without floating point support.\n\
   {
     Lisp_Object zero;
 
-    XFASTINT (zero) = 0;
+    XSETFASTINT (zero, 0);
     wait_reading_process_input (sec, usec, zero, 0);
   }
 
@@ -1955,7 +2350,7 @@ Emacs was built without floating point support.\n\
 /* This is just like wait_reading_process_input, except that
    it does the redisplay.
 
-   It's also just like Fsit_for, except that it can be used for
+   It's also much like Fsit_for, except that it can be used for
    waiting for input as well.  */
 
 Lisp_Object
@@ -1977,7 +2372,7 @@ sit_for (sec, usec, reading, display)
   gobble_input (0);
 #endif
 
-  XSET (read_kbd, Lisp_Int, reading ? -1 : 1);
+  XSETINT (read_kbd, reading ? -1 : 1);
   wait_reading_process_input (sec, usec, read_kbd, display);
 
 
@@ -2026,7 +2421,7 @@ Value is t if waited the full time with no input arriving.")
   int sec, usec;
 
   if (NILP (milliseconds))
-    XSET (milliseconds, Lisp_Int, 0);
+    XSETINT (milliseconds, 0);
   else
     CHECK_NUMBER (milliseconds, 1);
   usec = XINT (milliseconds) * 1000;
@@ -2102,6 +2497,15 @@ init_display ()
     }
 #endif /* HAVE_X_WINDOWS */
 
+#ifdef HAVE_NTGUI
+  if (!inhibit_window_system) 
+    {
+      Vwindow_system = intern ("win32");
+      Vwindow_system_version = make_number (1);
+      return;
+    }
+#endif /* HAVE_NTGUI */
+
   /* If no window system has been specified, try to use the terminal.  */
   if (! isatty (0))
     {
@@ -2164,14 +2568,21 @@ syms_of_display ()
   defsubr (&Sredraw_frame);
 #endif
   defsubr (&Sredraw_display);
+  defsubr (&Sframe_or_buffer_changed_p);
   defsubr (&Sopen_termscript);
   defsubr (&Sding);
   defsubr (&Ssit_for);
   defsubr (&Ssleep_for);
   defsubr (&Ssend_string_to_terminal);
 
+  frame_and_buffer_state = Fmake_vector (make_number (20), Qlambda);
+  staticpro (&frame_and_buffer_state);
+
+  Qdisplay_table = intern ("display-table");
+  staticpro (&Qdisplay_table);
+
   DEFVAR_INT ("baud-rate", &baud_rate,
-    "The output baud rate of the terminal.\n\
+    "*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.");
   DEFVAR_BOOL ("inverse-video", &inverse_video,
@@ -2199,7 +2610,7 @@ 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 `x-set-face').");
+    and this glyph / 256 is face code for X windows (see `face-id').");
   Vglyph_table = Qnil;
 
   DEFVAR_LISP ("standard-display-table", &Vstandard_display_table,
@@ -2216,4 +2627,3 @@ See `buffer-display-table' for more information.");
       Vwindow_system_version = Qnil;
     }
 }
-