Mercurial > emacs
comparison src/term.c @ 89563:d193de460ec1
(terminal_encode_buffer, terminal_encode_buf_size): New
variables.
(encode_terminal_code): Argument changed. Encode multiple
characters at once. Store the result of encoding in
terminal_encode_buffer.
(write_glyphs): Adjusted for the change of encode_terminal_code.
(insert_glyphs): Likewise.
(term_init): Initialize terminal_encode_buffer and
terminal_encode_buf_size.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Wed, 01 Oct 2003 04:43:53 +0000 |
parents | 2f877ed80fa6 |
children | 86c0ff434620 |
comparison
equal
deleted
inserted
replaced
89562:12fbcfebb9ad | 89563:d193de460ec1 |
---|---|
787 } | 787 } |
788 cmplus (first_unused_hpos - curX); | 788 cmplus (first_unused_hpos - curX); |
789 } | 789 } |
790 } | 790 } |
791 | 791 |
792 /* Buffer to store the result of terminal codes. It is initialized in | |
793 term_init and, if necessary, enlarged in encode_terminal_code. */ | |
794 static unsigned char *terminal_encode_buffer; | |
795 /* Size of terminal_encode_buffer. */ | |
796 static int terminal_encode_buf_size; | |
797 | |
792 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and | 798 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and |
793 store them at DST. Do not write more than DST_LEN bytes. That may | 799 store them in terminal_encode_buffer. |
794 require stopping before all SRC_LEN input glyphs have been | |
795 converted. | |
796 | 800 |
797 We store the number of glyphs actually converted in *CONSUMED. The | 801 We store the number of glyphs actually converted in *CONSUMED. The |
798 return value is the number of bytes store in DST. */ | 802 return value is the number of bytes stored in |
803 terminal_encode_buffer. | |
804 | |
805 This function will stop before encoding all glyphs in these two | |
806 cases. | |
807 | |
808 (1) If the first glyph doesn't have a string entry in Vglyph_table, | |
809 it stops at encountering a glyph that has a string entry in | |
810 Vglyph_table.n | |
811 | |
812 (2) If the first has a string entry in Vglyph_table, it stops after | |
813 encoding that string. | |
814 */ | |
799 | 815 |
800 int | 816 int |
801 encode_terminal_code (src, dst, src_len, dst_len, consumed) | 817 encode_terminal_code (src, src_len, consumed) |
802 struct glyph *src; | 818 struct glyph *src; |
803 int src_len; | 819 int src_len; |
804 unsigned char *dst; | 820 int *consumed; |
805 int dst_len, *consumed; | |
806 { | 821 { |
807 struct glyph *src_start = src, *src_end = src + src_len; | 822 struct glyph *src_start = src, *src_end = src + src_len; |
808 unsigned char *dst_start = dst, *dst_end = dst + dst_len; | |
809 register GLYPH g; | 823 register GLYPH g; |
810 unsigned char workbuf[MAX_MULTIBYTE_LENGTH]; | 824 register int c; |
811 const unsigned char *buf; | 825 Lisp_Object string; |
812 int len; | 826 unsigned char *workbuf, *buf; |
827 int nchars; | |
813 register int tlen = GLYPH_TABLE_LENGTH; | 828 register int tlen = GLYPH_TABLE_LENGTH; |
814 register Lisp_Object *tbase = GLYPH_TABLE_BASE; | 829 register Lisp_Object *tbase = GLYPH_TABLE_BASE; |
815 struct coding_system *coding; | 830 struct coding_system *coding; |
816 | 831 |
817 /* If terminal_coding does any conversion, use it, otherwise use | 832 /* If terminal_coding does any conversion, use it, otherwise use |
818 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here | 833 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here |
819 because it always return 1 if the member src_multibyte is 1. */ | 834 because it always return 1 if the member src_multibyte is 1. */ |
820 coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK | 835 coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK |
821 ? &terminal_coding | 836 ? &terminal_coding |
822 : &safe_terminal_coding); | 837 : &safe_terminal_coding); |
823 | 838 coding->destination = terminal_encode_buffer; |
824 while (src < src_end) | 839 coding->dst_bytes = terminal_encode_buf_size; |
840 coding->mode |= CODING_MODE_LAST_BLOCK; | |
841 | |
842 workbuf = buf = alloca (MAX_MULTIBYTE_LENGTH * src_len); | |
843 for (nchars = 0; src < src_end; src++) | |
825 { | 844 { |
826 /* We must skip glyphs to be padded for a wide character. */ | 845 /* We must skip glyphs to be padded for a wide character. */ |
827 if (! CHAR_GLYPH_PADDING_P (*src)) | 846 if (! CHAR_GLYPH_PADDING_P (*src)) |
828 { | 847 { |
829 g = GLYPH_FROM_CHAR_GLYPH (src[0]); | 848 g = GLYPH_FROM_CHAR_GLYPH (src[0]); |
849 string = Qnil; | |
830 | 850 |
831 if (g < 0 || g >= tlen) | 851 if (g < 0 || g >= tlen) |
832 { | 852 c = src->u.ch; |
833 /* This glyph doesn't have an entry in Vglyph_table. */ | |
834 if (! CHAR_VALID_P (src->u.ch, 0)) | |
835 { | |
836 len = 1; | |
837 buf = " "; | |
838 coding->src_multibyte = 0; | |
839 } | |
840 else | |
841 { | |
842 len = CHAR_STRING (src->u.ch, workbuf); | |
843 buf = workbuf; | |
844 coding->src_multibyte = 1; | |
845 } | |
846 } | |
847 else | 853 else |
848 { | 854 { |
849 /* This glyph has an entry in Vglyph_table, | 855 /* This glyph has an entry in Vglyph_table, |
850 so process any alias before testing for simpleness. */ | 856 so process any alias before testing for simpleness. */ |
851 GLYPH_FOLLOW_ALIASES (tbase, tlen, g); | 857 GLYPH_FOLLOW_ALIASES (tbase, tlen, g); |
852 | 858 |
853 if (GLYPH_SIMPLE_P (tbase, tlen, g)) | 859 if (GLYPH_SIMPLE_P (tbase, tlen, g)) |
860 /* We set the multi-byte form of a character in G | |
861 (that should be an ASCII character) at WORKBUF. */ | |
862 c = FAST_GLYPH_CHAR (g); | |
863 else | |
864 /* We have a string in Vglyph_table. */ | |
865 string = tbase[g]; | |
866 } | |
867 | |
868 if (NILP (string)) | |
869 { | |
870 /* Store the multibyte form of C at BUF. */ | |
871 buf += CHAR_STRING (c, buf); | |
872 nchars++; | |
873 } | |
874 else | |
875 { | |
876 if (nchars == 0) | |
854 { | 877 { |
855 /* We set the multi-byte form of a character in G | 878 encode_coding_object (coding, string, 0, 0, SCHARS (string), |
856 (that should be an ASCII character) at | 879 SBYTES (string), Qnil); |
857 WORKBUF. */ | 880 src++; |
858 workbuf[0] = FAST_GLYPH_CHAR (g); | |
859 len = 1; | |
860 buf = workbuf; | |
861 coding->src_multibyte = 0; | |
862 } | 881 } |
863 else | 882 break; |
864 { | |
865 /* We have a string in Vglyph_table. */ | |
866 len = GLYPH_LENGTH (tbase, g); | |
867 buf = GLYPH_STRING (tbase, g); | |
868 coding->src_multibyte = STRING_MULTIBYTE (tbase[g]); | |
869 } | |
870 } | |
871 | |
872 coding->source = buf; | |
873 coding->destination = dst; | |
874 coding->dst_bytes = dst_end - dst; | |
875 encode_coding_object (coding, Qnil, 0, 0, 1, len, Qnil); | |
876 len -= coding->consumed; | |
877 dst += coding->produced; | |
878 if (coding->result == CODING_RESULT_INSUFFICIENT_DST) | |
879 /* The remaining output buffer is too short. We must | |
880 break the loop here without increasing SRC so that the | |
881 next call of this function starts from the same glyph. */ | |
882 break; | |
883 | |
884 if (len > 0) | |
885 { | |
886 /* This is the case that a code of the range 0200..0237 | |
887 exists in buf. We must just write out such a code. */ | |
888 buf += coding->consumed; | |
889 while (len--) | |
890 *dst++ = *buf++; | |
891 } | 883 } |
892 } | 884 } |
893 src++; | 885 } |
894 } | 886 |
887 if (nchars > 0) | |
888 { | |
889 coding->source = workbuf; | |
890 encode_coding_object (coding, Qnil, 0, 0, nchars, | |
891 buf - workbuf, Qnil); | |
892 } | |
893 terminal_encode_buffer = coding->destination; | |
894 terminal_encode_buf_size = coding->dst_bytes; | |
895 | 895 |
896 *consumed = src - src_start; | 896 *consumed = src - src_start; |
897 return (dst - dst_start); | 897 return (coding->produced); |
898 } | 898 } |
899 | 899 |
900 | 900 |
901 void | 901 void |
902 write_glyphs (string, len) | 902 write_glyphs (string, len) |
904 register int len; | 904 register int len; |
905 { | 905 { |
906 int produced, consumed; | 906 int produced, consumed; |
907 struct frame *sf = XFRAME (selected_frame); | 907 struct frame *sf = XFRAME (selected_frame); |
908 struct frame *f = updating_frame ? updating_frame : sf; | 908 struct frame *f = updating_frame ? updating_frame : sf; |
909 unsigned char conversion_buffer[1024]; | |
910 int conversion_buffer_size = sizeof conversion_buffer; | |
911 | 909 |
912 if (write_glyphs_hook | 910 if (write_glyphs_hook |
913 && ! FRAME_TERMCAP_P (f)) | 911 && ! FRAME_TERMCAP_P (f)) |
914 { | 912 { |
915 (*write_glyphs_hook) (string, len); | 913 (*write_glyphs_hook) (string, len); |
949 highlight_if_desired (); | 947 highlight_if_desired (); |
950 turn_on_face (f, face_id); | 948 turn_on_face (f, face_id); |
951 | 949 |
952 while (n > 0) | 950 while (n > 0) |
953 { | 951 { |
954 /* We use a fixed size (1024 bytes) of conversion buffer. | 952 produced = encode_terminal_code (string, n, &consumed); |
955 Usually it is sufficient, but if not, we just repeat the | |
956 loop. */ | |
957 produced = encode_terminal_code (string, conversion_buffer, | |
958 n, conversion_buffer_size, | |
959 &consumed); | |
960 if (produced > 0) | 953 if (produced > 0) |
961 { | 954 { |
962 fwrite (conversion_buffer, 1, produced, stdout); | 955 fwrite (terminal_encode_buffer, 1, produced, stdout); |
963 if (ferror (stdout)) | 956 if (ferror (stdout)) |
964 clearerr (stdout); | 957 clearerr (stdout); |
965 if (termscript) | 958 if (termscript) |
966 fwrite (conversion_buffer, 1, produced, termscript); | 959 fwrite (terminal_encode_buffer, 1, produced, termscript); |
967 } | 960 } |
968 len -= consumed; | 961 len -= consumed; |
969 n -= consumed; | 962 n -= consumed; |
970 string += consumed; | 963 string += consumed; |
971 } | 964 } |
972 | 965 |
973 /* Turn appearance modes off. */ | 966 /* Turn appearance modes off. */ |
974 turn_off_face (f, face_id); | 967 turn_off_face (f, face_id); |
975 turn_off_highlight (); | 968 turn_off_highlight (); |
976 } | |
977 | |
978 /* We may have to output some codes to terminate the writing. */ | |
979 if (CODING_REQUIRE_FLUSHING (&terminal_coding)) | |
980 { | |
981 terminal_coding.mode |= CODING_MODE_LAST_BLOCK; | |
982 terminal_coding.source = (unsigned char *) ""; | |
983 terminal_coding.destination = conversion_buffer; | |
984 terminal_coding.dst_bytes = conversion_buffer_size; | |
985 encode_coding_object (&terminal_coding, Qnil, 0, 0, 0, 0, Qnil); | |
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 } | 969 } |
996 | 970 |
997 cmcheckmagic (); | 971 cmcheckmagic (); |
998 } | 972 } |
999 | 973 |
1035 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */ | 1009 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */ |
1036 terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK; | 1010 terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK; |
1037 while (len-- > 0) | 1011 while (len-- > 0) |
1038 { | 1012 { |
1039 int produced, consumed; | 1013 int produced, consumed; |
1040 unsigned char conversion_buffer[1024]; | |
1041 int conversion_buffer_size = sizeof conversion_buffer; | |
1042 | 1014 |
1043 OUTPUT1_IF (TS_ins_char); | 1015 OUTPUT1_IF (TS_ins_char); |
1044 if (!start) | 1016 if (!start) |
1045 { | 1017 { |
1046 conversion_buffer[0] = SPACEGLYPH; | 1018 terminal_encode_buffer[0] = SPACEGLYPH; |
1047 produced = 1; | 1019 produced = 1; |
1048 } | 1020 } |
1049 else | 1021 else |
1050 { | 1022 { |
1051 highlight_if_desired (); | 1023 highlight_if_desired (); |
1057 while (len && CHAR_GLYPH_PADDING_P (*start)) | 1029 while (len && CHAR_GLYPH_PADDING_P (*start)) |
1058 { | 1030 { |
1059 OUTPUT1_IF (TS_ins_char); | 1031 OUTPUT1_IF (TS_ins_char); |
1060 start++, len--; | 1032 start++, len--; |
1061 } | 1033 } |
1062 | 1034 produced = encode_terminal_code (glyph, 1, &consumed); |
1063 if (len <= 0) | |
1064 /* This is the last glyph. */ | |
1065 terminal_coding.mode |= CODING_MODE_LAST_BLOCK; | |
1066 | |
1067 /* The size of conversion buffer (1024 bytes) is surely | |
1068 sufficient for just one glyph. */ | |
1069 produced = encode_terminal_code (glyph, conversion_buffer, 1, | |
1070 conversion_buffer_size, &consumed); | |
1071 } | 1035 } |
1072 | 1036 |
1073 if (produced > 0) | 1037 if (produced > 0) |
1074 { | 1038 { |
1075 fwrite (conversion_buffer, 1, produced, stdout); | 1039 fwrite (terminal_encode_buffer, 1, produced, stdout); |
1076 if (ferror (stdout)) | 1040 if (ferror (stdout)) |
1077 clearerr (stdout); | 1041 clearerr (stdout); |
1078 if (termscript) | 1042 if (termscript) |
1079 fwrite (conversion_buffer, 1, produced, termscript); | 1043 fwrite (terminal_encode_buffer, 1, produced, termscript); |
1080 } | 1044 } |
1081 | 1045 |
1082 OUTPUT1_IF (TS_pad_inserted_char); | 1046 OUTPUT1_IF (TS_pad_inserted_char); |
1083 if (start) | 1047 if (start) |
1084 { | 1048 { |
2555 /* meaningless in this case */ | 2519 /* meaningless in this case */ |
2556 baud_rate = 9600; | 2520 baud_rate = 9600; |
2557 | 2521 |
2558 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0; | 2522 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0; |
2559 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none; | 2523 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none; |
2524 | |
2525 if (! terminal_encode_buffer) | |
2526 { | |
2527 terminal_encode_buffer = xmalloc (1024); | |
2528 if (! terminal_encode_buffer) | |
2529 abort (); | |
2530 terminal_encode_buf_size = 1024; | |
2531 } | |
2560 #endif /* WINDOWSNT */ | 2532 #endif /* WINDOWSNT */ |
2561 } | 2533 } |
2562 | 2534 |
2563 /* VARARGS 1 */ | 2535 /* VARARGS 1 */ |
2564 void | 2536 void |