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