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. */
62 #include "dispextern.h"
72 #endif /* HAVE_X_WINDOWS */
74 #define max(a, b) ((a) > (b) ? (a) : (b))
75 #define min(a, b) ((a) < (b) ? (a) : (b))
77 #ifndef PENDING_OUTPUT_COUNT
78 /* Get number of chars of output now in the buffer of a stdio stream.
79 This ought to be built in in stdio, but it isn't.
80 Some s- files override this because their stdio internals differ. */
81 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
84 /* Nonzero means do not assume anything about current
85 contents of actual terminal screen */
89 /* Nonzero means last display completed. Zero means it was preempted. */
91 int display_completed
;
93 /* Lisp variable visible-bell; enables use of screen-flash
94 instead of audible bell. */
98 /* Invert the color of the whole screen, at a low level. */
102 /* Line speed of the terminal. */
106 /* nil or a symbol naming the window system under which emacs is
107 running ('x is the only current possibility). */
109 Lisp_Object Vwindow_system
;
111 /* Version number of X windows: 10, 11 or nil. */
112 Lisp_Object Vwindow_system_version
;
114 /* Vector of glyph definitions. Indexed by glyph number,
115 the contents are a string which is how to output the glyph.
117 If Vglyph_table is nil, a glyph is output by using its low 8 bits
118 as a character code. */
120 Lisp_Object Vglyph_table
;
122 /* Display table to use for vectors that don't specify their own. */
124 Lisp_Object Vstandard_display_table
;
126 /* Nonzero means reading single-character input with prompt
127 so put cursor on minibuffer after the prompt. */
129 int cursor_in_echo_area
;
131 /* The currently selected screen.
132 In a single-screen version, this variable always remains 0. */
134 SCREEN_PTR selected_screen
;
136 /* In a single-screen version, the information that would otherwise
137 exist inside a `struct screen' lives in the following variables instead. */
141 /* Desired terminal cursor position (to show position of point),
146 /* Description of current screen contents */
148 struct screen_glyphs
*current_glyphs
;
150 /* Description of desired screen contents */
152 struct screen_glyphs
*desired_glyphs
;
154 #endif /* not MULTI_SCREEN */
156 /* This is a vector, made larger whenever it isn't large enough,
157 which is used inside `update_screen' to hold the old contents
158 of the SCREEN_PHYS_LINES of the screen being updated. */
159 struct screen_glyphs
**ophys_lines
;
160 /* Length of vector currently allocated. */
161 int ophys_lines_length
;
163 FILE *termscript
; /* Stdio stream being used for copy of all output. */
165 struct cm Wcm
; /* Structure for info on cursor positioning */
167 extern short ospeed
; /* Output speed (from sg_ospeed) */
169 int in_display
; /* 1 if in redisplay: can't handle SIGWINCH now. */
171 int delayed_size_change
; /* 1 means SIGWINCH happened when not safe. */
172 int delayed_screen_height
; /* Remembered new screen height. */
173 int delayed_screen_width
; /* Remembered new screen width. */
177 DEFUN ("redraw-screen", Fredraw_screen
, Sredraw_screen
, 1, 1, 0,
178 "Clear screen SCREEN and output again what is supposed to appear on it.")
184 CHECK_LIVE_SCREEN (screen
, 0);
185 s
= XSCREEN (screen
);
187 /* set_terminal_modes (); */
191 clear_screen_records (s
);
192 windows_or_buffers_changed
++;
193 /* Mark all windows as INaccurate,
194 so that every window will have its redisplay done. */
195 mark_window_display_accurate (SCREEN_ROOT_WINDOW (s
), 0);
200 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, "",
201 "Redraw all screens marked as having their images garbled.")
204 Lisp_Object screen
, tail
;
206 for (tail
= Vscreen_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
208 screen
= XCONS (tail
)->car
;
209 if (XSCREEN (screen
)->garbaged
&& XSCREEN (screen
)->visible
)
210 Fredraw_screen (screen
);
219 XSET (screen
, Lisp_Screen
, s
);
220 Fredraw_screen (screen
);
223 #else /* not MULTI_SCREEN */
225 DEFUN ("redraw-display", Fredraw_display
, Sredraw_display
, 0, 0, 0,
226 "Clear screen and output again what is supposed to appear on it.")
230 set_terminal_modes ();
234 clear_screen_records (0);
235 windows_or_buffers_changed
++;
236 /* Mark all windows as INaccurate,
237 so that every window will have its redisplay done. */
238 mark_window_display_accurate (XWINDOW (minibuf_window
)->prev
, 0);
242 #endif /* not MULTI_SCREEN */
244 static struct screen_glyphs
*
245 make_screen_glyphs (screen
, empty
)
246 register SCREEN_PTR screen
;
250 register width
= SCREEN_WIDTH (screen
);
251 register height
= SCREEN_HEIGHT (screen
);
252 register struct screen_glyphs
*new =
253 (struct screen_glyphs
*) xmalloc (sizeof (struct screen_glyphs
));
255 SET_GLYPHS_SCREEN (new, screen
);
256 new->height
= height
;
258 new->used
= (int *) xmalloc (height
* sizeof (int));
259 new->glyphs
= (GLYPH
**) xmalloc (height
* sizeof (GLYPH
*));
260 new->highlight
= (char *) xmalloc (height
* sizeof (char));
261 new->enable
= (char *) xmalloc (height
* sizeof (char));
262 bzero (new->enable
, height
* sizeof (char));
263 new->bufp
= (int *) xmalloc (height
* sizeof (int));
265 #ifdef HAVE_X_WINDOWS
266 if (SCREEN_IS_X (screen
))
268 new->nruns
= (int *) xmalloc (height
* sizeof (int));
270 = (struct run
**) xmalloc (height
* sizeof (struct run
*));
271 new->top_left_x
= (short *) xmalloc (height
* sizeof (short));
272 new->top_left_y
= (short *) xmalloc (height
* sizeof (short));
273 new->pix_width
= (short *) xmalloc (height
* sizeof (short));
274 new->pix_height
= (short *) xmalloc (height
* sizeof (short));
280 /* Make the buffer used by decode_mode_spec. This buffer is also
281 used as temporary storage when updating the screen. See scroll.c. */
282 unsigned int total_glyphs
= (width
+ 2) * sizeof (GLYPH
);
284 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
285 bzero (new->total_contents
, total_glyphs
);
289 unsigned int total_glyphs
= height
* (width
+ 2) * sizeof (GLYPH
);
291 new->total_contents
= (GLYPH
*) xmalloc (total_glyphs
);
292 bzero (new->total_contents
, total_glyphs
);
293 for (i
= 0; i
< height
; i
++)
294 new->glyphs
[i
] = new->total_contents
+ i
* (width
+ 2) + 1;
301 free_screen_glyphs (screen
, glyphs
)
303 struct screen_glyphs
*glyphs
;
305 if (glyphs
->total_contents
)
306 free (glyphs
->total_contents
);
309 free (glyphs
->glyphs
);
310 free (glyphs
->highlight
);
311 free (glyphs
->enable
);
314 #ifdef HAVE_X_WINDOWS
315 if (SCREEN_IS_X (screen
))
317 free (glyphs
->nruns
);
318 free (glyphs
->face_list
);
319 free (glyphs
->top_left_x
);
320 free (glyphs
->top_left_y
);
321 free (glyphs
->pix_width
);
322 free (glyphs
->pix_height
);
330 remake_screen_glyphs (screen
)
333 if (SCREEN_CURRENT_GLYPHS (screen
))
334 free_screen_glyphs (screen
, SCREEN_CURRENT_GLYPHS (screen
));
335 if (SCREEN_DESIRED_GLYPHS (screen
))
336 free_screen_glyphs (screen
, SCREEN_DESIRED_GLYPHS (screen
));
337 if (SCREEN_TEMP_GLYPHS (screen
))
338 free_screen_glyphs (screen
, SCREEN_TEMP_GLYPHS (screen
));
340 if (SCREEN_MESSAGE_BUF (screen
))
341 SCREEN_MESSAGE_BUF (screen
)
342 = (char *) xrealloc (SCREEN_MESSAGE_BUF (screen
),
343 SCREEN_WIDTH (screen
) + 1);
345 SCREEN_MESSAGE_BUF (screen
)
346 = (char *) xmalloc (SCREEN_WIDTH (screen
) + 1);
348 SCREEN_CURRENT_GLYPHS (screen
) = make_screen_glyphs (screen
, 0);
349 SCREEN_DESIRED_GLYPHS (screen
) = make_screen_glyphs (screen
, 0);
350 SCREEN_TEMP_GLYPHS (screen
) = make_screen_glyphs (screen
, 1);
351 SET_SCREEN_GARBAGED (screen
);
354 /* Return the hash code of contents of line VPOS in screen-matrix M. */
357 line_hash_code (m
, vpos
)
358 register struct screen_glyphs
*m
;
361 register GLYPH
*body
, *end
;
364 if (!m
->enable
[vpos
])
367 /* Give all lighlighted lines the same hash code
368 so as to encourage scrolling to leave them in place. */
369 if (m
->highlight
[vpos
])
372 body
= m
->glyphs
[vpos
];
374 if (must_write_spaces
)
381 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
- SPACEGLYPH
;
390 h
= (((h
<< 4) + (h
>> 24)) & 0x0fffffff) + g
;
398 /* Return number of characters in line in M at vpos VPOS,
399 except don't count leading and trailing spaces
400 unless the terminal requires those to be explicitly output. */
403 line_draw_cost (m
, vpos
)
404 struct screen_glyphs
*m
;
407 register GLYPH
*beg
= m
->glyphs
[vpos
];
408 register GLYPH
*end
= m
->glyphs
[vpos
] + m
->used
[vpos
];
410 register int tlen
= GLYPH_TABLE_LENGTH
;
411 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
413 /* Ignore trailing and leading spaces if we can. */
414 if (!must_write_spaces
)
416 while ((end
!= beg
) && (*end
== SPACEGLYPH
))
419 return (0); /* All blank line. */
421 while (*beg
== SPACEGLYPH
)
425 /* If we don't have a glyph-table, each glyph is one character,
426 so return the number of glyphs. */
430 /* Otherwise, scan the glyphs and accumulate their total size in I. */
432 while ((beg
<= end
) && *beg
)
434 register GLYPH g
= *beg
++;
436 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
439 i
+= GLYPH_LENGTH (tbase
, g
);
444 /* The functions on this page are the interface from xdisp.c to redisplay.
446 The only other interface into redisplay is through setting
447 SCREEN_CURSOR_X (screen) and SCREEN_CURSOR_Y (screen)
448 and SET_SCREEN_GARBAGED (screen). */
450 /* cancel_line eliminates any request to display a line at position `vpos' */
452 cancel_line (vpos
, screen
)
454 register SCREEN_PTR screen
;
456 SCREEN_DESIRED_GLYPHS (screen
)->enable
[vpos
] = 0;
459 clear_screen_records (screen
)
460 register SCREEN_PTR screen
;
462 bzero (SCREEN_CURRENT_GLYPHS (screen
)->enable
, SCREEN_HEIGHT (screen
));
465 /* Prepare to display on line VPOS starting at HPOS within it. */
468 get_display_line (screen
, vpos
, hpos
)
469 register SCREEN_PTR screen
;
473 register struct screen_glyphs
*glyphs
;
474 register struct screen_glyphs
*desired_glyphs
= SCREEN_DESIRED_GLYPHS (screen
);
477 if (vpos
< 0 || (! SCREEN_VISIBLE_P (screen
)))
480 if ((desired_glyphs
->enable
[vpos
]) && desired_glyphs
->used
[vpos
] > hpos
)
483 if (! desired_glyphs
->enable
[vpos
])
485 desired_glyphs
->used
[vpos
] = 0;
486 desired_glyphs
->highlight
[vpos
] = 0;
487 desired_glyphs
->enable
[vpos
] = 1;
490 if (hpos
> desired_glyphs
->used
[vpos
])
492 GLYPH
*g
= desired_glyphs
->glyphs
[vpos
] + desired_glyphs
->used
[vpos
];
493 GLYPH
*end
= desired_glyphs
->glyphs
[vpos
] + hpos
;
495 desired_glyphs
->used
[vpos
] = hpos
;
501 /* Like bcopy except never gets confused by overlap. */
504 safe_bcopy (from
, to
, size
)
514 /* If destination is higher in memory, and overlaps source zone,
515 copy from the end. */
516 if (from
< to
&& from
+ size
> to
)
521 /* If TO - FROM is large, then we should break the copy into
522 nonoverlapping chunks of TO - FROM bytes each. However, if
523 TO - FROM is small, then the bcopy function call overhead
524 makes this not worth it. The crossover point could be about
525 anywhere. Since I don't think the obvious copy loop is ever
526 too bad, I'm trying to err in its favor. */
531 while (endf
!= from
);
535 /* Since TO - FROM >= 64, the overlap is less than SIZE,
536 so we can always safely do this loop once. */
542 bcopy (endf
, endt
, to
- from
);
545 /* If TO - FROM wasn't a multiple of SIZE, there will be a
546 little left over. The amount left over is
547 (endt + (to - from)) - to, which is endt - from. */
548 bcopy (from
, to
, endt
- from
);
552 bcopy (from
, to
, size
);
557 safe_bcopy (from
, to
, size
)
567 /* If destination is higher in memory, and overlaps source zone,
568 copy from the end. */
569 if (from
< to
&& from
+ size
> to
)
576 while (endf
!= from
);
581 bcopy (from
, to
, size
);
585 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes.
586 DISTANCE may be negative. */
589 rotate_vector (vector
, size
, distance
)
594 char *temp
= (char *) alloca (size
);
599 bcopy (vector
, temp
+ distance
, size
- distance
);
600 bcopy (vector
+ size
- distance
, temp
, distance
);
601 bcopy (temp
, vector
, size
);
604 /* Scroll lines from vpos FROM up to but not including vpos END
605 down by AMOUNT lines (AMOUNT may be negative).
606 Returns nonzero if done, zero if terminal cannot scroll them. */
609 scroll_screen_lines (screen
, from
, end
, amount
)
610 register SCREEN_PTR screen
;
611 int from
, end
, amount
;
614 register struct screen_glyphs
*current_screen
615 = SCREEN_CURRENT_GLYPHS (screen
);
617 if (!line_ins_del_ok
)
625 update_begin (screen
);
626 set_terminal_window (end
+ amount
);
627 if (!scroll_region_ok
)
628 ins_del_lines (end
, -amount
);
629 ins_del_lines (from
, amount
);
630 set_terminal_window (0);
632 rotate_vector (current_screen
->glyphs
+ from
,
633 sizeof (GLYPH
*) * (end
+ amount
- from
),
634 amount
* sizeof (GLYPH
*));
636 safe_bcopy (current_screen
->used
+ from
,
637 current_screen
->used
+ from
+ amount
,
638 (end
- from
) * sizeof current_screen
->used
[0]);
640 safe_bcopy (current_screen
->highlight
+ from
,
641 current_screen
->highlight
+ from
+ amount
,
642 (end
- from
) * sizeof current_screen
->highlight
[0]);
644 safe_bcopy (current_screen
->enable
+ from
,
645 current_screen
->enable
+ from
+ amount
,
646 (end
- from
) * sizeof current_screen
->enable
[0]);
648 /* Mark the lines made empty by scrolling as enabled, empty and
650 bzero (current_screen
->used
+ from
,
651 amount
* sizeof current_screen
->used
[0]);
652 bzero (current_screen
->highlight
+ from
,
653 amount
* sizeof current_screen
->highlight
[0]);
654 for (i
= from
; i
< from
+ amount
; i
++)
656 current_screen
->glyphs
[i
][0] = '\0';
657 current_screen
->enable
[i
] = 1;
660 safe_bcopy (current_screen
->bufp
+ from
,
661 current_screen
->bufp
+ from
+ amount
,
662 (end
- from
) * sizeof current_screen
->bufp
[0]);
664 #ifdef HAVE_X_WINDOWS
665 if (SCREEN_IS_X (screen
))
667 safe_bcopy (current_screen
->nruns
+ from
,
668 current_screen
->nruns
+ from
+ amount
,
669 (end
- from
) * sizeof current_screen
->nruns
[0]);
671 safe_bcopy (current_screen
->face_list
+ from
,
672 current_screen
->face_list
+ from
+ amount
,
673 (end
- from
) * sizeof current_screen
->face_list
[0]);
675 safe_bcopy (current_screen
->top_left_x
+ from
,
676 current_screen
->top_left_x
+ from
+ amount
,
677 (end
- from
) * sizeof current_screen
->top_left_x
[0]);
679 safe_bcopy (current_screen
->top_left_y
+ from
,
680 current_screen
->top_left_y
+ from
+ amount
,
681 (end
- from
) * sizeof current_screen
->top_left_y
[0]);
683 safe_bcopy (current_screen
->pix_width
+ from
,
684 current_screen
->pix_width
+ from
+ amount
,
685 (end
- from
) * sizeof current_screen
->pix_width
[0]);
687 safe_bcopy (current_screen
->pix_height
+ from
,
688 current_screen
->pix_height
+ from
+ amount
,
689 (end
- from
) * sizeof current_screen
->pix_height
[0]);
691 #endif /* HAVE_X_WINDOWS */
697 update_begin (screen
);
698 set_terminal_window (end
);
699 ins_del_lines (from
+ amount
, amount
);
700 if (!scroll_region_ok
)
701 ins_del_lines (end
+ amount
, -amount
);
702 set_terminal_window (0);
704 rotate_vector (current_screen
->glyphs
+ from
+ amount
,
705 sizeof (GLYPH
*) * (end
- from
- amount
),
706 amount
* sizeof (GLYPH
*));
708 safe_bcopy (current_screen
->used
+ from
,
709 current_screen
->used
+ from
+ amount
,
710 (end
- from
) * sizeof current_screen
->used
[0]);
712 safe_bcopy (current_screen
->highlight
+ from
,
713 current_screen
->highlight
+ from
+ amount
,
714 (end
- from
) * sizeof current_screen
->highlight
[0]);
716 safe_bcopy (current_screen
->enable
+ from
,
717 current_screen
->enable
+ from
+ amount
,
718 (end
- from
) * sizeof current_screen
->enable
[0]);
720 /* Mark the lines made empty by scrolling as enabled, empty and
722 bzero (current_screen
->used
+ end
+ amount
,
723 - amount
* sizeof current_screen
->used
[0]);
724 bzero (current_screen
->highlight
+ end
+ amount
,
725 - amount
* sizeof current_screen
->highlight
[0]);
726 for (i
= end
+ amount
; i
< end
; i
++)
728 current_screen
->glyphs
[i
][0] = '\0';
729 current_screen
->enable
[i
] = 1;
732 safe_bcopy (current_screen
->bufp
+ from
,
733 current_screen
->bufp
+ from
+ amount
,
734 (end
- from
) * sizeof current_screen
->bufp
[0]);
736 #ifdef HAVE_X_WINDOWS
737 if (SCREEN_IS_X (screen
))
739 safe_bcopy (current_screen
->nruns
+ from
,
740 current_screen
->nruns
+ from
+ amount
,
741 (end
- from
) * sizeof current_screen
->nruns
[0]);
743 safe_bcopy (current_screen
->face_list
+ from
,
744 current_screen
->face_list
+ from
+ amount
,
745 (end
- from
) * sizeof current_screen
->face_list
[0]);
747 safe_bcopy (current_screen
->top_left_x
+ from
,
748 current_screen
->top_left_x
+ from
+ amount
,
749 (end
- from
) * sizeof current_screen
->top_left_x
[0]);
751 safe_bcopy (current_screen
->top_left_y
+ from
,
752 current_screen
->top_left_y
+ from
+ amount
,
753 (end
- from
) * sizeof current_screen
->top_left_y
[0]);
755 safe_bcopy (current_screen
->pix_width
+ from
,
756 current_screen
->pix_width
+ from
+ amount
,
757 (end
- from
) * sizeof current_screen
->pix_width
[0]);
759 safe_bcopy (current_screen
->pix_height
+ from
,
760 current_screen
->pix_height
+ from
+ amount
,
761 (end
- from
) * sizeof current_screen
->pix_height
[0]);
763 #endif /* HAVE_X_WINDOWS */
770 /* After updating a window W that isn't the full screen wide,
771 copy all the columns that W does not occupy
772 into the SCREEN_DESIRED_GLYPHS (screen) from the SCREEN_PHYS_GLYPHS (screen)
773 so that update_screen will not change those columns. */
775 preserve_other_columns (w
)
779 register struct screen_glyphs
*current_screen
, *desired_screen
;
780 register SCREEN_PTR screen
= XSCREEN (w
->screen
);
781 int start
= XFASTINT (w
->left
);
782 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
783 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
785 current_screen
= SCREEN_CURRENT_GLYPHS (screen
);
786 desired_screen
= SCREEN_DESIRED_GLYPHS (screen
);
788 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
790 if (current_screen
->enable
[vpos
] && desired_screen
->enable
[vpos
])
796 bcopy (current_screen
->glyphs
[vpos
],
797 desired_screen
->glyphs
[vpos
], start
);
798 len
= min (start
, current_screen
->used
[vpos
]);
799 if (desired_screen
->used
[vpos
] < len
)
800 desired_screen
->used
[vpos
] = len
;
802 if (current_screen
->used
[vpos
] > end
803 && desired_screen
->used
[vpos
] < current_screen
->used
[vpos
])
805 while (desired_screen
->used
[vpos
] < end
)
806 desired_screen
->glyphs
[vpos
][desired_screen
->used
[vpos
]++]
808 bcopy (current_screen
->glyphs
[vpos
] + end
,
809 desired_screen
->glyphs
[vpos
] + end
,
810 current_screen
->used
[vpos
] - end
);
811 desired_screen
->used
[vpos
] = current_screen
->used
[vpos
];
819 /* If window w does not need to be updated and isn't the full screen wide,
820 copy all the columns that w does occupy
821 into the SCREEN_DESIRED_LINES (screen) from the SCREEN_PHYS_LINES (screen)
822 so that update_screen will not change those columns.
824 Have not been able to figure out how to use this correctly. */
826 preserve_my_columns (w
)
829 register int vpos
, fin
;
830 register struct screen_glyphs
*l1
, *l2
;
831 register SCREEN_PTR screen
= XSCREEN (w
->screen
);
832 int start
= XFASTINT (w
->left
);
833 int end
= XFASTINT (w
->left
) + XFASTINT (w
->width
);
834 int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
836 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
838 if ((l1
= SCREEN_DESIRED_GLYPHS (screen
)->glyphs
[vpos
+ 1])
839 && (l2
= SCREEN_PHYS_GLYPHS (screen
)->glyphs
[vpos
+ 1]))
841 if (l2
->length
> start
&& l1
->length
< l2
->length
)
844 if (fin
> end
) fin
= end
;
845 while (l1
->length
< start
)
846 l1
->body
[l1
->length
++] = ' ';
847 bcopy (l2
->body
+ start
, l1
->body
+ start
, fin
- start
);
856 /* On discovering that the redisplay for a window was no good,
857 cancel the columns of that window, so that when the window is
858 displayed over again get_display_line will not complain. */
860 cancel_my_columns (w
)
864 register SCREEN_PTR screen
= XSCREEN (w
->screen
);
865 register struct screen_glyphs
*desired_glyphs
= screen
->desired_glyphs
;
866 register int start
= XFASTINT (w
->left
);
867 register int bot
= XFASTINT (w
->top
) + XFASTINT (w
->height
);
869 for (vpos
= XFASTINT (w
->top
); vpos
< bot
; vpos
++)
870 if (desired_glyphs
->enable
[vpos
]
871 && desired_glyphs
->used
[vpos
] >= start
)
872 desired_glyphs
->used
[vpos
] = start
;
875 /* These functions try to perform directly and immediately on the screen
876 the necessary output for one change in the buffer.
877 They may return 0 meaning nothing was done if anything is difficult,
878 or 1 meaning the output was performed properly.
879 They assume that the screen was up to date before the buffer
880 change being displayed. THey make various other assumptions too;
881 see command_loop_1 where these are called. */
884 direct_output_for_insert (g
)
887 register SCREEN_PTR screen
= selected_screen
;
888 register struct screen_glyphs
*current_screen
889 = SCREEN_CURRENT_GLYPHS (screen
);
891 #ifndef COMPILER_REGISTER_BUG
893 #endif /* COMPILER_REGISTER_BUG */
894 struct window
*w
= XWINDOW (selected_window
);
895 #ifndef COMPILER_REGISTER_BUG
897 #endif /* COMPILER_REGISTER_BUG */
898 int hpos
= SCREEN_CURSOR_X (screen
);
899 #ifndef COMPILER_REGISTER_BUG
901 #endif /* COMPILER_REGISTER_BUG */
902 int vpos
= SCREEN_CURSOR_Y (screen
);
904 /* Give up if about to continue line */
905 if (hpos
- XFASTINT (w
->left
) + 1 + 1 >= XFASTINT (w
->width
)
907 /* Avoid losing if cursor is in invisible text off left margin */
908 || (XINT (w
->hscroll
) && hpos
== XFASTINT (w
->left
))
910 /* Give up if cursor outside window (in minibuf, probably) */
911 || SCREEN_CURSOR_Y (screen
) < XFASTINT (w
->top
)
912 || SCREEN_CURSOR_Y (screen
) >= XFASTINT (w
->top
) + XFASTINT (w
->height
)
914 /* Give up if cursor not really at SCREEN_CURSOR_X, SCREEN_CURSOR_Y */
915 || !display_completed
917 /* Give up if buffer appears in two places. */
920 /* Give up if w is minibuffer and a message is being displayed there */
921 || (MINI_WINDOW_P (w
) && echo_area_glyphs
))
924 current_screen
->glyphs
[vpos
][hpos
] = g
;
925 unchanged_modified
= MODIFF
;
926 beg_unchanged
= GPT
- BEG
;
927 XFASTINT (w
->last_point
) = point
;
928 XFASTINT (w
->last_point_x
) = hpos
;
929 XFASTINT (w
->last_modified
) = MODIFF
;
931 reassert_line_highlight (0, vpos
);
932 write_glyphs (¤t_screen
->glyphs
[vpos
][hpos
], 1);
934 ++SCREEN_CURSOR_X (screen
);
935 if (hpos
== current_screen
->used
[vpos
])
937 current_screen
->used
[vpos
] = hpos
+ 1;
938 current_screen
->glyphs
[vpos
][hpos
+ 1] = 0;
945 direct_output_forward_char (n
)
948 register SCREEN_PTR screen
= selected_screen
;
949 register struct window
*w
= XWINDOW (selected_window
);
951 /* Avoid losing if cursor is in invisible text off left margin */
952 if (XINT (w
->hscroll
) && SCREEN_CURSOR_X (screen
) == XFASTINT (w
->left
))
955 SCREEN_CURSOR_X (screen
) += n
;
956 XFASTINT (w
->last_point_x
) = SCREEN_CURSOR_X (screen
);
957 XFASTINT (w
->last_point
) = point
;
958 cursor_to (SCREEN_CURSOR_Y (screen
), SCREEN_CURSOR_X (screen
));
963 static void update_line ();
965 /* Update screen S based on the data in SCREEN_DESIRED_GLYPHS.
966 Value is nonzero if redisplay stopped due to pending input.
967 FORCE nonzero means do not stop for pending input. */
970 update_screen (s
, force
, inhibit_hairy_id
)
973 int inhibit_hairy_id
;
975 register struct screen_glyphs
*current_screen
= SCREEN_CURRENT_GLYPHS (s
);
976 register struct screen_glyphs
*desired_screen
= SCREEN_DESIRED_GLYPHS (s
);
979 int preempt_count
= baud_rate
/ 2400 + 1;
980 extern input_pending
;
981 #ifdef HAVE_X_WINDOWS
982 register int downto
, leftmost
;
985 if (SCREEN_HEIGHT (s
) == 0) abort (); /* Some bug zeros some core */
987 detect_input_pending ();
988 if (input_pending
&& !force
)
996 if (!line_ins_del_ok
)
997 inhibit_hairy_id
= 1;
999 /* See if any of the desired lines are enabled; don't compute for
1000 i/d line if just want cursor motion. */
1001 for (i
= 0; i
< SCREEN_HEIGHT (s
); i
++)
1002 if (desired_screen
->enable
[i
])
1005 /* Try doing i/d line, if not yet inhibited. */
1006 if (!inhibit_hairy_id
&& i
< SCREEN_HEIGHT (s
))
1007 force
|= scrolling (s
);
1009 /* Update the individual lines as needed. Do bottom line first. */
1011 if (desired_screen
->enable
[SCREEN_HEIGHT (s
) - 1])
1012 update_line (s
, SCREEN_HEIGHT (s
) - 1);
1014 #ifdef HAVE_X_WINDOWS
1015 if (SCREEN_IS_X (s
))
1017 leftmost
= downto
= s
->display
.x
->internal_border_width
;
1018 if (desired_screen
->enable
[0])
1020 current_screen
->top_left_x
[SCREEN_HEIGHT (s
) - 1] = leftmost
;
1021 current_screen
->top_left_y
[SCREEN_HEIGHT (s
) - 1]
1022 = PIXEL_HEIGHT (s
) - s
->display
.x
->internal_border_width
1023 - LINE_HEIGHT(s
, SCREEN_HEIGHT (s
) - 1);
1024 current_screen
->top_left_x
[0] = leftmost
;
1025 current_screen
->top_left_y
[0] = downto
;
1028 #endif /* HAVE_X_WINDOWS */
1030 /* Now update the rest of the lines. */
1031 for (i
= 0; i
< SCREEN_HEIGHT (s
) - 1 && (force
|| !input_pending
); i
++)
1033 if (desired_screen
->enable
[i
])
1035 if (SCREEN_IS_TERMCAP (s
))
1037 /* Flush out every so many lines.
1038 Also flush out if likely to have more than 1k buffered
1039 otherwise. I'm told that some telnet connections get
1040 really screwed by more than 1k output at once. */
1041 int outq
= PENDING_OUTPUT_COUNT (stdout
);
1043 || (outq
> 20 && ((i
- 1) % preempt_count
== 0)))
1046 if (preempt_count
== 1)
1049 if (ioctl (0, TIOCOUTQ
, &outq
) < 0)
1050 /* Probably not a tty. Ignore the error and reset
1051 * the outq count. */
1052 outq
= PENDING_OUTPUT_COUNT (stdout
);
1055 sleep (outq
/ baud_rate
);
1058 if ((i
- 1) % preempt_count
== 0)
1059 detect_input_pending ();
1063 #ifdef HAVE_X_WINDOWS
1064 if (SCREEN_IS_X (s
))
1066 current_screen
->top_left_y
[i
] = downto
;
1067 current_screen
->top_left_x
[i
] = leftmost
;
1069 #endif /* HAVE_X_WINDOWS */
1072 if (SCREEN_IS_X (s
))
1073 downto
+= LINE_HEIGHT(s
, i
);
1075 pause
= (i
< SCREEN_HEIGHT (s
) - 1) ? i
: 0;
1077 /* Now just clean up termcap drivers and set cursor, etc. */
1081 if (s
== selected_screen
&& cursor_in_echo_area
< 0)
1082 cursor_to (SCREEN_HEIGHT (s
) - 1, 0);
1083 else if (s
== selected_screen
&& cursor_in_echo_area
1084 && !desired_screen
->used
[SCREEN_HEIGHT (s
) - 1])
1085 cursor_to (SCREEN_HEIGHT (s
), 0);
1086 else if (cursor_in_echo_area
)
1087 cursor_to (SCREEN_HEIGHT (s
) - 1,
1088 min (SCREEN_WIDTH (s
) - 1,
1089 desired_screen
->used
[SCREEN_HEIGHT (s
) - 1]));
1091 cursor_to (SCREEN_CURSOR_Y (s
), max (min (SCREEN_CURSOR_X (s
),
1092 SCREEN_WIDTH (s
) - 1), 0));
1098 fflush (termscript
);
1101 /* Here if output is preempted because input is detected. */
1104 if (SCREEN_HEIGHT (s
) == 0) abort (); /* Some bug zeros some core */
1105 display_completed
= !pause
;
1107 bzero (desired_screen
->enable
, SCREEN_HEIGHT (s
));
1111 /* Called when about to quit, to check for doing so
1112 at an improper time. */
1117 if (SCREEN_DESIRED_GLYPHS (selected_screen
) == 0)
1119 if (SCREEN_DESIRED_GLYPHS (selected_screen
)->enable
[0])
1121 if (SCREEN_DESIRED_GLYPHS (selected_screen
)->enable
[SCREEN_HEIGHT (selected_screen
) - 1])
1125 /* Decide what insert/delete line to do, and do it */
1127 extern void scrolling_1 ();
1132 int unchanged_at_top
, unchanged_at_bottom
;
1135 int *old_hash
= (int *) alloca (SCREEN_HEIGHT (screen
) * sizeof (int));
1136 int *new_hash
= (int *) alloca (SCREEN_HEIGHT (screen
) * sizeof (int));
1137 int *draw_cost
= (int *) alloca (SCREEN_HEIGHT (screen
) * sizeof (int));
1139 int free_at_end_vpos
= SCREEN_HEIGHT (screen
);
1140 register struct screen_glyphs
*current_screen
= SCREEN_CURRENT_GLYPHS (screen
);
1141 register struct screen_glyphs
*desired_screen
= SCREEN_DESIRED_GLYPHS (screen
);
1143 /* Compute hash codes of all the lines.
1144 Also calculate number of changed lines,
1145 number of unchanged lines at the beginning,
1146 and number of unchanged lines at the end. */
1149 unchanged_at_top
= 0;
1150 unchanged_at_bottom
= SCREEN_HEIGHT (screen
);
1151 for (i
= 0; i
< SCREEN_HEIGHT (screen
); i
++)
1153 /* Give up on this scrolling if some old lines are not enabled. */
1154 if (!current_screen
->enable
[i
])
1156 old_hash
[i
] = line_hash_code (current_screen
, i
);
1157 if (! desired_screen
->enable
[i
])
1158 new_hash
[i
] = old_hash
[i
];
1160 new_hash
[i
] = line_hash_code (desired_screen
, i
);
1162 if (old_hash
[i
] != new_hash
[i
])
1165 unchanged_at_bottom
= SCREEN_HEIGHT (screen
) - i
- 1;
1167 else if (i
== unchanged_at_top
)
1169 draw_cost
[i
] = line_draw_cost (desired_screen
, i
);
1172 /* If changed lines are few, don't allow preemption, don't scroll. */
1173 if (changed_lines
< baud_rate
/ 2400
1174 || unchanged_at_bottom
== SCREEN_HEIGHT (screen
))
1177 window_size
= (SCREEN_HEIGHT (screen
) - unchanged_at_top
1178 - unchanged_at_bottom
);
1180 if (scroll_region_ok
)
1181 free_at_end_vpos
-= unchanged_at_bottom
;
1182 else if (memory_below_screen
)
1183 free_at_end_vpos
= -1;
1185 /* If large window, fast terminal and few lines in common between
1186 current screen and desired screen, don't bother with i/d calc. */
1187 if (window_size
>= 18 && baud_rate
> 2400
1189 10 * scrolling_max_lines_saved (unchanged_at_top
,
1190 SCREEN_HEIGHT (screen
) - unchanged_at_bottom
,
1191 old_hash
, new_hash
, draw_cost
)))
1194 scrolling_1 (screen
, window_size
, unchanged_at_top
, unchanged_at_bottom
,
1195 draw_cost
+ unchanged_at_top
- 1,
1196 old_hash
+ unchanged_at_top
- 1,
1197 new_hash
+ unchanged_at_top
- 1,
1198 free_at_end_vpos
- unchanged_at_top
);
1203 /* Return the offset in its buffer of the character at location col, line
1204 in the given window. */
1206 buffer_posn_from_coords (window
, col
, line
)
1207 struct window
*window
;
1210 int window_left
= XFASTINT (window
->left
);
1212 /* The actual width of the window is window->width less one for the
1213 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
1215 int window_width
= (XFASTINT (window
->width
) - 1
1216 - (XFASTINT (window
->width
) + window_left
1217 != SCREEN_WIDTH (XSCREEN (window
->screen
))));
1219 int startp
= marker_position (window
->start
);
1221 /* Since compute_motion will only operate on the current buffer,
1222 we need to save the old one and restore it when we're done. */
1223 struct buffer
*old_current_buffer
= current_buffer
;
1224 struct position
*posn
;
1226 current_buffer
= XBUFFER (window
->buffer
);
1228 /* It would be nice if we could use SCREEN_CURRENT_GLYPHS (XSCREEN
1229 (window->screen))->bufp to avoid scanning from the very top of
1230 the window, but it isn't maintained correctly, and I'm not even
1231 sure I will keep it. */
1232 posn
= compute_motion (startp
, 0,
1233 (window
== XWINDOW (minibuf_window
) && startp
== 1
1234 ? minibuf_prompt_width
: 0),
1235 ZV
, line
, col
- window_left
,
1236 window_width
, XINT (window
->hscroll
), 0);
1238 current_buffer
= old_current_buffer
;
1240 /* compute_motion considers screen points past the end of a line
1241 to be *after* the newline, i.e. at the start of the next line.
1242 This is reasonable, but not really what we want. So if the
1243 result is on a line below LINE, back it up one character. */
1244 if (posn
->vpos
> line
)
1245 return posn
->bufpos
- 1;
1247 return posn
->bufpos
;
1254 register GLYPH
*p
= r
;
1255 while (*r
++ == SPACEGLYPH
);
1260 count_match (str1
, str2
)
1263 register GLYPH
*p1
= str1
;
1264 register GLYPH
*p2
= str2
;
1265 while (*p1
++ == *p2
++);
1266 return p1
- str1
- 1;
1269 /* Char insertion/deletion cost vector, from term.c */
1270 extern int *char_ins_del_vector
;
1272 #define char_ins_del_cost(s) (&char_ins_del_vector[SCREEN_HEIGHT((s))])
1275 update_line (screen
, vpos
)
1276 register SCREEN_PTR screen
;
1279 register GLYPH
*obody
, *nbody
, *op1
, *op2
, *np1
, *temp
;
1281 int osp
, nsp
, begmatch
, endmatch
, olen
, nlen
;
1283 register struct screen_glyphs
*current_screen
1284 = SCREEN_CURRENT_GLYPHS (screen
);
1285 register struct screen_glyphs
*desired_screen
1286 = SCREEN_DESIRED_GLYPHS (screen
);
1288 if (desired_screen
->highlight
[vpos
]
1289 != (current_screen
->enable
[vpos
] && current_screen
->highlight
[vpos
]))
1291 change_line_highlight (desired_screen
->highlight
[vpos
], vpos
,
1292 (current_screen
->enable
[vpos
] ?
1293 current_screen
->used
[vpos
] : 0));
1294 current_screen
->enable
[vpos
] = 0;
1297 reassert_line_highlight (desired_screen
->highlight
[vpos
], vpos
);
1299 if (! current_screen
->enable
[vpos
])
1305 obody
= current_screen
->glyphs
[vpos
];
1306 olen
= current_screen
->used
[vpos
];
1307 if (! current_screen
->highlight
[vpos
])
1309 if (!must_write_spaces
)
1310 while (obody
[olen
- 1] == SPACEGLYPH
&& olen
> 0)
1315 /* For an inverse-video line, remember we gave it
1316 spaces all the way to the screen edge
1317 so that the reverse video extends all the way across. */
1319 while (olen
< SCREEN_WIDTH (screen
) - 1)
1320 obody
[olen
++] = SPACEGLYPH
;
1324 /* One way or another, this will enable the line being updated. */
1325 current_screen
->enable
[vpos
] = 1;
1326 current_screen
->used
[vpos
] = desired_screen
->used
[vpos
];
1327 current_screen
->highlight
[vpos
] = desired_screen
->highlight
[vpos
];
1328 current_screen
->bufp
[vpos
] = desired_screen
->bufp
[vpos
];
1330 #ifdef HAVE_X_WINDOWS
1331 if (SCREEN_IS_X (screen
))
1333 current_screen
->pix_width
[vpos
]
1334 = current_screen
->used
[vpos
]
1335 * FONT_WIDTH (screen
->display
.x
->font
);
1336 current_screen
->pix_height
[vpos
]
1337 = FONT_HEIGHT (screen
->display
.x
->font
);
1339 #endif /* HAVE_X_WINDOWS */
1341 if (!desired_screen
->enable
[vpos
])
1347 nbody
= desired_screen
->glyphs
[vpos
];
1348 nlen
= desired_screen
->used
[vpos
];
1350 /* Pretend trailing spaces are not there at all,
1351 unless for one reason or another we must write all spaces. */
1352 if (! desired_screen
->highlight
[vpos
])
1354 if (!must_write_spaces
)
1355 /* We know that the previous character byte contains 0. */
1356 while (nbody
[nlen
- 1] == SPACEGLYPH
)
1361 /* For an inverse-video line, give it extra trailing spaces
1362 all the way to the screen edge
1363 so that the reverse video extends all the way across. */
1365 while (nlen
< SCREEN_WIDTH (screen
) - 1)
1366 nbody
[nlen
++] = SPACEGLYPH
;
1369 /* If there's no i/d char, quickly do the best we can without it. */
1370 if (!char_ins_del_ok
)
1374 for (i
= 0; i
< nlen
; i
++)
1376 if (i
>= olen
|| nbody
[i
] != obody
[i
]) /* A non-matching char. */
1378 cursor_to (vpos
, i
);
1379 for (j
= 1; (i
+ j
< nlen
&&
1380 (i
+ j
>= olen
|| nbody
[i
+j
] != obody
[i
+j
]));
1383 /* Output this run of non-matching chars. */
1384 write_glyphs (nbody
+ i
, j
);
1387 /* Now find the next non-match. */
1391 /* Clear the rest of the line, or the non-clear part of it. */
1394 cursor_to (vpos
, nlen
);
1395 clear_end_of_line (olen
);
1398 /* Exchange contents between current_screen and new_screen. */
1399 temp
= desired_screen
->glyphs
[vpos
];
1400 desired_screen
->glyphs
[vpos
] = current_screen
->glyphs
[vpos
];
1401 current_screen
->glyphs
[vpos
] = temp
;
1408 nsp
= (must_write_spaces
|| desired_screen
->highlight
[vpos
])
1409 ? 0 : count_blanks (nbody
);
1412 cursor_to (vpos
, nsp
);
1413 write_glyphs (nbody
+ nsp
, nlen
- nsp
);
1416 /* Exchange contents between current_screen and new_screen. */
1417 temp
= desired_screen
->glyphs
[vpos
];
1418 desired_screen
->glyphs
[vpos
] = current_screen
->glyphs
[vpos
];
1419 current_screen
->glyphs
[vpos
] = temp
;
1428 /* Compute number of leading blanks in old and new contents. */
1429 osp
= count_blanks (obody
);
1430 if (!desired_screen
->highlight
[vpos
])
1431 nsp
= count_blanks (nbody
);
1435 /* Compute number of matching chars starting with first nonblank. */
1436 begmatch
= count_match (obody
+ osp
, nbody
+ nsp
);
1438 /* Spaces in new match implicit space past the end of old. */
1439 /* A bug causing this to be a no-op was fixed in 18.29. */
1440 if (!must_write_spaces
&& osp
+ begmatch
== olen
)
1443 while (np1
[begmatch
] == SPACEGLYPH
)
1447 /* Avoid doing insert/delete char
1448 just cause number of leading spaces differs
1449 when the following text does not match. */
1450 if (begmatch
== 0 && osp
!= nsp
)
1451 osp
= nsp
= min (osp
, nsp
);
1453 /* Find matching characters at end of line */
1456 op2
= op1
+ begmatch
- min (olen
- osp
, nlen
- nsp
);
1457 while (op1
> op2
&& op1
[-1] == np1
[-1])
1462 endmatch
= obody
+ olen
- op1
;
1464 /* Put correct value back in nbody[nlen].
1465 This is important because direct_output_for_insert
1466 can write into the line at a later point.
1467 If this screws up the zero at the end of the line, re-establish it. */
1471 /* tem gets the distance to insert or delete.
1472 endmatch is how many characters we save by doing so.
1475 tem
= (nlen
- nsp
) - (olen
- osp
);
1477 && (!char_ins_del_ok
|| endmatch
<= char_ins_del_cost (screen
)[tem
]))
1480 /* nsp - osp is the distance to insert or delete.
1481 If that is nonzero, begmatch is known to be nonzero also.
1482 begmatch + endmatch is how much we save by doing the ins/del.
1486 && (!char_ins_del_ok
1487 || begmatch
+ endmatch
<= char_ins_del_cost (screen
)[nsp
- osp
]))
1491 osp
= nsp
= min (osp
, nsp
);
1494 /* Now go through the line, inserting, writing and
1495 deleting as appropriate. */
1499 cursor_to (vpos
, nsp
);
1500 delete_glyphs (osp
- nsp
);
1504 /* If going to delete chars later in line
1505 and insert earlier in the line,
1506 must delete first to avoid losing data in the insert */
1507 if (endmatch
&& nlen
< olen
+ nsp
- osp
)
1509 cursor_to (vpos
, nlen
- endmatch
+ osp
- nsp
);
1510 delete_glyphs (olen
+ nsp
- osp
- nlen
);
1511 olen
= nlen
- (nsp
- osp
);
1513 cursor_to (vpos
, osp
);
1514 insert_glyphs ((char *)0, nsp
- osp
);
1518 tem
= nsp
+ begmatch
+ endmatch
;
1519 if (nlen
!= tem
|| olen
!= tem
)
1521 cursor_to (vpos
, nsp
+ begmatch
);
1522 if (!endmatch
|| nlen
== olen
)
1524 /* If new text being written reaches right margin,
1525 there is no need to do clear-to-eol at the end.
1526 (and it would not be safe, since cursor is not
1527 going to be "at the margin" after the text is done) */
1528 if (nlen
== SCREEN_WIDTH (screen
))
1530 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1534 /* the following code loses disastrously if tem == nlen.
1535 Rather than trying to fix that case, I am trying the simpler
1536 solution found above. */
1538 /* If the text reaches to the right margin,
1539 it will lose one way or another (depending on AutoWrap)
1540 to clear to end of line after outputting all the text.
1541 So pause with one character to go and clear the line then. */
1542 if (nlen
== SCREEN_WIDTH (screen
) && fast_clear_end_of_line
&& olen
> nlen
)
1544 /* endmatch must be zero, and tem must equal nsp + begmatch */
1545 write_glyphs (nbody
+ tem
, nlen
- tem
- 1);
1546 clear_end_of_line (olen
);
1547 olen
= 0; /* Don't let it be cleared again later */
1548 write_glyphs (nbody
+ nlen
- 1, 1);
1551 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1552 #endif /* OBSOLETE */
1555 else if (nlen
> olen
)
1557 write_glyphs (nbody
+ nsp
+ begmatch
, olen
- tem
);
1558 insert_glyphs (nbody
+ nsp
+ begmatch
+ olen
- tem
, nlen
- olen
);
1561 else if (olen
> nlen
)
1563 write_glyphs (nbody
+ nsp
+ begmatch
, nlen
- tem
);
1564 delete_glyphs (olen
- nlen
);
1570 /* If any unerased characters remain after the new line, erase them. */
1573 cursor_to (vpos
, nlen
);
1574 clear_end_of_line (olen
);
1577 /* Exchange contents between current_screen and new_screen. */
1578 temp
= desired_screen
->glyphs
[vpos
];
1579 desired_screen
->glyphs
[vpos
] = current_screen
->glyphs
[vpos
];
1580 current_screen
->glyphs
[vpos
] = temp
;
1583 DEFUN ("open-termscript", Fopen_termscript
, Sopen_termscript
,
1584 1, 1, "FOpen termscript file: ",
1585 "Start writing all terminal output to FILE as well as the terminal.\n\
1586 FILE = nil means just close any termscript file currently open.")
1590 if (termscript
!= 0) fclose (termscript
);
1595 file
= Fexpand_file_name (file
, Qnil
);
1596 termscript
= fopen (XSTRING (file
)->data
, "w");
1597 if (termscript
== 0)
1598 report_file_error ("Opening termscript", Fcons (file
, Qnil
));
1606 window_change_signal ()
1610 int old_errno
= errno
;
1612 get_screen_size (&width
, &height
);
1614 /* The screen size change obviously applies to a termcap-controlled
1615 screen. Find such a screen in the list, and assume it's the only
1616 one (since the redisplay code always writes to stdout, not a
1617 FILE * specified in the screen structure). Record the new size,
1618 but don't reallocate the data structures now. Let that be done
1619 later outside of the signal handler. */
1624 for (tail
= Vscreen_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1626 SCREEN_PTR s
= XSCREEN (XCONS (tail
)->car
);
1628 if (SCREEN_IS_TERMCAP (s
))
1631 change_screen_size (s
, height
, width
, 0);
1638 signal (SIGWINCH
, window_change_signal
);
1641 #endif /* SIGWINCH */
1644 /* Do any change in screen size that was requested by a signal. */
1646 do_pending_window_change ()
1648 /* If window_change_signal should have run before, run it now. */
1649 while (delayed_size_change
)
1653 delayed_size_change
= 0;
1655 for (tail
= Vscreen_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1657 SCREEN_PTR s
= XSCREEN (XCONS (tail
)->car
);
1658 int height
= SCREEN_NEW_HEIGHT (s
);
1659 int width
= SCREEN_NEW_WIDTH (s
);
1661 SCREEN_NEW_HEIGHT (s
) = 0;
1662 SCREEN_NEW_WIDTH (s
) = 0;
1665 change_screen_size (s
, height
, width
, 0);
1671 /* Change the screen height and/or width. Values may be given as zero to
1672 indicate no change is to take place. */
1674 change_screen_size (screen
, newlength
, newwidth
, pretend
)
1675 register SCREEN_PTR screen
;
1676 register int newlength
, newwidth
, pretend
;
1678 /* If we can't deal with the change now, queue it for later. */
1681 SCREEN_NEW_HEIGHT (screen
) = newlength
;
1682 SCREEN_NEW_WIDTH (screen
) = newwidth
;
1683 delayed_size_change
= 1;
1687 /* This size-change overrides any pending one for this screen. */
1688 SCREEN_NEW_HEIGHT (screen
) = 0;
1689 SCREEN_NEW_WIDTH (screen
) = 0;
1691 if ((newlength
== 0 || newlength
== SCREEN_HEIGHT (screen
))
1692 && (newwidth
== 0 || newwidth
== SCREEN_WIDTH (screen
)))
1695 if (newlength
&& newlength
!= SCREEN_HEIGHT (screen
))
1697 if (SCREEN_HAS_MINIBUF (screen
)
1698 && ! SCREEN_MINIBUF_ONLY_P (screen
))
1700 /* Screen has both root and minibuffer. */
1701 set_window_height (SCREEN_ROOT_WINDOW (screen
),
1703 XFASTINT (XWINDOW (SCREEN_MINIBUF_WINDOW (screen
))->top
)
1705 set_window_height (SCREEN_MINIBUF_WINDOW (screen
), 1, 0);
1708 /* Screen has just one top-level window. */
1709 set_window_height (SCREEN_ROOT_WINDOW (screen
), newlength
, 0);
1711 if (SCREEN_IS_TERMCAP (screen
) && !pretend
)
1712 ScreenRows
= newlength
;
1715 if (screen
->output_method
== output_termcap
)
1717 screen_height
= newlength
;
1719 ScreenRows
= newlength
;
1724 if (newwidth
&& newwidth
!= SCREEN_WIDTH (screen
))
1726 set_window_width (SCREEN_ROOT_WINDOW (screen
), newwidth
, 0);
1727 if (SCREEN_HAS_MINIBUF (screen
))
1728 set_window_width (SCREEN_MINIBUF_WINDOW (screen
), newwidth
, 0);
1729 SCREEN_WIDTH (screen
) = newwidth
;
1731 if (SCREEN_IS_TERMCAP (screen
) && !pretend
)
1732 ScreenCols
= newwidth
;
1734 if (screen
->output_method
== output_termcap
)
1736 screen_width
= newwidth
;
1738 ScreenCols
= newwidth
;
1744 SCREEN_HEIGHT (screen
) = newlength
;
1746 remake_screen_glyphs (screen
);
1747 calculate_costs (screen
);
1750 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal
,
1751 Ssend_string_to_terminal
, 1, 1, 0,
1752 "Send STRING to the terminal without alteration.\n\
1753 Control characters in STRING will have terminal-dependent effects.")
1757 CHECK_STRING (str
, 0);
1758 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, stdout
);
1762 fwrite (XSTRING (str
)->data
, 1, XSTRING (str
)->size
, termscript
);
1763 fflush (termscript
);
1768 DEFUN ("ding", Fding
, Sding
, 0, 1, 0,
1769 "Beep, or flash the screen.\n\
1770 Also, unless an argument is given,\n\
1771 terminate any keyboard macro currently executing.")
1790 else if (!INTERACTIVE
) /* Stop executing a keyboard macro. */
1791 error ("Keyboard macro terminated by a command ringing the bell");
1797 DEFUN ("sleep-for", Fsleep_for
, Ssleep_for
, 1, 2, 0,
1798 "Pause, without updating display, for ARG seconds.\n\
1799 Optional second arg non-nil means ARG is measured in milliseconds.\n\
1800 \(Not all operating systems support milliseconds.)")
1802 Lisp_Object n
, millisec
;
1804 #ifndef subprocesses
1806 struct timeval timeout
, end_time
, garbage1
;
1807 #endif /* HAVE_TIMEVAL */
1808 #endif /* no subprocesses */
1812 CHECK_NUMBER (n
, 0);
1817 if (!NILP (millisec
))
1819 #ifndef HAVE_TIMEVAL
1820 error ("millisecond sit-for not supported on %s", SYSTEM_TYPE
);
1822 usec
= sec
% 1000 * 1000;
1828 wait_reading_process_input (sec
, usec
, 0, 0);
1829 #else /* No subprocesses */
1836 /* The reason this is done this way
1837 (rather than defined (H_S) && defined (H_T))
1838 is because the VMS preprocessor doesn't grok `defined' */
1841 gettimeofday (&end_time
, &garbage1
);
1842 end_time
.tv_sec
+= sec
;
1843 end_time
.tv_usec
+= usec
;
1844 if (end_time
.tv_usec
>= 1000000)
1845 end_time
.tv_sec
++, end_time
.tv_usec
-= 1000000;
1849 gettimeofday (&timeout
, &garbage1
);
1850 timeout
.tv_sec
= end_time
.tv_sec
- timeout
.tv_sec
;
1851 timeout
.tv_usec
= end_time
.tv_usec
- timeout
.tv_usec
;
1852 if (timeout
.tv_usec
< 0)
1853 timeout
.tv_usec
+= 1000000, timeout
.tv_sec
--;
1854 if (timeout
.tv_sec
< 0)
1856 if (!select (1, 0, 0, 0, &timeout
))
1859 #else /* not HAVE_TIMEVAL */
1860 /* Is it safe to quit out of `sleep'? I'm afraid to trust it. */
1862 #endif /* HAVE_TIMEVAL */
1863 #else /* not HAVE_SELECT */
1865 #endif /* HAVE_SELECT */
1866 #endif /* not VMS */
1869 #endif /* no subprocesses */
1874 DEFUN ("sit-for", Fsit_for
, Ssit_for
, 1, 3, 0,
1875 "Perform redisplay, then wait for ARG seconds or until input is available.\n\
1876 Optional second arg non-nil means ARG counts in milliseconds.\n\
1877 Optional third arg non-nil means don't redisplay, just wait for input.\n\
1878 Redisplay is preempted as always if input arrives, and does not happen\n\
1879 if input is available before it starts.\n\
1880 Value is t if waited the full time with no input arriving.")
1881 (n
, millisec
, nodisp
)
1882 Lisp_Object n
, millisec
, nodisp
;
1884 #ifndef subprocesses
1886 struct timeval timeout
;
1891 #endif /* no subprocesses */
1895 CHECK_NUMBER (n
, 0);
1897 if (detect_input_pending ())
1900 if (EQ (nodisp
, Qnil
))
1901 redisplay_preserve_echo_area ();
1907 if (!NILP (millisec
))
1909 #ifndef HAVE_TIMEVAL
1910 error ("millisecond sleep-for not supported on %s", SYSTEM_TYPE
);
1912 usec
= sec
% 1000 * 1000;
1921 wait_reading_process_input (sec
, usec
, 1, 1);
1922 #else /* no subprocesses */
1928 input_wait_timeout (XINT (n
));
1930 #ifndef HAVE_TIMEVAL
1932 select (1, &waitchannels
, 0, 0, &timeout_sec
);
1933 #else /* HAVE_TIMEVAL */
1934 timeout
.tv_sec
= sec
;
1935 timeout
.tv_usec
= usec
;
1936 select (1, &waitchannels
, 0, 0, &timeout
);
1937 #endif /* HAVE_TIMEVAL */
1938 #endif /* not VMS */
1941 #endif /* no subprocesses */
1943 return detect_input_pending () ? Qnil
: Qt
;
1946 DEFUN ("sleep-for-millisecs", Fsleep_for_millisecs
, Ssleep_for_millisecs
,
1948 "Pause, without updating display, for ARG milliseconds.")
1952 #ifndef HAVE_TIMEVAL
1953 error ("sleep-for-millisecs not supported on %s", SYSTEM_TYPE
);
1955 CHECK_NUMBER (n
, 0);
1956 wait_reading_process_input (XINT (n
) / 1000, XINT (n
) % 1000 * 1000,
1959 #endif /* HAVE_TIMEVAL */
1962 char *terminal_type
;
1964 /* Initialization done when Emacs fork is started, before doing stty. */
1965 /* Determine terminal type and set terminal_driver */
1966 /* Then invoke its decoding routine to set up variables
1967 in the terminal package */
1971 #ifdef HAVE_X_WINDOWS
1972 extern int display_arg
;
1977 cursor_in_echo_area
= 0;
1978 terminal_type
= (char *) 0;
1980 /* If the DISPLAY environment variable is set, try to use X, and
1981 die with an error message if that doesn't work. */
1983 /* Check if we're using a window system here before trying to
1984 initialize the terminal. If we check the terminal first,
1986 If someone has indicated that they want
1987 to use a window system, we shouldn't bother initializing the
1988 terminal. This is especially important when the terminal is so
1989 dumb that emacs gives up before and doesn't bother using the window
1992 #ifdef HAVE_X_WINDOWS
1993 if (!inhibit_window_system
&& (display_arg
|| getenv ("DISPLAY")))
1995 Vwindow_system
= intern ("x");
1997 Vwindow_system_version
= make_number (11);
1999 Vwindow_system_version
= make_number (10);
2003 #endif /* HAVE_X_WINDOWS */
2005 /* If no window system has been specified, try to use the terminal. */
2008 fprintf (stderr
, "emacs: standard input is not a tty\n");
2012 /* Look at the TERM variable */
2013 terminal_type
= (char *) getenv ("TERM");
2017 fprintf (stderr
, "Please specify your terminal type.\n\
2018 For types defined in VMS, use set term /device=TYPE.\n\
2019 For types not defined in VMS, use define emacs_term \"TYPE\".\n\
2020 \(The quotation marks are necessary since terminal types are lower case.)\n");
2022 fprintf (stderr
, "Please set the environment variable TERM; see tset(1).\n");
2028 /* VMS DCL tends to upcase things, so downcase term type.
2029 Hardly any uppercase letters in terminal types; should be none. */
2031 char *new = (char *) xmalloc (strlen (terminal_type
) + 1);
2034 strcpy (new, terminal_type
);
2036 for (p
= new; *p
; p
++)
2040 terminal_type
= new;
2044 term_init (terminal_type
);
2046 remake_screen_glyphs (selected_screen
);
2047 calculate_costs (selected_screen
);
2049 /* X and Y coordinates of the cursor between updates. */
2050 SCREEN_CURSOR_X (selected_screen
) = 0;
2051 SCREEN_CURSOR_Y (selected_screen
) = 0;
2056 #endif /* CANNOT_DUMP */
2057 signal (SIGWINCH
, window_change_signal
);
2058 #endif /* SIGWINCH */
2064 defsubr (&Sredraw_screen
);
2066 defsubr (&Sredraw_display
);
2067 defsubr (&Sopen_termscript
);
2069 defsubr (&Ssit_for
);
2070 defsubr (&Ssleep_for
);
2071 defsubr (&Ssend_string_to_terminal
);
2073 DEFVAR_INT ("baud-rate", &baud_rate
,
2074 "The output baud rate of the terminal.\n\
2075 On most systems, changing this value will affect the amount of padding\n\
2076 and the other strategic decisions made during redisplay.");
2077 DEFVAR_BOOL ("inverse-video", &inverse_video
,
2078 "*Non-nil means invert the entire screen display.\n\
2079 This means everything is in inverse video which otherwise would not be.");
2080 DEFVAR_BOOL ("visible-bell", &visible_bell
,
2081 "*Non-nil means try to flash the screen to represent a bell.");
2082 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
,
2083 "*Non-nil means no need to redraw entire screen after suspending.\n\
2084 A non-nil value is useful if the terminal can automatically preserve\n\
2085 Emacs's screen display when you reenter Emacs.\n\
2086 It is up to you to set this variable if your terminal can do that.");
2087 DEFVAR_LISP ("window-system", &Vwindow_system
,
2088 "A symbol naming the window-system under which Emacs is running\n\
2089 \(such as `x'), or nil if emacs is running on an ordinary terminal.");
2090 DEFVAR_LISP ("window-system-version", &Vwindow_system_version
,
2091 "The version number of the window system in use.\n\
2092 For X windows, this is 10 or 11.");
2093 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
,
2094 "Non-nil means put cursor in minibuffer, at end of any message there.");
2095 DEFVAR_LISP ("glyph-table", &Vglyph_table
,
2096 "Table defining how to output a glyph code to the screen.\n\
2097 If not nil, this is a vector indexed by glyph code to define the glyph.\n\
2098 Each element can be:\n\
2099 integer: a glyph code which this glyph is an alias for.\n\
2100 string: output this glyph using that string (not impl. in X windows).\n\
2101 nil: this glyph mod 256 is char code to output,\n\
2102 and this glyph / 256 is face code for X windows (see `x-set-face').");
2103 Vglyph_table
= Qnil
;
2105 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
,
2106 "Display table to use for buffers that specify none.\n\
2107 See `buffer-display-table' for more information.");
2108 Vstandard_display_table
= Qnil
;
2110 /* Initialize `window-system', unless init_display already decided it. */
2115 Vwindow_system
= Qnil
;
2116 Vwindow_system_version
= Qnil
;