home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / lucid / lemacs-19.6 / src / dispnew.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-13  |  67.8 KB  |  2,449 lines

  1. /* Updating of data structures for redisplay.
  2.    Copyright (C) 1992 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU Emacs.
  5.  
  6. GNU Emacs is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GNU Emacs is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU Emacs; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20.  
  21. #include <signal.h>
  22.  
  23. #include "config.h"
  24. #include <stdio.h>
  25. #include <ctype.h>
  26. #include "indent.h"
  27.  
  28. #if 0            /* It shouldn't be necessary to include time.h here,
  29.                because we include xterm.h, which includes
  30.                X11/Intrinsic.h, which includes X11/Xos.h, which
  31.                includes time.h.  Some bogon systems (like HP)
  32.                don't protect their header files from double
  33.                inclusion, so including time.h twice blows up!
  34.              */
  35.  
  36. #ifdef NEED_TIME_H
  37. #include <time.h>
  38. #else /* not NEED_TIME_H */
  39. #ifdef HAVE_TIMEVAL
  40. #include <sys/time.h>
  41. #endif /* HAVE_TIMEVAL */
  42. #endif /* not NEED_TIME_H */
  43.  
  44. #endif /* 0 */
  45.  
  46.  
  47. #ifdef HAVE_TERMIO
  48. #include <termio.h>
  49. #ifdef TCOUTQ
  50. #undef TIOCOUTQ
  51. #define TIOCOUTQ TCOUTQ
  52. #endif /* TCOUTQ defined */
  53. #else
  54. #ifndef VMS
  55. #include <sys/ioctl.h>
  56. #endif /* not VMS */
  57. #endif /* not HAVE_TERMIO */
  58.  
  59. /* Allow m- file to inhibit use of FIONREAD.  */
  60. #ifdef BROKEN_FIONREAD
  61. #undef FIONREAD
  62. #endif
  63.  
  64. /* Interupt input is not used if there is no FIONREAD.  */
  65. #ifndef FIONREAD
  66. #undef SIGIO
  67. #endif
  68.  
  69. #include "termchar.h"
  70. #include "termopts.h"
  71. #include "cm.h"
  72. #include "lisp.h"
  73. #include "buffer.h"
  74. #include "screen.h"
  75. #include "window.h"
  76. #include "commands.h"
  77. #include "disptab.h"
  78.  
  79. #ifdef HAVE_X_WINDOWS
  80. #include "xterm.h"
  81. #endif    /* HAVE_X_WINDOWS */
  82.  
  83. #define max(a, b) ((a) > (b) ? (a) : (b))
  84. #define min(a, b) ((a) < (b) ? (a) : (b))
  85.  
  86. #ifndef PENDING_OUTPUT_COUNT
  87. /* Get number of chars of output now in the buffer of a stdio stream.
  88.    This ought to be built in in stdio, but it isn't.
  89.    Some s- files override this because their stdio internals differ.  */
  90. #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
  91. #endif
  92.  
  93. /* Nonzero means do not assume anything about current
  94.  contents of actual terminal screen */
  95. int screen_garbaged;
  96.  
  97. /* Nonzero means last display completed.  Zero means it was preempted. */
  98. int display_completed;
  99.  
  100. int visible_bell;    /* If true and the terminal will support it
  101.                then the screen will flash instead of
  102.                feeping when an error occurs */
  103.  
  104. int inverse_video;    /* If true and the terminal will support it
  105.                then we will use inverse video */
  106.  
  107. int baud_rate;        /* Terminal speed, so we can calculate
  108.                the number of characters required to
  109.                make the cursor sit still for n secs. */
  110.  
  111. Lisp_Object Vwindow_system;    /* nil or a symbol naming the window system
  112.                    under which emacs is running
  113.                    ('x is the only current possibility) */
  114.  
  115. /* Version number of X windows: 10, 11 or nil.  */
  116. Lisp_Object Vwindow_system_version;
  117.  
  118. /* Vector of glyph definitions.  Indexed by glyph number,
  119.    the contents are a string which is how to output the glyph.
  120.  
  121.    If Vglyph_table is nil, a glyph is output by using its low 8 bits
  122.    as a character code.  */
  123. Lisp_Object Vglyph_table;
  124.  
  125. /* Display table to use for vectors that don't specify their own.  */
  126. Lisp_Object Vstandard_display_table;
  127.  
  128. /* Nonzero means reading single-character input with prompt
  129.    so put cursor on minibuffer after the prompt.  */
  130. int cursor_in_echo_area;
  131. Lisp_Object Qcursor_in_echo_area;
  132.  
  133. /* The currently selected screen.
  134.    In a single-screen version, this variable is always 0.  */
  135. SCREEN_PTR selected_screen;
  136.  
  137. /* In a single-screen version, the information that would otherwise
  138.    exist inside a `struct screen' lives in the following variables instead.  */
  139.  
  140. #ifndef MULTI_SCREEN
  141.  
  142. /* Desired terminal cursor position (to show position of point),
  143.    origin zero */
  144. int cursX, cursY;
  145.  
  146. /* The current (physical) screen contents */
  147. struct screen_glyphs *current_glyphs;
  148.  
  149. /* The desired (virtual) screen contents */
  150. struct screen_glyphs *desired_glyphs;
  151.  
  152. #endif /* not MULTI_SCREEN */
  153.  
  154. /* This is a vector, made larger whenever it isn't large enough,
  155.    which is used inside `update_screen' to hold the old contents
  156.    of the SCREEN_PHYS_LINES of the screen being updated.  */
  157. /*struct screen_glyphs **ophys_lines;*/
  158. /* Length of vector currently allocated.  */
  159. /*int ophys_lines_length;*/
  160.  
  161. FILE *termscript;    /* Stdio stream being used for copy of all output.  */
  162.  
  163. struct cm Wcm;        /* Structure for info on cursor positioning */
  164.  
  165. extern short ospeed;    /* Output speed (from sg_ospeed) */
  166.  
  167. int in_display;        /* 1 if in redisplay: can't handle SIGWINCH now.  */
  168.  
  169. int delayed_size_change;  /* 1 means SIGWINCH happened when not safe.  */
  170. int delayed_screen_height;  /* Remembered new screen height.  */
  171. int delayed_screen_width;   /* Remembered new screen width.  */
  172. void change_screen_size ();
  173.  
  174. static struct screen_glyphs *
  175. make_screen_glyphs (screen, empty)
  176.      register SCREEN_PTR screen;
  177.      int empty;
  178. {
  179.   register int i;
  180.   register int width = SCREEN_WIDTH (screen);
  181.   register int height = SCREEN_HEIGHT (screen);
  182.   register struct screen_glyphs *new =
  183.     (struct screen_glyphs *) xmalloc (sizeof (struct screen_glyphs));
  184.  
  185.   SET_GLYPHS_SCREEN (new, screen);
  186.   new->short_cut_taken = 0;
  187.   new->height = height;
  188.   new->width = width;
  189.   new->used = (int *) xmalloc (height * sizeof (int));
  190.   new->glyphs = (GLYPH **) xmalloc (height * sizeof (GLYPH *));
  191. #if 0
  192.   new->highlight = (char *) xmalloc (height * sizeof (char));
  193. #endif
  194.   new->enable = (char *) xmalloc (height * sizeof (char));
  195.   memset (new->enable, 0, height * sizeof (char));
  196.   new->bufp = (int *) xmalloc (height * sizeof (int));
  197.   memset (new->bufp, 0, height * sizeof (int));
  198.   new->nruns = (int *) xmalloc (height * sizeof (int));
  199.   memset (new->nruns, 0, height * sizeof (int));
  200.   new->face_list =
  201.     (struct run **) xmalloc (height * sizeof (struct run *));
  202.  
  203. #ifdef HAVE_X_WINDOWS
  204.   if (SCREEN_IS_X (screen))
  205.     {
  206.       new->top_left_x = (short *) xmalloc (height * sizeof (short));
  207.       new->top_left_y = (short *) xmalloc (height * sizeof (short));
  208.       new->pix_width = (short *) xmalloc (height * sizeof (short));
  209.       new->pix_height = (short *) xmalloc (height * sizeof (short));
  210.       new->max_ascent = (short *) xmalloc (height * sizeof (short));
  211.     }
  212. #endif
  213.  
  214.   if (empty)
  215.     {
  216.       /* Make the buffer used by decode_mode_spec.  This buffer is also
  217.      used as temporary storage when updating the screen.  See scroll.c. */
  218.       unsigned int total_glyphs = (width + 2) * sizeof (GLYPH);
  219.  
  220.       new->total_contents = (GLYPH *) xmalloc (total_glyphs);
  221.       memset (new->total_contents, 0, total_glyphs);
  222.  
  223.       new->faces = 0;
  224.     }
  225.   else
  226.     {
  227.       unsigned int padded_width = width + 10;
  228.       unsigned int total_glyphs = height * padded_width;
  229.  
  230.       new->total_contents = (GLYPH *) xmalloc (total_glyphs * sizeof (GLYPH));
  231.       memset (new->total_contents, 0, total_glyphs * sizeof (GLYPH));
  232.       for (i = 0; i < height; i++)
  233.     new->glyphs[i] = new->total_contents + i * padded_width;
  234.  
  235.       new->faces = 
  236.         (struct run *) xmalloc (total_glyphs * sizeof (struct run));
  237.  
  238.       memset (new->faces, 0, total_glyphs * sizeof (struct run));
  239.       for (i = 0; i < height; i++)
  240.     new->face_list[i] = new->faces + i * padded_width;
  241.     }
  242.  
  243.   return new;
  244. }
  245.  
  246. static void
  247. free_screen_glyphs (screen, glyphs)
  248.      SCREEN_PTR screen;
  249.      struct screen_glyphs *glyphs;
  250. {
  251.   if (glyphs->total_contents)
  252.     xfree (glyphs->total_contents);
  253.  
  254.   xfree (glyphs->used);
  255.   xfree (glyphs->glyphs);
  256. #if 0
  257.   xfree (glyphs->highlight);
  258. #endif
  259.   xfree (glyphs->enable);
  260.   xfree (glyphs->bufp);
  261.   xfree (glyphs->nruns);
  262.   xfree (glyphs->face_list);
  263.  
  264.   if (glyphs->faces)
  265.     xfree ((char *)glyphs->faces);
  266.  
  267. #ifdef HAVE_X_WINDOWS
  268.   if (SCREEN_IS_X (screen))
  269.     {
  270.       xfree (glyphs->top_left_x);
  271.       xfree (glyphs->top_left_y);
  272.       xfree (glyphs->pix_width);
  273.       xfree (glyphs->pix_height);
  274.       xfree (glyphs->max_ascent);
  275.     }
  276. #endif
  277.  
  278.   xfree (glyphs);
  279. }
  280.  
  281. static void
  282. remake_screen_glyphs (screen)
  283.      SCREEN_PTR screen;
  284. {
  285.   if (SCREEN_CURRENT_GLYPHS (screen))
  286.     free_screen_glyphs (screen, SCREEN_CURRENT_GLYPHS (screen));
  287.   if (SCREEN_DESIRED_GLYPHS (screen))
  288.     free_screen_glyphs (screen, SCREEN_DESIRED_GLYPHS (screen));
  289.   if (SCREEN_TEMP_GLYPHS (screen))
  290.     free_screen_glyphs (screen, SCREEN_TEMP_GLYPHS (screen));
  291.  
  292.   if (SCREEN_MESSAGE_BUF (screen))
  293.     {
  294.       char *new_message_buf
  295.     = (char *) xrealloc (SCREEN_MESSAGE_BUF (screen),
  296.                  SCREEN_WIDTH (screen) + 1);
  297.       if (echo_area_glyphs == SCREEN_MESSAGE_BUF (screen))
  298.     echo_area_glyphs = new_message_buf;
  299.       SCREEN_MESSAGE_BUF (screen) = new_message_buf;
  300.     }
  301.   else
  302.     SCREEN_MESSAGE_BUF (screen)
  303.       = (char *) xmalloc (SCREEN_WIDTH (screen) + 1);
  304.  
  305.   SCREEN_CURRENT_GLYPHS (screen) = make_screen_glyphs (screen, 0);
  306.   SCREEN_DESIRED_GLYPHS (screen) = make_screen_glyphs (screen, 0);
  307.   SCREEN_TEMP_GLYPHS (screen) = make_screen_glyphs (screen, 1);
  308.   SET_SCREEN_GARBAGED (screen);
  309. }
  310.  
  311.  
  312. void
  313. free_screen_display_glyphs (screen)    /* called from Fdelete_screen() */
  314.      SCREEN_PTR screen;
  315. {
  316.   if (SCREEN_CURRENT_GLYPHS (screen))
  317.     free_screen_glyphs (screen, SCREEN_CURRENT_GLYPHS (screen));
  318.   if (SCREEN_DESIRED_GLYPHS (screen))
  319.     free_screen_glyphs (screen, SCREEN_DESIRED_GLYPHS (screen));
  320.   if (SCREEN_TEMP_GLYPHS (screen))
  321.     free_screen_glyphs (screen, SCREEN_TEMP_GLYPHS (screen));
  322.  
  323.   if (echo_area_glyphs == SCREEN_MESSAGE_BUF (screen))
  324.     echo_area_glyphs = 0;
  325.   if (SCREEN_MESSAGE_BUF (screen))
  326.     xfree (SCREEN_MESSAGE_BUF (screen));
  327.  
  328.   SCREEN_CURRENT_GLYPHS (screen) = 0;
  329.   SCREEN_DESIRED_GLYPHS (screen) = 0;
  330.   SCREEN_TEMP_GLYPHS (screen) = 0;
  331.   SCREEN_MESSAGE_BUF (screen) = 0;
  332. }
  333.  
  334. /* Return the hash code of display_line p.  */
  335.  
  336. static int
  337. line_hash_code (p, vpos)
  338.      register struct screen_glyphs *p;
  339.      int vpos;
  340. {
  341.   register GLYPH *body;
  342.   register int h = 0;
  343.  
  344.   if (!p->enable[vpos])
  345.     return 0;
  346.  
  347.   if (p->nruns[vpos] > 1 || p->face_list[vpos][0].faceptr->hilited)
  348.     return -1;
  349.  
  350.   body = p->glyphs[vpos];
  351.  
  352.   if (must_write_spaces)
  353.     while (1)
  354.       {
  355.     GLYPH g = *body++;
  356.  
  357.     if (g == 0)
  358.       break;
  359.     h = (((h << 4) + (h >> 24)) & 0x0fffffff) + g - SPACEGLYPH;
  360.       }
  361.   else
  362.     while (1)
  363.       {
  364.     GLYPH g = *body++;
  365.  
  366.     if (g == 0)
  367.       break;
  368.     h = (((h << 4) + (h >> 24)) & 0x0fffffff) + g;
  369.       }
  370.  
  371.   if (h)
  372.     return h;
  373.   return 1;
  374. }
  375.  
  376. /* Return the cost to draw line p.  Cost is measured in characters,
  377.    with white space counting as one character (unless the terminal
  378.    requires those to be explicitly output). */
  379.  
  380. static unsigned int
  381. line_draw_cost (screen, vpos)
  382.      struct screen_glyphs *screen;
  383.      int vpos;
  384. {
  385.   register GLYPH *beg = screen->glyphs[vpos];
  386.   register GLYPH *end = screen->glyphs[vpos] + screen->used[vpos];
  387.   register int i;
  388.   register int tlen = GLYPH_TABLE_LENGTH;
  389.   register Lisp_Object *tbase = GLYPH_TABLE_BASE;
  390.  
  391.   /* Ignore trailing and leading spaces if we can.  */
  392.   if (!must_write_spaces)
  393.     {
  394.       while ((end != beg) && (*end == SPACEGLYPH))
  395.     --end;
  396.       if (end == beg)
  397.     return (0); /* All blank line. */
  398.  
  399.       while (*beg == SPACEGLYPH)
  400.     ++beg;
  401.     }
  402.  
  403.   /* If we don't have a glyph-table, each glyph is one character,
  404.      so return the number of glyphs.  */
  405.   if (tbase == 0)
  406.     return end - beg;
  407.  
  408.   /* Otherwise, scan the glyphs and accumulate their total size in I.  */
  409.   i = 0;
  410.   while ((beg <= end) && *beg)
  411.     {
  412.       register GLYPH g = *beg++;
  413.  
  414.       if (GLYPH_SIMPLE_P (tbase, tlen, (int)g))
  415.     i += 1;
  416.       else
  417.     i += GLYPH_LENGTH (tbase, g);
  418.     }
  419.   return i;
  420. }
  421.  
  422. /* The functions on this page are the interface from xdisp.c to redisplay.
  423.    They take cursor position arguments in origin 0.
  424.  
  425.    The only other interface into redisplay is through setting
  426.    SCREEN_CURSOR_X (screen) and SCREEN_CURSOR_Y (screen)
  427.    and SET_SCREEN_GARBAGED (screen). */
  428.  
  429. /* cancel_line eliminates any request to display a line at position `vpos' */
  430.  
  431. void
  432. cancel_line (vpos, screen)
  433.      int vpos;
  434.      register SCREEN_PTR screen;
  435. {
  436.   SCREEN_DESIRED_GLYPHS (screen)->enable[vpos] = 0;
  437. }
  438.  
  439. void
  440. clear_screen_records (screen)
  441.      register SCREEN_PTR screen;
  442. {
  443.   memset (SCREEN_CURRENT_GLYPHS (screen)->enable, 0, SCREEN_HEIGHT (screen));
  444. }
  445.  
  446. /* Prepare to display on line VPOS starting at HPOS within it.
  447.    Return the glyph string where that line */
  448.  
  449. void
  450. get_display_line (s, vpos, hpos)
  451.      register SCREEN_PTR s;
  452.      int vpos;
  453.      register int hpos;
  454. {
  455.   register struct screen_glyphs *desired_glyphs
  456.     = SCREEN_DESIRED_GLYPHS (s);
  457.   int run;
  458.  
  459.   if (vpos < 0 || (! SCREEN_VISIBLE_P (s)))
  460.     /* abort ();   skip this */
  461.     return;
  462.  
  463.   if ((desired_glyphs->enable[vpos]) && desired_glyphs->used[vpos] > hpos)
  464.     /* abort ();   skip this */
  465.     return;
  466.  
  467.   if (! desired_glyphs->enable[vpos])
  468.     {
  469.       desired_glyphs->used[vpos] = 0;
  470.       desired_glyphs->nruns[vpos] = 0;
  471.       desired_glyphs->face_list[vpos][0].type = unused_run;
  472.       desired_glyphs->face_list[vpos][0].length = 0;
  473.       desired_glyphs->face_list[vpos][0].faceptr = &SCREEN_NORMAL_FACE (s);
  474.       desired_glyphs->face_list[vpos][0].w = 0;
  475.       desired_glyphs->face_list[vpos][0].bufp = 0;
  476.       desired_glyphs->face_list[vpos][0].class = Qnil;
  477.       desired_glyphs->face_list[vpos][0].begin_p = 0;
  478. #ifdef HAVE_X_WINDOWS
  479.       desired_glyphs->face_list[vpos][0].pix_length = 0;
  480. #endif
  481.       desired_glyphs->enable[vpos] = 1;
  482.       run = 0;
  483. #ifdef HAVE_X_WINDOWS
  484.       if (SCREEN_IS_X (s))
  485.     {
  486.       desired_glyphs->pix_width[vpos] = 0;
  487.       desired_glyphs->pix_height[vpos] = 0;
  488.       desired_glyphs->max_ascent[vpos] = 0;
  489.       desired_glyphs->top_left_x[vpos] = 0;
  490.       desired_glyphs->top_left_y[vpos] = 0;
  491.     }
  492. #endif
  493.     }
  494.   else {
  495.     /* Lucid change:  I don't know what this means, but it's probably
  496.        better than crashing.  -- jwz. */
  497.     if (desired_glyphs->nruns[vpos] == 0)
  498.       return;
  499.  
  500.     /* More bogosity.  If all the runs on this line are 0 length, there's
  501.        nothing to do. -- eb */
  502.     /* Search through the face list looking either for runs of non-zero
  503.        length, or for an unused_run indicating no more runs.  If we find
  504.        an unused_run first, just return (there's nothing on this line.) */
  505.     {
  506.       int i = 0;
  507.  
  508.       while (desired_glyphs->face_list[vpos][i].length == 0)
  509.     {
  510.       if (desired_glyphs->face_list[vpos][i].type == unused_run)
  511.         return;
  512.       i++;
  513.     }
  514.     }
  515.  
  516.     /* skip this */
  517.     if (desired_glyphs->nruns[vpos] < 1)
  518.       {
  519.     desired_glyphs->nruns[vpos] = 1;
  520.     desired_glyphs->used[vpos] = 0;
  521.       }
  522.  
  523.     run = desired_glyphs->nruns[vpos] - 1;
  524.   }
  525.  
  526.   if (hpos > desired_glyphs->used[vpos])
  527.     {
  528.       GLYPH *g = desired_glyphs->glyphs[vpos] + desired_glyphs->used[vpos];
  529.       GLYPH *end = desired_glyphs->glyphs[vpos] + hpos;
  530.       int diff = hpos - desired_glyphs->used[vpos];
  531.  
  532.       desired_glyphs->used[vpos] = hpos;
  533.       desired_glyphs->face_list[vpos][run].length += diff;
  534. #ifdef HAVE_X_WINDOWS
  535.       if (SCREEN_IS_X (s))
  536.     {
  537.       XFontStruct *font;
  538.       int width;
  539.  
  540.       font = desired_glyphs->face_list[vpos][run].faceptr->font;
  541.       width = X_CHAR_WIDTH (font, SPACEGLYPH) * diff;
  542.       desired_glyphs->face_list[vpos][run].pix_length += width;
  543.       desired_glyphs->pix_width[vpos] += width;
  544.       }
  545. #endif
  546.       while (g != end)
  547.     *g++ = SPACEGLYPH;
  548.     }
  549. }
  550.  
  551. /* Like bcopy except never gets confused by overlap.  */
  552.  
  553. void
  554. safe_bcopy (from, to, size)
  555.      char *from, *to;
  556.      int size;
  557. {
  558.   register char *endf;
  559.   register char *endt;
  560.  
  561.   if (size == 0)
  562.     return;
  563.  
  564.   /* If destination is higher in memory, and overlaps source zone,
  565.      copy from the end. */
  566.   if (from < to && from + size > to)
  567.     {
  568.       endf = from + size;
  569.       endt = to + size;
  570.  
  571.       do
  572.     *--endt = *--endf;
  573.       while (endf != from);
  574.  
  575.       return;
  576.     }
  577.  
  578.   memcpy (to, from, size);
  579. }
  580.  
  581. /* Rotate a vector of SIZE bytes, by DISTANCE bytes.
  582.    DISTANCE may be negative.  */
  583.  
  584. static void
  585. rotate_vector (vector, size, distance)
  586.      char *vector;
  587.      int size;
  588.      int distance;
  589. {
  590.   char *temp = (char *) alloca (size);
  591.  
  592.   if (distance < 0)
  593.     distance += size;
  594.  
  595.   memcpy (temp + distance, vector, size - distance);
  596.   memcpy (temp, vector + size - distance, distance);
  597.   memcpy (vector, temp, size);
  598. }
  599.  
  600. void update_begin ();
  601. void set_terminal_window ();
  602. void ins_del_lines ();
  603. void update_end ();
  604.  
  605.  
  606. /* Scroll lines from vpos `from' up to but not including vpos `end'
  607.    down by `amount' lines (`amount' may be negative).
  608.    Returns nonzero if done, zero if terminal cannot scroll them. */
  609.  
  610. int
  611. scroll_screen_lines (screen, from, end, amount)
  612.      register SCREEN_PTR screen;
  613.      int from, end, amount;
  614. {
  615.   register struct screen_glyphs *current_screen
  616.     = SCREEN_CURRENT_GLYPHS (screen);
  617.  
  618.   if (!line_ins_del_ok)
  619.     return 0;
  620.  
  621.   if (amount == 0)
  622.     return 1;
  623.  
  624.   if (amount > 0)
  625.     {
  626.       update_begin (screen);
  627.       set_terminal_window (end + amount);
  628.       if (!scroll_region_ok)
  629.     ins_del_lines (end, -amount);
  630.       ins_del_lines (from, amount);
  631.       set_terminal_window (0);
  632.  
  633.       rotate_vector ((char*)(current_screen->glyphs + from),
  634.              sizeof (GLYPH *) * (end + amount - from),
  635.              amount * sizeof (GLYPH *));
  636.  
  637.       safe_bcopy ((char*)(current_screen->used + from),
  638.           (char*)(current_screen->used + from + amount),
  639.           (end - from) * sizeof current_screen->used[0]);
  640.  
  641.       safe_bcopy (current_screen->enable + from,
  642.           current_screen->enable + from + amount,
  643.           (end - from) * sizeof current_screen->enable[0]);
  644.  
  645.       memset (current_screen->enable + from, 0,
  646.          amount * sizeof current_screen->enable[0]);
  647.  
  648.       safe_bcopy ((char*)(current_screen->bufp + from),
  649.           (char*)(current_screen->bufp + from + amount),
  650.           (end - from) * sizeof current_screen->bufp[0]);
  651.  
  652.       rotate_vector ((char*)(current_screen->face_list + from),
  653.              sizeof (struct run *) * (end + amount - from),
  654.              amount * sizeof (struct run *));
  655.  
  656.       safe_bcopy ((char*)(current_screen->nruns + from),
  657.           (char*)(current_screen->nruns + from + amount),
  658.           (end - from) * sizeof current_screen->nruns[0]);
  659.  
  660. #ifdef HAVE_X_WINDOWS
  661.       if (SCREEN_IS_X (screen))
  662.     {
  663.       register int i;
  664.       register int pix_y;
  665.  
  666.       pix_y = current_screen->top_left_y[0];
  667.  
  668. #if 0
  669.       safe_bcopy (current_screen->top_left_x + from,
  670.               current_screen->top_left_x + from + amount,
  671.               (end - from) * sizeof current_screen->top_left_x[0]);
  672. #endif
  673.  
  674.       safe_bcopy ((char*)(current_screen->pix_height + from),
  675.               (char*)(current_screen->pix_height + from + amount),
  676.               (end - from) * sizeof current_screen->pix_height[0]);
  677.  
  678.       safe_bcopy ((char*)(current_screen->max_ascent + from),
  679.               (char*)(current_screen->max_ascent + from + amount),
  680.               (end - from) * sizeof current_screen->max_ascent[0]);
  681.  
  682.       safe_bcopy ((char*)(current_screen->pix_width + from),
  683.               (char*)(current_screen->pix_width + from + amount),
  684.               (end - from) * sizeof current_screen->pix_width[0]);
  685.  
  686.       for (i = 0; i < screen->height; i++)
  687.         {
  688.           current_screen->top_left_y[i] = pix_y;
  689.           pix_y += current_screen->pix_height[i];
  690.         }
  691.     }
  692. #endif /* HAVE_X_WINDOWS */
  693.  
  694.       update_end (screen);
  695.     }
  696.  
  697.   if (amount < 0)
  698.     {
  699.       update_begin (screen);
  700.       set_terminal_window (end);
  701.       ins_del_lines (from + amount, amount);
  702.       if (!scroll_region_ok)
  703.     ins_del_lines (end + amount, -amount);
  704.       set_terminal_window (0);
  705.  
  706.       rotate_vector ((char*)(current_screen->glyphs + from + amount),
  707.              sizeof (GLYPH *) * (end - from - amount),
  708.              amount * sizeof (GLYPH *));
  709.  
  710.       safe_bcopy ((char*)(current_screen->used + from),
  711.           (char*)(current_screen->used + from + amount),
  712.           (end - from) * sizeof current_screen->used[0]);
  713.  
  714.       safe_bcopy (current_screen->enable + from,
  715.           current_screen->enable + from + amount,
  716.           (end - from) * sizeof current_screen->enable[0]);
  717.  
  718.       memset (current_screen->enable + end + amount, 0,
  719.          - amount * sizeof current_screen->enable[0]);
  720.  
  721.       safe_bcopy ((char*)(current_screen->bufp + from),
  722.           (char*)(current_screen->bufp + from + amount),
  723.           (end - from) * sizeof current_screen->bufp[0]);
  724.  
  725.       rotate_vector ((char*)(current_screen->face_list + from + amount),
  726.              sizeof (struct run *) * (end - from - amount),
  727.              amount * sizeof (struct run *));
  728.  
  729.       safe_bcopy ((char*)(current_screen->nruns + from),
  730.           (char*)(current_screen->nruns + from + amount),
  731.           (end - from) * sizeof current_screen->nruns[0]);
  732.  
  733. #ifdef HAVE_X_WINDOWS
  734.       if (SCREEN_IS_X (screen))
  735.     {
  736.       register int pix_y;
  737.  
  738.       pix_y = current_screen->top_left_y[0];
  739.  
  740. #if 0
  741.       safe_bcopy (current_screen->top_left_x + from,
  742.               current_screen->top_left_x + from + amount,
  743.               (end - from) * sizeof current_screen->top_left_x[0]);
  744. #endif
  745.  
  746.       safe_bcopy ((char*)(current_screen->pix_width + from),
  747.               (char*)(current_screen->pix_width + from + amount),
  748.               (end - from) * sizeof current_screen->pix_width[0]);
  749.  
  750.       safe_bcopy ((char*)(current_screen->pix_height + from),
  751.               (char*)(current_screen->pix_height + from + amount),
  752.               (end - from) * sizeof current_screen->pix_height[0]);
  753.  
  754.       safe_bcopy ((char*)(current_screen->max_ascent + from),
  755.               (char*)(current_screen->max_ascent + from + amount),
  756.               (end - from) * sizeof current_screen->max_ascent[0]);
  757.     }
  758. #endif /* HAVE_X_WINDOWS */
  759.  
  760.       update_end (screen);
  761.     }
  762.   return 1;
  763. }
  764.  
  765. /* After updating a window w that isn't the full screen wide,
  766.    copy all the columns that w does not occupy
  767.    into the SCREEN_DESIRED_GLYPHS (screen) from the SCREEN_PHYS_GLYPHS (screen)
  768.    so that update_screen will not change those columns.  */
  769.  
  770. void
  771. preserve_other_columns (w)
  772.      struct window *w;
  773. {
  774.   register int vpos;
  775.   register struct screen_glyphs *current_screen, *desired_screen;
  776.   register SCREEN_PTR screen = XSCREEN (w->screen);
  777.   int start = XFASTINT (w->left);
  778.   int end = XFASTINT (w->left) + XFASTINT (w->width);
  779.   int bot = XFASTINT (w->top) + XFASTINT (w->height);
  780.  
  781.   current_screen = SCREEN_CURRENT_GLYPHS (screen);
  782.   desired_screen = SCREEN_DESIRED_GLYPHS (screen);
  783.  
  784.   for (vpos = XFASTINT (w->top); vpos < bot; vpos++)
  785.     {
  786.       if (current_screen->enable[vpos] && desired_screen->enable[vpos])
  787.     {
  788.       if (start > 0)
  789.         {
  790.           int len;
  791.  
  792.           memcpy (desired_screen->glyphs[vpos],
  793.               current_screen->glyphs[vpos],
  794.               start);
  795.           len = min (start, current_screen->used[vpos]);
  796.           if (desired_screen->used[vpos] < len)
  797.         desired_screen->used[vpos] = len;
  798.         }
  799.       if (current_screen->used[vpos] > end
  800.           && desired_screen->used[vpos] < current_screen->used[vpos])
  801.         {
  802.           while (desired_screen->used[vpos] < end)
  803.         desired_screen->glyphs[vpos][desired_screen->used[vpos]++]
  804.           = SPACEGLYPH;
  805.           memcpy (desired_screen->glyphs + end,
  806.               current_screen->glyphs + end,
  807.               current_screen->used[vpos] - end);
  808.           desired_screen->used[vpos] = current_screen->used[vpos];
  809.         }
  810.     }
  811.     }
  812. }
  813.  
  814. /* On discovering that the redisplay for a window was no good,
  815.    cancel the columns of that window, so that when the window is
  816.    displayed over again get_display_line will not complain. */
  817.  
  818. void
  819. cancel_my_columns (w)
  820.      struct window *w;
  821. {
  822.   register int vpos;
  823.   register SCREEN_PTR screen = XSCREEN (w->screen);
  824.   register struct screen_glyphs *desired_glyphs = screen->desired_glyphs;
  825.   register int start = XFASTINT (w->left);
  826.   register int bot = XFASTINT (w->top) + XFASTINT (w->height);
  827.  
  828.   for (vpos = XFASTINT (w->top); vpos < bot; vpos++)
  829.     if (desired_glyphs->enable[vpos]
  830.     && desired_glyphs->used[vpos] >= start)
  831.       while (desired_glyphs->used[vpos] > start)
  832.     {
  833.       register int n = desired_glyphs->nruns[vpos] - 1;
  834.  
  835.       desired_glyphs->used[vpos]
  836.         -= desired_glyphs->face_list[vpos][n].length;
  837. #ifdef HAVE_X_WINDOWS
  838.       if (SCREEN_IS_X (screen))
  839.         desired_glyphs->pix_width[vpos]
  840.           -= desired_glyphs->face_list[vpos][n].pix_length;
  841. #endif
  842.       desired_glyphs->nruns[vpos]--;
  843.     }
  844. }
  845.  
  846.  
  847. void write_glyphs ();
  848.  
  849. /* These functions try to perform directly and immediately on the screen
  850.    the necessary output for one change in the buffer.
  851.    They may return 0 meaning nothing was done if anything is difficult,
  852.    or 1 meaning the output was performed properly.
  853.    They assume that the screen was up to date before the buffer
  854.    change being displayed.  THey make various other assumptions too;
  855.    see command_loop_1 where these are called.  */
  856.  
  857. int
  858. direct_output_for_insert (g)
  859.      int g;
  860. {
  861.   register SCREEN_PTR screen = selected_screen;
  862.   register struct screen_glyphs *current_screen
  863.     = SCREEN_CURRENT_GLYPHS (screen);
  864.   register int i;
  865.  
  866. #ifndef COMPILER_REGISTER_BUG
  867.   register
  868. #endif /* COMPILER_REGISTER_BUG */
  869.     struct window *w = XWINDOW (selected_window);
  870. #ifndef COMPILER_REGISTER_BUG
  871.   register
  872. #endif /* COMPILER_REGISTER_BUG */
  873.     int hpos = SCREEN_CURSOR_X (screen);
  874. #ifndef COMPILER_REGISTER_BUG
  875.   register
  876. #endif /* COMPILER_REGISTER_BUG */
  877.     int vpos = SCREEN_CURSOR_Y (screen);
  878.  
  879.   /* Give up if about to continue line */
  880.   if (hpos - XFASTINT (w->left) + 1 + 1 >= XFASTINT (w->width)
  881.  
  882.   /* Avoid losing if cursor is in invisible text off left margin */
  883.       || (XINT (w->hscroll) && hpos == XFASTINT (w->left))
  884.     
  885.   /* Give up if cursor outside window (in minibuf, probably) */
  886.       || SCREEN_CURSOR_Y (screen) < XFASTINT (w->top)
  887.       || SCREEN_CURSOR_Y (screen) >= XFASTINT (w->top) + XFASTINT (w->height)
  888.  
  889.   /* Give up if cursor not really at SCREEN_CURSOR_X, SCREEN_CURSOR_Y */
  890.       || !display_completed
  891.  
  892.   /* Give up if buffer appears in two places.  */
  893.       || buffer_shared > 1
  894.  
  895.   /* Give up if w is minibuffer and a message is being displayed there */
  896.       || (MINI_WINDOW_P (w) && echo_area_glyphs))
  897.     return 0;
  898.  
  899.   current_screen->glyphs[vpos][hpos] = g;
  900.   for (i = vpos+1; i < SCREEN_HEIGHT (screen); i++)
  901.     if (current_screen->bufp[i])
  902.       current_screen->bufp[i]++;
  903.  
  904.   unchanged_modified = MODIFF;
  905.   beg_unchanged = GPT - BEG;
  906.   XFASTINT (w->last_point) = point;
  907.   XFASTINT (w->last_point_x) = hpos;
  908.   XFASTINT (w->last_modified) = MODIFF;
  909.   XFASTINT (w->last_facechange) = FACECHANGE;
  910.  
  911.   if (hpos == current_screen->used[vpos])
  912.     {
  913.       int last_run;
  914.  
  915.       if (current_screen->nruns[vpos] == 0)
  916.     current_screen->nruns[vpos] = 1;
  917.  
  918.       last_run = current_screen->nruns[vpos] - 1;
  919.  
  920.       current_screen->used[vpos] = hpos + 1;
  921.       current_screen->glyphs[vpos][hpos + 1] = 0;
  922.       current_screen->face_list[vpos][last_run].length++;
  923.  
  924. #ifdef HAVE_X_WINDOWS
  925.       if (SCREEN_IS_X (screen))
  926.     {
  927.       XFontStruct *font;
  928.       int width;
  929.  
  930.       font = current_screen->face_list[vpos][last_run].faceptr->font;
  931.       if (!font)
  932.         font = SCREEN_NORMAL_FACE (screen).font;
  933.       width = X_CHAR_WIDTH (font, g);
  934.       current_screen->face_list[vpos][last_run].pix_length += width;
  935.       current_screen->pix_width[vpos] += width;
  936.     }
  937. #endif
  938.     }
  939.  
  940.   write_glyphs (hpos, vpos, 1);
  941.   fflush (stdout);
  942.   ++SCREEN_CURSOR_X (screen);
  943.  
  944.   return 1;
  945. }
  946.  
  947. int
  948. direct_output_forward_char (n)
  949.      int n;
  950. {
  951.   /* Ok, I'm sick of this.  This function doesn't work right when glyphs
  952.      are involved, and neither does the compute_motion() hack below, so
  953.      just blow it off.  If we return 0 here, the cursor position will
  954.      be computed later in a way that works.  --jwz.
  955.    */
  956.   return 0;
  957.  
  958. #if 0
  959.   register SCREEN_PTR screen = selected_screen;
  960.   register struct window *w = XWINDOW (selected_window);
  961.  
  962.   /* Avoid losing if cursor is in invisible text off left margin */
  963.   if (XINT (w->hscroll) && SCREEN_CURSOR_X (screen) == XFASTINT (w->left)
  964.  
  965.   /* Give up if about to continue line */
  966.     || (SCREEN_CURSOR_X (screen) - XFASTINT (w->left) + 1 + 1
  967.     >= XFASTINT (w->width))
  968.     
  969.   /* Give up if cursor outside window (in minibuf, probably) */
  970.       || SCREEN_CURSOR_Y (screen) < XFASTINT (w->top)
  971.       || SCREEN_CURSOR_Y (screen) >= XFASTINT (w->top) + XFASTINT (w->height)
  972.  
  973.   /* Give up if cursor not really at SCREEN_CURSOR_X, SCREEN_CURSOR_Y */
  974.       || !display_completed
  975.  
  976.   /* Give up if buffer appears in two places.  */
  977.       || buffer_shared > 1
  978.  
  979.   /* Give up if w is minibuffer and a message is being displayed there */
  980.       || (MINI_WINDOW_P (w) && echo_area_glyphs))
  981.     return 0;
  982.   SCREEN_CURSOR_X (screen) += n;
  983.  
  984.   {
  985.     /* This has to be a lot more complicated because of glyphs: to move
  986.        forward one character, the cursor must sometimes move multiple
  987.        character-positions on the screen.  Only compute-motion knows how
  988.        to do this right, since the screen data structures really suck.
  989.      */
  990.     int cx = SCREEN_CURSOR_X (screen);
  991.     int cy = SCREEN_CURSOR_Y (screen);
  992.     int line_begin_pos      = SCREEN_CURRENT_GLYPHS (screen)->bufp[cy];
  993.     int next_line_begin_pos = SCREEN_CURRENT_GLYPHS (screen)->bufp[cy + 1];
  994.  
  995.     struct position *position
  996.       = compute_motion (SCREEN_SELECTED_WINDOW (screen),
  997.             /* from, fromvpos, fromhpos, */
  998.             line_begin_pos, cy, 0,
  999.             /* to, tovpos, tohpos, */
  1000.             next_line_begin_pos, cy, cx + n,
  1001.             /* width, hscroll, tab_offset */
  1002.             XINT(w->width), XINT(w->hscroll),
  1003.             pos_tab_offset(w, line_begin_pos),
  1004.             0, 0);
  1005.     if (SCREEN_CURSOR_Y (screen) != position->vpos)
  1006.       return 0;
  1007.     SCREEN_CURSOR_X (screen) = position->hpos;
  1008.   }
  1009.  
  1010.   XFASTINT (w->last_point_x) = SCREEN_CURSOR_X (screen);
  1011.   XFASTINT (w->last_point) = point;
  1012.   cursor_to (SCREEN_CURSOR_Y (screen), SCREEN_CURSOR_X (screen));
  1013.   fflush (stdout);
  1014.   return 1;
  1015. #endif
  1016. }
  1017.  
  1018. static int
  1019. count_blanks (r)
  1020.      register GLYPH *r;
  1021. {
  1022.   register GLYPH *p = r;
  1023.   while (*r++ == SPACEGLYPH);
  1024.   return r - p - 1;
  1025. }
  1026.  
  1027. static int
  1028. count_match (str1, str2)
  1029.      GLYPH *str1, *str2;
  1030. {
  1031.   register GLYPH *p1 = str1;
  1032.   register GLYPH *p2 = str2;
  1033.   while (*p1++ == *p2++);
  1034.   return p1 - str1 - 1;
  1035. }
  1036.  
  1037. /* Char insertion/deletion cost vector, from term.c */
  1038. extern int *char_ins_del_vector;
  1039.  
  1040. void cursor_to ();
  1041. void clear_end_of_line ();
  1042. void delete_glyphs ();
  1043. void insert_spaceglyphs ();
  1044. void insert_glyphs ();
  1045.  
  1046. #define char_ins_del_cost(s) (&char_ins_del_vector[SCREEN_HEIGHT((s))])
  1047.  
  1048. static void
  1049. update_line (screen, vpos)
  1050.      register SCREEN_PTR screen;
  1051.      int vpos;
  1052. {
  1053.   register GLYPH *obody, *nbody, *op1, *op2, *np1, *temp;
  1054.   int tem;
  1055.   int osp, nsp, m1, m2, olen, nlen;
  1056.   int save;
  1057.   register struct screen_glyphs *current_screen
  1058.     = SCREEN_CURRENT_GLYPHS (screen);
  1059.   register struct screen_glyphs *desired_screen
  1060.     = SCREEN_DESIRED_GLYPHS (screen);
  1061.   int nruns = desired_screen->nruns[vpos];
  1062.   int runs = current_screen->nruns[vpos];
  1063.   struct run *temp_runs;
  1064.  
  1065.   if (! current_screen->enable[vpos])
  1066.     {
  1067.       olen = 0;
  1068.     }
  1069.   else
  1070.     {
  1071.       obody = current_screen->glyphs[vpos];
  1072.       olen = current_screen->used[vpos];
  1073.       if (!must_write_spaces
  1074.       && runs == 1
  1075.       && ! current_screen->face_list[vpos][0].faceptr->hilited
  1076.       && ! current_screen->face_list[vpos][0].faceptr->underline)
  1077.     while (obody[olen - 1] == SPACEGLYPH && olen > 0)
  1078.       olen--;
  1079.     }
  1080.  
  1081.   nbody = desired_screen->glyphs[vpos];
  1082.   nlen = desired_screen->used[vpos];
  1083.  
  1084.   /* One way or another, this will enable the line being updated. */
  1085.   current_screen->enable[vpos] = 1;
  1086.   current_screen->used[vpos] = desired_screen->used[vpos];
  1087.   current_screen->bufp[vpos] = desired_screen->bufp[vpos];
  1088.   current_screen->nruns[vpos] = desired_screen->nruns[vpos];
  1089.  
  1090.   if (!desired_screen->enable[vpos])
  1091.     {
  1092.       struct run *run = desired_screen->face_list[vpos];
  1093.  
  1094.       current_screen->face_list[vpos] = desired_screen->face_list[vpos];
  1095.       desired_screen->face_list[vpos] = run;
  1096.  
  1097.       nlen = 0;
  1098.       goto just_erase;
  1099.     }
  1100.  
  1101.   if (!must_write_spaces
  1102.       && runs == 1
  1103.       && ! desired_screen->face_list[vpos][0].faceptr->hilited
  1104.       && ! desired_screen->face_list[vpos][0].faceptr->underline)
  1105.     /* We know that the previous character byte contains 0. */
  1106.     while (nbody[nlen - 1] == SPACEGLYPH)
  1107.       nlen--;
  1108.  
  1109.   /* Exchange contents between current_screen and new_screen.  */
  1110.   temp = desired_screen->glyphs[vpos];
  1111.   desired_screen->glyphs[vpos] = current_screen->glyphs[vpos];
  1112.   current_screen->glyphs[vpos] = temp;
  1113.  
  1114.   /* If there's no i/d char or there are several runs,
  1115.      output non-matching runs...  */
  1116.   if (!char_ins_del_ok || nruns > 1)
  1117.     {
  1118.       int i,j;
  1119.       int this_run;
  1120.       struct run *new_runs = desired_screen->face_list[vpos];
  1121.       struct run *old_runs = current_screen->face_list[vpos];
  1122.       int len_runs_output;
  1123.  
  1124.       desired_screen->face_list[vpos] = old_runs;
  1125.       current_screen->face_list[vpos] = new_runs;
  1126.  
  1127.       i = 0;
  1128.       this_run = 0;
  1129.       len_runs_output = 0;
  1130.  
  1131.       while (this_run < nruns && nlen > 0)
  1132.     {
  1133.       int run_len = new_runs[this_run].length;
  1134.       int orun_len;
  1135.  
  1136.       /* If past the end of the old runs, or the old contents,
  1137.          just write out the rest of the line and quit. */
  1138.       if (this_run >= runs || i > olen || olen == 0)
  1139.         {
  1140.           cursor_to (vpos, i);
  1141.           write_glyphs (i, vpos, nlen - len_runs_output);
  1142.           break;
  1143.         }
  1144.  
  1145.       orun_len = old_runs[this_run].length;
  1146.       /* If this run has a different face, write out the whole run. */
  1147.       if (old_runs[this_run].faceptr != new_runs[this_run].faceptr
  1148.           || new_runs[this_run].faceptr->modif)
  1149.         {
  1150.           new_runs[this_run].faceptr->modif = 0;
  1151.           cursor_to (vpos, i);
  1152.           if (old_runs[this_run].faceptr->underline
  1153.           && ! new_runs[this_run].faceptr->underline)
  1154.         {
  1155.           clear_end_of_line (i + orun_len);
  1156.         }
  1157.           write_glyphs (i, vpos, run_len);
  1158.           i += run_len;
  1159.         }
  1160.       else
  1161.         {
  1162.           int len = min (run_len, orun_len);
  1163.  
  1164.           /* Compare the contents, writing out what's changed. */
  1165.           while (i < len_runs_output + len)
  1166.         {
  1167.           if (i > olen || nbody[i] != obody[i])
  1168.             {
  1169.               cursor_to (vpos, i);
  1170.               for (j = 1; (i + j < len_runs_output + len
  1171.                    && (nbody[i+j] != obody[i+j]));
  1172.                j++);
  1173.  
  1174.               write_glyphs (i, vpos, j);
  1175.               i += j;
  1176.             }
  1177.           else
  1178.             i++;
  1179.         }
  1180.  
  1181.           /* If the new run is longer than the old, just rewrite those
  1182.          trailing characters, as they could be the same but with
  1183.          a different face. */
  1184.           if (len < run_len)
  1185.         {
  1186.           cursor_to (vpos, i);
  1187.           write_glyphs (i, vpos, (run_len - len));
  1188.           i += (run_len - len);
  1189.         }
  1190.         }
  1191.  
  1192.       this_run++;
  1193.       len_runs_output += run_len;
  1194.     }
  1195.  
  1196.       /* Exits */
  1197.       goto just_erase;
  1198.     }
  1199.  
  1200.   if (!nlen)
  1201.     {
  1202.       temp_runs = desired_screen->face_list[vpos];
  1203.       desired_screen->face_list[vpos] = current_screen->face_list[vpos];
  1204.       current_screen->face_list[vpos] = temp_runs;
  1205.  
  1206.       /* Exits */
  1207.       goto just_erase;
  1208.     }
  1209.  
  1210.   if (current_screen->face_list[vpos][0].faceptr
  1211.       != desired_screen->face_list[vpos][0].faceptr
  1212.       || desired_screen->face_list[vpos][0].faceptr->modif)
  1213.     {
  1214.       desired_screen->face_list[vpos][0].faceptr->modif = 0;
  1215.       temp_runs = desired_screen->face_list[vpos];
  1216.       desired_screen->face_list[vpos] = current_screen->face_list[vpos];
  1217.       current_screen->face_list[vpos] = temp_runs;
  1218.  
  1219.       cursor_to (vpos, 0);
  1220.       write_glyphs (0, vpos, nlen);
  1221.  
  1222.       /* Exits */
  1223.       goto just_erase;
  1224.     }
  1225.  
  1226.   if (!olen)
  1227.     {
  1228.       temp_runs = desired_screen->face_list[vpos];
  1229.       desired_screen->face_list[vpos] = current_screen->face_list[vpos];
  1230.       current_screen->face_list[vpos] = temp_runs;
  1231.  
  1232.       nsp = (must_write_spaces
  1233.          || desired_screen->face_list[vpos][0].faceptr->hilited
  1234.          || desired_screen->face_list[vpos][0].faceptr->underline)
  1235.     ? 0
  1236.       : count_blanks (nbody);
  1237.       if (nlen > nsp)
  1238.     {
  1239.       cursor_to (vpos, nsp);
  1240.       write_glyphs (nsp, vpos, nlen - nsp);
  1241.     }
  1242.  
  1243.       return;
  1244.     }
  1245.  
  1246.   temp_runs = desired_screen->face_list[vpos];
  1247.   desired_screen->face_list[vpos] = current_screen->face_list[vpos];
  1248.   current_screen->face_list[vpos] = temp_runs;
  1249.  
  1250.   obody[olen] = 1;
  1251.   save = nbody[nlen];
  1252.   nbody[nlen] = 0;
  1253.  
  1254.   /* Compute number of leading blanks in old and new contents.  */
  1255.   osp = ((current_screen->face_list[vpos][0].faceptr->hilited
  1256.       || current_screen->face_list[vpos][0].faceptr->underline)
  1257.      ? 0
  1258.      : count_blanks (obody));
  1259.   nsp = ((desired_screen->face_list[vpos][0].faceptr->hilited
  1260.       || desired_screen->face_list[vpos][0].faceptr->underline)
  1261.      ? 0
  1262.      : count_blanks (nbody));
  1263.  
  1264.   /* Compute number of matching chars starting with first nonblank.  */
  1265.   m1 = count_match (obody + osp, nbody + nsp);
  1266.  
  1267.   /* Spaces in new match implicit space past the end of old.  */
  1268.   /* A bug causing this to be a no-op was fixed in 18.29.  */
  1269.   if (!must_write_spaces && osp + m1 == olen)
  1270.     {
  1271.       np1 = nbody + nsp;
  1272.       while (np1[m1] == SPACEGLYPH)
  1273.     m1++;
  1274.     }
  1275.  
  1276.   /* Avoid doing insert/delete char
  1277.      just cause number of leading spaces differs
  1278.      when the following text does not match. */
  1279.   if (m1 == 0 && osp != nsp)
  1280.     osp = nsp = min (osp, nsp);
  1281.  
  1282.   /* Find matching characters at end of line */
  1283.   op1 = obody + olen;
  1284.   np1 = nbody + nlen;
  1285.   op2 = op1 + m1 - min (olen - osp, nlen - nsp);
  1286.   while (op1 > op2 && op1[-1] == np1[-1])
  1287.     {
  1288.       op1--;
  1289.       np1--;
  1290.     }
  1291.   m2 = obody + olen - op1;
  1292.  
  1293.   /* Put correct value back in nbody[nlen].
  1294.      This is important because direct_output_for_insert
  1295.      can write into the line at a later point.  */
  1296.   nbody[nlen] = save;
  1297.  
  1298.   /* tem gets the distance to insert or delete.
  1299.      m2 is how many characters we save by doing so.
  1300.      Is it worth it?  */
  1301.  
  1302.   tem = (nlen - nsp) - (olen - osp);
  1303.   if (m2 && tem && (!char_ins_del_ok || m2 <= char_ins_del_cost (screen)[tem]))
  1304.     m2 = 0;
  1305.  
  1306.   /* nsp - osp is the distance to insert or delete.
  1307.      If that is nonzero, m1 is known to be nonzero also.
  1308.      m1 + m2 is how much we save by doing the ins/del.
  1309.      Is it worth it?  */
  1310.  
  1311.   if (nsp != osp
  1312.       && (!char_ins_del_ok
  1313.       || m1 + m2 <= char_ins_del_cost (screen)[nsp - osp]))
  1314.     {
  1315.       m1 = 0;
  1316.       m2 = 0;
  1317.       osp = nsp = min (osp, nsp);
  1318.     }
  1319.  
  1320.   /* Now go through the line, inserting, writing
  1321.      and deleting as appropriate.  */
  1322.  
  1323.   if (osp > nsp)
  1324.     {
  1325.       cursor_to (vpos, nsp);
  1326.       delete_glyphs (osp - nsp);
  1327.     }
  1328.   else if (nsp > osp)
  1329.     {
  1330.       /* If going to delete chars later in line
  1331.      and insert earlier in the line,
  1332.      must delete first to avoid losing data in the insert */
  1333.       if (m2 && nlen < olen + nsp - osp)
  1334.     {
  1335.       cursor_to (vpos, nlen - m2 + osp - nsp);
  1336.       delete_glyphs (olen + nsp - osp - nlen);
  1337.       olen = nlen - (nsp - osp);
  1338.     }
  1339.       cursor_to (vpos, osp);
  1340.       insert_spaceglyphs (osp, vpos, nsp - osp);
  1341.     }
  1342.   olen += nsp - osp;
  1343.  
  1344.   tem = nsp + m1 + m2;
  1345.   if (nlen != tem || olen != tem)
  1346.     {
  1347.       cursor_to (vpos, nsp + m1);
  1348.       if (!m2 || nlen == olen)
  1349.     {
  1350.       /* If new text being written reaches right margin,
  1351.          there is no need to do clear-to-eol at the end.
  1352.          (and it would not be safe, since cursor is not
  1353.          going to be "at the margin" after the text is done) */
  1354.       if (nlen == SCREEN_WIDTH (screen))
  1355.         olen = 0;
  1356.       write_glyphs (nsp + m1, vpos, nlen - tem);
  1357.     }
  1358.       else if (nlen > olen)
  1359.     {
  1360.       write_glyphs (nsp + m1, vpos, olen - tem);
  1361.       insert_glyphs (nsp + m1 + olen - tem, vpos, nlen - olen);
  1362.       olen = nlen;
  1363.     }
  1364.       else if (olen > nlen)
  1365.     {
  1366.       write_glyphs (nsp + m1, vpos, nlen - tem);
  1367.       delete_glyphs (olen - nlen);
  1368.       olen = nlen;
  1369.     }
  1370.     }
  1371.  
  1372.  just_erase:
  1373.   /* If any unerased characters remain after the new line, erase them.  */
  1374.   if (olen > nlen)
  1375.     {
  1376.       cursor_to (vpos, nlen);
  1377.       clear_end_of_line (olen);
  1378.     }
  1379. }
  1380.  
  1381. #ifdef HAVE_X_WINDOWS
  1382.  
  1383. extern void x_clear_display_line (int, int);
  1384. extern int x_write_glyphs (struct screen *, int, int, int, GC, int);
  1385. extern void x_clear_display_line_end (int);
  1386.  
  1387. static void
  1388. x_update_line (screen, vpos, pix_y)
  1389.      register SCREEN_PTR screen;
  1390.      int vpos, pix_y;
  1391. {
  1392.   /* What we want to show. */
  1393.   register struct screen_glyphs *desired_screen
  1394.     = SCREEN_DESIRED_GLYPHS (screen);
  1395.   struct run *faces = desired_screen->face_list[vpos];
  1396.   int pix_length = desired_screen->pix_width[vpos];
  1397.   int used = desired_screen->used[vpos];
  1398.   int nruns = desired_screen->nruns[vpos];
  1399.   GLYPH *glyphs = desired_screen->glyphs[vpos];
  1400.   int pix_height = desired_screen->pix_height[vpos];
  1401.   int ascent = desired_screen->max_ascent[vpos];
  1402.  
  1403.   /* What is currently shown. */
  1404.   register struct screen_glyphs *current_screen
  1405.     = SCREEN_CURRENT_GLYPHS (screen);
  1406.   int currently_enabled = current_screen->enable[vpos];
  1407.   struct run *old_faces = 0;
  1408.   int old_pix_length = 0;
  1409.   int old_used = 0;
  1410.   int oruns = 0;
  1411.   GLYPH *old_glyphs = 0;
  1412.   int old_pix_y = 0;
  1413.   int old_pix_height = 0;
  1414.   int old_ascent = 0;
  1415.  
  1416.   GLYPH *temp;
  1417.   struct run *temp_runs;
  1418.   register int g, this_run;
  1419.   int line_changed;
  1420.  
  1421.   if (currently_enabled)
  1422.     {
  1423.       old_faces = current_screen->face_list[vpos];
  1424.       old_faces = current_screen->face_list[vpos];
  1425.       old_pix_length = current_screen->pix_width[vpos];
  1426.       old_used = current_screen->used[vpos];
  1427.       oruns = current_screen->nruns[vpos];
  1428.       old_glyphs = current_screen->glyphs[vpos];
  1429.       old_pix_y = current_screen->top_left_y[vpos];
  1430.       old_pix_height = current_screen->pix_height[vpos];
  1431.       old_ascent = current_screen->max_ascent[vpos];
  1432.     }
  1433.  
  1434.   current_screen->enable[vpos] = 1;
  1435.   current_screen->used[vpos] = desired_screen->used[vpos];
  1436.   current_screen->bufp[vpos] = desired_screen->bufp[vpos];
  1437.   current_screen->nruns[vpos] = desired_screen->nruns[vpos];
  1438.   current_screen->pix_width[vpos] = desired_screen->pix_width[vpos];
  1439.   current_screen->pix_height[vpos] = desired_screen->pix_height[vpos];
  1440.   current_screen->max_ascent[vpos] = desired_screen->max_ascent[vpos];
  1441.  
  1442.   current_screen->top_left_y[vpos] = pix_y;
  1443. #ifdef LINE_INFO_COLUMN
  1444.   current_screen->top_left_x[vpos] = screen->display.x->internal_border_width;
  1445. #else
  1446.   current_screen->top_left_x[vpos] = screen->display.x->internal_border_width;
  1447. #endif
  1448.  
  1449.   temp_runs = current_screen->face_list[vpos];
  1450.   current_screen->face_list[vpos] = desired_screen->face_list[vpos];
  1451.   desired_screen->face_list[vpos] = temp_runs;
  1452.  
  1453.   temp = desired_screen->glyphs[vpos];
  1454.   desired_screen->glyphs[vpos] = current_screen->glyphs[vpos];
  1455.   current_screen->glyphs[vpos] = temp;
  1456.  
  1457. /*  screen->cursor_y = vpos; */
  1458.  
  1459. #ifdef LINE_INFO_COLUMN
  1460.   /* If there was a lineinfo glyph and there isn't now, or it has
  1461.      changed, then clear it */
  1462.  /*  x_clear_lineinfo_glyph (screen, vpos); */
  1463. #endif
  1464.  
  1465.   if (used == 0)
  1466.     {
  1467.       /* Nothing here now.  Clear anything that was here before. */
  1468.       if (old_used > 0 || pix_y != old_pix_y)
  1469.     x_clear_display_line (vpos, old_pix_length);
  1470.       return;
  1471.     }
  1472.  
  1473.   /* Clear screen or something erased the line, or it was blank. */
  1474.   if (old_used == 0 || ! currently_enabled)
  1475.     {
  1476.       x_write_glyphs (screen, 0, vpos, used, 0, 0);
  1477.       return;
  1478.     }
  1479.  
  1480.   /* Remove blanks as optimization...? */
  1481.  
  1482.   if (pix_y < old_pix_y || pix_height > old_pix_height || ascent != old_ascent)
  1483.     {
  1484.       /* Different vertical coordinates, so rewrite the whole thing. */
  1485.       x_clear_display_line (vpos, old_pix_length);
  1486.       x_write_glyphs (screen, 0, vpos, used, 0, 0);
  1487.       return;
  1488.     }
  1489.  
  1490.   /* Go through all the runs. */
  1491.   g = 0;
  1492.   /* If this line wasn't enabled before, it's changed completely */
  1493.   line_changed = !currently_enabled;
  1494.   for (this_run = 0; this_run < nruns; this_run++)
  1495.     {
  1496.       /* If there are no more old runs to compare to, punt. */
  1497.       if (this_run >= oruns)
  1498.     {
  1499.       x_write_glyphs (screen, g, vpos, used - g, 0, 0);
  1500.       break;
  1501.     }
  1502.  
  1503.       {
  1504.  
  1505.     int from = g;
  1506.     int len = faces[this_run].length;
  1507.     int to = g + len;
  1508.     int oldlen = old_faces[this_run].length;
  1509.     int to_old = g + oldlen;
  1510.  
  1511. #ifdef LINE_INFO_COLUMN
  1512.     if (faces[this_run].type == column_glyph &&
  1513.         old_faces[this_run].type == column_glyph)
  1514.       {
  1515.         if (faces[this_run].lineinfo_glyph_index ==
  1516.         old_faces[this_run].lineinfo_glyph_index)
  1517.           {
  1518.         g = to;
  1519.         continue;
  1520.           }
  1521.       }
  1522.     else
  1523. #endif
  1524.       /* If everything else is the same, compare the line contents. */
  1525.       if (faces[this_run].faceptr == old_faces[this_run].faceptr
  1526.           && ! faces[this_run].faceptr->modif
  1527.           && faces[this_run].type == old_faces[this_run].type
  1528.           && !line_changed)
  1529.         {
  1530.           while (from < to && from < to_old
  1531.              && glyphs[from] == old_glyphs[from])
  1532.         from++;
  1533.         }
  1534.     if (from != to)
  1535.       {
  1536.         x_write_glyphs (screen, from, vpos, to - from, 0, 0);
  1537.         line_changed = 1;
  1538.       }
  1539.     else if (from != to_old)
  1540.       /* The new run only matches the beginning of the old run, so the line
  1541.          has changed */
  1542.       line_changed = 1;
  1543.     g = to;
  1544.     }
  1545.     }
  1546.   if (pix_length < old_pix_length)
  1547.     x_clear_display_line_end (vpos);
  1548. }
  1549. #endif /* HAVE_X_WINDOWS */
  1550.  
  1551. int detect_input_pending ();
  1552. int scrolling ();
  1553. unsigned sleep ();        /* int clashes with <unistd.h> */
  1554.  
  1555. /* At the time this function is called, no line is common
  1556.    to SCREEN_PHYS_LINES (screen) and SCREEN_DESIRED_LINES (screen).
  1557.    That is true again when this function returns.
  1558.  
  1559.    force' nonzero means do not stop for pending input
  1560.  
  1561.    value is nonzero if redisplay stopped due to pending input */
  1562.  
  1563. int
  1564. update_screen (s, force, inhibit_hairy_id)
  1565.      SCREEN_PTR s;
  1566.      int force;
  1567.      int inhibit_hairy_id;
  1568. {
  1569.   register struct screen_glyphs *current_screen = SCREEN_CURRENT_GLYPHS (s);
  1570.   register struct screen_glyphs *desired_screen = SCREEN_DESIRED_GLYPHS (s);
  1571.   register int i;
  1572.   int pause;
  1573.   int preempt_count;
  1574.   int input_pending;
  1575.   int cursor_hpos = SCREEN_CURSOR_X (s);
  1576.   int cursor_vpos = SCREEN_CURSOR_Y (s);
  1577. #ifdef HAVE_X_WINDOWS
  1578.   register int downto;
  1579. #endif
  1580.  
  1581.   input_pending = detect_input_pending ();
  1582.   if (input_pending && !force)
  1583.     {
  1584.       memset (desired_screen->enable, 0, SCREEN_HEIGHT (s));
  1585.       pause = 1;
  1586.       goto do_pause;
  1587.     }
  1588.  
  1589.   update_begin (s);
  1590.  
  1591.   if (!line_ins_del_ok)
  1592.     inhibit_hairy_id = 1;
  1593.  
  1594.   /* Don't compute for i/d line if just want cursor motion. */
  1595.   for (i = 0; i < SCREEN_HEIGHT (s); i++)
  1596.     if (desired_screen->enable[i])
  1597.       break;
  1598.  
  1599.   /* Try doing i/d line, if not yet inhibited.  */
  1600.   if (!inhibit_hairy_id && i < SCREEN_HEIGHT (s) && SCREEN_IS_TERMCAP (s))
  1601.     force |= scrolling (s);
  1602.  
  1603. #ifdef HAVE_X_WINDOWS
  1604.   if (SCREEN_IS_X (s))
  1605.     downto = s->display.x->internal_border_width;
  1606. #endif /* HAVE_X_WINDOWS */
  1607.  
  1608.   if (SCREEN_IS_TERMCAP (s))
  1609.     preempt_count = baud_rate / 2400;
  1610.  
  1611.   for (i = 0; i < SCREEN_HEIGHT (s) && (force || !input_pending); i++)
  1612.     {
  1613.       if (desired_screen->enable[i])
  1614.     {
  1615.       if (SCREEN_IS_TERMCAP (s))
  1616.         {
  1617.           /* Flush out every so many lines.
  1618.          Also flush out if likely to have more than 1k buffered
  1619.          otherwise.   I'm told that some telnet connections get
  1620.          really screwed by more than 1k output at once.  */
  1621.           int outq = PENDING_OUTPUT_COUNT (stdout);
  1622.           if (outq > ((--preempt_count < 0) ? 20 : 900))
  1623.         {
  1624.           fflush (stdout);
  1625.           if (baud_rate < 2400)
  1626.             {
  1627. #ifdef TIOCOUTQ
  1628.               if (ioctl (0, TIOCOUTQ, &outq) < 0)
  1629.             /* Probably not a tty.  Ignore the error and reset
  1630.              * the outq count. */
  1631.             outq = PENDING_OUTPUT_COUNT (stdout);
  1632. #endif
  1633.               outq *= 10;
  1634.               outq /= baud_rate; /* outq is now in seconds */
  1635.               if (outq)
  1636.             sleep (outq);
  1637.             }
  1638.           input_pending = detect_input_pending ();
  1639.  
  1640.           preempt_count = baud_rate / 2400;
  1641.         }
  1642.         }
  1643.  
  1644. #ifdef HAVE_X_WINDOWS
  1645.       if (SCREEN_IS_X (s))
  1646.         x_update_line (s, i, downto);
  1647.       else
  1648. #endif
  1649.         update_line (s, i);
  1650.     }
  1651.  
  1652.       if (SCREEN_IS_X (s))
  1653.     downto += s->display.x->text_height;
  1654.     }
  1655.   pause = (i < SCREEN_HEIGHT (s) - 1) ? i : 0;
  1656.  
  1657.   /* Now just clean up termcap drivers and set cursor, etc.  */
  1658.   if (!pause)
  1659.     {
  1660.       if (s == selected_screen && cursor_in_echo_area)
  1661.     {
  1662.       if (cursor_in_echo_area < 0)
  1663.         cursor_to (SCREEN_HEIGHT (s) - 1, 0);
  1664.       else
  1665.         cursor_to (SCREEN_HEIGHT (s) - 1,
  1666.                min (SCREEN_WIDTH (s) - 1,
  1667.                 current_screen->used[SCREEN_HEIGHT (s) - 1]));
  1668.       s->cursor_x = s->phys_cursor_x;
  1669.       s->cursor_y = s->phys_cursor_y;
  1670.     }
  1671.       else
  1672.     cursor_to (cursor_vpos, max (min (cursor_hpos, SCREEN_WIDTH (s) - 1),
  1673.                      0));
  1674.     }
  1675.  
  1676.   memset (desired_screen->enable, 0, SCREEN_HEIGHT (s));
  1677.   update_end (s);
  1678.  
  1679.   if (termscript)
  1680.     fflush (termscript);
  1681.   fflush (stdout);
  1682.  
  1683.   /* Here if output is preempted because input is detected.  */
  1684.  do_pause:
  1685.  
  1686.   if (SCREEN_HEIGHT (s) == 0)
  1687.     /* abort ();   skip this */
  1688.     return 0;
  1689.   display_completed = !pause;
  1690.  
  1691.   return pause;
  1692. }
  1693.  
  1694.  
  1695. /* Decide what insert/delete line to do, and do it */
  1696.  
  1697. extern void scrolling_1 ();
  1698. int scrolling_max_lines_saved ();
  1699.  
  1700. int
  1701. scrolling (screen)
  1702.      SCREEN_PTR screen;
  1703. {
  1704.   int unchanged_at_top, unchanged_at_bottom;
  1705.   int window_size;
  1706.   int changed_lines;
  1707.   int *old_hash = (int *) alloca (SCREEN_HEIGHT (screen) * sizeof (int));
  1708.   int *new_hash = (int *) alloca (SCREEN_HEIGHT (screen) * sizeof (int));
  1709.   int *draw_cost = (int *) alloca (SCREEN_HEIGHT (screen) * sizeof (int));
  1710.   register int i;
  1711.   int free_at_end_vpos = SCREEN_HEIGHT (screen);
  1712.   register struct screen_glyphs *current_screen = SCREEN_CURRENT_GLYPHS (screen);
  1713.   register struct screen_glyphs *desired_screen = SCREEN_DESIRED_GLYPHS (screen);
  1714.  
  1715.   /* Compute hash codes of all the lines.
  1716.      Also calculate number of changed lines,
  1717.      number of unchanged lines at the beginning,
  1718.      and number of unchanged lines at the end.  */
  1719.  
  1720.   changed_lines = 0;
  1721.   unchanged_at_top = 0;
  1722.   unchanged_at_bottom = SCREEN_HEIGHT (screen);
  1723.   for (i = 0; i < SCREEN_HEIGHT (screen); i++)
  1724.     {
  1725.       old_hash[i] = line_hash_code (current_screen, i);
  1726.       if (! desired_screen->enable[i])
  1727.     new_hash[i] = old_hash[i];
  1728.       else
  1729.     new_hash[i] = line_hash_code (desired_screen, i);
  1730.  
  1731.       if (old_hash[i] != new_hash[i])
  1732.     {
  1733.       changed_lines++;
  1734.       unchanged_at_bottom = SCREEN_HEIGHT (screen) - i - 1;
  1735.     }
  1736.       else if (i == unchanged_at_top)
  1737.     unchanged_at_top++;
  1738.       draw_cost[i] = line_draw_cost (desired_screen, i);
  1739.     }
  1740.  
  1741.   /* If changed lines are few, don't allow preemption, don't scroll.  */
  1742.   if (changed_lines < baud_rate / 2400
  1743.       || unchanged_at_bottom == SCREEN_HEIGHT (screen))
  1744.     return 1;
  1745.  
  1746.   window_size = (SCREEN_HEIGHT (screen) - unchanged_at_top
  1747.          - unchanged_at_bottom);
  1748.  
  1749.   if (scroll_region_ok)
  1750.     free_at_end_vpos -= unchanged_at_bottom;
  1751.   else if (memory_below_screen)
  1752.     free_at_end_vpos = -1;
  1753.  
  1754.   /* If large window, fast terminal and few lines in common between
  1755.      current screen and desired screen, don't bother with i/d calc. */
  1756.   if (window_size >= 18 && baud_rate > 2400
  1757.       && (window_size >=
  1758.       10 * scrolling_max_lines_saved (unchanged_at_top,
  1759.                       SCREEN_HEIGHT (screen) - unchanged_at_bottom,
  1760.                       old_hash, new_hash, draw_cost)))
  1761.     return 0;
  1762.  
  1763.   scrolling_1 (screen, window_size, unchanged_at_top, unchanged_at_bottom,
  1764.            draw_cost + unchanged_at_top - 1,
  1765.            old_hash + unchanged_at_top - 1,
  1766.            new_hash + unchanged_at_top - 1,
  1767.            free_at_end_vpos - unchanged_at_top);
  1768.  
  1769.   return 0;
  1770. }
  1771.  
  1772. #ifdef HAVE_X_WINDOWS
  1773.  
  1774. extern int shot_cut_taken_p (SCREEN_PTR s);
  1775. extern void recompute_glyphs_no_short_cut (SCREEN_PTR s);
  1776.  
  1777. int
  1778. pixel_to_glyph_translation (s, pix_x, pix_y, x, y, w, bufp, gly, class,
  1779.                 begin_p)
  1780.      SCREEN_PTR s;
  1781.      register unsigned int pix_x, pix_y;
  1782.      register int *x, *y;
  1783.      struct window** w;
  1784.      int* bufp;
  1785.      int* gly;
  1786.      Lisp_Object* class;
  1787.      int* begin_p;
  1788. {
  1789.   register struct screen_glyphs *current_screen = SCREEN_CURRENT_GLYPHS (s);
  1790.   register int line;
  1791.   int ibw = s->display.x->internal_border_width;
  1792. #ifdef LINE_INFO_COLUMN
  1793.   int licw  = s->display.x->line_info_column_width;
  1794. #endif
  1795.   register XFontStruct *this_font;
  1796.   int tab_width = 8; /* is set to buffer tab_width later */
  1797.   int tab_offset = 0;        /* Wrong, fix this later */
  1798.   int hscroll = 0;        /* Wrong, fix this later */
  1799.   struct buffer *buffer;
  1800.   Lisp_Object ctl_arrow;
  1801.  
  1802.   /* Gross hack to workaround the bug of clicking after point when
  1803.      edits were done. */
  1804.   if (shot_cut_taken_p (s))
  1805.     {
  1806.       /* recompute the desired glyphs */
  1807.       recompute_glyphs_no_short_cut (s);
  1808.       /* use the desired glyphs instead of the current glyphs */
  1809.       current_screen = SCREEN_DESIRED_GLYPHS (s);
  1810.     }
  1811.       
  1812.   *x = 0;
  1813.   *y = 0;
  1814.  
  1815.   *w = 0;
  1816.   *bufp = 0;
  1817.   *gly = Qnil;
  1818.   *class = Qnil;
  1819.   *begin_p = 0;
  1820.  
  1821.   line = (pix_y - ibw) / s->display.x->text_height;
  1822.  
  1823.   if (line < 0 || line >= SCREEN_HEIGHT (s))
  1824.     return 2;
  1825.  
  1826.   *y = line;
  1827.  
  1828.   /* try to set the window to something to start with */
  1829.   if (current_screen->enable[line]
  1830.       && current_screen->face_list[line][0].type == window)
  1831.     {
  1832.       *w = current_screen->face_list[line][0].w;
  1833.       buffer = XBUFFER ((*w)->buffer);
  1834.       tab_width = buffer->tab_width;
  1835.       ctl_arrow = buffer->ctl_arrow;
  1836.     }
  1837.  
  1838.   if (!*w)
  1839.     return 2;
  1840.  
  1841.   /* check if minibuffer window is enabled */
  1842.   if (*w && MINI_WINDOW_P (*w) && !minibuf_level)
  1843.     {
  1844.       *w = 0;
  1845.       return 2;
  1846.     }
  1847.  
  1848.   if (pix_x <= ibw || pix_y <= ibw
  1849.       || pix_y >= s->display.x->pixel_height - ibw
  1850.       || ! current_screen->enable[line])
  1851.     {
  1852.       return 2;
  1853.     }
  1854.  
  1855.   if (pix_x >= current_screen->pix_width[line] + ibw
  1856. #ifdef LINE_INFO_COLUMN
  1857.       + licw
  1858. #endif
  1859.       )
  1860.     {
  1861.       *x = current_screen->used[line];
  1862.       return 2;
  1863.     }
  1864.  
  1865. #ifdef LINE_INFO_COLUMN
  1866.   if (pix_x >= ibw && pix_x <= ibw + licw) {
  1867.     int run = 0;
  1868.     while (current_screen->face_list[line][run].type == window ||
  1869.        current_screen->face_list[line][run].type == column_glyph)
  1870.       run++;
  1871.     if (run != 0 && 
  1872.     current_screen->face_list[line][--run].type == column_glyph) {
  1873.       *class = current_screen->face_list[line][run].class;
  1874.       *begin_p = current_screen->face_list[line][run].begin_p;
  1875.       *gly = current_screen->glyphs[line][run];
  1876.       return 1;
  1877.     }
  1878.     return 2;
  1879.   }
  1880. #endif
  1881.  
  1882.     {
  1883.       register char g;
  1884.       register int this_pix;
  1885.       register int run, glyphs_in_run, glyphs_in_run_limit;
  1886.       int next_bufp, bufcol;
  1887.       int bufpos, minibuf_len;
  1888.  
  1889.       g = 0;
  1890.       run = 0;
  1891.       glyphs_in_run = current_screen->face_list[line][run].length;
  1892.       glyphs_in_run_limit = g + glyphs_in_run;
  1893.       bufpos = current_screen->bufp[line];
  1894.       next_bufp = bufpos;
  1895.       bufcol = 0;
  1896.       if (bufpos < 0)
  1897.     {
  1898.       if (STRINGP (Vminibuf_prompt))
  1899.         minibuf_len = (XSTRING (Vminibuf_prompt)->size);
  1900.       else
  1901.         abort ();
  1902.     }
  1903.       this_pix = current_screen->top_left_x[line];
  1904.       switch (current_screen->face_list[line][run].type)
  1905.     {
  1906.     case font:
  1907.     {
  1908.       int c;
  1909.       int c_width;
  1910.       this_font = current_screen->face_list[line][run].faceptr->font;
  1911.       if (!this_font)
  1912.         this_font = SCREEN_NORMAL_FACE (s).font;
  1913.       c = current_screen->glyphs[line][g];
  1914.       c_width = X_CHAR_WIDTH (this_font, c == TABGLYPH ? ' ' : c);
  1915.       this_pix += c_width;
  1916.       next_bufp = bufpos + 1;
  1917.       bufcol++;
  1918.  
  1919.       c = ((bufpos > 0)
  1920.            ? BUF_CHAR_AT (buffer, bufpos)
  1921.            : XSTRING(Vminibuf_prompt)->data[minibuf_len + bufpos - 1]);
  1922.       if ((c >= 040 && c < 0177) || /* Normal character. */
  1923.           (!NILP (ctl_arrow) &&    /* 8-bit display */
  1924.            !EQ (ctl_arrow, Qt) &&
  1925.            (FIXNUMP (ctl_arrow)
  1926.         ? c >= XINT (ctl_arrow)
  1927.         : c >= 0240)))
  1928.         {
  1929.         }
  1930.       else if (c == '\t')    /* Tab character. */
  1931.         {
  1932.           register int j;
  1933.  
  1934.           j = tab_width - ((((bufcol - 1) + tab_offset + hscroll - (hscroll > 0))
  1935.                 % tab_width)) - 1;
  1936.           g += j;
  1937.           bufcol += j;
  1938.           this_pix += j * X_CHAR_WIDTH (this_font, ' ');
  1939.         }
  1940.       else if (c < 0200 && !NILP (ctl_arrow))
  1941.         {
  1942.           g++;
  1943.           bufcol++;
  1944.           this_pix += X_CHAR_WIDTH (this_font, c ^ 0100);
  1945.         }
  1946.       else
  1947.         {
  1948.           g += 3;
  1949.           bufcol += 3;
  1950.           this_pix += X_CHAR_WIDTH (this_font, ((c >> 6) + '0'));
  1951.           this_pix += X_CHAR_WIDTH (this_font, ((7 & (c >> 3)) + '0'));
  1952.           this_pix += X_CHAR_WIDTH (this_font, ((7 & c) + '0'));
  1953.         }
  1954.       break;
  1955.     }
  1956.       
  1957.     case space:
  1958.       this_pix += current_screen->face_list[line][run].pix_length;
  1959.       /* bufcol++; */ /* Only chars count for tabs */
  1960.       next_bufp = bufpos + 1;
  1961.       break;
  1962.       
  1963.     case glyph:
  1964.       /* bufcol++; */ /* Only chars count for tabs */
  1965.     case column_glyph:
  1966.       this_pix += current_screen->face_list[line][run].pix_length;
  1967.       *class = current_screen->face_list[line][run].class;
  1968.       *begin_p = current_screen->face_list[line][run].begin_p;
  1969.       *gly = current_screen->glyphs[line][g];
  1970.       break;
  1971.       
  1972.     case window:
  1973.       *w = current_screen->face_list[line][run].w;
  1974.       tab_width = XBUFFER((*w)->buffer)->tab_width;
  1975.       next_bufp = current_screen->face_list[line][run].bufp;
  1976.       g--;            /* window runs don't consume glyphs */
  1977.       break;
  1978.       
  1979.     default:
  1980.       abort ();
  1981.     }
  1982.       
  1983.       while (this_pix < pix_x)
  1984.     {
  1985.       *x = (*x) + 1;
  1986.       g++;
  1987.       if (next_bufp > BUF_ZV (buffer))
  1988.         return 2;        /* Something's wrong */
  1989.       bufpos = next_bufp;
  1990.       *class = Qnil;
  1991.       *begin_p = 0;
  1992.       *gly = Qnil;
  1993.       if (g >= glyphs_in_run_limit)
  1994.         {
  1995.           run++;
  1996.           glyphs_in_run = current_screen->face_list[line][run].length;
  1997.           glyphs_in_run_limit = g + glyphs_in_run;
  1998.         }
  1999.       if (current_screen->face_list[line][run].type == font)
  2000.         {
  2001.           this_font
  2002.         = current_screen->face_list[line][run].faceptr->font;
  2003.           if (!this_font)
  2004.         this_font = SCREEN_NORMAL_FACE (s).font;
  2005.         }
  2006.       
  2007.       switch (current_screen->face_list[line][run].type)
  2008.         {
  2009.     case font:
  2010.     {
  2011.       int c;
  2012.       int c_width;
  2013.       this_font = current_screen->face_list[line][run].faceptr->font;
  2014.       if (!this_font)
  2015.         this_font = SCREEN_NORMAL_FACE (s).font;
  2016.       c = current_screen->glyphs[line][g];
  2017.       c_width = X_CHAR_WIDTH (this_font, c == TABGLYPH ? ' ' : c);
  2018.       this_pix += c_width;
  2019.       next_bufp = bufpos + 1;
  2020.       bufcol++;
  2021.  
  2022.       c = ((bufpos > 0)
  2023.            ? BUF_CHAR_AT (buffer, bufpos)
  2024.            : XSTRING(Vminibuf_prompt)->data[minibuf_len + bufpos - 1]);
  2025.       if ((c >= 040 && c < 0177) || /* Normal character. */
  2026.           (!NILP (ctl_arrow) && !EQ (ctl_arrow, Qt)
  2027.            && (FIXNUMP (ctl_arrow)
  2028.            ? c >= XINT (ctl_arrow)
  2029.            : c >= 0240)))
  2030.         {
  2031.         }
  2032.       else if (c == '\t')    /* Tab character. */
  2033.         {
  2034.           register int j;
  2035.  
  2036.           j = tab_width - ((((bufcol - 1) + tab_offset + hscroll - (hscroll > 0))
  2037.                 % tab_width)) - 1;
  2038.           g += j;
  2039.           bufcol += j;
  2040.           this_pix += j * X_CHAR_WIDTH (this_font, ' ');
  2041.         }
  2042.       else if (c < 0200 && !NILP (ctl_arrow))
  2043.         {
  2044.           g++;
  2045.           bufcol++;
  2046.           this_pix += X_CHAR_WIDTH (this_font, c ^ 0100);
  2047.         }
  2048.       else
  2049.         {
  2050.           g += 3;
  2051.           bufcol += 3;
  2052.           this_pix += X_CHAR_WIDTH (this_font, ((c >> 6) + '0'));
  2053.           this_pix += X_CHAR_WIDTH (this_font, ((7 & (c >> 3)) + '0'));
  2054.           this_pix += X_CHAR_WIDTH (this_font, ((7 & c) + '0'));
  2055.         }
  2056.       break;
  2057.     }
  2058.  
  2059.         case glyph:
  2060.           /* bufcol++; */ /* Only chars count for tabs */
  2061.         case column_glyph:
  2062.           this_pix += current_screen->face_list[line][run].pix_length;
  2063.           *class = current_screen->face_list[line][run].class;
  2064.           *begin_p = current_screen->face_list[line][run].begin_p;
  2065.           *gly = current_screen->glyphs[line][g];
  2066.           break;
  2067.           
  2068.         case space:
  2069.           this_pix += current_screen->face_list[line][run].pix_length;
  2070.           next_bufp = bufpos + 1;
  2071.           break;
  2072.           
  2073.         case window:
  2074.           *w = current_screen->face_list[line][run].w;
  2075.           tab_width = XBUFFER((*w)->buffer)->tab_width;
  2076.           next_bufp = current_screen->face_list[line][run].bufp;
  2077.           break;
  2078.           
  2079.         default:
  2080.           break;
  2081.         }
  2082.     }
  2083.       
  2084.       if (bufpos < 0)
  2085.     return 2;
  2086.       *bufp = bufpos;
  2087.       return 1;
  2088.     }
  2089. }
  2090.  
  2091. extern int x_mouse_x, x_mouse_y;
  2092.  
  2093. #endif /* HAVE_X_WINDOWS */
  2094.  
  2095. void report_file_error ();
  2096.  
  2097. DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
  2098.   1, 1, "FOpen termscript file: ",
  2099.   "Start writing all terminal output to FILE as well as the terminal.\n\
  2100. FILE = nil means just close any termscript file currently open.")
  2101.   (file)
  2102.      Lisp_Object file;
  2103. {
  2104.   if (termscript != 0) fclose (termscript);
  2105.   termscript = 0;
  2106.  
  2107.   if (! NILP (file))
  2108.     {
  2109.       file = Fexpand_file_name (file, Qnil);
  2110.       termscript = fopen ((char *)XSTRING (file)->data, "w");
  2111.       if (termscript == 0)
  2112.     report_file_error ("Opening termscript", Fcons (file, Qnil));
  2113.     }
  2114.   return Qnil;
  2115. }
  2116.  
  2117.  
  2118. #ifdef SIGWINCH
  2119. extern int interrupt_input;
  2120.  
  2121. extern void request_sigio (void);
  2122. extern void unrequest_sigio (void);
  2123.  
  2124. void
  2125. window_change_signal ()
  2126. {
  2127.   int width, height;
  2128.   extern int errno;
  2129.   int old_errno = errno;
  2130.   Lisp_Object tail;
  2131.  
  2132.   if (interrupt_input)
  2133.     unrequest_sigio ();
  2134.  
  2135.   get_screen_size (&width, &height);
  2136.  
  2137.   /* The screen size change obviously applies to a termcap-controlled
  2138.      screen.  Find such a screen in the list, and assume it's the only
  2139.      one (since the redisplay code always writes to stdout, not a
  2140.      FILE * specified in the screen structure).  Record the new size,
  2141.      but don't reallocate the data structures now.  Let that be done
  2142.      later outside of the signal handler.  */
  2143.  
  2144.   for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
  2145.     {
  2146.       SCREEN_PTR s = XSCREEN (XCONS (tail)->car);
  2147.     
  2148.       if (SCREEN_IS_TERMCAP (s))
  2149.     {
  2150.       ++in_display;
  2151.       change_screen_size (s, height, width, 0);
  2152.       --in_display;
  2153.       break;
  2154.     }
  2155.     }
  2156.  
  2157.   signal (SIGWINCH, (void (*)(int))window_change_signal);
  2158.   errno = old_errno;
  2159.  
  2160.   if (interrupt_input)
  2161.     request_sigio ();
  2162. }
  2163. #endif /* SIGWINCH */
  2164.  
  2165.  
  2166. /* Change the screen height and/or width.  Values may be given as zero to
  2167.    indicate no change is to take place. */
  2168.  
  2169. extern void calculate_costs (SCREEN_PTR);
  2170.  
  2171. void
  2172. change_screen_size (screen, newlength, newwidth, pretend)
  2173.      register SCREEN_PTR screen;
  2174.      register int newlength, newwidth, pretend;
  2175. {
  2176.   if (in_display)
  2177.     abort ();
  2178.  
  2179.   /* This size-change overrides any pending one for this screen.  */
  2180.   SCREEN_NEW_HEIGHT (screen) = 0;
  2181.   SCREEN_NEW_WIDTH (screen) = 0;
  2182.  
  2183.   if ((newlength == 0 || newlength == SCREEN_HEIGHT (screen))
  2184.       && (newwidth == 0 || newwidth == SCREEN_WIDTH (screen)))
  2185.     return;
  2186.  
  2187.   if (newlength && newlength != SCREEN_HEIGHT (screen))
  2188.     {
  2189.       if (XSCREEN (WINDOW_SCREEN (XWINDOW (SCREEN_MINIBUF_WINDOW (screen))))
  2190.       == screen
  2191.       && ! EQ (SCREEN_MINIBUF_WINDOW (screen),
  2192.            SCREEN_ROOT_WINDOW (screen)))
  2193.     {
  2194.       /* Screen has both root and minibuffer.  */
  2195.       set_window_height (SCREEN_ROOT_WINDOW (screen),
  2196.                  newlength - 1, 0);
  2197.       XFASTINT (XWINDOW (SCREEN_MINIBUF_WINDOW (screen))->top)
  2198.         = newlength - 1;
  2199.       set_window_height (SCREEN_MINIBUF_WINDOW (screen), 1, 0);
  2200.     }
  2201.       else
  2202.     /* Screen has just one top-level window.  */
  2203.     set_window_height (SCREEN_ROOT_WINDOW (screen), newlength, 0);
  2204.     
  2205.       if (SCREEN_IS_TERMCAP (screen) == output_termcap && !pretend)
  2206.     ScreenRows = newlength;
  2207.  
  2208.     }
  2209.  
  2210.   if (newwidth && newwidth != SCREEN_WIDTH (screen))
  2211.     {
  2212.       set_window_width (SCREEN_ROOT_WINDOW (screen), newwidth, 0);
  2213.       if (XSCREEN (WINDOW_SCREEN (XWINDOW (SCREEN_MINIBUF_WINDOW (screen))))
  2214.       == screen)
  2215.     set_window_width (SCREEN_MINIBUF_WINDOW (screen), newwidth, 0);
  2216.       SCREEN_WIDTH (screen) = newwidth;
  2217.  
  2218.       if (SCREEN_IS_TERMCAP (screen) && !pretend)
  2219.     ScreenCols = newwidth;
  2220.     }
  2221.  
  2222.   if (newlength)
  2223.     SCREEN_HEIGHT (screen) = newlength;
  2224.  
  2225.   remake_screen_glyphs (screen);
  2226.   calculate_costs (screen);
  2227. }
  2228.  
  2229. DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
  2230.   Ssend_string_to_terminal, 1, 1, 0,
  2231.   "Send STRING to the terminal without alteration.\n\
  2232. Control characters in STRING will have terminal-dependent effects.")
  2233.   (str)
  2234.      Lisp_Object str;
  2235. {
  2236.   CHECK_STRING (str, 0);
  2237.   fwrite (XSTRING (str)->data, 1, XSTRING (str)->size, stdout);
  2238.   fflush (stdout);
  2239.   if (termscript)
  2240.     {
  2241.       fwrite (XSTRING (str)->data, 1, XSTRING (str)->size, termscript);
  2242.       fflush (termscript);
  2243.     }
  2244.   return Qnil;
  2245. }
  2246.  
  2247. void bitch_at_user ();
  2248.  
  2249. /* Lucid sound change */
  2250. DEFUN ("ding", Fding, Sding, 0, 2, 0,
  2251.   "Beep, or flash the screen.\n\
  2252. Also, unless an argument is given,\n\
  2253. terminate any keyboard macro currently executing.\n\
  2254. When called from lisp, the second argument is what sound to make.")
  2255.   (arg, sound)
  2256.   Lisp_Object arg, sound;
  2257. {
  2258.   if (!NILP (arg))
  2259.     {
  2260.       ring_bell (sound);
  2261.       fflush (stdout);
  2262.     }
  2263.   else
  2264.     bitch_at_user (sound);
  2265.  
  2266.   return Qnil;
  2267. }
  2268.  
  2269. /* Lucid sound change */
  2270. void
  2271. bitch_at_user (sound)
  2272.      Lisp_Object sound;
  2273. {
  2274.   if (noninteractive)
  2275.     putchar (07);
  2276.   else if (!INTERACTIVE)  /* Stop executing a keyboard macro. */
  2277.     error ("Keyboard macro terminated by a command ringing the bell");
  2278.   else
  2279.     ring_bell (sound);
  2280.   fflush (stdout);
  2281. }
  2282.  
  2283.  
  2284. extern void initialize_first_screen (void);
  2285.  
  2286. /* so that .emacs can be loaded after screen is created */
  2287. DEFUN ("initialize-first-screen", Finitialize_first_screen,
  2288.        Sinitialize_first_screen,
  2289.   0, 0, 0, "Make redisplay work on the first screen (do this early.)")
  2290.   ()
  2291. {
  2292.   /* defined in xdisp.c because it needs to use "static void" functions */
  2293.   initialize_first_screen ();
  2294.   return Qnil;
  2295. }
  2296.  
  2297.  
  2298. char *terminal_type;
  2299.  
  2300. /* Initialization done when Emacs fork is started, before doing stty.
  2301.    Determine terminal type and set terminal_driver.
  2302.    Then invoke its decoding routine to set up variables
  2303.    in the terminal package */
  2304.  
  2305. extern int initial_screen_is_tty (void);
  2306. extern void term_init (char *);
  2307.  
  2308. void
  2309. init_display ()
  2310. {
  2311.   meta_key = 0;
  2312.   inverse_video = 0;
  2313.   cursor_in_echo_area = 0;
  2314.   terminal_type = (char *) 0;
  2315.  
  2316.   /* Look at the TERM variable */
  2317.   terminal_type = (char *) getenv ("TERM");
  2318.  
  2319.   if (!terminal_type && initial_screen_is_tty())
  2320.     {
  2321. #ifdef VMS
  2322.       fprintf (stderr, "Please specify your terminal type.\n\
  2323. For types defined in VMS, use  set term /device=TYPE.\n\
  2324. For types not defined in VMS, use  define emacs_term \"TYPE\".\n\
  2325. \(The quotation marks are necessary since terminal types are lower case.)\n");
  2326. #else
  2327.       fprintf (stderr, "Please set the environment variable TERM; see tset(1).\n");
  2328. #endif
  2329.       exit (1);
  2330.     }
  2331.  
  2332. #ifdef VMS
  2333.   /* VMS DCL tends to upcase things, so downcase ter type.
  2334.      Hardly any uppercade letters in terminal types; should be none.  */
  2335.   {
  2336.     char *new = (char *) xmalloc (strlen (terminal_type) + 1);
  2337.     char *p;
  2338.  
  2339.     strcpy (new, terminal_type);
  2340.  
  2341.     for (p = new; *p; p++)
  2342.       if (isupper (*p))
  2343.     *p = tolower (*p);
  2344.  
  2345.     terminal_type = new;
  2346.   }    
  2347. #endif
  2348.  
  2349.   term_init (terminal_type);
  2350.  
  2351. #ifndef MULTI_SCREEN
  2352.   highlight_face.hilited = 1;
  2353.   if (term_does_underline)
  2354.     selection_face.underline = 1;
  2355.   else
  2356.     selection_face.hilited = 1;
  2357. #endif
  2358.  
  2359. #if 0
  2360.   SCREEN_WIDTH (selected_screen) = screen_width;
  2361.   SCREEN_HEIGHT (selected_screen) = screen_height;
  2362. #endif
  2363.  
  2364. #ifdef HAVE_X_WINDOWS
  2365.   if (initial_screen_is_tty ())
  2366. #endif
  2367.     remake_screen_glyphs (selected_screen);
  2368.  
  2369.   /* X and Y coordiates of the cursor between updates. */
  2370.   SCREEN_CURSOR_X (selected_screen) = 0;
  2371.   SCREEN_CURSOR_Y (selected_screen) = 0;
  2372.  
  2373. #ifdef HAVE_X_WINDOWS
  2374.   if (!initial_screen_is_tty ())
  2375.     {
  2376.       Vwindow_system = intern ("x");
  2377.       Vwindow_system_version = make_number (11);
  2378.  
  2379.       /* Don't handle SIGWINCH if using X.  */
  2380.       return;
  2381.     }
  2382. #endif /* HAVE_X_WINDOWS */
  2383.  
  2384. #ifdef SIGWINCH
  2385. #ifndef CANNOT_DUMP
  2386.   if (initialized)
  2387. #endif /* CANNOT_DUMP */
  2388.     signal (SIGWINCH, (void (*)(int))window_change_signal);
  2389. #endif /* SIGWINCH */
  2390. }
  2391.  
  2392. void
  2393. syms_of_display ()
  2394. {
  2395.   defsubr (&Sopen_termscript);
  2396.   defsubr (&Sding);
  2397.   defsubr (&Ssend_string_to_terminal);
  2398.   defsubr (&Sinitialize_first_screen);
  2399.  
  2400.   DEFVAR_INT ("baud-rate", &baud_rate,
  2401.     "The output baud rate of the terminal.\n\
  2402. On most systems, changing this value will affect the amount of padding\n\
  2403. and the other strategic decisions made during redisplay.");
  2404.   DEFVAR_BOOL ("inverse-video", &inverse_video,
  2405.     "*Non-nil means invert the entire screen display.\n\
  2406. This means everything is in inverse video which otherwise would not be.");
  2407.   DEFVAR_BOOL ("visible-bell", &visible_bell,
  2408.     "*Non-nil means try to flash the screen to represent a bell.");
  2409.   DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter,
  2410.     "*Non-nil means no need to redraw entire screen after suspending.\n\
  2411. A non-nil value is useful if the terminal can automatically preserve\n\
  2412. Emacs's screen display when you reenter Emacs.\n\
  2413. It is up to you to set this variable if your terminal can do that.");
  2414.   DEFVAR_LISP ("window-system", &Vwindow_system,
  2415.     "A symbol naming the window-system under which Emacs is running,\n\
  2416. such as `x', or nil if emacs is running on an ordinary terminal.");
  2417.   DEFVAR_LISP ("window-system-version", &Vwindow_system_version,
  2418.     "The version number of the window system in use.\n\
  2419. For X windows, this is 10 or 11.");
  2420.   Vwindow_system_version = Qnil;
  2421.   DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area,
  2422.     "Non-nil means put cursor in minibuffer, at end of any message there.");
  2423.   Qcursor_in_echo_area = intern ("cursor-in-echo-area");
  2424.   staticpro (&Qcursor_in_echo_area);
  2425.  
  2426. #if 0 /* this isn't implemented yet, so there's no point in telling the user */
  2427.   DEFVAR_LISP ("glyph-table", &Vglyph_table,
  2428.     "Table defining how to output a glyph code to the screen.\n\
  2429. If not nil, this is a vector indexed by glyph code to define the glyph.\n\
  2430. Each element can be:\n\
  2431.  integer: a glyph code which this glyph is an alias for.\n\
  2432.  string: output this glyph using that string (not impl. in X windows).\n\
  2433.  nil: this glyph mod 256 is char code to output,\n\
  2434.     and this glyph / 256 is face code for X windows (see `x-set-face').");
  2435. #endif
  2436.   Vglyph_table = Qnil;
  2437.  
  2438.   DEFVAR_LISP ("standard-display-table", &Vstandard_display_table,
  2439.     "Display table to use for buffers that specify none.\n\
  2440. See `buffer-display-table' for more information.");
  2441.   Vstandard_display_table = Qnil;
  2442.  
  2443.   /* Initialize `window-system', unless init_display already decided it.  */
  2444. #ifdef CANNOT_DUMP
  2445.   if (noninteractive)
  2446. #endif
  2447.     Vwindow_system = Qnil;
  2448. }
  2449.