Mercurial > emacs
changeset 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 | ac5d1cd520fa |
children | f4646c30800a |
files | src/msdos.c |
diffstat | 1 files changed, 236 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/src/msdos.c Sun Dec 06 15:55:59 1998 +0000 +++ b/src/msdos.c Sun Dec 06 15:57:48 1998 +0000 @@ -50,8 +50,12 @@ #include "msdos.h" #include "systime.h" #include "termhooks.h" +#include "termchar.h" #include "dispextern.h" #include "termopts.h" +#include "charset.h" +#include "coding.h" +#include "disptab.h" #include "frame.h" #include "window.h" #include "buffer.h" @@ -352,6 +356,9 @@ static unsigned short screen_virtual_segment = 0; static unsigned short screen_virtual_offset = 0; +/* A flag to control how to display unibyte 8-bit character. */ +int unibyte_display_via_language_environment; + #if __DJGPP__ > 1 /* Update the screen from a part of relocated DOS/V screen buffer which begins at OFFSET and includes COUNT characters. */ @@ -671,37 +678,203 @@ ScreenAttrib = (FACE_BACKGROUND (fp) << 4) | FACE_FOREGROUND (fp); } +Lisp_Object Vdos_unsupported_char_glyph; + static void -IT_write_glyphs (GLYPH *str, int len) +IT_write_glyphs (GLYPH *str, int str_len) { - int newface; - int ch, l = len; - unsigned char *buf, *bp; + unsigned char *screen_buf, *screen_bp, *screen_buf_end, *bp; + int unsupported_face = FAST_GLYPH_FACE (Vdos_unsupported_char_glyph); + unsigned unsupported_char= FAST_GLYPH_CHAR (Vdos_unsupported_char_glyph); int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y); - - if (len == 0) return; + register int sl = str_len; + register int tlen = GLYPH_TABLE_LENGTH; + register Lisp_Object *tbase = GLYPH_TABLE_BASE; + + struct coding_system *coding = CODING_REQUIRE_ENCODING (&terminal_coding) + ? &terminal_coding + : &safe_terminal_coding; + + if (str_len == 0) return; - buf = bp = alloca (len * 2); + screen_buf = screen_bp = alloca (str_len * 2); + screen_buf_end = screen_buf + str_len * 2; - while (--l >= 0) + /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at + the tail. */ + terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK; + while (sl) { - newface = FAST_GLYPH_FACE (*str); - if (newface != screen_face) - IT_set_face (newface); - ch = FAST_GLYPH_CHAR (*str); - *bp++ = (unsigned char)ch; - *bp++ = ScreenAttrib; - - if (termscript) - fputc (ch, termscript); - str++; + int cf, ch, chlen, enclen; + unsigned char workbuf[4], *buf; + register GLYPH g = *str; + + /* Find the actual glyph to display by traversing the entire + aliases chain for this glyph. */ + GLYPH_FOLLOW_ALIASES (tbase, tlen, g); + + /* Glyphs with GLYPH_MASK_PADDING bit set are actually there + only for the redisplay code to know how many columns does + this character occupy on the screen. Skip padding glyphs. */ + if ((g & GLYPH_MASK_PADDING)) + { + str++; + sl--; + } + else + { + /* Convert the character code to multibyte, if they + requested display via language environment. */ + ch = FAST_GLYPH_CHAR (g); + if (unibyte_display_via_language_environment + && SINGLE_BYTE_CHAR_P (ch) + && (ch >= 0240 || !NILP (Vnonascii_translation_table))) + ch = unibyte_char_to_multibyte (ch); + + /* Invalid characters are displayed with a special glyph. */ + if (ch > MAX_CHAR) + { + g = !NILP (Vdos_unsupported_char_glyph) + ? Vdos_unsupported_char_glyph + : MAKE_GLYPH (selected_frame, '\177', + GLYPH_FACE (selected_frame, g)); + ch = FAST_GLYPH_CHAR (g); + } + if (COMPOSITE_CHAR_P (ch)) + { + /* If CH is a composite character, we can display + only the first component. */ + g = cmpchar_table[COMPOSITE_CHAR_ID (ch)]->glyph[0], + ch = GLYPH_CHAR (selected_frame, g); + cf = FAST_GLYPH_FACE (g); + } + + /* If the face of this glyph is different from the current + screen face, update the screen attribute byte. */ + cf = FAST_GLYPH_FACE (g); + if (cf != screen_face) + IT_set_face (cf); /* handles invalid faces gracefully */ + + if (GLYPH_SIMPLE_P (tbase, tlen, g)) + /* We generate the multi-byte form of CH in BUF. */ + chlen = CHAR_STRING (ch, workbuf, buf); + else + { + /* We have a string in Vglyph_table. */ + chlen = GLYPH_LENGTH (tbase, g); + buf = GLYPH_STRING (tbase, g); + } + + /* If the character is not multibyte, don't bother converting it. + FIXME: what about "emacs --unibyte" */ + if (chlen == 1) + { + *conversion_buffer = (unsigned char)ch; + chlen = 0; + enclen = 1; + } + else + { + encode_coding (coding, buf, conversion_buffer, chlen, + conversion_buffer_size); + chlen -= coding->consumed; + enclen = coding->produced; + + /* Replace glyph codes that cannot be converted by + terminal_coding with Vdos_unsupported_char_glyph. */ + if (*conversion_buffer == '?') + { + char *cbp = conversion_buffer; + + while (cbp < conversion_buffer + enclen && *cbp == '?') + *cbp++ = unsupported_char; + if (unsupported_face != screen_face) + IT_set_face (unsupported_face); + } + } + + if (enclen + chlen > screen_buf_end - screen_bp) + { + /* The allocated buffer for screen writes is too small. + Flush it and loop again without incrementing STR, so + that the next loop will begin with the same glyph. */ + int nbytes = screen_bp - screen_buf; + + mouse_off_maybe (); + dosmemput (screen_buf, nbytes, (int)ScreenPrimary + offset); + if (screen_virtual_segment) + dosv_refresh_virtual_screen (offset, nbytes / 2); + new_pos_X += nbytes / 2; + offset += nbytes; + + /* Prepare to reuse the same buffer again. */ + screen_bp = screen_buf; + } + else + { + /* There's enough place in the allocated buffer to add + the encoding of this glyph. */ + + /* First, copy the encoded bytes. */ + for (bp = conversion_buffer; enclen--; bp++) + { + *screen_bp++ = (unsigned char)*bp; + *screen_bp++ = ScreenAttrib; + if (termscript) + fputc (*bp, termscript); + } + + /* Now copy the bytes not consumed by the encoding. */ + if (chlen > 0) + { + buf += coding->consumed; + while (chlen--) + { + if (termscript) + fputc (*buf, termscript); + *screen_bp++ = (unsigned char)*buf++; + *screen_bp++ = ScreenAttrib; + } + } + + /* Update STR and its remaining length. */ + str++; + sl--; + } + } } + /* Dump whatever is left in the screen buffer. */ mouse_off_maybe (); - dosmemput (buf, 2 * len, (int)ScreenPrimary + offset); + dosmemput (screen_buf, screen_bp - screen_buf, (int)ScreenPrimary + offset); if (screen_virtual_segment) - dosv_refresh_virtual_screen (offset, len); - new_pos_X += len; + dosv_refresh_virtual_screen (offset, (screen_bp - screen_buf) / 2); + new_pos_X += (screen_bp - screen_buf) / 2; + + /* We may have to output some codes to terminate the writing. */ + if (CODING_REQUIRE_FLUSHING (coding)) + { + coding->mode |= CODING_MODE_LAST_BLOCK; + encode_coding (coding, "", conversion_buffer, 0, conversion_buffer_size); + if (coding->produced > 0) + { + for (screen_bp = screen_buf, bp = conversion_buffer; + coding->produced--; bp++) + { + *screen_bp++ = (unsigned char)*bp; + *screen_bp++ = ScreenAttrib; + if (termscript) + fputc (*bp, termscript); + } + offset += screen_bp - screen_buf; + mouse_off_maybe (); + dosmemput (screen_buf, screen_bp - screen_buf, + (int)ScreenPrimary + offset); + if (screen_virtual_segment) + dosv_refresh_virtual_screen (offset, (screen_bp - screen_buf) / 2); + new_pos_X += (screen_bp - screen_buf) / 2; + } + } } static void @@ -710,6 +883,10 @@ char *spaces, *sp; int i, j; int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y); + extern int fatal_error_in_progress; + + if (fatal_error_in_progress) + return; IT_set_face (0); if (termscript) @@ -890,6 +1067,24 @@ { } +/* Insert and delete characters. These are not supposed to be used + because we are supposed to turn off the feature of using them by + setting char_ins_del_ok to zero (see internal_terminal_init). */ +static void +IT_insert_glyphs (start, len) + register char *start; + register int len; +{ + abort (); +} + +static void +IT_delete_glyphs (n) + register int n; +{ + abort (); +} + /* set-window-configuration on window.c needs this. */ void x_set_menu_bar_lines (f, value, oldval) @@ -1208,6 +1403,8 @@ init_frame_faces (selected_frame); ring_bell_hook = IT_ring_bell; + insert_glyphs_hook = IT_insert_glyphs; + delete_glyphs_hook = IT_delete_glyphs; write_glyphs_hook = IT_write_glyphs; cursor_to_hook = raw_cursor_to_hook = IT_cursor_to; clear_to_end_hook = IT_clear_to_end; @@ -1223,6 +1420,8 @@ set_terminal_modes_hook = IT_set_terminal_modes; reset_terminal_modes_hook = IT_reset_terminal_modes; set_terminal_window_hook = IT_set_terminal_window; + + char_ins_del_ok = 0; /* just as fast to write the line */ #endif } @@ -3729,11 +3928,26 @@ "List of directories to search for bitmap files for X."); Vx_bitmap_file_path = decode_env_path ((char *) 0, "."); - /* The following two are from xfns.c: */ + /* The following three are from xfns.c: */ Qbackground_color = intern ("background-color"); staticpro (&Qbackground_color); Qforeground_color = intern ("foreground-color"); staticpro (&Qforeground_color); + + DEFVAR_BOOL ("unibyte-display-via-language-environment", + &unibyte_display_via_language_environment, + "*Non-nil means display unibyte text according to language environment.\n\ +Specifically this means that unibyte non-ASCII characters\n\ +are displayed by converting them to the equivalent multibyte characters\n\ +according to the current language environment. As a result, they are\n\ +displayed according to the current codepage and display table."); + unibyte_display_via_language_environment = 0; + + DEFVAR_LISP ("dos-unsupported-char-glyph", &Vdos_unsupported_char_glyph, + "*Glyph to display instead of chars not supported by current codepage.\n\ + +This variable is used only by MSDOS terminals."); + Vdos_unsupported_char_glyph = '\177'; #endif #ifndef subprocesses DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,