/* 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, 2009, 2010, 2011
+ Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2011
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <sys/file.h>
#include <unistd.h>
#include <signal.h>
-#include <stdarg.h>
#include <setjmp.h>
#include "lisp.h"
#include "termchar.h"
#include "termopts.h"
+#include "tparam.h"
#include "buffer.h"
#include "character.h"
#include "charset.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);
-
-char *tparam (char *, char *, int, int, ...);
-
-extern char *tgetstr (char *, char **);
-
#include "cm.h"
#ifdef HAVE_X_WINDOWS
#include "xterm.h"
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_turn_off_highlight (struct tty_display_info *);
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 struct terminal *get_tty_terminal (Lisp_Object, int);
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;
+ 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);
#define OUTPUT(tty, a) \
#define OUTPUT_IF(tty, a) \
do { \
if (a) \
- emacs_tputs ((tty), a, \
- (int) (FRAME_LINES (XFRAME (selected_frame)) \
- - curY (tty) ), \
- cmputc); \
+ OUTPUT (tty, a); \
} while (0)
#define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
/* The largest frame width in any call to calculate_costs. */
-int max_frame_cols;
+static int max_frame_cols;
/* The largest frame height in any call to calculate_costs. */
-int max_frame_lines;
+static int max_frame_lines;
/* Non-zero if we have dropped our controlling tty and therefore
should not open a frame on stdout. */
/* Set up termcap modes for Emacs. */
-void
+static void
tty_set_terminal_modes (struct terminal *terminal)
{
struct tty_display_info *tty = terminal->display_info.tty;
/* Reset termcap modes before exiting Emacs. */
-void
+static void
tty_reset_terminal_modes (struct terminal *terminal)
{
struct tty_display_info *tty = terminal->display_info.tty;
struct tty_display_info *tty = FRAME_TTY (f);
if (tty->TS_set_scroll_region)
- buf = tparam (tty->TS_set_scroll_region, 0, 0, start, stop - 1);
+ buf = tparam (tty->TS_set_scroll_region, 0, 0, start, stop - 1, 0, 0);
else if (tty->TS_set_scroll_region_1)
buf = tparam (tty->TS_set_scroll_region_1, 0, 0,
FRAME_LINES (f), start,
\f
/* Handle highlighting. */
-void
+static void
tty_turn_off_highlight (struct tty_display_info *tty)
{
if (tty->standout_mode)
{
if (src->type == COMPOSITE_GLYPH)
{
- struct composition *cmp;
- Lisp_Object gstring;
+ struct composition *cmp IF_LINT (= NULL);
+ Lisp_Object gstring IF_LINT (= Qnil);
int i;
nbytes = buf - encode_terminal_src;
else if (! CHAR_GLYPH_PADDING_P (*src))
{
GLYPH g;
- int c;
+ int c IF_LINT (= 0);
Lisp_Object string;
string = Qnil;
}
else
{
- unsigned char *p = SDATA (string);
-
if (! STRING_MULTIBYTE (string))
string = string_to_multibyte (string);
nbytes = buf - encode_terminal_src;
{
unsigned char *conversion_buffer;
struct coding_system *coding;
+ size_t n, stringlen;
struct tty_display_info *tty = FRAME_TTY (f);
the tail. */
coding->mode &= ~CODING_MODE_LAST_BLOCK;
- while (len > 0)
+ for (stringlen = len; stringlen != 0; stringlen -= n)
{
/* Identify a run of glyphs with the same face. */
int face_id = string->face_id;
- int n;
- for (n = 1; n < len; ++n)
+ for (n = 1; n < stringlen; ++n)
if (string[n].face_id != face_id)
break;
tty_highlight_if_desired (tty);
turn_on_face (f, face_id);
- if (n == len)
+ if (n == stringlen)
/* This is the last run. */
coding->mode |= CODING_MODE_LAST_BLOCK;
conversion_buffer = encode_terminal_code (string, n, coding);
fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
UNBLOCK_INPUT;
}
- len -= n;
string += n;
/* Turn appearance modes off. */
if (tty->TS_ins_multi_chars)
{
- buf = tparam (tty->TS_ins_multi_chars, 0, 0, len);
+ buf = tparam (tty->TS_ins_multi_chars, 0, 0, len, 0, 0, 0);
OUTPUT1 (tty, buf);
xfree (buf);
if (start)
if (tty->TS_del_multi_chars)
{
- buf = tparam (tty->TS_del_multi_chars, 0, 0, n);
+ buf = tparam (tty->TS_del_multi_chars, 0, 0, n, 0, 0, 0);
OUTPUT1 (tty, buf);
xfree (buf);
}
tty_ins_del_lines (struct frame *f, int vpos, int n)
{
struct tty_display_info *tty = FRAME_TTY (f);
- char *multi = n > 0 ? tty->TS_ins_multi_lines : tty->TS_del_multi_lines;
- char *single = n > 0 ? tty->TS_ins_line : tty->TS_del_line;
- char *scroll = n > 0 ? tty->TS_rev_scroll : tty->TS_fwd_scroll;
+ const char *multi =
+ n > 0 ? tty->TS_ins_multi_lines : tty->TS_del_multi_lines;
+ const char *single = n > 0 ? tty->TS_ins_line : tty->TS_del_line;
+ const char *scroll = n > 0 ? tty->TS_rev_scroll : tty->TS_fwd_scroll;
register int i = n > 0 ? n : -n;
register char *buf;
{
raw_cursor_to (f, vpos, 0);
tty_background_highlight (tty);
- buf = tparam (multi, 0, 0, i);
+ buf = tparam (multi, 0, 0, i, 0, 0, 0);
OUTPUT (tty, buf);
xfree (buf);
}
if (FRAME_TERMCAP_P (frame))
{
struct tty_display_info *tty = FRAME_TTY (frame);
- register char *f = (tty->TS_set_scroll_region
- ? tty->TS_set_scroll_region
- : tty->TS_set_scroll_region_1);
+ register const char *f = (tty->TS_set_scroll_region
+ ? tty->TS_set_scroll_region
+ : tty->TS_set_scroll_region_1);
FRAME_SCROLL_REGION_COST (frame) = string_cost (f);
}
\f
struct fkey_table {
- char *cap, *name;
+ const char *cap, *name;
};
/* Termcap capability names that correspond directly to X keysyms.
KBOARD *kboard = term_get_fkeys_kboard;
/* This can happen if CANNOT_DUMP or with strange options. */
- if (!KEYMAPP (kboard->Vinput_decode_map))
- kboard->Vinput_decode_map = Fmake_sparse_keymap (Qnil);
+ if (!KEYMAPP (KVAR (kboard, Vinput_decode_map)))
+ KVAR (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->Vinput_decode_map, build_string (sequence),
+ Fdefine_key (KVAR (kboard, Vinput_decode_map), build_string (sequence),
Fmake_vector (make_number (1),
intern (keys[i].name)));
}
"k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
*/
{
- char *k_semi = tgetstr ("k;", address);
- char *k0 = tgetstr ("k0", address);
- char *k0_name = "f10";
+ const char *k_semi = tgetstr ("k;", address);
+ const char *k0 = tgetstr ("k0", address);
+ const char *k0_name = "f10";
if (k_semi)
{
if (k0)
/* Define f0 first, so that f10 takes precedence in case the
key sequences happens to be the same. */
- Fdefine_key (kboard->Vinput_decode_map, build_string (k0),
+ Fdefine_key (KVAR (kboard, Vinput_decode_map), build_string (k0),
Fmake_vector (make_number (1), intern ("f0")));
- Fdefine_key (kboard->Vinput_decode_map, build_string (k_semi),
+ Fdefine_key (KVAR (kboard, Vinput_decode_map), build_string (k_semi),
Fmake_vector (make_number (1), intern ("f10")));
}
else if (k0)
- Fdefine_key (kboard->Vinput_decode_map, build_string (k0),
+ Fdefine_key (KVAR (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->Vinput_decode_map, build_string (sequence),
+ Fdefine_key (KVAR (kboard, Vinput_decode_map), build_string (sequence),
Fmake_vector (make_number (1),
intern (fkey)));
}
{ \
char *sequence = tgetstr (cap2, address); \
if (sequence) \
- Fdefine_key (kboard->Vinput_decode_map, build_string (sequence), \
+ Fdefine_key (KVAR (kboard, Vinput_decode_map), build_string (sequence), \
Fmake_vector (make_number (1), \
intern (sym))); \
}
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 append_glyphless_glyph (struct it *, int, const char *);
static void produce_glyphless_glyph (struct it *, int, Lisp_Object);
/* Append glyphs to IT's glyph_row. Called from produce_glyphs for
/* Nothing but characters are supported on terminal frames. */
xassert (it->what == IT_CHARACTER
|| it->what == IT_COMPOSITION
- || it->what == IT_STRETCH);
+ || it->what == IT_STRETCH
+ || it->what == IT_GLYPHLESS);
if (it->what == IT_STRETCH)
{
comes from it->nglyphs bytes). */
static void
-append_glyphless_glyph (struct it *it, int face_id, char *str)
+append_glyphless_glyph (struct it *it, int face_id, const char *str)
{
struct glyph *glyph, *end;
int i;
{
int face_id;
int len;
- char buf[9], *str = " ";
+ char buf[9];
+ char const *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 (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
+ if (CONSP (acronym))
+ acronym = XCDR (acronym);
buf[0] = '[';
- str = STRINGP (acronym) ? (char *) SDATA (acronym) : "";
+ 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] = ']';
it->pixel_width = len;
it->nglyphs = len;
- if (len > 0 && it->glyph_row)
+ if (it->glyph_row)
append_glyphless_glyph (it, face_id, str);
}
if (tty->TN_max_colors > 0)
{
- char *ts, *p;
+ const char *ts;
+ char *p;
ts = tty->standout_mode ? tty->TS_set_background : tty->TS_set_foreground;
if (fg >= 0 && ts)
{
- p = tparam (ts, NULL, 0, (int) fg);
+ p = tparam (ts, NULL, 0, (int) fg, 0, 0, 0);
OUTPUT (tty, p);
xfree (p);
}
ts = tty->standout_mode ? tty->TS_set_foreground : tty->TS_set_background;
if (bg >= 0 && ts)
{
- p = tparam (ts, NULL, 0, (int) bg);
+ p = tparam (ts, NULL, 0, (int) bg, 0, 0, 0);
OUTPUT (tty, p);
xfree (p);
}
/* Return the tty display object specified by TERMINAL. */
-struct terminal *
+static struct terminal *
get_tty_terminal (Lisp_Object terminal, int throw)
{
struct terminal *t = get_terminal (terminal, throw);
/* 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);
- }
+ 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);
delete_keyboard_wait_descriptor (fileno (f));
FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1);
}
+ set_tty_hooks (t);
init_sys_modes (t->display_info.tty);
- /* Run `resume-tty-functions'. */
- if (!NILP (Vrun_hooks))
- {
- Lisp_Object args[2];
- args[0] = intern ("resume-tty-functions");
- XSETTERMINAL (args[1], t);
- Frun_hook_with_args (2, args);
- }
+ {
+ /* Run `resume-tty-functions'. */
+ Lisp_Object args[2];
+ args[0] = intern ("resume-tty-functions");
+ XSETTERMINAL (args[1], t);
+ Frun_hook_with_args (2, args);
+ }
}
set_tty_hooks (t);
***********************************************************************/
#ifdef HAVE_GPM
+
+#ifndef HAVE_WINDOW_SYSTEM
void
term_mouse_moveto (int x, int y)
{
last_mouse_x = x;
last_mouse_y = y; */
}
+#endif /* HAVE_WINDOW_SYSTEM */
/* Implementation of draw_row_with_mouse_face for TTY/GPM. */
void
Set *bar_window to Qnil, and *x and *y to the column and
row of the character cell the mouse is over.
- Set *time to the time the mouse was at the returned position.
+ Set *timeptr to the time the mouse was at the returned position.
This clears mouse_moved until the next motion
event arrives. */
static void
term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
enum scroll_bar_part *part, Lisp_Object *x,
- Lisp_Object *y, unsigned long *time)
+ 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);
- *time = (now.tv_sec * 1000) + (now.tv_usec / 1000);
+ sec = now.tv_sec;
+ usec = now.tv_usec;
+ *timeptr = (sec * 1000) + (usec / 1000);
}
/* Prepare a mouse-event in *RESULT for placement in the input queue.
char *area = NULL;
char **address = &area;
int buffer_size = 4096;
- register char *p = NULL;
int status;
struct tty_display_info *tty = NULL;
struct terminal *terminal = NULL;
terminal = create_terminal ();
#ifdef MSDOS
if (been_here > 0)
- maybe_fatal (1, 0, "Attempt to create another terminal %s", "",
+ maybe_fatal (0, 0, "Attempt to create another terminal %s", "",
name, "");
been_here = 1;
tty = &the_only_display_info;
tty->mouse_highlight.mouse_face_window = Qnil;
#endif
-
+
#ifndef DOS_NT
set_tty_hooks (terminal);
if we don't have one at the moment. */
fd = emacs_open (name, O_RDWR | O_IGNORE_CTTY | O_NOCTTY, 0);
else
-#else
+#endif /* O_IGNORE_CTTY */
/* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
defined on Hurd. On other systems, we need to explicitly
dissociate ourselves from the controlling tty when we want to
open a frame on the same terminal. */
fd = emacs_open (name, O_RDWR | O_NOCTTY, 0);
-#endif /* O_IGNORE_CTTY */
tty->name = xstrdup (name);
terminal->name = xstrdup (name);
terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
init_kboard (terminal->kboard);
- terminal->kboard->Vwindow_system = Qnil;
+ KVAR (terminal->kboard, Vwindow_system) = Qnil;
terminal->kboard->next_kboard = all_kboards;
all_kboards = terminal->kboard;
terminal->kboard->reference_count++;
Down (tty) = 0;
}
- /* Special handling for certain terminal types known to need it */
-
- if (!strcmp (terminal_type, "supdup"))
- {
- terminal->memory_below_frame = 1;
- tty->Wcm->cm_losewrap = 1;
- }
- if (!strncmp (terminal_type, "c10", 3)
- || !strcmp (terminal_type, "perq"))
- {
- /* Supply a makeshift :wi string.
- This string is not valid in general since it works only
- for windows starting at the upper left corner;
- but that is all Emacs uses.
-
- This string works only if the frame is using
- the top of the video memory, because addressing is memory-relative.
- So first check the :ti string to see if that is true.
-
- It would be simpler if the :wi string could go in the termcap
- entry, but it can't because it is not fully valid.
- If it were in the termcap entry, it would confuse other programs. */
- if (!tty->TS_set_window)
- {
- p = tty->TS_termcap_modes;
- while (*p && strcmp (p, "\033v "))
- p++;
- if (*p)
- tty->TS_set_window = "\033v%C %C %C %C ";
- }
- /* Termcap entry often fails to have :in: flag */
- terminal->must_write_spaces = 1;
- /* :ti string typically fails to have \E^G! in it */
- /* This limits scope of insert-char to one line. */
- strcpy (area, tty->TS_termcap_modes);
- strcat (area, "\033\007!");
- tty->TS_termcap_modes = area;
- area += strlen (area) + 1;
- p = AbsPosition (tty);
- /* Change all %+ parameters to %C, to handle
- values above 96 correctly for the C100. */
- while (*p)
- {
- if (p[0] == '%' && p[1] == '+')
- p[1] = 'C';
- p++;
- }
- }
-
tty->specified_window = FrameRows (tty);
if (Wcm_init (tty) == -1) /* can't do cursor motion */
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. */
+ respectively, according to whether MUST_SUCCEED is zero or not. */
static void
maybe_fatal (int must_succeed, struct terminal *terminal,
encode_terminal_src = NULL;
encode_terminal_dst = NULL;
}
-