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