/* Terminal control module for terminals described by TERMCAP
- Copyright (C) 1985, 86, 87, 93, 94, 95, 98, 2000, 2001, 2002
- Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
+ 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
/* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
{
if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
{
- OUTPUT_IF (TS_termcap_modes);
+ if (TS_termcap_modes)
+ OUTPUT (TS_termcap_modes);
+ else
+ {
+ /* Output enough newlines to scroll all the old screen contents
+ off the screen, so it won't be overwritten and lost. */
+ int i;
+ for (i = 0; i < FRAME_LINES (XFRAME (selected_frame)); i++)
+ putchar ('\n');
+ }
+
OUTPUT_IF (TS_cursor_visible);
OUTPUT_IF (TS_keypad_mode);
losecursor ();
}
}
\f
-/* Buffer to store the result of terminal codes. It is initialized in
- term_init and, if necessary, enlarged in encode_terminal_code. */
-unsigned char *terminal_encode_buffer;
-/* Size of terminal_encode_buffer. */
-static int terminal_encode_buf_size;
-
-/* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
- store them in terminal_encode_buffer.
-
- We store the number of glyphs actually converted in *CONSUMED. The
- return value is the number of bytes stored in
- terminal_encode_buffer.
-
- This function will stop before encoding all glyphs in these two
- cases.
-
- (1) If the first glyph doesn't have a string entry in Vglyph_table,
- it stops at encountering a glyph that has a string entry in
- Vglyph_table.n
-
- (2) If the first has a string entry in Vglyph_table, it stops after
- encoding that string.
-*/
-
-int
-encode_terminal_code (src, src_len, consumed)
+/* 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
+ sequence, and return a pointer to that byte sequence. */
+
+unsigned char *
+encode_terminal_code (src, src_len, coding)
struct glyph *src;
int src_len;
- int *consumed;
+ struct coding_system *coding;
{
- struct glyph *src_start = src, *src_end = src + src_len;
+ struct glyph *src_end = src + src_len;
register GLYPH g;
- register int c;
- Lisp_Object string;
- unsigned char *workbuf, *buf;
- int nchars;
+ unsigned char *buf;
+ int nchars, nbytes, required;
register int tlen = GLYPH_TABLE_LENGTH;
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
- struct coding_system *coding;
- Lisp_Object attrs, charset_list;
+ Lisp_Object charset_list;
-#if 1
- /* GLYPH-TABLE is not supported anymore in xdisp.c. */
- tlen = 0;
-#endif
+ /* 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_src_size < required)
+ {
+ if (encode_terminal_src_size == 0)
+ encode_terminal_src = xmalloc (required);
+ else
+ encode_terminal_src = xrealloc (encode_terminal_src, required);
+ encode_terminal_src_size = required;
+ }
- /* 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 = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
- ? &terminal_coding
- : &safe_terminal_coding);
- coding->destination = terminal_encode_buffer;
- coding->dst_bytes = terminal_encode_buf_size;
- coding->mode |= CODING_MODE_LAST_BLOCK;
- attrs = CODING_ID_ATTRS (coding->id);
- charset_list = CODING_ATTR_CHARSET_LIST (attrs);
+ charset_list = coding_charset_list (coding);
- workbuf = buf = alloca (MAX_MULTIBYTE_LENGTH * src_len);
- for (nchars = 0; src < src_end; src++)
+ 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))
{
- g = GLYPH_FROM_CHAR_GLYPH (src[0]);
+ int c;
+ Lisp_Object string;
+
string = Qnil;
+ g = GLYPH_FROM_CHAR_GLYPH (src[0]);
if (g < 0 || g >= tlen)
- c = src->u.ch;
+ {
+ /* This glyph doesn't has an entry in Vglyph_table. */
+ c = src->u.ch;
+ }
else
{
/* This glyph has an entry in Vglyph_table,
if (NILP (string))
{
- if (! char_charset (c, charset_list, NULL))
+ if (char_charset (c, charset_list, NULL))
{
- /* C is not encodable. */
- int i;
-
- for (i = CHAR_WIDTH (c) - 1; i >= 0; i--, nchars++)
- *buf++ = '?';
+ /* Store the multibyte form of C at BUF. */
+ buf += CHAR_STRING (c, buf);
+ nchars++;
}
else
{
- /* Store the multibyte form of C at BUF. */
- buf += CHAR_STRING (c, buf);
+ /* C is not encodable. */
+ *buf++ = '?';
nchars++;
+ while (src + 1 < src_end && CHAR_GLYPH_PADDING_P (src[1]))
+ {
+ *buf++ = '?';
+ nchars++;
+ src++;
+ }
}
}
else
{
- if (nchars == 0)
+ 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_coding_object (coding, string, 0, 0, SCHARS (string),
- SBYTES (string), Qnil);
- src++;
+ encode_terminal_src_size = nbytes + SBYTES (string);
+ encode_terminal_src = xrealloc (encode_terminal_src,
+ encode_terminal_src_size);
+ buf = encode_terminal_src + nbytes;
}
- break;
+ bcopy (SDATA (string), buf, SBYTES (string));
+ buf += SBYTES (string);
+ nchars += SCHARS (string);
}
}
+ src++;
}
- if (nchars > 0)
+ if (nchars == 0)
{
- coding->source = workbuf;
- encode_coding_object (coding, Qnil, 0, 0, nchars,
- buf - workbuf, Qnil);
+ coding->produced = 0;
+ return NULL;
}
+
+ nbytes = buf - encode_terminal_src;
+ coding->source = encode_terminal_src;
+ if (encode_terminal_dst_size == 0)
+ {
+ 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. */
- terminal_encode_buffer = coding->destination;
- if (terminal_encode_buf_size < coding->dst_bytes)
- terminal_encode_buf_size = coding->dst_bytes;
+ encode_terminal_dst = coding->destination;
+ encode_terminal_dst_size = coding->dst_bytes;
- *consumed = src - src_start;
- return (coding->produced);
+ return (encode_terminal_dst);
}
int produced, consumed;
struct frame *sf = XFRAME (selected_frame);
struct frame *f = updating_frame ? updating_frame : sf;
+ unsigned char *conversion_buffer;
+ struct coding_system *coding;
if (write_glyphs_hook
&& ! FRAME_TERMCAP_P (f))
cmplus (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 = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
+ ? &terminal_coding : &safe_terminal_coding);
/* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
the tail. */
- terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
+ coding->mode &= ~CODING_MODE_LAST_BLOCK;
while (len > 0)
{
highlight_if_desired ();
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)
{
- produced = encode_terminal_code (string, n, &consumed);
- if (produced > 0)
- {
- fwrite (terminal_encode_buffer, 1, produced, stdout);
- if (ferror (stdout))
- clearerr (stdout);
- if (termscript)
- fwrite (terminal_encode_buffer, 1, produced, termscript);
- }
- len -= consumed;
- n -= consumed;
- string += consumed;
+ fwrite (conversion_buffer, 1, coding->produced, stdout);
+ if (ferror (stdout))
+ clearerr (stdout);
+ if (termscript)
+ fwrite (conversion_buffer, 1, coding->produced, termscript);
}
+ len -= n;
+ string += n;
/* Turn appearance modes off. */
turn_off_face (f, face_id);
char *buf;
struct glyph *glyph = NULL;
struct frame *f, *sf;
+ unsigned char *conversion_buffer;
+ unsigned char space[1];
+ struct coding_system *coding;
if (len <= 0)
return;
turn_on_insert ();
cmplus (len);
- /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
- terminal_coding.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 = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
+ ? &terminal_coding : &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;
-
OUTPUT1_IF (TS_ins_char);
if (!start)
{
- terminal_encode_buffer[0] = SPACEGLYPH;
- produced = 1;
+ conversion_buffer = space;
+ coding->produced = 1;
}
else
{
OUTPUT1_IF (TS_ins_char);
start++, len--;
}
- produced = encode_terminal_code (glyph, 1, &consumed);
+
+ if (len <= 0)
+ /* This is the last glyph. */
+ coding->mode |= CODING_MODE_LAST_BLOCK;
+
+ conversion_buffer = encode_terminal_code (glyph, 1, coding);
}
- if (produced > 0)
+ if (coding->produced > 0)
{
- fwrite (terminal_encode_buffer, 1, produced, stdout);
+ fwrite (conversion_buffer, 1, coding->produced, stdout);
if (ferror (stdout))
clearerr (stdout);
if (termscript)
- fwrite (terminal_encode_buffer, 1, produced, termscript);
+ fwrite (conversion_buffer, 1, coding->produced, termscript);
}
OUTPUT1_IF (TS_pad_inserted_char);
{"k6", "f6"},
{"k7", "f7"},
{"k8", "f8"},
- {"k9", "f9"}
+ {"k9", "f9"},
+
+ {"&0", "S-cancel"}, /*shifted cancel key*/
+ {"&9", "S-begin"}, /*shifted begin key*/
+ {"*0", "S-find"}, /*shifted find key*/
+ {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
+ {"*4", "S-delete"}, /*shifted delete-character key*/
+ {"*7", "S-end"}, /*shifted end key*/
+ {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
+ {"#1", "S-help"}, /*shifted help key*/
+ {"#2", "S-home"}, /*shifted home key*/
+ {"#3", "S-insert"}, /*shifted insert-character key*/
+ {"#4", "S-left"}, /*shifted left-arrow key*/
+ {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
+ {"%c", "S-next"}, /*shifted next key*/
+ {"%e", "S-prior"}, /*shifted previous key*/
+ {"%f", "S-print"}, /*shifted print key*/
+ {"%g", "S-redo"}, /*shifted redo key*/
+ {"%i", "S-right"}, /*shifted right-arrow key*/
+ {"!3", "S-undo"} /*shifted undo key*/
};
static char **term_get_fkeys_arg;
&& calc_pixel_width_or_height (&tem, it, prop, 0, 1, &align_to))
{
if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
- align_to = (align_to < 0
+ align_to = (align_to < 0
? 0
: align_to - window_box_left_offset (it->w, TEXT_AREA));
else if (align_to < 0)
enum display_element_type what;
{
struct it temp_it;
+ GLYPH glyph;
temp_it = *it;
temp_it.dp = NULL;
&& INTEGERP (DISP_CONTINUE_GLYPH (it->dp))
&& GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it->dp))))
{
- temp_it.c = FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it->dp)));
- temp_it.len = CHAR_BYTES (temp_it.c);
+ glyph = XINT (DISP_CONTINUE_GLYPH (it->dp));
+ glyph = spec_glyph_lookup_face (XWINDOW (it->window), glyph);
}
else
- temp_it.c = '\\';
-
- produce_glyphs (&temp_it);
- it->pixel_width = temp_it.pixel_width;
- it->nglyphs = temp_it.pixel_width;
+ glyph = '\\';
}
else if (what == IT_TRUNCATION)
{
&& INTEGERP (DISP_TRUNC_GLYPH (it->dp))
&& GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it->dp))))
{
- temp_it.c = FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it->dp)));
- temp_it.len = CHAR_BYTES (temp_it.c);
+ glyph = XINT (DISP_TRUNC_GLYPH (it->dp));
+ glyph = spec_glyph_lookup_face (XWINDOW (it->window), glyph);
}
else
- temp_it.c = '$';
-
- produce_glyphs (&temp_it);
- it->pixel_width = temp_it.pixel_width;
- it->nglyphs = temp_it.pixel_width;
+ glyph = '$';
}
else
abort ();
+
+ temp_it.c = FAST_GLYPH_CHAR (glyph);
+ temp_it.face_id = FAST_GLYPH_FACE (glyph);
+ temp_it.len = CHAR_BYTES (temp_it.c);
+
+ produce_glyphs (&temp_it);
+ it->pixel_width = temp_it.pixel_width;
+ it->nglyphs = temp_it.pixel_width;
}
? (TN_no_color_video & (ATTR)) == 0 \
: 1)
-/* Turn appearances of face FACE_ID on tty frame F on. */
+/* Turn appearances of face FACE_ID on tty frame F on.
+ FACE_ID is a realized face ID number, in the face cache. */
static void
turn_on_face (f, face_id)
if (TN_max_colors > 0)
{
- char *p;
+ char *ts, *p;
- if (fg >= 0 && TS_set_foreground)
+ ts = standout_mode ? TS_set_background : TS_set_foreground;
+ if (fg >= 0 && ts)
{
- p = tparam (TS_set_foreground, NULL, 0, (int) fg);
+ p = tparam (ts, NULL, 0, (int) fg);
OUTPUT (p);
xfree (p);
}
- if (bg >= 0 && TS_set_background)
+ ts = standout_mode ? TS_set_foreground : TS_set_background;
+ if (bg >= 0 && ts)
{
- p = tparam (TS_set_background, NULL, 0, (int) bg);
+ p = tparam (ts, NULL, 0, (int) bg);
OUTPUT (p);
xfree (p);
}
int status;
struct frame *sf = XFRAME (selected_frame);
+ encode_terminal_src_size = 0;
+ encode_terminal_dst_size = 0;
+
#ifdef WINDOWSNT
initialize_w32_display ();
FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
-
- if (! terminal_encode_buffer)
- {
- terminal_encode_buffer = xmalloc (1024);
- if (! terminal_encode_buffer)
- abort ();
- terminal_encode_buf_size = 1024;
- }
#endif /* WINDOWSNT */
xfree (buffer);
exit (1);
}
+DEFUN ("tty-no-underline", Ftty_no_underline, Stty_no_underline, 0, 0, 0,
+ doc: /* Declare that this terminal does not handle underlining.
+This is used to override the terminfo data, for certain terminals that
+do not really do underlining, but say that they do. */)
+ ()
+{
+ TS_enter_underline_mode = 0;
+ return Qnil;
+}
+
void
syms_of_term ()
{
defsubr (&Stty_display_color_p);
defsubr (&Stty_display_color_cells);
+ defsubr (&Stty_no_underline);
}
/* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193