diff options
| author | Karl Heuer | 1997-02-20 06:57:21 +0000 |
|---|---|---|
| committer | Karl Heuer | 1997-02-20 06:57:21 +0000 |
| commit | a4decb7fcd7b8d63b3526afc596e5ea972202d7e (patch) | |
| tree | edbcb0a968fcb60af0d9627e90a14c5434e83d1f /src/term.c | |
| parent | e0b8ff939dbb3ea39fcd7967d5d45e7b33ee45a1 (diff) | |
| download | emacs-a4decb7fcd7b8d63b3526afc596e5ea972202d7e.tar.gz emacs-a4decb7fcd7b8d63b3526afc596e5ea972202d7e.zip | |
Include charset.h and coding.h.
(TS_end_italic_mode, TS_italic_mode, TS_bold_mode): New variables.
(TS_end_bold_mode, TS_end_underscore_mode): New variables.
(TS_underscore_mode): New variable.
(encode_terminal_code): New function.
(write_glyphs, insert_glyphs): Perform character code conversion
on output to a terminal.
(term_init): Initialize TS_bold_mode, TS_end_bold_mode,
TS_end_underscore_mode, and TS_underscore_mode.
Diffstat (limited to 'src/term.c')
| -rw-r--r-- | src/term.c | 182 |
1 files changed, 139 insertions, 43 deletions
diff --git a/src/term.c b/src/term.c index ce771533b6f..0042da83600 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -27,6 +27,8 @@ Boston, MA 02111-1307, USA. */ | |||
| 27 | #include "cm.h" | 27 | #include "cm.h" |
| 28 | #undef NULL | 28 | #undef NULL |
| 29 | #include "lisp.h" | 29 | #include "lisp.h" |
| 30 | #include "charset.h" | ||
| 31 | #include "coding.h" | ||
| 30 | #include "frame.h" | 32 | #include "frame.h" |
| 31 | #include "disptab.h" | 33 | #include "disptab.h" |
| 32 | #include "termhooks.h" | 34 | #include "termhooks.h" |
| @@ -196,7 +198,9 @@ void (*judge_scroll_bars_hook)( /* FRAME_PTR *FRAME */ ); | |||
| 196 | 198 | ||
| 197 | /* Strings, numbers and flags taken from the termcap entry. */ | 199 | /* Strings, numbers and flags taken from the termcap entry. */ |
| 198 | 200 | ||
| 199 | char *TS_ins_line; /* termcap "al" */ | 201 | char *TS_end_italic_mode; /* termcal "ae" */ |
| 202 | char *TS_ins_line; /* "al" */ | ||
| 203 | char *TS_italic_mode; /* "as" */ | ||
| 200 | char *TS_ins_multi_lines; /* "AL" (one parameter, # lines to insert) */ | 204 | char *TS_ins_multi_lines; /* "AL" (one parameter, # lines to insert) */ |
| 201 | char *TS_bell; /* "bl" */ | 205 | char *TS_bell; /* "bl" */ |
| 202 | char *TS_clr_to_bottom; /* "cd" */ | 206 | char *TS_clr_to_bottom; /* "cd" */ |
| @@ -219,6 +223,8 @@ char *TS_insert_mode; /* "im", enter character-insert mode */ | |||
| 219 | char *TS_pad_inserted_char; /* "ip". Just padding, no commands. */ | 223 | char *TS_pad_inserted_char; /* "ip". Just padding, no commands. */ |
| 220 | char *TS_end_keypad_mode; /* "ke" */ | 224 | char *TS_end_keypad_mode; /* "ke" */ |
| 221 | char *TS_keypad_mode; /* "ks" */ | 225 | char *TS_keypad_mode; /* "ks" */ |
| 226 | char *TS_bold_mode; /* "md" */ | ||
| 227 | char *TS_end_bold_mode; /* "me" */ | ||
| 222 | char *TS_pad_char; /* "pc", char to use as padding */ | 228 | char *TS_pad_char; /* "pc", char to use as padding */ |
| 223 | char *TS_repeat; /* "rp" (2 params, # times to repeat | 229 | char *TS_repeat; /* "rp" (2 params, # times to repeat |
| 224 | and character to be repeated) */ | 230 | and character to be repeated) */ |
| @@ -228,6 +234,8 @@ char *TS_standout_mode; /* "so" */ | |||
| 228 | char *TS_rev_scroll; /* "sr" */ | 234 | char *TS_rev_scroll; /* "sr" */ |
| 229 | char *TS_end_termcap_modes; /* "te" */ | 235 | char *TS_end_termcap_modes; /* "te" */ |
| 230 | char *TS_termcap_modes; /* "ti" */ | 236 | char *TS_termcap_modes; /* "ti" */ |
| 237 | char *TS_end_underscore_mode; /* "ue" */ | ||
| 238 | char *TS_underscore_mode; /* "us" */ | ||
| 231 | char *TS_visible_bell; /* "vb" */ | 239 | char *TS_visible_bell; /* "vb" */ |
| 232 | char *TS_end_visual_mode; /* "ve" */ | 240 | char *TS_end_visual_mode; /* "ve" */ |
| 233 | char *TS_visual_mode; /* "vi" */ | 241 | char *TS_visual_mode; /* "vi" */ |
| @@ -760,6 +768,74 @@ clear_end_of_line_raw (first_unused_hpos) | |||
| 760 | } | 768 | } |
| 761 | } | 769 | } |
| 762 | 770 | ||
| 771 | /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and | ||
| 772 | store them at DST. Do not write more than DST_LEN bytes. That may | ||
| 773 | require stopping before all SRC_LEN input glyphs have been | ||
| 774 | converted. | ||
| 775 | |||
| 776 | We store the number of glyphs actually converted in *CONSUMED. The | ||
| 777 | return value is the number of bytes store in DST. */ | ||
| 778 | |||
| 779 | int | ||
| 780 | encode_terminal_code (src, dst, src_len, dst_len, consumed) | ||
| 781 | GLYPH *src; | ||
| 782 | int src_len; | ||
| 783 | unsigned char *dst; | ||
| 784 | int dst_len, *consumed; | ||
| 785 | { | ||
| 786 | GLYPH *src_start = src, *src_end = src + src_len; | ||
| 787 | unsigned char *dst_start = dst, *dst_end = dst + dst_len; | ||
| 788 | register GLYPH g = *src; | ||
| 789 | int c = GLYPH_CHAR (selected_frame, g); | ||
| 790 | unsigned char workbuf[4], *buf; | ||
| 791 | int len, produced, processed; | ||
| 792 | register int tlen = GLYPH_TABLE_LENGTH; | ||
| 793 | register Lisp_Object *tbase = GLYPH_TABLE_BASE; | ||
| 794 | |||
| 795 | while (src < src_end) | ||
| 796 | { | ||
| 797 | g = *src; | ||
| 798 | /* We must skip glyphs to be padded for a wide character. */ | ||
| 799 | if (! (g & GLYPH_MASK_PADDING)) | ||
| 800 | { | ||
| 801 | c = GLYPH_CHAR (selected_frame, g); | ||
| 802 | if (COMPOSITE_CHAR_P (c)) | ||
| 803 | { | ||
| 804 | /* If C is a composite character, we can display | ||
| 805 | only the first component. */ | ||
| 806 | g = cmpchar_table[COMPOSITE_CHAR_ID (c)]->glyph[0], | ||
| 807 | c = GLYPH_CHAR (selected_frame, g); | ||
| 808 | } | ||
| 809 | if (c < tlen) | ||
| 810 | { | ||
| 811 | /* G has an entry in Vglyph_table, | ||
| 812 | so process any alias before testing for simpleness. */ | ||
| 813 | GLYPH_FOLLOW_ALIASES (tbase, tlen, g); | ||
| 814 | c = GLYPH_CHAR (selected_frame, g); | ||
| 815 | } | ||
| 816 | if (GLYPH_SIMPLE_P (tbase, tlen, g)) | ||
| 817 | /* We set the multi-byte form of C at BUF. */ | ||
| 818 | len = CHAR_STRING (c, workbuf, buf); | ||
| 819 | else | ||
| 820 | /* We have the multi-byte form in Vglyph_table. */ | ||
| 821 | len = GLYPH_LENGTH (tbase, g), buf = GLYPH_STRING (tbase, g); | ||
| 822 | |||
| 823 | produced = encode_coding (&terminal_coding, buf, dst, | ||
| 824 | len, dst_end - dst, &processed); | ||
| 825 | if (processed < len) | ||
| 826 | /* We get a carryover because the remaining output | ||
| 827 | buffer is too short. We must break the loop here | ||
| 828 | without increasing SRC so that the next call of | ||
| 829 | this function start from the same glyph. */ | ||
| 830 | break; | ||
| 831 | dst += produced; | ||
| 832 | } | ||
| 833 | src++; | ||
| 834 | } | ||
| 835 | *consumed = src - src_start; | ||
| 836 | return (dst - dst_start); | ||
| 837 | } | ||
| 838 | |||
| 763 | 839 | ||
| 764 | write_glyphs (string, len) | 840 | write_glyphs (string, len) |
| 765 | register GLYPH *string; | 841 | register GLYPH *string; |
| @@ -768,6 +844,7 @@ write_glyphs (string, len) | |||
| 768 | register GLYPH g; | 844 | register GLYPH g; |
| 769 | register int tlen = GLYPH_TABLE_LENGTH; | 845 | register int tlen = GLYPH_TABLE_LENGTH; |
| 770 | register Lisp_Object *tbase = GLYPH_TABLE_BASE; | 846 | register Lisp_Object *tbase = GLYPH_TABLE_BASE; |
| 847 | int produced, consumed; | ||
| 771 | 848 | ||
| 772 | if (write_glyphs_hook | 849 | if (write_glyphs_hook |
| 773 | && ! FRAME_TERMCAP_P ((updating_frame ? updating_frame : selected_frame))) | 850 | && ! FRAME_TERMCAP_P ((updating_frame ? updating_frame : selected_frame))) |
| @@ -787,42 +864,42 @@ write_glyphs (string, len) | |||
| 787 | && (curX + len - (chars_wasted[curY] & 077) | 864 | && (curX + len - (chars_wasted[curY] & 077) |
| 788 | == FRAME_WIDTH (selected_frame))) | 865 | == FRAME_WIDTH (selected_frame))) |
| 789 | len --; | 866 | len --; |
| 867 | if (len <= 0) | ||
| 868 | return; | ||
| 790 | 869 | ||
| 791 | cmplus (len); | 870 | cmplus (len); |
| 792 | while (--len >= 0) | 871 | /* The field `last_block' should be set to 1 only at the tail. */ |
| 872 | terminal_coding.last_block = 0; | ||
| 873 | while (len > 0) | ||
| 793 | { | 874 | { |
| 794 | g = *string++; | 875 | /* We use shared conversion buffer of the current size (1024 |
| 795 | /* Check quickly for G beyond length of table. | 876 | bytes at least). Usually it is sufficient, but if not, we |
| 796 | That implies it isn't an alias and is simple. */ | 877 | just repeat the loop. */ |
| 797 | if (g >= tlen) | 878 | produced = encode_terminal_code (string, conversion_buffer, |
| 879 | len, conversion_buffer_size, &consumed); | ||
| 880 | if (produced > 0) | ||
| 798 | { | 881 | { |
| 799 | simple: | 882 | fwrite (conversion_buffer, 1, produced, stdout); |
| 800 | putc (g & 0xff, stdout); | ||
| 801 | if (ferror (stdout)) | 883 | if (ferror (stdout)) |
| 802 | clearerr (stdout); | 884 | clearerr (stdout); |
| 803 | if (termscript) | 885 | if (termscript) |
| 804 | putc (g & 0xff, termscript); | 886 | fwrite (conversion_buffer, 1, produced, termscript); |
| 805 | } | ||
| 806 | else | ||
| 807 | { | ||
| 808 | /* G has an entry in Vglyph_table, | ||
| 809 | so process any alias and then test for simpleness. */ | ||
| 810 | while (GLYPH_ALIAS_P (tbase, tlen, g)) | ||
| 811 | g = GLYPH_ALIAS (tbase, g); | ||
| 812 | if (GLYPH_SIMPLE_P (tbase, tlen, g)) | ||
| 813 | goto simple; | ||
| 814 | else | ||
| 815 | { | ||
| 816 | /* Here if G (or its definition as an alias) is not simple. */ | ||
| 817 | fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g), | ||
| 818 | stdout); | ||
| 819 | if (ferror (stdout)) | ||
| 820 | clearerr (stdout); | ||
| 821 | if (termscript) | ||
| 822 | fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g), | ||
| 823 | termscript); | ||
| 824 | } | ||
| 825 | } | 887 | } |
| 888 | len -= consumed; | ||
| 889 | string += consumed; | ||
| 890 | } | ||
| 891 | /* We may have to output some codes to terminate the writing. */ | ||
| 892 | terminal_coding.last_block = 1; | ||
| 893 | produced = encode_coding (&terminal_coding, (char *)0, conversion_buffer, | ||
| 894 | 0, conversion_buffer_size, | ||
| 895 | &consumed); | ||
| 896 | if (produced > 0) | ||
| 897 | { | ||
| 898 | fwrite (conversion_buffer, 1, produced, stdout); | ||
| 899 | if (ferror (stdout)) | ||
| 900 | clearerr (stdout); | ||
| 901 | if (termscript) | ||
| 902 | fwrite (conversion_buffer, 1, produced, termscript); | ||
| 826 | } | 903 | } |
| 827 | cmcheckmagic (); | 904 | cmcheckmagic (); |
| 828 | } | 905 | } |
| @@ -834,10 +911,13 @@ insert_glyphs (start, len) | |||
| 834 | register int len; | 911 | register int len; |
| 835 | { | 912 | { |
| 836 | char *buf; | 913 | char *buf; |
| 837 | register GLYPH g; | 914 | GLYPH g; |
| 838 | register int tlen = GLYPH_TABLE_LENGTH; | 915 | register int tlen = GLYPH_TABLE_LENGTH; |
| 839 | register Lisp_Object *tbase = GLYPH_TABLE_BASE; | 916 | register Lisp_Object *tbase = GLYPH_TABLE_BASE; |
| 840 | 917 | ||
| 918 | if (len <= 0) | ||
| 919 | return; | ||
| 920 | |||
| 841 | if (insert_glyphs_hook && ! FRAME_TERMCAP_P (updating_frame)) | 921 | if (insert_glyphs_hook && ! FRAME_TERMCAP_P (updating_frame)) |
| 842 | { | 922 | { |
| 843 | (*insert_glyphs_hook) (start, len); | 923 | (*insert_glyphs_hook) (start, len); |
| @@ -857,30 +937,42 @@ insert_glyphs (start, len) | |||
| 857 | 937 | ||
| 858 | turn_on_insert (); | 938 | turn_on_insert (); |
| 859 | cmplus (len); | 939 | cmplus (len); |
| 860 | while (--len >= 0) | 940 | /* The field `last_block' should be set to 1 only at the tail. */ |
| 941 | terminal_coding.last_block = 0; | ||
| 942 | while (len > 0) | ||
| 861 | { | 943 | { |
| 944 | int produced, consumed; | ||
| 945 | |||
| 862 | OUTPUT1_IF (TS_ins_char); | 946 | OUTPUT1_IF (TS_ins_char); |
| 863 | if (!start) | 947 | if (!start) |
| 864 | g = SPACEGLYPH; | 948 | g = SPACEGLYPH; |
| 865 | else | 949 | else |
| 866 | g = *start++; | ||
| 867 | |||
| 868 | if (GLYPH_SIMPLE_P (tbase, tlen, g)) | ||
| 869 | { | 950 | { |
| 870 | putc (g & 0xff, stdout); | 951 | g = *start++; |
| 871 | if (ferror (stdout)) | 952 | /* We must open sufficient space for a character which |
| 872 | clearerr (stdout); | 953 | occupies more than one column. */ |
| 873 | if (termscript) | 954 | while (*start && GLYPH_MASK_PADDING) |
| 874 | putc (g & 0xff, termscript); | 955 | { |
| 956 | OUTPUT1_IF (TS_ins_char); | ||
| 957 | start++, len--; | ||
| 958 | } | ||
| 875 | } | 959 | } |
| 876 | else | 960 | |
| 961 | if (len <= 0) | ||
| 962 | /* This is the last glyph. */ | ||
| 963 | terminal_coding.last_block = 1; | ||
| 964 | |||
| 965 | /* We use shared conversion buffer of the current size (1024 | ||
| 966 | bytes at least). It is surely sufficient for just one glyph. */ | ||
| 967 | produced = encode_terminal_code (&g, conversion_buffer, | ||
| 968 | 1, conversion_buffer_size, &consumed); | ||
| 969 | if (produced > 0) | ||
| 877 | { | 970 | { |
| 878 | fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g), stdout); | 971 | fwrite (conversion_buffer, 1, produced, stdout); |
| 879 | if (ferror (stdout)) | 972 | if (ferror (stdout)) |
| 880 | clearerr (stdout); | 973 | clearerr (stdout); |
| 881 | if (termscript) | 974 | if (termscript) |
| 882 | fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g), | 975 | fwrite (conversion_buffer, 1, produced, termscript); |
| 883 | termscript); | ||
| 884 | } | 976 | } |
| 885 | 977 | ||
| 886 | OUTPUT1_IF (TS_pad_inserted_char); | 978 | OUTPUT1_IF (TS_pad_inserted_char); |
| @@ -1558,6 +1650,10 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", | |||
| 1558 | Wcm.cm_tab = tgetstr ("ta", address); | 1650 | Wcm.cm_tab = tgetstr ("ta", address); |
| 1559 | TS_end_termcap_modes = tgetstr ("te", address); | 1651 | TS_end_termcap_modes = tgetstr ("te", address); |
| 1560 | TS_termcap_modes = tgetstr ("ti", address); | 1652 | TS_termcap_modes = tgetstr ("ti", address); |
| 1653 | TS_bold_mode = tgetstr ("md", address); | ||
| 1654 | TS_end_bold_mode = tgetstr ("me", address); | ||
| 1655 | TS_underscore_mode = tgetstr ("us", address); | ||
| 1656 | TS_end_underscore_mode = tgetstr ("ue", address); | ||
| 1561 | Up = tgetstr ("up", address); | 1657 | Up = tgetstr ("up", address); |
| 1562 | TS_visible_bell = tgetstr ("vb", address); | 1658 | TS_visible_bell = tgetstr ("vb", address); |
| 1563 | TS_end_visual_mode = tgetstr ("ve", address); | 1659 | TS_end_visual_mode = tgetstr ("ve", address); |