home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / e20313sr.zip / emacs / 20.3.1 / src / dispnew.c < prev    next >
C/C++ Source or Header  |  1999-07-31  |  82KB  |  2,728 lines

  1. /* Updating of data structures for redisplay.
  2.    Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 1998
  3.        Free Software Foundation, Inc.
  4.  
  5. This file is part of GNU Emacs.
  6.  
  7. GNU Emacs is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2, or (at your option)
  10. any later version.
  11.  
  12. GNU Emacs is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GNU Emacs; see the file COPYING.  If not, write to
  19. the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20. Boston, MA 02111-1307, USA.  */
  21.  
  22. /* Modified for emx by Jeremy Bowen, May 1999 based on patches
  23.    to v19.33 by Eberhard Mattes */
  24.  
  25. #include <signal.h>
  26.  
  27. #include <config.h>
  28.  
  29. #include <stdio.h>
  30. #include <ctype.h>
  31.  
  32. #ifdef HAVE_UNISTD_H
  33. #include <unistd.h>
  34. #endif
  35.  
  36. #include "lisp.h"
  37. #include "termchar.h"
  38. #include "termopts.h"
  39. #include "termhooks.h"
  40. /* cm.h must come after dispextern.h on Windows.  */
  41. #include "dispextern.h"
  42. #include "cm.h"
  43. #include "buffer.h"
  44. #include "charset.h"
  45. #include "frame.h"
  46. #include "window.h"
  47. #include "commands.h"
  48. #include "disptab.h"
  49. #include "indent.h"
  50. #include "intervals.h"
  51. #include "blockinput.h"
  52. #include "process.h"
  53. #include "keyboard.h"
  54.  
  55. /* I don't know why DEC Alpha OSF1 fail to compile this file if we
  56.    include the following file.  */
  57. /* #include "systty.h" */
  58. #include "syssignal.h"
  59.  
  60. #ifdef HAVE_X_WINDOWS
  61. #ifndef HAVE_PM
  62. #include "xterm.h"
  63. #else /* HAVE_PM */
  64. #include "pmterm.h"
  65. #endif /* HAVE_PM */
  66. #endif    /* HAVE_X_WINDOWS */
  67.  
  68. #ifdef EMX
  69. extern void emx_resize_vio (int *pheight, int *pwidth);
  70. #endif /* EMX */
  71.  
  72. #ifdef HAVE_NTGUI
  73. #include "w32term.h"
  74. #endif /* HAVE_NTGUI */
  75.  
  76. /* Include systime.h after xterm.h to avoid double inclusion of time.h. */
  77. #include "systime.h"
  78.  
  79. #include <errno.h>
  80.  
  81. #define max(a, b) ((a) > (b) ? (a) : (b))
  82. #define min(a, b) ((a) < (b) ? (a) : (b))
  83. #define minmax(floor, val, ceil) \
  84.     ((val) < (floor) ? (floor) : (val) > (ceil) ? (ceil) : (val))
  85.  
  86. /* Get number of chars of output now in the buffer of a stdio stream.
  87.    This ought to be built in in stdio, but it isn't.
  88.    Some s- files override this because their stdio internals differ.  */
  89. #ifdef __GNU_LIBRARY__
  90. /* The s- file might have overridden the definition with one that works for
  91.    the system's C library.  But we are using the GNU C library, so this is
  92.    the right definition for every system.  */
  93. #ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT
  94. #define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT
  95. #else
  96. #undef    PENDING_OUTPUT_COUNT
  97. #define    PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
  98. #endif
  99. #else /* not __GNU_LIBRARY__ */
  100. #ifndef PENDING_OUTPUT_COUNT
  101. #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
  102. #endif
  103. #endif
  104.  
  105. static void change_frame_size_1 ();
  106.  
  107. /* Nonzero upon entry to redisplay means do not assume anything about
  108.    current contents of actual terminal frame; clear and redraw it.  */
  109.  
  110. int frame_garbaged;
  111.  
  112. /* Nonzero means last display completed.  Zero means it was preempted. */
  113. int display_completed;
  114.  
  115. /* Lisp variable visible-bell; enables use of screen-flash
  116.    instead of audible bell.  */
  117. int visible_bell;
  118.  
  119. /* Invert the color of the whole frame, at a low level.  */
  120. int inverse_video;
  121.  
  122. /* Line speed of the terminal.  */
  123. int baud_rate;
  124.  
  125. /* Minimum length of a run of matching characters to be skipped in output. */
  126. int min_skip_run = 1;
  127.  
  128. /* nil or a symbol naming the window system under which emacs is
  129.    running ('x is the only current possibility).  */
  130. Lisp_Object Vwindow_system;
  131.  
  132. /* Version number of X windows: 10, 11 or nil.  */
  133. Lisp_Object Vwindow_system_version;
  134.  
  135. /* Vector of glyph definitions.  Indexed by glyph number,
  136.    the contents are a string which is how to output the glyph.
  137.  
  138.    If Vglyph_table is nil, a glyph is output by using its low 8 bits
  139.    as a character code.  */
  140. Lisp_Object Vglyph_table;
  141.  
  142. /* Display table to use for vectors that don't specify their own.  */
  143. Lisp_Object Vstandard_display_table;
  144.  
  145. /* Nonzero means reading single-character input with prompt
  146.    so put cursor on minibuffer after the prompt.
  147.    positive means at end of text in echo area;
  148.    negative means at beginning of line.  */
  149. int cursor_in_echo_area;
  150.  
  151. Lisp_Object Qdisplay_table;
  152.  
  153. /* The currently selected frame.
  154.    In a single-frame version, this variable always holds the address of
  155.    the_only_frame.  */
  156. FRAME_PTR selected_frame;
  157.  
  158. /* A frame which is not just a minibuffer, or 0 if there are no such
  159.    frames.  This is usually the most recent such frame that was
  160.    selected.  In a single-frame version, this variable always holds
  161.    the address of the_only_frame.  */
  162. FRAME_PTR last_nonminibuf_frame;
  163.  
  164. /* This is a vector, made larger whenever it isn't large enough,
  165.    which is used inside `update_frame' to hold the old contents
  166.    of the FRAME_PHYS_LINES of the frame being updated.  */
  167. struct frame_glyphs **ophys_lines;
  168. /* Length of vector currently allocated.  */
  169. int ophys_lines_length;
  170.  
  171. FILE *termscript;    /* Stdio stream being used for copy of all output.  */
  172.  
  173. struct cm Wcm;        /* Structure for info on cursor positioning */
  174.  
  175. int delayed_size_change;  /* 1 means SIGWINCH happened when not safe.  */
  176.  
  177. DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
  178.   "Clear frame FRAME and output again what is supposed to appear on it.")
  179.   (frame)
  180.      Lisp_Object frame;
  181. {
  182.   FRAME_PTR f;
  183.  
  184.   CHECK_LIVE_FRAME (frame, 0);
  185.   f = XFRAME (frame);
  186.  
  187.   /* Erase the frame and its glyph records--if it has any records.
  188.      It may have none, in the case of the terminal frame
  189.      that initially exists but is never used
  190.      when Emacs is using a window system.  */
  191.   if (FRAME_CURRENT_GLYPHS (f) != 0)
  192.     {
  193.       update_begin (f);
  194.       if (FRAME_MSDOS_P (f))
  195.     set_terminal_modes ();
  196.       clear_frame ();
  197.       clear_frame_records (f);
  198.       update_end (f);
  199.       fflush (stdout);
  200.     }
  201.  
  202.   windows_or_buffers_changed++;
  203.   /* Mark all windows as INaccurate,
  204.      so that every window will have its redisplay done.  */
  205.   mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
  206.   f->garbaged = 0;
  207.   return Qnil;
  208. }
  209.  
  210. void
  211. redraw_frame (f)
  212.      FRAME_PTR f;
  213. {
  214.   Lisp_Object frame;
  215.   XSETFRAME (frame, f);
  216.   Fredraw_frame (frame);
  217. }
  218.  
  219. DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
  220.   "Clear and redisplay all visible frames.")
  221.   ()
  222. {
  223.   Lisp_Object tail, frame;
  224.  
  225.   FOR_EACH_FRAME (tail, frame)
  226.     if (FRAME_VISIBLE_P (XFRAME (frame)))
  227.       Fredraw_frame (frame);
  228.  
  229.   return Qnil;
  230. }
  231.  
  232. /* This is used when frame_garbaged is set.
  233.    Redraw the individual frames marked as garbaged.  */
  234.  
  235. void
  236. redraw_garbaged_frames ()
  237. {
  238.   Lisp_Object tail, frame;
  239.  
  240.   FOR_EACH_FRAME (tail, frame)
  241.     if (FRAME_VISIBLE_P (XFRAME (frame))
  242.     && FRAME_GARBAGED_P (XFRAME (frame)))
  243.       Fredraw_frame (frame);
  244. }
  245.  
  246.  
  247. static struct frame_glyphs *
  248. make_frame_glyphs (frame, empty)
  249.      register FRAME_PTR frame;
  250.      int empty;
  251. {
  252.   register int i;
  253.   register int width = FRAME_WINDOW_WIDTH (frame);
  254.   register int height = FRAME_HEIGHT (frame);
  255.   register struct frame_glyphs *new
  256.     = (struct frame_glyphs *) xmalloc (sizeof (struct frame_glyphs));
  257.  
  258.   SET_GLYPHS_FRAME (new, frame);
  259.   new->height = height;
  260.   new->width = width;
  261.   new->used = (int *) xmalloc (height * sizeof (int));
  262.   new->glyphs = (GLYPH **) xmalloc (height * sizeof (GLYPH *));
  263.   new->charstarts = (int **) xmalloc (height * sizeof (int *));
  264.   new->highlight = (char *) xmalloc (height * sizeof (char));
  265.   new->enable = (char *) xmalloc (height * sizeof (char));
  266.   bzero (new->enable, height * sizeof (char));
  267.   new->bufp = (int *) xmalloc (height * sizeof (int));
  268.  
  269. #ifdef HAVE_WINDOW_SYSTEM
  270.   if (FRAME_WINDOW_P (frame))
  271.     {
  272.       new->top_left_x = (short *) xmalloc (height * sizeof (short));
  273.       new->top_left_y = (short *) xmalloc (height * sizeof (short));
  274.       new->pix_width = (short *) xmalloc (height * sizeof (short));
  275.       new->pix_height = (short *) xmalloc (height * sizeof (short));
  276.       new->max_ascent = (short *) xmalloc (height * sizeof (short));
  277.     }
  278. #endif /* HAVE_WINDOW_SYSTEM */
  279.  
  280.   if (empty)
  281.     {
  282.       /* Make the buffer used by decode_mode_spec.  This buffer is also
  283.          used as temporary storage when updating the frame.  See scroll.c. */
  284.       unsigned int total_glyphs = (width + 2) * sizeof (GLYPH);
  285.       unsigned int total_charstarts = (width + 2) * sizeof (int);
  286.  
  287.       new->total_contents = (GLYPH *) xmalloc (total_glyphs);
  288.       bzero (new->total_contents, total_glyphs);
  289.  
  290.       new->total_charstarts = (int *) xmalloc (total_charstarts);
  291.       bzero (new->total_charstarts, total_charstarts);
  292.     }
  293.   else
  294.     {
  295.       unsigned int total_glyphs = height * (width + 2) * sizeof (GLYPH);
  296.  
  297.       new->total_contents = (GLYPH *) xmalloc (total_glyphs);
  298.       bzero (new->total_contents, total_glyphs);
  299.       for (i = 0; i < height; i++)
  300.     new->glyphs[i] = new->total_contents + i * (width + 2) + 1;
  301.  
  302.       if (!FRAME_TERMCAP_P (frame))
  303.     {
  304.       unsigned int total_charstarts = height * (width + 2) * sizeof (int);
  305.  
  306.       new->total_charstarts = (int *) xmalloc (total_charstarts);
  307.       bzero (new->total_charstarts, total_charstarts);
  308.       for (i = 0; i < height; i++)
  309.         new->charstarts[i] = new->total_charstarts + i * (width + 2) + 1;
  310.     }
  311.       else
  312.     {
  313.       /* Without a window system, we don't really need charstarts.
  314.          So use a small amount of space to make enough data structure
  315.          to prevent crashes in display_text_line.  */
  316.       new->total_charstarts = (int *) xmalloc ((width + 2) * sizeof (int));
  317.       for (i = 0; i < height; i++)
  318.         new->charstarts[i] = new->total_charstarts;
  319.     }
  320.     }
  321.  
  322.   return new;
  323. }
  324.  
  325. void
  326. free_frame_glyphs (frame, glyphs)
  327.      FRAME_PTR frame;
  328.      struct frame_glyphs *glyphs;
  329. {
  330.   if (glyphs->total_contents)
  331.     xfree (glyphs->total_contents);
  332.   if (glyphs->total_charstarts)
  333.     xfree (glyphs->total_charstarts);
  334.  
  335.   xfree (glyphs->used);
  336.   xfree (glyphs->glyphs);
  337.   xfree (glyphs->highlight);
  338.   xfree (glyphs->enable);
  339.   xfree (glyphs->bufp);
  340.   if (glyphs->charstarts)
  341.     xfree (glyphs->charstarts);
  342.  
  343. #ifdef HAVE_WINDOW_SYSTEM
  344.   if (FRAME_WINDOW_P (frame))
  345.     {
  346.       xfree (glyphs->top_left_x);
  347.       xfree (glyphs->top_left_y);
  348.       xfree (glyphs->pix_width);
  349.       xfree (glyphs->pix_height);
  350.       xfree (glyphs->max_ascent);
  351.     }
  352. #endif /* HAVE_WINDOW_SYSTEM */
  353.  
  354.   xfree (glyphs);
  355. }
  356.  
  357. void
  358. remake_frame_glyphs (frame)
  359.      FRAME_PTR frame;
  360. {
  361.   if (FRAME_CURRENT_GLYPHS (frame))
  362.     free_frame_glyphs (frame, FRAME_CURRENT_GLYPHS (frame));
  363.   if (FRAME_DESIRED_GLYPHS (frame))
  364.     free_frame_glyphs (frame, FRAME_DESIRED_GLYPHS (frame));
  365.   if (FRAME_TEMP_GLYPHS (frame))
  366.     free_frame_glyphs (frame, FRAME_TEMP_GLYPHS (frame));
  367.  
  368.   if (FRAME_MESSAGE_BUF (frame))
  369.     {
  370.       /* Reallocate the frame's message buffer; remember that
  371.      echo_area_glyphs may be pointing here.  */
  372.       char *old_message_buf = FRAME_MESSAGE_BUF (frame);
  373.  
  374.       FRAME_MESSAGE_BUF (frame)
  375.     = (char *) xrealloc (FRAME_MESSAGE_BUF (frame),
  376.                  FRAME_MESSAGE_BUF_SIZE (frame) + 1);
  377.  
  378.       if (echo_area_glyphs == old_message_buf)
  379.     echo_area_glyphs = FRAME_MESSAGE_BUF (frame);
  380.       if (previous_echo_glyphs == old_message_buf)
  381.     previous_echo_glyphs = FRAME_MESSAGE_BUF (frame);
  382.     }
  383.   else
  384.     FRAME_MESSAGE_BUF (frame)
  385.       = (char *) xmalloc (FRAME_MESSAGE_BUF_SIZE (frame) + 1);
  386.  
  387.   FRAME_CURRENT_GLYPHS (frame) = make_frame_glyphs (frame, 0);
  388.   FRAME_DESIRED_GLYPHS (frame) = make_frame_glyphs (frame, 0);
  389.   FRAME_TEMP_GLYPHS (frame) = make_frame_glyphs (frame, 1);
  390.   if (FRAME_WINDOW_P (frame) || frame == selected_frame)
  391.     SET_FRAME_GARBAGED (frame);
  392. }
  393.  
  394. /* Return the hash code of contents of line VPOS in frame-matrix M.  */
  395.  
  396. static int
  397. line_hash_code (m, vpos)
  398.      register struct frame_glyphs *m;
  399.      int vpos;
  400. {
  401.   register GLYPH *body, *end;
  402.   register int h = 0;
  403.  
  404.   if (!m->enable[vpos])
  405.     return 0;
  406.  
  407.   /* Give all highlighted lines the same hash code
  408.      so as to encourage scrolling to leave them in place.  */
  409.   if (m->highlight[vpos])
  410.     return -1;
  411.  
  412.   body = m->glyphs[vpos];
  413.  
  414.   if (must_write_spaces)
  415.     while (1)
  416.       {
  417.     GLYPH g = *body++;
  418.  
  419.     if (g == 0)
  420.       break;
  421.     h = (((h << 4) + (h >> 24)) & 0x0fffffff) + g - SPACEGLYPH;
  422.       }
  423.   else
  424.     while (1)
  425.       {
  426.     GLYPH g = *body++;
  427.  
  428.     if (g == 0)
  429.       break;
  430.     h = (((h << 4) + (h >> 24)) & 0x0fffffff) + g;
  431.       }
  432.  
  433.   if (h)
  434.     return h;
  435.   return 1;
  436. }
  437.  
  438. /* Return number of characters in line in M at vpos VPOS,
  439.    except don't count leading and trailing spaces
  440.    unless the terminal requires those to be explicitly output.  */
  441.  
  442. static unsigned int
  443. line_draw_cost (m, vpos)
  444.      struct frame_glyphs *m;
  445.      int vpos;
  446. {
  447.   register GLYPH *beg = m->glyphs[vpos];
  448.   register GLYPH *end = m->glyphs[vpos] + m->used[vpos];
  449.   register int i;
  450.   register int tlen = GLYPH_TABLE_LENGTH;
  451.   register Lisp_Object *tbase = GLYPH_TABLE_BASE;
  452.  
  453.   /* Ignore trailing and leading spaces if we can.  */
  454.   if (!must_write_spaces)
  455.     {
  456.       while ((end != beg) && (*end == SPACEGLYPH))
  457.     --end;
  458.       if (end == beg)
  459.     return (0); /* All blank line. */
  460.  
  461.       while (*beg == SPACEGLYPH)
  462.     ++beg;
  463.     }
  464.  
  465.   /* If we don't have a glyph-table, each glyph is one character,
  466.      so return the number of glyphs.  */
  467.   if (tbase == 0)
  468.     return end - beg;
  469.  
  470.   /* Otherwise, scan the glyphs and accumulate their total size in I.  */
  471.   i = 0;
  472.   while ((beg <= end) && *beg)
  473.     {
  474.       register GLYPH g = *beg++;
  475.  
  476.       if (GLYPH_SIMPLE_P (tbase, tlen, g))
  477.     i += 1;
  478.       else
  479.     i += GLYPH_LENGTH (tbase, g);
  480.     }
  481.   return i;
  482. }
  483.  
  484. /* The functions on this page are the interface from xdisp.c to redisplay.
  485.  
  486.    The only other interface into redisplay is through setting
  487.    FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame)
  488.    and SET_FRAME_GARBAGED (frame).  */
  489.  
  490. /* cancel_line eliminates any request to display a line at position `vpos' */
  491.  
  492. void
  493. cancel_line (vpos, frame)
  494.      int vpos;
  495.      register FRAME_PTR frame;
  496. {
  497.   FRAME_DESIRED_GLYPHS (frame)->enable[vpos] = 0;
  498. }
  499.  
  500. void
  501. clear_frame_records (frame)
  502.      register FRAME_PTR frame;
  503. {
  504.   bzero (FRAME_CURRENT_GLYPHS (frame)->enable, FRAME_HEIGHT (frame));
  505. }
  506.  
  507. /* Clear out all display lines for a coming redisplay.  */
  508.  
  509. void
  510. init_desired_glyphs (frame)
  511.      register FRAME_PTR frame;
  512. {
  513.   register struct frame_glyphs *desired_glyphs = FRAME_DESIRED_GLYPHS (frame);
  514.   int vpos;
  515.   int height = FRAME_HEIGHT (frame);
  516.  
  517.   for (vpos = 0; vpos < height; vpos++)
  518.     desired_glyphs->enable[vpos] = 0;
  519. }
  520.  
  521. /* Prepare to display on line VPOS starting at HPOS within it.  */
  522.  
  523. void
  524. get_display_line (frame, vpos, hpos)
  525.      register FRAME_PTR frame;
  526.      int vpos;
  527.      register int hpos;
  528. {
  529.   register struct frame_glyphs *glyphs;
  530.   register struct frame_glyphs *desired_glyphs = FRAME_DESIRED_GLYPHS (frame);
  531.   register GLYPH *p;
  532.  
  533.   if (vpos < 0)
  534.     abort ();
  535.  
  536.   if (! desired_glyphs->enable[vpos])
  537.     {
  538.       desired_glyphs->used[vpos] = 0;
  539.       desired_glyphs->highlight[vpos] = 0;
  540.       desired_glyphs->enable[vpos] = 1;
  541.     }
  542.  
  543.   if (hpos > desired_glyphs->used[vpos])
  544.     {
  545.       GLYPH *g = desired_glyphs->glyphs[vpos] + desired_glyphs->used[vpos];
  546.       GLYPH *end = desired_glyphs->glyphs[vpos] + hpos;
  547.  
  548.       desired_glyphs->used[vpos] = hpos;
  549.       while (g != end)
  550.     *g++ = SPACEGLYPH;
  551.     }
  552. }
  553.  
  554. /* Like bcopy except never gets confused by overlap.  */
  555.  
  556. #ifdef EMX
  557. void
  558. safe_bcopy (from, to, size)
  559.      char *from, *to;
  560.      int size;
  561. {
  562.   bcopy (from, to, size);
  563. }
  564. #else /* not EMX */
  565. void
  566. safe_bcopy (from, to, size)
  567.      char *from, *to;
  568.      int size;
  569. {
  570.   if (size <= 0 || from == to)
  571.     return;
  572.  
  573.   /* If the source and destination don't overlap, then bcopy can
  574.      handle it.  If they do overlap, but the destination is lower in
  575.      memory than the source, we'll assume bcopy can handle that.  */
  576.   if (to < from || from + size <= to)
  577.     bcopy (from, to, size);
  578.  
  579.   /* Otherwise, we'll copy from the end.  */
  580.   else
  581.     {
  582.       register char *endf = from + size;
  583.       register char *endt = to + size;
  584.  
  585.       /* If TO - FROM is large, then we should break the copy into
  586.      nonoverlapping chunks of TO - FROM bytes each.  However, if
  587.      TO - FROM is small, then the bcopy function call overhead
  588.      makes this not worth it.  The crossover point could be about
  589.      anywhere.  Since I don't think the obvious copy loop is too
  590.      bad, I'm trying to err in its favor.  */
  591.       if (to - from < 64)
  592.     {
  593.       do
  594.         *--endt = *--endf;
  595.       while (endf != from);
  596.     }
  597.       else
  598.     {
  599.       for (;;)
  600.         {
  601.           endt -= (to - from);
  602.           endf -= (to - from);
  603.  
  604.           if (endt < to)
  605.         break;
  606.  
  607.           bcopy (endf, endt, to - from);
  608.         }
  609.  
  610.       /* If SIZE wasn't a multiple of TO - FROM, there will be a
  611.          little left over.  The amount left over is
  612.          (endt + (to - from)) - to, which is endt - from.  */
  613.       bcopy (from, to, endt - from);
  614.     }
  615.     }
  616. }     
  617. #endif /* not EMX */
  618.  
  619. /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
  620.    DISTANCE may be negative.  */
  621.  
  622. static void
  623. rotate_vector (vector, size, distance)
  624.      char *vector;
  625.      int size;
  626.      int distance;
  627. {
  628.   char *temp = (char *) alloca (size);
  629.  
  630.   if (distance < 0)
  631.     distance += size;
  632.  
  633.   bcopy (vector, temp + distance, size - distance);
  634.   bcopy (vector + size - distance, temp, distance);
  635.   bcopy (temp, vector, size);
  636. }
  637.  
  638. /* Scroll lines from vpos FROM up to but not including vpos END
  639.    down by AMOUNT lines (AMOUNT may be negative).
  640.    Returns nonzero if done, zero if terminal cannot scroll them.  */
  641.  
  642. int
  643. scroll_frame_lines (frame, from, end, amount, newpos)
  644.      register FRAME_PTR frame;
  645.      int from, end, amount, newpos;
  646. {
  647.   register int i;
  648.   register struct frame_glyphs *current_frame
  649.     = FRAME_CURRENT_GLYPHS (frame);
  650.   int pos_adjust;
  651.   int width = FRAME_WINDOW_WIDTH (frame);
  652.  
  653.   if (!line_ins_del_ok)
  654.     return 0;
  655.  
  656.   if (amount == 0)
  657.     return 1;
  658.  
  659.   if (amount > 0)
  660.     {
  661.       update_begin (frame);
  662.       set_terminal_window (end + amount);
  663.       if (!scroll_region_ok)
  664.     ins_del_lines (end, -amount);
  665.       ins_del_lines (from, amount);
  666.       set_terminal_window (0);
  667.  
  668.       rotate_vector (current_frame->glyphs + from,
  669.              sizeof (GLYPH *) * (end + amount - from),
  670.              amount * sizeof (GLYPH *));
  671.  
  672.       rotate_vector (current_frame->charstarts + from,
  673.              sizeof (int *) * (end + amount - from),
  674.              amount * sizeof (int *));
  675.  
  676.       safe_bcopy (current_frame->used + from,
  677.           current_frame->used + from + amount,
  678.           (end - from) * sizeof current_frame->used[0]);
  679.  
  680.       safe_bcopy (current_frame->highlight + from,
  681.           current_frame->highlight + from + amount,
  682.           (end - from) * sizeof current_frame->highlight[0]);
  683.  
  684.       safe_bcopy (current_frame->enable + from,
  685.           current_frame->enable + from + amount,
  686.           (end - from) * sizeof current_frame->enable[0]);
  687.  
  688.       /* Adjust the lines by an amount
  689.      that puts the first of them at NEWPOS.  */
  690.       pos_adjust = newpos - current_frame->charstarts[from + amount][0];
  691.  
  692.       /* Offset each char position in the charstarts lines we moved
  693.      by pos_adjust.  */
  694.       for (i = from + amount; i < end + amount; i++)
  695.     {
  696.       int *line = current_frame->charstarts[i];
  697.       int col;
  698.       for (col = 0; col < width; col++)
  699.         if (line[col] > 0)
  700.           line[col] += pos_adjust;
  701.     }
  702.       for (i = from; i < from + amount; i++)
  703.     {
  704.       int *line = current_frame->charstarts[i];
  705.       int col;
  706.       line[0] = -1;
  707.       for (col = 0; col < width; col++)
  708.         line[col] = 0;
  709.     }
  710.  
  711.       /* Mark the lines made empty by scrolling as enabled, empty and
  712.      normal video.  */
  713.       bzero (current_frame->used + from,
  714.          amount * sizeof current_frame->used[0]);
  715.       bzero (current_frame->highlight + from,
  716.          amount * sizeof current_frame->highlight[0]);
  717.       for (i = from; i < from + amount; i++)
  718.     {
  719.       current_frame->glyphs[i][0] = '\0';
  720.       current_frame->charstarts[i][0] = -1;
  721.       current_frame->enable[i] = 1;
  722.     }
  723.  
  724.       safe_bcopy (current_frame->bufp + from,
  725.           current_frame->bufp + from + amount,
  726.           (end - from) * sizeof current_frame->bufp[0]);
  727.  
  728. #ifdef HAVE_WINDOW_SYSTEM
  729.       if (FRAME_WINDOW_P (frame))
  730.     {
  731.       safe_bcopy (current_frame->top_left_x + from,
  732.               current_frame->top_left_x + from + amount,
  733.               (end - from) * sizeof current_frame->top_left_x[0]);
  734.  
  735.       safe_bcopy (current_frame->top_left_y + from,
  736.               current_frame->top_left_y + from + amount,
  737.               (end - from) * sizeof current_frame->top_left_y[0]);
  738.  
  739.       safe_bcopy (current_frame->pix_width + from,
  740.               current_frame->pix_width + from + amount,
  741.               (end - from) * sizeof current_frame->pix_width[0]);
  742.  
  743.       safe_bcopy (current_frame->pix_height + from,
  744.               current_frame->pix_height + from + amount,
  745.               (end - from) * sizeof current_frame->pix_height[0]);
  746.  
  747.       safe_bcopy (current_frame->max_ascent + from,
  748.               current_frame->max_ascent + from + amount,
  749.               (end - from) * sizeof current_frame->max_ascent[0]);
  750.     }
  751. #endif /* HAVE_WINDOW_SYSTEM */
  752.  
  753.       update_end (frame);
  754.     }
  755.   if (amount < 0)
  756.     {
  757.       update_begin (frame);
  758.       set_terminal_window (end);
  759.       ins_del_lines (from + amount, amount);
  760.       if (!scroll_region_ok)
  761.     ins_del_lines (end + amount, -amount);
  762.       set_terminal_window (0);
  763.  
  764.       rotate_vector (current_frame->glyphs + from + amount,
  765.              sizeof (GLYPH *) * (end - from - amount),
  766.              amount * sizeof (GLYPH *));
  767.  
  768.       rotate_vector (current_frame->charstarts + from + amount,
  769.              sizeof (int *) * (end - from - amount),
  770.              amount * sizeof (int *));
  771.  
  772.       safe_bcopy (current_frame->used + from,
  773.           current_frame->used + from + amount,
  774.           (end - from) * sizeof current_frame->used[0]);
  775.  
  776.       safe_bcopy (current_frame->highlight + from,
  777.           current_frame->highlight + from + amount,
  778.           (end - from) * sizeof current_frame->highlight[0]);
  779.  
  780.       safe_bcopy (current_frame->enable + from,
  781.           current_frame->enable + from + amount,
  782.           (end - from) * sizeof current_frame->enable[0]);
  783.  
  784.       /* Adjust the lines by an amount
  785.      that puts the first of them at NEWPOS.  */
  786.       pos_adjust = newpos - current_frame->charstarts[from + amount][0];
  787.  
  788.       /* Offset each char position in the charstarts lines we moved
  789.      by pos_adjust.  */
  790.       for (i = from + amount; i < end + amount; i++)
  791.     {
  792.       int *line = current_frame->charstarts[i];
  793.       int col;
  794.       for (col = 0; col < width; col++)
  795.         if (line[col] > 0)
  796.           line[col] += pos_adjust;
  797.     }
  798.       for (i = end + amount; i < end; i++)
  799.     {
  800.       int *line = current_frame->charstarts[i];
  801.       int col;
  802.       line[0] = -1;
  803.       for (col = 0; col < width; col++)
  804.         line[col] = 0;
  805.     }
  806.  
  807.       /* Mark the lines made empty by scrolling as enabled, empty and
  808.      normal video.  */
  809.       bzero (current_frame->used + end + amount,
  810.          - amount * sizeof current_frame->used[0]);
  811.       bzero (current_frame->highlight + end + amount,
  812.          - amount * sizeof current_frame->highlight[0]);
  813.       for (i = end + amount; i < end; i++)
  814.     {
  815.       current_frame->glyphs[i][0] = '\0';
  816.       current_frame->charstarts[i][0] = 0;
  817.       current_frame->enable[i] = 1;
  818.     }
  819.  
  820.       safe_bcopy (current_frame->bufp + from,
  821.           current_frame->bufp + from + amount,
  822.           (end - from) * sizeof current_frame->bufp[0]);
  823.  
  824. #ifdef HAVE_WINDOW_SYSTEM
  825.       if (FRAME_WINDOW_P (frame))
  826.     {
  827.       safe_bcopy (current_frame->top_left_x + from,
  828.               current_frame->top_left_x + from + amount,
  829.               (end - from) * sizeof current_frame->top_left_x[0]);
  830.  
  831.       safe_bcopy (current_frame->top_left_y + from,
  832.               current_frame->top_left_y + from + amount,
  833.               (end - from) * sizeof current_frame->top_left_y[0]);
  834.  
  835.       safe_bcopy (current_frame->pix_width + from,
  836.               current_frame->pix_width + from + amount,
  837.               (end - from) * sizeof current_frame->pix_width[0]);
  838.  
  839.       safe_bcopy (current_frame->pix_height + from,
  840.               current_frame->pix_height + from + amount,
  841.               (end - from) * sizeof current_frame->pix_height[0]);
  842.  
  843.       safe_bcopy (current_frame->max_ascent + from,
  844.               current_frame->max_ascent + from + amount,
  845.               (end - from) * sizeof current_frame->max_ascent[0]);
  846.     }
  847. #endif /* HAVE_WINDOW_SYSTEM */
  848.  
  849.       update_end (frame);
  850.     }
  851.   return 1;
  852. }
  853.  
  854. /* After updating a window W that isn't the full frame wide,
  855.    copy all the columns that W does not occupy
  856.    into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
  857.    so that update_frame will not change those columns.  */
  858.  
  859. void
  860. preserve_other_columns (w)
  861.      struct window *w;
  862. {
  863.   register int vpos;
  864.   register struct frame_glyphs *current_frame, *desired_frame;
  865.   register FRAME_PTR frame = XFRAME (w->frame);
  866.   int start = WINDOW_LEFT_MARGIN (w);
  867.   int end = WINDOW_RIGHT_EDGE (w);
  868.   int bot = XFASTINT (w->top) + XFASTINT (w->height);
  869.  
  870.   current_frame = FRAME_CURRENT_GLYPHS (frame);
  871.   desired_frame = FRAME_DESIRED_GLYPHS (frame);
  872.  
  873.   for (vpos = XFASTINT (w->top); vpos < bot; vpos++)
  874.     {
  875.       if (current_frame->enable[vpos] && desired_frame->enable[vpos])
  876.     {
  877.       if (start > 0)
  878.         {
  879.           int len;
  880.  
  881.           bcopy (current_frame->glyphs[vpos],
  882.              desired_frame->glyphs[vpos],
  883.              start * sizeof (current_frame->glyphs[vpos][0]));
  884.           bcopy (current_frame->charstarts[vpos],
  885.              desired_frame->charstarts[vpos],
  886.              start * sizeof (current_frame->charstarts[vpos][0]));
  887.           len = min (start, current_frame->used[vpos]);
  888.           if (desired_frame->used[vpos] < len)
  889.         desired_frame->used[vpos] = len;
  890.         }
  891.       if (current_frame->used[vpos] > end
  892.           && desired_frame->used[vpos] < current_frame->used[vpos])
  893.         {
  894.           while (desired_frame->used[vpos] < end)
  895.         {
  896.           int used = desired_frame->used[vpos]++;
  897.           desired_frame->glyphs[vpos][used] = SPACEGLYPH;
  898.           desired_frame->glyphs[vpos][used] = 0;
  899.         }
  900.           bcopy (current_frame->glyphs[vpos] + end,
  901.              desired_frame->glyphs[vpos] + end,
  902.              ((current_frame->used[vpos] - end)
  903.               * sizeof (current_frame->glyphs[vpos][0])));
  904.           bcopy (current_frame->charstarts[vpos] + end,
  905.              desired_frame->charstarts[vpos] + end,
  906.              ((current_frame->used[vpos] - end)
  907.               * sizeof (current_frame->charstarts[vpos][0])));
  908.           desired_frame->used[vpos] = current_frame->used[vpos];
  909.         }
  910.     }
  911.     }
  912. }
  913.  
  914. #if 0
  915.  
  916. /* If window w does not need to be updated and isn't the full frame wide,
  917.  copy all the columns that w does occupy
  918.  into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame)
  919.  so that update_frame will not change those columns.
  920.  
  921.  Have not been able to figure out how to use this correctly.  */
  922.  
  923. preserve_my_columns (w)
  924.      struct window *w;
  925. {
  926.   register int vpos, fin;
  927.   register struct frame_glyphs *l1, *l2;
  928.   register FRAME_PTR frame = XFRAME (w->frame);
  929.   int start = WINDOW_LEFT_MARGIN (w);
  930.   int end = WINDOW_RIGHT_EDGE (w);
  931.   int bot = XFASTINT (w->top) + XFASTINT (w->height);
  932.  
  933.   for (vpos = XFASTINT (w->top); vpos < bot; vpos++)
  934.     {
  935.       if ((l1 = FRAME_DESIRED_GLYPHS (frame)->glyphs[vpos + 1])
  936.       && (l2 = FRAME_PHYS_GLYPHS (frame)->glyphs[vpos + 1]))
  937.     {
  938.       if (l2->length > start && l1->length < l2->length)
  939.         {
  940.           fin = l2->length;
  941.           if (fin > end) fin = end;
  942.           while (l1->length < start)
  943.         l1->body[l1->length++] = ' ';
  944.           bcopy (l2->body + start, l1->body + start, fin - start);
  945.           l1->length = fin;
  946.         }
  947.     }
  948.     }
  949. }
  950.  
  951. #endif
  952.  
  953. /* Adjust by ADJUST the charstart values in window W
  954.    after vpos VPOS, which counts relative to the frame
  955.    (not relative to W itself).  */
  956.  
  957. void
  958. adjust_window_charstarts (w, vpos, adjust)
  959.      struct window *w;
  960.      int vpos;
  961.      int adjust;
  962. {
  963.   int left = WINDOW_LEFT_MARGIN (w);
  964.   int top = XFASTINT (w->top);
  965.   int right = left + window_internal_width (w);
  966.   int bottom = top + window_internal_height (w);
  967.   int i;
  968.  
  969.   for (i = vpos + 1; i < bottom; i++)
  970.     {
  971.       int *charstart
  972.     = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w)))->charstarts[i];
  973.       int j;
  974.       for (j = left; j < right; j++)
  975.     if (charstart[j] > 0)
  976.       charstart[j] += adjust;
  977.     }
  978. }
  979.  
  980. /* Check the charstarts values in the area of window W
  981.    for internal consistency.  We cannot check that they are "right";
  982.    we can only look for something nonsensical.  */
  983.  
  984. void
  985. verify_charstarts (w)
  986.      struct window *w;
  987. {
  988.   FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
  989.   int i;
  990.   int top = XFASTINT (w->top);
  991.   int bottom = top + window_internal_height (w);
  992.   int left = WINDOW_LEFT_MARGIN (w);
  993.   int right = left + window_internal_width (w);
  994.   int next_line;
  995.   int truncate = (XINT (w->hscroll)
  996.           || (truncate_partial_width_windows
  997.               && !WINDOW_FULL_WIDTH_P (w))
  998.           || !NILP (XBUFFER (w->buffer)->truncate_lines));
  999.  
  1000.   for (i = top; i < bottom; i++)
  1001.     {
  1002.       int j;
  1003.       int last;
  1004.       int *charstart = FRAME_CURRENT_GLYPHS (f)->charstarts[i];
  1005.  
  1006.       if (i != top)
  1007.     {
  1008.       if (truncate)
  1009.         {
  1010.           /* If we are truncating lines, allow a jump
  1011.          in charstarts from one line to the next.  */
  1012.           if (charstart[left] < next_line)
  1013.         abort ();
  1014.         }
  1015.       else
  1016.         {
  1017.           if (charstart[left] != next_line)
  1018.         abort ();
  1019.         }
  1020.     }
  1021.  
  1022.       for (j = left; j < right; j++)
  1023.     if (charstart[j] > 0)
  1024.       last = charstart[j];
  1025.       /* Record where the next line should start.  */
  1026.       next_line = last;
  1027.       if (BUF_ZV (XBUFFER (w->buffer)) != last)
  1028.     {
  1029.       /* If there's a newline between the two lines, count that.  */
  1030.       int endchar = *BUF_CHAR_ADDRESS (XBUFFER (w->buffer), last);
  1031.       if (endchar == '\n')
  1032.         next_line++;
  1033.     }
  1034.     }
  1035. }
  1036.  
  1037. /* On discovering that the redisplay for a window was no good,
  1038.    cancel the columns of that window, so that when the window is
  1039.    displayed over again get_display_line will not complain.  */
  1040.  
  1041. void
  1042. cancel_my_columns (w)
  1043.      struct window *w;
  1044. {
  1045.   register int vpos;
  1046.   register struct frame_glyphs *desired_glyphs
  1047.     = FRAME_DESIRED_GLYPHS (XFRAME (w->frame));
  1048.   register int start = WINDOW_LEFT_MARGIN (w);
  1049.   register int bot = XFASTINT (w->top) + XFASTINT (w->height);
  1050.  
  1051.   for (vpos = XFASTINT (w->top); vpos < bot; vpos++)
  1052.     if (desired_glyphs->enable[vpos]
  1053.     && desired_glyphs->used[vpos] >= start)
  1054.       desired_glyphs->used[vpos] = start;
  1055. }
  1056.  
  1057. /* These functions try to perform directly and immediately on the frame
  1058.    the necessary output for one change in the buffer.
  1059.    They may return 0 meaning nothing was done if anything is difficult,
  1060.    or 1 meaning the output was performed properly.
  1061.    They assume that the frame was up to date before the buffer
  1062.    change being displayed.  They make various other assumptions too;
  1063.    see command_loop_1 where these are called.  */
  1064.  
  1065. int
  1066. direct_output_for_insert (g)
  1067.      int g;
  1068. {
  1069.   register FRAME_PTR frame = selected_frame;
  1070.   register struct frame_glyphs *current_frame
  1071.     = FRAME_CURRENT_GLYPHS (frame);
  1072.  
  1073. #ifndef COMPILER_REGISTER_BUG
  1074.   register
  1075. #endif /* COMPILER_REGISTER_BUG */
  1076.     struct window *w = XWINDOW (selected_window);
  1077. #ifndef COMPILER_REGISTER_BUG
  1078.   register
  1079. #endif /* COMPILER_REGISTER_BUG */
  1080.     int hpos = FRAME_CURSOR_X (frame);
  1081. #ifndef COMPILER_REGISTER_BUG
  1082.   register
  1083. #endif /* COMPILER_REGISTER_BUG */
  1084.     int vpos = FRAME_CURSOR_Y (frame);
  1085.  
  1086.   /* Give up if about to continue line.  */
  1087.   if (hpos >= WINDOW_LEFT_MARGIN (w) + window_internal_width (w) - 1
  1088.     
  1089.   /* Avoid losing if cursor is in invisible text off left margin */
  1090.       || (XINT (w->hscroll) && hpos == WINDOW_LEFT_MARGIN (w))
  1091.     
  1092.   /* Give up if cursor outside window (in minibuf, probably) */
  1093.       || cursor_in_echo_area
  1094.       || FRAME_CURSOR_Y (frame) < XFASTINT (w->top)
  1095.       || FRAME_CURSOR_Y (frame) >= XFASTINT (w->top) + XFASTINT (w->height)
  1096.  
  1097.   /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */
  1098.       || !display_completed
  1099.  
  1100.   /* Give up if buffer appears in two places.  */
  1101.       || buffer_shared > 1
  1102.  
  1103. #ifdef USE_TEXT_PROPERTIES
  1104.   /* Intervals have already been adjusted, point is after the
  1105.      character that was just inserted. */
  1106.   /* Give up if character is invisible. */
  1107.   /* Give up if character has a face property.
  1108.      At the moment we only lose at end of line or end of buffer
  1109.      and only with faces that have some background */
  1110.   /* Instead of wasting time, give up if character has any text properties */
  1111.       || ! NILP (Ftext_properties_at (make_number (PT - 1), Qnil))
  1112. #endif
  1113.  
  1114.   /* Give up if w is minibuffer and a message is being displayed there */
  1115.       || (MINI_WINDOW_P (w) && echo_area_glyphs))
  1116.     return 0;
  1117.  
  1118.   {
  1119.     int face = 0;
  1120. #ifdef HAVE_FACES
  1121.     int dummy;
  1122.  
  1123.     if (FRAME_WINDOW_P (frame) || FRAME_MSDOS_P (frame))
  1124.       face = compute_char_face (frame, w, PT - 1, -1, -1, &dummy, PT, 0);
  1125. #endif
  1126.     current_frame->glyphs[vpos][hpos] = MAKE_GLYPH (frame, g, face);
  1127.     current_frame->charstarts[vpos][hpos] = PT - 1;
  1128.     /* Record the entry for after the newly inserted character.  */
  1129.     current_frame->charstarts[vpos][hpos + 1] = PT;
  1130.     adjust_window_charstarts (w, vpos, 1);
  1131.   }
  1132.   unchanged_modified = MODIFF;
  1133.   beg_unchanged = GPT - BEG;
  1134.   XSETFASTINT (w->last_point, PT);
  1135.   XSETFASTINT (w->last_point_x, hpos + 1);
  1136.   XSETFASTINT (w->last_modified, MODIFF);
  1137.   XSETFASTINT (w->last_overlay_modified, OVERLAY_MODIFF);
  1138.  
  1139.   reassert_line_highlight (0, vpos);
  1140.   write_glyphs (¤t_frame->glyphs[vpos][hpos], 1);
  1141.   fflush (stdout);
  1142.   ++FRAME_CURSOR_X (frame);
  1143.   if (hpos == current_frame->used[vpos])
  1144.     {
  1145.       current_frame->used[vpos] = hpos + 1;
  1146.       current_frame->glyphs[vpos][hpos + 1] = 0;
  1147.     }
  1148.  
  1149.   return 1;
  1150. }
  1151.  
  1152. int
  1153. direct_output_forward_char (n)
  1154.      int n;
  1155. {
  1156.   register FRAME_PTR frame = selected_frame;
  1157.   register struct window *w = XWINDOW (selected_window);
  1158.   Lisp_Object position;
  1159.   int hpos = FRAME_CURSOR_X (frame);
  1160.  
  1161.   /* Give up if in truncated text at end of line.  */
  1162.   /* This check is not redundant.  */
  1163.   if (hpos >= WINDOW_LEFT_MARGIN (w) + window_internal_width (w) - 1)
  1164.     return 0;
  1165.  
  1166.   /* Give up if the buffer's direction is reversed (i.e. right-to-left).  */
  1167.   if (!NILP (XBUFFER(w->buffer)->direction_reversed))
  1168.     return 0;
  1169.  
  1170.   /* Avoid losing if cursor is in invisible text off left margin
  1171.      or about to go off either side of window.  */
  1172.   if ((FRAME_CURSOR_X (frame) == WINDOW_LEFT_MARGIN (w)
  1173.        && (XINT (w->hscroll) || n < 0))
  1174.       || (n > 0
  1175.       && (FRAME_CURSOR_X (frame) + 1 
  1176.           >= XFASTINT (w->left) + window_internal_width (w) - 1))
  1177.       /* BUG FIX: Added "XFASTINT (w->left)".  Without this,
  1178.      direct_output_forward_char() always fails on "the right"
  1179.      window.  */
  1180.       || cursor_in_echo_area)
  1181.     return 0;
  1182.  
  1183.   /* Can't use direct output if highlighting a region.  */
  1184.   if (!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active))
  1185.     return 0;
  1186.  
  1187.   /* Can't use direct output at an overlay boundary; it might have
  1188.      before-string or after-string properties.  */
  1189.   if (overlay_touches_p (PT) || overlay_touches_p (PT - n))
  1190.     return 0;
  1191.  
  1192. #ifdef USE_TEXT_PROPERTIES
  1193.   /* Don't use direct output next to an invisible character
  1194.      since we might need to do something special.  */
  1195.  
  1196.   XSETFASTINT (position, PT);
  1197.   if (XFASTINT (position) < ZV
  1198.       && ! NILP (Fget_char_property (position,
  1199.                      Qinvisible,
  1200.                      selected_window)))
  1201.     return 0;
  1202.  
  1203.   XSETFASTINT (position, PT - 1);
  1204.   if (XFASTINT (position) >= BEGV
  1205.       && ! NILP (Fget_char_property (position,
  1206.                      Qinvisible,
  1207.                      selected_window)))
  1208.     return 0;
  1209. #endif
  1210.  
  1211.   FRAME_CURSOR_X (frame) += n;
  1212.   XSETFASTINT (w->last_point_x, FRAME_CURSOR_X (frame));
  1213.   XSETFASTINT (w->last_point, PT);
  1214.   cursor_to (FRAME_CURSOR_Y (frame), FRAME_CURSOR_X (frame));
  1215.   fflush (stdout);
  1216.  
  1217.   return 1;
  1218. }
  1219.  
  1220. static void update_line ();
  1221.  
  1222. /* Update frame F based on the data in FRAME_DESIRED_GLYPHS.
  1223.    Value is nonzero if redisplay stopped due to pending input.
  1224.    FORCE nonzero means do not stop for pending input.  */
  1225.  
  1226. int
  1227. update_frame (f, force, inhibit_hairy_id)
  1228.      FRAME_PTR f;
  1229.      int force;
  1230.      int inhibit_hairy_id;
  1231. {
  1232.   register struct frame_glyphs *current_frame;
  1233.   register struct frame_glyphs *desired_frame = 0;
  1234.   register int i;
  1235.   int pause;
  1236.   int preempt_count = baud_rate / 2400 + 1;
  1237.   extern int input_pending;
  1238. #ifdef HAVE_WINDOW_SYSTEM
  1239.   register int downto, leftmost;
  1240. #endif
  1241.  
  1242.   if (baud_rate != FRAME_COST_BAUD_RATE (f))
  1243.     calculate_costs (f);
  1244.  
  1245.   if (preempt_count <= 0)
  1246.     preempt_count = 1;
  1247.  
  1248.   if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */
  1249.  
  1250.   detect_input_pending ();
  1251.   if (input_pending && !force)
  1252.     {
  1253.       pause = 1;
  1254.       goto do_pause;
  1255.     }
  1256.  
  1257.   update_begin (f);
  1258.  
  1259.   if (!line_ins_del_ok)
  1260.     inhibit_hairy_id = 1;
  1261.  
  1262.   /* These are separate to avoid a possible bug in the AIX C compiler.  */
  1263.   current_frame = FRAME_CURRENT_GLYPHS (f);
  1264.   desired_frame = FRAME_DESIRED_GLYPHS (f);
  1265.  
  1266.   /* See if any of the desired lines are enabled; don't compute for
  1267.      i/d line if just want cursor motion. */
  1268.   for (i = 0; i < FRAME_HEIGHT (f); i++)
  1269.     if (desired_frame->enable[i])
  1270.       break;
  1271.  
  1272.   /* Try doing i/d line, if not yet inhibited.  */
  1273.   if (!inhibit_hairy_id && i < FRAME_HEIGHT (f))
  1274.     force |= scrolling (f);
  1275.  
  1276.   /* Update the individual lines as needed.  Do bottom line first.  */
  1277.  
  1278.   if (desired_frame->enable[FRAME_HEIGHT (f) - 1])
  1279.     update_line (f, FRAME_HEIGHT (f) - 1);
  1280.  
  1281. #ifdef HAVE_WINDOW_SYSTEM
  1282.   if (FRAME_WINDOW_P (f))
  1283.     {
  1284.       leftmost = downto = FRAME_INTERNAL_BORDER_WIDTH (f);
  1285.       if (desired_frame->enable[0])
  1286.     {
  1287.       current_frame->top_left_x[FRAME_HEIGHT (f) - 1] = leftmost;
  1288.       current_frame->top_left_y[FRAME_HEIGHT (f) - 1]
  1289.         = PIXEL_HEIGHT (f) - FRAME_INTERNAL_BORDER_WIDTH (f)
  1290.           - current_frame->pix_height[FRAME_HEIGHT (f) - 1];
  1291.       current_frame->top_left_x[0] = leftmost;
  1292.       current_frame->top_left_y[0] = downto;
  1293.     }
  1294.     }
  1295. #endif /* HAVE_WINDOW_SYSTEM */
  1296.  
  1297.   /* Now update the rest of the lines. */
  1298.   for (i = 0; i < FRAME_HEIGHT (f) - 1 && (force || !input_pending); i++)
  1299.     {
  1300.       if (desired_frame->enable[i])
  1301.     {
  1302.       if (FRAME_TERMCAP_P (f))
  1303.         {
  1304.           /* Flush out every so many lines.
  1305.          Also flush out if likely to have more than 1k buffered
  1306.          otherwise.   I'm told that some telnet connections get
  1307.          really screwed by more than 1k output at once.  */
  1308.           int outq = PENDING_OUTPUT_COUNT (stdout);
  1309.           if (outq > 900
  1310.           || (outq > 20 && ((i - 1) % preempt_count == 0)))
  1311.         {
  1312.           fflush (stdout);
  1313.           if (preempt_count == 1)
  1314.             {
  1315. #ifdef EMACS_OUTQSIZE
  1316.               if (EMACS_OUTQSIZE (0, &outq) < 0)
  1317.             /* Probably not a tty.  Ignore the error and reset
  1318.              * the outq count. */
  1319.             outq = PENDING_OUTPUT_COUNT (stdout);
  1320. #endif
  1321.               outq *= 10;
  1322.               if (baud_rate <= outq && baud_rate > 0)
  1323.             sleep (outq / baud_rate);
  1324.             }
  1325.         }
  1326.         }
  1327.  
  1328.       if ((i - 1) % preempt_count == 0)
  1329.         detect_input_pending ();
  1330.  
  1331.       update_line (f, i);
  1332. #ifdef HAVE_WINDOW_SYSTEM
  1333.       if (FRAME_WINDOW_P (f))
  1334.         {
  1335.           current_frame->top_left_y[i] = downto;
  1336.           current_frame->top_left_x[i] = leftmost;
  1337.         }
  1338. #endif /* HAVE_WINDOW_SYSTEM */
  1339.     }
  1340.  
  1341. #ifdef HAVE_WINDOW_SYSTEM
  1342.       if (FRAME_WINDOW_P (f))
  1343.     downto += current_frame->pix_height[i];
  1344. #endif /* HAVE_WINDOW_SYSTEM */
  1345.     }
  1346.   pause = (i < FRAME_HEIGHT (f) - 1) ? i : 0;
  1347.  
  1348.   /* Now just clean up termcap drivers and set cursor, etc.  */
  1349.   if (!pause)
  1350.     {
  1351.       if ((cursor_in_echo_area
  1352.        /* If we are showing a message instead of the minibuffer,
  1353.           show the cursor for the message instead of for the
  1354.           (now hidden) minibuffer contents.  */
  1355.        || (EQ (minibuf_window, selected_window)
  1356.            && EQ (minibuf_window, echo_area_window)
  1357.            && echo_area_glyphs != 0))
  1358.       /* These cases apply only to the frame that contains
  1359.          the active minibuffer window.  */
  1360.       && FRAME_HAS_MINIBUF_P (f)
  1361.       && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
  1362.     {
  1363.       int top = XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top);
  1364.       int row, col;
  1365.  
  1366.       if (cursor_in_echo_area < 0)
  1367.         {
  1368.           row = top;
  1369.           col = 0;
  1370.         }
  1371.       else
  1372.         {
  1373.           /* If the minibuffer is several lines high, find the last
  1374.          line that has any text on it.  */
  1375.           row = FRAME_HEIGHT (f);
  1376.           do 
  1377.         {
  1378.           row--;
  1379.           if (current_frame->enable[row])
  1380.             col = current_frame->used[row];
  1381.           else
  1382.             col = 0;
  1383.         }
  1384.           while (row > top && col == 0);
  1385.  
  1386.           /* Make sure COL is not out of range.  */
  1387.           if (col >= FRAME_CURSOR_X_LIMIT (f))
  1388.         {
  1389.           /* If we have another row, advance cursor into it.  */
  1390.           if (row < FRAME_HEIGHT (f) - 1)
  1391.             {
  1392.               col = FRAME_LEFT_SCROLL_BAR_WIDTH (f);
  1393.               row++;
  1394.             }
  1395.           /* Otherwise move it back in range.  */
  1396.           else
  1397.             col = FRAME_CURSOR_X_LIMIT (f) - 1;
  1398.         }
  1399.         }
  1400.  
  1401.       cursor_to (row, col);
  1402.     }
  1403.       else
  1404.     cursor_to (FRAME_CURSOR_Y (f), 
  1405.            minmax (0, FRAME_CURSOR_X (f),
  1406.                FRAME_CURSOR_X_LIMIT (f) - 1));
  1407.     }
  1408.  
  1409.   update_end (f);
  1410.  
  1411.   if (termscript)
  1412.     fflush (termscript);
  1413.   fflush (stdout);
  1414.  
  1415.   /* Here if output is preempted because input is detected.  */
  1416.  do_pause:
  1417.  
  1418.   if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */
  1419.   display_completed = !pause;
  1420.  
  1421.   bzero (FRAME_DESIRED_GLYPHS (f)->enable, FRAME_HEIGHT (f));
  1422.   return pause;
  1423. }
  1424.  
  1425. /* Called when about to quit, to check for doing so
  1426.    at an improper time.  */
  1427.  
  1428. void
  1429. quit_error_check ()
  1430. {
  1431. #if 0
  1432.   if (FRAME_DESIRED_GLYPHS (selected_frame) == 0)
  1433.     return;
  1434.   if (FRAME_DESIRED_GLYPHS (selected_frame)->enable[0])
  1435.     abort ();
  1436.   if (FRAME_DESIRED_GLYPHS (selected_frame)->enable[FRAME_HEIGHT (selected_frame) - 1])
  1437.     abort ();
  1438. #endif
  1439. }
  1440.  
  1441. /* Decide what insert/delete line to do, and do it */
  1442.  
  1443. extern void scrolling_1 ();
  1444.  
  1445. int
  1446. scrolling (frame)
  1447.      FRAME_PTR frame;
  1448. {
  1449.   int unchanged_at_top, unchanged_at_bottom;
  1450.   int window_size;
  1451.   int changed_lines;
  1452.   int *old_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
  1453.   int *new_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
  1454.   int *draw_cost = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
  1455.   int *old_draw_cost = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int));
  1456.   register int i;
  1457.   int free_at_end_vpos = FRAME_HEIGHT (frame);
  1458.   register struct frame_glyphs *current_frame = FRAME_CURRENT_GLYPHS (frame);
  1459.   register struct frame_glyphs *desired_frame = FRAME_DESIRED_GLYPHS (frame);
  1460.  
  1461.   /* Compute hash codes of all the lines.
  1462.      Also calculate number of changed lines,
  1463.      number of unchanged lines at the beginning,
  1464.      and number of unchanged lines at the end.  */
  1465.  
  1466.   changed_lines = 0;
  1467.   unchanged_at_top = 0;
  1468.   unchanged_at_bottom = FRAME_HEIGHT (frame);
  1469.   for (i = 0; i < FRAME_HEIGHT (frame); i++)
  1470.     {
  1471.       /* Give up on this scrolling if some old lines are not enabled.  */
  1472.       if (!current_frame->enable[i])
  1473.     return 0;
  1474.       old_hash[i] = line_hash_code (current_frame, i);
  1475.       if (! desired_frame->enable[i])
  1476.     {
  1477.       /* This line cannot be redrawn, so don't let scrolling mess it.  */
  1478.       new_hash[i] = old_hash[i];
  1479. #define INFINITY 1000000    /* Taken from scroll.c */
  1480.       draw_cost[i] = INFINITY;
  1481.     }
  1482.       else
  1483.     {
  1484.       new_hash[i] = line_hash_code (desired_frame, i);
  1485.       draw_cost[i] = line_draw_cost (desired_frame, i);
  1486.     }
  1487.  
  1488.       if (old_hash[i] != new_hash[i])
  1489.     {
  1490.       changed_lines++;
  1491.       unchanged_at_bottom = FRAME_HEIGHT (frame) - i - 1;
  1492.     }
  1493.       else if (i == unchanged_at_top)
  1494.     unchanged_at_top++;
  1495.       old_draw_cost[i] = line_draw_cost (current_frame, i);
  1496.     }
  1497.  
  1498.   /* If changed lines are few, don't allow preemption, don't scroll.  */
  1499.   if (!scroll_region_ok && changed_lines < baud_rate / 2400
  1500.       || unchanged_at_bottom == FRAME_HEIGHT (frame))
  1501.     return 1;
  1502.  
  1503.   window_size = (FRAME_HEIGHT (frame) - unchanged_at_top
  1504.          - unchanged_at_bottom);
  1505.  
  1506.   if (scroll_region_ok)
  1507.     free_at_end_vpos -= unchanged_at_bottom;
  1508.   else if (memory_below_frame)
  1509.     free_at_end_vpos = -1;
  1510.  
  1511.   /* If large window, fast terminal and few lines in common between
  1512.      current frame and desired frame, don't bother with i/d calc. */
  1513.   if (!scroll_region_ok && window_size >= 18 && baud_rate > 2400
  1514.       && (window_size >=
  1515.       10 * scrolling_max_lines_saved (unchanged_at_top,
  1516.                       FRAME_HEIGHT (frame) - unchanged_at_bottom,
  1517.                       old_hash, new_hash, draw_cost)))
  1518.     return 0;
  1519.  
  1520.   scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom,
  1521.            draw_cost + unchanged_at_top - 1,
  1522.            old_draw_cost + unchanged_at_top - 1,
  1523.            old_hash + unchanged_at_top - 1,
  1524.            new_hash + unchanged_at_top - 1,
  1525.            free_at_end_vpos - unchanged_at_top);
  1526.  
  1527.   return 0;
  1528. }
  1529.  
  1530. /* Return the offset in its buffer of the character at location col, line
  1531.    in the given window.  */
  1532. int
  1533. buffer_posn_from_coords (window, col, line)
  1534.      struct window *window;
  1535.      int col, line;
  1536. {
  1537.   int hscroll = XINT (window->hscroll);
  1538.   int window_left = WINDOW_LEFT_MARGIN (window);
  1539.  
  1540.   /* The actual width of the window is window->width less one for the
  1541.      DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
  1542.      window.  */
  1543.   int window_width = window_internal_width (window) - 1;
  1544.  
  1545.   int startp = marker_position (window->start);
  1546.  
  1547.   /* Since compute_motion will only operate on the current buffer,
  1548.      we need to save the old one and restore it when we're done.  */
  1549.   struct buffer *old_current_buffer = current_buffer;
  1550.   struct position *posn;
  1551.  
  1552.   current_buffer = XBUFFER (window->buffer);
  1553.  
  1554.   /* We can't get a correct result in this case,
  1555.      but at least prevent compute_motion from crashing.  */
  1556.   if (startp < BEGV)
  1557.     startp = BEGV;
  1558.  
  1559.   /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME
  1560.      (window->frame))->bufp to avoid scanning from the very top of
  1561.      the window, but it isn't maintained correctly, and I'm not even
  1562.      sure I will keep it.  */
  1563.   posn = compute_motion (startp, 0,
  1564.              ((window == XWINDOW (minibuf_window) && startp == BEG
  1565.                ? minibuf_prompt_width : 0)
  1566.               + (hscroll ? 1 - hscroll : 0)),
  1567.              0,
  1568.              ZV, line, col,
  1569.              window_width, hscroll, 0, window);
  1570.  
  1571.   current_buffer = old_current_buffer;
  1572.  
  1573.   /* compute_motion considers frame points past the end of a line
  1574.      to be *after* the newline, i.e. at the start of the next line.
  1575.      This is reasonable, but not really what we want.  So if the
  1576.      result is on a line below LINE, back it up one character.  */
  1577.   if (posn->vpos > line)
  1578.     return posn->bufpos - 1;
  1579.   else
  1580.     return posn->bufpos;
  1581. }
  1582.  
  1583. static int
  1584. count_blanks (r)
  1585.      register GLYPH *r;
  1586. {
  1587.   register GLYPH *p = r;
  1588.   while (*p++ == SPACEGLYPH);
  1589.   return p - r - 1;
  1590. }
  1591.  
  1592. static int
  1593. count_match (str1, str2)
  1594.      GLYPH *str1, *str2;
  1595. {
  1596.   register GLYPH *p1 = str1;
  1597.   register GLYPH *p2 = str2;
  1598.   while (*p1++ == *p2++);
  1599.   return p1 - str1 - 1;
  1600. }
  1601.  
  1602. /* Char insertion/deletion cost vector, from term.c */
  1603. extern int *char_ins_del_vector;
  1604.  
  1605. #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WINDOW_WIDTH((f))])
  1606.  
  1607. static void
  1608. update_line (frame, vpos)
  1609.      register FRAME_PTR frame;
  1610.      int vpos;
  1611. {
  1612.   register GLYPH *obody, *nbody, *op1, *op2, *np1, *temp;
  1613.   int *temp1;
  1614.   int tem;
  1615.   int osp, nsp, begmatch, endmatch, olen, nlen;
  1616.   GLYPH save;
  1617.   register struct frame_glyphs *current_frame
  1618.     = FRAME_CURRENT_GLYPHS (frame);
  1619.   register struct frame_glyphs *desired_frame
  1620.     = FRAME_DESIRED_GLYPHS (frame);
  1621.  
  1622.   if (desired_frame->highlight[vpos]
  1623.       != (current_frame->enable[vpos] && current_frame->highlight[vpos]))
  1624.     {
  1625.       change_line_highlight (desired_frame->highlight[vpos], vpos,
  1626.                  (current_frame->enable[vpos] ?
  1627.                   current_frame->used[vpos] : 0));
  1628.       current_frame->enable[vpos] = 0;
  1629.     }
  1630.   else
  1631.     reassert_line_highlight (desired_frame->highlight[vpos], vpos);
  1632.  
  1633.   if (! current_frame->enable[vpos])
  1634.     {
  1635.       olen = 0;
  1636.     }
  1637.   else
  1638.     {
  1639.       obody = current_frame->glyphs[vpos];
  1640.       olen = current_frame->used[vpos];
  1641.       if (! current_frame->highlight[vpos])
  1642.     {
  1643.       if (!must_write_spaces)
  1644.         while (olen > 0 && obody[olen - 1] == SPACEGLYPH)
  1645.           olen--;
  1646.     }
  1647.       else
  1648.     {
  1649.       /* For an inverse-video line, remember we gave it
  1650.          spaces all the way to the frame edge
  1651.          so that the reverse video extends all the way across.  */
  1652.  
  1653.       while (olen < FRAME_WINDOW_WIDTH (frame) - 1)
  1654.         obody[olen++] = SPACEGLYPH;
  1655.     }
  1656.     }
  1657.  
  1658.   /* One way or another, this will enable the line being updated.  */
  1659.   current_frame->enable[vpos] = 1;
  1660.   current_frame->used[vpos] = desired_frame->used[vpos];
  1661.   current_frame->highlight[vpos] = desired_frame->highlight[vpos];
  1662.   current_frame->bufp[vpos] = desired_frame->bufp[vpos];
  1663.  
  1664. #ifdef HAVE_WINDOW_SYSTEM
  1665.   if (FRAME_WINDOW_P (frame))
  1666.     {
  1667.       current_frame->pix_width[vpos]
  1668.     = current_frame->used[vpos]
  1669.       * FONT_WIDTH (FRAME_FONT (frame));
  1670.       current_frame->pix_height[vpos]
  1671.     = FRAME_LINE_HEIGHT (frame);
  1672.     }
  1673. #endif /* HAVE_WINDOW_SYSTEM */
  1674.  
  1675.   if (!desired_frame->enable[vpos])
  1676.     {
  1677.       nlen = 0;
  1678.       goto just_erase;
  1679.     }
  1680.  
  1681.   nbody = desired_frame->glyphs[vpos];
  1682.   nlen = desired_frame->used[vpos];
  1683.  
  1684.   /* Pretend trailing spaces are not there at all,
  1685.      unless for one reason or another we must write all spaces.  */
  1686.   if (! desired_frame->highlight[vpos])
  1687.     {
  1688.       if (!must_write_spaces)
  1689.     /* We know that the previous character byte contains 0.  */
  1690.     while (nbody[nlen - 1] == SPACEGLYPH)
  1691.       nlen--;
  1692.     }
  1693.   else
  1694.     {
  1695.       /* For an inverse-video line, give it extra trailing spaces
  1696.      all the way to the frame edge
  1697.      so that the reverse video extends all the way across.  */
  1698.  
  1699.       while (nlen < FRAME_WINDOW_WIDTH (frame) - 1)
  1700.     nbody[nlen++] = SPACEGLYPH;
  1701.     }
  1702.  
  1703.   /* If there's no i/d char, quickly do the best we can without it.  */
  1704.   if (!char_ins_del_ok)
  1705.     {
  1706.       int i,j;
  1707.  
  1708. #if 0
  1709.       if (FRAME_X_P (frame))
  1710.     {
  1711.       /* Under X, erase everything we are going to rewrite,
  1712.          and rewrite everything from the first char that's changed.
  1713.          This is part of supporting fonts like Courier
  1714.          whose chars can overlap outside the char width.  */
  1715.       for (i = 0; i < nlen; i++)
  1716.         if (i >= olen || nbody[i] != obody[i])
  1717.           break;
  1718.  
  1719.       cursor_to (vpos, i);
  1720.       if (i != olen)
  1721.         clear_end_of_line (olen);
  1722.       write_glyphs (nbody + i, nlen - i);
  1723.     }
  1724.       else
  1725.     {}
  1726. #endif /* 0 */
  1727.       for (i = 0; i < nlen; i++)
  1728.     {
  1729.       if (i >= olen || nbody[i] != obody[i])    /* A non-matching char. */
  1730.         {
  1731.           cursor_to (vpos, i);
  1732.           for (j = 1;
  1733.            (i + j < nlen
  1734.             && (i + j >= olen || nbody[i + j] != obody[i + j]
  1735.             || (nbody[i + j] & GLYPH_MASK_PADDING)));
  1736.            j++);
  1737.  
  1738.           /* Output this run of non-matching chars.  */ 
  1739.           write_glyphs (nbody + i, j);
  1740.           i += j - 1;
  1741.  
  1742.           /* Now find the next non-match.  */
  1743.         }
  1744.     }
  1745.  
  1746.       /* Clear the rest of the line, or the non-clear part of it.  */
  1747.       if (olen > nlen)
  1748.     {
  1749.       cursor_to (vpos, nlen);
  1750.       clear_end_of_line (olen);
  1751.     }
  1752.  
  1753.       /* Exchange contents between current_frame and new_frame.  */
  1754.       temp = desired_frame->glyphs[vpos];
  1755.       desired_frame->glyphs[vpos] = current_frame->glyphs[vpos];
  1756.       current_frame->glyphs[vpos] = temp;
  1757.  
  1758.       /* Exchange charstarts between current_frame and new_frame.  */
  1759.       temp1 = desired_frame->charstarts[vpos];
  1760.       desired_frame->charstarts[vpos] = current_frame->charstarts[vpos];
  1761.       current_frame->charstarts[vpos] = temp1;
  1762.  
  1763.       return;
  1764.     }
  1765.  
  1766.   if (!olen)
  1767.     {
  1768.       nsp = (must_write_spaces || desired_frame->highlight[vpos])
  1769.           ? 0 : count_blanks (nbody);
  1770.       if (nlen > nsp)
  1771.     {
  1772.       cursor_to (vpos, nsp);
  1773.       write_glyphs (nbody + nsp, nlen - nsp);
  1774.     }
  1775.  
  1776.       /* Exchange contents between current_frame and new_frame.  */
  1777.       temp = desired_frame->glyphs[vpos];
  1778.       desired_frame->glyphs[vpos] = current_frame->glyphs[vpos];
  1779.       current_frame->glyphs[vpos] = temp;
  1780.  
  1781.       /* Exchange charstarts between current_frame and new_frame.  */
  1782.       temp1 = desired_frame->charstarts[vpos];
  1783.       desired_frame->charstarts[vpos] = current_frame->charstarts[vpos];
  1784.       current_frame->charstarts[vpos] = temp1;
  1785.  
  1786.       return;
  1787.     }
  1788.  
  1789.   obody[olen] = 1;
  1790.   save = nbody[nlen];
  1791.   nbody[nlen] = 0;
  1792.  
  1793.   /* Compute number of leading blanks in old and new contents.  */
  1794.   osp = count_blanks (obody);
  1795.   if (!desired_frame->highlight[vpos])
  1796.     nsp = count_blanks (nbody);
  1797.   else
  1798.     nsp = 0;
  1799.  
  1800.   /* Compute number of matching chars starting with first nonblank.  */
  1801.   begmatch = count_match (obody + osp, nbody + nsp);
  1802.  
  1803.   /* Spaces in new match implicit space past the end of old.  */
  1804.   /* A bug causing this to be a no-op was fixed in 18.29.  */
  1805.   if (!must_write_spaces && osp + begmatch == olen)
  1806.     {
  1807.       np1 = nbody + nsp;
  1808.       while (np1[begmatch] == SPACEGLYPH)
  1809.     begmatch++;
  1810.     }
  1811.  
  1812.   /* Avoid doing insert/delete char
  1813.      just cause number of leading spaces differs
  1814.      when the following text does not match. */
  1815.   if (begmatch == 0 && osp != nsp)
  1816.     osp = nsp = min (osp, nsp);
  1817.  
  1818.   /* Find matching characters at end of line */
  1819.   op1 = obody + olen;
  1820.   np1 = nbody + nlen;
  1821.   op2 = op1 + begmatch - min (olen - osp, nlen - nsp);
  1822.   while (op1 > op2 && op1[-1] == np1[-1])
  1823.     {
  1824.       op1--;
  1825.       np1--;
  1826.     }
  1827.   endmatch = obody + olen - op1;
  1828.  
  1829.   /* Put correct value back in nbody[nlen].
  1830.      This is important because direct_output_for_insert
  1831.      can write into the line at a later point.
  1832.      If this screws up the zero at the end of the line, re-establish it.  */
  1833.   nbody[nlen] = save;
  1834.   obody[olen] = 0;
  1835.  
  1836.   /* tem gets the distance to insert or delete.
  1837.      endmatch is how many characters we save by doing so.
  1838.      Is it worth it?  */
  1839.  
  1840.   tem = (nlen - nsp) - (olen - osp);
  1841.   if (endmatch && tem
  1842.       && (!char_ins_del_ok || endmatch <= char_ins_del_cost (frame)[tem]))
  1843.     endmatch = 0;
  1844.  
  1845.   /* nsp - osp is the distance to insert or delete.
  1846.      If that is nonzero, begmatch is known to be nonzero also.
  1847.      begmatch + endmatch is how much we save by doing the ins/del.
  1848.      Is it worth it?  */
  1849.  
  1850.   if (nsp != osp
  1851.       && (!char_ins_del_ok
  1852.       || begmatch + endmatch <= char_ins_del_cost (frame)[nsp - osp]))
  1853.     {
  1854.       begmatch = 0;
  1855.       endmatch = 0;
  1856.       osp = nsp = min (osp, nsp);
  1857.     }
  1858.  
  1859.   /* Now go through the line, inserting, writing and
  1860.      deleting as appropriate.  */
  1861.  
  1862.   if (osp > nsp)
  1863.     {
  1864.       cursor_to (vpos, nsp);
  1865.       delete_glyphs (osp - nsp);
  1866.     }
  1867.   else if (nsp > osp)
  1868.     {
  1869.       /* If going to delete chars later in line
  1870.      and insert earlier in the line,
  1871.      must delete first to avoid losing data in the insert */
  1872.       if (endmatch && nlen < olen + nsp - osp)
  1873.     {
  1874.       cursor_to (vpos, nlen - endmatch + osp - nsp);
  1875.       delete_glyphs (olen + nsp - osp - nlen);
  1876.       olen = nlen - (nsp - osp);
  1877.     }
  1878.       cursor_to (vpos, osp);
  1879.       insert_glyphs ((GLYPH *) 0, nsp - osp);
  1880.     }
  1881.   olen += nsp - osp;
  1882.  
  1883.   tem = nsp + begmatch + endmatch;
  1884.   if (nlen != tem || olen != tem)
  1885.     {
  1886.       cursor_to (vpos, nsp + begmatch);
  1887.       if (!endmatch || nlen == olen)
  1888.     {
  1889.       /* If new text being written reaches right margin,
  1890.          there is no need to do clear-to-eol at the end.
  1891.          (and it would not be safe, since cursor is not
  1892.          going to be "at the margin" after the text is done) */
  1893.       if (nlen == FRAME_WINDOW_WIDTH (frame))
  1894.         olen = 0;
  1895.       write_glyphs (nbody + nsp + begmatch, nlen - tem);
  1896.  
  1897. #ifdef obsolete
  1898.  
  1899. /* the following code loses disastrously if tem == nlen.
  1900.    Rather than trying to fix that case, I am trying the simpler
  1901.    solution found above.  */
  1902.  
  1903.       /* If the text reaches to the right margin,
  1904.          it will lose one way or another (depending on AutoWrap)
  1905.          to clear to end of line after outputting all the text.
  1906.          So pause with one character to go and clear the line then.  */
  1907.       if (nlen == FRAME_WINDOW_WIDTH (frame) && fast_clear_end_of_line && olen > nlen)
  1908.         {
  1909.           /* endmatch must be zero, and tem must equal nsp + begmatch */
  1910.           write_glyphs (nbody + tem, nlen - tem - 1);
  1911.           clear_end_of_line (olen);
  1912.           olen = 0;        /* Don't let it be cleared again later */
  1913.           write_glyphs (nbody + nlen - 1, 1);
  1914.         }
  1915.       else
  1916.         write_glyphs (nbody + nsp + begmatch, nlen - tem);
  1917. #endif    /* OBSOLETE */
  1918.  
  1919.     }
  1920.       else if (nlen > olen)
  1921.     {
  1922.       /* Here, we used to have the following simple code:
  1923.          ----------------------------------------
  1924.          write_glyphs (nbody + nsp + begmatch, olen - tem);
  1925.          insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen);
  1926.          ----------------------------------------
  1927.          but it doesn't work if nbody[nsp + begmatch + olen - tem]
  1928.          is a padding glyph.  */
  1929.       int out = olen - tem;    /* Columns to be overwritten originally.  */
  1930.       int del;
  1931.  
  1932.       /* Calculate columns we can actually overwrite.  */
  1933.       while (nbody[nsp + begmatch + out] & GLYPH_MASK_PADDING) out--;
  1934.       write_glyphs (nbody + nsp + begmatch, out);
  1935.       /* If we left columns to be overwritten. we must delete them.  */
  1936.       del = olen - tem - out;
  1937.       if (del > 0) delete_glyphs (del);
  1938.       /* At last, we insert columns not yet written out.  */
  1939.       insert_glyphs (nbody + nsp + begmatch + out, nlen - olen + del);
  1940.       olen = nlen;
  1941.     }
  1942.       else if (olen > nlen)
  1943.     {
  1944.       write_glyphs (nbody + nsp + begmatch, nlen - tem);
  1945.       delete_glyphs (olen - nlen);
  1946.       olen = nlen;
  1947.     }
  1948.     }
  1949.  
  1950.  just_erase:
  1951.   /* If any unerased characters remain after the new line, erase them.  */
  1952.   if (olen > nlen)
  1953.     {
  1954.       cursor_to (vpos, nlen);
  1955.       clear_end_of_line (olen);
  1956.     }
  1957.  
  1958.   /* Exchange contents between current_frame and new_frame.  */
  1959.   temp = desired_frame->glyphs[vpos];
  1960.   desired_frame->glyphs[vpos] = current_frame->glyphs[vpos];
  1961.   current_frame->glyphs[vpos] = temp;
  1962.  
  1963.   /* Exchange charstarts between current_frame and new_frame.  */
  1964.   temp1 = desired_frame->charstarts[vpos];
  1965.   desired_frame->charstarts[vpos] = current_frame->charstarts[vpos];
  1966.   current_frame->charstarts[vpos] = temp1;
  1967. }
  1968.  
  1969. /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
  1970.    session's frames, frame names, buffers, buffer-read-only flags, and
  1971.    buffer-modified-flags, and a trailing sentinel (so we don't need to
  1972.    add length checks).  */
  1973. static Lisp_Object frame_and_buffer_state;
  1974.  
  1975. DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p,
  1976.   Sframe_or_buffer_changed_p, 0, 0, 0,
  1977.   "Return non-nil if the frame and buffer state appears to have changed.\n\
  1978. The state variable is an internal vector containing all frames and buffers,\n\
  1979. aside from buffers whose names start with space,\n\
  1980. along with the buffers' read-only and modified flags, which allows a fast\n\
  1981. check to see whether the menu bars might need to be recomputed.\n\
  1982. If this function returns non-nil, it updates the internal vector to reflect\n\
  1983. the current state.\n")
  1984.   ()
  1985. {
  1986.   Lisp_Object tail, frame, buf;
  1987.   Lisp_Object *vecp;
  1988.   int n;
  1989.  
  1990.   vecp = XVECTOR (frame_and_buffer_state)->contents;
  1991.   FOR_EACH_FRAME (tail, frame)
  1992.     {
  1993.       if (!EQ (*vecp++, frame))
  1994.     goto changed;
  1995.       if (!EQ (*vecp++, XFRAME (frame)->name))
  1996.     goto changed;
  1997.     }
  1998.   /* Check that the buffer info matches.
  1999.      No need to test for the end of the vector
  2000.      because the last element of the vector is lambda
  2001.      and that will always cause a mismatch.  */
  2002.   for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr)
  2003.     {
  2004.       buf = XCONS (XCONS (tail)->car)->cdr;
  2005.       /* Ignore buffers that aren't included in buffer lists.  */
  2006.       if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
  2007.     continue;
  2008.       if (!EQ (*vecp++, buf))
  2009.     goto changed;
  2010.       if (!EQ (*vecp++, XBUFFER (buf)->read_only))
  2011.     goto changed;
  2012.       if (!EQ (*vecp++, Fbuffer_modified_p (buf)))
  2013.     goto changed;
  2014.     }
  2015.   /* Detect deletion of a buffer at the end of the list.  */
  2016.   if (EQ (*vecp, Qlambda))
  2017.     return Qnil;
  2018.  changed:
  2019.   /* Start with 1 so there is room for at least one lambda at the end.  */
  2020.   n = 1;
  2021.   FOR_EACH_FRAME (tail, frame)
  2022.     n += 2;
  2023.   for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr)
  2024.     n += 3;
  2025.   /* Reallocate the vector if it's grown, or if it's shrunk a lot.  */
  2026.   if (n > XVECTOR (frame_and_buffer_state)->size
  2027.       || n + 20 < XVECTOR (frame_and_buffer_state)->size / 2)
  2028.     /* Add 20 extra so we grow it less often.  */
  2029.     frame_and_buffer_state = Fmake_vector (make_number (n + 20), Qlambda);
  2030.   vecp = XVECTOR (frame_and_buffer_state)->contents;
  2031.   FOR_EACH_FRAME (tail, frame)
  2032.     {
  2033.       *vecp++ = frame;
  2034.       *vecp++ = XFRAME (frame)->name;
  2035.     }
  2036.   for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr)
  2037.     {
  2038.       buf = XCONS (XCONS (tail)->car)->cdr;
  2039.       /* Ignore buffers that aren't included in buffer lists.  */
  2040.       if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
  2041.     continue;
  2042.       *vecp++ = buf;
  2043.       *vecp++ = XBUFFER (buf)->read_only;
  2044.       *vecp++ = Fbuffer_modified_p (buf);
  2045.     }
  2046.   /* Fill up the vector with lambdas (always at least one).  */
  2047.   *vecp++ = Qlambda;
  2048.   while  (vecp - XVECTOR (frame_and_buffer_state)->contents
  2049.       < XVECTOR (frame_and_buffer_state)->size)
  2050.     *vecp++ = Qlambda;
  2051.   /* Make sure we didn't overflow the vector.  */
  2052.   if (vecp - XVECTOR (frame_and_buffer_state)->contents
  2053.       > XVECTOR (frame_and_buffer_state)->size)
  2054.     abort ();
  2055.   return Qt;
  2056. }
  2057.  
  2058. DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
  2059.   1, 1, "FOpen termscript file: ",
  2060.   "Start writing all terminal output to FILE as well as the terminal.\n\
  2061. FILE = nil means just close any termscript file currently open.")
  2062.   (file)
  2063.      Lisp_Object file;
  2064. {
  2065.   if (termscript != 0) fclose (termscript);
  2066.   termscript = 0;
  2067.  
  2068.   if (! NILP (file))
  2069.     {
  2070.       file = Fexpand_file_name (file, Qnil);
  2071.       termscript = fopen (XSTRING (file)->data, "w");
  2072.       if (termscript == 0)
  2073.     report_file_error ("Opening termscript", Fcons (file, Qnil));
  2074.     }
  2075.   return Qnil;
  2076. }
  2077.  
  2078.  
  2079. #ifdef SIGWINCH
  2080. SIGTYPE
  2081. window_change_signal (signalnum) /* If we don't have an argument, */
  2082.      int signalnum;        /* some compilers complain in signal calls. */
  2083. {
  2084.   int width, height;
  2085.   extern int errno;
  2086.   int old_errno = errno;
  2087.  
  2088.   get_frame_size (&width, &height);
  2089.  
  2090.   /* The frame size change obviously applies to a termcap-controlled
  2091.      frame.  Find such a frame in the list, and assume it's the only
  2092.      one (since the redisplay code always writes to stdout, not a
  2093.      FILE * specified in the frame structure).  Record the new size,
  2094.      but don't reallocate the data structures now.  Let that be done
  2095.      later outside of the signal handler.  */
  2096.  
  2097.   {
  2098.     Lisp_Object tail, frame;
  2099.  
  2100.     FOR_EACH_FRAME (tail, frame)
  2101.       {
  2102.     if (FRAME_TERMCAP_P (XFRAME (frame)))
  2103.       {
  2104.         change_frame_size (XFRAME (frame), height, width, 0, 1);
  2105.         break;
  2106.       }
  2107.       }
  2108.   }
  2109.  
  2110.   signal (SIGWINCH, window_change_signal);
  2111.   errno = old_errno;
  2112. }
  2113. #endif /* SIGWINCH */
  2114.  
  2115.  
  2116. /* Do any change in frame size that was requested by a signal.  */
  2117.  
  2118. void
  2119. do_pending_window_change ()
  2120. {
  2121.   /* If window_change_signal should have run before, run it now.  */
  2122.   while (delayed_size_change)
  2123.     {
  2124.       Lisp_Object tail, frame;
  2125.  
  2126.       delayed_size_change = 0;
  2127.  
  2128.       FOR_EACH_FRAME (tail, frame)
  2129.     {
  2130.       FRAME_PTR f = XFRAME (frame);
  2131.  
  2132.       int height = FRAME_NEW_HEIGHT (f);
  2133.       int width = FRAME_NEW_WIDTH (f);
  2134.  
  2135.       if (height != 0 || width != 0)
  2136.         change_frame_size (f, height, width, 0, 0);
  2137.     }
  2138.     }
  2139. }
  2140.  
  2141.  
  2142. /* Change the frame height and/or width.  Values may be given as zero to
  2143.    indicate no change is to take place. 
  2144.  
  2145.    If DELAY is non-zero, then assume we're being called from a signal
  2146.    handler, and queue the change for later - perhaps the next
  2147.    redisplay.  Since this tries to resize windows, we can't call it
  2148.    from a signal handler.  */
  2149.  
  2150. void
  2151. change_frame_size (f, newheight, newwidth, pretend, delay)
  2152.      register FRAME_PTR f;
  2153.      int newheight, newwidth, pretend, delay;
  2154. {
  2155.   Lisp_Object tail, frame;
  2156.  
  2157.   if (! FRAME_WINDOW_P (f))
  2158.     {
  2159.       /* When using termcap, or on MS-DOS, all frames use
  2160.      the same screen, so a change in size affects all frames.  */
  2161.       FOR_EACH_FRAME (tail, frame)
  2162.     if (! FRAME_WINDOW_P (XFRAME (frame)))
  2163.       change_frame_size_1 (XFRAME (frame), newheight, newwidth,
  2164.                    pretend, delay);
  2165.     }
  2166.   else
  2167.     change_frame_size_1 (f, newheight, newwidth, pretend, delay);
  2168. }
  2169.  
  2170. static void
  2171. change_frame_size_1 (frame, newheight, newwidth, pretend, delay)
  2172.      register FRAME_PTR frame;
  2173.      int newheight, newwidth, pretend, delay;
  2174. {
  2175.   int new_frame_window_width;
  2176.   unsigned int total_glyphs;
  2177.   int count = specpdl_ptr - specpdl;
  2178.  
  2179.   /* If we can't deal with the change now, queue it for later.  */
  2180.   if (delay)
  2181.     {
  2182.       FRAME_NEW_HEIGHT (frame) = newheight;
  2183.       FRAME_NEW_WIDTH (frame) = newwidth;
  2184.       delayed_size_change = 1;
  2185.       return;
  2186.     }
  2187.  
  2188.   /* This size-change overrides any pending one for this frame.  */
  2189.   FRAME_NEW_HEIGHT (frame) = 0;
  2190.   FRAME_NEW_WIDTH  (frame) = 0;
  2191.  
  2192.   /* If an argument is zero, set it to the current value.  */
  2193.   if (newheight == 0)
  2194.     newheight = FRAME_HEIGHT (frame);
  2195.   if (newwidth == 0)
  2196.     newwidth  = FRAME_WIDTH  (frame);
  2197.   new_frame_window_width = FRAME_WINDOW_WIDTH_ARG (frame, newwidth);
  2198.  
  2199.   total_glyphs = newheight * (newwidth + 2) * sizeof (GLYPH);
  2200.  
  2201.   /* If these sizes are so big they cause overflow,
  2202.      just ignore the change.  It's not clear what better we could do.  */
  2203.   if (total_glyphs / sizeof (GLYPH) / newheight != newwidth + 2)
  2204.     return;
  2205.  
  2206.   /* Round up to the smallest acceptable size.  */
  2207.   check_frame_size (frame, &newheight, &newwidth);
  2208.  
  2209.   /* If we're not changing the frame size, quit now.  */
  2210.   if (newheight == FRAME_HEIGHT (frame)
  2211.       && new_frame_window_width == FRAME_WINDOW_WIDTH (frame))
  2212.     return;
  2213.  
  2214.   BLOCK_INPUT;
  2215.  
  2216. #ifdef MSDOS
  2217.   /* We only can set screen dimensions to certain values supported
  2218.      by our video hardware.  Try to find the smallest size greater
  2219.      or equal to the requested dimensions.  */
  2220.   dos_set_window_size (&newheight, &newwidth);
  2221. #endif
  2222.  
  2223.   if (newheight != FRAME_HEIGHT (frame))
  2224.     {
  2225.       if (FRAME_HAS_MINIBUF_P (frame)
  2226.       && ! FRAME_MINIBUF_ONLY_P (frame))
  2227.     {
  2228.       /* Frame has both root and minibuffer.  */
  2229.       set_window_height (FRAME_ROOT_WINDOW (frame),
  2230.                  newheight - 1 - FRAME_MENU_BAR_LINES (frame), 0);
  2231.       XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame))->top,
  2232.                newheight - 1);
  2233.       set_window_height (FRAME_MINIBUF_WINDOW (frame), 1, 0);
  2234.     }
  2235.       else
  2236.     /* Frame has just one top-level window.  */
  2237.     set_window_height (FRAME_ROOT_WINDOW (frame),
  2238.                newheight - FRAME_MENU_BAR_LINES (frame), 0);
  2239.  
  2240.       if (FRAME_TERMCAP_P (frame) && !pretend)
  2241.     FrameRows = newheight;
  2242.  
  2243. #if 0
  2244.       if (frame->output_method == output_termcap)
  2245.     {
  2246.       frame_height = newheight;
  2247.       if (!pretend)
  2248.         FrameRows = newheight;
  2249.     }
  2250. #endif
  2251.     }
  2252.  
  2253.   if (new_frame_window_width  != FRAME_WINDOW_WIDTH (frame))
  2254.     {
  2255.       set_window_width (FRAME_ROOT_WINDOW (frame), new_frame_window_width, 0);
  2256.       if (FRAME_HAS_MINIBUF_P (frame))
  2257.     set_window_width (FRAME_MINIBUF_WINDOW (frame), new_frame_window_width, 0);
  2258.  
  2259.       if (FRAME_TERMCAP_P (frame) && !pretend)
  2260.     FrameCols = newwidth;
  2261. #if 0
  2262.       if (frame->output_method == output_termcap)
  2263.     {
  2264.       frame_width = newwidth;
  2265.       if (!pretend)
  2266.         FrameCols = newwidth;
  2267.     }
  2268. #endif
  2269.     }
  2270.  
  2271.   FRAME_HEIGHT (frame) = newheight;
  2272.   SET_FRAME_WIDTH (frame, newwidth);
  2273.  
  2274.   if (FRAME_CURSOR_X (frame) >= FRAME_CURSOR_X_LIMIT (frame))
  2275.     FRAME_CURSOR_X (frame) = FRAME_CURSOR_X_LIMIT (frame) - 1;
  2276.   if (FRAME_CURSOR_Y (frame) >= FRAME_HEIGHT (frame))
  2277.     FRAME_CURSOR_Y (frame) = FRAME_HEIGHT (frame) - 1;
  2278.  
  2279.   remake_frame_glyphs (frame);
  2280.   calculate_costs (frame);
  2281.  
  2282.   UNBLOCK_INPUT;
  2283.  
  2284.   record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
  2285.  
  2286.   /* This isn't quite a no-op: it runs window-configuration-change-hook.  */
  2287.   Fset_window_buffer (FRAME_SELECTED_WINDOW (frame),
  2288.               XWINDOW (FRAME_SELECTED_WINDOW (frame))->buffer);
  2289.  
  2290.   unbind_to (count, Qnil);
  2291. }
  2292.  
  2293. DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
  2294.   Ssend_string_to_terminal, 1, 1, 0,
  2295.   "Send STRING to the terminal without alteration.\n\
  2296. Control characters in STRING will have terminal-dependent effects.")
  2297.   (string)
  2298.      Lisp_Object string;
  2299. {
  2300.   /* ??? Perhaps we should do something special for multibyte strings here.  */
  2301.   CHECK_STRING (string, 0);
  2302.   fwrite (XSTRING (string)->data, 1, STRING_BYTES (XSTRING (string)), stdout);
  2303.   fflush (stdout);
  2304.   if (termscript)
  2305.     {
  2306.       fwrite (XSTRING (string)->data, 1, STRING_BYTES (XSTRING (string)),
  2307.           termscript);
  2308.       fflush (termscript);
  2309.     }
  2310.   return Qnil;
  2311. }
  2312.  
  2313. DEFUN ("ding", Fding, Sding, 0, 1, 0,
  2314.   "Beep, or flash the screen.\n\
  2315. Also, unless an argument is given,\n\
  2316. terminate any keyboard macro currently executing.")
  2317.   (arg)
  2318.   Lisp_Object arg;
  2319. {
  2320.   if (!NILP (arg))
  2321.     {
  2322.       if (noninteractive)
  2323.     putchar (07);
  2324.       else
  2325.     ring_bell ();
  2326.       fflush (stdout);
  2327.     }
  2328.   else
  2329.     bitch_at_user ();
  2330.  
  2331.   return Qnil;
  2332. }
  2333.  
  2334. void
  2335. bitch_at_user ()
  2336. {
  2337.   if (noninteractive)
  2338.     putchar (07);
  2339.   else if (!INTERACTIVE)  /* Stop executing a keyboard macro. */
  2340.     error ("Keyboard macro terminated by a command ringing the bell");
  2341.   else
  2342.     ring_bell ();
  2343.   fflush (stdout);
  2344. }
  2345.  
  2346. DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
  2347.   "Pause, without updating display, for SECONDS seconds.\n\
  2348. SECONDS may be a floating-point value, meaning that you can wait for a\n\
  2349. fraction of a second.  Optional second arg MILLISECONDS specifies an\n\
  2350. additional wait period, in milliseconds; this may be useful if your\n\
  2351. Emacs was built without floating point support.\n\
  2352. \(Not all operating systems support waiting for a fraction of a second.)")
  2353.   (seconds, milliseconds)
  2354.      Lisp_Object seconds, milliseconds;
  2355. {
  2356.   int sec, usec;
  2357.  
  2358.   if (NILP (milliseconds))
  2359.     XSETINT (milliseconds, 0);
  2360.   else
  2361.     CHECK_NUMBER (milliseconds, 1);
  2362.   usec = XINT (milliseconds) * 1000;
  2363.  
  2364. #ifdef LISP_FLOAT_TYPE
  2365.   {
  2366.     double duration = extract_float (seconds);
  2367.     sec = (int) duration;
  2368.     usec += (duration - sec) * 1000000;
  2369.   }
  2370. #else
  2371.   CHECK_NUMBER (seconds, 0);
  2372.   sec = XINT (seconds);
  2373. #endif
  2374.  
  2375. #ifndef EMACS_HAS_USECS
  2376.   if (sec == 0 && usec != 0)
  2377.     error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE);
  2378. #endif
  2379.  
  2380.   /* Assure that 0 <= usec < 1000000.  */
  2381.   if (usec < 0)
  2382.     {
  2383.       /* We can't rely on the rounding being correct if user is negative.  */
  2384.       if (-1000000 < usec)
  2385.     sec--, usec += 1000000;
  2386.       else
  2387.     sec -= -usec / 1000000, usec = 1000000 - (-usec % 1000000);
  2388.     }
  2389.   else
  2390.     sec += usec / 1000000, usec %= 1000000;
  2391.  
  2392.   if (sec < 0 || (sec == 0 && usec == 0))
  2393.     return Qnil;
  2394.  
  2395.   {
  2396.     Lisp_Object zero;
  2397.  
  2398.     XSETFASTINT (zero, 0);
  2399.     wait_reading_process_input (sec, usec, zero, 0);
  2400.   }
  2401.  
  2402.   /* We should always have wait_reading_process_input; we have a dummy
  2403.      implementation for systems which don't support subprocesses.  */
  2404. #if 0
  2405.   /* No wait_reading_process_input */
  2406.   immediate_quit = 1;
  2407.   QUIT;
  2408.  
  2409. #ifdef VMS
  2410.   sys_sleep (sec);
  2411. #else /* not VMS */
  2412. /* The reason this is done this way 
  2413.     (rather than defined (H_S) && defined (H_T))
  2414.    is because the VMS preprocessor doesn't grok `defined' */
  2415. #ifdef HAVE_SELECT
  2416.   EMACS_GET_TIME (end_time);
  2417.   EMACS_SET_SECS_USECS (timeout, sec, usec);
  2418.   EMACS_ADD_TIME (end_time, end_time, timeout);
  2419.  
  2420.   while (1)
  2421.     {
  2422.       EMACS_GET_TIME (timeout);
  2423.       EMACS_SUB_TIME (timeout, end_time, timeout);
  2424.       if (EMACS_TIME_NEG_P (timeout)
  2425.       || !select (1, 0, 0, 0, &timeout))
  2426.     break;
  2427.     }
  2428. #else /* not HAVE_SELECT */
  2429.   sleep (sec);
  2430. #endif /* HAVE_SELECT */
  2431. #endif /* not VMS */
  2432.   
  2433.   immediate_quit = 0;
  2434. #endif /* no subprocesses */
  2435.  
  2436.   return Qnil;
  2437. }
  2438.  
  2439. /* This is just like wait_reading_process_input, except that
  2440.    it does the redisplay.
  2441.  
  2442.    It's also much like Fsit_for, except that it can be used for
  2443.    waiting for input as well.  */
  2444.  
  2445. Lisp_Object
  2446. sit_for (sec, usec, reading, display, initial_display)
  2447.      int sec, usec, reading, display, initial_display;
  2448. {
  2449.   Lisp_Object read_kbd;
  2450.  
  2451.   swallow_events (display);
  2452.  
  2453.   if (detect_input_pending_run_timers (display))
  2454.     return Qnil;
  2455.  
  2456.   if (initial_display)
  2457.     redisplay_preserve_echo_area ();
  2458.  
  2459.   if (sec == 0 && usec == 0)
  2460.     return Qt;
  2461.  
  2462. #ifdef SIGIO
  2463.   gobble_input (0);
  2464. #endif
  2465.  
  2466.   XSETINT (read_kbd, reading ? -1 : 1);
  2467.   wait_reading_process_input (sec, usec, read_kbd, display);
  2468.  
  2469.   return detect_input_pending () ? Qnil : Qt;
  2470. }
  2471.  
  2472. DEFUN ("sit-for", Fsit_for, Ssit_for, 1, 3, 0,
  2473.   "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
  2474. SECONDS may be a floating-point value, meaning that you can wait for a\n\
  2475. fraction of a second.  Optional second arg MILLISECONDS specifies an\n\
  2476. additional wait period, in milliseconds; this may be useful if your\n\
  2477. Emacs was built without floating point support.\n\
  2478. \(Not all operating systems support waiting for a fraction of a second.)\n\
  2479. Optional third arg NODISP non-nil means don't redisplay, just wait for input.\n\
  2480. Redisplay is preempted as always if input arrives, and does not happen\n\
  2481. if input is available before it starts.\n\
  2482. Value is t if waited the full time with no input arriving.")
  2483.   (seconds, milliseconds, nodisp)
  2484.      Lisp_Object seconds, milliseconds, nodisp;
  2485. {
  2486.   int sec, usec;
  2487.  
  2488.   if (NILP (milliseconds))
  2489.     XSETINT (milliseconds, 0);
  2490.   else
  2491.     CHECK_NUMBER (milliseconds, 1);
  2492.   usec = XINT (milliseconds) * 1000;
  2493.  
  2494. #ifdef LISP_FLOAT_TYPE
  2495.   {
  2496.     double duration = extract_float (seconds);
  2497.     sec = (int) duration;
  2498.     usec += (duration - sec) * 1000000;
  2499.   }
  2500. #else
  2501.   CHECK_NUMBER (seconds, 0);
  2502.   sec = XINT (seconds);
  2503. #endif
  2504.  
  2505. #ifndef EMACS_HAS_USECS
  2506.   if (usec != 0 && sec == 0)
  2507.     error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE);
  2508. #endif
  2509.  
  2510.   return sit_for (sec, usec, 0, NILP (nodisp), NILP (nodisp));
  2511. }
  2512.  
  2513. char *terminal_type;
  2514.  
  2515. /* Initialization done when Emacs fork is started, before doing stty. */
  2516. /* Determine terminal type and set terminal_driver */
  2517. /* Then invoke its decoding routine to set up variables
  2518.   in the terminal package */
  2519.  
  2520. void
  2521. init_display ()
  2522. {
  2523. #ifdef HAVE_X_WINDOWS
  2524.     extern int display_arg;
  2525. #endif
  2526.  
  2527.     meta_key = 0;
  2528.     inverse_video = 0;
  2529.     cursor_in_echo_area = 0;
  2530.     terminal_type = (char *) 0;
  2531.  
  2532.     /* Now is the time to initialize this; it's used by init_sys_modes
  2533.        during startup.  */
  2534.     Vwindow_system = Qnil;
  2535.  
  2536.     /* If the user wants to use a window system, we shouldn't bother
  2537.        initializing the terminal.  This is especially important when the
  2538.        terminal is so dumb that emacs gives up before and doesn't bother
  2539.        using the window system.
  2540.  
  2541.        If the DISPLAY environment variable is set and nonempty,
  2542.        try to use X, and die with an error message if that doesn't work.  */
  2543.  
  2544. #ifdef HAVE_X_WINDOWS
  2545. # ifdef HAVE_PM
  2546.     if (!inhibit_window_system && display_arg)
  2547.     {
  2548.         Vwindow_system = intern ("pm");
  2549.         return;
  2550.     }
  2551. #else /* not HAVE_PM */
  2552.     if (! display_arg)
  2553.     {
  2554.         char *display;
  2555. # ifdef VMS
  2556.         display = getenv ("DECW$DISPLAY");
  2557. # else
  2558.         display = getenv ("DISPLAY");
  2559. # endif
  2560.  
  2561.         display_arg = (display != 0 && *display != 0);
  2562.     }
  2563. #endif /* not HAVE_PM */
  2564.   
  2565.     if (!inhibit_window_system && display_arg 
  2566. #ifndef CANNOT_DUMP
  2567.         && initialized
  2568. #endif
  2569.         )
  2570.     {
  2571.         Vwindow_system = intern ("x");
  2572. #ifdef HAVE_X11
  2573.         Vwindow_system_version = make_number (11);
  2574. #else
  2575.         Vwindow_system_version = make_number (10);
  2576. #endif
  2577. #if defined (LINUX) && defined (HAVE_LIBNCURSES)
  2578.         /* In some versions of ncurses,
  2579.            tputs crashes if we have not called tgetent.
  2580.            So call tgetent.  */
  2581.         { char b[2044]; tgetent (b, "xterm");}
  2582. #endif
  2583.         return;
  2584.     }
  2585. #endif /* HAVE_X_WINDOWS */
  2586.  
  2587. #ifdef HAVE_NTGUI
  2588.     if (!inhibit_window_system) 
  2589.     {
  2590.         Vwindow_system = intern ("w32");
  2591.         Vwindow_system_version = make_number (1);
  2592.         return;
  2593.     }
  2594. #endif /* HAVE_NTGUI */
  2595.  
  2596.     /* If no window system has been specified, try to use the terminal.  */
  2597.     if (! isatty (0))
  2598.     {
  2599.         fatal ("standard input is not a tty");
  2600.         exit (1);
  2601.     }
  2602.  
  2603.     /* Look at the TERM variable */
  2604.     terminal_type = (char *) getenv ("TERM");
  2605.     if (!terminal_type)
  2606.     {
  2607. #ifdef VMS
  2608.         fprintf (stderr, "Please specify your terminal type.\n\
  2609. For types defined in VMS, use  set term /device=TYPE.\n\
  2610. For types not defined in VMS, use  define emacs_term \"TYPE\".\n\
  2611. \(The quotation marks are necessary since terminal types are lower case.)\n");
  2612. #else
  2613.         fprintf (stderr, "Please set the environment variable TERM; see tset(1).\n");
  2614. #endif
  2615.         exit (1);
  2616.     }
  2617.  
  2618. #ifdef VMS
  2619.     /* VMS DCL tends to upcase things, so downcase term type.
  2620.        Hardly any uppercase letters in terminal types; should be none.  */
  2621.     {
  2622.         char *new = (char *) xmalloc (strlen (terminal_type) + 1);
  2623.         char *p;
  2624.  
  2625.         strcpy (new, terminal_type);
  2626.  
  2627.         for (p = new; *p; p++)
  2628.             if (isupper (*p))
  2629.                 *p = tolower (*p);
  2630.  
  2631.         terminal_type = new;
  2632.     }    
  2633. #endif
  2634.  
  2635.     term_init (terminal_type);
  2636.  
  2637.     {
  2638.         int width = FRAME_WINDOW_WIDTH (selected_frame);
  2639.         int height = FRAME_HEIGHT (selected_frame);
  2640.  
  2641.         unsigned int total_glyphs = height * (width + 2) * sizeof (GLYPH);
  2642.  
  2643.         /* If these sizes are so big they cause overflow,
  2644.            just ignore the change.  It's not clear what better we could do.  */
  2645.         if (total_glyphs / sizeof (GLYPH) / height != width + 2)
  2646.             fatal ("screen size %dx%d too big", width, height);
  2647.     }
  2648.  
  2649.     remake_frame_glyphs (selected_frame);
  2650.     calculate_costs (selected_frame);
  2651.  
  2652.     /* X and Y coordinates of the cursor between updates. */
  2653.     FRAME_CURSOR_X (selected_frame) = 0;
  2654.     FRAME_CURSOR_Y (selected_frame) = 0;
  2655.  
  2656. #ifdef SIGWINCH
  2657. #ifndef CANNOT_DUMP
  2658.     if (initialized)
  2659. #endif /* CANNOT_DUMP */
  2660.         signal (SIGWINCH, window_change_signal);
  2661. #endif /* SIGWINCH */
  2662. }
  2663.  
  2664. void
  2665. syms_of_display ()
  2666. {
  2667.   defsubr (&Sredraw_frame);
  2668.   defsubr (&Sredraw_display);
  2669.   defsubr (&Sframe_or_buffer_changed_p);
  2670.   defsubr (&Sopen_termscript);
  2671.   defsubr (&Sding);
  2672.   defsubr (&Ssit_for);
  2673.   defsubr (&Ssleep_for);
  2674.   defsubr (&Ssend_string_to_terminal);
  2675.  
  2676.   frame_and_buffer_state = Fmake_vector (make_number (20), Qlambda);
  2677.   staticpro (&frame_and_buffer_state);
  2678.  
  2679.   Qdisplay_table = intern ("display-table");
  2680.   staticpro (&Qdisplay_table);
  2681.  
  2682.   DEFVAR_INT ("baud-rate", &baud_rate,
  2683.     "*The output baud rate of the terminal.\n\
  2684. On most systems, changing this value will affect the amount of padding\n\
  2685. and the other strategic decisions made during redisplay.");
  2686.   DEFVAR_BOOL ("inverse-video", &inverse_video,
  2687.     "*Non-nil means invert the entire frame display.\n\
  2688. This means everything is in inverse video which otherwise would not be.");
  2689.   DEFVAR_BOOL ("visible-bell", &visible_bell,
  2690.     "*Non-nil means try to flash the frame to represent a bell.");
  2691.   DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter,
  2692.     "*Non-nil means no need to redraw entire frame after suspending.\n\
  2693. A non-nil value is useful if the terminal can automatically preserve\n\
  2694. Emacs's frame display when you reenter Emacs.\n\
  2695. It is up to you to set this variable if your terminal can do that.");
  2696.   DEFVAR_LISP ("window-system", &Vwindow_system,
  2697.     "A symbol naming the window-system under which Emacs is running\n\
  2698. \(such as `x'), or nil if emacs is running on an ordinary terminal.");
  2699.   DEFVAR_LISP ("window-system-version", &Vwindow_system_version,
  2700.     "The version number of the window system in use.\n\
  2701. For X windows, this is 10 or 11.");
  2702.   DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area,
  2703.     "Non-nil means put cursor in minibuffer, at end of any message there.");
  2704.   DEFVAR_LISP ("glyph-table", &Vglyph_table,
  2705.     "Table defining how to output a glyph code to the frame.\n\
  2706. If not nil, this is a vector indexed by glyph code to define the glyph.\n\
  2707. Each element can be:\n\
  2708.  integer: a glyph code which this glyph is an alias for.\n\
  2709.  string: output this glyph using that string (not impl. in X windows).\n\
  2710.  nil: this glyph mod 256 is char code to output,\n\
  2711.     and this glyph / 256 is face code for X windows (see `face-id').");
  2712.   Vglyph_table = Qnil;
  2713.  
  2714.   DEFVAR_LISP ("standard-display-table", &Vstandard_display_table,
  2715.     "Display table to use for buffers that specify none.\n\
  2716. See `buffer-display-table' for more information.");
  2717.   Vstandard_display_table = Qnil;
  2718.  
  2719.   /* Initialize `window-system', unless init_display already decided it.  */
  2720. #ifdef CANNOT_DUMP
  2721.   if (noninteractive)
  2722. #endif
  2723.     {
  2724.       Vwindow_system = Qnil;
  2725.       Vwindow_system_version = Qnil;
  2726.     }
  2727. }
  2728.