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 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 * 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 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 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 314 cancel_line (vpos) 315 int vpos; 316 { 317 new_screen->enable[vpos] = 0; 318 } 319 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 * 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 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 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 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 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 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 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 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 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 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 1112 count_blanks (str) 1113 char *str; 1114 { 1115 register char *p = str; 1116 while (*str++ == ' '); 1117 return str - p - 1; 1118 } 1119 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 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 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 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 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 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 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 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