/* 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
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <signal.h>
#include <stdarg.h>
+#include <setjmp.h>
#include "lisp.h"
#include "termchar.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
+extern void tputs (const char *, int, int (*)(int));
+extern int tgetent (char *, const char *);
+extern int tgetflag (char *id);
+extern int tgetnum (char *id);
#include "cm.h"
#ifdef HAVE_X_WINDOWS
#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 *);
#define OUTPUT(tty, a) \
emacs_tputs ((tty), a, \
char *tparam ();
-extern char *tgetstr ();
+extern char *tgetstr (char *, char **);
\f
#ifdef HAVE_GPM
#include <sys/fcntl.h>
-static void term_clear_mouse_face ();
+static void term_clear_mouse_face (void);
static void term_mouse_highlight (struct frame *f, int x, int y);
/* The device for which we have enabled gpm support (or NULL). */
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;
if (src->u.cmp.automatic)
{
gstring = composition_gstring_from_id (src->u.cmp.id);
- required = src->u.cmp.to - src->u.cmp.from;
+ required = src->u.cmp.to + 1 - src->u.cmp.from;
}
else
{
}
if (src->u.cmp.automatic)
- for (i = src->u.cmp.from; i < src->u.cmp.to; i++)
+ for (i = src->u.cmp.from; i <= src->u.cmp.to; i++)
{
Lisp_Object g = LGSTRING_GLYPH (gstring, i);
int c = LGLYPH_CHAR (g);
if (! char_charset (c, charset_list, NULL))
- break;
+ c = '?';
buf += CHAR_STRING (c, buf);
nchars++;
}
{
int c = COMPOSITION_GLYPH (cmp, i);
- if (! char_charset (c, charset_list, NULL))
- break;
+ 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++;
}
- if (i == 0)
- {
- /* The first character of the composition is not encodable. */
- *buf++ = '?';
- nchars++;
- }
}
/* We must skip glyphs to be padded for a wide character. */
else if (! CHAR_GLYPH_PADDING_P (*src))
#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;
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 ();
+ extern Lisp_Object Fidentity (Lisp_Object);
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;
#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 *);
/* 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. */
if (unibyte_display_via_language_environment
&& (it->c >= 0240))
{
- it->char_to_display = unibyte_char_to_multibyte (it->c);
+ it->char_to_display = BYTE8_TO_CHAR (it->c);
it->pixel_width = CHAR_WIDTH (it->char_to_display);
it->nglyphs = it->pixel_width;
if (it->glyph_row)
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_it.id;
glyph->u.cmp.automatic = 1;
glyph->u.cmp.id = it->cmp_it.id;
glyph->u.cmp.from = it->cmp_it.from;
- glyph->u.cmp.to = it->cmp_it.to;
+ glyph->u.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)
{
int c;
{
struct composition *cmp = composition_table[it->cmp_it.id];
- c = COMPOSITION_GLYPH (cmp, 0);
- it->pixel_width = CHAR_WIDTH (it->c);
+ it->pixel_width = cmp->width;
}
else
{
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;
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);
}
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 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. */)
(terminal)
Lisp_Object terminal;
{
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 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. */)
(terminal)
Lisp_Object terminal;
{
}
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;
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;
Returns NULL if the named terminal device is not opened. */
struct terminal *
-get_named_tty (name)
- char *name;
+get_named_tty (char *name)
{
struct terminal *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 can be a terminal object, a frame, or nil (meaning the
+selected frame's terminal). */)
(terminal)
Lisp_Object terminal;
{
DEFUN ("controlling-tty-p", Fcontrolling_tty_p, Scontrolling_tty_p, 0, 1, 0,
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 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. */)
(terminal)
Lisp_Object terminal;
{
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 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. */)
(terminal)
Lisp_Object terminal;
{
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
`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 may be a terminal object, a frame, or nil (meaning the selected
+frame's terminal). */)
(tty)
Lisp_Object tty;
{
#endif
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);
}
static void
-term_clear_mouse_face ()
+term_clear_mouse_face (void)
{
if (!NILP (mouse_face_window))
term_show_mouse_face (DRAW_NORMAL_TEXT);
mouse_face_face_id
= face_at_buffer_position (w, pos, 0, 0,
- &ignore, pos + 1, 1);
+ &ignore, pos + 1, 1, -1);
/* Display it as active. */
term_show_mouse_face (DRAW_MOUSE_FACE);
mouse_face_face_id
= face_at_buffer_position (w, pos, 0, 0,
- &ignore, pos + 1, 1);
+ &ignore, pos + 1, 1, -1);
/* Display it as active. */
term_show_mouse_face (DRAW_MOUSE_FACE);
}
void
-close_gpm ()
+close_gpm (int fd)
{
- if (gpm_fd >= 0)
- delete_gpm_wait_descriptor (gpm_fd);
+ if (fd >= 0)
+ delete_gpm_wait_descriptor (fd);
while (Gpm_Close()); /* close all the stack */
gpm_tty = NULL;
}
if (!tty || gpm_tty != tty)
return Qnil; /* Not activated on this terminal, nothing to do. */
- close_gpm ();
+ close_gpm (gpm_fd);
return Qnil;
}
#endif /* HAVE_GPM */
\f
+#ifndef MSDOS
/***********************************************************************
Initialization
***********************************************************************/
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;
}
EMACS_GET_TTY_PGRP (fd, &pgid); /* If tcgetpgrp succeeds, fd is the ctty. */
if (pgid != -1)
{
-#if defined (USG) && !defined (BSD_PGRPS)
+#if defined (USG)
setpgrp ();
no_controlling_tty = 1;
#elif defined (CYGWIN)
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, terminal,
"Could not open file: %s",
#endif
file = fdopen (fd, "w+");
- tty->name = xstrdup (name);
- terminal->name = xstrdup (name);
tty->input = file;
tty->output = file;
}
tty->type = xstrdup (terminal_type);
-#ifdef subprocesses
add_keyboard_wait_descriptor (fileno (tty->input));
-#endif
#endif /* !DOS_NT */
tty->output = stdout;
tty->input = stdin;
/* The following two are inaccessible from w32console.c. */
- terminal->delete_frame_hook = &delete_tty_output;
+ terminal->delete_frame_hook = &tty_free_frame_resources;
terminal->delete_terminal_hook = &delete_tty;
tty->name = xstrdup (name);
}
if (status == 0)
{
-#ifdef TERMINFO
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, 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
"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");
if (!tty->TS_bell)
{
maybe_fatal (must_succeed, terminal,
"Terminal type \"%s\" is not powerful enough to run Emacs",
-# 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 */
terminal_type);
}
va_start (ap, str);
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);
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
xfree (tty->old_tty);
xfree (tty->Wcm);
- if (tty->termcap_strings_buffer)
- xfree (tty->termcap_strings_buffer);
- if (tty->termcap_term_buffer)
- xfree (tty->termcap_term_buffer);
+ xfree (tty->termcap_strings_buffer);
+ xfree (tty->termcap_term_buffer);
bzero (tty, sizeof (struct tty_display_info));
xfree (tty);
\f
void
-syms_of_term ()
+syms_of_term (void)
{
DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo,
doc: /* Non-nil means the system uses terminfo rather than termcap.
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,
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;