Mercurial > emacs
comparison src/term.c @ 17046:84b0e9794a87
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.
author | Karl Heuer <kwzh@gnu.org> |
---|---|
date | Thu, 20 Feb 1997 06:57:21 +0000 |
parents | cd8d6bf6b320 |
children | 364327df6e7c |
comparison
equal
deleted
inserted
replaced
17045:1dfa84b25d3b | 17046:84b0e9794a87 |
---|---|
25 #include "termchar.h" | 25 #include "termchar.h" |
26 #include "termopts.h" | 26 #include "termopts.h" |
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" |
33 #include "keyboard.h" | 35 #include "keyboard.h" |
34 | 36 |
194 void (*judge_scroll_bars_hook)( /* FRAME_PTR *FRAME */ ); | 196 void (*judge_scroll_bars_hook)( /* FRAME_PTR *FRAME */ ); |
195 | 197 |
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" */ |
203 char *TS_clr_line; /* "ce", clear to end of line */ | 207 char *TS_clr_line; /* "ce", clear to end of line */ |
204 char *TS_clr_frame; /* "cl" */ | 208 char *TS_clr_frame; /* "cl" */ |
217 char *TS_ins_multi_chars; /* "IC" (one parameter, # chars to insert) */ | 221 char *TS_ins_multi_chars; /* "IC" (one parameter, # chars to insert) */ |
218 char *TS_insert_mode; /* "im", enter character-insert mode */ | 222 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) */ |
225 char *TS_end_standout_mode; /* "se" */ | 231 char *TS_end_standout_mode; /* "se" */ |
226 char *TS_fwd_scroll; /* "sf" */ | 232 char *TS_fwd_scroll; /* "sf" */ |
227 char *TS_standout_mode; /* "so" */ | 233 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" */ |
234 char *TS_set_window; /* "wi" (4 params, start and end of window, | 242 char *TS_set_window; /* "wi" (4 params, start and end of window, |
235 each as vpos and hpos) */ | 243 each as vpos and hpos) */ |
758 } | 766 } |
759 cmplus (first_unused_hpos - curX); | 767 cmplus (first_unused_hpos - curX); |
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; |
766 register int len; | 842 register int len; |
767 { | 843 { |
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))) |
774 { | 851 { |
775 (*write_glyphs_hook) (string, len); | 852 (*write_glyphs_hook) (string, len); |
785 if (AutoWrap | 862 if (AutoWrap |
786 && curY + 1 == FRAME_HEIGHT (selected_frame) | 863 && curY + 1 == FRAME_HEIGHT (selected_frame) |
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. */ |
793 { | 872 terminal_coding.last_block = 0; |
794 g = *string++; | 873 while (len > 0) |
795 /* Check quickly for G beyond length of table. | 874 { |
796 That implies it isn't an alias and is simple. */ | 875 /* We use shared conversion buffer of the current size (1024 |
797 if (g >= tlen) | 876 bytes at least). Usually it is sufficient, but if not, we |
877 just repeat the loop. */ | |
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 } | 887 } |
806 else | 888 len -= consumed; |
807 { | 889 string += consumed; |
808 /* G has an entry in Vglyph_table, | 890 } |
809 so process any alias and then test for simpleness. */ | 891 /* We may have to output some codes to terminate the writing. */ |
810 while (GLYPH_ALIAS_P (tbase, tlen, g)) | 892 terminal_coding.last_block = 1; |
811 g = GLYPH_ALIAS (tbase, g); | 893 produced = encode_coding (&terminal_coding, (char *)0, conversion_buffer, |
812 if (GLYPH_SIMPLE_P (tbase, tlen, g)) | 894 0, conversion_buffer_size, |
813 goto simple; | 895 &consumed); |
814 else | 896 if (produced > 0) |
815 { | 897 { |
816 /* Here if G (or its definition as an alias) is not simple. */ | 898 fwrite (conversion_buffer, 1, produced, stdout); |
817 fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g), | 899 if (ferror (stdout)) |
818 stdout); | 900 clearerr (stdout); |
819 if (ferror (stdout)) | 901 if (termscript) |
820 clearerr (stdout); | 902 fwrite (conversion_buffer, 1, produced, termscript); |
821 if (termscript) | |
822 fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g), | |
823 termscript); | |
824 } | |
825 } | |
826 } | 903 } |
827 cmcheckmagic (); | 904 cmcheckmagic (); |
828 } | 905 } |
829 | 906 |
830 /* If start is zero, insert blanks instead of a string at start */ | 907 /* If start is zero, insert blanks instead of a string at start */ |
832 insert_glyphs (start, len) | 909 insert_glyphs (start, len) |
833 register GLYPH *start; | 910 register GLYPH *start; |
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; |
917 | |
918 if (len <= 0) | |
919 return; | |
840 | 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); |
844 return; | 924 return; |
855 return; | 935 return; |
856 } | 936 } |
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. */ |
861 { | 941 terminal_coding.last_block = 0; |
942 while (len > 0) | |
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++; |
952 /* We must open sufficient space for a character which | |
953 occupies more than one column. */ | |
954 while (*start && GLYPH_MASK_PADDING) | |
955 { | |
956 OUTPUT1_IF (TS_ins_char); | |
957 start++, len--; | |
958 } | |
959 } | |
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) | |
970 { | |
971 fwrite (conversion_buffer, 1, produced, stdout); | |
871 if (ferror (stdout)) | 972 if (ferror (stdout)) |
872 clearerr (stdout); | 973 clearerr (stdout); |
873 if (termscript) | 974 if (termscript) |
874 putc (g & 0xff, termscript); | 975 fwrite (conversion_buffer, 1, produced, termscript); |
875 } | |
876 else | |
877 { | |
878 fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g), stdout); | |
879 if (ferror (stdout)) | |
880 clearerr (stdout); | |
881 if (termscript) | |
882 fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g), | |
883 termscript); | |
884 } | 976 } |
885 | 977 |
886 OUTPUT1_IF (TS_pad_inserted_char); | 978 OUTPUT1_IF (TS_pad_inserted_char); |
887 } | 979 } |
888 cmcheckmagic (); | 980 cmcheckmagic (); |
1556 TS_standout_mode = tgetstr ("so", address); | 1648 TS_standout_mode = tgetstr ("so", address); |
1557 TS_rev_scroll = tgetstr ("sr", address); | 1649 TS_rev_scroll = tgetstr ("sr", address); |
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); |
1564 TS_visual_mode = tgetstr ("vs", address); | 1660 TS_visual_mode = tgetstr ("vs", address); |
1565 TS_set_window = tgetstr ("wi", address); | 1661 TS_set_window = tgetstr ("wi", address); |