/* Terminal control module for terminals described by TERMCAP
- Copyright (C) 1985, 86, 87, 93, 94, 95, 98, 2000, 2001
+ Copyright (C) 1985, 86, 87, 93, 94, 95, 98, 2000, 2001, 2002
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#ifdef HAVE_X_WINDOWS
#include "xterm.h"
#endif
-#ifdef macintosh
+#ifdef MAC_OS
#include "macterm.h"
#endif
static void tty_hide_cursor P_ ((void));
#define OUTPUT(a) \
- tputs (a, (int) (FRAME_HEIGHT (XFRAME (selected_frame)) - curY), cmputc)
+ tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) - curY), cmputc)
#define OUTPUT1(a) tputs (a, 1, cmputc)
#define OUTPUTL(a, lines) tputs (a, lines, cmputc)
#define OUTPUT_IF(a) \
do { \
if (a) \
- tputs (a, (int) (FRAME_HEIGHT (XFRAME (selected_frame)) \
+ tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) \
- curY), cmputc); \
} while (0)
-
+
#define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
/* Function to use to ring the bell. */
/* Arrange for all scroll bars on FRAME to be removed at the next call
to `*judge_scroll_bars_hook'. A scroll bar may be spared if
- `*redeem_scroll_bar_hook' is applied to its window before the judgment.
+ `*redeem_scroll_bar_hook' is applied to its window before the judgment.
This should be applied to each frame each time its window tree is
redisplayed, even if it is not displaying scroll bars at the moment;
void (*redeem_scroll_bar_hook) P_ ((struct window *window));
/* Remove all scroll bars on FRAME that haven't been saved since the
- last call to `*condemn_scroll_bars_hook'.
+ last call to `*condemn_scroll_bars_hook'.
This should be applied to each frame after each time its window
tree is redisplayed, even if it is not displaying scroll bars at the
void (*judge_scroll_bars_hook) P_ ((FRAME_PTR FRAME));
-/* Hook to call in estimate_mode_line_height, if any. */
-
-int (* estimate_mode_line_height_hook) P_ ((struct frame *f, enum face_id));
-
-
/* Strings, numbers and flags taken from the termcap entry. */
char *TS_ins_line; /* "al" */
/* The largest frame width in any call to calculate_costs. */
-int max_frame_width;
+int max_frame_cols;
/* The largest frame height in any call to calculate_costs. */
-int max_frame_height;
+int max_frame_lines;
-int costs_set = 0; /* Nonzero if costs have been calculated. */
+static int costs_set; /* Nonzero if costs have been calculated. */
int insert_mode; /* Nonzero when in insert mode. */
int standout_mode; /* Nonzero when in standout mode. */
This is the number of lines, from the top of frame downwards,
which can participate in insert-line/delete-line operations.
- Effectively it excludes the bottom frame_height - specified_window_size
+ Effectively it excludes the bottom frame_lines - specified_window_size
lines from those operations. */
int specified_window;
We don't specbind it, because that would carefully
restore the bad value if there's an error
and make the loop of errors happen anyway. */
-
+
function = Vring_bell_function;
Vring_bell_function = Qnil;
}
else
update_end_hook (f);
-
+
updating_frame = NULL;
}
{
if (FRAME_TERMCAP_P (updating_frame))
{
- specified_window = size ? size : FRAME_HEIGHT (updating_frame);
+ specified_window = size ? size : FRAME_LINES (updating_frame);
if (scroll_region_ok)
set_scroll_region (0, specified_window);
}
{
char *buf;
struct frame *sf = XFRAME (selected_frame);
-
+
if (TS_set_scroll_region)
buf = tparam (TS_set_scroll_region, 0, 0, start, stop - 1);
else if (TS_set_scroll_region_1)
buf = tparam (TS_set_scroll_region_1, 0, 0,
- FRAME_HEIGHT (sf), start,
- FRAME_HEIGHT (sf) - stop,
- FRAME_HEIGHT (sf));
+ FRAME_LINES (sf), start,
+ FRAME_LINES (sf) - stop,
+ FRAME_LINES (sf));
else
- buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_WIDTH (sf));
-
+ buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_COLS (sf));
+
OUTPUT (buf);
xfree (buf);
losecursor ();
int vpos, hpos;
{
struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
-
+
if (! FRAME_TERMCAP_P (f) && cursor_to_hook)
{
(*cursor_to_hook) (vpos, hpos);
}
else
{
- for (i = curY; i < FRAME_HEIGHT (XFRAME (selected_frame)); i++)
+ for (i = curY; i < FRAME_LINES (XFRAME (selected_frame)); i++)
{
cursor_to (i, 0);
- clear_end_of_line (FRAME_WIDTH (XFRAME (selected_frame)));
+ clear_end_of_line (FRAME_COLS (XFRAME (selected_frame)));
}
}
}
clear_frame ()
{
struct frame *sf = XFRAME (selected_frame);
-
+
if (clear_frame_hook
&& ! FRAME_TERMCAP_P ((updating_frame ? updating_frame : sf)))
{
turn_off_insert ();
/* Do not write in last row last col with Auto-wrap on. */
- if (AutoWrap && curY == FRAME_HEIGHT (sf) - 1
- && first_unused_hpos == FRAME_WIDTH (sf))
+ if (AutoWrap && curY == FRAME_LINES (sf) - 1
+ && first_unused_hpos == FRAME_COLS (sf))
first_unused_hpos--;
for (i = curX; i < first_unused_hpos; i++)
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], *buf;
+ unsigned char workbuf[MAX_MULTIBYTE_LENGTH];
+ const unsigned char *buf;
int len;
register int tlen = GLYPH_TABLE_LENGTH;
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
coding->src_multibyte = STRING_MULTIBYTE (tbase[g]);
}
}
-
+
result = encode_coding (coding, buf, dst, len, dst_end - dst);
len -= coding->consumed;
dst += coding->produced;
}
src++;
}
-
+
*consumed = src - src_start;
return (dst - dst_start);
}
since that would scroll the whole frame on some terminals. */
if (AutoWrap
- && curY + 1 == FRAME_HEIGHT (sf)
- && (curX + len) == FRAME_WIDTH (sf))
+ && curY + 1 == FRAME_LINES (sf)
+ && (curX + len) == FRAME_COLS (sf))
len --;
if (len <= 0)
return;
cmplus (len);
-
+
/* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
the tail. */
terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
-
+
while (len > 0)
{
/* Identify a run of glyphs with the same face. */
int face_id = string->face_id;
int n;
-
+
for (n = 1; n < len; ++n)
if (string[n].face_id != face_id)
break;
turn_off_face (f, face_id);
turn_off_highlight ();
}
-
+
/* We may have to output some codes to terminate the writing. */
if (CODING_REQUIRE_FLUSHING (&terminal_coding))
{
termscript);
}
}
-
+
cmcheckmagic ();
}
/* If start is zero, insert blanks instead of a string at start */
-
+
void
insert_glyphs (start, len)
register struct glyph *start;
turn_off_highlight ();
}
}
-
+
cmcheckmagic ();
}
}
sf = XFRAME (selected_frame);
-
+
/* If the lines below the insertion are being pushed
into the end of the window, this is the same as clearing;
and we know the lines are already clear, since the matching
as there will be a matching inslines later that will flush them. */
if (scroll_region_ok && vpos + i >= specified_window)
return;
- if (!memory_below_frame && vpos + i >= FRAME_HEIGHT (sf))
+ if (!memory_below_frame && vpos + i >= FRAME_LINES (sf))
return;
if (multi)
if (!scroll_region_ok && memory_below_frame && n < 0)
{
- cursor_to (FRAME_HEIGHT (sf) + n, 0);
+ cursor_to (FRAME_LINES (sf) + n, 0);
clear_to_end ();
}
}
#ifndef old
/* char_ins_del_cost[n] is cost of inserting N characters.
char_ins_del_cost[-n] is cost of deleting N characters.
- The length of this vector is based on max_frame_width. */
+ The length of this vector is based on max_frame_cols. */
int *char_ins_del_vector;
-#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))])
+#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
#endif
/* ARGSUSED */
/* Delete costs are at negative offsets */
p = &char_ins_del_cost (frame)[0];
- for (i = FRAME_WIDTH (frame); --i >= 0;)
+ for (i = FRAME_COLS (frame); --i >= 0;)
*--p = (del_startup_cost += del_cost_per_char);
/* Doing nothing is free */
*p++ = 0;
/* Insert costs are at positive offsets */
- for (i = FRAME_WIDTH (frame); --i >= 0;)
+ for (i = FRAME_COLS (frame); --i >= 0;)
*p++ = (ins_startup_cost += ins_cost_per_char);
}
char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
X turns off char_ins_del_ok. */
- max_frame_height = max (max_frame_height, FRAME_HEIGHT (frame));
- max_frame_width = max (max_frame_width, FRAME_WIDTH (frame));
+ max_frame_lines = max (max_frame_lines, FRAME_LINES (frame));
+ max_frame_cols = max (max_frame_cols, FRAME_COLS (frame));
costs_set = 1;
char_ins_del_vector
= (int *) xrealloc (char_ins_del_vector,
(sizeof (int)
- + 2 * max_frame_width * sizeof (int)));
+ + 2 * max_frame_cols * sizeof (int)));
else
char_ins_del_vector
= (int *) xmalloc (sizeof (int)
- + 2 * max_frame_width * sizeof (int));
+ + 2 * max_frame_cols * sizeof (int));
bzero (char_ins_del_vector, (sizeof (int)
- + 2 * max_frame_width * sizeof (int)));
+ + 2 * max_frame_cols * sizeof (int)));
if (f && (!TS_ins_line && !TS_del_line))
do_line_insertion_deletion_costs (frame,
if (TS_repeat && per_line_cost (TS_repeat) * baud_rate < 9000)
RPov = string_cost (TS_repeat);
else
- RPov = FRAME_WIDTH (frame) * 2;
+ RPov = FRAME_COLS (frame) * 2;
cmcostinit (); /* set up cursor motion costs */
}
static Lisp_Object term_get_fkeys_1 ();
/* Find the escape codes sent by the function keys for Vfunction_key_map.
- This function scans the termcap function key sequence entries, and
+ This function scans the termcap function key sequence entries, and
adds entries to Vfunction_key_map for each function key it finds. */
void
Fmake_vector (make_number (1), \
intern (sym))); \
}
-
+
/* if there's no key_next keycap, map key_npage to `next' keysym */
CONDITIONAL_REASSIGN ("%5", "kN", "next");
/* if there's no key_prev keycap, map key_ppage to `previous' keysym */
for which to produce glyphs; IT->face_id contains the character's
face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1. */
-
+
static void
append_glyph (it)
struct it *it;
+ it->glyph_row->used[it->area]);
end = it->glyph_row->glyphs[1 + it->area];
- for (i = 0;
- i < it->pixel_width && glyph < end;
+ for (i = 0;
+ i < it->pixel_width && glyph < end;
++i)
{
glyph->type = CHAR_GLYPH;
glyph->padding_p = i > 0;
glyph->charpos = CHARPOS (it->position);
glyph->object = it->object;
-
+
++it->glyph_row->used[it->area];
++glyph;
}
Callers usually don't call produce_glyphs directly;
instead they use the macro PRODUCE_GLYPHS. */
-void
+void
produce_glyphs (it)
struct it *it;
{
|| it->what == IT_COMPOSITION
|| it->what == IT_IMAGE
|| it->what == IT_STRETCH);
-
+
/* Nothing but characters are supported on terminal frames. For a
composition sequence, it->c is the first character of the
sequence. */
{
int absolute_x = (it->current_x
+ it->continuation_lines_width);
- int next_tab_x
- = (((1 + absolute_x + it->tab_width - 1)
+ int next_tab_x
+ = (((1 + absolute_x + it->tab_width - 1)
/ it->tab_width)
* it->tab_width);
int nspaces;
continued line. So, we will get the right number of spaces
here. */
nspaces = next_tab_x - absolute_x;
-
+
if (it->glyph_row)
{
int n = nspaces;
-
+
it->c = ' ';
it->pixel_width = it->len = 1;
-
+
while (n--)
append_glyph (it);
-
+
it->c = '\t';
}
it->pixel_width = CHARSET_WIDTH (charset);
it->nglyphs = it->pixel_width;
-
+
if (it->glyph_row)
append_glyph (it);
}
- /* Advance current_x by the pixel width as a convenience for
+ /* Advance current_x by the pixel width as a convenience for
the caller. */
if (it->area == TEXT_AREA)
it->current_x += it->pixel_width;
enum display_element_type what;
{
struct it temp_it;
-
+
temp_it = *it;
temp_it.dp = NULL;
temp_it.what = IT_CHARACTER;
}
else
temp_it.c = '\\';
-
+
produce_glyphs (&temp_it);
it->pixel_width = temp_it.pixel_width;
it->nglyphs = temp_it.pixel_width;
}
else
temp_it.c = '$';
-
+
produce_glyphs (&temp_it);
it->pixel_width = temp_it.pixel_width;
it->nglyphs = temp_it.pixel_width;
}
-/* Return an estimation of the pixel height of mode or top lines on
- frame F. FACE_ID specifies what line's height to estimate. */
-
-int
-estimate_mode_line_height (f, face_id)
- struct frame *f;
- enum face_id face_id;
-{
- if (estimate_mode_line_height_hook)
- return estimate_mode_line_height_hook (f, face_id);
- else
- return 1;
-}
-
-
\f
/***********************************************************************
Faces
if (TN_max_colors > 0)
{
char *p;
-
+
if (fg >= 0 && TS_set_foreground)
{
p = tparam (TS_set_foreground, NULL, 0, (int) fg);
}
}
}
-
+
/* Turn off appearances of face FACE_ID on tty frame F. */
&& face->background != FACE_TTY_DEFAULT_BG_COLOR)))
OUTPUT1_IF (TS_orig_pair);
}
-
-
+
+
+/* Return non-zero if the terminal on frame F supports all of the
+ capabilities in CAPS simultaneously, with foreground and background
+ colors FG and BG. */
+
+int
+tty_capable_p (f, caps, fg, bg)
+ struct frame *f;
+ unsigned caps;
+ unsigned long fg, bg;
+{
+#define TTY_CAPABLE_P_TRY(cap, TS, NC_bit) \
+ if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(NC_bit))) \
+ return 0;
+
+ TTY_CAPABLE_P_TRY (TTY_CAP_INVERSE, TS_standout_mode, NC_REVERSE);
+ TTY_CAPABLE_P_TRY (TTY_CAP_UNDERLINE, TS_enter_underline_mode, NC_UNDERLINE);
+ TTY_CAPABLE_P_TRY (TTY_CAP_BOLD, TS_enter_bold_mode, NC_BOLD);
+ TTY_CAPABLE_P_TRY (TTY_CAP_DIM, TS_enter_dim_mode, NC_DIM);
+ TTY_CAPABLE_P_TRY (TTY_CAP_BLINK, TS_enter_blink_mode, NC_BLINK);
+ TTY_CAPABLE_P_TRY (TTY_CAP_ALT_CHARSET, TS_enter_alt_charset_mode, NC_ALT_CHARSET);
+
+ /* We can do it! */
+ return 1;
+}
+
+
/* Return non-zero if the terminal is capable to display colors. */
DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p,
tty_setup_colors (mode)
int mode;
{
+ /* Canonicalize all negative values of MODE. */
+ if (mode < -1)
+ mode = -1;
+
switch (mode)
{
case -1: /* no colors at all */
tty_color_mode_alist = Fintern_soft (build_string ("tty-color-mode-alist"),
Qnil);
- if (NATNUMP (val))
+ if (INTEGERP (val))
color_mode = val;
else
{
current_mode = XCDR (current_mode_spec);
else
current_mode = Qnil;
- if (NATNUMP (color_mode))
+ if (INTEGERP (color_mode))
mode = XINT (color_mode);
else
mode = 0; /* meaning default */
- if (NATNUMP (current_mode))
+ if (INTEGERP (current_mode))
old_mode = XINT (current_mode);
else
old_mode = 0;
{
char *area;
char **address = &area;
- char buffer[2044];
+ char *buffer = NULL;
+ int buffer_size = 4096;
register char *p;
int status;
struct frame *sf = XFRAME (selected_frame);
area = (char *) xmalloc (2044);
- if (area == 0)
- abort ();
-
- FrameRows = FRAME_HEIGHT (sf);
- FrameCols = FRAME_WIDTH (sf);
- specified_window = FRAME_HEIGHT (sf);
+ FrameRows = FRAME_LINES (sf);
+ FrameCols = FRAME_COLS (sf);
+ specified_window = FRAME_LINES (sf);
delete_in_insert_mode = 1;
Wcm_clear ();
+ buffer = (char *) xmalloc (buffer_size);
status = tgetent (buffer, terminal_type);
if (status < 0)
{
terminal_type);
#endif
}
-#ifdef TERMINFO
- area = (char *) xmalloc (2044);
-#else
- area = (char *) xmalloc (strlen (buffer));
-#endif /* not TERMINFO */
- if (area == 0)
+
+#ifndef TERMINFO
+ if (strlen (buffer) >= buffer_size)
abort ();
+ buffer_size = strlen (buffer);
+#endif
+ area = (char *) xmalloc (buffer_size);
TS_ins_line = tgetstr ("al", address);
TS_ins_multi_lines = tgetstr ("AL", address);
TS_cursor_visible = tgetstr ("vs", address);
TS_cursor_invisible = tgetstr ("vi", address);
TS_set_window = tgetstr ("wi", address);
-
+
TS_enter_underline_mode = tgetstr ("us", address);
TS_exit_underline_mode = tgetstr ("ue", address);
TS_enter_bold_mode = tgetstr ("md", address);
TS_enter_alt_charset_mode = tgetstr ("as", address);
TS_exit_alt_charset_mode = tgetstr ("ae", address);
TS_exit_attribute_mode = tgetstr ("me", address);
-
+
MultiUp = tgetstr ("UP", address);
MultiDown = tgetstr ("DO", address);
MultiLeft = tgetstr ("LE", address);
TS_set_foreground = tgetstr ("Sf", address);
TS_set_background = tgetstr ("Sb", address);
}
-
+
TN_max_colors = tgetnum ("Co");
TN_max_pairs = tgetnum ("pa");
-
+
TN_no_color_video = tgetnum ("NC");
if (TN_no_color_video == -1)
TN_no_color_video = 0;
{
int height, width;
get_frame_size (&width, &height);
- FRAME_WIDTH (sf) = width;
- FRAME_HEIGHT (sf) = height;
+ FRAME_COLS (sf) = width;
+ FRAME_LINES (sf) = height;
}
- if (FRAME_WIDTH (sf) <= 0)
- SET_FRAME_WIDTH (sf, tgetnum ("co"));
+ if (FRAME_COLS (sf) <= 0)
+ SET_FRAME_COLS (sf, tgetnum ("co"));
else
/* Keep width and external_width consistent */
- SET_FRAME_WIDTH (sf, FRAME_WIDTH (sf));
- if (FRAME_HEIGHT (sf) <= 0)
- FRAME_HEIGHT (sf) = tgetnum ("li");
-
- if (FRAME_HEIGHT (sf) < 3 || FRAME_WIDTH (sf) < 3)
+ SET_FRAME_COLS (sf, FRAME_COLS (sf));
+ if (FRAME_LINES (sf) <= 0)
+ FRAME_LINES (sf) = tgetnum ("li");
+
+ if (FRAME_LINES (sf) < 3 || FRAME_COLS (sf) < 3)
fatal ("Screen size %dx%d is too small",
- FRAME_HEIGHT (sf), FRAME_WIDTH (sf));
+ FRAME_LINES (sf), FRAME_COLS (sf));
min_padding_speed = tgetnum ("pb");
TabWidth = tgetnum ("tw");
if (TabWidth < 0)
TabWidth = 8;
-
+
/* Turned off since /etc/termcap seems to have :ta= for most terminals
and newer termcap doc does not seem to say there is a default.
if (!Wcm.cm_tab)
}
}
- FrameRows = FRAME_HEIGHT (sf);
- FrameCols = FRAME_WIDTH (sf);
- specified_window = FRAME_HEIGHT (sf);
+ FrameRows = FRAME_LINES (sf);
+ FrameCols = FRAME_COLS (sf);
+ specified_window = FRAME_LINES (sf);
if (Wcm_init () == -1) /* can't do cursor motion */
#ifdef VMS
terminal_type);
# endif /* TERMINFO */
#endif /*VMS */
- if (FRAME_HEIGHT (sf) <= 0
- || FRAME_WIDTH (sf) <= 0)
+ if (FRAME_LINES (sf) <= 0
+ || FRAME_COLS (sf) <= 0)
fatal ("The frame size has not been specified");
delete_in_insert_mode
FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
#endif /* WINDOWSNT */
+
+ xfree (buffer);
}
/* VARARGS 1 */
defsubr (&Stty_display_color_cells);
}
+/* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
+ (do not change this comment) */