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.");