/* terminal control module for terminals described by TERMCAP
- Copyright (C) 1985, 86, 87, 93, 94, 95, 98
+ Copyright (C) 1985, 86, 87, 93, 94, 95, 98, 2000, 2001
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "lisp.h"
#include "charset.h"
#include "coding.h"
+#include "keyboard.h"
#include "frame.h"
#include "disptab.h"
#include "termhooks.h"
-#include "keyboard.h"
#include "dispextern.h"
#include "window.h"
-#ifdef HAVE_TERMCAP_H
+/* For now, don't try to include termcap.h. On some systems,
+ configure finds a non-standard termcap.h that the main build
+ won't find. */
+
+#if defined HAVE_TERMCAP_H && 0
#include <termcap.h>
+#else
+extern void tputs P_ ((const char *, int, int (*)(int)));
+extern int tgetent P_ ((char *, const char *));
+extern int tgetflag P_ ((char *id));
+extern int tgetnum P_ ((char *id));
#endif
#include "cm.h"
#ifdef HAVE_X_WINDOWS
#include "xterm.h"
#endif
+#ifdef macintosh
+#include "macterm.h"
+#endif
static void turn_on_face P_ ((struct frame *, int face_id));
static void turn_off_face P_ ((struct frame *, int face_id));
\f
#ifdef WINDOWSNT
-
/* We aren't X windows, but we aren't termcap either. This makes me
uncertain as to what value to use for frame.output_method. For
this file, we'll define FRAME_TERMCAP_P to be zero so that our
update_end (f)
FRAME_PTR f;
{
- if (! FRAME_TERMCAP_P (updating_frame))
+ if (! FRAME_TERMCAP_P (f))
{
(*update_end_hook) (f);
updating_frame = 0;
}
}
+static void
+toggle_highlight ()
+{
+ if (standout_mode)
+ turn_off_highlight ();
+ else
+ turn_on_highlight ();
+}
+
/* Make cursor invisible. */
else if (chars_wasted && chars_wasted[vpos] == 0)
/* For terminals with standout markers, write one on this line
if there isn't one already. */
- write_standout_marker (highlight, vpos);
+ write_standout_marker (inverse_video ? !highlight : highlight, vpos);
}
/* Call this when about to modify line at position VPOS
struct glyph *src_start = src, *src_end = src + src_len;
unsigned char *dst_start = dst, *dst_end = dst + dst_len;
register GLYPH g;
- unsigned int c;
unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *buf;
int len;
register int tlen = GLYPH_TABLE_LENGTH;
int result;
struct coding_system *coding;
- coding = (CODING_REQUIRE_ENCODING (&terminal_coding)
+ /* 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);
{
len = 1;
buf = " ";
+ coding->src_multibyte = 0;
}
else
{
len = CHAR_STRING (src->u.ch, workbuf);
buf = workbuf;
+ coding->src_multibyte = 1;
}
}
else
workbuf[0] = FAST_GLYPH_CHAR (g);
len = 1;
buf = workbuf;
+ coding->src_multibyte = 0;
}
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]);
}
}
int produced, consumed;
struct frame *sf = XFRAME (selected_frame);
struct frame *f = updating_frame ? updating_frame : sf;
+ unsigned char conversion_buffer[1024];
+ int conversion_buffer_size = sizeof conversion_buffer;
if (write_glyphs_hook
&& ! FRAME_TERMCAP_P (f))
return;
}
- highlight_if_desired ();
turn_off_insert ();
/* Don't dare write in last column of bottom line, if Auto-Wrap,
break;
/* Turn appearance modes of the face of the run on. */
+ highlight_if_desired ();
turn_on_face (f, face_id);
while (n > 0)
{
- /* We use a shared conversion buffer of the current size
- (1024 bytes at least). Usually it is sufficient, but if
- not, we just repeat the loop. */
+ /* 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 (string, conversion_buffer,
n, conversion_buffer_size,
&consumed);
/* Turn appearance modes off. */
turn_off_face (f, face_id);
+ turn_off_highlight ();
}
/* We may have to output some codes to terminate the writing. */
register int len;
{
char *buf;
- struct glyph *glyph;
+ struct glyph *glyph = NULL;
struct frame *f, *sf;
if (len <= 0)
sf = XFRAME (selected_frame);
f = updating_frame ? updating_frame : sf;
- highlight_if_desired ();
if (TS_ins_multi_chars)
{
while (len-- > 0)
{
int produced, consumed;
+ unsigned char conversion_buffer[1024];
+ int conversion_buffer_size = sizeof conversion_buffer;
OUTPUT1_IF (TS_ins_char);
if (!start)
}
else
{
+ highlight_if_desired ();
turn_on_face (f, start->face_id);
glyph = start;
++start;
/* This is the last glyph. */
terminal_coding.mode |= CODING_MODE_LAST_BLOCK;
- /* We use shared conversion buffer of the current size (1024
- bytes at least). It is surely sufficient for just one glyph. */
+ /* The size of conversion buffer (1024 bytes) is surely
+ sufficient for just one glyph. */
produced = encode_terminal_code (glyph, conversion_buffer, 1,
conversion_buffer_size, &consumed);
}
OUTPUT1_IF (TS_pad_inserted_char);
if (start)
- turn_off_face (f, glyph->face_id);
+ {
+ turn_off_face (f, glyph->face_id);
+ turn_off_highlight ();
+ }
}
cmcheckmagic ();
it->pixel_width = it->nglyphs = 0;
else if (it->c == '\t')
{
- int absolute_x = (it->current_x - it->prompt_width
+ int absolute_x = (it->current_x
+ it->continuation_lines_width);
int next_tab_x
= (((1 + absolute_x + it->tab_width - 1)
it->pixel_width = nspaces;
it->nglyphs = nspaces;
}
+ else if (SINGLE_BYTE_CHAR_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. */
+ 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
temp_it.dp = NULL;
temp_it.what = IT_CHARACTER;
temp_it.len = 1;
- temp_it.object = 0;
+ temp_it.object = make_number (0);
bzero (&temp_it.current, sizeof temp_it.current);
if (what == IT_CONTINUATION)
&& 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_LEN (temp_it.c);
+ temp_it.len = CHAR_BYTES (temp_it.c);
}
else
temp_it.c = '\\';
&& 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_LEN (temp_it.c);
+ temp_it.len = CHAR_BYTES (temp_it.c);
}
else
temp_it.c = '$';
int face_id;
{
struct face *face = FACE_FROM_ID (f, face_id);
+ long fg = face->foreground;
+ long bg = face->background;
- xassert (face != NULL);
+ /* Do this first because TS_end_standout_mode may be the same
+ as TS_exit_attribute_mode, which turns all appearances off. */
+ if (MAY_USE_WITH_COLORS_P (NC_REVERSE))
+ {
+ if (TN_max_colors > 0)
+ {
+ if (fg >= 0 && bg >= 0)
+ {
+ /* If the terminal supports colors, we can set them
+ below without using reverse video. The face's fg
+ and bg colors are set as they should appear on
+ the screen, i.e. they take the inverse-video'ness
+ of the face already into account. */
+ }
+ else if (inverse_video)
+ {
+ if (fg == FACE_TTY_DEFAULT_FG_COLOR
+ || bg == FACE_TTY_DEFAULT_BG_COLOR)
+ toggle_highlight ();
+ }
+ else
+ {
+ if (fg == FACE_TTY_DEFAULT_BG_COLOR
+ || bg == FACE_TTY_DEFAULT_FG_COLOR)
+ toggle_highlight ();
+ }
+ }
+ else
+ {
+ /* If we can't display colors, use reverse video
+ if the face specifies that. */
+ if (inverse_video)
+ {
+ if (fg == FACE_TTY_DEFAULT_FG_COLOR
+ || bg == FACE_TTY_DEFAULT_BG_COLOR)
+ toggle_highlight ();
+ }
+ else
+ {
+ if (fg == FACE_TTY_DEFAULT_BG_COLOR
+ || bg == FACE_TTY_DEFAULT_FG_COLOR)
+ toggle_highlight ();
+ }
+ }
+ }
if (face->tty_bold_p)
{
&& MAY_USE_WITH_COLORS_P (NC_UNDERLINE))
OUTPUT1_IF (TS_enter_underline_mode);
- if (MAY_USE_WITH_COLORS_P (NC_REVERSE))
- if (face->tty_reverse_p
- || face->foreground == FACE_TTY_DEFAULT_BG_COLOR
- || face->background == FACE_TTY_DEFAULT_FG_COLOR)
- OUTPUT1_IF (TS_enter_reverse_mode);
-
if (TN_max_colors > 0)
{
char *p;
- if (face->foreground != FACE_TTY_DEFAULT_COLOR
- && face->foreground != FACE_TTY_DEFAULT_FG_COLOR
- && face->foreground != FACE_TTY_DEFAULT_BG_COLOR
- && TS_set_foreground)
+ if (fg >= 0 && TS_set_foreground)
{
- p = tparam (TS_set_foreground, NULL, 0, (int) face->foreground);
+ p = tparam (TS_set_foreground, NULL, 0, (int) fg);
OUTPUT (p);
xfree (p);
}
- if (face->background != FACE_TTY_DEFAULT_COLOR
- && face->background != FACE_TTY_DEFAULT_BG_COLOR
- && face->background != FACE_TTY_DEFAULT_FG_COLOR
- && TS_set_background)
+ if (bg >= 0 && TS_set_background)
{
- p = tparam (TS_set_background, NULL, 0, (int) face->background);
+ p = tparam (TS_set_background, NULL, 0, (int) bg);
OUTPUT (p);
xfree (p);
}
|| face->tty_alt_charset_p
|| face->tty_blinking_p
|| face->tty_underline_p)
- OUTPUT1_IF (TS_exit_attribute_mode);
+ {
+ OUTPUT1_IF (TS_exit_attribute_mode);
+ if (strcmp (TS_exit_attribute_mode, TS_end_standout_mode) == 0)
+ standout_mode = 0;
+ }
if (face->tty_alt_charset_p)
OUTPUT_IF (TS_exit_alt_charset_mode);
TS_clr_to_bottom = tgetstr ("cd", address);
TS_clr_line = tgetstr ("ce", address);
TS_clr_frame = tgetstr ("cl", address);
- ColPosition = tgetstr ("ch", address);
+ ColPosition = NULL; /* tgetstr ("ch", address); */
AbsPosition = tgetstr ("cm", address);
CR = tgetstr ("cr", address);
TS_set_scroll_region = tgetstr ("cs", address);