aboutsummaryrefslogtreecommitdiffstats
path: root/src/msdos.c
diff options
context:
space:
mode:
authorEli Zaretskii1998-12-06 15:57:48 +0000
committerEli Zaretskii1998-12-06 15:57:48 +0000
commitaa9ce936727b47a6e4c110d378feffc5c884135a (patch)
treec7e1c35eaaf0accb321d0980574385752305803c /src/msdos.c
parentd24422702fb81c15b8c3698cc051be7ee0d05eb2 (diff)
downloademacs-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.c258
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;
352static unsigned short screen_virtual_segment = 0; 356static unsigned short screen_virtual_segment = 0;
353static unsigned short screen_virtual_offset = 0; 357static unsigned short screen_virtual_offset = 0;
354 358
359/* A flag to control how to display unibyte 8-bit character. */
360int 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
681Lisp_Object Vdos_unsupported_char_glyph;
682
674static void 683static void
675IT_write_glyphs (GLYPH *str, int len) 684IT_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
707static void 880static 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). */
1073static void
1074IT_insert_glyphs (start, len)
1075 register char *start;
1076 register int len;
1077{
1078 abort ();
1079}
1080
1081static void
1082IT_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. */
894void 1089void
895x_set_menu_bar_lines (f, value, oldval) 1090x_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\
3940Specifically this means that unibyte non-ASCII characters\n\
3941are displayed by converting them to the equivalent multibyte characters\n\
3942according to the current language environment. As a result, they are\n\
3943displayed 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
3949This 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,