diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 432 |
1 files changed, 263 insertions, 169 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index b20c4815abc..167b4afadaa 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -843,8 +843,8 @@ static struct text_pos run_window_scroll_functions P_ ((Lisp_Object, | |||
| 843 | struct text_pos)); | 843 | struct text_pos)); |
| 844 | static void reconsider_clip_changes P_ ((struct window *, struct buffer *)); | 844 | static void reconsider_clip_changes P_ ((struct window *, struct buffer *)); |
| 845 | static int text_outside_line_unchanged_p P_ ((struct window *, int, int)); | 845 | static int text_outside_line_unchanged_p P_ ((struct window *, int, int)); |
| 846 | static void store_frame_title_char P_ ((char)); | 846 | static void store_mode_line_noprop_char P_ ((char)); |
| 847 | static int store_frame_title P_ ((const unsigned char *, int, int)); | 847 | static int store_mode_line_noprop P_ ((const unsigned char *, int, int)); |
| 848 | static void x_consider_frame_title P_ ((Lisp_Object)); | 848 | static void x_consider_frame_title P_ ((Lisp_Object)); |
| 849 | static void handle_stop P_ ((struct it *)); | 849 | static void handle_stop P_ ((struct it *)); |
| 850 | static int tool_bar_lines_needed P_ ((struct frame *)); | 850 | static int tool_bar_lines_needed P_ ((struct frame *)); |
| @@ -8159,52 +8159,123 @@ echo_area_display (update_frame_p) | |||
| 8159 | 8159 | ||
| 8160 | 8160 | ||
| 8161 | /*********************************************************************** | 8161 | /*********************************************************************** |
| 8162 | Frame Titles | 8162 | Mode Lines and Frame Titles |
| 8163 | ***********************************************************************/ | 8163 | ***********************************************************************/ |
| 8164 | 8164 | ||
| 8165 | /* A buffer for constructing non-propertized mode-line strings and | ||
| 8166 | frame titles in it; allocated from the heap in init_xdisp and | ||
| 8167 | resized as needed in store_mode_line_noprop_char. */ | ||
| 8165 | 8168 | ||
| 8166 | /* The frame title buffering code is also used by Fformat_mode_line. | 8169 | static char *mode_line_noprop_buf; |
| 8167 | So it is not conditioned by HAVE_WINDOW_SYSTEM. */ | ||
| 8168 | 8170 | ||
| 8169 | /* A buffer for constructing frame titles in it; allocated from the | 8171 | /* The buffer's end, and a current output position in it. */ |
| 8170 | heap in init_xdisp and resized as needed in store_frame_title_char. */ | ||
| 8171 | 8172 | ||
| 8172 | static char *frame_title_buf; | 8173 | static char *mode_line_noprop_buf_end; |
| 8174 | static char *mode_line_noprop_ptr; | ||
| 8173 | 8175 | ||
| 8174 | /* The buffer's end, and a current output position in it. */ | 8176 | static enum { |
| 8177 | MODE_LINE_DISPLAY = 0, | ||
| 8178 | MODE_LINE_TITLE, | ||
| 8179 | MODE_LINE_NOPROP, | ||
| 8180 | MODE_LINE_STRING | ||
| 8181 | } mode_line_target; | ||
| 8182 | |||
| 8183 | /* Alist that caches the results of :propertize. | ||
| 8184 | Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */ | ||
| 8185 | static Lisp_Object mode_line_proptrans_alist; | ||
| 8186 | |||
| 8187 | /* List of strings making up the mode-line. */ | ||
| 8188 | static Lisp_Object mode_line_string_list; | ||
| 8189 | |||
| 8190 | /* Base face property when building propertized mode line string. */ | ||
| 8191 | static Lisp_Object mode_line_string_face; | ||
| 8192 | static Lisp_Object mode_line_string_face_prop; | ||
| 8193 | |||
| 8194 | |||
| 8195 | /* Unwind data for mode line strings */ | ||
| 8196 | |||
| 8197 | static Lisp_Object Vmode_line_unwind_vector; | ||
| 8198 | |||
| 8199 | static Lisp_Object | ||
| 8200 | format_mode_line_unwind_data (obuf) | ||
| 8201 | struct buffer *obuf; | ||
| 8202 | { | ||
| 8203 | int i = 0; | ||
| 8204 | Lisp_Object vector; | ||
| 8205 | |||
| 8206 | /* Reduce consing by keeping one vector in | ||
| 8207 | Vwith_echo_area_save_vector. */ | ||
| 8208 | vector = Vmode_line_unwind_vector; | ||
| 8209 | Vmode_line_unwind_vector = Qnil; | ||
| 8210 | |||
| 8211 | if (NILP (vector)) | ||
| 8212 | vector = Fmake_vector (make_number (7), Qnil); | ||
| 8213 | |||
| 8214 | AREF (vector, 0) = make_number (mode_line_target); | ||
| 8215 | AREF (vector, 1) = make_number (mode_line_noprop_ptr - mode_line_noprop_buf); | ||
| 8216 | AREF (vector, 2) = mode_line_string_list; | ||
| 8217 | AREF (vector, 3) = mode_line_proptrans_alist; | ||
| 8218 | AREF (vector, 4) = mode_line_string_face; | ||
| 8219 | AREF (vector, 5) = mode_line_string_face_prop; | ||
| 8220 | |||
| 8221 | if (obuf) | ||
| 8222 | XSETBUFFER (AREF (vector, 6), obuf); | ||
| 8223 | else | ||
| 8224 | AREF (vector, 6) = Qnil; | ||
| 8225 | |||
| 8226 | return vector; | ||
| 8227 | } | ||
| 8228 | |||
| 8229 | static Lisp_Object | ||
| 8230 | unwind_format_mode_line (vector) | ||
| 8231 | Lisp_Object vector; | ||
| 8232 | { | ||
| 8233 | mode_line_target = XINT (AREF (vector, 0)); | ||
| 8234 | mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1)); | ||
| 8235 | mode_line_string_list = AREF (vector, 2); | ||
| 8236 | mode_line_proptrans_alist = AREF (vector, 3); | ||
| 8237 | mode_line_string_face = AREF (vector, 4); | ||
| 8238 | mode_line_string_face_prop = AREF (vector, 5); | ||
| 8175 | 8239 | ||
| 8176 | static char *frame_title_buf_end; | 8240 | if (!NILP (AREF (vector, 6))) |
| 8177 | static char *frame_title_ptr; | 8241 | { |
| 8242 | set_buffer_internal_1 (XBUFFER (AREF (vector, 6))); | ||
| 8243 | AREF (vector, 6) = Qnil; | ||
| 8244 | } | ||
| 8178 | 8245 | ||
| 8246 | Vmode_line_unwind_vector = vector; | ||
| 8247 | return Qnil; | ||
| 8248 | } | ||
| 8179 | 8249 | ||
| 8180 | /* Store a single character C for the frame title in frame_title_buf. | 8250 | |
| 8181 | Re-allocate frame_title_buf if necessary. */ | 8251 | /* Store a single character C for the frame title in mode_line_noprop_buf. |
| 8252 | Re-allocate mode_line_noprop_buf if necessary. */ | ||
| 8182 | 8253 | ||
| 8183 | static void | 8254 | static void |
| 8184 | #ifdef PROTOTYPES | 8255 | #ifdef PROTOTYPES |
| 8185 | store_frame_title_char (char c) | 8256 | store_mode_line_noprop_char (char c) |
| 8186 | #else | 8257 | #else |
| 8187 | store_frame_title_char (c) | 8258 | store_mode_line_noprop_char (c) |
| 8188 | char c; | 8259 | char c; |
| 8189 | #endif | 8260 | #endif |
| 8190 | { | 8261 | { |
| 8191 | /* If output position has reached the end of the allocated buffer, | 8262 | /* If output position has reached the end of the allocated buffer, |
| 8192 | double the buffer's size. */ | 8263 | double the buffer's size. */ |
| 8193 | if (frame_title_ptr == frame_title_buf_end) | 8264 | if (mode_line_noprop_ptr == mode_line_noprop_buf_end) |
| 8194 | { | 8265 | { |
| 8195 | int len = frame_title_ptr - frame_title_buf; | 8266 | int len = mode_line_noprop_ptr - mode_line_noprop_buf; |
| 8196 | int new_size = 2 * len * sizeof *frame_title_buf; | 8267 | int new_size = 2 * len * sizeof *mode_line_noprop_buf; |
| 8197 | frame_title_buf = (char *) xrealloc (frame_title_buf, new_size); | 8268 | mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size); |
| 8198 | frame_title_buf_end = frame_title_buf + new_size; | 8269 | mode_line_noprop_buf_end = mode_line_noprop_buf + new_size; |
| 8199 | frame_title_ptr = frame_title_buf + len; | 8270 | mode_line_noprop_ptr = mode_line_noprop_buf + len; |
| 8200 | } | 8271 | } |
| 8201 | 8272 | ||
| 8202 | *frame_title_ptr++ = c; | 8273 | *mode_line_noprop_ptr++ = c; |
| 8203 | } | 8274 | } |
| 8204 | 8275 | ||
| 8205 | 8276 | ||
| 8206 | /* Store part of a frame title in frame_title_buf, beginning at | 8277 | /* Store part of a frame title in mode_line_noprop_buf, beginning at |
| 8207 | frame_title_ptr. STR is the string to store. Do not copy | 8278 | mode_line_noprop_ptr. STR is the string to store. Do not copy |
| 8208 | characters that yield more columns than PRECISION; PRECISION <= 0 | 8279 | characters that yield more columns than PRECISION; PRECISION <= 0 |
| 8209 | means copy the whole string. Pad with spaces until FIELD_WIDTH | 8280 | means copy the whole string. Pad with spaces until FIELD_WIDTH |
| 8210 | number of characters have been copied; FIELD_WIDTH <= 0 means don't | 8281 | number of characters have been copied; FIELD_WIDTH <= 0 means don't |
| @@ -8212,7 +8283,7 @@ store_frame_title_char (c) | |||
| 8212 | frame title. */ | 8283 | frame title. */ |
| 8213 | 8284 | ||
| 8214 | static int | 8285 | static int |
| 8215 | store_frame_title (str, field_width, precision) | 8286 | store_mode_line_noprop (str, field_width, precision) |
| 8216 | const unsigned char *str; | 8287 | const unsigned char *str; |
| 8217 | int field_width, precision; | 8288 | int field_width, precision; |
| 8218 | { | 8289 | { |
| @@ -8223,19 +8294,23 @@ store_frame_title (str, field_width, precision) | |||
| 8223 | nbytes = strlen (str); | 8294 | nbytes = strlen (str); |
| 8224 | n += c_string_width (str, nbytes, precision, &dummy, &nbytes); | 8295 | n += c_string_width (str, nbytes, precision, &dummy, &nbytes); |
| 8225 | while (nbytes--) | 8296 | while (nbytes--) |
| 8226 | store_frame_title_char (*str++); | 8297 | store_mode_line_noprop_char (*str++); |
| 8227 | 8298 | ||
| 8228 | /* Fill up with spaces until FIELD_WIDTH reached. */ | 8299 | /* Fill up with spaces until FIELD_WIDTH reached. */ |
| 8229 | while (field_width > 0 | 8300 | while (field_width > 0 |
| 8230 | && n < field_width) | 8301 | && n < field_width) |
| 8231 | { | 8302 | { |
| 8232 | store_frame_title_char (' '); | 8303 | store_mode_line_noprop_char (' '); |
| 8233 | ++n; | 8304 | ++n; |
| 8234 | } | 8305 | } |
| 8235 | 8306 | ||
| 8236 | return n; | 8307 | return n; |
| 8237 | } | 8308 | } |
| 8238 | 8309 | ||
| 8310 | /*********************************************************************** | ||
| 8311 | Frame Titles | ||
| 8312 | ***********************************************************************/ | ||
| 8313 | |||
| 8239 | #ifdef HAVE_WINDOW_SYSTEM | 8314 | #ifdef HAVE_WINDOW_SYSTEM |
| 8240 | 8315 | ||
| 8241 | /* Set the title of FRAME, if it has changed. The title format is | 8316 | /* Set the title of FRAME, if it has changed. The title format is |
| @@ -8255,9 +8330,10 @@ x_consider_frame_title (frame) | |||
| 8255 | /* Do we have more than one visible frame on this X display? */ | 8330 | /* Do we have more than one visible frame on this X display? */ |
| 8256 | Lisp_Object tail; | 8331 | Lisp_Object tail; |
| 8257 | Lisp_Object fmt; | 8332 | Lisp_Object fmt; |
| 8258 | struct buffer *obuf; | 8333 | char *title_start; |
| 8259 | int len; | 8334 | int len; |
| 8260 | struct it it; | 8335 | struct it it; |
| 8336 | int count = SPECPDL_INDEX (); | ||
| 8261 | 8337 | ||
| 8262 | for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) | 8338 | for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) |
| 8263 | { | 8339 | { |
| @@ -8276,18 +8352,22 @@ x_consider_frame_title (frame) | |||
| 8276 | multiple_frames = CONSP (tail); | 8352 | multiple_frames = CONSP (tail); |
| 8277 | 8353 | ||
| 8278 | /* Switch to the buffer of selected window of the frame. Set up | 8354 | /* Switch to the buffer of selected window of the frame. Set up |
| 8279 | frame_title_ptr so that display_mode_element will output into it; | 8355 | mode_line_noprop_ptr so that display_mode_element will output into it; |
| 8280 | then display the title. */ | 8356 | then display the title. */ |
| 8281 | obuf = current_buffer; | 8357 | record_unwind_protect (unwind_format_mode_line, |
| 8358 | format_mode_line_unwind_data (current_buffer)); | ||
| 8359 | |||
| 8282 | set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer)); | 8360 | set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer)); |
| 8283 | fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format; | 8361 | fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format; |
| 8284 | frame_title_ptr = frame_title_buf; | 8362 | |
| 8363 | mode_line_target = MODE_LINE_TITLE; | ||
| 8364 | title_start = mode_line_noprop_ptr; | ||
| 8285 | init_iterator (&it, XWINDOW (f->selected_window), -1, -1, | 8365 | init_iterator (&it, XWINDOW (f->selected_window), -1, -1, |
| 8286 | NULL, DEFAULT_FACE_ID); | 8366 | NULL, DEFAULT_FACE_ID); |
| 8287 | display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0); | 8367 | display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0); |
| 8288 | len = frame_title_ptr - frame_title_buf; | 8368 | len = mode_line_noprop_ptr - title_start; |
| 8289 | frame_title_ptr = NULL; | 8369 | |
| 8290 | set_buffer_internal_1 (obuf); | 8370 | unbind_to (count, Qnil); |
| 8291 | 8371 | ||
| 8292 | /* Set the title only if it's changed. This avoids consing in | 8372 | /* Set the title only if it's changed. This avoids consing in |
| 8293 | the common case where it hasn't. (If it turns out that we've | 8373 | the common case where it hasn't. (If it turns out that we've |
| @@ -8296,8 +8376,8 @@ x_consider_frame_title (frame) | |||
| 8296 | higher level than this.) */ | 8376 | higher level than this.) */ |
| 8297 | if (! STRINGP (f->name) | 8377 | if (! STRINGP (f->name) |
| 8298 | || SBYTES (f->name) != len | 8378 | || SBYTES (f->name) != len |
| 8299 | || bcmp (frame_title_buf, SDATA (f->name), len) != 0) | 8379 | || bcmp (title_start, SDATA (f->name), len) != 0) |
| 8300 | x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil); | 8380 | x_implicitly_set_name (f, make_string (title_start, len), Qnil); |
| 8301 | } | 8381 | } |
| 8302 | } | 8382 | } |
| 8303 | 8383 | ||
| @@ -15631,18 +15711,6 @@ display_mode_line (w, face_id, format) | |||
| 15631 | return it.glyph_row->height; | 15711 | return it.glyph_row->height; |
| 15632 | } | 15712 | } |
| 15633 | 15713 | ||
| 15634 | /* Alist that caches the results of :propertize. | ||
| 15635 | Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */ | ||
| 15636 | Lisp_Object mode_line_proptrans_alist; | ||
| 15637 | |||
| 15638 | /* List of strings making up the mode-line. */ | ||
| 15639 | Lisp_Object mode_line_string_list; | ||
| 15640 | |||
| 15641 | /* Base face property when building propertized mode line string. */ | ||
| 15642 | static Lisp_Object mode_line_string_face; | ||
| 15643 | static Lisp_Object mode_line_string_face_prop; | ||
| 15644 | |||
| 15645 | |||
| 15646 | /* Contribute ELT to the mode line for window IT->w. How it | 15714 | /* Contribute ELT to the mode line for window IT->w. How it |
| 15647 | translates into text depends on its data type. | 15715 | translates into text depends on its data type. |
| 15648 | 15716 | ||
| @@ -15663,8 +15731,9 @@ static Lisp_Object mode_line_string_face_prop; | |||
| 15663 | If RISKY is nonzero, remove (disregard) any properties in any string | 15731 | If RISKY is nonzero, remove (disregard) any properties in any string |
| 15664 | we encounter, and ignore :eval and :propertize. | 15732 | we encounter, and ignore :eval and :propertize. |
| 15665 | 15733 | ||
| 15666 | If the global variable `frame_title_ptr' is non-NULL, then the output | 15734 | The global variable `mode_line_target' determines whether the |
| 15667 | is passed to `store_frame_title' instead of `display_string'. */ | 15735 | output is passed to `store_mode_line_noprop', |
| 15736 | `store_mode_line_string', or `display_string'. */ | ||
| 15668 | 15737 | ||
| 15669 | static int | 15738 | static int |
| 15670 | display_mode_element (it, depth, field_width, precision, elt, props, risky) | 15739 | display_mode_element (it, depth, field_width, precision, elt, props, risky) |
| @@ -15753,21 +15822,27 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky) | |||
| 15753 | if (literal) | 15822 | if (literal) |
| 15754 | { | 15823 | { |
| 15755 | prec = precision - n; | 15824 | prec = precision - n; |
| 15756 | if (frame_title_ptr) | 15825 | switch (mode_line_target) |
| 15757 | n += store_frame_title (SDATA (elt), -1, prec); | 15826 | { |
| 15758 | else if (!NILP (mode_line_string_list)) | 15827 | case MODE_LINE_NOPROP: |
| 15759 | n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil); | 15828 | case MODE_LINE_TITLE: |
| 15760 | else | 15829 | n += store_mode_line_noprop (SDATA (elt), -1, prec); |
| 15761 | n += display_string (NULL, elt, Qnil, 0, 0, it, | 15830 | break; |
| 15762 | 0, prec, 0, STRING_MULTIBYTE (elt)); | 15831 | case MODE_LINE_STRING: |
| 15832 | n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil); | ||
| 15833 | break; | ||
| 15834 | case MODE_LINE_DISPLAY: | ||
| 15835 | n += display_string (NULL, elt, Qnil, 0, 0, it, | ||
| 15836 | 0, prec, 0, STRING_MULTIBYTE (elt)); | ||
| 15837 | break; | ||
| 15838 | } | ||
| 15763 | 15839 | ||
| 15764 | break; | 15840 | break; |
| 15765 | } | 15841 | } |
| 15766 | 15842 | ||
| 15767 | while ((precision <= 0 || n < precision) | 15843 | while ((precision <= 0 || n < precision) |
| 15768 | && *this | 15844 | && *this |
| 15769 | && (frame_title_ptr | 15845 | && (mode_line_target != MODE_LINE_DISPLAY |
| 15770 | || !NILP (mode_line_string_list) | ||
| 15771 | || it->current_x < it->last_visible_x)) | 15846 | || it->current_x < it->last_visible_x)) |
| 15772 | { | 15847 | { |
| 15773 | const unsigned char *last = this; | 15848 | const unsigned char *last = this; |
| @@ -15788,29 +15863,36 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky) | |||
| 15788 | prec = c_string_width (last, this - last, precision - n, | 15863 | prec = c_string_width (last, this - last, precision - n, |
| 15789 | &nchars, &nbytes); | 15864 | &nchars, &nbytes); |
| 15790 | 15865 | ||
| 15791 | if (frame_title_ptr) | 15866 | switch (mode_line_target) |
| 15792 | n += store_frame_title (last, 0, prec); | ||
| 15793 | else if (!NILP (mode_line_string_list)) | ||
| 15794 | { | ||
| 15795 | int bytepos = last - lisp_string; | ||
| 15796 | int charpos = string_byte_to_char (elt, bytepos); | ||
| 15797 | int endpos = (precision <= 0 | ||
| 15798 | ? string_byte_to_char (elt, | ||
| 15799 | this - lisp_string) | ||
| 15800 | : charpos + nchars); | ||
| 15801 | |||
| 15802 | n += store_mode_line_string (NULL, | ||
| 15803 | Fsubstring (elt, make_number (charpos), | ||
| 15804 | make_number (endpos)), | ||
| 15805 | 0, 0, 0, Qnil); | ||
| 15806 | } | ||
| 15807 | else | ||
| 15808 | { | 15867 | { |
| 15809 | int bytepos = last - lisp_string; | 15868 | case MODE_LINE_NOPROP: |
| 15810 | int charpos = string_byte_to_char (elt, bytepos); | 15869 | case MODE_LINE_TITLE: |
| 15811 | n += display_string (NULL, elt, Qnil, 0, charpos, | 15870 | n += store_mode_line_noprop (last, 0, prec); |
| 15812 | it, 0, prec, 0, | 15871 | break; |
| 15813 | STRING_MULTIBYTE (elt)); | 15872 | case MODE_LINE_STRING: |
| 15873 | { | ||
| 15874 | int bytepos = last - lisp_string; | ||
| 15875 | int charpos = string_byte_to_char (elt, bytepos); | ||
| 15876 | int endpos = (precision <= 0 | ||
| 15877 | ? string_byte_to_char (elt, | ||
| 15878 | this - lisp_string) | ||
| 15879 | : charpos + nchars); | ||
| 15880 | |||
| 15881 | n += store_mode_line_string (NULL, | ||
| 15882 | Fsubstring (elt, make_number (charpos), | ||
| 15883 | make_number (endpos)), | ||
| 15884 | 0, 0, 0, Qnil); | ||
| 15885 | } | ||
| 15886 | break; | ||
| 15887 | case MODE_LINE_DISPLAY: | ||
| 15888 | { | ||
| 15889 | int bytepos = last - lisp_string; | ||
| 15890 | int charpos = string_byte_to_char (elt, bytepos); | ||
| 15891 | n += display_string (NULL, elt, Qnil, 0, charpos, | ||
| 15892 | it, 0, prec, 0, | ||
| 15893 | STRING_MULTIBYTE (elt)); | ||
| 15894 | } | ||
| 15895 | break; | ||
| 15814 | } | 15896 | } |
| 15815 | } | 15897 | } |
| 15816 | else /* c == '%' */ | 15898 | else /* c == '%' */ |
| @@ -15848,44 +15930,51 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky) | |||
| 15848 | spec | 15930 | spec |
| 15849 | = decode_mode_spec (it->w, c, field, prec, &multibyte); | 15931 | = decode_mode_spec (it->w, c, field, prec, &multibyte); |
| 15850 | 15932 | ||
| 15851 | if (frame_title_ptr) | 15933 | switch (mode_line_target) |
| 15852 | n += store_frame_title (spec, field, prec); | ||
| 15853 | else if (!NILP (mode_line_string_list)) | ||
| 15854 | { | ||
| 15855 | int len = strlen (spec); | ||
| 15856 | Lisp_Object tem = make_string (spec, len); | ||
| 15857 | props = Ftext_properties_at (make_number (charpos), elt); | ||
| 15858 | /* Should only keep face property in props */ | ||
| 15859 | n += store_mode_line_string (NULL, tem, 0, field, prec, props); | ||
| 15860 | } | ||
| 15861 | else | ||
| 15862 | { | 15934 | { |
| 15863 | int nglyphs_before, nwritten; | 15935 | case MODE_LINE_NOPROP: |
| 15864 | 15936 | case MODE_LINE_TITLE: | |
| 15865 | nglyphs_before = it->glyph_row->used[TEXT_AREA]; | 15937 | n += store_mode_line_noprop (spec, field, prec); |
| 15866 | nwritten = display_string (spec, Qnil, elt, | 15938 | break; |
| 15867 | charpos, 0, it, | 15939 | case MODE_LINE_STRING: |
| 15868 | field, prec, 0, | 15940 | { |
| 15869 | multibyte); | 15941 | int len = strlen (spec); |
| 15870 | 15942 | Lisp_Object tem = make_string (spec, len); | |
| 15871 | /* Assign to the glyphs written above the | 15943 | props = Ftext_properties_at (make_number (charpos), elt); |
| 15872 | string where the `%x' came from, position | 15944 | /* Should only keep face property in props */ |
| 15873 | of the `%'. */ | 15945 | n += store_mode_line_string (NULL, tem, 0, field, prec, props); |
| 15874 | if (nwritten > 0) | 15946 | } |
| 15875 | { | 15947 | break; |
| 15876 | struct glyph *glyph | 15948 | case MODE_LINE_DISPLAY: |
| 15877 | = (it->glyph_row->glyphs[TEXT_AREA] | 15949 | { |
| 15878 | + nglyphs_before); | 15950 | int nglyphs_before, nwritten; |
| 15879 | int i; | 15951 | |
| 15880 | 15952 | nglyphs_before = it->glyph_row->used[TEXT_AREA]; | |
| 15881 | for (i = 0; i < nwritten; ++i) | 15953 | nwritten = display_string (spec, Qnil, elt, |
| 15882 | { | 15954 | charpos, 0, it, |
| 15883 | glyph[i].object = elt; | 15955 | field, prec, 0, |
| 15884 | glyph[i].charpos = charpos; | 15956 | multibyte); |
| 15885 | } | 15957 | |
| 15886 | 15958 | /* Assign to the glyphs written above the | |
| 15887 | n += nwritten; | 15959 | string where the `%x' came from, position |
| 15888 | } | 15960 | of the `%'. */ |
| 15961 | if (nwritten > 0) | ||
| 15962 | { | ||
| 15963 | struct glyph *glyph | ||
| 15964 | = (it->glyph_row->glyphs[TEXT_AREA] | ||
| 15965 | + nglyphs_before); | ||
| 15966 | int i; | ||
| 15967 | |||
| 15968 | for (i = 0; i < nwritten; ++i) | ||
| 15969 | { | ||
| 15970 | glyph[i].object = elt; | ||
| 15971 | glyph[i].charpos = charpos; | ||
| 15972 | } | ||
| 15973 | |||
| 15974 | n += nwritten; | ||
| 15975 | } | ||
| 15976 | } | ||
| 15977 | break; | ||
| 15889 | } | 15978 | } |
| 15890 | } | 15979 | } |
| 15891 | else /* c == 0 */ | 15980 | else /* c == 0 */ |
| @@ -16056,13 +16145,20 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky) | |||
| 16056 | /* Pad to FIELD_WIDTH. */ | 16145 | /* Pad to FIELD_WIDTH. */ |
| 16057 | if (field_width > 0 && n < field_width) | 16146 | if (field_width > 0 && n < field_width) |
| 16058 | { | 16147 | { |
| 16059 | if (frame_title_ptr) | 16148 | switch (mode_line_target) |
| 16060 | n += store_frame_title ("", field_width - n, 0); | 16149 | { |
| 16061 | else if (!NILP (mode_line_string_list)) | 16150 | case MODE_LINE_NOPROP: |
| 16062 | n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil); | 16151 | case MODE_LINE_TITLE: |
| 16063 | else | 16152 | n += store_mode_line_noprop ("", field_width - n, 0); |
| 16064 | n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n, | 16153 | break; |
| 16065 | 0, 0, 0); | 16154 | case MODE_LINE_STRING: |
| 16155 | n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil); | ||
| 16156 | break; | ||
| 16157 | case MODE_LINE_DISPLAY: | ||
| 16158 | n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n, | ||
| 16159 | 0, 0, 0); | ||
| 16160 | break; | ||
| 16161 | } | ||
| 16066 | } | 16162 | } |
| 16067 | 16163 | ||
| 16068 | return n; | 16164 | return n; |
| @@ -16194,6 +16290,9 @@ are the selected window and the window's buffer). */) | |||
| 16194 | struct buffer *old_buffer = NULL; | 16290 | struct buffer *old_buffer = NULL; |
| 16195 | int face_id = -1; | 16291 | int face_id = -1; |
| 16196 | int no_props = INTEGERP (face); | 16292 | int no_props = INTEGERP (face); |
| 16293 | int count = SPECPDL_INDEX (); | ||
| 16294 | Lisp_Object str; | ||
| 16295 | char *string_start = NULL; | ||
| 16197 | 16296 | ||
| 16198 | if (NILP (window)) | 16297 | if (NILP (window)) |
| 16199 | window = selected_window; | 16298 | window = selected_window; |
| @@ -16221,64 +16320,52 @@ are the selected window and the window's buffer). */) | |||
| 16221 | face_id = DEFAULT_FACE_ID; | 16320 | face_id = DEFAULT_FACE_ID; |
| 16222 | 16321 | ||
| 16223 | if (XBUFFER (buffer) != current_buffer) | 16322 | if (XBUFFER (buffer) != current_buffer) |
| 16224 | { | 16323 | old_buffer = current_buffer; |
| 16225 | old_buffer = current_buffer; | 16324 | |
| 16226 | set_buffer_internal_1 (XBUFFER (buffer)); | 16325 | record_unwind_protect (unwind_format_mode_line, |
| 16227 | } | 16326 | format_mode_line_unwind_data (old_buffer)); |
| 16327 | |||
| 16328 | if (old_buffer) | ||
| 16329 | set_buffer_internal_1 (XBUFFER (buffer)); | ||
| 16228 | 16330 | ||
| 16229 | init_iterator (&it, w, -1, -1, NULL, face_id); | 16331 | init_iterator (&it, w, -1, -1, NULL, face_id); |
| 16230 | 16332 | ||
| 16231 | if (!no_props) | 16333 | if (no_props) |
| 16232 | { | 16334 | { |
| 16233 | mode_line_string_face = face; | 16335 | mode_line_target = MODE_LINE_NOPROP; |
| 16234 | mode_line_string_face_prop | 16336 | mode_line_string_face_prop = Qnil; |
| 16235 | = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil))); | 16337 | mode_line_string_list = Qnil; |
| 16236 | 16338 | string_start = mode_line_noprop_ptr; | |
| 16237 | /* We need a dummy last element in mode_line_string_list to | ||
| 16238 | indicate we are building the propertized mode-line string. | ||
| 16239 | Using mode_line_string_face_prop here GC protects it. */ | ||
| 16240 | mode_line_string_list | ||
| 16241 | = Fcons (mode_line_string_face_prop, Qnil); | ||
| 16242 | frame_title_ptr = NULL; | ||
| 16243 | } | 16339 | } |
| 16244 | else | 16340 | else |
| 16245 | { | 16341 | { |
| 16246 | mode_line_string_face_prop = Qnil; | 16342 | mode_line_target = MODE_LINE_STRING; |
| 16247 | mode_line_string_list = Qnil; | 16343 | mode_line_string_list = Qnil; |
| 16248 | frame_title_ptr = frame_title_buf; | 16344 | mode_line_string_face = face; |
| 16345 | mode_line_string_face_prop | ||
| 16346 | = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil))); | ||
| 16347 | |||
| 16348 | string_start = NULL; | ||
| 16249 | } | 16349 | } |
| 16250 | 16350 | ||
| 16251 | push_frame_kboard (it.f); | 16351 | push_frame_kboard (it.f); |
| 16252 | display_mode_element (&it, 0, 0, 0, format, Qnil, 0); | 16352 | display_mode_element (&it, 0, 0, 0, format, Qnil, 0); |
| 16253 | pop_frame_kboard (); | 16353 | pop_frame_kboard (); |
| 16254 | 16354 | ||
| 16255 | if (old_buffer) | 16355 | if (no_props) |
| 16256 | set_buffer_internal_1 (old_buffer); | ||
| 16257 | |||
| 16258 | if (!no_props) | ||
| 16259 | { | 16356 | { |
| 16260 | Lisp_Object str; | 16357 | len = mode_line_noprop_ptr - string_start; |
| 16261 | mode_line_string_list = Fnreverse (mode_line_string_list); | 16358 | str = make_string (string_start, len); |
| 16262 | str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list), | ||
| 16263 | make_string ("", 0)); | ||
| 16264 | mode_line_string_face_prop = Qnil; | ||
| 16265 | mode_line_string_list = Qnil; | ||
| 16266 | return str; | ||
| 16267 | } | 16359 | } |
| 16268 | 16360 | else | |
| 16269 | len = frame_title_ptr - frame_title_buf; | ||
| 16270 | if (len > 0 && frame_title_ptr[-1] == '-') | ||
| 16271 | { | 16361 | { |
| 16272 | /* Mode lines typically ends with numerous dashes; reduce to two dashes. */ | 16362 | mode_line_string_list = Fnreverse (mode_line_string_list); |
| 16273 | while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-') | 16363 | str = Fmapconcat (intern ("identity"), mode_line_string_list, |
| 16274 | ; | 16364 | make_string ("", 0)); |
| 16275 | frame_title_ptr += 3; /* restore last non-dash + two dashes */ | ||
| 16276 | if (len > frame_title_ptr - frame_title_buf) | ||
| 16277 | len = frame_title_ptr - frame_title_buf; | ||
| 16278 | } | 16365 | } |
| 16279 | 16366 | ||
| 16280 | frame_title_ptr = NULL; | 16367 | unbind_to (count, Qnil); |
| 16281 | return make_string (frame_title_buf, len); | 16368 | return str; |
| 16282 | } | 16369 | } |
| 16283 | 16370 | ||
| 16284 | /* Write a null-terminated, right justified decimal representation of | 16371 | /* Write a null-terminated, right justified decimal representation of |
| @@ -16596,7 +16683,8 @@ decode_mode_spec (w, c, field_width, precision, multibyte) | |||
| 16596 | register int i; | 16683 | register int i; |
| 16597 | 16684 | ||
| 16598 | /* Let lots_of_dashes be a string of infinite length. */ | 16685 | /* Let lots_of_dashes be a string of infinite length. */ |
| 16599 | if (!NILP (mode_line_string_list)) | 16686 | if (mode_line_target == MODE_LINE_NOPROP || |
| 16687 | mode_line_target == MODE_LINE_STRING) | ||
| 16600 | return "--"; | 16688 | return "--"; |
| 16601 | if (field_width <= 0 | 16689 | if (field_width <= 0 |
| 16602 | || field_width > sizeof (lots_of_dashes)) | 16690 | || field_width > sizeof (lots_of_dashes)) |
| @@ -22689,9 +22777,14 @@ syms_of_xdisp () | |||
| 22689 | 22777 | ||
| 22690 | mode_line_proptrans_alist = Qnil; | 22778 | mode_line_proptrans_alist = Qnil; |
| 22691 | staticpro (&mode_line_proptrans_alist); | 22779 | staticpro (&mode_line_proptrans_alist); |
| 22692 | |||
| 22693 | mode_line_string_list = Qnil; | 22780 | mode_line_string_list = Qnil; |
| 22694 | staticpro (&mode_line_string_list); | 22781 | staticpro (&mode_line_string_list); |
| 22782 | mode_line_string_face = Qnil; | ||
| 22783 | staticpro (&mode_line_string_face); | ||
| 22784 | mode_line_string_face_prop = Qnil; | ||
| 22785 | staticpro (&mode_line_string_face_prop); | ||
| 22786 | Vmode_line_unwind_vector = Qnil; | ||
| 22787 | staticpro (&Vmode_line_unwind_vector); | ||
| 22695 | 22788 | ||
| 22696 | help_echo_string = Qnil; | 22789 | help_echo_string = Qnil; |
| 22697 | staticpro (&help_echo_string); | 22790 | staticpro (&help_echo_string); |
| @@ -23041,9 +23134,10 @@ init_xdisp () | |||
| 23041 | /* Allocate the buffer for frame titles. | 23134 | /* Allocate the buffer for frame titles. |
| 23042 | Also used for `format-mode-line'. */ | 23135 | Also used for `format-mode-line'. */ |
| 23043 | int size = 100; | 23136 | int size = 100; |
| 23044 | frame_title_buf = (char *) xmalloc (size); | 23137 | mode_line_noprop_buf = (char *) xmalloc (size); |
| 23045 | frame_title_buf_end = frame_title_buf + size; | 23138 | mode_line_noprop_buf_end = mode_line_noprop_buf + size; |
| 23046 | frame_title_ptr = NULL; | 23139 | mode_line_noprop_ptr = mode_line_noprop_buf; |
| 23140 | mode_line_target = MODE_LINE_DISPLAY; | ||
| 23047 | } | 23141 | } |
| 23048 | 23142 | ||
| 23049 | help_echo_showing_p = 0; | 23143 | help_echo_showing_p = 0; |