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