diff options
| author | Karoly Lorentey | 2004-12-08 22:20:27 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2004-12-08 22:20:27 +0000 |
| commit | fad2f6858075f49c4c8fd16f0535c287e3f14ac3 (patch) | |
| tree | 843a2ffe6caea6201877e3d2f1b6b954f47344b5 /src/term.c | |
| parent | 856dd47583918edd7987c13334703d3e7492d8f4 (diff) | |
| parent | b11e88237593ff7556d8535305e8f342e6b61d66 (diff) | |
| download | emacs-fad2f6858075f49c4c8fd16f0535c287e3f14ac3.tar.gz emacs-fad2f6858075f49c4c8fd16f0535c287e3f14ac3.zip | |
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
Diffstat (limited to 'src/term.c')
| -rw-r--r-- | src/term.c | 253 |
1 files changed, 122 insertions, 131 deletions
diff --git a/src/term.c b/src/term.c index 899829ebadb..cf79ea43531 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -612,39 +612,43 @@ tty_clear_end_of_line (struct frame *f, int first_unused_hpos) | |||
| 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 | sequence, and return a pointer to that byte sequence. */ | ||
| 622 | 623 | ||
| 623 | int | 624 | unsigned char * |
| 624 | encode_terminal_code (struct coding_system *coding, | 625 | encode_terminal_code (src, src_len, coding) |
| 625 | struct glyph *src, | 626 | struct glyph *src; |
| 626 | unsigned char *dst, | 627 | int src_len; |
| 627 | int src_len, | 628 | struct coding_system *coding; |
| 628 | int dst_len, | ||
| 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; | ||
| 640 | 636 | ||
| 641 | /* If the specified coding does any conversion, use it, otherwise use | 637 | /* Allocate sufficient size of buffer to store all characters in |
| 642 | safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here | 638 | multibyte-form. But, it may be enlarged on demand if |
| 643 | because it always returns 1 if the member src_multibyte is 1. */ | 639 | Vglyph_table contains a string. */ |
| 644 | coding = (coding->common_flags & CODING_REQUIRE_ENCODING_MASK | 640 | required = MAX_MULTIBYTE_LENGTH * src_len; |
| 645 | ? coding | 641 | if (encode_terminal_bufsize < required) |
| 646 | : &safe_terminal_coding); | 642 | { |
| 643 | encode_terminal_bufsize = required; | ||
| 644 | if (encode_terminal_bufsize == 0) | ||
| 645 | encode_terminal_buf = xmalloc (required); | ||
| 646 | else | ||
| 647 | encode_terminal_buf = xrealloc (encode_terminal_buf, required); | ||
| 648 | } | ||
| 647 | 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. */ |
| @@ -655,18 +659,11 @@ encode_terminal_code (struct coding_system *coding, | |||
| 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 | { |
| @@ -676,48 +673,61 @@ encode_terminal_code (struct coding_system *coding, | |||
| 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 | } | 704 | } |
| 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 | } | ||
| 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 | ||
| @@ -736,9 +746,8 @@ write_glyphs (struct frame *f, struct glyph *string, int len) | |||
| 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 | ||
| @@ -757,9 +766,14 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len) | |||
| 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 | { |
| @@ -775,55 +789,26 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len) | |||
| 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 | ||
| @@ -848,6 +833,9 @@ 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 | ||
| @@ -863,19 +851,26 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len) | |||
| 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 | { |
| @@ -893,24 +888,18 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len) | |||
| 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); |
| @@ -2445,6 +2434,8 @@ term_init (char *name, char *terminal_type, int must_succeed) | |||
| 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 | ||