Mercurial > emacs
diff src/term.c @ 83231:549734260e34
Merged in changes from CVS trunk.
Patches applied:
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-714
Update from CVS
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-271
author | Karoly Lorentey <lorentey@elte.hu> |
---|---|
date | Wed, 08 Dec 2004 22:20:27 +0000 |
parents | 6b4b299e2cd5 24c51e9d8586 |
children | 4ee39d9428b0 |
line wrap: on
line diff
--- a/src/term.c Sun Nov 28 14:39:06 2004 +0000 +++ b/src/term.c Wed Dec 08 22:20:27 2004 +0000 @@ -612,39 +612,43 @@ } } -/* Encode SRC_LEN glyphs starting at SRC to terminal output codes and - store them at DST. Do not write more than DST_LEN bytes. That may - require stopping before all SRC_LEN input glyphs have been - converted. - - We store the number of glyphs actually converted in *CONSUMED. The - return value is the number of bytes store in DST. */ - -int -encode_terminal_code (struct coding_system *coding, - struct glyph *src, - unsigned char *dst, - int src_len, - int dst_len, - int *consumed) +/* Buffer to store the source and result of code conversion for terminal. */ +static unsigned char *encode_terminal_buf; +/* Allocated size of the above buffer. */ +static int encode_terminal_bufsize; + +/* Encode SRC_LEN glyphs starting at SRC to terminal output codes. + Set CODING->produced to the byte-length of the resulting byte + sequence, and return a pointer to that byte sequence. */ + +unsigned char * +encode_terminal_code (src, src_len, coding) + struct glyph *src; + int src_len; + struct coding_system *coding; { struct glyph *src_start = src, *src_end = src + src_len; - unsigned char *dst_start = dst, *dst_end = dst + dst_len; register GLYPH g; - unsigned char workbuf[MAX_MULTIBYTE_LENGTH]; - const unsigned char *buf; - int len; + unsigned char *buf; + int nchars, nbytes, required; register int tlen = GLYPH_TABLE_LENGTH; register Lisp_Object *tbase = GLYPH_TABLE_BASE; - int result; - - /* If the specified coding does any conversion, use it, otherwise use - safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here - because it always returns 1 if the member src_multibyte is 1. */ - coding = (coding->common_flags & CODING_REQUIRE_ENCODING_MASK - ? coding - : &safe_terminal_coding); - + + /* Allocate sufficient size of buffer to store all characters in + multibyte-form. But, it may be enlarged on demand if + Vglyph_table contains a string. */ + required = MAX_MULTIBYTE_LENGTH * src_len; + if (encode_terminal_bufsize < required) + { + encode_terminal_bufsize = required; + if (encode_terminal_bufsize == 0) + encode_terminal_buf = xmalloc (required); + else + encode_terminal_buf = xrealloc (encode_terminal_buf, required); + } + + buf = encode_terminal_buf; + nchars = 0; while (src < src_end) { /* We must skip glyphs to be padded for a wide character. */ @@ -655,18 +659,11 @@ if (g < 0 || g >= tlen) { /* This glyph doesn't has an entry in Vglyph_table. */ - if (! CHAR_VALID_P (src->u.ch, 0)) - { - len = 1; - buf = " "; - coding->src_multibyte = 0; - } + if (CHAR_VALID_P (src->u.ch, 0)) + buf += CHAR_STRING (src->u.ch, buf); else - { - len = CHAR_STRING (src->u.ch, workbuf); - buf = workbuf; - coding->src_multibyte = 1; - } + *buf++ = SPACEGLYPH; + nchars++; } else { @@ -676,48 +673,61 @@ if (GLYPH_SIMPLE_P (tbase, tlen, g)) { - /* We set the multi-byte form of a character in G - (that should be an ASCII character) at - WORKBUF. */ - workbuf[0] = FAST_GLYPH_CHAR (g); - len = 1; - buf = workbuf; - coding->src_multibyte = 0; + int c = FAST_GLYPH_CHAR (g); + + if (CHAR_VALID_P (c, 0)) + buf += CHAR_STRING (c, buf); + else + *buf++ = SPACEGLYPH; + nchars++; } else { /* We have a string in Vglyph_table. */ - len = GLYPH_LENGTH (tbase, g); - buf = GLYPH_STRING (tbase, g); - coding->src_multibyte = STRING_MULTIBYTE (tbase[g]); + Lisp_Object string; + + string = tbase[g]; + if (! STRING_MULTIBYTE (string)) + string = string_to_multibyte (string); + nbytes = buf - encode_terminal_buf; + if (nbytes + SBYTES (string) < encode_terminal_bufsize) + { + encode_terminal_bufsize = nbytes + SBYTES (string); + encode_terminal_buf = xrealloc (encode_terminal_buf, + encode_terminal_bufsize); + buf = encode_terminal_buf + nbytes; + } + bcopy (SDATA (string), buf, SBYTES (string)); + buf += SBYTES (string); + nchars += SCHARS (string); } } - - result = encode_coding (coding, buf, dst, len, dst_end - dst); - len -= coding->consumed; - dst += coding->produced; - if (result == CODING_FINISH_INSUFFICIENT_DST - || (result == CODING_FINISH_INSUFFICIENT_SRC - && len > dst_end - dst)) - /* The remaining output buffer is too short. We must - break the loop here without increasing SRC so that the - next call of this function starts from the same glyph. */ - break; - - if (len > 0) - { - /* This is the case that a code of the range 0200..0237 - exists in buf. We must just write out such a code. */ - buf += coding->consumed; - while (len--) - *dst++ = *buf++; - } } src++; } - *consumed = src - src_start; - return (dst - dst_start); + nbytes = buf - encode_terminal_buf; + coding->src_multibyte = 1; + coding->dst_multibyte = 0; + if (SYMBOLP (coding->pre_write_conversion) + && ! NILP (Ffboundp (coding->pre_write_conversion))) + { + run_pre_write_conversin_on_c_str (&encode_terminal_buf, + &encode_terminal_bufsize, + nchars, nbytes, coding); + nchars = coding->produced_char; + nbytes = coding->produced; + } + required = nbytes + encoding_buffer_size (coding, nbytes); + if (encode_terminal_bufsize < required) + { + encode_terminal_bufsize = required; + encode_terminal_buf = xrealloc (encode_terminal_buf, required); + } + + encode_coding (coding, encode_terminal_buf, encode_terminal_buf + nbytes, + nbytes, encode_terminal_bufsize - nbytes); + return encode_terminal_buf + nbytes; } @@ -736,9 +746,8 @@ void tty_write_glyphs (struct frame *f, struct glyph *string, int len) { - int produced, consumed; - unsigned char conversion_buffer[1024]; - int conversion_buffer_size = sizeof conversion_buffer; + unsigned char *conversion_buffer; + struct coding_system *coding; struct tty_display_info *tty = FRAME_TTY (f); @@ -757,9 +766,14 @@ cmplus (tty, len); + /* If terminal_coding does any conversion, use it, otherwise use + safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here + because it always return 1 if the member src_multibyte is 1. */ + coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK + ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding); /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */ - FRAME_TERMINAL_CODING (f)->mode &= ~CODING_MODE_LAST_BLOCK; + coding->mode &= ~CODING_MODE_LAST_BLOCK; while (len > 0) { @@ -775,55 +789,26 @@ highlight_if_desired (tty); turn_on_face (f, face_id); - while (n > 0) + if (n == len) + /* This is the last run. */ + coding->mode |= CODING_MODE_LAST_BLOCK; + conversion_buffer = encode_terminal_code (string, n, coding); + if (coding->produced > 0) { - /* We use a fixed size (1024 bytes) of conversion buffer. - Usually it is sufficient, but if not, we just repeat the - loop. */ - produced = encode_terminal_code (FRAME_TERMINAL_CODING (f), - string, conversion_buffer, - n, conversion_buffer_size, - &consumed); - if (produced > 0) - { - fwrite (conversion_buffer, 1, produced, - tty->output); - if (ferror (tty->output)) - clearerr (tty->output); - if (tty->termscript) - fwrite (conversion_buffer, 1, produced, - tty->termscript); - } - len -= consumed; - n -= consumed; - string += consumed; + fwrite (conversion_buffer, 1, coding->produced, tty->output); + if (ferror (tty->output)) + clearerr (tty->output); + if (tty->termscript) + fwrite (conversion_buffer, 1, coding->produced, tty->termscript); } + len -= n; + string += n; /* Turn appearance modes off. */ turn_off_face (f, face_id); turn_off_highlight (tty); } - /* We may have to output some codes to terminate the writing. */ - if (CODING_REQUIRE_FLUSHING (FRAME_TERMINAL_CODING (f))) - { - FRAME_TERMINAL_CODING (f)->mode |= CODING_MODE_LAST_BLOCK; - encode_coding (FRAME_TERMINAL_CODING (f), "", - conversion_buffer, 0, conversion_buffer_size); - if (FRAME_TERMINAL_CODING (f)->produced > 0) - { - fwrite (conversion_buffer, 1, - FRAME_TERMINAL_CODING (f)->produced, - tty->output); - if (ferror (tty->output)) - clearerr (tty->output); - if (tty->termscript) - fwrite (conversion_buffer, 1, - FRAME_TERMINAL_CODING (f)->produced, - tty->termscript); - } - } - cmcheckmagic (tty); } @@ -848,6 +833,9 @@ { char *buf; struct glyph *glyph = NULL; + unsigned char *conversion_buffer; + unsigned char space[1]; + struct coding_system *coding; struct tty_display_info *tty = FRAME_TTY (f); @@ -863,19 +851,26 @@ turn_on_insert (tty); cmplus (tty, len); - /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */ - FRAME_TERMINAL_CODING (f)->mode &= ~CODING_MODE_LAST_BLOCK; + + if (! start) + space[0] = SPACEGLYPH; + + /* If terminal_coding does any conversion, use it, otherwise use + safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here + because it always return 1 if the member src_multibyte is 1. */ + coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK + ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding); + /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at + the tail. */ + coding->mode &= ~CODING_MODE_LAST_BLOCK; + while (len-- > 0) { - int produced, consumed; - unsigned char conversion_buffer[1024]; - int conversion_buffer_size = sizeof conversion_buffer; - OUTPUT1_IF (tty, tty->TS_ins_char); if (!start) { - conversion_buffer[0] = SPACEGLYPH; - produced = 1; + conversion_buffer = space; + coding->produced = 1; } else { @@ -893,24 +888,18 @@ if (len <= 0) /* This is the last glyph. */ - FRAME_TERMINAL_CODING (f)->mode |= CODING_MODE_LAST_BLOCK; - - /* The size of conversion buffer (1024 bytes) is surely - sufficient for just one glyph. */ - produced = encode_terminal_code (FRAME_TERMINAL_CODING (f), - glyph, conversion_buffer, 1, - conversion_buffer_size, &consumed); + coding->mode |= CODING_MODE_LAST_BLOCK; + + conversion_buffer = encode_terminal_code (glyph, 1, coding); } - if (produced > 0) + if (coding->produced > 0) { - fwrite (conversion_buffer, 1, produced, - tty->output); + fwrite (conversion_buffer, 1, coding->produced, tty->output); if (ferror (tty->output)) clearerr (tty->output); if (tty->termscript) - fwrite (conversion_buffer, 1, produced, - tty->termscript); + fwrite (conversion_buffer, 1, coding->produced, tty->termscript); } OUTPUT1_IF (tty, tty->TS_pad_inserted_char); @@ -2445,6 +2434,8 @@ add_keyboard_wait_descriptor (fileno (tty->input)); + encode_terminal_bufsize = 0; + #ifdef WINDOWSNT initialize_w32_display ();