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);