aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2009-02-14 10:50:29 +0000
committerEli Zaretskii2009-02-14 10:50:29 +0000
commitaff01dd96f651db009a0d318a14477ff1f91e1c8 (patch)
tree574a041234433d08db64505135bf141c4ace7ffa /src
parentb46957e2f4dacb404f30586c3675773a23715e16 (diff)
downloademacs-aff01dd96f651db009a0d318a14477ff1f91e1c8.tar.gz
emacs-aff01dd96f651db009a0d318a14477ff1f91e1c8.zip
(MAX_SCREEN_BUF): New macro.
(IT_write_glyphs): Make screen_buf[] always be MAX_SCREEN_BUF-long. Encode the entire run of glyphs sharing the same face, instead of doing that one glyph at a time (fixes a bug with displaying double-size characters).
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog8
-rw-r--r--src/msdos.c100
2 files changed, 46 insertions, 62 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index f9c24996500..fae28300ffc 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
12009-02-14 Eli Zaretskii <eliz@gnu.org>
2
3 * msdos.c (MAX_SCREEN_BUF): New macro.
4 (IT_write_glyphs): Make screen_buf[] always be MAX_SCREEN_BUF-long.
5 Encode the entire run of glyphs sharing the same face, instead of
6 doing that one glyph at a time (fixes a bug with displaying
7 double-size characters).
8
12009-02-13 Adrian Robert <Adrian.B.Robert@gmail.com> 92009-02-13 Adrian Robert <Adrian.B.Robert@gmail.com>
2 10
3 * nsfns.m (ns-read-file-name): BLOCK_INPUT while showing dialog. 11 * nsfns.m (ns-read-file-name): BLOCK_INPUT while showing dialog.
diff --git a/src/msdos.c b/src/msdos.c
index e4e57646991..6397539574e 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -957,19 +957,20 @@ IT_set_face (int face)
957 } 957 }
958} 958}
959 959
960/* According to RBIL (INTERRUP.A, V-1000), 160 is the maximum possible
961 width of a DOS display in any known text mode. We multiply by 2 to
962 accomodate the screen attribute byte. */
963#define MAX_SCREEN_BUF 160*2
964
960Lisp_Object Vdos_unsupported_char_glyph; 965Lisp_Object Vdos_unsupported_char_glyph;
961extern unsigned char *encode_terminal_code (struct glyph *, int, 966extern unsigned char *encode_terminal_code (struct glyph *, int,
962 struct coding_system *); 967 struct coding_system *);
963static void 968static void
964IT_write_glyphs (struct frame *f, struct glyph *str, int str_len) 969IT_write_glyphs (struct frame *f, struct glyph *str, int str_len)
965{ 970{
966 unsigned char *screen_buf, *screen_bp, *screen_buf_end, *bp; 971 unsigned char screen_buf[MAX_SCREEN_BUF], *screen_bp, *bp;
967 int unsupported_face = 0;
968 unsigned unsupported_char = '\177';
969 int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y); 972 int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y);
970 register int sl = str_len; 973 register int sl = str_len;
971 register int tlen = GLYPH_TABLE_LENGTH;
972 register Lisp_Object *tbase = GLYPH_TABLE_BASE;
973 struct tty_display_info *tty = FRAME_TTY (f); 974 struct tty_display_info *tty = FRAME_TTY (f);
974 struct frame *sf; 975 struct frame *sf;
975 unsigned char *conversion_buffer; 976 unsigned char *conversion_buffer;
@@ -990,8 +991,6 @@ IT_write_glyphs (struct frame *f, struct glyph *str, int str_len)
990 991
991 if (str_len <= 0) return; 992 if (str_len <= 0) return;
992 993
993 screen_buf = screen_bp = alloca (str_len * 2);
994 screen_buf_end = screen_buf + str_len * 2;
995 sf = SELECTED_FRAME(); 994 sf = SELECTED_FRAME();
996 995
997 /* Since faces get cached and uncached behind our back, we can't 996 /* Since faces get cached and uncached behind our back, we can't
@@ -1004,73 +1003,50 @@ IT_write_glyphs (struct frame *f, struct glyph *str, int str_len)
1004 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at 1003 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1005 the tail. */ 1004 the tail. */
1006 coding->mode &= ~CODING_MODE_LAST_BLOCK; 1005 coding->mode &= ~CODING_MODE_LAST_BLOCK;
1006 screen_bp = &screen_buf[0];
1007 while (sl > 0) 1007 while (sl > 0)
1008 { 1008 {
1009 int cf; 1009 int cf;
1010 int n;
1010 1011
1011 /* Glyphs with GLYPH_MASK_PADDING bit set are actually there 1012 /* If the face of this glyph is different from the current
1012 only for the redisplay code to know how many columns does 1013 screen face, update the screen attribute byte. */
1013 this character occupy on the screen. Skip padding glyphs. */ 1014 cf = str->face_id;
1014 if (CHAR_GLYPH_PADDING_P (*str)) 1015 if (cf != screen_face)
1015 { 1016 IT_set_face (cf); /* handles invalid faces gracefully */
1016 str++; 1017
1017 sl--; 1018 /* Identify a run of glyphs with the same face. */
1018 } 1019 for (n = 1; n < sl; ++n)
1019 else 1020 if (str[n].face_id != cf)
1021 break;
1022
1023 if (n >= sl)
1024 /* This is the last glyph. */
1025 coding->mode |= CODING_MODE_LAST_BLOCK;
1026
1027 conversion_buffer = encode_terminal_code (str, n, coding);
1028 if (coding->produced > 0)
1020 { 1029 {
1021 /* If the face of this glyph is different from the current 1030 /* Copy the encoded bytes to the screen buffer. */
1022 screen face, update the screen attribute byte. */ 1031 for (bp = conversion_buffer; coding->produced--; bp++)
1023 cf = str->face_id;
1024 if (cf != screen_face)
1025 IT_set_face (cf); /* handles invalid faces gracefully */
1026
1027 if (sl <= 1)
1028 /* This is the last glyph. */
1029 coding->mode |= CODING_MODE_LAST_BLOCK;
1030
1031 conversion_buffer = encode_terminal_code (str, 1, coding);
1032 if (coding->produced > 0)
1033 { 1032 {
1034 if (2*coding->produced > screen_buf_end - screen_bp) 1033 /* Paranoia: discard bytes that would overrun the end of
1034 the screen buffer. */
1035 if (screen_bp - screen_buf <= MAX_SCREEN_BUF - 2)
1035 { 1036 {
1036 /* The allocated buffer for screen writes is too small. 1037 *screen_bp++ = (unsigned char)*bp;
1037 Flush it and loop again without incrementing STR, so 1038 *screen_bp++ = ScreenAttrib;
1038 that the next loop will begin with the same glyph. */
1039 int nbytes = screen_bp - screen_buf;
1040
1041 mouse_off_maybe ();
1042 dosmemput (screen_buf, nbytes, (int)ScreenPrimary + offset);
1043 if (screen_virtual_segment)
1044 dosv_refresh_virtual_screen (offset, nbytes / 2);
1045 new_pos_X += nbytes / 2;
1046 offset += nbytes;
1047
1048 /* Prepare to reuse the same buffer again. */
1049 screen_bp = screen_buf;
1050 continue;
1051 }
1052 else
1053 {
1054 /* There's enough place in the allocated buffer to add
1055 the encoding of this glyph. */
1056
1057 /* Copy the encoded bytes to the allocated buffer. */
1058 for (bp = conversion_buffer; coding->produced--; bp++)
1059 {
1060 *screen_bp++ = (unsigned char)*bp;
1061 *screen_bp++ = ScreenAttrib;
1062 if (tty->termscript)
1063 fputc (*bp, tty->termscript);
1064 }
1065 } 1039 }
1040 if (tty->termscript)
1041 fputc (*bp, tty->termscript);
1066 } 1042 }
1067 /* Update STR and its remaining length. */
1068 str++;
1069 sl--;
1070 } 1043 }
1044 /* Update STR and its remaining length. */
1045 str += n;
1046 sl -= n;
1071 } 1047 }
1072 1048
1073 /* Dump whatever is left in the screen buffer. */ 1049 /* Dump whatever we have in the screen buffer. */
1074 mouse_off_maybe (); 1050 mouse_off_maybe ();
1075 dosmemput (screen_buf, screen_bp - screen_buf, (int)ScreenPrimary + offset); 1051 dosmemput (screen_buf, screen_bp - screen_buf, (int)ScreenPrimary + offset);
1076 if (screen_virtual_segment) 1052 if (screen_virtual_segment)