diff options
| author | Richard M. Stallman | 1993-12-23 01:04:26 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1993-12-23 01:04:26 +0000 |
| commit | 90adcf2077e004798b3ace8195ba610cfc822a34 (patch) | |
| tree | 231f8f2c084115309ad31f7957c98454d6f34cdd /src | |
| parent | f58534a3faddd86cf1dea26195db461b16b1bbd8 (diff) | |
| download | emacs-90adcf2077e004798b3ace8195ba610cfc822a34.tar.gz emacs-90adcf2077e004798b3ace8195ba610cfc822a34.zip | |
(message): Use message2, not message1.
(display_string): Fix truncation-criterion after main loop
for termination due to LENGTH.
(echo_area_glyphs_length): New variable.
(message1): Set it.
(message2): New function.
(display_string): New arg LENGTH.
(echo_area_display): Pass new arg to display_string.
(redisplay_window): Likewise.
(display_text_line): Likewise.
(display_menu_bar): Likewise.
(display_mode_element): Likewise.
(update_menu_bar, update_menu_bars): New functions.
(prepare_menu_bars): New function.
(redisplay_window): Don't update menu bar here.
(display_menu_bar): Assume item list already updated.
(redisplay_window): Don't alter lpoint when w is
selected window in a non-selected frame.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 312 |
1 files changed, 255 insertions, 57 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 62542515496..bb007713f6e 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -124,6 +124,8 @@ static void echo_area_display (); | |||
| 124 | void mark_window_display_accurate (); | 124 | void mark_window_display_accurate (); |
| 125 | static void redisplay_windows (); | 125 | static void redisplay_windows (); |
| 126 | static void redisplay_window (); | 126 | static void redisplay_window (); |
| 127 | static void update_menu_bars (); | ||
| 128 | static void update_menu_bar (); | ||
| 127 | static void try_window (); | 129 | static void try_window (); |
| 128 | static int try_window_id (); | 130 | static int try_window_id (); |
| 129 | static struct position *display_text_line (); | 131 | static struct position *display_text_line (); |
| @@ -147,6 +149,9 @@ int minibuf_prompt_width; | |||
| 147 | It overrides the minibuf_prompt as well as the buffer. */ | 149 | It overrides the minibuf_prompt as well as the buffer. */ |
| 148 | char *echo_area_glyphs; | 150 | char *echo_area_glyphs; |
| 149 | 151 | ||
| 152 | /* This is the length of the message in echo_area_glyphs. */ | ||
| 153 | int echo_area_glyphs_length; | ||
| 154 | |||
| 150 | /* true iff we should redraw the mode lines on the next redisplay */ | 155 | /* true iff we should redraw the mode lines on the next redisplay */ |
| 151 | int update_mode_lines; | 156 | int update_mode_lines; |
| 152 | 157 | ||
| @@ -182,6 +187,7 @@ int line_number_display_limit; | |||
| 182 | 187 | ||
| 183 | /* Specify m, a string, as a message in the minibuf. If m is 0, clear out | 188 | /* Specify m, a string, as a message in the minibuf. If m is 0, clear out |
| 184 | any existing message, and let the minibuffer text show through. */ | 189 | any existing message, and let the minibuffer text show through. */ |
| 190 | |||
| 185 | void | 191 | void |
| 186 | message1 (m) | 192 | message1 (m) |
| 187 | char *m; | 193 | char *m; |
| @@ -214,7 +220,59 @@ message1 (m) | |||
| 214 | #endif | 220 | #endif |
| 215 | 221 | ||
| 216 | if (m) | 222 | if (m) |
| 217 | echo_area_glyphs = m; | 223 | { |
| 224 | echo_area_glyphs = m; | ||
| 225 | echo_area_glyphs_length = strlen (m); | ||
| 226 | } | ||
| 227 | else | ||
| 228 | echo_area_glyphs = previous_echo_glyphs = 0; | ||
| 229 | |||
| 230 | do_pending_window_change (); | ||
| 231 | echo_area_display (); | ||
| 232 | update_frame (XFRAME (XWINDOW (minibuf_window)->frame), 1, 1); | ||
| 233 | do_pending_window_change (); | ||
| 234 | } | ||
| 235 | } | ||
| 236 | |||
| 237 | /* Display an echo area message M with a specified length of LEN chars. | ||
| 238 | This way, null characters can be included. */ | ||
| 239 | |||
| 240 | void | ||
| 241 | message2 (m, len) | ||
| 242 | char *m; | ||
| 243 | int len; | ||
| 244 | { | ||
| 245 | if (noninteractive) | ||
| 246 | { | ||
| 247 | if (noninteractive_need_newline) | ||
| 248 | putc ('\n', stderr); | ||
| 249 | noninteractive_need_newline = 0; | ||
| 250 | fwrite (m, len, 1, stderr); | ||
| 251 | if (cursor_in_echo_area == 0) | ||
| 252 | fprintf (stderr, "\n"); | ||
| 253 | fflush (stderr); | ||
| 254 | } | ||
| 255 | /* A null message buffer means that the frame hasn't really been | ||
| 256 | initialized yet. Error messages get reported properly by | ||
| 257 | cmd_error, so this must be just an informative message; toss it. */ | ||
| 258 | else if (INTERACTIVE && FRAME_MESSAGE_BUF (selected_frame)) | ||
| 259 | { | ||
| 260 | #ifdef MULTI_FRAME | ||
| 261 | Lisp_Object minibuf_frame; | ||
| 262 | |||
| 263 | choose_minibuf_frame (); | ||
| 264 | minibuf_frame = WINDOW_FRAME (XWINDOW (minibuf_window)); | ||
| 265 | FRAME_SAMPLE_VISIBILITY (XFRAME (minibuf_frame)); | ||
| 266 | if (FRAME_VISIBLE_P (selected_frame) | ||
| 267 | && ! FRAME_VISIBLE_P (XFRAME (minibuf_frame))) | ||
| 268 | Fmake_frame_visible (WINDOW_FRAME (XWINDOW (minibuf_window))); | ||
| 269 | #endif | ||
| 270 | |||
| 271 | if (m) | ||
| 272 | { | ||
| 273 | echo_area_glyphs = m; | ||
| 274 | echo_area_glyphs_length = len; | ||
| 275 | } | ||
| 218 | else | 276 | else |
| 219 | echo_area_glyphs = previous_echo_glyphs = 0; | 277 | echo_area_glyphs = previous_echo_glyphs = 0; |
| 220 | 278 | ||
| @@ -269,22 +327,21 @@ message (m, a1, a2, a3) | |||
| 269 | { | 327 | { |
| 270 | if (m) | 328 | if (m) |
| 271 | { | 329 | { |
| 272 | { | 330 | int len; |
| 273 | #ifdef NO_ARG_ARRAY | 331 | #ifdef NO_ARG_ARRAY |
| 274 | int a[3]; | 332 | int a[3]; |
| 275 | a[0] = a1; | 333 | a[0] = a1; |
| 276 | a[1] = a2; | 334 | a[1] = a2; |
| 277 | a[2] = a3; | 335 | a[2] = a3; |
| 278 | 336 | ||
| 279 | doprnt (FRAME_MESSAGE_BUF (echo_frame), | 337 | len = doprnt (FRAME_MESSAGE_BUF (echo_frame), |
| 280 | FRAME_WIDTH (echo_frame), m, 0, 3, a); | 338 | FRAME_WIDTH (echo_frame), m, 0, 3, a); |
| 281 | #else | 339 | #else |
| 282 | doprnt (FRAME_MESSAGE_BUF (echo_frame), | 340 | len = doprnt (FRAME_MESSAGE_BUF (echo_frame), |
| 283 | FRAME_WIDTH (echo_frame), m, 0, 3, &a1); | 341 | FRAME_WIDTH (echo_frame), m, 0, 3, &a1); |
| 284 | #endif /* NO_ARG_ARRAY */ | 342 | #endif /* NO_ARG_ARRAY */ |
| 285 | } | ||
| 286 | 343 | ||
| 287 | message1 (FRAME_MESSAGE_BUF (echo_frame)); | 344 | message2 (FRAME_MESSAGE_BUF (echo_frame), len); |
| 288 | } | 345 | } |
| 289 | else | 346 | else |
| 290 | message1 (0); | 347 | message1 (0); |
| @@ -323,6 +380,7 @@ echo_area_display () | |||
| 323 | get_display_line (f, vpos, 0); | 380 | get_display_line (f, vpos, 0); |
| 324 | display_string (XWINDOW (minibuf_window), vpos, | 381 | display_string (XWINDOW (minibuf_window), vpos, |
| 325 | echo_area_glyphs ? echo_area_glyphs : "", | 382 | echo_area_glyphs ? echo_area_glyphs : "", |
| 383 | echo_area_glyphs ? echo_area_glyphs_length : -1, | ||
| 326 | 0, 0, 0, FRAME_WIDTH (f)); | 384 | 0, 0, 0, FRAME_WIDTH (f)); |
| 327 | 385 | ||
| 328 | /* If desired cursor location is on this line, put it at end of text */ | 386 | /* If desired cursor location is on this line, put it at end of text */ |
| @@ -338,7 +396,7 @@ echo_area_display () | |||
| 338 | { | 396 | { |
| 339 | get_display_line (f, i, 0); | 397 | get_display_line (f, i, 0); |
| 340 | display_string (XWINDOW (minibuf_window), vpos, | 398 | display_string (XWINDOW (minibuf_window), vpos, |
| 341 | "", 0, 0, 0, FRAME_WIDTH (f)); | 399 | "", 0, 0, 0, 0, FRAME_WIDTH (f)); |
| 342 | } | 400 | } |
| 343 | } | 401 | } |
| 344 | } | 402 | } |
| @@ -351,6 +409,77 @@ echo_area_display () | |||
| 351 | previous_echo_glyphs = echo_area_glyphs; | 409 | previous_echo_glyphs = echo_area_glyphs; |
| 352 | } | 410 | } |
| 353 | 411 | ||
| 412 | /* Prepare for redisplay by updating menu-bar item lists when appropriate. | ||
| 413 | This can't be done in `redisplay' itself because it can call eval. */ | ||
| 414 | |||
| 415 | void | ||
| 416 | prepare_menu_bars () | ||
| 417 | { | ||
| 418 | register struct window *w = XWINDOW (selected_window); | ||
| 419 | int all_windows; | ||
| 420 | |||
| 421 | if (noninteractive) | ||
| 422 | return; | ||
| 423 | |||
| 424 | /* Set the visible flags for all frames. | ||
| 425 | Do this before checking for resized or garbaged frames; they want | ||
| 426 | to know if their frames are visible. | ||
| 427 | See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */ | ||
| 428 | { | ||
| 429 | Lisp_Object tail, frame; | ||
| 430 | |||
| 431 | FOR_EACH_FRAME (tail, frame) | ||
| 432 | FRAME_SAMPLE_VISIBILITY (XFRAME (frame)); | ||
| 433 | } | ||
| 434 | |||
| 435 | /* Notice any pending interrupt request to change frame size. */ | ||
| 436 | do_pending_window_change (); | ||
| 437 | |||
| 438 | if (frame_garbaged) | ||
| 439 | { | ||
| 440 | redraw_garbaged_frames (); | ||
| 441 | frame_garbaged = 0; | ||
| 442 | } | ||
| 443 | |||
| 444 | if (clip_changed || windows_or_buffers_changed) | ||
| 445 | update_mode_lines++; | ||
| 446 | |||
| 447 | /* Detect case that we need to write a star in the mode line. */ | ||
| 448 | if (XFASTINT (w->last_modified) < MODIFF | ||
| 449 | && XFASTINT (w->last_modified) <= current_buffer->save_modified) | ||
| 450 | { | ||
| 451 | w->update_mode_line = Qt; | ||
| 452 | if (buffer_shared > 1) | ||
| 453 | update_mode_lines++; | ||
| 454 | } | ||
| 455 | |||
| 456 | all_windows = update_mode_lines || buffer_shared > 1; | ||
| 457 | |||
| 458 | /* If specs for an arrow have changed, do thorough redisplay | ||
| 459 | to ensure we remove any arrow that should no longer exist. */ | ||
| 460 | if (! EQ (Voverlay_arrow_position, last_arrow_position) | ||
| 461 | || ! EQ (Voverlay_arrow_string, last_arrow_string)) | ||
| 462 | all_windows = 1, clip_changed = 1; | ||
| 463 | |||
| 464 | /* Update the menu bar item lists, if appropriate. | ||
| 465 | This has to be done before any actual redisplay | ||
| 466 | or generation of display lines. */ | ||
| 467 | if (all_windows) | ||
| 468 | { | ||
| 469 | Lisp_Object tail, frame; | ||
| 470 | |||
| 471 | FOR_EACH_FRAME (tail, frame) | ||
| 472 | { | ||
| 473 | FRAME_PTR f = XFRAME (frame); | ||
| 474 | |||
| 475 | if (FRAME_VISIBLE_P (f)) | ||
| 476 | update_menu_bars (FRAME_ROOT_WINDOW (f)); | ||
| 477 | } | ||
| 478 | } | ||
| 479 | else if (FRAME_VISIBLE_P (selected_frame)) | ||
| 480 | update_menu_bar (selected_window); | ||
| 481 | } | ||
| 482 | |||
| 354 | /* Do a frame update, taking possible shortcuts into account. | 483 | /* Do a frame update, taking possible shortcuts into account. |
| 355 | This is the main external entry point for redisplay. | 484 | This is the main external entry point for redisplay. |
| 356 | 485 | ||
| @@ -358,11 +487,14 @@ echo_area_display () | |||
| 358 | message is no longer requested, we clear the echo area | 487 | message is no longer requested, we clear the echo area |
| 359 | or bring back the minibuffer if that is in use. | 488 | or bring back the minibuffer if that is in use. |
| 360 | 489 | ||
| 361 | Everyone would like to have a hook here to call eval, | 490 | Do not call eval from within this function. |
| 362 | but that cannot be done safely without a lot of changes elsewhere. | 491 | Calls to eval after the call to echo_area_display would confuse |
| 363 | This can be called from signal handlers; with alarms set up; | 492 | the display_line mechanism and would cause a crash. |
| 493 | Calls to eval before that point will work most of the time, | ||
| 494 | but can still lose, because this function | ||
| 495 | can be called from signal handlers; with alarms set up; | ||
| 364 | or with synchronous processes running. | 496 | or with synchronous processes running. |
| 365 | See the function `echo' in keyboard.c. | 497 | |
| 366 | See Fcall_process; if you called it from here, it could be | 498 | See Fcall_process; if you called it from here, it could be |
| 367 | entered recursively. */ | 499 | entered recursively. */ |
| 368 | 500 | ||
| @@ -400,16 +532,6 @@ redisplay () | |||
| 400 | frame_garbaged = 0; | 532 | frame_garbaged = 0; |
| 401 | } | 533 | } |
| 402 | 534 | ||
| 403 | /* Normally the message* functions will have already displayed and | ||
| 404 | updated the echo area, but the frame may have been trashed, or | ||
| 405 | the update may have been preempted, so display the echo area | ||
| 406 | again here. */ | ||
| 407 | if (echo_area_glyphs || previous_echo_glyphs) | ||
| 408 | { | ||
| 409 | echo_area_display (); | ||
| 410 | must_finish = 1; | ||
| 411 | } | ||
| 412 | |||
| 413 | if (clip_changed || windows_or_buffers_changed) | 535 | if (clip_changed || windows_or_buffers_changed) |
| 414 | update_mode_lines++; | 536 | update_mode_lines++; |
| 415 | 537 | ||
| @@ -432,6 +554,16 @@ redisplay () | |||
| 432 | || ! EQ (Voverlay_arrow_string, last_arrow_string)) | 554 | || ! EQ (Voverlay_arrow_string, last_arrow_string)) |
| 433 | all_windows = 1, clip_changed = 1; | 555 | all_windows = 1, clip_changed = 1; |
| 434 | 556 | ||
| 557 | /* Normally the message* functions will have already displayed and | ||
| 558 | updated the echo area, but the frame may have been trashed, or | ||
| 559 | the update may have been preempted, so display the echo area | ||
| 560 | again here. */ | ||
| 561 | if (echo_area_glyphs || previous_echo_glyphs) | ||
| 562 | { | ||
| 563 | echo_area_display (); | ||
| 564 | must_finish = 1; | ||
| 565 | } | ||
| 566 | |||
| 435 | /* If showing region, and mark has changed, must redisplay whole window. */ | 567 | /* If showing region, and mark has changed, must redisplay whole window. */ |
| 436 | if (((!NILP (Vtransient_mark_mode) | 568 | if (((!NILP (Vtransient_mark_mode) |
| 437 | && !NILP (XBUFFER (w->buffer)->mark_active)) | 569 | && !NILP (XBUFFER (w->buffer)->mark_active)) |
| @@ -752,8 +884,78 @@ mark_window_display_accurate (window, flag) | |||
| 752 | } | 884 | } |
| 753 | } | 885 | } |
| 754 | 886 | ||
| 887 | /* Update the menu bar item lists for WINDOW | ||
| 888 | and its subwindows and siblings. | ||
| 889 | This has to be done before we start to fill in any display lines, | ||
| 890 | because it can call eval. */ | ||
| 891 | |||
| 892 | static void | ||
| 893 | update_menu_bars (window) | ||
| 894 | Lisp_Object window; | ||
| 895 | { | ||
| 896 | for (; !NILP (window); window = XWINDOW (window)->next) | ||
| 897 | update_menu_bar (window, 0); | ||
| 898 | } | ||
| 899 | |||
| 900 | /* Update the menu bar item list for window WINDOW and its subwindows. */ | ||
| 901 | |||
| 902 | static void | ||
| 903 | update_menu_bar (window, just_this_one) | ||
| 904 | Lisp_Object window; | ||
| 905 | int just_this_one; | ||
| 906 | { | ||
| 907 | register struct window *w = XWINDOW (window); | ||
| 908 | struct buffer *old = current_buffer; | ||
| 909 | FRAME_PTR f = XFRAME (WINDOW_FRAME (w)); | ||
| 910 | |||
| 911 | /* If this is a combination window, do its children; that's all. */ | ||
| 912 | |||
| 913 | if (!NILP (w->vchild)) | ||
| 914 | { | ||
| 915 | update_menu_bars (w->vchild); | ||
| 916 | return; | ||
| 917 | } | ||
| 918 | if (!NILP (w->hchild)) | ||
| 919 | { | ||
| 920 | update_menu_bars (w->hchild); | ||
| 921 | return; | ||
| 922 | } | ||
| 923 | if (NILP (w->buffer)) | ||
| 924 | abort (); | ||
| 925 | |||
| 926 | if (update_mode_lines) | ||
| 927 | w->update_mode_line = Qt; | ||
| 928 | |||
| 929 | /* When we reach a frame's selected window, redo the frame's menu bar. */ | ||
| 930 | if (!NILP (w->update_mode_line) | ||
| 931 | && FRAME_MENU_BAR_LINES (f) > 0 | ||
| 932 | && EQ (FRAME_SELECTED_WINDOW (f), window)) | ||
| 933 | { | ||
| 934 | /* If the user has switched buffers or windows, we need to | ||
| 935 | recompute to reflect the new bindings. But we'll | ||
| 936 | recompute when update_mode_lines is set too; that means | ||
| 937 | that people can use force-mode-line-update to request | ||
| 938 | that the menu bar be recomputed. The adverse effect on | ||
| 939 | the rest of the redisplay algorithm is about the same as | ||
| 940 | windows_or_buffers_changed anyway. */ | ||
| 941 | if (windows_or_buffers_changed | ||
| 942 | || update_mode_lines | ||
| 943 | || (XFASTINT (w->last_modified) < MODIFF | ||
| 944 | && (XFASTINT (w->last_modified) | ||
| 945 | <= XBUFFER (w->buffer)->save_modified))) | ||
| 946 | { | ||
| 947 | struct buffer *prev = current_buffer; | ||
| 948 | current_buffer = XBUFFER (w->buffer); | ||
| 949 | FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (); | ||
| 950 | current_buffer = prev; | ||
| 951 | } | ||
| 952 | } | ||
| 953 | } | ||
| 954 | |||
| 755 | int do_id = 1; | 955 | int do_id = 1; |
| 756 | 956 | ||
| 957 | /* Redisplay WINDOW and its subwindows and siblings. */ | ||
| 958 | |||
| 757 | static void | 959 | static void |
| 758 | redisplay_windows (window) | 960 | redisplay_windows (window) |
| 759 | Lisp_Object window; | 961 | Lisp_Object window; |
| @@ -762,6 +964,8 @@ redisplay_windows (window) | |||
| 762 | redisplay_window (window, 0); | 964 | redisplay_window (window, 0); |
| 763 | } | 965 | } |
| 764 | 966 | ||
| 967 | /* Redisplay window WINDOW and its subwindows. */ | ||
| 968 | |||
| 765 | static void | 969 | static void |
| 766 | redisplay_window (window, just_this_one) | 970 | redisplay_window (window, just_this_one) |
| 767 | Lisp_Object window; | 971 | Lisp_Object window; |
| @@ -817,7 +1021,7 @@ redisplay_window (window, just_this_one) | |||
| 817 | for (i = 0; i < height; i++) | 1021 | for (i = 0; i < height; i++) |
| 818 | { | 1022 | { |
| 819 | get_display_line (f, vpos + i, 0); | 1023 | get_display_line (f, vpos + i, 0); |
| 820 | display_string (w, vpos + i, "", 0, 0, 0, width); | 1024 | display_string (w, vpos + i, "", 0, 0, 0, 0, width); |
| 821 | } | 1025 | } |
| 822 | 1026 | ||
| 823 | goto finish_scroll_bars; | 1027 | goto finish_scroll_bars; |
| @@ -887,7 +1091,7 @@ redisplay_window (window, just_this_one) | |||
| 887 | - (1 << (SHORTBITS - 1)), | 1091 | - (1 << (SHORTBITS - 1)), |
| 888 | width, hscroll, pos_tab_offset (w, startp)); | 1092 | width, hscroll, pos_tab_offset (w, startp)); |
| 889 | SET_PT (pos.bufpos); | 1093 | SET_PT (pos.bufpos); |
| 890 | if (w != XWINDOW (FRAME_SELECTED_WINDOW (f))) | 1094 | if (w != XWINDOW (selected_window)) |
| 891 | Fset_marker (w->pointm, make_number (point), Qnil); | 1095 | Fset_marker (w->pointm, make_number (point), Qnil); |
| 892 | else | 1096 | else |
| 893 | { | 1097 | { |
| @@ -1765,7 +1969,7 @@ display_text_line (w, start, vpos, hpos, taboffset) | |||
| 1765 | && vpos == XFASTINT (w->top)) | 1969 | && vpos == XFASTINT (w->top)) |
| 1766 | { | 1970 | { |
| 1767 | if (minibuf_prompt) | 1971 | if (minibuf_prompt) |
| 1768 | hpos = display_string (w, vpos, minibuf_prompt, hpos, | 1972 | hpos = display_string (w, vpos, minibuf_prompt, -1, hpos, |
| 1769 | (!truncate ? continuer : truncator), | 1973 | (!truncate ? continuer : truncator), |
| 1770 | -1, -1); | 1974 | -1, -1); |
| 1771 | minibuf_prompt_width = hpos; | 1975 | minibuf_prompt_width = hpos; |
| @@ -2149,25 +2353,6 @@ display_menu_bar (w) | |||
| 2149 | 2353 | ||
| 2150 | get_display_line (f, vpos, 0); | 2354 | get_display_line (f, vpos, 0); |
| 2151 | 2355 | ||
| 2152 | /* If the user has switched buffers or windows, we need to | ||
| 2153 | recompute to reflect the new bindings. But we'll | ||
| 2154 | recompute when update_mode_lines is set too; that means | ||
| 2155 | that people can use force-mode-line-update to request | ||
| 2156 | that the menu bar be recomputed. The adverse effect on | ||
| 2157 | the rest of the redisplay algorithm is about the same as | ||
| 2158 | windows_or_buffers_changed anyway. */ | ||
| 2159 | if (windows_or_buffers_changed | ||
| 2160 | || update_mode_lines | ||
| 2161 | || (XFASTINT (w->last_modified) < MODIFF | ||
| 2162 | && (XFASTINT (w->last_modified) | ||
| 2163 | <= XBUFFER (w->buffer)->save_modified))) | ||
| 2164 | { | ||
| 2165 | struct buffer *prev = current_buffer; | ||
| 2166 | current_buffer = XBUFFER (w->buffer); | ||
| 2167 | FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (); | ||
| 2168 | current_buffer = prev; | ||
| 2169 | } | ||
| 2170 | |||
| 2171 | for (tail = FRAME_MENU_BAR_ITEMS (f); CONSP (tail); tail = XCONS (tail)->cdr) | 2356 | for (tail = FRAME_MENU_BAR_ITEMS (f); CONSP (tail); tail = XCONS (tail)->cdr) |
| 2172 | { | 2357 | { |
| 2173 | Lisp_Object string; | 2358 | Lisp_Object string; |
| @@ -2180,12 +2365,13 @@ display_menu_bar (w) | |||
| 2180 | if (hpos < maxendcol) | 2365 | if (hpos < maxendcol) |
| 2181 | hpos = display_string (XWINDOW (FRAME_ROOT_WINDOW (f)), vpos, | 2366 | hpos = display_string (XWINDOW (FRAME_ROOT_WINDOW (f)), vpos, |
| 2182 | XSTRING (string)->data, | 2367 | XSTRING (string)->data, |
| 2368 | XSTRING (string)->size, | ||
| 2183 | hpos, 0, hpos, maxendcol); | 2369 | hpos, 0, hpos, maxendcol); |
| 2184 | /* Put a gap of 3 spaces between items. */ | 2370 | /* Put a gap of 3 spaces between items. */ |
| 2185 | if (hpos < maxendcol) | 2371 | if (hpos < maxendcol) |
| 2186 | { | 2372 | { |
| 2187 | int hpos1 = hpos + 3; | 2373 | int hpos1 = hpos + 3; |
| 2188 | hpos = display_string (w, vpos, "", hpos, 0, | 2374 | hpos = display_string (w, vpos, "", 0, hpos, 0, |
| 2189 | min (hpos1, maxendcol), maxendcol); | 2375 | min (hpos1, maxendcol), maxendcol); |
| 2190 | } | 2376 | } |
| 2191 | } | 2377 | } |
| @@ -2195,7 +2381,7 @@ display_menu_bar (w) | |||
| 2195 | 2381 | ||
| 2196 | /* Fill out the line with spaces. */ | 2382 | /* Fill out the line with spaces. */ |
| 2197 | if (maxendcol > hpos) | 2383 | if (maxendcol > hpos) |
| 2198 | hpos = display_string (w, vpos, "", hpos, 0, maxendcol, -1); | 2384 | hpos = display_string (w, vpos, "", 0, hpos, 0, maxendcol, -1); |
| 2199 | 2385 | ||
| 2200 | /* Clear the rest of the lines allocated to the menu bar. */ | 2386 | /* Clear the rest of the lines allocated to the menu bar. */ |
| 2201 | vpos++; | 2387 | vpos++; |
| @@ -2311,7 +2497,7 @@ display_mode_element (w, vpos, hpos, depth, minendcol, maxendcol, elt) | |||
| 2311 | if (this - 1 != last) | 2497 | if (this - 1 != last) |
| 2312 | { | 2498 | { |
| 2313 | register int lim = --this - last + hpos; | 2499 | register int lim = --this - last + hpos; |
| 2314 | hpos = display_string (w, vpos, last, hpos, 0, hpos, | 2500 | hpos = display_string (w, vpos, last, -1, hpos, 0, hpos, |
| 2315 | min (lim, maxendcol)); | 2501 | min (lim, maxendcol)); |
| 2316 | } | 2502 | } |
| 2317 | else /* c == '%' */ | 2503 | else /* c == '%' */ |
| @@ -2340,6 +2526,7 @@ display_mode_element (w, vpos, hpos, depth, minendcol, maxendcol, elt) | |||
| 2340 | hpos = display_string (w, vpos, | 2526 | hpos = display_string (w, vpos, |
| 2341 | decode_mode_spec (w, c, | 2527 | decode_mode_spec (w, c, |
| 2342 | maxendcol - hpos), | 2528 | maxendcol - hpos), |
| 2529 | -1, | ||
| 2343 | hpos, 0, spec_width, maxendcol); | 2530 | hpos, 0, spec_width, maxendcol); |
| 2344 | } | 2531 | } |
| 2345 | } | 2532 | } |
| @@ -2361,6 +2548,7 @@ display_mode_element (w, vpos, hpos, depth, minendcol, maxendcol, elt) | |||
| 2361 | don't check for % within it. */ | 2548 | don't check for % within it. */ |
| 2362 | if (XTYPE (tem) == Lisp_String) | 2549 | if (XTYPE (tem) == Lisp_String) |
| 2363 | hpos = display_string (w, vpos, XSTRING (tem)->data, | 2550 | hpos = display_string (w, vpos, XSTRING (tem)->data, |
| 2551 | XSTRING (tem)->size, | ||
| 2364 | hpos, 0, minendcol, maxendcol); | 2552 | hpos, 0, minendcol, maxendcol); |
| 2365 | /* Give up right away for nil or t. */ | 2553 | /* Give up right away for nil or t. */ |
| 2366 | else if (!EQ (tem, elt)) | 2554 | else if (!EQ (tem, elt)) |
| @@ -2450,13 +2638,13 @@ display_mode_element (w, vpos, hpos, depth, minendcol, maxendcol, elt) | |||
| 2450 | 2638 | ||
| 2451 | default: | 2639 | default: |
| 2452 | invalid: | 2640 | invalid: |
| 2453 | return (display_string (w, vpos, "*invalid*", hpos, 0, | 2641 | return (display_string (w, vpos, "*invalid*", -1, hpos, 0, |
| 2454 | minendcol, maxendcol)); | 2642 | minendcol, maxendcol)); |
| 2455 | } | 2643 | } |
| 2456 | 2644 | ||
| 2457 | end: | 2645 | end: |
| 2458 | if (minendcol > hpos) | 2646 | if (minendcol > hpos) |
| 2459 | hpos = display_string (w, vpos, "", hpos, 0, minendcol, -1); | 2647 | hpos = display_string (w, vpos, "", 0, hpos, 0, minendcol, -1); |
| 2460 | return hpos; | 2648 | return hpos; |
| 2461 | } | 2649 | } |
| 2462 | 2650 | ||
| @@ -2733,6 +2921,7 @@ display_count_lines (from, limit, n, pos_ptr) | |||
| 2733 | /* Display STRING on one line of window W, starting at HPOS. | 2921 | /* Display STRING on one line of window W, starting at HPOS. |
| 2734 | Display at position VPOS. Caller should have done get_display_line. | 2922 | Display at position VPOS. Caller should have done get_display_line. |
| 2735 | If VPOS == -1, display it as the current frame's title. | 2923 | If VPOS == -1, display it as the current frame's title. |
| 2924 | LENGTH is the length of STRING, or -1 meaning STRING is null-terminated. | ||
| 2736 | 2925 | ||
| 2737 | TRUNCATE is GLYPH to display at end if truncated. Zero for none. | 2926 | TRUNCATE is GLYPH to display at end if truncated. Zero for none. |
| 2738 | 2927 | ||
| @@ -2746,9 +2935,10 @@ display_count_lines (from, limit, n, pos_ptr) | |||
| 2746 | Returns ending hpos */ | 2935 | Returns ending hpos */ |
| 2747 | 2936 | ||
| 2748 | static int | 2937 | static int |
| 2749 | display_string (w, vpos, string, hpos, truncate, mincol, maxcol) | 2938 | display_string (w, vpos, string, length, hpos, truncate, mincol, maxcol) |
| 2750 | struct window *w; | 2939 | struct window *w; |
| 2751 | unsigned char *string; | 2940 | unsigned char *string; |
| 2941 | int length; | ||
| 2752 | int vpos, hpos; | 2942 | int vpos, hpos; |
| 2753 | GLYPH truncate; | 2943 | GLYPH truncate; |
| 2754 | int mincol, maxcol; | 2944 | int mincol, maxcol; |
| @@ -2798,8 +2988,16 @@ display_string (w, vpos, string, hpos, truncate, mincol, maxcol) | |||
| 2798 | 2988 | ||
| 2799 | while (p1 < end) | 2989 | while (p1 < end) |
| 2800 | { | 2990 | { |
| 2991 | if (length == 0) | ||
| 2992 | break; | ||
| 2801 | c = *string++; | 2993 | c = *string++; |
| 2802 | if (!c) break; | 2994 | /* Specified length. */ |
| 2995 | if (length >= 0) | ||
| 2996 | length--; | ||
| 2997 | /* Unspecified length (null-terminated string). */ | ||
| 2998 | else if (c == 0) | ||
| 2999 | break; | ||
| 3000 | |||
| 2803 | if (c >= 040 && c < 0177 | 3001 | if (c >= 040 && c < 0177 |
| 2804 | && (dp == 0 || XTYPE (DISP_CHAR_VECTOR (dp, c)) != Lisp_Vector)) | 3002 | && (dp == 0 || XTYPE (DISP_CHAR_VECTOR (dp, c)) != Lisp_Vector)) |
| 2805 | { | 3003 | { |
| @@ -2847,7 +3045,7 @@ display_string (w, vpos, string, hpos, truncate, mincol, maxcol) | |||
| 2847 | } | 3045 | } |
| 2848 | } | 3046 | } |
| 2849 | 3047 | ||
| 2850 | if (c) | 3048 | if (c && length > 0) |
| 2851 | { | 3049 | { |
| 2852 | p1 = end; | 3050 | p1 = end; |
| 2853 | if (truncate) *p1++ = truncate; | 3051 | if (truncate) *p1++ = truncate; |