/* Terminal control module for terminals described by TERMCAP
- Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2011
+ Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2012
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <ctype.h>
#include <errno.h>
#include <sys/file.h>
+#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
#include "termchar.h"
#include "termopts.h"
#include "tparam.h"
-#include "buffer.h"
#include "character.h"
+#include "buffer.h"
#include "charset.h"
#include "coding.h"
#include "composite.h"
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 ATTRIBUTE_FORMAT_PRINTF (3, 5) ATTRIBUTE_FORMAT_PRINTF (4, 5);
-static void vfatal (const char *str, va_list ap)
- NO_RETURN ATTRIBUTE_FORMAT_PRINTF (1, 0);
+static _Noreturn void maybe_fatal (int must_succeed, struct terminal *terminal,
+ const char *str1, const char *str2, ...)
+ ATTRIBUTE_FORMAT_PRINTF (3, 5) ATTRIBUTE_FORMAT_PRINTF (4, 5);
+static _Noreturn void vfatal (const char *str, va_list ap)
+ ATTRIBUTE_FORMAT_PRINTF (1, 0);
#define OUTPUT(tty, a) \
NC_STANDOUT = 1 << 0,
NC_UNDERLINE = 1 << 1,
NC_REVERSE = 1 << 2,
- NC_BLINK = 1 << 3,
+ NC_ITALIC = 1 << 3,
NC_DIM = 1 << 4,
NC_BOLD = 1 << 5,
NC_INVIS = 1 << 6,
- NC_PROTECT = 1 << 7,
- NC_ALT_CHARSET = 1 << 8
+ NC_PROTECT = 1 << 7
};
/* internal state */
struct glyph *glyph, *end;
int i;
- xassert (it->glyph_row);
+ eassert (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 a hook is installed, let it do the work. */
/* Nothing but characters are supported on terminal frames. */
- xassert (it->what == IT_CHARACTER
+ eassert (it->what == IT_CHARACTER
|| it->what == IT_COMPOSITION
|| it->what == IT_STRETCH
|| it->what == IT_GLYPHLESS);
{
Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
- xassert (it->what == IT_GLYPHLESS);
+ eassert (it->what == IT_GLYPHLESS);
produce_glyphless_glyph (it, 1, acronym);
}
}
{
struct glyph *glyph;
- xassert (it->glyph_row);
+ eassert (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])
{
struct glyph *glyph, *end;
int i;
- xassert (it->glyph_row);
+ eassert (it->glyph_row);
glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area];
end = it->glyph_row->glyphs[1 + it->area];
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
+ is not supported 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. */
len = 1;
else if (len > 4)
len = 4;
- sprintf (buf, "[%.*s]", len, str);
- len += 2;
+ len = sprintf (buf, "[%.*s]", len, str);
str = buf;
}
else
}
else
{
- xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
+ eassert (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));
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
- non-null glyph_row member. This function ensures that fields like
- face_id, c, len of IT are left untouched. */
-
-void
-produce_special_glyphs (struct it *it, enum display_element_type what)
-{
- struct it temp_it;
- Lisp_Object gc;
- GLYPH glyph;
-
- temp_it = *it;
- temp_it.dp = NULL;
- temp_it.what = IT_CHARACTER;
- temp_it.len = 1;
- temp_it.object = make_number (0);
- memset (&temp_it.current, 0, sizeof temp_it.current);
-
- if (what == IT_CONTINUATION)
- {
- /* 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)))
- {
- /* FIXME: Should we mirror GC for R2L lines? */
- SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
- spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
- }
- }
- else if (what == IT_TRUNCATION)
- {
- /* Truncation glyph. */
- SET_GLYPH_FROM_CHAR (glyph, '$');
- if (it->dp
- && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_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 = temp_it.char_to_display = GLYPH_CHAR (glyph);
- temp_it.face_id = GLYPH_FACE (glyph);
- temp_it.len = CHAR_BYTES (temp_it.c);
-
- produce_glyphs (&temp_it);
- it->pixel_width = temp_it.pixel_width;
- it->nglyphs = temp_it.pixel_width;
-}
-
-
\f
/***********************************************************************
Faces
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
- && MAY_USE_WITH_COLORS_P (tty, NC_ALT_CHARSET))
- OUTPUT1_IF (tty, tty->TS_enter_alt_charset_mode);
-
- if (face->tty_blinking_p
- && MAY_USE_WITH_COLORS_P (tty, NC_BLINK))
- OUTPUT1_IF (tty, tty->TS_enter_blink_mode);
+ if (face->tty_italic_p && MAY_USE_WITH_COLORS_P (tty, NC_ITALIC))
+ {
+ if (tty->TS_enter_italic_mode)
+ OUTPUT1 (tty, tty->TS_enter_italic_mode);
+ else
+ /* Italics mode is unavailable on many terminals. In that
+ case, map slant to dimmed text; we want italic text to
+ appear different and dimming is not otherwise used. */
+ OUTPUT1 (tty, tty->TS_enter_dim_mode);
+ }
if (face->tty_underline_p && MAY_USE_WITH_COLORS_P (tty, NC_UNDERLINE))
OUTPUT1_IF (tty, tty->TS_enter_underline_mode);
struct face *face = FACE_FROM_ID (f, face_id);
struct tty_display_info *tty = FRAME_TTY (f);
- xassert (face != NULL);
+ eassert (face != NULL);
if (tty->TS_exit_attribute_mode)
{
half-bright, reverse-video, standout, underline. It may or
may not turn off alt-char-mode. */
if (face->tty_bold_p
- || face->tty_dim_p
+ || face->tty_italic_p
|| face->tty_reverse_p
- || face->tty_alt_charset_p
- || face->tty_blinking_p
|| face->tty_underline_p)
{
OUTPUT1_IF (tty, tty->TS_exit_attribute_mode);
if (strcmp (tty->TS_exit_attribute_mode, tty->TS_end_standout_mode) == 0)
tty->standout_mode = 0;
}
-
- if (face->tty_alt_charset_p)
- OUTPUT_IF (tty, tty->TS_exit_alt_charset_mode);
}
else
{
/* If we don't have "me" we can only have those appearances
that have exit sequences defined. */
- if (face->tty_alt_charset_p)
- OUTPUT_IF (tty, tty->TS_exit_alt_charset_mode);
-
if (face->tty_underline_p)
OUTPUT_IF (tty, tty->TS_exit_underline_mode);
}
TTY_CAPABLE_P_TRY (tty, TTY_CAP_UNDERLINE, tty->TS_enter_underline_mode, NC_UNDERLINE);
TTY_CAPABLE_P_TRY (tty, TTY_CAP_BOLD, tty->TS_enter_bold_mode, NC_BOLD);
TTY_CAPABLE_P_TRY (tty, TTY_CAP_DIM, tty->TS_enter_dim_mode, NC_DIM);
- TTY_CAPABLE_P_TRY (tty, TTY_CAP_BLINK, tty->TS_enter_blink_mode, NC_BLINK);
- TTY_CAPABLE_P_TRY (tty, TTY_CAP_ALT_CHARSET, tty->TS_enter_alt_charset_mode, NC_ALT_CHARSET);
+ TTY_CAPABLE_P_TRY (tty, TTY_CAP_ITALIC, tty->TS_enter_italic_mode, NC_ITALIC);
/* We can do it! */
return 1;
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 does not refer to a text terminal. */)
(Lisp_Object terminal)
{
struct terminal *t = get_tty_terminal (terminal, 0);
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 does not refer to a text terminal. */)
(Lisp_Object terminal)
{
struct terminal *t = get_tty_terminal (terminal, 0);
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 does not refer to a text terminal. */)
(Lisp_Object terminal)
{
struct terminal *t = get_terminal (terminal, 1);
return Qnil;
}
+DEFUN ("tty-top-frame", Ftty_top_frame, Stty_top_frame, 0, 1, 0,
+ doc: /* Return the topmost terminal frame on TERMINAL.
+TERMINAL can be a terminal object, a frame or nil (meaning the
+selected frame's terminal). This function returns nil if TERMINAL
+does not refer to a text terminal. Otherwise, it returns the
+top-most frame on the text terminal. */)
+ (Lisp_Object terminal)
+{
+ struct terminal *t = get_terminal (terminal, 1);
+
+ if (t->type == output_termcap)
+ return t->display_info.tty->top_frame;
+ return Qnil;
+}
+
\f
DEFUN ("suspend-tty", Fsuspend_tty, Ssuspend_tty, 0, 1, 0,
return 0;
}
+/* Return the Time that corresponds to T. Wrap around on overflow. */
+static Time
+timeval_to_Time (struct timeval const *t)
+{
+ Time s_1000, ms;
+
+ s_1000 = t->tv_sec;
+ s_1000 *= 1000;
+ ms = t->tv_usec / 1000;
+ return s_1000 + ms;
+}
+
/* Return the current position of the mouse.
Set *f to the frame the mouse is in, or zero if the mouse is in no
Lisp_Object *y, Time *timeptr)
{
struct timeval now;
- Time sec, usec;
*fp = SELECTED_FRAME ();
(*fp)->mouse_moved = 0;
XSETINT (*x, last_mouse_x);
XSETINT (*y, last_mouse_y);
gettimeofday(&now, 0);
- sec = now.tv_sec;
- usec = now.tv_usec;
- *timeptr = (sec * 1000) + (usec / 1000);
+ *timeptr = timeval_to_Time (&now);
}
/* Prepare a mouse-event in *RESULT for placement in the input queue.
}
}
gettimeofday(&now, 0);
- result->timestamp = (now.tv_sec * 1000) + (now.tv_usec / 1000);
+ result->timestamp = timeval_to_Time (&now);
if (event->type & GPM_UP)
result->modifiers = up_modifier;
void
create_tty_output (struct frame *f)
{
- struct tty_output *t;
+ struct tty_output *t = xzalloc (sizeof *t);
if (! FRAME_TERMCAP_P (f))
abort ();
- t = xmalloc (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;
been_here = 1;
tty = &the_only_display_info;
#else
- tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info));
+ tty = xzalloc (sizeof *tty);
#endif
- memset (tty, 0, sizeof (struct tty_display_info));
tty->next = tty_list;
tty_list = tty;
terminal->display_info.tty = tty;
tty->terminal = terminal;
- tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm));
+ tty->Wcm = xmalloc (sizeof *tty->Wcm);
Wcm_clear (tty);
encode_terminal_src_size = 0;
Wcm_clear (tty);
- tty->termcap_term_buffer = (char *) xmalloc (buffer_size);
+ tty->termcap_term_buffer = xmalloc (buffer_size);
/* On some systems, tgetent tries to access the controlling
terminal. */
abort ();
buffer_size = strlen (tty->termcap_term_buffer);
#endif
- tty->termcap_strings_buffer = area = (char *) xmalloc (buffer_size);
+ tty->termcap_strings_buffer = area = xmalloc (buffer_size);
tty->TS_ins_line = tgetstr ("al", address);
tty->TS_ins_multi_lines = tgetstr ("AL", address);
tty->TS_bell = tgetstr ("bl", address);
tty->TS_enter_underline_mode = tgetstr ("us", address);
tty->TS_exit_underline_mode = tgetstr ("ue", address);
tty->TS_enter_bold_mode = tgetstr ("md", address);
+ tty->TS_enter_italic_mode = tgetstr ("ZH", address);
tty->TS_enter_dim_mode = tgetstr ("mh", address);
- tty->TS_enter_blink_mode = tgetstr ("mb", address);
tty->TS_enter_reverse_mode = tgetstr ("mr", address);
tty->TS_enter_alt_charset_mode = tgetstr ("as", address);
tty->TS_exit_alt_charset_mode = tgetstr ("ae", address);
MultiLeft (tty) = tgetstr ("LE", address);
MultiRight (tty) = tgetstr ("RI", address);
- /* SVr4/ANSI color suppert. If "op" isn't available, don't support
+ /* SVr4/ANSI color support. If "op" isn't available, don't support
color because we can't switch back to the default foreground and
background. */
tty->TS_orig_pair = tgetstr ("op", address);
tty->mouse_highlight.mouse_face_window = Qnil;
#endif
- terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+ terminal->kboard = xmalloc (sizeof *terminal->kboard);
init_kboard (terminal->kboard);
KVAR (terminal->kboard, Vwindow_system) = Qnil;
terminal->kboard->next_kboard = all_kboards;
xfree (tty->termcap_strings_buffer);
xfree (tty->termcap_term_buffer);
- memset (tty, 0, sizeof (struct tty_display_info));
xfree (tty);
}
\f
/* Mark the pointers in the tty_display_info objects.
- Called by the Fgarbage_collector. */
+ Called by Fgarbage_collect. */
void
mark_ttys (void)
defsubr (&Stty_no_underline);
defsubr (&Stty_type);
defsubr (&Scontrolling_tty_p);
+ defsubr (&Stty_top_frame);
defsubr (&Ssuspend_tty);
defsubr (&Sresume_tty);
#ifdef HAVE_GPM