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