/* Terminal control module for terminals described by TERMCAP
- Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2011
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <config.h>
#include <stdio.h>
#include <ctype.h>
-#include <string.h>
#include <errno.h>
#include <sys/file.h>
-
-#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#endif
-
-#if HAVE_TERMIOS_H
-#include <termios.h> /* For TIOCNOTTY. */
-#endif
-
#include <signal.h>
#include <stdarg.h>
+#include <setjmp.h>
#include "lisp.h"
#include "termchar.h"
#include "syssignal.h"
#include "systty.h"
#include "intervals.h"
+#ifdef MSDOS
+#include "msdos.h"
+static int been_here = -1;
+#endif
/* 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. */
+extern void tputs (const char *, int, int (*)(int));
+extern int tgetent (char *, const char *);
+extern int tgetflag (char *id);
+extern int tgetnum (char *id);
-#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
+char *tparam (char *, char *, int, int, ...);
+
+extern char *tgetstr (char *, char **);
#include "cm.h"
#ifdef HAVE_X_WINDOWS
#include "xterm.h"
#endif
-#ifdef MAC_OS
-#include "macterm.h"
-#endif
#ifndef O_RDWR
#define O_RDWR 2
#define DEV_TTY "/dev/tty"
#endif
-static void tty_set_scroll_region P_ ((struct frame *f, int start, int stop));
-static void turn_on_face P_ ((struct frame *, int face_id));
-static void turn_off_face P_ ((struct frame *, int face_id));
-static void tty_show_cursor P_ ((struct tty_display_info *));
-static void tty_hide_cursor P_ ((struct tty_display_info *));
-static void tty_background_highlight P_ ((struct tty_display_info *tty));
-static void clear_tty_hooks P_ ((struct terminal *terminal));
-static void set_tty_hooks P_ ((struct terminal *terminal));
-static void dissociate_if_controlling_tty P_ ((int fd));
-static void delete_tty P_ ((struct terminal *));
+static void tty_set_scroll_region (struct frame *f, int start, int stop);
+static void turn_on_face (struct frame *, int face_id);
+static void turn_off_face (struct frame *, int face_id);
+static void tty_show_cursor (struct tty_display_info *);
+static void tty_hide_cursor (struct tty_display_info *);
+static void tty_background_highlight (struct tty_display_info *tty);
+static void clear_tty_hooks (struct terminal *terminal);
+static void set_tty_hooks (struct terminal *terminal);
+static void dissociate_if_controlling_tty (int fd);
+static void delete_tty (struct terminal *);
+static void maybe_fatal (int must_succeed, struct terminal *terminal,
+ const char *str1, const char *str2, ...) NO_RETURN;
+static void vfatal (const char *str, va_list ap) NO_RETURN;
+
#define OUTPUT(tty, a) \
emacs_tputs ((tty), a, \
#define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
-/* If true, use "vs", otherwise use "ve" to make the cursor visible. */
-
-static int visible_cursor;
-
/* Display space properties */
-extern Lisp_Object Qspace, QCalign_to, QCwidth;
-
-/* Functions to call after suspending a tty. */
-Lisp_Object Vsuspend_tty_functions;
-
-/* Functions to call after resuming a tty. */
-Lisp_Object Vresume_tty_functions;
-
/* Chain of all tty device parameters. */
struct tty_display_info *tty_list;
-/* Nonzero means no need to redraw the entire frame on resuming a
- suspended Emacs. This is useful on terminals with multiple
- pages, where one page is used for Emacs and another for all
- else. */
-int no_redraw_on_reenter;
-
/* Meaning of bits in no_color_video. Each bit set means that the
corresponding attribute cannot be combined with colors. */
should not open a frame on stdout. */
static int no_controlling_tty;
-/* Provided for lisp packages. */
-
-static int system_uses_terminfo;
-
-char *tparam ();
-
-extern char *tgetstr ();
\f
#ifdef HAVE_GPM
#include <sys/fcntl.h>
-static void term_clear_mouse_face ();
-static void term_mouse_highlight (struct frame *f, int x, int y);
-
/* The device for which we have enabled gpm support (or NULL). */
struct tty_display_info *gpm_tty = NULL;
-/* These variables describe the range of text currently shown in its
- mouse-face, together with the window they apply to. As long as
- the mouse stays within this range, we need not redraw anything on
- its account. Rows and columns are glyph matrix positions in
- MOUSE_FACE_WINDOW. */
-static int mouse_face_beg_row, mouse_face_beg_col;
-static int mouse_face_end_row, mouse_face_end_col;
-static int mouse_face_past_end;
-static Lisp_Object mouse_face_window;
-static int mouse_face_face_id;
-
-static int pos_x, pos_y;
+/* Last recorded mouse coordinates. */
static int last_mouse_x, last_mouse_y;
#endif /* HAVE_GPM */
cmputc ('\n');
}
- OUTPUT_IF (tty, tty->TS_termcap_modes);
OUTPUT_IF (tty, visible_cursor ? tty->TS_cursor_visible : tty->TS_cursor_normal);
OUTPUT_IF (tty, tty->TS_keypad_mode);
losecursor (tty);
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;
+encode_terminal_code (struct glyph *src, int src_len, struct coding_system *coding)
{
struct glyph *src_end = src + src_len;
unsigned char *buf;
required = MAX_MULTIBYTE_LENGTH * src_len;
if (encode_terminal_src_size < required)
{
- if (encode_terminal_src_size == 0)
- encode_terminal_src = xmalloc (required);
- else
+ if (encode_terminal_src)
encode_terminal_src = xrealloc (encode_terminal_src, required);
+ else
+ encode_terminal_src = xmalloc (required);
encode_terminal_src_size = required;
}
{
if (src->type == COMPOSITE_GLYPH)
{
- struct composition *cmp = composition_table[src->u.cmp_id];
+ struct composition *cmp;
+ Lisp_Object gstring;
int i;
nbytes = buf - encode_terminal_src;
- required = MAX_MULTIBYTE_LENGTH * cmp->glyph_len;
+ if (src->u.cmp.automatic)
+ {
+ gstring = composition_gstring_from_id (src->u.cmp.id);
+ required = src->slice.cmp.to + 1 - src->slice.cmp.from;
+ }
+ else
+ {
+ cmp = composition_table[src->u.cmp.id];
+ required = MAX_MULTIBYTE_LENGTH * cmp->glyph_len;
+ }
if (encode_terminal_src_size < nbytes + required)
{
buf = encode_terminal_src + nbytes;
}
- for (i = 0; i < cmp->glyph_len; i++)
- {
- int c = COMPOSITION_GLYPH (cmp, i);
+ if (src->u.cmp.automatic)
+ for (i = src->slice.cmp.from; i <= src->slice.cmp.to; i++)
+ {
+ Lisp_Object g = LGSTRING_GLYPH (gstring, i);
+ int c = LGLYPH_CHAR (g);
- if (! char_charset (c, charset_list, NULL))
- break;
- buf += CHAR_STRING (c, buf);
- nchars++;
- }
- if (i == 0)
- {
- /* The first character of the composition is not encodable. */
- *buf++ = '?';
- nchars++;
- }
+ if (! char_charset (c, charset_list, NULL))
+ c = '?';
+ buf += CHAR_STRING (c, buf);
+ nchars++;
+ }
+ else
+ for (i = 0; i < cmp->glyph_len; i++)
+ {
+ int c = COMPOSITION_GLYPH (cmp, i);
+
+ if (c == '\t')
+ continue;
+ if (char_charset (c, charset_list, NULL))
+ {
+ if (CHAR_WIDTH (c) == 0
+ && i > 0 && COMPOSITION_GLYPH (cmp, i - 1) == '\t')
+ /* Should be left-padded */
+ {
+ buf += CHAR_STRING (' ', buf);
+ nchars++;
+ }
+ }
+ else
+ c = '?';
+ buf += CHAR_STRING (c, buf);
+ nchars++;
+ }
}
/* We must skip glyphs to be padded for a wide character. */
else if (! CHAR_GLYPH_PADDING_P (*src))
if (GLYPH_INVALID_P (g) || GLYPH_SIMPLE_P (tbase, tlen, g))
{
- /* This glyph doesn't has an entry in Vglyph_table. */
+ /* This glyph doesn't have an entry in Vglyph_table. */
c = src->u.ch;
}
else
encode_terminal_src_size);
buf = encode_terminal_src + nbytes;
}
- if (char_charset (c, charset_list, NULL))
+ if (CHAR_BYTE8_P (c)
+ || char_charset (c, charset_list, NULL))
{
/* Store the multibyte form of C at BUF. */
buf += CHAR_STRING (c, buf);
}
else
{
- unsigned char *p = SDATA (string), *pend = p + SBYTES (string);
+ unsigned char *p = SDATA (string);
if (! STRING_MULTIBYTE (string))
string = string_to_multibyte (string);
encode_terminal_src_size);
buf = encode_terminal_src + nbytes;
}
- bcopy (SDATA (string), buf, SBYTES (string));
+ memcpy (buf, SDATA (string), SBYTES (string));
buf += SBYTES (string);
nchars += SCHARS (string);
}
if (encode_terminal_dst_size == 0)
{
encode_terminal_dst_size = encode_terminal_src_size;
- encode_terminal_dst = xmalloc (encode_terminal_dst_size);
+ if (encode_terminal_dst)
+ encode_terminal_dst = xrealloc (encode_terminal_dst,
+ encode_terminal_dst_size);
+ else
+ encode_terminal_dst = xmalloc (encode_terminal_dst_size);
}
coding->destination = encode_terminal_dst;
coding->dst_bytes = encode_terminal_dst_size;
#ifdef HAVE_GPM /* Only used by GPM code. */
static void
-tty_write_glyphs_with_face (f, string, len, face_id)
- register struct frame *f;
- register struct glyph *string;
- register int len, face_id;
+tty_write_glyphs_with_face (register struct frame *f, register struct glyph *string,
+ register int len, register int face_id)
{
unsigned char *conversion_buffer;
struct coding_system *coding;
not counting any line-dependent padding. */
int
-string_cost (char *str)
+string_cost (const char *str)
{
cost = 0;
if (str)
counting any line-dependent padding at one line. */
static int
-string_cost_one_line (char *str)
+string_cost_one_line (const char *str)
{
cost = 0;
if (str)
in tenths of characters. */
int
-per_line_cost (char *str)
+per_line_cost (const char *str)
{
cost = 0;
if (str)
return cost;
}
-#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_cols. */
int *char_ins_del_vector;
#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
-#endif
/* ARGSUSED */
static void
= (int *) xmalloc (sizeof (int)
+ 2 * max_frame_cols * sizeof (int));
- bzero (char_ins_del_vector, (sizeof (int)
- + 2 * max_frame_cols * sizeof (int)));
+ memset (char_ins_del_vector, 0,
+ (sizeof (int) + 2 * max_frame_cols * sizeof (int)));
if (f && (!tty->TS_ins_line && !tty->TS_del_line))
other keys (as on the IBM PC keyboard) they get overridden.
*/
-static struct fkey_table keys[] =
+static const struct fkey_table keys[] =
{
{"kh", "home"}, /* termcap */
{"kl", "left"}, /* termcap */
{"!3", "S-undo"} /*shifted undo key*/
};
+#ifndef DOS_NT
static char **term_get_fkeys_address;
static KBOARD *term_get_fkeys_kboard;
-static Lisp_Object term_get_fkeys_1 ();
+static Lisp_Object term_get_fkeys_1 (void);
/* Find the escape codes sent by the function keys for Vinput_decode_map.
This function scans the termcap function key sequence entries, and
adds entries to Vinput_decode_map for each function key it finds. */
static void
-term_get_fkeys (address, kboard)
- char **address;
- KBOARD *kboard;
+term_get_fkeys (char **address, KBOARD *kboard)
{
/* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
errors during the call. The only errors should be from Fdefine_key
function key specification, rather than giving the user an error and
refusing to run at all on such a terminal. */
- extern Lisp_Object Fidentity ();
term_get_fkeys_address = address;
term_get_fkeys_kboard = kboard;
internal_condition_case (term_get_fkeys_1, Qerror, Fidentity);
}
static Lisp_Object
-term_get_fkeys_1 ()
+term_get_fkeys_1 (void)
{
int i;
return Qnil;
}
+#endif /* not DOS_NT */
\f
/***********************************************************************
Character Display Information
***********************************************************************/
-
-/* Avoid name clash with functions defined in xterm.c */
-#ifdef static
-#define append_glyph append_glyph_term
-#define produce_stretch_glyph produce_stretch_glyph_term
-#define append_composite_glyph append_composite_glyph_term
-#define produce_composite_glyph produce_composite_glyph_term
-#endif
-
-static void append_glyph P_ ((struct it *));
-static void produce_stretch_glyph P_ ((struct it *));
-static void append_composite_glyph P_ ((struct it *));
-static void produce_composite_glyph P_ ((struct it *));
+static void append_glyph (struct it *);
+static void produce_stretch_glyph (struct it *);
+static void append_composite_glyph (struct it *);
+static void produce_composite_glyph (struct it *);
+static void append_glyphless_glyph (struct it *, int, char *);
+static void produce_glyphless_glyph (struct it *, int, Lisp_Object);
/* Append glyphs to IT's glyph_row. Called from produce_glyphs for
terminal frames if IT->glyph_row != NULL. IT->char_to_display is
IT->pixel_width > 1. */
static void
-append_glyph (it)
- struct it *it;
+append_glyph (struct it *it)
{
struct glyph *glyph, *end;
int i;
+ it->glyph_row->used[it->area]);
end = it->glyph_row->glyphs[1 + it->area];
+ /* If the glyph row is reversed, we need to prepend the glyph rather
+ than append it. */
+ if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
+ {
+ struct glyph *g;
+ int move_by = it->pixel_width;
+
+ /* Make room for the new glyphs. */
+ if (move_by > end - glyph) /* don't overstep end of this area */
+ move_by = end - glyph;
+ for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
+ g[move_by] = *g;
+ glyph = it->glyph_row->glyphs[it->area];
+ end = glyph + move_by;
+ }
+
+ /* BIDI Note: we put the glyphs of a "multi-pixel" character left to
+ right, even in the REVERSED_P case, since (a) all of its u.ch are
+ identical, and (b) the PADDING_P flag needs to be set for the
+ leftmost one, because we write to the terminal left-to-right. */
for (i = 0;
i < it->pixel_width && glyph < end;
++i)
glyph->padding_p = i > 0;
glyph->charpos = CHARPOS (it->position);
glyph->object = it->object;
+ if (it->bidi_p)
+ {
+ glyph->resolved_level = it->bidi_it.resolved_level;
+ if ((it->bidi_it.type & 7) != it->bidi_it.type)
+ abort ();
+ glyph->bidi_type = it->bidi_it.type;
+ }
+ else
+ {
+ glyph->resolved_level = 0;
+ glyph->bidi_type = UNKNOWN_BT;
+ }
++it->glyph_row->used[it->area];
++glyph;
}
}
-
/* Produce glyphs for the display element described by IT. *IT
specifies what we want to produce a glyph for (character, image, ...),
and where in the glyph matrix we currently are (glyph row and hpos).
produce_glyphs fills in output fields of *IT with information such as the
pixel width and height of a character, and maybe output actual glyphs at
- the same time if IT->glyph_row is non-null. See the explanation of
- struct display_iterator in dispextern.h for an overview.
+ the same time if IT->glyph_row is non-null. For an overview, see
+ the explanation in dispextern.h, before the definition of the
+ display_element_type enumeration.
produce_glyphs also stores the result of glyph width, ascent
etc. computations in *IT.
instead they use the macro PRODUCE_GLYPHS. */
void
-produce_glyphs (it)
- struct it *it;
+produce_glyphs (struct it *it)
{
/* If a hook is installed, let it do the work. */
goto done;
}
- /* Maybe translate single-byte characters to multibyte. */
- it->char_to_display = it->c;
+ if (it->what == IT_GLYPHLESS)
+ {
+ produce_glyphless_glyph (it, 0, Qnil);
+ goto done;
+ }
- if (it->c >= 040 && it->c < 0177)
+ if (it->char_to_display >= 040 && it->char_to_display < 0177)
{
it->pixel_width = it->nglyphs = 1;
if (it->glyph_row)
append_glyph (it);
}
- else if (it->c == '\n')
+ else if (it->char_to_display == '\n')
it->pixel_width = it->nglyphs = 0;
- else if (it->c == '\t')
+ else if (it->char_to_display == '\t')
{
int absolute_x = (it->current_x
+ it->continuation_lines_width);
it->pixel_width = nspaces;
it->nglyphs = nspaces;
}
- else if (CHAR_BYTE8_P (it->c))
+ else if (CHAR_BYTE8_P (it->char_to_display))
+ {
+ /* Coming here means that 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
{
- if (unibyte_display_via_language_environment
- && (it->c >= 0240))
+ Lisp_Object charset_list = FRAME_TERMINAL (it->f)->charset_list;
+
+ if (char_charset (it->char_to_display, charset_list, NULL))
{
- it->char_to_display = unibyte_char_to_multibyte (it->c);
it->pixel_width = CHAR_WIDTH (it->char_to_display);
it->nglyphs = it->pixel_width;
if (it->glyph_row)
}
else
{
- /* Coming here means that it->c is from display table, thus
- 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
- {
- it->pixel_width = CHAR_WIDTH (it->c);
- it->nglyphs = it->pixel_width;
+ Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
- if (it->glyph_row)
- append_glyph (it);
+ xassert (it->what == IT_GLYPHLESS);
+ produce_glyphless_glyph (it, 1, acronym);
+ }
}
done:
to reach HPOS, a value in canonical character units. */
static void
-produce_stretch_glyph (it)
- struct it *it;
+produce_stretch_glyph (struct it *it)
{
/* (space :width WIDTH ...) */
Lisp_Object prop, plist;
if (width <= 0 && (width < 0 || !zero_width_ok_p))
width = 1;
+ if (width > 0 && it->line_wrap != TRUNCATE
+ && it->current_x + width > it->last_visible_x)
+ width = it->last_visible_x - it->current_x - 1;
+
if (width > 0 && it->glyph_row)
{
Lisp_Object o_object = it->object;
face. */
static void
-append_composite_glyph (it)
- struct it *it;
+append_composite_glyph (struct it *it)
{
struct glyph *glyph;
glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area];
if (glyph < it->glyph_row->glyphs[1 + it->area])
{
+ /* If the glyph row is reversed, we need to prepend the glyph
+ rather than append it. */
+ if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
+ {
+ struct glyph *g;
+
+ /* Make room for the new glyph. */
+ for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
+ g[1] = *g;
+ glyph = it->glyph_row->glyphs[it->area];
+ }
glyph->type = COMPOSITE_GLYPH;
glyph->pixel_width = it->pixel_width;
- glyph->u.cmp_id = it->cmp_id;
+ glyph->u.cmp.id = it->cmp_it.id;
+ if (it->cmp_it.ch < 0)
+ {
+ glyph->u.cmp.automatic = 0;
+ glyph->u.cmp.id = it->cmp_it.id;
+ }
+ else
+ {
+ glyph->u.cmp.automatic = 1;
+ glyph->u.cmp.id = it->cmp_it.id;
+ glyph->slice.cmp.from = it->cmp_it.from;
+ glyph->slice.cmp.to = it->cmp_it.to - 1;
+ }
+
glyph->face_id = it->face_id;
glyph->padding_p = 0;
glyph->charpos = CHARPOS (it->position);
glyph->object = it->object;
+ if (it->bidi_p)
+ {
+ glyph->resolved_level = it->bidi_it.resolved_level;
+ if ((it->bidi_it.type & 7) != it->bidi_it.type)
+ abort ();
+ glyph->bidi_type = it->bidi_it.type;
+ }
+ else
+ {
+ glyph->resolved_level = 0;
+ glyph->bidi_type = UNKNOWN_BT;
+ }
++it->glyph_row->used[it->area];
++glyph;
/* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
the composition. We simply produces components of the composition
- assuming that that the terminal has a capability to layout/render
- it correctly. */
+ assuming that the terminal has a capability to layout/render it
+ correctly. */
static void
-produce_composite_glyph (it)
- struct it *it;
+produce_composite_glyph (struct it *it)
{
- struct composition *cmp = composition_table[it->cmp_id];
- int c;
+ if (it->cmp_it.ch < 0)
+ {
+ struct composition *cmp = composition_table[it->cmp_it.id];
- xassert (cmp->glyph_len > 0);
- c = COMPOSITION_GLYPH (cmp, 0);
- it->pixel_width = CHAR_WIDTH (it->c);
- it->nglyphs = 1;
+ it->pixel_width = cmp->width;
+ }
+ else
+ {
+ Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
+ it->pixel_width = composition_gstring_width (gstring, it->cmp_it.from,
+ it->cmp_it.to, NULL);
+ }
+ it->nglyphs = 1;
if (it->glyph_row)
append_composite_glyph (it);
}
+/* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
+ is a face ID to be used for the glyph. What is actually appended
+ are glyphs of type CHAR_GLYPH whose characters are in STR (which
+ comes from it->nglyphs bytes). */
+
+static void
+append_glyphless_glyph (struct it *it, int face_id, char *str)
+{
+ struct glyph *glyph, *end;
+ int i;
+
+ xassert (it->glyph_row);
+ glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area];
+ end = it->glyph_row->glyphs[1 + it->area];
+
+ /* If the glyph row is reversed, we need to prepend the glyph rather
+ than append it. */
+ if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
+ {
+ struct glyph *g;
+ int move_by = it->pixel_width;
+
+ /* Make room for the new glyphs. */
+ if (move_by > end - glyph) /* don't overstep end of this area */
+ move_by = end - glyph;
+ for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
+ g[move_by] = *g;
+ glyph = it->glyph_row->glyphs[it->area];
+ end = glyph + move_by;
+ }
+
+ if (glyph >= end)
+ return;
+ glyph->type = CHAR_GLYPH;
+ glyph->pixel_width = 1;
+ glyph->face_id = face_id;
+ glyph->padding_p = 0;
+ glyph->charpos = CHARPOS (it->position);
+ glyph->object = it->object;
+ if (it->bidi_p)
+ {
+ glyph->resolved_level = it->bidi_it.resolved_level;
+ if ((it->bidi_it.type & 7) != it->bidi_it.type)
+ abort ();
+ glyph->bidi_type = it->bidi_it.type;
+ }
+ else
+ {
+ glyph->resolved_level = 0;
+ glyph->bidi_type = UNKNOWN_BT;
+ }
+
+ /* BIDI Note: we put the glyphs of characters left to right, even in
+ the REVERSED_P case because we write to the terminal
+ left-to-right. */
+ for (i = 0; i < it->nglyphs && glyph < end; ++i)
+ {
+ if (i > 0)
+ glyph[0] = glyph[-1];
+ glyph->u.ch = str[i];
+ ++it->glyph_row->used[it->area];
+ ++glyph;
+ }
+}
+
+/* Produce glyphs for a glyphless character for iterator IT.
+ IT->glyphless_method specifies which method to use for displaying
+ the character. See the description of enum
+ glyphless_display_method in dispextern.h for the details.
+
+ FOR_NO_FONT is nonzero if and only if this is for a character that
+ is not supproted by the coding system of the terminal. ACRONYM, if
+ non-nil, is an acronym string for the character.
+
+ The glyphs actually produced are of type CHAR_GLYPH. */
+
+static void
+produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
+{
+ int face_id;
+ int len;
+ char buf[9], *str = " ";
+
+ /* Get a face ID for the glyph by utilizing a cache (the same way as
+ done for `escape-glyph' in get_next_display_element). */
+ if (it->f == last_glyphless_glyph_frame
+ && it->face_id == last_glyphless_glyph_face_id)
+ {
+ face_id = last_glyphless_glyph_merged_face_id;
+ }
+ else
+ {
+ /* Merge the `glyphless-char' face into the current face. */
+ face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
+ last_glyphless_glyph_frame = it->f;
+ last_glyphless_glyph_face_id = it->face_id;
+ last_glyphless_glyph_merged_face_id = face_id;
+ }
+
+ if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
+ {
+ /* As there's no way to produce a thin space, we produce a space
+ of canonical width. */
+ len = 1;
+ }
+ else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
+ {
+ len = CHAR_WIDTH (it->c);
+ if (len == 0)
+ len = 1;
+ else if (len > 4)
+ len = 4;
+ sprintf (buf, "[%.*s]", len, str);
+ len += 2;
+ str = buf;
+ }
+ else
+ {
+ if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
+ {
+ if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
+ acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
+ buf[0] = '[';
+ str = STRINGP (acronym) ? SSDATA (acronym) : "";
+ for (len = 0; len < 6 && str[len] && ASCII_BYTE_P (str[len]); len++)
+ buf[1 + len] = str[len];
+ buf[1 + len] = ']';
+ len += 2;
+ }
+ else
+ {
+ xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
+ len = (it->c < 0x10000 ? sprintf (buf, "\\u%04X", it->c)
+ : it->c <= MAX_UNICODE_CHAR ? sprintf (buf, "\\U%06X", it->c)
+ : sprintf (buf, "\\x%06X", it->c));
+ }
+ str = buf;
+ }
+
+ it->pixel_width = len;
+ it->nglyphs = len;
+ if (len > 0 && it->glyph_row)
+ append_glyphless_glyph (it, face_id, str);
+}
+
+
/* Get information about special display element WHAT in an
environment described by IT. WHAT is one of IT_TRUNCATION or
IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
face_id, c, len of IT are left untouched. */
void
-produce_special_glyphs (it, what)
- struct it *it;
- enum display_element_type what;
+produce_special_glyphs (struct it *it, enum display_element_type what)
{
struct it temp_it;
Lisp_Object gc;
temp_it.what = IT_CHARACTER;
temp_it.len = 1;
temp_it.object = make_number (0);
- bzero (&temp_it.current, sizeof temp_it.current);
+ memset (&temp_it.current, 0, sizeof temp_it.current);
if (what == IT_CONTINUATION)
{
- /* Continuation glyph. */
- SET_GLYPH_FROM_CHAR (glyph, '\\');
+ /* Continuation glyph. For R2L lines, we mirror it by hand. */
+ if (it->bidi_it.paragraph_dir == R2L)
+ SET_GLYPH_FROM_CHAR (glyph, '/');
+ else
+ SET_GLYPH_FROM_CHAR (glyph, '\\');
if (it->dp
&& (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc))
&& GLYPH_CODE_CHAR_VALID_P (gc))
{
+ /* FIXME: Should we mirror GC for R2L lines? */
SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
}
&& (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc))
&& GLYPH_CODE_CHAR_VALID_P (gc))
{
+ /* FIXME: Should we mirror GC for R2L lines? */
SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
}
else
abort ();
- temp_it.c = GLYPH_CHAR (glyph);
+ temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
temp_it.face_id = GLYPH_FACE (glyph);
temp_it.len = CHAR_BYTES (temp_it.c);
FACE_ID is a realized face ID number, in the face cache. */
static void
-turn_on_face (f, face_id)
- struct frame *f;
- int face_id;
+turn_on_face (struct frame *f, int face_id)
{
struct face *face = FACE_FROM_ID (f, face_id);
long fg = face->foreground;
}
}
- if (face->tty_bold_p)
- {
- if (MAY_USE_WITH_COLORS_P (tty, NC_BOLD))
- OUTPUT1_IF (tty, tty->TS_enter_bold_mode);
- }
- else if (face->tty_dim_p)
- if (MAY_USE_WITH_COLORS_P (tty, NC_DIM))
- OUTPUT1_IF (tty, tty->TS_enter_dim_mode);
+ if (face->tty_bold_p && MAY_USE_WITH_COLORS_P (tty, NC_BOLD))
+ OUTPUT1_IF (tty, tty->TS_enter_bold_mode);
+
+ if (face->tty_dim_p && MAY_USE_WITH_COLORS_P (tty, NC_DIM))
+ OUTPUT1_IF (tty, tty->TS_enter_dim_mode);
/* Alternate charset and blinking not yet used. */
if (face->tty_alt_charset_p
/* Turn off appearances of face FACE_ID on tty frame F. */
static void
-turn_off_face (f, face_id)
- struct frame *f;
- int face_id;
+turn_off_face (struct frame *f, int face_id)
{
struct face *face = FACE_FROM_ID (f, face_id);
struct tty_display_info *tty = FRAME_TTY (f);
colors FG and BG. */
int
-tty_capable_p (tty, caps, fg, bg)
- struct tty_display_info *tty;
- unsigned caps;
- unsigned long fg, bg;
+tty_capable_p (struct tty_display_info *tty, unsigned int caps,
+ unsigned long fg, unsigned long bg)
{
#define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
0, 1, 0,
doc: /* Return non-nil if the tty device TERMINAL can display colors.
-TERMINAL can be a terminal id, a frame or nil (meaning the selected
-frame's terminal). This function always returns nil if TERMINAL
-is not on a tty device. */)
- (terminal)
- Lisp_Object terminal;
+TERMINAL can be a terminal object, a frame, or nil (meaning the
+selected frame's terminal). This function always returns nil if
+TERMINAL does not refer to a text-only terminal. */)
+ (Lisp_Object terminal)
{
struct terminal *t = get_tty_terminal (terminal, 0);
if (!t)
Stty_display_color_cells, 0, 1, 0,
doc: /* Return the number of colors supported by the tty device TERMINAL.
-TERMINAL can be a terminal id, a frame or nil (meaning the selected
-frame's terminal). This function always returns 0 if TERMINAL
-is not on a tty device. */)
- (terminal)
- Lisp_Object terminal;
+TERMINAL can be a terminal object, a frame, or nil (meaning the
+selected frame's terminal). This function always returns 0 if
+TERMINAL does not refer to a text-only terminal. */)
+ (Lisp_Object terminal)
{
struct terminal *t = get_tty_terminal (terminal, 0);
if (!t)
return make_number (t->display_info.tty->TN_max_colors);
}
-#ifndef WINDOWSNT
+#ifndef DOS_NT
/* Declare here rather than in the function, as in the rest of Emacs,
to work around an HPUX compiler bug (?). See
if (save)
{
- if (default_orig_pair)
- xfree (default_orig_pair);
+ xfree (default_orig_pair);
default_orig_pair = tty->TS_orig_pair ? xstrdup (tty->TS_orig_pair) : NULL;
- if (default_set_foreground)
- xfree (default_set_foreground);
+ xfree (default_set_foreground);
default_set_foreground = tty->TS_set_foreground ? xstrdup (tty->TS_set_foreground)
: NULL;
- if (default_set_background)
- xfree (default_set_background);
+ xfree (default_set_background);
default_set_background = tty->TS_set_background ? xstrdup (tty->TS_set_background)
: NULL;
}
void
-set_tty_color_mode (tty, f)
- struct tty_display_info *tty;
- struct frame *f;
+set_tty_color_mode (struct tty_display_info *tty, struct frame *f)
{
- Lisp_Object tem, val, color_mode_spec;
+ Lisp_Object tem, val;
Lisp_Object color_mode;
int mode;
- extern Lisp_Object Qtty_color_mode;
Lisp_Object tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"), Qnil);
if (INTEGERP (val))
color_mode = val;
- else
+ else if (SYMBOLP (tty_color_mode_alist))
{
- tem = (NILP (tty_color_mode_alist) ? Qnil
- : Fassq (val, XSYMBOL (tty_color_mode_alist)->value));
+ tem = Fassq (val, Fsymbol_value (tty_color_mode_alist));
color_mode = CONSP (tem) ? XCDR (tem) : Qnil;
}
+ else
+ color_mode = Qnil;
mode = INTEGERP (color_mode) ? XINT (color_mode) : 0;
}
}
-#endif /* !WINDOWSNT */
+#endif /* !DOS_NT */
\f
{
struct terminal *t = get_terminal (terminal, throw);
- if (t && t->type != output_termcap)
+ if (t && t->type != output_termcap && t->type != output_msdos_raw)
{
if (throw)
error ("Device %d is not a termcap terminal device", t->id);
Returns NULL if the named terminal device is not opened. */
struct terminal *
-get_named_tty (name)
- char *name;
+get_named_tty (const char *name)
{
struct terminal *t;
for (t = terminal_list; t; t = t->next_terminal)
{
- if (t->type == output_termcap
+ if ((t->type == output_termcap || t->type == output_msdos_raw)
&& !strcmp (t->display_info.tty->name, name)
&& TERMINAL_ACTIVE_P (t))
return t;
doc: /* Return the type of the tty device that TERMINAL uses.
Returns nil if TERMINAL is not on a tty device.
-TERMINAL can be a terminal id, a frame or nil (meaning the selected
-frame's terminal). */)
- (terminal)
- Lisp_Object terminal;
+TERMINAL can be a terminal object, a frame, or nil (meaning the
+selected frame's terminal). */)
+ (Lisp_Object terminal)
{
struct terminal *t = get_terminal (terminal, 1);
- if (t->type != output_termcap)
+ if (t->type != output_termcap && t->type != output_msdos_raw)
return Qnil;
if (t->display_info.tty->type)
}
DEFUN ("controlling-tty-p", Fcontrolling_tty_p, Scontrolling_tty_p, 0, 1, 0,
- doc: /* Return non-nil if TERMINAL is on the controlling tty of the Emacs process.
+ doc: /* Return non-nil if TERMINAL is the controlling tty of the Emacs process.
-TERMINAL can be a terminal id, a frame or nil (meaning the selected
-frame's terminal). This function always returns nil if TERMINAL
-is not on a tty device. */)
- (terminal)
- Lisp_Object terminal;
+TERMINAL can be a terminal object, a frame, or nil (meaning the
+selected frame's terminal). This function always returns nil if
+TERMINAL is not on a tty device. */)
+ (Lisp_Object terminal)
{
struct terminal *t = get_terminal (terminal, 1);
- if (t->type != output_termcap || strcmp (t->display_info.tty->name, DEV_TTY))
+ if ((t->type != output_termcap && t->type != output_msdos_raw)
+ || strcmp (t->display_info.tty->name, DEV_TTY) != 0)
return Qnil;
else
return Qt;
do not really do underlining, but say that they do. This function has
no effect if used on a non-tty terminal.
-TERMINAL can be a terminal id, a frame or nil (meaning the selected
-frame's terminal). This function always returns nil if TERMINAL
-is not on a tty device. */)
- (terminal)
- Lisp_Object terminal;
+TERMINAL can be a terminal object, a frame or nil (meaning the
+selected frame's terminal). This function always returns nil if
+TERMINAL does not refer to a text-only terminal. */)
+ (Lisp_Object terminal)
{
struct terminal *t = get_terminal (terminal, 1);
but input is not read from them and if they change, their display is
not updated.
-TTY may be a terminal id, a frame, or nil for the terminal device of
-the currently selected frame.
+TTY may be a terminal object, a frame, or nil for the terminal device
+of the currently selected frame.
This function runs `suspend-tty-functions' after suspending the
device. The functions are run with one arg, the id of the suspended
suspended.
A suspended tty may be resumed by calling `resume-tty' on it. */)
- (tty)
- Lisp_Object tty;
+ (Lisp_Object tty)
{
struct terminal *t = get_tty_terminal (tty, 1);
FILE *f;
}
reset_sys_modes (t->display_info.tty);
-
delete_keyboard_wait_descriptor (fileno (f));
+#ifndef MSDOS
fclose (f);
if (f != t->display_info.tty->output)
fclose (t->display_info.tty->output);
+#endif
t->display_info.tty->input = 0;
t->display_info.tty->output = 0;
`resume-tty' does nothing if it is called on a device that is not
suspended.
-TTY may be a terminal id, a frame, or nil for the terminal device of
-the currently selected frame. */)
- (tty)
- Lisp_Object tty;
+TTY may be a terminal object, a frame, or nil (meaning the selected
+frame's terminal). */)
+ (Lisp_Object tty)
{
struct terminal *t = get_tty_terminal (tty, 1);
int fd;
if (get_named_tty (t->display_info.tty->name))
error ("Cannot resume display while another display is active on the same device");
+#ifdef MSDOS
+ t->display_info.tty->output = stdout;
+ t->display_info.tty->input = stdin;
+#else /* !MSDOS */
fd = emacs_open (t->display_info.tty->name, O_RDWR | O_NOCTTY, 0);
if (fd == -1)
t->display_info.tty->output = fdopen (fd, "w+");
t->display_info.tty->input = t->display_info.tty->output;
+#endif
add_keyboard_wait_descriptor (fd);
if (FRAMEP (t->display_info.tty->top_frame))
- FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1);
+ {
+ struct frame *f = XFRAME (t->display_info.tty->top_frame);
+ int width, height;
+ int old_height = FRAME_COLS (f);
+ int old_width = FRAME_LINES (f);
+
+ /* Check if terminal/window size has changed while the frame
+ was suspended. */
+ get_tty_size (fileno (t->display_info.tty->input), &width, &height);
+ if (width != old_width || height != old_height)
+ change_frame_size (f, height, width, 0, 0, 0);
+ FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1);
+ }
init_sys_modes (t->display_info.tty);
last_mouse_y = y; */
}
-static void
-term_show_mouse_face (enum draw_glyphs_face draw)
+/* Implementation of draw_row_with_mouse_face for TTY/GPM. */
+void
+tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
+ int start_hpos, int end_hpos,
+ enum draw_glyphs_face draw)
{
- struct window *w = XWINDOW (mouse_face_window);
- int save_x, save_y;
- int i;
-
- struct frame *f = XFRAME (w->frame);
+ int nglyphs = end_hpos - start_hpos;
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
struct tty_display_info *tty = FRAME_TTY (f);
+ int face_id = tty->mouse_highlight.mouse_face_face_id;
+ int save_x, save_y, pos_x, pos_y;
- if (/* If window is in the process of being destroyed, don't bother
- to do anything. */
- w->current_matrix != NULL
- /* Recognize when we are called to operate on rows that don't exist
- anymore. This can happen when a window is split. */
- && mouse_face_end_row < w->current_matrix->nrows)
- {
- /* write_glyphs writes at cursor position, so we need to
- temporarily move cursor coordinates to the beginning of
- the highlight region. */
-
- /* Save current cursor co-ordinates */
- save_y = curY (tty);
- save_x = curX (tty);
-
- /* Note that mouse_face_beg_row etc. are window relative. */
- for (i = mouse_face_beg_row; i <= mouse_face_end_row; i++)
- {
- int start_hpos, end_hpos, nglyphs;
- struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
-
- /* Don't do anything if row doesn't have valid contents. */
- if (!row->enabled_p)
- continue;
-
- /* For all but the first row, the highlight starts at column 0. */
- if (i == mouse_face_beg_row)
- start_hpos = mouse_face_beg_col;
- else
- start_hpos = 0;
-
- if (i == mouse_face_end_row)
- end_hpos = mouse_face_end_col;
- else
- {
- end_hpos = row->used[TEXT_AREA];
- if (draw == DRAW_NORMAL_TEXT)
- row->fill_line_p = 1; /* Clear to end of line */
- }
-
- if (end_hpos <= start_hpos)
- continue;
- /* Record that some glyphs of this row are displayed in
- mouse-face. */
- row->mouse_face_p = draw > 0;
-
- nglyphs = end_hpos - start_hpos;
-
- if (end_hpos >= row->used[TEXT_AREA])
- nglyphs = row->used[TEXT_AREA] - start_hpos;
-
- pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
- pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos
- + WINDOW_LEFT_EDGE_X (w);
-
- cursor_to (f, pos_y, pos_x);
-
- if (draw == DRAW_MOUSE_FACE)
- {
- tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos,
- nglyphs, mouse_face_face_id);
- }
- else /* draw == DRAW_NORMAL_TEXT */
- write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
- }
- cursor_to (f, save_y, save_x);
- }
-}
-
-static void
-term_clear_mouse_face ()
-{
- if (!NILP (mouse_face_window))
- term_show_mouse_face (DRAW_NORMAL_TEXT);
-
- mouse_face_beg_row = mouse_face_beg_col = -1;
- mouse_face_end_row = mouse_face_end_col = -1;
- mouse_face_window = Qnil;
-}
-
-/* Find the glyph matrix position of buffer position POS in window W.
- *HPOS and *VPOS are set to the positions found. W's current glyphs
- must be up to date. If POS is above window start return (0, 0).
- If POS is after end of W, return end of last line in W.
- - taken from msdos.c */
-static int
-fast_find_position (struct window *w, int pos, int *hpos, int *vpos)
-{
- int i, lastcol, line_start_position, maybe_next_line_p = 0;
- int yb = window_text_bottom_y (w);
- struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0), *best_row = row;
-
- while (row->y < yb)
- {
- if (row->used[TEXT_AREA])
- line_start_position = row->glyphs[TEXT_AREA]->charpos;
- else
- line_start_position = 0;
-
- if (line_start_position > pos)
- break;
- /* If the position sought is the end of the buffer,
- don't include the blank lines at the bottom of the window. */
- else if (line_start_position == pos
- && pos == BUF_ZV (XBUFFER (w->buffer)))
- {
- maybe_next_line_p = 1;
- break;
- }
- else if (line_start_position > 0)
- best_row = row;
-
- /* Don't overstep the last matrix row, lest we get into the
- never-never land... */
- if (row->y + 1 >= yb)
- break;
-
- ++row;
- }
-
- /* Find the right column within BEST_ROW. */
- lastcol = 0;
- row = best_row;
- for (i = 0; i < row->used[TEXT_AREA]; i++)
- {
- struct glyph *glyph = row->glyphs[TEXT_AREA] + i;
- int charpos;
-
- charpos = glyph->charpos;
- if (charpos == pos)
- {
- *hpos = i;
- *vpos = row->y;
- return 1;
- }
- else if (charpos > pos)
- break;
- else if (charpos > 0)
- lastcol = i;
- }
-
- /* If we're looking for the end of the buffer,
- and we didn't find it in the line we scanned,
- use the start of the following line. */
- if (maybe_next_line_p)
- {
- ++row;
- lastcol = 0;
- }
-
- *vpos = row->y;
- *hpos = lastcol + 1;
- return 0;
-}
-
-static void
-term_mouse_highlight (struct frame *f, int x, int y)
-{
- enum window_part part;
- Lisp_Object window;
- struct window *w;
- struct buffer *b;
-
- if (NILP (Vmouse_highlight)
- || !f->glyphs_initialized_p)
- return;
-
- /* Which window is that in? */
- window = window_from_coordinates (f, x, y, &part, &x, &y, 0);
+ if (end_hpos >= row->used[TEXT_AREA])
+ nglyphs = row->used[TEXT_AREA] - start_hpos;
- /* Not on a window -> return. */
- if (!WINDOWP (window))
- return;
-
- if (!EQ (window, mouse_face_window))
- term_clear_mouse_face ();
+ pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
+ pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w);
- w = XWINDOW (window);
-
- /* Are we in a window whose display is up to date?
- And verify the buffer's text has not changed. */
- b = XBUFFER (w->buffer);
- if (part == ON_TEXT
- && EQ (w->window_end_valid, w->buffer)
- && XFASTINT (w->last_modified) == BUF_MODIFF (b)
- && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
- {
- int pos, i, nrows = w->current_matrix->nrows;
- struct glyph_row *row;
- struct glyph *glyph;
+ /* Save current cursor co-ordinates. */
+ save_y = curY (tty);
+ save_x = curX (tty);
+ cursor_to (f, pos_y, pos_x);
- /* Find the glyph under X/Y. */
- glyph = NULL;
- if (y >= 0 && y < nrows)
- {
- row = MATRIX_ROW (w->current_matrix, y);
- /* Give up if some row before the one we are looking for is
- not enabled. */
- for (i = 0; i <= y; i++)
- if (!MATRIX_ROW (w->current_matrix, i)->enabled_p)
- break;
- if (i > y /* all rows upto and including the one at Y are enabled */
- && row->displays_text_p
- && x < window_box_width (w, TEXT_AREA))
- {
- glyph = row->glyphs[TEXT_AREA];
- if (x >= row->used[TEXT_AREA])
- glyph = NULL;
- else
- {
- glyph += x;
- if (!BUFFERP (glyph->object))
- glyph = NULL;
- }
- }
- }
+ if (draw == DRAW_MOUSE_FACE)
+ tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos,
+ nglyphs, face_id);
+ else if (draw == DRAW_NORMAL_TEXT)
+ write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
- /* Clear mouse face if X/Y not over text. */
- if (glyph == NULL)
- {
- term_clear_mouse_face ();
- return;
- }
-
- if (!BUFFERP (glyph->object))
- abort ();
- pos = glyph->charpos;
-
- /* Check for mouse-face. */
- {
- extern Lisp_Object Qmouse_face;
- Lisp_Object mouse_face, overlay, position, *overlay_vec;
- int noverlays, obegv, ozv;
- struct buffer *obuf;
-
- /* If we get an out-of-range value, return now; avoid an error. */
- if (pos > BUF_Z (b))
- return;
-
- /* Make the window's buffer temporarily current for
- overlays_at and compute_char_face. */
- obuf = current_buffer;
- current_buffer = b;
- obegv = BEGV;
- ozv = ZV;
- BEGV = BEG;
- ZV = Z;
-
- /* Is this char mouse-active? */
- XSETINT (position, pos);
-
- /* Put all the overlays we want in a vector in overlay_vec. */
- GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
- /* Sort overlays into increasing priority order. */
- noverlays = sort_overlays (overlay_vec, noverlays, w);
-
- /* Check mouse-face highlighting. */
- if (!(EQ (window, mouse_face_window)
- && y >= mouse_face_beg_row
- && y <= mouse_face_end_row
- && (y > mouse_face_beg_row
- || x >= mouse_face_beg_col)
- && (y < mouse_face_end_row
- || x < mouse_face_end_col
- || mouse_face_past_end)))
- {
- /* Clear the display of the old active region, if any. */
- term_clear_mouse_face ();
-
- /* Find the highest priority overlay that has a mouse-face
- property. */
- overlay = Qnil;
- for (i = noverlays - 1; i >= 0; --i)
- {
- mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
- if (!NILP (mouse_face))
- {
- overlay = overlay_vec[i];
- break;
- }
- }
-
- /* If no overlay applies, get a text property. */
- if (NILP (overlay))
- mouse_face = Fget_text_property (position, Qmouse_face,
- w->buffer);
-
- /* Handle the overlay case. */
- if (!NILP (overlay))
- {
- /* Find the range of text around this char that
- should be active. */
- Lisp_Object before, after;
- EMACS_INT ignore;
-
-
- before = Foverlay_start (overlay);
- after = Foverlay_end (overlay);
- /* Record this as the current active region. */
- fast_find_position (w, XFASTINT (before),
- &mouse_face_beg_col,
- &mouse_face_beg_row);
-
- mouse_face_past_end
- = !fast_find_position (w, XFASTINT (after),
- &mouse_face_end_col,
- &mouse_face_end_row);
- mouse_face_window = window;
-
- mouse_face_face_id
- = face_at_buffer_position (w, pos, 0, 0,
- &ignore, pos + 1, 1);
-
- /* Display it as active. */
- term_show_mouse_face (DRAW_MOUSE_FACE);
- }
- /* Handle the text property case. */
- else if (!NILP (mouse_face))
- {
- /* Find the range of text around this char that
- should be active. */
- Lisp_Object before, after, beginning, end;
- EMACS_INT ignore;
-
- beginning = Fmarker_position (w->start);
- XSETINT (end, (BUF_Z (b) - XFASTINT (w->window_end_pos)));
- before
- = Fprevious_single_property_change (make_number (pos + 1),
- Qmouse_face,
- w->buffer, beginning);
- after
- = Fnext_single_property_change (position, Qmouse_face,
- w->buffer, end);
-
- /* Record this as the current active region. */
- fast_find_position (w, XFASTINT (before),
- &mouse_face_beg_col,
- &mouse_face_beg_row);
- mouse_face_past_end
- = !fast_find_position (w, XFASTINT (after),
- &mouse_face_end_col,
- &mouse_face_end_row);
- mouse_face_window = window;
-
- mouse_face_face_id
- = face_at_buffer_position (w, pos, 0, 0,
- &ignore, pos + 1, 1);
-
- /* Display it as active. */
- term_show_mouse_face (DRAW_MOUSE_FACE);
- }
- }
-
- /* Look for a `help-echo' property. */
- {
- Lisp_Object help;
- extern Lisp_Object Qhelp_echo;
-
- /* Check overlays first. */
- help = Qnil;
- for (i = noverlays - 1; i >= 0 && NILP (help); --i)
- {
- overlay = overlay_vec[i];
- help = Foverlay_get (overlay, Qhelp_echo);
- }
-
- if (!NILP (help))
- {
- help_echo_string = help;
- help_echo_window = window;
- help_echo_object = overlay;
- help_echo_pos = pos;
- }
- /* Try text properties. */
- else if (NILP (help)
- && ((STRINGP (glyph->object)
- && glyph->charpos >= 0
- && glyph->charpos < SCHARS (glyph->object))
- || (BUFFERP (glyph->object)
- && glyph->charpos >= BEGV
- && glyph->charpos < ZV)))
- {
- help = Fget_text_property (make_number (glyph->charpos),
- Qhelp_echo, glyph->object);
- if (!NILP (help))
- {
- help_echo_string = help;
- help_echo_window = window;
- help_echo_object = glyph->object;
- help_echo_pos = glyph->charpos;
- }
- }
- }
-
- BEGV = obegv;
- ZV = ozv;
- current_buffer = obuf;
- }
- }
+ cursor_to (f, save_y, save_x);
}
static int
if (event->x != last_mouse_x || event->y != last_mouse_y)
{
frame->mouse_moved = 1;
- term_mouse_highlight (frame, event->x, event->y);
+ note_mouse_highlight (frame, event->x, event->y);
/* Remember which glyph we're now on. */
last_mouse_x = event->x;
last_mouse_y = event->y;
0, 0, 0,
doc: /* Open a connection to Gpm.
Gpm-mouse can only be activated for one tty at a time. */)
- ()
+ (void)
{
struct frame *f = SELECTED_FRAME ();
struct tty_display_info *tty
}
}
+void
+close_gpm (int fd)
+{
+ if (fd >= 0)
+ delete_gpm_wait_descriptor (fd);
+ while (Gpm_Close()); /* close all the stack */
+ gpm_tty = NULL;
+}
+
DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop, Sgpm_mouse_stop,
0, 0, 0,
doc: /* Close a connection to Gpm. */)
- ()
+ (void)
{
struct frame *f = SELECTED_FRAME ();
struct tty_display_info *tty
if (!tty || gpm_tty != tty)
return Qnil; /* Not activated on this terminal, nothing to do. */
- if (gpm_fd >= 0)
- delete_gpm_wait_descriptor (gpm_fd);
- while (Gpm_Close()); /* close all the stack */
- gpm_tty = NULL;
+ close_gpm (gpm_fd);
return Qnil;
}
#endif /* HAVE_GPM */
\f
+#ifndef MSDOS
/***********************************************************************
Initialization
***********************************************************************/
abort ();
t = xmalloc (sizeof (struct tty_output));
- bzero (t, sizeof (struct tty_output));
+ memset (t, 0, sizeof (struct tty_output));
t->display_info = FRAME_TERMINAL (f)->display_info.tty;
f->output_data.tty = t;
}
-/* Delete the tty-dependent part of frame F. */
+/* Delete frame F's face cache, and its tty-dependent part. */
static void
-delete_tty_output (struct frame *f)
+tty_free_frame_resources (struct frame *f)
{
if (! FRAME_TERMCAP_P (f))
abort ();
+ if (FRAME_FACE_CACHE (f))
+ free_frame_faces (f);
+
xfree (f->output_data.tty);
}
+#else /* MSDOS */
+
+/* Delete frame F's face cache. */
+
+static void
+tty_free_frame_resources (struct frame *f)
+{
+ if (! FRAME_TERMCAP_P (f) && ! FRAME_MSDOS_P (f))
+ abort ();
+
+ if (FRAME_FACE_CACHE (f))
+ free_frame_faces (f);
+}
+#endif /* MSDOS */
\f
/* Reset the hooks in TERMINAL. */
/* Leave these two set, or suspended frames are not deleted
correctly. */
- terminal->delete_frame_hook = &delete_tty_output;
+ terminal->delete_frame_hook = &tty_free_frame_resources;
terminal->delete_terminal_hook = &delete_tty;
}
terminal->read_socket_hook = &tty_read_avail_input; /* keyboard.c */
terminal->frame_up_to_date_hook = 0; /* Not needed. */
- terminal->delete_frame_hook = &delete_tty_output;
+ terminal->delete_frame_hook = &tty_free_frame_resources;
terminal->delete_terminal_hook = &delete_tty;
}
static void
dissociate_if_controlling_tty (int fd)
{
-#ifndef WINDOWSNT
- int pgid;
- EMACS_GET_TTY_PGRP (fd, &pgid); /* If tcgetpgrp succeeds, fd is the ctty. */
+#ifndef DOS_NT
+ int pgid = tcgetpgrp (fd); /* If tcgetpgrp succeeds, fd is the ctty. */
if (pgid != -1)
{
-#if defined (USG) && !defined (BSD_PGRPS)
+#if defined (USG5)
setpgrp ();
no_controlling_tty = 1;
#elif defined (CYGWIN)
#endif /* ! TIOCNOTTY */
#endif /* ! USG */
}
-#endif /* !WINDOWSNT */
+#endif /* !DOS_NT */
}
-static void maybe_fatal();
-
/* Create a termcap display on the tty device with the given name and
type.
If MUST_SUCCEED is true, then all errors are fatal. */
struct terminal *
-init_tty (char *name, char *terminal_type, int must_succeed)
+init_tty (const char *name, const char *terminal_type, int must_succeed)
{
char *area = NULL;
char **address = &area;
- char *buffer = NULL;
int buffer_size = 4096;
register char *p = NULL;
int status;
int ctty = 0; /* 1 if asked to open controlling tty. */
if (!terminal_type)
- maybe_fatal (must_succeed, 0, 0,
+ maybe_fatal (must_succeed, 0,
"Unknown terminal type",
"Unknown terminal type");
return terminal;
terminal = create_terminal ();
+#ifdef MSDOS
+ if (been_here > 0)
+ maybe_fatal (1, 0, "Attempt to create another terminal %s", "",
+ name, "");
+ been_here = 1;
+ tty = &the_only_display_info;
+#else
tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info));
- bzero (tty, sizeof (struct tty_display_info));
+#endif
+ memset (tty, 0, sizeof (struct tty_display_info));
tty->next = tty_list;
tty_list = tty;
tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm));
Wcm_clear (tty);
-#ifndef WINDOWSNT
+ encode_terminal_src_size = 0;
+ encode_terminal_dst_size = 0;
+
+#ifdef HAVE_GPM
+ terminal->mouse_position_hook = term_mouse_position;
+ tty->mouse_highlight.mouse_face_window = Qnil;
+#endif
+
+
+#ifndef DOS_NT
set_tty_hooks (terminal);
{
fd = emacs_open (name, O_RDWR | O_NOCTTY, 0);
#endif /* O_IGNORE_CTTY */
+ tty->name = xstrdup (name);
+ terminal->name = xstrdup (name);
+
if (fd < 0)
- maybe_fatal (must_succeed, buffer, terminal,
+ maybe_fatal (must_succeed, terminal,
"Could not open file: %s",
"Could not open file: %s",
name);
if (!isatty (fd))
{
close (fd);
- maybe_fatal (must_succeed, buffer, terminal,
+ maybe_fatal (must_succeed, terminal,
"Not a tty device: %s",
"Not a tty device: %s",
name);
#endif
file = fdopen (fd, "w+");
- tty->name = xstrdup (name);
- terminal->name = xstrdup (name);
tty->input = file;
tty->output = file;
}
add_keyboard_wait_descriptor (fileno (tty->input));
-#endif
-
- encode_terminal_src_size = 0;
- encode_terminal_dst_size = 0;
-
-#ifdef HAVE_GPM
- terminal->mouse_position_hook = term_mouse_position;
- mouse_face_window = Qnil;
-#endif
-
-#ifdef WINDOWSNT
- initialize_w32_display (terminal);
- /* The following two are inaccessible from w32console.c. */
- terminal->delete_frame_hook = &delete_tty_output;
- terminal->delete_terminal_hook = &delete_tty;
-
- tty->name = xstrdup (name);
- terminal->name = xstrdup (name);
- tty->type = xstrdup (terminal_type);
-
- tty->output = stdout;
- tty->input = stdin;
- add_keyboard_wait_descriptor (0);
-
Wcm_clear (tty);
- {
- struct frame *f = XFRAME (selected_frame);
-
- FrameRows (tty) = FRAME_LINES (f);
- FrameCols (tty) = FRAME_COLS (f);
- tty->specified_window = FRAME_LINES (f);
-
- FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
- FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
- }
- tty->delete_in_insert_mode = 1;
-
- UseTabs (tty) = 0;
- terminal->scroll_region_ok = 0;
-
- /* Seems to insert lines when it's not supposed to, messing up the
- display. In doing a trace, it didn't seem to be called much, so I
- don't think we're losing anything by turning it off. */
- terminal->line_ins_del_ok = 0;
- terminal->char_ins_del_ok = 1;
-
- baud_rate = 19200;
-
- tty->TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
-
-#else /* not WINDOWSNT */
-
- Wcm_clear (tty);
-
- buffer = (char *) xmalloc (buffer_size);
+ tty->termcap_term_buffer = (char *) xmalloc (buffer_size);
/* On some systems, tgetent tries to access the controlling
terminal. */
sigblock (sigmask (SIGTTOU));
- status = tgetent (buffer, terminal_type);
+ status = tgetent (tty->termcap_term_buffer, terminal_type);
sigunblock (sigmask (SIGTTOU));
if (status < 0)
{
#ifdef TERMINFO
- maybe_fatal (must_succeed, buffer, terminal,
+ maybe_fatal (must_succeed, terminal,
"Cannot open terminfo database file",
"Cannot open terminfo database file");
#else
- maybe_fatal (must_succeed, buffer, terminal,
+ maybe_fatal (must_succeed, terminal,
"Cannot open termcap database file",
"Cannot open termcap database file");
#endif
}
if (status == 0)
{
-#ifdef TERMINFO
- maybe_fatal (must_succeed, buffer, terminal,
+ maybe_fatal (must_succeed, terminal,
"Terminal type %s is not defined",
"Terminal type %s is not defined.\n\
If that is not the actual type of terminal you have,\n\
use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
-`setenv TERM ...') to specify the correct type. It may be necessary\n\
-to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
- terminal_type);
+`setenv TERM ...') to specify the correct type. It may be necessary\n"
+#ifdef TERMINFO
+"to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
#else
- maybe_fatal (must_succeed, buffer, terminal,
- "Terminal type %s is not defined",
- "Terminal type %s is not defined.\n\
-If that is not the actual type of terminal you have,\n\
-use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
-`setenv TERM ...') to specify the correct type. It may be necessary\n\
-to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
- terminal_type);
+"to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
#endif
+ terminal_type);
}
#ifndef TERMINFO
- if (strlen (buffer) >= buffer_size)
+ if (strlen (tty->termcap_term_buffer) >= buffer_size)
abort ();
- buffer_size = strlen (buffer);
+ buffer_size = strlen (tty->termcap_term_buffer);
#endif
- area = (char *) xmalloc (buffer_size);
-
+ tty->termcap_strings_buffer = area = (char *) xmalloc (buffer_size);
tty->TS_ins_line = tgetstr ("al", address);
tty->TS_ins_multi_lines = tgetstr ("AL", address);
tty->TS_bell = tgetstr ("bl", address);
Down (tty) = tgetstr ("do", address);
if (!Down (tty))
Down (tty) = tgetstr ("nl", address); /* Obsolete name for "do" */
-#ifdef VMS
- /* VMS puts a carriage return before each linefeed,
- so it is not safe to use linefeeds. */
- if (Down (tty) && Down (tty)[0] == '\n' && Down (tty)[1] == '\0')
- Down (tty) = 0;
-#endif /* VMS */
if (tgetflag ("bs"))
Left (tty) = "\b"; /* can't possibly be longer! */
else /* (Actually, "bs" is obsolete...) */
tty->TF_underscore = tgetflag ("ul");
tty->TF_teleray = tgetflag ("xt");
-#endif /* !WINDOWSNT */
-#ifdef MULTI_KBOARD
+#else /* DOS_NT */
+#ifdef WINDOWSNT
+ {
+ struct frame *f = XFRAME (selected_frame);
+
+ initialize_w32_display (terminal);
+
+ FrameRows (tty) = FRAME_LINES (f);
+ FrameCols (tty) = FRAME_COLS (f);
+ tty->specified_window = FRAME_LINES (f);
+
+ FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
+ FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
+ terminal->char_ins_del_ok = 1;
+ baud_rate = 19200;
+ }
+#else /* MSDOS */
+ {
+ int height, width;
+ if (strcmp (terminal_type, "internal") == 0)
+ terminal->type = output_msdos_raw;
+ initialize_msdos_display (terminal);
+
+ get_tty_size (fileno (tty->input), &width, &height);
+ FrameCols (tty) = width;
+ FrameRows (tty) = height;
+ terminal->char_ins_del_ok = 0;
+ init_baud_rate (fileno (tty->input));
+ }
+#endif /* MSDOS */
+ tty->output = stdout;
+ tty->input = stdin;
+ /* The following two are inaccessible from w32console.c. */
+ terminal->delete_frame_hook = &tty_free_frame_resources;
+ terminal->delete_terminal_hook = &delete_tty;
+
+ tty->name = xstrdup (name);
+ terminal->name = xstrdup (name);
+ tty->type = xstrdup (terminal_type);
+
+ add_keyboard_wait_descriptor (0);
+
+ tty->delete_in_insert_mode = 1;
+
+ UseTabs (tty) = 0;
+ terminal->scroll_region_ok = 0;
+
+ /* Seems to insert lines when it's not supposed to, messing up the
+ display. In doing a trace, it didn't seem to be called much, so I
+ don't think we're losing anything by turning it off. */
+ terminal->line_ins_del_ok = 0;
+
+ tty->TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
+#endif /* DOS_NT */
+
terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
init_kboard (terminal->kboard);
terminal->kboard->Vwindow_system = Qnil;
prompt in the mini-buffer. */
if (current_kboard == initial_kboard)
current_kboard = terminal->kboard;
-#ifndef WINDOWSNT
+#ifndef DOS_NT
term_get_fkeys (address, terminal->kboard);
-#endif
-#endif
-#ifndef WINDOWSNT
/* Get frame size from system, or else from termcap. */
{
int height, width;
FrameRows (tty) = tgetnum ("li");
if (FrameRows (tty) < 3 || FrameCols (tty) < 3)
- maybe_fatal (must_succeed, NULL, terminal,
- "Screen size %dx%d is too small"
+ maybe_fatal (must_succeed, terminal,
+ "Screen size %dx%d is too small",
"Screen size %dx%d is too small",
FrameCols (tty), FrameRows (tty));
-#if 0 /* This is not used anywhere. */
- tty->terminal->min_padding_speed = tgetnum ("pb");
-#endif
-
TabWidth (tty) = tgetnum ("tw");
-#ifdef VMS
- /* These capabilities commonly use ^J.
- I don't know why, but sending them on VMS does not work;
- it causes following spaces to be lost, sometimes.
- For now, the simplest fix is to avoid using these capabilities ever. */
- if (Down (tty) && Down (tty)[0] == '\n')
- Down (tty) = 0;
-#endif /* VMS */
-
if (!tty->TS_bell)
tty->TS_bell = "\07";
if (Wcm_init (tty) == -1) /* can't do cursor motion */
{
- maybe_fatal (must_succeed, NULL, terminal,
+ maybe_fatal (must_succeed, terminal,
"Terminal type \"%s\" is not powerful enough to run Emacs",
-#ifdef VMS
- "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
-It lacks the ability to position the cursor.\n\
-If that is not the actual type of terminal you have, use either the\n\
-DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
-or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
-#else /* not VMS */
-# ifdef TERMINFO
"Terminal type \"%s\" is not powerful enough to run Emacs.\n\
It lacks the ability to position the cursor.\n\
If that is not the actual type of terminal you have,\n\
use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
-`setenv TERM ...') to specify the correct type. It may be necessary\n\
-to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
+`setenv TERM ...') to specify the correct type. It may be necessary\n"
+# ifdef TERMINFO
+"to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
# else /* TERMCAP */
- "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
-It lacks the ability to position the cursor.\n\
-If that is not the actual type of terminal you have,\n\
-use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
-`setenv TERM ...') to specify the correct type. It may be necessary\n\
-to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
+"to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
# endif /* TERMINFO */
-#endif /*VMS */
terminal_type);
}
if (FrameRows (tty) <= 0 || FrameCols (tty) <= 0)
- maybe_fatal (must_succeed, NULL, terminal,
+ maybe_fatal (must_succeed, terminal,
"Could not determine the frame size",
"Could not determine the frame size");
init_baud_rate (fileno (tty->input));
-#ifdef AIXHFT
- /* The HFT system on AIX doesn't optimize for scrolling, so it's
- really ugly at times. */
- terminal->line_ins_del_ok = 0;
- terminal->char_ins_del_ok = 0;
-#endif
-
- /* Don't do this. I think termcap may still need the buffer. */
- /* xfree (buffer); */
-
-#endif /* not WINDOWSNT */
+#endif /* not DOS_NT */
/* Init system terminal modes (RAW or CBREAK, etc.). */
init_sys_modes (tty);
return terminal;
}
-/* Auxiliary error-handling function for init_tty.
- Free BUFFER and delete TERMINAL, then call error or fatal
- with str1 or str2, respectively, according to MUST_SUCCEED. */
static void
-maybe_fatal (must_succeed, buffer, terminal, str1, str2, arg1, arg2)
- int must_succeed;
- char *buffer;
- struct terminal *terminal;
- char *str1, *str2, *arg1, *arg2;
+vfatal (const char *str, va_list ap)
{
- if (buffer)
- xfree (buffer);
+ fprintf (stderr, "emacs: ");
+ vfprintf (stderr, str, ap);
+ if (!(strlen (str) > 0 && str[strlen (str) - 1] == '\n'))
+ fprintf (stderr, "\n");
+ va_end (ap);
+ fflush (stderr);
+ exit (1);
+}
+
+/* Auxiliary error-handling function for init_tty.
+ Delete TERMINAL, then call error or fatal with str1 or str2,
+ respectively, according to MUST_SUCCEED. */
+
+static void
+maybe_fatal (int must_succeed, struct terminal *terminal,
+ const char *str1, const char *str2, ...)
+{
+ va_list ap;
+ va_start (ap, str2);
if (terminal)
delete_tty (terminal);
if (must_succeed)
- fatal (str2, arg1, arg2);
+ vfatal (str2, ap);
else
- error (str1, arg1, arg2);
+ verror (str1, ap);
+ va_end (ap);
abort ();
}
{
va_list ap;
va_start (ap, str);
- fprintf (stderr, "emacs: ");
- vfprintf (stderr, str, ap);
+ vfatal (str, ap);
va_end (ap);
- fflush (stderr);
- exit (1);
}
\f
delete_tty (struct terminal *terminal)
{
struct tty_display_info *tty;
- Lisp_Object tail, frame;
- int last_terminal;
- /* Protect against recursive calls. Fdelete_frame in
+ /* Protect against recursive calls. delete_frame in
delete_terminal calls us back when it deletes our last frame. */
if (!terminal->name)
return;
tty = terminal->display_info.tty;
- last_terminal = 1;
- FOR_EACH_FRAME (tail, frame)
- {
- struct frame *f = XFRAME (frame);
- if (FRAME_LIVE_P (f) && (!FRAME_TERMCAP_P (f) || FRAME_TTY (f) != tty))
- {
- last_terminal = 0;
- break;
- }
- }
- if (last_terminal)
- error ("Attempt to delete the sole terminal device with live frames");
-
if (tty == tty_list)
tty_list = tty->next;
else
delete_terminal (terminal);
- if (tty->name)
- xfree (tty->name);
-
- if (tty->type)
- xfree (tty->type);
+ xfree (tty->name);
+ xfree (tty->type);
if (tty->input)
{
if (tty->termscript)
fclose (tty->termscript);
- if (tty->old_tty)
- xfree (tty->old_tty);
+ xfree (tty->old_tty);
+ xfree (tty->Wcm);
+ xfree (tty->termcap_strings_buffer);
+ xfree (tty->termcap_term_buffer);
- if (tty->Wcm)
- xfree (tty->Wcm);
-
- bzero (tty, sizeof (struct tty_display_info));
+ memset (tty, 0, sizeof (struct tty_display_info));
xfree (tty);
}
\f
void
-syms_of_term ()
+syms_of_term (void)
{
- DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo,
+ DEFVAR_BOOL ("system-uses-terminfo", system_uses_terminfo,
doc: /* Non-nil means the system uses terminfo rather than termcap.
This variable can be used by terminal emulator packages. */);
#ifdef TERMINFO
system_uses_terminfo = 0;
#endif
- DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions,
+ DEFVAR_LISP ("suspend-tty-functions", Vsuspend_tty_functions,
doc: /* Functions to be run after suspending a tty.
-The functions are run with one argument, the terminal id to be suspended.
+The functions are run with one argument, the terminal object to be suspended.
See `suspend-tty'. */);
Vsuspend_tty_functions = Qnil;
- DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions,
+ DEFVAR_LISP ("resume-tty-functions", Vresume_tty_functions,
doc: /* Functions to be run after resuming a tty.
-The functions are run with one argument, the terminal id that was revived.
+The functions are run with one argument, the terminal object that was revived.
See `resume-tty'. */);
Vresume_tty_functions = Qnil;
- DEFVAR_BOOL ("visible-cursor", &visible_cursor,
+ DEFVAR_BOOL ("visible-cursor", visible_cursor,
doc: /* Non-nil means to make the cursor very visible.
This only has an effect when running in a text terminal.
What means \"very visible\" is up to your terminal. It may make the cursor
#ifdef HAVE_GPM
defsubr (&Sgpm_mouse_start);
defsubr (&Sgpm_mouse_stop);
-
- staticpro (&mouse_face_window);
#endif /* HAVE_GPM */
-}
-
+#ifndef DOS_NT
+ default_orig_pair = NULL;
+ default_set_foreground = NULL;
+ default_set_background = NULL;
+#endif /* !DOS_NT */
-/* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
- (do not change this comment) */
+ encode_terminal_src = NULL;
+ encode_terminal_dst = NULL;
+}