/* 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 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
This file is part of GNU Emacs.
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
#endif
#include <signal.h>
+#include <stdarg.h>
+#include <setjmp.h>
#include "lisp.h"
#include "termchar.h"
#include "termopts.h"
+#include "buffer.h"
+#include "character.h"
#include "charset.h"
#include "coding.h"
+#include "composite.h"
#include "keyboard.h"
#include "frame.h"
#include "disptab.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
#ifdef HAVE_X_WINDOWS
#include "xterm.h"
#endif
-#ifdef MAC_OS
-#include "macterm.h"
-#endif
#ifndef O_RDWR
#define O_RDWR 2
#define O_NOCTTY 0
#endif
+/* The name of the default console device. */
+#ifdef WINDOWSNT
+#define DEV_TTY "CONOUT$"
+#else
+#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));
char *tparam ();
extern char *tgetstr ();
-
-static void term_clear_mouse_face ();
-static void term_mouse_highlight (struct frame *f, int x, int y);
\f
-#ifdef WINDOWSNT
-/* We aren't X windows, but we aren't termcap either. This makes me
- uncertain as to what value to use for frame.output_method. For
- this file, we'll define FRAME_TERMCAP_P to be zero so that our
- output hooks get called instead of the termcap functions. Probably
- the best long-term solution is to define an output_windows_nt... */
-
-#undef FRAME_TERMCAP_P
-#define FRAME_TERMCAP_P(_f_) 0
-#endif /* WINDOWSNT */
-
#ifdef HAVE_GPM
#include <sys/fcntl.h>
-#include "buffer.h"
-/* Nonzero means mouse is enabled on Linux console. */
-int term_gpm = 0;
+static void term_clear_mouse_face ();
+static void term_mouse_highlight (struct frame *f, int x, int y);
-/* The id of the terminal device for which we have gpm support. */
-int gpm_tty;
+/* 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
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 Qmouse_face_window;
+static Lisp_Object mouse_face_window;
static int mouse_face_face_id;
static int pos_x, pos_y;
tty_set_terminal_modes (struct terminal *terminal)
{
struct tty_display_info *tty = terminal->display_info.tty;
-
+
if (tty->output)
{
if (tty->TS_termcap_modes)
}
}
\f
-/* Buffer to store the source and result of code conversion for terminal. */
-static unsigned char *encode_terminal_buf;
-/* Allocated size of the above buffer. */
-static int encode_terminal_bufsize;
+/* Buffers to store the source and result of code conversion for terminal. */
+static unsigned char *encode_terminal_src;
+static unsigned char *encode_terminal_dst;
+/* Allocated sizes of the above buffers. */
+static int encode_terminal_src_size;
+static int encode_terminal_dst_size;
/* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
Set CODING->produced to the byte-length of the resulting byte
struct coding_system *coding;
{
struct glyph *src_end = src + src_len;
- register GLYPH g;
unsigned char *buf;
int nchars, nbytes, required;
register int tlen = GLYPH_TABLE_LENGTH;
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
+ Lisp_Object charset_list;
/* Allocate sufficient size of buffer to store all characters in
multibyte-form. But, it may be enlarged on demand if
- Vglyph_table contains a string. */
+ Vglyph_table contains a string or a composite glyph is
+ encountered. */
required = MAX_MULTIBYTE_LENGTH * src_len;
- if (encode_terminal_bufsize < required)
+ if (encode_terminal_src_size < required)
{
- if (encode_terminal_bufsize == 0)
- encode_terminal_buf = xmalloc (required);
+ if (encode_terminal_src)
+ encode_terminal_src = xrealloc (encode_terminal_src, required);
else
- encode_terminal_buf = xrealloc (encode_terminal_buf, required);
- encode_terminal_bufsize = required;
+ encode_terminal_src = xmalloc (required);
+ encode_terminal_src_size = required;
}
- buf = encode_terminal_buf;
+ charset_list = coding_charset_list (coding);
+
+ buf = encode_terminal_src;
nchars = 0;
while (src < src_end)
{
+ if (src->type == COMPOSITE_GLYPH)
+ {
+ struct composition *cmp;
+ Lisp_Object gstring;
+ int i;
+
+ nbytes = buf - encode_terminal_src;
+ if (src->u.cmp.automatic)
+ {
+ gstring = composition_gstring_from_id (src->u.cmp.id);
+ required = src->u.cmp.to + 1 - src->u.cmp.from;
+ }
+ else
+ {
+ cmp = composition_table[src->u.cmp.id];
+ required = MAX_MULTIBYTE_LENGTH * cmp->glyph_len;
+ }
+
+ if (encode_terminal_src_size < nbytes + required)
+ {
+ encode_terminal_src_size = nbytes + required;
+ encode_terminal_src = xrealloc (encode_terminal_src,
+ encode_terminal_src_size);
+ buf = encode_terminal_src + nbytes;
+ }
+
+ if (src->u.cmp.automatic)
+ 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))
+ 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. */
- if (! CHAR_GLYPH_PADDING_P (*src))
+ else if (! CHAR_GLYPH_PADDING_P (*src))
{
- g = GLYPH_FROM_CHAR_GLYPH (src[0]);
+ GLYPH g;
+ int c;
+ Lisp_Object string;
- if (g < 0 || g >= tlen)
+ string = Qnil;
+ SET_GLYPH_FROM_CHAR_GLYPH (g, src[0]);
+
+ if (GLYPH_INVALID_P (g) || GLYPH_SIMPLE_P (tbase, tlen, g))
{
- /* This glyph doesn't has an entry in Vglyph_table. */
- if (CHAR_VALID_P (src->u.ch, 0))
- buf += CHAR_STRING (src->u.ch, buf);
- else
- *buf++ = SPACEGLYPH;
- nchars++;
+ /* This glyph doesn't have an entry in Vglyph_table. */
+ c = src->u.ch;
}
else
{
GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
if (GLYPH_SIMPLE_P (tbase, tlen, g))
- {
- int c = FAST_GLYPH_CHAR (g);
+ /* We set the multi-byte form of a character in G
+ (that should be an ASCII character) at WORKBUF. */
+ c = GLYPH_CHAR (g);
+ else
+ /* We have a string in Vglyph_table. */
+ string = tbase[GLYPH_CHAR (g)];
+ }
- if (CHAR_VALID_P (c, 0))
- buf += CHAR_STRING (c, buf);
- else
- *buf++ = SPACEGLYPH;
+ if (NILP (string))
+ {
+ nbytes = buf - encode_terminal_src;
+ if (encode_terminal_src_size < nbytes + MAX_MULTIBYTE_LENGTH)
+ {
+ encode_terminal_src_size = nbytes + MAX_MULTIBYTE_LENGTH;
+ encode_terminal_src = xrealloc (encode_terminal_src,
+ encode_terminal_src_size);
+ buf = encode_terminal_src + nbytes;
+ }
+ if (char_charset (c, charset_list, NULL))
+ {
+ /* Store the multibyte form of C at BUF. */
+ buf += CHAR_STRING (c, buf);
nchars++;
}
else
{
- /* We have a string in Vglyph_table. */
- Lisp_Object string;
-
- string = tbase[g];
- if (! STRING_MULTIBYTE (string))
- string = string_to_multibyte (string);
- nbytes = buf - encode_terminal_buf;
- if (encode_terminal_bufsize < nbytes + SBYTES (string))
+ /* C is not encodable. */
+ *buf++ = '?';
+ nchars++;
+ while (src + 1 < src_end && CHAR_GLYPH_PADDING_P (src[1]))
{
- encode_terminal_bufsize = nbytes + SBYTES (string);
- encode_terminal_buf = xrealloc (encode_terminal_buf,
- encode_terminal_bufsize);
- buf = encode_terminal_buf + nbytes;
+ *buf++ = '?';
+ nchars++;
+ src++;
}
- bcopy (SDATA (string), buf, SBYTES (string));
- buf += SBYTES (string);
- nchars += SCHARS (string);
}
}
+ else
+ {
+ unsigned char *p = SDATA (string), *pend = p + SBYTES (string);
+
+ if (! STRING_MULTIBYTE (string))
+ string = string_to_multibyte (string);
+ nbytes = buf - encode_terminal_src;
+ if (encode_terminal_src_size < nbytes + SBYTES (string))
+ {
+ encode_terminal_src_size = nbytes + SBYTES (string);
+ encode_terminal_src = xrealloc (encode_terminal_src,
+ encode_terminal_src_size);
+ buf = encode_terminal_src + nbytes;
+ }
+ bcopy (SDATA (string), buf, SBYTES (string));
+ buf += SBYTES (string);
+ nchars += SCHARS (string);
+ }
}
src++;
}
- nbytes = buf - encode_terminal_buf;
- coding->src_multibyte = 1;
- coding->dst_multibyte = 0;
- if (SYMBOLP (coding->pre_write_conversion)
- && ! NILP (Ffboundp (coding->pre_write_conversion)))
+ if (nchars == 0)
{
- run_pre_write_conversin_on_c_str (&encode_terminal_buf,
- &encode_terminal_bufsize,
- nchars, nbytes, coding);
- nchars = coding->produced_char;
- nbytes = coding->produced;
+ coding->produced = 0;
+ return NULL;
}
- required = nbytes + encoding_buffer_size (coding, nbytes);
- if (encode_terminal_bufsize < required)
+
+ nbytes = buf - encode_terminal_src;
+ coding->source = encode_terminal_src;
+ if (encode_terminal_dst_size == 0)
{
- encode_terminal_bufsize = required;
- encode_terminal_buf = xrealloc (encode_terminal_buf, required);
+ encode_terminal_dst_size = encode_terminal_src_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;
+ encode_coding_object (coding, Qnil, 0, 0, nchars, nbytes, Qnil);
+ /* coding->destination may have been reallocated. */
+ encode_terminal_dst = coding->destination;
+ encode_terminal_dst_size = coding->dst_bytes;
- encode_coding (coding, encode_terminal_buf, encode_terminal_buf + nbytes,
- nbytes, encode_terminal_bufsize - nbytes);
- return encode_terminal_buf + nbytes;
+ return (encode_terminal_dst);
}
+
/* An implementation of write_glyphs for termcap frames. */
static void
cmcheckmagic (tty);
}
+#ifdef HAVE_GPM /* Only used by GPM code. */
+
static void
tty_write_glyphs_with_face (f, string, len, face_id)
register struct frame *f;
cmcheckmagic (tty);
}
-
+#endif
/* An implementation of insert_glyphs for termcap frames. */
if (!FRAME_MEMORY_BELOW_FRAME (f)
&& vpos + i >= FRAME_LINES (f))
return;
-
+
if (multi)
{
raw_cursor_to (f, vpos, 0);
OUTPUTL (tty, scroll, tty->specified_window - vpos);
tty_set_scroll_region (f, 0, tty->specified_window);
}
-
+
if (!FRAME_SCROLL_REGION_OK (f)
&& FRAME_MEMORY_BELOW_FRAME (f)
&& n < 0)
static KBOARD *term_get_fkeys_kboard;
static Lisp_Object term_get_fkeys_1 ();
-/* Find the escape codes sent by the function keys for Vfunction_key_map.
+/* 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 Vfunction_key_map for each function key it finds. */
+ adds entries to Vinput_decode_map for each function key it finds. */
static void
term_get_fkeys (address, kboard)
char **address = term_get_fkeys_address;
KBOARD *kboard = term_get_fkeys_kboard;
-
+
/* This can happen if CANNOT_DUMP or with strange options. */
- if (!initialized)
- kboard->Vlocal_function_key_map = Fmake_sparse_keymap (Qnil);
+ if (!KEYMAPP (kboard->Vinput_decode_map))
+ kboard->Vinput_decode_map = Fmake_sparse_keymap (Qnil);
for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++)
{
char *sequence = tgetstr (keys[i].cap, address);
if (sequence)
- Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence),
+ Fdefine_key (kboard->Vinput_decode_map, build_string (sequence),
Fmake_vector (make_number (1),
intern (keys[i].name)));
}
if (k0)
/* Define f0 first, so that f10 takes precedence in case the
key sequences happens to be the same. */
- Fdefine_key (kboard->Vlocal_function_key_map, build_string (k0),
+ Fdefine_key (kboard->Vinput_decode_map, build_string (k0),
Fmake_vector (make_number (1), intern ("f0")));
- Fdefine_key (kboard->Vlocal_function_key_map, build_string (k_semi),
+ Fdefine_key (kboard->Vinput_decode_map, build_string (k_semi),
Fmake_vector (make_number (1), intern ("f10")));
}
else if (k0)
- Fdefine_key (kboard->Vlocal_function_key_map, build_string (k0),
+ Fdefine_key (kboard->Vinput_decode_map, build_string (k0),
Fmake_vector (make_number (1), intern (k0_name)));
}
if (sequence)
{
sprintf (fkey, "f%d", i);
- Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence),
+ Fdefine_key (kboard->Vinput_decode_map, build_string (sequence),
Fmake_vector (make_number (1),
intern (fkey)));
}
{ \
char *sequence = tgetstr (cap2, address); \
if (sequence) \
- Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence), \
+ Fdefine_key (kboard->Vinput_decode_map, build_string (sequence), \
Fmake_vector (make_number (1), \
intern (sym))); \
}
#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 *));
/* Append glyphs to IT's glyph_row. Called from produce_glyphs for
terminal frames if IT->glyph_row != NULL. IT->char_to_display is
struct it *it;
{
/* If a hook is installed, let it do the work. */
+
+ /* Nothing but characters are supported on terminal frames. */
xassert (it->what == IT_CHARACTER
|| it->what == IT_COMPOSITION
|| it->what == IT_STRETCH);
goto done;
}
- /* Nothing but characters are supported on terminal frames. For a
- composition sequence, it->c is the first character of the
- sequence. */
- xassert (it->what == IT_CHARACTER
- || it->what == IT_COMPOSITION);
+ if (it->what == IT_COMPOSITION)
+ {
+ produce_composite_glyph (it);
+ goto done;
+ }
/* Maybe translate single-byte characters to multibyte. */
it->char_to_display = it->c;
it->pixel_width = nspaces;
it->nglyphs = nspaces;
}
- else if (SINGLE_BYTE_CHAR_P (it->c))
+ else if (CHAR_BYTE8_P (it->c))
{
if (unibyte_display_via_language_environment
- && (it->c >= 0240
- || !NILP (Vnonascii_translation_table)))
+ && (it->c >= 0240))
{
- int charset;
-
- it->char_to_display = unibyte_char_to_multibyte (it->c);
- charset = CHAR_CHARSET (it->char_to_display);
- it->pixel_width = CHARSET_WIDTH (charset);
+ 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)
append_glyph (it);
}
else
{
- /* Coming here means that it->c is from display table, thus we
- must send the code as is to the terminal. Although there's
- no way to know how many columns it occupies on a screen, it
- is a good assumption that a single byte code has 1-column
- width. */
+ /* 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
{
- /* A multi-byte character. The display width is fixed for all
- characters of the set. Some of the glyphs may have to be
- ignored because they are already displayed in a continued
- line. */
- int charset = CHAR_CHARSET (it->c);
-
- it->pixel_width = CHARSET_WIDTH (charset);
+ it->pixel_width = CHAR_WIDTH (it->c);
it->nglyphs = it->pixel_width;
if (it->glyph_row)
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;
}
+/* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
+ Called from produce_composite_glyph for terminal frames if
+ IT->glyph_row != NULL. IT->face_id contains the character's
+ face. */
+
+static void
+append_composite_glyph (it)
+ struct it *it;
+{
+ struct glyph *glyph;
+
+ xassert (it->glyph_row);
+ glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area];
+ if (glyph < it->glyph_row->glyphs[1 + it->area])
+ {
+ glyph->type = COMPOSITE_GLYPH;
+ glyph->pixel_width = it->pixel_width;
+ 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->u.cmp.from = it->cmp_it.from;
+ 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;
+
+ ++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 the terminal has a capability to layout/render it
+ correctly. */
+
+static void
+produce_composite_glyph (it)
+ struct it *it;
+{
+ int c;
+
+ if (it->cmp_it.ch < 0)
+ {
+ struct composition *cmp = composition_table[it->cmp_it.id];
+
+ 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);
+}
+
+
/* 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
enum display_element_type what;
{
struct it temp_it;
+ Lisp_Object gc;
GLYPH glyph;
temp_it = *it;
if (what == IT_CONTINUATION)
{
/* Continuation glyph. */
+ SET_GLYPH_FROM_CHAR (glyph, '\\');
if (it->dp
- && INTEGERP (DISP_CONTINUE_GLYPH (it->dp))
- && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it->dp))))
+ && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc))
+ && GLYPH_CODE_CHAR_VALID_P (gc))
{
- glyph = XINT (DISP_CONTINUE_GLYPH (it->dp));
- glyph = spec_glyph_lookup_face (XWINDOW (it->window), glyph);
+ SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
+ spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
}
- else
- glyph = '\\';
}
else if (what == IT_TRUNCATION)
{
/* Truncation glyph. */
+ SET_GLYPH_FROM_CHAR (glyph, '$');
if (it->dp
- && INTEGERP (DISP_TRUNC_GLYPH (it->dp))
- && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it->dp))))
+ && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc))
+ && GLYPH_CODE_CHAR_VALID_P (gc))
{
- glyph = XINT (DISP_TRUNC_GLYPH (it->dp));
- glyph = spec_glyph_lookup_face (XWINDOW (it->window), glyph);
+ SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
+ spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
}
- else
- glyph = '$';
}
else
abort ();
- temp_it.c = FAST_GLYPH_CHAR (glyph);
- temp_it.face_id = FAST_GLYPH_FACE (glyph);
+ temp_it.c = GLYPH_CHAR (glyph);
+ temp_it.face_id = GLYPH_FACE (glyph);
temp_it.len = CHAR_BYTES (temp_it.c);
produce_glyphs (&temp_it);
}
}
- 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
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;
{
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
+ http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
+static int default_max_colors;
+static int default_max_pairs;
+static int default_no_color_video;
+static char *default_orig_pair;
+static char *default_set_foreground;
+static char *default_set_background;
/* Save or restore the default color-related capabilities of this
terminal. */
static void
tty_default_color_capabilities (struct tty_display_info *tty, int save)
{
- static char
- *default_orig_pair, *default_set_foreground, *default_set_background;
- static int default_max_colors, default_max_pairs, default_no_color_video;
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 (f, val)
+set_tty_color_mode (tty, f)
+ struct tty_display_info *tty;
struct frame *f;
- Lisp_Object val;
{
- Lisp_Object color_mode_spec, current_mode_spec;
- Lisp_Object color_mode, current_mode;
- int mode, old_mode;
+ Lisp_Object tem, val, color_mode_spec;
+ Lisp_Object color_mode;
+ int mode;
extern Lisp_Object Qtty_color_mode;
- Lisp_Object tty_color_mode_alist;
+ Lisp_Object tty_color_mode_alist
+ = Fintern_soft (build_string ("tty-color-mode-alist"), Qnil);
- tty_color_mode_alist = Fintern_soft (build_string ("tty-color-mode-alist"),
- Qnil);
+ tem = assq_no_quit (Qtty_color_mode, f->param_alist);
+ val = CONSP (tem) ? XCDR (tem) : Qnil;
if (INTEGERP (val))
color_mode = val;
else
{
- if (NILP (tty_color_mode_alist))
- color_mode_spec = Qnil;
- else
- color_mode_spec = Fassq (val, XSYMBOL (tty_color_mode_alist)->value);
-
- if (CONSP (color_mode_spec))
- color_mode = XCDR (color_mode_spec);
- else
- color_mode = Qnil;
+ tem = (NILP (tty_color_mode_alist) ? Qnil
+ : Fassq (val, XSYMBOL (tty_color_mode_alist)->value));
+ color_mode = CONSP (tem) ? XCDR (tem) : Qnil;
}
- current_mode_spec = assq_no_quit (Qtty_color_mode, f->param_alist);
-
- if (CONSP (current_mode_spec))
- current_mode = XCDR (current_mode_spec);
- else
- current_mode = Qnil;
- if (INTEGERP (color_mode))
- mode = XINT (color_mode);
- else
- mode = 0; /* meaning default */
- if (INTEGERP (current_mode))
- old_mode = XINT (current_mode);
- else
- old_mode = 0;
+ mode = INTEGERP (color_mode) ? XINT (color_mode) : 0;
- if (mode != old_mode)
+ if (mode != tty->previous_color_mode)
{
- tty_setup_colors (FRAME_TTY (f), mode);
- /* This recomputes all the faces given the new color
- definitions. */
- call0 (intern ("tty-set-up-initial-frame-faces"));
- redraw_frame (f);
+ Lisp_Object funsym = intern ("tty-set-up-initial-frame-faces");
+ tty->previous_color_mode = mode;
+ tty_setup_colors (tty , mode);
+ /* This recomputes all the faces given the new color definitions. */
+ safe_call (1, &funsym);
}
}
-#endif /* !WINDOWSNT */
+#endif /* !DOS_NT */
\f
{
struct terminal *t = get_terminal (terminal, throw);
- if (t && t->type == output_initial)
- return NULL;
-
- 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);
This function ignores suspended devices.
Returns NULL if the named terminal device is not opened. */
-
+
struct terminal *
get_named_tty (name)
char *name;
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 can be a terminal object, a frame, or nil (meaning the
+selected frame's terminal). */)
(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 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;
{
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 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
{
struct terminal *t = get_tty_terminal (tty, 1);
FILE *f;
-
+
if (!t)
error ("Unknown tty device");
f = t->display_info.tty->input;
-
+
if (f)
{
+ /* First run `suspend-tty-functions' and then clean up the tty
+ state because `suspend-tty-functions' might need to change
+ the tty state. */
+ if (!NILP (Vrun_hooks))
+ {
+ Lisp_Object args[2];
+ args[0] = intern ("suspend-tty-functions");
+ XSETTERMINAL (args[1], t);
+ Frun_hook_with_args (2, args);
+ }
+
reset_sys_modes (t->display_info.tty);
+#ifdef subprocesses
delete_keyboard_wait_descriptor (fileno (f));
-
+#endif
+
+#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;
if (FRAMEP (t->display_info.tty->top_frame))
FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 0);
-
- /* Run `suspend-tty-functions'. */
- if (!NILP (Vrun_hooks))
- {
- Lisp_Object args[2];
- args[0] = intern ("suspend-tty-functions");
- args[1] = make_number (t->id);
- Frun_hook_with_args (2, args);
- }
+
}
/* Clear display hooks to prevent further output. */
`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;
{
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)
error ("Can not reopen tty device %s: %s", t->display_info.tty->name, strerror (errno));
- if (strcmp (t->display_info.tty->name, "/dev/tty"))
+ if (strcmp (t->display_info.tty->name, DEV_TTY))
dissociate_if_controlling_tty (fd);
-
+
t->display_info.tty->output = fdopen (fd, "w+");
t->display_info.tty->input = t->display_info.tty->output;
-
+#endif
+
+#ifdef subprocesses
add_keyboard_wait_descriptor (fd);
+#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);
- /* Run `suspend-tty-functions'. */
+ /* Run `resume-tty-functions'. */
if (!NILP (Vrun_hooks))
{
Lisp_Object args[2];
args[0] = intern ("resume-tty-functions");
- args[1] = make_number (t->id);
+ XSETTERMINAL (args[1], t);
Frun_hook_with_args (2, args);
}
}
static void
term_show_mouse_face (enum draw_glyphs_face draw)
{
- struct window *w = XWINDOW (Qmouse_face_window);
+ struct window *w = XWINDOW (mouse_face_window);
int save_x, save_y;
int i;
/* 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);
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)
static void
term_clear_mouse_face ()
{
- if (!NILP (Qmouse_face_window))
+ 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;
- Qmouse_face_window = Qnil;
+ mouse_face_window = Qnil;
}
/* Find the glyph matrix position of buffer position POS in window W.
if (!WINDOWP (window))
return;
- if (!EQ (window, Qmouse_face_window))
+ if (!EQ (window, mouse_face_window))
term_clear_mouse_face ();
w = XWINDOW (window);
noverlays = sort_overlays (overlay_vec, noverlays, w);
/* Check mouse-face highlighting. */
- if (!(EQ (window, Qmouse_face_window)
+ if (!(EQ (window, mouse_face_window)
&& y >= mouse_face_beg_row
&& y <= mouse_face_end_row
&& (y > mouse_face_beg_row
/* Find the range of text around this char that
should be active. */
Lisp_Object before, after;
- int ignore;
+ EMACS_INT ignore;
before = Foverlay_start (overlay);
= !fast_find_position (w, XFASTINT (after),
&mouse_face_end_col,
&mouse_face_end_row);
- Qmouse_face_window = window;
+ mouse_face_window = window;
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);
/* Find the range of text around this char that
should be active. */
Lisp_Object before, after, beginning, end;
- int ignore;
+ EMACS_INT ignore;
beginning = Fmarker_position (w->start);
XSETINT (end, (BUF_Z (b) - XFASTINT (w->window_end_pos)));
= !fast_find_position (w, XFASTINT (after),
&mouse_face_end_col,
&mouse_face_end_row);
- Qmouse_face_window = window;
+ mouse_face_window = window;
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);
result->modifiers = down_modifier;
else
result->modifiers = 0;
-
+
if (event->type & GPM_SINGLE)
result->modifiers |= click_modifier;
-
+
if (event->type & GPM_DOUBLE)
result->modifiers |= double_modifier;
return Qnil;
}
-int
+int
handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event, struct input_event* hold_quit)
{
struct frame *f = XFRAME (tty->top_frame);
- int fd;
struct input_event ie;
int do_help = 0;
int count = 0;
ie.arg = Qnil;
if (event->type & (GPM_MOVE | GPM_DRAG)) {
- unsigned char buf[6 * sizeof (short)];
- unsigned short *arg = (unsigned short *) buf + 1;
- const char *name;
-
previous_help_echo_string = help_echo_string;
help_echo_string = Qnil;
- /* Display mouse pointer */
- buf[sizeof(short) - 1] = 2; /* set selection */
-
- arg[0] = arg[2] = (unsigned short) event->x + gpm_zerobased;
- arg[1] = arg[3] = (unsigned short) event->y + gpm_zerobased;
- arg[4] = (unsigned short) 3;
-
- name = ttyname (0);
- fd = open (name, O_WRONLY);
- ioctl (fd, TIOCLINUX, buf + sizeof (short) - 1);
- close (fd);
+ Gpm_DrawPointer (event->x, event->y, fileno (tty->output));
if (!term_mouse_movement (f, event))
help_echo_string = previous_help_echo_string;
return count;
}
-DEFUN ("term-open-connection", Fterm_open_connection, Sterm_open_connection,
+DEFUN ("gpm-mouse-start", Fgpm_mouse_start, Sgpm_mouse_start,
0, 0, 0,
- doc: /* Open a connection to Gpm. */)
+ doc: /* Open a connection to Gpm.
+Gpm-mouse can only be activated for one tty at a time. */)
()
{
- struct tty_display_info *tty = FRAME_TTY (SELECTED_FRAME ());
+ struct frame *f = SELECTED_FRAME ();
+ struct tty_display_info *tty
+ = ((f)->output_method == output_termcap
+ ? (f)->terminal->display_info.tty : NULL);
Gpm_Connect connection;
+ if (!tty)
+ error ("Gpm-mouse only works in the GNU/Linux console");
+ if (gpm_tty == tty)
+ return Qnil; /* Already activated, nothing to do. */
+ if (gpm_tty)
+ error ("Gpm-mouse can only be activated for one tty at a time");
+
connection.eventMask = ~0;
connection.defaultMask = ~GPM_HARD;
connection.maxMod = ~0;
connection.minMod = 0;
gpm_zerobased = 1;
- /* We only support GPM on the controlling tty. */
- if (term_gpm || tty->terminal->id > 1
- || Gpm_Open (&connection, 0) < 0)
- return Qnil;
+ if (Gpm_Open (&connection, 0) < 0)
+ error ("Gpm-mouse failed to connect to the gpm daemon");
else
{
- term_gpm = 1;
- gpm_tty = tty->terminal->id;
+ gpm_tty = tty;
+ /* `init_sys_modes' arranges for mouse movements sent through gpm_fd
+ to generate SIGIOs. Apparently we need to call reset_sys_modes
+ before calling init_sys_modes. */
reset_sys_modes (tty);
init_sys_modes (tty);
add_gpm_wait_descriptor (gpm_fd);
- return Qt;
+ return Qnil;
}
}
-DEFUN ("term-close-connection", Fterm_close_connection, Sterm_close_connection,
+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. */)
()
{
- delete_gpm_wait_descriptor (gpm_fd);
- while (Gpm_Close()); /* close all the stack */
- term_gpm = 0;
- return Qnil;
+ struct frame *f = SELECTED_FRAME ();
+ struct tty_display_info *tty
+ = ((f)->output_method == output_termcap
+ ? (f)->terminal->display_info.tty : NULL);
+
+ if (!tty || gpm_tty != tty)
+ return Qnil; /* Not activated on this terminal, nothing to do. */
+
+ 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. */
static void
clear_tty_hooks (struct terminal *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;
}
+/* Initialize hooks in TERMINAL with the values needed for a tty. */
+
static void
set_tty_hooks (struct terminal *terminal)
{
terminal->delete_glyphs_hook = &tty_delete_glyphs;
terminal->ring_bell_hook = &tty_ring_bell;
-
+
terminal->reset_terminal_modes_hook = &tty_reset_terminal_modes;
terminal->set_terminal_modes_hook = &tty_set_terminal_modes;
terminal->update_begin_hook = 0; /* Not needed. */
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
+#ifndef DOS_NT
int pgid;
EMACS_GET_TTY_PGRP (fd, &pgid); /* If tcgetpgrp succeeds, fd is the ctty. */
if (pgid != -1)
#if defined (USG) && !defined (BSD_PGRPS)
setpgrp ();
no_controlling_tty = 1;
+#elif defined (CYGWIN)
+ setsid ();
+ no_controlling_tty = 1;
#else
#ifdef TIOCNOTTY /* Try BSD ioctls. */
sigblock (sigmask (SIGTTOU));
- fd = emacs_open ("/dev/tty", O_RDWR, 0);
+ fd = emacs_open (DEV_TTY, O_RDWR, 0);
if (fd != -1 && ioctl (fd, TIOCNOTTY, 0) != -1)
{
no_controlling_tty = 1;
#endif /* ! TIOCNOTTY */
#endif /* ! USG */
}
-#endif
+#endif /* !DOS_NT */
}
static void maybe_fatal();
{
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");
-#ifndef WINDOWSNT
if (name == NULL)
- name = "/dev/tty";
- if (!strcmp (name, "/dev/tty"))
+ name = DEV_TTY;
+ if (!strcmp (name, DEV_TTY))
ctty = 1;
/* If we already have a terminal on the given device, use that. If
terminal = get_named_tty (name);
if (terminal)
return terminal;
-#endif
-
+
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));
+#endif
bzero (tty, 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
+#ifndef DOS_NT
set_tty_hooks (terminal);
-
+
{
int fd;
FILE *file;
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;
}
-
+
tty->type = xstrdup (terminal_type);
add_keyboard_wait_descriptor (fileno (tty->input));
-#endif
+#endif /* !DOS_NT */
- encode_terminal_bufsize = 0;
+ encode_terminal_src_size = 0;
+ encode_terminal_dst_size = 0;
#ifdef HAVE_GPM
terminal->mouse_position_hook = term_mouse_position;
- Qmouse_face_window = Qnil;
+ mouse_face_window = Qnil;
#endif
+#ifdef DOS_NT
#ifdef WINDOWSNT
- initialize_w32_display ();
+ initialize_w32_display (terminal);
+#else /* MSDOS */
+ if (strcmp (terminal_type, "internal") == 0)
+ terminal->type = output_msdos_raw;
+ initialize_msdos_display (terminal);
+#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;
- /* XXX Can this be non-null? */
- if (name)
- {
- tty->name = xstrdup (name);
- terminal->name = xstrdup (name);
- }
- tty->type = xstrdup (terminal_type);
+ tty->name = xstrdup (name);
+ terminal->name = xstrdup (name);
+ tty->type = xstrdup (terminal_type);
- /* XXX not sure if this line is correct. If it is not set then we
- crash in update_display_1. */
- tty->output = stdout;
-
- Wcm_clear (tty);
+#ifdef subprocesses
+ add_keyboard_wait_descriptor (0);
+#endif
- area = (char *) xmalloc (2044); /* XXX this seems unused. */
+ Wcm_clear (tty);
+#ifdef WINDOWSNT
{
struct frame *f = XFRAME (selected_frame);
- FrameRows (tty) = FRAME_LINES (f); /* XXX */
- FrameCols (tty) = FRAME_COLS (f); /* XXX */
- tty->specified_window = FRAME_LINES (f); /* XXX */
+ FrameRows (tty) = FRAME_LINES (f);
+ FrameCols (tty) = FRAME_COLS (f);
+ tty->specified_window = FRAME_LINES (f);
- FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; /* XXX */
- FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; /* XXX */
+ FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
+ FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
}
+#else /* MSDOS */
+ {
+ int height, width;
+ get_tty_size (fileno (tty->input), &width, &height);
+ FrameCols (tty) = width;
+ FrameRows (tty) = height;
+ }
+#endif /* MSDOS */
tty->delete_in_insert_mode = 1;
UseTabs (tty) = 0;
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;
+#ifdef WINDOWSNT
terminal->char_ins_del_ok = 1;
-
baud_rate = 19200;
+#else /* MSDOS */
+ terminal->char_ins_del_ok = 0;
+ init_baud_rate (fileno (tty->input));
+#endif /* MSDOS */
tty->TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
- return terminal;
-#else /* not WINDOWSNT */
+#else /* not DOS_NT */
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\
to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
terminal_type);
#else
- 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\
}
#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");
-#ifdef MULTI_KBOARD
+#endif /* !DOS_NT */
terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
init_kboard (terminal->kboard);
+ terminal->kboard->Vwindow_system = Qnil;
terminal->kboard->next_kboard = all_kboards;
all_kboards = terminal->kboard;
terminal->kboard->reference_count++;
prompt in the mini-buffer. */
if (current_kboard == initial_kboard)
current_kboard = terminal->kboard;
+#ifndef DOS_NT
term_get_fkeys (address, terminal->kboard);
-#endif
/* Get frame size from system, or else from termcap. */
{
FrameRows (tty) = tgetnum ("li");
if (FrameRows (tty) < 3 || FrameCols (tty) < 3)
- maybe_fatal (must_succeed, NULL, terminal,
+ 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\
`setenv TERM ...') to specify the correct type. It may be necessary\n\
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 DOS_NT */
/* Init system terminal modes (RAW or CBREAK, etc.). */
init_sys_modes (tty);
return terminal;
-#endif /* not WINDOWSNT */
}
/* 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. */
+ 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)
+maybe_fatal (must_succeed, terminal, str1, str2, arg1, arg2)
int must_succeed;
- char *buffer;
struct terminal *terminal;
char *str1, *str2, *arg1, *arg2;
{
- if (buffer)
- xfree (buffer);
-
if (terminal)
delete_tty (terminal);
-
+
if (must_succeed)
fatal (str2, arg1, arg2);
else
abort ();
}
-/* VARARGS 1 */
void
-fatal (str, arg1, arg2)
- char *str, *arg1, *arg2;
+fatal (const char *str, ...)
{
+ va_list ap;
+ va_start (ap, str);
fprintf (stderr, "emacs: ");
- fprintf (stderr, str, arg1, arg2);
- fprintf (stderr, "\n");
+ vfprintf (stderr, str, ap);
+ 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->deleted)
+ if (!terminal->name)
return;
if (terminal->type != output_termcap)
abort ();
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)
{
+#ifdef subprocesses
delete_keyboard_wait_descriptor (fileno (tty->input));
+#endif
if (tty->input != stdin)
fclose (tty->input);
}
if (tty->termscript)
fclose (tty->termscript);
- if (tty->old_tty)
- xfree (tty->old_tty);
-
- if (tty->Wcm)
- xfree (tty->Wcm);
+ xfree (tty->old_tty);
+ xfree (tty->Wcm);
+ xfree (tty->termcap_strings_buffer);
+ xfree (tty->termcap_term_buffer);
bzero (tty, sizeof (struct tty_display_info));
xfree (tty);
struct tty_display_info *tty;
for (tty = tty_list; tty; tty = tty->next)
- {
- if (tty->top_frame)
- mark_object (tty->top_frame);
- }
+ mark_object (tty->top_frame);
}
\f
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;
defsubr (&Ssuspend_tty);
defsubr (&Sresume_tty);
#ifdef HAVE_GPM
- defsubr (&Sterm_open_connection);
- defsubr (&Sterm_close_connection);
+ defsubr (&Sgpm_mouse_start);
+ defsubr (&Sgpm_mouse_stop);
- staticpro (&Qmouse_face_window);
+ 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 */
+
+ encode_terminal_src = NULL;
+ encode_terminal_dst = NULL;
}