aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenichi Handa2004-11-30 08:19:32 +0000
committerKenichi Handa2004-11-30 08:19:32 +0000
commitaf645abff50eb8209d3c9d21bf8ca8bdee85212f (patch)
tree87abbcc42a8d9a6948225c316a06844aaff6c323
parent2a47931bdbc9fe78f9c777180c7011dc4f52e373 (diff)
downloademacs-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.c241
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 795static 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. 797static 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
802int 803static unsigned char *
803encode_terminal_code (src, dst, src_len, dst_len, consumed) 804encode_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
903void 912void
904write_glyphs (string, len) 913write_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