/* Terminal control module for terminals described by TERMCAP
- Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2015 Free Software
+ Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2016 Free Software
Foundation, Inc.
This file is part of GNU Emacs.
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 of the License, 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
#include "keymap.h"
#include "blockinput.h"
#include "syssignal.h"
-#include "systty.h"
-#include "intervals.h"
#ifdef MSDOS
#include "msdos.h"
static int been_here = -1;
#endif
#include "cm.h"
-#ifdef HAVE_X_WINDOWS
-#include "xterm.h"
-#endif
-
#include "menu.h"
/* The name of the default console device. */
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, bool);
static void clear_tty_hooks (struct terminal *terminal);
static void set_tty_hooks (struct terminal *terminal);
static void dissociate_if_controlling_tty (int fd);
#define OUTPUT(tty, a) \
emacs_tputs ((tty), a, \
- FRAME_LINES (XFRAME (selected_frame)) - curY (tty), \
+ FRAME_TOTAL_LINES (XFRAME (selected_frame)) - curY (tty), \
cmputc)
#define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
#define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
-/* Display space properties */
+/* Display space properties. */
-/* Chain of all tty device parameters. */
+/* Chain of all tty device parameters. */
struct tty_display_info *tty_list;
/* Meaning of bits in no_color_video. Each bit set means that the
/* Set up termcap modes for Emacs. */
+static void
+tty_send_additional_strings (struct terminal *terminal, Lisp_Object sym)
+{
+ Lisp_Object lisp_terminal;
+ Lisp_Object extra_codes;
+ struct tty_display_info *tty = terminal->display_info.tty;
+
+ XSETTERMINAL (lisp_terminal, terminal);
+ for (extra_codes = Fterminal_parameter (lisp_terminal, sym);
+ CONSP (extra_codes);
+ extra_codes = XCDR (extra_codes))
+ {
+ Lisp_Object string = XCAR (extra_codes);
+ if (STRINGP (string))
+ {
+ fwrite (SDATA (string), 1, SBYTES (string), tty->output);
+ if (tty->termscript)
+ fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
+ }
+ }
+}
+
static void
tty_set_terminal_modes (struct terminal *terminal)
{
off the screen, so it won't be overwritten and lost. */
int i;
current_tty = tty;
- for (i = 0; i < FRAME_LINES (XFRAME (selected_frame)); i++)
+ for (i = 0; i < FRAME_TOTAL_LINES (XFRAME (selected_frame)); i++)
cmputc ('\n');
}
OUTPUT_IF (tty, visible_cursor ? tty->TS_cursor_visible : tty->TS_cursor_normal);
OUTPUT_IF (tty, tty->TS_keypad_mode);
losecursor (tty);
+ tty_send_additional_strings (terminal, Qtty_mode_set_strings);
fflush (tty->output);
}
}
if (tty->output)
{
+ tty_send_additional_strings (terminal, Qtty_mode_reset_strings);
tty_turn_off_highlight (tty);
tty_turn_off_insert (tty);
OUTPUT_IF (tty, tty->TS_end_keypad_mode);
{
struct tty_display_info *tty = FRAME_TTY (f);
- tty->specified_window = size ? size : FRAME_LINES (f);
+ tty->specified_window = size ? size : FRAME_TOTAL_LINES (f);
if (FRAME_SCROLL_REGION_OK (f))
tty_set_scroll_region (f, 0, tty->specified_window);
}
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,
- FRAME_LINES (f) - stop,
- FRAME_LINES (f));
+ FRAME_TOTAL_LINES (f), start,
+ FRAME_TOTAL_LINES (f) - stop,
+ FRAME_TOTAL_LINES (f));
else
buf = tparam (tty->TS_set_window, 0, 0, start, 0, stop, FRAME_COLS (f));
}
else
{
- for (i = curY (tty); i < FRAME_LINES (f); i++)
+ for (i = curY (tty); i < FRAME_TOTAL_LINES (f); i++)
{
cursor_to (f, i, 0);
clear_end_of_line (f, FRAME_COLS (f));
Set CODING->produced to the byte-length of the resulting byte
sequence, and return a pointer to that byte sequence. */
-#ifndef DOS_NT
-static
-#endif
unsigned char *
encode_terminal_code (struct glyph *src, int src_len,
struct coding_system *coding)
multibyte-form. But, it may be enlarged on demand if
Vglyph_table contains a string or a composite glyph is
encountered. */
- if (min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH < src_len)
+ if (INT_MULTIPLY_WRAPV (src_len, MAX_MULTIBYTE_LENGTH, &required))
memory_full (SIZE_MAX);
- required = src_len;
- required *= MAX_MULTIBYTE_LENGTH;
if (encode_terminal_src_size < required)
- {
- encode_terminal_src = xrealloc (encode_terminal_src, required);
- encode_terminal_src_size = required;
- }
+ encode_terminal_src = xpalloc (encode_terminal_src,
+ &encode_terminal_src_size,
+ required - encode_terminal_src_size,
+ -1, sizeof *encode_terminal_src);
charset_list = coding_charset_list (coding);
since that would scroll the whole frame on some terminals. */
if (AutoWrap (tty)
- && curY (tty) + 1 == FRAME_LINES (f)
+ && curY (tty) + 1 == FRAME_TOTAL_LINES (f)
&& (curX (tty) + len) == FRAME_COLS (f))
len --;
if (len <= 0)
since that would scroll the whole frame on some terminals. */
if (AutoWrap (tty)
- && curY (tty) + 1 == FRAME_LINES (f)
+ && curY (tty) + 1 == FRAME_TOTAL_LINES (f)
&& (curX (tty) + len) == FRAME_COLS (f))
len --;
if (len <= 0)
&& vpos + i >= tty->specified_window)
return;
if (!FRAME_MEMORY_BELOW_FRAME (f)
- && vpos + i >= FRAME_LINES (f))
+ && vpos + i >= FRAME_TOTAL_LINES (f))
return;
if (multi)
&& FRAME_MEMORY_BELOW_FRAME (f)
&& n < 0)
{
- cursor_to (f, FRAME_LINES (f) + n, 0);
+ cursor_to (f, FRAME_TOTAL_LINES (f) + n, 0);
clear_to_end (f);
}
}
if (!KEYMAPP (KVAR (kboard, Vinput_decode_map)))
kset_input_decode_map (kboard, Fmake_sparse_keymap (Qnil));
- for (i = 0; i < (sizeof (keys) / sizeof (keys[0])); i++)
+ for (i = 0; i < ARRAYELTS (keys); i++)
{
char *sequence = tgetstr (keys[i].cap, address);
if (sequence)
if (it->bidi_p)
{
glyph->resolved_level = it->bidi_it.resolved_level;
- if ((it->bidi_it.type & 7) != it->bidi_it.type)
- emacs_abort ();
+ eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
glyph->bidi_type = it->bidi_it.type;
}
else
glyph = it->glyph_row->glyphs[it->area];
}
glyph->type = COMPOSITE_GLYPH;
+ eassert (it->pixel_width <= SHRT_MAX);
glyph->pixel_width = it->pixel_width;
glyph->u.cmp.id = it->cmp_it.id;
if (it->cmp_it.ch < 0)
if (it->bidi_p)
{
glyph->resolved_level = it->bidi_it.resolved_level;
- if ((it->bidi_it.type & 7) != it->bidi_it.type)
- emacs_abort ();
+ eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
glyph->bidi_type = it->bidi_it.type;
}
else
if (it->bidi_p)
{
glyph->resolved_level = it->bidi_it.resolved_level;
- if ((it->bidi_it.type & 7) != it->bidi_it.type)
- emacs_abort ();
+ eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
glyph->bidi_type = it->bidi_it.type;
}
else
acronym = XCDR (acronym);
buf[0] = '[';
str = STRINGP (acronym) ? SSDATA (acronym) : "";
- for (len = 0; len < 6 && str[len] && ASCII_BYTE_P (str[len]); len++)
+ for (len = 0; len < 6 && str[len] && ASCII_CHAR_P (str[len]); len++)
buf[1 + len] = str[len];
buf[1 + len] = ']';
len += 2;
else
{
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));
+ len = sprintf (buf,
+ (it->c < 0x10000 ? "\\u%04X"
+ : it->c <= MAX_UNICODE_CHAR ? "\\U%06X"
+ : "\\x%06X"),
+ it->c + 0u);
}
str = buf;
}
TERMINAL does not refer to a text terminal. */)
(Lisp_Object terminal)
{
- struct terminal *t = get_tty_terminal (terminal, 0);
- if (!t)
- return Qnil;
- else
- return t->display_info.tty->TN_max_colors > 0 ? Qt : Qnil;
+ struct terminal *t = decode_tty_terminal (terminal);
+
+ return (t && t->display_info.tty->TN_max_colors > 0) ? Qt : Qnil;
}
/* Return the number of supported colors. */
TERMINAL does not refer to a text terminal. */)
(Lisp_Object terminal)
{
- struct terminal *t = get_tty_terminal (terminal, 0);
- if (!t)
- return make_number (0);
- else
- return make_number (t->display_info.tty->TN_max_colors);
+ struct terminal *t = decode_tty_terminal (terminal);
+
+ return make_number (t ? t->display_info.tty->TN_max_colors : 0);
}
#ifndef DOS_NT
#endif /* !DOS_NT */
-\f
-
-/* Return the tty display object specified by TERMINAL. */
-
-static struct terminal *
-get_tty_terminal (Lisp_Object terminal, bool throw)
-{
- struct terminal *t = get_terminal (terminal, throw);
-
- if (t && t->type != output_termcap && t->type != output_msdos_raw)
- {
- if (throw)
- error ("Device %d is not a termcap terminal device", t->id);
- else
- return NULL;
- }
-
- return t;
-}
-
-/* Return an active termcap device that uses the tty device with the
- given name.
-
- This function ignores suspended devices.
-
- Returns NULL if the named terminal device is not opened. */
-
-struct terminal *
-get_named_tty (const char *name)
-{
- struct terminal *t;
-
- eassert (name);
-
- for (t = terminal_list; t; t = t->next_terminal)
- {
- if ((t->type == output_termcap || t->type == output_msdos_raw)
- && !strcmp (t->display_info.tty->name, name)
- && TERMINAL_ACTIVE_P (t))
- return t;
- }
-
- return 0;
-}
-
-\f
DEFUN ("tty-type", Ftty_type, Stty_type, 0, 1, 0,
doc: /* Return the type of the tty device that TERMINAL uses.
Returns nil if TERMINAL is not on a tty device.
selected frame's terminal). */)
(Lisp_Object terminal)
{
- struct terminal *t = get_terminal (terminal, 1);
+ struct terminal *t = decode_tty_terminal (terminal);
- if (t->type != output_termcap && t->type != output_msdos_raw)
- return Qnil;
-
- if (t->display_info.tty->type)
- return build_string (t->display_info.tty->type);
- else
- return Qnil;
+ return (t && t->display_info.tty->type
+ ? build_string (t->display_info.tty->type) : Qnil);
}
DEFUN ("controlling-tty-p", Fcontrolling_tty_p, Scontrolling_tty_p, 0, 1, 0,
TERMINAL is not on a tty device. */)
(Lisp_Object terminal)
{
- struct terminal *t = get_terminal (terminal, 1);
+ struct terminal *t = decode_tty_terminal (terminal);
- if ((t->type != output_termcap && t->type != output_msdos_raw)
- || strcmp (t->display_info.tty->name, DEV_TTY) != 0)
- return Qnil;
- else
- return Qt;
+ return (t && !strcmp (t->display_info.tty->name, DEV_TTY) ? Qt : Qnil);
}
DEFUN ("tty-no-underline", Ftty_no_underline, Stty_no_underline, 0, 1, 0,
TERMINAL does not refer to a text terminal. */)
(Lisp_Object terminal)
{
- struct terminal *t = get_terminal (terminal, 1);
+ struct terminal *t = decode_live_terminal (terminal);
if (t->type == output_termcap)
t->display_info.tty->TS_enter_underline_mode = 0;
top-most frame on the text terminal. */)
(Lisp_Object terminal)
{
- struct terminal *t = get_terminal (terminal, 1);
+ struct terminal *t = decode_live_terminal (terminal);
if (t->type == output_termcap)
return t->display_info.tty->top_frame;
A suspended tty may be resumed by calling `resume-tty' on it. */)
(Lisp_Object tty)
{
- struct terminal *t = get_tty_terminal (tty, 1);
+ struct terminal *t = decode_tty_terminal (tty);
FILE *f;
if (!t)
- error ("Unknown tty device");
+ error ("Attempt to suspend a non-text terminal device");
f = t->display_info.tty->input;
/* First run `suspend-tty-functions' and then clean up the tty
state because `suspend-tty-functions' might need to change
the tty state. */
- Lisp_Object args[2];
- args[0] = intern ("suspend-tty-functions");
- XSETTERMINAL (args[1], t);
- Frun_hook_with_args (2, args);
+ Lisp_Object term;
+ XSETTERMINAL (term, t);
+ CALLN (Frun_hook_with_args, intern ("suspend-tty-functions"), term);
reset_sys_modes (t->display_info.tty);
delete_keyboard_wait_descriptor (fileno (f));
frame's terminal). */)
(Lisp_Object tty)
{
- struct terminal *t = get_tty_terminal (tty, 1);
+ struct terminal *t = decode_tty_terminal (tty);
int fd;
if (!t)
- error ("Unknown tty device");
+ error ("Attempt to resume a non-text terminal device");
if (!t->display_info.tty->input)
{
- if (get_named_tty (t->display_info.tty->name))
+ if (get_named_terminal (t->display_info.tty->name))
error ("Cannot resume display while another display is active on the same device");
#ifdef MSDOS
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);
+ int old_width = FRAME_TOTAL_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, width, height, 0, 0, 0, 0);
+ change_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f),
+ 0, 0, 0, 0);
SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1);
}
set_tty_hooks (t);
init_sys_modes (t->display_info.tty);
- {
- /* Run `resume-tty-functions'. */
- 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 term;
+ XSETTERMINAL (term, t);
+ CALLN (Frun_hook_with_args, intern ("resume-tty-functions"), term);
}
set_tty_hooks (t);
(*fp)->mouse_moved = 0;
*bar_window = Qnil;
- *part = 0;
+ *part = scroll_bar_above_handle;
XSETINT (*x, last_mouse_x);
XSETINT (*y, last_mouse_y);
last menu help message. */
static int menu_help_paneno, menu_help_itemno;
-static Lisp_Object Qtty_menu_navigation_map, Qtty_menu_exit;
-static Lisp_Object Qtty_menu_prev_item, Qtty_menu_next_item;
-static Lisp_Object Qtty_menu_next_menu, Qtty_menu_prev_menu;
-static Lisp_Object Qtty_menu_select, Qtty_menu_ignore;
-static Lisp_Object Qtty_menu_mouse_movement;
-
typedef struct tty_menu_struct
{
int count;
/* Don't try to display more menu items than the console can display
using the available screen lines. Exclude the echo area line, as
it will be overwritten by the help-echo anyway. */
- int max_items = min (menu->count - first_item, FRAME_LINES (sf) - 1 - y);
+ int max_items = min (menu->count - first_item, FRAME_TOTAL_LINES (sf) - 1 - y);
menu_help_message = NULL;
tty_menu_add_pane (tty_menu *menu, const char *txt)
{
int len;
- const unsigned char *p;
tty_menu_make_room (menu);
menu->submenu[menu->count] = tty_menu_create ();
menu->count++;
/* Update the menu width, if necessary. */
- for (len = 0, p = (unsigned char *) txt; *p; )
- {
- int ch_len;
- int ch = STRING_CHAR_AND_LENGTH (p, ch_len);
-
- len += CHAR_WIDTH (ch);
- p += ch_len;
- }
-
+ len = menu_item_width ((const unsigned char *) txt);
if (len > menu->width)
menu->width = len;
char *txt, bool enable, char const *help_text)
{
int len;
- unsigned char *p;
if (pane)
{
menu->count++;
/* Update the menu width, if necessary. */
- for (len = 0, p = (unsigned char *) txt; *p; )
- {
- int ch_len;
- int ch = STRING_CHAR_AND_LENGTH (p, ch_len);
-
- len += CHAR_WIDTH (ch);
- p += ch_len;
- }
-
+ len = menu_item_width ((const unsigned char *) txt);
if (len > menu->width)
menu->width = len;
Lisp_Object selectface;
int first_item = 0;
int col, row;
+ Lisp_Object prev_inhibit_redisplay = Vinhibit_redisplay;
+ USE_SAFE_ALLOCA;
/* Don't allow non-positive x0 and y0, lest the menu will wrap
around the display. */
if (y0 <= 0)
y0 = 1;
- state = alloca (menu->panecount * sizeof (struct tty_menu_state));
+ SAFE_NALLOCA (state, 1, menu->panecount);
memset (state, 0, sizeof (*state));
faces[0]
= lookup_derived_face (sf, intern ("tty-menu-disabled-face"),
buffers_num_deleted = 1;
}
+ /* Inhibit redisplay for as long as the menu is active, to avoid
+ messing the screen if some timer calls sit-for or a similar
+ function. */
+ Vinhibit_redisplay = Qt;
+
/* Force update of the current frame, so that the desired and the
current matrices are identical. */
update_frame_with_menu (sf, -1, -1);
{
mi_result input_status;
int min_y = state[0].y;
- int max_y = min (min_y + state[0].menu->count, FRAME_LINES (sf) - 1) - 1;
+ int max_y = min (min_y + state[0].menu->count, FRAME_TOTAL_LINES (sf) - 1) - 1;
input_status = read_menu_input (sf, &x, &y, min_y, max_y, &first_time);
if (input_status)
discard_mouse_events ();
if (!kbd_buffer_events_waiting ())
clear_input_pending ();
+ SAFE_FREE ();
+ Vinhibit_redisplay = prev_inhibit_redisplay;
return result;
}
tty_pop_down_menu (Lisp_Object arg)
{
tty_menu *menu = XSAVE_POINTER (arg, 0);
+ struct buffer *orig_buffer = XSAVE_POINTER (arg, 1);
block_input ();
tty_menu_destroy (menu);
+ set_buffer_internal (orig_buffer);
unblock_input ();
}
}
}
+/* WINDOWSNT uses this as menu_show_hook, see w32console.c. */
Lisp_Object
-tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
- Lisp_Object title, bool kbd_navigation, const char **error_name)
+tty_menu_show (struct frame *f, int x, int y, int menuflags,
+ Lisp_Object title, const char **error_name)
{
tty_menu *menu;
int pane, selidx, lpane, status;
/* Make the menu on that window. */
menu = tty_menu_create ();
- if (menu == NULL)
- {
- *error_name = "Can't create menu";
- return Qnil;
- }
/* Don't GC while we prepare and show the menu, because we give the
menu functions pointers to the contents of strings. */
specpdl_count = inhibit_garbage_collection ();
+ /* Avoid crashes if, e.g., another client will connect while we
+ are in a menu. */
+ temporarily_switch_to_single_kboard (f);
+
/* Adjust coordinates to be root-window-relative. */
item_x = x += f->left_pos;
item_y = y += f->top_pos;
/* Create all the necessary panes and their items. */
+ USE_SAFE_ALLOCA;
maxwidth = maxlines = lines = i = 0;
lpane = TTYM_FAILURE;
while (i < menu_items_used)
prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
pane_string = (NILP (pane_name)
? "" : SSDATA (pane_name));
- if (keymaps && !NILP (prefix))
+ if ((menuflags & MENU_KEYMAPS) && !NILP (prefix))
pane_string++;
lpane = tty_menu_add_pane (menu, pane_string);
if (!NILP (descrip))
{
- /* If alloca is fast, use that to make the space,
- to reduce gc needs. */
- item_data = (char *) alloca (maxwidth + SBYTES (descrip) + 1);
+ item_data = SAFE_ALLOCA (maxwidth + SBYTES (descrip) + 1);
memcpy (item_data, SSDATA (item_name), SBYTES (item_name));
for (j = SCHARS (item_name); j < maxwidth; j++)
item_data[j] = ' ';
pane = selidx = 0;
- record_unwind_protect (tty_pop_down_menu, make_save_ptr (menu));
+ /* We save and restore the current buffer because tty_menu_activate
+ triggers redisplay, which switches buffers at will. */
+ record_unwind_protect (tty_pop_down_menu,
+ make_save_ptr_ptr (menu, current_buffer));
specbind (Qoverriding_terminal_local_map,
Fsymbol_value (Qtty_menu_navigation_map));
status = tty_menu_activate (menu, &pane, &selidx, x, y, &datap,
- tty_menu_help_callback, kbd_navigation);
+ tty_menu_help_callback,
+ menuflags & MENU_KBD_NAVIGATION);
entry = pane_prefix = Qnil;
switch (status)
{
entry
= AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
- if (keymaps != 0)
+ if (menuflags & MENU_KEYMAPS)
{
entry = Fcons (entry, Qnil);
if (!NILP (pane_prefix))
Ftop_level ();
/* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means
the menu was invoked with a mouse event as POSITION). */
- if (! for_click)
+ if (!(menuflags & MENU_FOR_CLICK))
Fsignal (Qquit, Qnil);
break;
}
tty_menu_end:
+ SAFE_FREE ();
unbind_to (specpdl_count, Qnil);
return entry;
}
terminal->frame_rehighlight_hook = 0;
terminal->frame_raise_lower_hook = 0;
terminal->fullscreen_hook = 0;
+ terminal->menu_show_hook = 0;
terminal->set_vertical_scroll_bar_hook = 0;
+ terminal->set_horizontal_scroll_bar_hook = 0;
terminal->condemn_scroll_bars_hook = 0;
terminal->redeem_scroll_bar_hook = 0;
terminal->judge_scroll_bars_hook = 0;
static void
set_tty_hooks (struct terminal *terminal)
{
- terminal->rif = 0; /* ttys don't support window-based redisplay. */
-
terminal->cursor_to_hook = &tty_cursor_to;
terminal->raw_cursor_to_hook = &tty_raw_cursor_to;
-
terminal->clear_to_end_hook = &tty_clear_to_end;
terminal->clear_frame_hook = &tty_clear_frame;
terminal->clear_end_of_line_hook = &tty_clear_end_of_line;
-
terminal->ins_del_lines_hook = &tty_ins_del_lines;
-
terminal->insert_glyphs_hook = &tty_insert_glyphs;
terminal->write_glyphs_hook = &tty_write_glyphs;
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->update_end_hook = &tty_update_end;
+#ifdef MSDOS
+ terminal->menu_show_hook = &x_menu_show;
+#else
+ terminal->menu_show_hook = &tty_menu_show;
+#endif
terminal->set_terminal_window_hook = &tty_set_terminal_window;
-
- terminal->mouse_position_hook = 0; /* Not needed. */
- terminal->frame_rehighlight_hook = 0; /* Not needed. */
- terminal->frame_raise_lower_hook = 0; /* Not needed. */
-
- terminal->set_vertical_scroll_bar_hook = 0; /* Not needed. */
- terminal->condemn_scroll_bars_hook = 0; /* Not needed. */
- terminal->redeem_scroll_bar_hook = 0; /* Not needed. */
- terminal->judge_scroll_bars_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 = &tty_free_frame_resources;
terminal->delete_terminal_hook = &delete_tty;
+ /* Other hooks are NULL by default. */
}
/* If FD is the controlling terminal, drop it. */
/* setsid failed, presumably because Emacs is already a process
group leader. Fall back on the obsolescent way to dissociate
a controlling tty. */
- block_tty_out_signal ();
+ sigset_t oldset;
+ block_tty_out_signal (&oldset);
ioctl (fd, TIOCNOTTY, 0);
- unblock_tty_out_signal ();
+ unblock_tty_out_signal (&oldset);
#endif
}
}
int status;
struct tty_display_info *tty = NULL;
struct terminal *terminal = NULL;
+ sigset_t oldset;
bool ctty = false; /* True if asked to open controlling tty. */
if (!terminal_type)
/* XXX Perhaps this should be made explicit by having init_tty
always create a new terminal and separating terminal and frame
creation on Lisp level. */
- terminal = get_named_tty (name);
+ terminal = get_named_terminal (name);
if (terminal)
return terminal;
- terminal = create_terminal ();
+ terminal = create_terminal (output_termcap, NULL);
#ifdef MSDOS
if (been_here > 0)
maybe_fatal (0, 0, "Attempt to create another terminal %s", "",
tty->next = tty_list;
tty_list = tty;
- terminal->type = output_termcap;
terminal->display_info.tty = tty;
tty->terminal = terminal;
open a frame on the same terminal. */
int flags = O_RDWR | O_NOCTTY | (ctty ? 0 : O_IGNORE_CTTY);
int fd = emacs_open (name, flags, 0);
- tty->input = tty->output = fd < 0 || ! isatty (fd) ? 0 : fdopen (fd, "w+");
+ tty->input = tty->output
+ = ((fd < 0 || ! isatty (fd))
+ ? NULL
+ : fdopen (fd, "w+"));
if (! tty->input)
{
char const *diagnostic
- = tty->input ? "Not a tty device: %s" : "Could not open file: %s";
+ = (fd < 0) ? "Could not open file: %s" : "Not a tty device: %s";
emacs_close (fd);
maybe_fatal (must_succeed, terminal, diagnostic, diagnostic, name);
}
/* On some systems, tgetent tries to access the controlling
terminal. */
- block_tty_out_signal ();
+ block_tty_out_signal (&oldset);
status = tgetent (tty->termcap_term_buffer, terminal_type);
if (tty->termcap_term_buffer[TERMCAP_BUFFER_SIZE - 1])
emacs_abort ();
- unblock_tty_out_signal ();
+ unblock_tty_out_signal (&oldset);
if (status < 0)
{
"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"
+use the Bourne shell command 'TERM=...; export TERM' (C-shell:\n\
+'setenv TERM ...') to specify the correct type. It may be necessary\n"
#ifdef TERMINFO
-"to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
+"to do 'unset TERMINFO' (C-shell: 'unsetenv TERMINFO') as well.",
#else
-"to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
+"to do 'unset TERMCAP' (C-shell: 'unsetenv TERMCAP') as well.",
#endif
terminal_type);
}
tty->specified_window = height;
FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
+ FRAME_HAS_HORIZONTAL_SCROLL_BARS (f) = 0;
tty->char_ins_del_ok = 1;
baud_rate = 19200;
}
"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"
+use the Bourne shell command 'TERM=...; export TERM' (C-shell:\n\
+'setenv TERM ...') to specify the correct type. It may be necessary\n"
# ifdef TERMINFO
-"to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
+"to do 'unset TERMINFO' (C-shell: 'unsetenv TERMINFO') as well.",
# else /* TERMCAP */
-"to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
+"to do 'unset TERMCAP' (C-shell: 'unsetenv TERMCAP') as well.",
# endif /* TERMINFO */
terminal_type);
}
\f
-/* Delete the given tty terminal, closing all frames on it. */
+/* Delete the given tty terminal, closing all frames on it. */
static void
delete_tty (struct terminal *terminal)
;
if (! p)
- /* This should not happen. */
+ /* This should not happen. */
emacs_abort ();
p->next = tty->next;
}
/* reset_sys_modes needs a valid device, so this call needs to be
- before delete_terminal. */
+ before delete_terminal. */
reset_sys_modes (tty);
delete_terminal (terminal);
encode_terminal_src = NULL;
encode_terminal_dst = NULL;
+ DEFSYM (Qtty_mode_set_strings, "tty-mode-set-strings");
+ DEFSYM (Qtty_mode_reset_strings, "tty-mode-reset-strings");
+
#ifndef MSDOS
DEFSYM (Qtty_menu_next_item, "tty-menu-next-item");
DEFSYM (Qtty_menu_prev_item, "tty-menu-prev-item");