Mercurial > emacs
comparison src/term.c @ 83231:549734260e34
Merged in changes from CVS trunk.
Patches applied:
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-714
Update from CVS
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-271
author | Karoly Lorentey <lorentey@elte.hu> |
---|---|
date | Wed, 08 Dec 2004 22:20:27 +0000 |
parents | 6b4b299e2cd5 24c51e9d8586 |
children | 4ee39d9428b0 |
comparison
equal
deleted
inserted
replaced
83230:d8738586aaec | 83231:549734260e34 |
---|---|
610 } | 610 } |
611 cmplus (tty, first_unused_hpos - curX (tty)); | 611 cmplus (tty, first_unused_hpos - curX (tty)); |
612 } | 612 } |
613 } | 613 } |
614 | 614 |
615 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and | 615 /* Buffer to store the source and result of code conversion for terminal. */ |
616 store them at DST. Do not write more than DST_LEN bytes. That may | 616 static unsigned char *encode_terminal_buf; |
617 require stopping before all SRC_LEN input glyphs have been | 617 /* Allocated size of the above buffer. */ |
618 converted. | 618 static int encode_terminal_bufsize; |
619 | 619 |
620 We store the number of glyphs actually converted in *CONSUMED. The | 620 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes. |
621 return value is the number of bytes store in DST. */ | 621 Set CODING->produced to the byte-length of the resulting byte |
622 | 622 sequence, and return a pointer to that byte sequence. */ |
623 int | 623 |
624 encode_terminal_code (struct coding_system *coding, | 624 unsigned char * |
625 struct glyph *src, | 625 encode_terminal_code (src, src_len, coding) |
626 unsigned char *dst, | 626 struct glyph *src; |
627 int src_len, | 627 int src_len; |
628 int dst_len, | 628 struct coding_system *coding; |
629 int *consumed) | |
630 { | 629 { |
631 struct glyph *src_start = src, *src_end = src + src_len; | 630 struct glyph *src_start = src, *src_end = src + src_len; |
632 unsigned char *dst_start = dst, *dst_end = dst + dst_len; | |
633 register GLYPH g; | 631 register GLYPH g; |
634 unsigned char workbuf[MAX_MULTIBYTE_LENGTH]; | 632 unsigned char *buf; |
635 const unsigned char *buf; | 633 int nchars, nbytes, required; |
636 int len; | |
637 register int tlen = GLYPH_TABLE_LENGTH; | 634 register int tlen = GLYPH_TABLE_LENGTH; |
638 register Lisp_Object *tbase = GLYPH_TABLE_BASE; | 635 register Lisp_Object *tbase = GLYPH_TABLE_BASE; |
639 int result; | 636 |
640 | 637 /* Allocate sufficient size of buffer to store all characters in |
641 /* If the specified coding does any conversion, use it, otherwise use | 638 multibyte-form. But, it may be enlarged on demand if |
642 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here | 639 Vglyph_table contains a string. */ |
643 because it always returns 1 if the member src_multibyte is 1. */ | 640 required = MAX_MULTIBYTE_LENGTH * src_len; |
644 coding = (coding->common_flags & CODING_REQUIRE_ENCODING_MASK | 641 if (encode_terminal_bufsize < required) |
645 ? coding | 642 { |
646 : &safe_terminal_coding); | 643 encode_terminal_bufsize = required; |
647 | 644 if (encode_terminal_bufsize == 0) |
645 encode_terminal_buf = xmalloc (required); | |
646 else | |
647 encode_terminal_buf = xrealloc (encode_terminal_buf, required); | |
648 } | |
649 | |
650 buf = encode_terminal_buf; | |
651 nchars = 0; | |
648 while (src < src_end) | 652 while (src < src_end) |
649 { | 653 { |
650 /* We must skip glyphs to be padded for a wide character. */ | 654 /* We must skip glyphs to be padded for a wide character. */ |
651 if (! CHAR_GLYPH_PADDING_P (*src)) | 655 if (! CHAR_GLYPH_PADDING_P (*src)) |
652 { | 656 { |
653 g = GLYPH_FROM_CHAR_GLYPH (src[0]); | 657 g = GLYPH_FROM_CHAR_GLYPH (src[0]); |
654 | 658 |
655 if (g < 0 || g >= tlen) | 659 if (g < 0 || g >= tlen) |
656 { | 660 { |
657 /* This glyph doesn't has an entry in Vglyph_table. */ | 661 /* This glyph doesn't has an entry in Vglyph_table. */ |
658 if (! CHAR_VALID_P (src->u.ch, 0)) | 662 if (CHAR_VALID_P (src->u.ch, 0)) |
659 { | 663 buf += CHAR_STRING (src->u.ch, buf); |
660 len = 1; | |
661 buf = " "; | |
662 coding->src_multibyte = 0; | |
663 } | |
664 else | 664 else |
665 { | 665 *buf++ = SPACEGLYPH; |
666 len = CHAR_STRING (src->u.ch, workbuf); | 666 nchars++; |
667 buf = workbuf; | |
668 coding->src_multibyte = 1; | |
669 } | |
670 } | 667 } |
671 else | 668 else |
672 { | 669 { |
673 /* This glyph has an entry in Vglyph_table, | 670 /* This glyph has an entry in Vglyph_table, |
674 so process any alias before testing for simpleness. */ | 671 so process any alias before testing for simpleness. */ |
675 GLYPH_FOLLOW_ALIASES (tbase, tlen, g); | 672 GLYPH_FOLLOW_ALIASES (tbase, tlen, g); |
676 | 673 |
677 if (GLYPH_SIMPLE_P (tbase, tlen, g)) | 674 if (GLYPH_SIMPLE_P (tbase, tlen, g)) |
678 { | 675 { |
679 /* We set the multi-byte form of a character in G | 676 int c = FAST_GLYPH_CHAR (g); |
680 (that should be an ASCII character) at | 677 |
681 WORKBUF. */ | 678 if (CHAR_VALID_P (c, 0)) |
682 workbuf[0] = FAST_GLYPH_CHAR (g); | 679 buf += CHAR_STRING (c, buf); |
683 len = 1; | 680 else |
684 buf = workbuf; | 681 *buf++ = SPACEGLYPH; |
685 coding->src_multibyte = 0; | 682 nchars++; |
686 } | 683 } |
687 else | 684 else |
688 { | 685 { |
689 /* We have a string in Vglyph_table. */ | 686 /* We have a string in Vglyph_table. */ |
690 len = GLYPH_LENGTH (tbase, g); | 687 Lisp_Object string; |
691 buf = GLYPH_STRING (tbase, g); | 688 |
692 coding->src_multibyte = STRING_MULTIBYTE (tbase[g]); | 689 string = tbase[g]; |
690 if (! STRING_MULTIBYTE (string)) | |
691 string = string_to_multibyte (string); | |
692 nbytes = buf - encode_terminal_buf; | |
693 if (nbytes + SBYTES (string) < encode_terminal_bufsize) | |
694 { | |
695 encode_terminal_bufsize = nbytes + SBYTES (string); | |
696 encode_terminal_buf = xrealloc (encode_terminal_buf, | |
697 encode_terminal_bufsize); | |
698 buf = encode_terminal_buf + nbytes; | |
699 } | |
700 bcopy (SDATA (string), buf, SBYTES (string)); | |
701 buf += SBYTES (string); | |
702 nchars += SCHARS (string); | |
693 } | 703 } |
694 } | |
695 | |
696 result = encode_coding (coding, buf, dst, len, dst_end - dst); | |
697 len -= coding->consumed; | |
698 dst += coding->produced; | |
699 if (result == CODING_FINISH_INSUFFICIENT_DST | |
700 || (result == CODING_FINISH_INSUFFICIENT_SRC | |
701 && len > dst_end - dst)) | |
702 /* The remaining output buffer is too short. We must | |
703 break the loop here without increasing SRC so that the | |
704 next call of this function starts from the same glyph. */ | |
705 break; | |
706 | |
707 if (len > 0) | |
708 { | |
709 /* This is the case that a code of the range 0200..0237 | |
710 exists in buf. We must just write out such a code. */ | |
711 buf += coding->consumed; | |
712 while (len--) | |
713 *dst++ = *buf++; | |
714 } | 704 } |
715 } | 705 } |
716 src++; | 706 src++; |
717 } | 707 } |
718 | 708 |
719 *consumed = src - src_start; | 709 nbytes = buf - encode_terminal_buf; |
720 return (dst - dst_start); | 710 coding->src_multibyte = 1; |
711 coding->dst_multibyte = 0; | |
712 if (SYMBOLP (coding->pre_write_conversion) | |
713 && ! NILP (Ffboundp (coding->pre_write_conversion))) | |
714 { | |
715 run_pre_write_conversin_on_c_str (&encode_terminal_buf, | |
716 &encode_terminal_bufsize, | |
717 nchars, nbytes, coding); | |
718 nchars = coding->produced_char; | |
719 nbytes = coding->produced; | |
720 } | |
721 required = nbytes + encoding_buffer_size (coding, nbytes); | |
722 if (encode_terminal_bufsize < required) | |
723 { | |
724 encode_terminal_bufsize = required; | |
725 encode_terminal_buf = xrealloc (encode_terminal_buf, required); | |
726 } | |
727 | |
728 encode_coding (coding, encode_terminal_buf, encode_terminal_buf + nbytes, | |
729 nbytes, encode_terminal_bufsize - nbytes); | |
730 return encode_terminal_buf + nbytes; | |
721 } | 731 } |
722 | 732 |
723 | 733 |
724 /* Output LEN glyphs starting at STRING at the nominal cursor position. | 734 /* Output LEN glyphs starting at STRING at the nominal cursor position. |
725 Advance the nominal cursor over the text. */ | 735 Advance the nominal cursor over the text. */ |
734 /* An implementation of write_glyphs for termcap frames. */ | 744 /* An implementation of write_glyphs for termcap frames. */ |
735 | 745 |
736 void | 746 void |
737 tty_write_glyphs (struct frame *f, struct glyph *string, int len) | 747 tty_write_glyphs (struct frame *f, struct glyph *string, int len) |
738 { | 748 { |
739 int produced, consumed; | 749 unsigned char *conversion_buffer; |
740 unsigned char conversion_buffer[1024]; | 750 struct coding_system *coding; |
741 int conversion_buffer_size = sizeof conversion_buffer; | |
742 | 751 |
743 struct tty_display_info *tty = FRAME_TTY (f); | 752 struct tty_display_info *tty = FRAME_TTY (f); |
744 | 753 |
745 turn_off_insert (tty); | 754 turn_off_insert (tty); |
746 tty_hide_cursor (tty); | 755 tty_hide_cursor (tty); |
755 if (len <= 0) | 764 if (len <= 0) |
756 return; | 765 return; |
757 | 766 |
758 cmplus (tty, len); | 767 cmplus (tty, len); |
759 | 768 |
769 /* If terminal_coding does any conversion, use it, otherwise use | |
770 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here | |
771 because it always return 1 if the member src_multibyte is 1. */ | |
772 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK | |
773 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding); | |
760 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at | 774 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at |
761 the tail. */ | 775 the tail. */ |
762 FRAME_TERMINAL_CODING (f)->mode &= ~CODING_MODE_LAST_BLOCK; | 776 coding->mode &= ~CODING_MODE_LAST_BLOCK; |
763 | 777 |
764 while (len > 0) | 778 while (len > 0) |
765 { | 779 { |
766 /* Identify a run of glyphs with the same face. */ | 780 /* Identify a run of glyphs with the same face. */ |
767 int face_id = string->face_id; | 781 int face_id = string->face_id; |
773 | 787 |
774 /* Turn appearance modes of the face of the run on. */ | 788 /* Turn appearance modes of the face of the run on. */ |
775 highlight_if_desired (tty); | 789 highlight_if_desired (tty); |
776 turn_on_face (f, face_id); | 790 turn_on_face (f, face_id); |
777 | 791 |
778 while (n > 0) | 792 if (n == len) |
793 /* This is the last run. */ | |
794 coding->mode |= CODING_MODE_LAST_BLOCK; | |
795 conversion_buffer = encode_terminal_code (string, n, coding); | |
796 if (coding->produced > 0) | |
779 { | 797 { |
780 /* We use a fixed size (1024 bytes) of conversion buffer. | 798 fwrite (conversion_buffer, 1, coding->produced, tty->output); |
781 Usually it is sufficient, but if not, we just repeat the | 799 if (ferror (tty->output)) |
782 loop. */ | 800 clearerr (tty->output); |
783 produced = encode_terminal_code (FRAME_TERMINAL_CODING (f), | 801 if (tty->termscript) |
784 string, conversion_buffer, | 802 fwrite (conversion_buffer, 1, coding->produced, tty->termscript); |
785 n, conversion_buffer_size, | |
786 &consumed); | |
787 if (produced > 0) | |
788 { | |
789 fwrite (conversion_buffer, 1, produced, | |
790 tty->output); | |
791 if (ferror (tty->output)) | |
792 clearerr (tty->output); | |
793 if (tty->termscript) | |
794 fwrite (conversion_buffer, 1, produced, | |
795 tty->termscript); | |
796 } | |
797 len -= consumed; | |
798 n -= consumed; | |
799 string += consumed; | |
800 } | 803 } |
804 len -= n; | |
805 string += n; | |
801 | 806 |
802 /* Turn appearance modes off. */ | 807 /* Turn appearance modes off. */ |
803 turn_off_face (f, face_id); | 808 turn_off_face (f, face_id); |
804 turn_off_highlight (tty); | 809 turn_off_highlight (tty); |
805 } | 810 } |
806 | 811 |
807 /* We may have to output some codes to terminate the writing. */ | |
808 if (CODING_REQUIRE_FLUSHING (FRAME_TERMINAL_CODING (f))) | |
809 { | |
810 FRAME_TERMINAL_CODING (f)->mode |= CODING_MODE_LAST_BLOCK; | |
811 encode_coding (FRAME_TERMINAL_CODING (f), "", | |
812 conversion_buffer, 0, conversion_buffer_size); | |
813 if (FRAME_TERMINAL_CODING (f)->produced > 0) | |
814 { | |
815 fwrite (conversion_buffer, 1, | |
816 FRAME_TERMINAL_CODING (f)->produced, | |
817 tty->output); | |
818 if (ferror (tty->output)) | |
819 clearerr (tty->output); | |
820 if (tty->termscript) | |
821 fwrite (conversion_buffer, 1, | |
822 FRAME_TERMINAL_CODING (f)->produced, | |
823 tty->termscript); | |
824 } | |
825 } | |
826 | |
827 cmcheckmagic (tty); | 812 cmcheckmagic (tty); |
828 } | 813 } |
829 | 814 |
830 /* Insert LEN glyphs from START at the nominal cursor position. | 815 /* Insert LEN glyphs from START at the nominal cursor position. |
831 | 816 |
846 void | 831 void |
847 tty_insert_glyphs (struct frame *f, struct glyph *start, int len) | 832 tty_insert_glyphs (struct frame *f, struct glyph *start, int len) |
848 { | 833 { |
849 char *buf; | 834 char *buf; |
850 struct glyph *glyph = NULL; | 835 struct glyph *glyph = NULL; |
836 unsigned char *conversion_buffer; | |
837 unsigned char space[1]; | |
838 struct coding_system *coding; | |
851 | 839 |
852 struct tty_display_info *tty = FRAME_TTY (f); | 840 struct tty_display_info *tty = FRAME_TTY (f); |
853 | 841 |
854 if (tty->TS_ins_multi_chars) | 842 if (tty->TS_ins_multi_chars) |
855 { | 843 { |
861 return; | 849 return; |
862 } | 850 } |
863 | 851 |
864 turn_on_insert (tty); | 852 turn_on_insert (tty); |
865 cmplus (tty, len); | 853 cmplus (tty, len); |
866 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */ | 854 |
867 FRAME_TERMINAL_CODING (f)->mode &= ~CODING_MODE_LAST_BLOCK; | 855 if (! start) |
856 space[0] = SPACEGLYPH; | |
857 | |
858 /* If terminal_coding does any conversion, use it, otherwise use | |
859 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here | |
860 because it always return 1 if the member src_multibyte is 1. */ | |
861 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK | |
862 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding); | |
863 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at | |
864 the tail. */ | |
865 coding->mode &= ~CODING_MODE_LAST_BLOCK; | |
866 | |
868 while (len-- > 0) | 867 while (len-- > 0) |
869 { | 868 { |
870 int produced, consumed; | |
871 unsigned char conversion_buffer[1024]; | |
872 int conversion_buffer_size = sizeof conversion_buffer; | |
873 | |
874 OUTPUT1_IF (tty, tty->TS_ins_char); | 869 OUTPUT1_IF (tty, tty->TS_ins_char); |
875 if (!start) | 870 if (!start) |
876 { | 871 { |
877 conversion_buffer[0] = SPACEGLYPH; | 872 conversion_buffer = space; |
878 produced = 1; | 873 coding->produced = 1; |
879 } | 874 } |
880 else | 875 else |
881 { | 876 { |
882 highlight_if_desired (tty); | 877 highlight_if_desired (tty); |
883 turn_on_face (f, start->face_id); | 878 turn_on_face (f, start->face_id); |
891 start++, len--; | 886 start++, len--; |
892 } | 887 } |
893 | 888 |
894 if (len <= 0) | 889 if (len <= 0) |
895 /* This is the last glyph. */ | 890 /* This is the last glyph. */ |
896 FRAME_TERMINAL_CODING (f)->mode |= CODING_MODE_LAST_BLOCK; | 891 coding->mode |= CODING_MODE_LAST_BLOCK; |
897 | 892 |
898 /* The size of conversion buffer (1024 bytes) is surely | 893 conversion_buffer = encode_terminal_code (glyph, 1, coding); |
899 sufficient for just one glyph. */ | |
900 produced = encode_terminal_code (FRAME_TERMINAL_CODING (f), | |
901 glyph, conversion_buffer, 1, | |
902 conversion_buffer_size, &consumed); | |
903 } | 894 } |
904 | 895 |
905 if (produced > 0) | 896 if (coding->produced > 0) |
906 { | 897 { |
907 fwrite (conversion_buffer, 1, produced, | 898 fwrite (conversion_buffer, 1, coding->produced, tty->output); |
908 tty->output); | |
909 if (ferror (tty->output)) | 899 if (ferror (tty->output)) |
910 clearerr (tty->output); | 900 clearerr (tty->output); |
911 if (tty->termscript) | 901 if (tty->termscript) |
912 fwrite (conversion_buffer, 1, produced, | 902 fwrite (conversion_buffer, 1, coding->produced, tty->termscript); |
913 tty->termscript); | |
914 } | 903 } |
915 | 904 |
916 OUTPUT1_IF (tty, tty->TS_pad_inserted_char); | 905 OUTPUT1_IF (tty, tty->TS_pad_inserted_char); |
917 if (start) | 906 if (start) |
918 { | 907 { |
2443 | 2432 |
2444 tty->type = xstrdup (terminal_type); | 2433 tty->type = xstrdup (terminal_type); |
2445 | 2434 |
2446 add_keyboard_wait_descriptor (fileno (tty->input)); | 2435 add_keyboard_wait_descriptor (fileno (tty->input)); |
2447 | 2436 |
2437 encode_terminal_bufsize = 0; | |
2438 | |
2448 #ifdef WINDOWSNT | 2439 #ifdef WINDOWSNT |
2449 initialize_w32_display (); | 2440 initialize_w32_display (); |
2450 | 2441 |
2451 Wcm_clear (tty); | 2442 Wcm_clear (tty); |
2452 | 2443 |