1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 1986, 1987, 1988, 1990 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
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)
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.
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. */
29 #else /* not NEED_TIME_H */
32 #endif /* HAVE_TIMEVAL */
33 #endif /* not NEED_TIME_H */
39 #define TIOCOUTQ TCOUTQ
40 #endif /* TCOUTQ defined */
44 #include <sys/ioctl.h>
46 #endif /* not HAVE_TERMIO */
48 /* Allow m- file to inhibit use of FIONREAD. */
49 #ifdef BROKEN_FIONREAD
53 /* Interupt input is not used if there is no FIONREAD. */
64 #include "dispextern.h"
74 #endif /* HAVE_X_WINDOWS */
76 #define max(a, b) ((a) > (b) ? (a) : (b))
77 #define min(a, b) ((a) < (b) ? (a) : (b))
79 #ifndef PENDING_OUTPUT_COUNT
80 /* Get number of chars of output now in the buffer of a stdio stream.
81 This ought to be built in in stdio, but it isn't.
82 Some s- files override this because their stdio internals differ. */
83 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
86 /* Nonzero means do not assume anything about current
87 contents of actual terminal screen */
91 /* Nonzero means last display completed. Zero means it was preempted. */
93 int display_completed
;
95 /* Lisp variable visible-bell; enables use of screen-flash
96 instead of audible bell. */
100 /* Invert the color of the whole screen, at a low level. */
104 /* Line speed of the terminal. */
108 /* nil or a symbol naming the window system under which emacs is
109 running ('x is the only current possibility). */
111 Lisp_Object Vwindow_system
;
113 /* Version number of X windows: 10, 11 or nil. */
114 Lisp_Object Vwindow_system_version
;
116 /* Vector of glyph definitions. Indexed by glyph number,
117 the contents are a string which is how to output the glyph.
119 If Vglyph_table is nil, a glyph is output by using its low 8 bits
120 as a character code. */
122 Lisp_Object Vglyph_table
;
124 /* Display table to use for vectors that don't specify their own. */
126 Lisp_Object Vstandard_display_table
;
128 /* Nonzero means reading single-character input with prompt
129 so put cursor on minibuffer after the prompt. */
131 int cursor_in_echo_area
;
133 /* The currently selected screen.
134 In a single-screen version, this variable always remains 0. */
136 SCREEN_PTR selected_screen
;
138 /* In a single-screen version, the information that would otherwise
139 exist inside a `struct screen' lives in the following variables instead. */
143 /* Desired terminal cursor position (to show position of point),
148 /* Description of current screen contents */
150 struct screen_glyphs
*current_glyphs
;
152 /* Description of desired screen contents */
154 struct screen_glyphs
*desired_glyphs
;
156 #endif /* not MULTI_SCREEN */
158 /* This is a vector, made larger whenever it isn't large enough,
159 which is used inside `update_screen' to hold the old contents
160 of the SCREEN_PHYS_LINES of the screen being updated. */
161 struct screen_glyphs
**ophys_lines
;
162 /* Length of vector currently allocated. */
163 int ophys_lines_length
;
165 FILE *termscript
; /* Stdio stream being used for copy of all output. */
167 struct cm Wcm
; /* Structure for info on cursor positioning */
169 extern short ospeed
; /* Output speed (from sg_ospeed) */
171 int in_display
; /* 1 if in redisplay: can't handle SIGWINCH now. */
173 int delayed_size_change
; /* 1 means SIGWINCH happened when not safe. */
174 int delayed_screen_height
; /* Remembered new screen height. */
175 int delayed_screen_width
; /* Remembered new screen width. */
179 DEFUN ("redraw-screen", Fredraw_screen
, Sredraw_screen
, 1, 1, 0,
180 "Clear screen SCREEN and output again what is supposed to appear on it.")
186 CHECK_SCREEN (screen
, 0);
187 s
= XSCREEN (screen
);
189 /* set_terminal_modes (); */
193 clear_screen_records (s
);
194 windows_or_buffers_changed
++;
195 /* Mark all windows as INaccurate,
196 so that every window will have its redisplay done. */
197 mark_window_display_accurate (SCREEN_ROOT_WINDOW (s
), 0);
202 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
203 "Redraw all screens marked as having their images garbled.")
206 Lisp_Object screen
, tail
;
208 for (tail
= Vscreen_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
210 screen
= XCONS (tail
)->car
;
211 if (XSCREEN (screen
)->garbaged
&& XSCREEN (screen
)->visible
)
212 Fredraw_screen (screen
);
221 XSET (screen
, Lisp_Screen
, s
);
222 Fredraw_screen (screen
);
225 #else /* not MULTI_SCREEN */
227 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, 0,
228 "Clear screen and output again what is supposed to appear on it.")
232 set_terminal_modes ();
236 clear_screen_records (0);
237 windows_or_buffers_changed
++;
238 /* Mark all windows as INaccurate,
239 so that every window will have its redisplay done. */
240 mark_window_display_accurate (XWINDOW (minibuf_window
)->prev
, 0);
244 #endif /* not MULTI_SCREEN */
246 static struct screen_glyphs
*
247 make_screen_glyphs (screen
, empty
)
248 register SCREEN_PTR screen
;
252 register width
= SCREEN_WIDTH (screen
);
253 register height
= SCREEN_HEIGHT (screen
);
254 register struct screen_glyphs
*new =
255 (struct screen_glyphs
*) xmalloc (sizeof (struct screen_glyphs
));
257 SET_GLYPHS_SCREEN (new, screen
);
258 new->height
= height
;
260 new->used
= (int *) xmalloc (height
* sizeof (int));
261 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
262 new->highlight
= (char *) xmalloc (height
* sizeof (char));
263 new->enable
= (char *) xmalloc (height
* sizeof (char));
264 bzero (new->enable
, height
* sizeof (char));
265 new->bufp
= (int *) xmalloc (height
* sizeof (int));
267 #ifdef HAVE_X_WINDOWS
268 if (SCREEN_IS_X (screen
))
270 new->nruns
= (int *) xmalloc (height
* sizeof (int));
272 = (struct run
**) xmalloc (height
* sizeof (struct run
*));
273 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
274 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
275 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
276 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
282 /* Make the buffer used by decode_mode_spec. This buffer is also
283 used as temporary storage when updating the screen. See scroll.c. */
284 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
286 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
287 bzero (new->total_contents
, total_glyphs
);
291 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
293 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
294 bzero (new->total_contents
, total_glyphs
);
295 for (i
= 0; i
< height
; i
++)
296 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
303 free_screen_glyphs (screen
, glyphs
)
305 struct screen_glyphs
*glyphs
;
307 if (glyphs
->total_contents
)
308 free (glyphs
->total_contents
);
311 free (glyphs
->glyphs
);
312 free (glyphs
->highlight
);
313 free (glyphs
->enable
);
316 #ifdef HAVE_X_WINDOWS
317 if (SCREEN_IS_X (screen
))
319 free (glyphs
->nruns
);
320 free (glyphs
->face_list
);
321 free (glyphs
->top_left_x
);
322 free (glyphs
->top_left_y
);
323 free (glyphs
->pix_width
);
324 free (glyphs
->pix_height
);
332 remake_screen_glyphs (screen
)
335 if (SCREEN_CURRENT_GLYPHS (screen
))
336 free_screen_glyphs (screen
, SCREEN_CURRENT_GLYPHS (screen
));
337 if (SCREEN_DESIRED_GLYPHS (screen
))
338 free_screen_glyphs (screen
, SCREEN_DESIRED_GLYPHS (screen
));
339 if (SCREEN_TEMP_GLYPHS (screen
))
340 free_screen_glyphs (screen
, SCREEN_TEMP_GLYPHS (screen
));
342 if (SCREEN_MESSAGE_BUF (screen
))
343 SCREEN_MESSAGE_BUF (screen
)
344 = (char *) xrealloc (SCREEN_MESSAGE_BUF (screen
),
345 SCREEN_WIDTH (screen
) + 1);
347 SCREEN_MESSAGE_BUF (screen
)
348 = (char *) xmalloc (SCREEN_WIDTH (screen
) + 1);
350 SCREEN_CURRENT_GLYPHS (screen
) = make_screen_glyphs (screen
, 0);
351 SCREEN_DESIRED_GLYPHS (screen
) = make_screen_glyphs (screen
, 0);
352 SCREEN_TEMP_GLYPHS (screen
) = make_screen_glyphs (screen
, 1);
353 SET_SCREEN_GARBAGED (screen
);
356 /* Return the hash code of contents of line VPOS in screen-matrix M. */
359 line_hash_code (m
, vpos
)
360 register struct screen_glyphs
*m
;
363 register GLYPH
*body
, *end
;
366 if (!m
->enable
[vpos
])
369 /* Give all lighlighted lines the same hash code
370 so as to encourage scrolling to leave them in place. */
371 if (m
->highlight
[vpos
])
374 body
= m
->glyphs
[vpos
];
376 if (must_write_spaces
)
383 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
392 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
400 /* Return number of characters in line in M at vpos VPOS,
401 except don't count leading and trailing spaces
402 unless the terminal requires those to be explicitly output. */
405 line_draw_cost (m
, vpos
)
406 struct screen_glyphs
*m
;
409 register GLYPH
*beg
= m
->glyphs
[vpos
];
410 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
412 register int tlen
= GLYPH_TABLE_LENGTH
;
413 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
415 /* Ignore trailing and leading spaces if we can. */
416 if (!must_write_spaces
)
418 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
421 return (0); /* All blank line. */
423 while (*beg
== SPACEGLYPH
)
427 /* If we don't have a glyph-table, each glyph is one character,
428 so return the number of glyphs. */
432 /* Otherwise, scan the glyphs and accumulate their total size in I. */
434 while ((beg
<= end
) && *beg
)
436 register GLYPH g
= *beg
++;
438 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
441 i
+= GLYPH_LENGTH (tbase
, g
);
446 /* The functions on this page are the interface from xdisp.c to redisplay.
448 The only other interface into redisplay is through setting
449 SCREEN_CURSOR_X (screen) and SCREEN_CURSOR_Y (screen)
450 and SET_SCREEN_GARBAGED (screen). */
452 /* cancel_line eliminates any request to display a line at position `vpos' */
454 cancel_line (vpos
, screen
)
456 register SCREEN_PTR screen
;
458 SCREEN_DESIRED_GLYPHS (screen
)->enable
[vpos
] = 0;
461 clear_screen_records (screen
)
462 register SCREEN_PTR screen
;
464 bzero (SCREEN_CURRENT_GLYPHS (screen
)->enable
, SCREEN_HEIGHT (screen
));
467 /* Prepare to display on line VPOS starting at HPOS within it. */
470 get_display_line (screen
, vpos
, hpos
)
471 register SCREEN_PTR screen
;
475 register struct screen_glyphs
*glyphs
;
476 register struct screen_glyphs
*desired_glyphs
= SCREEN_DESIRED_GLYPHS (screen
);
479 if (vpos
< 0 || (! SCREEN_VISIBLE_P (screen
)))
482 if ((desired_glyphs
->enable
[vpos
]) && desired_glyphs
->used
[vpos
] > hpos
)
485 if (! desired_glyphs
->enable
[vpos
])
487 desired_glyphs
->used
[vpos
] = 0;
488 desired_glyphs
->highlight
[vpos
] = 0;
489 desired_glyphs
->enable
[vpos
] = 1;
492 if (hpos
> desired_glyphs
->used
[vpos
])
494 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
495 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
497 desired_glyphs
->used
[vpos
] = hpos
;
503 /* Like bcopy except never gets confused by overlap. */
506 safe_bcopy (from
, to
, size
)
516 /* If destination is higher in memory, and overlaps source zone,
517 copy from the end. */
518 if (from
< to
&& from
+ size
> to
)
523 /* If TO - FROM is large, then we should break the copy into
524 nonoverlapping chunks of TO - FROM bytes each. However, if
525 TO - FROM is small, then the bcopy function call overhead
526 makes this not worth it. The crossover point could be about
527 anywhere. Since I don't think the obvious copy loop is ever
528 too bad, I'm trying to err in its favor. */
533 while (endf
!= from
);
537 /* Since TO - FROM >= 64, the overlap is less than SIZE,
538 so we can always safely do this loop once. */
544 bcopy (endf
, endt
, to
- from
);
547 /* If TO - FROM wasn't a multiple of SIZE, there will be a
548 little left over. The amount left over is
549 (endt + (to - from)) - to, which is endt - from. */
550 bcopy (from
, to
, endt
- from
);
554 bcopy (from
, to
, size
);
559 safe_bcopy (from
, to
, size
)
569 /* If destination is higher in memory, and overlaps source zone,
570 copy from the end. */
571 if (from
< to
&& from
+ size
> to
)
578 while (endf
!= from
);
583 bcopy (from
, to
, size
);
587 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
588 DISTANCE may be negative. */
591 rotate_vector (vector
, size
, distance
)
596 char *temp
= (char *) alloca (size
);
601 bcopy (vector
, temp
+ distance
, size
- distance
);
602 bcopy (vector
+ size
- distance
, temp
, distance
);
603 bcopy (temp
, vector
, size
);
606 /* Scroll lines from vpos FROM up to but not including vpos END
607 down by AMOUNT lines (AMOUNT may be negative).
608 Returns nonzero if done, zero if terminal cannot scroll them. */
611 scroll_screen_lines (screen
, from
, end
, amount
)
612 register SCREEN_PTR screen
;
613 int from
, end
, amount
;
616 register struct screen_glyphs
*current_screen
617 = SCREEN_CURRENT_GLYPHS (screen
);
619 if (!line_ins_del_ok
)
627 update_begin (screen
);
628 set_terminal_window (end
+ amount
);
629 if (!scroll_region_ok
)
630 ins_del_lines (end
, -amount
);
631 ins_del_lines (from
, amount
);
632 set_terminal_window (0);
634 rotate_vector (current_screen
->glyphs
+ from
,
635 sizeof (GLYPH
*) * (end
+ amount
- from
),
636 amount
* sizeof (GLYPH
*));
638 safe_bcopy (current_screen
->used
+ from
,
639 current_screen
->used
+ from
+ amount
,
640 (end
- from
) * sizeof current_screen
->used
[0]);
642 safe_bcopy (current_screen
->highlight
+ from
,
643 current_screen
->highlight
+ from
+ amount
,
644 (end
- from
) * sizeof current_screen
->highlight
[0]);
646 safe_bcopy (current_screen
->enable
+ from
,
647 current_screen
->enable
+ from
+ amount
,
648 (end
- from
) * sizeof current_screen
->enable
[0]);
650 /* Mark the lines made empty by scrolling as enabled, empty and
652 bzero (current_screen
->used
+ from
,
653 amount
* sizeof current_screen
->used
[0]);
654 bzero (current_screen
->highlight
+ from
,
655 amount
* sizeof current_screen
->highlight
[0]);
656 for (i
= from
; i
< from
+ amount
; i
++)
658 current_screen
->glyphs
[i
][0] = '\0';
659 current_screen
->enable
[i
] = 1;
662 safe_bcopy (current_screen
->bufp
+ from
,
663 current_screen
->bufp
+ from
+ amount
,
664 (end
- from
) * sizeof current_screen
->bufp
[0]);
666 #ifdef HAVE_X_WINDOWS
667 if (SCREEN_IS_X (screen
))
669 safe_bcopy (current_screen
->nruns
+ from
,
670 current_screen
->nruns
+ from
+ amount
,
671 (end
- from
) * sizeof current_screen
->nruns
[0]);
673 safe_bcopy (current_screen
->face_list
+ from
,
674 current_screen
->face_list
+ from
+ amount
,
675 (end
- from
) * sizeof current_screen
->face_list
[0]);
677 safe_bcopy (current_screen
->top_left_x
+ from
,
678 current_screen
->top_left_x
+ from
+ amount
,
679 (end
- from
) * sizeof current_screen
->top_left_x
[0]);
681 safe_bcopy (current_screen
->top_left_y
+ from
,
682 current_screen
->top_left_y
+ from
+ amount
,
683 (end
- from
) * sizeof current_screen
->top_left_y
[0]);
685 safe_bcopy (current_screen
->pix_width
+ from
,
686 current_screen
->pix_width
+ from
+ amount
,
687 (end
- from
) * sizeof current_screen
->pix_width
[0]);
689 safe_bcopy (current_screen
->pix_height
+ from
,
690 current_screen
->pix_height
+ from
+ amount
,
691 (end
- from
) * sizeof current_screen
->pix_height
[0]);
693 #endif /* HAVE_X_WINDOWS */
699 update_begin (screen
);
700 set_terminal_window (end
);
701 ins_del_lines (from
+ amount
, amount
);
702 if (!scroll_region_ok
)
703 ins_del_lines (end
+ amount
, -amount
);
704 set_terminal_window (0);
706 rotate_vector (current_screen
->glyphs
+ from
+ amount
,
707 sizeof (GLYPH
*) * (end
- from
- amount
),
708 amount
* sizeof (GLYPH
*));
710 safe_bcopy (current_screen
->used
+ from
,
711 current_screen
->used
+ from
+ amount
,
712 (end
- from
) * sizeof current_screen
->used
[0]);
714 safe_bcopy (current_screen
->highlight
+ from
,
715 current_screen
->highlight
+ from
+ amount
,
716 (end
- from
) * sizeof current_screen
->highlight
[0]);
718 safe_bcopy (current_screen
->enable
+ from
,
719 current_screen
->enable
+ from
+ amount
,
720 (end
- from
) * sizeof current_screen
->enable
[0]);
722 /* Mark the lines made empty by scrolling as enabled, empty and
724 bzero (current_screen
->used
+ end
+ amount
,
725 - amount
* sizeof current_screen
->used
[0]);
726 bzero (current_screen
->highlight
+ end
+ amount
,
727 - amount
* sizeof current_screen
->highlight
[0]);
728 for (i
= end
+ amount
; i
< end
; i
++)
730 current_screen
->glyphs
[i
][0] = '\0';
731 current_screen
->enable
[i
] = 1;
734 safe_bcopy (current_screen
->bufp
+ from
,
735 current_screen
->bufp
+ from
+ amount
,
736 (end
- from
) * sizeof current_screen
->bufp
[0]);
738 #ifdef HAVE_X_WINDOWS
739 if (SCREEN_IS_X (screen
))
741 safe_bcopy (current_screen
->nruns
+ from
,
742 current_screen
->nruns
+ from
+ amount
,
743 (end
- from
) * sizeof current_screen
->nruns
[0]);
745 safe_bcopy (current_screen
->face_list
+ from
,
746 current_screen
->face_list
+ from
+ amount
,
747 (end
- from
) * sizeof current_screen
->face_list
[0]);
749 safe_bcopy (current_screen
->top_left_x
+ from
,
750 current_screen
->top_left_x
+ from
+ amount
,
751 (end
- from
) * sizeof current_screen
->top_left_x
[0]);
753 safe_bcopy (current_screen
->top_left_y
+ from
,
754 current_screen
->top_left_y
+ from
+ amount
,
755 (end
- from
) * sizeof current_screen
->top_left_y
[0]);
757 safe_bcopy (current_screen
->pix_width
+ from
,
758 current_screen
->pix_width
+ from
+ amount
,
759 (end
- from
) * sizeof current_screen
->pix_width
[0]);
761 safe_bcopy (current_screen
->pix_height
+ from
,
762 current_screen
->pix_height
+ from
+ amount
,
763 (end
- from
) * sizeof current_screen
->pix_height
[0]);
765 #endif /* HAVE_X_WINDOWS */
772 /* After updating a window W that isn't the full screen wide,
773 copy all the columns that W does not occupy
774 into the SCREEN_DESIRED_GLYPHS (screen) from the SCREEN_PHYS_GLYPHS (screen)
775 so that update_screen will not change those columns. */
777 preserve_other_columns (w
)
781 register struct screen_glyphs
*current_screen
, *desired_screen
;
782 register SCREEN_PTR screen
= XSCREEN (w
->screen
);
783 int start
= XFASTINT (w
->left
);
784 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
785 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
787 current_screen
= SCREEN_CURRENT_GLYPHS (screen
);
788 desired_screen
= SCREEN_DESIRED_GLYPHS (screen
);
790 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
792 if (current_screen
->enable
[vpos
] && desired_screen
->enable
[vpos
])
798 bcopy (current_screen
->glyphs
[vpos
],
799 desired_screen
->glyphs
[vpos
], start
);
800 len
= min (start
, current_screen
->used
[vpos
]);
801 if (desired_screen
->used
[vpos
] < len
)
802 desired_screen
->used
[vpos
] = len
;
804 if (current_screen
->used
[vpos
] > end
805 && desired_screen
->used
[vpos
] < current_screen
->used
[vpos
])
807 while (desired_screen
->used
[vpos
] < end
)
808 desired_screen
->glyphs
[vpos
][desired_screen
->used
[vpos
]++]
810 bcopy (current_screen
->glyphs
[vpos
] + end
,
811 desired_screen
->glyphs
[vpos
] + end
,
812 current_screen
->used
[vpos
] - end
);
813 desired_screen
->used
[vpos
] = current_screen
->used
[vpos
];
821 /* If window w does not need to be updated and isn't the full screen wide,
822 copy all the columns that w does occupy
823 into the SCREEN_DESIRED_LINES (screen) from the SCREEN_PHYS_LINES (screen)
824 so that update_screen will not change those columns.
826 Have not been able to figure out how to use this correctly. */
828 preserve_my_columns (w
)
831 register int vpos
, fin
;
832 register struct screen_glyphs
*l1
, *l2
;
833 register SCREEN_PTR screen
= XSCREEN (w
->screen
);
834 int start
= XFASTINT (w
->left
);
835 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
836 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
838 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
840 if ((l1
= SCREEN_DESIRED_GLYPHS (screen
)->glyphs
[vpos
+ 1])
841 && (l2
= SCREEN_PHYS_GLYPHS (screen
)->glyphs
[vpos
+ 1]))
843 if (l2
->length
> start
&& l1
->length
< l2
->length
)
846 if (fin
> end
) fin
= end
;
847 while (l1
->length
< start
)
848 l1
->body
[l1
->length
++] = ' ';
849 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
858 /* On discovering that the redisplay for a window was no good,
859 cancel the columns of that window, so that when the window is
860 displayed over again get_display_line will not complain. */
862 cancel_my_columns (w
)
866 register SCREEN_PTR screen
= XSCREEN (w
->screen
);
867 register struct screen_glyphs
*desired_glyphs
= screen
->desired_glyphs
;
868 register int start
= XFASTINT (w
->left
);
869 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
871 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
872 if (desired_glyphs
->enable
[vpos
]
873 && desired_glyphs
->used
[vpos
] >= start
)
874 desired_glyphs
->used
[vpos
] = start
;
877 /* These functions try to perform directly and immediately on the screen
878 the necessary output for one change in the buffer.
879 They may return 0 meaning nothing was done if anything is difficult,
880 or 1 meaning the output was performed properly.
881 They assume that the screen was up to date before the buffer
882 change being displayed. THey make various other assumptions too;
883 see command_loop_1 where these are called. */
886 direct_output_for_insert (g
)
889 register SCREEN_PTR screen
= selected_screen
;
890 register struct screen_glyphs
*current_screen
891 = SCREEN_CURRENT_GLYPHS (screen
);
893 #ifndef COMPILER_REGISTER_BUG
895 #endif /* COMPILER_REGISTER_BUG */
896 struct window
*w
= XWINDOW (selected_window
);
897 #ifndef COMPILER_REGISTER_BUG
899 #endif /* COMPILER_REGISTER_BUG */
900 int hpos
= SCREEN_CURSOR_X (screen
);
901 #ifndef COMPILER_REGISTER_BUG
903 #endif /* COMPILER_REGISTER_BUG */
904 int vpos
= SCREEN_CURSOR_Y (screen
);
906 /* Give up if about to continue line */
907 if (hpos
- XFASTINT (w
->left
) + 1 + 1 >= XFASTINT (w
->width
)
909 /* Avoid losing if cursor is in invisible text off left margin */
910 || (XINT (w
->hscroll
) && hpos
== XFASTINT (w
->left
))
912 /* Give up if cursor outside window (in minibuf, probably) */
913 || SCREEN_CURSOR_Y (screen
) < XFASTINT (w
->top
)
914 || SCREEN_CURSOR_Y (screen
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
916 /* Give up if cursor not really at SCREEN_CURSOR_X, SCREEN_CURSOR_Y */
917 || !display_completed
919 /* Give up if buffer appears in two places. */
922 /* Give up if w is minibuffer and a message is being displayed there */
923 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
926 current_screen
->glyphs
[vpos
][hpos
] = g
;
927 unchanged_modified
= MODIFF
;
928 beg_unchanged
= GPT
- BEG
;
929 XFASTINT (w
->last_point
) = point
;
930 XFASTINT (w
->last_point_x
) = hpos
;
931 XFASTINT (w
->last_modified
) = MODIFF
;
933 reassert_line_highlight (0, vpos
);
934 write_glyphs (¤t_screen
->glyphs
[vpos
][hpos
], 1);
936 ++SCREEN_CURSOR_X (screen
);
937 if (hpos
== current_screen
->used
[vpos
])
939 current_screen
->used
[vpos
] = hpos
+ 1;
940 current_screen
->glyphs
[vpos
][hpos
+ 1] = 0;
947 direct_output_forward_char (n
)
950 register SCREEN_PTR screen
= selected_screen
;
951 register struct window
*w
= XWINDOW (selected_window
);
953 /* Avoid losing if cursor is in invisible text off left margin */
954 if (XINT (w
->hscroll
) && SCREEN_CURSOR_X (screen
) == XFASTINT (w
->left
))
957 SCREEN_CURSOR_X (screen
) += n
;
958 XFASTINT (w
->last_point_x
) = SCREEN_CURSOR_X (screen
);
959 XFASTINT (w
->last_point
) = point
;
960 cursor_to (SCREEN_CURSOR_Y (screen
), SCREEN_CURSOR_X (screen
));
965 static void update_line ();
967 /* Update screen S based on the data in SCREEN_DESIRED_GLYPHS.
968 Value is nonzero if redisplay stopped due to pending input.
969 FORCE nonzero means do not stop for pending input. */
972 update_screen (s
, force
, inhibit_hairy_id
)
975 int inhibit_hairy_id
;
977 register struct screen_glyphs
*current_screen
= SCREEN_CURRENT_GLYPHS (s
);
978 register struct screen_glyphs
*desired_screen
= SCREEN_DESIRED_GLYPHS (s
);
981 int preempt_count
= baud_rate
/ 2400 + 1;
982 extern input_pending
;
983 #ifdef HAVE_X_WINDOWS
984 register int downto
, leftmost
;
987 if (SCREEN_HEIGHT (s
) == 0) abort (); /* Some bug zeros some core */
989 detect_input_pending ();
990 if (input_pending
&& !force
)
998 if (!line_ins_del_ok
)
999 inhibit_hairy_id
= 1;
1001 /* Don't compute for i/d line if just want cursor motion. */
1002 for (i
= 0; i
< SCREEN_HEIGHT (s
); i
++)
1003 if (desired_screen
->enable
[i
])
1006 /* Try doing i/d line, if not yet inhibited. */
1007 if (!inhibit_hairy_id
&& i
< SCREEN_HEIGHT (s
))
1008 force
|= scrolling (s
);
1010 /* Update the individual lines as needed. Do bottom line first. */
1012 if (desired_screen
->enable
[SCREEN_HEIGHT (s
) - 1])
1013 update_line (s
, SCREEN_HEIGHT (s
) - 1);
1015 #ifdef HAVE_X_WINDOWS
1016 if (SCREEN_IS_X (s
))
1018 leftmost
= downto
= s
->display
.x
->internal_border_width
;
1019 if (desired_screen
->enable
[0])
1021 current_screen
->top_left_x
[SCREEN_HEIGHT (s
) - 1] = leftmost
;
1022 current_screen
->top_left_y
[SCREEN_HEIGHT (s
) - 1]
1023 = PIXEL_HEIGHT (s
) - s
->display
.x
->internal_border_width
1024 - LINE_HEIGHT(s
, SCREEN_HEIGHT (s
) - 1);
1025 current_screen
->top_left_x
[0] = leftmost
;
1026 current_screen
->top_left_y
[0] = downto
;
1029 #endif /* HAVE_X_WINDOWS */
1031 /* Now update the rest of the lines. */
1032 for (i
= 0; i
< SCREEN_HEIGHT (s
) - 1 && (force
|| !input_pending
); i
++)
1034 if (desired_screen
->enable
[i
])
1036 if (SCREEN_IS_TERMCAP (s
))
1038 /* Flush out every so many lines.
1039 Also flush out if likely to have more than 1k buffered
1040 otherwise. I'm told that some telnet connections get
1041 really screwed by more than 1k output at once. */
1042 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1044 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1047 if (preempt_count
== 1)
1050 if (ioctl (0, TIOCOUTQ
, &outq
) < 0)
1051 /* Probably not a tty. Ignore the error and reset
1052 * the outq count. */
1053 outq
= PENDING_OUTPUT_COUNT (stdout
);
1056 sleep (outq
/ baud_rate
);
1059 if ((i
- 1) % preempt_count
== 0)
1060 detect_input_pending ();
1064 #ifdef HAVE_X_WINDOWS
1065 if (SCREEN_IS_X (s
))
1067 current_screen
->top_left_y
[i
] = downto
;
1068 current_screen
->top_left_x
[i
] = leftmost
;
1070 #endif /* HAVE_X_WINDOWS */
1073 if (SCREEN_IS_X (s
))
1074 downto
+= LINE_HEIGHT(s
, i
);
1076 pause
= (i
< SCREEN_HEIGHT (s
) - 1) ? i
: 0;
1078 /* Now just clean up termcap drivers and set cursor, etc. */
1082 if (s
== selected_screen
&& cursor_in_echo_area
< 0)
1083 cursor_to (SCREEN_HEIGHT (s
) - 1, 0);
1084 else if (s
== selected_screen
&& cursor_in_echo_area
1085 && !desired_screen
->used
[SCREEN_HEIGHT (s
) - 1])
1086 cursor_to (SCREEN_HEIGHT (s
), 0);
1087 else if (cursor_in_echo_area
)
1088 cursor_to (SCREEN_HEIGHT (s
) - 1,
1089 min (SCREEN_WIDTH (s
) - 1,
1090 desired_screen
->used
[SCREEN_HEIGHT (s
) - 1]));
1092 cursor_to (SCREEN_CURSOR_Y (s
), max (min (SCREEN_CURSOR_X (s
),
1093 SCREEN_WIDTH (s
) - 1), 0));
1099 fflush (termscript
);
1102 /* Here if output is preempted because input is detected. */
1105 if (SCREEN_HEIGHT (s
) == 0) abort (); /* Some bug zeros some core */
1106 display_completed
= !pause
;
1108 bzero (desired_screen
->enable
, SCREEN_HEIGHT (s
));
1112 /* Called when about to quit, to check for doing so
1113 at an improper time. */
1118 if (SCREEN_DESIRED_GLYPHS (selected_screen
) == 0)
1120 if (SCREEN_DESIRED_GLYPHS (selected_screen
)->enable
[0])
1122 if (SCREEN_DESIRED_GLYPHS (selected_screen
)->enable
[SCREEN_HEIGHT (selected_screen
) - 1])
1126 /* Decide what insert/delete line to do, and do it */
1128 extern void scrolling_1 ();
1133 int unchanged_at_top
, unchanged_at_bottom
;
1136 int *old_hash
= (int *) alloca (SCREEN_HEIGHT (screen
) * sizeof (int));
1137 int *new_hash
= (int *) alloca (SCREEN_HEIGHT (screen
) * sizeof (int));
1138 int *draw_cost
= (int *) alloca (SCREEN_HEIGHT (screen
) * sizeof (int));
1140 int free_at_end_vpos
= SCREEN_HEIGHT (screen
);
1141 register struct screen_glyphs
*current_screen
= SCREEN_CURRENT_GLYPHS (screen
);
1142 register struct screen_glyphs
*desired_screen
= SCREEN_DESIRED_GLYPHS (screen
);
1144 /* Compute hash codes of all the lines.
1145 Also calculate number of changed lines,
1146 number of unchanged lines at the beginning,
1147 and number of unchanged lines at the end. */
1150 unchanged_at_top
= 0;
1151 unchanged_at_bottom
= SCREEN_HEIGHT (screen
);
1152 for (i
= 0; i
< SCREEN_HEIGHT (screen
); i
++)
1154 /* Give up on this scrolling if some old lines are not enabled. */
1155 if (!current_screen
->enable
[i
])
1157 old_hash
[i
] = line_hash_code (current_screen
, i
);
1158 if (! desired_screen
->enable
[i
])
1159 new_hash
[i
] = old_hash
[i
];
1161 new_hash
[i
] = line_hash_code (desired_screen
, i
);
1163 if (old_hash
[i
] != new_hash
[i
])
1166 unchanged_at_bottom
= SCREEN_HEIGHT (screen
) - i
- 1;
1168 else if (i
== unchanged_at_top
)
1170 draw_cost
[i
] = line_draw_cost (desired_screen
, i
);
1173 /* If changed lines are few, don't allow preemption, don't scroll. */
1174 if (changed_lines
< baud_rate
/ 2400
1175 || unchanged_at_bottom
== SCREEN_HEIGHT (screen
))
1178 window_size
= (SCREEN_HEIGHT (screen
) - unchanged_at_top
1179 - unchanged_at_bottom
);
1181 if (scroll_region_ok
)
1182 free_at_end_vpos
-= unchanged_at_bottom
;
1183 else if (memory_below_screen
)
1184 free_at_end_vpos
= -1;
1186 /* If large window, fast terminal and few lines in common between
1187 current screen and desired screen, don't bother with i/d calc. */
1188 if (window_size
>= 18 && baud_rate
> 2400
1190 10 * scrolling_max_lines_saved (unchanged_at_top
,
1191 SCREEN_HEIGHT (screen
) - unchanged_at_bottom
,
1192 old_hash
, new_hash
, draw_cost
)))
1195 scrolling_1 (screen
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1196 draw_cost
+ unchanged_at_top
- 1,
1197 old_hash
+ unchanged_at_top
- 1,
1198 new_hash
+ unchanged_at_top
- 1,
1199 free_at_end_vpos
- unchanged_at_top
);
1204 /* Return the offset in its buffer of the character at location col, line
1205 in the given window. */
1207 buffer_posn_from_coords (window
, col
, line
)
1208 struct window
*window
;
1211 int window_left
= XFASTINT (window
->left
);
1213 /* The actual width of the window is window->width less one for the
1214 \ which ends wrapped lines, and less one if it's not the
1215 rightmost window. */
1216 int window_width
= (XFASTINT (window
->width
) - 1
1217 - (XFASTINT (window
->width
) + window_left
1218 != SCREEN_WIDTH (XSCREEN (window
->screen
))));
1220 /* The screen's list of buffer positions of line starts. */
1221 int *bufp
= SCREEN_CURRENT_GLYPHS (XSCREEN (window
->screen
))->bufp
;
1223 /* Since compute_motion will only operate on the current buffer,
1224 we need to save the old one and restore it when we're done. */
1225 struct buffer
*old_current_buffer
= current_buffer
;
1228 current_buffer
= XBUFFER (window
->buffer
);
1231 /* compute_motion will find the buffer position corresponding to a
1232 screen position, given a buffer position to start at and its
1233 screen position, by scanning from the start to the goal. In
1234 order to make this faster, we need to choose a starting buffer
1235 position with a known screen position as close to the goal as
1238 The bufp array in the screen_glyphs structure gives the buffer
1239 position of the first character on each screen line. This
1240 would be a perfect starting location, except that there's no
1241 way to know if this character really starts flush with the
1242 beginning of the line or if it is being continued from the
1243 previous line; characters like ?\M-x display as \370 and can
1244 wrap off the end of one line onto the next.
1246 So what we do is start on the target line, and scan upwards
1247 until we find a screen line that starts right after a newline
1248 in the buffer, or at the top of the window; both of these
1249 assure us that the character at bufp starts flush with the
1250 beginning of the line. */
1254 /* Unfortunately, the bufp array doesn't seem to be updated properly. */
1256 /* Only works for the leftmost window on a line. bufp is useless
1258 if (window_left
== 0)
1260 for (start_line
= line
; start_line
> 0; start_line
--)
1261 if (FETCH_CHAR (bufp
[XFASTINT (window
->top
) + start_line
]-1)
1264 posn
= bufp
[XFASTINT (window
->top
) + start_line
];
1270 posn
= marker_position (window
->start
);
1274 = compute_motion (posn
, start_line
, window_left
,
1275 ZV
, line
, col
- window_left
,
1276 window_width
, XINT (window
->hscroll
), 0)
1280 current_buffer
= old_current_buffer
;
1289 register GLYPH
*p
= r
;
1290 while (*r
++ == SPACEGLYPH
);
1295 count_match (str1
, str2
)
1298 register GLYPH
*p1
= str1
;
1299 register GLYPH
*p2
= str2
;
1300 while (*p1
++ == *p2
++);
1301 return p1
- str1
- 1;
1304 /* Char insertion/deletion cost vector, from term.c */
1305 extern int *char_ins_del_vector
;
1307 #define char_ins_del_cost(s) (&char_ins_del_vector[SCREEN_HEIGHT((s))])
1310 update_line (screen
, vpos
)
1311 register SCREEN_PTR screen
;
1314 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1316 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1318 register struct screen_glyphs
*current_screen
1319 = SCREEN_CURRENT_GLYPHS (screen
);
1320 register struct screen_glyphs
*desired_screen
1321 = SCREEN_DESIRED_GLYPHS (screen
);
1323 if (desired_screen
->highlight
[vpos
]
1324 != (current_screen
->enable
[vpos
] && current_screen
->highlight
[vpos
]))
1326 change_line_highlight (desired_screen
->highlight
[vpos
], vpos
,
1327 (current_screen
->enable
[vpos
] ?
1328 current_screen
->used
[vpos
] : 0));
1329 current_screen
->enable
[vpos
] = 0;
1332 reassert_line_highlight (desired_screen
->highlight
[vpos
], vpos
);
1334 if (! current_screen
->enable
[vpos
])
1340 obody
= current_screen
->glyphs
[vpos
];
1341 olen
= current_screen
->used
[vpos
];
1342 if (! current_screen
->highlight
[vpos
])
1344 if (!must_write_spaces
)
1345 while (obody
[olen
- 1] == SPACEGLYPH
&& olen
> 0)
1350 /* For an inverse-video line, remember we gave it
1351 spaces all the way to the screen edge
1352 so that the reverse video extends all the way across. */
1354 while (olen
< SCREEN_WIDTH (screen
) - 1)
1355 obody
[olen
++] = SPACEGLYPH
;
1359 /* One way or another, this will enable the line being updated. */
1360 current_screen
->enable
[vpos
] = 1;
1361 current_screen
->used
[vpos
] = desired_screen
->used
[vpos
];
1362 current_screen
->highlight
[vpos
] = desired_screen
->highlight
[vpos
];
1363 current_screen
->bufp
[vpos
] = desired_screen
->bufp
[vpos
];
1365 #ifdef HAVE_X_WINDOWS
1366 if (SCREEN_IS_X (screen
))
1368 current_screen
->pix_width
[vpos
]
1369 = current_screen
->used
[vpos
]
1370 * FONT_WIDTH (screen
->display
.x
->font
);
1371 current_screen
->pix_height
[vpos
]
1372 = FONT_HEIGHT (screen
->display
.x
->font
);
1374 #endif /* HAVE_X_WINDOWS */
1376 if (!desired_screen
->enable
[vpos
])
1382 nbody
= desired_screen
->glyphs
[vpos
];
1383 nlen
= desired_screen
->used
[vpos
];
1385 /* Pretend trailing spaces are not there at all,
1386 unless for one reason or another we must write all spaces. */
1387 if (! desired_screen
->highlight
[vpos
])
1389 if (!must_write_spaces
)
1390 /* We know that the previous character byte contains 0. */
1391 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1396 /* For an inverse-video line, give it extra trailing spaces
1397 all the way to the screen edge
1398 so that the reverse video extends all the way across. */
1400 while (nlen
< SCREEN_WIDTH (screen
) - 1)
1401 nbody
[nlen
++] = SPACEGLYPH
;
1404 /* If there's no i/d char, quickly do the best we can without it. */
1405 if (!char_ins_del_ok
)
1409 for (i
= 0; i
< nlen
; i
++)
1411 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1413 cursor_to (vpos
, i
);
1414 for (j
= 1; (i
+ j
< nlen
&&
1415 (i
+ j
>= olen
|| nbody
[i
+j
] != obody
[i
+j
]));
1418 /* Output this run of non-matching chars. */
1419 write_glyphs (nbody
+ i
, j
);
1422 /* Now find the next non-match. */
1426 /* Clear the rest of the line, or the non-clear part of it. */
1429 cursor_to (vpos
, nlen
);
1430 clear_end_of_line (olen
);
1433 /* Exchange contents between current_screen and new_screen. */
1434 temp
= desired_screen
->glyphs
[vpos
];
1435 desired_screen
->glyphs
[vpos
] = current_screen
->glyphs
[vpos
];
1436 current_screen
->glyphs
[vpos
] = temp
;
1443 nsp
= (must_write_spaces
|| desired_screen
->highlight
[vpos
])
1444 ? 0 : count_blanks (nbody
);
1447 cursor_to (vpos
, nsp
);
1448 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1451 /* Exchange contents between current_screen and new_screen. */
1452 temp
= desired_screen
->glyphs
[vpos
];
1453 desired_screen
->glyphs
[vpos
] = current_screen
->glyphs
[vpos
];
1454 current_screen
->glyphs
[vpos
] = temp
;
1463 /* Compute number of leading blanks in old and new contents. */
1464 osp
= count_blanks (obody
);
1465 if (!desired_screen
->highlight
[vpos
])
1466 nsp
= count_blanks (nbody
);
1470 /* Compute number of matching chars starting with first nonblank. */
1471 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1473 /* Spaces in new match implicit space past the end of old. */
1474 /* A bug causing this to be a no-op was fixed in 18.29. */
1475 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1478 while (np1
[begmatch
] == SPACEGLYPH
)
1482 /* Avoid doing insert/delete char
1483 just cause number of leading spaces differs
1484 when the following text does not match. */
1485 if (begmatch
== 0 && osp
!= nsp
)
1486 osp
= nsp
= min (osp
, nsp
);
1488 /* Find matching characters at end of line */
1491 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1492 while (op1
> op2
&& op1
[-1] == np1
[-1])
1497 endmatch
= obody
+ olen
- op1
;
1499 /* Put correct value back in nbody[nlen].
1500 This is important because direct_output_for_insert
1501 can write into the line at a later point.
1502 If this screws up the zero at the end of the line, re-establish it. */
1506 /* tem gets the distance to insert or delete.
1507 endmatch is how many characters we save by doing so.
1510 tem
= (nlen
- nsp
) - (olen
- osp
);
1512 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (screen
)[tem
]))
1515 /* nsp - osp is the distance to insert or delete.
1516 If that is nonzero, begmatch is known to be nonzero also.
1517 begmatch + endmatch is how much we save by doing the ins/del.
1521 && (!char_ins_del_ok
1522 || begmatch
+ endmatch
<= char_ins_del_cost (screen
)[nsp
- osp
]))
1526 osp
= nsp
= min (osp
, nsp
);
1529 /* Now go through the line, inserting, writing and
1530 deleting as appropriate. */
1534 cursor_to (vpos
, nsp
);
1535 delete_glyphs (osp
- nsp
);
1539 /* If going to delete chars later in line
1540 and insert earlier in the line,
1541 must delete first to avoid losing data in the insert */
1542 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1544 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1545 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1546 olen
= nlen
- (nsp
- osp
);
1548 cursor_to (vpos
, osp
);
1549 insert_glyphs ((char *)0, nsp
- osp
);
1553 tem
= nsp
+ begmatch
+ endmatch
;
1554 if (nlen
!= tem
|| olen
!= tem
)
1556 cursor_to (vpos
, nsp
+ begmatch
);
1557 if (!endmatch
|| nlen
== olen
)
1559 /* If new text being written reaches right margin,
1560 there is no need to do clear-to-eol at the end.
1561 (and it would not be safe, since cursor is not
1562 going to be "at the margin" after the text is done) */
1563 if (nlen
== SCREEN_WIDTH (screen
))
1565 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1569 /* the following code loses disastrously if tem == nlen.
1570 Rather than trying to fix that case, I am trying the simpler
1571 solution found above. */
1573 /* If the text reaches to the right margin,
1574 it will lose one way or another (depending on AutoWrap)
1575 to clear to end of line after outputting all the text.
1576 So pause with one character to go and clear the line then. */
1577 if (nlen
== SCREEN_WIDTH (screen
) && fast_clear_end_of_line
&& olen
> nlen
)
1579 /* endmatch must be zero, and tem must equal nsp + begmatch */
1580 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1581 clear_end_of_line (olen
);
1582 olen
= 0; /* Don't let it be cleared again later */
1583 write_glyphs (nbody
+ nlen
- 1, 1);
1586 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1587 #endif /* OBSOLETE */
1590 else if (nlen
> olen
)
1592 write_glyphs (nbody
+ nsp
+ begmatch
, olen
- tem
);
1593 insert_glyphs (nbody
+ nsp
+ begmatch
+ olen
- tem
, nlen
- olen
);
1596 else if (olen
> nlen
)
1598 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1599 delete_glyphs (olen
- nlen
);
1605 /* If any unerased characters remain after the new line, erase them. */
1608 cursor_to (vpos
, nlen
);
1609 clear_end_of_line (olen
);
1612 /* Exchange contents between current_screen and new_screen. */
1613 temp
= desired_screen
->glyphs
[vpos
];
1614 desired_screen
->glyphs
[vpos
] = current_screen
->glyphs
[vpos
];
1615 current_screen
->glyphs
[vpos
] = temp
;
1618 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
1619 1, 1, "FOpen termscript file: ",
1620 "Start writing all terminal output to FILE as well as the terminal.\n\
1621 FILE = nil means just close any termscript file currently open.")
1625 if (termscript
!= 0) fclose (termscript
);
1630 file
= Fexpand_file_name (file
, Qnil
);
1631 termscript
= fopen (XSTRING (file
)->data
, "w");
1632 if (termscript
== 0)
1633 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
1640 window_change_signal ()
1644 int old_errno
= errno
;
1646 get_screen_size (&width
, &height
);
1648 /* The screen size change obviously applies to a termcap-controlled
1649 screen. Find such a screen in the list, and assume it's the only
1650 one (since the redisplay code always writes to stdout, not a
1651 FILE * specified in the screen structure). Record the new size,
1652 but don't reallocate the data structures now. Let that be done
1653 later outside of the signal handler. */
1658 for (tail
= Vscreen_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1660 SCREEN_PTR s
= XSCREEN (XCONS (tail
)->car
);
1662 if (s
->output_method
== output_termcap
)
1665 change_screen_size (s
, height
, width
, 0);
1672 signal (SIGWINCH
, window_change_signal
);
1675 #endif /* SIGWINCH */
1678 /* Do any change in screen size that was requested by a signal. */
1680 do_pending_window_change ()
1682 /* If window_change_signal should have run before, run it now. */
1683 while (delayed_size_change
)
1687 delayed_size_change
= 0;
1689 for (tail
= Vscreen_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1691 SCREEN_PTR s
= XSCREEN (XCONS (tail
)->car
);
1692 int height
= SCREEN_NEW_HEIGHT (s
);
1693 int width
= SCREEN_NEW_WIDTH (s
);
1695 SCREEN_NEW_HEIGHT (s
) = 0;
1696 SCREEN_NEW_WIDTH (s
) = 0;
1699 change_screen_size (s
, height
, width
, 0);
1705 /* Change the screen height and/or width. Values may be given as zero to
1706 indicate no change is to take place. */
1708 change_screen_size (screen
, newlength
, newwidth
, pretend
)
1709 register SCREEN_PTR screen
;
1710 register int newlength
, newwidth
, pretend
;
1712 /* If we can't deal with the change now, queue it for later. */
1715 SCREEN_NEW_HEIGHT (screen
) = newlength
;
1716 SCREEN_NEW_WIDTH (screen
) = newwidth
;
1717 delayed_size_change
= 1;
1721 /* This size-change overrides any pending one for this screen. */
1722 SCREEN_NEW_HEIGHT (screen
) = 0;
1723 SCREEN_NEW_WIDTH (screen
) = 0;
1725 if ((newlength
== 0 || newlength
== SCREEN_HEIGHT (screen
))
1726 && (newwidth
== 0 || newwidth
== SCREEN_WIDTH (screen
)))
1729 if (newlength
&& newlength
!= SCREEN_HEIGHT (screen
))
1731 if (XSCREEN (WINDOW_SCREEN (XWINDOW (SCREEN_MINIBUF_WINDOW (screen
))))
1733 && ! EQ (SCREEN_MINIBUF_WINDOW (screen
),
1734 SCREEN_ROOT_WINDOW (screen
)))
1736 /* Screen has both root and minibuffer. */
1737 set_window_height (SCREEN_ROOT_WINDOW (screen
),
1739 XFASTINT (XWINDOW (SCREEN_MINIBUF_WINDOW (screen
))->top
)
1741 set_window_height (SCREEN_MINIBUF_WINDOW (screen
), 1, 0);
1744 /* Screen has just one top-level window. */
1745 set_window_height (SCREEN_ROOT_WINDOW (screen
), newlength
, 0);
1747 if (SCREEN_IS_TERMCAP (screen
) == output_termcap
&& !pretend
)
1748 ScreenRows
= newlength
;
1751 if (screen
->output_method
== output_termcap
)
1753 screen_height
= newlength
;
1755 ScreenRows
= newlength
;
1760 if (newwidth
&& newwidth
!= SCREEN_WIDTH (screen
))
1762 set_window_width (SCREEN_ROOT_WINDOW (screen
), newwidth
, 0);
1763 if (XSCREEN (WINDOW_SCREEN (XWINDOW (SCREEN_MINIBUF_WINDOW (screen
))))
1765 set_window_width (SCREEN_MINIBUF_WINDOW (screen
), newwidth
, 0);
1766 SCREEN_WIDTH (screen
) = newwidth
;
1768 if (SCREEN_IS_TERMCAP (screen
) && !pretend
)
1769 ScreenCols
= newwidth
;
1771 if (screen
->output_method
== output_termcap
)
1773 screen_width
= newwidth
;
1775 ScreenCols
= newwidth
;
1781 SCREEN_HEIGHT (screen
) = newlength
;
1783 remake_screen_glyphs (screen
);
1784 calculate_costs (screen
);
1787 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
1788 Ssend_string_to_terminal
, 1, 1, 0,
1789 "Send STRING to the terminal without alteration.\n\
1790 Control characters in STRING will have terminal-dependent effects.")
1794 CHECK_STRING (str
, 0);
1795 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, stdout
);
1799 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, termscript
);
1800 fflush (termscript
);
1805 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
1806 "Beep, or flash the screen.\n\
1807 Also, unless an argument is given,\n\
1808 terminate any keyboard macro currently executing.")
1827 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
1828 error ("Keyboard macro terminated by a command ringing the bell");
1834 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
1835 "Pause, without updating display, for ARG seconds.\n\
1836 Optional second arg non-nil means ARG is measured in milliseconds.\n\
1837 \(Not all operating systems support milliseconds.)")
1839 Lisp_Object n
, millisec
;
1841 #ifndef subprocesses
1843 struct timeval timeout
, end_time
, garbage1
;
1844 #endif /* HAVE_TIMEVAL */
1845 #endif /* no subprocesses */
1849 CHECK_NUMBER (n
, 0);
1854 if (!NULL (millisec
))
1856 #ifndef HAVE_TIMEVAL
1857 error ("millisecond sit-for not supported on %s", SYSTEM_TYPE
);
1859 usec
= sec
% 1000 * 1000;
1865 wait_reading_process_input (sec
, usec
, 0, 0);
1866 #else /* No subprocesses */
1873 /* The reason this is done this way
1874 (rather than defined (H_S) && defined (H_T))
1875 is because the VMS preprocessor doesn't grok `defined' */
1878 gettimeofday (&end_time
, &garbage1
);
1879 end_time
.tv_sec
+= sec
;
1880 end_time
.tv_usec
+= usec
;
1881 if (end_time
.tv_usec
>= 1000000)
1882 end_time
.tv_sec
++, end_time
.tv_usec
-= 1000000;
1886 gettimeofday (&timeout
, &garbage1
);
1887 timeout
.tv_sec
= end_time
.tv_sec
- timeout
.tv_sec
;
1888 timeout
.tv_usec
= end_time
.tv_usec
- timeout
.tv_usec
;
1889 if (timeout
.tv_usec
< 0)
1890 timeout
.tv_usec
+= 1000000, timeout
.tv_sec
--;
1891 if (timeout
.tv_sec
< 0)
1893 if (!select (1, 0, 0, 0, &timeout
))
1896 #else /* not HAVE_TIMEVAL */
1897 /* Is it safe to quit out of `sleep'? I'm afraid to trust it. */
1899 #endif /* HAVE_TIMEVAL */
1900 #else /* not HAVE_SELECT */
1902 #endif /* HAVE_SELECT */
1903 #endif /* not VMS */
1906 #endif /* no subprocesses */
1911 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
1912 "Perform redisplay, then wait for ARG seconds or until input is available.\n\
1913 Optional second arg non-nil means ARG counts in milliseconds.\n\
1914 Optional third arg non-nil means don't redisplay, just wait for input.\n\
1915 Redisplay is preempted as always if input arrives, and does not happen\n\
1916 if input is available before it starts.\n\
1917 Value is t if waited the full time with no input arriving.")
1918 (n
, millisec
, nodisp
)
1919 Lisp_Object n
, millisec
, nodisp
;
1921 #ifndef subprocesses
1923 struct timeval timeout
;
1928 #endif /* no subprocesses */
1932 CHECK_NUMBER (n
, 0);
1934 if (detect_input_pending ())
1937 if (EQ (nodisp
, Qnil
))
1938 redisplay_preserve_echo_area ();
1944 if (!NULL (millisec
))
1946 #ifndef HAVE_TIMEVAL
1947 error ("millisecond sleep-for not supported on %s", SYSTEM_TYPE
);
1949 usec
= sec
% 1000 * 1000;
1958 wait_reading_process_input (sec
, usec
, 1, 1);
1959 #else /* no subprocesses */
1965 input_wait_timeout (XINT (n
));
1967 #ifndef HAVE_TIMEVAL
1969 select (1, &waitchannels
, 0, 0, &timeout_sec
);
1970 #else /* HAVE_TIMEVAL */
1971 timeout
.tv_sec
= sec
;
1972 timeout
.tv_usec
= usec
;
1973 select (1, &waitchannels
, 0, 0, &timeout
);
1974 #endif /* HAVE_TIMEVAL */
1975 #endif /* not VMS */
1978 #endif /* no subprocesses */
1980 return detect_input_pending () ? Qnil
: Qt
;
1983 DEFUN ("sleep-for-millisecs", Fsleep_for_millisecs
, Ssleep_for_millisecs
,
1985 "Pause, without updating display, for ARG milliseconds.")
1989 #ifndef HAVE_TIMEVAL
1990 error ("sleep-for-millisecs not supported on %s", SYSTEM_TYPE
);
1992 CHECK_NUMBER (n
, 0);
1993 wait_reading_process_input (XINT (n
) / 1000, XINT (n
) % 1000 * 1000,
1996 #endif /* HAVE_TIMEVAL */
1999 char *terminal_type
;
2001 /* Initialization done when Emacs fork is started, before doing stty. */
2002 /* Determine terminal type and set terminal_driver */
2003 /* Then invoke its decoding routine to set up variables
2004 in the terminal package */
2008 #ifdef HAVE_X_WINDOWS
2009 extern int display_arg
;
2014 cursor_in_echo_area
= 0;
2015 terminal_type
= (char *) 0;
2017 /* If the DISPLAY environment variable is set, try to use X, and
2018 die with an error message if that doesn't work. */
2020 /* Check if we're using a window system here before trying to
2021 initialize the terminal. If we check the terminal first,
2023 If someone has indicated that they want
2024 to use a window system, we shouldn't bother initializing the
2025 terminal. This is especially important when the terminal is so
2026 dumb that emacs gives up before and doesn't bother using the window
2029 #ifdef HAVE_X_WINDOWS
2030 if (!inhibit_window_system
&& (display_arg
|| egetenv ("DISPLAY")))
2032 Vwindow_system
= intern ("x");
2034 Vwindow_system_version
= make_number (11);
2036 Vwindow_system_version
= make_number (10);
2040 #endif /* HAVE_X_WINDOWS */
2042 /* If no window system has been specified, try to use the terminal. */
2045 fprintf (stderr
, "emacs: standard input is not a tty\n");
2049 /* Look at the TERM variable */
2050 terminal_type
= (char *) getenv ("TERM");
2054 fprintf (stderr
, "Please specify your terminal type.\n\
2055 For types defined in VMS, use set term /device=TYPE.\n\
2056 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2057 \(The quotation marks are necessary since terminal types are lower case.)\n");
2059 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2065 /* VMS DCL tends to upcase things, so downcase term type.
2066 Hardly any uppercase letters in terminal types; should be none. */
2068 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2071 strcpy (new, terminal_type
);
2073 for (p
= new; *p
; p
++)
2077 terminal_type
= new;
2081 term_init (terminal_type
);
2083 remake_screen_glyphs (selected_screen
);
2084 calculate_costs (selected_screen
);
2086 /* X and Y coordinates of the cursor between updates. */
2087 SCREEN_CURSOR_X (selected_screen
) = 0;
2088 SCREEN_CURSOR_Y (selected_screen
) = 0;
2093 #endif /* CANNOT_DUMP */
2094 signal (SIGWINCH
, window_change_signal
);
2095 #endif /* SIGWINCH */
2101 defsubr (&Sredraw_screen
);
2103 defsubr (&Sredraw_display
);
2104 defsubr (&Sopen_termscript
);
2106 defsubr (&Ssit_for
);
2107 defsubr (&Ssleep_for
);
2108 defsubr (&Ssend_string_to_terminal
);
2110 DEFVAR_INT ("baud-rate", &baud_rate
,
2111 "The output baud rate of the terminal.\n\
2112 On most systems, changing this value will affect the amount of padding\n\
2113 and the other strategic decisions made during redisplay.");
2114 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2115 "*Non-nil means invert the entire screen display.\n\
2116 This means everything is in inverse video which otherwise would not be.");
2117 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2118 "*Non-nil means try to flash the screen to represent a bell.");
2119 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2120 "*Non-nil means no need to redraw entire screen after suspending.\n\
2121 A non-nil value is useful if the terminal can automatically preserve\n\
2122 Emacs's screen display when you reenter Emacs.\n\
2123 It is up to you to set this variable if your terminal can do that.");
2124 DEFVAR_LISP ("window-system", &Vwindow_system
,
2125 "A symbol naming the window-system under which Emacs is running\n\
2126 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2127 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2128 "The version number of the window system in use.\n\
2129 For X windows, this is 10 or 11.");
2130 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2131 "Non-nil means put cursor in minibuffer, at end of any message there.");
2132 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2133 "Table defining how to output a glyph code to the screen.\n\
2134 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2135 Each element can be:\n\
2136 integer: a glyph code which this glyph is an alias for.\n\
2137 string: output this glyph using that string (not impl. in X windows).\n\
2138 nil: this glyph mod 256 is char code to output,\n\
2139 and this glyph / 256 is face code for X windows (see `x-set-face').");
2140 Vglyph_table
= Qnil
;
2142 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2143 "Display table to use for buffers that specify none.\n\
2144 See `buffer-display-table' for more information.");
2145 Vstandard_display_table
= Qnil
;
2147 /* Initialize `window-system', unless init_display already decided it. */
2152 Vwindow_system
= Qnil
;
2153 Vwindow_system_version
= Qnil
;