summaryrefslogtreecommitdiff
path: root/src/term.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/term.c')
-rw-r--r--src/term.c153
1 files changed, 86 insertions, 67 deletions
diff --git a/src/term.c b/src/term.c
index 23da2ac8704..d53ba74c781 100644
--- a/src/term.c
+++ b/src/term.c
@@ -29,6 +29,8 @@ Boston, MA 02111-1307, USA. */
#include "termchar.h"
#include "termopts.h"
#include "lisp.h"
+#include "buffer.h"
+#include "character.h"
#include "charset.h"
#include "coding.h"
#include "keyboard.h"
@@ -791,10 +793,12 @@ clear_end_of_line (first_unused_hpos)
}
}
-/* 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;
+/* Buffers to store the source and result of code conversion for terminal. */
+static unsigned char *encode_terminal_src;
+static unsigned char *encode_terminal_dst;
+/* Allocated sizes of the above buffers. */
+static int encode_terminal_src_size;
+static int encode_terminal_dst_size;
/* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
Set CODING->produced to the byte-length of the resulting byte
@@ -812,37 +816,40 @@ encode_terminal_code (src, src_len, coding)
int nchars, nbytes, required;
register int tlen = GLYPH_TABLE_LENGTH;
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
+ Lisp_Object charset_list;
/* 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)
+ if (encode_terminal_src_size < required)
{
- if (encode_terminal_bufsize == 0)
- encode_terminal_buf = xmalloc (required);
+ if (encode_terminal_src_size == 0)
+ encode_terminal_src = xmalloc (required);
else
- encode_terminal_buf = xrealloc (encode_terminal_buf, required);
- encode_terminal_bufsize = required;
+ encode_terminal_src = xrealloc (encode_terminal_src, required);
+ encode_terminal_src_size = required;
}
- buf = encode_terminal_buf;
+ charset_list = coding_charset_list (coding);
+
+ buf = encode_terminal_src;
nchars = 0;
while (src < src_end)
{
/* We must skip glyphs to be padded for a wide character. */
if (! CHAR_GLYPH_PADDING_P (*src))
{
+ int c;
+ Lisp_Object string;
+
+ string = Qnil;
g = GLYPH_FROM_CHAR_GLYPH (src[0]);
if (g < 0 || g >= tlen)
{
/* This glyph doesn't has an entry in Vglyph_table. */
- if (CHAR_VALID_P (src->u.ch, 0))
- buf += CHAR_STRING (src->u.ch, buf);
- else
- *buf++ = SPACEGLYPH;
- nchars++;
+ c = src->u.ch;
}
else
{
@@ -851,69 +858,87 @@ encode_terminal_code (src, src_len, coding)
GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
if (GLYPH_SIMPLE_P (tbase, tlen, g))
- {
- int c = FAST_GLYPH_CHAR (g);
+ /* We set the multi-byte form of a character in G
+ (that should be an ASCII character) at WORKBUF. */
+ c = FAST_GLYPH_CHAR (g);
+ else
+ /* We have a string in Vglyph_table. */
+ string = tbase[g];
+ }
- if (CHAR_VALID_P (c, 0))
- buf += CHAR_STRING (c, buf);
- else
- *buf++ = SPACEGLYPH;
+ if (NILP (string))
+ {
+ if (char_charset (c, charset_list, NULL))
+ {
+ /* Store the multibyte form of C at BUF. */
+ buf += CHAR_STRING (c, buf);
nchars++;
}
else
{
- /* We have a string in Vglyph_table. */
- Lisp_Object string;
-
- string = tbase[g];
- if (! STRING_MULTIBYTE (string))
- string = string_to_multibyte (string);
- nbytes = buf - encode_terminal_buf;
- if (encode_terminal_bufsize < nbytes + SBYTES (string))
+ /* C is not encodable. */
+ *buf++ = '?';
+ nchars++;
+ while (src + 1 < src_end && CHAR_GLYPH_PADDING_P (src[1]))
{
- encode_terminal_bufsize = nbytes + SBYTES (string);
- encode_terminal_buf = xrealloc (encode_terminal_buf,
- encode_terminal_bufsize);
- buf = encode_terminal_buf + nbytes;
+ *buf++ = '?';
+ nchars++;
+ src++;
}
- bcopy (SDATA (string), buf, SBYTES (string));
- buf += SBYTES (string);
- nchars += SCHARS (string);
}
}
+ else
+ {
+ unsigned char *p = SDATA (string), *pend = p + SBYTES (string);
+
+ if (! STRING_MULTIBYTE (string))
+ string = string_to_multibyte (string);
+ nbytes = buf - encode_terminal_src;
+ if (encode_terminal_src_size < nbytes + SBYTES (string))
+ {
+ encode_terminal_src_size = nbytes + SBYTES (string);
+ encode_terminal_src = xrealloc (encode_terminal_src,
+ encode_terminal_src_size);
+ buf = encode_terminal_src + nbytes;
+ }
+ bcopy (SDATA (string), buf, SBYTES (string));
+ buf += SBYTES (string);
+ nchars += SCHARS (string);
+ }
}
src++;
}
- 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)))
+ if (nchars == 0)
{
- run_pre_write_conversin_on_c_str (&encode_terminal_buf,
- &encode_terminal_bufsize,
- nchars, nbytes, coding);
- nchars = coding->produced_char;
- nbytes = coding->produced;
+ coding->produced = 0;
+ return NULL;
}
- required = nbytes + encoding_buffer_size (coding, nbytes);
- if (encode_terminal_bufsize < required)
+
+ nbytes = buf - encode_terminal_src;
+ coding->source = encode_terminal_src;
+ if (encode_terminal_dst_size == 0)
{
- encode_terminal_bufsize = required;
- encode_terminal_buf = xrealloc (encode_terminal_buf, required);
+ encode_terminal_dst_size = encode_terminal_src_size;
+ encode_terminal_dst = xmalloc (encode_terminal_dst_size);
}
+ coding->destination = encode_terminal_dst;
+ coding->dst_bytes = encode_terminal_dst_size;
+ encode_coding_object (coding, Qnil, 0, 0, nchars, nbytes, Qnil);
+ /* coding->destination may have been reallocated. */
+ encode_terminal_dst = coding->destination;
+ encode_terminal_dst_size = coding->dst_bytes;
- encode_coding (coding, encode_terminal_buf, encode_terminal_buf + nbytes,
- nbytes, encode_terminal_bufsize - nbytes);
- return encode_terminal_buf + nbytes;
+ return (encode_terminal_dst);
}
+
void
write_glyphs (string, len)
register struct glyph *string;
register int len;
{
+ int produced, consumed;
struct frame *sf = XFRAME (selected_frame);
struct frame *f = updating_frame ? updating_frame : sf;
unsigned char *conversion_buffer;
@@ -1715,26 +1740,19 @@ produce_glyphs (it)
it->pixel_width = nspaces;
it->nglyphs = nspaces;
}
- else if (SINGLE_BYTE_CHAR_P (it->c))
+ else if (CHAR_BYTE8_P (it->c))
{
- /* Coming here means that it->c is from display table, thus we
- must send the code as is to the terminal. Although there's
- no way to know how many columns it occupies on a screen, it
- is a good assumption that a single byte code has 1-column
- width. */
+ /* We must send the raw 8-bit byte as is to the terminal.
+ Although there's no way to know how many columns it occupies
+ on a screen, it is a good assumption that a single byte code
+ has 1-column width. */
it->pixel_width = it->nglyphs = 1;
if (it->glyph_row)
append_glyph (it);
}
else
{
- /* A multi-byte character. The display width is fixed for all
- characters of the set. Some of the glyphs may have to be
- ignored because they are already displayed in a continued
- line. */
- int charset = CHAR_CHARSET (it->c);
-
- it->pixel_width = CHARSET_WIDTH (charset);
+ it->pixel_width = CHAR_WIDTH (it->c);
it->nglyphs = it->pixel_width;
if (it->glyph_row)
@@ -2254,7 +2272,8 @@ term_init (terminal_type)
int status;
struct frame *sf = XFRAME (selected_frame);
- encode_terminal_bufsize = 0;
+ encode_terminal_src_size = 0;
+ encode_terminal_dst_size = 0;
#ifdef WINDOWSNT
initialize_w32_display ();