diff options
| author | Karl Heuer | 1997-02-20 06:40:53 +0000 |
|---|---|---|
| committer | Karl Heuer | 1997-02-20 06:40:53 +0000 |
| commit | 1c9241f53ad8d5b3684be53b66e936369f852ea3 (patch) | |
| tree | 55979b9d8b28471d7173ab168c9ccf5690f07fbd /src | |
| parent | a997a7ca075879b76589d5e9ab47209cd31ef0f6 (diff) | |
| download | emacs-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.c | 479 |
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) |
| 41 | extern void set_frame_menubar (); | 44 | extern 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 | ||
| 1962 | done: | 2001 | done: |
| 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 | |||
| 3924 | static char * | ||
| 3925 | decode_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) |