aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKarl Heuer1997-02-20 06:40:53 +0000
committerKarl Heuer1997-02-20 06:40:53 +0000
commit1c9241f53ad8d5b3684be53b66e936369f852ea3 (patch)
tree55979b9d8b28471d7173ab168c9ccf5690f07fbd /src
parenta997a7ca075879b76589d5e9ab47209cd31ef0f6 (diff)
downloademacs-1c9241f53ad8d5b3684be53b66e936369f852ea3.tar.gz
emacs-1c9241f53ad8d5b3684be53b66e936369f852ea3.zip
(display_text_line): Introduce new local variable
rev_dir_bit to display right to left characters (not yet used). (message): Use FRAME_MESSAGE_BUF_SIZE(). (redisplay_internal): Add canceling code for continuation at wide-column. (display_text_line): Don't just decrement left_edge->bufpos, it may be multi-byte character, use DEC_POS instead. (try_window): Change the way of calculation of tab offset. We now use val.tab_offset to maintain tab offset. Removed local variable tab_offset. (try_window_id): Likewise. (pos_tab_offset): Return COL (Modulo is no longer valid). Add the line to set tab_offset member. Use pos.tab_offset. (redisplay_window): Specify big negative number for TOHPOS of compute_motion(). (try_window_id): Likewise. (tri_window_id): Specify "1 << (BITS_PER_SHORT - 1)" to express "Don't care". Include charset.h, coding.h, and process.h. (display_text_line): Handle multibyte characters. (display_mode_line): Pay attention to wide-column characters. (decode_mode_spec_coding): New function. (decode_mode_spec): Handle %-constructs `%z' and `%Z' to print coding system mnemonics. (display_string): Handle multibyte characters.
Diffstat (limited to 'src')
-rw-r--r--src/xdisp.c479
1 files changed, 393 insertions, 86 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index e0de4f96e05..e96cf8494cc 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -29,6 +29,7 @@ Boston, MA 02111-1307, USA. */
29#include "termchar.h" 29#include "termchar.h"
30#include "dispextern.h" 30#include "dispextern.h"
31#include "buffer.h" 31#include "buffer.h"
32#include "charset.h"
32#include "indent.h" 33#include "indent.h"
33#include "commands.h" 34#include "commands.h"
34#include "macros.h" 35#include "macros.h"
@@ -36,6 +37,8 @@ Boston, MA 02111-1307, USA. */
36#include "termhooks.h" 37#include "termhooks.h"
37#include "intervals.h" 38#include "intervals.h"
38#include "keyboard.h" 39#include "keyboard.h"
40#include "coding.h"
41#include "process.h"
39 42
40#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) 43#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
41extern void set_frame_menubar (); 44extern void set_frame_menubar ();
@@ -548,10 +551,10 @@ message (m, a1, a2, a3)
548 a[2] = a3; 551 a[2] = a3;
549 552
550 len = doprnt (FRAME_MESSAGE_BUF (f), 553 len = doprnt (FRAME_MESSAGE_BUF (f),
551 (int) FRAME_WIDTH (f), m, (char *)0, 3, a); 554 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
552#else 555#else
553 len = doprnt (FRAME_MESSAGE_BUF (f), 556 len = doprnt (FRAME_MESSAGE_BUF (f),
554 (int) FRAME_WIDTH (f), m, (char *)0, 3, &a1); 557 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, &a1);
555#endif /* NO_ARG_ARRAY */ 558#endif /* NO_ARG_ARRAY */
556 559
557 message2 (FRAME_MESSAGE_BUF (f), len); 560 message2 (FRAME_MESSAGE_BUF (f), len);
@@ -987,15 +990,44 @@ redisplay_internal (preserve_echo_area)
987 && end_unchanged >= tlendpos 990 && end_unchanged >= tlendpos
988 && Z - GPT >= tlendpos))) 991 && Z - GPT >= tlendpos)))
989 { 992 {
990 if (tlbufpos > BEGV && FETCH_CHAR (tlbufpos - 1) != '\n' 993 if (tlbufpos > BEGV && FETCH_BYTE (tlbufpos - 1) != '\n'
991 && (tlbufpos == ZV 994 && (tlbufpos == ZV
992 || FETCH_CHAR (tlbufpos) == '\n')) 995 || FETCH_BYTE (tlbufpos) == '\n'))
993 /* Former continuation line has disappeared by becoming empty */ 996 /* Former continuation line has disappeared by becoming empty */
994 goto cancel; 997 goto cancel;
995 else if (XFASTINT (w->last_modified) < MODIFF 998 else if (XFASTINT (w->last_modified) < MODIFF
996 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF 999 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
997 || MINI_WINDOW_P (w)) 1000 || MINI_WINDOW_P (w))
998 { 1001 {
1002 /* We have to handle the case of continuation around a
1003 wide-column character (See the comment in indent.c around
1004 line 885).
1005
1006 For instance, in the following case:
1007
1008 -------- Insert --------
1009 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
1010 J_I_ ==> J_I_ `^^' are cursors.
1011 ^^ ^^
1012 -------- --------
1013
1014 As we have to redraw the line above, we should goto cancel. */
1015
1016 struct position val;
1017 int prevline;
1018
1019 prevline = find_next_newline (tlbufpos, -1);
1020 val = *compute_motion (prevline, 0,
1021 XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0,
1022 0,
1023 tlbufpos,
1024 1 << (BITS_PER_SHORT - 1),
1025 1 << (BITS_PER_SHORT - 1),
1026 window_internal_width (w) - 1,
1027 XINT (w->hscroll), 0, w);
1028 if (val.hpos != this_line_start_hpos)
1029 goto cancel;
1030
999 cursor_vpos = -1; 1031 cursor_vpos = -1;
1000 overlay_arrow_seen = 0; 1032 overlay_arrow_seen = 0;
1001 zv_strings_seen = 0; 1033 zv_strings_seen = 0;
@@ -1604,7 +1636,10 @@ redisplay_window (window, just_this_one, preserve_echo_area)
1604 ? minibuf_prompt_width : 0) 1636 ? minibuf_prompt_width : 0)
1605 + (hscroll ? 1 - hscroll : 0)), 1637 + (hscroll ? 1 - hscroll : 0)),
1606 0, 1638 0,
1607 PT, height, 0, 1639 PT, height,
1640 /* BUG FIX: See the comment of
1641 Fpos_visible_in_window_p (window.c). */
1642 - (1 << (BITS_PER_SHORT - 1)),
1608 width, hscroll, pos_tab_offset (w, startp), w); 1643 width, hscroll, pos_tab_offset (w, startp), w);
1609 /* If PT does fit on the screen, we will use this start pos, 1644 /* If PT does fit on the screen, we will use this start pos,
1610 so do so by setting force_start. */ 1645 so do so by setting force_start. */
@@ -1711,8 +1746,12 @@ redisplay_window (window, just_this_one, preserve_echo_area)
1711 int this_scroll_margin = scroll_margin; 1746 int this_scroll_margin = scroll_margin;
1712 1747
1713 pos = *compute_motion (startp, 0, (hscroll ? 1 - hscroll : 0), 0, 1748 pos = *compute_motion (startp, 0, (hscroll ? 1 - hscroll : 0), 0,
1714 PT, height, 0, width, hscroll, 1749 PT, height,
1715 pos_tab_offset (w, startp), w); 1750 /* BUG FIX: See the comment of
1751 Fpos_visible_in_window_p (window.c). */
1752 - (1 << (BITS_PER_SHORT - 1)),
1753 width, hscroll,
1754 pos_tab_offset (w, startp), w);
1716 1755
1717 /* Don't use a scroll margin that is negative or too large. */ 1756 /* Don't use a scroll margin that is negative or too large. */
1718 if (this_scroll_margin < 0) 1757 if (this_scroll_margin < 0)
@@ -1750,7 +1789,7 @@ redisplay_window (window, just_this_one, preserve_echo_area)
1750 but no longer is, find a new starting point. */ 1789 but no longer is, find a new starting point. */
1751 else if (!NILP (w->start_at_line_beg) 1790 else if (!NILP (w->start_at_line_beg)
1752 && !(startp <= BEGV 1791 && !(startp <= BEGV
1753 || FETCH_CHAR (startp - 1) == '\n')) 1792 || FETCH_BYTE (startp - 1) == '\n'))
1754 { 1793 {
1755 goto recenter; 1794 goto recenter;
1756 } 1795 }
@@ -1957,7 +1996,7 @@ recenter:
1957 1996
1958 startp = marker_position (w->start); 1997 startp = marker_position (w->start);
1959 w->start_at_line_beg 1998 w->start_at_line_beg
1960 = (startp == BEGV || FETCH_CHAR (startp - 1) == '\n') ? Qt : Qnil; 1999 = (startp == BEGV || FETCH_BYTE (startp - 1) == '\n') ? Qt : Qnil;
1961 2000
1962done: 2001done:
1963 if ((update_mode_line 2002 if ((update_mode_line
@@ -2043,7 +2082,6 @@ try_window (window, pos)
2043 register int height = window_internal_height (w); 2082 register int height = window_internal_height (w);
2044 register int vpos = XFASTINT (w->top); 2083 register int vpos = XFASTINT (w->top);
2045 register int last_text_vpos = vpos; 2084 register int last_text_vpos = vpos;
2046 int tab_offset = pos_tab_offset (w, pos);
2047 FRAME_PTR f = XFRAME (w->frame); 2085 FRAME_PTR f = XFRAME (w->frame);
2048 int width = window_internal_width (w) - 1; 2086 int width = window_internal_width (w) - 1;
2049 struct position val; 2087 struct position val;
@@ -2059,13 +2097,18 @@ try_window (window, pos)
2059 zv_strings_seen = 0; 2097 zv_strings_seen = 0;
2060 val.hpos = XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0; 2098 val.hpos = XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0;
2061 val.ovstring_chars_done = 0; 2099 val.ovstring_chars_done = 0;
2100 val.tab_offset = pos_tab_offset (w, pos);
2062 2101
2063 while (--height >= 0) 2102 while (--height >= 0)
2064 { 2103 {
2065 val = *display_text_line (w, pos, vpos, val.hpos, tab_offset, 2104 val = *display_text_line (w, pos, vpos, val.hpos, val.tab_offset,
2066 val.ovstring_chars_done); 2105 val.ovstring_chars_done);
2106 /* The following code is omitted because we maintain tab_offset
2107 in VAL. */
2108#if 0
2067 tab_offset += width; 2109 tab_offset += width;
2068 if (val.vpos) tab_offset = 0; 2110 if (val.vpos) tab_offset = 0;
2111#endif /* 0 */
2069 vpos++; 2112 vpos++;
2070 if (pos != val.bufpos) 2113 if (pos != val.bufpos)
2071 { 2114 {
@@ -2079,7 +2122,7 @@ try_window (window, pos)
2079 last_text_vpos 2122 last_text_vpos
2080 /* Next line, unless prev line ended in end of buffer with no cr */ 2123 /* Next line, unless prev line ended in end of buffer with no cr */
2081 = vpos - (val.vpos 2124 = vpos - (val.vpos
2082 && (FETCH_CHAR (val.bufpos - 1) != '\n' || invis)); 2125 && (FETCH_BYTE (val.bufpos - 1) != '\n' || invis));
2083 } 2126 }
2084 pos = val.bufpos; 2127 pos = val.bufpos;
2085 } 2128 }
@@ -2133,7 +2176,7 @@ try_window_id (window)
2133 struct position val, bp, ep, xp, pp; 2176 struct position val, bp, ep, xp, pp;
2134 int scroll_amount = 0; 2177 int scroll_amount = 0;
2135 int delta; 2178 int delta;
2136 int tab_offset, epto, old_tick; 2179 int epto, old_tick;
2137 2180
2138 if (GPT - BEG < beg_unchanged) 2181 if (GPT - BEG < beg_unchanged)
2139 beg_unchanged = GPT - BEG; 2182 beg_unchanged = GPT - BEG;
@@ -2145,7 +2188,10 @@ try_window_id (window)
2145 2188
2146 /* Find position before which nothing is changed. */ 2189 /* Find position before which nothing is changed. */
2147 bp = *compute_motion (start, 0, lmargin, 0, 2190 bp = *compute_motion (start, 0, lmargin, 0,
2148 min (ZV, beg_unchanged + BEG), height, 0, 2191 min (ZV, beg_unchanged + BEG), height,
2192 /* BUG FIX: See the comment of
2193 Fpos_visible_in_window_p() (window.c). */
2194 - (1 << (BITS_PER_SHORT - 1)),
2149 width, hscroll, pos_tab_offset (w, start), w); 2195 width, hscroll, pos_tab_offset (w, start), w);
2150 if (bp.vpos >= height) 2196 if (bp.vpos >= height)
2151 { 2197 {
@@ -2156,7 +2202,10 @@ try_window_id (window)
2156 But we need to update window_end_pos to account for 2202 But we need to update window_end_pos to account for
2157 any change in buffer size. */ 2203 any change in buffer size. */
2158 bp = *compute_motion (start, 0, lmargin, 0, 2204 bp = *compute_motion (start, 0, lmargin, 0,
2159 ZV, height, 0, 2205 ZV, height,
2206 /* BUG FIX: See the comment of
2207 Fpos_visible_in_window_p() (window.c). */
2208 - (1 << (BITS_PER_SHORT - 1)),
2160 width, hscroll, pos_tab_offset (w, start), w); 2209 width, hscroll, pos_tab_offset (w, start), w);
2161 XSETFASTINT (w->window_end_vpos, height); 2210 XSETFASTINT (w->window_end_vpos, height);
2162 XSETFASTINT (w->window_end_pos, Z - bp.bufpos); 2211 XSETFASTINT (w->window_end_pos, Z - bp.bufpos);
@@ -2188,12 +2237,14 @@ try_window_id (window)
2188 --vpos; 2237 --vpos;
2189 pos = bp.bufpos; 2238 pos = bp.bufpos;
2190 } 2239 }
2240 val.tab_offset = bp.tab_offset; /* Update tab offset. */
2191 2241
2192 if (bp.contin && bp.hpos != lmargin) 2242 if (bp.contin && bp.hpos != lmargin)
2193 { 2243 {
2194 val.hpos = bp.prevhpos - width + lmargin; 2244 val.hpos = bp.prevhpos - width + lmargin;
2245 val.tab_offset = bp.tab_offset + bp.prevhpos - width;
2195 did_motion = 1; 2246 did_motion = 1;
2196 pos--; 2247 DEC_POS (pos);
2197 } 2248 }
2198 2249
2199 bp.vpos = vpos; 2250 bp.vpos = vpos;
@@ -2207,7 +2258,9 @@ try_window_id (window)
2207 /* Compute the cursor position after that newline. */ 2258 /* Compute the cursor position after that newline. */
2208 ep = *compute_motion (pos, vpos, val.hpos, did_motion, tem, 2259 ep = *compute_motion (pos, vpos, val.hpos, did_motion, tem,
2209 height, - (1 << (BITS_PER_SHORT - 1)), 2260 height, - (1 << (BITS_PER_SHORT - 1)),
2210 width, hscroll, pos_tab_offset (w, bp.bufpos), w); 2261 width, hscroll,
2262 /* We have tab offset in VAL, use it. */
2263 val.tab_offset, w);
2211 2264
2212 /* If changes reach past the text available on the frame, 2265 /* If changes reach past the text available on the frame,
2213 just display rest of frame. */ 2266 just display rest of frame. */
@@ -2223,7 +2276,7 @@ try_window_id (window)
2223 newline before it, so the following line must be redrawn. */ 2276 newline before it, so the following line must be redrawn. */
2224 if (stop_vpos == ep.vpos 2277 if (stop_vpos == ep.vpos
2225 && (ep.bufpos == BEGV 2278 && (ep.bufpos == BEGV
2226 || FETCH_CHAR (ep.bufpos - 1) != '\n' 2279 || FETCH_BYTE (ep.bufpos - 1) != '\n'
2227 || ep.bufpos == Z - end_unchanged)) 2280 || ep.bufpos == Z - end_unchanged))
2228 stop_vpos = ep.vpos + 1; 2281 stop_vpos = ep.vpos + 1;
2229 2282
@@ -2236,17 +2289,20 @@ try_window_id (window)
2236 if (stop_vpos < height) 2289 if (stop_vpos < height)
2237 { 2290 {
2238 /* Now determine how far up or down the rest of the window has moved */ 2291 /* Now determine how far up or down the rest of the window has moved */
2239 epto = pos_tab_offset (w, ep.bufpos);
2240 xp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, 1, 2292 xp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, 1,
2241 Z - XFASTINT (w->window_end_pos), 2293 Z - XFASTINT (w->window_end_pos),
2242 10000, 0, width, hscroll, epto, w); 2294 /* Don't care for VPOS... */
2295 1 << (BITS_PER_SHORT - 1),
2296 /* ... nor HPOS. */
2297 1 << (BITS_PER_SHORT - 1),
2298 width, hscroll, ep.tab_offset, w);
2243 scroll_amount = xp.vpos - XFASTINT (w->window_end_vpos); 2299 scroll_amount = xp.vpos - XFASTINT (w->window_end_vpos);
2244 2300
2245 /* Is everything on frame below the changes whitespace? 2301 /* Is everything on frame below the changes whitespace?
2246 If so, no scrolling is really necessary. */ 2302 If so, no scrolling is really necessary. */
2247 for (i = ep.bufpos; i < xp.bufpos; i++) 2303 for (i = ep.bufpos; i < xp.bufpos; i++)
2248 { 2304 {
2249 tem = FETCH_CHAR (i); 2305 tem = FETCH_BYTE (i);
2250 if (tem != ' ' && tem != '\n' && tem != '\t') 2306 if (tem != ' ' && tem != '\n' && tem != '\t')
2251 break; 2307 break;
2252 } 2308 }
@@ -2263,14 +2319,17 @@ try_window_id (window)
2263 { 2319 {
2264 pp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, 1, 2320 pp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, 1,
2265 PT, height, - (1 << (BITS_PER_SHORT - 1)), 2321 PT, height, - (1 << (BITS_PER_SHORT - 1)),
2266 width, hscroll, epto, w); 2322 width, hscroll,
2323 /* We have tab offset in EP, use it. */
2324 ep.tab_offset, w);
2267 } 2325 }
2268 else 2326 else
2269 { 2327 {
2270 pp = *compute_motion (xp.bufpos, xp.vpos, xp.hpos, 1, 2328 pp = *compute_motion (xp.bufpos, xp.vpos, xp.hpos, 1,
2271 PT, height, - (1 << (BITS_PER_SHORT - 1)), 2329 PT, height, - (1 << (BITS_PER_SHORT - 1)),
2272 width, hscroll, 2330 width, hscroll,
2273 pos_tab_offset (w, xp.bufpos), w); 2331 /* We have tab offset in XP, use it. */
2332 xp.tab_offset, w);
2274 } 2333 }
2275 if (pp.bufpos < PT || pp.vpos == height) 2334 if (pp.bufpos < PT || pp.vpos == height)
2276 return 0; 2335 return 0;
@@ -2373,27 +2432,35 @@ try_window_id (window)
2373 2432
2374 /* Redisplay the lines where the text was changed */ 2433 /* Redisplay the lines where the text was changed */
2375 last_text_vpos = vpos; 2434 last_text_vpos = vpos;
2435 /* The following code is omitted because we maintain tab offset in
2436 val.tab_offset. */
2437#if 0
2376 tab_offset = pos_tab_offset (w, pos); 2438 tab_offset = pos_tab_offset (w, pos);
2377 /* If we are starting display in mid-character, correct tab_offset 2439 /* If we are starting display in mid-character, correct tab_offset
2378 to account for passing the line that that character really starts in. */ 2440 to account for passing the line that that character really starts in. */
2379 if (val.hpos < lmargin) 2441 if (val.hpos < lmargin)
2380 tab_offset += width; 2442 tab_offset += width;
2443#endif /* 0 */
2381 old_tick = MODIFF; 2444 old_tick = MODIFF;
2382 while (vpos < stop_vpos) 2445 while (vpos < stop_vpos)
2383 { 2446 {
2384 val = *display_text_line (w, pos, top + vpos++, val.hpos, tab_offset, 2447 val = *display_text_line (w, pos, top + vpos++, val.hpos, val.tab_offset,
2385 val.ovstring_chars_done); 2448 val.ovstring_chars_done);
2386 /* If display_text_line ran a hook and changed some text, 2449 /* If display_text_line ran a hook and changed some text,
2387 redisplay all the way to bottom of buffer 2450 redisplay all the way to bottom of buffer
2388 So that we show the changes. */ 2451 So that we show the changes. */
2389 if (old_tick != MODIFF) 2452 if (old_tick != MODIFF)
2390 stop_vpos = height; 2453 stop_vpos = height;
2454 /* The following code is omitted because we maintain tab offset
2455 in val.tab_offset. */
2456#if 0
2391 tab_offset += width; 2457 tab_offset += width;
2392 if (val.vpos) tab_offset = 0; 2458 if (val.vpos) tab_offset = 0;
2459#endif
2393 if (pos != val.bufpos) 2460 if (pos != val.bufpos)
2394 last_text_vpos 2461 last_text_vpos
2395 /* Next line, unless prev line ended in end of buffer with no cr */ 2462 /* Next line, unless prev line ended in end of buffer with no cr */
2396 = vpos - (val.vpos && FETCH_CHAR (val.bufpos - 1) != '\n'); 2463 = vpos - (val.vpos && FETCH_BYTE (val.bufpos - 1) != '\n');
2397 pos = val.bufpos; 2464 pos = val.bufpos;
2398 } 2465 }
2399 2466
@@ -2420,28 +2487,37 @@ try_window_id (window)
2420 FRAME_SCROLL_BOTTOM_VPOS (f) = xp.vpos; 2487 FRAME_SCROLL_BOTTOM_VPOS (f) = xp.vpos;
2421 vpos = xp.vpos; 2488 vpos = xp.vpos;
2422 pos = xp.bufpos; 2489 pos = xp.bufpos;
2423 val.hpos = lmargin; 2490 val.hpos = xp.hpos;
2491 val.tab_offset = xp.tab_offset;
2424 if (pos == ZV) 2492 if (pos == ZV)
2425 vpos = height + scroll_amount; 2493 vpos = height + scroll_amount;
2426 else if (xp.contin && xp.hpos != lmargin) 2494 else if (xp.contin && xp.hpos != lmargin)
2427 { 2495 {
2428 val.hpos = xp.prevhpos - width + lmargin; 2496 val.hpos = xp.prevhpos - width + lmargin;
2429 pos--; 2497 val.tab_offset = xp.tab_offset + bp.prevhpos - width;
2498 DEC_POS (pos);
2430 } 2499 }
2431 2500
2432 blank_end_of_window = 1; 2501 blank_end_of_window = 1;
2502 /* The following code is omitted because we maintain tab offset
2503 in val.tab_offset. */
2504#if 0
2433 tab_offset = pos_tab_offset (w, pos); 2505 tab_offset = pos_tab_offset (w, pos);
2434 /* If we are starting display in mid-character, correct tab_offset 2506 /* If we are starting display in mid-character, correct tab_offset
2435 to account for passing the line that that character starts in. */ 2507 to account for passing the line that that character starts in. */
2436 if (val.hpos < lmargin) 2508 if (val.hpos < lmargin)
2437 tab_offset += width; 2509 tab_offset += width;
2438 2510#endif
2439 while (vpos < height) 2511 while (vpos < height)
2440 { 2512 {
2441 val = *display_text_line (w, pos, top + vpos++, val.hpos, tab_offset, 2513 val = *display_text_line (w, pos, top + vpos++, val.hpos,
2442 val.ovstring_chars_done); 2514 val.tab_offset, val.ovstring_chars_done);
2515 /* The following code is omitted because we maintain tab
2516 offset in val.tab_offset. */
2517#if 0
2443 tab_offset += width; 2518 tab_offset += width;
2444 if (val.vpos) tab_offset = 0; 2519 if (val.vpos) tab_offset = 0;
2520#endif /* 0 */
2445 pos = val.bufpos; 2521 pos = val.bufpos;
2446 } 2522 }
2447 2523
@@ -2478,7 +2554,11 @@ try_window_id (window)
2478 if (cursor_vpos < 0) 2554 if (cursor_vpos < 0)
2479 { 2555 {
2480 findpoint: 2556 findpoint:
2481 val = *compute_motion (start, 0, lmargin, 0, PT, 10000, 10000, 2557 val = *compute_motion (start, 0, lmargin, 0, PT,
2558 /* Don't care for VPOS... */
2559 1 << (BITS_PER_SHORT - 1),
2560 /* ... nor HPOS. */
2561 1 << (BITS_PER_SHORT - 1),
2482 width, hscroll, pos_tab_offset (w, start), w); 2562 width, hscroll, pos_tab_offset (w, start), w);
2483 /* Admit failure if point is off frame now */ 2563 /* Admit failure if point is off frame now */
2484 if (val.vpos >= height) 2564 if (val.vpos >= height)
@@ -2677,6 +2757,15 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
2677 GLYPH continuer = (dp == 0 || !INTEGERP (DISP_CONTINUE_GLYPH (dp)) 2757 GLYPH continuer = (dp == 0 || !INTEGERP (DISP_CONTINUE_GLYPH (dp))
2678 ? '\\' : XINT (DISP_CONTINUE_GLYPH (dp))); 2758 ? '\\' : XINT (DISP_CONTINUE_GLYPH (dp)));
2679 2759
2760 /* If 1, we must handle multibyte characters. */
2761 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
2762 /* Length of multibyte form of each character. */
2763 int len;
2764 /* Glyphs generated should be set this bit mask if text must be
2765 displayed from right to left. */
2766 GLYPH rev_dir_bit = (NILP (current_buffer->direction_reversed)
2767 ? 0 : GLYPH_MASK_REV_DIR);
2768
2680 /* The next buffer location at which the face should change, due 2769 /* The next buffer location at which the face should change, due
2681 to overlays or text property changes. */ 2770 to overlays or text property changes. */
2682 int next_face_change; 2771 int next_face_change;
@@ -2760,7 +2849,8 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
2760 if (left_edge->vpos > vpos 2849 if (left_edge->vpos > vpos
2761 || left_edge->hpos > 0) 2850 || left_edge->hpos > 0)
2762 { 2851 {
2763 pos = left_edge->bufpos - 1; 2852 pos = left_edge->bufpos;
2853 DEC_POS (pos); /* MULE: It may be a multi-byte character */
2764 hpos = left_edge->prevhpos; 2854 hpos = left_edge->prevhpos;
2765 } 2855 }
2766 else 2856 else
@@ -2820,13 +2910,32 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
2820 ovstr += ovstr_done; 2910 ovstr += ovstr_done;
2821 ovlen -= ovstr_done; 2911 ovlen -= ovstr_done;
2822 2912
2823 /* Start outputting. */ 2913 while (ovlen > 0)
2824 for (; ovlen; ovlen--, ovstr++)
2825 { 2914 {
2826 if (p1 >= leftmargin && p1 < endp) 2915 int charset, cols;
2827 *p1 = MAKE_GLYPH (f, *ovstr, current_face); 2916 GLYPH g;
2828 p1++; 2917
2829 ovstr_done++; 2918 if (multibyte)
2919 {
2920 c = STRING_CHAR_AND_LENGTH (ovstr, ovlen, len);
2921 ovstr += len, ovlen -= len, ovstr_done += len;
2922 charset = CHAR_CHARSET (c);
2923 cols = (charset == CHARSET_COMPOSITION
2924 ? cmpchar_table[COMPOSITE_CHAR_ID (c)]->width
2925 : CHARSET_WIDTH (charset));
2926 }
2927 else
2928 {
2929 c = *ovstr++, ovlen--, ovstr_done++;
2930 cols = 1;
2931 }
2932 g = MAKE_GLYPH (f, c, current_face) | rev_dir_bit;
2933 while (cols-- > 0)
2934 {
2935 if (p1 >= leftmargin && p1 < endp)
2936 *p1 = g, g |= GLYPH_MASK_PADDING;
2937 p1++;
2938 }
2830 } 2939 }
2831 /* If we did all the overlay strings 2940 /* If we did all the overlay strings
2832 and we have room for text, clear ovstr_done 2941 and we have room for text, clear ovstr_done
@@ -2852,7 +2961,12 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
2852 /* This is just an estimate to give reasonable 2961 /* This is just an estimate to give reasonable
2853 performance; nothing should go wrong if it is too small. */ 2962 performance; nothing should go wrong if it is too small. */
2854 if (XFASTINT (limit) > pos + 50) 2963 if (XFASTINT (limit) > pos + 50)
2855 XSETFASTINT (limit, pos + 50); 2964 {
2965 int limitpos = pos + 50;
2966 if (limitpos < Z)
2967 INC_POS (limitpos); /* Adjust to character boundary. */
2968 XSETFASTINT (limit, limitpos);
2969 }
2856 limit = Fnext_single_property_change (position, Qinvisible, 2970 limit = Fnext_single_property_change (position, Qinvisible,
2857 Fcurrent_buffer (), limit); 2971 Fcurrent_buffer (), limit);
2858#endif 2972#endif
@@ -2933,9 +3047,15 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
2933 loop, to see what face we should start with. */ 3047 loop, to see what face we should start with. */
2934 if (pos >= next_face_change 3048 if (pos >= next_face_change
2935 && (FRAME_WINDOW_P (f) || FRAME_MSDOS_P (f))) 3049 && (FRAME_WINDOW_P (f) || FRAME_MSDOS_P (f)))
2936 current_face = compute_char_face (f, w, pos, 3050 {
2937 region_beg, region_end, 3051 int limit = pos + 50;
2938 &next_face_change, pos + 50, 0); 3052
3053 if (limit < Z && !CHAR_HEAD_P (POS_ADDR (limit)))
3054 INC_POS (limit); /* Adjust to character boundary. */
3055 current_face = compute_char_face (f, w, pos,
3056 region_beg, region_end,
3057 &next_face_change, limit, 0);
3058 }
2939#endif 3059#endif
2940 3060
2941 /* Compute the next place we need to stop 3061 /* Compute the next place we need to stop
@@ -2958,7 +3078,7 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
2958 if (pos < GPT && GPT < pause) 3078 if (pos < GPT && GPT < pause)
2959 pause = GPT; 3079 pause = GPT;
2960 3080
2961 p = &FETCH_CHAR (pos); 3081 p = POS_ADDR (pos);
2962 } 3082 }
2963 3083
2964 if (p1 >= endp) 3084 if (p1 >= endp)
@@ -2966,19 +3086,23 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
2966 3086
2967 p1prev = p1; 3087 p1prev = p1;
2968 3088
2969 c = *p++; 3089 if (multibyte)
3090 /* PAUSE is surely at character boundary. */
3091 c = STRING_CHAR_AND_LENGTH (p, pause - pos, len), p += len;
3092 else
3093 c = *p++, len = 1;
2970 /* Let a display table override all standard display methods. */ 3094 /* Let a display table override all standard display methods. */
2971 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) 3095 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
2972 { 3096 {
2973 p1 = copy_part_of_rope (f, p1, leftmargin, 3097 p1 = copy_part_of_rope (f, p1, leftmargin,
2974 XVECTOR (DISP_CHAR_VECTOR (dp, c))->contents, 3098 XVECTOR (DISP_CHAR_VECTOR (dp, c))->contents,
2975 XVECTOR (DISP_CHAR_VECTOR (dp, c))->size, 3099 XVECTOR (DISP_CHAR_VECTOR (dp, c))->size,
2976 current_face); 3100 current_face, rev_dir_bit);
2977 } 3101 }
2978 else if (c >= 040 && c < 0177) 3102 else if (c >= 040 && c < 0177)
2979 { 3103 {
2980 if (p1 >= leftmargin) 3104 if (p1 >= leftmargin)
2981 *p1 = MAKE_GLYPH (f, c, current_face); 3105 *p1 = MAKE_GLYPH (f, c, current_face) | rev_dir_bit;
2982 p1++; 3106 p1++;
2983 } 3107 }
2984 else if (c == '\n') 3108 else if (c == '\n')
@@ -2993,7 +3117,7 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
2993 { 3117 {
2994 invis = 1; 3118 invis = 1;
2995 pos = find_next_newline (pos + 1, 1); 3119 pos = find_next_newline (pos + 1, 1);
2996 if (FETCH_CHAR (pos - 1) == '\n') 3120 if (FETCH_BYTE (pos - 1) == '\n')
2997 pos--; 3121 pos--;
2998 } 3122 }
2999 if (invis && selective_rlen > 0 && p1 >= leftmargin) 3123 if (invis && selective_rlen > 0 && p1 >= leftmargin)
@@ -3002,7 +3126,7 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3002 if (p1 - leftmargin > width) 3126 if (p1 - leftmargin > width)
3003 p1 = endp; 3127 p1 = endp;
3004 copy_part_of_rope (f, p1prev, p1prev, invis_vector_contents, 3128 copy_part_of_rope (f, p1prev, p1prev, invis_vector_contents,
3005 (p1 - p1prev), current_face); 3129 (p1 - p1prev), current_face, rev_dir_bit);
3006 } 3130 }
3007#ifdef HAVE_FACES 3131#ifdef HAVE_FACES
3008 /* Draw the face of the newline character as extending all the 3132 /* Draw the face of the newline character as extending all the
@@ -3012,7 +3136,7 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3012 if (p1 < leftmargin) 3136 if (p1 < leftmargin)
3013 p1 = leftmargin; 3137 p1 = leftmargin;
3014 while (p1 < endp) 3138 while (p1 < endp)
3015 *p1++ = FAST_MAKE_GLYPH (' ', current_face); 3139 *p1++ = FAST_MAKE_GLYPH (' ', current_face) | rev_dir_bit;
3016 } 3140 }
3017#endif 3141#endif
3018 3142
@@ -3041,7 +3165,7 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3041 do 3165 do
3042 { 3166 {
3043 if (p1 >= leftmargin && p1 < endp) 3167 if (p1 >= leftmargin && p1 < endp)
3044 *p1 = MAKE_GLYPH (f, ' ', current_face); 3168 *p1 = MAKE_GLYPH (f, ' ', current_face) | rev_dir_bit;
3045 p1++; 3169 p1++;
3046 } 3170 }
3047 while ((p1 - leftmargin + taboffset + hscroll - (hscroll > 0)) 3171 while ((p1 - leftmargin + taboffset + hscroll - (hscroll > 0))
@@ -3050,7 +3174,7 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3050 else if (c == Ctl ('M') && selective == -1) 3174 else if (c == Ctl ('M') && selective == -1)
3051 { 3175 {
3052 pos = find_next_newline (pos, 1); 3176 pos = find_next_newline (pos, 1);
3053 if (FETCH_CHAR (pos - 1) == '\n') 3177 if (FETCH_BYTE (pos - 1) == '\n')
3054 pos--; 3178 pos--;
3055 if (selective_rlen > 0) 3179 if (selective_rlen > 0)
3056 { 3180 {
@@ -3058,7 +3182,7 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3058 if (p1 - leftmargin > width) 3182 if (p1 - leftmargin > width)
3059 p1 = endp; 3183 p1 = endp;
3060 copy_part_of_rope (f, p1prev, p1prev, invis_vector_contents, 3184 copy_part_of_rope (f, p1prev, p1prev, invis_vector_contents,
3061 (p1 - p1prev), current_face); 3185 (p1 - p1prev), current_face, rev_dir_bit);
3062 } 3186 }
3063#ifdef HAVE_FACES 3187#ifdef HAVE_FACES
3064 /* Draw the face of the newline character as extending all the 3188 /* Draw the face of the newline character as extending all the
@@ -3068,7 +3192,7 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3068 if (p1 < leftmargin) 3192 if (p1 < leftmargin)
3069 p1 = leftmargin; 3193 p1 = leftmargin;
3070 while (p1 < endp) 3194 while (p1 < endp)
3071 *p1++ = FAST_MAKE_GLYPH (' ', current_face); 3195 *p1++ = FAST_MAKE_GLYPH (' ', current_face) | rev_dir_bit;
3072 } 3196 }
3073#endif 3197#endif
3074 3198
@@ -3094,34 +3218,54 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3094 else if (c < 0200 && ctl_arrow) 3218 else if (c < 0200 && ctl_arrow)
3095 { 3219 {
3096 if (p1 >= leftmargin) 3220 if (p1 >= leftmargin)
3097 *p1 = fix_glyph (f, (dp && INTEGERP (DISP_CTRL_GLYPH (dp)) 3221 *p1 = (fix_glyph (f, (dp && INTEGERP (DISP_CTRL_GLYPH (dp))
3098 ? XINT (DISP_CTRL_GLYPH (dp)) : '^'), 3222 ? XINT (DISP_CTRL_GLYPH (dp)) : '^'),
3099 current_face); 3223 current_face)
3224 | rev_dir_bit);
3100 p1++; 3225 p1++;
3101 if (p1 >= leftmargin && p1 < endp) 3226 if (p1 >= leftmargin && p1 < endp)
3102 *p1 = MAKE_GLYPH (f, c ^ 0100, current_face); 3227 *p1 = MAKE_GLYPH (f, c ^ 0100, current_face) | rev_dir_bit;
3103 p1++; 3228 p1++;
3104 } 3229 }
3105 else 3230 else if (len == 1)
3106 { 3231 {
3232 /* C is not a multibyte character. */
3107 if (p1 >= leftmargin) 3233 if (p1 >= leftmargin)
3108 *p1 = fix_glyph (f, (dp && INTEGERP (DISP_ESCAPE_GLYPH (dp)) 3234 *p1 = (fix_glyph (f, (dp && INTEGERP (DISP_ESCAPE_GLYPH (dp))
3109 ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'), 3235 ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'),
3110 current_face); 3236 current_face)
3237 | rev_dir_bit);
3111 p1++; 3238 p1++;
3112 if (p1 >= leftmargin && p1 < endp) 3239 if (p1 >= leftmargin && p1 < endp)
3113 *p1 = MAKE_GLYPH (f, (c >> 6) + '0', current_face); 3240 *p1 = MAKE_GLYPH (f, (c >> 6) + '0', current_face) | rev_dir_bit;
3114 p1++; 3241 p1++;
3115 if (p1 >= leftmargin && p1 < endp) 3242 if (p1 >= leftmargin && p1 < endp)
3116 *p1 = MAKE_GLYPH (f, (7 & (c >> 3)) + '0', current_face); 3243 *p1 = (MAKE_GLYPH (f, (7 & (c >> 3)) + '0', current_face)
3244 | rev_dir_bit);
3117 p1++; 3245 p1++;
3118 if (p1 >= leftmargin && p1 < endp) 3246 if (p1 >= leftmargin && p1 < endp)
3119 *p1 = MAKE_GLYPH (f, (7 & c) + '0', current_face); 3247 *p1 = MAKE_GLYPH (f, (7 & c) + '0', current_face) | rev_dir_bit;
3120 p1++; 3248 p1++;
3121 } 3249 }
3250 else
3251 {
3252 /* C is a multibyte character. */
3253 int charset = CHAR_CHARSET (c);
3254 int columns = (charset == CHARSET_COMPOSITION
3255 ? cmpchar_table[COMPOSITE_CHAR_ID (c)]->width
3256 : CHARSET_WIDTH (charset));
3257 GLYPH g = MAKE_GLYPH (f, c, current_face) | rev_dir_bit;
3258
3259 while (columns--)
3260 {
3261 if (p1 >= leftmargin && p1 < endp)
3262 *p1 = g, g |= GLYPH_MASK_PADDING;
3263 p1++;
3264 }
3265 }
3122 3266
3123 prevpos = pos; 3267 prevpos = pos;
3124 pos++; 3268 pos += len;
3125 3269
3126 /* Update charstarts for the character just output. */ 3270 /* Update charstarts for the character just output. */
3127 3271
@@ -3174,10 +3318,37 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3174 This occurs when the minibuffer prompt takes up the whole line. */ 3318 This occurs when the minibuffer prompt takes up the whole line. */
3175 if (p1prev) 3319 if (p1prev)
3176 { 3320 {
3177 /* Start the next line with that same character */ 3321 /* Start the next line with that same character whose
3178 pos--; 3322 character code is C and the length of multi-byte form is
3179 /* but at negative hpos, to skip the columns output on this line. */ 3323 LEN. */
3180 val.hpos += p1prev - endp; 3324 pos = prevpos;
3325
3326 if (len == 1)
3327 /* C is not a multi-byte character. We can break it and
3328 start from the middle column in the next line. So,
3329 adjust VAL.HPOS to skip the columns output on this
3330 line. */
3331 val.hpos += p1prev - endp;
3332 else
3333 {
3334 /* C is a multibyte character. Since we can't broke it
3335 in the middle, the whole character should be driven
3336 into the next line. */
3337 /* As the result, the actual columns occupied by the
3338 text on this line is less than WIDTH. VAL.TAB_OFFSET
3339 must be adjusted. */
3340 taboffset = taboffset + (p1prev - endp);
3341 /* Let's fill unused columns with TRUNCATOR or CONTINUER. */
3342 {
3343 GLYPH g = fix_glyph (f, truncate ? truncator : continuer, 0);
3344 while (p1prev < endp)
3345 *p1prev++ = g;
3346 }
3347 /* If POINT is at POS, cursor should not on this line. */
3348 lastpos = pos;
3349 if (PT == pos)
3350 cursor_vpos = -1;
3351 }
3181 } 3352 }
3182 3353
3183 /* Keep in this line everything up to the continuation column. */ 3354 /* Keep in this line everything up to the continuation column. */
@@ -3191,10 +3362,11 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3191 3362
3192 if (pos < ZV) 3363 if (pos < ZV)
3193 { 3364 {
3194 if (FETCH_CHAR (pos) == '\n') 3365 if (FETCH_BYTE (pos) == '\n')
3195 { 3366 {
3196 /* If stopped due to a newline, start next line after it */ 3367 /* If stopped due to a newline, start next line after it */
3197 pos++; 3368 pos++;
3369 val.tab_offset = 0;
3198 /* Check again for hidden lines, in case the newline occurred exactly 3370 /* Check again for hidden lines, in case the newline occurred exactly
3199 at the right margin. */ 3371 at the right margin. */
3200 while (pos < ZV && selective > 0 3372 while (pos < ZV && selective > 0
@@ -3216,16 +3388,20 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3216 && indented_beyond_p (pos, selective)); 3388 && indented_beyond_p (pos, selective));
3217 val.hpos = XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0; 3389 val.hpos = XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0;
3218 3390
3219 lastpos = pos - (FETCH_CHAR (pos - 1) == '\n'); 3391 lastpos = pos - (FETCH_BYTE (pos - 1) == '\n');
3392 val.tab_offset = 0;
3220 } 3393 }
3221 else 3394 else
3222 { 3395 {
3223 *p1++ = fix_glyph (f, continuer, 0); 3396 *p1++ = fix_glyph (f, continuer, 0);
3224 val.vpos = 0; 3397 val.vpos = 0;
3225 lastpos--; 3398 lastpos--;
3399 val.tab_offset = taboffset + width;
3226 } 3400 }
3227 } 3401 }
3228 } 3402 }
3403 else
3404 val.tab_offset = 0;
3229 3405
3230 /* If point is at eol or in invisible text at eol, 3406 /* If point is at eol or in invisible text at eol,
3231 record its frame location now. */ 3407 record its frame location now. */
@@ -3273,9 +3449,16 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3273 /* If hscroll and line not empty, insert truncation-at-left marker */ 3449 /* If hscroll and line not empty, insert truncation-at-left marker */
3274 if (hscroll && lastpos != start) 3450 if (hscroll && lastpos != start)
3275 { 3451 {
3276 *leftmargin = fix_glyph (f, truncator, 0); 3452 GLYPH g = fix_glyph (f, truncator, 0);
3453 *leftmargin = g;
3277 if (p1 <= leftmargin) 3454 if (p1 <= leftmargin)
3278 p1 = leftmargin + 1; 3455 p1 = leftmargin + 1;
3456 else /* MULE: it may be a wide-column character */
3457 {
3458 p1prev = leftmargin + 1;
3459 while (p1prev < p1 && *p1prev & GLYPH_MASK_PADDING)
3460 *p1prev++ = g;
3461 }
3279 } 3462 }
3280 3463
3281 if (!WINDOW_RIGHTMOST_P (w)) 3464 if (!WINDOW_RIGHTMOST_P (w))
@@ -3454,9 +3637,13 @@ display_mode_line (w)
3454 { 3637 {
3455 /* For a partial width window, explicitly set face of each glyph. */ 3638 /* For a partial width window, explicitly set face of each glyph. */
3456 int i; 3639 int i;
3640 unsigned int padding;
3457 GLYPH *ptr = FRAME_DESIRED_GLYPHS (f)->glyphs[vpos]; 3641 GLYPH *ptr = FRAME_DESIRED_GLYPHS (f)->glyphs[vpos];
3458 for (i = left; i < right; ++i) 3642 for (i = left; i < right; ++i)
3459 ptr[i] = FAST_MAKE_GLYPH (FAST_GLYPH_CHAR (ptr[i]), 1); 3643 {
3644 padding = ptr[i] & GLYPH_MASK_PADDING;
3645 ptr[i] = FAST_MAKE_GLYPH (FAST_GLYPH_CHAR (ptr[i]), 1) | padding;
3646 }
3460 } 3647 }
3461#endif 3648#endif
3462 3649
@@ -3730,6 +3917,46 @@ pint2str (buf, width, d)
3730 } 3917 }
3731} 3918}
3732 3919
3920/* Set a mnemonic character for CODING_SYSTEM (Lisp symbol) in BUF.
3921 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
3922 type of CODING_SYSTEM. Return updated pointer into BUF. */
3923
3924static char *
3925decode_mode_spec_coding (coding_system, buf, eol_flag)
3926 Lisp_Object coding_system;
3927 register char *buf;
3928 int eol_flag;
3929{
3930 register Lisp_Object val = coding_system;
3931
3932 if (NILP (val)) /* Not yet decided. */
3933 {
3934 *buf++ = '-';
3935 if (eol_flag) *buf++ = eol_mnemonic_undecided;
3936 }
3937 else
3938 {
3939 while (!NILP (val) && SYMBOLP (val))
3940 val = Fget (val, Qcoding_system);
3941 *buf++ = XFASTINT (XVECTOR (val)->contents[1]);
3942 if (eol_flag)
3943 {
3944 val = Fget (coding_system, Qeol_type);
3945
3946 if (NILP (val)) /* Not yet decided. */
3947 *buf++ = eol_mnemonic_undecided;
3948 else if (VECTORP (val)) /* Not yet decided. */
3949 *buf++ = eol_mnemonic_undecided;
3950 else /* INTEGERP (val) -- 1:LF, 2:CRLF, 3:CR */
3951 *buf++ = (XFASTINT (val) == 1
3952 ? eol_mnemonic_unix
3953 : (XFASTINT (val) == 2
3954 ? eol_mnemonic_dos : eol_mnemonic_mac));
3955 }
3956 }
3957 return buf;
3958}
3959
3733/* Return a string for the output of a mode line %-spec for window W, 3960/* Return a string for the output of a mode line %-spec for window W,
3734 generated by character C. SPEC_WIDTH is the field width when 3961 generated by character C. SPEC_WIDTH is the field width when
3735 padding to the left (%c, %l). The value returned from this 3962 padding to the left (%c, %l). The value returned from this
@@ -4052,6 +4279,36 @@ decode_mode_spec (w, c, spec_width, maxwidth)
4052#else 4279#else
4053 return "T"; 4280 return "T";
4054#endif 4281#endif
4282
4283 case 'z':
4284 /* coding-system (not including end-of-line format) */
4285 case 'Z':
4286 /* coding-system (including end-of-line type) */
4287 {
4288 int eol_flag = (c == 'Z');
4289 char *p;
4290
4291 p = decode_mode_spec_coding
4292 (find_symbol_value (Qbuffer_file_coding_system),
4293 decode_mode_spec_buf, eol_flag);
4294 if (FRAME_TERMCAP_P (f))
4295 {
4296 p = decode_mode_spec_coding (keyboard_coding.symbol, p, eol_flag);
4297 p = decode_mode_spec_coding (terminal_coding.symbol, p, eol_flag);
4298 }
4299#ifdef subprocesses
4300 obj = Fget_buffer_process (Fcurrent_buffer ());
4301 if (PROCESSP (obj))
4302 {
4303 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
4304 p, eol_flag);
4305 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
4306 p, eol_flag);
4307 }
4308#endif /* subprocesses */
4309 *p = 0;
4310 return decode_mode_spec_buf;
4311 }
4055 } 4312 }
4056 4313
4057 if (STRINGP (obj)) 4314 if (STRINGP (obj))
@@ -4104,8 +4361,8 @@ display_scan_buffer (start, count, shortage)
4104 { 4361 {
4105 ceiling = BUFFER_CEILING_OF (start); 4362 ceiling = BUFFER_CEILING_OF (start);
4106 ceiling = min (limit, ceiling); 4363 ceiling = min (limit, ceiling);
4107 ceiling_addr = &FETCH_CHAR (ceiling) + 1; 4364 ceiling_addr = POS_ADDR (ceiling) + 1;
4108 base = (cursor = &FETCH_CHAR (start)); 4365 base = (cursor = POS_ADDR (start));
4109 while (1) 4366 while (1)
4110 { 4367 {
4111 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr) 4368 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
@@ -4133,8 +4390,8 @@ display_scan_buffer (start, count, shortage)
4133 { /* we WILL scan under start */ 4390 { /* we WILL scan under start */
4134 ceiling = BUFFER_FLOOR_OF (start); 4391 ceiling = BUFFER_FLOOR_OF (start);
4135 ceiling = max (limit, ceiling); 4392 ceiling = max (limit, ceiling);
4136 ceiling_addr = &FETCH_CHAR (ceiling) - 1; 4393 ceiling_addr = POS_ADDR (ceiling) - 1;
4137 base = (cursor = &FETCH_CHAR (start)); 4394 base = (cursor = POS_ADDR (start));
4138 cursor++; 4395 cursor++;
4139 while (1) 4396 while (1)
4140 { 4397 {
@@ -4235,6 +4492,8 @@ display_string (w, vpos, string, length, hpos, truncate,
4235 struct frame_glyphs *desired_glyphs = FRAME_DESIRED_GLYPHS (f); 4492 struct frame_glyphs *desired_glyphs = FRAME_DESIRED_GLYPHS (f);
4236 GLYPH *p1start = desired_glyphs->glyphs[vpos] + hpos; 4493 GLYPH *p1start = desired_glyphs->glyphs[vpos] + hpos;
4237 int window_width = XFASTINT (w->width); 4494 int window_width = XFASTINT (w->width);
4495 /* If 1, we must display multibyte characters. */
4496 int multibyte = !NILP (XBUFFER (w->buffer)->enable_multibyte_characters);
4238 4497
4239 /* Use the standard display table, not the window's display table. 4498 /* Use the standard display table, not the window's display table.
4240 We don't want the mode line in rot13. */ 4499 We don't want the mode line in rot13. */
@@ -4278,20 +4537,25 @@ display_string (w, vpos, string, length, hpos, truncate,
4278 if (maxcol >= 0 && mincol > maxcol) 4537 if (maxcol >= 0 && mincol > maxcol)
4279 mincol = maxcol; 4538 mincol = maxcol;
4280 4539
4540 if (length < 0)
4541 /* We need this value for multibyte characters. */
4542 length = strlen (string);
4543
4281 /* We set truncated to 1 if we get stopped by trying to pass END 4544 /* We set truncated to 1 if we get stopped by trying to pass END
4282 (that is, trying to pass MAXCOL.) */ 4545 (that is, trying to pass MAXCOL.) */
4283 truncated = 0; 4546 truncated = 0;
4284 while (1) 4547 while (1)
4285 { 4548 {
4286 if (length == 0) 4549 int len;
4287 break; 4550
4288 c = *string++; 4551 if (length <= 0)
4289 /* Specified length. */
4290 if (length >= 0)
4291 length--;
4292 /* Unspecified length (null-terminated string). */
4293 else if (c == 0)
4294 break; 4552 break;
4553 if (multibyte)
4554 c = STRING_CHAR_AND_LENGTH (string, length, len);
4555 else
4556 c = *string, len = 1;
4557
4558 string += len, length -= len;
4295 4559
4296 if (p1 >= end) 4560 if (p1 >= end)
4297 { 4561 {
@@ -4333,8 +4597,9 @@ display_string (w, vpos, string, length, hpos, truncate,
4333 *p1 = c ^ 0100; 4597 *p1 = c ^ 0100;
4334 p1++; 4598 p1++;
4335 } 4599 }
4336 else 4600 else if (len == 1)
4337 { 4601 {
4602 /* C is a control character or a binary byte data. */
4338 if (p1 >= start) 4603 if (p1 >= start)
4339 *p1 = fix_glyph (f, (dp && INTEGERP (DISP_ESCAPE_GLYPH (dp)) 4604 *p1 = fix_glyph (f, (dp && INTEGERP (DISP_ESCAPE_GLYPH (dp))
4340 ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'), 4605 ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'),
@@ -4350,6 +4615,48 @@ display_string (w, vpos, string, length, hpos, truncate,
4350 *p1 = (7 & c) + '0'; 4615 *p1 = (7 & c) + '0';
4351 p1++; 4616 p1++;
4352 } 4617 }
4618 else
4619 {
4620 /* C is a multibyte character. */
4621 int charset = CHAR_CHARSET (c);
4622 int columns = (charset == CHARSET_COMPOSITION
4623 ? cmpchar_table[COMPOSITE_CHAR_ID (c)]->width
4624 : CHARSET_WIDTH (charset));
4625
4626 if (p1 < start)
4627 {
4628 /* Since we can't show the left part of C, fill all
4629 columns with spaces. */
4630 columns -= start - p1;
4631 p1 = start;
4632 while (columns--)
4633 {
4634 if (p1 < end)
4635 *p1 = SPACEGLYPH;
4636 p1++;
4637 }
4638 }
4639 else if (p1 + columns > end)
4640 {
4641 /* Since we can't show the right part of C, fill all
4642 columns with TRUNCATE if TRUNCATE is specified. */
4643 if (truncate)
4644 {
4645 while (p1 < end)
4646 *p1++ = fix_glyph (f, truncate, 0);
4647 /* And tell the line is truncated. */
4648 truncated = 1;
4649 }
4650 break;
4651 }
4652 else
4653 {
4654 /* We can show the whole glyph of C. */
4655 *p1++ = c;
4656 while (--columns)
4657 *p1++ = c | GLYPH_MASK_PADDING;
4658 }
4659 }
4353 } 4660 }
4354 4661
4355 if (truncated) 4662 if (truncated)