diff options
| author | Stefan Monnier | 2010-03-31 00:14:08 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2010-03-31 00:14:08 -0400 |
| commit | 855a0da7fdb9c33761d7ba3ad6ab66a41bc2d1f3 (patch) | |
| tree | 7e136862fdaf8e885e1706be53e92914c8f27a0b /src | |
| parent | dcf7843e7e1a857c21e39c2a5e53d27039a34a3a (diff) | |
| download | emacs-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/ChangeLog | 20 | ||||
| -rw-r--r-- | src/cmds.c | 2 | ||||
| -rw-r--r-- | src/dispextern.h | 14 | ||||
| -rw-r--r-- | src/dispnew.c | 401 | ||||
| -rw-r--r-- | src/keyboard.c | 146 | ||||
| -rw-r--r-- | src/sysdep.c | 5 | ||||
| -rw-r--r-- | src/xdisp.c | 37 |
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 @@ | |||
| 1 | 2010-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 | |||
| 1 | 2010-03-31 Bernhard Herzog <bh@intevation.de> (tiny change) | 17 | 2010-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 | ||
| 10 | 2010-03-31 Adrian Robert <adrian.b.robert@gmail.com> | 26 | 2010-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 | ||
| 320 | int nonundocount; | 320 | static 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 | ||
| 1103 | extern int display_completed; | 1103 | extern 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 | |||
| 1111 | extern 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 | ||
| 1117 | extern struct glyph_row scratch_glyph_row; | 1109 | extern struct glyph_row scratch_glyph_row; |
| 1118 | 1110 | ||
| @@ -3172,8 +3164,6 @@ extern void redraw_garbaged_frames P_ ((void)); | |||
| 3172 | extern void cancel_line P_ ((int, struct frame *)); | 3164 | extern void cancel_line P_ ((int, struct frame *)); |
| 3173 | extern void init_desired_glyphs P_ ((struct frame *)); | 3165 | extern void init_desired_glyphs P_ ((struct frame *)); |
| 3174 | extern int scroll_frame_lines P_ ((struct frame *, int, int, int, int)); | 3166 | extern int scroll_frame_lines P_ ((struct frame *, int, int, int, int)); |
| 3175 | extern int direct_output_for_insert P_ ((int)); | ||
| 3176 | extern int direct_output_forward_char P_ ((int)); | ||
| 3177 | extern int update_frame P_ ((struct frame *, int, int)); | 3167 | extern int update_frame P_ ((struct frame *, int, int)); |
| 3178 | extern int scrolling P_ ((struct frame *)); | 3168 | extern int scrolling P_ ((struct frame *)); |
| 3179 | extern void bitch_at_user P_ ((void)); | 3169 | extern void bitch_at_user P_ ((void)); |
| @@ -3200,8 +3190,6 @@ void set_window_update_flags P_ ((struct window *, int)); | |||
| 3200 | void redraw_frame P_ ((struct frame *)); | 3190 | void redraw_frame P_ ((struct frame *)); |
| 3201 | void redraw_garbaged_frames P_ ((void)); | 3191 | void redraw_garbaged_frames P_ ((void)); |
| 3202 | int scroll_cost P_ ((struct frame *, int, int, int)); | 3192 | int scroll_cost P_ ((struct frame *, int, int, int)); |
| 3203 | int direct_output_for_insert P_ ((int)); | ||
| 3204 | int direct_output_forward_char P_ ((int)); | ||
| 3205 | int update_frame P_ ((struct frame *, int, int)); | 3193 | int update_frame P_ ((struct frame *, int, int)); |
| 3206 | void update_single_window P_ ((struct window *, int)); | 3194 | void update_single_window P_ ((struct window *, int)); |
| 3207 | int scrolling P_ ((struct frame *)); | 3195 | int 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 | ||
| 303 | struct glyph space_glyph; | 303 | struct 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 | |||
| 309 | int 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 | |||
| 3476 | int | ||
| 3477 | direct_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 | |||
| 3763 | int | ||
| 3764 | direct_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 | ||
| 1523 | extern int nonundocount; /* Declared in cmds.c. */ | ||
| 1524 | |||
| 1525 | Lisp_Object | 1523 | Lisp_Object |
| 1526 | command_loop_1 () | 1524 | command_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; |