1*59810Shibler /* Newly written part of redisplay code.
2*59810Shibler Copyright (C) 1985, 1986, 1987, 1988, 1990 Free Software Foundation, Inc.
3*59810Shibler
4*59810Shibler This file is part of GNU Emacs.
5*59810Shibler
6*59810Shibler GNU Emacs is free software; you can redistribute it and/or modify
7*59810Shibler it under the terms of the GNU General Public License as published by
8*59810Shibler the Free Software Foundation; either version 1, or (at your option)
9*59810Shibler any later version.
10*59810Shibler
11*59810Shibler GNU Emacs is distributed in the hope that it will be useful,
12*59810Shibler but WITHOUT ANY WARRANTY; without even the implied warranty of
13*59810Shibler MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*59810Shibler GNU General Public License for more details.
15*59810Shibler
16*59810Shibler You should have received a copy of the GNU General Public License
17*59810Shibler along with GNU Emacs; see the file COPYING. If not, write to
18*59810Shibler the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19*59810Shibler
20*59810Shibler
21*59810Shibler #include <signal.h>
22*59810Shibler
23*59810Shibler #include "config.h"
24*59810Shibler #include <stdio.h>
25*59810Shibler
26*59810Shibler #ifdef HAVE_TIMEVAL
27*59810Shibler #ifdef HPUX
28*59810Shibler #include <time.h>
29*59810Shibler #else
30*59810Shibler #include <sys/time.h>
31*59810Shibler #endif
32*59810Shibler #endif
33*59810Shibler
34*59810Shibler #ifdef HAVE_TERMIO
35*59810Shibler #include <termio.h>
36*59810Shibler #ifdef TCOUTQ
37*59810Shibler #undef TIOCOUTQ
38*59810Shibler #define TIOCOUTQ TCOUTQ
39*59810Shibler #include <fcntl.h>
40*59810Shibler #endif /* TCOUTQ defined */
41*59810Shibler #else
42*59810Shibler #ifndef VMS
43*59810Shibler #include <sys/ioctl.h>
44*59810Shibler #endif /* not VMS */
45*59810Shibler #endif /* not HAVE_TERMIO */
46*59810Shibler
47*59810Shibler /* Allow m- file to inhibit use of FIONREAD. */
48*59810Shibler #ifdef BROKEN_FIONREAD
49*59810Shibler #undef FIONREAD
50*59810Shibler #endif
51*59810Shibler
52*59810Shibler /* We are unable to use interrupts if FIONREAD is not available,
53*59810Shibler so flush SIGIO so we won't try. */
54*59810Shibler #ifndef FIONREAD
55*59810Shibler #ifdef SIGIO
56*59810Shibler #undef SIGIO
57*59810Shibler #endif
58*59810Shibler #endif
59*59810Shibler
60*59810Shibler #undef NULL
61*59810Shibler
62*59810Shibler #include "termchar.h"
63*59810Shibler #include "termopts.h"
64*59810Shibler #include "cm.h"
65*59810Shibler #include "dispextern.h"
66*59810Shibler #include "lisp.h"
67*59810Shibler #include "buffer.h"
68*59810Shibler #include "window.h"
69*59810Shibler #include "commands.h"
70*59810Shibler
71*59810Shibler #define max(a, b) ((a) > (b) ? (a) : (b))
72*59810Shibler #define min(a, b) ((a) < (b) ? (a) : (b))
73*59810Shibler
74*59810Shibler #ifndef PENDING_OUTPUT_COUNT
75*59810Shibler /* Get number of chars of output now in the buffer of a stdio stream.
76*59810Shibler This ought to be built in in stdio, but it isn't.
77*59810Shibler Some s- files override this because their stdio internals differ. */
78*59810Shibler #ifdef __GNU_LIBRARY__
79*59810Shibler #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bp - (FILE)->__buf)
80*59810Shibler #else
81*59810Shibler #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
82*59810Shibler #endif
83*59810Shibler #endif /* No PENDING_OUTPUT_COUNT */
84*59810Shibler
85*59810Shibler /* Nonzero means do not assume anything about current
86*59810Shibler contents of actual terminal screen */
87*59810Shibler
88*59810Shibler int screen_garbaged;
89*59810Shibler
90*59810Shibler /* Desired terminal cursor position (to show position of point),
91*59810Shibler origin zero */
92*59810Shibler
93*59810Shibler int cursor_hpos, cursor_vpos;
94*59810Shibler
95*59810Shibler /* Nonzero means last display completed and cursor is really at
96*59810Shibler cursor_hpos, cursor_vpos. Zero means it was preempted. */
97*59810Shibler
98*59810Shibler int display_completed;
99*59810Shibler
100*59810Shibler /* Lisp variable visible-bell; enables use of screen-flash
101*59810Shibler instead of audible bell. */
102*59810Shibler
103*59810Shibler int visible_bell;
104*59810Shibler
105*59810Shibler /* Invert the color of the whole screen, at a low level. */
106*59810Shibler
107*59810Shibler int inverse_video;
108*59810Shibler
109*59810Shibler /* Line speed of the terminal. */
110*59810Shibler
111*59810Shibler int baud_rate;
112*59810Shibler
113*59810Shibler /* nil or a symbol naming the window system
114*59810Shibler under which emacs is running
115*59810Shibler ('x is the only current possibility). */
116*59810Shibler
117*59810Shibler Lisp_Object Vwindow_system;
118*59810Shibler
119*59810Shibler /* Version number of window system, or nil if no window system. */
120*59810Shibler
121*59810Shibler Lisp_Object Vwindow_system_version;
122*59810Shibler
123*59810Shibler /* Nonzero means reading single-character input with prompt
124*59810Shibler so put cursor on minibuffer after the prompt. */
125*59810Shibler
126*59810Shibler int cursor_in_echo_area;
127*59810Shibler
128*59810Shibler /* Description of actual screen contents. */
129*59810Shibler
130*59810Shibler struct matrix *current_screen;
131*59810Shibler
132*59810Shibler /* Description of desired screen contents. */
133*59810Shibler
134*59810Shibler struct matrix *new_screen;
135*59810Shibler
136*59810Shibler /* Buffer sometimes used to hold partial screen contents. */
137*59810Shibler
138*59810Shibler struct matrix *temp_screen;
139*59810Shibler
140*59810Shibler /* Stdio stream being used for copy of all terminal output. */
141*59810Shibler
142*59810Shibler FILE *termscript;
143*59810Shibler
144*59810Shibler /* Structure for info on cursor positioning */
145*59810Shibler
146*59810Shibler struct cm Wcm;
147*59810Shibler
148*59810Shibler int in_display; /* 1 if in redisplay: can't handle SIGWINCH now. */
149*59810Shibler
150*59810Shibler int delayed_size_change; /* 1 means SIGWINCH happened when not safe. */
151*59810Shibler int delayed_screen_height; /* Remembered new screen height. */
152*59810Shibler int delayed_screen_width; /* Remembered new screen width. */
153*59810Shibler
154*59810Shibler /* This buffer records the history of display preemption. */
155*59810Shibler
156*59810Shibler struct preempt
157*59810Shibler {
158*59810Shibler /* Number of keyboard characters read so far at preempt. */
159*59810Shibler int keyboard_char_count;
160*59810Shibler /* Vertical position at which preemption occurred. */
161*59810Shibler int vpos;
162*59810Shibler };
163*59810Shibler
164*59810Shibler #define N_PREEMPTIONS 50
165*59810Shibler
166*59810Shibler /* Circular buffer recording recent display preemptions. */
167*59810Shibler struct preempt preemptions[N_PREEMPTIONS];
168*59810Shibler
169*59810Shibler /* Index of next element in preemptions. */
170*59810Shibler int preemption_index;
171*59810Shibler
172*59810Shibler /* Set these variables in the debugger to force a display preemption. */
173*59810Shibler int debug_preemption_vpos = -1;
174*59810Shibler int debug_preemption_char_count = -1;
175*59810Shibler
176*59810Shibler extern int num_input_chars;
177*59810Shibler
178*59810Shibler /* Free and reallocate current_screen and new_screen. */
179*59810Shibler
180*59810Shibler struct matrix *make_screen_structure ();
181*59810Shibler
remake_screen_structures()182*59810Shibler remake_screen_structures ()
183*59810Shibler {
184*59810Shibler if (current_screen)
185*59810Shibler free_screen_structure (current_screen);
186*59810Shibler if (new_screen)
187*59810Shibler free_screen_structure (new_screen);
188*59810Shibler if (temp_screen)
189*59810Shibler free_screen_structure (temp_screen);
190*59810Shibler
191*59810Shibler current_screen = make_screen_structure (0);
192*59810Shibler new_screen = make_screen_structure (0);
193*59810Shibler temp_screen = make_screen_structure (1);
194*59810Shibler
195*59810Shibler if (message_buf)
196*59810Shibler message_buf = (char *) xrealloc (message_buf, screen_width + 1);
197*59810Shibler else
198*59810Shibler message_buf = (char *) xmalloc (screen_width + 1);
199*59810Shibler }
200*59810Shibler
201*59810Shibler struct matrix *
make_screen_structure(empty)202*59810Shibler make_screen_structure (empty)
203*59810Shibler int empty;
204*59810Shibler {
205*59810Shibler int i;
206*59810Shibler struct matrix *new = (struct matrix *) xmalloc (sizeof (struct matrix));
207*59810Shibler
208*59810Shibler new->height = screen_height;
209*59810Shibler new->width = screen_width;
210*59810Shibler new->highlight = (char *) xmalloc (screen_height);
211*59810Shibler new->enable = (char *) xmalloc (screen_height);
212*59810Shibler new->contents = (unsigned char **) xmalloc (screen_height * sizeof (char *));
213*59810Shibler new->used = (int *) xmalloc (screen_height * sizeof (int));
214*59810Shibler if (empty)
215*59810Shibler {
216*59810Shibler /* Make the buffer used by decode_mode_spec. */
217*59810Shibler new->total_contents = (unsigned char *) xmalloc (screen_width + 2);
218*59810Shibler bzero (new->contents, screen_height * sizeof (char *));
219*59810Shibler }
220*59810Shibler else
221*59810Shibler {
222*59810Shibler /* Add 2 to leave extra bytes at beginning and end of each line. */
223*59810Shibler new->total_contents = (unsigned char *) xmalloc (screen_height * (screen_width + 2));
224*59810Shibler bzero (new->total_contents, screen_height * (screen_width + 2));
225*59810Shibler for (i = 0; i < screen_height; i++)
226*59810Shibler new->contents[i] = new->total_contents + i * (screen_width + 2) + 1;
227*59810Shibler }
228*59810Shibler bzero (new->enable, screen_height);
229*59810Shibler return new;
230*59810Shibler }
231*59810Shibler
232*59810Shibler free_screen_structure (matrix)
233*59810Shibler struct matrix *matrix;
234*59810Shibler {
235*59810Shibler if (matrix->total_contents)
236*59810Shibler free (matrix->total_contents);
237*59810Shibler free (matrix->contents);
238*59810Shibler free (matrix->highlight);
239*59810Shibler free (matrix->enable);
240*59810Shibler free (matrix->used);
241*59810Shibler free (matrix);
242*59810Shibler }
243*59810Shibler
244*59810Shibler /* Return the hash code of contents of line VPOS of screen-matrix M. */
245*59810Shibler
246*59810Shibler int
line_hash_code(m,vpos)247*59810Shibler line_hash_code (m, vpos)
248*59810Shibler struct matrix *m;
249*59810Shibler int vpos;
250*59810Shibler {
251*59810Shibler register unsigned char *body;
252*59810Shibler register int h = 0;
253*59810Shibler /* Give all lighlighted lines the same hash code
254*59810Shibler so as to encourage scrolling to leave them in place. */
255*59810Shibler if (m->highlight[vpos])
256*59810Shibler return -1;
257*59810Shibler
258*59810Shibler body = m->contents[vpos];
259*59810Shibler
260*59810Shibler if (must_write_spaces)
261*59810Shibler {
262*59810Shibler while (1)
263*59810Shibler {
264*59810Shibler int c = *body++;
265*59810Shibler if (c == 0)
266*59810Shibler break;
267*59810Shibler h = (((h << 4) + (h >> 24)) & 0x0fffffff) + c - ' ';
268*59810Shibler }
269*59810Shibler }
270*59810Shibler else
271*59810Shibler {
272*59810Shibler while (1)
273*59810Shibler {
274*59810Shibler int c = *body++;
275*59810Shibler if (c == 0)
276*59810Shibler break;
277*59810Shibler h = (((h << 4) + (h >> 24)) & 0x0fffffff) + c;
278*59810Shibler }
279*59810Shibler }
280*59810Shibler if (h)
281*59810Shibler return h;
282*59810Shibler return 1;
283*59810Shibler }
284*59810Shibler
285*59810Shibler /* Return number of characters in line in M at vpos VPOS,
286*59810Shibler except don't count leading and trailing spaces
287*59810Shibler unless the terminal requires those to be explicitly output. */
288*59810Shibler
289*59810Shibler int
line_draw_cost(m,vpos)290*59810Shibler line_draw_cost (m, vpos)
291*59810Shibler struct matrix *m;
292*59810Shibler int vpos;
293*59810Shibler {
294*59810Shibler register unsigned char *body;
295*59810Shibler register int i;
296*59810Shibler
297*59810Shibler if (must_write_spaces)
298*59810Shibler return m->used[vpos];
299*59810Shibler
300*59810Shibler body = m->contents[vpos];
301*59810Shibler for (i = m->used[vpos]; i > 0 && body[i - 2] == ' '; i--);
302*59810Shibler
303*59810Shibler i -= count_blanks (body);
304*59810Shibler return max (i, 0);
305*59810Shibler }
306*59810Shibler
307*59810Shibler /* The functions on this page are the interface from xdisp.c to redisplay.
308*59810Shibler
309*59810Shibler The only other interface into redisplay is through setting
310*59810Shibler cursor_hpos and cursor_vpos (in xdisp.c) and setting screen_garbaged. */
311*59810Shibler
312*59810Shibler /* cancel_line eliminates any request to display a line at position `vpos' */
313*59810Shibler
cancel_line(vpos)314*59810Shibler cancel_line (vpos)
315*59810Shibler int vpos;
316*59810Shibler {
317*59810Shibler new_screen->enable[vpos] = 0;
318*59810Shibler }
319*59810Shibler
clear_screen_records()320*59810Shibler clear_screen_records ()
321*59810Shibler {
322*59810Shibler int i;
323*59810Shibler
324*59810Shibler bzero (current_screen->enable, screen_height);
325*59810Shibler }
326*59810Shibler
327*59810Shibler /* Get ready to display on line `vpos'
328*59810Shibler and set it up for outputting starting at `hpos' within it.
329*59810Shibler Return the text string where that line is stored. */
330*59810Shibler
331*59810Shibler unsigned char *
get_display_line(vpos,hpos)332*59810Shibler get_display_line (vpos, hpos)
333*59810Shibler int vpos;
334*59810Shibler register int hpos;
335*59810Shibler {
336*59810Shibler if (new_screen->enable[vpos] && new_screen->used[vpos] > hpos)
337*59810Shibler abort ();
338*59810Shibler if (! new_screen->enable[vpos])
339*59810Shibler {
340*59810Shibler new_screen->used[vpos] = 0;
341*59810Shibler new_screen->highlight[vpos] = 0;
342*59810Shibler new_screen->enable[vpos] = 1;
343*59810Shibler }
344*59810Shibler
345*59810Shibler if (hpos > new_screen->used[vpos])
346*59810Shibler {
347*59810Shibler unsigned char *p = new_screen->contents[vpos] + new_screen->used[vpos];
348*59810Shibler unsigned char *end = new_screen->contents[vpos] + hpos;
349*59810Shibler new_screen->used[vpos] = hpos;
350*59810Shibler while (p != end)
351*59810Shibler *p++ = ' ';
352*59810Shibler }
353*59810Shibler
354*59810Shibler return new_screen->contents[vpos];
355*59810Shibler }
356*59810Shibler
357*59810Shibler /* Scroll lines from vpos `from' up to but not including vpos `end'
358*59810Shibler down by `amount' lines (`amount' may be negative).
359*59810Shibler Returns nonzero if done, zero if terminal cannot scroll them. */
360*59810Shibler
361*59810Shibler int
scroll_screen_lines(from,end,amount)362*59810Shibler scroll_screen_lines (from, end, amount)
363*59810Shibler int from, end, amount;
364*59810Shibler {
365*59810Shibler register int i;
366*59810Shibler
367*59810Shibler if (!line_ins_del_ok)
368*59810Shibler return 0;
369*59810Shibler
370*59810Shibler if (amount == 0)
371*59810Shibler return 1;
372*59810Shibler if (amount > 0)
373*59810Shibler {
374*59810Shibler set_terminal_window (end + amount);
375*59810Shibler if (!scroll_region_ok)
376*59810Shibler ins_del_lines (end, -amount);
377*59810Shibler ins_del_lines (from, amount);
378*59810Shibler set_terminal_window (0);
379*59810Shibler
380*59810Shibler rotate_vector (current_screen->contents + from,
381*59810Shibler sizeof (char *) * (end + amount - from),
382*59810Shibler amount * sizeof (char *));
383*59810Shibler safe_bcopy (current_screen->used + from,
384*59810Shibler current_screen->used + from + amount,
385*59810Shibler (end - from) * sizeof current_screen->used[0]);
386*59810Shibler safe_bcopy (current_screen->highlight + from,
387*59810Shibler current_screen->highlight + from + amount,
388*59810Shibler (end - from) * sizeof current_screen->highlight[0]);
389*59810Shibler safe_bcopy (current_screen->enable + from,
390*59810Shibler current_screen->enable + from + amount,
391*59810Shibler (end - from) * sizeof current_screen->enable[0]);
392*59810Shibler /* Mark the lines made empty by scrolling as enabled, empty and
393*59810Shibler normal video. */
394*59810Shibler bzero (current_screen->used + from,
395*59810Shibler amount * sizeof current_screen->used[0]);
396*59810Shibler bzero (current_screen->highlight + from,
397*59810Shibler amount * sizeof current_screen->highlight[0]);
398*59810Shibler for (i = from; i < from + amount; i++)
399*59810Shibler {
400*59810Shibler current_screen->contents[i][0] = '\0';
401*59810Shibler current_screen->enable[i] = 1;
402*59810Shibler }
403*59810Shibler }
404*59810Shibler if (amount < 0)
405*59810Shibler {
406*59810Shibler set_terminal_window (end);
407*59810Shibler ins_del_lines (from + amount, amount);
408*59810Shibler if (!scroll_region_ok)
409*59810Shibler ins_del_lines (end + amount, -amount);
410*59810Shibler set_terminal_window (0);
411*59810Shibler
412*59810Shibler rotate_vector (current_screen->contents + from + amount,
413*59810Shibler sizeof (char *) * (end - from - amount),
414*59810Shibler (end - from) * sizeof (char *));
415*59810Shibler safe_bcopy (current_screen->used + from,
416*59810Shibler current_screen->used + from + amount,
417*59810Shibler (end - from) * sizeof current_screen->used[0]);
418*59810Shibler safe_bcopy (current_screen->highlight + from,
419*59810Shibler current_screen->highlight + from + amount,
420*59810Shibler (end - from) * sizeof current_screen->highlight[0]);
421*59810Shibler safe_bcopy (current_screen->enable + from,
422*59810Shibler current_screen->enable + from + amount,
423*59810Shibler (end - from) * sizeof current_screen->enable[0]);
424*59810Shibler /* Mark the lines made empty by scrolling as enabled, empty and
425*59810Shibler normal video. */
426*59810Shibler bzero (current_screen->used + end + amount,
427*59810Shibler - amount * sizeof current_screen->used[0]);
428*59810Shibler bzero (current_screen->highlight + end + amount,
429*59810Shibler - amount * sizeof current_screen->highlight[0]);
430*59810Shibler for (i = end + amount; i < end; i++)
431*59810Shibler {
432*59810Shibler current_screen->contents[i][0] = '\0';
433*59810Shibler current_screen->enable[i] = 1;
434*59810Shibler }
435*59810Shibler }
436*59810Shibler return 1;
437*59810Shibler }
438*59810Shibler
439*59810Shibler /* Rotate a vector of SIZE bytes, by DISTANCE bytes.
440*59810Shibler DISTANCE may be negative. */
441*59810Shibler
rotate_vector(vector,size,distance)442*59810Shibler rotate_vector (vector, size, distance)
443*59810Shibler char *vector;
444*59810Shibler int size;
445*59810Shibler int distance;
446*59810Shibler {
447*59810Shibler char *temp = (char *) alloca (size);
448*59810Shibler
449*59810Shibler if (distance < 0)
450*59810Shibler distance += size;
451*59810Shibler
452*59810Shibler bcopy (vector, temp + distance, size - distance);
453*59810Shibler bcopy (vector + size - distance, temp, distance);
454*59810Shibler bcopy (temp, vector, size);
455*59810Shibler }
456*59810Shibler
457*59810Shibler /* Like bcopy except never gets confused by overlap. */
458*59810Shibler
safe_bcopy(from,to,size)459*59810Shibler safe_bcopy (from, to, size)
460*59810Shibler char *from, *to;
461*59810Shibler int size;
462*59810Shibler {
463*59810Shibler register char *endf;
464*59810Shibler register char *endt;
465*59810Shibler
466*59810Shibler if (size == 0)
467*59810Shibler return;
468*59810Shibler if (from > to)
469*59810Shibler {
470*59810Shibler /* If destination is lower in memory, we can go from the beginning. */
471*59810Shibler endf = from + size;
472*59810Shibler while (from != endf)
473*59810Shibler *to++ = *from++;
474*59810Shibler return;
475*59810Shibler }
476*59810Shibler
477*59810Shibler /* If destination is higher in memory, we can go backwards from the end. */
478*59810Shibler endf = from + size;
479*59810Shibler endt = to + size;
480*59810Shibler
481*59810Shibler do
482*59810Shibler *--endt = *--endf;
483*59810Shibler while (endf != from);
484*59810Shibler }
485*59810Shibler
486*59810Shibler /* After updating a window w that isn't the full screen wide,
487*59810Shibler copy all the columns that w does not occupy
488*59810Shibler from current_screen to new_screen,
489*59810Shibler so that update_screen will not change those columns. */
490*59810Shibler
491*59810Shibler preserve_other_columns (w)
492*59810Shibler struct window *w;
493*59810Shibler {
494*59810Shibler register int vpos;
495*59810Shibler int start = XFASTINT (w->left);
496*59810Shibler int end = XFASTINT (w->left) + XFASTINT (w->width);
497*59810Shibler int bot = XFASTINT (w->top) + XFASTINT (w->height);
498*59810Shibler
499*59810Shibler for (vpos = XFASTINT (w->top); vpos < bot; vpos++)
500*59810Shibler {
501*59810Shibler if (current_screen->enable[vpos] && new_screen->enable[vpos])
502*59810Shibler {
503*59810Shibler if (start > 0)
504*59810Shibler {
505*59810Shibler int len;
506*59810Shibler
507*59810Shibler bcopy (current_screen->contents[vpos],
508*59810Shibler new_screen->contents[vpos], start);
509*59810Shibler len = min (start, current_screen->used[vpos]);
510*59810Shibler if (new_screen->used[vpos] < len)
511*59810Shibler new_screen->used[vpos] = len;
512*59810Shibler }
513*59810Shibler if (current_screen->used[vpos] > end
514*59810Shibler && new_screen->used[vpos] < current_screen->used[vpos])
515*59810Shibler {
516*59810Shibler while (new_screen->used[vpos] < end)
517*59810Shibler new_screen->contents[vpos][new_screen->used[vpos]++] = ' ';
518*59810Shibler bcopy (current_screen->contents[vpos] + end,
519*59810Shibler new_screen->contents[vpos] + end,
520*59810Shibler current_screen->used[vpos] - end);
521*59810Shibler new_screen->used[vpos] = current_screen->used[vpos];
522*59810Shibler }
523*59810Shibler }
524*59810Shibler }
525*59810Shibler }
526*59810Shibler
527*59810Shibler /* On discovering that the redisplay for a window was no good,
528*59810Shibler cancel the columns of that window,
529*59810Shibler so that when the window is displayed over again
530*59810Shibler get_display_line will not complain. */
531*59810Shibler
532*59810Shibler cancel_my_columns (w)
533*59810Shibler struct window *w;
534*59810Shibler {
535*59810Shibler register int vpos;
536*59810Shibler register int start = XFASTINT (w->left);
537*59810Shibler register int bot = XFASTINT (w->top) + XFASTINT (w->height);
538*59810Shibler
539*59810Shibler for (vpos = XFASTINT (w->top); vpos < bot; vpos++)
540*59810Shibler if (new_screen->enable[vpos] && new_screen->used[vpos] >= start)
541*59810Shibler new_screen->used[vpos] = start;
542*59810Shibler }
543*59810Shibler
544*59810Shibler /* These functions try to perform directly and immediately on the screen
545*59810Shibler the necessary output for one change in the buffer.
546*59810Shibler They may return 0 meaning nothing was done if anything is difficult,
547*59810Shibler or 1 meaning the output was performed properly.
548*59810Shibler They assume that the screen was up to date before the buffer
549*59810Shibler change being displayed. THey make various other assumptions too;
550*59810Shibler see command_loop_1 where these are called. */
551*59810Shibler
552*59810Shibler int
direct_output_for_insert(c)553*59810Shibler direct_output_for_insert (c)
554*59810Shibler int c;
555*59810Shibler {
556*59810Shibler #ifndef COMPILER_REGISTER_BUG
557*59810Shibler register
558*59810Shibler #endif COMPILER_REGISTER_BUG
559*59810Shibler struct window *w = XWINDOW (selected_window);
560*59810Shibler #ifndef COMPILER_REGISTER_BUG
561*59810Shibler register
562*59810Shibler #endif COMPILER_REGISTER_BUG
563*59810Shibler int hpos = cursor_hpos;
564*59810Shibler #ifndef COMPILER_REGISTER_BUG
565*59810Shibler register
566*59810Shibler #endif COMPILER_REGISTER_BUG
567*59810Shibler int vpos = cursor_vpos;
568*59810Shibler
569*59810Shibler /* Give up if about to continue line */
570*59810Shibler if (hpos - XFASTINT (w->left) + 1 + 1 >= XFASTINT (w->width)
571*59810Shibler
572*59810Shibler /* Avoid losing if cursor is in invisible text off left margin */
573*59810Shibler || XINT (w->hscroll) && hpos == XFASTINT (w->left)
574*59810Shibler
575*59810Shibler /* Give up if cursor outside window (in minibuf, probably) */
576*59810Shibler || cursor_vpos < XFASTINT (w->top)
577*59810Shibler || cursor_vpos >= XFASTINT (w->top) + XFASTINT (w->height)
578*59810Shibler
579*59810Shibler /* Give up if cursor not really at cursor_hpos, cursor_vpos */
580*59810Shibler || !display_completed
581*59810Shibler
582*59810Shibler /* Give up if w is minibuffer and a message is being displayed there */
583*59810Shibler || EQ (selected_window, minibuf_window) && echo_area_contents)
584*59810Shibler return 0;
585*59810Shibler
586*59810Shibler current_screen->contents[vpos][hpos] = c;
587*59810Shibler unchanged_modified = MODIFF;
588*59810Shibler beg_unchanged = GPT - BEG;
589*59810Shibler XFASTINT (w->last_point) = point;
590*59810Shibler XFASTINT (w->last_point_x) = cursor_hpos;
591*59810Shibler XFASTINT (w->last_modified) = MODIFF;
592*59810Shibler
593*59810Shibler reassert_line_highlight (0, cursor_vpos);
594*59810Shibler output_chars (¤t_screen->contents[vpos][hpos], 1);
595*59810Shibler fflush (stdout);
596*59810Shibler ++cursor_hpos;
597*59810Shibler if (hpos == current_screen->used[vpos])
598*59810Shibler {
599*59810Shibler current_screen->used[vpos] = hpos + 1;
600*59810Shibler current_screen->contents[vpos][hpos + 1] = 0;
601*59810Shibler }
602*59810Shibler return 1;
603*59810Shibler }
604*59810Shibler
605*59810Shibler int
direct_output_forward_char(n)606*59810Shibler direct_output_forward_char (n)
607*59810Shibler int n;
608*59810Shibler {
609*59810Shibler register struct window *w = XWINDOW (selected_window);
610*59810Shibler
611*59810Shibler /* Avoid losing if cursor is in invisible text off left margin */
612*59810Shibler if (XINT (w->hscroll) && cursor_hpos == XFASTINT (w->left))
613*59810Shibler return 0;
614*59810Shibler
615*59810Shibler cursor_hpos += n;
616*59810Shibler XFASTINT (w->last_point_x) = cursor_hpos;
617*59810Shibler XFASTINT (w->last_point) = point;
618*59810Shibler move_cursor (cursor_vpos, cursor_hpos);
619*59810Shibler fflush (stdout);
620*59810Shibler return 1;
621*59810Shibler }
622*59810Shibler
623*59810Shibler /* Update the actual terminal screen based on the data in new_screen.
624*59810Shibler Value is nonzero if redisplay stopped due to pending input.
625*59810Shibler FORCE nonzero means do not stop for pending input. */
626*59810Shibler
update_screen(force,inhibit_hairy_id)627*59810Shibler update_screen (force, inhibit_hairy_id)
628*59810Shibler int force;
629*59810Shibler int inhibit_hairy_id;
630*59810Shibler {
631*59810Shibler register struct display_line **p;
632*59810Shibler register struct display_line *l, *lnew;
633*59810Shibler register int i;
634*59810Shibler int pause;
635*59810Shibler int preempt_count = baud_rate / 2400 + 1;
636*59810Shibler extern input_pending;
637*59810Shibler
638*59810Shibler if (screen_height == 0) abort (); /* Some bug zeros some core */
639*59810Shibler
640*59810Shibler detect_input_pending ();
641*59810Shibler if (!force
642*59810Shibler && ((num_input_chars == debug_preemption_char_count
643*59810Shibler && debug_preemption_vpos == screen_height - 1)
644*59810Shibler || input_pending))
645*59810Shibler {
646*59810Shibler pause = screen_height;
647*59810Shibler goto do_pause;
648*59810Shibler }
649*59810Shibler
650*59810Shibler update_begin ();
651*59810Shibler
652*59810Shibler if (!line_ins_del_ok)
653*59810Shibler inhibit_hairy_id = 1;
654*59810Shibler
655*59810Shibler /* Don't compute for i/d line if just want cursor motion. */
656*59810Shibler for (i = 0; i < screen_height; i++)
657*59810Shibler if (new_screen->enable)
658*59810Shibler break;
659*59810Shibler
660*59810Shibler /* Try doing i/d line, if not yet inhibited. */
661*59810Shibler if (!inhibit_hairy_id && i < screen_height)
662*59810Shibler force |= scrolling ();
663*59810Shibler
664*59810Shibler /* Update the individual lines as needed. Do bottom line first. */
665*59810Shibler
666*59810Shibler if (new_screen->enable[screen_height - 1])
667*59810Shibler update_line (screen_height - 1);
668*59810Shibler for (i = 0; i < screen_height - 1 && (force || !input_pending); i++)
669*59810Shibler {
670*59810Shibler if (!force && num_input_chars == debug_preemption_char_count
671*59810Shibler && debug_preemption_vpos == i)
672*59810Shibler break;
673*59810Shibler if (new_screen->enable[i])
674*59810Shibler {
675*59810Shibler /* Flush out every so many lines.
676*59810Shibler Also flush out if likely to have more than 1k buffered
677*59810Shibler otherwise. I'm told that telnet connections get really
678*59810Shibler screwed by more than 1k output at once. */
679*59810Shibler int outq = PENDING_OUTPUT_COUNT (stdout);
680*59810Shibler if (outq > 900
681*59810Shibler || (outq > 20 && ((i - 1) % preempt_count == 0)))
682*59810Shibler {
683*59810Shibler fflush (stdout);
684*59810Shibler if (preempt_count == 1)
685*59810Shibler {
686*59810Shibler #ifdef TIOCOUTQ
687*59810Shibler if (ioctl (0, TIOCOUTQ, &outq) < 0)
688*59810Shibler /* Probably not a tty. Ignore the error and reset
689*59810Shibler * the outq count. */
690*59810Shibler outq = PENDING_OUTPUT_COUNT (stdout);
691*59810Shibler #endif
692*59810Shibler outq *= 10;
693*59810Shibler sleep (outq / baud_rate);
694*59810Shibler }
695*59810Shibler }
696*59810Shibler if ((i - 1) % preempt_count == 0)
697*59810Shibler detect_input_pending ();
698*59810Shibler /* Now update this line. */
699*59810Shibler update_line (i);
700*59810Shibler }
701*59810Shibler }
702*59810Shibler pause = (i < screen_height - 1) ? i + 1 : 0;
703*59810Shibler
704*59810Shibler /* Now just clean up termcap drivers and set cursor, etc. */
705*59810Shibler if (!pause)
706*59810Shibler {
707*59810Shibler if (cursor_in_echo_area < 0)
708*59810Shibler move_cursor (screen_height - 1, 0);
709*59810Shibler else if (cursor_in_echo_area > 0
710*59810Shibler && !current_screen->enable[screen_height - 1])
711*59810Shibler move_cursor (screen_height - 1, 0);
712*59810Shibler else if (cursor_in_echo_area)
713*59810Shibler move_cursor (screen_height - 1,
714*59810Shibler min (screen_width - 1,
715*59810Shibler current_screen->used[screen_height - 1]));
716*59810Shibler else
717*59810Shibler move_cursor (cursor_vpos, max (min (cursor_hpos, screen_width - 1), 0));
718*59810Shibler }
719*59810Shibler
720*59810Shibler update_end ();
721*59810Shibler
722*59810Shibler if (termscript)
723*59810Shibler fflush (termscript);
724*59810Shibler fflush (stdout);
725*59810Shibler
726*59810Shibler /* Here if output is preempted because input is detected. */
727*59810Shibler do_pause:
728*59810Shibler
729*59810Shibler if (screen_height == 0) abort (); /* Some bug zeros some core */
730*59810Shibler display_completed = !pause;
731*59810Shibler if (pause)
732*59810Shibler {
733*59810Shibler preemptions[preemption_index].vpos = pause - 1;
734*59810Shibler preemptions[preemption_index].keyboard_char_count = num_input_chars;
735*59810Shibler preemption_index++;
736*59810Shibler if (preemption_index == N_PREEMPTIONS)
737*59810Shibler preemption_index = 0;
738*59810Shibler }
739*59810Shibler
740*59810Shibler bzero (new_screen->enable, screen_height);
741*59810Shibler return pause;
742*59810Shibler }
743*59810Shibler
744*59810Shibler /* Called when about to quit, to check for doing so
745*59810Shibler at an improper time. */
746*59810Shibler
747*59810Shibler void
quit_error_check()748*59810Shibler quit_error_check ()
749*59810Shibler {
750*59810Shibler if (new_screen == 0)
751*59810Shibler return;
752*59810Shibler if (new_screen->enable[0])
753*59810Shibler abort ();
754*59810Shibler if (new_screen->enable[screen_height - 1])
755*59810Shibler abort ();
756*59810Shibler }
757*59810Shibler
758*59810Shibler /* Decide what insert/delete line to do, and do it */
759*59810Shibler
scrolling()760*59810Shibler scrolling ()
761*59810Shibler {
762*59810Shibler int unchanged_at_top, unchanged_at_bottom;
763*59810Shibler int window_size;
764*59810Shibler int changed_lines;
765*59810Shibler int *old_hash = (int *) alloca (screen_height * sizeof (int));
766*59810Shibler int *new_hash = (int *) alloca (screen_height * sizeof (int));
767*59810Shibler int *draw_cost = (int *) alloca (screen_height * sizeof (int));
768*59810Shibler register int i;
769*59810Shibler int free_at_end_vpos = screen_height;
770*59810Shibler
771*59810Shibler /* Compute hash codes of all the lines.
772*59810Shibler Also calculate number of changed lines,
773*59810Shibler number of unchanged lines at the beginning,
774*59810Shibler and number of unchanged lines at the end. */
775*59810Shibler
776*59810Shibler changed_lines = 0;
777*59810Shibler unchanged_at_top = 0;
778*59810Shibler unchanged_at_bottom = screen_height;
779*59810Shibler for (i = 0; i < screen_height; i++)
780*59810Shibler {
781*59810Shibler /* Give up on this scrolling if some old lines are not enabled. */
782*59810Shibler if (!current_screen->enable[i])
783*59810Shibler return 0;
784*59810Shibler old_hash[i] = line_hash_code (current_screen, i);
785*59810Shibler if (!new_screen->enable[i])
786*59810Shibler new_hash[i] = old_hash[i];
787*59810Shibler else
788*59810Shibler new_hash[i] = line_hash_code (new_screen, i);
789*59810Shibler if (old_hash[i] != new_hash[i])
790*59810Shibler {
791*59810Shibler changed_lines++;
792*59810Shibler unchanged_at_bottom = screen_height - i - 1;
793*59810Shibler }
794*59810Shibler else if (i == unchanged_at_top)
795*59810Shibler unchanged_at_top++;
796*59810Shibler /* If line is not changing, its redraw cost is infinite,
797*59810Shibler since we can't redraw it. */
798*59810Shibler if (!new_screen->enable[i])
799*59810Shibler draw_cost[i] = INFINITY;
800*59810Shibler else
801*59810Shibler draw_cost[i] = line_draw_cost (new_screen, i);
802*59810Shibler }
803*59810Shibler
804*59810Shibler /* If changed lines are few, don't allow preemption, don't scroll. */
805*59810Shibler if (changed_lines < baud_rate / 2400 || unchanged_at_bottom == screen_height)
806*59810Shibler return 1;
807*59810Shibler
808*59810Shibler window_size = screen_height - unchanged_at_top - unchanged_at_bottom;
809*59810Shibler
810*59810Shibler if (scroll_region_ok)
811*59810Shibler free_at_end_vpos -= unchanged_at_bottom;
812*59810Shibler else if (memory_below_screen)
813*59810Shibler free_at_end_vpos = -1;
814*59810Shibler
815*59810Shibler /* If large window, fast terminal and few lines in common between
816*59810Shibler current_screen and new_screen, don't bother with i/d calc. */
817*59810Shibler if (window_size >= 18 && baud_rate > 2400
818*59810Shibler && (window_size >=
819*59810Shibler 10 * scrolling_max_lines_saved (unchanged_at_top,
820*59810Shibler screen_height - unchanged_at_bottom,
821*59810Shibler old_hash, new_hash, draw_cost)))
822*59810Shibler return 0;
823*59810Shibler
824*59810Shibler scrolling_1 (window_size, unchanged_at_top, unchanged_at_bottom,
825*59810Shibler draw_cost + unchanged_at_top - 1,
826*59810Shibler old_hash + unchanged_at_top - 1,
827*59810Shibler new_hash + unchanged_at_top - 1,
828*59810Shibler free_at_end_vpos - unchanged_at_top);
829*59810Shibler
830*59810Shibler return 0;
831*59810Shibler }
832*59810Shibler
update_line(vpos)833*59810Shibler update_line (vpos)
834*59810Shibler int vpos;
835*59810Shibler {
836*59810Shibler register unsigned char *obody, *nbody, *op1, *op2, *np1;
837*59810Shibler int tem;
838*59810Shibler int osp, nsp, begmatch, endmatch, olen, nlen;
839*59810Shibler int save;
840*59810Shibler unsigned char *temp;
841*59810Shibler
842*59810Shibler /* Check for highlighting change. */
843*59810Shibler if (new_screen->highlight[vpos]
844*59810Shibler != (current_screen->enable[vpos] && current_screen->highlight[vpos]))
845*59810Shibler {
846*59810Shibler change_line_highlight (new_screen->highlight[vpos], vpos,
847*59810Shibler (current_screen->enable[vpos]
848*59810Shibler ? current_screen->used[vpos] : 0));
849*59810Shibler current_screen->enable[vpos] = 0;
850*59810Shibler }
851*59810Shibler else
852*59810Shibler reassert_line_highlight (new_screen->highlight[vpos], vpos);
853*59810Shibler
854*59810Shibler /* ??? */
855*59810Shibler if (! current_screen->enable[vpos])
856*59810Shibler {
857*59810Shibler olen = 0;
858*59810Shibler }
859*59810Shibler else
860*59810Shibler {
861*59810Shibler obody = current_screen->contents[vpos];
862*59810Shibler olen = current_screen->used[vpos];
863*59810Shibler if (! current_screen->highlight[vpos])
864*59810Shibler {
865*59810Shibler /* Note obody[-1] is always 0. */
866*59810Shibler if (!must_write_spaces)
867*59810Shibler while (obody[olen - 1] == ' ')
868*59810Shibler olen--;
869*59810Shibler }
870*59810Shibler else
871*59810Shibler {
872*59810Shibler /* For an inverse-video line, remember we gave it
873*59810Shibler spaces all the way to the screen edge
874*59810Shibler so that the reverse video extends all the way across. */
875*59810Shibler while (olen < screen_width - 1)
876*59810Shibler obody[olen++] = ' ';
877*59810Shibler }
878*59810Shibler }
879*59810Shibler
880*59810Shibler /* One way or another, this will enable the line being updated. */
881*59810Shibler current_screen->enable[vpos] = 1;
882*59810Shibler current_screen->used[vpos] = new_screen->used[vpos];
883*59810Shibler current_screen->highlight[vpos] = new_screen->highlight[vpos];
884*59810Shibler
885*59810Shibler if (!new_screen->enable[vpos])
886*59810Shibler {
887*59810Shibler nlen = 0;
888*59810Shibler goto just_erase;
889*59810Shibler }
890*59810Shibler
891*59810Shibler nbody = new_screen->contents[vpos];
892*59810Shibler nlen = new_screen->used[vpos];
893*59810Shibler
894*59810Shibler /* Pretend trailing spaces are not there at all,
895*59810Shibler unless for one reason or another we must write all spaces. */
896*59810Shibler /* We know that the previous character byte contains 0. */
897*59810Shibler if (! new_screen->highlight[vpos])
898*59810Shibler {
899*59810Shibler if (!must_write_spaces)
900*59810Shibler while (nbody[nlen - 1] == ' ')
901*59810Shibler nlen--;
902*59810Shibler }
903*59810Shibler else
904*59810Shibler {
905*59810Shibler /* For an inverse-video line, give it extra trailing spaces
906*59810Shibler all the way to the screen edge
907*59810Shibler so that the reverse video extends all the way across. */
908*59810Shibler while (nlen < screen_width - 1)
909*59810Shibler nbody[nlen++] = ' ';
910*59810Shibler }
911*59810Shibler
912*59810Shibler /* If there's no i/d char, quickly do the best we can without it. */
913*59810Shibler if (!char_ins_del_ok)
914*59810Shibler {
915*59810Shibler int i,j;
916*59810Shibler
917*59810Shibler for (i = 0; i < nlen; i++)
918*59810Shibler {
919*59810Shibler if (i >= olen || nbody[i] != obody[i])
920*59810Shibler {
921*59810Shibler /* We found a non-matching char. */
922*59810Shibler move_cursor (vpos, i);
923*59810Shibler for (j = 1; (i + j < nlen &&
924*59810Shibler (i + j >= olen || nbody[i+j] != obody[i+j]));
925*59810Shibler j++);
926*59810Shibler /* Output this run of non-matching chars. */
927*59810Shibler output_chars (nbody + i, j);
928*59810Shibler i += j - 1;
929*59810Shibler /* Now find the next non-match. */
930*59810Shibler }
931*59810Shibler }
932*59810Shibler /* Clear the rest of the line, or the non-clear part of it. */
933*59810Shibler if (olen > nlen)
934*59810Shibler {
935*59810Shibler move_cursor (vpos, nlen);
936*59810Shibler clear_end_of_line (olen);
937*59810Shibler }
938*59810Shibler
939*59810Shibler /* Exchange contents between current_screen and new_screen. */
940*59810Shibler temp = new_screen->contents[vpos];
941*59810Shibler new_screen->contents[vpos] = current_screen->contents[vpos];
942*59810Shibler current_screen->contents[vpos] = temp;
943*59810Shibler return;
944*59810Shibler }
945*59810Shibler
946*59810Shibler if (!olen)
947*59810Shibler {
948*59810Shibler nsp = (must_write_spaces || new_screen->highlight[vpos])
949*59810Shibler ? 0 : count_blanks (nbody);
950*59810Shibler if (nlen > nsp)
951*59810Shibler {
952*59810Shibler move_cursor (vpos, nsp);
953*59810Shibler output_chars (nbody + nsp, nlen - nsp);
954*59810Shibler }
955*59810Shibler
956*59810Shibler /* Exchange contents between current_screen and new_screen. */
957*59810Shibler temp = new_screen->contents[vpos];
958*59810Shibler new_screen->contents[vpos] = current_screen->contents[vpos];
959*59810Shibler current_screen->contents[vpos] = temp;
960*59810Shibler return;
961*59810Shibler }
962*59810Shibler
963*59810Shibler obody[olen] = 1;
964*59810Shibler save = nbody[nlen];
965*59810Shibler nbody[nlen] = 0;
966*59810Shibler
967*59810Shibler /* Compute number of leading blanks in old and new contents. */
968*59810Shibler osp = count_blanks (obody);
969*59810Shibler if (!new_screen->highlight[vpos])
970*59810Shibler nsp = count_blanks (nbody);
971*59810Shibler else
972*59810Shibler nsp = 0;
973*59810Shibler
974*59810Shibler /* Compute number of matching chars starting with first nonblank. */
975*59810Shibler begmatch = count_match (obody + osp, nbody + nsp);
976*59810Shibler
977*59810Shibler /* Spaces in new match implicit space past the end of old. */
978*59810Shibler /* A bug causing this to be a no-op was fixed in 18.29. */
979*59810Shibler if (!must_write_spaces && osp + begmatch == olen)
980*59810Shibler {
981*59810Shibler np1 = nbody + nsp;
982*59810Shibler while (np1[begmatch] == ' ')
983*59810Shibler begmatch++;
984*59810Shibler }
985*59810Shibler
986*59810Shibler /* Avoid doing insert/delete char
987*59810Shibler just cause number of leading spaces differs
988*59810Shibler when the following text does not match. */
989*59810Shibler if (begmatch == 0 && osp != nsp)
990*59810Shibler osp = nsp = min (osp, nsp);
991*59810Shibler
992*59810Shibler /* Find matching characters at end of line */
993*59810Shibler op1 = obody + olen;
994*59810Shibler np1 = nbody + nlen;
995*59810Shibler op2 = op1 + begmatch - min (olen - osp, nlen - nsp);
996*59810Shibler while (op1 > op2 && op1[-1] == np1[-1])
997*59810Shibler {
998*59810Shibler op1--;
999*59810Shibler np1--;
1000*59810Shibler }
1001*59810Shibler endmatch = obody + olen - op1;
1002*59810Shibler
1003*59810Shibler /* Put correct value back in nbody[nlen].
1004*59810Shibler This is important because direct_output_for_insert
1005*59810Shibler can write into the line at a later point. */
1006*59810Shibler nbody[nlen] = save;
1007*59810Shibler
1008*59810Shibler /* tem gets the distance to insert or delete.
1009*59810Shibler endmatch is how many characters we save by doing so.
1010*59810Shibler Is it worth it? */
1011*59810Shibler
1012*59810Shibler tem = (nlen - nsp) - (olen - osp);
1013*59810Shibler if (endmatch && tem && endmatch <= DCICcost[tem])
1014*59810Shibler endmatch = 0;
1015*59810Shibler
1016*59810Shibler /* nsp - osp is the distance to insert or delete.
1017*59810Shibler begmatch + endmatch is how much we save by doing so.
1018*59810Shibler Is it worth it? */
1019*59810Shibler
1020*59810Shibler if (begmatch + endmatch > 0 && nsp != osp
1021*59810Shibler && begmatch + endmatch <= DCICcost[nsp - osp])
1022*59810Shibler {
1023*59810Shibler begmatch = 0;
1024*59810Shibler endmatch = 0;
1025*59810Shibler osp = nsp = min (osp, nsp);
1026*59810Shibler }
1027*59810Shibler
1028*59810Shibler /* Now go through the line, inserting, writing and deleting as appropriate. */
1029*59810Shibler
1030*59810Shibler if (osp > nsp)
1031*59810Shibler {
1032*59810Shibler move_cursor (vpos, nsp);
1033*59810Shibler delete_chars (osp - nsp);
1034*59810Shibler }
1035*59810Shibler else if (nsp > osp)
1036*59810Shibler {
1037*59810Shibler /* If going to delete chars later in line
1038*59810Shibler and insert earlier in the line,
1039*59810Shibler must delete first to avoid losing data in the insert */
1040*59810Shibler if (endmatch && nlen < olen + nsp - osp)
1041*59810Shibler {
1042*59810Shibler move_cursor (vpos, nlen - endmatch + osp - nsp);
1043*59810Shibler delete_chars (olen + nsp - osp - nlen);
1044*59810Shibler olen = nlen - (nsp - osp);
1045*59810Shibler }
1046*59810Shibler move_cursor (vpos, osp);
1047*59810Shibler insert_chars ((char *)0, nsp - osp);
1048*59810Shibler }
1049*59810Shibler olen += nsp - osp;
1050*59810Shibler
1051*59810Shibler tem = nsp + begmatch + endmatch;
1052*59810Shibler if (nlen != tem || olen != tem)
1053*59810Shibler {
1054*59810Shibler move_cursor (vpos, nsp + begmatch);
1055*59810Shibler if (!endmatch || nlen == olen)
1056*59810Shibler {
1057*59810Shibler /* If new text being written reaches right margin,
1058*59810Shibler there is no need to do clear-to-eol at the end.
1059*59810Shibler (and it would not be safe, since cursor is not
1060*59810Shibler going to be "at the margin" after the text is done) */
1061*59810Shibler if (nlen == screen_width)
1062*59810Shibler olen = 0;
1063*59810Shibler output_chars (nbody + nsp + begmatch, nlen - tem);
1064*59810Shibler #ifdef obsolete
1065*59810Shibler /* the following code loses disastrously if tem == nlen.
1066*59810Shibler Rather than trying to fix that case, I am trying the simpler
1067*59810Shibler solution found above. */
1068*59810Shibler /* If the text reaches to the right margin,
1069*59810Shibler it will lose one way or another (depending on AutoWrap)
1070*59810Shibler to clear to end of line after outputting all the text.
1071*59810Shibler So pause with one character to go and clear the line then. */
1072*59810Shibler if (nlen == screen_width && fast_clear_end_of_line && olen > nlen)
1073*59810Shibler {
1074*59810Shibler /* endmatch must be zero, and tem must equal nsp + begmatch */
1075*59810Shibler output_chars (nbody + tem, nlen - tem - 1);
1076*59810Shibler clear_end_of_line (olen);
1077*59810Shibler olen = 0; /* Don't let it be cleared again later */
1078*59810Shibler output_chars (nbody + nlen - 1, 1);
1079*59810Shibler }
1080*59810Shibler else
1081*59810Shibler output_chars (nbody + nsp + begmatch, nlen - tem);
1082*59810Shibler #endif
1083*59810Shibler }
1084*59810Shibler else if (nlen > olen)
1085*59810Shibler {
1086*59810Shibler output_chars (nbody + nsp + begmatch, olen - tem);
1087*59810Shibler insert_chars (nbody + nsp + begmatch + olen - tem, nlen - olen);
1088*59810Shibler olen = nlen;
1089*59810Shibler }
1090*59810Shibler else if (olen > nlen)
1091*59810Shibler {
1092*59810Shibler output_chars (nbody + nsp + begmatch, nlen - tem);
1093*59810Shibler delete_chars (olen - nlen);
1094*59810Shibler olen = nlen;
1095*59810Shibler }
1096*59810Shibler }
1097*59810Shibler
1098*59810Shibler just_erase:
1099*59810Shibler /* If any unerased characters remain after the new line, erase them. */
1100*59810Shibler if (olen > nlen)
1101*59810Shibler {
1102*59810Shibler move_cursor (vpos, nlen);
1103*59810Shibler clear_end_of_line (olen);
1104*59810Shibler }
1105*59810Shibler
1106*59810Shibler /* Exchange contents between current_screen and new_screen. */
1107*59810Shibler temp = new_screen->contents[vpos];
1108*59810Shibler new_screen->contents[vpos] = current_screen->contents[vpos];
1109*59810Shibler current_screen->contents[vpos] = temp;
1110*59810Shibler }
1111*59810Shibler
count_blanks(str)1112*59810Shibler count_blanks (str)
1113*59810Shibler char *str;
1114*59810Shibler {
1115*59810Shibler register char *p = str;
1116*59810Shibler while (*str++ == ' ');
1117*59810Shibler return str - p - 1;
1118*59810Shibler }
1119*59810Shibler
count_match(str1,str2)1120*59810Shibler count_match (str1, str2)
1121*59810Shibler char *str1, *str2;
1122*59810Shibler {
1123*59810Shibler register char *p1 = str1;
1124*59810Shibler register char *p2 = str2;
1125*59810Shibler while (*p1++ == *p2++);
1126*59810Shibler return p1 - str1 - 1;
1127*59810Shibler }
1128*59810Shibler
1129*59810Shibler DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
1130*59810Shibler 1, 1, "FOpen termscript file: ",
1131*59810Shibler "Start writing all terminal output to FILE as well as the terminal.\n\
1132*59810Shibler FILE = nil means just close any termscript file currently open.")
1133*59810Shibler (file)
1134*59810Shibler Lisp_Object file;
1135*59810Shibler {
1136*59810Shibler if (termscript != 0) fclose (termscript);
1137*59810Shibler termscript = 0;
1138*59810Shibler
1139*59810Shibler if (! NULL (file))
1140*59810Shibler {
1141*59810Shibler file = Fexpand_file_name (file, Qnil);
1142*59810Shibler termscript = fopen (XSTRING (file)->data, "w");
1143*59810Shibler if (termscript == 0)
1144*59810Shibler report_file_error ("Opening termscript", Fcons (file, Qnil));
1145*59810Shibler }
1146*59810Shibler return Qnil;
1147*59810Shibler }
1148*59810Shibler
1149*59810Shibler DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
1150*59810Shibler "Tell redisplay that the screen has LINES lines.\n\
1151*59810Shibler Optional second arg non-nil means that redisplay should use LINES lines\n\
1152*59810Shibler but that the idea of the actual height of the screen should not be changed.")
1153*59810Shibler (n, pretend)
1154*59810Shibler Lisp_Object n, pretend;
1155*59810Shibler {
1156*59810Shibler CHECK_NUMBER (n, 0);
1157*59810Shibler change_screen_size (XINT (n), 0, !NULL (pretend));
1158*59810Shibler return Qnil;
1159*59810Shibler }
1160*59810Shibler
1161*59810Shibler DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
1162*59810Shibler "Tell redisplay that the screen has COLS columns.\n\
1163*59810Shibler Optional second arg non-nil means that redisplay should use COLS columns\n\
1164*59810Shibler but that the idea of the actual width of the screen should not be changed.")
1165*59810Shibler (n, pretend)
1166*59810Shibler Lisp_Object n, pretend;
1167*59810Shibler {
1168*59810Shibler CHECK_NUMBER (n, 0);
1169*59810Shibler change_screen_size (0, XINT (n), !NULL (pretend));
1170*59810Shibler return Qnil;
1171*59810Shibler }
1172*59810Shibler
1173*59810Shibler DEFUN ("screen-height", Fscreen_height, Sscreen_height, 0, 0, 0,
1174*59810Shibler "Return number of lines on screen available for display.")
1175*59810Shibler ()
1176*59810Shibler {
1177*59810Shibler return make_number (screen_height);
1178*59810Shibler }
1179*59810Shibler
1180*59810Shibler DEFUN ("screen-width", Fscreen_width, Sscreen_width, 0, 0, 0,
1181*59810Shibler "Return number of columns on screen available for display.")
1182*59810Shibler ()
1183*59810Shibler {
1184*59810Shibler return make_number (screen_width);
1185*59810Shibler }
1186*59810Shibler
1187*59810Shibler #ifdef SIGWINCH
window_change_signal()1188*59810Shibler window_change_signal ()
1189*59810Shibler {
1190*59810Shibler int width, height;
1191*59810Shibler extern int errno;
1192*59810Shibler int old_errno = errno;
1193*59810Shibler
1194*59810Shibler get_screen_size (&width, &height);
1195*59810Shibler /* Record the new size, but don't reallocate the data structures now.
1196*59810Shibler Let that be done later outside of the signal handler. */
1197*59810Shibler in_display++;
1198*59810Shibler change_screen_size (height, width, 0);
1199*59810Shibler in_display--;
1200*59810Shibler signal (SIGWINCH, window_change_signal);
1201*59810Shibler
1202*59810Shibler errno = old_errno;
1203*59810Shibler }
1204*59810Shibler #endif /* SIGWINCH */
1205*59810Shibler
1206*59810Shibler /* Do any change in screen size that was requested by a signal. */
1207*59810Shibler
do_pending_window_change()1208*59810Shibler do_pending_window_change ()
1209*59810Shibler {
1210*59810Shibler /* If change_screen_size should have run before, run it now. */
1211*59810Shibler while (delayed_size_change)
1212*59810Shibler {
1213*59810Shibler int newwidth = delayed_screen_width;
1214*59810Shibler int newheight = delayed_screen_height;
1215*59810Shibler delayed_size_change = 0;
1216*59810Shibler change_screen_size_1 (newheight, newwidth, 0);
1217*59810Shibler }
1218*59810Shibler }
1219*59810Shibler
1220*59810Shibler /* Change the screen height and/or width. Values may be given as zero to
1221*59810Shibler indicate no change is to take place.
1222*59810Shibler PRETEND is normally 0; 1 means change used-size only
1223*59810Shibler but don't change the size used for calculations;
1224*59810Shibler -1 means don't redisplay. */
1225*59810Shibler
change_screen_size(newlength,newwidth,pretend)1226*59810Shibler change_screen_size (newlength, newwidth, pretend)
1227*59810Shibler register int newlength, newwidth, pretend;
1228*59810Shibler {
1229*59810Shibler /* If we can't deal with the change now, queue it for later. */
1230*59810Shibler if (in_display)
1231*59810Shibler {
1232*59810Shibler delayed_screen_width = newwidth;
1233*59810Shibler delayed_screen_height = newlength;
1234*59810Shibler delayed_size_change = 1;
1235*59810Shibler return;
1236*59810Shibler }
1237*59810Shibler delayed_size_change = 0;
1238*59810Shibler change_screen_size_1 (newlength, newwidth, pretend);
1239*59810Shibler }
1240*59810Shibler
change_screen_size_1(newlength,newwidth,pretend)1241*59810Shibler change_screen_size_1 (newlength, newwidth, pretend)
1242*59810Shibler register int newlength, newwidth, pretend;
1243*59810Shibler {
1244*59810Shibler if ((newlength == 0 || newlength == screen_height)
1245*59810Shibler && (newwidth == 0 || newwidth == screen_width))
1246*59810Shibler return;
1247*59810Shibler if (newlength && newlength != screen_height)
1248*59810Shibler {
1249*59810Shibler set_window_height (XWINDOW (minibuf_window)->prev, newlength - 1, 0);
1250*59810Shibler XFASTINT (XWINDOW (minibuf_window)->top) = newlength - 1;
1251*59810Shibler set_window_height (minibuf_window, 1, 0);
1252*59810Shibler screen_height = newlength;
1253*59810Shibler if (pretend <= 0)
1254*59810Shibler ScreenRows = newlength;
1255*59810Shibler set_terminal_window (0);
1256*59810Shibler }
1257*59810Shibler if (newwidth && newwidth != screen_width)
1258*59810Shibler {
1259*59810Shibler set_window_width (XWINDOW (minibuf_window)->prev, newwidth, 0);
1260*59810Shibler set_window_width (minibuf_window, newwidth, 0);
1261*59810Shibler screen_width = newwidth;
1262*59810Shibler if (pretend <= 0)
1263*59810Shibler ScreenCols = newwidth;
1264*59810Shibler }
1265*59810Shibler remake_screen_structures ();
1266*59810Shibler screen_garbaged = 1;
1267*59810Shibler calculate_costs ();
1268*59810Shibler if (pretend >= 0)
1269*59810Shibler redisplay_preserve_echo_area ();
1270*59810Shibler }
1271*59810Shibler
1272*59810Shibler DEFUN ("baud-rate", Fbaud_rate, Sbaud_rate, 0, 0, 0,
1273*59810Shibler "Return the output baud rate of the terminal.")
1274*59810Shibler ()
1275*59810Shibler {
1276*59810Shibler Lisp_Object temp;
1277*59810Shibler XSET (temp, Lisp_Int, baud_rate);
1278*59810Shibler return temp;
1279*59810Shibler }
1280*59810Shibler
1281*59810Shibler DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
1282*59810Shibler Ssend_string_to_terminal, 1, 1, 0,
1283*59810Shibler "Send STRING to the terminal without alteration.\n\
1284*59810Shibler Control characters in STRING will have terminal-dependent effects.")
1285*59810Shibler (str)
1286*59810Shibler Lisp_Object str;
1287*59810Shibler {
1288*59810Shibler CHECK_STRING (str, 0);
1289*59810Shibler fwrite (XSTRING (str)->data, 1, XSTRING (str)->size, stdout);
1290*59810Shibler fflush (stdout);
1291*59810Shibler if (termscript)
1292*59810Shibler {
1293*59810Shibler fwrite (XSTRING (str)->data, 1, XSTRING (str)->size, termscript);
1294*59810Shibler fflush (termscript);
1295*59810Shibler }
1296*59810Shibler return Qnil;
1297*59810Shibler }
1298*59810Shibler
1299*59810Shibler DEFUN ("ding", Fding, Sding, 0, 1, 0,
1300*59810Shibler "Beep, or flash the screen.\n\
1301*59810Shibler Terminates any keyboard macro currently executing unless an argument\n\
1302*59810Shibler is given.")
1303*59810Shibler (arg)
1304*59810Shibler Lisp_Object arg;
1305*59810Shibler {
1306*59810Shibler if (!NULL (arg))
1307*59810Shibler {
1308*59810Shibler bell ();
1309*59810Shibler fflush (stdout);
1310*59810Shibler }
1311*59810Shibler else
1312*59810Shibler bell ();
1313*59810Shibler return Qnil;
1314*59810Shibler }
1315*59810Shibler
bell()1316*59810Shibler bell ()
1317*59810Shibler {
1318*59810Shibler if (noninteractive)
1319*59810Shibler putchar (07);
1320*59810Shibler else if (!FROM_KBD) /* Stop executing a keyboard macro. */
1321*59810Shibler error ("Keyboard macro terminated by a command ringing the bell");
1322*59810Shibler else
1323*59810Shibler ring_bell ();
1324*59810Shibler fflush (stdout);
1325*59810Shibler }
1326*59810Shibler
1327*59810Shibler DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 1, 0,
1328*59810Shibler "Pause, without updating display, for ARG seconds.")
1329*59810Shibler (n)
1330*59810Shibler Lisp_Object n;
1331*59810Shibler {
1332*59810Shibler register int t;
1333*59810Shibler #ifndef subprocesses
1334*59810Shibler #ifdef HAVE_TIMEVAL
1335*59810Shibler struct timeval timeout, end_time, garbage1;
1336*59810Shibler #endif /* HAVE_TIMEVAL */
1337*59810Shibler #endif /* no subprocesses */
1338*59810Shibler
1339*59810Shibler CHECK_NUMBER (n, 0);
1340*59810Shibler t = XINT (n);
1341*59810Shibler if (t <= 0)
1342*59810Shibler return Qnil;
1343*59810Shibler
1344*59810Shibler #ifdef subprocesses
1345*59810Shibler wait_reading_process_input (t, 0, 0);
1346*59810Shibler #else /* No subprocesses */
1347*59810Shibler immediate_quit = 1;
1348*59810Shibler QUIT;
1349*59810Shibler
1350*59810Shibler #ifdef VMS
1351*59810Shibler sys_sleep (t);
1352*59810Shibler #else /* not VMS */
1353*59810Shibler /* The reason this is done this way
1354*59810Shibler (rather than defined (H_S) && defined (H_T))
1355*59810Shibler is because the VMS preprocessor doesn't grok `defined' */
1356*59810Shibler #ifdef HAVE_SELECT
1357*59810Shibler #ifdef HAVE_TIMEVAL
1358*59810Shibler gettimeofday (&end_time, &garbage1);
1359*59810Shibler end_time.tv_sec += t;
1360*59810Shibler
1361*59810Shibler while (1)
1362*59810Shibler {
1363*59810Shibler gettimeofday (&timeout, &garbage1);
1364*59810Shibler timeout.tv_sec = end_time.tv_sec - timeout.tv_sec;
1365*59810Shibler timeout.tv_usec = end_time.tv_usec - timeout.tv_usec;
1366*59810Shibler if (timeout.tv_usec < 0)
1367*59810Shibler timeout.tv_usec += 1000000,
1368*59810Shibler timeout.tv_sec--;
1369*59810Shibler if (timeout.tv_sec < 0)
1370*59810Shibler break;
1371*59810Shibler if (!select (1, 0, 0, 0, &timeout))
1372*59810Shibler break;
1373*59810Shibler }
1374*59810Shibler #else /* not HAVE_TIMEVAL */
1375*59810Shibler /* Is it safe to quit out of `sleep'? I'm afraid to trust it. */
1376*59810Shibler sleep (t);
1377*59810Shibler #endif /* HAVE_TIMEVAL */
1378*59810Shibler #else /* not HAVE_SELECT */
1379*59810Shibler sleep (t);
1380*59810Shibler #endif /* HAVE_SELECT */
1381*59810Shibler #endif /* not VMS */
1382*59810Shibler
1383*59810Shibler immediate_quit = 0;
1384*59810Shibler #endif /* no subprocesses */
1385*59810Shibler return Qnil;
1386*59810Shibler }
1387*59810Shibler
1388*59810Shibler DEFUN ("sit-for", Fsit_for, Ssit_for, 1, 2, 0,
1389*59810Shibler "Perform redisplay, then wait for ARG seconds or until input is available.\n\
1390*59810Shibler Optional second arg non-nil means don't redisplay.\n\
1391*59810Shibler Redisplay is preempted as always if input arrives, and does not happen\n\
1392*59810Shibler if input is available before it starts.\n\
1393*59810Shibler Value is t if waited the full time with no input arriving.")
1394*59810Shibler (n, nodisp)
1395*59810Shibler Lisp_Object n, nodisp;
1396*59810Shibler {
1397*59810Shibler #ifndef subprocesses
1398*59810Shibler #ifdef HAVE_TIMEVAL
1399*59810Shibler struct timeval timeout;
1400*59810Shibler #else
1401*59810Shibler int timeout_sec;
1402*59810Shibler #endif
1403*59810Shibler int waitchannels;
1404*59810Shibler #endif /* no subprocesses */
1405*59810Shibler
1406*59810Shibler CHECK_NUMBER (n, 0);
1407*59810Shibler
1408*59810Shibler if (detect_input_pending ())
1409*59810Shibler return Qnil;
1410*59810Shibler
1411*59810Shibler if (EQ (nodisp, Qnil))
1412*59810Shibler redisplay_preserve_echo_area ();
1413*59810Shibler if (XINT (n) > 0)
1414*59810Shibler {
1415*59810Shibler #ifdef subprocesses
1416*59810Shibler #ifdef SIGIO
1417*59810Shibler gobble_input ();
1418*59810Shibler #endif /* SIGIO */
1419*59810Shibler wait_reading_process_input (XINT (n), 1, 1);
1420*59810Shibler #else /* no subprocesses */
1421*59810Shibler immediate_quit = 1;
1422*59810Shibler QUIT;
1423*59810Shibler
1424*59810Shibler waitchannels = 1;
1425*59810Shibler #ifdef VMS
1426*59810Shibler input_wait_timeout (XINT (n));
1427*59810Shibler #else /* not VMS */
1428*59810Shibler #ifndef HAVE_TIMEVAL
1429*59810Shibler timeout_sec = XINT (n);
1430*59810Shibler select (1, &waitchannels, 0, 0, &timeout_sec);
1431*59810Shibler #else /* HAVE_TIMEVAL */
1432*59810Shibler timeout.tv_sec = XINT (n);
1433*59810Shibler timeout.tv_usec = 0;
1434*59810Shibler select (1, &waitchannels, 0, 0, &timeout);
1435*59810Shibler #endif /* HAVE_TIMEVAL */
1436*59810Shibler #endif /* not VMS */
1437*59810Shibler
1438*59810Shibler immediate_quit = 0;
1439*59810Shibler #endif /* no subprocesses */
1440*59810Shibler }
1441*59810Shibler return detect_input_pending () ? Qnil : Qt;
1442*59810Shibler }
1443*59810Shibler
1444*59810Shibler char *terminal_type;
1445*59810Shibler
1446*59810Shibler /* Initialization done when Emacs fork is started, before doing stty. */
1447*59810Shibler /* Determine terminal type and set terminal_driver */
1448*59810Shibler /* Then invoke its decoding routine to set up variables
1449*59810Shibler in the terminal package */
1450*59810Shibler
init_display()1451*59810Shibler init_display ()
1452*59810Shibler {
1453*59810Shibler #ifdef HAVE_X_WINDOWS
1454*59810Shibler extern Lisp_Object Vxterm;
1455*59810Shibler Vxterm = Qnil;
1456*59810Shibler #endif
1457*59810Shibler
1458*59810Shibler Vwindow_system = Qnil;
1459*59810Shibler meta_key = 0;
1460*59810Shibler inverse_video = 0;
1461*59810Shibler cursor_in_echo_area = 0;
1462*59810Shibler terminal_type = (char *) 0;
1463*59810Shibler
1464*59810Shibler if (!inhibit_window_system)
1465*59810Shibler {
1466*59810Shibler #ifdef HAVE_X_WINDOWS
1467*59810Shibler extern char *alternate_display;
1468*59810Shibler char *disp = (char *) egetenv ("DISPLAY");
1469*59810Shibler
1470*59810Shibler /* Note KSH likes to provide an empty string as an envvar value. */
1471*59810Shibler if (alternate_display || (disp && *disp))
1472*59810Shibler {
1473*59810Shibler x_term_init ();
1474*59810Shibler Vxterm = Qt;
1475*59810Shibler Vwindow_system = intern ("x");
1476*59810Shibler #ifdef X11
1477*59810Shibler Vwindow_system_version = make_number (11);
1478*59810Shibler #else
1479*59810Shibler Vwindow_system_version = make_number (10);
1480*59810Shibler #endif
1481*59810Shibler goto term_init_done;
1482*59810Shibler }
1483*59810Shibler #endif /* HAVE_X_WINDOWS */
1484*59810Shibler ;
1485*59810Shibler }
1486*59810Shibler /* Record we aren't using a window system. */
1487*59810Shibler inhibit_window_system = 1;
1488*59810Shibler
1489*59810Shibler /* Look at the TERM variable */
1490*59810Shibler terminal_type = (char *) getenv ("TERM");
1491*59810Shibler if (!terminal_type)
1492*59810Shibler {
1493*59810Shibler #ifdef VMS
1494*59810Shibler fprintf (stderr, "Please specify your terminal type.\n\
1495*59810Shibler For types defined in VMS, use set term /device=TYPE.\n\
1496*59810Shibler For types not defined in VMS, use define emacs_term \"TYPE\".\n\
1497*59810Shibler \(The quotation marks are necessary since terminal types are lower case.)\n");
1498*59810Shibler #else
1499*59810Shibler fprintf (stderr, "Please set the environment variable TERM; see tset(1).\n");
1500*59810Shibler #endif
1501*59810Shibler exit (1);
1502*59810Shibler }
1503*59810Shibler term_init (terminal_type);
1504*59810Shibler
1505*59810Shibler term_init_done:
1506*59810Shibler remake_screen_structures ();
1507*59810Shibler calculate_costs ();
1508*59810Shibler
1509*59810Shibler #ifdef SIGWINCH
1510*59810Shibler #ifndef CANNOT_DUMP
1511*59810Shibler if (initialized)
1512*59810Shibler #endif /* CANNOT_DUMP */
1513*59810Shibler if (inhibit_window_system)
1514*59810Shibler signal (SIGWINCH, window_change_signal);
1515*59810Shibler #endif /* SIGWINCH */
1516*59810Shibler }
1517*59810Shibler
syms_of_display()1518*59810Shibler syms_of_display ()
1519*59810Shibler {
1520*59810Shibler defsubr (&Sopen_termscript);
1521*59810Shibler defsubr (&Sding);
1522*59810Shibler defsubr (&Ssit_for);
1523*59810Shibler defsubr (&Sscreen_height);
1524*59810Shibler defsubr (&Sscreen_width);
1525*59810Shibler defsubr (&Sset_screen_height);
1526*59810Shibler defsubr (&Sset_screen_width);
1527*59810Shibler defsubr (&Ssleep_for);
1528*59810Shibler defsubr (&Sbaud_rate);
1529*59810Shibler defsubr (&Ssend_string_to_terminal);
1530*59810Shibler
1531*59810Shibler DEFVAR_BOOL ("inverse-video", &inverse_video,
1532*59810Shibler "*Non-nil means use inverse-video.");
1533*59810Shibler DEFVAR_BOOL ("visible-bell", &visible_bell,
1534*59810Shibler "*Non-nil means try to flash the screen to represent a bell.");
1535*59810Shibler DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter,
1536*59810Shibler "*Non-nil means no need to redraw entire screen after suspending.\n\
1537*59810Shibler It is up to you to set this variable to inform Emacs.");
1538*59810Shibler DEFVAR_LISP ("window-system", &Vwindow_system,
1539*59810Shibler "A symbol naming the window-system under which Emacs is running,\n\
1540*59810Shibler \(such as `x'), or nil if emacs is running on an ordinary terminal.");
1541*59810Shibler DEFVAR_LISP ("window-system-version", &Vwindow_system_version,
1542*59810Shibler "Version number of the window system Emacs is running under.");
1543*59810Shibler DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area,
1544*59810Shibler "Non-nil means put cursor in minibuffer after any message displayed there.");
1545*59810Shibler
1546*59810Shibler /* Initialize `window-system', unless init_display already decided it. */
1547*59810Shibler #ifdef CANNOT_DUMP
1548*59810Shibler if (noninteractive)
1549*59810Shibler #endif
1550*59810Shibler {
1551*59810Shibler Vwindow_system_version = Qnil;
1552*59810Shibler Vwindow_system = Qnil;
1553*59810Shibler }
1554*59810Shibler }
1555