diff options
| author | Eli Zaretskii | 1998-12-06 15:57:48 +0000 |
|---|---|---|
| committer | Eli Zaretskii | 1998-12-06 15:57:48 +0000 |
| commit | aa9ce936727b47a6e4c110d378feffc5c884135a (patch) | |
| tree | c7e1c35eaaf0accb321d0980574385752305803c /src/msdos.c | |
| parent | d24422702fb81c15b8c3698cc051be7ee0d05eb2 (diff) | |
| download | emacs-aa9ce936727b47a6e4c110d378feffc5c884135a.tar.gz emacs-aa9ce936727b47a6e4c110d378feffc5c884135a.zip | |
(Vdos_unsupported_char_glyph): New variable.
(syms_of_msdos): DEFVAR_LISP it.
(IT_insert_glyphs, IT_delete_glyphs): New functions which abort
Emacs.
(internal_terminal_init): Set up insert_glyphs_hook and
delete_glyphs_hook to call them. Explicitly set char_ins_del_ok
to 0.
(unibyte_display_via_language_environment): New variable.
(syms_of_msdos): Devfar it.
(IT_write_glyphs): Honor glyph aliasing via Vglyph_table.
Encode the character codes of the glyphs according to the
terminal_coding in effect.
Diffstat (limited to 'src/msdos.c')
| -rw-r--r-- | src/msdos.c | 258 |
1 files changed, 236 insertions, 22 deletions
diff --git a/src/msdos.c b/src/msdos.c index 5ca21f37225..f94413ee452 100644 --- a/src/msdos.c +++ b/src/msdos.c | |||
| @@ -50,8 +50,12 @@ Boston, MA 02111-1307, USA. */ | |||
| 50 | #include "msdos.h" | 50 | #include "msdos.h" |
| 51 | #include "systime.h" | 51 | #include "systime.h" |
| 52 | #include "termhooks.h" | 52 | #include "termhooks.h" |
| 53 | #include "termchar.h" | ||
| 53 | #include "dispextern.h" | 54 | #include "dispextern.h" |
| 54 | #include "termopts.h" | 55 | #include "termopts.h" |
| 56 | #include "charset.h" | ||
| 57 | #include "coding.h" | ||
| 58 | #include "disptab.h" | ||
| 55 | #include "frame.h" | 59 | #include "frame.h" |
| 56 | #include "window.h" | 60 | #include "window.h" |
| 57 | #include "buffer.h" | 61 | #include "buffer.h" |
| @@ -352,6 +356,9 @@ static unsigned long screen_old_address = 0; | |||
| 352 | static unsigned short screen_virtual_segment = 0; | 356 | static unsigned short screen_virtual_segment = 0; |
| 353 | static unsigned short screen_virtual_offset = 0; | 357 | static unsigned short screen_virtual_offset = 0; |
| 354 | 358 | ||
| 359 | /* A flag to control how to display unibyte 8-bit character. */ | ||
| 360 | int unibyte_display_via_language_environment; | ||
| 361 | |||
| 355 | #if __DJGPP__ > 1 | 362 | #if __DJGPP__ > 1 |
| 356 | /* Update the screen from a part of relocated DOS/V screen buffer which | 363 | /* Update the screen from a part of relocated DOS/V screen buffer which |
| 357 | begins at OFFSET and includes COUNT characters. */ | 364 | begins at OFFSET and includes COUNT characters. */ |
| @@ -671,37 +678,203 @@ IT_set_face (int face) | |||
| 671 | ScreenAttrib = (FACE_BACKGROUND (fp) << 4) | FACE_FOREGROUND (fp); | 678 | ScreenAttrib = (FACE_BACKGROUND (fp) << 4) | FACE_FOREGROUND (fp); |
| 672 | } | 679 | } |
| 673 | 680 | ||
| 681 | Lisp_Object Vdos_unsupported_char_glyph; | ||
| 682 | |||
| 674 | static void | 683 | static void |
| 675 | IT_write_glyphs (GLYPH *str, int len) | 684 | IT_write_glyphs (GLYPH *str, int str_len) |
| 676 | { | 685 | { |
| 677 | int newface; | 686 | unsigned char *screen_buf, *screen_bp, *screen_buf_end, *bp; |
| 678 | int ch, l = len; | 687 | int unsupported_face = FAST_GLYPH_FACE (Vdos_unsupported_char_glyph); |
| 679 | unsigned char *buf, *bp; | 688 | unsigned unsupported_char= FAST_GLYPH_CHAR (Vdos_unsupported_char_glyph); |
| 680 | int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y); | 689 | int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y); |
| 690 | register int sl = str_len; | ||
| 691 | register int tlen = GLYPH_TABLE_LENGTH; | ||
| 692 | register Lisp_Object *tbase = GLYPH_TABLE_BASE; | ||
| 693 | |||
| 694 | struct coding_system *coding = CODING_REQUIRE_ENCODING (&terminal_coding) | ||
| 695 | ? &terminal_coding | ||
| 696 | : &safe_terminal_coding; | ||
| 681 | 697 | ||
| 682 | if (len == 0) return; | 698 | if (str_len == 0) return; |
| 683 | 699 | ||
| 684 | buf = bp = alloca (len * 2); | 700 | screen_buf = screen_bp = alloca (str_len * 2); |
| 701 | screen_buf_end = screen_buf + str_len * 2; | ||
| 685 | 702 | ||
| 686 | while (--l >= 0) | 703 | /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at |
| 687 | { | 704 | the tail. */ |
| 688 | newface = FAST_GLYPH_FACE (*str); | 705 | terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK; |
| 689 | if (newface != screen_face) | 706 | while (sl) |
| 690 | IT_set_face (newface); | 707 | { |
| 691 | ch = FAST_GLYPH_CHAR (*str); | 708 | int cf, ch, chlen, enclen; |
| 692 | *bp++ = (unsigned char)ch; | 709 | unsigned char workbuf[4], *buf; |
| 693 | *bp++ = ScreenAttrib; | 710 | register GLYPH g = *str; |
| 694 | 711 | ||
| 695 | if (termscript) | 712 | /* Find the actual glyph to display by traversing the entire |
| 696 | fputc (ch, termscript); | 713 | aliases chain for this glyph. */ |
| 697 | str++; | 714 | GLYPH_FOLLOW_ALIASES (tbase, tlen, g); |
| 715 | |||
| 716 | /* Glyphs with GLYPH_MASK_PADDING bit set are actually there | ||
| 717 | only for the redisplay code to know how many columns does | ||
| 718 | this character occupy on the screen. Skip padding glyphs. */ | ||
| 719 | if ((g & GLYPH_MASK_PADDING)) | ||
| 720 | { | ||
| 721 | str++; | ||
| 722 | sl--; | ||
| 723 | } | ||
| 724 | else | ||
| 725 | { | ||
| 726 | /* Convert the character code to multibyte, if they | ||
| 727 | requested display via language environment. */ | ||
| 728 | ch = FAST_GLYPH_CHAR (g); | ||
| 729 | if (unibyte_display_via_language_environment | ||
| 730 | && SINGLE_BYTE_CHAR_P (ch) | ||
| 731 | && (ch >= 0240 || !NILP (Vnonascii_translation_table))) | ||
| 732 | ch = unibyte_char_to_multibyte (ch); | ||
| 733 | |||
| 734 | /* Invalid characters are displayed with a special glyph. */ | ||
| 735 | if (ch > MAX_CHAR) | ||
| 736 | { | ||
| 737 | g = !NILP (Vdos_unsupported_char_glyph) | ||
| 738 | ? Vdos_unsupported_char_glyph | ||
| 739 | : MAKE_GLYPH (selected_frame, '\177', | ||
| 740 | GLYPH_FACE (selected_frame, g)); | ||
| 741 | ch = FAST_GLYPH_CHAR (g); | ||
| 742 | } | ||
| 743 | if (COMPOSITE_CHAR_P (ch)) | ||
| 744 | { | ||
| 745 | /* If CH is a composite character, we can display | ||
| 746 | only the first component. */ | ||
| 747 | g = cmpchar_table[COMPOSITE_CHAR_ID (ch)]->glyph[0], | ||
| 748 | ch = GLYPH_CHAR (selected_frame, g); | ||
| 749 | cf = FAST_GLYPH_FACE (g); | ||
| 750 | } | ||
| 751 | |||
| 752 | /* If the face of this glyph is different from the current | ||
| 753 | screen face, update the screen attribute byte. */ | ||
| 754 | cf = FAST_GLYPH_FACE (g); | ||
| 755 | if (cf != screen_face) | ||
| 756 | IT_set_face (cf); /* handles invalid faces gracefully */ | ||
| 757 | |||
| 758 | if (GLYPH_SIMPLE_P (tbase, tlen, g)) | ||
| 759 | /* We generate the multi-byte form of CH in BUF. */ | ||
| 760 | chlen = CHAR_STRING (ch, workbuf, buf); | ||
| 761 | else | ||
| 762 | { | ||
| 763 | /* We have a string in Vglyph_table. */ | ||
| 764 | chlen = GLYPH_LENGTH (tbase, g); | ||
| 765 | buf = GLYPH_STRING (tbase, g); | ||
| 766 | } | ||
| 767 | |||
| 768 | /* If the character is not multibyte, don't bother converting it. | ||
| 769 | FIXME: what about "emacs --unibyte" */ | ||
| 770 | if (chlen == 1) | ||
| 771 | { | ||
| 772 | *conversion_buffer = (unsigned char)ch; | ||
| 773 | chlen = 0; | ||
| 774 | enclen = 1; | ||
| 775 | } | ||
| 776 | else | ||
| 777 | { | ||
| 778 | encode_coding (coding, buf, conversion_buffer, chlen, | ||
| 779 | conversion_buffer_size); | ||
| 780 | chlen -= coding->consumed; | ||
| 781 | enclen = coding->produced; | ||
| 782 | |||
| 783 | /* Replace glyph codes that cannot be converted by | ||
| 784 | terminal_coding with Vdos_unsupported_char_glyph. */ | ||
| 785 | if (*conversion_buffer == '?') | ||
| 786 | { | ||
| 787 | char *cbp = conversion_buffer; | ||
| 788 | |||
| 789 | while (cbp < conversion_buffer + enclen && *cbp == '?') | ||
| 790 | *cbp++ = unsupported_char; | ||
| 791 | if (unsupported_face != screen_face) | ||
| 792 | IT_set_face (unsupported_face); | ||
| 793 | } | ||
| 794 | } | ||
| 795 | |||
| 796 | if (enclen + chlen > screen_buf_end - screen_bp) | ||
| 797 | { | ||
| 798 | /* The allocated buffer for screen writes is too small. | ||
| 799 | Flush it and loop again without incrementing STR, so | ||
| 800 | that the next loop will begin with the same glyph. */ | ||
| 801 | int nbytes = screen_bp - screen_buf; | ||
| 802 | |||
| 803 | mouse_off_maybe (); | ||
| 804 | dosmemput (screen_buf, nbytes, (int)ScreenPrimary + offset); | ||
| 805 | if (screen_virtual_segment) | ||
| 806 | dosv_refresh_virtual_screen (offset, nbytes / 2); | ||
| 807 | new_pos_X += nbytes / 2; | ||
| 808 | offset += nbytes; | ||
| 809 | |||
| 810 | /* Prepare to reuse the same buffer again. */ | ||
| 811 | screen_bp = screen_buf; | ||
| 812 | } | ||
| 813 | else | ||
| 814 | { | ||
| 815 | /* There's enough place in the allocated buffer to add | ||
| 816 | the encoding of this glyph. */ | ||
| 817 | |||
| 818 | /* First, copy the encoded bytes. */ | ||
| 819 | for (bp = conversion_buffer; enclen--; bp++) | ||
| 820 | { | ||
| 821 | *screen_bp++ = (unsigned char)*bp; | ||
| 822 | *screen_bp++ = ScreenAttrib; | ||
| 823 | if (termscript) | ||
| 824 | fputc (*bp, termscript); | ||
| 825 | } | ||
| 826 | |||
| 827 | /* Now copy the bytes not consumed by the encoding. */ | ||
| 828 | if (chlen > 0) | ||
| 829 | { | ||
| 830 | buf += coding->consumed; | ||
| 831 | while (chlen--) | ||
| 832 | { | ||
| 833 | if (termscript) | ||
| 834 | fputc (*buf, termscript); | ||
| 835 | *screen_bp++ = (unsigned char)*buf++; | ||
| 836 | *screen_bp++ = ScreenAttrib; | ||
| 837 | } | ||
| 838 | } | ||
| 839 | |||
| 840 | /* Update STR and its remaining length. */ | ||
| 841 | str++; | ||
| 842 | sl--; | ||
| 843 | } | ||
| 844 | } | ||
| 698 | } | 845 | } |
| 699 | 846 | ||
| 847 | /* Dump whatever is left in the screen buffer. */ | ||
| 700 | mouse_off_maybe (); | 848 | mouse_off_maybe (); |
| 701 | dosmemput (buf, 2 * len, (int)ScreenPrimary + offset); | 849 | dosmemput (screen_buf, screen_bp - screen_buf, (int)ScreenPrimary + offset); |
| 702 | if (screen_virtual_segment) | 850 | if (screen_virtual_segment) |
| 703 | dosv_refresh_virtual_screen (offset, len); | 851 | dosv_refresh_virtual_screen (offset, (screen_bp - screen_buf) / 2); |
| 704 | new_pos_X += len; | 852 | new_pos_X += (screen_bp - screen_buf) / 2; |
| 853 | |||
| 854 | /* We may have to output some codes to terminate the writing. */ | ||
| 855 | if (CODING_REQUIRE_FLUSHING (coding)) | ||
| 856 | { | ||
| 857 | coding->mode |= CODING_MODE_LAST_BLOCK; | ||
| 858 | encode_coding (coding, "", conversion_buffer, 0, conversion_buffer_size); | ||
| 859 | if (coding->produced > 0) | ||
| 860 | { | ||
| 861 | for (screen_bp = screen_buf, bp = conversion_buffer; | ||
| 862 | coding->produced--; bp++) | ||
| 863 | { | ||
| 864 | *screen_bp++ = (unsigned char)*bp; | ||
| 865 | *screen_bp++ = ScreenAttrib; | ||
| 866 | if (termscript) | ||
| 867 | fputc (*bp, termscript); | ||
| 868 | } | ||
| 869 | offset += screen_bp - screen_buf; | ||
| 870 | mouse_off_maybe (); | ||
| 871 | dosmemput (screen_buf, screen_bp - screen_buf, | ||
| 872 | (int)ScreenPrimary + offset); | ||
| 873 | if (screen_virtual_segment) | ||
| 874 | dosv_refresh_virtual_screen (offset, (screen_bp - screen_buf) / 2); | ||
| 875 | new_pos_X += (screen_bp - screen_buf) / 2; | ||
| 876 | } | ||
| 877 | } | ||
| 705 | } | 878 | } |
| 706 | 879 | ||
| 707 | static void | 880 | static void |
| @@ -710,6 +883,10 @@ IT_clear_end_of_line (int first_unused) | |||
| 710 | char *spaces, *sp; | 883 | char *spaces, *sp; |
| 711 | int i, j; | 884 | int i, j; |
| 712 | int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y); | 885 | int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y); |
| 886 | extern int fatal_error_in_progress; | ||
| 887 | |||
| 888 | if (fatal_error_in_progress) | ||
| 889 | return; | ||
| 713 | 890 | ||
| 714 | IT_set_face (0); | 891 | IT_set_face (0); |
| 715 | if (termscript) | 892 | if (termscript) |
| @@ -890,6 +1067,24 @@ IT_update_end (struct frame *foo) | |||
| 890 | { | 1067 | { |
| 891 | } | 1068 | } |
| 892 | 1069 | ||
| 1070 | /* Insert and delete characters. These are not supposed to be used | ||
| 1071 | because we are supposed to turn off the feature of using them by | ||
| 1072 | setting char_ins_del_ok to zero (see internal_terminal_init). */ | ||
| 1073 | static void | ||
| 1074 | IT_insert_glyphs (start, len) | ||
| 1075 | register char *start; | ||
| 1076 | register int len; | ||
| 1077 | { | ||
| 1078 | abort (); | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | static void | ||
| 1082 | IT_delete_glyphs (n) | ||
| 1083 | register int n; | ||
| 1084 | { | ||
| 1085 | abort (); | ||
| 1086 | } | ||
| 1087 | |||
| 893 | /* set-window-configuration on window.c needs this. */ | 1088 | /* set-window-configuration on window.c needs this. */ |
| 894 | void | 1089 | void |
| 895 | x_set_menu_bar_lines (f, value, oldval) | 1090 | x_set_menu_bar_lines (f, value, oldval) |
| @@ -1208,6 +1403,8 @@ internal_terminal_init () | |||
| 1208 | init_frame_faces (selected_frame); | 1403 | init_frame_faces (selected_frame); |
| 1209 | 1404 | ||
| 1210 | ring_bell_hook = IT_ring_bell; | 1405 | ring_bell_hook = IT_ring_bell; |
| 1406 | insert_glyphs_hook = IT_insert_glyphs; | ||
| 1407 | delete_glyphs_hook = IT_delete_glyphs; | ||
| 1211 | write_glyphs_hook = IT_write_glyphs; | 1408 | write_glyphs_hook = IT_write_glyphs; |
| 1212 | cursor_to_hook = raw_cursor_to_hook = IT_cursor_to; | 1409 | cursor_to_hook = raw_cursor_to_hook = IT_cursor_to; |
| 1213 | clear_to_end_hook = IT_clear_to_end; | 1410 | clear_to_end_hook = IT_clear_to_end; |
| @@ -1223,6 +1420,8 @@ internal_terminal_init () | |||
| 1223 | set_terminal_modes_hook = IT_set_terminal_modes; | 1420 | set_terminal_modes_hook = IT_set_terminal_modes; |
| 1224 | reset_terminal_modes_hook = IT_reset_terminal_modes; | 1421 | reset_terminal_modes_hook = IT_reset_terminal_modes; |
| 1225 | set_terminal_window_hook = IT_set_terminal_window; | 1422 | set_terminal_window_hook = IT_set_terminal_window; |
| 1423 | |||
| 1424 | char_ins_del_ok = 0; /* just as fast to write the line */ | ||
| 1226 | #endif | 1425 | #endif |
| 1227 | } | 1426 | } |
| 1228 | 1427 | ||
| @@ -3729,11 +3928,26 @@ syms_of_msdos () | |||
| 3729 | "List of directories to search for bitmap files for X."); | 3928 | "List of directories to search for bitmap files for X."); |
| 3730 | Vx_bitmap_file_path = decode_env_path ((char *) 0, "."); | 3929 | Vx_bitmap_file_path = decode_env_path ((char *) 0, "."); |
| 3731 | 3930 | ||
| 3732 | /* The following two are from xfns.c: */ | 3931 | /* The following three are from xfns.c: */ |
| 3733 | Qbackground_color = intern ("background-color"); | 3932 | Qbackground_color = intern ("background-color"); |
| 3734 | staticpro (&Qbackground_color); | 3933 | staticpro (&Qbackground_color); |
| 3735 | Qforeground_color = intern ("foreground-color"); | 3934 | Qforeground_color = intern ("foreground-color"); |
| 3736 | staticpro (&Qforeground_color); | 3935 | staticpro (&Qforeground_color); |
| 3936 | |||
| 3937 | DEFVAR_BOOL ("unibyte-display-via-language-environment", | ||
| 3938 | &unibyte_display_via_language_environment, | ||
| 3939 | "*Non-nil means display unibyte text according to language environment.\n\ | ||
| 3940 | Specifically this means that unibyte non-ASCII characters\n\ | ||
| 3941 | are displayed by converting them to the equivalent multibyte characters\n\ | ||
| 3942 | according to the current language environment. As a result, they are\n\ | ||
| 3943 | displayed according to the current codepage and display table."); | ||
| 3944 | unibyte_display_via_language_environment = 0; | ||
| 3945 | |||
| 3946 | DEFVAR_LISP ("dos-unsupported-char-glyph", &Vdos_unsupported_char_glyph, | ||
| 3947 | "*Glyph to display instead of chars not supported by current codepage.\n\ | ||
| 3948 | |||
| 3949 | This variable is used only by MSDOS terminals."); | ||
| 3950 | Vdos_unsupported_char_glyph = '\177'; | ||
| 3737 | #endif | 3951 | #endif |
| 3738 | #ifndef subprocesses | 3952 | #ifndef subprocesses |
| 3739 | DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes, | 3953 | DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes, |