Mercurial > emacs
comparison src/msdos.c @ 23825:085b163b6115
(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.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Sun, 06 Dec 1998 15:57:48 +0000 |
parents | fe9557bb7056 |
children | f2d6df96a3c7 |
comparison
equal
deleted
inserted
replaced
23824:ac5d1cd520fa | 23825:085b163b6115 |
---|---|
48 | 48 |
49 #include "dosfns.h" | 49 #include "dosfns.h" |
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" |
58 #include "commands.h" | 62 #include "commands.h" |
59 #include <go32.h> | 63 #include <go32.h> |
349 /* Holds the address of the text-mode screen buffer. */ | 353 /* Holds the address of the text-mode screen buffer. */ |
350 static unsigned long screen_old_address = 0; | 354 static unsigned long screen_old_address = 0; |
351 /* Segment and offset of the virtual screen. If 0, DOS/V is NOT loaded. */ | 355 /* Segment and offset of the virtual screen. If 0, DOS/V is NOT loaded. */ |
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; |
358 | |
359 /* A flag to control how to display unibyte 8-bit character. */ | |
360 int unibyte_display_via_language_environment; | |
354 | 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. */ |
358 static void | 365 static void |
669 face, FACE_FOREGROUND (fp), FACE_BACKGROUND (fp)); | 676 face, FACE_FOREGROUND (fp), FACE_BACKGROUND (fp)); |
670 screen_face = face; | 677 screen_face = 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); |
681 | 690 register int sl = str_len; |
682 if (len == 0) return; | 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; | |
697 | |
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); |
698 } | 715 |
699 | 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 } | |
845 } | |
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 |
708 IT_clear_end_of_line (int first_unused) | 881 IT_clear_end_of_line (int first_unused) |
709 { | 882 { |
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) |
716 fprintf (termscript, "<CLR:EOL>"); | 893 fprintf (termscript, "<CLR:EOL>"); |
717 i = (j = screen_size_X - new_pos_X) * 2; | 894 i = (j = screen_size_X - new_pos_X) * 2; |
886 } | 1063 } |
887 | 1064 |
888 static void | 1065 static void |
889 IT_update_end (struct frame *foo) | 1066 IT_update_end (struct frame *foo) |
890 { | 1067 { |
1068 } | |
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 (); | |
891 } | 1086 } |
892 | 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) |
1206 the_only_x_display.font = (XFontStruct *)1; /* must *not* be zero */ | 1401 the_only_x_display.font = (XFontStruct *)1; /* must *not* be zero */ |
1207 | 1402 |
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; |
1214 clear_end_of_line_hook = IT_clear_end_of_line; | 1411 clear_end_of_line_hook = IT_clear_end_of_line; |
1215 clear_frame_hook = IT_clear_screen; | 1412 clear_frame_hook = IT_clear_screen; |
1221 | 1418 |
1222 /* These hooks are called by term.c without being checked. */ | 1419 /* These hooks are called by term.c without being checked. */ |
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 |
1229 dos_get_saved_screen (screen, rows, cols) | 1428 dos_get_saved_screen (screen, rows, cols) |
1230 char **screen; | 1429 char **screen; |
3727 #ifndef HAVE_X_WINDOWS | 3926 #ifndef HAVE_X_WINDOWS |
3728 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path, | 3927 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path, |
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, |
3740 "*Non-nil means delete processes immediately when they exit.\n\ | 3954 "*Non-nil means delete processes immediately when they exit.\n\ |
3741 nil means don't delete them until `list-processes' is run."); | 3955 nil means don't delete them until `list-processes' is run."); |