aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2010-03-31 00:14:08 -0400
committerStefan Monnier2010-03-31 00:14:08 -0400
commit855a0da7fdb9c33761d7ba3ad6ab66a41bc2d1f3 (patch)
tree7e136862fdaf8e885e1706be53e92914c8f27a0b /src
parentdcf7843e7e1a857c21e39c2a5e53d27039a34a3a (diff)
downloademacs-855a0da7fdb9c33761d7ba3ad6ab66a41bc2d1f3.tar.gz
emacs-855a0da7fdb9c33761d7ba3ad6ab66a41bc2d1f3.zip
Get rid of the direct_output optimizations.
* keyboard.c (nonundocount): Remove extern declaration. (command_loop_1): Remove brittle optimisation for cheap and common operations. * xdisp.c (redisplay_internal): Don't bother checking redisplay_performed_directly_p any more. * sysdep.c (init_sys_modes): Don't call direct_output_forward_char any more. * dispnew.c (redisplay_performed_directly_p) (direct_output_for_insert, direct_output_forward_char): * dispextern.h (redisplay_performed_directly_p) (direct_output_for_insert, direct_output_forward_char): Remove. * cmds.c (nonundocount): Make it static.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog20
-rw-r--r--src/cmds.c2
-rw-r--r--src/dispextern.h14
-rw-r--r--src/dispnew.c401
-rw-r--r--src/keyboard.c146
-rw-r--r--src/sysdep.c5
-rw-r--r--src/xdisp.c37
7 files changed, 23 insertions, 602 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 767780d6938..9d70a3327b6 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,19 @@
12010-03-31 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 Get rid of the direct_output optimizations.
4 * keyboard.c (nonundocount): Remove extern declaration.
5 (command_loop_1): Remove brittle optimisation for cheap and
6 common operations.
7 * xdisp.c (redisplay_internal): Don't bother checking
8 redisplay_performed_directly_p any more.
9 * sysdep.c (init_sys_modes): Don't call direct_output_forward_char
10 any more.
11 * dispnew.c (redisplay_performed_directly_p)
12 (direct_output_for_insert, direct_output_forward_char):
13 * dispextern.h (redisplay_performed_directly_p)
14 (direct_output_for_insert, direct_output_forward_char): Remove.
15 * cmds.c (nonundocount): Make it static.
16
12010-03-31 Bernhard Herzog <bh@intevation.de> (tiny change) 172010-03-31 Bernhard Herzog <bh@intevation.de> (tiny change)
2 18
3 * menu.c (Fx_popup_menu): Use last_event_timestamp (Bug#4930). 19 * menu.c (Fx_popup_menu): Use last_event_timestamp (Bug#4930).
@@ -9,8 +25,8 @@
9 25
102010-03-31 Adrian Robert <adrian.b.robert@gmail.com> 262010-03-31 Adrian Robert <adrian.b.robert@gmail.com>
11 27
12 * xdisp.c (x_consider_frame_title, update_window_cursor): Remove 28 * xdisp.c (x_consider_frame_title, update_window_cursor):
13 HAVE_NS conditionals. 29 Remove HAVE_NS conditionals.
14 (prepare_menu_bars)[HAVE_NS]: Call ns_set_doc_edited. 30 (prepare_menu_bars)[HAVE_NS]: Call ns_set_doc_edited.
15 31
16 * nsfns.m (x_implicitly_set_name): If frame-title-format is t, use 32 * nsfns.m (x_implicitly_set_name): If frame-title-format is t, use
diff --git a/src/cmds.c b/src/cmds.c
index fd337f378bb..5d450fe9a13 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -317,7 +317,7 @@ N was explicitly specified. */)
317 return value; 317 return value;
318} 318}
319 319
320int nonundocount; 320static int nonundocount;
321 321
322/* Note that there's code in command_loop_1 which typically avoids 322/* Note that there's code in command_loop_1 which typically avoids
323 calling this. */ 323 calling this. */
diff --git a/src/dispextern.h b/src/dispextern.h
index 5083199c529..b8f68ec0e70 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1102,17 +1102,9 @@ extern int cursor_in_echo_area;
1102 1102
1103extern int display_completed; 1103extern int display_completed;
1104 1104
1105/* Non-zero means redisplay has been performed directly (see also
1106 direct_output_for_insert and direct_output_forward_char), so that
1107 no further updating has to be performed. The function
1108 redisplay_internal checks this flag, and does nothing but reset it
1109 to zero if it is non-zero. */
1110
1111extern int redisplay_performed_directly_p;
1112
1113/* A temporary storage area, including a row of glyphs. Initialized 1105/* A temporary storage area, including a row of glyphs. Initialized
1114 in xdisp.c. Used for various purposes, as an example see 1106 in xdisp.c. Used for various purposes, as an example see
1115 direct_output_for_insert. */ 1107 get_overlay_arrow_glyph_row. */
1116 1108
1117extern struct glyph_row scratch_glyph_row; 1109extern struct glyph_row scratch_glyph_row;
1118 1110
@@ -3172,8 +3164,6 @@ extern void redraw_garbaged_frames P_ ((void));
3172extern void cancel_line P_ ((int, struct frame *)); 3164extern void cancel_line P_ ((int, struct frame *));
3173extern void init_desired_glyphs P_ ((struct frame *)); 3165extern void init_desired_glyphs P_ ((struct frame *));
3174extern int scroll_frame_lines P_ ((struct frame *, int, int, int, int)); 3166extern int scroll_frame_lines P_ ((struct frame *, int, int, int, int));
3175extern int direct_output_for_insert P_ ((int));
3176extern int direct_output_forward_char P_ ((int));
3177extern int update_frame P_ ((struct frame *, int, int)); 3167extern int update_frame P_ ((struct frame *, int, int));
3178extern int scrolling P_ ((struct frame *)); 3168extern int scrolling P_ ((struct frame *));
3179extern void bitch_at_user P_ ((void)); 3169extern void bitch_at_user P_ ((void));
@@ -3200,8 +3190,6 @@ void set_window_update_flags P_ ((struct window *, int));
3200void redraw_frame P_ ((struct frame *)); 3190void redraw_frame P_ ((struct frame *));
3201void redraw_garbaged_frames P_ ((void)); 3191void redraw_garbaged_frames P_ ((void));
3202int scroll_cost P_ ((struct frame *, int, int, int)); 3192int scroll_cost P_ ((struct frame *, int, int, int));
3203int direct_output_for_insert P_ ((int));
3204int direct_output_forward_char P_ ((int));
3205int update_frame P_ ((struct frame *, int, int)); 3193int update_frame P_ ((struct frame *, int, int));
3206void update_single_window P_ ((struct window *, int)); 3194void update_single_window P_ ((struct window *, int));
3207int scrolling P_ ((struct frame *)); 3195int scrolling P_ ((struct frame *));
diff --git a/src/dispnew.c b/src/dispnew.c
index fd470491f78..52d7f38728f 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -302,12 +302,6 @@ int updated_area;
302 302
303struct glyph space_glyph; 303struct glyph space_glyph;
304 304
305/* Non-zero means update has been performed directly, so that there's
306 no need for redisplay_internal to do much work. Set by
307 direct_output_for_insert. */
308
309int redisplay_performed_directly_p;
310
311/* Counts of allocated structures. These counts serve to diagnose 305/* Counts of allocated structures. These counts serve to diagnose
312 memory leaks and double frees. */ 306 memory leaks and double frees. */
313 307
@@ -3456,401 +3450,6 @@ redraw_garbaged_frames ()
3456 3450
3457 3451
3458/*********************************************************************** 3452/***********************************************************************
3459 Direct Operations
3460 ***********************************************************************/
3461
3462/* Try to update display and current glyph matrix directly.
3463
3464 This function is called after a character G has been inserted into
3465 current_buffer. It tries to update the current glyph matrix and
3466 perform appropriate screen output to reflect the insertion. If it
3467 succeeds, the global flag redisplay_performed_directly_p will be
3468 set to 1, and thereby prevent the more costly general redisplay
3469 from running (see redisplay_internal).
3470
3471 This function is not called for `hairy' character insertions.
3472 In particular, it is not called when after or before change
3473 functions exist, like they are used by font-lock. See keyboard.c
3474 for details where this function is called. */
3475
3476int
3477direct_output_for_insert (g)
3478 int g;
3479{
3480 register struct frame *f = SELECTED_FRAME ();
3481 struct window *w = XWINDOW (selected_window);
3482 struct it it, it2;
3483 struct glyph_row *glyph_row;
3484 struct glyph *glyphs, *glyph, *end;
3485 int n;
3486 /* Non-null means that redisplay of W is based on window matrices. */
3487 int window_redisplay_p = FRAME_WINDOW_P (f);
3488 /* Non-null means we are in overwrite mode. */
3489 int overwrite_p = !NILP (current_buffer->overwrite_mode);
3490 int added_width;
3491 struct text_pos pos;
3492 int delta, delta_bytes;
3493
3494 /* Not done directly. */
3495 redisplay_performed_directly_p = 0;
3496
3497 /* Quickly give up for some common cases. */
3498 if (cursor_in_echo_area
3499 /* Give up if fonts have changed. */
3500 || fonts_changed_p
3501 /* Give up if face attributes have been changed. */
3502 || face_change_count
3503 /* Give up if cursor position not really known. */
3504 || !display_completed
3505 /* Give up if buffer appears in two places. */
3506 || buffer_shared > 1
3507 /* Give up if we need to reorder bidirectional text. */
3508 || !NILP (current_buffer->bidi_display_reordering)
3509 /* Give up if currently displaying a message instead of the
3510 minibuffer contents. */
3511 || (EQ (selected_window, minibuf_window)
3512 && EQ (minibuf_window, echo_area_window))
3513 /* Give up for hscrolled mini-buffer because display of the prompt
3514 is handled specially there (see display_line). */
3515 || (MINI_WINDOW_P (w) && XFASTINT (w->hscroll))
3516 /* Give up if overwriting in the middle of a line. */
3517 || (overwrite_p
3518 && PT != ZV
3519 && FETCH_BYTE (PT) != '\n')
3520 /* Give up for tabs and line ends. */
3521 || g == '\t'
3522 || g == '\n'
3523 || g == '\r'
3524 || (g == ' ' && !NILP (current_buffer->word_wrap))
3525 /* Give up if unable to display the cursor in the window. */
3526 || w->cursor.vpos < 0
3527 /* Give up if we are showing a message or just cleared the message
3528 because we might need to resize the echo area window. */
3529 || !NILP (echo_area_buffer[0])
3530 || !NILP (echo_area_buffer[1])
3531 || (glyph_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos),
3532 /* Can't do it in a continued line because continuation
3533 lines would change. */
3534 (glyph_row->continued_p
3535 || glyph_row->exact_window_width_line_p
3536 /* Can't use this method if the line overlaps others or is
3537 overlapped by others because these other lines would
3538 have to be redisplayed. */
3539 || glyph_row->overlapping_p
3540 || glyph_row->overlapped_p))
3541 /* Can't do it for partial width windows on terminal frames
3542 because we can't clear to eol in such a window. */
3543 || (!window_redisplay_p && !WINDOW_FULL_WIDTH_P (w)))
3544 return 0;
3545
3546 /* If we can't insert glyphs, we can use this method only
3547 at the end of a line. */
3548 if (!FRAME_CHAR_INS_DEL_OK (f))
3549 if (PT != ZV && FETCH_BYTE (PT_BYTE) != '\n')
3550 return 0;
3551
3552 /* Set up a display iterator structure for W. Glyphs will be
3553 produced in scratch_glyph_row. Current position is W's cursor
3554 position. */
3555 clear_glyph_row (&scratch_glyph_row);
3556 SET_TEXT_POS (pos, PT, PT_BYTE);
3557 DEC_TEXT_POS (pos, !NILP (current_buffer->enable_multibyte_characters));
3558 init_iterator (&it, w, CHARPOS (pos), BYTEPOS (pos), &scratch_glyph_row,
3559 DEFAULT_FACE_ID);
3560
3561 glyph_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
3562 if (glyph_row->mouse_face_p)
3563 return 0;
3564
3565 /* Give up if highlighting trailing whitespace and we have trailing
3566 whitespace in glyph_row. We would have to remove the trailing
3567 whitespace face in that case. */
3568 if (!NILP (Vshow_trailing_whitespace)
3569 && glyph_row->used[TEXT_AREA])
3570 {
3571 struct glyph *last;
3572
3573 last = glyph_row->glyphs[TEXT_AREA] + glyph_row->used[TEXT_AREA] - 1;
3574 if (last->type == STRETCH_GLYPH
3575 || (last->type == CHAR_GLYPH
3576 && last->u.ch == ' '))
3577 return 0;
3578 }
3579
3580 /* Give up if there are overlay strings at pos. This would fail
3581 if the overlay string has newlines in it. */
3582 if (STRINGP (it.string))
3583 return 0;
3584
3585 it.hpos = w->cursor.hpos;
3586 it.vpos = w->cursor.vpos;
3587 it.current_x = w->cursor.x + it.first_visible_x;
3588 it.current_y = w->cursor.y;
3589 it.end_charpos = PT;
3590 it.stop_charpos = min (PT, it.stop_charpos);
3591 it.stop_charpos = max (IT_CHARPOS (it), it.stop_charpos);
3592
3593 /* More than one display element may be returned for PT - 1 if
3594 (i) it's a control character which is translated into `\003' or
3595 `^C', or (ii) it has a display table entry, or (iii) it's a
3596 combination of both. */
3597 delta = delta_bytes = 0;
3598 while (get_next_display_element (&it))
3599 {
3600 PRODUCE_GLYPHS (&it);
3601
3602 /* Give up if glyph doesn't fit completely on the line. */
3603 if (it.current_x >= it.last_visible_x)
3604 return 0;
3605
3606 /* Give up if new glyph has different ascent or descent than
3607 the original row, or if it is not a character glyph. */
3608 if (glyph_row->ascent != it.ascent
3609 || glyph_row->height != it.ascent + it.descent
3610 || glyph_row->phys_ascent != it.phys_ascent
3611 || glyph_row->phys_height != it.phys_ascent + it.phys_descent
3612 || it.what != IT_CHARACTER)
3613 return 0;
3614
3615 delta += 1;
3616 delta_bytes += it.len;
3617 set_iterator_to_next (&it, 1);
3618 }
3619
3620 /* Give up if we hit the right edge of the window. We would have
3621 to insert truncation or continuation glyphs. */
3622 added_width = it.current_x - (w->cursor.x + it.first_visible_x);
3623 if (glyph_row->pixel_width + added_width >= it.last_visible_x)
3624 return 0;
3625
3626 /* Give up if there is a \t following in the line. */
3627 it2 = it;
3628 it2.end_charpos = ZV;
3629 it2.stop_charpos = min (it2.stop_charpos, ZV);
3630 while (get_next_display_element (&it2)
3631 && !ITERATOR_AT_END_OF_LINE_P (&it2))
3632 {
3633 if (it2.c == '\t')
3634 return 0;
3635 set_iterator_to_next (&it2, 1);
3636 }
3637
3638 /* Number of new glyphs produced. */
3639 n = it.glyph_row->used[TEXT_AREA];
3640
3641 /* Start and end of glyphs in original row. */
3642 glyphs = glyph_row->glyphs[TEXT_AREA] + w->cursor.hpos;
3643 end = glyph_row->glyphs[1 + TEXT_AREA];
3644
3645 /* Make room for new glyphs, then insert them. */
3646 xassert (end - glyphs - n >= 0);
3647 safe_bcopy ((char *) glyphs, (char *) (glyphs + n),
3648 (end - glyphs - n) * sizeof (*end));
3649 bcopy (it.glyph_row->glyphs[TEXT_AREA], glyphs, n * sizeof *glyphs);
3650 glyph_row->used[TEXT_AREA] = min (glyph_row->used[TEXT_AREA] + n,
3651 end - glyph_row->glyphs[TEXT_AREA]);
3652
3653 /* Compute new line width. */
3654 glyph = glyph_row->glyphs[TEXT_AREA];
3655 end = glyph + glyph_row->used[TEXT_AREA];
3656 glyph_row->pixel_width = glyph_row->x;
3657 while (glyph < end)
3658 {
3659 glyph_row->pixel_width += glyph->pixel_width;
3660 ++glyph;
3661 }
3662
3663 /* Increment buffer positions for glyphs following the newly
3664 inserted ones. */
3665 for (glyph = glyphs + n; glyph < end; ++glyph)
3666 if (glyph->charpos > 0 && BUFFERP (glyph->object))
3667 glyph->charpos += delta;
3668
3669 if (MATRIX_ROW_END_CHARPOS (glyph_row) > 0)
3670 {
3671 MATRIX_ROW_END_CHARPOS (glyph_row) += delta;
3672 MATRIX_ROW_END_BYTEPOS (glyph_row) += delta_bytes;
3673 }
3674
3675 /* Adjust positions in lines following the one we are in. */
3676 increment_matrix_positions (w->current_matrix,
3677 w->cursor.vpos + 1,
3678 w->current_matrix->nrows,
3679 delta, delta_bytes);
3680
3681 glyph_row->contains_overlapping_glyphs_p
3682 |= it.glyph_row->contains_overlapping_glyphs_p;
3683
3684 glyph_row->displays_text_p = 1;
3685 w->window_end_vpos = make_number (max (w->cursor.vpos,
3686 XFASTINT (w->window_end_vpos)));
3687
3688 if (!NILP (Vshow_trailing_whitespace))
3689 highlight_trailing_whitespace (it.f, glyph_row);
3690
3691 /* Write glyphs. If at end of row, we can simply call write_glyphs.
3692 In the middle, we have to insert glyphs. Note that this is now
3693 implemented for X frames. The implementation uses updated_window
3694 and updated_row. */
3695 updated_row = glyph_row;
3696 updated_area = TEXT_AREA;
3697 update_begin (f);
3698 if (FRAME_RIF (f))
3699 {
3700 FRAME_RIF (f)->update_window_begin_hook (w);
3701
3702 if (glyphs == end - n
3703 /* In front of a space added by append_space. */
3704 || (glyphs == end - n - 1
3705 && (end - n)->charpos <= 0))
3706 FRAME_RIF (f)->write_glyphs (glyphs, n);
3707 else
3708 FRAME_RIF (f)->insert_glyphs (glyphs, n);
3709 }
3710 else
3711 {
3712 if (glyphs == end - n)
3713 write_glyphs (f, glyphs, n);
3714 else
3715 insert_glyphs (f, glyphs, n);
3716 }
3717
3718 w->cursor.hpos += n;
3719 w->cursor.x = it.current_x - it.first_visible_x;
3720 xassert (w->cursor.hpos >= 0
3721 && w->cursor.hpos < w->desired_matrix->matrix_w);
3722
3723 /* How to set the cursor differs depending on whether we are
3724 using a frame matrix or a window matrix. Note that when
3725 a frame matrix is used, cursor_to expects frame coordinates,
3726 and the X and Y parameters are not used. */
3727 if (window_redisplay_p)
3728 FRAME_RIF (f)->cursor_to (w->cursor.vpos, w->cursor.hpos,
3729 w->cursor.y, w->cursor.x);
3730 else
3731 {
3732 int x, y;
3733 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos)
3734 + (INTEGERP (w->left_margin_cols)
3735 ? XFASTINT (w->left_margin_cols)
3736 : 0));
3737 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
3738 cursor_to (f, y, x);
3739 }
3740
3741#ifdef HAVE_WINDOW_SYSTEM
3742 update_window_fringes (w, 0);
3743#endif
3744
3745 if (FRAME_RIF (f))
3746 FRAME_RIF (f)->update_window_end_hook (w, 1, 0);
3747 update_end (f);
3748 updated_row = NULL;
3749 if (FRAME_TERMCAP_P (f))
3750 fflush (FRAME_TTY (f)->output);
3751
3752 TRACE ((stderr, "direct output for insert\n"));
3753 mark_window_display_accurate (it.window, 1);
3754 redisplay_performed_directly_p = 1;
3755 return 1;
3756}
3757
3758
3759/* Perform a direct display update for moving PT by N positions
3760 left or right. N < 0 means a movement backwards. This function
3761 is currently only called for N == 1 or N == -1. */
3762
3763int
3764direct_output_forward_char (n)
3765 int n;
3766{
3767 struct frame *f = SELECTED_FRAME ();
3768 struct window *w = XWINDOW (selected_window);
3769 struct glyph_row *row;
3770
3771 /* Give up if point moved out of or into a composition. */
3772 if (check_point_in_composition (current_buffer, XINT (w->last_point),
3773 current_buffer, PT))
3774 return 0;
3775
3776 /* Give up if face attributes have been changed. */
3777 if (face_change_count)
3778 return 0;
3779
3780 /* Give up if current matrix is not up to date or we are
3781 displaying a message. */
3782 if (!display_completed || cursor_in_echo_area)
3783 return 0;
3784
3785 /* Give up if we need to reorder bidirectional text. */
3786 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
3787 return 0;
3788
3789 /* Give up if the buffer's direction is reversed. */
3790 if (!NILP (XBUFFER (w->buffer)->direction_reversed))
3791 return 0;
3792
3793 /* Can't use direct output if highlighting a region. */
3794 if (!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active))
3795 return 0;
3796
3797 /* Can't use direct output if highlighting trailing whitespace. */
3798 if (!NILP (Vshow_trailing_whitespace))
3799 return 0;
3800
3801 /* Give up if we are showing a message or just cleared the message
3802 because we might need to resize the echo area window. */
3803 if (!NILP (echo_area_buffer[0]) || !NILP (echo_area_buffer[1]))
3804 return 0;
3805
3806 /* Give up if currently displaying a message instead of the
3807 minibuffer contents. */
3808 if (XWINDOW (minibuf_window) == w
3809 && EQ (minibuf_window, echo_area_window))
3810 return 0;
3811
3812 /* Give up if we don't know where the cursor is. */
3813 if (w->cursor.vpos < 0)
3814 return 0;
3815
3816 row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
3817
3818 /* Give up if PT is outside of the last known cursor row. */
3819 if (PT <= MATRIX_ROW_START_CHARPOS (row)
3820 || PT >= MATRIX_ROW_END_CHARPOS (row))
3821 return 0;
3822
3823 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
3824
3825 w->last_cursor = w->cursor;
3826 XSETFASTINT (w->last_point, PT);
3827
3828 xassert (w->cursor.hpos >= 0
3829 && w->cursor.hpos < w->desired_matrix->matrix_w);
3830
3831 if (FRAME_WINDOW_P (f))
3832 FRAME_RIF (f)->cursor_to (w->cursor.vpos, w->cursor.hpos,
3833 w->cursor.y, w->cursor.x);
3834 else
3835 {
3836 int x, y;
3837 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos)
3838 + (INTEGERP (w->left_margin_cols)
3839 ? XFASTINT (w->left_margin_cols)
3840 : 0));
3841 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
3842 cursor_to (f, y, x);
3843 }
3844
3845 if (FRAME_TERMCAP_P (f))
3846 fflush (FRAME_TTY (f)->output);
3847 redisplay_performed_directly_p = 1;
3848 return 1;
3849}
3850
3851
3852
3853/***********************************************************************
3854 Frame Update 3453 Frame Update
3855 ***********************************************************************/ 3454 ***********************************************************************/
3856 3455
diff --git a/src/keyboard.c b/src/keyboard.c
index f6d6704b373..3cd042fb21e 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1520,8 +1520,6 @@ cancel_hourglass_unwind (arg)
1520} 1520}
1521#endif 1521#endif
1522 1522
1523extern int nonundocount; /* Declared in cmds.c. */
1524
1525Lisp_Object 1523Lisp_Object
1526command_loop_1 () 1524command_loop_1 ()
1527{ 1525{
@@ -1744,149 +1742,8 @@ command_loop_1 ()
1744 } 1742 }
1745 else 1743 else
1746 { 1744 {
1747 if (NILP (current_kboard->Vprefix_arg))
1748 {
1749 /* In case we jump to directly_done. */
1750 Vcurrent_prefix_arg = current_kboard->Vprefix_arg;
1751
1752 /* Recognize some common commands in common situations and
1753 do them directly. */
1754 if (EQ (Vthis_command, Qforward_char) && PT < ZV
1755 && NILP (Vthis_command_keys_shift_translated)
1756 && !CONSP (Vtransient_mark_mode))
1757 {
1758 struct Lisp_Char_Table *dp
1759 = window_display_table (XWINDOW (selected_window));
1760 lose = FETCH_CHAR (PT_BYTE);
1761 SET_PT (PT + 1);
1762 if (! NILP (Vpost_command_hook))
1763 /* Put this before calling adjust_point_for_property
1764 so it will only get called once in any case. */
1765 goto directly_done;
1766 if (current_buffer == prev_buffer
1767 && last_point_position != PT
1768 && NILP (Vdisable_point_adjustment)
1769 && NILP (Vglobal_disable_point_adjustment))
1770 adjust_point_for_property (last_point_position, 0);
1771 already_adjusted = 1;
1772 if (PT == last_point_position + 1
1773 && (dp
1774 ? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
1775 ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
1776 : (NILP (DISP_CHAR_VECTOR (dp, lose))
1777 && (lose >= 0x20 && lose < 0x7f)))
1778 : (lose >= 0x20 && lose < 0x7f))
1779 /* To extract the case of continuation on
1780 wide-column characters. */
1781 && ASCII_BYTE_P (lose)
1782 && (XFASTINT (XWINDOW (selected_window)->last_modified)
1783 >= MODIFF)
1784 && (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
1785 >= OVERLAY_MODIFF)
1786 && (XFASTINT (XWINDOW (selected_window)->last_point)
1787 == PT - 1)
1788 && !windows_or_buffers_changed
1789 && EQ (current_buffer->selective_display, Qnil)
1790 && !detect_input_pending ()
1791 && NILP (XWINDOW (selected_window)->column_number_displayed)
1792 && NILP (Vexecuting_kbd_macro))
1793 direct_output_forward_char (1);
1794 goto directly_done;
1795 }
1796 else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV
1797 && NILP (Vthis_command_keys_shift_translated)
1798 && !CONSP (Vtransient_mark_mode))
1799 {
1800 struct Lisp_Char_Table *dp
1801 = window_display_table (XWINDOW (selected_window));
1802 SET_PT (PT - 1);
1803 lose = FETCH_CHAR (PT_BYTE);
1804 if (! NILP (Vpost_command_hook))
1805 goto directly_done;
1806 if (current_buffer == prev_buffer
1807 && last_point_position != PT
1808 && NILP (Vdisable_point_adjustment)
1809 && NILP (Vglobal_disable_point_adjustment))
1810 adjust_point_for_property (last_point_position, 0);
1811 already_adjusted = 1;
1812 if (PT == last_point_position - 1
1813 && (dp
1814 ? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
1815 ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
1816 : (NILP (DISP_CHAR_VECTOR (dp, lose))
1817 && (lose >= 0x20 && lose < 0x7f)))
1818 : (lose >= 0x20 && lose < 0x7f))
1819 && (XFASTINT (XWINDOW (selected_window)->last_modified)
1820 >= MODIFF)
1821 && (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
1822 >= OVERLAY_MODIFF)
1823 && (XFASTINT (XWINDOW (selected_window)->last_point)
1824 == PT + 1)
1825 && !windows_or_buffers_changed
1826 && EQ (current_buffer->selective_display, Qnil)
1827 && !detect_input_pending ()
1828 && NILP (XWINDOW (selected_window)->column_number_displayed)
1829 && NILP (Vexecuting_kbd_macro))
1830 direct_output_forward_char (-1);
1831 goto directly_done;
1832 }
1833 else if (EQ (Vthis_command, Qself_insert_command)
1834 /* Try this optimization only on char keystrokes. */
1835 && NATNUMP (last_command_event)
1836 && CHAR_VALID_P (XFASTINT (last_command_event), 0))
1837 {
1838 unsigned int c
1839 = translate_char (Vtranslation_table_for_input,
1840 XFASTINT (last_command_event));
1841 int value;
1842 if (NILP (Vexecuting_kbd_macro)
1843 && !EQ (minibuf_window, selected_window))
1844 {
1845 if (!nonundocount || nonundocount >= 20)
1846 {
1847 Fundo_boundary ();
1848 nonundocount = 0;
1849 }
1850 nonundocount++;
1851 }
1852
1853 lose = ((XFASTINT (XWINDOW (selected_window)->last_modified)
1854 < MODIFF)
1855 || (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
1856 < OVERLAY_MODIFF)
1857 || (XFASTINT (XWINDOW (selected_window)->last_point)
1858 != PT)
1859 || MODIFF <= SAVE_MODIFF
1860 || windows_or_buffers_changed
1861 || !EQ (current_buffer->selective_display, Qnil)
1862 || detect_input_pending ()
1863 || !NILP (XWINDOW (selected_window)->column_number_displayed)
1864 || !NILP (Vexecuting_kbd_macro));
1865
1866 value = internal_self_insert (c, 0);
1867
1868 if (value == 2)
1869 nonundocount = 0;
1870
1871 frame_make_pointer_invisible ();
1872
1873 if (! NILP (Vpost_command_hook))
1874 /* Put this before calling adjust_point_for_property
1875 so it will only get called once in any case. */
1876 goto directly_done;
1877
1878 /* VALUE == 1 when AFTER-CHANGE functions are
1879 installed which is the case most of the time
1880 because FONT-LOCK installs one. */
1881 if (!lose && !value)
1882 direct_output_for_insert (c);
1883 goto directly_done;
1884 }
1885 }
1886
1887 /* Here for a command that isn't executed directly */ 1745 /* Here for a command that isn't executed directly */
1888 1746
1889 {
1890#ifdef HAVE_WINDOW_SYSTEM 1747#ifdef HAVE_WINDOW_SYSTEM
1891 int scount = SPECPDL_INDEX (); 1748 int scount = SPECPDL_INDEX ();
1892 1749
@@ -1898,7 +1755,6 @@ command_loop_1 ()
1898 } 1755 }
1899#endif 1756#endif
1900 1757
1901 nonundocount = 0;
1902 if (NILP (current_kboard->Vprefix_arg)) /* FIXME: Why? --Stef */ 1758 if (NILP (current_kboard->Vprefix_arg)) /* FIXME: Why? --Stef */
1903 Fundo_boundary (); 1759 Fundo_boundary ();
1904 Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil); 1760 Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil);
@@ -1913,8 +1769,6 @@ command_loop_1 ()
1913 unbind_to (scount, Qnil); 1769 unbind_to (scount, Qnil);
1914#endif 1770#endif
1915 } 1771 }
1916 }
1917 directly_done: ;
1918 current_kboard->Vlast_prefix_arg = Vcurrent_prefix_arg; 1772 current_kboard->Vlast_prefix_arg = Vcurrent_prefix_arg;
1919 1773
1920 /* Note that the value cell will never directly contain nil 1774 /* Note that the value cell will never directly contain nil
diff --git a/src/sysdep.c b/src/sysdep.c
index 2f79a711cfd..73209b03c08 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1401,9 +1401,8 @@ init_sys_modes (tty_out)
1401 1401
1402 if (tty_out->term_initted && no_redraw_on_reenter) 1402 if (tty_out->term_initted && no_redraw_on_reenter)
1403 { 1403 {
1404 /* XXX This seems wrong on multi-tty. */ 1404 /* We used to call "direct_output_forward_char(0)" here,
1405 if (display_completed) 1405 but it's not clear why, since it may not do anything anyway. */
1406 direct_output_forward_char (0);
1407 } 1406 }
1408 else 1407 else
1409 { 1408 {
diff --git a/src/xdisp.c b/src/xdisp.c
index b6c69f661ed..b3aaa52e2e5 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -32,9 +32,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32 decides it's time to do it. This is done either automatically for 32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of 33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay' 34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code. (Or, 35 in xdisp.c is the only entry into the inner redisplay code.
36 let's say almost---see the description of direct update
37 operations, below.)
38 36
39 The following diagram shows how redisplay code is invoked. As you 37 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems 38 can see, Lisp calls redisplay and vice versa. Under window systems
@@ -46,12 +44,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
46 change the interpreter's state. If you don't follow these rules, 44 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain. 45 you will encounter bugs which are very hard to explain.
48 46
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
53 | |
54 | V
55 +--------------+ redisplay +----------------+ 47 +--------------+ redisplay +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+ 48 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ | 49 +--------------+ (xdisp.c) +----------------+ |
@@ -85,28 +77,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
85 then compared to find a cheap way to update the display, e.g. by 77 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines. 78 reusing part of the display by scrolling lines.
87 79
88
89 Direct operations.
90
91 You will find a lot of redisplay optimizations when you start 80 You will find a lot of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these 81 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done 82 optimizations is to make redisplay fast because it is done
94 frequently. 83 frequently.
95 84
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
101 the current matrix.
102
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
107 dispnew.c.
108
109
110 Desired matrices. 85 Desired matrices.
111 86
112 Desired matrices are always built per Emacs window. The function 87 Desired matrices are always built per Emacs window. The function
@@ -11618,16 +11593,6 @@ redisplay_internal (preserve_echo_area)
11618 if (!f->glyphs_initialized_p) 11593 if (!f->glyphs_initialized_p)
11619 return; 11594 return;
11620 11595
11621 /* The flag redisplay_performed_directly_p is set by
11622 direct_output_for_insert when it already did the whole screen
11623 update necessary. */
11624 if (redisplay_performed_directly_p)
11625 {
11626 redisplay_performed_directly_p = 0;
11627 if (!hscroll_windows (selected_window))
11628 return;
11629 }
11630
11631#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) 11596#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
11632 if (popup_activated ()) 11597 if (popup_activated ())
11633 return; 11598 return;