Mercurial > emacs
comparison src/dispnew.c @ 83716:a73440d2f146 merge-multi-tty-to-trunk
Merge multi-tty branch
Revision: emacs@sv.gnu.org/emacs--devo--0--patch-866
author | Miles Bader <miles@gnu.org> |
---|---|
date | Wed, 29 Aug 2007 05:28:10 +0000 |
parents | 65663fcd2caa |
children | 62ea6778c569 bdb3fe0ba9fa |
comparison
equal
deleted
inserted
replaced
82950:ed8435ec5652 | 83716:a73440d2f146 |
---|---|
30 #endif | 30 #endif |
31 | 31 |
32 #include "lisp.h" | 32 #include "lisp.h" |
33 #include "termchar.h" | 33 #include "termchar.h" |
34 #include "termopts.h" | 34 #include "termopts.h" |
35 #include "termhooks.h" | |
36 /* cm.h must come after dispextern.h on Windows. */ | 35 /* cm.h must come after dispextern.h on Windows. */ |
37 #include "dispextern.h" | 36 #include "dispextern.h" |
38 #include "cm.h" | 37 #include "cm.h" |
39 #include "buffer.h" | 38 #include "buffer.h" |
40 #include "charset.h" | 39 #include "charset.h" |
41 #include "keyboard.h" | 40 #include "keyboard.h" |
42 #include "frame.h" | 41 #include "frame.h" |
42 #include "termhooks.h" | |
43 #include "window.h" | 43 #include "window.h" |
44 #include "commands.h" | 44 #include "commands.h" |
45 #include "disptab.h" | 45 #include "disptab.h" |
46 #include "indent.h" | 46 #include "indent.h" |
47 #include "intervals.h" | 47 #include "intervals.h" |
236 /* Line speed of the terminal. */ | 236 /* Line speed of the terminal. */ |
237 | 237 |
238 EMACS_INT baud_rate; | 238 EMACS_INT baud_rate; |
239 | 239 |
240 /* Either nil or a symbol naming the window system under which Emacs | 240 /* Either nil or a symbol naming the window system under which Emacs |
241 is running. */ | 241 creates the first frame. */ |
242 | 242 |
243 Lisp_Object Vwindow_system; | 243 Lisp_Object Vinitial_window_system; |
244 | 244 |
245 /* Version number of X windows: 10, 11 or nil. */ | 245 /* Version number of X windows: 10, 11 or nil. */ |
246 | 246 |
247 Lisp_Object Vwindow_system_version; | 247 Lisp_Object Vwindow_system_version; |
248 | 248 |
280 selected. In a single-frame version, this variable always holds | 280 selected. In a single-frame version, this variable always holds |
281 the address of the_only_frame. */ | 281 the address of the_only_frame. */ |
282 | 282 |
283 struct frame *last_nonminibuf_frame; | 283 struct frame *last_nonminibuf_frame; |
284 | 284 |
285 /* Stdio stream being used for copy of all output. */ | |
286 | |
287 FILE *termscript; | |
288 | |
289 /* Structure for info on cursor positioning. */ | |
290 | |
291 struct cm Wcm; | |
292 | |
293 /* 1 means SIGWINCH happened when not safe. */ | 285 /* 1 means SIGWINCH happened when not safe. */ |
294 | 286 |
295 int delayed_size_change; | 287 int delayed_size_change; |
296 | 288 |
297 /* 1 means glyph initialization has been completed at startup. */ | 289 /* 1 means glyph initialization has been completed at startup. */ |
325 | 317 |
326 /* If non-null, the frame whose frame matrices are manipulated. If | 318 /* If non-null, the frame whose frame matrices are manipulated. If |
327 null, window matrices are worked on. */ | 319 null, window matrices are worked on. */ |
328 | 320 |
329 static struct frame *frame_matrix_frame; | 321 static struct frame *frame_matrix_frame; |
330 | |
331 /* Current interface for window-based redisplay. Set from init_xterm. | |
332 A null value means we are not using window-based redisplay. */ | |
333 | |
334 struct redisplay_interface *rif; | |
335 | 322 |
336 /* Non-zero means that fonts have been loaded since the last glyph | 323 /* Non-zero means that fonts have been loaded since the last glyph |
337 matrix adjustments. Redisplay must stop, and glyph matrices must | 324 matrix adjustments. Redisplay must stop, and glyph matrices must |
338 be adjusted when this flag becomes non-zero during display. The | 325 be adjusted when this flag becomes non-zero during display. The |
339 reason fonts can be loaded so late is that fonts of fontsets are | 326 reason fonts can be loaded so late is that fonts of fontsets are |
1421 | 1408 |
1422 while (glyph < end) | 1409 while (glyph < end) |
1423 { | 1410 { |
1424 int c = glyph->u.ch; | 1411 int c = glyph->u.ch; |
1425 int face_id = glyph->face_id; | 1412 int face_id = glyph->face_id; |
1426 if (must_write_spaces) | 1413 if (FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */ |
1427 c -= SPACEGLYPH; | 1414 c -= SPACEGLYPH; |
1428 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c; | 1415 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c; |
1429 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + face_id; | 1416 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + face_id; |
1430 ++glyph; | 1417 ++glyph; |
1431 } | 1418 } |
1453 int len; | 1440 int len; |
1454 Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE; | 1441 Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE; |
1455 int glyph_table_len = GLYPH_TABLE_LENGTH; | 1442 int glyph_table_len = GLYPH_TABLE_LENGTH; |
1456 | 1443 |
1457 /* Ignore trailing and leading spaces if we can. */ | 1444 /* Ignore trailing and leading spaces if we can. */ |
1458 if (!must_write_spaces) | 1445 if (!FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */ |
1459 { | 1446 { |
1460 /* Skip from the end over trailing spaces. */ | 1447 /* Skip from the end over trailing spaces. */ |
1461 while (end > beg && CHAR_GLYPH_SPACE_P (*(end - 1))) | 1448 while (end > beg && CHAR_GLYPH_SPACE_P (*(end - 1))) |
1462 --end; | 1449 --end; |
1463 | 1450 |
1669 ***********************************************************************/ | 1656 ***********************************************************************/ |
1670 | 1657 |
1671 #if GLYPH_DEBUG | 1658 #if GLYPH_DEBUG |
1672 | 1659 |
1673 | 1660 |
1674 /* Flush standard output. This is sometimes useful to call from | 1661 /* Flush standard output. This is sometimes useful to call from the debugger. |
1675 the debugger. */ | 1662 XXX Maybe this should be changed to flush the current terminal instead of |
1663 stdout. | |
1664 */ | |
1676 | 1665 |
1677 void | 1666 void |
1678 flush_stdout () | 1667 flush_stdout () |
1679 { | 1668 { |
1680 fflush (stdout); | 1669 fflush (stdout); |
3391 called so early here). */ | 3380 called so early here). */ |
3392 if (!glyphs_initialized_initially_p) | 3381 if (!glyphs_initialized_initially_p) |
3393 return Qnil; | 3382 return Qnil; |
3394 | 3383 |
3395 update_begin (f); | 3384 update_begin (f); |
3385 #ifdef MSDOS | |
3396 if (FRAME_MSDOS_P (f)) | 3386 if (FRAME_MSDOS_P (f)) |
3397 set_terminal_modes (); | 3387 set_terminal_modes (FRAME_TERMINAL (f)); |
3398 clear_frame (); | 3388 #endif |
3389 clear_frame (f); | |
3399 clear_current_matrices (f); | 3390 clear_current_matrices (f); |
3400 update_end (f); | 3391 update_end (f); |
3401 fflush (stdout); | 3392 if (FRAME_TERMCAP_P (f)) |
3393 fflush (FRAME_TTY (f)->output); | |
3402 windows_or_buffers_changed++; | 3394 windows_or_buffers_changed++; |
3403 /* Mark all windows as inaccurate, so that every window will have | 3395 /* Mark all windows as inaccurate, so that every window will have |
3404 its redisplay done. */ | 3396 its redisplay done. */ |
3405 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0); | 3397 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0); |
3406 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), 1); | 3398 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), 1); |
3537 || (!window_redisplay_p && !WINDOW_FULL_WIDTH_P (w))) | 3529 || (!window_redisplay_p && !WINDOW_FULL_WIDTH_P (w))) |
3538 return 0; | 3530 return 0; |
3539 | 3531 |
3540 /* If we can't insert glyphs, we can use this method only | 3532 /* If we can't insert glyphs, we can use this method only |
3541 at the end of a line. */ | 3533 at the end of a line. */ |
3542 if (!char_ins_del_ok) | 3534 if (!FRAME_CHAR_INS_DEL_OK (f)) |
3543 if (PT != ZV && FETCH_BYTE (PT_BYTE) != '\n') | 3535 if (PT != ZV && FETCH_BYTE (PT_BYTE) != '\n') |
3544 return 0; | 3536 return 0; |
3545 | 3537 |
3546 /* Set up a display iterator structure for W. Glyphs will be | 3538 /* Set up a display iterator structure for W. Glyphs will be |
3547 produced in scratch_glyph_row. Current position is W's cursor | 3539 produced in scratch_glyph_row. Current position is W's cursor |
3687 implemented for X frames. The implementation uses updated_window | 3679 implemented for X frames. The implementation uses updated_window |
3688 and updated_row. */ | 3680 and updated_row. */ |
3689 updated_row = glyph_row; | 3681 updated_row = glyph_row; |
3690 updated_area = TEXT_AREA; | 3682 updated_area = TEXT_AREA; |
3691 update_begin (f); | 3683 update_begin (f); |
3692 if (rif) | 3684 if (FRAME_RIF (f)) |
3693 { | 3685 { |
3694 rif->update_window_begin_hook (w); | 3686 FRAME_RIF (f)->update_window_begin_hook (w); |
3695 | 3687 |
3696 if (glyphs == end - n | 3688 if (glyphs == end - n |
3697 /* In front of a space added by append_space. */ | 3689 /* In front of a space added by append_space. */ |
3698 || (glyphs == end - n - 1 | 3690 || (glyphs == end - n - 1 |
3699 && (end - n)->charpos <= 0)) | 3691 && (end - n)->charpos <= 0)) |
3700 rif->write_glyphs (glyphs, n); | 3692 FRAME_RIF (f)->write_glyphs (glyphs, n); |
3701 else | 3693 else |
3702 rif->insert_glyphs (glyphs, n); | 3694 FRAME_RIF (f)->insert_glyphs (glyphs, n); |
3703 } | 3695 } |
3704 else | 3696 else |
3705 { | 3697 { |
3706 if (glyphs == end - n) | 3698 if (glyphs == end - n) |
3707 write_glyphs (glyphs, n); | 3699 write_glyphs (f, glyphs, n); |
3708 else | 3700 else |
3709 insert_glyphs (glyphs, n); | 3701 insert_glyphs (f, glyphs, n); |
3710 } | 3702 } |
3711 | 3703 |
3712 w->cursor.hpos += n; | 3704 w->cursor.hpos += n; |
3713 w->cursor.x = it.current_x - it.first_visible_x; | 3705 w->cursor.x = it.current_x - it.first_visible_x; |
3714 xassert (w->cursor.hpos >= 0 | 3706 xassert (w->cursor.hpos >= 0 |
3717 /* How to set the cursor differs depending on whether we are | 3709 /* How to set the cursor differs depending on whether we are |
3718 using a frame matrix or a window matrix. Note that when | 3710 using a frame matrix or a window matrix. Note that when |
3719 a frame matrix is used, cursor_to expects frame coordinates, | 3711 a frame matrix is used, cursor_to expects frame coordinates, |
3720 and the X and Y parameters are not used. */ | 3712 and the X and Y parameters are not used. */ |
3721 if (window_redisplay_p) | 3713 if (window_redisplay_p) |
3722 rif->cursor_to (w->cursor.vpos, w->cursor.hpos, | 3714 FRAME_RIF (f)->cursor_to (w->cursor.vpos, w->cursor.hpos, |
3723 w->cursor.y, w->cursor.x); | 3715 w->cursor.y, w->cursor.x); |
3724 else | 3716 else |
3725 { | 3717 { |
3726 int x, y; | 3718 int x, y; |
3727 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos) | 3719 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos) |
3728 + (INTEGERP (w->left_margin_cols) | 3720 + (INTEGERP (w->left_margin_cols) |
3729 ? XFASTINT (w->left_margin_cols) | 3721 ? XFASTINT (w->left_margin_cols) |
3730 : 0)); | 3722 : 0)); |
3731 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos); | 3723 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos); |
3732 cursor_to (y, x); | 3724 cursor_to (f, y, x); |
3733 } | 3725 } |
3734 | 3726 |
3735 #ifdef HAVE_WINDOW_SYSTEM | 3727 #ifdef HAVE_WINDOW_SYSTEM |
3736 update_window_fringes (w, 0); | 3728 update_window_fringes (w, 0); |
3737 #endif | 3729 #endif |
3738 | 3730 |
3739 if (rif) | 3731 if (FRAME_RIF (f)) |
3740 rif->update_window_end_hook (w, 1, 0); | 3732 FRAME_RIF (f)->update_window_end_hook (w, 1, 0); |
3741 update_end (f); | 3733 update_end (f); |
3742 updated_row = NULL; | 3734 updated_row = NULL; |
3743 fflush (stdout); | 3735 if (FRAME_TERMCAP_P (f)) |
3736 fflush (FRAME_TTY (f)->output); | |
3744 | 3737 |
3745 TRACE ((stderr, "direct output for insert\n")); | 3738 TRACE ((stderr, "direct output for insert\n")); |
3746 mark_window_display_accurate (it.window, 1); | 3739 mark_window_display_accurate (it.window, 1); |
3747 redisplay_performed_directly_p = 1; | 3740 redisplay_performed_directly_p = 1; |
3748 return 1; | 3741 return 1; |
3816 | 3809 |
3817 xassert (w->cursor.hpos >= 0 | 3810 xassert (w->cursor.hpos >= 0 |
3818 && w->cursor.hpos < w->desired_matrix->matrix_w); | 3811 && w->cursor.hpos < w->desired_matrix->matrix_w); |
3819 | 3812 |
3820 if (FRAME_WINDOW_P (f)) | 3813 if (FRAME_WINDOW_P (f)) |
3821 rif->cursor_to (w->cursor.vpos, w->cursor.hpos, | 3814 FRAME_RIF (f)->cursor_to (w->cursor.vpos, w->cursor.hpos, |
3822 w->cursor.y, w->cursor.x); | 3815 w->cursor.y, w->cursor.x); |
3823 else | 3816 else |
3824 { | 3817 { |
3825 int x, y; | 3818 int x, y; |
3826 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos) | 3819 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos) |
3827 + (INTEGERP (w->left_margin_cols) | 3820 + (INTEGERP (w->left_margin_cols) |
3828 ? XFASTINT (w->left_margin_cols) | 3821 ? XFASTINT (w->left_margin_cols) |
3829 : 0)); | 3822 : 0)); |
3830 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos); | 3823 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos); |
3831 cursor_to (y, x); | 3824 cursor_to (f, y, x); |
3832 } | 3825 } |
3833 | 3826 |
3834 fflush (stdout); | 3827 if (FRAME_TERMCAP_P (f)) |
3828 fflush (FRAME_TTY (f)->output); | |
3835 redisplay_performed_directly_p = 1; | 3829 redisplay_performed_directly_p = 1; |
3836 return 1; | 3830 return 1; |
3837 } | 3831 } |
3838 | 3832 |
3839 | 3833 |
3928 /* Update windows. */ | 3922 /* Update windows. */ |
3929 paused_p = update_window_tree (root_window, force_p); | 3923 paused_p = update_window_tree (root_window, force_p); |
3930 update_end (f); | 3924 update_end (f); |
3931 | 3925 |
3932 /* This flush is a performance bottleneck under X, | 3926 /* This flush is a performance bottleneck under X, |
3933 and it doesn't seem to be necessary anyway (in general). | 3927 and it doesn't seem to be necessary anyway (in general). |
3934 It is necessary when resizing the window with the mouse, or | 3928 It is necessary when resizing the window with the mouse, or |
3935 at least the fringes are not redrawn in a timely manner. ++kfs */ | 3929 at least the fringes are not redrawn in a timely manner. ++kfs */ |
3936 if (f->force_flush_display_p) | 3930 if (f->force_flush_display_p) |
3937 { | 3931 { |
3938 rif->flush_display (f); | 3932 FRAME_RIF (f)->flush_display (f); |
3939 f->force_flush_display_p = 0; | 3933 f->force_flush_display_p = 0; |
3940 } | 3934 } |
3941 } | 3935 } |
3942 else | 3936 else |
3943 { | 3937 { |
3944 /* We are working on frame matrix basis. Set the frame on whose | 3938 /* We are working on frame matrix basis. Set the frame on whose |
3945 frame matrix we operate. */ | 3939 frame matrix we operate. */ |
3951 /* Update the display */ | 3945 /* Update the display */ |
3952 update_begin (f); | 3946 update_begin (f); |
3953 paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p); | 3947 paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p); |
3954 update_end (f); | 3948 update_end (f); |
3955 | 3949 |
3956 if (termscript) | 3950 if (FRAME_TERMCAP_P (f)) |
3957 fflush (termscript); | 3951 { |
3958 fflush (stdout); | 3952 if (FRAME_TTY (f)->termscript) |
3953 fflush (FRAME_TTY (f)->termscript); | |
3954 fflush (FRAME_TTY (f)->output); | |
3955 } | |
3959 | 3956 |
3960 /* Check window matrices for lost pointers. */ | 3957 /* Check window matrices for lost pointers. */ |
3961 #if GLYPH_DEBUG | 3958 #if GLYPH_DEBUG |
3962 check_window_matrix_pointers (root_window); | 3959 check_window_matrix_pointers (root_window); |
3963 add_frame_display_history (f, paused_p); | 3960 add_frame_display_history (f, paused_p); |
4058 redraw_overlapped_rows (w, yb) | 4055 redraw_overlapped_rows (w, yb) |
4059 struct window *w; | 4056 struct window *w; |
4060 int yb; | 4057 int yb; |
4061 { | 4058 { |
4062 int i; | 4059 int i; |
4063 | 4060 struct frame *f = XFRAME (WINDOW_FRAME (w)); |
4061 | |
4064 /* If rows overlapping others have been changed, the rows being | 4062 /* If rows overlapping others have been changed, the rows being |
4065 overlapped have to be redrawn. This won't draw lines that have | 4063 overlapped have to be redrawn. This won't draw lines that have |
4066 already been drawn in update_window_line because overlapped_p in | 4064 already been drawn in update_window_line because overlapped_p in |
4067 desired rows is 0, so after row assignment overlapped_p in | 4065 desired rows is 0, so after row assignment overlapped_p in |
4068 current rows is 0. */ | 4066 current rows is 0. */ |
4081 | 4079 |
4082 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) | 4080 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) |
4083 { | 4081 { |
4084 updated_row = row; | 4082 updated_row = row; |
4085 updated_area = area; | 4083 updated_area = area; |
4086 rif->cursor_to (i, 0, row->y, area == TEXT_AREA ? row->x : 0); | 4084 FRAME_RIF (f)->cursor_to (i, 0, row->y, |
4085 area == TEXT_AREA ? row->x : 0); | |
4087 if (row->used[area]) | 4086 if (row->used[area]) |
4088 rif->write_glyphs (row->glyphs[area], row->used[area]); | 4087 FRAME_RIF (f)->write_glyphs (row->glyphs[area], |
4089 rif->clear_end_of_line (-1); | 4088 row->used[area]); |
4089 FRAME_RIF (f)->clear_end_of_line (-1); | |
4090 } | 4090 } |
4091 | 4091 |
4092 row->overlapped_p = 0; | 4092 row->overlapped_p = 0; |
4093 } | 4093 } |
4094 | 4094 |
4106 struct window *w; | 4106 struct window *w; |
4107 int yb; | 4107 int yb; |
4108 { | 4108 { |
4109 int i, bottom_y; | 4109 int i, bottom_y; |
4110 struct glyph_row *row; | 4110 struct glyph_row *row; |
4111 | 4111 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); |
4112 | |
4112 for (i = 0; i < w->current_matrix->nrows; ++i) | 4113 for (i = 0; i < w->current_matrix->nrows; ++i) |
4113 { | 4114 { |
4114 row = w->current_matrix->rows + i; | 4115 row = w->current_matrix->rows + i; |
4115 | 4116 |
4116 if (!row->enabled_p) | 4117 if (!row->enabled_p) |
4197 #if !PERIODIC_PREEMPTION_CHECKING | 4198 #if !PERIODIC_PREEMPTION_CHECKING |
4198 int preempt_count = baud_rate / 2400 + 1; | 4199 int preempt_count = baud_rate / 2400 + 1; |
4199 #endif | 4200 #endif |
4200 extern int input_pending; | 4201 extern int input_pending; |
4201 extern Lisp_Object do_mouse_tracking; | 4202 extern Lisp_Object do_mouse_tracking; |
4203 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); | |
4202 #if GLYPH_DEBUG | 4204 #if GLYPH_DEBUG |
4203 /* Check that W's frame doesn't have glyph matrices. */ | 4205 /* Check that W's frame doesn't have glyph matrices. */ |
4204 xassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w)))); | 4206 xassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w)))); |
4205 xassert (updating_frame != NULL); | |
4206 #endif | 4207 #endif |
4207 | 4208 |
4208 /* Check pending input the first time so that we can quickly return. */ | 4209 /* Check pending input the first time so that we can quickly return. */ |
4209 #if !PERIODIC_PREEMPTION_CHECKING | 4210 #if !PERIODIC_PREEMPTION_CHECKING |
4210 if (!force_p) | 4211 if (!force_p) |
4385 update_marginal_area (w, area, vpos) | 4386 update_marginal_area (w, area, vpos) |
4386 struct window *w; | 4387 struct window *w; |
4387 int area, vpos; | 4388 int area, vpos; |
4388 { | 4389 { |
4389 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); | 4390 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); |
4391 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); | |
4390 | 4392 |
4391 /* Let functions in xterm.c know what area subsequent X positions | 4393 /* Let functions in xterm.c know what area subsequent X positions |
4392 will be relative to. */ | 4394 will be relative to. */ |
4393 updated_area = area; | 4395 updated_area = area; |
4394 | 4396 |
4410 struct window *w; | 4412 struct window *w; |
4411 int vpos; | 4413 int vpos; |
4412 { | 4414 { |
4413 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos); | 4415 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos); |
4414 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); | 4416 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); |
4417 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); | |
4415 int changed_p = 0; | 4418 int changed_p = 0; |
4416 | 4419 |
4417 /* Let functions in xterm.c know what area subsequent X positions | 4420 /* Let functions in xterm.c know what area subsequent X positions |
4418 will be relative to. */ | 4421 will be relative to. */ |
4419 updated_area = TEXT_AREA; | 4422 updated_area = TEXT_AREA; |
4645 struct window *w; | 4648 struct window *w; |
4646 int vpos, *mouse_face_overwritten_p; | 4649 int vpos, *mouse_face_overwritten_p; |
4647 { | 4650 { |
4648 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos); | 4651 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos); |
4649 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); | 4652 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); |
4653 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); | |
4650 int changed_p = 0; | 4654 int changed_p = 0; |
4651 | 4655 |
4652 /* Set the row being updated. This is important to let xterm.c | 4656 /* Set the row being updated. This is important to let xterm.c |
4653 know what line height values are in effect. */ | 4657 know what line height values are in effect. */ |
4654 updated_row = desired_row; | 4658 updated_row = desired_row; |
4713 static void | 4717 static void |
4714 set_window_cursor_after_update (w) | 4718 set_window_cursor_after_update (w) |
4715 struct window *w; | 4719 struct window *w; |
4716 { | 4720 { |
4717 struct frame *f = XFRAME (w->frame); | 4721 struct frame *f = XFRAME (w->frame); |
4722 struct redisplay_interface *rif = FRAME_RIF (f); | |
4718 int cx, cy, vpos, hpos; | 4723 int cx, cy, vpos, hpos; |
4719 | 4724 |
4720 /* Not intended for frame matrix updates. */ | 4725 /* Not intended for frame matrix updates. */ |
4721 xassert (FRAME_WINDOW_P (f)); | 4726 xassert (FRAME_WINDOW_P (f)); |
4722 | 4727 |
4936 struct glyph_matrix *current_matrix = w->current_matrix; | 4941 struct glyph_matrix *current_matrix = w->current_matrix; |
4937 int yb = window_text_bottom_y (w); | 4942 int yb = window_text_bottom_y (w); |
4938 int i, j, first_old, first_new, last_old, last_new; | 4943 int i, j, first_old, first_new, last_old, last_new; |
4939 int nruns, nbytes, n, run_idx; | 4944 int nruns, nbytes, n, run_idx; |
4940 struct row_entry *entry; | 4945 struct row_entry *entry; |
4946 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); | |
4941 | 4947 |
4942 /* Skip over rows equal at the start. */ | 4948 /* Skip over rows equal at the start. */ |
4943 for (i = header_line_p ? 1 : 0; i < current_matrix->nrows - 1; ++i) | 4949 for (i = header_line_p ? 1 : 0; i < current_matrix->nrows - 1; ++i) |
4944 { | 4950 { |
4945 struct glyph_row *d = MATRIX_ROW (desired_matrix, i); | 4951 struct glyph_row *d = MATRIX_ROW (desired_matrix, i); |
5260 goto do_pause; | 5266 goto do_pause; |
5261 } | 5267 } |
5262 #endif | 5268 #endif |
5263 | 5269 |
5264 /* If we cannot insert/delete lines, it's no use trying it. */ | 5270 /* If we cannot insert/delete lines, it's no use trying it. */ |
5265 if (!line_ins_del_ok) | 5271 if (!FRAME_LINE_INS_DEL_OK (f)) |
5266 inhibit_id_p = 1; | 5272 inhibit_id_p = 1; |
5267 | 5273 |
5268 /* See if any of the desired lines are enabled; don't compute for | 5274 /* See if any of the desired lines are enabled; don't compute for |
5269 i/d line if just want cursor motion. */ | 5275 i/d line if just want cursor motion. */ |
5270 for (i = 0; i < desired_matrix->nrows; i++) | 5276 for (i = 0; i < desired_matrix->nrows; i++) |
5288 { | 5294 { |
5289 /* Flush out every so many lines. | 5295 /* Flush out every so many lines. |
5290 Also flush out if likely to have more than 1k buffered | 5296 Also flush out if likely to have more than 1k buffered |
5291 otherwise. I'm told that some telnet connections get | 5297 otherwise. I'm told that some telnet connections get |
5292 really screwed by more than 1k output at once. */ | 5298 really screwed by more than 1k output at once. */ |
5293 int outq = PENDING_OUTPUT_COUNT (stdout); | 5299 int outq = PENDING_OUTPUT_COUNT (FRAME_TTY (f)->output); |
5294 if (outq > 900 | 5300 if (outq > 900 |
5295 || (outq > 20 && ((i - 1) % preempt_count == 0))) | 5301 || (outq > 20 && ((i - 1) % preempt_count == 0))) |
5296 { | 5302 { |
5297 fflush (stdout); | 5303 fflush (FRAME_TTY (f)->output); |
5298 if (preempt_count == 1) | 5304 if (preempt_count == 1) |
5299 { | 5305 { |
5300 #ifdef EMACS_OUTQSIZE | 5306 #ifdef EMACS_OUTQSIZE |
5301 if (EMACS_OUTQSIZE (0, &outq) < 0) | 5307 if (EMACS_OUTQSIZE (0, &outq) < 0) |
5302 /* Probably not a tty. Ignore the error and reset | 5308 /* Probably not a tty. Ignore the error and reset |
5303 the outq count. */ | 5309 the outq count. */ |
5304 outq = PENDING_OUTPUT_COUNT (stdout); | 5310 outq = PENDING_OUTPUT_COUNT (FRAME_TTY (f->output)); |
5305 #endif | 5311 #endif |
5306 outq *= 10; | 5312 outq *= 10; |
5307 if (baud_rate <= outq && baud_rate > 0) | 5313 if (baud_rate <= outq && baud_rate > 0) |
5308 sleep (outq / baud_rate); | 5314 sleep (outq / baud_rate); |
5309 } | 5315 } |
5402 else | 5408 else |
5403 col = FRAME_CURSOR_X_LIMIT (f) - 1; | 5409 col = FRAME_CURSOR_X_LIMIT (f) - 1; |
5404 } | 5410 } |
5405 } | 5411 } |
5406 | 5412 |
5407 cursor_to (row, col); | 5413 cursor_to (f, row, col); |
5408 } | 5414 } |
5409 else | 5415 else |
5410 { | 5416 { |
5411 /* We have only one cursor on terminal frames. Use it to | 5417 /* We have only one cursor on terminal frames. Use it to |
5412 display the cursor of the selected window. */ | 5418 display the cursor of the selected window. */ |
5424 | 5430 |
5425 if (INTEGERP (w->left_margin_cols)) | 5431 if (INTEGERP (w->left_margin_cols)) |
5426 x += XFASTINT (w->left_margin_cols); | 5432 x += XFASTINT (w->left_margin_cols); |
5427 | 5433 |
5428 /* x = max (min (x, FRAME_TOTAL_COLS (f) - 1), 0); */ | 5434 /* x = max (min (x, FRAME_TOTAL_COLS (f) - 1), 0); */ |
5429 cursor_to (y, x); | 5435 cursor_to (f, y, x); |
5430 } | 5436 } |
5431 } | 5437 } |
5432 } | 5438 } |
5433 | 5439 |
5434 do_pause: | 5440 do_pause: |
5493 unchanged_at_top++; | 5499 unchanged_at_top++; |
5494 old_draw_cost[i] = line_draw_cost (current_matrix, i); | 5500 old_draw_cost[i] = line_draw_cost (current_matrix, i); |
5495 } | 5501 } |
5496 | 5502 |
5497 /* If changed lines are few, don't allow preemption, don't scroll. */ | 5503 /* If changed lines are few, don't allow preemption, don't scroll. */ |
5498 if ((!scroll_region_ok && changed_lines < baud_rate / 2400) | 5504 if ((!FRAME_SCROLL_REGION_OK (frame) |
5505 && changed_lines < baud_rate / 2400) | |
5499 || unchanged_at_bottom == FRAME_LINES (frame)) | 5506 || unchanged_at_bottom == FRAME_LINES (frame)) |
5500 return 1; | 5507 return 1; |
5501 | 5508 |
5502 window_size = (FRAME_LINES (frame) - unchanged_at_top | 5509 window_size = (FRAME_LINES (frame) - unchanged_at_top |
5503 - unchanged_at_bottom); | 5510 - unchanged_at_bottom); |
5504 | 5511 |
5505 if (scroll_region_ok) | 5512 if (FRAME_SCROLL_REGION_OK (frame)) |
5506 free_at_end_vpos -= unchanged_at_bottom; | 5513 free_at_end_vpos -= unchanged_at_bottom; |
5507 else if (memory_below_frame) | 5514 else if (FRAME_MEMORY_BELOW_FRAME (frame)) |
5508 free_at_end_vpos = -1; | 5515 free_at_end_vpos = -1; |
5509 | 5516 |
5510 /* If large window, fast terminal and few lines in common between | 5517 /* If large window, fast terminal and few lines in common between |
5511 current frame and desired frame, don't bother with i/d calc. */ | 5518 current frame and desired frame, don't bother with i/d calc. */ |
5512 if (!scroll_region_ok && window_size >= 18 && baud_rate > 2400 | 5519 if (!FRAME_SCROLL_REGION_OK (frame) |
5520 && window_size >= 18 && baud_rate > 2400 | |
5513 && (window_size >= | 5521 && (window_size >= |
5514 10 * scrolling_max_lines_saved (unchanged_at_top, | 5522 10 * scrolling_max_lines_saved (unchanged_at_top, |
5515 FRAME_LINES (frame) - unchanged_at_bottom, | 5523 FRAME_LINES (frame) - unchanged_at_bottom, |
5516 old_hash, new_hash, draw_cost))) | 5524 old_hash, new_hash, draw_cost))) |
5517 return 0; | 5525 return 0; |
5587 struct glyph_matrix *current_matrix = f->current_matrix; | 5595 struct glyph_matrix *current_matrix = f->current_matrix; |
5588 struct glyph_matrix *desired_matrix = f->desired_matrix; | 5596 struct glyph_matrix *desired_matrix = f->desired_matrix; |
5589 struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos); | 5597 struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos); |
5590 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, vpos); | 5598 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, vpos); |
5591 int must_write_whole_line_p; | 5599 int must_write_whole_line_p; |
5592 int write_spaces_p = must_write_spaces; | 5600 int write_spaces_p = FRAME_MUST_WRITE_SPACES (f); |
5593 int colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background | 5601 int colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background |
5594 != FACE_TTY_DEFAULT_BG_COLOR); | 5602 != FACE_TTY_DEFAULT_BG_COLOR); |
5595 | 5603 |
5596 if (colored_spaces_p) | 5604 if (colored_spaces_p) |
5597 write_spaces_p = 1; | 5605 write_spaces_p = 1; |
5638 --nlen; | 5646 --nlen; |
5639 | 5647 |
5640 /* Write the contents of the desired line. */ | 5648 /* Write the contents of the desired line. */ |
5641 if (nlen) | 5649 if (nlen) |
5642 { | 5650 { |
5643 cursor_to (vpos, 0); | 5651 cursor_to (f, vpos, 0); |
5644 write_glyphs (nbody, nlen); | 5652 write_glyphs (f, nbody, nlen); |
5645 } | 5653 } |
5646 | 5654 |
5647 /* Don't call clear_end_of_line if we already wrote the whole | 5655 /* Don't call clear_end_of_line if we already wrote the whole |
5648 line. The cursor will not be at the right margin in that | 5656 line. The cursor will not be at the right margin in that |
5649 case but in the line below. */ | 5657 case but in the line below. */ |
5650 if (nlen < FRAME_TOTAL_COLS (f)) | 5658 if (nlen < FRAME_TOTAL_COLS (f)) |
5651 { | 5659 { |
5652 cursor_to (vpos, nlen); | 5660 cursor_to (f, vpos, nlen); |
5653 clear_end_of_line (FRAME_TOTAL_COLS (f)); | 5661 clear_end_of_line (f, FRAME_TOTAL_COLS (f)); |
5654 } | 5662 } |
5655 else | 5663 else |
5656 /* Make sure we are in the right row, otherwise cursor movement | 5664 /* Make sure we are in the right row, otherwise cursor movement |
5657 with cmgoto might use `ch' in the wrong row. */ | 5665 with cmgoto might use `ch' in the wrong row. */ |
5658 cursor_to (vpos, 0); | 5666 cursor_to (f, vpos, 0); |
5659 | 5667 |
5660 make_current (desired_matrix, current_matrix, vpos); | 5668 make_current (desired_matrix, current_matrix, vpos); |
5661 return; | 5669 return; |
5662 } | 5670 } |
5663 | 5671 |
5666 if (!write_spaces_p) | 5674 if (!write_spaces_p) |
5667 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1])) | 5675 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1])) |
5668 nlen--; | 5676 nlen--; |
5669 | 5677 |
5670 /* If there's no i/d char, quickly do the best we can without it. */ | 5678 /* If there's no i/d char, quickly do the best we can without it. */ |
5671 if (!char_ins_del_ok) | 5679 if (!FRAME_CHAR_INS_DEL_OK (f)) |
5672 { | 5680 { |
5673 int i, j; | 5681 int i, j; |
5674 | 5682 |
5675 /* Find the first glyph in desired row that doesn't agree with | 5683 /* Find the first glyph in desired row that doesn't agree with |
5676 a glyph in the current row, and write the rest from there on. */ | 5684 a glyph in the current row, and write the rest from there on. */ |
5685 || !GLYPH_EQUAL_P (nbody + j, obody + j) | 5693 || !GLYPH_EQUAL_P (nbody + j, obody + j) |
5686 || CHAR_GLYPH_PADDING_P (nbody[j]))) | 5694 || CHAR_GLYPH_PADDING_P (nbody[j]))) |
5687 ++j; | 5695 ++j; |
5688 | 5696 |
5689 /* Output this run of non-matching chars. */ | 5697 /* Output this run of non-matching chars. */ |
5690 cursor_to (vpos, i); | 5698 cursor_to (f, vpos, i); |
5691 write_glyphs (nbody + i, j - i); | 5699 write_glyphs (f, nbody + i, j - i); |
5692 i = j - 1; | 5700 i = j - 1; |
5693 | 5701 |
5694 /* Now find the next non-match. */ | 5702 /* Now find the next non-match. */ |
5695 } | 5703 } |
5696 } | 5704 } |
5697 | 5705 |
5698 /* Clear the rest of the line, or the non-clear part of it. */ | 5706 /* Clear the rest of the line, or the non-clear part of it. */ |
5699 if (olen > nlen) | 5707 if (olen > nlen) |
5700 { | 5708 { |
5701 cursor_to (vpos, nlen); | 5709 cursor_to (f, vpos, nlen); |
5702 clear_end_of_line (olen); | 5710 clear_end_of_line (f, olen); |
5703 } | 5711 } |
5704 | 5712 |
5705 /* Make current row = desired row. */ | 5713 /* Make current row = desired row. */ |
5706 make_current (desired_matrix, current_matrix, vpos); | 5714 make_current (desired_matrix, current_matrix, vpos); |
5707 return; | 5715 return; |
5719 else | 5727 else |
5720 nsp = count_blanks (nbody, nlen); | 5728 nsp = count_blanks (nbody, nlen); |
5721 | 5729 |
5722 if (nlen > nsp) | 5730 if (nlen > nsp) |
5723 { | 5731 { |
5724 cursor_to (vpos, nsp); | 5732 cursor_to (f, vpos, nsp); |
5725 write_glyphs (nbody + nsp, nlen - nsp); | 5733 write_glyphs (f, nbody + nsp, nlen - nsp); |
5726 } | 5734 } |
5727 | 5735 |
5728 /* Exchange contents between current_frame and new_frame. */ | 5736 /* Exchange contents between current_frame and new_frame. */ |
5729 make_current (desired_matrix, current_matrix, vpos); | 5737 make_current (desired_matrix, current_matrix, vpos); |
5730 return; | 5738 return; |
5769 endmatch is how many characters we save by doing so. | 5777 endmatch is how many characters we save by doing so. |
5770 Is it worth it? */ | 5778 Is it worth it? */ |
5771 | 5779 |
5772 tem = (nlen - nsp) - (olen - osp); | 5780 tem = (nlen - nsp) - (olen - osp); |
5773 if (endmatch && tem | 5781 if (endmatch && tem |
5774 && (!char_ins_del_ok || endmatch <= char_ins_del_cost (f)[tem])) | 5782 && (!FRAME_CHAR_INS_DEL_OK (f) |
5783 || endmatch <= char_ins_del_cost (f)[tem])) | |
5775 endmatch = 0; | 5784 endmatch = 0; |
5776 | 5785 |
5777 /* nsp - osp is the distance to insert or delete. | 5786 /* nsp - osp is the distance to insert or delete. |
5778 If that is nonzero, begmatch is known to be nonzero also. | 5787 If that is nonzero, begmatch is known to be nonzero also. |
5779 begmatch + endmatch is how much we save by doing the ins/del. | 5788 begmatch + endmatch is how much we save by doing the ins/del. |
5780 Is it worth it? */ | 5789 Is it worth it? */ |
5781 | 5790 |
5782 if (nsp != osp | 5791 if (nsp != osp |
5783 && (!char_ins_del_ok | 5792 && (!FRAME_CHAR_INS_DEL_OK (f) |
5784 || begmatch + endmatch <= char_ins_del_cost (f)[nsp - osp])) | 5793 || begmatch + endmatch <= char_ins_del_cost (f)[nsp - osp])) |
5785 { | 5794 { |
5786 begmatch = 0; | 5795 begmatch = 0; |
5787 endmatch = 0; | 5796 endmatch = 0; |
5788 osp = nsp = min (osp, nsp); | 5797 osp = nsp = min (osp, nsp); |
5791 /* Now go through the line, inserting, writing and | 5800 /* Now go through the line, inserting, writing and |
5792 deleting as appropriate. */ | 5801 deleting as appropriate. */ |
5793 | 5802 |
5794 if (osp > nsp) | 5803 if (osp > nsp) |
5795 { | 5804 { |
5796 cursor_to (vpos, nsp); | 5805 cursor_to (f, vpos, nsp); |
5797 delete_glyphs (osp - nsp); | 5806 delete_glyphs (f, osp - nsp); |
5798 } | 5807 } |
5799 else if (nsp > osp) | 5808 else if (nsp > osp) |
5800 { | 5809 { |
5801 /* If going to delete chars later in line | 5810 /* If going to delete chars later in line |
5802 and insert earlier in the line, | 5811 and insert earlier in the line, |
5803 must delete first to avoid losing data in the insert */ | 5812 must delete first to avoid losing data in the insert */ |
5804 if (endmatch && nlen < olen + nsp - osp) | 5813 if (endmatch && nlen < olen + nsp - osp) |
5805 { | 5814 { |
5806 cursor_to (vpos, nlen - endmatch + osp - nsp); | 5815 cursor_to (f, vpos, nlen - endmatch + osp - nsp); |
5807 delete_glyphs (olen + nsp - osp - nlen); | 5816 delete_glyphs (f, olen + nsp - osp - nlen); |
5808 olen = nlen - (nsp - osp); | 5817 olen = nlen - (nsp - osp); |
5809 } | 5818 } |
5810 cursor_to (vpos, osp); | 5819 cursor_to (f, vpos, osp); |
5811 insert_glyphs (0, nsp - osp); | 5820 insert_glyphs (f, 0, nsp - osp); |
5812 } | 5821 } |
5813 olen += nsp - osp; | 5822 olen += nsp - osp; |
5814 | 5823 |
5815 tem = nsp + begmatch + endmatch; | 5824 tem = nsp + begmatch + endmatch; |
5816 if (nlen != tem || olen != tem) | 5825 if (nlen != tem || olen != tem) |
5827 /* Function write_glyphs is prepared to do nothing | 5836 /* Function write_glyphs is prepared to do nothing |
5828 if passed a length <= 0. Check it here to avoid | 5837 if passed a length <= 0. Check it here to avoid |
5829 unnecessary cursor movement. */ | 5838 unnecessary cursor movement. */ |
5830 if (nlen - tem > 0) | 5839 if (nlen - tem > 0) |
5831 { | 5840 { |
5832 cursor_to (vpos, nsp + begmatch); | 5841 cursor_to (f, vpos, nsp + begmatch); |
5833 write_glyphs (nbody + nsp + begmatch, nlen - tem); | 5842 write_glyphs (f, nbody + nsp + begmatch, nlen - tem); |
5834 } | 5843 } |
5835 } | 5844 } |
5836 else if (nlen > olen) | 5845 else if (nlen > olen) |
5837 { | 5846 { |
5838 /* Here, we used to have the following simple code: | 5847 /* Here, we used to have the following simple code: |
5843 but it doesn't work if nbody[nsp + begmatch + olen - tem] | 5852 but it doesn't work if nbody[nsp + begmatch + olen - tem] |
5844 is a padding glyph. */ | 5853 is a padding glyph. */ |
5845 int out = olen - tem; /* Columns to be overwritten originally. */ | 5854 int out = olen - tem; /* Columns to be overwritten originally. */ |
5846 int del; | 5855 int del; |
5847 | 5856 |
5848 cursor_to (vpos, nsp + begmatch); | 5857 cursor_to (f, vpos, nsp + begmatch); |
5849 | 5858 |
5850 /* Calculate columns we can actually overwrite. */ | 5859 /* Calculate columns we can actually overwrite. */ |
5851 while (CHAR_GLYPH_PADDING_P (nbody[nsp + begmatch + out])) | 5860 while (CHAR_GLYPH_PADDING_P (nbody[nsp + begmatch + out])) |
5852 out--; | 5861 out--; |
5853 write_glyphs (nbody + nsp + begmatch, out); | 5862 write_glyphs (f, nbody + nsp + begmatch, out); |
5854 | 5863 |
5855 /* If we left columns to be overwritten, we must delete them. */ | 5864 /* If we left columns to be overwritten, we must delete them. */ |
5856 del = olen - tem - out; | 5865 del = olen - tem - out; |
5857 if (del > 0) | 5866 if (del > 0) |
5858 delete_glyphs (del); | 5867 delete_glyphs (f, del); |
5859 | 5868 |
5860 /* At last, we insert columns not yet written out. */ | 5869 /* At last, we insert columns not yet written out. */ |
5861 insert_glyphs (nbody + nsp + begmatch + out, nlen - olen + del); | 5870 insert_glyphs (f, nbody + nsp + begmatch + out, nlen - olen + del); |
5862 olen = nlen; | 5871 olen = nlen; |
5863 } | 5872 } |
5864 else if (olen > nlen) | 5873 else if (olen > nlen) |
5865 { | 5874 { |
5866 cursor_to (vpos, nsp + begmatch); | 5875 cursor_to (f, vpos, nsp + begmatch); |
5867 write_glyphs (nbody + nsp + begmatch, nlen - tem); | 5876 write_glyphs (f, nbody + nsp + begmatch, nlen - tem); |
5868 delete_glyphs (olen - nlen); | 5877 delete_glyphs (f, olen - nlen); |
5869 olen = nlen; | 5878 olen = nlen; |
5870 } | 5879 } |
5871 } | 5880 } |
5872 | 5881 |
5873 just_erase: | 5882 just_erase: |
5874 /* If any unerased characters remain after the new line, erase them. */ | 5883 /* If any unerased characters remain after the new line, erase them. */ |
5875 if (olen > nlen) | 5884 if (olen > nlen) |
5876 { | 5885 { |
5877 cursor_to (vpos, nlen); | 5886 cursor_to (f, vpos, nlen); |
5878 clear_end_of_line (olen); | 5887 clear_end_of_line (f, olen); |
5879 } | 5888 } |
5880 | 5889 |
5881 /* Exchange contents between current_frame and new_frame. */ | 5890 /* Exchange contents between current_frame and new_frame. */ |
5882 make_current (desired_matrix, current_matrix, vpos); | 5891 make_current (desired_matrix, current_matrix, vpos); |
5883 } | 5892 } |
6170 #ifndef USE_CRT_DLL | 6179 #ifndef USE_CRT_DLL |
6171 extern int errno; | 6180 extern int errno; |
6172 #endif | 6181 #endif |
6173 int old_errno = errno; | 6182 int old_errno = errno; |
6174 | 6183 |
6184 struct tty_display_info *tty; | |
6185 | |
6175 signal (SIGWINCH, window_change_signal); | 6186 signal (SIGWINCH, window_change_signal); |
6176 SIGNAL_THREAD_CHECK (signalnum); | 6187 SIGNAL_THREAD_CHECK (signalnum); |
6177 | 6188 |
6178 get_frame_size (&width, &height); | 6189 /* The frame size change obviously applies to a single |
6179 | 6190 termcap-controlled terminal, but we can't decide which. |
6180 /* The frame size change obviously applies to a termcap-controlled | 6191 Therefore, we resize the frames corresponding to each tty. |
6181 frame. Find such a frame in the list, and assume it's the only | 6192 */ |
6182 one (since the redisplay code always writes to stdout, not a | 6193 for (tty = tty_list; tty; tty = tty->next) { |
6183 FILE * specified in the frame structure). Record the new size, | 6194 |
6184 but don't reallocate the data structures now. Let that be done | 6195 if (! tty->term_initted) |
6185 later outside of the signal handler. */ | 6196 continue; |
6186 | 6197 |
6187 { | 6198 get_tty_size (fileno (tty->input), &width, &height); |
6188 Lisp_Object tail, frame; | 6199 |
6189 | 6200 if (width > 5 && height > 2) { |
6190 FOR_EACH_FRAME (tail, frame) | 6201 Lisp_Object tail, frame; |
6191 { | 6202 |
6192 if (FRAME_TERMCAP_P (XFRAME (frame))) | 6203 FOR_EACH_FRAME (tail, frame) |
6193 { | 6204 if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty) |
6194 change_frame_size (XFRAME (frame), height, width, 0, 1, 0); | 6205 /* Record the new sizes, but don't reallocate the data |
6195 break; | 6206 structures now. Let that be done later outside of the |
6196 } | 6207 signal handler. */ |
6197 } | 6208 change_frame_size (XFRAME (frame), height, width, 0, 1, 0); |
6209 } | |
6198 } | 6210 } |
6199 | 6211 |
6200 errno = old_errno; | 6212 errno = old_errno; |
6201 } | 6213 } |
6202 #endif /* SIGWINCH */ | 6214 #endif /* SIGWINCH */ |
6203 | 6215 |
6204 | 6216 |
6248 register struct frame *f; | 6260 register struct frame *f; |
6249 int newheight, newwidth, pretend, delay, safe; | 6261 int newheight, newwidth, pretend, delay, safe; |
6250 { | 6262 { |
6251 Lisp_Object tail, frame; | 6263 Lisp_Object tail, frame; |
6252 | 6264 |
6253 if (! FRAME_WINDOW_P (f)) | 6265 if (FRAME_MSDOS_P (f)) |
6254 { | 6266 { |
6255 /* When using termcap, or on MS-DOS, all frames use | 6267 /* On MS-DOS, all frames use the same screen, so a change in |
6256 the same screen, so a change in size affects all frames. */ | 6268 size affects all frames. Termcap now supports multiple |
6269 ttys. */ | |
6257 FOR_EACH_FRAME (tail, frame) | 6270 FOR_EACH_FRAME (tail, frame) |
6258 if (! FRAME_WINDOW_P (XFRAME (frame))) | 6271 if (! FRAME_WINDOW_P (XFRAME (frame))) |
6259 change_frame_size_1 (XFRAME (frame), newheight, newwidth, | 6272 change_frame_size_1 (XFRAME (frame), newheight, newwidth, |
6260 pretend, delay, safe); | 6273 pretend, delay, safe); |
6261 } | 6274 } |
6331 /* Frame has just one top-level window. */ | 6344 /* Frame has just one top-level window. */ |
6332 set_window_height (FRAME_ROOT_WINDOW (f), | 6345 set_window_height (FRAME_ROOT_WINDOW (f), |
6333 newheight - FRAME_TOP_MARGIN (f), 0); | 6346 newheight - FRAME_TOP_MARGIN (f), 0); |
6334 | 6347 |
6335 if (FRAME_TERMCAP_P (f) && !pretend) | 6348 if (FRAME_TERMCAP_P (f) && !pretend) |
6336 FrameRows = newheight; | 6349 FrameRows (FRAME_TTY (f)) = newheight; |
6337 } | 6350 } |
6338 | 6351 |
6339 if (new_frame_total_cols != FRAME_TOTAL_COLS (f)) | 6352 if (new_frame_total_cols != FRAME_TOTAL_COLS (f)) |
6340 { | 6353 { |
6341 set_window_width (FRAME_ROOT_WINDOW (f), new_frame_total_cols, 0); | 6354 set_window_width (FRAME_ROOT_WINDOW (f), new_frame_total_cols, 0); |
6342 if (FRAME_HAS_MINIBUF_P (f)) | 6355 if (FRAME_HAS_MINIBUF_P (f)) |
6343 set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_total_cols, 0); | 6356 set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_total_cols, 0); |
6344 | 6357 |
6345 if (FRAME_TERMCAP_P (f) && !pretend) | 6358 if (FRAME_TERMCAP_P (f) && !pretend) |
6346 FrameCols = newwidth; | 6359 FrameCols (FRAME_TTY (f)) = newwidth; |
6347 | 6360 |
6348 if (WINDOWP (f->tool_bar_window)) | 6361 if (WINDOWP (f->tool_bar_window)) |
6349 XSETFASTINT (XWINDOW (f->tool_bar_window)->total_cols, newwidth); | 6362 XSETFASTINT (XWINDOW (f->tool_bar_window)->total_cols, newwidth); |
6350 } | 6363 } |
6351 | 6364 |
6391 doc: /* Start writing all terminal output to FILE as well as the terminal. | 6404 doc: /* Start writing all terminal output to FILE as well as the terminal. |
6392 FILE = nil means just close any termscript file currently open. */) | 6405 FILE = nil means just close any termscript file currently open. */) |
6393 (file) | 6406 (file) |
6394 Lisp_Object file; | 6407 Lisp_Object file; |
6395 { | 6408 { |
6396 if (termscript != 0) | 6409 struct tty_display_info *tty; |
6397 { | 6410 |
6398 BLOCK_INPUT; | 6411 if (! FRAME_TERMCAP_P (SELECTED_FRAME ())) |
6399 fclose (termscript); | 6412 error ("Current frame is not on a tty device"); |
6400 UNBLOCK_INPUT; | 6413 |
6401 } | 6414 tty = CURTTY (); |
6402 termscript = 0; | 6415 |
6416 if (tty->termscript != 0) | |
6417 { | |
6418 BLOCK_INPUT; | |
6419 fclose (tty->termscript); | |
6420 UNBLOCK_INPUT; | |
6421 } | |
6422 tty->termscript = 0; | |
6403 | 6423 |
6404 if (! NILP (file)) | 6424 if (! NILP (file)) |
6405 { | 6425 { |
6406 file = Fexpand_file_name (file, Qnil); | 6426 file = Fexpand_file_name (file, Qnil); |
6407 termscript = fopen (SDATA (file), "w"); | 6427 tty->termscript = fopen (SDATA (file), "w"); |
6408 if (termscript == 0) | 6428 if (tty->termscript == 0) |
6409 report_file_error ("Opening termscript", Fcons (file, Qnil)); | 6429 report_file_error ("Opening termscript", Fcons (file, Qnil)); |
6410 } | 6430 } |
6411 return Qnil; | 6431 return Qnil; |
6412 } | 6432 } |
6413 | 6433 |
6414 | 6434 |
6415 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal, | 6435 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal, |
6416 Ssend_string_to_terminal, 1, 1, 0, | 6436 Ssend_string_to_terminal, 1, 2, 0, |
6417 doc: /* Send STRING to the terminal without alteration. | 6437 doc: /* Send STRING to the terminal without alteration. |
6418 Control characters in STRING will have terminal-dependent effects. */) | 6438 Control characters in STRING will have terminal-dependent effects. |
6419 (string) | 6439 |
6440 Optional parameter TERMINAL specifies the tty terminal device to use. | |
6441 It may be a terminal id, a frame, or nil for the terminal used by the | |
6442 currently selected frame. */) | |
6443 (string, terminal) | |
6420 Lisp_Object string; | 6444 Lisp_Object string; |
6421 { | 6445 Lisp_Object terminal; |
6446 { | |
6447 struct terminal *t = get_tty_terminal (terminal, 1); | |
6448 struct tty_display_info *tty; | |
6449 | |
6422 /* ??? Perhaps we should do something special for multibyte strings here. */ | 6450 /* ??? Perhaps we should do something special for multibyte strings here. */ |
6423 CHECK_STRING (string); | 6451 CHECK_STRING (string); |
6424 BLOCK_INPUT; | 6452 BLOCK_INPUT; |
6425 fwrite (SDATA (string), 1, SBYTES (string), stdout); | 6453 |
6426 fflush (stdout); | 6454 if (!t) |
6427 if (termscript) | 6455 error ("Unknown terminal device"); |
6428 { | 6456 |
6429 fwrite (SDATA (string), 1, SBYTES (string), | 6457 tty = t->display_info.tty; |
6430 termscript); | 6458 |
6431 fflush (termscript); | 6459 if (tty->termscript) |
6432 } | 6460 { |
6461 fwrite (SDATA (string), 1, SBYTES (string), tty->termscript); | |
6462 fflush (tty->termscript); | |
6463 } | |
6464 fwrite (SDATA (string), 1, SBYTES (string), tty->output); | |
6465 fflush (tty->output); | |
6433 UNBLOCK_INPUT; | 6466 UNBLOCK_INPUT; |
6434 return Qnil; | 6467 return Qnil; |
6435 } | 6468 } |
6436 | 6469 |
6437 | 6470 |
6445 if (!NILP (arg)) | 6478 if (!NILP (arg)) |
6446 { | 6479 { |
6447 if (noninteractive) | 6480 if (noninteractive) |
6448 putchar (07); | 6481 putchar (07); |
6449 else | 6482 else |
6450 ring_bell (); | 6483 ring_bell (XFRAME (selected_frame)); |
6451 fflush (stdout); | |
6452 } | 6484 } |
6453 else | 6485 else |
6454 bitch_at_user (); | 6486 bitch_at_user (); |
6455 | 6487 |
6456 return Qnil; | 6488 return Qnil; |
6462 if (noninteractive) | 6494 if (noninteractive) |
6463 putchar (07); | 6495 putchar (07); |
6464 else if (!INTERACTIVE) /* Stop executing a keyboard macro. */ | 6496 else if (!INTERACTIVE) /* Stop executing a keyboard macro. */ |
6465 error ("Keyboard macro terminated by a command ringing the bell"); | 6497 error ("Keyboard macro terminated by a command ringing the bell"); |
6466 else | 6498 else |
6467 ring_bell (); | 6499 ring_bell (XFRAME (selected_frame)); |
6468 fflush (stdout); | |
6469 } | 6500 } |
6470 | 6501 |
6471 | 6502 |
6472 | 6503 |
6473 /*********************************************************************** | 6504 /*********************************************************************** |
6746 | 6777 |
6747 /*********************************************************************** | 6778 /*********************************************************************** |
6748 Initialization | 6779 Initialization |
6749 ***********************************************************************/ | 6780 ***********************************************************************/ |
6750 | 6781 |
6751 char *terminal_type; | |
6752 | |
6753 /* Initialization done when Emacs fork is started, before doing stty. | 6782 /* Initialization done when Emacs fork is started, before doing stty. |
6754 Determine terminal type and set terminal_driver. Then invoke its | 6783 Determine terminal type and set terminal_driver. Then invoke its |
6755 decoding routine to set up variables in the terminal package. */ | 6784 decoding routine to set up variables in the terminal package. */ |
6756 | 6785 |
6757 void | 6786 void |
6758 init_display () | 6787 init_display () |
6759 { | 6788 { |
6789 char *terminal_type; | |
6790 | |
6760 #ifdef HAVE_X_WINDOWS | 6791 #ifdef HAVE_X_WINDOWS |
6761 extern int display_arg; | 6792 extern int display_arg; |
6762 #endif | 6793 #endif |
6763 | 6794 |
6764 /* Construct the space glyph. */ | 6795 /* Construct the space glyph. */ |
6765 space_glyph.type = CHAR_GLYPH; | 6796 space_glyph.type = CHAR_GLYPH; |
6766 SET_CHAR_GLYPH_FROM_GLYPH (space_glyph, ' '); | 6797 SET_CHAR_GLYPH_FROM_GLYPH (space_glyph, ' '); |
6767 space_glyph.charpos = -1; | 6798 space_glyph.charpos = -1; |
6768 | 6799 |
6769 meta_key = 0; | |
6770 inverse_video = 0; | 6800 inverse_video = 0; |
6771 cursor_in_echo_area = 0; | 6801 cursor_in_echo_area = 0; |
6772 terminal_type = (char *) 0; | 6802 terminal_type = (char *) 0; |
6773 | 6803 |
6774 /* Now is the time to initialize this; it's used by init_sys_modes | 6804 /* Now is the time to initialize this; it's used by init_sys_modes |
6775 during startup. */ | 6805 during startup. */ |
6776 Vwindow_system = Qnil; | 6806 Vinitial_window_system = Qnil; |
6807 | |
6808 /* SIGWINCH needs to be handled no matter what display we start | |
6809 with. Otherwise newly opened tty frames will not resize | |
6810 automatically. */ | |
6811 #ifdef SIGWINCH | |
6812 #ifndef CANNOT_DUMP | |
6813 if (initialized) | |
6814 #endif /* CANNOT_DUMP */ | |
6815 signal (SIGWINCH, window_change_signal); | |
6816 #endif /* SIGWINCH */ | |
6777 | 6817 |
6778 /* If the user wants to use a window system, we shouldn't bother | 6818 /* If the user wants to use a window system, we shouldn't bother |
6779 initializing the terminal. This is especially important when the | 6819 initializing the terminal. This is especially important when the |
6780 terminal is so dumb that emacs gives up before and doesn't bother | 6820 terminal is so dumb that emacs gives up before and doesn't bother |
6781 using the window system. | 6821 using the window system. |
6807 #ifndef CANNOT_DUMP | 6847 #ifndef CANNOT_DUMP |
6808 && initialized | 6848 && initialized |
6809 #endif | 6849 #endif |
6810 ) | 6850 ) |
6811 { | 6851 { |
6812 Vwindow_system = intern ("x"); | 6852 Vinitial_window_system = intern ("x"); |
6813 #ifdef HAVE_X11 | 6853 #ifdef HAVE_X11 |
6814 Vwindow_system_version = make_number (11); | 6854 Vwindow_system_version = make_number (11); |
6815 #else | 6855 #else |
6816 Vwindow_system_version = make_number (10); | 6856 Vwindow_system_version = make_number (10); |
6817 #endif | 6857 #endif |
6827 #endif /* HAVE_X_WINDOWS */ | 6867 #endif /* HAVE_X_WINDOWS */ |
6828 | 6868 |
6829 #ifdef HAVE_NTGUI | 6869 #ifdef HAVE_NTGUI |
6830 if (!inhibit_window_system) | 6870 if (!inhibit_window_system) |
6831 { | 6871 { |
6832 Vwindow_system = intern ("w32"); | 6872 Vinitial_window_system = intern ("w32"); |
6833 Vwindow_system_version = make_number (1); | 6873 Vwindow_system_version = make_number (1); |
6834 adjust_frame_glyphs_initially (); | 6874 adjust_frame_glyphs_initially (); |
6835 return; | 6875 return; |
6836 } | 6876 } |
6837 #endif /* HAVE_NTGUI */ | 6877 #endif /* HAVE_NTGUI */ |
6838 | 6878 |
6839 #ifdef MAC_OS | 6879 #ifdef MAC_OS |
6840 if (!inhibit_window_system) | 6880 if (!inhibit_window_system) |
6841 { | 6881 { |
6842 Vwindow_system = intern ("mac"); | 6882 Vinitial_window_system = intern ("mac"); |
6843 Vwindow_system_version = make_number (1); | 6883 Vwindow_system_version = make_number (1); |
6844 adjust_frame_glyphs_initially (); | 6884 adjust_frame_glyphs_initially (); |
6845 return; | 6885 return; |
6846 } | 6886 } |
6847 #endif /* MAC_OS */ | 6887 #endif /* MAC_OS */ |
6889 | 6929 |
6890 terminal_type = new; | 6930 terminal_type = new; |
6891 } | 6931 } |
6892 #endif /* VMS */ | 6932 #endif /* VMS */ |
6893 | 6933 |
6894 term_init (terminal_type); | 6934 { |
6895 | 6935 struct terminal *t; |
6936 struct frame *f = XFRAME (selected_frame); | |
6937 | |
6938 /* Open a display on the controlling tty. */ | |
6939 t = init_tty (0, terminal_type, 1); /* Errors are fatal. */ | |
6940 | |
6941 /* Convert the initial frame to use the new display. */ | |
6942 if (f->output_method != output_initial) | |
6943 abort (); | |
6944 f->output_method = t->type; | |
6945 f->terminal = t; | |
6946 | |
6947 t->reference_count++; | |
6948 t->display_info.tty->top_frame = selected_frame; | |
6949 change_frame_size (XFRAME (selected_frame), | |
6950 FrameRows (t->display_info.tty), | |
6951 FrameCols (t->display_info.tty), 0, 0, 1); | |
6952 | |
6953 /* Delete the initial terminal. */ | |
6954 if (--initial_terminal->reference_count == 0 | |
6955 && initial_terminal->delete_terminal_hook) | |
6956 (*initial_terminal->delete_terminal_hook) (initial_terminal); | |
6957 | |
6958 /* Update frame parameters to reflect the new type. */ | |
6959 Fmodify_frame_parameters (selected_frame, Fcons (Fcons (Qwindow_system, Qnil), Qnil)); | |
6960 Fmodify_frame_parameters | |
6961 (selected_frame, Fcons (Fcons (Qtty_type, | |
6962 Ftty_type (selected_frame)), Qnil)); | |
6963 Fmodify_frame_parameters (selected_frame, Fcons (Fcons (Qtty, Qnil), Qnil)); | |
6964 } | |
6965 | |
6896 { | 6966 { |
6897 struct frame *sf = SELECTED_FRAME (); | 6967 struct frame *sf = SELECTED_FRAME (); |
6898 int width = FRAME_TOTAL_COLS (sf); | 6968 int width = FRAME_TOTAL_COLS (sf); |
6899 int height = FRAME_LINES (sf); | 6969 int height = FRAME_LINES (sf); |
6900 | 6970 |
6906 fatal ("screen size %dx%d too big", width, height); | 6976 fatal ("screen size %dx%d too big", width, height); |
6907 } | 6977 } |
6908 | 6978 |
6909 adjust_frame_glyphs_initially (); | 6979 adjust_frame_glyphs_initially (); |
6910 calculate_costs (XFRAME (selected_frame)); | 6980 calculate_costs (XFRAME (selected_frame)); |
6911 | |
6912 #ifdef SIGWINCH | |
6913 #ifndef CANNOT_DUMP | |
6914 if (initialized) | |
6915 #endif /* CANNOT_DUMP */ | |
6916 signal (SIGWINCH, window_change_signal); | |
6917 #endif /* SIGWINCH */ | |
6918 | 6981 |
6919 /* Set up faces of the initial terminal frame of a dumped Emacs. */ | 6982 /* Set up faces of the initial terminal frame of a dumped Emacs. */ |
6920 if (initialized | 6983 if (initialized |
6921 && !noninteractive | 6984 && !noninteractive |
6922 #ifdef MSDOS | 6985 #ifdef MSDOS |
6924 late into the startup, so we cannot do the frame faces' | 6987 late into the startup, so we cannot do the frame faces' |
6925 initialization just yet. It will be done later by pc-win.el | 6988 initialization just yet. It will be done later by pc-win.el |
6926 and internal_terminal_init. */ | 6989 and internal_terminal_init. */ |
6927 && (strcmp (terminal_type, "internal") != 0 || inhibit_window_system) | 6990 && (strcmp (terminal_type, "internal") != 0 || inhibit_window_system) |
6928 #endif | 6991 #endif |
6929 && NILP (Vwindow_system)) | 6992 && NILP (Vinitial_window_system)) |
6930 { | 6993 { |
6931 /* For the initial frame, we don't have any way of knowing what | 6994 /* For the initial frame, we don't have any way of knowing what |
6932 are the foreground and background colors of the terminal. */ | 6995 are the foreground and background colors of the terminal. */ |
6933 struct frame *sf = SELECTED_FRAME(); | 6996 struct frame *sf = SELECTED_FRAME(); |
6934 | 6997 |
7036 doc: /* *Non-nil means no need to redraw entire frame after suspending. | 7099 doc: /* *Non-nil means no need to redraw entire frame after suspending. |
7037 A non-nil value is useful if the terminal can automatically preserve | 7100 A non-nil value is useful if the terminal can automatically preserve |
7038 Emacs's frame display when you reenter Emacs. | 7101 Emacs's frame display when you reenter Emacs. |
7039 It is up to you to set this variable if your terminal can do that. */); | 7102 It is up to you to set this variable if your terminal can do that. */); |
7040 | 7103 |
7041 DEFVAR_LISP ("window-system", &Vwindow_system, | 7104 DEFVAR_LISP ("initial-window-system", &Vinitial_window_system, |
7042 doc: /* Name of window system that Emacs is displaying through. | 7105 doc: /* Name of the window system that Emacs uses for the first frame. |
7043 The value is a symbol--for instance, `x' for X windows. | 7106 The value is a symbol--for instance, `x' for X windows. |
7044 The value is nil if Emacs is using a text-only terminal. */); | 7107 The value is nil if Emacs is using a text-only terminal. */); |
7045 | 7108 |
7046 DEFVAR_LISP ("window-system-version", &Vwindow_system_version, | 7109 DEFVAR_LISP ("window-system-version", &Vwindow_system_version, |
7047 doc: /* The version number of the window system in use. | 7110 doc: /* The version number of the window system in use. |
7080 | 7143 |
7081 #ifdef CANNOT_DUMP | 7144 #ifdef CANNOT_DUMP |
7082 if (noninteractive) | 7145 if (noninteractive) |
7083 #endif | 7146 #endif |
7084 { | 7147 { |
7085 Vwindow_system = Qnil; | 7148 Vinitial_window_system = Qnil; |
7086 Vwindow_system_version = Qnil; | 7149 Vwindow_system_version = Qnil; |
7087 } | 7150 } |
7088 } | 7151 } |
7089 | 7152 |
7090 /* arch-tag: 8d812b1f-04a2-4195-a9c4-381f8457a413 | 7153 /* arch-tag: 8d812b1f-04a2-4195-a9c4-381f8457a413 |