diff options
| author | Kenichi Handa | 2004-11-30 08:19:32 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2004-11-30 08:19:32 +0000 |
| commit | af645abff50eb8209d3c9d21bf8ca8bdee85212f (patch) | |
| tree | 87abbcc42a8d9a6948225c316a06844aaff6c323 | |
| parent | 2a47931bdbc9fe78f9c777180c7011dc4f52e373 (diff) | |
| download | emacs-af645abff50eb8209d3c9d21bf8ca8bdee85212f.tar.gz emacs-af645abff50eb8209d3c9d21bf8ca8bdee85212f.zip | |
(encode_terminal_buf, encode_terminal_bufsize): New
variables.
(encode_terminal_code): Argument changed. Encode all
characters at once, and return a pointer to the result of
encoding.
(write_glyphs): Decide coding here. Adjusted for the above
change.
(insert_glyphs): Likewise.
(term_init): Initialize encode_terminal_bufsize to 0.
| -rw-r--r-- | src/term.c | 241 |
1 files changed, 120 insertions, 121 deletions
diff --git a/src/term.c b/src/term.c index dc0e51cdf81..7654b64bbe5 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -791,39 +791,43 @@ clear_end_of_line (first_unused_hpos) | |||
| 791 | } | 791 | } |
| 792 | } | 792 | } |
| 793 | 793 | ||
| 794 | /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and | 794 | /* Buffer to store the source and result of code conversion for terminal. */ |
| 795 | store them at DST. Do not write more than DST_LEN bytes. That may | 795 | static unsigned char *encode_terminal_buf; |
| 796 | require stopping before all SRC_LEN input glyphs have been | 796 | /* Allocated size of the above buffer. */ |
| 797 | converted. | 797 | static int encode_terminal_bufsize; |
| 798 | 798 | ||
| 799 | We store the number of glyphs actually converted in *CONSUMED. The | 799 | /* Encode SRC_LEN glyphs starting at SRC to terminal output codes. |
| 800 | return value is the number of bytes store in DST. */ | 800 | Set CODING->produced to the byte-length of the resulting byte |
| 801 | sequence, and return a pointer to that byte sequence. */ | ||
| 801 | 802 | ||
| 802 | int | 803 | static unsigned char * |
| 803 | encode_terminal_code (src, dst, src_len, dst_len, consumed) | 804 | encode_terminal_code (src, src_len, coding) |
| 804 | struct glyph *src; | 805 | struct glyph *src; |
| 805 | int src_len; | 806 | int src_len; |
| 806 | unsigned char *dst; | 807 | struct coding_system *coding; |
| 807 | int dst_len, *consumed; | ||
| 808 | { | 808 | { |
| 809 | struct glyph *src_start = src, *src_end = src + src_len; | 809 | struct glyph *src_start = src, *src_end = src + src_len; |
| 810 | unsigned char *dst_start = dst, *dst_end = dst + dst_len; | ||
| 811 | register GLYPH g; | 810 | register GLYPH g; |
| 812 | unsigned char workbuf[MAX_MULTIBYTE_LENGTH]; | 811 | unsigned char *buf; |
| 813 | const unsigned char *buf; | 812 | int nchars, nbytes, required; |
| 814 | int len; | ||
| 815 | register int tlen = GLYPH_TABLE_LENGTH; | 813 | register int tlen = GLYPH_TABLE_LENGTH; |
| 816 | register Lisp_Object *tbase = GLYPH_TABLE_BASE; | 814 | register Lisp_Object *tbase = GLYPH_TABLE_BASE; |
| 817 | int result; | ||
| 818 | struct coding_system *coding; | ||
| 819 | 815 | ||
| 820 | /* If terminal_coding does any conversion, use it, otherwise use | 816 | /* Allocate sufficient size of buffer to store all characters in |
| 821 | safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here | 817 | multibyte-form. But, it may be enlarged on demand if |
| 822 | because it always return 1 if the member src_multibyte is 1. */ | 818 | Vglyph_table contains a string. */ |
| 823 | coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK | 819 | required = MAX_MULTIBYTE_LENGTH * src_len; |
| 824 | ? &terminal_coding | 820 | if (encode_terminal_bufsize < required) |
| 825 | : &safe_terminal_coding); | 821 | { |
| 822 | encode_terminal_bufsize = required; | ||
| 823 | if (encode_terminal_bufsize == 0) | ||
| 824 | encode_terminal_buf = xmalloc (required); | ||
| 825 | else | ||
| 826 | encode_terminal_buf = xrealloc (encode_terminal_buf, required); | ||
| 827 | } | ||
| 826 | 828 | ||
| 829 | buf = encode_terminal_buf; | ||
| 830 | nchars = 0; | ||
| 827 | while (src < src_end) | 831 | while (src < src_end) |
| 828 | { | 832 | { |
| 829 | /* We must skip glyphs to be padded for a wide character. */ | 833 | /* We must skip glyphs to be padded for a wide character. */ |
| @@ -834,18 +838,11 @@ encode_terminal_code (src, dst, src_len, dst_len, consumed) | |||
| 834 | if (g < 0 || g >= tlen) | 838 | if (g < 0 || g >= tlen) |
| 835 | { | 839 | { |
| 836 | /* This glyph doesn't has an entry in Vglyph_table. */ | 840 | /* This glyph doesn't has an entry in Vglyph_table. */ |
| 837 | if (! CHAR_VALID_P (src->u.ch, 0)) | 841 | if (CHAR_VALID_P (src->u.ch, 0)) |
| 838 | { | 842 | buf += CHAR_STRING (src->u.ch, buf); |
| 839 | len = 1; | ||
| 840 | buf = " "; | ||
| 841 | coding->src_multibyte = 0; | ||
| 842 | } | ||
| 843 | else | 843 | else |
| 844 | { | 844 | *buf++ = SPACEGLYPH; |
| 845 | len = CHAR_STRING (src->u.ch, workbuf); | 845 | nchars++; |
| 846 | buf = workbuf; | ||
| 847 | coding->src_multibyte = 1; | ||
| 848 | } | ||
| 849 | } | 846 | } |
| 850 | else | 847 | else |
| 851 | { | 848 | { |
| @@ -855,61 +852,72 @@ encode_terminal_code (src, dst, src_len, dst_len, consumed) | |||
| 855 | 852 | ||
| 856 | if (GLYPH_SIMPLE_P (tbase, tlen, g)) | 853 | if (GLYPH_SIMPLE_P (tbase, tlen, g)) |
| 857 | { | 854 | { |
| 858 | /* We set the multi-byte form of a character in G | 855 | int c = FAST_GLYPH_CHAR (g); |
| 859 | (that should be an ASCII character) at | 856 | |
| 860 | WORKBUF. */ | 857 | if (CHAR_VALID_P (c, 0)) |
| 861 | workbuf[0] = FAST_GLYPH_CHAR (g); | 858 | buf += CHAR_STRING (c, buf); |
| 862 | len = 1; | 859 | else |
| 863 | buf = workbuf; | 860 | *buf++ = SPACEGLYPH; |
| 864 | coding->src_multibyte = 0; | 861 | nchars++; |
| 865 | } | 862 | } |
| 866 | else | 863 | else |
| 867 | { | 864 | { |
| 868 | /* We have a string in Vglyph_table. */ | 865 | /* We have a string in Vglyph_table. */ |
| 869 | len = GLYPH_LENGTH (tbase, g); | 866 | Lisp_Object string; |
| 870 | buf = GLYPH_STRING (tbase, g); | 867 | |
| 871 | coding->src_multibyte = STRING_MULTIBYTE (tbase[g]); | 868 | string = tbase[g]; |
| 869 | if (! STRING_MULTIBYTE (string)) | ||
| 870 | string = string_to_multibyte (string); | ||
| 871 | nbytes = buf - encode_terminal_buf; | ||
| 872 | if (nbytes + SBYTES (string) < encode_terminal_bufsize) | ||
| 873 | { | ||
| 874 | encode_terminal_bufsize = nbytes + SBYTES (string); | ||
| 875 | encode_terminal_buf = xrealloc (encode_terminal_buf, | ||
| 876 | encode_terminal_bufsize); | ||
| 877 | buf = encode_terminal_buf + nbytes; | ||
| 878 | } | ||
| 879 | bcopy (SDATA (string), buf, SBYTES (string)); | ||
| 880 | buf += SBYTES (string); | ||
| 881 | nchars += SCHARS (string); | ||
| 872 | } | 882 | } |
| 873 | } | 883 | } |
| 874 | |||
| 875 | result = encode_coding (coding, buf, dst, len, dst_end - dst); | ||
| 876 | len -= coding->consumed; | ||
| 877 | dst += coding->produced; | ||
| 878 | if (result == CODING_FINISH_INSUFFICIENT_DST | ||
| 879 | || (result == CODING_FINISH_INSUFFICIENT_SRC | ||
| 880 | && len > dst_end - dst)) | ||
| 881 | /* The remaining output buffer is too short. We must | ||
| 882 | break the loop here without increasing SRC so that the | ||
| 883 | next call of this function starts from the same glyph. */ | ||
| 884 | break; | ||
| 885 | |||
| 886 | if (len > 0) | ||
| 887 | { | ||
| 888 | /* This is the case that a code of the range 0200..0237 | ||
| 889 | exists in buf. We must just write out such a code. */ | ||
| 890 | buf += coding->consumed; | ||
| 891 | while (len--) | ||
| 892 | *dst++ = *buf++; | ||
| 893 | } | ||
| 894 | } | 884 | } |
| 895 | src++; | 885 | src++; |
| 896 | } | 886 | } |
| 897 | 887 | ||
| 898 | *consumed = src - src_start; | 888 | nbytes = buf - encode_terminal_buf; |
| 899 | return (dst - dst_start); | 889 | coding->src_multibyte = 1; |
| 900 | } | 890 | coding->dst_multibyte = 0; |
| 891 | if (SYMBOLP (coding->pre_write_conversion) | ||
| 892 | && ! NILP (Ffboundp (coding->pre_write_conversion))) | ||
| 893 | { | ||
| 894 | run_pre_write_conversin_on_c_str (&encode_terminal_buf, | ||
| 895 | &encode_terminal_bufsize, | ||
| 896 | nchars, nbytes, coding); | ||
| 897 | nchars = coding->produced_char; | ||
| 898 | nbytes = coding->produced; | ||
| 899 | } | ||
| 900 | required = nbytes + encoding_buffer_size (coding, nbytes); | ||
| 901 | if (encode_terminal_bufsize < required) | ||
| 902 | { | ||
| 903 | encode_terminal_bufsize = required; | ||
| 904 | encode_terminal_buf = xrealloc (encode_terminal_buf, required); | ||
| 905 | } | ||
| 901 | 906 | ||
| 907 | encode_coding (coding, encode_terminal_buf, encode_terminal_buf + nbytes, | ||
| 908 | nbytes, encode_terminal_bufsize - nbytes); | ||
| 909 | return encode_terminal_buf + nbytes; | ||
| 910 | } | ||
| 902 | 911 | ||
| 903 | void | 912 | void |
| 904 | write_glyphs (string, len) | 913 | write_glyphs (string, len) |
| 905 | register struct glyph *string; | 914 | register struct glyph *string; |
| 906 | register int len; | 915 | register int len; |
| 907 | { | 916 | { |
| 908 | int produced, consumed; | ||
| 909 | struct frame *sf = XFRAME (selected_frame); | 917 | struct frame *sf = XFRAME (selected_frame); |
| 910 | struct frame *f = updating_frame ? updating_frame : sf; | 918 | struct frame *f = updating_frame ? updating_frame : sf; |
| 911 | unsigned char conversion_buffer[1024]; | 919 | unsigned char *conversion_buffer; |
| 912 | int conversion_buffer_size = sizeof conversion_buffer; | 920 | struct coding_system *coding; |
| 913 | 921 | ||
| 914 | if (write_glyphs_hook | 922 | if (write_glyphs_hook |
| 915 | && ! FRAME_TERMCAP_P (f)) | 923 | && ! FRAME_TERMCAP_P (f)) |
| @@ -933,9 +941,14 @@ write_glyphs (string, len) | |||
| 933 | 941 | ||
| 934 | cmplus (len); | 942 | cmplus (len); |
| 935 | 943 | ||
| 944 | /* If terminal_coding does any conversion, use it, otherwise use | ||
| 945 | safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here | ||
| 946 | because it always return 1 if the member src_multibyte is 1. */ | ||
| 947 | coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK | ||
| 948 | ? &terminal_coding : &safe_terminal_coding); | ||
| 936 | /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at | 949 | /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at |
| 937 | the tail. */ | 950 | the tail. */ |
| 938 | terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK; | 951 | coding->mode &= ~CODING_MODE_LAST_BLOCK; |
| 939 | 952 | ||
| 940 | while (len > 0) | 953 | while (len > 0) |
| 941 | { | 954 | { |
| @@ -951,49 +964,26 @@ write_glyphs (string, len) | |||
| 951 | highlight_if_desired (); | 964 | highlight_if_desired (); |
| 952 | turn_on_face (f, face_id); | 965 | turn_on_face (f, face_id); |
| 953 | 966 | ||
| 954 | while (n > 0) | 967 | if (n == len) |
| 968 | /* This is the last run. */ | ||
| 969 | coding->mode |= CODING_MODE_LAST_BLOCK; | ||
| 970 | conversion_buffer = encode_terminal_code (string, n, coding); | ||
| 971 | if (coding->produced > 0) | ||
| 955 | { | 972 | { |
| 956 | /* We use a fixed size (1024 bytes) of conversion buffer. | 973 | fwrite (conversion_buffer, 1, coding->produced, stdout); |
| 957 | Usually it is sufficient, but if not, we just repeat the | 974 | if (ferror (stdout)) |
| 958 | loop. */ | 975 | clearerr (stdout); |
| 959 | produced = encode_terminal_code (string, conversion_buffer, | 976 | if (termscript) |
| 960 | n, conversion_buffer_size, | 977 | fwrite (conversion_buffer, 1, coding->produced, termscript); |
| 961 | &consumed); | ||
| 962 | if (produced > 0) | ||
| 963 | { | ||
| 964 | fwrite (conversion_buffer, 1, produced, stdout); | ||
| 965 | if (ferror (stdout)) | ||
| 966 | clearerr (stdout); | ||
| 967 | if (termscript) | ||
| 968 | fwrite (conversion_buffer, 1, produced, termscript); | ||
| 969 | } | ||
| 970 | len -= consumed; | ||
| 971 | n -= consumed; | ||
| 972 | string += consumed; | ||
| 973 | } | 978 | } |
| 979 | len -= n; | ||
| 980 | string += n; | ||
| 974 | 981 | ||
| 975 | /* Turn appearance modes off. */ | 982 | /* Turn appearance modes off. */ |
| 976 | turn_off_face (f, face_id); | 983 | turn_off_face (f, face_id); |
| 977 | turn_off_highlight (); | 984 | turn_off_highlight (); |
| 978 | } | 985 | } |
| 979 | 986 | ||
| 980 | /* We may have to output some codes to terminate the writing. */ | ||
| 981 | if (CODING_REQUIRE_FLUSHING (&terminal_coding)) | ||
| 982 | { | ||
| 983 | terminal_coding.mode |= CODING_MODE_LAST_BLOCK; | ||
| 984 | encode_coding (&terminal_coding, "", conversion_buffer, | ||
| 985 | 0, conversion_buffer_size); | ||
| 986 | if (terminal_coding.produced > 0) | ||
| 987 | { | ||
| 988 | fwrite (conversion_buffer, 1, terminal_coding.produced, stdout); | ||
| 989 | if (ferror (stdout)) | ||
| 990 | clearerr (stdout); | ||
| 991 | if (termscript) | ||
| 992 | fwrite (conversion_buffer, 1, terminal_coding.produced, | ||
| 993 | termscript); | ||
| 994 | } | ||
| 995 | } | ||
| 996 | |||
| 997 | cmcheckmagic (); | 987 | cmcheckmagic (); |
| 998 | } | 988 | } |
| 999 | 989 | ||
| @@ -1007,6 +997,9 @@ insert_glyphs (start, len) | |||
| 1007 | char *buf; | 997 | char *buf; |
| 1008 | struct glyph *glyph = NULL; | 998 | struct glyph *glyph = NULL; |
| 1009 | struct frame *f, *sf; | 999 | struct frame *f, *sf; |
| 1000 | unsigned char *conversion_buffer; | ||
| 1001 | unsigned char space[1]; | ||
| 1002 | struct coding_system *coding; | ||
| 1010 | 1003 | ||
| 1011 | if (len <= 0) | 1004 | if (len <= 0) |
| 1012 | return; | 1005 | return; |
| @@ -1032,19 +1025,26 @@ insert_glyphs (start, len) | |||
| 1032 | 1025 | ||
| 1033 | turn_on_insert (); | 1026 | turn_on_insert (); |
| 1034 | cmplus (len); | 1027 | cmplus (len); |
| 1035 | /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */ | 1028 | |
| 1036 | terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK; | 1029 | if (! start) |
| 1030 | space[0] = SPACEGLYPH; | ||
| 1031 | |||
| 1032 | /* If terminal_coding does any conversion, use it, otherwise use | ||
| 1033 | safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here | ||
| 1034 | because it always return 1 if the member src_multibyte is 1. */ | ||
| 1035 | coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK | ||
| 1036 | ? &terminal_coding : &safe_terminal_coding); | ||
| 1037 | /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at | ||
| 1038 | the tail. */ | ||
| 1039 | coding->mode &= ~CODING_MODE_LAST_BLOCK; | ||
| 1040 | |||
| 1037 | while (len-- > 0) | 1041 | while (len-- > 0) |
| 1038 | { | 1042 | { |
| 1039 | int produced, consumed; | ||
| 1040 | unsigned char conversion_buffer[1024]; | ||
| 1041 | int conversion_buffer_size = sizeof conversion_buffer; | ||
| 1042 | |||
| 1043 | OUTPUT1_IF (TS_ins_char); | 1043 | OUTPUT1_IF (TS_ins_char); |
| 1044 | if (!start) | 1044 | if (!start) |
| 1045 | { | 1045 | { |
| 1046 | conversion_buffer[0] = SPACEGLYPH; | 1046 | conversion_buffer = space; |
| 1047 | produced = 1; | 1047 | coding->produced = 1; |
| 1048 | } | 1048 | } |
| 1049 | else | 1049 | else |
| 1050 | { | 1050 | { |
| @@ -1062,21 +1062,18 @@ insert_glyphs (start, len) | |||
| 1062 | 1062 | ||
| 1063 | if (len <= 0) | 1063 | if (len <= 0) |
| 1064 | /* This is the last glyph. */ | 1064 | /* This is the last glyph. */ |
| 1065 | terminal_coding.mode |= CODING_MODE_LAST_BLOCK; | 1065 | coding->mode |= CODING_MODE_LAST_BLOCK; |
| 1066 | 1066 | ||
| 1067 | /* The size of conversion buffer (1024 bytes) is surely | 1067 | conversion_buffer = encode_terminal_code (glyph, 1, coding); |
| 1068 | sufficient for just one glyph. */ | ||
| 1069 | produced = encode_terminal_code (glyph, conversion_buffer, 1, | ||
| 1070 | conversion_buffer_size, &consumed); | ||
| 1071 | } | 1068 | } |
| 1072 | 1069 | ||
| 1073 | if (produced > 0) | 1070 | if (coding->produced > 0) |
| 1074 | { | 1071 | { |
| 1075 | fwrite (conversion_buffer, 1, produced, stdout); | 1072 | fwrite (conversion_buffer, 1, coding->produced, stdout); |
| 1076 | if (ferror (stdout)) | 1073 | if (ferror (stdout)) |
| 1077 | clearerr (stdout); | 1074 | clearerr (stdout); |
| 1078 | if (termscript) | 1075 | if (termscript) |
| 1079 | fwrite (conversion_buffer, 1, produced, termscript); | 1076 | fwrite (conversion_buffer, 1, coding->produced, termscript); |
| 1080 | } | 1077 | } |
| 1081 | 1078 | ||
| 1082 | OUTPUT1_IF (TS_pad_inserted_char); | 1079 | OUTPUT1_IF (TS_pad_inserted_char); |
| @@ -2257,6 +2254,8 @@ term_init (terminal_type) | |||
| 2257 | int status; | 2254 | int status; |
| 2258 | struct frame *sf = XFRAME (selected_frame); | 2255 | struct frame *sf = XFRAME (selected_frame); |
| 2259 | 2256 | ||
| 2257 | encode_terminal_bufsize = 0; | ||
| 2258 | |||
| 2260 | #ifdef WINDOWSNT | 2259 | #ifdef WINDOWSNT |
| 2261 | initialize_w32_display (); | 2260 | initialize_w32_display (); |
| 2262 | 2261 | ||