diff options
| author | Gerd Moellmann | 1999-08-21 19:30:44 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 1999-08-21 19:30:44 +0000 |
| commit | c6e89d6c44fe6736f31724b07e07fccb3bfaa09d (patch) | |
| tree | f5528d7fabe34fc5819162273a06e1b39ec6b23b | |
| parent | 4da43475454611843f75dbcf604250f8565404e0 (diff) | |
| download | emacs-c6e89d6c44fe6736f31724b07e07fccb3bfaa09d.tar.gz emacs-c6e89d6c44fe6736f31724b07e07fccb3bfaa09d.zip | |
Call change_frame_size and do_pending_window_change with
new parameter.
Remove conditional compilation on
NO_PROMPT_IN_BUFFER.
(get_next_display_element): Display \r as ^M.
(minibuffer_scroll_overlap): Removed because not used
anywhere.
(unwind_redisplay): Return nil.
(clear_garbaged_frames): New.
(redisplay_internal): Use it.
(echo_area_display): Ditto.
(resize_mini_window): Mew.
(display_echo_area_1): Use it to resize echo area window.
(redisplay_internal): Use it to resize active mini-window.
(echo_area_glyphs, echo_area_message,
echo_area_glyphs_length, previous_echo_glyphs,
previous_echo_area_message, previous_echo_area_glyphs_length):
Removed.
(Vmessage_stack, echo_area_buffer, echo_buffer,
display_last_displayed_message_p, Vwith_echo_area_save_vector): New.
(message2_nolog): Use set_message and clear_message.
(message3): Rename parameter len to nbytes to make clear what
it is.
(message3_nolog): Ditto. Use set_message and clear_message.
(update_echo_area): Rewritten.
(with_echo_area_buffer): New.
(with_echo_area_buffer_unwind_data, unwind_with_area_buffer): New.
(setup_echo_area_for_printing): New.
(display_echo_area, display_echo_area_1): New.
(current_message, current_message_1): New.
(push_message, restore_message, pop_message,
check_message_stack): New.
(truncate_echo_area): Rewritten.
(truncate_message_1): New.
(set_message, set_message_1, clear_message): New.
(echo_area_display): Rewritten.
(redisplay_internal): Check for needed echo area update
differently.
(redisplay_preserve_echo_area): Rewritten.
(redisplay_window): Check for mini-window displaying echo area
message differently.
(syms_of_xdisp): Initialize Vmessage_stack and echo area buffers.
Remove initialzation of removed variables.
(init_xdisp): Remove references to removed variables.
| -rw-r--r-- | src/xdisp.c | 1078 |
1 files changed, 775 insertions, 303 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 5cdb732e5f3..506af36dea4 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -381,11 +381,6 @@ static int scroll_conservatively; | |||
| 381 | 381 | ||
| 382 | int scroll_margin; | 382 | int scroll_margin; |
| 383 | 383 | ||
| 384 | /* Number of characters of overlap to show, when scrolling a one-line | ||
| 385 | window such as a minibuffer. */ | ||
| 386 | |||
| 387 | static int minibuffer_scroll_overlap; | ||
| 388 | |||
| 389 | /* Number of windows showing the buffer of the selected window (or | 384 | /* Number of windows showing the buffer of the selected window (or |
| 390 | another buffer with the same base buffer). keyboard.c refers to | 385 | another buffer with the same base buffer). keyboard.c refers to |
| 391 | this. */ | 386 | this. */ |
| @@ -410,37 +405,19 @@ Lisp_Object minibuf_prompt; | |||
| 410 | int minibuf_prompt_width; | 405 | int minibuf_prompt_width; |
| 411 | int minibuf_prompt_pixel_width; | 406 | int minibuf_prompt_pixel_width; |
| 412 | 407 | ||
| 413 | /* Message to display instead of mini-buffer contents. This is what | ||
| 414 | the functions error and message make, and command echoing uses it | ||
| 415 | as well. It overrides the minibuf_prompt as well as the buffer. */ | ||
| 416 | |||
| 417 | char *echo_area_glyphs; | ||
| 418 | |||
| 419 | /* A Lisp string to display instead of mini-buffer contents, analogous | ||
| 420 | to echo_area_glyphs. If this is a string, display that string. | ||
| 421 | Otherwise, if echo_area_glyphs is non-null, display that. */ | ||
| 422 | |||
| 423 | Lisp_Object echo_area_message; | ||
| 424 | |||
| 425 | /* This is the length of the message in echo_area_glyphs or | ||
| 426 | echo_area_message. */ | ||
| 427 | |||
| 428 | int echo_area_glyphs_length; | ||
| 429 | |||
| 430 | /* Value of echo_area_glyphs when it was last acted on. If this is | ||
| 431 | nonzero, there is a message on the frame in the mini-buffer and it | ||
| 432 | should be erased as soon as it is no longer requested to appear. */ | ||
| 433 | |||
| 434 | char *previous_echo_glyphs; | ||
| 435 | Lisp_Object previous_echo_area_message; | ||
| 436 | static int previous_echo_glyphs_length; | ||
| 437 | |||
| 438 | /* This is the window where the echo area message was displayed. It | 408 | /* This is the window where the echo area message was displayed. It |
| 439 | is always a mini-buffer window, but it may not be the same window | 409 | is always a mini-buffer window, but it may not be the same window |
| 440 | currently active as a mini-buffer. */ | 410 | currently active as a mini-buffer. */ |
| 441 | 411 | ||
| 442 | Lisp_Object echo_area_window; | 412 | Lisp_Object echo_area_window; |
| 443 | 413 | ||
| 414 | /* List of pairs (MESSAGE . MULTIBYTE). The function save_message | ||
| 415 | pushes the current message and the value of | ||
| 416 | message_enable_multibyte on the stack, the function restore_message | ||
| 417 | pops the stack and displays MESSAGE again. */ | ||
| 418 | |||
| 419 | Lisp_Object Vmessage_stack; | ||
| 420 | |||
| 444 | /* Nonzero means multibyte characters were enabled when the echo area | 421 | /* Nonzero means multibyte characters were enabled when the echo area |
| 445 | message was specified. */ | 422 | message was specified. */ |
| 446 | 423 | ||
| @@ -495,6 +472,33 @@ static int line_number_display_limit_width; | |||
| 495 | 472 | ||
| 496 | Lisp_Object Vmessage_log_max; | 473 | Lisp_Object Vmessage_log_max; |
| 497 | 474 | ||
| 475 | /* Current, index 0, and last displayed echo area message. Either | ||
| 476 | buffers from echo_buffers, or nil to indicate no message. */ | ||
| 477 | |||
| 478 | Lisp_Object echo_area_buffer[2]; | ||
| 479 | |||
| 480 | /* The buffers referenced from echo_area_buffer. */ | ||
| 481 | |||
| 482 | static Lisp_Object echo_buffer[2]; | ||
| 483 | |||
| 484 | /* A vector saved used in with_area_buffer to reduce consing. */ | ||
| 485 | |||
| 486 | static Lisp_Object Vwith_echo_area_save_vector; | ||
| 487 | |||
| 488 | /* Non-zero means display_echo_area should display the last echo area | ||
| 489 | message again. Set by redisplay_preserve_echo_area. */ | ||
| 490 | |||
| 491 | static int display_last_displayed_message_p; | ||
| 492 | |||
| 493 | /* Nonzero if echo area is being used by print; zero if being used by | ||
| 494 | message. */ | ||
| 495 | |||
| 496 | int message_buf_print; | ||
| 497 | |||
| 498 | /* Maximum height for resizing mini-windows. */ | ||
| 499 | |||
| 500 | static Lisp_Object Vmax_mini_window_height; | ||
| 501 | |||
| 498 | /* A scratch glyph row with contents used for generating truncation | 502 | /* A scratch glyph row with contents used for generating truncation |
| 499 | glyphs. Also used in direct_output_for_insert. */ | 503 | glyphs. Also used in direct_output_for_insert. */ |
| 500 | 504 | ||
| @@ -600,6 +604,15 @@ enum move_it_result | |||
| 600 | 604 | ||
| 601 | /* Function prototypes. */ | 605 | /* Function prototypes. */ |
| 602 | 606 | ||
| 607 | static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object)); | ||
| 608 | static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *)); | ||
| 609 | static int resize_mini_window P_ ((struct window *)); | ||
| 610 | static void clear_garbaged_frames P_ ((void)); | ||
| 611 | static int current_message_1 P_ ((Lisp_Object *)); | ||
| 612 | static int truncate_message_1 P_ ((int)); | ||
| 613 | static int set_message_1 P_ ((char *s, Lisp_Object, int, int)); | ||
| 614 | static int display_echo_area P_ ((struct window *)); | ||
| 615 | static int display_echo_area_1 P_ ((struct window *)); | ||
| 603 | static Lisp_Object unwind_redisplay P_ ((Lisp_Object)); | 616 | static Lisp_Object unwind_redisplay P_ ((Lisp_Object)); |
| 604 | static int string_char_and_length P_ ((unsigned char *, int, int *)); | 617 | static int string_char_and_length P_ ((unsigned char *, int, int *)); |
| 605 | static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object, | 618 | static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object, |
| @@ -621,7 +634,7 @@ static void push_it P_ ((struct it *)); | |||
| 621 | static void pop_it P_ ((struct it *)); | 634 | static void pop_it P_ ((struct it *)); |
| 622 | static void sync_frame_with_window_matrix_rows P_ ((struct window *)); | 635 | static void sync_frame_with_window_matrix_rows P_ ((struct window *)); |
| 623 | static void redisplay_internal P_ ((int)); | 636 | static void redisplay_internal P_ ((int)); |
| 624 | static void echo_area_display P_ ((int)); | 637 | static int echo_area_display P_ ((int)); |
| 625 | static void redisplay_windows P_ ((Lisp_Object)); | 638 | static void redisplay_windows P_ ((Lisp_Object)); |
| 626 | static void redisplay_window P_ ((Lisp_Object, int)); | 639 | static void redisplay_window P_ ((Lisp_Object, int)); |
| 627 | static void update_menu_bar P_ ((struct frame *, int)); | 640 | static void update_menu_bar P_ ((struct frame *, int)); |
| @@ -1180,11 +1193,9 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id) | |||
| 1180 | enum face_id base_face_id; | 1193 | enum face_id base_face_id; |
| 1181 | { | 1194 | { |
| 1182 | int highlight_region_p; | 1195 | int highlight_region_p; |
| 1183 | Lisp_Object value; | ||
| 1184 | 1196 | ||
| 1185 | /* Some precondition checks. */ | 1197 | /* Some precondition checks. */ |
| 1186 | xassert (w != NULL && it != NULL); | 1198 | xassert (w != NULL && it != NULL); |
| 1187 | xassert (charpos < 0 || current_buffer == XBUFFER (w->buffer)); | ||
| 1188 | xassert (charpos < 0 || (charpos > 0 && charpos <= ZV)); | 1199 | xassert (charpos < 0 || (charpos > 0 && charpos <= ZV)); |
| 1189 | 1200 | ||
| 1190 | /* If face attributes have been changed since the last redisplay, | 1201 | /* If face attributes have been changed since the last redisplay, |
| @@ -1429,16 +1440,6 @@ start_display (it, w, pos) | |||
| 1429 | if (!start_at_line_beg_p) | 1440 | if (!start_at_line_beg_p) |
| 1430 | reseat_at_previous_visible_line_start (it); | 1441 | reseat_at_previous_visible_line_start (it); |
| 1431 | 1442 | ||
| 1432 | #if NO_PROMPT_IN_BUFFER | ||
| 1433 | /* Take the mini-buffer prompt width into account for tab | ||
| 1434 | calculations. */ | ||
| 1435 | if (MINI_WINDOW_P (w) && IT_CHARPOS (*it) == BEGV) | ||
| 1436 | { | ||
| 1437 | /* Why is mini-buffer_prompt_width guaranteed to be set here? */ | ||
| 1438 | it->prompt_width = minibuf_prompt_pixel_width; | ||
| 1439 | } | ||
| 1440 | #endif /* NO_PROMPT_IN_BUFFER */ | ||
| 1441 | |||
| 1442 | /* If window start is not at a line start, skip forward to POS to | 1443 | /* If window start is not at a line start, skip forward to POS to |
| 1443 | get the correct continuation_lines_width and current_x. */ | 1444 | get the correct continuation_lines_width and current_x. */ |
| 1444 | if (!start_at_line_beg_p) | 1445 | if (!start_at_line_beg_p) |
| @@ -3318,9 +3319,7 @@ get_next_display_element (it) | |||
| 3318 | don't believe that it is worth doing. */ | 3319 | don't believe that it is worth doing. */ |
| 3319 | else if ((it->c < ' ' | 3320 | else if ((it->c < ' ' |
| 3320 | && (it->area != TEXT_AREA | 3321 | && (it->area != TEXT_AREA |
| 3321 | || (it->c != '\n' | 3322 | || (it->c != '\n' && it->c != '\t'))) |
| 3322 | && it->c != '\t' | ||
| 3323 | && it->c != '\r'))) | ||
| 3324 | || (it->c >= 127 | 3323 | || (it->c >= 127 |
| 3325 | && it->len == 1)) | 3324 | && it->len == 1)) |
| 3326 | { | 3325 | { |
| @@ -3461,8 +3460,6 @@ set_iterator_to_next (it) | |||
| 3461 | Advance in the display table definition. Reset it to null if | 3460 | Advance in the display table definition. Reset it to null if |
| 3462 | end reached, and continue with characters from buffers/ | 3461 | end reached, and continue with characters from buffers/ |
| 3463 | strings. */ | 3462 | strings. */ |
| 3464 | struct face *face; | ||
| 3465 | |||
| 3466 | ++it->current.dpvec_index; | 3463 | ++it->current.dpvec_index; |
| 3467 | 3464 | ||
| 3468 | /* Restore face and charset of the iterator to what they were | 3465 | /* Restore face and charset of the iterator to what they were |
| @@ -3998,16 +3995,6 @@ move_it_in_display_line_to (it, to_charpos, to_x, op) | |||
| 3998 | saved_glyph_row = it->glyph_row; | 3995 | saved_glyph_row = it->glyph_row; |
| 3999 | it->glyph_row = NULL; | 3996 | it->glyph_row = NULL; |
| 4000 | 3997 | ||
| 4001 | #if NO_PROMPT_IN_BUFFER | ||
| 4002 | /* Take a mini-buffer prompt into account. */ | ||
| 4003 | if (MINI_WINDOW_P (it->w) | ||
| 4004 | && IT_CHARPOS (*it) == BEGV) | ||
| 4005 | { | ||
| 4006 | it->current_x = minibuf_prompt_pixel_width; | ||
| 4007 | it->hpos = minibuf_prompt_width; | ||
| 4008 | } | ||
| 4009 | #endif | ||
| 4010 | |||
| 4011 | while (1) | 3998 | while (1) |
| 4012 | { | 3999 | { |
| 4013 | int x, i; | 4000 | int x, i; |
| @@ -4169,8 +4156,6 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op) | |||
| 4169 | enum move_it_result skip, skip2 = MOVE_X_REACHED; | 4156 | enum move_it_result skip, skip2 = MOVE_X_REACHED; |
| 4170 | int line_height; | 4157 | int line_height; |
| 4171 | 4158 | ||
| 4172 | xassert (XBUFFER (it->w->buffer) == current_buffer); | ||
| 4173 | |||
| 4174 | while (1) | 4159 | while (1) |
| 4175 | { | 4160 | { |
| 4176 | if (op & MOVE_TO_VPOS) | 4161 | if (op & MOVE_TO_VPOS) |
| @@ -4867,37 +4852,31 @@ message2_nolog (m, len, multibyte) | |||
| 4867 | 4852 | ||
| 4868 | if (m) | 4853 | if (m) |
| 4869 | { | 4854 | { |
| 4870 | echo_area_glyphs = m; | 4855 | set_message (m, Qnil, len, multibyte); |
| 4871 | echo_area_glyphs_length = len; | ||
| 4872 | echo_area_message = Qnil; | ||
| 4873 | |||
| 4874 | if (minibuffer_auto_raise) | 4856 | if (minibuffer_auto_raise) |
| 4875 | Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window))); | 4857 | Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window))); |
| 4876 | } | 4858 | } |
| 4877 | else | 4859 | else |
| 4878 | { | 4860 | clear_message (1, 1); |
| 4879 | echo_area_glyphs = previous_echo_glyphs = NULL; | ||
| 4880 | echo_area_message = previous_echo_area_message = Qnil; | ||
| 4881 | } | ||
| 4882 | 4861 | ||
| 4883 | do_pending_window_change (); | 4862 | do_pending_window_change (0); |
| 4884 | echo_area_display (1); | 4863 | echo_area_display (1); |
| 4885 | do_pending_window_change (); | 4864 | do_pending_window_change (0); |
| 4886 | if (frame_up_to_date_hook != 0 && ! gc_in_progress) | 4865 | if (frame_up_to_date_hook != 0 && ! gc_in_progress) |
| 4887 | (*frame_up_to_date_hook) (f); | 4866 | (*frame_up_to_date_hook) (f); |
| 4888 | } | 4867 | } |
| 4889 | } | 4868 | } |
| 4890 | 4869 | ||
| 4891 | 4870 | ||
| 4892 | /* Display an echo area message M with a specified length of LEN | 4871 | /* Display an echo area message M with a specified length of NBYTES |
| 4893 | chars. The string may include null characters. If M is not a | 4872 | bytes. The string may include null characters. If M is not a |
| 4894 | string, clear out any existing message, and let the mini-buffer | 4873 | string, clear out any existing message, and let the mini-buffer |
| 4895 | text show through. */ | 4874 | text show through. */ |
| 4896 | 4875 | ||
| 4897 | void | 4876 | void |
| 4898 | message3 (m, len, multibyte) | 4877 | message3 (m, nbytes, multibyte) |
| 4899 | Lisp_Object m; | 4878 | Lisp_Object m; |
| 4900 | int len; | 4879 | int nbytes; |
| 4901 | int multibyte; | 4880 | int multibyte; |
| 4902 | { | 4881 | { |
| 4903 | struct gcpro gcpro1; | 4882 | struct gcpro gcpro1; |
| @@ -4907,8 +4886,8 @@ message3 (m, len, multibyte) | |||
| 4907 | /* First flush out any partial line written with print. */ | 4886 | /* First flush out any partial line written with print. */ |
| 4908 | message_log_maybe_newline (); | 4887 | message_log_maybe_newline (); |
| 4909 | if (STRINGP (m)) | 4888 | if (STRINGP (m)) |
| 4910 | message_dolog (XSTRING (m)->data, len, 1, multibyte); | 4889 | message_dolog (XSTRING (m)->data, nbytes, 1, multibyte); |
| 4911 | message3_nolog (m, len, multibyte); | 4890 | message3_nolog (m, nbytes, multibyte); |
| 4912 | 4891 | ||
| 4913 | UNGCPRO; | 4892 | UNGCPRO; |
| 4914 | } | 4893 | } |
| @@ -4917,9 +4896,9 @@ message3 (m, len, multibyte) | |||
| 4917 | /* The non-logging version of message3. */ | 4896 | /* The non-logging version of message3. */ |
| 4918 | 4897 | ||
| 4919 | void | 4898 | void |
| 4920 | message3_nolog (m, len, multibyte) | 4899 | message3_nolog (m, nbytes, multibyte) |
| 4921 | Lisp_Object m; | 4900 | Lisp_Object m; |
| 4922 | int len, multibyte; | 4901 | int nbytes, multibyte; |
| 4923 | { | 4902 | { |
| 4924 | message_enable_multibyte = multibyte; | 4903 | message_enable_multibyte = multibyte; |
| 4925 | 4904 | ||
| @@ -4929,7 +4908,7 @@ message3_nolog (m, len, multibyte) | |||
| 4929 | putc ('\n', stderr); | 4908 | putc ('\n', stderr); |
| 4930 | noninteractive_need_newline = 0; | 4909 | noninteractive_need_newline = 0; |
| 4931 | if (STRINGP (m)) | 4910 | if (STRINGP (m)) |
| 4932 | fwrite (XSTRING (m)->data, len, 1, stderr); | 4911 | fwrite (XSTRING (m)->data, nbytes, 1, stderr); |
| 4933 | if (cursor_in_echo_area == 0) | 4912 | if (cursor_in_echo_area == 0) |
| 4934 | fprintf (stderr, "\n"); | 4913 | fprintf (stderr, "\n"); |
| 4935 | fflush (stderr); | 4914 | fflush (stderr); |
| @@ -4942,36 +4921,31 @@ message3_nolog (m, len, multibyte) | |||
| 4942 | && FRAME_MESSAGE_BUF (selected_frame)) | 4921 | && FRAME_MESSAGE_BUF (selected_frame)) |
| 4943 | { | 4922 | { |
| 4944 | Lisp_Object mini_window; | 4923 | Lisp_Object mini_window; |
| 4924 | Lisp_Object frame; | ||
| 4945 | struct frame *f; | 4925 | struct frame *f; |
| 4946 | 4926 | ||
| 4947 | /* Get the frame containing the mini-buffer | 4927 | /* Get the frame containing the mini-buffer |
| 4948 | that the selected frame is using. */ | 4928 | that the selected frame is using. */ |
| 4949 | mini_window = FRAME_MINIBUF_WINDOW (selected_frame); | 4929 | mini_window = FRAME_MINIBUF_WINDOW (selected_frame); |
| 4950 | f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window))); | 4930 | frame = XWINDOW (mini_window)->frame; |
| 4931 | f = XFRAME (frame); | ||
| 4951 | 4932 | ||
| 4952 | FRAME_SAMPLE_VISIBILITY (f); | 4933 | FRAME_SAMPLE_VISIBILITY (f); |
| 4953 | if (FRAME_VISIBLE_P (selected_frame) | 4934 | if (FRAME_VISIBLE_P (selected_frame) |
| 4954 | && ! FRAME_VISIBLE_P (f)) | 4935 | && !FRAME_VISIBLE_P (f)) |
| 4955 | Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window))); | 4936 | Fmake_frame_visible (frame); |
| 4956 | 4937 | ||
| 4957 | if (STRINGP (m)) | 4938 | if (STRINGP (m) && XSTRING (m)->size) |
| 4958 | { | 4939 | { |
| 4959 | echo_area_glyphs = NULL; | 4940 | set_message (NULL, m, nbytes, multibyte); |
| 4960 | echo_area_message = m; | 4941 | Fraise_frame (frame); |
| 4961 | echo_area_glyphs_length = len; | ||
| 4962 | |||
| 4963 | if (minibuffer_auto_raise) | ||
| 4964 | Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window))); | ||
| 4965 | } | 4942 | } |
| 4966 | else | 4943 | else |
| 4967 | { | 4944 | clear_message (1, 1); |
| 4968 | echo_area_glyphs = previous_echo_glyphs = NULL; | ||
| 4969 | echo_area_message = previous_echo_area_message = Qnil; | ||
| 4970 | } | ||
| 4971 | 4945 | ||
| 4972 | do_pending_window_change (); | 4946 | do_pending_window_change (0); |
| 4973 | echo_area_display (1); | 4947 | echo_area_display (1); |
| 4974 | do_pending_window_change (); | 4948 | do_pending_window_change (0); |
| 4975 | if (frame_up_to_date_hook != 0 && ! gc_in_progress) | 4949 | if (frame_up_to_date_hook != 0 && ! gc_in_progress) |
| 4976 | (*frame_up_to_date_hook) (f); | 4950 | (*frame_up_to_date_hook) (f); |
| 4977 | } | 4951 | } |
| @@ -5065,27 +5039,6 @@ message_with_string (m, string, log) | |||
| 5065 | } | 5039 | } |
| 5066 | 5040 | ||
| 5067 | 5041 | ||
| 5068 | /* Truncate what will be displayed in the echo area | ||
| 5069 | the next time we display it--but don't redisplay it now. */ | ||
| 5070 | |||
| 5071 | void | ||
| 5072 | truncate_echo_area (len) | ||
| 5073 | int len; | ||
| 5074 | { | ||
| 5075 | /* A null message buffer means that the frame hasn't really been | ||
| 5076 | initialized yet. Error messages get reported properly by | ||
| 5077 | cmd_error, so this must be just an informative message; toss it. */ | ||
| 5078 | if (!noninteractive && INTERACTIVE && FRAME_MESSAGE_BUF (selected_frame)) | ||
| 5079 | echo_area_glyphs_length = len; | ||
| 5080 | } | ||
| 5081 | |||
| 5082 | |||
| 5083 | /* Nonzero if FRAME_MESSAGE_BUF (selected_frame) is being used by | ||
| 5084 | print; zero if being used by message. */ | ||
| 5085 | |||
| 5086 | int message_buf_print; | ||
| 5087 | |||
| 5088 | |||
| 5089 | /* Dump an informative message to the minibuf. If M is 0, clear out | 5042 | /* Dump an informative message to the minibuf. If M is 0, clear out |
| 5090 | any existing message, and let the mini-buffer text show through. */ | 5043 | any existing message, and let the mini-buffer text show through. */ |
| 5091 | 5044 | ||
| @@ -5172,59 +5125,621 @@ message_nolog (m, a1, a2, a3) | |||
| 5172 | } | 5125 | } |
| 5173 | 5126 | ||
| 5174 | 5127 | ||
| 5175 | /* Display echo_area_message or echo_area_glyphs in the current | 5128 | /* Display the current message in the current mini-buffer. This is |
| 5176 | mini-buffer. */ | 5129 | only called from error handlers in process.c, and is not time |
| 5130 | critical. */ | ||
| 5177 | 5131 | ||
| 5178 | void | 5132 | void |
| 5179 | update_echo_area () | 5133 | update_echo_area () |
| 5180 | { | 5134 | { |
| 5181 | if (STRINGP (echo_area_message)) | 5135 | if (!NILP (echo_area_buffer[0])) |
| 5182 | message3 (echo_area_message, echo_area_glyphs_length, | 5136 | { |
| 5183 | !NILP (current_buffer->enable_multibyte_characters)); | 5137 | Lisp_Object string; |
| 5138 | string = Fcurrent_message (); | ||
| 5139 | message3 (string, XSTRING (string)->size, | ||
| 5140 | !NILP (current_buffer->enable_multibyte_characters)); | ||
| 5141 | } | ||
| 5142 | } | ||
| 5143 | |||
| 5144 | |||
| 5145 | /* Call FN with args A1..A5 with either the current or last displayed | ||
| 5146 | echo_area_buffer as current buffer. | ||
| 5147 | |||
| 5148 | WHICH zero means use the current message buffer | ||
| 5149 | echo_area_buffer[0]. If that is nil, choose a suitable buffer | ||
| 5150 | from echo_buffer[] and clear it. | ||
| 5151 | |||
| 5152 | WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a | ||
| 5153 | suitable buffer from echo_buffer[] and clear it. | ||
| 5154 | |||
| 5155 | If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so | ||
| 5156 | that the current message becomes the last displayed one, make | ||
| 5157 | choose a suitable buffer for echo_area_buffer[0], and clear it. | ||
| 5158 | |||
| 5159 | Value is what FN returns. */ | ||
| 5160 | |||
| 5161 | static int | ||
| 5162 | with_echo_area_buffer (w, which, fn, a1, a2, a3, a4, a5) | ||
| 5163 | struct window *w; | ||
| 5164 | int which; | ||
| 5165 | int (*fn) (); | ||
| 5166 | int a1, a2, a3, a4, a5; | ||
| 5167 | { | ||
| 5168 | Lisp_Object buffer; | ||
| 5169 | int i, this_one, the_other, clear_buffer_p, rc; | ||
| 5170 | int count = specpdl_ptr - specpdl; | ||
| 5171 | |||
| 5172 | /* If buffers aren't life, make new ones. */ | ||
| 5173 | for (i = 0; i < 2; ++i) | ||
| 5174 | if (!BUFFERP (echo_buffer[i]) | ||
| 5175 | || NILP (XBUFFER (echo_buffer[i])->name)) | ||
| 5176 | { | ||
| 5177 | char name[30]; | ||
| 5178 | sprintf (name, " *Echo Area %d*", i); | ||
| 5179 | echo_buffer[i] = Fget_buffer_create (build_string (name)); | ||
| 5180 | } | ||
| 5181 | |||
| 5182 | clear_buffer_p = 0; | ||
| 5183 | |||
| 5184 | if (which == 0) | ||
| 5185 | this_one = 0, the_other = 1; | ||
| 5186 | else if (which > 0) | ||
| 5187 | this_one = 1, the_other = 0; | ||
| 5184 | else | 5188 | else |
| 5185 | message2 (echo_area_glyphs, echo_area_glyphs_length, | 5189 | { |
| 5186 | !NILP (current_buffer->enable_multibyte_characters)); | 5190 | this_one = 0, the_other = 1; |
| 5191 | clear_buffer_p = 1; | ||
| 5192 | |||
| 5193 | /* We need a fresh one in case the current echo buffer equals | ||
| 5194 | the one containing the last displayed echo area message. */ | ||
| 5195 | if (!NILP (echo_area_buffer[this_one]) | ||
| 5196 | && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other])) | ||
| 5197 | echo_area_buffer[this_one] = Qnil; | ||
| 5198 | |||
| 5199 | } | ||
| 5200 | |||
| 5201 | /* Choose a suitable buffer from echo_buffer[] is we don't | ||
| 5202 | have one. */ | ||
| 5203 | if (NILP (echo_area_buffer[this_one])) | ||
| 5204 | { | ||
| 5205 | echo_area_buffer[this_one] | ||
| 5206 | = (EQ (echo_area_buffer[the_other], echo_buffer[this_one]) | ||
| 5207 | ? echo_buffer[the_other] | ||
| 5208 | : echo_buffer[this_one]); | ||
| 5209 | clear_buffer_p = 1; | ||
| 5210 | } | ||
| 5211 | |||
| 5212 | buffer = echo_area_buffer[this_one]; | ||
| 5213 | |||
| 5214 | record_unwind_protect (unwind_with_echo_area_buffer, | ||
| 5215 | with_echo_area_buffer_unwind_data (w)); | ||
| 5216 | |||
| 5217 | /* Make the echo area buffer current. Note that for display | ||
| 5218 | purposes, it is not necessary that the displayed window's buffer | ||
| 5219 | == current_buffer, except for text property lookup. So, let's | ||
| 5220 | only set that buffer temporarily here without doing a full | ||
| 5221 | Fset_window_buffer. We must also change w->pointm, though, | ||
| 5222 | because otherwise an assertions in unshow_buffer fails, and Emacs | ||
| 5223 | aborts. */ | ||
| 5224 | set_buffer_internal (XBUFFER (buffer)); | ||
| 5225 | if (w) | ||
| 5226 | { | ||
| 5227 | w->buffer = buffer; | ||
| 5228 | set_marker_both (w->pointm, buffer, BEG, BEG_BYTE); | ||
| 5229 | } | ||
| 5230 | current_buffer->truncate_lines = Qnil; | ||
| 5231 | current_buffer->undo_list = Qt; | ||
| 5232 | current_buffer->read_only = Qnil; | ||
| 5233 | |||
| 5234 | if (clear_buffer_p && Z > BEG) | ||
| 5235 | del_range (BEG, Z); | ||
| 5236 | |||
| 5237 | xassert (BEGV >= BEG); | ||
| 5238 | xassert (ZV <= Z && ZV >= BEGV); | ||
| 5239 | |||
| 5240 | rc = fn (a1, a2, a3, a4, a5); | ||
| 5241 | |||
| 5242 | xassert (BEGV >= BEG); | ||
| 5243 | xassert (ZV <= Z && ZV >= BEGV); | ||
| 5244 | |||
| 5245 | unbind_to (count, Qnil); | ||
| 5246 | return rc; | ||
| 5187 | } | 5247 | } |
| 5188 | 5248 | ||
| 5189 | 5249 | ||
| 5190 | /* Redisplay the echo area of selected_frame. If UPDATE_FRAME_P is | 5250 | /* Save state that should be preserved around the call to the function |
| 5191 | non-zero update selected_frame. */ | 5251 | FN called in with_echo_area_buffer. */ |
| 5192 | 5252 | ||
| 5193 | static void | 5253 | static Lisp_Object |
| 5194 | echo_area_display (update_frame_p) | 5254 | with_echo_area_buffer_unwind_data (w) |
| 5195 | int update_frame_p; | 5255 | struct window *w; |
| 5196 | { | 5256 | { |
| 5197 | Lisp_Object mini_window; | 5257 | int i = 0; |
| 5198 | struct window *w; | 5258 | Lisp_Object vector; |
| 5199 | struct frame *f; | ||
| 5200 | 5259 | ||
| 5201 | mini_window = FRAME_MINIBUF_WINDOW (selected_frame); | 5260 | /* Reduce consing by keeping one vector in |
| 5202 | w = XWINDOW (mini_window); | 5261 | Vwith_echo_area_save_vector. */ |
| 5203 | f = XFRAME (WINDOW_FRAME (w)); | 5262 | vector = Vwith_echo_area_save_vector; |
| 5263 | Vwith_echo_area_save_vector = Qnil; | ||
| 5264 | |||
| 5265 | if (NILP (vector)) | ||
| 5266 | vector = Fmake_vector (make_number (9), Qnil); | ||
| 5267 | |||
| 5268 | XSETBUFFER (XVECTOR (vector)->contents[i], current_buffer); ++i; | ||
| 5269 | XVECTOR (vector)->contents[i++] = Vdeactivate_mark; | ||
| 5270 | XVECTOR (vector)->contents[i++] = make_number (windows_or_buffers_changed); | ||
| 5271 | XVECTOR (vector)->contents[i++] = make_number (beg_unchanged); | ||
| 5272 | XVECTOR (vector)->contents[i++] = make_number (end_unchanged); | ||
| 5273 | |||
| 5274 | if (w) | ||
| 5275 | { | ||
| 5276 | XSETWINDOW (XVECTOR (vector)->contents[i], w); ++i; | ||
| 5277 | XVECTOR (vector)->contents[i++] = w->buffer; | ||
| 5278 | XVECTOR (vector)->contents[i++] | ||
| 5279 | = make_number (XMARKER (w->pointm)->charpos); | ||
| 5280 | XVECTOR (vector)->contents[i++] | ||
| 5281 | = make_number (XMARKER (w->pointm)->bytepos); | ||
| 5282 | } | ||
| 5283 | else | ||
| 5284 | { | ||
| 5285 | int end = i + 4; | ||
| 5286 | while (i < end) | ||
| 5287 | XVECTOR (vector)->contents[i++] = Qnil; | ||
| 5288 | } | ||
| 5204 | 5289 | ||
| 5205 | /* Don't display if frame is invisible or not yet initialized. */ | 5290 | xassert (i == XVECTOR (vector)->size); |
| 5206 | if (!FRAME_VISIBLE_P (f) | 5291 | return vector; |
| 5207 | || !f->glyphs_initialized_p) | 5292 | } |
| 5208 | return; | ||
| 5209 | 5293 | ||
| 5210 | /* When Emacs starts, selected_frame may be a visible terminal | ||
| 5211 | frame, even if we run under a window system. If we let this | ||
| 5212 | through, a message would be displayed on the terminal. */ | ||
| 5213 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 5214 | if (!inhibit_window_system && !FRAME_WINDOW_P (selected_frame)) | ||
| 5215 | return; | ||
| 5216 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 5217 | 5294 | ||
| 5218 | /* Redraw garbaged frames. */ | 5295 | /* Restore global state from VECTOR which was created by |
| 5296 | with_echo_area_buffer_unwind_data. */ | ||
| 5297 | |||
| 5298 | static Lisp_Object | ||
| 5299 | unwind_with_echo_area_buffer (vector) | ||
| 5300 | Lisp_Object vector; | ||
| 5301 | { | ||
| 5302 | int i = 0; | ||
| 5303 | |||
| 5304 | set_buffer_internal (XBUFFER (XVECTOR (vector)->contents[i])); ++i; | ||
| 5305 | Vdeactivate_mark = XVECTOR (vector)->contents[i]; ++i; | ||
| 5306 | windows_or_buffers_changed = XFASTINT (XVECTOR (vector)->contents[i]); ++i; | ||
| 5307 | beg_unchanged = XFASTINT (XVECTOR (vector)->contents[i]); ++i; | ||
| 5308 | end_unchanged = XFASTINT (XVECTOR (vector)->contents[i]); ++i; | ||
| 5309 | |||
| 5310 | if (WINDOWP (XVECTOR (vector)->contents[i])) | ||
| 5311 | { | ||
| 5312 | struct window *w; | ||
| 5313 | Lisp_Object buffer, charpos, bytepos; | ||
| 5314 | |||
| 5315 | w = XWINDOW (XVECTOR (vector)->contents[i]); ++i; | ||
| 5316 | buffer = XVECTOR (vector)->contents[i]; ++i; | ||
| 5317 | charpos = XVECTOR (vector)->contents[i]; ++i; | ||
| 5318 | bytepos = XVECTOR (vector)->contents[i]; ++i; | ||
| 5319 | |||
| 5320 | w->buffer = buffer; | ||
| 5321 | set_marker_both (w->pointm, buffer, | ||
| 5322 | XFASTINT (charpos), XFASTINT (bytepos)); | ||
| 5323 | } | ||
| 5324 | |||
| 5325 | Vwith_echo_area_save_vector = vector; | ||
| 5326 | return Qnil; | ||
| 5327 | } | ||
| 5328 | |||
| 5329 | |||
| 5330 | /* Set up the echo area for use by print functions. MULTIBYTE_P | ||
| 5331 | non-zero means we will print multibyte. */ | ||
| 5332 | |||
| 5333 | void | ||
| 5334 | setup_echo_area_for_printing (multibyte_p) | ||
| 5335 | int multibyte_p; | ||
| 5336 | { | ||
| 5337 | if (!message_buf_print) | ||
| 5338 | { | ||
| 5339 | /* A message has been output since the last time we printed. | ||
| 5340 | Choose a fresh echo area buffer. */ | ||
| 5341 | if (EQ (echo_area_buffer[1], echo_buffer[0])) | ||
| 5342 | echo_area_buffer[0] = echo_buffer[1]; | ||
| 5343 | else | ||
| 5344 | echo_area_buffer[0] = echo_buffer[0]; | ||
| 5345 | |||
| 5346 | /* Switch to that buffer and clear it. */ | ||
| 5347 | set_buffer_internal (XBUFFER (echo_area_buffer[0])); | ||
| 5348 | if (Z > BEG) | ||
| 5349 | del_range (BEG, Z); | ||
| 5350 | TEMP_SET_PT_BOTH (BEG, BEG_BYTE); | ||
| 5351 | |||
| 5352 | /* Set up the buffer for the multibyteness we need. */ | ||
| 5353 | if (multibyte_p | ||
| 5354 | != !NILP (current_buffer->enable_multibyte_characters)) | ||
| 5355 | Fset_buffer_multibyte (multibyte_p ? Qt : Qnil); | ||
| 5356 | |||
| 5357 | /* Raise the frame containing the echo area. */ | ||
| 5358 | if (minibuffer_auto_raise) | ||
| 5359 | { | ||
| 5360 | Lisp_Object mini_window; | ||
| 5361 | mini_window = FRAME_MINIBUF_WINDOW (selected_frame); | ||
| 5362 | Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window))); | ||
| 5363 | } | ||
| 5364 | |||
| 5365 | message_buf_print = 1; | ||
| 5366 | } | ||
| 5367 | else if (current_buffer != XBUFFER (echo_area_buffer[0])) | ||
| 5368 | /* Someone switched buffers between print requests. */ | ||
| 5369 | set_buffer_internal (XBUFFER (echo_area_buffer[0])); | ||
| 5370 | } | ||
| 5371 | |||
| 5372 | |||
| 5373 | /* Display the current echo area message in window W. Value is | ||
| 5374 | non-zero if W's height is changed. */ | ||
| 5375 | |||
| 5376 | static int | ||
| 5377 | display_echo_area (w) | ||
| 5378 | struct window *w; | ||
| 5379 | { | ||
| 5380 | return with_echo_area_buffer (w, display_last_displayed_message_p, | ||
| 5381 | (int (*) ()) display_echo_area_1, w); | ||
| 5382 | } | ||
| 5383 | |||
| 5384 | |||
| 5385 | /* Helper for display_echo_area. Display the current buffer which | ||
| 5386 | contains the current echo area message in window W, a mini-window. | ||
| 5387 | Change the height of W so that all of the message is displayed. | ||
| 5388 | Value is non-zero if height of W was changed. */ | ||
| 5389 | |||
| 5390 | static int | ||
| 5391 | display_echo_area_1 (w) | ||
| 5392 | struct window *w; | ||
| 5393 | { | ||
| 5394 | Lisp_Object window; | ||
| 5395 | struct frame *f = XFRAME (w->frame); | ||
| 5396 | struct text_pos start; | ||
| 5397 | int window_height_changed_p = 0; | ||
| 5398 | |||
| 5399 | /* Do this before displaying, so that we have a large enough glyph | ||
| 5400 | matrix for the display. */ | ||
| 5401 | window_height_changed_p = resize_mini_window (w); | ||
| 5402 | |||
| 5403 | /* Display. */ | ||
| 5404 | clear_glyph_matrix (w->desired_matrix); | ||
| 5405 | XSETWINDOW (window, w); | ||
| 5406 | SET_TEXT_POS (start, BEG, BEG_BYTE); | ||
| 5407 | try_window (window, start); | ||
| 5408 | |||
| 5409 | /* The current buffer is the one containing the last displayed | ||
| 5410 | echo area message. */ | ||
| 5411 | XSETBUFFER (echo_area_buffer[1], current_buffer); | ||
| 5412 | |||
| 5413 | return window_height_changed_p; | ||
| 5414 | } | ||
| 5415 | |||
| 5416 | |||
| 5417 | /* Resize mini-window W to fit the size of its contents. Value is | ||
| 5418 | non-zero if the window height has been changed. */ | ||
| 5419 | |||
| 5420 | static int | ||
| 5421 | resize_mini_window (w) | ||
| 5422 | struct window *w; | ||
| 5423 | { | ||
| 5424 | struct frame *f = XFRAME (w->frame); | ||
| 5425 | int window_height_changed_p = 0; | ||
| 5426 | |||
| 5427 | xassert (MINI_WINDOW_P (w)); | ||
| 5428 | |||
| 5429 | if (!FRAME_MINIBUF_ONLY_P (f)) | ||
| 5430 | { | ||
| 5431 | struct it it; | ||
| 5432 | |||
| 5433 | init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID); | ||
| 5434 | if (!it.truncate_lines_p) | ||
| 5435 | { | ||
| 5436 | struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f)); | ||
| 5437 | int total_height = XFASTINT (root->height) + XFASTINT (w->height); | ||
| 5438 | int height, max_height; | ||
| 5439 | int unit = CANON_Y_UNIT (f); | ||
| 5440 | struct text_pos start; | ||
| 5441 | |||
| 5442 | /* Compute the max. number of lines specified by the user. */ | ||
| 5443 | if (FLOATP (Vmax_mini_window_height)) | ||
| 5444 | max_height = XFLOATINT (Vmax_mini_window_height) * total_height; | ||
| 5445 | else if (INTEGERP (Vmax_mini_window_height)) | ||
| 5446 | max_height = XINT (Vmax_mini_window_height); | ||
| 5447 | |||
| 5448 | /* Correct that max. height if it's bogus. */ | ||
| 5449 | max_height = max (1, max_height); | ||
| 5450 | max_height = min (total_height, max_height); | ||
| 5451 | |||
| 5452 | /* Find out the height of the text in the window. */ | ||
| 5453 | move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS); | ||
| 5454 | height = (unit - 1 + it.current_y + last_height) / unit; | ||
| 5455 | height = max (1, height); | ||
| 5456 | |||
| 5457 | /* Compute a suitable window start. */ | ||
| 5458 | if (height > max_height) | ||
| 5459 | { | ||
| 5460 | height = max_height; | ||
| 5461 | init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); | ||
| 5462 | move_it_vertically_backward (&it, (height - 1) * unit); | ||
| 5463 | start = it.current.pos; | ||
| 5464 | } | ||
| 5465 | else | ||
| 5466 | SET_TEXT_POS (start, BEGV, BEGV_BYTE); | ||
| 5467 | SET_MARKER_FROM_TEXT_POS (w->start, start); | ||
| 5468 | |||
| 5469 | /* Change window's height, if necessary. */ | ||
| 5470 | if (height != XFASTINT (w->height)) | ||
| 5471 | { | ||
| 5472 | Lisp_Object old_selected_window; | ||
| 5473 | |||
| 5474 | old_selected_window = selected_window; | ||
| 5475 | XSETWINDOW (selected_window, w); | ||
| 5476 | change_window_height (height - XFASTINT (w->height), 0); | ||
| 5477 | selected_window = old_selected_window; | ||
| 5478 | window_height_changed_p = 1; | ||
| 5479 | } | ||
| 5480 | } | ||
| 5481 | } | ||
| 5482 | |||
| 5483 | return window_height_changed_p; | ||
| 5484 | } | ||
| 5485 | |||
| 5486 | |||
| 5487 | /* Value is the current message, a string, or nil if there is no | ||
| 5488 | current message. */ | ||
| 5489 | |||
| 5490 | Lisp_Object | ||
| 5491 | current_message () | ||
| 5492 | { | ||
| 5493 | Lisp_Object msg; | ||
| 5494 | |||
| 5495 | if (NILP (echo_area_buffer[0])) | ||
| 5496 | msg = Qnil; | ||
| 5497 | else | ||
| 5498 | { | ||
| 5499 | with_echo_area_buffer (0, 0, (int (*) ()) current_message_1, &msg); | ||
| 5500 | if (NILP (msg)) | ||
| 5501 | echo_area_buffer[0] = Qnil; | ||
| 5502 | } | ||
| 5503 | |||
| 5504 | return msg; | ||
| 5505 | } | ||
| 5506 | |||
| 5507 | |||
| 5508 | static int | ||
| 5509 | current_message_1 (msg) | ||
| 5510 | Lisp_Object *msg; | ||
| 5511 | { | ||
| 5512 | if (Z > BEG) | ||
| 5513 | *msg = make_buffer_string (BEG, Z, 1); | ||
| 5514 | else | ||
| 5515 | *msg = Qnil; | ||
| 5516 | return 0; | ||
| 5517 | } | ||
| 5518 | |||
| 5519 | |||
| 5520 | /* Push the current message on Vmessage_stack for later restauration | ||
| 5521 | by restore_message. Value is non-zero if the current message isn't | ||
| 5522 | empty. This is a relatively infrequent operation, so it's not | ||
| 5523 | worth optimizing. */ | ||
| 5524 | |||
| 5525 | int | ||
| 5526 | push_message () | ||
| 5527 | { | ||
| 5528 | Lisp_Object msg; | ||
| 5529 | msg = current_message (); | ||
| 5530 | Vmessage_stack = Fcons (msg, Vmessage_stack); | ||
| 5531 | return STRINGP (msg); | ||
| 5532 | } | ||
| 5533 | |||
| 5534 | |||
| 5535 | /* Restore message display from the top of Vmessage_stack. */ | ||
| 5536 | |||
| 5537 | void | ||
| 5538 | restore_message () | ||
| 5539 | { | ||
| 5540 | Lisp_Object msg; | ||
| 5541 | |||
| 5542 | xassert (CONSP (Vmessage_stack)); | ||
| 5543 | msg = XCAR (Vmessage_stack); | ||
| 5544 | if (STRINGP (msg)) | ||
| 5545 | message3_nolog (msg, STRING_BYTES (XSTRING (msg)), STRING_MULTIBYTE (msg)); | ||
| 5546 | else | ||
| 5547 | message3_nolog (msg, 0, 0); | ||
| 5548 | } | ||
| 5549 | |||
| 5550 | |||
| 5551 | /* Pop the top-most entry off Vmessage_stack. */ | ||
| 5552 | |||
| 5553 | void | ||
| 5554 | pop_message () | ||
| 5555 | { | ||
| 5556 | xassert (CONSP (Vmessage_stack)); | ||
| 5557 | Vmessage_stack = XCDR (Vmessage_stack); | ||
| 5558 | } | ||
| 5559 | |||
| 5560 | |||
| 5561 | /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs | ||
| 5562 | exits. If the stack is not empty, we have a missing pop_message | ||
| 5563 | somewhere. */ | ||
| 5564 | |||
| 5565 | void | ||
| 5566 | check_message_stack () | ||
| 5567 | { | ||
| 5568 | if (!NILP (Vmessage_stack)) | ||
| 5569 | abort (); | ||
| 5570 | } | ||
| 5571 | |||
| 5572 | |||
| 5573 | /* Truncate to NCHARS what will be displayed in the echo area the next | ||
| 5574 | time we display it---but don't redisplay it now. */ | ||
| 5575 | |||
| 5576 | void | ||
| 5577 | truncate_echo_area (nchars) | ||
| 5578 | int nchars; | ||
| 5579 | { | ||
| 5580 | if (nchars == 0) | ||
| 5581 | echo_area_buffer[0] = Qnil; | ||
| 5582 | /* A null message buffer means that the frame hasn't really been | ||
| 5583 | initialized yet. Error messages get reported properly by | ||
| 5584 | cmd_error, so this must be just an informative message; toss it. */ | ||
| 5585 | else if (!noninteractive | ||
| 5586 | && INTERACTIVE | ||
| 5587 | && FRAME_MESSAGE_BUF (selected_frame) | ||
| 5588 | && !NILP (echo_area_buffer[0])) | ||
| 5589 | with_echo_area_buffer (0, 0, (int (*) ()) truncate_message_1, nchars); | ||
| 5590 | } | ||
| 5591 | |||
| 5592 | |||
| 5593 | /* Helper function for truncate_echo_area. Truncate the current | ||
| 5594 | message to at most NCHARS characters. */ | ||
| 5595 | |||
| 5596 | static int | ||
| 5597 | truncate_message_1 (nchars) | ||
| 5598 | int nchars; | ||
| 5599 | { | ||
| 5600 | if (BEG + nchars < Z) | ||
| 5601 | del_range (BEG + nchars, Z); | ||
| 5602 | if (Z == BEG) | ||
| 5603 | echo_area_buffer[0] = Qnil; | ||
| 5604 | return 0; | ||
| 5605 | } | ||
| 5606 | |||
| 5607 | |||
| 5608 | /* Set the current message to a substring of S or STRING. | ||
| 5609 | |||
| 5610 | If STRING is a Lisp string, set the message to the first NBYTES | ||
| 5611 | bytes from STRING. NBYTES zero means use the whole string. If | ||
| 5612 | STRING is multibyte, the message will be displayed multibyte. | ||
| 5613 | |||
| 5614 | If S is not null, set the message to the first LEN bytes of S. LEN | ||
| 5615 | zero means use the whole string. MULTIBYTE_P non-zero means S is | ||
| 5616 | multibyte. Display the message multibyte in that case. */ | ||
| 5617 | |||
| 5618 | void | ||
| 5619 | set_message (s, string, nbytes, multibyte_p) | ||
| 5620 | char *s; | ||
| 5621 | Lisp_Object string; | ||
| 5622 | int nbytes; | ||
| 5623 | { | ||
| 5624 | message_enable_multibyte | ||
| 5625 | = ((s && multibyte_p) | ||
| 5626 | || (STRINGP (string) && STRING_MULTIBYTE (string))); | ||
| 5627 | |||
| 5628 | with_echo_area_buffer (0, -1, (int (*) ()) set_message_1, | ||
| 5629 | s, string, nbytes, multibyte_p); | ||
| 5630 | message_buf_print = 0; | ||
| 5631 | } | ||
| 5632 | |||
| 5633 | |||
| 5634 | /* Helper function for set_message. Arguments have the same meaning | ||
| 5635 | as there. This function is called with the echo area buffer being | ||
| 5636 | current. */ | ||
| 5637 | |||
| 5638 | static int | ||
| 5639 | set_message_1 (s, string, nbytes, multibyte_p) | ||
| 5640 | char *s; | ||
| 5641 | Lisp_Object string; | ||
| 5642 | int nbytes, multibyte_p; | ||
| 5643 | { | ||
| 5644 | xassert (BEG == Z); | ||
| 5645 | |||
| 5646 | /* Change multibyteness of the echo buffer appropriately. */ | ||
| 5647 | if (message_enable_multibyte | ||
| 5648 | != !NILP (current_buffer->enable_multibyte_characters)) | ||
| 5649 | Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil); | ||
| 5650 | |||
| 5651 | /* Insert new message at BEG. */ | ||
| 5652 | TEMP_SET_PT_BOTH (BEG, BEG_BYTE); | ||
| 5653 | |||
| 5654 | if (STRINGP (string)) | ||
| 5655 | { | ||
| 5656 | int nchars; | ||
| 5657 | |||
| 5658 | if (nbytes == 0) | ||
| 5659 | nbytes = XSTRING (string)->size_byte; | ||
| 5660 | nchars = string_byte_to_char (string, nbytes); | ||
| 5661 | |||
| 5662 | /* This function takes care of single/multibyte conversion. We | ||
| 5663 | just have to ensure that the echo area buffer has the right | ||
| 5664 | setting of enable_multibyte_characters. */ | ||
| 5665 | insert_from_string (string, 0, 0, nchars, nbytes, 1); | ||
| 5666 | } | ||
| 5667 | else if (s) | ||
| 5668 | { | ||
| 5669 | if (nbytes == 0) | ||
| 5670 | nbytes = strlen (s); | ||
| 5671 | |||
| 5672 | if (multibyte_p && NILP (current_buffer->enable_multibyte_characters)) | ||
| 5673 | { | ||
| 5674 | /* Convert from multi-byte to single-byte. */ | ||
| 5675 | int i, c, n; | ||
| 5676 | unsigned char work[1]; | ||
| 5677 | |||
| 5678 | /* Convert a multibyte string to single-byte. */ | ||
| 5679 | for (i = 0; i < nbytes; i += n) | ||
| 5680 | { | ||
| 5681 | c = string_char_and_length (s + i, nbytes - i, &n); | ||
| 5682 | work[0] = (SINGLE_BYTE_CHAR_P (c) | ||
| 5683 | ? c | ||
| 5684 | : multibyte_char_to_unibyte (c, Qnil)); | ||
| 5685 | insert_1_both (work, 1, 1, 1, 0, 0); | ||
| 5686 | } | ||
| 5687 | } | ||
| 5688 | else if (!multibyte_p | ||
| 5689 | && !NILP (current_buffer->enable_multibyte_characters)) | ||
| 5690 | { | ||
| 5691 | /* Convert from single-byte to multi-byte. */ | ||
| 5692 | int i, c, n; | ||
| 5693 | unsigned char *msg = (unsigned char *) s; | ||
| 5694 | unsigned char *str, work[4]; | ||
| 5695 | |||
| 5696 | /* Convert a single-byte string to multibyte. */ | ||
| 5697 | for (i = 0; i < nbytes; i++) | ||
| 5698 | { | ||
| 5699 | c = unibyte_char_to_multibyte (msg[i]); | ||
| 5700 | n = CHAR_STRING (c, work, str); | ||
| 5701 | insert_1_both (work, 1, n, 1, 0, 0); | ||
| 5702 | } | ||
| 5703 | } | ||
| 5704 | else | ||
| 5705 | insert_1 (s, nbytes, 1, 0, 0); | ||
| 5706 | } | ||
| 5707 | |||
| 5708 | return 0; | ||
| 5709 | } | ||
| 5710 | |||
| 5711 | |||
| 5712 | /* Clear messages. CURRENT_P non-zero means clear the current | ||
| 5713 | message. LAST_DISPLAYED_P non-zero means clear the message | ||
| 5714 | last displayed. */ | ||
| 5715 | |||
| 5716 | void | ||
| 5717 | clear_message (current_p, last_displayed_p) | ||
| 5718 | int current_p, last_displayed_p; | ||
| 5719 | { | ||
| 5720 | if (current_p) | ||
| 5721 | echo_area_buffer[0] = Qnil; | ||
| 5722 | |||
| 5723 | if (last_displayed_p) | ||
| 5724 | echo_area_buffer[1] = Qnil; | ||
| 5725 | |||
| 5726 | message_buf_print = 0; | ||
| 5727 | } | ||
| 5728 | |||
| 5729 | /* Clear garbaged frames. | ||
| 5730 | |||
| 5731 | This function is used where the old redisplay called | ||
| 5732 | redraw_garbaged_frames which in turn called redraw_frame which in | ||
| 5733 | turn called clear_frame. The call to clear_frame was a source of | ||
| 5734 | flickering. I believe a clear_frame is not necessary. It should | ||
| 5735 | suffice in the new redisplay to invalidate all current matrices, | ||
| 5736 | and ensure a complete redisplay of all windows. */ | ||
| 5737 | |||
| 5738 | static void | ||
| 5739 | clear_garbaged_frames () | ||
| 5740 | { | ||
| 5219 | if (frame_garbaged) | 5741 | if (frame_garbaged) |
| 5220 | { | 5742 | { |
| 5221 | /* Old redisplay called redraw_garbaged_frames here which in | ||
| 5222 | turn called redraw_frame which in turn called clear_frame. | ||
| 5223 | The call to clear_frame is a source of flickering. After | ||
| 5224 | checking the places where SET_FRAME_GARBAGED is called, I | ||
| 5225 | believe a clear_frame is not necessary. It should suffice in | ||
| 5226 | the new redisplay to invalidate all current matrices, and | ||
| 5227 | ensure a complete redisplay of all windows. */ | ||
| 5228 | Lisp_Object tail, frame; | 5743 | Lisp_Object tail, frame; |
| 5229 | 5744 | ||
| 5230 | FOR_EACH_FRAME (tail, frame) | 5745 | FOR_EACH_FRAME (tail, frame) |
| @@ -5241,52 +5756,48 @@ echo_area_display (update_frame_p) | |||
| 5241 | frame_garbaged = 0; | 5756 | frame_garbaged = 0; |
| 5242 | ++windows_or_buffers_changed; | 5757 | ++windows_or_buffers_changed; |
| 5243 | } | 5758 | } |
| 5759 | } | ||
| 5244 | 5760 | ||
| 5245 | if (echo_area_glyphs | ||
| 5246 | || STRINGP (echo_area_message) | ||
| 5247 | || minibuf_level == 0) | ||
| 5248 | { | ||
| 5249 | struct it it; | ||
| 5250 | 5761 | ||
| 5251 | echo_area_window = mini_window; | 5762 | /* Redisplay the echo area of selected_frame. If UPDATE_FRAME_P is |
| 5252 | clear_glyph_matrix (w->desired_matrix); | 5763 | non-zero update selected_frame. Value is non-zero if the |
| 5253 | init_iterator (&it, w, -1, -1, w->desired_matrix->rows, DEFAULT_FACE_ID); | 5764 | mini-windows height has been changed. */ |
| 5254 | |||
| 5255 | if (STRINGP (echo_area_message) | ||
| 5256 | && echo_area_glyphs_length) | ||
| 5257 | { | ||
| 5258 | prepare_desired_row (it.glyph_row); | ||
| 5259 | display_string (NULL, echo_area_message, Qnil, 0, 0, | ||
| 5260 | &it, -1, echo_area_glyphs_length, 0, | ||
| 5261 | message_enable_multibyte); | ||
| 5262 | it.glyph_row->truncated_on_right_p = 0; | ||
| 5263 | compute_line_metrics (&it); | ||
| 5264 | } | ||
| 5265 | else if (echo_area_glyphs | ||
| 5266 | && echo_area_glyphs_length) | ||
| 5267 | { | ||
| 5268 | prepare_desired_row (it.glyph_row); | ||
| 5269 | display_string (echo_area_glyphs, Qnil, Qnil, 0, 0, &it, | ||
| 5270 | -1, echo_area_glyphs_length, 0, | ||
| 5271 | message_enable_multibyte); | ||
| 5272 | it.glyph_row->truncated_on_right_p = 0; | ||
| 5273 | compute_line_metrics (&it); | ||
| 5274 | } | ||
| 5275 | else | ||
| 5276 | blank_row (w, it.glyph_row, 0); | ||
| 5277 | |||
| 5278 | it.glyph_row->y = it.current_y; | ||
| 5279 | it.current_y += it.glyph_row->height; | ||
| 5280 | 5765 | ||
| 5281 | /* Clear the rest of the lines. */ | 5766 | static int |
| 5282 | while (it.current_y < it.last_visible_y) | 5767 | echo_area_display (update_frame_p) |
| 5283 | { | 5768 | int update_frame_p; |
| 5284 | ++it.glyph_row; | 5769 | { |
| 5285 | blank_row (w, it.glyph_row, it.current_y); | 5770 | Lisp_Object mini_window; |
| 5286 | it.current_y += it.glyph_row->height; | 5771 | struct window *w; |
| 5287 | } | 5772 | struct frame *f; |
| 5773 | int window_height_changed_p = 0; | ||
| 5774 | |||
| 5775 | mini_window = FRAME_MINIBUF_WINDOW (selected_frame); | ||
| 5776 | w = XWINDOW (mini_window); | ||
| 5777 | f = XFRAME (WINDOW_FRAME (w)); | ||
| 5778 | |||
| 5779 | /* Don't display if frame is invisible or not yet initialized. */ | ||
| 5780 | if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p) | ||
| 5781 | return 0; | ||
| 5288 | 5782 | ||
| 5783 | /* When Emacs starts, selected_frame may be a visible terminal | ||
| 5784 | frame, even if we run under a window system. If we let this | ||
| 5785 | through, a message would be displayed on the terminal. */ | ||
| 5786 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 5787 | if (!inhibit_window_system && !FRAME_WINDOW_P (selected_frame)) | ||
| 5788 | return 0; | ||
| 5789 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 5790 | |||
| 5791 | /* Redraw garbaged frames. */ | ||
| 5792 | if (frame_garbaged) | ||
| 5793 | clear_garbaged_frames (); | ||
| 5794 | |||
| 5795 | if (!NILP (echo_area_buffer[0]) || minibuf_level == 0) | ||
| 5796 | { | ||
| 5797 | echo_area_window = mini_window; | ||
| 5798 | window_height_changed_p = display_echo_area (w); | ||
| 5289 | w->must_be_updated_p = 1; | 5799 | w->must_be_updated_p = 1; |
| 5800 | |||
| 5290 | if (update_frame_p) | 5801 | if (update_frame_p) |
| 5291 | { | 5802 | { |
| 5292 | /* Calling update_single_window is faster when we can use | 5803 | /* Calling update_single_window is faster when we can use |
| @@ -5303,15 +5814,16 @@ echo_area_display (update_frame_p) | |||
| 5303 | else if (!EQ (mini_window, selected_window)) | 5814 | else if (!EQ (mini_window, selected_window)) |
| 5304 | windows_or_buffers_changed++; | 5815 | windows_or_buffers_changed++; |
| 5305 | 5816 | ||
| 5817 | if (NILP (echo_area_buffer[0])) | ||
| 5818 | clear_message (0, 1); | ||
| 5819 | |||
| 5306 | /* Prevent redisplay optimization in redisplay_internal by resetting | 5820 | /* Prevent redisplay optimization in redisplay_internal by resetting |
| 5307 | this_line_start_pos. This is done because the mini-buffer now | 5821 | this_line_start_pos. This is done because the mini-buffer now |
| 5308 | displays the message instead of its buffer text. */ | 5822 | displays the message instead of its buffer text. */ |
| 5309 | if (EQ (mini_window, selected_window)) | 5823 | if (EQ (mini_window, selected_window)) |
| 5310 | CHARPOS (this_line_start_pos) = 0; | 5824 | CHARPOS (this_line_start_pos) = 0; |
| 5311 | 5825 | ||
| 5312 | previous_echo_glyphs = echo_area_glyphs; | 5826 | return window_height_changed_p; |
| 5313 | previous_echo_area_message = echo_area_message; | ||
| 5314 | previous_echo_glyphs_length = echo_area_glyphs_length; | ||
| 5315 | } | 5827 | } |
| 5316 | 5828 | ||
| 5317 | 5829 | ||
| @@ -6441,38 +6953,17 @@ redisplay_internal (preserve_echo_area) | |||
| 6441 | } | 6953 | } |
| 6442 | 6954 | ||
| 6443 | /* Notice any pending interrupt request to change frame size. */ | 6955 | /* Notice any pending interrupt request to change frame size. */ |
| 6444 | do_pending_window_change (); | 6956 | do_pending_window_change (1); |
| 6445 | 6957 | ||
| 6446 | /* Clear frames marked as garbaged. */ | 6958 | /* Clear frames marked as garbaged. */ |
| 6447 | if (frame_garbaged) | 6959 | if (frame_garbaged) |
| 6448 | { | 6960 | clear_garbaged_frames (); |
| 6449 | /* Old redisplay called redraw_garbaged_frames here which in | ||
| 6450 | turn called redraw_frame which in turn called clear_frame. | ||
| 6451 | The call to clear_frame is a source of flickering. After | ||
| 6452 | checking the places where SET_FRAME_GARBAGED is called, I | ||
| 6453 | believe a clear_frame is not necessary. It should suffice in | ||
| 6454 | the new redisplay to invalidate all current matrices, and | ||
| 6455 | ensure a complete redisplay of all windows. */ | ||
| 6456 | Lisp_Object tail, frame; | ||
| 6457 | |||
| 6458 | FOR_EACH_FRAME (tail, frame) | ||
| 6459 | { | ||
| 6460 | struct frame *f = XFRAME (frame); | ||
| 6461 | |||
| 6462 | if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f)) | ||
| 6463 | { | ||
| 6464 | clear_current_matrices (f); | ||
| 6465 | f->garbaged = 0; | ||
| 6466 | } | ||
| 6467 | } | ||
| 6468 | |||
| 6469 | frame_garbaged = 0; | ||
| 6470 | ++windows_or_buffers_changed; | ||
| 6471 | } | ||
| 6472 | 6961 | ||
| 6473 | /* Build menubar and toolbar items. */ | 6962 | /* Build menubar and toolbar items. */ |
| 6474 | prepare_menu_bars (); | 6963 | prepare_menu_bars (); |
| 6475 | 6964 | ||
| 6965 | retry_1: | ||
| 6966 | |||
| 6476 | if (windows_or_buffers_changed) | 6967 | if (windows_or_buffers_changed) |
| 6477 | update_mode_lines++; | 6968 | update_mode_lines++; |
| 6478 | 6969 | ||
| @@ -6510,15 +7001,29 @@ redisplay_internal (preserve_echo_area) | |||
| 6510 | /* Normally the message* functions will have already displayed and | 7001 | /* Normally the message* functions will have already displayed and |
| 6511 | updated the echo area, but the frame may have been trashed, or | 7002 | updated the echo area, but the frame may have been trashed, or |
| 6512 | the update may have been preempted, so display the echo area | 7003 | the update may have been preempted, so display the echo area |
| 6513 | again here. */ | 7004 | again here. Checking both message buffers captures the case that |
| 6514 | if (echo_area_glyphs | 7005 | the echo area should be cleared. */ |
| 6515 | || STRINGP (echo_area_message) | 7006 | if (!NILP (echo_area_buffer[0]) || !NILP (echo_area_buffer[1])) |
| 6516 | || previous_echo_glyphs | ||
| 6517 | || STRINGP (previous_echo_area_message)) | ||
| 6518 | { | 7007 | { |
| 6519 | echo_area_display (0); | 7008 | int window_height_changed_p = echo_area_display (0); |
| 6520 | must_finish = 1; | 7009 | must_finish = 1; |
| 7010 | if (fonts_changed_p) | ||
| 7011 | goto retry; | ||
| 7012 | else if (window_height_changed_p) | ||
| 7013 | { | ||
| 7014 | consider_all_windows_p = 1; | ||
| 7015 | ++update_mode_lines; | ||
| 7016 | ++windows_or_buffers_changed; | ||
| 7017 | } | ||
| 6521 | } | 7018 | } |
| 7019 | else if (w == XWINDOW (minibuf_window) && resize_mini_window (w)) | ||
| 7020 | { | ||
| 7021 | /* Resized active mini-window to fit the size of what it is | ||
| 7022 | showing. */ | ||
| 7023 | ++windows_or_buffers_changed; | ||
| 7024 | goto retry; | ||
| 7025 | } | ||
| 7026 | |||
| 6522 | 7027 | ||
| 6523 | /* If showing the region, and mark has changed, we must redisplay | 7028 | /* If showing the region, and mark has changed, we must redisplay |
| 6524 | the whole window. The assignment to this_line_start_pos prevents | 7029 | the whole window. The assignment to this_line_start_pos prevents |
| @@ -6682,7 +7187,7 @@ redisplay_internal (preserve_echo_area) | |||
| 6682 | { | 7187 | { |
| 6683 | if (!must_finish) | 7188 | if (!must_finish) |
| 6684 | { | 7189 | { |
| 6685 | do_pending_window_change (); | 7190 | do_pending_window_change (1); |
| 6686 | 7191 | ||
| 6687 | /* We used to always goto end_of_redisplay here, but this | 7192 | /* We used to always goto end_of_redisplay here, but this |
| 6688 | isn't enough if we have a blinking cursor. */ | 7193 | isn't enough if we have a blinking cursor. */ |
| @@ -6975,7 +7480,7 @@ update: | |||
| 6975 | } | 7480 | } |
| 6976 | 7481 | ||
| 6977 | /* Change frame size now if a change is pending. */ | 7482 | /* Change frame size now if a change is pending. */ |
| 6978 | do_pending_window_change (); | 7483 | do_pending_window_change (1); |
| 6979 | 7484 | ||
| 6980 | /* If we just did a pending size change, or have additional | 7485 | /* If we just did a pending size change, or have additional |
| 6981 | visible frames, redisplay again. */ | 7486 | visible frames, redisplay again. */ |
| @@ -6983,7 +7488,7 @@ update: | |||
| 6983 | goto retry; | 7488 | goto retry; |
| 6984 | 7489 | ||
| 6985 | end_of_redisplay:; | 7490 | end_of_redisplay:; |
| 6986 | 7491 | ||
| 6987 | unbind_to (count, Qnil); | 7492 | unbind_to (count, Qnil); |
| 6988 | } | 7493 | } |
| 6989 | 7494 | ||
| @@ -6999,17 +7504,13 @@ update: | |||
| 6999 | void | 7504 | void |
| 7000 | redisplay_preserve_echo_area () | 7505 | redisplay_preserve_echo_area () |
| 7001 | { | 7506 | { |
| 7002 | if (!echo_area_glyphs | 7507 | if (!NILP (echo_area_buffer[1])) |
| 7003 | && !STRINGP (echo_area_message) | ||
| 7004 | && (previous_echo_glyphs | ||
| 7005 | || STRINGP (previous_echo_area_message))) | ||
| 7006 | { | 7508 | { |
| 7007 | echo_area_glyphs = previous_echo_glyphs; | 7509 | /* We have a previously displayed message, but no current |
| 7008 | echo_area_message = previous_echo_area_message; | 7510 | message. Redisplay the previous message. */ |
| 7009 | echo_area_glyphs_length = previous_echo_glyphs_length; | 7511 | display_last_displayed_message_p = 1; |
| 7010 | redisplay_internal (1); | 7512 | redisplay_internal (1); |
| 7011 | echo_area_glyphs = NULL; | 7513 | display_last_displayed_message_p = 0; |
| 7012 | echo_area_message = Qnil; | ||
| 7013 | } | 7514 | } |
| 7014 | else | 7515 | else |
| 7015 | redisplay_internal (1); | 7516 | redisplay_internal (1); |
| @@ -7025,6 +7526,7 @@ unwind_redisplay (old_redisplaying_p) | |||
| 7025 | Lisp_Object old_redisplaying_p; | 7526 | Lisp_Object old_redisplaying_p; |
| 7026 | { | 7527 | { |
| 7027 | redisplaying_p = XFASTINT (old_redisplaying_p); | 7528 | redisplaying_p = XFASTINT (old_redisplaying_p); |
| 7529 | return Qnil; | ||
| 7028 | } | 7530 | } |
| 7029 | 7531 | ||
| 7030 | 7532 | ||
| @@ -7641,8 +8143,7 @@ redisplay_window (window, just_this_one_p) | |||
| 7641 | if (MINI_WINDOW_P (w)) | 8143 | if (MINI_WINDOW_P (w)) |
| 7642 | { | 8144 | { |
| 7643 | if (w == XWINDOW (echo_area_window) | 8145 | if (w == XWINDOW (echo_area_window) |
| 7644 | && (echo_area_glyphs | 8146 | && !NILP (echo_area_buffer[0])) |
| 7645 | || STRINGP (echo_area_message))) | ||
| 7646 | { | 8147 | { |
| 7647 | if (update_mode_line) | 8148 | if (update_mode_line) |
| 7648 | /* We may have to update a tty frame's menu bar or a | 8149 | /* We may have to update a tty frame's menu bar or a |
| @@ -8382,10 +8883,9 @@ redisplay_window (window, just_this_one_p) | |||
| 8382 | visible region. | 8883 | visible region. |
| 8383 | 8884 | ||
| 8384 | Note that mini-buffers sometimes aren't displaying any text. */ | 8885 | Note that mini-buffers sometimes aren't displaying any text. */ |
| 8385 | if (! MINI_WINDOW_P (w) | 8886 | if (!MINI_WINDOW_P (w) |
| 8386 | || (w == XWINDOW (minibuf_window) | 8887 | || (w == XWINDOW (minibuf_window) |
| 8387 | && !echo_area_glyphs | 8888 | && NILP (echo_area_buffer[0]))) |
| 8388 | && !STRINGP (echo_area_message))) | ||
| 8389 | { | 8889 | { |
| 8390 | whole = ZV - BEGV; | 8890 | whole = ZV - BEGV; |
| 8391 | start = marker_position (w->start) - BEGV; | 8891 | start = marker_position (w->start) - BEGV; |
| @@ -8978,11 +9478,6 @@ get_first_unchanged_at_end_row (w, delta, delta_bytes) | |||
| 8978 | /* Set row to the last row in W's current matrix displaying text. */ | 9478 | /* Set row to the last row in W's current matrix displaying text. */ |
| 8979 | row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); | 9479 | row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); |
| 8980 | 9480 | ||
| 8981 | /* End vpos should always be on text, except in an entirely empty | ||
| 8982 | matrix. */ | ||
| 8983 | xassert (MATRIX_ROW_DISPLAYS_TEXT_P (row) | ||
| 8984 | || MATRIX_ROW_VPOS (row, w->current_matrix) == 0); | ||
| 8985 | |||
| 8986 | /* If matrix is entirely empty, no unchanged row exists. */ | 9481 | /* If matrix is entirely empty, no unchanged row exists. */ |
| 8987 | if (MATRIX_ROW_DISPLAYS_TEXT_P (row)) | 9482 | if (MATRIX_ROW_DISPLAYS_TEXT_P (row)) |
| 8988 | { | 9483 | { |
| @@ -10018,10 +10513,15 @@ compute_line_metrics (it) | |||
| 10018 | /* Append one space to the glyph row of iterator IT if doing a | 10513 | /* Append one space to the glyph row of iterator IT if doing a |
| 10019 | window-based redisplay. DEFAULT_FACE_P non-zero means let the | 10514 | window-based redisplay. DEFAULT_FACE_P non-zero means let the |
| 10020 | space have the default face, otherwise let it have the same face as | 10515 | space have the default face, otherwise let it have the same face as |
| 10021 | IT->face_id. This function is called to make sure that there is | 10516 | IT->face_id. |
| 10022 | always one glyph at the end of a glyph row that the cursor can be | 10517 | |
| 10023 | set on under window-systems. (If there weren't such a glyph we | 10518 | This function is called to make sure that there is always one glyph |
| 10024 | would not know how wide and tall the cursor should be displayed). */ | 10519 | at the end of a glyph row that the cursor can be set on under |
| 10520 | window-systems. (If there weren't such a glyph we would not know | ||
| 10521 | how wide and tall a box cursor should be displayed). | ||
| 10522 | |||
| 10523 | At the same time this space let's a nicely handle clearing to the | ||
| 10524 | end of the line if the row ends in italic text. */ | ||
| 10025 | 10525 | ||
| 10026 | static void | 10526 | static void |
| 10027 | append_space (it, default_face_p) | 10527 | append_space (it, default_face_p) |
| @@ -10269,45 +10769,6 @@ display_line (it) | |||
| 10269 | recenter_overlay_lists but the first will be pretty cheap. */ | 10769 | recenter_overlay_lists but the first will be pretty cheap. */ |
| 10270 | recenter_overlay_lists (current_buffer, IT_CHARPOS (*it)); | 10770 | recenter_overlay_lists (current_buffer, IT_CHARPOS (*it)); |
| 10271 | 10771 | ||
| 10272 | #if NO_PROMPT_IN_BUFFER | ||
| 10273 | /* Show mini-buffer prompt, if at the beginning of a mini-buffer | ||
| 10274 | window. */ | ||
| 10275 | if (MINI_WINDOW_P (it->w) | ||
| 10276 | && MATRIX_ROW_START_CHARPOS (row) == BEG | ||
| 10277 | && it->vpos == 0) | ||
| 10278 | { | ||
| 10279 | if (NILP (minibuf_prompt)) | ||
| 10280 | minibuf_prompt_width = minibuf_prompt_pixel_width = 0; | ||
| 10281 | else | ||
| 10282 | { | ||
| 10283 | /* We would like to truncate the prompt a little bit before | ||
| 10284 | the right margin of the window, so that user input can | ||
| 10285 | start on the first line. Set max_x to this position. */ | ||
| 10286 | int max_x = (it->last_visible_x - 4 * CANON_X_UNIT (it->f)); | ||
| 10287 | |||
| 10288 | /* We use a temporary iterator different from IT so that | ||
| 10289 | IT's settings are not overwritten when displaying | ||
| 10290 | the prompt. */ | ||
| 10291 | struct it ti; | ||
| 10292 | |||
| 10293 | ti = *it; | ||
| 10294 | |||
| 10295 | /* Display the prompt. Set minibuf_prompt_width to the | ||
| 10296 | number of glyphs generated for the prompt, set | ||
| 10297 | minibuf_prompt_pixel_width to its width in pixels. */ | ||
| 10298 | xassert (it->current_x == 0); | ||
| 10299 | display_string (NULL, minibuf_prompt, Qnil, 0, 0, &ti, | ||
| 10300 | 0, 0, max_x, -1); | ||
| 10301 | minibuf_prompt_width = ti.hpos; | ||
| 10302 | minibuf_prompt_pixel_width = ti.current_x; | ||
| 10303 | |||
| 10304 | /* Transfer pixel and hpos information to IT. */ | ||
| 10305 | it->hpos = ti.hpos; | ||
| 10306 | it->current_x = ti.current_x; | ||
| 10307 | } | ||
| 10308 | } | ||
| 10309 | #endif /* NO_PROMPT_IN_BUFFER */ | ||
| 10310 | |||
| 10311 | /* Move over display elements that are not visible because we are | 10772 | /* Move over display elements that are not visible because we are |
| 10312 | hscrolled. This may stop at an x-position < IT->first_visible_x | 10773 | hscrolled. This may stop at an x-position < IT->first_visible_x |
| 10313 | if the first glyph is partially visible or if we hit a line end. */ | 10774 | if the first glyph is partially visible or if we hit a line end. */ |
| @@ -11174,7 +11635,6 @@ decode_mode_spec_coding (coding_system, buf, eol_flag) | |||
| 11174 | else if (INTEGERP (eoltype) | 11635 | else if (INTEGERP (eoltype) |
| 11175 | && CHAR_VALID_P (XINT (eoltype), 0)) | 11636 | && CHAR_VALID_P (XINT (eoltype), 0)) |
| 11176 | { | 11637 | { |
| 11177 | int c = XINT (eoltype); | ||
| 11178 | unsigned char work[4]; | 11638 | unsigned char work[4]; |
| 11179 | 11639 | ||
| 11180 | eol_str_len = CHAR_STRING (XINT (eoltype), work, eol_str); | 11640 | eol_str_len = CHAR_STRING (XINT (eoltype), work, eol_str); |
| @@ -11932,12 +12392,14 @@ invisible_ellipsis_p (propval, list) | |||
| 11932 | void | 12392 | void |
| 11933 | syms_of_xdisp () | 12393 | syms_of_xdisp () |
| 11934 | { | 12394 | { |
| 11935 | echo_area_message = previous_echo_area_message = Qnil; | 12395 | Vwith_echo_area_save_vector = Qnil; |
| 11936 | staticpro (&echo_area_message); | 12396 | staticpro (&Vwith_echo_area_save_vector); |
| 11937 | staticpro (&previous_echo_area_message); | ||
| 11938 | 12397 | ||
| 11939 | staticpro (&Qinhibit_redisplay); | 12398 | Vmessage_stack = Qnil; |
| 12399 | staticpro (&Vmessage_stack); | ||
| 12400 | |||
| 11940 | Qinhibit_redisplay = intern ("inhibit-redisplay"); | 12401 | Qinhibit_redisplay = intern ("inhibit-redisplay"); |
| 12402 | staticpro (&Qinhibit_redisplay); | ||
| 11941 | 12403 | ||
| 11942 | #if GLYPH_DEBUG | 12404 | #if GLYPH_DEBUG |
| 11943 | defsubr (&Sdump_glyph_matrix); | 12405 | defsubr (&Sdump_glyph_matrix); |
| @@ -12007,6 +12469,14 @@ syms_of_xdisp () | |||
| 12007 | staticpro (&last_arrow_string); | 12469 | staticpro (&last_arrow_string); |
| 12008 | last_arrow_position = Qnil; | 12470 | last_arrow_position = Qnil; |
| 12009 | last_arrow_string = Qnil; | 12471 | last_arrow_string = Qnil; |
| 12472 | |||
| 12473 | echo_buffer[0] = echo_buffer[1] = Qnil; | ||
| 12474 | staticpro (&echo_buffer[0]); | ||
| 12475 | staticpro (&echo_buffer[1]); | ||
| 12476 | |||
| 12477 | echo_area_buffer[0] = echo_area_buffer[1] = Qnil; | ||
| 12478 | staticpro (&echo_area_buffer[0]); | ||
| 12479 | staticpro (&echo_area_buffer[1]); | ||
| 12010 | 12480 | ||
| 12011 | DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace, | 12481 | DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace, |
| 12012 | "Non-nil means highlight trailing whitespace.\n\ | 12482 | "Non-nil means highlight trailing whitespace.\n\ |
| @@ -12162,6 +12632,12 @@ are displayed by converting them to the equivalent multibyte characters\n\ | |||
| 12162 | according to the current language environment. As a result, they are\n\ | 12632 | according to the current language environment. As a result, they are\n\ |
| 12163 | displayed according to the current fontset."); | 12633 | displayed according to the current fontset."); |
| 12164 | unibyte_display_via_language_environment = 0; | 12634 | unibyte_display_via_language_environment = 0; |
| 12635 | |||
| 12636 | DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height, | ||
| 12637 | "*Maximum height for resizing mini-windows.\n\ | ||
| 12638 | If a float, it specifies a fraction of the mini-window frame's height.\n\ | ||
| 12639 | If an integer, it specifies a number of lines."); | ||
| 12640 | Vmax_mini_window_height = make_float (0.25); | ||
| 12165 | } | 12641 | } |
| 12166 | 12642 | ||
| 12167 | 12643 | ||
| @@ -12178,10 +12654,6 @@ init_xdisp () | |||
| 12178 | mini_w = XWINDOW (minibuf_window); | 12654 | mini_w = XWINDOW (minibuf_window); |
| 12179 | root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w))); | 12655 | root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w))); |
| 12180 | 12656 | ||
| 12181 | echo_area_glyphs = 0; | ||
| 12182 | previous_echo_glyphs = 0; | ||
| 12183 | echo_area_message = previous_echo_area_message = Qnil; | ||
| 12184 | |||
| 12185 | if (!noninteractive) | 12657 | if (!noninteractive) |
| 12186 | { | 12658 | { |
| 12187 | struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window))); | 12659 | struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window))); |